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