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