blob: 9306143b3ab52f8a50d8f062ad3ef165964a9dac [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
Shawn Willden63ac0432014-12-29 14:07:08 -070047template <typename T> std::ostream& operator<<(std::ostream& os, const std::vector<T>& vec) {
48 os << "{ ";
49 bool first = true;
50 for (T t : vec) {
51 os << (first ? "" : ", ") << t;
52 if (first)
53 first = false;
54 }
55 os << " }";
56 return os;
57}
58
Shawn Willden128ffe02014-08-06 12:31:33 -060059namespace keymaster {
60namespace test {
61
Shawn Willdenb15d77e2014-12-17 16:44:29 -070062/**
63 * Utility class to make construction of AuthorizationSets easy, and readable. Use like:
64 *
65 * ParamBuilder()
66 * .Option(TAG_ALGORITHM, KM_ALGORITHM_RSA)
67 * .Option(TAG_KEY_SIZE, 512)
68 * .Option(TAG_DIGEST, KM_DIGEST_NONE)
69 * .Option(TAG_PADDING, KM_PAD_NONE)
70 * .Option(TAG_SINGLE_USE_PER_BOOT, true)
71 * .build();
72 *
73 * In addition there are methods that add common sets of parameters, like RsaSigningKey().
74 */
75class ParamBuilder {
76 public:
77 template <typename TagType, typename ValueType>
78 ParamBuilder& Option(TagType tag, ValueType value) {
79 set.push_back(tag, value);
80 return *this;
81 }
82
83 ParamBuilder& RsaKey(uint32_t key_size = 0, uint64_t public_exponent = 0) {
84 Option(TAG_ALGORITHM, KM_ALGORITHM_RSA);
85 if (key_size != 0)
86 Option(TAG_KEY_SIZE, key_size);
87 if (public_exponent != 0)
88 Option(TAG_RSA_PUBLIC_EXPONENT, public_exponent);
89 return *this;
90 }
91
92 ParamBuilder& EcdsaKey(uint32_t key_size = 0) {
93 Option(TAG_ALGORITHM, KM_ALGORITHM_ECDSA);
94 if (key_size != 0)
95 Option(TAG_KEY_SIZE, key_size);
96 return *this;
97 }
98
99 ParamBuilder& AesKey(uint32_t key_size) {
100 Option(TAG_ALGORITHM, KM_ALGORITHM_AES);
101 return Option(TAG_KEY_SIZE, key_size);
102 }
103
104 ParamBuilder& HmacKey(uint32_t key_size, keymaster_digest_t digest, uint32_t mac_length) {
105 Option(TAG_ALGORITHM, KM_ALGORITHM_HMAC);
106 Option(TAG_KEY_SIZE, key_size);
107 SigningKey();
108 Option(TAG_DIGEST, digest);
109 return Option(TAG_MAC_LENGTH, mac_length);
110 }
111
112 ParamBuilder& RsaSigningKey(uint32_t key_size = 0, keymaster_digest_t digest = KM_DIGEST_NONE,
113 keymaster_padding_t padding = KM_PAD_NONE,
114 uint64_t public_exponent = 0) {
115 RsaKey(key_size, public_exponent);
116 SigningKey();
117 Option(TAG_DIGEST, digest);
118 return Option(TAG_PADDING, padding);
119 }
120
121 ParamBuilder& RsaEncryptionKey(uint32_t key_size = 0,
122 keymaster_padding_t padding = KM_PAD_RSA_OAEP,
123 uint64_t public_exponent = 0) {
124 RsaKey(key_size, public_exponent);
125 EncryptionKey();
126 return Option(TAG_PADDING, padding);
127 }
128
129 ParamBuilder& EcdsaSigningKey(uint32_t key_size = 0) {
130 EcdsaKey(key_size);
131 return SigningKey();
132 }
133
134 ParamBuilder& AesEncryptionKey(uint32_t key_size) {
135 AesKey(key_size);
136 return EncryptionKey();
137 }
138
139 ParamBuilder& SigningKey() {
140 Option(TAG_PURPOSE, KM_PURPOSE_SIGN);
141 return Option(TAG_PURPOSE, KM_PURPOSE_VERIFY);
142 }
143
144 ParamBuilder& EncryptionKey() {
145 Option(TAG_PURPOSE, KM_PURPOSE_ENCRYPT);
146 return Option(TAG_PURPOSE, KM_PURPOSE_DECRYPT);
147 }
148
149 ParamBuilder& NoDigestOrPadding() {
150 Option(TAG_DIGEST, KM_DIGEST_NONE);
151 return Option(TAG_PADDING, KM_PAD_NONE);
152 }
153
154 ParamBuilder& OcbMode(uint32_t chunk_length, uint32_t mac_length) {
155 Option(TAG_BLOCK_MODE, KM_MODE_OCB);
156 Option(TAG_CHUNK_LENGTH, chunk_length);
157 return Option(TAG_MAC_LENGTH, mac_length);
158 }
159
160 AuthorizationSet build() const { return set; }
161
162 private:
163 AuthorizationSet set;
Shawn Willden6bbe6782014-09-18 11:26:15 -0600164};
165
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700166const uint64_t OP_HANDLE_SENTINEL = 0xFFFFFFFFFFFFFFFF;
Shawn Willden128ffe02014-08-06 12:31:33 -0600167class KeymasterTest : public testing::Test {
168 protected:
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700169 KeymasterTest()
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700170 : device_(new StdoutLogger), out_params_(NULL), op_handle_(OP_HANDLE_SENTINEL),
171 characteristics_(NULL) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700172 blob_.key_material = NULL;
173 RAND_seed("foobar", 6);
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700174 blob_.key_material = 0;
Shawn Willden5b53c992015-02-02 08:05:25 -0700175 }
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700176
Shawn Willden5b53c992015-02-02 08:05:25 -0700177 ~KeymasterTest() {
178 FreeCharacteristics();
179 FreeKeyBlob();
Shawn Willdend0772312014-09-18 12:27:57 -0600180 }
181
Shawn Willden5b53c992015-02-02 08:05:25 -0700182 keymaster_device* device() { return reinterpret_cast<keymaster_device*>(device_.hw_device()); }
183
Shawn Willdenc24c1102014-12-22 15:30:09 -0700184 keymaster_error_t GenerateKey(const ParamBuilder& builder) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700185 AuthorizationSet params(builder.build());
186 params.push_back(UserAuthParams());
187 params.push_back(ClientParams());
188
Shawn Willden0d560bf2014-12-15 17:44:02 -0700189 FreeKeyBlob();
190 FreeCharacteristics();
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700191 return device()->generate_key(device(), params.data(), params.size(), &blob_,
192 &characteristics_);
Shawn Willden0d560bf2014-12-15 17:44:02 -0700193 }
194
Shawn Willdenc24c1102014-12-22 15:30:09 -0700195 keymaster_error_t ImportKey(const ParamBuilder& builder, keymaster_key_format_t format,
196 const string& key_material) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700197 AuthorizationSet params(builder.build());
198 params.push_back(UserAuthParams());
199 params.push_back(ClientParams());
200
201 FreeKeyBlob();
202 FreeCharacteristics();
203 return device()->import_key(device(), params.data(), params.size(), format,
204 reinterpret_cast<const uint8_t*>(key_material.c_str()),
205 key_material.length(), &blob_, &characteristics_);
206 }
207
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700208 AuthorizationSet UserAuthParams() {
209 AuthorizationSet set;
210 set.push_back(TAG_USER_ID, 7);
211 set.push_back(TAG_USER_AUTH_ID, 8);
212 set.push_back(TAG_AUTH_TIMEOUT, 300);
213 return set;
214 }
215
216 AuthorizationSet ClientParams() {
217 AuthorizationSet set;
218 set.push_back(TAG_APPLICATION_ID, "app_id", 6);
219 return set;
220 }
221
222 keymaster_error_t BeginOperation(keymaster_purpose_t purpose) {
223 return device()->begin(device(), purpose, &blob_, client_params_,
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700224 array_length(client_params_), &out_params_, &out_params_count_,
225 &op_handle_);
226 }
227
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700228 keymaster_error_t UpdateOperation(const string& message, string* output,
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700229 size_t* input_consumed) {
230 uint8_t* out_tmp = NULL;
231 size_t out_length;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700232 EXPECT_NE(op_handle_, OP_HANDLE_SENTINEL);
233 keymaster_error_t error = device()->update(
Shawn Willden6bfbff02015-02-06 19:48:24 -0700234 device(), op_handle_, NULL /* additional_params */, 0 /* additional_params_count */,
235 reinterpret_cast<const uint8_t*>(message.c_str()), message.length(), input_consumed,
236 &out_tmp, &out_length);
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700237 if (out_tmp)
238 output->append(reinterpret_cast<char*>(out_tmp), out_length);
239 free(out_tmp);
240 return error;
241 }
242
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700243 keymaster_error_t FinishOperation(string* output) { return FinishOperation("", output); }
244
245 keymaster_error_t FinishOperation(const string& signature, string* output) {
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700246 uint8_t* out_tmp = NULL;
247 size_t out_length;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700248 keymaster_error_t error = device()->finish(
Shawn Willden6bfbff02015-02-06 19:48:24 -0700249 device(), op_handle_, NULL /* additional_params */, 0 /* additional_params_count */,
250 reinterpret_cast<const uint8_t*>(signature.c_str()), signature.length(), &out_tmp,
251 &out_length);
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700252 if (out_tmp)
253 output->append(reinterpret_cast<char*>(out_tmp), out_length);
254 free(out_tmp);
255 return error;
256 }
257
Shawn Willden76076ab2014-12-18 08:36:35 -0700258 template <typename T>
259 bool ResponseContains(const vector<T>& expected, const T* values, size_t len) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700260 return expected.size() == len &&
261 std::is_permutation(values, values + len, expected.begin());
Shawn Willden76076ab2014-12-18 08:36:35 -0700262 }
263
264 template <typename T> bool ResponseContains(T expected, const T* values, size_t len) {
265 return (len == 1 && *values == expected);
Shawn Willdend0772312014-09-18 12:27:57 -0600266 }
267
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700268 keymaster_error_t AbortOperation() { return device()->abort(device(), op_handle_); }
269
270 string ProcessMessage(keymaster_purpose_t purpose, const string& message) {
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(&result));
278 return result;
279 }
280
281 string ProcessMessage(keymaster_purpose_t purpose, const string& message,
282 const string& signature) {
283 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose));
284
285 string result;
286 size_t input_consumed;
287 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
288 EXPECT_EQ(message.size(), input_consumed);
289 EXPECT_EQ(KM_ERROR_OK, FinishOperation(signature, &result));
290 return result;
291 }
292
293 void SignMessage(const string& message, string* signature) {
Shawn Willden63ac0432014-12-29 14:07:08 -0700294 SCOPED_TRACE("SignMessage");
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700295 *signature = ProcessMessage(KM_PURPOSE_SIGN, message);
296 EXPECT_GT(signature->size(), 0);
297 }
298
299 void VerifyMessage(const string& message, const string& signature) {
Shawn Willden63ac0432014-12-29 14:07:08 -0700300 SCOPED_TRACE("VerifyMessage");
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700301 ProcessMessage(KM_PURPOSE_VERIFY, message, signature);
302 }
303
304 string EncryptMessage(const string& message) {
Shawn Willden63ac0432014-12-29 14:07:08 -0700305 SCOPED_TRACE("EncryptMessage");
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700306 return ProcessMessage(KM_PURPOSE_ENCRYPT, message);
307 }
308
309 string DecryptMessage(const string& ciphertext) {
Shawn Willden63ac0432014-12-29 14:07:08 -0700310 SCOPED_TRACE("DecryptMessage");
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700311 return ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext);
312 }
313
314 keymaster_error_t GetCharacteristics() {
315 FreeCharacteristics();
316 return device()->get_key_characteristics(device(), &blob_, &client_id_, NULL /* app_data */,
317 &characteristics_);
318 }
319
320 keymaster_error_t ExportKey(keymaster_key_format_t format, string* export_data) {
321 uint8_t* export_data_tmp;
322 size_t export_data_length;
323
324 keymaster_error_t error =
325 device()->export_key(device(), format, &blob_, &client_id_, NULL /* app_data */,
326 &export_data_tmp, &export_data_length);
327
328 if (error != KM_ERROR_OK)
329 return error;
330
331 *export_data = string(reinterpret_cast<char*>(export_data_tmp), export_data_length);
332 free(export_data_tmp);
333 return error;
334 }
335
336 keymaster_error_t GetVersion(uint8_t* major, uint8_t* minor, uint8_t* subminor) {
337 GetVersionRequest request;
338 GetVersionResponse response;
339 device_.GetVersion(request, &response);
340 if (response.error != KM_ERROR_OK)
341 return response.error;
342 *major = response.major_ver;
343 *minor = response.minor_ver;
344 *subminor = response.subminor_ver;
345 return response.error;
346 }
347
348 AuthorizationSet hw_enforced() {
349 EXPECT_TRUE(characteristics_ != NULL);
350 return AuthorizationSet(characteristics_->hw_enforced);
351 }
352
353 AuthorizationSet sw_enforced() {
354 EXPECT_TRUE(characteristics_ != NULL);
355 return AuthorizationSet(characteristics_->sw_enforced);
356 }
357
Shawn Willden5b53c992015-02-02 08:05:25 -0700358 void FreeCharacteristics() {
359 keymaster_free_characteristics(characteristics_);
360 free(characteristics_);
361 characteristics_ = NULL;
362 }
363
364 void FreeKeyBlob() {
365 free(const_cast<uint8_t*>(blob_.key_material));
366 blob_.key_material = NULL;
367 }
368
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700369 void corrupt_key_blob() {
370 assert(blob_.key_material);
371 uint8_t* tmp = const_cast<uint8_t*>(blob_.key_material);
372 ++tmp[blob_.key_material_size / 2];
373 }
Shawn Willden5b53c992015-02-02 08:05:25 -0700374
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700375 private:
376 SoftKeymasterDevice device_;
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700377 keymaster_blob_t client_id_ = {.data = reinterpret_cast<const uint8_t*>("app_id"),
378 .data_length = 6};
379 keymaster_key_param_t client_params_[1] = {
380 Authorization(TAG_APPLICATION_ID, client_id_.data, client_id_.data_length)};
381
382 keymaster_key_param_t* out_params_;
383 size_t out_params_count_;
384 uint64_t op_handle_;
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700385
Shawn Willden5b53c992015-02-02 08:05:25 -0700386 keymaster_key_blob_t blob_;
387 keymaster_key_characteristics_t* characteristics_;
Shawn Willden128ffe02014-08-06 12:31:33 -0600388};
389
Shawn Willden128ffe02014-08-06 12:31:33 -0600390typedef KeymasterTest CheckSupported;
391TEST_F(CheckSupported, SupportedAlgorithms) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700392 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
393 device()->get_supported_algorithms(device(), NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600394
Shawn Willden5b53c992015-02-02 08:05:25 -0700395 size_t len;
396 keymaster_algorithm_t* algorithms;
397 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_algorithms(device(), &algorithms, &len));
Shawn Willdena278f612014-12-23 11:22:21 -0700398 EXPECT_TRUE(ResponseContains(
399 {KM_ALGORITHM_RSA, KM_ALGORITHM_ECDSA, KM_ALGORITHM_AES, KM_ALGORITHM_HMAC}, algorithms,
400 len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700401 free(algorithms);
Shawn Willden128ffe02014-08-06 12:31:33 -0600402}
403
404TEST_F(CheckSupported, SupportedBlockModes) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700405 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
406 device()->get_supported_block_modes(device(), KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT,
407 NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600408
Shawn Willden5b53c992015-02-02 08:05:25 -0700409 size_t len;
410 keymaster_block_mode_t* modes;
Shawn Willden63ac0432014-12-29 14:07:08 -0700411 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_block_modes(device(), KM_ALGORITHM_RSA,
412 KM_PURPOSE_ENCRYPT, &modes, &len));
413 EXPECT_EQ(0, len);
414 free(modes);
Shawn Willden128ffe02014-08-06 12:31:33 -0600415
Shawn Willden76076ab2014-12-18 08:36:35 -0700416 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM,
Shawn Willden5b53c992015-02-02 08:05:25 -0700417 device()->get_supported_block_modes(device(), KM_ALGORITHM_DSA, KM_PURPOSE_ENCRYPT,
418 &modes, &len));
Shawn Willden28e41472014-08-18 13:35:22 -0600419
Shawn Willden63ac0432014-12-29 14:07:08 -0700420 EXPECT_EQ(KM_ERROR_UNSUPPORTED_PURPOSE,
Shawn Willden5b53c992015-02-02 08:05:25 -0700421 device()->get_supported_block_modes(device(), KM_ALGORITHM_ECDSA, KM_PURPOSE_ENCRYPT,
422 &modes, &len));
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600423
Shawn Willden63ac0432014-12-29 14:07:08 -0700424 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_block_modes(device(), KM_ALGORITHM_AES,
425 KM_PURPOSE_ENCRYPT, &modes, &len));
426 EXPECT_TRUE(ResponseContains({KM_MODE_OCB}, modes, len));
427 free(modes);
Shawn Willden128ffe02014-08-06 12:31:33 -0600428}
429
430TEST_F(CheckSupported, SupportedPaddingModes) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700431 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
432 device()->get_supported_padding_modes(device(), KM_ALGORITHM_RSA, KM_PURPOSE_ENCRYPT,
433 NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600434
Shawn Willden5b53c992015-02-02 08:05:25 -0700435 size_t len;
436 keymaster_padding_t* modes;
437 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_RSA,
438 KM_PURPOSE_SIGN, &modes, &len));
Shawn Willden63ac0432014-12-29 14:07:08 -0700439 EXPECT_TRUE(ResponseContains({KM_PAD_NONE}, modes, len));
440 free(modes);
441
442 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_RSA,
443 KM_PURPOSE_ENCRYPT, &modes, &len));
444 EXPECT_TRUE(ResponseContains({KM_PAD_RSA_OAEP, KM_PAD_RSA_PKCS1_1_5_ENCRYPT}, modes, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700445 free(modes);
Shawn Willden128ffe02014-08-06 12:31:33 -0600446
Shawn Willden76076ab2014-12-18 08:36:35 -0700447 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM,
448 device()->get_supported_padding_modes(device(), KM_ALGORITHM_DSA, KM_PURPOSE_SIGN,
449 &modes, &len));
Shawn Willden28e41472014-08-18 13:35:22 -0600450
Shawn Willden5b53c992015-02-02 08:05:25 -0700451 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_padding_modes(device(), KM_ALGORITHM_ECDSA,
452 KM_PURPOSE_SIGN, &modes, &len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700453 EXPECT_EQ(0, len);
454 free(modes);
Shawn Willden63ac0432014-12-29 14:07:08 -0700455
456 EXPECT_EQ(KM_ERROR_UNSUPPORTED_PURPOSE,
457 device()->get_supported_padding_modes(device(), KM_ALGORITHM_AES, KM_PURPOSE_SIGN,
458 &modes, &len));
Shawn Willden128ffe02014-08-06 12:31:33 -0600459}
460
461TEST_F(CheckSupported, SupportedDigests) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700462 EXPECT_EQ(
463 KM_ERROR_OUTPUT_PARAMETER_NULL,
464 device()->get_supported_digests(device(), KM_ALGORITHM_RSA, KM_PURPOSE_SIGN, NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600465
Shawn Willden5b53c992015-02-02 08:05:25 -0700466 size_t len;
467 keymaster_digest_t* digests;
468 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_RSA,
469 KM_PURPOSE_SIGN, &digests, &len));
Shawn Willden63ac0432014-12-29 14:07:08 -0700470 EXPECT_TRUE(ResponseContains({KM_DIGEST_NONE}, digests, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700471 free(digests);
Shawn Willden128ffe02014-08-06 12:31:33 -0600472
Shawn Willden76076ab2014-12-18 08:36:35 -0700473 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM,
474 device()->get_supported_digests(device(), KM_ALGORITHM_DSA, KM_PURPOSE_SIGN, &digests,
475 &len));
Shawn Willden28e41472014-08-18 13:35:22 -0600476
Shawn Willden5b53c992015-02-02 08:05:25 -0700477 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_ECDSA,
478 KM_PURPOSE_SIGN, &digests, &len));
Shawn Willden63ac0432014-12-29 14:07:08 -0700479 EXPECT_EQ(0, len);
Shawn Willden5b53c992015-02-02 08:05:25 -0700480 free(digests);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600481
Shawn Willden63ac0432014-12-29 14:07:08 -0700482 EXPECT_EQ(KM_ERROR_UNSUPPORTED_PURPOSE,
483 device()->get_supported_digests(device(), KM_ALGORITHM_AES, KM_PURPOSE_SIGN, &digests,
484 &len));
485
486 EXPECT_EQ(KM_ERROR_OK, device()->get_supported_digests(device(), KM_ALGORITHM_HMAC,
Shawn Willden5b53c992015-02-02 08:05:25 -0700487 KM_PURPOSE_SIGN, &digests, &len));
Shawn Willden63ac0432014-12-29 14:07:08 -0700488 EXPECT_TRUE(ResponseContains({KM_DIGEST_SHA_2_224, KM_DIGEST_SHA_2_256, KM_DIGEST_SHA_2_384,
489 KM_DIGEST_SHA_2_512, KM_DIGEST_SHA1},
490 digests, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700491 free(digests);
Shawn Willden128ffe02014-08-06 12:31:33 -0600492}
493
494TEST_F(CheckSupported, SupportedImportFormats) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700495 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
496 device()->get_supported_import_formats(device(), KM_ALGORITHM_RSA, NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600497
Shawn Willden5b53c992015-02-02 08:05:25 -0700498 size_t len;
499 keymaster_key_format_t* formats;
500 EXPECT_EQ(KM_ERROR_OK,
501 device()->get_supported_import_formats(device(), KM_ALGORITHM_RSA, &formats, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700502 EXPECT_TRUE(ResponseContains(KM_KEY_FORMAT_PKCS8, formats, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700503 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600504}
505
506TEST_F(CheckSupported, SupportedExportFormats) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700507 EXPECT_EQ(KM_ERROR_OUTPUT_PARAMETER_NULL,
508 device()->get_supported_export_formats(device(), KM_ALGORITHM_RSA, NULL, NULL));
Shawn Willden128ffe02014-08-06 12:31:33 -0600509
Shawn Willden5b53c992015-02-02 08:05:25 -0700510 size_t len;
511 keymaster_key_format_t* formats;
512 EXPECT_EQ(KM_ERROR_OK,
513 device()->get_supported_export_formats(device(), KM_ALGORITHM_RSA, &formats, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700514 EXPECT_TRUE(ResponseContains(KM_KEY_FORMAT_X509, formats, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700515 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600516
Shawn Willden76076ab2014-12-18 08:36:35 -0700517 EXPECT_EQ(KM_ERROR_UNSUPPORTED_ALGORITHM,
Shawn Willden5b53c992015-02-02 08:05:25 -0700518 device()->get_supported_export_formats(device(), KM_ALGORITHM_DSA, &formats, &len));
Shawn Willden28e41472014-08-18 13:35:22 -0600519
Shawn Willden5b53c992015-02-02 08:05:25 -0700520 EXPECT_EQ(KM_ERROR_OK,
521 device()->get_supported_export_formats(device(), KM_ALGORITHM_ECDSA, &formats, &len));
Shawn Willden76076ab2014-12-18 08:36:35 -0700522 EXPECT_TRUE(ResponseContains(KM_KEY_FORMAT_X509, formats, len));
Shawn Willden5b53c992015-02-02 08:05:25 -0700523 free(formats);
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600524
Shawn Willden5b53c992015-02-02 08:05:25 -0700525 EXPECT_EQ(KM_ERROR_OK,
526 device()->get_supported_export_formats(device(), KM_ALGORITHM_AES, &formats, &len));
527 EXPECT_EQ(0, len);
528 free(formats);
Shawn Willden128ffe02014-08-06 12:31:33 -0600529}
530
Shawn Willden5b53c992015-02-02 08:05:25 -0700531TEST_F(KeymasterTest, TestFlags) {
532 EXPECT_TRUE(device()->flags & KEYMASTER_SOFTWARE_ONLY);
533 EXPECT_TRUE(device()->flags & KEYMASTER_BLOBS_ARE_STANDALONE);
534 EXPECT_FALSE(device()->flags & KEYMASTER_SUPPORTS_DSA);
535 EXPECT_TRUE(device()->flags & KEYMASTER_SUPPORTS_EC);
536}
537
538typedef KeymasterTest OldKeyGeneration;
539
540TEST_F(OldKeyGeneration, Rsa) {
541 keymaster_rsa_keygen_params_t params = {.modulus_size = 256, .public_exponent = 3};
542 uint8_t* key_blob;
543 size_t key_blob_length;
544 EXPECT_EQ(0,
545 device()->generate_keypair(device(), TYPE_RSA, &params, &key_blob, &key_blob_length));
546 EXPECT_GT(key_blob_length, 0);
547
548 free(key_blob);
549}
550
Shawn Willdenddf2d672015-02-20 16:37:12 -0700551TEST_F(OldKeyGeneration, Ecdsa256) {
Shawn Willden5b53c992015-02-02 08:05:25 -0700552 keymaster_ec_keygen_params_t params = {.field_size = 256};
553 uint8_t* key_blob;
554 size_t key_blob_length;
555 EXPECT_EQ(0,
556 device()->generate_keypair(device(), TYPE_EC, &params, &key_blob, &key_blob_length));
557 EXPECT_GT(key_blob_length, 0);
558
559 free(key_blob);
560}
561
Shawn Willdenddf2d672015-02-20 16:37:12 -0700562TEST_F(OldKeyGeneration, Ecdsa192Fails) {
563 keymaster_ec_keygen_params_t params = {.field_size = 192};
564 uint8_t* key_blob;
565 size_t key_blob_length;
566 EXPECT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE,
567 device()->generate_keypair(device(), TYPE_EC, &params, &key_blob, &key_blob_length));
568}
569
Shawn Willdend0772312014-09-18 12:27:57 -0600570class NewKeyGeneration : public KeymasterTest {
571 protected:
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700572 void CheckBaseParams() {
573 EXPECT_EQ(0U, hw_enforced().size());
574 EXPECT_EQ(12U, hw_enforced().SerializedSize());
Shawn Willdend0772312014-09-18 12:27:57 -0600575
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700576 AuthorizationSet auths = sw_enforced();
577 EXPECT_GT(auths.SerializedSize(), 12U);
578
Shawn Willden5b53c992015-02-02 08:05:25 -0700579 EXPECT_TRUE(contains(auths, TAG_PURPOSE, KM_PURPOSE_SIGN));
580 EXPECT_TRUE(contains(auths, TAG_PURPOSE, KM_PURPOSE_VERIFY));
581 EXPECT_TRUE(contains(auths, TAG_USER_ID, 7));
582 EXPECT_TRUE(contains(auths, TAG_USER_AUTH_ID, 8));
583 EXPECT_TRUE(contains(auths, TAG_AUTH_TIMEOUT, 300));
Shawn Willdend0772312014-09-18 12:27:57 -0600584
585 // Verify that App ID, App data and ROT are NOT included.
Shawn Willden5b53c992015-02-02 08:05:25 -0700586 EXPECT_FALSE(contains(auths, TAG_ROOT_OF_TRUST));
587 EXPECT_FALSE(contains(auths, TAG_APPLICATION_ID));
588 EXPECT_FALSE(contains(auths, TAG_APPLICATION_DATA));
Shawn Willdend0772312014-09-18 12:27:57 -0600589
590 // Just for giggles, check that some unexpected tags/values are NOT present.
Shawn Willden5b53c992015-02-02 08:05:25 -0700591 EXPECT_FALSE(contains(auths, TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
592 EXPECT_FALSE(contains(auths, TAG_PURPOSE, KM_PURPOSE_DECRYPT));
593 EXPECT_FALSE(contains(auths, TAG_AUTH_TIMEOUT, 301));
Shawn Willdend0772312014-09-18 12:27:57 -0600594
595 // Now check that unspecified, defaulted tags are correct.
Shawn Willden5b53c992015-02-02 08:05:25 -0700596 EXPECT_TRUE(contains(auths, TAG_ORIGIN, KM_ORIGIN_SOFTWARE));
597 EXPECT_TRUE(contains(auths, KM_TAG_CREATION_DATETIME));
Shawn Willdend0772312014-09-18 12:27:57 -0600598 }
Shawn Willden2079ae82015-01-22 13:42:31 -0700599};
600
Shawn Willden128ffe02014-08-06 12:31:33 -0600601TEST_F(NewKeyGeneration, Rsa) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700602 ASSERT_EQ(KM_ERROR_OK,
603 GenerateKey(ParamBuilder().RsaSigningKey(256, KM_DIGEST_NONE, KM_PAD_NONE, 3)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700604 CheckBaseParams();
Shawn Willden128ffe02014-08-06 12:31:33 -0600605
Shawn Willden5b53c992015-02-02 08:05:25 -0700606 // Check specified tags are all present in auths
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700607 AuthorizationSet auths(sw_enforced());
Shawn Willden5b53c992015-02-02 08:05:25 -0700608 EXPECT_TRUE(contains(auths, TAG_ALGORITHM, KM_ALGORITHM_RSA));
609 EXPECT_TRUE(contains(auths, TAG_KEY_SIZE, 256));
610 EXPECT_TRUE(contains(auths, TAG_RSA_PUBLIC_EXPONENT, 3));
Shawn Willden128ffe02014-08-06 12:31:33 -0600611}
612
Shawn Willden6bbe6782014-09-18 11:26:15 -0600613TEST_F(NewKeyGeneration, RsaDefaultSize) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700614 // TODO(swillden): Remove support for defaulting RSA parameter size and pub exponent.
Shawn Willdenc24c1102014-12-22 15:30:09 -0700615 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey()));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700616 CheckBaseParams();
Shawn Willden6bbe6782014-09-18 11:26:15 -0600617
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700618 // Check specified tags are all present in unenforced characteristics
619 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_RSA));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600620
621 // Now check that unspecified, defaulted tags are correct.
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700622 EXPECT_TRUE(contains(sw_enforced(), TAG_RSA_PUBLIC_EXPONENT, 65537));
623 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 2048));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600624}
625
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600626TEST_F(NewKeyGeneration, Ecdsa) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700627 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().EcdsaSigningKey(224)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700628 CheckBaseParams();
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600629
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700630 // Check specified tags are all present in unenforced characteristics
631 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
632 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 224));
Shawn Willdenc3864dd2014-08-18 15:20:01 -0600633}
634
Shawn Willden6bbe6782014-09-18 11:26:15 -0600635TEST_F(NewKeyGeneration, EcdsaDefaultSize) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700636 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().EcdsaSigningKey()));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700637 CheckBaseParams();
Shawn Willden6bbe6782014-09-18 11:26:15 -0600638
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700639 // Check specified tags are all present in unenforced characteristics
640 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600641
642 // Now check that unspecified, defaulted tags are correct.
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700643 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 224));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600644}
645
646TEST_F(NewKeyGeneration, EcdsaInvalidSize) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700647 ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE, GenerateKey(ParamBuilder().EcdsaSigningKey(190)));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600648}
649
650TEST_F(NewKeyGeneration, EcdsaAllValidSizes) {
Shawn Willden8c856c82014-09-26 09:34:36 -0600651 size_t valid_sizes[] = {224, 256, 384, 521};
Shawn Willden6bbe6782014-09-18 11:26:15 -0600652 for (size_t size : valid_sizes) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700653 EXPECT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().EcdsaSigningKey(size)))
Shawn Willden5b53c992015-02-02 08:05:25 -0700654 << "Failed to generate size: " << size;
Shawn Willden6bbe6782014-09-18 11:26:15 -0600655 }
656}
657
Shawn Willden19fca882015-01-22 16:35:30 -0700658TEST_F(NewKeyGeneration, AesOcb) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700659 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willden19fca882015-01-22 16:35:30 -0700660}
661
662TEST_F(NewKeyGeneration, AesOcbInvalidKeySize) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700663 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(136).OcbMode(4096, 16)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700664 EXPECT_EQ(KM_ERROR_UNSUPPORTED_KEY_SIZE, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willden19fca882015-01-22 16:35:30 -0700665}
666
667TEST_F(NewKeyGeneration, AesOcbAllValidSizes) {
Shawn Willden19fca882015-01-22 16:35:30 -0700668 size_t valid_sizes[] = {128, 192, 256};
669 for (size_t size : valid_sizes) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700670 EXPECT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(size)))
Shawn Willden5b53c992015-02-02 08:05:25 -0700671 << "Failed to generate size: " << size;
Shawn Willden19fca882015-01-22 16:35:30 -0700672 }
673}
674
Shawn Willden0d560bf2014-12-15 17:44:02 -0700675TEST_F(NewKeyGeneration, HmacSha256) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700676 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_256, 16)));
Shawn Willden0d560bf2014-12-15 17:44:02 -0700677}
678
Shawn Willden76364712014-08-11 17:48:04 -0600679typedef KeymasterTest GetKeyCharacteristics;
680TEST_F(GetKeyCharacteristics, SimpleRsa) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700681 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey(256)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700682 AuthorizationSet original(sw_enforced());
Shawn Willden76364712014-08-11 17:48:04 -0600683
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700684 ASSERT_EQ(KM_ERROR_OK, GetCharacteristics());
685 EXPECT_EQ(original, sw_enforced());
Shawn Willden76364712014-08-11 17:48:04 -0600686}
687
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700688typedef KeymasterTest SigningOperationsTest;
Shawn Willden1615f2e2014-08-13 10:37:40 -0600689TEST_F(SigningOperationsTest, RsaSuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700690 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey(256)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700691 string message = "12345678901234567890123456789012";
692 string signature;
693 SignMessage(message, &signature);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600694}
695
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600696TEST_F(SigningOperationsTest, EcdsaSuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700697 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().EcdsaSigningKey(224)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700698 string message = "123456789012345678901234567890123456789012345678";
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700699 string signature;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700700 SignMessage(message, &signature);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600701}
702
Shawn Willden1615f2e2014-08-13 10:37:40 -0600703TEST_F(SigningOperationsTest, RsaAbort) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700704 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey(256)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700705 ASSERT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_SIGN));
706 EXPECT_EQ(KM_ERROR_OK, AbortOperation());
707 // Another abort should fail
708 EXPECT_EQ(KM_ERROR_INVALID_OPERATION_HANDLE, AbortOperation());
Shawn Willden1615f2e2014-08-13 10:37:40 -0600709}
710
711TEST_F(SigningOperationsTest, RsaUnsupportedDigest) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700712 GenerateKey(ParamBuilder().RsaSigningKey(256, KM_DIGEST_SHA_2_256, KM_PAD_NONE));
713 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600714}
715
716TEST_F(SigningOperationsTest, RsaUnsupportedPadding) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700717 GenerateKey(ParamBuilder().RsaSigningKey(256, KM_DIGEST_NONE, KM_PAD_RSA_OAEP));
718 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600719}
720
721TEST_F(SigningOperationsTest, RsaNoDigest) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700722 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaKey(256).SigningKey().Option(
723 TAG_PADDING, KM_PAD_NONE)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700724 ASSERT_EQ(KM_ERROR_UNSUPPORTED_DIGEST, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600725}
726
727TEST_F(SigningOperationsTest, RsaNoPadding) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700728 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaKey(256).SigningKey().Option(
729 TAG_DIGEST, KM_DIGEST_NONE)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700730 ASSERT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden1615f2e2014-08-13 10:37:40 -0600731}
732
Shawn Willden62c22862014-12-17 08:36:20 -0700733TEST_F(SigningOperationsTest, HmacSha224Success) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700734 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_224, 28)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700735 string message = "12345678901234567890123456789012";
736 string signature;
737 SignMessage(message, &signature);
738 ASSERT_EQ(28, signature.size());
Shawn Willden62c22862014-12-17 08:36:20 -0700739}
740
Shawn Willden0d560bf2014-12-15 17:44:02 -0700741TEST_F(SigningOperationsTest, HmacSha256Success) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700742 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_256, 32)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700743 string message = "12345678901234567890123456789012";
744 string signature;
745 SignMessage(message, &signature);
746 ASSERT_EQ(32, signature.size());
Shawn Willden0d560bf2014-12-15 17:44:02 -0700747}
748
Shawn Willden62c22862014-12-17 08:36:20 -0700749TEST_F(SigningOperationsTest, HmacSha384Success) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700750 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_384, 48)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700751 string message = "12345678901234567890123456789012";
752 string signature;
753 SignMessage(message, &signature);
754 ASSERT_EQ(48, signature.size());
Shawn Willden62c22862014-12-17 08:36:20 -0700755}
756
757TEST_F(SigningOperationsTest, HmacSha512Success) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700758 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_512, 64)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700759 string message = "12345678901234567890123456789012";
Shawn Willden62c22862014-12-17 08:36:20 -0700760 string signature;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700761 SignMessage(message, &signature);
762 ASSERT_EQ(64, signature.size());
Shawn Willden62c22862014-12-17 08:36:20 -0700763}
764
765// TODO(swillden): Add HMACSHA{224|256|384|512} tests that validates against the test vectors from
766// RFC4231. Doing that requires being able to import keys, rather than just
767// generate them randomly.
Shawn Willden0d560bf2014-12-15 17:44:02 -0700768
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700769TEST_F(SigningOperationsTest, HmacSha256NoMacLength) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700770 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder()
771 .Option(TAG_ALGORITHM, KM_ALGORITHM_HMAC)
772 .Option(TAG_KEY_SIZE, 128)
773 .SigningKey()
774 .Option(TAG_DIGEST, KM_DIGEST_SHA_2_256)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700775 EXPECT_EQ(KM_ERROR_UNSUPPORTED_MAC_LENGTH, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden0d560bf2014-12-15 17:44:02 -0700776}
777
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700778TEST_F(SigningOperationsTest, HmacSha256TooLargeMacLength) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700779 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_256, 33)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700780 ASSERT_EQ(KM_ERROR_UNSUPPORTED_MAC_LENGTH, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willden0d560bf2014-12-15 17:44:02 -0700781}
782
Shawn Willden1615f2e2014-08-13 10:37:40 -0600783TEST_F(SigningOperationsTest, RsaTooShortMessage) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700784 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey(256)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700785 ASSERT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_SIGN));
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700786
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700787 string message = "1234567890123456789012345678901";
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700788 string result;
789 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700790 ASSERT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700791 EXPECT_EQ(0U, result.size());
792 EXPECT_EQ(31U, input_consumed);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600793
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700794 string signature;
795 ASSERT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&signature));
796 EXPECT_EQ(0U, signature.length());
Shawn Willden43e999e2014-08-13 13:29:50 -0600797}
798
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700799typedef KeymasterTest VerificationOperationsTest;
Shawn Willden43e999e2014-08-13 13:29:50 -0600800TEST_F(VerificationOperationsTest, RsaSuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700801 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey(256)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700802 string message = "12345678901234567890123456789012";
803 string signature;
804 SignMessage(message, &signature);
805 VerifyMessage(message, signature);
Shawn Willden1615f2e2014-08-13 10:37:40 -0600806}
807
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600808TEST_F(VerificationOperationsTest, EcdsaSuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700809 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().EcdsaSigningKey(256)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700810 string message = "123456789012345678901234567890123456789012345678";
811 string signature;
812 SignMessage(message, &signature);
813 VerifyMessage(message, signature);
Shawn Willden5ac2f8f2014-08-18 15:33:10 -0600814}
815
Shawn Willden0d560bf2014-12-15 17:44:02 -0700816TEST_F(VerificationOperationsTest, HmacSha256Success) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700817 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().HmacKey(128, KM_DIGEST_SHA_2_256, 16)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700818 string message = "123456789012345678901234567890123456789012345678";
Shawn Willden0d560bf2014-12-15 17:44:02 -0700819 string signature;
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700820 SignMessage(message, &signature);
821 VerifyMessage(message, signature);
Shawn Willden0d560bf2014-12-15 17:44:02 -0700822}
823
Shawn Willden5b53c992015-02-02 08:05:25 -0700824typedef VerificationOperationsTest ExportKeyTest;
Shawn Willdenffd790c2014-08-18 21:20:06 -0600825TEST_F(ExportKeyTest, RsaSuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700826 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey(256)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700827 string export_data;
828 ASSERT_EQ(KM_ERROR_OK, ExportKey(KM_KEY_FORMAT_X509, &export_data));
829 EXPECT_GT(export_data.length(), 0);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600830
831 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willdenffd790c2014-08-18 21:20:06 -0600832}
833
Shawn Willdenf268d742014-08-19 15:36:26 -0600834TEST_F(ExportKeyTest, EcdsaSuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700835 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().EcdsaSigningKey(224)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700836 string export_data;
837 ASSERT_EQ(KM_ERROR_OK, ExportKey(KM_KEY_FORMAT_X509, &export_data));
838 EXPECT_GT(export_data.length(), 0);
Shawn Willdene46a43f2014-08-27 10:35:36 -0600839
840 // TODO(swillden): Verify that the exported key is actually usable to verify signatures.
Shawn Willdenf268d742014-08-19 15:36:26 -0600841}
842
843TEST_F(ExportKeyTest, RsaUnsupportedKeyFormat) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700844 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey(256)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700845 string export_data;
846 ASSERT_EQ(KM_ERROR_UNSUPPORTED_KEY_FORMAT, ExportKey(KM_KEY_FORMAT_PKCS8, &export_data));
Shawn Willdenf268d742014-08-19 15:36:26 -0600847}
848
849TEST_F(ExportKeyTest, RsaCorruptedKeyBlob) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700850 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaSigningKey(256)));
Shawn Willden5b53c992015-02-02 08:05:25 -0700851 corrupt_key_blob();
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700852 string export_data;
853 ASSERT_EQ(KM_ERROR_INVALID_KEY_BLOB, ExportKey(KM_KEY_FORMAT_X509, &export_data));
Shawn Willdenf268d742014-08-19 15:36:26 -0600854}
855
Shawn Willden437fbd12014-08-20 11:59:49 -0600856static string read_file(const string& file_name) {
857 ifstream file_stream(file_name, std::ios::binary);
858 istreambuf_iterator<char> file_begin(file_stream);
859 istreambuf_iterator<char> file_end;
860 return string(file_begin, file_end);
861}
862
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700863typedef VerificationOperationsTest ImportKeyTest;
Shawn Willden5b53c992015-02-02 08:05:25 -0700864TEST_F(ImportKeyTest, RsaSuccess) {
Shawn Willden81effc62014-08-27 10:08:46 -0600865 string pk8_key = read_file("rsa_privkey_pk8.der");
Shawn Willden437fbd12014-08-20 11:59:49 -0600866 ASSERT_EQ(633U, pk8_key.size());
867
Shawn Willdena278f612014-12-23 11:22:21 -0700868 ASSERT_EQ(KM_ERROR_OK, ImportKey(ParamBuilder().RsaSigningKey().NoDigestOrPadding(),
Shawn Willdenc24c1102014-12-22 15:30:09 -0700869 KM_KEY_FORMAT_PKCS8, pk8_key));
Shawn Willden437fbd12014-08-20 11:59:49 -0600870
871 // Check values derived from the key.
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700872 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_RSA));
873 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 1024));
874 EXPECT_TRUE(contains(sw_enforced(), TAG_RSA_PUBLIC_EXPONENT, 65537U));
Shawn Willden437fbd12014-08-20 11:59:49 -0600875
876 // And values provided by GoogleKeymaster
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700877 EXPECT_TRUE(contains(sw_enforced(), TAG_ORIGIN, KM_ORIGIN_IMPORTED));
878 EXPECT_TRUE(contains(sw_enforced(), KM_TAG_CREATION_DATETIME));
Shawn Willden437fbd12014-08-20 11:59:49 -0600879
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700880 string message(1024 / 8, 'a');
881 string signature;
882 SignMessage(message, &signature);
883 VerifyMessage(message, signature);
Shawn Willden437fbd12014-08-20 11:59:49 -0600884}
885
Shawn Willden6bbe6782014-09-18 11:26:15 -0600886TEST_F(ImportKeyTest, RsaKeySizeMismatch) {
Shawn Willden6bbe6782014-09-18 11:26:15 -0600887 string pk8_key = read_file("rsa_privkey_pk8.der");
888 ASSERT_EQ(633U, pk8_key.size());
Shawn Willden5b53c992015-02-02 08:05:25 -0700889 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
Shawn Willdenc24c1102014-12-22 15:30:09 -0700890 ImportKey(ParamBuilder()
Shawn Willdena278f612014-12-23 11:22:21 -0700891 .RsaSigningKey(2048) // Size doesn't match key
Shawn Willdenc24c1102014-12-22 15:30:09 -0700892 .NoDigestOrPadding(),
893 KM_KEY_FORMAT_PKCS8, pk8_key));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600894}
895
896TEST_F(ImportKeyTest, RsaPublicExponenMismatch) {
Shawn Willden6bbe6782014-09-18 11:26:15 -0600897 string pk8_key = read_file("rsa_privkey_pk8.der");
898 ASSERT_EQ(633U, pk8_key.size());
Shawn Willden5b53c992015-02-02 08:05:25 -0700899 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
Shawn Willdenc24c1102014-12-22 15:30:09 -0700900 ImportKey(ParamBuilder()
Shawn Willdena278f612014-12-23 11:22:21 -0700901 .RsaSigningKey()
Shawn Willdenc24c1102014-12-22 15:30:09 -0700902 .Option(TAG_RSA_PUBLIC_EXPONENT, 3) // Doesn't match key
903 .NoDigestOrPadding(),
904 KM_KEY_FORMAT_PKCS8, pk8_key));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600905}
906
Shawn Willden81effc62014-08-27 10:08:46 -0600907TEST_F(ImportKeyTest, EcdsaSuccess) {
Shawn Willden81effc62014-08-27 10:08:46 -0600908 string pk8_key = read_file("ec_privkey_pk8.der");
909 ASSERT_EQ(138U, pk8_key.size());
910
Shawn Willdena278f612014-12-23 11:22:21 -0700911 ASSERT_EQ(KM_ERROR_OK,
912 ImportKey(ParamBuilder().EcdsaSigningKey(), KM_KEY_FORMAT_PKCS8, pk8_key));
Shawn Willden81effc62014-08-27 10:08:46 -0600913
914 // Check values derived from the key.
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700915 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
916 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 256));
Shawn Willden81effc62014-08-27 10:08:46 -0600917
918 // And values provided by GoogleKeymaster
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700919 EXPECT_TRUE(contains(sw_enforced(), TAG_ORIGIN, KM_ORIGIN_IMPORTED));
920 EXPECT_TRUE(contains(sw_enforced(), KM_TAG_CREATION_DATETIME));
Shawn Willden81effc62014-08-27 10:08:46 -0600921
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700922 string message(1024 / 8, 'a');
923 string signature;
924 SignMessage(message, &signature);
925 VerifyMessage(message, signature);
Shawn Willden81effc62014-08-27 10:08:46 -0600926}
927
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700928TEST_F(ImportKeyTest, EcdsaSizeSpecified) {
929 string pk8_key = read_file("ec_privkey_pk8.der");
930 ASSERT_EQ(138U, pk8_key.size());
Shawn Willden6bbe6782014-09-18 11:26:15 -0600931
Shawn Willdena278f612014-12-23 11:22:21 -0700932 ASSERT_EQ(KM_ERROR_OK,
933 ImportKey(ParamBuilder().EcdsaSigningKey(256), KM_KEY_FORMAT_PKCS8, pk8_key));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600934
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700935 // Check values derived from the key.
936 EXPECT_TRUE(contains(sw_enforced(), TAG_ALGORITHM, KM_ALGORITHM_ECDSA));
937 EXPECT_TRUE(contains(sw_enforced(), TAG_KEY_SIZE, 256));
938
939 // And values provided by GoogleKeymaster
940 EXPECT_TRUE(contains(sw_enforced(), TAG_ORIGIN, KM_ORIGIN_IMPORTED));
941 EXPECT_TRUE(contains(sw_enforced(), KM_TAG_CREATION_DATETIME));
942
943 string message(1024 / 8, 'a');
944 string signature;
945 SignMessage(message, &signature);
946 VerifyMessage(message, signature);
947}
948
949TEST_F(ImportKeyTest, EcdsaSizeMismatch) {
950 string pk8_key = read_file("ec_privkey_pk8.der");
951 ASSERT_EQ(138U, pk8_key.size());
Shawn Willden5b53c992015-02-02 08:05:25 -0700952 ASSERT_EQ(KM_ERROR_IMPORT_PARAMETER_MISMATCH,
Shawn Willdena278f612014-12-23 11:22:21 -0700953 ImportKey(ParamBuilder().EcdsaSigningKey(224), // Size does not match key
954 KM_KEY_FORMAT_PKCS8, pk8_key));
Shawn Willden6bbe6782014-09-18 11:26:15 -0600955}
956
Shawn Willden2665e862014-11-24 14:46:21 -0700957typedef KeymasterTest VersionTest;
958TEST_F(VersionTest, GetVersion) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700959 uint8_t major, minor, subminor;
960 ASSERT_EQ(KM_ERROR_OK, GetVersion(&major, &minor, &subminor));
961 EXPECT_EQ(1, major);
962 EXPECT_EQ(0, minor);
963 EXPECT_EQ(0, subminor);
Shawn Willden2665e862014-11-24 14:46:21 -0700964}
965
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700966typedef KeymasterTest EncryptionOperationsTest;
Shawn Willden4200f212014-12-02 07:01:21 -0700967TEST_F(EncryptionOperationsTest, RsaOaepSuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700968 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_OAEP)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700969
970 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -0700971 string ciphertext1 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -0700972 EXPECT_EQ(512 / 8, ciphertext1.size());
973
Shawn Willden6dde87c2014-12-11 14:08:48 -0700974 string ciphertext2 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -0700975 EXPECT_EQ(512 / 8, ciphertext2.size());
976
977 // OAEP randomizes padding so every result should be different.
978 EXPECT_NE(ciphertext1, ciphertext2);
979}
980
981TEST_F(EncryptionOperationsTest, RsaOaepRoundTrip) {
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
Shawn Willden6dde87c2014-12-11 14:08:48 -0700987 string plaintext = DecryptMessage(ciphertext);
Shawn Willden4200f212014-12-02 07:01:21 -0700988 EXPECT_EQ(message, plaintext);
989}
990
991TEST_F(EncryptionOperationsTest, RsaOaepTooLarge) {
Shawn Willdenc24c1102014-12-22 15:30:09 -0700992 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_OAEP)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700993 string message = "12345678901234567890123";
Shawn Willden4200f212014-12-02 07:01:21 -0700994 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -0700995 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -0700996
Shawn Willdenb15d77e2014-12-17 16:44:29 -0700997 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT));
998 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -0700999 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -07001000 EXPECT_EQ(0, result.size());
1001}
1002
1003TEST_F(EncryptionOperationsTest, RsaOaepCorruptedDecrypt) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001004 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_OAEP)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001005 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001006 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001007 EXPECT_EQ(512 / 8, ciphertext.size());
1008
1009 // Corrupt the ciphertext
1010 ciphertext[512 / 8 / 2]++;
1011
Shawn Willden4200f212014-12-02 07:01:21 -07001012 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001013 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001014 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
1015 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001016 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -07001017 EXPECT_EQ(0, result.size());
1018}
1019
1020TEST_F(EncryptionOperationsTest, RsaPkcs1Success) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001021 ASSERT_EQ(KM_ERROR_OK,
1022 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_PKCS1_1_5_ENCRYPT)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001023 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001024 string ciphertext1 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001025 EXPECT_EQ(512 / 8, ciphertext1.size());
1026
Shawn Willden6dde87c2014-12-11 14:08:48 -07001027 string ciphertext2 = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001028 EXPECT_EQ(512 / 8, ciphertext2.size());
1029
1030 // PKCS1 v1.5 randomizes padding so every result should be different.
1031 EXPECT_NE(ciphertext1, ciphertext2);
1032}
1033
1034TEST_F(EncryptionOperationsTest, RsaPkcs1RoundTrip) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001035 ASSERT_EQ(KM_ERROR_OK,
1036 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_PKCS1_1_5_ENCRYPT)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001037 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001038 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001039 EXPECT_EQ(512 / 8, ciphertext.size());
1040
Shawn Willden6dde87c2014-12-11 14:08:48 -07001041 string plaintext = DecryptMessage(ciphertext);
Shawn Willden4200f212014-12-02 07:01:21 -07001042 EXPECT_EQ(message, plaintext);
1043}
1044
1045TEST_F(EncryptionOperationsTest, RsaPkcs1TooLarge) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001046 ASSERT_EQ(KM_ERROR_OK,
1047 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_PKCS1_1_5_ENCRYPT)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001048 string message = "12345678901234567890123456789012345678901234567890123";
Shawn Willden4200f212014-12-02 07:01:21 -07001049 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001050 size_t input_consumed;
Shawn Willden4200f212014-12-02 07:01:21 -07001051
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001052 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT));
1053 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001054 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -07001055 EXPECT_EQ(0, result.size());
1056}
1057
1058TEST_F(EncryptionOperationsTest, RsaPkcs1CorruptedDecrypt) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001059 ASSERT_EQ(KM_ERROR_OK,
1060 GenerateKey(ParamBuilder().RsaEncryptionKey(512, KM_PAD_RSA_PKCS1_1_5_ENCRYPT)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001061 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001062 string ciphertext = EncryptMessage(string(message));
Shawn Willden4200f212014-12-02 07:01:21 -07001063 EXPECT_EQ(512 / 8, ciphertext.size());
1064
1065 // Corrupt the ciphertext
1066 ciphertext[512 / 8 / 2]++;
1067
Shawn Willden4200f212014-12-02 07:01:21 -07001068 string result;
Shawn Willdenb7361132014-12-08 08:15:14 -07001069 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001070 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
1071 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001072 EXPECT_EQ(KM_ERROR_UNKNOWN_ERROR, FinishOperation(&result));
Shawn Willden4200f212014-12-02 07:01:21 -07001073 EXPECT_EQ(0, result.size());
1074}
1075
Shawn Willden907c3012014-12-08 15:51:55 -07001076TEST_F(EncryptionOperationsTest, AesOcbSuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001077 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001078 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001079 string ciphertext1 = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001080 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext1.size());
Shawn Willden907c3012014-12-08 15:51:55 -07001081
Shawn Willden6dde87c2014-12-11 14:08:48 -07001082 string ciphertext2 = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001083 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext2.size());
Shawn Willden907c3012014-12-08 15:51:55 -07001084
1085 // OCB uses a random nonce, so every output should be different
1086 EXPECT_NE(ciphertext1, ciphertext2);
1087}
1088
Shawn Willden6dde87c2014-12-11 14:08:48 -07001089TEST_F(EncryptionOperationsTest, AesOcbRoundTripSuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001090 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001091 string message = "Hello World!";
1092 string ciphertext = EncryptMessage(message);
1093 EXPECT_EQ(12 /* nonce */ + message.length() + 16 /* tag */, ciphertext.size());
1094
1095 string plaintext = DecryptMessage(ciphertext);
1096 EXPECT_EQ(message, plaintext);
1097}
1098
1099TEST_F(EncryptionOperationsTest, AesOcbRoundTripCorrupted) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001100 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001101 string message = "Hello World!";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001102 string ciphertext = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001103 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext.size());
Shawn Willden6dde87c2014-12-11 14:08:48 -07001104
1105 ciphertext[ciphertext.size() / 2]++;
1106
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001107 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001108
1109 string result;
1110 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001111 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001112 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001113 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001114}
1115
1116TEST_F(EncryptionOperationsTest, AesDecryptGarbage) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001117 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001118 string ciphertext(128, 'a');
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001119 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001120
1121 string result;
1122 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001123 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001124 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001125 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001126}
1127
1128TEST_F(EncryptionOperationsTest, AesDecryptTooShort) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001129 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001130
Shawn Willden6dde87c2014-12-11 14:08:48 -07001131 // Try decrypting garbage ciphertext that is too short to be valid (< nonce + tag).
Shawn Willden6dde87c2014-12-11 14:08:48 -07001132 string ciphertext(12 + 15, 'a');
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001133 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001134
1135 string result;
1136 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001137 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001138 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001139 EXPECT_EQ(KM_ERROR_INVALID_INPUT_LENGTH, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001140}
1141
1142TEST_F(EncryptionOperationsTest, AesOcbRoundTripEmptySuccess) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001143 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001144 string message = "";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001145 string ciphertext = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001146 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext.size());
Shawn Willden6dde87c2014-12-11 14:08:48 -07001147
1148 string plaintext = DecryptMessage(ciphertext);
1149 EXPECT_EQ(message, plaintext);
1150}
1151
1152TEST_F(EncryptionOperationsTest, AesOcbRoundTripEmptyCorrupted) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001153 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001154 string message = "";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001155 string ciphertext = EncryptMessage(string(message));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001156 EXPECT_EQ(12 /* nonce */ + message.size() + 16 /* tag */, ciphertext.size());
Shawn Willden6dde87c2014-12-11 14:08:48 -07001157
1158 ciphertext[ciphertext.size() / 2]++;
1159
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001160 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_DECRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001161
1162 string result;
1163 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001164 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(ciphertext, &result, &input_consumed));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001165 EXPECT_EQ(ciphertext.length(), input_consumed);
Shawn Willdend6cd7e32014-12-17 08:01:26 -07001166 EXPECT_EQ(KM_ERROR_VERIFICATION_FAILED, FinishOperation(&result));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001167}
1168
1169TEST_F(EncryptionOperationsTest, AesOcbFullChunk) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001170 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001171 string message(4096, 'a');
1172 string ciphertext = EncryptMessage(message);
1173 EXPECT_EQ(12 /* nonce */ + message.length() + 16 /* tag */, ciphertext.size());
1174
1175 string plaintext = DecryptMessage(ciphertext);
1176 EXPECT_EQ(message, plaintext);
1177}
1178
1179TEST_F(EncryptionOperationsTest, AesOcbVariousChunkLengths) {
1180 for (unsigned chunk_length = 1; chunk_length <= 128; ++chunk_length) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001181 ASSERT_EQ(KM_ERROR_OK,
1182 GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(chunk_length, 16)));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001183 string message(128, 'a');
1184 string ciphertext = EncryptMessage(message);
1185 int expected_tag_count = (message.length() + chunk_length - 1) / chunk_length;
1186 EXPECT_EQ(12 /* nonce */ + message.length() + 16 * expected_tag_count, ciphertext.size())
1187 << "Unexpected ciphertext size for chunk length " << chunk_length
1188 << " expected tag count was " << expected_tag_count
1189 << " but actual tag count was probably "
1190 << (ciphertext.size() - message.length() - 12) / 16;
1191
1192 string plaintext = DecryptMessage(ciphertext);
1193 EXPECT_EQ(message, plaintext);
1194 }
1195}
1196
1197TEST_F(EncryptionOperationsTest, AesOcbAbort) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001198 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001199 string message = "Hello";
Shawn Willden6dde87c2014-12-11 14:08:48 -07001200
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001201 EXPECT_EQ(KM_ERROR_OK, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willden6dde87c2014-12-11 14:08:48 -07001202
1203 string result;
1204 size_t input_consumed;
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001205 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
1206 EXPECT_EQ(message.length(), input_consumed);
1207 EXPECT_EQ(KM_ERROR_OK, AbortOperation());
Shawn Willden6dde87c2014-12-11 14:08:48 -07001208}
1209
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001210TEST_F(EncryptionOperationsTest, AesOcbNoChunkLength) {
Shawn Willdenc24c1102014-12-22 15:30:09 -07001211 EXPECT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder()
1212 .AesEncryptionKey(128)
1213 .Option(TAG_BLOCK_MODE, KM_MODE_OCB)
1214 .Option(TAG_MAC_LENGTH, 16)));
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001215 EXPECT_EQ(KM_ERROR_INVALID_ARGUMENT, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001216}
1217
1218TEST_F(EncryptionOperationsTest, AesEcbUnsupported) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001219 GenerateKey(ParamBuilder().AesEncryptionKey(128).Option(TAG_BLOCK_MODE, KM_MODE_ECB));
1220 EXPECT_EQ(KM_ERROR_UNSUPPORTED_BLOCK_MODE, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001221}
1222
1223TEST_F(EncryptionOperationsTest, AesOcbPaddingUnsupported) {
Shawn Willdenb15d77e2014-12-17 16:44:29 -07001224 GenerateKey(
1225 ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 16).Option(TAG_PADDING, KM_PAD_ZERO));
1226 EXPECT_EQ(KM_ERROR_UNSUPPORTED_PADDING_MODE, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001227}
1228
1229TEST_F(EncryptionOperationsTest, AesOcbInvalidMacLength) {
Shawn Willden63ac0432014-12-29 14:07:08 -07001230 ASSERT_EQ(KM_ERROR_OK, GenerateKey(ParamBuilder().AesEncryptionKey(128).OcbMode(4096, 17)));
1231 EXPECT_EQ(KM_ERROR_INVALID_ARGUMENT, BeginOperation(KM_PURPOSE_ENCRYPT));
Shawn Willdenbe4a2a32014-12-15 14:51:10 -07001232}
1233
Shawn Willden128ffe02014-08-06 12:31:33 -06001234} // namespace test
1235} // namespace keymaster