summaryrefslogtreecommitdiffstats
path: root/include/keymaster/key_blob.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/keymaster/key_blob.h')
-rw-r--r--include/keymaster/key_blob.h130
1 files changed, 130 insertions, 0 deletions
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_