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