blob: 2e60fbd7c2a58514c4eacd993d944bd76322d29e [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 Willden76076ab2014-12-18 08:36:35 -070017#include <algorithm>
Shawn Willden437fbd12014-08-20 11:59:49 -060018#include <fstream>
Shawn Willden76076ab2014-12-18 08:36:35 -070019#include <string>
20#include <vector>
Shawn Willden437fbd12014-08-20 11:59:49 -060021
Shawn Willden128ffe02014-08-06 12:31:33 -060022#include <gtest/gtest.h>
Shawn Willden76364712014-08-11 17:48:04 -060023
Shawn Willden128ffe02014-08-06 12:31:33 -060024#include <openssl/engine.h>
25
Shawn Willden98d9b922014-08-26 08:14:10 -060026#include <keymaster/google_keymaster_utils.h>
27#include <keymaster/keymaster_tags.h>
Shawn Willdenb7510332015-02-06 19:58:29 -070028#include <keymaster/soft_keymaster_device.h>
Shawn Willden98d9b922014-08-26 08:14:10 -060029
Shawn Willden76364712014-08-11 17:48:04 -060030#include "google_keymaster_test_utils.h"
Shawn Willden128ffe02014-08-06 12:31:33 -060031
Shawn Willden437fbd12014-08-20 11:59:49 -060032using std::ifstream;
33using std::istreambuf_iterator;
Shawn Willden76076ab2014-12-18 08:36:35 -070034using std::string;
35using std::vector;
Shawn Willden437fbd12014-08-20 11:59:49 -060036
Shawn Willden128ffe02014-08-06 12:31:33 -060037int main(int argc, char** argv) {
38 ::testing::InitGoogleTest(&argc, argv);
39 int result = RUN_ALL_TESTS();
40 // Clean up stuff OpenSSL leaves around, so Valgrind doesn't complain.
41 CRYPTO_cleanup_all_ex_data();
Shawn Willden7c0a82b2014-09-17 12:57:32 -060042 ERR_remove_thread_state(NULL);
Shawn Willden128ffe02014-08-06 12:31:33 -060043 ERR_free_strings();
44 return result;
45}
46
47namespace keymaster {
48namespace test {
49
Shawn Willdenb15d77e2014-12-17 16:44:29 -070050/**
51 * Utility class to make construction of AuthorizationSets easy, and readable. Use like:
52 *
53 * ParamBuilder()
54 * .Option(TAG_ALGORITHM, KM_ALGORITHM_RSA)
55 * .Option(TAG_KEY_SIZE, 512)
56 * .Option(TAG_DIGEST, KM_DIGEST_NONE)
57 * .Option(TAG_PADDING, KM_PAD_NONE)
58 * .Option(TAG_SINGLE_USE_PER_BOOT, true)
59 * .build();
60 *
61 * In addition there are methods that add common sets of parameters, like RsaSigningKey().
62 */
63class ParamBuilder {
64 public:
65 template <typename TagType, typename ValueType>
66 ParamBuilder& Option(TagType tag, ValueType value) {
67 set.push_back(tag, value);
68 return *this;
69 }
70
71 ParamBuilder& RsaKey(uint32_t key_size = 0, uint64_t public_exponent = 0) {
72 Option(TAG_ALGORITHM, KM_ALGORITHM_RSA);
73 if (key_size != 0)
74 Option(TAG_KEY_SIZE, key_size);
75 if (public_exponent != 0)
76 Option(TAG_RSA_PUBLIC_EXPONENT, public_exponent);
77 return *this;
78 }
79
80 ParamBuilder& EcdsaKey(uint32_t key_size = 0) {
81 Option(TAG_ALGORITHM, KM_ALGORITHM_ECDSA);
82 if (key_size != 0)
83 Option(TAG_KEY_SIZE, key_size);
84 return *this;
85 }
86
87 ParamBuilder& AesKey(uint32_t key_size) {
88 Option(TAG_ALGORITHM, KM_ALGORITHM_AES);
89 return Option(TAG_KEY_SIZE, key_size);
90 }
91
92 ParamBuilder& HmacKey(uint32_t key_size, keymaster_digest_t digest, uint32_t mac_length) {
93 Option(TAG_ALGORITHM, KM_ALGORITHM_HMAC);
94 Option(TAG_KEY_SIZE, key_size);
95 SigningKey();
96 Option(TAG_DIGEST, digest);
97 return Option(TAG_MAC_LENGTH, mac_length);
98 }
99
100 ParamBuilder& RsaSigningKey(uint32_t key_size = 0, keymaster_digest_t digest = KM_DIGEST_NONE,
101 keymaster_padding_t padding = KM_PAD_NONE,
102 uint64_t public_exponent = 0) {
103 RsaKey(key_size, public_exponent);
104 SigningKey();
105 Option(TAG_DIGEST, digest);
106 return Option(TAG_PADDING, padding);
107 }
108
109 ParamBuilder& RsaEncryptionKey(uint32_t key_size = 0,
110 keymaster_padding_t padding = KM_PAD_RSA_OAEP,
111 uint64_t public_exponent = 0) {
112 RsaKey(key_size, public_exponent);
113 EncryptionKey();
114 return Option(TAG_PADDING, padding);
115 }
116
117 ParamBuilder& EcdsaSigningKey(uint32_t key_size = 0) {
118 EcdsaKey(key_size);
119 return SigningKey();
120 }
121
122 ParamBuilder& AesEncryptionKey(uint32_t key_size) {
123 AesKey(key_size);
124 return EncryptionKey();
125 }
126
127 ParamBuilder& SigningKey() {
128 Option(TAG_PURPOSE, KM_PURPOSE_SIGN);
129 return Option(TAG_PURPOSE, KM_PURPOSE_VERIFY);
130 }
131
132 ParamBuilder& EncryptionKey() {
133 Option(TAG_PURPOSE, KM_PURPOSE_ENCRYPT);
134 return Option(TAG_PURPOSE, KM_PURPOSE_DECRYPT);
135 }
136
137 ParamBuilder& NoDigestOrPadding() {
138 Option(TAG_DIGEST, KM_DIGEST_NONE);
139 return Option(TAG_PADDING, KM_PAD_NONE);
140 }
141
142 ParamBuilder& OcbMode(uint32_t chunk_length, uint32_t mac_length) {
143 Option(TAG_BLOCK_MODE, KM_MODE_OCB);
144 Option(TAG_CHUNK_LENGTH, chunk_length);
145 return Option(TAG_MAC_LENGTH, mac_length);
146 }
147
148 AuthorizationSet build() const { return set; }
149
150 private:
151 AuthorizationSet set;
Shawn Willden6bbe6782014-09-18 11:26:15 -0600152};
153
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700154const uint64_t OP_HANDLE_SENTINEL = 0xFFFFFFFFFFFFFFFF;
Shawn Willden128ffe02014-08-06 12:31:33 -0600155class KeymasterTest : public testing::Test {
156 protected:
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700157 KeymasterTest()
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700158 : device_(new StdoutLogger), out_params_(NULL), op_handle_(OP_HANDLE_SENTINEL),
159 characteristics_(NULL) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700160 blob_.key_material = NULL;
161 RAND_seed("foobar", 6);
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700162 blob_.key_material = 0;
Shawn Willden5b53c992015-02-02 08:05:25 -0700163 }
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700164
Shawn Willden5b53c992015-02-02 08:05:25 -0700165 ~KeymasterTest() {
166 FreeCharacteristics();
167 FreeKeyBlob();
Shawn Willdend0772312014-09-18 12:27:57 -0600168 }
169
Shawn Willden5b53c992015-02-02 08:05:25 -0700170 keymaster_device* device() { return reinterpret_cast<keymaster_device*>(device_.hw_device()); }
171
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700172 keymaster_error_t AttemptToGenerateKey(const ParamBuilder& builder) {
173 AuthorizationSet params(builder.build());
174 params.push_back(UserAuthParams());
175 params.push_back(ClientParams());
176
Shawn Willden0d560bf2014-12-15 17:44:02 -0700177 FreeKeyBlob();
178 FreeCharacteristics();
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700179 return device()->generate_key(device(), params.data(), params.size(), &blob_,
180 &characteristics_);
Shawn Willden0d560bf2014-12-15 17:44:02 -0700181 }
182
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700183 void GenerateKey(const ParamBuilder& builder) {
184 ASSERT_EQ(KM_ERROR_OK, AttemptToGenerateKey(builder));
185 }
186
187 keymaster_error_t AttemptImportKey(const ParamBuilder& builder, keymaster_key_format_t format,
188 const string& key_material) {
189 AuthorizationSet params(builder.build());
190 params.push_back(UserAuthParams());
191 params.push_back(ClientParams());
192
193 FreeKeyBlob();
194 FreeCharacteristics();
195 return device()->import_key(device(), params.data(), params.size(), format,
196 reinterpret_cast<const uint8_t*>(key_material.c_str()),
197 key_material.length(), &blob_, &characteristics_);
198 }
199
200 void ImportKey(const ParamBuilder& builder, keymaster_key_format_t format,
201 const string& key_material) {
202 ASSERT_EQ(KM_ERROR_OK, AttemptImportKey(builder, format, key_material));
203 }
204
205 AuthorizationSet UserAuthParams() {
206 AuthorizationSet set;
207 set.push_back(TAG_USER_ID, 7);
208 set.push_back(TAG_USER_AUTH_ID, 8);
209 set.push_back(TAG_AUTH_TIMEOUT, 300);
210 return set;
211 }
212
213 AuthorizationSet ClientParams() {
214 AuthorizationSet set;
215 set.push_back(TAG_APPLICATION_ID, "app_id", 6);
216 return set;
217 }
218
219 keymaster_error_t BeginOperation(keymaster_purpose_t purpose) {
220 return device()->begin(device(), purpose, &blob_, client_params_,
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700221 array_length(client_params_), &out_params_, &out_params_count_,
222 &op_handle_);
223 }
224
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700225 keymaster_error_t UpdateOperation(const string& message, string* output,
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700226 size_t* input_consumed) {
227 uint8_t* out_tmp = NULL;
228 size_t out_length;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700229 EXPECT_NE(op_handle_, OP_HANDLE_SENTINEL);
230 keymaster_error_t error = device()->update(
231 device(), op_handle_, reinterpret_cast<const uint8_t*>(message.c_str()),
232 message.length(), input_consumed, &out_tmp, &out_length);
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700233 if (out_tmp)
234 output->append(reinterpret_cast<char*>(out_tmp), out_length);
235 free(out_tmp);
236 return error;
237 }
238
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700239 keymaster_error_t FinishOperation(string* output) { return FinishOperation("", output); }
240
241 keymaster_error_t FinishOperation(const string& signature, string* output) {
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700242 uint8_t* out_tmp = NULL;
243 size_t out_length;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700244 keymaster_error_t error = device()->finish(
245 device(), op_handle_, reinterpret_cast<const uint8_t*>(signature.c_str()),
246 signature.length(), &out_tmp, &out_length);
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700247 if (out_tmp)
248 output->append(reinterpret_cast<char*>(out_tmp), out_length);
249 free(out_tmp);
250 return error;
251 }
252
Shawn Willden76076ab2014-12-18 08:36:35 -0700253 template <typename T>
254 bool ResponseContains(const vector<T>& expected, const T* values, size_t len) {
255 return std::is_permutation(values, values + len, expected.begin());
256 }
257
258 template <typename T> bool ResponseContains(T expected, const T* values, size_t len) {
259 return (len == 1 && *values == expected);
Shawn Willdend0772312014-09-18 12:27:57 -0600260 }
261
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700262 keymaster_error_t AbortOperation() { return device()->abort(device(), op_handle_); }
263
264 string ProcessMessage(keymaster_purpose_t purpose, const string& message) {
265 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose));
266
267 string result;
268 size_t input_consumed;
269 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
270 EXPECT_EQ(message.size(), input_consumed);
271 EXPECT_EQ(KM_ERROR_OK, FinishOperation(&result));
272 return result;
273 }
274
275 string ProcessMessage(keymaster_purpose_t purpose, const string& message,
276 const string& signature) {
277 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose));
278
279 string result;
280 size_t input_consumed;
281 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
282 EXPECT_EQ(message.size(), input_consumed);
283 EXPECT_EQ(KM_ERROR_OK, FinishOperation(signature, &result));
284 return result;
285 }
286
287 void SignMessage(const string& message, string* signature) {
288 *signature = ProcessMessage(KM_PURPOSE_SIGN, message);
289 EXPECT_GT(signature->size(), 0);
290 }
291
292 void VerifyMessage(const string& message, const string& signature) {
293 ProcessMessage(KM_PURPOSE_VERIFY, message, signature);
294 }
295
296 string EncryptMessage(const string& message) {
297 return ProcessMessage(KM_PURPOSE_ENCRYPT, message);
298 }
299
300 string DecryptMessage(const string& ciphertext) {
301 return ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext);
302 }
303
304 keymaster_error_t GetCharacteristics() {
305 FreeCharacteristics();
306 return device()->get_key_characteristics(device(), &blob_, &client_id_, NULL /* app_data */,
307 &characteristics_);
308 }
309
310 keymaster_error_t ExportKey(keymaster_key_format_t format, string* export_data) {
311 uint8_t* export_data_tmp;
312 size_t export_data_length;
313
314 keymaster_error_t error =
315 device()->export_key(device(), format, &blob_, &client_id_, NULL /* app_data */,
316 &export_data_tmp, &export_data_length);
317
318 if (error != KM_ERROR_OK)
319 return error;
320
321 *export_data = string(reinterpret_cast<char*>(export_data_tmp), export_data_length);
322 free(export_data_tmp);
323 return error;
324 }
325
326 keymaster_error_t GetVersion(uint8_t* major, uint8_t* minor, uint8_t* subminor) {
327 GetVersionRequest request;
328 GetVersionResponse response;
329 device_.GetVersion(request, &response);
330 if (response.error != KM_ERROR_OK)
331 return response.error;
332 *major = response.major_ver;
333 *minor = response.minor_ver;
334 *subminor = response.subminor_ver;
335 return response.error;
336 }
337
338 AuthorizationSet hw_enforced() {
339 EXPECT_TRUE(characteristics_ != NULL);
340 return AuthorizationSet(characteristics_->hw_enforced);
341 }
342
343 AuthorizationSet sw_enforced() {
344 EXPECT_TRUE(characteristics_ != NULL);
345 return AuthorizationSet(characteristics_->sw_enforced);
346 }
347
Shawn Willden5b53c992015-02-02 08:05:25 -0700348 void FreeCharacteristics() {
349 keymaster_free_characteristics(characteristics_);
350 free(characteristics_);
351 characteristics_ = NULL;
352 }
353
354 void FreeKeyBlob() {
355 free(const_cast<uint8_t*>(blob_.key_material));
356 blob_.key_material = NULL;
357 }
358
Shawn Willden6dde87c2014-12-11 14:08:48 -0700359 const keymaster_key_blob_t& key_blob() { return blob_; }
360
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700361 void corrupt_key_blob() {
362 assert(blob_.key_material);
363 uint8_t* tmp = const_cast<uint8_t*>(blob_.key_material);
364 ++tmp[blob_.key_material_size / 2];
365 }
Shawn Willden5b53c992015-02-02 08:05:25 -0700366
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700367 private:
368 SoftKeymasterDevice device_;
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700369 keymaster_blob_t client_id_ = {.data = reinterpret_cast<const uint8_t*>("app_id"),
370 .data_length = 6};
371 keymaster_key_param_t client_params_[1] = {
372 Authorization(TAG_APPLICATION_ID, client_id_.data, client_id_.data_length)};
373
374 keymaster_key_param_t* out_params_;
375 size_t out_params_count_;
376 uint64_t op_handle_;
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700377
Shawn Willden5b53c992015-02-02 08:05:25 -0700378 keymaster_key_blob_t blob_;
379 keymaster_key_characteristics_t* characteristics_;
Shawn Willden128ffe02014-08-06 12:31:33 -0600380};
381
Shawn Willden128ffe02014-08-06 12:31:33 -0600382typedef KeymasterTest CheckSupported;
383TEST_F(CheckSupported, SupportedAlgorithms) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700384 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
385 device()->get_supported_algorithms(device(), NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600386
Shawn Willden5b53c992015-02-02 08:05:25 -0700387 size_t len;
388 keymaster_algorithm_t* algorithms;
389 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_algorithms(device(), &algorithms, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700390 EXPECT_TRUE(ResponseContains({KM_ALGORITHM_RSA, KM_ALGORITHM_ECDSA, KM_ALGORITHM_AES},
391 algorithms, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700392 free(algorithms);
Shawn Willden128ffe02014-08-06 12:31:33 -0600393}
394
395TEST_F(CheckSupported, SupportedBlockModes) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700396 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
397 device()->get_supported_block_modes(device(), KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT,
398 NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600399
Shawn Willden5b53c992015-02-02 08:05:25 -0700400 size_t len;
401 keymaster_block_mode_t* modes;
402 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE,
403 device()->get_supported_block_modes(device(), KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT,
404 &modes, &len));
Shawn Willden128ffe02014-08-06 12:31:33 -0600405
Shawn Willden76076ab2014-12-18 08:36:35 -0700406 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM,
Shawn Willden5b53c992015-02-02 08:05:25 -0700407 device()->get_supported_block_modes(device(), KM_ALGORITHM_DSA, KM_PURPOSE_ENCRYPT,
408 &modes, &len));
Shawn Willden28e41472014-08-18 13:35:22 -0600409
Shawn Willden5b53c992015-02-02 08:05:25 -0700410 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE,
411 device()->get_supported_block_modes(device(), KM_ALGORITHM_ECDSA, KM_PURPOSE_ENCRYPT,
412 &modes, &len));
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600413
Shawn Willden5b53c992015-02-02 08:05:25 -0700414 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE,
415 device()->get_supported_block_modes(device(), KM_ALGORITHM_AES, KM_PURPOSE_ENCRYPT,
416 &modes, &len));
Shawn Willden128ffe02014-08-06 12:31:33 -0600417}
418
419TEST_F(CheckSupported, SupportedPaddingModes) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700420 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
421 device()->get_supported_padding_modes(device(), KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT,
422 NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600423
Shawn Willden5b53c992015-02-02 08:05:25 -0700424 size_t len;
425 keymaster_padding_t* modes;
426 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_RSA,
427 KM_PURPOSE_SIGN, &modes, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700428 EXPECT_TRUE(ResponseContains(KM_PAD_NONE, modes, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700429 free(modes);
Shawn Willden128ffe02014-08-06 12:31:33 -0600430
Shawn Willden76076ab2014-12-18 08:36:35 -0700431 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM,
432 device()->get_supported_padding_modes(device(), KM_ALGORITHM_DSA, KM_PURPOSE_SIGN,
433 &modes, &len));
Shawn Willden28e41472014-08-18 13:35:22 -0600434
Shawn Willden5b53c992015-02-02 08:05:25 -0700435 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_ECDSA,
436 KM_PURPOSE_SIGN, &modes, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700437 EXPECT_TRUE(ResponseContains(KM_PAD_NONE, modes, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700438 free(modes);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600439
Shawn Willden5b53c992015-02-02 08:05:25 -0700440 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_AES,
441 KM_PURPOSE_SIGN, &modes, &len));
442 EXPECT_EQ(0, len);
443 free(modes);
Shawn Willden128ffe02014-08-06 12:31:33 -0600444}
445
446TEST_F(CheckSupported, SupportedDigests) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700447 EXPECT_EQ(
448 KM_ERROR_OUTPUT_PARAMETER_NULL,
449 device()->get_supported_digests(device(), KM_ALGORITHM_RSA, KM_PURPOSE_SIGN, NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600450
Shawn Willden5b53c992015-02-02 08:05:25 -0700451 size_t len;
452 keymaster_digest_t* digests;
453 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_RSA,
454 KM_PURPOSE_SIGN, &digests, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700455 EXPECT_TRUE(ResponseContains(KM_DIGEST_NONE, digests, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700456 free(digests);
Shawn Willden128ffe02014-08-06 12:31:33 -0600457
Shawn Willden76076ab2014-12-18 08:36:35 -0700458 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM,
459 device()->get_supported_digests(device(), KM_ALGORITHM_DSA, KM_PURPOSE_SIGN, &digests,
460 &len));
Shawn Willden28e41472014-08-18 13:35:22 -0600461
Shawn Willden5b53c992015-02-02 08:05:25 -0700462 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_ECDSA,
463 KM_PURPOSE_SIGN, &digests, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700464 EXPECT_TRUE(ResponseContains(KM_DIGEST_NONE, digests, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700465 free(digests);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600466
Shawn Willden5b53c992015-02-02 08:05:25 -0700467 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_AES,
468 KM_PURPOSE_SIGN, &digests, &len));
469 EXPECT_EQ(0, len);
470 free(digests);
Shawn Willden128ffe02014-08-06 12:31:33 -0600471}
472
473TEST_F(CheckSupported, SupportedImportFormats) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700474 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
475 device()->get_supported_import_formats(device(), KM_ALGORITHM_RSA, NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600476
Shawn Willden5b53c992015-02-02 08:05:25 -0700477 size_t len;
478 keymaster_key_format_t* formats;
479 EXPECT_EQ(KM_ERROR_OK,
480 device()->get_supported_import_formats(device(), KM_ALGORITHM_RSA, &formats, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700481 EXPECT_TRUE(ResponseContains(KM_KEY_FORMAT_PKCS8, formats, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700482 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600483
Shawn Willden76076ab2014-12-18 08:36:35 -0700484 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM,
Shawn Willden5b53c992015-02-02 08:05:25 -0700485 device()->get_supported_import_formats(device(), KM_ALGORITHM_DSA, &formats, &len));
Shawn Willden28e41472014-08-18 13:35:22 -0600486
Shawn Willden5b53c992015-02-02 08:05:25 -0700487 EXPECT_EQ(KM_ERROR_OK,
488 device()->get_supported_import_formats(device(), KM_ALGORITHM_ECDSA, &formats, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700489 EXPECT_TRUE(ResponseContains(KM_KEY_FORMAT_PKCS8, formats, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700490 free(formats);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600491
Shawn Willden5b53c992015-02-02 08:05:25 -0700492 EXPECT_EQ(KM_ERROR_OK,
493 device()->get_supported_import_formats(device(), KM_ALGORITHM_AES, &formats, &len));
494 EXPECT_EQ(0, len);
495 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600496}
497
498TEST_F(CheckSupported, SupportedExportFormats) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700499 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
500 device()->get_supported_export_formats(device(), KM_ALGORITHM_RSA, NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600501
Shawn Willden5b53c992015-02-02 08:05:25 -0700502 size_t len;
503 keymaster_key_format_t* formats;
504 EXPECT_EQ(KM_ERROR_OK,
505 device()->get_supported_export_formats(device(), KM_ALGORITHM_RSA, &formats, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700506 EXPECT_TRUE(ResponseContains(KM_KEY_FORMAT_X509, formats, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700507 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600508
Shawn Willden76076ab2014-12-18 08:36:35 -0700509 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM,
Shawn Willden5b53c992015-02-02 08:05:25 -0700510 device()->get_supported_export_formats(device(), KM_ALGORITHM_DSA, &formats, &len));
Shawn Willden28e41472014-08-18 13:35:22 -0600511
Shawn Willden5b53c992015-02-02 08:05:25 -0700512 EXPECT_EQ(KM_ERROR_OK,
513 device()->get_supported_export_formats(device(), KM_ALGORITHM_ECDSA, &formats, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700514 EXPECT_TRUE(ResponseContains(KM_KEY_FORMAT_X509, formats, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700515 free(formats);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600516
Shawn Willden5b53c992015-02-02 08:05:25 -0700517 EXPECT_EQ(KM_ERROR_OK,
518 device()->get_supported_export_formats(device(), KM_ALGORITHM_AES, &formats, &len));
519 EXPECT_EQ(0, len);
520 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600521}
522
Shawn Willden5b53c992015-02-02 08:05:25 -0700523TEST_F(KeymasterTest, TestFlags) {
524 EXPECT_TRUE(device()->flags & KEYMASTER_SOFTWARE_ONLY);
525 EXPECT_TRUE(device()->flags & KEYMASTER_BLOBS_ARE_STANDALONE);
526 EXPECT_FALSE(device()->flags & KEYMASTER_SUPPORTS_DSA);
527 EXPECT_TRUE(device()->flags & KEYMASTER_SUPPORTS_EC);
528}
529
530typedef KeymasterTest OldKeyGeneration;
531
532TEST_F(OldKeyGeneration, Rsa) {
533 keymaster_rsa_keygen_params_t params = {.modulus_size = 256, .public_exponent = 3};
534 uint8_t* key_blob;
535 size_t key_blob_length;
536 EXPECT_EQ(0,
537 device()->generate_keypair(device(), TYPE_RSA, &params, &key_blob, &key_blob_length));
538 EXPECT_GT(key_blob_length, 0);
539
540 free(key_blob);
541}
542
543TEST_F(OldKeyGeneration, Ecdsa) {
544
545 keymaster_ec_keygen_params_t params = {.field_size = 256};
546 uint8_t* key_blob;
547 size_t key_blob_length;
548 EXPECT_EQ(0,
549 device()->generate_keypair(device(), TYPE_EC, &params, &key_blob, &key_blob_length));
550 EXPECT_GT(key_blob_length, 0);
551
552 free(key_blob);
553}
554
Shawn Willdend0772312014-09-18 12:27:57 -0600555class NewKeyGeneration : public KeymasterTest {
556 protected:
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700557 void CheckBaseParams() {
558 EXPECT_EQ(0U, hw_enforced().size());
559 EXPECT_EQ(12U, hw_enforced().SerializedSize());
Shawn Willdend0772312014-09-18 12:27:57 -0600560
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700561 AuthorizationSet auths = sw_enforced();
562 EXPECT_GT(auths.SerializedSize(), 12U);
563
Shawn Willden5b53c992015-02-02 08:05:25 -0700564 EXPECT_TRUE(contains(auths, TAG_PURPOSE, KM_PURPOSE_SIGN));
565 EXPECT_TRUE(contains(auths, TAG_PURPOSE, KM_PURPOSE_VERIFY));
566 EXPECT_TRUE(contains(auths, TAG_USER_ID, 7));
567 EXPECT_TRUE(contains(auths, TAG_USER_AUTH_ID, 8));
568 EXPECT_TRUE(contains(auths, TAG_AUTH_TIMEOUT, 300));
Shawn Willdend0772312014-09-18 12:27:57 -0600569
570 // Verify that App ID, App data and ROT are NOT included.
Shawn Willden5b53c992015-02-02 08:05:25 -0700571 EXPECT_FALSE(contains(auths, TAG_ROOT_OF_TRUST));
572 EXPECT_FALSE(contains(auths, TAG_APPLICATION_ID));
573 EXPECT_FALSE(contains(auths, TAG_APPLICATION_DATA));
Shawn Willdend0772312014-09-18 12:27:57 -0600574
575 // Just for giggles, check that some unexpected tags/values are NOT present.
Shawn Willden5b53c992015-02-02 08:05:25 -0700576 EXPECT_FALSE(contains(auths, TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
577 EXPECT_FALSE(contains(auths, TAG_PURPOSE, KM_PURPOSE_DECRYPT));
578 EXPECT_FALSE(contains(auths, TAG_AUTH_TIMEOUT, 301));
Shawn Willdend0772312014-09-18 12:27:57 -0600579
580 // Now check that unspecified, defaulted tags are correct.
Shawn Willden5b53c992015-02-02 08:05:25 -0700581 EXPECT_TRUE(contains(auths, TAG_ORIGIN, KM_ORIGIN_SOFTWARE));
582 EXPECT_TRUE(contains(auths, KM_TAG_CREATION_DATETIME));
Shawn Willdend0772312014-09-18 12:27:57 -0600583 }
Shawn Willden2079ae82015-01-22 13:42:31 -0700584};
585
Shawn Willden128ffe02014-08-06 12:31:33 -0600586TEST_F(NewKeyGeneration, Rsa) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700587 GenerateKey(ParamBuilder().RsaSigningKey(256, KM_DIGEST_NONE, KM_PAD_NONE, 3));
588 CheckBaseParams();
Shawn Willden128ffe02014-08-06 12:31:33 -0600589
Shawn Willden5b53c992015-02-02 08:05:25 -0700590 // Check specified tags are all present in auths
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700591 AuthorizationSet auths(sw_enforced());
Shawn Willden5b53c992015-02-02 08:05:25 -0700592 EXPECT_TRUE(contains(auths, TAG_ALGORITHM, KM_ALGORITHM_RSA));
593 EXPECT_TRUE(contains(auths, TAG_KEY_SIZE, 256));
594 EXPECT_TRUE(contains(auths, TAG_RSA_PUBLIC_EXPONENT, 3));
Shawn Willden128ffe02014-08-06 12:31:33 -0600595}
596
Shawn Willden6bbe6782014-09-18 11:26:15 -0600597TEST_F(NewKeyGeneration, RsaDefaultSize) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700598 // TODO(swillden): Remove support for defaulting RSA parameter size and pub exponent.
599 GenerateKey(ParamBuilder().RsaSigningKey());
600 CheckBaseParams();
Shawn Willden6bbe6782014-09-18 11:26:15 -0600601
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700602 // Check specified tags are all present in unenforced characteristics
603 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_RSA));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600604
605 // Now check that unspecified, defaulted tags are correct.
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700606 EXPECT_TRUE(contains(sw_enforced(), TAG_RSA_PUBLIC_EXPONENT, 65537));
607 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 2048));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600608}
609
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600610TEST_F(NewKeyGeneration, Ecdsa) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700611 GenerateKey(ParamBuilder().EcdsaSigningKey(224));
612 CheckBaseParams();
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600613
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700614 // Check specified tags are all present in unenforced characteristics
615 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
616 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 224));
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600617}
618
Shawn Willden6bbe6782014-09-18 11:26:15 -0600619TEST_F(NewKeyGeneration, EcdsaDefaultSize) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700620 GenerateKey(ParamBuilder().EcdsaSigningKey());
621 CheckBaseParams();
Shawn Willden6bbe6782014-09-18 11:26:15 -0600622
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700623 // Check specified tags are all present in unenforced characteristics
624 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600625
626 // Now check that unspecified, defaulted tags are correct.
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700627 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 224));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600628}
629
630TEST_F(NewKeyGeneration, EcdsaInvalidSize) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700631 ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE,
632 AttemptToGenerateKey(ParamBuilder().EcdsaSigningKey(190)));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600633}
634
635TEST_F(NewKeyGeneration, EcdsaAllValidSizes) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600636 size_t valid_sizes[] = {224, 256, 384, 521};
Shawn Willden6bbe6782014-09-18 11:26:15 -0600637 for (size_t size : valid_sizes) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700638 EXPECT_EQ(KM_ERROR_OK, AttemptToGenerateKey(ParamBuilder().EcdsaSigningKey(size)))
Shawn Willden5b53c992015-02-02 08:05:25 -0700639 << "Failed to generate size: " << size;
Shawn Willden6bbe6782014-09-18 11:26:15 -0600640 }
641}
642
Shawn Willden19fca882015-01-22 16:35:30 -0700643TEST_F(NewKeyGeneration, AesOcb) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700644 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
Shawn Willden19fca882015-01-22 16:35:30 -0700645}
646
647TEST_F(NewKeyGeneration, AesOcbInvalidKeySize) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700648 GenerateKey(ParamBuilder().AesEncryptionKey(136).OcbMode(4096, 16));
649 EXPECT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willden19fca882015-01-22 16:35:30 -0700650}
651
652TEST_F(NewKeyGeneration, AesOcbAllValidSizes) {
Shawn Willden19fca882015-01-22 16:35:30 -0700653 size_t valid_sizes[] = {128, 192, 256};
654 for (size_t size : valid_sizes) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700655 EXPECT_EQ(KM_ERROR_OK, AttemptToGenerateKey(ParamBuilder().AesEncryptionKey(size)))
Shawn Willden5b53c992015-02-02 08:05:25 -0700656 << "Failed to generate size: " << size;
Shawn Willden19fca882015-01-22 16:35:30 -0700657 }
658}
659
Shawn Willden0d560bf2014-12-15 17:44:02 -0700660TEST_F(NewKeyGeneration, HmacSha256) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700661 GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_256, 16));
Shawn Willden0d560bf2014-12-15 17:44:02 -0700662}
663
Shawn Willden76364712014-08-11 17:48:04 -0600664typedef KeymasterTest GetKeyCharacteristics;
665TEST_F(GetKeyCharacteristics, SimpleRsa) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700666 GenerateKey(ParamBuilder().RsaSigningKey(256));
667 AuthorizationSet original(sw_enforced());
Shawn Willden76364712014-08-11 17:48:04 -0600668
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700669 ASSERT_EQ(KM_ERROR_OK, GetCharacteristics());
670 EXPECT_EQ(original, sw_enforced());
Shawn Willden76364712014-08-11 17:48:04 -0600671}
672
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700673typedef KeymasterTest SigningOperationsTest;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600674TEST_F(SigningOperationsTest, RsaSuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700675 GenerateKey(ParamBuilder().RsaSigningKey(256));
676 string message = "12345678901234567890123456789012";
677 string signature;
678 SignMessage(message, &signature);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600679}
680
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600681TEST_F(SigningOperationsTest, EcdsaSuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700682 GenerateKey(ParamBuilder().EcdsaSigningKey(224));
683 string message = "123456789012345678901234567890123456789012345678";
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700684 string signature;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700685 SignMessage(message, &signature);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600686}
687
Shawn Willden1615f2e2014-08-13 10:37:40 -0600688TEST_F(SigningOperationsTest, RsaAbort) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700689 GenerateKey(ParamBuilder().RsaSigningKey(256));
690 ASSERT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_SIGN));
691 EXPECT_EQ(KM_ERROR_OK, AbortOperation());
692 // Another abort should fail
693 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, AbortOperation());
Shawn Willden1615f2e2014-08-13 10:37:40 -0600694}
695
696TEST_F(SigningOperationsTest, RsaUnsupportedDigest) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700697 GenerateKey(ParamBuilder().RsaSigningKey(256, KM_DIGEST_SHA_2_256, KM_PAD_NONE));
698 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600699}
700
701TEST_F(SigningOperationsTest, RsaUnsupportedPadding) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700702 GenerateKey(ParamBuilder().RsaSigningKey(256, KM_DIGEST_NONE, KM_PAD_RSA_OAEP));
703 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600704}
705
706TEST_F(SigningOperationsTest, RsaNoDigest) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700707 GenerateKey(ParamBuilder().RsaKey(256).SigningKey().Option(TAG_PADDING, KM_PAD_NONE));
708 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600709}
710
711TEST_F(SigningOperationsTest, RsaNoPadding) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700712 GenerateKey(ParamBuilder().RsaKey(256).SigningKey().Option(TAG_DIGEST, KM_DIGEST_NONE));
713 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600714}
715
Shawn Willden62c22862014-12-17 08:36:20 -0700716TEST_F(SigningOperationsTest, HmacSha224Success) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700717 GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_224, 28));
718 string message = "12345678901234567890123456789012";
719 string signature;
720 SignMessage(message, &signature);
721 ASSERT_EQ(28, signature.size());
Shawn Willden62c22862014-12-17 08:36:20 -0700722}
723
Shawn Willden0d560bf2014-12-15 17:44:02 -0700724TEST_F(SigningOperationsTest, HmacSha256Success) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700725 GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_256, 32));
726 string message = "12345678901234567890123456789012";
727 string signature;
728 SignMessage(message, &signature);
729 ASSERT_EQ(32, signature.size());
Shawn Willden0d560bf2014-12-15 17:44:02 -0700730}
731
Shawn Willden62c22862014-12-17 08:36:20 -0700732TEST_F(SigningOperationsTest, HmacSha384Success) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700733 GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_384, 48));
734 string message = "12345678901234567890123456789012";
735 string signature;
736 SignMessage(message, &signature);
737 ASSERT_EQ(48, signature.size());
Shawn Willden62c22862014-12-17 08:36:20 -0700738}
739
740TEST_F(SigningOperationsTest, HmacSha512Success) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700741 GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_512, 64));
742 string message = "12345678901234567890123456789012";
Shawn Willden62c22862014-12-17 08:36:20 -0700743 string signature;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700744 SignMessage(message, &signature);
745 ASSERT_EQ(64, signature.size());
Shawn Willden62c22862014-12-17 08:36:20 -0700746}
747
748// TODO(swillden): Add HMACSHA{224|256|384|512} tests that validates against the test vectors from
749// RFC4231. Doing that requires being able to import keys, rather than just
750// generate them randomly.
Shawn Willden0d560bf2014-12-15 17:44:02 -0700751
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700752TEST_F(SigningOperationsTest, HmacSha256NoMacLength) {
753 GenerateKey(ParamBuilder()
754 .Option(TAG_ALGORITHM, KM_ALGORITHM_HMAC)
755 .Option(TAG_KEY_SIZE, 128)
756 .SigningKey()
757 .Option(TAG_DIGEST, KM_DIGEST_SHA_2_256));
758 EXPECT_EQ(KM_ERROR_UNSUPPORTED_MAC_LENGTH, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden0d560bf2014-12-15 17:44:02 -0700759}
760
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700761TEST_F(SigningOperationsTest, HmacSha256TooLargeMacLength) {
762 GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_256, 33));
763 ASSERT_EQ(KM_ERROR_UNSUPPORTED_MAC_LENGTH, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden0d560bf2014-12-15 17:44:02 -0700764}
765
Shawn Willden1615f2e2014-08-13 10:37:40 -0600766TEST_F(SigningOperationsTest, RsaTooShortMessage) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700767 GenerateKey(ParamBuilder().RsaSigningKey(256));
768 ASSERT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700769
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700770 string message = "1234567890123456789012345678901";
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700771 string result;
772 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700773 ASSERT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700774 EXPECT_EQ(0U, result.size());
775 EXPECT_EQ(31U, input_consumed);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600776
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700777 string signature;
778 ASSERT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&signature));
779 EXPECT_EQ(0U, signature.length());
Shawn Willden43e999e2014-08-13 13:29:50 -0600780}
781
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700782typedef KeymasterTest VerificationOperationsTest;
Shawn Willden43e999e2014-08-13 13:29:50 -0600783TEST_F(VerificationOperationsTest, RsaSuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700784 GenerateKey(ParamBuilder().RsaSigningKey(256));
785 string message = "12345678901234567890123456789012";
786 string signature;
787 SignMessage(message, &signature);
788 VerifyMessage(message, signature);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600789}
790
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600791TEST_F(VerificationOperationsTest, EcdsaSuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700792 GenerateKey(ParamBuilder().EcdsaSigningKey(256));
793 string message = "123456789012345678901234567890123456789012345678";
794 string signature;
795 SignMessage(message, &signature);
796 VerifyMessage(message, signature);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600797}
798
Shawn Willden0d560bf2014-12-15 17:44:02 -0700799TEST_F(VerificationOperationsTest, HmacSha256Success) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700800 GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_256, 16));
801 string message = "123456789012345678901234567890123456789012345678";
Shawn Willden0d560bf2014-12-15 17:44:02 -0700802 string signature;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700803 SignMessage(message, &signature);
804 VerifyMessage(message, signature);
Shawn Willden0d560bf2014-12-15 17:44:02 -0700805}
806
Shawn Willden5b53c992015-02-02 08:05:25 -0700807typedef VerificationOperationsTest ExportKeyTest;
Shawn Willdenffd790c2014-08-18 21:20:06 -0600808TEST_F(ExportKeyTest, RsaSuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700809 GenerateKey(ParamBuilder().RsaSigningKey(256));
810 string export_data;
811 ASSERT_EQ(KM_ERROR_OK, ExportKey(KM_KEY_FORMAT_X509, &export_data));
812 EXPECT_GT(export_data.length(), 0);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600813
814 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willdenffd790c2014-08-18 21:20:06 -0600815}
816
Shawn Willdenf268d742014-08-19 15:36:26 -0600817TEST_F(ExportKeyTest, EcdsaSuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700818 GenerateKey(ParamBuilder().EcdsaSigningKey(224));
819 string export_data;
820 ASSERT_EQ(KM_ERROR_OK, ExportKey(KM_KEY_FORMAT_X509, &export_data));
821 EXPECT_GT(export_data.length(), 0);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600822
823 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willdenf268d742014-08-19 15:36:26 -0600824}
825
826TEST_F(ExportKeyTest, RsaUnsupportedKeyFormat) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700827 GenerateKey(ParamBuilder().RsaSigningKey(256));
828 string export_data;
829 ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_FORMAT, ExportKey(KM_KEY_FORMAT_PKCS8, &export_data));
Shawn Willdenf268d742014-08-19 15:36:26 -0600830}
831
832TEST_F(ExportKeyTest, RsaCorruptedKeyBlob) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700833 GenerateKey(ParamBuilder().RsaSigningKey(256));
Shawn Willden5b53c992015-02-02 08:05:25 -0700834 corrupt_key_blob();
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700835 string export_data;
836 ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, ExportKey(KM_KEY_FORMAT_X509, &export_data));
Shawn Willdenf268d742014-08-19 15:36:26 -0600837}
838
Shawn Willden437fbd12014-08-20 11:59:49 -0600839static string read_file(const string& file_name) {
840 ifstream file_stream(file_name, std::ios::binary);
841 istreambuf_iterator<char> file_begin(file_stream);
842 istreambuf_iterator<char> file_end;
843 return string(file_begin, file_end);
844}
845
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700846typedef VerificationOperationsTest ImportKeyTest;
Shawn Willden5b53c992015-02-02 08:05:25 -0700847TEST_F(ImportKeyTest, RsaSuccess) {
Shawn Willden81effc62014-08-27 10:08:46 -0600848 string pk8_key = read_file("rsa_privkey_pk8.der");
Shawn Willden437fbd12014-08-20 11:59:49 -0600849 ASSERT_EQ(633U, pk8_key.size());
850
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700851 ImportKey(ParamBuilder().SigningKey().NoDigestOrPadding(), KM_KEY_FORMAT_PKCS8, pk8_key);
Shawn Willden437fbd12014-08-20 11:59:49 -0600852
853 // Check values derived from the key.
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700854 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_RSA));
855 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 1024));
856 EXPECT_TRUE(contains(sw_enforced(), TAG_RSA_PUBLIC_EXPONENT, 65537U));
Shawn Willden437fbd12014-08-20 11:59:49 -0600857
858 // And values provided by GoogleKeymaster
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700859 EXPECT_TRUE(contains(sw_enforced(), TAG_ORIGIN, KM_ORIGIN_IMPORTED));
860 EXPECT_TRUE(contains(sw_enforced(), KM_TAG_CREATION_DATETIME));
Shawn Willden437fbd12014-08-20 11:59:49 -0600861
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700862 string message(1024 / 8, 'a');
863 string signature;
864 SignMessage(message, &signature);
865 VerifyMessage(message, signature);
Shawn Willden437fbd12014-08-20 11:59:49 -0600866}
867
Shawn Willden6bbe6782014-09-18 11:26:15 -0600868TEST_F(ImportKeyTest, RsaKeySizeMismatch) {
Shawn Willden6bbe6782014-09-18 11:26:15 -0600869 string pk8_key = read_file("rsa_privkey_pk8.der");
870 ASSERT_EQ(633U, pk8_key.size());
Shawn Willden5b53c992015-02-02 08:05:25 -0700871 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700872 AttemptImportKey(ParamBuilder()
873 .SigningKey()
874 .Option(TAG_KEY_SIZE, 2048) // Doesn't match key
875 .NoDigestOrPadding(),
876 KM_KEY_FORMAT_PKCS8, pk8_key));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600877}
878
879TEST_F(ImportKeyTest, RsaPublicExponenMismatch) {
Shawn Willden6bbe6782014-09-18 11:26:15 -0600880 string pk8_key = read_file("rsa_privkey_pk8.der");
881 ASSERT_EQ(633U, pk8_key.size());
Shawn Willden5b53c992015-02-02 08:05:25 -0700882 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700883 AttemptImportKey(ParamBuilder()
884 .SigningKey()
885 .Option(TAG_RSA_PUBLIC_EXPONENT, 3) // Doesn't match key
886 .NoDigestOrPadding(),
887 KM_KEY_FORMAT_PKCS8, pk8_key));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600888}
889
Shawn Willden81effc62014-08-27 10:08:46 -0600890TEST_F(ImportKeyTest, EcdsaSuccess) {
Shawn Willden81effc62014-08-27 10:08:46 -0600891 string pk8_key = read_file("ec_privkey_pk8.der");
892 ASSERT_EQ(138U, pk8_key.size());
893
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700894 ImportKey(ParamBuilder().SigningKey(), KM_KEY_FORMAT_PKCS8, pk8_key);
Shawn Willden81effc62014-08-27 10:08:46 -0600895
896 // Check values derived from the key.
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700897 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
898 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 256));
Shawn Willden81effc62014-08-27 10:08:46 -0600899
900 // And values provided by GoogleKeymaster
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700901 EXPECT_TRUE(contains(sw_enforced(), TAG_ORIGIN, KM_ORIGIN_IMPORTED));
902 EXPECT_TRUE(contains(sw_enforced(), KM_TAG_CREATION_DATETIME));
Shawn Willden81effc62014-08-27 10:08:46 -0600903
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700904 string message(1024 / 8, 'a');
905 string signature;
906 SignMessage(message, &signature);
907 VerifyMessage(message, signature);
Shawn Willden81effc62014-08-27 10:08:46 -0600908}
909
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700910TEST_F(ImportKeyTest, EcdsaSizeSpecified) {
911 string pk8_key = read_file("ec_privkey_pk8.der");
912 ASSERT_EQ(138U, pk8_key.size());
Shawn Willden6bbe6782014-09-18 11:26:15 -0600913
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700914 ImportKey(ParamBuilder().SigningKey().Option(TAG_KEY_SIZE, 256), KM_KEY_FORMAT_PKCS8, pk8_key);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600915
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700916 // Check values derived from the key.
917 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
918 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 256));
919
920 // And values provided by GoogleKeymaster
921 EXPECT_TRUE(contains(sw_enforced(), TAG_ORIGIN, KM_ORIGIN_IMPORTED));
922 EXPECT_TRUE(contains(sw_enforced(), KM_TAG_CREATION_DATETIME));
923
924 string message(1024 / 8, 'a');
925 string signature;
926 SignMessage(message, &signature);
927 VerifyMessage(message, signature);
928}
929
930TEST_F(ImportKeyTest, EcdsaSizeMismatch) {
931 string pk8_key = read_file("ec_privkey_pk8.der");
932 ASSERT_EQ(138U, pk8_key.size());
Shawn Willden5b53c992015-02-02 08:05:25 -0700933 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700934 AttemptImportKey(ParamBuilder().SigningKey().Option(TAG_KEY_SIZE, 224),
935 KM_KEY_FORMAT_PKCS8, pk8_key));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600936}
937
Shawn Willden2665e862014-11-24 14:46:21 -0700938typedef KeymasterTest VersionTest;
939TEST_F(VersionTest, GetVersion) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700940 uint8_t major, minor, subminor;
941 ASSERT_EQ(KM_ERROR_OK, GetVersion(&major, &minor, &subminor));
942 EXPECT_EQ(1, major);
943 EXPECT_EQ(0, minor);
944 EXPECT_EQ(0, subminor);
Shawn Willden2665e862014-11-24 14:46:21 -0700945}
946
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700947typedef KeymasterTest EncryptionOperationsTest;
Shawn Willden4200f212014-12-02 07:01:21 -0700948TEST_F(EncryptionOperationsTest, RsaOaepSuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700949 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_OAEP));
950
951 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -0700952 string ciphertext1 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -0700953 EXPECT_EQ(512 / 8, ciphertext1.size());
954
Shawn Willden6dde87c2014-12-11 14:08:48 -0700955 string ciphertext2 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -0700956 EXPECT_EQ(512 / 8, ciphertext2.size());
957
958 // OAEP randomizes padding so every result should be different.
959 EXPECT_NE(ciphertext1, ciphertext2);
960}
961
962TEST_F(EncryptionOperationsTest, RsaOaepRoundTrip) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700963 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_OAEP));
964 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -0700965 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -0700966 EXPECT_EQ(512 / 8, ciphertext.size());
967
Shawn Willden6dde87c2014-12-11 14:08:48 -0700968 string plaintext = DecryptMessage(ciphertext);
Shawn Willden4200f212014-12-02 07:01:21 -0700969 EXPECT_EQ(message, plaintext);
970}
971
972TEST_F(EncryptionOperationsTest, RsaOaepTooLarge) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700973 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_OAEP));
974 string message = "12345678901234567890123";
Shawn Willden4200f212014-12-02 07:01:21 -0700975 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -0700976 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -0700977
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700978 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT));
979 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700980 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -0700981 EXPECT_EQ(0, result.size());
982}
983
984TEST_F(EncryptionOperationsTest, RsaOaepCorruptedDecrypt) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700985 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_OAEP));
986 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -0700987 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -0700988 EXPECT_EQ(512 / 8, ciphertext.size());
989
990 // Corrupt the ciphertext
991 ciphertext[512 / 8 / 2]++;
992
Shawn Willden4200f212014-12-02 07:01:21 -0700993 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -0700994 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700995 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
996 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700997 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -0700998 EXPECT_EQ(0, result.size());
999}
1000
1001TEST_F(EncryptionOperationsTest, RsaPkcs1Success) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001002 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_PKCS1_1_5_ENCRYPT));
1003 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001004 string ciphertext1 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001005 EXPECT_EQ(512 / 8, ciphertext1.size());
1006
Shawn Willden6dde87c2014-12-11 14:08:48 -07001007 string ciphertext2 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001008 EXPECT_EQ(512 / 8, ciphertext2.size());
1009
1010 // PKCS1 v1.5 randomizes padding so every result should be different.
1011 EXPECT_NE(ciphertext1, ciphertext2);
1012}
1013
1014TEST_F(EncryptionOperationsTest, RsaPkcs1RoundTrip) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001015 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_PKCS1_1_5_ENCRYPT));
1016 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001017 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001018 EXPECT_EQ(512 / 8, ciphertext.size());
1019
Shawn Willden6dde87c2014-12-11 14:08:48 -07001020 string plaintext = DecryptMessage(ciphertext);
Shawn Willden4200f212014-12-02 07:01:21 -07001021 EXPECT_EQ(message, plaintext);
1022}
1023
1024TEST_F(EncryptionOperationsTest, RsaPkcs1TooLarge) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001025 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_PKCS1_1_5_ENCRYPT));
1026 string message = "12345678901234567890123456789012345678901234567890123";
Shawn Willden4200f212014-12-02 07:01:21 -07001027 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001028 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001029
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001030 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT));
1031 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001032 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -07001033 EXPECT_EQ(0, result.size());
1034}
1035
1036TEST_F(EncryptionOperationsTest, RsaPkcs1CorruptedDecrypt) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001037 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_PKCS1_1_5_ENCRYPT));
1038 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001039 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001040 EXPECT_EQ(512 / 8, ciphertext.size());
1041
1042 // Corrupt the ciphertext
1043 ciphertext[512 / 8 / 2]++;
1044
Shawn Willden4200f212014-12-02 07:01:21 -07001045 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001046 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001047 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
1048 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001049 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -07001050 EXPECT_EQ(0, result.size());
1051}
1052
Shawn Willden907c3012014-12-08 15:51:55 -07001053TEST_F(EncryptionOperationsTest, AesOcbSuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001054 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
1055 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001056 string ciphertext1 = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001057 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext1.size());
Shawn Willden907c3012014-12-08 15:51:55 -07001058
Shawn Willden6dde87c2014-12-11 14:08:48 -07001059 string ciphertext2 = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001060 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext2.size());
Shawn Willden907c3012014-12-08 15:51:55 -07001061
1062 // OCB uses a random nonce, so every output should be different
1063 EXPECT_NE(ciphertext1, ciphertext2);
1064}
1065
Shawn Willden6dde87c2014-12-11 14:08:48 -07001066TEST_F(EncryptionOperationsTest, AesOcbRoundTripSuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001067 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001068 string message = "Hello World!";
1069 string ciphertext = EncryptMessage(message);
1070 EXPECT_EQ(12 /* nonce */ + message.length() + 16 /* tag */, ciphertext.size());
1071
1072 string plaintext = DecryptMessage(ciphertext);
1073 EXPECT_EQ(message, plaintext);
1074}
1075
1076TEST_F(EncryptionOperationsTest, AesOcbRoundTripCorrupted) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001077 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
1078 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001079 string ciphertext = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001080 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext.size());
Shawn Willden6dde87c2014-12-11 14:08:48 -07001081
1082 ciphertext[ciphertext.size() / 2]++;
1083
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001084 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001085
1086 string result;
1087 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001088 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001089 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001090 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001091}
1092
1093TEST_F(EncryptionOperationsTest, AesDecryptGarbage) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001094 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001095 string ciphertext(128, 'a');
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001096 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001097
1098 string result;
1099 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001100 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001101 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001102 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001103}
1104
1105TEST_F(EncryptionOperationsTest, AesDecryptTooShort) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001106 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
1107
Shawn Willden6dde87c2014-12-11 14:08:48 -07001108 // Try decrypting garbage ciphertext that is too short to be valid (< nonce + tag).
Shawn Willden6dde87c2014-12-11 14:08:48 -07001109 string ciphertext(12 + 15, 'a');
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001110 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001111
1112 string result;
1113 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001114 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001115 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001116 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001117}
1118
1119TEST_F(EncryptionOperationsTest, AesOcbRoundTripEmptySuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001120 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
1121 string message = "";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001122 string ciphertext = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001123 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext.size());
Shawn Willden6dde87c2014-12-11 14:08:48 -07001124
1125 string plaintext = DecryptMessage(ciphertext);
1126 EXPECT_EQ(message, plaintext);
1127}
1128
1129TEST_F(EncryptionOperationsTest, AesOcbRoundTripEmptyCorrupted) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001130 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
1131 string message = "";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001132 string ciphertext = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001133 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext.size());
Shawn Willden6dde87c2014-12-11 14:08:48 -07001134
1135 ciphertext[ciphertext.size() / 2]++;
1136
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001137 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001138
1139 string result;
1140 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001141 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001142 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001143 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001144}
1145
1146TEST_F(EncryptionOperationsTest, AesOcbFullChunk) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001147 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001148 string message(4096, 'a');
1149 string ciphertext = EncryptMessage(message);
1150 EXPECT_EQ(12 /* nonce */ + message.length() + 16 /* tag */, ciphertext.size());
1151
1152 string plaintext = DecryptMessage(ciphertext);
1153 EXPECT_EQ(message, plaintext);
1154}
1155
1156TEST_F(EncryptionOperationsTest, AesOcbVariousChunkLengths) {
1157 for (unsigned chunk_length = 1; chunk_length <= 128; ++chunk_length) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001158 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(chunk_length, 16));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001159 string message(128, 'a');
1160 string ciphertext = EncryptMessage(message);
1161 int expected_tag_count = (message.length() + chunk_length - 1) / chunk_length;
1162 EXPECT_EQ(12 /* nonce */ + message.length() + 16 * expected_tag_count, ciphertext.size())
1163 << "Unexpected ciphertext size for chunk length " << chunk_length
1164 << " expected tag count was " << expected_tag_count
1165 << " but actual tag count was probably "
1166 << (ciphertext.size() - message.length() - 12) / 16;
1167
1168 string plaintext = DecryptMessage(ciphertext);
1169 EXPECT_EQ(message, plaintext);
1170 }
1171}
1172
1173TEST_F(EncryptionOperationsTest, AesOcbAbort) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001174 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
1175 string message = "Hello";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001176
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001177 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001178
1179 string result;
1180 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001181 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
1182 EXPECT_EQ(message.length(), input_consumed);
1183 EXPECT_EQ(KM_ERROR_OK, AbortOperation());
Shawn Willden6dde87c2014-12-11 14:08:48 -07001184}
1185
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001186TEST_F(EncryptionOperationsTest, AesOcbNoChunkLength) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001187 GenerateKey(ParamBuilder()
1188 .AesEncryptionKey(128)
1189 .Option(TAG_BLOCK_MODE, KM_MODE_OCB)
1190 .Option(TAG_MAC_LENGTH, 16));
1191 EXPECT_EQ(KM_ERROR_INVALID_ARGUMENT, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001192}
1193
1194TEST_F(EncryptionOperationsTest, AesEcbUnsupported) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001195 GenerateKey(ParamBuilder().AesEncryptionKey(128).Option(TAG_BLOCK_MODE, KM_MODE_ECB));
1196 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001197}
1198
1199TEST_F(EncryptionOperationsTest, AesOcbPaddingUnsupported) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001200 GenerateKey(
1201 ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16).Option(TAG_PADDING, KM_PAD_ZERO));
1202 EXPECT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001203}
1204
1205TEST_F(EncryptionOperationsTest, AesOcbInvalidMacLength) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001206 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 17));
1207 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001208}
1209
Shawn Willden128ffe02014-08-06 12:31:33 -06001210} // namespace test
1211} // namespace keymaster