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/rsa_key_factory.h> 18 19 #include <new> 20 21 #include <keymaster/keymaster_context.h> 22 23 #include "openssl_err.h" 24 #include "openssl_utils.h" 25 #include "rsa_key.h" 26 #include "rsa_operation.h" 27 28 namespace keymaster { 29 30 const int kMaximumRsaKeySize = 16 * 1024; // 16kbits should be enough for anyone. 31 32 static RsaSigningOperationFactory sign_factory; 33 static RsaVerificationOperationFactory verify_factory; 34 static RsaEncryptionOperationFactory encrypt_factory; 35 static RsaDecryptionOperationFactory decrypt_factory; 36 37 OperationFactory* RsaKeyFactory::GetOperationFactory(keymaster_purpose_t purpose) const { 38 switch (purpose) { 39 case KM_PURPOSE_SIGN: 40 return &sign_factory; 41 case KM_PURPOSE_VERIFY: 42 return &verify_factory; 43 case KM_PURPOSE_ENCRYPT: 44 return &encrypt_factory; 45 case KM_PURPOSE_DECRYPT: 46 return &decrypt_factory; 47 default: 48 return nullptr; 49 } 50 } 51 52 keymaster_error_t RsaKeyFactory::GenerateKey(const AuthorizationSet& key_description, 53 KeymasterKeyBlob* key_blob, 54 AuthorizationSet* hw_enforced, 55 AuthorizationSet* sw_enforced) const { 56 if (!key_blob || !hw_enforced || !sw_enforced) 57 return KM_ERROR_OUTPUT_PARAMETER_NULL; 58 59 AuthorizationSet authorizations(key_description); 60 61 uint64_t public_exponent; 62 if (!authorizations.GetTagValue(TAG_RSA_PUBLIC_EXPONENT, &public_exponent)) { 63 LOG_E("%s", "No public exponent specified for RSA key generation"); 64 return KM_ERROR_INVALID_ARGUMENT; 65 } 66 67 uint32_t key_size; 68 if (!authorizations.GetTagValue(TAG_KEY_SIZE, &key_size)) { 69 LOG_E("No key size specified for RSA key generation", 0); 70 return KM_ERROR_UNSUPPORTED_KEY_SIZE; 71 } 72 if (key_size % 8 != 0 || key_size > kMaximumRsaKeySize) { 73 LOG_E("Invalid key size of %u bits specified for RSA key generation", key_size); 74 return KM_ERROR_UNSUPPORTED_KEY_SIZE; 75 } 76 77 UniquePtr<BIGNUM, BIGNUM_Delete> exponent(BN_new()); 78 UniquePtr<RSA, RsaKey::RSA_Delete> rsa_key(RSA_new()); 79 UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new()); 80 if (exponent.get() == NULL || rsa_key.get() == NULL || pkey.get() == NULL) 81 return KM_ERROR_MEMORY_ALLOCATION_FAILED; 82 83 if (!BN_set_word(exponent.get(), public_exponent) || 84 !RSA_generate_key_ex(rsa_key.get(), key_size, exponent.get(), NULL /* callback */)) 85 return TranslateLastOpenSslError(); 86 87 if (EVP_PKEY_set1_RSA(pkey.get(), rsa_key.get()) != 1) 88 return TranslateLastOpenSslError(); 89 90 KeymasterKeyBlob key_material; 91 keymaster_error_t error = EvpKeyToKeyMaterial(pkey.get(), &key_material); 92 if (error != KM_ERROR_OK) 93 return error; 94 95 return context_->CreateKeyBlob(authorizations, KM_ORIGIN_GENERATED, key_material, key_blob, 96 hw_enforced, sw_enforced); 97 } 98 99 keymaster_error_t RsaKeyFactory::ImportKey(const AuthorizationSet& key_description, 100 keymaster_key_format_t input_key_material_format, 101 const KeymasterKeyBlob& input_key_material, 102 KeymasterKeyBlob* output_key_blob, 103 AuthorizationSet* hw_enforced, 104 AuthorizationSet* sw_enforced) const { 105 if (!output_key_blob || !hw_enforced || !sw_enforced) 106 return KM_ERROR_OUTPUT_PARAMETER_NULL; 107 108 AuthorizationSet authorizations; 109 uint64_t public_exponent; 110 uint32_t key_size; 111 keymaster_error_t error = 112 UpdateImportKeyDescription(key_description, input_key_material_format, input_key_material, 113 &authorizations, &public_exponent, &key_size); 114 if (error != KM_ERROR_OK) 115 return error; 116 return context_->CreateKeyBlob(authorizations, KM_ORIGIN_IMPORTED, input_key_material, 117 output_key_blob, hw_enforced, sw_enforced); 118 } 119 120 keymaster_error_t RsaKeyFactory::UpdateImportKeyDescription(const AuthorizationSet& key_description, 121 keymaster_key_format_t key_format, 122 const KeymasterKeyBlob& key_material, 123 AuthorizationSet* updated_description, 124 uint64_t* public_exponent, 125 uint32_t* key_size) const { 126 if (!updated_description || !public_exponent || !key_size) 127 return KM_ERROR_OUTPUT_PARAMETER_NULL; 128 129 UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey; 130 keymaster_error_t error = 131 KeyMaterialToEvpKey(key_format, key_material, keymaster_key_type(), &pkey); 132 if (error != KM_ERROR_OK) 133 return error; 134 135 UniquePtr<RSA, RsaKey::RSA_Delete> rsa_key(EVP_PKEY_get1_RSA(pkey.get())); 136 if (!rsa_key.get()) 137 return TranslateLastOpenSslError(); 138 139 updated_description->Reinitialize(key_description); 140 141 *public_exponent = BN_get_word(rsa_key->e); 142 if (*public_exponent == 0xffffffffL) 143 return KM_ERROR_INVALID_KEY_BLOB; 144 if (!updated_description->GetTagValue(TAG_RSA_PUBLIC_EXPONENT, public_exponent)) 145 updated_description->push_back(TAG_RSA_PUBLIC_EXPONENT, *public_exponent); 146 if (*public_exponent != BN_get_word(rsa_key->e)) { 147 LOG_E("Imported public exponent (%u) does not match specified public exponent (%u)", 148 *public_exponent, BN_get_word(rsa_key->e)); 149 return KM_ERROR_IMPORT_PARAMETER_MISMATCH; 150 } 151 152 *key_size = RSA_size(rsa_key.get()) * 8; 153 if (!updated_description->GetTagValue(TAG_KEY_SIZE, key_size)) 154 updated_description->push_back(TAG_KEY_SIZE, *key_size); 155 if (RSA_size(rsa_key.get()) * 8 != *key_size) { 156 LOG_E("Imported key size (%u bits) does not match specified key size (%u bits)", 157 RSA_size(rsa_key.get()) * 8, *key_size); 158 return KM_ERROR_IMPORT_PARAMETER_MISMATCH; 159 } 160 161 keymaster_algorithm_t algorithm = KM_ALGORITHM_RSA; 162 if (!updated_description->GetTagValue(TAG_ALGORITHM, &algorithm)) 163 updated_description->push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA); 164 if (algorithm != KM_ALGORITHM_RSA) 165 return KM_ERROR_IMPORT_PARAMETER_MISMATCH; 166 167 return KM_ERROR_OK; 168 } 169 170 keymaster_error_t RsaKeyFactory::CreateEmptyKey(const AuthorizationSet& hw_enforced, 171 const AuthorizationSet& sw_enforced, 172 UniquePtr<AsymmetricKey>* key) const { 173 keymaster_error_t error; 174 key->reset(new (std::nothrow) RsaKey(hw_enforced, sw_enforced, &error)); 175 if (!key->get()) 176 error = KM_ERROR_MEMORY_ALLOCATION_FAILED; 177 return error; 178 } 179 180 } // namespace keymaster 181