blob: 8551ab7b6d9c706e14f895c87b311764df7383bf [file] [log] [blame]
David Zeuthen630de2a2020-05-11 14:04:54 -04001/*
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>
David Zeuthen1eb12b22021-09-11 13:59:43 -040026#include <map>
David Zeuthen630de2a2020-05-11 14:04:54 -040027
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
47using ::std::optional;
48using ::std::string;
49using ::std::tuple;
50using ::std::vector;
51
52namespace android::hardware::identity {
53
54// ----------------------------------------------------------------------
55
David Zeuthen1eb12b22021-09-11 13:59:43 -040056// The singleton EicProvisioning object used everywhere.
57//
58EicProvisioning FakeSecureHardwareProvisioningProxy::ctx_;
David Zeuthen630de2a2020-05-11 14:04:54 -040059
David Zeuthen1eb12b22021-09-11 13:59:43 -040060FakeSecureHardwareProvisioningProxy::~FakeSecureHardwareProvisioningProxy() {
61 if (id_ != 0) {
62 shutdown();
63 }
David Zeuthen630de2a2020-05-11 14:04:54 -040064}
65
66bool FakeSecureHardwareProvisioningProxy::initialize(bool testCredential) {
David Zeuthen1eb12b22021-09-11 13:59:43 -040067 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;
David Zeuthen630de2a2020-05-11 14:04:54 -040082}
83
David Zeuthen49f2d252020-10-16 11:27:24 -040084bool FakeSecureHardwareProvisioningProxy::initializeForUpdate(
David Zeuthen1eb12b22021-09-11 13:59:43 -040085 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
106optional<uint32_t> FakeSecureHardwareProvisioningProxy::getId() {
107 uint32_t id;
108 if (!eicProvisioningGetId(&ctx_, &id)) {
109 return std::nullopt;
110 }
111 return id;
112}
113
114bool 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
134bool 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;
David Zeuthen49f2d252020-10-16 11:27:24 -0400145}
146
David Zeuthen630de2a2020-05-11 14:04:54 -0400147// Returns public key certificate.
148optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::createCredentialKey(
149 const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId) {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400150 if (!validateId(__func__)) {
151 return std::nullopt;
152 }
153
David Zeuthen630de2a2020-05-11 14:04:54 -0400154 uint8_t publicKeyCert[4096];
155 size_t publicKeyCertSize = sizeof publicKeyCert;
156 if (!eicProvisioningCreateCredentialKey(&ctx_, challenge.data(), challenge.size(),
157 applicationId.data(), applicationId.size(),
Seth Moore1bf823c2022-01-25 23:04:37 +0000158 /*attestationKeyBlob=*/nullptr,
159 /*attestationKeyBlobSize=*/0,
160 /*attestationKeyCert=*/nullptr,
161 /*attestationKeyCertSize=*/0, publicKeyCert,
162 &publicKeyCertSize)) {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400163 return std::nullopt;
David Zeuthen630de2a2020-05-11 14:04:54 -0400164 }
165 vector<uint8_t> pubKeyCert(publicKeyCertSize);
166 memcpy(pubKeyCert.data(), publicKeyCert, publicKeyCertSize);
167 return pubKeyCert;
168}
169
Seth Moore1bf823c2022-01-25 23:04:37 +0000170optional<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
David Zeuthen630de2a2020-05-11 14:04:54 -0400187bool FakeSecureHardwareProvisioningProxy::startPersonalization(
David Zeuthen1eb12b22021-09-11 13:59:43 -0400188 int accessControlProfileCount, const vector<int>& entryCounts, const string& docType,
David Zeuthen630de2a2020-05-11 14:04:54 -0400189 size_t expectedProofOfProvisioningSize) {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400190 if (!validateId(__func__)) {
191 return false;
192 }
Joseph Jangdabb3c52021-09-01 16:50:09 +0800193
194 if (!eicProvisioningStartPersonalization(&ctx_, accessControlProfileCount,
195 entryCounts.data(),
196 entryCounts.size(),
197 docType.c_str(), docType.size(),
David Zeuthen630de2a2020-05-11 14:04:54 -0400198 expectedProofOfProvisioningSize)) {
199 return false;
200 }
201 return true;
202}
203
204// Returns MAC (28 bytes).
205optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::addAccessControlProfile(
206 int id, const vector<uint8_t>& readerCertificate, bool userAuthenticationRequired,
207 uint64_t timeoutMillis, uint64_t secureUserId) {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400208 if (!validateId(__func__)) {
209 return std::nullopt;
210 }
211
David Zeuthen630de2a2020-05-11 14:04:54 -0400212 vector<uint8_t> mac(28);
Joseph Jangdabb3c52021-09-01 16:50:09 +0800213 uint8_t scratchSpace[512];
David Zeuthen630de2a2020-05-11 14:04:54 -0400214 if (!eicProvisioningAddAccessControlProfile(
215 &ctx_, id, readerCertificate.data(), readerCertificate.size(),
Joseph Jangdabb3c52021-09-01 16:50:09 +0800216 userAuthenticationRequired, timeoutMillis, secureUserId, mac.data(),
217 scratchSpace, sizeof(scratchSpace))) {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400218 return std::nullopt;
David Zeuthen630de2a2020-05-11 14:04:54 -0400219 }
220 return mac;
221}
222
223bool FakeSecureHardwareProvisioningProxy::beginAddEntry(const vector<int>& accessControlProfileIds,
224 const string& nameSpace, const string& name,
225 uint64_t entrySize) {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400226 if (!validateId(__func__)) {
227 return false;
228 }
229
David Zeuthen630de2a2020-05-11 14:04:54 -0400230 uint8_t scratchSpace[512];
Joseph Jangdabb3c52021-09-01 16:50:09 +0800231 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));
David Zeuthen630de2a2020-05-11 14:04:54 -0400240}
241
242// Returns encryptedContent.
243optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::addEntryValue(
244 const vector<int>& accessControlProfileIds, const string& nameSpace, const string& name,
245 const vector<uint8_t>& content) {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400246 if (!validateId(__func__)) {
247 return std::nullopt;
248 }
249
David Zeuthen630de2a2020-05-11 14:04:54 -0400250 vector<uint8_t> eicEncryptedContent;
251 uint8_t scratchSpace[512];
Joseph Jangdabb3c52021-09-01 16:50:09 +0800252 vector<uint8_t> uint8AccessControlProfileIds;
253 for (size_t i = 0; i < accessControlProfileIds.size(); i++) {
254 uint8AccessControlProfileIds.push_back(accessControlProfileIds[i] & 0xFF);
255 }
256
David Zeuthen630de2a2020-05-11 14:04:54 -0400257 eicEncryptedContent.resize(content.size() + 28);
258 if (!eicProvisioningAddEntryValue(
Joseph Jangdabb3c52021-09-01 16:50:09 +0800259 &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))) {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400262 return std::nullopt;
David Zeuthen630de2a2020-05-11 14:04:54 -0400263 }
264 return eicEncryptedContent;
265}
266
267// Returns signatureOfToBeSigned (EIC_ECDSA_P256_SIGNATURE_SIZE bytes).
268optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::finishAddingEntries() {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400269 if (!validateId(__func__)) {
270 return std::nullopt;
271 }
272
David Zeuthen630de2a2020-05-11 14:04:54 -0400273 vector<uint8_t> signatureOfToBeSigned(EIC_ECDSA_P256_SIGNATURE_SIZE);
274 if (!eicProvisioningFinishAddingEntries(&ctx_, signatureOfToBeSigned.data())) {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400275 return std::nullopt;
David Zeuthen630de2a2020-05-11 14:04:54 -0400276 }
277 return signatureOfToBeSigned;
278}
279
David Zeuthen49f2d252020-10-16 11:27:24 -0400280// Returns encryptedCredentialKeys.
David Zeuthen630de2a2020-05-11 14:04:54 -0400281optional<vector<uint8_t>> FakeSecureHardwareProvisioningProxy::finishGetCredentialData(
282 const string& docType) {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400283 if (!validateId(__func__)) {
284 return std::nullopt;
285 }
286
David Zeuthen49f2d252020-10-16 11:27:24 -0400287 vector<uint8_t> encryptedCredentialKeys(116);
288 size_t size = encryptedCredentialKeys.size();
Joseph Jangdabb3c52021-09-01 16:50:09 +0800289 if (!eicProvisioningFinishGetCredentialData(&ctx_, docType.c_str(), docType.size(),
David Zeuthen49f2d252020-10-16 11:27:24 -0400290 encryptedCredentialKeys.data(), &size)) {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400291 return std::nullopt;
David Zeuthen630de2a2020-05-11 14:04:54 -0400292 }
David Zeuthen49f2d252020-10-16 11:27:24 -0400293 encryptedCredentialKeys.resize(size);
David Zeuthen630de2a2020-05-11 14:04:54 -0400294 return encryptedCredentialKeys;
295}
296
297// ----------------------------------------------------------------------
298
David Zeuthen1eb12b22021-09-11 13:59:43 -0400299// The singleton EicSession object used everywhere.
300//
301EicSession FakeSecureHardwareSessionProxy::ctx_;
David Zeuthen630de2a2020-05-11 14:04:54 -0400302
David Zeuthen1eb12b22021-09-11 13:59:43 -0400303FakeSecureHardwareSessionProxy::~FakeSecureHardwareSessionProxy() {
304 if (id_ != 0) {
305 shutdown();
306 }
307}
David Zeuthen630de2a2020-05-11 14:04:54 -0400308
David Zeuthen1eb12b22021-09-11 13:59:43 -0400309bool 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
327optional<uint32_t> FakeSecureHardwareSessionProxy::getId() {
328 uint32_t id;
329 if (!eicSessionGetId(&ctx_, &id)) {
330 return std::nullopt;
331 }
332 return id;
333}
334
335bool 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
348bool 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
368optional<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
380optional<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
392bool 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
401bool 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//
415EicPresentation FakeSecureHardwarePresentationProxy::ctx_;
416
417FakeSecureHardwarePresentationProxy::~FakeSecureHardwarePresentationProxy() {
418 if (id_ != 0) {
419 shutdown();
420 }
421}
422
423bool 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
445optional<uint32_t> FakeSecureHardwarePresentationProxy::getId() {
446 uint32_t id;
447 if (!eicPresentationGetId(&ctx_, &id)) {
448 return std::nullopt;
449 }
450 return id;
451}
452
453bool 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
473bool 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;
David Zeuthen630de2a2020-05-11 14:04:54 -0400484}
485
486// Returns publicKeyCert (1st component) and signingKeyBlob (2nd component)
487optional<pair<vector<uint8_t>, vector<uint8_t>>>
David Zeuthen1eb12b22021-09-11 13:59:43 -0400488FakeSecureHardwarePresentationProxy::generateSigningKeyPair(const string& docType, time_t now) {
489 if (!validateId(__func__)) {
490 return std::nullopt;
491 }
492
David Zeuthen630de2a2020-05-11 14:04:54 -0400493 uint8_t publicKeyCert[512];
494 size_t publicKeyCertSize = sizeof(publicKeyCert);
495 vector<uint8_t> signingKeyBlob(60);
496
Joseph Jangdabb3c52021-09-01 16:50:09 +0800497 if (!eicPresentationGenerateSigningKeyPair(&ctx_, docType.c_str(), docType.size(), now,
498 publicKeyCert, &publicKeyCertSize,
499 signingKeyBlob.data())) {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400500 return std::nullopt;
David Zeuthen630de2a2020-05-11 14:04:54 -0400501 }
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
511optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::createEphemeralKeyPair() {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400512 if (!validateId(__func__)) {
513 return std::nullopt;
514 }
515
David Zeuthen630de2a2020-05-11 14:04:54 -0400516 vector<uint8_t> priv(EIC_P256_PRIV_KEY_SIZE);
517 if (!eicPresentationCreateEphemeralKeyPair(&ctx_, priv.data())) {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400518 return std::nullopt;
David Zeuthen630de2a2020-05-11 14:04:54 -0400519 }
520 return priv;
521}
522
523optional<uint64_t> FakeSecureHardwarePresentationProxy::createAuthChallenge() {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400524 if (!validateId(__func__)) {
525 return std::nullopt;
526 }
527
David Zeuthen630de2a2020-05-11 14:04:54 -0400528 uint64_t challenge;
529 if (!eicPresentationCreateAuthChallenge(&ctx_, &challenge)) {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400530 return std::nullopt;
David Zeuthen630de2a2020-05-11 14:04:54 -0400531 }
532 return challenge;
533}
534
David Zeuthen630de2a2020-05-11 14:04:54 -0400535bool FakeSecureHardwarePresentationProxy::pushReaderCert(const vector<uint8_t>& certX509) {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400536 if (!validateId(__func__)) {
537 return false;
538 }
539
David Zeuthen630de2a2020-05-11 14:04:54 -0400540 return eicPresentationPushReaderCert(&ctx_, certX509.data(), certX509.size());
541}
542
543bool FakeSecureHardwarePresentationProxy::validateRequestMessage(
544 const vector<uint8_t>& sessionTranscript, const vector<uint8_t>& requestMessage,
545 int coseSignAlg, const vector<uint8_t>& readerSignatureOfToBeSigned) {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400546 if (!validateId(__func__)) {
547 return false;
548 }
549
David Zeuthen630de2a2020-05-11 14:04:54 -0400550 return eicPresentationValidateRequestMessage(
551 &ctx_, sessionTranscript.data(), sessionTranscript.size(), requestMessage.data(),
552 requestMessage.size(), coseSignAlg, readerSignatureOfToBeSigned.data(),
553 readerSignatureOfToBeSigned.size());
554}
555
556bool 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) {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400561 if (!validateId(__func__)) {
562 return false;
563 }
564
David Zeuthen630de2a2020-05-11 14:04:54 -0400565 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
572optional<bool> FakeSecureHardwarePresentationProxy::validateAccessControlProfile(
573 int id, const vector<uint8_t>& readerCertificate, bool userAuthenticationRequired,
574 int timeoutMillis, uint64_t secureUserId, const vector<uint8_t>& mac) {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400575 if (!validateId(__func__)) {
576 return std::nullopt;
577 }
578
David Zeuthen630de2a2020-05-11 14:04:54 -0400579 bool accessGranted = false;
Joseph Jangdabb3c52021-09-01 16:50:09 +0800580 uint8_t scratchSpace[512];
David Zeuthen630de2a2020-05-11 14:04:54 -0400581 if (!eicPresentationValidateAccessControlProfile(&ctx_, id, readerCertificate.data(),
582 readerCertificate.size(),
583 userAuthenticationRequired, timeoutMillis,
Joseph Jangdabb3c52021-09-01 16:50:09 +0800584 secureUserId, mac.data(), &accessGranted,
585 scratchSpace, sizeof(scratchSpace))) {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400586 return std::nullopt;
David Zeuthen630de2a2020-05-11 14:04:54 -0400587 }
588 return accessGranted;
589}
590
591bool FakeSecureHardwarePresentationProxy::startRetrieveEntries() {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400592 if (!validateId(__func__)) {
593 return false;
594 }
595
David Zeuthen630de2a2020-05-11 14:04:54 -0400596 return eicPresentationStartRetrieveEntries(&ctx_);
597}
598
David Zeuthenf3e06002022-10-04 13:17:14 -0400599bool FakeSecureHardwarePresentationProxy::prepareDeviceAuthentication(
David Zeuthen630de2a2020-05-11 14:04:54 -0400600 const vector<uint8_t>& sessionTranscript, const vector<uint8_t>& readerEphemeralPublicKey,
601 const vector<uint8_t>& signingKeyBlob, const string& docType,
David Zeuthenf3e06002022-10-04 13:17:14 -0400602 unsigned int numNamespacesWithValues, size_t expectedDeviceNamespacesSize) {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400603 if (!validateId(__func__)) {
604 return false;
605 }
606
David Zeuthen630de2a2020-05-11 14:04:54 -0400607 if (signingKeyBlob.size() != 60) {
608 eicDebug("Unexpected size %zd of signingKeyBlob, expected 60", signingKeyBlob.size());
609 return false;
610 }
David Zeuthenf3e06002022-10-04 13:17:14 -0400611 return eicPresentationPrepareDeviceAuthentication(
612 &ctx_, sessionTranscript.data(), sessionTranscript.size(),
613 readerEphemeralPublicKey.data(), readerEphemeralPublicKey.size(), signingKeyBlob.data(),
614 docType.c_str(), docType.size(), numNamespacesWithValues, expectedDeviceNamespacesSize);
David Zeuthen630de2a2020-05-11 14:04:54 -0400615}
616
617AccessCheckResult FakeSecureHardwarePresentationProxy::startRetrieveEntryValue(
618 const string& nameSpace, const string& name, unsigned int newNamespaceNumEntries,
619 int32_t entrySize, const vector<int32_t>& accessControlProfileIds) {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400620 if (!validateId(__func__)) {
621 return AccessCheckResult::kFailed;
622 }
623
David Zeuthen630de2a2020-05-11 14:04:54 -0400624 uint8_t scratchSpace[512];
Joseph Jangdabb3c52021-09-01 16:50:09 +0800625 vector<uint8_t> uint8AccessControlProfileIds;
626 for (size_t i = 0; i < accessControlProfileIds.size(); i++) {
627 uint8AccessControlProfileIds.push_back(accessControlProfileIds[i] & 0xFF);
628 }
629
David Zeuthen630de2a2020-05-11 14:04:54 -0400630 EicAccessCheckResult result = eicPresentationStartRetrieveEntryValue(
Joseph Jangdabb3c52021-09-01 16:50:09 +0800631 &ctx_, nameSpace.c_str(), nameSpace.size(), name.c_str(), name.size(),
632 newNamespaceNumEntries, entrySize, uint8AccessControlProfileIds.data(),
633 uint8AccessControlProfileIds.size(), scratchSpace,
634 sizeof(scratchSpace));
David Zeuthen630de2a2020-05-11 14:04:54 -0400635 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
651optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::retrieveEntryValue(
652 const vector<uint8_t>& encryptedContent, const string& nameSpace, const string& name,
653 const vector<int32_t>& accessControlProfileIds) {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400654 if (!validateId(__func__)) {
655 return std::nullopt;
656 }
657
David Zeuthen630de2a2020-05-11 14:04:54 -0400658 uint8_t scratchSpace[512];
Joseph Jangdabb3c52021-09-01 16:50:09 +0800659 vector<uint8_t> uint8AccessControlProfileIds;
660 for (size_t i = 0; i < accessControlProfileIds.size(); i++) {
661 uint8AccessControlProfileIds.push_back(accessControlProfileIds[i] & 0xFF);
662 }
663
David Zeuthen630de2a2020-05-11 14:04:54 -0400664 vector<uint8_t> content;
665 content.resize(encryptedContent.size() - 28);
666 if (!eicPresentationRetrieveEntryValue(
667 &ctx_, encryptedContent.data(), encryptedContent.size(), content.data(),
Joseph Jangdabb3c52021-09-01 16:50:09 +0800668 nameSpace.c_str(), nameSpace.size(), name.c_str(), name.size(),
669 uint8AccessControlProfileIds.data(), uint8AccessControlProfileIds.size(),
670 scratchSpace, sizeof(scratchSpace))) {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400671 return std::nullopt;
David Zeuthen630de2a2020-05-11 14:04:54 -0400672 }
673 return content;
674}
675
David Zeuthenf3e06002022-10-04 13:17:14 -0400676optional<pair<vector<uint8_t>, vector<uint8_t>>>
677FakeSecureHardwarePresentationProxy::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
David Zeuthen630de2a2020-05-11 14:04:54 -0400695optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::finishRetrieval() {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400696 if (!validateId(__func__)) {
697 return std::nullopt;
698 }
699
David Zeuthen630de2a2020-05-11 14:04:54 -0400700 vector<uint8_t> mac(32);
701 size_t macSize = 32;
702 if (!eicPresentationFinishRetrieval(&ctx_, mac.data(), &macSize)) {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400703 return std::nullopt;
David Zeuthen630de2a2020-05-11 14:04:54 -0400704 }
705 mac.resize(macSize);
706 return mac;
707}
708
709optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::deleteCredential(
David Zeuthen49f2d252020-10-16 11:27:24 -0400710 const string& docType, const vector<uint8_t>& challenge, bool includeChallenge,
711 size_t proofOfDeletionCborSize) {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400712 if (!validateId(__func__)) {
713 return std::nullopt;
714 }
715
David Zeuthen630de2a2020-05-11 14:04:54 -0400716 vector<uint8_t> signatureOfToBeSigned(EIC_ECDSA_P256_SIGNATURE_SIZE);
Joseph Jangdabb3c52021-09-01 16:50:09 +0800717 if (!eicPresentationDeleteCredential(&ctx_, docType.c_str(), docType.size(), challenge.data(),
718 challenge.size(), includeChallenge,
719 proofOfDeletionCborSize, signatureOfToBeSigned.data())) {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400720 return std::nullopt;
David Zeuthen630de2a2020-05-11 14:04:54 -0400721 }
722 return signatureOfToBeSigned;
723}
724
David Zeuthen49f2d252020-10-16 11:27:24 -0400725optional<vector<uint8_t>> FakeSecureHardwarePresentationProxy::proveOwnership(
726 const string& docType, bool testCredential, const vector<uint8_t>& challenge,
727 size_t proofOfOwnershipCborSize) {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400728 if (!validateId(__func__)) {
729 return std::nullopt;
730 }
731
David Zeuthen49f2d252020-10-16 11:27:24 -0400732 vector<uint8_t> signatureOfToBeSigned(EIC_ECDSA_P256_SIGNATURE_SIZE);
Joseph Jangdabb3c52021-09-01 16:50:09 +0800733 if (!eicPresentationProveOwnership(&ctx_, docType.c_str(), docType.size(), testCredential,
734 challenge.data(), challenge.size(), proofOfOwnershipCborSize,
David Zeuthen49f2d252020-10-16 11:27:24 -0400735 signatureOfToBeSigned.data())) {
David Zeuthen1eb12b22021-09-11 13:59:43 -0400736 return std::nullopt;
David Zeuthen49f2d252020-10-16 11:27:24 -0400737 }
738 return signatureOfToBeSigned;
739}
740
David Zeuthen630de2a2020-05-11 14:04:54 -0400741} // namespace android::hardware::identity