blob: 91aef7b6d9f92c12aa77fbad95bbe9c331041e8a [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 Willdenc24c1102014-12-22 15:30:09 -0700172 keymaster_error_t GenerateKey(const ParamBuilder& builder) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700173 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 Willdenc24c1102014-12-22 15:30:09 -0700183 keymaster_error_t ImportKey(const ParamBuilder& builder, keymaster_key_format_t format,
184 const string& key_material) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700185 AuthorizationSet params(builder.build());
186 params.push_back(UserAuthParams());
187 params.push_back(ClientParams());
188
189 FreeKeyBlob();
190 FreeCharacteristics();
191 return device()->import_key(device(), params.data(), params.size(), format,
192 reinterpret_cast<const uint8_t*>(key_material.c_str()),
193 key_material.length(), &blob_, &characteristics_);
194 }
195
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700196 AuthorizationSet UserAuthParams() {
197 AuthorizationSet set;
198 set.push_back(TAG_USER_ID, 7);
199 set.push_back(TAG_USER_AUTH_ID, 8);
200 set.push_back(TAG_AUTH_TIMEOUT, 300);
201 return set;
202 }
203
204 AuthorizationSet ClientParams() {
205 AuthorizationSet set;
206 set.push_back(TAG_APPLICATION_ID, "app_id", 6);
207 return set;
208 }
209
210 keymaster_error_t BeginOperation(keymaster_purpose_t purpose) {
211 return device()->begin(device(), purpose, &blob_, client_params_,
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700212 array_length(client_params_), &out_params_, &out_params_count_,
213 &op_handle_);
214 }
215
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700216 keymaster_error_t UpdateOperation(const string& message, string* output,
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700217 size_t* input_consumed) {
218 uint8_t* out_tmp = NULL;
219 size_t out_length;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700220 EXPECT_NE(op_handle_, OP_HANDLE_SENTINEL);
221 keymaster_error_t error = device()->update(
Shawn Willden6bfbff02015-02-06 19:48:24 -0700222 device(), op_handle_, NULL /* additional_params */, 0 /* additional_params_count */,
223 reinterpret_cast<const uint8_t*>(message.c_str()), message.length(), input_consumed,
224 &out_tmp, &out_length);
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700225 if (out_tmp)
226 output->append(reinterpret_cast<char*>(out_tmp), out_length);
227 free(out_tmp);
228 return error;
229 }
230
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700231 keymaster_error_t FinishOperation(string* output) { return FinishOperation("", output); }
232
233 keymaster_error_t FinishOperation(const string& signature, string* output) {
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700234 uint8_t* out_tmp = NULL;
235 size_t out_length;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700236 keymaster_error_t error = device()->finish(
Shawn Willden6bfbff02015-02-06 19:48:24 -0700237 device(), op_handle_, NULL /* additional_params */, 0 /* additional_params_count */,
238 reinterpret_cast<const uint8_t*>(signature.c_str()), signature.length(), &out_tmp,
239 &out_length);
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700240 if (out_tmp)
241 output->append(reinterpret_cast<char*>(out_tmp), out_length);
242 free(out_tmp);
243 return error;
244 }
245
Shawn Willden76076ab2014-12-18 08:36:35 -0700246 template <typename T>
247 bool ResponseContains(const vector<T>& expected, const T* values, size_t len) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700248 return expected.size() == len &&
249 std::is_permutation(values, values + len, expected.begin());
Shawn Willden76076ab2014-12-18 08:36:35 -0700250 }
251
252 template <typename T> bool ResponseContains(T expected, const T* values, size_t len) {
253 return (len == 1 && *values == expected);
Shawn Willdend0772312014-09-18 12:27:57 -0600254 }
255
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700256 keymaster_error_t AbortOperation() { return device()->abort(device(), op_handle_); }
257
258 string ProcessMessage(keymaster_purpose_t purpose, const string& message) {
259 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose));
260
261 string result;
262 size_t input_consumed;
263 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
264 EXPECT_EQ(message.size(), input_consumed);
265 EXPECT_EQ(KM_ERROR_OK, FinishOperation(&result));
266 return result;
267 }
268
269 string ProcessMessage(keymaster_purpose_t purpose, const string& message,
270 const string& signature) {
271 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose));
272
273 string result;
274 size_t input_consumed;
275 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
276 EXPECT_EQ(message.size(), input_consumed);
277 EXPECT_EQ(KM_ERROR_OK, FinishOperation(signature, &result));
278 return result;
279 }
280
281 void SignMessage(const string& message, string* signature) {
282 *signature = ProcessMessage(KM_PURPOSE_SIGN, message);
283 EXPECT_GT(signature->size(), 0);
284 }
285
286 void VerifyMessage(const string& message, const string& signature) {
287 ProcessMessage(KM_PURPOSE_VERIFY, message, signature);
288 }
289
290 string EncryptMessage(const string& message) {
291 return ProcessMessage(KM_PURPOSE_ENCRYPT, message);
292 }
293
294 string DecryptMessage(const string& ciphertext) {
295 return ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext);
296 }
297
298 keymaster_error_t GetCharacteristics() {
299 FreeCharacteristics();
300 return device()->get_key_characteristics(device(), &blob_, &client_id_, NULL /* app_data */,
301 &characteristics_);
302 }
303
304 keymaster_error_t ExportKey(keymaster_key_format_t format, string* export_data) {
305 uint8_t* export_data_tmp;
306 size_t export_data_length;
307
308 keymaster_error_t error =
309 device()->export_key(device(), format, &blob_, &client_id_, NULL /* app_data */,
310 &export_data_tmp, &export_data_length);
311
312 if (error != KM_ERROR_OK)
313 return error;
314
315 *export_data = string(reinterpret_cast<char*>(export_data_tmp), export_data_length);
316 free(export_data_tmp);
317 return error;
318 }
319
320 keymaster_error_t GetVersion(uint8_t* major, uint8_t* minor, uint8_t* subminor) {
321 GetVersionRequest request;
322 GetVersionResponse response;
323 device_.GetVersion(request, &response);
324 if (response.error != KM_ERROR_OK)
325 return response.error;
326 *major = response.major_ver;
327 *minor = response.minor_ver;
328 *subminor = response.subminor_ver;
329 return response.error;
330 }
331
332 AuthorizationSet hw_enforced() {
333 EXPECT_TRUE(characteristics_ != NULL);
334 return AuthorizationSet(characteristics_->hw_enforced);
335 }
336
337 AuthorizationSet sw_enforced() {
338 EXPECT_TRUE(characteristics_ != NULL);
339 return AuthorizationSet(characteristics_->sw_enforced);
340 }
341
Shawn Willden5b53c992015-02-02 08:05:25 -0700342 void FreeCharacteristics() {
343 keymaster_free_characteristics(characteristics_);
344 free(characteristics_);
345 characteristics_ = NULL;
346 }
347
348 void FreeKeyBlob() {
349 free(const_cast<uint8_t*>(blob_.key_material));
350 blob_.key_material = NULL;
351 }
352
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700353 void corrupt_key_blob() {
354 assert(blob_.key_material);
355 uint8_t* tmp = const_cast<uint8_t*>(blob_.key_material);
356 ++tmp[blob_.key_material_size / 2];
357 }
Shawn Willden5b53c992015-02-02 08:05:25 -0700358
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700359 private:
360 SoftKeymasterDevice device_;
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700361 keymaster_blob_t client_id_ = {.data = reinterpret_cast<const uint8_t*>("app_id"),
362 .data_length = 6};
363 keymaster_key_param_t client_params_[1] = {
364 Authorization(TAG_APPLICATION_ID, client_id_.data, client_id_.data_length)};
365
366 keymaster_key_param_t* out_params_;
367 size_t out_params_count_;
368 uint64_t op_handle_;
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700369
Shawn Willden5b53c992015-02-02 08:05:25 -0700370 keymaster_key_blob_t blob_;
371 keymaster_key_characteristics_t* characteristics_;
Shawn Willden128ffe02014-08-06 12:31:33 -0600372};
373
Shawn Willden128ffe02014-08-06 12:31:33 -0600374typedef KeymasterTest CheckSupported;
375TEST_F(CheckSupported, SupportedAlgorithms) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700376 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
377 device()->get_supported_algorithms(device(), NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600378
Shawn Willden5b53c992015-02-02 08:05:25 -0700379 size_t len;
380 keymaster_algorithm_t* algorithms;
381 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_algorithms(device(), &algorithms, &len));
Shawn Willdena278f612014-12-23 11:22:21 -0700382 EXPECT_TRUE(ResponseContains(
383 {KM_ALGORITHM_RSA, KM_ALGORITHM_ECDSA, KM_ALGORITHM_AES, KM_ALGORITHM_HMAC}, algorithms,
384 len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700385 free(algorithms);
Shawn Willden128ffe02014-08-06 12:31:33 -0600386}
387
388TEST_F(CheckSupported, SupportedBlockModes) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700389 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
390 device()->get_supported_block_modes(device(), KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT,
391 NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600392
Shawn Willden5b53c992015-02-02 08:05:25 -0700393 size_t len;
394 keymaster_block_mode_t* modes;
395 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE,
396 device()->get_supported_block_modes(device(), KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT,
397 &modes, &len));
Shawn Willden128ffe02014-08-06 12:31:33 -0600398
Shawn Willden76076ab2014-12-18 08:36:35 -0700399 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM,
Shawn Willden5b53c992015-02-02 08:05:25 -0700400 device()->get_supported_block_modes(device(), KM_ALGORITHM_DSA, KM_PURPOSE_ENCRYPT,
401 &modes, &len));
Shawn Willden28e41472014-08-18 13:35:22 -0600402
Shawn Willden5b53c992015-02-02 08:05:25 -0700403 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE,
404 device()->get_supported_block_modes(device(), KM_ALGORITHM_ECDSA, KM_PURPOSE_ENCRYPT,
405 &modes, &len));
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600406
Shawn Willden5b53c992015-02-02 08:05:25 -0700407 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE,
408 device()->get_supported_block_modes(device(), KM_ALGORITHM_AES, KM_PURPOSE_ENCRYPT,
409 &modes, &len));
Shawn Willden128ffe02014-08-06 12:31:33 -0600410}
411
412TEST_F(CheckSupported, SupportedPaddingModes) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700413 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
414 device()->get_supported_padding_modes(device(), KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT,
415 NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600416
Shawn Willden5b53c992015-02-02 08:05:25 -0700417 size_t len;
418 keymaster_padding_t* modes;
419 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_RSA,
420 KM_PURPOSE_SIGN, &modes, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700421 EXPECT_TRUE(ResponseContains(KM_PAD_NONE, modes, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700422 free(modes);
Shawn Willden128ffe02014-08-06 12:31:33 -0600423
Shawn Willden76076ab2014-12-18 08:36:35 -0700424 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM,
425 device()->get_supported_padding_modes(device(), KM_ALGORITHM_DSA, KM_PURPOSE_SIGN,
426 &modes, &len));
Shawn Willden28e41472014-08-18 13:35:22 -0600427
Shawn Willden5b53c992015-02-02 08:05:25 -0700428 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_ECDSA,
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 Willdenc3864dd2014-08-18 15:20:01 -0600432
Shawn Willden5b53c992015-02-02 08:05:25 -0700433 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_AES,
434 KM_PURPOSE_SIGN, &modes, &len));
435 EXPECT_EQ(0, len);
436 free(modes);
Shawn Willden128ffe02014-08-06 12:31:33 -0600437}
438
439TEST_F(CheckSupported, SupportedDigests) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700440 EXPECT_EQ(
441 KM_ERROR_OUTPUT_PARAMETER_NULL,
442 device()->get_supported_digests(device(), KM_ALGORITHM_RSA, KM_PURPOSE_SIGN, NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600443
Shawn Willden5b53c992015-02-02 08:05:25 -0700444 size_t len;
445 keymaster_digest_t* digests;
446 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_RSA,
447 KM_PURPOSE_SIGN, &digests, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700448 EXPECT_TRUE(ResponseContains(KM_DIGEST_NONE, digests, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700449 free(digests);
Shawn Willden128ffe02014-08-06 12:31:33 -0600450
Shawn Willden76076ab2014-12-18 08:36:35 -0700451 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM,
452 device()->get_supported_digests(device(), KM_ALGORITHM_DSA, KM_PURPOSE_SIGN, &digests,
453 &len));
Shawn Willden28e41472014-08-18 13:35:22 -0600454
Shawn Willden5b53c992015-02-02 08:05:25 -0700455 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_ECDSA,
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 Willdenc3864dd2014-08-18 15:20:01 -0600459
Shawn Willden5b53c992015-02-02 08:05:25 -0700460 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_AES,
461 KM_PURPOSE_SIGN, &digests, &len));
462 EXPECT_EQ(0, len);
463 free(digests);
Shawn Willden128ffe02014-08-06 12:31:33 -0600464}
465
466TEST_F(CheckSupported, SupportedImportFormats) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700467 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
468 device()->get_supported_import_formats(device(), KM_ALGORITHM_RSA, NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600469
Shawn Willden5b53c992015-02-02 08:05:25 -0700470 size_t len;
471 keymaster_key_format_t* formats;
472 EXPECT_EQ(KM_ERROR_OK,
473 device()->get_supported_import_formats(device(), KM_ALGORITHM_RSA, &formats, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700474 EXPECT_TRUE(ResponseContains(KM_KEY_FORMAT_PKCS8, formats, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700475 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600476
Shawn Willden76076ab2014-12-18 08:36:35 -0700477 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM,
Shawn Willden5b53c992015-02-02 08:05:25 -0700478 device()->get_supported_import_formats(device(), KM_ALGORITHM_DSA, &formats, &len));
Shawn Willden28e41472014-08-18 13:35:22 -0600479
Shawn Willden5b53c992015-02-02 08:05:25 -0700480 EXPECT_EQ(KM_ERROR_OK,
481 device()->get_supported_import_formats(device(), KM_ALGORITHM_ECDSA, &formats, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700482 EXPECT_TRUE(ResponseContains(KM_KEY_FORMAT_PKCS8, formats, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700483 free(formats);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600484
Shawn Willden5b53c992015-02-02 08:05:25 -0700485 EXPECT_EQ(KM_ERROR_OK,
486 device()->get_supported_import_formats(device(), KM_ALGORITHM_AES, &formats, &len));
487 EXPECT_EQ(0, len);
488 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600489}
490
491TEST_F(CheckSupported, SupportedExportFormats) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700492 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
493 device()->get_supported_export_formats(device(), KM_ALGORITHM_RSA, NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600494
Shawn Willden5b53c992015-02-02 08:05:25 -0700495 size_t len;
496 keymaster_key_format_t* formats;
497 EXPECT_EQ(KM_ERROR_OK,
498 device()->get_supported_export_formats(device(), KM_ALGORITHM_RSA, &formats, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700499 EXPECT_TRUE(ResponseContains(KM_KEY_FORMAT_X509, formats, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700500 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600501
Shawn Willden76076ab2014-12-18 08:36:35 -0700502 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM,
Shawn Willden5b53c992015-02-02 08:05:25 -0700503 device()->get_supported_export_formats(device(), KM_ALGORITHM_DSA, &formats, &len));
Shawn Willden28e41472014-08-18 13:35:22 -0600504
Shawn Willden5b53c992015-02-02 08:05:25 -0700505 EXPECT_EQ(KM_ERROR_OK,
506 device()->get_supported_export_formats(device(), KM_ALGORITHM_ECDSA, &formats, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700507 EXPECT_TRUE(ResponseContains(KM_KEY_FORMAT_X509, formats, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700508 free(formats);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600509
Shawn Willden5b53c992015-02-02 08:05:25 -0700510 EXPECT_EQ(KM_ERROR_OK,
511 device()->get_supported_export_formats(device(), KM_ALGORITHM_AES, &formats, &len));
512 EXPECT_EQ(0, len);
513 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600514}
515
Shawn Willden5b53c992015-02-02 08:05:25 -0700516TEST_F(KeymasterTest, TestFlags) {
517 EXPECT_TRUE(device()->flags & KEYMASTER_SOFTWARE_ONLY);
518 EXPECT_TRUE(device()->flags & KEYMASTER_BLOBS_ARE_STANDALONE);
519 EXPECT_FALSE(device()->flags & KEYMASTER_SUPPORTS_DSA);
520 EXPECT_TRUE(device()->flags & KEYMASTER_SUPPORTS_EC);
521}
522
523typedef KeymasterTest OldKeyGeneration;
524
525TEST_F(OldKeyGeneration, Rsa) {
526 keymaster_rsa_keygen_params_t params = {.modulus_size = 256, .public_exponent = 3};
527 uint8_t* key_blob;
528 size_t key_blob_length;
529 EXPECT_EQ(0,
530 device()->generate_keypair(device(), TYPE_RSA, &params, &key_blob, &key_blob_length));
531 EXPECT_GT(key_blob_length, 0);
532
533 free(key_blob);
534}
535
536TEST_F(OldKeyGeneration, Ecdsa) {
537
538 keymaster_ec_keygen_params_t params = {.field_size = 256};
539 uint8_t* key_blob;
540 size_t key_blob_length;
541 EXPECT_EQ(0,
542 device()->generate_keypair(device(), TYPE_EC, &params, &key_blob, &key_blob_length));
543 EXPECT_GT(key_blob_length, 0);
544
545 free(key_blob);
546}
547
Shawn Willdend0772312014-09-18 12:27:57 -0600548class NewKeyGeneration : public KeymasterTest {
549 protected:
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700550 void CheckBaseParams() {
551 EXPECT_EQ(0U, hw_enforced().size());
552 EXPECT_EQ(12U, hw_enforced().SerializedSize());
Shawn Willdend0772312014-09-18 12:27:57 -0600553
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700554 AuthorizationSet auths = sw_enforced();
555 EXPECT_GT(auths.SerializedSize(), 12U);
556
Shawn Willden5b53c992015-02-02 08:05:25 -0700557 EXPECT_TRUE(contains(auths, TAG_PURPOSE, KM_PURPOSE_SIGN));
558 EXPECT_TRUE(contains(auths, TAG_PURPOSE, KM_PURPOSE_VERIFY));
559 EXPECT_TRUE(contains(auths, TAG_USER_ID, 7));
560 EXPECT_TRUE(contains(auths, TAG_USER_AUTH_ID, 8));
561 EXPECT_TRUE(contains(auths, TAG_AUTH_TIMEOUT, 300));
Shawn Willdend0772312014-09-18 12:27:57 -0600562
563 // Verify that App ID, App data and ROT are NOT included.
Shawn Willden5b53c992015-02-02 08:05:25 -0700564 EXPECT_FALSE(contains(auths, TAG_ROOT_OF_TRUST));
565 EXPECT_FALSE(contains(auths, TAG_APPLICATION_ID));
566 EXPECT_FALSE(contains(auths, TAG_APPLICATION_DATA));
Shawn Willdend0772312014-09-18 12:27:57 -0600567
568 // Just for giggles, check that some unexpected tags/values are NOT present.
Shawn Willden5b53c992015-02-02 08:05:25 -0700569 EXPECT_FALSE(contains(auths, TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
570 EXPECT_FALSE(contains(auths, TAG_PURPOSE, KM_PURPOSE_DECRYPT));
571 EXPECT_FALSE(contains(auths, TAG_AUTH_TIMEOUT, 301));
Shawn Willdend0772312014-09-18 12:27:57 -0600572
573 // Now check that unspecified, defaulted tags are correct.
Shawn Willden5b53c992015-02-02 08:05:25 -0700574 EXPECT_TRUE(contains(auths, TAG_ORIGIN, KM_ORIGIN_SOFTWARE));
575 EXPECT_TRUE(contains(auths, KM_TAG_CREATION_DATETIME));
Shawn Willdend0772312014-09-18 12:27:57 -0600576 }
Shawn Willden2079ae82015-01-22 13:42:31 -0700577};
578
Shawn Willden128ffe02014-08-06 12:31:33 -0600579TEST_F(NewKeyGeneration, Rsa) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700580 ASSERT_EQ(KM_ERROR_OK,
581 GenerateKey(ParamBuilder().RsaSigningKey(256, KM_DIGEST_NONE, KM_PAD_NONE, 3)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700582 CheckBaseParams();
Shawn Willden128ffe02014-08-06 12:31:33 -0600583
Shawn Willden5b53c992015-02-02 08:05:25 -0700584 // Check specified tags are all present in auths
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700585 AuthorizationSet auths(sw_enforced());
Shawn Willden5b53c992015-02-02 08:05:25 -0700586 EXPECT_TRUE(contains(auths, TAG_ALGORITHM, KM_ALGORITHM_RSA));
587 EXPECT_TRUE(contains(auths, TAG_KEY_SIZE, 256));
588 EXPECT_TRUE(contains(auths, TAG_RSA_PUBLIC_EXPONENT, 3));
Shawn Willden128ffe02014-08-06 12:31:33 -0600589}
590
Shawn Willden6bbe6782014-09-18 11:26:15 -0600591TEST_F(NewKeyGeneration, RsaDefaultSize) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700592 // TODO(swillden): Remove support for defaulting RSA parameter size and pub exponent.
Shawn Willdenc24c1102014-12-22 15:30:09 -0700593 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey()));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700594 CheckBaseParams();
Shawn Willden6bbe6782014-09-18 11:26:15 -0600595
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700596 // Check specified tags are all present in unenforced characteristics
597 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_RSA));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600598
599 // Now check that unspecified, defaulted tags are correct.
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700600 EXPECT_TRUE(contains(sw_enforced(), TAG_RSA_PUBLIC_EXPONENT, 65537));
601 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 2048));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600602}
603
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600604TEST_F(NewKeyGeneration, Ecdsa) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700605 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().EcdsaSigningKey(224)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700606 CheckBaseParams();
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600607
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700608 // Check specified tags are all present in unenforced characteristics
609 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
610 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 224));
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600611}
612
Shawn Willden6bbe6782014-09-18 11:26:15 -0600613TEST_F(NewKeyGeneration, EcdsaDefaultSize) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700614 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().EcdsaSigningKey()));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700615 CheckBaseParams();
Shawn Willden6bbe6782014-09-18 11:26:15 -0600616
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700617 // Check specified tags are all present in unenforced characteristics
618 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600619
620 // Now check that unspecified, defaulted tags are correct.
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700621 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 224));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600622}
623
624TEST_F(NewKeyGeneration, EcdsaInvalidSize) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700625 ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE, GenerateKey(ParamBuilder().EcdsaSigningKey(190)));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600626}
627
628TEST_F(NewKeyGeneration, EcdsaAllValidSizes) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600629 size_t valid_sizes[] = {224, 256, 384, 521};
Shawn Willden6bbe6782014-09-18 11:26:15 -0600630 for (size_t size : valid_sizes) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700631 EXPECT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().EcdsaSigningKey(size)))
Shawn Willden5b53c992015-02-02 08:05:25 -0700632 << "Failed to generate size: " << size;
Shawn Willden6bbe6782014-09-18 11:26:15 -0600633 }
634}
635
Shawn Willden19fca882015-01-22 16:35:30 -0700636TEST_F(NewKeyGeneration, AesOcb) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700637 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willden19fca882015-01-22 16:35:30 -0700638}
639
640TEST_F(NewKeyGeneration, AesOcbInvalidKeySize) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700641 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(136).OcbMode(4096, 16)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700642 EXPECT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willden19fca882015-01-22 16:35:30 -0700643}
644
645TEST_F(NewKeyGeneration, AesOcbAllValidSizes) {
Shawn Willden19fca882015-01-22 16:35:30 -0700646 size_t valid_sizes[] = {128, 192, 256};
647 for (size_t size : valid_sizes) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700648 EXPECT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(size)))
Shawn Willden5b53c992015-02-02 08:05:25 -0700649 << "Failed to generate size: " << size;
Shawn Willden19fca882015-01-22 16:35:30 -0700650 }
651}
652
Shawn Willden0d560bf2014-12-15 17:44:02 -0700653TEST_F(NewKeyGeneration, HmacSha256) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700654 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_256, 16)));
Shawn Willden0d560bf2014-12-15 17:44:02 -0700655}
656
Shawn Willden76364712014-08-11 17:48:04 -0600657typedef KeymasterTest GetKeyCharacteristics;
658TEST_F(GetKeyCharacteristics, SimpleRsa) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700659 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey(256)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700660 AuthorizationSet original(sw_enforced());
Shawn Willden76364712014-08-11 17:48:04 -0600661
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700662 ASSERT_EQ(KM_ERROR_OK, GetCharacteristics());
663 EXPECT_EQ(original, sw_enforced());
Shawn Willden76364712014-08-11 17:48:04 -0600664}
665
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700666typedef KeymasterTest SigningOperationsTest;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600667TEST_F(SigningOperationsTest, RsaSuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700668 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey(256)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700669 string message = "12345678901234567890123456789012";
670 string signature;
671 SignMessage(message, &signature);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600672}
673
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600674TEST_F(SigningOperationsTest, EcdsaSuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700675 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().EcdsaSigningKey(224)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700676 string message = "123456789012345678901234567890123456789012345678";
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700677 string signature;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700678 SignMessage(message, &signature);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600679}
680
Shawn Willden1615f2e2014-08-13 10:37:40 -0600681TEST_F(SigningOperationsTest, RsaAbort) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700682 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey(256)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700683 ASSERT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_SIGN));
684 EXPECT_EQ(KM_ERROR_OK, AbortOperation());
685 // Another abort should fail
686 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, AbortOperation());
Shawn Willden1615f2e2014-08-13 10:37:40 -0600687}
688
689TEST_F(SigningOperationsTest, RsaUnsupportedDigest) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700690 GenerateKey(ParamBuilder().RsaSigningKey(256, KM_DIGEST_SHA_2_256, KM_PAD_NONE));
691 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600692}
693
694TEST_F(SigningOperationsTest, RsaUnsupportedPadding) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700695 GenerateKey(ParamBuilder().RsaSigningKey(256, KM_DIGEST_NONE, KM_PAD_RSA_OAEP));
696 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600697}
698
699TEST_F(SigningOperationsTest, RsaNoDigest) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700700 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaKey(256).SigningKey().Option(
701 TAG_PADDING, KM_PAD_NONE)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700702 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600703}
704
705TEST_F(SigningOperationsTest, RsaNoPadding) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700706 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaKey(256).SigningKey().Option(
707 TAG_DIGEST, KM_DIGEST_NONE)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700708 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600709}
710
Shawn Willden62c22862014-12-17 08:36:20 -0700711TEST_F(SigningOperationsTest, HmacSha224Success) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700712 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_224, 28)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700713 string message = "12345678901234567890123456789012";
714 string signature;
715 SignMessage(message, &signature);
716 ASSERT_EQ(28, signature.size());
Shawn Willden62c22862014-12-17 08:36:20 -0700717}
718
Shawn Willden0d560bf2014-12-15 17:44:02 -0700719TEST_F(SigningOperationsTest, HmacSha256Success) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700720 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_256, 32)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700721 string message = "12345678901234567890123456789012";
722 string signature;
723 SignMessage(message, &signature);
724 ASSERT_EQ(32, signature.size());
Shawn Willden0d560bf2014-12-15 17:44:02 -0700725}
726
Shawn Willden62c22862014-12-17 08:36:20 -0700727TEST_F(SigningOperationsTest, HmacSha384Success) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700728 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_384, 48)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700729 string message = "12345678901234567890123456789012";
730 string signature;
731 SignMessage(message, &signature);
732 ASSERT_EQ(48, signature.size());
Shawn Willden62c22862014-12-17 08:36:20 -0700733}
734
735TEST_F(SigningOperationsTest, HmacSha512Success) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700736 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_512, 64)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700737 string message = "12345678901234567890123456789012";
Shawn Willden62c22862014-12-17 08:36:20 -0700738 string signature;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700739 SignMessage(message, &signature);
740 ASSERT_EQ(64, signature.size());
Shawn Willden62c22862014-12-17 08:36:20 -0700741}
742
743// TODO(swillden): Add HMACSHA{224|256|384|512} tests that validates against the test vectors from
744// RFC4231. Doing that requires being able to import keys, rather than just
745// generate them randomly.
Shawn Willden0d560bf2014-12-15 17:44:02 -0700746
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700747TEST_F(SigningOperationsTest, HmacSha256NoMacLength) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700748 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder()
749 .Option(TAG_ALGORITHM, KM_ALGORITHM_HMAC)
750 .Option(TAG_KEY_SIZE, 128)
751 .SigningKey()
752 .Option(TAG_DIGEST, KM_DIGEST_SHA_2_256)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700753 EXPECT_EQ(KM_ERROR_UNSUPPORTED_MAC_LENGTH, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden0d560bf2014-12-15 17:44:02 -0700754}
755
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700756TEST_F(SigningOperationsTest, HmacSha256TooLargeMacLength) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700757 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_256, 33)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700758 ASSERT_EQ(KM_ERROR_UNSUPPORTED_MAC_LENGTH, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden0d560bf2014-12-15 17:44:02 -0700759}
760
Shawn Willden1615f2e2014-08-13 10:37:40 -0600761TEST_F(SigningOperationsTest, RsaTooShortMessage) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700762 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey(256)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700763 ASSERT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700764
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700765 string message = "1234567890123456789012345678901";
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700766 string result;
767 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700768 ASSERT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700769 EXPECT_EQ(0U, result.size());
770 EXPECT_EQ(31U, input_consumed);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600771
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700772 string signature;
773 ASSERT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&signature));
774 EXPECT_EQ(0U, signature.length());
Shawn Willden43e999e2014-08-13 13:29:50 -0600775}
776
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700777typedef KeymasterTest VerificationOperationsTest;
Shawn Willden43e999e2014-08-13 13:29:50 -0600778TEST_F(VerificationOperationsTest, RsaSuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700779 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey(256)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700780 string message = "12345678901234567890123456789012";
781 string signature;
782 SignMessage(message, &signature);
783 VerifyMessage(message, signature);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600784}
785
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600786TEST_F(VerificationOperationsTest, EcdsaSuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700787 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().EcdsaSigningKey(256)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700788 string message = "123456789012345678901234567890123456789012345678";
789 string signature;
790 SignMessage(message, &signature);
791 VerifyMessage(message, signature);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600792}
793
Shawn Willden0d560bf2014-12-15 17:44:02 -0700794TEST_F(VerificationOperationsTest, HmacSha256Success) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700795 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_256, 16)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700796 string message = "123456789012345678901234567890123456789012345678";
Shawn Willden0d560bf2014-12-15 17:44:02 -0700797 string signature;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700798 SignMessage(message, &signature);
799 VerifyMessage(message, signature);
Shawn Willden0d560bf2014-12-15 17:44:02 -0700800}
801
Shawn Willden5b53c992015-02-02 08:05:25 -0700802typedef VerificationOperationsTest ExportKeyTest;
Shawn Willdenffd790c2014-08-18 21:20:06 -0600803TEST_F(ExportKeyTest, RsaSuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700804 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey(256)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700805 string export_data;
806 ASSERT_EQ(KM_ERROR_OK, ExportKey(KM_KEY_FORMAT_X509, &export_data));
807 EXPECT_GT(export_data.length(), 0);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600808
809 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willdenffd790c2014-08-18 21:20:06 -0600810}
811
Shawn Willdenf268d742014-08-19 15:36:26 -0600812TEST_F(ExportKeyTest, EcdsaSuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700813 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().EcdsaSigningKey(224)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700814 string export_data;
815 ASSERT_EQ(KM_ERROR_OK, ExportKey(KM_KEY_FORMAT_X509, &export_data));
816 EXPECT_GT(export_data.length(), 0);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600817
818 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willdenf268d742014-08-19 15:36:26 -0600819}
820
821TEST_F(ExportKeyTest, RsaUnsupportedKeyFormat) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700822 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey(256)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700823 string export_data;
824 ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_FORMAT, ExportKey(KM_KEY_FORMAT_PKCS8, &export_data));
Shawn Willdenf268d742014-08-19 15:36:26 -0600825}
826
827TEST_F(ExportKeyTest, RsaCorruptedKeyBlob) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700828 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey(256)));
Shawn Willden5b53c992015-02-02 08:05:25 -0700829 corrupt_key_blob();
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700830 string export_data;
831 ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, ExportKey(KM_KEY_FORMAT_X509, &export_data));
Shawn Willdenf268d742014-08-19 15:36:26 -0600832}
833
Shawn Willden437fbd12014-08-20 11:59:49 -0600834static string read_file(const string& file_name) {
835 ifstream file_stream(file_name, std::ios::binary);
836 istreambuf_iterator<char> file_begin(file_stream);
837 istreambuf_iterator<char> file_end;
838 return string(file_begin, file_end);
839}
840
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700841typedef VerificationOperationsTest ImportKeyTest;
Shawn Willden5b53c992015-02-02 08:05:25 -0700842TEST_F(ImportKeyTest, RsaSuccess) {
Shawn Willden81effc62014-08-27 10:08:46 -0600843 string pk8_key = read_file("rsa_privkey_pk8.der");
Shawn Willden437fbd12014-08-20 11:59:49 -0600844 ASSERT_EQ(633U, pk8_key.size());
845
Shawn Willdena278f612014-12-23 11:22:21 -0700846 ASSERT_EQ(KM_ERROR_OK, ImportKey(ParamBuilder().RsaSigningKey().NoDigestOrPadding(),
Shawn Willdenc24c1102014-12-22 15:30:09 -0700847 KM_KEY_FORMAT_PKCS8, pk8_key));
Shawn Willden437fbd12014-08-20 11:59:49 -0600848
849 // Check values derived from the key.
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700850 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_RSA));
851 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 1024));
852 EXPECT_TRUE(contains(sw_enforced(), TAG_RSA_PUBLIC_EXPONENT, 65537U));
Shawn Willden437fbd12014-08-20 11:59:49 -0600853
854 // And values provided by GoogleKeymaster
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700855 EXPECT_TRUE(contains(sw_enforced(), TAG_ORIGIN, KM_ORIGIN_IMPORTED));
856 EXPECT_TRUE(contains(sw_enforced(), KM_TAG_CREATION_DATETIME));
Shawn Willden437fbd12014-08-20 11:59:49 -0600857
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700858 string message(1024 / 8, 'a');
859 string signature;
860 SignMessage(message, &signature);
861 VerifyMessage(message, signature);
Shawn Willden437fbd12014-08-20 11:59:49 -0600862}
863
Shawn Willden6bbe6782014-09-18 11:26:15 -0600864TEST_F(ImportKeyTest, RsaKeySizeMismatch) {
Shawn Willden6bbe6782014-09-18 11:26:15 -0600865 string pk8_key = read_file("rsa_privkey_pk8.der");
866 ASSERT_EQ(633U, pk8_key.size());
Shawn Willden5b53c992015-02-02 08:05:25 -0700867 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
Shawn Willdenc24c1102014-12-22 15:30:09 -0700868 ImportKey(ParamBuilder()
Shawn Willdena278f612014-12-23 11:22:21 -0700869 .RsaSigningKey(2048) // Size doesn't match key
Shawn Willdenc24c1102014-12-22 15:30:09 -0700870 .NoDigestOrPadding(),
871 KM_KEY_FORMAT_PKCS8, pk8_key));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600872}
873
874TEST_F(ImportKeyTest, RsaPublicExponenMismatch) {
Shawn Willden6bbe6782014-09-18 11:26:15 -0600875 string pk8_key = read_file("rsa_privkey_pk8.der");
876 ASSERT_EQ(633U, pk8_key.size());
Shawn Willden5b53c992015-02-02 08:05:25 -0700877 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
Shawn Willdenc24c1102014-12-22 15:30:09 -0700878 ImportKey(ParamBuilder()
Shawn Willdena278f612014-12-23 11:22:21 -0700879 .RsaSigningKey()
Shawn Willdenc24c1102014-12-22 15:30:09 -0700880 .Option(TAG_RSA_PUBLIC_EXPONENT, 3) // Doesn't match key
881 .NoDigestOrPadding(),
882 KM_KEY_FORMAT_PKCS8, pk8_key));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600883}
884
Shawn Willden81effc62014-08-27 10:08:46 -0600885TEST_F(ImportKeyTest, EcdsaSuccess) {
Shawn Willden81effc62014-08-27 10:08:46 -0600886 string pk8_key = read_file("ec_privkey_pk8.der");
887 ASSERT_EQ(138U, pk8_key.size());
888
Shawn Willdena278f612014-12-23 11:22:21 -0700889 ASSERT_EQ(KM_ERROR_OK,
890 ImportKey(ParamBuilder().EcdsaSigningKey(), KM_KEY_FORMAT_PKCS8, pk8_key));
Shawn Willden81effc62014-08-27 10:08:46 -0600891
892 // Check values derived from the key.
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700893 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
894 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 256));
Shawn Willden81effc62014-08-27 10:08:46 -0600895
896 // And values provided by GoogleKeymaster
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700897 EXPECT_TRUE(contains(sw_enforced(), TAG_ORIGIN, KM_ORIGIN_IMPORTED));
898 EXPECT_TRUE(contains(sw_enforced(), KM_TAG_CREATION_DATETIME));
Shawn Willden81effc62014-08-27 10:08:46 -0600899
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700900 string message(1024 / 8, 'a');
901 string signature;
902 SignMessage(message, &signature);
903 VerifyMessage(message, signature);
Shawn Willden81effc62014-08-27 10:08:46 -0600904}
905
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700906TEST_F(ImportKeyTest, EcdsaSizeSpecified) {
907 string pk8_key = read_file("ec_privkey_pk8.der");
908 ASSERT_EQ(138U, pk8_key.size());
Shawn Willden6bbe6782014-09-18 11:26:15 -0600909
Shawn Willdena278f612014-12-23 11:22:21 -0700910 ASSERT_EQ(KM_ERROR_OK,
911 ImportKey(ParamBuilder().EcdsaSigningKey(256), KM_KEY_FORMAT_PKCS8, pk8_key));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600912
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700913 // Check values derived from the key.
914 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
915 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 256));
916
917 // And values provided by GoogleKeymaster
918 EXPECT_TRUE(contains(sw_enforced(), TAG_ORIGIN, KM_ORIGIN_IMPORTED));
919 EXPECT_TRUE(contains(sw_enforced(), KM_TAG_CREATION_DATETIME));
920
921 string message(1024 / 8, 'a');
922 string signature;
923 SignMessage(message, &signature);
924 VerifyMessage(message, signature);
925}
926
927TEST_F(ImportKeyTest, EcdsaSizeMismatch) {
928 string pk8_key = read_file("ec_privkey_pk8.der");
929 ASSERT_EQ(138U, pk8_key.size());
Shawn Willden5b53c992015-02-02 08:05:25 -0700930 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
Shawn Willdena278f612014-12-23 11:22:21 -0700931 ImportKey(ParamBuilder().EcdsaSigningKey(224), // Size does not match key
932 KM_KEY_FORMAT_PKCS8, pk8_key));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600933}
934
Shawn Willden2665e862014-11-24 14:46:21 -0700935typedef KeymasterTest VersionTest;
936TEST_F(VersionTest, GetVersion) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700937 uint8_t major, minor, subminor;
938 ASSERT_EQ(KM_ERROR_OK, GetVersion(&major, &minor, &subminor));
939 EXPECT_EQ(1, major);
940 EXPECT_EQ(0, minor);
941 EXPECT_EQ(0, subminor);
Shawn Willden2665e862014-11-24 14:46:21 -0700942}
943
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700944typedef KeymasterTest EncryptionOperationsTest;
Shawn Willden4200f212014-12-02 07:01:21 -0700945TEST_F(EncryptionOperationsTest, RsaOaepSuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700946 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_OAEP)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700947
948 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -0700949 string ciphertext1 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -0700950 EXPECT_EQ(512 / 8, ciphertext1.size());
951
Shawn Willden6dde87c2014-12-11 14:08:48 -0700952 string ciphertext2 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -0700953 EXPECT_EQ(512 / 8, ciphertext2.size());
954
955 // OAEP randomizes padding so every result should be different.
956 EXPECT_NE(ciphertext1, ciphertext2);
957}
958
959TEST_F(EncryptionOperationsTest, RsaOaepRoundTrip) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700960 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_OAEP)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700961 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -0700962 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -0700963 EXPECT_EQ(512 / 8, ciphertext.size());
964
Shawn Willden6dde87c2014-12-11 14:08:48 -0700965 string plaintext = DecryptMessage(ciphertext);
Shawn Willden4200f212014-12-02 07:01:21 -0700966 EXPECT_EQ(message, plaintext);
967}
968
969TEST_F(EncryptionOperationsTest, RsaOaepTooLarge) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700970 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_OAEP)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700971 string message = "12345678901234567890123";
Shawn Willden4200f212014-12-02 07:01:21 -0700972 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -0700973 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -0700974
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700975 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT));
976 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700977 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -0700978 EXPECT_EQ(0, result.size());
979}
980
981TEST_F(EncryptionOperationsTest, RsaOaepCorruptedDecrypt) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700982 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_OAEP)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700983 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -0700984 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -0700985 EXPECT_EQ(512 / 8, ciphertext.size());
986
987 // Corrupt the ciphertext
988 ciphertext[512 / 8 / 2]++;
989
Shawn Willden4200f212014-12-02 07:01:21 -0700990 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -0700991 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700992 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
993 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700994 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -0700995 EXPECT_EQ(0, result.size());
996}
997
998TEST_F(EncryptionOperationsTest, RsaPkcs1Success) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700999 ASSERT_EQ(KM_ERROR_OK,
1000 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_PKCS1_1_5_ENCRYPT)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001001 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001002 string ciphertext1 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001003 EXPECT_EQ(512 / 8, ciphertext1.size());
1004
Shawn Willden6dde87c2014-12-11 14:08:48 -07001005 string ciphertext2 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001006 EXPECT_EQ(512 / 8, ciphertext2.size());
1007
1008 // PKCS1 v1.5 randomizes padding so every result should be different.
1009 EXPECT_NE(ciphertext1, ciphertext2);
1010}
1011
1012TEST_F(EncryptionOperationsTest, RsaPkcs1RoundTrip) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001013 ASSERT_EQ(KM_ERROR_OK,
1014 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_PKCS1_1_5_ENCRYPT)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001015 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001016 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001017 EXPECT_EQ(512 / 8, ciphertext.size());
1018
Shawn Willden6dde87c2014-12-11 14:08:48 -07001019 string plaintext = DecryptMessage(ciphertext);
Shawn Willden4200f212014-12-02 07:01:21 -07001020 EXPECT_EQ(message, plaintext);
1021}
1022
1023TEST_F(EncryptionOperationsTest, RsaPkcs1TooLarge) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001024 ASSERT_EQ(KM_ERROR_OK,
1025 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_PKCS1_1_5_ENCRYPT)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001026 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 Willdenc24c1102014-12-22 15:30:09 -07001037 ASSERT_EQ(KM_ERROR_OK,
1038 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_PKCS1_1_5_ENCRYPT)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001039 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001040 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001041 EXPECT_EQ(512 / 8, ciphertext.size());
1042
1043 // Corrupt the ciphertext
1044 ciphertext[512 / 8 / 2]++;
1045
Shawn Willden4200f212014-12-02 07:01:21 -07001046 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001047 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001048 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
1049 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001050 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -07001051 EXPECT_EQ(0, result.size());
1052}
1053
Shawn Willden907c3012014-12-08 15:51:55 -07001054TEST_F(EncryptionOperationsTest, AesOcbSuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001055 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001056 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001057 string ciphertext1 = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001058 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext1.size());
Shawn Willden907c3012014-12-08 15:51:55 -07001059
Shawn Willden6dde87c2014-12-11 14:08:48 -07001060 string ciphertext2 = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001061 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext2.size());
Shawn Willden907c3012014-12-08 15:51:55 -07001062
1063 // OCB uses a random nonce, so every output should be different
1064 EXPECT_NE(ciphertext1, ciphertext2);
1065}
1066
Shawn Willden6dde87c2014-12-11 14:08:48 -07001067TEST_F(EncryptionOperationsTest, AesOcbRoundTripSuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001068 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001069 string message = "Hello World!";
1070 string ciphertext = EncryptMessage(message);
1071 EXPECT_EQ(12 /* nonce */ + message.length() + 16 /* tag */, ciphertext.size());
1072
1073 string plaintext = DecryptMessage(ciphertext);
1074 EXPECT_EQ(message, plaintext);
1075}
1076
1077TEST_F(EncryptionOperationsTest, AesOcbRoundTripCorrupted) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001078 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001079 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001080 string ciphertext = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001081 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext.size());
Shawn Willden6dde87c2014-12-11 14:08:48 -07001082
1083 ciphertext[ciphertext.size() / 2]++;
1084
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001085 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001086
1087 string result;
1088 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001089 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001090 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001091 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001092}
1093
1094TEST_F(EncryptionOperationsTest, AesDecryptGarbage) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001095 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001096 string ciphertext(128, 'a');
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001097 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001098
1099 string result;
1100 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001101 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001102 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001103 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001104}
1105
1106TEST_F(EncryptionOperationsTest, AesDecryptTooShort) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001107 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001108
Shawn Willden6dde87c2014-12-11 14:08:48 -07001109 // Try decrypting garbage ciphertext that is too short to be valid (< nonce + tag).
Shawn Willden6dde87c2014-12-11 14:08:48 -07001110 string ciphertext(12 + 15, 'a');
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001111 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001112
1113 string result;
1114 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001115 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001116 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001117 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001118}
1119
1120TEST_F(EncryptionOperationsTest, AesOcbRoundTripEmptySuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001121 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001122 string message = "";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001123 string ciphertext = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001124 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext.size());
Shawn Willden6dde87c2014-12-11 14:08:48 -07001125
1126 string plaintext = DecryptMessage(ciphertext);
1127 EXPECT_EQ(message, plaintext);
1128}
1129
1130TEST_F(EncryptionOperationsTest, AesOcbRoundTripEmptyCorrupted) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001131 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001132 string message = "";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001133 string ciphertext = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001134 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext.size());
Shawn Willden6dde87c2014-12-11 14:08:48 -07001135
1136 ciphertext[ciphertext.size() / 2]++;
1137
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001138 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001139
1140 string result;
1141 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001142 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001143 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001144 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001145}
1146
1147TEST_F(EncryptionOperationsTest, AesOcbFullChunk) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001148 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001149 string message(4096, 'a');
1150 string ciphertext = EncryptMessage(message);
1151 EXPECT_EQ(12 /* nonce */ + message.length() + 16 /* tag */, ciphertext.size());
1152
1153 string plaintext = DecryptMessage(ciphertext);
1154 EXPECT_EQ(message, plaintext);
1155}
1156
1157TEST_F(EncryptionOperationsTest, AesOcbVariousChunkLengths) {
1158 for (unsigned chunk_length = 1; chunk_length <= 128; ++chunk_length) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001159 ASSERT_EQ(KM_ERROR_OK,
1160 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 Willdenc24c1102014-12-22 15:30:09 -07001176 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001177 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 Willdenc24c1102014-12-22 15:30:09 -07001189 EXPECT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder()
1190 .AesEncryptionKey(128)
1191 .Option(TAG_BLOCK_MODE, KM_MODE_OCB)
1192 .Option(TAG_MAC_LENGTH, 16)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001193 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