blob: 8906543e7f42bbb6042244cda3e668581becf326 [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>
Seth Moore42c11332021-07-02 15:38:17 -070038#include <vector>
Shawn Willden274bb552020-09-30 22:39:22 -060039
David Drysdalef0d516d2021-03-22 07:51:43 +000040#include "KeyMintAidlTestBase.h"
41
Shawn Willden274bb552020-09-30 22:39:22 -060042namespace aidl::android::hardware::security::keymint::test {
43
44using ::std::string;
45using ::std::vector;
46
47namespace {
48
Seth Moorefc86bf42021-12-09 14:07:04 -080049constexpr int32_t VERSION_WITH_UNIQUE_ID_SUPPORT = 2;
Andrew Scullf2ae1932023-04-24 19:09:09 +000050
51constexpr int32_t VERSION_WITHOUT_EEK = 3;
Tri Vo0d6204e2022-09-29 16:15:34 -070052constexpr int32_t VERSION_WITHOUT_TEST_MODE = 3;
Andrew Scullf2ae1932023-04-24 19:09:09 +000053constexpr int32_t VERSION_WITH_CERTIFICATE_REQUEST_V2 = 3;
54constexpr int32_t VERSION_WITH_SUPPORTED_NUM_KEYS_IN_CSR = 3;
Seth Moorefc86bf42021-12-09 14:07:04 -080055
Tommy Chiufde3ad12023-03-17 05:58:28 +000056constexpr uint8_t MIN_CHALLENGE_SIZE = 0;
57constexpr uint8_t MAX_CHALLENGE_SIZE = 64;
58
Shawn Willden274bb552020-09-30 22:39:22 -060059#define INSTANTIATE_REM_PROV_AIDL_TEST(name) \
Seth Moore6305e232021-07-27 14:20:17 -070060 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(name); \
Shawn Willden274bb552020-09-30 22:39:22 -060061 INSTANTIATE_TEST_SUITE_P( \
62 PerInstance, name, \
63 testing::ValuesIn(VtsRemotelyProvisionedComponentTests::build_params()), \
64 ::android::PrintInstanceNameToString)
65
Seth Moorefc86bf42021-12-09 14:07:04 -080066using ::android::sp;
Shawn Willden274bb552020-09-30 22:39:22 -060067using bytevec = std::vector<uint8_t>;
68using testing::MatchesRegex;
69using namespace remote_prov;
70using namespace keymaster;
71
72bytevec string_to_bytevec(const char* s) {
73 const uint8_t* p = reinterpret_cast<const uint8_t*>(s);
74 return bytevec(p, p + strlen(s));
75}
76
David Drysdalee99ed862021-03-15 16:43:06 +000077ErrMsgOr<MacedPublicKey> corrupt_maced_key(const MacedPublicKey& macedPubKey) {
78 auto [coseMac0, _, mac0ParseErr] = cppbor::parse(macedPubKey.macedKey);
79 if (!coseMac0 || coseMac0->asArray()->size() != kCoseMac0EntryCount) {
80 return "COSE Mac0 parse failed";
81 }
82 auto protParams = coseMac0->asArray()->get(kCoseMac0ProtectedParams)->asBstr();
83 auto unprotParams = coseMac0->asArray()->get(kCoseMac0UnprotectedParams)->asMap();
84 auto payload = coseMac0->asArray()->get(kCoseMac0Payload)->asBstr();
85 auto tag = coseMac0->asArray()->get(kCoseMac0Tag)->asBstr();
86 if (!protParams || !unprotParams || !payload || !tag) {
87 return "Invalid COSE_Sign1: missing content";
88 }
89 auto corruptMac0 = cppbor::Array();
90 corruptMac0.add(protParams->clone());
91 corruptMac0.add(unprotParams->clone());
92 corruptMac0.add(payload->clone());
93 vector<uint8_t> tagData = tag->value();
94 tagData[0] ^= 0x08;
95 tagData[tagData.size() - 1] ^= 0x80;
96 corruptMac0.add(cppbor::Bstr(tagData));
97
98 return MacedPublicKey{corruptMac0.encode()};
99}
100
David Drysdalecceca9f2021-03-12 15:49:47 +0000101ErrMsgOr<cppbor::Array> corrupt_sig(const cppbor::Array* coseSign1) {
102 if (coseSign1->size() != kCoseSign1EntryCount) {
103 return "Invalid COSE_Sign1, wrong entry count";
104 }
105 const cppbor::Bstr* protectedParams = coseSign1->get(kCoseSign1ProtectedParams)->asBstr();
106 const cppbor::Map* unprotectedParams = coseSign1->get(kCoseSign1UnprotectedParams)->asMap();
107 const cppbor::Bstr* payload = coseSign1->get(kCoseSign1Payload)->asBstr();
108 const cppbor::Bstr* signature = coseSign1->get(kCoseSign1Signature)->asBstr();
109 if (!protectedParams || !unprotectedParams || !payload || !signature) {
110 return "Invalid COSE_Sign1: missing content";
111 }
112
113 auto corruptSig = cppbor::Array();
114 corruptSig.add(protectedParams->clone());
115 corruptSig.add(unprotectedParams->clone());
116 corruptSig.add(payload->clone());
117 vector<uint8_t> sigData = signature->value();
118 sigData[0] ^= 0x08;
119 corruptSig.add(cppbor::Bstr(sigData));
120
121 return std::move(corruptSig);
122}
123
Seth Moore19acbe92021-06-23 15:15:52 -0700124ErrMsgOr<bytevec> corrupt_sig_chain(const bytevec& encodedEekChain, int which) {
125 auto [chain, _, parseErr] = cppbor::parse(encodedEekChain);
David Drysdalecceca9f2021-03-12 15:49:47 +0000126 if (!chain || !chain->asArray()) {
127 return "EekChain parse failed";
128 }
129
130 cppbor::Array* eekChain = chain->asArray();
131 if (which >= eekChain->size()) {
132 return "selected sig out of range";
133 }
134 auto corruptChain = cppbor::Array();
135
136 for (int ii = 0; ii < eekChain->size(); ++ii) {
137 if (ii == which) {
138 auto sig = corrupt_sig(eekChain->get(which)->asArray());
139 if (!sig) {
140 return "Failed to build corrupted signature" + sig.moveMessage();
141 }
142 corruptChain.add(sig.moveValue());
143 } else {
144 corruptChain.add(eekChain->get(ii)->clone());
145 }
146 }
Seth Moore19acbe92021-06-23 15:15:52 -0700147 return corruptChain.encode();
David Drysdalecceca9f2021-03-12 15:49:47 +0000148}
149
David Drysdale4d3c2982021-03-31 18:21:40 +0100150string device_suffix(const string& name) {
151 size_t pos = name.find('/');
152 if (pos == string::npos) {
153 return name;
154 }
155 return name.substr(pos + 1);
156}
157
158bool matching_keymint_device(const string& rp_name, std::shared_ptr<IKeyMintDevice>* keyMint) {
159 string rp_suffix = device_suffix(rp_name);
160
161 vector<string> km_names = ::android::getAidlHalInstanceNames(IKeyMintDevice::descriptor);
162 for (const string& km_name : km_names) {
163 // If the suffix of the KeyMint instance equals the suffix of the
164 // RemotelyProvisionedComponent instance, assume they match.
165 if (device_suffix(km_name) == rp_suffix && AServiceManager_isDeclared(km_name.c_str())) {
166 ::ndk::SpAIBinder binder(AServiceManager_waitForService(km_name.c_str()));
167 *keyMint = IKeyMintDevice::fromBinder(binder);
168 return true;
169 }
170 }
171 return false;
172}
173
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())) {
180 ::ndk::SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str()));
181 provisionable_ = IRemotelyProvisionedComponent::fromBinder(binder);
182 }
183 ASSERT_NE(provisionable_, nullptr);
subrahmanyamanfb213d62022-02-02 23:10:55 +0000184 ASSERT_TRUE(provisionable_->getHardwareInfo(&rpcHardwareInfo).isOk());
Shawn Willden274bb552020-09-30 22:39:22 -0600185 }
186
187 static vector<string> build_params() {
188 auto params = ::android::getAidlHalInstanceNames(IRemotelyProvisionedComponent::descriptor);
189 return params;
190 }
191
192 protected:
193 std::shared_ptr<IRemotelyProvisionedComponent> provisionable_;
subrahmanyamanfb213d62022-02-02 23:10:55 +0000194 RpcHardwareInfo rpcHardwareInfo;
Shawn Willden274bb552020-09-30 22:39:22 -0600195};
196
Seth Moorefc86bf42021-12-09 14:07:04 -0800197/**
198 * Verify that every implementation reports a different unique id.
199 */
200TEST(NonParameterizedTests, eachRpcHasAUniqueId) {
201 std::set<std::string> uniqueIds;
202 for (auto hal : ::android::getAidlHalInstanceNames(IRemotelyProvisionedComponent::descriptor)) {
203 ASSERT_TRUE(AServiceManager_isDeclared(hal.c_str()));
204 ::ndk::SpAIBinder binder(AServiceManager_waitForService(hal.c_str()));
205 std::shared_ptr<IRemotelyProvisionedComponent> rpc =
206 IRemotelyProvisionedComponent::fromBinder(binder);
207 ASSERT_NE(rpc, nullptr);
208
209 RpcHardwareInfo hwInfo;
210 ASSERT_TRUE(rpc->getHardwareInfo(&hwInfo).isOk());
211
Tri Vodd12c482022-10-12 22:41:28 +0000212 if (hwInfo.versionNumber >= VERSION_WITH_UNIQUE_ID_SUPPORT) {
Seth Moorefc86bf42021-12-09 14:07:04 -0800213 ASSERT_TRUE(hwInfo.uniqueId);
214 auto [_, wasInserted] = uniqueIds.insert(*hwInfo.uniqueId);
215 EXPECT_TRUE(wasInserted);
216 } else {
217 ASSERT_FALSE(hwInfo.uniqueId);
218 }
219 }
220}
221
222using GetHardwareInfoTests = VtsRemotelyProvisionedComponentTests;
223
224INSTANTIATE_REM_PROV_AIDL_TEST(GetHardwareInfoTests);
225
226/**
227 * Verify that a valid curve is reported by the implementation.
228 */
229TEST_P(GetHardwareInfoTests, supportsValidCurve) {
230 RpcHardwareInfo hwInfo;
231 ASSERT_TRUE(provisionable_->getHardwareInfo(&hwInfo).isOk());
232
Andrew Scullf2ae1932023-04-24 19:09:09 +0000233 if (rpcHardwareInfo.versionNumber >= VERSION_WITHOUT_EEK) {
234 ASSERT_EQ(hwInfo.supportedEekCurve, RpcHardwareInfo::CURVE_NONE)
235 << "Invalid curve: " << hwInfo.supportedEekCurve;
236 return;
Hasini Gunasinghe666b2712023-01-05 21:35:51 +0000237 }
Andrew Scullf2ae1932023-04-24 19:09:09 +0000238
239 const std::set<int> validCurves = {RpcHardwareInfo::CURVE_P256, RpcHardwareInfo::CURVE_25519};
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) {
Andrew Scullf2ae1932023-04-24 19:09:09 +0000263 if (rpcHardwareInfo.versionNumber < VERSION_WITH_SUPPORTED_NUM_KEYS_IN_CSR) {
Tri Vo9cab73c2022-10-28 13:40:24 -0700264 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);
Andrew Scullf2ae1932023-04-24 19:09:09 +0000364
365 if (rpcHardwareInfo.versionNumber >= VERSION_WITHOUT_TEST_MODE) {
366 ASSERT_FALSE(status.isOk());
367 EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_REMOVED);
368 return;
369 }
370
Shawn Willden274bb552020-09-30 22:39:22 -0600371 ASSERT_TRUE(status.isOk());
Tri Vob0b8acc2022-11-30 16:22:23 -0800372 check_maced_pubkey(macedPubKey, testMode, nullptr);
Shawn Willden274bb552020-09-30 22:39:22 -0600373}
374
Tri Vo0d6204e2022-09-29 16:15:34 -0700375class CertificateRequestTestBase : public VtsRemotelyProvisionedComponentTests {
Shawn Willden274bb552020-09-30 22:39:22 -0600376 protected:
Tri Vo0d6204e2022-09-29 16:15:34 -0700377 CertificateRequestTestBase()
378 : eekId_(string_to_bytevec("eekid")), challenge_(randomBytes(64)) {}
David Drysdalecceca9f2021-03-12 15:49:47 +0000379
Seth Moore19acbe92021-06-23 15:15:52 -0700380 void generateTestEekChain(size_t eekLength) {
subrahmanyamanfb213d62022-02-02 23:10:55 +0000381 auto chain = generateEekChain(rpcHardwareInfo.supportedEekCurve, eekLength, eekId_);
David Drysdale08696a72022-03-10 10:43:25 +0000382 ASSERT_TRUE(chain) << chain.message();
Seth Moore19acbe92021-06-23 15:15:52 -0700383 if (chain) testEekChain_ = chain.moveValue();
384 testEekLength_ = eekLength;
Shawn Willden274bb552020-09-30 22:39:22 -0600385 }
386
387 void generateKeys(bool testMode, size_t numKeys) {
388 keysToSign_ = std::vector<MacedPublicKey>(numKeys);
389 cborKeysToSign_ = cppbor::Array();
390
391 for (auto& key : keysToSign_) {
392 bytevec privateKeyBlob;
393 auto status = provisionable_->generateEcdsaP256KeyPair(testMode, &key, &privateKeyBlob);
394 ASSERT_TRUE(status.isOk()) << status.getMessage();
395
David Drysdalec8400772021-03-11 12:35:11 +0000396 vector<uint8_t> payload_value;
Tri Vob0b8acc2022-11-30 16:22:23 -0800397 check_maced_pubkey(key, testMode, &payload_value);
David Drysdalec8400772021-03-11 12:35:11 +0000398 cborKeysToSign_.add(cppbor::EncodedItem(payload_value));
Shawn Willden274bb552020-09-30 22:39:22 -0600399 }
400 }
401
402 bytevec eekId_;
Seth Moore19acbe92021-06-23 15:15:52 -0700403 size_t testEekLength_;
404 EekChain testEekChain_;
David Drysdalec8400772021-03-11 12:35:11 +0000405 bytevec challenge_;
Shawn Willden274bb552020-09-30 22:39:22 -0600406 std::vector<MacedPublicKey> keysToSign_;
407 cppbor::Array cborKeysToSign_;
408};
409
Tri Vo0d6204e2022-09-29 16:15:34 -0700410class CertificateRequestTest : public CertificateRequestTestBase {
411 protected:
412 void SetUp() override {
413 CertificateRequestTestBase::SetUp();
Andrew Scull1bcb6022022-12-27 10:43:27 +0000414 ASSERT_FALSE(HasFatalFailure());
Tri Vo0d6204e2022-09-29 16:15:34 -0700415
Andrew Scullf2ae1932023-04-24 19:09:09 +0000416 if (rpcHardwareInfo.versionNumber >= VERSION_WITH_CERTIFICATE_REQUEST_V2) {
Andrew Scull95b31312023-03-27 19:16:07 +0000417 GTEST_SKIP() << "This test case only applies to RKP v1 and v2. "
418 << "RKP version discovered: " << rpcHardwareInfo.versionNumber;
Tri Vo0d6204e2022-09-29 16:15:34 -0700419 }
420 }
421};
422
Shawn Willden274bb552020-09-30 22:39:22 -0600423/**
424 * Generate an empty certificate request in test mode, and decrypt and verify the structure and
425 * content.
426 */
Max Bires126869a2021-02-21 18:32:59 -0800427TEST_P(CertificateRequestTest, EmptyRequest_testMode) {
Shawn Willden274bb552020-09-30 22:39:22 -0600428 bool testMode = true;
David Drysdalecceca9f2021-03-12 15:49:47 +0000429 for (size_t eekLength : {2, 3, 7}) {
430 SCOPED_TRACE(testing::Message() << "EEK of length " << eekLength);
Seth Moore19acbe92021-06-23 15:15:52 -0700431 generateTestEekChain(eekLength);
Shawn Willden274bb552020-09-30 22:39:22 -0600432
David Drysdalecceca9f2021-03-12 15:49:47 +0000433 bytevec keysToSignMac;
434 DeviceInfo deviceInfo;
435 ProtectedData protectedData;
436 auto status = provisionable_->generateCertificateRequest(
Seth Moore19acbe92021-06-23 15:15:52 -0700437 testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
David Drysdalecceca9f2021-03-12 15:49:47 +0000438 &protectedData, &keysToSignMac);
439 ASSERT_TRUE(status.isOk()) << status.getMessage();
440
Seth Moore2fc6f832022-09-13 16:10:11 -0700441 auto result = verifyProductionProtectedData(
442 deviceInfo, cppbor::Array(), keysToSignMac, protectedData, testEekChain_, eekId_,
443 rpcHardwareInfo.supportedEekCurve, provisionable_.get(), challenge_);
444 ASSERT_TRUE(result) << result.message();
David Drysdalecceca9f2021-03-12 15:49:47 +0000445 }
Shawn Willden274bb552020-09-30 22:39:22 -0600446}
447
448/**
Seth Moore42c11332021-07-02 15:38:17 -0700449 * Ensure that test mode outputs a unique BCC root key every time we request a
450 * certificate request. Else, it's possible that the test mode API could be used
451 * to fingerprint devices. Only the GEEK should be allowed to decrypt the same
452 * device public key multiple times.
453 */
454TEST_P(CertificateRequestTest, NewKeyPerCallInTestMode) {
455 constexpr bool testMode = true;
Seth Moore42c11332021-07-02 15:38:17 -0700456
457 bytevec keysToSignMac;
458 DeviceInfo deviceInfo;
459 ProtectedData protectedData;
subrahmanyamanfb213d62022-02-02 23:10:55 +0000460 generateTestEekChain(3);
Seth Moore42c11332021-07-02 15:38:17 -0700461 auto status = provisionable_->generateCertificateRequest(
Seth Moore19acbe92021-06-23 15:15:52 -0700462 testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
463 &protectedData, &keysToSignMac);
Seth Moore42c11332021-07-02 15:38:17 -0700464 ASSERT_TRUE(status.isOk()) << status.getMessage();
465
Seth Moore2fc6f832022-09-13 16:10:11 -0700466 auto firstBcc = verifyProductionProtectedData(
467 deviceInfo, /*keysToSign=*/cppbor::Array(), keysToSignMac, protectedData, testEekChain_,
468 eekId_, rpcHardwareInfo.supportedEekCurve, provisionable_.get(), challenge_);
469 ASSERT_TRUE(firstBcc) << firstBcc.message();
Seth Moore42c11332021-07-02 15:38:17 -0700470
Seth Moore19acbe92021-06-23 15:15:52 -0700471 status = provisionable_->generateCertificateRequest(
472 testMode, {} /* keysToSign */, testEekChain_.chain, challenge_, &deviceInfo,
473 &protectedData, &keysToSignMac);
Seth Moore42c11332021-07-02 15:38:17 -0700474 ASSERT_TRUE(status.isOk()) << status.getMessage();
475
Seth Moore2fc6f832022-09-13 16:10:11 -0700476 auto secondBcc = verifyProductionProtectedData(
477 deviceInfo, /*keysToSign=*/cppbor::Array(), keysToSignMac, protectedData, testEekChain_,
478 eekId_, rpcHardwareInfo.supportedEekCurve, provisionable_.get(), challenge_);
479 ASSERT_TRUE(secondBcc) << secondBcc.message();
Seth Moore42c11332021-07-02 15:38:17 -0700480
481 // Verify that none of the keys in the first BCC are repeated in the second one.
Seth Moore2fc6f832022-09-13 16:10:11 -0700482 for (const auto& i : *firstBcc) {
483 for (auto& j : *secondBcc) {
Seth Moore42c11332021-07-02 15:38:17 -0700484 ASSERT_THAT(i.pubKey, testing::Not(testing::ElementsAreArray(j.pubKey)))
485 << "Found a repeated pubkey in two generateCertificateRequest test mode calls";
486 }
487 }
488}
489
490/**
Seth Moore19acbe92021-06-23 15:15:52 -0700491 * Generate an empty certificate request in prod mode. This test must be run explicitly, and
492 * is not run by default. Not all devices are GMS devices, and therefore they do not all
493 * trust the Google EEK root.
Shawn Willden274bb552020-09-30 22:39:22 -0600494 */
Seth Moore19acbe92021-06-23 15:15:52 -0700495TEST_P(CertificateRequestTest, DISABLED_EmptyRequest_prodMode) {
Shawn Willden274bb552020-09-30 22:39:22 -0600496 bool testMode = false;
David Drysdalecceca9f2021-03-12 15:49:47 +0000497
Seth Moore19acbe92021-06-23 15:15:52 -0700498 bytevec keysToSignMac;
499 DeviceInfo deviceInfo;
500 ProtectedData protectedData;
501 auto status = provisionable_->generateCertificateRequest(
subrahmanyamanfb213d62022-02-02 23:10:55 +0000502 testMode, {} /* keysToSign */, getProdEekChain(rpcHardwareInfo.supportedEekCurve),
503 challenge_, &deviceInfo, &protectedData, &keysToSignMac);
Seth Moore19acbe92021-06-23 15:15:52 -0700504 EXPECT_TRUE(status.isOk());
Shawn Willden274bb552020-09-30 22:39:22 -0600505}
506
507/**
508 * Generate a non-empty certificate request in test mode. Decrypt, parse and validate the contents.
509 */
Max Bires126869a2021-02-21 18:32:59 -0800510TEST_P(CertificateRequestTest, NonEmptyRequest_testMode) {
Shawn Willden274bb552020-09-30 22:39:22 -0600511 bool testMode = true;
512 generateKeys(testMode, 4 /* numKeys */);
513
David Drysdalecceca9f2021-03-12 15:49:47 +0000514 for (size_t eekLength : {2, 3, 7}) {
515 SCOPED_TRACE(testing::Message() << "EEK of length " << eekLength);
Seth Moore19acbe92021-06-23 15:15:52 -0700516 generateTestEekChain(eekLength);
Shawn Willden274bb552020-09-30 22:39:22 -0600517
David Drysdalecceca9f2021-03-12 15:49:47 +0000518 bytevec keysToSignMac;
519 DeviceInfo deviceInfo;
520 ProtectedData protectedData;
521 auto status = provisionable_->generateCertificateRequest(
Seth Moore19acbe92021-06-23 15:15:52 -0700522 testMode, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo, &protectedData,
David Drysdalecceca9f2021-03-12 15:49:47 +0000523 &keysToSignMac);
524 ASSERT_TRUE(status.isOk()) << status.getMessage();
525
Seth Moore2fc6f832022-09-13 16:10:11 -0700526 auto result = verifyProductionProtectedData(
527 deviceInfo, cborKeysToSign_, keysToSignMac, protectedData, testEekChain_, eekId_,
528 rpcHardwareInfo.supportedEekCurve, provisionable_.get(), challenge_);
529 ASSERT_TRUE(result) << result.message();
David Drysdalecceca9f2021-03-12 15:49:47 +0000530 }
Shawn Willden274bb552020-09-30 22:39:22 -0600531}
532
533/**
Seth Moore19acbe92021-06-23 15:15:52 -0700534 * Generate a non-empty certificate request in prod mode. This test must be run explicitly, and
535 * is not run by default. Not all devices are GMS devices, and therefore they do not all
536 * trust the Google EEK root.
Shawn Willden274bb552020-09-30 22:39:22 -0600537 */
Seth Moore19acbe92021-06-23 15:15:52 -0700538TEST_P(CertificateRequestTest, DISABLED_NonEmptyRequest_prodMode) {
Shawn Willden274bb552020-09-30 22:39:22 -0600539 bool testMode = false;
540 generateKeys(testMode, 4 /* numKeys */);
541
Seth Moore19acbe92021-06-23 15:15:52 -0700542 bytevec keysToSignMac;
543 DeviceInfo deviceInfo;
544 ProtectedData protectedData;
545 auto status = provisionable_->generateCertificateRequest(
subrahmanyamanfb213d62022-02-02 23:10:55 +0000546 testMode, keysToSign_, getProdEekChain(rpcHardwareInfo.supportedEekCurve), challenge_,
547 &deviceInfo, &protectedData, &keysToSignMac);
Seth Moore19acbe92021-06-23 15:15:52 -0700548 EXPECT_TRUE(status.isOk());
David Drysdalecceca9f2021-03-12 15:49:47 +0000549}
550
551/**
David Drysdalee99ed862021-03-15 16:43:06 +0000552 * Generate a non-empty certificate request in test mode, but with the MAC corrupted on the keypair.
553 */
554TEST_P(CertificateRequestTest, NonEmptyRequestCorruptMac_testMode) {
555 bool testMode = true;
556 generateKeys(testMode, 1 /* numKeys */);
David Drysdale08696a72022-03-10 10:43:25 +0000557 auto result = corrupt_maced_key(keysToSign_[0]);
558 ASSERT_TRUE(result) << result.moveMessage();
559 MacedPublicKey keyWithCorruptMac = result.moveValue();
David Drysdalee99ed862021-03-15 16:43:06 +0000560
561 bytevec keysToSignMac;
562 DeviceInfo deviceInfo;
563 ProtectedData protectedData;
subrahmanyamanfb213d62022-02-02 23:10:55 +0000564 generateTestEekChain(3);
David Drysdalee99ed862021-03-15 16:43:06 +0000565 auto status = provisionable_->generateCertificateRequest(
Seth Moore19acbe92021-06-23 15:15:52 -0700566 testMode, {keyWithCorruptMac}, testEekChain_.chain, challenge_, &deviceInfo,
567 &protectedData, &keysToSignMac);
David Drysdalee99ed862021-03-15 16:43:06 +0000568 ASSERT_FALSE(status.isOk()) << status.getMessage();
569 EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
570}
571
572/**
573 * Generate a non-empty certificate request in prod mode, but with the MAC corrupted on the keypair.
574 */
575TEST_P(CertificateRequestTest, NonEmptyRequestCorruptMac_prodMode) {
Seth Moore19acbe92021-06-23 15:15:52 -0700576 bool testMode = false;
David Drysdalee99ed862021-03-15 16:43:06 +0000577 generateKeys(testMode, 1 /* numKeys */);
David Drysdale08696a72022-03-10 10:43:25 +0000578 auto result = corrupt_maced_key(keysToSign_[0]);
579 ASSERT_TRUE(result) << result.moveMessage();
580 MacedPublicKey keyWithCorruptMac = result.moveValue();
David Drysdalee99ed862021-03-15 16:43:06 +0000581
582 bytevec keysToSignMac;
583 DeviceInfo deviceInfo;
584 ProtectedData protectedData;
585 auto status = provisionable_->generateCertificateRequest(
subrahmanyamanfb213d62022-02-02 23:10:55 +0000586 testMode, {keyWithCorruptMac}, getProdEekChain(rpcHardwareInfo.supportedEekCurve),
587 challenge_, &deviceInfo, &protectedData, &keysToSignMac);
David Drysdalee99ed862021-03-15 16:43:06 +0000588 ASSERT_FALSE(status.isOk()) << status.getMessage();
Seth Moore19acbe92021-06-23 15:15:52 -0700589 EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
David Drysdalee99ed862021-03-15 16:43:06 +0000590}
591
592/**
David Drysdalecceca9f2021-03-12 15:49:47 +0000593 * Generate a non-empty certificate request in prod mode that has a corrupt EEK chain.
594 * Confirm that the request is rejected.
David Drysdalecceca9f2021-03-12 15:49:47 +0000595 */
596TEST_P(CertificateRequestTest, NonEmptyCorruptEekRequest_prodMode) {
597 bool testMode = false;
598 generateKeys(testMode, 4 /* numKeys */);
599
subrahmanyamanfb213d62022-02-02 23:10:55 +0000600 auto prodEekChain = getProdEekChain(rpcHardwareInfo.supportedEekCurve);
Seth Moore19acbe92021-06-23 15:15:52 -0700601 auto [parsedChain, _, parseErr] = cppbor::parse(prodEekChain);
602 ASSERT_NE(parsedChain, nullptr) << parseErr;
603 ASSERT_NE(parsedChain->asArray(), nullptr);
604
605 for (int ii = 0; ii < parsedChain->asArray()->size(); ++ii) {
606 auto chain = corrupt_sig_chain(prodEekChain, ii);
David Drysdalecceca9f2021-03-12 15:49:47 +0000607 ASSERT_TRUE(chain) << chain.message();
David Drysdalecceca9f2021-03-12 15:49:47 +0000608
609 bytevec keysToSignMac;
610 DeviceInfo deviceInfo;
611 ProtectedData protectedData;
Seth Moore19acbe92021-06-23 15:15:52 -0700612 auto status = provisionable_->generateCertificateRequest(testMode, keysToSign_, *chain,
613 challenge_, &deviceInfo,
614 &protectedData, &keysToSignMac);
David Drysdalecceca9f2021-03-12 15:49:47 +0000615 ASSERT_FALSE(status.isOk());
616 ASSERT_EQ(status.getServiceSpecificError(),
617 BnRemotelyProvisionedComponent::STATUS_INVALID_EEK);
618 }
619}
620
621/**
622 * Generate a non-empty certificate request in prod mode that has an incomplete EEK chain.
623 * Confirm that the request is rejected.
David Drysdalecceca9f2021-03-12 15:49:47 +0000624 */
625TEST_P(CertificateRequestTest, NonEmptyIncompleteEekRequest_prodMode) {
626 bool testMode = false;
627 generateKeys(testMode, 4 /* numKeys */);
628
629 // Build an EEK chain that omits the first self-signed cert.
630 auto truncatedChain = cppbor::Array();
subrahmanyamanfb213d62022-02-02 23:10:55 +0000631 auto [chain, _, parseErr] = cppbor::parse(getProdEekChain(rpcHardwareInfo.supportedEekCurve));
David Drysdalecceca9f2021-03-12 15:49:47 +0000632 ASSERT_TRUE(chain);
633 auto eekChain = chain->asArray();
634 ASSERT_NE(eekChain, nullptr);
635 for (size_t ii = 1; ii < eekChain->size(); ii++) {
636 truncatedChain.add(eekChain->get(ii)->clone());
637 }
638
Shawn Willden274bb552020-09-30 22:39:22 -0600639 bytevec keysToSignMac;
Max Biresfdbb9042021-03-23 12:43:38 -0700640 DeviceInfo deviceInfo;
Shawn Willden274bb552020-09-30 22:39:22 -0600641 ProtectedData protectedData;
David Drysdalecceca9f2021-03-12 15:49:47 +0000642 auto status = provisionable_->generateCertificateRequest(
643 testMode, keysToSign_, truncatedChain.encode(), challenge_, &deviceInfo, &protectedData,
644 &keysToSignMac);
Shawn Willden274bb552020-09-30 22:39:22 -0600645 ASSERT_FALSE(status.isOk());
646 ASSERT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_EEK);
647}
648
649/**
650 * Generate a non-empty certificate request in test mode, with prod keys. Must fail with
651 * STATUS_PRODUCTION_KEY_IN_TEST_REQUEST.
652 */
Max Bires126869a2021-02-21 18:32:59 -0800653TEST_P(CertificateRequestTest, NonEmptyRequest_prodKeyInTestCert) {
Shawn Willden274bb552020-09-30 22:39:22 -0600654 generateKeys(false /* testMode */, 2 /* numKeys */);
655
656 bytevec keysToSignMac;
Max Biresfdbb9042021-03-23 12:43:38 -0700657 DeviceInfo deviceInfo;
Shawn Willden274bb552020-09-30 22:39:22 -0600658 ProtectedData protectedData;
subrahmanyamanfb213d62022-02-02 23:10:55 +0000659 generateTestEekChain(3);
Max Biresfdbb9042021-03-23 12:43:38 -0700660 auto status = provisionable_->generateCertificateRequest(
Seth Moore19acbe92021-06-23 15:15:52 -0700661 true /* testMode */, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo,
Max Biresfdbb9042021-03-23 12:43:38 -0700662 &protectedData, &keysToSignMac);
Shawn Willden274bb552020-09-30 22:39:22 -0600663 ASSERT_FALSE(status.isOk());
664 ASSERT_EQ(status.getServiceSpecificError(),
665 BnRemotelyProvisionedComponent::STATUS_PRODUCTION_KEY_IN_TEST_REQUEST);
666}
667
668/**
669 * Generate a non-empty certificate request in prod mode, with test keys. Must fail with
670 * STATUS_TEST_KEY_IN_PRODUCTION_REQUEST.
671 */
Max Bires126869a2021-02-21 18:32:59 -0800672TEST_P(CertificateRequestTest, NonEmptyRequest_testKeyInProdCert) {
Shawn Willden274bb552020-09-30 22:39:22 -0600673 generateKeys(true /* testMode */, 2 /* numKeys */);
674
675 bytevec keysToSignMac;
Max Biresfdbb9042021-03-23 12:43:38 -0700676 DeviceInfo deviceInfo;
Shawn Willden274bb552020-09-30 22:39:22 -0600677 ProtectedData protectedData;
subrahmanyamanfb213d62022-02-02 23:10:55 +0000678 generateTestEekChain(3);
Shawn Willden274bb552020-09-30 22:39:22 -0600679 auto status = provisionable_->generateCertificateRequest(
Seth Moore19acbe92021-06-23 15:15:52 -0700680 false /* testMode */, keysToSign_, testEekChain_.chain, challenge_, &deviceInfo,
David Drysdalec8400772021-03-11 12:35:11 +0000681 &protectedData, &keysToSignMac);
Shawn Willden274bb552020-09-30 22:39:22 -0600682 ASSERT_FALSE(status.isOk());
683 ASSERT_EQ(status.getServiceSpecificError(),
684 BnRemotelyProvisionedComponent::STATUS_TEST_KEY_IN_PRODUCTION_REQUEST);
685}
686
687INSTANTIATE_REM_PROV_AIDL_TEST(CertificateRequestTest);
688
Tri Vo0d6204e2022-09-29 16:15:34 -0700689class CertificateRequestV2Test : public CertificateRequestTestBase {
690 void SetUp() override {
691 CertificateRequestTestBase::SetUp();
Andrew Scull1bcb6022022-12-27 10:43:27 +0000692 ASSERT_FALSE(HasFatalFailure());
Tri Vo0d6204e2022-09-29 16:15:34 -0700693
Andrew Scullf2ae1932023-04-24 19:09:09 +0000694 if (rpcHardwareInfo.versionNumber < VERSION_WITH_CERTIFICATE_REQUEST_V2) {
Tri Vo0d6204e2022-09-29 16:15:34 -0700695 GTEST_SKIP() << "This test case only applies to RKP v3 and above. "
696 << "RKP version discovered: " << rpcHardwareInfo.versionNumber;
697 }
698 }
699};
700
701/**
Tommy Chiufde3ad12023-03-17 05:58:28 +0000702 * Generate an empty certificate request with all possible length of challenge, and decrypt and
703 * verify the structure and content.
Tri Vo0d6204e2022-09-29 16:15:34 -0700704 */
705TEST_P(CertificateRequestV2Test, EmptyRequest) {
706 bytevec csr;
707
Tommy Chiufde3ad12023-03-17 05:58:28 +0000708 for (auto size = MIN_CHALLENGE_SIZE; size <= MAX_CHALLENGE_SIZE; size++) {
709 SCOPED_TRACE(testing::Message() << "challenge[" << size << "]");
710 auto challenge = randomBytes(size);
711 auto status =
712 provisionable_->generateCertificateRequestV2({} /* keysToSign */, challenge, &csr);
713 ASSERT_TRUE(status.isOk()) << status.getMessage();
Tri Vo0d6204e2022-09-29 16:15:34 -0700714
Tommy Chiufde3ad12023-03-17 05:58:28 +0000715 auto result = verifyProductionCsr(cppbor::Array(), csr, provisionable_.get(), challenge);
716 ASSERT_TRUE(result) << result.message();
717 }
Tri Vo0d6204e2022-09-29 16:15:34 -0700718}
719
720/**
Tommy Chiufde3ad12023-03-17 05:58:28 +0000721 * Generate a non-empty certificate request with all possible length of challenge. Decrypt, parse
722 * and validate the contents.
Tri Vo0d6204e2022-09-29 16:15:34 -0700723 */
724TEST_P(CertificateRequestV2Test, NonEmptyRequest) {
725 generateKeys(false /* testMode */, 1 /* numKeys */);
726
727 bytevec csr;
728
Tommy Chiufde3ad12023-03-17 05:58:28 +0000729 for (auto size = MIN_CHALLENGE_SIZE; size <= MAX_CHALLENGE_SIZE; size++) {
730 SCOPED_TRACE(testing::Message() << "challenge[" << size << "]");
731 auto challenge = randomBytes(size);
732 auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge, &csr);
733 ASSERT_TRUE(status.isOk()) << status.getMessage();
Tri Vo0d6204e2022-09-29 16:15:34 -0700734
Tommy Chiufde3ad12023-03-17 05:58:28 +0000735 auto result = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge);
736 ASSERT_TRUE(result) << result.message();
737 }
738}
739
740/**
741 * Generate an empty certificate request with invalid size of challenge
742 */
743TEST_P(CertificateRequestV2Test, EmptyRequestWithInvalidChallengeFail) {
744 bytevec csr;
745
746 auto status = provisionable_->generateCertificateRequestV2(
747 /* keysToSign */ {}, randomBytes(MAX_CHALLENGE_SIZE + 1), &csr);
748 EXPECT_FALSE(status.isOk()) << status.getMessage();
749 EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_FAILED);
Tri Vo0d6204e2022-09-29 16:15:34 -0700750}
751
752/**
Andrew Scullfb49ad22022-11-09 21:02:48 +0000753 * Generate a non-empty certificate request. Make sure contents are reproducible but allow for the
754 * signature to be different since algorithms including ECDSA P-256 can include a random value.
Tri Vo0d6204e2022-09-29 16:15:34 -0700755 */
756TEST_P(CertificateRequestV2Test, NonEmptyRequestReproducible) {
757 generateKeys(false /* testMode */, 1 /* numKeys */);
758
759 bytevec csr;
760
761 auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
762 ASSERT_TRUE(status.isOk()) << status.getMessage();
763
Andrew Scullfb49ad22022-11-09 21:02:48 +0000764 auto firstCsr = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_);
765 ASSERT_TRUE(firstCsr) << firstCsr.message();
Tri Vo0d6204e2022-09-29 16:15:34 -0700766
767 status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
768 ASSERT_TRUE(status.isOk()) << status.getMessage();
769
Andrew Scullfb49ad22022-11-09 21:02:48 +0000770 auto secondCsr = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_);
771 ASSERT_TRUE(secondCsr) << secondCsr.message();
Tri Vo0d6204e2022-09-29 16:15:34 -0700772
Andrew Scullfb49ad22022-11-09 21:02:48 +0000773 ASSERT_EQ(**firstCsr, **secondCsr);
Tri Vo0d6204e2022-09-29 16:15:34 -0700774}
775
776/**
777 * Generate a non-empty certificate request with multiple keys.
778 */
779TEST_P(CertificateRequestV2Test, NonEmptyRequestMultipleKeys) {
Tri Vo9cab73c2022-10-28 13:40:24 -0700780 generateKeys(false /* testMode */, rpcHardwareInfo.supportedNumKeysInCsr /* numKeys */);
Tri Vo0d6204e2022-09-29 16:15:34 -0700781
782 bytevec csr;
783
784 auto status = provisionable_->generateCertificateRequestV2(keysToSign_, challenge_, &csr);
785 ASSERT_TRUE(status.isOk()) << status.getMessage();
786
787 auto result = verifyProductionCsr(cborKeysToSign_, csr, provisionable_.get(), challenge_);
788 ASSERT_TRUE(result) << result.message();
789}
790
791/**
792 * Generate a non-empty certificate request, but with the MAC corrupted on the keypair.
793 */
794TEST_P(CertificateRequestV2Test, NonEmptyRequestCorruptMac) {
795 generateKeys(false /* testMode */, 1 /* numKeys */);
796 auto result = corrupt_maced_key(keysToSign_[0]);
797 ASSERT_TRUE(result) << result.moveMessage();
798 MacedPublicKey keyWithCorruptMac = result.moveValue();
799
800 bytevec csr;
801 auto status =
802 provisionable_->generateCertificateRequestV2({keyWithCorruptMac}, challenge_, &csr);
803 ASSERT_FALSE(status.isOk()) << status.getMessage();
804 EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_MAC);
805}
806
807/**
Andrew Scullf2ae1932023-04-24 19:09:09 +0000808 * Call generateCertificateRequest(). Make sure it's removed.
Tri Vo0d6204e2022-09-29 16:15:34 -0700809 */
Andrew Scullf2ae1932023-04-24 19:09:09 +0000810TEST_P(CertificateRequestV2Test, CertificateRequestV1Removed_prodMode) {
811 bytevec keysToSignMac;
812 DeviceInfo deviceInfo;
813 ProtectedData protectedData;
814 auto status = provisionable_->generateCertificateRequest(
815 false /* testMode */, {} /* keysToSign */, {} /* EEK chain */, challenge_, &deviceInfo,
816 &protectedData, &keysToSignMac);
Tri Vo0d6204e2022-09-29 16:15:34 -0700817 ASSERT_FALSE(status.isOk()) << status.getMessage();
Andrew Scullf2ae1932023-04-24 19:09:09 +0000818 EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_REMOVED);
Tri Vo0d6204e2022-09-29 16:15:34 -0700819}
820
Andrew Scull95b31312023-03-27 19:16:07 +0000821/**
Andrew Scullf2ae1932023-04-24 19:09:09 +0000822 * Call generateCertificateRequest() in test mode. Make sure it's removed.
Andrew Scull95b31312023-03-27 19:16:07 +0000823 */
Andrew Scullf2ae1932023-04-24 19:09:09 +0000824TEST_P(CertificateRequestV2Test, CertificateRequestV1Removed_testMode) {
Andrew Scull95b31312023-03-27 19:16:07 +0000825 bytevec keysToSignMac;
826 DeviceInfo deviceInfo;
827 ProtectedData protectedData;
828 auto status = provisionable_->generateCertificateRequest(
829 true /* testMode */, {} /* keysToSign */, {} /* EEK chain */, challenge_, &deviceInfo,
830 &protectedData, &keysToSignMac);
831 ASSERT_FALSE(status.isOk()) << status.getMessage();
832 EXPECT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_REMOVED);
833}
834
Tri Voec50ee12023-02-14 16:29:53 -0800835void parse_root_of_trust(const vector<uint8_t>& attestation_cert,
836 vector<uint8_t>* verified_boot_key, VerifiedBoot* verified_boot_state,
837 bool* device_locked, vector<uint8_t>* verified_boot_hash) {
838 X509_Ptr cert(parse_cert_blob(attestation_cert));
839 ASSERT_TRUE(cert.get());
840
841 ASN1_OCTET_STRING* attest_rec = get_attestation_record(cert.get());
842 ASSERT_TRUE(attest_rec);
843
844 auto error = parse_root_of_trust(attest_rec->data, attest_rec->length, verified_boot_key,
845 verified_boot_state, device_locked, verified_boot_hash);
846 ASSERT_EQ(error, ErrorCode::OK);
847}
848
849/**
850 * Generate a CSR and verify DeviceInfo against IDs attested by KeyMint.
851 */
852TEST_P(CertificateRequestV2Test, DeviceInfo) {
853 // See if there is a matching IKeyMintDevice for this IRemotelyProvisionedComponent.
854 std::shared_ptr<IKeyMintDevice> keyMint;
855 if (!matching_keymint_device(GetParam(), &keyMint)) {
856 // No matching IKeyMintDevice.
857 GTEST_SKIP() << "Skipping key use test as no matching KeyMint device found";
858 return;
859 }
860 KeyMintHardwareInfo info;
861 ASSERT_TRUE(keyMint->getHardwareInfo(&info).isOk());
862
863 // Get IDs attested by KeyMint.
864 MacedPublicKey macedPubKey;
865 bytevec privateKeyBlob;
866 auto irpcStatus =
867 provisionable_->generateEcdsaP256KeyPair(false, &macedPubKey, &privateKeyBlob);
868 ASSERT_TRUE(irpcStatus.isOk());
869
870 AttestationKey attestKey;
871 attestKey.keyBlob = std::move(privateKeyBlob);
872 attestKey.issuerSubjectName = make_name_from_str("Android Keystore Key");
873
874 // Generate an ECDSA key that is attested by the generated P256 keypair.
875 AuthorizationSet keyDesc = AuthorizationSetBuilder()
876 .Authorization(TAG_NO_AUTH_REQUIRED)
877 .EcdsaSigningKey(EcCurve::P_256)
878 .AttestationChallenge("foo")
879 .AttestationApplicationId("bar")
880 .Digest(Digest::NONE)
881 .SetDefaultValidity();
882 KeyCreationResult creationResult;
883 auto kmStatus = keyMint->generateKey(keyDesc.vector_data(), attestKey, &creationResult);
884 ASSERT_TRUE(kmStatus.isOk());
885
886 vector<KeyCharacteristics> key_characteristics = std::move(creationResult.keyCharacteristics);
887 vector<Certificate> key_cert_chain = std::move(creationResult.certificateChain);
888 // We didn't provision the attestation key.
889 ASSERT_EQ(key_cert_chain.size(), 1);
890
891 // Parse attested patch levels.
892 auto auths = HwEnforcedAuthorizations(key_characteristics);
893
894 auto attestedSystemPatchLevel = auths.GetTagValue(TAG_OS_PATCHLEVEL);
895 auto attestedVendorPatchLevel = auths.GetTagValue(TAG_VENDOR_PATCHLEVEL);
896 auto attestedBootPatchLevel = auths.GetTagValue(TAG_BOOT_PATCHLEVEL);
897
898 ASSERT_TRUE(attestedSystemPatchLevel.has_value());
899 ASSERT_TRUE(attestedVendorPatchLevel.has_value());
900 ASSERT_TRUE(attestedBootPatchLevel.has_value());
901
902 // Parse attested AVB values.
903 vector<uint8_t> key;
904 VerifiedBoot attestedVbState;
905 bool attestedBootloaderState;
906 vector<uint8_t> attestedVbmetaDigest;
907 parse_root_of_trust(key_cert_chain[0].encodedCertificate, &key, &attestedVbState,
908 &attestedBootloaderState, &attestedVbmetaDigest);
909
910 // Get IDs from DeviceInfo.
911 bytevec csr;
912 irpcStatus =
913 provisionable_->generateCertificateRequestV2({} /* keysToSign */, challenge_, &csr);
914 ASSERT_TRUE(irpcStatus.isOk()) << irpcStatus.getMessage();
915
916 auto result = verifyProductionCsr(cppbor::Array(), csr, provisionable_.get(), challenge_);
917 ASSERT_TRUE(result) << result.message();
918
919 std::unique_ptr<cppbor::Array> csrPayload = std::move(*result);
920 ASSERT_TRUE(csrPayload);
921
922 auto deviceInfo = csrPayload->get(2)->asMap();
923 ASSERT_TRUE(deviceInfo);
924
925 auto vbState = deviceInfo->get("vb_state")->asTstr();
926 auto bootloaderState = deviceInfo->get("bootloader_state")->asTstr();
927 auto vbmetaDigest = deviceInfo->get("vbmeta_digest")->asBstr();
928 auto systemPatchLevel = deviceInfo->get("system_patch_level")->asUint();
929 auto vendorPatchLevel = deviceInfo->get("vendor_patch_level")->asUint();
930 auto bootPatchLevel = deviceInfo->get("boot_patch_level")->asUint();
931 auto securityLevel = deviceInfo->get("security_level")->asTstr();
932
933 ASSERT_TRUE(vbState);
934 ASSERT_TRUE(bootloaderState);
935 ASSERT_TRUE(vbmetaDigest);
936 ASSERT_TRUE(systemPatchLevel);
937 ASSERT_TRUE(vendorPatchLevel);
938 ASSERT_TRUE(bootPatchLevel);
939 ASSERT_TRUE(securityLevel);
940
941 auto kmDeviceName = device_suffix(GetParam());
942
943 // Compare DeviceInfo against IDs attested by KeyMint.
944 ASSERT_TRUE((securityLevel->value() == "tee" && kmDeviceName == "default") ||
945 (securityLevel->value() == "strongbox" && kmDeviceName == "strongbox"));
946 ASSERT_TRUE((vbState->value() == "green" && attestedVbState == VerifiedBoot::VERIFIED) ||
947 (vbState->value() == "yellow" && attestedVbState == VerifiedBoot::SELF_SIGNED) ||
948 (vbState->value() == "orange" && attestedVbState == VerifiedBoot::UNVERIFIED));
949 ASSERT_TRUE((bootloaderState->value() == "locked" && attestedBootloaderState) ||
950 (bootloaderState->value() == "unlocked" && !attestedBootloaderState));
951 ASSERT_EQ(vbmetaDigest->value(), attestedVbmetaDigest);
952 ASSERT_EQ(systemPatchLevel->value(), attestedSystemPatchLevel.value());
953 ASSERT_EQ(vendorPatchLevel->value(), attestedVendorPatchLevel.value());
954 ASSERT_EQ(bootPatchLevel->value(), attestedBootPatchLevel.value());
955}
956
Tri Vo0d6204e2022-09-29 16:15:34 -0700957INSTANTIATE_REM_PROV_AIDL_TEST(CertificateRequestV2Test);
958
Max Biresa9b3bb92022-11-21 23:02:09 -0800959using VsrRequirementTest = VtsRemotelyProvisionedComponentTests;
960
961INSTANTIATE_REM_PROV_AIDL_TEST(VsrRequirementTest);
962
963TEST_P(VsrRequirementTest, VsrEnforcementTest) {
964 RpcHardwareInfo hwInfo;
965 ASSERT_TRUE(provisionable_->getHardwareInfo(&hwInfo).isOk());
966 int vsr_api_level = get_vsr_api_level();
967 if (vsr_api_level < 34) {
968 GTEST_SKIP() << "Applies only to VSR API level 34 or newer, this device is: "
969 << vsr_api_level;
970 }
971 EXPECT_GE(hwInfo.versionNumber, 3)
972 << "VSR 14+ requires IRemotelyProvisionedComponent v3 or newer.";
973}
974
Shawn Willden274bb552020-09-30 22:39:22 -0600975} // namespace aidl::android::hardware::security::keymint::test