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 return engine_->GenerateKey(key_params_copy, key_blob, hw_enforced, sw_enforced); 71 } 72 73 keymaster_error_t EcdsaKeymaster1KeyFactory::ImportKey( 74 const AuthorizationSet& key_description, keymaster_key_format_t input_key_material_format, 75 const KeymasterKeyBlob& input_key_material, KeymasterKeyBlob* output_key_blob, 76 AuthorizationSet* hw_enforced, AuthorizationSet* sw_enforced) const { 77 AuthorizationSet key_params_copy; 78 UpdateToWorkAroundUnsupportedDigests(key_description, &key_params_copy); 79 return engine_->ImportKey(key_params_copy, input_key_material_format, input_key_material, 80 output_key_blob, hw_enforced, sw_enforced); 81 } 82 83 keymaster_error_t EcdsaKeymaster1KeyFactory::LoadKey(const KeymasterKeyBlob& key_material, 84 const AuthorizationSet& additional_params, 85 const AuthorizationSet& hw_enforced, 86 const AuthorizationSet& sw_enforced, 87 UniquePtr<Key>* key) const { 88 if (!key) 89 return KM_ERROR_OUTPUT_PARAMETER_NULL; 90 91 keymaster_error_t error; 92 unique_ptr<EC_KEY, EC_KEY_Delete> ecdsa( 93 engine_->BuildEcKey(key_material, additional_params, &error)); 94 if (!ecdsa) 95 return error; 96 97 key->reset(new (std::nothrow) 98 EcdsaKeymaster1Key(ecdsa.release(), hw_enforced, sw_enforced, &error)); 99 if (!key->get()) 100 error = KM_ERROR_MEMORY_ALLOCATION_FAILED; 101 102 if (error != KM_ERROR_OK) 103 return error; 104 105 return KM_ERROR_OK; 106 } 107 108 OperationFactory* 109 EcdsaKeymaster1KeyFactory::GetOperationFactory(keymaster_purpose_t purpose) const { 110 switch (purpose) { 111 case KM_PURPOSE_SIGN: 112 return sign_factory_.get(); 113 case KM_PURPOSE_VERIFY: 114 return verify_factory_.get(); 115 default: 116 return nullptr; 117 } 118 } 119 120 } // namespace keymaster 121