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