blob: 34bc1dd6a1af12d69771d5a7cc2342bb9f711465 [file] [log] [blame]
Shawn Willden76364712014-08-11 17:48:04 -06001/*
2 * Copyright 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
17#include "google_keymaster_test_utils.h"
18
Shawn Willden95dda362015-02-27 10:58:37 -070019#include <algorithm>
20
21#include <openssl/rand.h>
22
23#include <keymaster/google_keymaster_messages.h>
24#include <keymaster/google_keymaster_utils.h>
25
26using std::is_permutation;
27using std::ostream;
28using std::string;
29using std::vector;
30
Shawn Willden76364712014-08-11 17:48:04 -060031std::ostream& operator<<(std::ostream& os, const keymaster_key_param_t& param) {
32 os << "Tag: " << keymaster_tag_mask_type(param.tag);
33 switch (keymaster_tag_get_type(param.tag)) {
34 case KM_INVALID:
35 os << " Invalid";
36 break;
37 case KM_INT_REP:
38 os << " (Rep)";
39 /* Falls through */
40 case KM_INT:
41 os << " Int: " << param.integer;
42 break;
43 case KM_ENUM_REP:
44 os << " (Rep)";
45 /* Falls through */
46 case KM_ENUM:
47 os << " Enum: " << param.enumerated;
48 break;
Shawn Willdeneb63b972015-03-14 08:01:12 -060049 case KM_LONG_REP:
50 os << " (Rep)";
51 /* Falls through */
Shawn Willden76364712014-08-11 17:48:04 -060052 case KM_LONG:
53 os << " Long: " << param.long_integer;
54 break;
55 case KM_DATE:
56 os << " Date: " << param.date_time;
57 break;
58 case KM_BOOL:
59 os << " Bool: " << param.boolean;
60 break;
61 case KM_BIGNUM:
62 os << " Bignum: ";
63 break;
64 case KM_BYTES:
65 os << " Bytes: ";
66 break;
67 }
68 return os;
69}
70
71bool operator==(const keymaster_key_param_t& a, const keymaster_key_param_t& b) {
72 if (a.tag != b.tag) {
73 return false;
74 }
75
76 switch (keymaster_tag_get_type(a.tag)) {
77 default:
78 return false;
79 case KM_INVALID:
80 return true;
81 case KM_INT_REP:
82 case KM_INT:
83 return a.integer == b.integer;
84 case KM_ENUM_REP:
85 case KM_ENUM:
86 return a.enumerated == b.enumerated;
87 case KM_LONG:
88 return a.long_integer == b.long_integer;
89 case KM_DATE:
90 return a.date_time == b.date_time;
91 case KM_BOOL:
92 return a.boolean == b.boolean;
93 case KM_BIGNUM:
94 case KM_BYTES:
95 if ((a.blob.data == NULL || b.blob.data == NULL) && a.blob.data != b.blob.data)
96 return false;
97 return a.blob.data_length == b.blob.data_length &&
98 (memcmp(a.blob.data, b.blob.data, a.blob.data_length) == 0);
99 }
100}
101
Thai Duong7689ed62015-03-20 16:50:18 -0700102static char hex_value[256] = {
Thai Duong20d725d2015-03-24 17:49:58 -0700103 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
104 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
105 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, // '0'..'9'
Thai Duong7689ed62015-03-20 16:50:18 -0700106 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 'A'..'F'
Thai Duong20d725d2015-03-24 17:49:58 -0700107 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 0,
108 0, 0, 0, 0, 0, 0, 0, 0, // 'a'..'f'
109 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
110 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
111 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
112 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
113 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
114 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
Thai Duong7689ed62015-03-20 16:50:18 -0700115
116string hex2str(string a) {
117 string b;
Thai Duong20d725d2015-03-24 17:49:58 -0700118 size_t num = a.size() / 2;
Thai Duong7689ed62015-03-20 16:50:18 -0700119 b.resize(num);
120 for (size_t i = 0; i < num; i++) {
121 b[i] = (hex_value[a[i * 2] & 0xFF] << 4) + (hex_value[a[i * 2 + 1] & 0xFF]);
122 }
123 return b;
124}
125
Shawn Willden76364712014-08-11 17:48:04 -0600126namespace keymaster {
127
128bool operator==(const AuthorizationSet& a, const AuthorizationSet& b) {
129 if (a.size() != b.size())
130 return false;
131
132 for (size_t i = 0; i < a.size(); ++i)
133 if (!(a[i] == b[i]))
134 return false;
135 return true;
136}
137
Shawn Willden2c242002015-02-27 07:01:02 -0700138bool operator!=(const AuthorizationSet& a, const AuthorizationSet& b) {
139 return !(a == b);
140}
141
Shawn Willden76364712014-08-11 17:48:04 -0600142std::ostream& operator<<(std::ostream& os, const AuthorizationSet& set) {
143 if (set.size() == 0)
144 os << "(Empty)" << std::endl;
145 for (size_t i = 0; i < set.size(); ++i) {
146 os << set[i] << std::endl;
147 }
148 return os;
149}
150
Shawn Willden95dda362015-02-27 10:58:37 -0700151namespace test {
152
153Keymaster1Test::Keymaster1Test()
154 : device_(NULL), op_handle_(OP_HANDLE_SENTINEL), characteristics_(NULL) {
155 blob_.key_material = NULL;
156 RAND_seed("foobar", 6);
157 blob_.key_material = 0;
158}
159
160Keymaster1Test::~Keymaster1Test() {
161 FreeCharacteristics();
162 FreeKeyBlob();
163 device_->common.close(reinterpret_cast<hw_device_t*>(device_));
164}
165
166keymaster1_device_t* Keymaster1Test::device() {
167 return device_;
168}
169
170keymaster_error_t Keymaster1Test::GenerateKey(const AuthorizationSetBuilder& builder) {
171 AuthorizationSet params(builder.build());
172 params.push_back(UserAuthParams());
173 params.push_back(ClientParams());
174
175 FreeKeyBlob();
176 FreeCharacteristics();
177 return device()->generate_key(device(), params.data(), params.size(), &blob_,
178 &characteristics_);
179}
180
181keymaster_error_t Keymaster1Test::ImportKey(const AuthorizationSetBuilder& builder,
182 keymaster_key_format_t format,
183 const string& key_material) {
184 AuthorizationSet params(builder.build());
185 params.push_back(UserAuthParams());
186 params.push_back(ClientParams());
187
188 FreeKeyBlob();
189 FreeCharacteristics();
190 return device()->import_key(device(), params.data(), params.size(), format,
191 reinterpret_cast<const uint8_t*>(key_material.c_str()),
192 key_material.length(), &blob_, &characteristics_);
193}
194
195AuthorizationSet Keymaster1Test::UserAuthParams() {
196 AuthorizationSet set;
197 set.push_back(TAG_USER_ID, 7);
Shawn Willdeneb63b972015-03-14 08:01:12 -0600198 set.push_back(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD);
Shawn Willden95dda362015-02-27 10:58:37 -0700199 set.push_back(TAG_AUTH_TIMEOUT, 300);
200 return set;
201}
202
203AuthorizationSet Keymaster1Test::ClientParams() {
204 AuthorizationSet set;
205 set.push_back(TAG_APPLICATION_ID, "app_id", 6);
206 return set;
207}
208
209keymaster_error_t Keymaster1Test::BeginOperation(keymaster_purpose_t purpose) {
210 keymaster_key_param_t* out_params = NULL;
211 size_t out_params_count = 0;
212 keymaster_error_t error =
213 device()->begin(device(), purpose, &blob_, client_params_, array_length(client_params_),
214 &out_params, &out_params_count, &op_handle_);
215 EXPECT_EQ(0, out_params_count);
216 EXPECT_TRUE(out_params == NULL);
217 return error;
218}
219
220keymaster_error_t Keymaster1Test::BeginOperation(keymaster_purpose_t purpose,
221 const AuthorizationSet& input_set,
Shawn Willdend7a5c712015-04-09 16:33:52 -0600222 AuthorizationSet* output_set,
223 bool use_client_params) {
224 AuthorizationSet additional_params;
225 if (use_client_params)
226 additional_params.push_back(AuthorizationSet(client_params_, array_length(client_params_)));
Shawn Willden95dda362015-02-27 10:58:37 -0700227 additional_params.push_back(input_set);
228
229 keymaster_key_param_t* out_params;
230 size_t out_params_count;
231 keymaster_error_t error =
232 device()->begin(device(), purpose, &blob_, additional_params.data(),
233 additional_params.size(), &out_params, &out_params_count, &op_handle_);
234 if (error == KM_ERROR_OK) {
235 if (output_set) {
236 output_set->Reinitialize(out_params, out_params_count);
237 } else {
238 EXPECT_EQ(0, out_params_count);
239 EXPECT_TRUE(out_params == NULL);
240 }
241 keymaster_free_param_values(out_params, out_params_count);
242 free(out_params);
243 }
244 return error;
245}
246
247keymaster_error_t Keymaster1Test::UpdateOperation(const string& message, string* output,
248 size_t* input_consumed) {
249 uint8_t* out_tmp = NULL;
250 size_t out_length;
251 EXPECT_NE(op_handle_, OP_HANDLE_SENTINEL);
252 keymaster_error_t error =
253 device()->update(device(), op_handle_, NULL /* params */, 0 /* params_count */,
254 reinterpret_cast<const uint8_t*>(message.c_str()), message.length(),
255 input_consumed, &out_tmp, &out_length);
256 if (error == KM_ERROR_OK && out_tmp)
257 output->append(reinterpret_cast<char*>(out_tmp), out_length);
258 free(out_tmp);
259 return error;
260}
261
262keymaster_error_t Keymaster1Test::UpdateOperation(const AuthorizationSet& additional_params,
263 const string& message, string* output,
264 size_t* input_consumed) {
265 uint8_t* out_tmp = NULL;
266 size_t out_length;
267 EXPECT_NE(op_handle_, OP_HANDLE_SENTINEL);
268 keymaster_error_t error =
269 device()->update(device(), op_handle_, additional_params.data(), additional_params.size(),
270 reinterpret_cast<const uint8_t*>(message.c_str()), message.length(),
271 input_consumed, &out_tmp, &out_length);
272 if (error == KM_ERROR_OK && out_tmp)
273 output->append(reinterpret_cast<char*>(out_tmp), out_length);
274 free(out_tmp);
275 return error;
276}
277
278keymaster_error_t Keymaster1Test::FinishOperation(string* output) {
279 return FinishOperation("", output);
280}
281
282keymaster_error_t Keymaster1Test::FinishOperation(const string& signature, string* output) {
283 AuthorizationSet additional_params;
284 return FinishOperation(additional_params, signature, output);
285}
286
287keymaster_error_t Keymaster1Test::FinishOperation(const AuthorizationSet& additional_params,
288 const string& signature, string* output) {
289 uint8_t* out_tmp = NULL;
290 size_t out_length;
291 keymaster_error_t error =
292 device()->finish(device(), op_handle_, additional_params.data(), additional_params.size(),
293 reinterpret_cast<const uint8_t*>(signature.c_str()), signature.length(),
294 &out_tmp, &out_length);
295 if (out_tmp)
296 output->append(reinterpret_cast<char*>(out_tmp), out_length);
297 free(out_tmp);
298 return error;
299}
300
301keymaster_error_t Keymaster1Test::AbortOperation() {
302 return device()->abort(device(), op_handle_);
303}
304
Shawn Willdend7a5c712015-04-09 16:33:52 -0600305string Keymaster1Test::ProcessMessage(keymaster_purpose_t purpose, const string& message,
306 bool use_client_params) {
Shawn Willden95dda362015-02-27 10:58:37 -0700307 AuthorizationSet input_params;
Shawn Willdend7a5c712015-04-09 16:33:52 -0600308 EXPECT_EQ(KM_ERROR_OK,
309 BeginOperation(purpose, input_params, NULL /* output_params */, use_client_params));
Shawn Willden95dda362015-02-27 10:58:37 -0700310
311 string result;
312 size_t input_consumed;
313 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
314 EXPECT_EQ(message.size(), input_consumed);
315 EXPECT_EQ(KM_ERROR_OK, FinishOperation(&result));
316 return result;
317}
318
319string Keymaster1Test::ProcessMessage(keymaster_purpose_t purpose, const string& message,
320 const AuthorizationSet& begin_params,
321 const AuthorizationSet& update_params,
322 AuthorizationSet* output_params) {
323 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose, begin_params, output_params));
324
325 string result;
326 size_t input_consumed;
327 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(update_params, message, &result, &input_consumed));
328 EXPECT_EQ(message.size(), input_consumed);
329 EXPECT_EQ(KM_ERROR_OK, FinishOperation(update_params, "", &result));
330 return result;
331}
332
333string Keymaster1Test::ProcessMessage(keymaster_purpose_t purpose, const string& message,
Shawn Willdend7a5c712015-04-09 16:33:52 -0600334 const string& signature, bool use_client_params) {
Shawn Willden95dda362015-02-27 10:58:37 -0700335 AuthorizationSet input_params;
Shawn Willdend7a5c712015-04-09 16:33:52 -0600336 EXPECT_EQ(KM_ERROR_OK,
337 BeginOperation(purpose, input_params, NULL /* output_params */, use_client_params));
Shawn Willden95dda362015-02-27 10:58:37 -0700338
339 string result;
340 size_t input_consumed;
341 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
342 EXPECT_EQ(message.size(), input_consumed);
343 EXPECT_EQ(KM_ERROR_OK, FinishOperation(signature, &result));
344 return result;
345}
346
Shawn Willdend7a5c712015-04-09 16:33:52 -0600347void Keymaster1Test::SignMessage(const string& message, string* signature, bool use_client_params) {
Shawn Willden95dda362015-02-27 10:58:37 -0700348 SCOPED_TRACE("SignMessage");
Shawn Willdend7a5c712015-04-09 16:33:52 -0600349 *signature = ProcessMessage(KM_PURPOSE_SIGN, message, use_client_params);
Shawn Willden95dda362015-02-27 10:58:37 -0700350 EXPECT_GT(signature->size(), 0);
351}
352
Shawn Willdend7a5c712015-04-09 16:33:52 -0600353void Keymaster1Test::VerifyMessage(const string& message, const string& signature,
354 bool use_client_params) {
Shawn Willden95dda362015-02-27 10:58:37 -0700355 SCOPED_TRACE("VerifyMessage");
Shawn Willdend7a5c712015-04-09 16:33:52 -0600356 ProcessMessage(KM_PURPOSE_VERIFY, message, signature, use_client_params);
Shawn Willden95dda362015-02-27 10:58:37 -0700357}
358
359string Keymaster1Test::EncryptMessage(const string& message, string* generated_nonce) {
360 AuthorizationSet update_params;
361 return EncryptMessage(update_params, message, generated_nonce);
362}
363
364string Keymaster1Test::EncryptMessage(const AuthorizationSet& update_params, const string& message,
365 string* generated_nonce) {
366 SCOPED_TRACE("EncryptMessage");
367 AuthorizationSet begin_params, output_params;
368 string ciphertext =
369 ProcessMessage(KM_PURPOSE_ENCRYPT, message, begin_params, update_params, &output_params);
370 if (generated_nonce) {
371 keymaster_blob_t nonce_blob;
372 EXPECT_TRUE(output_params.GetTagValue(TAG_NONCE, &nonce_blob));
373 *generated_nonce = make_string(nonce_blob.data, nonce_blob.data_length);
374 } else {
375 EXPECT_EQ(-1, output_params.find(TAG_NONCE));
376 }
377 return ciphertext;
378}
379
380string Keymaster1Test::EncryptMessageWithParams(const string& message,
381 const AuthorizationSet& begin_params,
382 const AuthorizationSet& update_params,
383 AuthorizationSet* output_params) {
384 SCOPED_TRACE("EncryptMessageWithParams");
385 return ProcessMessage(KM_PURPOSE_ENCRYPT, message, begin_params, update_params, output_params);
386}
387
388string Keymaster1Test::DecryptMessage(const string& ciphertext) {
389 SCOPED_TRACE("DecryptMessage");
390 return ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext);
391}
392
393string Keymaster1Test::DecryptMessage(const string& ciphertext, const string& nonce) {
394 SCOPED_TRACE("DecryptMessage");
395 AuthorizationSet update_params;
396 return DecryptMessage(update_params, ciphertext, nonce);
397}
398
399string Keymaster1Test::DecryptMessage(const AuthorizationSet& update_params,
400 const string& ciphertext, const string& nonce) {
401 SCOPED_TRACE("DecryptMessage");
402 AuthorizationSet begin_params;
403 begin_params.push_back(TAG_NONCE, nonce.data(), nonce.size());
404 return ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext, begin_params, update_params);
405}
406
407keymaster_error_t Keymaster1Test::GetCharacteristics() {
408 FreeCharacteristics();
409 return device()->get_key_characteristics(device(), &blob_, &client_id_, NULL /* app_data */,
410 &characteristics_);
411}
412
413keymaster_error_t Keymaster1Test::ExportKey(keymaster_key_format_t format, string* export_data) {
414 uint8_t* export_data_tmp;
415 size_t export_data_length;
416
417 keymaster_error_t error =
418 device()->export_key(device(), format, &blob_, &client_id_, NULL /* app_data */,
419 &export_data_tmp, &export_data_length);
420
421 if (error != KM_ERROR_OK)
422 return error;
423
424 *export_data = string(reinterpret_cast<char*>(export_data_tmp), export_data_length);
425 free(export_data_tmp);
426 return error;
427}
428
429keymaster_error_t
430Keymaster1Test::Rescope(const AuthorizationSet& new_params, keymaster_key_blob_t* rescoped_blob,
431 keymaster_key_characteristics_t** rescoped_characteristics) {
432 return device()->rescope(device(), new_params.data(), new_params.size(), &blob_, &client_id_,
433 NULL /* app data */, rescoped_blob, rescoped_characteristics);
434}
435
436void Keymaster1Test::CheckHmacTestVector(string key, string message, keymaster_digest_t digest,
437 string expected_mac) {
438 ASSERT_EQ(KM_ERROR_OK, ImportKey(AuthorizationSetBuilder().HmacKey(key.size() * 8, digest,
439 expected_mac.size()),
440 KM_KEY_FORMAT_RAW, key));
441 string signature;
442 SignMessage(message, &signature);
443 EXPECT_EQ(expected_mac, signature) << "Test vector didn't match for digest " << digest;
444}
445
446void Keymaster1Test::CheckAesOcbTestVector(const string& key, const string& nonce,
447 const string& associated_data, const string& message,
448 const string& expected_ciphertext) {
449 ASSERT_EQ(KM_ERROR_OK, ImportKey(AuthorizationSetBuilder()
450 .AesEncryptionKey(key.size() * 8)
451 .OcbMode(4096 /* chunk length */, 16 /* tag length */)
452 .Authorization(TAG_CALLER_NONCE),
453 KM_KEY_FORMAT_RAW, key));
454
455 AuthorizationSet begin_params, update_params, output_params;
456 begin_params.push_back(TAG_NONCE, nonce.data(), nonce.size());
457 update_params.push_back(TAG_ASSOCIATED_DATA, associated_data.data(), associated_data.size());
458 string ciphertext =
459 EncryptMessageWithParams(message, begin_params, update_params, &output_params);
460 EXPECT_EQ(expected_ciphertext, ciphertext);
461}
462
Thai Duong20d725d2015-03-24 17:49:58 -0700463void Keymaster1Test::CheckAesCtrTestVector(const string& key, const string& nonce,
464 const string& message,
465 const string& expected_ciphertext) {
466 ASSERT_EQ(KM_ERROR_OK, ImportKey(AuthorizationSetBuilder()
467 .AesEncryptionKey(key.size() * 8)
468 .Authorization(TAG_BLOCK_MODE, KM_MODE_CTR)
469 .Authorization(TAG_CALLER_NONCE),
470 KM_KEY_FORMAT_RAW, key));
471
472 AuthorizationSet begin_params, update_params, output_params;
473 begin_params.push_back(TAG_NONCE, nonce.data(), nonce.size());
474 string ciphertext =
475 EncryptMessageWithParams(message, begin_params, update_params, &output_params);
476 EXPECT_EQ(expected_ciphertext, ciphertext);
477}
478
Shawn Willden95dda362015-02-27 10:58:37 -0700479AuthorizationSet Keymaster1Test::hw_enforced() {
480 EXPECT_TRUE(characteristics_ != NULL);
481 return AuthorizationSet(characteristics_->hw_enforced);
482}
483
484AuthorizationSet Keymaster1Test::sw_enforced() {
485 EXPECT_TRUE(characteristics_ != NULL);
486 return AuthorizationSet(characteristics_->sw_enforced);
487}
488
489void Keymaster1Test::FreeCharacteristics() {
490 keymaster_free_characteristics(characteristics_);
491 free(characteristics_);
492 characteristics_ = NULL;
493}
494
495void Keymaster1Test::FreeKeyBlob() {
496 free(const_cast<uint8_t*>(blob_.key_material));
497 blob_.key_material = NULL;
498}
499
500void Keymaster1Test::corrupt_key_blob() {
501 assert(blob_.key_material);
502 uint8_t* tmp = const_cast<uint8_t*>(blob_.key_material);
503 ++tmp[blob_.key_material_size / 2];
504}
505
506} // namespace test
Shawn Willden76364712014-08-11 17:48:04 -0600507} // namespace keymaster