blob: 16df37e956b2a4d7d8df435c050989f60a78b06a [file] [log] [blame]
Shawn Willden128ffe02014-08-06 12:31:33 -06001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Shawn Willden437fbd12014-08-20 11:59:49 -060017#include <string>
18#include <fstream>
19
Shawn Willden128ffe02014-08-06 12:31:33 -060020#include <gtest/gtest.h>
Shawn Willden76364712014-08-11 17:48:04 -060021
Shawn Willden128ffe02014-08-06 12:31:33 -060022#include <openssl/engine.h>
23
Shawn Willden98d9b922014-08-26 08:14:10 -060024#include <keymaster/google_keymaster_utils.h>
25#include <keymaster/keymaster_tags.h>
26
Shawn Willden76364712014-08-11 17:48:04 -060027#include "google_keymaster_test_utils.h"
Shawn Willden128ffe02014-08-06 12:31:33 -060028#include "google_softkeymaster.h"
29
Shawn Willden437fbd12014-08-20 11:59:49 -060030using std::string;
31using std::ifstream;
32using std::istreambuf_iterator;
33
Shawn Willden128ffe02014-08-06 12:31:33 -060034int main(int argc, char** argv) {
35 ::testing::InitGoogleTest(&argc, argv);
36 int result = RUN_ALL_TESTS();
37 // Clean up stuff OpenSSL leaves around, so Valgrind doesn't complain.
38 CRYPTO_cleanup_all_ex_data();
Shawn Willden7c0a82b2014-09-17 12:57:32 -060039 ERR_remove_thread_state(NULL);
Shawn Willden128ffe02014-08-06 12:31:33 -060040 ERR_free_strings();
41 return result;
42}
43
44namespace keymaster {
45namespace test {
46
Shawn Willden6bbe6782014-09-18 11:26:15 -060047// Note that these DSA generator, p and q values must match the values from dsa_privkey_pk8.der.
48const uint8_t dsa_g[] = {
49 0x19, 0x1C, 0x71, 0xFD, 0xE0, 0x03, 0x0C, 0x43, 0xD9, 0x0B, 0xF6, 0xCD, 0xD6, 0xA9, 0x70, 0xE7,
50 0x37, 0x86, 0x3A, 0x78, 0xE9, 0xA7, 0x47, 0xA7, 0x47, 0x06, 0x88, 0xB1, 0xAF, 0xD7, 0xF3, 0xF1,
51 0xA1, 0xD7, 0x00, 0x61, 0x28, 0x88, 0x31, 0x48, 0x60, 0xD8, 0x11, 0xEF, 0xA5, 0x24, 0x1A, 0x81,
52 0xC4, 0x2A, 0xE2, 0xEA, 0x0E, 0x36, 0xD2, 0xD2, 0x05, 0x84, 0x37, 0xCF, 0x32, 0x7D, 0x09, 0xE6,
53 0x0F, 0x8B, 0x0C, 0xC8, 0xC2, 0xA4, 0xB1, 0xDC, 0x80, 0xCA, 0x68, 0xDF, 0xAF, 0xD2, 0x90, 0xC0,
54 0x37, 0x58, 0x54, 0x36, 0x8F, 0x49, 0xB8, 0x62, 0x75, 0x8B, 0x48, 0x47, 0xC0, 0xBE, 0xF7, 0x9A,
55 0x92, 0xA6, 0x68, 0x05, 0xDA, 0x9D, 0xAF, 0x72, 0x9A, 0x67, 0xB3, 0xB4, 0x14, 0x03, 0xAE, 0x4F,
56 0x4C, 0x76, 0xB9, 0xD8, 0x64, 0x0A, 0xBA, 0x3B, 0xA8, 0x00, 0x60, 0x4D, 0xAE, 0x81, 0xC3, 0xC5,
57};
58const uint8_t dsa_p[] = {
59 0xA3, 0xF3, 0xE9, 0xB6, 0x7E, 0x7D, 0x88, 0xF6, 0xB7, 0xE5, 0xF5, 0x1F, 0x3B, 0xEE, 0xAC, 0xD7,
60 0xAD, 0xBC, 0xC9, 0xD1, 0x5A, 0xF8, 0x88, 0xC4, 0xEF, 0x6E, 0x3D, 0x74, 0x19, 0x74, 0xE7, 0xD8,
61 0xE0, 0x26, 0x44, 0x19, 0x86, 0xAF, 0x19, 0xDB, 0x05, 0xE9, 0x3B, 0x8B, 0x58, 0x58, 0xDE, 0xE5,
62 0x4F, 0x48, 0x15, 0x01, 0xEA, 0xE6, 0x83, 0x52, 0xD7, 0xC1, 0x21, 0xDF, 0xB9, 0xB8, 0x07, 0x66,
63 0x50, 0xFB, 0x3A, 0x0C, 0xB3, 0x85, 0xEE, 0xBB, 0x04, 0x5F, 0xC2, 0x6D, 0x6D, 0x95, 0xFA, 0x11,
64 0x93, 0x1E, 0x59, 0x5B, 0xB1, 0x45, 0x8D, 0xE0, 0x3D, 0x73, 0xAA, 0xF2, 0x41, 0x14, 0x51, 0x07,
65 0x72, 0x3D, 0xA2, 0xF7, 0x58, 0xCD, 0x11, 0xA1, 0x32, 0xCF, 0xDA, 0x42, 0xB7, 0xCC, 0x32, 0x80,
66 0xDB, 0x87, 0x82, 0xEC, 0x42, 0xDB, 0x5A, 0x55, 0x24, 0x24, 0xA2, 0xD1, 0x55, 0x29, 0xAD, 0xEB,
67};
68const uint8_t dsa_q[] = {
69 0xEB, 0xEA, 0x17, 0xD2, 0x09, 0xB3, 0xD7, 0x21, 0x9A, 0x21,
70 0x07, 0x82, 0x8F, 0xAB, 0xFE, 0x88, 0x71, 0x68, 0xF7, 0xE3,
71};
72
Shawn Willden128ffe02014-08-06 12:31:33 -060073class KeymasterTest : public testing::Test {
74 protected:
Shawn Willden2f3be362014-08-25 11:31:39 -060075 KeymasterTest() : device(5, new StdoutLogger) { RAND_seed("foobar", 6); }
Shawn Willdenda8485e2014-08-17 08:00:01 -060076 ~KeymasterTest() {}
Shawn Willden128ffe02014-08-06 12:31:33 -060077
Shawn Willdend0772312014-09-18 12:27:57 -060078 template <typename T> void ExpectEmptyResponse(const SupportedResponse<T>& response) {
79 EXPECT_EQ(KM_ERROR_OK, response.error);
80 EXPECT_EQ(0U, response.results_length);
81 }
82
83 template <typename T> void ExpectResponseContains(T val, const SupportedResponse<T>& response) {
84 EXPECT_EQ(KM_ERROR_OK, response.error);
85 EXPECT_EQ(1U, response.results_length);
86 EXPECT_EQ(val, response.results[0]);
87 }
88
Shawn Willden128ffe02014-08-06 12:31:33 -060089 GoogleSoftKeymaster device;
90};
91
Shawn Willden128ffe02014-08-06 12:31:33 -060092typedef KeymasterTest CheckSupported;
93TEST_F(CheckSupported, SupportedAlgorithms) {
94 // Shouldn't blow up on NULL.
95 device.SupportedAlgorithms(NULL);
96
97 SupportedResponse<keymaster_algorithm_t> response;
98 device.SupportedAlgorithms(&response);
99 EXPECT_EQ(KM_ERROR_OK, response.error);
Shawn Willden19fca882015-01-22 16:35:30 -0700100 EXPECT_EQ(4U, response.results_length);
Shawn Willden128ffe02014-08-06 12:31:33 -0600101 EXPECT_EQ(KM_ALGORITHM_RSA, response.results[0]);
Shawn Willden28e41472014-08-18 13:35:22 -0600102 EXPECT_EQ(KM_ALGORITHM_DSA, response.results[1]);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600103 EXPECT_EQ(KM_ALGORITHM_ECDSA, response.results[2]);
Shawn Willden19fca882015-01-22 16:35:30 -0700104 EXPECT_EQ(KM_ALGORITHM_AES, response.results[3]);
Shawn Willden128ffe02014-08-06 12:31:33 -0600105}
106
107TEST_F(CheckSupported, SupportedBlockModes) {
108 // Shouldn't blow up on NULL.
Shawn Willden3809b932014-12-02 06:59:46 -0700109 device.SupportedBlockModes(KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT, NULL);
Shawn Willden128ffe02014-08-06 12:31:33 -0600110
111 SupportedResponse<keymaster_block_mode_t> response;
Shawn Willden3809b932014-12-02 06:59:46 -0700112 device.SupportedBlockModes(KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT, &response);
113 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE, response.error);
Shawn Willden128ffe02014-08-06 12:31:33 -0600114
Shawn Willden3809b932014-12-02 06:59:46 -0700115 device.SupportedBlockModes(KM_ALGORITHM_DSA, KM_PURPOSE_ENCRYPT, &response);
116 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE, response.error);
Shawn Willden28e41472014-08-18 13:35:22 -0600117
Shawn Willden3809b932014-12-02 06:59:46 -0700118 device.SupportedBlockModes(KM_ALGORITHM_ECDSA, KM_PURPOSE_ENCRYPT, &response);
119 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE, response.error);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600120
Shawn Willden3809b932014-12-02 06:59:46 -0700121 device.SupportedBlockModes(KM_ALGORITHM_AES, KM_PURPOSE_ENCRYPT, &response);
Shawn Willden19fca882015-01-22 16:35:30 -0700122 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE, response.error);
Shawn Willden128ffe02014-08-06 12:31:33 -0600123}
124
125TEST_F(CheckSupported, SupportedPaddingModes) {
126 // Shouldn't blow up on NULL.
Shawn Willden3809b932014-12-02 06:59:46 -0700127 device.SupportedPaddingModes(KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT, NULL);
Shawn Willden128ffe02014-08-06 12:31:33 -0600128
129 SupportedResponse<keymaster_padding_t> response;
Shawn Willden3809b932014-12-02 06:59:46 -0700130 device.SupportedPaddingModes(KM_ALGORITHM_RSA, KM_PURPOSE_SIGN, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600131 ExpectResponseContains(KM_PAD_NONE, response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600132
Shawn Willden3809b932014-12-02 06:59:46 -0700133 device.SupportedPaddingModes(KM_ALGORITHM_DSA, KM_PURPOSE_SIGN, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600134 ExpectResponseContains(KM_PAD_NONE, response);
Shawn Willden28e41472014-08-18 13:35:22 -0600135
Shawn Willden3809b932014-12-02 06:59:46 -0700136 device.SupportedPaddingModes(KM_ALGORITHM_ECDSA, KM_PURPOSE_SIGN, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600137 ExpectResponseContains(KM_PAD_NONE, response);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600138
Shawn Willden3809b932014-12-02 06:59:46 -0700139 device.SupportedPaddingModes(KM_ALGORITHM_AES, KM_PURPOSE_SIGN, &response);
Shawn Willden19fca882015-01-22 16:35:30 -0700140 ExpectEmptyResponse(response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600141}
142
143TEST_F(CheckSupported, SupportedDigests) {
144 // Shouldn't blow up on NULL.
Shawn Willden3809b932014-12-02 06:59:46 -0700145 device.SupportedDigests(KM_ALGORITHM_RSA, KM_PURPOSE_SIGN, NULL);
Shawn Willden128ffe02014-08-06 12:31:33 -0600146
147 SupportedResponse<keymaster_digest_t> response;
Shawn Willden3809b932014-12-02 06:59:46 -0700148 device.SupportedDigests(KM_ALGORITHM_RSA, KM_PURPOSE_SIGN, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600149 ExpectResponseContains(KM_DIGEST_NONE, response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600150
Shawn Willden3809b932014-12-02 06:59:46 -0700151 device.SupportedDigests(KM_ALGORITHM_DSA, KM_PURPOSE_SIGN, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600152 ExpectResponseContains(KM_DIGEST_NONE, response);
Shawn Willden28e41472014-08-18 13:35:22 -0600153
Shawn Willden3809b932014-12-02 06:59:46 -0700154 device.SupportedDigests(KM_ALGORITHM_ECDSA, KM_PURPOSE_SIGN, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600155 ExpectResponseContains(KM_DIGEST_NONE, response);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600156
Shawn Willden3809b932014-12-02 06:59:46 -0700157 device.SupportedDigests(KM_ALGORITHM_AES, KM_PURPOSE_SIGN, &response);
Shawn Willden19fca882015-01-22 16:35:30 -0700158 ExpectEmptyResponse(response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600159}
160
161TEST_F(CheckSupported, SupportedImportFormats) {
162 // Shouldn't blow up on NULL.
163 device.SupportedImportFormats(KM_ALGORITHM_RSA, NULL);
164
165 SupportedResponse<keymaster_key_format_t> response;
166 device.SupportedImportFormats(KM_ALGORITHM_RSA, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600167 ExpectResponseContains(KM_KEY_FORMAT_PKCS8, response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600168
169 device.SupportedImportFormats(KM_ALGORITHM_DSA, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600170 ExpectResponseContains(KM_KEY_FORMAT_PKCS8, response);
Shawn Willden28e41472014-08-18 13:35:22 -0600171
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600172 device.SupportedImportFormats(KM_ALGORITHM_ECDSA, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600173 ExpectResponseContains(KM_KEY_FORMAT_PKCS8, response);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600174
Shawn Willden28e41472014-08-18 13:35:22 -0600175 device.SupportedImportFormats(KM_ALGORITHM_AES, &response);
Shawn Willden19fca882015-01-22 16:35:30 -0700176 ExpectEmptyResponse(response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600177}
178
179TEST_F(CheckSupported, SupportedExportFormats) {
180 // Shouldn't blow up on NULL.
181 device.SupportedExportFormats(KM_ALGORITHM_RSA, NULL);
182
183 SupportedResponse<keymaster_key_format_t> response;
184 device.SupportedExportFormats(KM_ALGORITHM_RSA, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600185 ExpectResponseContains(KM_KEY_FORMAT_X509, response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600186
187 device.SupportedExportFormats(KM_ALGORITHM_DSA, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600188 ExpectResponseContains(KM_KEY_FORMAT_X509, response);
Shawn Willden28e41472014-08-18 13:35:22 -0600189
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600190 device.SupportedExportFormats(KM_ALGORITHM_ECDSA, &response);
Shawn Willdend0772312014-09-18 12:27:57 -0600191 ExpectResponseContains(KM_KEY_FORMAT_X509, response);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600192
Shawn Willden28e41472014-08-18 13:35:22 -0600193 device.SupportedExportFormats(KM_ALGORITHM_AES, &response);
Shawn Willden19fca882015-01-22 16:35:30 -0700194 ExpectEmptyResponse(response);
Shawn Willden128ffe02014-08-06 12:31:33 -0600195}
196
Shawn Willdend0772312014-09-18 12:27:57 -0600197keymaster_key_param_t key_generation_base_params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700198 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
199 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
Shawn Willdend0772312014-09-18 12:27:57 -0600200 Authorization(TAG_APPLICATION_ID, "app_id", 6),
Shawn Willden3809b932014-12-02 06:59:46 -0700201 Authorization(TAG_APPLICATION_DATA, "app_data", 8), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willdend0772312014-09-18 12:27:57 -0600202};
203
204class NewKeyGeneration : public KeymasterTest {
205 protected:
206 NewKeyGeneration() {
207 req_.key_description.Reinitialize(key_generation_base_params,
208 array_length(key_generation_base_params));
209 }
210
211 void CheckBaseParams(const GenerateKeyResponse& rsp) {
212 ASSERT_EQ(KM_ERROR_OK, rsp.error);
213 EXPECT_EQ(0U, rsp.enforced.size());
214 EXPECT_EQ(12U, rsp.enforced.SerializedSize());
215 EXPECT_GT(rsp.unenforced.SerializedSize(), 12U);
216
217 EXPECT_TRUE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_SIGN));
218 EXPECT_TRUE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_VERIFY));
219 EXPECT_TRUE(contains(rsp.unenforced, TAG_USER_ID, 7));
220 EXPECT_TRUE(contains(rsp.unenforced, TAG_USER_AUTH_ID, 8));
221 EXPECT_TRUE(contains(rsp.unenforced, TAG_AUTH_TIMEOUT, 300));
222
223 // Verify that App ID, App data and ROT are NOT included.
224 EXPECT_FALSE(contains(rsp.unenforced, TAG_ROOT_OF_TRUST));
225 EXPECT_FALSE(contains(rsp.unenforced, TAG_APPLICATION_ID));
226 EXPECT_FALSE(contains(rsp.unenforced, TAG_APPLICATION_DATA));
227
228 // Just for giggles, check that some unexpected tags/values are NOT present.
229 EXPECT_FALSE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
230 EXPECT_FALSE(contains(rsp.unenforced, TAG_PURPOSE, KM_PURPOSE_DECRYPT));
231 EXPECT_FALSE(contains(rsp.unenforced, TAG_AUTH_TIMEOUT, 301));
232 EXPECT_FALSE(contains(rsp.unenforced, TAG_RESCOPE_AUTH_TIMEOUT));
233
234 // Now check that unspecified, defaulted tags are correct.
235 EXPECT_TRUE(contains(rsp.unenforced, TAG_ORIGIN, KM_ORIGIN_SOFTWARE));
236 EXPECT_TRUE(contains(rsp.unenforced, KM_TAG_CREATION_DATETIME));
237 }
238
239 GenerateKeyRequest req_;
240 GenerateKeyResponse rsp_;
241};
242
Shawn Willden128ffe02014-08-06 12:31:33 -0600243TEST_F(NewKeyGeneration, Rsa) {
Shawn Willdend0772312014-09-18 12:27:57 -0600244 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA));
245 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, 256));
246 req_.key_description.push_back(Authorization(TAG_RSA_PUBLIC_EXPONENT, 3));
247 device.GenerateKey(req_, &rsp_);
Shawn Willden128ffe02014-08-06 12:31:33 -0600248
Shawn Willdend0772312014-09-18 12:27:57 -0600249 CheckBaseParams(rsp_);
Shawn Willden128ffe02014-08-06 12:31:33 -0600250
251 // Check specified tags are all present in unenforced characteristics
Shawn Willdend0772312014-09-18 12:27:57 -0600252 EXPECT_TRUE(contains(rsp_.unenforced, TAG_ALGORITHM, KM_ALGORITHM_RSA));
253 EXPECT_TRUE(contains(rsp_.unenforced, TAG_KEY_SIZE, 256));
254 EXPECT_TRUE(contains(rsp_.unenforced, TAG_RSA_PUBLIC_EXPONENT, 3));
Shawn Willden128ffe02014-08-06 12:31:33 -0600255}
256
Shawn Willden6bbe6782014-09-18 11:26:15 -0600257TEST_F(NewKeyGeneration, RsaDefaultSize) {
Shawn Willdend0772312014-09-18 12:27:57 -0600258 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA));
259 device.GenerateKey(req_, &rsp_);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600260
Shawn Willdend0772312014-09-18 12:27:57 -0600261 CheckBaseParams(rsp_);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600262
263 // Check specified tags are all present in unenforced characteristics
Shawn Willdend0772312014-09-18 12:27:57 -0600264 EXPECT_TRUE(contains(rsp_.unenforced, TAG_ALGORITHM, KM_ALGORITHM_RSA));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600265
266 // Now check that unspecified, defaulted tags are correct.
Shawn Willdend0772312014-09-18 12:27:57 -0600267 EXPECT_TRUE(contains(rsp_.unenforced, TAG_RSA_PUBLIC_EXPONENT, 65537));
268 EXPECT_TRUE(contains(rsp_.unenforced, TAG_KEY_SIZE, 2048));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600269}
270
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600271TEST_F(NewKeyGeneration, Ecdsa) {
Shawn Willdend0772312014-09-18 12:27:57 -0600272 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
Shawn Willden8c856c82014-09-26 09:34:36 -0600273 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, 224));
Shawn Willdend0772312014-09-18 12:27:57 -0600274 device.GenerateKey(req_, &rsp_);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600275
Shawn Willdend0772312014-09-18 12:27:57 -0600276 CheckBaseParams(rsp_);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600277
278 // Check specified tags are all present in unenforced characteristics
Shawn Willdend0772312014-09-18 12:27:57 -0600279 EXPECT_TRUE(contains(rsp_.unenforced, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
Shawn Willden8c856c82014-09-26 09:34:36 -0600280 EXPECT_TRUE(contains(rsp_.unenforced, TAG_KEY_SIZE, 224));
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600281}
282
Shawn Willden6bbe6782014-09-18 11:26:15 -0600283TEST_F(NewKeyGeneration, EcdsaDefaultSize) {
Shawn Willdend0772312014-09-18 12:27:57 -0600284 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
285 device.GenerateKey(req_, &rsp_);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600286
Shawn Willdend0772312014-09-18 12:27:57 -0600287 CheckBaseParams(rsp_);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600288
289 // Check specified tags are all present in unenforced characteristics
Shawn Willdend0772312014-09-18 12:27:57 -0600290 EXPECT_TRUE(contains(rsp_.unenforced, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600291
292 // Now check that unspecified, defaulted tags are correct.
Shawn Willdend0772312014-09-18 12:27:57 -0600293 EXPECT_TRUE(contains(rsp_.unenforced, TAG_KEY_SIZE, 224));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600294}
295
296TEST_F(NewKeyGeneration, EcdsaInvalidSize) {
Shawn Willdend0772312014-09-18 12:27:57 -0600297 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
298 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, 190));
299 device.GenerateKey(req_, &rsp_);
300 ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE, rsp_.error);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600301}
302
303TEST_F(NewKeyGeneration, EcdsaAllValidSizes) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600304 size_t valid_sizes[] = {224, 256, 384, 521};
Shawn Willden6bbe6782014-09-18 11:26:15 -0600305 for (size_t size : valid_sizes) {
Shawn Willden0302c552014-12-03 15:33:39 -0700306 GenerateKeyResponse rsp;
Shawn Willdend0772312014-09-18 12:27:57 -0600307 req_.key_description.Reinitialize(key_generation_base_params,
308 array_length(key_generation_base_params));
309 req_.key_description.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
310 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, size));
Shawn Willden0302c552014-12-03 15:33:39 -0700311 device.GenerateKey(req_, &rsp);
312 EXPECT_EQ(KM_ERROR_OK, rsp.error) << "Failed to generate size: " << size;
Shawn Willden6bbe6782014-09-18 11:26:15 -0600313 }
314}
315
Shawn Willden19fca882015-01-22 16:35:30 -0700316TEST_F(NewKeyGeneration, AesOcb) {
317 keymaster_key_param_t params[] = {
318 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
319 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
320 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
321 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_CHUNK_LENGTH, 4096),
322 Authorization(TAG_PADDING, KM_PAD_NONE),
323 };
324 req_.key_description.Reinitialize(params, array_length(params));
325 device.GenerateKey(req_, &rsp_);
326 EXPECT_EQ(KM_ERROR_OK, rsp_.error);
327}
328
329TEST_F(NewKeyGeneration, AesOcbInvalidKeySize) {
330 keymaster_key_param_t params[] = {
331 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
332 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
333 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 129),
334 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_CHUNK_LENGTH, 4096),
335 Authorization(TAG_PADDING, KM_PAD_NONE),
336 };
337 req_.key_description.Reinitialize(params, array_length(params));
338 device.GenerateKey(req_, &rsp_);
339 EXPECT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE, rsp_.error);
340}
341
342TEST_F(NewKeyGeneration, AesOcbAllValidSizes) {
343 keymaster_key_param_t params[] = {
344 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
345 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
346 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES),
347 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB),
348 Authorization(TAG_CHUNK_LENGTH, 4096),
349 Authorization(TAG_PADDING, KM_PAD_NONE),
350 };
351
352 size_t valid_sizes[] = {128, 192, 256};
353 for (size_t size : valid_sizes) {
354 GenerateKeyResponse rsp;
355 req_.key_description.Reinitialize(params, array_length(params));
356 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, size));
357 device.GenerateKey(req_, &rsp);
358 EXPECT_EQ(KM_ERROR_OK, rsp.error) << "Failed to generate size: " << size;
359 }
360}
361
362TEST_F(NewKeyGeneration, AesOcbNoChunkLength) {
363 keymaster_key_param_t params[] = {
364 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
365 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
366 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
367 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_PADDING, KM_PAD_NONE),
368 };
369 req_.key_description.Reinitialize(params, array_length(params));
370 device.GenerateKey(req_, &rsp_);
371 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, rsp_.error);
372}
373
374TEST_F(NewKeyGeneration, AesEcbUnsupported) {
375 keymaster_key_param_t params[] = {
376 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
377 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
378 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
379 Authorization(TAG_BLOCK_MODE, KM_MODE_ECB), Authorization(TAG_PADDING, KM_PAD_NONE),
380 };
381 req_.key_description.Reinitialize(params, array_length(params));
382 device.GenerateKey(req_, &rsp_);
383 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE, rsp_.error);
384}
385
386TEST_F(NewKeyGeneration, AesOcbPaddingUnsupported) {
387 keymaster_key_param_t params[] = {
388 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
389 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
390 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
391 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_CHUNK_LENGTH, 4096),
392 Authorization(TAG_PADDING, KM_PAD_ZERO),
393 };
394 req_.key_description.Reinitialize(params, array_length(params));
395 device.GenerateKey(req_, &rsp_);
396 EXPECT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, rsp_.error);
397}
398
Shawn Willden76364712014-08-11 17:48:04 -0600399typedef KeymasterTest GetKeyCharacteristics;
400TEST_F(GetKeyCharacteristics, SimpleRsa) {
401 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700402 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
403 Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), Authorization(TAG_KEY_SIZE, 256),
404 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
405 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden76364712014-08-11 17:48:04 -0600406 };
407
408 GenerateKeyRequest gen_req;
409 gen_req.key_description.Reinitialize(params, array_length(params));
410 GenerateKeyResponse gen_rsp;
411
412 device.GenerateKey(gen_req, &gen_rsp);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600413 ASSERT_EQ(KM_ERROR_OK, gen_rsp.error);
Shawn Willden76364712014-08-11 17:48:04 -0600414
415 GetKeyCharacteristicsRequest req;
Shawn Willdenda8485e2014-08-17 08:00:01 -0600416 req.SetKeyMaterial(gen_rsp.key_blob);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600417 req.additional_params.push_back(TAG_APPLICATION_ID, "app_id", 6);
Shawn Willden76364712014-08-11 17:48:04 -0600418
419 GetKeyCharacteristicsResponse rsp;
420 device.GetKeyCharacteristics(req, &rsp);
421 ASSERT_EQ(KM_ERROR_OK, rsp.error);
422
423 EXPECT_EQ(gen_rsp.enforced, rsp.enforced);
424 EXPECT_EQ(gen_rsp.unenforced, rsp.unenforced);
425}
426
Shawn Willden61644f32014-08-18 13:43:14 -0600427/**
428 * Test class that provides some infrastructure for generating keys and signing messages.
429 */
Shawn Willden1615f2e2014-08-13 10:37:40 -0600430class SigningOperationsTest : public KeymasterTest {
431 protected:
Shawn Willden61644f32014-08-18 13:43:14 -0600432 void GenerateKey(keymaster_algorithm_t algorithm, keymaster_digest_t digest,
433 keymaster_padding_t padding, uint32_t key_size) {
Shawn Willden1615f2e2014-08-13 10:37:40 -0600434 keymaster_key_param_t params[] = {
435 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
Shawn Willden3809b932014-12-02 06:59:46 -0700436 Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY), Authorization(TAG_ALGORITHM, algorithm),
437 Authorization(TAG_KEY_SIZE, key_size), Authorization(TAG_USER_ID, 7),
438 Authorization(TAG_USER_AUTH_ID, 8), Authorization(TAG_APPLICATION_ID, "app_id", 6),
Shawn Willden1615f2e2014-08-13 10:37:40 -0600439 Authorization(TAG_AUTH_TIMEOUT, 300),
440 };
441 GenerateKeyRequest generate_request;
442 generate_request.key_description.Reinitialize(params, array_length(params));
Shawn Willden43e999e2014-08-13 13:29:50 -0600443 if (static_cast<int>(digest) != -1)
Shawn Willden1615f2e2014-08-13 10:37:40 -0600444 generate_request.key_description.push_back(TAG_DIGEST, digest);
Shawn Willden43e999e2014-08-13 13:29:50 -0600445 if (static_cast<int>(padding) != -1)
Shawn Willden1615f2e2014-08-13 10:37:40 -0600446 generate_request.key_description.push_back(TAG_PADDING, padding);
447 device.GenerateKey(generate_request, &generate_response_);
448 EXPECT_EQ(KM_ERROR_OK, generate_response_.error);
Shawn Willden61644f32014-08-18 13:43:14 -0600449 }
Shawn Willden1615f2e2014-08-13 10:37:40 -0600450
Shawn Willden61644f32014-08-18 13:43:14 -0600451 void SignMessage(const void* message, size_t size) {
Shawn Willden437fbd12014-08-20 11:59:49 -0600452 SignMessage(generate_response_.key_blob, message, size);
453 }
454
455 void SignMessage(const keymaster_key_blob_t& key_blob, const void* message, size_t size) {
Shawn Willden61644f32014-08-18 13:43:14 -0600456 BeginOperationRequest begin_request;
457 BeginOperationResponse begin_response;
Shawn Willden437fbd12014-08-20 11:59:49 -0600458 begin_request.SetKeyMaterial(key_blob);
Shawn Willden61644f32014-08-18 13:43:14 -0600459 begin_request.purpose = KM_PURPOSE_SIGN;
460 AddClientParams(&begin_request.additional_params);
461
462 device.BeginOperation(begin_request, &begin_response);
463 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
464
465 UpdateOperationRequest update_request;
466 UpdateOperationResponse update_response;
467 update_request.op_handle = begin_response.op_handle;
468 update_request.input.Reinitialize(message, size);
469 EXPECT_EQ(size, update_request.input.available_read());
470
471 device.UpdateOperation(update_request, &update_response);
472 ASSERT_EQ(KM_ERROR_OK, update_response.error);
473 EXPECT_EQ(0U, update_response.output.available_read());
Shawn Willdenb7361132014-12-08 08:15:14 -0700474 EXPECT_EQ(size, update_response.input_consumed);
Shawn Willden61644f32014-08-18 13:43:14 -0600475
476 FinishOperationRequest finish_request;
477 finish_request.op_handle = begin_response.op_handle;
478 device.FinishOperation(finish_request, &finish_response_);
479 ASSERT_EQ(KM_ERROR_OK, finish_response_.error);
480 EXPECT_GT(finish_response_.output.available_read(), 0U);
481 }
482
483 void AddClientParams(AuthorizationSet* set) { set->push_back(TAG_APPLICATION_ID, "app_id", 6); }
484
485 const keymaster_key_blob_t& key_blob() { return generate_response_.key_blob; }
Shawn Willdenf268d742014-08-19 15:36:26 -0600486
487 const keymaster_key_blob_t& corrupt_key_blob() {
Shawn Willden2241bf02014-08-28 09:59:53 -0600488 uint8_t* tmp = const_cast<uint8_t*>(generate_response_.key_blob.key_material);
489 ++tmp[generate_response_.key_blob.key_material_size / 2];
Shawn Willdenf268d742014-08-19 15:36:26 -0600490 return generate_response_.key_blob;
491 }
492
Shawn Willden61644f32014-08-18 13:43:14 -0600493 Buffer* signature() {
494 if (finish_response_.error == KM_ERROR_OK)
495 return &finish_response_.output;
496 return NULL;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600497 }
498
Shawn Willden1615f2e2014-08-13 10:37:40 -0600499 GenerateKeyResponse generate_response_;
Shawn Willden61644f32014-08-18 13:43:14 -0600500 FinishOperationResponse finish_response_;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600501};
502
503TEST_F(SigningOperationsTest, RsaSuccess) {
Shawn Willden61644f32014-08-18 13:43:14 -0600504 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willdenffd790c2014-08-18 21:20:06 -0600505 const char message[] = "12345678901234567890123456789012";
Shawn Willdend05cba52014-09-26 09:58:12 -0600506 SignMessage(message, array_size(message) - 1);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600507}
508
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600509TEST_F(SigningOperationsTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600510 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willdend05cba52014-09-26 09:58:12 -0600511 const char message[] = "123456789012345678901234567890123456789012345678";
512 SignMessage(message, array_size(message) - 1);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600513}
514
Shawn Willden1615f2e2014-08-13 10:37:40 -0600515TEST_F(SigningOperationsTest, RsaAbort) {
Shawn Willden61644f32014-08-18 13:43:14 -0600516 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600517
518 BeginOperationRequest begin_request;
519 BeginOperationResponse begin_response;
Shawn Willden61644f32014-08-18 13:43:14 -0600520 begin_request.SetKeyMaterial(key_blob());
Shawn Willden1615f2e2014-08-13 10:37:40 -0600521 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600522 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600523
524 device.BeginOperation(begin_request, &begin_response);
525 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
526
527 EXPECT_EQ(KM_ERROR_OK, device.AbortOperation(begin_response.op_handle));
528
529 // Another abort should fail
530 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
531}
532
533TEST_F(SigningOperationsTest, RsaUnsupportedDigest) {
Shawn Willden61644f32014-08-18 13:43:14 -0600534 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_SHA_2_256, KM_PAD_NONE, 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600535
536 BeginOperationRequest begin_request;
537 BeginOperationResponse begin_response;
538 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600539 begin_request.SetKeyMaterial(key_blob());
540 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600541
542 device.BeginOperation(begin_request, &begin_response);
543 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, begin_response.error);
544
545 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
546}
547
548TEST_F(SigningOperationsTest, RsaUnsupportedPadding) {
Shawn Willden61644f32014-08-18 13:43:14 -0600549 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_RSA_OAEP, 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600550
551 BeginOperationRequest begin_request;
552 BeginOperationResponse begin_response;
553 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600554 begin_request.SetKeyMaterial(key_blob());
555 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600556
557 device.BeginOperation(begin_request, &begin_response);
558 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, begin_response.error);
559
560 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
561}
562
563TEST_F(SigningOperationsTest, RsaNoDigest) {
Shawn Willden61644f32014-08-18 13:43:14 -0600564 GenerateKey(KM_ALGORITHM_RSA, static_cast<keymaster_digest_t>(-1), KM_PAD_NONE,
565 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600566
567 BeginOperationRequest begin_request;
568 BeginOperationResponse begin_response;
569 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600570 begin_request.SetKeyMaterial(key_blob());
571 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600572
573 device.BeginOperation(begin_request, &begin_response);
574 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, begin_response.error);
575
576 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
577}
578
579TEST_F(SigningOperationsTest, RsaNoPadding) {
Shawn Willden61644f32014-08-18 13:43:14 -0600580 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, static_cast<keymaster_padding_t>(-1),
581 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600582
583 BeginOperationRequest begin_request;
584 BeginOperationResponse begin_response;
585 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600586 begin_request.SetKeyMaterial(key_blob());
587 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600588
589 device.BeginOperation(begin_request, &begin_response);
590 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, begin_response.error);
591
592 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
593}
594
595TEST_F(SigningOperationsTest, RsaTooShortMessage) {
Shawn Willden61644f32014-08-18 13:43:14 -0600596 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600597
598 BeginOperationRequest begin_request;
599 BeginOperationResponse begin_response;
Shawn Willden61644f32014-08-18 13:43:14 -0600600 begin_request.SetKeyMaterial(key_blob());
Shawn Willden1615f2e2014-08-13 10:37:40 -0600601 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600602 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600603
604 device.BeginOperation(begin_request, &begin_response);
605 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
606
607 UpdateOperationRequest update_request;
608 UpdateOperationResponse update_response;
609 update_request.op_handle = begin_response.op_handle;
610 update_request.input.Reinitialize("01234567890123456789012345678901", 31);
611 EXPECT_EQ(31U, update_request.input.available_read());
612
613 device.UpdateOperation(update_request, &update_response);
614 ASSERT_EQ(KM_ERROR_OK, update_response.error);
615 EXPECT_EQ(0U, update_response.output.available_read());
Shawn Willdenb7361132014-12-08 08:15:14 -0700616 EXPECT_EQ(31U, update_response.input_consumed);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600617
Shawn Willden43e999e2014-08-13 13:29:50 -0600618 FinishOperationRequest finish_request;
619 finish_request.op_handle = begin_response.op_handle;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600620 FinishOperationResponse finish_response;
Shawn Willden43e999e2014-08-13 13:29:50 -0600621 device.FinishOperation(finish_request, &finish_response);
Shawn Willden00aa7942014-09-10 07:57:43 -0600622 ASSERT_EQ(KM_ERROR_UNKNOWN_ERROR, finish_response.error);
Shawn Willden43e999e2014-08-13 13:29:50 -0600623 EXPECT_EQ(0U, finish_response.output.available_read());
624
625 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
626}
627
Shawn Willdend05cba52014-09-26 09:58:12 -0600628class VerificationOperationsTest : public SigningOperationsTest {
629 protected:
630 void VerifyMessage(const void* message, size_t message_len) {
631 VerifyMessage(generate_response_.key_blob, message, message_len);
632 }
633
634 void VerifyMessage(const keymaster_key_blob_t& key_blob, const void* message,
635 size_t message_len) {
636 ASSERT_TRUE(signature() != NULL);
637
638 BeginOperationRequest begin_request;
639 BeginOperationResponse begin_response;
640 begin_request.SetKeyMaterial(key_blob);
641 begin_request.purpose = KM_PURPOSE_VERIFY;
642 AddClientParams(&begin_request.additional_params);
643
644 device.BeginOperation(begin_request, &begin_response);
645 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
646
647 UpdateOperationRequest update_request;
648 UpdateOperationResponse update_response;
649 update_request.op_handle = begin_response.op_handle;
650 update_request.input.Reinitialize(message, message_len);
651 EXPECT_EQ(message_len, update_request.input.available_read());
652
653 device.UpdateOperation(update_request, &update_response);
654 ASSERT_EQ(KM_ERROR_OK, update_response.error);
655 EXPECT_EQ(0U, update_response.output.available_read());
Shawn Willdenb7361132014-12-08 08:15:14 -0700656 EXPECT_EQ(message_len, update_response.input_consumed);
Shawn Willdend05cba52014-09-26 09:58:12 -0600657
658 FinishOperationRequest finish_request;
659 finish_request.op_handle = begin_response.op_handle;
660 finish_request.signature.Reinitialize(*signature());
661 FinishOperationResponse finish_response;
662 device.FinishOperation(finish_request, &finish_response);
663 ASSERT_EQ(KM_ERROR_OK, finish_response.error);
664 EXPECT_EQ(0U, finish_response.output.available_read());
665
666 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE,
667 device.AbortOperation(begin_response.op_handle));
668 }
669};
670
Shawn Willden43e999e2014-08-13 13:29:50 -0600671TEST_F(VerificationOperationsTest, RsaSuccess) {
Shawn Willden61644f32014-08-18 13:43:14 -0600672 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
673 const char message[] = "12345678901234567890123456789012";
674 SignMessage(message, array_size(message) - 1);
Shawn Willdend05cba52014-09-26 09:58:12 -0600675 VerifyMessage(message, array_size(message) - 1);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600676}
677
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600678TEST_F(VerificationOperationsTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600679 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600680 const char message[] = "123456789012345678901234567890123456789012345678";
681 SignMessage(message, array_size(message) - 1);
Shawn Willdend05cba52014-09-26 09:58:12 -0600682 VerifyMessage(message, array_size(message) - 1);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600683}
684
Shawn Willdenffd790c2014-08-18 21:20:06 -0600685typedef SigningOperationsTest ExportKeyTest;
686TEST_F(ExportKeyTest, RsaSuccess) {
687 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willdenffd790c2014-08-18 21:20:06 -0600688
689 ExportKeyRequest request;
690 ExportKeyResponse response;
691 AddClientParams(&request.additional_params);
692 request.key_format = KM_KEY_FORMAT_X509;
693 request.SetKeyMaterial(key_blob());
694
695 device.ExportKey(request, &response);
696 ASSERT_EQ(KM_ERROR_OK, response.error);
697 EXPECT_TRUE(response.key_data != NULL);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600698
699 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willdenffd790c2014-08-18 21:20:06 -0600700}
701
Shawn Willdenf268d742014-08-19 15:36:26 -0600702TEST_F(ExportKeyTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600703 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willdenf268d742014-08-19 15:36:26 -0600704
705 ExportKeyRequest request;
706 ExportKeyResponse response;
707 AddClientParams(&request.additional_params);
708 request.key_format = KM_KEY_FORMAT_X509;
709 request.SetKeyMaterial(key_blob());
710
711 device.ExportKey(request, &response);
712 ASSERT_EQ(KM_ERROR_OK, response.error);
713 EXPECT_TRUE(response.key_data != NULL);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600714
715 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willdenf268d742014-08-19 15:36:26 -0600716}
717
718TEST_F(ExportKeyTest, RsaUnsupportedKeyFormat) {
719 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256);
720
721 ExportKeyRequest request;
722 ExportKeyResponse response;
723 AddClientParams(&request.additional_params);
724
725 /* We have no other defined export formats defined. */
726 request.key_format = KM_KEY_FORMAT_PKCS8;
727 request.SetKeyMaterial(key_blob());
728
729 device.ExportKey(request, &response);
730 ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_FORMAT, response.error);
731 EXPECT_TRUE(response.key_data == NULL);
732}
733
734TEST_F(ExportKeyTest, RsaCorruptedKeyBlob) {
735 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256);
736
737 ExportKeyRequest request;
738 ExportKeyResponse response;
739 AddClientParams(&request.additional_params);
740 request.key_format = KM_KEY_FORMAT_X509;
741 request.SetKeyMaterial(corrupt_key_blob());
742
743 device.ExportKey(request, &response);
744 ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, response.error);
745 ASSERT_TRUE(response.key_data == NULL);
746}
747
Shawn Willden437fbd12014-08-20 11:59:49 -0600748static string read_file(const string& file_name) {
749 ifstream file_stream(file_name, std::ios::binary);
750 istreambuf_iterator<char> file_begin(file_stream);
751 istreambuf_iterator<char> file_end;
752 return string(file_begin, file_end);
753}
754
Shawn Willdend05cba52014-09-26 09:58:12 -0600755typedef VerificationOperationsTest ImportKeyTest;
Shawn Willden437fbd12014-08-20 11:59:49 -0600756TEST_F(ImportKeyTest, RsaSuccess) {
757 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700758 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
759 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
760 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
761 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden437fbd12014-08-20 11:59:49 -0600762 };
763
Shawn Willden81effc62014-08-27 10:08:46 -0600764 string pk8_key = read_file("rsa_privkey_pk8.der");
Shawn Willden437fbd12014-08-20 11:59:49 -0600765 ASSERT_EQ(633U, pk8_key.size());
766
767 ImportKeyRequest import_request;
768 import_request.key_description.Reinitialize(params, array_length(params));
769 import_request.key_format = KM_KEY_FORMAT_PKCS8;
770 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
771
772 ImportKeyResponse import_response;
773 device.ImportKey(import_request, &import_response);
774 ASSERT_EQ(KM_ERROR_OK, import_response.error);
775 EXPECT_EQ(0U, import_response.enforced.size());
776 EXPECT_GT(import_response.unenforced.size(), 0U);
777
778 // Check values derived from the key.
779 EXPECT_TRUE(contains(import_response.unenforced, TAG_ALGORITHM, KM_ALGORITHM_RSA));
780 EXPECT_TRUE(contains(import_response.unenforced, TAG_KEY_SIZE, 1024));
781 EXPECT_TRUE(contains(import_response.unenforced, TAG_RSA_PUBLIC_EXPONENT, 65537U));
782
783 // And values provided by GoogleKeymaster
784 EXPECT_TRUE(contains(import_response.unenforced, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
785 EXPECT_TRUE(contains(import_response.unenforced, KM_TAG_CREATION_DATETIME));
786
787 size_t message_len = 1024 / 8;
788 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
789 std::fill(message.get(), message.get() + message_len, 'a');
790 SignMessage(import_response.key_blob, message.get(), message_len);
791 ASSERT_TRUE(signature() != NULL);
Shawn Willdend05cba52014-09-26 09:58:12 -0600792 VerifyMessage(import_response.key_blob, message.get(), message_len);
Shawn Willden437fbd12014-08-20 11:59:49 -0600793}
794
Shawn Willden6bbe6782014-09-18 11:26:15 -0600795TEST_F(ImportKeyTest, RsaKeySizeMismatch) {
796 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700797 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
798 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
Shawn Willden6bbe6782014-09-18 11:26:15 -0600799 Authorization(TAG_KEY_SIZE, 2048), // Doesn't match key
Shawn Willden3809b932014-12-02 06:59:46 -0700800 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
801 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden6bbe6782014-09-18 11:26:15 -0600802 };
803
804 string pk8_key = read_file("rsa_privkey_pk8.der");
805 ASSERT_EQ(633U, pk8_key.size());
806
807 ImportKeyRequest import_request;
808 import_request.key_description.Reinitialize(params, array_length(params));
809 import_request.key_format = KM_KEY_FORMAT_PKCS8;
810 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
811
812 ImportKeyResponse import_response;
813 device.ImportKey(import_request, &import_response);
814 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH, import_response.error);
815}
816
817TEST_F(ImportKeyTest, RsaPublicExponenMismatch) {
818 keymaster_key_param_t params[] = {
819 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
Shawn Willden3809b932014-12-02 06:59:46 -0700820 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
821 Authorization(TAG_RSA_PUBLIC_EXPONENT, 3), Authorization(TAG_USER_ID, 7),
822 Authorization(TAG_USER_AUTH_ID, 8), Authorization(TAG_APPLICATION_ID, "app_id", 6),
Shawn Willden6bbe6782014-09-18 11:26:15 -0600823 Authorization(TAG_AUTH_TIMEOUT, 300),
824 };
825
826 string pk8_key = read_file("rsa_privkey_pk8.der");
827 ASSERT_EQ(633U, pk8_key.size());
828
829 ImportKeyRequest import_request;
830 import_request.key_description.Reinitialize(params, array_length(params));
831 import_request.key_format = KM_KEY_FORMAT_PKCS8;
832 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
833
834 ImportKeyResponse import_response;
835 device.ImportKey(import_request, &import_response);
836 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH, import_response.error);
837}
838
Shawn Willden81effc62014-08-27 10:08:46 -0600839TEST_F(ImportKeyTest, EcdsaSuccess) {
840 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700841 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
842 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
843 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
844 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden81effc62014-08-27 10:08:46 -0600845 };
846
847 string pk8_key = read_file("ec_privkey_pk8.der");
848 ASSERT_EQ(138U, pk8_key.size());
849
850 ImportKeyRequest import_request;
851 import_request.key_description.Reinitialize(params, array_length(params));
852 import_request.key_format = KM_KEY_FORMAT_PKCS8;
853 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
854
855 ImportKeyResponse import_response;
856 device.ImportKey(import_request, &import_response);
857 ASSERT_EQ(KM_ERROR_OK, import_response.error);
858 EXPECT_EQ(0U, import_response.enforced.size());
859 EXPECT_GT(import_response.unenforced.size(), 0U);
860
861 // Check values derived from the key.
862 EXPECT_TRUE(contains(import_response.unenforced, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
863 EXPECT_TRUE(contains(import_response.unenforced, TAG_KEY_SIZE, 256));
864
865 // And values provided by GoogleKeymaster
866 EXPECT_TRUE(contains(import_response.unenforced, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
867 EXPECT_TRUE(contains(import_response.unenforced, KM_TAG_CREATION_DATETIME));
868
869 size_t message_len = 1024 / 8;
870 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
871 std::fill(message.get(), message.get() + message_len, 'a');
872 SignMessage(import_response.key_blob, message.get(), message_len);
873 ASSERT_TRUE(signature() != NULL);
Shawn Willdend05cba52014-09-26 09:58:12 -0600874 VerifyMessage(import_response.key_blob, message.get(), message_len);
Shawn Willden81effc62014-08-27 10:08:46 -0600875}
876
Shawn Willden6bbe6782014-09-18 11:26:15 -0600877TEST_F(ImportKeyTest, EcdsaSizeSpecified) {
878 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700879 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
880 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
881 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
882 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden6bbe6782014-09-18 11:26:15 -0600883 Authorization(TAG_KEY_SIZE, 256),
884 };
885
886 string pk8_key = read_file("ec_privkey_pk8.der");
887 ASSERT_EQ(138U, pk8_key.size());
888
889 ImportKeyRequest import_request;
890 import_request.key_description.Reinitialize(params, array_length(params));
891 import_request.key_format = KM_KEY_FORMAT_PKCS8;
892 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
893
894 ImportKeyResponse import_response;
895 device.ImportKey(import_request, &import_response);
896 ASSERT_EQ(KM_ERROR_OK, import_response.error);
897 EXPECT_EQ(0U, import_response.enforced.size());
898 EXPECT_GT(import_response.unenforced.size(), 0U);
899
900 // Check values derived from the key.
901 EXPECT_TRUE(contains(import_response.unenforced, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
902 EXPECT_TRUE(contains(import_response.unenforced, TAG_KEY_SIZE, 256));
903
904 // And values provided by GoogleKeymaster
905 EXPECT_TRUE(contains(import_response.unenforced, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
906 EXPECT_TRUE(contains(import_response.unenforced, KM_TAG_CREATION_DATETIME));
907
908 size_t message_len = 1024 / 8;
909 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
910 std::fill(message.get(), message.get() + message_len, 'a');
911 SignMessage(import_response.key_blob, message.get(), message_len);
912 ASSERT_TRUE(signature() != NULL);
Shawn Willdend05cba52014-09-26 09:58:12 -0600913 VerifyMessage(import_response.key_blob, message.get(), message_len);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600914}
915
916TEST_F(ImportKeyTest, EcdsaSizeMismatch) {
917 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700918 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
919 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
920 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
921 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden8c856c82014-09-26 09:34:36 -0600922 Authorization(TAG_KEY_SIZE, 224),
Shawn Willden6bbe6782014-09-18 11:26:15 -0600923 };
924
925 string pk8_key = read_file("ec_privkey_pk8.der");
926 ASSERT_EQ(138U, pk8_key.size());
927
928 ImportKeyRequest import_request;
929 import_request.key_description.Reinitialize(params, array_length(params));
930 import_request.key_format = KM_KEY_FORMAT_PKCS8;
931 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
932
933 ImportKeyResponse import_response;
934 device.ImportKey(import_request, &import_response);
935 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH, import_response.error);
936}
937
Shawn Willden2665e862014-11-24 14:46:21 -0700938typedef KeymasterTest VersionTest;
939TEST_F(VersionTest, GetVersion) {
940 GetVersionRequest req;
941 GetVersionResponse rsp;
942 device.GetVersion(req, &rsp);
943 EXPECT_EQ(KM_ERROR_OK, rsp.error);
944 EXPECT_EQ(1, rsp.major_ver);
945 EXPECT_EQ(0, rsp.minor_ver);
946 EXPECT_EQ(0, rsp.subminor_ver);
947}
948
Shawn Willden4200f212014-12-02 07:01:21 -0700949/**
950 * Test class that provides some infrastructure for generating keys and encrypting messages.
951 */
952class EncryptionOperationsTest : public KeymasterTest {
953 protected:
954 void GenerateKey(keymaster_algorithm_t algorithm, keymaster_padding_t padding,
955 uint32_t key_size) {
956 keymaster_key_param_t params[] = {
957 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
958 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT), Authorization(TAG_ALGORITHM, algorithm),
959 Authorization(TAG_KEY_SIZE, key_size), Authorization(TAG_USER_ID, 7),
960 Authorization(TAG_USER_AUTH_ID, 8), Authorization(TAG_APPLICATION_ID, "app_id", 6),
961 Authorization(TAG_AUTH_TIMEOUT, 300),
962 };
963 GenerateKeyRequest generate_request;
964 generate_request.key_description.Reinitialize(params, array_length(params));
965 if (static_cast<int>(padding) != -1)
966 generate_request.key_description.push_back(TAG_PADDING, padding);
967 device.GenerateKey(generate_request, &generate_response_);
968 EXPECT_EQ(KM_ERROR_OK, generate_response_.error);
969 }
970
Shawn Willden907c3012014-12-08 15:51:55 -0700971 void GenerateSymmetricKey(keymaster_algorithm_t algorithm, uint32_t key_size,
972 keymaster_block_mode_t block_mode, uint32_t chunk_length) {
973 keymaster_key_param_t params[] = {
974 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
975 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT), Authorization(TAG_ALGORITHM, algorithm),
976 Authorization(TAG_BLOCK_MODE, block_mode),
977 Authorization(TAG_CHUNK_LENGTH, chunk_length), Authorization(TAG_KEY_SIZE, key_size),
978 Authorization(TAG_MAC_LENGTH, 16), Authorization(TAG_USER_ID, 7),
979 Authorization(TAG_USER_AUTH_ID, 8), Authorization(TAG_APPLICATION_ID, "app_id", 6),
980 Authorization(TAG_AUTH_TIMEOUT, 300),
981 };
982 GenerateKeyRequest generate_request;
983 generate_request.key_description.Reinitialize(params, array_length(params));
984 device.GenerateKey(generate_request, &generate_response_);
985 EXPECT_EQ(KM_ERROR_OK, generate_response_.error);
986 }
987
Shawn Willden4200f212014-12-02 07:01:21 -0700988 keymaster_error_t BeginOperation(keymaster_purpose_t purpose,
989 const keymaster_key_blob_t& key_blob, uint64_t* op_handle) {
990 BeginOperationRequest begin_request;
991 begin_request.SetKeyMaterial(key_blob);
992 begin_request.purpose = purpose;
993 AddClientParams(&begin_request.additional_params);
994
995 BeginOperationResponse begin_response;
996 device.BeginOperation(begin_request, &begin_response);
997 *op_handle = begin_response.op_handle;
998 return begin_response.error;
999 }
1000
1001 keymaster_error_t UpdateOperation(uint64_t op_handle, const void* message, size_t size,
Shawn Willdenb7361132014-12-08 08:15:14 -07001002 string* output, size_t* input_consumed) {
Shawn Willden4200f212014-12-02 07:01:21 -07001003 UpdateOperationRequest update_request;
1004 update_request.op_handle = op_handle;
1005 update_request.input.Reinitialize(message, size);
1006
1007 UpdateOperationResponse update_response;
1008 device.UpdateOperation(update_request, &update_response);
1009 if (update_response.error == KM_ERROR_OK)
1010 output->append(reinterpret_cast<const char*>(update_response.output.peek_read()),
1011 update_response.output.available_read());
Shawn Willdenb7361132014-12-08 08:15:14 -07001012 *input_consumed = update_response.input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001013 return update_response.error;
1014 }
1015
1016 keymaster_error_t FinishOperation(uint64_t op_handle, string* output) {
1017 FinishOperationRequest finish_request;
1018 finish_request.op_handle = op_handle;
1019 FinishOperationResponse finish_response;
1020 device.FinishOperation(finish_request, &finish_response);
1021 if (finish_response.error == KM_ERROR_OK)
1022 output->append(reinterpret_cast<const char*>(finish_response.output.peek_read()),
1023 finish_response.output.available_read());
1024 return finish_response.error;
1025 }
1026
1027 string ProcessMessage(keymaster_purpose_t purpose, const keymaster_key_blob_t& key_blob,
1028 const void* message, size_t size) {
1029 uint64_t op_handle;
1030 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose, key_blob, &op_handle));
1031
1032 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001033 size_t input_consumed;
1034 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, message, size, &result, &input_consumed));
1035 EXPECT_EQ(size, input_consumed);
Shawn Willden4200f212014-12-02 07:01:21 -07001036 EXPECT_EQ(KM_ERROR_OK, FinishOperation(op_handle, &result));
Shawn Willdenb7361132014-12-08 08:15:14 -07001037
Shawn Willden4200f212014-12-02 07:01:21 -07001038 return result;
1039 }
1040
1041 string EncryptMessage(const void* message, size_t size) {
1042 return ProcessMessage(KM_PURPOSE_ENCRYPT, generate_response_.key_blob, message, size);
1043 }
1044
1045 string DecryptMessage(const void* ciphertext, size_t size) {
1046 return ProcessMessage(KM_PURPOSE_DECRYPT, generate_response_.key_blob, ciphertext, size);
1047 }
1048
1049 void AddClientParams(AuthorizationSet* set) { set->push_back(TAG_APPLICATION_ID, "app_id", 6); }
1050
1051 const keymaster_key_blob_t& key_blob() { return generate_response_.key_blob; }
1052
1053 const keymaster_key_blob_t& corrupt_key_blob() {
1054 uint8_t* tmp = const_cast<uint8_t*>(generate_response_.key_blob.key_material);
1055 ++tmp[generate_response_.key_blob.key_material_size / 2];
1056 return generate_response_.key_blob;
1057 }
1058
1059 protected:
1060 GenerateKeyResponse generate_response_;
1061};
1062
1063TEST_F(EncryptionOperationsTest, RsaOaepSuccess) {
1064 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1065 const char message[] = "Hello World!";
1066 string ciphertext1 = EncryptMessage(message, strlen(message));
1067 EXPECT_EQ(512 / 8, ciphertext1.size());
1068
1069 string ciphertext2 = EncryptMessage(message, strlen(message));
1070 EXPECT_EQ(512 / 8, ciphertext2.size());
1071
1072 // OAEP randomizes padding so every result should be different.
1073 EXPECT_NE(ciphertext1, ciphertext2);
1074}
1075
1076TEST_F(EncryptionOperationsTest, RsaOaepRoundTrip) {
1077 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1078 const char message[] = "Hello World!";
1079 string ciphertext = EncryptMessage(message, strlen(message));
1080 EXPECT_EQ(512 / 8, ciphertext.size());
1081
1082 string plaintext = DecryptMessage(ciphertext.data(), ciphertext.size());
1083 EXPECT_EQ(message, plaintext);
1084}
1085
1086TEST_F(EncryptionOperationsTest, RsaOaepTooLarge) {
1087 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1088 const char message[] = "12345678901234567890123";
1089 uint64_t op_handle;
1090 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001091 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001092
1093 EXPECT_EQ(KM_ERROR_OK,
1094 BeginOperation(KM_PURPOSE_ENCRYPT, generate_response_.key_blob, &op_handle));
Shawn Willdenb7361132014-12-08 08:15:14 -07001095 EXPECT_EQ(KM_ERROR_OK,
1096 UpdateOperation(op_handle, message, array_size(message), &result, &input_consumed));
Shawn Willden4200f212014-12-02 07:01:21 -07001097 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(op_handle, &result));
1098 EXPECT_EQ(0, result.size());
1099}
1100
1101TEST_F(EncryptionOperationsTest, RsaOaepCorruptedDecrypt) {
1102 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1103 const char message[] = "Hello World!";
1104 string ciphertext = EncryptMessage(message, strlen(message));
1105 EXPECT_EQ(512 / 8, ciphertext.size());
1106
1107 // Corrupt the ciphertext
1108 ciphertext[512 / 8 / 2]++;
1109
1110 uint64_t op_handle;
1111 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001112 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001113 EXPECT_EQ(KM_ERROR_OK,
1114 BeginOperation(KM_PURPOSE_DECRYPT, generate_response_.key_blob, &op_handle));
Shawn Willdenb7361132014-12-08 08:15:14 -07001115 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, ciphertext.data(), ciphertext.size(), &result,
1116 &input_consumed));
Shawn Willden4200f212014-12-02 07:01:21 -07001117 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(op_handle, &result));
1118 EXPECT_EQ(0, result.size());
1119}
1120
1121TEST_F(EncryptionOperationsTest, RsaPkcs1Success) {
1122 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1123 const char message[] = "Hello World!";
1124 string ciphertext1 = EncryptMessage(message, strlen(message));
1125 EXPECT_EQ(512 / 8, ciphertext1.size());
1126
1127 string ciphertext2 = EncryptMessage(message, strlen(message));
1128 EXPECT_EQ(512 / 8, ciphertext2.size());
1129
1130 // PKCS1 v1.5 randomizes padding so every result should be different.
1131 EXPECT_NE(ciphertext1, ciphertext2);
1132}
1133
1134TEST_F(EncryptionOperationsTest, RsaPkcs1RoundTrip) {
1135 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1136 const char message[] = "Hello World!";
1137 string ciphertext = EncryptMessage(message, strlen(message));
1138 EXPECT_EQ(512 / 8, ciphertext.size());
1139
1140 string plaintext = DecryptMessage(ciphertext.data(), ciphertext.size());
1141 EXPECT_EQ(message, plaintext);
1142}
1143
1144TEST_F(EncryptionOperationsTest, RsaPkcs1TooLarge) {
1145 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1146 const char message[] = "1234567890123456789012345678901234567890123456789012";
1147 uint64_t op_handle;
1148 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001149 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001150
1151 EXPECT_EQ(KM_ERROR_OK,
1152 BeginOperation(KM_PURPOSE_ENCRYPT, generate_response_.key_blob, &op_handle));
Shawn Willdenb7361132014-12-08 08:15:14 -07001153 EXPECT_EQ(KM_ERROR_OK,
1154 UpdateOperation(op_handle, message, array_size(message), &result, &input_consumed));
Shawn Willden4200f212014-12-02 07:01:21 -07001155 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(op_handle, &result));
1156 EXPECT_EQ(0, result.size());
1157}
1158
1159TEST_F(EncryptionOperationsTest, RsaPkcs1CorruptedDecrypt) {
1160 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1161 const char message[] = "Hello World!";
1162 string ciphertext = EncryptMessage(message, strlen(message));
1163 EXPECT_EQ(512 / 8, ciphertext.size());
1164
1165 // Corrupt the ciphertext
1166 ciphertext[512 / 8 / 2]++;
1167
1168 uint64_t op_handle;
1169 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001170 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001171 EXPECT_EQ(KM_ERROR_OK,
1172 BeginOperation(KM_PURPOSE_DECRYPT, generate_response_.key_blob, &op_handle));
Shawn Willdenb7361132014-12-08 08:15:14 -07001173 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, ciphertext.data(), ciphertext.size(), &result,
1174 &input_consumed));
Shawn Willden4200f212014-12-02 07:01:21 -07001175 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(op_handle, &result));
1176 EXPECT_EQ(0, result.size());
1177}
1178
Shawn Willden907c3012014-12-08 15:51:55 -07001179TEST_F(EncryptionOperationsTest, AesOcbSuccess) {
1180 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1181 const char message[] = "Hello World!";
1182 string ciphertext1 = EncryptMessage(message, strlen(message));
1183 EXPECT_EQ(12 /* nonce */ + strlen(message) + 16 /* tag */, ciphertext1.size());
1184
1185 string ciphertext2 = EncryptMessage(message, strlen(message));
1186 EXPECT_EQ(12 /* nonce */ + strlen(message) + 16 /* tag */, ciphertext2.size());
1187
1188 // OCB uses a random nonce, so every output should be different
1189 EXPECT_NE(ciphertext1, ciphertext2);
1190}
1191
Shawn Willden128ffe02014-08-06 12:31:33 -06001192} // namespace test
1193} // namespace keymaster