blob: f40a7523f4f29b9a6ca7bcc826560a1a9fe6b1c6 [file] [log] [blame]
Shawn Willden274bb552020-09-30 22:39:22 -06001/*
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
Seth Mooref1f62152022-09-13 12:00:30 -070017#include <memory>
Seth Moore2fc6f832022-09-13 16:10:11 -070018#include <string>
Shawn Willden274bb552020-09-30 22:39:22 -060019#define LOG_TAG "VtsRemotelyProvisionableComponentTests"
20
Seth Moore8f810b12022-12-12 16:51:01 -080021#include <aidl/android/hardware/security/keymint/BnRemotelyProvisionedComponent.h>
Shawn Willden274bb552020-09-30 22:39:22 -060022#include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
23#include <aidl/android/hardware/security/keymint/SecurityLevel.h>
24#include <android/binder_manager.h>
Seth Moorefc86bf42021-12-09 14:07:04 -080025#include <binder/IServiceManager.h>
Tri Voec50ee12023-02-14 16:29:53 -080026#include <cppbor.h>
Shawn Willden274bb552020-09-30 22:39:22 -060027#include <cppbor_parse.h>
Shawn Willden274bb552020-09-30 22:39:22 -060028#include <gmock/gmock.h>
Max Bires9704ff62021-04-07 11:12:01 -070029#include <keymaster/cppcose/cppcose.h>
Shawn Willden274bb552020-09-30 22:39:22 -060030#include <keymaster/keymaster_configuration.h>
David Drysdalef0d516d2021-03-22 07:51:43 +000031#include <keymint_support/authorization_set.h>
32#include <openssl/ec.h>
33#include <openssl/ec_key.h>
34#include <openssl/x509.h>
Shawn Willden274bb552020-09-30 22:39:22 -060035#include <remote_prov/remote_prov_utils.h>
Max Bires757ed422022-09-07 16:20:31 -070036#include <optional>
Seth Moorefc86bf42021-12-09 14:07:04 -080037#include <set>
Sean Thomasafbab602024-11-07 23:14:05 +000038#include <string_view>
Seth Moore42c11332021-07-02 15:38:17 -070039#include <vector>
Shawn Willden274bb552020-09-30 22:39:22 -060040
David Drysdalef0d516d2021-03-22 07:51:43 +000041#include "KeyMintAidlTestBase.h"
42
Shawn Willden274bb552020-09-30 22:39:22 -060043namespace aidl::android::hardware::security::keymint::test {
44
45using ::std::string;
46using ::std::vector;
47
48namespace {
49
Seth Moorefc86bf42021-12-09 14:07:04 -080050constexpr int32_t VERSION_WITH_UNIQUE_ID_SUPPORT = 2;
Andrew Scullf2ae1932023-04-24 19:09:09 +000051
52constexpr int32_t VERSION_WITHOUT_EEK = 3;
Tri Vo0d6204e2022-09-29 16:15:34 -070053constexpr int32_t VERSION_WITHOUT_TEST_MODE = 3;
Andrew Scullf2ae1932023-04-24 19:09:09 +000054constexpr int32_t VERSION_WITH_CERTIFICATE_REQUEST_V2 = 3;
55constexpr int32_t VERSION_WITH_SUPPORTED_NUM_KEYS_IN_CSR = 3;
Seth Moorefc86bf42021-12-09 14:07:04 -080056
Tommy Chiufde3ad12023-03-17 05:58:28 +000057constexpr uint8_t MIN_CHALLENGE_SIZE = 0;
58constexpr uint8_t MAX_CHALLENGE_SIZE = 64;
Alice Wangf112ec92024-10-08 07:30:28 +000059
Andrew Scull21461522024-03-25 15:08:08 +000060const string KEYMINT_STRONGBOX_INSTANCE_NAME =
61 "android.hardware.security.keymint.IKeyMintDevice/strongbox";
Tommy Chiufde3ad12023-03-17 05:58:28 +000062
Shawn Willden274bb552020-09-30 22:39:22 -060063#define INSTANTIATE_REM_PROV_AIDL_TEST(name) \
Seth Moore6305e232021-07-27 14:20:17 -070064 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(name); \
Shawn Willden274bb552020-09-30 22:39:22 -060065 INSTANTIATE_TEST_SUITE_P( \
66 PerInstance, name, \
67 testing::ValuesIn(VtsRemotelyProvisionedComponentTests::build_params()), \
68 ::android::PrintInstanceNameToString)
69
Seth Moorefc86bf42021-12-09 14:07:04 -080070using ::android::sp;
Shawn Willden274bb552020-09-30 22:39:22 -060071using bytevec = std::vector<uint8_t>;
72using testing::MatchesRegex;
73using namespace remote_prov;
74using namespace keymaster;
75
76bytevec string_to_bytevec(const char* s) {
77 const uint8_t* p = reinterpret_cast<const uint8_t*>(s);
78 return bytevec(p, p + strlen(s));
79}
80
David Drysdalee99ed862021-03-15 16:43:06 +000081ErrMsgOr<MacedPublicKey> corrupt_maced_key(const MacedPublicKey& macedPubKey) {
82 auto [coseMac0, _, mac0ParseErr] = cppbor::parse(macedPubKey.macedKey);
83 if (!coseMac0 || coseMac0->asArray()->size() != kCoseMac0EntryCount) {
84 return "COSE Mac0 parse failed";
85 }
86 auto protParams = coseMac0->asArray()->get(kCoseMac0ProtectedParams)->asBstr();
87 auto unprotParams = coseMac0->asArray()->get(kCoseMac0UnprotectedParams)->asMap();
88 auto payload = coseMac0->asArray()->get(kCoseMac0Payload)->asBstr();
89 auto tag = coseMac0->asArray()->get(kCoseMac0Tag)->asBstr();
90 if (!protParams || !unprotParams || !payload || !tag) {
91 return "Invalid COSE_Sign1: missing content";
92 }
93 auto corruptMac0 = cppbor::Array();
94 corruptMac0.add(protParams->clone());
95 corruptMac0.add(unprotParams->clone());
96 corruptMac0.add(payload->clone());
97 vector<uint8_t> tagData = tag->value();
98 tagData[0] ^= 0x08;
99 tagData[tagData.size() - 1] ^= 0x80;
100 corruptMac0.add(cppbor::Bstr(tagData));
101
102 return MacedPublicKey{corruptMac0.encode()};
103}
104
David Drysdalecceca9f2021-03-12 15:49:47 +0000105ErrMsgOr<cppbor::Array> corrupt_sig(const cppbor::Array* coseSign1) {
106 if (coseSign1->size() != kCoseSign1EntryCount) {
107 return "Invalid COSE_Sign1, wrong entry count";
108 }
109 const cppbor::Bstr* protectedParams = coseSign1->get(kCoseSign1ProtectedParams)->asBstr();
110 const cppbor::Map* unprotectedParams = coseSign1->get(kCoseSign1UnprotectedParams)->asMap();
111 const cppbor::Bstr* payload = coseSign1->get(kCoseSign1Payload)->asBstr();
112 const cppbor::Bstr* signature = coseSign1->get(kCoseSign1Signature)->asBstr();
113 if (!protectedParams || !unprotectedParams || !payload || !signature) {
114 return "Invalid COSE_Sign1: missing content";
115 }
116
117 auto corruptSig = cppbor::Array();
118 corruptSig.add(protectedParams->clone());
119 corruptSig.add(unprotectedParams->clone());
120 corruptSig.add(payload->clone());
121 vector<uint8_t> sigData = signature->value();
122 sigData[0] ^= 0x08;
123 corruptSig.add(cppbor::Bstr(sigData));
124
125 return std::move(corruptSig);
126}
127
Seth Moore19acbe92021-06-23 15:15:52 -0700128ErrMsgOr<bytevec> corrupt_sig_chain(const bytevec& encodedEekChain, int which) {
129 auto [chain, _, parseErr] = cppbor::parse(encodedEekChain);
David Drysdalecceca9f2021-03-12 15:49:47 +0000130 if (!chain || !chain->asArray()) {
131 return "EekChain parse failed";
132 }
133
134 cppbor::Array* eekChain = chain->asArray();
135 if (which >= eekChain->size()) {
136 return "selected sig out of range";
137 }
138 auto corruptChain = cppbor::Array();
139
140 for (int ii = 0; ii < eekChain->size(); ++ii) {
141 if (ii == which) {
142 auto sig = corrupt_sig(eekChain->get(which)->asArray());
143 if (!sig) {
144 return "Failed to build corrupted signature" + sig.moveMessage();
145 }
146 corruptChain.add(sig.moveValue());
147 } else {
148 corruptChain.add(eekChain->get(ii)->clone());
149 }
150 }
Seth Moore19acbe92021-06-23 15:15:52 -0700151 return corruptChain.encode();
David Drysdalecceca9f2021-03-12 15:49:47 +0000152}
153
Sean Thomasa737a2d2024-11-20 17:25:53 +0000154template <class T>
155auto getHandle(const string& serviceName) {
156 ::ndk::SpAIBinder binder(AServiceManager_waitForService(serviceName.c_str()));
157 return T::fromBinder(binder);
158}
David Drysdale4d3c2982021-03-31 18:21:40 +0100159
Sean Thomasa737a2d2024-11-20 17:25:53 +0000160std::shared_ptr<IKeyMintDevice> matchingKeyMintDevice(const string& rpcName) {
161 auto rpcSuffix = deviceSuffix(rpcName);
162
163 vector<string> kmNames = ::android::getAidlHalInstanceNames(IKeyMintDevice::descriptor);
164 for (const string& kmName : kmNames) {
David Drysdale4d3c2982021-03-31 18:21:40 +0100165 // If the suffix of the KeyMint instance equals the suffix of the
166 // RemotelyProvisionedComponent instance, assume they match.
Sean Thomasa737a2d2024-11-20 17:25:53 +0000167 if (deviceSuffix(kmName) == rpcSuffix && AServiceManager_isDeclared(kmName.c_str())) {
168 getHandle<IKeyMintDevice>(kmName);
David Drysdale4d3c2982021-03-31 18:21:40 +0100169 }
170 }
Sean Thomasa737a2d2024-11-20 17:25:53 +0000171 return nullptr;
David Drysdale4d3c2982021-03-31 18:21:40 +0100172}
173
Shawn Willden274bb552020-09-30 22:39:22 -0600174} // namespace
175
176class VtsRemotelyProvisionedComponentTests : public testing::TestWithParam<std::string> {
177 public:
178 virtual void SetUp() override {
179 if (AServiceManager_isDeclared(GetParam().c_str())) {
Sean Thomasa737a2d2024-11-20 17:25:53 +0000180 provisionable_ = getHandle<IRemotelyProvisionedComponent>(GetParam());
Shawn Willden274bb552020-09-30 22:39:22 -0600181 }
182 ASSERT_NE(provisionable_, nullptr);
Alice Wang895f4b32023-11-14 07:38:18 +0000183 auto status = provisionable_->getHardwareInfo(&rpcHardwareInfo);
Alice Wangf112ec92024-10-08 07:30:28 +0000184 isRkpVmInstance_ = GetParam() == RKPVM_INSTANCE_NAME;
Karuna Wadheraca6d8cc2024-07-18 14:08:36 +0000185 if (isRkpVmInstance_) {
Alice Wang46ff2862024-05-14 07:07:05 +0000186 if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
187 GTEST_SKIP() << "The RKP VM is not supported on this system.";
188 }
189 int apiLevel = get_vsr_api_level();
190 if (apiLevel < __ANDROID_API_V__) {
191 GTEST_SKIP() << "The RKP VM is supported only on V+ devices. Vendor API level: "
192 << apiLevel;
193 }
Alice Wang895f4b32023-11-14 07:38:18 +0000194 }
195 ASSERT_TRUE(status.isOk());
Shawn Willden274bb552020-09-30 22:39:22 -0600196 }
197
198 static vector<string> build_params() {
199 auto params = ::android::getAidlHalInstanceNames(IRemotelyProvisionedComponent::descriptor);
200 return params;
201 }
202
203 protected:
204 std::shared_ptr<IRemotelyProvisionedComponent> provisionable_;
subrahmanyamanfb213d62022-02-02 23:10:55 +0000205 RpcHardwareInfo rpcHardwareInfo;
Karuna Wadheraca6d8cc2024-07-18 14:08:36 +0000206 bool isRkpVmInstance_;
Shawn Willden274bb552020-09-30 22:39:22 -0600207};
208
Seth Moorefc86bf42021-12-09 14:07:04 -0800209/**
210 * Verify that every implementation reports a different unique id.
211 */
212TEST(NonParameterizedTests, eachRpcHasAUniqueId) {
213 std::set<std::string> uniqueIds;
214 for (auto hal : ::android::getAidlHalInstanceNames(IRemotelyProvisionedComponent::descriptor)) {
215 ASSERT_TRUE(AServiceManager_isDeclared(hal.c_str()));
Sean Thomasa737a2d2024-11-20 17:25:53 +0000216 auto rpc = getHandle<IRemotelyProvisionedComponent>(hal);
Seth Moorefc86bf42021-12-09 14:07:04 -0800217 ASSERT_NE(rpc, nullptr);
218
219 RpcHardwareInfo hwInfo;
Alice Wang895f4b32023-11-14 07:38:18 +0000220 auto status = rpc->getHardwareInfo(&hwInfo);
Alice Wangf112ec92024-10-08 07:30:28 +0000221 if (hal == RKPVM_INSTANCE_NAME && status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) {
Alice Wang895f4b32023-11-14 07:38:18 +0000222 GTEST_SKIP() << "The RKP VM is not supported on this system.";
223 }
224 ASSERT_TRUE(status.isOk());
Seth Moorefc86bf42021-12-09 14:07:04 -0800225
Tri Vodd12c482022-10-12 22:41:28 +0000226 if (hwInfo.versionNumber >= VERSION_WITH_UNIQUE_ID_SUPPORT) {
Seth Moorefc86bf42021-12-09 14:07:04 -0800227 ASSERT_TRUE(hwInfo.uniqueId);
228 auto [_, wasInserted] = uniqueIds.insert(*hwInfo.uniqueId);
229 EXPECT_TRUE(wasInserted);
230 } else {
231 ASSERT_FALSE(hwInfo.uniqueId);
232 }
233 }
234}
235
Andrew Scull21461522024-03-25 15:08:08 +0000236/**
237 * Verify that the default implementation supports DICE if there is a StrongBox KeyMint instance
238 * on the device.
239 */
240// @VsrTest = 3.10-015
Sean Thomas08cda5d2024-11-20 23:19:57 +0000241// @VsrTest = 3.10-018.001
Andrew Scull21461522024-03-25 15:08:08 +0000242TEST(NonParameterizedTests, requireDiceOnDefaultInstanceIfStrongboxPresent) {
243 int vsr_api_level = get_vsr_api_level();
244 if (vsr_api_level < 35) {
245 GTEST_SKIP() << "Applies only to VSR API level 35 or newer, this device is: "
246 << vsr_api_level;
247 }
248
249 if (!AServiceManager_isDeclared(KEYMINT_STRONGBOX_INSTANCE_NAME.c_str())) {
250 GTEST_SKIP() << "Strongbox is not present on this device.";
251 }
252
Sean Thomasa737a2d2024-11-20 17:25:53 +0000253 auto rpc = getHandle<IRemotelyProvisionedComponent>(DEFAULT_INSTANCE_NAME);
Andrew Scull21461522024-03-25 15:08:08 +0000254 ASSERT_NE(rpc, nullptr);
255
256 bytevec challenge = randomBytes(64);
257 bytevec csr;
258 auto status = rpc->generateCertificateRequestV2({} /* keysToSign */, challenge, &csr);
259 EXPECT_TRUE(status.isOk()) << status.getDescription();
260
Alice Wangf112ec92024-10-08 07:30:28 +0000261 auto result = isCsrWithProperDiceChain(csr, DEFAULT_INSTANCE_NAME);
Andrew Scull21461522024-03-25 15:08:08 +0000262 ASSERT_TRUE(result) << result.message();
263 ASSERT_TRUE(*result);
264}
265
Sean Thomasa737a2d2024-11-20 17:25:53 +0000266/**
267 * Verify that if a protected VM (also called `avf` or RKP VM) implementation exists, then the
268 * protected VM and the primary KeyMint (also called 'default') implementation's DICE certificate
269 * chain has the same root public key, i.e., the same UDS public key
270 */
271// @VsrTest = 7.1-003.001
272TEST(NonParameterizedTests, equalUdsPubInDiceCertChainForRkpVmAndPrimaryKeyMintInstances) {
273 int apiLevel = get_vsr_api_level();
Sean Thomas08cda5d2024-11-20 23:19:57 +0000274 if (apiLevel < 202504 && !AServiceManager_isDeclared(RKPVM_INSTANCE_NAME.c_str())) {
275 GTEST_SKIP() << "The RKP VM (" << RKPVM_INSTANCE_NAME << ") is not present on this device.";
276 }
277 if (apiLevel >= 202504) {
Sean Thomasa737a2d2024-11-20 17:25:53 +0000278 ASSERT_TRUE(AServiceManager_isDeclared(RKPVM_INSTANCE_NAME.c_str()));
279 }
280
281 auto rkpVmRpc = getHandle<IRemotelyProvisionedComponent>(RKPVM_INSTANCE_NAME);
282 ASSERT_NE(rkpVmRpc, nullptr) << "The RKP VM (" << RKPVM_INSTANCE_NAME
283 << ") RPC is unavailable.";
284
285 RpcHardwareInfo hardwareInfo;
286 auto status = rkpVmRpc->getHardwareInfo(&hardwareInfo);
287 if (!status.isOk()) {
288 GTEST_SKIP() << "The RKP VM is not supported on this system.";
289 }
290
291 bytevec rkpVmChallenge = randomBytes(MAX_CHALLENGE_SIZE);
292 bytevec rkpVmCsr;
293 auto rkpVmStatus =
294 rkpVmRpc->generateCertificateRequestV2({} /* keysToSign */, rkpVmChallenge, &rkpVmCsr);
295 ASSERT_TRUE(rkpVmStatus.isOk()) << rkpVmStatus.getDescription();
296
297 auto primaryKeyMintRpc = getHandle<IRemotelyProvisionedComponent>(DEFAULT_INSTANCE_NAME);
298 ASSERT_NE(primaryKeyMintRpc, nullptr)
299 << "The Primary KeyMint (" << DEFAULT_INSTANCE_NAME << ") RPC is unavailable.";
300
301 bytevec primaryKeyMintChallenge = randomBytes(MAX_CHALLENGE_SIZE);
302 bytevec primaryKeyMintCsr;
303 auto primaryKeyMintStatus = primaryKeyMintRpc->generateCertificateRequestV2(
304 {} /* keysToSign */, primaryKeyMintChallenge, &primaryKeyMintCsr);
305 ASSERT_TRUE(primaryKeyMintStatus.isOk()) << primaryKeyMintStatus.getDescription();
306
307 auto equal = compareRootPublicKeysInDiceChains(rkpVmCsr, RKPVM_INSTANCE_NAME, primaryKeyMintCsr,
308 DEFAULT_INSTANCE_NAME);
309 ASSERT_TRUE(equal) << equal.message();
310 ASSERT_TRUE(*equal) << "Primary KeyMint and RKP VM RPCs have different UDS public keys";
311}
312
Sean Thomas08cda5d2024-11-20 23:19:57 +0000313/**
314 * Suppose that there is a StrongBox KeyMint instance on the device.
315 *
316 * Then, this test verifies that "keymint" is a substring of the component name in the configuration
317 * descriptor in the leaf certificate of the DICE chain for the primary ("default") KeyMint
318 * instance.
319 */
320// @VsrTest = 3.10-018.003
321TEST(NonParameterizedTests, componentNameInConfigurationDescriptorForPrimaryKeyMintInstance) {
322 int vsr_api_level = get_vsr_api_level();
323 if (vsr_api_level < 202504) {
324 GTEST_SKIP() << "Applies only to VSR API level 202504 or newer, this device is: "
325 << vsr_api_level;
326 }
327
328 if (!AServiceManager_isDeclared(KEYMINT_STRONGBOX_INSTANCE_NAME.c_str())) {
329 GTEST_SKIP() << "Strongbox is not present on this device.";
330 }
331
332 ::ndk::SpAIBinder binder(AServiceManager_waitForService(DEFAULT_INSTANCE_NAME.c_str()));
333 std::shared_ptr<IRemotelyProvisionedComponent> rpc =
334 IRemotelyProvisionedComponent::fromBinder(binder);
335 ASSERT_NE(rpc, nullptr);
336
337 bytevec challenge = randomBytes(64);
338 bytevec csr;
339 auto status = rpc->generateCertificateRequestV2({} /* keysToSign */, challenge, &csr);
340 EXPECT_TRUE(status.isOk()) << status.getDescription();
341
342 auto result = verifyComponentNameInKeyMintDiceChain(csr);
343 ASSERT_TRUE(result) << result.message();
344 ASSERT_TRUE(*result);
345}
346
Seth Moorefc86bf42021-12-09 14:07:04 -0800347using GetHardwareInfoTests = VtsRemotelyProvisionedComponentTests;
348
349INSTANTIATE_REM_PROV_AIDL_TEST(GetHardwareInfoTests);
350
351/**
352 * Verify that a valid curve is reported by the implementation.
353 */
354TEST_P(GetHardwareInfoTests, supportsValidCurve) {
355 RpcHardwareInfo hwInfo;
356 ASSERT_TRUE(provisionable_->getHardwareInfo(&hwInfo).isOk());
357
Andrew Scullf2ae1932023-04-24 19:09:09 +0000358 if (rpcHardwareInfo.versionNumber >= VERSION_WITHOUT_EEK) {
359 ASSERT_EQ(hwInfo.supportedEekCurve, RpcHardwareInfo::CURVE_NONE)
360 << "Invalid curve: " << hwInfo.supportedEekCurve;
361 return;
Hasini Gunasinghe666b2712023-01-05 21:35:51 +0000362 }
Andrew Scullf2ae1932023-04-24 19:09:09 +0000363
364 const std::set<int> validCurves = {RpcHardwareInfo::CURVE_P256, RpcHardwareInfo::CURVE_25519};
Seth Moorefc86bf42021-12-09 14:07:04 -0800365 ASSERT_EQ(validCurves.count(hwInfo.supportedEekCurve), 1)
366 << "Invalid curve: " << hwInfo.supportedEekCurve;
367}
368
369/**
370 * Verify that the unique id is within the length limits as described in RpcHardwareInfo.aidl.
371 */
372TEST_P(GetHardwareInfoTests, uniqueId) {
Tri Vodd12c482022-10-12 22:41:28 +0000373 if (rpcHardwareInfo.versionNumber < VERSION_WITH_UNIQUE_ID_SUPPORT) {
Seth Moorefc86bf42021-12-09 14:07:04 -0800374 return;
375 }
376
377 RpcHardwareInfo hwInfo;
378 ASSERT_TRUE(provisionable_->getHardwareInfo(&hwInfo).isOk());
379 ASSERT_TRUE(hwInfo.uniqueId);
380 EXPECT_GE(hwInfo.uniqueId->size(), 1);
381 EXPECT_LE(hwInfo.uniqueId->size(), 32);
382}
383
Tri Vo9cab73c2022-10-28 13:40:24 -0700384/**
385 * Verify implementation supports at least MIN_SUPPORTED_NUM_KEYS_IN_CSR keys in a CSR.
386 */
387TEST_P(GetHardwareInfoTests, supportedNumKeysInCsr) {
Andrew Scullf2ae1932023-04-24 19:09:09 +0000388 if (rpcHardwareInfo.versionNumber < VERSION_WITH_SUPPORTED_NUM_KEYS_IN_CSR) {
Tri Vo9cab73c2022-10-28 13:40:24 -0700389 return;
390 }
391
392 RpcHardwareInfo hwInfo;
393 ASSERT_TRUE(provisionable_->getHardwareInfo(&hwInfo).isOk());
394 ASSERT_GE(hwInfo.supportedNumKeysInCsr, RpcHardwareInfo::MIN_SUPPORTED_NUM_KEYS_IN_CSR);
395}
396
Shawn Willden274bb552020-09-30 22:39:22 -0600397using GenerateKeyTests = VtsRemotelyProvisionedComponentTests;
398
399INSTANTIATE_REM_PROV_AIDL_TEST(GenerateKeyTests);
400
401/**
David Drysdalef0d516d2021-03-22 07:51:43 +0000402 * Generate and validate a production-mode key. MAC tag can't be verified, but
403 * the private key blob should be usable in KeyMint operations.
Shawn Willden274bb552020-09-30 22:39:22 -0600404 */
Max Bires126869a2021-02-21 18:32:59 -0800405TEST_P(GenerateKeyTests, generateEcdsaP256Key_prodMode) {
Shawn Willden274bb552020-09-30 22:39:22 -0600406 MacedPublicKey macedPubKey;
407 bytevec privateKeyBlob;
408 bool testMode = false;
409 auto status = provisionable_->generateEcdsaP256KeyPair(testMode, &macedPubKey, &privateKeyBlob);
410 ASSERT_TRUE(status.isOk());
David Drysdalef0d516d2021-03-22 07:51:43 +0000411 vector<uint8_t> coseKeyData;
Tri Vob0b8acc2022-11-30 16:22:23 -0800412 check_maced_pubkey(macedPubKey, testMode, &coseKeyData);
David Drysdale4d3c2982021-03-31 18:21:40 +0100413}
414
415/**
416 * Generate and validate a production-mode key, then use it as a KeyMint attestation key.
417 */
418TEST_P(GenerateKeyTests, generateAndUseEcdsaP256Key_prodMode) {
419 // See if there is a matching IKeyMintDevice for this IRemotelyProvisionedComponent.
Sean Thomasa737a2d2024-11-20 17:25:53 +0000420 auto keyMint = matchingKeyMintDevice(GetParam());
421 if (!keyMint) {
David Drysdale4d3c2982021-03-31 18:21:40 +0100422 GTEST_SKIP() << "Skipping key use test as no matching KeyMint device found";
423 return;
424 }
425 KeyMintHardwareInfo info;
426 ASSERT_TRUE(keyMint->getHardwareInfo(&info).isOk());
427
428 MacedPublicKey macedPubKey;
429 bytevec privateKeyBlob;
430 bool testMode = false;
431 auto status = provisionable_->generateEcdsaP256KeyPair(testMode, &macedPubKey, &privateKeyBlob);
432 ASSERT_TRUE(status.isOk());
433 vector<uint8_t> coseKeyData;
Tri Vob0b8acc2022-11-30 16:22:23 -0800434 check_maced_pubkey(macedPubKey, testMode, &coseKeyData);
David Drysdale4d3c2982021-03-31 18:21:40 +0100435
David Drysdalef0d516d2021-03-22 07:51:43 +0000436 AttestationKey attestKey;
437 attestKey.keyBlob = std::move(privateKeyBlob);
438 attestKey.issuerSubjectName = make_name_from_str("Android Keystore Key");
Shawn Willden274bb552020-09-30 22:39:22 -0600439
David Drysdalef0d516d2021-03-22 07:51:43 +0000440 // Generate an ECDSA key that is attested by the generated P256 keypair.
441 AuthorizationSet keyDesc = AuthorizationSetBuilder()
442 .Authorization(TAG_NO_AUTH_REQUIRED)
David Drysdale915ce252021-10-14 15:17:36 +0100443 .EcdsaSigningKey(EcCurve::P_256)
David Drysdalef0d516d2021-03-22 07:51:43 +0000444 .AttestationChallenge("foo")
445 .AttestationApplicationId("bar")
446 .Digest(Digest::NONE)
447 .SetDefaultValidity();
448 KeyCreationResult creationResult;
449 auto result = keyMint->generateKey(keyDesc.vector_data(), attestKey, &creationResult);
450 ASSERT_TRUE(result.isOk());
451 vector<uint8_t> attested_key_blob = std::move(creationResult.keyBlob);
452 vector<KeyCharacteristics> attested_key_characteristics =
453 std::move(creationResult.keyCharacteristics);
454 vector<Certificate> attested_key_cert_chain = std::move(creationResult.certificateChain);
455 EXPECT_EQ(attested_key_cert_chain.size(), 1);
456
David Drysdale7dff4fc2021-12-10 10:10:52 +0000457 int32_t aidl_version = 0;
458 ASSERT_TRUE(keyMint->getInterfaceVersion(&aidl_version).isOk());
David Drysdalef0d516d2021-03-22 07:51:43 +0000459 AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
460 AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
David Drysdale7dff4fc2021-12-10 10:10:52 +0000461 EXPECT_TRUE(verify_attestation_record(aidl_version, "foo", "bar", sw_enforced, hw_enforced,
David Drysdalef0d516d2021-03-22 07:51:43 +0000462 info.securityLevel,
463 attested_key_cert_chain[0].encodedCertificate));
464
465 // Attestation by itself is not valid (last entry is not self-signed).
466 EXPECT_FALSE(ChainSignaturesAreValid(attested_key_cert_chain));
467
468 // The signature over the attested key should correspond to the P256 public key.
469 X509_Ptr key_cert(parse_cert_blob(attested_key_cert_chain[0].encodedCertificate));
470 ASSERT_TRUE(key_cert.get());
471 EVP_PKEY_Ptr signing_pubkey;
472 p256_pub_key(coseKeyData, &signing_pubkey);
473 ASSERT_TRUE(signing_pubkey.get());
474
475 ASSERT_TRUE(X509_verify(key_cert.get(), signing_pubkey.get()))
476 << "Verification of attested certificate failed "
477 << "OpenSSL error string: " << ERR_error_string(ERR_get_error(), NULL);
Shawn Willden274bb552020-09-30 22:39:22 -0600478}
479
480/**
481 * Generate and validate a test-mode key.
482 */
Max Bires126869a2021-02-21 18:32:59 -0800483TEST_P(GenerateKeyTests, generateEcdsaP256Key_testMode) {
Shawn Willden274bb552020-09-30 22:39:22 -0600484 MacedPublicKey macedPubKey;
485 bytevec privateKeyBlob;
486 bool testMode = true;
487 auto status = provisionable_->generateEcdsaP256KeyPair(testMode, &macedPubKey, &privateKeyBlob);
Andrew Scullf2ae1932023-04-24 19:09:09 +0000488
489 if (rpcHardwareInfo.versionNumber >= VERSION_WITHOUT_TEST_MODE) {
490 ASSERT_FALSE(status.isOk());
491 EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_REMOVED);
492 return;
493 }
494
Shawn Willden274bb552020-09-30 22:39:22 -0600495 ASSERT_TRUE(status.isOk());
Tri Vob0b8acc2022-11-30 16:22:23 -0800496 check_maced_pubkey(macedPubKey, testMode, nullptr);
Shawn Willden274bb552020-09-30 22:39:22 -0600497}
498
Sean Thomasf2946ab2024-11-27 18:09:46 +0000499/**
500 * Generate and validate at most 2**16 production-mode keys. This aims to catch issues that do not
501 * deterministically show up. In practice, this will test far fewer keys, but a certain number are
502 * tested at a minimum.
503 */
504TEST_P(GenerateKeyTests, generateManyEcdsaP256KeysInProdMode) {
505 const auto start = std::chrono::steady_clock::now();
506 const auto time_bound = std::chrono::seconds(5);
507 const auto upper_bound = 1 << 16;
508 const auto lower_bound = 1 << 8;
509 for (auto iteration = 0; iteration < upper_bound; iteration++) {
510 MacedPublicKey macedPubKey;
511 bytevec privateKeyBlob;
512 bool testMode = false;
513 auto status =
514 provisionable_->generateEcdsaP256KeyPair(testMode, &macedPubKey, &privateKeyBlob);
515 ASSERT_TRUE(status.isOk());
516 vector<uint8_t> coseKeyData;
517 check_maced_pubkey(macedPubKey, testMode, &coseKeyData);
518 const auto current_time = std::chrono::steady_clock::now() - start;
519 if (iteration >= lower_bound && current_time >= time_bound) {
520 break;
521 }
522 }
523}
524
Tri Vo0d6204e2022-09-29 16:15:34 -0700525class CertificateRequestTestBase : public VtsRemotelyProvisionedComponentTests {
Shawn Willden274bb552020-09-30 22:39:22 -0600526 protected:
Tri Vo0d6204e2022-09-29 16:15:34 -0700527 CertificateRequestTestBase()
528 : eekId_(string_to_bytevec("eekid")), challenge_(randomBytes(64)) {}
David Drysdalecceca9f2021-03-12 15:49:47 +0000529
Seth Moore19acbe92021-06-23 15:15:52 -0700530 void generateTestEekChain(size_t eekLength) {
subrahmanyamanfb213d62022-02-02 23:10:55 +0000531 auto chain = generateEekChain(rpcHardwareInfo.supportedEekCurve, eekLength, eekId_);
David Drysdale08696a72022-03-10 10:43:25 +0000532 ASSERT_TRUE(chain) << chain.message();
Seth Moore19acbe92021-06-23 15:15:52 -0700533 if (chain) testEekChain_ = chain.moveValue();
534 testEekLength_ = eekLength;
Shawn Willden274bb552020-09-30 22:39:22 -0600535 }
536
537 void generateKeys(bool testMode, size_t numKeys) {
538 keysToSign_ = std::vector<MacedPublicKey>(numKeys);
539 cborKeysToSign_ = cppbor::Array();
540
541 for (auto& key : keysToSign_) {
542 bytevec privateKeyBlob;
543 auto status = provisionable_->generateEcdsaP256KeyPair(testMode, &key, &privateKeyBlob);
Frederick Mayle9891be02023-11-03 14:39:24 -0700544 ASSERT_TRUE(status.isOk()) << status.getDescription();
Shawn Willden274bb552020-09-30 22:39:22 -0600545
David Drysdalec8400772021-03-11 12:35:11 +0000546 vector<uint8_t> payload_value;
Tri Vob0b8acc2022-11-30 16:22:23 -0800547 check_maced_pubkey(key, testMode, &payload_value);
David Drysdalec8400772021-03-11 12:35:11 +0000548 cborKeysToSign_.add(cppbor::EncodedItem(payload_value));
Shawn Willden274bb552020-09-30 22:39:22 -0600549 }
550 }
551
552 bytevec eekId_;
Seth Moore19acbe92021-06-23 15:15:52 -0700553 size_t testEekLength_;
554 EekChain testEekChain_;
David Drysdalec8400772021-03-11 12:35:11 +0000555 bytevec challenge_;
Shawn Willden274bb552020-09-30 22:39:22 -0600556 std::vector<MacedPublicKey> keysToSign_;
557 cppbor::Array cborKeysToSign_;
558};
559
Tri Vo0d6204e2022-09-29 16:15:34 -0700560class CertificateRequestTest : public CertificateRequestTestBase {
561 protected:
562 void SetUp() override {
563 CertificateRequestTestBase::SetUp();
Andrew Scull1bcb6022022-12-27 10:43:27 +0000564 ASSERT_FALSE(HasFatalFailure());
Tri Vo0d6204e2022-09-29 16:15:34 -0700565
Andrew Scullf2ae1932023-04-24 19:09:09 +0000566 if (rpcHardwareInfo.versionNumber >= VERSION_WITH_CERTIFICATE_REQUEST_V2) {
Andrew Scull95b31312023-03-27 19:16:07 +0000567 GTEST_SKIP() << "This test case only applies to RKP v1 and v2. "
568 << "RKP version discovered: " << rpcHardwareInfo.versionNumber;
Tri Vo0d6204e2022-09-29 16:15:34 -0700569 }
570 }
571};
572
Shawn Willden274bb552020-09-30 22:39:22 -0600573/**
574 * Generate an empty certificate request in test mode, and decrypt and verify the structure and
575 * content.
576 */
Max Bires126869a2021-02-21 18:32:59 -0800577TEST_P(CertificateRequestTest, EmptyRequest_testMode) {
Shawn Willden274bb552020-09-30 22:39:22 -0600578 bool testMode = true;
David Drysdalecceca9f2021-03-12 15:49:47 +0000579 for (size_t eekLength : {2, 3, 7}) {
580 SCOPED_TRACE(testing::Message() << "EEK of length " << eekLength);
Seth Moore19acbe92021-06-23 15:15:52 -0700581 generateTestEekChain(eekLength);
Shawn Willden274bb552020-09-30 22:39:22 -0600582
David Drysdalecceca9f2021-03-12 15:49:47 +0000583 bytevec keysToSignMac;
584 DeviceInfo deviceInfo;
585 ProtectedData protectedData;
586 auto status = provisionable_->generateCertificateRequest(
Seth Moore19acbe92021-06-23 15:15:52 -0700587 testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
David Drysdalecceca9f2021-03-12 15:49:47 +0000588 &protectedData, &keysToSignMac);
Frederick Mayle9891be02023-11-03 14:39:24 -0700589 ASSERT_TRUE(status.isOk()) << status.getDescription();
David Drysdalecceca9f2021-03-12 15:49:47 +0000590
Sean Thomas2d2385b2024-11-07 23:56:03 +0000591 auto result = verifyProductionProtectedData(deviceInfo, cppbor::Array(), keysToSignMac,
592 protectedData, testEekChain_, eekId_,
593 rpcHardwareInfo, GetParam(), challenge_);
Seth Moore2fc6f832022-09-13 16:10:11 -0700594 ASSERT_TRUE(result) << result.message();
David Drysdalecceca9f2021-03-12 15:49:47 +0000595 }
Shawn Willden274bb552020-09-30 22:39:22 -0600596}
597
598/**
Seth Moore42c11332021-07-02 15:38:17 -0700599 * Ensure that test mode outputs a unique BCC root key every time we request a
600 * certificate request. Else, it's possible that the test mode API could be used
601 * to fingerprint devices. Only the GEEK should be allowed to decrypt the same
602 * device public key multiple times.
603 */
604TEST_P(CertificateRequestTest, NewKeyPerCallInTestMode) {
605 constexpr bool testMode = true;
Seth Moore42c11332021-07-02 15:38:17 -0700606
607 bytevec keysToSignMac;
608 DeviceInfo deviceInfo;
609 ProtectedData protectedData;
subrahmanyamanfb213d62022-02-02 23:10:55 +0000610 generateTestEekChain(3);
Seth Moore42c11332021-07-02 15:38:17 -0700611 auto status = provisionable_->generateCertificateRequest(
Seth Moore19acbe92021-06-23 15:15:52 -0700612 testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
613 &protectedData, &keysToSignMac);
Frederick Mayle9891be02023-11-03 14:39:24 -0700614 ASSERT_TRUE(status.isOk()) << status.getDescription();
Seth Moore42c11332021-07-02 15:38:17 -0700615
Alice Wangf112ec92024-10-08 07:30:28 +0000616 auto firstBcc = verifyProductionProtectedData(deviceInfo, /*keysToSign=*/cppbor::Array(),
617 keysToSignMac, protectedData, testEekChain_,
Sean Thomas2d2385b2024-11-07 23:56:03 +0000618 eekId_, rpcHardwareInfo, GetParam(), challenge_);
Seth Moore2fc6f832022-09-13 16:10:11 -0700619 ASSERT_TRUE(firstBcc) << firstBcc.message();
Seth Moore42c11332021-07-02 15:38:17 -0700620
Seth Moore19acbe92021-06-23 15:15:52 -0700621 status = provisionable_->generateCertificateRequest(
622 testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
623 &protectedData, &keysToSignMac);
Frederick Mayle9891be02023-11-03 14:39:24 -0700624 ASSERT_TRUE(status.isOk()) << status.getDescription();
Seth Moore42c11332021-07-02 15:38:17 -0700625
Alice Wangf112ec92024-10-08 07:30:28 +0000626 auto secondBcc = verifyProductionProtectedData(deviceInfo, /*keysToSign=*/cppbor::Array(),
627 keysToSignMac, protectedData, testEekChain_,
Sean Thomas2d2385b2024-11-07 23:56:03 +0000628 eekId_, rpcHardwareInfo, GetParam(), challenge_);
Seth Moore2fc6f832022-09-13 16:10:11 -0700629 ASSERT_TRUE(secondBcc) << secondBcc.message();
Seth Moore42c11332021-07-02 15:38:17 -0700630
631 // Verify that none of the keys in the first BCC are repeated in the second one.
Seth Moore2fc6f832022-09-13 16:10:11 -0700632 for (const auto& i : *firstBcc) {
633 for (auto& j : *secondBcc) {
Seth Moore42c11332021-07-02 15:38:17 -0700634 ASSERT_THAT(i.pubKey, testing::Not(testing::ElementsAreArray(j.pubKey)))
635 << "Found a repeated pubkey in two generateCertificateRequest test mode calls";
636 }
637 }
638}
639
640/**
Seth Moore19acbe92021-06-23 15:15:52 -0700641 * Generate an empty certificate request in prod mode. This test must be run explicitly, and
642 * is not run by default. Not all devices are GMS devices, and therefore they do not all
643 * trust the Google EEK root.
Shawn Willden274bb552020-09-30 22:39:22 -0600644 */
Seth Moore19acbe92021-06-23 15:15:52 -0700645TEST_P(CertificateRequestTest, DISABLED_EmptyRequest_prodMode) {
Shawn Willden274bb552020-09-30 22:39:22 -0600646 bool testMode = false;
David Drysdalecceca9f2021-03-12 15:49:47 +0000647
Seth Moore19acbe92021-06-23 15:15:52 -0700648 bytevec keysToSignMac;
649 DeviceInfo deviceInfo;
650 ProtectedData protectedData;
651 auto status = provisionable_->generateCertificateRequest(
subrahmanyamanfb213d62022-02-02 23:10:55 +0000652 testMode, {} /* keysToSign */, getProdEekChain(rpcHardwareInfo.supportedEekCurve),
653 challenge_, &deviceInfo, &protectedData, &keysToSignMac);
Seth Moore19acbe92021-06-23 15:15:52 -0700654 EXPECT_TRUE(status.isOk());
Shawn Willden274bb552020-09-30 22:39:22 -0600655}
656
657/**
658 * Generate a non-empty certificate request in test mode. Decrypt, parse and validate the contents.
659 */
Max Bires126869a2021-02-21 18:32:59 -0800660TEST_P(CertificateRequestTest, NonEmptyRequest_testMode) {
Shawn Willden274bb552020-09-30 22:39:22 -0600661 bool testMode = true;
662 generateKeys(testMode, 4 /* numKeys */);
663
David Drysdalecceca9f2021-03-12 15:49:47 +0000664 for (size_t eekLength : {2, 3, 7}) {
665 SCOPED_TRACE(testing::Message() << "EEK of length " << eekLength);
Seth Moore19acbe92021-06-23 15:15:52 -0700666 generateTestEekChain(eekLength);
Shawn Willden274bb552020-09-30 22:39:22 -0600667
David Drysdalecceca9f2021-03-12 15:49:47 +0000668 bytevec keysToSignMac;
669 DeviceInfo deviceInfo;
670 ProtectedData protectedData;
671 auto status = provisionable_->generateCertificateRequest(
Seth Moore19acbe92021-06-23 15:15:52 -0700672 testMode, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo, &protectedData,
David Drysdalecceca9f2021-03-12 15:49:47 +0000673 &keysToSignMac);
Frederick Mayle9891be02023-11-03 14:39:24 -0700674 ASSERT_TRUE(status.isOk()) << status.getDescription();
David Drysdalecceca9f2021-03-12 15:49:47 +0000675
Sean Thomas2d2385b2024-11-07 23:56:03 +0000676 auto result = verifyProductionProtectedData(deviceInfo, cborKeysToSign_, keysToSignMac,
677 protectedData, testEekChain_, eekId_,
678 rpcHardwareInfo, GetParam(), challenge_);
Seth Moore2fc6f832022-09-13 16:10:11 -0700679 ASSERT_TRUE(result) << result.message();
David Drysdalecceca9f2021-03-12 15:49:47 +0000680 }
Shawn Willden274bb552020-09-30 22:39:22 -0600681}
682
683/**
Seth Moore19acbe92021-06-23 15:15:52 -0700684 * Generate a non-empty certificate request in prod mode. This test must be run explicitly, and
685 * is not run by default. Not all devices are GMS devices, and therefore they do not all
686 * trust the Google EEK root.
Shawn Willden274bb552020-09-30 22:39:22 -0600687 */
Seth Moore19acbe92021-06-23 15:15:52 -0700688TEST_P(CertificateRequestTest, DISABLED_NonEmptyRequest_prodMode) {
Shawn Willden274bb552020-09-30 22:39:22 -0600689 bool testMode = false;
690 generateKeys(testMode, 4 /* numKeys */);
691
Seth Moore19acbe92021-06-23 15:15:52 -0700692 bytevec keysToSignMac;
693 DeviceInfo deviceInfo;
694 ProtectedData protectedData;
695 auto status = provisionable_->generateCertificateRequest(
subrahmanyamanfb213d62022-02-02 23:10:55 +0000696 testMode, keysToSign_, getProdEekChain(rpcHardwareInfo.supportedEekCurve), challenge_,
697 &deviceInfo, &protectedData, &keysToSignMac);
Seth Moore19acbe92021-06-23 15:15:52 -0700698 EXPECT_TRUE(status.isOk());
David Drysdalecceca9f2021-03-12 15:49:47 +0000699}
700
701/**
David Drysdalee99ed862021-03-15 16:43:06 +0000702 * Generate a non-empty certificate request in test mode, but with the MAC corrupted on the keypair.
703 */
704TEST_P(CertificateRequestTest, NonEmptyRequestCorruptMac_testMode) {
705 bool testMode = true;
706 generateKeys(testMode, 1 /* numKeys */);
David Drysdale08696a72022-03-10 10:43:25 +0000707 auto result = corrupt_maced_key(keysToSign_[0]);
708 ASSERT_TRUE(result) << result.moveMessage();
709 MacedPublicKey keyWithCorruptMac = result.moveValue();
David Drysdalee99ed862021-03-15 16:43:06 +0000710
711 bytevec keysToSignMac;
712 DeviceInfo deviceInfo;
713 ProtectedData protectedData;
subrahmanyamanfb213d62022-02-02 23:10:55 +0000714 generateTestEekChain(3);
David Drysdalee99ed862021-03-15 16:43:06 +0000715 auto status = provisionable_->generateCertificateRequest(
Seth Moore19acbe92021-06-23 15:15:52 -0700716 testMode, {keyWithCorruptMac}, testEekChain_.chain, challenge_, &deviceInfo,
717 &protectedData, &keysToSignMac);
Frederick Mayle9891be02023-11-03 14:39:24 -0700718 ASSERT_FALSE(status.isOk()) << status.getDescription();
David Drysdalee99ed862021-03-15 16:43:06 +0000719 EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
720}
721
722/**
723 * Generate a non-empty certificate request in prod mode, but with the MAC corrupted on the keypair.
724 */
725TEST_P(CertificateRequestTest, NonEmptyRequestCorruptMac_prodMode) {
Seth Moore19acbe92021-06-23 15:15:52 -0700726 bool testMode = false;
David Drysdalee99ed862021-03-15 16:43:06 +0000727 generateKeys(testMode, 1 /* numKeys */);
David Drysdale08696a72022-03-10 10:43:25 +0000728 auto result = corrupt_maced_key(keysToSign_[0]);
729 ASSERT_TRUE(result) << result.moveMessage();
730 MacedPublicKey keyWithCorruptMac = result.moveValue();
David Drysdalee99ed862021-03-15 16:43:06 +0000731
732 bytevec keysToSignMac;
733 DeviceInfo deviceInfo;
734 ProtectedData protectedData;
735 auto status = provisionable_->generateCertificateRequest(
subrahmanyamanfb213d62022-02-02 23:10:55 +0000736 testMode, {keyWithCorruptMac}, getProdEekChain(rpcHardwareInfo.supportedEekCurve),
737 challenge_, &deviceInfo, &protectedData, &keysToSignMac);
Frederick Mayle9891be02023-11-03 14:39:24 -0700738 ASSERT_FALSE(status.isOk()) << status.getDescription();
Seth Moore19acbe92021-06-23 15:15:52 -0700739 EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
David Drysdalee99ed862021-03-15 16:43:06 +0000740}
741
742/**
David Drysdalecceca9f2021-03-12 15:49:47 +0000743 * Generate a non-empty certificate request in prod mode that has a corrupt EEK chain.
744 * Confirm that the request is rejected.
David Drysdalecceca9f2021-03-12 15:49:47 +0000745 */
746TEST_P(CertificateRequestTest, NonEmptyCorruptEekRequest_prodMode) {
747 bool testMode = false;
748 generateKeys(testMode, 4 /* numKeys */);
749
subrahmanyamanfb213d62022-02-02 23:10:55 +0000750 auto prodEekChain = getProdEekChain(rpcHardwareInfo.supportedEekCurve);
Seth Moore19acbe92021-06-23 15:15:52 -0700751 auto [parsedChain, _, parseErr] = cppbor::parse(prodEekChain);
752 ASSERT_NE(parsedChain, nullptr) << parseErr;
753 ASSERT_NE(parsedChain->asArray(), nullptr);
754
755 for (int ii = 0; ii < parsedChain->asArray()->size(); ++ii) {
756 auto chain = corrupt_sig_chain(prodEekChain, ii);
David Drysdalecceca9f2021-03-12 15:49:47 +0000757 ASSERT_TRUE(chain) << chain.message();
David Drysdalecceca9f2021-03-12 15:49:47 +0000758
759 bytevec keysToSignMac;
760 DeviceInfo deviceInfo;
761 ProtectedData protectedData;
Seth Moore19acbe92021-06-23 15:15:52 -0700762 auto status = provisionable_->generateCertificateRequest(testMode, keysToSign_, *chain,
763 challenge_, &deviceInfo,
764 &protectedData, &keysToSignMac);
David Drysdalecceca9f2021-03-12 15:49:47 +0000765 ASSERT_FALSE(status.isOk());
766 ASSERT_EQ(status.getServiceSpecificError(),
767 BnRemotelyProvisionedComponent::STATUS_INVALID_EEK);
768 }
769}
770
771/**
772 * Generate a non-empty certificate request in prod mode that has an incomplete EEK chain.
773 * Confirm that the request is rejected.
David Drysdalecceca9f2021-03-12 15:49:47 +0000774 */
775TEST_P(CertificateRequestTest, NonEmptyIncompleteEekRequest_prodMode) {
776 bool testMode = false;
777 generateKeys(testMode, 4 /* numKeys */);
778
779 // Build an EEK chain that omits the first self-signed cert.
780 auto truncatedChain = cppbor::Array();
subrahmanyamanfb213d62022-02-02 23:10:55 +0000781 auto [chain, _, parseErr] = cppbor::parse(getProdEekChain(rpcHardwareInfo.supportedEekCurve));
David Drysdalecceca9f2021-03-12 15:49:47 +0000782 ASSERT_TRUE(chain);
783 auto eekChain = chain->asArray();
784 ASSERT_NE(eekChain, nullptr);
785 for (size_t ii = 1; ii < eekChain->size(); ii++) {
786 truncatedChain.add(eekChain->get(ii)->clone());
787 }
788
Shawn Willden274bb552020-09-30 22:39:22 -0600789 bytevec keysToSignMac;
Max Biresfdbb9042021-03-23 12:43:38 -0700790 DeviceInfo deviceInfo;
Shawn Willden274bb552020-09-30 22:39:22 -0600791 ProtectedData protectedData;
David Drysdalecceca9f2021-03-12 15:49:47 +0000792 auto status = provisionable_->generateCertificateRequest(
793 testMode, keysToSign_, truncatedChain.encode(), challenge_, &deviceInfo, &protectedData,
794 &keysToSignMac);
Shawn Willden274bb552020-09-30 22:39:22 -0600795 ASSERT_FALSE(status.isOk());
796 ASSERT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_EEK);
797}
798
799/**
800 * Generate a non-empty certificate request in test mode, with prod keys. Must fail with
801 * STATUS_PRODUCTION_KEY_IN_TEST_REQUEST.
802 */
Max Bires126869a2021-02-21 18:32:59 -0800803TEST_P(CertificateRequestTest, NonEmptyRequest_prodKeyInTestCert) {
Shawn Willden274bb552020-09-30 22:39:22 -0600804 generateKeys(false /* testMode */, 2 /* numKeys */);
805
806 bytevec keysToSignMac;
Max Biresfdbb9042021-03-23 12:43:38 -0700807 DeviceInfo deviceInfo;
Shawn Willden274bb552020-09-30 22:39:22 -0600808 ProtectedData protectedData;
subrahmanyamanfb213d62022-02-02 23:10:55 +0000809 generateTestEekChain(3);
Max Biresfdbb9042021-03-23 12:43:38 -0700810 auto status = provisionable_->generateCertificateRequest(
Seth Moore19acbe92021-06-23 15:15:52 -0700811 true /* testMode */, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo,
Max Biresfdbb9042021-03-23 12:43:38 -0700812 &protectedData, &keysToSignMac);
Shawn Willden274bb552020-09-30 22:39:22 -0600813 ASSERT_FALSE(status.isOk());
814 ASSERT_EQ(status.getServiceSpecificError(),
815 BnRemotelyProvisionedComponent::STATUS_PRODUCTION_KEY_IN_TEST_REQUEST);
816}
817
818/**
819 * Generate a non-empty certificate request in prod mode, with test keys. Must fail with
820 * STATUS_TEST_KEY_IN_PRODUCTION_REQUEST.
821 */
Max Bires126869a2021-02-21 18:32:59 -0800822TEST_P(CertificateRequestTest, NonEmptyRequest_testKeyInProdCert) {
Shawn Willden274bb552020-09-30 22:39:22 -0600823 generateKeys(true /* testMode */, 2 /* numKeys */);
824
825 bytevec keysToSignMac;
Max Biresfdbb9042021-03-23 12:43:38 -0700826 DeviceInfo deviceInfo;
Shawn Willden274bb552020-09-30 22:39:22 -0600827 ProtectedData protectedData;
subrahmanyamanfb213d62022-02-02 23:10:55 +0000828 generateTestEekChain(3);
Shawn Willden274bb552020-09-30 22:39:22 -0600829 auto status = provisionable_->generateCertificateRequest(
Seth Moore19acbe92021-06-23 15:15:52 -0700830 false /* testMode */, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo,
David Drysdalec8400772021-03-11 12:35:11 +0000831 &protectedData, &keysToSignMac);
Shawn Willden274bb552020-09-30 22:39:22 -0600832 ASSERT_FALSE(status.isOk());
833 ASSERT_EQ(status.getServiceSpecificError(),
834 BnRemotelyProvisionedComponent::STATUS_TEST_KEY_IN_PRODUCTION_REQUEST);
835}
836
837INSTANTIATE_REM_PROV_AIDL_TEST(CertificateRequestTest);
838
Tri Vo0d6204e2022-09-29 16:15:34 -0700839class CertificateRequestV2Test : public CertificateRequestTestBase {
840 void SetUp() override {
841 CertificateRequestTestBase::SetUp();
Andrew Scull1bcb6022022-12-27 10:43:27 +0000842 ASSERT_FALSE(HasFatalFailure());
Tri Vo0d6204e2022-09-29 16:15:34 -0700843
Andrew Scullf2ae1932023-04-24 19:09:09 +0000844 if (rpcHardwareInfo.versionNumber < VERSION_WITH_CERTIFICATE_REQUEST_V2) {
Tri Vo0d6204e2022-09-29 16:15:34 -0700845 GTEST_SKIP() << "This test case only applies to RKP v3 and above. "
846 << "RKP version discovered: " << rpcHardwareInfo.versionNumber;
847 }
848 }
849};
850
851/**
Sean Thomas4991fdd2024-11-22 19:12:00 +0000852 * Check that ro.boot.vbmeta.device_state is not "locked" or ro.boot.verifiedbootstate
853 * is not "green" if and only if the mode on at least one certificate in the DICE chain
854 * is non-normal.
855 */
856TEST_P(CertificateRequestV2Test, unlockedBootloaderStatesImpliesNonnormalDiceChain) {
857 auto challenge = randomBytes(MAX_CHALLENGE_SIZE);
858 bytevec csr;
859 auto status =
860 provisionable_->generateCertificateRequestV2({} /* keysToSign */, challenge, &csr);
861 ASSERT_TRUE(status.isOk()) << status.getDescription();
862
863 auto isProper = isCsrWithProperDiceChain(csr, GetParam());
864 ASSERT_TRUE(isProper) << isProper.message();
865 if (!*isProper) {
866 GTEST_SKIP() << "Skipping test: Only a proper DICE chain has a mode set.";
867 }
868
869 auto nonNormalMode = hasNonNormalModeInDiceChain(csr, GetParam());
870 ASSERT_TRUE(nonNormalMode) << nonNormalMode.message();
871
872 auto deviceState = ::android::base::GetProperty("ro.boot.vbmeta.device_state", "");
873 auto verifiedBootState = ::android::base::GetProperty("ro.boot.verifiedbootstate", "");
874
875 ASSERT_EQ(deviceState != "locked" || verifiedBootState != "green", *nonNormalMode)
876 << "ro.boot.vbmeta.device_state = '" << deviceState
877 << "' and ro.boot.verifiedbootstate = '" << verifiedBootState << "', but it is "
878 << *nonNormalMode
879 << " that the DICE chain has a certificate with a non-normal mode set.";
880}
881
882/**
Tommy Chiufde3ad12023-03-17 05:58:28 +0000883 * Generate an empty certificate request with all possible length of challenge, and decrypt and
884 * verify the structure and content.
Tri Vo0d6204e2022-09-29 16:15:34 -0700885 */
Seth Mooreac1639f2023-04-27 11:14:11 -0700886// @VsrTest = 3.10-015
Tri Vo0d6204e2022-09-29 16:15:34 -0700887TEST_P(CertificateRequestV2Test, EmptyRequest) {
888 bytevec csr;
889
Tommy Chiufde3ad12023-03-17 05:58:28 +0000890 for (auto size = MIN_CHALLENGE_SIZE; size <= MAX_CHALLENGE_SIZE; size++) {
891 SCOPED_TRACE(testing::Message() << "challenge[" << size << "]");
892 auto challenge = randomBytes(size);
893 auto status =
894 provisionable_->generateCertificateRequestV2({} /* keysToSign */, challenge, &csr);
Frederick Mayle9891be02023-11-03 14:39:24 -0700895 ASSERT_TRUE(status.isOk()) << status.getDescription();
Tri Vo0d6204e2022-09-29 16:15:34 -0700896
Sean Thomas2d2385b2024-11-07 23:56:03 +0000897 auto result = verifyProductionCsr(cppbor::Array(), csr, rpcHardwareInfo, GetParam(),
Alice Wangf112ec92024-10-08 07:30:28 +0000898 challenge, isRkpVmInstance_);
Tommy Chiufde3ad12023-03-17 05:58:28 +0000899 ASSERT_TRUE(result) << result.message();
900 }
Tri Vo0d6204e2022-09-29 16:15:34 -0700901}
902
903/**
Tommy Chiufde3ad12023-03-17 05:58:28 +0000904 * Generate a non-empty certificate request with all possible length of challenge. Decrypt, parse
905 * and validate the contents.
Tri Vo0d6204e2022-09-29 16:15:34 -0700906 */
Seth Mooreac1639f2023-04-27 11:14:11 -0700907// @VsrTest = 3.10-015
Tri Vo0d6204e2022-09-29 16:15:34 -0700908TEST_P(CertificateRequestV2Test, NonEmptyRequest) {
909 generateKeys(false /* testMode */, 1 /* numKeys */);
910
911 bytevec csr;
912
Tommy Chiufde3ad12023-03-17 05:58:28 +0000913 for (auto size = MIN_CHALLENGE_SIZE; size <= MAX_CHALLENGE_SIZE; size++) {
914 SCOPED_TRACE(testing::Message() << "challenge[" << size << "]");
915 auto challenge = randomBytes(size);
916 auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge, &csr);
Frederick Mayle9891be02023-11-03 14:39:24 -0700917 ASSERT_TRUE(status.isOk()) << status.getDescription();
Tri Vo0d6204e2022-09-29 16:15:34 -0700918
Sean Thomas2d2385b2024-11-07 23:56:03 +0000919 auto result = verifyProductionCsr(cborKeysToSign_, csr, rpcHardwareInfo, GetParam(),
Alice Wangf112ec92024-10-08 07:30:28 +0000920 challenge, isRkpVmInstance_);
Tommy Chiufde3ad12023-03-17 05:58:28 +0000921 ASSERT_TRUE(result) << result.message();
922 }
923}
924
925/**
926 * Generate an empty certificate request with invalid size of challenge
927 */
928TEST_P(CertificateRequestV2Test, EmptyRequestWithInvalidChallengeFail) {
929 bytevec csr;
930
931 auto status = provisionable_->generateCertificateRequestV2(
932 /* keysToSign */ {}, randomBytes(MAX_CHALLENGE_SIZE + 1), &csr);
Frederick Mayle9891be02023-11-03 14:39:24 -0700933 EXPECT_FALSE(status.isOk()) << status.getDescription();
Tommy Chiufde3ad12023-03-17 05:58:28 +0000934 EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_FAILED);
Tri Vo0d6204e2022-09-29 16:15:34 -0700935}
936
937/**
Andrew Scullfb49ad22022-11-09 21:02:48 +0000938 * Generate a non-empty certificate request. Make sure contents are reproducible but allow for the
939 * signature to be different since algorithms including ECDSA P-256 can include a random value.
Tri Vo0d6204e2022-09-29 16:15:34 -0700940 */
Seth Mooreac1639f2023-04-27 11:14:11 -0700941// @VsrTest = 3.10-015
Tri Vo0d6204e2022-09-29 16:15:34 -0700942TEST_P(CertificateRequestV2Test, NonEmptyRequestReproducible) {
943 generateKeys(false /* testMode */, 1 /* numKeys */);
944
945 bytevec csr;
946
947 auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
Frederick Mayle9891be02023-11-03 14:39:24 -0700948 ASSERT_TRUE(status.isOk()) << status.getDescription();
Tri Vo0d6204e2022-09-29 16:15:34 -0700949
Sean Thomas2d2385b2024-11-07 23:56:03 +0000950 auto firstCsr = verifyProductionCsr(cborKeysToSign_, csr, rpcHardwareInfo, GetParam(),
Alice Wangf112ec92024-10-08 07:30:28 +0000951 challenge_, isRkpVmInstance_);
Andrew Scullfb49ad22022-11-09 21:02:48 +0000952 ASSERT_TRUE(firstCsr) << firstCsr.message();
Tri Vo0d6204e2022-09-29 16:15:34 -0700953
954 status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
Frederick Mayle9891be02023-11-03 14:39:24 -0700955 ASSERT_TRUE(status.isOk()) << status.getDescription();
Tri Vo0d6204e2022-09-29 16:15:34 -0700956
Sean Thomas2d2385b2024-11-07 23:56:03 +0000957 auto secondCsr = verifyProductionCsr(cborKeysToSign_, csr, rpcHardwareInfo, GetParam(),
Alice Wangf112ec92024-10-08 07:30:28 +0000958 challenge_, isRkpVmInstance_);
Andrew Scullfb49ad22022-11-09 21:02:48 +0000959 ASSERT_TRUE(secondCsr) << secondCsr.message();
Tri Vo0d6204e2022-09-29 16:15:34 -0700960
Andrew Scullfb49ad22022-11-09 21:02:48 +0000961 ASSERT_EQ(**firstCsr, **secondCsr);
Tri Vo0d6204e2022-09-29 16:15:34 -0700962}
963
964/**
965 * Generate a non-empty certificate request with multiple keys.
966 */
Seth Mooreac1639f2023-04-27 11:14:11 -0700967// @VsrTest = 3.10-015
Tri Vo0d6204e2022-09-29 16:15:34 -0700968TEST_P(CertificateRequestV2Test, NonEmptyRequestMultipleKeys) {
Tri Vo9cab73c2022-10-28 13:40:24 -0700969 generateKeys(false /* testMode */, rpcHardwareInfo.supportedNumKeysInCsr /* numKeys */);
Tri Vo0d6204e2022-09-29 16:15:34 -0700970
971 bytevec csr;
972
973 auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
Frederick Mayle9891be02023-11-03 14:39:24 -0700974 ASSERT_TRUE(status.isOk()) << status.getDescription();
Tri Vo0d6204e2022-09-29 16:15:34 -0700975
Sean Thomas2d2385b2024-11-07 23:56:03 +0000976 auto result = verifyProductionCsr(cborKeysToSign_, csr, rpcHardwareInfo, GetParam(), challenge_,
977 isRkpVmInstance_);
Tri Vo0d6204e2022-09-29 16:15:34 -0700978 ASSERT_TRUE(result) << result.message();
979}
980
981/**
982 * Generate a non-empty certificate request, but with the MAC corrupted on the keypair.
983 */
984TEST_P(CertificateRequestV2Test, NonEmptyRequestCorruptMac) {
985 generateKeys(false /* testMode */, 1 /* numKeys */);
986 auto result = corrupt_maced_key(keysToSign_[0]);
987 ASSERT_TRUE(result) << result.moveMessage();
988 MacedPublicKey keyWithCorruptMac = result.moveValue();
989
990 bytevec csr;
991 auto status =
992 provisionable_->generateCertificateRequestV2({keyWithCorruptMac}, challenge_, &csr);
Frederick Mayle9891be02023-11-03 14:39:24 -0700993 ASSERT_FALSE(status.isOk()) << status.getDescription();
Tri Vo0d6204e2022-09-29 16:15:34 -0700994 EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
995}
996
997/**
Andrew Scullf2ae1932023-04-24 19:09:09 +0000998 * Call generateCertificateRequest(). Make sure it's removed.
Tri Vo0d6204e2022-09-29 16:15:34 -0700999 */
Andrew Scullf2ae1932023-04-24 19:09:09 +00001000TEST_P(CertificateRequestV2Test, CertificateRequestV1Removed_prodMode) {
1001 bytevec keysToSignMac;
1002 DeviceInfo deviceInfo;
1003 ProtectedData protectedData;
1004 auto status = provisionable_->generateCertificateRequest(
1005 false /* testMode */, {} /* keysToSign */, {} /* EEK chain */, challenge_, &deviceInfo,
1006 &protectedData, &keysToSignMac);
Frederick Mayle9891be02023-11-03 14:39:24 -07001007 ASSERT_FALSE(status.isOk()) << status.getDescription();
Andrew Scullf2ae1932023-04-24 19:09:09 +00001008 EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_REMOVED);
Tri Vo0d6204e2022-09-29 16:15:34 -07001009}
1010
Andrew Scull95b31312023-03-27 19:16:07 +00001011/**
Andrew Scullf2ae1932023-04-24 19:09:09 +00001012 * Call generateCertificateRequest() in test mode. Make sure it's removed.
Andrew Scull95b31312023-03-27 19:16:07 +00001013 */
Andrew Scullf2ae1932023-04-24 19:09:09 +00001014TEST_P(CertificateRequestV2Test, CertificateRequestV1Removed_testMode) {
Andrew Scull95b31312023-03-27 19:16:07 +00001015 bytevec keysToSignMac;
1016 DeviceInfo deviceInfo;
1017 ProtectedData protectedData;
1018 auto status = provisionable_->generateCertificateRequest(
1019 true /* testMode */, {} /* keysToSign */, {} /* EEK chain */, challenge_, &deviceInfo,
1020 &protectedData, &keysToSignMac);
Frederick Mayle9891be02023-11-03 14:39:24 -07001021 ASSERT_FALSE(status.isOk()) << status.getDescription();
Andrew Scull95b31312023-03-27 19:16:07 +00001022 EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_REMOVED);
1023}
1024
Tri Voec50ee12023-02-14 16:29:53 -08001025void parse_root_of_trust(const vector<uint8_t>& attestation_cert,
1026 vector<uint8_t>* verified_boot_key, VerifiedBoot* verified_boot_state,
1027 bool* device_locked, vector<uint8_t>* verified_boot_hash) {
1028 X509_Ptr cert(parse_cert_blob(attestation_cert));
1029 ASSERT_TRUE(cert.get());
1030
1031 ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get());
1032 ASSERT_TRUE(attest_rec);
1033
1034 auto error = parse_root_of_trust(attest_rec->data, attest_rec->length, verified_boot_key,
1035 verified_boot_state, device_locked, verified_boot_hash);
1036 ASSERT_EQ(error, ErrorCode::OK);
1037}
1038
1039/**
1040 * Generate a CSR and verify DeviceInfo against IDs attested by KeyMint.
1041 */
Seth Mooreac1639f2023-04-27 11:14:11 -07001042// @VsrTest = 3.10-015
Tri Voec50ee12023-02-14 16:29:53 -08001043TEST_P(CertificateRequestV2Test, DeviceInfo) {
1044 // See if there is a matching IKeyMintDevice for this IRemotelyProvisionedComponent.
Sean Thomasa737a2d2024-11-20 17:25:53 +00001045 std::shared_ptr<IKeyMintDevice> keyMint = matchingKeyMintDevice(GetParam());
1046 if (!keyMint) {
Tri Voec50ee12023-02-14 16:29:53 -08001047 GTEST_SKIP() << "Skipping key use test as no matching KeyMint device found";
1048 return;
1049 }
1050 KeyMintHardwareInfo info;
1051 ASSERT_TRUE(keyMint->getHardwareInfo(&info).isOk());
1052
1053 // Get IDs attested by KeyMint.
1054 MacedPublicKey macedPubKey;
1055 bytevec privateKeyBlob;
1056 auto irpcStatus =
1057 provisionable_->generateEcdsaP256KeyPair(false, &macedPubKey, &privateKeyBlob);
1058 ASSERT_TRUE(irpcStatus.isOk());
1059
1060 AttestationKey attestKey;
1061 attestKey.keyBlob = std::move(privateKeyBlob);
1062 attestKey.issuerSubjectName = make_name_from_str("Android Keystore Key");
1063
1064 // Generate an ECDSA key that is attested by the generated P256 keypair.
1065 AuthorizationSet keyDesc = AuthorizationSetBuilder()
1066 .Authorization(TAG_NO_AUTH_REQUIRED)
1067 .EcdsaSigningKey(EcCurve::P_256)
1068 .AttestationChallenge("foo")
1069 .AttestationApplicationId("bar")
1070 .Digest(Digest::NONE)
1071 .SetDefaultValidity();
1072 KeyCreationResult creationResult;
1073 auto kmStatus = keyMint->generateKey(keyDesc.vector_data(), attestKey, &creationResult);
1074 ASSERT_TRUE(kmStatus.isOk());
1075
1076 vector<KeyCharacteristics> key_characteristics = std::move(creationResult.keyCharacteristics);
1077 vector<Certificate> key_cert_chain = std::move(creationResult.certificateChain);
1078 // We didn't provision the attestation key.
1079 ASSERT_EQ(key_cert_chain.size(), 1);
1080
1081 // Parse attested patch levels.
1082 auto auths = HwEnforcedAuthorizations(key_characteristics);
1083
1084 auto attestedSystemPatchLevel = auths.GetTagValue(TAG_OS_PATCHLEVEL);
1085 auto attestedVendorPatchLevel = auths.GetTagValue(TAG_VENDOR_PATCHLEVEL);
1086 auto attestedBootPatchLevel = auths.GetTagValue(TAG_BOOT_PATCHLEVEL);
1087
1088 ASSERT_TRUE(attestedSystemPatchLevel.has_value());
1089 ASSERT_TRUE(attestedVendorPatchLevel.has_value());
1090 ASSERT_TRUE(attestedBootPatchLevel.has_value());
1091
1092 // Parse attested AVB values.
1093 vector<uint8_t> key;
1094 VerifiedBoot attestedVbState;
1095 bool attestedBootloaderState;
1096 vector<uint8_t> attestedVbmetaDigest;
1097 parse_root_of_trust(key_cert_chain[0].encodedCertificate, &key, &attestedVbState,
1098 &attestedBootloaderState, &attestedVbmetaDigest);
1099
1100 // Get IDs from DeviceInfo.
1101 bytevec csr;
1102 irpcStatus =
1103 provisionable_->generateCertificateRequestV2({} /* keysToSign */, challenge_, &csr);
Frederick Mayle9891be02023-11-03 14:39:24 -07001104 ASSERT_TRUE(irpcStatus.isOk()) << irpcStatus.getDescription();
Tri Voec50ee12023-02-14 16:29:53 -08001105
Alice Wangf112ec92024-10-08 07:30:28 +00001106 auto result =
Sean Thomas2d2385b2024-11-07 23:56:03 +00001107 verifyProductionCsr(cppbor::Array(), csr, rpcHardwareInfo, GetParam(), challenge_);
Tri Voec50ee12023-02-14 16:29:53 -08001108 ASSERT_TRUE(result) << result.message();
1109
1110 std::unique_ptr<cppbor::Array> csrPayload = std::move(*result);
1111 ASSERT_TRUE(csrPayload);
Sean Thomasb85a71d2024-11-12 20:29:21 +00001112 ASSERT_TRUE(csrPayload->size() > 2);
Tri Voec50ee12023-02-14 16:29:53 -08001113
1114 auto deviceInfo = csrPayload->get(2)->asMap();
1115 ASSERT_TRUE(deviceInfo);
1116
1117 auto vbState = deviceInfo->get("vb_state")->asTstr();
1118 auto bootloaderState = deviceInfo->get("bootloader_state")->asTstr();
1119 auto vbmetaDigest = deviceInfo->get("vbmeta_digest")->asBstr();
1120 auto systemPatchLevel = deviceInfo->get("system_patch_level")->asUint();
1121 auto vendorPatchLevel = deviceInfo->get("vendor_patch_level")->asUint();
1122 auto bootPatchLevel = deviceInfo->get("boot_patch_level")->asUint();
1123 auto securityLevel = deviceInfo->get("security_level")->asTstr();
1124
1125 ASSERT_TRUE(vbState);
1126 ASSERT_TRUE(bootloaderState);
1127 ASSERT_TRUE(vbmetaDigest);
1128 ASSERT_TRUE(systemPatchLevel);
1129 ASSERT_TRUE(vendorPatchLevel);
1130 ASSERT_TRUE(bootPatchLevel);
1131 ASSERT_TRUE(securityLevel);
1132
Sean Thomasafbab602024-11-07 23:14:05 +00001133 auto kmDeviceName = deviceSuffix(GetParam());
Tri Voec50ee12023-02-14 16:29:53 -08001134
1135 // Compare DeviceInfo against IDs attested by KeyMint.
1136 ASSERT_TRUE((securityLevel->value() == "tee" && kmDeviceName == "default") ||
1137 (securityLevel->value() == "strongbox" && kmDeviceName == "strongbox"));
1138 ASSERT_TRUE((vbState->value() == "green" && attestedVbState == VerifiedBoot::VERIFIED) ||
1139 (vbState->value() == "yellow" && attestedVbState == VerifiedBoot::SELF_SIGNED) ||
1140 (vbState->value() == "orange" && attestedVbState == VerifiedBoot::UNVERIFIED));
1141 ASSERT_TRUE((bootloaderState->value() == "locked" && attestedBootloaderState) ||
1142 (bootloaderState->value() == "unlocked" && !attestedBootloaderState));
1143 ASSERT_EQ(vbmetaDigest->value(), attestedVbmetaDigest);
1144 ASSERT_EQ(systemPatchLevel->value(), attestedSystemPatchLevel.value());
1145 ASSERT_EQ(vendorPatchLevel->value(), attestedVendorPatchLevel.value());
1146 ASSERT_EQ(bootPatchLevel->value(), attestedBootPatchLevel.value());
1147}
1148
Tri Vo0d6204e2022-09-29 16:15:34 -07001149INSTANTIATE_REM_PROV_AIDL_TEST(CertificateRequestV2Test);
1150
Max Biresa9b3bb92022-11-21 23:02:09 -08001151using VsrRequirementTest = VtsRemotelyProvisionedComponentTests;
1152
1153INSTANTIATE_REM_PROV_AIDL_TEST(VsrRequirementTest);
1154
1155TEST_P(VsrRequirementTest, VsrEnforcementTest) {
1156 RpcHardwareInfo hwInfo;
1157 ASSERT_TRUE(provisionable_->getHardwareInfo(&hwInfo).isOk());
1158 int vsr_api_level = get_vsr_api_level();
1159 if (vsr_api_level < 34) {
1160 GTEST_SKIP() << "Applies only to VSR API level 34 or newer, this device is: "
1161 << vsr_api_level;
1162 }
1163 EXPECT_GE(hwInfo.versionNumber, 3)
1164 << "VSR 14+ requires IRemotelyProvisionedComponent v3 or newer.";
1165}
1166
Shawn Willden274bb552020-09-30 22:39:22 -06001167} // namespace aidl::android::hardware::security::keymint::test