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