blob: 0bb7896789573ba27d7a365de261fd20b99e5ae9 [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),
Shawn Willden7efb8782014-12-11 14:07:44 -0700322 Authorization(TAG_MAC_LENGTH, 16), Authorization(TAG_PADDING, KM_PAD_NONE),
Shawn Willden19fca882015-01-22 16:35:30 -0700323 };
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),
Shawn Willden7efb8782014-12-11 14:07:44 -0700335 Authorization(TAG_MAC_LENGTH, 16), Authorization(TAG_PADDING, KM_PAD_NONE),
Shawn Willden19fca882015-01-22 16:35:30 -0700336 };
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),
Shawn Willden7efb8782014-12-11 14:07:44 -0700346 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_BLOCK_MODE, KM_MODE_OCB),
347 Authorization(TAG_MAC_LENGTH, 16), Authorization(TAG_CHUNK_LENGTH, 4096),
Shawn Willden19fca882015-01-22 16:35:30 -0700348 Authorization(TAG_PADDING, KM_PAD_NONE),
349 };
350
351 size_t valid_sizes[] = {128, 192, 256};
352 for (size_t size : valid_sizes) {
353 GenerateKeyResponse rsp;
354 req_.key_description.Reinitialize(params, array_length(params));
355 req_.key_description.push_back(Authorization(TAG_KEY_SIZE, size));
356 device.GenerateKey(req_, &rsp);
357 EXPECT_EQ(KM_ERROR_OK, rsp.error) << "Failed to generate size: " << size;
358 }
359}
360
361TEST_F(NewKeyGeneration, AesOcbNoChunkLength) {
362 keymaster_key_param_t params[] = {
363 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
364 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
365 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
366 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_PADDING, KM_PAD_NONE),
367 };
368 req_.key_description.Reinitialize(params, array_length(params));
369 device.GenerateKey(req_, &rsp_);
Shawn Willden7efb8782014-12-11 14:07:44 -0700370 EXPECT_EQ(KM_ERROR_INVALID_ARGUMENT, rsp_.error);
Shawn Willden19fca882015-01-22 16:35:30 -0700371}
372
373TEST_F(NewKeyGeneration, AesEcbUnsupported) {
374 keymaster_key_param_t params[] = {
375 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
376 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
377 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
378 Authorization(TAG_BLOCK_MODE, KM_MODE_ECB), Authorization(TAG_PADDING, KM_PAD_NONE),
379 };
380 req_.key_description.Reinitialize(params, array_length(params));
381 device.GenerateKey(req_, &rsp_);
382 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE, rsp_.error);
383}
384
385TEST_F(NewKeyGeneration, AesOcbPaddingUnsupported) {
386 keymaster_key_param_t params[] = {
387 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
388 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
389 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
390 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_CHUNK_LENGTH, 4096),
391 Authorization(TAG_PADDING, KM_PAD_ZERO),
392 };
393 req_.key_description.Reinitialize(params, array_length(params));
394 device.GenerateKey(req_, &rsp_);
395 EXPECT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, rsp_.error);
396}
397
Shawn Willden7efb8782014-12-11 14:07:44 -0700398TEST_F(NewKeyGeneration, AesOcbInvalidMacLength) {
399 keymaster_key_param_t params[] = {
400 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
401 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
402 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
403 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_CHUNK_LENGTH, 4096),
404 Authorization(TAG_MAC_LENGTH, 17), Authorization(TAG_PADDING, KM_PAD_NONE),
405 };
406 req_.key_description.Reinitialize(params, array_length(params));
407 device.GenerateKey(req_, &rsp_);
408 EXPECT_EQ(KM_ERROR_INVALID_ARGUMENT, rsp_.error);
409}
410
Shawn Willden76364712014-08-11 17:48:04 -0600411typedef KeymasterTest GetKeyCharacteristics;
412TEST_F(GetKeyCharacteristics, SimpleRsa) {
413 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700414 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
415 Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), Authorization(TAG_KEY_SIZE, 256),
416 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
417 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden76364712014-08-11 17:48:04 -0600418 };
419
420 GenerateKeyRequest gen_req;
421 gen_req.key_description.Reinitialize(params, array_length(params));
422 GenerateKeyResponse gen_rsp;
423
424 device.GenerateKey(gen_req, &gen_rsp);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600425 ASSERT_EQ(KM_ERROR_OK, gen_rsp.error);
Shawn Willden76364712014-08-11 17:48:04 -0600426
427 GetKeyCharacteristicsRequest req;
Shawn Willdenda8485e2014-08-17 08:00:01 -0600428 req.SetKeyMaterial(gen_rsp.key_blob);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600429 req.additional_params.push_back(TAG_APPLICATION_ID, "app_id", 6);
Shawn Willden76364712014-08-11 17:48:04 -0600430
431 GetKeyCharacteristicsResponse rsp;
432 device.GetKeyCharacteristics(req, &rsp);
433 ASSERT_EQ(KM_ERROR_OK, rsp.error);
434
435 EXPECT_EQ(gen_rsp.enforced, rsp.enforced);
436 EXPECT_EQ(gen_rsp.unenforced, rsp.unenforced);
437}
438
Shawn Willden61644f32014-08-18 13:43:14 -0600439/**
440 * Test class that provides some infrastructure for generating keys and signing messages.
441 */
Shawn Willden1615f2e2014-08-13 10:37:40 -0600442class SigningOperationsTest : public KeymasterTest {
443 protected:
Shawn Willden61644f32014-08-18 13:43:14 -0600444 void GenerateKey(keymaster_algorithm_t algorithm, keymaster_digest_t digest,
445 keymaster_padding_t padding, uint32_t key_size) {
Shawn Willden1615f2e2014-08-13 10:37:40 -0600446 keymaster_key_param_t params[] = {
447 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN),
Shawn Willden3809b932014-12-02 06:59:46 -0700448 Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY), Authorization(TAG_ALGORITHM, algorithm),
449 Authorization(TAG_KEY_SIZE, key_size), Authorization(TAG_USER_ID, 7),
450 Authorization(TAG_USER_AUTH_ID, 8), Authorization(TAG_APPLICATION_ID, "app_id", 6),
Shawn Willden1615f2e2014-08-13 10:37:40 -0600451 Authorization(TAG_AUTH_TIMEOUT, 300),
452 };
453 GenerateKeyRequest generate_request;
454 generate_request.key_description.Reinitialize(params, array_length(params));
Shawn Willden43e999e2014-08-13 13:29:50 -0600455 if (static_cast<int>(digest) != -1)
Shawn Willden1615f2e2014-08-13 10:37:40 -0600456 generate_request.key_description.push_back(TAG_DIGEST, digest);
Shawn Willden43e999e2014-08-13 13:29:50 -0600457 if (static_cast<int>(padding) != -1)
Shawn Willden1615f2e2014-08-13 10:37:40 -0600458 generate_request.key_description.push_back(TAG_PADDING, padding);
459 device.GenerateKey(generate_request, &generate_response_);
460 EXPECT_EQ(KM_ERROR_OK, generate_response_.error);
Shawn Willden61644f32014-08-18 13:43:14 -0600461 }
Shawn Willden1615f2e2014-08-13 10:37:40 -0600462
Shawn Willden61644f32014-08-18 13:43:14 -0600463 void SignMessage(const void* message, size_t size) {
Shawn Willden437fbd12014-08-20 11:59:49 -0600464 SignMessage(generate_response_.key_blob, message, size);
465 }
466
467 void SignMessage(const keymaster_key_blob_t& key_blob, const void* message, size_t size) {
Shawn Willden61644f32014-08-18 13:43:14 -0600468 BeginOperationRequest begin_request;
469 BeginOperationResponse begin_response;
Shawn Willden437fbd12014-08-20 11:59:49 -0600470 begin_request.SetKeyMaterial(key_blob);
Shawn Willden61644f32014-08-18 13:43:14 -0600471 begin_request.purpose = KM_PURPOSE_SIGN;
472 AddClientParams(&begin_request.additional_params);
473
474 device.BeginOperation(begin_request, &begin_response);
475 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
476
477 UpdateOperationRequest update_request;
478 UpdateOperationResponse update_response;
479 update_request.op_handle = begin_response.op_handle;
480 update_request.input.Reinitialize(message, size);
481 EXPECT_EQ(size, update_request.input.available_read());
482
483 device.UpdateOperation(update_request, &update_response);
484 ASSERT_EQ(KM_ERROR_OK, update_response.error);
485 EXPECT_EQ(0U, update_response.output.available_read());
Shawn Willdenb7361132014-12-08 08:15:14 -0700486 EXPECT_EQ(size, update_response.input_consumed);
Shawn Willden61644f32014-08-18 13:43:14 -0600487
488 FinishOperationRequest finish_request;
489 finish_request.op_handle = begin_response.op_handle;
490 device.FinishOperation(finish_request, &finish_response_);
491 ASSERT_EQ(KM_ERROR_OK, finish_response_.error);
492 EXPECT_GT(finish_response_.output.available_read(), 0U);
493 }
494
495 void AddClientParams(AuthorizationSet* set) { set->push_back(TAG_APPLICATION_ID, "app_id", 6); }
496
497 const keymaster_key_blob_t& key_blob() { return generate_response_.key_blob; }
Shawn Willdenf268d742014-08-19 15:36:26 -0600498
499 const keymaster_key_blob_t& corrupt_key_blob() {
Shawn Willden2241bf02014-08-28 09:59:53 -0600500 uint8_t* tmp = const_cast<uint8_t*>(generate_response_.key_blob.key_material);
501 ++tmp[generate_response_.key_blob.key_material_size / 2];
Shawn Willdenf268d742014-08-19 15:36:26 -0600502 return generate_response_.key_blob;
503 }
504
Shawn Willden61644f32014-08-18 13:43:14 -0600505 Buffer* signature() {
506 if (finish_response_.error == KM_ERROR_OK)
507 return &finish_response_.output;
508 return NULL;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600509 }
510
Shawn Willden1615f2e2014-08-13 10:37:40 -0600511 GenerateKeyResponse generate_response_;
Shawn Willden61644f32014-08-18 13:43:14 -0600512 FinishOperationResponse finish_response_;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600513};
514
515TEST_F(SigningOperationsTest, RsaSuccess) {
Shawn Willden61644f32014-08-18 13:43:14 -0600516 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willdenffd790c2014-08-18 21:20:06 -0600517 const char message[] = "12345678901234567890123456789012";
Shawn Willdend05cba52014-09-26 09:58:12 -0600518 SignMessage(message, array_size(message) - 1);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600519}
520
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600521TEST_F(SigningOperationsTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600522 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willdend05cba52014-09-26 09:58:12 -0600523 const char message[] = "123456789012345678901234567890123456789012345678";
524 SignMessage(message, array_size(message) - 1);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600525}
526
Shawn Willden1615f2e2014-08-13 10:37:40 -0600527TEST_F(SigningOperationsTest, RsaAbort) {
Shawn Willden61644f32014-08-18 13:43:14 -0600528 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600529
530 BeginOperationRequest begin_request;
531 BeginOperationResponse begin_response;
Shawn Willden61644f32014-08-18 13:43:14 -0600532 begin_request.SetKeyMaterial(key_blob());
Shawn Willden1615f2e2014-08-13 10:37:40 -0600533 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600534 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600535
536 device.BeginOperation(begin_request, &begin_response);
537 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
538
539 EXPECT_EQ(KM_ERROR_OK, device.AbortOperation(begin_response.op_handle));
540
541 // Another abort should fail
542 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
543}
544
545TEST_F(SigningOperationsTest, RsaUnsupportedDigest) {
Shawn Willden61644f32014-08-18 13:43:14 -0600546 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_SHA_2_256, KM_PAD_NONE, 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600547
548 BeginOperationRequest begin_request;
549 BeginOperationResponse begin_response;
550 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600551 begin_request.SetKeyMaterial(key_blob());
552 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600553
554 device.BeginOperation(begin_request, &begin_response);
555 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, begin_response.error);
556
557 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
558}
559
560TEST_F(SigningOperationsTest, RsaUnsupportedPadding) {
Shawn Willden61644f32014-08-18 13:43:14 -0600561 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_RSA_OAEP, 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600562
563 BeginOperationRequest begin_request;
564 BeginOperationResponse begin_response;
565 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600566 begin_request.SetKeyMaterial(key_blob());
567 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600568
569 device.BeginOperation(begin_request, &begin_response);
570 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, begin_response.error);
571
572 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
573}
574
575TEST_F(SigningOperationsTest, RsaNoDigest) {
Shawn Willden61644f32014-08-18 13:43:14 -0600576 GenerateKey(KM_ALGORITHM_RSA, static_cast<keymaster_digest_t>(-1), KM_PAD_NONE,
577 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600578
579 BeginOperationRequest begin_request;
580 BeginOperationResponse begin_response;
581 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600582 begin_request.SetKeyMaterial(key_blob());
583 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600584
585 device.BeginOperation(begin_request, &begin_response);
586 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, begin_response.error);
587
588 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
589}
590
591TEST_F(SigningOperationsTest, RsaNoPadding) {
Shawn Willden61644f32014-08-18 13:43:14 -0600592 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, static_cast<keymaster_padding_t>(-1),
593 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600594
595 BeginOperationRequest begin_request;
596 BeginOperationResponse begin_response;
597 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600598 begin_request.SetKeyMaterial(key_blob());
599 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600600
601 device.BeginOperation(begin_request, &begin_response);
602 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, begin_response.error);
603
604 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
605}
606
607TEST_F(SigningOperationsTest, RsaTooShortMessage) {
Shawn Willden61644f32014-08-18 13:43:14 -0600608 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600609
610 BeginOperationRequest begin_request;
611 BeginOperationResponse begin_response;
Shawn Willden61644f32014-08-18 13:43:14 -0600612 begin_request.SetKeyMaterial(key_blob());
Shawn Willden1615f2e2014-08-13 10:37:40 -0600613 begin_request.purpose = KM_PURPOSE_SIGN;
Shawn Willden61644f32014-08-18 13:43:14 -0600614 AddClientParams(&begin_request.additional_params);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600615
616 device.BeginOperation(begin_request, &begin_response);
617 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
618
619 UpdateOperationRequest update_request;
620 UpdateOperationResponse update_response;
621 update_request.op_handle = begin_response.op_handle;
622 update_request.input.Reinitialize("01234567890123456789012345678901", 31);
623 EXPECT_EQ(31U, update_request.input.available_read());
624
625 device.UpdateOperation(update_request, &update_response);
626 ASSERT_EQ(KM_ERROR_OK, update_response.error);
627 EXPECT_EQ(0U, update_response.output.available_read());
Shawn Willdenb7361132014-12-08 08:15:14 -0700628 EXPECT_EQ(31U, update_response.input_consumed);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600629
Shawn Willden43e999e2014-08-13 13:29:50 -0600630 FinishOperationRequest finish_request;
631 finish_request.op_handle = begin_response.op_handle;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600632 FinishOperationResponse finish_response;
Shawn Willden43e999e2014-08-13 13:29:50 -0600633 device.FinishOperation(finish_request, &finish_response);
Shawn Willden00aa7942014-09-10 07:57:43 -0600634 ASSERT_EQ(KM_ERROR_UNKNOWN_ERROR, finish_response.error);
Shawn Willden43e999e2014-08-13 13:29:50 -0600635 EXPECT_EQ(0U, finish_response.output.available_read());
636
637 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device.AbortOperation(begin_response.op_handle));
638}
639
Shawn Willdend05cba52014-09-26 09:58:12 -0600640class VerificationOperationsTest : public SigningOperationsTest {
641 protected:
642 void VerifyMessage(const void* message, size_t message_len) {
643 VerifyMessage(generate_response_.key_blob, message, message_len);
644 }
645
646 void VerifyMessage(const keymaster_key_blob_t& key_blob, const void* message,
647 size_t message_len) {
648 ASSERT_TRUE(signature() != NULL);
649
650 BeginOperationRequest begin_request;
651 BeginOperationResponse begin_response;
652 begin_request.SetKeyMaterial(key_blob);
653 begin_request.purpose = KM_PURPOSE_VERIFY;
654 AddClientParams(&begin_request.additional_params);
655
656 device.BeginOperation(begin_request, &begin_response);
657 ASSERT_EQ(KM_ERROR_OK, begin_response.error);
658
659 UpdateOperationRequest update_request;
660 UpdateOperationResponse update_response;
661 update_request.op_handle = begin_response.op_handle;
662 update_request.input.Reinitialize(message, message_len);
663 EXPECT_EQ(message_len, update_request.input.available_read());
664
665 device.UpdateOperation(update_request, &update_response);
666 ASSERT_EQ(KM_ERROR_OK, update_response.error);
667 EXPECT_EQ(0U, update_response.output.available_read());
Shawn Willdenb7361132014-12-08 08:15:14 -0700668 EXPECT_EQ(message_len, update_response.input_consumed);
Shawn Willdend05cba52014-09-26 09:58:12 -0600669
670 FinishOperationRequest finish_request;
671 finish_request.op_handle = begin_response.op_handle;
672 finish_request.signature.Reinitialize(*signature());
673 FinishOperationResponse finish_response;
674 device.FinishOperation(finish_request, &finish_response);
675 ASSERT_EQ(KM_ERROR_OK, finish_response.error);
676 EXPECT_EQ(0U, finish_response.output.available_read());
677
678 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE,
679 device.AbortOperation(begin_response.op_handle));
680 }
681};
682
Shawn Willden43e999e2014-08-13 13:29:50 -0600683TEST_F(VerificationOperationsTest, RsaSuccess) {
Shawn Willden61644f32014-08-18 13:43:14 -0600684 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
685 const char message[] = "12345678901234567890123456789012";
686 SignMessage(message, array_size(message) - 1);
Shawn Willdend05cba52014-09-26 09:58:12 -0600687 VerifyMessage(message, array_size(message) - 1);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600688}
689
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600690TEST_F(VerificationOperationsTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600691 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600692 const char message[] = "123456789012345678901234567890123456789012345678";
693 SignMessage(message, array_size(message) - 1);
Shawn Willdend05cba52014-09-26 09:58:12 -0600694 VerifyMessage(message, array_size(message) - 1);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600695}
696
Shawn Willdenffd790c2014-08-18 21:20:06 -0600697typedef SigningOperationsTest ExportKeyTest;
698TEST_F(ExportKeyTest, RsaSuccess) {
699 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willdenffd790c2014-08-18 21:20:06 -0600700
701 ExportKeyRequest request;
702 ExportKeyResponse response;
703 AddClientParams(&request.additional_params);
704 request.key_format = KM_KEY_FORMAT_X509;
705 request.SetKeyMaterial(key_blob());
706
707 device.ExportKey(request, &response);
708 ASSERT_EQ(KM_ERROR_OK, response.error);
709 EXPECT_TRUE(response.key_data != NULL);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600710
711 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willdenffd790c2014-08-18 21:20:06 -0600712}
713
Shawn Willdenf268d742014-08-19 15:36:26 -0600714TEST_F(ExportKeyTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600715 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willdenf268d742014-08-19 15:36:26 -0600716
717 ExportKeyRequest request;
718 ExportKeyResponse response;
719 AddClientParams(&request.additional_params);
720 request.key_format = KM_KEY_FORMAT_X509;
721 request.SetKeyMaterial(key_blob());
722
723 device.ExportKey(request, &response);
724 ASSERT_EQ(KM_ERROR_OK, response.error);
725 EXPECT_TRUE(response.key_data != NULL);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600726
727 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willdenf268d742014-08-19 15:36:26 -0600728}
729
730TEST_F(ExportKeyTest, RsaUnsupportedKeyFormat) {
731 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256);
732
733 ExportKeyRequest request;
734 ExportKeyResponse response;
735 AddClientParams(&request.additional_params);
736
737 /* We have no other defined export formats defined. */
738 request.key_format = KM_KEY_FORMAT_PKCS8;
739 request.SetKeyMaterial(key_blob());
740
741 device.ExportKey(request, &response);
742 ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_FORMAT, response.error);
743 EXPECT_TRUE(response.key_data == NULL);
744}
745
746TEST_F(ExportKeyTest, RsaCorruptedKeyBlob) {
747 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256);
748
749 ExportKeyRequest request;
750 ExportKeyResponse response;
751 AddClientParams(&request.additional_params);
752 request.key_format = KM_KEY_FORMAT_X509;
753 request.SetKeyMaterial(corrupt_key_blob());
754
755 device.ExportKey(request, &response);
756 ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, response.error);
757 ASSERT_TRUE(response.key_data == NULL);
758}
759
Shawn Willden437fbd12014-08-20 11:59:49 -0600760static string read_file(const string& file_name) {
761 ifstream file_stream(file_name, std::ios::binary);
762 istreambuf_iterator<char> file_begin(file_stream);
763 istreambuf_iterator<char> file_end;
764 return string(file_begin, file_end);
765}
766
Shawn Willdend05cba52014-09-26 09:58:12 -0600767typedef VerificationOperationsTest ImportKeyTest;
Shawn Willden437fbd12014-08-20 11:59:49 -0600768TEST_F(ImportKeyTest, RsaSuccess) {
769 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700770 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
771 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
772 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
773 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden437fbd12014-08-20 11:59:49 -0600774 };
775
Shawn Willden81effc62014-08-27 10:08:46 -0600776 string pk8_key = read_file("rsa_privkey_pk8.der");
Shawn Willden437fbd12014-08-20 11:59:49 -0600777 ASSERT_EQ(633U, pk8_key.size());
778
779 ImportKeyRequest import_request;
780 import_request.key_description.Reinitialize(params, array_length(params));
781 import_request.key_format = KM_KEY_FORMAT_PKCS8;
782 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
783
784 ImportKeyResponse import_response;
785 device.ImportKey(import_request, &import_response);
786 ASSERT_EQ(KM_ERROR_OK, import_response.error);
787 EXPECT_EQ(0U, import_response.enforced.size());
788 EXPECT_GT(import_response.unenforced.size(), 0U);
789
790 // Check values derived from the key.
791 EXPECT_TRUE(contains(import_response.unenforced, TAG_ALGORITHM, KM_ALGORITHM_RSA));
792 EXPECT_TRUE(contains(import_response.unenforced, TAG_KEY_SIZE, 1024));
793 EXPECT_TRUE(contains(import_response.unenforced, TAG_RSA_PUBLIC_EXPONENT, 65537U));
794
795 // And values provided by GoogleKeymaster
796 EXPECT_TRUE(contains(import_response.unenforced, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
797 EXPECT_TRUE(contains(import_response.unenforced, KM_TAG_CREATION_DATETIME));
798
799 size_t message_len = 1024 / 8;
800 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
801 std::fill(message.get(), message.get() + message_len, 'a');
802 SignMessage(import_response.key_blob, message.get(), message_len);
803 ASSERT_TRUE(signature() != NULL);
Shawn Willdend05cba52014-09-26 09:58:12 -0600804 VerifyMessage(import_response.key_blob, message.get(), message_len);
Shawn Willden437fbd12014-08-20 11:59:49 -0600805}
806
Shawn Willden6bbe6782014-09-18 11:26:15 -0600807TEST_F(ImportKeyTest, RsaKeySizeMismatch) {
808 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700809 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
810 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
Shawn Willden6bbe6782014-09-18 11:26:15 -0600811 Authorization(TAG_KEY_SIZE, 2048), // Doesn't match key
Shawn Willden3809b932014-12-02 06:59:46 -0700812 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
813 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden6bbe6782014-09-18 11:26:15 -0600814 };
815
816 string pk8_key = read_file("rsa_privkey_pk8.der");
817 ASSERT_EQ(633U, pk8_key.size());
818
819 ImportKeyRequest import_request;
820 import_request.key_description.Reinitialize(params, array_length(params));
821 import_request.key_format = KM_KEY_FORMAT_PKCS8;
822 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
823
824 ImportKeyResponse import_response;
825 device.ImportKey(import_request, &import_response);
826 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH, import_response.error);
827}
828
829TEST_F(ImportKeyTest, RsaPublicExponenMismatch) {
830 keymaster_key_param_t params[] = {
831 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
Shawn Willden3809b932014-12-02 06:59:46 -0700832 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
833 Authorization(TAG_RSA_PUBLIC_EXPONENT, 3), Authorization(TAG_USER_ID, 7),
834 Authorization(TAG_USER_AUTH_ID, 8), Authorization(TAG_APPLICATION_ID, "app_id", 6),
Shawn Willden6bbe6782014-09-18 11:26:15 -0600835 Authorization(TAG_AUTH_TIMEOUT, 300),
836 };
837
838 string pk8_key = read_file("rsa_privkey_pk8.der");
839 ASSERT_EQ(633U, pk8_key.size());
840
841 ImportKeyRequest import_request;
842 import_request.key_description.Reinitialize(params, array_length(params));
843 import_request.key_format = KM_KEY_FORMAT_PKCS8;
844 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
845
846 ImportKeyResponse import_response;
847 device.ImportKey(import_request, &import_response);
848 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH, import_response.error);
849}
850
Shawn Willden81effc62014-08-27 10:08:46 -0600851TEST_F(ImportKeyTest, EcdsaSuccess) {
852 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700853 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
854 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
855 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
856 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden81effc62014-08-27 10:08:46 -0600857 };
858
859 string pk8_key = read_file("ec_privkey_pk8.der");
860 ASSERT_EQ(138U, pk8_key.size());
861
862 ImportKeyRequest import_request;
863 import_request.key_description.Reinitialize(params, array_length(params));
864 import_request.key_format = KM_KEY_FORMAT_PKCS8;
865 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
866
867 ImportKeyResponse import_response;
868 device.ImportKey(import_request, &import_response);
869 ASSERT_EQ(KM_ERROR_OK, import_response.error);
870 EXPECT_EQ(0U, import_response.enforced.size());
871 EXPECT_GT(import_response.unenforced.size(), 0U);
872
873 // Check values derived from the key.
874 EXPECT_TRUE(contains(import_response.unenforced, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
875 EXPECT_TRUE(contains(import_response.unenforced, TAG_KEY_SIZE, 256));
876
877 // And values provided by GoogleKeymaster
878 EXPECT_TRUE(contains(import_response.unenforced, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
879 EXPECT_TRUE(contains(import_response.unenforced, KM_TAG_CREATION_DATETIME));
880
881 size_t message_len = 1024 / 8;
882 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
883 std::fill(message.get(), message.get() + message_len, 'a');
884 SignMessage(import_response.key_blob, message.get(), message_len);
885 ASSERT_TRUE(signature() != NULL);
Shawn Willdend05cba52014-09-26 09:58:12 -0600886 VerifyMessage(import_response.key_blob, message.get(), message_len);
Shawn Willden81effc62014-08-27 10:08:46 -0600887}
888
Shawn Willden6bbe6782014-09-18 11:26:15 -0600889TEST_F(ImportKeyTest, EcdsaSizeSpecified) {
890 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700891 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
892 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
893 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
894 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden6bbe6782014-09-18 11:26:15 -0600895 Authorization(TAG_KEY_SIZE, 256),
896 };
897
898 string pk8_key = read_file("ec_privkey_pk8.der");
899 ASSERT_EQ(138U, pk8_key.size());
900
901 ImportKeyRequest import_request;
902 import_request.key_description.Reinitialize(params, array_length(params));
903 import_request.key_format = KM_KEY_FORMAT_PKCS8;
904 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
905
906 ImportKeyResponse import_response;
907 device.ImportKey(import_request, &import_response);
908 ASSERT_EQ(KM_ERROR_OK, import_response.error);
909 EXPECT_EQ(0U, import_response.enforced.size());
910 EXPECT_GT(import_response.unenforced.size(), 0U);
911
912 // Check values derived from the key.
913 EXPECT_TRUE(contains(import_response.unenforced, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
914 EXPECT_TRUE(contains(import_response.unenforced, TAG_KEY_SIZE, 256));
915
916 // And values provided by GoogleKeymaster
917 EXPECT_TRUE(contains(import_response.unenforced, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
918 EXPECT_TRUE(contains(import_response.unenforced, KM_TAG_CREATION_DATETIME));
919
920 size_t message_len = 1024 / 8;
921 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
922 std::fill(message.get(), message.get() + message_len, 'a');
923 SignMessage(import_response.key_blob, message.get(), message_len);
924 ASSERT_TRUE(signature() != NULL);
Shawn Willdend05cba52014-09-26 09:58:12 -0600925 VerifyMessage(import_response.key_blob, message.get(), message_len);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600926}
927
928TEST_F(ImportKeyTest, EcdsaSizeMismatch) {
929 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700930 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
931 Authorization(TAG_DIGEST, KM_DIGEST_NONE), Authorization(TAG_PADDING, KM_PAD_NONE),
932 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
933 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden8c856c82014-09-26 09:34:36 -0600934 Authorization(TAG_KEY_SIZE, 224),
Shawn Willden6bbe6782014-09-18 11:26:15 -0600935 };
936
937 string pk8_key = read_file("ec_privkey_pk8.der");
938 ASSERT_EQ(138U, pk8_key.size());
939
940 ImportKeyRequest import_request;
941 import_request.key_description.Reinitialize(params, array_length(params));
942 import_request.key_format = KM_KEY_FORMAT_PKCS8;
943 import_request.SetKeyMaterial(pk8_key.data(), pk8_key.size());
944
945 ImportKeyResponse import_response;
946 device.ImportKey(import_request, &import_response);
947 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH, import_response.error);
948}
949
Shawn Willden2665e862014-11-24 14:46:21 -0700950typedef KeymasterTest VersionTest;
951TEST_F(VersionTest, GetVersion) {
952 GetVersionRequest req;
953 GetVersionResponse rsp;
954 device.GetVersion(req, &rsp);
955 EXPECT_EQ(KM_ERROR_OK, rsp.error);
956 EXPECT_EQ(1, rsp.major_ver);
957 EXPECT_EQ(0, rsp.minor_ver);
958 EXPECT_EQ(0, rsp.subminor_ver);
959}
960
Shawn Willden4200f212014-12-02 07:01:21 -0700961/**
962 * Test class that provides some infrastructure for generating keys and encrypting messages.
963 */
964class EncryptionOperationsTest : public KeymasterTest {
965 protected:
966 void GenerateKey(keymaster_algorithm_t algorithm, keymaster_padding_t padding,
967 uint32_t key_size) {
968 keymaster_key_param_t params[] = {
969 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
970 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT), Authorization(TAG_ALGORITHM, algorithm),
971 Authorization(TAG_KEY_SIZE, key_size), Authorization(TAG_USER_ID, 7),
972 Authorization(TAG_USER_AUTH_ID, 8), Authorization(TAG_APPLICATION_ID, "app_id", 6),
973 Authorization(TAG_AUTH_TIMEOUT, 300),
974 };
975 GenerateKeyRequest generate_request;
976 generate_request.key_description.Reinitialize(params, array_length(params));
977 if (static_cast<int>(padding) != -1)
978 generate_request.key_description.push_back(TAG_PADDING, padding);
979 device.GenerateKey(generate_request, &generate_response_);
980 EXPECT_EQ(KM_ERROR_OK, generate_response_.error);
981 }
982
Shawn Willden907c3012014-12-08 15:51:55 -0700983 void GenerateSymmetricKey(keymaster_algorithm_t algorithm, uint32_t key_size,
984 keymaster_block_mode_t block_mode, uint32_t chunk_length) {
985 keymaster_key_param_t params[] = {
986 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
987 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT), Authorization(TAG_ALGORITHM, algorithm),
988 Authorization(TAG_BLOCK_MODE, block_mode),
989 Authorization(TAG_CHUNK_LENGTH, chunk_length), Authorization(TAG_KEY_SIZE, key_size),
990 Authorization(TAG_MAC_LENGTH, 16), Authorization(TAG_USER_ID, 7),
991 Authorization(TAG_USER_AUTH_ID, 8), Authorization(TAG_APPLICATION_ID, "app_id", 6),
992 Authorization(TAG_AUTH_TIMEOUT, 300),
993 };
994 GenerateKeyRequest generate_request;
995 generate_request.key_description.Reinitialize(params, array_length(params));
996 device.GenerateKey(generate_request, &generate_response_);
997 EXPECT_EQ(KM_ERROR_OK, generate_response_.error);
998 }
999
Shawn Willden4200f212014-12-02 07:01:21 -07001000 keymaster_error_t BeginOperation(keymaster_purpose_t purpose,
1001 const keymaster_key_blob_t& key_blob, uint64_t* op_handle) {
1002 BeginOperationRequest begin_request;
1003 begin_request.SetKeyMaterial(key_blob);
1004 begin_request.purpose = purpose;
1005 AddClientParams(&begin_request.additional_params);
1006
1007 BeginOperationResponse begin_response;
1008 device.BeginOperation(begin_request, &begin_response);
1009 *op_handle = begin_response.op_handle;
1010 return begin_response.error;
1011 }
1012
1013 keymaster_error_t UpdateOperation(uint64_t op_handle, const void* message, size_t size,
Shawn Willdenb7361132014-12-08 08:15:14 -07001014 string* output, size_t* input_consumed) {
Shawn Willden4200f212014-12-02 07:01:21 -07001015 UpdateOperationRequest update_request;
1016 update_request.op_handle = op_handle;
1017 update_request.input.Reinitialize(message, size);
1018
1019 UpdateOperationResponse update_response;
1020 device.UpdateOperation(update_request, &update_response);
1021 if (update_response.error == KM_ERROR_OK)
1022 output->append(reinterpret_cast<const char*>(update_response.output.peek_read()),
1023 update_response.output.available_read());
Shawn Willdenb7361132014-12-08 08:15:14 -07001024 *input_consumed = update_response.input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001025 return update_response.error;
1026 }
1027
1028 keymaster_error_t FinishOperation(uint64_t op_handle, string* output) {
1029 FinishOperationRequest finish_request;
1030 finish_request.op_handle = op_handle;
1031 FinishOperationResponse finish_response;
1032 device.FinishOperation(finish_request, &finish_response);
1033 if (finish_response.error == KM_ERROR_OK)
1034 output->append(reinterpret_cast<const char*>(finish_response.output.peek_read()),
1035 finish_response.output.available_read());
1036 return finish_response.error;
1037 }
1038
1039 string ProcessMessage(keymaster_purpose_t purpose, const keymaster_key_blob_t& key_blob,
1040 const void* message, size_t size) {
1041 uint64_t op_handle;
1042 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose, key_blob, &op_handle));
1043
1044 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001045 size_t input_consumed;
1046 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, message, size, &result, &input_consumed));
1047 EXPECT_EQ(size, input_consumed);
Shawn Willden4200f212014-12-02 07:01:21 -07001048 EXPECT_EQ(KM_ERROR_OK, FinishOperation(op_handle, &result));
Shawn Willdenb7361132014-12-08 08:15:14 -07001049
Shawn Willden4200f212014-12-02 07:01:21 -07001050 return result;
1051 }
1052
1053 string EncryptMessage(const void* message, size_t size) {
1054 return ProcessMessage(KM_PURPOSE_ENCRYPT, generate_response_.key_blob, message, size);
1055 }
1056
1057 string DecryptMessage(const void* ciphertext, size_t size) {
1058 return ProcessMessage(KM_PURPOSE_DECRYPT, generate_response_.key_blob, ciphertext, size);
1059 }
1060
1061 void AddClientParams(AuthorizationSet* set) { set->push_back(TAG_APPLICATION_ID, "app_id", 6); }
1062
1063 const keymaster_key_blob_t& key_blob() { return generate_response_.key_blob; }
1064
1065 const keymaster_key_blob_t& corrupt_key_blob() {
1066 uint8_t* tmp = const_cast<uint8_t*>(generate_response_.key_blob.key_material);
1067 ++tmp[generate_response_.key_blob.key_material_size / 2];
1068 return generate_response_.key_blob;
1069 }
1070
1071 protected:
1072 GenerateKeyResponse generate_response_;
1073};
1074
1075TEST_F(EncryptionOperationsTest, RsaOaepSuccess) {
1076 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1077 const char message[] = "Hello World!";
1078 string ciphertext1 = EncryptMessage(message, strlen(message));
1079 EXPECT_EQ(512 / 8, ciphertext1.size());
1080
1081 string ciphertext2 = EncryptMessage(message, strlen(message));
1082 EXPECT_EQ(512 / 8, ciphertext2.size());
1083
1084 // OAEP randomizes padding so every result should be different.
1085 EXPECT_NE(ciphertext1, ciphertext2);
1086}
1087
1088TEST_F(EncryptionOperationsTest, RsaOaepRoundTrip) {
1089 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1090 const char message[] = "Hello World!";
1091 string ciphertext = EncryptMessage(message, strlen(message));
1092 EXPECT_EQ(512 / 8, ciphertext.size());
1093
1094 string plaintext = DecryptMessage(ciphertext.data(), ciphertext.size());
1095 EXPECT_EQ(message, plaintext);
1096}
1097
1098TEST_F(EncryptionOperationsTest, RsaOaepTooLarge) {
1099 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1100 const char message[] = "12345678901234567890123";
1101 uint64_t op_handle;
1102 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001103 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001104
1105 EXPECT_EQ(KM_ERROR_OK,
1106 BeginOperation(KM_PURPOSE_ENCRYPT, generate_response_.key_blob, &op_handle));
Shawn Willdenb7361132014-12-08 08:15:14 -07001107 EXPECT_EQ(KM_ERROR_OK,
1108 UpdateOperation(op_handle, message, array_size(message), &result, &input_consumed));
Shawn Willden4200f212014-12-02 07:01:21 -07001109 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(op_handle, &result));
1110 EXPECT_EQ(0, result.size());
1111}
1112
1113TEST_F(EncryptionOperationsTest, RsaOaepCorruptedDecrypt) {
1114 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1115 const char message[] = "Hello World!";
1116 string ciphertext = EncryptMessage(message, strlen(message));
1117 EXPECT_EQ(512 / 8, ciphertext.size());
1118
1119 // Corrupt the ciphertext
1120 ciphertext[512 / 8 / 2]++;
1121
1122 uint64_t op_handle;
1123 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001124 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001125 EXPECT_EQ(KM_ERROR_OK,
1126 BeginOperation(KM_PURPOSE_DECRYPT, generate_response_.key_blob, &op_handle));
Shawn Willdenb7361132014-12-08 08:15:14 -07001127 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, ciphertext.data(), ciphertext.size(), &result,
1128 &input_consumed));
Shawn Willden4200f212014-12-02 07:01:21 -07001129 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(op_handle, &result));
1130 EXPECT_EQ(0, result.size());
1131}
1132
1133TEST_F(EncryptionOperationsTest, RsaPkcs1Success) {
1134 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1135 const char message[] = "Hello World!";
1136 string ciphertext1 = EncryptMessage(message, strlen(message));
1137 EXPECT_EQ(512 / 8, ciphertext1.size());
1138
1139 string ciphertext2 = EncryptMessage(message, strlen(message));
1140 EXPECT_EQ(512 / 8, ciphertext2.size());
1141
1142 // PKCS1 v1.5 randomizes padding so every result should be different.
1143 EXPECT_NE(ciphertext1, ciphertext2);
1144}
1145
1146TEST_F(EncryptionOperationsTest, RsaPkcs1RoundTrip) {
1147 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1148 const char message[] = "Hello World!";
1149 string ciphertext = EncryptMessage(message, strlen(message));
1150 EXPECT_EQ(512 / 8, ciphertext.size());
1151
1152 string plaintext = DecryptMessage(ciphertext.data(), ciphertext.size());
1153 EXPECT_EQ(message, plaintext);
1154}
1155
1156TEST_F(EncryptionOperationsTest, RsaPkcs1TooLarge) {
1157 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1158 const char message[] = "1234567890123456789012345678901234567890123456789012";
1159 uint64_t op_handle;
1160 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001161 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001162
1163 EXPECT_EQ(KM_ERROR_OK,
1164 BeginOperation(KM_PURPOSE_ENCRYPT, generate_response_.key_blob, &op_handle));
Shawn Willdenb7361132014-12-08 08:15:14 -07001165 EXPECT_EQ(KM_ERROR_OK,
1166 UpdateOperation(op_handle, message, array_size(message), &result, &input_consumed));
Shawn Willden4200f212014-12-02 07:01:21 -07001167 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(op_handle, &result));
1168 EXPECT_EQ(0, result.size());
1169}
1170
1171TEST_F(EncryptionOperationsTest, RsaPkcs1CorruptedDecrypt) {
1172 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1173 const char message[] = "Hello World!";
1174 string ciphertext = EncryptMessage(message, strlen(message));
1175 EXPECT_EQ(512 / 8, ciphertext.size());
1176
1177 // Corrupt the ciphertext
1178 ciphertext[512 / 8 / 2]++;
1179
1180 uint64_t op_handle;
1181 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001182 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001183 EXPECT_EQ(KM_ERROR_OK,
1184 BeginOperation(KM_PURPOSE_DECRYPT, generate_response_.key_blob, &op_handle));
Shawn Willdenb7361132014-12-08 08:15:14 -07001185 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, ciphertext.data(), ciphertext.size(), &result,
1186 &input_consumed));
Shawn Willden4200f212014-12-02 07:01:21 -07001187 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(op_handle, &result));
1188 EXPECT_EQ(0, result.size());
1189}
1190
Shawn Willden907c3012014-12-08 15:51:55 -07001191TEST_F(EncryptionOperationsTest, AesOcbSuccess) {
1192 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1193 const char message[] = "Hello World!";
1194 string ciphertext1 = EncryptMessage(message, strlen(message));
1195 EXPECT_EQ(12 /* nonce */ + strlen(message) + 16 /* tag */, ciphertext1.size());
1196
1197 string ciphertext2 = EncryptMessage(message, strlen(message));
1198 EXPECT_EQ(12 /* nonce */ + strlen(message) + 16 /* tag */, ciphertext2.size());
1199
1200 // OCB uses a random nonce, so every output should be different
1201 EXPECT_NE(ciphertext1, ciphertext2);
1202}
1203
Shawn Willden128ffe02014-08-06 12:31:33 -06001204} // namespace test
1205} // namespace keymaster