diff options
author | Shawn Willden <swillden@google.com> | 2015-06-20 09:16:30 -0600 |
---|---|---|
committer | Shawn Willden <swillden@google.com> | 2015-06-22 15:34:23 -0600 |
commit | 0f906ec40f6ade7955c6b967ea522aade54ea2e4 (patch) | |
tree | 17593f61259b566713e099fe750668281b35d444 /ocb_utils.cpp | |
parent | b5508298cdb1d42eaf8c81aa8a6ac2cbfdeef3c7 (diff) | |
download | android_system_keymaster-0f906ec40f6ade7955c6b967ea522aade54ea2e4.tar.gz android_system_keymaster-0f906ec40f6ade7955c6b967ea522aade54ea2e4.tar.bz2 android_system_keymaster-0f906ec40f6ade7955c6b967ea522aade54ea2e4.zip |
Add buffer wrap checks and disable throwing of std::bad_alloc.
Android is built with exceptions disabled, but "operator new" and
"operator new[]" still throw std::bad_alloc on failure rather than
returning new. In general this is a good thing, because it will cause
an immediate crash of the process rather than assigning a null pointer
which is probably not checked. But most memory allocations in Keymaster
are checked, because it's written to run in an environment where new
does *not* throw. This CL updates the code to explicitly use the
non-throwing new.
A handful of throwing news remain, but only in places where a crash on
failure is appropriate.
In addition, this CL also inserts buffer wrap checks in key locations
and changes the development-machine Makefile to build in 32-bit mode, to
make memory problems more apparent.
Bug: 21888473
Change-Id: I8ebc5ec12053e4f5274f6f57ce312abc10611cef
Diffstat (limited to 'ocb_utils.cpp')
-rw-r--r-- | ocb_utils.cpp | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/ocb_utils.cpp b/ocb_utils.cpp index 171d07e..7038da0 100644 --- a/ocb_utils.cpp +++ b/ocb_utils.cpp @@ -18,6 +18,8 @@ #include <assert.h> +#include <new> + #include <openssl/aes.h> #include <openssl/sha.h> @@ -50,7 +52,7 @@ static keymaster_error_t BuildDerivationData(const AuthorizationSet& hw_enforced size_t* derivation_data_length) { *derivation_data_length = hidden.SerializedSize() + hw_enforced.SerializedSize() + sw_enforced.SerializedSize(); - derivation_data->reset(new uint8_t[*derivation_data_length]); + derivation_data->reset(new (std::nothrow) uint8_t[*derivation_data_length]); if (!derivation_data->get()) return KM_ERROR_MEMORY_ALLOCATION_FAILED; @@ -76,9 +78,13 @@ static keymaster_error_t InitializeKeyWrappingContext(const AuthorizationSet& hw return error; SHA256_CTX sha256_ctx; - UniquePtr<uint8_t[]> hash_buf(new uint8_t[SHA256_DIGEST_LENGTH]); + UniquePtr<uint8_t[]> hash_buf(new (std::nothrow) uint8_t[SHA256_DIGEST_LENGTH]); + if (!hash_buf.get()) + return KM_ERROR_MEMORY_ALLOCATION_FAILED; Eraser hash_eraser(hash_buf.get(), SHA256_DIGEST_LENGTH); - UniquePtr<uint8_t[]> derived_key(new uint8_t[AES_BLOCK_SIZE]); + UniquePtr<uint8_t[]> derived_key(new (std::nothrow) uint8_t[AES_BLOCK_SIZE]); + if (!derived_key.get()) + return KM_ERROR_MEMORY_ALLOCATION_FAILED; Eraser derived_key_eraser(derived_key.get(), AES_BLOCK_SIZE); if (!ctx->get() || !hash_buf.get() || !derived_key.get()) @@ -120,13 +126,15 @@ keymaster_error_t OcbEncryptKey(const AuthorizationSet& hw_enforced, return KM_ERROR_INVALID_ARGUMENT; AeCtx ctx; + if (!ctx.get()) + return KM_ERROR_MEMORY_ALLOCATION_FAILED; + keymaster_error_t error = InitializeKeyWrappingContext(hw_enforced, sw_enforced, hidden, master_key, &ctx); if (error != KM_ERROR_OK) return error; - ciphertext->Reset(plaintext.key_material_size); - if (!ciphertext->key_material) + if (!ciphertext->Reset(plaintext.key_material_size)) return KM_ERROR_MEMORY_ALLOCATION_FAILED; int ae_err = ae_encrypt(ctx.get(), nonce.peek_read(), plaintext.key_material, @@ -137,7 +145,8 @@ keymaster_error_t OcbEncryptKey(const AuthorizationSet& hw_enforced, LOG_E("Error %d while encrypting key", ae_err); return KM_ERROR_UNKNOWN_ERROR; } - tag->advance_write(OCB_TAG_LENGTH); + if (!tag->advance_write(OCB_TAG_LENGTH)) + return KM_ERROR_UNKNOWN_ERROR; assert(ae_err == static_cast<int>(plaintext.key_material_size)); return KM_ERROR_OK; } @@ -153,13 +162,15 @@ keymaster_error_t OcbDecryptKey(const AuthorizationSet& hw_enforced, return KM_ERROR_INVALID_ARGUMENT; AeCtx ctx; + if (!ctx.get()) + return KM_ERROR_MEMORY_ALLOCATION_FAILED; + keymaster_error_t error = InitializeKeyWrappingContext(hw_enforced, sw_enforced, hidden, master_key, &ctx); if (error != KM_ERROR_OK) return error; - plaintext->Reset(ciphertext.key_material_size); - if (!plaintext->key_material) + if (!plaintext->Reset(ciphertext.key_material_size)) return KM_ERROR_MEMORY_ALLOCATION_FAILED; int ae_err = ae_decrypt(ctx.get(), nonce.peek_read(), ciphertext.key_material, |