blob: 055cfa307b67732629e1a46fb15268fe9bcc8d74 [file] [log] [blame]
Shawn Willden128ffe02014-08-06 12:31:33 -06001/*
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
Shawn Willden98d9b922014-08-26 08:14:10 -060021#include <keymaster/keymaster_tags.h>
22#include <keymaster/google_keymaster_utils.h>
23
Shawn Willdenda8485e2014-08-17 08:00:01 -060024#include "google_keymaster_test_utils.h"
Shawn Willden128ffe02014-08-06 12:31:33 -060025#include "google_softkeymaster.h"
26
27int main(int argc, char** argv) {
28 ::testing::InitGoogleTest(&argc, argv);
29 int result = RUN_ALL_TESTS();
30 return result;
31}
32
33namespace keymaster {
34namespace test {
35
Shawn Willdenda8485e2014-08-17 08:00:01 -060036/**
37 * Serialize and deserialize a message.
38 */
39template <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;
Shawn Willden128ffe02014-08-06 12:31:33 -060044
45 UniquePtr<uint8_t[]> buf(new uint8_t[size]);
Shawn Willdenda8485e2014-08-17 08:00:01 -060046 EXPECT_EQ(buf.get() + size, message.Serialize(buf.get(), buf.get() + size));
Shawn Willden128ffe02014-08-06 12:31:33 -060047
Shawn Willdenda8485e2014-08-17 08:00:01 -060048 Message* deserialized = new Message;
Shawn Willden58e1a542014-08-08 21:58:29 -060049 const uint8_t* p = buf.get();
Shawn Willdenda8485e2014-08-17 08:00:01 -060050 EXPECT_TRUE(deserialized->Deserialize(&p, p + size));
51 EXPECT_EQ((ptrdiff_t)size, p - buf.get());
52 return deserialized;
Shawn Willden128ffe02014-08-06 12:31:33 -060053}
54
Shawn Willdenda8485e2014-08-17 08:00:01 -060055class EmptyKeymasterResponse : public KeymasterResponse {
56 size_t NonErrorSerializedSize() const { return 1; }
57 uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* /* end */) const {
58 *buf++ = 0;
59 return buf;
60 }
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
70TEST(RoundTrip, EmptyKeymasterResponse) {
71 EmptyKeymasterResponse msg;
72 msg.error = KM_ERROR_OK;
73
74 UniquePtr<EmptyKeymasterResponse> deserialized(round_trip(msg, 5));
75}
76
77TEST(RoundTrip, EmptyKeymasterResponseError) {
78 EmptyKeymasterResponse msg;
79 msg.error = KM_ERROR_MEMORY_ALLOCATION_FAILED;
80
81 UniquePtr<EmptyKeymasterResponse> deserialized(round_trip(msg, 4));
82}
83
84TEST(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
96TEST(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
107static 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};
Shawn Willden128ffe02014-08-06 12:31:33 -0600113uint8_t TEST_DATA[] = "a key blob";
114
Shawn Willdenda8485e2014-08-17 08:00:01 -0600115TEST(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
122TEST(RoundTrip, GenerateKeyResponse) {
Shawn Willden128ffe02014-08-06 12:31:33 -0600123 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
Shawn Willdenf2282b32014-08-25 06:49:54 -0600129 UniquePtr<GenerateKeyResponse> deserialized(round_trip(rsp, 109));
Shawn Willdenda8485e2014-08-17 08:00:01 -0600130 EXPECT_EQ(KM_ERROR_OK, deserialized->error);
131 EXPECT_EQ(deserialized->enforced, rsp.enforced);
132 EXPECT_EQ(deserialized->unenforced, rsp.unenforced);
Shawn Willden128ffe02014-08-06 12:31:33 -0600133}
134
Shawn Willdenda8485e2014-08-17 08:00:01 -0600135TEST(RoundTrip, GenerateKeyResponseTestError) {
Shawn Willden128ffe02014-08-06 12:31:33 -0600136 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
Shawn Willdenda8485e2014-08-17 08:00:01 -0600142 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}
Shawn Willden128ffe02014-08-06 12:31:33 -0600148
Shawn Willdenda8485e2014-08-17 08:00:01 -0600149TEST(RoundTrip, GetKeyCharacteristicsRequest) {
150 GetKeyCharacteristicsRequest req;
151 req.additional_params.Reinitialize(params, array_length(params));
152 req.SetKeyMaterial("foo", 3);
Shawn Willden128ffe02014-08-06 12:31:33 -0600153
Shawn Willdenf2282b32014-08-25 06:49:54 -0600154 UniquePtr<GetKeyCharacteristicsRequest> deserialized(round_trip(req, 85));
Shawn Willdenda8485e2014-08-17 08:00:01 -0600155 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
160TEST(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
Shawn Willdenf2282b32014-08-25 06:49:54 -0600166 UniquePtr<GetKeyCharacteristicsResponse> deserialized(round_trip(msg, 160));
Shawn Willdenda8485e2014-08-17 08:00:01 -0600167 EXPECT_EQ(msg.enforced, deserialized->enforced);
168 EXPECT_EQ(msg.unenforced, deserialized->unenforced);
169}
170
171TEST(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
184TEST(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
194TEST(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
203TEST(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
213TEST(RoundTrip, UpdateOperationResponse) {
214 UpdateOperationResponse msg;
215 msg.error = KM_ERROR_OK;
216 msg.output.Reinitialize("foo", 3);
217
Shawn Willden5da34d22015-01-20 11:44:47 -0700218 UniquePtr<UpdateOperationResponse> deserialized(round_trip(msg, 11));
Shawn Willdenda8485e2014-08-17 08:00:01 -0600219 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
224TEST(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
235TEST(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
247TEST(RoundTrip, ImportKeyRequest) {
248 ImportKeyRequest msg;
Shawn Willden437fbd12014-08-20 11:59:49 -0600249 msg.key_description.Reinitialize(params, array_length(params));
Shawn Willdenda8485e2014-08-17 08:00:01 -0600250 msg.key_format = KM_KEY_FORMAT_X509;
251 msg.SetKeyMaterial("foo", 3);
252
Shawn Willdenf2282b32014-08-25 06:49:54 -0600253 UniquePtr<ImportKeyRequest> deserialized(round_trip(msg, 89));
Shawn Willden437fbd12014-08-20 11:59:49 -0600254 EXPECT_EQ(msg.key_description, deserialized->key_description);
Shawn Willdenda8485e2014-08-17 08:00:01 -0600255 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
260TEST(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
Shawn Willdenf2282b32014-08-25 06:49:54 -0600267 UniquePtr<ImportKeyResponse> deserialized(round_trip(msg, 167));
Shawn Willdenda8485e2014-08-17 08:00:01 -0600268 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
276TEST(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
Shawn Willdenf2282b32014-08-25 06:49:54 -0600282 UniquePtr<ExportKeyRequest> deserialized(round_trip(msg, 89));
Shawn Willdenda8485e2014-08-17 08:00:01 -0600283 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
289TEST(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));
Shawn Willden128ffe02014-08-06 12:31:33 -0600297}
298
Shawn Willdenf2282b32014-08-25 06:49:54 -0600299uint8_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
332template <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
345GARBAGE_TEST(SupportedAlgorithmsResponse)
346GARBAGE_TEST(GenerateKeyRequest);
347GARBAGE_TEST(GenerateKeyResponse);
348GARBAGE_TEST(GetKeyCharacteristicsRequest);
349GARBAGE_TEST(GetKeyCharacteristicsResponse);
350GARBAGE_TEST(BeginOperationRequest);
351GARBAGE_TEST(BeginOperationResponse);
352GARBAGE_TEST(UpdateOperationRequest);
353GARBAGE_TEST(UpdateOperationResponse);
354GARBAGE_TEST(FinishOperationRequest);
355GARBAGE_TEST(FinishOperationResponse);
356// GARBAGE_TEST(AddEntropyRequest);
357GARBAGE_TEST(ImportKeyRequest);
358GARBAGE_TEST(ImportKeyResponse);
359GARBAGE_TEST(ExportKeyRequest);
360GARBAGE_TEST(ExportKeyResponse);
361// GARBAGE_TEST(RescopeRequest);
362// GARBAGE_TEST(RescopeResponse);
363
364// The macro doesn't work on this one.
365TEST(GarbageTest, SupportedResponse) {
366 parse_garbage<SupportedResponse<keymaster_digest_t>>();
367}
368
Shawn Willden128ffe02014-08-06 12:31:33 -0600369} // namespace test
370} // namespace keymaster