1/* 2 * Copyright 2015 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 "rsa_keymaster0_key.h" 18 19#include <memory> 20 21#define LOG_TAG "RsaKeymaster0Key" 22#include <cutils/log.h> 23 24#include <keymaster/android_keymaster_utils.h> 25#include <keymaster/logger.h> 26#include <keymaster/soft_keymaster_context.h> 27 28#include "keymaster0_engine.h" 29#include "openssl_utils.h" 30 31using std::unique_ptr; 32 33namespace keymaster { 34 35RsaKeymaster0KeyFactory::RsaKeymaster0KeyFactory(const SoftKeymasterContext* context, 36 const Keymaster0Engine* engine) 37 : RsaKeyFactory(context), engine_(engine), soft_context_(context) {} 38 39keymaster_error_t RsaKeymaster0KeyFactory::GenerateKey(const AuthorizationSet& key_description, 40 KeymasterKeyBlob* key_blob, 41 AuthorizationSet* hw_enforced, 42 AuthorizationSet* sw_enforced) const { 43 if (!key_blob || !hw_enforced || !sw_enforced) 44 return KM_ERROR_OUTPUT_PARAMETER_NULL; 45 46 if (!engine_) 47 return super::GenerateKey(key_description, key_blob, hw_enforced, sw_enforced); 48 49 uint64_t public_exponent; 50 if (!key_description.GetTagValue(TAG_RSA_PUBLIC_EXPONENT, &public_exponent)) { 51 LOG_E("%s", "No public exponent specified for RSA key generation"); 52 return KM_ERROR_INVALID_ARGUMENT; 53 } 54 55 uint32_t key_size; 56 if (!key_description.GetTagValue(TAG_KEY_SIZE, &key_size)) { 57 LOG_E("%s", "No key size specified for RSA key generation"); 58 return KM_ERROR_UNSUPPORTED_KEY_SIZE; 59 } 60 61 KeymasterKeyBlob key_material; 62 if (!engine_->GenerateRsaKey(public_exponent, key_size, &key_material)) 63 return KM_ERROR_UNKNOWN_ERROR; 64 65 // These tags are hardware-enforced. Putting them in the hw_enforced set here will ensure that 66 // context_->CreateKeyBlob doesn't put them in sw_enforced. 67 hw_enforced->push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA); 68 hw_enforced->push_back(TAG_RSA_PUBLIC_EXPONENT, public_exponent); 69 hw_enforced->push_back(TAG_KEY_SIZE, key_size); 70 hw_enforced->push_back(TAG_ORIGIN, KM_ORIGIN_UNKNOWN); 71 72 return context_->CreateKeyBlob(key_description, KM_ORIGIN_UNKNOWN, key_material, key_blob, 73 hw_enforced, sw_enforced); 74} 75 76keymaster_error_t RsaKeymaster0KeyFactory::ImportKey( 77 const AuthorizationSet& key_description, keymaster_key_format_t input_key_material_format, 78 const KeymasterKeyBlob& input_key_material, KeymasterKeyBlob* output_key_blob, 79 AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced) const { 80 if (!output_key_blob || !hw_enforced || !sw_enforced) 81 return KM_ERROR_OUTPUT_PARAMETER_NULL; 82 83 if (!engine_) 84 return super::ImportKey(key_description, input_key_material_format, input_key_material, 85 output_key_blob, hw_enforced, sw_enforced); 86 87 AuthorizationSet authorizations; 88 uint64_t public_exponent; 89 uint32_t key_size; 90 keymaster_error_t error = 91 UpdateImportKeyDescription(key_description, input_key_material_format, input_key_material, 92 &authorizations, &public_exponent, &key_size); 93 if (error != KM_ERROR_OK) 94 return error; 95 96 KeymasterKeyBlob imported_hw_key; 97 if (!engine_->ImportKey(input_key_material_format, input_key_material, &imported_hw_key)) 98 return KM_ERROR_UNKNOWN_ERROR; 99 100 // These tags are hardware-enforced. Putting them in the hw_enforced set here will ensure that 101 // context_->CreateKeyBlob doesn't put them in sw_enforced. 102 hw_enforced->push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA); 103 hw_enforced->push_back(TAG_RSA_PUBLIC_EXPONENT, public_exponent); 104 hw_enforced->push_back(TAG_KEY_SIZE, key_size); 105 hw_enforced->push_back(TAG_ORIGIN, KM_ORIGIN_UNKNOWN); 106 107 return context_->CreateKeyBlob(authorizations, KM_ORIGIN_UNKNOWN, imported_hw_key, 108 output_key_blob, hw_enforced, sw_enforced); 109} 110 111keymaster_error_t RsaKeymaster0KeyFactory::LoadKey(const KeymasterKeyBlob& key_material, 112 const AuthorizationSet& hw_enforced, 113 const AuthorizationSet& sw_enforced, 114 UniquePtr<Key>* key) const { 115 if (!key) 116 return KM_ERROR_OUTPUT_PARAMETER_NULL; 117 118 if (sw_enforced.GetTagCount(TAG_ALGORITHM) == 1) 119 return super::LoadKey(key_material, hw_enforced, sw_enforced, key); 120 121 unique_ptr<RSA, RSA_Delete> rsa(engine_->BlobToRsaKey(key_material)); 122 if (!rsa) 123 return KM_ERROR_UNKNOWN_ERROR; 124 125 keymaster_error_t error; 126 key->reset(new (std::nothrow) 127 RsaKeymaster0Key(rsa.release(), hw_enforced, sw_enforced, engine_, &error)); 128 if (!key->get()) 129 error = KM_ERROR_MEMORY_ALLOCATION_FAILED; 130 131 if (error != KM_ERROR_OK) 132 return error; 133 134 return KM_ERROR_OK; 135} 136 137RsaKeymaster0Key::RsaKeymaster0Key(RSA* rsa_key, const AuthorizationSet& hw_enforced, 138 const AuthorizationSet& sw_enforced, 139 const Keymaster0Engine* engine, keymaster_error_t* error) 140 : RsaKey(rsa_key, hw_enforced, sw_enforced, error), engine_(engine) {} 141 142keymaster_error_t RsaKeymaster0Key::key_material(UniquePtr<uint8_t[]>* material, 143 size_t* size) const { 144 if (!engine_) 145 return super::key_material(material, size); 146 147 const keymaster_key_blob_t* blob = engine_->RsaKeyToBlob(key()); 148 if (!blob) 149 return KM_ERROR_UNKNOWN_ERROR; 150 151 *size = blob->key_material_size; 152 material->reset(dup_buffer(blob->key_material, *size)); 153 if (!material->get()) 154 return KM_ERROR_MEMORY_ALLOCATION_FAILED; 155 return KM_ERROR_OK; 156} 157 158} // namespace keymaster 159