blob: fc1f8256d191a84de0432cbb5bb6ed0305e8398f [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 Willdenda8485e2014-08-17 08:00:01 -060040 KeymasterTest() : device(5) { RAND_seed("foobar", 6); }
41 ~KeymasterTest() {}
Shawn Willden128ffe02014-08-06 12:31:33 -060042
43 GoogleSoftKeymaster device;
44};
45
46template <keymaster_tag_t Tag, typename KeymasterEnum>
47bool contains(const AuthorizationSet& set, TypedEnumTag<KM_ENUM, Tag, KeymasterEnum> tag,
48 KeymasterEnum val) {
49 int pos = set.find(tag);
50 return pos != -1 && set[pos].enumerated == val;
51}
52
53template <keymaster_tag_t Tag, typename KeymasterEnum>
54bool contains(const AuthorizationSet& set, TypedEnumTag<KM_ENUM_REP, Tag, KeymasterEnum> tag,
55 KeymasterEnum val) {
56 int pos = -1;
57 while ((pos = set.find(tag, pos)) != -1)
58 if (set[pos].enumerated == val)
59 return true;
60 return false;
61}
62
63template <keymaster_tag_t Tag>
64bool contains(const AuthorizationSet& set, TypedTag<KM_INT, Tag> tag, uint32_t val) {
65 int pos = set.find(tag);
66 return pos != -1 && set[pos].integer == val;
67}
68
69template <keymaster_tag_t Tag>
70bool contains(const AuthorizationSet& set, TypedTag<KM_INT_REP, Tag> tag, uint32_t val) {
71 int pos = -1;
72 while ((pos = set.find(tag, pos)) != -1)
73 if (set[pos].integer == val)
74 return true;
75 return false;
76}
77
78template <keymaster_tag_t Tag>
79bool contains(const AuthorizationSet& set, TypedTag<KM_LONG, Tag> tag, uint64_t val) {
80 int pos = set.find(tag);
81 return pos != -1 && set[pos].long_integer == val;
82}
83
84template <keymaster_tag_t Tag>
85bool contains(const AuthorizationSet& set, TypedTag<KM_BYTES, Tag> tag, const std::string& val) {
86 int pos = set.find(tag);
87 return pos != -1 &&
88 std::string(reinterpret_cast<const char*>(set[pos].blob.data),
89 set[pos].blob.data_length) == val;
90}
91
92inline bool contains(const AuthorizationSet& set, keymaster_tag_t tag) {
93 return set.find(tag) != -1;
94}
95
96typedef KeymasterTest CheckSupported;
97TEST_F(CheckSupported, SupportedAlgorithms) {
98 // Shouldn't blow up on NULL.
99 device.SupportedAlgorithms(NULL);
100
101 SupportedResponse<keymaster_algorithm_t> response;
102 device.SupportedAlgorithms(&response);
103 EXPECT_EQ(KM_ERROR_OK, response.error);
104 EXPECT_EQ(1U, response.results_length);
105 EXPECT_EQ(KM_ALGORITHM_RSA, response.results[0]);
106}
107
108TEST_F(CheckSupported, SupportedBlockModes) {
109 // Shouldn't blow up on NULL.
110 device.SupportedBlockModes(KM_ALGORITHM_RSA, NULL);
111
112 SupportedResponse<keymaster_block_mode_t> response;
113 device.SupportedBlockModes(KM_ALGORITHM_RSA, &response);
114 EXPECT_EQ(KM_ERROR_OK, response.error);
115 EXPECT_EQ(0U, response.results_length);
116
117 device.SupportedBlockModes(KM_ALGORITHM_DSA, &response);
118 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM, response.error);
119}
120
121TEST_F(CheckSupported, SupportedPaddingModes) {
122 // Shouldn't blow up on NULL.
123 device.SupportedPaddingModes(KM_ALGORITHM_RSA, NULL);
124
125 SupportedResponse<keymaster_padding_t> response;
126 device.SupportedPaddingModes(KM_ALGORITHM_RSA, &response);
127 EXPECT_EQ(KM_ERROR_OK, response.error);
128 EXPECT_EQ(1U, response.results_length);
129 EXPECT_EQ(KM_PAD_NONE, response.results[0]);
130
131 device.SupportedPaddingModes(KM_ALGORITHM_DSA, &response);
132 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM, response.error);
133}
134
135TEST_F(CheckSupported, SupportedDigests) {
136 // Shouldn't blow up on NULL.
137 device.SupportedDigests(KM_ALGORITHM_RSA, NULL);
138
139 SupportedResponse<keymaster_digest_t> response;
140 device.SupportedDigests(KM_ALGORITHM_RSA, &response);
141 EXPECT_EQ(KM_ERROR_OK, response.error);
142 EXPECT_EQ(1U, response.results_length);
143 EXPECT_EQ(KM_DIGEST_NONE, response.results[0]);
144
145 device.SupportedDigests(KM_ALGORITHM_DSA, &response);
146 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM, response.error);
147}
148
149TEST_F(CheckSupported, SupportedImportFormats) {
150 // Shouldn't blow up on NULL.
151 device.SupportedImportFormats(KM_ALGORITHM_RSA, NULL);
152
153 SupportedResponse<keymaster_key_format_t> response;
154 device.SupportedImportFormats(KM_ALGORITHM_RSA, &response);
155 EXPECT_EQ(KM_ERROR_OK, response.error);
156 EXPECT_EQ(1U, response.results_length);
157 EXPECT_EQ(KM_KEY_FORMAT_PKCS8, response.results[0]);
158
159 device.SupportedImportFormats(KM_ALGORITHM_DSA, &response);
160 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM, response.error);
161}
162
163TEST_F(CheckSupported, SupportedExportFormats) {
164 // Shouldn't blow up on NULL.
165 device.SupportedExportFormats(KM_ALGORITHM_RSA, NULL);
166
167 SupportedResponse<keymaster_key_format_t> response;
168 device.SupportedExportFormats(KM_ALGORITHM_RSA, &response);
169 EXPECT_EQ(KM_ERROR_OK, response.error);
170 EXPECT_EQ(1U, response.results_length);
171 EXPECT_EQ(KM_KEY_FORMAT_X509, response.results[0]);
172
173 device.SupportedExportFormats(KM_ALGORITHM_DSA, &response);
174 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM, response.error);
175}
176
177typedef KeymasterTest NewKeyGeneration;
178TEST_F(NewKeyGeneration, Rsa) {
179 keymaster_key_param_t params[] = {
180 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
181 Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
182 Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
Shawn Willden76364712014-08-11 17:48:04 -0600183 Authorization(TAG_KEY_SIZE, 256),
Shawn Willden128ffe02014-08-06 12:31:33 -0600184 Authorization(TAG_USER_ID, 7),
185 Authorization(TAG_USER_AUTH_ID, 8),
Shawn Willden76364712014-08-11 17:48:04 -0600186 Authorization(TAG_APPLICATION_ID, "app_id", 6),
187 Authorization(TAG_APPLICATION_DATA, "app_data", 8),
Shawn Willden128ffe02014-08-06 12:31:33 -0600188 Authorization(TAG_AUTH_TIMEOUT, 300),
189 };
190 GenerateKeyRequest req;
191 req.key_description.Reinitialize(params, array_length(params));
192 GenerateKeyResponse rsp;
193
194 device.GenerateKey(req, &rsp);
195
196 ASSERT_EQ(KM_ERROR_OK, rsp.error);
197 EXPECT_EQ(0U, rsp.enforced.size());
Shawn Willden8d336ae2014-08-09 15:47:05 -0600198 EXPECT_EQ(12U, rsp.enforced.SerializedSize());
199 EXPECT_GT(rsp.unenforced.SerializedSize(), 12U);
Shawn Willden128ffe02014-08-06 12:31:33 -0600200
201 // Check specified tags are all present in unenforced characteristics
202 EXPECT_TRUE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_SIGN));
203 EXPECT_TRUE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_VERIFY));
204
205 EXPECT_TRUE(contains(rsp.unenforced, TAG_ALGORITHM, KM_ALGORITHM_RSA));
206
207 EXPECT_TRUE(contains(rsp.unenforced, TAG_USER_ID, 7));
208 EXPECT_TRUE(contains(rsp.unenforced, TAG_USER_AUTH_ID, 8));
Shawn Willden76364712014-08-11 17:48:04 -0600209 EXPECT_TRUE(contains(rsp.unenforced, TAG_KEY_SIZE, 256));
Shawn Willden128ffe02014-08-06 12:31:33 -0600210 EXPECT_TRUE(contains(rsp.unenforced, TAG_AUTH_TIMEOUT, 300));
211
Shawn Willden39b970b2014-08-11 09:11:21 -0600212 // Verify that App ID, App data and ROT are NOT included.
213 EXPECT_FALSE(contains(rsp.unenforced, TAG_ROOT_OF_TRUST));
214 EXPECT_FALSE(contains(rsp.unenforced, TAG_APPLICATION_ID));
215 EXPECT_FALSE(contains(rsp.unenforced, TAG_APPLICATION_DATA));
216
Shawn Willden128ffe02014-08-06 12:31:33 -0600217 // Just for giggles, check that some unexpected tags/values are NOT present.
218 EXPECT_FALSE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
219 EXPECT_FALSE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_DECRYPT));
220 EXPECT_FALSE(contains(rsp.unenforced, TAG_AUTH_TIMEOUT, 301));
221 EXPECT_FALSE(contains(rsp.unenforced, TAG_RESCOPE_AUTH_TIMEOUT));
222
223 // Now check that unspecified, defaulted tags are correct.
224 EXPECT_TRUE(contains(rsp.unenforced, TAG_RSA_PUBLIC_EXPONENT, 65537));
225 EXPECT_TRUE(contains(rsp.unenforced, TAG_ORIGIN, KM_ORIGIN_SOFTWARE));
226 EXPECT_TRUE(contains(rsp.unenforced, KM_TAG_CREATION_DATETIME));
Shawn Willden128ffe02014-08-06 12:31:33 -0600227}
228
Shawn Willden76364712014-08-11 17:48:04 -0600229typedef KeymasterTest GetKeyCharacteristics;
230TEST_F(GetKeyCharacteristics, SimpleRsa) {
231 keymaster_key_param_t params[] = {
232 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
233 Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
234 Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
235 Authorization(TAG_KEY_SIZE, 256),
236 Authorization(TAG_USER_ID, 7),
237 Authorization(TAG_USER_AUTH_ID, 8),
Shawn Willden1615f2e2014-08-13 10:37:40 -0600238 Authorization(TAG_APPLICATION_ID, "app_id", 6),
Shawn Willden76364712014-08-11 17:48:04 -0600239 Authorization(TAG_AUTH_TIMEOUT, 300),
240 };
241
242 GenerateKeyRequest gen_req;
243 gen_req.key_description.Reinitialize(params, array_length(params));
244 GenerateKeyResponse gen_rsp;
245
246 device.GenerateKey(gen_req, &gen_rsp);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600247 ASSERT_EQ(KM_ERROR_OK, gen_rsp.error);
Shawn Willden76364712014-08-11 17:48:04 -0600248
249 GetKeyCharacteristicsRequest req;
Shawn Willdenda8485e2014-08-17 08:00:01 -0600250 req.SetKeyMaterial(gen_rsp.key_blob);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600251 req.additional_params.push_back(TAG_APPLICATION_ID, "app_id", 6);
Shawn Willden76364712014-08-11 17:48:04 -0600252
253 GetKeyCharacteristicsResponse rsp;
254 device.GetKeyCharacteristics(req, &rsp);
255 ASSERT_EQ(KM_ERROR_OK, rsp.error);
256
257 EXPECT_EQ(gen_rsp.enforced, rsp.enforced);
258 EXPECT_EQ(gen_rsp.unenforced, rsp.unenforced);
259}
260
Shawn Willden1615f2e2014-08-13 10:37:40 -0600261class SigningOperationsTest : public KeymasterTest {
262 protected:
263 keymaster_key_blob_t* GenerateKey(keymaster_digest_t digest, keymaster_padding_t padding,
264 uint32_t key_size) {
265 keymaster_key_param_t params[] = {
266 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
267 Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
268 Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
269 Authorization(TAG_KEY_SIZE, key_size),
270 Authorization(TAG_USER_ID, 7),
271 Authorization(TAG_USER_AUTH_ID, 8),
272 Authorization(TAG_APPLICATION_ID, "app_id", 6),
273 Authorization(TAG_AUTH_TIMEOUT, 300),
274 };
275 GenerateKeyRequest generate_request;
276 generate_request.key_description.Reinitialize(params, array_length(params));
Shawn Willden43e999e2014-08-13 13:29:50 -0600277 if (static_cast<int>(digest) != -1)
Shawn Willden1615f2e2014-08-13 10:37:40 -0600278 generate_request.key_description.push_back(TAG_DIGEST, digest);
Shawn Willden43e999e2014-08-13 13:29:50 -0600279 if (static_cast<int>(padding) != -1)
Shawn Willden1615f2e2014-08-13 10:37:40 -0600280 generate_request.key_description.push_back(TAG_PADDING, padding);
281 device.GenerateKey(generate_request, &generate_response_);
282 EXPECT_EQ(KM_ERROR_OK, generate_response_.error);
283
284 // This is safe because generate_response_ lives as long as the test and will keep the key
285 // blob around.
286 return &generate_response_.key_blob;
287 }
288
289 private:
290 GenerateKeyResponse generate_response_;
291};
292
293TEST_F(SigningOperationsTest, RsaSuccess) {
294 keymaster_key_blob_t* key = GenerateKey(KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
295 ASSERT_TRUE(key != NULL);
296
297 BeginOperationRequest begin_request;
298 BeginOperationResponse begin_response;
Shawn Willdenda8485e2014-08-17 08:00:01 -0600299 begin_request.SetKeyMaterial(*key);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600300 begin_request.purpose = KM_PURPOSE_SIGN;
301 begin_request.additional_params.push_back(TAG_APPLICATION_ID, "app_id", 6);
302
303 device.BeginOperation(begin_request, &begin_response);
304 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
305
306 UpdateOperationRequest update_request;
307 UpdateOperationResponse update_response;
308 update_request.op_handle = begin_response.op_handle;
309 update_request.input.Reinitialize("012345678901234567890123456789012", 32);
310 EXPECT_EQ(32U, update_request.input.available_read());
311
312 device.UpdateOperation(update_request, &update_response);
313 ASSERT_EQ(KM_ERROR_OK, update_response.error);
314 EXPECT_EQ(0U, update_response.output.available_read());
315
Shawn Willden43e999e2014-08-13 13:29:50 -0600316 FinishOperationRequest finish_request;
317 finish_request.op_handle = begin_response.op_handle;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600318 FinishOperationResponse finish_response;
Shawn Willden43e999e2014-08-13 13:29:50 -0600319 device.FinishOperation(finish_request, &finish_response);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600320 ASSERT_EQ(KM_ERROR_OK, finish_response.error);
Shawn Willden43e999e2014-08-13 13:29:50 -0600321 EXPECT_GT(finish_response.output.available_read(), 0U);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600322
323 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
324}
325
326TEST_F(SigningOperationsTest, RsaAbort) {
327 keymaster_key_blob_t* key = GenerateKey(KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
328 ASSERT_TRUE(key != NULL);
329
330 BeginOperationRequest begin_request;
331 BeginOperationResponse begin_response;
Shawn Willdenda8485e2014-08-17 08:00:01 -0600332 begin_request.SetKeyMaterial(*key);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600333 begin_request.purpose = KM_PURPOSE_SIGN;
334 begin_request.additional_params.push_back(TAG_APPLICATION_ID, "app_id", 6);
335
336 device.BeginOperation(begin_request, &begin_response);
337 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
338
339 EXPECT_EQ(KM_ERROR_OK, device.AbortOperation(begin_response.op_handle));
340
341 // Another abort should fail
342 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
343}
344
345TEST_F(SigningOperationsTest, RsaUnsupportedDigest) {
346 keymaster_key_blob_t* key = GenerateKey(KM_DIGEST_SHA_2_256, KM_PAD_NONE, 256 /* key size */);
347 ASSERT_TRUE(key != NULL);
348
349 BeginOperationRequest begin_request;
350 BeginOperationResponse begin_response;
351 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willdenda8485e2014-08-17 08:00:01 -0600352 begin_request.SetKeyMaterial(*key);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600353 begin_request.additional_params.push_back(TAG_APPLICATION_ID, "app_id", 6);
354
355 device.BeginOperation(begin_request, &begin_response);
356 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, begin_response.error);
357
358 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
359}
360
361TEST_F(SigningOperationsTest, RsaUnsupportedPadding) {
362 keymaster_key_blob_t* key = GenerateKey(KM_DIGEST_NONE, KM_PAD_RSA_OAEP, 256 /* key size */);
363 ASSERT_TRUE(key != NULL);
364
365 BeginOperationRequest begin_request;
366 BeginOperationResponse begin_response;
367 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willdenda8485e2014-08-17 08:00:01 -0600368 begin_request.SetKeyMaterial(*key);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600369 begin_request.additional_params.push_back(TAG_APPLICATION_ID, "app_id", 6);
370
371 device.BeginOperation(begin_request, &begin_response);
372 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, begin_response.error);
373
374 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
375}
376
377TEST_F(SigningOperationsTest, RsaNoDigest) {
378 keymaster_key_blob_t* key =
379 GenerateKey(static_cast<keymaster_digest_t>(-1), KM_PAD_NONE, 256 /* key size */);
380 ASSERT_TRUE(key != NULL);
381
382 BeginOperationRequest begin_request;
383 BeginOperationResponse begin_response;
384 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willdenda8485e2014-08-17 08:00:01 -0600385 begin_request.SetKeyMaterial(*key);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600386 begin_request.additional_params.push_back(TAG_APPLICATION_ID, "app_id", 6);
387
388 device.BeginOperation(begin_request, &begin_response);
389 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, begin_response.error);
390
391 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
392}
393
394TEST_F(SigningOperationsTest, RsaNoPadding) {
395 keymaster_key_blob_t* key =
396 GenerateKey(KM_DIGEST_NONE, static_cast<keymaster_padding_t>(-1), 256 /* key size */);
397 ASSERT_TRUE(key != NULL);
398
399 BeginOperationRequest begin_request;
400 BeginOperationResponse begin_response;
401 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willdenda8485e2014-08-17 08:00:01 -0600402 begin_request.SetKeyMaterial(*key);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600403 begin_request.additional_params.push_back(TAG_APPLICATION_ID, "app_id", 6);
404
405 device.BeginOperation(begin_request, &begin_response);
406 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, begin_response.error);
407
408 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
409}
410
411TEST_F(SigningOperationsTest, RsaTooShortMessage) {
412 keymaster_key_blob_t* key = GenerateKey(KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
413 ASSERT_TRUE(key != NULL);
414
415 BeginOperationRequest begin_request;
416 BeginOperationResponse begin_response;
Shawn Willdenda8485e2014-08-17 08:00:01 -0600417 begin_request.SetKeyMaterial(*key);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600418 begin_request.purpose = KM_PURPOSE_SIGN;
419 begin_request.additional_params.push_back(TAG_APPLICATION_ID, "app_id", 6);
420
421 device.BeginOperation(begin_request, &begin_response);
422 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
423
424 UpdateOperationRequest update_request;
425 UpdateOperationResponse update_response;
426 update_request.op_handle = begin_response.op_handle;
427 update_request.input.Reinitialize("01234567890123456789012345678901", 31);
428 EXPECT_EQ(31U, update_request.input.available_read());
429
430 device.UpdateOperation(update_request, &update_response);
431 ASSERT_EQ(KM_ERROR_OK, update_response.error);
432 EXPECT_EQ(0U, update_response.output.available_read());
433
Shawn Willden43e999e2014-08-13 13:29:50 -0600434 FinishOperationRequest finish_request;
435 finish_request.op_handle = begin_response.op_handle;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600436 FinishOperationResponse finish_response;
Shawn Willden43e999e2014-08-13 13:29:50 -0600437 device.FinishOperation(finish_request, &finish_response);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600438 ASSERT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, finish_response.error);
Shawn Willden43e999e2014-08-13 13:29:50 -0600439 EXPECT_EQ(0U, finish_response.output.available_read());
440
441 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
442}
443
444class VerificationOperationsTest : public KeymasterTest {
445 protected:
446 VerificationOperationsTest() {
447 generate_response_.error = KM_ERROR_UNKNOWN_ERROR;
448 finish_response_.error = KM_ERROR_UNKNOWN_ERROR;
449 }
450
Shawn Willdenda8485e2014-08-17 08:00:01 -0600451 void GenerateKey(keymaster_digest_t digest, keymaster_padding_t padding, uint32_t key_size) {
Shawn Willden43e999e2014-08-13 13:29:50 -0600452 keymaster_key_param_t params[] = {
453 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
454 Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
455 Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA),
456 Authorization(TAG_KEY_SIZE, key_size),
457 Authorization(TAG_USER_ID, 7),
458 Authorization(TAG_USER_AUTH_ID, 8),
459 Authorization(TAG_APPLICATION_ID, "app_id", 6),
460 Authorization(TAG_AUTH_TIMEOUT, 300),
461 };
462 GenerateKeyRequest generate_request;
463 generate_request.key_description.Reinitialize(params, array_length(params));
464 if (static_cast<int>(digest) != -1)
465 generate_request.key_description.push_back(TAG_DIGEST, digest);
466 if (static_cast<int>(padding) != -1)
467 generate_request.key_description.push_back(TAG_PADDING, padding);
468 device.GenerateKey(generate_request, &generate_response_);
469 EXPECT_EQ(KM_ERROR_OK, generate_response_.error);
470
471 BeginOperationRequest begin_request;
472 BeginOperationResponse begin_response;
Shawn Willdenda8485e2014-08-17 08:00:01 -0600473 begin_request.SetKeyMaterial(generate_response_.key_blob);
Shawn Willden43e999e2014-08-13 13:29:50 -0600474 begin_request.purpose = KM_PURPOSE_SIGN;
475 begin_request.additional_params.push_back(TAG_APPLICATION_ID, "app_id", 6);
476
477 device.BeginOperation(begin_request, &begin_response);
478 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
479
480 UpdateOperationRequest update_request;
481 UpdateOperationResponse update_response;
482 update_request.op_handle = begin_response.op_handle;
483 update_request.input.Reinitialize("012345678901234567890123456789012", 32);
484 EXPECT_EQ(32U, update_request.input.available_read());
485
486 device.UpdateOperation(update_request, &update_response);
487 ASSERT_EQ(KM_ERROR_OK, update_response.error);
488 EXPECT_EQ(0U, update_response.output.available_read());
489
490 FinishOperationRequest finish_request;
491 finish_request.op_handle = begin_response.op_handle;
492 device.FinishOperation(finish_request, &finish_response_);
493 ASSERT_EQ(KM_ERROR_OK, finish_response_.error);
494 EXPECT_GT(finish_response_.output.available_read(), 0U);
495 }
496
497 keymaster_key_blob_t* key_blob() {
498 if (generate_response_.error == KM_ERROR_OK)
499 return &generate_response_.key_blob;
500 return NULL;
501 }
502
503 Buffer* signature() {
504 if (finish_response_.error == KM_ERROR_OK)
505 return &finish_response_.output;
506 return NULL;
507 }
508
509 private:
510 GenerateKeyResponse generate_response_;
511 FinishOperationResponse finish_response_;
512};
513
514TEST_F(VerificationOperationsTest, RsaSuccess) {
515 GenerateKey(KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
516 ASSERT_TRUE(key_blob() != NULL);
517 ASSERT_TRUE(signature() != NULL);
518
519 BeginOperationRequest begin_request;
520 BeginOperationResponse begin_response;
Shawn Willdenda8485e2014-08-17 08:00:01 -0600521 begin_request.SetKeyMaterial(*key_blob());
Shawn Willden43e999e2014-08-13 13:29:50 -0600522 begin_request.purpose = KM_PURPOSE_VERIFY;
523 begin_request.additional_params.push_back(TAG_APPLICATION_ID, "app_id", 6);
524
525 device.BeginOperation(begin_request, &begin_response);
526 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
527
528 UpdateOperationRequest update_request;
529 UpdateOperationResponse update_response;
530 update_request.op_handle = begin_response.op_handle;
531 update_request.input.Reinitialize("012345678901234567890123456789012", 32);
532 EXPECT_EQ(32U, update_request.input.available_read());
533
534 device.UpdateOperation(update_request, &update_response);
535 ASSERT_EQ(KM_ERROR_OK, update_response.error);
536 EXPECT_EQ(0U, update_response.output.available_read());
537
538 FinishOperationRequest finish_request;
539 finish_request.op_handle = begin_response.op_handle;
540 finish_request.signature.Reinitialize(*signature());
541 FinishOperationResponse finish_response;
542 device.FinishOperation(finish_request, &finish_response);
543 ASSERT_EQ(KM_ERROR_OK, finish_response.error);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600544 EXPECT_EQ(0U, finish_response.output.available_read());
545
546 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
547}
548
Shawn Willden128ffe02014-08-06 12:31:33 -0600549} // namespace test
550} // namespace keymaster