blob: ccbefccee5e130d6ec14ba02473a588c034d83e4 [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 Willden5b53c992015-02-02 08:05:25 -070028#include "soft_keymaster_device.h"
Shawn Willden128ffe02014-08-06 12:31:33 -060029
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 Willdend6cd7e32014-12-17 08:01:26 -070073const uint64_t OP_HANDLE_SENTINEL = 0xFFFFFFFFFFFFFFFF;
Shawn Willden128ffe02014-08-06 12:31:33 -060074class KeymasterTest : public testing::Test {
75 protected:
Shawn Willdend6cd7e32014-12-17 08:01:26 -070076 KeymasterTest()
77 : device_(new StdoutLogger), out_params_(NULL), signature_(NULL), characteristics_(NULL) {
Shawn Willden5b53c992015-02-02 08:05:25 -070078 blob_.key_material = NULL;
79 RAND_seed("foobar", 6);
80 }
81 ~KeymasterTest() {
82 FreeCharacteristics();
83 FreeKeyBlob();
Shawn Willdend0772312014-09-18 12:27:57 -060084 }
85
Shawn Willden5b53c992015-02-02 08:05:25 -070086 keymaster_device* device() { return reinterpret_cast<keymaster_device*>(device_.hw_device()); }
87
Shawn Willden0d560bf2014-12-15 17:44:02 -070088 void GenerateKey(AuthorizationSet* params) {
89 FreeKeyBlob();
90 FreeCharacteristics();
91 AddClientParams(params);
92 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params->data(), params->size(),
93 &blob_, &characteristics_));
94 }
95
Shawn Willdend6cd7e32014-12-17 08:01:26 -070096 keymaster_error_t BeginOperation(keymaster_purpose_t purpose,
97 const keymaster_key_blob_t& key_blob) {
98 return device()->begin(device(), purpose, &key_blob, client_params_,
99 array_length(client_params_), &out_params_, &out_params_count_,
100 &op_handle_);
101 }
102
103 keymaster_error_t UpdateOperation(const void* message, size_t size, string* output,
104 size_t* input_consumed) {
105 uint8_t* out_tmp = NULL;
106 size_t out_length;
107 keymaster_error_t error =
108 device()->update(device(), op_handle_, reinterpret_cast<const uint8_t*>(message), size,
109 input_consumed, &out_tmp, &out_length);
110 if (out_tmp)
111 output->append(reinterpret_cast<char*>(out_tmp), out_length);
112 free(out_tmp);
113 return error;
114 }
115
116 keymaster_error_t FinishOperation(string* output) {
117 uint8_t* out_tmp = NULL;
118 size_t out_length;
119 keymaster_error_t error =
120 device()->finish(device(), op_handle_, reinterpret_cast<const uint8_t*>(signature_),
121 signature_length_, &out_tmp, &out_length);
122 if (out_tmp)
123 output->append(reinterpret_cast<char*>(out_tmp), out_length);
124 free(out_tmp);
125 return error;
126 }
127
Shawn Willden5b53c992015-02-02 08:05:25 -0700128 template <typename T> void ExpectContains(T val, T* vals, size_t len) {
129 EXPECT_EQ(1U, len);
130 EXPECT_EQ(val, vals[0]);
Shawn Willdend0772312014-09-18 12:27:57 -0600131 }
132
Shawn Willden5b53c992015-02-02 08:05:25 -0700133 void FreeCharacteristics() {
134 keymaster_free_characteristics(characteristics_);
135 free(characteristics_);
136 characteristics_ = NULL;
137 }
138
139 void FreeKeyBlob() {
140 free(const_cast<uint8_t*>(blob_.key_material));
141 blob_.key_material = NULL;
142 }
143
Shawn Willden0d560bf2014-12-15 17:44:02 -0700144 void AddClientParams(AuthorizationSet* set) { set->push_back(TAG_APPLICATION_ID, "app_id", 6); }
145
Shawn Willden6dde87c2014-12-11 14:08:48 -0700146 const keymaster_key_blob_t& key_blob() { return blob_; }
147
Shawn Willden5b53c992015-02-02 08:05:25 -0700148 SoftKeymasterDevice device_;
149
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700150 keymaster_blob_t client_id_ = {.data = reinterpret_cast<const uint8_t*>("app_id"),
151 .data_length = 6};
152 keymaster_key_param_t client_params_[1] = {
153 Authorization(TAG_APPLICATION_ID, client_id_.data, client_id_.data_length)};
154
155 keymaster_key_param_t* out_params_;
156 size_t out_params_count_;
157 uint64_t op_handle_;
158 size_t input_consumed_;
159 uint8_t* signature_;
160 size_t signature_length_;
161
Shawn Willden5b53c992015-02-02 08:05:25 -0700162 AuthorizationSet params_;
163 keymaster_key_blob_t blob_;
164 keymaster_key_characteristics_t* characteristics_;
Shawn Willden128ffe02014-08-06 12:31:33 -0600165};
166
Shawn Willden128ffe02014-08-06 12:31:33 -0600167typedef KeymasterTest CheckSupported;
168TEST_F(CheckSupported, SupportedAlgorithms) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700169 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
170 device()->get_supported_algorithms(device(), NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600171
Shawn Willden5b53c992015-02-02 08:05:25 -0700172 size_t len;
173 keymaster_algorithm_t* algorithms;
174 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_algorithms(device(), &algorithms, &len));
175 ASSERT_EQ(4U, len);
176 EXPECT_EQ(KM_ALGORITHM_RSA, algorithms[0]);
177 EXPECT_EQ(KM_ALGORITHM_DSA, algorithms[1]);
178 EXPECT_EQ(KM_ALGORITHM_ECDSA, algorithms[2]);
179 EXPECT_EQ(KM_ALGORITHM_AES, algorithms[3]);
180
181 free(algorithms);
Shawn Willden128ffe02014-08-06 12:31:33 -0600182}
183
184TEST_F(CheckSupported, SupportedBlockModes) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700185 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
186 device()->get_supported_block_modes(device(), KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT,
187 NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600188
Shawn Willden5b53c992015-02-02 08:05:25 -0700189 size_t len;
190 keymaster_block_mode_t* modes;
191 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE,
192 device()->get_supported_block_modes(device(), KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT,
193 &modes, &len));
Shawn Willden128ffe02014-08-06 12:31:33 -0600194
Shawn Willden5b53c992015-02-02 08:05:25 -0700195 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE,
196 device()->get_supported_block_modes(device(), KM_ALGORITHM_DSA, KM_PURPOSE_ENCRYPT,
197 &modes, &len));
Shawn Willden28e41472014-08-18 13:35:22 -0600198
Shawn Willden5b53c992015-02-02 08:05:25 -0700199 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE,
200 device()->get_supported_block_modes(device(), KM_ALGORITHM_ECDSA, KM_PURPOSE_ENCRYPT,
201 &modes, &len));
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600202
Shawn Willden5b53c992015-02-02 08:05:25 -0700203 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE,
204 device()->get_supported_block_modes(device(), KM_ALGORITHM_AES, KM_PURPOSE_ENCRYPT,
205 &modes, &len));
Shawn Willden128ffe02014-08-06 12:31:33 -0600206}
207
208TEST_F(CheckSupported, SupportedPaddingModes) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700209 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
210 device()->get_supported_padding_modes(device(), KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT,
211 NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600212
Shawn Willden5b53c992015-02-02 08:05:25 -0700213 size_t len;
214 keymaster_padding_t* modes;
215 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_RSA,
216 KM_PURPOSE_SIGN, &modes, &len));
217 ExpectContains(KM_PAD_NONE, modes, len);
218 free(modes);
Shawn Willden128ffe02014-08-06 12:31:33 -0600219
Shawn Willden5b53c992015-02-02 08:05:25 -0700220 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_DSA,
221 KM_PURPOSE_SIGN, &modes, &len));
222 ExpectContains(KM_PAD_NONE, modes, len);
223 free(modes);
Shawn Willden28e41472014-08-18 13:35:22 -0600224
Shawn Willden5b53c992015-02-02 08:05:25 -0700225 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_ECDSA,
226 KM_PURPOSE_SIGN, &modes, &len));
227 ExpectContains(KM_PAD_NONE, modes, len);
228 free(modes);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600229
Shawn Willden5b53c992015-02-02 08:05:25 -0700230 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_AES,
231 KM_PURPOSE_SIGN, &modes, &len));
232 EXPECT_EQ(0, len);
233 free(modes);
Shawn Willden128ffe02014-08-06 12:31:33 -0600234}
235
236TEST_F(CheckSupported, SupportedDigests) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700237 EXPECT_EQ(
238 KM_ERROR_OUTPUT_PARAMETER_NULL,
239 device()->get_supported_digests(device(), KM_ALGORITHM_RSA, KM_PURPOSE_SIGN, NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600240
Shawn Willden5b53c992015-02-02 08:05:25 -0700241 size_t len;
242 keymaster_digest_t* digests;
243 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_RSA,
244 KM_PURPOSE_SIGN, &digests, &len));
245 ExpectContains(KM_DIGEST_NONE, digests, len);
246 free(digests);
Shawn Willden128ffe02014-08-06 12:31:33 -0600247
Shawn Willden5b53c992015-02-02 08:05:25 -0700248 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_DSA,
249 KM_PURPOSE_SIGN, &digests, &len));
250 ExpectContains(KM_DIGEST_NONE, digests, len);
251 free(digests);
Shawn Willden28e41472014-08-18 13:35:22 -0600252
Shawn Willden5b53c992015-02-02 08:05:25 -0700253 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_ECDSA,
254 KM_PURPOSE_SIGN, &digests, &len));
255 ExpectContains(KM_DIGEST_NONE, digests, len);
256 free(digests);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600257
Shawn Willden5b53c992015-02-02 08:05:25 -0700258 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_AES,
259 KM_PURPOSE_SIGN, &digests, &len));
260 EXPECT_EQ(0, len);
261 free(digests);
Shawn Willden128ffe02014-08-06 12:31:33 -0600262}
263
264TEST_F(CheckSupported, SupportedImportFormats) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700265 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
266 device()->get_supported_import_formats(device(), KM_ALGORITHM_RSA, NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600267
Shawn Willden5b53c992015-02-02 08:05:25 -0700268 size_t len;
269 keymaster_key_format_t* formats;
270 EXPECT_EQ(KM_ERROR_OK,
271 device()->get_supported_import_formats(device(), KM_ALGORITHM_RSA, &formats, &len));
272 ExpectContains(KM_KEY_FORMAT_PKCS8, formats, len);
273 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600274
Shawn Willden5b53c992015-02-02 08:05:25 -0700275 EXPECT_EQ(KM_ERROR_OK,
276 device()->get_supported_import_formats(device(), KM_ALGORITHM_DSA, &formats, &len));
277 ExpectContains(KM_KEY_FORMAT_PKCS8, formats, len);
278 free(formats);
Shawn Willden28e41472014-08-18 13:35:22 -0600279
Shawn Willden5b53c992015-02-02 08:05:25 -0700280 EXPECT_EQ(KM_ERROR_OK,
281 device()->get_supported_import_formats(device(), KM_ALGORITHM_ECDSA, &formats, &len));
282 ExpectContains(KM_KEY_FORMAT_PKCS8, formats, len);
283 free(formats);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600284
Shawn Willden5b53c992015-02-02 08:05:25 -0700285 EXPECT_EQ(KM_ERROR_OK,
286 device()->get_supported_import_formats(device(), KM_ALGORITHM_AES, &formats, &len));
287 EXPECT_EQ(0, len);
288 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600289}
290
291TEST_F(CheckSupported, SupportedExportFormats) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700292 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
293 device()->get_supported_export_formats(device(), KM_ALGORITHM_RSA, NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600294
Shawn Willden5b53c992015-02-02 08:05:25 -0700295 size_t len;
296 keymaster_key_format_t* formats;
297 EXPECT_EQ(KM_ERROR_OK,
298 device()->get_supported_export_formats(device(), KM_ALGORITHM_RSA, &formats, &len));
299 ExpectContains(KM_KEY_FORMAT_X509, formats, len);
300 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600301
Shawn Willden5b53c992015-02-02 08:05:25 -0700302 EXPECT_EQ(KM_ERROR_OK,
303 device()->get_supported_export_formats(device(), KM_ALGORITHM_DSA, &formats, &len));
304 ExpectContains(KM_KEY_FORMAT_X509, formats, len);
305 free(formats);
Shawn Willden28e41472014-08-18 13:35:22 -0600306
Shawn Willden5b53c992015-02-02 08:05:25 -0700307 EXPECT_EQ(KM_ERROR_OK,
308 device()->get_supported_export_formats(device(), KM_ALGORITHM_ECDSA, &formats, &len));
309 ExpectContains(KM_KEY_FORMAT_X509, formats, len);
310 free(formats);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600311
Shawn Willden5b53c992015-02-02 08:05:25 -0700312 EXPECT_EQ(KM_ERROR_OK,
313 device()->get_supported_export_formats(device(), KM_ALGORITHM_AES, &formats, &len));
314 EXPECT_EQ(0, len);
315 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600316}
317
Shawn Willdend0772312014-09-18 12:27:57 -0600318keymaster_key_param_t key_generation_base_params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700319 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
320 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
Shawn Willdend0772312014-09-18 12:27:57 -0600321 Authorization(TAG_APPLICATION_ID, "app_id", 6),
Shawn Willden3809b932014-12-02 06:59:46 -0700322 Authorization(TAG_APPLICATION_DATA, "app_data", 8), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willdend0772312014-09-18 12:27:57 -0600323};
324
Shawn Willden5b53c992015-02-02 08:05:25 -0700325TEST_F(KeymasterTest, TestFlags) {
326 EXPECT_TRUE(device()->flags & KEYMASTER_SOFTWARE_ONLY);
327 EXPECT_TRUE(device()->flags & KEYMASTER_BLOBS_ARE_STANDALONE);
328 EXPECT_FALSE(device()->flags & KEYMASTER_SUPPORTS_DSA);
329 EXPECT_TRUE(device()->flags & KEYMASTER_SUPPORTS_EC);
330}
331
332typedef KeymasterTest OldKeyGeneration;
333
334TEST_F(OldKeyGeneration, Rsa) {
335 keymaster_rsa_keygen_params_t params = {.modulus_size = 256, .public_exponent = 3};
336 uint8_t* key_blob;
337 size_t key_blob_length;
338 EXPECT_EQ(0,
339 device()->generate_keypair(device(), TYPE_RSA, &params, &key_blob, &key_blob_length));
340 EXPECT_GT(key_blob_length, 0);
341
342 free(key_blob);
343}
344
345TEST_F(OldKeyGeneration, Ecdsa) {
346
347 keymaster_ec_keygen_params_t params = {.field_size = 256};
348 uint8_t* key_blob;
349 size_t key_blob_length;
350 EXPECT_EQ(0,
351 device()->generate_keypair(device(), TYPE_EC, &params, &key_blob, &key_blob_length));
352 EXPECT_GT(key_blob_length, 0);
353
354 free(key_blob);
355}
356
Shawn Willdend0772312014-09-18 12:27:57 -0600357class NewKeyGeneration : public KeymasterTest {
358 protected:
359 NewKeyGeneration() {
Shawn Willden5b53c992015-02-02 08:05:25 -0700360 params_.Reinitialize(key_generation_base_params, array_length(key_generation_base_params));
Shawn Willdend0772312014-09-18 12:27:57 -0600361 }
362
Shawn Willden5b53c992015-02-02 08:05:25 -0700363 void CheckBaseParams(const AuthorizationSet& auths) {
364 EXPECT_TRUE(contains(auths, TAG_PURPOSE, KM_PURPOSE_SIGN));
365 EXPECT_TRUE(contains(auths, TAG_PURPOSE, KM_PURPOSE_VERIFY));
366 EXPECT_TRUE(contains(auths, TAG_USER_ID, 7));
367 EXPECT_TRUE(contains(auths, TAG_USER_AUTH_ID, 8));
368 EXPECT_TRUE(contains(auths, TAG_AUTH_TIMEOUT, 300));
Shawn Willdend0772312014-09-18 12:27:57 -0600369
370 // Verify that App ID, App data and ROT are NOT included.
Shawn Willden5b53c992015-02-02 08:05:25 -0700371 EXPECT_FALSE(contains(auths, TAG_ROOT_OF_TRUST));
372 EXPECT_FALSE(contains(auths, TAG_APPLICATION_ID));
373 EXPECT_FALSE(contains(auths, TAG_APPLICATION_DATA));
Shawn Willdend0772312014-09-18 12:27:57 -0600374
375 // Just for giggles, check that some unexpected tags/values are NOT present.
Shawn Willden5b53c992015-02-02 08:05:25 -0700376 EXPECT_FALSE(contains(auths, TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
377 EXPECT_FALSE(contains(auths, TAG_PURPOSE, KM_PURPOSE_DECRYPT));
378 EXPECT_FALSE(contains(auths, TAG_AUTH_TIMEOUT, 301));
Shawn Willdend0772312014-09-18 12:27:57 -0600379
380 // Now check that unspecified, defaulted tags are correct.
Shawn Willden5b53c992015-02-02 08:05:25 -0700381 EXPECT_TRUE(contains(auths, TAG_ORIGIN, KM_ORIGIN_SOFTWARE));
382 EXPECT_TRUE(contains(auths, KM_TAG_CREATION_DATETIME));
Shawn Willdend0772312014-09-18 12:27:57 -0600383 }
Shawn Willden2079ae82015-01-22 13:42:31 -0700384};
385
Shawn Willden5b53c992015-02-02 08:05:25 -0700386struct ParamListDelete {
387 void operator()(keymaster_key_param_set_t* p) { keymaster_free_param_set(p); }
388};
389
390typedef UniquePtr<keymaster_key_param_set_t, ParamListDelete> UniqueParamSetPtr;
391
Shawn Willden128ffe02014-08-06 12:31:33 -0600392TEST_F(NewKeyGeneration, Rsa) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700393 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA));
394 params_.push_back(Authorization(TAG_KEY_SIZE, 256));
395 params_.push_back(Authorization(TAG_RSA_PUBLIC_EXPONENT, 3));
396 ASSERT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(), &blob_,
397 &characteristics_));
398 EXPECT_EQ(0U, characteristics_->hw_enforced.length);
399 AuthorizationSet auths(characteristics_->sw_enforced);
400 CheckBaseParams(auths);
Shawn Willden128ffe02014-08-06 12:31:33 -0600401
Shawn Willden5b53c992015-02-02 08:05:25 -0700402 // Check specified tags are all present in auths
403 EXPECT_TRUE(contains(auths, TAG_ALGORITHM, KM_ALGORITHM_RSA));
404 EXPECT_TRUE(contains(auths, TAG_KEY_SIZE, 256));
405 EXPECT_TRUE(contains(auths, TAG_RSA_PUBLIC_EXPONENT, 3));
Shawn Willden128ffe02014-08-06 12:31:33 -0600406}
407
Shawn Willden6bbe6782014-09-18 11:26:15 -0600408TEST_F(NewKeyGeneration, RsaDefaultSize) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700409 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA));
410 ASSERT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(), &blob_,
411 &characteristics_));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600412
Shawn Willden5b53c992015-02-02 08:05:25 -0700413 EXPECT_EQ(0U, characteristics_->hw_enforced.length);
414 AuthorizationSet auths(characteristics_->sw_enforced);
415 CheckBaseParams(auths);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600416
Shawn Willden5b53c992015-02-02 08:05:25 -0700417 // Check specified tags are all present in auths
418 EXPECT_TRUE(contains(auths, TAG_ALGORITHM, KM_ALGORITHM_RSA));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600419
420 // Now check that unspecified, defaulted tags are correct.
Shawn Willden5b53c992015-02-02 08:05:25 -0700421 EXPECT_TRUE(contains(auths, TAG_RSA_PUBLIC_EXPONENT, 65537));
422 EXPECT_TRUE(contains(auths, TAG_KEY_SIZE, 2048));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600423}
424
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600425TEST_F(NewKeyGeneration, Ecdsa) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700426 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
427 params_.push_back(Authorization(TAG_KEY_SIZE, 224));
428 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(), &blob_,
429 &characteristics_));
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600430
Shawn Willden5b53c992015-02-02 08:05:25 -0700431 EXPECT_EQ(0U, characteristics_->hw_enforced.length);
432 AuthorizationSet auths(characteristics_->sw_enforced);
433 CheckBaseParams(auths);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600434
Shawn Willden5b53c992015-02-02 08:05:25 -0700435 // Check specified tags are all present in auths characteristics
436 EXPECT_TRUE(contains(auths, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
437 EXPECT_TRUE(contains(auths, TAG_KEY_SIZE, 224));
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600438}
439
Shawn Willden6bbe6782014-09-18 11:26:15 -0600440TEST_F(NewKeyGeneration, EcdsaDefaultSize) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700441 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
442 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(), &blob_,
443 &characteristics_));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600444
Shawn Willden5b53c992015-02-02 08:05:25 -0700445 EXPECT_EQ(0U, characteristics_->hw_enforced.length);
446 AuthorizationSet auths(characteristics_->sw_enforced);
447 CheckBaseParams(auths);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600448
Shawn Willden5b53c992015-02-02 08:05:25 -0700449 // Check specified tags are all present in auths
450 EXPECT_TRUE(contains(auths, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600451
452 // Now check that unspecified, defaulted tags are correct.
Shawn Willden5b53c992015-02-02 08:05:25 -0700453 EXPECT_TRUE(contains(auths, TAG_KEY_SIZE, 224));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600454}
455
456TEST_F(NewKeyGeneration, EcdsaInvalidSize) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700457 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
458 params_.push_back(Authorization(TAG_KEY_SIZE, 190));
459 EXPECT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE,
460 device()->generate_key(device(), params_.data(), params_.size(), &blob_,
461 &characteristics_));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600462}
463
464TEST_F(NewKeyGeneration, EcdsaAllValidSizes) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600465 size_t valid_sizes[] = {224, 256, 384, 521};
Shawn Willden6bbe6782014-09-18 11:26:15 -0600466 for (size_t size : valid_sizes) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700467 params_.Reinitialize(key_generation_base_params, array_length(key_generation_base_params));
468 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
469 params_.push_back(Authorization(TAG_KEY_SIZE, size));
470 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(),
471 &blob_, &characteristics_))
472 << "Failed to generate size: " << size;
473
474 FreeCharacteristics();
475 FreeKeyBlob();
Shawn Willden6bbe6782014-09-18 11:26:15 -0600476 }
477}
478
Shawn Willden19fca882015-01-22 16:35:30 -0700479TEST_F(NewKeyGeneration, AesOcb) {
480 keymaster_key_param_t params[] = {
481 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
482 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
483 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
484 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_CHUNK_LENGTH, 4096),
Shawn Willden7efb8782014-12-11 14:07:44 -0700485 Authorization(TAG_MAC_LENGTH, 16), Authorization(TAG_PADDING, KM_PAD_NONE),
Shawn Willden19fca882015-01-22 16:35:30 -0700486 };
Shawn Willden5b53c992015-02-02 08:05:25 -0700487 params_.Reinitialize(params, array_length(params));
488 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(), &blob_,
489 &characteristics_));
Shawn Willden19fca882015-01-22 16:35:30 -0700490}
491
492TEST_F(NewKeyGeneration, AesOcbInvalidKeySize) {
493 keymaster_key_param_t params[] = {
494 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
495 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
Shawn Willden95e13822014-12-15 16:12:16 -0700496 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 136),
Shawn Willden19fca882015-01-22 16:35:30 -0700497 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_CHUNK_LENGTH, 4096),
Shawn Willden7efb8782014-12-11 14:07:44 -0700498 Authorization(TAG_MAC_LENGTH, 16), Authorization(TAG_PADDING, KM_PAD_NONE),
Shawn Willden19fca882015-01-22 16:35:30 -0700499 };
Shawn Willden5b53c992015-02-02 08:05:25 -0700500 params_.Reinitialize(params, array_length(params));
Shawn Willden95e13822014-12-15 16:12:16 -0700501 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(), &blob_,
502 &characteristics_));
503
504 keymaster_key_param_t* out_params;
505 size_t out_params_count;
506 uint64_t op_handle;
Shawn Willden5b53c992015-02-02 08:05:25 -0700507 EXPECT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE,
Shawn Willden95e13822014-12-15 16:12:16 -0700508 device()->begin(device(), KM_PURPOSE_ENCRYPT, &blob_, NULL, 0, &out_params,
509 &out_params_count, &op_handle));
510 free(out_params);
Shawn Willden19fca882015-01-22 16:35:30 -0700511}
512
513TEST_F(NewKeyGeneration, AesOcbAllValidSizes) {
514 keymaster_key_param_t params[] = {
515 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
516 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
Shawn Willden7efb8782014-12-11 14:07:44 -0700517 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_BLOCK_MODE, KM_MODE_OCB),
518 Authorization(TAG_MAC_LENGTH, 16), Authorization(TAG_CHUNK_LENGTH, 4096),
Shawn Willden19fca882015-01-22 16:35:30 -0700519 Authorization(TAG_PADDING, KM_PAD_NONE),
520 };
521
522 size_t valid_sizes[] = {128, 192, 256};
523 for (size_t size : valid_sizes) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700524 params_.Reinitialize(params, array_length(params));
525 params_.push_back(Authorization(TAG_KEY_SIZE, size));
Shawn Willden95e13822014-12-15 16:12:16 -0700526 FreeCharacteristics();
527 FreeKeyBlob();
528
Shawn Willden5b53c992015-02-02 08:05:25 -0700529 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(),
530 &blob_, &characteristics_))
531 << "Failed to generate size: " << size;
532
Shawn Willden95e13822014-12-15 16:12:16 -0700533 keymaster_key_param_t* out_params;
534 size_t out_params_count;
535 uint64_t op_handle;
536 EXPECT_EQ(KM_ERROR_OK, device()->begin(device(), KM_PURPOSE_ENCRYPT, &blob_, NULL, 0,
537 &out_params, &out_params_count, &op_handle))
538 << "Unsupported key size: " << size;
539 free(out_params);
Shawn Willden19fca882015-01-22 16:35:30 -0700540 }
541}
542
Shawn Willden0d560bf2014-12-15 17:44:02 -0700543TEST_F(NewKeyGeneration, HmacSha256) {
544 keymaster_key_param_t params[] = {
545 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
546 Authorization(TAG_ALGORITHM, KM_ALGORITHM_HMAC), Authorization(TAG_KEY_SIZE, 128),
547 Authorization(TAG_MAC_LENGTH, 16), Authorization(TAG_DIGEST, KM_DIGEST_SHA_2_256),
548 };
549 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params, array_length(params), &blob_,
550 &characteristics_));
551}
552
Shawn Willden76364712014-08-11 17:48:04 -0600553typedef KeymasterTest GetKeyCharacteristics;
554TEST_F(GetKeyCharacteristics, SimpleRsa) {
555 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700556 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
557 Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), Authorization(TAG_KEY_SIZE, 256),
558 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
559 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden76364712014-08-11 17:48:04 -0600560 };
561
Shawn Willden5b53c992015-02-02 08:05:25 -0700562 ASSERT_EQ(KM_ERROR_OK, device()->generate_key(device(), params, array_length(params), &blob_,
563 &characteristics_));
564 AuthorizationSet original(characteristics_->sw_enforced);
565 FreeCharacteristics();
Shawn Willden76364712014-08-11 17:48:04 -0600566
Shawn Willden5b53c992015-02-02 08:05:25 -0700567 keymaster_blob_t client_id = {.data = reinterpret_cast<const uint8_t*>("app_id"),
568 .data_length = 6};
569 ASSERT_EQ(KM_ERROR_OK,
570 device()->get_key_characteristics(device(), &blob_, &client_id, NULL /* app_data */,
571 &characteristics_));
572 EXPECT_EQ(original, AuthorizationSet(characteristics_->sw_enforced));
Shawn Willden76364712014-08-11 17:48:04 -0600573}
574
Shawn Willden61644f32014-08-18 13:43:14 -0600575/**
576 * Test class that provides some infrastructure for generating keys and signing messages.
577 */
Shawn Willden1615f2e2014-08-13 10:37:40 -0600578class SigningOperationsTest : public KeymasterTest {
579 protected:
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700580 SigningOperationsTest() {}
Shawn Willden5b53c992015-02-02 08:05:25 -0700581 ~SigningOperationsTest() {
582 // Clean up so (most) tests won't have to.
Shawn Willden5b53c992015-02-02 08:05:25 -0700583 FreeSignature();
584 }
585
Shawn Willden0d560bf2014-12-15 17:44:02 -0700586 // TODO(swillden): Refactor and move common test utils to KeymasterTest
587 using KeymasterTest::GenerateKey;
588
Shawn Willden61644f32014-08-18 13:43:14 -0600589 void GenerateKey(keymaster_algorithm_t algorithm, keymaster_digest_t digest,
590 keymaster_padding_t padding, uint32_t key_size) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700591 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));
592 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY));
593 params_.push_back(Authorization(TAG_ALGORITHM, algorithm));
594 params_.push_back(Authorization(TAG_KEY_SIZE, key_size));
595 params_.push_back(Authorization(TAG_USER_ID, 7));
596 params_.push_back(Authorization(TAG_USER_AUTH_ID, 8));
597 params_.push_back(Authorization(TAG_APPLICATION_ID, "app_id", 6));
598 params_.push_back(Authorization(TAG_AUTH_TIMEOUT, 300));
Shawn Willden43e999e2014-08-13 13:29:50 -0600599 if (static_cast<int>(digest) != -1)
Shawn Willden5b53c992015-02-02 08:05:25 -0700600 params_.push_back(TAG_DIGEST, digest);
Shawn Willden43e999e2014-08-13 13:29:50 -0600601 if (static_cast<int>(padding) != -1)
Shawn Willden5b53c992015-02-02 08:05:25 -0700602 params_.push_back(TAG_PADDING, padding);
603
604 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(),
605 &blob_, &characteristics_));
Shawn Willden61644f32014-08-18 13:43:14 -0600606 }
Shawn Willden1615f2e2014-08-13 10:37:40 -0600607
Shawn Willden61644f32014-08-18 13:43:14 -0600608 void SignMessage(const void* message, size_t size) {
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700609 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_SIGN, blob_));
610 string result;
611 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, size, &result, &input_consumed_));
612 EXPECT_EQ(0, result.length());
Shawn Willden5b53c992015-02-02 08:05:25 -0700613 EXPECT_EQ(size, input_consumed_);
614
615 EXPECT_EQ(KM_ERROR_OK,
616 device()->finish(device(), op_handle_, NULL /* signature to verify */,
617 0 /* signature to verify length */, &signature_,
618 &signature_length_));
619 EXPECT_GT(signature_length_, 0);
Shawn Willden437fbd12014-08-20 11:59:49 -0600620 }
621
Shawn Willden5b53c992015-02-02 08:05:25 -0700622 void FreeSignature() {
623 free(signature_);
624 signature_ = NULL;
Shawn Willdenf268d742014-08-19 15:36:26 -0600625 }
626
Shawn Willden0d560bf2014-12-15 17:44:02 -0700627 const keymaster_key_blob_t& key_blob() { return blob_; }
628
Shawn Willden5b53c992015-02-02 08:05:25 -0700629 void corrupt_key_blob() {
630 uint8_t* tmp = const_cast<uint8_t*>(blob_.key_material);
631 ++tmp[blob_.key_material_size / 2];
Shawn Willden1615f2e2014-08-13 10:37:40 -0600632 }
Shawn Willden1615f2e2014-08-13 10:37:40 -0600633};
634
635TEST_F(SigningOperationsTest, RsaSuccess) {
Shawn Willden61644f32014-08-18 13:43:14 -0600636 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willdenffd790c2014-08-18 21:20:06 -0600637 const char message[] = "12345678901234567890123456789012";
Shawn Willdend05cba52014-09-26 09:58:12 -0600638 SignMessage(message, array_size(message) - 1);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600639}
640
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600641TEST_F(SigningOperationsTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600642 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willdend05cba52014-09-26 09:58:12 -0600643 const char message[] = "123456789012345678901234567890123456789012345678";
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700644 string signature;
Shawn Willdend05cba52014-09-26 09:58:12 -0600645 SignMessage(message, array_size(message) - 1);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600646}
647
Shawn Willden1615f2e2014-08-13 10:37:40 -0600648TEST_F(SigningOperationsTest, RsaAbort) {
Shawn Willden61644f32014-08-18 13:43:14 -0600649 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willden5b53c992015-02-02 08:05:25 -0700650 ASSERT_EQ(KM_ERROR_OK, device()->begin(device(), KM_PURPOSE_SIGN, &blob_, client_params_,
651 array_length(client_params_), &out_params_,
652 &out_params_count_, &op_handle_));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600653
Shawn Willden5b53c992015-02-02 08:05:25 -0700654 EXPECT_EQ(KM_ERROR_OK, device()->abort(device(), op_handle_));
655 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle_));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600656}
657
658TEST_F(SigningOperationsTest, RsaUnsupportedDigest) {
Shawn Willden61644f32014-08-18 13:43:14 -0600659 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_SHA_2_256, KM_PAD_NONE, 256 /* key size */);
Shawn Willden5b53c992015-02-02 08:05:25 -0700660 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST,
661 device()->begin(device(), KM_PURPOSE_SIGN, &blob_, client_params_,
662 array_length(client_params_), &out_params_, &out_params_count_,
663 &op_handle_));
664 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle_));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600665}
666
667TEST_F(SigningOperationsTest, RsaUnsupportedPadding) {
Shawn Willden61644f32014-08-18 13:43:14 -0600668 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_RSA_OAEP, 256 /* key size */);
Shawn Willden5b53c992015-02-02 08:05:25 -0700669 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE,
670 device()->begin(device(), KM_PURPOSE_SIGN, &blob_, client_params_,
671 array_length(client_params_), &out_params_, &out_params_count_,
672 &op_handle_));
673 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle_));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600674}
675
676TEST_F(SigningOperationsTest, RsaNoDigest) {
Shawn Willden61644f32014-08-18 13:43:14 -0600677 GenerateKey(KM_ALGORITHM_RSA, static_cast<keymaster_digest_t>(-1), KM_PAD_NONE,
678 256 /* key size */);
Shawn Willden5b53c992015-02-02 08:05:25 -0700679 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST,
680 device()->begin(device(), KM_PURPOSE_SIGN, &blob_, client_params_,
681 array_length(client_params_), &out_params_, &out_params_count_,
682 &op_handle_));
683 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle_));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600684}
685
686TEST_F(SigningOperationsTest, RsaNoPadding) {
Shawn Willden61644f32014-08-18 13:43:14 -0600687 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, static_cast<keymaster_padding_t>(-1),
688 256 /* key size */);
Shawn Willden5b53c992015-02-02 08:05:25 -0700689 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE,
690 device()->begin(device(), KM_PURPOSE_SIGN, &blob_, client_params_,
691 array_length(client_params_), &out_params_, &out_params_count_,
692 &op_handle_));
693 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle_));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600694}
695
Shawn Willden62c22862014-12-17 08:36:20 -0700696TEST_F(SigningOperationsTest, HmacSha224Success) {
697 keymaster_key_param_t params[] = {
698 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
699 Authorization(TAG_ALGORITHM, KM_ALGORITHM_HMAC), Authorization(TAG_KEY_SIZE, 128),
700 Authorization(TAG_MAC_LENGTH, 28), Authorization(TAG_DIGEST, KM_DIGEST_SHA_2_224),
701 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
702 Authorization(TAG_AUTH_TIMEOUT, 300),
703 };
704 params_.Reinitialize(params, array_length(params));
705 GenerateKey(&params_);
706 const char message[] = "12345678901234567890123456789012";
707 SignMessage(message, array_size(message) - 1);
708 ASSERT_EQ(28, signature_length_);
709}
710
Shawn Willden0d560bf2014-12-15 17:44:02 -0700711TEST_F(SigningOperationsTest, HmacSha256Success) {
712 keymaster_key_param_t params[] = {
713 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
714 Authorization(TAG_ALGORITHM, KM_ALGORITHM_HMAC), Authorization(TAG_KEY_SIZE, 128),
715 Authorization(TAG_MAC_LENGTH, 32), Authorization(TAG_DIGEST, KM_DIGEST_SHA_2_256),
716 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
717 Authorization(TAG_AUTH_TIMEOUT, 300),
718 };
719 params_.Reinitialize(params, array_length(params));
720 GenerateKey(&params_);
721 const char message[] = "12345678901234567890123456789012";
Shawn Willden0d560bf2014-12-15 17:44:02 -0700722 SignMessage(message, array_size(message) - 1);
723 ASSERT_EQ(32, signature_length_);
724}
725
Shawn Willden62c22862014-12-17 08:36:20 -0700726TEST_F(SigningOperationsTest, HmacSha384Success) {
727 keymaster_key_param_t params[] = {
728 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
729 Authorization(TAG_ALGORITHM, KM_ALGORITHM_HMAC), Authorization(TAG_KEY_SIZE, 128),
730 Authorization(TAG_MAC_LENGTH, 48), Authorization(TAG_DIGEST, KM_DIGEST_SHA_2_384),
731 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
732 Authorization(TAG_AUTH_TIMEOUT, 300),
733 };
734 params_.Reinitialize(params, array_length(params));
735 GenerateKey(&params_);
736 const char message[] = "12345678901234567890123456789012";
737 SignMessage(message, array_size(message) - 1);
738 ASSERT_EQ(48, signature_length_);
739}
740
741TEST_F(SigningOperationsTest, HmacSha512Success) {
742 keymaster_key_param_t params[] = {
743 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
744 Authorization(TAG_ALGORITHM, KM_ALGORITHM_HMAC), Authorization(TAG_KEY_SIZE, 128),
745 Authorization(TAG_MAC_LENGTH, 64), Authorization(TAG_DIGEST, KM_DIGEST_SHA_2_512),
746 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
747 Authorization(TAG_AUTH_TIMEOUT, 300),
748 };
749 params_.Reinitialize(params, array_length(params));
750 GenerateKey(&params_);
751 const char message[] = "12345678901234567890123456789012";
752 string signature;
753 SignMessage(message, array_size(message) - 1);
754 ASSERT_EQ(64, signature_length_);
755}
756
757// TODO(swillden): Add HMACSHA{224|256|384|512} tests that validates against the test vectors from
758// RFC4231. Doing that requires being able to import keys, rather than just
759// generate them randomly.
Shawn Willden0d560bf2014-12-15 17:44:02 -0700760
761TEST_F(SigningOperationsTest, HmacSha256NoTag) {
762 keymaster_key_param_t params[] = {
763 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
764 Authorization(TAG_ALGORITHM, KM_ALGORITHM_HMAC), Authorization(TAG_KEY_SIZE, 128),
765 Authorization(TAG_MAC_LENGTH, 16), Authorization(TAG_DIGEST, KM_DIGEST_SHA_2_256),
766 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
767 Authorization(TAG_AUTH_TIMEOUT, 300),
768 };
769 params_.Reinitialize(params, array_length(params));
770 GenerateKey(&params_);
771 const char message[] = "12345678901234567890123456789012";
772 string signature;
773 SignMessage(message, array_size(message) - 1);
774}
775
776TEST_F(SigningOperationsTest, HmacSha256TooLargeTag) {
777 keymaster_key_param_t params[] = {
778 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
779 Authorization(TAG_ALGORITHM, KM_ALGORITHM_HMAC), Authorization(TAG_KEY_SIZE, 128),
780 Authorization(TAG_MAC_LENGTH, 33), Authorization(TAG_DIGEST, KM_DIGEST_SHA_2_256),
781 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
782 Authorization(TAG_AUTH_TIMEOUT, 300),
783 };
784 params_.Reinitialize(params, array_length(params));
785 GenerateKey(&params_);
786 ASSERT_EQ(KM_ERROR_UNSUPPORTED_MAC_LENGTH, BeginOperation(KM_PURPOSE_SIGN, key_blob()));
787}
788
Shawn Willden1615f2e2014-08-13 10:37:40 -0600789TEST_F(SigningOperationsTest, RsaTooShortMessage) {
Shawn Willden61644f32014-08-18 13:43:14 -0600790 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700791 ASSERT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_SIGN, key_blob()));
792
793 const char message[] = "012345678901234567890123456789";
794 string result;
795 size_t input_consumed;
Shawn Willden5b53c992015-02-02 08:05:25 -0700796 ASSERT_EQ(KM_ERROR_OK,
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700797 UpdateOperation(message, array_length(message), &result, &input_consumed));
798 EXPECT_EQ(0U, result.size());
799 EXPECT_EQ(31U, input_consumed);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600800
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700801 string signature;
802 ASSERT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&signature));
803 EXPECT_EQ(0U, signature.length());
Shawn Willden43e999e2014-08-13 13:29:50 -0600804}
805
Shawn Willdend05cba52014-09-26 09:58:12 -0600806class VerificationOperationsTest : public SigningOperationsTest {
807 protected:
808 void VerifyMessage(const void* message, size_t message_len) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700809 EXPECT_TRUE(signature_ != NULL);
Shawn Willdend05cba52014-09-26 09:58:12 -0600810
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700811 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_VERIFY, blob_));
812 string output;
813 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, message_len, &output, &input_consumed_));
814 EXPECT_EQ(0U, output.size());
Shawn Willden5b53c992015-02-02 08:05:25 -0700815 EXPECT_EQ(message_len, input_consumed_);
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700816 output.clear();
817 EXPECT_EQ(KM_ERROR_OK, FinishOperation(&output));
818 EXPECT_EQ(0U, output.size());
Shawn Willdend05cba52014-09-26 09:58:12 -0600819
Shawn Willden5b53c992015-02-02 08:05:25 -0700820 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle_));
Shawn Willdend05cba52014-09-26 09:58:12 -0600821 }
822};
823
Shawn Willden43e999e2014-08-13 13:29:50 -0600824TEST_F(VerificationOperationsTest, RsaSuccess) {
Shawn Willden61644f32014-08-18 13:43:14 -0600825 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
826 const char message[] = "12345678901234567890123456789012";
827 SignMessage(message, array_size(message) - 1);
Shawn Willdend05cba52014-09-26 09:58:12 -0600828 VerifyMessage(message, array_size(message) - 1);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600829}
830
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600831TEST_F(VerificationOperationsTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600832 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600833 const char message[] = "123456789012345678901234567890123456789012345678";
834 SignMessage(message, array_size(message) - 1);
Shawn Willdend05cba52014-09-26 09:58:12 -0600835 VerifyMessage(message, array_size(message) - 1);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600836}
837
Shawn Willden0d560bf2014-12-15 17:44:02 -0700838TEST_F(VerificationOperationsTest, HmacSha256Success) {
839 keymaster_key_param_t params[] = {
840 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
841 Authorization(TAG_ALGORITHM, KM_ALGORITHM_HMAC), Authorization(TAG_KEY_SIZE, 128),
842 Authorization(TAG_MAC_LENGTH, 16), Authorization(TAG_DIGEST, KM_DIGEST_SHA_2_256),
843 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
844 Authorization(TAG_AUTH_TIMEOUT, 300),
845 };
846 params_.Reinitialize(params, array_length(params));
847 GenerateKey(&params_);
848 const char message[] = "123456789012345678901234567890123456789012345678";
849 string signature;
850 SignMessage(message, array_size(message) - 1);
851 VerifyMessage(message, array_size(message) - 1);
852}
853
Shawn Willden5b53c992015-02-02 08:05:25 -0700854typedef VerificationOperationsTest ExportKeyTest;
Shawn Willdenffd790c2014-08-18 21:20:06 -0600855TEST_F(ExportKeyTest, RsaSuccess) {
856 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willdenffd790c2014-08-18 21:20:06 -0600857
Shawn Willden5b53c992015-02-02 08:05:25 -0700858 uint8_t* export_data;
859 size_t export_data_length;
860 ASSERT_EQ(KM_ERROR_OK,
861 device()->export_key(device(), KM_KEY_FORMAT_X509, &blob_, &client_id_,
862 NULL /* app_data */, &export_data, &export_data_length));
863 EXPECT_TRUE(export_data != NULL);
864 EXPECT_GT(export_data_length, 0);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600865
866 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willden5b53c992015-02-02 08:05:25 -0700867 free(export_data);
Shawn Willdenffd790c2014-08-18 21:20:06 -0600868}
869
Shawn Willdenf268d742014-08-19 15:36:26 -0600870TEST_F(ExportKeyTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600871 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willdenf268d742014-08-19 15:36:26 -0600872
Shawn Willden5b53c992015-02-02 08:05:25 -0700873 uint8_t* export_data;
874 size_t export_data_length;
875 ASSERT_EQ(KM_ERROR_OK,
876 device()->export_key(device(), KM_KEY_FORMAT_X509, &blob_, &client_id_,
877 NULL /* app_data */, &export_data, &export_data_length));
878 EXPECT_TRUE(export_data != NULL);
879 EXPECT_GT(export_data_length, 0);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600880
881 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willden5b53c992015-02-02 08:05:25 -0700882 free(export_data);
Shawn Willdenf268d742014-08-19 15:36:26 -0600883}
884
885TEST_F(ExportKeyTest, RsaUnsupportedKeyFormat) {
886 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256);
887
Shawn Willden5b53c992015-02-02 08:05:25 -0700888 uint8_t dummy[] = {1};
889 uint8_t* export_data = dummy; // So it's not NULL;
890 size_t export_data_length;
891 ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_FORMAT,
892 device()->export_key(device(), KM_KEY_FORMAT_PKCS8, &blob_, &client_id_,
893 NULL /* app_data */, &export_data, &export_data_length));
894 ASSERT_TRUE(export_data == NULL);
Shawn Willdenf268d742014-08-19 15:36:26 -0600895}
896
897TEST_F(ExportKeyTest, RsaCorruptedKeyBlob) {
898 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256);
Shawn Willden5b53c992015-02-02 08:05:25 -0700899 corrupt_key_blob();
Shawn Willdenf268d742014-08-19 15:36:26 -0600900
Shawn Willden5b53c992015-02-02 08:05:25 -0700901 uint8_t dummy[] = {1};
902 uint8_t* export_data = dummy; // So it's not NULL
903 size_t export_data_length;
904 ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB,
905 device()->export_key(device(), KM_KEY_FORMAT_X509, &blob_, &client_id_,
906 NULL /* app_data */, &export_data, &export_data_length));
907 ASSERT_TRUE(export_data == NULL);
Shawn Willdenf268d742014-08-19 15:36:26 -0600908}
909
Shawn Willden437fbd12014-08-20 11:59:49 -0600910static string read_file(const string& file_name) {
911 ifstream file_stream(file_name, std::ios::binary);
912 istreambuf_iterator<char> file_begin(file_stream);
913 istreambuf_iterator<char> file_end;
914 return string(file_begin, file_end);
915}
916
Shawn Willden5b53c992015-02-02 08:05:25 -0700917class ImportKeyTest : public VerificationOperationsTest {
918 protected:
919 ImportKeyTest() {
920 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));
921 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY));
922 params_.push_back(Authorization(TAG_DIGEST, KM_DIGEST_NONE));
923 params_.push_back(Authorization(TAG_PADDING, KM_PAD_NONE));
924 params_.push_back(Authorization(TAG_USER_ID, 7));
925 params_.push_back(Authorization(TAG_USER_AUTH_ID, 8));
926 params_.push_back(Authorization(TAG_APPLICATION_ID, "app_id", 6));
927 params_.push_back(Authorization(TAG_AUTH_TIMEOUT, 300));
928 }
929};
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800930
Shawn Willden5b53c992015-02-02 08:05:25 -0700931TEST_F(ImportKeyTest, RsaSuccess) {
Shawn Willden81effc62014-08-27 10:08:46 -0600932 string pk8_key = read_file("rsa_privkey_pk8.der");
Shawn Willden437fbd12014-08-20 11:59:49 -0600933 ASSERT_EQ(633U, pk8_key.size());
934
Shawn Willden5b53c992015-02-02 08:05:25 -0700935 ASSERT_EQ(KM_ERROR_OK,
936 device()->import_key(device(), params_.data(), params_.size(), KM_KEY_FORMAT_PKCS8,
937 reinterpret_cast<const uint8_t*>(pk8_key.data()), pk8_key.size(),
938 &blob_, &characteristics_));
939 EXPECT_EQ(0U, characteristics_->hw_enforced.length);
940 AuthorizationSet auths(characteristics_->sw_enforced);
Shawn Willden437fbd12014-08-20 11:59:49 -0600941
942 // Check values derived from the key.
Shawn Willden5b53c992015-02-02 08:05:25 -0700943 EXPECT_TRUE(contains(auths, TAG_ALGORITHM, KM_ALGORITHM_RSA));
944 EXPECT_TRUE(contains(auths, TAG_KEY_SIZE, 1024));
945 EXPECT_TRUE(contains(auths, TAG_RSA_PUBLIC_EXPONENT, 65537U));
Shawn Willden437fbd12014-08-20 11:59:49 -0600946
947 // And values provided by GoogleKeymaster
Shawn Willden5b53c992015-02-02 08:05:25 -0700948 EXPECT_TRUE(contains(auths, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
949 EXPECT_TRUE(contains(auths, KM_TAG_CREATION_DATETIME));
Shawn Willden437fbd12014-08-20 11:59:49 -0600950
951 size_t message_len = 1024 / 8;
952 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
953 std::fill(message.get(), message.get() + message_len, 'a');
Shawn Willden5b53c992015-02-02 08:05:25 -0700954 SignMessage(message.get(), message_len);
955 VerifyMessage(message.get(), message_len);
Shawn Willden437fbd12014-08-20 11:59:49 -0600956}
957
Shawn Willden6bbe6782014-09-18 11:26:15 -0600958TEST_F(ImportKeyTest, RsaKeySizeMismatch) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700959 params_.push_back(Authorization(TAG_KEY_SIZE, 2048)); // Doesn't match key
Shawn Willden6bbe6782014-09-18 11:26:15 -0600960
961 string pk8_key = read_file("rsa_privkey_pk8.der");
962 ASSERT_EQ(633U, pk8_key.size());
963
Shawn Willden5b53c992015-02-02 08:05:25 -0700964 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
965 device()->import_key(device(), params_.data(), params_.size(), KM_KEY_FORMAT_PKCS8,
966 reinterpret_cast<const uint8_t*>(pk8_key.data()), pk8_key.size(),
967 &blob_, &characteristics_));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600968}
969
970TEST_F(ImportKeyTest, RsaPublicExponenMismatch) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700971 params_.push_back(Authorization(TAG_RSA_PUBLIC_EXPONENT, 3)); // Doesn't match key
Shawn Willden6bbe6782014-09-18 11:26:15 -0600972
973 string pk8_key = read_file("rsa_privkey_pk8.der");
974 ASSERT_EQ(633U, pk8_key.size());
975
Shawn Willden5b53c992015-02-02 08:05:25 -0700976 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
977 device()->import_key(device(), params_.data(), params_.size(), KM_KEY_FORMAT_PKCS8,
978 reinterpret_cast<const uint8_t*>(pk8_key.data()), pk8_key.size(),
979 &blob_, &characteristics_));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600980}
981
Shawn Willden81effc62014-08-27 10:08:46 -0600982TEST_F(ImportKeyTest, EcdsaSuccess) {
Shawn Willden81effc62014-08-27 10:08:46 -0600983 string pk8_key = read_file("ec_privkey_pk8.der");
984 ASSERT_EQ(138U, pk8_key.size());
985
Shawn Willden5b53c992015-02-02 08:05:25 -0700986 ASSERT_EQ(KM_ERROR_OK,
987 device()->import_key(device(), params_.data(), params_.size(), KM_KEY_FORMAT_PKCS8,
988 reinterpret_cast<const uint8_t*>(pk8_key.data()), pk8_key.size(),
989 &blob_, &characteristics_));
990 EXPECT_EQ(0U, characteristics_->hw_enforced.length);
991 AuthorizationSet auths(characteristics_->sw_enforced);
Shawn Willden81effc62014-08-27 10:08:46 -0600992
993 // Check values derived from the key.
Shawn Willden5b53c992015-02-02 08:05:25 -0700994 EXPECT_TRUE(contains(auths, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
995 EXPECT_TRUE(contains(auths, TAG_KEY_SIZE, 256));
Shawn Willden81effc62014-08-27 10:08:46 -0600996
997 // And values provided by GoogleKeymaster
Shawn Willden5b53c992015-02-02 08:05:25 -0700998 EXPECT_TRUE(contains(auths, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
999 EXPECT_TRUE(contains(auths, KM_TAG_CREATION_DATETIME));
Shawn Willden81effc62014-08-27 10:08:46 -06001000
Shawn Willden5b53c992015-02-02 08:05:25 -07001001 size_t message_len = 1024;
Shawn Willden81effc62014-08-27 10:08:46 -06001002 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
1003 std::fill(message.get(), message.get() + message_len, 'a');
Shawn Willden5b53c992015-02-02 08:05:25 -07001004 SignMessage(message.get(), message_len);
1005 VerifyMessage(message.get(), message_len);
Shawn Willden81effc62014-08-27 10:08:46 -06001006}
1007
Shawn Willden5b53c992015-02-02 08:05:25 -07001008TEST_F(ImportKeyTest, EcdsaKeySizeMismatch) {
1009 params_.push_back(Authorization(TAG_KEY_SIZE, 224)); // Doesn't match key
Shawn Willden6bbe6782014-09-18 11:26:15 -06001010
Shawn Willden5b53c992015-02-02 08:05:25 -07001011 string pk8_key = read_file("rsa_privkey_pk8.der");
1012 ASSERT_EQ(633U, pk8_key.size());
Shawn Willden6bbe6782014-09-18 11:26:15 -06001013
Shawn Willden5b53c992015-02-02 08:05:25 -07001014 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
1015 device()->import_key(device(), params_.data(), params_.size(), KM_KEY_FORMAT_PKCS8,
1016 reinterpret_cast<const uint8_t*>(pk8_key.data()), pk8_key.size(),
1017 &blob_, &characteristics_));
Shawn Willden6bbe6782014-09-18 11:26:15 -06001018}
1019
Shawn Willden2665e862014-11-24 14:46:21 -07001020typedef KeymasterTest VersionTest;
1021TEST_F(VersionTest, GetVersion) {
1022 GetVersionRequest req;
1023 GetVersionResponse rsp;
Shawn Willden5b53c992015-02-02 08:05:25 -07001024 device_.GetVersion(req, &rsp);
Shawn Willden2665e862014-11-24 14:46:21 -07001025 EXPECT_EQ(KM_ERROR_OK, rsp.error);
1026 EXPECT_EQ(1, rsp.major_ver);
1027 EXPECT_EQ(0, rsp.minor_ver);
1028 EXPECT_EQ(0, rsp.subminor_ver);
1029}
1030
Shawn Willden4200f212014-12-02 07:01:21 -07001031/**
1032 * Test class that provides some infrastructure for generating keys and encrypting messages.
1033 */
1034class EncryptionOperationsTest : public KeymasterTest {
1035 protected:
Shawn Willden0d560bf2014-12-15 17:44:02 -07001036 // TODO(swillden): Refactor and move common test utils to KeymasterTest
1037 using KeymasterTest::GenerateKey;
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001038
Shawn Willden4200f212014-12-02 07:01:21 -07001039 void GenerateKey(keymaster_algorithm_t algorithm, keymaster_padding_t padding,
1040 uint32_t key_size) {
Shawn Willden6dde87c2014-12-11 14:08:48 -07001041 params_.Clear();
Shawn Willden5b53c992015-02-02 08:05:25 -07001042 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
1043 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT));
1044 params_.push_back(Authorization(TAG_ALGORITHM, algorithm));
1045 params_.push_back(Authorization(TAG_KEY_SIZE, key_size));
1046 params_.push_back(Authorization(TAG_USER_ID, 7));
1047 params_.push_back(Authorization(TAG_USER_AUTH_ID, 8));
Shawn Willden5b53c992015-02-02 08:05:25 -07001048 params_.push_back(Authorization(TAG_AUTH_TIMEOUT, 300));
Shawn Willden4200f212014-12-02 07:01:21 -07001049 if (static_cast<int>(padding) != -1)
Shawn Willden5b53c992015-02-02 08:05:25 -07001050 params_.push_back(TAG_PADDING, padding);
Shawn Willden6dde87c2014-12-11 14:08:48 -07001051
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001052 GenerateKey(&params_);
Shawn Willden4200f212014-12-02 07:01:21 -07001053 }
1054
Shawn Willden907c3012014-12-08 15:51:55 -07001055 void GenerateSymmetricKey(keymaster_algorithm_t algorithm, uint32_t key_size,
1056 keymaster_block_mode_t block_mode, uint32_t chunk_length) {
Shawn Willden6dde87c2014-12-11 14:08:48 -07001057 params_.Clear();
Shawn Willden5b53c992015-02-02 08:05:25 -07001058 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
1059 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT));
1060 params_.push_back(Authorization(TAG_ALGORITHM, algorithm));
1061 params_.push_back(Authorization(TAG_BLOCK_MODE, block_mode));
1062 params_.push_back(Authorization(TAG_CHUNK_LENGTH, chunk_length));
1063 params_.push_back(Authorization(TAG_KEY_SIZE, key_size));
1064 params_.push_back(Authorization(TAG_MAC_LENGTH, 16));
1065 params_.push_back(Authorization(TAG_USER_ID, 7));
1066 params_.push_back(Authorization(TAG_USER_AUTH_ID, 8));
Shawn Willden5b53c992015-02-02 08:05:25 -07001067 params_.push_back(Authorization(TAG_AUTH_TIMEOUT, 300));
1068
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001069 GenerateKey(&params_);
Shawn Willden907c3012014-12-08 15:51:55 -07001070 }
1071
Shawn Willden4200f212014-12-02 07:01:21 -07001072 string ProcessMessage(keymaster_purpose_t purpose, const keymaster_key_blob_t& key_blob,
1073 const void* message, size_t size) {
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001074 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose, key_blob));
Shawn Willden4200f212014-12-02 07:01:21 -07001075
1076 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001077 size_t input_consumed;
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001078 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, size, &result, &input_consumed));
Shawn Willdenb7361132014-12-08 08:15:14 -07001079 EXPECT_EQ(size, input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001080 EXPECT_EQ(KM_ERROR_OK, FinishOperation(&result));
1081 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle_));
Shawn Willden4200f212014-12-02 07:01:21 -07001082 return result;
1083 }
1084
Shawn Willden6dde87c2014-12-11 14:08:48 -07001085 string EncryptMessage(const string& message) {
1086 return ProcessMessage(KM_PURPOSE_ENCRYPT, blob_, message.c_str(), message.length());
Shawn Willden4200f212014-12-02 07:01:21 -07001087 }
1088
Shawn Willden6dde87c2014-12-11 14:08:48 -07001089 string DecryptMessage(const string& ciphertext) {
1090 return ProcessMessage(KM_PURPOSE_DECRYPT, blob_, ciphertext.c_str(), ciphertext.length());
Shawn Willden4200f212014-12-02 07:01:21 -07001091 }
1092
Shawn Willden5b53c992015-02-02 08:05:25 -07001093 const void corrupt_key_blob() {
1094 uint8_t* tmp = const_cast<uint8_t*>(blob_.key_material);
1095 ++tmp[blob_.key_material_size / 2];
Shawn Willden4200f212014-12-02 07:01:21 -07001096 }
1097
Shawn Willden5b53c992015-02-02 08:05:25 -07001098 keymaster_blob_t client_id_ = {.data = reinterpret_cast<const uint8_t*>("app_id"),
1099 .data_length = 6};
1100 keymaster_key_param_t client_params_[1] = {
1101 Authorization(TAG_APPLICATION_ID, client_id_.data, client_id_.data_length)};
1102
1103 keymaster_key_param_t* out_params_;
1104 size_t out_params_count_;
Shawn Willden4200f212014-12-02 07:01:21 -07001105};
1106
1107TEST_F(EncryptionOperationsTest, RsaOaepSuccess) {
1108 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1109 const char message[] = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001110 string ciphertext1 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001111 EXPECT_EQ(512 / 8, ciphertext1.size());
1112
Shawn Willden6dde87c2014-12-11 14:08:48 -07001113 string ciphertext2 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001114 EXPECT_EQ(512 / 8, ciphertext2.size());
1115
1116 // OAEP randomizes padding so every result should be different.
1117 EXPECT_NE(ciphertext1, ciphertext2);
1118}
1119
1120TEST_F(EncryptionOperationsTest, RsaOaepRoundTrip) {
1121 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1122 const char message[] = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001123 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001124 EXPECT_EQ(512 / 8, ciphertext.size());
1125
Shawn Willden6dde87c2014-12-11 14:08:48 -07001126 string plaintext = DecryptMessage(ciphertext);
Shawn Willden4200f212014-12-02 07:01:21 -07001127 EXPECT_EQ(message, plaintext);
1128}
1129
1130TEST_F(EncryptionOperationsTest, RsaOaepTooLarge) {
1131 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1132 const char message[] = "12345678901234567890123";
Shawn Willden4200f212014-12-02 07:01:21 -07001133 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001134 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001135
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001136 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT, blob_));
1137 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, array_size(message), &result, &input_consumed));
1138 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -07001139 EXPECT_EQ(0, result.size());
1140}
1141
1142TEST_F(EncryptionOperationsTest, RsaOaepCorruptedDecrypt) {
1143 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1144 const char message[] = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001145 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001146 EXPECT_EQ(512 / 8, ciphertext.size());
1147
1148 // Corrupt the ciphertext
1149 ciphertext[512 / 8 / 2]++;
1150
Shawn Willden4200f212014-12-02 07:01:21 -07001151 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001152 size_t input_consumed;
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001153 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, blob_));
1154 EXPECT_EQ(KM_ERROR_OK,
1155 UpdateOperation(ciphertext.data(), ciphertext.size(), &result, &input_consumed));
1156 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -07001157 EXPECT_EQ(0, result.size());
1158}
1159
1160TEST_F(EncryptionOperationsTest, RsaPkcs1Success) {
1161 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1162 const char message[] = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001163 string ciphertext1 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001164 EXPECT_EQ(512 / 8, ciphertext1.size());
1165
Shawn Willden6dde87c2014-12-11 14:08:48 -07001166 string ciphertext2 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001167 EXPECT_EQ(512 / 8, ciphertext2.size());
1168
1169 // PKCS1 v1.5 randomizes padding so every result should be different.
1170 EXPECT_NE(ciphertext1, ciphertext2);
1171}
1172
1173TEST_F(EncryptionOperationsTest, RsaPkcs1RoundTrip) {
1174 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1175 const char message[] = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001176 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001177 EXPECT_EQ(512 / 8, ciphertext.size());
1178
Shawn Willden6dde87c2014-12-11 14:08:48 -07001179 string plaintext = DecryptMessage(ciphertext);
Shawn Willden4200f212014-12-02 07:01:21 -07001180 EXPECT_EQ(message, plaintext);
1181}
1182
1183TEST_F(EncryptionOperationsTest, RsaPkcs1TooLarge) {
1184 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1185 const char message[] = "1234567890123456789012345678901234567890123456789012";
Shawn Willden4200f212014-12-02 07:01:21 -07001186 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001187 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001188
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001189 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT, blob_));
1190 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, array_size(message), &result, &input_consumed));
1191 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -07001192 EXPECT_EQ(0, result.size());
1193}
1194
1195TEST_F(EncryptionOperationsTest, RsaPkcs1CorruptedDecrypt) {
1196 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1197 const char message[] = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001198 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001199 EXPECT_EQ(512 / 8, ciphertext.size());
1200
1201 // Corrupt the ciphertext
1202 ciphertext[512 / 8 / 2]++;
1203
Shawn Willden4200f212014-12-02 07:01:21 -07001204 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001205 size_t input_consumed;
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001206 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, blob_));
1207 EXPECT_EQ(KM_ERROR_OK,
1208 UpdateOperation(ciphertext.data(), ciphertext.size(), &result, &input_consumed));
1209 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -07001210 EXPECT_EQ(0, result.size());
1211}
1212
Shawn Willden907c3012014-12-08 15:51:55 -07001213TEST_F(EncryptionOperationsTest, AesOcbSuccess) {
1214 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1215 const char message[] = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001216 string ciphertext1 = EncryptMessage(string(message));
Shawn Willden907c3012014-12-08 15:51:55 -07001217 EXPECT_EQ(12 /* nonce */ + strlen(message) + 16 /* tag */, ciphertext1.size());
1218
Shawn Willden6dde87c2014-12-11 14:08:48 -07001219 string ciphertext2 = EncryptMessage(string(message));
Shawn Willden907c3012014-12-08 15:51:55 -07001220 EXPECT_EQ(12 /* nonce */ + strlen(message) + 16 /* tag */, ciphertext2.size());
1221
1222 // OCB uses a random nonce, so every output should be different
1223 EXPECT_NE(ciphertext1, ciphertext2);
1224}
1225
Shawn Willden6dde87c2014-12-11 14:08:48 -07001226TEST_F(EncryptionOperationsTest, AesOcbRoundTripSuccess) {
1227 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1228 string message = "Hello World!";
1229 string ciphertext = EncryptMessage(message);
1230 EXPECT_EQ(12 /* nonce */ + message.length() + 16 /* tag */, ciphertext.size());
1231
1232 string plaintext = DecryptMessage(ciphertext);
1233 EXPECT_EQ(message, plaintext);
1234}
1235
1236TEST_F(EncryptionOperationsTest, AesOcbRoundTripCorrupted) {
1237 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1238 const char message[] = "Hello World!";
1239 string ciphertext = EncryptMessage(string(message));
1240 EXPECT_EQ(12 /* nonce */ + strlen(message) + 16 /* tag */, ciphertext.size());
1241
1242 ciphertext[ciphertext.size() / 2]++;
1243
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001244 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, key_blob()));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001245
1246 string result;
1247 size_t input_consumed;
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001248 EXPECT_EQ(KM_ERROR_OK,
1249 UpdateOperation(ciphertext.c_str(), ciphertext.length(), &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001250 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001251 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001252}
1253
1254TEST_F(EncryptionOperationsTest, AesDecryptGarbage) {
1255 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1256 string ciphertext(128, 'a');
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001257 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, key_blob()));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001258
1259 string result;
1260 size_t input_consumed;
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001261 EXPECT_EQ(KM_ERROR_OK,
1262 UpdateOperation(ciphertext.c_str(), ciphertext.length(), &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001263 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001264 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001265}
1266
1267TEST_F(EncryptionOperationsTest, AesDecryptTooShort) {
1268 // Try decrypting garbage ciphertext that is too short to be valid (< nonce + tag).
1269 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1270 string ciphertext(12 + 15, 'a');
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001271 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, key_blob()));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001272
1273 string result;
1274 size_t input_consumed;
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001275 EXPECT_EQ(KM_ERROR_OK,
1276 UpdateOperation(ciphertext.c_str(), ciphertext.length(), &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001277 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001278 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001279}
1280
1281TEST_F(EncryptionOperationsTest, AesOcbRoundTripEmptySuccess) {
1282 // Empty messages should work fine.
1283 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1284 const char message[] = "";
1285 string ciphertext = EncryptMessage(string(message));
1286 EXPECT_EQ(12 /* nonce */ + strlen(message) + 16 /* tag */, ciphertext.size());
1287
1288 string plaintext = DecryptMessage(ciphertext);
1289 EXPECT_EQ(message, plaintext);
1290}
1291
1292TEST_F(EncryptionOperationsTest, AesOcbRoundTripEmptyCorrupted) {
1293 // Should even detect corruption of empty messages.
1294 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1295 const char message[] = "";
1296 string ciphertext = EncryptMessage(string(message));
1297 EXPECT_EQ(12 /* nonce */ + strlen(message) + 16 /* tag */, ciphertext.size());
1298
1299 ciphertext[ciphertext.size() / 2]++;
1300
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001301 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, key_blob()));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001302
1303 string result;
1304 size_t input_consumed;
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001305 EXPECT_EQ(KM_ERROR_OK,
1306 UpdateOperation(ciphertext.c_str(), ciphertext.length(), &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001307 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001308 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001309}
1310
1311TEST_F(EncryptionOperationsTest, AesOcbFullChunk) {
1312 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1313 string message(4096, 'a');
1314 string ciphertext = EncryptMessage(message);
1315 EXPECT_EQ(12 /* nonce */ + message.length() + 16 /* tag */, ciphertext.size());
1316
1317 string plaintext = DecryptMessage(ciphertext);
1318 EXPECT_EQ(message, plaintext);
1319}
1320
1321TEST_F(EncryptionOperationsTest, AesOcbVariousChunkLengths) {
1322 for (unsigned chunk_length = 1; chunk_length <= 128; ++chunk_length) {
1323 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, chunk_length);
1324 string message(128, 'a');
1325 string ciphertext = EncryptMessage(message);
1326 int expected_tag_count = (message.length() + chunk_length - 1) / chunk_length;
1327 EXPECT_EQ(12 /* nonce */ + message.length() + 16 * expected_tag_count, ciphertext.size())
1328 << "Unexpected ciphertext size for chunk length " << chunk_length
1329 << " expected tag count was " << expected_tag_count
1330 << " but actual tag count was probably "
1331 << (ciphertext.size() - message.length() - 12) / 16;
1332
1333 string plaintext = DecryptMessage(ciphertext);
1334 EXPECT_EQ(message, plaintext);
1335 }
1336}
1337
1338TEST_F(EncryptionOperationsTest, AesOcbAbort) {
1339 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1340 const char message[] = "Hello";
1341
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001342 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT, key_blob()));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001343
1344 string result;
1345 size_t input_consumed;
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001346 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, strlen(message), &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001347 EXPECT_EQ(strlen(message), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001348 EXPECT_EQ(KM_ERROR_OK, device()->abort(device(), op_handle_));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001349}
1350
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001351TEST_F(EncryptionOperationsTest, AesOcbNoChunkLength) {
1352 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
1353 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT));
1354 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES));
1355 params_.push_back(Authorization(TAG_KEY_SIZE, 128));
1356 params_.push_back(Authorization(TAG_MAC_LENGTH, 16));
1357 params_.push_back(Authorization(TAG_BLOCK_MODE, KM_MODE_OCB));
1358 params_.push_back(Authorization(TAG_PADDING, KM_PAD_NONE));
1359
1360 GenerateKey(&params_);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001361 EXPECT_EQ(KM_ERROR_INVALID_ARGUMENT, BeginOperation(KM_PURPOSE_ENCRYPT, key_blob()));
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001362}
1363
1364TEST_F(EncryptionOperationsTest, AesEcbUnsupported) {
1365 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
1366 params_.push_back(Authorization(TAG_MAC_LENGTH, 16));
1367 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT));
1368 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES));
1369 params_.push_back(Authorization(TAG_KEY_SIZE, 128));
1370 params_.push_back(Authorization(TAG_BLOCK_MODE, KM_MODE_ECB));
1371 params_.push_back(Authorization(TAG_PADDING, KM_PAD_NONE));
1372
1373 GenerateKey(&params_);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001374 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE, BeginOperation(KM_PURPOSE_ENCRYPT, key_blob()));
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001375}
1376
1377TEST_F(EncryptionOperationsTest, AesOcbPaddingUnsupported) {
1378 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
1379 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT));
1380 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES));
1381 params_.push_back(Authorization(TAG_KEY_SIZE, 128));
1382 params_.push_back(Authorization(TAG_MAC_LENGTH, 16));
1383 params_.push_back(Authorization(TAG_BLOCK_MODE, KM_MODE_OCB));
1384 params_.push_back(Authorization(TAG_CHUNK_LENGTH, 4096));
1385 params_.push_back(Authorization(TAG_PADDING, KM_PAD_ZERO));
1386
1387 GenerateKey(&params_);
1388 uint64_t op_handle;
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001389 EXPECT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, BeginOperation(KM_PURPOSE_ENCRYPT, key_blob()));
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001390}
1391
1392TEST_F(EncryptionOperationsTest, AesOcbInvalidMacLength) {
1393 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
1394 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT));
1395 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES));
1396 params_.push_back(Authorization(TAG_KEY_SIZE, 128));
1397 params_.push_back(Authorization(TAG_MAC_LENGTH, 17));
1398 params_.push_back(Authorization(TAG_BLOCK_MODE, KM_MODE_OCB));
1399 params_.push_back(Authorization(TAG_CHUNK_LENGTH, 4096));
1400
1401 GenerateKey(&params_);
1402 uint64_t op_handle;
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001403 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, BeginOperation(KM_PURPOSE_ENCRYPT, key_blob()));
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001404}
1405
Shawn Willden128ffe02014-08-06 12:31:33 -06001406} // namespace test
1407} // namespace keymaster