1 /*
2 * Copyright (C) 2014 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 <UniquePtr.h>
18
19 #include <gtest/gtest.h>
20
21 #include <keymaster/keymaster_tags.h>
22 #include <keymaster/google_keymaster_utils.h>
23
24 #include "google_keymaster_test_utils.h"
25 #include "google_softkeymaster.h"
26
main(int argc,char ** argv)27 int main(int argc, char** argv) {
28 ::testing::InitGoogleTest(&argc, argv);
29 int result = RUN_ALL_TESTS();
30 return result;
31 }
32
33 namespace keymaster {
34 namespace test {
35
36 /**
37 * Serialize and deserialize a message.
38 */
round_trip(const Message & message,size_t expected_size)39 template <typename Message> Message* round_trip(const Message& message, size_t expected_size) {
40 size_t size = message.SerializedSize();
41 EXPECT_EQ(expected_size, size);
42 if (size == 0)
43 return NULL;
44
45 UniquePtr<uint8_t[]> buf(new uint8_t[size]);
46 EXPECT_EQ(buf.get() + size, message.Serialize(buf.get(), buf.get() + size));
47
48 Message* deserialized = new Message;
49 const uint8_t* p = buf.get();
50 EXPECT_TRUE(deserialized->Deserialize(&p, p + size));
51 EXPECT_EQ((ptrdiff_t)size, p - buf.get());
52 return deserialized;
53 }
54
55 class EmptyKeymasterResponse : public KeymasterResponse {
NonErrorSerializedSize() const56 size_t NonErrorSerializedSize() const { return 1; }
NonErrorSerialize(uint8_t * buf,const uint8_t *) const57 uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* /* end */) const {
58 *buf++ = 0;
59 return buf;
60 }
NonErrorDeserialize(const uint8_t ** buf_ptr,const uint8_t * end)61 bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) {
62 if (*buf_ptr >= end)
63 return false;
64 EXPECT_EQ(0, **buf_ptr);
65 (*buf_ptr)++;
66 return true;
67 }
68 };
69
TEST(RoundTrip,EmptyKeymasterResponse)70 TEST(RoundTrip, EmptyKeymasterResponse) {
71 EmptyKeymasterResponse msg;
72 msg.error = KM_ERROR_OK;
73
74 UniquePtr<EmptyKeymasterResponse> deserialized(round_trip(msg, 5));
75 }
76
TEST(RoundTrip,EmptyKeymasterResponseError)77 TEST(RoundTrip, EmptyKeymasterResponseError) {
78 EmptyKeymasterResponse msg;
79 msg.error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
80
81 UniquePtr<EmptyKeymasterResponse> deserialized(round_trip(msg, 4));
82 }
83
TEST(RoundTrip,SupportedAlgorithmsResponse)84 TEST(RoundTrip, SupportedAlgorithmsResponse) {
85 SupportedAlgorithmsResponse rsp;
86 keymaster_algorithm_t algorithms[] = {KM_ALGORITHM_RSA, KM_ALGORITHM_DSA, KM_ALGORITHM_ECDSA};
87 rsp.error = KM_ERROR_OK;
88 rsp.algorithms = dup_array(algorithms);
89 rsp.algorithms_length = array_length(algorithms);
90
91 UniquePtr<SupportedAlgorithmsResponse> deserialized(round_trip(rsp, 20));
92 EXPECT_EQ(array_length(algorithms), deserialized->algorithms_length);
93 EXPECT_EQ(0, memcmp(deserialized->algorithms, algorithms, array_size(algorithms)));
94 }
95
TEST(RoundTrip,SupportedResponse)96 TEST(RoundTrip, SupportedResponse) {
97 SupportedResponse<keymaster_digest_t> rsp;
98 keymaster_digest_t digests[] = {KM_DIGEST_NONE, KM_DIGEST_MD5, KM_DIGEST_SHA1};
99 rsp.error = KM_ERROR_OK;
100 rsp.SetResults(digests);
101
102 UniquePtr<SupportedResponse<keymaster_digest_t>> deserialized(round_trip(rsp, 20));
103 EXPECT_EQ(array_length(digests), deserialized->results_length);
104 EXPECT_EQ(0, memcmp(deserialized->results, digests, array_size(digests)));
105 }
106
107 static keymaster_key_param_t params[] = {
108 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
109 Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), Authorization(TAG_USER_ID, 7),
110 Authorization(TAG_USER_AUTH_ID, 8), Authorization(TAG_APPLICATION_ID, "app_id", 6),
111 Authorization(TAG_AUTH_TIMEOUT, 300),
112 };
113 uint8_t TEST_DATA[] = "a key blob";
114
TEST(RoundTrip,GenerateKeyRequest)115 TEST(RoundTrip, GenerateKeyRequest) {
116 GenerateKeyRequest req;
117 req.key_description.Reinitialize(params, array_length(params));
118 UniquePtr<GenerateKeyRequest> deserialized(round_trip(req, 78));
119 EXPECT_EQ(deserialized->key_description, req.key_description);
120 }
121
TEST(RoundTrip,GenerateKeyResponse)122 TEST(RoundTrip, GenerateKeyResponse) {
123 GenerateKeyResponse rsp;
124 rsp.error = KM_ERROR_OK;
125 rsp.key_blob.key_material = dup_array(TEST_DATA);
126 rsp.key_blob.key_material_size = array_length(TEST_DATA);
127 rsp.enforced.Reinitialize(params, array_length(params));
128
129 UniquePtr<GenerateKeyResponse> deserialized(round_trip(rsp, 109));
130 EXPECT_EQ(KM_ERROR_OK, deserialized->error);
131 EXPECT_EQ(deserialized->enforced, rsp.enforced);
132 EXPECT_EQ(deserialized->unenforced, rsp.unenforced);
133 }
134
TEST(RoundTrip,GenerateKeyResponseTestError)135 TEST(RoundTrip, GenerateKeyResponseTestError) {
136 GenerateKeyResponse rsp;
137 rsp.error = KM_ERROR_UNSUPPORTED_ALGORITHM;
138 rsp.key_blob.key_material = dup_array(TEST_DATA);
139 rsp.key_blob.key_material_size = array_length(TEST_DATA);
140 rsp.enforced.Reinitialize(params, array_length(params));
141
142 UniquePtr<GenerateKeyResponse> deserialized(round_trip(rsp, 4));
143 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM, deserialized->error);
144 EXPECT_EQ(0U, deserialized->enforced.size());
145 EXPECT_EQ(0U, deserialized->unenforced.size());
146 EXPECT_EQ(0U, deserialized->key_blob.key_material_size);
147 }
148
TEST(RoundTrip,GetKeyCharacteristicsRequest)149 TEST(RoundTrip, GetKeyCharacteristicsRequest) {
150 GetKeyCharacteristicsRequest req;
151 req.additional_params.Reinitialize(params, array_length(params));
152 req.SetKeyMaterial("foo", 3);
153
154 UniquePtr<GetKeyCharacteristicsRequest> deserialized(round_trip(req, 85));
155 EXPECT_EQ(7U, deserialized->additional_params.size());
156 EXPECT_EQ(3U, deserialized->key_blob.key_material_size);
157 EXPECT_EQ(0, memcmp(deserialized->key_blob.key_material, "foo", 3));
158 }
159
TEST(RoundTrip,GetKeyCharacteristicsResponse)160 TEST(RoundTrip, GetKeyCharacteristicsResponse) {
161 GetKeyCharacteristicsResponse msg;
162 msg.error = KM_ERROR_OK;
163 msg.enforced.Reinitialize(params, array_length(params));
164 msg.unenforced.Reinitialize(params, array_length(params));
165
166 UniquePtr<GetKeyCharacteristicsResponse> deserialized(round_trip(msg, 160));
167 EXPECT_EQ(msg.enforced, deserialized->enforced);
168 EXPECT_EQ(msg.unenforced, deserialized->unenforced);
169 }
170
TEST(RoundTrip,BeginOperationRequest)171 TEST(RoundTrip, BeginOperationRequest) {
172 BeginOperationRequest msg;
173 msg.purpose = KM_PURPOSE_SIGN;
174 msg.SetKeyMaterial("foo", 3);
175 msg.additional_params.Reinitialize(params, array_length(params));
176
177 UniquePtr<BeginOperationRequest> deserialized(round_trip(msg, 89));
178 EXPECT_EQ(KM_PURPOSE_SIGN, deserialized->purpose);
179 EXPECT_EQ(3U, deserialized->key_blob.key_material_size);
180 EXPECT_EQ(0, memcmp(deserialized->key_blob.key_material, "foo", 3));
181 EXPECT_EQ(msg.additional_params, deserialized->additional_params);
182 }
183
TEST(RoundTrip,BeginOperationResponse)184 TEST(RoundTrip, BeginOperationResponse) {
185 BeginOperationResponse msg;
186 msg.error = KM_ERROR_OK;
187 msg.op_handle = 0xDEADBEEF;
188
189 UniquePtr<BeginOperationResponse> deserialized(round_trip(msg, 12));
190 EXPECT_EQ(KM_ERROR_OK, deserialized->error);
191 EXPECT_EQ(0xDEADBEEF, deserialized->op_handle);
192 }
193
TEST(RoundTrip,BeginOperationResponseError)194 TEST(RoundTrip, BeginOperationResponseError) {
195 BeginOperationResponse msg;
196 msg.error = KM_ERROR_INVALID_OPERATION_HANDLE;
197 msg.op_handle = 0xDEADBEEF;
198
199 UniquePtr<BeginOperationResponse> deserialized(round_trip(msg, 4));
200 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, deserialized->error);
201 }
202
TEST(RoundTrip,UpdateOperationRequest)203 TEST(RoundTrip, UpdateOperationRequest) {
204 UpdateOperationRequest msg;
205 msg.op_handle = 0xDEADBEEF;
206 msg.input.Reinitialize("foo", 3);
207
208 UniquePtr<UpdateOperationRequest> deserialized(round_trip(msg, 15));
209 EXPECT_EQ(3U, deserialized->input.available_read());
210 EXPECT_EQ(0, memcmp(deserialized->input.peek_read(), "foo", 3));
211 }
212
TEST(RoundTrip,UpdateOperationResponse)213 TEST(RoundTrip, UpdateOperationResponse) {
214 UpdateOperationResponse msg;
215 msg.error = KM_ERROR_OK;
216 msg.output.Reinitialize("foo", 3);
217
218 UniquePtr<UpdateOperationResponse> deserialized(round_trip(msg, 11));
219 EXPECT_EQ(KM_ERROR_OK, deserialized->error);
220 EXPECT_EQ(3U, deserialized->output.available_read());
221 EXPECT_EQ(0, memcmp(deserialized->output.peek_read(), "foo", 3));
222 }
223
TEST(RoundTrip,FinishOperationRequest)224 TEST(RoundTrip, FinishOperationRequest) {
225 FinishOperationRequest msg;
226 msg.op_handle = 0xDEADBEEF;
227 msg.signature.Reinitialize("bar", 3);
228
229 UniquePtr<FinishOperationRequest> deserialized(round_trip(msg, 15));
230 EXPECT_EQ(0xDEADBEEF, deserialized->op_handle);
231 EXPECT_EQ(3U, deserialized->signature.available_read());
232 EXPECT_EQ(0, memcmp(deserialized->signature.peek_read(), "bar", 3));
233 }
234
TEST(Round_Trip,FinishOperationResponse)235 TEST(Round_Trip, FinishOperationResponse) {
236 FinishOperationResponse msg;
237 msg.error = KM_ERROR_OK;
238 msg.output.Reinitialize("foo", 3);
239
240 UniquePtr<FinishOperationResponse> deserialized(round_trip(msg, 11));
241 EXPECT_EQ(msg.error, deserialized->error);
242 EXPECT_EQ(msg.output.available_read(), deserialized->output.available_read());
243 EXPECT_EQ(0, memcmp(msg.output.peek_read(), deserialized->output.peek_read(),
244 msg.output.available_read()));
245 }
246
TEST(RoundTrip,ImportKeyRequest)247 TEST(RoundTrip, ImportKeyRequest) {
248 ImportKeyRequest msg;
249 msg.key_description.Reinitialize(params, array_length(params));
250 msg.key_format = KM_KEY_FORMAT_X509;
251 msg.SetKeyMaterial("foo", 3);
252
253 UniquePtr<ImportKeyRequest> deserialized(round_trip(msg, 89));
254 EXPECT_EQ(msg.key_description, deserialized->key_description);
255 EXPECT_EQ(msg.key_format, deserialized->key_format);
256 EXPECT_EQ(msg.key_data_length, deserialized->key_data_length);
257 EXPECT_EQ(0, memcmp(msg.key_data, deserialized->key_data, msg.key_data_length));
258 }
259
TEST(RoundTrip,ImportKeyResponse)260 TEST(RoundTrip, ImportKeyResponse) {
261 ImportKeyResponse msg;
262 msg.error = KM_ERROR_OK;
263 msg.SetKeyMaterial("foo", 3);
264 msg.enforced.Reinitialize(params, array_length(params));
265 msg.unenforced.Reinitialize(params, array_length(params));
266
267 UniquePtr<ImportKeyResponse> deserialized(round_trip(msg, 167));
268 EXPECT_EQ(msg.error, deserialized->error);
269 EXPECT_EQ(msg.key_blob.key_material_size, deserialized->key_blob.key_material_size);
270 EXPECT_EQ(0, memcmp(msg.key_blob.key_material, deserialized->key_blob.key_material,
271 msg.key_blob.key_material_size));
272 EXPECT_EQ(msg.enforced, deserialized->enforced);
273 EXPECT_EQ(msg.unenforced, deserialized->unenforced);
274 }
275
TEST(RoundTrip,ExportKeyRequest)276 TEST(RoundTrip, ExportKeyRequest) {
277 ExportKeyRequest msg;
278 msg.additional_params.Reinitialize(params, array_length(params));
279 msg.key_format = KM_KEY_FORMAT_X509;
280 msg.SetKeyMaterial("foo", 3);
281
282 UniquePtr<ExportKeyRequest> deserialized(round_trip(msg, 89));
283 EXPECT_EQ(msg.additional_params, deserialized->additional_params);
284 EXPECT_EQ(msg.key_format, deserialized->key_format);
285 EXPECT_EQ(3U, deserialized->key_blob.key_material_size);
286 EXPECT_EQ(0, memcmp("foo", deserialized->key_blob.key_material, 3));
287 }
288
TEST(RoundTrip,ExportKeyResponse)289 TEST(RoundTrip, ExportKeyResponse) {
290 ExportKeyResponse msg;
291 msg.error = KM_ERROR_OK;
292 msg.SetKeyMaterial("foo", 3);
293
294 UniquePtr<ExportKeyResponse> deserialized(round_trip(msg, 11));
295 EXPECT_EQ(3U, deserialized->key_data_length);
296 EXPECT_EQ(0, memcmp("foo", deserialized->key_data, 3));
297 }
298
299 uint8_t msgbuf[] = {
300 220, 88, 183, 255, 71, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
301 0, 173, 0, 0, 0, 228, 174, 98, 187, 191, 135, 253, 200, 51, 230, 114, 247, 151, 109,
302 237, 79, 87, 32, 94, 5, 204, 46, 154, 30, 91, 6, 103, 148, 254, 129, 65, 171, 228,
303 167, 224, 163, 9, 15, 206, 90, 58, 11, 205, 55, 211, 33, 87, 178, 149, 91, 28, 236,
304 218, 112, 231, 34, 82, 82, 134, 103, 137, 115, 27, 156, 102, 159, 220, 226, 89, 42, 25,
305 37, 9, 84, 239, 76, 161, 198, 72, 167, 163, 39, 91, 148, 191, 17, 191, 87, 169, 179,
306 136, 10, 194, 154, 4, 40, 107, 109, 61, 161, 20, 176, 247, 13, 214, 106, 229, 45, 17,
307 5, 60, 189, 64, 39, 166, 208, 14, 57, 25, 140, 148, 25, 177, 246, 189, 43, 181, 88,
308 204, 29, 126, 224, 100, 143, 93, 60, 57, 249, 55, 0, 87, 83, 227, 224, 166, 59, 214,
309 81, 144, 129, 58, 6, 57, 46, 254, 232, 41, 220, 209, 230, 167, 138, 158, 94, 180, 125,
310 247, 26, 162, 116, 238, 202, 187, 100, 65, 13, 180, 44, 245, 159, 83, 161, 176, 58, 72,
311 236, 109, 105, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
312 0, 11, 0, 0, 0, 98, 0, 0, 0, 1, 0, 0, 32, 2, 0, 0, 0, 1, 0,
313 0, 32, 3, 0, 0, 0, 2, 0, 0, 16, 1, 0, 0, 0, 3, 0, 0, 48, 0,
314 1, 0, 0, 200, 0, 0, 80, 3, 0, 0, 0, 0, 0, 0, 0, 244, 1, 0, 112,
315 1, 246, 1, 0, 112, 1, 189, 2, 0, 96, 144, 178, 236, 250, 255, 255, 255, 255, 145,
316 1, 0, 96, 144, 226, 33, 60, 222, 2, 0, 0, 189, 2, 0, 96, 0, 0, 0, 0,
317 0, 0, 0, 0, 190, 2, 0, 16, 1, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0,
318 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 0, 0, 0, 0, 0, 0, 0, 11, 0,
319 0, 0, 98, 0, 0, 0, 1, 0, 0, 32, 2, 0, 0, 0, 1, 0, 0, 32, 3,
320 0, 0, 0, 2, 0, 0, 16, 1, 0, 0, 0, 3, 0, 0, 48, 0, 1, 0, 0,
321 200, 0, 0, 80, 3, 0, 0, 0, 0, 0, 0, 0, 244, 1, 0, 112, 1, 246, 1,
322 0, 112, 1, 189, 2, 0, 96, 144, 178, 236, 250, 255, 255, 255, 255, 145, 1, 0, 96,
323 144, 226, 33, 60, 222, 2, 0, 0, 189, 2, 0, 96, 0, 0, 0, 0, 0, 0, 0,
324 0, 190, 2, 0, 16, 1, 0, 0, 0,
325 };
326
327 /*
328 * These tests don't have any assertions or expectations. They just try to parse garbage, to see if
329 * the result will be a crash. This is especially informative when run under Valgrind memcheck.
330 */
331
parse_garbage()332 template <typename Message> void parse_garbage() {
333 Message msg;
334 const uint8_t* end = msgbuf + array_length(msgbuf);
335 for (size_t i = 0; i < array_length(msgbuf); ++i) {
336 const uint8_t* begin = msgbuf + i;
337 const uint8_t* p = begin;
338 msg.Deserialize(&p, end);
339 }
340 }
341
342 #define GARBAGE_TEST(Message) \
343 TEST(GarbageTest, Message) { parse_garbage<Message>(); }
344
345 GARBAGE_TEST(SupportedAlgorithmsResponse)
346 GARBAGE_TEST(GenerateKeyRequest);
347 GARBAGE_TEST(GenerateKeyResponse);
348 GARBAGE_TEST(GetKeyCharacteristicsRequest);
349 GARBAGE_TEST(GetKeyCharacteristicsResponse);
350 GARBAGE_TEST(BeginOperationRequest);
351 GARBAGE_TEST(BeginOperationResponse);
352 GARBAGE_TEST(UpdateOperationRequest);
353 GARBAGE_TEST(UpdateOperationResponse);
354 GARBAGE_TEST(FinishOperationRequest);
355 GARBAGE_TEST(FinishOperationResponse);
356 // GARBAGE_TEST(AddEntropyRequest);
357 GARBAGE_TEST(ImportKeyRequest);
358 GARBAGE_TEST(ImportKeyResponse);
359 GARBAGE_TEST(ExportKeyRequest);
360 GARBAGE_TEST(ExportKeyResponse);
361 // GARBAGE_TEST(RescopeRequest);
362 // GARBAGE_TEST(RescopeResponse);
363
364 // The macro doesn't work on this one.
TEST(GarbageTest,SupportedResponse)365 TEST(GarbageTest, SupportedResponse) {
366 parse_garbage<SupportedResponse<keymaster_digest_t>>();
367 }
368
369 } // namespace test
370 } // namespace keymaster
371