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