summaryrefslogtreecommitdiffstats
path: root/ocb_utils.cpp
diff options
context:
space:
mode:
authorShawn Willden <swillden@google.com>2015-06-20 09:16:30 -0600
committerShawn Willden <swillden@google.com>2015-06-22 15:34:23 -0600
commit0f906ec40f6ade7955c6b967ea522aade54ea2e4 (patch)
tree17593f61259b566713e099fe750668281b35d444 /ocb_utils.cpp
parentb5508298cdb1d42eaf8c81aa8a6ac2cbfdeef3c7 (diff)
downloadandroid_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.cpp27
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,