1 /*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "rkp_factory_extraction_lib.h"
18
19 #include "gmock/gmock-matchers.h"
20 #include "gmock/gmock-more-matchers.h"
21 #include <aidl/android/hardware/security/keymint/DeviceInfo.h>
22 #include <aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.h>
23 #include <aidl/android/hardware/security/keymint/MacedPublicKey.h>
24 #include <aidl/android/hardware/security/keymint/RpcHardwareInfo.h>
25 #include <android-base/properties.h>
26 #include <gmock/gmock.h>
27 #include <gtest/gtest.h>
28 #include <openssl/base64.h>
29
30 #include <cstdint>
31 #include <memory>
32 #include <ostream>
33 #include <set>
34 #include <vector>
35
36 #include "aidl/android/hardware/security/keymint/ProtectedData.h"
37 #include "android/binder_auto_utils.h"
38 #include "android/binder_interface_utils.h"
39 #include "cppbor.h"
40
41 using ::ndk::ScopedAStatus;
42 using ::ndk::SharedRefBase;
43
44 using namespace ::aidl::android::hardware::security::keymint;
45 using namespace ::cppbor;
46 using namespace ::testing;
47
48 namespace cppbor {
49
operator <<(std::ostream & os,const Item & item)50 std::ostream& operator<<(std::ostream& os, const Item& item) {
51 return os << prettyPrint(&item);
52 }
53
operator <<(std::ostream & os,const std::unique_ptr<Item> & item)54 std::ostream& operator<<(std::ostream& os, const std::unique_ptr<Item>& item) {
55 return os << *item;
56 }
57
operator <<(std::ostream & os,const Item * item)58 std::ostream& operator<<(std::ostream& os, const Item* item) {
59 return os << *item;
60 }
61
62 } // namespace cppbor
63
64 inline const std::vector<uint8_t> kCsrWithoutUdsCerts{
65 0x85, 0x01, 0xa0, 0x82, 0xa5, 0x01, 0x02, 0x03, 0x26, 0x20, 0x01, 0x21, 0x58, 0x20, 0xb8, 0x36,
66 0xbb, 0x1e, 0x07, 0x85, 0x02, 0xde, 0xdb, 0x91, 0x38, 0x5d, 0xc7, 0xf8, 0x59, 0xa9, 0x4f, 0x50,
67 0xee, 0x2a, 0x3f, 0xa5, 0x5f, 0xaa, 0xa1, 0x8e, 0x46, 0x84, 0xb8, 0x3b, 0x4b, 0x6d, 0x22, 0x58,
68 0x20, 0xa1, 0xc1, 0xd8, 0xa5, 0x9d, 0x1b, 0xce, 0x8c, 0x65, 0x10, 0x8d, 0xcf, 0xa1, 0xf4, 0x91,
69 0x10, 0x09, 0xfb, 0xb0, 0xc5, 0xb4, 0x01, 0x75, 0x72, 0xb4, 0x44, 0xaa, 0x23, 0x13, 0xe1, 0xe9,
70 0xe5, 0x84, 0x43, 0xa1, 0x01, 0x26, 0xa0, 0x59, 0x01, 0x04, 0xa9, 0x01, 0x66, 0x69, 0x73, 0x73,
71 0x75, 0x65, 0x72, 0x02, 0x67, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x00, 0x47, 0x44,
72 0x50, 0x58, 0x20, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
73 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
74 0x55, 0x55, 0x55, 0x3a, 0x00, 0x47, 0x44, 0x52, 0x58, 0x20, 0xb8, 0x96, 0x54, 0xe2, 0x2c, 0xa4,
75 0xd2, 0x4a, 0x9c, 0x0e, 0x45, 0x11, 0xc8, 0xf2, 0x63, 0xf0, 0x66, 0x0d, 0x2e, 0x20, 0x48, 0x96,
76 0x90, 0x14, 0xf4, 0x54, 0x63, 0xc4, 0xf4, 0x39, 0x30, 0x38, 0x3a, 0x00, 0x47, 0x44, 0x53, 0x55,
77 0xa1, 0x3a, 0x00, 0x01, 0x11, 0x71, 0x6e, 0x63, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74,
78 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x00, 0x47, 0x44, 0x54, 0x58, 0x20, 0x55, 0x55, 0x55, 0x55,
79 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
80 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x3a, 0x00, 0x47, 0x44,
81 0x56, 0x41, 0x01, 0x3a, 0x00, 0x47, 0x44, 0x57, 0x58, 0x4d, 0xa5, 0x01, 0x02, 0x03, 0x26, 0x20,
82 0x01, 0x21, 0x58, 0x20, 0x91, 0xdc, 0x49, 0x60, 0x0d, 0x22, 0xf6, 0x28, 0x14, 0xaf, 0xab, 0xa5,
83 0x9d, 0x4f, 0x26, 0xac, 0xf9, 0x99, 0xe7, 0xe1, 0xc9, 0xb7, 0x5d, 0x36, 0x21, 0x9d, 0x00, 0x47,
84 0x63, 0x28, 0x79, 0xa7, 0x22, 0x58, 0x20, 0x13, 0x77, 0x51, 0x7f, 0x6a, 0xca, 0xa0, 0x50, 0x79,
85 0x52, 0xb4, 0x6b, 0xd9, 0xb1, 0x3a, 0x1c, 0x9f, 0x91, 0x97, 0x60, 0xc1, 0x4b, 0x43, 0x5e, 0x45,
86 0xd3, 0x0b, 0xa4, 0xbb, 0xc7, 0x27, 0x39, 0x3a, 0x00, 0x47, 0x44, 0x58, 0x41, 0x20, 0x58, 0x40,
87 0x88, 0xbd, 0xf9, 0x82, 0x04, 0xfe, 0xa6, 0xfe, 0x82, 0x94, 0xa3, 0xe9, 0x10, 0x91, 0xb5, 0x2e,
88 0xa1, 0x62, 0x68, 0xa5, 0x3d, 0xab, 0xdb, 0xa5, 0x87, 0x2a, 0x97, 0x26, 0xb8, 0xd4, 0x60, 0x1a,
89 0xf1, 0x3a, 0x45, 0x72, 0x77, 0xd4, 0xeb, 0x2b, 0xa4, 0x48, 0x93, 0xba, 0xae, 0x79, 0x35, 0x57,
90 0x66, 0x54, 0x9d, 0x8e, 0xbd, 0xb0, 0x87, 0x5f, 0x8c, 0xf9, 0x04, 0xa3, 0xa7, 0x00, 0xf1, 0x21,
91 0x84, 0x43, 0xa1, 0x01, 0x26, 0xa0, 0x59, 0x02, 0x0f, 0x82, 0x58, 0x20, 0x01, 0x02, 0x03, 0x04,
92 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
93 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x59, 0x01, 0xe9, 0x84,
94 0x03, 0x67, 0x6b, 0x65, 0x79, 0x6d, 0x69, 0x6e, 0x74, 0xae, 0x65, 0x62, 0x72, 0x61, 0x6e, 0x64,
95 0x66, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x65, 0x66, 0x75, 0x73, 0x65, 0x64, 0x01, 0x65, 0x6d,
96 0x6f, 0x64, 0x65, 0x6c, 0x65, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x66, 0x64, 0x65, 0x76, 0x69, 0x63,
97 0x65, 0x66, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x67, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74,
98 0x65, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x68, 0x76, 0x62, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x65,
99 0x67, 0x72, 0x65, 0x65, 0x6e, 0x6a, 0x6f, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
100 0x62, 0x31, 0x32, 0x6c, 0x6d, 0x61, 0x6e, 0x75, 0x66, 0x61, 0x63, 0x74, 0x75, 0x72, 0x65, 0x72,
101 0x66, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x6d, 0x76, 0x62, 0x6d, 0x65, 0x74, 0x61, 0x5f, 0x64,
102 0x69, 0x67, 0x65, 0x73, 0x74, 0x4f, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa,
103 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x5f, 0x6c,
104 0x65, 0x76, 0x65, 0x6c, 0x63, 0x74, 0x65, 0x65, 0x70, 0x62, 0x6f, 0x6f, 0x74, 0x5f, 0x70, 0x61,
105 0x74, 0x63, 0x68, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x1a, 0x01, 0x34, 0x8c, 0x62, 0x70, 0x62,
106 0x6f, 0x6f, 0x74, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x66,
107 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x72, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x70, 0x61,
108 0x74, 0x63, 0x68, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x1a, 0x01, 0x34, 0x8c, 0x61, 0x72, 0x76,
109 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x70, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6c, 0x65, 0x76, 0x65,
110 0x6c, 0x1a, 0x01, 0x34, 0x8c, 0x63, 0x82, 0xa6, 0x01, 0x02, 0x03, 0x26, 0x20, 0x01, 0x21, 0x58,
111 0x20, 0x85, 0xcd, 0xd8, 0x8c, 0x35, 0x50, 0x11, 0x9c, 0x44, 0x24, 0xa7, 0xf1, 0xbf, 0x75, 0x6e,
112 0x7c, 0xab, 0x8c, 0x86, 0xfa, 0x23, 0x95, 0x2c, 0x11, 0xaf, 0xf9, 0x52, 0x80, 0x8f, 0x45, 0x43,
113 0x40, 0x22, 0x58, 0x20, 0xec, 0x4e, 0x0d, 0x5a, 0x81, 0xe8, 0x06, 0x12, 0x18, 0xa8, 0x10, 0x74,
114 0x6e, 0x56, 0x33, 0x11, 0x7d, 0x74, 0xff, 0x49, 0xf7, 0x38, 0x32, 0xda, 0xf4, 0x60, 0xaa, 0x19,
115 0x64, 0x29, 0x58, 0xbe, 0x23, 0x58, 0x21, 0x00, 0xa6, 0xd1, 0x85, 0xdb, 0x8b, 0x15, 0x84, 0xde,
116 0x34, 0xf2, 0xe3, 0xee, 0x73, 0x8b, 0x85, 0x57, 0xc1, 0xa3, 0x5d, 0x3f, 0x95, 0x14, 0xd3, 0x74,
117 0xfc, 0x73, 0x51, 0x7f, 0xe7, 0x1b, 0x30, 0xbb, 0xa6, 0x01, 0x02, 0x03, 0x26, 0x20, 0x01, 0x21,
118 0x58, 0x20, 0x96, 0x6c, 0x16, 0x6c, 0x4c, 0xa7, 0x73, 0x64, 0x9a, 0x34, 0x88, 0x75, 0xf4, 0xdc,
119 0xf3, 0x93, 0xb2, 0xf1, 0xd7, 0xfd, 0xe3, 0x11, 0xcf, 0x6b, 0xee, 0x26, 0xa4, 0xc5, 0xeb, 0xa5,
120 0x33, 0x24, 0x22, 0x58, 0x20, 0xe0, 0x33, 0xe8, 0x53, 0xb2, 0x65, 0x1e, 0x33, 0x2a, 0x61, 0x9a,
121 0x7a, 0xf4, 0x5f, 0x40, 0x0f, 0x80, 0x4a, 0x38, 0xff, 0x5d, 0x3c, 0xa3, 0x82, 0x36, 0x1e, 0x9d,
122 0x93, 0xd9, 0x48, 0xaa, 0x0a, 0x23, 0x58, 0x20, 0x5e, 0xe5, 0x8f, 0x9a, 0x8c, 0xd3, 0xf4, 0xc0,
123 0xf7, 0x08, 0x27, 0x5f, 0x8f, 0x77, 0x12, 0x36, 0x7b, 0x6d, 0xf7, 0x65, 0xd4, 0xcc, 0x63, 0xdc,
124 0x28, 0x35, 0x33, 0x27, 0x5d, 0x28, 0xc9, 0x9d, 0x58, 0x40, 0x6c, 0xfa, 0xc9, 0xc0, 0xdf, 0x0e,
125 0xe4, 0x17, 0x58, 0x06, 0xea, 0xf9, 0x88, 0x9e, 0x27, 0xa0, 0x89, 0x17, 0xa8, 0x1a, 0xe6, 0x0c,
126 0x5e, 0x85, 0xa1, 0x13, 0x20, 0x86, 0x14, 0x2e, 0xd6, 0xae, 0xfb, 0xc1, 0xb6, 0x59, 0x66, 0x83,
127 0xd2, 0xf4, 0xc8, 0x7a, 0x30, 0x0c, 0x6b, 0x53, 0x8b, 0x76, 0x06, 0xcb, 0x1b, 0x0f, 0xc3, 0x51,
128 0x71, 0x52, 0xd1, 0xe3, 0x2a, 0xbc, 0x53, 0x16, 0x46, 0x49, 0xa1, 0x6b, 0x66, 0x69, 0x6e, 0x67,
129 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x78, 0x3b, 0x62, 0x72, 0x61, 0x6e, 0x64, 0x31, 0x2f,
130 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x31, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x31,
131 0x3a, 0x31, 0x31, 0x2f, 0x69, 0x64, 0x2f, 0x32, 0x30, 0x32, 0x31, 0x30, 0x38, 0x30, 0x35, 0x2e,
132 0x34, 0x32, 0x3a, 0x75, 0x73, 0x65, 0x72, 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x2d,
133 0x6b, 0x65, 0x79, 0x73};
134
toBase64(const std::vector<uint8_t> & buffer)135 std::string toBase64(const std::vector<uint8_t>& buffer) {
136 size_t base64Length;
137 int rc = EVP_EncodedLength(&base64Length, buffer.size());
138 if (!rc) {
139 std::cerr << "Error getting base64 length. Size overflow?" << std::endl;
140 exit(-1);
141 }
142
143 std::string base64(base64Length, ' ');
144 rc = EVP_EncodeBlock(reinterpret_cast<uint8_t*>(base64.data()), buffer.data(), buffer.size());
145 ++rc; // Account for NUL, which BoringSSL does not for some reason.
146 if (rc != base64Length) {
147 std::cerr << "Error writing base64. Expected " << base64Length
148 << " bytes to be written, but " << rc << " bytes were actually written."
149 << std::endl;
150 exit(-1);
151 }
152
153 // BoringSSL automatically adds a NUL -- remove it from the string data
154 base64.pop_back();
155
156 return base64;
157 }
158
159 class MockIRemotelyProvisionedComponent : public IRemotelyProvisionedComponentDefault {
160 public:
161 MOCK_METHOD(ScopedAStatus, getHardwareInfo, (RpcHardwareInfo * _aidl_return), (override));
162 MOCK_METHOD(ScopedAStatus, generateEcdsaP256KeyPair,
163 (bool in_testMode, MacedPublicKey* out_macedPublicKey,
164 std::vector<uint8_t>* _aidl_return),
165 (override));
166 MOCK_METHOD(ScopedAStatus, generateCertificateRequest,
167 (bool in_testMode, const std::vector<MacedPublicKey>& in_keysToSign,
168 const std::vector<uint8_t>& in_endpointEncryptionCertChain,
169 const std::vector<uint8_t>& in_challenge, DeviceInfo* out_deviceInfo,
170 ProtectedData* out_protectedData, std::vector<uint8_t>* _aidl_return),
171 (override));
172 MOCK_METHOD(ScopedAStatus, generateCertificateRequestV2,
173 (const std::vector<MacedPublicKey>& in_keysToSign,
174 const std::vector<uint8_t>& in_challenge, std::vector<uint8_t>* _aidl_return),
175 (override));
176 MOCK_METHOD(ScopedAStatus, getInterfaceVersion, (int32_t* _aidl_return), (override));
177 MOCK_METHOD(ScopedAStatus, getInterfaceHash, (std::string * _aidl_return), (override));
178 };
179
TEST(LibRkpFactoryExtractionTests,ToBase64)180 TEST(LibRkpFactoryExtractionTests, ToBase64) {
181 std::vector<uint8_t> input(UINT8_MAX + 1);
182 for (int i = 0; i < input.size(); ++i) {
183 input[i] = i;
184 }
185
186 // Test three lengths so we get all the different padding options
187 EXPECT_EQ("AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4"
188 "vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV"
189 "5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMj"
190 "Y6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8"
191 "vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uv"
192 "s7e7v8PHy8/T19vf4+fr7/P3+/w==",
193 toBase64(input));
194
195 input.push_back(42);
196 EXPECT_EQ("AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4"
197 "vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV"
198 "5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMj"
199 "Y6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8"
200 "vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uv"
201 "s7e7v8PHy8/T19vf4+fr7/P3+/yo=",
202 toBase64(input));
203
204 input.push_back(42);
205 EXPECT_EQ("AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4"
206 "vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV"
207 "5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMj"
208 "Y6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8"
209 "vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uv"
210 "s7e7v8PHy8/T19vf4+fr7/P3+/yoq",
211 toBase64(input));
212 }
213
TEST(LibRkpFactoryExtractionTests,UniqueChallengeSmokeTest)214 TEST(LibRkpFactoryExtractionTests, UniqueChallengeSmokeTest) {
215 // This will at least catch VERY broken implementations.
216 constexpr size_t NUM_CHALLENGES = 32;
217 std::set<std::vector<uint8_t>> challenges;
218 for (size_t i = 0; i < NUM_CHALLENGES; ++i) {
219 const std::vector<uint8_t> challenge = generateChallenge();
220 const auto [_, wasInserted] = challenges.insert(generateChallenge());
221 EXPECT_TRUE(wasInserted) << "Duplicate challenge: " << toBase64(challenge);
222 }
223 }
224
TEST(LibRkpFactoryExtractionTests,GetCsrWithV2Hal)225 TEST(LibRkpFactoryExtractionTests, GetCsrWithV2Hal) {
226 ASSERT_TRUE(true);
227
228 const std::vector<uint8_t> kFakeMac = {1, 2, 3, 4};
229
230 Map cborDeviceInfo;
231 cborDeviceInfo.add("product", "gShoe");
232 cborDeviceInfo.add("version", 2);
233 cborDeviceInfo.add("brand", "Fake Brand");
234 cborDeviceInfo.add("manufacturer", "Fake Mfr");
235 cborDeviceInfo.add("model", "Fake Model");
236 cborDeviceInfo.add("device", "Fake Device");
237 cborDeviceInfo.add("vb_state", "orange");
238 cborDeviceInfo.add("bootloader_state", "unlocked");
239 cborDeviceInfo.add("vbmeta_digest", std::vector<uint8_t>{1, 2, 3, 4});
240 cborDeviceInfo.add("system_patch_level", 42);
241 cborDeviceInfo.add("boot_patch_level", 31415);
242 cborDeviceInfo.add("vendor_patch_level", 0);
243 cborDeviceInfo.add("fused", 0);
244 cborDeviceInfo.add("security_level", "tee");
245 cborDeviceInfo.add("os_version", "the best version");
246 const DeviceInfo kVerifiedDeviceInfo = {cborDeviceInfo.canonicalize().encode()};
247
248 Array cborProtectedData;
249 cborProtectedData.add(Bstr()); // protected
250 cborProtectedData.add(Map()); // unprotected
251 cborProtectedData.add(Bstr()); // ciphertext
252 cborProtectedData.add(Array()); // recipients
253 const ProtectedData kProtectedData = {cborProtectedData.encode()};
254
255 std::vector<uint8_t> eekChain;
256 std::vector<uint8_t> challenge;
257
258 // Set up mock, then call getCsr
259 auto mockRpc = SharedRefBase::make<MockIRemotelyProvisionedComponent>();
260 EXPECT_CALL(*mockRpc, getHardwareInfo(NotNull())).WillRepeatedly([](RpcHardwareInfo* hwInfo) {
261 hwInfo->versionNumber = 2;
262 return ScopedAStatus::ok();
263 });
264 EXPECT_CALL(*mockRpc,
265 generateCertificateRequest(false, // testMode
266 IsEmpty(), // keysToSign
267 _, // endpointEncryptionCertChain
268 _, // challenge
269 NotNull(), // deviceInfo
270 NotNull(), // protectedData
271 NotNull())) // _aidl_return
272 .WillOnce(DoAll(SaveArg<2>(&eekChain), //
273 SaveArg<3>(&challenge), //
274 SetArgPointee<4>(kVerifiedDeviceInfo), //
275 SetArgPointee<5>(kProtectedData), //
276 SetArgPointee<6>(kFakeMac), //
277 Return(ByMove(ScopedAStatus::ok())))); //
278
279 auto [csr, csrErrMsg] =
280 getCsr("mock component name", mockRpc.get(),
281 /*selfTest=*/false, /*allowDegenerate=*/true, /*requireUdsCerts=*/false);
282 ASSERT_THAT(csr, NotNull()) << csrErrMsg;
283 ASSERT_THAT(csr->asArray(), Pointee(Property(&Array::size, Eq(4))));
284
285 // Verify the input parameters that we received
286 auto [parsedEek, ignore1, eekParseError] = parse(eekChain);
287 ASSERT_THAT(parsedEek, NotNull()) << eekParseError;
288 EXPECT_THAT(parsedEek->asArray(), Pointee(Property(&Array::size, Gt(1))));
289 EXPECT_THAT(challenge, Property(&std::vector<uint8_t>::size, Eq(kChallengeSize)));
290
291 // Device info consists of (verified info, unverified info)
292 const Array* deviceInfoArray = csr->get(0)->asArray();
293 EXPECT_THAT(deviceInfoArray, Pointee(Property(&Array::size, 2)));
294
295 // Verified device info must match our mock value
296 const Map* actualVerifiedDeviceInfo = deviceInfoArray->get(0)->asMap();
297 EXPECT_THAT(actualVerifiedDeviceInfo, Pointee(Property(&Map::size, Eq(cborDeviceInfo.size()))));
298 EXPECT_THAT(actualVerifiedDeviceInfo->get("product"), Pointee(Eq(Tstr("gShoe"))));
299 EXPECT_THAT(actualVerifiedDeviceInfo->get("version"), Pointee(Eq(Uint(2))));
300
301 // Empty unverified device info
302 const Map* actualUnverifiedDeviceInfo = deviceInfoArray->get(1)->asMap();
303 EXPECT_THAT(actualUnverifiedDeviceInfo, Pointee(Property(&Map::size, Eq(0))));
304
305 // Challenge must match the call to generateCertificateRequest
306 const Bstr* actualChallenge = csr->get(1)->asBstr();
307 EXPECT_THAT(actualChallenge, Pointee(Property(&Bstr::value, Eq(challenge))));
308
309 // Protected data must match the mock value
310 const Array* actualProtectedData = csr->get(2)->asArray();
311 EXPECT_THAT(actualProtectedData, Pointee(Eq(ByRef(cborProtectedData))));
312
313 // Ensure the maced public key matches the expected COSE_mac0
314 const Array* actualMacedKeys = csr->get(3)->asArray();
315 ASSERT_THAT(actualMacedKeys, Pointee(Property(&Array::size, Eq(4))));
316 ASSERT_THAT(actualMacedKeys->get(0)->asBstr(), NotNull());
317 auto [macProtectedParams, ignore2, macParamParseError] =
318 parse(actualMacedKeys->get(0)->asBstr());
319 ASSERT_THAT(macProtectedParams, NotNull()) << macParamParseError;
320 Map expectedMacProtectedParams;
321 expectedMacProtectedParams.add(1, 5);
322 EXPECT_THAT(macProtectedParams, Pointee(Eq(ByRef(expectedMacProtectedParams))));
323 EXPECT_THAT(actualMacedKeys->get(1)->asMap(), Pointee(Property(&Map::size, Eq(0))));
324 EXPECT_THAT(actualMacedKeys->get(2)->asNull(), NotNull());
325 EXPECT_THAT(actualMacedKeys->get(3)->asBstr(), Pointee(Eq(Bstr(kFakeMac))));
326 }
327
TEST(LibRkpFactoryExtractionTests,GetCsrWithV3Hal)328 TEST(LibRkpFactoryExtractionTests, GetCsrWithV3Hal) {
329 const std::vector<uint8_t> kCsr = Array()
330 .add(1 /* version */)
331 .add(Map() /* UdsCerts */)
332 .add(Array() /* DiceCertChain */)
333 .add(Array() /* SignedData */)
334 .encode();
335 std::vector<uint8_t> challenge;
336
337 // Set up mock, then call getCsr
338 auto mockRpc = SharedRefBase::make<MockIRemotelyProvisionedComponent>();
339 EXPECT_CALL(*mockRpc, getHardwareInfo(NotNull())).WillRepeatedly([](RpcHardwareInfo* hwInfo) {
340 hwInfo->versionNumber = 3;
341 return ScopedAStatus::ok();
342 });
343 EXPECT_CALL(*mockRpc,
344 generateCertificateRequestV2(IsEmpty(), // keysToSign
345 _, // challenge
346 NotNull())) // _aidl_return
347 .WillOnce(DoAll(SaveArg<1>(&challenge), SetArgPointee<2>(kCsr),
348 Return(ByMove(ScopedAStatus::ok()))));
349
350 auto [csr, csrErrMsg] =
351 getCsr("mock component name", mockRpc.get(),
352 /*selfTest=*/false, /*allowDegenerate=*/true, /*requireUdsCerts=*/false);
353 ASSERT_THAT(csr, NotNull()) << csrErrMsg;
354 ASSERT_THAT(csr, Pointee(Property(&Array::size, Eq(5))));
355
356 EXPECT_THAT(csr->get(0 /* version */), Pointee(Eq(Uint(1))));
357 EXPECT_THAT(csr->get(1)->asMap(), NotNull());
358 EXPECT_THAT(csr->get(2)->asArray(), NotNull());
359 EXPECT_THAT(csr->get(3)->asArray(), NotNull());
360
361 const Map* unverifedDeviceInfo = csr->get(4)->asMap();
362 ASSERT_THAT(unverifedDeviceInfo, NotNull());
363 EXPECT_THAT(unverifedDeviceInfo->get("fingerprint"), NotNull());
364 const Tstr fingerprint(android::base::GetProperty("ro.build.fingerprint", ""));
365 EXPECT_THAT(*unverifedDeviceInfo->get("fingerprint")->asTstr(), Eq(fingerprint));
366 }
367
TEST(LibRkpFactoryExtractionTests,requireUdsCerts)368 TEST(LibRkpFactoryExtractionTests, requireUdsCerts) {
369 const std::vector<uint8_t> csrEncoded = kCsrWithoutUdsCerts;
370 std::vector<uint8_t> challenge;
371
372 // Set up mock, then call getCsr
373 auto mockRpc = SharedRefBase::make<MockIRemotelyProvisionedComponent>();
374 EXPECT_CALL(*mockRpc, getHardwareInfo(NotNull())).WillRepeatedly([](RpcHardwareInfo* hwInfo) {
375 hwInfo->versionNumber = 3;
376 return ScopedAStatus::ok();
377 });
378 EXPECT_CALL(*mockRpc,
379 generateCertificateRequestV2(IsEmpty(), // keysToSign
380 _, // challenge
381 NotNull())) // _aidl_return
382 .WillOnce(DoAll(SaveArg<1>(&challenge), SetArgPointee<2>(csrEncoded),
383 Return(ByMove(ScopedAStatus::ok()))));
384
385 auto [csr, csrErrMsg] =
386 getCsr("default", mockRpc.get(),
387 /*selfTest=*/true, /*allowDegenerate=*/false, /*requireUdsCerts=*/true);
388 ASSERT_EQ(csr, nullptr);
389 ASSERT_THAT(csrErrMsg, testing::HasSubstr("UdsCerts are required"));
390 }
391
TEST(LibRkpFactoryExtractionTests,dontRequireUdsCerts)392 TEST(LibRkpFactoryExtractionTests, dontRequireUdsCerts) {
393 const std::vector<uint8_t> csrEncoded = kCsrWithoutUdsCerts;
394 std::vector<uint8_t> challenge;
395
396 // Set up mock, then call getCsr
397 auto mockRpc = SharedRefBase::make<MockIRemotelyProvisionedComponent>();
398 EXPECT_CALL(*mockRpc, getHardwareInfo(NotNull())).WillRepeatedly([](RpcHardwareInfo* hwInfo) {
399 hwInfo->versionNumber = 3;
400 return ScopedAStatus::ok();
401 });
402 EXPECT_CALL(*mockRpc,
403 generateCertificateRequestV2(IsEmpty(), // keysToSign
404 _, // challenge
405 NotNull())) // _aidl_return
406 .WillOnce(DoAll(SaveArg<1>(&challenge), SetArgPointee<2>(csrEncoded),
407 Return(ByMove(ScopedAStatus::ok()))));
408
409 auto [csr, csrErrMsg] =
410 getCsr("default", mockRpc.get(),
411 /*selfTest=*/true, /*allowDegenerate=*/false, /*requireUdsCerts=*/false);
412 ASSERT_EQ(csr, nullptr);
413 ASSERT_THAT(csrErrMsg, testing::HasSubstr("challenges do not match"));
414 }
415
TEST(LibRkpFactoryExtractionTests,parseCommaDelimitedString)416 TEST(LibRkpFactoryExtractionTests, parseCommaDelimitedString) {
417 const auto& rpcNames = "default,avf,,default,Strongbox,strongbox,,";
418 const auto& rpcSet = parseCommaDelimited(rpcNames);
419
420 ASSERT_EQ(rpcSet.size(), 4);
421 ASSERT_TRUE(rpcSet.count("") == 0);
422 ASSERT_TRUE(rpcSet.count("default") == 1);
423 ASSERT_TRUE(rpcSet.count("avf") == 1);
424 ASSERT_TRUE(rpcSet.count("strongbox") == 1);
425 ASSERT_TRUE(rpcSet.count("Strongbox") == 1);
426 }
427