diff options
author | Steve Kondik <steve@cyngn.com> | 2015-12-08 03:25:28 -0800 |
---|---|---|
committer | Steve Kondik <steve@cyngn.com> | 2015-12-08 03:25:28 -0800 |
commit | 9f57b4677e87c42cb47939c28e3cabeac19e0d67 (patch) | |
tree | e853546fbe63e8e96df47be8d12fc2fea5c7c99a | |
parent | 18b04441a40a728bf0b7578d89ff7603b7b21f44 (diff) | |
parent | 39ba76dc0fd9f516d8bcd76cf2d6251206316811 (diff) | |
download | android_system_keymaster-stable/cm-13.0-ZNH0E.tar.gz android_system_keymaster-stable/cm-13.0-ZNH0E.tar.bz2 android_system_keymaster-stable/cm-13.0-ZNH0E.zip |
Merge tag 'android-6.0.1_r3' of https://android.googlesource.com/platform/system/keymaster into HEADstable/cm-13.0-ZNH0E
Android 6.0.1 release 3
-rw-r--r-- | android_keymaster_test.cpp | 23 | ||||
-rw-r--r-- | keymaster0_engine.cpp | 25 | ||||
-rw-r--r-- | openssl_err.cpp | 3 |
3 files changed, 48 insertions, 3 deletions
diff --git a/android_keymaster_test.cpp b/android_keymaster_test.cpp index a340206..5fb3699 100644 --- a/android_keymaster_test.cpp +++ b/android_keymaster_test.cpp @@ -795,6 +795,29 @@ TEST_P(SigningOperationsTest, RsaSignWithEncryptionKey) { EXPECT_EQ(2, GetParam()->keymaster0_calls()); } +TEST_P(SigningOperationsTest, RsaSignTooLargeMessage) { + ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder() + .RsaSigningKey(256, 3) + .Digest(KM_DIGEST_NONE) + .Padding(KM_PAD_NONE))); + string message(256 / 8, static_cast<char>(0xff)); + string signature; + AuthorizationSet begin_params(client_params()); + begin_params.push_back(TAG_PADDING, KM_PAD_NONE); + begin_params.push_back(TAG_DIGEST, KM_DIGEST_NONE); + ASSERT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_SIGN, begin_params)); + string result; + size_t input_consumed; + ASSERT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed)); + ASSERT_EQ(message.size(), input_consumed); + string output; + ASSERT_EQ(KM_ERROR_INVALID_ARGUMENT, FinishOperation(&output)); + + + if (GetParam()->algorithm_in_km0_hardware(KM_ALGORITHM_RSA)) + EXPECT_EQ(3, GetParam()->keymaster0_calls()); +} + TEST_P(SigningOperationsTest, EcdsaSuccess) { ASSERT_EQ(KM_ERROR_OK, GenerateKey(AuthorizationSetBuilder().EcdsaSigningKey(224).Digest(KM_DIGEST_NONE))); diff --git a/keymaster0_engine.cpp b/keymaster0_engine.cpp index 995bc0b..70987f9 100644 --- a/keymaster0_engine.cpp +++ b/keymaster0_engine.cpp @@ -295,6 +295,15 @@ EVP_PKEY* Keymaster0Engine::GetKeymaster0PublicKey(const KeymasterKeyBlob& blob) return d2i_PUBKEY(nullptr /* allocate new struct */, &p, pub_key_data_length); } +static bool data_too_large_for_public_modulus(const uint8_t* data, size_t len, const RSA* rsa) { + unique_ptr<BIGNUM, BIGNUM_Delete> input_as_bn( + BN_bin2bn(data, len, nullptr /* allocate result */)); + return input_as_bn && BN_ucmp(input_as_bn.get(), rsa->n) >= 0; +} + +#define USER_F_private_transform 100 +#define USER_F_ecdsa_sign 101 + int Keymaster0Engine::RsaPrivateTransform(RSA* rsa, uint8_t* out, const uint8_t* in, size_t len) const { const keymaster_key_blob_t* key_blob = RsaKeyToBlob(rsa); @@ -306,8 +315,16 @@ int Keymaster0Engine::RsaPrivateTransform(RSA* rsa, uint8_t* out, const uint8_t* keymaster_rsa_sign_params_t sign_params = {DIGEST_NONE, PADDING_NONE}; unique_ptr<uint8_t[], Malloc_Delete> signature; size_t signature_length; - if (!Keymaster0Sign(&sign_params, *key_blob, in, len, &signature, &signature_length)) + if (!Keymaster0Sign(&sign_params, *key_blob, in, len, &signature, &signature_length)) { + if (data_too_large_for_public_modulus(in, len, rsa)) { + ALOGE("Keymaster0 signing failed because data is too large."); + OPENSSL_PUT_ERROR(RSA, private_transform, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + } else { + // We don't know what error code is correct; force an "unknown error" return + OPENSSL_PUT_ERROR(USER, private_transform, KM_ERROR_UNKNOWN_ERROR); + } return 0; + } Eraser eraser(signature.get(), signature_length); if (signature_length > len) { @@ -347,8 +364,12 @@ int Keymaster0Engine::EcdsaSign(const uint8_t* digest, size_t digest_len, uint8_ keymaster_ec_sign_params_t sign_params = {DIGEST_NONE}; unique_ptr<uint8_t[], Malloc_Delete> signature; size_t signature_length; - if (!Keymaster0Sign(&sign_params, *key_blob, digest, digest_len, &signature, &signature_length)) + if (!Keymaster0Sign(&sign_params, *key_blob, digest, digest_len, &signature, + &signature_length)) { + // We don't know what error code is correct; force an "unknown error" return + OPENSSL_PUT_ERROR(USER, ecdsa_sign, KM_ERROR_UNKNOWN_ERROR); return 0; + } Eraser eraser(signature.get(), signature_length); if (signature_length == 0) { diff --git a/openssl_err.cpp b/openssl_err.cpp index 51a29d9..df2920b 100644 --- a/openssl_err.cpp +++ b/openssl_err.cpp @@ -49,7 +49,8 @@ keymaster_error_t TranslateLastOpenSslError(bool log_message) { int reason = ERR_GET_REASON(error); switch (ERR_GET_LIB(error)) { - + case ERR_LIB_USER: + return static_cast<keymaster_error_t>(reason); case ERR_LIB_EVP: return TranslateEvpError(reason); #if defined(OPENSSL_IS_BORINGSSL) |