Home | History | Annotate | Download | only in src
      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