summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn Willden <swillden@google.com>2015-07-20 09:10:32 -0600
committerShawn Willden <swillden@google.com>2015-07-28 12:57:24 -0600
commit5cf45028751471f79d9f8a390f64fe9412acd53a (patch)
treea08170f7f0934dacfcb8b550fba63528e7e6cf03
parent3ac35814df71dce203c9b3cc1a937b178f7dc9c7 (diff)
downloadandroid_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.cpp47
-rw-r--r--include/keymaster/soft_keymaster_device.h13
-rw-r--r--operation.cpp6
-rw-r--r--soft_keymaster_context.cpp32
-rw-r--r--soft_keymaster_device.cpp30
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