ec_key_factory.cpp revision efbd7e432228cf1e65abb6d85dffa38ec03f7a26
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 <keymaster/ec_key_factory.h> 18 19#include <openssl/evp.h> 20 21#include <keymaster/keymaster_context.h> 22 23#include "ec_key.h" 24#include "ecdsa_operation.h" 25#include "openssl_err.h" 26 27namespace keymaster { 28 29static EcdsaSignOperationFactory sign_factory; 30static EcdsaVerifyOperationFactory verify_factory; 31 32OperationFactory* EcKeyFactory::GetOperationFactory(keymaster_purpose_t purpose) const { 33 switch (purpose) { 34 case KM_PURPOSE_SIGN: 35 return &sign_factory; 36 case KM_PURPOSE_VERIFY: 37 return &verify_factory; 38 default: 39 return nullptr; 40 } 41} 42 43keymaster_error_t EcKeyFactory::GenerateKey(const AuthorizationSet& key_description, 44 KeymasterKeyBlob* key_blob, 45 AuthorizationSet* hw_enforced, 46 AuthorizationSet* sw_enforced) const { 47 if (!key_blob || !hw_enforced || !sw_enforced) 48 return KM_ERROR_OUTPUT_PARAMETER_NULL; 49 50 AuthorizationSet authorizations(key_description); 51 52 uint32_t key_size; 53 if (!authorizations.GetTagValue(TAG_KEY_SIZE, &key_size)) { 54 LOG_E("%s", "No key size specified for EC key generation"); 55 return KM_ERROR_UNSUPPORTED_KEY_SIZE; 56 } 57 58 UniquePtr<EC_KEY, EC_Delete> ec_key(EC_KEY_new()); 59 UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new()); 60 if (ec_key.get() == NULL || pkey.get() == NULL) 61 return KM_ERROR_MEMORY_ALLOCATION_FAILED; 62 63 UniquePtr<EC_GROUP, EC_GROUP_Delete> group(choose_group(key_size)); 64 if (group.get() == NULL) { 65 LOG_E("Unable to get EC group for key of size %d", key_size); 66 return KM_ERROR_UNSUPPORTED_KEY_SIZE; 67 } 68 69#if !defined(OPENSSL_IS_BORINGSSL) 70 EC_GROUP_set_point_conversion_form(group.get(), POINT_CONVERSION_UNCOMPRESSED); 71 EC_GROUP_set_asn1_flag(group.get(), OPENSSL_EC_NAMED_CURVE); 72#endif 73 74 if (EC_KEY_set_group(ec_key.get(), group.get()) != 1 || 75 EC_KEY_generate_key(ec_key.get()) != 1 || EC_KEY_check_key(ec_key.get()) < 0) { 76 return TranslateLastOpenSslError(); 77 } 78 79 if (EVP_PKEY_set1_EC_KEY(pkey.get(), ec_key.get()) != 1) 80 return TranslateLastOpenSslError(); 81 82 KeymasterKeyBlob key_material; 83 keymaster_error_t error = EvpKeyToKeyMaterial(pkey.get(), &key_material); 84 if (error != KM_ERROR_OK) 85 return error; 86 87 return context_->CreateKeyBlob(authorizations, KM_ORIGIN_GENERATED, key_material, key_blob, 88 hw_enforced, sw_enforced); 89} 90 91keymaster_error_t EcKeyFactory::ImportKey(const AuthorizationSet& key_description, 92 keymaster_key_format_t input_key_material_format, 93 const KeymasterKeyBlob& input_key_material, 94 KeymasterKeyBlob* output_key_blob, 95 AuthorizationSet* hw_enforced, 96 AuthorizationSet* sw_enforced) const { 97 if (!output_key_blob || !hw_enforced || !sw_enforced) 98 return KM_ERROR_OUTPUT_PARAMETER_NULL; 99 100 AuthorizationSet authorizations; 101 uint32_t key_size; 102 keymaster_error_t error = UpdateImportKeyDescription( 103 key_description, input_key_material_format, input_key_material, &authorizations, &key_size); 104 if (error != KM_ERROR_OK) 105 return error; 106 107 return context_->CreateKeyBlob(authorizations, KM_ORIGIN_IMPORTED, input_key_material, 108 output_key_blob, hw_enforced, sw_enforced); 109} 110 111keymaster_error_t EcKeyFactory::UpdateImportKeyDescription(const AuthorizationSet& key_description, 112 keymaster_key_format_t key_format, 113 const KeymasterKeyBlob& key_material, 114 AuthorizationSet* updated_description, 115 uint32_t* key_size_bits) const { 116 if (!updated_description || !key_size_bits) 117 return KM_ERROR_OUTPUT_PARAMETER_NULL; 118 119 UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey; 120 keymaster_error_t error = 121 KeyMaterialToEvpKey(key_format, key_material, keymaster_key_type(), &pkey); 122 if (error != KM_ERROR_OK) 123 return error; 124 125 UniquePtr<EC_KEY, EC_Delete> ec_key(EVP_PKEY_get1_EC_KEY(pkey.get())); 126 if (!ec_key.get()) 127 return TranslateLastOpenSslError(); 128 129 updated_description->Reinitialize(key_description); 130 131 size_t extracted_key_size_bits; 132 error = get_group_size(*EC_KEY_get0_group(ec_key.get()), &extracted_key_size_bits); 133 if (error != KM_ERROR_OK) 134 return error; 135 136 *key_size_bits = extracted_key_size_bits; 137 if (!updated_description->GetTagValue(TAG_KEY_SIZE, key_size_bits)) 138 updated_description->push_back(TAG_KEY_SIZE, extracted_key_size_bits); 139 if (*key_size_bits != extracted_key_size_bits) 140 return KM_ERROR_IMPORT_PARAMETER_MISMATCH; 141 142 keymaster_algorithm_t algorithm = KM_ALGORITHM_EC; 143 if (!updated_description->GetTagValue(TAG_ALGORITHM, &algorithm)) 144 updated_description->push_back(TAG_ALGORITHM, KM_ALGORITHM_EC); 145 if (algorithm != KM_ALGORITHM_EC) 146 return KM_ERROR_IMPORT_PARAMETER_MISMATCH; 147 148 return KM_ERROR_OK; 149} 150 151/* static */ 152EC_GROUP* EcKeyFactory::choose_group(size_t key_size_bits) { 153 switch (key_size_bits) { 154 case 224: 155 return EC_GROUP_new_by_curve_name(NID_secp224r1); 156 break; 157 case 256: 158 return EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); 159 break; 160 case 384: 161 return EC_GROUP_new_by_curve_name(NID_secp384r1); 162 break; 163 case 521: 164 return EC_GROUP_new_by_curve_name(NID_secp521r1); 165 break; 166 default: 167 return NULL; 168 break; 169 } 170} 171/* static */ 172keymaster_error_t EcKeyFactory::get_group_size(const EC_GROUP& group, size_t* key_size_bits) { 173 switch (EC_GROUP_get_curve_name(&group)) { 174 case NID_secp224r1: 175 *key_size_bits = 224; 176 break; 177 case NID_X9_62_prime256v1: 178 *key_size_bits = 256; 179 break; 180 case NID_secp384r1: 181 *key_size_bits = 384; 182 break; 183 case NID_secp521r1: 184 *key_size_bits = 521; 185 break; 186 default: 187 return KM_ERROR_UNSUPPORTED_EC_FIELD; 188 } 189 return KM_ERROR_OK; 190} 191 192keymaster_error_t EcKeyFactory::CreateEmptyKey(const AuthorizationSet& hw_enforced, 193 const AuthorizationSet& sw_enforced, 194 UniquePtr<AsymmetricKey>* key) const { 195 keymaster_error_t error; 196 key->reset(new EcKey(hw_enforced, sw_enforced, &error)); 197 if (!key->get()) 198 error = KM_ERROR_MEMORY_ALLOCATION_FAILED; 199 return error; 200} 201 202} // namespace keymaster 203