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