1 /*
2  * Copyright 2019, 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 "IdentityCredentialSupport"
18 
19 #include <android/hardware/identity/support/IdentityCredentialSupport.h>
20 
21 #define _POSIX_C_SOURCE 199309L
22 
23 #include <ctype.h>
24 #include <stdarg.h>
25 #include <stdio.h>
26 #include <time.h>
27 #include <chrono>
28 #include <iomanip>
29 
30 #include <openssl/aes.h>
31 #include <openssl/bn.h>
32 #include <openssl/crypto.h>
33 #include <openssl/ec.h>
34 #include <openssl/err.h>
35 #include <openssl/evp.h>
36 #include <openssl/hkdf.h>
37 #include <openssl/hmac.h>
38 #include <openssl/objects.h>
39 #include <openssl/pem.h>
40 #include <openssl/pkcs12.h>
41 #include <openssl/rand.h>
42 #include <openssl/x509.h>
43 #include <openssl/x509_vfy.h>
44 
45 #include <android-base/logging.h>
46 #include <android-base/stringprintf.h>
47 
48 #include <cppbor.h>
49 #include <cppbor_parse.h>
50 
51 #include <android/hardware/keymaster/4.0/types.h>
52 #include <keymaster/authorization_set.h>
53 #include <keymaster/contexts/pure_soft_keymaster_context.h>
54 #include <keymaster/contexts/soft_attestation_cert.h>
55 #include <keymaster/keymaster_tags.h>
56 #include <keymaster/km_openssl/attestation_utils.h>
57 
58 namespace android {
59 namespace hardware {
60 namespace identity {
61 namespace support {
62 
63 using ::std::pair;
64 using ::std::unique_ptr;
65 
66 // ---------------------------------------------------------------------------
67 // Miscellaneous utilities.
68 // ---------------------------------------------------------------------------
69 
hexdump(const string & name,const vector<uint8_t> & data)70 void hexdump(const string& name, const vector<uint8_t>& data) {
71     fprintf(stderr, "%s: dumping %zd bytes\n", name.c_str(), data.size());
72     size_t n, m, o;
73     for (n = 0; n < data.size(); n += 16) {
74         fprintf(stderr, "%04zx  ", n);
75         for (m = 0; m < 16 && n + m < data.size(); m++) {
76             fprintf(stderr, "%02x ", data[n + m]);
77         }
78         for (o = m; o < 16; o++) {
79             fprintf(stderr, "   ");
80         }
81         fprintf(stderr, " ");
82         for (m = 0; m < 16 && n + m < data.size(); m++) {
83             int c = data[n + m];
84             fprintf(stderr, "%c", isprint(c) ? c : '.');
85         }
86         fprintf(stderr, "\n");
87     }
88     fprintf(stderr, "\n");
89 }
90 
encodeHex(const uint8_t * data,size_t dataLen)91 string encodeHex(const uint8_t* data, size_t dataLen) {
92     static const char hexDigits[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
93                                        '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
94 
95     string ret;
96     ret.resize(dataLen * 2);
97     for (size_t n = 0; n < dataLen; n++) {
98         uint8_t byte = data[n];
99         ret[n * 2 + 0] = hexDigits[byte >> 4];
100         ret[n * 2 + 1] = hexDigits[byte & 0x0f];
101     }
102 
103     return ret;
104 }
105 
encodeHex(const string & str)106 string encodeHex(const string& str) {
107     return encodeHex(reinterpret_cast<const uint8_t*>(str.data()), str.size());
108 }
109 
encodeHex(const vector<uint8_t> & data)110 string encodeHex(const vector<uint8_t>& data) {
111     return encodeHex(data.data(), data.size());
112 }
113 
114 // Returns -1 on error, otherwise an integer in the range 0 through 15, both inclusive.
parseHexDigit(char hexDigit)115 int parseHexDigit(char hexDigit) {
116     if (hexDigit >= '0' && hexDigit <= '9') {
117         return int(hexDigit) - '0';
118     } else if (hexDigit >= 'a' && hexDigit <= 'f') {
119         return int(hexDigit) - 'a' + 10;
120     } else if (hexDigit >= 'A' && hexDigit <= 'F') {
121         return int(hexDigit) - 'A' + 10;
122     }
123     return -1;
124 }
125 
decodeHex(const string & hexEncoded)126 optional<vector<uint8_t>> decodeHex(const string& hexEncoded) {
127     vector<uint8_t> out;
128     size_t hexSize = hexEncoded.size();
129     if ((hexSize & 1) != 0) {
130         LOG(ERROR) << "Size of data cannot be odd";
131         return {};
132     }
133 
134     out.resize(hexSize / 2);
135     for (size_t n = 0; n < hexSize / 2; n++) {
136         int upperNibble = parseHexDigit(hexEncoded[n * 2]);
137         int lowerNibble = parseHexDigit(hexEncoded[n * 2 + 1]);
138         if (upperNibble == -1 || lowerNibble == -1) {
139             LOG(ERROR) << "Invalid hex digit at position " << n;
140             return {};
141         }
142         out[n] = (upperNibble << 4) + lowerNibble;
143     }
144 
145     return out;
146 }
147 
148 // ---------------------------------------------------------------------------
149 // CBOR utilities.
150 // ---------------------------------------------------------------------------
151 
cborAreAllElementsNonCompound(const cppbor::CompoundItem * compoundItem)152 static bool cborAreAllElementsNonCompound(const cppbor::CompoundItem* compoundItem) {
153     if (compoundItem->type() == cppbor::ARRAY) {
154         const cppbor::Array* array = compoundItem->asArray();
155         for (size_t n = 0; n < array->size(); n++) {
156             const cppbor::Item* entry = (*array)[n].get();
157             switch (entry->type()) {
158                 case cppbor::ARRAY:
159                 case cppbor::MAP:
160                     return false;
161                 default:
162                     break;
163             }
164         }
165     } else {
166         const cppbor::Map* map = compoundItem->asMap();
167         for (size_t n = 0; n < map->size(); n++) {
168             auto [keyEntry, valueEntry] = (*map)[n];
169             switch (keyEntry->type()) {
170                 case cppbor::ARRAY:
171                 case cppbor::MAP:
172                     return false;
173                 default:
174                     break;
175             }
176             switch (valueEntry->type()) {
177                 case cppbor::ARRAY:
178                 case cppbor::MAP:
179                     return false;
180                 default:
181                     break;
182             }
183         }
184     }
185     return true;
186 }
187 
cborPrettyPrintInternal(const cppbor::Item * item,string & out,size_t indent,size_t maxBStrSize,const vector<string> & mapKeysToNotPrint)188 static bool cborPrettyPrintInternal(const cppbor::Item* item, string& out, size_t indent,
189                                     size_t maxBStrSize, const vector<string>& mapKeysToNotPrint) {
190     char buf[80];
191 
192     string indentString(indent, ' ');
193 
194     switch (item->type()) {
195         case cppbor::UINT:
196             snprintf(buf, sizeof(buf), "%" PRIu64, item->asUint()->unsignedValue());
197             out.append(buf);
198             break;
199 
200         case cppbor::NINT:
201             snprintf(buf, sizeof(buf), "%" PRId64, item->asNint()->value());
202             out.append(buf);
203             break;
204 
205         case cppbor::BSTR: {
206             const cppbor::Bstr* bstr = item->asBstr();
207             const vector<uint8_t>& value = bstr->value();
208             if (value.size() > maxBStrSize) {
209                 unsigned char digest[SHA_DIGEST_LENGTH];
210                 SHA_CTX ctx;
211                 SHA1_Init(&ctx);
212                 SHA1_Update(&ctx, value.data(), value.size());
213                 SHA1_Final(digest, &ctx);
214                 char buf2[SHA_DIGEST_LENGTH * 2 + 1];
215                 for (size_t n = 0; n < SHA_DIGEST_LENGTH; n++) {
216                     snprintf(buf2 + n * 2, 3, "%02x", digest[n]);
217                 }
218                 snprintf(buf, sizeof(buf), "<bstr size=%zd sha1=%s>", value.size(), buf2);
219                 out.append(buf);
220             } else {
221                 out.append("{");
222                 for (size_t n = 0; n < value.size(); n++) {
223                     if (n > 0) {
224                         out.append(", ");
225                     }
226                     snprintf(buf, sizeof(buf), "0x%02x", value[n]);
227                     out.append(buf);
228                 }
229                 out.append("}");
230             }
231         } break;
232 
233         case cppbor::TSTR:
234             out.append("'");
235             {
236                 // TODO: escape "'" characters
237                 out.append(item->asTstr()->value().c_str());
238             }
239             out.append("'");
240             break;
241 
242         case cppbor::ARRAY: {
243             const cppbor::Array* array = item->asArray();
244             if (array->size() == 0) {
245                 out.append("[]");
246             } else if (cborAreAllElementsNonCompound(array)) {
247                 out.append("[");
248                 for (size_t n = 0; n < array->size(); n++) {
249                     if (!cborPrettyPrintInternal((*array)[n].get(), out, indent + 2, maxBStrSize,
250                                                  mapKeysToNotPrint)) {
251                         return false;
252                     }
253                     out.append(", ");
254                 }
255                 out.append("]");
256             } else {
257                 out.append("[\n" + indentString);
258                 for (size_t n = 0; n < array->size(); n++) {
259                     out.append("  ");
260                     if (!cborPrettyPrintInternal((*array)[n].get(), out, indent + 2, maxBStrSize,
261                                                  mapKeysToNotPrint)) {
262                         return false;
263                     }
264                     out.append(",\n" + indentString);
265                 }
266                 out.append("]");
267             }
268         } break;
269 
270         case cppbor::MAP: {
271             const cppbor::Map* map = item->asMap();
272 
273             if (map->size() == 0) {
274                 out.append("{}");
275             } else {
276                 out.append("{\n" + indentString);
277                 for (size_t n = 0; n < map->size(); n++) {
278                     out.append("  ");
279 
280                     auto [map_key, map_value] = (*map)[n];
281 
282                     if (!cborPrettyPrintInternal(map_key.get(), out, indent + 2, maxBStrSize,
283                                                  mapKeysToNotPrint)) {
284                         return false;
285                     }
286                     out.append(" : ");
287                     if (map_key->type() == cppbor::TSTR &&
288                         std::find(mapKeysToNotPrint.begin(), mapKeysToNotPrint.end(),
289                                   map_key->asTstr()->value()) != mapKeysToNotPrint.end()) {
290                         out.append("<not printed>");
291                     } else {
292                         if (!cborPrettyPrintInternal(map_value.get(), out, indent + 2, maxBStrSize,
293                                                      mapKeysToNotPrint)) {
294                             return false;
295                         }
296                     }
297                     out.append(",\n" + indentString);
298                 }
299                 out.append("}");
300             }
301         } break;
302 
303         case cppbor::SEMANTIC: {
304             const cppbor::Semantic* semantic = item->asSemantic();
305             snprintf(buf, sizeof(buf), "tag %" PRIu64 " ", semantic->value());
306             out.append(buf);
307             cborPrettyPrintInternal(semantic->child().get(), out, indent, maxBStrSize,
308                                     mapKeysToNotPrint);
309         } break;
310 
311         case cppbor::SIMPLE:
312             const cppbor::Bool* asBool = item->asSimple()->asBool();
313             const cppbor::Null* asNull = item->asSimple()->asNull();
314             if (asBool != nullptr) {
315                 out.append(asBool->value() ? "true" : "false");
316             } else if (asNull != nullptr) {
317                 out.append("null");
318             } else {
319                 LOG(ERROR) << "Only boolean/null is implemented for SIMPLE";
320                 return false;
321             }
322             break;
323     }
324 
325     return true;
326 }
327 
cborPrettyPrint(const vector<uint8_t> & encodedCbor,size_t maxBStrSize,const vector<string> & mapKeysToNotPrint)328 string cborPrettyPrint(const vector<uint8_t>& encodedCbor, size_t maxBStrSize,
329                        const vector<string>& mapKeysToNotPrint) {
330     auto [item, _, message] = cppbor::parse(encodedCbor);
331     if (item == nullptr) {
332         LOG(ERROR) << "Data to pretty print is not valid CBOR: " << message;
333         return "";
334     }
335 
336     string out;
337     cborPrettyPrintInternal(item.get(), out, 0, maxBStrSize, mapKeysToNotPrint);
338     return out;
339 }
340 
341 // ---------------------------------------------------------------------------
342 // Crypto functionality / abstraction.
343 // ---------------------------------------------------------------------------
344 
345 struct EVP_CIPHER_CTX_Deleter {
operator ()android::hardware::identity::support::EVP_CIPHER_CTX_Deleter346     void operator()(EVP_CIPHER_CTX* ctx) const {
347         if (ctx != nullptr) {
348             EVP_CIPHER_CTX_free(ctx);
349         }
350     }
351 };
352 
353 using EvpCipherCtxPtr = unique_ptr<EVP_CIPHER_CTX, EVP_CIPHER_CTX_Deleter>;
354 
355 // bool getRandom(size_t numBytes, vector<uint8_t>& output) {
getRandom(size_t numBytes)356 optional<vector<uint8_t>> getRandom(size_t numBytes) {
357     vector<uint8_t> output;
358     output.resize(numBytes);
359     if (RAND_bytes(output.data(), numBytes) != 1) {
360         LOG(ERROR) << "RAND_bytes: failed getting " << numBytes << " random";
361         return {};
362     }
363     return output;
364 }
365 
decryptAes128Gcm(const vector<uint8_t> & key,const vector<uint8_t> & encryptedData,const vector<uint8_t> & additionalAuthenticatedData)366 optional<vector<uint8_t>> decryptAes128Gcm(const vector<uint8_t>& key,
367                                            const vector<uint8_t>& encryptedData,
368                                            const vector<uint8_t>& additionalAuthenticatedData) {
369     int cipherTextSize = int(encryptedData.size()) - kAesGcmIvSize - kAesGcmTagSize;
370     if (cipherTextSize < 0) {
371         LOG(ERROR) << "encryptedData too small";
372         return {};
373     }
374     unsigned char* nonce = (unsigned char*)encryptedData.data();
375     unsigned char* cipherText = nonce + kAesGcmIvSize;
376     unsigned char* tag = cipherText + cipherTextSize;
377 
378     vector<uint8_t> plainText;
379     plainText.resize(cipherTextSize);
380 
381     auto ctx = EvpCipherCtxPtr(EVP_CIPHER_CTX_new());
382     if (ctx.get() == nullptr) {
383         LOG(ERROR) << "EVP_CIPHER_CTX_new: failed";
384         return {};
385     }
386 
387     if (EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_gcm(), NULL, NULL, NULL) != 1) {
388         LOG(ERROR) << "EVP_DecryptInit_ex: failed";
389         return {};
390     }
391 
392     if (EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_IVLEN, kAesGcmIvSize, NULL) != 1) {
393         LOG(ERROR) << "EVP_CIPHER_CTX_ctrl: failed setting nonce length";
394         return {};
395     }
396 
397     if (EVP_DecryptInit_ex(ctx.get(), NULL, NULL, (unsigned char*)key.data(), nonce) != 1) {
398         LOG(ERROR) << "EVP_DecryptInit_ex: failed";
399         return {};
400     }
401 
402     int numWritten;
403     if (additionalAuthenticatedData.size() > 0) {
404         if (EVP_DecryptUpdate(ctx.get(), NULL, &numWritten,
405                               (unsigned char*)additionalAuthenticatedData.data(),
406                               additionalAuthenticatedData.size()) != 1) {
407             LOG(ERROR) << "EVP_DecryptUpdate: failed for additionalAuthenticatedData";
408             return {};
409         }
410         if ((size_t)numWritten != additionalAuthenticatedData.size()) {
411             LOG(ERROR) << "EVP_DecryptUpdate: Unexpected outl=" << numWritten << " (expected "
412                        << additionalAuthenticatedData.size() << ") for additionalAuthenticatedData";
413             return {};
414         }
415     }
416 
417     if (EVP_DecryptUpdate(ctx.get(), (unsigned char*)plainText.data(), &numWritten, cipherText,
418                           cipherTextSize) != 1) {
419         LOG(ERROR) << "EVP_DecryptUpdate: failed";
420         return {};
421     }
422     if (numWritten != cipherTextSize) {
423         LOG(ERROR) << "EVP_DecryptUpdate: Unexpected outl=" << numWritten << " (expected "
424                    << cipherTextSize << ")";
425         return {};
426     }
427 
428     if (!EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_TAG, kAesGcmTagSize, tag)) {
429         LOG(ERROR) << "EVP_CIPHER_CTX_ctrl: failed setting expected tag";
430         return {};
431     }
432 
433     int ret = EVP_DecryptFinal_ex(ctx.get(), (unsigned char*)plainText.data() + numWritten,
434                                   &numWritten);
435     if (ret != 1) {
436         LOG(ERROR) << "EVP_DecryptFinal_ex: failed";
437         return {};
438     }
439     if (numWritten != 0) {
440         LOG(ERROR) << "EVP_DecryptFinal_ex: Unexpected non-zero outl=" << numWritten;
441         return {};
442     }
443 
444     return plainText;
445 }
446 
encryptAes128Gcm(const vector<uint8_t> & key,const vector<uint8_t> & nonce,const vector<uint8_t> & data,const vector<uint8_t> & additionalAuthenticatedData)447 optional<vector<uint8_t>> encryptAes128Gcm(const vector<uint8_t>& key, const vector<uint8_t>& nonce,
448                                            const vector<uint8_t>& data,
449                                            const vector<uint8_t>& additionalAuthenticatedData) {
450     if (key.size() != kAes128GcmKeySize) {
451         LOG(ERROR) << "key is not kAes128GcmKeySize bytes";
452         return {};
453     }
454     if (nonce.size() != kAesGcmIvSize) {
455         LOG(ERROR) << "nonce is not kAesGcmIvSize bytes";
456         return {};
457     }
458 
459     // The result is the nonce (kAesGcmIvSize bytes), the ciphertext, and
460     // finally the tag (kAesGcmTagSize bytes).
461     vector<uint8_t> encryptedData;
462     encryptedData.resize(data.size() + kAesGcmIvSize + kAesGcmTagSize);
463     unsigned char* noncePtr = (unsigned char*)encryptedData.data();
464     unsigned char* cipherText = noncePtr + kAesGcmIvSize;
465     unsigned char* tag = cipherText + data.size();
466     memcpy(noncePtr, nonce.data(), kAesGcmIvSize);
467 
468     auto ctx = EvpCipherCtxPtr(EVP_CIPHER_CTX_new());
469     if (ctx.get() == nullptr) {
470         LOG(ERROR) << "EVP_CIPHER_CTX_new: failed";
471         return {};
472     }
473 
474     if (EVP_EncryptInit_ex(ctx.get(), EVP_aes_128_gcm(), NULL, NULL, NULL) != 1) {
475         LOG(ERROR) << "EVP_EncryptInit_ex: failed";
476         return {};
477     }
478 
479     if (EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_IVLEN, kAesGcmIvSize, NULL) != 1) {
480         LOG(ERROR) << "EVP_CIPHER_CTX_ctrl: failed setting nonce length";
481         return {};
482     }
483 
484     if (EVP_EncryptInit_ex(ctx.get(), NULL, NULL, (unsigned char*)key.data(),
485                            (unsigned char*)nonce.data()) != 1) {
486         LOG(ERROR) << "EVP_EncryptInit_ex: failed";
487         return {};
488     }
489 
490     int numWritten;
491     if (additionalAuthenticatedData.size() > 0) {
492         if (EVP_EncryptUpdate(ctx.get(), NULL, &numWritten,
493                               (unsigned char*)additionalAuthenticatedData.data(),
494                               additionalAuthenticatedData.size()) != 1) {
495             LOG(ERROR) << "EVP_EncryptUpdate: failed for additionalAuthenticatedData";
496             return {};
497         }
498         if ((size_t)numWritten != additionalAuthenticatedData.size()) {
499             LOG(ERROR) << "EVP_EncryptUpdate: Unexpected outl=" << numWritten << " (expected "
500                        << additionalAuthenticatedData.size() << ") for additionalAuthenticatedData";
501             return {};
502         }
503     }
504 
505     if (data.size() > 0) {
506         if (EVP_EncryptUpdate(ctx.get(), cipherText, &numWritten, (unsigned char*)data.data(),
507                               data.size()) != 1) {
508             LOG(ERROR) << "EVP_EncryptUpdate: failed";
509             return {};
510         }
511         if ((size_t)numWritten != data.size()) {
512             LOG(ERROR) << "EVP_EncryptUpdate: Unexpected outl=" << numWritten << " (expected "
513                        << data.size() << ")";
514             return {};
515         }
516     }
517 
518     if (EVP_EncryptFinal_ex(ctx.get(), cipherText + numWritten, &numWritten) != 1) {
519         LOG(ERROR) << "EVP_EncryptFinal_ex: failed";
520         return {};
521     }
522     if (numWritten != 0) {
523         LOG(ERROR) << "EVP_EncryptFinal_ex: Unexpected non-zero outl=" << numWritten;
524         return {};
525     }
526 
527     if (EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_GET_TAG, kAesGcmTagSize, tag) != 1) {
528         LOG(ERROR) << "EVP_CIPHER_CTX_ctrl: failed getting tag";
529         return {};
530     }
531 
532     return encryptedData;
533 }
534 
535 struct EC_KEY_Deleter {
operator ()android::hardware::identity::support::EC_KEY_Deleter536     void operator()(EC_KEY* key) const {
537         if (key != nullptr) {
538             EC_KEY_free(key);
539         }
540     }
541 };
542 using EC_KEY_Ptr = unique_ptr<EC_KEY, EC_KEY_Deleter>;
543 
544 struct EVP_PKEY_Deleter {
operator ()android::hardware::identity::support::EVP_PKEY_Deleter545     void operator()(EVP_PKEY* key) const {
546         if (key != nullptr) {
547             EVP_PKEY_free(key);
548         }
549     }
550 };
551 using EVP_PKEY_Ptr = unique_ptr<EVP_PKEY, EVP_PKEY_Deleter>;
552 
553 struct EVP_PKEY_CTX_Deleter {
operator ()android::hardware::identity::support::EVP_PKEY_CTX_Deleter554     void operator()(EVP_PKEY_CTX* ctx) const {
555         if (ctx != nullptr) {
556             EVP_PKEY_CTX_free(ctx);
557         }
558     }
559 };
560 using EVP_PKEY_CTX_Ptr = unique_ptr<EVP_PKEY_CTX, EVP_PKEY_CTX_Deleter>;
561 
562 struct EC_GROUP_Deleter {
operator ()android::hardware::identity::support::EC_GROUP_Deleter563     void operator()(EC_GROUP* group) const {
564         if (group != nullptr) {
565             EC_GROUP_free(group);
566         }
567     }
568 };
569 using EC_GROUP_Ptr = unique_ptr<EC_GROUP, EC_GROUP_Deleter>;
570 
571 struct EC_POINT_Deleter {
operator ()android::hardware::identity::support::EC_POINT_Deleter572     void operator()(EC_POINT* point) const {
573         if (point != nullptr) {
574             EC_POINT_free(point);
575         }
576     }
577 };
578 
579 using EC_POINT_Ptr = unique_ptr<EC_POINT, EC_POINT_Deleter>;
580 
581 struct ECDSA_SIG_Deleter {
operator ()android::hardware::identity::support::ECDSA_SIG_Deleter582     void operator()(ECDSA_SIG* sig) const {
583         if (sig != nullptr) {
584             ECDSA_SIG_free(sig);
585         }
586     }
587 };
588 using ECDSA_SIG_Ptr = unique_ptr<ECDSA_SIG, ECDSA_SIG_Deleter>;
589 
590 struct X509_Deleter {
operator ()android::hardware::identity::support::X509_Deleter591     void operator()(X509* x509) const {
592         if (x509 != nullptr) {
593             X509_free(x509);
594         }
595     }
596 };
597 using X509_Ptr = unique_ptr<X509, X509_Deleter>;
598 
599 struct PKCS12_Deleter {
operator ()android::hardware::identity::support::PKCS12_Deleter600     void operator()(PKCS12* pkcs12) const {
601         if (pkcs12 != nullptr) {
602             PKCS12_free(pkcs12);
603         }
604     }
605 };
606 using PKCS12_Ptr = unique_ptr<PKCS12, PKCS12_Deleter>;
607 
608 struct BIGNUM_Deleter {
operator ()android::hardware::identity::support::BIGNUM_Deleter609     void operator()(BIGNUM* bignum) const {
610         if (bignum != nullptr) {
611             BN_free(bignum);
612         }
613     }
614 };
615 using BIGNUM_Ptr = unique_ptr<BIGNUM, BIGNUM_Deleter>;
616 
617 struct ASN1_INTEGER_Deleter {
operator ()android::hardware::identity::support::ASN1_INTEGER_Deleter618     void operator()(ASN1_INTEGER* value) const {
619         if (value != nullptr) {
620             ASN1_INTEGER_free(value);
621         }
622     }
623 };
624 using ASN1_INTEGER_Ptr = unique_ptr<ASN1_INTEGER, ASN1_INTEGER_Deleter>;
625 
626 struct ASN1_TIME_Deleter {
operator ()android::hardware::identity::support::ASN1_TIME_Deleter627     void operator()(ASN1_TIME* value) const {
628         if (value != nullptr) {
629             ASN1_TIME_free(value);
630         }
631     }
632 };
633 using ASN1_TIME_Ptr = unique_ptr<ASN1_TIME, ASN1_TIME_Deleter>;
634 
635 struct X509_NAME_Deleter {
operator ()android::hardware::identity::support::X509_NAME_Deleter636     void operator()(X509_NAME* value) const {
637         if (value != nullptr) {
638             X509_NAME_free(value);
639         }
640     }
641 };
642 using X509_NAME_Ptr = unique_ptr<X509_NAME, X509_NAME_Deleter>;
643 
certificateChainJoin(const vector<vector<uint8_t>> & certificateChain)644 vector<uint8_t> certificateChainJoin(const vector<vector<uint8_t>>& certificateChain) {
645     vector<uint8_t> ret;
646     for (const vector<uint8_t>& certificate : certificateChain) {
647         ret.insert(ret.end(), certificate.begin(), certificate.end());
648     }
649     return ret;
650 }
651 
certificateChainSplit(const vector<uint8_t> & certificateChain)652 optional<vector<vector<uint8_t>>> certificateChainSplit(const vector<uint8_t>& certificateChain) {
653     const unsigned char* pStart = (unsigned char*)certificateChain.data();
654     const unsigned char* p = pStart;
655     const unsigned char* pEnd = p + certificateChain.size();
656     vector<vector<uint8_t>> certificates;
657     while (p < pEnd) {
658         size_t begin = p - pStart;
659         auto x509 = X509_Ptr(d2i_X509(nullptr, &p, pEnd - p));
660         size_t next = p - pStart;
661         if (x509 == nullptr) {
662             LOG(ERROR) << "Error parsing X509 certificate";
663             return {};
664         }
665         vector<uint8_t> cert =
666                 vector<uint8_t>(certificateChain.begin() + begin, certificateChain.begin() + next);
667         certificates.push_back(std::move(cert));
668     }
669     return certificates;
670 }
671 
parseX509Certificates(const vector<uint8_t> & certificateChain,vector<X509_Ptr> & parsedCertificates)672 static bool parseX509Certificates(const vector<uint8_t>& certificateChain,
673                                   vector<X509_Ptr>& parsedCertificates) {
674     const unsigned char* p = (unsigned char*)certificateChain.data();
675     const unsigned char* pEnd = p + certificateChain.size();
676     parsedCertificates.resize(0);
677     while (p < pEnd) {
678         auto x509 = X509_Ptr(d2i_X509(nullptr, &p, pEnd - p));
679         if (x509 == nullptr) {
680             LOG(ERROR) << "Error parsing X509 certificate";
681             return false;
682         }
683         parsedCertificates.push_back(std::move(x509));
684     }
685     return true;
686 }
687 
certificateSignedByPublicKey(const vector<uint8_t> & certificate,const vector<uint8_t> & publicKey)688 bool certificateSignedByPublicKey(const vector<uint8_t>& certificate,
689                                   const vector<uint8_t>& publicKey) {
690     const unsigned char* p = certificate.data();
691     auto x509 = X509_Ptr(d2i_X509(nullptr, &p, certificate.size()));
692     if (x509 == nullptr) {
693         LOG(ERROR) << "Error parsing X509 certificate";
694         return false;
695     }
696 
697     auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
698     auto point = EC_POINT_Ptr(EC_POINT_new(group.get()));
699     if (EC_POINT_oct2point(group.get(), point.get(), publicKey.data(), publicKey.size(), nullptr) !=
700         1) {
701         LOG(ERROR) << "Error decoding publicKey";
702         return false;
703     }
704     auto ecKey = EC_KEY_Ptr(EC_KEY_new());
705     auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
706     if (ecKey.get() == nullptr || pkey.get() == nullptr) {
707         LOG(ERROR) << "Memory allocation failed";
708         return false;
709     }
710     if (EC_KEY_set_group(ecKey.get(), group.get()) != 1) {
711         LOG(ERROR) << "Error setting group";
712         return false;
713     }
714     if (EC_KEY_set_public_key(ecKey.get(), point.get()) != 1) {
715         LOG(ERROR) << "Error setting point";
716         return false;
717     }
718     if (EVP_PKEY_set1_EC_KEY(pkey.get(), ecKey.get()) != 1) {
719         LOG(ERROR) << "Error setting key";
720         return false;
721     }
722 
723     if (X509_verify(x509.get(), pkey.get()) != 1) {
724         return false;
725     }
726 
727     return true;
728 }
729 
730 // TODO: Right now the only check we perform is to check that each certificate
731 //       is signed by its successor. We should - but currently don't - also check
732 //       things like valid dates etc.
733 //
734 //       It would be nice to use X509_verify_cert() instead of doing our own thing.
735 //
certificateChainValidate(const vector<uint8_t> & certificateChain)736 bool certificateChainValidate(const vector<uint8_t>& certificateChain) {
737     vector<X509_Ptr> certs;
738 
739     if (!parseX509Certificates(certificateChain, certs)) {
740         LOG(ERROR) << "Error parsing X509 certificates";
741         return false;
742     }
743 
744     if (certs.size() == 1) {
745         return true;
746     }
747 
748     for (size_t n = 1; n < certs.size(); n++) {
749         const X509_Ptr& keyCert = certs[n - 1];
750         const X509_Ptr& signingCert = certs[n];
751         EVP_PKEY_Ptr signingPubkey(X509_get_pubkey(signingCert.get()));
752         if (X509_verify(keyCert.get(), signingPubkey.get()) != 1) {
753             LOG(ERROR) << "Error validating cert at index " << n - 1
754                        << " is signed by its successor";
755             return false;
756         }
757     }
758 
759     return true;
760 }
761 
checkEcDsaSignature(const vector<uint8_t> & digest,const vector<uint8_t> & signature,const vector<uint8_t> & publicKey)762 bool checkEcDsaSignature(const vector<uint8_t>& digest, const vector<uint8_t>& signature,
763                          const vector<uint8_t>& publicKey) {
764     const unsigned char* p = (unsigned char*)signature.data();
765     auto sig = ECDSA_SIG_Ptr(d2i_ECDSA_SIG(nullptr, &p, signature.size()));
766     if (sig.get() == nullptr) {
767         LOG(ERROR) << "Error decoding DER encoded signature";
768         return false;
769     }
770 
771     auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
772     auto point = EC_POINT_Ptr(EC_POINT_new(group.get()));
773     if (EC_POINT_oct2point(group.get(), point.get(), publicKey.data(), publicKey.size(), nullptr) !=
774         1) {
775         LOG(ERROR) << "Error decoding publicKey";
776         return false;
777     }
778     auto ecKey = EC_KEY_Ptr(EC_KEY_new());
779     auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
780     if (ecKey.get() == nullptr || pkey.get() == nullptr) {
781         LOG(ERROR) << "Memory allocation failed";
782         return false;
783     }
784     if (EC_KEY_set_group(ecKey.get(), group.get()) != 1) {
785         LOG(ERROR) << "Error setting group";
786         return false;
787     }
788     if (EC_KEY_set_public_key(ecKey.get(), point.get()) != 1) {
789         LOG(ERROR) << "Error setting point";
790         return false;
791     }
792     if (EVP_PKEY_set1_EC_KEY(pkey.get(), ecKey.get()) != 1) {
793         LOG(ERROR) << "Error setting key";
794         return false;
795     }
796 
797     int rc = ECDSA_do_verify(digest.data(), digest.size(), sig.get(), ecKey.get());
798     if (rc != 1) {
799         LOG(ERROR) << "Error verifying signature (rc=" << rc << ")";
800         return false;
801     }
802 
803     return true;
804 }
805 
sha256(const vector<uint8_t> & data)806 vector<uint8_t> sha256(const vector<uint8_t>& data) {
807     vector<uint8_t> ret;
808     ret.resize(SHA256_DIGEST_LENGTH);
809     SHA256_CTX ctx;
810     SHA256_Init(&ctx);
811     SHA256_Update(&ctx, data.data(), data.size());
812     SHA256_Final((unsigned char*)ret.data(), &ctx);
813     return ret;
814 }
815 
signEcDsaDigest(const vector<uint8_t> & key,const vector<uint8_t> & dataDigest)816 optional<vector<uint8_t>> signEcDsaDigest(const vector<uint8_t>& key,
817                                           const vector<uint8_t>& dataDigest) {
818     auto bn = BIGNUM_Ptr(BN_bin2bn(key.data(), key.size(), nullptr));
819     if (bn.get() == nullptr) {
820         LOG(ERROR) << "Error creating BIGNUM";
821         return {};
822     }
823 
824     auto ec_key = EC_KEY_Ptr(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
825     if (EC_KEY_set_private_key(ec_key.get(), bn.get()) != 1) {
826         LOG(ERROR) << "Error setting private key from BIGNUM";
827         return {};
828     }
829 
830     ECDSA_SIG* sig = ECDSA_do_sign(dataDigest.data(), dataDigest.size(), ec_key.get());
831     if (sig == nullptr) {
832         LOG(ERROR) << "Error signing digest";
833         return {};
834     }
835     size_t len = i2d_ECDSA_SIG(sig, nullptr);
836     vector<uint8_t> signature;
837     signature.resize(len);
838     unsigned char* p = (unsigned char*)signature.data();
839     i2d_ECDSA_SIG(sig, &p);
840     ECDSA_SIG_free(sig);
841     return signature;
842 }
843 
signEcDsa(const vector<uint8_t> & key,const vector<uint8_t> & data)844 optional<vector<uint8_t>> signEcDsa(const vector<uint8_t>& key, const vector<uint8_t>& data) {
845     return signEcDsaDigest(key, sha256(data));
846 }
847 
hmacSha256(const vector<uint8_t> & key,const vector<uint8_t> & data)848 optional<vector<uint8_t>> hmacSha256(const vector<uint8_t>& key, const vector<uint8_t>& data) {
849     HMAC_CTX ctx;
850     HMAC_CTX_init(&ctx);
851     if (HMAC_Init_ex(&ctx, key.data(), key.size(), EVP_sha256(), nullptr /* impl */) != 1) {
852         LOG(ERROR) << "Error initializing HMAC_CTX";
853         return {};
854     }
855     if (HMAC_Update(&ctx, data.data(), data.size()) != 1) {
856         LOG(ERROR) << "Error updating HMAC_CTX";
857         return {};
858     }
859     vector<uint8_t> hmac;
860     hmac.resize(32);
861     unsigned int size = 0;
862     if (HMAC_Final(&ctx, hmac.data(), &size) != 1) {
863         LOG(ERROR) << "Error finalizing HMAC_CTX";
864         return {};
865     }
866     if (size != 32) {
867         LOG(ERROR) << "Expected 32 bytes from HMAC_Final, got " << size;
868         return {};
869     }
870     return hmac;
871 }
872 
873 // Generates the attestation certificate with the parameters passed in.  Note
874 // that the passed in |activeTimeMilliSeconds| |expireTimeMilliSeconds| are in
875 // milli seconds since epoch.  We are setting them to milliseconds due to
876 // requirement in AuthorizationSet KM_DATE fields.  The certificate created is
877 // actually in seconds.
createAttestation(const EVP_PKEY * key,const vector<uint8_t> & applicationId,const vector<uint8_t> & challenge,uint64_t activeTimeMilliSeconds,uint64_t expireTimeMilliSeconds)878 optional<vector<vector<uint8_t>>> createAttestation(const EVP_PKEY* key,
879                                                     const vector<uint8_t>& applicationId,
880                                                     const vector<uint8_t>& challenge,
881                                                     uint64_t activeTimeMilliSeconds,
882                                                     uint64_t expireTimeMilliSeconds) {
883     ::keymaster::AuthorizationSet auth_set(
884             ::keymaster::AuthorizationSetBuilder()
885                     .Authorization(::keymaster::TAG_ATTESTATION_CHALLENGE, challenge.data(),
886                                    challenge.size())
887                     .Authorization(::keymaster::TAG_ACTIVE_DATETIME, activeTimeMilliSeconds)
888                     // Even though identity attestation hal said the application
889                     // id should be in software enforced authentication set,
890                     // keymaster portable lib expect the input in this
891                     // parameter because the software enforced in input to keymaster
892                     // refers to the key software enforced properties. And this
893                     // parameter refers to properties of the attestation which
894                     // includes app id.
895                     .Authorization(::keymaster::TAG_ATTESTATION_APPLICATION_ID,
896                                    applicationId.data(), applicationId.size())
897                     .Authorization(::keymaster::TAG_USAGE_EXPIRE_DATETIME, expireTimeMilliSeconds));
898 
899     // Unique id and device id is not applicable for identity credential attestation,
900     // so we don't need to set those or application id.
901     ::keymaster::AuthorizationSet swEnforced(::keymaster::AuthorizationSetBuilder().Authorization(
902             ::keymaster::TAG_CREATION_DATETIME, activeTimeMilliSeconds));
903 
904     ::keymaster::AuthorizationSet hwEnforced(
905             ::keymaster::AuthorizationSetBuilder()
906                     .Authorization(::keymaster::TAG_PURPOSE, KM_PURPOSE_SIGN)
907                     .Authorization(::keymaster::TAG_KEY_SIZE, 256)
908                     .Authorization(::keymaster::TAG_ALGORITHM, KM_ALGORITHM_EC)
909                     .Authorization(::keymaster::TAG_NO_AUTH_REQUIRED)
910                     .Authorization(::keymaster::TAG_DIGEST, KM_DIGEST_SHA_2_256)
911                     .Authorization(::keymaster::TAG_EC_CURVE, KM_EC_CURVE_P_256)
912                     .Authorization(::keymaster::TAG_IDENTITY_CREDENTIAL_KEY));
913 
914     const keymaster_cert_chain_t* attestation_chain =
915             ::keymaster::getAttestationChain(KM_ALGORITHM_EC, nullptr);
916 
917     if (attestation_chain == nullptr) {
918         LOG(ERROR) << "Error getting attestation chain";
919         return {};
920     }
921 
922     const keymaster_key_blob_t* attestation_signing_key =
923             ::keymaster::getAttestationKey(KM_ALGORITHM_EC, nullptr);
924     if (attestation_signing_key == nullptr) {
925         LOG(ERROR) << "Error getting attestation key";
926         return {};
927     }
928 
929     keymaster_error_t error;
930     ::keymaster::CertChainPtr cert_chain_out;
931     ::keymaster::PureSoftKeymasterContext context;
932 
933     // set identity version to 10 per hal requirements specified in IWriteableCredential.hal
934     // For now, the identity version in the attestation is set in the keymaster
935     // version field in the portable keymaster lib, which is a bit misleading.
936     uint identity_version = 10;
937     error = generate_attestation_from_EVP(key, swEnforced, hwEnforced, auth_set, context,
938                                           identity_version, *attestation_chain,
939                                           *attestation_signing_key, &cert_chain_out);
940 
941     if (KM_ERROR_OK != error || !cert_chain_out) {
942         LOG(ERROR) << "Error generate attestation from EVP key" << error;
943         return {};
944     }
945 
946     // translate certificate format from keymaster_cert_chain_t to vector<uint8_t>.
947     vector<vector<uint8_t>> attestationCertificate;
948     for (int i = 0; i < cert_chain_out->entry_count; i++) {
949         attestationCertificate.insert(
950                 attestationCertificate.end(),
951                 vector<uint8_t>(
952                         cert_chain_out->entries[i].data,
953                         cert_chain_out->entries[i].data + cert_chain_out->entries[i].data_length));
954     }
955 
956     return attestationCertificate;
957 }
958 
createEcKeyPairAndAttestation(const vector<uint8_t> & challenge,const vector<uint8_t> & applicationId)959 optional<std::pair<vector<uint8_t>, vector<vector<uint8_t>>>> createEcKeyPairAndAttestation(
960         const vector<uint8_t>& challenge, const vector<uint8_t>& applicationId) {
961     auto ec_key = ::keymaster::EC_KEY_Ptr(EC_KEY_new());
962     auto pkey = ::keymaster::EVP_PKEY_Ptr(EVP_PKEY_new());
963     auto group = ::keymaster::EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
964 
965     if (ec_key.get() == nullptr || pkey.get() == nullptr) {
966         LOG(ERROR) << "Memory allocation failed";
967         return {};
968     }
969 
970     if (EC_KEY_set_group(ec_key.get(), group.get()) != 1 ||
971         EC_KEY_generate_key(ec_key.get()) != 1 || EC_KEY_check_key(ec_key.get()) < 0) {
972         LOG(ERROR) << "Error generating key";
973         return {};
974     }
975 
976     if (EVP_PKEY_set1_EC_KEY(pkey.get(), ec_key.get()) != 1) {
977         LOG(ERROR) << "Error getting private key";
978         return {};
979     }
980 
981     uint64_t now = time(nullptr);
982     uint64_t secondsInOneYear = 365 * 24 * 60 * 60;
983     uint64_t expireTimeMs = (now + secondsInOneYear) * 1000;
984 
985     optional<vector<vector<uint8_t>>> attestationCert =
986             createAttestation(pkey.get(), applicationId, challenge, now * 1000, expireTimeMs);
987     if (!attestationCert) {
988         LOG(ERROR) << "Error create attestation from key and challenge";
989         return {};
990     }
991 
992     int size = i2d_PrivateKey(pkey.get(), nullptr);
993     if (size == 0) {
994         LOG(ERROR) << "Error generating public key encoding";
995         return {};
996     }
997 
998     vector<uint8_t> keyPair(size);
999     unsigned char* p = keyPair.data();
1000     i2d_PrivateKey(pkey.get(), &p);
1001 
1002     return make_pair(keyPair, attestationCert.value());
1003 }
1004 
createAttestationForEcPublicKey(const vector<uint8_t> & publicKey,const vector<uint8_t> & challenge,const vector<uint8_t> & applicationId)1005 optional<vector<vector<uint8_t>>> createAttestationForEcPublicKey(
1006         const vector<uint8_t>& publicKey, const vector<uint8_t>& challenge,
1007         const vector<uint8_t>& applicationId) {
1008     auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
1009     auto point = EC_POINT_Ptr(EC_POINT_new(group.get()));
1010     if (EC_POINT_oct2point(group.get(), point.get(), publicKey.data(), publicKey.size(), nullptr) !=
1011         1) {
1012         LOG(ERROR) << "Error decoding publicKey";
1013         return {};
1014     }
1015     auto ecKey = EC_KEY_Ptr(EC_KEY_new());
1016     auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
1017     if (ecKey.get() == nullptr || pkey.get() == nullptr) {
1018         LOG(ERROR) << "Memory allocation failed";
1019         return {};
1020     }
1021     if (EC_KEY_set_group(ecKey.get(), group.get()) != 1) {
1022         LOG(ERROR) << "Error setting group";
1023         return {};
1024     }
1025     if (EC_KEY_set_public_key(ecKey.get(), point.get()) != 1) {
1026         LOG(ERROR) << "Error setting point";
1027         return {};
1028     }
1029     if (EVP_PKEY_set1_EC_KEY(pkey.get(), ecKey.get()) != 1) {
1030         LOG(ERROR) << "Error setting key";
1031         return {};
1032     }
1033 
1034     uint64_t now = (std::chrono::duration_cast<std::chrono::nanoseconds>(
1035                     std::chrono::system_clock::now().time_since_epoch()).
1036                     count()/ 1000000000);
1037     uint64_t secondsInOneYear = 365 * 24 * 60 * 60;
1038     uint64_t expireTimeMs = (now + secondsInOneYear) * 1000;
1039 
1040     optional<vector<vector<uint8_t>>> attestationCert =
1041             createAttestation(pkey.get(), applicationId, challenge, now * 1000, expireTimeMs);
1042     if (!attestationCert) {
1043         LOG(ERROR) << "Error create attestation from key and challenge";
1044         return {};
1045     }
1046 
1047     return attestationCert.value();
1048 }
1049 
createEcKeyPair()1050 optional<vector<uint8_t>> createEcKeyPair() {
1051     auto ec_key = EC_KEY_Ptr(EC_KEY_new());
1052     auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
1053     if (ec_key.get() == nullptr || pkey.get() == nullptr) {
1054         LOG(ERROR) << "Memory allocation failed";
1055         return {};
1056     }
1057 
1058     auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
1059     if (group.get() == nullptr) {
1060         LOG(ERROR) << "Error creating EC group by curve name";
1061         return {};
1062     }
1063 
1064     if (EC_KEY_set_group(ec_key.get(), group.get()) != 1 ||
1065         EC_KEY_generate_key(ec_key.get()) != 1 || EC_KEY_check_key(ec_key.get()) < 0) {
1066         LOG(ERROR) << "Error generating key";
1067         return {};
1068     }
1069 
1070     if (EVP_PKEY_set1_EC_KEY(pkey.get(), ec_key.get()) != 1) {
1071         LOG(ERROR) << "Error getting private key";
1072         return {};
1073     }
1074 
1075     int size = i2d_PrivateKey(pkey.get(), nullptr);
1076     if (size == 0) {
1077         LOG(ERROR) << "Error generating public key encoding";
1078         return {};
1079     }
1080     vector<uint8_t> keyPair;
1081     keyPair.resize(size);
1082     unsigned char* p = keyPair.data();
1083     i2d_PrivateKey(pkey.get(), &p);
1084     return keyPair;
1085 }
1086 
ecKeyPairGetPublicKey(const vector<uint8_t> & keyPair)1087 optional<vector<uint8_t>> ecKeyPairGetPublicKey(const vector<uint8_t>& keyPair) {
1088     const unsigned char* p = (const unsigned char*)keyPair.data();
1089     auto pkey = EVP_PKEY_Ptr(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &p, keyPair.size()));
1090     if (pkey.get() == nullptr) {
1091         LOG(ERROR) << "Error parsing keyPair";
1092         return {};
1093     }
1094 
1095     auto ecKey = EC_KEY_Ptr(EVP_PKEY_get1_EC_KEY(pkey.get()));
1096     if (ecKey.get() == nullptr) {
1097         LOG(ERROR) << "Failed getting EC key";
1098         return {};
1099     }
1100 
1101     auto ecGroup = EC_KEY_get0_group(ecKey.get());
1102     auto ecPoint = EC_KEY_get0_public_key(ecKey.get());
1103     int size = EC_POINT_point2oct(ecGroup, ecPoint, POINT_CONVERSION_UNCOMPRESSED, nullptr, 0,
1104                                   nullptr);
1105     if (size == 0) {
1106         LOG(ERROR) << "Error generating public key encoding";
1107         return {};
1108     }
1109 
1110     vector<uint8_t> publicKey;
1111     publicKey.resize(size);
1112     EC_POINT_point2oct(ecGroup, ecPoint, POINT_CONVERSION_UNCOMPRESSED, publicKey.data(),
1113                        publicKey.size(), nullptr);
1114     return publicKey;
1115 }
1116 
ecKeyPairGetPrivateKey(const vector<uint8_t> & keyPair)1117 optional<vector<uint8_t>> ecKeyPairGetPrivateKey(const vector<uint8_t>& keyPair) {
1118     const unsigned char* p = (const unsigned char*)keyPair.data();
1119     auto pkey = EVP_PKEY_Ptr(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &p, keyPair.size()));
1120     if (pkey.get() == nullptr) {
1121         LOG(ERROR) << "Error parsing keyPair";
1122         return {};
1123     }
1124 
1125     auto ecKey = EC_KEY_Ptr(EVP_PKEY_get1_EC_KEY(pkey.get()));
1126     if (ecKey.get() == nullptr) {
1127         LOG(ERROR) << "Failed getting EC key";
1128         return {};
1129     }
1130 
1131     const BIGNUM* bignum = EC_KEY_get0_private_key(ecKey.get());
1132     if (bignum == nullptr) {
1133         LOG(ERROR) << "Error getting bignum from private key";
1134         return {};
1135     }
1136     vector<uint8_t> privateKey;
1137     privateKey.resize(BN_num_bytes(bignum));
1138     BN_bn2bin(bignum, privateKey.data());
1139     return privateKey;
1140 }
1141 
ecPrivateKeyToKeyPair(const vector<uint8_t> & privateKey)1142 optional<vector<uint8_t>> ecPrivateKeyToKeyPair(const vector<uint8_t>& privateKey) {
1143     auto bn = BIGNUM_Ptr(BN_bin2bn(privateKey.data(), privateKey.size(), nullptr));
1144     if (bn.get() == nullptr) {
1145         LOG(ERROR) << "Error creating BIGNUM";
1146         return {};
1147     }
1148 
1149     auto ecKey = EC_KEY_Ptr(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
1150     if (EC_KEY_set_private_key(ecKey.get(), bn.get()) != 1) {
1151         LOG(ERROR) << "Error setting private key from BIGNUM";
1152         return {};
1153     }
1154 
1155     auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
1156     if (pkey.get() == nullptr) {
1157         LOG(ERROR) << "Memory allocation failed";
1158         return {};
1159     }
1160 
1161     if (EVP_PKEY_set1_EC_KEY(pkey.get(), ecKey.get()) != 1) {
1162         LOG(ERROR) << "Error getting private key";
1163         return {};
1164     }
1165 
1166     int size = i2d_PrivateKey(pkey.get(), nullptr);
1167     if (size == 0) {
1168         LOG(ERROR) << "Error generating public key encoding";
1169         return {};
1170     }
1171     vector<uint8_t> keyPair;
1172     keyPair.resize(size);
1173     unsigned char* p = keyPair.data();
1174     i2d_PrivateKey(pkey.get(), &p);
1175     return keyPair;
1176 }
1177 
ecKeyPairGetPkcs12(const vector<uint8_t> & keyPair,const string & name,const string & serialDecimal,const string & issuer,const string & subject,time_t validityNotBefore,time_t validityNotAfter)1178 optional<vector<uint8_t>> ecKeyPairGetPkcs12(const vector<uint8_t>& keyPair, const string& name,
1179                                              const string& serialDecimal, const string& issuer,
1180                                              const string& subject, time_t validityNotBefore,
1181                                              time_t validityNotAfter) {
1182     const unsigned char* p = (const unsigned char*)keyPair.data();
1183     auto pkey = EVP_PKEY_Ptr(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &p, keyPair.size()));
1184     if (pkey.get() == nullptr) {
1185         LOG(ERROR) << "Error parsing keyPair";
1186         return {};
1187     }
1188 
1189     auto x509 = X509_Ptr(X509_new());
1190     if (!x509.get()) {
1191         LOG(ERROR) << "Error creating X509 certificate";
1192         return {};
1193     }
1194 
1195     if (!X509_set_version(x509.get(), 2 /* version 3, but zero-based */)) {
1196         LOG(ERROR) << "Error setting version to 3";
1197         return {};
1198     }
1199 
1200     if (X509_set_pubkey(x509.get(), pkey.get()) != 1) {
1201         LOG(ERROR) << "Error setting public key";
1202         return {};
1203     }
1204 
1205     BIGNUM* bignumSerial = nullptr;
1206     if (BN_dec2bn(&bignumSerial, serialDecimal.c_str()) == 0) {
1207         LOG(ERROR) << "Error parsing serial";
1208         return {};
1209     }
1210     auto bignumSerialPtr = BIGNUM_Ptr(bignumSerial);
1211     auto asnSerial = ASN1_INTEGER_Ptr(BN_to_ASN1_INTEGER(bignumSerial, nullptr));
1212     if (X509_set_serialNumber(x509.get(), asnSerial.get()) != 1) {
1213         LOG(ERROR) << "Error setting serial";
1214         return {};
1215     }
1216 
1217     auto x509Issuer = X509_NAME_Ptr(X509_NAME_new());
1218     if (x509Issuer.get() == nullptr ||
1219         X509_NAME_add_entry_by_txt(x509Issuer.get(), "CN", MBSTRING_ASC,
1220                                    (const uint8_t*)issuer.c_str(), issuer.size(), -1 /* loc */,
1221                                    0 /* set */) != 1 ||
1222         X509_set_issuer_name(x509.get(), x509Issuer.get()) != 1) {
1223         LOG(ERROR) << "Error setting issuer";
1224         return {};
1225     }
1226 
1227     auto x509Subject = X509_NAME_Ptr(X509_NAME_new());
1228     if (x509Subject.get() == nullptr ||
1229         X509_NAME_add_entry_by_txt(x509Subject.get(), "CN", MBSTRING_ASC,
1230                                    (const uint8_t*)subject.c_str(), subject.size(), -1 /* loc */,
1231                                    0 /* set */) != 1 ||
1232         X509_set_subject_name(x509.get(), x509Subject.get()) != 1) {
1233         LOG(ERROR) << "Error setting subject";
1234         return {};
1235     }
1236 
1237     auto asnNotBefore = ASN1_TIME_Ptr(ASN1_TIME_set(nullptr, validityNotBefore));
1238     if (asnNotBefore.get() == nullptr || X509_set_notBefore(x509.get(), asnNotBefore.get()) != 1) {
1239         LOG(ERROR) << "Error setting notBefore";
1240         return {};
1241     }
1242 
1243     auto asnNotAfter = ASN1_TIME_Ptr(ASN1_TIME_set(nullptr, validityNotAfter));
1244     if (asnNotAfter.get() == nullptr || X509_set_notAfter(x509.get(), asnNotAfter.get()) != 1) {
1245         LOG(ERROR) << "Error setting notAfter";
1246         return {};
1247     }
1248 
1249     if (X509_sign(x509.get(), pkey.get(), EVP_sha256()) == 0) {
1250         LOG(ERROR) << "Error signing X509 certificate";
1251         return {};
1252     }
1253 
1254     // Ideally we wouldn't encrypt it (we're only using this function for
1255     // sending a key-pair over binder to the Android app) but BoringSSL does not
1256     // support this: from pkcs8_x509.c in BoringSSL: "In OpenSSL, -1 here means
1257     // to use no encryption, which we do not currently support."
1258     //
1259     // Passing nullptr as |pass|, though, means "no password". So we'll do that.
1260     // Compare with the receiving side - CredstoreIdentityCredential.java - where
1261     // an empty char[] is passed as the password.
1262     //
1263     auto pkcs12 = PKCS12_Ptr(PKCS12_create(nullptr, name.c_str(), pkey.get(), x509.get(),
1264                                            nullptr,  // ca
1265                                            0,        // nid_key
1266                                            0,        // nid_cert
1267                                            0,        // iter,
1268                                            0,        // mac_iter,
1269                                            0));      // keytype
1270     if (pkcs12.get() == nullptr) {
1271         char buf[128];
1272         long errCode = ERR_get_error();
1273         ERR_error_string_n(errCode, buf, sizeof buf);
1274         LOG(ERROR) << "Error creating PKCS12, code " << errCode << ": " << buf;
1275         return {};
1276     }
1277 
1278     unsigned char* buffer = nullptr;
1279     int length = i2d_PKCS12(pkcs12.get(), &buffer);
1280     if (length < 0) {
1281         LOG(ERROR) << "Error encoding PKCS12";
1282         return {};
1283     }
1284     vector<uint8_t> pkcs12Bytes;
1285     pkcs12Bytes.resize(length);
1286     memcpy(pkcs12Bytes.data(), buffer, length);
1287     OPENSSL_free(buffer);
1288 
1289     return pkcs12Bytes;
1290 }
1291 
ecPublicKeyGenerateCertificate(const vector<uint8_t> & publicKey,const vector<uint8_t> & signingKey,const string & serialDecimal,const string & issuer,const string & subject,time_t validityNotBefore,time_t validityNotAfter)1292 optional<vector<uint8_t>> ecPublicKeyGenerateCertificate(
1293         const vector<uint8_t>& publicKey, const vector<uint8_t>& signingKey,
1294         const string& serialDecimal, const string& issuer, const string& subject,
1295         time_t validityNotBefore, time_t validityNotAfter) {
1296     auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
1297     auto point = EC_POINT_Ptr(EC_POINT_new(group.get()));
1298     if (EC_POINT_oct2point(group.get(), point.get(), publicKey.data(), publicKey.size(), nullptr) !=
1299         1) {
1300         LOG(ERROR) << "Error decoding publicKey";
1301         return {};
1302     }
1303     auto ecKey = EC_KEY_Ptr(EC_KEY_new());
1304     auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
1305     if (ecKey.get() == nullptr || pkey.get() == nullptr) {
1306         LOG(ERROR) << "Memory allocation failed";
1307         return {};
1308     }
1309     if (EC_KEY_set_group(ecKey.get(), group.get()) != 1) {
1310         LOG(ERROR) << "Error setting group";
1311         return {};
1312     }
1313     if (EC_KEY_set_public_key(ecKey.get(), point.get()) != 1) {
1314         LOG(ERROR) << "Error setting point";
1315         return {};
1316     }
1317     if (EVP_PKEY_set1_EC_KEY(pkey.get(), ecKey.get()) != 1) {
1318         LOG(ERROR) << "Error setting key";
1319         return {};
1320     }
1321 
1322     auto bn = BIGNUM_Ptr(BN_bin2bn(signingKey.data(), signingKey.size(), nullptr));
1323     if (bn.get() == nullptr) {
1324         LOG(ERROR) << "Error creating BIGNUM for private key";
1325         return {};
1326     }
1327     auto privEcKey = EC_KEY_Ptr(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
1328     if (EC_KEY_set_private_key(privEcKey.get(), bn.get()) != 1) {
1329         LOG(ERROR) << "Error setting private key from BIGNUM";
1330         return {};
1331     }
1332     auto privPkey = EVP_PKEY_Ptr(EVP_PKEY_new());
1333     if (EVP_PKEY_set1_EC_KEY(privPkey.get(), privEcKey.get()) != 1) {
1334         LOG(ERROR) << "Error setting private key";
1335         return {};
1336     }
1337 
1338     auto x509 = X509_Ptr(X509_new());
1339     if (!x509.get()) {
1340         LOG(ERROR) << "Error creating X509 certificate";
1341         return {};
1342     }
1343 
1344     if (!X509_set_version(x509.get(), 2 /* version 3, but zero-based */)) {
1345         LOG(ERROR) << "Error setting version to 3";
1346         return {};
1347     }
1348 
1349     if (X509_set_pubkey(x509.get(), pkey.get()) != 1) {
1350         LOG(ERROR) << "Error setting public key";
1351         return {};
1352     }
1353 
1354     BIGNUM* bignumSerial = nullptr;
1355     if (BN_dec2bn(&bignumSerial, serialDecimal.c_str()) == 0) {
1356         LOG(ERROR) << "Error parsing serial";
1357         return {};
1358     }
1359     auto bignumSerialPtr = BIGNUM_Ptr(bignumSerial);
1360     auto asnSerial = ASN1_INTEGER_Ptr(BN_to_ASN1_INTEGER(bignumSerial, nullptr));
1361     if (X509_set_serialNumber(x509.get(), asnSerial.get()) != 1) {
1362         LOG(ERROR) << "Error setting serial";
1363         return {};
1364     }
1365 
1366     auto x509Issuer = X509_NAME_Ptr(X509_NAME_new());
1367     if (x509Issuer.get() == nullptr ||
1368         X509_NAME_add_entry_by_txt(x509Issuer.get(), "CN", MBSTRING_ASC,
1369                                    (const uint8_t*)issuer.c_str(), issuer.size(), -1 /* loc */,
1370                                    0 /* set */) != 1 ||
1371         X509_set_issuer_name(x509.get(), x509Issuer.get()) != 1) {
1372         LOG(ERROR) << "Error setting issuer";
1373         return {};
1374     }
1375 
1376     auto x509Subject = X509_NAME_Ptr(X509_NAME_new());
1377     if (x509Subject.get() == nullptr ||
1378         X509_NAME_add_entry_by_txt(x509Subject.get(), "CN", MBSTRING_ASC,
1379                                    (const uint8_t*)subject.c_str(), subject.size(), -1 /* loc */,
1380                                    0 /* set */) != 1 ||
1381         X509_set_subject_name(x509.get(), x509Subject.get()) != 1) {
1382         LOG(ERROR) << "Error setting subject";
1383         return {};
1384     }
1385 
1386     auto asnNotBefore = ASN1_TIME_Ptr(ASN1_TIME_set(nullptr, validityNotBefore));
1387     if (asnNotBefore.get() == nullptr || X509_set_notBefore(x509.get(), asnNotBefore.get()) != 1) {
1388         LOG(ERROR) << "Error setting notBefore";
1389         return {};
1390     }
1391 
1392     auto asnNotAfter = ASN1_TIME_Ptr(ASN1_TIME_set(nullptr, validityNotAfter));
1393     if (asnNotAfter.get() == nullptr || X509_set_notAfter(x509.get(), asnNotAfter.get()) != 1) {
1394         LOG(ERROR) << "Error setting notAfter";
1395         return {};
1396     }
1397 
1398     if (X509_sign(x509.get(), privPkey.get(), EVP_sha256()) == 0) {
1399         LOG(ERROR) << "Error signing X509 certificate";
1400         return {};
1401     }
1402 
1403     unsigned char* buffer = nullptr;
1404     int length = i2d_X509(x509.get(), &buffer);
1405     if (length < 0) {
1406         LOG(ERROR) << "Error DER encoding X509 certificate";
1407         return {};
1408     }
1409 
1410     vector<uint8_t> certificate;
1411     certificate.resize(length);
1412     memcpy(certificate.data(), buffer, length);
1413     OPENSSL_free(buffer);
1414     return certificate;
1415 }
1416 
ecdh(const vector<uint8_t> & publicKey,const vector<uint8_t> & privateKey)1417 optional<vector<uint8_t>> ecdh(const vector<uint8_t>& publicKey,
1418                                const vector<uint8_t>& privateKey) {
1419     auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
1420     auto point = EC_POINT_Ptr(EC_POINT_new(group.get()));
1421     if (EC_POINT_oct2point(group.get(), point.get(), publicKey.data(), publicKey.size(), nullptr) !=
1422         1) {
1423         LOG(ERROR) << "Error decoding publicKey";
1424         return {};
1425     }
1426     auto ecKey = EC_KEY_Ptr(EC_KEY_new());
1427     auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
1428     if (ecKey.get() == nullptr || pkey.get() == nullptr) {
1429         LOG(ERROR) << "Memory allocation failed";
1430         return {};
1431     }
1432     if (EC_KEY_set_group(ecKey.get(), group.get()) != 1) {
1433         LOG(ERROR) << "Error setting group";
1434         return {};
1435     }
1436     if (EC_KEY_set_public_key(ecKey.get(), point.get()) != 1) {
1437         LOG(ERROR) << "Error setting point";
1438         return {};
1439     }
1440     if (EVP_PKEY_set1_EC_KEY(pkey.get(), ecKey.get()) != 1) {
1441         LOG(ERROR) << "Error setting key";
1442         return {};
1443     }
1444 
1445     auto bn = BIGNUM_Ptr(BN_bin2bn(privateKey.data(), privateKey.size(), nullptr));
1446     if (bn.get() == nullptr) {
1447         LOG(ERROR) << "Error creating BIGNUM for private key";
1448         return {};
1449     }
1450     auto privEcKey = EC_KEY_Ptr(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
1451     if (EC_KEY_set_private_key(privEcKey.get(), bn.get()) != 1) {
1452         LOG(ERROR) << "Error setting private key from BIGNUM";
1453         return {};
1454     }
1455     auto privPkey = EVP_PKEY_Ptr(EVP_PKEY_new());
1456     if (EVP_PKEY_set1_EC_KEY(privPkey.get(), privEcKey.get()) != 1) {
1457         LOG(ERROR) << "Error setting private key";
1458         return {};
1459     }
1460 
1461     auto ctx = EVP_PKEY_CTX_Ptr(EVP_PKEY_CTX_new(privPkey.get(), NULL));
1462     if (ctx.get() == nullptr) {
1463         LOG(ERROR) << "Error creating context";
1464         return {};
1465     }
1466 
1467     if (EVP_PKEY_derive_init(ctx.get()) != 1) {
1468         LOG(ERROR) << "Error initializing context";
1469         return {};
1470     }
1471 
1472     if (EVP_PKEY_derive_set_peer(ctx.get(), pkey.get()) != 1) {
1473         LOG(ERROR) << "Error setting peer";
1474         return {};
1475     }
1476 
1477     /* Determine buffer length for shared secret */
1478     size_t secretLen = 0;
1479     if (EVP_PKEY_derive(ctx.get(), NULL, &secretLen) != 1) {
1480         LOG(ERROR) << "Error determing length of shared secret";
1481         return {};
1482     }
1483     vector<uint8_t> sharedSecret;
1484     sharedSecret.resize(secretLen);
1485 
1486     if (EVP_PKEY_derive(ctx.get(), sharedSecret.data(), &secretLen) != 1) {
1487         LOG(ERROR) << "Error deriving shared secret";
1488         return {};
1489     }
1490     return sharedSecret;
1491 }
1492 
hkdf(const vector<uint8_t> & sharedSecret,const vector<uint8_t> & salt,const vector<uint8_t> & info,size_t size)1493 optional<vector<uint8_t>> hkdf(const vector<uint8_t>& sharedSecret, const vector<uint8_t>& salt,
1494                                const vector<uint8_t>& info, size_t size) {
1495     vector<uint8_t> derivedKey;
1496     derivedKey.resize(size);
1497     if (HKDF(derivedKey.data(), derivedKey.size(), EVP_sha256(), sharedSecret.data(),
1498              sharedSecret.size(), salt.data(), salt.size(), info.data(), info.size()) != 1) {
1499         LOG(ERROR) << "Error deriving key";
1500         return {};
1501     }
1502     return derivedKey;
1503 }
1504 
removeLeadingZeroes(vector<uint8_t> & vec)1505 void removeLeadingZeroes(vector<uint8_t>& vec) {
1506     while (vec.size() >= 1 && vec[0] == 0x00) {
1507         vec.erase(vec.begin());
1508     }
1509 }
1510 
ecPublicKeyGetXandY(const vector<uint8_t> & publicKey)1511 tuple<bool, vector<uint8_t>, vector<uint8_t>> ecPublicKeyGetXandY(
1512         const vector<uint8_t>& publicKey) {
1513     if (publicKey.size() != 65 || publicKey[0] != 0x04) {
1514         LOG(ERROR) << "publicKey is not in the expected format";
1515         return std::make_tuple(false, vector<uint8_t>(), vector<uint8_t>());
1516     }
1517     vector<uint8_t> x, y;
1518     x.resize(32);
1519     y.resize(32);
1520     memcpy(x.data(), publicKey.data() + 1, 32);
1521     memcpy(y.data(), publicKey.data() + 33, 32);
1522 
1523     removeLeadingZeroes(x);
1524     removeLeadingZeroes(y);
1525 
1526     return std::make_tuple(true, x, y);
1527 }
1528 
certificateChainGetTopMostKey(const vector<uint8_t> & certificateChain)1529 optional<vector<uint8_t>> certificateChainGetTopMostKey(const vector<uint8_t>& certificateChain) {
1530     vector<X509_Ptr> certs;
1531     if (!parseX509Certificates(certificateChain, certs)) {
1532         return {};
1533     }
1534     if (certs.size() < 1) {
1535         LOG(ERROR) << "No certificates in chain";
1536         return {};
1537     }
1538 
1539     int algoId = OBJ_obj2nid(certs[0]->cert_info->key->algor->algorithm);
1540     if (algoId != NID_X9_62_id_ecPublicKey) {
1541         LOG(ERROR) << "Expected NID_X9_62_id_ecPublicKey, got " << OBJ_nid2ln(algoId);
1542         return {};
1543     }
1544 
1545     auto pkey = EVP_PKEY_Ptr(X509_get_pubkey(certs[0].get()));
1546     if (pkey.get() == nullptr) {
1547         LOG(ERROR) << "No public key";
1548         return {};
1549     }
1550 
1551     auto ecKey = EC_KEY_Ptr(EVP_PKEY_get1_EC_KEY(pkey.get()));
1552     if (ecKey.get() == nullptr) {
1553         LOG(ERROR) << "Failed getting EC key";
1554         return {};
1555     }
1556 
1557     auto ecGroup = EC_KEY_get0_group(ecKey.get());
1558     auto ecPoint = EC_KEY_get0_public_key(ecKey.get());
1559     int size = EC_POINT_point2oct(ecGroup, ecPoint, POINT_CONVERSION_UNCOMPRESSED, nullptr, 0,
1560                                   nullptr);
1561     if (size == 0) {
1562         LOG(ERROR) << "Error generating public key encoding";
1563         return {};
1564     }
1565     vector<uint8_t> publicKey;
1566     publicKey.resize(size);
1567     EC_POINT_point2oct(ecGroup, ecPoint, POINT_CONVERSION_UNCOMPRESSED, publicKey.data(),
1568                        publicKey.size(), nullptr);
1569     return publicKey;
1570 }
1571 
certificateFindPublicKey(const vector<uint8_t> & x509Certificate)1572 optional<pair<size_t, size_t>> certificateFindPublicKey(const vector<uint8_t>& x509Certificate) {
1573     vector<X509_Ptr> certs;
1574     if (!parseX509Certificates(x509Certificate, certs)) {
1575         return {};
1576     }
1577     if (certs.size() < 1) {
1578         LOG(ERROR) << "No certificates in chain";
1579         return {};
1580     }
1581 
1582     auto pkey = EVP_PKEY_Ptr(X509_get_pubkey(certs[0].get()));
1583     if (pkey.get() == nullptr) {
1584         LOG(ERROR) << "No public key";
1585         return {};
1586     }
1587 
1588     auto ecKey = EC_KEY_Ptr(EVP_PKEY_get1_EC_KEY(pkey.get()));
1589     if (ecKey.get() == nullptr) {
1590         LOG(ERROR) << "Failed getting EC key";
1591         return {};
1592     }
1593 
1594     auto ecGroup = EC_KEY_get0_group(ecKey.get());
1595     auto ecPoint = EC_KEY_get0_public_key(ecKey.get());
1596     int size = EC_POINT_point2oct(ecGroup, ecPoint, POINT_CONVERSION_UNCOMPRESSED, nullptr, 0,
1597                                   nullptr);
1598     if (size == 0) {
1599         LOG(ERROR) << "Error generating public key encoding";
1600         return {};
1601     }
1602     vector<uint8_t> publicKey;
1603     publicKey.resize(size);
1604     EC_POINT_point2oct(ecGroup, ecPoint, POINT_CONVERSION_UNCOMPRESSED, publicKey.data(),
1605                        publicKey.size(), nullptr);
1606 
1607     size_t publicKeyOffset = 0;
1608     size_t publicKeySize = (size_t)size;
1609     void* location = memmem((const void*)x509Certificate.data(), x509Certificate.size(),
1610                             (const void*)publicKey.data(), publicKey.size());
1611 
1612     if (location == NULL) {
1613         LOG(ERROR) << "Error finding publicKey from x509Certificate";
1614         return {};
1615     }
1616     publicKeyOffset = (size_t)((const char*)location - (const char*)x509Certificate.data());
1617 
1618     return std::make_pair(publicKeyOffset, publicKeySize);
1619 }
1620 
certificateTbsCertificate(const vector<uint8_t> & x509Certificate)1621 optional<pair<size_t, size_t>> certificateTbsCertificate(const vector<uint8_t>& x509Certificate) {
1622     vector<X509_Ptr> certs;
1623     if (!parseX509Certificates(x509Certificate, certs)) {
1624         return {};
1625     }
1626     if (certs.size() < 1) {
1627         LOG(ERROR) << "No certificates in chain";
1628         return {};
1629     }
1630 
1631     unsigned char* buf = NULL;
1632     int len = i2d_re_X509_tbs(certs[0].get(), &buf);
1633     if ((len < 0) || (buf == NULL)) {
1634         LOG(ERROR) << "fail to extract tbsCertificate in x509Certificate";
1635         return {};
1636     }
1637 
1638     vector<uint8_t> tbsCertificate(len);
1639     memcpy(tbsCertificate.data(), buf, len);
1640 
1641     size_t tbsCertificateOffset = 0;
1642     size_t tbsCertificateSize = (size_t)len;
1643     void* location = memmem((const void*)x509Certificate.data(), x509Certificate.size(),
1644                             (const void*)tbsCertificate.data(), tbsCertificate.size());
1645 
1646     if (location == NULL) {
1647         LOG(ERROR) << "Error finding tbsCertificate from x509Certificate";
1648         return {};
1649     }
1650     tbsCertificateOffset = (size_t)((const char*)location - (const char*)x509Certificate.data());
1651 
1652     return std::make_pair(tbsCertificateOffset, tbsCertificateSize);
1653 }
1654 
certificateFindSignature(const vector<uint8_t> & x509Certificate)1655 optional<pair<size_t, size_t>> certificateFindSignature(const vector<uint8_t>& x509Certificate) {
1656     vector<X509_Ptr> certs;
1657     if (!parseX509Certificates(x509Certificate, certs)) {
1658         return {};
1659     }
1660     if (certs.size() < 1) {
1661         LOG(ERROR) << "No certificates in chain";
1662         return {};
1663     }
1664 
1665     ASN1_BIT_STRING* psig;
1666     X509_ALGOR* palg;
1667     X509_get0_signature((const ASN1_BIT_STRING**)&psig, (const X509_ALGOR**)&palg, certs[0].get());
1668 
1669     vector<char> signature(psig->length);
1670     memcpy(signature.data(), psig->data, psig->length);
1671 
1672     size_t signatureOffset = 0;
1673     size_t signatureSize = (size_t)psig->length;
1674     void* location = memmem((const void*)x509Certificate.data(), x509Certificate.size(),
1675                             (const void*)signature.data(), signature.size());
1676 
1677     if (location == NULL) {
1678         LOG(ERROR) << "Error finding signature from x509Certificate";
1679         return {};
1680     }
1681     signatureOffset = (size_t)((const char*)location - (const char*)x509Certificate.data());
1682 
1683     return std::make_pair(signatureOffset, signatureSize);
1684 }
1685 
1686 // ---------------------------------------------------------------------------
1687 // COSE Utility Functions
1688 // ---------------------------------------------------------------------------
1689 
coseBuildToBeSigned(const vector<uint8_t> & encodedProtectedHeaders,const vector<uint8_t> & data,const vector<uint8_t> & detachedContent)1690 vector<uint8_t> coseBuildToBeSigned(const vector<uint8_t>& encodedProtectedHeaders,
1691                                     const vector<uint8_t>& data,
1692                                     const vector<uint8_t>& detachedContent) {
1693     cppbor::Array sigStructure;
1694     sigStructure.add("Signature1");
1695     sigStructure.add(encodedProtectedHeaders);
1696 
1697     // We currently don't support Externally Supplied Data (RFC 8152 section 4.3)
1698     // so external_aad is the empty bstr
1699     vector<uint8_t> emptyExternalAad;
1700     sigStructure.add(emptyExternalAad);
1701 
1702     // Next field is the payload, independently of how it's transported (RFC
1703     // 8152 section 4.4). Since our API specifies only one of |data| and
1704     // |detachedContent| can be non-empty, it's simply just the non-empty one.
1705     if (data.size() > 0) {
1706         sigStructure.add(data);
1707     } else {
1708         sigStructure.add(detachedContent);
1709     }
1710     return sigStructure.encode();
1711 }
1712 
coseEncodeHeaders(const cppbor::Map & protectedHeaders)1713 vector<uint8_t> coseEncodeHeaders(const cppbor::Map& protectedHeaders) {
1714     if (protectedHeaders.size() == 0) {
1715         cppbor::Bstr emptyBstr(vector<uint8_t>({}));
1716         return emptyBstr.encode();
1717     }
1718     return protectedHeaders.encode();
1719 }
1720 
1721 // From https://tools.ietf.org/html/rfc8152
1722 const int COSE_LABEL_ALG = 1;
1723 const int COSE_LABEL_X5CHAIN = 33;  // temporary identifier
1724 
1725 // From "COSE Algorithms" registry
1726 const int COSE_ALG_ECDSA_256 = -7;
1727 const int COSE_ALG_HMAC_256_256 = 5;
1728 
ecdsaSignatureCoseToDer(const vector<uint8_t> & ecdsaCoseSignature,vector<uint8_t> & ecdsaDerSignature)1729 bool ecdsaSignatureCoseToDer(const vector<uint8_t>& ecdsaCoseSignature,
1730                              vector<uint8_t>& ecdsaDerSignature) {
1731     if (ecdsaCoseSignature.size() != 64) {
1732         LOG(ERROR) << "COSE signature length is " << ecdsaCoseSignature.size() << ", expected 64";
1733         return false;
1734     }
1735 
1736     auto rBn = BIGNUM_Ptr(BN_bin2bn(ecdsaCoseSignature.data(), 32, nullptr));
1737     if (rBn.get() == nullptr) {
1738         LOG(ERROR) << "Error creating BIGNUM for r";
1739         return false;
1740     }
1741 
1742     auto sBn = BIGNUM_Ptr(BN_bin2bn(ecdsaCoseSignature.data() + 32, 32, nullptr));
1743     if (sBn.get() == nullptr) {
1744         LOG(ERROR) << "Error creating BIGNUM for s";
1745         return false;
1746     }
1747 
1748     ECDSA_SIG sig;
1749     sig.r = rBn.get();
1750     sig.s = sBn.get();
1751 
1752     size_t len = i2d_ECDSA_SIG(&sig, nullptr);
1753     ecdsaDerSignature.resize(len);
1754     unsigned char* p = (unsigned char*)ecdsaDerSignature.data();
1755     i2d_ECDSA_SIG(&sig, &p);
1756 
1757     return true;
1758 }
1759 
ecdsaSignatureDerToCose(const vector<uint8_t> & ecdsaDerSignature,vector<uint8_t> & ecdsaCoseSignature)1760 bool ecdsaSignatureDerToCose(const vector<uint8_t>& ecdsaDerSignature,
1761                              vector<uint8_t>& ecdsaCoseSignature) {
1762     ECDSA_SIG* sig;
1763     const unsigned char* p = ecdsaDerSignature.data();
1764     sig = d2i_ECDSA_SIG(nullptr, &p, ecdsaDerSignature.size());
1765     if (sig == nullptr) {
1766         LOG(ERROR) << "Error decoding DER signature";
1767         return false;
1768     }
1769 
1770     ecdsaCoseSignature.clear();
1771     ecdsaCoseSignature.resize(64);
1772     if (BN_bn2binpad(sig->r, ecdsaCoseSignature.data(), 32) != 32) {
1773         LOG(ERROR) << "Error encoding r";
1774         return false;
1775     }
1776     if (BN_bn2binpad(sig->s, ecdsaCoseSignature.data() + 32, 32) != 32) {
1777         LOG(ERROR) << "Error encoding s";
1778         return false;
1779     }
1780     return true;
1781 }
1782 
coseSignEcDsaWithSignature(const vector<uint8_t> & signatureToBeSigned,const vector<uint8_t> & data,const vector<uint8_t> & certificateChain)1783 optional<vector<uint8_t>> coseSignEcDsaWithSignature(const vector<uint8_t>& signatureToBeSigned,
1784                                                      const vector<uint8_t>& data,
1785                                                      const vector<uint8_t>& certificateChain) {
1786     if (signatureToBeSigned.size() != 64) {
1787         LOG(ERROR) << "Invalid size for signatureToBeSigned, expected 64 got "
1788                    << signatureToBeSigned.size();
1789         return {};
1790     }
1791 
1792     cppbor::Map unprotectedHeaders;
1793     cppbor::Map protectedHeaders;
1794 
1795     protectedHeaders.add(COSE_LABEL_ALG, COSE_ALG_ECDSA_256);
1796 
1797     if (certificateChain.size() != 0) {
1798         optional<vector<vector<uint8_t>>> certs = support::certificateChainSplit(certificateChain);
1799         if (!certs) {
1800             LOG(ERROR) << "Error splitting certificate chain";
1801             return {};
1802         }
1803         if (certs.value().size() == 1) {
1804             unprotectedHeaders.add(COSE_LABEL_X5CHAIN, certs.value()[0]);
1805         } else {
1806             cppbor::Array certArray;
1807             for (const vector<uint8_t>& cert : certs.value()) {
1808                 certArray.add(cert);
1809             }
1810             unprotectedHeaders.add(COSE_LABEL_X5CHAIN, std::move(certArray));
1811         }
1812     }
1813 
1814     vector<uint8_t> encodedProtectedHeaders = coseEncodeHeaders(protectedHeaders);
1815 
1816     cppbor::Array coseSign1;
1817     coseSign1.add(encodedProtectedHeaders);
1818     coseSign1.add(std::move(unprotectedHeaders));
1819     if (data.size() == 0) {
1820         cppbor::Null nullValue;
1821         coseSign1.add(std::move(nullValue));
1822     } else {
1823         coseSign1.add(data);
1824     }
1825     coseSign1.add(signatureToBeSigned);
1826     vector<uint8_t> signatureCoseSign1;
1827     signatureCoseSign1 = coseSign1.encode();
1828 
1829     return signatureCoseSign1;
1830 }
1831 
coseSignEcDsa(const vector<uint8_t> & key,const vector<uint8_t> & data,const vector<uint8_t> & detachedContent,const vector<uint8_t> & certificateChain)1832 optional<vector<uint8_t>> coseSignEcDsa(const vector<uint8_t>& key, const vector<uint8_t>& data,
1833                                         const vector<uint8_t>& detachedContent,
1834                                         const vector<uint8_t>& certificateChain) {
1835     cppbor::Map unprotectedHeaders;
1836     cppbor::Map protectedHeaders;
1837 
1838     if (data.size() > 0 && detachedContent.size() > 0) {
1839         LOG(ERROR) << "data and detachedContent cannot both be non-empty";
1840         return {};
1841     }
1842 
1843     protectedHeaders.add(COSE_LABEL_ALG, COSE_ALG_ECDSA_256);
1844 
1845     if (certificateChain.size() != 0) {
1846         optional<vector<vector<uint8_t>>> certs = support::certificateChainSplit(certificateChain);
1847         if (!certs) {
1848             LOG(ERROR) << "Error splitting certificate chain";
1849             return {};
1850         }
1851         if (certs.value().size() == 1) {
1852             unprotectedHeaders.add(COSE_LABEL_X5CHAIN, certs.value()[0]);
1853         } else {
1854             cppbor::Array certArray;
1855             for (const vector<uint8_t>& cert : certs.value()) {
1856                 certArray.add(cert);
1857             }
1858             unprotectedHeaders.add(COSE_LABEL_X5CHAIN, std::move(certArray));
1859         }
1860     }
1861 
1862     vector<uint8_t> encodedProtectedHeaders = coseEncodeHeaders(protectedHeaders);
1863     vector<uint8_t> toBeSigned =
1864             coseBuildToBeSigned(encodedProtectedHeaders, data, detachedContent);
1865 
1866     optional<vector<uint8_t>> derSignature = signEcDsa(key, toBeSigned);
1867     if (!derSignature) {
1868         LOG(ERROR) << "Error signing toBeSigned data";
1869         return {};
1870     }
1871     vector<uint8_t> coseSignature;
1872     if (!ecdsaSignatureDerToCose(derSignature.value(), coseSignature)) {
1873         LOG(ERROR) << "Error converting ECDSA signature from DER to COSE format";
1874         return {};
1875     }
1876 
1877     cppbor::Array coseSign1;
1878     coseSign1.add(encodedProtectedHeaders);
1879     coseSign1.add(std::move(unprotectedHeaders));
1880     if (data.size() == 0) {
1881         cppbor::Null nullValue;
1882         coseSign1.add(std::move(nullValue));
1883     } else {
1884         coseSign1.add(data);
1885     }
1886     coseSign1.add(coseSignature);
1887     vector<uint8_t> signatureCoseSign1;
1888     signatureCoseSign1 = coseSign1.encode();
1889     return signatureCoseSign1;
1890 }
1891 
coseCheckEcDsaSignature(const vector<uint8_t> & signatureCoseSign1,const vector<uint8_t> & detachedContent,const vector<uint8_t> & publicKey)1892 bool coseCheckEcDsaSignature(const vector<uint8_t>& signatureCoseSign1,
1893                              const vector<uint8_t>& detachedContent,
1894                              const vector<uint8_t>& publicKey) {
1895     auto [item, _, message] = cppbor::parse(signatureCoseSign1);
1896     if (item == nullptr) {
1897         LOG(ERROR) << "Passed-in COSE_Sign1 is not valid CBOR: " << message;
1898         return false;
1899     }
1900     const cppbor::Array* array = item->asArray();
1901     if (array == nullptr) {
1902         LOG(ERROR) << "Value for COSE_Sign1 is not an array";
1903         return false;
1904     }
1905     if (array->size() != 4) {
1906         LOG(ERROR) << "Value for COSE_Sign1 is not an array of size 4";
1907         return false;
1908     }
1909 
1910     const cppbor::Bstr* encodedProtectedHeadersBstr = (*array)[0]->asBstr();
1911     ;
1912     if (encodedProtectedHeadersBstr == nullptr) {
1913         LOG(ERROR) << "Value for encodedProtectedHeaders is not a bstr";
1914         return false;
1915     }
1916     const vector<uint8_t> encodedProtectedHeaders = encodedProtectedHeadersBstr->value();
1917 
1918     const cppbor::Map* unprotectedHeaders = (*array)[1]->asMap();
1919     if (unprotectedHeaders == nullptr) {
1920         LOG(ERROR) << "Value for unprotectedHeaders is not a map";
1921         return false;
1922     }
1923 
1924     vector<uint8_t> data;
1925     const cppbor::Simple* payloadAsSimple = (*array)[2]->asSimple();
1926     if (payloadAsSimple != nullptr) {
1927         if (payloadAsSimple->asNull() == nullptr) {
1928             LOG(ERROR) << "Value for payload is not null or a bstr";
1929             return false;
1930         }
1931     } else {
1932         const cppbor::Bstr* payloadAsBstr = (*array)[2]->asBstr();
1933         if (payloadAsBstr == nullptr) {
1934             LOG(ERROR) << "Value for payload is not null or a bstr";
1935             return false;
1936         }
1937         data = payloadAsBstr->value();  // TODO: avoid copy
1938     }
1939 
1940     if (data.size() > 0 && detachedContent.size() > 0) {
1941         LOG(ERROR) << "data and detachedContent cannot both be non-empty";
1942         return false;
1943     }
1944 
1945     const cppbor::Bstr* signatureBstr = (*array)[3]->asBstr();
1946     if (signatureBstr == nullptr) {
1947         LOG(ERROR) << "Value for signature is a bstr";
1948         return false;
1949     }
1950     const vector<uint8_t>& coseSignature = signatureBstr->value();
1951 
1952     vector<uint8_t> derSignature;
1953     if (!ecdsaSignatureCoseToDer(coseSignature, derSignature)) {
1954         LOG(ERROR) << "Error converting ECDSA signature from COSE to DER format";
1955         return false;
1956     }
1957 
1958     vector<uint8_t> toBeSigned =
1959             coseBuildToBeSigned(encodedProtectedHeaders, data, detachedContent);
1960     if (!checkEcDsaSignature(support::sha256(toBeSigned), derSignature, publicKey)) {
1961         LOG(ERROR) << "Signature check failed";
1962         return false;
1963     }
1964     return true;
1965 }
1966 
1967 // Extracts the signature (of the ToBeSigned CBOR) from a COSE_Sign1.
coseSignGetSignature(const vector<uint8_t> & signatureCoseSign1)1968 optional<vector<uint8_t>> coseSignGetSignature(const vector<uint8_t>& signatureCoseSign1) {
1969     auto [item, _, message] = cppbor::parse(signatureCoseSign1);
1970     if (item == nullptr) {
1971         LOG(ERROR) << "Passed-in COSE_Sign1 is not valid CBOR: " << message;
1972         return {};
1973     }
1974     const cppbor::Array* array = item->asArray();
1975     if (array == nullptr) {
1976         LOG(ERROR) << "Value for COSE_Sign1 is not an array";
1977         return {};
1978     }
1979     if (array->size() != 4) {
1980         LOG(ERROR) << "Value for COSE_Sign1 is not an array of size 4";
1981         return {};
1982     }
1983 
1984     vector<uint8_t> signature;
1985     const cppbor::Bstr* signatureAsBstr = (*array)[3]->asBstr();
1986     if (signatureAsBstr == nullptr) {
1987         LOG(ERROR) << "Value for signature is not a bstr";
1988         return {};
1989     }
1990     // Copy payload into |data|
1991     signature = signatureAsBstr->value();
1992 
1993     return signature;
1994 }
1995 
coseSignGetPayload(const vector<uint8_t> & signatureCoseSign1)1996 optional<vector<uint8_t>> coseSignGetPayload(const vector<uint8_t>& signatureCoseSign1) {
1997     auto [item, _, message] = cppbor::parse(signatureCoseSign1);
1998     if (item == nullptr) {
1999         LOG(ERROR) << "Passed-in COSE_Sign1 is not valid CBOR: " << message;
2000         return {};
2001     }
2002     const cppbor::Array* array = item->asArray();
2003     if (array == nullptr) {
2004         LOG(ERROR) << "Value for COSE_Sign1 is not an array";
2005         return {};
2006     }
2007     if (array->size() != 4) {
2008         LOG(ERROR) << "Value for COSE_Sign1 is not an array of size 4";
2009         return {};
2010     }
2011 
2012     vector<uint8_t> data;
2013     const cppbor::Simple* payloadAsSimple = (*array)[2]->asSimple();
2014     if (payloadAsSimple != nullptr) {
2015         if (payloadAsSimple->asNull() == nullptr) {
2016             LOG(ERROR) << "Value for payload is not null or a bstr";
2017             return {};
2018         }
2019         // payload is null, so |data| should be empty (as it is)
2020     } else {
2021         const cppbor::Bstr* payloadAsBstr = (*array)[2]->asBstr();
2022         if (payloadAsBstr == nullptr) {
2023             LOG(ERROR) << "Value for payload is not null or a bstr";
2024             return {};
2025         }
2026         // Copy payload into |data|
2027         data = payloadAsBstr->value();
2028     }
2029 
2030     return data;
2031 }
2032 
coseSignGetAlg(const vector<uint8_t> & signatureCoseSign1)2033 optional<int> coseSignGetAlg(const vector<uint8_t>& signatureCoseSign1) {
2034     auto [item, _, message] = cppbor::parse(signatureCoseSign1);
2035     if (item == nullptr) {
2036         LOG(ERROR) << "Passed-in COSE_Sign1 is not valid CBOR: " << message;
2037         return {};
2038     }
2039     const cppbor::Array* array = item->asArray();
2040     if (array == nullptr) {
2041         LOG(ERROR) << "Value for COSE_Sign1 is not an array";
2042         return {};
2043     }
2044     if (array->size() != 4) {
2045         LOG(ERROR) << "Value for COSE_Sign1 is not an array of size 4";
2046         return {};
2047     }
2048 
2049     const cppbor::Bstr* protectedHeadersBytes = (*array)[0]->asBstr();
2050     if (protectedHeadersBytes == nullptr) {
2051         LOG(ERROR) << "Value for protectedHeaders is not a bstr";
2052         return {};
2053     }
2054     auto [item2, _2, message2] = cppbor::parse(protectedHeadersBytes->value());
2055     if (item2 == nullptr) {
2056         LOG(ERROR) << "Error parsing protectedHeaders: " << message2;
2057         return {};
2058     }
2059     const cppbor::Map* protectedHeaders = item2->asMap();
2060     if (protectedHeaders == nullptr) {
2061         LOG(ERROR) << "Decoded CBOR for protectedHeaders is not a map";
2062         return {};
2063     }
2064 
2065     for (size_t n = 0; n < protectedHeaders->size(); n++) {
2066         auto [keyItem, valueItem] = (*protectedHeaders)[n];
2067         const cppbor::Int* number = keyItem->asInt();
2068         if (number == nullptr) {
2069             LOG(ERROR) << "Key item in top-level map is not a number";
2070             return {};
2071         }
2072         int label = number->value();
2073         if (label == COSE_LABEL_ALG) {
2074             const cppbor::Int* number = valueItem->asInt();
2075             if (number != nullptr) {
2076                 return number->value();
2077             }
2078             LOG(ERROR) << "Value for COSE_LABEL_ALG label is not a number";
2079             return {};
2080         }
2081     }
2082     LOG(ERROR) << "Did not find COSE_LABEL_ALG label in protected headers";
2083     return {};
2084 }
2085 
coseSignGetX5Chain(const vector<uint8_t> & signatureCoseSign1)2086 optional<vector<uint8_t>> coseSignGetX5Chain(const vector<uint8_t>& signatureCoseSign1) {
2087     auto [item, _, message] = cppbor::parse(signatureCoseSign1);
2088     if (item == nullptr) {
2089         LOG(ERROR) << "Passed-in COSE_Sign1 is not valid CBOR: " << message;
2090         return {};
2091     }
2092     const cppbor::Array* array = item->asArray();
2093     if (array == nullptr) {
2094         LOG(ERROR) << "Value for COSE_Sign1 is not an array";
2095         return {};
2096     }
2097     if (array->size() != 4) {
2098         LOG(ERROR) << "Value for COSE_Sign1 is not an array of size 4";
2099         return {};
2100     }
2101 
2102     const cppbor::Map* unprotectedHeaders = (*array)[1]->asMap();
2103     if (unprotectedHeaders == nullptr) {
2104         LOG(ERROR) << "Value for unprotectedHeaders is not a map";
2105         return {};
2106     }
2107 
2108     for (size_t n = 0; n < unprotectedHeaders->size(); n++) {
2109         auto [keyItem, valueItem] = (*unprotectedHeaders)[n];
2110         const cppbor::Int* number = keyItem->asInt();
2111         if (number == nullptr) {
2112             LOG(ERROR) << "Key item in top-level map is not a number";
2113             return {};
2114         }
2115         int label = number->value();
2116         if (label == COSE_LABEL_X5CHAIN) {
2117             const cppbor::Bstr* bstr = valueItem->asBstr();
2118             if (bstr != nullptr) {
2119                 return bstr->value();
2120             }
2121             const cppbor::Array* array = valueItem->asArray();
2122             if (array != nullptr) {
2123                 vector<uint8_t> certs;
2124                 for (size_t m = 0; m < array->size(); m++) {
2125                     const cppbor::Bstr* bstr = ((*array)[m])->asBstr();
2126                     if (bstr == nullptr) {
2127                         LOG(ERROR) << "Item in x5chain array is not a bstr";
2128                         return {};
2129                     }
2130                     const vector<uint8_t>& certValue = bstr->value();
2131                     certs.insert(certs.end(), certValue.begin(), certValue.end());
2132                 }
2133                 return certs;
2134             }
2135             LOG(ERROR) << "Value for x5chain label is not a bstr or array";
2136             return {};
2137         }
2138     }
2139     LOG(ERROR) << "Did not find x5chain label in unprotected headers";
2140     return {};
2141 }
2142 
coseBuildToBeMACed(const vector<uint8_t> & encodedProtectedHeaders,const vector<uint8_t> & data,const vector<uint8_t> & detachedContent)2143 vector<uint8_t> coseBuildToBeMACed(const vector<uint8_t>& encodedProtectedHeaders,
2144                                    const vector<uint8_t>& data,
2145                                    const vector<uint8_t>& detachedContent) {
2146     cppbor::Array macStructure;
2147     macStructure.add("MAC0");
2148     macStructure.add(encodedProtectedHeaders);
2149 
2150     // We currently don't support Externally Supplied Data (RFC 8152 section 4.3)
2151     // so external_aad is the empty bstr
2152     vector<uint8_t> emptyExternalAad;
2153     macStructure.add(emptyExternalAad);
2154 
2155     // Next field is the payload, independently of how it's transported (RFC
2156     // 8152 section 4.4). Since our API specifies only one of |data| and
2157     // |detachedContent| can be non-empty, it's simply just the non-empty one.
2158     if (data.size() > 0) {
2159         macStructure.add(data);
2160     } else {
2161         macStructure.add(detachedContent);
2162     }
2163 
2164     return macStructure.encode();
2165 }
2166 
coseMac0(const vector<uint8_t> & key,const vector<uint8_t> & data,const vector<uint8_t> & detachedContent)2167 optional<vector<uint8_t>> coseMac0(const vector<uint8_t>& key, const vector<uint8_t>& data,
2168                                    const vector<uint8_t>& detachedContent) {
2169     cppbor::Map unprotectedHeaders;
2170     cppbor::Map protectedHeaders;
2171 
2172     if (data.size() > 0 && detachedContent.size() > 0) {
2173         LOG(ERROR) << "data and detachedContent cannot both be non-empty";
2174         return {};
2175     }
2176 
2177     protectedHeaders.add(COSE_LABEL_ALG, COSE_ALG_HMAC_256_256);
2178 
2179     vector<uint8_t> encodedProtectedHeaders = coseEncodeHeaders(protectedHeaders);
2180     vector<uint8_t> toBeMACed = coseBuildToBeMACed(encodedProtectedHeaders, data, detachedContent);
2181 
2182     optional<vector<uint8_t>> mac = hmacSha256(key, toBeMACed);
2183     if (!mac) {
2184         LOG(ERROR) << "Error MACing toBeMACed data";
2185         return {};
2186     }
2187 
2188     cppbor::Array array;
2189     array.add(encodedProtectedHeaders);
2190     array.add(std::move(unprotectedHeaders));
2191     if (data.size() == 0) {
2192         cppbor::Null nullValue;
2193         array.add(std::move(nullValue));
2194     } else {
2195         array.add(data);
2196     }
2197     array.add(mac.value());
2198     return array.encode();
2199 }
2200 
coseMacWithDigest(const vector<uint8_t> & digestToBeMaced,const vector<uint8_t> & data)2201 optional<vector<uint8_t>> coseMacWithDigest(const vector<uint8_t>& digestToBeMaced,
2202                                             const vector<uint8_t>& data) {
2203     cppbor::Map unprotectedHeaders;
2204     cppbor::Map protectedHeaders;
2205 
2206     protectedHeaders.add(COSE_LABEL_ALG, COSE_ALG_HMAC_256_256);
2207 
2208     vector<uint8_t> encodedProtectedHeaders = coseEncodeHeaders(protectedHeaders);
2209 
2210     cppbor::Array array;
2211     array.add(encodedProtectedHeaders);
2212     array.add(std::move(unprotectedHeaders));
2213     if (data.size() == 0) {
2214         cppbor::Null nullValue;
2215         array.add(std::move(nullValue));
2216     } else {
2217         array.add(data);
2218     }
2219     array.add(digestToBeMaced);
2220     return array.encode();
2221 }
2222 
2223 // ---------------------------------------------------------------------------
2224 // Utility functions specific to IdentityCredential.
2225 // ---------------------------------------------------------------------------
2226 
chunkVector(const vector<uint8_t> & content,size_t maxChunkSize)2227 vector<vector<uint8_t>> chunkVector(const vector<uint8_t>& content, size_t maxChunkSize) {
2228     vector<vector<uint8_t>> ret;
2229 
2230     size_t contentSize = content.size();
2231     if (contentSize <= maxChunkSize) {
2232         ret.push_back(content);
2233         return ret;
2234     }
2235 
2236     size_t numChunks = (contentSize + maxChunkSize - 1) / maxChunkSize;
2237 
2238     size_t pos = 0;
2239     for (size_t n = 0; n < numChunks; n++) {
2240         size_t size = contentSize - pos;
2241         if (size > maxChunkSize) {
2242             size = maxChunkSize;
2243         }
2244         auto begin = content.begin() + pos;
2245         auto end = content.begin() + pos + size;
2246         ret.emplace_back(vector<uint8_t>(begin, end));
2247         pos += maxChunkSize;
2248     }
2249 
2250     return ret;
2251 }
2252 
2253 
2254 vector<uint8_t> testHardwareBoundKey = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
2255 
getTestHardwareBoundKey()2256 const vector<uint8_t>& getTestHardwareBoundKey() {
2257     return testHardwareBoundKey;
2258 }
2259 
2260 }  // namespace support
2261 }  // namespace identity
2262 }  // namespace hardware
2263 }  // namespace android
2264