blob: 3fd9f1dceeed61beda4879f223fa4c5e4a17586f [file] [log] [blame]
David Zeuthen630de2a2020-05-11 14:04:54 -04001/*
2 * Copyright 2020, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "EicOpsImpl"
18
19#include <optional>
20#include <tuple>
21#include <vector>
22
David Zeuthen1eb12b22021-09-11 13:59:43 -040023#ifndef _GNU_SOURCE
24#define _GNU_SOURCE
25#endif
26#include <string.h>
27
David Zeuthen630de2a2020-05-11 14:04:54 -040028#include <android-base/logging.h>
29#include <android-base/stringprintf.h>
David Zeuthen630de2a2020-05-11 14:04:54 -040030
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
David Zeuthen49f2d252020-10-16 11:27:24 -040052using ::std::map;
David Zeuthen630de2a2020-05-11 14:04:54 -040053using ::std::optional;
54using ::std::string;
55using ::std::tuple;
56using ::std::vector;
57
58void* eicMemSet(void* s, int c, size_t n) {
59 return memset(s, c, n);
60}
61
62void* eicMemCpy(void* dest, const void* src, size_t n) {
63 return memcpy(dest, src, n);
64}
65
66size_t eicStrLen(const char* s) {
67 return strlen(s);
68}
69
David Zeuthen1eb12b22021-09-11 13:59:43 -040070void* 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
David Zeuthen630de2a2020-05-11 14:04:54 -040075int eicCryptoMemCmp(const void* s1, const void* s2, size_t n) {
76 return CRYPTO_memcmp(s1, s2, n);
77}
78
79void 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
87void 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
94void 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
105void eicOpsSha256Init(EicSha256Ctx* ctx) {
106 SHA256_CTX* realCtx = (SHA256_CTX*)ctx;
107 SHA256_Init(realCtx);
108}
109
110void 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
115void eicOpsSha256Final(EicSha256Ctx* ctx, uint8_t digest[EIC_SHA256_DIGEST_SIZE]) {
116 SHA256_CTX* realCtx = (SHA256_CTX*)ctx;
117 SHA256_Final(digest, realCtx);
118}
119
120bool 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
David Zeuthen1eb12b22021-09-11 13:59:43 -0400129bool 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
David Zeuthen630de2a2020-05-11 14:04:54 -0400148bool 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.
191bool 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
230bool 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) {
David Zeuthen49f2d252020-10-16 11:27:24 -0400244 eicDebug("Private key is %zd bytes, expected %zd", privKey.value().size(),
245 (size_t)EIC_P256_PRIV_KEY_SIZE);
David Zeuthen630de2a2020-05-11 14:04:54 -0400246 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) {
David Zeuthen49f2d252020-10-16 11:27:24 -0400257 eicDebug("Public key is %zd bytes long, expected %zd", pubKey.value().size(),
David Zeuthen630de2a2020-05-11 14:04:54 -0400258 (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
268bool eicOpsCreateCredentialKey(uint8_t privateKey[EIC_P256_PRIV_KEY_SIZE], const uint8_t* challenge,
269 size_t challengeSize, const uint8_t* applicationId,
Seth Moore1bf823c2022-01-25 23:04:37 +0000270 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);
David Zeuthen630de2a2020-05-11 14:04:54 -0400304 }
305
David Zeuthen630de2a2020-05-11 14:04:54 -0400306 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 =
Seth Moore1bf823c2022-01-25 23:04:37 +0000316 android::hardware::identity::support::ecKeyPairGetPrivateKey(keyPair);
David Zeuthen630de2a2020-05-11 14:04:54 -0400317 if (!privKey) {
318 eicDebug("Error extracting private key");
319 return false;
320 }
321 if (privKey.value().size() != EIC_P256_PRIV_KEY_SIZE) {
David Zeuthen49f2d252020-10-16 11:27:24 -0400322 eicDebug("Private key is %zd bytes, expected %zd", privKey.value().size(),
323 (size_t)EIC_P256_PRIV_KEY_SIZE);
David Zeuthen630de2a2020-05-11 14:04:54 -0400324 return false;
325 }
326
327 memcpy(privateKey, privKey.value().data(), EIC_P256_PRIV_KEY_SIZE);
328
329 return true;
330}
331
332bool 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,
David Zeuthen49f2d252020-10-16 11:27:24 -0400335 time_t validityNotAfter, const uint8_t* proofOfBinding,
336 size_t proofOfBindingSize, uint8_t* cert, size_t* certSize) { // inout
David Zeuthen630de2a2020-05-11 14:04:54 -0400337 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
David Zeuthen49f2d252020-10-16 11:27:24 -0400344 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 }
David Zeuthen630de2a2020-05-11 14:04:54 -0400351
352 optional<vector<uint8_t>> certVec =
353 android::hardware::identity::support::ecPublicKeyGenerateCertificate(
354 pubKeyVec, signingKeyVec, serialDecimal, issuerName, subjectName,
David Zeuthen49f2d252020-10-16 11:27:24 -0400355 validityNotBefore, validityNotAfter, extensions);
David Zeuthen630de2a2020-05-11 14:04:54 -0400356 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
372bool 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
408static const uint8_t hbkTest[16] = {0};
409static const uint8_t hbkReal[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
410
411const uint8_t* eicOpsGetHardwareBoundKey(bool testCredential) {
412 if (testCredential) {
413 return hbkTest;
414 }
415 return hbkReal;
416}
417
418bool 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
435bool 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
457bool 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
465bool 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
487bool 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
512bool 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
539void eicPrint(const char* format, ...) {
Seth Moore1bf823c2022-01-25 23:04:37 +0000540 char buf[1024];
David Zeuthen630de2a2020-05-11 14:04:54 -0400541 va_list args;
542 va_start(args, format);
Seth Moore1bf823c2022-01-25 23:04:37 +0000543 vsnprintf(buf, sizeof(buf), format, args);
David Zeuthen630de2a2020-05-11 14:04:54 -0400544 va_end(args);
Seth Moore1bf823c2022-01-25 23:04:37 +0000545 LOG(INFO) << buf;
David Zeuthen630de2a2020-05-11 14:04:54 -0400546}
547
548void 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
554void 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