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