blob: 67d06a9213334369333f99dcc751995ea20412a0 [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(
Shawn Willden6bfbff02015-02-06 19:48:24 -0700231 device(), op_handle_, NULL /* additional_params */, 0 /* additional_params_count */,
232 reinterpret_cast<const uint8_t*>(message.c_str()), message.length(), input_consumed,
233 &out_tmp, &out_length);
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700234 if (out_tmp)
235 output->append(reinterpret_cast<char*>(out_tmp), out_length);
236 free(out_tmp);
237 return error;
238 }
239
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700240 keymaster_error_t FinishOperation(string* output) { return FinishOperation("", output); }
241
242 keymaster_error_t FinishOperation(const string& signature, string* output) {
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700243 uint8_t* out_tmp = NULL;
244 size_t out_length;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700245 keymaster_error_t error = device()->finish(
Shawn Willden6bfbff02015-02-06 19:48:24 -0700246 device(), op_handle_, NULL /* additional_params */, 0 /* additional_params_count */,
247 reinterpret_cast<const uint8_t*>(signature.c_str()), signature.length(), &out_tmp,
248 &out_length);
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700249 if (out_tmp)
250 output->append(reinterpret_cast<char*>(out_tmp), out_length);
251 free(out_tmp);
252 return error;
253 }
254
Shawn Willden76076ab2014-12-18 08:36:35 -0700255 template <typename T>
256 bool ResponseContains(const vector<T>& expected, const T* values, size_t len) {
257 return std::is_permutation(values, values + len, expected.begin());
258 }
259
260 template <typename T> bool ResponseContains(T expected, const T* values, size_t len) {
261 return (len == 1 && *values == expected);
Shawn Willdend0772312014-09-18 12:27:57 -0600262 }
263
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700264 keymaster_error_t AbortOperation() { return device()->abort(device(), op_handle_); }
265
266 string ProcessMessage(keymaster_purpose_t purpose, const string& message) {
267 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose));
268
269 string result;
270 size_t input_consumed;
271 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
272 EXPECT_EQ(message.size(), input_consumed);
273 EXPECT_EQ(KM_ERROR_OK, FinishOperation(&result));
274 return result;
275 }
276
277 string ProcessMessage(keymaster_purpose_t purpose, const string& message,
278 const string& signature) {
279 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose));
280
281 string result;
282 size_t input_consumed;
283 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
284 EXPECT_EQ(message.size(), input_consumed);
285 EXPECT_EQ(KM_ERROR_OK, FinishOperation(signature, &result));
286 return result;
287 }
288
289 void SignMessage(const string& message, string* signature) {
290 *signature = ProcessMessage(KM_PURPOSE_SIGN, message);
291 EXPECT_GT(signature->size(), 0);
292 }
293
294 void VerifyMessage(const string& message, const string& signature) {
295 ProcessMessage(KM_PURPOSE_VERIFY, message, signature);
296 }
297
298 string EncryptMessage(const string& message) {
299 return ProcessMessage(KM_PURPOSE_ENCRYPT, message);
300 }
301
302 string DecryptMessage(const string& ciphertext) {
303 return ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext);
304 }
305
306 keymaster_error_t GetCharacteristics() {
307 FreeCharacteristics();
308 return device()->get_key_characteristics(device(), &blob_, &client_id_, NULL /* app_data */,
309 &characteristics_);
310 }
311
312 keymaster_error_t ExportKey(keymaster_key_format_t format, string* export_data) {
313 uint8_t* export_data_tmp;
314 size_t export_data_length;
315
316 keymaster_error_t error =
317 device()->export_key(device(), format, &blob_, &client_id_, NULL /* app_data */,
318 &export_data_tmp, &export_data_length);
319
320 if (error != KM_ERROR_OK)
321 return error;
322
323 *export_data = string(reinterpret_cast<char*>(export_data_tmp), export_data_length);
324 free(export_data_tmp);
325 return error;
326 }
327
328 keymaster_error_t GetVersion(uint8_t* major, uint8_t* minor, uint8_t* subminor) {
329 GetVersionRequest request;
330 GetVersionResponse response;
331 device_.GetVersion(request, &response);
332 if (response.error != KM_ERROR_OK)
333 return response.error;
334 *major = response.major_ver;
335 *minor = response.minor_ver;
336 *subminor = response.subminor_ver;
337 return response.error;
338 }
339
340 AuthorizationSet hw_enforced() {
341 EXPECT_TRUE(characteristics_ != NULL);
342 return AuthorizationSet(characteristics_->hw_enforced);
343 }
344
345 AuthorizationSet sw_enforced() {
346 EXPECT_TRUE(characteristics_ != NULL);
347 return AuthorizationSet(characteristics_->sw_enforced);
348 }
349
Shawn Willden5b53c992015-02-02 08:05:25 -0700350 void FreeCharacteristics() {
351 keymaster_free_characteristics(characteristics_);
352 free(characteristics_);
353 characteristics_ = NULL;
354 }
355
356 void FreeKeyBlob() {
357 free(const_cast<uint8_t*>(blob_.key_material));
358 blob_.key_material = NULL;
359 }
360
Shawn Willden6dde87c2014-12-11 14:08:48 -0700361 const keymaster_key_blob_t& key_blob() { return blob_; }
362
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700363 void corrupt_key_blob() {
364 assert(blob_.key_material);
365 uint8_t* tmp = const_cast<uint8_t*>(blob_.key_material);
366 ++tmp[blob_.key_material_size / 2];
367 }
Shawn Willden5b53c992015-02-02 08:05:25 -0700368
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700369 private:
370 SoftKeymasterDevice device_;
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700371 keymaster_blob_t client_id_ = {.data = reinterpret_cast<const uint8_t*>("app_id"),
372 .data_length = 6};
373 keymaster_key_param_t client_params_[1] = {
374 Authorization(TAG_APPLICATION_ID, client_id_.data, client_id_.data_length)};
375
376 keymaster_key_param_t* out_params_;
377 size_t out_params_count_;
378 uint64_t op_handle_;
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700379
Shawn Willden5b53c992015-02-02 08:05:25 -0700380 keymaster_key_blob_t blob_;
381 keymaster_key_characteristics_t* characteristics_;
Shawn Willden128ffe02014-08-06 12:31:33 -0600382};
383
Shawn Willden128ffe02014-08-06 12:31:33 -0600384typedef KeymasterTest CheckSupported;
385TEST_F(CheckSupported, SupportedAlgorithms) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700386 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
387 device()->get_supported_algorithms(device(), NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600388
Shawn Willden5b53c992015-02-02 08:05:25 -0700389 size_t len;
390 keymaster_algorithm_t* algorithms;
391 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_algorithms(device(), &algorithms, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700392 EXPECT_TRUE(ResponseContains({KM_ALGORITHM_RSA, KM_ALGORITHM_ECDSA, KM_ALGORITHM_AES},
393 algorithms, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700394 free(algorithms);
Shawn Willden128ffe02014-08-06 12:31:33 -0600395}
396
397TEST_F(CheckSupported, SupportedBlockModes) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700398 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
399 device()->get_supported_block_modes(device(), KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT,
400 NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600401
Shawn Willden5b53c992015-02-02 08:05:25 -0700402 size_t len;
403 keymaster_block_mode_t* modes;
404 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE,
405 device()->get_supported_block_modes(device(), KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT,
406 &modes, &len));
Shawn Willden128ffe02014-08-06 12:31:33 -0600407
Shawn Willden76076ab2014-12-18 08:36:35 -0700408 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM,
Shawn Willden5b53c992015-02-02 08:05:25 -0700409 device()->get_supported_block_modes(device(), KM_ALGORITHM_DSA, KM_PURPOSE_ENCRYPT,
410 &modes, &len));
Shawn Willden28e41472014-08-18 13:35:22 -0600411
Shawn Willden5b53c992015-02-02 08:05:25 -0700412 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE,
413 device()->get_supported_block_modes(device(), KM_ALGORITHM_ECDSA, KM_PURPOSE_ENCRYPT,
414 &modes, &len));
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600415
Shawn Willden5b53c992015-02-02 08:05:25 -0700416 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE,
417 device()->get_supported_block_modes(device(), KM_ALGORITHM_AES, KM_PURPOSE_ENCRYPT,
418 &modes, &len));
Shawn Willden128ffe02014-08-06 12:31:33 -0600419}
420
421TEST_F(CheckSupported, SupportedPaddingModes) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700422 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
423 device()->get_supported_padding_modes(device(), KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT,
424 NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600425
Shawn Willden5b53c992015-02-02 08:05:25 -0700426 size_t len;
427 keymaster_padding_t* modes;
428 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_RSA,
429 KM_PURPOSE_SIGN, &modes, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700430 EXPECT_TRUE(ResponseContains(KM_PAD_NONE, modes, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700431 free(modes);
Shawn Willden128ffe02014-08-06 12:31:33 -0600432
Shawn Willden76076ab2014-12-18 08:36:35 -0700433 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM,
434 device()->get_supported_padding_modes(device(), KM_ALGORITHM_DSA, KM_PURPOSE_SIGN,
435 &modes, &len));
Shawn Willden28e41472014-08-18 13:35:22 -0600436
Shawn Willden5b53c992015-02-02 08:05:25 -0700437 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_ECDSA,
438 KM_PURPOSE_SIGN, &modes, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700439 EXPECT_TRUE(ResponseContains(KM_PAD_NONE, modes, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700440 free(modes);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600441
Shawn Willden5b53c992015-02-02 08:05:25 -0700442 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_AES,
443 KM_PURPOSE_SIGN, &modes, &len));
444 EXPECT_EQ(0, len);
445 free(modes);
Shawn Willden128ffe02014-08-06 12:31:33 -0600446}
447
448TEST_F(CheckSupported, SupportedDigests) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700449 EXPECT_EQ(
450 KM_ERROR_OUTPUT_PARAMETER_NULL,
451 device()->get_supported_digests(device(), KM_ALGORITHM_RSA, KM_PURPOSE_SIGN, NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600452
Shawn Willden5b53c992015-02-02 08:05:25 -0700453 size_t len;
454 keymaster_digest_t* digests;
455 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_RSA,
456 KM_PURPOSE_SIGN, &digests, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700457 EXPECT_TRUE(ResponseContains(KM_DIGEST_NONE, digests, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700458 free(digests);
Shawn Willden128ffe02014-08-06 12:31:33 -0600459
Shawn Willden76076ab2014-12-18 08:36:35 -0700460 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM,
461 device()->get_supported_digests(device(), KM_ALGORITHM_DSA, KM_PURPOSE_SIGN, &digests,
462 &len));
Shawn Willden28e41472014-08-18 13:35:22 -0600463
Shawn Willden5b53c992015-02-02 08:05:25 -0700464 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_ECDSA,
465 KM_PURPOSE_SIGN, &digests, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700466 EXPECT_TRUE(ResponseContains(KM_DIGEST_NONE, digests, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700467 free(digests);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600468
Shawn Willden5b53c992015-02-02 08:05:25 -0700469 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_AES,
470 KM_PURPOSE_SIGN, &digests, &len));
471 EXPECT_EQ(0, len);
472 free(digests);
Shawn Willden128ffe02014-08-06 12:31:33 -0600473}
474
475TEST_F(CheckSupported, SupportedImportFormats) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700476 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
477 device()->get_supported_import_formats(device(), KM_ALGORITHM_RSA, NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600478
Shawn Willden5b53c992015-02-02 08:05:25 -0700479 size_t len;
480 keymaster_key_format_t* formats;
481 EXPECT_EQ(KM_ERROR_OK,
482 device()->get_supported_import_formats(device(), KM_ALGORITHM_RSA, &formats, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700483 EXPECT_TRUE(ResponseContains(KM_KEY_FORMAT_PKCS8, formats, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700484 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600485
Shawn Willden76076ab2014-12-18 08:36:35 -0700486 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM,
Shawn Willden5b53c992015-02-02 08:05:25 -0700487 device()->get_supported_import_formats(device(), KM_ALGORITHM_DSA, &formats, &len));
Shawn Willden28e41472014-08-18 13:35:22 -0600488
Shawn Willden5b53c992015-02-02 08:05:25 -0700489 EXPECT_EQ(KM_ERROR_OK,
490 device()->get_supported_import_formats(device(), KM_ALGORITHM_ECDSA, &formats, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700491 EXPECT_TRUE(ResponseContains(KM_KEY_FORMAT_PKCS8, formats, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700492 free(formats);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600493
Shawn Willden5b53c992015-02-02 08:05:25 -0700494 EXPECT_EQ(KM_ERROR_OK,
495 device()->get_supported_import_formats(device(), KM_ALGORITHM_AES, &formats, &len));
496 EXPECT_EQ(0, len);
497 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600498}
499
500TEST_F(CheckSupported, SupportedExportFormats) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700501 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
502 device()->get_supported_export_formats(device(), KM_ALGORITHM_RSA, NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600503
Shawn Willden5b53c992015-02-02 08:05:25 -0700504 size_t len;
505 keymaster_key_format_t* formats;
506 EXPECT_EQ(KM_ERROR_OK,
507 device()->get_supported_export_formats(device(), KM_ALGORITHM_RSA, &formats, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700508 EXPECT_TRUE(ResponseContains(KM_KEY_FORMAT_X509, formats, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700509 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600510
Shawn Willden76076ab2014-12-18 08:36:35 -0700511 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM,
Shawn Willden5b53c992015-02-02 08:05:25 -0700512 device()->get_supported_export_formats(device(), KM_ALGORITHM_DSA, &formats, &len));
Shawn Willden28e41472014-08-18 13:35:22 -0600513
Shawn Willden5b53c992015-02-02 08:05:25 -0700514 EXPECT_EQ(KM_ERROR_OK,
515 device()->get_supported_export_formats(device(), KM_ALGORITHM_ECDSA, &formats, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700516 EXPECT_TRUE(ResponseContains(KM_KEY_FORMAT_X509, formats, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700517 free(formats);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600518
Shawn Willden5b53c992015-02-02 08:05:25 -0700519 EXPECT_EQ(KM_ERROR_OK,
520 device()->get_supported_export_formats(device(), KM_ALGORITHM_AES, &formats, &len));
521 EXPECT_EQ(0, len);
522 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600523}
524
Shawn Willden5b53c992015-02-02 08:05:25 -0700525TEST_F(KeymasterTest, TestFlags) {
526 EXPECT_TRUE(device()->flags & KEYMASTER_SOFTWARE_ONLY);
527 EXPECT_TRUE(device()->flags & KEYMASTER_BLOBS_ARE_STANDALONE);
528 EXPECT_FALSE(device()->flags & KEYMASTER_SUPPORTS_DSA);
529 EXPECT_TRUE(device()->flags & KEYMASTER_SUPPORTS_EC);
530}
531
532typedef KeymasterTest OldKeyGeneration;
533
534TEST_F(OldKeyGeneration, Rsa) {
535 keymaster_rsa_keygen_params_t params = {.modulus_size = 256, .public_exponent = 3};
536 uint8_t* key_blob;
537 size_t key_blob_length;
538 EXPECT_EQ(0,
539 device()->generate_keypair(device(), TYPE_RSA, &params, &key_blob, &key_blob_length));
540 EXPECT_GT(key_blob_length, 0);
541
542 free(key_blob);
543}
544
545TEST_F(OldKeyGeneration, Ecdsa) {
546
547 keymaster_ec_keygen_params_t params = {.field_size = 256};
548 uint8_t* key_blob;
549 size_t key_blob_length;
550 EXPECT_EQ(0,
551 device()->generate_keypair(device(), TYPE_EC, &params, &key_blob, &key_blob_length));
552 EXPECT_GT(key_blob_length, 0);
553
554 free(key_blob);
555}
556
Shawn Willdend0772312014-09-18 12:27:57 -0600557class NewKeyGeneration : public KeymasterTest {
558 protected:
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700559 void CheckBaseParams() {
560 EXPECT_EQ(0U, hw_enforced().size());
561 EXPECT_EQ(12U, hw_enforced().SerializedSize());
Shawn Willdend0772312014-09-18 12:27:57 -0600562
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700563 AuthorizationSet auths = sw_enforced();
564 EXPECT_GT(auths.SerializedSize(), 12U);
565
Shawn Willden5b53c992015-02-02 08:05:25 -0700566 EXPECT_TRUE(contains(auths, TAG_PURPOSE, KM_PURPOSE_SIGN));
567 EXPECT_TRUE(contains(auths, TAG_PURPOSE, KM_PURPOSE_VERIFY));
568 EXPECT_TRUE(contains(auths, TAG_USER_ID, 7));
569 EXPECT_TRUE(contains(auths, TAG_USER_AUTH_ID, 8));
570 EXPECT_TRUE(contains(auths, TAG_AUTH_TIMEOUT, 300));
Shawn Willdend0772312014-09-18 12:27:57 -0600571
572 // Verify that App ID, App data and ROT are NOT included.
Shawn Willden5b53c992015-02-02 08:05:25 -0700573 EXPECT_FALSE(contains(auths, TAG_ROOT_OF_TRUST));
574 EXPECT_FALSE(contains(auths, TAG_APPLICATION_ID));
575 EXPECT_FALSE(contains(auths, TAG_APPLICATION_DATA));
Shawn Willdend0772312014-09-18 12:27:57 -0600576
577 // Just for giggles, check that some unexpected tags/values are NOT present.
Shawn Willden5b53c992015-02-02 08:05:25 -0700578 EXPECT_FALSE(contains(auths, TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
579 EXPECT_FALSE(contains(auths, TAG_PURPOSE, KM_PURPOSE_DECRYPT));
580 EXPECT_FALSE(contains(auths, TAG_AUTH_TIMEOUT, 301));
Shawn Willdend0772312014-09-18 12:27:57 -0600581
582 // Now check that unspecified, defaulted tags are correct.
Shawn Willden5b53c992015-02-02 08:05:25 -0700583 EXPECT_TRUE(contains(auths, TAG_ORIGIN, KM_ORIGIN_SOFTWARE));
584 EXPECT_TRUE(contains(auths, KM_TAG_CREATION_DATETIME));
Shawn Willdend0772312014-09-18 12:27:57 -0600585 }
Shawn Willden2079ae82015-01-22 13:42:31 -0700586};
587
Shawn Willden128ffe02014-08-06 12:31:33 -0600588TEST_F(NewKeyGeneration, Rsa) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700589 GenerateKey(ParamBuilder().RsaSigningKey(256, KM_DIGEST_NONE, KM_PAD_NONE, 3));
590 CheckBaseParams();
Shawn Willden128ffe02014-08-06 12:31:33 -0600591
Shawn Willden5b53c992015-02-02 08:05:25 -0700592 // Check specified tags are all present in auths
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700593 AuthorizationSet auths(sw_enforced());
Shawn Willden5b53c992015-02-02 08:05:25 -0700594 EXPECT_TRUE(contains(auths, TAG_ALGORITHM, KM_ALGORITHM_RSA));
595 EXPECT_TRUE(contains(auths, TAG_KEY_SIZE, 256));
596 EXPECT_TRUE(contains(auths, TAG_RSA_PUBLIC_EXPONENT, 3));
Shawn Willden128ffe02014-08-06 12:31:33 -0600597}
598
Shawn Willden6bbe6782014-09-18 11:26:15 -0600599TEST_F(NewKeyGeneration, RsaDefaultSize) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700600 // TODO(swillden): Remove support for defaulting RSA parameter size and pub exponent.
601 GenerateKey(ParamBuilder().RsaSigningKey());
602 CheckBaseParams();
Shawn Willden6bbe6782014-09-18 11:26:15 -0600603
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700604 // Check specified tags are all present in unenforced characteristics
605 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_RSA));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600606
607 // Now check that unspecified, defaulted tags are correct.
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700608 EXPECT_TRUE(contains(sw_enforced(), TAG_RSA_PUBLIC_EXPONENT, 65537));
609 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 2048));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600610}
611
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600612TEST_F(NewKeyGeneration, Ecdsa) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700613 GenerateKey(ParamBuilder().EcdsaSigningKey(224));
614 CheckBaseParams();
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600615
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700616 // Check specified tags are all present in unenforced characteristics
617 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
618 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 224));
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600619}
620
Shawn Willden6bbe6782014-09-18 11:26:15 -0600621TEST_F(NewKeyGeneration, EcdsaDefaultSize) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700622 GenerateKey(ParamBuilder().EcdsaSigningKey());
623 CheckBaseParams();
Shawn Willden6bbe6782014-09-18 11:26:15 -0600624
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700625 // Check specified tags are all present in unenforced characteristics
626 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600627
628 // Now check that unspecified, defaulted tags are correct.
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700629 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 224));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600630}
631
632TEST_F(NewKeyGeneration, EcdsaInvalidSize) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700633 ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE,
634 AttemptToGenerateKey(ParamBuilder().EcdsaSigningKey(190)));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600635}
636
637TEST_F(NewKeyGeneration, EcdsaAllValidSizes) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600638 size_t valid_sizes[] = {224, 256, 384, 521};
Shawn Willden6bbe6782014-09-18 11:26:15 -0600639 for (size_t size : valid_sizes) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700640 EXPECT_EQ(KM_ERROR_OK, AttemptToGenerateKey(ParamBuilder().EcdsaSigningKey(size)))
Shawn Willden5b53c992015-02-02 08:05:25 -0700641 << "Failed to generate size: " << size;
Shawn Willden6bbe6782014-09-18 11:26:15 -0600642 }
643}
644
Shawn Willden19fca882015-01-22 16:35:30 -0700645TEST_F(NewKeyGeneration, AesOcb) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700646 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
Shawn Willden19fca882015-01-22 16:35:30 -0700647}
648
649TEST_F(NewKeyGeneration, AesOcbInvalidKeySize) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700650 GenerateKey(ParamBuilder().AesEncryptionKey(136).OcbMode(4096, 16));
651 EXPECT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willden19fca882015-01-22 16:35:30 -0700652}
653
654TEST_F(NewKeyGeneration, AesOcbAllValidSizes) {
Shawn Willden19fca882015-01-22 16:35:30 -0700655 size_t valid_sizes[] = {128, 192, 256};
656 for (size_t size : valid_sizes) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700657 EXPECT_EQ(KM_ERROR_OK, AttemptToGenerateKey(ParamBuilder().AesEncryptionKey(size)))
Shawn Willden5b53c992015-02-02 08:05:25 -0700658 << "Failed to generate size: " << size;
Shawn Willden19fca882015-01-22 16:35:30 -0700659 }
660}
661
Shawn Willden0d560bf2014-12-15 17:44:02 -0700662TEST_F(NewKeyGeneration, HmacSha256) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700663 GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_256, 16));
Shawn Willden0d560bf2014-12-15 17:44:02 -0700664}
665
Shawn Willden76364712014-08-11 17:48:04 -0600666typedef KeymasterTest GetKeyCharacteristics;
667TEST_F(GetKeyCharacteristics, SimpleRsa) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700668 GenerateKey(ParamBuilder().RsaSigningKey(256));
669 AuthorizationSet original(sw_enforced());
Shawn Willden76364712014-08-11 17:48:04 -0600670
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700671 ASSERT_EQ(KM_ERROR_OK, GetCharacteristics());
672 EXPECT_EQ(original, sw_enforced());
Shawn Willden76364712014-08-11 17:48:04 -0600673}
674
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700675typedef KeymasterTest SigningOperationsTest;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600676TEST_F(SigningOperationsTest, RsaSuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700677 GenerateKey(ParamBuilder().RsaSigningKey(256));
678 string message = "12345678901234567890123456789012";
679 string signature;
680 SignMessage(message, &signature);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600681}
682
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600683TEST_F(SigningOperationsTest, EcdsaSuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700684 GenerateKey(ParamBuilder().EcdsaSigningKey(224));
685 string message = "123456789012345678901234567890123456789012345678";
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700686 string signature;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700687 SignMessage(message, &signature);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600688}
689
Shawn Willden1615f2e2014-08-13 10:37:40 -0600690TEST_F(SigningOperationsTest, RsaAbort) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700691 GenerateKey(ParamBuilder().RsaSigningKey(256));
692 ASSERT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_SIGN));
693 EXPECT_EQ(KM_ERROR_OK, AbortOperation());
694 // Another abort should fail
695 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, AbortOperation());
Shawn Willden1615f2e2014-08-13 10:37:40 -0600696}
697
698TEST_F(SigningOperationsTest, RsaUnsupportedDigest) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700699 GenerateKey(ParamBuilder().RsaSigningKey(256, KM_DIGEST_SHA_2_256, KM_PAD_NONE));
700 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600701}
702
703TEST_F(SigningOperationsTest, RsaUnsupportedPadding) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700704 GenerateKey(ParamBuilder().RsaSigningKey(256, KM_DIGEST_NONE, KM_PAD_RSA_OAEP));
705 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600706}
707
708TEST_F(SigningOperationsTest, RsaNoDigest) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700709 GenerateKey(ParamBuilder().RsaKey(256).SigningKey().Option(TAG_PADDING, KM_PAD_NONE));
710 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600711}
712
713TEST_F(SigningOperationsTest, RsaNoPadding) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700714 GenerateKey(ParamBuilder().RsaKey(256).SigningKey().Option(TAG_DIGEST, KM_DIGEST_NONE));
715 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600716}
717
Shawn Willden62c22862014-12-17 08:36:20 -0700718TEST_F(SigningOperationsTest, HmacSha224Success) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700719 GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_224, 28));
720 string message = "12345678901234567890123456789012";
721 string signature;
722 SignMessage(message, &signature);
723 ASSERT_EQ(28, signature.size());
Shawn Willden62c22862014-12-17 08:36:20 -0700724}
725
Shawn Willden0d560bf2014-12-15 17:44:02 -0700726TEST_F(SigningOperationsTest, HmacSha256Success) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700727 GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_256, 32));
728 string message = "12345678901234567890123456789012";
729 string signature;
730 SignMessage(message, &signature);
731 ASSERT_EQ(32, signature.size());
Shawn Willden0d560bf2014-12-15 17:44:02 -0700732}
733
Shawn Willden62c22862014-12-17 08:36:20 -0700734TEST_F(SigningOperationsTest, HmacSha384Success) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700735 GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_384, 48));
736 string message = "12345678901234567890123456789012";
737 string signature;
738 SignMessage(message, &signature);
739 ASSERT_EQ(48, signature.size());
Shawn Willden62c22862014-12-17 08:36:20 -0700740}
741
742TEST_F(SigningOperationsTest, HmacSha512Success) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700743 GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_512, 64));
744 string message = "12345678901234567890123456789012";
Shawn Willden62c22862014-12-17 08:36:20 -0700745 string signature;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700746 SignMessage(message, &signature);
747 ASSERT_EQ(64, signature.size());
Shawn Willden62c22862014-12-17 08:36:20 -0700748}
749
750// TODO(swillden): Add HMACSHA{224|256|384|512} tests that validates against the test vectors from
751// RFC4231. Doing that requires being able to import keys, rather than just
752// generate them randomly.
Shawn Willden0d560bf2014-12-15 17:44:02 -0700753
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700754TEST_F(SigningOperationsTest, HmacSha256NoMacLength) {
755 GenerateKey(ParamBuilder()
756 .Option(TAG_ALGORITHM, KM_ALGORITHM_HMAC)
757 .Option(TAG_KEY_SIZE, 128)
758 .SigningKey()
759 .Option(TAG_DIGEST, KM_DIGEST_SHA_2_256));
760 EXPECT_EQ(KM_ERROR_UNSUPPORTED_MAC_LENGTH, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden0d560bf2014-12-15 17:44:02 -0700761}
762
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700763TEST_F(SigningOperationsTest, HmacSha256TooLargeMacLength) {
764 GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_256, 33));
765 ASSERT_EQ(KM_ERROR_UNSUPPORTED_MAC_LENGTH, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden0d560bf2014-12-15 17:44:02 -0700766}
767
Shawn Willden1615f2e2014-08-13 10:37:40 -0600768TEST_F(SigningOperationsTest, RsaTooShortMessage) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700769 GenerateKey(ParamBuilder().RsaSigningKey(256));
770 ASSERT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700771
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700772 string message = "1234567890123456789012345678901";
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700773 string result;
774 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700775 ASSERT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700776 EXPECT_EQ(0U, result.size());
777 EXPECT_EQ(31U, input_consumed);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600778
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700779 string signature;
780 ASSERT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&signature));
781 EXPECT_EQ(0U, signature.length());
Shawn Willden43e999e2014-08-13 13:29:50 -0600782}
783
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700784typedef KeymasterTest VerificationOperationsTest;
Shawn Willden43e999e2014-08-13 13:29:50 -0600785TEST_F(VerificationOperationsTest, RsaSuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700786 GenerateKey(ParamBuilder().RsaSigningKey(256));
787 string message = "12345678901234567890123456789012";
788 string signature;
789 SignMessage(message, &signature);
790 VerifyMessage(message, signature);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600791}
792
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600793TEST_F(VerificationOperationsTest, EcdsaSuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700794 GenerateKey(ParamBuilder().EcdsaSigningKey(256));
795 string message = "123456789012345678901234567890123456789012345678";
796 string signature;
797 SignMessage(message, &signature);
798 VerifyMessage(message, signature);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600799}
800
Shawn Willden0d560bf2014-12-15 17:44:02 -0700801TEST_F(VerificationOperationsTest, HmacSha256Success) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700802 GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_256, 16));
803 string message = "123456789012345678901234567890123456789012345678";
Shawn Willden0d560bf2014-12-15 17:44:02 -0700804 string signature;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700805 SignMessage(message, &signature);
806 VerifyMessage(message, signature);
Shawn Willden0d560bf2014-12-15 17:44:02 -0700807}
808
Shawn Willden5b53c992015-02-02 08:05:25 -0700809typedef VerificationOperationsTest ExportKeyTest;
Shawn Willdenffd790c2014-08-18 21:20:06 -0600810TEST_F(ExportKeyTest, RsaSuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700811 GenerateKey(ParamBuilder().RsaSigningKey(256));
812 string export_data;
813 ASSERT_EQ(KM_ERROR_OK, ExportKey(KM_KEY_FORMAT_X509, &export_data));
814 EXPECT_GT(export_data.length(), 0);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600815
816 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willdenffd790c2014-08-18 21:20:06 -0600817}
818
Shawn Willdenf268d742014-08-19 15:36:26 -0600819TEST_F(ExportKeyTest, EcdsaSuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700820 GenerateKey(ParamBuilder().EcdsaSigningKey(224));
821 string export_data;
822 ASSERT_EQ(KM_ERROR_OK, ExportKey(KM_KEY_FORMAT_X509, &export_data));
823 EXPECT_GT(export_data.length(), 0);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600824
825 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willdenf268d742014-08-19 15:36:26 -0600826}
827
828TEST_F(ExportKeyTest, RsaUnsupportedKeyFormat) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700829 GenerateKey(ParamBuilder().RsaSigningKey(256));
830 string export_data;
831 ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_FORMAT, ExportKey(KM_KEY_FORMAT_PKCS8, &export_data));
Shawn Willdenf268d742014-08-19 15:36:26 -0600832}
833
834TEST_F(ExportKeyTest, RsaCorruptedKeyBlob) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700835 GenerateKey(ParamBuilder().RsaSigningKey(256));
Shawn Willden5b53c992015-02-02 08:05:25 -0700836 corrupt_key_blob();
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700837 string export_data;
838 ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, ExportKey(KM_KEY_FORMAT_X509, &export_data));
Shawn Willdenf268d742014-08-19 15:36:26 -0600839}
840
Shawn Willden437fbd12014-08-20 11:59:49 -0600841static string read_file(const string& file_name) {
842 ifstream file_stream(file_name, std::ios::binary);
843 istreambuf_iterator<char> file_begin(file_stream);
844 istreambuf_iterator<char> file_end;
845 return string(file_begin, file_end);
846}
847
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700848typedef VerificationOperationsTest ImportKeyTest;
Shawn Willden5b53c992015-02-02 08:05:25 -0700849TEST_F(ImportKeyTest, RsaSuccess) {
Shawn Willden81effc62014-08-27 10:08:46 -0600850 string pk8_key = read_file("rsa_privkey_pk8.der");
Shawn Willden437fbd12014-08-20 11:59:49 -0600851 ASSERT_EQ(633U, pk8_key.size());
852
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700853 ImportKey(ParamBuilder().SigningKey().NoDigestOrPadding(), KM_KEY_FORMAT_PKCS8, pk8_key);
Shawn Willden437fbd12014-08-20 11:59:49 -0600854
855 // Check values derived from the key.
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700856 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_RSA));
857 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 1024));
858 EXPECT_TRUE(contains(sw_enforced(), TAG_RSA_PUBLIC_EXPONENT, 65537U));
Shawn Willden437fbd12014-08-20 11:59:49 -0600859
860 // And values provided by GoogleKeymaster
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700861 EXPECT_TRUE(contains(sw_enforced(), TAG_ORIGIN, KM_ORIGIN_IMPORTED));
862 EXPECT_TRUE(contains(sw_enforced(), KM_TAG_CREATION_DATETIME));
Shawn Willden437fbd12014-08-20 11:59:49 -0600863
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700864 string message(1024 / 8, 'a');
865 string signature;
866 SignMessage(message, &signature);
867 VerifyMessage(message, signature);
Shawn Willden437fbd12014-08-20 11:59:49 -0600868}
869
Shawn Willden6bbe6782014-09-18 11:26:15 -0600870TEST_F(ImportKeyTest, RsaKeySizeMismatch) {
Shawn Willden6bbe6782014-09-18 11:26:15 -0600871 string pk8_key = read_file("rsa_privkey_pk8.der");
872 ASSERT_EQ(633U, pk8_key.size());
Shawn Willden5b53c992015-02-02 08:05:25 -0700873 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700874 AttemptImportKey(ParamBuilder()
875 .SigningKey()
876 .Option(TAG_KEY_SIZE, 2048) // Doesn't match key
877 .NoDigestOrPadding(),
878 KM_KEY_FORMAT_PKCS8, pk8_key));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600879}
880
881TEST_F(ImportKeyTest, RsaPublicExponenMismatch) {
Shawn Willden6bbe6782014-09-18 11:26:15 -0600882 string pk8_key = read_file("rsa_privkey_pk8.der");
883 ASSERT_EQ(633U, pk8_key.size());
Shawn Willden5b53c992015-02-02 08:05:25 -0700884 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700885 AttemptImportKey(ParamBuilder()
886 .SigningKey()
887 .Option(TAG_RSA_PUBLIC_EXPONENT, 3) // Doesn't match key
888 .NoDigestOrPadding(),
889 KM_KEY_FORMAT_PKCS8, pk8_key));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600890}
891
Shawn Willden81effc62014-08-27 10:08:46 -0600892TEST_F(ImportKeyTest, EcdsaSuccess) {
Shawn Willden81effc62014-08-27 10:08:46 -0600893 string pk8_key = read_file("ec_privkey_pk8.der");
894 ASSERT_EQ(138U, pk8_key.size());
895
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700896 ImportKey(ParamBuilder().SigningKey(), KM_KEY_FORMAT_PKCS8, pk8_key);
Shawn Willden81effc62014-08-27 10:08:46 -0600897
898 // Check values derived from the key.
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700899 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
900 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 256));
Shawn Willden81effc62014-08-27 10:08:46 -0600901
902 // And values provided by GoogleKeymaster
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700903 EXPECT_TRUE(contains(sw_enforced(), TAG_ORIGIN, KM_ORIGIN_IMPORTED));
904 EXPECT_TRUE(contains(sw_enforced(), KM_TAG_CREATION_DATETIME));
Shawn Willden81effc62014-08-27 10:08:46 -0600905
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700906 string message(1024 / 8, 'a');
907 string signature;
908 SignMessage(message, &signature);
909 VerifyMessage(message, signature);
Shawn Willden81effc62014-08-27 10:08:46 -0600910}
911
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700912TEST_F(ImportKeyTest, EcdsaSizeSpecified) {
913 string pk8_key = read_file("ec_privkey_pk8.der");
914 ASSERT_EQ(138U, pk8_key.size());
Shawn Willden6bbe6782014-09-18 11:26:15 -0600915
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700916 ImportKey(ParamBuilder().SigningKey().Option(TAG_KEY_SIZE, 256), KM_KEY_FORMAT_PKCS8, pk8_key);
Shawn Willden6bbe6782014-09-18 11:26:15 -0600917
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700918 // Check values derived from the key.
919 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
920 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 256));
921
922 // And values provided by GoogleKeymaster
923 EXPECT_TRUE(contains(sw_enforced(), TAG_ORIGIN, KM_ORIGIN_IMPORTED));
924 EXPECT_TRUE(contains(sw_enforced(), KM_TAG_CREATION_DATETIME));
925
926 string message(1024 / 8, 'a');
927 string signature;
928 SignMessage(message, &signature);
929 VerifyMessage(message, signature);
930}
931
932TEST_F(ImportKeyTest, EcdsaSizeMismatch) {
933 string pk8_key = read_file("ec_privkey_pk8.der");
934 ASSERT_EQ(138U, pk8_key.size());
Shawn Willden5b53c992015-02-02 08:05:25 -0700935 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700936 AttemptImportKey(ParamBuilder().SigningKey().Option(TAG_KEY_SIZE, 224),
937 KM_KEY_FORMAT_PKCS8, pk8_key));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600938}
939
Shawn Willden2665e862014-11-24 14:46:21 -0700940typedef KeymasterTest VersionTest;
941TEST_F(VersionTest, GetVersion) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700942 uint8_t major, minor, subminor;
943 ASSERT_EQ(KM_ERROR_OK, GetVersion(&major, &minor, &subminor));
944 EXPECT_EQ(1, major);
945 EXPECT_EQ(0, minor);
946 EXPECT_EQ(0, subminor);
Shawn Willden2665e862014-11-24 14:46:21 -0700947}
948
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700949typedef KeymasterTest EncryptionOperationsTest;
Shawn Willden4200f212014-12-02 07:01:21 -0700950TEST_F(EncryptionOperationsTest, RsaOaepSuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700951 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_OAEP));
952
953 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -0700954 string ciphertext1 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -0700955 EXPECT_EQ(512 / 8, ciphertext1.size());
956
Shawn Willden6dde87c2014-12-11 14:08:48 -0700957 string ciphertext2 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -0700958 EXPECT_EQ(512 / 8, ciphertext2.size());
959
960 // OAEP randomizes padding so every result should be different.
961 EXPECT_NE(ciphertext1, ciphertext2);
962}
963
964TEST_F(EncryptionOperationsTest, RsaOaepRoundTrip) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700965 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_OAEP));
966 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -0700967 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -0700968 EXPECT_EQ(512 / 8, ciphertext.size());
969
Shawn Willden6dde87c2014-12-11 14:08:48 -0700970 string plaintext = DecryptMessage(ciphertext);
Shawn Willden4200f212014-12-02 07:01:21 -0700971 EXPECT_EQ(message, plaintext);
972}
973
974TEST_F(EncryptionOperationsTest, RsaOaepTooLarge) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700975 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_OAEP));
976 string message = "12345678901234567890123";
Shawn Willden4200f212014-12-02 07:01:21 -0700977 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -0700978 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -0700979
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700980 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT));
981 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700982 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -0700983 EXPECT_EQ(0, result.size());
984}
985
986TEST_F(EncryptionOperationsTest, RsaOaepCorruptedDecrypt) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700987 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_OAEP));
988 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -0700989 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -0700990 EXPECT_EQ(512 / 8, ciphertext.size());
991
992 // Corrupt the ciphertext
993 ciphertext[512 / 8 / 2]++;
994
Shawn Willden4200f212014-12-02 07:01:21 -0700995 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -0700996 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700997 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
998 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700999 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -07001000 EXPECT_EQ(0, result.size());
1001}
1002
1003TEST_F(EncryptionOperationsTest, RsaPkcs1Success) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001004 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_PKCS1_1_5_ENCRYPT));
1005 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001006 string ciphertext1 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001007 EXPECT_EQ(512 / 8, ciphertext1.size());
1008
Shawn Willden6dde87c2014-12-11 14:08:48 -07001009 string ciphertext2 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001010 EXPECT_EQ(512 / 8, ciphertext2.size());
1011
1012 // PKCS1 v1.5 randomizes padding so every result should be different.
1013 EXPECT_NE(ciphertext1, ciphertext2);
1014}
1015
1016TEST_F(EncryptionOperationsTest, RsaPkcs1RoundTrip) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001017 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_PKCS1_1_5_ENCRYPT));
1018 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001019 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001020 EXPECT_EQ(512 / 8, ciphertext.size());
1021
Shawn Willden6dde87c2014-12-11 14:08:48 -07001022 string plaintext = DecryptMessage(ciphertext);
Shawn Willden4200f212014-12-02 07:01:21 -07001023 EXPECT_EQ(message, plaintext);
1024}
1025
1026TEST_F(EncryptionOperationsTest, RsaPkcs1TooLarge) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001027 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_PKCS1_1_5_ENCRYPT));
1028 string message = "12345678901234567890123456789012345678901234567890123";
Shawn Willden4200f212014-12-02 07:01:21 -07001029 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001030 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001031
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001032 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT));
1033 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001034 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -07001035 EXPECT_EQ(0, result.size());
1036}
1037
1038TEST_F(EncryptionOperationsTest, RsaPkcs1CorruptedDecrypt) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001039 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_PKCS1_1_5_ENCRYPT));
1040 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001041 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001042 EXPECT_EQ(512 / 8, ciphertext.size());
1043
1044 // Corrupt the ciphertext
1045 ciphertext[512 / 8 / 2]++;
1046
Shawn Willden4200f212014-12-02 07:01:21 -07001047 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001048 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001049 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
1050 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001051 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -07001052 EXPECT_EQ(0, result.size());
1053}
1054
Shawn Willden907c3012014-12-08 15:51:55 -07001055TEST_F(EncryptionOperationsTest, AesOcbSuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001056 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
1057 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001058 string ciphertext1 = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001059 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext1.size());
Shawn Willden907c3012014-12-08 15:51:55 -07001060
Shawn Willden6dde87c2014-12-11 14:08:48 -07001061 string ciphertext2 = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001062 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext2.size());
Shawn Willden907c3012014-12-08 15:51:55 -07001063
1064 // OCB uses a random nonce, so every output should be different
1065 EXPECT_NE(ciphertext1, ciphertext2);
1066}
1067
Shawn Willden6dde87c2014-12-11 14:08:48 -07001068TEST_F(EncryptionOperationsTest, AesOcbRoundTripSuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001069 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001070 string message = "Hello World!";
1071 string ciphertext = EncryptMessage(message);
1072 EXPECT_EQ(12 /* nonce */ + message.length() + 16 /* tag */, ciphertext.size());
1073
1074 string plaintext = DecryptMessage(ciphertext);
1075 EXPECT_EQ(message, plaintext);
1076}
1077
1078TEST_F(EncryptionOperationsTest, AesOcbRoundTripCorrupted) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001079 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
1080 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001081 string ciphertext = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001082 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext.size());
Shawn Willden6dde87c2014-12-11 14:08:48 -07001083
1084 ciphertext[ciphertext.size() / 2]++;
1085
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001086 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001087
1088 string result;
1089 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001090 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001091 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001092 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001093}
1094
1095TEST_F(EncryptionOperationsTest, AesDecryptGarbage) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001096 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001097 string ciphertext(128, 'a');
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001098 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001099
1100 string result;
1101 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001102 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001103 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001104 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001105}
1106
1107TEST_F(EncryptionOperationsTest, AesDecryptTooShort) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001108 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
1109
Shawn Willden6dde87c2014-12-11 14:08:48 -07001110 // Try decrypting garbage ciphertext that is too short to be valid (< nonce + tag).
Shawn Willden6dde87c2014-12-11 14:08:48 -07001111 string ciphertext(12 + 15, 'a');
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001112 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001113
1114 string result;
1115 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001116 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001117 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001118 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001119}
1120
1121TEST_F(EncryptionOperationsTest, AesOcbRoundTripEmptySuccess) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001122 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
1123 string message = "";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001124 string ciphertext = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001125 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext.size());
Shawn Willden6dde87c2014-12-11 14:08:48 -07001126
1127 string plaintext = DecryptMessage(ciphertext);
1128 EXPECT_EQ(message, plaintext);
1129}
1130
1131TEST_F(EncryptionOperationsTest, AesOcbRoundTripEmptyCorrupted) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001132 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
1133 string message = "";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001134 string ciphertext = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001135 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext.size());
Shawn Willden6dde87c2014-12-11 14:08:48 -07001136
1137 ciphertext[ciphertext.size() / 2]++;
1138
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001139 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001140
1141 string result;
1142 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001143 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001144 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001145 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001146}
1147
1148TEST_F(EncryptionOperationsTest, AesOcbFullChunk) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001149 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001150 string message(4096, 'a');
1151 string ciphertext = EncryptMessage(message);
1152 EXPECT_EQ(12 /* nonce */ + message.length() + 16 /* tag */, ciphertext.size());
1153
1154 string plaintext = DecryptMessage(ciphertext);
1155 EXPECT_EQ(message, plaintext);
1156}
1157
1158TEST_F(EncryptionOperationsTest, AesOcbVariousChunkLengths) {
1159 for (unsigned chunk_length = 1; chunk_length <= 128; ++chunk_length) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001160 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(chunk_length, 16));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001161 string message(128, 'a');
1162 string ciphertext = EncryptMessage(message);
1163 int expected_tag_count = (message.length() + chunk_length - 1) / chunk_length;
1164 EXPECT_EQ(12 /* nonce */ + message.length() + 16 * expected_tag_count, ciphertext.size())
1165 << "Unexpected ciphertext size for chunk length " << chunk_length
1166 << " expected tag count was " << expected_tag_count
1167 << " but actual tag count was probably "
1168 << (ciphertext.size() - message.length() - 12) / 16;
1169
1170 string plaintext = DecryptMessage(ciphertext);
1171 EXPECT_EQ(message, plaintext);
1172 }
1173}
1174
1175TEST_F(EncryptionOperationsTest, AesOcbAbort) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001176 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16));
1177 string message = "Hello";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001178
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001179 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001180
1181 string result;
1182 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001183 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
1184 EXPECT_EQ(message.length(), input_consumed);
1185 EXPECT_EQ(KM_ERROR_OK, AbortOperation());
Shawn Willden6dde87c2014-12-11 14:08:48 -07001186}
1187
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001188TEST_F(EncryptionOperationsTest, AesOcbNoChunkLength) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001189 GenerateKey(ParamBuilder()
1190 .AesEncryptionKey(128)
1191 .Option(TAG_BLOCK_MODE, KM_MODE_OCB)
1192 .Option(TAG_MAC_LENGTH, 16));
1193 EXPECT_EQ(KM_ERROR_INVALID_ARGUMENT, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001194}
1195
1196TEST_F(EncryptionOperationsTest, AesEcbUnsupported) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001197 GenerateKey(ParamBuilder().AesEncryptionKey(128).Option(TAG_BLOCK_MODE, KM_MODE_ECB));
1198 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001199}
1200
1201TEST_F(EncryptionOperationsTest, AesOcbPaddingUnsupported) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001202 GenerateKey(
1203 ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16).Option(TAG_PADDING, KM_PAD_ZERO));
1204 EXPECT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001205}
1206
1207TEST_F(EncryptionOperationsTest, AesOcbInvalidMacLength) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001208 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 17));
1209 EXPECT_EQ(KM_ERROR_INVALID_KEY_BLOB, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001210}
1211
Shawn Willden128ffe02014-08-06 12:31:33 -06001212} // namespace test
1213} // namespace keymaster