blob: d6c62c7e15c36aec1f86a055fb5f575e3a40d652 [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 Willdenb15d77e2014-12-17 16:44:29 -070047/**
48 * Utility class to make construction of AuthorizationSets easy, and readable. Use like:
49 *
50 * ParamBuilder()
51 * .Option(TAG_ALGORITHM, KM_ALGORITHM_RSA)
52 * .Option(TAG_KEY_SIZE, 512)
53 * .Option(TAG_DIGEST, KM_DIGEST_NONE)
54 * .Option(TAG_PADDING, KM_PAD_NONE)
55 * .Option(TAG_SINGLE_USE_PER_BOOT, true)
56 * .build();
57 *
58 * In addition there are methods that add common sets of parameters, like RsaSigningKey().
59 */
60class ParamBuilder {
61 public:
62 template <typename TagType, typename ValueType>
63 ParamBuilder& Option(TagType tag, ValueType value) {
64 set.push_back(tag, value);
65 return *this;
66 }
67
68 ParamBuilder& RsaKey(uint32_t key_size = 0, uint64_t public_exponent = 0) {
69 Option(TAG_ALGORITHM, KM_ALGORITHM_RSA);
70 if (key_size != 0)
71 Option(TAG_KEY_SIZE, key_size);
72 if (public_exponent != 0)
73 Option(TAG_RSA_PUBLIC_EXPONENT, public_exponent);
74 return *this;
75 }
76
77 ParamBuilder& EcdsaKey(uint32_t key_size = 0) {
78 Option(TAG_ALGORITHM, KM_ALGORITHM_ECDSA);
79 if (key_size != 0)
80 Option(TAG_KEY_SIZE, key_size);
81 return *this;
82 }
83
84 ParamBuilder& AesKey(uint32_t key_size) {
85 Option(TAG_ALGORITHM, KM_ALGORITHM_AES);
86 return Option(TAG_KEY_SIZE, key_size);
87 }
88
89 ParamBuilder& HmacKey(uint32_t key_size, keymaster_digest_t digest, uint32_t mac_length) {
90 Option(TAG_ALGORITHM, KM_ALGORITHM_HMAC);
91 Option(TAG_KEY_SIZE, key_size);
92 SigningKey();
93 Option(TAG_DIGEST, digest);
94 return Option(TAG_MAC_LENGTH, mac_length);
95 }
96
97 ParamBuilder& RsaSigningKey(uint32_t key_size = 0, keymaster_digest_t digest = KM_DIGEST_NONE,
98 keymaster_padding_t padding = KM_PAD_NONE,
99 uint64_t public_exponent = 0) {
100 RsaKey(key_size, public_exponent);
101 SigningKey();
102 Option(TAG_DIGEST, digest);
103 return Option(TAG_PADDING, padding);
104 }
105
106 ParamBuilder& RsaEncryptionKey(uint32_t key_size = 0,
107 keymaster_padding_t padding = KM_PAD_RSA_OAEP,
108 uint64_t public_exponent = 0) {
109 RsaKey(key_size, public_exponent);
110 EncryptionKey();
111 return Option(TAG_PADDING, padding);
112 }
113
114 ParamBuilder& EcdsaSigningKey(uint32_t key_size = 0) {
115 EcdsaKey(key_size);
116 return SigningKey();
117 }
118
119 ParamBuilder& AesEncryptionKey(uint32_t key_size) {
120 AesKey(key_size);
121 return EncryptionKey();
122 }
123
124 ParamBuilder& SigningKey() {
125 Option(TAG_PURPOSE, KM_PURPOSE_SIGN);
126 return Option(TAG_PURPOSE, KM_PURPOSE_VERIFY);
127 }
128
129 ParamBuilder& EncryptionKey() {
130 Option(TAG_PURPOSE, KM_PURPOSE_ENCRYPT);
131 return Option(TAG_PURPOSE, KM_PURPOSE_DECRYPT);
132 }
133
134 ParamBuilder& NoDigestOrPadding() {
135 Option(TAG_DIGEST, KM_DIGEST_NONE);
136 return Option(TAG_PADDING, KM_PAD_NONE);
137 }
138
139 ParamBuilder& OcbMode(uint32_t chunk_length, uint32_t mac_length) {
140 Option(TAG_BLOCK_MODE, KM_MODE_OCB);
141 Option(TAG_CHUNK_LENGTH, chunk_length);
142 return Option(TAG_MAC_LENGTH, mac_length);
143 }
144
145 AuthorizationSet build() const { return set; }
146
147 private:
148 AuthorizationSet set;
Shawn Willden6bbe6782014-09-18 11:26:15 -0600149};
150
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700151const uint64_t OP_HANDLE_SENTINEL = 0xFFFFFFFFFFFFFFFF;
Shawn Willden128ffe02014-08-06 12:31:33 -0600152class KeymasterTest : public testing::Test {
153 protected:
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700154 KeymasterTest()
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700155 : device_(new StdoutLogger), out_params_(NULL), op_handle_(OP_HANDLE_SENTINEL),
156 characteristics_(NULL) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700157 blob_.key_material = NULL;
158 RAND_seed("foobar", 6);
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700159 blob_.key_material = 0;
Shawn Willden5b53c992015-02-02 08:05:25 -0700160 }
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700161
Shawn Willden5b53c992015-02-02 08:05:25 -0700162 ~KeymasterTest() {
163 FreeCharacteristics();
164 FreeKeyBlob();
Shawn Willdend0772312014-09-18 12:27:57 -0600165 }
166
Shawn Willden5b53c992015-02-02 08:05:25 -0700167 keymaster_device* device() { return reinterpret_cast<keymaster_device*>(device_.hw_device()); }
168
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700169 keymaster_error_t AttemptToGenerateKey(const ParamBuilder& builder) {
170 AuthorizationSet params(builder.build());
171 params.push_back(UserAuthParams());
172 params.push_back(ClientParams());
173
Shawn Willden0d560bf2014-12-15 17:44:02 -0700174 FreeKeyBlob();
175 FreeCharacteristics();
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700176 return device()->generate_key(device(), params.data(), params.size(), &blob_,
177 &characteristics_);
Shawn Willden0d560bf2014-12-15 17:44:02 -0700178 }
179
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700180 void GenerateKey(const ParamBuilder& builder) {
181 ASSERT_EQ(KM_ERROR_OK, AttemptToGenerateKey(builder));
182 }
183
184 keymaster_error_t AttemptImportKey(const ParamBuilder& builder, keymaster_key_format_t format,
185 const string& key_material) {
186 AuthorizationSet params(builder.build());
187 params.push_back(UserAuthParams());
188 params.push_back(ClientParams());
189
190 FreeKeyBlob();
191 FreeCharacteristics();
192 return device()->import_key(device(), params.data(), params.size(), format,
193 reinterpret_cast<const uint8_t*>(key_material.c_str()),
194 key_material.length(), &blob_, &characteristics_);
195 }
196
197 void ImportKey(const ParamBuilder& builder, keymaster_key_format_t format,
198 const string& key_material) {
199 ASSERT_EQ(KM_ERROR_OK, AttemptImportKey(builder, format, key_material));
200 }
201
202 AuthorizationSet UserAuthParams() {
203 AuthorizationSet set;
204 set.push_back(TAG_USER_ID, 7);
205 set.push_back(TAG_USER_AUTH_ID, 8);
206 set.push_back(TAG_AUTH_TIMEOUT, 300);
207 return set;
208 }
209
210 AuthorizationSet ClientParams() {
211 AuthorizationSet set;
212 set.push_back(TAG_APPLICATION_ID, "app_id", 6);
213 return set;
214 }
215
216 keymaster_error_t BeginOperation(keymaster_purpose_t purpose) {
217 return device()->begin(device(), purpose, &blob_, client_params_,
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700218 array_length(client_params_), &out_params_, &out_params_count_,
219 &op_handle_);
220 }
221
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700222 keymaster_error_t UpdateOperation(const string& message, string* output,
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700223 size_t* input_consumed) {
224 uint8_t* out_tmp = NULL;
225 size_t out_length;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700226 EXPECT_NE(op_handle_, OP_HANDLE_SENTINEL);
227 keymaster_error_t error = device()->update(
228 device(), op_handle_, reinterpret_cast<const uint8_t*>(message.c_str()),
229 message.length(), input_consumed, &out_tmp, &out_length);
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700230 if (out_tmp)
231 output->append(reinterpret_cast<char*>(out_tmp), out_length);
232 free(out_tmp);
233 return error;
234 }
235
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700236 keymaster_error_t FinishOperation(string* output) { return FinishOperation("", output); }
237
238 keymaster_error_t FinishOperation(const string& signature, string* output) {
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700239 uint8_t* out_tmp = NULL;
240 size_t out_length;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700241 keymaster_error_t error = device()->finish(
242 device(), op_handle_, reinterpret_cast<const uint8_t*>(signature.c_str()),
243 signature.length(), &out_tmp, &out_length);
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700244 if (out_tmp)
245 output->append(reinterpret_cast<char*>(out_tmp), out_length);
246 free(out_tmp);
247 return error;
248 }
249
Shawn Willden5b53c992015-02-02 08:05:25 -0700250 template <typename T> void ExpectContains(T val, T* vals, size_t len) {
251 EXPECT_EQ(1U, len);
252 EXPECT_EQ(val, vals[0]);
Shawn Willdend0772312014-09-18 12:27:57 -0600253 }
254
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700255 keymaster_error_t AbortOperation() { return device()->abort(device(), op_handle_); }
256
257 string ProcessMessage(keymaster_purpose_t purpose, const string& message) {
258 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose));
259
260 string result;
261 size_t input_consumed;
262 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
263 EXPECT_EQ(message.size(), input_consumed);
264 EXPECT_EQ(KM_ERROR_OK, FinishOperation(&result));
265 return result;
266 }
267
268 string ProcessMessage(keymaster_purpose_t purpose, const string& message,
269 const string& signature) {
270 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose));
271
272 string result;
273 size_t input_consumed;
274 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
275 EXPECT_EQ(message.size(), input_consumed);
276 EXPECT_EQ(KM_ERROR_OK, FinishOperation(signature, &result));
277 return result;
278 }
279
280 void SignMessage(const string& message, string* signature) {
281 *signature = ProcessMessage(KM_PURPOSE_SIGN, message);
282 EXPECT_GT(signature->size(), 0);
283 }
284
285 void VerifyMessage(const string& message, const string& signature) {
286 ProcessMessage(KM_PURPOSE_VERIFY, message, signature);
287 }
288
289 string EncryptMessage(const string& message) {
290 return ProcessMessage(KM_PURPOSE_ENCRYPT, message);
291 }
292
293 string DecryptMessage(const string& ciphertext) {
294 return ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext);
295 }
296
297 keymaster_error_t GetCharacteristics() {
298 FreeCharacteristics();
299 return device()->get_key_characteristics(device(), &blob_, &client_id_, NULL /* app_data */,
300 &characteristics_);
301 }
302
303 keymaster_error_t ExportKey(keymaster_key_format_t format, string* export_data) {
304 uint8_t* export_data_tmp;
305 size_t export_data_length;
306
307 keymaster_error_t error =
308 device()->export_key(device(), format, &blob_, &client_id_, NULL /* app_data */,
309 &export_data_tmp, &export_data_length);
310
311 if (error != KM_ERROR_OK)
312 return error;
313
314 *export_data = string(reinterpret_cast<char*>(export_data_tmp), export_data_length);
315 free(export_data_tmp);
316 return error;
317 }
318
319 keymaster_error_t GetVersion(uint8_t* major, uint8_t* minor, uint8_t* subminor) {
320 GetVersionRequest request;
321 GetVersionResponse response;
322 device_.GetVersion(request, &response);
323 if (response.error != KM_ERROR_OK)
324 return response.error;
325 *major = response.major_ver;
326 *minor = response.minor_ver;
327 *subminor = response.subminor_ver;
328 return response.error;
329 }
330
331 AuthorizationSet hw_enforced() {
332 EXPECT_TRUE(characteristics_ != NULL);
333 return AuthorizationSet(characteristics_->hw_enforced);
334 }
335
336 AuthorizationSet sw_enforced() {
337 EXPECT_TRUE(characteristics_ != NULL);
338 return AuthorizationSet(characteristics_->sw_enforced);
339 }
340
Shawn Willden5b53c992015-02-02 08:05:25 -0700341 void FreeCharacteristics() {
342 keymaster_free_characteristics(characteristics_);
343 free(characteristics_);
344 characteristics_ = NULL;
345 }
346
347 void FreeKeyBlob() {
348 free(const_cast<uint8_t*>(blob_.key_material));
349 blob_.key_material = NULL;
350 }
351
Shawn Willden6dde87c2014-12-11 14:08:48 -0700352 const keymaster_key_blob_t& key_blob() { return blob_; }
353
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700354 void corrupt_key_blob() {
355 assert(blob_.key_material);
356 uint8_t* tmp = const_cast<uint8_t*>(blob_.key_material);
357 ++tmp[blob_.key_material_size / 2];
358 }
Shawn Willden5b53c992015-02-02 08:05:25 -0700359
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700360 private:
361 SoftKeymasterDevice device_;
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700362 keymaster_blob_t client_id_ = {.data = reinterpret_cast<const uint8_t*>("app_id"),
363 .data_length = 6};
364 keymaster_key_param_t client_params_[1] = {
365 Authorization(TAG_APPLICATION_ID, client_id_.data, client_id_.data_length)};
366
367 keymaster_key_param_t* out_params_;
368 size_t out_params_count_;
369 uint64_t op_handle_;
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700370
Shawn Willden5b53c992015-02-02 08:05:25 -0700371 keymaster_key_blob_t blob_;
372 keymaster_key_characteristics_t* characteristics_;
Shawn Willden128ffe02014-08-06 12:31:33 -0600373};
374
Shawn Willden128ffe02014-08-06 12:31:33 -0600375typedef KeymasterTest CheckSupported;
376TEST_F(CheckSupported, SupportedAlgorithms) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700377 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
378 device()->get_supported_algorithms(device(), NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600379
Shawn Willden5b53c992015-02-02 08:05:25 -0700380 size_t len;
381 keymaster_algorithm_t* algorithms;
382 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_algorithms(device(), &algorithms, &len));
383 ASSERT_EQ(4U, len);
384 EXPECT_EQ(KM_ALGORITHM_RSA, algorithms[0]);
385 EXPECT_EQ(KM_ALGORITHM_DSA, algorithms[1]);
386 EXPECT_EQ(KM_ALGORITHM_ECDSA, algorithms[2]);
387 EXPECT_EQ(KM_ALGORITHM_AES, algorithms[3]);
388
389 free(algorithms);
Shawn Willden128ffe02014-08-06 12:31:33 -0600390}
391
392TEST_F(CheckSupported, SupportedBlockModes) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700393 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
394 device()->get_supported_block_modes(device(), KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT,
395 NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600396
Shawn Willden5b53c992015-02-02 08:05:25 -0700397 size_t len;
398 keymaster_block_mode_t* modes;
399 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE,
400 device()->get_supported_block_modes(device(), KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT,
401 &modes, &len));
Shawn Willden128ffe02014-08-06 12:31:33 -0600402
Shawn Willden5b53c992015-02-02 08:05:25 -0700403 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE,
404 device()->get_supported_block_modes(device(), KM_ALGORITHM_DSA, KM_PURPOSE_ENCRYPT,
405 &modes, &len));
Shawn Willden28e41472014-08-18 13:35:22 -0600406
Shawn Willden5b53c992015-02-02 08:05:25 -0700407 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE,
408 device()->get_supported_block_modes(device(), KM_ALGORITHM_ECDSA, KM_PURPOSE_ENCRYPT,
409 &modes, &len));
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600410
Shawn Willden5b53c992015-02-02 08:05:25 -0700411 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE,
412 device()->get_supported_block_modes(device(), KM_ALGORITHM_AES, KM_PURPOSE_ENCRYPT,
413 &modes, &len));
Shawn Willden128ffe02014-08-06 12:31:33 -0600414}
415
416TEST_F(CheckSupported, SupportedPaddingModes) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700417 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
418 device()->get_supported_padding_modes(device(), KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT,
419 NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600420
Shawn Willden5b53c992015-02-02 08:05:25 -0700421 size_t len;
422 keymaster_padding_t* modes;
423 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_RSA,
424 KM_PURPOSE_SIGN, &modes, &len));
425 ExpectContains(KM_PAD_NONE, modes, len);
426 free(modes);
Shawn Willden128ffe02014-08-06 12:31:33 -0600427
Shawn Willden5b53c992015-02-02 08:05:25 -0700428 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_DSA,
429 KM_PURPOSE_SIGN, &modes, &len));
430 ExpectContains(KM_PAD_NONE, modes, len);
431 free(modes);
Shawn Willden28e41472014-08-18 13:35:22 -0600432
Shawn Willden5b53c992015-02-02 08:05:25 -0700433 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_ECDSA,
434 KM_PURPOSE_SIGN, &modes, &len));
435 ExpectContains(KM_PAD_NONE, modes, len);
436 free(modes);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600437
Shawn Willden5b53c992015-02-02 08:05:25 -0700438 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_AES,
439 KM_PURPOSE_SIGN, &modes, &len));
440 EXPECT_EQ(0, len);
441 free(modes);
Shawn Willden128ffe02014-08-06 12:31:33 -0600442}
443
444TEST_F(CheckSupported, SupportedDigests) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700445 EXPECT_EQ(
446 KM_ERROR_OUTPUT_PARAMETER_NULL,
447 device()->get_supported_digests(device(), KM_ALGORITHM_RSA, KM_PURPOSE_SIGN, NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600448
Shawn Willden5b53c992015-02-02 08:05:25 -0700449 size_t len;
450 keymaster_digest_t* digests;
451 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_RSA,
452 KM_PURPOSE_SIGN, &digests, &len));
453 ExpectContains(KM_DIGEST_NONE, digests, len);
454 free(digests);
Shawn Willden128ffe02014-08-06 12:31:33 -0600455
Shawn Willden5b53c992015-02-02 08:05:25 -0700456 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_DSA,
457 KM_PURPOSE_SIGN, &digests, &len));
458 ExpectContains(KM_DIGEST_NONE, digests, len);
459 free(digests);
Shawn Willden28e41472014-08-18 13:35:22 -0600460
Shawn Willden5b53c992015-02-02 08:05:25 -0700461 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_ECDSA,
462 KM_PURPOSE_SIGN, &digests, &len));
463 ExpectContains(KM_DIGEST_NONE, digests, len);
464 free(digests);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600465
Shawn Willden5b53c992015-02-02 08:05:25 -0700466 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_AES,
467 KM_PURPOSE_SIGN, &digests, &len));
468 EXPECT_EQ(0, len);
469 free(digests);
Shawn Willden128ffe02014-08-06 12:31:33 -0600470}
471
472TEST_F(CheckSupported, SupportedImportFormats) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700473 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
474 device()->get_supported_import_formats(device(), KM_ALGORITHM_RSA, NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600475
Shawn Willden5b53c992015-02-02 08:05:25 -0700476 size_t len;
477 keymaster_key_format_t* formats;
478 EXPECT_EQ(KM_ERROR_OK,
479 device()->get_supported_import_formats(device(), KM_ALGORITHM_RSA, &formats, &len));
480 ExpectContains(KM_KEY_FORMAT_PKCS8, formats, len);
481 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600482
Shawn Willden5b53c992015-02-02 08:05:25 -0700483 EXPECT_EQ(KM_ERROR_OK,
484 device()->get_supported_import_formats(device(), KM_ALGORITHM_DSA, &formats, &len));
485 ExpectContains(KM_KEY_FORMAT_PKCS8, formats, len);
486 free(formats);
Shawn Willden28e41472014-08-18 13:35:22 -0600487
Shawn Willden5b53c992015-02-02 08:05:25 -0700488 EXPECT_EQ(KM_ERROR_OK,
489 device()->get_supported_import_formats(device(), KM_ALGORITHM_ECDSA, &formats, &len));
490 ExpectContains(KM_KEY_FORMAT_PKCS8, formats, len);
491 free(formats);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600492
Shawn Willden5b53c992015-02-02 08:05:25 -0700493 EXPECT_EQ(KM_ERROR_OK,
494 device()->get_supported_import_formats(device(), KM_ALGORITHM_AES, &formats, &len));
495 EXPECT_EQ(0, len);
496 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600497}
498
499TEST_F(CheckSupported, SupportedExportFormats) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700500 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
501 device()->get_supported_export_formats(device(), KM_ALGORITHM_RSA, NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600502
Shawn Willden5b53c992015-02-02 08:05:25 -0700503 size_t len;
504 keymaster_key_format_t* formats;
505 EXPECT_EQ(KM_ERROR_OK,
506 device()->get_supported_export_formats(device(), KM_ALGORITHM_RSA, &formats, &len));
507 ExpectContains(KM_KEY_FORMAT_X509, formats, len);
508 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600509
Shawn Willden5b53c992015-02-02 08:05:25 -0700510 EXPECT_EQ(KM_ERROR_OK,
511 device()->get_supported_export_formats(device(), KM_ALGORITHM_DSA, &formats, &len));
512 ExpectContains(KM_KEY_FORMAT_X509, formats, len);
513 free(formats);
Shawn Willden28e41472014-08-18 13:35:22 -0600514
Shawn Willden5b53c992015-02-02 08:05:25 -0700515 EXPECT_EQ(KM_ERROR_OK,
516 device()->get_supported_export_formats(device(), KM_ALGORITHM_ECDSA, &formats, &len));
517 ExpectContains(KM_KEY_FORMAT_X509, formats, len);
518 free(formats);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600519
Shawn Willden5b53c992015-02-02 08:05:25 -0700520 EXPECT_EQ(KM_ERROR_OK,
521 device()->get_supported_export_formats(device(), KM_ALGORITHM_AES, &formats, &len));
522 EXPECT_EQ(0, len);
523 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600524}
525
Shawn Willden5b53c992015-02-02 08:05:25 -0700526TEST_F(KeymasterTest, TestFlags) {
527 EXPECT_TRUE(device()->flags & KEYMASTER_SOFTWARE_ONLY);
528 EXPECT_TRUE(device()->flags & KEYMASTER_BLOBS_ARE_STANDALONE);
529 EXPECT_FALSE(device()->flags & KEYMASTER_SUPPORTS_DSA);
530 EXPECT_TRUE(device()->flags & KEYMASTER_SUPPORTS_EC);
531}
532
533typedef KeymasterTest OldKeyGeneration;
534
535TEST_F(OldKeyGeneration, Rsa) {
536 keymaster_rsa_keygen_params_t params = {.modulus_size = 256, .public_exponent = 3};
537 uint8_t* key_blob;
538 size_t key_blob_length;
539 EXPECT_EQ(0,
540 device()->generate_keypair(device(), TYPE_RSA, &params, &key_blob, &key_blob_length));
541 EXPECT_GT(key_blob_length, 0);
542
543 free(key_blob);
544}
545
546TEST_F(OldKeyGeneration, Ecdsa) {
547
548 keymaster_ec_keygen_params_t params = {.field_size = 256};
549 uint8_t* key_blob;
550 size_t key_blob_length;
551 EXPECT_EQ(0,
552 device()->generate_keypair(device(), TYPE_EC, &params, &key_blob, &key_blob_length));
553 EXPECT_GT(key_blob_length, 0);
554
555 free(key_blob);
556}
557
Shawn Willdend0772312014-09-18 12:27:57 -0600558class NewKeyGeneration : public KeymasterTest {
559 protected:
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700560 void CheckBaseParams() {
561 EXPECT_EQ(0U, hw_enforced().size());
562 EXPECT_EQ(12U, hw_enforced().SerializedSize());
Shawn Willdend0772312014-09-18 12:27:57 -0600563
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700564 AuthorizationSet auths = sw_enforced();
565 EXPECT_GT(auths.SerializedSize(), 12U);
566
Shawn Willden5b53c992015-02-02 08:05:25 -0700567 EXPECT_TRUE(contains(auths, TAG_PURPOSE, KM_PURPOSE_SIGN));
568 EXPECT_TRUE(contains(auths, TAG_PURPOSE, KM_PURPOSE_VERIFY));
569 EXPECT_TRUE(contains(auths, TAG_USER_ID, 7));
570 EXPECT_TRUE(contains(auths, TAG_USER_AUTH_ID, 8));
571 EXPECT_TRUE(contains(auths, TAG_AUTH_TIMEOUT, 300));
Shawn Willdend0772312014-09-18 12:27:57 -0600572
573 // Verify that App ID, App data and ROT are NOT included.
Shawn Willden5b53c992015-02-02 08:05:25 -0700574 EXPECT_FALSE(contains(auths, TAG_ROOT_OF_TRUST));
575 EXPECT_FALSE(contains(auths, TAG_APPLICATION_ID));
576 EXPECT_FALSE(contains(auths, TAG_APPLICATION_DATA));
Shawn Willdend0772312014-09-18 12:27:57 -0600577
578 // Just for giggles, check that some unexpected tags/values are NOT present.
Shawn Willden5b53c992015-02-02 08:05:25 -0700579 EXPECT_FALSE(contains(auths, TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
580 EXPECT_FALSE(contains(auths, TAG_PURPOSE, KM_PURPOSE_DECRYPT));
581 EXPECT_FALSE(contains(auths, TAG_AUTH_TIMEOUT, 301));
Shawn Willdend0772312014-09-18 12:27:57 -0600582
583 // Now check that unspecified, defaulted tags are correct.
Shawn Willden5b53c992015-02-02 08:05:25 -0700584 EXPECT_TRUE(contains(auths, TAG_ORIGIN, KM_ORIGIN_SOFTWARE));
585 EXPECT_TRUE(contains(auths, KM_TAG_CREATION_DATETIME));
Shawn Willdend0772312014-09-18 12:27:57 -0600586 }
Shawn Willden2079ae82015-01-22 13:42:31 -0700587};
588
Shawn Willden128ffe02014-08-06 12:31:33 -0600589TEST_F(NewKeyGeneration, Rsa) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700590 GenerateKey(ParamBuilder().RsaSigningKey(256, KM_DIGEST_NONE, KM_PAD_NONE, 3));
591 CheckBaseParams();
Shawn Willden128ffe02014-08-06 12:31:33 -0600592
Shawn Willden5b53c992015-02-02 08:05:25 -0700593 // Check specified tags are all present in auths
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700594 AuthorizationSet auths(sw_enforced());
Shawn Willden5b53c992015-02-02 08:05:25 -0700595 EXPECT_TRUE(contains(auths, TAG_ALGORITHM, KM_ALGORITHM_RSA));
596 EXPECT_TRUE(contains(auths, TAG_KEY_SIZE, 256));
597 EXPECT_TRUE(contains(auths, TAG_RSA_PUBLIC_EXPONENT, 3));
Shawn Willden128ffe02014-08-06 12:31:33 -0600598}
599
Shawn Willden6bbe6782014-09-18 11:26:15 -0600600TEST_F(NewKeyGeneration, RsaDefaultSize) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700601 // TODO(swillden): Remove support for defaulting RSA parameter size and pub exponent.
602 GenerateKey(ParamBuilder().RsaSigningKey());
603 CheckBaseParams();
Shawn Willden6bbe6782014-09-18 11:26:15 -0600604
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700605 // Check specified tags are all present in unenforced characteristics
606 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_RSA));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600607
608 // Now check that unspecified, defaulted tags are correct.
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700609 EXPECT_TRUE(contains(sw_enforced(), TAG_RSA_PUBLIC_EXPONENT, 65537));
610 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 2048));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600611}
612
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600613TEST_F(NewKeyGeneration, Ecdsa) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700614 GenerateKey(ParamBuilder().EcdsaSigningKey(224));
615 CheckBaseParams();
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600616
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700617 // Check specified tags are all present in unenforced characteristics
618 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
619 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 224));
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600620}
621
Shawn Willden6bbe6782014-09-18 11:26:15 -0600622TEST_F(NewKeyGeneration, EcdsaDefaultSize) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700623 GenerateKey(ParamBuilder().EcdsaSigningKey());
624 CheckBaseParams();
Shawn Willden6bbe6782014-09-18 11:26:15 -0600625
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700626 // Check specified tags are all present in unenforced characteristics
627 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600628
629 // Now check that unspecified, defaulted tags are correct.
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700630 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 224));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600631}
632
633TEST_F(NewKeyGeneration, EcdsaInvalidSize) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700634 ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE,
635 AttemptToGenerateKey(ParamBuilder().EcdsaSigningKey(190)));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600636}
637
638TEST_F(NewKeyGeneration, EcdsaAllValidSizes) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600639 size_t valid_sizes[] = {224, 256, 384, 521};
Shawn Willden6bbe6782014-09-18 11:26:15 -0600640 for (size_t size : valid_sizes) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700641 EXPECT_EQ(KM_ERROR_OK, AttemptToGenerateKey(ParamBuilder().EcdsaSigningKey(size)))
Shawn Willden5b53c992015-02-02 08:05:25 -0700642 << "Failed to generate size: " << size;
Shawn Willden6bbe6782014-09-18 11:26:15 -0600643 }
644}
645
Shawn Willden19fca882015-01-22 16:35:30 -0700646TEST_F(NewKeyGeneration, AesOcb) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700647 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
Shawn Willden19fca882015-01-22 16:35:30 -0700648}
649
650TEST_F(NewKeyGeneration, AesOcbInvalidKeySize) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700651 GenerateKey(ParamBuilder().AesEncryptionKey(136).OcbMode(4096, 16));
652 EXPECT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willden19fca882015-01-22 16:35:30 -0700653}
654
655TEST_F(NewKeyGeneration, AesOcbAllValidSizes) {
Shawn Willden19fca882015-01-22 16:35:30 -0700656 size_t valid_sizes[] = {128, 192, 256};
657 for (size_t size : valid_sizes) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700658 EXPECT_EQ(KM_ERROR_OK, AttemptToGenerateKey(ParamBuilder().AesEncryptionKey(size)))
Shawn Willden5b53c992015-02-02 08:05:25 -0700659 << "Failed to generate size: " << size;
Shawn Willden19fca882015-01-22 16:35:30 -0700660 }
661}
662
Shawn Willden0d560bf2014-12-15 17:44:02 -0700663TEST_F(NewKeyGeneration, HmacSha256) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700664 GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_256, 16));
Shawn Willden0d560bf2014-12-15 17:44:02 -0700665}
666
Shawn Willden76364712014-08-11 17:48:04 -0600667typedef KeymasterTest GetKeyCharacteristics;
668TEST_F(GetKeyCharacteristics, SimpleRsa) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700669 GenerateKey(ParamBuilder().RsaSigningKey(256));
670 AuthorizationSet original(sw_enforced());
Shawn Willden76364712014-08-11 17:48:04 -0600671
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700672 ASSERT_EQ(KM_ERROR_OK, GetCharacteristics());
673 EXPECT_EQ(original, sw_enforced());
Shawn Willden76364712014-08-11 17:48:04 -0600674}
675
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700676typedef KeymasterTest SigningOperationsTest;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600677TEST_F(SigningOperationsTest, RsaSuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700678 GenerateKey(ParamBuilder().RsaSigningKey(256));
679 string message = "12345678901234567890123456789012";
680 string signature;
681 SignMessage(message, &signature);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600682}
683
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600684TEST_F(SigningOperationsTest, EcdsaSuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700685 GenerateKey(ParamBuilder().EcdsaSigningKey(224));
686 string message = "123456789012345678901234567890123456789012345678";
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700687 string signature;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700688 SignMessage(message, &signature);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600689}
690
Shawn Willden1615f2e2014-08-13 10:37:40 -0600691TEST_F(SigningOperationsTest, RsaAbort) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700692 GenerateKey(ParamBuilder().RsaSigningKey(256));
693 ASSERT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_SIGN));
694 EXPECT_EQ(KM_ERROR_OK, AbortOperation());
695 // Another abort should fail
696 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, AbortOperation());
Shawn Willden1615f2e2014-08-13 10:37:40 -0600697}
698
699TEST_F(SigningOperationsTest, RsaUnsupportedDigest) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700700 GenerateKey(ParamBuilder().RsaSigningKey(256, KM_DIGEST_SHA_2_256, KM_PAD_NONE));
701 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600702}
703
704TEST_F(SigningOperationsTest, RsaUnsupportedPadding) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700705 GenerateKey(ParamBuilder().RsaSigningKey(256, KM_DIGEST_NONE, KM_PAD_RSA_OAEP));
706 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600707}
708
709TEST_F(SigningOperationsTest, RsaNoDigest) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700710 GenerateKey(ParamBuilder().RsaKey(256).SigningKey().Option(TAG_PADDING, KM_PAD_NONE));
711 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600712}
713
714TEST_F(SigningOperationsTest, RsaNoPadding) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700715 GenerateKey(ParamBuilder().RsaKey(256).SigningKey().Option(TAG_DIGEST, KM_DIGEST_NONE));
716 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600717}
718
Shawn Willden62c22862014-12-17 08:36:20 -0700719TEST_F(SigningOperationsTest, HmacSha224Success) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700720 GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_224, 28));
721 string message = "12345678901234567890123456789012";
722 string signature;
723 SignMessage(message, &signature);
724 ASSERT_EQ(28, signature.size());
Shawn Willden62c22862014-12-17 08:36:20 -0700725}
726
Shawn Willden0d560bf2014-12-15 17:44:02 -0700727TEST_F(SigningOperationsTest, HmacSha256Success) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700728 GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_256, 32));
729 string message = "12345678901234567890123456789012";
730 string signature;
731 SignMessage(message, &signature);
732 ASSERT_EQ(32, signature.size());
Shawn Willden0d560bf2014-12-15 17:44:02 -0700733}
734
Shawn Willden62c22862014-12-17 08:36:20 -0700735TEST_F(SigningOperationsTest, HmacSha384Success) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700736 GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_384, 48));
737 string message = "12345678901234567890123456789012";
738 string signature;
739 SignMessage(message, &signature);
740 ASSERT_EQ(48, signature.size());
Shawn Willden62c22862014-12-17 08:36:20 -0700741}
742
743TEST_F(SigningOperationsTest, HmacSha512Success) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700744 GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_512, 64));
745 string message = "12345678901234567890123456789012";
Shawn Willden62c22862014-12-17 08:36:20 -0700746 string signature;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700747 SignMessage(message, &signature);
748 ASSERT_EQ(64, signature.size());
Shawn Willden62c22862014-12-17 08:36:20 -0700749}
750
751// TODO(swillden): Add HMACSHA{224|256|384|512} tests that validates against the test vectors from
752// RFC4231. Doing that requires being able to import keys, rather than just
753// generate them randomly.
Shawn Willden0d560bf2014-12-15 17:44:02 -0700754
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700755TEST_F(SigningOperationsTest, HmacSha256NoMacLength) {
756 GenerateKey(ParamBuilder()
757 .Option(TAG_ALGORITHM, KM_ALGORITHM_HMAC)
758 .Option(TAG_KEY_SIZE, 128)
759 .SigningKey()
760 .Option(TAG_DIGEST, KM_DIGEST_SHA_2_256));
761 EXPECT_EQ(KM_ERROR_UNSUPPORTED_MAC_LENGTH, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden0d560bf2014-12-15 17:44:02 -0700762}
763
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700764TEST_F(SigningOperationsTest, HmacSha256TooLargeMacLength) {
765 GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_256, 33));
766 ASSERT_EQ(KM_ERROR_UNSUPPORTED_MAC_LENGTH, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden0d560bf2014-12-15 17:44:02 -0700767}
768
Shawn Willden1615f2e2014-08-13 10:37:40 -0600769TEST_F(SigningOperationsTest, RsaTooShortMessage) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700770 GenerateKey(ParamBuilder().RsaSigningKey(256));
771 ASSERT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700772
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700773 string message = "1234567890123456789012345678901";
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700774 string result;
775 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700776 ASSERT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700777 EXPECT_EQ(0U, result.size());
778 EXPECT_EQ(31U, input_consumed);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600779
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700780 string signature;
781 ASSERT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&signature));
782 EXPECT_EQ(0U, signature.length());
Shawn Willden43e999e2014-08-13 13:29:50 -0600783}
784
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700785typedef KeymasterTest VerificationOperationsTest;
Shawn Willden43e999e2014-08-13 13:29:50 -0600786TEST_F(VerificationOperationsTest, RsaSuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700787 GenerateKey(ParamBuilder().RsaSigningKey(256));
788 string message = "12345678901234567890123456789012";
789 string signature;
790 SignMessage(message, &signature);
791 VerifyMessage(message, signature);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600792}
793
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600794TEST_F(VerificationOperationsTest, EcdsaSuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700795 GenerateKey(ParamBuilder().EcdsaSigningKey(256));
796 string message = "123456789012345678901234567890123456789012345678";
797 string signature;
798 SignMessage(message, &signature);
799 VerifyMessage(message, signature);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600800}
801
Shawn Willden0d560bf2014-12-15 17:44:02 -0700802TEST_F(VerificationOperationsTest, HmacSha256Success) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700803 GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_256, 16));
804 string message = "123456789012345678901234567890123456789012345678";
Shawn Willden0d560bf2014-12-15 17:44:02 -0700805 string signature;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700806 SignMessage(message, &signature);
807 VerifyMessage(message, signature);
Shawn Willden0d560bf2014-12-15 17:44:02 -0700808}
809
Shawn Willden5b53c992015-02-02 08:05:25 -0700810typedef VerificationOperationsTest ExportKeyTest;
Shawn Willdenffd790c2014-08-18 21:20:06 -0600811TEST_F(ExportKeyTest, RsaSuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700812 GenerateKey(ParamBuilder().RsaSigningKey(256));
813 string export_data;
814 ASSERT_EQ(KM_ERROR_OK, ExportKey(KM_KEY_FORMAT_X509, &export_data));
815 EXPECT_GT(export_data.length(), 0);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600816
817 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willdenffd790c2014-08-18 21:20:06 -0600818}
819
Shawn Willdenf268d742014-08-19 15:36:26 -0600820TEST_F(ExportKeyTest, EcdsaSuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700821 GenerateKey(ParamBuilder().EcdsaSigningKey(224));
822 string export_data;
823 ASSERT_EQ(KM_ERROR_OK, ExportKey(KM_KEY_FORMAT_X509, &export_data));
824 EXPECT_GT(export_data.length(), 0);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600825
826 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willdenf268d742014-08-19 15:36:26 -0600827}
828
829TEST_F(ExportKeyTest, RsaUnsupportedKeyFormat) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700830 GenerateKey(ParamBuilder().RsaSigningKey(256));
831 string export_data;
832 ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_FORMAT, ExportKey(KM_KEY_FORMAT_PKCS8, &export_data));
Shawn Willdenf268d742014-08-19 15:36:26 -0600833}
834
835TEST_F(ExportKeyTest, RsaCorruptedKeyBlob) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700836 GenerateKey(ParamBuilder().RsaSigningKey(256));
Shawn Willden5b53c992015-02-02 08:05:25 -0700837 corrupt_key_blob();
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700838 string export_data;
839 ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, ExportKey(KM_KEY_FORMAT_X509, &export_data));
Shawn Willdenf268d742014-08-19 15:36:26 -0600840}
841
Shawn Willden437fbd12014-08-20 11:59:49 -0600842static string read_file(const string& file_name) {
843 ifstream file_stream(file_name, std::ios::binary);
844 istreambuf_iterator<char> file_begin(file_stream);
845 istreambuf_iterator<char> file_end;
846 return string(file_begin, file_end);
847}
848
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700849typedef VerificationOperationsTest ImportKeyTest;
Shawn Willden5b53c992015-02-02 08:05:25 -0700850TEST_F(ImportKeyTest, RsaSuccess) {
Shawn Willden81effc62014-08-27 10:08:46 -0600851 string pk8_key = read_file("rsa_privkey_pk8.der");
Shawn Willden437fbd12014-08-20 11:59:49 -0600852 ASSERT_EQ(633U, pk8_key.size());
853
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700854 ImportKey(ParamBuilder().SigningKey().NoDigestOrPadding(), KM_KEY_FORMAT_PKCS8, pk8_key);
Shawn Willden437fbd12014-08-20 11:59:49 -0600855
856 // Check values derived from the key.
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700857 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_RSA));
858 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 1024));
859 EXPECT_TRUE(contains(sw_enforced(), TAG_RSA_PUBLIC_EXPONENT, 65537U));
Shawn Willden437fbd12014-08-20 11:59:49 -0600860
861 // And values provided by GoogleKeymaster
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700862 EXPECT_TRUE(contains(sw_enforced(), TAG_ORIGIN, KM_ORIGIN_IMPORTED));
863 EXPECT_TRUE(contains(sw_enforced(), KM_TAG_CREATION_DATETIME));
Shawn Willden437fbd12014-08-20 11:59:49 -0600864
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700865 string message(1024 / 8, 'a');
866 string signature;
867 SignMessage(message, &signature);
868 VerifyMessage(message, signature);
Shawn Willden437fbd12014-08-20 11:59:49 -0600869}
870
Shawn Willden6bbe6782014-09-18 11:26:15 -0600871TEST_F(ImportKeyTest, RsaKeySizeMismatch) {
Shawn Willden6bbe6782014-09-18 11:26:15 -0600872 string pk8_key = read_file("rsa_privkey_pk8.der");
873 ASSERT_EQ(633U, pk8_key.size());
Shawn Willden5b53c992015-02-02 08:05:25 -0700874 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700875 AttemptImportKey(ParamBuilder()
876 .SigningKey()
877 .Option(TAG_KEY_SIZE, 2048) // Doesn't match key
878 .NoDigestOrPadding(),
879 KM_KEY_FORMAT_PKCS8, pk8_key));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600880}
881
882TEST_F(ImportKeyTest, RsaPublicExponenMismatch) {
Shawn Willden6bbe6782014-09-18 11:26:15 -0600883 string pk8_key = read_file("rsa_privkey_pk8.der");
884 ASSERT_EQ(633U, pk8_key.size());
Shawn Willden5b53c992015-02-02 08:05:25 -0700885 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700886 AttemptImportKey(ParamBuilder()
887 .SigningKey()
888 .Option(TAG_RSA_PUBLIC_EXPONENT, 3) // Doesn't match key
889 .NoDigestOrPadding(),
890 KM_KEY_FORMAT_PKCS8, pk8_key));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600891}
892
Shawn Willden81effc62014-08-27 10:08:46 -0600893TEST_F(ImportKeyTest, EcdsaSuccess) {
Shawn Willden81effc62014-08-27 10:08:46 -0600894 string pk8_key = read_file("ec_privkey_pk8.der");
895 ASSERT_EQ(138U, pk8_key.size());
896
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700897 ImportKey(ParamBuilder().SigningKey(), KM_KEY_FORMAT_PKCS8, pk8_key);
Shawn Willden81effc62014-08-27 10:08:46 -0600898
899 // Check values derived from the key.
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700900 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
901 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 256));
Shawn Willden81effc62014-08-27 10:08:46 -0600902
903 // And values provided by GoogleKeymaster
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700904 EXPECT_TRUE(contains(sw_enforced(), TAG_ORIGIN, KM_ORIGIN_IMPORTED));
905 EXPECT_TRUE(contains(sw_enforced(), KM_TAG_CREATION_DATETIME));
Shawn Willden81effc62014-08-27 10:08:46 -0600906
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700907 string message(1024 / 8, 'a');
908 string signature;
909 SignMessage(message, &signature);
910 VerifyMessage(message, signature);
Shawn Willden81effc62014-08-27 10:08:46 -0600911}
912
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700913TEST_F(ImportKeyTest, EcdsaSizeSpecified) {
914 string pk8_key = read_file("ec_privkey_pk8.der");
915 ASSERT_EQ(138U, pk8_key.size());
Shawn Willden6bbe6782014-09-18 11:26:15 -0600916
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700917 ImportKey(ParamBuilder().SigningKey().Option(TAG_KEY_SIZE, 256), KM_KEY_FORMAT_PKCS8, pk8_key);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600918
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700919 // Check values derived from the key.
920 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
921 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 256));
922
923 // And values provided by GoogleKeymaster
924 EXPECT_TRUE(contains(sw_enforced(), TAG_ORIGIN, KM_ORIGIN_IMPORTED));
925 EXPECT_TRUE(contains(sw_enforced(), KM_TAG_CREATION_DATETIME));
926
927 string message(1024 / 8, 'a');
928 string signature;
929 SignMessage(message, &signature);
930 VerifyMessage(message, signature);
931}
932
933TEST_F(ImportKeyTest, EcdsaSizeMismatch) {
934 string pk8_key = read_file("ec_privkey_pk8.der");
935 ASSERT_EQ(138U, pk8_key.size());
Shawn Willden5b53c992015-02-02 08:05:25 -0700936 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700937 AttemptImportKey(ParamBuilder().SigningKey().Option(TAG_KEY_SIZE, 224),
938 KM_KEY_FORMAT_PKCS8, pk8_key));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600939}
940
Shawn Willden2665e862014-11-24 14:46:21 -0700941typedef KeymasterTest VersionTest;
942TEST_F(VersionTest, GetVersion) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700943 uint8_t major, minor, subminor;
944 ASSERT_EQ(KM_ERROR_OK, GetVersion(&major, &minor, &subminor));
945 EXPECT_EQ(1, major);
946 EXPECT_EQ(0, minor);
947 EXPECT_EQ(0, subminor);
Shawn Willden2665e862014-11-24 14:46:21 -0700948}
949
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700950typedef KeymasterTest EncryptionOperationsTest;
Shawn Willden4200f212014-12-02 07:01:21 -0700951TEST_F(EncryptionOperationsTest, RsaOaepSuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700952 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_OAEP));
953
954 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -0700955 string ciphertext1 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -0700956 EXPECT_EQ(512 / 8, ciphertext1.size());
957
Shawn Willden6dde87c2014-12-11 14:08:48 -0700958 string ciphertext2 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -0700959 EXPECT_EQ(512 / 8, ciphertext2.size());
960
961 // OAEP randomizes padding so every result should be different.
962 EXPECT_NE(ciphertext1, ciphertext2);
963}
964
965TEST_F(EncryptionOperationsTest, RsaOaepRoundTrip) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700966 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_OAEP));
967 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -0700968 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -0700969 EXPECT_EQ(512 / 8, ciphertext.size());
970
Shawn Willden6dde87c2014-12-11 14:08:48 -0700971 string plaintext = DecryptMessage(ciphertext);
Shawn Willden4200f212014-12-02 07:01:21 -0700972 EXPECT_EQ(message, plaintext);
973}
974
975TEST_F(EncryptionOperationsTest, RsaOaepTooLarge) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700976 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_OAEP));
977 string message = "12345678901234567890123";
Shawn Willden4200f212014-12-02 07:01:21 -0700978 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -0700979 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -0700980
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700981 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT));
982 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700983 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -0700984 EXPECT_EQ(0, result.size());
985}
986
987TEST_F(EncryptionOperationsTest, RsaOaepCorruptedDecrypt) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700988 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_OAEP));
989 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -0700990 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -0700991 EXPECT_EQ(512 / 8, ciphertext.size());
992
993 // Corrupt the ciphertext
994 ciphertext[512 / 8 / 2]++;
995
Shawn Willden4200f212014-12-02 07:01:21 -0700996 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -0700997 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700998 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
999 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001000 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -07001001 EXPECT_EQ(0, result.size());
1002}
1003
1004TEST_F(EncryptionOperationsTest, RsaPkcs1Success) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001005 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_PKCS1_1_5_ENCRYPT));
1006 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001007 string ciphertext1 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001008 EXPECT_EQ(512 / 8, ciphertext1.size());
1009
Shawn Willden6dde87c2014-12-11 14:08:48 -07001010 string ciphertext2 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001011 EXPECT_EQ(512 / 8, ciphertext2.size());
1012
1013 // PKCS1 v1.5 randomizes padding so every result should be different.
1014 EXPECT_NE(ciphertext1, ciphertext2);
1015}
1016
1017TEST_F(EncryptionOperationsTest, RsaPkcs1RoundTrip) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001018 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_PKCS1_1_5_ENCRYPT));
1019 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001020 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001021 EXPECT_EQ(512 / 8, ciphertext.size());
1022
Shawn Willden6dde87c2014-12-11 14:08:48 -07001023 string plaintext = DecryptMessage(ciphertext);
Shawn Willden4200f212014-12-02 07:01:21 -07001024 EXPECT_EQ(message, plaintext);
1025}
1026
1027TEST_F(EncryptionOperationsTest, RsaPkcs1TooLarge) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001028 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_PKCS1_1_5_ENCRYPT));
1029 string message = "12345678901234567890123456789012345678901234567890123";
Shawn Willden4200f212014-12-02 07:01:21 -07001030 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001031 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001032
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001033 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT));
1034 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001035 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -07001036 EXPECT_EQ(0, result.size());
1037}
1038
1039TEST_F(EncryptionOperationsTest, RsaPkcs1CorruptedDecrypt) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001040 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_PKCS1_1_5_ENCRYPT));
1041 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001042 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001043 EXPECT_EQ(512 / 8, ciphertext.size());
1044
1045 // Corrupt the ciphertext
1046 ciphertext[512 / 8 / 2]++;
1047
Shawn Willden4200f212014-12-02 07:01:21 -07001048 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001049 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001050 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
1051 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001052 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -07001053 EXPECT_EQ(0, result.size());
1054}
1055
Shawn Willden907c3012014-12-08 15:51:55 -07001056TEST_F(EncryptionOperationsTest, AesOcbSuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001057 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
1058 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001059 string ciphertext1 = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001060 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext1.size());
Shawn Willden907c3012014-12-08 15:51:55 -07001061
Shawn Willden6dde87c2014-12-11 14:08:48 -07001062 string ciphertext2 = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001063 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext2.size());
Shawn Willden907c3012014-12-08 15:51:55 -07001064
1065 // OCB uses a random nonce, so every output should be different
1066 EXPECT_NE(ciphertext1, ciphertext2);
1067}
1068
Shawn Willden6dde87c2014-12-11 14:08:48 -07001069TEST_F(EncryptionOperationsTest, AesOcbRoundTripSuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001070 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001071 string message = "Hello World!";
1072 string ciphertext = EncryptMessage(message);
1073 EXPECT_EQ(12 /* nonce */ + message.length() + 16 /* tag */, ciphertext.size());
1074
1075 string plaintext = DecryptMessage(ciphertext);
1076 EXPECT_EQ(message, plaintext);
1077}
1078
1079TEST_F(EncryptionOperationsTest, AesOcbRoundTripCorrupted) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001080 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
1081 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001082 string ciphertext = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001083 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext.size());
Shawn Willden6dde87c2014-12-11 14:08:48 -07001084
1085 ciphertext[ciphertext.size() / 2]++;
1086
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001087 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001088
1089 string result;
1090 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001091 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001092 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001093 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001094}
1095
1096TEST_F(EncryptionOperationsTest, AesDecryptGarbage) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001097 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001098 string ciphertext(128, 'a');
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001099 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001100
1101 string result;
1102 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001103 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001104 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001105 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001106}
1107
1108TEST_F(EncryptionOperationsTest, AesDecryptTooShort) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001109 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
1110
Shawn Willden6dde87c2014-12-11 14:08:48 -07001111 // Try decrypting garbage ciphertext that is too short to be valid (< nonce + tag).
Shawn Willden6dde87c2014-12-11 14:08:48 -07001112 string ciphertext(12 + 15, 'a');
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001113 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001114
1115 string result;
1116 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001117 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001118 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001119 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001120}
1121
1122TEST_F(EncryptionOperationsTest, AesOcbRoundTripEmptySuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001123 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
1124 string message = "";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001125 string ciphertext = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001126 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext.size());
Shawn Willden6dde87c2014-12-11 14:08:48 -07001127
1128 string plaintext = DecryptMessage(ciphertext);
1129 EXPECT_EQ(message, plaintext);
1130}
1131
1132TEST_F(EncryptionOperationsTest, AesOcbRoundTripEmptyCorrupted) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001133 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
1134 string message = "";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001135 string ciphertext = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001136 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext.size());
Shawn Willden6dde87c2014-12-11 14:08:48 -07001137
1138 ciphertext[ciphertext.size() / 2]++;
1139
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001140 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001141
1142 string result;
1143 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001144 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001145 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001146 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001147}
1148
1149TEST_F(EncryptionOperationsTest, AesOcbFullChunk) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001150 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001151 string message(4096, 'a');
1152 string ciphertext = EncryptMessage(message);
1153 EXPECT_EQ(12 /* nonce */ + message.length() + 16 /* tag */, ciphertext.size());
1154
1155 string plaintext = DecryptMessage(ciphertext);
1156 EXPECT_EQ(message, plaintext);
1157}
1158
1159TEST_F(EncryptionOperationsTest, AesOcbVariousChunkLengths) {
1160 for (unsigned chunk_length = 1; chunk_length <= 128; ++chunk_length) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001161 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(chunk_length, 16));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001162 string message(128, 'a');
1163 string ciphertext = EncryptMessage(message);
1164 int expected_tag_count = (message.length() + chunk_length - 1) / chunk_length;
1165 EXPECT_EQ(12 /* nonce */ + message.length() + 16 * expected_tag_count, ciphertext.size())
1166 << "Unexpected ciphertext size for chunk length " << chunk_length
1167 << " expected tag count was " << expected_tag_count
1168 << " but actual tag count was probably "
1169 << (ciphertext.size() - message.length() - 12) / 16;
1170
1171 string plaintext = DecryptMessage(ciphertext);
1172 EXPECT_EQ(message, plaintext);
1173 }
1174}
1175
1176TEST_F(EncryptionOperationsTest, AesOcbAbort) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001177 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
1178 string message = "Hello";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001179
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001180 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001181
1182 string result;
1183 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001184 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
1185 EXPECT_EQ(message.length(), input_consumed);
1186 EXPECT_EQ(KM_ERROR_OK, AbortOperation());
Shawn Willden6dde87c2014-12-11 14:08:48 -07001187}
1188
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001189TEST_F(EncryptionOperationsTest, AesOcbNoChunkLength) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001190 GenerateKey(ParamBuilder()
1191 .AesEncryptionKey(128)
1192 .Option(TAG_BLOCK_MODE, KM_MODE_OCB)
1193 .Option(TAG_MAC_LENGTH, 16));
1194 EXPECT_EQ(KM_ERROR_INVALID_ARGUMENT, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001195}
1196
1197TEST_F(EncryptionOperationsTest, AesEcbUnsupported) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001198 GenerateKey(ParamBuilder().AesEncryptionKey(128).Option(TAG_BLOCK_MODE, KM_MODE_ECB));
1199 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001200}
1201
1202TEST_F(EncryptionOperationsTest, AesOcbPaddingUnsupported) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001203 GenerateKey(
1204 ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16).Option(TAG_PADDING, KM_PAD_ZERO));
1205 EXPECT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001206}
1207
1208TEST_F(EncryptionOperationsTest, AesOcbInvalidMacLength) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001209 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 17));
1210 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001211}
1212
Shawn Willden128ffe02014-08-06 12:31:33 -06001213} // namespace test
1214} // namespace keymaster