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