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