1 /*
2  * Copyright 2020, 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 #define LOG_TAG "FakeSecureHardwareProxy"
18 
19 #include "FakeSecureHardwareProxy.h"
20 
21 #include <android/hardware/identity/support/IdentityCredentialSupport.h>
22 
23 #include <android-base/logging.h>
24 #include <android-base/stringprintf.h>
25 #include <string.h>
26 #include <map>
27 
28 #include <openssl/sha.h>
29 
30 #include <openssl/aes.h>
31 #include <openssl/bn.h>
32 #include <openssl/crypto.h>
33 #include <openssl/ec.h>
34 #include <openssl/err.h>
35 #include <openssl/evp.h>
36 #include <openssl/hkdf.h>
37 #include <openssl/hmac.h>
38 #include <openssl/objects.h>
39 #include <openssl/pem.h>
40 #include <openssl/pkcs12.h>
41 #include <openssl/rand.h>
42 #include <openssl/x509.h>
43 #include <openssl/x509_vfy.h>
44 
45 #include <libeic.h>
46 
47 using ::std::optional;
48 using ::std::string;
49 using ::std::tuple;
50 using ::std::vector;
51 
52 namespace android::hardware::identity {
53 
54 // ----------------------------------------------------------------------
55 
56 // The singleton EicProvisioning object used everywhere.
57 //
58 EicProvisioning FakeSecureHardwareProvisioningProxy::ctx_;
59 
~FakeSecureHardwareProvisioningProxy()60 FakeSecureHardwareProvisioningProxy::~FakeSecureHardwareProvisioningProxy() {
61     if (id_ != 0) {
62         shutdown();
63     }
64 }
65 
initialize(bool testCredential)66 bool FakeSecureHardwareProvisioningProxy::initialize(bool testCredential) {
67     if (id_ != 0) {
68         LOG(WARNING) << "Proxy is already initialized";
69         return false;
70     }
71     bool initialized = eicProvisioningInit(&ctx_, testCredential);
72     if (!initialized) {
73         return false;
74     }
75     optional<uint32_t> id = getId();
76     if (!id) {
77         LOG(WARNING) << "Error getting id";
78         return false;
79     }
80     id_ = id.value();
81     return true;
82 }
83 
initializeForUpdate(bool testCredential,const string & docType,const vector<uint8_t> & encryptedCredentialKeys)84 bool FakeSecureHardwareProvisioningProxy::initializeForUpdate(
85         bool testCredential, const string& docType,
86         const vector<uint8_t>& encryptedCredentialKeys) {
87     if (id_ != 0) {
88         LOG(WARNING) << "Proxy is already initialized";
89         return false;
90     }
91     bool initialized = eicProvisioningInitForUpdate(&ctx_, testCredential, docType.c_str(),
92                                                     docType.size(), encryptedCredentialKeys.data(),
93                                                     encryptedCredentialKeys.size());
94     if (!initialized) {
95         return false;
96     }
97     optional<uint32_t> id = getId();
98     if (!id) {
99         LOG(WARNING) << "Error getting id";
100         return false;
101     }
102     id_ = id.value();
103     return true;
104 }
105 
getId()106 optional<uint32_t> FakeSecureHardwareProvisioningProxy::getId() {
107     uint32_t id;
108     if (!eicProvisioningGetId(&ctx_, &id)) {
109         return std::nullopt;
110     }
111     return id;
112 }
113 
validateId(const string & callerName)114 bool FakeSecureHardwareProvisioningProxy::validateId(const string& callerName) {
115     if (id_ == 0) {
116         LOG(WARNING) << "FakeSecureHardwareProvisioningProxy::" << callerName
117                      << ": While validating expected id is 0";
118         return false;
119     }
120     optional<uint32_t> id = getId();
121     if (!id) {
122         LOG(WARNING) << "FakeSecureHardwareProvisioningProxy::" << callerName
123                      << ": Error getting id for validating";
124         return false;
125     }
126     if (id.value() != id_) {
127         LOG(WARNING) << "FakeSecureHardwareProvisioningProxy::" << callerName
128                      << ": While validating expected id " << id_ << " but got " << id.value();
129         return false;
130     }
131     return true;
132 }
133 
shutdown()134 bool FakeSecureHardwareProvisioningProxy::shutdown() {
135     bool validated = validateId(__func__);
136     id_ = 0;
137     if (!validated) {
138         return false;
139     }
140     if (!eicProvisioningShutdown(&ctx_)) {
141         LOG(INFO) << "Error shutting down provisioning";
142         return false;
143     }
144     return true;
145 }
146 
147 // Returns public key certificate.
createCredentialKey(const vector<uint8_t> & challenge,const vector<uint8_t> & applicationId)148 optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::createCredentialKey(
149         const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId) {
150     if (!validateId(__func__)) {
151         return std::nullopt;
152     }
153 
154     uint8_t publicKeyCert[4096];
155     size_t publicKeyCertSize = sizeof publicKeyCert;
156     if (!eicProvisioningCreateCredentialKey(&ctx_, challenge.data(), challenge.size(),
157                                             applicationId.data(), applicationId.size(),
158                                             /*attestationKeyBlob=*/nullptr,
159                                             /*attestationKeyBlobSize=*/0,
160                                             /*attestationKeyCert=*/nullptr,
161                                             /*attestationKeyCertSize=*/0, publicKeyCert,
162                                             &publicKeyCertSize)) {
163         return std::nullopt;
164     }
165     vector<uint8_t> pubKeyCert(publicKeyCertSize);
166     memcpy(pubKeyCert.data(), publicKeyCert, publicKeyCertSize);
167     return pubKeyCert;
168 }
169 
createCredentialKeyUsingRkp(const vector<uint8_t> & challenge,const vector<uint8_t> & applicationId,const vector<uint8_t> & attestationKeyBlob,const vector<uint8_t> & attstationKeyCert)170 optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::createCredentialKeyUsingRkp(
171         const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId,
172         const vector<uint8_t>& attestationKeyBlob, const vector<uint8_t>& attstationKeyCert) {
173     size_t publicKeyCertSize = 4096;
174     vector<uint8_t> publicKeyCert(publicKeyCertSize);
175     if (!eicProvisioningCreateCredentialKey(&ctx_, challenge.data(), challenge.size(),
176                                             applicationId.data(), applicationId.size(),
177                                             attestationKeyBlob.data(), attestationKeyBlob.size(),
178                                             attstationKeyCert.data(), attstationKeyCert.size(),
179                                             publicKeyCert.data(), &publicKeyCertSize)) {
180         LOG(ERROR) << "error creating credential key";
181         return std::nullopt;
182     }
183     publicKeyCert.resize(publicKeyCertSize);
184     return publicKeyCert;
185 }
186 
startPersonalization(int accessControlProfileCount,const vector<int> & entryCounts,const string & docType,size_t expectedProofOfProvisioningSize)187 bool FakeSecureHardwareProvisioningProxy::startPersonalization(
188         int accessControlProfileCount, const vector<int>& entryCounts, const string& docType,
189         size_t expectedProofOfProvisioningSize) {
190     if (!validateId(__func__)) {
191         return false;
192     }
193 
194     if (!eicProvisioningStartPersonalization(&ctx_, accessControlProfileCount,
195                                              entryCounts.data(),
196                                              entryCounts.size(),
197                                              docType.c_str(), docType.size(),
198                                              expectedProofOfProvisioningSize)) {
199         return false;
200     }
201     return true;
202 }
203 
204 // Returns MAC (28 bytes).
addAccessControlProfile(int id,const vector<uint8_t> & readerCertificate,bool userAuthenticationRequired,uint64_t timeoutMillis,uint64_t secureUserId)205 optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::addAccessControlProfile(
206         int id, const vector<uint8_t>& readerCertificate, bool userAuthenticationRequired,
207         uint64_t timeoutMillis, uint64_t secureUserId) {
208     if (!validateId(__func__)) {
209         return std::nullopt;
210     }
211 
212     vector<uint8_t> mac(28);
213     uint8_t scratchSpace[512];
214     if (!eicProvisioningAddAccessControlProfile(
215                 &ctx_, id, readerCertificate.data(), readerCertificate.size(),
216                 userAuthenticationRequired, timeoutMillis, secureUserId, mac.data(),
217                 scratchSpace, sizeof(scratchSpace))) {
218         return std::nullopt;
219     }
220     return mac;
221 }
222 
beginAddEntry(const vector<int> & accessControlProfileIds,const string & nameSpace,const string & name,uint64_t entrySize)223 bool FakeSecureHardwareProvisioningProxy::beginAddEntry(const vector<int>& accessControlProfileIds,
224                                                         const string& nameSpace, const string& name,
225                                                         uint64_t entrySize) {
226     if (!validateId(__func__)) {
227         return false;
228     }
229 
230     uint8_t scratchSpace[512];
231     vector<uint8_t> uint8AccessControlProfileIds;
232     for (size_t i = 0; i < accessControlProfileIds.size(); i++) {
233         uint8AccessControlProfileIds.push_back(accessControlProfileIds[i] & 0xFF);
234     }
235 
236     return eicProvisioningBeginAddEntry(&ctx_, uint8AccessControlProfileIds.data(),
237                                         uint8AccessControlProfileIds.size(), nameSpace.c_str(),
238                                         nameSpace.size(), name.c_str(), name.size(), entrySize,
239                                         scratchSpace, sizeof(scratchSpace));
240 }
241 
242 // Returns encryptedContent.
addEntryValue(const vector<int> & accessControlProfileIds,const string & nameSpace,const string & name,const vector<uint8_t> & content)243 optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::addEntryValue(
244         const vector<int>& accessControlProfileIds, const string& nameSpace, const string& name,
245         const vector<uint8_t>& content) {
246     if (!validateId(__func__)) {
247         return std::nullopt;
248     }
249 
250     vector<uint8_t> eicEncryptedContent;
251     uint8_t scratchSpace[512];
252     vector<uint8_t> uint8AccessControlProfileIds;
253     for (size_t i = 0; i < accessControlProfileIds.size(); i++) {
254         uint8AccessControlProfileIds.push_back(accessControlProfileIds[i] & 0xFF);
255     }
256 
257     eicEncryptedContent.resize(content.size() + 28);
258     if (!eicProvisioningAddEntryValue(
259                 &ctx_, uint8AccessControlProfileIds.data(), uint8AccessControlProfileIds.size(),
260                 nameSpace.c_str(), nameSpace.size(), name.c_str(), name.size(), content.data(),
261                 content.size(), eicEncryptedContent.data(), scratchSpace, sizeof(scratchSpace))) {
262         return std::nullopt;
263     }
264     return eicEncryptedContent;
265 }
266 
267 // Returns signatureOfToBeSigned (EIC_ECDSA_P256_SIGNATURE_SIZE bytes).
finishAddingEntries()268 optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::finishAddingEntries() {
269     if (!validateId(__func__)) {
270         return std::nullopt;
271     }
272 
273     vector<uint8_t> signatureOfToBeSigned(EIC_ECDSA_P256_SIGNATURE_SIZE);
274     if (!eicProvisioningFinishAddingEntries(&ctx_, signatureOfToBeSigned.data())) {
275         return std::nullopt;
276     }
277     return signatureOfToBeSigned;
278 }
279 
280 // Returns encryptedCredentialKeys.
finishGetCredentialData(const string & docType)281 optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::finishGetCredentialData(
282         const string& docType) {
283     if (!validateId(__func__)) {
284         return std::nullopt;
285     }
286 
287     vector<uint8_t> encryptedCredentialKeys(116);
288     size_t size = encryptedCredentialKeys.size();
289     if (!eicProvisioningFinishGetCredentialData(&ctx_, docType.c_str(), docType.size(),
290                                                 encryptedCredentialKeys.data(), &size)) {
291         return std::nullopt;
292     }
293     encryptedCredentialKeys.resize(size);
294     return encryptedCredentialKeys;
295 }
296 
297 // ----------------------------------------------------------------------
298 
299 // The singleton EicSession object used everywhere.
300 //
301 EicSession FakeSecureHardwareSessionProxy::ctx_;
302 
~FakeSecureHardwareSessionProxy()303 FakeSecureHardwareSessionProxy::~FakeSecureHardwareSessionProxy() {
304     if (id_ != 0) {
305         shutdown();
306     }
307 }
308 
initialize()309 bool FakeSecureHardwareSessionProxy::initialize() {
310     if (id_ != 0) {
311         LOG(WARNING) << "Proxy is already initialized";
312         return false;
313     }
314     bool initialized = eicSessionInit(&ctx_);
315     if (!initialized) {
316         return false;
317     }
318     optional<uint32_t> id = getId();
319     if (!id) {
320         LOG(WARNING) << "Error getting id";
321         return false;
322     }
323     id_ = id.value();
324     return true;
325 }
326 
getId()327 optional<uint32_t> FakeSecureHardwareSessionProxy::getId() {
328     uint32_t id;
329     if (!eicSessionGetId(&ctx_, &id)) {
330         return std::nullopt;
331     }
332     return id;
333 }
334 
shutdown()335 bool FakeSecureHardwareSessionProxy::shutdown() {
336     bool validated = validateId(__func__);
337     id_ = 0;
338     if (!validated) {
339         return false;
340     }
341     if (!eicSessionShutdown(&ctx_)) {
342         LOG(INFO) << "Error shutting down session";
343         return false;
344     }
345     return true;
346 }
347 
validateId(const string & callerName)348 bool FakeSecureHardwareSessionProxy::validateId(const string& callerName) {
349     if (id_ == 0) {
350         LOG(WARNING) << "FakeSecureHardwareSessionProxy::" << callerName
351                      << ": While validating expected id is 0";
352         return false;
353     }
354     optional<uint32_t> id = getId();
355     if (!id) {
356         LOG(WARNING) << "FakeSecureHardwareSessionProxy::" << callerName
357                      << ": Error getting id for validating";
358         return false;
359     }
360     if (id.value() != id_) {
361         LOG(WARNING) << "FakeSecureHardwareSessionProxy::" << callerName
362                      << ": While validating expected id " << id_ << " but got " << id.value();
363         return false;
364     }
365     return true;
366 }
367 
getAuthChallenge()368 optional<uint64_t> FakeSecureHardwareSessionProxy::getAuthChallenge() {
369     if (!validateId(__func__)) {
370         return std::nullopt;
371     }
372 
373     uint64_t authChallenge;
374     if (!eicSessionGetAuthChallenge(&ctx_, &authChallenge)) {
375         return std::nullopt;
376     }
377     return authChallenge;
378 }
379 
getEphemeralKeyPair()380 optional<vector<uint8_t>> FakeSecureHardwareSessionProxy::getEphemeralKeyPair() {
381     if (!validateId(__func__)) {
382         return std::nullopt;
383     }
384 
385     vector<uint8_t> priv(EIC_P256_PRIV_KEY_SIZE);
386     if (!eicSessionGetEphemeralKeyPair(&ctx_, priv.data())) {
387         return std::nullopt;
388     }
389     return priv;
390 }
391 
setReaderEphemeralPublicKey(const vector<uint8_t> & readerEphemeralPublicKey)392 bool FakeSecureHardwareSessionProxy::setReaderEphemeralPublicKey(
393         const vector<uint8_t>& readerEphemeralPublicKey) {
394     if (!validateId(__func__)) {
395         return false;
396     }
397 
398     return eicSessionSetReaderEphemeralPublicKey(&ctx_, readerEphemeralPublicKey.data());
399 }
400 
setSessionTranscript(const vector<uint8_t> & sessionTranscript)401 bool FakeSecureHardwareSessionProxy::setSessionTranscript(
402         const vector<uint8_t>& sessionTranscript) {
403     if (!validateId(__func__)) {
404         return false;
405     }
406 
407     return eicSessionSetSessionTranscript(&ctx_, sessionTranscript.data(),
408                                           sessionTranscript.size());
409 }
410 
411 // ----------------------------------------------------------------------
412 
413 // The singleton EicPresentation object used everywhere.
414 //
415 EicPresentation FakeSecureHardwarePresentationProxy::ctx_;
416 
~FakeSecureHardwarePresentationProxy()417 FakeSecureHardwarePresentationProxy::~FakeSecureHardwarePresentationProxy() {
418     if (id_ != 0) {
419         shutdown();
420     }
421 }
422 
initialize(uint32_t sessionId,bool testCredential,const string & docType,const vector<uint8_t> & encryptedCredentialKeys)423 bool FakeSecureHardwarePresentationProxy::initialize(
424         uint32_t sessionId, bool testCredential, const string& docType,
425         const vector<uint8_t>& encryptedCredentialKeys) {
426     if (id_ != 0) {
427         LOG(WARNING) << "Proxy is already initialized";
428         return false;
429     }
430     bool initialized =
431             eicPresentationInit(&ctx_, sessionId, testCredential, docType.c_str(), docType.size(),
432                                 encryptedCredentialKeys.data(), encryptedCredentialKeys.size());
433     if (!initialized) {
434         return false;
435     }
436     optional<uint32_t> id = getId();
437     if (!id) {
438         LOG(WARNING) << "Error getting id";
439         return false;
440     }
441     id_ = id.value();
442     return true;
443 }
444 
getId()445 optional<uint32_t> FakeSecureHardwarePresentationProxy::getId() {
446     uint32_t id;
447     if (!eicPresentationGetId(&ctx_, &id)) {
448         return std::nullopt;
449     }
450     return id;
451 }
452 
validateId(const string & callerName)453 bool FakeSecureHardwarePresentationProxy::validateId(const string& callerName) {
454     if (id_ == 0) {
455         LOG(WARNING) << "FakeSecureHardwarePresentationProxy::" << callerName
456                      << ": While validating expected id is 0";
457         return false;
458     }
459     optional<uint32_t> id = getId();
460     if (!id) {
461         LOG(WARNING) << "FakeSecureHardwarePresentationProxy::" << callerName
462                      << ": Error getting id for validating";
463         return false;
464     }
465     if (id.value() != id_) {
466         LOG(WARNING) << "FakeSecureHardwarePresentationProxy::" << callerName
467                      << ": While validating expected id " << id_ << " but got " << id.value();
468         return false;
469     }
470     return true;
471 }
472 
shutdown()473 bool FakeSecureHardwarePresentationProxy::shutdown() {
474     bool validated = validateId(__func__);
475     id_ = 0;
476     if (!validated) {
477         return false;
478     }
479     if (!eicPresentationShutdown(&ctx_)) {
480         LOG(INFO) << "Error shutting down presentation";
481         return false;
482     }
483     return true;
484 }
485 
486 // Returns publicKeyCert (1st component) and signingKeyBlob (2nd component)
487 optional<pair<vector<uint8_t>, vector<uint8_t>>>
generateSigningKeyPair(const string & docType,time_t now)488 FakeSecureHardwarePresentationProxy::generateSigningKeyPair(const string& docType, time_t now) {
489     if (!validateId(__func__)) {
490         return std::nullopt;
491     }
492 
493     uint8_t publicKeyCert[512];
494     size_t publicKeyCertSize = sizeof(publicKeyCert);
495     vector<uint8_t> signingKeyBlob(60);
496 
497     if (!eicPresentationGenerateSigningKeyPair(&ctx_, docType.c_str(), docType.size(), now,
498                                                publicKeyCert, &publicKeyCertSize,
499                                                signingKeyBlob.data())) {
500         return std::nullopt;
501     }
502 
503     vector<uint8_t> cert;
504     cert.resize(publicKeyCertSize);
505     memcpy(cert.data(), publicKeyCert, publicKeyCertSize);
506 
507     return std::make_pair(cert, signingKeyBlob);
508 }
509 
510 // Returns private key
createEphemeralKeyPair()511 optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::createEphemeralKeyPair() {
512     if (!validateId(__func__)) {
513         return std::nullopt;
514     }
515 
516     vector<uint8_t> priv(EIC_P256_PRIV_KEY_SIZE);
517     if (!eicPresentationCreateEphemeralKeyPair(&ctx_, priv.data())) {
518         return std::nullopt;
519     }
520     return priv;
521 }
522 
createAuthChallenge()523 optional<uint64_t> FakeSecureHardwarePresentationProxy::createAuthChallenge() {
524     if (!validateId(__func__)) {
525         return std::nullopt;
526     }
527 
528     uint64_t challenge;
529     if (!eicPresentationCreateAuthChallenge(&ctx_, &challenge)) {
530         return std::nullopt;
531     }
532     return challenge;
533 }
534 
pushReaderCert(const vector<uint8_t> & certX509)535 bool FakeSecureHardwarePresentationProxy::pushReaderCert(const vector<uint8_t>& certX509) {
536     if (!validateId(__func__)) {
537         return false;
538     }
539 
540     return eicPresentationPushReaderCert(&ctx_, certX509.data(), certX509.size());
541 }
542 
validateRequestMessage(const vector<uint8_t> & sessionTranscript,const vector<uint8_t> & requestMessage,int coseSignAlg,const vector<uint8_t> & readerSignatureOfToBeSigned)543 bool FakeSecureHardwarePresentationProxy::validateRequestMessage(
544         const vector<uint8_t>& sessionTranscript, const vector<uint8_t>& requestMessage,
545         int coseSignAlg, const vector<uint8_t>& readerSignatureOfToBeSigned) {
546     if (!validateId(__func__)) {
547         return false;
548     }
549 
550     return eicPresentationValidateRequestMessage(
551             &ctx_, sessionTranscript.data(), sessionTranscript.size(), requestMessage.data(),
552             requestMessage.size(), coseSignAlg, readerSignatureOfToBeSigned.data(),
553             readerSignatureOfToBeSigned.size());
554 }
555 
setAuthToken(uint64_t challenge,uint64_t secureUserId,uint64_t authenticatorId,int hardwareAuthenticatorType,uint64_t timeStamp,const vector<uint8_t> & mac,uint64_t verificationTokenChallenge,uint64_t verificationTokenTimestamp,int verificationTokenSecurityLevel,const vector<uint8_t> & verificationTokenMac)556 bool FakeSecureHardwarePresentationProxy::setAuthToken(
557         uint64_t challenge, uint64_t secureUserId, uint64_t authenticatorId,
558         int hardwareAuthenticatorType, uint64_t timeStamp, const vector<uint8_t>& mac,
559         uint64_t verificationTokenChallenge, uint64_t verificationTokenTimestamp,
560         int verificationTokenSecurityLevel, const vector<uint8_t>& verificationTokenMac) {
561     if (!validateId(__func__)) {
562         return false;
563     }
564 
565     return eicPresentationSetAuthToken(&ctx_, challenge, secureUserId, authenticatorId,
566                                        hardwareAuthenticatorType, timeStamp, mac.data(), mac.size(),
567                                        verificationTokenChallenge, verificationTokenTimestamp,
568                                        verificationTokenSecurityLevel, verificationTokenMac.data(),
569                                        verificationTokenMac.size());
570 }
571 
validateAccessControlProfile(int id,const vector<uint8_t> & readerCertificate,bool userAuthenticationRequired,int timeoutMillis,uint64_t secureUserId,const vector<uint8_t> & mac)572 optional<bool> FakeSecureHardwarePresentationProxy::validateAccessControlProfile(
573         int id, const vector<uint8_t>& readerCertificate, bool userAuthenticationRequired,
574         int timeoutMillis, uint64_t secureUserId, const vector<uint8_t>& mac) {
575     if (!validateId(__func__)) {
576         return std::nullopt;
577     }
578 
579     bool accessGranted = false;
580     uint8_t scratchSpace[512];
581     if (!eicPresentationValidateAccessControlProfile(&ctx_, id, readerCertificate.data(),
582                                                      readerCertificate.size(),
583                                                      userAuthenticationRequired, timeoutMillis,
584                                                      secureUserId, mac.data(), &accessGranted,
585                                                      scratchSpace, sizeof(scratchSpace))) {
586         return std::nullopt;
587     }
588     return accessGranted;
589 }
590 
startRetrieveEntries()591 bool FakeSecureHardwarePresentationProxy::startRetrieveEntries() {
592     if (!validateId(__func__)) {
593         return false;
594     }
595 
596     return eicPresentationStartRetrieveEntries(&ctx_);
597 }
598 
prepareDeviceAuthentication(const vector<uint8_t> & sessionTranscript,const vector<uint8_t> & readerEphemeralPublicKey,const vector<uint8_t> & signingKeyBlob,const string & docType,unsigned int numNamespacesWithValues,size_t expectedDeviceNamespacesSize)599 bool FakeSecureHardwarePresentationProxy::prepareDeviceAuthentication(
600         const vector<uint8_t>& sessionTranscript, const vector<uint8_t>& readerEphemeralPublicKey,
601         const vector<uint8_t>& signingKeyBlob, const string& docType,
602         unsigned int numNamespacesWithValues, size_t expectedDeviceNamespacesSize) {
603     if (!validateId(__func__)) {
604         return false;
605     }
606 
607     if (signingKeyBlob.size() != 60) {
608         eicDebug("Unexpected size %zd of signingKeyBlob, expected 60", signingKeyBlob.size());
609         return false;
610     }
611     return eicPresentationPrepareDeviceAuthentication(
612             &ctx_, sessionTranscript.data(), sessionTranscript.size(),
613             readerEphemeralPublicKey.data(), readerEphemeralPublicKey.size(), signingKeyBlob.data(),
614             docType.c_str(), docType.size(), numNamespacesWithValues, expectedDeviceNamespacesSize);
615 }
616 
startRetrieveEntryValue(const string & nameSpace,const string & name,unsigned int newNamespaceNumEntries,int32_t entrySize,const vector<int32_t> & accessControlProfileIds)617 AccessCheckResult FakeSecureHardwarePresentationProxy::startRetrieveEntryValue(
618         const string& nameSpace, const string& name, unsigned int newNamespaceNumEntries,
619         int32_t entrySize, const vector<int32_t>& accessControlProfileIds) {
620     if (!validateId(__func__)) {
621         return AccessCheckResult::kFailed;
622     }
623 
624     uint8_t scratchSpace[512];
625     vector<uint8_t> uint8AccessControlProfileIds;
626     for (size_t i = 0; i < accessControlProfileIds.size(); i++) {
627         uint8AccessControlProfileIds.push_back(accessControlProfileIds[i] & 0xFF);
628     }
629 
630     EicAccessCheckResult result = eicPresentationStartRetrieveEntryValue(
631             &ctx_, nameSpace.c_str(), nameSpace.size(), name.c_str(), name.size(),
632             newNamespaceNumEntries, entrySize, uint8AccessControlProfileIds.data(),
633             uint8AccessControlProfileIds.size(), scratchSpace,
634             sizeof(scratchSpace));
635     switch (result) {
636         case EIC_ACCESS_CHECK_RESULT_OK:
637             return AccessCheckResult::kOk;
638         case EIC_ACCESS_CHECK_RESULT_NO_ACCESS_CONTROL_PROFILES:
639             return AccessCheckResult::kNoAccessControlProfiles;
640         case EIC_ACCESS_CHECK_RESULT_FAILED:
641             return AccessCheckResult::kFailed;
642         case EIC_ACCESS_CHECK_RESULT_USER_AUTHENTICATION_FAILED:
643             return AccessCheckResult::kUserAuthenticationFailed;
644         case EIC_ACCESS_CHECK_RESULT_READER_AUTHENTICATION_FAILED:
645             return AccessCheckResult::kReaderAuthenticationFailed;
646     }
647     eicDebug("Unknown result with code %d, returning kFailed", (int)result);
648     return AccessCheckResult::kFailed;
649 }
650 
retrieveEntryValue(const vector<uint8_t> & encryptedContent,const string & nameSpace,const string & name,const vector<int32_t> & accessControlProfileIds)651 optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::retrieveEntryValue(
652         const vector<uint8_t>& encryptedContent, const string& nameSpace, const string& name,
653         const vector<int32_t>& accessControlProfileIds) {
654     if (!validateId(__func__)) {
655         return std::nullopt;
656     }
657 
658     uint8_t scratchSpace[512];
659     vector<uint8_t> uint8AccessControlProfileIds;
660     for (size_t i = 0; i < accessControlProfileIds.size(); i++) {
661         uint8AccessControlProfileIds.push_back(accessControlProfileIds[i] & 0xFF);
662     }
663 
664     vector<uint8_t> content;
665     content.resize(encryptedContent.size() - 28);
666     if (!eicPresentationRetrieveEntryValue(
667                 &ctx_, encryptedContent.data(), encryptedContent.size(), content.data(),
668                 nameSpace.c_str(), nameSpace.size(), name.c_str(), name.size(),
669                 uint8AccessControlProfileIds.data(), uint8AccessControlProfileIds.size(),
670                 scratchSpace, sizeof(scratchSpace))) {
671         return std::nullopt;
672     }
673     return content;
674 }
675 
676 optional<pair<vector<uint8_t>, vector<uint8_t>>>
finishRetrievalWithSignature()677 FakeSecureHardwarePresentationProxy::finishRetrievalWithSignature() {
678     if (!validateId(__func__)) {
679         return std::nullopt;
680     }
681 
682     vector<uint8_t> mac(32);
683     size_t macSize = 32;
684     vector<uint8_t> ecdsaSignature(EIC_ECDSA_P256_SIGNATURE_SIZE);
685     size_t ecdsaSignatureSize = EIC_ECDSA_P256_SIGNATURE_SIZE;
686     if (!eicPresentationFinishRetrievalWithSignature(&ctx_, mac.data(), &macSize,
687                                                      ecdsaSignature.data(), &ecdsaSignatureSize)) {
688         return std::nullopt;
689     }
690     mac.resize(macSize);
691     ecdsaSignature.resize(ecdsaSignatureSize);
692     return std::make_pair(mac, ecdsaSignature);
693 }
694 
finishRetrieval()695 optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::finishRetrieval() {
696     if (!validateId(__func__)) {
697         return std::nullopt;
698     }
699 
700     vector<uint8_t> mac(32);
701     size_t macSize = 32;
702     if (!eicPresentationFinishRetrieval(&ctx_, mac.data(), &macSize)) {
703         return std::nullopt;
704     }
705     mac.resize(macSize);
706     return mac;
707 }
708 
deleteCredential(const string & docType,const vector<uint8_t> & challenge,bool includeChallenge,size_t proofOfDeletionCborSize)709 optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::deleteCredential(
710         const string& docType, const vector<uint8_t>& challenge, bool includeChallenge,
711         size_t proofOfDeletionCborSize) {
712     if (!validateId(__func__)) {
713         return std::nullopt;
714     }
715 
716     vector<uint8_t> signatureOfToBeSigned(EIC_ECDSA_P256_SIGNATURE_SIZE);
717     if (!eicPresentationDeleteCredential(&ctx_, docType.c_str(), docType.size(), challenge.data(),
718                                          challenge.size(), includeChallenge,
719                                          proofOfDeletionCborSize, signatureOfToBeSigned.data())) {
720         return std::nullopt;
721     }
722     return signatureOfToBeSigned;
723 }
724 
proveOwnership(const string & docType,bool testCredential,const vector<uint8_t> & challenge,size_t proofOfOwnershipCborSize)725 optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::proveOwnership(
726         const string& docType, bool testCredential, const vector<uint8_t>& challenge,
727         size_t proofOfOwnershipCborSize) {
728     if (!validateId(__func__)) {
729         return std::nullopt;
730     }
731 
732     vector<uint8_t> signatureOfToBeSigned(EIC_ECDSA_P256_SIGNATURE_SIZE);
733     if (!eicPresentationProveOwnership(&ctx_, docType.c_str(), docType.size(), testCredential,
734                                        challenge.data(), challenge.size(), proofOfOwnershipCborSize,
735                                        signatureOfToBeSigned.data())) {
736         return std::nullopt;
737     }
738     return signatureOfToBeSigned;
739 }
740 
741 }  // namespace android::hardware::identity
742