1 /*
2  * Copyright (c) 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 #include <iomanip>
18 #include <iterator>
19 #include <memory>
20 #include <set>
21 #include <string>
22 #include <tuple>
23 #include "aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h"
24 
25 #include <aidl/android/hardware/security/keymint/RpcHardwareInfo.h>
26 #include <android-base/macros.h>
27 #include <android-base/properties.h>
28 #include <cppbor.h>
29 #include <hwtrust/hwtrust.h>
30 #include <json/json.h>
31 #include <keymaster/km_openssl/ec_key.h>
32 #include <keymaster/km_openssl/ecdsa_operation.h>
33 #include <keymaster/km_openssl/openssl_err.h>
34 #include <keymaster/km_openssl/openssl_utils.h>
35 #include <openssl/base64.h>
36 #include <openssl/evp.h>
37 #include <openssl/rand.h>
38 #include <openssl/x509.h>
39 #include <remote_prov/remote_prov_utils.h>
40 
41 namespace aidl::android::hardware::security::keymint::remote_prov {
42 
43 constexpr uint32_t kBccPayloadIssuer = 1;
44 constexpr uint32_t kBccPayloadSubject = 2;
45 constexpr int32_t kBccPayloadSubjPubKey = -4670552;
46 constexpr int32_t kBccPayloadKeyUsage = -4670553;
47 constexpr int kP256AffinePointSize = 32;
48 constexpr uint32_t kNumTeeDeviceInfoEntries = 14;
49 
50 using EC_KEY_Ptr = bssl::UniquePtr<EC_KEY>;
51 using EVP_PKEY_Ptr = bssl::UniquePtr<EVP_PKEY>;
52 using EVP_PKEY_CTX_Ptr = bssl::UniquePtr<EVP_PKEY_CTX>;
53 using X509_Ptr = bssl::UniquePtr<X509>;
54 using CRYPTO_BUFFER_Ptr = bssl::UniquePtr<CRYPTO_BUFFER>;
55 
ecKeyGetPrivateKey(const EC_KEY * ecKey)56 ErrMsgOr<bytevec> ecKeyGetPrivateKey(const EC_KEY* ecKey) {
57     // Extract private key.
58     const BIGNUM* bignum = EC_KEY_get0_private_key(ecKey);
59     if (bignum == nullptr) {
60         return "Error getting bignum from private key";
61     }
62     // Pad with zeros in case the length is lesser than 32.
63     bytevec privKey(32, 0);
64     BN_bn2binpad(bignum, privKey.data(), privKey.size());
65     return privKey;
66 }
67 
ecKeyGetPublicKey(const EC_KEY * ecKey)68 ErrMsgOr<bytevec> ecKeyGetPublicKey(const EC_KEY* ecKey) {
69     // Extract public key.
70     auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
71     if (group.get() == nullptr) {
72         return "Error creating EC group by curve name";
73     }
74     const EC_POINT* point = EC_KEY_get0_public_key(ecKey);
75     if (point == nullptr) return "Error getting ecpoint from public key";
76 
77     int size =
78         EC_POINT_point2oct(group.get(), point, POINT_CONVERSION_UNCOMPRESSED, nullptr, 0, nullptr);
79     if (size == 0) {
80         return "Error generating public key encoding";
81     }
82 
83     bytevec publicKey;
84     publicKey.resize(size);
85     EC_POINT_point2oct(group.get(), point, POINT_CONVERSION_UNCOMPRESSED, publicKey.data(),
86                        publicKey.size(), nullptr);
87     return publicKey;
88 }
89 
getAffineCoordinates(const bytevec & pubKey)90 ErrMsgOr<std::tuple<bytevec, bytevec>> getAffineCoordinates(const bytevec& pubKey) {
91     auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
92     if (group.get() == nullptr) {
93         return "Error creating EC group by curve name";
94     }
95     auto point = EC_POINT_Ptr(EC_POINT_new(group.get()));
96     if (EC_POINT_oct2point(group.get(), point.get(), pubKey.data(), pubKey.size(), nullptr) != 1) {
97         return "Error decoding publicKey";
98     }
99     BIGNUM_Ptr x(BN_new());
100     BIGNUM_Ptr y(BN_new());
101     BN_CTX_Ptr ctx(BN_CTX_new());
102     if (!ctx.get()) return "Failed to create BN_CTX instance";
103 
104     if (!EC_POINT_get_affine_coordinates_GFp(group.get(), point.get(), x.get(), y.get(),
105                                              ctx.get())) {
106         return "Failed to get affine coordinates from ECPoint";
107     }
108     bytevec pubX(kP256AffinePointSize);
109     bytevec pubY(kP256AffinePointSize);
110     if (BN_bn2binpad(x.get(), pubX.data(), kP256AffinePointSize) != kP256AffinePointSize) {
111         return "Error in converting absolute value of x coordinate to big-endian";
112     }
113     if (BN_bn2binpad(y.get(), pubY.data(), kP256AffinePointSize) != kP256AffinePointSize) {
114         return "Error in converting absolute value of y coordinate to big-endian";
115     }
116     return std::make_tuple(std::move(pubX), std::move(pubY));
117 }
118 
getRawPublicKey(const EVP_PKEY_Ptr & pubKey)119 ErrMsgOr<bytevec> getRawPublicKey(const EVP_PKEY_Ptr& pubKey) {
120     if (pubKey.get() == nullptr) {
121         return "pkey is null.";
122     }
123     int keyType = EVP_PKEY_base_id(pubKey.get());
124     switch (keyType) {
125         case EVP_PKEY_EC: {
126             auto ecKey = EC_KEY_Ptr(EVP_PKEY_get1_EC_KEY(pubKey.get()));
127             if (ecKey.get() == nullptr) {
128                 return "Failed to get ec key";
129             }
130             return ecKeyGetPublicKey(ecKey.get());
131         }
132         case EVP_PKEY_ED25519: {
133             bytevec rawPubKey;
134             size_t rawKeySize = 0;
135             if (!EVP_PKEY_get_raw_public_key(pubKey.get(), NULL, &rawKeySize)) {
136                 return "Failed to get raw public key.";
137             }
138             rawPubKey.resize(rawKeySize);
139             if (!EVP_PKEY_get_raw_public_key(pubKey.get(), rawPubKey.data(), &rawKeySize)) {
140                 return "Failed to get raw public key.";
141             }
142             return rawPubKey;
143         }
144         default:
145             return "Unknown key type.";
146     }
147 }
148 
generateEc256KeyPair()149 ErrMsgOr<std::tuple<bytevec, bytevec>> generateEc256KeyPair() {
150     auto ec_key = EC_KEY_Ptr(EC_KEY_new());
151     if (ec_key.get() == nullptr) {
152         return "Failed to allocate ec key";
153     }
154 
155     auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
156     if (group.get() == nullptr) {
157         return "Error creating EC group by curve name";
158     }
159 
160     if (EC_KEY_set_group(ec_key.get(), group.get()) != 1 ||
161         EC_KEY_generate_key(ec_key.get()) != 1 || EC_KEY_check_key(ec_key.get()) < 0) {
162         return "Error generating key";
163     }
164 
165     auto privKey = ecKeyGetPrivateKey(ec_key.get());
166     if (!privKey) return privKey.moveMessage();
167 
168     auto pubKey = ecKeyGetPublicKey(ec_key.get());
169     if (!pubKey) return pubKey.moveMessage();
170 
171     return std::make_tuple(pubKey.moveValue(), privKey.moveValue());
172 }
173 
generateX25519KeyPair()174 ErrMsgOr<std::tuple<bytevec, bytevec>> generateX25519KeyPair() {
175     /* Generate X25519 key pair */
176     bytevec pubKey(X25519_PUBLIC_VALUE_LEN);
177     bytevec privKey(X25519_PRIVATE_KEY_LEN);
178     X25519_keypair(pubKey.data(), privKey.data());
179     return std::make_tuple(std::move(pubKey), std::move(privKey));
180 }
181 
generateED25519KeyPair()182 ErrMsgOr<std::tuple<bytevec, bytevec>> generateED25519KeyPair() {
183     /* Generate ED25519 key pair */
184     bytevec pubKey(ED25519_PUBLIC_KEY_LEN);
185     bytevec privKey(ED25519_PRIVATE_KEY_LEN);
186     ED25519_keypair(pubKey.data(), privKey.data());
187     return std::make_tuple(std::move(pubKey), std::move(privKey));
188 }
189 
generateKeyPair(int32_t supportedEekCurve,bool isEek)190 ErrMsgOr<std::tuple<bytevec, bytevec>> generateKeyPair(int32_t supportedEekCurve, bool isEek) {
191     switch (supportedEekCurve) {
192     case RpcHardwareInfo::CURVE_25519:
193         if (isEek) {
194             return generateX25519KeyPair();
195         }
196         return generateED25519KeyPair();
197     case RpcHardwareInfo::CURVE_P256:
198         return generateEc256KeyPair();
199     default:
200         return "Unknown EEK Curve.";
201     }
202 }
203 
constructCoseKey(int32_t supportedEekCurve,const bytevec & eekId,const bytevec & pubKey)204 ErrMsgOr<bytevec> constructCoseKey(int32_t supportedEekCurve, const bytevec& eekId,
205                                    const bytevec& pubKey) {
206     CoseKeyType keyType;
207     CoseKeyAlgorithm algorithm;
208     CoseKeyCurve curve;
209     bytevec pubX;
210     bytevec pubY;
211     switch (supportedEekCurve) {
212     case RpcHardwareInfo::CURVE_25519:
213         keyType = OCTET_KEY_PAIR;
214         algorithm = (eekId.empty()) ? EDDSA : ECDH_ES_HKDF_256;
215         curve = (eekId.empty()) ? ED25519 : cppcose::X25519;
216         pubX = pubKey;
217         break;
218     case RpcHardwareInfo::CURVE_P256: {
219         keyType = EC2;
220         algorithm = (eekId.empty()) ? ES256 : ECDH_ES_HKDF_256;
221         curve = P256;
222         auto affineCoordinates = getAffineCoordinates(pubKey);
223         if (!affineCoordinates) return affineCoordinates.moveMessage();
224         std::tie(pubX, pubY) = affineCoordinates.moveValue();
225     } break;
226     default:
227         return "Unknown EEK Curve.";
228     }
229     cppbor::Map coseKey = cppbor::Map()
230                               .add(CoseKey::KEY_TYPE, keyType)
231                               .add(CoseKey::ALGORITHM, algorithm)
232                               .add(CoseKey::CURVE, curve)
233                               .add(CoseKey::PUBKEY_X, pubX);
234 
235     if (!pubY.empty()) coseKey.add(CoseKey::PUBKEY_Y, pubY);
236     if (!eekId.empty()) coseKey.add(CoseKey::KEY_ID, eekId);
237 
238     return coseKey.canonicalize().encode();
239 }
240 
241 bytevec kTestMacKey(32 /* count */, 0 /* byte value */);
242 
randomBytes(size_t numBytes)243 bytevec randomBytes(size_t numBytes) {
244     bytevec retval(numBytes);
245     RAND_bytes(retval.data(), numBytes);
246     return retval;
247 }
248 
constructCoseSign1(int32_t supportedEekCurve,const bytevec & key,const bytevec & payload,const bytevec & aad)249 ErrMsgOr<cppbor::Array> constructCoseSign1(int32_t supportedEekCurve, const bytevec& key,
250                                            const bytevec& payload, const bytevec& aad) {
251     if (supportedEekCurve == RpcHardwareInfo::CURVE_P256) {
252         return constructECDSACoseSign1(key, {} /* protectedParams */, payload, aad);
253     } else {
254         return cppcose::constructCoseSign1(key, payload, aad);
255     }
256 }
257 
generateEekChain(int32_t supportedEekCurve,size_t length,const bytevec & eekId)258 ErrMsgOr<EekChain> generateEekChain(int32_t supportedEekCurve, size_t length,
259                                     const bytevec& eekId) {
260     if (length < 2) {
261         return "EEK chain must contain at least 2 certs.";
262     }
263 
264     auto eekChain = cppbor::Array();
265 
266     bytevec prev_priv_key;
267     for (size_t i = 0; i < length - 1; ++i) {
268         auto keyPair = generateKeyPair(supportedEekCurve, false);
269         if (!keyPair) return keyPair.moveMessage();
270         auto [pub_key, priv_key] = keyPair.moveValue();
271 
272         // The first signing key is self-signed.
273         if (prev_priv_key.empty()) prev_priv_key = priv_key;
274 
275         auto coseKey = constructCoseKey(supportedEekCurve, {}, pub_key);
276         if (!coseKey) return coseKey.moveMessage();
277 
278         auto coseSign1 =
279             constructCoseSign1(supportedEekCurve, prev_priv_key, coseKey.moveValue(), {} /* AAD */);
280         if (!coseSign1) return coseSign1.moveMessage();
281         eekChain.add(coseSign1.moveValue());
282 
283         prev_priv_key = priv_key;
284     }
285     auto keyPair = generateKeyPair(supportedEekCurve, true);
286     if (!keyPair) return keyPair.moveMessage();
287     auto [pub_key, priv_key] = keyPair.moveValue();
288 
289     auto coseKey = constructCoseKey(supportedEekCurve, eekId, pub_key);
290     if (!coseKey) return coseKey.moveMessage();
291 
292     auto coseSign1 =
293         constructCoseSign1(supportedEekCurve, prev_priv_key, coseKey.moveValue(), {} /* AAD */);
294     if (!coseSign1) return coseSign1.moveMessage();
295     eekChain.add(coseSign1.moveValue());
296 
297     if (supportedEekCurve == RpcHardwareInfo::CURVE_P256) {
298         // convert ec public key to x and y co-ordinates.
299         auto affineCoordinates = getAffineCoordinates(pub_key);
300         if (!affineCoordinates) return affineCoordinates.moveMessage();
301         auto [pubX, pubY] = affineCoordinates.moveValue();
302         pub_key.clear();
303         pub_key.insert(pub_key.begin(), pubX.begin(), pubX.end());
304         pub_key.insert(pub_key.end(), pubY.begin(), pubY.end());
305     }
306 
307     return EekChain{eekChain.encode(), pub_key, priv_key};
308 }
309 
getProdEekChain(int32_t supportedEekCurve)310 bytevec getProdEekChain(int32_t supportedEekCurve) {
311     cppbor::Array chain;
312     if (supportedEekCurve == RpcHardwareInfo::CURVE_P256) {
313         chain.add(cppbor::EncodedItem(bytevec(std::begin(kCoseEncodedEcdsa256RootCert),
314                                               std::end(kCoseEncodedEcdsa256RootCert))));
315         chain.add(cppbor::EncodedItem(bytevec(std::begin(kCoseEncodedEcdsa256GeekCert),
316                                               std::end(kCoseEncodedEcdsa256GeekCert))));
317     } else {
318         chain.add(cppbor::EncodedItem(
319             bytevec(std::begin(kCoseEncodedRootCert), std::end(kCoseEncodedRootCert))));
320         chain.add(cppbor::EncodedItem(
321             bytevec(std::begin(kCoseEncodedGeekCert), std::end(kCoseEncodedGeekCert))));
322     }
323     return chain.encode();
324 }
325 
validateBcc(const cppbor::Array * bcc,hwtrust::DiceChain::Kind kind)326 ErrMsgOr<std::vector<BccEntryData>> validateBcc(const cppbor::Array* bcc,
327                                                 hwtrust::DiceChain::Kind kind) {
328     auto encodedBcc = bcc->encode();
329     auto chain = hwtrust::DiceChain::Verify(encodedBcc, kind);
330     if (!chain.ok()) return chain.error().message();
331     auto keys = chain->CosePublicKeys();
332     if (!keys.ok()) return keys.error().message();
333     std::vector<BccEntryData> result;
334     for (auto& key : *keys) {
335         result.push_back({std::move(key)});
336     }
337     return result;
338 }
339 
jsonEncodeCsrWithBuild(const std::string & instance_name,const cppbor::Array & csr,const std::string & serialno_prop)340 JsonOutput jsonEncodeCsrWithBuild(const std::string& instance_name, const cppbor::Array& csr,
341                                   const std::string& serialno_prop) {
342     const std::string kFingerprintProp = "ro.build.fingerprint";
343 
344     if (!::android::base::WaitForPropertyCreation(kFingerprintProp)) {
345         return JsonOutput::Error("Unable to read build fingerprint");
346     }
347 
348     bytevec csrCbor = csr.encode();
349     size_t base64Length;
350     int rc = EVP_EncodedLength(&base64Length, csrCbor.size());
351     if (!rc) {
352         return JsonOutput::Error("Error getting base64 length. Size overflow?");
353     }
354 
355     std::vector<char> base64(base64Length);
356     rc = EVP_EncodeBlock(reinterpret_cast<uint8_t*>(base64.data()), csrCbor.data(), csrCbor.size());
357     ++rc;  // Account for NUL, which BoringSSL does not for some reason.
358     if (rc != base64Length) {
359         return JsonOutput::Error("Error writing base64. Expected " + std::to_string(base64Length) +
360                                  " bytes to be written, but " + std::to_string(rc) +
361                                  " bytes were actually written.");
362     }
363 
364     Json::Value json(Json::objectValue);
365     json["name"] = instance_name;
366     json["build_fingerprint"] = ::android::base::GetProperty(kFingerprintProp, /*default=*/"");
367     json["serialno"] = ::android::base::GetProperty(serialno_prop, /*default=*/"");
368     json["csr"] = base64.data();  // Boring writes a NUL-terminated c-string
369 
370     Json::StreamWriterBuilder factory;
371     factory["indentation"] = "";  // disable pretty formatting
372     return JsonOutput::Ok(Json::writeString(factory, json));
373 }
374 
checkMapEntry(bool isFactory,const cppbor::Map & devInfo,cppbor::MajorType majorType,const std::string & entryName)375 std::string checkMapEntry(bool isFactory, const cppbor::Map& devInfo, cppbor::MajorType majorType,
376                           const std::string& entryName) {
377     const std::unique_ptr<cppbor::Item>& val = devInfo.get(entryName);
378     if (!val) {
379         return entryName + " is missing.\n";
380     }
381     if (val->type() != majorType) {
382         return entryName + " has the wrong type.\n";
383     }
384     if (isFactory) {
385         return "";
386     }
387     switch (majorType) {
388         case cppbor::TSTR:
389             if (val->asTstr()->value().size() <= 0) {
390                 return entryName + " is present but the value is empty.\n";
391             }
392             break;
393         case cppbor::BSTR:
394             if (val->asBstr()->value().size() <= 0) {
395                 return entryName + " is present but the value is empty.\n";
396             }
397             break;
398         default:
399             break;
400     }
401     return "";
402 }
403 
checkMapEntry(bool isFactory,const cppbor::Map & devInfo,cppbor::MajorType majorType,const std::string & entryName,const cppbor::Array & allowList)404 std::string checkMapEntry(bool isFactory, const cppbor::Map& devInfo, cppbor::MajorType majorType,
405                           const std::string& entryName, const cppbor::Array& allowList) {
406     std::string error = checkMapEntry(isFactory, devInfo, majorType, entryName);
407     if (!error.empty()) {
408         return error;
409     }
410 
411     if (isFactory) {
412         return "";
413     }
414 
415     const std::unique_ptr<cppbor::Item>& val = devInfo.get(entryName);
416     for (auto i = allowList.begin(); i != allowList.end(); ++i) {
417         if (**i == *val) {
418             return "";
419         }
420     }
421     return entryName + " has an invalid value.\n";
422 }
423 
checkMapPatchLevelEntry(bool isFactory,const cppbor::Map & devInfo,const std::string & entryName)424 std::string checkMapPatchLevelEntry(bool isFactory, const cppbor::Map& devInfo,
425                                     const std::string& entryName) {
426     std::string error = checkMapEntry(isFactory, devInfo, cppbor::UINT, entryName);
427     if (!error.empty()) {
428         return error;
429     }
430 
431     if (isFactory) {
432         return "";
433     }
434 
435     const std::unique_ptr<cppbor::Item>& val = devInfo.get(entryName);
436     std::string dateString = std::to_string(val->asUint()->unsignedValue());
437     if (dateString.size() == 6) {
438         dateString += "01";
439     }
440     if (dateString.size() != 8) {
441         return entryName + " should in the format YYYYMMDD or YYYYMM\n";
442     }
443 
444     std::tm t;
445     std::istringstream ss(dateString);
446     ss >> std::get_time(&t, "%Y%m%d");
447     if (!ss) {
448         return entryName + " should in the format YYYYMMDD or YYYYMM\n";
449     }
450 
451     return "";
452 }
453 
isTeeDeviceInfo(const cppbor::Map & devInfo)454 bool isTeeDeviceInfo(const cppbor::Map& devInfo) {
455     return devInfo.get("security_level") && devInfo.get("security_level")->asTstr() &&
456            devInfo.get("security_level")->asTstr()->value() == "tee";
457 }
458 
parseAndValidateDeviceInfo(const std::vector<uint8_t> & deviceInfoBytes,IRemotelyProvisionedComponent * provisionable,bool isFactory)459 ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateDeviceInfo(
460         const std::vector<uint8_t>& deviceInfoBytes, IRemotelyProvisionedComponent* provisionable,
461         bool isFactory) {
462     const cppbor::Array kValidVbStates = {"green", "yellow", "orange"};
463     const cppbor::Array kValidBootloaderStates = {"locked", "unlocked"};
464     const cppbor::Array kValidSecurityLevels = {"tee", "strongbox"};
465     const cppbor::Array kValidAttIdStates = {"locked", "open"};
466     const cppbor::Array kValidFused = {0, 1};
467     constexpr std::array<std::string_view, kNumTeeDeviceInfoEntries> kDeviceInfoKeys = {
468             "brand",
469             "manufacturer",
470             "product",
471             "model",
472             "device",
473             "vb_state",
474             "bootloader_state",
475             "vbmeta_digest",
476             "os_version",
477             "system_patch_level",
478             "boot_patch_level",
479             "vendor_patch_level",
480             "security_level",
481             "fused"};
482 
483     struct AttestationIdEntry {
484         const char* id;
485         bool alwaysValidate;
486     };
487     constexpr AttestationIdEntry kAttestationIdEntrySet[] = {{"brand", false},
488                                                              {"manufacturer", true},
489                                                              {"product", false},
490                                                              {"model", false},
491                                                              {"device", false}};
492 
493     auto [parsedVerifiedDeviceInfo, ignore1, errMsg] = cppbor::parse(deviceInfoBytes);
494     if (!parsedVerifiedDeviceInfo) {
495         return errMsg;
496     }
497 
498     std::unique_ptr<cppbor::Map> parsed(parsedVerifiedDeviceInfo.release()->asMap());
499     if (!parsed) {
500         return "DeviceInfo must be a CBOR map.";
501     }
502 
503     if (parsed->clone()->asMap()->canonicalize().encode() != deviceInfoBytes) {
504         return "DeviceInfo ordering is non-canonical.";
505     }
506 
507     RpcHardwareInfo info;
508     provisionable->getHardwareInfo(&info);
509     if (info.versionNumber < 3) {
510         const std::unique_ptr<cppbor::Item>& version = parsed->get("version");
511         if (!version) {
512             return "Device info is missing version";
513         }
514         if (!version->asUint()) {
515             return "version must be an unsigned integer";
516         }
517         if (version->asUint()->value() != info.versionNumber) {
518             return "DeviceInfo version (" + std::to_string(version->asUint()->value()) +
519                    ") does not match the remotely provisioned component version (" +
520                    std::to_string(info.versionNumber) + ").";
521         }
522     }
523     // Bypasses the device info validation since the device info in AVF is currently
524     // empty. Check b/299256925 for more information.
525     //
526     // TODO(b/300911665): This check is temporary and will be replaced once the markers
527     // on the DICE chain become available. We need to determine if the CSR is from the
528     // RKP VM using the markers on the DICE chain.
529     if (info.uniqueId == "AVF Remote Provisioning 1") {
530         return std::move(parsed);
531     }
532 
533     std::string error;
534     std::string tmp;
535     std::set<std::string_view> previousKeys;
536     switch (info.versionNumber) {
537         case 3:
538             if (isTeeDeviceInfo(*parsed) && parsed->size() != kNumTeeDeviceInfoEntries) {
539                 error += fmt::format(
540                         "Err: Incorrect number of device info entries. Expected {} but got "
541                         "{}\n",
542                         kNumTeeDeviceInfoEntries, parsed->size());
543             }
544             // TEE IRPC instances require all entries to be present in DeviceInfo. Non-TEE instances
545             // may omit `os_version`
546             if (!isTeeDeviceInfo(*parsed) && (parsed->size() != kNumTeeDeviceInfoEntries &&
547                                               parsed->size() != kNumTeeDeviceInfoEntries - 1)) {
548                 error += fmt::format(
549                         "Err: Incorrect number of device info entries. Expected {} or {} but got "
550                         "{}\n",
551                         kNumTeeDeviceInfoEntries - 1, kNumTeeDeviceInfoEntries, parsed->size());
552             }
553             for (auto& [key, _] : *parsed) {
554                 const std::string& keyValue = key->asTstr()->value();
555                 if (!previousKeys.insert(keyValue).second) {
556                     error += "Err: Duplicate device info entry: <" + keyValue + ">,\n";
557                 }
558                 if (std::find(kDeviceInfoKeys.begin(), kDeviceInfoKeys.end(), keyValue) ==
559                     kDeviceInfoKeys.end()) {
560                     error += "Err: Unrecognized key entry: <" + key->asTstr()->value() + ">,\n";
561                 }
562             }
563             // Checks that only apply to v3.
564             error += checkMapPatchLevelEntry(isFactory, *parsed, "system_patch_level");
565             error += checkMapPatchLevelEntry(isFactory, *parsed, "boot_patch_level");
566             error += checkMapPatchLevelEntry(isFactory, *parsed, "vendor_patch_level");
567             FALLTHROUGH_INTENDED;
568         case 2:
569             for (const auto& entry : kAttestationIdEntrySet) {
570                 tmp = checkMapEntry(isFactory && !entry.alwaysValidate, *parsed, cppbor::TSTR,
571                                     entry.id);
572             }
573             if (!tmp.empty()) {
574                 error += tmp +
575                          "Attestation IDs are missing or malprovisioned. If this test is being\n"
576                          "run against an early proto or EVT build, this error is probably WAI\n"
577                          "and indicates that Device IDs were not provisioned in the factory. If\n"
578                          "this error is returned on a DVT or later build revision, then\n"
579                          "something is likely wrong with the factory provisioning process.";
580             }
581             // TODO: Refactor the KeyMint code that validates these fields and include it here.
582             error += checkMapEntry(isFactory, *parsed, cppbor::TSTR, "vb_state", kValidVbStates);
583             error += checkMapEntry(isFactory, *parsed, cppbor::TSTR, "bootloader_state",
584                                    kValidBootloaderStates);
585             error += checkMapEntry(isFactory, *parsed, cppbor::BSTR, "vbmeta_digest");
586             error += checkMapEntry(isFactory, *parsed, cppbor::UINT, "system_patch_level");
587             error += checkMapEntry(isFactory, *parsed, cppbor::UINT, "boot_patch_level");
588             error += checkMapEntry(isFactory, *parsed, cppbor::UINT, "vendor_patch_level");
589             error += checkMapEntry(isFactory, *parsed, cppbor::UINT, "fused", kValidFused);
590             error += checkMapEntry(isFactory, *parsed, cppbor::TSTR, "security_level",
591                                    kValidSecurityLevels);
592             if (isTeeDeviceInfo(*parsed)) {
593                 error += checkMapEntry(isFactory, *parsed, cppbor::TSTR, "os_version");
594             }
595             break;
596         case 1:
597             error += checkMapEntry(isFactory, *parsed, cppbor::TSTR, "security_level",
598                                    kValidSecurityLevels);
599             error += checkMapEntry(isFactory, *parsed, cppbor::TSTR, "att_id_state",
600                                    kValidAttIdStates);
601             break;
602         default:
603             return "Unrecognized version: " + std::to_string(info.versionNumber);
604     }
605 
606     if (!error.empty()) {
607         return error;
608     }
609 
610     return std::move(parsed);
611 }
612 
parseAndValidateFactoryDeviceInfo(const std::vector<uint8_t> & deviceInfoBytes,IRemotelyProvisionedComponent * provisionable)613 ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateFactoryDeviceInfo(
614         const std::vector<uint8_t>& deviceInfoBytes, IRemotelyProvisionedComponent* provisionable) {
615     return parseAndValidateDeviceInfo(deviceInfoBytes, provisionable, /*isFactory=*/true);
616 }
617 
parseAndValidateProductionDeviceInfo(const std::vector<uint8_t> & deviceInfoBytes,IRemotelyProvisionedComponent * provisionable)618 ErrMsgOr<std::unique_ptr<cppbor::Map>> parseAndValidateProductionDeviceInfo(
619         const std::vector<uint8_t>& deviceInfoBytes, IRemotelyProvisionedComponent* provisionable) {
620     return parseAndValidateDeviceInfo(deviceInfoBytes, provisionable, /*isFactory=*/false);
621 }
622 
getSessionKey(ErrMsgOr<std::pair<bytevec,bytevec>> & senderPubkey,const EekChain & eekChain,int32_t supportedEekCurve)623 ErrMsgOr<bytevec> getSessionKey(ErrMsgOr<std::pair<bytevec, bytevec>>& senderPubkey,
624                                 const EekChain& eekChain, int32_t supportedEekCurve) {
625     if (supportedEekCurve == RpcHardwareInfo::CURVE_25519 ||
626         supportedEekCurve == RpcHardwareInfo::CURVE_NONE) {
627         return x25519_HKDF_DeriveKey(eekChain.last_pubkey, eekChain.last_privkey,
628                                      senderPubkey->first, false /* senderIsA */);
629     } else {
630         return ECDH_HKDF_DeriveKey(eekChain.last_pubkey, eekChain.last_privkey, senderPubkey->first,
631                                    false /* senderIsA */);
632     }
633 }
634 
verifyProtectedData(const DeviceInfo & deviceInfo,const cppbor::Array & keysToSign,const std::vector<uint8_t> & keysToSignMac,const ProtectedData & protectedData,const EekChain & eekChain,const std::vector<uint8_t> & eekId,int32_t supportedEekCurve,IRemotelyProvisionedComponent * provisionable,const std::vector<uint8_t> & challenge,bool isFactory)635 ErrMsgOr<std::vector<BccEntryData>> verifyProtectedData(
636         const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign,
637         const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData,
638         const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve,
639         IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge,
640         bool isFactory) {
641     auto [parsedProtectedData, _, protDataErrMsg] = cppbor::parse(protectedData.protectedData);
642     if (!parsedProtectedData) {
643         return protDataErrMsg;
644     }
645     if (!parsedProtectedData->asArray()) {
646         return "Protected data is not a CBOR array.";
647     }
648     if (parsedProtectedData->asArray()->size() != kCoseEncryptEntryCount) {
649         return "The protected data COSE_encrypt structure must have " +
650                std::to_string(kCoseEncryptEntryCount) + " entries, but it only has " +
651                std::to_string(parsedProtectedData->asArray()->size());
652     }
653 
654     auto senderPubkey = getSenderPubKeyFromCoseEncrypt(parsedProtectedData);
655     if (!senderPubkey) {
656         return senderPubkey.message();
657     }
658     if (senderPubkey->second != eekId) {
659         return "The COSE_encrypt recipient does not match the expected EEK identifier";
660     }
661 
662     auto sessionKey = getSessionKey(senderPubkey, eekChain, supportedEekCurve);
663     if (!sessionKey) {
664         return sessionKey.message();
665     }
666 
667     auto protectedDataPayload =
668             decryptCoseEncrypt(*sessionKey, parsedProtectedData.get(), bytevec{} /* aad */);
669     if (!protectedDataPayload) {
670         return protectedDataPayload.message();
671     }
672 
673     auto [parsedPayload, __, payloadErrMsg] = cppbor::parse(*protectedDataPayload);
674     if (!parsedPayload) {
675         return "Failed to parse payload: " + payloadErrMsg;
676     }
677     if (!parsedPayload->asArray()) {
678         return "The protected data payload must be an Array.";
679     }
680     if (parsedPayload->asArray()->size() != 3U && parsedPayload->asArray()->size() != 2U) {
681         return "The protected data payload must contain SignedMAC and BCC. It may optionally "
682                "contain AdditionalDKSignatures. However, the parsed payload has " +
683                std::to_string(parsedPayload->asArray()->size()) + " entries.";
684     }
685 
686     auto& signedMac = parsedPayload->asArray()->get(0);
687     auto& bcc = parsedPayload->asArray()->get(1);
688     if (!signedMac->asArray()) {
689         return "The SignedMAC in the protected data payload is not an Array.";
690     }
691     if (!bcc->asArray()) {
692         return "The BCC in the protected data payload is not an Array.";
693     }
694 
695     // BCC is [ pubkey, + BccEntry]
696     auto bccContents = validateBcc(bcc->asArray(), hwtrust::DiceChain::Kind::kVsr13);
697     if (!bccContents) {
698         return bccContents.message() + "\n" + prettyPrint(bcc.get());
699     }
700 
701     auto deviceInfoResult =
702             parseAndValidateDeviceInfo(deviceInfo.deviceInfo, provisionable, isFactory);
703     if (!deviceInfoResult) {
704         return deviceInfoResult.message();
705     }
706     std::unique_ptr<cppbor::Map> deviceInfoMap = deviceInfoResult.moveValue();
707     auto& signingKey = bccContents->back().pubKey;
708     auto macKey = verifyAndParseCoseSign1(signedMac->asArray(), signingKey,
709                                           cppbor::Array()  // SignedMacAad
710                                                   .add(challenge)
711                                                   .add(std::move(deviceInfoMap))
712                                                   .add(keysToSignMac)
713                                                   .encode());
714     if (!macKey) {
715         return macKey.message();
716     }
717 
718     auto coseMac0 = cppbor::Array()
719                             .add(cppbor::Map()  // protected
720                                          .add(ALGORITHM, HMAC_256)
721                                          .canonicalize()
722                                          .encode())
723                             .add(cppbor::Map())        // unprotected
724                             .add(keysToSign.encode())  // payload (keysToSign)
725                             .add(keysToSignMac);       // tag
726 
727     auto macPayload = verifyAndParseCoseMac0(&coseMac0, *macKey);
728     if (!macPayload) {
729         return macPayload.message();
730     }
731 
732     return *bccContents;
733 }
734 
verifyFactoryProtectedData(const DeviceInfo & deviceInfo,const cppbor::Array & keysToSign,const std::vector<uint8_t> & keysToSignMac,const ProtectedData & protectedData,const EekChain & eekChain,const std::vector<uint8_t> & eekId,int32_t supportedEekCurve,IRemotelyProvisionedComponent * provisionable,const std::vector<uint8_t> & challenge)735 ErrMsgOr<std::vector<BccEntryData>> verifyFactoryProtectedData(
736         const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign,
737         const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData,
738         const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve,
739         IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge) {
740     return verifyProtectedData(deviceInfo, keysToSign, keysToSignMac, protectedData, eekChain,
741                                eekId, supportedEekCurve, provisionable, challenge,
742                                /*isFactory=*/true);
743 }
744 
verifyProductionProtectedData(const DeviceInfo & deviceInfo,const cppbor::Array & keysToSign,const std::vector<uint8_t> & keysToSignMac,const ProtectedData & protectedData,const EekChain & eekChain,const std::vector<uint8_t> & eekId,int32_t supportedEekCurve,IRemotelyProvisionedComponent * provisionable,const std::vector<uint8_t> & challenge)745 ErrMsgOr<std::vector<BccEntryData>> verifyProductionProtectedData(
746         const DeviceInfo& deviceInfo, const cppbor::Array& keysToSign,
747         const std::vector<uint8_t>& keysToSignMac, const ProtectedData& protectedData,
748         const EekChain& eekChain, const std::vector<uint8_t>& eekId, int32_t supportedEekCurve,
749         IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge) {
750     return verifyProtectedData(deviceInfo, keysToSign, keysToSignMac, protectedData, eekChain,
751                                eekId, supportedEekCurve, provisionable, challenge,
752                                /*isFactory=*/false);
753 }
754 
parseX509Cert(const std::vector<uint8_t> & cert)755 ErrMsgOr<X509_Ptr> parseX509Cert(const std::vector<uint8_t>& cert) {
756     CRYPTO_BUFFER_Ptr certBuf(CRYPTO_BUFFER_new(cert.data(), cert.size(), nullptr));
757     if (!certBuf.get()) {
758         return "Failed to create crypto buffer.";
759     }
760     X509_Ptr result(X509_parse_from_buffer(certBuf.get()));
761     if (!result.get()) {
762         return "Failed to parse certificate.";
763     }
764     return result;
765 }
766 
getX509IssuerName(const X509_Ptr & cert)767 std::string getX509IssuerName(const X509_Ptr& cert) {
768     char* name = X509_NAME_oneline(X509_get_issuer_name(cert.get()), nullptr, 0);
769     std::string result(name);
770     OPENSSL_free(name);
771     return result;
772 }
773 
getX509SubjectName(const X509_Ptr & cert)774 std::string getX509SubjectName(const X509_Ptr& cert) {
775     char* name = X509_NAME_oneline(X509_get_subject_name(cert.get()), nullptr, 0);
776     std::string result(name);
777     OPENSSL_free(name);
778     return result;
779 }
780 
781 // Validates the certificate chain and returns the leaf public key.
validateCertChain(const cppbor::Array & chain)782 ErrMsgOr<bytevec> validateCertChain(const cppbor::Array& chain) {
783     bytevec rawPubKey;
784     for (size_t i = 0; i < chain.size(); ++i) {
785         // Root must be self-signed.
786         size_t signingCertIndex = (i > 0) ? i - 1 : i;
787         auto& keyCertItem = chain[i];
788         auto& signingCertItem = chain[signingCertIndex];
789         if (!keyCertItem || !keyCertItem->asBstr()) {
790             return "Key certificate must be a Bstr.";
791         }
792         if (!signingCertItem || !signingCertItem->asBstr()) {
793             return "Signing certificate must be a Bstr.";
794         }
795 
796         auto keyCert = parseX509Cert(keyCertItem->asBstr()->value());
797         if (!keyCert) {
798             return keyCert.message();
799         }
800         auto signingCert = parseX509Cert(signingCertItem->asBstr()->value());
801         if (!signingCert) {
802             return signingCert.message();
803         }
804 
805         EVP_PKEY_Ptr pubKey(X509_get_pubkey(keyCert->get()));
806         if (!pubKey.get()) {
807             return "Failed to get public key.";
808         }
809         EVP_PKEY_Ptr signingPubKey(X509_get_pubkey(signingCert->get()));
810         if (!signingPubKey.get()) {
811             return "Failed to get signing public key.";
812         }
813 
814         if (!X509_verify(keyCert->get(), signingPubKey.get())) {
815             return "Verification of certificate " + std::to_string(i) +
816                    " faile. OpenSSL error string: " + ERR_error_string(ERR_get_error(), NULL);
817         }
818 
819         auto certIssuer = getX509IssuerName(*keyCert);
820         auto signerSubj = getX509SubjectName(*signingCert);
821         if (certIssuer != signerSubj) {
822             return "Certificate " + std::to_string(i) + " has wrong issuer. Signer subject is " +
823                    signerSubj + " Issuer subject is " + certIssuer;
824         }
825         if (i == chain.size() - 1) {
826             auto key = getRawPublicKey(pubKey);
827             if (!key) key.moveMessage();
828             rawPubKey = key.moveValue();
829         }
830     }
831     return rawPubKey;
832 }
833 
validateUdsCerts(const cppbor::Map & udsCerts,const bytevec & udsCoseKeyBytes)834 std::string validateUdsCerts(const cppbor::Map& udsCerts, const bytevec& udsCoseKeyBytes) {
835     for (const auto& [signerName, udsCertChain] : udsCerts) {
836         if (!signerName || !signerName->asTstr()) {
837             return "Signer Name must be a Tstr.";
838         }
839         if (!udsCertChain || !udsCertChain->asArray()) {
840             return "UDS certificate chain must be an Array.";
841         }
842         if (udsCertChain->asArray()->size() < 2) {
843             return "UDS certificate chain must have at least two entries: root and leaf.";
844         }
845 
846         auto leafPubKey = validateCertChain(*udsCertChain->asArray());
847         if (!leafPubKey) {
848             return leafPubKey.message();
849         }
850         auto coseKey = CoseKey::parse(udsCoseKeyBytes);
851         if (!coseKey) return coseKey.moveMessage();
852 
853         auto curve = coseKey->getIntValue(CoseKey::CURVE);
854         if (!curve) {
855             return "CoseKey must contain curve.";
856         }
857         bytevec udsPub;
858         if (curve == CoseKeyCurve::P256 || curve == CoseKeyCurve::P384) {
859             auto pubKey = coseKey->getEcPublicKey();
860             if (!pubKey) return pubKey.moveMessage();
861             // convert public key to uncompressed form by prepending 0x04 at begin.
862             pubKey->insert(pubKey->begin(), 0x04);
863             udsPub = pubKey.moveValue();
864         } else if (curve == CoseKeyCurve::ED25519) {
865             auto& pubkey = coseKey->getMap().get(cppcose::CoseKey::PUBKEY_X);
866             if (!pubkey || !pubkey->asBstr()) {
867                 return "Invalid public key.";
868             }
869             udsPub = pubkey->asBstr()->value();
870         } else {
871             return "Unknown curve.";
872         }
873         if (*leafPubKey != udsPub) {
874             return "Leaf public key in UDS certificate chain doesn't match UDS public key.";
875         }
876     }
877     return "";
878 }
879 
parseAndValidateCsrPayload(const cppbor::Array & keysToSign,const std::vector<uint8_t> & csrPayload,IRemotelyProvisionedComponent * provisionable,bool isFactory)880 ErrMsgOr<std::unique_ptr<cppbor::Array>> parseAndValidateCsrPayload(
881         const cppbor::Array& keysToSign, const std::vector<uint8_t>& csrPayload,
882         IRemotelyProvisionedComponent* provisionable, bool isFactory) {
883     auto [parsedCsrPayload, _, errMsg] = cppbor::parse(csrPayload);
884     if (!parsedCsrPayload) {
885         return errMsg;
886     }
887 
888     std::unique_ptr<cppbor::Array> parsed(parsedCsrPayload.release()->asArray());
889     if (!parsed) {
890         return "CSR payload is not a CBOR array.";
891     }
892 
893     if (parsed->size() != 4U) {
894         return "CSR payload must contain version, certificate type, device info, keys. "
895                "However, the parsed CSR payload has " +
896                std::to_string(parsed->size()) + " entries.";
897     }
898 
899     auto signedVersion = parsed->get(0)->asUint();
900     auto signedCertificateType = parsed->get(1)->asTstr();
901     auto signedDeviceInfo = parsed->get(2)->asMap();
902     auto signedKeys = parsed->get(3)->asArray();
903 
904     if (!signedVersion || signedVersion->value() != 3U) {
905         return "CSR payload version must be an unsigned integer and must be equal to 3.";
906     }
907     if (!signedCertificateType) {
908         // Certificate type is allowed to be extendend by vendor, i.e. we can't
909         // enforce its value.
910         return "Certificate type must be a Tstr.";
911     }
912     if (!signedDeviceInfo) {
913         return "Device info must be an Map.";
914     }
915     if (!signedKeys) {
916         return "Keys must be an Array.";
917     }
918 
919     auto result = parseAndValidateDeviceInfo(signedDeviceInfo->encode(), provisionable, isFactory);
920     if (!result) {
921         return result.message();
922     }
923 
924     if (signedKeys->encode() != keysToSign.encode()) {
925         return "Signed keys do not match.";
926     }
927 
928     return std::move(parsed);
929 }
930 
parseAndValidateAuthenticatedRequestSignedPayload(const std::vector<uint8_t> & signedPayload,const std::vector<uint8_t> & challenge)931 ErrMsgOr<bytevec> parseAndValidateAuthenticatedRequestSignedPayload(
932         const std::vector<uint8_t>& signedPayload, const std::vector<uint8_t>& challenge) {
933     auto [parsedSignedPayload, _, errMsg] = cppbor::parse(signedPayload);
934     if (!parsedSignedPayload) {
935         return errMsg;
936     }
937     if (!parsedSignedPayload->asArray()) {
938         return "SignedData payload is not a CBOR array.";
939     }
940     if (parsedSignedPayload->asArray()->size() != 2U) {
941         return "SignedData payload must contain the challenge and request. However, the parsed "
942                "SignedData payload has " +
943                std::to_string(parsedSignedPayload->asArray()->size()) + " entries.";
944     }
945 
946     auto signedChallenge = parsedSignedPayload->asArray()->get(0)->asBstr();
947     auto signedRequest = parsedSignedPayload->asArray()->get(1)->asBstr();
948 
949     if (!signedChallenge) {
950         return "Challenge must be a Bstr.";
951     }
952 
953     if (challenge.size() > 64) {
954         return "Challenge size must be between 0 and 64 bytes inclusive. "
955                "However, challenge is " +
956                std::to_string(challenge.size()) + " bytes long.";
957     }
958 
959     auto challengeBstr = cppbor::Bstr(challenge);
960     if (*signedChallenge != challengeBstr) {
961         return "Signed challenge does not match."
962                "\n  Actual: " +
963                cppbor::prettyPrint(signedChallenge->asBstr(), 64 /* maxBStrSize */) +
964                "\nExpected: " + cppbor::prettyPrint(&challengeBstr, 64 /* maxBStrSize */);
965     }
966 
967     if (!signedRequest) {
968         return "Request must be a Bstr.";
969     }
970 
971     return signedRequest->value();
972 }
973 
getDiceChainKind()974 ErrMsgOr<hwtrust::DiceChain::Kind> getDiceChainKind() {
975     int vendor_api_level = ::android::base::GetIntProperty("ro.vendor.api_level", -1);
976     switch (vendor_api_level) {
977         case __ANDROID_API_T__:
978             return hwtrust::DiceChain::Kind::kVsr13;
979         case __ANDROID_API_U__:
980             return hwtrust::DiceChain::Kind::kVsr14;
981         case 202404: /* TODO(b/315056516) Use a version macro for vendor API 24Q2 */
982             return hwtrust::DiceChain::Kind::kVsr15;
983         default:
984             return "Unsupported vendor API level: " + std::to_string(vendor_api_level);
985     }
986 }
987 
parseAndValidateAuthenticatedRequest(const std::vector<uint8_t> & request,const std::vector<uint8_t> & challenge)988 ErrMsgOr<bytevec> parseAndValidateAuthenticatedRequest(const std::vector<uint8_t>& request,
989                                                        const std::vector<uint8_t>& challenge) {
990     auto [parsedRequest, _, csrErrMsg] = cppbor::parse(request);
991     if (!parsedRequest) {
992         return csrErrMsg;
993     }
994     if (!parsedRequest->asArray()) {
995         return "AuthenticatedRequest is not a CBOR array.";
996     }
997     if (parsedRequest->asArray()->size() != 4U) {
998         return "AuthenticatedRequest must contain version, UDS certificates, DICE chain, and "
999                "signed data. However, the parsed AuthenticatedRequest has " +
1000                std::to_string(parsedRequest->asArray()->size()) + " entries.";
1001     }
1002 
1003     auto version = parsedRequest->asArray()->get(0)->asUint();
1004     auto udsCerts = parsedRequest->asArray()->get(1)->asMap();
1005     auto diceCertChain = parsedRequest->asArray()->get(2)->asArray();
1006     auto signedData = parsedRequest->asArray()->get(3)->asArray();
1007 
1008     if (!version || version->value() != 1U) {
1009         return "AuthenticatedRequest version must be an unsigned integer and must be equal to 1.";
1010     }
1011     if (!udsCerts) {
1012         return "AuthenticatedRequest UdsCerts must be an Map.";
1013     }
1014     if (!diceCertChain) {
1015         return "AuthenticatedRequest DiceCertChain must be an Array.";
1016     }
1017     if (!signedData) {
1018         return "AuthenticatedRequest SignedData must be an Array.";
1019     }
1020 
1021     // DICE chain is [ pubkey, + DiceChainEntry ].
1022     auto diceChainKind = getDiceChainKind();
1023     if (!diceChainKind) {
1024         return diceChainKind.message();
1025     }
1026 
1027     auto diceContents = validateBcc(diceCertChain, *diceChainKind);
1028     if (!diceContents) {
1029         return diceContents.message() + "\n" + prettyPrint(diceCertChain);
1030     }
1031 
1032     auto& udsPub = diceContents->back().pubKey;
1033 
1034     auto error = validateUdsCerts(*udsCerts, udsPub);
1035     if (!error.empty()) {
1036         return error;
1037     }
1038 
1039     auto signedPayload = verifyAndParseCoseSign1(signedData, udsPub, {} /* aad */);
1040     if (!signedPayload) {
1041         return signedPayload.message();
1042     }
1043 
1044     auto payload = parseAndValidateAuthenticatedRequestSignedPayload(*signedPayload, challenge);
1045     if (!payload) {
1046         return payload.message();
1047     }
1048 
1049     return payload;
1050 }
1051 
verifyCsr(const cppbor::Array & keysToSign,const std::vector<uint8_t> & csr,IRemotelyProvisionedComponent * provisionable,const std::vector<uint8_t> & challenge,bool isFactory)1052 ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyCsr(const cppbor::Array& keysToSign,
1053                                                    const std::vector<uint8_t>& csr,
1054                                                    IRemotelyProvisionedComponent* provisionable,
1055                                                    const std::vector<uint8_t>& challenge,
1056                                                    bool isFactory) {
1057     RpcHardwareInfo info;
1058     provisionable->getHardwareInfo(&info);
1059     if (info.versionNumber != 3) {
1060         return "Remotely provisioned component version (" + std::to_string(info.versionNumber) +
1061                ") does not match expected version (3).";
1062     }
1063 
1064     auto csrPayload = parseAndValidateAuthenticatedRequest(csr, challenge);
1065     if (!csrPayload) {
1066         return csrPayload.message();
1067     }
1068 
1069     return parseAndValidateCsrPayload(keysToSign, *csrPayload, provisionable, isFactory);
1070 }
1071 
verifyFactoryCsr(const cppbor::Array & keysToSign,const std::vector<uint8_t> & csr,IRemotelyProvisionedComponent * provisionable,const std::vector<uint8_t> & challenge)1072 ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyFactoryCsr(
1073         const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr,
1074         IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge) {
1075     return verifyCsr(keysToSign, csr, provisionable, challenge, /*isFactory=*/true);
1076 }
1077 
verifyProductionCsr(const cppbor::Array & keysToSign,const std::vector<uint8_t> & csr,IRemotelyProvisionedComponent * provisionable,const std::vector<uint8_t> & challenge)1078 ErrMsgOr<std::unique_ptr<cppbor::Array>> verifyProductionCsr(
1079         const cppbor::Array& keysToSign, const std::vector<uint8_t>& csr,
1080         IRemotelyProvisionedComponent* provisionable, const std::vector<uint8_t>& challenge) {
1081     return verifyCsr(keysToSign, csr, provisionable, challenge, /*isFactory=*/false);
1082 }
1083 
isCsrWithProperDiceChain(const std::vector<uint8_t> & csr)1084 ErrMsgOr<bool> isCsrWithProperDiceChain(const std::vector<uint8_t>& csr) {
1085     auto [parsedRequest, _, csrErrMsg] = cppbor::parse(csr);
1086     if (!parsedRequest) {
1087         return csrErrMsg;
1088     }
1089     if (!parsedRequest->asArray()) {
1090         return "AuthenticatedRequest is not a CBOR array.";
1091     }
1092     if (parsedRequest->asArray()->size() != 4U) {
1093         return "AuthenticatedRequest must contain version, UDS certificates, DICE chain, and "
1094                "signed data. However, the parsed AuthenticatedRequest has " +
1095                std::to_string(parsedRequest->asArray()->size()) + " entries.";
1096     }
1097 
1098     auto version = parsedRequest->asArray()->get(0)->asUint();
1099     auto diceCertChain = parsedRequest->asArray()->get(2)->asArray();
1100 
1101     if (!version || version->value() != 1U) {
1102         return "AuthenticatedRequest version must be an unsigned integer and must be equal to 1.";
1103     }
1104     if (!diceCertChain) {
1105         return "AuthenticatedRequest DiceCertChain must be an Array.";
1106     }
1107 
1108     // DICE chain is [ pubkey, + DiceChainEntry ].
1109     auto diceChainKind = getDiceChainKind();
1110     if (!diceChainKind) {
1111         return diceChainKind.message();
1112     }
1113 
1114     auto encodedDiceChain = diceCertChain->encode();
1115     auto chain = hwtrust::DiceChain::Verify(encodedDiceChain, *diceChainKind);
1116     if (!chain.ok()) return chain.error().message();
1117     return chain->IsProper();
1118 }
1119 
1120 }  // namespace aidl::android::hardware::security::keymint::remote_prov
1121