blob: ff21f45aea0ce2f00b3dc91aa80be158ae21d5d6 [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 Willden4d024ce2015-01-20 11:45:11 -0700100 EXPECT_EQ(3U, 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 Willden128ffe02014-08-06 12:31:33 -0600104}
105
106TEST_F(CheckSupported, SupportedBlockModes) {
107 // Shouldn't blow up on NULL.
Shawn Willden3809b932014-12-02 06:59:46 -0700108 device.SupportedBlockModes(KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT, NULL);
Shawn Willden128ffe02014-08-06 12:31:33 -0600109
110 SupportedResponse<keymaster_block_mode_t> response;
Shawn Willden3809b932014-12-02 06:59:46 -0700111 device.SupportedBlockModes(KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT, &response);
112 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE, response.error);
Shawn Willden128ffe02014-08-06 12:31:33 -0600113
Shawn Willden3809b932014-12-02 06:59:46 -0700114 device.SupportedBlockModes(KM_ALGORITHM_DSA, KM_PURPOSE_ENCRYPT, &response);
115 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE, response.error);
Shawn Willden28e41472014-08-18 13:35:22 -0600116
Shawn Willden3809b932014-12-02 06:59:46 -0700117 device.SupportedBlockModes(KM_ALGORITHM_ECDSA, KM_PURPOSE_ENCRYPT, &response);
118 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE, response.error);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600119
Shawn Willden3809b932014-12-02 06:59:46 -0700120 device.SupportedBlockModes(KM_ALGORITHM_AES, KM_PURPOSE_ENCRYPT, &response);
Shawn Willden4d024ce2015-01-20 11:45:11 -0700121 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM, response.error);
Shawn Willden128ffe02014-08-06 12:31:33 -0600122}
123
124TEST_F(CheckSupported, SupportedPaddingModes) {
125 // Shouldn't blow up on NULL.
Shawn Willden3809b932014-12-02 06:59:46 -0700126 device.SupportedPaddingModes(KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT, NULL);
Shawn Willden128ffe02014-08-06 12:31:33 -0600127
128 SupportedResponse<keymaster_padding_t> response;
Shawn Willden3809b932014-12-02 06:59:46 -0700129 device.SupportedPaddingModes(KM_ALGORITHM_RSA, KM_PURPOSE_SIGN, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600130 ExpectResponseContains(KM_PAD_NONE, response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600131
Shawn Willden3809b932014-12-02 06:59:46 -0700132 device.SupportedPaddingModes(KM_ALGORITHM_DSA, KM_PURPOSE_SIGN, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600133 ExpectResponseContains(KM_PAD_NONE, response);
Shawn Willden28e41472014-08-18 13:35:22 -0600134
Shawn Willden3809b932014-12-02 06:59:46 -0700135 device.SupportedPaddingModes(KM_ALGORITHM_ECDSA, KM_PURPOSE_SIGN, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600136 ExpectResponseContains(KM_PAD_NONE, response);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600137
Shawn Willden3809b932014-12-02 06:59:46 -0700138 device.SupportedPaddingModes(KM_ALGORITHM_AES, KM_PURPOSE_SIGN, &response);
Shawn Willden4d024ce2015-01-20 11:45:11 -0700139 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM, response.error);
Shawn Willden128ffe02014-08-06 12:31:33 -0600140}
141
142TEST_F(CheckSupported, SupportedDigests) {
143 // Shouldn't blow up on NULL.
Shawn Willden3809b932014-12-02 06:59:46 -0700144 device.SupportedDigests(KM_ALGORITHM_RSA, KM_PURPOSE_SIGN, NULL);
Shawn Willden128ffe02014-08-06 12:31:33 -0600145
146 SupportedResponse<keymaster_digest_t> response;
Shawn Willden3809b932014-12-02 06:59:46 -0700147 device.SupportedDigests(KM_ALGORITHM_RSA, KM_PURPOSE_SIGN, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600148 ExpectResponseContains(KM_DIGEST_NONE, response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600149
Shawn Willden3809b932014-12-02 06:59:46 -0700150 device.SupportedDigests(KM_ALGORITHM_DSA, KM_PURPOSE_SIGN, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600151 ExpectResponseContains(KM_DIGEST_NONE, response);
Shawn Willden28e41472014-08-18 13:35:22 -0600152
Shawn Willden3809b932014-12-02 06:59:46 -0700153 device.SupportedDigests(KM_ALGORITHM_ECDSA, KM_PURPOSE_SIGN, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600154 ExpectResponseContains(KM_DIGEST_NONE, response);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600155
Shawn Willden3809b932014-12-02 06:59:46 -0700156 device.SupportedDigests(KM_ALGORITHM_AES, KM_PURPOSE_SIGN, &response);
Shawn Willden4d024ce2015-01-20 11:45:11 -0700157 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM, response.error);
Shawn Willden128ffe02014-08-06 12:31:33 -0600158}
159
160TEST_F(CheckSupported, SupportedImportFormats) {
161 // Shouldn't blow up on NULL.
162 device.SupportedImportFormats(KM_ALGORITHM_RSA, NULL);
163
164 SupportedResponse<keymaster_key_format_t> response;
165 device.SupportedImportFormats(KM_ALGORITHM_RSA, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600166 ExpectResponseContains(KM_KEY_FORMAT_PKCS8, response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600167
168 device.SupportedImportFormats(KM_ALGORITHM_DSA, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600169 ExpectResponseContains(KM_KEY_FORMAT_PKCS8, response);
Shawn Willden28e41472014-08-18 13:35:22 -0600170
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600171 device.SupportedImportFormats(KM_ALGORITHM_ECDSA, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600172 ExpectResponseContains(KM_KEY_FORMAT_PKCS8, response);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600173
Shawn Willden28e41472014-08-18 13:35:22 -0600174 device.SupportedImportFormats(KM_ALGORITHM_AES, &response);
Shawn Willden4d024ce2015-01-20 11:45:11 -0700175 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM, response.error);
Shawn Willden128ffe02014-08-06 12:31:33 -0600176}
177
178TEST_F(CheckSupported, SupportedExportFormats) {
179 // Shouldn't blow up on NULL.
180 device.SupportedExportFormats(KM_ALGORITHM_RSA, NULL);
181
182 SupportedResponse<keymaster_key_format_t> response;
183 device.SupportedExportFormats(KM_ALGORITHM_RSA, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600184 ExpectResponseContains(KM_KEY_FORMAT_X509, response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600185
186 device.SupportedExportFormats(KM_ALGORITHM_DSA, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600187 ExpectResponseContains(KM_KEY_FORMAT_X509, response);
Shawn Willden28e41472014-08-18 13:35:22 -0600188
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600189 device.SupportedExportFormats(KM_ALGORITHM_ECDSA, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600190 ExpectResponseContains(KM_KEY_FORMAT_X509, response);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600191
Shawn Willden28e41472014-08-18 13:35:22 -0600192 device.SupportedExportFormats(KM_ALGORITHM_AES, &response);
Shawn Willden4d024ce2015-01-20 11:45:11 -0700193 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM, response.error);
Shawn Willden128ffe02014-08-06 12:31:33 -0600194}
195
Shawn Willdend0772312014-09-18 12:27:57 -0600196keymaster_key_param_t key_generation_base_params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700197 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
198 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
Shawn Willdend0772312014-09-18 12:27:57 -0600199 Authorization(TAG_APPLICATION_ID, "app_id", 6),
Shawn Willden3809b932014-12-02 06:59:46 -0700200 Authorization(TAG_APPLICATION_DATA, "app_data", 8), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willdend0772312014-09-18 12:27:57 -0600201};
202
203class NewKeyGeneration : public KeymasterTest {
204 protected:
205 NewKeyGeneration() {
206 req_.key_description.Reinitialize(key_generation_base_params,
207 array_length(key_generation_base_params));
208 }
209
210 void CheckBaseParams(const GenerateKeyResponse& rsp) {
211 ASSERT_EQ(KM_ERROR_OK, rsp.error);
212 EXPECT_EQ(0U, rsp.enforced.size());
213 EXPECT_EQ(12U, rsp.enforced.SerializedSize());
214 EXPECT_GT(rsp.unenforced.SerializedSize(), 12U);
215
216 EXPECT_TRUE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_SIGN));
217 EXPECT_TRUE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_VERIFY));
218 EXPECT_TRUE(contains(rsp.unenforced, TAG_USER_ID, 7));
219 EXPECT_TRUE(contains(rsp.unenforced, TAG_USER_AUTH_ID, 8));
220 EXPECT_TRUE(contains(rsp.unenforced, TAG_AUTH_TIMEOUT, 300));
221
222 // Verify that App ID, App data and ROT are NOT included.
223 EXPECT_FALSE(contains(rsp.unenforced, TAG_ROOT_OF_TRUST));
224 EXPECT_FALSE(contains(rsp.unenforced, TAG_APPLICATION_ID));
225 EXPECT_FALSE(contains(rsp.unenforced, TAG_APPLICATION_DATA));
226
227 // Just for giggles, check that some unexpected tags/values are NOT present.
228 EXPECT_FALSE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
229 EXPECT_FALSE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_DECRYPT));
230 EXPECT_FALSE(contains(rsp.unenforced, TAG_AUTH_TIMEOUT, 301));
231 EXPECT_FALSE(contains(rsp.unenforced, TAG_RESCOPE_AUTH_TIMEOUT));
232
233 // Now check that unspecified, defaulted tags are correct.
234 EXPECT_TRUE(contains(rsp.unenforced, TAG_ORIGIN, KM_ORIGIN_SOFTWARE));
235 EXPECT_TRUE(contains(rsp.unenforced, KM_TAG_CREATION_DATETIME));
236 }
237
238 GenerateKeyRequest req_;
239 GenerateKeyResponse rsp_;
240};
241
Shawn Willden128ffe02014-08-06 12:31:33 -0600242TEST_F(NewKeyGeneration, Rsa) {
Shawn Willdend0772312014-09-18 12:27:57 -0600243 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA));
244 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, 256));
245 req_.key_description.push_back(Authorization(TAG_RSA_PUBLIC_EXPONENT, 3));
246 device.GenerateKey(req_, &rsp_);
Shawn Willden128ffe02014-08-06 12:31:33 -0600247
Shawn Willdend0772312014-09-18 12:27:57 -0600248 CheckBaseParams(rsp_);
Shawn Willden128ffe02014-08-06 12:31:33 -0600249
250 // Check specified tags are all present in unenforced characteristics
Shawn Willdend0772312014-09-18 12:27:57 -0600251 EXPECT_TRUE(contains(rsp_.unenforced, TAG_ALGORITHM, KM_ALGORITHM_RSA));
252 EXPECT_TRUE(contains(rsp_.unenforced, TAG_KEY_SIZE, 256));
253 EXPECT_TRUE(contains(rsp_.unenforced, TAG_RSA_PUBLIC_EXPONENT, 3));
Shawn Willden128ffe02014-08-06 12:31:33 -0600254}
255
Shawn Willden6bbe6782014-09-18 11:26:15 -0600256TEST_F(NewKeyGeneration, RsaDefaultSize) {
Shawn Willdend0772312014-09-18 12:27:57 -0600257 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA));
258 device.GenerateKey(req_, &rsp_);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600259
Shawn Willdend0772312014-09-18 12:27:57 -0600260 CheckBaseParams(rsp_);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600261
262 // Check specified tags are all present in unenforced characteristics
Shawn Willdend0772312014-09-18 12:27:57 -0600263 EXPECT_TRUE(contains(rsp_.unenforced, TAG_ALGORITHM, KM_ALGORITHM_RSA));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600264
265 // Now check that unspecified, defaulted tags are correct.
Shawn Willdend0772312014-09-18 12:27:57 -0600266 EXPECT_TRUE(contains(rsp_.unenforced, TAG_RSA_PUBLIC_EXPONENT, 65537));
267 EXPECT_TRUE(contains(rsp_.unenforced, TAG_KEY_SIZE, 2048));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600268}
269
Shawn Willdend63e3052015-01-20 11:45:07 -0700270TEST_F(NewKeyGeneration, Dsa) {
271 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_DSA));
272 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, 256));
273 device.GenerateKey(req_, &rsp_);
274
275 CheckBaseParams(rsp_);
276
277 // Check specified tags are all present in unenforced characteristics
278 EXPECT_TRUE(contains(rsp_.unenforced, TAG_ALGORITHM, KM_ALGORITHM_DSA));
279 EXPECT_TRUE(contains(rsp_.unenforced, TAG_KEY_SIZE, 256));
280
281 // Generator should have created DSA params.
282 keymaster_blob_t g, p, q;
283 EXPECT_TRUE(rsp_.unenforced.GetTagValue(TAG_DSA_GENERATOR, &g));
284 EXPECT_TRUE(rsp_.unenforced.GetTagValue(TAG_DSA_P, &p));
285 EXPECT_TRUE(rsp_.unenforced.GetTagValue(TAG_DSA_Q, &q));
286 EXPECT_TRUE(g.data_length >= 63 && g.data_length <= 64);
287 EXPECT_EQ(64U, p.data_length);
288 EXPECT_EQ(20U, q.data_length);
289}
290
291TEST_F(NewKeyGeneration, DsaDefaultSize) {
292 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_DSA));
293 device.GenerateKey(req_, &rsp_);
294
295 CheckBaseParams(rsp_);
296
297 // Check specified tags are all present in unenforced characteristics
298 EXPECT_TRUE(contains(rsp_.unenforced, TAG_ALGORITHM, KM_ALGORITHM_DSA));
299
300 // Now check that unspecified, defaulted tags are correct.
301 EXPECT_TRUE(contains(rsp_.unenforced, TAG_KEY_SIZE, 2048));
302 keymaster_blob_t g, p, q;
303 EXPECT_TRUE(rsp_.unenforced.GetTagValue(TAG_DSA_GENERATOR, &g));
304 EXPECT_TRUE(rsp_.unenforced.GetTagValue(TAG_DSA_P, &p));
305 EXPECT_TRUE(rsp_.unenforced.GetTagValue(TAG_DSA_Q, &q));
306 EXPECT_TRUE(g.data_length >= 255 && g.data_length <= 256);
307 EXPECT_EQ(256U, p.data_length);
308 EXPECT_EQ(32U, q.data_length);
309}
310
311TEST_F(NewKeyGeneration, Dsa_ParamsSpecified) {
312 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_DSA));
313 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, 256));
314 req_.key_description.push_back(Authorization(TAG_DSA_GENERATOR, dsa_g, array_size(dsa_g)));
315 req_.key_description.push_back(Authorization(TAG_DSA_P, dsa_p, array_size(dsa_p)));
316 req_.key_description.push_back(Authorization(TAG_DSA_Q, dsa_q, array_size(dsa_q)));
317 device.GenerateKey(req_, &rsp_);
318
319 CheckBaseParams(rsp_);
320
321 // Check specified tags are all present in unenforced characteristics
322 EXPECT_TRUE(contains(rsp_.unenforced, TAG_ALGORITHM, KM_ALGORITHM_DSA));
323 EXPECT_TRUE(contains(rsp_.unenforced, TAG_KEY_SIZE, 256));
324 EXPECT_TRUE(contains(rsp_.unenforced, TAG_DSA_GENERATOR,
325 std::string(reinterpret_cast<const char*>(dsa_g), array_size(dsa_g))));
326 EXPECT_TRUE(contains(rsp_.unenforced, TAG_DSA_P,
327 std::string(reinterpret_cast<const char*>(dsa_p), array_size(dsa_p))));
328 EXPECT_TRUE(contains(rsp_.unenforced, TAG_DSA_Q,
329 std::string(reinterpret_cast<const char*>(dsa_q), array_size(dsa_q))));
330}
331
332TEST_F(NewKeyGeneration, Dsa_SomeParamsSpecified) {
333 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_DSA));
334 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, 256));
335 req_.key_description.push_back(Authorization(TAG_DSA_P, dsa_p, array_size(dsa_p)));
336 req_.key_description.push_back(Authorization(TAG_DSA_Q, dsa_q, array_size(dsa_q)));
337 device.GenerateKey(req_, &rsp_);
338
339 ASSERT_EQ(KM_ERROR_INVALID_DSA_PARAMS, rsp_.error);
340}
341
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600342TEST_F(NewKeyGeneration, Ecdsa) {
Shawn Willdend0772312014-09-18 12:27:57 -0600343 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
Shawn Willden8c856c82014-09-26 09:34:36 -0600344 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, 224));
Shawn Willdend0772312014-09-18 12:27:57 -0600345 device.GenerateKey(req_, &rsp_);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600346
Shawn Willdend0772312014-09-18 12:27:57 -0600347 CheckBaseParams(rsp_);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600348
349 // Check specified tags are all present in unenforced characteristics
Shawn Willdend0772312014-09-18 12:27:57 -0600350 EXPECT_TRUE(contains(rsp_.unenforced, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
Shawn Willden8c856c82014-09-26 09:34:36 -0600351 EXPECT_TRUE(contains(rsp_.unenforced, TAG_KEY_SIZE, 224));
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600352}
353
Shawn Willden6bbe6782014-09-18 11:26:15 -0600354TEST_F(NewKeyGeneration, EcdsaDefaultSize) {
Shawn Willdend0772312014-09-18 12:27:57 -0600355 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
356 device.GenerateKey(req_, &rsp_);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600357
Shawn Willdend0772312014-09-18 12:27:57 -0600358 CheckBaseParams(rsp_);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600359
360 // Check specified tags are all present in unenforced characteristics
Shawn Willdend0772312014-09-18 12:27:57 -0600361 EXPECT_TRUE(contains(rsp_.unenforced, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600362
363 // Now check that unspecified, defaulted tags are correct.
Shawn Willdend0772312014-09-18 12:27:57 -0600364 EXPECT_TRUE(contains(rsp_.unenforced, TAG_KEY_SIZE, 224));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600365}
366
367TEST_F(NewKeyGeneration, EcdsaInvalidSize) {
Shawn Willdend0772312014-09-18 12:27:57 -0600368 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
369 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, 190));
370 device.GenerateKey(req_, &rsp_);
371 ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE, rsp_.error);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600372}
373
374TEST_F(NewKeyGeneration, EcdsaAllValidSizes) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600375 size_t valid_sizes[] = {224, 256, 384, 521};
Shawn Willden6bbe6782014-09-18 11:26:15 -0600376 for (size_t size : valid_sizes) {
Shawn Willdena03c62b2014-12-03 15:33:39 -0700377 GenerateKeyResponse rsp;
Shawn Willdend0772312014-09-18 12:27:57 -0600378 req_.key_description.Reinitialize(key_generation_base_params,
379 array_length(key_generation_base_params));
380 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
381 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, size));
Shawn Willdena03c62b2014-12-03 15:33:39 -0700382 device.GenerateKey(req_, &rsp);
383 EXPECT_EQ(KM_ERROR_OK, rsp.error) << "Failed to generate size: " << size;
Shawn Willden6bbe6782014-09-18 11:26:15 -0600384 }
385}
386
Shawn Willden76364712014-08-11 17:48:04 -0600387typedef KeymasterTest GetKeyCharacteristics;
388TEST_F(GetKeyCharacteristics, SimpleRsa) {
389 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700390 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
391 Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), Authorization(TAG_KEY_SIZE, 256),
392 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
393 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden76364712014-08-11 17:48:04 -0600394 };
395
396 GenerateKeyRequest gen_req;
397 gen_req.key_description.Reinitialize(params, array_length(params));
398 GenerateKeyResponse gen_rsp;
399
400 device.GenerateKey(gen_req, &gen_rsp);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600401 ASSERT_EQ(KM_ERROR_OK, gen_rsp.error);
Shawn Willden76364712014-08-11 17:48:04 -0600402
403 GetKeyCharacteristicsRequest req;
Shawn Willdenda8485e2014-08-17 08:00:01 -0600404 req.SetKeyMaterial(gen_rsp.key_blob);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600405 req.additional_params.push_back(TAG_APPLICATION_ID, "app_id", 6);
Shawn Willden76364712014-08-11 17:48:04 -0600406
407 GetKeyCharacteristicsResponse rsp;
408 device.GetKeyCharacteristics(req, &rsp);
409 ASSERT_EQ(KM_ERROR_OK, rsp.error);
410
411 EXPECT_EQ(gen_rsp.enforced, rsp.enforced);
412 EXPECT_EQ(gen_rsp.unenforced, rsp.unenforced);
413}
414
Shawn Willden61644f32014-08-18 13:43:14 -0600415/**
416 * Test class that provides some infrastructure for generating keys and signing messages.
417 */
Shawn Willden1615f2e2014-08-13 10:37:40 -0600418class SigningOperationsTest : public KeymasterTest {
419 protected:
Shawn Willden61644f32014-08-18 13:43:14 -0600420 void GenerateKey(keymaster_algorithm_t algorithm, keymaster_digest_t digest,
421 keymaster_padding_t padding, uint32_t key_size) {
Shawn Willden1615f2e2014-08-13 10:37:40 -0600422 keymaster_key_param_t params[] = {
423 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
Shawn Willden3809b932014-12-02 06:59:46 -0700424 Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY), Authorization(TAG_ALGORITHM, algorithm),
425 Authorization(TAG_KEY_SIZE, key_size), Authorization(TAG_USER_ID, 7),
426 Authorization(TAG_USER_AUTH_ID, 8), Authorization(TAG_APPLICATION_ID, "app_id", 6),
Shawn Willden1615f2e2014-08-13 10:37:40 -0600427 Authorization(TAG_AUTH_TIMEOUT, 300),
428 };
429 GenerateKeyRequest generate_request;
430 generate_request.key_description.Reinitialize(params, array_length(params));
Shawn Willden43e999e2014-08-13 13:29:50 -0600431 if (static_cast<int>(digest) != -1)
Shawn Willden1615f2e2014-08-13 10:37:40 -0600432 generate_request.key_description.push_back(TAG_DIGEST, digest);
Shawn Willden43e999e2014-08-13 13:29:50 -0600433 if (static_cast<int>(padding) != -1)
Shawn Willden1615f2e2014-08-13 10:37:40 -0600434 generate_request.key_description.push_back(TAG_PADDING, padding);
435 device.GenerateKey(generate_request, &generate_response_);
436 EXPECT_EQ(KM_ERROR_OK, generate_response_.error);
Shawn Willden61644f32014-08-18 13:43:14 -0600437 }
Shawn Willden1615f2e2014-08-13 10:37:40 -0600438
Shawn Willden61644f32014-08-18 13:43:14 -0600439 void SignMessage(const void* message, size_t size) {
Shawn Willden437fbd12014-08-20 11:59:49 -0600440 SignMessage(generate_response_.key_blob, message, size);
441 }
442
443 void SignMessage(const keymaster_key_blob_t& key_blob, const void* message, size_t size) {
Shawn Willden61644f32014-08-18 13:43:14 -0600444 BeginOperationRequest begin_request;
445 BeginOperationResponse begin_response;
Shawn Willden437fbd12014-08-20 11:59:49 -0600446 begin_request.SetKeyMaterial(key_blob);
Shawn Willden61644f32014-08-18 13:43:14 -0600447 begin_request.purpose = KM_PURPOSE_SIGN;
448 AddClientParams(&begin_request.additional_params);
449
450 device.BeginOperation(begin_request, &begin_response);
451 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
452
453 UpdateOperationRequest update_request;
454 UpdateOperationResponse update_response;
455 update_request.op_handle = begin_response.op_handle;
456 update_request.input.Reinitialize(message, size);
457 EXPECT_EQ(size, update_request.input.available_read());
458
459 device.UpdateOperation(update_request, &update_response);
460 ASSERT_EQ(KM_ERROR_OK, update_response.error);
461 EXPECT_EQ(0U, update_response.output.available_read());
462
463 FinishOperationRequest finish_request;
464 finish_request.op_handle = begin_response.op_handle;
465 device.FinishOperation(finish_request, &finish_response_);
466 ASSERT_EQ(KM_ERROR_OK, finish_response_.error);
467 EXPECT_GT(finish_response_.output.available_read(), 0U);
468 }
469
470 void AddClientParams(AuthorizationSet* set) { set->push_back(TAG_APPLICATION_ID, "app_id", 6); }
471
472 const keymaster_key_blob_t& key_blob() { return generate_response_.key_blob; }
Shawn Willdenf268d742014-08-19 15:36:26 -0600473
474 const keymaster_key_blob_t& corrupt_key_blob() {
Shawn Willden2241bf02014-08-28 09:59:53 -0600475 uint8_t* tmp = const_cast<uint8_t*>(generate_response_.key_blob.key_material);
476 ++tmp[generate_response_.key_blob.key_material_size / 2];
Shawn Willdenf268d742014-08-19 15:36:26 -0600477 return generate_response_.key_blob;
478 }
479
Shawn Willden61644f32014-08-18 13:43:14 -0600480 Buffer* signature() {
481 if (finish_response_.error == KM_ERROR_OK)
482 return &finish_response_.output;
483 return NULL;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600484 }
485
Shawn Willden1615f2e2014-08-13 10:37:40 -0600486 GenerateKeyResponse generate_response_;
Shawn Willden61644f32014-08-18 13:43:14 -0600487 FinishOperationResponse finish_response_;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600488};
489
490TEST_F(SigningOperationsTest, RsaSuccess) {
Shawn Willden61644f32014-08-18 13:43:14 -0600491 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willdenffd790c2014-08-18 21:20:06 -0600492 const char message[] = "12345678901234567890123456789012";
Shawn Willdend05cba52014-09-26 09:58:12 -0600493 SignMessage(message, array_size(message) - 1);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600494}
495
Shawn Willdend63e3052015-01-20 11:45:07 -0700496TEST_F(SigningOperationsTest, DsaSuccess) {
497 GenerateKey(KM_ALGORITHM_DSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
498 const char message[] = "123456789012345678901234567890123456789012345678";
499 SignMessage(message, array_size(message) - 1);
500}
501
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600502TEST_F(SigningOperationsTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600503 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willdend05cba52014-09-26 09:58:12 -0600504 const char message[] = "123456789012345678901234567890123456789012345678";
505 SignMessage(message, array_size(message) - 1);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600506}
507
Shawn Willden1615f2e2014-08-13 10:37:40 -0600508TEST_F(SigningOperationsTest, RsaAbort) {
Shawn Willden61644f32014-08-18 13:43:14 -0600509 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600510
511 BeginOperationRequest begin_request;
512 BeginOperationResponse begin_response;
Shawn Willden61644f32014-08-18 13:43:14 -0600513 begin_request.SetKeyMaterial(key_blob());
Shawn Willden1615f2e2014-08-13 10:37:40 -0600514 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600515 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600516
517 device.BeginOperation(begin_request, &begin_response);
518 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
519
520 EXPECT_EQ(KM_ERROR_OK, device.AbortOperation(begin_response.op_handle));
521
522 // Another abort should fail
523 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
524}
525
526TEST_F(SigningOperationsTest, RsaUnsupportedDigest) {
Shawn Willden61644f32014-08-18 13:43:14 -0600527 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_SHA_2_256, KM_PAD_NONE, 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600528
529 BeginOperationRequest begin_request;
530 BeginOperationResponse begin_response;
531 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600532 begin_request.SetKeyMaterial(key_blob());
533 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600534
535 device.BeginOperation(begin_request, &begin_response);
536 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, begin_response.error);
537
538 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
539}
540
541TEST_F(SigningOperationsTest, RsaUnsupportedPadding) {
Shawn Willden61644f32014-08-18 13:43:14 -0600542 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_RSA_OAEP, 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600543
544 BeginOperationRequest begin_request;
545 BeginOperationResponse begin_response;
546 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600547 begin_request.SetKeyMaterial(key_blob());
548 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600549
550 device.BeginOperation(begin_request, &begin_response);
551 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, begin_response.error);
552
553 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
554}
555
556TEST_F(SigningOperationsTest, RsaNoDigest) {
Shawn Willden61644f32014-08-18 13:43:14 -0600557 GenerateKey(KM_ALGORITHM_RSA, static_cast<keymaster_digest_t>(-1), KM_PAD_NONE,
558 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600559
560 BeginOperationRequest begin_request;
561 BeginOperationResponse begin_response;
562 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600563 begin_request.SetKeyMaterial(key_blob());
564 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600565
566 device.BeginOperation(begin_request, &begin_response);
567 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, begin_response.error);
568
569 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
570}
571
572TEST_F(SigningOperationsTest, RsaNoPadding) {
Shawn Willden61644f32014-08-18 13:43:14 -0600573 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, static_cast<keymaster_padding_t>(-1),
574 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600575
576 BeginOperationRequest begin_request;
577 BeginOperationResponse begin_response;
578 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600579 begin_request.SetKeyMaterial(key_blob());
580 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600581
582 device.BeginOperation(begin_request, &begin_response);
583 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, begin_response.error);
584
585 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
586}
587
588TEST_F(SigningOperationsTest, RsaTooShortMessage) {
Shawn Willden61644f32014-08-18 13:43:14 -0600589 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600590
591 BeginOperationRequest begin_request;
592 BeginOperationResponse begin_response;
Shawn Willden61644f32014-08-18 13:43:14 -0600593 begin_request.SetKeyMaterial(key_blob());
Shawn Willden1615f2e2014-08-13 10:37:40 -0600594 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600595 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600596
597 device.BeginOperation(begin_request, &begin_response);
598 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
599
600 UpdateOperationRequest update_request;
601 UpdateOperationResponse update_response;
602 update_request.op_handle = begin_response.op_handle;
603 update_request.input.Reinitialize("01234567890123456789012345678901", 31);
604 EXPECT_EQ(31U, update_request.input.available_read());
605
606 device.UpdateOperation(update_request, &update_response);
607 ASSERT_EQ(KM_ERROR_OK, update_response.error);
608 EXPECT_EQ(0U, update_response.output.available_read());
609
Shawn Willden43e999e2014-08-13 13:29:50 -0600610 FinishOperationRequest finish_request;
611 finish_request.op_handle = begin_response.op_handle;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600612 FinishOperationResponse finish_response;
Shawn Willden43e999e2014-08-13 13:29:50 -0600613 device.FinishOperation(finish_request, &finish_response);
Shawn Willden00aa7942014-09-10 07:57:43 -0600614 ASSERT_EQ(KM_ERROR_UNKNOWN_ERROR, finish_response.error);
Shawn Willden43e999e2014-08-13 13:29:50 -0600615 EXPECT_EQ(0U, finish_response.output.available_read());
616
617 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
618}
619
Shawn Willdend05cba52014-09-26 09:58:12 -0600620class VerificationOperationsTest : public SigningOperationsTest {
621 protected:
622 void VerifyMessage(const void* message, size_t message_len) {
623 VerifyMessage(generate_response_.key_blob, message, message_len);
624 }
625
626 void VerifyMessage(const keymaster_key_blob_t& key_blob, const void* message,
627 size_t message_len) {
628 ASSERT_TRUE(signature() != NULL);
629
630 BeginOperationRequest begin_request;
631 BeginOperationResponse begin_response;
632 begin_request.SetKeyMaterial(key_blob);
633 begin_request.purpose = KM_PURPOSE_VERIFY;
634 AddClientParams(&begin_request.additional_params);
635
636 device.BeginOperation(begin_request, &begin_response);
637 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
638
639 UpdateOperationRequest update_request;
640 UpdateOperationResponse update_response;
641 update_request.op_handle = begin_response.op_handle;
642 update_request.input.Reinitialize(message, message_len);
643 EXPECT_EQ(message_len, update_request.input.available_read());
644
645 device.UpdateOperation(update_request, &update_response);
646 ASSERT_EQ(KM_ERROR_OK, update_response.error);
647 EXPECT_EQ(0U, update_response.output.available_read());
648
649 FinishOperationRequest finish_request;
650 finish_request.op_handle = begin_response.op_handle;
651 finish_request.signature.Reinitialize(*signature());
652 FinishOperationResponse finish_response;
653 device.FinishOperation(finish_request, &finish_response);
654 ASSERT_EQ(KM_ERROR_OK, finish_response.error);
655 EXPECT_EQ(0U, finish_response.output.available_read());
656
657 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE,
658 device.AbortOperation(begin_response.op_handle));
659 }
660};
661
Shawn Willden43e999e2014-08-13 13:29:50 -0600662TEST_F(VerificationOperationsTest, RsaSuccess) {
Shawn Willden61644f32014-08-18 13:43:14 -0600663 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
664 const char message[] = "12345678901234567890123456789012";
665 SignMessage(message, array_size(message) - 1);
Shawn Willdend05cba52014-09-26 09:58:12 -0600666 VerifyMessage(message, array_size(message) - 1);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600667}
668
Shawn Willdend63e3052015-01-20 11:45:07 -0700669TEST_F(VerificationOperationsTest, DsaSuccess) {
670 GenerateKey(KM_ALGORITHM_DSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
671 const char message[] = "123456789012345678901234567890123456789012345678";
672 SignMessage(message, array_size(message) - 1);
673 VerifyMessage(message, array_size(message) - 1);
674}
675
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600676TEST_F(VerificationOperationsTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600677 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600678 const char message[] = "123456789012345678901234567890123456789012345678";
679 SignMessage(message, array_size(message) - 1);
Shawn Willdend05cba52014-09-26 09:58:12 -0600680 VerifyMessage(message, array_size(message) - 1);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600681}
682
Shawn Willdenffd790c2014-08-18 21:20:06 -0600683typedef SigningOperationsTest ExportKeyTest;
684TEST_F(ExportKeyTest, RsaSuccess) {
685 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willdenffd790c2014-08-18 21:20:06 -0600686
687 ExportKeyRequest request;
688 ExportKeyResponse response;
689 AddClientParams(&request.additional_params);
690 request.key_format = KM_KEY_FORMAT_X509;
691 request.SetKeyMaterial(key_blob());
692
693 device.ExportKey(request, &response);
694 ASSERT_EQ(KM_ERROR_OK, response.error);
695 EXPECT_TRUE(response.key_data != NULL);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600696
697 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willdenffd790c2014-08-18 21:20:06 -0600698}
699
Shawn Willdend63e3052015-01-20 11:45:07 -0700700TEST_F(ExportKeyTest, DsaSuccess) {
701 GenerateKey(KM_ALGORITHM_DSA, KM_DIGEST_NONE, KM_PAD_NONE, 1024 /* key size */);
702
703 ExportKeyRequest request;
704 ExportKeyResponse response;
705 AddClientParams(&request.additional_params);
706 request.key_format = KM_KEY_FORMAT_X509;
707 request.SetKeyMaterial(key_blob());
708
709 device.ExportKey(request, &response);
710 ASSERT_EQ(KM_ERROR_OK, response.error);
711 EXPECT_TRUE(response.key_data != NULL);
712
713 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
714}
715
Shawn Willdenf268d742014-08-19 15:36:26 -0600716TEST_F(ExportKeyTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600717 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willdenf268d742014-08-19 15:36:26 -0600718
719 ExportKeyRequest request;
720 ExportKeyResponse response;
721 AddClientParams(&request.additional_params);
722 request.key_format = KM_KEY_FORMAT_X509;
723 request.SetKeyMaterial(key_blob());
724
725 device.ExportKey(request, &response);
726 ASSERT_EQ(KM_ERROR_OK, response.error);
727 EXPECT_TRUE(response.key_data != NULL);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600728
729 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willdenf268d742014-08-19 15:36:26 -0600730}
731
732TEST_F(ExportKeyTest, RsaUnsupportedKeyFormat) {
733 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256);
734
735 ExportKeyRequest request;
736 ExportKeyResponse response;
737 AddClientParams(&request.additional_params);
738
739 /* We have no other defined export formats defined. */
740 request.key_format = KM_KEY_FORMAT_PKCS8;
741 request.SetKeyMaterial(key_blob());
742
743 device.ExportKey(request, &response);
744 ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_FORMAT, response.error);
745 EXPECT_TRUE(response.key_data == NULL);
746}
747
748TEST_F(ExportKeyTest, RsaCorruptedKeyBlob) {
749 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256);
750
751 ExportKeyRequest request;
752 ExportKeyResponse response;
753 AddClientParams(&request.additional_params);
754 request.key_format = KM_KEY_FORMAT_X509;
755 request.SetKeyMaterial(corrupt_key_blob());
756
757 device.ExportKey(request, &response);
758 ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, response.error);
759 ASSERT_TRUE(response.key_data == NULL);
760}
761
Shawn Willden437fbd12014-08-20 11:59:49 -0600762static string read_file(const string& file_name) {
763 ifstream file_stream(file_name, std::ios::binary);
764 istreambuf_iterator<char> file_begin(file_stream);
765 istreambuf_iterator<char> file_end;
766 return string(file_begin, file_end);
767}
768
Shawn Willdend05cba52014-09-26 09:58:12 -0600769typedef VerificationOperationsTest ImportKeyTest;
Shawn Willden437fbd12014-08-20 11:59:49 -0600770TEST_F(ImportKeyTest, RsaSuccess) {
771 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700772 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
773 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
774 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
775 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden437fbd12014-08-20 11:59:49 -0600776 };
777
Shawn Willden81effc62014-08-27 10:08:46 -0600778 string pk8_key = read_file("rsa_privkey_pk8.der");
Shawn Willden437fbd12014-08-20 11:59:49 -0600779 ASSERT_EQ(633U, pk8_key.size());
780
781 ImportKeyRequest import_request;
782 import_request.key_description.Reinitialize(params, array_length(params));
783 import_request.key_format = KM_KEY_FORMAT_PKCS8;
784 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
785
786 ImportKeyResponse import_response;
787 device.ImportKey(import_request, &import_response);
788 ASSERT_EQ(KM_ERROR_OK, import_response.error);
789 EXPECT_EQ(0U, import_response.enforced.size());
790 EXPECT_GT(import_response.unenforced.size(), 0U);
791
792 // Check values derived from the key.
793 EXPECT_TRUE(contains(import_response.unenforced, TAG_ALGORITHM, KM_ALGORITHM_RSA));
794 EXPECT_TRUE(contains(import_response.unenforced, TAG_KEY_SIZE, 1024));
795 EXPECT_TRUE(contains(import_response.unenforced, TAG_RSA_PUBLIC_EXPONENT, 65537U));
796
797 // And values provided by GoogleKeymaster
798 EXPECT_TRUE(contains(import_response.unenforced, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
799 EXPECT_TRUE(contains(import_response.unenforced, KM_TAG_CREATION_DATETIME));
800
801 size_t message_len = 1024 / 8;
802 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
803 std::fill(message.get(), message.get() + message_len, 'a');
804 SignMessage(import_response.key_blob, message.get(), message_len);
805 ASSERT_TRUE(signature() != NULL);
Shawn Willdend05cba52014-09-26 09:58:12 -0600806 VerifyMessage(import_response.key_blob, message.get(), message_len);
Shawn Willden437fbd12014-08-20 11:59:49 -0600807}
808
Shawn Willden6bbe6782014-09-18 11:26:15 -0600809TEST_F(ImportKeyTest, RsaKeySizeMismatch) {
810 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700811 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
812 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
Shawn Willden6bbe6782014-09-18 11:26:15 -0600813 Authorization(TAG_KEY_SIZE, 2048), // Doesn't match key
Shawn Willden3809b932014-12-02 06:59:46 -0700814 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
815 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden6bbe6782014-09-18 11:26:15 -0600816 };
817
818 string pk8_key = read_file("rsa_privkey_pk8.der");
819 ASSERT_EQ(633U, pk8_key.size());
820
821 ImportKeyRequest import_request;
822 import_request.key_description.Reinitialize(params, array_length(params));
823 import_request.key_format = KM_KEY_FORMAT_PKCS8;
824 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
825
826 ImportKeyResponse import_response;
827 device.ImportKey(import_request, &import_response);
828 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH, import_response.error);
829}
830
831TEST_F(ImportKeyTest, RsaPublicExponenMismatch) {
832 keymaster_key_param_t params[] = {
833 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
Shawn Willden3809b932014-12-02 06:59:46 -0700834 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
835 Authorization(TAG_RSA_PUBLIC_EXPONENT, 3), Authorization(TAG_USER_ID, 7),
836 Authorization(TAG_USER_AUTH_ID, 8), Authorization(TAG_APPLICATION_ID, "app_id", 6),
Shawn Willden6bbe6782014-09-18 11:26:15 -0600837 Authorization(TAG_AUTH_TIMEOUT, 300),
838 };
839
840 string pk8_key = read_file("rsa_privkey_pk8.der");
841 ASSERT_EQ(633U, pk8_key.size());
842
843 ImportKeyRequest import_request;
844 import_request.key_description.Reinitialize(params, array_length(params));
845 import_request.key_format = KM_KEY_FORMAT_PKCS8;
846 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
847
848 ImportKeyResponse import_response;
849 device.ImportKey(import_request, &import_response);
850 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH, import_response.error);
851}
852
Shawn Willdend63e3052015-01-20 11:45:07 -0700853TEST_F(ImportKeyTest, DsaSuccess) {
854 keymaster_key_param_t params[] = {
855 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
856 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
857 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
858 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
859 };
860
861 string pk8_key = read_file("dsa_privkey_pk8.der");
862 ASSERT_EQ(335U, pk8_key.size());
863
864 ImportKeyRequest import_request;
865 import_request.key_description.Reinitialize(params, array_length(params));
866 import_request.key_format = KM_KEY_FORMAT_PKCS8;
867 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
868
869 ImportKeyResponse import_response;
870 device.ImportKey(import_request, &import_response);
871 ASSERT_EQ(KM_ERROR_OK, import_response.error);
872 EXPECT_EQ(0U, import_response.enforced.size());
873 EXPECT_GT(import_response.unenforced.size(), 0U);
874
875 // Check values derived from the key.
876 EXPECT_TRUE(contains(import_response.unenforced, TAG_ALGORITHM, KM_ALGORITHM_DSA));
877 EXPECT_TRUE(contains(import_response.unenforced, TAG_KEY_SIZE, 1024));
878
879 // And values provided by GoogleKeymaster
880 EXPECT_TRUE(contains(import_response.unenforced, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
881 EXPECT_TRUE(contains(import_response.unenforced, KM_TAG_CREATION_DATETIME));
882
883 size_t message_len = 48;
884 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
885 std::fill(message.get(), message.get() + message_len, 'a');
886 SignMessage(import_response.key_blob, message.get(), message_len);
887 ASSERT_TRUE(signature() != NULL);
888 VerifyMessage(import_response.key_blob, message.get(), message_len);
889}
890
891TEST_F(ImportKeyTest, DsaParametersMatch) {
892 keymaster_key_param_t params[] = {
893 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
894 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
895 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
896 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
897 Authorization(TAG_KEY_SIZE, 1024),
898 Authorization(TAG_DSA_GENERATOR, dsa_g, array_size(dsa_g)),
899 Authorization(TAG_DSA_P, dsa_p, array_size(dsa_p)),
900 Authorization(TAG_DSA_Q, dsa_q, array_size(dsa_q)),
901 };
902
903 string pk8_key = read_file("dsa_privkey_pk8.der");
904 ASSERT_EQ(335U, pk8_key.size());
905
906 ImportKeyRequest import_request;
907 import_request.key_description.Reinitialize(params, array_length(params));
908 import_request.key_format = KM_KEY_FORMAT_PKCS8;
909 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
910
911 ImportKeyResponse import_response;
912 device.ImportKey(import_request, &import_response);
913 ASSERT_EQ(KM_ERROR_OK, import_response.error);
914 EXPECT_EQ(0U, import_response.enforced.size());
915 EXPECT_GT(import_response.unenforced.size(), 0U);
916
917 // Check values derived from the key.
918 EXPECT_TRUE(contains(import_response.unenforced, TAG_ALGORITHM, KM_ALGORITHM_DSA));
919 EXPECT_TRUE(contains(import_response.unenforced, TAG_KEY_SIZE, 1024));
920
921 // And values provided by GoogleKeymaster
922 EXPECT_TRUE(contains(import_response.unenforced, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
923 EXPECT_TRUE(contains(import_response.unenforced, KM_TAG_CREATION_DATETIME));
924
925 size_t message_len = 48;
926 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
927 std::fill(message.get(), message.get() + message_len, 'a');
928 SignMessage(import_response.key_blob, message.get(), message_len);
929 ASSERT_TRUE(signature() != NULL);
930 VerifyMessage(import_response.key_blob, message.get(), message_len);
931}
932
933uint8_t dsa_wrong_q[] = {
934 0xC0, 0x66, 0x64, 0xF9, 0x05, 0x38, 0x64, 0x38, 0x4A, 0x17,
935 0x66, 0x79, 0xDD, 0x7F, 0x6E, 0x55, 0x22, 0x2A, 0xDF, 0xC5,
936};
937
938TEST_F(ImportKeyTest, DsaParameterMismatch) {
939 keymaster_key_param_t params[] = {
940 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
941 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
942 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
943 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
944 Authorization(TAG_KEY_SIZE, 1024),
945 Authorization(TAG_DSA_Q, dsa_wrong_q, array_size(dsa_wrong_q)),
946 };
947
948 string pk8_key = read_file("dsa_privkey_pk8.der");
949 ASSERT_EQ(335U, pk8_key.size());
950
951 ImportKeyRequest import_request;
952 import_request.key_description.Reinitialize(params, array_length(params));
953 import_request.key_format = KM_KEY_FORMAT_PKCS8;
954 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
955
956 ImportKeyResponse import_response;
957 device.ImportKey(import_request, &import_response);
958 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH, import_response.error);
959}
960
961TEST_F(ImportKeyTest, DsaKeySizeMismatch) {
962 keymaster_key_param_t params[] = {
963 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
964 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
965 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
966 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
967 Authorization(TAG_KEY_SIZE, 2048),
968 };
969
970 string pk8_key = read_file("dsa_privkey_pk8.der");
971 ASSERT_EQ(335U, pk8_key.size());
972
973 ImportKeyRequest import_request;
974 import_request.key_description.Reinitialize(params, array_length(params));
975 import_request.key_format = KM_KEY_FORMAT_PKCS8;
976 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
977
978 ImportKeyResponse import_response;
979 device.ImportKey(import_request, &import_response);
980 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH, import_response.error);
981}
982
Shawn Willden81effc62014-08-27 10:08:46 -0600983TEST_F(ImportKeyTest, EcdsaSuccess) {
984 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700985 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
986 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
987 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
988 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden81effc62014-08-27 10:08:46 -0600989 };
990
991 string pk8_key = read_file("ec_privkey_pk8.der");
992 ASSERT_EQ(138U, pk8_key.size());
993
994 ImportKeyRequest import_request;
995 import_request.key_description.Reinitialize(params, array_length(params));
996 import_request.key_format = KM_KEY_FORMAT_PKCS8;
997 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
998
999 ImportKeyResponse import_response;
1000 device.ImportKey(import_request, &import_response);
1001 ASSERT_EQ(KM_ERROR_OK, import_response.error);
1002 EXPECT_EQ(0U, import_response.enforced.size());
1003 EXPECT_GT(import_response.unenforced.size(), 0U);
1004
1005 // Check values derived from the key.
1006 EXPECT_TRUE(contains(import_response.unenforced, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
1007 EXPECT_TRUE(contains(import_response.unenforced, TAG_KEY_SIZE, 256));
1008
1009 // And values provided by GoogleKeymaster
1010 EXPECT_TRUE(contains(import_response.unenforced, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
1011 EXPECT_TRUE(contains(import_response.unenforced, KM_TAG_CREATION_DATETIME));
1012
1013 size_t message_len = 1024 / 8;
1014 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
1015 std::fill(message.get(), message.get() + message_len, 'a');
1016 SignMessage(import_response.key_blob, message.get(), message_len);
1017 ASSERT_TRUE(signature() != NULL);
Shawn Willdend05cba52014-09-26 09:58:12 -06001018 VerifyMessage(import_response.key_blob, message.get(), message_len);
Shawn Willden81effc62014-08-27 10:08:46 -06001019}
1020
Shawn Willden6bbe6782014-09-18 11:26:15 -06001021TEST_F(ImportKeyTest, EcdsaSizeSpecified) {
1022 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -07001023 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
1024 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
1025 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
1026 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden6bbe6782014-09-18 11:26:15 -06001027 Authorization(TAG_KEY_SIZE, 256),
1028 };
1029
1030 string pk8_key = read_file("ec_privkey_pk8.der");
1031 ASSERT_EQ(138U, pk8_key.size());
1032
1033 ImportKeyRequest import_request;
1034 import_request.key_description.Reinitialize(params, array_length(params));
1035 import_request.key_format = KM_KEY_FORMAT_PKCS8;
1036 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
1037
1038 ImportKeyResponse import_response;
1039 device.ImportKey(import_request, &import_response);
1040 ASSERT_EQ(KM_ERROR_OK, import_response.error);
1041 EXPECT_EQ(0U, import_response.enforced.size());
1042 EXPECT_GT(import_response.unenforced.size(), 0U);
1043
1044 // Check values derived from the key.
1045 EXPECT_TRUE(contains(import_response.unenforced, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
1046 EXPECT_TRUE(contains(import_response.unenforced, TAG_KEY_SIZE, 256));
1047
1048 // And values provided by GoogleKeymaster
1049 EXPECT_TRUE(contains(import_response.unenforced, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
1050 EXPECT_TRUE(contains(import_response.unenforced, KM_TAG_CREATION_DATETIME));
1051
1052 size_t message_len = 1024 / 8;
1053 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
1054 std::fill(message.get(), message.get() + message_len, 'a');
1055 SignMessage(import_response.key_blob, message.get(), message_len);
1056 ASSERT_TRUE(signature() != NULL);
Shawn Willdend05cba52014-09-26 09:58:12 -06001057 VerifyMessage(import_response.key_blob, message.get(), message_len);
Shawn Willden6bbe6782014-09-18 11:26:15 -06001058}
1059
1060TEST_F(ImportKeyTest, EcdsaSizeMismatch) {
1061 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -07001062 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
1063 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
1064 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
1065 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden8c856c82014-09-26 09:34:36 -06001066 Authorization(TAG_KEY_SIZE, 224),
Shawn Willden6bbe6782014-09-18 11:26:15 -06001067 };
1068
1069 string pk8_key = read_file("ec_privkey_pk8.der");
1070 ASSERT_EQ(138U, pk8_key.size());
1071
1072 ImportKeyRequest import_request;
1073 import_request.key_description.Reinitialize(params, array_length(params));
1074 import_request.key_format = KM_KEY_FORMAT_PKCS8;
1075 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
1076
1077 ImportKeyResponse import_response;
1078 device.ImportKey(import_request, &import_response);
1079 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH, import_response.error);
1080}
1081
Shawn Willden46a420d2014-12-02 07:01:21 -07001082/**
1083 * Test class that provides some infrastructure for generating keys and encrypting messages.
1084 */
1085class EncryptionOperationsTest : public KeymasterTest {
1086 protected:
1087 void GenerateKey(keymaster_algorithm_t algorithm, keymaster_padding_t padding,
1088 uint32_t key_size) {
1089 keymaster_key_param_t params[] = {
1090 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
1091 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT), Authorization(TAG_ALGORITHM, algorithm),
1092 Authorization(TAG_KEY_SIZE, key_size), Authorization(TAG_USER_ID, 7),
1093 Authorization(TAG_USER_AUTH_ID, 8), Authorization(TAG_APPLICATION_ID, "app_id", 6),
1094 Authorization(TAG_AUTH_TIMEOUT, 300),
1095 };
1096 GenerateKeyRequest generate_request;
1097 generate_request.key_description.Reinitialize(params, array_length(params));
1098 if (static_cast<int>(padding) != -1)
1099 generate_request.key_description.push_back(TAG_PADDING, padding);
1100 device.GenerateKey(generate_request, &generate_response_);
1101 EXPECT_EQ(KM_ERROR_OK, generate_response_.error);
1102 }
1103
1104 keymaster_error_t BeginOperation(keymaster_purpose_t purpose,
1105 const keymaster_key_blob_t& key_blob, uint64_t* op_handle) {
1106 BeginOperationRequest begin_request;
1107 begin_request.SetKeyMaterial(key_blob);
1108 begin_request.purpose = purpose;
1109 AddClientParams(&begin_request.additional_params);
1110
1111 BeginOperationResponse begin_response;
1112 device.BeginOperation(begin_request, &begin_response);
1113 *op_handle = begin_response.op_handle;
1114 return begin_response.error;
1115 }
1116
1117 keymaster_error_t UpdateOperation(uint64_t op_handle, const void* message, size_t size,
Shawn Willden5da34d22015-01-20 11:44:47 -07001118 string* output) {
Shawn Willden46a420d2014-12-02 07:01:21 -07001119 UpdateOperationRequest update_request;
1120 update_request.op_handle = op_handle;
1121 update_request.input.Reinitialize(message, size);
1122
1123 UpdateOperationResponse update_response;
1124 device.UpdateOperation(update_request, &update_response);
1125 if (update_response.error == KM_ERROR_OK)
1126 output->append(reinterpret_cast<const char*>(update_response.output.peek_read()),
1127 update_response.output.available_read());
1128 return update_response.error;
1129 }
1130
1131 keymaster_error_t FinishOperation(uint64_t op_handle, string* output) {
1132 FinishOperationRequest finish_request;
1133 finish_request.op_handle = op_handle;
1134 FinishOperationResponse finish_response;
1135 device.FinishOperation(finish_request, &finish_response);
1136 if (finish_response.error == KM_ERROR_OK)
1137 output->append(reinterpret_cast<const char*>(finish_response.output.peek_read()),
1138 finish_response.output.available_read());
1139 return finish_response.error;
1140 }
1141
1142 string ProcessMessage(keymaster_purpose_t purpose, const keymaster_key_blob_t& key_blob,
1143 const void* message, size_t size) {
1144 uint64_t op_handle;
1145 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose, key_blob, &op_handle));
1146
1147 string result;
Shawn Willden5da34d22015-01-20 11:44:47 -07001148 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, message, size, &result));
Shawn Willden46a420d2014-12-02 07:01:21 -07001149 EXPECT_EQ(KM_ERROR_OK, FinishOperation(op_handle, &result));
1150 return result;
1151 }
1152
1153 string EncryptMessage(const void* message, size_t size) {
1154 return ProcessMessage(KM_PURPOSE_ENCRYPT, generate_response_.key_blob, message, size);
1155 }
1156
1157 string DecryptMessage(const void* ciphertext, size_t size) {
1158 return ProcessMessage(KM_PURPOSE_DECRYPT, generate_response_.key_blob, ciphertext, size);
1159 }
1160
1161 void AddClientParams(AuthorizationSet* set) { set->push_back(TAG_APPLICATION_ID, "app_id", 6); }
1162
1163 const keymaster_key_blob_t& key_blob() { return generate_response_.key_blob; }
1164
1165 const keymaster_key_blob_t& corrupt_key_blob() {
1166 uint8_t* tmp = const_cast<uint8_t*>(generate_response_.key_blob.key_material);
1167 ++tmp[generate_response_.key_blob.key_material_size / 2];
1168 return generate_response_.key_blob;
1169 }
1170
1171 protected:
1172 GenerateKeyResponse generate_response_;
1173};
1174
1175TEST_F(EncryptionOperationsTest, RsaOaepSuccess) {
1176 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1177 const char message[] = "Hello World!";
1178 string ciphertext1 = EncryptMessage(message, strlen(message));
1179 EXPECT_EQ(512 / 8, ciphertext1.size());
1180
1181 string ciphertext2 = EncryptMessage(message, strlen(message));
1182 EXPECT_EQ(512 / 8, ciphertext2.size());
1183
1184 // OAEP randomizes padding so every result should be different.
1185 EXPECT_NE(ciphertext1, ciphertext2);
1186}
1187
1188TEST_F(EncryptionOperationsTest, RsaOaepRoundTrip) {
1189 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1190 const char message[] = "Hello World!";
1191 string ciphertext = EncryptMessage(message, strlen(message));
1192 EXPECT_EQ(512 / 8, ciphertext.size());
1193
1194 string plaintext = DecryptMessage(ciphertext.data(), ciphertext.size());
1195 EXPECT_EQ(message, plaintext);
1196}
1197
1198TEST_F(EncryptionOperationsTest, RsaOaepTooLarge) {
1199 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1200 const char message[] = "12345678901234567890123";
1201 uint64_t op_handle;
1202 string result;
1203
1204 EXPECT_EQ(KM_ERROR_OK,
1205 BeginOperation(KM_PURPOSE_ENCRYPT, generate_response_.key_blob, &op_handle));
Shawn Willden5da34d22015-01-20 11:44:47 -07001206 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, message, array_size(message), &result));
Shawn Willden46a420d2014-12-02 07:01:21 -07001207 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(op_handle, &result));
1208 EXPECT_EQ(0, result.size());
1209}
1210
1211TEST_F(EncryptionOperationsTest, RsaOaepCorruptedDecrypt) {
1212 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1213 const char message[] = "Hello World!";
1214 string ciphertext = EncryptMessage(message, strlen(message));
1215 EXPECT_EQ(512 / 8, ciphertext.size());
1216
1217 // Corrupt the ciphertext
1218 ciphertext[512 / 8 / 2]++;
1219
1220 uint64_t op_handle;
1221 string result;
1222 EXPECT_EQ(KM_ERROR_OK,
1223 BeginOperation(KM_PURPOSE_DECRYPT, generate_response_.key_blob, &op_handle));
Shawn Willden5da34d22015-01-20 11:44:47 -07001224 EXPECT_EQ(KM_ERROR_OK,
1225 UpdateOperation(op_handle, ciphertext.data(), ciphertext.size(), &result));
Shawn Willden46a420d2014-12-02 07:01:21 -07001226 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(op_handle, &result));
1227 EXPECT_EQ(0, result.size());
1228}
1229
1230TEST_F(EncryptionOperationsTest, RsaPkcs1Success) {
1231 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1232 const char message[] = "Hello World!";
1233 string ciphertext1 = EncryptMessage(message, strlen(message));
1234 EXPECT_EQ(512 / 8, ciphertext1.size());
1235
1236 string ciphertext2 = EncryptMessage(message, strlen(message));
1237 EXPECT_EQ(512 / 8, ciphertext2.size());
1238
1239 // PKCS1 v1.5 randomizes padding so every result should be different.
1240 EXPECT_NE(ciphertext1, ciphertext2);
1241}
1242
1243TEST_F(EncryptionOperationsTest, RsaPkcs1RoundTrip) {
1244 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1245 const char message[] = "Hello World!";
1246 string ciphertext = EncryptMessage(message, strlen(message));
1247 EXPECT_EQ(512 / 8, ciphertext.size());
1248
1249 string plaintext = DecryptMessage(ciphertext.data(), ciphertext.size());
1250 EXPECT_EQ(message, plaintext);
1251}
1252
1253TEST_F(EncryptionOperationsTest, RsaPkcs1TooLarge) {
1254 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1255 const char message[] = "1234567890123456789012345678901234567890123456789012";
1256 uint64_t op_handle;
1257 string result;
1258
1259 EXPECT_EQ(KM_ERROR_OK,
1260 BeginOperation(KM_PURPOSE_ENCRYPT, generate_response_.key_blob, &op_handle));
Shawn Willden5da34d22015-01-20 11:44:47 -07001261 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, message, array_size(message), &result));
Shawn Willden46a420d2014-12-02 07:01:21 -07001262 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(op_handle, &result));
1263 EXPECT_EQ(0, result.size());
1264}
1265
1266TEST_F(EncryptionOperationsTest, RsaPkcs1CorruptedDecrypt) {
1267 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1268 const char message[] = "Hello World!";
1269 string ciphertext = EncryptMessage(message, strlen(message));
1270 EXPECT_EQ(512 / 8, ciphertext.size());
1271
1272 // Corrupt the ciphertext
1273 ciphertext[512 / 8 / 2]++;
1274
1275 uint64_t op_handle;
1276 string result;
1277 EXPECT_EQ(KM_ERROR_OK,
1278 BeginOperation(KM_PURPOSE_DECRYPT, generate_response_.key_blob, &op_handle));
Shawn Willden5da34d22015-01-20 11:44:47 -07001279 EXPECT_EQ(KM_ERROR_OK,
1280 UpdateOperation(op_handle, ciphertext.data(), ciphertext.size(), &result));
Shawn Willden46a420d2014-12-02 07:01:21 -07001281 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(op_handle, &result));
1282 EXPECT_EQ(0, result.size());
1283}
1284
Shawn Willden128ffe02014-08-06 12:31:33 -06001285} // namespace test
1286} // namespace keymaster