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