1 #include "gtest/gtest.h" 2 #include "avb_tools.h" 3 #include "keymaster_tools.h" 4 #include "nugget_tools.h" 5 #include "nugget/app/keymaster/keymaster.pb.h" 6 #include "nugget/app/keymaster/keymaster_defs.pb.h" 7 #include "nugget/app/keymaster/keymaster_types.pb.h" 8 #include "Keymaster.client.h" 9 #include "util.h" 10 11 #include "src/macros.h" 12 #include "src/test-data/test-keys/rsa.h" 13 14 #include "openssl/bn.h" 15 #include "openssl/ec_key.h" 16 #include "openssl/nid.h" 17 18 #include <sstream> 19 20 using std::cout; 21 using std::string; 22 using std::stringstream; 23 using std::unique_ptr; 24 25 using namespace nugget::app::keymaster; 26 27 using namespace test_data; 28 29 namespace { 30 31 class ImportKeyTest: public testing::Test { 32 protected: 33 static unique_ptr<nos::NuggetClientInterface> client; 34 static unique_ptr<Keymaster> service; 35 static unique_ptr<test_harness::TestHarness> uart_printer; 36 37 static void SetUpTestCase(); 38 static void TearDownTestCase(); 39 40 void initRSARequest(ImportKeyRequest *request, Algorithm alg) { 41 KeyParameters *params = request->mutable_params(); 42 KeyParameter *param = params->add_params(); 43 param->set_tag(Tag::ALGORITHM); 44 param->set_integer((uint32_t)alg); 45 } 46 47 void initRSARequest(ImportKeyRequest *request, Algorithm alg, int key_size) { 48 initRSARequest(request, alg); 49 50 if (key_size >= 0) { 51 KeyParameters *params = request->mutable_params(); 52 KeyParameter *param = params->add_params(); 53 param->set_tag(Tag::KEY_SIZE); 54 param->set_integer(key_size); 55 } 56 } 57 58 void initRSARequest(ImportKeyRequest *request, Algorithm alg, int key_size, 59 int public_exponent_tag) { 60 initRSARequest(request, alg, key_size); 61 62 if (public_exponent_tag >= 0) { 63 KeyParameters *params = request->mutable_params(); 64 KeyParameter *param = params->add_params(); 65 param->set_tag(Tag::RSA_PUBLIC_EXPONENT); 66 param->set_long_integer(public_exponent_tag); 67 } 68 } 69 70 void initRSARequest(ImportKeyRequest *request, Algorithm alg, int key_size, 71 int public_exponent_tag, uint32_t public_exponent, 72 const string& d, const string& n) { 73 initRSARequest(request, alg, key_size, public_exponent_tag); 74 75 request->mutable_rsa()->set_e(public_exponent); 76 request->mutable_rsa()->set_d(d); 77 request->mutable_rsa()->set_n(n); 78 } 79 }; 80 81 unique_ptr<nos::NuggetClientInterface> ImportKeyTest::client; 82 unique_ptr<Keymaster> ImportKeyTest::service; 83 unique_ptr<test_harness::TestHarness> ImportKeyTest::uart_printer; 84 85 void ImportKeyTest::SetUpTestCase() { 86 uart_printer = test_harness::TestHarness::MakeUnique(); 87 88 client = nugget_tools::MakeNuggetClient(); 89 client->Open(); 90 EXPECT_TRUE(client->IsOpen()) << "Unable to connect"; 91 92 service.reset(new Keymaster(*client)); 93 94 // Do setup that is normally done by the bootloader. 95 keymaster_tools::SetRootOfTrust(client.get()); 96 keymaster_tools::SetBootState(client.get()); 97 } 98 99 void ImportKeyTest::TearDownTestCase() { 100 client->Close(); 101 client = unique_ptr<nos::NuggetClientInterface>(); 102 103 uart_printer = nullptr; 104 } 105 106 // TODO: refactor into import key tests. 107 108 // Failure cases. 109 TEST_F(ImportKeyTest, AlgorithmMissingFails) { 110 ImportKeyRequest request; 111 ImportKeyResponse response; 112 113 KeyParameters *params = request.mutable_params(); 114 115 /* Algorithm tag is unspecified, import should fail. */ 116 KeyParameter *param = params->add_params(); 117 param->set_tag(Tag::KEY_SIZE); 118 param->set_integer(512); 119 120 param = params->add_params(); 121 param->set_tag(Tag::RSA_PUBLIC_EXPONENT); 122 param->set_long_integer(3); 123 124 ASSERT_NO_ERROR(service->ImportKey(request, &response), ""); 125 EXPECT_EQ((ErrorCode)response.error_code(), ErrorCode::INVALID_ARGUMENT); 126 } 127 128 // RSA 129 130 TEST_F(ImportKeyTest, RSAInvalidKeySizeFails) { 131 ImportKeyRequest request; 132 ImportKeyResponse response; 133 134 initRSARequest(&request, Algorithm::RSA, 256, 3); 135 136 ASSERT_NO_ERROR(service->ImportKey(request, &response), ""); 137 EXPECT_EQ((ErrorCode)response.error_code(), ErrorCode::UNSUPPORTED_KEY_SIZE); 138 } 139 140 TEST_F(ImportKeyTest, RSAInvalidPublicExponentFails) { 141 ImportKeyRequest request; 142 ImportKeyResponse response; 143 144 // Unsupported exponent 145 initRSARequest(&request, Algorithm::RSA, 1024, 2, 2, 146 string(64, '\0'), string(64, '\0')); 147 148 ASSERT_NO_ERROR(service->ImportKey(request, &response), ""); 149 EXPECT_EQ((ErrorCode)response.error_code(), 150 ErrorCode::UNSUPPORTED_KEY_SIZE); 151 } 152 153 TEST_F(ImportKeyTest, RSAKeySizeTagMisatchNFails) { 154 ImportKeyRequest request; 155 ImportKeyResponse response; 156 157 // N does not match KEY_SIZE. 158 initRSARequest(&request, Algorithm::RSA, 1024, 3, 3, 159 string(64, '\0'), string(63, '\0')); 160 ASSERT_NO_ERROR(service->ImportKey(request, &response), ""); 161 EXPECT_EQ((ErrorCode)response.error_code(), 162 ErrorCode::IMPORT_PARAMETER_MISMATCH); 163 } 164 165 TEST_F(ImportKeyTest, RSAKeySizeTagMisatchDFails) { 166 ImportKeyRequest request; 167 ImportKeyResponse response; 168 169 // D does not match KEY_SIZE. 170 initRSARequest(&request, Algorithm::RSA, 1024, 3, 3, 171 string(63, '\0'), string(64, '\0')); 172 ASSERT_NO_ERROR(service->ImportKey(request, &response), ""); 173 EXPECT_EQ((ErrorCode)response.error_code(), 174 ErrorCode::IMPORT_PARAMETER_MISMATCH); 175 } 176 177 TEST_F(ImportKeyTest, RSAPublicExponentTagMisatchFails) { 178 ImportKeyRequest request; 179 ImportKeyResponse response; 180 181 // e does not match PUBLIC_EXPONENT tag. 182 initRSARequest(&request, Algorithm::RSA, 1024, 3, 2, 183 string(64, '\0'), string(64, '\0')); 184 ASSERT_NO_ERROR(service->ImportKey(request, &response), ""); 185 EXPECT_EQ((ErrorCode)response.error_code(), 186 ErrorCode::IMPORT_PARAMETER_MISMATCH); 187 } 188 189 TEST_F(ImportKeyTest, RSA1024BadEFails) { 190 ImportKeyRequest request; 191 ImportKeyResponse response; 192 193 // Mis-matched e. 194 const string d((const char *)RSA_1024_D, sizeof(RSA_1024_D)); 195 const string N((const char *)RSA_1024_N, sizeof(RSA_1024_N)); 196 initRSARequest(&request, Algorithm::RSA, 1024, 3, 3, d, N); 197 198 ASSERT_NO_ERROR(service->ImportKey(request, &response), ""); 199 EXPECT_EQ((ErrorCode)response.error_code(), ErrorCode::INVALID_ARGUMENT); 200 } 201 202 TEST_F(ImportKeyTest, RSA1024BadDFails) { 203 ImportKeyRequest request; 204 ImportKeyResponse response; 205 206 const string d(string("\x01") + /* Twiddle LSB of D. */ 207 string((const char *)RSA_1024_D, sizeof(RSA_1024_D) - 1)); 208 const string N((const char *)RSA_1024_N, sizeof(RSA_1024_N)); 209 initRSARequest(&request, Algorithm::RSA, 1024, 65537, 65537, d, N); 210 211 ASSERT_NO_ERROR(service->ImportKey(request, &response), ""); 212 EXPECT_EQ((ErrorCode)response.error_code(), ErrorCode::INVALID_ARGUMENT); 213 } 214 215 TEST_F(ImportKeyTest, RSA1024BadNFails) { 216 ImportKeyRequest request; 217 ImportKeyResponse response; 218 219 const string d((const char *)RSA_1024_D, sizeof(RSA_1024_D)); 220 const string N(string("\x01") + /* Twiddle LSB of N. */ 221 string((const char *)RSA_1024_N, sizeof(RSA_1024_N) - 1)); 222 initRSARequest(&request, Algorithm::RSA, 1024, 65537, 65537, d, N); 223 224 ASSERT_NO_ERROR(service->ImportKey(request, &response), ""); 225 EXPECT_EQ((ErrorCode)response.error_code(), ErrorCode::INVALID_ARGUMENT); 226 } 227 228 TEST_F(ImportKeyTest, RSASuccess) { 229 ImportKeyRequest request; 230 ImportKeyResponse response; 231 232 initRSARequest(&request, Algorithm::RSA); 233 KeyParameters *params = request.mutable_params(); 234 KeyParameter *param = params->add_params(); 235 for (size_t i = 0; i < ARRAYSIZE(TEST_RSA_KEYS); i++) { 236 param->set_tag(Tag::RSA_PUBLIC_EXPONENT); 237 param->set_long_integer(TEST_RSA_KEYS[i].e); 238 239 request.mutable_rsa()->set_e(TEST_RSA_KEYS[i].e); 240 request.mutable_rsa()->set_d(TEST_RSA_KEYS[i].d, TEST_RSA_KEYS[i].size); 241 request.mutable_rsa()->set_n(TEST_RSA_KEYS[i].n, TEST_RSA_KEYS[i].size); 242 243 stringstream ss; 244 ss << "Failed at TEST_RSA_KEYS[" << i << "]"; 245 ASSERT_NO_ERROR(service->ImportKey(request, &response), ss.str()); 246 EXPECT_EQ((ErrorCode)response.error_code(), ErrorCode::OK) 247 << "Failed at TEST_RSA_KEYS[" << i << "]"; 248 249 /* TODO: do something useful with the imported key */ 250 } 251 } 252 253 TEST_F(ImportKeyTest, UpgradeSuccess) { 254 ImportKeyRequest request; 255 ImportKeyResponse response; 256 257 initRSARequest(&request, Algorithm::RSA); 258 KeyParameters *params = request.mutable_params(); 259 KeyParameter *param = params->add_params(); 260 261 param->set_tag(Tag::RSA_PUBLIC_EXPONENT); 262 param->set_long_integer(TEST_RSA_KEYS[0].e); 263 264 request.mutable_rsa()->set_e(TEST_RSA_KEYS[0].e); 265 request.mutable_rsa()->set_d(TEST_RSA_KEYS[0].d, TEST_RSA_KEYS[0].size); 266 request.mutable_rsa()->set_n(TEST_RSA_KEYS[0].n, TEST_RSA_KEYS[0].size); 267 268 { 269 EXPECT_TRUE(nugget_tools::RebootNugget(client.get())) 270 << "Failed to reboot nugget"; 271 272 SetSystemVersionInfoRequest svRequest; 273 SetSystemVersionInfoResponse svResponse; 274 275 svRequest.set_system_version(1); 276 svRequest.set_system_security_level(1); 277 svRequest.set_vendor_security_level(1); 278 279 ASSERT_NO_ERROR(service->SetSystemVersionInfo(svRequest, &svResponse), ""); 280 EXPECT_EQ((ErrorCode)svResponse.error_code(), ErrorCode::OK); 281 282 // Do setup that is normally done by the bootloader. 283 keymaster_tools::SetRootOfTrust(client.get()); 284 keymaster_tools::SetBootState(client.get()); 285 } 286 287 stringstream ss; 288 ASSERT_NO_ERROR(service->ImportKey(request, &response), ""); 289 EXPECT_EQ((ErrorCode)response.error_code(), ErrorCode::OK) 290 << "Failed at TEST_RSA_KEYS[" << 0 << "]"; 291 292 { 293 EXPECT_TRUE(nugget_tools::RebootNugget(client.get())) 294 << "Failed to reboot nugget"; 295 296 SetSystemVersionInfoRequest svRequest; 297 SetSystemVersionInfoResponse svResponse; 298 299 /* Bump vendor version level, to force Upgrade. */ 300 svRequest.set_system_version(1); 301 svRequest.set_system_security_level(1); 302 svRequest.set_vendor_security_level(2); 303 304 ASSERT_NO_ERROR(service->SetSystemVersionInfo(svRequest, &svResponse), ""); 305 EXPECT_EQ((ErrorCode)svResponse.error_code(), ErrorCode::OK); 306 307 // Do setup that is normally done by the bootloader. 308 keymaster_tools::SetRootOfTrust(client.get()); 309 keymaster_tools::SetBootState(client.get()); 310 } 311 312 { 313 GetKeyCharacteristicsRequest gkRequest; 314 GetKeyCharacteristicsResponse gkResponse; 315 316 gkRequest.mutable_blob()->set_blob(response.blob().blob().data(), 317 response.blob().blob().size()); 318 ASSERT_NO_ERROR(service->GetKeyCharacteristics(gkRequest, &gkResponse), ""); 319 EXPECT_EQ((ErrorCode)gkResponse.error_code(), 320 ErrorCode::KEY_REQUIRES_UPGRADE); 321 } 322 323 { 324 UpgradeKeyRequest ukRequest; 325 UpgradeKeyResponse ukResponse; 326 327 ukRequest.mutable_blob()->set_blob(response.blob().blob().data(), 328 response.blob().blob().size()); 329 ASSERT_NO_ERROR(service->UpgradeKey(ukRequest, &ukResponse), ""); 330 EXPECT_EQ((ErrorCode)ukResponse.error_code(), ErrorCode::OK); 331 332 // GetKeyCharacteristics succeeds after the UpgradeKey(). 333 GetKeyCharacteristicsRequest gkRequest; 334 GetKeyCharacteristicsResponse gkResponse; 335 336 gkRequest.mutable_blob()->set_blob(ukResponse.blob().blob().data(), 337 ukResponse.blob().blob().size()); 338 ASSERT_NO_ERROR(service->GetKeyCharacteristics(gkRequest, &gkResponse), ""); 339 EXPECT_EQ((ErrorCode)gkResponse.error_code(), ErrorCode::OK); 340 } 341 } 342 343 TEST_F(ImportKeyTest, RSA1024OptionalParamsAbsentSuccess) { 344 ImportKeyRequest request; 345 ImportKeyResponse response; 346 347 initRSARequest(&request, Algorithm::RSA, -1, -1, 65537, 348 string((const char *)RSA_1024_D, sizeof(RSA_1024_D)), 349 string((const char *)RSA_1024_N, sizeof(RSA_1024_N))); 350 351 ASSERT_NO_ERROR(service->ImportKey(request, &response), ""); 352 EXPECT_EQ((ErrorCode)response.error_code(), ErrorCode::OK); 353 354 /* TODO: do something useful with the imported key */ 355 } 356 357 // EC 358 359 TEST_F(ImportKeyTest, ECMissingCurveIdTagFails) { 360 ImportKeyRequest request; 361 ImportKeyResponse response; 362 363 KeyParameters *params = request.mutable_params(); 364 KeyParameter *param = params->add_params(); 365 param->set_tag(Tag::ALGORITHM); 366 param->set_integer((uint32_t)Algorithm::EC); 367 368 ASSERT_NO_ERROR(service->ImportKey(request, &response), ""); 369 EXPECT_EQ((ErrorCode)response.error_code(), ErrorCode::INVALID_ARGUMENT); 370 } 371 372 TEST_F(ImportKeyTest, ECMisMatchedCurveIdTagFails) { 373 ImportKeyRequest request; 374 ImportKeyResponse response; 375 376 KeyParameters *params = request.mutable_params(); 377 KeyParameter *param = params->add_params(); 378 param->set_tag(Tag::ALGORITHM); 379 param->set_integer((uint32_t)Algorithm::EC); 380 381 param = params->add_params(); 382 param->set_tag(Tag::EC_CURVE); 383 param->set_integer((uint32_t)EcCurve::P_256); 384 385 request.mutable_ec()->set_curve_id(((uint32_t)EcCurve::P_256) + 1); 386 387 ASSERT_NO_ERROR(service->ImportKey(request, &response), ""); 388 EXPECT_EQ((ErrorCode)response.error_code(), ErrorCode::INVALID_ARGUMENT); 389 } 390 391 TEST_F(ImportKeyTest, ECMisMatchedKeySizeTagCurveTagFails) { 392 ImportKeyRequest request; 393 ImportKeyResponse response; 394 395 KeyParameters *params = request.mutable_params(); 396 KeyParameter *param = params->add_params(); 397 param->set_tag(Tag::ALGORITHM); 398 param->set_integer((uint32_t)Algorithm::EC); 399 400 param = params->add_params(); 401 param->set_tag(Tag::EC_CURVE); 402 param->set_integer((uint32_t)EcCurve::P_256); 403 404 param = params->add_params(); 405 param->set_tag(Tag::KEY_SIZE); 406 param->set_integer((uint32_t)384); /* Should be 256 */ 407 408 request.mutable_ec()->set_curve_id((uint32_t)EcCurve::P_256); 409 410 ASSERT_NO_ERROR(service->ImportKey(request, &response), ""); 411 EXPECT_EQ((ErrorCode)response.error_code(), ErrorCode::INVALID_ARGUMENT); 412 } 413 414 TEST_F(ImportKeyTest, ECMisMatchedP256KeySizeFails) { 415 ImportKeyRequest request; 416 ImportKeyResponse response; 417 418 KeyParameters *params = request.mutable_params(); 419 KeyParameter *param = params->add_params(); 420 param->set_tag(Tag::ALGORITHM); 421 param->set_integer((uint32_t)Algorithm::EC); 422 423 param = params->add_params(); 424 param->set_tag(Tag::EC_CURVE); 425 param->set_integer((uint32_t)EcCurve::P_256); 426 427 request.mutable_ec()->set_curve_id((uint32_t)EcCurve::P_256); 428 request.mutable_ec()->set_d(string((256 >> 3) - 1, '\0')); 429 request.mutable_ec()->set_x(string((256 >> 3), '\0')); 430 request.mutable_ec()->set_y(string((256 >> 3), '\0')); 431 432 ASSERT_NO_ERROR(service->ImportKey(request, &response), ""); 433 EXPECT_EQ((ErrorCode)response.error_code(), ErrorCode::INVALID_ARGUMENT); 434 } 435 436 // TODO: bad key tests. invalid d, {x,y} not on curve, d, xy mismatched. 437 TEST_F(ImportKeyTest, ECP256BadKeyFails) { 438 ImportKeyRequest request; 439 ImportKeyResponse response; 440 441 KeyParameters *params = request.mutable_params(); 442 KeyParameter *param = params->add_params(); 443 param->set_tag(Tag::ALGORITHM); 444 param->set_integer((uint32_t)Algorithm::EC); 445 446 param = params->add_params(); 447 param->set_tag(Tag::EC_CURVE); 448 param->set_integer((uint32_t)EcCurve::P_256); 449 450 request.mutable_ec()->set_curve_id((uint32_t)EcCurve::P_256); 451 request.mutable_ec()->set_d(string((256 >> 3), '\0')); 452 request.mutable_ec()->set_x(string((256 >> 3), '\0')); 453 request.mutable_ec()->set_y(string((256 >> 3), '\0')); 454 455 ASSERT_NO_ERROR(service->ImportKey(request, &response), ""); 456 EXPECT_EQ((ErrorCode)response.error_code(), ErrorCode::INVALID_ARGUMENT); 457 } 458 459 TEST_F (ImportKeyTest, ImportECP256KeySuccess) { 460 // Generate an EC key. 461 // TODO: just hardcode a test key. 462 bssl::UniquePtr<EC_KEY> ec(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); 463 EXPECT_EQ(EC_KEY_generate_key(ec.get()), 1); 464 const EC_GROUP *group = EC_KEY_get0_group(ec.get()); 465 const BIGNUM *d = EC_KEY_get0_private_key(ec.get()); 466 const EC_POINT *point = EC_KEY_get0_public_key(ec.get()); 467 bssl::UniquePtr<BIGNUM> x(BN_new()); 468 bssl::UniquePtr<BIGNUM> y(BN_new()); 469 EXPECT_EQ(EC_POINT_get_affine_coordinates_GFp( 470 group, point, x.get(), y.get(), NULL), 1); 471 472 // Turn d, x, y into binary strings. 473 const size_t field_size = (EC_GROUP_get_degree(group) + 7) >> 3; 474 std::unique_ptr<uint8_t []> dstr(new uint8_t[field_size]); 475 std::unique_ptr<uint8_t []> xstr(new uint8_t[field_size]); 476 std::unique_ptr<uint8_t []> ystr(new uint8_t[field_size]); 477 478 EXPECT_EQ(BN_bn2le_padded(dstr.get(), field_size, d), 1); 479 EXPECT_EQ(BN_bn2le_padded(xstr.get(), field_size, x.get()), 1); 480 EXPECT_EQ(BN_bn2le_padded(ystr.get(), field_size, y.get()), 1); 481 482 ImportKeyRequest request; 483 ImportKeyResponse response; 484 485 KeyParameters *params = request.mutable_params(); 486 KeyParameter *param = params->add_params(); 487 param->set_tag(Tag::ALGORITHM); 488 param->set_integer((uint32_t)Algorithm::EC); 489 490 param = params->add_params(); 491 param->set_tag(Tag::EC_CURVE); 492 param->set_integer((uint32_t)EcCurve::P_256); 493 494 param = params->add_params(); 495 param->set_tag(Tag::KEY_SIZE); 496 param->set_integer((uint32_t)256); 497 498 request.mutable_ec()->set_curve_id((uint32_t)EcCurve::P_256); 499 request.mutable_ec()->set_d(dstr.get(), field_size); 500 request.mutable_ec()->set_x(xstr.get(), field_size); 501 request.mutable_ec()->set_y(ystr.get(), field_size); 502 503 ASSERT_NO_ERROR(service->ImportKey(request, &response), ""); 504 EXPECT_EQ((ErrorCode)response.error_code(), ErrorCode::OK); 505 } 506 507 // TODO: add tests for symmetric key import. 508 509 } // namespace 510