blob: 199b523beec901263027c2083c5796906fa80567 [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));
Shawn Willdend0772312014-09-18 12:27:57 -0600232
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 Willdenc3864dd2014-08-18 15:20:01 -0600270TEST_F(NewKeyGeneration, Ecdsa) {
Shawn Willdend0772312014-09-18 12:27:57 -0600271 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
Shawn Willden8c856c82014-09-26 09:34:36 -0600272 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, 224));
Shawn Willdend0772312014-09-18 12:27:57 -0600273 device.GenerateKey(req_, &rsp_);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600274
Shawn Willdend0772312014-09-18 12:27:57 -0600275 CheckBaseParams(rsp_);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600276
277 // Check specified tags are all present in unenforced characteristics
Shawn Willdend0772312014-09-18 12:27:57 -0600278 EXPECT_TRUE(contains(rsp_.unenforced, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
Shawn Willden8c856c82014-09-26 09:34:36 -0600279 EXPECT_TRUE(contains(rsp_.unenforced, TAG_KEY_SIZE, 224));
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600280}
281
Shawn Willden6bbe6782014-09-18 11:26:15 -0600282TEST_F(NewKeyGeneration, EcdsaDefaultSize) {
Shawn Willdend0772312014-09-18 12:27:57 -0600283 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
284 device.GenerateKey(req_, &rsp_);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600285
Shawn Willdend0772312014-09-18 12:27:57 -0600286 CheckBaseParams(rsp_);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600287
288 // Check specified tags are all present in unenforced characteristics
Shawn Willdend0772312014-09-18 12:27:57 -0600289 EXPECT_TRUE(contains(rsp_.unenforced, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600290
291 // Now check that unspecified, defaulted tags are correct.
Shawn Willdend0772312014-09-18 12:27:57 -0600292 EXPECT_TRUE(contains(rsp_.unenforced, TAG_KEY_SIZE, 224));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600293}
294
295TEST_F(NewKeyGeneration, EcdsaInvalidSize) {
Shawn Willdend0772312014-09-18 12:27:57 -0600296 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
297 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, 190));
298 device.GenerateKey(req_, &rsp_);
299 ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE, rsp_.error);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600300}
301
302TEST_F(NewKeyGeneration, EcdsaAllValidSizes) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600303 size_t valid_sizes[] = {224, 256, 384, 521};
Shawn Willden6bbe6782014-09-18 11:26:15 -0600304 for (size_t size : valid_sizes) {
Shawn Willden0302c552014-12-03 15:33:39 -0700305 GenerateKeyResponse rsp;
Shawn Willdend0772312014-09-18 12:27:57 -0600306 req_.key_description.Reinitialize(key_generation_base_params,
307 array_length(key_generation_base_params));
308 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
309 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, size));
Shawn Willden0302c552014-12-03 15:33:39 -0700310 device.GenerateKey(req_, &rsp);
311 EXPECT_EQ(KM_ERROR_OK, rsp.error) << "Failed to generate size: " << size;
Shawn Willden6bbe6782014-09-18 11:26:15 -0600312 }
313}
314
Shawn Willden19fca882015-01-22 16:35:30 -0700315TEST_F(NewKeyGeneration, AesOcb) {
316 keymaster_key_param_t params[] = {
317 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
318 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
319 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
320 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_CHUNK_LENGTH, 4096),
Shawn Willden7efb8782014-12-11 14:07:44 -0700321 Authorization(TAG_MAC_LENGTH, 16), Authorization(TAG_PADDING, KM_PAD_NONE),
Shawn Willden19fca882015-01-22 16:35:30 -0700322 };
323 req_.key_description.Reinitialize(params, array_length(params));
324 device.GenerateKey(req_, &rsp_);
325 EXPECT_EQ(KM_ERROR_OK, rsp_.error);
326}
327
328TEST_F(NewKeyGeneration, AesOcbInvalidKeySize) {
329 keymaster_key_param_t params[] = {
330 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
331 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
332 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 129),
333 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_CHUNK_LENGTH, 4096),
Shawn Willden7efb8782014-12-11 14:07:44 -0700334 Authorization(TAG_MAC_LENGTH, 16), Authorization(TAG_PADDING, KM_PAD_NONE),
Shawn Willden19fca882015-01-22 16:35:30 -0700335 };
336 req_.key_description.Reinitialize(params, array_length(params));
337 device.GenerateKey(req_, &rsp_);
338 EXPECT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE, rsp_.error);
339}
340
341TEST_F(NewKeyGeneration, AesOcbAllValidSizes) {
342 keymaster_key_param_t params[] = {
343 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
344 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
Shawn Willden7efb8782014-12-11 14:07:44 -0700345 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_BLOCK_MODE, KM_MODE_OCB),
346 Authorization(TAG_MAC_LENGTH, 16), Authorization(TAG_CHUNK_LENGTH, 4096),
Shawn Willden19fca882015-01-22 16:35:30 -0700347 Authorization(TAG_PADDING, KM_PAD_NONE),
348 };
349
350 size_t valid_sizes[] = {128, 192, 256};
351 for (size_t size : valid_sizes) {
352 GenerateKeyResponse rsp;
353 req_.key_description.Reinitialize(params, array_length(params));
354 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, size));
355 device.GenerateKey(req_, &rsp);
356 EXPECT_EQ(KM_ERROR_OK, rsp.error) << "Failed to generate size: " << size;
357 }
358}
359
360TEST_F(NewKeyGeneration, AesOcbNoChunkLength) {
361 keymaster_key_param_t params[] = {
362 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
363 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
364 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
365 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_PADDING, KM_PAD_NONE),
366 };
367 req_.key_description.Reinitialize(params, array_length(params));
368 device.GenerateKey(req_, &rsp_);
Shawn Willden7efb8782014-12-11 14:07:44 -0700369 EXPECT_EQ(KM_ERROR_INVALID_ARGUMENT, rsp_.error);
Shawn Willden19fca882015-01-22 16:35:30 -0700370}
371
372TEST_F(NewKeyGeneration, AesEcbUnsupported) {
373 keymaster_key_param_t params[] = {
374 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
375 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
376 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
377 Authorization(TAG_BLOCK_MODE, KM_MODE_ECB), Authorization(TAG_PADDING, KM_PAD_NONE),
378 };
379 req_.key_description.Reinitialize(params, array_length(params));
380 device.GenerateKey(req_, &rsp_);
381 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE, rsp_.error);
382}
383
384TEST_F(NewKeyGeneration, AesOcbPaddingUnsupported) {
385 keymaster_key_param_t params[] = {
386 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
387 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
388 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
389 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_CHUNK_LENGTH, 4096),
390 Authorization(TAG_PADDING, KM_PAD_ZERO),
391 };
392 req_.key_description.Reinitialize(params, array_length(params));
393 device.GenerateKey(req_, &rsp_);
394 EXPECT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, rsp_.error);
395}
396
Shawn Willden7efb8782014-12-11 14:07:44 -0700397TEST_F(NewKeyGeneration, AesOcbInvalidMacLength) {
398 keymaster_key_param_t params[] = {
399 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
400 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
401 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
402 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_CHUNK_LENGTH, 4096),
403 Authorization(TAG_MAC_LENGTH, 17), Authorization(TAG_PADDING, KM_PAD_NONE),
404 };
405 req_.key_description.Reinitialize(params, array_length(params));
406 device.GenerateKey(req_, &rsp_);
407 EXPECT_EQ(KM_ERROR_INVALID_ARGUMENT, rsp_.error);
408}
409
Shawn Willden76364712014-08-11 17:48:04 -0600410typedef KeymasterTest GetKeyCharacteristics;
411TEST_F(GetKeyCharacteristics, SimpleRsa) {
412 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700413 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
414 Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), Authorization(TAG_KEY_SIZE, 256),
415 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
416 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden76364712014-08-11 17:48:04 -0600417 };
418
419 GenerateKeyRequest gen_req;
420 gen_req.key_description.Reinitialize(params, array_length(params));
421 GenerateKeyResponse gen_rsp;
422
423 device.GenerateKey(gen_req, &gen_rsp);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600424 ASSERT_EQ(KM_ERROR_OK, gen_rsp.error);
Shawn Willden76364712014-08-11 17:48:04 -0600425
426 GetKeyCharacteristicsRequest req;
Shawn Willdenda8485e2014-08-17 08:00:01 -0600427 req.SetKeyMaterial(gen_rsp.key_blob);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600428 req.additional_params.push_back(TAG_APPLICATION_ID, "app_id", 6);
Shawn Willden76364712014-08-11 17:48:04 -0600429
430 GetKeyCharacteristicsResponse rsp;
431 device.GetKeyCharacteristics(req, &rsp);
432 ASSERT_EQ(KM_ERROR_OK, rsp.error);
433
434 EXPECT_EQ(gen_rsp.enforced, rsp.enforced);
435 EXPECT_EQ(gen_rsp.unenforced, rsp.unenforced);
436}
437
Shawn Willden61644f32014-08-18 13:43:14 -0600438/**
439 * Test class that provides some infrastructure for generating keys and signing messages.
440 */
Shawn Willden1615f2e2014-08-13 10:37:40 -0600441class SigningOperationsTest : public KeymasterTest {
442 protected:
Shawn Willden61644f32014-08-18 13:43:14 -0600443 void GenerateKey(keymaster_algorithm_t algorithm, keymaster_digest_t digest,
444 keymaster_padding_t padding, uint32_t key_size) {
Shawn Willden1615f2e2014-08-13 10:37:40 -0600445 keymaster_key_param_t params[] = {
446 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
Shawn Willden3809b932014-12-02 06:59:46 -0700447 Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY), Authorization(TAG_ALGORITHM, algorithm),
448 Authorization(TAG_KEY_SIZE, key_size), Authorization(TAG_USER_ID, 7),
449 Authorization(TAG_USER_AUTH_ID, 8), Authorization(TAG_APPLICATION_ID, "app_id", 6),
Shawn Willden1615f2e2014-08-13 10:37:40 -0600450 Authorization(TAG_AUTH_TIMEOUT, 300),
451 };
452 GenerateKeyRequest generate_request;
453 generate_request.key_description.Reinitialize(params, array_length(params));
Shawn Willden43e999e2014-08-13 13:29:50 -0600454 if (static_cast<int>(digest) != -1)
Shawn Willden1615f2e2014-08-13 10:37:40 -0600455 generate_request.key_description.push_back(TAG_DIGEST, digest);
Shawn Willden43e999e2014-08-13 13:29:50 -0600456 if (static_cast<int>(padding) != -1)
Shawn Willden1615f2e2014-08-13 10:37:40 -0600457 generate_request.key_description.push_back(TAG_PADDING, padding);
458 device.GenerateKey(generate_request, &generate_response_);
459 EXPECT_EQ(KM_ERROR_OK, generate_response_.error);
Shawn Willden61644f32014-08-18 13:43:14 -0600460 }
Shawn Willden1615f2e2014-08-13 10:37:40 -0600461
Shawn Willden61644f32014-08-18 13:43:14 -0600462 void SignMessage(const void* message, size_t size) {
Shawn Willden437fbd12014-08-20 11:59:49 -0600463 SignMessage(generate_response_.key_blob, message, size);
464 }
465
466 void SignMessage(const keymaster_key_blob_t& key_blob, const void* message, size_t size) {
Shawn Willden61644f32014-08-18 13:43:14 -0600467 BeginOperationRequest begin_request;
468 BeginOperationResponse begin_response;
Shawn Willden437fbd12014-08-20 11:59:49 -0600469 begin_request.SetKeyMaterial(key_blob);
Shawn Willden61644f32014-08-18 13:43:14 -0600470 begin_request.purpose = KM_PURPOSE_SIGN;
471 AddClientParams(&begin_request.additional_params);
472
473 device.BeginOperation(begin_request, &begin_response);
474 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
475
476 UpdateOperationRequest update_request;
477 UpdateOperationResponse update_response;
478 update_request.op_handle = begin_response.op_handle;
479 update_request.input.Reinitialize(message, size);
480 EXPECT_EQ(size, update_request.input.available_read());
481
482 device.UpdateOperation(update_request, &update_response);
483 ASSERT_EQ(KM_ERROR_OK, update_response.error);
484 EXPECT_EQ(0U, update_response.output.available_read());
Shawn Willdenb7361132014-12-08 08:15:14 -0700485 EXPECT_EQ(size, update_response.input_consumed);
Shawn Willden61644f32014-08-18 13:43:14 -0600486
487 FinishOperationRequest finish_request;
488 finish_request.op_handle = begin_response.op_handle;
489 device.FinishOperation(finish_request, &finish_response_);
490 ASSERT_EQ(KM_ERROR_OK, finish_response_.error);
491 EXPECT_GT(finish_response_.output.available_read(), 0U);
492 }
493
494 void AddClientParams(AuthorizationSet* set) { set->push_back(TAG_APPLICATION_ID, "app_id", 6); }
495
496 const keymaster_key_blob_t& key_blob() { return generate_response_.key_blob; }
Shawn Willdenf268d742014-08-19 15:36:26 -0600497
498 const keymaster_key_blob_t& corrupt_key_blob() {
Shawn Willden2241bf02014-08-28 09:59:53 -0600499 uint8_t* tmp = const_cast<uint8_t*>(generate_response_.key_blob.key_material);
500 ++tmp[generate_response_.key_blob.key_material_size / 2];
Shawn Willdenf268d742014-08-19 15:36:26 -0600501 return generate_response_.key_blob;
502 }
503
Shawn Willden61644f32014-08-18 13:43:14 -0600504 Buffer* signature() {
505 if (finish_response_.error == KM_ERROR_OK)
506 return &finish_response_.output;
507 return NULL;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600508 }
509
Shawn Willden1615f2e2014-08-13 10:37:40 -0600510 GenerateKeyResponse generate_response_;
Shawn Willden61644f32014-08-18 13:43:14 -0600511 FinishOperationResponse finish_response_;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600512};
513
514TEST_F(SigningOperationsTest, RsaSuccess) {
Shawn Willden61644f32014-08-18 13:43:14 -0600515 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willdenffd790c2014-08-18 21:20:06 -0600516 const char message[] = "12345678901234567890123456789012";
Shawn Willdend05cba52014-09-26 09:58:12 -0600517 SignMessage(message, array_size(message) - 1);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600518}
519
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600520TEST_F(SigningOperationsTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600521 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willdend05cba52014-09-26 09:58:12 -0600522 const char message[] = "123456789012345678901234567890123456789012345678";
523 SignMessage(message, array_size(message) - 1);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600524}
525
Shawn Willden1615f2e2014-08-13 10:37:40 -0600526TEST_F(SigningOperationsTest, RsaAbort) {
Shawn Willden61644f32014-08-18 13:43:14 -0600527 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600528
529 BeginOperationRequest begin_request;
530 BeginOperationResponse begin_response;
Shawn Willden61644f32014-08-18 13:43:14 -0600531 begin_request.SetKeyMaterial(key_blob());
Shawn Willden1615f2e2014-08-13 10:37:40 -0600532 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600533 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_OK, begin_response.error);
537
538 EXPECT_EQ(KM_ERROR_OK, device.AbortOperation(begin_response.op_handle));
539
540 // Another abort should fail
541 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
542}
543
544TEST_F(SigningOperationsTest, RsaUnsupportedDigest) {
Shawn Willden61644f32014-08-18 13:43:14 -0600545 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_SHA_2_256, KM_PAD_NONE, 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600546
547 BeginOperationRequest begin_request;
548 BeginOperationResponse begin_response;
549 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600550 begin_request.SetKeyMaterial(key_blob());
551 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600552
553 device.BeginOperation(begin_request, &begin_response);
554 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, begin_response.error);
555
556 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
557}
558
559TEST_F(SigningOperationsTest, RsaUnsupportedPadding) {
Shawn Willden61644f32014-08-18 13:43:14 -0600560 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_RSA_OAEP, 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600561
562 BeginOperationRequest begin_request;
563 BeginOperationResponse begin_response;
564 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600565 begin_request.SetKeyMaterial(key_blob());
566 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600567
568 device.BeginOperation(begin_request, &begin_response);
569 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, begin_response.error);
570
571 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
572}
573
574TEST_F(SigningOperationsTest, RsaNoDigest) {
Shawn Willden61644f32014-08-18 13:43:14 -0600575 GenerateKey(KM_ALGORITHM_RSA, static_cast<keymaster_digest_t>(-1), KM_PAD_NONE,
576 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600577
578 BeginOperationRequest begin_request;
579 BeginOperationResponse begin_response;
580 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600581 begin_request.SetKeyMaterial(key_blob());
582 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600583
584 device.BeginOperation(begin_request, &begin_response);
585 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, begin_response.error);
586
587 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
588}
589
590TEST_F(SigningOperationsTest, RsaNoPadding) {
Shawn Willden61644f32014-08-18 13:43:14 -0600591 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, static_cast<keymaster_padding_t>(-1),
592 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600593
594 BeginOperationRequest begin_request;
595 BeginOperationResponse begin_response;
596 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600597 begin_request.SetKeyMaterial(key_blob());
598 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600599
600 device.BeginOperation(begin_request, &begin_response);
601 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, begin_response.error);
602
603 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
604}
605
606TEST_F(SigningOperationsTest, RsaTooShortMessage) {
Shawn Willden61644f32014-08-18 13:43:14 -0600607 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600608
609 BeginOperationRequest begin_request;
610 BeginOperationResponse begin_response;
Shawn Willden61644f32014-08-18 13:43:14 -0600611 begin_request.SetKeyMaterial(key_blob());
Shawn Willden1615f2e2014-08-13 10:37:40 -0600612 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600613 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600614
615 device.BeginOperation(begin_request, &begin_response);
616 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
617
618 UpdateOperationRequest update_request;
619 UpdateOperationResponse update_response;
620 update_request.op_handle = begin_response.op_handle;
621 update_request.input.Reinitialize("01234567890123456789012345678901", 31);
622 EXPECT_EQ(31U, update_request.input.available_read());
623
624 device.UpdateOperation(update_request, &update_response);
625 ASSERT_EQ(KM_ERROR_OK, update_response.error);
626 EXPECT_EQ(0U, update_response.output.available_read());
Shawn Willdenb7361132014-12-08 08:15:14 -0700627 EXPECT_EQ(31U, update_response.input_consumed);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600628
Shawn Willden43e999e2014-08-13 13:29:50 -0600629 FinishOperationRequest finish_request;
630 finish_request.op_handle = begin_response.op_handle;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600631 FinishOperationResponse finish_response;
Shawn Willden43e999e2014-08-13 13:29:50 -0600632 device.FinishOperation(finish_request, &finish_response);
Shawn Willden00aa7942014-09-10 07:57:43 -0600633 ASSERT_EQ(KM_ERROR_UNKNOWN_ERROR, finish_response.error);
Shawn Willden43e999e2014-08-13 13:29:50 -0600634 EXPECT_EQ(0U, finish_response.output.available_read());
635
636 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
637}
638
Shawn Willdend05cba52014-09-26 09:58:12 -0600639class VerificationOperationsTest : public SigningOperationsTest {
640 protected:
641 void VerifyMessage(const void* message, size_t message_len) {
642 VerifyMessage(generate_response_.key_blob, message, message_len);
643 }
644
645 void VerifyMessage(const keymaster_key_blob_t& key_blob, const void* message,
646 size_t message_len) {
647 ASSERT_TRUE(signature() != NULL);
648
649 BeginOperationRequest begin_request;
650 BeginOperationResponse begin_response;
651 begin_request.SetKeyMaterial(key_blob);
652 begin_request.purpose = KM_PURPOSE_VERIFY;
653 AddClientParams(&begin_request.additional_params);
654
655 device.BeginOperation(begin_request, &begin_response);
656 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
657
658 UpdateOperationRequest update_request;
659 UpdateOperationResponse update_response;
660 update_request.op_handle = begin_response.op_handle;
661 update_request.input.Reinitialize(message, message_len);
662 EXPECT_EQ(message_len, update_request.input.available_read());
663
664 device.UpdateOperation(update_request, &update_response);
665 ASSERT_EQ(KM_ERROR_OK, update_response.error);
666 EXPECT_EQ(0U, update_response.output.available_read());
Shawn Willdenb7361132014-12-08 08:15:14 -0700667 EXPECT_EQ(message_len, update_response.input_consumed);
Shawn Willdend05cba52014-09-26 09:58:12 -0600668
669 FinishOperationRequest finish_request;
670 finish_request.op_handle = begin_response.op_handle;
671 finish_request.signature.Reinitialize(*signature());
672 FinishOperationResponse finish_response;
673 device.FinishOperation(finish_request, &finish_response);
674 ASSERT_EQ(KM_ERROR_OK, finish_response.error);
675 EXPECT_EQ(0U, finish_response.output.available_read());
676
677 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE,
678 device.AbortOperation(begin_response.op_handle));
679 }
680};
681
Shawn Willden43e999e2014-08-13 13:29:50 -0600682TEST_F(VerificationOperationsTest, RsaSuccess) {
Shawn Willden61644f32014-08-18 13:43:14 -0600683 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
684 const char message[] = "12345678901234567890123456789012";
685 SignMessage(message, array_size(message) - 1);
Shawn Willdend05cba52014-09-26 09:58:12 -0600686 VerifyMessage(message, array_size(message) - 1);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600687}
688
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600689TEST_F(VerificationOperationsTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600690 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600691 const char message[] = "123456789012345678901234567890123456789012345678";
692 SignMessage(message, array_size(message) - 1);
Shawn Willdend05cba52014-09-26 09:58:12 -0600693 VerifyMessage(message, array_size(message) - 1);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600694}
695
Shawn Willdenffd790c2014-08-18 21:20:06 -0600696typedef SigningOperationsTest ExportKeyTest;
697TEST_F(ExportKeyTest, RsaSuccess) {
698 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willdenffd790c2014-08-18 21:20:06 -0600699
700 ExportKeyRequest request;
701 ExportKeyResponse response;
702 AddClientParams(&request.additional_params);
703 request.key_format = KM_KEY_FORMAT_X509;
704 request.SetKeyMaterial(key_blob());
705
706 device.ExportKey(request, &response);
707 ASSERT_EQ(KM_ERROR_OK, response.error);
708 EXPECT_TRUE(response.key_data != NULL);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600709
710 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willdenffd790c2014-08-18 21:20:06 -0600711}
712
Shawn Willdenf268d742014-08-19 15:36:26 -0600713TEST_F(ExportKeyTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600714 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willdenf268d742014-08-19 15:36:26 -0600715
716 ExportKeyRequest request;
717 ExportKeyResponse response;
718 AddClientParams(&request.additional_params);
719 request.key_format = KM_KEY_FORMAT_X509;
720 request.SetKeyMaterial(key_blob());
721
722 device.ExportKey(request, &response);
723 ASSERT_EQ(KM_ERROR_OK, response.error);
724 EXPECT_TRUE(response.key_data != NULL);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600725
726 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willdenf268d742014-08-19 15:36:26 -0600727}
728
729TEST_F(ExportKeyTest, RsaUnsupportedKeyFormat) {
730 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256);
731
732 ExportKeyRequest request;
733 ExportKeyResponse response;
734 AddClientParams(&request.additional_params);
735
736 /* We have no other defined export formats defined. */
737 request.key_format = KM_KEY_FORMAT_PKCS8;
738 request.SetKeyMaterial(key_blob());
739
740 device.ExportKey(request, &response);
741 ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_FORMAT, response.error);
742 EXPECT_TRUE(response.key_data == NULL);
743}
744
745TEST_F(ExportKeyTest, RsaCorruptedKeyBlob) {
746 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256);
747
748 ExportKeyRequest request;
749 ExportKeyResponse response;
750 AddClientParams(&request.additional_params);
751 request.key_format = KM_KEY_FORMAT_X509;
752 request.SetKeyMaterial(corrupt_key_blob());
753
754 device.ExportKey(request, &response);
755 ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, response.error);
756 ASSERT_TRUE(response.key_data == NULL);
757}
758
Shawn Willden437fbd12014-08-20 11:59:49 -0600759static string read_file(const string& file_name) {
760 ifstream file_stream(file_name, std::ios::binary);
761 istreambuf_iterator<char> file_begin(file_stream);
762 istreambuf_iterator<char> file_end;
763 return string(file_begin, file_end);
764}
765
Shawn Willdend05cba52014-09-26 09:58:12 -0600766typedef VerificationOperationsTest ImportKeyTest;
Shawn Willden437fbd12014-08-20 11:59:49 -0600767TEST_F(ImportKeyTest, RsaSuccess) {
768 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700769 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
770 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
771 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
772 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden437fbd12014-08-20 11:59:49 -0600773 };
774
Shawn Willden81effc62014-08-27 10:08:46 -0600775 string pk8_key = read_file("rsa_privkey_pk8.der");
Shawn Willden437fbd12014-08-20 11:59:49 -0600776 ASSERT_EQ(633U, pk8_key.size());
777
778 ImportKeyRequest import_request;
779 import_request.key_description.Reinitialize(params, array_length(params));
780 import_request.key_format = KM_KEY_FORMAT_PKCS8;
781 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
782
783 ImportKeyResponse import_response;
784 device.ImportKey(import_request, &import_response);
785 ASSERT_EQ(KM_ERROR_OK, import_response.error);
786 EXPECT_EQ(0U, import_response.enforced.size());
787 EXPECT_GT(import_response.unenforced.size(), 0U);
788
789 // Check values derived from the key.
790 EXPECT_TRUE(contains(import_response.unenforced, TAG_ALGORITHM, KM_ALGORITHM_RSA));
791 EXPECT_TRUE(contains(import_response.unenforced, TAG_KEY_SIZE, 1024));
792 EXPECT_TRUE(contains(import_response.unenforced, TAG_RSA_PUBLIC_EXPONENT, 65537U));
793
794 // And values provided by GoogleKeymaster
795 EXPECT_TRUE(contains(import_response.unenforced, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
796 EXPECT_TRUE(contains(import_response.unenforced, KM_TAG_CREATION_DATETIME));
797
798 size_t message_len = 1024 / 8;
799 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
800 std::fill(message.get(), message.get() + message_len, 'a');
801 SignMessage(import_response.key_blob, message.get(), message_len);
802 ASSERT_TRUE(signature() != NULL);
Shawn Willdend05cba52014-09-26 09:58:12 -0600803 VerifyMessage(import_response.key_blob, message.get(), message_len);
Shawn Willden437fbd12014-08-20 11:59:49 -0600804}
805
Shawn Willden6bbe6782014-09-18 11:26:15 -0600806TEST_F(ImportKeyTest, RsaKeySizeMismatch) {
807 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700808 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
809 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
Shawn Willden6bbe6782014-09-18 11:26:15 -0600810 Authorization(TAG_KEY_SIZE, 2048), // Doesn't match key
Shawn Willden3809b932014-12-02 06:59:46 -0700811 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
812 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden6bbe6782014-09-18 11:26:15 -0600813 };
814
815 string pk8_key = read_file("rsa_privkey_pk8.der");
816 ASSERT_EQ(633U, pk8_key.size());
817
818 ImportKeyRequest import_request;
819 import_request.key_description.Reinitialize(params, array_length(params));
820 import_request.key_format = KM_KEY_FORMAT_PKCS8;
821 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
822
823 ImportKeyResponse import_response;
824 device.ImportKey(import_request, &import_response);
825 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH, import_response.error);
826}
827
828TEST_F(ImportKeyTest, RsaPublicExponenMismatch) {
829 keymaster_key_param_t params[] = {
830 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
Shawn Willden3809b932014-12-02 06:59:46 -0700831 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
832 Authorization(TAG_RSA_PUBLIC_EXPONENT, 3), Authorization(TAG_USER_ID, 7),
833 Authorization(TAG_USER_AUTH_ID, 8), Authorization(TAG_APPLICATION_ID, "app_id", 6),
Shawn Willden6bbe6782014-09-18 11:26:15 -0600834 Authorization(TAG_AUTH_TIMEOUT, 300),
835 };
836
837 string pk8_key = read_file("rsa_privkey_pk8.der");
838 ASSERT_EQ(633U, pk8_key.size());
839
840 ImportKeyRequest import_request;
841 import_request.key_description.Reinitialize(params, array_length(params));
842 import_request.key_format = KM_KEY_FORMAT_PKCS8;
843 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
844
845 ImportKeyResponse import_response;
846 device.ImportKey(import_request, &import_response);
847 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH, import_response.error);
848}
849
Shawn Willden81effc62014-08-27 10:08:46 -0600850TEST_F(ImportKeyTest, EcdsaSuccess) {
851 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700852 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
853 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
854 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
855 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden81effc62014-08-27 10:08:46 -0600856 };
857
858 string pk8_key = read_file("ec_privkey_pk8.der");
859 ASSERT_EQ(138U, pk8_key.size());
860
861 ImportKeyRequest import_request;
862 import_request.key_description.Reinitialize(params, array_length(params));
863 import_request.key_format = KM_KEY_FORMAT_PKCS8;
864 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
865
866 ImportKeyResponse import_response;
867 device.ImportKey(import_request, &import_response);
868 ASSERT_EQ(KM_ERROR_OK, import_response.error);
869 EXPECT_EQ(0U, import_response.enforced.size());
870 EXPECT_GT(import_response.unenforced.size(), 0U);
871
872 // Check values derived from the key.
873 EXPECT_TRUE(contains(import_response.unenforced, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
874 EXPECT_TRUE(contains(import_response.unenforced, TAG_KEY_SIZE, 256));
875
876 // And values provided by GoogleKeymaster
877 EXPECT_TRUE(contains(import_response.unenforced, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
878 EXPECT_TRUE(contains(import_response.unenforced, KM_TAG_CREATION_DATETIME));
879
880 size_t message_len = 1024 / 8;
881 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
882 std::fill(message.get(), message.get() + message_len, 'a');
883 SignMessage(import_response.key_blob, message.get(), message_len);
884 ASSERT_TRUE(signature() != NULL);
Shawn Willdend05cba52014-09-26 09:58:12 -0600885 VerifyMessage(import_response.key_blob, message.get(), message_len);
Shawn Willden81effc62014-08-27 10:08:46 -0600886}
887
Shawn Willden6bbe6782014-09-18 11:26:15 -0600888TEST_F(ImportKeyTest, EcdsaSizeSpecified) {
889 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700890 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
891 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
892 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
893 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden6bbe6782014-09-18 11:26:15 -0600894 Authorization(TAG_KEY_SIZE, 256),
895 };
896
897 string pk8_key = read_file("ec_privkey_pk8.der");
898 ASSERT_EQ(138U, pk8_key.size());
899
900 ImportKeyRequest import_request;
901 import_request.key_description.Reinitialize(params, array_length(params));
902 import_request.key_format = KM_KEY_FORMAT_PKCS8;
903 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
904
905 ImportKeyResponse import_response;
906 device.ImportKey(import_request, &import_response);
907 ASSERT_EQ(KM_ERROR_OK, import_response.error);
908 EXPECT_EQ(0U, import_response.enforced.size());
909 EXPECT_GT(import_response.unenforced.size(), 0U);
910
911 // Check values derived from the key.
912 EXPECT_TRUE(contains(import_response.unenforced, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
913 EXPECT_TRUE(contains(import_response.unenforced, TAG_KEY_SIZE, 256));
914
915 // And values provided by GoogleKeymaster
916 EXPECT_TRUE(contains(import_response.unenforced, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
917 EXPECT_TRUE(contains(import_response.unenforced, KM_TAG_CREATION_DATETIME));
918
919 size_t message_len = 1024 / 8;
920 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
921 std::fill(message.get(), message.get() + message_len, 'a');
922 SignMessage(import_response.key_blob, message.get(), message_len);
923 ASSERT_TRUE(signature() != NULL);
Shawn Willdend05cba52014-09-26 09:58:12 -0600924 VerifyMessage(import_response.key_blob, message.get(), message_len);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600925}
926
927TEST_F(ImportKeyTest, EcdsaSizeMismatch) {
928 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700929 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
930 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
931 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
932 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden8c856c82014-09-26 09:34:36 -0600933 Authorization(TAG_KEY_SIZE, 224),
Shawn Willden6bbe6782014-09-18 11:26:15 -0600934 };
935
936 string pk8_key = read_file("ec_privkey_pk8.der");
937 ASSERT_EQ(138U, pk8_key.size());
938
939 ImportKeyRequest import_request;
940 import_request.key_description.Reinitialize(params, array_length(params));
941 import_request.key_format = KM_KEY_FORMAT_PKCS8;
942 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
943
944 ImportKeyResponse import_response;
945 device.ImportKey(import_request, &import_response);
946 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH, import_response.error);
947}
948
Shawn Willden2665e862014-11-24 14:46:21 -0700949typedef KeymasterTest VersionTest;
950TEST_F(VersionTest, GetVersion) {
951 GetVersionRequest req;
952 GetVersionResponse rsp;
953 device.GetVersion(req, &rsp);
954 EXPECT_EQ(KM_ERROR_OK, rsp.error);
955 EXPECT_EQ(1, rsp.major_ver);
956 EXPECT_EQ(0, rsp.minor_ver);
957 EXPECT_EQ(0, rsp.subminor_ver);
958}
959
Shawn Willden4200f212014-12-02 07:01:21 -0700960/**
961 * Test class that provides some infrastructure for generating keys and encrypting messages.
962 */
963class EncryptionOperationsTest : public KeymasterTest {
964 protected:
965 void GenerateKey(keymaster_algorithm_t algorithm, keymaster_padding_t padding,
966 uint32_t key_size) {
967 keymaster_key_param_t params[] = {
968 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
969 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT), Authorization(TAG_ALGORITHM, algorithm),
970 Authorization(TAG_KEY_SIZE, key_size), Authorization(TAG_USER_ID, 7),
971 Authorization(TAG_USER_AUTH_ID, 8), Authorization(TAG_APPLICATION_ID, "app_id", 6),
972 Authorization(TAG_AUTH_TIMEOUT, 300),
973 };
974 GenerateKeyRequest generate_request;
975 generate_request.key_description.Reinitialize(params, array_length(params));
976 if (static_cast<int>(padding) != -1)
977 generate_request.key_description.push_back(TAG_PADDING, padding);
978 device.GenerateKey(generate_request, &generate_response_);
979 EXPECT_EQ(KM_ERROR_OK, generate_response_.error);
980 }
981
Shawn Willden907c3012014-12-08 15:51:55 -0700982 void GenerateSymmetricKey(keymaster_algorithm_t algorithm, uint32_t key_size,
983 keymaster_block_mode_t block_mode, uint32_t chunk_length) {
984 keymaster_key_param_t params[] = {
985 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
986 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT), Authorization(TAG_ALGORITHM, algorithm),
987 Authorization(TAG_BLOCK_MODE, block_mode),
988 Authorization(TAG_CHUNK_LENGTH, chunk_length), Authorization(TAG_KEY_SIZE, key_size),
989 Authorization(TAG_MAC_LENGTH, 16), Authorization(TAG_USER_ID, 7),
990 Authorization(TAG_USER_AUTH_ID, 8), Authorization(TAG_APPLICATION_ID, "app_id", 6),
991 Authorization(TAG_AUTH_TIMEOUT, 300),
992 };
993 GenerateKeyRequest generate_request;
994 generate_request.key_description.Reinitialize(params, array_length(params));
995 device.GenerateKey(generate_request, &generate_response_);
996 EXPECT_EQ(KM_ERROR_OK, generate_response_.error);
997 }
998
Shawn Willden4200f212014-12-02 07:01:21 -0700999 keymaster_error_t BeginOperation(keymaster_purpose_t purpose,
1000 const keymaster_key_blob_t& key_blob, uint64_t* op_handle) {
1001 BeginOperationRequest begin_request;
1002 begin_request.SetKeyMaterial(key_blob);
1003 begin_request.purpose = purpose;
1004 AddClientParams(&begin_request.additional_params);
1005
1006 BeginOperationResponse begin_response;
1007 device.BeginOperation(begin_request, &begin_response);
1008 *op_handle = begin_response.op_handle;
1009 return begin_response.error;
1010 }
1011
1012 keymaster_error_t UpdateOperation(uint64_t op_handle, const void* message, size_t size,
Shawn Willdenb7361132014-12-08 08:15:14 -07001013 string* output, size_t* input_consumed) {
Shawn Willden4200f212014-12-02 07:01:21 -07001014 UpdateOperationRequest update_request;
1015 update_request.op_handle = op_handle;
1016 update_request.input.Reinitialize(message, size);
1017
1018 UpdateOperationResponse update_response;
1019 device.UpdateOperation(update_request, &update_response);
1020 if (update_response.error == KM_ERROR_OK)
1021 output->append(reinterpret_cast<const char*>(update_response.output.peek_read()),
1022 update_response.output.available_read());
Shawn Willdenb7361132014-12-08 08:15:14 -07001023 *input_consumed = update_response.input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001024 return update_response.error;
1025 }
1026
1027 keymaster_error_t FinishOperation(uint64_t op_handle, string* output) {
1028 FinishOperationRequest finish_request;
1029 finish_request.op_handle = op_handle;
1030 FinishOperationResponse finish_response;
1031 device.FinishOperation(finish_request, &finish_response);
1032 if (finish_response.error == KM_ERROR_OK)
1033 output->append(reinterpret_cast<const char*>(finish_response.output.peek_read()),
1034 finish_response.output.available_read());
1035 return finish_response.error;
1036 }
1037
1038 string ProcessMessage(keymaster_purpose_t purpose, const keymaster_key_blob_t& key_blob,
1039 const void* message, size_t size) {
1040 uint64_t op_handle;
1041 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose, key_blob, &op_handle));
1042
1043 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001044 size_t input_consumed;
1045 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, message, size, &result, &input_consumed));
1046 EXPECT_EQ(size, input_consumed);
Shawn Willden4200f212014-12-02 07:01:21 -07001047 EXPECT_EQ(KM_ERROR_OK, FinishOperation(op_handle, &result));
Shawn Willdenb7361132014-12-08 08:15:14 -07001048
Shawn Willden4200f212014-12-02 07:01:21 -07001049 return result;
1050 }
1051
1052 string EncryptMessage(const void* message, size_t size) {
1053 return ProcessMessage(KM_PURPOSE_ENCRYPT, generate_response_.key_blob, message, size);
1054 }
1055
1056 string DecryptMessage(const void* ciphertext, size_t size) {
1057 return ProcessMessage(KM_PURPOSE_DECRYPT, generate_response_.key_blob, ciphertext, size);
1058 }
1059
1060 void AddClientParams(AuthorizationSet* set) { set->push_back(TAG_APPLICATION_ID, "app_id", 6); }
1061
1062 const keymaster_key_blob_t& key_blob() { return generate_response_.key_blob; }
1063
1064 const keymaster_key_blob_t& corrupt_key_blob() {
1065 uint8_t* tmp = const_cast<uint8_t*>(generate_response_.key_blob.key_material);
1066 ++tmp[generate_response_.key_blob.key_material_size / 2];
1067 return generate_response_.key_blob;
1068 }
1069
1070 protected:
1071 GenerateKeyResponse generate_response_;
1072};
1073
1074TEST_F(EncryptionOperationsTest, RsaOaepSuccess) {
1075 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1076 const char message[] = "Hello World!";
1077 string ciphertext1 = EncryptMessage(message, strlen(message));
1078 EXPECT_EQ(512 / 8, ciphertext1.size());
1079
1080 string ciphertext2 = EncryptMessage(message, strlen(message));
1081 EXPECT_EQ(512 / 8, ciphertext2.size());
1082
1083 // OAEP randomizes padding so every result should be different.
1084 EXPECT_NE(ciphertext1, ciphertext2);
1085}
1086
1087TEST_F(EncryptionOperationsTest, RsaOaepRoundTrip) {
1088 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1089 const char message[] = "Hello World!";
1090 string ciphertext = EncryptMessage(message, strlen(message));
1091 EXPECT_EQ(512 / 8, ciphertext.size());
1092
1093 string plaintext = DecryptMessage(ciphertext.data(), ciphertext.size());
1094 EXPECT_EQ(message, plaintext);
1095}
1096
1097TEST_F(EncryptionOperationsTest, RsaOaepTooLarge) {
1098 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1099 const char message[] = "12345678901234567890123";
1100 uint64_t op_handle;
1101 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001102 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001103
1104 EXPECT_EQ(KM_ERROR_OK,
1105 BeginOperation(KM_PURPOSE_ENCRYPT, generate_response_.key_blob, &op_handle));
Shawn Willdenb7361132014-12-08 08:15:14 -07001106 EXPECT_EQ(KM_ERROR_OK,
1107 UpdateOperation(op_handle, message, array_size(message), &result, &input_consumed));
Shawn Willden4200f212014-12-02 07:01:21 -07001108 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(op_handle, &result));
1109 EXPECT_EQ(0, result.size());
1110}
1111
1112TEST_F(EncryptionOperationsTest, RsaOaepCorruptedDecrypt) {
1113 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1114 const char message[] = "Hello World!";
1115 string ciphertext = EncryptMessage(message, strlen(message));
1116 EXPECT_EQ(512 / 8, ciphertext.size());
1117
1118 // Corrupt the ciphertext
1119 ciphertext[512 / 8 / 2]++;
1120
1121 uint64_t op_handle;
1122 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001123 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001124 EXPECT_EQ(KM_ERROR_OK,
1125 BeginOperation(KM_PURPOSE_DECRYPT, generate_response_.key_blob, &op_handle));
Shawn Willdenb7361132014-12-08 08:15:14 -07001126 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, ciphertext.data(), ciphertext.size(), &result,
1127 &input_consumed));
Shawn Willden4200f212014-12-02 07:01:21 -07001128 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(op_handle, &result));
1129 EXPECT_EQ(0, result.size());
1130}
1131
1132TEST_F(EncryptionOperationsTest, RsaPkcs1Success) {
1133 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1134 const char message[] = "Hello World!";
1135 string ciphertext1 = EncryptMessage(message, strlen(message));
1136 EXPECT_EQ(512 / 8, ciphertext1.size());
1137
1138 string ciphertext2 = EncryptMessage(message, strlen(message));
1139 EXPECT_EQ(512 / 8, ciphertext2.size());
1140
1141 // PKCS1 v1.5 randomizes padding so every result should be different.
1142 EXPECT_NE(ciphertext1, ciphertext2);
1143}
1144
1145TEST_F(EncryptionOperationsTest, RsaPkcs1RoundTrip) {
1146 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1147 const char message[] = "Hello World!";
1148 string ciphertext = EncryptMessage(message, strlen(message));
1149 EXPECT_EQ(512 / 8, ciphertext.size());
1150
1151 string plaintext = DecryptMessage(ciphertext.data(), ciphertext.size());
1152 EXPECT_EQ(message, plaintext);
1153}
1154
1155TEST_F(EncryptionOperationsTest, RsaPkcs1TooLarge) {
1156 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1157 const char message[] = "1234567890123456789012345678901234567890123456789012";
1158 uint64_t op_handle;
1159 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001160 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001161
1162 EXPECT_EQ(KM_ERROR_OK,
1163 BeginOperation(KM_PURPOSE_ENCRYPT, generate_response_.key_blob, &op_handle));
Shawn Willdenb7361132014-12-08 08:15:14 -07001164 EXPECT_EQ(KM_ERROR_OK,
1165 UpdateOperation(op_handle, message, array_size(message), &result, &input_consumed));
Shawn Willden4200f212014-12-02 07:01:21 -07001166 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(op_handle, &result));
1167 EXPECT_EQ(0, result.size());
1168}
1169
1170TEST_F(EncryptionOperationsTest, RsaPkcs1CorruptedDecrypt) {
1171 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1172 const char message[] = "Hello World!";
1173 string ciphertext = EncryptMessage(message, strlen(message));
1174 EXPECT_EQ(512 / 8, ciphertext.size());
1175
1176 // Corrupt the ciphertext
1177 ciphertext[512 / 8 / 2]++;
1178
1179 uint64_t op_handle;
1180 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001181 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001182 EXPECT_EQ(KM_ERROR_OK,
1183 BeginOperation(KM_PURPOSE_DECRYPT, generate_response_.key_blob, &op_handle));
Shawn Willdenb7361132014-12-08 08:15:14 -07001184 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, ciphertext.data(), ciphertext.size(), &result,
1185 &input_consumed));
Shawn Willden4200f212014-12-02 07:01:21 -07001186 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(op_handle, &result));
1187 EXPECT_EQ(0, result.size());
1188}
1189
Shawn Willden907c3012014-12-08 15:51:55 -07001190TEST_F(EncryptionOperationsTest, AesOcbSuccess) {
1191 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1192 const char message[] = "Hello World!";
1193 string ciphertext1 = EncryptMessage(message, strlen(message));
1194 EXPECT_EQ(12 /* nonce */ + strlen(message) + 16 /* tag */, ciphertext1.size());
1195
1196 string ciphertext2 = EncryptMessage(message, strlen(message));
1197 EXPECT_EQ(12 /* nonce */ + strlen(message) + 16 /* tag */, ciphertext2.size());
1198
1199 // OCB uses a random nonce, so every output should be different
1200 EXPECT_NE(ciphertext1, ciphertext2);
1201}
1202
Shawn Willden128ffe02014-08-06 12:31:33 -06001203} // namespace test
1204} // namespace keymaster