xref: /aosp_15_r20/hardware/interfaces/identity/aidl/default/EicOpsImpl.cc (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
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 "EicOpsImpl"
18*4d7e907cSAndroid Build Coastguard Worker 
19*4d7e907cSAndroid Build Coastguard Worker #include <optional>
20*4d7e907cSAndroid Build Coastguard Worker #include <tuple>
21*4d7e907cSAndroid Build Coastguard Worker #include <vector>
22*4d7e907cSAndroid Build Coastguard Worker 
23*4d7e907cSAndroid Build Coastguard Worker #ifndef _GNU_SOURCE
24*4d7e907cSAndroid Build Coastguard Worker #define _GNU_SOURCE
25*4d7e907cSAndroid Build Coastguard Worker #endif
26*4d7e907cSAndroid Build Coastguard Worker #include <string.h>
27*4d7e907cSAndroid Build Coastguard Worker 
28*4d7e907cSAndroid Build Coastguard Worker #include <android-base/logging.h>
29*4d7e907cSAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
30*4d7e907cSAndroid Build Coastguard Worker 
31*4d7e907cSAndroid Build Coastguard Worker #include <android/hardware/identity/support/IdentityCredentialSupport.h>
32*4d7e907cSAndroid Build Coastguard Worker 
33*4d7e907cSAndroid Build Coastguard Worker #include <openssl/sha.h>
34*4d7e907cSAndroid Build Coastguard Worker 
35*4d7e907cSAndroid Build Coastguard Worker #include <openssl/aes.h>
36*4d7e907cSAndroid Build Coastguard Worker #include <openssl/bn.h>
37*4d7e907cSAndroid Build Coastguard Worker #include <openssl/crypto.h>
38*4d7e907cSAndroid Build Coastguard Worker #include <openssl/ec.h>
39*4d7e907cSAndroid Build Coastguard Worker #include <openssl/err.h>
40*4d7e907cSAndroid Build Coastguard Worker #include <openssl/evp.h>
41*4d7e907cSAndroid Build Coastguard Worker #include <openssl/hkdf.h>
42*4d7e907cSAndroid Build Coastguard Worker #include <openssl/hmac.h>
43*4d7e907cSAndroid Build Coastguard Worker #include <openssl/objects.h>
44*4d7e907cSAndroid Build Coastguard Worker #include <openssl/pem.h>
45*4d7e907cSAndroid Build Coastguard Worker #include <openssl/pkcs12.h>
46*4d7e907cSAndroid Build Coastguard Worker #include <openssl/rand.h>
47*4d7e907cSAndroid Build Coastguard Worker #include <openssl/x509.h>
48*4d7e907cSAndroid Build Coastguard Worker #include <openssl/x509_vfy.h>
49*4d7e907cSAndroid Build Coastguard Worker 
50*4d7e907cSAndroid Build Coastguard Worker #include "EicOps.h"
51*4d7e907cSAndroid Build Coastguard Worker 
52*4d7e907cSAndroid Build Coastguard Worker using ::std::map;
53*4d7e907cSAndroid Build Coastguard Worker using ::std::optional;
54*4d7e907cSAndroid Build Coastguard Worker using ::std::string;
55*4d7e907cSAndroid Build Coastguard Worker using ::std::tuple;
56*4d7e907cSAndroid Build Coastguard Worker using ::std::vector;
57*4d7e907cSAndroid Build Coastguard Worker 
eicMemSet(void * s,int c,size_t n)58*4d7e907cSAndroid Build Coastguard Worker void* eicMemSet(void* s, int c, size_t n) {
59*4d7e907cSAndroid Build Coastguard Worker     return memset(s, c, n);
60*4d7e907cSAndroid Build Coastguard Worker }
61*4d7e907cSAndroid Build Coastguard Worker 
eicMemCpy(void * dest,const void * src,size_t n)62*4d7e907cSAndroid Build Coastguard Worker void* eicMemCpy(void* dest, const void* src, size_t n) {
63*4d7e907cSAndroid Build Coastguard Worker     return memcpy(dest, src, n);
64*4d7e907cSAndroid Build Coastguard Worker }
65*4d7e907cSAndroid Build Coastguard Worker 
eicStrLen(const char * s)66*4d7e907cSAndroid Build Coastguard Worker size_t eicStrLen(const char* s) {
67*4d7e907cSAndroid Build Coastguard Worker     return strlen(s);
68*4d7e907cSAndroid Build Coastguard Worker }
69*4d7e907cSAndroid Build Coastguard Worker 
eicMemMem(const uint8_t * haystack,size_t haystackLen,const uint8_t * needle,size_t needleLen)70*4d7e907cSAndroid Build Coastguard Worker void* eicMemMem(const uint8_t* haystack, size_t haystackLen, const uint8_t* needle,
71*4d7e907cSAndroid Build Coastguard Worker                 size_t needleLen) {
72*4d7e907cSAndroid Build Coastguard Worker     return memmem(haystack, haystackLen, needle, needleLen);
73*4d7e907cSAndroid Build Coastguard Worker }
74*4d7e907cSAndroid Build Coastguard Worker 
eicCryptoMemCmp(const void * s1,const void * s2,size_t n)75*4d7e907cSAndroid Build Coastguard Worker int eicCryptoMemCmp(const void* s1, const void* s2, size_t n) {
76*4d7e907cSAndroid Build Coastguard Worker     return CRYPTO_memcmp(s1, s2, n);
77*4d7e907cSAndroid Build Coastguard Worker }
78*4d7e907cSAndroid Build Coastguard Worker 
eicOpsHmacSha256Init(EicHmacSha256Ctx * ctx,const uint8_t * key,size_t keySize)79*4d7e907cSAndroid Build Coastguard Worker void eicOpsHmacSha256Init(EicHmacSha256Ctx* ctx, const uint8_t* key, size_t keySize) {
80*4d7e907cSAndroid Build Coastguard Worker     HMAC_CTX* realCtx = (HMAC_CTX*)ctx;
81*4d7e907cSAndroid Build Coastguard Worker     HMAC_CTX_init(realCtx);
82*4d7e907cSAndroid Build Coastguard Worker     if (HMAC_Init_ex(realCtx, key, keySize, EVP_sha256(), nullptr /* impl */) != 1) {
83*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << "Error initializing HMAC_CTX";
84*4d7e907cSAndroid Build Coastguard Worker     }
85*4d7e907cSAndroid Build Coastguard Worker }
86*4d7e907cSAndroid Build Coastguard Worker 
eicOpsHmacSha256Update(EicHmacSha256Ctx * ctx,const uint8_t * data,size_t len)87*4d7e907cSAndroid Build Coastguard Worker void eicOpsHmacSha256Update(EicHmacSha256Ctx* ctx, const uint8_t* data, size_t len) {
88*4d7e907cSAndroid Build Coastguard Worker     HMAC_CTX* realCtx = (HMAC_CTX*)ctx;
89*4d7e907cSAndroid Build Coastguard Worker     if (HMAC_Update(realCtx, data, len) != 1) {
90*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << "Error updating HMAC_CTX";
91*4d7e907cSAndroid Build Coastguard Worker     }
92*4d7e907cSAndroid Build Coastguard Worker }
93*4d7e907cSAndroid Build Coastguard Worker 
eicOpsHmacSha256Final(EicHmacSha256Ctx * ctx,uint8_t digest[EIC_SHA256_DIGEST_SIZE])94*4d7e907cSAndroid Build Coastguard Worker void eicOpsHmacSha256Final(EicHmacSha256Ctx* ctx, uint8_t digest[EIC_SHA256_DIGEST_SIZE]) {
95*4d7e907cSAndroid Build Coastguard Worker     HMAC_CTX* realCtx = (HMAC_CTX*)ctx;
96*4d7e907cSAndroid Build Coastguard Worker     unsigned int size = 0;
97*4d7e907cSAndroid Build Coastguard Worker     if (HMAC_Final(realCtx, digest, &size) != 1) {
98*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << "Error finalizing HMAC_CTX";
99*4d7e907cSAndroid Build Coastguard Worker     }
100*4d7e907cSAndroid Build Coastguard Worker     if (size != EIC_SHA256_DIGEST_SIZE) {
101*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << "Expected 32 bytes from HMAC_Final, got " << size;
102*4d7e907cSAndroid Build Coastguard Worker     }
103*4d7e907cSAndroid Build Coastguard Worker     HMAC_CTX_cleanup(realCtx);
104*4d7e907cSAndroid Build Coastguard Worker }
105*4d7e907cSAndroid Build Coastguard Worker 
eicOpsSha256Init(EicSha256Ctx * ctx)106*4d7e907cSAndroid Build Coastguard Worker void eicOpsSha256Init(EicSha256Ctx* ctx) {
107*4d7e907cSAndroid Build Coastguard Worker     SHA256_CTX* realCtx = (SHA256_CTX*)ctx;
108*4d7e907cSAndroid Build Coastguard Worker     SHA256_Init(realCtx);
109*4d7e907cSAndroid Build Coastguard Worker }
110*4d7e907cSAndroid Build Coastguard Worker 
eicOpsSha256Update(EicSha256Ctx * ctx,const uint8_t * data,size_t len)111*4d7e907cSAndroid Build Coastguard Worker void eicOpsSha256Update(EicSha256Ctx* ctx, const uint8_t* data, size_t len) {
112*4d7e907cSAndroid Build Coastguard Worker     SHA256_CTX* realCtx = (SHA256_CTX*)ctx;
113*4d7e907cSAndroid Build Coastguard Worker     SHA256_Update(realCtx, data, len);
114*4d7e907cSAndroid Build Coastguard Worker }
115*4d7e907cSAndroid Build Coastguard Worker 
eicOpsSha256Final(EicSha256Ctx * ctx,uint8_t digest[EIC_SHA256_DIGEST_SIZE])116*4d7e907cSAndroid Build Coastguard Worker void eicOpsSha256Final(EicSha256Ctx* ctx, uint8_t digest[EIC_SHA256_DIGEST_SIZE]) {
117*4d7e907cSAndroid Build Coastguard Worker     SHA256_CTX* realCtx = (SHA256_CTX*)ctx;
118*4d7e907cSAndroid Build Coastguard Worker     SHA256_Final(digest, realCtx);
119*4d7e907cSAndroid Build Coastguard Worker }
120*4d7e907cSAndroid Build Coastguard Worker 
eicOpsRandom(uint8_t * buf,size_t numBytes)121*4d7e907cSAndroid Build Coastguard Worker bool eicOpsRandom(uint8_t* buf, size_t numBytes) {
122*4d7e907cSAndroid Build Coastguard Worker     optional<vector<uint8_t>> bytes = ::android::hardware::identity::support::getRandom(numBytes);
123*4d7e907cSAndroid Build Coastguard Worker     if (!bytes.has_value()) {
124*4d7e907cSAndroid Build Coastguard Worker         return false;
125*4d7e907cSAndroid Build Coastguard Worker     }
126*4d7e907cSAndroid Build Coastguard Worker     memcpy(buf, bytes.value().data(), numBytes);
127*4d7e907cSAndroid Build Coastguard Worker     return true;
128*4d7e907cSAndroid Build Coastguard Worker }
129*4d7e907cSAndroid Build Coastguard Worker 
eicNextId(uint32_t * id)130*4d7e907cSAndroid Build Coastguard Worker bool eicNextId(uint32_t* id) {
131*4d7e907cSAndroid Build Coastguard Worker     uint32_t oldId = *id;
132*4d7e907cSAndroid Build Coastguard Worker     uint32_t newId = 0;
133*4d7e907cSAndroid Build Coastguard Worker 
134*4d7e907cSAndroid Build Coastguard Worker     do {
135*4d7e907cSAndroid Build Coastguard Worker         union {
136*4d7e907cSAndroid Build Coastguard Worker             uint8_t value8;
137*4d7e907cSAndroid Build Coastguard Worker             uint32_t value32;
138*4d7e907cSAndroid Build Coastguard Worker         } value;
139*4d7e907cSAndroid Build Coastguard Worker         if (!eicOpsRandom(&value.value8, sizeof(value))) {
140*4d7e907cSAndroid Build Coastguard Worker             return false;
141*4d7e907cSAndroid Build Coastguard Worker         }
142*4d7e907cSAndroid Build Coastguard Worker         newId = value.value32;
143*4d7e907cSAndroid Build Coastguard Worker     } while (newId == oldId && newId == 0);
144*4d7e907cSAndroid Build Coastguard Worker 
145*4d7e907cSAndroid Build Coastguard Worker     *id = newId;
146*4d7e907cSAndroid Build Coastguard Worker     return true;
147*4d7e907cSAndroid Build Coastguard Worker }
148*4d7e907cSAndroid Build Coastguard Worker 
eicOpsEncryptAes128Gcm(const uint8_t * key,const uint8_t * nonce,const uint8_t * data,size_t dataSize,const uint8_t * additionalAuthenticationData,size_t additionalAuthenticationDataSize,uint8_t * encryptedData)149*4d7e907cSAndroid Build Coastguard Worker bool eicOpsEncryptAes128Gcm(
150*4d7e907cSAndroid Build Coastguard Worker         const uint8_t* key,    // Must be 16 bytes
151*4d7e907cSAndroid Build Coastguard Worker         const uint8_t* nonce,  // Must be 12 bytes
152*4d7e907cSAndroid Build Coastguard Worker         const uint8_t* data,   // May be NULL if size is 0
153*4d7e907cSAndroid Build Coastguard Worker         size_t dataSize,
154*4d7e907cSAndroid Build Coastguard Worker         const uint8_t* additionalAuthenticationData,  // May be NULL if size is 0
155*4d7e907cSAndroid Build Coastguard Worker         size_t additionalAuthenticationDataSize, uint8_t* encryptedData) {
156*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> cppKey;
157*4d7e907cSAndroid Build Coastguard Worker     cppKey.resize(16);
158*4d7e907cSAndroid Build Coastguard Worker     memcpy(cppKey.data(), key, 16);
159*4d7e907cSAndroid Build Coastguard Worker 
160*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> cppData;
161*4d7e907cSAndroid Build Coastguard Worker     cppData.resize(dataSize);
162*4d7e907cSAndroid Build Coastguard Worker     if (dataSize > 0) {
163*4d7e907cSAndroid Build Coastguard Worker         memcpy(cppData.data(), data, dataSize);
164*4d7e907cSAndroid Build Coastguard Worker     }
165*4d7e907cSAndroid Build Coastguard Worker 
166*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> cppAAD;
167*4d7e907cSAndroid Build Coastguard Worker     cppAAD.resize(additionalAuthenticationDataSize);
168*4d7e907cSAndroid Build Coastguard Worker     if (additionalAuthenticationDataSize > 0) {
169*4d7e907cSAndroid Build Coastguard Worker         memcpy(cppAAD.data(), additionalAuthenticationData, additionalAuthenticationDataSize);
170*4d7e907cSAndroid Build Coastguard Worker     }
171*4d7e907cSAndroid Build Coastguard Worker 
172*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> cppNonce;
173*4d7e907cSAndroid Build Coastguard Worker     cppNonce.resize(12);
174*4d7e907cSAndroid Build Coastguard Worker     memcpy(cppNonce.data(), nonce, 12);
175*4d7e907cSAndroid Build Coastguard Worker 
176*4d7e907cSAndroid Build Coastguard Worker     optional<vector<uint8_t>> cppEncryptedData =
177*4d7e907cSAndroid Build Coastguard Worker             android::hardware::identity::support::encryptAes128Gcm(cppKey, cppNonce, cppData,
178*4d7e907cSAndroid Build Coastguard Worker                                                                    cppAAD);
179*4d7e907cSAndroid Build Coastguard Worker     if (!cppEncryptedData.has_value()) {
180*4d7e907cSAndroid Build Coastguard Worker         return false;
181*4d7e907cSAndroid Build Coastguard Worker     }
182*4d7e907cSAndroid Build Coastguard Worker 
183*4d7e907cSAndroid Build Coastguard Worker     memcpy(encryptedData, cppEncryptedData.value().data(), cppEncryptedData.value().size());
184*4d7e907cSAndroid Build Coastguard Worker     return true;
185*4d7e907cSAndroid Build Coastguard Worker }
186*4d7e907cSAndroid Build Coastguard Worker 
187*4d7e907cSAndroid Build Coastguard Worker // Decrypts |encryptedData| using |key| and |additionalAuthenticatedData|,
188*4d7e907cSAndroid Build Coastguard Worker // returns resulting plaintext in |data| must be of size |encryptedDataSize| - 28.
189*4d7e907cSAndroid Build Coastguard Worker //
190*4d7e907cSAndroid Build Coastguard Worker // The format of |encryptedData| must be as specified in the
191*4d7e907cSAndroid Build Coastguard Worker // encryptAes128Gcm() function.
eicOpsDecryptAes128Gcm(const uint8_t * key,const uint8_t * encryptedData,size_t encryptedDataSize,const uint8_t * additionalAuthenticationData,size_t additionalAuthenticationDataSize,uint8_t * data)192*4d7e907cSAndroid Build Coastguard Worker bool eicOpsDecryptAes128Gcm(const uint8_t* key,  // Must be 16 bytes
193*4d7e907cSAndroid Build Coastguard Worker                             const uint8_t* encryptedData, size_t encryptedDataSize,
194*4d7e907cSAndroid Build Coastguard Worker                             const uint8_t* additionalAuthenticationData,
195*4d7e907cSAndroid Build Coastguard Worker                             size_t additionalAuthenticationDataSize, uint8_t* data) {
196*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> keyVec;
197*4d7e907cSAndroid Build Coastguard Worker     keyVec.resize(16);
198*4d7e907cSAndroid Build Coastguard Worker     memcpy(keyVec.data(), key, 16);
199*4d7e907cSAndroid Build Coastguard Worker 
200*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> encryptedDataVec;
201*4d7e907cSAndroid Build Coastguard Worker     encryptedDataVec.resize(encryptedDataSize);
202*4d7e907cSAndroid Build Coastguard Worker     if (encryptedDataSize > 0) {
203*4d7e907cSAndroid Build Coastguard Worker         memcpy(encryptedDataVec.data(), encryptedData, encryptedDataSize);
204*4d7e907cSAndroid Build Coastguard Worker     }
205*4d7e907cSAndroid Build Coastguard Worker 
206*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> aadVec;
207*4d7e907cSAndroid Build Coastguard Worker     aadVec.resize(additionalAuthenticationDataSize);
208*4d7e907cSAndroid Build Coastguard Worker     if (additionalAuthenticationDataSize > 0) {
209*4d7e907cSAndroid Build Coastguard Worker         memcpy(aadVec.data(), additionalAuthenticationData, additionalAuthenticationDataSize);
210*4d7e907cSAndroid Build Coastguard Worker     }
211*4d7e907cSAndroid Build Coastguard Worker 
212*4d7e907cSAndroid Build Coastguard Worker     optional<vector<uint8_t>> decryptedDataVec =
213*4d7e907cSAndroid Build Coastguard Worker             android::hardware::identity::support::decryptAes128Gcm(keyVec, encryptedDataVec,
214*4d7e907cSAndroid Build Coastguard Worker                                                                    aadVec);
215*4d7e907cSAndroid Build Coastguard Worker     if (!decryptedDataVec.has_value()) {
216*4d7e907cSAndroid Build Coastguard Worker         eicDebug("Error decrypting data");
217*4d7e907cSAndroid Build Coastguard Worker         return false;
218*4d7e907cSAndroid Build Coastguard Worker     }
219*4d7e907cSAndroid Build Coastguard Worker     if (decryptedDataVec.value().size() != encryptedDataSize - 28) {
220*4d7e907cSAndroid Build Coastguard Worker         eicDebug("Decrypted data is size %zd, expected %zd", decryptedDataVec.value().size(),
221*4d7e907cSAndroid Build Coastguard Worker                  encryptedDataSize - 28);
222*4d7e907cSAndroid Build Coastguard Worker         return false;
223*4d7e907cSAndroid Build Coastguard Worker     }
224*4d7e907cSAndroid Build Coastguard Worker 
225*4d7e907cSAndroid Build Coastguard Worker     if (decryptedDataVec.value().size() > 0) {
226*4d7e907cSAndroid Build Coastguard Worker         memcpy(data, decryptedDataVec.value().data(), decryptedDataVec.value().size());
227*4d7e907cSAndroid Build Coastguard Worker     }
228*4d7e907cSAndroid Build Coastguard Worker     return true;
229*4d7e907cSAndroid Build Coastguard Worker }
230*4d7e907cSAndroid Build Coastguard Worker 
eicOpsCreateEcKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE],uint8_t publicKey[EIC_P256_PUB_KEY_SIZE])231*4d7e907cSAndroid Build Coastguard Worker bool eicOpsCreateEcKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE],
232*4d7e907cSAndroid Build Coastguard Worker                        uint8_t publicKey[EIC_P256_PUB_KEY_SIZE]) {
233*4d7e907cSAndroid Build Coastguard Worker     optional<vector<uint8_t>> keyPair = android::hardware::identity::support::createEcKeyPair();
234*4d7e907cSAndroid Build Coastguard Worker     if (!keyPair) {
235*4d7e907cSAndroid Build Coastguard Worker         eicDebug("Error creating EC keypair");
236*4d7e907cSAndroid Build Coastguard Worker         return false;
237*4d7e907cSAndroid Build Coastguard Worker     }
238*4d7e907cSAndroid Build Coastguard Worker     optional<vector<uint8_t>> privKey =
239*4d7e907cSAndroid Build Coastguard Worker             android::hardware::identity::support::ecKeyPairGetPrivateKey(keyPair.value());
240*4d7e907cSAndroid Build Coastguard Worker     if (!privKey) {
241*4d7e907cSAndroid Build Coastguard Worker         eicDebug("Error extracting private key");
242*4d7e907cSAndroid Build Coastguard Worker         return false;
243*4d7e907cSAndroid Build Coastguard Worker     }
244*4d7e907cSAndroid Build Coastguard Worker     if (privKey.value().size() != EIC_P256_PRIV_KEY_SIZE) {
245*4d7e907cSAndroid Build Coastguard Worker         eicDebug("Private key is %zd bytes, expected %zd", privKey.value().size(),
246*4d7e907cSAndroid Build Coastguard Worker                  (size_t)EIC_P256_PRIV_KEY_SIZE);
247*4d7e907cSAndroid Build Coastguard Worker         return false;
248*4d7e907cSAndroid Build Coastguard Worker     }
249*4d7e907cSAndroid Build Coastguard Worker 
250*4d7e907cSAndroid Build Coastguard Worker     optional<vector<uint8_t>> pubKey =
251*4d7e907cSAndroid Build Coastguard Worker             android::hardware::identity::support::ecKeyPairGetPublicKey(keyPair.value());
252*4d7e907cSAndroid Build Coastguard Worker     if (!pubKey) {
253*4d7e907cSAndroid Build Coastguard Worker         eicDebug("Error extracting public key");
254*4d7e907cSAndroid Build Coastguard Worker         return false;
255*4d7e907cSAndroid Build Coastguard Worker     }
256*4d7e907cSAndroid Build Coastguard Worker     // ecKeyPairGetPublicKey() returns 0x04 | x | y, we don't want the leading 0x04.
257*4d7e907cSAndroid Build Coastguard Worker     if (pubKey.value().size() != EIC_P256_PUB_KEY_SIZE + 1) {
258*4d7e907cSAndroid Build Coastguard Worker         eicDebug("Public key is %zd bytes long, expected %zd", pubKey.value().size(),
259*4d7e907cSAndroid Build Coastguard Worker                  (size_t)EIC_P256_PRIV_KEY_SIZE + 1);
260*4d7e907cSAndroid Build Coastguard Worker         return false;
261*4d7e907cSAndroid Build Coastguard Worker     }
262*4d7e907cSAndroid Build Coastguard Worker 
263*4d7e907cSAndroid Build Coastguard Worker     memcpy(privateKey, privKey.value().data(), EIC_P256_PRIV_KEY_SIZE);
264*4d7e907cSAndroid Build Coastguard Worker     memcpy(publicKey, pubKey.value().data() + 1, EIC_P256_PUB_KEY_SIZE);
265*4d7e907cSAndroid Build Coastguard Worker 
266*4d7e907cSAndroid Build Coastguard Worker     return true;
267*4d7e907cSAndroid Build Coastguard Worker }
268*4d7e907cSAndroid Build Coastguard Worker 
eicOpsCreateCredentialKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE],const uint8_t * challenge,size_t challengeSize,const uint8_t * applicationId,size_t applicationIdSize,bool testCredential,const uint8_t * attestationKeyBlob,size_t attestationKeyBlobSize,const uint8_t * attestationKeyCert,size_t attestationKeyCertSize,uint8_t * cert,size_t * certSize)269*4d7e907cSAndroid Build Coastguard Worker bool eicOpsCreateCredentialKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE], const uint8_t* challenge,
270*4d7e907cSAndroid Build Coastguard Worker                                size_t challengeSize, const uint8_t* applicationId,
271*4d7e907cSAndroid Build Coastguard Worker                                size_t applicationIdSize, bool testCredential,
272*4d7e907cSAndroid Build Coastguard Worker                                const uint8_t* attestationKeyBlob, size_t attestationKeyBlobSize,
273*4d7e907cSAndroid Build Coastguard Worker                                const uint8_t* attestationKeyCert, size_t attestationKeyCertSize,
274*4d7e907cSAndroid Build Coastguard Worker                                uint8_t* cert, size_t* certSize) {
275*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> flatChain;
276*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> keyPair;
277*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> challengeVec(challenge, challenge + challengeSize);
278*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> applicationIdVec(applicationId, applicationId + applicationIdSize);
279*4d7e907cSAndroid Build Coastguard Worker     if (attestationKeyBlob && attestationKeyBlobSize > 0 && attestationKeyCert &&
280*4d7e907cSAndroid Build Coastguard Worker         attestationKeyCertSize > 0) {
281*4d7e907cSAndroid Build Coastguard Worker         vector<uint8_t> attestationKeyBlobVec(attestationKeyBlob,
282*4d7e907cSAndroid Build Coastguard Worker                                               attestationKeyBlob + attestationKeyBlobSize);
283*4d7e907cSAndroid Build Coastguard Worker         vector<uint8_t> attestationKeyCertVec(attestationKeyCert,
284*4d7e907cSAndroid Build Coastguard Worker                                               attestationKeyCert + attestationKeyCertSize);
285*4d7e907cSAndroid Build Coastguard Worker         optional<std::pair<vector<uint8_t>, vector<uint8_t>>> keyAndCert =
286*4d7e907cSAndroid Build Coastguard Worker                 android::hardware::identity::support::createEcKeyPairWithAttestationKey(
287*4d7e907cSAndroid Build Coastguard Worker                         challengeVec, applicationIdVec, attestationKeyBlobVec,
288*4d7e907cSAndroid Build Coastguard Worker                         attestationKeyCertVec, testCredential);
289*4d7e907cSAndroid Build Coastguard Worker         if (!keyAndCert) {
290*4d7e907cSAndroid Build Coastguard Worker             eicDebug("Error generating CredentialKey and attestation");
291*4d7e907cSAndroid Build Coastguard Worker             return false;
292*4d7e907cSAndroid Build Coastguard Worker         }
293*4d7e907cSAndroid Build Coastguard Worker         keyPair = std::move(keyAndCert->first);
294*4d7e907cSAndroid Build Coastguard Worker         flatChain = std::move(keyAndCert->second);
295*4d7e907cSAndroid Build Coastguard Worker     } else {
296*4d7e907cSAndroid Build Coastguard Worker         optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> ret =
297*4d7e907cSAndroid Build Coastguard Worker                 android::hardware::identity::support::createEcKeyPairAndAttestation(
298*4d7e907cSAndroid Build Coastguard Worker                         challengeVec, applicationIdVec, testCredential);
299*4d7e907cSAndroid Build Coastguard Worker         if (!ret) {
300*4d7e907cSAndroid Build Coastguard Worker             eicDebug("Error generating CredentialKey and attestation");
301*4d7e907cSAndroid Build Coastguard Worker             return false;
302*4d7e907cSAndroid Build Coastguard Worker         }
303*4d7e907cSAndroid Build Coastguard Worker         keyPair = std::move(ret->first);
304*4d7e907cSAndroid Build Coastguard Worker         flatChain = android::hardware::identity::support::certificateChainJoin(ret->second);
305*4d7e907cSAndroid Build Coastguard Worker     }
306*4d7e907cSAndroid Build Coastguard Worker 
307*4d7e907cSAndroid Build Coastguard Worker     if (*certSize < flatChain.size()) {
308*4d7e907cSAndroid Build Coastguard Worker         eicDebug("Buffer for certificate is only %zd bytes long, need %zd bytes", *certSize,
309*4d7e907cSAndroid Build Coastguard Worker                  flatChain.size());
310*4d7e907cSAndroid Build Coastguard Worker         return false;
311*4d7e907cSAndroid Build Coastguard Worker     }
312*4d7e907cSAndroid Build Coastguard Worker     memcpy(cert, flatChain.data(), flatChain.size());
313*4d7e907cSAndroid Build Coastguard Worker     *certSize = flatChain.size();
314*4d7e907cSAndroid Build Coastguard Worker 
315*4d7e907cSAndroid Build Coastguard Worker     // Extract private key.
316*4d7e907cSAndroid Build Coastguard Worker     optional<vector<uint8_t>> privKey =
317*4d7e907cSAndroid Build Coastguard Worker             android::hardware::identity::support::ecKeyPairGetPrivateKey(keyPair);
318*4d7e907cSAndroid Build Coastguard Worker     if (!privKey) {
319*4d7e907cSAndroid Build Coastguard Worker         eicDebug("Error extracting private key");
320*4d7e907cSAndroid Build Coastguard Worker         return false;
321*4d7e907cSAndroid Build Coastguard Worker     }
322*4d7e907cSAndroid Build Coastguard Worker     if (privKey.value().size() != EIC_P256_PRIV_KEY_SIZE) {
323*4d7e907cSAndroid Build Coastguard Worker         eicDebug("Private key is %zd bytes, expected %zd", privKey.value().size(),
324*4d7e907cSAndroid Build Coastguard Worker                  (size_t)EIC_P256_PRIV_KEY_SIZE);
325*4d7e907cSAndroid Build Coastguard Worker         return false;
326*4d7e907cSAndroid Build Coastguard Worker     }
327*4d7e907cSAndroid Build Coastguard Worker 
328*4d7e907cSAndroid Build Coastguard Worker     memcpy(privateKey, privKey.value().data(), EIC_P256_PRIV_KEY_SIZE);
329*4d7e907cSAndroid Build Coastguard Worker 
330*4d7e907cSAndroid Build Coastguard Worker     return true;
331*4d7e907cSAndroid Build Coastguard Worker }
332*4d7e907cSAndroid Build Coastguard Worker 
eicOpsSignEcKey(const uint8_t publicKey[EIC_P256_PUB_KEY_SIZE],const uint8_t signingKey[EIC_P256_PRIV_KEY_SIZE],unsigned int serial,const char * issuerName,const char * subjectName,time_t validityNotBefore,time_t validityNotAfter,const uint8_t * proofOfBinding,size_t proofOfBindingSize,uint8_t * cert,size_t * certSize)333*4d7e907cSAndroid Build Coastguard Worker bool eicOpsSignEcKey(const uint8_t publicKey[EIC_P256_PUB_KEY_SIZE],
334*4d7e907cSAndroid Build Coastguard Worker                      const uint8_t signingKey[EIC_P256_PRIV_KEY_SIZE], unsigned int serial,
335*4d7e907cSAndroid Build Coastguard Worker                      const char* issuerName, const char* subjectName, time_t validityNotBefore,
336*4d7e907cSAndroid Build Coastguard Worker                      time_t validityNotAfter, const uint8_t* proofOfBinding,
337*4d7e907cSAndroid Build Coastguard Worker                      size_t proofOfBindingSize, uint8_t* cert, size_t* certSize) {  // inout
338*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> signingKeyVec(EIC_P256_PRIV_KEY_SIZE);
339*4d7e907cSAndroid Build Coastguard Worker     memcpy(signingKeyVec.data(), signingKey, EIC_P256_PRIV_KEY_SIZE);
340*4d7e907cSAndroid Build Coastguard Worker 
341*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> pubKeyVec(EIC_P256_PUB_KEY_SIZE + 1);
342*4d7e907cSAndroid Build Coastguard Worker     pubKeyVec[0] = 0x04;
343*4d7e907cSAndroid Build Coastguard Worker     memcpy(pubKeyVec.data() + 1, publicKey, EIC_P256_PUB_KEY_SIZE);
344*4d7e907cSAndroid Build Coastguard Worker 
345*4d7e907cSAndroid Build Coastguard Worker     string serialDecimal = android::base::StringPrintf("%d", serial);
346*4d7e907cSAndroid Build Coastguard Worker 
347*4d7e907cSAndroid Build Coastguard Worker     map<string, vector<uint8_t>> extensions;
348*4d7e907cSAndroid Build Coastguard Worker     if (proofOfBinding != nullptr) {
349*4d7e907cSAndroid Build Coastguard Worker         vector<uint8_t> proofOfBindingVec(proofOfBinding, proofOfBinding + proofOfBindingSize);
350*4d7e907cSAndroid Build Coastguard Worker         extensions["1.3.6.1.4.1.11129.2.1.26"] = proofOfBindingVec;
351*4d7e907cSAndroid Build Coastguard Worker     }
352*4d7e907cSAndroid Build Coastguard Worker 
353*4d7e907cSAndroid Build Coastguard Worker     optional<vector<uint8_t>> certVec =
354*4d7e907cSAndroid Build Coastguard Worker             android::hardware::identity::support::ecPublicKeyGenerateCertificate(
355*4d7e907cSAndroid Build Coastguard Worker                     pubKeyVec, signingKeyVec, serialDecimal, issuerName, subjectName,
356*4d7e907cSAndroid Build Coastguard Worker                     validityNotBefore, validityNotAfter, extensions);
357*4d7e907cSAndroid Build Coastguard Worker     if (!certVec) {
358*4d7e907cSAndroid Build Coastguard Worker         eicDebug("Error generating certificate");
359*4d7e907cSAndroid Build Coastguard Worker         return false;
360*4d7e907cSAndroid Build Coastguard Worker     }
361*4d7e907cSAndroid Build Coastguard Worker 
362*4d7e907cSAndroid Build Coastguard Worker     if (*certSize < certVec.value().size()) {
363*4d7e907cSAndroid Build Coastguard Worker         eicDebug("Buffer for certificate is only %zd bytes long, need %zd bytes", *certSize,
364*4d7e907cSAndroid Build Coastguard Worker                  certVec.value().size());
365*4d7e907cSAndroid Build Coastguard Worker         return false;
366*4d7e907cSAndroid Build Coastguard Worker     }
367*4d7e907cSAndroid Build Coastguard Worker     memcpy(cert, certVec.value().data(), certVec.value().size());
368*4d7e907cSAndroid Build Coastguard Worker     *certSize = certVec.value().size();
369*4d7e907cSAndroid Build Coastguard Worker 
370*4d7e907cSAndroid Build Coastguard Worker     return true;
371*4d7e907cSAndroid Build Coastguard Worker }
372*4d7e907cSAndroid Build Coastguard Worker 
eicOpsEcDsa(const uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE],const uint8_t digestOfData[EIC_SHA256_DIGEST_SIZE],uint8_t signature[EIC_ECDSA_P256_SIGNATURE_SIZE])373*4d7e907cSAndroid Build Coastguard Worker bool eicOpsEcDsa(const uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE],
374*4d7e907cSAndroid Build Coastguard Worker                  const uint8_t digestOfData[EIC_SHA256_DIGEST_SIZE],
375*4d7e907cSAndroid Build Coastguard Worker                  uint8_t signature[EIC_ECDSA_P256_SIGNATURE_SIZE]) {
376*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> privKeyVec(EIC_P256_PRIV_KEY_SIZE);
377*4d7e907cSAndroid Build Coastguard Worker     memcpy(privKeyVec.data(), privateKey, EIC_P256_PRIV_KEY_SIZE);
378*4d7e907cSAndroid Build Coastguard Worker 
379*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> digestVec(EIC_SHA256_DIGEST_SIZE);
380*4d7e907cSAndroid Build Coastguard Worker     memcpy(digestVec.data(), digestOfData, EIC_SHA256_DIGEST_SIZE);
381*4d7e907cSAndroid Build Coastguard Worker 
382*4d7e907cSAndroid Build Coastguard Worker     optional<vector<uint8_t>> derSignature =
383*4d7e907cSAndroid Build Coastguard Worker             android::hardware::identity::support::signEcDsaDigest(privKeyVec, digestVec);
384*4d7e907cSAndroid Build Coastguard Worker     if (!derSignature) {
385*4d7e907cSAndroid Build Coastguard Worker         eicDebug("Error signing data");
386*4d7e907cSAndroid Build Coastguard Worker         return false;
387*4d7e907cSAndroid Build Coastguard Worker     }
388*4d7e907cSAndroid Build Coastguard Worker 
389*4d7e907cSAndroid Build Coastguard Worker     ECDSA_SIG* sig;
390*4d7e907cSAndroid Build Coastguard Worker     const unsigned char* p = derSignature.value().data();
391*4d7e907cSAndroid Build Coastguard Worker     sig = d2i_ECDSA_SIG(nullptr, &p, derSignature.value().size());
392*4d7e907cSAndroid Build Coastguard Worker     if (sig == nullptr) {
393*4d7e907cSAndroid Build Coastguard Worker         eicDebug("Error decoding DER signature");
394*4d7e907cSAndroid Build Coastguard Worker         return false;
395*4d7e907cSAndroid Build Coastguard Worker     }
396*4d7e907cSAndroid Build Coastguard Worker 
397*4d7e907cSAndroid Build Coastguard Worker     if (BN_bn2binpad(sig->r, signature, 32) != 32) {
398*4d7e907cSAndroid Build Coastguard Worker         ECDSA_SIG_free(sig);
399*4d7e907cSAndroid Build Coastguard Worker         eicDebug("Error encoding r");
400*4d7e907cSAndroid Build Coastguard Worker         return false;
401*4d7e907cSAndroid Build Coastguard Worker     }
402*4d7e907cSAndroid Build Coastguard Worker     if (BN_bn2binpad(sig->s, signature + 32, 32) != 32) {
403*4d7e907cSAndroid Build Coastguard Worker         ECDSA_SIG_free(sig);
404*4d7e907cSAndroid Build Coastguard Worker         eicDebug("Error encoding s");
405*4d7e907cSAndroid Build Coastguard Worker         return false;
406*4d7e907cSAndroid Build Coastguard Worker     }
407*4d7e907cSAndroid Build Coastguard Worker 
408*4d7e907cSAndroid Build Coastguard Worker     ECDSA_SIG_free(sig);
409*4d7e907cSAndroid Build Coastguard Worker     return true;
410*4d7e907cSAndroid Build Coastguard Worker }
411*4d7e907cSAndroid Build Coastguard Worker 
412*4d7e907cSAndroid Build Coastguard Worker static const uint8_t hbkTest[16] = {0};
413*4d7e907cSAndroid Build Coastguard Worker static const uint8_t hbkReal[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
414*4d7e907cSAndroid Build Coastguard Worker 
eicOpsGetHardwareBoundKey(bool testCredential)415*4d7e907cSAndroid Build Coastguard Worker const uint8_t* eicOpsGetHardwareBoundKey(bool testCredential) {
416*4d7e907cSAndroid Build Coastguard Worker     if (testCredential) {
417*4d7e907cSAndroid Build Coastguard Worker         return hbkTest;
418*4d7e907cSAndroid Build Coastguard Worker     }
419*4d7e907cSAndroid Build Coastguard Worker     return hbkReal;
420*4d7e907cSAndroid Build Coastguard Worker }
421*4d7e907cSAndroid Build Coastguard Worker 
eicOpsValidateAuthToken(uint64_t,uint64_t,uint64_t,int,uint64_t,const uint8_t *,size_t,uint64_t,uint64_t,int,const uint8_t *,size_t)422*4d7e907cSAndroid Build Coastguard Worker bool eicOpsValidateAuthToken(uint64_t /* challenge */, uint64_t /* secureUserId */,
423*4d7e907cSAndroid Build Coastguard Worker                              uint64_t /* authenticatorId */, int /* hardwareAuthenticatorType */,
424*4d7e907cSAndroid Build Coastguard Worker                              uint64_t /* timeStamp */, const uint8_t* /* mac */,
425*4d7e907cSAndroid Build Coastguard Worker                              size_t /* macSize */, uint64_t /* verificationTokenChallenge */,
426*4d7e907cSAndroid Build Coastguard Worker                              uint64_t /* verificationTokenTimeStamp */,
427*4d7e907cSAndroid Build Coastguard Worker                              int /* verificationTokenSecurityLevel */,
428*4d7e907cSAndroid Build Coastguard Worker                              const uint8_t* /* verificationTokenMac */,
429*4d7e907cSAndroid Build Coastguard Worker                              size_t /* verificationTokenMacSize */) {
430*4d7e907cSAndroid Build Coastguard Worker     // Here's where we would validate the passed-in |authToken| to assure ourselves
431*4d7e907cSAndroid Build Coastguard Worker     // that it comes from the e.g. biometric hardware and wasn't made up by an attacker.
432*4d7e907cSAndroid Build Coastguard Worker     //
433*4d7e907cSAndroid Build Coastguard Worker     // However this involves calculating the MAC which requires access to the to
434*4d7e907cSAndroid Build Coastguard Worker     // a pre-shared key which we don't have...
435*4d7e907cSAndroid Build Coastguard Worker     //
436*4d7e907cSAndroid Build Coastguard Worker     return true;
437*4d7e907cSAndroid Build Coastguard Worker }
438*4d7e907cSAndroid Build Coastguard Worker 
eicOpsX509GetPublicKey(const uint8_t * x509Cert,size_t x509CertSize,uint8_t * publicKey,size_t * publicKeySize)439*4d7e907cSAndroid Build Coastguard Worker bool eicOpsX509GetPublicKey(const uint8_t* x509Cert, size_t x509CertSize, uint8_t* publicKey,
440*4d7e907cSAndroid Build Coastguard Worker                             size_t* publicKeySize) {
441*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> chain;
442*4d7e907cSAndroid Build Coastguard Worker     chain.resize(x509CertSize);
443*4d7e907cSAndroid Build Coastguard Worker     memcpy(chain.data(), x509Cert, x509CertSize);
444*4d7e907cSAndroid Build Coastguard Worker     optional<vector<uint8_t>> res =
445*4d7e907cSAndroid Build Coastguard Worker             android::hardware::identity::support::certificateChainGetTopMostKey(chain);
446*4d7e907cSAndroid Build Coastguard Worker     if (!res) {
447*4d7e907cSAndroid Build Coastguard Worker         return false;
448*4d7e907cSAndroid Build Coastguard Worker     }
449*4d7e907cSAndroid Build Coastguard Worker     if (res.value().size() > *publicKeySize) {
450*4d7e907cSAndroid Build Coastguard Worker         eicDebug("Public key size is %zd but buffer only has room for %zd bytes",
451*4d7e907cSAndroid Build Coastguard Worker                  res.value().size(), *publicKeySize);
452*4d7e907cSAndroid Build Coastguard Worker         return false;
453*4d7e907cSAndroid Build Coastguard Worker     }
454*4d7e907cSAndroid Build Coastguard Worker     *publicKeySize = res.value().size();
455*4d7e907cSAndroid Build Coastguard Worker     memcpy(publicKey, res.value().data(), *publicKeySize);
456*4d7e907cSAndroid Build Coastguard Worker     eicDebug("Extracted %zd bytes public key from %zd bytes X.509 cert", *publicKeySize,
457*4d7e907cSAndroid Build Coastguard Worker              x509CertSize);
458*4d7e907cSAndroid Build Coastguard Worker     return true;
459*4d7e907cSAndroid Build Coastguard Worker }
460*4d7e907cSAndroid Build Coastguard Worker 
eicOpsX509CertSignedByPublicKey(const uint8_t * x509Cert,size_t x509CertSize,const uint8_t * publicKey,size_t publicKeySize)461*4d7e907cSAndroid Build Coastguard Worker bool eicOpsX509CertSignedByPublicKey(const uint8_t* x509Cert, size_t x509CertSize,
462*4d7e907cSAndroid Build Coastguard Worker                                      const uint8_t* publicKey, size_t publicKeySize) {
463*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> certVec(x509Cert, x509Cert + x509CertSize);
464*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> publicKeyVec(publicKey, publicKey + publicKeySize);
465*4d7e907cSAndroid Build Coastguard Worker     return android::hardware::identity::support::certificateSignedByPublicKey(certVec,
466*4d7e907cSAndroid Build Coastguard Worker                                                                               publicKeyVec);
467*4d7e907cSAndroid Build Coastguard Worker }
468*4d7e907cSAndroid Build Coastguard Worker 
eicOpsEcDsaVerifyWithPublicKey(const uint8_t * digest,size_t digestSize,const uint8_t * signature,size_t signatureSize,const uint8_t * publicKey,size_t publicKeySize)469*4d7e907cSAndroid Build Coastguard Worker bool eicOpsEcDsaVerifyWithPublicKey(const uint8_t* digest, size_t digestSize,
470*4d7e907cSAndroid Build Coastguard Worker                                     const uint8_t* signature, size_t signatureSize,
471*4d7e907cSAndroid Build Coastguard Worker                                     const uint8_t* publicKey, size_t publicKeySize) {
472*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> digestVec(digest, digest + digestSize);
473*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> signatureVec(signature, signature + signatureSize);
474*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> publicKeyVec(publicKey, publicKey + publicKeySize);
475*4d7e907cSAndroid Build Coastguard Worker 
476*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> derSignature;
477*4d7e907cSAndroid Build Coastguard Worker     if (!android::hardware::identity::support::ecdsaSignatureCoseToDer(signatureVec,
478*4d7e907cSAndroid Build Coastguard Worker                                                                        derSignature)) {
479*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << "Error convering signature to DER format";
480*4d7e907cSAndroid Build Coastguard Worker         return false;
481*4d7e907cSAndroid Build Coastguard Worker     }
482*4d7e907cSAndroid Build Coastguard Worker 
483*4d7e907cSAndroid Build Coastguard Worker     if (!android::hardware::identity::support::checkEcDsaSignature(digestVec, derSignature,
484*4d7e907cSAndroid Build Coastguard Worker                                                                    publicKeyVec)) {
485*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << "Signature check failed";
486*4d7e907cSAndroid Build Coastguard Worker         return false;
487*4d7e907cSAndroid Build Coastguard Worker     }
488*4d7e907cSAndroid Build Coastguard Worker     return true;
489*4d7e907cSAndroid Build Coastguard Worker }
490*4d7e907cSAndroid Build Coastguard Worker 
eicOpsEcdh(const uint8_t publicKey[EIC_P256_PUB_KEY_SIZE],const uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE],uint8_t sharedSecret[EIC_P256_COORDINATE_SIZE])491*4d7e907cSAndroid Build Coastguard Worker bool eicOpsEcdh(const uint8_t publicKey[EIC_P256_PUB_KEY_SIZE],
492*4d7e907cSAndroid Build Coastguard Worker                 const uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE],
493*4d7e907cSAndroid Build Coastguard Worker                 uint8_t sharedSecret[EIC_P256_COORDINATE_SIZE]) {
494*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> pubKeyVec(EIC_P256_PUB_KEY_SIZE + 1);
495*4d7e907cSAndroid Build Coastguard Worker     pubKeyVec[0] = 0x04;
496*4d7e907cSAndroid Build Coastguard Worker     memcpy(pubKeyVec.data() + 1, publicKey, EIC_P256_PUB_KEY_SIZE);
497*4d7e907cSAndroid Build Coastguard Worker 
498*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> privKeyVec(EIC_P256_PRIV_KEY_SIZE);
499*4d7e907cSAndroid Build Coastguard Worker     memcpy(privKeyVec.data(), privateKey, EIC_P256_PRIV_KEY_SIZE);
500*4d7e907cSAndroid Build Coastguard Worker 
501*4d7e907cSAndroid Build Coastguard Worker     optional<vector<uint8_t>> shared =
502*4d7e907cSAndroid Build Coastguard Worker             android::hardware::identity::support::ecdh(pubKeyVec, privKeyVec);
503*4d7e907cSAndroid Build Coastguard Worker     if (!shared) {
504*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << "Error performing ECDH";
505*4d7e907cSAndroid Build Coastguard Worker         return false;
506*4d7e907cSAndroid Build Coastguard Worker     }
507*4d7e907cSAndroid Build Coastguard Worker     if (shared.value().size() != EIC_P256_COORDINATE_SIZE) {
508*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << "Unexpected size of shared secret " << shared.value().size() << " expected "
509*4d7e907cSAndroid Build Coastguard Worker                    << EIC_P256_COORDINATE_SIZE << " bytes";
510*4d7e907cSAndroid Build Coastguard Worker         return false;
511*4d7e907cSAndroid Build Coastguard Worker     }
512*4d7e907cSAndroid Build Coastguard Worker     memcpy(sharedSecret, shared.value().data(), EIC_P256_COORDINATE_SIZE);
513*4d7e907cSAndroid Build Coastguard Worker     return true;
514*4d7e907cSAndroid Build Coastguard Worker }
515*4d7e907cSAndroid Build Coastguard Worker 
eicOpsHkdf(const uint8_t * sharedSecret,size_t sharedSecretSize,const uint8_t * salt,size_t saltSize,const uint8_t * info,size_t infoSize,uint8_t * output,size_t outputSize)516*4d7e907cSAndroid Build Coastguard Worker bool eicOpsHkdf(const uint8_t* sharedSecret, size_t sharedSecretSize, const uint8_t* salt,
517*4d7e907cSAndroid Build Coastguard Worker                 size_t saltSize, const uint8_t* info, size_t infoSize, uint8_t* output,
518*4d7e907cSAndroid Build Coastguard Worker                 size_t outputSize) {
519*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> sharedSecretVec(sharedSecretSize);
520*4d7e907cSAndroid Build Coastguard Worker     memcpy(sharedSecretVec.data(), sharedSecret, sharedSecretSize);
521*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> saltVec(saltSize);
522*4d7e907cSAndroid Build Coastguard Worker     memcpy(saltVec.data(), salt, saltSize);
523*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> infoVec(infoSize);
524*4d7e907cSAndroid Build Coastguard Worker     memcpy(infoVec.data(), info, infoSize);
525*4d7e907cSAndroid Build Coastguard Worker 
526*4d7e907cSAndroid Build Coastguard Worker     optional<vector<uint8_t>> result = android::hardware::identity::support::hkdf(
527*4d7e907cSAndroid Build Coastguard Worker             sharedSecretVec, saltVec, infoVec, outputSize);
528*4d7e907cSAndroid Build Coastguard Worker     if (!result) {
529*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << "Error performing HKDF";
530*4d7e907cSAndroid Build Coastguard Worker         return false;
531*4d7e907cSAndroid Build Coastguard Worker     }
532*4d7e907cSAndroid Build Coastguard Worker     if (result.value().size() != outputSize) {
533*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << "Unexpected size of HKDF " << result.value().size() << " expected "
534*4d7e907cSAndroid Build Coastguard Worker                    << outputSize;
535*4d7e907cSAndroid Build Coastguard Worker         return false;
536*4d7e907cSAndroid Build Coastguard Worker     }
537*4d7e907cSAndroid Build Coastguard Worker     memcpy(output, result.value().data(), outputSize);
538*4d7e907cSAndroid Build Coastguard Worker     return true;
539*4d7e907cSAndroid Build Coastguard Worker }
540*4d7e907cSAndroid Build Coastguard Worker 
541*4d7e907cSAndroid Build Coastguard Worker #ifdef EIC_DEBUG
542*4d7e907cSAndroid Build Coastguard Worker 
eicPrint(const char * format,...)543*4d7e907cSAndroid Build Coastguard Worker void eicPrint(const char* format, ...) {
544*4d7e907cSAndroid Build Coastguard Worker     char buf[1024];
545*4d7e907cSAndroid Build Coastguard Worker     va_list args;
546*4d7e907cSAndroid Build Coastguard Worker     va_start(args, format);
547*4d7e907cSAndroid Build Coastguard Worker     vsnprintf(buf, sizeof(buf), format, args);
548*4d7e907cSAndroid Build Coastguard Worker     va_end(args);
549*4d7e907cSAndroid Build Coastguard Worker     LOG(INFO) << buf;
550*4d7e907cSAndroid Build Coastguard Worker }
551*4d7e907cSAndroid Build Coastguard Worker 
eicHexdump(const char * message,const uint8_t * data,size_t dataSize)552*4d7e907cSAndroid Build Coastguard Worker void eicHexdump(const char* message, const uint8_t* data, size_t dataSize) {
553*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> dataVec(dataSize);
554*4d7e907cSAndroid Build Coastguard Worker     memcpy(dataVec.data(), data, dataSize);
555*4d7e907cSAndroid Build Coastguard Worker     android::hardware::identity::support::hexdump(message, dataVec);
556*4d7e907cSAndroid Build Coastguard Worker }
557*4d7e907cSAndroid Build Coastguard Worker 
eicCborPrettyPrint(const uint8_t * cborData,size_t cborDataSize,size_t maxBStrSize)558*4d7e907cSAndroid Build Coastguard Worker void eicCborPrettyPrint(const uint8_t* cborData, size_t cborDataSize, size_t maxBStrSize) {
559*4d7e907cSAndroid Build Coastguard Worker     vector<uint8_t> cborDataVec(cborDataSize);
560*4d7e907cSAndroid Build Coastguard Worker     memcpy(cborDataVec.data(), cborData, cborDataSize);
561*4d7e907cSAndroid Build Coastguard Worker     string str =
562*4d7e907cSAndroid Build Coastguard Worker             android::hardware::identity::support::cborPrettyPrint(cborDataVec, maxBStrSize, {});
563*4d7e907cSAndroid Build Coastguard Worker     fprintf(stderr, "%s\n", str.c_str());
564*4d7e907cSAndroid Build Coastguard Worker }
565*4d7e907cSAndroid Build Coastguard Worker 
566*4d7e907cSAndroid Build Coastguard Worker #endif  // EIC_DEBUG
567