diff options
author | Shawn Willden <swillden@google.com> | 2015-05-23 03:36:30 +0000 |
---|---|---|
committer | Shawn Willden <swillden@google.com> | 2015-05-23 03:36:30 +0000 |
commit | 13fbe3e93247943c26e7ca2ed27b6d650282b8bf (patch) | |
tree | cd71086d18f6eb1ffc47d7f8cc3d92346ba639c6 /include | |
parent | 8ba2a043f0d44ad3f58d4af518f9391c03eca9c3 (diff) | |
download | android_system_keymaster-13fbe3e93247943c26e7ca2ed27b6d650282b8bf.tar.gz android_system_keymaster-13fbe3e93247943c26e7ca2ed27b6d650282b8bf.tar.bz2 android_system_keymaster-13fbe3e93247943c26e7ca2ed27b6d650282b8bf.zip |
Revert "Large refactor to move context out of AndroidKeymaster."
This reverts commit 8ba2a043f0d44ad3f58d4af518f9391c03eca9c3.
I need to update the Volantis non-secure code in sync. Reverting while I get that done.
Change-Id: I0fb9f928e7e624ad678050a04bb873b43b1c9a48
Diffstat (limited to 'include')
-rw-r--r-- | include/keymaster/android_keymaster.h | 34 | ||||
-rw-r--r-- | include/keymaster/android_keymaster_utils.h | 94 | ||||
-rw-r--r-- | include/keymaster/key_blob.h | 130 | ||||
-rw-r--r-- | include/keymaster/keymaster_context.h | 110 | ||||
-rw-r--r-- | include/keymaster/serializable.h | 3 | ||||
-rw-r--r-- | include/keymaster/soft_keymaster_device.h | 3 |
6 files changed, 164 insertions, 210 deletions
diff --git a/include/keymaster/android_keymaster.h b/include/keymaster/android_keymaster.h index c7a3f41..7f8e65f 100644 --- a/include/keymaster/android_keymaster.h +++ b/include/keymaster/android_keymaster.h @@ -23,7 +23,7 @@ namespace keymaster { class Key; -class KeymasterContext; +class UnencryptedKeyBlob; class OperationTable; /** @@ -46,7 +46,7 @@ class OperationTable; */ class AndroidKeymaster { public: - AndroidKeymaster(KeymasterContext* context, size_t operation_table_size); + AndroidKeymaster(size_t operation_table_size); virtual ~AndroidKeymaster(); void SupportedAlgorithms(SupportedResponse<keymaster_algorithm_t>* response) const; @@ -61,7 +61,7 @@ class AndroidKeymaster { void SupportedExportFormats(keymaster_algorithm_t algorithm, SupportedResponse<keymaster_key_format_t>* response) const; - keymaster_error_t AddRngEntropy(const AddEntropyRequest& request); + virtual keymaster_error_t AddRngEntropy(const AddEntropyRequest& request) = 0; void GenerateKey(const GenerateKeyRequest& request, GenerateKeyResponse* response); void GetKeyCharacteristics(const GetKeyCharacteristicsRequest& request, GetKeyCharacteristicsResponse* response); @@ -74,12 +74,30 @@ class AndroidKeymaster { void GetVersion(const GetVersionRequest& request, GetVersionResponse* response); private: - keymaster_error_t LoadKey(const keymaster_key_blob_t& key_blob, - const AuthorizationSet& additional_params, - AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced, - keymaster_algorithm_t* algorithm, UniquePtr<Key>* key); + virtual bool is_enforced(keymaster_tag_t tag) = 0; + virtual bool is_hardware() = 0; + virtual keymaster_key_param_t RootOfTrustTag() = 0; + virtual keymaster_key_blob_t MasterKey() = 0; + virtual void GenerateNonce(uint8_t* nonce, size_t length) = 0; + + keymaster_error_t SerializeKey(const Key* key, keymaster_key_origin_t origin, + keymaster_key_blob_t* keymaster_blob, AuthorizationSet* enforced, + AuthorizationSet* unenforced); + Key* LoadKey(const keymaster_key_blob_t& key, const AuthorizationSet& client_params, + keymaster_algorithm_t* algorithm, keymaster_error_t* error); + UnencryptedKeyBlob* LoadKeyBlob(const keymaster_key_blob_t& key, + const AuthorizationSet& client_params, + keymaster_error_t* error); + + keymaster_error_t SetAuthorizations(const AuthorizationSet& key_description, + keymaster_key_origin_t origin, AuthorizationSet* enforced, + AuthorizationSet* unenforced); + keymaster_error_t BuildHiddenAuthorizations(const AuthorizationSet& input_set, + AuthorizationSet* hidden); + + void AddAuthorization(const keymaster_key_param_t& auth, AuthorizationSet* enforced, + AuthorizationSet* unenforced); - UniquePtr<KeymasterContext> context_; UniquePtr<OperationTable> operation_table_; }; diff --git a/include/keymaster/android_keymaster_utils.h b/include/keymaster/android_keymaster_utils.h index c636f5c..20afcdd 100644 --- a/include/keymaster/android_keymaster_utils.h +++ b/include/keymaster/android_keymaster_utils.h @@ -23,7 +23,6 @@ #include <UniquePtr.h> -#include <hardware/keymaster_defs.h> #include <keymaster/serializable.h> namespace keymaster { @@ -50,14 +49,14 @@ inline int64_t java_time(time_t time) { /** * Return the size in bytes of the array \p a. */ -template <typename T, size_t N> inline size_t array_size(const T(&a)[N]) { +template <typename T, size_t N> inline size_t array_size(const T (&a)[N]) { return sizeof(a); } /** * Return the number of elements in array \p a. */ -template <typename T, size_t N> inline size_t array_length(const T(&)[N]) { +template <typename T, size_t N> inline size_t array_length(const T (&)[N]) { return N; } @@ -78,7 +77,7 @@ template <typename T> inline T* dup_array(const T* a, size_t n) { * responsibility. Note that the dup is necessarily returned as a pointer, so size is lost. Call * array_length() on the original array to discover the size. */ -template <typename T, size_t N> inline T* dup_array(const T(&a)[N]) { +template <typename T, size_t N> inline T* dup_array(const T (&a)[N]) { return dup_array(a, N); } @@ -91,7 +90,7 @@ uint8_t* dup_buffer(const void* buf, size_t size); /** * Copy the contents of array \p arr to \p dest. */ -template <typename T, size_t N> inline void copy_array(const T(&arr)[N], T* dest) { +template <typename T, size_t N> inline void copy_array(const T (&arr)[N], T* dest) { for (size_t i = 0; i < N; ++i) dest[i] = arr[i]; } @@ -101,7 +100,7 @@ template <typename T, size_t N> inline void copy_array(const T(&arr)[N], T* dest * early-exit, meaning that it should not be used in contexts where timing analysis attacks could be * a concern. */ -template <typename T, size_t N> inline bool array_contains(const T(&a)[N], T val) { +template <typename T, size_t N> inline bool array_contains(const T (&a)[N], T val) { for (size_t i = 0; i < N; ++i) { if (a[i] == val) { return true; @@ -145,9 +144,9 @@ class Eraser { template <typename T> explicit Eraser(T& t) - : buf_(reinterpret_cast<uint8_t*>(&t)), size_(sizeof(t)) {} + : buf_(reinterpret_cast<uint8_t*> (&t)), size_(sizeof(t)) {} - template <size_t N> explicit Eraser(uint8_t(&arr)[N]) : buf_(arr), size_(N) {} + template <size_t N> explicit Eraser(uint8_t (&arr)[N]) : buf_(arr), size_(N) {} Eraser(void* buf, size_t size) : buf_(static_cast<uint8_t*>(buf)), size_(size) {} ~Eraser() { memset_s(buf_, 0, size_); } @@ -207,85 +206,6 @@ template <typename T> T hton(T t) { return retval; } -/** - * KeymasterKeyBlob is a very simple extension of the C struct keymaster_key_blob_t. It manages its - * own memory, which makes avoiding memory leaks much easier. - */ -struct KeymasterKeyBlob : public keymaster_key_blob_t { - KeymasterKeyBlob() { - key_material = nullptr; - key_material_size = 0; - } - - KeymasterKeyBlob(const uint8_t* data, size_t size) { - key_material = dup_buffer(data, size); - key_material_size = size; - } - - explicit KeymasterKeyBlob(size_t size) { - key_material = new uint8_t[size]; - key_material_size = size; - } - - explicit KeymasterKeyBlob(const keymaster_key_blob_t& blob) { - key_material = dup_buffer(blob.key_material, blob.key_material_size); - key_material_size = blob.key_material_size; - } - - KeymasterKeyBlob(const KeymasterKeyBlob& blob) { - key_material = dup_buffer(blob.key_material, blob.key_material_size); - key_material_size = blob.key_material_size; - } - - ~KeymasterKeyBlob() { Clear(); } - - const uint8_t* begin() const { return key_material; } - const uint8_t* end() const { return key_material + key_material_size; } - - void Clear() { - memset_s(const_cast<uint8_t*>(key_material), 0, key_material_size); - delete[] key_material; - key_material = nullptr; - key_material_size = 0; - } - - const uint8_t* Reset(size_t new_size) { - Clear(); - key_material = new uint8_t[new_size]; - key_material_size = new_size; - return key_material; - } - - // The key_material in keymaster_key_blob_t is const, which is the right thing in most - // circumstances, but occasionally we do need to write into it. This method exposes a non-const - // version of the pointer. Use sparingly. - uint8_t* writable_data() { return const_cast<uint8_t*>(key_material); } - - keymaster_key_blob_t release() { - keymaster_key_blob_t tmp = {key_material, key_material_size}; - key_material = nullptr; - key_material_size = 0; - return tmp; - } - - size_t SerializedSize() const { return sizeof(uint32_t) + key_material_size; } - uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const { - return append_size_and_data_to_buf(buf, end, key_material, key_material_size); - } - - bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) { - Clear(); - UniquePtr<uint8_t[]> tmp; - if (!copy_size_and_data_from_buf(buf_ptr, end, &key_material_size, &tmp)) { - key_material = nullptr; - key_material_size = 0; - return false; - } - key_material = tmp.release(); - return true; - } -}; - } // namespace keymaster #endif // SYSTEM_KEYMASTER_ANDROID_KEYMASTER_UTILS_H_ diff --git a/include/keymaster/key_blob.h b/include/keymaster/key_blob.h new file mode 100644 index 0000000..b2a3778 --- /dev/null +++ b/include/keymaster/key_blob.h @@ -0,0 +1,130 @@ +/* + * Copyright 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SYSTEM_KEYMASTER_KEY_BLOB_H_ +#define SYSTEM_KEYMASTER_KEY_BLOB_H_ + +#include <cstddef> + +#include <stdint.h> + +#include <UniquePtr.h> + +#include <hardware/keymaster_defs.h> +#include <keymaster/android_keymaster_utils.h> +#include <keymaster/authorization_set.h> +#include <keymaster/serializable.h> + +namespace keymaster { + +/** + * This class represents a Keymaster key blob, including authorization sets and encrypted key + * material. It serializes and deserializes blob arrays, and provides access to the data in the + * blob. + */ +class KeyBlob : public Serializable { + public: + static const size_t NONCE_LENGTH = 12; + static const size_t TAG_LENGTH = 128 / 8; + + /** + * Create a KeyBlob, extracting the enforced and unenforced sets. The KeyBlob does *not* take + * ownership of \p key_blob. + * + * IMPORTANT: After constructing a KeyBlob, call error() to verify that the blob is usable. + */ + KeyBlob(const uint8_t* key_blob, size_t key_blob_length); + + /** + * Create a KeyBlob, extracting the enforced and unenforced sets. The KeyBlob does *not* take + * ownership of \p key_blob's contents. + * + * IMPORTANT: After constructing a KeyBlob, call error() to verify that the blob is usable. + */ + KeyBlob(const keymaster_key_blob_t& key_blob); + + ~KeyBlob() { + ClearKeyData(); + // AuthorizationSets clear themselves. + } + + size_t SerializedSize() const; + uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const; + bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end); + + /** + * Returns KM_ERROR_OK if all is well, or an appropriate error code if there is a problem. This + * error code should be checked after construction or deserialization, and if it does not return + * KM_ERROR_OK, then don't call any other methods. + */ + inline keymaster_error_t error() { return error_; } + + inline const uint8_t* nonce() const { return nonce_.get(); } + inline const uint8_t* encrypted_key_material() const { return encrypted_key_material_.get(); } + inline size_t key_material_length() const { return key_material_length_; } + inline const uint8_t* tag() const { return tag_.get(); } + + inline const AuthorizationSet& enforced() const { return enforced_; } + inline const AuthorizationSet& unenforced() const { return unenforced_; } + inline keymaster_algorithm_t algorithm() const { return algorithm_; } + inline size_t key_size_bits() const { return key_size_bits_; } + keymaster_key_origin_t origin() const; + bool is_hardware() const; + + protected: + /** + * Create a KeyBlob containing the specified authorization data. + * + * IMPORTANT: After constructing a KeyBlob, call error() to verify that the blob is usable. + */ + KeyBlob(const AuthorizationSet& enforced, const AuthorizationSet& unenforced); + + /** + * Set encrypted key and supporting nonce and tag. Takes ownership of all arguments. + */ + void SetEncryptedKey(uint8_t* encrypted_key_material, size_t encrypted_key_material_length, + uint8_t* nonce, uint8_t* tag); + + keymaster_error_t error_; + + private: + void ClearKeyData() { + // None of these are sensitive, but clear them anyway. + if (encrypted_key_material_.get()) + memset_s(encrypted_key_material_.get(), 0, key_material_length_); + if (nonce_.get()) + memset_s(nonce_.get(), 0, NONCE_LENGTH); + if (tag_.get()) + memset_s(tag_.get(), 0, TAG_LENGTH); + } + + bool DeserializeUnversionedBlob(const uint8_t** buf_ptr, const uint8_t* end); + + bool ExtractKeyCharacteristics(); + + UniquePtr<uint8_t[]> nonce_; + UniquePtr<uint8_t[]> encrypted_key_material_; + UniquePtr<uint8_t[]> tag_; + size_t key_material_length_; + AuthorizationSet enforced_; + AuthorizationSet unenforced_; + keymaster_algorithm_t algorithm_; + uint32_t key_size_bits_; +}; + +} // namespace keymaster + +#endif // SYSTEM_KEYMASTER_KEY_BLOB_H_ diff --git a/include/keymaster/keymaster_context.h b/include/keymaster/keymaster_context.h deleted file mode 100644 index 68410f8..0000000 --- a/include/keymaster/keymaster_context.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef SYSTEM_KEYMASTER_KEYMASTER_CONTEXT_H_ -#define SYSTEM_KEYMASTER_KEYMASTER_CONTEXT_H_ - -#include <assert.h> - -#include <keymaster/authorization_set.h> -#include <keymaster/android_keymaster_utils.h> - -namespace keymaster { - -/** - * KeymasterContext provides a singleton abstract interface that encapsulates various - * environment-dependent elements of AndroidKeymaster. - * - * AndroidKeymaster runs in multiple contexts. Primarily: - * - * - In a trusted execution environment (TEE) as a "secure hardware" implementation. In this - * context keys are wrapped with an master key that never leaves the TEE, TEE-specific routines - * are used for random number generation, all AndroidKeymaster-enforced authorizations are - * considered hardware-enforced, and there's a bootloader-provided root of trust. - * - * - In the non-secure world as a software-only implementation. In this context keys are not - * encrypted (though they are integrity-checked) because there is no place to securely store a - * key, OpenSSL is used for random number generation, no AndroidKeymaster-enforced authorizations - * are considered hardware enforced and the root of trust is a static string. - * - * - In the non-secure world as a hybrid implementation fronting a less-capable hardware - * implementation. For example, a keymaster0 hardware implementation. In this context keys are - * not encrypted by AndroidKeymaster, but some may be opaque blobs provided by the backing - * hardware, but blobs that lack the extended authorization lists of keymaster1. In addition, - * keymaster0 lacks many features of keymaster1, including modes of operation related to the - * backing keymaster0 keys. AndroidKeymaster must extend the blobs to add authorization lists, - * and must provide the missing operation mode implementations in software, which means that - * authorization lists are partially hardware-enforced (the bits that are enforced by the - * underlying keymaster0) and partially software-enforced (the rest). OpenSSL is used for number - * generation and the root of trust is a static string. - * - * More contexts are possible. - */ -class KeymasterContext { - public: - KeymasterContext() {} - virtual ~KeymasterContext() {}; - - /** - * CreateKeyBlob takes authorization sets and key material and produces a key blob and hardware - * and software authorization lists ready to be returned to the AndroidKeymaster client - * (Keystore, generally). The blob is integrity-checked and may be encrypted, depending on the - * needs of the context. - * - * This method is generally called only by KeyFactory subclassses. - */ - virtual keymaster_error_t CreateKeyBlob(const AuthorizationSet& key_description, - keymaster_key_origin_t origin, - const KeymasterKeyBlob& key_material, - KeymasterKeyBlob* blob, AuthorizationSet* hw_enforced, - AuthorizationSet* sw_enforced) const = 0; - - /** - * ParseKeyBlob takes a blob and extracts authorization sets and key material, returning an - * error if the blob fails integrity checking or decryption. Note that the returned key - * material may itself be an opaque blob usable only by secure hardware (in the hybrid case). - * - * This method is called by AndroidKeymaster. - */ - virtual keymaster_error_t ParseKeyBlob(const KeymasterKeyBlob& blob, - const AuthorizationSet& additional_params, - KeymasterKeyBlob* key_material, - AuthorizationSet* hw_enforced, - AuthorizationSet* sw_enforced) const = 0; - - /** - * Adds entropy to the Cryptographic Pseudo Random Number Generator used to generate key - * material, and other cryptographic protocol elements. Note that if the underlying CPRNG - * tracks the size of its entropy pool, it should not assume that the provided data contributes - * any entropy, and it should also ensure that data provided through this interface cannot - * "poison" the CPRNG outputs, making them predictable. - */ - virtual keymaster_error_t AddRngEntropy(const uint8_t* buf, size_t length) const = 0; - - /** - * Generates \p length random bytes, placing them in \p buf. - */ - virtual keymaster_error_t GenerateRandom(uint8_t* buf, size_t length) const = 0; - - private: - // Uncopyable. - KeymasterContext(const KeymasterContext&); - void operator=(const KeymasterContext&); -}; - -} // namespace keymaster - -#endif // SYSTEM_KEYMASTER_KEYMASTER_CONTEXT_H_ diff --git a/include/keymaster/serializable.h b/include/keymaster/serializable.h index e996fd8..b183367 100644 --- a/include/keymaster/serializable.h +++ b/include/keymaster/serializable.h @@ -194,9 +194,6 @@ class Buffer : public Serializable { return Reinitialize(buffer.peek_read(), buffer.available_read()); } - const uint8_t* begin() const { return peek_read(); } - const uint8_t* end() const { return peek_read() + available_read(); } - void Clear(); size_t available_write() const; diff --git a/include/keymaster/soft_keymaster_device.h b/include/keymaster/soft_keymaster_device.h index 44e64e9..58dd2d9 100644 --- a/include/keymaster/soft_keymaster_device.h +++ b/include/keymaster/soft_keymaster_device.h @@ -51,8 +51,7 @@ class SoftKeymasterDevice { } private: - static keymaster_error_t ExtractSigningParams(const keymaster1_device_t* dev, - const void* signing_params, + static keymaster_error_t ExtractSigningParams(const void* signing_params, const uint8_t* key_blob, size_t key_blob_length, AuthorizationSet* auth_set); static void StoreDefaultNewKeyParams(AuthorizationSet* auth_set); |