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/km_openssl/rsa_key_factory.h>
18
19 #include <keymaster/keymaster_context.h>
20 #include <keymaster/km_openssl/openssl_err.h>
21 #include <keymaster/km_openssl/openssl_utils.h>
22 #include <keymaster/km_openssl/rsa_key.h>
23 #include <keymaster/km_openssl/rsa_operation.h>
24
25 namespace keymaster {
26
27 const int kMaximumRsaKeySize = 4096; // OpenSSL fails above 4096.
28 const int kMinimumRsaKeySize = 16; // OpenSSL goes into an infinite loop if key size < 10
29 const int kMinimumRsaExponent = 3;
30
31 static RsaSigningOperationFactory sign_factory;
32 static RsaVerificationOperationFactory verify_factory;
33 static RsaEncryptionOperationFactory encrypt_factory;
34 static RsaDecryptionOperationFactory decrypt_factory;
35
GetOperationFactory(keymaster_purpose_t purpose) const36 OperationFactory* RsaKeyFactory::GetOperationFactory(keymaster_purpose_t purpose) const {
37 switch (purpose) {
38 case KM_PURPOSE_SIGN:
39 return &sign_factory;
40 case KM_PURPOSE_VERIFY:
41 return &verify_factory;
42 case KM_PURPOSE_ENCRYPT:
43 return &encrypt_factory;
44 case KM_PURPOSE_DECRYPT:
45 return &decrypt_factory;
46 default:
47 return nullptr;
48 }
49 }
50
GenerateKey(const AuthorizationSet & key_description,UniquePtr<Key> attest_key,const KeymasterBlob & issuer_subject,KeymasterKeyBlob * key_blob,AuthorizationSet * hw_enforced,AuthorizationSet * sw_enforced,CertificateChain * cert_chain) const51 keymaster_error_t RsaKeyFactory::GenerateKey(const AuthorizationSet& key_description,
52 UniquePtr<Key> attest_key, //
53 const KeymasterBlob& issuer_subject,
54 KeymasterKeyBlob* key_blob,
55 AuthorizationSet* hw_enforced,
56 AuthorizationSet* sw_enforced,
57 CertificateChain* cert_chain) const {
58 if (!key_blob || !hw_enforced || !sw_enforced) return KM_ERROR_OUTPUT_PARAMETER_NULL;
59
60 uint64_t public_exponent;
61 if (!key_description.GetTagValue(TAG_RSA_PUBLIC_EXPONENT, &public_exponent)) {
62 LOG_E("No public exponent specified for RSA key generation", 0);
63 return KM_ERROR_INVALID_ARGUMENT;
64 }
65 if (public_exponent < kMinimumRsaExponent || public_exponent % 2 != 1) {
66 LOG_E("Invalid public exponent specified for RSA key generation", 0);
67 return KM_ERROR_INVALID_ARGUMENT;
68 }
69
70 uint32_t key_size;
71 if (!key_description.GetTagValue(TAG_KEY_SIZE, &key_size)) {
72 LOG_E("No key size specified for RSA key generation", 0);
73 return KM_ERROR_UNSUPPORTED_KEY_SIZE;
74 }
75 if (key_size % 8 != 0 || key_size > kMaximumRsaKeySize || key_size < kMinimumRsaKeySize) {
76 LOG_E("Invalid key size of %u bits specified for RSA key generation", key_size);
77 return KM_ERROR_UNSUPPORTED_KEY_SIZE;
78 }
79
80 BIGNUM_Ptr exponent(BN_new());
81 RSA_Ptr rsa_key(RSA_new());
82 EVP_PKEY_Ptr pkey(EVP_PKEY_new());
83 if (exponent.get() == nullptr || rsa_key.get() == nullptr || pkey.get() == nullptr) {
84 return KM_ERROR_MEMORY_ALLOCATION_FAILED;
85 }
86
87 if (!BN_set_word(exponent.get(), public_exponent) ||
88 !RSA_generate_key_ex(rsa_key.get(), key_size, exponent.get(), nullptr /* callback */))
89 return TranslateLastOpenSslError();
90
91 if (EVP_PKEY_set1_RSA(pkey.get(), rsa_key.get()) != 1) return TranslateLastOpenSslError();
92
93 KeymasterKeyBlob key_material;
94 keymaster_error_t error = EvpKeyToKeyMaterial(pkey.get(), &key_material);
95 if (error != KM_ERROR_OK) return error;
96
97 error = blob_maker_.CreateKeyBlob(key_description, KM_ORIGIN_GENERATED, key_material, key_blob,
98 hw_enforced, sw_enforced);
99 if (error != KM_ERROR_OK) return error;
100
101 if (context_.GetKmVersion() < KmVersion::KEYMINT_1) return KM_ERROR_OK;
102 if (!cert_chain) return KM_ERROR_UNEXPECTED_NULL_POINTER;
103
104 RsaKey key(*hw_enforced, *sw_enforced, this, move(rsa_key));
105 if (key_description.Contains(TAG_ATTESTATION_CHALLENGE)) {
106 *cert_chain = context_.GenerateAttestation(key, key_description, move(attest_key),
107 issuer_subject, &error);
108 } else if (attest_key.get() != nullptr) {
109 return KM_ERROR_ATTESTATION_CHALLENGE_MISSING;
110 } else {
111 bool fake_signature = key_size < 1024 || !IsCertSigningKey(key_description);
112 *cert_chain =
113 context_.GenerateSelfSignedCertificate(key, key_description, fake_signature, &error);
114 }
115
116 return error;
117 }
118
ImportKey(const AuthorizationSet & key_description,keymaster_key_format_t input_key_material_format,const KeymasterKeyBlob & input_key_material,UniquePtr<Key> attest_key,const KeymasterBlob & issuer_subject,KeymasterKeyBlob * output_key_blob,AuthorizationSet * hw_enforced,AuthorizationSet * sw_enforced,CertificateChain * cert_chain) const119 keymaster_error_t RsaKeyFactory::ImportKey(const AuthorizationSet& key_description, //
120 keymaster_key_format_t input_key_material_format,
121 const KeymasterKeyBlob& input_key_material,
122 UniquePtr<Key> attest_key, //
123 const KeymasterBlob& issuer_subject,
124 KeymasterKeyBlob* output_key_blob,
125 AuthorizationSet* hw_enforced,
126 AuthorizationSet* sw_enforced,
127 CertificateChain* cert_chain) const {
128 if (!output_key_blob || !hw_enforced || !sw_enforced) return KM_ERROR_OUTPUT_PARAMETER_NULL;
129
130 AuthorizationSet authorizations;
131 uint64_t public_exponent;
132 uint32_t key_size;
133 keymaster_error_t error =
134 UpdateImportKeyDescription(key_description, input_key_material_format, input_key_material,
135 &authorizations, &public_exponent, &key_size);
136 if (error != KM_ERROR_OK) return error;
137 error = blob_maker_.CreateKeyBlob(authorizations, KM_ORIGIN_IMPORTED, input_key_material,
138 output_key_blob, hw_enforced, sw_enforced);
139 if (error != KM_ERROR_OK) return error;
140
141 if (context_.GetKmVersion() < KmVersion::KEYMINT_1) return KM_ERROR_OK;
142 if (!cert_chain) return KM_ERROR_UNEXPECTED_NULL_POINTER;
143
144 EVP_PKEY_Ptr pkey;
145 error = KeyMaterialToEvpKey(KM_KEY_FORMAT_PKCS8, input_key_material, KM_ALGORITHM_RSA, &pkey);
146 if (error != KM_ERROR_OK) return error;
147
148 RSA_Ptr rsa_key(EVP_PKEY_get1_RSA(pkey.get()));
149 if (!rsa_key.get()) return KM_ERROR_INVALID_ARGUMENT;
150
151 RsaKey key(*hw_enforced, *sw_enforced, this, move(rsa_key));
152 if (key_description.Contains(KM_TAG_ATTESTATION_CHALLENGE)) {
153 *cert_chain = context_.GenerateAttestation(key, key_description, move(attest_key),
154 issuer_subject, &error);
155 } else if (attest_key.get() != nullptr) {
156 return KM_ERROR_ATTESTATION_CHALLENGE_MISSING;
157 } else {
158 bool fake_signature = key_size < 1024 || !IsCertSigningKey(key_description);
159 *cert_chain =
160 context_.GenerateSelfSignedCertificate(key, key_description, fake_signature, &error);
161 }
162
163 return error;
164 }
165
UpdateImportKeyDescription(const AuthorizationSet & key_description,keymaster_key_format_t key_format,const KeymasterKeyBlob & key_material,AuthorizationSet * updated_description,uint64_t * public_exponent,uint32_t * key_size) const166 keymaster_error_t RsaKeyFactory::UpdateImportKeyDescription(const AuthorizationSet& key_description,
167 keymaster_key_format_t key_format,
168 const KeymasterKeyBlob& key_material,
169 AuthorizationSet* updated_description,
170 uint64_t* public_exponent,
171 uint32_t* key_size) const {
172 if (!updated_description || !public_exponent || !key_size)
173 return KM_ERROR_OUTPUT_PARAMETER_NULL;
174
175 EVP_PKEY_Ptr pkey;
176 keymaster_error_t error =
177 KeyMaterialToEvpKey(key_format, key_material, keymaster_key_type(), &pkey);
178 if (error != KM_ERROR_OK) return error;
179
180 RSA_Ptr rsa_key(EVP_PKEY_get1_RSA(pkey.get()));
181 if (!rsa_key.get()) return TranslateLastOpenSslError();
182
183 updated_description->Reinitialize(key_description);
184
185 *public_exponent = BN_get_word(rsa_key->e);
186 if (*public_exponent == 0xffffffffL) return KM_ERROR_INVALID_KEY_BLOB;
187 if (!updated_description->GetTagValue(TAG_RSA_PUBLIC_EXPONENT, public_exponent))
188 updated_description->push_back(TAG_RSA_PUBLIC_EXPONENT, *public_exponent);
189 if (*public_exponent != BN_get_word(rsa_key->e)) {
190 LOG_E("Imported public exponent (%u) does not match specified public exponent (%u)",
191 *public_exponent, BN_get_word(rsa_key->e));
192 return KM_ERROR_IMPORT_PARAMETER_MISMATCH;
193 }
194
195 *key_size = RSA_size(rsa_key.get()) * 8;
196 if (!updated_description->GetTagValue(TAG_KEY_SIZE, key_size))
197 updated_description->push_back(TAG_KEY_SIZE, *key_size);
198 if (RSA_size(rsa_key.get()) * 8 != *key_size) {
199 LOG_E("Imported key size (%u bits) does not match specified key size (%u bits)",
200 RSA_size(rsa_key.get()) * 8, *key_size);
201 return KM_ERROR_IMPORT_PARAMETER_MISMATCH;
202 }
203
204 keymaster_algorithm_t algorithm = KM_ALGORITHM_RSA;
205 if (!updated_description->GetTagValue(TAG_ALGORITHM, &algorithm))
206 updated_description->push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA);
207 if (algorithm != KM_ALGORITHM_RSA) return KM_ERROR_IMPORT_PARAMETER_MISMATCH;
208
209 return KM_ERROR_OK;
210 }
211
CreateEmptyKey(AuthorizationSet && hw_enforced,AuthorizationSet && sw_enforced,UniquePtr<AsymmetricKey> * key) const212 keymaster_error_t RsaKeyFactory::CreateEmptyKey(AuthorizationSet&& hw_enforced,
213 AuthorizationSet&& sw_enforced,
214 UniquePtr<AsymmetricKey>* key) const {
215 key->reset(new (std::nothrow) RsaKey(move(hw_enforced), move(sw_enforced), this));
216 if (!(*key)) return KM_ERROR_MEMORY_ALLOCATION_FAILED;
217 return KM_ERROR_OK;
218 }
219
220 } // namespace keymaster
221