blob: bb19ada47793ee794a4893cde9585c1762f6ce3b [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) {
Shawn Willdenf0f68b92014-12-30 16:03:28 -070038 ERR_load_crypto_strings();
Shawn Willden128ffe02014-08-06 12:31:33 -060039 ::testing::InitGoogleTest(&argc, argv);
40 int result = RUN_ALL_TESTS();
41 // Clean up stuff OpenSSL leaves around, so Valgrind doesn't complain.
42 CRYPTO_cleanup_all_ex_data();
Shawn Willden7c0a82b2014-09-17 12:57:32 -060043 ERR_remove_thread_state(NULL);
Shawn Willden128ffe02014-08-06 12:31:33 -060044 ERR_free_strings();
45 return result;
46}
47
Shawn Willden63ac0432014-12-29 14:07:08 -070048template <typename T> std::ostream& operator<<(std::ostream& os, const std::vector<T>& vec) {
49 os << "{ ";
50 bool first = true;
51 for (T t : vec) {
52 os << (first ? "" : ", ") << t;
53 if (first)
54 first = false;
55 }
56 os << " }";
57 return os;
58}
59
Shawn Willden128ffe02014-08-06 12:31:33 -060060namespace keymaster {
61namespace test {
62
Shawn Willdenb15d77e2014-12-17 16:44:29 -070063/**
64 * Utility class to make construction of AuthorizationSets easy, and readable. Use like:
65 *
66 * ParamBuilder()
67 * .Option(TAG_ALGORITHM, KM_ALGORITHM_RSA)
68 * .Option(TAG_KEY_SIZE, 512)
69 * .Option(TAG_DIGEST, KM_DIGEST_NONE)
70 * .Option(TAG_PADDING, KM_PAD_NONE)
71 * .Option(TAG_SINGLE_USE_PER_BOOT, true)
72 * .build();
73 *
74 * In addition there are methods that add common sets of parameters, like RsaSigningKey().
75 */
76class ParamBuilder {
77 public:
78 template <typename TagType, typename ValueType>
79 ParamBuilder& Option(TagType tag, ValueType value) {
80 set.push_back(tag, value);
81 return *this;
82 }
83
84 ParamBuilder& RsaKey(uint32_t key_size = 0, uint64_t public_exponent = 0) {
85 Option(TAG_ALGORITHM, KM_ALGORITHM_RSA);
86 if (key_size != 0)
87 Option(TAG_KEY_SIZE, key_size);
88 if (public_exponent != 0)
89 Option(TAG_RSA_PUBLIC_EXPONENT, public_exponent);
90 return *this;
91 }
92
93 ParamBuilder& EcdsaKey(uint32_t key_size = 0) {
94 Option(TAG_ALGORITHM, KM_ALGORITHM_ECDSA);
95 if (key_size != 0)
96 Option(TAG_KEY_SIZE, key_size);
97 return *this;
98 }
99
100 ParamBuilder& AesKey(uint32_t key_size) {
101 Option(TAG_ALGORITHM, KM_ALGORITHM_AES);
102 return Option(TAG_KEY_SIZE, key_size);
103 }
104
105 ParamBuilder& HmacKey(uint32_t key_size, keymaster_digest_t digest, uint32_t mac_length) {
106 Option(TAG_ALGORITHM, KM_ALGORITHM_HMAC);
107 Option(TAG_KEY_SIZE, key_size);
108 SigningKey();
109 Option(TAG_DIGEST, digest);
110 return Option(TAG_MAC_LENGTH, mac_length);
111 }
112
113 ParamBuilder& RsaSigningKey(uint32_t key_size = 0, keymaster_digest_t digest = KM_DIGEST_NONE,
114 keymaster_padding_t padding = KM_PAD_NONE,
115 uint64_t public_exponent = 0) {
116 RsaKey(key_size, public_exponent);
117 SigningKey();
118 Option(TAG_DIGEST, digest);
119 return Option(TAG_PADDING, padding);
120 }
121
122 ParamBuilder& RsaEncryptionKey(uint32_t key_size = 0,
123 keymaster_padding_t padding = KM_PAD_RSA_OAEP,
124 uint64_t public_exponent = 0) {
125 RsaKey(key_size, public_exponent);
126 EncryptionKey();
127 return Option(TAG_PADDING, padding);
128 }
129
130 ParamBuilder& EcdsaSigningKey(uint32_t key_size = 0) {
131 EcdsaKey(key_size);
132 return SigningKey();
133 }
134
135 ParamBuilder& AesEncryptionKey(uint32_t key_size) {
136 AesKey(key_size);
137 return EncryptionKey();
138 }
139
140 ParamBuilder& SigningKey() {
141 Option(TAG_PURPOSE, KM_PURPOSE_SIGN);
142 return Option(TAG_PURPOSE, KM_PURPOSE_VERIFY);
143 }
144
145 ParamBuilder& EncryptionKey() {
146 Option(TAG_PURPOSE, KM_PURPOSE_ENCRYPT);
147 return Option(TAG_PURPOSE, KM_PURPOSE_DECRYPT);
148 }
149
150 ParamBuilder& NoDigestOrPadding() {
151 Option(TAG_DIGEST, KM_DIGEST_NONE);
152 return Option(TAG_PADDING, KM_PAD_NONE);
153 }
154
155 ParamBuilder& OcbMode(uint32_t chunk_length, uint32_t mac_length) {
156 Option(TAG_BLOCK_MODE, KM_MODE_OCB);
157 Option(TAG_CHUNK_LENGTH, chunk_length);
158 return Option(TAG_MAC_LENGTH, mac_length);
159 }
160
161 AuthorizationSet build() const { return set; }
162
163 private:
164 AuthorizationSet set;
Shawn Willden6bbe6782014-09-18 11:26:15 -0600165};
166
Shawn Willden567a4a02014-12-31 12:14:46 -0700167StdoutLogger logger;
168
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700169const uint64_t OP_HANDLE_SENTINEL = 0xFFFFFFFFFFFFFFFF;
Shawn Willden128ffe02014-08-06 12:31:33 -0600170class KeymasterTest : public testing::Test {
171 protected:
Shawn Willden567a4a02014-12-31 12:14:46 -0700172 KeymasterTest() : out_params_(NULL), op_handle_(OP_HANDLE_SENTINEL), characteristics_(NULL) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700173 blob_.key_material = NULL;
174 RAND_seed("foobar", 6);
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700175 blob_.key_material = 0;
Shawn Willden5b53c992015-02-02 08:05:25 -0700176 }
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700177
Shawn Willden5b53c992015-02-02 08:05:25 -0700178 ~KeymasterTest() {
179 FreeCharacteristics();
180 FreeKeyBlob();
Shawn Willdend0772312014-09-18 12:27:57 -0600181 }
182
Shawn Willden30255022015-02-24 14:00:21 -0700183 keymaster1_device_t* device() {
184 return reinterpret_cast<keymaster1_device_t*>(device_.hw_device());
185 }
Shawn Willden5b53c992015-02-02 08:05:25 -0700186
Shawn Willdenc24c1102014-12-22 15:30:09 -0700187 keymaster_error_t GenerateKey(const ParamBuilder& builder) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700188 AuthorizationSet params(builder.build());
189 params.push_back(UserAuthParams());
190 params.push_back(ClientParams());
191
Shawn Willden0d560bf2014-12-15 17:44:02 -0700192 FreeKeyBlob();
193 FreeCharacteristics();
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700194 return device()->generate_key(device(), params.data(), params.size(), &blob_,
195 &characteristics_);
Shawn Willden0d560bf2014-12-15 17:44:02 -0700196 }
197
Shawn Willdenc24c1102014-12-22 15:30:09 -0700198 keymaster_error_t ImportKey(const ParamBuilder& builder, keymaster_key_format_t format,
199 const string& key_material) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700200 AuthorizationSet params(builder.build());
201 params.push_back(UserAuthParams());
202 params.push_back(ClientParams());
203
204 FreeKeyBlob();
205 FreeCharacteristics();
206 return device()->import_key(device(), params.data(), params.size(), format,
207 reinterpret_cast<const uint8_t*>(key_material.c_str()),
208 key_material.length(), &blob_, &characteristics_);
209 }
210
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700211 AuthorizationSet UserAuthParams() {
212 AuthorizationSet set;
213 set.push_back(TAG_USER_ID, 7);
214 set.push_back(TAG_USER_AUTH_ID, 8);
215 set.push_back(TAG_AUTH_TIMEOUT, 300);
216 return set;
217 }
218
219 AuthorizationSet ClientParams() {
220 AuthorizationSet set;
221 set.push_back(TAG_APPLICATION_ID, "app_id", 6);
222 return set;
223 }
224
225 keymaster_error_t BeginOperation(keymaster_purpose_t purpose) {
226 return device()->begin(device(), purpose, &blob_, client_params_,
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700227 array_length(client_params_), &out_params_, &out_params_count_,
228 &op_handle_);
229 }
230
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700231 keymaster_error_t UpdateOperation(const string& message, string* output,
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700232 size_t* input_consumed) {
233 uint8_t* out_tmp = NULL;
234 size_t out_length;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700235 EXPECT_NE(op_handle_, OP_HANDLE_SENTINEL);
236 keymaster_error_t error = device()->update(
Shawn Willden6bfbff02015-02-06 19:48:24 -0700237 device(), op_handle_, NULL /* additional_params */, 0 /* additional_params_count */,
238 reinterpret_cast<const uint8_t*>(message.c_str()), message.length(), input_consumed,
239 &out_tmp, &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 Willdenb15d77e2014-12-17 16:44:29 -0700246 keymaster_error_t FinishOperation(string* output) { return FinishOperation("", output); }
247
248 keymaster_error_t FinishOperation(const string& signature, string* output) {
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700249 uint8_t* out_tmp = NULL;
250 size_t out_length;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700251 keymaster_error_t error = device()->finish(
Shawn Willden6bfbff02015-02-06 19:48:24 -0700252 device(), op_handle_, NULL /* additional_params */, 0 /* additional_params_count */,
253 reinterpret_cast<const uint8_t*>(signature.c_str()), signature.length(), &out_tmp,
254 &out_length);
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700255 if (out_tmp)
256 output->append(reinterpret_cast<char*>(out_tmp), out_length);
257 free(out_tmp);
258 return error;
259 }
260
Shawn Willden76076ab2014-12-18 08:36:35 -0700261 template <typename T>
262 bool ResponseContains(const vector<T>& expected, const T* values, size_t len) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700263 return expected.size() == len &&
264 std::is_permutation(values, values + len, expected.begin());
Shawn Willden76076ab2014-12-18 08:36:35 -0700265 }
266
267 template <typename T> bool ResponseContains(T expected, const T* values, size_t len) {
268 return (len == 1 && *values == expected);
Shawn Willdend0772312014-09-18 12:27:57 -0600269 }
270
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700271 keymaster_error_t AbortOperation() { return device()->abort(device(), op_handle_); }
272
273 string ProcessMessage(keymaster_purpose_t purpose, const string& message) {
274 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose));
275
276 string result;
277 size_t input_consumed;
278 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
279 EXPECT_EQ(message.size(), input_consumed);
280 EXPECT_EQ(KM_ERROR_OK, FinishOperation(&result));
281 return result;
282 }
283
284 string ProcessMessage(keymaster_purpose_t purpose, const string& message,
285 const string& signature) {
286 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose));
287
288 string result;
289 size_t input_consumed;
290 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
291 EXPECT_EQ(message.size(), input_consumed);
292 EXPECT_EQ(KM_ERROR_OK, FinishOperation(signature, &result));
293 return result;
294 }
295
296 void SignMessage(const string& message, string* signature) {
Shawn Willden63ac0432014-12-29 14:07:08 -0700297 SCOPED_TRACE("SignMessage");
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700298 *signature = ProcessMessage(KM_PURPOSE_SIGN, message);
299 EXPECT_GT(signature->size(), 0);
300 }
301
302 void VerifyMessage(const string& message, const string& signature) {
Shawn Willden63ac0432014-12-29 14:07:08 -0700303 SCOPED_TRACE("VerifyMessage");
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700304 ProcessMessage(KM_PURPOSE_VERIFY, message, signature);
305 }
306
307 string EncryptMessage(const string& message) {
Shawn Willden63ac0432014-12-29 14:07:08 -0700308 SCOPED_TRACE("EncryptMessage");
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700309 return ProcessMessage(KM_PURPOSE_ENCRYPT, message);
310 }
311
312 string DecryptMessage(const string& ciphertext) {
Shawn Willden63ac0432014-12-29 14:07:08 -0700313 SCOPED_TRACE("DecryptMessage");
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700314 return ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext);
315 }
316
317 keymaster_error_t GetCharacteristics() {
318 FreeCharacteristics();
319 return device()->get_key_characteristics(device(), &blob_, &client_id_, NULL /* app_data */,
320 &characteristics_);
321 }
322
323 keymaster_error_t ExportKey(keymaster_key_format_t format, string* export_data) {
324 uint8_t* export_data_tmp;
325 size_t export_data_length;
326
327 keymaster_error_t error =
328 device()->export_key(device(), format, &blob_, &client_id_, NULL /* app_data */,
329 &export_data_tmp, &export_data_length);
330
331 if (error != KM_ERROR_OK)
332 return error;
333
334 *export_data = string(reinterpret_cast<char*>(export_data_tmp), export_data_length);
335 free(export_data_tmp);
336 return error;
337 }
338
339 keymaster_error_t GetVersion(uint8_t* major, uint8_t* minor, uint8_t* subminor) {
340 GetVersionRequest request;
341 GetVersionResponse response;
342 device_.GetVersion(request, &response);
343 if (response.error != KM_ERROR_OK)
344 return response.error;
345 *major = response.major_ver;
346 *minor = response.minor_ver;
347 *subminor = response.subminor_ver;
348 return response.error;
349 }
350
351 AuthorizationSet hw_enforced() {
352 EXPECT_TRUE(characteristics_ != NULL);
353 return AuthorizationSet(characteristics_->hw_enforced);
354 }
355
356 AuthorizationSet sw_enforced() {
357 EXPECT_TRUE(characteristics_ != NULL);
358 return AuthorizationSet(characteristics_->sw_enforced);
359 }
360
Shawn Willden5b53c992015-02-02 08:05:25 -0700361 void FreeCharacteristics() {
362 keymaster_free_characteristics(characteristics_);
363 free(characteristics_);
364 characteristics_ = NULL;
365 }
366
367 void FreeKeyBlob() {
368 free(const_cast<uint8_t*>(blob_.key_material));
369 blob_.key_material = NULL;
370 }
371
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700372 void corrupt_key_blob() {
373 assert(blob_.key_material);
374 uint8_t* tmp = const_cast<uint8_t*>(blob_.key_material);
375 ++tmp[blob_.key_material_size / 2];
376 }
Shawn Willden5b53c992015-02-02 08:05:25 -0700377
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700378 private:
379 SoftKeymasterDevice device_;
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700380 keymaster_blob_t client_id_ = {.data = reinterpret_cast<const uint8_t*>("app_id"),
381 .data_length = 6};
382 keymaster_key_param_t client_params_[1] = {
383 Authorization(TAG_APPLICATION_ID, client_id_.data, client_id_.data_length)};
384
385 keymaster_key_param_t* out_params_;
386 size_t out_params_count_;
387 uint64_t op_handle_;
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700388
Shawn Willden5b53c992015-02-02 08:05:25 -0700389 keymaster_key_blob_t blob_;
390 keymaster_key_characteristics_t* characteristics_;
Shawn Willden128ffe02014-08-06 12:31:33 -0600391};
392
Shawn Willden128ffe02014-08-06 12:31:33 -0600393typedef KeymasterTest CheckSupported;
394TEST_F(CheckSupported, SupportedAlgorithms) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700395 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
396 device()->get_supported_algorithms(device(), NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600397
Shawn Willden5b53c992015-02-02 08:05:25 -0700398 size_t len;
399 keymaster_algorithm_t* algorithms;
400 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_algorithms(device(), &algorithms, &len));
Shawn Willdena278f612014-12-23 11:22:21 -0700401 EXPECT_TRUE(ResponseContains(
402 {KM_ALGORITHM_RSA, KM_ALGORITHM_ECDSA, KM_ALGORITHM_AES, KM_ALGORITHM_HMAC}, algorithms,
403 len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700404 free(algorithms);
Shawn Willden128ffe02014-08-06 12:31:33 -0600405}
406
407TEST_F(CheckSupported, SupportedBlockModes) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700408 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
409 device()->get_supported_block_modes(device(), KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT,
410 NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600411
Shawn Willden5b53c992015-02-02 08:05:25 -0700412 size_t len;
413 keymaster_block_mode_t* modes;
Shawn Willden63ac0432014-12-29 14:07:08 -0700414 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_block_modes(device(), KM_ALGORITHM_RSA,
415 KM_PURPOSE_ENCRYPT, &modes, &len));
416 EXPECT_EQ(0, len);
417 free(modes);
Shawn Willden128ffe02014-08-06 12:31:33 -0600418
Shawn Willden76076ab2014-12-18 08:36:35 -0700419 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM,
Shawn Willden5b53c992015-02-02 08:05:25 -0700420 device()->get_supported_block_modes(device(), KM_ALGORITHM_DSA, KM_PURPOSE_ENCRYPT,
421 &modes, &len));
Shawn Willden28e41472014-08-18 13:35:22 -0600422
Shawn Willden63ac0432014-12-29 14:07:08 -0700423 EXPECT_EQ(KM_ERROR_UNSUPPORTED_PURPOSE,
Shawn Willden5b53c992015-02-02 08:05:25 -0700424 device()->get_supported_block_modes(device(), KM_ALGORITHM_ECDSA, KM_PURPOSE_ENCRYPT,
425 &modes, &len));
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600426
Shawn Willden63ac0432014-12-29 14:07:08 -0700427 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_block_modes(device(), KM_ALGORITHM_AES,
428 KM_PURPOSE_ENCRYPT, &modes, &len));
Shawn Willdenf0f68b92014-12-30 16:03:28 -0700429 EXPECT_TRUE(ResponseContains({KM_MODE_OCB, KM_MODE_ECB, KM_MODE_CBC, KM_MODE_OFB, KM_MODE_CFB},
430 modes, len));
Shawn Willden63ac0432014-12-29 14:07:08 -0700431 free(modes);
Shawn Willden128ffe02014-08-06 12:31:33 -0600432}
433
434TEST_F(CheckSupported, SupportedPaddingModes) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700435 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
436 device()->get_supported_padding_modes(device(), KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT,
437 NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600438
Shawn Willden5b53c992015-02-02 08:05:25 -0700439 size_t len;
440 keymaster_padding_t* modes;
441 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_RSA,
442 KM_PURPOSE_SIGN, &modes, &len));
Shawn Willdenf90f2352014-12-18 23:01:15 -0700443 EXPECT_TRUE(
444 ResponseContains({KM_PAD_NONE, KM_PAD_RSA_PKCS1_1_5_SIGN, KM_PAD_RSA_PSS}, modes, len));
Shawn Willden63ac0432014-12-29 14:07:08 -0700445 free(modes);
446
447 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_RSA,
448 KM_PURPOSE_ENCRYPT, &modes, &len));
449 EXPECT_TRUE(ResponseContains({KM_PAD_RSA_OAEP, KM_PAD_RSA_PKCS1_1_5_ENCRYPT}, modes, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700450 free(modes);
Shawn Willden128ffe02014-08-06 12:31:33 -0600451
Shawn Willden76076ab2014-12-18 08:36:35 -0700452 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM,
453 device()->get_supported_padding_modes(device(), KM_ALGORITHM_DSA, KM_PURPOSE_SIGN,
454 &modes, &len));
Shawn Willden28e41472014-08-18 13:35:22 -0600455
Shawn Willden5b53c992015-02-02 08:05:25 -0700456 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_ECDSA,
457 KM_PURPOSE_SIGN, &modes, &len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700458 EXPECT_EQ(0, len);
459 free(modes);
Shawn Willden63ac0432014-12-29 14:07:08 -0700460
461 EXPECT_EQ(KM_ERROR_UNSUPPORTED_PURPOSE,
462 device()->get_supported_padding_modes(device(), KM_ALGORITHM_AES, KM_PURPOSE_SIGN,
463 &modes, &len));
Shawn Willden128ffe02014-08-06 12:31:33 -0600464}
465
466TEST_F(CheckSupported, SupportedDigests) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700467 EXPECT_EQ(
468 KM_ERROR_OUTPUT_PARAMETER_NULL,
469 device()->get_supported_digests(device(), KM_ALGORITHM_RSA, KM_PURPOSE_SIGN, NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600470
Shawn Willden5b53c992015-02-02 08:05:25 -0700471 size_t len;
472 keymaster_digest_t* digests;
473 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_RSA,
474 KM_PURPOSE_SIGN, &digests, &len));
Shawn Willden61902362014-12-18 10:33:24 -0700475 EXPECT_TRUE(ResponseContains({KM_DIGEST_NONE, KM_DIGEST_SHA_2_256}, digests, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700476 free(digests);
Shawn Willden128ffe02014-08-06 12:31:33 -0600477
Shawn Willden76076ab2014-12-18 08:36:35 -0700478 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM,
479 device()->get_supported_digests(device(), KM_ALGORITHM_DSA, KM_PURPOSE_SIGN, &digests,
480 &len));
Shawn Willden28e41472014-08-18 13:35:22 -0600481
Shawn Willden5b53c992015-02-02 08:05:25 -0700482 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_ECDSA,
483 KM_PURPOSE_SIGN, &digests, &len));
Shawn Willden63ac0432014-12-29 14:07:08 -0700484 EXPECT_EQ(0, len);
Shawn Willden5b53c992015-02-02 08:05:25 -0700485 free(digests);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600486
Shawn Willden63ac0432014-12-29 14:07:08 -0700487 EXPECT_EQ(KM_ERROR_UNSUPPORTED_PURPOSE,
488 device()->get_supported_digests(device(), KM_ALGORITHM_AES, KM_PURPOSE_SIGN, &digests,
489 &len));
490
491 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_HMAC,
Shawn Willden5b53c992015-02-02 08:05:25 -0700492 KM_PURPOSE_SIGN, &digests, &len));
Shawn Willden63ac0432014-12-29 14:07:08 -0700493 EXPECT_TRUE(ResponseContains({KM_DIGEST_SHA_2_224, KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384,
494 KM_DIGEST_SHA_2_512, KM_DIGEST_SHA1},
495 digests, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700496 free(digests);
Shawn Willden128ffe02014-08-06 12:31:33 -0600497}
498
499TEST_F(CheckSupported, SupportedImportFormats) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700500 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
501 device()->get_supported_import_formats(device(), KM_ALGORITHM_RSA, NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600502
Shawn Willden5b53c992015-02-02 08:05:25 -0700503 size_t len;
504 keymaster_key_format_t* formats;
505 EXPECT_EQ(KM_ERROR_OK,
506 device()->get_supported_import_formats(device(), KM_ALGORITHM_RSA, &formats, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700507 EXPECT_TRUE(ResponseContains(KM_KEY_FORMAT_PKCS8, formats, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700508 free(formats);
Shawn Willden7dad93b2015-02-05 10:20:47 -0700509
510 EXPECT_EQ(KM_ERROR_OK,
511 device()->get_supported_import_formats(device(), KM_ALGORITHM_AES, &formats, &len));
512 EXPECT_TRUE(ResponseContains(KM_KEY_FORMAT_RAW, formats, len));
513 free(formats);
514
515 EXPECT_EQ(KM_ERROR_OK,
516 device()->get_supported_import_formats(device(), KM_ALGORITHM_HMAC, &formats, &len));
517 EXPECT_TRUE(ResponseContains(KM_KEY_FORMAT_RAW, formats, len));
518 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600519}
520
521TEST_F(CheckSupported, SupportedExportFormats) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700522 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
523 device()->get_supported_export_formats(device(), KM_ALGORITHM_RSA, NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600524
Shawn Willden5b53c992015-02-02 08:05:25 -0700525 size_t len;
526 keymaster_key_format_t* formats;
527 EXPECT_EQ(KM_ERROR_OK,
528 device()->get_supported_export_formats(device(), KM_ALGORITHM_RSA, &formats, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700529 EXPECT_TRUE(ResponseContains(KM_KEY_FORMAT_X509, formats, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700530 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600531
Shawn Willden76076ab2014-12-18 08:36:35 -0700532 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM,
Shawn Willden5b53c992015-02-02 08:05:25 -0700533 device()->get_supported_export_formats(device(), KM_ALGORITHM_DSA, &formats, &len));
Shawn Willden28e41472014-08-18 13:35:22 -0600534
Shawn Willden5b53c992015-02-02 08:05:25 -0700535 EXPECT_EQ(KM_ERROR_OK,
536 device()->get_supported_export_formats(device(), KM_ALGORITHM_ECDSA, &formats, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700537 EXPECT_TRUE(ResponseContains(KM_KEY_FORMAT_X509, formats, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700538 free(formats);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600539
Shawn Willden5b53c992015-02-02 08:05:25 -0700540 EXPECT_EQ(KM_ERROR_OK,
541 device()->get_supported_export_formats(device(), KM_ALGORITHM_AES, &formats, &len));
542 EXPECT_EQ(0, len);
543 free(formats);
Shawn Willden7dad93b2015-02-05 10:20:47 -0700544
545 EXPECT_EQ(KM_ERROR_OK,
546 device()->get_supported_export_formats(device(), KM_ALGORITHM_AES, &formats, &len));
547 EXPECT_EQ(0, len);
548 free(formats);
549
550 EXPECT_EQ(KM_ERROR_OK,
551 device()->get_supported_export_formats(device(), KM_ALGORITHM_HMAC, &formats, &len));
552 EXPECT_EQ(0, len);
553 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600554}
555
Shawn Willdend0772312014-09-18 12:27:57 -0600556class NewKeyGeneration : public KeymasterTest {
557 protected:
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700558 void CheckBaseParams() {
559 EXPECT_EQ(0U, hw_enforced().size());
560 EXPECT_EQ(12U, hw_enforced().SerializedSize());
Shawn Willdend0772312014-09-18 12:27:57 -0600561
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700562 AuthorizationSet auths = sw_enforced();
563 EXPECT_GT(auths.SerializedSize(), 12U);
564
Shawn Willden5b53c992015-02-02 08:05:25 -0700565 EXPECT_TRUE(contains(auths, TAG_PURPOSE, KM_PURPOSE_SIGN));
566 EXPECT_TRUE(contains(auths, TAG_PURPOSE, KM_PURPOSE_VERIFY));
567 EXPECT_TRUE(contains(auths, TAG_USER_ID, 7));
568 EXPECT_TRUE(contains(auths, TAG_USER_AUTH_ID, 8));
569 EXPECT_TRUE(contains(auths, TAG_AUTH_TIMEOUT, 300));
Shawn Willdend0772312014-09-18 12:27:57 -0600570
571 // Verify that App ID, App data and ROT are NOT included.
Shawn Willden5b53c992015-02-02 08:05:25 -0700572 EXPECT_FALSE(contains(auths, TAG_ROOT_OF_TRUST));
573 EXPECT_FALSE(contains(auths, TAG_APPLICATION_ID));
574 EXPECT_FALSE(contains(auths, TAG_APPLICATION_DATA));
Shawn Willdend0772312014-09-18 12:27:57 -0600575
576 // Just for giggles, check that some unexpected tags/values are NOT present.
Shawn Willden5b53c992015-02-02 08:05:25 -0700577 EXPECT_FALSE(contains(auths, TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
578 EXPECT_FALSE(contains(auths, TAG_PURPOSE, KM_PURPOSE_DECRYPT));
579 EXPECT_FALSE(contains(auths, TAG_AUTH_TIMEOUT, 301));
Shawn Willdend0772312014-09-18 12:27:57 -0600580
581 // Now check that unspecified, defaulted tags are correct.
Shawn Willden5b53c992015-02-02 08:05:25 -0700582 EXPECT_TRUE(contains(auths, TAG_ORIGIN, KM_ORIGIN_SOFTWARE));
583 EXPECT_TRUE(contains(auths, KM_TAG_CREATION_DATETIME));
Shawn Willdend0772312014-09-18 12:27:57 -0600584 }
Shawn Willden2079ae82015-01-22 13:42:31 -0700585};
586
Shawn Willden128ffe02014-08-06 12:31:33 -0600587TEST_F(NewKeyGeneration, Rsa) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700588 ASSERT_EQ(KM_ERROR_OK,
589 GenerateKey(ParamBuilder().RsaSigningKey(256, KM_DIGEST_NONE, KM_PAD_NONE, 3)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700590 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.
Shawn Willdenc24c1102014-12-22 15:30:09 -0700601 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey()));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700602 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 Willdenc24c1102014-12-22 15:30:09 -0700613 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().EcdsaSigningKey(224)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700614 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 Willdenc24c1102014-12-22 15:30:09 -0700622 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().EcdsaSigningKey()));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700623 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 Willdenc24c1102014-12-22 15:30:09 -0700633 ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE, GenerateKey(ParamBuilder().EcdsaSigningKey(190)));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600634}
635
636TEST_F(NewKeyGeneration, EcdsaAllValidSizes) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600637 size_t valid_sizes[] = {224, 256, 384, 521};
Shawn Willden6bbe6782014-09-18 11:26:15 -0600638 for (size_t size : valid_sizes) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700639 EXPECT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().EcdsaSigningKey(size)))
Shawn Willden5b53c992015-02-02 08:05:25 -0700640 << "Failed to generate size: " << size;
Shawn Willden6bbe6782014-09-18 11:26:15 -0600641 }
642}
643
Shawn Willden19fca882015-01-22 16:35:30 -0700644TEST_F(NewKeyGeneration, AesOcb) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700645 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willden19fca882015-01-22 16:35:30 -0700646}
647
648TEST_F(NewKeyGeneration, AesOcbInvalidKeySize) {
Shawn Willden7dad93b2015-02-05 10:20:47 -0700649 ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE,
650 GenerateKey(ParamBuilder().AesEncryptionKey(136).OcbMode(4096, 16)));
Shawn Willden19fca882015-01-22 16:35:30 -0700651}
652
653TEST_F(NewKeyGeneration, AesOcbAllValidSizes) {
Shawn Willden19fca882015-01-22 16:35:30 -0700654 size_t valid_sizes[] = {128, 192, 256};
655 for (size_t size : valid_sizes) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700656 EXPECT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(size)))
Shawn Willden5b53c992015-02-02 08:05:25 -0700657 << "Failed to generate size: " << size;
Shawn Willden19fca882015-01-22 16:35:30 -0700658 }
659}
660
Shawn Willden0d560bf2014-12-15 17:44:02 -0700661TEST_F(NewKeyGeneration, HmacSha256) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700662 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_256, 16)));
Shawn Willden0d560bf2014-12-15 17:44:02 -0700663}
664
Shawn Willden76364712014-08-11 17:48:04 -0600665typedef KeymasterTest GetKeyCharacteristics;
666TEST_F(GetKeyCharacteristics, SimpleRsa) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700667 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey(256)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700668 AuthorizationSet original(sw_enforced());
Shawn Willden76364712014-08-11 17:48:04 -0600669
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700670 ASSERT_EQ(KM_ERROR_OK, GetCharacteristics());
671 EXPECT_EQ(original, sw_enforced());
Shawn Willden76364712014-08-11 17:48:04 -0600672}
673
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700674typedef KeymasterTest SigningOperationsTest;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600675TEST_F(SigningOperationsTest, RsaSuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700676 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey(256)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700677 string message = "12345678901234567890123456789012";
678 string signature;
679 SignMessage(message, &signature);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600680}
681
Shawn Willden61902362014-12-18 10:33:24 -0700682TEST_F(SigningOperationsTest, RsaSha256DigestSuccess) {
683 // Note that without padding, key size must exactly match digest size.
Shawn Willdenf90f2352014-12-18 23:01:15 -0700684 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey(256, KM_DIGEST_SHA_2_256)));
685 string message(1024, 'a');
686 string signature;
687 SignMessage(message, &signature);
688}
689
690TEST_F(SigningOperationsTest, RsaPssSha256Success) {
691 ASSERT_EQ(KM_ERROR_OK,
692 GenerateKey(ParamBuilder().RsaSigningKey(512, KM_DIGEST_SHA_2_256, KM_PAD_RSA_PSS)));
Shawn Willden61902362014-12-18 10:33:24 -0700693 // Use large message, which won't work without digesting.
694 string message(1024, 'a');
695 string signature;
696 SignMessage(message, &signature);
697}
698
Shawn Willdenf90f2352014-12-18 23:01:15 -0700699TEST_F(SigningOperationsTest, RsaPkcs1Sha256Success) {
700 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey(512, KM_DIGEST_SHA_2_256,
701 KM_PAD_RSA_PKCS1_1_5_SIGN)));
702 string message(1024, 'a');
703 string signature;
704 SignMessage(message, &signature);
705}
706
707TEST_F(SigningOperationsTest, RsaPssSha256TooSmallKey) {
708 // Key must be at least 10 bytes larger than hash, to provide minimal random salt, so verify
709 // that 9 bytes larger than hash won't work.
710 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey(
711 256 + 9 * 8, KM_DIGEST_SHA_2_256, KM_PAD_RSA_PSS)));
712 string message(1024, 'a');
713 string signature;
714
715 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_SIGN));
716
717 string result;
718 size_t input_consumed;
719 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
720 EXPECT_EQ(message.size(), input_consumed);
721 EXPECT_EQ(KM_ERROR_INCOMPATIBLE_DIGEST, FinishOperation(signature, &result));
722}
723
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600724TEST_F(SigningOperationsTest, EcdsaSuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700725 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().EcdsaSigningKey(224)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700726 string message = "123456789012345678901234567890123456789012345678";
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700727 string signature;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700728 SignMessage(message, &signature);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600729}
730
Shawn Willden1615f2e2014-08-13 10:37:40 -0600731TEST_F(SigningOperationsTest, RsaAbort) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700732 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey(256)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700733 ASSERT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_SIGN));
734 EXPECT_EQ(KM_ERROR_OK, AbortOperation());
735 // Another abort should fail
736 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, AbortOperation());
Shawn Willden1615f2e2014-08-13 10:37:40 -0600737}
738
739TEST_F(SigningOperationsTest, RsaUnsupportedDigest) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700740 GenerateKey(
741 ParamBuilder().RsaSigningKey(256, KM_DIGEST_MD5, KM_PAD_RSA_PSS /* supported padding */));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700742 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600743}
744
745TEST_F(SigningOperationsTest, RsaUnsupportedPadding) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700746 GenerateKey(ParamBuilder().RsaSigningKey(256, KM_DIGEST_SHA_2_256 /* supported digest */,
747 KM_PAD_PKCS7));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700748 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600749}
750
751TEST_F(SigningOperationsTest, RsaNoDigest) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700752 // Digest must be specified.
Shawn Willdenc24c1102014-12-22 15:30:09 -0700753 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaKey(256).SigningKey().Option(
754 TAG_PADDING, KM_PAD_NONE)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700755 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willdenf90f2352014-12-18 23:01:15 -0700756 // PSS requires a digest.
757 GenerateKey(ParamBuilder().RsaSigningKey(256, KM_DIGEST_NONE, KM_PAD_RSA_PSS));
758 ASSERT_EQ(KM_ERROR_INCOMPATIBLE_DIGEST, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600759}
760
761TEST_F(SigningOperationsTest, RsaNoPadding) {
Shawn Willdenf90f2352014-12-18 23:01:15 -0700762 // Padding must be specified
Shawn Willdenc24c1102014-12-22 15:30:09 -0700763 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaKey(256).SigningKey().Option(
764 TAG_DIGEST, KM_DIGEST_NONE)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700765 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600766}
767
Shawn Willden51d5e0e2014-12-18 10:44:03 -0700768TEST_F(SigningOperationsTest, HmacSha1Success) {
769 GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA1, 20));
770 string message = "12345678901234567890123456789012";
771 string signature;
772 SignMessage(message, &signature);
773 ASSERT_EQ(20, signature.size());
774}
775
Shawn Willden62c22862014-12-17 08:36:20 -0700776TEST_F(SigningOperationsTest, HmacSha224Success) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700777 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_224, 28)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700778 string message = "12345678901234567890123456789012";
779 string signature;
780 SignMessage(message, &signature);
781 ASSERT_EQ(28, signature.size());
Shawn Willden62c22862014-12-17 08:36:20 -0700782}
783
Shawn Willden0d560bf2014-12-15 17:44:02 -0700784TEST_F(SigningOperationsTest, HmacSha256Success) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700785 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_256, 32)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700786 string message = "12345678901234567890123456789012";
787 string signature;
788 SignMessage(message, &signature);
789 ASSERT_EQ(32, signature.size());
Shawn Willden0d560bf2014-12-15 17:44:02 -0700790}
791
Shawn Willden62c22862014-12-17 08:36:20 -0700792TEST_F(SigningOperationsTest, HmacSha384Success) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700793 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_384, 48)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700794 string message = "12345678901234567890123456789012";
795 string signature;
796 SignMessage(message, &signature);
797 ASSERT_EQ(48, signature.size());
Shawn Willden62c22862014-12-17 08:36:20 -0700798}
799
800TEST_F(SigningOperationsTest, HmacSha512Success) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700801 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_512, 64)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700802 string message = "12345678901234567890123456789012";
Shawn Willden62c22862014-12-17 08:36:20 -0700803 string signature;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700804 SignMessage(message, &signature);
805 ASSERT_EQ(64, signature.size());
Shawn Willden62c22862014-12-17 08:36:20 -0700806}
807
808// TODO(swillden): Add HMACSHA{224|256|384|512} tests that validates against the test vectors from
809// RFC4231. Doing that requires being able to import keys, rather than just
810// generate them randomly.
Shawn Willden0d560bf2014-12-15 17:44:02 -0700811
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700812TEST_F(SigningOperationsTest, HmacSha256NoMacLength) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700813 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder()
814 .Option(TAG_ALGORITHM, KM_ALGORITHM_HMAC)
815 .Option(TAG_KEY_SIZE, 128)
816 .SigningKey()
817 .Option(TAG_DIGEST, KM_DIGEST_SHA_2_256)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700818 EXPECT_EQ(KM_ERROR_UNSUPPORTED_MAC_LENGTH, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden0d560bf2014-12-15 17:44:02 -0700819}
820
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700821TEST_F(SigningOperationsTest, HmacSha256TooLargeMacLength) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700822 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_256, 33)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700823 ASSERT_EQ(KM_ERROR_UNSUPPORTED_MAC_LENGTH, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden0d560bf2014-12-15 17:44:02 -0700824}
825
Shawn Willden1615f2e2014-08-13 10:37:40 -0600826TEST_F(SigningOperationsTest, RsaTooShortMessage) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700827 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey(256)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700828 ASSERT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700829
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700830 string message = "1234567890123456789012345678901";
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700831 string result;
832 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700833 ASSERT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700834 EXPECT_EQ(0U, result.size());
835 EXPECT_EQ(31U, input_consumed);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600836
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700837 string signature;
838 ASSERT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&signature));
839 EXPECT_EQ(0U, signature.length());
Shawn Willden43e999e2014-08-13 13:29:50 -0600840}
841
Shawn Willden61902362014-12-18 10:33:24 -0700842// TODO(swillden): Add more verification failure tests.
843
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700844typedef KeymasterTest VerificationOperationsTest;
Shawn Willden43e999e2014-08-13 13:29:50 -0600845TEST_F(VerificationOperationsTest, RsaSuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700846 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey(256)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700847 string message = "12345678901234567890123456789012";
848 string signature;
849 SignMessage(message, &signature);
850 VerifyMessage(message, signature);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600851}
852
Shawn Willden61902362014-12-18 10:33:24 -0700853TEST_F(VerificationOperationsTest, RsaSha256DigestSuccess) {
854 // Note that without padding, key size must exactly match digest size.
855 GenerateKey(ParamBuilder().RsaSigningKey(256, KM_DIGEST_SHA_2_256));
Shawn Willden61902362014-12-18 10:33:24 -0700856 string message(1024, 'a');
857 string signature;
858 SignMessage(message, &signature);
859 VerifyMessage(message, signature);
860}
861
Shawn Willdenf90f2352014-12-18 23:01:15 -0700862TEST_F(VerificationOperationsTest, RsaSha256CorruptSignature) {
Shawn Willden61902362014-12-18 10:33:24 -0700863 GenerateKey(ParamBuilder().RsaSigningKey(256, KM_DIGEST_SHA_2_256));
Shawn Willden61902362014-12-18 10:33:24 -0700864 string message(1024, 'a');
865 string signature;
866 SignMessage(message, &signature);
867 ++signature[signature.size() / 2];
868
869 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_VERIFY));
870
871 string result;
872 size_t input_consumed;
873 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
874 EXPECT_EQ(message.size(), input_consumed);
875 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(signature, &result));
876}
877
Shawn Willdenf90f2352014-12-18 23:01:15 -0700878TEST_F(VerificationOperationsTest, RsaPssSha256Success) {
879 ASSERT_EQ(KM_ERROR_OK,
880 GenerateKey(ParamBuilder().RsaSigningKey(512, KM_DIGEST_SHA_2_256, KM_PAD_RSA_PSS)));
881 // Use large message, which won't work without digesting.
882 string message(1024, 'a');
883 string signature;
884 SignMessage(message, &signature);
885 VerifyMessage(message, signature);
886}
887
888TEST_F(VerificationOperationsTest, RsaPssSha256CorruptSignature) {
889 GenerateKey(ParamBuilder().RsaSigningKey(512, KM_DIGEST_SHA_2_256, KM_PAD_RSA_PSS));
890 string message(1024, 'a');
891 string signature;
892 SignMessage(message, &signature);
893 ++signature[signature.size() / 2];
894
895 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_VERIFY));
896
897 string result;
898 size_t input_consumed;
899 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
900 EXPECT_EQ(message.size(), input_consumed);
901 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(signature, &result));
902}
903
904TEST_F(VerificationOperationsTest, RsaPssSha256CorruptInput) {
905 ASSERT_EQ(KM_ERROR_OK,
906 GenerateKey(ParamBuilder().RsaSigningKey(512, KM_DIGEST_SHA_2_256, KM_PAD_RSA_PSS)));
Shawn Willden61902362014-12-18 10:33:24 -0700907 // Use large message, which won't work without digesting.
908 string message(1024, 'a');
909 string signature;
910 SignMessage(message, &signature);
911 ++message[message.size() / 2];
912
913 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_VERIFY));
914
915 string result;
916 size_t input_consumed;
917 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
918 EXPECT_EQ(message.size(), input_consumed);
919 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(signature, &result));
920}
921
Shawn Willdenf90f2352014-12-18 23:01:15 -0700922TEST_F(VerificationOperationsTest, RsaPkcs1Sha256Success) {
923 GenerateKey(ParamBuilder().RsaSigningKey(512, KM_DIGEST_SHA_2_256, KM_PAD_RSA_PKCS1_1_5_SIGN));
924 string message(1024, 'a');
925 string signature;
926 SignMessage(message, &signature);
927 VerifyMessage(message, signature);
928}
929
930TEST_F(VerificationOperationsTest, RsaPkcs1Sha256CorruptSignature) {
931 GenerateKey(ParamBuilder().RsaSigningKey(512, KM_DIGEST_SHA_2_256, KM_PAD_RSA_PKCS1_1_5_SIGN));
932 string message(1024, 'a');
933 string signature;
934 SignMessage(message, &signature);
935 ++signature[signature.size() / 2];
936
937 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_VERIFY));
938
939 string result;
940 size_t input_consumed;
941 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
942 EXPECT_EQ(message.size(), input_consumed);
943 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(signature, &result));
944}
945
946TEST_F(VerificationOperationsTest, RsaPkcs1Sha256CorruptInput) {
947 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey(512, KM_DIGEST_SHA_2_256,
948 KM_PAD_RSA_PKCS1_1_5_SIGN)));
949 // Use large message, which won't work without digesting.
950 string message(1024, 'a');
951 string signature;
952 SignMessage(message, &signature);
953 ++message[message.size() / 2];
954
955 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_VERIFY));
956
957 string result;
958 size_t input_consumed;
959 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
960 EXPECT_EQ(message.size(), input_consumed);
961 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(signature, &result));
962}
963
964template <typename T> vector<T> make_vector(const T* array, size_t len) {
965 return vector<T>(array, array + len);
966}
967
968TEST_F(VerificationOperationsTest, RsaAllDigestAndPadCombinations) {
969 // Get all supported digests and padding modes.
970 size_t digests_len;
971 keymaster_digest_t* digests;
972 EXPECT_EQ(KM_ERROR_OK,
973 device()->get_supported_digests(device(), KM_ALGORITHM_RSA, KM_PURPOSE_SIGN, &digests,
974 &digests_len));
975
976 size_t padding_modes_len;
977 keymaster_padding_t* padding_modes;
978 EXPECT_EQ(KM_ERROR_OK,
979 device()->get_supported_padding_modes(device(), KM_ALGORITHM_RSA, KM_PURPOSE_SIGN,
980 &padding_modes, &padding_modes_len));
981
982 // Try them.
983 for (keymaster_padding_t padding_mode : make_vector(padding_modes, padding_modes_len)) {
984 for (keymaster_digest_t digest : make_vector(digests, digests_len)) {
985 // Compute key & message size that will work.
986 size_t key_bits = 256;
987 size_t message_len = 1000;
988 switch (digest) {
989 case KM_DIGEST_NONE:
990 switch (padding_mode) {
991 case KM_PAD_NONE:
992 // Match key size.
993 message_len = key_bits / 8;
994 break;
995 case KM_PAD_RSA_PKCS1_1_5_SIGN:
996 message_len = key_bits / 8 - 11;
997 break;
998 case KM_PAD_RSA_PSS:
999 // PSS requires a digest.
1000 continue;
1001 default:
1002 FAIL() << "Missing padding";
1003 break;
1004 }
1005 break;
1006
1007 case KM_DIGEST_SHA_2_256:
1008 switch (padding_mode) {
1009 case KM_PAD_NONE:
1010 // Key size matches digest size
1011 break;
1012 case KM_PAD_RSA_PKCS1_1_5_SIGN:
1013 key_bits += 8 * 11;
1014 break;
1015 case KM_PAD_RSA_PSS:
1016 key_bits += 8 * 10;
1017 break;
1018 default:
1019 FAIL() << "Missing padding";
1020 break;
1021 }
1022 break;
1023 default:
1024 FAIL() << "Missing digest";
1025 }
1026
1027 GenerateKey(ParamBuilder().RsaSigningKey(key_bits, digest, padding_mode));
1028 string message(message_len, 'a');
1029 string signature;
1030 SignMessage(message, &signature);
1031 VerifyMessage(message, signature);
1032 }
1033 }
1034
1035 free(padding_modes);
1036 free(digests);
1037}
1038
Shawn Willden5ac2f8f2014-08-18 15:33:10 -06001039TEST_F(VerificationOperationsTest, EcdsaSuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001040 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().EcdsaSigningKey(256)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001041 string message = "123456789012345678901234567890123456789012345678";
1042 string signature;
1043 SignMessage(message, &signature);
1044 VerifyMessage(message, signature);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -06001045}
1046
Shawn Willden51d5e0e2014-12-18 10:44:03 -07001047TEST_F(VerificationOperationsTest, HmacSha1Success) {
1048 GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA1, 16));
1049 string message = "123456789012345678901234567890123456789012345678";
1050 string signature;
1051 SignMessage(message, &signature);
1052 VerifyMessage(message, signature);
1053}
1054
1055TEST_F(VerificationOperationsTest, HmacSha224Success) {
1056 GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_224, 16));
1057 string message = "123456789012345678901234567890123456789012345678";
1058 string signature;
1059 SignMessage(message, &signature);
1060 VerifyMessage(message, signature);
1061}
1062
Shawn Willden0d560bf2014-12-15 17:44:02 -07001063TEST_F(VerificationOperationsTest, HmacSha256Success) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001064 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_256, 16)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001065 string message = "123456789012345678901234567890123456789012345678";
Shawn Willden0d560bf2014-12-15 17:44:02 -07001066 string signature;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001067 SignMessage(message, &signature);
1068 VerifyMessage(message, signature);
Shawn Willden0d560bf2014-12-15 17:44:02 -07001069}
1070
Shawn Willden51d5e0e2014-12-18 10:44:03 -07001071TEST_F(VerificationOperationsTest, HmacSha384Success) {
1072 GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_384, 16));
1073 string message = "123456789012345678901234567890123456789012345678";
1074 string signature;
1075 SignMessage(message, &signature);
1076 VerifyMessage(message, signature);
1077}
1078
1079TEST_F(VerificationOperationsTest, HmacSha512Success) {
1080 GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_512, 16));
1081 string message = "123456789012345678901234567890123456789012345678";
1082 string signature;
1083 SignMessage(message, &signature);
1084 VerifyMessage(message, signature);
1085}
1086
Shawn Willden5b53c992015-02-02 08:05:25 -07001087typedef VerificationOperationsTest ExportKeyTest;
Shawn Willdenffd790c2014-08-18 21:20:06 -06001088TEST_F(ExportKeyTest, RsaSuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001089 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey(256)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001090 string export_data;
1091 ASSERT_EQ(KM_ERROR_OK, ExportKey(KM_KEY_FORMAT_X509, &export_data));
1092 EXPECT_GT(export_data.length(), 0);
Shawn Willdene46a43f2014-08-27 10:35:36 -06001093
1094 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willdenffd790c2014-08-18 21:20:06 -06001095}
1096
Shawn Willdenf268d742014-08-19 15:36:26 -06001097TEST_F(ExportKeyTest, EcdsaSuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001098 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().EcdsaSigningKey(224)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001099 string export_data;
1100 ASSERT_EQ(KM_ERROR_OK, ExportKey(KM_KEY_FORMAT_X509, &export_data));
1101 EXPECT_GT(export_data.length(), 0);
Shawn Willdene46a43f2014-08-27 10:35:36 -06001102
1103 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willdenf268d742014-08-19 15:36:26 -06001104}
1105
1106TEST_F(ExportKeyTest, RsaUnsupportedKeyFormat) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001107 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey(256)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001108 string export_data;
1109 ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_FORMAT, ExportKey(KM_KEY_FORMAT_PKCS8, &export_data));
Shawn Willdenf268d742014-08-19 15:36:26 -06001110}
1111
1112TEST_F(ExportKeyTest, RsaCorruptedKeyBlob) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001113 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey(256)));
Shawn Willden5b53c992015-02-02 08:05:25 -07001114 corrupt_key_blob();
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001115 string export_data;
1116 ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, ExportKey(KM_KEY_FORMAT_X509, &export_data));
Shawn Willdenf268d742014-08-19 15:36:26 -06001117}
1118
Shawn Willden7dad93b2015-02-05 10:20:47 -07001119TEST_F(ExportKeyTest, AesKeyExportFails) {
1120 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128)));
1121 string export_data;
1122
1123 EXPECT_EQ(KM_ERROR_UNSUPPORTED_KEY_FORMAT, ExportKey(KM_KEY_FORMAT_X509, &export_data));
1124 EXPECT_EQ(KM_ERROR_UNSUPPORTED_KEY_FORMAT, ExportKey(KM_KEY_FORMAT_PKCS8, &export_data));
1125 EXPECT_EQ(KM_ERROR_UNSUPPORTED_KEY_FORMAT, ExportKey(KM_KEY_FORMAT_RAW, &export_data));
1126}
1127
Shawn Willden437fbd12014-08-20 11:59:49 -06001128static string read_file(const string& file_name) {
1129 ifstream file_stream(file_name, std::ios::binary);
1130 istreambuf_iterator<char> file_begin(file_stream);
1131 istreambuf_iterator<char> file_end;
1132 return string(file_begin, file_end);
1133}
1134
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001135typedef VerificationOperationsTest ImportKeyTest;
Shawn Willden5b53c992015-02-02 08:05:25 -07001136TEST_F(ImportKeyTest, RsaSuccess) {
Shawn Willden81effc62014-08-27 10:08:46 -06001137 string pk8_key = read_file("rsa_privkey_pk8.der");
Shawn Willden437fbd12014-08-20 11:59:49 -06001138 ASSERT_EQ(633U, pk8_key.size());
1139
Shawn Willdena278f612014-12-23 11:22:21 -07001140 ASSERT_EQ(KM_ERROR_OK, ImportKey(ParamBuilder().RsaSigningKey().NoDigestOrPadding(),
Shawn Willdenc24c1102014-12-22 15:30:09 -07001141 KM_KEY_FORMAT_PKCS8, pk8_key));
Shawn Willden437fbd12014-08-20 11:59:49 -06001142
1143 // Check values derived from the key.
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001144 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_RSA));
1145 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 1024));
1146 EXPECT_TRUE(contains(sw_enforced(), TAG_RSA_PUBLIC_EXPONENT, 65537U));
Shawn Willden437fbd12014-08-20 11:59:49 -06001147
1148 // And values provided by GoogleKeymaster
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001149 EXPECT_TRUE(contains(sw_enforced(), TAG_ORIGIN, KM_ORIGIN_IMPORTED));
1150 EXPECT_TRUE(contains(sw_enforced(), KM_TAG_CREATION_DATETIME));
Shawn Willden437fbd12014-08-20 11:59:49 -06001151
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001152 string message(1024 / 8, 'a');
1153 string signature;
1154 SignMessage(message, &signature);
1155 VerifyMessage(message, signature);
Shawn Willden437fbd12014-08-20 11:59:49 -06001156}
1157
Shawn Willden6bbe6782014-09-18 11:26:15 -06001158TEST_F(ImportKeyTest, RsaKeySizeMismatch) {
Shawn Willden6bbe6782014-09-18 11:26:15 -06001159 string pk8_key = read_file("rsa_privkey_pk8.der");
1160 ASSERT_EQ(633U, pk8_key.size());
Shawn Willden5b53c992015-02-02 08:05:25 -07001161 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
Shawn Willdenc24c1102014-12-22 15:30:09 -07001162 ImportKey(ParamBuilder()
Shawn Willdena278f612014-12-23 11:22:21 -07001163 .RsaSigningKey(2048) // Size doesn't match key
Shawn Willdenc24c1102014-12-22 15:30:09 -07001164 .NoDigestOrPadding(),
1165 KM_KEY_FORMAT_PKCS8, pk8_key));
Shawn Willden6bbe6782014-09-18 11:26:15 -06001166}
1167
1168TEST_F(ImportKeyTest, RsaPublicExponenMismatch) {
Shawn Willden6bbe6782014-09-18 11:26:15 -06001169 string pk8_key = read_file("rsa_privkey_pk8.der");
1170 ASSERT_EQ(633U, pk8_key.size());
Shawn Willden5b53c992015-02-02 08:05:25 -07001171 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
Shawn Willdenc24c1102014-12-22 15:30:09 -07001172 ImportKey(ParamBuilder()
Shawn Willdena278f612014-12-23 11:22:21 -07001173 .RsaSigningKey()
Shawn Willdenc24c1102014-12-22 15:30:09 -07001174 .Option(TAG_RSA_PUBLIC_EXPONENT, 3) // Doesn't match key
1175 .NoDigestOrPadding(),
1176 KM_KEY_FORMAT_PKCS8, pk8_key));
Shawn Willden6bbe6782014-09-18 11:26:15 -06001177}
1178
Shawn Willden81effc62014-08-27 10:08:46 -06001179TEST_F(ImportKeyTest, EcdsaSuccess) {
Shawn Willden81effc62014-08-27 10:08:46 -06001180 string pk8_key = read_file("ec_privkey_pk8.der");
1181 ASSERT_EQ(138U, pk8_key.size());
1182
Shawn Willdena278f612014-12-23 11:22:21 -07001183 ASSERT_EQ(KM_ERROR_OK,
1184 ImportKey(ParamBuilder().EcdsaSigningKey(), KM_KEY_FORMAT_PKCS8, pk8_key));
Shawn Willden81effc62014-08-27 10:08:46 -06001185
1186 // Check values derived from the key.
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001187 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
1188 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 256));
Shawn Willden81effc62014-08-27 10:08:46 -06001189
1190 // And values provided by GoogleKeymaster
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001191 EXPECT_TRUE(contains(sw_enforced(), TAG_ORIGIN, KM_ORIGIN_IMPORTED));
1192 EXPECT_TRUE(contains(sw_enforced(), KM_TAG_CREATION_DATETIME));
Shawn Willden81effc62014-08-27 10:08:46 -06001193
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001194 string message(1024 / 8, 'a');
1195 string signature;
1196 SignMessage(message, &signature);
1197 VerifyMessage(message, signature);
Shawn Willden81effc62014-08-27 10:08:46 -06001198}
1199
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001200TEST_F(ImportKeyTest, EcdsaSizeSpecified) {
1201 string pk8_key = read_file("ec_privkey_pk8.der");
1202 ASSERT_EQ(138U, pk8_key.size());
Shawn Willden6bbe6782014-09-18 11:26:15 -06001203
Shawn Willdena278f612014-12-23 11:22:21 -07001204 ASSERT_EQ(KM_ERROR_OK,
1205 ImportKey(ParamBuilder().EcdsaSigningKey(256), KM_KEY_FORMAT_PKCS8, pk8_key));
Shawn Willden6bbe6782014-09-18 11:26:15 -06001206
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001207 // Check values derived from the key.
1208 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
1209 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 256));
1210
1211 // And values provided by GoogleKeymaster
1212 EXPECT_TRUE(contains(sw_enforced(), TAG_ORIGIN, KM_ORIGIN_IMPORTED));
1213 EXPECT_TRUE(contains(sw_enforced(), KM_TAG_CREATION_DATETIME));
1214
1215 string message(1024 / 8, 'a');
1216 string signature;
1217 SignMessage(message, &signature);
1218 VerifyMessage(message, signature);
1219}
1220
1221TEST_F(ImportKeyTest, EcdsaSizeMismatch) {
1222 string pk8_key = read_file("ec_privkey_pk8.der");
1223 ASSERT_EQ(138U, pk8_key.size());
Shawn Willden5b53c992015-02-02 08:05:25 -07001224 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
Shawn Willdena278f612014-12-23 11:22:21 -07001225 ImportKey(ParamBuilder().EcdsaSigningKey(224), // Size does not match key
1226 KM_KEY_FORMAT_PKCS8, pk8_key));
Shawn Willden6bbe6782014-09-18 11:26:15 -06001227}
1228
Shawn Willden2665e862014-11-24 14:46:21 -07001229typedef KeymasterTest VersionTest;
1230TEST_F(VersionTest, GetVersion) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001231 uint8_t major, minor, subminor;
1232 ASSERT_EQ(KM_ERROR_OK, GetVersion(&major, &minor, &subminor));
1233 EXPECT_EQ(1, major);
1234 EXPECT_EQ(0, minor);
1235 EXPECT_EQ(0, subminor);
Shawn Willden2665e862014-11-24 14:46:21 -07001236}
1237
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001238typedef KeymasterTest EncryptionOperationsTest;
Shawn Willden4200f212014-12-02 07:01:21 -07001239TEST_F(EncryptionOperationsTest, RsaOaepSuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001240 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_OAEP)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001241
1242 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001243 string ciphertext1 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001244 EXPECT_EQ(512 / 8, ciphertext1.size());
1245
Shawn Willden6dde87c2014-12-11 14:08:48 -07001246 string ciphertext2 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001247 EXPECT_EQ(512 / 8, ciphertext2.size());
1248
1249 // OAEP randomizes padding so every result should be different.
1250 EXPECT_NE(ciphertext1, ciphertext2);
1251}
1252
1253TEST_F(EncryptionOperationsTest, RsaOaepRoundTrip) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001254 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_OAEP)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001255 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001256 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001257 EXPECT_EQ(512 / 8, ciphertext.size());
1258
Shawn Willden6dde87c2014-12-11 14:08:48 -07001259 string plaintext = DecryptMessage(ciphertext);
Shawn Willden4200f212014-12-02 07:01:21 -07001260 EXPECT_EQ(message, plaintext);
1261}
1262
1263TEST_F(EncryptionOperationsTest, RsaOaepTooLarge) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001264 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_OAEP)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001265 string message = "12345678901234567890123";
Shawn Willden4200f212014-12-02 07:01:21 -07001266 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001267 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001268
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001269 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT));
1270 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001271 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -07001272 EXPECT_EQ(0, result.size());
1273}
1274
1275TEST_F(EncryptionOperationsTest, RsaOaepCorruptedDecrypt) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001276 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_OAEP)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001277 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001278 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001279 EXPECT_EQ(512 / 8, ciphertext.size());
1280
1281 // Corrupt the ciphertext
1282 ciphertext[512 / 8 / 2]++;
1283
Shawn Willden4200f212014-12-02 07:01:21 -07001284 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001285 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001286 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
1287 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001288 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -07001289 EXPECT_EQ(0, result.size());
1290}
1291
1292TEST_F(EncryptionOperationsTest, RsaPkcs1Success) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001293 ASSERT_EQ(KM_ERROR_OK,
1294 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_PKCS1_1_5_ENCRYPT)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001295 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001296 string ciphertext1 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001297 EXPECT_EQ(512 / 8, ciphertext1.size());
1298
Shawn Willden6dde87c2014-12-11 14:08:48 -07001299 string ciphertext2 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001300 EXPECT_EQ(512 / 8, ciphertext2.size());
1301
1302 // PKCS1 v1.5 randomizes padding so every result should be different.
1303 EXPECT_NE(ciphertext1, ciphertext2);
1304}
1305
1306TEST_F(EncryptionOperationsTest, RsaPkcs1RoundTrip) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001307 ASSERT_EQ(KM_ERROR_OK,
1308 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_PKCS1_1_5_ENCRYPT)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001309 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001310 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001311 EXPECT_EQ(512 / 8, ciphertext.size());
1312
Shawn Willden6dde87c2014-12-11 14:08:48 -07001313 string plaintext = DecryptMessage(ciphertext);
Shawn Willden4200f212014-12-02 07:01:21 -07001314 EXPECT_EQ(message, plaintext);
1315}
1316
1317TEST_F(EncryptionOperationsTest, RsaPkcs1TooLarge) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001318 ASSERT_EQ(KM_ERROR_OK,
1319 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_PKCS1_1_5_ENCRYPT)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001320 string message = "12345678901234567890123456789012345678901234567890123";
Shawn Willden4200f212014-12-02 07:01:21 -07001321 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001322 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001323
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001324 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT));
1325 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001326 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -07001327 EXPECT_EQ(0, result.size());
1328}
1329
1330TEST_F(EncryptionOperationsTest, RsaPkcs1CorruptedDecrypt) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001331 ASSERT_EQ(KM_ERROR_OK,
1332 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_PKCS1_1_5_ENCRYPT)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001333 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001334 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001335 EXPECT_EQ(512 / 8, ciphertext.size());
1336
1337 // Corrupt the ciphertext
1338 ciphertext[512 / 8 / 2]++;
1339
Shawn Willden4200f212014-12-02 07:01:21 -07001340 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001341 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001342 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
1343 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001344 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -07001345 EXPECT_EQ(0, result.size());
1346}
1347
Shawn Willden907c3012014-12-08 15:51:55 -07001348TEST_F(EncryptionOperationsTest, AesOcbSuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001349 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001350 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001351 string ciphertext1 = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001352 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext1.size());
Shawn Willden907c3012014-12-08 15:51:55 -07001353
Shawn Willden6dde87c2014-12-11 14:08:48 -07001354 string ciphertext2 = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001355 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext2.size());
Shawn Willden907c3012014-12-08 15:51:55 -07001356
1357 // OCB uses a random nonce, so every output should be different
1358 EXPECT_NE(ciphertext1, ciphertext2);
1359}
1360
Shawn Willden6dde87c2014-12-11 14:08:48 -07001361TEST_F(EncryptionOperationsTest, AesOcbRoundTripSuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001362 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001363 string message = "Hello World!";
1364 string ciphertext = EncryptMessage(message);
1365 EXPECT_EQ(12 /* nonce */ + message.length() + 16 /* tag */, ciphertext.size());
1366
1367 string plaintext = DecryptMessage(ciphertext);
1368 EXPECT_EQ(message, plaintext);
1369}
1370
1371TEST_F(EncryptionOperationsTest, AesOcbRoundTripCorrupted) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001372 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001373 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001374 string ciphertext = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001375 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext.size());
Shawn Willden6dde87c2014-12-11 14:08:48 -07001376
1377 ciphertext[ciphertext.size() / 2]++;
1378
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001379 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001380
1381 string result;
1382 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001383 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001384 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001385 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001386}
1387
1388TEST_F(EncryptionOperationsTest, AesDecryptGarbage) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001389 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001390 string ciphertext(128, 'a');
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001391 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001392
1393 string result;
1394 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001395 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001396 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001397 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001398}
1399
1400TEST_F(EncryptionOperationsTest, AesDecryptTooShort) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001401 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001402
Shawn Willden6dde87c2014-12-11 14:08:48 -07001403 // Try decrypting garbage ciphertext that is too short to be valid (< nonce + tag).
Shawn Willden6dde87c2014-12-11 14:08:48 -07001404 string ciphertext(12 + 15, 'a');
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001405 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001406
1407 string result;
1408 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001409 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001410 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001411 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001412}
1413
1414TEST_F(EncryptionOperationsTest, AesOcbRoundTripEmptySuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001415 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001416 string message = "";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001417 string ciphertext = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001418 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext.size());
Shawn Willden6dde87c2014-12-11 14:08:48 -07001419
1420 string plaintext = DecryptMessage(ciphertext);
1421 EXPECT_EQ(message, plaintext);
1422}
1423
1424TEST_F(EncryptionOperationsTest, AesOcbRoundTripEmptyCorrupted) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001425 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001426 string message = "";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001427 string ciphertext = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001428 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext.size());
Shawn Willden6dde87c2014-12-11 14:08:48 -07001429
1430 ciphertext[ciphertext.size() / 2]++;
1431
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001432 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001433
1434 string result;
1435 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001436 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001437 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001438 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001439}
1440
1441TEST_F(EncryptionOperationsTest, AesOcbFullChunk) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001442 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001443 string message(4096, 'a');
1444 string ciphertext = EncryptMessage(message);
1445 EXPECT_EQ(12 /* nonce */ + message.length() + 16 /* tag */, ciphertext.size());
1446
1447 string plaintext = DecryptMessage(ciphertext);
1448 EXPECT_EQ(message, plaintext);
1449}
1450
1451TEST_F(EncryptionOperationsTest, AesOcbVariousChunkLengths) {
1452 for (unsigned chunk_length = 1; chunk_length <= 128; ++chunk_length) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001453 ASSERT_EQ(KM_ERROR_OK,
1454 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(chunk_length, 16)));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001455 string message(128, 'a');
1456 string ciphertext = EncryptMessage(message);
1457 int expected_tag_count = (message.length() + chunk_length - 1) / chunk_length;
1458 EXPECT_EQ(12 /* nonce */ + message.length() + 16 * expected_tag_count, ciphertext.size())
1459 << "Unexpected ciphertext size for chunk length " << chunk_length
1460 << " expected tag count was " << expected_tag_count
1461 << " but actual tag count was probably "
1462 << (ciphertext.size() - message.length() - 12) / 16;
1463
1464 string plaintext = DecryptMessage(ciphertext);
1465 EXPECT_EQ(message, plaintext);
1466 }
1467}
1468
1469TEST_F(EncryptionOperationsTest, AesOcbAbort) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001470 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001471 string message = "Hello";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001472
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001473 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001474
1475 string result;
1476 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001477 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
1478 EXPECT_EQ(message.length(), input_consumed);
1479 EXPECT_EQ(KM_ERROR_OK, AbortOperation());
Shawn Willden6dde87c2014-12-11 14:08:48 -07001480}
1481
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001482TEST_F(EncryptionOperationsTest, AesOcbNoChunkLength) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001483 EXPECT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder()
1484 .AesEncryptionKey(128)
1485 .Option(TAG_BLOCK_MODE, KM_MODE_OCB)
1486 .Option(TAG_MAC_LENGTH, 16)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001487 EXPECT_EQ(KM_ERROR_INVALID_ARGUMENT, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001488}
1489
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001490TEST_F(EncryptionOperationsTest, AesOcbPaddingUnsupported) {
Shawn Willdenf0f68b92014-12-30 16:03:28 -07001491 ASSERT_EQ(KM_ERROR_OK,
1492 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16).Option(
1493 TAG_PADDING, KM_PAD_ZERO)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001494 EXPECT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001495}
1496
1497TEST_F(EncryptionOperationsTest, AesOcbInvalidMacLength) {
Shawn Willden63ac0432014-12-29 14:07:08 -07001498 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 17)));
1499 EXPECT_EQ(KM_ERROR_INVALID_ARGUMENT, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001500}
1501
Shawn Willdenf0f68b92014-12-30 16:03:28 -07001502TEST_F(EncryptionOperationsTest, AesEcbRoundTripSuccess) {
1503 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).Option(TAG_BLOCK_MODE,
1504 KM_MODE_ECB)));
1505 // Two-block message.
1506 string message = "12345678901234567890123456789012";
1507 string ciphertext1 = EncryptMessage(message);
1508 EXPECT_EQ(message.size(), ciphertext1.size());
1509
1510 string ciphertext2 = EncryptMessage(string(message));
1511 EXPECT_EQ(message.size(), ciphertext2.size());
1512
1513 // ECB is deterministic.
1514 EXPECT_EQ(ciphertext1, ciphertext2);
1515
1516 string plaintext = DecryptMessage(ciphertext1);
1517 EXPECT_EQ(message, plaintext);
1518}
1519
1520TEST_F(EncryptionOperationsTest, AesEcbNoPaddingWrongInputSize) {
1521 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).Option(TAG_BLOCK_MODE,
1522 KM_MODE_ECB)));
1523 // Message is slightly shorter than two blocks.
1524 string message = "1234567890123456789012345678901";
1525
1526 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT));
1527 string ciphertext;
1528 size_t input_consumed;
1529 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &ciphertext, &input_consumed));
1530 EXPECT_EQ(message.size(), input_consumed);
1531 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&ciphertext));
1532}
1533
1534TEST_F(EncryptionOperationsTest, AesEcbPkcs7Padding) {
1535 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder()
1536 .AesEncryptionKey(128)
1537 .Option(TAG_BLOCK_MODE, KM_MODE_ECB)
1538 .Option(TAG_PADDING, KM_PAD_PKCS7)));
1539
1540 // Try various message lengths; all should work.
1541 for (int i = 0; i < 32; ++i) {
1542 string message(i, 'a');
1543 string ciphertext = EncryptMessage(message);
1544 EXPECT_EQ(i + 16 - (i % 16), ciphertext.size());
1545 string plaintext = DecryptMessage(ciphertext);
1546 EXPECT_EQ(message, plaintext);
1547 }
1548}
1549
1550TEST_F(EncryptionOperationsTest, AesEcbPkcs7PaddingCorrupted) {
1551 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder()
1552 .AesEncryptionKey(128)
1553 .Option(TAG_BLOCK_MODE, KM_MODE_ECB)
1554 .Option(TAG_PADDING, KM_PAD_PKCS7)));
1555
1556 string message = "a";
1557 string ciphertext = EncryptMessage(message);
1558 EXPECT_EQ(16, ciphertext.size());
1559 EXPECT_NE(ciphertext, message);
1560 ++ciphertext[ciphertext.size() / 2];
1561
1562 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
1563 string plaintext;
1564 size_t input_consumed;
1565 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &plaintext, &input_consumed));
1566 EXPECT_EQ(ciphertext.size(), input_consumed);
1567 EXPECT_EQ(KM_ERROR_INVALID_ARGUMENT, FinishOperation(&plaintext));
1568}
1569
1570TEST_F(EncryptionOperationsTest, AesCbcRoundTripSuccess) {
1571 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).Option(TAG_BLOCK_MODE,
1572 KM_MODE_CBC)));
1573 // Two-block message.
1574 string message = "12345678901234567890123456789012";
1575 string ciphertext1 = EncryptMessage(message);
1576 EXPECT_EQ(message.size() + 16, ciphertext1.size());
1577
1578 string ciphertext2 = EncryptMessage(string(message));
1579 EXPECT_EQ(message.size() + 16, ciphertext2.size());
1580
1581 // CBC uses random IVs, so ciphertexts shouldn't match.
1582 EXPECT_NE(ciphertext1, ciphertext2);
1583
1584 string plaintext = DecryptMessage(ciphertext1);
1585 EXPECT_EQ(message, plaintext);
1586}
1587
1588TEST_F(EncryptionOperationsTest, AesCbcIncrementalNoPadding) {
1589 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).Option(TAG_BLOCK_MODE,
1590 KM_MODE_CBC)));
1591
1592 int increment = 15;
1593 string message(240, 'a');
1594 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT));
1595 string ciphertext;
1596 size_t input_consumed;
1597 for (size_t i = 0; i < message.size(); i += increment)
1598 EXPECT_EQ(KM_ERROR_OK,
1599 UpdateOperation(message.substr(i, increment), &ciphertext, &input_consumed));
1600 EXPECT_EQ(KM_ERROR_OK, FinishOperation(&ciphertext));
1601 EXPECT_EQ(message.size() + 16, ciphertext.size());
1602
1603 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
1604 string plaintext;
1605 for (size_t i = 0; i < ciphertext.size(); i += increment)
1606 EXPECT_EQ(KM_ERROR_OK,
1607 UpdateOperation(ciphertext.substr(i, increment), &plaintext, &input_consumed));
1608 EXPECT_EQ(KM_ERROR_OK, FinishOperation(&plaintext));
1609 EXPECT_EQ(ciphertext.size() - 16, plaintext.size());
1610 EXPECT_EQ(message, plaintext);
1611}
1612
1613TEST_F(EncryptionOperationsTest, AesCbcPkcs7Padding) {
1614 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder()
1615 .AesEncryptionKey(128)
1616 .Option(TAG_BLOCK_MODE, KM_MODE_CBC)
1617 .Option(TAG_PADDING, KM_PAD_PKCS7)));
1618
1619 // Try various message lengths; all should work.
1620 for (int i = 0; i < 32; ++i) {
1621 string message(i, 'a');
1622 string ciphertext = EncryptMessage(message);
1623 EXPECT_EQ(i + 32 - (i % 16), ciphertext.size());
1624 string plaintext = DecryptMessage(ciphertext);
1625 EXPECT_EQ(message, plaintext);
1626 }
1627}
1628
1629TEST_F(EncryptionOperationsTest, AesCfbRoundTripSuccess) {
1630 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).Option(TAG_BLOCK_MODE,
1631 KM_MODE_CFB)));
1632 // Two-block message.
1633 string message = "12345678901234567890123456789012";
1634 string ciphertext1 = EncryptMessage(message);
1635 EXPECT_EQ(message.size() + 16, ciphertext1.size());
1636
1637 string ciphertext2 = EncryptMessage(string(message));
1638 EXPECT_EQ(message.size() + 16, ciphertext2.size());
1639
1640 // CBC uses random IVs, so ciphertexts shouldn't match.
1641 EXPECT_NE(ciphertext1, ciphertext2);
1642
1643 string plaintext = DecryptMessage(ciphertext1);
1644 EXPECT_EQ(message, plaintext);
1645}
1646
1647TEST_F(EncryptionOperationsTest, AesCfbIncrementalNoPadding) {
1648 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder()
1649 .AesEncryptionKey(128)
1650 .Option(TAG_BLOCK_MODE, KM_MODE_CFB)
1651 .Option(TAG_PADDING, KM_PAD_PKCS7)));
1652
1653 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).Option(TAG_BLOCK_MODE,
1654 KM_MODE_CBC)));
1655
1656 int increment = 15;
1657 string message(240, 'a');
1658 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT));
1659 string ciphertext;
1660 size_t input_consumed;
1661 for (size_t i = 0; i < message.size(); i += increment)
1662 EXPECT_EQ(KM_ERROR_OK,
1663 UpdateOperation(message.substr(i, increment), &ciphertext, &input_consumed));
1664 EXPECT_EQ(KM_ERROR_OK, FinishOperation(&ciphertext));
1665 EXPECT_EQ(message.size() + 16, ciphertext.size());
1666
1667 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
1668 string plaintext;
1669 for (size_t i = 0; i < ciphertext.size(); i += increment)
1670 EXPECT_EQ(KM_ERROR_OK,
1671 UpdateOperation(ciphertext.substr(i, increment), &plaintext, &input_consumed));
1672 EXPECT_EQ(KM_ERROR_OK, FinishOperation(&plaintext));
1673 EXPECT_EQ(ciphertext.size() - 16, plaintext.size());
1674 EXPECT_EQ(message, plaintext);
1675}
1676
1677TEST_F(EncryptionOperationsTest, AesCfbPkcs7Padding) {
1678 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).Option(TAG_BLOCK_MODE,
1679 KM_MODE_CFB)));
1680
1681 // Try various message lengths; all should work.
1682 for (int i = 0; i < 32; ++i) {
1683 string message(i, 'a');
1684 string ciphertext = EncryptMessage(message);
1685 EXPECT_EQ(i + 16, ciphertext.size());
1686 string plaintext = DecryptMessage(ciphertext);
1687 EXPECT_EQ(message, plaintext);
1688 }
1689}
1690
Shawn Willden128ffe02014-08-06 12:31:33 -06001691} // namespace test
1692} // namespace keymaster