blob: 573f10bc5bdef48237a087ebd988bf14047b6eec [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>
Shawn Willden274bb552020-09-30 22:39:22 -060026#include <cppbor_parse.h>
Shawn Willden274bb552020-09-30 22:39:22 -060027#include <gmock/gmock.h>
Max Bires9704ff62021-04-07 11:12:01 -070028#include <keymaster/cppcose/cppcose.h>
Shawn Willden274bb552020-09-30 22:39:22 -060029#include <keymaster/keymaster_configuration.h>
David Drysdalef0d516d2021-03-22 07:51:43 +000030#include <keymint_support/authorization_set.h>
31#include <openssl/ec.h>
32#include <openssl/ec_key.h>
33#include <openssl/x509.h>
Shawn Willden274bb552020-09-30 22:39:22 -060034#include <remote_prov/remote_prov_utils.h>
Max Bires757ed422022-09-07 16:20:31 -070035#include <optional>
Seth Moorefc86bf42021-12-09 14:07:04 -080036#include <set>
Seth Moore42c11332021-07-02 15:38:17 -070037#include <vector>
Shawn Willden274bb552020-09-30 22:39:22 -060038
David Drysdalef0d516d2021-03-22 07:51:43 +000039#include "KeyMintAidlTestBase.h"
40
Shawn Willden274bb552020-09-30 22:39:22 -060041namespace aidl::android::hardware::security::keymint::test {
42
43using ::std::string;
44using ::std::vector;
45
46namespace {
47
Seth Moorefc86bf42021-12-09 14:07:04 -080048constexpr int32_t VERSION_WITH_UNIQUE_ID_SUPPORT = 2;
Tri Vo0d6204e2022-09-29 16:15:34 -070049constexpr int32_t VERSION_WITHOUT_TEST_MODE = 3;
Seth Moorefc86bf42021-12-09 14:07:04 -080050
Shawn Willden274bb552020-09-30 22:39:22 -060051#define INSTANTIATE_REM_PROV_AIDL_TEST(name) \
Seth Moore6305e232021-07-27 14:20:17 -070052 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(name); \
Shawn Willden274bb552020-09-30 22:39:22 -060053 INSTANTIATE_TEST_SUITE_P( \
54 PerInstance, name, \
55 testing::ValuesIn(VtsRemotelyProvisionedComponentTests::build_params()), \
56 ::android::PrintInstanceNameToString)
57
Seth Moorefc86bf42021-12-09 14:07:04 -080058using ::android::sp;
Shawn Willden274bb552020-09-30 22:39:22 -060059using bytevec = std::vector<uint8_t>;
60using testing::MatchesRegex;
61using namespace remote_prov;
62using namespace keymaster;
63
64bytevec string_to_bytevec(const char* s) {
65 const uint8_t* p = reinterpret_cast<const uint8_t*>(s);
66 return bytevec(p, p + strlen(s));
67}
68
David Drysdalee99ed862021-03-15 16:43:06 +000069ErrMsgOr<MacedPublicKey> corrupt_maced_key(const MacedPublicKey& macedPubKey) {
70 auto [coseMac0, _, mac0ParseErr] = cppbor::parse(macedPubKey.macedKey);
71 if (!coseMac0 || coseMac0->asArray()->size() != kCoseMac0EntryCount) {
72 return "COSE Mac0 parse failed";
73 }
74 auto protParams = coseMac0->asArray()->get(kCoseMac0ProtectedParams)->asBstr();
75 auto unprotParams = coseMac0->asArray()->get(kCoseMac0UnprotectedParams)->asMap();
76 auto payload = coseMac0->asArray()->get(kCoseMac0Payload)->asBstr();
77 auto tag = coseMac0->asArray()->get(kCoseMac0Tag)->asBstr();
78 if (!protParams || !unprotParams || !payload || !tag) {
79 return "Invalid COSE_Sign1: missing content";
80 }
81 auto corruptMac0 = cppbor::Array();
82 corruptMac0.add(protParams->clone());
83 corruptMac0.add(unprotParams->clone());
84 corruptMac0.add(payload->clone());
85 vector<uint8_t> tagData = tag->value();
86 tagData[0] ^= 0x08;
87 tagData[tagData.size() - 1] ^= 0x80;
88 corruptMac0.add(cppbor::Bstr(tagData));
89
90 return MacedPublicKey{corruptMac0.encode()};
91}
92
David Drysdalecceca9f2021-03-12 15:49:47 +000093ErrMsgOr<cppbor::Array> corrupt_sig(const cppbor::Array* coseSign1) {
94 if (coseSign1->size() != kCoseSign1EntryCount) {
95 return "Invalid COSE_Sign1, wrong entry count";
96 }
97 const cppbor::Bstr* protectedParams = coseSign1->get(kCoseSign1ProtectedParams)->asBstr();
98 const cppbor::Map* unprotectedParams = coseSign1->get(kCoseSign1UnprotectedParams)->asMap();
99 const cppbor::Bstr* payload = coseSign1->get(kCoseSign1Payload)->asBstr();
100 const cppbor::Bstr* signature = coseSign1->get(kCoseSign1Signature)->asBstr();
101 if (!protectedParams || !unprotectedParams || !payload || !signature) {
102 return "Invalid COSE_Sign1: missing content";
103 }
104
105 auto corruptSig = cppbor::Array();
106 corruptSig.add(protectedParams->clone());
107 corruptSig.add(unprotectedParams->clone());
108 corruptSig.add(payload->clone());
109 vector<uint8_t> sigData = signature->value();
110 sigData[0] ^= 0x08;
111 corruptSig.add(cppbor::Bstr(sigData));
112
113 return std::move(corruptSig);
114}
115
Seth Moore19acbe92021-06-23 15:15:52 -0700116ErrMsgOr<bytevec> corrupt_sig_chain(const bytevec& encodedEekChain, int which) {
117 auto [chain, _, parseErr] = cppbor::parse(encodedEekChain);
David Drysdalecceca9f2021-03-12 15:49:47 +0000118 if (!chain || !chain->asArray()) {
119 return "EekChain parse failed";
120 }
121
122 cppbor::Array* eekChain = chain->asArray();
123 if (which >= eekChain->size()) {
124 return "selected sig out of range";
125 }
126 auto corruptChain = cppbor::Array();
127
128 for (int ii = 0; ii < eekChain->size(); ++ii) {
129 if (ii == which) {
130 auto sig = corrupt_sig(eekChain->get(which)->asArray());
131 if (!sig) {
132 return "Failed to build corrupted signature" + sig.moveMessage();
133 }
134 corruptChain.add(sig.moveValue());
135 } else {
136 corruptChain.add(eekChain->get(ii)->clone());
137 }
138 }
Seth Moore19acbe92021-06-23 15:15:52 -0700139 return corruptChain.encode();
David Drysdalecceca9f2021-03-12 15:49:47 +0000140}
141
David Drysdale4d3c2982021-03-31 18:21:40 +0100142string device_suffix(const string& name) {
143 size_t pos = name.find('/');
144 if (pos == string::npos) {
145 return name;
146 }
147 return name.substr(pos + 1);
148}
149
150bool matching_keymint_device(const string& rp_name, std::shared_ptr<IKeyMintDevice>* keyMint) {
151 string rp_suffix = device_suffix(rp_name);
152
153 vector<string> km_names = ::android::getAidlHalInstanceNames(IKeyMintDevice::descriptor);
154 for (const string& km_name : km_names) {
155 // If the suffix of the KeyMint instance equals the suffix of the
156 // RemotelyProvisionedComponent instance, assume they match.
157 if (device_suffix(km_name) == rp_suffix && AServiceManager_isDeclared(km_name.c_str())) {
158 ::ndk::SpAIBinder binder(AServiceManager_waitForService(km_name.c_str()));
159 *keyMint = IKeyMintDevice::fromBinder(binder);
160 return true;
161 }
162 }
163 return false;
164}
165
Shawn Willden274bb552020-09-30 22:39:22 -0600166} // namespace
167
168class VtsRemotelyProvisionedComponentTests : public testing::TestWithParam<std::string> {
169 public:
170 virtual void SetUp() override {
171 if (AServiceManager_isDeclared(GetParam().c_str())) {
172 ::ndk::SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str()));
173 provisionable_ = IRemotelyProvisionedComponent::fromBinder(binder);
174 }
175 ASSERT_NE(provisionable_, nullptr);
subrahmanyamanfb213d62022-02-02 23:10:55 +0000176 ASSERT_TRUE(provisionable_->getHardwareInfo(&rpcHardwareInfo).isOk());
Shawn Willden274bb552020-09-30 22:39:22 -0600177 }
178
179 static vector<string> build_params() {
180 auto params = ::android::getAidlHalInstanceNames(IRemotelyProvisionedComponent::descriptor);
181 return params;
182 }
183
184 protected:
185 std::shared_ptr<IRemotelyProvisionedComponent> provisionable_;
subrahmanyamanfb213d62022-02-02 23:10:55 +0000186 RpcHardwareInfo rpcHardwareInfo;
Shawn Willden274bb552020-09-30 22:39:22 -0600187};
188
Seth Moorefc86bf42021-12-09 14:07:04 -0800189/**
190 * Verify that every implementation reports a different unique id.
191 */
192TEST(NonParameterizedTests, eachRpcHasAUniqueId) {
193 std::set<std::string> uniqueIds;
194 for (auto hal : ::android::getAidlHalInstanceNames(IRemotelyProvisionedComponent::descriptor)) {
195 ASSERT_TRUE(AServiceManager_isDeclared(hal.c_str()));
196 ::ndk::SpAIBinder binder(AServiceManager_waitForService(hal.c_str()));
197 std::shared_ptr<IRemotelyProvisionedComponent> rpc =
198 IRemotelyProvisionedComponent::fromBinder(binder);
199 ASSERT_NE(rpc, nullptr);
200
201 RpcHardwareInfo hwInfo;
202 ASSERT_TRUE(rpc->getHardwareInfo(&hwInfo).isOk());
203
Tri Vodd12c482022-10-12 22:41:28 +0000204 if (hwInfo.versionNumber >= VERSION_WITH_UNIQUE_ID_SUPPORT) {
Seth Moorefc86bf42021-12-09 14:07:04 -0800205 ASSERT_TRUE(hwInfo.uniqueId);
206 auto [_, wasInserted] = uniqueIds.insert(*hwInfo.uniqueId);
207 EXPECT_TRUE(wasInserted);
208 } else {
209 ASSERT_FALSE(hwInfo.uniqueId);
210 }
211 }
212}
213
214using GetHardwareInfoTests = VtsRemotelyProvisionedComponentTests;
215
216INSTANTIATE_REM_PROV_AIDL_TEST(GetHardwareInfoTests);
217
218/**
219 * Verify that a valid curve is reported by the implementation.
220 */
221TEST_P(GetHardwareInfoTests, supportsValidCurve) {
222 RpcHardwareInfo hwInfo;
223 ASSERT_TRUE(provisionable_->getHardwareInfo(&hwInfo).isOk());
224
225 const std::set<int> validCurves = {RpcHardwareInfo::CURVE_P256, RpcHardwareInfo::CURVE_25519};
Hasini Gunasinghe666b2712023-01-05 21:35:51 +0000226 // First check for the implementations that supports only IRPC V3+.
227 if (rpcHardwareInfo.versionNumber >= VERSION_WITHOUT_TEST_MODE) {
228 bytevec keysToSignMac;
229 DeviceInfo deviceInfo;
230 ProtectedData protectedData;
231 auto status = provisionable_->generateCertificateRequest(false, {}, {}, {}, &deviceInfo,
232 &protectedData, &keysToSignMac);
233 if (!status.isOk() &&
234 (status.getServiceSpecificError() == BnRemotelyProvisionedComponent::STATUS_REMOVED)) {
235 ASSERT_EQ(hwInfo.supportedEekCurve, RpcHardwareInfo::CURVE_NONE)
236 << "Invalid curve: " << hwInfo.supportedEekCurve;
237 return;
238 }
239 }
Seth Moorefc86bf42021-12-09 14:07:04 -0800240 ASSERT_EQ(validCurves.count(hwInfo.supportedEekCurve), 1)
241 << "Invalid curve: " << hwInfo.supportedEekCurve;
242}
243
244/**
245 * Verify that the unique id is within the length limits as described in RpcHardwareInfo.aidl.
246 */
247TEST_P(GetHardwareInfoTests, uniqueId) {
Tri Vodd12c482022-10-12 22:41:28 +0000248 if (rpcHardwareInfo.versionNumber < VERSION_WITH_UNIQUE_ID_SUPPORT) {
Seth Moorefc86bf42021-12-09 14:07:04 -0800249 return;
250 }
251
252 RpcHardwareInfo hwInfo;
253 ASSERT_TRUE(provisionable_->getHardwareInfo(&hwInfo).isOk());
254 ASSERT_TRUE(hwInfo.uniqueId);
255 EXPECT_GE(hwInfo.uniqueId->size(), 1);
256 EXPECT_LE(hwInfo.uniqueId->size(), 32);
257}
258
Tri Vo9cab73c2022-10-28 13:40:24 -0700259/**
260 * Verify implementation supports at least MIN_SUPPORTED_NUM_KEYS_IN_CSR keys in a CSR.
261 */
262TEST_P(GetHardwareInfoTests, supportedNumKeysInCsr) {
263 if (rpcHardwareInfo.versionNumber < VERSION_WITHOUT_TEST_MODE) {
264 return;
265 }
266
267 RpcHardwareInfo hwInfo;
268 ASSERT_TRUE(provisionable_->getHardwareInfo(&hwInfo).isOk());
269 ASSERT_GE(hwInfo.supportedNumKeysInCsr, RpcHardwareInfo::MIN_SUPPORTED_NUM_KEYS_IN_CSR);
270}
271
Shawn Willden274bb552020-09-30 22:39:22 -0600272using GenerateKeyTests = VtsRemotelyProvisionedComponentTests;
273
274INSTANTIATE_REM_PROV_AIDL_TEST(GenerateKeyTests);
275
276/**
David Drysdalef0d516d2021-03-22 07:51:43 +0000277 * Generate and validate a production-mode key. MAC tag can't be verified, but
278 * the private key blob should be usable in KeyMint operations.
Shawn Willden274bb552020-09-30 22:39:22 -0600279 */
Max Bires126869a2021-02-21 18:32:59 -0800280TEST_P(GenerateKeyTests, generateEcdsaP256Key_prodMode) {
Shawn Willden274bb552020-09-30 22:39:22 -0600281 MacedPublicKey macedPubKey;
282 bytevec privateKeyBlob;
283 bool testMode = false;
284 auto status = provisionable_->generateEcdsaP256KeyPair(testMode, &macedPubKey, &privateKeyBlob);
285 ASSERT_TRUE(status.isOk());
David Drysdalef0d516d2021-03-22 07:51:43 +0000286 vector<uint8_t> coseKeyData;
Tri Vob0b8acc2022-11-30 16:22:23 -0800287 check_maced_pubkey(macedPubKey, testMode, &coseKeyData);
David Drysdale4d3c2982021-03-31 18:21:40 +0100288}
289
290/**
291 * Generate and validate a production-mode key, then use it as a KeyMint attestation key.
292 */
293TEST_P(GenerateKeyTests, generateAndUseEcdsaP256Key_prodMode) {
294 // See if there is a matching IKeyMintDevice for this IRemotelyProvisionedComponent.
295 std::shared_ptr<IKeyMintDevice> keyMint;
296 if (!matching_keymint_device(GetParam(), &keyMint)) {
297 // No matching IKeyMintDevice.
298 GTEST_SKIP() << "Skipping key use test as no matching KeyMint device found";
299 return;
300 }
301 KeyMintHardwareInfo info;
302 ASSERT_TRUE(keyMint->getHardwareInfo(&info).isOk());
303
304 MacedPublicKey macedPubKey;
305 bytevec privateKeyBlob;
306 bool testMode = false;
307 auto status = provisionable_->generateEcdsaP256KeyPair(testMode, &macedPubKey, &privateKeyBlob);
308 ASSERT_TRUE(status.isOk());
309 vector<uint8_t> coseKeyData;
Tri Vob0b8acc2022-11-30 16:22:23 -0800310 check_maced_pubkey(macedPubKey, testMode, &coseKeyData);
David Drysdale4d3c2982021-03-31 18:21:40 +0100311
David Drysdalef0d516d2021-03-22 07:51:43 +0000312 AttestationKey attestKey;
313 attestKey.keyBlob = std::move(privateKeyBlob);
314 attestKey.issuerSubjectName = make_name_from_str("Android Keystore Key");
Shawn Willden274bb552020-09-30 22:39:22 -0600315
David Drysdalef0d516d2021-03-22 07:51:43 +0000316 // Generate an ECDSA key that is attested by the generated P256 keypair.
317 AuthorizationSet keyDesc = AuthorizationSetBuilder()
318 .Authorization(TAG_NO_AUTH_REQUIRED)
David Drysdale915ce252021-10-14 15:17:36 +0100319 .EcdsaSigningKey(EcCurve::P_256)
David Drysdalef0d516d2021-03-22 07:51:43 +0000320 .AttestationChallenge("foo")
321 .AttestationApplicationId("bar")
322 .Digest(Digest::NONE)
323 .SetDefaultValidity();
324 KeyCreationResult creationResult;
325 auto result = keyMint->generateKey(keyDesc.vector_data(), attestKey, &creationResult);
326 ASSERT_TRUE(result.isOk());
327 vector<uint8_t> attested_key_blob = std::move(creationResult.keyBlob);
328 vector<KeyCharacteristics> attested_key_characteristics =
329 std::move(creationResult.keyCharacteristics);
330 vector<Certificate> attested_key_cert_chain = std::move(creationResult.certificateChain);
331 EXPECT_EQ(attested_key_cert_chain.size(), 1);
332
David Drysdale7dff4fc2021-12-10 10:10:52 +0000333 int32_t aidl_version = 0;
334 ASSERT_TRUE(keyMint->getInterfaceVersion(&aidl_version).isOk());
David Drysdalef0d516d2021-03-22 07:51:43 +0000335 AuthorizationSet hw_enforced = HwEnforcedAuthorizations(attested_key_characteristics);
336 AuthorizationSet sw_enforced = SwEnforcedAuthorizations(attested_key_characteristics);
David Drysdale7dff4fc2021-12-10 10:10:52 +0000337 EXPECT_TRUE(verify_attestation_record(aidl_version, "foo", "bar", sw_enforced, hw_enforced,
David Drysdalef0d516d2021-03-22 07:51:43 +0000338 info.securityLevel,
339 attested_key_cert_chain[0].encodedCertificate));
340
341 // Attestation by itself is not valid (last entry is not self-signed).
342 EXPECT_FALSE(ChainSignaturesAreValid(attested_key_cert_chain));
343
344 // The signature over the attested key should correspond to the P256 public key.
345 X509_Ptr key_cert(parse_cert_blob(attested_key_cert_chain[0].encodedCertificate));
346 ASSERT_TRUE(key_cert.get());
347 EVP_PKEY_Ptr signing_pubkey;
348 p256_pub_key(coseKeyData, &signing_pubkey);
349 ASSERT_TRUE(signing_pubkey.get());
350
351 ASSERT_TRUE(X509_verify(key_cert.get(), signing_pubkey.get()))
352 << "Verification of attested certificate failed "
353 << "OpenSSL error string: " << ERR_error_string(ERR_get_error(), NULL);
Shawn Willden274bb552020-09-30 22:39:22 -0600354}
355
356/**
357 * Generate and validate a test-mode key.
358 */
Max Bires126869a2021-02-21 18:32:59 -0800359TEST_P(GenerateKeyTests, generateEcdsaP256Key_testMode) {
Shawn Willden274bb552020-09-30 22:39:22 -0600360 MacedPublicKey macedPubKey;
361 bytevec privateKeyBlob;
362 bool testMode = true;
363 auto status = provisionable_->generateEcdsaP256KeyPair(testMode, &macedPubKey, &privateKeyBlob);
364 ASSERT_TRUE(status.isOk());
Tri Vob0b8acc2022-11-30 16:22:23 -0800365 check_maced_pubkey(macedPubKey, testMode, nullptr);
Shawn Willden274bb552020-09-30 22:39:22 -0600366}
367
Tri Vo0d6204e2022-09-29 16:15:34 -0700368class CertificateRequestTestBase : public VtsRemotelyProvisionedComponentTests {
Shawn Willden274bb552020-09-30 22:39:22 -0600369 protected:
Tri Vo0d6204e2022-09-29 16:15:34 -0700370 CertificateRequestTestBase()
371 : eekId_(string_to_bytevec("eekid")), challenge_(randomBytes(64)) {}
David Drysdalecceca9f2021-03-12 15:49:47 +0000372
Seth Moore19acbe92021-06-23 15:15:52 -0700373 void generateTestEekChain(size_t eekLength) {
subrahmanyamanfb213d62022-02-02 23:10:55 +0000374 auto chain = generateEekChain(rpcHardwareInfo.supportedEekCurve, eekLength, eekId_);
David Drysdale08696a72022-03-10 10:43:25 +0000375 ASSERT_TRUE(chain) << chain.message();
Seth Moore19acbe92021-06-23 15:15:52 -0700376 if (chain) testEekChain_ = chain.moveValue();
377 testEekLength_ = eekLength;
Shawn Willden274bb552020-09-30 22:39:22 -0600378 }
379
380 void generateKeys(bool testMode, size_t numKeys) {
381 keysToSign_ = std::vector<MacedPublicKey>(numKeys);
382 cborKeysToSign_ = cppbor::Array();
383
384 for (auto& key : keysToSign_) {
385 bytevec privateKeyBlob;
386 auto status = provisionable_->generateEcdsaP256KeyPair(testMode, &key, &privateKeyBlob);
387 ASSERT_TRUE(status.isOk()) << status.getMessage();
388
David Drysdalec8400772021-03-11 12:35:11 +0000389 vector<uint8_t> payload_value;
Tri Vob0b8acc2022-11-30 16:22:23 -0800390 check_maced_pubkey(key, testMode, &payload_value);
David Drysdalec8400772021-03-11 12:35:11 +0000391 cborKeysToSign_.add(cppbor::EncodedItem(payload_value));
Shawn Willden274bb552020-09-30 22:39:22 -0600392 }
393 }
394
395 bytevec eekId_;
Seth Moore19acbe92021-06-23 15:15:52 -0700396 size_t testEekLength_;
397 EekChain testEekChain_;
David Drysdalec8400772021-03-11 12:35:11 +0000398 bytevec challenge_;
Shawn Willden274bb552020-09-30 22:39:22 -0600399 std::vector<MacedPublicKey> keysToSign_;
400 cppbor::Array cborKeysToSign_;
401};
402
Tri Vo0d6204e2022-09-29 16:15:34 -0700403class CertificateRequestTest : public CertificateRequestTestBase {
404 protected:
405 void SetUp() override {
406 CertificateRequestTestBase::SetUp();
Andrew Scull1bcb6022022-12-27 10:43:27 +0000407 ASSERT_FALSE(HasFatalFailure());
Tri Vo0d6204e2022-09-29 16:15:34 -0700408
409 if (rpcHardwareInfo.versionNumber >= VERSION_WITHOUT_TEST_MODE) {
Tri Vob0b8acc2022-11-30 16:22:23 -0800410 bytevec keysToSignMac;
411 DeviceInfo deviceInfo;
412 ProtectedData protectedData;
413 auto status = provisionable_->generateCertificateRequest(
414 false, {}, {}, {}, &deviceInfo, &protectedData, &keysToSignMac);
415 if (!status.isOk() && (status.getServiceSpecificError() ==
416 BnRemotelyProvisionedComponent::STATUS_REMOVED)) {
417 GTEST_SKIP() << "This test case applies to RKP v3+ only if "
418 << "generateCertificateRequest() is implemented.";
419 }
Tri Vo0d6204e2022-09-29 16:15:34 -0700420 }
421 }
422};
423
Shawn Willden274bb552020-09-30 22:39:22 -0600424/**
425 * Generate an empty certificate request in test mode, and decrypt and verify the structure and
426 * content.
427 */
Max Bires126869a2021-02-21 18:32:59 -0800428TEST_P(CertificateRequestTest, EmptyRequest_testMode) {
Shawn Willden274bb552020-09-30 22:39:22 -0600429 bool testMode = true;
David Drysdalecceca9f2021-03-12 15:49:47 +0000430 for (size_t eekLength : {2, 3, 7}) {
431 SCOPED_TRACE(testing::Message() << "EEK of length " << eekLength);
Seth Moore19acbe92021-06-23 15:15:52 -0700432 generateTestEekChain(eekLength);
Shawn Willden274bb552020-09-30 22:39:22 -0600433
David Drysdalecceca9f2021-03-12 15:49:47 +0000434 bytevec keysToSignMac;
435 DeviceInfo deviceInfo;
436 ProtectedData protectedData;
437 auto status = provisionable_->generateCertificateRequest(
Seth Moore19acbe92021-06-23 15:15:52 -0700438 testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
David Drysdalecceca9f2021-03-12 15:49:47 +0000439 &protectedData, &keysToSignMac);
440 ASSERT_TRUE(status.isOk()) << status.getMessage();
441
Seth Moore2fc6f832022-09-13 16:10:11 -0700442 auto result = verifyProductionProtectedData(
443 deviceInfo, cppbor::Array(), keysToSignMac, protectedData, testEekChain_, eekId_,
444 rpcHardwareInfo.supportedEekCurve, provisionable_.get(), challenge_);
445 ASSERT_TRUE(result) << result.message();
David Drysdalecceca9f2021-03-12 15:49:47 +0000446 }
Shawn Willden274bb552020-09-30 22:39:22 -0600447}
448
449/**
Seth Moore42c11332021-07-02 15:38:17 -0700450 * Ensure that test mode outputs a unique BCC root key every time we request a
451 * certificate request. Else, it's possible that the test mode API could be used
452 * to fingerprint devices. Only the GEEK should be allowed to decrypt the same
453 * device public key multiple times.
454 */
455TEST_P(CertificateRequestTest, NewKeyPerCallInTestMode) {
456 constexpr bool testMode = true;
Seth Moore42c11332021-07-02 15:38:17 -0700457
458 bytevec keysToSignMac;
459 DeviceInfo deviceInfo;
460 ProtectedData protectedData;
subrahmanyamanfb213d62022-02-02 23:10:55 +0000461 generateTestEekChain(3);
Seth Moore42c11332021-07-02 15:38:17 -0700462 auto status = provisionable_->generateCertificateRequest(
Seth Moore19acbe92021-06-23 15:15:52 -0700463 testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
464 &protectedData, &keysToSignMac);
Seth Moore42c11332021-07-02 15:38:17 -0700465 ASSERT_TRUE(status.isOk()) << status.getMessage();
466
Seth Moore2fc6f832022-09-13 16:10:11 -0700467 auto firstBcc = verifyProductionProtectedData(
468 deviceInfo, /*keysToSign=*/cppbor::Array(), keysToSignMac, protectedData, testEekChain_,
469 eekId_, rpcHardwareInfo.supportedEekCurve, provisionable_.get(), challenge_);
470 ASSERT_TRUE(firstBcc) << firstBcc.message();
Seth Moore42c11332021-07-02 15:38:17 -0700471
Seth Moore19acbe92021-06-23 15:15:52 -0700472 status = provisionable_->generateCertificateRequest(
473 testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
474 &protectedData, &keysToSignMac);
Seth Moore42c11332021-07-02 15:38:17 -0700475 ASSERT_TRUE(status.isOk()) << status.getMessage();
476
Seth Moore2fc6f832022-09-13 16:10:11 -0700477 auto secondBcc = verifyProductionProtectedData(
478 deviceInfo, /*keysToSign=*/cppbor::Array(), keysToSignMac, protectedData, testEekChain_,
479 eekId_, rpcHardwareInfo.supportedEekCurve, provisionable_.get(), challenge_);
480 ASSERT_TRUE(secondBcc) << secondBcc.message();
Seth Moore42c11332021-07-02 15:38:17 -0700481
482 // Verify that none of the keys in the first BCC are repeated in the second one.
Seth Moore2fc6f832022-09-13 16:10:11 -0700483 for (const auto& i : *firstBcc) {
484 for (auto& j : *secondBcc) {
Seth Moore42c11332021-07-02 15:38:17 -0700485 ASSERT_THAT(i.pubKey, testing::Not(testing::ElementsAreArray(j.pubKey)))
486 << "Found a repeated pubkey in two generateCertificateRequest test mode calls";
487 }
488 }
489}
490
491/**
Seth Moore19acbe92021-06-23 15:15:52 -0700492 * Generate an empty certificate request in prod mode. This test must be run explicitly, and
493 * is not run by default. Not all devices are GMS devices, and therefore they do not all
494 * trust the Google EEK root.
Shawn Willden274bb552020-09-30 22:39:22 -0600495 */
Seth Moore19acbe92021-06-23 15:15:52 -0700496TEST_P(CertificateRequestTest, DISABLED_EmptyRequest_prodMode) {
Shawn Willden274bb552020-09-30 22:39:22 -0600497 bool testMode = false;
David Drysdalecceca9f2021-03-12 15:49:47 +0000498
Seth Moore19acbe92021-06-23 15:15:52 -0700499 bytevec keysToSignMac;
500 DeviceInfo deviceInfo;
501 ProtectedData protectedData;
502 auto status = provisionable_->generateCertificateRequest(
subrahmanyamanfb213d62022-02-02 23:10:55 +0000503 testMode, {} /* keysToSign */, getProdEekChain(rpcHardwareInfo.supportedEekCurve),
504 challenge_, &deviceInfo, &protectedData, &keysToSignMac);
Seth Moore19acbe92021-06-23 15:15:52 -0700505 EXPECT_TRUE(status.isOk());
Shawn Willden274bb552020-09-30 22:39:22 -0600506}
507
508/**
509 * Generate a non-empty certificate request in test mode. Decrypt, parse and validate the contents.
510 */
Max Bires126869a2021-02-21 18:32:59 -0800511TEST_P(CertificateRequestTest, NonEmptyRequest_testMode) {
Shawn Willden274bb552020-09-30 22:39:22 -0600512 bool testMode = true;
513 generateKeys(testMode, 4 /* numKeys */);
514
David Drysdalecceca9f2021-03-12 15:49:47 +0000515 for (size_t eekLength : {2, 3, 7}) {
516 SCOPED_TRACE(testing::Message() << "EEK of length " << eekLength);
Seth Moore19acbe92021-06-23 15:15:52 -0700517 generateTestEekChain(eekLength);
Shawn Willden274bb552020-09-30 22:39:22 -0600518
David Drysdalecceca9f2021-03-12 15:49:47 +0000519 bytevec keysToSignMac;
520 DeviceInfo deviceInfo;
521 ProtectedData protectedData;
522 auto status = provisionable_->generateCertificateRequest(
Seth Moore19acbe92021-06-23 15:15:52 -0700523 testMode, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo, &protectedData,
David Drysdalecceca9f2021-03-12 15:49:47 +0000524 &keysToSignMac);
525 ASSERT_TRUE(status.isOk()) << status.getMessage();
526
Seth Moore2fc6f832022-09-13 16:10:11 -0700527 auto result = verifyProductionProtectedData(
528 deviceInfo, cborKeysToSign_, keysToSignMac, protectedData, testEekChain_, eekId_,
529 rpcHardwareInfo.supportedEekCurve, provisionable_.get(), challenge_);
530 ASSERT_TRUE(result) << result.message();
David Drysdalecceca9f2021-03-12 15:49:47 +0000531 }
Shawn Willden274bb552020-09-30 22:39:22 -0600532}
533
534/**
Seth Moore19acbe92021-06-23 15:15:52 -0700535 * Generate a non-empty certificate request in prod mode. This test must be run explicitly, and
536 * is not run by default. Not all devices are GMS devices, and therefore they do not all
537 * trust the Google EEK root.
Shawn Willden274bb552020-09-30 22:39:22 -0600538 */
Seth Moore19acbe92021-06-23 15:15:52 -0700539TEST_P(CertificateRequestTest, DISABLED_NonEmptyRequest_prodMode) {
Shawn Willden274bb552020-09-30 22:39:22 -0600540 bool testMode = false;
541 generateKeys(testMode, 4 /* numKeys */);
542
Seth Moore19acbe92021-06-23 15:15:52 -0700543 bytevec keysToSignMac;
544 DeviceInfo deviceInfo;
545 ProtectedData protectedData;
546 auto status = provisionable_->generateCertificateRequest(
subrahmanyamanfb213d62022-02-02 23:10:55 +0000547 testMode, keysToSign_, getProdEekChain(rpcHardwareInfo.supportedEekCurve), challenge_,
548 &deviceInfo, &protectedData, &keysToSignMac);
Seth Moore19acbe92021-06-23 15:15:52 -0700549 EXPECT_TRUE(status.isOk());
David Drysdalecceca9f2021-03-12 15:49:47 +0000550}
551
552/**
David Drysdalee99ed862021-03-15 16:43:06 +0000553 * Generate a non-empty certificate request in test mode, but with the MAC corrupted on the keypair.
554 */
555TEST_P(CertificateRequestTest, NonEmptyRequestCorruptMac_testMode) {
556 bool testMode = true;
557 generateKeys(testMode, 1 /* numKeys */);
David Drysdale08696a72022-03-10 10:43:25 +0000558 auto result = corrupt_maced_key(keysToSign_[0]);
559 ASSERT_TRUE(result) << result.moveMessage();
560 MacedPublicKey keyWithCorruptMac = result.moveValue();
David Drysdalee99ed862021-03-15 16:43:06 +0000561
562 bytevec keysToSignMac;
563 DeviceInfo deviceInfo;
564 ProtectedData protectedData;
subrahmanyamanfb213d62022-02-02 23:10:55 +0000565 generateTestEekChain(3);
David Drysdalee99ed862021-03-15 16:43:06 +0000566 auto status = provisionable_->generateCertificateRequest(
Seth Moore19acbe92021-06-23 15:15:52 -0700567 testMode, {keyWithCorruptMac}, testEekChain_.chain, challenge_, &deviceInfo,
568 &protectedData, &keysToSignMac);
David Drysdalee99ed862021-03-15 16:43:06 +0000569 ASSERT_FALSE(status.isOk()) << status.getMessage();
570 EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
571}
572
573/**
574 * Generate a non-empty certificate request in prod mode, but with the MAC corrupted on the keypair.
575 */
576TEST_P(CertificateRequestTest, NonEmptyRequestCorruptMac_prodMode) {
Seth Moore19acbe92021-06-23 15:15:52 -0700577 bool testMode = false;
David Drysdalee99ed862021-03-15 16:43:06 +0000578 generateKeys(testMode, 1 /* numKeys */);
David Drysdale08696a72022-03-10 10:43:25 +0000579 auto result = corrupt_maced_key(keysToSign_[0]);
580 ASSERT_TRUE(result) << result.moveMessage();
581 MacedPublicKey keyWithCorruptMac = result.moveValue();
David Drysdalee99ed862021-03-15 16:43:06 +0000582
583 bytevec keysToSignMac;
584 DeviceInfo deviceInfo;
585 ProtectedData protectedData;
586 auto status = provisionable_->generateCertificateRequest(
subrahmanyamanfb213d62022-02-02 23:10:55 +0000587 testMode, {keyWithCorruptMac}, getProdEekChain(rpcHardwareInfo.supportedEekCurve),
588 challenge_, &deviceInfo, &protectedData, &keysToSignMac);
David Drysdalee99ed862021-03-15 16:43:06 +0000589 ASSERT_FALSE(status.isOk()) << status.getMessage();
Seth Moore19acbe92021-06-23 15:15:52 -0700590 EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
David Drysdalee99ed862021-03-15 16:43:06 +0000591}
592
593/**
David Drysdalecceca9f2021-03-12 15:49:47 +0000594 * Generate a non-empty certificate request in prod mode that has a corrupt EEK chain.
595 * Confirm that the request is rejected.
David Drysdalecceca9f2021-03-12 15:49:47 +0000596 */
597TEST_P(CertificateRequestTest, NonEmptyCorruptEekRequest_prodMode) {
598 bool testMode = false;
599 generateKeys(testMode, 4 /* numKeys */);
600
subrahmanyamanfb213d62022-02-02 23:10:55 +0000601 auto prodEekChain = getProdEekChain(rpcHardwareInfo.supportedEekCurve);
Seth Moore19acbe92021-06-23 15:15:52 -0700602 auto [parsedChain, _, parseErr] = cppbor::parse(prodEekChain);
603 ASSERT_NE(parsedChain, nullptr) << parseErr;
604 ASSERT_NE(parsedChain->asArray(), nullptr);
605
606 for (int ii = 0; ii < parsedChain->asArray()->size(); ++ii) {
607 auto chain = corrupt_sig_chain(prodEekChain, ii);
David Drysdalecceca9f2021-03-12 15:49:47 +0000608 ASSERT_TRUE(chain) << chain.message();
David Drysdalecceca9f2021-03-12 15:49:47 +0000609
610 bytevec keysToSignMac;
611 DeviceInfo deviceInfo;
612 ProtectedData protectedData;
Seth Moore19acbe92021-06-23 15:15:52 -0700613 auto status = provisionable_->generateCertificateRequest(testMode, keysToSign_, *chain,
614 challenge_, &deviceInfo,
615 &protectedData, &keysToSignMac);
David Drysdalecceca9f2021-03-12 15:49:47 +0000616 ASSERT_FALSE(status.isOk());
617 ASSERT_EQ(status.getServiceSpecificError(),
618 BnRemotelyProvisionedComponent::STATUS_INVALID_EEK);
619 }
620}
621
622/**
623 * Generate a non-empty certificate request in prod mode that has an incomplete EEK chain.
624 * Confirm that the request is rejected.
David Drysdalecceca9f2021-03-12 15:49:47 +0000625 */
626TEST_P(CertificateRequestTest, NonEmptyIncompleteEekRequest_prodMode) {
627 bool testMode = false;
628 generateKeys(testMode, 4 /* numKeys */);
629
630 // Build an EEK chain that omits the first self-signed cert.
631 auto truncatedChain = cppbor::Array();
subrahmanyamanfb213d62022-02-02 23:10:55 +0000632 auto [chain, _, parseErr] = cppbor::parse(getProdEekChain(rpcHardwareInfo.supportedEekCurve));
David Drysdalecceca9f2021-03-12 15:49:47 +0000633 ASSERT_TRUE(chain);
634 auto eekChain = chain->asArray();
635 ASSERT_NE(eekChain, nullptr);
636 for (size_t ii = 1; ii < eekChain->size(); ii++) {
637 truncatedChain.add(eekChain->get(ii)->clone());
638 }
639
Shawn Willden274bb552020-09-30 22:39:22 -0600640 bytevec keysToSignMac;
Max Biresfdbb9042021-03-23 12:43:38 -0700641 DeviceInfo deviceInfo;
Shawn Willden274bb552020-09-30 22:39:22 -0600642 ProtectedData protectedData;
David Drysdalecceca9f2021-03-12 15:49:47 +0000643 auto status = provisionable_->generateCertificateRequest(
644 testMode, keysToSign_, truncatedChain.encode(), challenge_, &deviceInfo, &protectedData,
645 &keysToSignMac);
Shawn Willden274bb552020-09-30 22:39:22 -0600646 ASSERT_FALSE(status.isOk());
647 ASSERT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_EEK);
648}
649
650/**
651 * Generate a non-empty certificate request in test mode, with prod keys. Must fail with
652 * STATUS_PRODUCTION_KEY_IN_TEST_REQUEST.
653 */
Max Bires126869a2021-02-21 18:32:59 -0800654TEST_P(CertificateRequestTest, NonEmptyRequest_prodKeyInTestCert) {
Shawn Willden274bb552020-09-30 22:39:22 -0600655 generateKeys(false /* testMode */, 2 /* numKeys */);
656
657 bytevec keysToSignMac;
Max Biresfdbb9042021-03-23 12:43:38 -0700658 DeviceInfo deviceInfo;
Shawn Willden274bb552020-09-30 22:39:22 -0600659 ProtectedData protectedData;
subrahmanyamanfb213d62022-02-02 23:10:55 +0000660 generateTestEekChain(3);
Max Biresfdbb9042021-03-23 12:43:38 -0700661 auto status = provisionable_->generateCertificateRequest(
Seth Moore19acbe92021-06-23 15:15:52 -0700662 true /* testMode */, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo,
Max Biresfdbb9042021-03-23 12:43:38 -0700663 &protectedData, &keysToSignMac);
Shawn Willden274bb552020-09-30 22:39:22 -0600664 ASSERT_FALSE(status.isOk());
665 ASSERT_EQ(status.getServiceSpecificError(),
666 BnRemotelyProvisionedComponent::STATUS_PRODUCTION_KEY_IN_TEST_REQUEST);
667}
668
669/**
670 * Generate a non-empty certificate request in prod mode, with test keys. Must fail with
671 * STATUS_TEST_KEY_IN_PRODUCTION_REQUEST.
672 */
Max Bires126869a2021-02-21 18:32:59 -0800673TEST_P(CertificateRequestTest, NonEmptyRequest_testKeyInProdCert) {
Shawn Willden274bb552020-09-30 22:39:22 -0600674 generateKeys(true /* testMode */, 2 /* numKeys */);
675
676 bytevec keysToSignMac;
Max Biresfdbb9042021-03-23 12:43:38 -0700677 DeviceInfo deviceInfo;
Shawn Willden274bb552020-09-30 22:39:22 -0600678 ProtectedData protectedData;
subrahmanyamanfb213d62022-02-02 23:10:55 +0000679 generateTestEekChain(3);
Shawn Willden274bb552020-09-30 22:39:22 -0600680 auto status = provisionable_->generateCertificateRequest(
Seth Moore19acbe92021-06-23 15:15:52 -0700681 false /* testMode */, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo,
David Drysdalec8400772021-03-11 12:35:11 +0000682 &protectedData, &keysToSignMac);
Shawn Willden274bb552020-09-30 22:39:22 -0600683 ASSERT_FALSE(status.isOk());
684 ASSERT_EQ(status.getServiceSpecificError(),
685 BnRemotelyProvisionedComponent::STATUS_TEST_KEY_IN_PRODUCTION_REQUEST);
686}
687
688INSTANTIATE_REM_PROV_AIDL_TEST(CertificateRequestTest);
689
Tri Vo0d6204e2022-09-29 16:15:34 -0700690class CertificateRequestV2Test : public CertificateRequestTestBase {
691 void SetUp() override {
692 CertificateRequestTestBase::SetUp();
Andrew Scull1bcb6022022-12-27 10:43:27 +0000693 ASSERT_FALSE(HasFatalFailure());
Tri Vo0d6204e2022-09-29 16:15:34 -0700694
695 if (rpcHardwareInfo.versionNumber < VERSION_WITHOUT_TEST_MODE) {
696 GTEST_SKIP() << "This test case only applies to RKP v3 and above. "
697 << "RKP version discovered: " << rpcHardwareInfo.versionNumber;
698 }
699 }
700};
701
702/**
703 * Generate an empty certificate request, and decrypt and verify the structure and content.
704 */
705TEST_P(CertificateRequestV2Test, EmptyRequest) {
706 bytevec csr;
707
708 auto status =
709 provisionable_->generateCertificateRequestV2({} /* keysToSign */, challenge_, &csr);
710 ASSERT_TRUE(status.isOk()) << status.getMessage();
711
712 auto result = verifyProductionCsr(cppbor::Array(), csr, provisionable_.get(), challenge_);
713 ASSERT_TRUE(result) << result.message();
714}
715
716/**
717 * Generate a non-empty certificate request. Decrypt, parse and validate the contents.
718 */
719TEST_P(CertificateRequestV2Test, NonEmptyRequest) {
720 generateKeys(false /* testMode */, 1 /* numKeys */);
721
722 bytevec csr;
723
724 auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
725 ASSERT_TRUE(status.isOk()) << status.getMessage();
726
727 auto result = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_);
728 ASSERT_TRUE(result) << result.message();
729}
730
731/**
Andrew Scullfb49ad22022-11-09 21:02:48 +0000732 * Generate a non-empty certificate request. Make sure contents are reproducible but allow for the
733 * signature to be different since algorithms including ECDSA P-256 can include a random value.
Tri Vo0d6204e2022-09-29 16:15:34 -0700734 */
735TEST_P(CertificateRequestV2Test, NonEmptyRequestReproducible) {
736 generateKeys(false /* testMode */, 1 /* numKeys */);
737
738 bytevec csr;
739
740 auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
741 ASSERT_TRUE(status.isOk()) << status.getMessage();
742
Andrew Scullfb49ad22022-11-09 21:02:48 +0000743 auto firstCsr = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_);
744 ASSERT_TRUE(firstCsr) << firstCsr.message();
Tri Vo0d6204e2022-09-29 16:15:34 -0700745
746 status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
747 ASSERT_TRUE(status.isOk()) << status.getMessage();
748
Andrew Scullfb49ad22022-11-09 21:02:48 +0000749 auto secondCsr = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_);
750 ASSERT_TRUE(secondCsr) << secondCsr.message();
Tri Vo0d6204e2022-09-29 16:15:34 -0700751
Andrew Scullfb49ad22022-11-09 21:02:48 +0000752 ASSERT_EQ(**firstCsr, **secondCsr);
Tri Vo0d6204e2022-09-29 16:15:34 -0700753}
754
755/**
756 * Generate a non-empty certificate request with multiple keys.
757 */
758TEST_P(CertificateRequestV2Test, NonEmptyRequestMultipleKeys) {
Tri Vo9cab73c2022-10-28 13:40:24 -0700759 generateKeys(false /* testMode */, rpcHardwareInfo.supportedNumKeysInCsr /* numKeys */);
Tri Vo0d6204e2022-09-29 16:15:34 -0700760
761 bytevec csr;
762
763 auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
764 ASSERT_TRUE(status.isOk()) << status.getMessage();
765
766 auto result = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_);
767 ASSERT_TRUE(result) << result.message();
768}
769
770/**
771 * Generate a non-empty certificate request, but with the MAC corrupted on the keypair.
772 */
773TEST_P(CertificateRequestV2Test, NonEmptyRequestCorruptMac) {
774 generateKeys(false /* testMode */, 1 /* numKeys */);
775 auto result = corrupt_maced_key(keysToSign_[0]);
776 ASSERT_TRUE(result) << result.moveMessage();
777 MacedPublicKey keyWithCorruptMac = result.moveValue();
778
779 bytevec csr;
780 auto status =
781 provisionable_->generateCertificateRequestV2({keyWithCorruptMac}, challenge_, &csr);
782 ASSERT_FALSE(status.isOk()) << status.getMessage();
783 EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
784}
785
786/**
Tri Vob0b8acc2022-11-30 16:22:23 -0800787 * Generate a non-empty certificate request in prod mode, with test keys. Must fail with
788 * STATUS_TEST_KEY_IN_PRODUCTION_REQUEST.
Tri Vo0d6204e2022-09-29 16:15:34 -0700789 */
790TEST_P(CertificateRequestV2Test, NonEmptyRequest_testKeyInProdCert) {
791 generateKeys(true /* testMode */, 1 /* numKeys */);
792
793 bytevec csr;
794 auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
Tri Vo0d6204e2022-09-29 16:15:34 -0700795 ASSERT_FALSE(status.isOk()) << status.getMessage();
Tri Vob0b8acc2022-11-30 16:22:23 -0800796 ASSERT_EQ(status.getServiceSpecificError(),
797 BnRemotelyProvisionedComponent::STATUS_TEST_KEY_IN_PRODUCTION_REQUEST);
Tri Vo0d6204e2022-09-29 16:15:34 -0700798}
799
800INSTANTIATE_REM_PROV_AIDL_TEST(CertificateRequestV2Test);
801
Max Biresa9b3bb92022-11-21 23:02:09 -0800802using VsrRequirementTest = VtsRemotelyProvisionedComponentTests;
803
804INSTANTIATE_REM_PROV_AIDL_TEST(VsrRequirementTest);
805
806TEST_P(VsrRequirementTest, VsrEnforcementTest) {
807 RpcHardwareInfo hwInfo;
808 ASSERT_TRUE(provisionable_->getHardwareInfo(&hwInfo).isOk());
809 int vsr_api_level = get_vsr_api_level();
810 if (vsr_api_level < 34) {
811 GTEST_SKIP() << "Applies only to VSR API level 34 or newer, this device is: "
812 << vsr_api_level;
813 }
814 EXPECT_GE(hwInfo.versionNumber, 3)
815 << "VSR 14+ requires IRemotelyProvisionedComponent v3 or newer.";
816}
817
Shawn Willden274bb552020-09-30 22:39:22 -0600818} // namespace aidl::android::hardware::security::keymint::test