summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorShawn Willden <swillden@google.com>2015-05-23 03:36:30 +0000
committerShawn Willden <swillden@google.com>2015-05-23 03:36:30 +0000
commit13fbe3e93247943c26e7ca2ed27b6d650282b8bf (patch)
treecd71086d18f6eb1ffc47d7f8cc3d92346ba639c6 /include
parent8ba2a043f0d44ad3f58d4af518f9391c03eca9c3 (diff)
downloadkeymaster-13fbe3e93247943c26e7ca2ed27b6d650282b8bf.tar.gz
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.h34
-rw-r--r--include/keymaster/android_keymaster_utils.h94
-rw-r--r--include/keymaster/key_blob.h130
-rw-r--r--include/keymaster/keymaster_context.h110
-rw-r--r--include/keymaster/serializable.h3
-rw-r--r--include/keymaster/soft_keymaster_device.h3
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);