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