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 "ec_keymaster1_key.h" 18 19 #include <memory> 20 21 #include <keymaster/logger.h> 22 23 #include "ecdsa_keymaster1_operation.h" 24 #include "ecdsa_operation.h" 25 26 using std::unique_ptr; 27 28 namespace keymaster { 29 30 EcdsaKeymaster1KeyFactory::EcdsaKeymaster1KeyFactory(const SoftKeymasterContext* context, 31 const Keymaster1Engine* engine) 32 : EcKeyFactory(context), engine_(engine), 33 sign_factory_(new EcdsaKeymaster1OperationFactory(KM_PURPOSE_SIGN, engine)), 34 // For pubkey ops we can use the normal operation factories. 35 verify_factory_(new EcdsaVerifyOperationFactory) {} 36 37 static bool is_supported(uint32_t digest) { 38 return digest == KM_DIGEST_NONE || digest == KM_DIGEST_SHA_2_256; 39 } 40 41 static void UpdateToWorkAroundUnsupportedDigests(const AuthorizationSet& key_description, 42 AuthorizationSet* new_description) { 43 bool have_unsupported_digests = false; 44 bool have_digest_none = false; 45 for (const keymaster_key_param_t& entry : key_description) { 46 new_description->push_back(entry); 47 48 if (entry.tag == TAG_DIGEST) { 49 if (entry.enumerated == KM_DIGEST_NONE) { 50 have_digest_none = true; 51 } else if (!is_supported(entry.enumerated)) { 52 LOG_D("Found request for unsupported digest %u", entry.enumerated); 53 have_unsupported_digests = true; 54 } 55 } 56 } 57 58 if (have_unsupported_digests && !have_digest_none) { 59 LOG_I("Adding KM_DIGEST_NONE to key authorization, to enable software digesting", 0); 60 new_description->push_back(TAG_DIGEST, KM_DIGEST_NONE); 61 } 62 } 63 64 keymaster_error_t EcdsaKeymaster1KeyFactory::GenerateKey(const AuthorizationSet& key_description, 65 KeymasterKeyBlob* key_blob, 66 AuthorizationSet* hw_enforced, 67 AuthorizationSet* sw_enforced) const { 68 AuthorizationSet key_params_copy; 69 UpdateToWorkAroundUnsupportedDigests(key_description, &key_params_copy); 70 71 keymaster_ec_curve_t ec_curve; 72 uint32_t key_size; 73 keymaster_error_t error = GetCurveAndSize(key_description, &ec_curve, &key_size); 74 if (error != KM_ERROR_OK) { 75 return error; 76 } else if (!key_description.Contains(TAG_KEY_SIZE, key_size)) { 77 key_params_copy.push_back(TAG_KEY_SIZE, key_size); 78 } 79 return engine_->GenerateKey(key_params_copy, key_blob, hw_enforced, sw_enforced); 80 } 81 82 keymaster_error_t EcdsaKeymaster1KeyFactory::ImportKey( 83 const AuthorizationSet& key_description, keymaster_key_format_t input_key_material_format, 84 const KeymasterKeyBlob& input_key_material, KeymasterKeyBlob* output_key_blob, 85 AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced) const { 86 AuthorizationSet key_params_copy; 87 UpdateToWorkAroundUnsupportedDigests(key_description, &key_params_copy); 88 return engine_->ImportKey(key_params_copy, input_key_material_format, input_key_material, 89 output_key_blob, hw_enforced, sw_enforced); 90 } 91 92 keymaster_error_t EcdsaKeymaster1KeyFactory::LoadKey(const KeymasterKeyBlob& key_material, 93 const AuthorizationSet& additional_params, 94 const AuthorizationSet& hw_enforced, 95 const AuthorizationSet& sw_enforced, 96 UniquePtr<Key>* key) const { 97 if (!key) 98 return KM_ERROR_OUTPUT_PARAMETER_NULL; 99 100 keymaster_error_t error; 101 unique_ptr<EC_KEY, EC_KEY_Delete> ecdsa( 102 engine_->BuildEcKey(key_material, additional_params, &error)); 103 if (!ecdsa) 104 return error; 105 106 key->reset(new (std::nothrow) 107 EcdsaKeymaster1Key(ecdsa.release(), hw_enforced, sw_enforced, &error)); 108 if (!key->get()) 109 error = KM_ERROR_MEMORY_ALLOCATION_FAILED; 110 111 if (error != KM_ERROR_OK) 112 return error; 113 114 return KM_ERROR_OK; 115 } 116 117 OperationFactory* 118 EcdsaKeymaster1KeyFactory::GetOperationFactory(keymaster_purpose_t purpose) const { 119 switch (purpose) { 120 case KM_PURPOSE_SIGN: 121 return sign_factory_.get(); 122 case KM_PURPOSE_VERIFY: 123 return verify_factory_.get(); 124 default: 125 return nullptr; 126 } 127 } 128 129 } // namespace keymaster 130