Revert "Revert "Large refactor to move context out of AndroidKeymaster.""

This reverts commit 13fbe3e93247943c26e7ca2ed27b6d650282b8bf.

Bug: 20912868, 19799085
Change-Id: Iadd6ce5cbe94956c2a2fe277f1bf5b108e4bcf57
diff --git a/symmetric_key.cpp b/symmetric_key.cpp
index e1ce39f..68fa6f1 100644
--- a/symmetric_key.cpp
+++ b/symmetric_key.cpp
@@ -22,53 +22,73 @@
 #include <openssl/rand.h>
 
 #include <keymaster/logger.h>
+#include <keymaster/keymaster_context.h>
 
 #include "aes_key.h"
 #include "hmac_key.h"
 #include "openssl_err.h"
-#include "unencrypted_key_blob.h"
 
 namespace keymaster {
 
-Key* SymmetricKeyFactory::GenerateKey(const AuthorizationSet& key_description,
-                                      keymaster_error_t* error) {
-    UniquePtr<SymmetricKey> key(CreateKeyAndValidateSize(key_description, error));
-    if (!key.get())
-        return NULL;
+keymaster_error_t SymmetricKeyFactory::GenerateKey(const AuthorizationSet& key_description,
+                                                   KeymasterKeyBlob* key_blob,
+                                                   AuthorizationSet* hw_enforced,
+                                                   AuthorizationSet* sw_enforced) {
+    if (!key_blob || !hw_enforced || !sw_enforced)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
 
-    if (RAND_bytes(key->key_data_.get(), key->key_data_size_) != 1) {
-        LOG_E("Error %ul generating %d bit AES key", ERR_get_error(), key->key_data_size_ * 8);
-        *error = TranslateLastOpenSslError();
-        return NULL;
+    uint32_t key_size_bits;
+    if (!key_description.GetTagValue(TAG_KEY_SIZE, &key_size_bits) ||
+        !key_size_supported(key_size_bits))
+        return KM_ERROR_UNSUPPORTED_KEY_SIZE;
+
+    size_t key_data_size = key_size_bits / 8;
+    KeymasterKeyBlob key_material(key_data_size);
+    if (!key_material.key_material)
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+
+    keymaster_error_t error = context_->GenerateRandom(key_material.writable_data(), key_data_size);
+    if (error != KM_ERROR_OK) {
+        LOG_E("Error generating %d bit symmetric key", key_size_bits);
+        return error;
     }
 
-    if (*error != KM_ERROR_OK)
-        return NULL;
-    return key.release();
+    return context_->CreateKeyBlob(key_description, KM_ORIGIN_GENERATED, key_material, key_blob,
+                                   hw_enforced, sw_enforced);
 }
 
-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;
+keymaster_error_t SymmetricKeyFactory::ImportKey(const AuthorizationSet& key_description,
+                                                 keymaster_key_format_t input_key_material_format,
+                                                 const KeymasterKeyBlob& input_key_material,
+                                                 KeymasterKeyBlob* output_key_blob,
+                                                 AuthorizationSet* hw_enforced,
+                                                 AuthorizationSet* sw_enforced) {
+    if (!output_key_blob || !hw_enforced || !sw_enforced)
+        return KM_ERROR_OUTPUT_PARAMETER_NULL;
 
-    if (format != KM_KEY_FORMAT_RAW) {
-        *error = KM_ERROR_UNSUPPORTED_KEY_FORMAT;
-        return NULL;
+    AuthorizationSet authorizations(key_description);
+
+    uint32_t key_size_bits;
+    if (!authorizations.GetTagValue(TAG_KEY_SIZE, &key_size_bits)) {
+        // Default key size if not specified.
+        key_size_bits = input_key_material.key_material_size * 8;
+        authorizations.push_back(TAG_KEY_SIZE, key_size_bits);
     }
 
-    if (key->key_data_size_ != key_material_length) {
-        LOG_E("Expected %d byte key data but got %d bytes", key->key_data_size_,
-              key_material_length);
-        *error = KM_ERROR_INVALID_KEY_BLOB;
-        return NULL;
+    if (!key_size_supported(key_size_bits))
+        return KM_ERROR_UNSUPPORTED_KEY_SIZE;
+
+    if (input_key_material_format != KM_KEY_FORMAT_RAW)
+        return KM_ERROR_UNSUPPORTED_KEY_FORMAT;
+
+    if (key_size_bits != input_key_material.key_material_size * 8) {
+        LOG_E("Expected %d-bit key data but got %d bits", key_size_bits,
+              input_key_material.key_material_size * 8);
+        return KM_ERROR_INVALID_KEY_BLOB;
     }
 
-    key->key_data_size_ = key_material_length;
-    memcpy(key->key_data_.get(), key_material, key_material_length);
-    return key.release();
+    return context_->CreateKeyBlob(authorizations, KM_ORIGIN_IMPORTED, input_key_material,
+                                   output_key_blob, hw_enforced, sw_enforced);
 }
 
 static const keymaster_key_format_t supported_import_formats[] = {KM_KEY_FORMAT_RAW};
@@ -77,40 +97,21 @@
     return supported_import_formats;
 }
 
-SymmetricKey* SymmetricKeyFactory::CreateKeyAndValidateSize(const AuthorizationSet& key_description,
-                                                            keymaster_error_t* error) {
-    if (!error)
-        return NULL;
-    *error = KM_ERROR_OK;
-
-    UniquePtr<SymmetricKey> key(CreateKey(key_description));
-
-    uint32_t key_size_bits;
-    if (!key_description.GetTagValue(TAG_KEY_SIZE, &key_size_bits) || key_size_bits % 8 != 0) {
-        *error = KM_ERROR_UNSUPPORTED_KEY_SIZE;
-        return NULL;
-    }
-
-    *error = key->set_size(key_size_bits / 8);
+SymmetricKey::SymmetricKey(const KeymasterKeyBlob& key_material,
+                           const AuthorizationSet& hw_enforced, const AuthorizationSet& sw_enforced,
+                           keymaster_error_t* error)
+    : Key(hw_enforced, sw_enforced, error) {
     if (*error != KM_ERROR_OK)
-        return NULL;
-
-    return key.release();
-}
-
-SymmetricKey::SymmetricKey(const UnencryptedKeyBlob& blob, keymaster_error_t* error)
-    : Key(blob), key_data_size_(blob.unencrypted_key_material_length()) {
-    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)
+    uint8_t* tmp = dup_buffer(key_material.key_material, key_material.key_material_size);
+    if (tmp) {
+        key_data_.reset(tmp);
+        key_data_size_ = key_material.key_material_size;
         *error = KM_ERROR_OK;
+    } else {
+        *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    }
 }
 
 SymmetricKey::~SymmetricKey() {
@@ -127,16 +128,4 @@
     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;
-}
-
 }  // namespace keymaster