diff options
Diffstat (limited to 'keymaster0_engine.cpp')
| -rw-r--r-- | keymaster0_engine.cpp | 25 |
1 files changed, 23 insertions, 2 deletions
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) { |
