1 /*
2 **
3 ** Copyright 2017, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18 #include <openssl/evp.h>
19 #include <openssl/x509v3.h>
20
21 #include <hardware/keymaster_defs.h>
22
23 #include <keymaster/authorization_set.h>
24 #include <keymaster/km_openssl/asymmetric_key.h>
25 #include <keymaster/km_openssl/attestation_record.h>
26 #include <keymaster/km_openssl/attestation_utils.h>
27 #include <keymaster/km_openssl/certificate_utils.h>
28 #include <keymaster/km_openssl/openssl_err.h>
29 #include <keymaster/km_openssl/openssl_utils.h>
30
31 namespace keymaster {
32
33 namespace {
34
make_cert_chain(X509 * certificate,CertificateChain chain,keymaster_error_t * error)35 CertificateChain make_cert_chain(X509* certificate, CertificateChain chain,
36 keymaster_error_t* error) {
37 keymaster_blob_t blob{};
38 *error = encode_certificate(certificate, &blob);
39 if (*error != KM_ERROR_OK) return {};
40
41 if (!chain.push_front(blob)) {
42 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
43 return {};
44 }
45 return chain;
46 }
47
build_attestation_extension(const AuthorizationSet & attest_params,const AuthorizationSet & tee_enforced,const AuthorizationSet & sw_enforced,const AttestationContext & context,X509_EXTENSION_Ptr * extension)48 keymaster_error_t build_attestation_extension(const AuthorizationSet& attest_params,
49 const AuthorizationSet& tee_enforced,
50 const AuthorizationSet& sw_enforced,
51 const AttestationContext& context,
52 X509_EXTENSION_Ptr* extension) {
53 ASN1_OBJECT_Ptr oid(
54 OBJ_txt2obj(kAsn1TokenOid, 1 /* accept numerical dotted string form only */));
55 if (!oid.get()) return TranslateLastOpenSslError();
56
57 UniquePtr<uint8_t[]> attest_bytes;
58 size_t attest_bytes_len;
59 keymaster_error_t error = build_attestation_record(attest_params, sw_enforced, tee_enforced,
60 context, &attest_bytes, &attest_bytes_len);
61 if (error != KM_ERROR_OK) return error;
62
63 ASN1_OCTET_STRING_Ptr attest_str(ASN1_OCTET_STRING_new());
64 if (!attest_str.get() ||
65 !ASN1_OCTET_STRING_set(attest_str.get(), attest_bytes.get(), attest_bytes_len)) {
66 return TranslateLastOpenSslError();
67 }
68
69 extension->reset(
70 X509_EXTENSION_create_by_OBJ(nullptr, oid.get(), 0 /* not critical */, attest_str.get()));
71 if (!extension->get()) {
72 return TranslateLastOpenSslError();
73 }
74
75 return KM_ERROR_OK;
76 }
77
build_eat_extension(const AuthorizationSet & attest_params,const AuthorizationSet & tee_enforced,const AuthorizationSet & sw_enforced,const AttestationContext & context,X509_EXTENSION_Ptr * extension)78 keymaster_error_t build_eat_extension(const AuthorizationSet& attest_params,
79 const AuthorizationSet& tee_enforced,
80 const AuthorizationSet& sw_enforced,
81 const AttestationContext& context, //
82 X509_EXTENSION_Ptr* extension) {
83 ASN1_OBJECT_Ptr oid(
84 OBJ_txt2obj(kEatTokenOid, 1 /* accept numerical dotted string form only */));
85 if (!oid.get()) {
86 return TranslateLastOpenSslError();
87 }
88
89 std::vector<uint8_t> eat_bytes;
90 keymaster_error_t error =
91 build_eat_record(attest_params, sw_enforced, tee_enforced, context, &eat_bytes);
92 if (error != KM_ERROR_OK) return error;
93
94 ASN1_OCTET_STRING_Ptr eat_str(ASN1_OCTET_STRING_new());
95 if (!eat_str.get() ||
96 !ASN1_OCTET_STRING_set(eat_str.get(), eat_bytes.data(), eat_bytes.size())) {
97 return TranslateLastOpenSslError();
98 }
99
100 extension->reset(
101 X509_EXTENSION_create_by_OBJ(nullptr, oid.get(), 0 /* not critical */, eat_str.get()));
102 if (!extension->get()) {
103 return TranslateLastOpenSslError();
104 }
105
106 return KM_ERROR_OK;
107 }
108
add_attestation_extension(const AuthorizationSet & attest_params,const AuthorizationSet & tee_enforced,const AuthorizationSet & sw_enforced,const AttestationContext & context,X509 * certificate)109 keymaster_error_t add_attestation_extension(const AuthorizationSet& attest_params,
110 const AuthorizationSet& tee_enforced,
111 const AuthorizationSet& sw_enforced,
112 const AttestationContext& context, //
113 X509* certificate) {
114 X509_EXTENSION_Ptr attest_extension;
115 if (context.GetKmVersion() <= KmVersion::KEYMINT_1) {
116 if (auto error = build_attestation_extension(attest_params, tee_enforced, sw_enforced,
117 context, &attest_extension)) {
118 return error;
119 }
120 } else {
121 if (auto error = build_eat_extension(attest_params, tee_enforced, sw_enforced, context,
122 &attest_extension)) {
123 return error;
124 }
125 }
126
127 if (!X509_add_ext(certificate, attest_extension.get() /* Don't release; copied */,
128 -1 /* insert at end */)) {
129 return TranslateLastOpenSslError();
130 }
131
132 return KM_ERROR_OK;
133 }
134
make_attestation_cert(const EVP_PKEY * evp_pkey,const X509_NAME * issuer,const CertificateCallerParams & cert_params,const AuthorizationSet & attest_params,const AuthorizationSet & tee_enforced,const AuthorizationSet & sw_enforced,const AttestationContext & context,X509_Ptr * cert_out)135 keymaster_error_t make_attestation_cert(const EVP_PKEY* evp_pkey, const X509_NAME* issuer,
136 const CertificateCallerParams& cert_params,
137 const AuthorizationSet& attest_params,
138 const AuthorizationSet& tee_enforced,
139 const AuthorizationSet& sw_enforced,
140 const AttestationContext& context, X509_Ptr* cert_out) {
141
142 // First make the basic certificate with usage extension.
143 X509_Ptr certificate;
144 if (auto error = make_cert(evp_pkey, issuer, cert_params, &certificate)) {
145 return error;
146 }
147
148 // Add attestation extension.
149 if (auto error = add_attestation_extension(attest_params, tee_enforced, sw_enforced, context,
150 certificate.get())) {
151 return error;
152 }
153
154 *cert_out = move(certificate);
155 return KM_ERROR_OK;
156 }
157
get_issuer_subject(const AttestKeyInfo & attest_key,keymaster_error_t * error)158 X509_NAME_Ptr get_issuer_subject(const AttestKeyInfo& attest_key, keymaster_error_t* error) {
159 // Use subject from attest_key.
160 const uint8_t* p = attest_key.issuer_subject->data;
161 if (!p || !attest_key.issuer_subject->data_length) {
162 *error = KM_ERROR_MISSING_ISSUER_SUBJECT;
163 return {};
164 }
165 X509_NAME_Ptr retval(d2i_X509_NAME(nullptr /* Allocate X509_NAME */, &p,
166 attest_key.issuer_subject->data_length));
167 if (!retval) *error = KM_ERROR_INVALID_ISSUER_SUBJECT;
168 return retval;
169 }
170
get_issuer_subject(const keymaster_blob_t & signing_cert_der,keymaster_error_t * error)171 X509_NAME_Ptr get_issuer_subject(const keymaster_blob_t& signing_cert_der,
172 keymaster_error_t* error) {
173 const uint8_t* p = signing_cert_der.data;
174 if (!p) {
175 *error = KM_ERROR_UNEXPECTED_NULL_POINTER;
176 return {};
177 }
178 X509_Ptr signing_cert(d2i_X509(nullptr /* Allocate X509 */, &p, signing_cert_der.data_length));
179 if (!signing_cert) {
180 *error = TranslateLastOpenSslError();
181 return {};
182 }
183
184 X509_NAME* issuer_subject = X509_get_subject_name(signing_cert.get());
185 if (!issuer_subject) {
186 *error = TranslateLastOpenSslError();
187 return {};
188 }
189
190 X509_NAME_Ptr retval(X509_NAME_dup(issuer_subject));
191 if (!retval) *error = TranslateLastOpenSslError();
192
193 return retval;
194 }
195
196 // Return subject from attest_key, if non-null, otherwise extract from cert_chain.
get_issuer_subject(const AttestKeyInfo & attest_key,const CertificateChain & cert_chain,keymaster_error_t * error)197 X509_NAME_Ptr get_issuer_subject(const AttestKeyInfo& attest_key,
198 const CertificateChain& cert_chain, keymaster_error_t* error) {
199 if (attest_key) {
200 return get_issuer_subject(attest_key, error);
201 }
202
203 // Need to extract issuer from cert chain. First cert in the chain is the signing key cert.
204 if (cert_chain.entry_count >= 1) return get_issuer_subject(cert_chain.entries[0], error);
205
206 *error = KM_ERROR_UNKNOWN_ERROR;
207 return {};
208 }
209
check_attest_key_auths(const Key & key)210 keymaster_error_t check_attest_key_auths(const Key& key) {
211 auto auths = key.authorizations();
212
213 if (!auths.Contains(TAG_ALGORITHM, KM_ALGORITHM_RSA) &&
214 !auths.Contains(TAG_ALGORITHM, KM_ALGORITHM_EC)) {
215 return KM_ERROR_INCOMPATIBLE_ALGORITHM;
216 }
217 if (!auths.Contains(TAG_PURPOSE, KM_PURPOSE_ATTEST_KEY)) {
218 return KM_ERROR_INCOMPATIBLE_PURPOSE;
219 }
220 return KM_ERROR_OK;
221 }
222
get_attestation_key(keymaster_algorithm_t algorithm,const AttestationContext & context,keymaster_error_t * error)223 EVP_PKEY_Ptr get_attestation_key(keymaster_algorithm_t algorithm, const AttestationContext& context,
224 keymaster_error_t* error) {
225 KeymasterKeyBlob signing_key_blob = context.GetAttestationKey(algorithm, error);
226 if (*error != KM_ERROR_OK) return {};
227
228 const uint8_t* p = signing_key_blob.key_material;
229 EVP_PKEY_Ptr retval(
230 d2i_AutoPrivateKey(nullptr /* Allocate key */, &p, signing_key_blob.key_material_size));
231 if (!retval) *error = TranslateLastOpenSslError();
232 return retval;
233 }
234
235 } // namespace
236
AttestKeyInfo(const UniquePtr<Key> & key,const KeymasterBlob * issuer_subject_,keymaster_error_t * error)237 AttestKeyInfo::AttestKeyInfo(const UniquePtr<Key>& key, const KeymasterBlob* issuer_subject_,
238 keymaster_error_t* error)
239 : issuer_subject(issuer_subject_) {
240 if (!error) return;
241
242 if (!key) {
243 // No key... so this is just an empty AttestKeyInfo.
244 issuer_subject = nullptr;
245 return;
246 }
247
248 if (!issuer_subject) {
249 *error = KM_ERROR_UNEXPECTED_NULL_POINTER;
250 return;
251 }
252
253 *error = check_attest_key_auths(*key);
254 if (*error != KM_ERROR_OK) return;
255
256 signing_key.reset(EVP_PKEY_new());
257 if (!signing_key) {
258 *error = TranslateLastOpenSslError();
259 return;
260 }
261
262 if (!static_cast<const AsymmetricKey&>(*key).InternalToEvp(signing_key.get())) {
263 *error = KM_ERROR_UNKNOWN_ERROR;
264 }
265 }
266
generate_attestation(const AsymmetricKey & key,const AuthorizationSet & attest_params,AttestKeyInfo attest_key,const AttestationContext & context,keymaster_error_t * error)267 CertificateChain generate_attestation(const AsymmetricKey& key,
268 const AuthorizationSet& attest_params,
269 AttestKeyInfo attest_key,
270 const AttestationContext& context, //
271 keymaster_error_t* error) {
272 EVP_PKEY_Ptr pkey(EVP_PKEY_new());
273 if (!key.InternalToEvp(pkey.get())) {
274 *error = TranslateLastOpenSslError();
275 return {};
276 }
277
278 return generate_attestation(pkey.get(), key.sw_enforced(), key.hw_enforced(), attest_params,
279 move(attest_key), context, error);
280 }
281
generate_attestation(const EVP_PKEY * evp_key,const AuthorizationSet & sw_enforced,const AuthorizationSet & tee_enforced,const AuthorizationSet & attest_params,AttestKeyInfo attest_key,const AttestationContext & context,keymaster_error_t * error)282 CertificateChain generate_attestation(const EVP_PKEY* evp_key, //
283 const AuthorizationSet& sw_enforced, //
284 const AuthorizationSet& tee_enforced,
285 const AuthorizationSet& attest_params,
286 AttestKeyInfo attest_key,
287 const AttestationContext& context, //
288 keymaster_error_t* error) {
289 if (!error) return {};
290
291 CertificateCallerParams cert_params{};
292 *error = get_certificate_params(attest_params, &cert_params, context.GetKmVersion());
293 if (*error != KM_ERROR_OK) return {};
294
295 AuthProxy proxy(tee_enforced, sw_enforced);
296 cert_params.is_signing_key = (proxy.Contains(TAG_PURPOSE, KM_PURPOSE_SIGN) ||
297 proxy.Contains(TAG_PURPOSE, KM_PURPOSE_ATTEST_KEY));
298 cert_params.is_encryption_key = proxy.Contains(TAG_PURPOSE, KM_PURPOSE_DECRYPT);
299 cert_params.is_agreement_key = proxy.Contains(TAG_PURPOSE, KM_PURPOSE_AGREE_KEY);
300
301 keymaster_algorithm_t algorithm;
302 if (!proxy.GetTagValue(TAG_ALGORITHM, &algorithm)) {
303 *error = KM_ERROR_UNSUPPORTED_PURPOSE;
304 return {};
305 }
306
307 CertificateChain cert_chain =
308 attest_key ? CertificateChain() : context.GetAttestationChain(algorithm, error);
309 if (*error != KM_ERROR_OK) return {};
310
311 X509_NAME_Ptr issuer_subject = get_issuer_subject(attest_key, cert_chain, error);
312 if (*error != KM_ERROR_OK) return {};
313
314 X509_Ptr certificate;
315 *error = make_attestation_cert(evp_key, issuer_subject.get(), cert_params, attest_params,
316 tee_enforced, sw_enforced, context, &certificate);
317 if (*error != KM_ERROR_OK) return {};
318
319 EVP_PKEY_Ptr signing_key;
320 const EVP_PKEY* signing_key_ptr = attest_key.signing_key.get();
321 if (!signing_key_ptr) {
322 signing_key = get_attestation_key(algorithm, context, error);
323 if (*error != KM_ERROR_OK) return {};
324 signing_key_ptr = signing_key.get();
325 }
326
327 *error = sign_cert(certificate.get(), signing_key_ptr);
328 if (*error != KM_ERROR_OK) return {};
329
330 return make_cert_chain(certificate.get(), move(cert_chain), error);
331 }
332
333 } // namespace keymaster
334