blob: 4c8c28e43dbfa13f0fe10b7b9ac6768211729095 [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 <gtest/gtest.h>
Shawn Willden76364712014-08-11 17:48:04 -060018
Shawn Willden128ffe02014-08-06 12:31:33 -060019#include <openssl/engine.h>
20
Shawn Willden76364712014-08-11 17:48:04 -060021#include "google_keymaster_test_utils.h"
Shawn Willden128ffe02014-08-06 12:31:33 -060022#include "google_keymaster_utils.h"
23#include "google_softkeymaster.h"
Shawn Willden76364712014-08-11 17:48:04 -060024#include "keymaster_tags.h"
Shawn Willden128ffe02014-08-06 12:31:33 -060025
26int main(int argc, char** argv) {
27 ::testing::InitGoogleTest(&argc, argv);
28 int result = RUN_ALL_TESTS();
29 // Clean up stuff OpenSSL leaves around, so Valgrind doesn't complain.
30 CRYPTO_cleanup_all_ex_data();
31 ERR_free_strings();
32 return result;
33}
34
35namespace keymaster {
36namespace test {
37
38class KeymasterTest : public testing::Test {
39 protected:
Shawn Willden1615f2e2014-08-13 10:37:40 -060040 KeymasterTest() : device(5) {
41 RAND_seed("foobar", 6);
Shawn Willden128ffe02014-08-06 12:31:33 -060042 }
43 ~KeymasterTest() {
44 }
45
46 GoogleSoftKeymaster device;
47};
48
49template <keymaster_tag_t Tag, typename KeymasterEnum>
50bool contains(const AuthorizationSet& set, TypedEnumTag<KM_ENUM, Tag, KeymasterEnum> tag,
51 KeymasterEnum val) {
52 int pos = set.find(tag);
53 return pos != -1 && set[pos].enumerated == val;
54}
55
56template <keymaster_tag_t Tag, typename KeymasterEnum>
57bool contains(const AuthorizationSet& set, TypedEnumTag<KM_ENUM_REP, Tag, KeymasterEnum> tag,
58 KeymasterEnum val) {
59 int pos = -1;
60 while ((pos = set.find(tag, pos)) != -1)
61 if (set[pos].enumerated == val)
62 return true;
63 return false;
64}
65
66template <keymaster_tag_t Tag>
67bool contains(const AuthorizationSet& set, TypedTag<KM_INT, Tag> tag, uint32_t val) {
68 int pos = set.find(tag);
69 return pos != -1 && set[pos].integer == val;
70}
71
72template <keymaster_tag_t Tag>
73bool contains(const AuthorizationSet& set, TypedTag<KM_INT_REP, Tag> tag, uint32_t val) {
74 int pos = -1;
75 while ((pos = set.find(tag, pos)) != -1)
76 if (set[pos].integer == val)
77 return true;
78 return false;
79}
80
81template <keymaster_tag_t Tag>
82bool contains(const AuthorizationSet& set, TypedTag<KM_LONG, Tag> tag, uint64_t val) {
83 int pos = set.find(tag);
84 return pos != -1 && set[pos].long_integer == val;
85}
86
87template <keymaster_tag_t Tag>
88bool contains(const AuthorizationSet& set, TypedTag<KM_BYTES, Tag> tag, const std::string& val) {
89 int pos = set.find(tag);
90 return pos != -1 &&
91 std::string(reinterpret_cast<const char*>(set[pos].blob.data),
92 set[pos].blob.data_length) == val;
93}
94
95inline bool contains(const AuthorizationSet& set, keymaster_tag_t tag) {
96 return set.find(tag) != -1;
97}
98
99typedef KeymasterTest CheckSupported;
100TEST_F(CheckSupported, SupportedAlgorithms) {
101 // Shouldn't blow up on NULL.
102 device.SupportedAlgorithms(NULL);
103
104 SupportedResponse<keymaster_algorithm_t> response;
105 device.SupportedAlgorithms(&response);
106 EXPECT_EQ(KM_ERROR_OK, response.error);
107 EXPECT_EQ(1U, response.results_length);
108 EXPECT_EQ(KM_ALGORITHM_RSA, response.results[0]);
109}
110
111TEST_F(CheckSupported, SupportedBlockModes) {
112 // Shouldn't blow up on NULL.
113 device.SupportedBlockModes(KM_ALGORITHM_RSA, NULL);
114
115 SupportedResponse<keymaster_block_mode_t> response;
116 device.SupportedBlockModes(KM_ALGORITHM_RSA, &response);
117 EXPECT_EQ(KM_ERROR_OK, response.error);
118 EXPECT_EQ(0U, response.results_length);
119
120 device.SupportedBlockModes(KM_ALGORITHM_DSA, &response);
121 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM, response.error);
122}
123
124TEST_F(CheckSupported, SupportedPaddingModes) {
125 // Shouldn't blow up on NULL.
126 device.SupportedPaddingModes(KM_ALGORITHM_RSA, NULL);
127
128 SupportedResponse<keymaster_padding_t> response;
129 device.SupportedPaddingModes(KM_ALGORITHM_RSA, &response);
130 EXPECT_EQ(KM_ERROR_OK, response.error);
131 EXPECT_EQ(1U, response.results_length);
132 EXPECT_EQ(KM_PAD_NONE, response.results[0]);
133
134 device.SupportedPaddingModes(KM_ALGORITHM_DSA, &response);
135 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM, response.error);
136}
137
138TEST_F(CheckSupported, SupportedDigests) {
139 // Shouldn't blow up on NULL.
140 device.SupportedDigests(KM_ALGORITHM_RSA, NULL);
141
142 SupportedResponse<keymaster_digest_t> response;
143 device.SupportedDigests(KM_ALGORITHM_RSA, &response);
144 EXPECT_EQ(KM_ERROR_OK, response.error);
145 EXPECT_EQ(1U, response.results_length);
146 EXPECT_EQ(KM_DIGEST_NONE, response.results[0]);
147
148 device.SupportedDigests(KM_ALGORITHM_DSA, &response);
149 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM, response.error);
150}
151
152TEST_F(CheckSupported, SupportedImportFormats) {
153 // Shouldn't blow up on NULL.
154 device.SupportedImportFormats(KM_ALGORITHM_RSA, NULL);
155
156 SupportedResponse<keymaster_key_format_t> response;
157 device.SupportedImportFormats(KM_ALGORITHM_RSA, &response);
158 EXPECT_EQ(KM_ERROR_OK, response.error);
159 EXPECT_EQ(1U, response.results_length);
160 EXPECT_EQ(KM_KEY_FORMAT_PKCS8, response.results[0]);
161
162 device.SupportedImportFormats(KM_ALGORITHM_DSA, &response);
163 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM, response.error);
164}
165
166TEST_F(CheckSupported, SupportedExportFormats) {
167 // Shouldn't blow up on NULL.
168 device.SupportedExportFormats(KM_ALGORITHM_RSA, NULL);
169
170 SupportedResponse<keymaster_key_format_t> response;
171 device.SupportedExportFormats(KM_ALGORITHM_RSA, &response);
172 EXPECT_EQ(KM_ERROR_OK, response.error);
173 EXPECT_EQ(1U, response.results_length);
174 EXPECT_EQ(KM_KEY_FORMAT_X509, response.results[0]);
175
176 device.SupportedExportFormats(KM_ALGORITHM_DSA, &response);
177 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM, response.error);
178}
179
180typedef KeymasterTest NewKeyGeneration;
181TEST_F(NewKeyGeneration, Rsa) {
182 keymaster_key_param_t params[] = {
183 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
184 Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
185 Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
Shawn Willden76364712014-08-11 17:48:04 -0600186 Authorization(TAG_KEY_SIZE, 256),
Shawn Willden128ffe02014-08-06 12:31:33 -0600187 Authorization(TAG_USER_ID, 7),
188 Authorization(TAG_USER_AUTH_ID, 8),
Shawn Willden76364712014-08-11 17:48:04 -0600189 Authorization(TAG_APPLICATION_ID, "app_id", 6),
190 Authorization(TAG_APPLICATION_DATA, "app_data", 8),
Shawn Willden128ffe02014-08-06 12:31:33 -0600191 Authorization(TAG_AUTH_TIMEOUT, 300),
192 };
193 GenerateKeyRequest req;
194 req.key_description.Reinitialize(params, array_length(params));
195 GenerateKeyResponse rsp;
196
197 device.GenerateKey(req, &rsp);
198
199 ASSERT_EQ(KM_ERROR_OK, rsp.error);
200 EXPECT_EQ(0U, rsp.enforced.size());
Shawn Willden8d336ae2014-08-09 15:47:05 -0600201 EXPECT_EQ(12U, rsp.enforced.SerializedSize());
202 EXPECT_GT(rsp.unenforced.SerializedSize(), 12U);
Shawn Willden128ffe02014-08-06 12:31:33 -0600203
204 // Check specified tags are all present in unenforced characteristics
205 EXPECT_TRUE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_SIGN));
206 EXPECT_TRUE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_VERIFY));
207
208 EXPECT_TRUE(contains(rsp.unenforced, TAG_ALGORITHM, KM_ALGORITHM_RSA));
209
210 EXPECT_TRUE(contains(rsp.unenforced, TAG_USER_ID, 7));
211 EXPECT_TRUE(contains(rsp.unenforced, TAG_USER_AUTH_ID, 8));
Shawn Willden76364712014-08-11 17:48:04 -0600212 EXPECT_TRUE(contains(rsp.unenforced, TAG_KEY_SIZE, 256));
Shawn Willden128ffe02014-08-06 12:31:33 -0600213 EXPECT_TRUE(contains(rsp.unenforced, TAG_AUTH_TIMEOUT, 300));
214
Shawn Willden39b970b2014-08-11 09:11:21 -0600215 // Verify that App ID, App data and ROT are NOT included.
216 EXPECT_FALSE(contains(rsp.unenforced, TAG_ROOT_OF_TRUST));
217 EXPECT_FALSE(contains(rsp.unenforced, TAG_APPLICATION_ID));
218 EXPECT_FALSE(contains(rsp.unenforced, TAG_APPLICATION_DATA));
219
Shawn Willden128ffe02014-08-06 12:31:33 -0600220 // Just for giggles, check that some unexpected tags/values are NOT present.
221 EXPECT_FALSE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
222 EXPECT_FALSE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_DECRYPT));
223 EXPECT_FALSE(contains(rsp.unenforced, TAG_AUTH_TIMEOUT, 301));
224 EXPECT_FALSE(contains(rsp.unenforced, TAG_RESCOPE_AUTH_TIMEOUT));
225
226 // Now check that unspecified, defaulted tags are correct.
227 EXPECT_TRUE(contains(rsp.unenforced, TAG_RSA_PUBLIC_EXPONENT, 65537));
228 EXPECT_TRUE(contains(rsp.unenforced, TAG_ORIGIN, KM_ORIGIN_SOFTWARE));
229 EXPECT_TRUE(contains(rsp.unenforced, KM_TAG_CREATION_DATETIME));
Shawn Willden128ffe02014-08-06 12:31:33 -0600230}
231
Shawn Willden76364712014-08-11 17:48:04 -0600232typedef KeymasterTest GetKeyCharacteristics;
233TEST_F(GetKeyCharacteristics, SimpleRsa) {
234 keymaster_key_param_t params[] = {
235 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
236 Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
237 Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
238 Authorization(TAG_KEY_SIZE, 256),
239 Authorization(TAG_USER_ID, 7),
240 Authorization(TAG_USER_AUTH_ID, 8),
Shawn Willden1615f2e2014-08-13 10:37:40 -0600241 Authorization(TAG_APPLICATION_ID, "app_id", 6),
Shawn Willden76364712014-08-11 17:48:04 -0600242 Authorization(TAG_AUTH_TIMEOUT, 300),
243 };
244
245 GenerateKeyRequest gen_req;
246 gen_req.key_description.Reinitialize(params, array_length(params));
247 GenerateKeyResponse gen_rsp;
248
249 device.GenerateKey(gen_req, &gen_rsp);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600250 ASSERT_EQ(KM_ERROR_OK, gen_rsp.error);
Shawn Willden76364712014-08-11 17:48:04 -0600251
252 GetKeyCharacteristicsRequest req;
253 req.key_blob = gen_rsp.key_blob;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600254 req.additional_params.push_back(TAG_APPLICATION_ID, "app_id", 6);
Shawn Willden76364712014-08-11 17:48:04 -0600255
256 GetKeyCharacteristicsResponse rsp;
257 device.GetKeyCharacteristics(req, &rsp);
258 ASSERT_EQ(KM_ERROR_OK, rsp.error);
259
260 EXPECT_EQ(gen_rsp.enforced, rsp.enforced);
261 EXPECT_EQ(gen_rsp.unenforced, rsp.unenforced);
262}
263
Shawn Willden1615f2e2014-08-13 10:37:40 -0600264class SigningOperationsTest : public KeymasterTest {
265 protected:
266 keymaster_key_blob_t* GenerateKey(keymaster_digest_t digest, keymaster_padding_t padding,
267 uint32_t key_size) {
268 keymaster_key_param_t params[] = {
269 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
270 Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
271 Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
272 Authorization(TAG_KEY_SIZE, key_size),
273 Authorization(TAG_USER_ID, 7),
274 Authorization(TAG_USER_AUTH_ID, 8),
275 Authorization(TAG_APPLICATION_ID, "app_id", 6),
276 Authorization(TAG_AUTH_TIMEOUT, 300),
277 };
278 GenerateKeyRequest generate_request;
279 generate_request.key_description.Reinitialize(params, array_length(params));
280 if (digest != -1)
281 generate_request.key_description.push_back(TAG_DIGEST, digest);
282 if (padding != -1)
283 generate_request.key_description.push_back(TAG_PADDING, padding);
284 device.GenerateKey(generate_request, &generate_response_);
285 EXPECT_EQ(KM_ERROR_OK, generate_response_.error);
286
287 // This is safe because generate_response_ lives as long as the test and will keep the key
288 // blob around.
289 return &generate_response_.key_blob;
290 }
291
292 private:
293 GenerateKeyResponse generate_response_;
294};
295
296TEST_F(SigningOperationsTest, RsaSuccess) {
297 keymaster_key_blob_t* key = GenerateKey(KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
298 ASSERT_TRUE(key != NULL);
299
300 BeginOperationRequest begin_request;
301 BeginOperationResponse begin_response;
302 begin_request.key_blob = *key;
303 begin_request.purpose = KM_PURPOSE_SIGN;
304 begin_request.additional_params.push_back(TAG_APPLICATION_ID, "app_id", 6);
305
306 device.BeginOperation(begin_request, &begin_response);
307 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
308
309 UpdateOperationRequest update_request;
310 UpdateOperationResponse update_response;
311 update_request.op_handle = begin_response.op_handle;
312 update_request.input.Reinitialize("012345678901234567890123456789012", 32);
313 EXPECT_EQ(32U, update_request.input.available_read());
314
315 device.UpdateOperation(update_request, &update_response);
316 ASSERT_EQ(KM_ERROR_OK, update_response.error);
317 EXPECT_EQ(0U, update_response.output.available_read());
318
319 FinishOperationResponse finish_response;
320 device.FinishOperation(begin_response.op_handle, &finish_response);
321 ASSERT_EQ(KM_ERROR_OK, finish_response.error);
322 EXPECT_GT(finish_response.signature.available_read(), 0U);
323 EXPECT_EQ(0U, finish_response.output.available_read());
324
325 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
326}
327
328TEST_F(SigningOperationsTest, RsaAbort) {
329 keymaster_key_blob_t* key = GenerateKey(KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
330 ASSERT_TRUE(key != NULL);
331
332 BeginOperationRequest begin_request;
333 BeginOperationResponse begin_response;
334 begin_request.key_blob = *key;
335 begin_request.purpose = KM_PURPOSE_SIGN;
336 begin_request.additional_params.push_back(TAG_APPLICATION_ID, "app_id", 6);
337
338 device.BeginOperation(begin_request, &begin_response);
339 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
340
341 EXPECT_EQ(KM_ERROR_OK, device.AbortOperation(begin_response.op_handle));
342
343 // Another abort should fail
344 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
345}
346
347TEST_F(SigningOperationsTest, RsaUnsupportedDigest) {
348 keymaster_key_blob_t* key = GenerateKey(KM_DIGEST_SHA_2_256, KM_PAD_NONE, 256 /* key size */);
349 ASSERT_TRUE(key != NULL);
350
351 BeginOperationRequest begin_request;
352 BeginOperationResponse begin_response;
353 begin_request.purpose = KM_PURPOSE_SIGN;
354 begin_request.key_blob = *key;
355 begin_request.additional_params.push_back(TAG_APPLICATION_ID, "app_id", 6);
356
357 device.BeginOperation(begin_request, &begin_response);
358 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, begin_response.error);
359
360 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
361}
362
363TEST_F(SigningOperationsTest, RsaUnsupportedPadding) {
364 keymaster_key_blob_t* key = GenerateKey(KM_DIGEST_NONE, KM_PAD_RSA_OAEP, 256 /* key size */);
365 ASSERT_TRUE(key != NULL);
366
367 BeginOperationRequest begin_request;
368 BeginOperationResponse begin_response;
369 begin_request.purpose = KM_PURPOSE_SIGN;
370 begin_request.key_blob = *key;
371 begin_request.additional_params.push_back(TAG_APPLICATION_ID, "app_id", 6);
372
373 device.BeginOperation(begin_request, &begin_response);
374 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, begin_response.error);
375
376 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
377}
378
379TEST_F(SigningOperationsTest, RsaNoDigest) {
380 keymaster_key_blob_t* key =
381 GenerateKey(static_cast<keymaster_digest_t>(-1), KM_PAD_NONE, 256 /* key size */);
382 ASSERT_TRUE(key != NULL);
383
384 BeginOperationRequest begin_request;
385 BeginOperationResponse begin_response;
386 begin_request.purpose = KM_PURPOSE_SIGN;
387 begin_request.key_blob = *key;
388 begin_request.additional_params.push_back(TAG_APPLICATION_ID, "app_id", 6);
389
390 device.BeginOperation(begin_request, &begin_response);
391 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, begin_response.error);
392
393 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
394}
395
396TEST_F(SigningOperationsTest, RsaNoPadding) {
397 keymaster_key_blob_t* key =
398 GenerateKey(KM_DIGEST_NONE, static_cast<keymaster_padding_t>(-1), 256 /* key size */);
399 ASSERT_TRUE(key != NULL);
400
401 BeginOperationRequest begin_request;
402 BeginOperationResponse begin_response;
403 begin_request.purpose = KM_PURPOSE_SIGN;
404 begin_request.key_blob = *key;
405 begin_request.additional_params.push_back(TAG_APPLICATION_ID, "app_id", 6);
406
407 device.BeginOperation(begin_request, &begin_response);
408 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, begin_response.error);
409
410 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
411}
412
413TEST_F(SigningOperationsTest, RsaTooShortMessage) {
414 keymaster_key_blob_t* key = GenerateKey(KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
415 ASSERT_TRUE(key != NULL);
416
417 BeginOperationRequest begin_request;
418 BeginOperationResponse begin_response;
419 begin_request.key_blob = *key;
420 begin_request.purpose = KM_PURPOSE_SIGN;
421 begin_request.additional_params.push_back(TAG_APPLICATION_ID, "app_id", 6);
422
423 device.BeginOperation(begin_request, &begin_response);
424 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
425
426 UpdateOperationRequest update_request;
427 UpdateOperationResponse update_response;
428 update_request.op_handle = begin_response.op_handle;
429 update_request.input.Reinitialize("01234567890123456789012345678901", 31);
430 EXPECT_EQ(31U, update_request.input.available_read());
431
432 device.UpdateOperation(update_request, &update_response);
433 ASSERT_EQ(KM_ERROR_OK, update_response.error);
434 EXPECT_EQ(0U, update_response.output.available_read());
435
436 FinishOperationResponse finish_response;
437 device.FinishOperation(begin_response.op_handle, &finish_response);
438 ASSERT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, finish_response.error);
439 EXPECT_EQ(0U, finish_response.signature.available_read());
440 EXPECT_EQ(0U, finish_response.output.available_read());
441
442 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
443}
444
Shawn Willden128ffe02014-08-06 12:31:33 -0600445} // namespace test
446} // namespace keymaster