Implement symmetric key import.
Change-Id: I902933c06c74c7b3b434873f53fb2c767d3b9721
diff --git a/symmetric_key.cpp b/symmetric_key.cpp
index fc8472f..41983ac 100644
--- a/symmetric_key.cpp
+++ b/symmetric_key.cpp
@@ -32,6 +32,51 @@
Key* SymmetricKeyFactory::GenerateKey(const AuthorizationSet& key_description,
keymaster_error_t* error) {
+ UniquePtr<SymmetricKey> key(CreateKeyAndValidateSize(key_description, error));
+ if (!key.get())
+ return NULL;
+
+ if (!RAND_bytes(key->key_data_.get(), key->key_data_size_)) {
+ LOG_E("Error %ul generating %d bit AES key", ERR_get_error(), key->key_data_size_ * 8);
+ *error = TranslateLastOpenSslError();
+ return NULL;
+ }
+
+ if (*error != KM_ERROR_OK)
+ return NULL;
+ return key.release();
+}
+
+Key* SymmetricKeyFactory::ImportKey(const AuthorizationSet& key_description,
+ keymaster_key_format_t format, const uint8_t* key_material,
+ size_t key_material_length, keymaster_error_t* error) {
+ UniquePtr<SymmetricKey> key(CreateKeyAndValidateSize(key_description, error));
+ if (!key.get())
+ return NULL;
+
+ if (format != KM_KEY_FORMAT_RAW) {
+ *error = KM_ERROR_UNSUPPORTED_KEY_FORMAT;
+ return NULL;
+ }
+
+ if (key->key_data_size_ != key_material_length) {
+ *error = KM_ERROR_INVALID_KEY_BLOB;
+ return NULL;
+ }
+
+ key->key_data_size_ = key_material_length;
+ memcpy(key->key_data_.get(), key_material, key_material_length);
+ return key.release();
+}
+
+static const keymaster_key_format_t supported_import_formats[] = {KM_KEY_FORMAT_RAW};
+const keymaster_key_format_t* SymmetricKeyFactory::SupportedImportFormats(size_t* format_count) {
+ *format_count = array_length(supported_import_formats);
+ return supported_import_formats;
+}
+
+SymmetricKey* SymmetricKeyFactory::CreateKeyAndValidateSize(const AuthorizationSet& key_description,
+ keymaster_error_t* error) {
if (!error)
return NULL;
*error = KM_ERROR_OK;
@@ -44,17 +89,7 @@
return NULL;
}
- key->key_data_size_ = key_size_bits / 8;
- if (key->key_data_size_ > SymmetricKey::MAX_KEY_SIZE) {
- *error = KM_ERROR_UNSUPPORTED_KEY_SIZE;
- return NULL;
- }
- if (!RAND_bytes(key->key_data_, key->key_data_size_)) {
- LOG_E("Error %ul generating %d bit AES key", ERR_get_error(), key_size_bits);
- *error = TranslateLastOpenSslError();
- return NULL;
- }
-
+ *error = key->set_size(key_size_bits / 8);
if (*error != KM_ERROR_OK)
return NULL;
return key.release();
@@ -62,13 +97,21 @@
SymmetricKey::SymmetricKey(const UnencryptedKeyBlob& blob, keymaster_error_t* error)
: Key(blob), key_data_size_(blob.unencrypted_key_material_length()) {
- memcpy(key_data_, blob.unencrypted_key_material(), key_data_size_);
+ key_data_.reset(new uint8_t[key_data_size_]);
+ if (!key_data_.get()) {
+ if (error)
+ *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
+ key_data_size_ = 0;
+ return;
+ }
+
+ memcpy(key_data_.get(), blob.unencrypted_key_material(), key_data_size_);
if (error)
*error = KM_ERROR_OK;
}
SymmetricKey::~SymmetricKey() {
- memset_s(key_data_, 0, MAX_KEY_SIZE);
+ memset_s(key_data_.get(), 0, key_data_size_);
}
keymaster_error_t SymmetricKey::key_material(UniquePtr<uint8_t[]>* key_material,
@@ -77,7 +120,19 @@
key_material->reset(new uint8_t[*size]);
if (!key_material->get())
return KM_ERROR_MEMORY_ALLOCATION_FAILED;
- memcpy(key_material->get(), key_data_, *size);
+ memcpy(key_material->get(), key_data_.get(), *size);
+ return KM_ERROR_OK;
+}
+
+keymaster_error_t SymmetricKey::set_size(size_t key_size) {
+ if (!size_supported(key_size))
+ return KM_ERROR_UNSUPPORTED_KEY_SIZE;
+
+ key_data_.reset(new uint8_t[key_size]);
+ if (!key_data_.get())
+ return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+ key_data_size_ = key_size;
+
return KM_ERROR_OK;
}