diff options
author | Shawn Willden <swillden@google.com> | 2015-07-20 09:10:32 -0600 |
---|---|---|
committer | Shawn Willden <swillden@google.com> | 2015-07-28 12:57:24 -0600 |
commit | 5cf45028751471f79d9f8a390f64fe9412acd53a (patch) | |
tree | a08170f7f0934dacfcb8b550fba63528e7e6cf03 | |
parent | 3ac35814df71dce203c9b3cc1a937b178f7dc9c7 (diff) | |
download | android_system_keymaster-5cf45028751471f79d9f8a390f64fe9412acd53a.tar.gz android_system_keymaster-5cf45028751471f79d9f8a390f64fe9412acd53a.tar.bz2 android_system_keymaster-5cf45028751471f79d9f8a390f64fe9412acd53a.zip |
Make NONE mean NONE only (not ANY)
KM_DIGEST_NONE and KM_PAD_NONE have implicit meanings of "any digest"
and "any padding", respectively, as well as the expected meanings of "no
digest" and "no padding". This CL changes that so they mean only "no
digest" and "no padding".
Bug: 22556114
Change-Id: I7b0b4c079067d85ba1aa39ae7edf0c6b17a9a500
-rw-r--r-- | android_keymaster_test.cpp | 47 | ||||
-rw-r--r-- | include/keymaster/soft_keymaster_device.h | 13 | ||||
-rw-r--r-- | operation.cpp | 6 | ||||
-rw-r--r-- | soft_keymaster_context.cpp | 32 | ||||
-rw-r--r-- | soft_keymaster_device.cpp | 30 |
5 files changed, 91 insertions, 37 deletions
diff --git a/android_keymaster_test.cpp b/android_keymaster_test.cpp index 13ff796..7a9f1ae 100644 --- a/android_keymaster_test.cpp +++ b/android_keymaster_test.cpp @@ -544,17 +544,18 @@ TEST_P(SigningOperationsTest, RsaPssSha256Success) { EXPECT_EQ(3, GetParam()->keymaster0_calls()); } -TEST_P(SigningOperationsTest, RsaPaddingNoneAllowsOther) { +TEST_P(SigningOperationsTest, RsaPaddingNoneDoesNotAllowOther) { ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder() .RsaSigningKey(512, 3) .Digest(KM_DIGEST_NONE) .Padding(KM_PAD_NONE))); string message = "12345678901234567890123456789012"; string signature; - SignMessage(message, &signature, KM_DIGEST_SHA_2_256, KM_PAD_RSA_PSS); - if (GetParam()->algorithm_in_hardware(KM_ALGORITHM_RSA)) - EXPECT_EQ(3, GetParam()->keymaster0_calls()); + AuthorizationSet begin_params(client_params()); + begin_params.push_back(TAG_DIGEST, KM_DIGEST_NONE); + begin_params.push_back(TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_SIGN); + EXPECT_EQ(KM_ERROR_INCOMPATIBLE_PADDING_MODE, BeginOperation(KM_PURPOSE_SIGN, begin_params)); } TEST_P(SigningOperationsTest, RsaPkcs1Sha256Success) { @@ -868,6 +869,20 @@ TEST_P(SigningOperationsTest, HmacSha512Success) { ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder() .HmacKey(128) .Digest(KM_DIGEST_SHA_2_512) + .Authorization(TAG_MIN_MAC_LENGTH, 384))); + string message = "12345678901234567890123456789012"; + string signature; + MacMessage(message, &signature, 512); + ASSERT_EQ(64U, signature.size()); + + EXPECT_EQ(0, GetParam()->keymaster0_calls()); +} + +TEST_P(SigningOperationsTest, HmacLengthInKey) { + // TODO(swillden): unified API should generate an error on key generation. + ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder() + .HmacKey(128) + .Digest(KM_DIGEST_SHA_2_512) .Authorization(TAG_MIN_MAC_LENGTH, 512))); string message = "12345678901234567890123456789012"; string signature; @@ -2256,13 +2271,13 @@ TEST_P(EncryptionOperationsTest, AesEcbNoPaddingKeyWithPkcs7Padding) { .Authorization(TAG_BLOCK_MODE, KM_MODE_ECB) .Authorization(TAG_PADDING, KM_PAD_NONE))); - // Try various message lengths; all should work. + // Try various message lengths; all should fail. for (size_t i = 0; i < 32; ++i) { - string message(i, 'a'); - string ciphertext = EncryptMessage(message, KM_MODE_ECB, KM_PAD_PKCS7); - EXPECT_EQ(i + 16 - (i % 16), ciphertext.size()); - string plaintext = DecryptMessage(ciphertext, KM_MODE_ECB, KM_PAD_PKCS7); - EXPECT_EQ(message, plaintext); + AuthorizationSet begin_params(client_params()); + begin_params.push_back(TAG_BLOCK_MODE, KM_MODE_ECB); + begin_params.push_back(TAG_PADDING, KM_PAD_PKCS7); + EXPECT_EQ(KM_ERROR_INCOMPATIBLE_PADDING_MODE, + BeginOperation(KM_PURPOSE_ENCRYPT, begin_params)); } EXPECT_EQ(0, GetParam()->keymaster0_calls()); @@ -3259,8 +3274,18 @@ TEST_P(Keymaster0AdapterTest, OldHwKeymaster0RsaBlobGetCharacteristics) { EXPECT_TRUE(contains(hw_enforced(), TAG_KEY_SIZE, 512)); EXPECT_TRUE(contains(hw_enforced(), TAG_RSA_PUBLIC_EXPONENT, 3)); EXPECT_TRUE(contains(hw_enforced(), TAG_DIGEST, KM_DIGEST_NONE)); + EXPECT_TRUE(contains(hw_enforced(), TAG_DIGEST, KM_DIGEST_MD5)); + EXPECT_TRUE(contains(hw_enforced(), TAG_DIGEST, KM_DIGEST_SHA1)); + EXPECT_TRUE(contains(hw_enforced(), TAG_DIGEST, KM_DIGEST_SHA_2_224)); + EXPECT_TRUE(contains(hw_enforced(), TAG_DIGEST, KM_DIGEST_SHA_2_256)); + EXPECT_TRUE(contains(hw_enforced(), TAG_DIGEST, KM_DIGEST_SHA_2_384)); + EXPECT_TRUE(contains(hw_enforced(), TAG_DIGEST, KM_DIGEST_SHA_2_512)); EXPECT_TRUE(contains(hw_enforced(), TAG_PADDING, KM_PAD_NONE)); - EXPECT_EQ(5U, hw_enforced().size()); + EXPECT_TRUE(contains(hw_enforced(), TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_ENCRYPT)); + EXPECT_TRUE(contains(hw_enforced(), TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_SIGN)); + EXPECT_TRUE(contains(hw_enforced(), TAG_PADDING, KM_PAD_RSA_OAEP)); + EXPECT_TRUE(contains(hw_enforced(), TAG_PADDING, KM_PAD_RSA_PSS)); + EXPECT_EQ(15U, hw_enforced().size()); EXPECT_TRUE(contains(sw_enforced(), TAG_PURPOSE, KM_PURPOSE_SIGN)); EXPECT_TRUE(contains(sw_enforced(), TAG_PURPOSE, KM_PURPOSE_VERIFY)); diff --git a/include/keymaster/soft_keymaster_device.h b/include/keymaster/soft_keymaster_device.h index f2ffb68..86ad260 100644 --- a/include/keymaster/soft_keymaster_device.h +++ b/include/keymaster/soft_keymaster_device.h @@ -70,7 +70,8 @@ class SoftKeymasterDevice { private: void initialize(keymaster0_device_t* keymaster0_device); - static void StoreDefaultNewKeyParams(AuthorizationSet* auth_set); + static void StoreDefaultNewKeyParams(keymaster_algorithm_t algorithm, + AuthorizationSet* auth_set); static keymaster_error_t GetPkcs8KeyAlgorithm(const uint8_t* key, size_t key_length, keymaster_algorithm_t* algorithm); @@ -159,12 +160,10 @@ class SoftKeymasterDevice { const keymaster_key_param_set_t* in_params, keymaster_key_param_set_t* out_params, keymaster_operation_handle_t* operation_handle); - static keymaster_error_t update(const keymaster1_device_t* dev, - keymaster_operation_handle_t operation_handle, - const keymaster_key_param_set_t* in_params, - const keymaster_blob_t* input, size_t* input_consumed, - keymaster_key_param_set_t* out_params, - keymaster_blob_t* output); + static keymaster_error_t + update(const keymaster1_device_t* dev, keymaster_operation_handle_t operation_handle, + const keymaster_key_param_set_t* in_params, const keymaster_blob_t* input, + size_t* input_consumed, keymaster_key_param_set_t* out_params, keymaster_blob_t* output); static keymaster_error_t finish(const keymaster1_device_t* dev, keymaster_operation_handle_t operation_handle, const keymaster_key_param_set_t* in_params, const keymaster_blob_t* signature, diff --git a/operation.cpp b/operation.cpp index 477b71b..686b99c 100644 --- a/operation.cpp +++ b/operation.cpp @@ -97,9 +97,6 @@ bool OperationFactory::GetAndValidatePadding(const AuthorizationSet& begin_param } else if ( // If it's a public key operation, all padding modes are authorized. !is_public_key_operation() && - // If key contains KM_PAD_NONE, all padding modes are authorized. - !key.authorizations().Contains(TAG_PADDING, KM_PAD_NONE) && - !key.authorizations().Contains(TAG_PADDING_OLD, KM_PAD_NONE) && // Otherwise the key needs to authorize the specific mode. !key.authorizations().Contains(TAG_PADDING, *padding) && !key.authorizations().Contains(TAG_PADDING_OLD, *padding)) { @@ -125,9 +122,6 @@ bool OperationFactory::GetAndValidateDigest(const AuthorizationSet& begin_params } else if ( // If it's a public key operation, all digests are authorized. !is_public_key_operation() && - // If key contains KM_DIGEST_NONE, all digests are authorized. - !key.authorizations().Contains(TAG_DIGEST, KM_DIGEST_NONE) && - !key.authorizations().Contains(TAG_DIGEST_OLD, KM_DIGEST_NONE) && // Otherwise the key needs to authorize the specific digest. !key.authorizations().Contains(TAG_DIGEST, *digest) && !key.authorizations().Contains(TAG_DIGEST_OLD, *digest)) { diff --git a/soft_keymaster_context.cpp b/soft_keymaster_context.cpp index e2ef6de..3e5fc35 100644 --- a/soft_keymaster_context.cpp +++ b/soft_keymaster_context.cpp @@ -351,12 +351,27 @@ keymaster_error_t SoftKeymasterContext::FakeKeyAuthorizations(EVP_PKEY* pubkey, hw_enforced->Clear(); sw_enforced->Clear(); - // It does; build auth sets switch (EVP_PKEY_type(pubkey->type)) { case EVP_PKEY_RSA: { hw_enforced->push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA); hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_NONE); + hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_MD5); + hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA1); + hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_224); + hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_256); + hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_384); + hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_512); hw_enforced->push_back(TAG_PADDING, KM_PAD_NONE); + hw_enforced->push_back(TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_SIGN); + hw_enforced->push_back(TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_ENCRYPT); + hw_enforced->push_back(TAG_PADDING, KM_PAD_RSA_PSS); + hw_enforced->push_back(TAG_PADDING, KM_PAD_RSA_OAEP); + + sw_enforced->push_back(TAG_PURPOSE, KM_PURPOSE_SIGN); + sw_enforced->push_back(TAG_PURPOSE, KM_PURPOSE_VERIFY); + sw_enforced->push_back(TAG_PURPOSE, KM_PURPOSE_ENCRYPT); + sw_enforced->push_back(TAG_PURPOSE, KM_PURPOSE_DECRYPT); + unique_ptr<RSA, RSA_Delete> rsa(EVP_PKEY_get1_RSA(pubkey)); if (!rsa) return TranslateLastOpenSslError(); @@ -371,6 +386,16 @@ keymaster_error_t SoftKeymasterContext::FakeKeyAuthorizations(EVP_PKEY* pubkey, case EVP_PKEY_EC: { hw_enforced->push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA); hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_NONE); + hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_MD5); + hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA1); + hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_224); + hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_256); + hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_384); + hw_enforced->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_512); + + sw_enforced->push_back(TAG_PURPOSE, KM_PURPOSE_SIGN); + sw_enforced->push_back(TAG_PURPOSE, KM_PURPOSE_VERIFY); + UniquePtr<EC_KEY, EC_Delete> ec_key(EVP_PKEY_get1_EC_KEY(pubkey)); if (!ec_key.get()) return TranslateLastOpenSslError(); @@ -387,13 +412,8 @@ keymaster_error_t SoftKeymasterContext::FakeKeyAuthorizations(EVP_PKEY* pubkey, return KM_ERROR_UNSUPPORTED_ALGORITHM; } - sw_enforced->push_back(TAG_PURPOSE, KM_PURPOSE_SIGN); - sw_enforced->push_back(TAG_PURPOSE, KM_PURPOSE_VERIFY); sw_enforced->push_back(TAG_ALL_USERS); sw_enforced->push_back(TAG_NO_AUTH_REQUIRED); - uint64_t now = java_time(time(NULL)); - sw_enforced->push_back(TAG_CREATION_DATETIME, now); - sw_enforced->push_back(TAG_ORIGINATION_EXPIRE_DATETIME, now + HUNDRED_YEARS); return KM_ERROR_OK; } diff --git a/soft_keymaster_device.cpp b/soft_keymaster_device.cpp index 69499e5..e1d9090 100644 --- a/soft_keymaster_device.cpp +++ b/soft_keymaster_device.cpp @@ -187,11 +187,11 @@ int SoftKeymasterDevice::generate_keypair(const keymaster1_device_t* dev, return KM_ERROR_OUTPUT_PARAMETER_NULL; GenerateKeyRequest req; - StoreDefaultNewKeyParams(&req.key_description); switch (key_type) { case TYPE_RSA: { req.key_description.push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA); + StoreDefaultNewKeyParams(KM_ALGORITHM_RSA, &req.key_description); const keymaster_rsa_keygen_params_t* rsa_params = static_cast<const keymaster_rsa_keygen_params_t*>(key_params); LOG_D("Generating RSA pair, modulus size: %u, public exponent: %lu", @@ -203,6 +203,7 @@ int SoftKeymasterDevice::generate_keypair(const keymaster1_device_t* dev, case TYPE_EC: { req.key_description.push_back(TAG_ALGORITHM, KM_ALGORITHM_EC); + StoreDefaultNewKeyParams(KM_ALGORITHM_EC, &req.key_description); const keymaster_ec_keygen_params_t* ec_params = static_cast<const keymaster_ec_keygen_params_t*>(key_params); LOG_D("Generating ECDSA pair, key size: %u", ec_params->field_size); @@ -247,12 +248,12 @@ int SoftKeymasterDevice::import_keypair(const keymaster1_device_t* dev, const ui return KM_ERROR_OUTPUT_PARAMETER_NULL; ImportKeyRequest request; - StoreDefaultNewKeyParams(&request.key_description); keymaster_algorithm_t algorithm; keymaster_error_t err = GetPkcs8KeyAlgorithm(key, key_length, &algorithm); if (err != KM_ERROR_OK) return err; request.key_description.push_back(TAG_ALGORITHM, algorithm); + StoreDefaultNewKeyParams(algorithm, &request.key_description); request.SetKeyMaterial(key, key_length); request.key_format = KM_KEY_FORMAT_PKCS8; @@ -943,16 +944,31 @@ keymaster_error_t SoftKeymasterDevice::abort(const keymaster1_device_t* dev, } /* static */ -void SoftKeymasterDevice::StoreDefaultNewKeyParams(AuthorizationSet* auth_set) { +void SoftKeymasterDevice::StoreDefaultNewKeyParams(keymaster_algorithm_t algorithm, + AuthorizationSet* auth_set) { auth_set->push_back(TAG_PURPOSE, KM_PURPOSE_SIGN); auth_set->push_back(TAG_PURPOSE, KM_PURPOSE_VERIFY); auth_set->push_back(TAG_ALL_USERS); auth_set->push_back(TAG_NO_AUTH_REQUIRED); - uint64_t now = java_time(time(NULL)); - auth_set->push_back(TAG_CREATION_DATETIME, now); - auth_set->push_back(TAG_ORIGINATION_EXPIRE_DATETIME, now + HUNDRED_YEARS); + + // All digests. auth_set->push_back(TAG_DIGEST, KM_DIGEST_NONE); - auth_set->push_back(TAG_PADDING, KM_PAD_NONE); + auth_set->push_back(TAG_DIGEST, KM_DIGEST_MD5); + auth_set->push_back(TAG_DIGEST, KM_DIGEST_SHA1); + auth_set->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_224); + auth_set->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_256); + auth_set->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_384); + auth_set->push_back(TAG_DIGEST, KM_DIGEST_SHA_2_512); + + if (algorithm == KM_ALGORITHM_RSA) { + auth_set->push_back(TAG_PURPOSE, KM_PURPOSE_ENCRYPT); + auth_set->push_back(TAG_PURPOSE, KM_PURPOSE_DECRYPT); + auth_set->push_back(TAG_PADDING, KM_PAD_NONE); + auth_set->push_back(TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_SIGN); + auth_set->push_back(TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_ENCRYPT); + auth_set->push_back(TAG_PADDING, KM_PAD_RSA_PSS); + auth_set->push_back(TAG_PADDING, KM_PAD_RSA_OAEP); + } } } // namespace keymaster |