blob: 448a15ea61dd0f03c6d2f72454eeb2105040692a [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),
Shawn Willden95e13822014-12-15 16:12:16 -0700440 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_KEY_SIZE, 136),
Shawn Willden19fca882015-01-22 16:35:30 -0700441 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));
Shawn Willden95e13822014-12-15 16:12:16 -0700445 params_.Reinitialize(params, array_length(params));
446 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(), &blob_,
447 &characteristics_));
448
449 keymaster_key_param_t* out_params;
450 size_t out_params_count;
451 uint64_t op_handle;
Shawn Willden5b53c992015-02-02 08:05:25 -0700452 EXPECT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE,
Shawn Willden95e13822014-12-15 16:12:16 -0700453 device()->begin(device(), KM_PURPOSE_ENCRYPT, &blob_, NULL, 0, &out_params,
454 &out_params_count, &op_handle));
455 free(out_params);
Shawn Willden19fca882015-01-22 16:35:30 -0700456}
457
458TEST_F(NewKeyGeneration, AesOcbAllValidSizes) {
459 keymaster_key_param_t params[] = {
460 Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT),
461 Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT),
Shawn Willden7efb8782014-12-11 14:07:44 -0700462 Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES), Authorization(TAG_BLOCK_MODE, KM_MODE_OCB),
463 Authorization(TAG_MAC_LENGTH, 16), Authorization(TAG_CHUNK_LENGTH, 4096),
Shawn Willden19fca882015-01-22 16:35:30 -0700464 Authorization(TAG_PADDING, KM_PAD_NONE),
465 };
466
467 size_t valid_sizes[] = {128, 192, 256};
468 for (size_t size : valid_sizes) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700469 params_.Reinitialize(params, array_length(params));
470 params_.push_back(Authorization(TAG_KEY_SIZE, size));
Shawn Willden95e13822014-12-15 16:12:16 -0700471 FreeCharacteristics();
472 FreeKeyBlob();
473
Shawn Willden5b53c992015-02-02 08:05:25 -0700474 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(),
475 &blob_, &characteristics_))
476 << "Failed to generate size: " << size;
477
Shawn Willden95e13822014-12-15 16:12:16 -0700478 keymaster_key_param_t* out_params;
479 size_t out_params_count;
480 uint64_t op_handle;
481 EXPECT_EQ(KM_ERROR_OK, device()->begin(device(), KM_PURPOSE_ENCRYPT, &blob_, NULL, 0,
482 &out_params, &out_params_count, &op_handle))
483 << "Unsupported key size: " << size;
484 free(out_params);
Shawn Willden19fca882015-01-22 16:35:30 -0700485 }
486}
487
Shawn Willden76364712014-08-11 17:48:04 -0600488typedef KeymasterTest GetKeyCharacteristics;
489TEST_F(GetKeyCharacteristics, SimpleRsa) {
490 keymaster_key_param_t params[] = {
Shawn Willden3809b932014-12-02 06:59:46 -0700491 Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN), Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY),
492 Authorization(TAG_ALGORITHM, KM_ALGORITHM_RSA), Authorization(TAG_KEY_SIZE, 256),
493 Authorization(TAG_USER_ID, 7), Authorization(TAG_USER_AUTH_ID, 8),
494 Authorization(TAG_APPLICATION_ID, "app_id", 6), Authorization(TAG_AUTH_TIMEOUT, 300),
Shawn Willden76364712014-08-11 17:48:04 -0600495 };
496
Shawn Willden5b53c992015-02-02 08:05:25 -0700497 ASSERT_EQ(KM_ERROR_OK, device()->generate_key(device(), params, array_length(params), &blob_,
498 &characteristics_));
499 AuthorizationSet original(characteristics_->sw_enforced);
500 FreeCharacteristics();
Shawn Willden76364712014-08-11 17:48:04 -0600501
Shawn Willden5b53c992015-02-02 08:05:25 -0700502 keymaster_blob_t client_id = {.data = reinterpret_cast<const uint8_t*>("app_id"),
503 .data_length = 6};
504 ASSERT_EQ(KM_ERROR_OK,
505 device()->get_key_characteristics(device(), &blob_, &client_id, NULL /* app_data */,
506 &characteristics_));
507 EXPECT_EQ(original, AuthorizationSet(characteristics_->sw_enforced));
Shawn Willden76364712014-08-11 17:48:04 -0600508}
509
Shawn Willden61644f32014-08-18 13:43:14 -0600510/**
511 * Test class that provides some infrastructure for generating keys and signing messages.
512 */
Shawn Willden1615f2e2014-08-13 10:37:40 -0600513class SigningOperationsTest : public KeymasterTest {
514 protected:
Shawn Willden5b53c992015-02-02 08:05:25 -0700515 SigningOperationsTest() : out_params_(NULL), output_(NULL), signature_(NULL) {}
516 ~SigningOperationsTest() {
517 // Clean up so (most) tests won't have to.
518 FreeOutput();
519 FreeSignature();
520 }
521
Shawn Willden61644f32014-08-18 13:43:14 -0600522 void GenerateKey(keymaster_algorithm_t algorithm, keymaster_digest_t digest,
523 keymaster_padding_t padding, uint32_t key_size) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700524 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));
525 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY));
526 params_.push_back(Authorization(TAG_ALGORITHM, algorithm));
527 params_.push_back(Authorization(TAG_KEY_SIZE, key_size));
528 params_.push_back(Authorization(TAG_USER_ID, 7));
529 params_.push_back(Authorization(TAG_USER_AUTH_ID, 8));
530 params_.push_back(Authorization(TAG_APPLICATION_ID, "app_id", 6));
531 params_.push_back(Authorization(TAG_AUTH_TIMEOUT, 300));
Shawn Willden43e999e2014-08-13 13:29:50 -0600532 if (static_cast<int>(digest) != -1)
Shawn Willden5b53c992015-02-02 08:05:25 -0700533 params_.push_back(TAG_DIGEST, digest);
Shawn Willden43e999e2014-08-13 13:29:50 -0600534 if (static_cast<int>(padding) != -1)
Shawn Willden5b53c992015-02-02 08:05:25 -0700535 params_.push_back(TAG_PADDING, padding);
536
537 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params_.data(), params_.size(),
538 &blob_, &characteristics_));
Shawn Willden61644f32014-08-18 13:43:14 -0600539 }
Shawn Willden1615f2e2014-08-13 10:37:40 -0600540
Shawn Willden61644f32014-08-18 13:43:14 -0600541 void SignMessage(const void* message, size_t size) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700542 EXPECT_EQ(KM_ERROR_OK, device()->begin(device(), KM_PURPOSE_SIGN, &blob_, client_params_,
543 array_length(client_params_), &out_params_,
544 &out_params_count_, &op_handle_));
545
546 EXPECT_EQ(KM_ERROR_OK,
547 device()->update(device(), op_handle_, reinterpret_cast<const uint8_t*>(message),
548 size, &input_consumed_, &output_, &output_length_));
549 EXPECT_EQ(0, output_length_);
550 FreeOutput();
551 EXPECT_EQ(size, input_consumed_);
552
553 EXPECT_EQ(KM_ERROR_OK,
554 device()->finish(device(), op_handle_, NULL /* signature to verify */,
555 0 /* signature to verify length */, &signature_,
556 &signature_length_));
557 EXPECT_GT(signature_length_, 0);
Shawn Willden437fbd12014-08-20 11:59:49 -0600558 }
559
Shawn Willden5b53c992015-02-02 08:05:25 -0700560 void FreeOutput() {
561 free(out_params_);
562 out_params_ = NULL;
563 free(output_);
564 output_ = NULL;
Shawn Willden61644f32014-08-18 13:43:14 -0600565 }
566
Shawn Willden5b53c992015-02-02 08:05:25 -0700567 void FreeSignature() {
568 free(signature_);
569 signature_ = NULL;
Shawn Willdenf268d742014-08-19 15:36:26 -0600570 }
571
Shawn Willden5b53c992015-02-02 08:05:25 -0700572 void corrupt_key_blob() {
573 uint8_t* tmp = const_cast<uint8_t*>(blob_.key_material);
574 ++tmp[blob_.key_material_size / 2];
Shawn Willden1615f2e2014-08-13 10:37:40 -0600575 }
576
Shawn Willden5b53c992015-02-02 08:05:25 -0700577 keymaster_blob_t client_id_ = {.data = reinterpret_cast<const uint8_t*>("app_id"),
578 .data_length = 6};
579 keymaster_key_param_t client_params_[1] = {
580 Authorization(TAG_APPLICATION_ID, client_id_.data, client_id_.data_length)};
581 keymaster_key_param_t* out_params_;
582 size_t out_params_count_;
583 uint64_t op_handle_;
584 size_t input_consumed_;
585 uint8_t* output_;
586 size_t output_length_;
587 uint8_t* signature_;
588 size_t signature_length_;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600589};
590
591TEST_F(SigningOperationsTest, RsaSuccess) {
Shawn Willden61644f32014-08-18 13:43:14 -0600592 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willdenffd790c2014-08-18 21:20:06 -0600593 const char message[] = "12345678901234567890123456789012";
Shawn Willdend05cba52014-09-26 09:58:12 -0600594 SignMessage(message, array_size(message) - 1);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600595}
596
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600597TEST_F(SigningOperationsTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600598 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willdend05cba52014-09-26 09:58:12 -0600599 const char message[] = "123456789012345678901234567890123456789012345678";
600 SignMessage(message, array_size(message) - 1);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600601}
602
Shawn Willden1615f2e2014-08-13 10:37:40 -0600603TEST_F(SigningOperationsTest, RsaAbort) {
Shawn Willden61644f32014-08-18 13:43:14 -0600604 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willden5b53c992015-02-02 08:05:25 -0700605 ASSERT_EQ(KM_ERROR_OK, device()->begin(device(), KM_PURPOSE_SIGN, &blob_, client_params_,
606 array_length(client_params_), &out_params_,
607 &out_params_count_, &op_handle_));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600608
Shawn Willden5b53c992015-02-02 08:05:25 -0700609 EXPECT_EQ(KM_ERROR_OK, device()->abort(device(), op_handle_));
610 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle_));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600611}
612
613TEST_F(SigningOperationsTest, RsaUnsupportedDigest) {
Shawn Willden61644f32014-08-18 13:43:14 -0600614 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_SHA_2_256, KM_PAD_NONE, 256 /* key size */);
Shawn Willden5b53c992015-02-02 08:05:25 -0700615 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST,
616 device()->begin(device(), KM_PURPOSE_SIGN, &blob_, client_params_,
617 array_length(client_params_), &out_params_, &out_params_count_,
618 &op_handle_));
619 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle_));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600620}
621
622TEST_F(SigningOperationsTest, RsaUnsupportedPadding) {
Shawn Willden61644f32014-08-18 13:43:14 -0600623 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_RSA_OAEP, 256 /* key size */);
Shawn Willden5b53c992015-02-02 08:05:25 -0700624 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE,
625 device()->begin(device(), KM_PURPOSE_SIGN, &blob_, client_params_,
626 array_length(client_params_), &out_params_, &out_params_count_,
627 &op_handle_));
628 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle_));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600629}
630
631TEST_F(SigningOperationsTest, RsaNoDigest) {
Shawn Willden61644f32014-08-18 13:43:14 -0600632 GenerateKey(KM_ALGORITHM_RSA, static_cast<keymaster_digest_t>(-1), KM_PAD_NONE,
633 256 /* key size */);
Shawn Willden5b53c992015-02-02 08:05:25 -0700634 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST,
635 device()->begin(device(), KM_PURPOSE_SIGN, &blob_, client_params_,
636 array_length(client_params_), &out_params_, &out_params_count_,
637 &op_handle_));
638 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle_));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600639}
640
641TEST_F(SigningOperationsTest, RsaNoPadding) {
Shawn Willden61644f32014-08-18 13:43:14 -0600642 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, static_cast<keymaster_padding_t>(-1),
643 256 /* key size */);
Shawn Willden5b53c992015-02-02 08:05:25 -0700644 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE,
645 device()->begin(device(), KM_PURPOSE_SIGN, &blob_, client_params_,
646 array_length(client_params_), &out_params_, &out_params_count_,
647 &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, RsaTooShortMessage) {
Shawn Willden61644f32014-08-18 13:43:14 -0600652 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willden5b53c992015-02-02 08:05:25 -0700653 ASSERT_EQ(KM_ERROR_OK, device()->begin(device(), KM_PURPOSE_SIGN, &blob_, client_params_,
654 array_length(client_params_), &out_params_,
655 &out_params_count_, &op_handle_));
656 ASSERT_EQ(KM_ERROR_OK,
657 device()->update(device(), op_handle_,
658 reinterpret_cast<const uint8_t*>("01234567890123456789012345678901"),
659 31, &input_consumed_, &output_, &output_length_));
660 EXPECT_EQ(0U, output_length_);
661 EXPECT_EQ(31U, input_consumed_);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600662
Shawn Willden5b53c992015-02-02 08:05:25 -0700663 ASSERT_EQ(KM_ERROR_UNKNOWN_ERROR,
664 device()->finish(device(), op_handle_, NULL, 0, &signature_, &signature_length_));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600665
Shawn Willden5b53c992015-02-02 08:05:25 -0700666 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle_));
Shawn Willden43e999e2014-08-13 13:29:50 -0600667}
668
Shawn Willdend05cba52014-09-26 09:58:12 -0600669class VerificationOperationsTest : public SigningOperationsTest {
670 protected:
671 void VerifyMessage(const void* message, size_t message_len) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700672 EXPECT_TRUE(signature_ != NULL);
Shawn Willdend05cba52014-09-26 09:58:12 -0600673
Shawn Willden5b53c992015-02-02 08:05:25 -0700674 EXPECT_EQ(KM_ERROR_OK, device()->begin(device(), KM_PURPOSE_VERIFY, &blob_, client_params_,
675 array_length(client_params_), &out_params_,
676 &out_params_count_, &op_handle_));
677 ASSERT_EQ(KM_ERROR_OK,
678 device()->update(device(), op_handle_, reinterpret_cast<const uint8_t*>(message),
679 message_len, &input_consumed_, &output_, &output_length_));
680 EXPECT_EQ(0U, output_length_);
681 FreeOutput();
682 EXPECT_EQ(message_len, input_consumed_);
Shawn Willdend05cba52014-09-26 09:58:12 -0600683
Shawn Willden5b53c992015-02-02 08:05:25 -0700684 ASSERT_EQ(KM_ERROR_OK, device()->finish(device(), op_handle_, signature_, signature_length_,
685 &output_, &output_length_));
686 EXPECT_EQ(0U, output_length_);
Shawn Willdend05cba52014-09-26 09:58:12 -0600687
Shawn Willden5b53c992015-02-02 08:05:25 -0700688 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle_));
Shawn Willdend05cba52014-09-26 09:58:12 -0600689 }
690};
691
Shawn Willden43e999e2014-08-13 13:29:50 -0600692TEST_F(VerificationOperationsTest, RsaSuccess) {
Shawn Willden61644f32014-08-18 13:43:14 -0600693 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
694 const char message[] = "12345678901234567890123456789012";
695 SignMessage(message, array_size(message) - 1);
Shawn Willdend05cba52014-09-26 09:58:12 -0600696 VerifyMessage(message, array_size(message) - 1);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600697}
698
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600699TEST_F(VerificationOperationsTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600700 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600701 const char message[] = "123456789012345678901234567890123456789012345678";
702 SignMessage(message, array_size(message) - 1);
Shawn Willdend05cba52014-09-26 09:58:12 -0600703 VerifyMessage(message, array_size(message) - 1);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600704}
705
Shawn Willden5b53c992015-02-02 08:05:25 -0700706typedef VerificationOperationsTest ExportKeyTest;
Shawn Willdenffd790c2014-08-18 21:20:06 -0600707TEST_F(ExportKeyTest, RsaSuccess) {
708 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256 /* key size */);
Shawn Willdenffd790c2014-08-18 21:20:06 -0600709
Shawn Willden5b53c992015-02-02 08:05:25 -0700710 uint8_t* export_data;
711 size_t export_data_length;
712 ASSERT_EQ(KM_ERROR_OK,
713 device()->export_key(device(), KM_KEY_FORMAT_X509, &blob_, &client_id_,
714 NULL /* app_data */, &export_data, &export_data_length));
715 EXPECT_TRUE(export_data != NULL);
716 EXPECT_GT(export_data_length, 0);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600717
718 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willden5b53c992015-02-02 08:05:25 -0700719 free(export_data);
Shawn Willdenffd790c2014-08-18 21:20:06 -0600720}
721
Shawn Willdenf268d742014-08-19 15:36:26 -0600722TEST_F(ExportKeyTest, EcdsaSuccess) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600723 GenerateKey(KM_ALGORITHM_ECDSA, KM_DIGEST_NONE, KM_PAD_NONE, 224 /* key size */);
Shawn Willdenf268d742014-08-19 15:36:26 -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 Willdenf268d742014-08-19 15:36:26 -0600735}
736
737TEST_F(ExportKeyTest, RsaUnsupportedKeyFormat) {
738 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256);
739
Shawn Willden5b53c992015-02-02 08:05:25 -0700740 uint8_t dummy[] = {1};
741 uint8_t* export_data = dummy; // So it's not NULL;
742 size_t export_data_length;
743 ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_FORMAT,
744 device()->export_key(device(), KM_KEY_FORMAT_PKCS8, &blob_, &client_id_,
745 NULL /* app_data */, &export_data, &export_data_length));
746 ASSERT_TRUE(export_data == NULL);
Shawn Willdenf268d742014-08-19 15:36:26 -0600747}
748
749TEST_F(ExportKeyTest, RsaCorruptedKeyBlob) {
750 GenerateKey(KM_ALGORITHM_RSA, KM_DIGEST_NONE, KM_PAD_NONE, 256);
Shawn Willden5b53c992015-02-02 08:05:25 -0700751 corrupt_key_blob();
Shawn Willdenf268d742014-08-19 15:36:26 -0600752
Shawn Willden5b53c992015-02-02 08:05:25 -0700753 uint8_t dummy[] = {1};
754 uint8_t* export_data = dummy; // So it's not NULL
755 size_t export_data_length;
756 ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB,
757 device()->export_key(device(), KM_KEY_FORMAT_X509, &blob_, &client_id_,
758 NULL /* app_data */, &export_data, &export_data_length));
759 ASSERT_TRUE(export_data == NULL);
Shawn Willdenf268d742014-08-19 15:36:26 -0600760}
761
Shawn Willden437fbd12014-08-20 11:59:49 -0600762static string read_file(const string& file_name) {
763 ifstream file_stream(file_name, std::ios::binary);
764 istreambuf_iterator<char> file_begin(file_stream);
765 istreambuf_iterator<char> file_end;
766 return string(file_begin, file_end);
767}
768
Shawn Willden5b53c992015-02-02 08:05:25 -0700769class ImportKeyTest : public VerificationOperationsTest {
770 protected:
771 ImportKeyTest() {
772 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_SIGN));
773 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_VERIFY));
774 params_.push_back(Authorization(TAG_DIGEST, KM_DIGEST_NONE));
775 params_.push_back(Authorization(TAG_PADDING, KM_PAD_NONE));
776 params_.push_back(Authorization(TAG_USER_ID, 7));
777 params_.push_back(Authorization(TAG_USER_AUTH_ID, 8));
778 params_.push_back(Authorization(TAG_APPLICATION_ID, "app_id", 6));
779 params_.push_back(Authorization(TAG_AUTH_TIMEOUT, 300));
780 }
781};
Brian Carlstromecf2ae92015-01-29 09:56:10 -0800782
Shawn Willden5b53c992015-02-02 08:05:25 -0700783TEST_F(ImportKeyTest, RsaSuccess) {
Shawn Willden81effc62014-08-27 10:08:46 -0600784 string pk8_key = read_file("rsa_privkey_pk8.der");
Shawn Willden437fbd12014-08-20 11:59:49 -0600785 ASSERT_EQ(633U, pk8_key.size());
786
Shawn Willden5b53c992015-02-02 08:05:25 -0700787 ASSERT_EQ(KM_ERROR_OK,
788 device()->import_key(device(), params_.data(), params_.size(), KM_KEY_FORMAT_PKCS8,
789 reinterpret_cast<const uint8_t*>(pk8_key.data()), pk8_key.size(),
790 &blob_, &characteristics_));
791 EXPECT_EQ(0U, characteristics_->hw_enforced.length);
792 AuthorizationSet auths(characteristics_->sw_enforced);
Shawn Willden437fbd12014-08-20 11:59:49 -0600793
794 // Check values derived from the key.
Shawn Willden5b53c992015-02-02 08:05:25 -0700795 EXPECT_TRUE(contains(auths, TAG_ALGORITHM, KM_ALGORITHM_RSA));
796 EXPECT_TRUE(contains(auths, TAG_KEY_SIZE, 1024));
797 EXPECT_TRUE(contains(auths, TAG_RSA_PUBLIC_EXPONENT, 65537U));
Shawn Willden437fbd12014-08-20 11:59:49 -0600798
799 // And values provided by GoogleKeymaster
Shawn Willden5b53c992015-02-02 08:05:25 -0700800 EXPECT_TRUE(contains(auths, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
801 EXPECT_TRUE(contains(auths, KM_TAG_CREATION_DATETIME));
Shawn Willden437fbd12014-08-20 11:59:49 -0600802
803 size_t message_len = 1024 / 8;
804 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
805 std::fill(message.get(), message.get() + message_len, 'a');
Shawn Willden5b53c992015-02-02 08:05:25 -0700806 SignMessage(message.get(), message_len);
807 VerifyMessage(message.get(), message_len);
Shawn Willden437fbd12014-08-20 11:59:49 -0600808}
809
Shawn Willden6bbe6782014-09-18 11:26:15 -0600810TEST_F(ImportKeyTest, RsaKeySizeMismatch) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700811 params_.push_back(Authorization(TAG_KEY_SIZE, 2048)); // Doesn't match key
Shawn Willden6bbe6782014-09-18 11:26:15 -0600812
813 string pk8_key = read_file("rsa_privkey_pk8.der");
814 ASSERT_EQ(633U, pk8_key.size());
815
Shawn Willden5b53c992015-02-02 08:05:25 -0700816 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
817 device()->import_key(device(), params_.data(), params_.size(), KM_KEY_FORMAT_PKCS8,
818 reinterpret_cast<const uint8_t*>(pk8_key.data()), pk8_key.size(),
819 &blob_, &characteristics_));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600820}
821
822TEST_F(ImportKeyTest, RsaPublicExponenMismatch) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700823 params_.push_back(Authorization(TAG_RSA_PUBLIC_EXPONENT, 3)); // Doesn't match key
Shawn Willden6bbe6782014-09-18 11:26:15 -0600824
825 string pk8_key = read_file("rsa_privkey_pk8.der");
826 ASSERT_EQ(633U, pk8_key.size());
827
Shawn Willden5b53c992015-02-02 08:05:25 -0700828 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
829 device()->import_key(device(), params_.data(), params_.size(), KM_KEY_FORMAT_PKCS8,
830 reinterpret_cast<const uint8_t*>(pk8_key.data()), pk8_key.size(),
831 &blob_, &characteristics_));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600832}
833
Shawn Willden81effc62014-08-27 10:08:46 -0600834TEST_F(ImportKeyTest, EcdsaSuccess) {
Shawn Willden81effc62014-08-27 10:08:46 -0600835 string pk8_key = read_file("ec_privkey_pk8.der");
836 ASSERT_EQ(138U, pk8_key.size());
837
Shawn Willden5b53c992015-02-02 08:05:25 -0700838 ASSERT_EQ(KM_ERROR_OK,
839 device()->import_key(device(), params_.data(), params_.size(), KM_KEY_FORMAT_PKCS8,
840 reinterpret_cast<const uint8_t*>(pk8_key.data()), pk8_key.size(),
841 &blob_, &characteristics_));
842 EXPECT_EQ(0U, characteristics_->hw_enforced.length);
843 AuthorizationSet auths(characteristics_->sw_enforced);
Shawn Willden81effc62014-08-27 10:08:46 -0600844
845 // Check values derived from the key.
Shawn Willden5b53c992015-02-02 08:05:25 -0700846 EXPECT_TRUE(contains(auths, TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
847 EXPECT_TRUE(contains(auths, TAG_KEY_SIZE, 256));
Shawn Willden81effc62014-08-27 10:08:46 -0600848
849 // And values provided by GoogleKeymaster
Shawn Willden5b53c992015-02-02 08:05:25 -0700850 EXPECT_TRUE(contains(auths, TAG_ORIGIN, KM_ORIGIN_IMPORTED));
851 EXPECT_TRUE(contains(auths, KM_TAG_CREATION_DATETIME));
Shawn Willden81effc62014-08-27 10:08:46 -0600852
Shawn Willden5b53c992015-02-02 08:05:25 -0700853 size_t message_len = 1024;
Shawn Willden81effc62014-08-27 10:08:46 -0600854 UniquePtr<uint8_t[]> message(new uint8_t[message_len]);
855 std::fill(message.get(), message.get() + message_len, 'a');
Shawn Willden5b53c992015-02-02 08:05:25 -0700856 SignMessage(message.get(), message_len);
857 VerifyMessage(message.get(), message_len);
Shawn Willden81effc62014-08-27 10:08:46 -0600858}
859
Shawn Willden5b53c992015-02-02 08:05:25 -0700860TEST_F(ImportKeyTest, EcdsaKeySizeMismatch) {
861 params_.push_back(Authorization(TAG_KEY_SIZE, 224)); // Doesn't match key
Shawn Willden6bbe6782014-09-18 11:26:15 -0600862
Shawn Willden5b53c992015-02-02 08:05:25 -0700863 string pk8_key = read_file("rsa_privkey_pk8.der");
864 ASSERT_EQ(633U, pk8_key.size());
Shawn Willden6bbe6782014-09-18 11:26:15 -0600865
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 Willden2665e862014-11-24 14:46:21 -0700872typedef KeymasterTest VersionTest;
873TEST_F(VersionTest, GetVersion) {
874 GetVersionRequest req;
875 GetVersionResponse rsp;
Shawn Willden5b53c992015-02-02 08:05:25 -0700876 device_.GetVersion(req, &rsp);
Shawn Willden2665e862014-11-24 14:46:21 -0700877 EXPECT_EQ(KM_ERROR_OK, rsp.error);
878 EXPECT_EQ(1, rsp.major_ver);
879 EXPECT_EQ(0, rsp.minor_ver);
880 EXPECT_EQ(0, rsp.subminor_ver);
881}
882
Shawn Willden4200f212014-12-02 07:01:21 -0700883/**
884 * Test class that provides some infrastructure for generating keys and encrypting messages.
885 */
886class EncryptionOperationsTest : public KeymasterTest {
887 protected:
Shawn Willdenbe4a2a32014-12-15 14:51:10 -0700888 void GenerateKey(AuthorizationSet* params) {
889 FreeKeyBlob();
890 FreeCharacteristics();
891 AddClientParams(params);
892 EXPECT_EQ(KM_ERROR_OK, device()->generate_key(device(), params->data(), params->size(),
893 &blob_, &characteristics_));
894 }
895
Shawn Willden4200f212014-12-02 07:01:21 -0700896 void GenerateKey(keymaster_algorithm_t algorithm, keymaster_padding_t padding,
897 uint32_t key_size) {
Shawn Willden6dde87c2014-12-11 14:08:48 -0700898 params_.Clear();
Shawn Willden5b53c992015-02-02 08:05:25 -0700899 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
900 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT));
901 params_.push_back(Authorization(TAG_ALGORITHM, algorithm));
902 params_.push_back(Authorization(TAG_KEY_SIZE, key_size));
903 params_.push_back(Authorization(TAG_USER_ID, 7));
904 params_.push_back(Authorization(TAG_USER_AUTH_ID, 8));
Shawn Willden5b53c992015-02-02 08:05:25 -0700905 params_.push_back(Authorization(TAG_AUTH_TIMEOUT, 300));
Shawn Willden4200f212014-12-02 07:01:21 -0700906 if (static_cast<int>(padding) != -1)
Shawn Willden5b53c992015-02-02 08:05:25 -0700907 params_.push_back(TAG_PADDING, padding);
Shawn Willden6dde87c2014-12-11 14:08:48 -0700908
Shawn Willdenbe4a2a32014-12-15 14:51:10 -0700909 GenerateKey(&params_);
Shawn Willden4200f212014-12-02 07:01:21 -0700910 }
911
Shawn Willden907c3012014-12-08 15:51:55 -0700912 void GenerateSymmetricKey(keymaster_algorithm_t algorithm, uint32_t key_size,
913 keymaster_block_mode_t block_mode, uint32_t chunk_length) {
Shawn Willden6dde87c2014-12-11 14:08:48 -0700914 params_.Clear();
Shawn Willden5b53c992015-02-02 08:05:25 -0700915 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
916 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT));
917 params_.push_back(Authorization(TAG_ALGORITHM, algorithm));
918 params_.push_back(Authorization(TAG_BLOCK_MODE, block_mode));
919 params_.push_back(Authorization(TAG_CHUNK_LENGTH, chunk_length));
920 params_.push_back(Authorization(TAG_KEY_SIZE, key_size));
921 params_.push_back(Authorization(TAG_MAC_LENGTH, 16));
922 params_.push_back(Authorization(TAG_USER_ID, 7));
923 params_.push_back(Authorization(TAG_USER_AUTH_ID, 8));
Shawn Willden5b53c992015-02-02 08:05:25 -0700924 params_.push_back(Authorization(TAG_AUTH_TIMEOUT, 300));
925
Shawn Willdenbe4a2a32014-12-15 14:51:10 -0700926 GenerateKey(&params_);
Shawn Willden907c3012014-12-08 15:51:55 -0700927 }
928
Shawn Willden4200f212014-12-02 07:01:21 -0700929 keymaster_error_t BeginOperation(keymaster_purpose_t purpose,
930 const keymaster_key_blob_t& key_blob, uint64_t* op_handle) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700931 return device()->begin(device(), purpose, &key_blob, client_params_,
932 array_length(client_params_), &out_params_, &out_params_count_,
933 op_handle);
Shawn Willden4200f212014-12-02 07:01:21 -0700934 }
935
936 keymaster_error_t UpdateOperation(uint64_t op_handle, const void* message, size_t size,
Shawn Willdenb7361132014-12-08 08:15:14 -0700937 string* output, size_t* input_consumed) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700938 uint8_t* out_tmp = NULL;
939 size_t out_length;
940 keymaster_error_t error =
941 device()->update(device(), op_handle, reinterpret_cast<const uint8_t*>(message), size,
942 input_consumed, &out_tmp, &out_length);
943 if (out_tmp)
Shawn Willden6dde87c2014-12-11 14:08:48 -0700944 output->append(reinterpret_cast<char*>(out_tmp), out_length);
Shawn Willden5b53c992015-02-02 08:05:25 -0700945 free(out_tmp);
946 return error;
Shawn Willden4200f212014-12-02 07:01:21 -0700947 }
948
949 keymaster_error_t FinishOperation(uint64_t op_handle, string* output) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700950 uint8_t* out_tmp = NULL;
951 size_t out_length;
952 keymaster_error_t error = device()->finish(device(), op_handle, NULL /* signature */,
953 0 /* signature_length */, &out_tmp, &out_length);
954 if (out_tmp)
Shawn Willden6dde87c2014-12-11 14:08:48 -0700955 output->append(reinterpret_cast<char*>(out_tmp), out_length);
Shawn Willden5b53c992015-02-02 08:05:25 -0700956 free(out_tmp);
957 return error;
Shawn Willden4200f212014-12-02 07:01:21 -0700958 }
959
960 string ProcessMessage(keymaster_purpose_t purpose, const keymaster_key_blob_t& key_blob,
961 const void* message, size_t size) {
962 uint64_t op_handle;
963 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose, key_blob, &op_handle));
964
965 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -0700966 size_t input_consumed;
967 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, message, size, &result, &input_consumed));
968 EXPECT_EQ(size, input_consumed);
Shawn Willden4200f212014-12-02 07:01:21 -0700969 EXPECT_EQ(KM_ERROR_OK, FinishOperation(op_handle, &result));
Shawn Willden6dde87c2014-12-11 14:08:48 -0700970 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, device()->abort(device(), op_handle));
Shawn Willden4200f212014-12-02 07:01:21 -0700971 return result;
972 }
973
Shawn Willden6dde87c2014-12-11 14:08:48 -0700974 string EncryptMessage(const string& message) {
975 return ProcessMessage(KM_PURPOSE_ENCRYPT, blob_, message.c_str(), message.length());
Shawn Willden4200f212014-12-02 07:01:21 -0700976 }
977
Shawn Willden6dde87c2014-12-11 14:08:48 -0700978 string DecryptMessage(const string& ciphertext) {
979 return ProcessMessage(KM_PURPOSE_DECRYPT, blob_, ciphertext.c_str(), ciphertext.length());
Shawn Willden4200f212014-12-02 07:01:21 -0700980 }
981
982 void AddClientParams(AuthorizationSet* set) { set->push_back(TAG_APPLICATION_ID, "app_id", 6); }
983
Shawn Willden5b53c992015-02-02 08:05:25 -0700984 const void corrupt_key_blob() {
985 uint8_t* tmp = const_cast<uint8_t*>(blob_.key_material);
986 ++tmp[blob_.key_material_size / 2];
Shawn Willden4200f212014-12-02 07:01:21 -0700987 }
988
Shawn Willden5b53c992015-02-02 08:05:25 -0700989 keymaster_blob_t client_id_ = {.data = reinterpret_cast<const uint8_t*>("app_id"),
990 .data_length = 6};
991 keymaster_key_param_t client_params_[1] = {
992 Authorization(TAG_APPLICATION_ID, client_id_.data, client_id_.data_length)};
993
994 keymaster_key_param_t* out_params_;
995 size_t out_params_count_;
Shawn Willden4200f212014-12-02 07:01:21 -0700996};
997
998TEST_F(EncryptionOperationsTest, RsaOaepSuccess) {
999 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1000 const char message[] = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001001 string ciphertext1 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001002 EXPECT_EQ(512 / 8, ciphertext1.size());
1003
Shawn Willden6dde87c2014-12-11 14:08:48 -07001004 string ciphertext2 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001005 EXPECT_EQ(512 / 8, ciphertext2.size());
1006
1007 // OAEP randomizes padding so every result should be different.
1008 EXPECT_NE(ciphertext1, ciphertext2);
1009}
1010
1011TEST_F(EncryptionOperationsTest, RsaOaepRoundTrip) {
1012 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1013 const char message[] = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001014 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001015 EXPECT_EQ(512 / 8, ciphertext.size());
1016
Shawn Willden6dde87c2014-12-11 14:08:48 -07001017 string plaintext = DecryptMessage(ciphertext);
Shawn Willden4200f212014-12-02 07:01:21 -07001018 EXPECT_EQ(message, plaintext);
1019}
1020
1021TEST_F(EncryptionOperationsTest, RsaOaepTooLarge) {
1022 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1023 const char message[] = "12345678901234567890123";
1024 uint64_t op_handle;
1025 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001026 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001027
Shawn Willden5b53c992015-02-02 08:05:25 -07001028 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT, blob_, &op_handle));
Shawn Willdenb7361132014-12-08 08:15:14 -07001029 EXPECT_EQ(KM_ERROR_OK,
1030 UpdateOperation(op_handle, message, array_size(message), &result, &input_consumed));
Shawn Willden4200f212014-12-02 07:01:21 -07001031 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(op_handle, &result));
1032 EXPECT_EQ(0, result.size());
1033}
1034
1035TEST_F(EncryptionOperationsTest, RsaOaepCorruptedDecrypt) {
1036 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_OAEP, 512);
1037 const char message[] = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001038 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001039 EXPECT_EQ(512 / 8, ciphertext.size());
1040
1041 // Corrupt the ciphertext
1042 ciphertext[512 / 8 / 2]++;
1043
1044 uint64_t op_handle;
1045 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001046 size_t input_consumed;
Shawn Willden5b53c992015-02-02 08:05:25 -07001047 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, blob_, &op_handle));
Shawn Willdenb7361132014-12-08 08:15:14 -07001048 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, ciphertext.data(), ciphertext.size(), &result,
1049 &input_consumed));
Shawn Willden4200f212014-12-02 07:01:21 -07001050 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(op_handle, &result));
1051 EXPECT_EQ(0, result.size());
1052}
1053
1054TEST_F(EncryptionOperationsTest, RsaPkcs1Success) {
1055 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1056 const char message[] = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001057 string ciphertext1 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001058 EXPECT_EQ(512 / 8, ciphertext1.size());
1059
Shawn Willden6dde87c2014-12-11 14:08:48 -07001060 string ciphertext2 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001061 EXPECT_EQ(512 / 8, ciphertext2.size());
1062
1063 // PKCS1 v1.5 randomizes padding so every result should be different.
1064 EXPECT_NE(ciphertext1, ciphertext2);
1065}
1066
1067TEST_F(EncryptionOperationsTest, RsaPkcs1RoundTrip) {
1068 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1069 const char message[] = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001070 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001071 EXPECT_EQ(512 / 8, ciphertext.size());
1072
Shawn Willden6dde87c2014-12-11 14:08:48 -07001073 string plaintext = DecryptMessage(ciphertext);
Shawn Willden4200f212014-12-02 07:01:21 -07001074 EXPECT_EQ(message, plaintext);
1075}
1076
1077TEST_F(EncryptionOperationsTest, RsaPkcs1TooLarge) {
1078 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1079 const char message[] = "1234567890123456789012345678901234567890123456789012";
1080 uint64_t op_handle;
1081 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001082 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001083
Shawn Willden5b53c992015-02-02 08:05:25 -07001084 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT, blob_, &op_handle));
Shawn Willdenb7361132014-12-08 08:15:14 -07001085 EXPECT_EQ(KM_ERROR_OK,
1086 UpdateOperation(op_handle, message, array_size(message), &result, &input_consumed));
Shawn Willden4200f212014-12-02 07:01:21 -07001087 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(op_handle, &result));
1088 EXPECT_EQ(0, result.size());
1089}
1090
1091TEST_F(EncryptionOperationsTest, RsaPkcs1CorruptedDecrypt) {
1092 GenerateKey(KM_ALGORITHM_RSA, KM_PAD_RSA_PKCS1_1_5_ENCRYPT, 512);
1093 const char message[] = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001094 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001095 EXPECT_EQ(512 / 8, ciphertext.size());
1096
1097 // Corrupt the ciphertext
1098 ciphertext[512 / 8 / 2]++;
1099
1100 uint64_t op_handle;
1101 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001102 size_t input_consumed;
Shawn Willden5b53c992015-02-02 08:05:25 -07001103 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, blob_, &op_handle));
Shawn Willdenb7361132014-12-08 08:15:14 -07001104 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, ciphertext.data(), ciphertext.size(), &result,
1105 &input_consumed));
Shawn Willden4200f212014-12-02 07:01:21 -07001106 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(op_handle, &result));
1107 EXPECT_EQ(0, result.size());
1108}
1109
Shawn Willden907c3012014-12-08 15:51:55 -07001110TEST_F(EncryptionOperationsTest, AesOcbSuccess) {
1111 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1112 const char message[] = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001113 string ciphertext1 = EncryptMessage(string(message));
Shawn Willden907c3012014-12-08 15:51:55 -07001114 EXPECT_EQ(12 /* nonce */ + strlen(message) + 16 /* tag */, ciphertext1.size());
1115
Shawn Willden6dde87c2014-12-11 14:08:48 -07001116 string ciphertext2 = EncryptMessage(string(message));
Shawn Willden907c3012014-12-08 15:51:55 -07001117 EXPECT_EQ(12 /* nonce */ + strlen(message) + 16 /* tag */, ciphertext2.size());
1118
1119 // OCB uses a random nonce, so every output should be different
1120 EXPECT_NE(ciphertext1, ciphertext2);
1121}
1122
Shawn Willden6dde87c2014-12-11 14:08:48 -07001123TEST_F(EncryptionOperationsTest, AesOcbRoundTripSuccess) {
1124 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1125 string message = "Hello World!";
1126 string ciphertext = EncryptMessage(message);
1127 EXPECT_EQ(12 /* nonce */ + message.length() + 16 /* tag */, ciphertext.size());
1128
1129 string plaintext = DecryptMessage(ciphertext);
1130 EXPECT_EQ(message, plaintext);
1131}
1132
1133TEST_F(EncryptionOperationsTest, AesOcbRoundTripCorrupted) {
1134 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1135 const char message[] = "Hello World!";
1136 string ciphertext = EncryptMessage(string(message));
1137 EXPECT_EQ(12 /* nonce */ + strlen(message) + 16 /* tag */, ciphertext.size());
1138
1139 ciphertext[ciphertext.size() / 2]++;
1140
1141 uint64_t op_handle;
1142 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, key_blob(), &op_handle));
1143
1144 string result;
1145 size_t input_consumed;
1146 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, ciphertext.c_str(), ciphertext.length(),
1147 &result, &input_consumed));
1148 EXPECT_EQ(ciphertext.length(), input_consumed);
1149 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(op_handle, &result));
1150}
1151
1152TEST_F(EncryptionOperationsTest, AesDecryptGarbage) {
1153 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1154 string ciphertext(128, 'a');
1155 uint64_t op_handle;
1156 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, key_blob(), &op_handle));
1157
1158 string result;
1159 size_t input_consumed;
1160 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, ciphertext.c_str(), ciphertext.length(),
1161 &result, &input_consumed));
1162 EXPECT_EQ(ciphertext.length(), input_consumed);
1163 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(op_handle, &result));
1164}
1165
1166TEST_F(EncryptionOperationsTest, AesDecryptTooShort) {
1167 // Try decrypting garbage ciphertext that is too short to be valid (< nonce + tag).
1168 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1169 string ciphertext(12 + 15, 'a');
1170 uint64_t op_handle;
1171 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, key_blob(), &op_handle));
1172
1173 string result;
1174 size_t input_consumed;
1175 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, ciphertext.c_str(), ciphertext.length(),
1176 &result, &input_consumed));
1177 EXPECT_EQ(ciphertext.length(), input_consumed);
1178 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(op_handle, &result));
1179}
1180
1181TEST_F(EncryptionOperationsTest, AesOcbRoundTripEmptySuccess) {
1182 // Empty messages should work fine.
1183 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1184 const char message[] = "";
1185 string ciphertext = EncryptMessage(string(message));
1186 EXPECT_EQ(12 /* nonce */ + strlen(message) + 16 /* tag */, ciphertext.size());
1187
1188 string plaintext = DecryptMessage(ciphertext);
1189 EXPECT_EQ(message, plaintext);
1190}
1191
1192TEST_F(EncryptionOperationsTest, AesOcbRoundTripEmptyCorrupted) {
1193 // Should even detect corruption of empty messages.
1194 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1195 const char message[] = "";
1196 string ciphertext = EncryptMessage(string(message));
1197 EXPECT_EQ(12 /* nonce */ + strlen(message) + 16 /* tag */, ciphertext.size());
1198
1199 ciphertext[ciphertext.size() / 2]++;
1200
1201 uint64_t op_handle;
1202 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT, key_blob(), &op_handle));
1203
1204 string result;
1205 size_t input_consumed;
1206 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(op_handle, ciphertext.c_str(), ciphertext.length(),
1207 &result, &input_consumed));
1208 EXPECT_EQ(ciphertext.length(), input_consumed);
1209 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(op_handle, &result));
1210}
1211
1212TEST_F(EncryptionOperationsTest, AesOcbFullChunk) {
1213 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1214 string message(4096, 'a');
1215 string ciphertext = EncryptMessage(message);
1216 EXPECT_EQ(12 /* nonce */ + message.length() + 16 /* tag */, ciphertext.size());
1217
1218 string plaintext = DecryptMessage(ciphertext);
1219 EXPECT_EQ(message, plaintext);
1220}
1221
1222TEST_F(EncryptionOperationsTest, AesOcbVariousChunkLengths) {
1223 for (unsigned chunk_length = 1; chunk_length <= 128; ++chunk_length) {
1224 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, chunk_length);
1225 string message(128, 'a');
1226 string ciphertext = EncryptMessage(message);
1227 int expected_tag_count = (message.length() + chunk_length - 1) / chunk_length;
1228 EXPECT_EQ(12 /* nonce */ + message.length() + 16 * expected_tag_count, ciphertext.size())
1229 << "Unexpected ciphertext size for chunk length " << chunk_length
1230 << " expected tag count was " << expected_tag_count
1231 << " but actual tag count was probably "
1232 << (ciphertext.size() - message.length() - 12) / 16;
1233
1234 string plaintext = DecryptMessage(ciphertext);
1235 EXPECT_EQ(message, plaintext);
1236 }
1237}
1238
1239TEST_F(EncryptionOperationsTest, AesOcbAbort) {
1240 GenerateSymmetricKey(KM_ALGORITHM_AES, 128, KM_MODE_OCB, 4096);
1241 const char message[] = "Hello";
1242
1243 uint64_t op_handle;
1244 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT, key_blob(), &op_handle));
1245
1246 string result;
1247 size_t input_consumed;
1248 EXPECT_EQ(KM_ERROR_OK,
1249 UpdateOperation(op_handle, message, strlen(message), &result, &input_consumed));
1250 EXPECT_EQ(strlen(message), input_consumed);
1251 EXPECT_EQ(KM_ERROR_OK, device()->abort(device(), op_handle));
1252}
1253
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001254TEST_F(EncryptionOperationsTest, AesOcbNoChunkLength) {
1255 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
1256 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT));
1257 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES));
1258 params_.push_back(Authorization(TAG_KEY_SIZE, 128));
1259 params_.push_back(Authorization(TAG_MAC_LENGTH, 16));
1260 params_.push_back(Authorization(TAG_BLOCK_MODE, KM_MODE_OCB));
1261 params_.push_back(Authorization(TAG_PADDING, KM_PAD_NONE));
1262
1263 GenerateKey(&params_);
1264 uint64_t op_handle;
1265 EXPECT_EQ(KM_ERROR_INVALID_ARGUMENT,
1266 BeginOperation(KM_PURPOSE_ENCRYPT, key_blob(), &op_handle));
1267}
1268
1269TEST_F(EncryptionOperationsTest, AesEcbUnsupported) {
1270 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
1271 params_.push_back(Authorization(TAG_MAC_LENGTH, 16));
1272 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT));
1273 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES));
1274 params_.push_back(Authorization(TAG_KEY_SIZE, 128));
1275 params_.push_back(Authorization(TAG_BLOCK_MODE, KM_MODE_ECB));
1276 params_.push_back(Authorization(TAG_PADDING, KM_PAD_NONE));
1277
1278 GenerateKey(&params_);
1279 uint64_t op_handle;
1280 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE,
1281 BeginOperation(KM_PURPOSE_ENCRYPT, key_blob(), &op_handle));
1282}
1283
1284TEST_F(EncryptionOperationsTest, AesOcbPaddingUnsupported) {
1285 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
1286 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT));
1287 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES));
1288 params_.push_back(Authorization(TAG_KEY_SIZE, 128));
1289 params_.push_back(Authorization(TAG_MAC_LENGTH, 16));
1290 params_.push_back(Authorization(TAG_BLOCK_MODE, KM_MODE_OCB));
1291 params_.push_back(Authorization(TAG_CHUNK_LENGTH, 4096));
1292 params_.push_back(Authorization(TAG_PADDING, KM_PAD_ZERO));
1293
1294 GenerateKey(&params_);
1295 uint64_t op_handle;
1296 EXPECT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE,
1297 BeginOperation(KM_PURPOSE_ENCRYPT, key_blob(), &op_handle));
1298}
1299
1300TEST_F(EncryptionOperationsTest, AesOcbInvalidMacLength) {
1301 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
1302 params_.push_back(Authorization(TAG_PURPOSE, KM_PURPOSE_DECRYPT));
1303 params_.push_back(Authorization(TAG_ALGORITHM, KM_ALGORITHM_AES));
1304 params_.push_back(Authorization(TAG_KEY_SIZE, 128));
1305 params_.push_back(Authorization(TAG_MAC_LENGTH, 17));
1306 params_.push_back(Authorization(TAG_BLOCK_MODE, KM_MODE_OCB));
1307 params_.push_back(Authorization(TAG_CHUNK_LENGTH, 4096));
1308
1309 GenerateKey(&params_);
1310 uint64_t op_handle;
1311 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB,
1312 BeginOperation(KM_PURPOSE_ENCRYPT, key_blob(), &op_handle));
1313}
1314
Shawn Willden128ffe02014-08-06 12:31:33 -06001315} // namespace test
1316} // namespace keymaster