blob: 596aeed079435b499d83f1e2502c7149534c8aed [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 Willdend6cd7e32014-12-17 08:01:26 -070088 keymaster_error_t BeginOperation(keymaster_purpose_t purpose,
89 const keymaster_key_blob_t& key_blob) {
90 return device()->begin(device(), purpose, &key_blob, client_params_,
91 array_length(client_params_), &out_params_, &out_params_count_,
92 &op_handle_);
93 }
94
95 keymaster_error_t UpdateOperation(const void* message, size_t size, string* output,
96 size_t* input_consumed) {
97 uint8_t* out_tmp = NULL;
98 size_t out_length;
99 keymaster_error_t error =
100 device()->update(device(), op_handle_, reinterpret_cast<const uint8_t*>(message), size,
101 input_consumed, &out_tmp, &out_length);
102 if (out_tmp)
103 output->append(reinterpret_cast<char*>(out_tmp), out_length);
104 free(out_tmp);
105 return error;
106 }
107
108 keymaster_error_t FinishOperation(string* output) {
109 uint8_t* out_tmp = NULL;
110 size_t out_length;
111 keymaster_error_t error =
112 device()->finish(device(), op_handle_, reinterpret_cast<const uint8_t*>(signature_),
113 signature_length_, &out_tmp, &out_length);
114 if (out_tmp)
115 output->append(reinterpret_cast<char*>(out_tmp), out_length);
116 free(out_tmp);
117 return error;
118 }
119
Shawn Willden5b53c992015-02-02 08:05:25 -0700120 template <typename T> void ExpectContains(T val, T* vals, size_t len) {
121 EXPECT_EQ(1U, len);
122 EXPECT_EQ(val, vals[0]);
Shawn Willdend0772312014-09-18 12:27:57 -0600123 }
124
Shawn Willden5b53c992015-02-02 08:05:25 -0700125 void FreeCharacteristics() {
126 keymaster_free_characteristics(characteristics_);
127 free(characteristics_);
128 characteristics_ = NULL;
129 }
130
131 void FreeKeyBlob() {
132 free(const_cast<uint8_t*>(blob_.key_material));
133 blob_.key_material = NULL;
134 }
135
Shawn Willden6dde87c2014-12-11 14:08:48 -0700136 const keymaster_key_blob_t& key_blob() { return blob_; }
137
Shawn Willden5b53c992015-02-02 08:05:25 -0700138 SoftKeymasterDevice device_;
139
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700140 keymaster_blob_t client_id_ = {.data = reinterpret_cast<const uint8_t*>("app_id"),
141 .data_length = 6};
142 keymaster_key_param_t client_params_[1] = {
143 Authorization(TAG_APPLICATION_ID, client_id_.data, client_id_.data_length)};
144
145 keymaster_key_param_t* out_params_;
146 size_t out_params_count_;
147 uint64_t op_handle_;
148 size_t input_consumed_;
149 uint8_t* signature_;
150 size_t signature_length_;
151
Shawn Willden5b53c992015-02-02 08:05:25 -0700152 AuthorizationSet params_;
153 keymaster_key_blob_t blob_;
154 keymaster_key_characteristics_t* characteristics_;
Shawn Willden128ffe02014-08-06 12:31:33 -0600155};
156
Shawn Willden128ffe02014-08-06 12:31:33 -0600157typedef KeymasterTest CheckSupported;
158TEST_F(CheckSupported, SupportedAlgorithms) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700159 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
160 device()->get_supported_algorithms(device(), NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600161
Shawn Willden5b53c992015-02-02 08:05:25 -0700162 size_t len;
163 keymaster_algorithm_t* algorithms;
164 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_algorithms(device(), &algorithms, &len));
165 ASSERT_EQ(4U, len);
166 EXPECT_EQ(KM_ALGORITHM_RSA, algorithms[0]);
167 EXPECT_EQ(KM_ALGORITHM_DSA, algorithms[1]);
168 EXPECT_EQ(KM_ALGORITHM_ECDSA, algorithms[2]);
169 EXPECT_EQ(KM_ALGORITHM_AES, algorithms[3]);
170
171 free(algorithms);
Shawn Willden128ffe02014-08-06 12:31:33 -0600172}
173
174TEST_F(CheckSupported, SupportedBlockModes) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700175 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
176 device()->get_supported_block_modes(device(), KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT,
177 NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600178
Shawn Willden5b53c992015-02-02 08:05:25 -0700179 size_t len;
180 keymaster_block_mode_t* modes;
181 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE,
182 device()->get_supported_block_modes(device(), KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT,
183 &modes, &len));
Shawn Willden128ffe02014-08-06 12:31:33 -0600184
Shawn Willden5b53c992015-02-02 08:05:25 -0700185 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE,
186 device()->get_supported_block_modes(device(), KM_ALGORITHM_DSA, KM_PURPOSE_ENCRYPT,
187 &modes, &len));
Shawn Willden28e41472014-08-18 13:35:22 -0600188
Shawn Willden5b53c992015-02-02 08:05:25 -0700189 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE,
190 device()->get_supported_block_modes(device(), KM_ALGORITHM_ECDSA, KM_PURPOSE_ENCRYPT,
191 &modes, &len));
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600192
Shawn Willden5b53c992015-02-02 08:05:25 -0700193 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE,
194 device()->get_supported_block_modes(device(), KM_ALGORITHM_AES, KM_PURPOSE_ENCRYPT,
195 &modes, &len));
Shawn Willden128ffe02014-08-06 12:31:33 -0600196}
197
198TEST_F(CheckSupported, SupportedPaddingModes) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700199 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
200 device()->get_supported_padding_modes(device(), KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT,
201 NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600202
Shawn Willden5b53c992015-02-02 08:05:25 -0700203 size_t len;
204 keymaster_padding_t* modes;
205 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_RSA,
206 KM_PURPOSE_SIGN, &modes, &len));
207 ExpectContains(KM_PAD_NONE, modes, len);
208 free(modes);
Shawn Willden128ffe02014-08-06 12:31:33 -0600209
Shawn Willden5b53c992015-02-02 08:05:25 -0700210 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_DSA,
211 KM_PURPOSE_SIGN, &modes, &len));
212 ExpectContains(KM_PAD_NONE, modes, len);
213 free(modes);
Shawn Willden28e41472014-08-18 13:35:22 -0600214
Shawn Willden5b53c992015-02-02 08:05:25 -0700215 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_ECDSA,
216 KM_PURPOSE_SIGN, &modes, &len));
217 ExpectContains(KM_PAD_NONE, modes, len);
218 free(modes);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600219
Shawn Willden5b53c992015-02-02 08:05:25 -0700220 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_AES,
221 KM_PURPOSE_SIGN, &modes, &len));
222 EXPECT_EQ(0, len);
223 free(modes);
Shawn Willden128ffe02014-08-06 12:31:33 -0600224}
225
226TEST_F(CheckSupported, SupportedDigests) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700227 EXPECT_EQ(
228 KM_ERROR_OUTPUT_PARAMETER_NULL,
229 device()->get_supported_digests(device(), KM_ALGORITHM_RSA, KM_PURPOSE_SIGN, NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600230
Shawn Willden5b53c992015-02-02 08:05:25 -0700231 size_t len;
232 keymaster_digest_t* digests;
233 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_RSA,
234 KM_PURPOSE_SIGN, &digests, &len));
235 ExpectContains(KM_DIGEST_NONE, digests, len);
236 free(digests);
Shawn Willden128ffe02014-08-06 12:31:33 -0600237
Shawn Willden5b53c992015-02-02 08:05:25 -0700238 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_DSA,
239 KM_PURPOSE_SIGN, &digests, &len));
240 ExpectContains(KM_DIGEST_NONE, digests, len);
241 free(digests);
Shawn Willden28e41472014-08-18 13:35:22 -0600242
Shawn Willden5b53c992015-02-02 08:05:25 -0700243 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_ECDSA,
244 KM_PURPOSE_SIGN, &digests, &len));
245 ExpectContains(KM_DIGEST_NONE, digests, len);
246 free(digests);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600247
Shawn Willden5b53c992015-02-02 08:05:25 -0700248 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_AES,
249 KM_PURPOSE_SIGN, &digests, &len));
250 EXPECT_EQ(0, len);
251 free(digests);
Shawn Willden128ffe02014-08-06 12:31:33 -0600252}
253
254TEST_F(CheckSupported, SupportedImportFormats) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700255 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
256 device()->get_supported_import_formats(device(), KM_ALGORITHM_RSA, NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600257
Shawn Willden5b53c992015-02-02 08:05:25 -0700258 size_t len;
259 keymaster_key_format_t* formats;
260 EXPECT_EQ(KM_ERROR_OK,
261 device()->get_supported_import_formats(device(), KM_ALGORITHM_RSA, &formats, &len));
262 ExpectContains(KM_KEY_FORMAT_PKCS8, formats, len);
263 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600264
Shawn Willden5b53c992015-02-02 08:05:25 -0700265 EXPECT_EQ(KM_ERROR_OK,
266 device()->get_supported_import_formats(device(), KM_ALGORITHM_DSA, &formats, &len));
267 ExpectContains(KM_KEY_FORMAT_PKCS8, formats, len);
268 free(formats);
Shawn Willden28e41472014-08-18 13:35:22 -0600269
Shawn Willden5b53c992015-02-02 08:05:25 -0700270 EXPECT_EQ(KM_ERROR_OK,
271 device()->get_supported_import_formats(device(), KM_ALGORITHM_ECDSA, &formats, &len));
272 ExpectContains(KM_KEY_FORMAT_PKCS8, formats, len);
273 free(formats);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600274
Shawn Willden5b53c992015-02-02 08:05:25 -0700275 EXPECT_EQ(KM_ERROR_OK,
276 device()->get_supported_import_formats(device(), KM_ALGORITHM_AES, &formats, &len));
277 EXPECT_EQ(0, len);
278 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600279}
280
281TEST_F(CheckSupported, SupportedExportFormats) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700282 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
283 device()->get_supported_export_formats(device(), KM_ALGORITHM_RSA, NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600284
Shawn Willden5b53c992015-02-02 08:05:25 -0700285 size_t len;
286 keymaster_key_format_t* formats;
287 EXPECT_EQ(KM_ERROR_OK,
288 device()->get_supported_export_formats(device(), KM_ALGORITHM_RSA, &formats, &len));
289 ExpectContains(KM_KEY_FORMAT_X509, formats, len);
290 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600291
Shawn Willden5b53c992015-02-02 08:05:25 -0700292 EXPECT_EQ(KM_ERROR_OK,
293 device()->get_supported_export_formats(device(), KM_ALGORITHM_DSA, &formats, &len));
294 ExpectContains(KM_KEY_FORMAT_X509, formats, len);
295 free(formats);
Shawn Willden28e41472014-08-18 13:35:22 -0600296
Shawn Willden5b53c992015-02-02 08:05:25 -0700297 EXPECT_EQ(KM_ERROR_OK,
298 device()->get_supported_export_formats(device(), KM_ALGORITHM_ECDSA, &formats, &len));
299 ExpectContains(KM_KEY_FORMAT_X509, formats, len);
300 free(formats);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600301
Shawn Willden5b53c992015-02-02 08:05:25 -0700302 EXPECT_EQ(KM_ERROR_OK,
303 device()->get_supported_export_formats(device(), KM_ALGORITHM_AES, &formats, &len));
304 EXPECT_EQ(0, len);
305 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600306}
307
Shawn Willdend0772312014-09-18 12:27:57 -0600308keymaster_key_param_t key_generation_base_params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700309 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
310 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
Shawn Willdend0772312014-09-18 12:27:57 -0600311 Authorization(TAG_APPLICATION_ID, "app_id", 6),
Shawn Willden3809b932014-12-02 06:59:46 -0700312 Authorization(TAG_APPLICATION_DATA, "app_data", 8), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willdend0772312014-09-18 12:27:57 -0600313};
314
Shawn Willden5b53c992015-02-02 08:05:25 -0700315TEST_F(KeymasterTest, TestFlags) {
316 EXPECT_TRUE(device()->flags & KEYMASTER_SOFTWARE_ONLY);
317 EXPECT_TRUE(device()->flags & KEYMASTER_BLOBS_ARE_STANDALONE);
318 EXPECT_FALSE(device()->flags & KEYMASTER_SUPPORTS_DSA);
319 EXPECT_TRUE(device()->flags & KEYMASTER_SUPPORTS_EC);
320}
321
322typedef KeymasterTest OldKeyGeneration;
323
324TEST_F(OldKeyGeneration, Rsa) {
325 keymaster_rsa_keygen_params_t params = {.modulus_size = 256, .public_exponent = 3};
326 uint8_t* key_blob;
327 size_t key_blob_length;
328 EXPECT_EQ(0,
329 device()->generate_keypair(device(), TYPE_RSA, &params, &key_blob, &key_blob_length));
330 EXPECT_GT(key_blob_length, 0);
331
332 free(key_blob);
333}
334
335TEST_F(OldKeyGeneration, Ecdsa) {
336
337 keymaster_ec_keygen_params_t params = {.field_size = 256};
338 uint8_t* key_blob;
339 size_t key_blob_length;
340 EXPECT_EQ(0,
341 device()->generate_keypair(device(), TYPE_EC, &params, &key_blob, &key_blob_length));
342 EXPECT_GT(key_blob_length, 0);
343
344 free(key_blob);
345}
346
Shawn Willdend0772312014-09-18 12:27:57 -0600347class NewKeyGeneration : public KeymasterTest {
348 protected:
349 NewKeyGeneration() {
Shawn Willden5b53c992015-02-02 08:05:25 -0700350 params_.Reinitialize(key_generation_base_params, array_length(key_generation_base_params));
Shawn Willdend0772312014-09-18 12:27:57 -0600351 }
352
Shawn Willden5b53c992015-02-02 08:05:25 -0700353 void CheckBaseParams(const AuthorizationSet& auths) {
354 EXPECT_TRUE(contains(auths, TAG_PURPOSE, KM_PURPOSE_SIGN));
355 EXPECT_TRUE(contains(auths, TAG_PURPOSE, KM_PURPOSE_VERIFY));
356 EXPECT_TRUE(contains(auths, TAG_USER_ID, 7));
357 EXPECT_TRUE(contains(auths, TAG_USER_AUTH_ID, 8));
358 EXPECT_TRUE(contains(auths, TAG_AUTH_TIMEOUT, 300));
Shawn Willdend0772312014-09-18 12:27:57 -0600359
360 // Verify that App ID, App data and ROT are NOT included.
Shawn Willden5b53c992015-02-02 08:05:25 -0700361 EXPECT_FALSE(contains(auths, TAG_ROOT_OF_TRUST));
362 EXPECT_FALSE(contains(auths, TAG_APPLICATION_ID));
363 EXPECT_FALSE(contains(auths, TAG_APPLICATION_DATA));
Shawn Willdend0772312014-09-18 12:27:57 -0600364
365 // Just for giggles, check that some unexpected tags/values are NOT present.
Shawn Willden5b53c992015-02-02 08:05:25 -0700366 EXPECT_FALSE(contains(auths, TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
367 EXPECT_FALSE(contains(auths, TAG_PURPOSE, KM_PURPOSE_DECRYPT));
368 EXPECT_FALSE(contains(auths, TAG_AUTH_TIMEOUT, 301));
Shawn Willdend0772312014-09-18 12:27:57 -0600369
370 // Now check that unspecified, defaulted tags are correct.
Shawn Willden5b53c992015-02-02 08:05:25 -0700371 EXPECT_TRUE(contains(auths, TAG_ORIGIN, KM_ORIGIN_SOFTWARE));
372 EXPECT_TRUE(contains(auths, KM_TAG_CREATION_DATETIME));
Shawn Willdend0772312014-09-18 12:27:57 -0600373 }
Shawn Willden2079ae82015-01-22 13:42:31 -0700374};
375
Shawn Willden5b53c992015-02-02 08:05:25 -0700376struct ParamListDelete {
377 void operator()(keymaster_key_param_set_t* p) { keymaster_free_param_set(p); }
378};
379
380typedef UniquePtr<keymaster_key_param_set_t, ParamListDelete> UniqueParamSetPtr;
381
Shawn Willden128ffe02014-08-06 12:31:33 -0600382TEST_F(NewKeyGeneration, Rsa) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700383 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA));
384 params_.push_back(Authorization(TAG_KEY_SIZE, 256));
385 params_.push_back(Authorization(TAG_RSA_PUBLIC_EXPONENT, 3));
386 ASSERT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(), &blob_,
387 &characteristics_));
388 EXPECT_EQ(0U, characteristics_->hw_enforced.length);
389 AuthorizationSet auths(characteristics_->sw_enforced);
390 CheckBaseParams(auths);
Shawn Willden128ffe02014-08-06 12:31:33 -0600391
Shawn Willden5b53c992015-02-02 08:05:25 -0700392 // Check specified tags are all present in auths
393 EXPECT_TRUE(contains(auths, TAG_ALGORITHM, KM_ALGORITHM_RSA));
394 EXPECT_TRUE(contains(auths, TAG_KEY_SIZE, 256));
395 EXPECT_TRUE(contains(auths, TAG_RSA_PUBLIC_EXPONENT, 3));
Shawn Willden128ffe02014-08-06 12:31:33 -0600396}
397
Shawn Willden6bbe6782014-09-18 11:26:15 -0600398TEST_F(NewKeyGeneration, RsaDefaultSize) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700399 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA));
400 ASSERT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(), &blob_,
401 &characteristics_));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600402
Shawn Willden5b53c992015-02-02 08:05:25 -0700403 EXPECT_EQ(0U, characteristics_->hw_enforced.length);
404 AuthorizationSet auths(characteristics_->sw_enforced);
405 CheckBaseParams(auths);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600406
Shawn Willden5b53c992015-02-02 08:05:25 -0700407 // Check specified tags are all present in auths
408 EXPECT_TRUE(contains(auths, TAG_ALGORITHM, KM_ALGORITHM_RSA));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600409
410 // Now check that unspecified, defaulted tags are correct.
Shawn Willden5b53c992015-02-02 08:05:25 -0700411 EXPECT_TRUE(contains(auths, TAG_RSA_PUBLIC_EXPONENT, 65537));
412 EXPECT_TRUE(contains(auths, TAG_KEY_SIZE, 2048));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600413}
414
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600415TEST_F(NewKeyGeneration, Ecdsa) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700416 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
417 params_.push_back(Authorization(TAG_KEY_SIZE, 224));
418 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(), &blob_,
419 &characteristics_));
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600420
Shawn Willden5b53c992015-02-02 08:05:25 -0700421 EXPECT_EQ(0U, characteristics_->hw_enforced.length);
422 AuthorizationSet auths(characteristics_->sw_enforced);
423 CheckBaseParams(auths);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600424
Shawn Willden5b53c992015-02-02 08:05:25 -0700425 // Check specified tags are all present in auths characteristics
426 EXPECT_TRUE(contains(auths, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
427 EXPECT_TRUE(contains(auths, TAG_KEY_SIZE, 224));
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600428}
429
Shawn Willden6bbe6782014-09-18 11:26:15 -0600430TEST_F(NewKeyGeneration, EcdsaDefaultSize) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700431 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
432 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(), &blob_,
433 &characteristics_));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600434
Shawn Willden5b53c992015-02-02 08:05:25 -0700435 EXPECT_EQ(0U, characteristics_->hw_enforced.length);
436 AuthorizationSet auths(characteristics_->sw_enforced);
437 CheckBaseParams(auths);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600438
Shawn Willden5b53c992015-02-02 08:05:25 -0700439 // Check specified tags are all present in auths
440 EXPECT_TRUE(contains(auths, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600441
442 // Now check that unspecified, defaulted tags are correct.
Shawn Willden5b53c992015-02-02 08:05:25 -0700443 EXPECT_TRUE(contains(auths, TAG_KEY_SIZE, 224));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600444}
445
446TEST_F(NewKeyGeneration, EcdsaInvalidSize) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700447 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
448 params_.push_back(Authorization(TAG_KEY_SIZE, 190));
449 EXPECT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE,
450 device()->generate_key(device(), params_.data(), params_.size(), &blob_,
451 &characteristics_));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600452}
453
454TEST_F(NewKeyGeneration, EcdsaAllValidSizes) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600455 size_t valid_sizes[] = {224, 256, 384, 521};
Shawn Willden6bbe6782014-09-18 11:26:15 -0600456 for (size_t size : valid_sizes) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700457 params_.Reinitialize(key_generation_base_params, array_length(key_generation_base_params));
458 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
459 params_.push_back(Authorization(TAG_KEY_SIZE, size));
460 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(),
461 &blob_, &characteristics_))
462 << "Failed to generate size: " << size;
463
464 FreeCharacteristics();
465 FreeKeyBlob();
Shawn Willden6bbe6782014-09-18 11:26:15 -0600466 }
467}
468
Shawn Willden19fca882015-01-22 16:35:30 -0700469TEST_F(NewKeyGeneration, AesOcb) {
470 keymaster_key_param_t params[] = {
471 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
472 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
473 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
474 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_CHUNK_LENGTH, 4096),
Shawn Willden7efb8782014-12-11 14:07:44 -0700475 Authorization(TAG_MAC_LENGTH, 16), Authorization(TAG_PADDING, KM_PAD_NONE),
Shawn Willden19fca882015-01-22 16:35:30 -0700476 };
Shawn Willden5b53c992015-02-02 08:05:25 -0700477 params_.Reinitialize(params, array_length(params));
478 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(), &blob_,
479 &characteristics_));
Shawn Willden19fca882015-01-22 16:35:30 -0700480}
481
482TEST_F(NewKeyGeneration, AesOcbInvalidKeySize) {
483 keymaster_key_param_t params[] = {
484 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
485 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
Shawn Willden95e13822014-12-15 16:12:16 -0700486 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 136),
Shawn Willden19fca882015-01-22 16:35:30 -0700487 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_CHUNK_LENGTH, 4096),
Shawn Willden7efb8782014-12-11 14:07:44 -0700488 Authorization(TAG_MAC_LENGTH, 16), Authorization(TAG_PADDING, KM_PAD_NONE),
Shawn Willden19fca882015-01-22 16:35:30 -0700489 };
Shawn Willden5b53c992015-02-02 08:05:25 -0700490 params_.Reinitialize(params, array_length(params));
Shawn Willden95e13822014-12-15 16:12:16 -0700491 params_.Reinitialize(params, array_length(params));
492 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(), &blob_,
493 &characteristics_));
494
495 keymaster_key_param_t* out_params;
496 size_t out_params_count;
497 uint64_t op_handle;
Shawn Willden5b53c992015-02-02 08:05:25 -0700498 EXPECT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE,
Shawn Willden95e13822014-12-15 16:12:16 -0700499 device()->begin(device(), KM_PURPOSE_ENCRYPT, &blob_, NULL, 0, &out_params,
500 &out_params_count, &op_handle));
501 free(out_params);
Shawn Willden19fca882015-01-22 16:35:30 -0700502}
503
504TEST_F(NewKeyGeneration, AesOcbAllValidSizes) {
505 keymaster_key_param_t params[] = {
506 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
507 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
Shawn Willden7efb8782014-12-11 14:07:44 -0700508 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_BLOCK_MODE, KM_MODE_OCB),
509 Authorization(TAG_MAC_LENGTH, 16), Authorization(TAG_CHUNK_LENGTH, 4096),
Shawn Willden19fca882015-01-22 16:35:30 -0700510 Authorization(TAG_PADDING, KM_PAD_NONE),
511 };
512
513 size_t valid_sizes[] = {128, 192, 256};
514 for (size_t size : valid_sizes) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700515 params_.Reinitialize(params, array_length(params));
516 params_.push_back(Authorization(TAG_KEY_SIZE, size));
Shawn Willden95e13822014-12-15 16:12:16 -0700517 FreeCharacteristics();
518 FreeKeyBlob();
519
Shawn Willden5b53c992015-02-02 08:05:25 -0700520 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(),
521 &blob_, &characteristics_))
522 << "Failed to generate size: " << size;
523
Shawn Willden95e13822014-12-15 16:12:16 -0700524 keymaster_key_param_t* out_params;
525 size_t out_params_count;
526 uint64_t op_handle;
527 EXPECT_EQ(KM_ERROR_OK, device()->begin(device(), KM_PURPOSE_ENCRYPT, &blob_, NULL, 0,
528 &out_params, &out_params_count, &op_handle))
529 << "Unsupported key size: " << size;
530 free(out_params);
Shawn Willden19fca882015-01-22 16:35:30 -0700531 }
532}
533
Shawn Willden76364712014-08-11 17:48:04 -0600534typedef KeymasterTest GetKeyCharacteristics;
535TEST_F(GetKeyCharacteristics, SimpleRsa) {
536 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700537 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
538 Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), Authorization(TAG_KEY_SIZE, 256),
539 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
540 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden76364712014-08-11 17:48:04 -0600541 };
542
Shawn Willden5b53c992015-02-02 08:05:25 -0700543 ASSERT_EQ(KM_ERROR_OK, device()->generate_key(device(), params, array_length(params), &blob_,
544 &characteristics_));
545 AuthorizationSet original(characteristics_->sw_enforced);
546 FreeCharacteristics();
Shawn Willden76364712014-08-11 17:48:04 -0600547
Shawn Willden5b53c992015-02-02 08:05:25 -0700548 keymaster_blob_t client_id = {.data = reinterpret_cast<const uint8_t*>("app_id"),
549 .data_length = 6};
550 ASSERT_EQ(KM_ERROR_OK,
551 device()->get_key_characteristics(device(), &blob_, &client_id, NULL /* app_data */,
552 &characteristics_));
553 EXPECT_EQ(original, AuthorizationSet(characteristics_->sw_enforced));
Shawn Willden76364712014-08-11 17:48:04 -0600554}
555
Shawn Willden61644f32014-08-18 13:43:14 -0600556/**
557 * Test class that provides some infrastructure for generating keys and signing messages.
558 */
Shawn Willden1615f2e2014-08-13 10:37:40 -0600559class SigningOperationsTest : public KeymasterTest {
560 protected:
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700561 SigningOperationsTest() {}
Shawn Willden5b53c992015-02-02 08:05:25 -0700562 ~SigningOperationsTest() {
563 // Clean up so (most) tests won't have to.
Shawn Willden5b53c992015-02-02 08:05:25 -0700564 FreeSignature();
565 }
566
Shawn Willden61644f32014-08-18 13:43:14 -0600567 void GenerateKey(keymaster_algorithm_t algorithm, keymaster_digest_t digest,
568 keymaster_padding_t padding, uint32_t key_size) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700569 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));
570 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY));
571 params_.push_back(Authorization(TAG_ALGORITHM, algorithm));
572 params_.push_back(Authorization(TAG_KEY_SIZE, key_size));
573 params_.push_back(Authorization(TAG_USER_ID, 7));
574 params_.push_back(Authorization(TAG_USER_AUTH_ID, 8));
575 params_.push_back(Authorization(TAG_APPLICATION_ID, "app_id", 6));
576 params_.push_back(Authorization(TAG_AUTH_TIMEOUT, 300));
Shawn Willden43e999e2014-08-13 13:29:50 -0600577 if (static_cast<int>(digest) != -1)
Shawn Willden5b53c992015-02-02 08:05:25 -0700578 params_.push_back(TAG_DIGEST, digest);
Shawn Willden43e999e2014-08-13 13:29:50 -0600579 if (static_cast<int>(padding) != -1)
Shawn Willden5b53c992015-02-02 08:05:25 -0700580 params_.push_back(TAG_PADDING, padding);
581
582 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(),
583 &blob_, &characteristics_));
Shawn Willden61644f32014-08-18 13:43:14 -0600584 }
Shawn Willden1615f2e2014-08-13 10:37:40 -0600585
Shawn Willden61644f32014-08-18 13:43:14 -0600586 void SignMessage(const void* message, size_t size) {
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700587 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_SIGN, blob_));
588 string result;
589 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, size, &result, &input_consumed_));
590 EXPECT_EQ(0, result.length());
Shawn Willden5b53c992015-02-02 08:05:25 -0700591 EXPECT_EQ(size, input_consumed_);
592
593 EXPECT_EQ(KM_ERROR_OK,
594 device()->finish(device(), op_handle_, NULL /* signature to verify */,
595 0 /* signature to verify length */, &signature_,
596 &signature_length_));
597 EXPECT_GT(signature_length_, 0);
Shawn Willden437fbd12014-08-20 11:59:49 -0600598 }
599
Shawn Willden5b53c992015-02-02 08:05:25 -0700600 void FreeSignature() {
601 free(signature_);
602 signature_ = NULL;
Shawn Willdenf268d742014-08-19 15:36:26 -0600603 }
604
Shawn Willden5b53c992015-02-02 08:05:25 -0700605 void corrupt_key_blob() {
606 uint8_t* tmp = const_cast<uint8_t*>(blob_.key_material);
607 ++tmp[blob_.key_material_size / 2];
Shawn Willden1615f2e2014-08-13 10:37:40 -0600608 }
Shawn Willden1615f2e2014-08-13 10:37:40 -0600609};
610
611TEST_F(SigningOperationsTest, RsaSuccess) {
Shawn Willden61644f32014-08-18 13:43:14 -0600612 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willdenffd790c2014-08-18 21:20:06 -0600613 const char message[] = "12345678901234567890123456789012";
Shawn Willdend05cba52014-09-26 09:58:12 -0600614 SignMessage(message, array_size(message) - 1);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600615}
616
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600617TEST_F(SigningOperationsTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600618 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willdend05cba52014-09-26 09:58:12 -0600619 const char message[] = "123456789012345678901234567890123456789012345678";
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700620 string signature;
Shawn Willdend05cba52014-09-26 09:58:12 -0600621 SignMessage(message, array_size(message) - 1);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600622}
623
Shawn Willden1615f2e2014-08-13 10:37:40 -0600624TEST_F(SigningOperationsTest, RsaAbort) {
Shawn Willden61644f32014-08-18 13:43:14 -0600625 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willden5b53c992015-02-02 08:05:25 -0700626 ASSERT_EQ(KM_ERROR_OK, device()->begin(device(), KM_PURPOSE_SIGN, &blob_, client_params_,
627 array_length(client_params_), &out_params_,
628 &out_params_count_, &op_handle_));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600629
Shawn Willden5b53c992015-02-02 08:05:25 -0700630 EXPECT_EQ(KM_ERROR_OK, device()->abort(device(), op_handle_));
631 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle_));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600632}
633
634TEST_F(SigningOperationsTest, RsaUnsupportedDigest) {
Shawn Willden61644f32014-08-18 13:43:14 -0600635 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_SHA_2_256, KM_PAD_NONE, 256 /* key size */);
Shawn Willden5b53c992015-02-02 08:05:25 -0700636 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST,
637 device()->begin(device(), KM_PURPOSE_SIGN, &blob_, client_params_,
638 array_length(client_params_), &out_params_, &out_params_count_,
639 &op_handle_));
640 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle_));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600641}
642
643TEST_F(SigningOperationsTest, RsaUnsupportedPadding) {
Shawn Willden61644f32014-08-18 13:43:14 -0600644 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_RSA_OAEP, 256 /* key size */);
Shawn Willden5b53c992015-02-02 08:05:25 -0700645 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE,
646 device()->begin(device(), KM_PURPOSE_SIGN, &blob_, client_params_,
647 array_length(client_params_), &out_params_, &out_params_count_,
648 &op_handle_));
649 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle_));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600650}
651
652TEST_F(SigningOperationsTest, RsaNoDigest) {
Shawn Willden61644f32014-08-18 13:43:14 -0600653 GenerateKey(KM_ALGORITHM_RSA, static_cast<keymaster_digest_t>(-1), KM_PAD_NONE,
654 256 /* key size */);
Shawn Willden5b53c992015-02-02 08:05:25 -0700655 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST,
656 device()->begin(device(), KM_PURPOSE_SIGN, &blob_, client_params_,
657 array_length(client_params_), &out_params_, &out_params_count_,
658 &op_handle_));
659 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle_));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600660}
661
662TEST_F(SigningOperationsTest, RsaNoPadding) {
Shawn Willden61644f32014-08-18 13:43:14 -0600663 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, static_cast<keymaster_padding_t>(-1),
664 256 /* key size */);
Shawn Willden5b53c992015-02-02 08:05:25 -0700665 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE,
666 device()->begin(device(), KM_PURPOSE_SIGN, &blob_, client_params_,
667 array_length(client_params_), &out_params_, &out_params_count_,
668 &op_handle_));
669 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle_));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600670}
671
672TEST_F(SigningOperationsTest, RsaTooShortMessage) {
Shawn Willden61644f32014-08-18 13:43:14 -0600673 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700674 ASSERT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_SIGN, key_blob()));
675
676 const char message[] = "012345678901234567890123456789";
677 string result;
678 size_t input_consumed;
Shawn Willden5b53c992015-02-02 08:05:25 -0700679 ASSERT_EQ(KM_ERROR_OK,
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700680 UpdateOperation(message, array_length(message), &result, &input_consumed));
681 EXPECT_EQ(0U, result.size());
682 EXPECT_EQ(31U, input_consumed);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600683
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700684 string signature;
685 ASSERT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&signature));
686 EXPECT_EQ(0U, signature.length());
Shawn Willden43e999e2014-08-13 13:29:50 -0600687}
688
Shawn Willdend05cba52014-09-26 09:58:12 -0600689class VerificationOperationsTest : public SigningOperationsTest {
690 protected:
691 void VerifyMessage(const void* message, size_t message_len) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700692 EXPECT_TRUE(signature_ != NULL);
Shawn Willdend05cba52014-09-26 09:58:12 -0600693
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700694 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_VERIFY, blob_));
695 string output;
696 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, message_len, &output, &input_consumed_));
697 EXPECT_EQ(0U, output.size());
Shawn Willden5b53c992015-02-02 08:05:25 -0700698 EXPECT_EQ(message_len, input_consumed_);
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700699 output.clear();
700 EXPECT_EQ(KM_ERROR_OK, FinishOperation(&output));
701 EXPECT_EQ(0U, output.size());
Shawn Willdend05cba52014-09-26 09:58:12 -0600702
Shawn Willden5b53c992015-02-02 08:05:25 -0700703 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle_));
Shawn Willdend05cba52014-09-26 09:58:12 -0600704 }
705};
706
Shawn Willden43e999e2014-08-13 13:29:50 -0600707TEST_F(VerificationOperationsTest, RsaSuccess) {
Shawn Willden61644f32014-08-18 13:43:14 -0600708 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
709 const char message[] = "12345678901234567890123456789012";
710 SignMessage(message, array_size(message) - 1);
Shawn Willdend05cba52014-09-26 09:58:12 -0600711 VerifyMessage(message, array_size(message) - 1);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600712}
713
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600714TEST_F(VerificationOperationsTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600715 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600716 const char message[] = "123456789012345678901234567890123456789012345678";
717 SignMessage(message, array_size(message) - 1);
Shawn Willdend05cba52014-09-26 09:58:12 -0600718 VerifyMessage(message, array_size(message) - 1);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600719}
720
Shawn Willden5b53c992015-02-02 08:05:25 -0700721typedef VerificationOperationsTest ExportKeyTest;
Shawn Willdenffd790c2014-08-18 21:20:06 -0600722TEST_F(ExportKeyTest, RsaSuccess) {
723 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willdenffd790c2014-08-18 21:20:06 -0600724
Shawn Willden5b53c992015-02-02 08:05:25 -0700725 uint8_t* export_data;
726 size_t export_data_length;
727 ASSERT_EQ(KM_ERROR_OK,
728 device()->export_key(device(), KM_KEY_FORMAT_X509, &blob_, &client_id_,
729 NULL /* app_data */, &export_data, &export_data_length));
730 EXPECT_TRUE(export_data != NULL);
731 EXPECT_GT(export_data_length, 0);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600732
733 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willden5b53c992015-02-02 08:05:25 -0700734 free(export_data);
Shawn Willdenffd790c2014-08-18 21:20:06 -0600735}
736
Shawn Willdenf268d742014-08-19 15:36:26 -0600737TEST_F(ExportKeyTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600738 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willdenf268d742014-08-19 15:36:26 -0600739
Shawn Willden5b53c992015-02-02 08:05:25 -0700740 uint8_t* export_data;
741 size_t export_data_length;
742 ASSERT_EQ(KM_ERROR_OK,
743 device()->export_key(device(), KM_KEY_FORMAT_X509, &blob_, &client_id_,
744 NULL /* app_data */, &export_data, &export_data_length));
745 EXPECT_TRUE(export_data != NULL);
746 EXPECT_GT(export_data_length, 0);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600747
748 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willden5b53c992015-02-02 08:05:25 -0700749 free(export_data);
Shawn Willdenf268d742014-08-19 15:36:26 -0600750}
751
752TEST_F(ExportKeyTest, RsaUnsupportedKeyFormat) {
753 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256);
754
Shawn Willden5b53c992015-02-02 08:05:25 -0700755 uint8_t dummy[] = {1};
756 uint8_t* export_data = dummy; // So it's not NULL;
757 size_t export_data_length;
758 ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_FORMAT,
759 device()->export_key(device(), KM_KEY_FORMAT_PKCS8, &blob_, &client_id_,
760 NULL /* app_data */, &export_data, &export_data_length));
761 ASSERT_TRUE(export_data == NULL);
Shawn Willdenf268d742014-08-19 15:36:26 -0600762}
763
764TEST_F(ExportKeyTest, RsaCorruptedKeyBlob) {
765 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256);
Shawn Willden5b53c992015-02-02 08:05:25 -0700766 corrupt_key_blob();
Shawn Willdenf268d742014-08-19 15:36:26 -0600767
Shawn Willden5b53c992015-02-02 08:05:25 -0700768 uint8_t dummy[] = {1};
769 uint8_t* export_data = dummy; // So it's not NULL
770 size_t export_data_length;
771 ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB,
772 device()->export_key(device(), KM_KEY_FORMAT_X509, &blob_, &client_id_,
773 NULL /* app_data */, &export_data, &export_data_length));
774 ASSERT_TRUE(export_data == NULL);
Shawn Willdenf268d742014-08-19 15:36:26 -0600775}
776
Shawn Willden437fbd12014-08-20 11:59:49 -0600777static string read_file(const string& file_name) {
778 ifstream file_stream(file_name, std::ios::binary);
779 istreambuf_iterator<char> file_begin(file_stream);
780 istreambuf_iterator<char> file_end;
781 return string(file_begin, file_end);
782}
783
Shawn Willden5b53c992015-02-02 08:05:25 -0700784class ImportKeyTest : public VerificationOperationsTest {
785 protected:
786 ImportKeyTest() {
787 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));
788 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY));
789 params_.push_back(Authorization(TAG_DIGEST, KM_DIGEST_NONE));
790 params_.push_back(Authorization(TAG_PADDING, KM_PAD_NONE));
791 params_.push_back(Authorization(TAG_USER_ID, 7));
792 params_.push_back(Authorization(TAG_USER_AUTH_ID, 8));
793 params_.push_back(Authorization(TAG_APPLICATION_ID, "app_id", 6));
794 params_.push_back(Authorization(TAG_AUTH_TIMEOUT, 300));
795 }
796};
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800797
Shawn Willden5b53c992015-02-02 08:05:25 -0700798TEST_F(ImportKeyTest, RsaSuccess) {
Shawn Willden81effc62014-08-27 10:08:46 -0600799 string pk8_key = read_file("rsa_privkey_pk8.der");
Shawn Willden437fbd12014-08-20 11:59:49 -0600800 ASSERT_EQ(633U, pk8_key.size());
801
Shawn Willden5b53c992015-02-02 08:05:25 -0700802 ASSERT_EQ(KM_ERROR_OK,
803 device()->import_key(device(), params_.data(), params_.size(), KM_KEY_FORMAT_PKCS8,
804 reinterpret_cast<const uint8_t*>(pk8_key.data()), pk8_key.size(),
805 &blob_, &characteristics_));
806 EXPECT_EQ(0U, characteristics_->hw_enforced.length);
807 AuthorizationSet auths(characteristics_->sw_enforced);
Shawn Willden437fbd12014-08-20 11:59:49 -0600808
809 // Check values derived from the key.
Shawn Willden5b53c992015-02-02 08:05:25 -0700810 EXPECT_TRUE(contains(auths, TAG_ALGORITHM, KM_ALGORITHM_RSA));
811 EXPECT_TRUE(contains(auths, TAG_KEY_SIZE, 1024));
812 EXPECT_TRUE(contains(auths, TAG_RSA_PUBLIC_EXPONENT, 65537U));
Shawn Willden437fbd12014-08-20 11:59:49 -0600813
814 // And values provided by GoogleKeymaster
Shawn Willden5b53c992015-02-02 08:05:25 -0700815 EXPECT_TRUE(contains(auths, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
816 EXPECT_TRUE(contains(auths, KM_TAG_CREATION_DATETIME));
Shawn Willden437fbd12014-08-20 11:59:49 -0600817
818 size_t message_len = 1024 / 8;
819 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
820 std::fill(message.get(), message.get() + message_len, 'a');
Shawn Willden5b53c992015-02-02 08:05:25 -0700821 SignMessage(message.get(), message_len);
822 VerifyMessage(message.get(), message_len);
Shawn Willden437fbd12014-08-20 11:59:49 -0600823}
824
Shawn Willden6bbe6782014-09-18 11:26:15 -0600825TEST_F(ImportKeyTest, RsaKeySizeMismatch) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700826 params_.push_back(Authorization(TAG_KEY_SIZE, 2048)); // Doesn't match key
Shawn Willden6bbe6782014-09-18 11:26:15 -0600827
828 string pk8_key = read_file("rsa_privkey_pk8.der");
829 ASSERT_EQ(633U, pk8_key.size());
830
Shawn Willden5b53c992015-02-02 08:05:25 -0700831 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
832 device()->import_key(device(), params_.data(), params_.size(), KM_KEY_FORMAT_PKCS8,
833 reinterpret_cast<const uint8_t*>(pk8_key.data()), pk8_key.size(),
834 &blob_, &characteristics_));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600835}
836
837TEST_F(ImportKeyTest, RsaPublicExponenMismatch) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700838 params_.push_back(Authorization(TAG_RSA_PUBLIC_EXPONENT, 3)); // Doesn't match key
Shawn Willden6bbe6782014-09-18 11:26:15 -0600839
840 string pk8_key = read_file("rsa_privkey_pk8.der");
841 ASSERT_EQ(633U, pk8_key.size());
842
Shawn Willden5b53c992015-02-02 08:05:25 -0700843 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
844 device()->import_key(device(), params_.data(), params_.size(), KM_KEY_FORMAT_PKCS8,
845 reinterpret_cast<const uint8_t*>(pk8_key.data()), pk8_key.size(),
846 &blob_, &characteristics_));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600847}
848
Shawn Willden81effc62014-08-27 10:08:46 -0600849TEST_F(ImportKeyTest, EcdsaSuccess) {
Shawn Willden81effc62014-08-27 10:08:46 -0600850 string pk8_key = read_file("ec_privkey_pk8.der");
851 ASSERT_EQ(138U, pk8_key.size());
852
Shawn Willden5b53c992015-02-02 08:05:25 -0700853 ASSERT_EQ(KM_ERROR_OK,
854 device()->import_key(device(), params_.data(), params_.size(), KM_KEY_FORMAT_PKCS8,
855 reinterpret_cast<const uint8_t*>(pk8_key.data()), pk8_key.size(),
856 &blob_, &characteristics_));
857 EXPECT_EQ(0U, characteristics_->hw_enforced.length);
858 AuthorizationSet auths(characteristics_->sw_enforced);
Shawn Willden81effc62014-08-27 10:08:46 -0600859
860 // Check values derived from the key.
Shawn Willden5b53c992015-02-02 08:05:25 -0700861 EXPECT_TRUE(contains(auths, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
862 EXPECT_TRUE(contains(auths, TAG_KEY_SIZE, 256));
Shawn Willden81effc62014-08-27 10:08:46 -0600863
864 // And values provided by GoogleKeymaster
Shawn Willden5b53c992015-02-02 08:05:25 -0700865 EXPECT_TRUE(contains(auths, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
866 EXPECT_TRUE(contains(auths, KM_TAG_CREATION_DATETIME));
Shawn Willden81effc62014-08-27 10:08:46 -0600867
Shawn Willden5b53c992015-02-02 08:05:25 -0700868 size_t message_len = 1024;
Shawn Willden81effc62014-08-27 10:08:46 -0600869 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
870 std::fill(message.get(), message.get() + message_len, 'a');
Shawn Willden5b53c992015-02-02 08:05:25 -0700871 SignMessage(message.get(), message_len);
872 VerifyMessage(message.get(), message_len);
Shawn Willden81effc62014-08-27 10:08:46 -0600873}
874
Shawn Willden5b53c992015-02-02 08:05:25 -0700875TEST_F(ImportKeyTest, EcdsaKeySizeMismatch) {
876 params_.push_back(Authorization(TAG_KEY_SIZE, 224)); // Doesn't match key
Shawn Willden6bbe6782014-09-18 11:26:15 -0600877
Shawn Willden5b53c992015-02-02 08:05:25 -0700878 string pk8_key = read_file("rsa_privkey_pk8.der");
879 ASSERT_EQ(633U, pk8_key.size());
Shawn Willden6bbe6782014-09-18 11:26:15 -0600880
Shawn Willden5b53c992015-02-02 08:05:25 -0700881 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
882 device()->import_key(device(), params_.data(), params_.size(), KM_KEY_FORMAT_PKCS8,
883 reinterpret_cast<const uint8_t*>(pk8_key.data()), pk8_key.size(),
884 &blob_, &characteristics_));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600885}
886
Shawn Willden2665e862014-11-24 14:46:21 -0700887typedef KeymasterTest VersionTest;
888TEST_F(VersionTest, GetVersion) {
889 GetVersionRequest req;
890 GetVersionResponse rsp;
Shawn Willden5b53c992015-02-02 08:05:25 -0700891 device_.GetVersion(req, &rsp);
Shawn Willden2665e862014-11-24 14:46:21 -0700892 EXPECT_EQ(KM_ERROR_OK, rsp.error);
893 EXPECT_EQ(1, rsp.major_ver);
894 EXPECT_EQ(0, rsp.minor_ver);
895 EXPECT_EQ(0, rsp.subminor_ver);
896}
897
Shawn Willden4200f212014-12-02 07:01:21 -0700898/**
899 * Test class that provides some infrastructure for generating keys and encrypting messages.
900 */
901class EncryptionOperationsTest : public KeymasterTest {
902 protected:
Shawn Willdenbe4a2a32014-12-15 14:51:10 -0700903 void GenerateKey(AuthorizationSet* params) {
904 FreeKeyBlob();
905 FreeCharacteristics();
906 AddClientParams(params);
907 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params->data(), params->size(),
908 &blob_, &characteristics_));
909 }
910
Shawn Willden4200f212014-12-02 07:01:21 -0700911 void GenerateKey(keymaster_algorithm_t algorithm, keymaster_padding_t padding,
912 uint32_t key_size) {
Shawn Willden6dde87c2014-12-11 14:08:48 -0700913 params_.Clear();
Shawn Willden5b53c992015-02-02 08:05:25 -0700914 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
915 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT));
916 params_.push_back(Authorization(TAG_ALGORITHM, algorithm));
917 params_.push_back(Authorization(TAG_KEY_SIZE, key_size));
918 params_.push_back(Authorization(TAG_USER_ID, 7));
919 params_.push_back(Authorization(TAG_USER_AUTH_ID, 8));
Shawn Willden5b53c992015-02-02 08:05:25 -0700920 params_.push_back(Authorization(TAG_AUTH_TIMEOUT, 300));
Shawn Willden4200f212014-12-02 07:01:21 -0700921 if (static_cast<int>(padding) != -1)
Shawn Willden5b53c992015-02-02 08:05:25 -0700922 params_.push_back(TAG_PADDING, padding);
Shawn Willden6dde87c2014-12-11 14:08:48 -0700923
Shawn Willdenbe4a2a32014-12-15 14:51:10 -0700924 GenerateKey(&params_);
Shawn Willden4200f212014-12-02 07:01:21 -0700925 }
926
Shawn Willden907c3012014-12-08 15:51:55 -0700927 void GenerateSymmetricKey(keymaster_algorithm_t algorithm, uint32_t key_size,
928 keymaster_block_mode_t block_mode, uint32_t chunk_length) {
Shawn Willden6dde87c2014-12-11 14:08:48 -0700929 params_.Clear();
Shawn Willden5b53c992015-02-02 08:05:25 -0700930 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
931 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT));
932 params_.push_back(Authorization(TAG_ALGORITHM, algorithm));
933 params_.push_back(Authorization(TAG_BLOCK_MODE, block_mode));
934 params_.push_back(Authorization(TAG_CHUNK_LENGTH, chunk_length));
935 params_.push_back(Authorization(TAG_KEY_SIZE, key_size));
936 params_.push_back(Authorization(TAG_MAC_LENGTH, 16));
937 params_.push_back(Authorization(TAG_USER_ID, 7));
938 params_.push_back(Authorization(TAG_USER_AUTH_ID, 8));
Shawn Willden5b53c992015-02-02 08:05:25 -0700939 params_.push_back(Authorization(TAG_AUTH_TIMEOUT, 300));
940
Shawn Willdenbe4a2a32014-12-15 14:51:10 -0700941 GenerateKey(&params_);
Shawn Willden907c3012014-12-08 15:51:55 -0700942 }
943
Shawn Willden4200f212014-12-02 07:01:21 -0700944 string ProcessMessage(keymaster_purpose_t purpose, const keymaster_key_blob_t& key_blob,
945 const void* message, size_t size) {
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700946 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose, key_blob));
Shawn Willden4200f212014-12-02 07:01:21 -0700947
948 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -0700949 size_t input_consumed;
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700950 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, size, &result, &input_consumed));
Shawn Willdenb7361132014-12-08 08:15:14 -0700951 EXPECT_EQ(size, input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700952 EXPECT_EQ(KM_ERROR_OK, FinishOperation(&result));
953 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle_));
Shawn Willden4200f212014-12-02 07:01:21 -0700954 return result;
955 }
956
Shawn Willden6dde87c2014-12-11 14:08:48 -0700957 string EncryptMessage(const string& message) {
958 return ProcessMessage(KM_PURPOSE_ENCRYPT, blob_, message.c_str(), message.length());
Shawn Willden4200f212014-12-02 07:01:21 -0700959 }
960
Shawn Willden6dde87c2014-12-11 14:08:48 -0700961 string DecryptMessage(const string& ciphertext) {
962 return ProcessMessage(KM_PURPOSE_DECRYPT, blob_, ciphertext.c_str(), ciphertext.length());
Shawn Willden4200f212014-12-02 07:01:21 -0700963 }
964
965 void AddClientParams(AuthorizationSet* set) { set->push_back(TAG_APPLICATION_ID, "app_id", 6); }
966
Shawn Willden5b53c992015-02-02 08:05:25 -0700967 const void corrupt_key_blob() {
968 uint8_t* tmp = const_cast<uint8_t*>(blob_.key_material);
969 ++tmp[blob_.key_material_size / 2];
Shawn Willden4200f212014-12-02 07:01:21 -0700970 }
971
Shawn Willden5b53c992015-02-02 08:05:25 -0700972 keymaster_blob_t client_id_ = {.data = reinterpret_cast<const uint8_t*>("app_id"),
973 .data_length = 6};
974 keymaster_key_param_t client_params_[1] = {
975 Authorization(TAG_APPLICATION_ID, client_id_.data, client_id_.data_length)};
976
977 keymaster_key_param_t* out_params_;
978 size_t out_params_count_;
Shawn Willden4200f212014-12-02 07:01:21 -0700979};
980
981TEST_F(EncryptionOperationsTest, RsaOaepSuccess) {
982 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
983 const char message[] = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -0700984 string ciphertext1 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -0700985 EXPECT_EQ(512 / 8, ciphertext1.size());
986
Shawn Willden6dde87c2014-12-11 14:08:48 -0700987 string ciphertext2 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -0700988 EXPECT_EQ(512 / 8, ciphertext2.size());
989
990 // OAEP randomizes padding so every result should be different.
991 EXPECT_NE(ciphertext1, ciphertext2);
992}
993
994TEST_F(EncryptionOperationsTest, RsaOaepRoundTrip) {
995 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
996 const char message[] = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -0700997 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -0700998 EXPECT_EQ(512 / 8, ciphertext.size());
999
Shawn Willden6dde87c2014-12-11 14:08:48 -07001000 string plaintext = DecryptMessage(ciphertext);
Shawn Willden4200f212014-12-02 07:01:21 -07001001 EXPECT_EQ(message, plaintext);
1002}
1003
1004TEST_F(EncryptionOperationsTest, RsaOaepTooLarge) {
1005 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1006 const char message[] = "12345678901234567890123";
Shawn Willden4200f212014-12-02 07:01:21 -07001007 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001008 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001009
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001010 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT, blob_));
1011 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, array_size(message), &result, &input_consumed));
1012 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -07001013 EXPECT_EQ(0, result.size());
1014}
1015
1016TEST_F(EncryptionOperationsTest, RsaOaepCorruptedDecrypt) {
1017 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1018 const char message[] = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001019 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001020 EXPECT_EQ(512 / 8, ciphertext.size());
1021
1022 // Corrupt the ciphertext
1023 ciphertext[512 / 8 / 2]++;
1024
Shawn Willden4200f212014-12-02 07:01:21 -07001025 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001026 size_t input_consumed;
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001027 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, blob_));
1028 EXPECT_EQ(KM_ERROR_OK,
1029 UpdateOperation(ciphertext.data(), ciphertext.size(), &result, &input_consumed));
1030 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -07001031 EXPECT_EQ(0, result.size());
1032}
1033
1034TEST_F(EncryptionOperationsTest, RsaPkcs1Success) {
1035 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1036 const char message[] = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001037 string ciphertext1 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001038 EXPECT_EQ(512 / 8, ciphertext1.size());
1039
Shawn Willden6dde87c2014-12-11 14:08:48 -07001040 string ciphertext2 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001041 EXPECT_EQ(512 / 8, ciphertext2.size());
1042
1043 // PKCS1 v1.5 randomizes padding so every result should be different.
1044 EXPECT_NE(ciphertext1, ciphertext2);
1045}
1046
1047TEST_F(EncryptionOperationsTest, RsaPkcs1RoundTrip) {
1048 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1049 const char message[] = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001050 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001051 EXPECT_EQ(512 / 8, ciphertext.size());
1052
Shawn Willden6dde87c2014-12-11 14:08:48 -07001053 string plaintext = DecryptMessage(ciphertext);
Shawn Willden4200f212014-12-02 07:01:21 -07001054 EXPECT_EQ(message, plaintext);
1055}
1056
1057TEST_F(EncryptionOperationsTest, RsaPkcs1TooLarge) {
1058 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1059 const char message[] = "1234567890123456789012345678901234567890123456789012";
Shawn Willden4200f212014-12-02 07:01:21 -07001060 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001061 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001062
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001063 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT, blob_));
1064 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, array_size(message), &result, &input_consumed));
1065 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -07001066 EXPECT_EQ(0, result.size());
1067}
1068
1069TEST_F(EncryptionOperationsTest, RsaPkcs1CorruptedDecrypt) {
1070 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1071 const char message[] = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001072 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001073 EXPECT_EQ(512 / 8, ciphertext.size());
1074
1075 // Corrupt the ciphertext
1076 ciphertext[512 / 8 / 2]++;
1077
Shawn Willden4200f212014-12-02 07:01:21 -07001078 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001079 size_t input_consumed;
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001080 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, blob_));
1081 EXPECT_EQ(KM_ERROR_OK,
1082 UpdateOperation(ciphertext.data(), ciphertext.size(), &result, &input_consumed));
1083 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -07001084 EXPECT_EQ(0, result.size());
1085}
1086
Shawn Willden907c3012014-12-08 15:51:55 -07001087TEST_F(EncryptionOperationsTest, AesOcbSuccess) {
1088 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1089 const char message[] = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001090 string ciphertext1 = EncryptMessage(string(message));
Shawn Willden907c3012014-12-08 15:51:55 -07001091 EXPECT_EQ(12 /* nonce */ + strlen(message) + 16 /* tag */, ciphertext1.size());
1092
Shawn Willden6dde87c2014-12-11 14:08:48 -07001093 string ciphertext2 = EncryptMessage(string(message));
Shawn Willden907c3012014-12-08 15:51:55 -07001094 EXPECT_EQ(12 /* nonce */ + strlen(message) + 16 /* tag */, ciphertext2.size());
1095
1096 // OCB uses a random nonce, so every output should be different
1097 EXPECT_NE(ciphertext1, ciphertext2);
1098}
1099
Shawn Willden6dde87c2014-12-11 14:08:48 -07001100TEST_F(EncryptionOperationsTest, AesOcbRoundTripSuccess) {
1101 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1102 string message = "Hello World!";
1103 string ciphertext = EncryptMessage(message);
1104 EXPECT_EQ(12 /* nonce */ + message.length() + 16 /* tag */, ciphertext.size());
1105
1106 string plaintext = DecryptMessage(ciphertext);
1107 EXPECT_EQ(message, plaintext);
1108}
1109
1110TEST_F(EncryptionOperationsTest, AesOcbRoundTripCorrupted) {
1111 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1112 const char message[] = "Hello World!";
1113 string ciphertext = EncryptMessage(string(message));
1114 EXPECT_EQ(12 /* nonce */ + strlen(message) + 16 /* tag */, ciphertext.size());
1115
1116 ciphertext[ciphertext.size() / 2]++;
1117
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001118 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, key_blob()));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001119
1120 string result;
1121 size_t input_consumed;
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001122 EXPECT_EQ(KM_ERROR_OK,
1123 UpdateOperation(ciphertext.c_str(), ciphertext.length(), &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001124 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001125 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001126}
1127
1128TEST_F(EncryptionOperationsTest, AesDecryptGarbage) {
1129 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1130 string ciphertext(128, 'a');
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001131 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, key_blob()));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001132
1133 string result;
1134 size_t input_consumed;
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001135 EXPECT_EQ(KM_ERROR_OK,
1136 UpdateOperation(ciphertext.c_str(), ciphertext.length(), &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001137 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001138 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001139}
1140
1141TEST_F(EncryptionOperationsTest, AesDecryptTooShort) {
1142 // Try decrypting garbage ciphertext that is too short to be valid (< nonce + tag).
1143 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1144 string ciphertext(12 + 15, 'a');
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001145 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, key_blob()));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001146
1147 string result;
1148 size_t input_consumed;
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001149 EXPECT_EQ(KM_ERROR_OK,
1150 UpdateOperation(ciphertext.c_str(), ciphertext.length(), &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001151 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001152 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001153}
1154
1155TEST_F(EncryptionOperationsTest, AesOcbRoundTripEmptySuccess) {
1156 // Empty messages should work fine.
1157 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1158 const char message[] = "";
1159 string ciphertext = EncryptMessage(string(message));
1160 EXPECT_EQ(12 /* nonce */ + strlen(message) + 16 /* tag */, ciphertext.size());
1161
1162 string plaintext = DecryptMessage(ciphertext);
1163 EXPECT_EQ(message, plaintext);
1164}
1165
1166TEST_F(EncryptionOperationsTest, AesOcbRoundTripEmptyCorrupted) {
1167 // Should even detect corruption of empty messages.
1168 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1169 const char message[] = "";
1170 string ciphertext = EncryptMessage(string(message));
1171 EXPECT_EQ(12 /* nonce */ + strlen(message) + 16 /* tag */, ciphertext.size());
1172
1173 ciphertext[ciphertext.size() / 2]++;
1174
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001175 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, key_blob()));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001176
1177 string result;
1178 size_t input_consumed;
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001179 EXPECT_EQ(KM_ERROR_OK,
1180 UpdateOperation(ciphertext.c_str(), ciphertext.length(), &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001181 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001182 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001183}
1184
1185TEST_F(EncryptionOperationsTest, AesOcbFullChunk) {
1186 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1187 string message(4096, 'a');
1188 string ciphertext = EncryptMessage(message);
1189 EXPECT_EQ(12 /* nonce */ + message.length() + 16 /* tag */, ciphertext.size());
1190
1191 string plaintext = DecryptMessage(ciphertext);
1192 EXPECT_EQ(message, plaintext);
1193}
1194
1195TEST_F(EncryptionOperationsTest, AesOcbVariousChunkLengths) {
1196 for (unsigned chunk_length = 1; chunk_length <= 128; ++chunk_length) {
1197 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, chunk_length);
1198 string message(128, 'a');
1199 string ciphertext = EncryptMessage(message);
1200 int expected_tag_count = (message.length() + chunk_length - 1) / chunk_length;
1201 EXPECT_EQ(12 /* nonce */ + message.length() + 16 * expected_tag_count, ciphertext.size())
1202 << "Unexpected ciphertext size for chunk length " << chunk_length
1203 << " expected tag count was " << expected_tag_count
1204 << " but actual tag count was probably "
1205 << (ciphertext.size() - message.length() - 12) / 16;
1206
1207 string plaintext = DecryptMessage(ciphertext);
1208 EXPECT_EQ(message, plaintext);
1209 }
1210}
1211
1212TEST_F(EncryptionOperationsTest, AesOcbAbort) {
1213 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1214 const char message[] = "Hello";
1215
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001216 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT, key_blob()));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001217
1218 string result;
1219 size_t input_consumed;
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001220 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, strlen(message), &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001221 EXPECT_EQ(strlen(message), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001222 EXPECT_EQ(KM_ERROR_OK, device()->abort(device(), op_handle_));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001223}
1224
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001225TEST_F(EncryptionOperationsTest, AesOcbNoChunkLength) {
1226 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
1227 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT));
1228 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES));
1229 params_.push_back(Authorization(TAG_KEY_SIZE, 128));
1230 params_.push_back(Authorization(TAG_MAC_LENGTH, 16));
1231 params_.push_back(Authorization(TAG_BLOCK_MODE, KM_MODE_OCB));
1232 params_.push_back(Authorization(TAG_PADDING, KM_PAD_NONE));
1233
1234 GenerateKey(&params_);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001235 EXPECT_EQ(KM_ERROR_INVALID_ARGUMENT, BeginOperation(KM_PURPOSE_ENCRYPT, key_blob()));
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001236}
1237
1238TEST_F(EncryptionOperationsTest, AesEcbUnsupported) {
1239 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
1240 params_.push_back(Authorization(TAG_MAC_LENGTH, 16));
1241 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT));
1242 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES));
1243 params_.push_back(Authorization(TAG_KEY_SIZE, 128));
1244 params_.push_back(Authorization(TAG_BLOCK_MODE, KM_MODE_ECB));
1245 params_.push_back(Authorization(TAG_PADDING, KM_PAD_NONE));
1246
1247 GenerateKey(&params_);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001248 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE, BeginOperation(KM_PURPOSE_ENCRYPT, key_blob()));
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001249}
1250
1251TEST_F(EncryptionOperationsTest, AesOcbPaddingUnsupported) {
1252 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
1253 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT));
1254 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES));
1255 params_.push_back(Authorization(TAG_KEY_SIZE, 128));
1256 params_.push_back(Authorization(TAG_MAC_LENGTH, 16));
1257 params_.push_back(Authorization(TAG_BLOCK_MODE, KM_MODE_OCB));
1258 params_.push_back(Authorization(TAG_CHUNK_LENGTH, 4096));
1259 params_.push_back(Authorization(TAG_PADDING, KM_PAD_ZERO));
1260
1261 GenerateKey(&params_);
1262 uint64_t op_handle;
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001263 EXPECT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, BeginOperation(KM_PURPOSE_ENCRYPT, key_blob()));
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001264}
1265
1266TEST_F(EncryptionOperationsTest, AesOcbInvalidMacLength) {
1267 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
1268 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT));
1269 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES));
1270 params_.push_back(Authorization(TAG_KEY_SIZE, 128));
1271 params_.push_back(Authorization(TAG_MAC_LENGTH, 17));
1272 params_.push_back(Authorization(TAG_BLOCK_MODE, KM_MODE_OCB));
1273 params_.push_back(Authorization(TAG_CHUNK_LENGTH, 4096));
1274
1275 GenerateKey(&params_);
1276 uint64_t op_handle;
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001277 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, BeginOperation(KM_PURPOSE_ENCRYPT, key_blob()));
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001278}
1279
Shawn Willden128ffe02014-08-06 12:31:33 -06001280} // namespace test
1281} // namespace keymaster