1 /*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <memory>
18 #include <string>
19 #define LOG_TAG "VtsRemotelyProvisionableComponentTests"
20
21 #include <aidl/android/hardware/security/keymint/BnRemotelyProvisionedComponent.h>
22 #include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
23 #include <aidl/android/hardware/security/keymint/SecurityLevel.h>
24 #include <android/binder_manager.h>
25 #include <binder/IServiceManager.h>
26 #include <cppbor.h>
27 #include <cppbor_parse.h>
28 #include <gmock/gmock.h>
29 #include <keymaster/cppcose/cppcose.h>
30 #include <keymaster/keymaster_configuration.h>
31 #include <keymint_support/authorization_set.h>
32 #include <openssl/ec.h>
33 #include <openssl/ec_key.h>
34 #include <openssl/x509.h>
35 #include <remote_prov/remote_prov_utils.h>
36 #include <optional>
37 #include <set>
38 #include <string_view>
39 #include <vector>
40
41 #include "KeyMintAidlTestBase.h"
42
43 namespace aidl::android::hardware::security::keymint::test {
44
45 using ::std::string;
46 using ::std::vector;
47
48 namespace {
49
50 constexpr int32_t VERSION_WITH_UNIQUE_ID_SUPPORT = 2;
51
52 constexpr int32_t VERSION_WITHOUT_EEK = 3;
53 constexpr int32_t VERSION_WITHOUT_TEST_MODE = 3;
54 constexpr int32_t VERSION_WITH_CERTIFICATE_REQUEST_V2 = 3;
55 constexpr int32_t VERSION_WITH_SUPPORTED_NUM_KEYS_IN_CSR = 3;
56
57 constexpr uint8_t MIN_CHALLENGE_SIZE = 0;
58 constexpr uint8_t MAX_CHALLENGE_SIZE = 64;
59
60 const string KEYMINT_STRONGBOX_INSTANCE_NAME =
61 "android.hardware.security.keymint.IKeyMintDevice/strongbox";
62
63 #define INSTANTIATE_REM_PROV_AIDL_TEST(name) \
64 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(name); \
65 INSTANTIATE_TEST_SUITE_P( \
66 PerInstance, name, \
67 testing::ValuesIn(VtsRemotelyProvisionedComponentTests::build_params()), \
68 ::android::PrintInstanceNameToString)
69
70 using ::android::sp;
71 using bytevec = std::vector<uint8_t>;
72 using testing::MatchesRegex;
73 using namespace remote_prov;
74 using namespace keymaster;
75
string_to_bytevec(const char * s)76 bytevec string_to_bytevec(const char* s) {
77 const uint8_t* p = reinterpret_cast<const uint8_t*>(s);
78 return bytevec(p, p + strlen(s));
79 }
80
corrupt_maced_key(const MacedPublicKey & macedPubKey)81 ErrMsgOr<MacedPublicKey> corrupt_maced_key(const MacedPublicKey& macedPubKey) {
82 auto [coseMac0, _, mac0ParseErr] = cppbor::parse(macedPubKey.macedKey);
83 if (!coseMac0 || coseMac0->asArray()->size() != kCoseMac0EntryCount) {
84 return "COSE Mac0 parse failed";
85 }
86 auto protParams = coseMac0->asArray()->get(kCoseMac0ProtectedParams)->asBstr();
87 auto unprotParams = coseMac0->asArray()->get(kCoseMac0UnprotectedParams)->asMap();
88 auto payload = coseMac0->asArray()->get(kCoseMac0Payload)->asBstr();
89 auto tag = coseMac0->asArray()->get(kCoseMac0Tag)->asBstr();
90 if (!protParams || !unprotParams || !payload || !tag) {
91 return "Invalid COSE_Sign1: missing content";
92 }
93 auto corruptMac0 = cppbor::Array();
94 corruptMac0.add(protParams->clone());
95 corruptMac0.add(unprotParams->clone());
96 corruptMac0.add(payload->clone());
97 vector<uint8_t> tagData = tag->value();
98 tagData[0] ^= 0x08;
99 tagData[tagData.size() - 1] ^= 0x80;
100 corruptMac0.add(cppbor::Bstr(tagData));
101
102 return MacedPublicKey{corruptMac0.encode()};
103 }
104
corrupt_sig(const cppbor::Array * coseSign1)105 ErrMsgOr<cppbor::Array> corrupt_sig(const cppbor::Array* coseSign1) {
106 if (coseSign1->size() != kCoseSign1EntryCount) {
107 return "Invalid COSE_Sign1, wrong entry count";
108 }
109 const cppbor::Bstr* protectedParams = coseSign1->get(kCoseSign1ProtectedParams)->asBstr();
110 const cppbor::Map* unprotectedParams = coseSign1->get(kCoseSign1UnprotectedParams)->asMap();
111 const cppbor::Bstr* payload = coseSign1->get(kCoseSign1Payload)->asBstr();
112 const cppbor::Bstr* signature = coseSign1->get(kCoseSign1Signature)->asBstr();
113 if (!protectedParams || !unprotectedParams || !payload || !signature) {
114 return "Invalid COSE_Sign1: missing content";
115 }
116
117 auto corruptSig = cppbor::Array();
118 corruptSig.add(protectedParams->clone());
119 corruptSig.add(unprotectedParams->clone());
120 corruptSig.add(payload->clone());
121 vector<uint8_t> sigData = signature->value();
122 sigData[0] ^= 0x08;
123 corruptSig.add(cppbor::Bstr(sigData));
124
125 return std::move(corruptSig);
126 }
127
corrupt_sig_chain(const bytevec & encodedEekChain,int which)128 ErrMsgOr<bytevec> corrupt_sig_chain(const bytevec& encodedEekChain, int which) {
129 auto [chain, _, parseErr] = cppbor::parse(encodedEekChain);
130 if (!chain || !chain->asArray()) {
131 return "EekChain parse failed";
132 }
133
134 cppbor::Array* eekChain = chain->asArray();
135 if (which >= eekChain->size()) {
136 return "selected sig out of range";
137 }
138 auto corruptChain = cppbor::Array();
139
140 for (int ii = 0; ii < eekChain->size(); ++ii) {
141 if (ii == which) {
142 auto sig = corrupt_sig(eekChain->get(which)->asArray());
143 if (!sig) {
144 return "Failed to build corrupted signature" + sig.moveMessage();
145 }
146 corruptChain.add(sig.moveValue());
147 } else {
148 corruptChain.add(eekChain->get(ii)->clone());
149 }
150 }
151 return corruptChain.encode();
152 }
153
matching_keymint_device(const string & rp_name,std::shared_ptr<IKeyMintDevice> * keyMint)154 bool matching_keymint_device(const string& rp_name, std::shared_ptr<IKeyMintDevice>* keyMint) {
155 auto rp_suffix = deviceSuffix(rp_name);
156
157 vector<string> km_names = ::android::getAidlHalInstanceNames(IKeyMintDevice::descriptor);
158 for (const string& km_name : km_names) {
159 // If the suffix of the KeyMint instance equals the suffix of the
160 // RemotelyProvisionedComponent instance, assume they match.
161 if (deviceSuffix(km_name) == rp_suffix && AServiceManager_isDeclared(km_name.c_str())) {
162 ::ndk::SpAIBinder binder(AServiceManager_waitForService(km_name.c_str()));
163 *keyMint = IKeyMintDevice::fromBinder(binder);
164 return true;
165 }
166 }
167 return false;
168 }
169
170 } // namespace
171
172 class VtsRemotelyProvisionedComponentTests : public testing::TestWithParam<std::string> {
173 public:
SetUp()174 virtual void SetUp() override {
175 if (AServiceManager_isDeclared(GetParam().c_str())) {
176 ::ndk::SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str()));
177 provisionable_ = IRemotelyProvisionedComponent::fromBinder(binder);
178 }
179 ASSERT_NE(provisionable_, nullptr);
180 auto status = provisionable_->getHardwareInfo(&rpcHardwareInfo);
181 isRkpVmInstance_ = GetParam() == RKPVM_INSTANCE_NAME;
182 if (isRkpVmInstance_) {
183 if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
184 GTEST_SKIP() << "The RKP VM is not supported on this system.";
185 }
186 int apiLevel = get_vsr_api_level();
187 if (apiLevel < __ANDROID_API_V__) {
188 GTEST_SKIP() << "The RKP VM is supported only on V+ devices. Vendor API level: "
189 << apiLevel;
190 }
191 }
192 ASSERT_TRUE(status.isOk());
193 }
194
build_params()195 static vector<string> build_params() {
196 auto params = ::android::getAidlHalInstanceNames(IRemotelyProvisionedComponent::descriptor);
197 return params;
198 }
199
200 protected:
201 std::shared_ptr<IRemotelyProvisionedComponent> provisionable_;
202 RpcHardwareInfo rpcHardwareInfo;
203 bool isRkpVmInstance_;
204 };
205
206 /**
207 * Verify that every implementation reports a different unique id.
208 */
TEST(NonParameterizedTests,eachRpcHasAUniqueId)209 TEST(NonParameterizedTests, eachRpcHasAUniqueId) {
210 std::set<std::string> uniqueIds;
211 for (auto hal : ::android::getAidlHalInstanceNames(IRemotelyProvisionedComponent::descriptor)) {
212 ASSERT_TRUE(AServiceManager_isDeclared(hal.c_str()));
213 ::ndk::SpAIBinder binder(AServiceManager_waitForService(hal.c_str()));
214 std::shared_ptr<IRemotelyProvisionedComponent> rpc =
215 IRemotelyProvisionedComponent::fromBinder(binder);
216 ASSERT_NE(rpc, nullptr);
217
218 RpcHardwareInfo hwInfo;
219 auto status = rpc->getHardwareInfo(&hwInfo);
220 if (hal == RKPVM_INSTANCE_NAME && status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
221 GTEST_SKIP() << "The RKP VM is not supported on this system.";
222 }
223 ASSERT_TRUE(status.isOk());
224
225 if (hwInfo.versionNumber >= VERSION_WITH_UNIQUE_ID_SUPPORT) {
226 ASSERT_TRUE(hwInfo.uniqueId);
227 auto [_, wasInserted] = uniqueIds.insert(*hwInfo.uniqueId);
228 EXPECT_TRUE(wasInserted);
229 } else {
230 ASSERT_FALSE(hwInfo.uniqueId);
231 }
232 }
233 }
234
235 /**
236 * Verify that the default implementation supports DICE if there is a StrongBox KeyMint instance
237 * on the device.
238 */
239 // @VsrTest = 3.10-015
TEST(NonParameterizedTests,requireDiceOnDefaultInstanceIfStrongboxPresent)240 TEST(NonParameterizedTests, requireDiceOnDefaultInstanceIfStrongboxPresent) {
241 int vsr_api_level = get_vsr_api_level();
242 if (vsr_api_level < 35) {
243 GTEST_SKIP() << "Applies only to VSR API level 35 or newer, this device is: "
244 << vsr_api_level;
245 }
246
247 if (!AServiceManager_isDeclared(KEYMINT_STRONGBOX_INSTANCE_NAME.c_str())) {
248 GTEST_SKIP() << "Strongbox is not present on this device.";
249 }
250
251 ::ndk::SpAIBinder binder(AServiceManager_waitForService(DEFAULT_INSTANCE_NAME.c_str()));
252 std::shared_ptr<IRemotelyProvisionedComponent> rpc =
253 IRemotelyProvisionedComponent::fromBinder(binder);
254 ASSERT_NE(rpc, nullptr);
255
256 bytevec challenge = randomBytes(64);
257 bytevec csr;
258 auto status = rpc->generateCertificateRequestV2({} /* keysToSign */, challenge, &csr);
259 EXPECT_TRUE(status.isOk()) << status.getDescription();
260
261 auto result = isCsrWithProperDiceChain(csr, DEFAULT_INSTANCE_NAME);
262 ASSERT_TRUE(result) << result.message();
263 ASSERT_TRUE(*result);
264 }
265
266 using GetHardwareInfoTests = VtsRemotelyProvisionedComponentTests;
267
268 INSTANTIATE_REM_PROV_AIDL_TEST(GetHardwareInfoTests);
269
270 /**
271 * Verify that a valid curve is reported by the implementation.
272 */
TEST_P(GetHardwareInfoTests,supportsValidCurve)273 TEST_P(GetHardwareInfoTests, supportsValidCurve) {
274 RpcHardwareInfo hwInfo;
275 ASSERT_TRUE(provisionable_->getHardwareInfo(&hwInfo).isOk());
276
277 if (rpcHardwareInfo.versionNumber >= VERSION_WITHOUT_EEK) {
278 ASSERT_EQ(hwInfo.supportedEekCurve, RpcHardwareInfo::CURVE_NONE)
279 << "Invalid curve: " << hwInfo.supportedEekCurve;
280 return;
281 }
282
283 const std::set<int> validCurves = {RpcHardwareInfo::CURVE_P256, RpcHardwareInfo::CURVE_25519};
284 ASSERT_EQ(validCurves.count(hwInfo.supportedEekCurve), 1)
285 << "Invalid curve: " << hwInfo.supportedEekCurve;
286 }
287
288 /**
289 * Verify that the unique id is within the length limits as described in RpcHardwareInfo.aidl.
290 */
TEST_P(GetHardwareInfoTests,uniqueId)291 TEST_P(GetHardwareInfoTests, uniqueId) {
292 if (rpcHardwareInfo.versionNumber < VERSION_WITH_UNIQUE_ID_SUPPORT) {
293 return;
294 }
295
296 RpcHardwareInfo hwInfo;
297 ASSERT_TRUE(provisionable_->getHardwareInfo(&hwInfo).isOk());
298 ASSERT_TRUE(hwInfo.uniqueId);
299 EXPECT_GE(hwInfo.uniqueId->size(), 1);
300 EXPECT_LE(hwInfo.uniqueId->size(), 32);
301 }
302
303 /**
304 * Verify implementation supports at least MIN_SUPPORTED_NUM_KEYS_IN_CSR keys in a CSR.
305 */
TEST_P(GetHardwareInfoTests,supportedNumKeysInCsr)306 TEST_P(GetHardwareInfoTests, supportedNumKeysInCsr) {
307 if (rpcHardwareInfo.versionNumber < VERSION_WITH_SUPPORTED_NUM_KEYS_IN_CSR) {
308 return;
309 }
310
311 RpcHardwareInfo hwInfo;
312 ASSERT_TRUE(provisionable_->getHardwareInfo(&hwInfo).isOk());
313 ASSERT_GE(hwInfo.supportedNumKeysInCsr, RpcHardwareInfo::MIN_SUPPORTED_NUM_KEYS_IN_CSR);
314 }
315
316 using GenerateKeyTests = VtsRemotelyProvisionedComponentTests;
317
318 INSTANTIATE_REM_PROV_AIDL_TEST(GenerateKeyTests);
319
320 /**
321 * Generate and validate a production-mode key. MAC tag can't be verified, but
322 * the private key blob should be usable in KeyMint operations.
323 */
TEST_P(GenerateKeyTests,generateEcdsaP256Key_prodMode)324 TEST_P(GenerateKeyTests, generateEcdsaP256Key_prodMode) {
325 MacedPublicKey macedPubKey;
326 bytevec privateKeyBlob;
327 bool testMode = false;
328 auto status = provisionable_->generateEcdsaP256KeyPair(testMode, &macedPubKey, &privateKeyBlob);
329 ASSERT_TRUE(status.isOk());
330 vector<uint8_t> coseKeyData;
331 check_maced_pubkey(macedPubKey, testMode, &coseKeyData);
332 }
333
334 /**
335 * Generate and validate a production-mode key, then use it as a KeyMint attestation key.
336 */
TEST_P(GenerateKeyTests,generateAndUseEcdsaP256Key_prodMode)337 TEST_P(GenerateKeyTests, generateAndUseEcdsaP256Key_prodMode) {
338 // See if there is a matching IKeyMintDevice for this IRemotelyProvisionedComponent.
339 std::shared_ptr<IKeyMintDevice> keyMint;
340 if (!matching_keymint_device(GetParam(), &keyMint)) {
341 // No matching IKeyMintDevice.
342 GTEST_SKIP() << "Skipping key use test as no matching KeyMint device found";
343 return;
344 }
345 KeyMintHardwareInfo info;
346 ASSERT_TRUE(keyMint->getHardwareInfo(&info).isOk());
347
348 MacedPublicKey macedPubKey;
349 bytevec privateKeyBlob;
350 bool testMode = false;
351 auto status = provisionable_->generateEcdsaP256KeyPair(testMode, &macedPubKey, &privateKeyBlob);
352 ASSERT_TRUE(status.isOk());
353 vector<uint8_t> coseKeyData;
354 check_maced_pubkey(macedPubKey, testMode, &coseKeyData);
355
356 AttestationKey attestKey;
357 attestKey.keyBlob = std::move(privateKeyBlob);
358 attestKey.issuerSubjectName = make_name_from_str("Android Keystore Key");
359
360 // Generate an ECDSA key that is attested by the generated P256 keypair.
361 AuthorizationSet keyDesc = AuthorizationSetBuilder()
362 .Authorization(TAG_NO_AUTH_REQUIRED)
363 .EcdsaSigningKey(EcCurve::P_256)
364 .AttestationChallenge("foo")
365 .AttestationApplicationId("bar")
366 .Digest(Digest::NONE)
367 .SetDefaultValidity();
368 KeyCreationResult creationResult;
369 auto result = keyMint->generateKey(keyDesc.vector_data(), attestKey, &creationResult);
370 ASSERT_TRUE(result.isOk());
371 vector<uint8_t> attested_key_blob = std::move(creationResult.keyBlob);
372 vector<KeyCharacteristics> attested_key_characteristics =
373 std::move(creationResult.keyCharacteristics);
374 vector<Certificate> attested_key_cert_chain = std::move(creationResult.certificateChain);
375 EXPECT_EQ(attested_key_cert_chain.size(), 1);
376
377 int32_t aidl_version = 0;
378 ASSERT_TRUE(keyMint->getInterfaceVersion(&aidl_version).isOk());
379 AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
380 AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
381 EXPECT_TRUE(verify_attestation_record(aidl_version, "foo", "bar", sw_enforced, hw_enforced,
382 info.securityLevel,
383 attested_key_cert_chain[0].encodedCertificate));
384
385 // Attestation by itself is not valid (last entry is not self-signed).
386 EXPECT_FALSE(ChainSignaturesAreValid(attested_key_cert_chain));
387
388 // The signature over the attested key should correspond to the P256 public key.
389 X509_Ptr key_cert(parse_cert_blob(attested_key_cert_chain[0].encodedCertificate));
390 ASSERT_TRUE(key_cert.get());
391 EVP_PKEY_Ptr signing_pubkey;
392 p256_pub_key(coseKeyData, &signing_pubkey);
393 ASSERT_TRUE(signing_pubkey.get());
394
395 ASSERT_TRUE(X509_verify(key_cert.get(), signing_pubkey.get()))
396 << "Verification of attested certificate failed "
397 << "OpenSSL error string: " << ERR_error_string(ERR_get_error(), NULL);
398 }
399
400 /**
401 * Generate and validate a test-mode key.
402 */
TEST_P(GenerateKeyTests,generateEcdsaP256Key_testMode)403 TEST_P(GenerateKeyTests, generateEcdsaP256Key_testMode) {
404 MacedPublicKey macedPubKey;
405 bytevec privateKeyBlob;
406 bool testMode = true;
407 auto status = provisionable_->generateEcdsaP256KeyPair(testMode, &macedPubKey, &privateKeyBlob);
408
409 if (rpcHardwareInfo.versionNumber >= VERSION_WITHOUT_TEST_MODE) {
410 ASSERT_FALSE(status.isOk());
411 EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_REMOVED);
412 return;
413 }
414
415 ASSERT_TRUE(status.isOk());
416 check_maced_pubkey(macedPubKey, testMode, nullptr);
417 }
418
419 /**
420 * Generate and validate at most 2**16 production-mode keys. This aims to catch issues that do not
421 * deterministically show up. In practice, this will test far fewer keys, but a certain number are
422 * tested at a minimum.
423 */
TEST_P(GenerateKeyTests,generateManyEcdsaP256KeysInProdMode)424 TEST_P(GenerateKeyTests, generateManyEcdsaP256KeysInProdMode) {
425 const auto start = std::chrono::steady_clock::now();
426 const auto time_bound = std::chrono::seconds(5);
427 const auto upper_bound = 1 << 16;
428 const auto lower_bound = 1 << 8;
429 for (auto iteration = 0; iteration < upper_bound; iteration++) {
430 MacedPublicKey macedPubKey;
431 bytevec privateKeyBlob;
432 bool testMode = false;
433 auto status =
434 provisionable_->generateEcdsaP256KeyPair(testMode, &macedPubKey, &privateKeyBlob);
435 ASSERT_TRUE(status.isOk());
436 vector<uint8_t> coseKeyData;
437 check_maced_pubkey(macedPubKey, testMode, &coseKeyData);
438 const auto current_time = std::chrono::steady_clock::now() - start;
439 if (iteration >= lower_bound && current_time >= time_bound) {
440 break;
441 }
442 }
443 }
444
445 class CertificateRequestTestBase : public VtsRemotelyProvisionedComponentTests {
446 protected:
CertificateRequestTestBase()447 CertificateRequestTestBase()
448 : eekId_(string_to_bytevec("eekid")), challenge_(randomBytes(64)) {}
449
generateTestEekChain(size_t eekLength)450 void generateTestEekChain(size_t eekLength) {
451 auto chain = generateEekChain(rpcHardwareInfo.supportedEekCurve, eekLength, eekId_);
452 ASSERT_TRUE(chain) << chain.message();
453 if (chain) testEekChain_ = chain.moveValue();
454 testEekLength_ = eekLength;
455 }
456
generateKeys(bool testMode,size_t numKeys)457 void generateKeys(bool testMode, size_t numKeys) {
458 keysToSign_ = std::vector<MacedPublicKey>(numKeys);
459 cborKeysToSign_ = cppbor::Array();
460
461 for (auto& key : keysToSign_) {
462 bytevec privateKeyBlob;
463 auto status = provisionable_->generateEcdsaP256KeyPair(testMode, &key, &privateKeyBlob);
464 ASSERT_TRUE(status.isOk()) << status.getDescription();
465
466 vector<uint8_t> payload_value;
467 check_maced_pubkey(key, testMode, &payload_value);
468 cborKeysToSign_.add(cppbor::EncodedItem(payload_value));
469 }
470 }
471
472 bytevec eekId_;
473 size_t testEekLength_;
474 EekChain testEekChain_;
475 bytevec challenge_;
476 std::vector<MacedPublicKey> keysToSign_;
477 cppbor::Array cborKeysToSign_;
478 };
479
480 class CertificateRequestTest : public CertificateRequestTestBase {
481 protected:
SetUp()482 void SetUp() override {
483 CertificateRequestTestBase::SetUp();
484 ASSERT_FALSE(HasFatalFailure());
485
486 if (rpcHardwareInfo.versionNumber >= VERSION_WITH_CERTIFICATE_REQUEST_V2) {
487 GTEST_SKIP() << "This test case only applies to RKP v1 and v2. "
488 << "RKP version discovered: " << rpcHardwareInfo.versionNumber;
489 }
490 }
491 };
492
493 /**
494 * Generate an empty certificate request in test mode, and decrypt and verify the structure and
495 * content.
496 */
TEST_P(CertificateRequestTest,EmptyRequest_testMode)497 TEST_P(CertificateRequestTest, EmptyRequest_testMode) {
498 bool testMode = true;
499 for (size_t eekLength : {2, 3, 7}) {
500 SCOPED_TRACE(testing::Message() << "EEK of length " << eekLength);
501 generateTestEekChain(eekLength);
502
503 bytevec keysToSignMac;
504 DeviceInfo deviceInfo;
505 ProtectedData protectedData;
506 auto status = provisionable_->generateCertificateRequest(
507 testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
508 &protectedData, &keysToSignMac);
509 ASSERT_TRUE(status.isOk()) << status.getDescription();
510
511 auto result = verifyProductionProtectedData(deviceInfo, cppbor::Array(), keysToSignMac,
512 protectedData, testEekChain_, eekId_,
513 rpcHardwareInfo, GetParam(), challenge_);
514 ASSERT_TRUE(result) << result.message();
515 }
516 }
517
518 /**
519 * Ensure that test mode outputs a unique BCC root key every time we request a
520 * certificate request. Else, it's possible that the test mode API could be used
521 * to fingerprint devices. Only the GEEK should be allowed to decrypt the same
522 * device public key multiple times.
523 */
TEST_P(CertificateRequestTest,NewKeyPerCallInTestMode)524 TEST_P(CertificateRequestTest, NewKeyPerCallInTestMode) {
525 constexpr bool testMode = true;
526
527 bytevec keysToSignMac;
528 DeviceInfo deviceInfo;
529 ProtectedData protectedData;
530 generateTestEekChain(3);
531 auto status = provisionable_->generateCertificateRequest(
532 testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
533 &protectedData, &keysToSignMac);
534 ASSERT_TRUE(status.isOk()) << status.getDescription();
535
536 auto firstBcc = verifyProductionProtectedData(deviceInfo, /*keysToSign=*/cppbor::Array(),
537 keysToSignMac, protectedData, testEekChain_,
538 eekId_, rpcHardwareInfo, GetParam(), challenge_);
539 ASSERT_TRUE(firstBcc) << firstBcc.message();
540
541 status = provisionable_->generateCertificateRequest(
542 testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
543 &protectedData, &keysToSignMac);
544 ASSERT_TRUE(status.isOk()) << status.getDescription();
545
546 auto secondBcc = verifyProductionProtectedData(deviceInfo, /*keysToSign=*/cppbor::Array(),
547 keysToSignMac, protectedData, testEekChain_,
548 eekId_, rpcHardwareInfo, GetParam(), challenge_);
549 ASSERT_TRUE(secondBcc) << secondBcc.message();
550
551 // Verify that none of the keys in the first BCC are repeated in the second one.
552 for (const auto& i : *firstBcc) {
553 for (auto& j : *secondBcc) {
554 ASSERT_THAT(i.pubKey, testing::Not(testing::ElementsAreArray(j.pubKey)))
555 << "Found a repeated pubkey in two generateCertificateRequest test mode calls";
556 }
557 }
558 }
559
560 /**
561 * Generate an empty certificate request in prod mode. This test must be run explicitly, and
562 * is not run by default. Not all devices are GMS devices, and therefore they do not all
563 * trust the Google EEK root.
564 */
TEST_P(CertificateRequestTest,DISABLED_EmptyRequest_prodMode)565 TEST_P(CertificateRequestTest, DISABLED_EmptyRequest_prodMode) {
566 bool testMode = false;
567
568 bytevec keysToSignMac;
569 DeviceInfo deviceInfo;
570 ProtectedData protectedData;
571 auto status = provisionable_->generateCertificateRequest(
572 testMode, {} /* keysToSign */, getProdEekChain(rpcHardwareInfo.supportedEekCurve),
573 challenge_, &deviceInfo, &protectedData, &keysToSignMac);
574 EXPECT_TRUE(status.isOk());
575 }
576
577 /**
578 * Generate a non-empty certificate request in test mode. Decrypt, parse and validate the contents.
579 */
TEST_P(CertificateRequestTest,NonEmptyRequest_testMode)580 TEST_P(CertificateRequestTest, NonEmptyRequest_testMode) {
581 bool testMode = true;
582 generateKeys(testMode, 4 /* numKeys */);
583
584 for (size_t eekLength : {2, 3, 7}) {
585 SCOPED_TRACE(testing::Message() << "EEK of length " << eekLength);
586 generateTestEekChain(eekLength);
587
588 bytevec keysToSignMac;
589 DeviceInfo deviceInfo;
590 ProtectedData protectedData;
591 auto status = provisionable_->generateCertificateRequest(
592 testMode, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo, &protectedData,
593 &keysToSignMac);
594 ASSERT_TRUE(status.isOk()) << status.getDescription();
595
596 auto result = verifyProductionProtectedData(deviceInfo, cborKeysToSign_, keysToSignMac,
597 protectedData, testEekChain_, eekId_,
598 rpcHardwareInfo, GetParam(), challenge_);
599 ASSERT_TRUE(result) << result.message();
600 }
601 }
602
603 /**
604 * Generate a non-empty certificate request in prod mode. This test must be run explicitly, and
605 * is not run by default. Not all devices are GMS devices, and therefore they do not all
606 * trust the Google EEK root.
607 */
TEST_P(CertificateRequestTest,DISABLED_NonEmptyRequest_prodMode)608 TEST_P(CertificateRequestTest, DISABLED_NonEmptyRequest_prodMode) {
609 bool testMode = false;
610 generateKeys(testMode, 4 /* numKeys */);
611
612 bytevec keysToSignMac;
613 DeviceInfo deviceInfo;
614 ProtectedData protectedData;
615 auto status = provisionable_->generateCertificateRequest(
616 testMode, keysToSign_, getProdEekChain(rpcHardwareInfo.supportedEekCurve), challenge_,
617 &deviceInfo, &protectedData, &keysToSignMac);
618 EXPECT_TRUE(status.isOk());
619 }
620
621 /**
622 * Generate a non-empty certificate request in test mode, but with the MAC corrupted on the keypair.
623 */
TEST_P(CertificateRequestTest,NonEmptyRequestCorruptMac_testMode)624 TEST_P(CertificateRequestTest, NonEmptyRequestCorruptMac_testMode) {
625 bool testMode = true;
626 generateKeys(testMode, 1 /* numKeys */);
627 auto result = corrupt_maced_key(keysToSign_[0]);
628 ASSERT_TRUE(result) << result.moveMessage();
629 MacedPublicKey keyWithCorruptMac = result.moveValue();
630
631 bytevec keysToSignMac;
632 DeviceInfo deviceInfo;
633 ProtectedData protectedData;
634 generateTestEekChain(3);
635 auto status = provisionable_->generateCertificateRequest(
636 testMode, {keyWithCorruptMac}, testEekChain_.chain, challenge_, &deviceInfo,
637 &protectedData, &keysToSignMac);
638 ASSERT_FALSE(status.isOk()) << status.getDescription();
639 EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
640 }
641
642 /**
643 * Generate a non-empty certificate request in prod mode, but with the MAC corrupted on the keypair.
644 */
TEST_P(CertificateRequestTest,NonEmptyRequestCorruptMac_prodMode)645 TEST_P(CertificateRequestTest, NonEmptyRequestCorruptMac_prodMode) {
646 bool testMode = false;
647 generateKeys(testMode, 1 /* numKeys */);
648 auto result = corrupt_maced_key(keysToSign_[0]);
649 ASSERT_TRUE(result) << result.moveMessage();
650 MacedPublicKey keyWithCorruptMac = result.moveValue();
651
652 bytevec keysToSignMac;
653 DeviceInfo deviceInfo;
654 ProtectedData protectedData;
655 auto status = provisionable_->generateCertificateRequest(
656 testMode, {keyWithCorruptMac}, getProdEekChain(rpcHardwareInfo.supportedEekCurve),
657 challenge_, &deviceInfo, &protectedData, &keysToSignMac);
658 ASSERT_FALSE(status.isOk()) << status.getDescription();
659 EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
660 }
661
662 /**
663 * Generate a non-empty certificate request in prod mode that has a corrupt EEK chain.
664 * Confirm that the request is rejected.
665 */
TEST_P(CertificateRequestTest,NonEmptyCorruptEekRequest_prodMode)666 TEST_P(CertificateRequestTest, NonEmptyCorruptEekRequest_prodMode) {
667 bool testMode = false;
668 generateKeys(testMode, 4 /* numKeys */);
669
670 auto prodEekChain = getProdEekChain(rpcHardwareInfo.supportedEekCurve);
671 auto [parsedChain, _, parseErr] = cppbor::parse(prodEekChain);
672 ASSERT_NE(parsedChain, nullptr) << parseErr;
673 ASSERT_NE(parsedChain->asArray(), nullptr);
674
675 for (int ii = 0; ii < parsedChain->asArray()->size(); ++ii) {
676 auto chain = corrupt_sig_chain(prodEekChain, ii);
677 ASSERT_TRUE(chain) << chain.message();
678
679 bytevec keysToSignMac;
680 DeviceInfo deviceInfo;
681 ProtectedData protectedData;
682 auto status = provisionable_->generateCertificateRequest(testMode, keysToSign_, *chain,
683 challenge_, &deviceInfo,
684 &protectedData, &keysToSignMac);
685 ASSERT_FALSE(status.isOk());
686 ASSERT_EQ(status.getServiceSpecificError(),
687 BnRemotelyProvisionedComponent::STATUS_INVALID_EEK);
688 }
689 }
690
691 /**
692 * Generate a non-empty certificate request in prod mode that has an incomplete EEK chain.
693 * Confirm that the request is rejected.
694 */
TEST_P(CertificateRequestTest,NonEmptyIncompleteEekRequest_prodMode)695 TEST_P(CertificateRequestTest, NonEmptyIncompleteEekRequest_prodMode) {
696 bool testMode = false;
697 generateKeys(testMode, 4 /* numKeys */);
698
699 // Build an EEK chain that omits the first self-signed cert.
700 auto truncatedChain = cppbor::Array();
701 auto [chain, _, parseErr] = cppbor::parse(getProdEekChain(rpcHardwareInfo.supportedEekCurve));
702 ASSERT_TRUE(chain);
703 auto eekChain = chain->asArray();
704 ASSERT_NE(eekChain, nullptr);
705 for (size_t ii = 1; ii < eekChain->size(); ii++) {
706 truncatedChain.add(eekChain->get(ii)->clone());
707 }
708
709 bytevec keysToSignMac;
710 DeviceInfo deviceInfo;
711 ProtectedData protectedData;
712 auto status = provisionable_->generateCertificateRequest(
713 testMode, keysToSign_, truncatedChain.encode(), challenge_, &deviceInfo, &protectedData,
714 &keysToSignMac);
715 ASSERT_FALSE(status.isOk());
716 ASSERT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_EEK);
717 }
718
719 /**
720 * Generate a non-empty certificate request in test mode, with prod keys. Must fail with
721 * STATUS_PRODUCTION_KEY_IN_TEST_REQUEST.
722 */
TEST_P(CertificateRequestTest,NonEmptyRequest_prodKeyInTestCert)723 TEST_P(CertificateRequestTest, NonEmptyRequest_prodKeyInTestCert) {
724 generateKeys(false /* testMode */, 2 /* numKeys */);
725
726 bytevec keysToSignMac;
727 DeviceInfo deviceInfo;
728 ProtectedData protectedData;
729 generateTestEekChain(3);
730 auto status = provisionable_->generateCertificateRequest(
731 true /* testMode */, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo,
732 &protectedData, &keysToSignMac);
733 ASSERT_FALSE(status.isOk());
734 ASSERT_EQ(status.getServiceSpecificError(),
735 BnRemotelyProvisionedComponent::STATUS_PRODUCTION_KEY_IN_TEST_REQUEST);
736 }
737
738 /**
739 * Generate a non-empty certificate request in prod mode, with test keys. Must fail with
740 * STATUS_TEST_KEY_IN_PRODUCTION_REQUEST.
741 */
TEST_P(CertificateRequestTest,NonEmptyRequest_testKeyInProdCert)742 TEST_P(CertificateRequestTest, NonEmptyRequest_testKeyInProdCert) {
743 generateKeys(true /* testMode */, 2 /* numKeys */);
744
745 bytevec keysToSignMac;
746 DeviceInfo deviceInfo;
747 ProtectedData protectedData;
748 generateTestEekChain(3);
749 auto status = provisionable_->generateCertificateRequest(
750 false /* testMode */, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo,
751 &protectedData, &keysToSignMac);
752 ASSERT_FALSE(status.isOk());
753 ASSERT_EQ(status.getServiceSpecificError(),
754 BnRemotelyProvisionedComponent::STATUS_TEST_KEY_IN_PRODUCTION_REQUEST);
755 }
756
757 INSTANTIATE_REM_PROV_AIDL_TEST(CertificateRequestTest);
758
759 class CertificateRequestV2Test : public CertificateRequestTestBase {
SetUp()760 void SetUp() override {
761 CertificateRequestTestBase::SetUp();
762 ASSERT_FALSE(HasFatalFailure());
763
764 if (rpcHardwareInfo.versionNumber < VERSION_WITH_CERTIFICATE_REQUEST_V2) {
765 GTEST_SKIP() << "This test case only applies to RKP v3 and above. "
766 << "RKP version discovered: " << rpcHardwareInfo.versionNumber;
767 }
768 }
769 };
770
771 /**
772 * Generate an empty certificate request with all possible length of challenge, and decrypt and
773 * verify the structure and content.
774 */
775 // @VsrTest = 3.10-015
TEST_P(CertificateRequestV2Test,EmptyRequest)776 TEST_P(CertificateRequestV2Test, EmptyRequest) {
777 bytevec csr;
778
779 for (auto size = MIN_CHALLENGE_SIZE; size <= MAX_CHALLENGE_SIZE; size++) {
780 SCOPED_TRACE(testing::Message() << "challenge[" << size << "]");
781 auto challenge = randomBytes(size);
782 auto status =
783 provisionable_->generateCertificateRequestV2({} /* keysToSign */, challenge, &csr);
784 ASSERT_TRUE(status.isOk()) << status.getDescription();
785
786 auto result = verifyProductionCsr(cppbor::Array(), csr, rpcHardwareInfo, GetParam(),
787 challenge, isRkpVmInstance_);
788 ASSERT_TRUE(result) << result.message();
789 }
790 }
791
792 /**
793 * Generate a non-empty certificate request with all possible length of challenge. Decrypt, parse
794 * and validate the contents.
795 */
796 // @VsrTest = 3.10-015
TEST_P(CertificateRequestV2Test,NonEmptyRequest)797 TEST_P(CertificateRequestV2Test, NonEmptyRequest) {
798 generateKeys(false /* testMode */, 1 /* numKeys */);
799
800 bytevec csr;
801
802 for (auto size = MIN_CHALLENGE_SIZE; size <= MAX_CHALLENGE_SIZE; size++) {
803 SCOPED_TRACE(testing::Message() << "challenge[" << size << "]");
804 auto challenge = randomBytes(size);
805 auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge, &csr);
806 ASSERT_TRUE(status.isOk()) << status.getDescription();
807
808 auto result = verifyProductionCsr(cborKeysToSign_, csr, rpcHardwareInfo, GetParam(),
809 challenge, isRkpVmInstance_);
810 ASSERT_TRUE(result) << result.message();
811 }
812 }
813
814 /**
815 * Generate an empty certificate request with invalid size of challenge
816 */
TEST_P(CertificateRequestV2Test,EmptyRequestWithInvalidChallengeFail)817 TEST_P(CertificateRequestV2Test, EmptyRequestWithInvalidChallengeFail) {
818 bytevec csr;
819
820 auto status = provisionable_->generateCertificateRequestV2(
821 /* keysToSign */ {}, randomBytes(MAX_CHALLENGE_SIZE + 1), &csr);
822 EXPECT_FALSE(status.isOk()) << status.getDescription();
823 EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_FAILED);
824 }
825
826 /**
827 * Generate a non-empty certificate request. Make sure contents are reproducible but allow for the
828 * signature to be different since algorithms including ECDSA P-256 can include a random value.
829 */
830 // @VsrTest = 3.10-015
TEST_P(CertificateRequestV2Test,NonEmptyRequestReproducible)831 TEST_P(CertificateRequestV2Test, NonEmptyRequestReproducible) {
832 generateKeys(false /* testMode */, 1 /* numKeys */);
833
834 bytevec csr;
835
836 auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
837 ASSERT_TRUE(status.isOk()) << status.getDescription();
838
839 auto firstCsr = verifyProductionCsr(cborKeysToSign_, csr, rpcHardwareInfo, GetParam(),
840 challenge_, isRkpVmInstance_);
841 ASSERT_TRUE(firstCsr) << firstCsr.message();
842
843 status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
844 ASSERT_TRUE(status.isOk()) << status.getDescription();
845
846 auto secondCsr = verifyProductionCsr(cborKeysToSign_, csr, rpcHardwareInfo, GetParam(),
847 challenge_, isRkpVmInstance_);
848 ASSERT_TRUE(secondCsr) << secondCsr.message();
849
850 ASSERT_EQ(**firstCsr, **secondCsr);
851 }
852
853 /**
854 * Generate a non-empty certificate request with multiple keys.
855 */
856 // @VsrTest = 3.10-015
TEST_P(CertificateRequestV2Test,NonEmptyRequestMultipleKeys)857 TEST_P(CertificateRequestV2Test, NonEmptyRequestMultipleKeys) {
858 generateKeys(false /* testMode */, rpcHardwareInfo.supportedNumKeysInCsr /* numKeys */);
859
860 bytevec csr;
861
862 auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
863 ASSERT_TRUE(status.isOk()) << status.getDescription();
864
865 auto result = verifyProductionCsr(cborKeysToSign_, csr, rpcHardwareInfo, GetParam(), challenge_,
866 isRkpVmInstance_);
867 ASSERT_TRUE(result) << result.message();
868 }
869
870 /**
871 * Generate a non-empty certificate request, but with the MAC corrupted on the keypair.
872 */
TEST_P(CertificateRequestV2Test,NonEmptyRequestCorruptMac)873 TEST_P(CertificateRequestV2Test, NonEmptyRequestCorruptMac) {
874 generateKeys(false /* testMode */, 1 /* numKeys */);
875 auto result = corrupt_maced_key(keysToSign_[0]);
876 ASSERT_TRUE(result) << result.moveMessage();
877 MacedPublicKey keyWithCorruptMac = result.moveValue();
878
879 bytevec csr;
880 auto status =
881 provisionable_->generateCertificateRequestV2({keyWithCorruptMac}, challenge_, &csr);
882 ASSERT_FALSE(status.isOk()) << status.getDescription();
883 EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
884 }
885
886 /**
887 * Call generateCertificateRequest(). Make sure it's removed.
888 */
TEST_P(CertificateRequestV2Test,CertificateRequestV1Removed_prodMode)889 TEST_P(CertificateRequestV2Test, CertificateRequestV1Removed_prodMode) {
890 bytevec keysToSignMac;
891 DeviceInfo deviceInfo;
892 ProtectedData protectedData;
893 auto status = provisionable_->generateCertificateRequest(
894 false /* testMode */, {} /* keysToSign */, {} /* EEK chain */, challenge_, &deviceInfo,
895 &protectedData, &keysToSignMac);
896 ASSERT_FALSE(status.isOk()) << status.getDescription();
897 EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_REMOVED);
898 }
899
900 /**
901 * Call generateCertificateRequest() in test mode. Make sure it's removed.
902 */
TEST_P(CertificateRequestV2Test,CertificateRequestV1Removed_testMode)903 TEST_P(CertificateRequestV2Test, CertificateRequestV1Removed_testMode) {
904 bytevec keysToSignMac;
905 DeviceInfo deviceInfo;
906 ProtectedData protectedData;
907 auto status = provisionable_->generateCertificateRequest(
908 true /* testMode */, {} /* keysToSign */, {} /* EEK chain */, challenge_, &deviceInfo,
909 &protectedData, &keysToSignMac);
910 ASSERT_FALSE(status.isOk()) << status.getDescription();
911 EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_REMOVED);
912 }
913
parse_root_of_trust(const vector<uint8_t> & attestation_cert,vector<uint8_t> * verified_boot_key,VerifiedBoot * verified_boot_state,bool * device_locked,vector<uint8_t> * verified_boot_hash)914 void parse_root_of_trust(const vector<uint8_t>& attestation_cert,
915 vector<uint8_t>* verified_boot_key, VerifiedBoot* verified_boot_state,
916 bool* device_locked, vector<uint8_t>* verified_boot_hash) {
917 X509_Ptr cert(parse_cert_blob(attestation_cert));
918 ASSERT_TRUE(cert.get());
919
920 ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get());
921 ASSERT_TRUE(attest_rec);
922
923 auto error = parse_root_of_trust(attest_rec->data, attest_rec->length, verified_boot_key,
924 verified_boot_state, device_locked, verified_boot_hash);
925 ASSERT_EQ(error, ErrorCode::OK);
926 }
927
928 /**
929 * Generate a CSR and verify DeviceInfo against IDs attested by KeyMint.
930 */
931 // @VsrTest = 3.10-015
TEST_P(CertificateRequestV2Test,DeviceInfo)932 TEST_P(CertificateRequestV2Test, DeviceInfo) {
933 // See if there is a matching IKeyMintDevice for this IRemotelyProvisionedComponent.
934 std::shared_ptr<IKeyMintDevice> keyMint;
935 if (!matching_keymint_device(GetParam(), &keyMint)) {
936 // No matching IKeyMintDevice.
937 GTEST_SKIP() << "Skipping key use test as no matching KeyMint device found";
938 return;
939 }
940 KeyMintHardwareInfo info;
941 ASSERT_TRUE(keyMint->getHardwareInfo(&info).isOk());
942
943 // Get IDs attested by KeyMint.
944 MacedPublicKey macedPubKey;
945 bytevec privateKeyBlob;
946 auto irpcStatus =
947 provisionable_->generateEcdsaP256KeyPair(false, &macedPubKey, &privateKeyBlob);
948 ASSERT_TRUE(irpcStatus.isOk());
949
950 AttestationKey attestKey;
951 attestKey.keyBlob = std::move(privateKeyBlob);
952 attestKey.issuerSubjectName = make_name_from_str("Android Keystore Key");
953
954 // Generate an ECDSA key that is attested by the generated P256 keypair.
955 AuthorizationSet keyDesc = AuthorizationSetBuilder()
956 .Authorization(TAG_NO_AUTH_REQUIRED)
957 .EcdsaSigningKey(EcCurve::P_256)
958 .AttestationChallenge("foo")
959 .AttestationApplicationId("bar")
960 .Digest(Digest::NONE)
961 .SetDefaultValidity();
962 KeyCreationResult creationResult;
963 auto kmStatus = keyMint->generateKey(keyDesc.vector_data(), attestKey, &creationResult);
964 ASSERT_TRUE(kmStatus.isOk());
965
966 vector<KeyCharacteristics> key_characteristics = std::move(creationResult.keyCharacteristics);
967 vector<Certificate> key_cert_chain = std::move(creationResult.certificateChain);
968 // We didn't provision the attestation key.
969 ASSERT_EQ(key_cert_chain.size(), 1);
970
971 // Parse attested patch levels.
972 auto auths = HwEnforcedAuthorizations(key_characteristics);
973
974 auto attestedSystemPatchLevel = auths.GetTagValue(TAG_OS_PATCHLEVEL);
975 auto attestedVendorPatchLevel = auths.GetTagValue(TAG_VENDOR_PATCHLEVEL);
976 auto attestedBootPatchLevel = auths.GetTagValue(TAG_BOOT_PATCHLEVEL);
977
978 ASSERT_TRUE(attestedSystemPatchLevel.has_value());
979 ASSERT_TRUE(attestedVendorPatchLevel.has_value());
980 ASSERT_TRUE(attestedBootPatchLevel.has_value());
981
982 // Parse attested AVB values.
983 vector<uint8_t> key;
984 VerifiedBoot attestedVbState;
985 bool attestedBootloaderState;
986 vector<uint8_t> attestedVbmetaDigest;
987 parse_root_of_trust(key_cert_chain[0].encodedCertificate, &key, &attestedVbState,
988 &attestedBootloaderState, &attestedVbmetaDigest);
989
990 // Get IDs from DeviceInfo.
991 bytevec csr;
992 irpcStatus =
993 provisionable_->generateCertificateRequestV2({} /* keysToSign */, challenge_, &csr);
994 ASSERT_TRUE(irpcStatus.isOk()) << irpcStatus.getDescription();
995
996 auto result =
997 verifyProductionCsr(cppbor::Array(), csr, rpcHardwareInfo, GetParam(), challenge_);
998 ASSERT_TRUE(result) << result.message();
999
1000 std::unique_ptr<cppbor::Array> csrPayload = std::move(*result);
1001 ASSERT_TRUE(csrPayload);
1002
1003 auto deviceInfo = csrPayload->get(2)->asMap();
1004 ASSERT_TRUE(deviceInfo);
1005
1006 auto vbState = deviceInfo->get("vb_state")->asTstr();
1007 auto bootloaderState = deviceInfo->get("bootloader_state")->asTstr();
1008 auto vbmetaDigest = deviceInfo->get("vbmeta_digest")->asBstr();
1009 auto systemPatchLevel = deviceInfo->get("system_patch_level")->asUint();
1010 auto vendorPatchLevel = deviceInfo->get("vendor_patch_level")->asUint();
1011 auto bootPatchLevel = deviceInfo->get("boot_patch_level")->asUint();
1012 auto securityLevel = deviceInfo->get("security_level")->asTstr();
1013
1014 ASSERT_TRUE(vbState);
1015 ASSERT_TRUE(bootloaderState);
1016 ASSERT_TRUE(vbmetaDigest);
1017 ASSERT_TRUE(systemPatchLevel);
1018 ASSERT_TRUE(vendorPatchLevel);
1019 ASSERT_TRUE(bootPatchLevel);
1020 ASSERT_TRUE(securityLevel);
1021
1022 auto kmDeviceName = deviceSuffix(GetParam());
1023
1024 // Compare DeviceInfo against IDs attested by KeyMint.
1025 ASSERT_TRUE((securityLevel->value() == "tee" && kmDeviceName == "default") ||
1026 (securityLevel->value() == "strongbox" && kmDeviceName == "strongbox"));
1027 ASSERT_TRUE((vbState->value() == "green" && attestedVbState == VerifiedBoot::VERIFIED) ||
1028 (vbState->value() == "yellow" && attestedVbState == VerifiedBoot::SELF_SIGNED) ||
1029 (vbState->value() == "orange" && attestedVbState == VerifiedBoot::UNVERIFIED));
1030 ASSERT_TRUE((bootloaderState->value() == "locked" && attestedBootloaderState) ||
1031 (bootloaderState->value() == "unlocked" && !attestedBootloaderState));
1032 ASSERT_EQ(vbmetaDigest->value(), attestedVbmetaDigest);
1033 ASSERT_EQ(systemPatchLevel->value(), attestedSystemPatchLevel.value());
1034 ASSERT_EQ(vendorPatchLevel->value(), attestedVendorPatchLevel.value());
1035 ASSERT_EQ(bootPatchLevel->value(), attestedBootPatchLevel.value());
1036 }
1037
1038 INSTANTIATE_REM_PROV_AIDL_TEST(CertificateRequestV2Test);
1039
1040 using VsrRequirementTest = VtsRemotelyProvisionedComponentTests;
1041
1042 INSTANTIATE_REM_PROV_AIDL_TEST(VsrRequirementTest);
1043
TEST_P(VsrRequirementTest,VsrEnforcementTest)1044 TEST_P(VsrRequirementTest, VsrEnforcementTest) {
1045 RpcHardwareInfo hwInfo;
1046 ASSERT_TRUE(provisionable_->getHardwareInfo(&hwInfo).isOk());
1047 int vsr_api_level = get_vsr_api_level();
1048 if (vsr_api_level < 34) {
1049 GTEST_SKIP() << "Applies only to VSR API level 34 or newer, this device is: "
1050 << vsr_api_level;
1051 }
1052 EXPECT_GE(hwInfo.versionNumber, 3)
1053 << "VSR 14+ requires IRemotelyProvisionedComponent v3 or newer.";
1054 }
1055
1056 } // namespace aidl::android::hardware::security::keymint::test
1057