blob: 1cc61d77ff835bb54db2de9eada798b5e954973c [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
Shawn Willden437fbd12014-08-20 11:59:49 -060017#include <string>
18#include <fstream>
19
Shawn Willden128ffe02014-08-06 12:31:33 -060020#include <gtest/gtest.h>
Shawn Willden76364712014-08-11 17:48:04 -060021
Shawn Willden128ffe02014-08-06 12:31:33 -060022#include <openssl/engine.h>
23
Shawn Willden98d9b922014-08-26 08:14:10 -060024#include <keymaster/google_keymaster_utils.h>
25#include <keymaster/keymaster_tags.h>
26
Shawn Willden76364712014-08-11 17:48:04 -060027#include "google_keymaster_test_utils.h"
Shawn Willden128ffe02014-08-06 12:31:33 -060028#include "google_softkeymaster.h"
29
Shawn Willden437fbd12014-08-20 11:59:49 -060030using std::string;
31using std::ifstream;
32using std::istreambuf_iterator;
33
Shawn Willden128ffe02014-08-06 12:31:33 -060034int main(int argc, char** argv) {
35 ::testing::InitGoogleTest(&argc, argv);
36 int result = RUN_ALL_TESTS();
37 // Clean up stuff OpenSSL leaves around, so Valgrind doesn't complain.
38 CRYPTO_cleanup_all_ex_data();
Shawn Willden7c0a82b2014-09-17 12:57:32 -060039 ERR_remove_thread_state(NULL);
Shawn Willden128ffe02014-08-06 12:31:33 -060040 ERR_free_strings();
41 return result;
42}
43
44namespace keymaster {
45namespace test {
46
Shawn Willden6bbe6782014-09-18 11:26:15 -060047// Note that these DSA generator, p and q values must match the values from dsa_privkey_pk8.der.
48const uint8_t dsa_g[] = {
49 0x19, 0x1C, 0x71, 0xFD, 0xE0, 0x03, 0x0C, 0x43, 0xD9, 0x0B, 0xF6, 0xCD, 0xD6, 0xA9, 0x70, 0xE7,
50 0x37, 0x86, 0x3A, 0x78, 0xE9, 0xA7, 0x47, 0xA7, 0x47, 0x06, 0x88, 0xB1, 0xAF, 0xD7, 0xF3, 0xF1,
51 0xA1, 0xD7, 0x00, 0x61, 0x28, 0x88, 0x31, 0x48, 0x60, 0xD8, 0x11, 0xEF, 0xA5, 0x24, 0x1A, 0x81,
52 0xC4, 0x2A, 0xE2, 0xEA, 0x0E, 0x36, 0xD2, 0xD2, 0x05, 0x84, 0x37, 0xCF, 0x32, 0x7D, 0x09, 0xE6,
53 0x0F, 0x8B, 0x0C, 0xC8, 0xC2, 0xA4, 0xB1, 0xDC, 0x80, 0xCA, 0x68, 0xDF, 0xAF, 0xD2, 0x90, 0xC0,
54 0x37, 0x58, 0x54, 0x36, 0x8F, 0x49, 0xB8, 0x62, 0x75, 0x8B, 0x48, 0x47, 0xC0, 0xBE, 0xF7, 0x9A,
55 0x92, 0xA6, 0x68, 0x05, 0xDA, 0x9D, 0xAF, 0x72, 0x9A, 0x67, 0xB3, 0xB4, 0x14, 0x03, 0xAE, 0x4F,
56 0x4C, 0x76, 0xB9, 0xD8, 0x64, 0x0A, 0xBA, 0x3B, 0xA8, 0x00, 0x60, 0x4D, 0xAE, 0x81, 0xC3, 0xC5,
57};
58const uint8_t dsa_p[] = {
59 0xA3, 0xF3, 0xE9, 0xB6, 0x7E, 0x7D, 0x88, 0xF6, 0xB7, 0xE5, 0xF5, 0x1F, 0x3B, 0xEE, 0xAC, 0xD7,
60 0xAD, 0xBC, 0xC9, 0xD1, 0x5A, 0xF8, 0x88, 0xC4, 0xEF, 0x6E, 0x3D, 0x74, 0x19, 0x74, 0xE7, 0xD8,
61 0xE0, 0x26, 0x44, 0x19, 0x86, 0xAF, 0x19, 0xDB, 0x05, 0xE9, 0x3B, 0x8B, 0x58, 0x58, 0xDE, 0xE5,
62 0x4F, 0x48, 0x15, 0x01, 0xEA, 0xE6, 0x83, 0x52, 0xD7, 0xC1, 0x21, 0xDF, 0xB9, 0xB8, 0x07, 0x66,
63 0x50, 0xFB, 0x3A, 0x0C, 0xB3, 0x85, 0xEE, 0xBB, 0x04, 0x5F, 0xC2, 0x6D, 0x6D, 0x95, 0xFA, 0x11,
64 0x93, 0x1E, 0x59, 0x5B, 0xB1, 0x45, 0x8D, 0xE0, 0x3D, 0x73, 0xAA, 0xF2, 0x41, 0x14, 0x51, 0x07,
65 0x72, 0x3D, 0xA2, 0xF7, 0x58, 0xCD, 0x11, 0xA1, 0x32, 0xCF, 0xDA, 0x42, 0xB7, 0xCC, 0x32, 0x80,
66 0xDB, 0x87, 0x82, 0xEC, 0x42, 0xDB, 0x5A, 0x55, 0x24, 0x24, 0xA2, 0xD1, 0x55, 0x29, 0xAD, 0xEB,
67};
68const uint8_t dsa_q[] = {
69 0xEB, 0xEA, 0x17, 0xD2, 0x09, 0xB3, 0xD7, 0x21, 0x9A, 0x21,
70 0x07, 0x82, 0x8F, 0xAB, 0xFE, 0x88, 0x71, 0x68, 0xF7, 0xE3,
71};
72
Shawn Willden128ffe02014-08-06 12:31:33 -060073class KeymasterTest : public testing::Test {
74 protected:
Shawn Willden2f3be362014-08-25 11:31:39 -060075 KeymasterTest() : device(5, new StdoutLogger) { RAND_seed("foobar", 6); }
Shawn Willdenda8485e2014-08-17 08:00:01 -060076 ~KeymasterTest() {}
Shawn Willden128ffe02014-08-06 12:31:33 -060077
Shawn Willdend0772312014-09-18 12:27:57 -060078 template <typename T> void ExpectEmptyResponse(const SupportedResponse<T>& response) {
79 EXPECT_EQ(KM_ERROR_OK, response.error);
80 EXPECT_EQ(0U, response.results_length);
81 }
82
83 template <typename T> void ExpectResponseContains(T val, const SupportedResponse<T>& response) {
84 EXPECT_EQ(KM_ERROR_OK, response.error);
85 EXPECT_EQ(1U, response.results_length);
86 EXPECT_EQ(val, response.results[0]);
87 }
88
Shawn Willden128ffe02014-08-06 12:31:33 -060089 GoogleSoftKeymaster device;
90};
91
Shawn Willden128ffe02014-08-06 12:31:33 -060092typedef KeymasterTest CheckSupported;
93TEST_F(CheckSupported, SupportedAlgorithms) {
94 // Shouldn't blow up on NULL.
95 device.SupportedAlgorithms(NULL);
96
97 SupportedResponse<keymaster_algorithm_t> response;
98 device.SupportedAlgorithms(&response);
99 EXPECT_EQ(KM_ERROR_OK, response.error);
Shawn Willden19fca882015-01-22 16:35:30 -0700100 EXPECT_EQ(4U, response.results_length);
Shawn Willden128ffe02014-08-06 12:31:33 -0600101 EXPECT_EQ(KM_ALGORITHM_RSA, response.results[0]);
Shawn Willden28e41472014-08-18 13:35:22 -0600102 EXPECT_EQ(KM_ALGORITHM_DSA, response.results[1]);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600103 EXPECT_EQ(KM_ALGORITHM_ECDSA, response.results[2]);
Shawn Willden19fca882015-01-22 16:35:30 -0700104 EXPECT_EQ(KM_ALGORITHM_AES, response.results[3]);
Shawn Willden128ffe02014-08-06 12:31:33 -0600105}
106
107TEST_F(CheckSupported, SupportedBlockModes) {
108 // Shouldn't blow up on NULL.
Shawn Willden3809b932014-12-02 06:59:46 -0700109 device.SupportedBlockModes(KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT, NULL);
Shawn Willden128ffe02014-08-06 12:31:33 -0600110
111 SupportedResponse<keymaster_block_mode_t> response;
Shawn Willden3809b932014-12-02 06:59:46 -0700112 device.SupportedBlockModes(KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT, &response);
113 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE, response.error);
Shawn Willden128ffe02014-08-06 12:31:33 -0600114
Shawn Willden3809b932014-12-02 06:59:46 -0700115 device.SupportedBlockModes(KM_ALGORITHM_DSA, KM_PURPOSE_ENCRYPT, &response);
116 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE, response.error);
Shawn Willden28e41472014-08-18 13:35:22 -0600117
Shawn Willden3809b932014-12-02 06:59:46 -0700118 device.SupportedBlockModes(KM_ALGORITHM_ECDSA, KM_PURPOSE_ENCRYPT, &response);
119 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE, response.error);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600120
Shawn Willden3809b932014-12-02 06:59:46 -0700121 device.SupportedBlockModes(KM_ALGORITHM_AES, KM_PURPOSE_ENCRYPT, &response);
Shawn Willden19fca882015-01-22 16:35:30 -0700122 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE, response.error);
Shawn Willden128ffe02014-08-06 12:31:33 -0600123}
124
125TEST_F(CheckSupported, SupportedPaddingModes) {
126 // Shouldn't blow up on NULL.
Shawn Willden3809b932014-12-02 06:59:46 -0700127 device.SupportedPaddingModes(KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT, NULL);
Shawn Willden128ffe02014-08-06 12:31:33 -0600128
129 SupportedResponse<keymaster_padding_t> response;
Shawn Willden3809b932014-12-02 06:59:46 -0700130 device.SupportedPaddingModes(KM_ALGORITHM_RSA, KM_PURPOSE_SIGN, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600131 ExpectResponseContains(KM_PAD_NONE, response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600132
Shawn Willden3809b932014-12-02 06:59:46 -0700133 device.SupportedPaddingModes(KM_ALGORITHM_DSA, KM_PURPOSE_SIGN, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600134 ExpectResponseContains(KM_PAD_NONE, response);
Shawn Willden28e41472014-08-18 13:35:22 -0600135
Shawn Willden3809b932014-12-02 06:59:46 -0700136 device.SupportedPaddingModes(KM_ALGORITHM_ECDSA, KM_PURPOSE_SIGN, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600137 ExpectResponseContains(KM_PAD_NONE, response);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600138
Shawn Willden3809b932014-12-02 06:59:46 -0700139 device.SupportedPaddingModes(KM_ALGORITHM_AES, KM_PURPOSE_SIGN, &response);
Shawn Willden19fca882015-01-22 16:35:30 -0700140 ExpectEmptyResponse(response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600141}
142
143TEST_F(CheckSupported, SupportedDigests) {
144 // Shouldn't blow up on NULL.
Shawn Willden3809b932014-12-02 06:59:46 -0700145 device.SupportedDigests(KM_ALGORITHM_RSA, KM_PURPOSE_SIGN, NULL);
Shawn Willden128ffe02014-08-06 12:31:33 -0600146
147 SupportedResponse<keymaster_digest_t> response;
Shawn Willden3809b932014-12-02 06:59:46 -0700148 device.SupportedDigests(KM_ALGORITHM_RSA, KM_PURPOSE_SIGN, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600149 ExpectResponseContains(KM_DIGEST_NONE, response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600150
Shawn Willden3809b932014-12-02 06:59:46 -0700151 device.SupportedDigests(KM_ALGORITHM_DSA, KM_PURPOSE_SIGN, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600152 ExpectResponseContains(KM_DIGEST_NONE, response);
Shawn Willden28e41472014-08-18 13:35:22 -0600153
Shawn Willden3809b932014-12-02 06:59:46 -0700154 device.SupportedDigests(KM_ALGORITHM_ECDSA, KM_PURPOSE_SIGN, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600155 ExpectResponseContains(KM_DIGEST_NONE, response);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600156
Shawn Willden3809b932014-12-02 06:59:46 -0700157 device.SupportedDigests(KM_ALGORITHM_AES, KM_PURPOSE_SIGN, &response);
Shawn Willden19fca882015-01-22 16:35:30 -0700158 ExpectEmptyResponse(response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600159}
160
161TEST_F(CheckSupported, SupportedImportFormats) {
162 // Shouldn't blow up on NULL.
163 device.SupportedImportFormats(KM_ALGORITHM_RSA, NULL);
164
165 SupportedResponse<keymaster_key_format_t> response;
166 device.SupportedImportFormats(KM_ALGORITHM_RSA, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600167 ExpectResponseContains(KM_KEY_FORMAT_PKCS8, response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600168
169 device.SupportedImportFormats(KM_ALGORITHM_DSA, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600170 ExpectResponseContains(KM_KEY_FORMAT_PKCS8, response);
Shawn Willden28e41472014-08-18 13:35:22 -0600171
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600172 device.SupportedImportFormats(KM_ALGORITHM_ECDSA, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600173 ExpectResponseContains(KM_KEY_FORMAT_PKCS8, response);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600174
Shawn Willden28e41472014-08-18 13:35:22 -0600175 device.SupportedImportFormats(KM_ALGORITHM_AES, &response);
Shawn Willden19fca882015-01-22 16:35:30 -0700176 ExpectEmptyResponse(response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600177}
178
179TEST_F(CheckSupported, SupportedExportFormats) {
180 // Shouldn't blow up on NULL.
181 device.SupportedExportFormats(KM_ALGORITHM_RSA, NULL);
182
183 SupportedResponse<keymaster_key_format_t> response;
184 device.SupportedExportFormats(KM_ALGORITHM_RSA, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600185 ExpectResponseContains(KM_KEY_FORMAT_X509, response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600186
187 device.SupportedExportFormats(KM_ALGORITHM_DSA, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600188 ExpectResponseContains(KM_KEY_FORMAT_X509, response);
Shawn Willden28e41472014-08-18 13:35:22 -0600189
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600190 device.SupportedExportFormats(KM_ALGORITHM_ECDSA, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600191 ExpectResponseContains(KM_KEY_FORMAT_X509, response);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600192
Shawn Willden28e41472014-08-18 13:35:22 -0600193 device.SupportedExportFormats(KM_ALGORITHM_AES, &response);
Shawn Willden19fca882015-01-22 16:35:30 -0700194 ExpectEmptyResponse(response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600195}
196
Shawn Willdend0772312014-09-18 12:27:57 -0600197keymaster_key_param_t key_generation_base_params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700198 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
199 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
Shawn Willdend0772312014-09-18 12:27:57 -0600200 Authorization(TAG_APPLICATION_ID, "app_id", 6),
Shawn Willden3809b932014-12-02 06:59:46 -0700201 Authorization(TAG_APPLICATION_DATA, "app_data", 8), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willdend0772312014-09-18 12:27:57 -0600202};
203
204class NewKeyGeneration : public KeymasterTest {
205 protected:
206 NewKeyGeneration() {
207 req_.key_description.Reinitialize(key_generation_base_params,
208 array_length(key_generation_base_params));
209 }
210
211 void CheckBaseParams(const GenerateKeyResponse& rsp) {
212 ASSERT_EQ(KM_ERROR_OK, rsp.error);
213 EXPECT_EQ(0U, rsp.enforced.size());
214 EXPECT_EQ(12U, rsp.enforced.SerializedSize());
215 EXPECT_GT(rsp.unenforced.SerializedSize(), 12U);
216
217 EXPECT_TRUE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_SIGN));
218 EXPECT_TRUE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_VERIFY));
219 EXPECT_TRUE(contains(rsp.unenforced, TAG_USER_ID, 7));
220 EXPECT_TRUE(contains(rsp.unenforced, TAG_USER_AUTH_ID, 8));
221 EXPECT_TRUE(contains(rsp.unenforced, TAG_AUTH_TIMEOUT, 300));
222
223 // Verify that App ID, App data and ROT are NOT included.
224 EXPECT_FALSE(contains(rsp.unenforced, TAG_ROOT_OF_TRUST));
225 EXPECT_FALSE(contains(rsp.unenforced, TAG_APPLICATION_ID));
226 EXPECT_FALSE(contains(rsp.unenforced, TAG_APPLICATION_DATA));
227
228 // Just for giggles, check that some unexpected tags/values are NOT present.
229 EXPECT_FALSE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
230 EXPECT_FALSE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_DECRYPT));
231 EXPECT_FALSE(contains(rsp.unenforced, TAG_AUTH_TIMEOUT, 301));
232 EXPECT_FALSE(contains(rsp.unenforced, TAG_RESCOPE_AUTH_TIMEOUT));
233
234 // Now check that unspecified, defaulted tags are correct.
235 EXPECT_TRUE(contains(rsp.unenforced, TAG_ORIGIN, KM_ORIGIN_SOFTWARE));
236 EXPECT_TRUE(contains(rsp.unenforced, KM_TAG_CREATION_DATETIME));
237 }
238
239 GenerateKeyRequest req_;
240 GenerateKeyResponse rsp_;
241};
242
Shawn Willden128ffe02014-08-06 12:31:33 -0600243TEST_F(NewKeyGeneration, Rsa) {
Shawn Willdend0772312014-09-18 12:27:57 -0600244 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA));
245 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, 256));
246 req_.key_description.push_back(Authorization(TAG_RSA_PUBLIC_EXPONENT, 3));
247 device.GenerateKey(req_, &rsp_);
Shawn Willden128ffe02014-08-06 12:31:33 -0600248
Shawn Willdend0772312014-09-18 12:27:57 -0600249 CheckBaseParams(rsp_);
Shawn Willden128ffe02014-08-06 12:31:33 -0600250
251 // Check specified tags are all present in unenforced characteristics
Shawn Willdend0772312014-09-18 12:27:57 -0600252 EXPECT_TRUE(contains(rsp_.unenforced, TAG_ALGORITHM, KM_ALGORITHM_RSA));
253 EXPECT_TRUE(contains(rsp_.unenforced, TAG_KEY_SIZE, 256));
254 EXPECT_TRUE(contains(rsp_.unenforced, TAG_RSA_PUBLIC_EXPONENT, 3));
Shawn Willden128ffe02014-08-06 12:31:33 -0600255}
256
Shawn Willden6bbe6782014-09-18 11:26:15 -0600257TEST_F(NewKeyGeneration, RsaDefaultSize) {
Shawn Willdend0772312014-09-18 12:27:57 -0600258 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA));
259 device.GenerateKey(req_, &rsp_);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600260
Shawn Willdend0772312014-09-18 12:27:57 -0600261 CheckBaseParams(rsp_);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600262
263 // Check specified tags are all present in unenforced characteristics
Shawn Willdend0772312014-09-18 12:27:57 -0600264 EXPECT_TRUE(contains(rsp_.unenforced, TAG_ALGORITHM, KM_ALGORITHM_RSA));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600265
266 // Now check that unspecified, defaulted tags are correct.
Shawn Willdend0772312014-09-18 12:27:57 -0600267 EXPECT_TRUE(contains(rsp_.unenforced, TAG_RSA_PUBLIC_EXPONENT, 65537));
268 EXPECT_TRUE(contains(rsp_.unenforced, TAG_KEY_SIZE, 2048));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600269}
270
Shawn Willdend63e3052015-01-20 11:45:07 -0700271TEST_F(NewKeyGeneration, Dsa) {
272 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_DSA));
273 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, 256));
274 device.GenerateKey(req_, &rsp_);
275
276 CheckBaseParams(rsp_);
277
278 // Check specified tags are all present in unenforced characteristics
279 EXPECT_TRUE(contains(rsp_.unenforced, TAG_ALGORITHM, KM_ALGORITHM_DSA));
280 EXPECT_TRUE(contains(rsp_.unenforced, TAG_KEY_SIZE, 256));
281
282 // Generator should have created DSA params.
283 keymaster_blob_t g, p, q;
284 EXPECT_TRUE(rsp_.unenforced.GetTagValue(TAG_DSA_GENERATOR, &g));
285 EXPECT_TRUE(rsp_.unenforced.GetTagValue(TAG_DSA_P, &p));
286 EXPECT_TRUE(rsp_.unenforced.GetTagValue(TAG_DSA_Q, &q));
287 EXPECT_TRUE(g.data_length >= 63 && g.data_length <= 64);
288 EXPECT_EQ(64U, p.data_length);
289 EXPECT_EQ(20U, q.data_length);
290}
291
292TEST_F(NewKeyGeneration, DsaDefaultSize) {
293 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_DSA));
294 device.GenerateKey(req_, &rsp_);
295
296 CheckBaseParams(rsp_);
297
298 // Check specified tags are all present in unenforced characteristics
299 EXPECT_TRUE(contains(rsp_.unenforced, TAG_ALGORITHM, KM_ALGORITHM_DSA));
300
301 // Now check that unspecified, defaulted tags are correct.
302 EXPECT_TRUE(contains(rsp_.unenforced, TAG_KEY_SIZE, 2048));
303 keymaster_blob_t g, p, q;
304 EXPECT_TRUE(rsp_.unenforced.GetTagValue(TAG_DSA_GENERATOR, &g));
305 EXPECT_TRUE(rsp_.unenforced.GetTagValue(TAG_DSA_P, &p));
306 EXPECT_TRUE(rsp_.unenforced.GetTagValue(TAG_DSA_Q, &q));
307 EXPECT_TRUE(g.data_length >= 255 && g.data_length <= 256);
308 EXPECT_EQ(256U, p.data_length);
309 EXPECT_EQ(32U, q.data_length);
310}
311
312TEST_F(NewKeyGeneration, Dsa_ParamsSpecified) {
313 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_DSA));
314 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, 256));
315 req_.key_description.push_back(Authorization(TAG_DSA_GENERATOR, dsa_g, array_size(dsa_g)));
316 req_.key_description.push_back(Authorization(TAG_DSA_P, dsa_p, array_size(dsa_p)));
317 req_.key_description.push_back(Authorization(TAG_DSA_Q, dsa_q, array_size(dsa_q)));
318 device.GenerateKey(req_, &rsp_);
319
320 CheckBaseParams(rsp_);
321
322 // Check specified tags are all present in unenforced characteristics
323 EXPECT_TRUE(contains(rsp_.unenforced, TAG_ALGORITHM, KM_ALGORITHM_DSA));
324 EXPECT_TRUE(contains(rsp_.unenforced, TAG_KEY_SIZE, 256));
325 EXPECT_TRUE(contains(rsp_.unenforced, TAG_DSA_GENERATOR,
326 std::string(reinterpret_cast<const char*>(dsa_g), array_size(dsa_g))));
327 EXPECT_TRUE(contains(rsp_.unenforced, TAG_DSA_P,
328 std::string(reinterpret_cast<const char*>(dsa_p), array_size(dsa_p))));
329 EXPECT_TRUE(contains(rsp_.unenforced, TAG_DSA_Q,
330 std::string(reinterpret_cast<const char*>(dsa_q), array_size(dsa_q))));
331}
332
333TEST_F(NewKeyGeneration, Dsa_SomeParamsSpecified) {
334 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_DSA));
335 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, 256));
336 req_.key_description.push_back(Authorization(TAG_DSA_P, dsa_p, array_size(dsa_p)));
337 req_.key_description.push_back(Authorization(TAG_DSA_Q, dsa_q, array_size(dsa_q)));
338 device.GenerateKey(req_, &rsp_);
339
340 ASSERT_EQ(KM_ERROR_INVALID_DSA_PARAMS, rsp_.error);
341}
342
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600343TEST_F(NewKeyGeneration, Ecdsa) {
Shawn Willdend0772312014-09-18 12:27:57 -0600344 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
Shawn Willden8c856c82014-09-26 09:34:36 -0600345 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, 224));
Shawn Willdend0772312014-09-18 12:27:57 -0600346 device.GenerateKey(req_, &rsp_);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600347
Shawn Willdend0772312014-09-18 12:27:57 -0600348 CheckBaseParams(rsp_);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600349
350 // Check specified tags are all present in unenforced characteristics
Shawn Willdend0772312014-09-18 12:27:57 -0600351 EXPECT_TRUE(contains(rsp_.unenforced, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
Shawn Willden8c856c82014-09-26 09:34:36 -0600352 EXPECT_TRUE(contains(rsp_.unenforced, TAG_KEY_SIZE, 224));
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600353}
354
Shawn Willden6bbe6782014-09-18 11:26:15 -0600355TEST_F(NewKeyGeneration, EcdsaDefaultSize) {
Shawn Willdend0772312014-09-18 12:27:57 -0600356 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
357 device.GenerateKey(req_, &rsp_);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600358
Shawn Willdend0772312014-09-18 12:27:57 -0600359 CheckBaseParams(rsp_);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600360
361 // Check specified tags are all present in unenforced characteristics
Shawn Willdend0772312014-09-18 12:27:57 -0600362 EXPECT_TRUE(contains(rsp_.unenforced, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600363
364 // Now check that unspecified, defaulted tags are correct.
Shawn Willdend0772312014-09-18 12:27:57 -0600365 EXPECT_TRUE(contains(rsp_.unenforced, TAG_KEY_SIZE, 224));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600366}
367
368TEST_F(NewKeyGeneration, EcdsaInvalidSize) {
Shawn Willdend0772312014-09-18 12:27:57 -0600369 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
370 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, 190));
371 device.GenerateKey(req_, &rsp_);
372 ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE, rsp_.error);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600373}
374
375TEST_F(NewKeyGeneration, EcdsaAllValidSizes) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600376 size_t valid_sizes[] = {224, 256, 384, 521};
Shawn Willden6bbe6782014-09-18 11:26:15 -0600377 for (size_t size : valid_sizes) {
Shawn Willden0302c552014-12-03 15:33:39 -0700378 GenerateKeyResponse rsp;
Shawn Willdend0772312014-09-18 12:27:57 -0600379 req_.key_description.Reinitialize(key_generation_base_params,
380 array_length(key_generation_base_params));
381 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
382 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, size));
Shawn Willden0302c552014-12-03 15:33:39 -0700383 device.GenerateKey(req_, &rsp);
384 EXPECT_EQ(KM_ERROR_OK, rsp.error) << "Failed to generate size: " << size;
Shawn Willden6bbe6782014-09-18 11:26:15 -0600385 }
386}
387
Shawn Willden19fca882015-01-22 16:35:30 -0700388TEST_F(NewKeyGeneration, AesOcb) {
389 keymaster_key_param_t params[] = {
390 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
391 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
392 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
393 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_CHUNK_LENGTH, 4096),
394 Authorization(TAG_PADDING, KM_PAD_NONE),
395 };
396 req_.key_description.Reinitialize(params, array_length(params));
397 device.GenerateKey(req_, &rsp_);
398 EXPECT_EQ(KM_ERROR_OK, rsp_.error);
399}
400
401TEST_F(NewKeyGeneration, AesOcbInvalidKeySize) {
402 keymaster_key_param_t params[] = {
403 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
404 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
405 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 129),
406 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_CHUNK_LENGTH, 4096),
407 Authorization(TAG_PADDING, KM_PAD_NONE),
408 };
409 req_.key_description.Reinitialize(params, array_length(params));
410 device.GenerateKey(req_, &rsp_);
411 EXPECT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE, rsp_.error);
412}
413
414TEST_F(NewKeyGeneration, AesOcbAllValidSizes) {
415 keymaster_key_param_t params[] = {
416 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
417 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
418 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES),
419 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB),
420 Authorization(TAG_CHUNK_LENGTH, 4096),
421 Authorization(TAG_PADDING, KM_PAD_NONE),
422 };
423
424 size_t valid_sizes[] = {128, 192, 256};
425 for (size_t size : valid_sizes) {
426 GenerateKeyResponse rsp;
427 req_.key_description.Reinitialize(params, array_length(params));
428 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, size));
429 device.GenerateKey(req_, &rsp);
430 EXPECT_EQ(KM_ERROR_OK, rsp.error) << "Failed to generate size: " << size;
431 }
432}
433
434TEST_F(NewKeyGeneration, AesOcbNoChunkLength) {
435 keymaster_key_param_t params[] = {
436 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
437 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
438 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
439 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_PADDING, KM_PAD_NONE),
440 };
441 req_.key_description.Reinitialize(params, array_length(params));
442 device.GenerateKey(req_, &rsp_);
443 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, rsp_.error);
444}
445
446TEST_F(NewKeyGeneration, AesEcbUnsupported) {
447 keymaster_key_param_t params[] = {
448 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
449 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
450 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
451 Authorization(TAG_BLOCK_MODE, KM_MODE_ECB), Authorization(TAG_PADDING, KM_PAD_NONE),
452 };
453 req_.key_description.Reinitialize(params, array_length(params));
454 device.GenerateKey(req_, &rsp_);
455 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE, rsp_.error);
456}
457
458TEST_F(NewKeyGeneration, AesOcbPaddingUnsupported) {
459 keymaster_key_param_t params[] = {
460 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
461 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
462 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
463 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_CHUNK_LENGTH, 4096),
464 Authorization(TAG_PADDING, KM_PAD_ZERO),
465 };
466 req_.key_description.Reinitialize(params, array_length(params));
467 device.GenerateKey(req_, &rsp_);
468 EXPECT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, rsp_.error);
469}
470
Shawn Willden76364712014-08-11 17:48:04 -0600471typedef KeymasterTest GetKeyCharacteristics;
472TEST_F(GetKeyCharacteristics, SimpleRsa) {
473 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700474 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
475 Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), Authorization(TAG_KEY_SIZE, 256),
476 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
477 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden76364712014-08-11 17:48:04 -0600478 };
479
480 GenerateKeyRequest gen_req;
481 gen_req.key_description.Reinitialize(params, array_length(params));
482 GenerateKeyResponse gen_rsp;
483
484 device.GenerateKey(gen_req, &gen_rsp);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600485 ASSERT_EQ(KM_ERROR_OK, gen_rsp.error);
Shawn Willden76364712014-08-11 17:48:04 -0600486
487 GetKeyCharacteristicsRequest req;
Shawn Willdenda8485e2014-08-17 08:00:01 -0600488 req.SetKeyMaterial(gen_rsp.key_blob);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600489 req.additional_params.push_back(TAG_APPLICATION_ID, "app_id", 6);
Shawn Willden76364712014-08-11 17:48:04 -0600490
491 GetKeyCharacteristicsResponse rsp;
492 device.GetKeyCharacteristics(req, &rsp);
493 ASSERT_EQ(KM_ERROR_OK, rsp.error);
494
495 EXPECT_EQ(gen_rsp.enforced, rsp.enforced);
496 EXPECT_EQ(gen_rsp.unenforced, rsp.unenforced);
497}
498
Shawn Willden61644f32014-08-18 13:43:14 -0600499/**
500 * Test class that provides some infrastructure for generating keys and signing messages.
501 */
Shawn Willden1615f2e2014-08-13 10:37:40 -0600502class SigningOperationsTest : public KeymasterTest {
503 protected:
Shawn Willden61644f32014-08-18 13:43:14 -0600504 void GenerateKey(keymaster_algorithm_t algorithm, keymaster_digest_t digest,
505 keymaster_padding_t padding, uint32_t key_size) {
Shawn Willden1615f2e2014-08-13 10:37:40 -0600506 keymaster_key_param_t params[] = {
507 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
Shawn Willden3809b932014-12-02 06:59:46 -0700508 Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY), Authorization(TAG_ALGORITHM, algorithm),
509 Authorization(TAG_KEY_SIZE, key_size), Authorization(TAG_USER_ID, 7),
510 Authorization(TAG_USER_AUTH_ID, 8), Authorization(TAG_APPLICATION_ID, "app_id", 6),
Shawn Willden1615f2e2014-08-13 10:37:40 -0600511 Authorization(TAG_AUTH_TIMEOUT, 300),
512 };
513 GenerateKeyRequest generate_request;
514 generate_request.key_description.Reinitialize(params, array_length(params));
Shawn Willden43e999e2014-08-13 13:29:50 -0600515 if (static_cast<int>(digest) != -1)
Shawn Willden1615f2e2014-08-13 10:37:40 -0600516 generate_request.key_description.push_back(TAG_DIGEST, digest);
Shawn Willden43e999e2014-08-13 13:29:50 -0600517 if (static_cast<int>(padding) != -1)
Shawn Willden1615f2e2014-08-13 10:37:40 -0600518 generate_request.key_description.push_back(TAG_PADDING, padding);
519 device.GenerateKey(generate_request, &generate_response_);
520 EXPECT_EQ(KM_ERROR_OK, generate_response_.error);
Shawn Willden61644f32014-08-18 13:43:14 -0600521 }
Shawn Willden1615f2e2014-08-13 10:37:40 -0600522
Shawn Willden61644f32014-08-18 13:43:14 -0600523 void SignMessage(const void* message, size_t size) {
Shawn Willden437fbd12014-08-20 11:59:49 -0600524 SignMessage(generate_response_.key_blob, message, size);
525 }
526
527 void SignMessage(const keymaster_key_blob_t& key_blob, const void* message, size_t size) {
Shawn Willden61644f32014-08-18 13:43:14 -0600528 BeginOperationRequest begin_request;
529 BeginOperationResponse begin_response;
Shawn Willden437fbd12014-08-20 11:59:49 -0600530 begin_request.SetKeyMaterial(key_blob);
Shawn Willden61644f32014-08-18 13:43:14 -0600531 begin_request.purpose = KM_PURPOSE_SIGN;
532 AddClientParams(&begin_request.additional_params);
533
534 device.BeginOperation(begin_request, &begin_response);
535 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
536
537 UpdateOperationRequest update_request;
538 UpdateOperationResponse update_response;
539 update_request.op_handle = begin_response.op_handle;
540 update_request.input.Reinitialize(message, size);
541 EXPECT_EQ(size, update_request.input.available_read());
542
543 device.UpdateOperation(update_request, &update_response);
544 ASSERT_EQ(KM_ERROR_OK, update_response.error);
545 EXPECT_EQ(0U, update_response.output.available_read());
546
547 FinishOperationRequest finish_request;
548 finish_request.op_handle = begin_response.op_handle;
549 device.FinishOperation(finish_request, &finish_response_);
550 ASSERT_EQ(KM_ERROR_OK, finish_response_.error);
551 EXPECT_GT(finish_response_.output.available_read(), 0U);
552 }
553
554 void AddClientParams(AuthorizationSet* set) { set->push_back(TAG_APPLICATION_ID, "app_id", 6); }
555
556 const keymaster_key_blob_t& key_blob() { return generate_response_.key_blob; }
Shawn Willdenf268d742014-08-19 15:36:26 -0600557
558 const keymaster_key_blob_t& corrupt_key_blob() {
Shawn Willden2241bf02014-08-28 09:59:53 -0600559 uint8_t* tmp = const_cast<uint8_t*>(generate_response_.key_blob.key_material);
560 ++tmp[generate_response_.key_blob.key_material_size / 2];
Shawn Willdenf268d742014-08-19 15:36:26 -0600561 return generate_response_.key_blob;
562 }
563
Shawn Willden61644f32014-08-18 13:43:14 -0600564 Buffer* signature() {
565 if (finish_response_.error == KM_ERROR_OK)
566 return &finish_response_.output;
567 return NULL;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600568 }
569
Shawn Willden1615f2e2014-08-13 10:37:40 -0600570 GenerateKeyResponse generate_response_;
Shawn Willden61644f32014-08-18 13:43:14 -0600571 FinishOperationResponse finish_response_;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600572};
573
574TEST_F(SigningOperationsTest, RsaSuccess) {
Shawn Willden61644f32014-08-18 13:43:14 -0600575 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willdenffd790c2014-08-18 21:20:06 -0600576 const char message[] = "12345678901234567890123456789012";
Shawn Willdend05cba52014-09-26 09:58:12 -0600577 SignMessage(message, array_size(message) - 1);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600578}
579
Shawn Willdend63e3052015-01-20 11:45:07 -0700580TEST_F(SigningOperationsTest, DsaSuccess) {
581 GenerateKey(KM_ALGORITHM_DSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
582 const char message[] = "123456789012345678901234567890123456789012345678";
583 SignMessage(message, array_size(message) - 1);
584}
585
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600586TEST_F(SigningOperationsTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600587 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willdend05cba52014-09-26 09:58:12 -0600588 const char message[] = "123456789012345678901234567890123456789012345678";
589 SignMessage(message, array_size(message) - 1);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600590}
591
Shawn Willden1615f2e2014-08-13 10:37:40 -0600592TEST_F(SigningOperationsTest, RsaAbort) {
Shawn Willden61644f32014-08-18 13:43:14 -0600593 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600594
595 BeginOperationRequest begin_request;
596 BeginOperationResponse begin_response;
Shawn Willden61644f32014-08-18 13:43:14 -0600597 begin_request.SetKeyMaterial(key_blob());
Shawn Willden1615f2e2014-08-13 10:37:40 -0600598 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600599 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600600
601 device.BeginOperation(begin_request, &begin_response);
602 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
603
604 EXPECT_EQ(KM_ERROR_OK, device.AbortOperation(begin_response.op_handle));
605
606 // Another abort should fail
607 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
608}
609
610TEST_F(SigningOperationsTest, RsaUnsupportedDigest) {
Shawn Willden61644f32014-08-18 13:43:14 -0600611 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_SHA_2_256, KM_PAD_NONE, 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600612
613 BeginOperationRequest begin_request;
614 BeginOperationResponse begin_response;
615 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600616 begin_request.SetKeyMaterial(key_blob());
617 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600618
619 device.BeginOperation(begin_request, &begin_response);
620 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, begin_response.error);
621
622 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
623}
624
625TEST_F(SigningOperationsTest, RsaUnsupportedPadding) {
Shawn Willden61644f32014-08-18 13:43:14 -0600626 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_RSA_OAEP, 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600627
628 BeginOperationRequest begin_request;
629 BeginOperationResponse begin_response;
630 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600631 begin_request.SetKeyMaterial(key_blob());
632 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600633
634 device.BeginOperation(begin_request, &begin_response);
635 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, begin_response.error);
636
637 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
638}
639
640TEST_F(SigningOperationsTest, RsaNoDigest) {
Shawn Willden61644f32014-08-18 13:43:14 -0600641 GenerateKey(KM_ALGORITHM_RSA, static_cast<keymaster_digest_t>(-1), KM_PAD_NONE,
642 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600643
644 BeginOperationRequest begin_request;
645 BeginOperationResponse begin_response;
646 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600647 begin_request.SetKeyMaterial(key_blob());
648 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600649
650 device.BeginOperation(begin_request, &begin_response);
651 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, begin_response.error);
652
653 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
654}
655
656TEST_F(SigningOperationsTest, RsaNoPadding) {
Shawn Willden61644f32014-08-18 13:43:14 -0600657 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, static_cast<keymaster_padding_t>(-1),
658 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600659
660 BeginOperationRequest begin_request;
661 BeginOperationResponse begin_response;
662 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600663 begin_request.SetKeyMaterial(key_blob());
664 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600665
666 device.BeginOperation(begin_request, &begin_response);
667 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, begin_response.error);
668
669 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
670}
671
672TEST_F(SigningOperationsTest, RsaTooShortMessage) {
Shawn Willden61644f32014-08-18 13:43:14 -0600673 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600674
675 BeginOperationRequest begin_request;
676 BeginOperationResponse begin_response;
Shawn Willden61644f32014-08-18 13:43:14 -0600677 begin_request.SetKeyMaterial(key_blob());
Shawn Willden1615f2e2014-08-13 10:37:40 -0600678 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600679 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600680
681 device.BeginOperation(begin_request, &begin_response);
682 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
683
684 UpdateOperationRequest update_request;
685 UpdateOperationResponse update_response;
686 update_request.op_handle = begin_response.op_handle;
687 update_request.input.Reinitialize("01234567890123456789012345678901", 31);
688 EXPECT_EQ(31U, update_request.input.available_read());
689
690 device.UpdateOperation(update_request, &update_response);
691 ASSERT_EQ(KM_ERROR_OK, update_response.error);
692 EXPECT_EQ(0U, update_response.output.available_read());
693
Shawn Willden43e999e2014-08-13 13:29:50 -0600694 FinishOperationRequest finish_request;
695 finish_request.op_handle = begin_response.op_handle;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600696 FinishOperationResponse finish_response;
Shawn Willden43e999e2014-08-13 13:29:50 -0600697 device.FinishOperation(finish_request, &finish_response);
Shawn Willden00aa7942014-09-10 07:57:43 -0600698 ASSERT_EQ(KM_ERROR_UNKNOWN_ERROR, finish_response.error);
Shawn Willden43e999e2014-08-13 13:29:50 -0600699 EXPECT_EQ(0U, finish_response.output.available_read());
700
701 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
702}
703
Shawn Willdend05cba52014-09-26 09:58:12 -0600704class VerificationOperationsTest : public SigningOperationsTest {
705 protected:
706 void VerifyMessage(const void* message, size_t message_len) {
707 VerifyMessage(generate_response_.key_blob, message, message_len);
708 }
709
710 void VerifyMessage(const keymaster_key_blob_t& key_blob, const void* message,
711 size_t message_len) {
712 ASSERT_TRUE(signature() != NULL);
713
714 BeginOperationRequest begin_request;
715 BeginOperationResponse begin_response;
716 begin_request.SetKeyMaterial(key_blob);
717 begin_request.purpose = KM_PURPOSE_VERIFY;
718 AddClientParams(&begin_request.additional_params);
719
720 device.BeginOperation(begin_request, &begin_response);
721 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
722
723 UpdateOperationRequest update_request;
724 UpdateOperationResponse update_response;
725 update_request.op_handle = begin_response.op_handle;
726 update_request.input.Reinitialize(message, message_len);
727 EXPECT_EQ(message_len, update_request.input.available_read());
728
729 device.UpdateOperation(update_request, &update_response);
730 ASSERT_EQ(KM_ERROR_OK, update_response.error);
731 EXPECT_EQ(0U, update_response.output.available_read());
732
733 FinishOperationRequest finish_request;
734 finish_request.op_handle = begin_response.op_handle;
735 finish_request.signature.Reinitialize(*signature());
736 FinishOperationResponse finish_response;
737 device.FinishOperation(finish_request, &finish_response);
738 ASSERT_EQ(KM_ERROR_OK, finish_response.error);
739 EXPECT_EQ(0U, finish_response.output.available_read());
740
741 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE,
742 device.AbortOperation(begin_response.op_handle));
743 }
744};
745
Shawn Willden43e999e2014-08-13 13:29:50 -0600746TEST_F(VerificationOperationsTest, RsaSuccess) {
Shawn Willden61644f32014-08-18 13:43:14 -0600747 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
748 const char message[] = "12345678901234567890123456789012";
749 SignMessage(message, array_size(message) - 1);
Shawn Willdend05cba52014-09-26 09:58:12 -0600750 VerifyMessage(message, array_size(message) - 1);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600751}
752
Shawn Willdend63e3052015-01-20 11:45:07 -0700753TEST_F(VerificationOperationsTest, DsaSuccess) {
754 GenerateKey(KM_ALGORITHM_DSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
755 const char message[] = "123456789012345678901234567890123456789012345678";
756 SignMessage(message, array_size(message) - 1);
757 VerifyMessage(message, array_size(message) - 1);
758}
759
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600760TEST_F(VerificationOperationsTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600761 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600762 const char message[] = "123456789012345678901234567890123456789012345678";
763 SignMessage(message, array_size(message) - 1);
Shawn Willdend05cba52014-09-26 09:58:12 -0600764 VerifyMessage(message, array_size(message) - 1);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600765}
766
Shawn Willdenffd790c2014-08-18 21:20:06 -0600767typedef SigningOperationsTest ExportKeyTest;
768TEST_F(ExportKeyTest, RsaSuccess) {
769 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willdenffd790c2014-08-18 21:20:06 -0600770
771 ExportKeyRequest request;
772 ExportKeyResponse response;
773 AddClientParams(&request.additional_params);
774 request.key_format = KM_KEY_FORMAT_X509;
775 request.SetKeyMaterial(key_blob());
776
777 device.ExportKey(request, &response);
778 ASSERT_EQ(KM_ERROR_OK, response.error);
779 EXPECT_TRUE(response.key_data != NULL);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600780
781 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willdenffd790c2014-08-18 21:20:06 -0600782}
783
Shawn Willdend63e3052015-01-20 11:45:07 -0700784TEST_F(ExportKeyTest, DsaSuccess) {
785 GenerateKey(KM_ALGORITHM_DSA, KM_DIGEST_NONE, KM_PAD_NONE, 1024 /* key size */);
786
787 ExportKeyRequest request;
788 ExportKeyResponse response;
789 AddClientParams(&request.additional_params);
790 request.key_format = KM_KEY_FORMAT_X509;
791 request.SetKeyMaterial(key_blob());
792
793 device.ExportKey(request, &response);
794 ASSERT_EQ(KM_ERROR_OK, response.error);
795 EXPECT_TRUE(response.key_data != NULL);
796
797 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
798}
799
Shawn Willdenf268d742014-08-19 15:36:26 -0600800TEST_F(ExportKeyTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600801 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willdenf268d742014-08-19 15:36:26 -0600802
803 ExportKeyRequest request;
804 ExportKeyResponse response;
805 AddClientParams(&request.additional_params);
806 request.key_format = KM_KEY_FORMAT_X509;
807 request.SetKeyMaterial(key_blob());
808
809 device.ExportKey(request, &response);
810 ASSERT_EQ(KM_ERROR_OK, response.error);
811 EXPECT_TRUE(response.key_data != NULL);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600812
813 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willdenf268d742014-08-19 15:36:26 -0600814}
815
816TEST_F(ExportKeyTest, RsaUnsupportedKeyFormat) {
817 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256);
818
819 ExportKeyRequest request;
820 ExportKeyResponse response;
821 AddClientParams(&request.additional_params);
822
823 /* We have no other defined export formats defined. */
824 request.key_format = KM_KEY_FORMAT_PKCS8;
825 request.SetKeyMaterial(key_blob());
826
827 device.ExportKey(request, &response);
828 ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_FORMAT, response.error);
829 EXPECT_TRUE(response.key_data == NULL);
830}
831
832TEST_F(ExportKeyTest, RsaCorruptedKeyBlob) {
833 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256);
834
835 ExportKeyRequest request;
836 ExportKeyResponse response;
837 AddClientParams(&request.additional_params);
838 request.key_format = KM_KEY_FORMAT_X509;
839 request.SetKeyMaterial(corrupt_key_blob());
840
841 device.ExportKey(request, &response);
842 ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, response.error);
843 ASSERT_TRUE(response.key_data == NULL);
844}
845
Shawn Willden437fbd12014-08-20 11:59:49 -0600846static string read_file(const string& file_name) {
847 ifstream file_stream(file_name, std::ios::binary);
848 istreambuf_iterator<char> file_begin(file_stream);
849 istreambuf_iterator<char> file_end;
850 return string(file_begin, file_end);
851}
852
Shawn Willdend05cba52014-09-26 09:58:12 -0600853typedef VerificationOperationsTest ImportKeyTest;
Shawn Willden437fbd12014-08-20 11:59:49 -0600854TEST_F(ImportKeyTest, RsaSuccess) {
855 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700856 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
857 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
858 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
859 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden437fbd12014-08-20 11:59:49 -0600860 };
861
Shawn Willden81effc62014-08-27 10:08:46 -0600862 string pk8_key = read_file("rsa_privkey_pk8.der");
Shawn Willden437fbd12014-08-20 11:59:49 -0600863 ASSERT_EQ(633U, pk8_key.size());
864
865 ImportKeyRequest import_request;
866 import_request.key_description.Reinitialize(params, array_length(params));
867 import_request.key_format = KM_KEY_FORMAT_PKCS8;
868 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
869
870 ImportKeyResponse import_response;
871 device.ImportKey(import_request, &import_response);
872 ASSERT_EQ(KM_ERROR_OK, import_response.error);
873 EXPECT_EQ(0U, import_response.enforced.size());
874 EXPECT_GT(import_response.unenforced.size(), 0U);
875
876 // Check values derived from the key.
877 EXPECT_TRUE(contains(import_response.unenforced, TAG_ALGORITHM, KM_ALGORITHM_RSA));
878 EXPECT_TRUE(contains(import_response.unenforced, TAG_KEY_SIZE, 1024));
879 EXPECT_TRUE(contains(import_response.unenforced, TAG_RSA_PUBLIC_EXPONENT, 65537U));
880
881 // And values provided by GoogleKeymaster
882 EXPECT_TRUE(contains(import_response.unenforced, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
883 EXPECT_TRUE(contains(import_response.unenforced, KM_TAG_CREATION_DATETIME));
884
885 size_t message_len = 1024 / 8;
886 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
887 std::fill(message.get(), message.get() + message_len, 'a');
888 SignMessage(import_response.key_blob, message.get(), message_len);
889 ASSERT_TRUE(signature() != NULL);
Shawn Willdend05cba52014-09-26 09:58:12 -0600890 VerifyMessage(import_response.key_blob, message.get(), message_len);
Shawn Willden437fbd12014-08-20 11:59:49 -0600891}
892
Shawn Willden6bbe6782014-09-18 11:26:15 -0600893TEST_F(ImportKeyTest, RsaKeySizeMismatch) {
894 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700895 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
896 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
Shawn Willden6bbe6782014-09-18 11:26:15 -0600897 Authorization(TAG_KEY_SIZE, 2048), // Doesn't match key
Shawn Willden3809b932014-12-02 06:59:46 -0700898 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
899 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden6bbe6782014-09-18 11:26:15 -0600900 };
901
902 string pk8_key = read_file("rsa_privkey_pk8.der");
903 ASSERT_EQ(633U, pk8_key.size());
904
905 ImportKeyRequest import_request;
906 import_request.key_description.Reinitialize(params, array_length(params));
907 import_request.key_format = KM_KEY_FORMAT_PKCS8;
908 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
909
910 ImportKeyResponse import_response;
911 device.ImportKey(import_request, &import_response);
912 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH, import_response.error);
913}
914
915TEST_F(ImportKeyTest, RsaPublicExponenMismatch) {
916 keymaster_key_param_t params[] = {
917 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
Shawn Willden3809b932014-12-02 06:59:46 -0700918 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
919 Authorization(TAG_RSA_PUBLIC_EXPONENT, 3), Authorization(TAG_USER_ID, 7),
920 Authorization(TAG_USER_AUTH_ID, 8), Authorization(TAG_APPLICATION_ID, "app_id", 6),
Shawn Willden6bbe6782014-09-18 11:26:15 -0600921 Authorization(TAG_AUTH_TIMEOUT, 300),
922 };
923
924 string pk8_key = read_file("rsa_privkey_pk8.der");
925 ASSERT_EQ(633U, pk8_key.size());
926
927 ImportKeyRequest import_request;
928 import_request.key_description.Reinitialize(params, array_length(params));
929 import_request.key_format = KM_KEY_FORMAT_PKCS8;
930 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
931
932 ImportKeyResponse import_response;
933 device.ImportKey(import_request, &import_response);
934 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH, import_response.error);
935}
936
Shawn Willdend63e3052015-01-20 11:45:07 -0700937TEST_F(ImportKeyTest, DsaSuccess) {
938 keymaster_key_param_t params[] = {
939 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
940 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
941 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
942 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
943 };
944
945 string pk8_key = read_file("dsa_privkey_pk8.der");
946 ASSERT_EQ(335U, pk8_key.size());
947
948 ImportKeyRequest import_request;
949 import_request.key_description.Reinitialize(params, array_length(params));
950 import_request.key_format = KM_KEY_FORMAT_PKCS8;
951 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
952
953 ImportKeyResponse import_response;
954 device.ImportKey(import_request, &import_response);
955 ASSERT_EQ(KM_ERROR_OK, import_response.error);
956 EXPECT_EQ(0U, import_response.enforced.size());
957 EXPECT_GT(import_response.unenforced.size(), 0U);
958
959 // Check values derived from the key.
960 EXPECT_TRUE(contains(import_response.unenforced, TAG_ALGORITHM, KM_ALGORITHM_DSA));
961 EXPECT_TRUE(contains(import_response.unenforced, TAG_KEY_SIZE, 1024));
962
963 // And values provided by GoogleKeymaster
964 EXPECT_TRUE(contains(import_response.unenforced, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
965 EXPECT_TRUE(contains(import_response.unenforced, KM_TAG_CREATION_DATETIME));
966
967 size_t message_len = 48;
968 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
969 std::fill(message.get(), message.get() + message_len, 'a');
970 SignMessage(import_response.key_blob, message.get(), message_len);
971 ASSERT_TRUE(signature() != NULL);
972 VerifyMessage(import_response.key_blob, message.get(), message_len);
973}
974
975TEST_F(ImportKeyTest, DsaParametersMatch) {
976 keymaster_key_param_t params[] = {
977 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
978 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
979 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
980 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
981 Authorization(TAG_KEY_SIZE, 1024),
982 Authorization(TAG_DSA_GENERATOR, dsa_g, array_size(dsa_g)),
983 Authorization(TAG_DSA_P, dsa_p, array_size(dsa_p)),
984 Authorization(TAG_DSA_Q, dsa_q, array_size(dsa_q)),
985 };
986
987 string pk8_key = read_file("dsa_privkey_pk8.der");
988 ASSERT_EQ(335U, pk8_key.size());
989
990 ImportKeyRequest import_request;
991 import_request.key_description.Reinitialize(params, array_length(params));
992 import_request.key_format = KM_KEY_FORMAT_PKCS8;
993 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
994
995 ImportKeyResponse import_response;
996 device.ImportKey(import_request, &import_response);
997 ASSERT_EQ(KM_ERROR_OK, import_response.error);
998 EXPECT_EQ(0U, import_response.enforced.size());
999 EXPECT_GT(import_response.unenforced.size(), 0U);
1000
1001 // Check values derived from the key.
1002 EXPECT_TRUE(contains(import_response.unenforced, TAG_ALGORITHM, KM_ALGORITHM_DSA));
1003 EXPECT_TRUE(contains(import_response.unenforced, TAG_KEY_SIZE, 1024));
1004
1005 // And values provided by GoogleKeymaster
1006 EXPECT_TRUE(contains(import_response.unenforced, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
1007 EXPECT_TRUE(contains(import_response.unenforced, KM_TAG_CREATION_DATETIME));
1008
1009 size_t message_len = 48;
1010 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
1011 std::fill(message.get(), message.get() + message_len, 'a');
1012 SignMessage(import_response.key_blob, message.get(), message_len);
1013 ASSERT_TRUE(signature() != NULL);
1014 VerifyMessage(import_response.key_blob, message.get(), message_len);
1015}
1016
1017uint8_t dsa_wrong_q[] = {
1018 0xC0, 0x66, 0x64, 0xF9, 0x05, 0x38, 0x64, 0x38, 0x4A, 0x17,
1019 0x66, 0x79, 0xDD, 0x7F, 0x6E, 0x55, 0x22, 0x2A, 0xDF, 0xC5,
1020};
1021
1022TEST_F(ImportKeyTest, DsaParameterMismatch) {
1023 keymaster_key_param_t params[] = {
1024 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
1025 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
1026 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
1027 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
1028 Authorization(TAG_KEY_SIZE, 1024),
1029 Authorization(TAG_DSA_Q, dsa_wrong_q, array_size(dsa_wrong_q)),
1030 };
1031
1032 string pk8_key = read_file("dsa_privkey_pk8.der");
1033 ASSERT_EQ(335U, pk8_key.size());
1034
1035 ImportKeyRequest import_request;
1036 import_request.key_description.Reinitialize(params, array_length(params));
1037 import_request.key_format = KM_KEY_FORMAT_PKCS8;
1038 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
1039
1040 ImportKeyResponse import_response;
1041 device.ImportKey(import_request, &import_response);
1042 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH, import_response.error);
1043}
1044
1045TEST_F(ImportKeyTest, DsaKeySizeMismatch) {
1046 keymaster_key_param_t params[] = {
1047 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
1048 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
1049 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
1050 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
1051 Authorization(TAG_KEY_SIZE, 2048),
1052 };
1053
1054 string pk8_key = read_file("dsa_privkey_pk8.der");
1055 ASSERT_EQ(335U, pk8_key.size());
1056
1057 ImportKeyRequest import_request;
1058 import_request.key_description.Reinitialize(params, array_length(params));
1059 import_request.key_format = KM_KEY_FORMAT_PKCS8;
1060 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
1061
1062 ImportKeyResponse import_response;
1063 device.ImportKey(import_request, &import_response);
1064 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH, import_response.error);
1065}
1066
Shawn Willden81effc62014-08-27 10:08:46 -06001067TEST_F(ImportKeyTest, EcdsaSuccess) {
1068 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -07001069 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
1070 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
1071 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
1072 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden81effc62014-08-27 10:08:46 -06001073 };
1074
1075 string pk8_key = read_file("ec_privkey_pk8.der");
1076 ASSERT_EQ(138U, pk8_key.size());
1077
1078 ImportKeyRequest import_request;
1079 import_request.key_description.Reinitialize(params, array_length(params));
1080 import_request.key_format = KM_KEY_FORMAT_PKCS8;
1081 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
1082
1083 ImportKeyResponse import_response;
1084 device.ImportKey(import_request, &import_response);
1085 ASSERT_EQ(KM_ERROR_OK, import_response.error);
1086 EXPECT_EQ(0U, import_response.enforced.size());
1087 EXPECT_GT(import_response.unenforced.size(), 0U);
1088
1089 // Check values derived from the key.
1090 EXPECT_TRUE(contains(import_response.unenforced, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
1091 EXPECT_TRUE(contains(import_response.unenforced, TAG_KEY_SIZE, 256));
1092
1093 // And values provided by GoogleKeymaster
1094 EXPECT_TRUE(contains(import_response.unenforced, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
1095 EXPECT_TRUE(contains(import_response.unenforced, KM_TAG_CREATION_DATETIME));
1096
1097 size_t message_len = 1024 / 8;
1098 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
1099 std::fill(message.get(), message.get() + message_len, 'a');
1100 SignMessage(import_response.key_blob, message.get(), message_len);
1101 ASSERT_TRUE(signature() != NULL);
Shawn Willdend05cba52014-09-26 09:58:12 -06001102 VerifyMessage(import_response.key_blob, message.get(), message_len);
Shawn Willden81effc62014-08-27 10:08:46 -06001103}
1104
Shawn Willden6bbe6782014-09-18 11:26:15 -06001105TEST_F(ImportKeyTest, EcdsaSizeSpecified) {
1106 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -07001107 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
1108 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
1109 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
1110 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden6bbe6782014-09-18 11:26:15 -06001111 Authorization(TAG_KEY_SIZE, 256),
1112 };
1113
1114 string pk8_key = read_file("ec_privkey_pk8.der");
1115 ASSERT_EQ(138U, pk8_key.size());
1116
1117 ImportKeyRequest import_request;
1118 import_request.key_description.Reinitialize(params, array_length(params));
1119 import_request.key_format = KM_KEY_FORMAT_PKCS8;
1120 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
1121
1122 ImportKeyResponse import_response;
1123 device.ImportKey(import_request, &import_response);
1124 ASSERT_EQ(KM_ERROR_OK, import_response.error);
1125 EXPECT_EQ(0U, import_response.enforced.size());
1126 EXPECT_GT(import_response.unenforced.size(), 0U);
1127
1128 // Check values derived from the key.
1129 EXPECT_TRUE(contains(import_response.unenforced, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
1130 EXPECT_TRUE(contains(import_response.unenforced, TAG_KEY_SIZE, 256));
1131
1132 // And values provided by GoogleKeymaster
1133 EXPECT_TRUE(contains(import_response.unenforced, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
1134 EXPECT_TRUE(contains(import_response.unenforced, KM_TAG_CREATION_DATETIME));
1135
1136 size_t message_len = 1024 / 8;
1137 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
1138 std::fill(message.get(), message.get() + message_len, 'a');
1139 SignMessage(import_response.key_blob, message.get(), message_len);
1140 ASSERT_TRUE(signature() != NULL);
Shawn Willdend05cba52014-09-26 09:58:12 -06001141 VerifyMessage(import_response.key_blob, message.get(), message_len);
Shawn Willden6bbe6782014-09-18 11:26:15 -06001142}
1143
1144TEST_F(ImportKeyTest, EcdsaSizeMismatch) {
1145 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -07001146 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
1147 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
1148 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
1149 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden8c856c82014-09-26 09:34:36 -06001150 Authorization(TAG_KEY_SIZE, 224),
Shawn Willden6bbe6782014-09-18 11:26:15 -06001151 };
1152
1153 string pk8_key = read_file("ec_privkey_pk8.der");
1154 ASSERT_EQ(138U, pk8_key.size());
1155
1156 ImportKeyRequest import_request;
1157 import_request.key_description.Reinitialize(params, array_length(params));
1158 import_request.key_format = KM_KEY_FORMAT_PKCS8;
1159 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
1160
1161 ImportKeyResponse import_response;
1162 device.ImportKey(import_request, &import_response);
1163 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH, import_response.error);
1164}
1165
Shawn Willden2665e862014-11-24 14:46:21 -07001166typedef KeymasterTest VersionTest;
1167TEST_F(VersionTest, GetVersion) {
1168 GetVersionRequest req;
1169 GetVersionResponse rsp;
1170 device.GetVersion(req, &rsp);
1171 EXPECT_EQ(KM_ERROR_OK, rsp.error);
1172 EXPECT_EQ(1, rsp.major_ver);
1173 EXPECT_EQ(0, rsp.minor_ver);
1174 EXPECT_EQ(0, rsp.subminor_ver);
1175}
1176
Shawn Willden4200f212014-12-02 07:01:21 -07001177/**
1178 * Test class that provides some infrastructure for generating keys and encrypting messages.
1179 */
1180class EncryptionOperationsTest : public KeymasterTest {
1181 protected:
1182 void GenerateKey(keymaster_algorithm_t algorithm, keymaster_padding_t padding,
1183 uint32_t key_size) {
1184 keymaster_key_param_t params[] = {
1185 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
1186 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT), Authorization(TAG_ALGORITHM, algorithm),
1187 Authorization(TAG_KEY_SIZE, key_size), Authorization(TAG_USER_ID, 7),
1188 Authorization(TAG_USER_AUTH_ID, 8), Authorization(TAG_APPLICATION_ID, "app_id", 6),
1189 Authorization(TAG_AUTH_TIMEOUT, 300),
1190 };
1191 GenerateKeyRequest generate_request;
1192 generate_request.key_description.Reinitialize(params, array_length(params));
1193 if (static_cast<int>(padding) != -1)
1194 generate_request.key_description.push_back(TAG_PADDING, padding);
1195 device.GenerateKey(generate_request, &generate_response_);
1196 EXPECT_EQ(KM_ERROR_OK, generate_response_.error);
1197 }
1198
1199 keymaster_error_t BeginOperation(keymaster_purpose_t purpose,
1200 const keymaster_key_blob_t& key_blob, uint64_t* op_handle) {
1201 BeginOperationRequest begin_request;
1202 begin_request.SetKeyMaterial(key_blob);
1203 begin_request.purpose = purpose;
1204 AddClientParams(&begin_request.additional_params);
1205
1206 BeginOperationResponse begin_response;
1207 device.BeginOperation(begin_request, &begin_response);
1208 *op_handle = begin_response.op_handle;
1209 return begin_response.error;
1210 }
1211
1212 keymaster_error_t UpdateOperation(uint64_t op_handle, const void* message, size_t size,
1213 string* output) {
1214 UpdateOperationRequest update_request;
1215 update_request.op_handle = op_handle;
1216 update_request.input.Reinitialize(message, size);
1217
1218 UpdateOperationResponse update_response;
1219 device.UpdateOperation(update_request, &update_response);
1220 if (update_response.error == KM_ERROR_OK)
1221 output->append(reinterpret_cast<const char*>(update_response.output.peek_read()),
1222 update_response.output.available_read());
1223 return update_response.error;
1224 }
1225
1226 keymaster_error_t FinishOperation(uint64_t op_handle, string* output) {
1227 FinishOperationRequest finish_request;
1228 finish_request.op_handle = op_handle;
1229 FinishOperationResponse finish_response;
1230 device.FinishOperation(finish_request, &finish_response);
1231 if (finish_response.error == KM_ERROR_OK)
1232 output->append(reinterpret_cast<const char*>(finish_response.output.peek_read()),
1233 finish_response.output.available_read());
1234 return finish_response.error;
1235 }
1236
1237 string ProcessMessage(keymaster_purpose_t purpose, const keymaster_key_blob_t& key_blob,
1238 const void* message, size_t size) {
1239 uint64_t op_handle;
1240 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose, key_blob, &op_handle));
1241
1242 string result;
1243 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, message, size, &result));
1244 EXPECT_EQ(KM_ERROR_OK, FinishOperation(op_handle, &result));
1245 return result;
1246 }
1247
1248 string EncryptMessage(const void* message, size_t size) {
1249 return ProcessMessage(KM_PURPOSE_ENCRYPT, generate_response_.key_blob, message, size);
1250 }
1251
1252 string DecryptMessage(const void* ciphertext, size_t size) {
1253 return ProcessMessage(KM_PURPOSE_DECRYPT, generate_response_.key_blob, ciphertext, size);
1254 }
1255
1256 void AddClientParams(AuthorizationSet* set) { set->push_back(TAG_APPLICATION_ID, "app_id", 6); }
1257
1258 const keymaster_key_blob_t& key_blob() { return generate_response_.key_blob; }
1259
1260 const keymaster_key_blob_t& corrupt_key_blob() {
1261 uint8_t* tmp = const_cast<uint8_t*>(generate_response_.key_blob.key_material);
1262 ++tmp[generate_response_.key_blob.key_material_size / 2];
1263 return generate_response_.key_blob;
1264 }
1265
1266 protected:
1267 GenerateKeyResponse generate_response_;
1268};
1269
1270TEST_F(EncryptionOperationsTest, RsaOaepSuccess) {
1271 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1272 const char message[] = "Hello World!";
1273 string ciphertext1 = EncryptMessage(message, strlen(message));
1274 EXPECT_EQ(512 / 8, ciphertext1.size());
1275
1276 string ciphertext2 = EncryptMessage(message, strlen(message));
1277 EXPECT_EQ(512 / 8, ciphertext2.size());
1278
1279 // OAEP randomizes padding so every result should be different.
1280 EXPECT_NE(ciphertext1, ciphertext2);
1281}
1282
1283TEST_F(EncryptionOperationsTest, RsaOaepRoundTrip) {
1284 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1285 const char message[] = "Hello World!";
1286 string ciphertext = EncryptMessage(message, strlen(message));
1287 EXPECT_EQ(512 / 8, ciphertext.size());
1288
1289 string plaintext = DecryptMessage(ciphertext.data(), ciphertext.size());
1290 EXPECT_EQ(message, plaintext);
1291}
1292
1293TEST_F(EncryptionOperationsTest, RsaOaepTooLarge) {
1294 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1295 const char message[] = "12345678901234567890123";
1296 uint64_t op_handle;
1297 string result;
1298
1299 EXPECT_EQ(KM_ERROR_OK,
1300 BeginOperation(KM_PURPOSE_ENCRYPT, generate_response_.key_blob, &op_handle));
1301 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, message, array_size(message), &result));
1302 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(op_handle, &result));
1303 EXPECT_EQ(0, result.size());
1304}
1305
1306TEST_F(EncryptionOperationsTest, RsaOaepCorruptedDecrypt) {
1307 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1308 const char message[] = "Hello World!";
1309 string ciphertext = EncryptMessage(message, strlen(message));
1310 EXPECT_EQ(512 / 8, ciphertext.size());
1311
1312 // Corrupt the ciphertext
1313 ciphertext[512 / 8 / 2]++;
1314
1315 uint64_t op_handle;
1316 string result;
1317 EXPECT_EQ(KM_ERROR_OK,
1318 BeginOperation(KM_PURPOSE_DECRYPT, generate_response_.key_blob, &op_handle));
1319 EXPECT_EQ(KM_ERROR_OK,
1320 UpdateOperation(op_handle, ciphertext.data(), ciphertext.size(), &result));
1321 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(op_handle, &result));
1322 EXPECT_EQ(0, result.size());
1323}
1324
1325TEST_F(EncryptionOperationsTest, RsaPkcs1Success) {
1326 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1327 const char message[] = "Hello World!";
1328 string ciphertext1 = EncryptMessage(message, strlen(message));
1329 EXPECT_EQ(512 / 8, ciphertext1.size());
1330
1331 string ciphertext2 = EncryptMessage(message, strlen(message));
1332 EXPECT_EQ(512 / 8, ciphertext2.size());
1333
1334 // PKCS1 v1.5 randomizes padding so every result should be different.
1335 EXPECT_NE(ciphertext1, ciphertext2);
1336}
1337
1338TEST_F(EncryptionOperationsTest, RsaPkcs1RoundTrip) {
1339 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1340 const char message[] = "Hello World!";
1341 string ciphertext = EncryptMessage(message, strlen(message));
1342 EXPECT_EQ(512 / 8, ciphertext.size());
1343
1344 string plaintext = DecryptMessage(ciphertext.data(), ciphertext.size());
1345 EXPECT_EQ(message, plaintext);
1346}
1347
1348TEST_F(EncryptionOperationsTest, RsaPkcs1TooLarge) {
1349 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1350 const char message[] = "1234567890123456789012345678901234567890123456789012";
1351 uint64_t op_handle;
1352 string result;
1353
1354 EXPECT_EQ(KM_ERROR_OK,
1355 BeginOperation(KM_PURPOSE_ENCRYPT, generate_response_.key_blob, &op_handle));
1356 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, message, array_size(message), &result));
1357 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(op_handle, &result));
1358 EXPECT_EQ(0, result.size());
1359}
1360
1361TEST_F(EncryptionOperationsTest, RsaPkcs1CorruptedDecrypt) {
1362 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1363 const char message[] = "Hello World!";
1364 string ciphertext = EncryptMessage(message, strlen(message));
1365 EXPECT_EQ(512 / 8, ciphertext.size());
1366
1367 // Corrupt the ciphertext
1368 ciphertext[512 / 8 / 2]++;
1369
1370 uint64_t op_handle;
1371 string result;
1372 EXPECT_EQ(KM_ERROR_OK,
1373 BeginOperation(KM_PURPOSE_DECRYPT, generate_response_.key_blob, &op_handle));
1374 EXPECT_EQ(KM_ERROR_OK,
1375 UpdateOperation(op_handle, ciphertext.data(), ciphertext.size(), &result));
1376 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(op_handle, &result));
1377 EXPECT_EQ(0, result.size());
1378}
1379
Shawn Willden128ffe02014-08-06 12:31:33 -06001380} // namespace test
1381} // namespace keymaster