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