symmetric_key.cpp revision 7dad93b6552a2253ad6e7a493ddf0c9113806712
195e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden/* 295e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden * Copyright 2014 The Android Open Source Project 395e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden * 495e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden * Licensed under the Apache License, Version 2.0 (the "License"); 595e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden * you may not use this file except in compliance with the License. 695e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden * You may obtain a copy of the License at 795e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden * 895e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden * http://www.apache.org/licenses/LICENSE-2.0 995e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden * 1095e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden * Unless required by applicable law or agreed to in writing, software 1195e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden * distributed under the License is distributed on an "AS IS" BASIS, 1295e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1395e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden * See the License for the specific language governing permissions and 1495e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden * limitations under the License. 1595e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden */ 1695e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden 1795e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden#include "symmetric_key.h" 1895e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden 1995e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden#include <assert.h> 2095e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden 2195e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden#include <openssl/err.h> 2295e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden#include <openssl/rand.h> 2395e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden 24567a4a04f43d35b785d50508e6459b01f2ab4d14Shawn Willden#include <keymaster/logger.h> 25567a4a04f43d35b785d50508e6459b01f2ab4d14Shawn Willden 2695e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden#include "aes_key.h" 270d560bfedd40389387f31f6696660fff6bc3a48aShawn Willden#include "hmac_key.h" 28567a4a04f43d35b785d50508e6459b01f2ab4d14Shawn Willden#include "openssl_err.h" 2995e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden#include "unencrypted_key_blob.h" 3095e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden 3195e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willdennamespace keymaster { 3295e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden 33567a4a04f43d35b785d50508e6459b01f2ab4d14Shawn WilldenKey* SymmetricKeyFactory::GenerateKey(const AuthorizationSet& key_description, 34a278f6156b9e57e1de8ca380b14fef113ad10be8Shawn Willden keymaster_error_t* error) { 357dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden UniquePtr<SymmetricKey> key(CreateKeyAndValidateSize(key_description, error)); 367dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden if (!key.get()) 377dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden return NULL; 387dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden 397dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden if (!RAND_bytes(key->key_data_.get(), key->key_data_size_)) { 407dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden LOG_E("Error %ul generating %d bit AES key", ERR_get_error(), key->key_data_size_ * 8); 417dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden *error = TranslateLastOpenSslError(); 427dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden return NULL; 437dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden } 447dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden 457dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden if (*error != KM_ERROR_OK) 467dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden return NULL; 477dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden return key.release(); 487dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden} 497dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden 507dad93b6552a2253ad6e7a493ddf0c9113806712Shawn WilldenKey* SymmetricKeyFactory::ImportKey(const AuthorizationSet& key_description, 517dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden keymaster_key_format_t format, const uint8_t* key_material, 527dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden size_t key_material_length, keymaster_error_t* error) { 537dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden UniquePtr<SymmetricKey> key(CreateKeyAndValidateSize(key_description, error)); 547dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden if (!key.get()) 557dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden return NULL; 567dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden 577dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden if (format != KM_KEY_FORMAT_RAW) { 587dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden *error = KM_ERROR_UNSUPPORTED_KEY_FORMAT; 597dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden return NULL; 607dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden } 617dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden 627dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden if (key->key_data_size_ != key_material_length) { 637dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden *error = KM_ERROR_INVALID_KEY_BLOB; 647dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden return NULL; 657dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden } 667dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden 677dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden key->key_data_size_ = key_material_length; 687dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden memcpy(key->key_data_.get(), key_material, key_material_length); 697dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden return key.release(); 707dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden} 717dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden 727dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willdenstatic const keymaster_key_format_t supported_import_formats[] = {KM_KEY_FORMAT_RAW}; 737dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willdenconst keymaster_key_format_t* SymmetricKeyFactory::SupportedImportFormats(size_t* format_count) { 747dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden *format_count = array_length(supported_import_formats); 757dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden return supported_import_formats; 767dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden} 777dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden 787dad93b6552a2253ad6e7a493ddf0c9113806712Shawn WilldenSymmetricKey* SymmetricKeyFactory::CreateKeyAndValidateSize(const AuthorizationSet& key_description, 797dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden keymaster_error_t* error) { 8095e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden if (!error) 8195e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden return NULL; 8295e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden *error = KM_ERROR_OK; 8395e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden 84567a4a04f43d35b785d50508e6459b01f2ab4d14Shawn Willden UniquePtr<SymmetricKey> key(CreateKey(key_description)); 8595e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden 8695e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden uint32_t key_size_bits; 8795e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden if (!key_description.GetTagValue(TAG_KEY_SIZE, &key_size_bits) || key_size_bits % 8 != 0) { 8895e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden *error = KM_ERROR_UNSUPPORTED_KEY_SIZE; 8995e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden return NULL; 9095e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden } 9195e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden 927dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden *error = key->set_size(key_size_bits / 8); 9395e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden if (*error != KM_ERROR_OK) 9495e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden return NULL; 9595e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden return key.release(); 9695e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden} 9795e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden 98567a4a04f43d35b785d50508e6459b01f2ab4d14Shawn WilldenSymmetricKey::SymmetricKey(const UnencryptedKeyBlob& blob, keymaster_error_t* error) 99567a4a04f43d35b785d50508e6459b01f2ab4d14Shawn Willden : Key(blob), key_data_size_(blob.unencrypted_key_material_length()) { 1007dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden key_data_.reset(new uint8_t[key_data_size_]); 1017dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden if (!key_data_.get()) { 1027dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden if (error) 1037dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden *error = KM_ERROR_MEMORY_ALLOCATION_FAILED; 1047dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden key_data_size_ = 0; 1057dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden return; 1067dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden } 1077dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden 1087dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden memcpy(key_data_.get(), blob.unencrypted_key_material(), key_data_size_); 10995e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden if (error) 110a278f6156b9e57e1de8ca380b14fef113ad10be8Shawn Willden *error = KM_ERROR_OK; 11195e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden} 11295e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden 11395e1382b75bab7d8b4cce3c1267fa23df2006957Shawn WilldenSymmetricKey::~SymmetricKey() { 1147dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden memset_s(key_data_.get(), 0, key_data_size_); 11595e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden} 11695e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden 11795e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willdenkeymaster_error_t SymmetricKey::key_material(UniquePtr<uint8_t[]>* key_material, 11895e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden size_t* size) const { 11995e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden *size = key_data_size_; 12095e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden key_material->reset(new uint8_t[*size]); 12195e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden if (!key_material->get()) 12295e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden return KM_ERROR_MEMORY_ALLOCATION_FAILED; 1237dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden memcpy(key_material->get(), key_data_.get(), *size); 1247dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden return KM_ERROR_OK; 1257dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden} 1267dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden 1277dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willdenkeymaster_error_t SymmetricKey::set_size(size_t key_size) { 1287dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden if (!size_supported(key_size)) 1297dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden return KM_ERROR_UNSUPPORTED_KEY_SIZE; 1307dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden 1317dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden key_data_.reset(new uint8_t[key_size]); 1327dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden if (!key_data_.get()) 1337dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden return KM_ERROR_MEMORY_ALLOCATION_FAILED; 1347dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden key_data_size_ = key_size; 1357dad93b6552a2253ad6e7a493ddf0c9113806712Shawn Willden 13695e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden return KM_ERROR_OK; 13795e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden} 13895e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden 13995e1382b75bab7d8b4cce3c1267fa23df2006957Shawn Willden} // namespace keymaster 140