From 6e1683f5d508a4c1ff761a9a3508619ac5ac6ed7 Mon Sep 17 00:00:00 2001 From: Kenny Root Date: Mon, 19 Aug 2013 09:51:35 -0700 Subject: Add support for DSA and ECDSA key types Change-Id: I4b7d11c0915c716a0f1be65f5933f33a36e0fb4b --- include/hardware/keymaster.h | 50 ++++- tests/keymaster/keymaster_test.cpp | 378 +++++++++++++++++++++++++++++++++---- 2 files changed, 386 insertions(+), 42 deletions(-) diff --git a/include/hardware/keymaster.h b/include/hardware/keymaster.h index e0014c8a..968beb96 100644 --- a/include/hardware/keymaster.h +++ b/include/hardware/keymaster.h @@ -37,7 +37,7 @@ __BEGIN_DECLS * module to recognize which API level of the client it is dealing with in * the case of pre-compiled binary clients. */ -#define KEYMASTER_API_VERSION 1 +#define KEYMASTER_API_VERSION 2 /** * Flags for keymaster_device::flags @@ -62,6 +62,8 @@ struct keystore_module { */ typedef enum { TYPE_RSA = 1, + TYPE_DSA = 2, + TYPE_EC = 3, } keymaster_keypair_t; /** @@ -73,11 +75,42 @@ typedef struct { } keymaster_rsa_keygen_params_t; /** - * Digest type used for RSA operations. + * Parameters needed to generate a DSA key. + */ +typedef struct { + uint32_t key_size; + uint32_t generator_len; + uint32_t prime_p_len; + uint32_t prime_q_len; + const uint8_t* generator; + const uint8_t* prime_p; + const uint8_t* prime_q; +} keymaster_dsa_keygen_params_t; + +/** + * Parameters needed to generate an EC key. + * + * Field size is the only parameter in version 2. The sizes correspond to these required curves: + * + * 192 = NIST P-192 + * 224 = NIST P-224 + * 256 = NIST P-256 + * 384 = NIST P-384 + * 521 = NIST P-521 + * + * The parameters for these curves are available at: http://www.nsa.gov/ia/_files/nist-routines.pdf + * in Chapter 4. + */ +typedef struct { + uint32_t field_size; +} keymaster_ec_keygen_params_t; + +/** + * Digest type. */ typedef enum { DIGEST_NONE, -} keymaster_rsa_digest_t; +} keymaster_digest_t; /** * Type of padding used for RSA operations. @@ -86,8 +119,17 @@ typedef enum { PADDING_NONE, } keymaster_rsa_padding_t; + +typedef struct { + keymaster_digest_t digest_type; +} keymaster_dsa_sign_params_t; + +typedef struct { + keymaster_digest_t digest_type; +} keymaster_ec_sign_params_t; + typedef struct { - keymaster_rsa_digest_t digest_type; + keymaster_digest_t digest_type; keymaster_rsa_padding_t padding_type; } keymaster_rsa_sign_params_t; diff --git a/tests/keymaster/keymaster_test.cpp b/tests/keymaster/keymaster_test.cpp index 0046ea48..b3d3f359 100644 --- a/tests/keymaster/keymaster_test.cpp +++ b/tests/keymaster/keymaster_test.cpp @@ -186,12 +186,20 @@ struct RSA_Delete { }; typedef UniquePtr Unique_RSA; +struct EC_KEY_Delete { + void operator()(EC_KEY* p) const { + EC_KEY_free(p); + } +}; +typedef UniquePtr Unique_EC_KEY; + + /* * DER-encoded PKCS#8 format RSA key. Generated using: * * openssl genrsa 2048 | openssl pkcs8 -topk8 -nocrypt -outform der | recode ../x1 */ -static uint8_t TEST_KEY_1[] = { +static uint8_t TEST_RSA_KEY_1[] = { 0x30, 0x82, 0x04, 0xBE, 0x02, 0x01, 0x00, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x04, 0xA8, 0x30, 0x82, 0x04, 0xA4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, @@ -296,6 +304,27 @@ static uint8_t TEST_KEY_1[] = { 0xDE, 0x3B, 0xF1, 0x70, 0x23, 0xE5, }; +/* + * DER-encoded PKCS#8 format EC key. Generated using: + * + * openssl ecparam -name prime256v1 -genkey -noout | openssl pkcs8 -topk8 -nocrypt -outform der | recode ../x1 + */ +static uint8_t TEST_EC_KEY_1[] = { + 0x30, 0x81, 0x87, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, + 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, + 0x03, 0x01, 0x07, 0x04, 0x6D, 0x30, 0x6B, 0x02, 0x01, 0x01, 0x04, 0x20, + 0x25, 0xAC, 0x77, 0x2B, 0x04, 0x33, 0xC8, 0x16, 0x59, 0xA3, 0xC7, 0xE7, + 0x11, 0x42, 0xD0, 0x11, 0x71, 0x30, 0x7B, 0xB8, 0xD2, 0x67, 0xFF, 0x9C, + 0x5F, 0x50, 0x2E, 0xAB, 0x67, 0xD4, 0x17, 0x51, 0xA1, 0x44, 0x03, 0x42, + 0x00, 0x04, 0xCF, 0xCE, 0xB8, 0x7F, 0x88, 0x36, 0xC4, 0xF8, 0x51, 0x29, + 0xE2, 0xA7, 0x21, 0xC3, 0x3B, 0xFF, 0x88, 0xE3, 0x87, 0x98, 0xD1, 0xA6, + 0x4B, 0xB3, 0x4B, 0xD5, 0x44, 0xF8, 0xE0, 0x43, 0x6B, 0x50, 0x74, 0xFB, + 0xB0, 0xAD, 0x41, 0x1C, 0x11, 0x9D, 0xC6, 0x1E, 0x83, 0x8C, 0x49, 0xCA, + 0xBE, 0xC6, 0xCE, 0xB6, 0xC9, 0xA1, 0xBF, 0x69, 0xA9, 0xA0, 0xA3, 0x80, + 0x14, 0x39, 0x57, 0x94, 0xDA, 0x5D +}; + + /* * Generated using keys on the keyboard and lack of imagination. */ @@ -314,6 +343,9 @@ public: ASSERT_EQ(0, keymaster_open(mod, &sDevice)) << "Should be able to open the keymaster device"; + ASSERT_EQ(2U, sDevice->client_version) + << "Keymaster should implement API version 2"; + ASSERT_TRUE(sDevice->generate_keypair != NULL) << "Should implement generate_keypair"; @@ -343,11 +375,23 @@ keymaster_device_t* KeymasterBaseTest::sDevice = NULL; class KeymasterTest : public KeymasterBaseTest { }; -class KeymasterGenerateTest : public KeymasterBaseTest, +class KeymasterAllTypesTest : public KeymasterBaseTest, + public ::testing::WithParamInterface { +}; + +class KeymasterGenerateRSATest : public KeymasterBaseTest, public ::testing::WithParamInterface { }; -TEST_P(KeymasterGenerateTest, GenerateKeyPair_RSA_Success) { +class KeymasterGenerateDSATest : public KeymasterBaseTest, + public ::testing::WithParamInterface { +}; + +class KeymasterGenerateECTest : public KeymasterBaseTest, + public ::testing::WithParamInterface { +}; + +TEST_P(KeymasterGenerateRSATest, GenerateKeyPair_RSA_Success) { keymaster_keypair_t key_type = TYPE_RSA; keymaster_rsa_keygen_params_t params = { modulus_size: GetParam(), @@ -359,7 +403,7 @@ TEST_P(KeymasterGenerateTest, GenerateKeyPair_RSA_Success) { ASSERT_EQ(0, sDevice->generate_keypair(sDevice, key_type, ¶ms, &key_blob, &key_blob_length)) - << "Should generate an RSA key with 512 bit modulus size"; + << "Should generate an RSA key with " << GetParam() << " bit modulus size"; UniqueKey key(&sDevice, key_blob, key_blob_length); uint8_t* x509_data = NULL; @@ -386,25 +430,77 @@ TEST_P(KeymasterGenerateTest, GenerateKeyPair_RSA_Success) { ASSERT_EQ(static_cast(RSA_F4), BN_get_word(rsa.get()->e)) << "Exponent should be RSA_F4"; - ASSERT_EQ(GetParam() / 8, static_cast(RSA_size(rsa.get()))) + ASSERT_EQ((GetParam() + 7) / 8, static_cast(RSA_size(rsa.get()))) << "Modulus size should be the specified parameter"; } INSTANTIATE_TEST_CASE_P(RSA, - KeymasterGenerateTest, + KeymasterGenerateRSATest, ::testing::Values(512U, 1024U, 2048U, 3072U, 4096U)); -TEST_F(KeymasterTest, GenerateKeyPair_RSA_NullParams_Failure) { - keymaster_keypair_t key_type = TYPE_RSA; + +TEST_P(KeymasterGenerateECTest, GenerateKeyPair_EC_Success) { + keymaster_keypair_t key_type = TYPE_EC; + keymaster_ec_keygen_params_t params = { + field_size: GetParam(), + }; + + uint8_t* key_blob; + size_t key_blob_length; + + ASSERT_EQ(0, + sDevice->generate_keypair(sDevice, key_type, ¶ms, &key_blob, &key_blob_length)) + << "Should generate an EC key with " << GetParam() << " field size"; + UniqueKey key(&sDevice, key_blob, key_blob_length); + + uint8_t* x509_data = NULL; + size_t x509_data_length; + ASSERT_EQ(0, + sDevice->get_keypair_public(sDevice, key_blob, key_blob_length, + &x509_data, &x509_data_length)) + << "Should be able to retrieve EC public key successfully"; + UniqueBlob x509_blob(x509_data, x509_data_length); + ASSERT_FALSE(x509_blob.get() == NULL) + << "X509 data should be allocated"; + + const unsigned char *tmp = static_cast(x509_blob.get()); + Unique_EVP_PKEY actual(d2i_PUBKEY((EVP_PKEY**) NULL, &tmp, + static_cast(x509_blob.length()))); + + ASSERT_EQ(EVP_PKEY_EC, EVP_PKEY_type(actual.get()->type)) + << "Generated key type should be of type EC"; + + Unique_EC_KEY ecKey(EVP_PKEY_get1_EC_KEY(actual.get())); + ASSERT_FALSE(ecKey.get() == NULL) + << "Should be able to extract EC key from EVP_PKEY"; + + ASSERT_FALSE(EC_KEY_get0_group(ecKey.get()) == NULL) + << "EC key should have a EC_GROUP"; + + ASSERT_TRUE(EC_KEY_check_key(ecKey.get())) + << "EC key should check correctly"; +} + +INSTANTIATE_TEST_CASE_P(EC, + KeymasterGenerateECTest, + ::testing::Values(192U, 224U, 256U, 384U, 521U)); + + +TEST_P(KeymasterAllTypesTest, GenerateKeyPair_NullParams_Failure) { + keymaster_keypair_t key_type = GetParam(); uint8_t* key_blob; size_t key_blob_length; ASSERT_EQ(-1, sDevice->generate_keypair(sDevice, key_type, NULL, &key_blob, &key_blob_length)) - << "Should not be able to generate an RSA key with null params"; + << "Should not be able to generate a key with null params"; } +INSTANTIATE_TEST_CASE_P(Types, + KeymasterAllTypesTest, + ::testing::Values(TYPE_RSA, TYPE_DSA, TYPE_EC)); + TEST_F(KeymasterTest, GenerateKeyPair_UnknownType_Failure) { keymaster_keypair_t key_type = static_cast(0xFFFF); @@ -421,7 +517,7 @@ TEST_F(KeymasterTest, ImportKeyPair_RSA_Success) { size_t key_blob_length; ASSERT_EQ(0, - sDevice->import_keypair(sDevice, TEST_KEY_1, sizeof(TEST_KEY_1), + sDevice->import_keypair(sDevice, TEST_RSA_KEY_1, sizeof(TEST_RSA_KEY_1), &key_blob, &key_blob_length)) << "Should successfully import an RSA key"; UniqueKey key(&sDevice, key_blob, key_blob_length); @@ -441,10 +537,46 @@ TEST_F(KeymasterTest, ImportKeyPair_RSA_Success) { ASSERT_EQ(EVP_PKEY_type(actual.get()->type), EVP_PKEY_RSA) << "Generated key type should be of type RSA"; - const unsigned char *expectedTmp = static_cast(TEST_KEY_1); + const unsigned char *expectedTmp = static_cast(TEST_RSA_KEY_1); Unique_PKCS8_PRIV_KEY_INFO expectedPkcs8( d2i_PKCS8_PRIV_KEY_INFO((PKCS8_PRIV_KEY_INFO**) NULL, &expectedTmp, - sizeof(TEST_KEY_1))); + sizeof(TEST_RSA_KEY_1))); + + Unique_EVP_PKEY expected(EVP_PKCS82PKEY(expectedPkcs8.get())); + + ASSERT_EQ(1, EVP_PKEY_cmp(expected.get(), actual.get())) + << "Expected and actual keys should match"; +} + +TEST_F(KeymasterTest, ImportKeyPair_EC_Success) { + uint8_t* key_blob; + size_t key_blob_length; + + ASSERT_EQ(0, + sDevice->import_keypair(sDevice, TEST_EC_KEY_1, sizeof(TEST_EC_KEY_1), + &key_blob, &key_blob_length)) + << "Should successfully import an EC key"; + UniqueKey key(&sDevice, key_blob, key_blob_length); + + uint8_t* x509_data; + size_t x509_data_length; + ASSERT_EQ(0, + sDevice->get_keypair_public(sDevice, key_blob, key_blob_length, + &x509_data, &x509_data_length)) + << "Should be able to retrieve EC public key successfully"; + UniqueBlob x509_blob(x509_data, x509_data_length); + + const unsigned char *tmp = static_cast(x509_blob.get()); + Unique_EVP_PKEY actual(d2i_PUBKEY((EVP_PKEY**) NULL, &tmp, + static_cast(x509_blob.length()))); + + ASSERT_EQ(EVP_PKEY_type(actual.get()->type), EVP_PKEY_EC) + << "Generated key type should be of type EC"; + + const unsigned char *expectedTmp = static_cast(TEST_EC_KEY_1); + Unique_PKCS8_PRIV_KEY_INFO expectedPkcs8( + d2i_PKCS8_PRIV_KEY_INFO((PKCS8_PRIV_KEY_INFO**) NULL, &expectedTmp, + sizeof(TEST_EC_KEY_1))); Unique_EVP_PKEY expected(EVP_PKCS82PKEY(expectedPkcs8.get())); @@ -476,7 +608,7 @@ TEST_F(KeymasterTest, GetKeypairPublic_RSA_Success) { uint8_t* key_blob; size_t key_blob_length; - UniqueReadOnlyBlob testKey(TEST_KEY_1, sizeof(TEST_KEY_1)); + UniqueReadOnlyBlob testKey(TEST_RSA_KEY_1, sizeof(TEST_RSA_KEY_1)); ASSERT_TRUE(testKey.get() != NULL); ASSERT_EQ(0, @@ -494,7 +626,29 @@ TEST_F(KeymasterTest, GetKeypairPublic_RSA_Success) { UniqueBlob x509_blob(x509_data, x509_data_length); } -TEST_F(KeymasterTest, GetKeypairPublic_RSA_NullKey_Failure) { +TEST_F(KeymasterTest, GetKeypairPublic_EC_Success) { + uint8_t* key_blob; + size_t key_blob_length; + + UniqueReadOnlyBlob testKey(TEST_EC_KEY_1, sizeof(TEST_EC_KEY_1)); + ASSERT_TRUE(testKey.get() != NULL); + + ASSERT_EQ(0, + sDevice->import_keypair(sDevice, testKey.get(), testKey.length(), + &key_blob, &key_blob_length)) + << "Should successfully import an EC key"; + UniqueKey key(&sDevice, key_blob, key_blob_length); + + uint8_t* x509_data; + size_t x509_data_length; + ASSERT_EQ(0, + sDevice->get_keypair_public(sDevice, key_blob, key_blob_length, + &x509_data, &x509_data_length)) + << "Should be able to retrieve EC public key successfully"; + UniqueBlob x509_blob(x509_data, x509_data_length); +} + +TEST_F(KeymasterTest, GetKeypairPublic_NullKey_Failure) { uint8_t* key_blob; size_t key_blob_length; @@ -503,7 +657,7 @@ TEST_F(KeymasterTest, GetKeypairPublic_RSA_NullKey_Failure) { ASSERT_EQ(-1, sDevice->get_keypair_public(sDevice, NULL, 0, &x509_data, &x509_data_length)) - << "Should not be able to retrieve RSA public key from null key"; + << "Should not be able to retrieve public key from null key"; UniqueBlob x509_blob(x509_data, x509_data_length); } @@ -511,7 +665,26 @@ TEST_F(KeymasterTest, GetKeypairPublic_RSA_NullDestination_Failure) { uint8_t* key_blob; size_t key_blob_length; - UniqueReadOnlyBlob testKey(TEST_KEY_1, sizeof(TEST_KEY_1)); + UniqueReadOnlyBlob testKey(TEST_RSA_KEY_1, sizeof(TEST_RSA_KEY_1)); + ASSERT_TRUE(testKey.get() != NULL); + + ASSERT_EQ(0, + sDevice->import_keypair(sDevice, testKey.get(), testKey.length(), + &key_blob, &key_blob_length)) + << "Should successfully import an RSA key"; + UniqueKey key(&sDevice, key_blob, key_blob_length); + + ASSERT_EQ(-1, + sDevice->get_keypair_public(sDevice, key.get(), key.length(), + NULL, NULL)) + << "Should not be able to succeed with NULL destination blob"; +} + +TEST_F(KeymasterTest, GetKeypairPublic_EC_NullDestination_Failure) { + uint8_t* key_blob; + size_t key_blob_length; + + UniqueReadOnlyBlob testKey(TEST_EC_KEY_1, sizeof(TEST_EC_KEY_1)); ASSERT_TRUE(testKey.get() != NULL); ASSERT_EQ(0, @@ -530,7 +703,7 @@ TEST_F(KeymasterTest, DeleteKeyPair_RSA_Success) { uint8_t* key_blob; size_t key_blob_length; - UniqueReadOnlyBlob testKey(TEST_KEY_1, sizeof(TEST_KEY_1)); + UniqueReadOnlyBlob testKey(TEST_RSA_KEY_1, sizeof(TEST_RSA_KEY_1)); ASSERT_TRUE(testKey.get() != NULL); ASSERT_EQ(0, @@ -544,7 +717,7 @@ TEST_F(KeymasterTest, DeleteKeyPair_RSA_DoubleDelete_Failure) { uint8_t* key_blob; size_t key_blob_length; - UniqueReadOnlyBlob testKey(TEST_KEY_1, sizeof(TEST_KEY_1)); + UniqueReadOnlyBlob testKey(TEST_RSA_KEY_1, sizeof(TEST_RSA_KEY_1)); ASSERT_TRUE(testKey.get() != NULL); /* @@ -582,7 +755,7 @@ TEST_F(KeymasterTest, DeleteKeyPair_RSA_NullKey_Failure) { * * openssl genrsa 512 | openssl pkcs8 -topk8 -nocrypt -outform der | recode ../x1 */ -static uint8_t TEST_SIGN_KEY_1[] = { +static uint8_t TEST_SIGN_RSA_KEY_1[] = { 0x30, 0x82, 0x01, 0x56, 0x02, 0x01, 0x00, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x40, 0x30, 0x82, 0x01, 0x3C, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00, @@ -614,6 +787,26 @@ static uint8_t TEST_SIGN_KEY_1[] = { 0x68, 0x68, 0xC8, 0x60, 0xB3, 0x66, 0xC8, 0xF9, 0x08, 0x9A, }; +/* + * DER-encoded PKCS#8 format EC key. Generated using: + * + * openssl ecparam -name prime256v1 -genkey -noout | openssl pkcs8 -topk8 -nocrypt -outform der | recode ../x1 + */ +static uint8_t TEST_SIGN_EC_KEY_1[] = { + 0x30, 0x81, 0x87, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, + 0x48, 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, + 0x03, 0x01, 0x07, 0x04, 0x6D, 0x30, 0x6B, 0x02, 0x01, 0x01, 0x04, 0x20, + 0x9E, 0x66, 0x11, 0x6A, 0x89, 0xF5, 0x78, 0x57, 0xF3, 0x35, 0xA2, 0x46, + 0x09, 0x06, 0x4B, 0x4D, 0x81, 0xEC, 0xD3, 0x9B, 0x0A, 0xC4, 0x68, 0x06, + 0xB8, 0x42, 0x24, 0x5E, 0x74, 0x2C, 0x62, 0x79, 0xA1, 0x44, 0x03, 0x42, + 0x00, 0x04, 0x35, 0xB5, 0x9A, 0x5C, 0xE5, 0x52, 0x35, 0xF2, 0x10, 0x6C, + 0xD9, 0x98, 0x67, 0xED, 0x5E, 0xCB, 0x6B, 0xB8, 0x96, 0x5E, 0x54, 0x7C, + 0x34, 0x2A, 0xA3, 0x3B, 0xF3, 0xD1, 0x39, 0x48, 0x36, 0x7A, 0xEA, 0xD8, + 0xCA, 0xDD, 0x40, 0x8F, 0xE9, 0xE0, 0x95, 0x2E, 0x3F, 0x95, 0x0F, 0x14, + 0xD6, 0x14, 0x78, 0xB5, 0xAD, 0x17, 0xD2, 0x5A, 0x41, 0x96, 0x99, 0x20, + 0xC7, 0x5B, 0x0F, 0x60, 0xFD, 0xBA +}; + /* * PKCS#1 v1.5 padded raw "Hello, world" Can be generated be generated by verifying * the signature below in no padding mode: @@ -630,11 +823,11 @@ static uint8_t TEST_SIGN_DATA_1[] = { }; /* - * Signature of TEST_SIGN_DATA_1 using TEST_SIGN_KEY_1. Generated using: + * Signature of TEST_SIGN_DATA_1 using TEST_SIGN_RSA_KEY_1. Generated using: * * echo 'Hello, world' | openssl rsautl -keyform der -inkey rsa.der -sign | recode ../x1 */ -static uint8_t TEST_SIGN_SIGNATURE_1[] = { +static uint8_t TEST_SIGN_RSA_SIGNATURE_1[] = { 0xA4, 0xBB, 0x76, 0x87, 0xFE, 0x61, 0x0C, 0x9D, 0xD6, 0xFF, 0x4B, 0x76, 0x96, 0x08, 0x36, 0x23, 0x11, 0xC6, 0x44, 0x3F, 0x88, 0x77, 0x97, 0xB2, 0xA8, 0x3B, 0xFB, 0x9C, 0x3C, 0xD3, 0x20, 0x65, 0xFD, 0x26, 0x3B, 0x2A, @@ -644,7 +837,7 @@ static uint8_t TEST_SIGN_SIGNATURE_1[] = { }; /* - * Identical to TEST_SIGN_SIGNATURE_1 except the last octet is '1' instead of '0' + * Identical to TEST_SIGN_RSA_SIGNATURE_1 except the last octet is '1' instead of '0' * This should fail any test. */ static uint8_t TEST_SIGN_SIGNATURE_BOGUS_1[] = { @@ -660,7 +853,7 @@ TEST_F(KeymasterTest, SignData_RSA_Raw_Success) { uint8_t* key_blob; size_t key_blob_length; - UniqueReadOnlyBlob testKey(TEST_SIGN_KEY_1, sizeof(TEST_SIGN_KEY_1)); + UniqueReadOnlyBlob testKey(TEST_SIGN_RSA_KEY_1, sizeof(TEST_SIGN_RSA_KEY_1)); ASSERT_TRUE(testKey.get() != NULL); ASSERT_EQ(0, @@ -687,7 +880,7 @@ TEST_F(KeymasterTest, SignData_RSA_Raw_Success) { << "Should sign data successfully"; UniqueBlob sig_blob(sig, sig_length); - UniqueBlob expected_sig(TEST_SIGN_SIGNATURE_1, sizeof(TEST_SIGN_SIGNATURE_1)); + UniqueBlob expected_sig(TEST_SIGN_RSA_SIGNATURE_1, sizeof(TEST_SIGN_RSA_SIGNATURE_1)); ASSERT_EQ(expected_sig, sig_blob) << "Generated signature should match expected signature"; @@ -696,11 +889,59 @@ TEST_F(KeymasterTest, SignData_RSA_Raw_Success) { uint8_t* unused __attribute__((unused)) = expected_sig.release(); } +TEST_F(KeymasterTest, SignData_EC_Success) { + uint8_t* key_blob; + size_t key_blob_length; + + UniqueReadOnlyBlob testKey(TEST_SIGN_EC_KEY_1, sizeof(TEST_SIGN_EC_KEY_1)); + ASSERT_TRUE(testKey.get() != NULL); + + ASSERT_EQ(0, + sDevice->import_keypair(sDevice, testKey.get(), testKey.length(), + &key_blob, &key_blob_length)) + << "Should successfully import an EC key"; + UniqueKey key(&sDevice, key_blob, key_blob_length); + + keymaster_ec_sign_params_t params = { + digest_type: DIGEST_NONE, + }; + + uint8_t* sig; + size_t sig_length; + + UniqueReadOnlyBlob testData(TEST_SIGN_DATA_1, sizeof(TEST_SIGN_DATA_1)); + ASSERT_TRUE(testData.get() != NULL); + + ASSERT_EQ(0, + sDevice->sign_data(sDevice, ¶ms, key_blob, key_blob_length, + testData.get(), testData.length(), + &sig, &sig_length)) + << "Should sign data successfully"; + UniqueBlob sig_blob(sig, sig_length); + + uint8_t* x509_data; + size_t x509_data_length; + ASSERT_EQ(0, + sDevice->get_keypair_public(sDevice, key_blob, key_blob_length, + &x509_data, &x509_data_length)) + << "Should be able to retrieve RSA public key successfully"; + UniqueBlob x509_blob(x509_data, x509_data_length); + + const unsigned char *tmp = static_cast(x509_blob.get()); + Unique_EVP_PKEY expected(d2i_PUBKEY((EVP_PKEY**) NULL, &tmp, + static_cast(x509_blob.length()))); + + Unique_EC_KEY ecKey(EVP_PKEY_get1_EC_KEY(expected.get())); + + ASSERT_EQ(1, ECDSA_verify(0, testData.get(), testData.length(), sig_blob.get(), sig_blob.length(), ecKey.get())) + << "Signature should verify"; +} + TEST_F(KeymasterTest, SignData_RSA_Raw_InvalidSizeInput_Failure) { uint8_t* key_blob; size_t key_blob_length; - UniqueReadOnlyBlob testKey(TEST_SIGN_KEY_1, sizeof(TEST_SIGN_KEY_1)); + UniqueReadOnlyBlob testKey(TEST_SIGN_RSA_KEY_1, sizeof(TEST_SIGN_RSA_KEY_1)); ASSERT_TRUE(testKey.get() != NULL); ASSERT_EQ(0, @@ -717,7 +958,7 @@ TEST_F(KeymasterTest, SignData_RSA_Raw_InvalidSizeInput_Failure) { uint8_t* sig; size_t sig_length; - UniqueReadOnlyBlob testData(TEST_KEY_1, sizeof(TEST_KEY_1)); + UniqueReadOnlyBlob testData(TEST_RSA_KEY_1, sizeof(TEST_RSA_KEY_1)); ASSERT_TRUE(testData.get() != NULL); ASSERT_EQ(-1, @@ -736,7 +977,7 @@ TEST_F(KeymasterTest, SignData_RSA_Raw_NullKey_Failure) { uint8_t* sig; size_t sig_length; - UniqueReadOnlyBlob testData(TEST_KEY_1, sizeof(TEST_KEY_1)); + UniqueReadOnlyBlob testData(TEST_RSA_KEY_1, sizeof(TEST_RSA_KEY_1)); ASSERT_TRUE(testData.get() != NULL); ASSERT_EQ(-1, @@ -750,7 +991,7 @@ TEST_F(KeymasterTest, SignData_RSA_Raw_NullInput_Failure) { uint8_t* key_blob; size_t key_blob_length; - UniqueReadOnlyBlob testKey(TEST_SIGN_KEY_1, sizeof(TEST_SIGN_KEY_1)); + UniqueReadOnlyBlob testKey(TEST_SIGN_RSA_KEY_1, sizeof(TEST_SIGN_RSA_KEY_1)); ASSERT_TRUE(testKey.get() != NULL); ASSERT_EQ(0, @@ -778,7 +1019,7 @@ TEST_F(KeymasterTest, SignData_RSA_Raw_NullOutput_Failure) { uint8_t* key_blob; size_t key_blob_length; - UniqueReadOnlyBlob testKey(TEST_SIGN_KEY_1, sizeof(TEST_SIGN_KEY_1)); + UniqueReadOnlyBlob testKey(TEST_SIGN_RSA_KEY_1, sizeof(TEST_SIGN_RSA_KEY_1)); ASSERT_TRUE(testKey.get() != NULL); ASSERT_EQ(0, @@ -795,7 +1036,7 @@ TEST_F(KeymasterTest, SignData_RSA_Raw_NullOutput_Failure) { uint8_t* sig; size_t sig_length; - UniqueReadOnlyBlob testData(TEST_KEY_1, sizeof(TEST_KEY_1)); + UniqueReadOnlyBlob testData(TEST_RSA_KEY_1, sizeof(TEST_RSA_KEY_1)); ASSERT_TRUE(testData.get() != NULL); ASSERT_EQ(-1, @@ -809,7 +1050,7 @@ TEST_F(KeymasterTest, VerifyData_RSA_Raw_Success) { uint8_t* key_blob; size_t key_blob_length; - UniqueReadOnlyBlob testKey(TEST_SIGN_KEY_1, sizeof(TEST_SIGN_KEY_1)); + UniqueReadOnlyBlob testKey(TEST_SIGN_RSA_KEY_1, sizeof(TEST_SIGN_RSA_KEY_1)); ASSERT_TRUE(testKey.get() != NULL); ASSERT_EQ(0, @@ -826,7 +1067,7 @@ TEST_F(KeymasterTest, VerifyData_RSA_Raw_Success) { UniqueReadOnlyBlob testData(TEST_SIGN_DATA_1, sizeof(TEST_SIGN_DATA_1)); ASSERT_TRUE(testData.get() != NULL); - UniqueReadOnlyBlob testSig(TEST_SIGN_SIGNATURE_1, sizeof(TEST_SIGN_SIGNATURE_1)); + UniqueReadOnlyBlob testSig(TEST_SIGN_RSA_SIGNATURE_1, sizeof(TEST_SIGN_RSA_SIGNATURE_1)); ASSERT_TRUE(testSig.get() != NULL); ASSERT_EQ(0, @@ -836,11 +1077,48 @@ TEST_F(KeymasterTest, VerifyData_RSA_Raw_Success) { << "Should verify data successfully"; } +TEST_F(KeymasterTest, VerifyData_EC_Raw_Success) { + uint8_t* key_blob; + size_t key_blob_length; + + UniqueReadOnlyBlob testKey(TEST_SIGN_EC_KEY_1, sizeof(TEST_SIGN_EC_KEY_1)); + ASSERT_TRUE(testKey.get() != NULL); + + ASSERT_EQ(0, + sDevice->import_keypair(sDevice, testKey.get(), testKey.length(), + &key_blob, &key_blob_length)) + << "Should successfully import an RSA key"; + UniqueKey key(&sDevice, key_blob, key_blob_length); + + keymaster_ec_sign_params_t params = { + digest_type: DIGEST_NONE, + }; + + uint8_t* sig; + size_t sig_length; + + UniqueReadOnlyBlob testData(TEST_SIGN_DATA_1, sizeof(TEST_SIGN_DATA_1)); + ASSERT_TRUE(testData.get() != NULL); + + ASSERT_EQ(0, + sDevice->sign_data(sDevice, ¶ms, key_blob, key_blob_length, + testData.get(), testData.length(), + &sig, &sig_length)) + << "Should sign data successfully"; + UniqueBlob sig_blob(sig, sig_length); + + ASSERT_EQ(0, + sDevice->verify_data(sDevice, ¶ms, key_blob, key_blob_length, + testData.get(), testData.length(), + sig_blob.get(), sig_blob.length())) + << "Should verify data successfully"; +} + TEST_F(KeymasterTest, VerifyData_RSA_Raw_BadSignature_Failure) { uint8_t* key_blob; size_t key_blob_length; - UniqueReadOnlyBlob testKey(TEST_SIGN_KEY_1, sizeof(TEST_SIGN_KEY_1)); + UniqueReadOnlyBlob testKey(TEST_SIGN_RSA_KEY_1, sizeof(TEST_SIGN_RSA_KEY_1)); ASSERT_TRUE(testKey.get() != NULL); ASSERT_EQ(0, @@ -861,6 +1139,30 @@ TEST_F(KeymasterTest, VerifyData_RSA_Raw_BadSignature_Failure) { << "Should sign data successfully"; } +TEST_F(KeymasterTest, VerifyData_EC_Raw_BadSignature_Failure) { + uint8_t* key_blob; + size_t key_blob_length; + + UniqueReadOnlyBlob testKey(TEST_SIGN_EC_KEY_1, sizeof(TEST_SIGN_EC_KEY_1)); + ASSERT_TRUE(testKey.get() != NULL); + + ASSERT_EQ(0, + sDevice->import_keypair(sDevice, testKey.get(), testKey.length(), + &key_blob, &key_blob_length)) + << "Should successfully import an RSA key"; + UniqueKey key(&sDevice, key_blob, key_blob_length); + + keymaster_ec_sign_params_t params = { + digest_type: DIGEST_NONE, + }; + + ASSERT_EQ(-1, + sDevice->verify_data(sDevice, ¶ms, key_blob, key_blob_length, + TEST_SIGN_DATA_1, sizeof(TEST_SIGN_DATA_1), + TEST_SIGN_SIGNATURE_BOGUS_1, sizeof(TEST_SIGN_SIGNATURE_BOGUS_1))) + << "Should sign data successfully"; +} + TEST_F(KeymasterTest, VerifyData_RSA_Raw_NullKey_Failure) { keymaster_rsa_sign_params_t params = { digest_type: DIGEST_NONE, @@ -885,7 +1187,7 @@ TEST_F(KeymasterTest, VerifyData_RSA_NullInput_Failure) { size_t key_blob_length; ASSERT_EQ(0, - sDevice->import_keypair(sDevice, TEST_SIGN_KEY_1, sizeof(TEST_SIGN_KEY_1), + sDevice->import_keypair(sDevice, TEST_SIGN_RSA_KEY_1, sizeof(TEST_SIGN_RSA_KEY_1), &key_blob, &key_blob_length)) << "Should successfully import an RSA key"; UniqueKey key(&sDevice, key_blob, key_blob_length); @@ -895,7 +1197,7 @@ TEST_F(KeymasterTest, VerifyData_RSA_NullInput_Failure) { padding_type: PADDING_NONE, }; - UniqueReadOnlyBlob testSig(TEST_SIGN_SIGNATURE_1, sizeof(TEST_SIGN_SIGNATURE_1)); + UniqueReadOnlyBlob testSig(TEST_SIGN_RSA_SIGNATURE_1, sizeof(TEST_SIGN_RSA_SIGNATURE_1)); ASSERT_TRUE(testSig.get() != NULL); ASSERT_EQ(-1, @@ -909,7 +1211,7 @@ TEST_F(KeymasterTest, VerifyData_RSA_NullSignature_Failure) { uint8_t* key_blob; size_t key_blob_length; - UniqueReadOnlyBlob testKey(TEST_SIGN_KEY_1, sizeof(TEST_SIGN_KEY_1)); + UniqueReadOnlyBlob testKey(TEST_SIGN_RSA_KEY_1, sizeof(TEST_SIGN_RSA_KEY_1)); ASSERT_TRUE(testKey.get() != NULL); ASSERT_EQ(0, @@ -942,7 +1244,7 @@ TEST_F(KeymasterTest, EraseAll_Success) { return; } - UniqueReadOnlyBlob testKey(TEST_SIGN_KEY_1, sizeof(TEST_SIGN_KEY_1)); + UniqueReadOnlyBlob testKey(TEST_SIGN_RSA_KEY_1, sizeof(TEST_SIGN_RSA_KEY_1)); ASSERT_TRUE(testKey.get() != NULL); ASSERT_EQ(0, @@ -951,7 +1253,7 @@ TEST_F(KeymasterTest, EraseAll_Success) { << "Should successfully import an RSA key"; UniqueKey key1(&sDevice, key1_blob, key1_blob_length); - UniqueReadOnlyBlob testKey2(TEST_SIGN_KEY_1, sizeof(TEST_SIGN_KEY_1)); + UniqueReadOnlyBlob testKey2(TEST_SIGN_RSA_KEY_1, sizeof(TEST_SIGN_RSA_KEY_1)); ASSERT_TRUE(testKey2.get() != NULL); ASSERT_EQ(0, -- cgit v1.2.3