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