symmetric_key.cpp revision 41d5a7486e335387c8dd9437e0c84b285b5c7f28
1/* 2 * Copyright 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <keymaster/km_openssl/symmetric_key.h> 18 19#include <assert.h> 20 21#include <openssl/err.h> 22#include <openssl/rand.h> 23 24#include <keymaster/android_keymaster_utils.h> 25#include <keymaster/keymaster_context.h> 26#include <keymaster/km_openssl/aes_key.h> 27#include <keymaster/km_openssl/hmac_key.h> 28#include <keymaster/km_openssl/openssl_err.h> 29#include <keymaster/logger.h> 30 31namespace keymaster { 32 33keymaster_error_t SymmetricKeyFactory::GenerateKey(const AuthorizationSet& key_description, 34 KeymasterKeyBlob* key_blob, 35 AuthorizationSet* hw_enforced, 36 AuthorizationSet* sw_enforced) const { 37 if (!key_blob || !hw_enforced || !sw_enforced) 38 return KM_ERROR_OUTPUT_PARAMETER_NULL; 39 40 uint32_t key_size_bits; 41 if (!key_description.GetTagValue(TAG_KEY_SIZE, &key_size_bits) || 42 !key_size_supported(key_size_bits)) 43 return KM_ERROR_UNSUPPORTED_KEY_SIZE; 44 45 keymaster_error_t error = validate_algorithm_specific_new_key_params(key_description); 46 if (error != KM_ERROR_OK) 47 return error; 48 49 size_t key_data_size = key_size_bits / 8; 50 KeymasterKeyBlob key_material(key_data_size); 51 if (!key_material.key_material) 52 return KM_ERROR_MEMORY_ALLOCATION_FAILED; 53 54 error = random_source_.GenerateRandom(key_material.writable_data(), key_data_size); 55 if (error != KM_ERROR_OK) { 56 LOG_E("Error generating %d bit symmetric key", key_size_bits); 57 return error; 58 } 59 60 return blob_maker_.CreateKeyBlob(key_description, KM_ORIGIN_GENERATED, key_material, key_blob, 61 hw_enforced, sw_enforced); 62} 63 64keymaster_error_t SymmetricKeyFactory::ImportKey(const AuthorizationSet& key_description, 65 keymaster_key_format_t input_key_material_format, 66 const KeymasterKeyBlob& input_key_material, 67 KeymasterKeyBlob* output_key_blob, 68 AuthorizationSet* hw_enforced, 69 AuthorizationSet* sw_enforced) const { 70 if (!output_key_blob || !hw_enforced || !sw_enforced) 71 return KM_ERROR_OUTPUT_PARAMETER_NULL; 72 73 AuthorizationSet authorizations(key_description); 74 75 uint32_t key_size_bits; 76 if (!authorizations.GetTagValue(TAG_KEY_SIZE, &key_size_bits)) { 77 // Default key size if not specified. 78 key_size_bits = input_key_material.key_material_size * 8; 79 authorizations.push_back(TAG_KEY_SIZE, key_size_bits); 80 } 81 82 keymaster_error_t error = validate_algorithm_specific_new_key_params(key_description); 83 if (error != KM_ERROR_OK) 84 return error; 85 86 if (!key_size_supported(key_size_bits)) 87 return KM_ERROR_UNSUPPORTED_KEY_SIZE; 88 89 if (input_key_material_format != KM_KEY_FORMAT_RAW) 90 return KM_ERROR_UNSUPPORTED_KEY_FORMAT; 91 92 if (key_size_bits != input_key_material.key_material_size * 8) { 93 LOG_E("Expected %d-bit key data but got %d bits", key_size_bits, 94 input_key_material.key_material_size * 8); 95 return KM_ERROR_INVALID_KEY_BLOB; 96 } 97 98 return blob_maker_.CreateKeyBlob(authorizations, KM_ORIGIN_IMPORTED, input_key_material, 99 output_key_blob, hw_enforced, sw_enforced); 100} 101 102static const keymaster_key_format_t supported_import_formats[] = {KM_KEY_FORMAT_RAW}; 103const keymaster_key_format_t* 104SymmetricKeyFactory::SupportedImportFormats(size_t* format_count) const { 105 *format_count = array_length(supported_import_formats); 106 return supported_import_formats; 107} 108 109SymmetricKey::SymmetricKey(const KeymasterKeyBlob& key_material, 110 const AuthorizationSet& hw_enforced, const AuthorizationSet& sw_enforced, 111 keymaster_error_t* error) 112 : Key(hw_enforced, sw_enforced, error) { 113 if (*error != KM_ERROR_OK) 114 return; 115 116 uint8_t* tmp = dup_buffer(key_material.key_material, key_material.key_material_size); 117 if (tmp) { 118 key_data_.reset(tmp); 119 key_data_size_ = key_material.key_material_size; 120 *error = KM_ERROR_OK; 121 } else { 122 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED; 123 } 124} 125 126SymmetricKey::~SymmetricKey() { 127 memset_s(key_data_.get(), 0, key_data_size_); 128} 129 130keymaster_error_t SymmetricKey::key_material(UniquePtr<uint8_t[]>* key_material, 131 size_t* size) const { 132 *size = key_data_size_; 133 key_material->reset(new (std::nothrow) uint8_t[*size]); 134 if (!key_material->get()) 135 return KM_ERROR_MEMORY_ALLOCATION_FAILED; 136 memcpy(key_material->get(), key_data_.get(), *size); 137 return KM_ERROR_OK; 138} 139 140} // namespace keymaster 141