blob: f5a9f6ba4f7de2b9340c58341ffb8c6bb54ebb69 [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 Willden128ffe02014-08-06 12:31:33 -060073class KeymasterTest : public testing::Test {
74 protected:
Shawn Willden5b53c992015-02-02 08:05:25 -070075 KeymasterTest() : device_(new StdoutLogger), characteristics_(NULL) {
76 blob_.key_material = NULL;
77 RAND_seed("foobar", 6);
78 }
79 ~KeymasterTest() {
80 FreeCharacteristics();
81 FreeKeyBlob();
Shawn Willdend0772312014-09-18 12:27:57 -060082 }
83
Shawn Willden5b53c992015-02-02 08:05:25 -070084 keymaster_device* device() { return reinterpret_cast<keymaster_device*>(device_.hw_device()); }
85
86 template <typename T> void ExpectContains(T val, T* vals, size_t len) {
87 EXPECT_EQ(1U, len);
88 EXPECT_EQ(val, vals[0]);
Shawn Willdend0772312014-09-18 12:27:57 -060089 }
90
Shawn Willden5b53c992015-02-02 08:05:25 -070091 void FreeCharacteristics() {
92 keymaster_free_characteristics(characteristics_);
93 free(characteristics_);
94 characteristics_ = NULL;
95 }
96
97 void FreeKeyBlob() {
98 free(const_cast<uint8_t*>(blob_.key_material));
99 blob_.key_material = NULL;
100 }
101
Shawn Willden6dde87c2014-12-11 14:08:48 -0700102 const keymaster_key_blob_t& key_blob() { return blob_; }
103
Shawn Willden5b53c992015-02-02 08:05:25 -0700104 SoftKeymasterDevice device_;
105
106 AuthorizationSet params_;
107 keymaster_key_blob_t blob_;
108 keymaster_key_characteristics_t* characteristics_;
Shawn Willden128ffe02014-08-06 12:31:33 -0600109};
110
Shawn Willden128ffe02014-08-06 12:31:33 -0600111typedef KeymasterTest CheckSupported;
112TEST_F(CheckSupported, SupportedAlgorithms) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700113 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
114 device()->get_supported_algorithms(device(), NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600115
Shawn Willden5b53c992015-02-02 08:05:25 -0700116 size_t len;
117 keymaster_algorithm_t* algorithms;
118 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_algorithms(device(), &algorithms, &len));
119 ASSERT_EQ(4U, len);
120 EXPECT_EQ(KM_ALGORITHM_RSA, algorithms[0]);
121 EXPECT_EQ(KM_ALGORITHM_DSA, algorithms[1]);
122 EXPECT_EQ(KM_ALGORITHM_ECDSA, algorithms[2]);
123 EXPECT_EQ(KM_ALGORITHM_AES, algorithms[3]);
124
125 free(algorithms);
Shawn Willden128ffe02014-08-06 12:31:33 -0600126}
127
128TEST_F(CheckSupported, SupportedBlockModes) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700129 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
130 device()->get_supported_block_modes(device(), KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT,
131 NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600132
Shawn Willden5b53c992015-02-02 08:05:25 -0700133 size_t len;
134 keymaster_block_mode_t* modes;
135 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE,
136 device()->get_supported_block_modes(device(), KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT,
137 &modes, &len));
Shawn Willden128ffe02014-08-06 12:31:33 -0600138
Shawn Willden5b53c992015-02-02 08:05:25 -0700139 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE,
140 device()->get_supported_block_modes(device(), KM_ALGORITHM_DSA, KM_PURPOSE_ENCRYPT,
141 &modes, &len));
Shawn Willden28e41472014-08-18 13:35:22 -0600142
Shawn Willden5b53c992015-02-02 08:05:25 -0700143 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE,
144 device()->get_supported_block_modes(device(), KM_ALGORITHM_ECDSA, KM_PURPOSE_ENCRYPT,
145 &modes, &len));
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600146
Shawn Willden5b53c992015-02-02 08:05:25 -0700147 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE,
148 device()->get_supported_block_modes(device(), KM_ALGORITHM_AES, KM_PURPOSE_ENCRYPT,
149 &modes, &len));
Shawn Willden128ffe02014-08-06 12:31:33 -0600150}
151
152TEST_F(CheckSupported, SupportedPaddingModes) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700153 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
154 device()->get_supported_padding_modes(device(), KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT,
155 NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600156
Shawn Willden5b53c992015-02-02 08:05:25 -0700157 size_t len;
158 keymaster_padding_t* modes;
159 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_RSA,
160 KM_PURPOSE_SIGN, &modes, &len));
161 ExpectContains(KM_PAD_NONE, modes, len);
162 free(modes);
Shawn Willden128ffe02014-08-06 12:31:33 -0600163
Shawn Willden5b53c992015-02-02 08:05:25 -0700164 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_DSA,
165 KM_PURPOSE_SIGN, &modes, &len));
166 ExpectContains(KM_PAD_NONE, modes, len);
167 free(modes);
Shawn Willden28e41472014-08-18 13:35:22 -0600168
Shawn Willden5b53c992015-02-02 08:05:25 -0700169 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_ECDSA,
170 KM_PURPOSE_SIGN, &modes, &len));
171 ExpectContains(KM_PAD_NONE, modes, len);
172 free(modes);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600173
Shawn Willden5b53c992015-02-02 08:05:25 -0700174 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_AES,
175 KM_PURPOSE_SIGN, &modes, &len));
176 EXPECT_EQ(0, len);
177 free(modes);
Shawn Willden128ffe02014-08-06 12:31:33 -0600178}
179
180TEST_F(CheckSupported, SupportedDigests) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700181 EXPECT_EQ(
182 KM_ERROR_OUTPUT_PARAMETER_NULL,
183 device()->get_supported_digests(device(), KM_ALGORITHM_RSA, KM_PURPOSE_SIGN, NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600184
Shawn Willden5b53c992015-02-02 08:05:25 -0700185 size_t len;
186 keymaster_digest_t* digests;
187 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_RSA,
188 KM_PURPOSE_SIGN, &digests, &len));
189 ExpectContains(KM_DIGEST_NONE, digests, len);
190 free(digests);
Shawn Willden128ffe02014-08-06 12:31:33 -0600191
Shawn Willden5b53c992015-02-02 08:05:25 -0700192 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_DSA,
193 KM_PURPOSE_SIGN, &digests, &len));
194 ExpectContains(KM_DIGEST_NONE, digests, len);
195 free(digests);
Shawn Willden28e41472014-08-18 13:35:22 -0600196
Shawn Willden5b53c992015-02-02 08:05:25 -0700197 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_ECDSA,
198 KM_PURPOSE_SIGN, &digests, &len));
199 ExpectContains(KM_DIGEST_NONE, digests, len);
200 free(digests);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600201
Shawn Willden5b53c992015-02-02 08:05:25 -0700202 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_AES,
203 KM_PURPOSE_SIGN, &digests, &len));
204 EXPECT_EQ(0, len);
205 free(digests);
Shawn Willden128ffe02014-08-06 12:31:33 -0600206}
207
208TEST_F(CheckSupported, SupportedImportFormats) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700209 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
210 device()->get_supported_import_formats(device(), KM_ALGORITHM_RSA, NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600211
Shawn Willden5b53c992015-02-02 08:05:25 -0700212 size_t len;
213 keymaster_key_format_t* formats;
214 EXPECT_EQ(KM_ERROR_OK,
215 device()->get_supported_import_formats(device(), KM_ALGORITHM_RSA, &formats, &len));
216 ExpectContains(KM_KEY_FORMAT_PKCS8, formats, len);
217 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600218
Shawn Willden5b53c992015-02-02 08:05:25 -0700219 EXPECT_EQ(KM_ERROR_OK,
220 device()->get_supported_import_formats(device(), KM_ALGORITHM_DSA, &formats, &len));
221 ExpectContains(KM_KEY_FORMAT_PKCS8, formats, len);
222 free(formats);
Shawn Willden28e41472014-08-18 13:35:22 -0600223
Shawn Willden5b53c992015-02-02 08:05:25 -0700224 EXPECT_EQ(KM_ERROR_OK,
225 device()->get_supported_import_formats(device(), KM_ALGORITHM_ECDSA, &formats, &len));
226 ExpectContains(KM_KEY_FORMAT_PKCS8, formats, len);
227 free(formats);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600228
Shawn Willden5b53c992015-02-02 08:05:25 -0700229 EXPECT_EQ(KM_ERROR_OK,
230 device()->get_supported_import_formats(device(), KM_ALGORITHM_AES, &formats, &len));
231 EXPECT_EQ(0, len);
232 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600233}
234
235TEST_F(CheckSupported, SupportedExportFormats) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700236 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
237 device()->get_supported_export_formats(device(), KM_ALGORITHM_RSA, NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600238
Shawn Willden5b53c992015-02-02 08:05:25 -0700239 size_t len;
240 keymaster_key_format_t* formats;
241 EXPECT_EQ(KM_ERROR_OK,
242 device()->get_supported_export_formats(device(), KM_ALGORITHM_RSA, &formats, &len));
243 ExpectContains(KM_KEY_FORMAT_X509, formats, len);
244 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600245
Shawn Willden5b53c992015-02-02 08:05:25 -0700246 EXPECT_EQ(KM_ERROR_OK,
247 device()->get_supported_export_formats(device(), KM_ALGORITHM_DSA, &formats, &len));
248 ExpectContains(KM_KEY_FORMAT_X509, formats, len);
249 free(formats);
Shawn Willden28e41472014-08-18 13:35:22 -0600250
Shawn Willden5b53c992015-02-02 08:05:25 -0700251 EXPECT_EQ(KM_ERROR_OK,
252 device()->get_supported_export_formats(device(), KM_ALGORITHM_ECDSA, &formats, &len));
253 ExpectContains(KM_KEY_FORMAT_X509, formats, len);
254 free(formats);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600255
Shawn Willden5b53c992015-02-02 08:05:25 -0700256 EXPECT_EQ(KM_ERROR_OK,
257 device()->get_supported_export_formats(device(), KM_ALGORITHM_AES, &formats, &len));
258 EXPECT_EQ(0, len);
259 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600260}
261
Shawn Willdend0772312014-09-18 12:27:57 -0600262keymaster_key_param_t key_generation_base_params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700263 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
264 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
Shawn Willdend0772312014-09-18 12:27:57 -0600265 Authorization(TAG_APPLICATION_ID, "app_id", 6),
Shawn Willden3809b932014-12-02 06:59:46 -0700266 Authorization(TAG_APPLICATION_DATA, "app_data", 8), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willdend0772312014-09-18 12:27:57 -0600267};
268
Shawn Willden5b53c992015-02-02 08:05:25 -0700269TEST_F(KeymasterTest, TestFlags) {
270 EXPECT_TRUE(device()->flags & KEYMASTER_SOFTWARE_ONLY);
271 EXPECT_TRUE(device()->flags & KEYMASTER_BLOBS_ARE_STANDALONE);
272 EXPECT_FALSE(device()->flags & KEYMASTER_SUPPORTS_DSA);
273 EXPECT_TRUE(device()->flags & KEYMASTER_SUPPORTS_EC);
274}
275
276typedef KeymasterTest OldKeyGeneration;
277
278TEST_F(OldKeyGeneration, Rsa) {
279 keymaster_rsa_keygen_params_t params = {.modulus_size = 256, .public_exponent = 3};
280 uint8_t* key_blob;
281 size_t key_blob_length;
282 EXPECT_EQ(0,
283 device()->generate_keypair(device(), TYPE_RSA, &params, &key_blob, &key_blob_length));
284 EXPECT_GT(key_blob_length, 0);
285
286 free(key_blob);
287}
288
289TEST_F(OldKeyGeneration, Ecdsa) {
290
291 keymaster_ec_keygen_params_t params = {.field_size = 256};
292 uint8_t* key_blob;
293 size_t key_blob_length;
294 EXPECT_EQ(0,
295 device()->generate_keypair(device(), TYPE_EC, &params, &key_blob, &key_blob_length));
296 EXPECT_GT(key_blob_length, 0);
297
298 free(key_blob);
299}
300
Shawn Willdend0772312014-09-18 12:27:57 -0600301class NewKeyGeneration : public KeymasterTest {
302 protected:
303 NewKeyGeneration() {
Shawn Willden5b53c992015-02-02 08:05:25 -0700304 params_.Reinitialize(key_generation_base_params, array_length(key_generation_base_params));
Shawn Willdend0772312014-09-18 12:27:57 -0600305 }
306
Shawn Willden5b53c992015-02-02 08:05:25 -0700307 void CheckBaseParams(const AuthorizationSet& auths) {
308 EXPECT_TRUE(contains(auths, TAG_PURPOSE, KM_PURPOSE_SIGN));
309 EXPECT_TRUE(contains(auths, TAG_PURPOSE, KM_PURPOSE_VERIFY));
310 EXPECT_TRUE(contains(auths, TAG_USER_ID, 7));
311 EXPECT_TRUE(contains(auths, TAG_USER_AUTH_ID, 8));
312 EXPECT_TRUE(contains(auths, TAG_AUTH_TIMEOUT, 300));
Shawn Willdend0772312014-09-18 12:27:57 -0600313
314 // Verify that App ID, App data and ROT are NOT included.
Shawn Willden5b53c992015-02-02 08:05:25 -0700315 EXPECT_FALSE(contains(auths, TAG_ROOT_OF_TRUST));
316 EXPECT_FALSE(contains(auths, TAG_APPLICATION_ID));
317 EXPECT_FALSE(contains(auths, TAG_APPLICATION_DATA));
Shawn Willdend0772312014-09-18 12:27:57 -0600318
319 // Just for giggles, check that some unexpected tags/values are NOT present.
Shawn Willden5b53c992015-02-02 08:05:25 -0700320 EXPECT_FALSE(contains(auths, TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
321 EXPECT_FALSE(contains(auths, TAG_PURPOSE, KM_PURPOSE_DECRYPT));
322 EXPECT_FALSE(contains(auths, TAG_AUTH_TIMEOUT, 301));
Shawn Willdend0772312014-09-18 12:27:57 -0600323
324 // Now check that unspecified, defaulted tags are correct.
Shawn Willden5b53c992015-02-02 08:05:25 -0700325 EXPECT_TRUE(contains(auths, TAG_ORIGIN, KM_ORIGIN_SOFTWARE));
326 EXPECT_TRUE(contains(auths, KM_TAG_CREATION_DATETIME));
Shawn Willdend0772312014-09-18 12:27:57 -0600327 }
Shawn Willden2079ae82015-01-22 13:42:31 -0700328};
329
Shawn Willden5b53c992015-02-02 08:05:25 -0700330struct ParamListDelete {
331 void operator()(keymaster_key_param_set_t* p) { keymaster_free_param_set(p); }
332};
333
334typedef UniquePtr<keymaster_key_param_set_t, ParamListDelete> UniqueParamSetPtr;
335
Shawn Willden128ffe02014-08-06 12:31:33 -0600336TEST_F(NewKeyGeneration, Rsa) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700337 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA));
338 params_.push_back(Authorization(TAG_KEY_SIZE, 256));
339 params_.push_back(Authorization(TAG_RSA_PUBLIC_EXPONENT, 3));
340 ASSERT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(), &blob_,
341 &characteristics_));
342 EXPECT_EQ(0U, characteristics_->hw_enforced.length);
343 AuthorizationSet auths(characteristics_->sw_enforced);
344 CheckBaseParams(auths);
Shawn Willden128ffe02014-08-06 12:31:33 -0600345
Shawn Willden5b53c992015-02-02 08:05:25 -0700346 // Check specified tags are all present in auths
347 EXPECT_TRUE(contains(auths, TAG_ALGORITHM, KM_ALGORITHM_RSA));
348 EXPECT_TRUE(contains(auths, TAG_KEY_SIZE, 256));
349 EXPECT_TRUE(contains(auths, TAG_RSA_PUBLIC_EXPONENT, 3));
Shawn Willden128ffe02014-08-06 12:31:33 -0600350}
351
Shawn Willden6bbe6782014-09-18 11:26:15 -0600352TEST_F(NewKeyGeneration, RsaDefaultSize) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700353 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA));
354 ASSERT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(), &blob_,
355 &characteristics_));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600356
Shawn Willden5b53c992015-02-02 08:05:25 -0700357 EXPECT_EQ(0U, characteristics_->hw_enforced.length);
358 AuthorizationSet auths(characteristics_->sw_enforced);
359 CheckBaseParams(auths);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600360
Shawn Willden5b53c992015-02-02 08:05:25 -0700361 // Check specified tags are all present in auths
362 EXPECT_TRUE(contains(auths, TAG_ALGORITHM, KM_ALGORITHM_RSA));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600363
364 // Now check that unspecified, defaulted tags are correct.
Shawn Willden5b53c992015-02-02 08:05:25 -0700365 EXPECT_TRUE(contains(auths, TAG_RSA_PUBLIC_EXPONENT, 65537));
366 EXPECT_TRUE(contains(auths, TAG_KEY_SIZE, 2048));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600367}
368
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600369TEST_F(NewKeyGeneration, Ecdsa) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700370 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
371 params_.push_back(Authorization(TAG_KEY_SIZE, 224));
372 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(), &blob_,
373 &characteristics_));
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600374
Shawn Willden5b53c992015-02-02 08:05:25 -0700375 EXPECT_EQ(0U, characteristics_->hw_enforced.length);
376 AuthorizationSet auths(characteristics_->sw_enforced);
377 CheckBaseParams(auths);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600378
Shawn Willden5b53c992015-02-02 08:05:25 -0700379 // Check specified tags are all present in auths characteristics
380 EXPECT_TRUE(contains(auths, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
381 EXPECT_TRUE(contains(auths, TAG_KEY_SIZE, 224));
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600382}
383
Shawn Willden6bbe6782014-09-18 11:26:15 -0600384TEST_F(NewKeyGeneration, EcdsaDefaultSize) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700385 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
386 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(), &blob_,
387 &characteristics_));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600388
Shawn Willden5b53c992015-02-02 08:05:25 -0700389 EXPECT_EQ(0U, characteristics_->hw_enforced.length);
390 AuthorizationSet auths(characteristics_->sw_enforced);
391 CheckBaseParams(auths);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600392
Shawn Willden5b53c992015-02-02 08:05:25 -0700393 // Check specified tags are all present in auths
394 EXPECT_TRUE(contains(auths, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600395
396 // Now check that unspecified, defaulted tags are correct.
Shawn Willden5b53c992015-02-02 08:05:25 -0700397 EXPECT_TRUE(contains(auths, TAG_KEY_SIZE, 224));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600398}
399
400TEST_F(NewKeyGeneration, EcdsaInvalidSize) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700401 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
402 params_.push_back(Authorization(TAG_KEY_SIZE, 190));
403 EXPECT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE,
404 device()->generate_key(device(), params_.data(), params_.size(), &blob_,
405 &characteristics_));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600406}
407
408TEST_F(NewKeyGeneration, EcdsaAllValidSizes) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600409 size_t valid_sizes[] = {224, 256, 384, 521};
Shawn Willden6bbe6782014-09-18 11:26:15 -0600410 for (size_t size : valid_sizes) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700411 params_.Reinitialize(key_generation_base_params, array_length(key_generation_base_params));
412 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
413 params_.push_back(Authorization(TAG_KEY_SIZE, size));
414 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(),
415 &blob_, &characteristics_))
416 << "Failed to generate size: " << size;
417
418 FreeCharacteristics();
419 FreeKeyBlob();
Shawn Willden6bbe6782014-09-18 11:26:15 -0600420 }
421}
422
Shawn Willden19fca882015-01-22 16:35:30 -0700423TEST_F(NewKeyGeneration, AesOcb) {
424 keymaster_key_param_t params[] = {
425 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
426 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
427 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
428 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_CHUNK_LENGTH, 4096),
Shawn Willden7efb8782014-12-11 14:07:44 -0700429 Authorization(TAG_MAC_LENGTH, 16), Authorization(TAG_PADDING, KM_PAD_NONE),
Shawn Willden19fca882015-01-22 16:35:30 -0700430 };
Shawn Willden5b53c992015-02-02 08:05:25 -0700431 params_.Reinitialize(params, array_length(params));
432 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(), &blob_,
433 &characteristics_));
Shawn Willden19fca882015-01-22 16:35:30 -0700434}
435
436TEST_F(NewKeyGeneration, AesOcbInvalidKeySize) {
437 keymaster_key_param_t params[] = {
438 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
439 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
440 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 129),
441 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_CHUNK_LENGTH, 4096),
Shawn Willden7efb8782014-12-11 14:07:44 -0700442 Authorization(TAG_MAC_LENGTH, 16), Authorization(TAG_PADDING, KM_PAD_NONE),
Shawn Willden19fca882015-01-22 16:35:30 -0700443 };
Shawn Willden5b53c992015-02-02 08:05:25 -0700444 params_.Reinitialize(params, array_length(params));
445 EXPECT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE,
446 device()->generate_key(device(), params_.data(), params_.size(), &blob_,
447 &characteristics_));
Shawn Willden19fca882015-01-22 16:35:30 -0700448}
449
450TEST_F(NewKeyGeneration, AesOcbAllValidSizes) {
451 keymaster_key_param_t params[] = {
452 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
453 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
Shawn Willden7efb8782014-12-11 14:07:44 -0700454 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_BLOCK_MODE, KM_MODE_OCB),
455 Authorization(TAG_MAC_LENGTH, 16), Authorization(TAG_CHUNK_LENGTH, 4096),
Shawn Willden19fca882015-01-22 16:35:30 -0700456 Authorization(TAG_PADDING, KM_PAD_NONE),
457 };
458
459 size_t valid_sizes[] = {128, 192, 256};
460 for (size_t size : valid_sizes) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700461 params_.Reinitialize(params, array_length(params));
462 params_.push_back(Authorization(TAG_KEY_SIZE, size));
463 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(),
464 &blob_, &characteristics_))
465 << "Failed to generate size: " << size;
466
467 FreeCharacteristics();
468 FreeKeyBlob();
Shawn Willden19fca882015-01-22 16:35:30 -0700469 }
470}
471
472TEST_F(NewKeyGeneration, AesOcbNoChunkLength) {
473 keymaster_key_param_t params[] = {
474 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
475 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
476 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
477 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_PADDING, KM_PAD_NONE),
478 };
Shawn Willden5b53c992015-02-02 08:05:25 -0700479 params_.Reinitialize(params, array_length(params));
480 EXPECT_EQ(KM_ERROR_INVALID_ARGUMENT,
481 device()->generate_key(device(), params_.data(), params_.size(), &blob_,
482 &characteristics_));
Shawn Willden19fca882015-01-22 16:35:30 -0700483}
484
485TEST_F(NewKeyGeneration, AesEcbUnsupported) {
486 keymaster_key_param_t params[] = {
487 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
488 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
489 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
490 Authorization(TAG_BLOCK_MODE, KM_MODE_ECB), Authorization(TAG_PADDING, KM_PAD_NONE),
491 };
Shawn Willden5b53c992015-02-02 08:05:25 -0700492 params_.Reinitialize(params, array_length(params));
493 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE,
494 device()->generate_key(device(), params_.data(), params_.size(), &blob_,
495 &characteristics_));
Shawn Willden19fca882015-01-22 16:35:30 -0700496}
497
498TEST_F(NewKeyGeneration, AesOcbPaddingUnsupported) {
499 keymaster_key_param_t params[] = {
500 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
501 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
502 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
503 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_CHUNK_LENGTH, 4096),
504 Authorization(TAG_PADDING, KM_PAD_ZERO),
505 };
Shawn Willden5b53c992015-02-02 08:05:25 -0700506 params_.Reinitialize(params, array_length(params));
507 EXPECT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE,
508 device()->generate_key(device(), params_.data(), params_.size(), &blob_,
509 &characteristics_));
Shawn Willden19fca882015-01-22 16:35:30 -0700510}
511
Shawn Willden7efb8782014-12-11 14:07:44 -0700512TEST_F(NewKeyGeneration, AesOcbInvalidMacLength) {
513 keymaster_key_param_t params[] = {
514 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
515 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
516 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 128),
517 Authorization(TAG_BLOCK_MODE, KM_MODE_OCB), Authorization(TAG_CHUNK_LENGTH, 4096),
518 Authorization(TAG_MAC_LENGTH, 17), Authorization(TAG_PADDING, KM_PAD_NONE),
519 };
Shawn Willden5b53c992015-02-02 08:05:25 -0700520 params_.Reinitialize(params, array_length(params));
521 EXPECT_EQ(KM_ERROR_INVALID_ARGUMENT,
522 device()->generate_key(device(), params_.data(), params_.size(), &blob_,
523 &characteristics_));
Shawn Willden7efb8782014-12-11 14:07:44 -0700524}
525
Shawn Willden76364712014-08-11 17:48:04 -0600526typedef KeymasterTest GetKeyCharacteristics;
527TEST_F(GetKeyCharacteristics, SimpleRsa) {
528 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700529 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
530 Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), Authorization(TAG_KEY_SIZE, 256),
531 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
532 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden76364712014-08-11 17:48:04 -0600533 };
534
Shawn Willden5b53c992015-02-02 08:05:25 -0700535 ASSERT_EQ(KM_ERROR_OK, device()->generate_key(device(), params, array_length(params), &blob_,
536 &characteristics_));
537 AuthorizationSet original(characteristics_->sw_enforced);
538 FreeCharacteristics();
Shawn Willden76364712014-08-11 17:48:04 -0600539
Shawn Willden5b53c992015-02-02 08:05:25 -0700540 keymaster_blob_t client_id = {.data = reinterpret_cast<const uint8_t*>("app_id"),
541 .data_length = 6};
542 ASSERT_EQ(KM_ERROR_OK,
543 device()->get_key_characteristics(device(), &blob_, &client_id, NULL /* app_data */,
544 &characteristics_));
545 EXPECT_EQ(original, AuthorizationSet(characteristics_->sw_enforced));
Shawn Willden76364712014-08-11 17:48:04 -0600546}
547
Shawn Willden61644f32014-08-18 13:43:14 -0600548/**
549 * Test class that provides some infrastructure for generating keys and signing messages.
550 */
Shawn Willden1615f2e2014-08-13 10:37:40 -0600551class SigningOperationsTest : public KeymasterTest {
552 protected:
Shawn Willden5b53c992015-02-02 08:05:25 -0700553 SigningOperationsTest() : out_params_(NULL), output_(NULL), signature_(NULL) {}
554 ~SigningOperationsTest() {
555 // Clean up so (most) tests won't have to.
556 FreeOutput();
557 FreeSignature();
558 }
559
Shawn Willden61644f32014-08-18 13:43:14 -0600560 void GenerateKey(keymaster_algorithm_t algorithm, keymaster_digest_t digest,
561 keymaster_padding_t padding, uint32_t key_size) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700562 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));
563 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY));
564 params_.push_back(Authorization(TAG_ALGORITHM, algorithm));
565 params_.push_back(Authorization(TAG_KEY_SIZE, key_size));
566 params_.push_back(Authorization(TAG_USER_ID, 7));
567 params_.push_back(Authorization(TAG_USER_AUTH_ID, 8));
568 params_.push_back(Authorization(TAG_APPLICATION_ID, "app_id", 6));
569 params_.push_back(Authorization(TAG_AUTH_TIMEOUT, 300));
Shawn Willden43e999e2014-08-13 13:29:50 -0600570 if (static_cast<int>(digest) != -1)
Shawn Willden5b53c992015-02-02 08:05:25 -0700571 params_.push_back(TAG_DIGEST, digest);
Shawn Willden43e999e2014-08-13 13:29:50 -0600572 if (static_cast<int>(padding) != -1)
Shawn Willden5b53c992015-02-02 08:05:25 -0700573 params_.push_back(TAG_PADDING, padding);
574
575 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(),
576 &blob_, &characteristics_));
Shawn Willden61644f32014-08-18 13:43:14 -0600577 }
Shawn Willden1615f2e2014-08-13 10:37:40 -0600578
Shawn Willden61644f32014-08-18 13:43:14 -0600579 void SignMessage(const void* message, size_t size) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700580 EXPECT_EQ(KM_ERROR_OK, device()->begin(device(), KM_PURPOSE_SIGN, &blob_, client_params_,
581 array_length(client_params_), &out_params_,
582 &out_params_count_, &op_handle_));
583
584 EXPECT_EQ(KM_ERROR_OK,
585 device()->update(device(), op_handle_, reinterpret_cast<const uint8_t*>(message),
586 size, &input_consumed_, &output_, &output_length_));
587 EXPECT_EQ(0, output_length_);
588 FreeOutput();
589 EXPECT_EQ(size, input_consumed_);
590
591 EXPECT_EQ(KM_ERROR_OK,
592 device()->finish(device(), op_handle_, NULL /* signature to verify */,
593 0 /* signature to verify length */, &signature_,
594 &signature_length_));
595 EXPECT_GT(signature_length_, 0);
Shawn Willden437fbd12014-08-20 11:59:49 -0600596 }
597
Shawn Willden5b53c992015-02-02 08:05:25 -0700598 void FreeOutput() {
599 free(out_params_);
600 out_params_ = NULL;
601 free(output_);
602 output_ = NULL;
Shawn Willden61644f32014-08-18 13:43:14 -0600603 }
604
Shawn Willden5b53c992015-02-02 08:05:25 -0700605 void FreeSignature() {
606 free(signature_);
607 signature_ = NULL;
Shawn Willdenf268d742014-08-19 15:36:26 -0600608 }
609
Shawn Willden5b53c992015-02-02 08:05:25 -0700610 void corrupt_key_blob() {
611 uint8_t* tmp = const_cast<uint8_t*>(blob_.key_material);
612 ++tmp[blob_.key_material_size / 2];
Shawn Willden1615f2e2014-08-13 10:37:40 -0600613 }
614
Shawn Willden5b53c992015-02-02 08:05:25 -0700615 keymaster_blob_t client_id_ = {.data = reinterpret_cast<const uint8_t*>("app_id"),
616 .data_length = 6};
617 keymaster_key_param_t client_params_[1] = {
618 Authorization(TAG_APPLICATION_ID, client_id_.data, client_id_.data_length)};
619 keymaster_key_param_t* out_params_;
620 size_t out_params_count_;
621 uint64_t op_handle_;
622 size_t input_consumed_;
623 uint8_t* output_;
624 size_t output_length_;
625 uint8_t* signature_;
626 size_t signature_length_;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600627};
628
629TEST_F(SigningOperationsTest, RsaSuccess) {
Shawn Willden61644f32014-08-18 13:43:14 -0600630 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willdenffd790c2014-08-18 21:20:06 -0600631 const char message[] = "12345678901234567890123456789012";
Shawn Willdend05cba52014-09-26 09:58:12 -0600632 SignMessage(message, array_size(message) - 1);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600633}
634
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600635TEST_F(SigningOperationsTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600636 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willdend05cba52014-09-26 09:58:12 -0600637 const char message[] = "123456789012345678901234567890123456789012345678";
638 SignMessage(message, array_size(message) - 1);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600639}
640
Shawn Willden1615f2e2014-08-13 10:37:40 -0600641TEST_F(SigningOperationsTest, RsaAbort) {
Shawn Willden61644f32014-08-18 13:43:14 -0600642 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willden5b53c992015-02-02 08:05:25 -0700643 ASSERT_EQ(KM_ERROR_OK, device()->begin(device(), KM_PURPOSE_SIGN, &blob_, client_params_,
644 array_length(client_params_), &out_params_,
645 &out_params_count_, &op_handle_));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600646
Shawn Willden5b53c992015-02-02 08:05:25 -0700647 EXPECT_EQ(KM_ERROR_OK, device()->abort(device(), op_handle_));
648 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle_));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600649}
650
651TEST_F(SigningOperationsTest, RsaUnsupportedDigest) {
Shawn Willden61644f32014-08-18 13:43:14 -0600652 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_SHA_2_256, KM_PAD_NONE, 256 /* key size */);
Shawn Willden5b53c992015-02-02 08:05:25 -0700653 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST,
654 device()->begin(device(), KM_PURPOSE_SIGN, &blob_, client_params_,
655 array_length(client_params_), &out_params_, &out_params_count_,
656 &op_handle_));
657 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle_));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600658}
659
660TEST_F(SigningOperationsTest, RsaUnsupportedPadding) {
Shawn Willden61644f32014-08-18 13:43:14 -0600661 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_RSA_OAEP, 256 /* key size */);
Shawn Willden5b53c992015-02-02 08:05:25 -0700662 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE,
663 device()->begin(device(), KM_PURPOSE_SIGN, &blob_, client_params_,
664 array_length(client_params_), &out_params_, &out_params_count_,
665 &op_handle_));
666 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle_));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600667}
668
669TEST_F(SigningOperationsTest, RsaNoDigest) {
Shawn Willden61644f32014-08-18 13:43:14 -0600670 GenerateKey(KM_ALGORITHM_RSA, static_cast<keymaster_digest_t>(-1), KM_PAD_NONE,
671 256 /* key size */);
Shawn Willden5b53c992015-02-02 08:05:25 -0700672 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST,
673 device()->begin(device(), KM_PURPOSE_SIGN, &blob_, client_params_,
674 array_length(client_params_), &out_params_, &out_params_count_,
675 &op_handle_));
676 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle_));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600677}
678
679TEST_F(SigningOperationsTest, RsaNoPadding) {
Shawn Willden61644f32014-08-18 13:43:14 -0600680 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, static_cast<keymaster_padding_t>(-1),
681 256 /* key size */);
Shawn Willden5b53c992015-02-02 08:05:25 -0700682 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE,
683 device()->begin(device(), KM_PURPOSE_SIGN, &blob_, client_params_,
684 array_length(client_params_), &out_params_, &out_params_count_,
685 &op_handle_));
686 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle_));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600687}
688
689TEST_F(SigningOperationsTest, RsaTooShortMessage) {
Shawn Willden61644f32014-08-18 13:43:14 -0600690 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willden5b53c992015-02-02 08:05:25 -0700691 ASSERT_EQ(KM_ERROR_OK, device()->begin(device(), KM_PURPOSE_SIGN, &blob_, client_params_,
692 array_length(client_params_), &out_params_,
693 &out_params_count_, &op_handle_));
694 ASSERT_EQ(KM_ERROR_OK,
695 device()->update(device(), op_handle_,
696 reinterpret_cast<const uint8_t*>("01234567890123456789012345678901"),
697 31, &input_consumed_, &output_, &output_length_));
698 EXPECT_EQ(0U, output_length_);
699 EXPECT_EQ(31U, input_consumed_);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600700
Shawn Willden5b53c992015-02-02 08:05:25 -0700701 ASSERT_EQ(KM_ERROR_UNKNOWN_ERROR,
702 device()->finish(device(), op_handle_, NULL, 0, &signature_, &signature_length_));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600703
Shawn Willden5b53c992015-02-02 08:05:25 -0700704 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle_));
Shawn Willden43e999e2014-08-13 13:29:50 -0600705}
706
Shawn Willdend05cba52014-09-26 09:58:12 -0600707class VerificationOperationsTest : public SigningOperationsTest {
708 protected:
709 void VerifyMessage(const void* message, size_t message_len) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700710 EXPECT_TRUE(signature_ != NULL);
Shawn Willdend05cba52014-09-26 09:58:12 -0600711
Shawn Willden5b53c992015-02-02 08:05:25 -0700712 EXPECT_EQ(KM_ERROR_OK, device()->begin(device(), KM_PURPOSE_VERIFY, &blob_, client_params_,
713 array_length(client_params_), &out_params_,
714 &out_params_count_, &op_handle_));
715 ASSERT_EQ(KM_ERROR_OK,
716 device()->update(device(), op_handle_, reinterpret_cast<const uint8_t*>(message),
717 message_len, &input_consumed_, &output_, &output_length_));
718 EXPECT_EQ(0U, output_length_);
719 FreeOutput();
720 EXPECT_EQ(message_len, input_consumed_);
Shawn Willdend05cba52014-09-26 09:58:12 -0600721
Shawn Willden5b53c992015-02-02 08:05:25 -0700722 ASSERT_EQ(KM_ERROR_OK, device()->finish(device(), op_handle_, signature_, signature_length_,
723 &output_, &output_length_));
724 EXPECT_EQ(0U, output_length_);
Shawn Willdend05cba52014-09-26 09:58:12 -0600725
Shawn Willden5b53c992015-02-02 08:05:25 -0700726 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle_));
Shawn Willdend05cba52014-09-26 09:58:12 -0600727 }
728};
729
Shawn Willden43e999e2014-08-13 13:29:50 -0600730TEST_F(VerificationOperationsTest, RsaSuccess) {
Shawn Willden61644f32014-08-18 13:43:14 -0600731 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
732 const char message[] = "12345678901234567890123456789012";
733 SignMessage(message, array_size(message) - 1);
Shawn Willdend05cba52014-09-26 09:58:12 -0600734 VerifyMessage(message, array_size(message) - 1);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600735}
736
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600737TEST_F(VerificationOperationsTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600738 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600739 const char message[] = "123456789012345678901234567890123456789012345678";
740 SignMessage(message, array_size(message) - 1);
Shawn Willdend05cba52014-09-26 09:58:12 -0600741 VerifyMessage(message, array_size(message) - 1);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600742}
743
Shawn Willden5b53c992015-02-02 08:05:25 -0700744typedef VerificationOperationsTest ExportKeyTest;
Shawn Willdenffd790c2014-08-18 21:20:06 -0600745TEST_F(ExportKeyTest, RsaSuccess) {
746 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willdenffd790c2014-08-18 21:20:06 -0600747
Shawn Willden5b53c992015-02-02 08:05:25 -0700748 uint8_t* export_data;
749 size_t export_data_length;
750 ASSERT_EQ(KM_ERROR_OK,
751 device()->export_key(device(), KM_KEY_FORMAT_X509, &blob_, &client_id_,
752 NULL /* app_data */, &export_data, &export_data_length));
753 EXPECT_TRUE(export_data != NULL);
754 EXPECT_GT(export_data_length, 0);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600755
756 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willden5b53c992015-02-02 08:05:25 -0700757 free(export_data);
Shawn Willdenffd790c2014-08-18 21:20:06 -0600758}
759
Shawn Willdenf268d742014-08-19 15:36:26 -0600760TEST_F(ExportKeyTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600761 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willdenf268d742014-08-19 15:36:26 -0600762
Shawn Willden5b53c992015-02-02 08:05:25 -0700763 uint8_t* export_data;
764 size_t export_data_length;
765 ASSERT_EQ(KM_ERROR_OK,
766 device()->export_key(device(), KM_KEY_FORMAT_X509, &blob_, &client_id_,
767 NULL /* app_data */, &export_data, &export_data_length));
768 EXPECT_TRUE(export_data != NULL);
769 EXPECT_GT(export_data_length, 0);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600770
771 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willden5b53c992015-02-02 08:05:25 -0700772 free(export_data);
Shawn Willdenf268d742014-08-19 15:36:26 -0600773}
774
775TEST_F(ExportKeyTest, RsaUnsupportedKeyFormat) {
776 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256);
777
Shawn Willden5b53c992015-02-02 08:05:25 -0700778 uint8_t dummy[] = {1};
779 uint8_t* export_data = dummy; // So it's not NULL;
780 size_t export_data_length;
781 ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_FORMAT,
782 device()->export_key(device(), KM_KEY_FORMAT_PKCS8, &blob_, &client_id_,
783 NULL /* app_data */, &export_data, &export_data_length));
784 ASSERT_TRUE(export_data == NULL);
Shawn Willdenf268d742014-08-19 15:36:26 -0600785}
786
787TEST_F(ExportKeyTest, RsaCorruptedKeyBlob) {
788 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256);
Shawn Willden5b53c992015-02-02 08:05:25 -0700789 corrupt_key_blob();
Shawn Willdenf268d742014-08-19 15:36:26 -0600790
Shawn Willden5b53c992015-02-02 08:05:25 -0700791 uint8_t dummy[] = {1};
792 uint8_t* export_data = dummy; // So it's not NULL
793 size_t export_data_length;
794 ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB,
795 device()->export_key(device(), KM_KEY_FORMAT_X509, &blob_, &client_id_,
796 NULL /* app_data */, &export_data, &export_data_length));
797 ASSERT_TRUE(export_data == NULL);
Shawn Willdenf268d742014-08-19 15:36:26 -0600798}
799
Shawn Willden437fbd12014-08-20 11:59:49 -0600800static string read_file(const string& file_name) {
801 ifstream file_stream(file_name, std::ios::binary);
802 istreambuf_iterator<char> file_begin(file_stream);
803 istreambuf_iterator<char> file_end;
804 return string(file_begin, file_end);
805}
806
Shawn Willden5b53c992015-02-02 08:05:25 -0700807class ImportKeyTest : public VerificationOperationsTest {
808 protected:
809 ImportKeyTest() {
810 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));
811 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY));
812 params_.push_back(Authorization(TAG_DIGEST, KM_DIGEST_NONE));
813 params_.push_back(Authorization(TAG_PADDING, KM_PAD_NONE));
814 params_.push_back(Authorization(TAG_USER_ID, 7));
815 params_.push_back(Authorization(TAG_USER_AUTH_ID, 8));
816 params_.push_back(Authorization(TAG_APPLICATION_ID, "app_id", 6));
817 params_.push_back(Authorization(TAG_AUTH_TIMEOUT, 300));
818 }
819};
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800820
Shawn Willden5b53c992015-02-02 08:05:25 -0700821TEST_F(ImportKeyTest, RsaSuccess) {
Shawn Willden81effc62014-08-27 10:08:46 -0600822 string pk8_key = read_file("rsa_privkey_pk8.der");
Shawn Willden437fbd12014-08-20 11:59:49 -0600823 ASSERT_EQ(633U, pk8_key.size());
824
Shawn Willden5b53c992015-02-02 08:05:25 -0700825 ASSERT_EQ(KM_ERROR_OK,
826 device()->import_key(device(), params_.data(), params_.size(), KM_KEY_FORMAT_PKCS8,
827 reinterpret_cast<const uint8_t*>(pk8_key.data()), pk8_key.size(),
828 &blob_, &characteristics_));
829 EXPECT_EQ(0U, characteristics_->hw_enforced.length);
830 AuthorizationSet auths(characteristics_->sw_enforced);
Shawn Willden437fbd12014-08-20 11:59:49 -0600831
832 // Check values derived from the key.
Shawn Willden5b53c992015-02-02 08:05:25 -0700833 EXPECT_TRUE(contains(auths, TAG_ALGORITHM, KM_ALGORITHM_RSA));
834 EXPECT_TRUE(contains(auths, TAG_KEY_SIZE, 1024));
835 EXPECT_TRUE(contains(auths, TAG_RSA_PUBLIC_EXPONENT, 65537U));
Shawn Willden437fbd12014-08-20 11:59:49 -0600836
837 // And values provided by GoogleKeymaster
Shawn Willden5b53c992015-02-02 08:05:25 -0700838 EXPECT_TRUE(contains(auths, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
839 EXPECT_TRUE(contains(auths, KM_TAG_CREATION_DATETIME));
Shawn Willden437fbd12014-08-20 11:59:49 -0600840
841 size_t message_len = 1024 / 8;
842 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
843 std::fill(message.get(), message.get() + message_len, 'a');
Shawn Willden5b53c992015-02-02 08:05:25 -0700844 SignMessage(message.get(), message_len);
845 VerifyMessage(message.get(), message_len);
Shawn Willden437fbd12014-08-20 11:59:49 -0600846}
847
Shawn Willden6bbe6782014-09-18 11:26:15 -0600848TEST_F(ImportKeyTest, RsaKeySizeMismatch) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700849 params_.push_back(Authorization(TAG_KEY_SIZE, 2048)); // Doesn't match key
Shawn Willden6bbe6782014-09-18 11:26:15 -0600850
851 string pk8_key = read_file("rsa_privkey_pk8.der");
852 ASSERT_EQ(633U, pk8_key.size());
853
Shawn Willden5b53c992015-02-02 08:05:25 -0700854 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
855 device()->import_key(device(), params_.data(), params_.size(), KM_KEY_FORMAT_PKCS8,
856 reinterpret_cast<const uint8_t*>(pk8_key.data()), pk8_key.size(),
857 &blob_, &characteristics_));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600858}
859
860TEST_F(ImportKeyTest, RsaPublicExponenMismatch) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700861 params_.push_back(Authorization(TAG_RSA_PUBLIC_EXPONENT, 3)); // Doesn't match key
Shawn Willden6bbe6782014-09-18 11:26:15 -0600862
863 string pk8_key = read_file("rsa_privkey_pk8.der");
864 ASSERT_EQ(633U, pk8_key.size());
865
Shawn Willden5b53c992015-02-02 08:05:25 -0700866 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
867 device()->import_key(device(), params_.data(), params_.size(), KM_KEY_FORMAT_PKCS8,
868 reinterpret_cast<const uint8_t*>(pk8_key.data()), pk8_key.size(),
869 &blob_, &characteristics_));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600870}
871
Shawn Willden81effc62014-08-27 10:08:46 -0600872TEST_F(ImportKeyTest, EcdsaSuccess) {
Shawn Willden81effc62014-08-27 10:08:46 -0600873 string pk8_key = read_file("ec_privkey_pk8.der");
874 ASSERT_EQ(138U, pk8_key.size());
875
Shawn Willden5b53c992015-02-02 08:05:25 -0700876 ASSERT_EQ(KM_ERROR_OK,
877 device()->import_key(device(), params_.data(), params_.size(), KM_KEY_FORMAT_PKCS8,
878 reinterpret_cast<const uint8_t*>(pk8_key.data()), pk8_key.size(),
879 &blob_, &characteristics_));
880 EXPECT_EQ(0U, characteristics_->hw_enforced.length);
881 AuthorizationSet auths(characteristics_->sw_enforced);
Shawn Willden81effc62014-08-27 10:08:46 -0600882
883 // Check values derived from the key.
Shawn Willden5b53c992015-02-02 08:05:25 -0700884 EXPECT_TRUE(contains(auths, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
885 EXPECT_TRUE(contains(auths, TAG_KEY_SIZE, 256));
Shawn Willden81effc62014-08-27 10:08:46 -0600886
887 // And values provided by GoogleKeymaster
Shawn Willden5b53c992015-02-02 08:05:25 -0700888 EXPECT_TRUE(contains(auths, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
889 EXPECT_TRUE(contains(auths, KM_TAG_CREATION_DATETIME));
Shawn Willden81effc62014-08-27 10:08:46 -0600890
Shawn Willden5b53c992015-02-02 08:05:25 -0700891 size_t message_len = 1024;
Shawn Willden81effc62014-08-27 10:08:46 -0600892 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
893 std::fill(message.get(), message.get() + message_len, 'a');
Shawn Willden5b53c992015-02-02 08:05:25 -0700894 SignMessage(message.get(), message_len);
895 VerifyMessage(message.get(), message_len);
Shawn Willden81effc62014-08-27 10:08:46 -0600896}
897
Shawn Willden5b53c992015-02-02 08:05:25 -0700898TEST_F(ImportKeyTest, EcdsaKeySizeMismatch) {
899 params_.push_back(Authorization(TAG_KEY_SIZE, 224)); // Doesn't match key
Shawn Willden6bbe6782014-09-18 11:26:15 -0600900
Shawn Willden5b53c992015-02-02 08:05:25 -0700901 string pk8_key = read_file("rsa_privkey_pk8.der");
902 ASSERT_EQ(633U, pk8_key.size());
Shawn Willden6bbe6782014-09-18 11:26:15 -0600903
Shawn Willden5b53c992015-02-02 08:05:25 -0700904 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
905 device()->import_key(device(), params_.data(), params_.size(), KM_KEY_FORMAT_PKCS8,
906 reinterpret_cast<const uint8_t*>(pk8_key.data()), pk8_key.size(),
907 &blob_, &characteristics_));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600908}
909
Shawn Willden2665e862014-11-24 14:46:21 -0700910typedef KeymasterTest VersionTest;
911TEST_F(VersionTest, GetVersion) {
912 GetVersionRequest req;
913 GetVersionResponse rsp;
Shawn Willden5b53c992015-02-02 08:05:25 -0700914 device_.GetVersion(req, &rsp);
Shawn Willden2665e862014-11-24 14:46:21 -0700915 EXPECT_EQ(KM_ERROR_OK, rsp.error);
916 EXPECT_EQ(1, rsp.major_ver);
917 EXPECT_EQ(0, rsp.minor_ver);
918 EXPECT_EQ(0, rsp.subminor_ver);
919}
920
Shawn Willden4200f212014-12-02 07:01:21 -0700921/**
922 * Test class that provides some infrastructure for generating keys and encrypting messages.
923 */
924class EncryptionOperationsTest : public KeymasterTest {
925 protected:
926 void GenerateKey(keymaster_algorithm_t algorithm, keymaster_padding_t padding,
927 uint32_t key_size) {
Shawn Willden6dde87c2014-12-11 14:08:48 -0700928 params_.Clear();
Shawn Willden5b53c992015-02-02 08:05:25 -0700929 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
930 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT));
931 params_.push_back(Authorization(TAG_ALGORITHM, algorithm));
932 params_.push_back(Authorization(TAG_KEY_SIZE, key_size));
933 params_.push_back(Authorization(TAG_USER_ID, 7));
934 params_.push_back(Authorization(TAG_USER_AUTH_ID, 8));
935 params_.push_back(Authorization(TAG_APPLICATION_ID, "app_id", 6));
936 params_.push_back(Authorization(TAG_AUTH_TIMEOUT, 300));
Shawn Willden4200f212014-12-02 07:01:21 -0700937 if (static_cast<int>(padding) != -1)
Shawn Willden5b53c992015-02-02 08:05:25 -0700938 params_.push_back(TAG_PADDING, padding);
Shawn Willden6dde87c2014-12-11 14:08:48 -0700939
940 FreeKeyBlob();
941 FreeCharacteristics();
Shawn Willden5b53c992015-02-02 08:05:25 -0700942 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(),
943 &blob_, &characteristics_));
Shawn Willden4200f212014-12-02 07:01:21 -0700944 }
945
Shawn Willden907c3012014-12-08 15:51:55 -0700946 void GenerateSymmetricKey(keymaster_algorithm_t algorithm, uint32_t key_size,
947 keymaster_block_mode_t block_mode, uint32_t chunk_length) {
Shawn Willden6dde87c2014-12-11 14:08:48 -0700948 params_.Clear();
Shawn Willden5b53c992015-02-02 08:05:25 -0700949 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
950 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT));
951 params_.push_back(Authorization(TAG_ALGORITHM, algorithm));
952 params_.push_back(Authorization(TAG_BLOCK_MODE, block_mode));
953 params_.push_back(Authorization(TAG_CHUNK_LENGTH, chunk_length));
954 params_.push_back(Authorization(TAG_KEY_SIZE, key_size));
955 params_.push_back(Authorization(TAG_MAC_LENGTH, 16));
956 params_.push_back(Authorization(TAG_USER_ID, 7));
957 params_.push_back(Authorization(TAG_USER_AUTH_ID, 8));
958 params_.push_back(Authorization(TAG_APPLICATION_ID, "app_id", 6));
959 params_.push_back(Authorization(TAG_AUTH_TIMEOUT, 300));
960
Shawn Willden6dde87c2014-12-11 14:08:48 -0700961 FreeKeyBlob();
962 FreeCharacteristics();
Shawn Willden5b53c992015-02-02 08:05:25 -0700963 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(),
964 &blob_, &characteristics_));
Shawn Willden907c3012014-12-08 15:51:55 -0700965 }
966
Shawn Willden4200f212014-12-02 07:01:21 -0700967 keymaster_error_t BeginOperation(keymaster_purpose_t purpose,
968 const keymaster_key_blob_t& key_blob, uint64_t* op_handle) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700969 return device()->begin(device(), purpose, &key_blob, client_params_,
970 array_length(client_params_), &out_params_, &out_params_count_,
971 op_handle);
Shawn Willden4200f212014-12-02 07:01:21 -0700972 }
973
974 keymaster_error_t UpdateOperation(uint64_t op_handle, const void* message, size_t size,
Shawn Willdenb7361132014-12-08 08:15:14 -0700975 string* output, size_t* input_consumed) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700976 uint8_t* out_tmp = NULL;
977 size_t out_length;
978 keymaster_error_t error =
979 device()->update(device(), op_handle, reinterpret_cast<const uint8_t*>(message), size,
980 input_consumed, &out_tmp, &out_length);
981 if (out_tmp)
Shawn Willden6dde87c2014-12-11 14:08:48 -0700982 output->append(reinterpret_cast<char*>(out_tmp), out_length);
Shawn Willden5b53c992015-02-02 08:05:25 -0700983 free(out_tmp);
984 return error;
Shawn Willden4200f212014-12-02 07:01:21 -0700985 }
986
987 keymaster_error_t FinishOperation(uint64_t op_handle, string* output) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700988 uint8_t* out_tmp = NULL;
989 size_t out_length;
990 keymaster_error_t error = device()->finish(device(), op_handle, NULL /* signature */,
991 0 /* signature_length */, &out_tmp, &out_length);
992 if (out_tmp)
Shawn Willden6dde87c2014-12-11 14:08:48 -0700993 output->append(reinterpret_cast<char*>(out_tmp), out_length);
Shawn Willden5b53c992015-02-02 08:05:25 -0700994 free(out_tmp);
995 return error;
Shawn Willden4200f212014-12-02 07:01:21 -0700996 }
997
998 string ProcessMessage(keymaster_purpose_t purpose, const keymaster_key_blob_t& key_blob,
999 const void* message, size_t size) {
1000 uint64_t op_handle;
1001 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose, key_blob, &op_handle));
1002
1003 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001004 size_t input_consumed;
1005 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, message, size, &result, &input_consumed));
1006 EXPECT_EQ(size, input_consumed);
Shawn Willden4200f212014-12-02 07:01:21 -07001007 EXPECT_EQ(KM_ERROR_OK, FinishOperation(op_handle, &result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001008 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle));
Shawn Willden4200f212014-12-02 07:01:21 -07001009 return result;
1010 }
1011
Shawn Willden6dde87c2014-12-11 14:08:48 -07001012 string EncryptMessage(const string& message) {
1013 return ProcessMessage(KM_PURPOSE_ENCRYPT, blob_, message.c_str(), message.length());
Shawn Willden4200f212014-12-02 07:01:21 -07001014 }
1015
Shawn Willden6dde87c2014-12-11 14:08:48 -07001016 string DecryptMessage(const string& ciphertext) {
1017 return ProcessMessage(KM_PURPOSE_DECRYPT, blob_, ciphertext.c_str(), ciphertext.length());
Shawn Willden4200f212014-12-02 07:01:21 -07001018 }
1019
1020 void AddClientParams(AuthorizationSet* set) { set->push_back(TAG_APPLICATION_ID, "app_id", 6); }
1021
Shawn Willden5b53c992015-02-02 08:05:25 -07001022 const void corrupt_key_blob() {
1023 uint8_t* tmp = const_cast<uint8_t*>(blob_.key_material);
1024 ++tmp[blob_.key_material_size / 2];
Shawn Willden4200f212014-12-02 07:01:21 -07001025 }
1026
Shawn Willden5b53c992015-02-02 08:05:25 -07001027 keymaster_blob_t client_id_ = {.data = reinterpret_cast<const uint8_t*>("app_id"),
1028 .data_length = 6};
1029 keymaster_key_param_t client_params_[1] = {
1030 Authorization(TAG_APPLICATION_ID, client_id_.data, client_id_.data_length)};
1031
1032 keymaster_key_param_t* out_params_;
1033 size_t out_params_count_;
Shawn Willden4200f212014-12-02 07:01:21 -07001034};
1035
1036TEST_F(EncryptionOperationsTest, RsaOaepSuccess) {
1037 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1038 const char message[] = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001039 string ciphertext1 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001040 EXPECT_EQ(512 / 8, ciphertext1.size());
1041
Shawn Willden6dde87c2014-12-11 14:08:48 -07001042 string ciphertext2 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001043 EXPECT_EQ(512 / 8, ciphertext2.size());
1044
1045 // OAEP randomizes padding so every result should be different.
1046 EXPECT_NE(ciphertext1, ciphertext2);
1047}
1048
1049TEST_F(EncryptionOperationsTest, RsaOaepRoundTrip) {
1050 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1051 const char message[] = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001052 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001053 EXPECT_EQ(512 / 8, ciphertext.size());
1054
Shawn Willden6dde87c2014-12-11 14:08:48 -07001055 string plaintext = DecryptMessage(ciphertext);
Shawn Willden4200f212014-12-02 07:01:21 -07001056 EXPECT_EQ(message, plaintext);
1057}
1058
1059TEST_F(EncryptionOperationsTest, RsaOaepTooLarge) {
1060 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1061 const char message[] = "12345678901234567890123";
1062 uint64_t op_handle;
1063 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001064 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001065
Shawn Willden5b53c992015-02-02 08:05:25 -07001066 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT, blob_, &op_handle));
Shawn Willdenb7361132014-12-08 08:15:14 -07001067 EXPECT_EQ(KM_ERROR_OK,
1068 UpdateOperation(op_handle, message, array_size(message), &result, &input_consumed));
Shawn Willden4200f212014-12-02 07:01:21 -07001069 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(op_handle, &result));
1070 EXPECT_EQ(0, result.size());
1071}
1072
1073TEST_F(EncryptionOperationsTest, RsaOaepCorruptedDecrypt) {
1074 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1075 const char message[] = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001076 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001077 EXPECT_EQ(512 / 8, ciphertext.size());
1078
1079 // Corrupt the ciphertext
1080 ciphertext[512 / 8 / 2]++;
1081
1082 uint64_t op_handle;
1083 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001084 size_t input_consumed;
Shawn Willden5b53c992015-02-02 08:05:25 -07001085 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, blob_, &op_handle));
Shawn Willdenb7361132014-12-08 08:15:14 -07001086 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, ciphertext.data(), ciphertext.size(), &result,
1087 &input_consumed));
Shawn Willden4200f212014-12-02 07:01:21 -07001088 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(op_handle, &result));
1089 EXPECT_EQ(0, result.size());
1090}
1091
1092TEST_F(EncryptionOperationsTest, RsaPkcs1Success) {
1093 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1094 const char message[] = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001095 string ciphertext1 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001096 EXPECT_EQ(512 / 8, ciphertext1.size());
1097
Shawn Willden6dde87c2014-12-11 14:08:48 -07001098 string ciphertext2 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001099 EXPECT_EQ(512 / 8, ciphertext2.size());
1100
1101 // PKCS1 v1.5 randomizes padding so every result should be different.
1102 EXPECT_NE(ciphertext1, ciphertext2);
1103}
1104
1105TEST_F(EncryptionOperationsTest, RsaPkcs1RoundTrip) {
1106 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1107 const char message[] = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001108 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001109 EXPECT_EQ(512 / 8, ciphertext.size());
1110
Shawn Willden6dde87c2014-12-11 14:08:48 -07001111 string plaintext = DecryptMessage(ciphertext);
Shawn Willden4200f212014-12-02 07:01:21 -07001112 EXPECT_EQ(message, plaintext);
1113}
1114
1115TEST_F(EncryptionOperationsTest, RsaPkcs1TooLarge) {
1116 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1117 const char message[] = "1234567890123456789012345678901234567890123456789012";
1118 uint64_t op_handle;
1119 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001120 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001121
Shawn Willden5b53c992015-02-02 08:05:25 -07001122 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT, blob_, &op_handle));
Shawn Willdenb7361132014-12-08 08:15:14 -07001123 EXPECT_EQ(KM_ERROR_OK,
1124 UpdateOperation(op_handle, message, array_size(message), &result, &input_consumed));
Shawn Willden4200f212014-12-02 07:01:21 -07001125 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(op_handle, &result));
1126 EXPECT_EQ(0, result.size());
1127}
1128
1129TEST_F(EncryptionOperationsTest, RsaPkcs1CorruptedDecrypt) {
1130 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1131 const char message[] = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001132 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001133 EXPECT_EQ(512 / 8, ciphertext.size());
1134
1135 // Corrupt the ciphertext
1136 ciphertext[512 / 8 / 2]++;
1137
1138 uint64_t op_handle;
1139 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001140 size_t input_consumed;
Shawn Willden5b53c992015-02-02 08:05:25 -07001141 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, blob_, &op_handle));
Shawn Willdenb7361132014-12-08 08:15:14 -07001142 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, ciphertext.data(), ciphertext.size(), &result,
1143 &input_consumed));
Shawn Willden4200f212014-12-02 07:01:21 -07001144 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(op_handle, &result));
1145 EXPECT_EQ(0, result.size());
1146}
1147
Shawn Willden907c3012014-12-08 15:51:55 -07001148TEST_F(EncryptionOperationsTest, AesOcbSuccess) {
1149 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1150 const char message[] = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001151 string ciphertext1 = EncryptMessage(string(message));
Shawn Willden907c3012014-12-08 15:51:55 -07001152 EXPECT_EQ(12 /* nonce */ + strlen(message) + 16 /* tag */, ciphertext1.size());
1153
Shawn Willden6dde87c2014-12-11 14:08:48 -07001154 string ciphertext2 = EncryptMessage(string(message));
Shawn Willden907c3012014-12-08 15:51:55 -07001155 EXPECT_EQ(12 /* nonce */ + strlen(message) + 16 /* tag */, ciphertext2.size());
1156
1157 // OCB uses a random nonce, so every output should be different
1158 EXPECT_NE(ciphertext1, ciphertext2);
1159}
1160
Shawn Willden6dde87c2014-12-11 14:08:48 -07001161TEST_F(EncryptionOperationsTest, AesOcbRoundTripSuccess) {
1162 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1163 string message = "Hello World!";
1164 string ciphertext = EncryptMessage(message);
1165 EXPECT_EQ(12 /* nonce */ + message.length() + 16 /* tag */, ciphertext.size());
1166
1167 string plaintext = DecryptMessage(ciphertext);
1168 EXPECT_EQ(message, plaintext);
1169}
1170
1171TEST_F(EncryptionOperationsTest, AesOcbRoundTripCorrupted) {
1172 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1173 const char message[] = "Hello World!";
1174 string ciphertext = EncryptMessage(string(message));
1175 EXPECT_EQ(12 /* nonce */ + strlen(message) + 16 /* tag */, ciphertext.size());
1176
1177 ciphertext[ciphertext.size() / 2]++;
1178
1179 uint64_t op_handle;
1180 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, key_blob(), &op_handle));
1181
1182 string result;
1183 size_t input_consumed;
1184 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, ciphertext.c_str(), ciphertext.length(),
1185 &result, &input_consumed));
1186 EXPECT_EQ(ciphertext.length(), input_consumed);
1187 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(op_handle, &result));
1188}
1189
1190TEST_F(EncryptionOperationsTest, AesDecryptGarbage) {
1191 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1192 string ciphertext(128, 'a');
1193 uint64_t op_handle;
1194 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, key_blob(), &op_handle));
1195
1196 string result;
1197 size_t input_consumed;
1198 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, ciphertext.c_str(), ciphertext.length(),
1199 &result, &input_consumed));
1200 EXPECT_EQ(ciphertext.length(), input_consumed);
1201 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(op_handle, &result));
1202}
1203
1204TEST_F(EncryptionOperationsTest, AesDecryptTooShort) {
1205 // Try decrypting garbage ciphertext that is too short to be valid (< nonce + tag).
1206 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1207 string ciphertext(12 + 15, 'a');
1208 uint64_t op_handle;
1209 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, key_blob(), &op_handle));
1210
1211 string result;
1212 size_t input_consumed;
1213 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, ciphertext.c_str(), ciphertext.length(),
1214 &result, &input_consumed));
1215 EXPECT_EQ(ciphertext.length(), input_consumed);
1216 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(op_handle, &result));
1217}
1218
1219TEST_F(EncryptionOperationsTest, AesOcbRoundTripEmptySuccess) {
1220 // Empty messages should work fine.
1221 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1222 const char message[] = "";
1223 string ciphertext = EncryptMessage(string(message));
1224 EXPECT_EQ(12 /* nonce */ + strlen(message) + 16 /* tag */, ciphertext.size());
1225
1226 string plaintext = DecryptMessage(ciphertext);
1227 EXPECT_EQ(message, plaintext);
1228}
1229
1230TEST_F(EncryptionOperationsTest, AesOcbRoundTripEmptyCorrupted) {
1231 // Should even detect corruption of empty messages.
1232 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1233 const char message[] = "";
1234 string ciphertext = EncryptMessage(string(message));
1235 EXPECT_EQ(12 /* nonce */ + strlen(message) + 16 /* tag */, ciphertext.size());
1236
1237 ciphertext[ciphertext.size() / 2]++;
1238
1239 uint64_t op_handle;
1240 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, key_blob(), &op_handle));
1241
1242 string result;
1243 size_t input_consumed;
1244 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, ciphertext.c_str(), ciphertext.length(),
1245 &result, &input_consumed));
1246 EXPECT_EQ(ciphertext.length(), input_consumed);
1247 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(op_handle, &result));
1248}
1249
1250TEST_F(EncryptionOperationsTest, AesOcbFullChunk) {
1251 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1252 string message(4096, 'a');
1253 string ciphertext = EncryptMessage(message);
1254 EXPECT_EQ(12 /* nonce */ + message.length() + 16 /* tag */, ciphertext.size());
1255
1256 string plaintext = DecryptMessage(ciphertext);
1257 EXPECT_EQ(message, plaintext);
1258}
1259
1260TEST_F(EncryptionOperationsTest, AesOcbVariousChunkLengths) {
1261 for (unsigned chunk_length = 1; chunk_length <= 128; ++chunk_length) {
1262 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, chunk_length);
1263 string message(128, 'a');
1264 string ciphertext = EncryptMessage(message);
1265 int expected_tag_count = (message.length() + chunk_length - 1) / chunk_length;
1266 EXPECT_EQ(12 /* nonce */ + message.length() + 16 * expected_tag_count, ciphertext.size())
1267 << "Unexpected ciphertext size for chunk length " << chunk_length
1268 << " expected tag count was " << expected_tag_count
1269 << " but actual tag count was probably "
1270 << (ciphertext.size() - message.length() - 12) / 16;
1271
1272 string plaintext = DecryptMessage(ciphertext);
1273 EXPECT_EQ(message, plaintext);
1274 }
1275}
1276
1277TEST_F(EncryptionOperationsTest, AesOcbAbort) {
1278 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1279 const char message[] = "Hello";
1280
1281 uint64_t op_handle;
1282 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT, key_blob(), &op_handle));
1283
1284 string result;
1285 size_t input_consumed;
1286 EXPECT_EQ(KM_ERROR_OK,
1287 UpdateOperation(op_handle, message, strlen(message), &result, &input_consumed));
1288 EXPECT_EQ(strlen(message), input_consumed);
1289 EXPECT_EQ(KM_ERROR_OK, device()->abort(device(), op_handle));
1290}
1291
Shawn Willden128ffe02014-08-06 12:31:33 -06001292} // namespace test
1293} // namespace keymaster