blob: 7f394789e6a2df3dd81bc8cb2f319c861c9da6d6 [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,
222 AuthorizationSet* output_set) {
223 AuthorizationSet additional_params(client_params_, array_length(client_params_));
224 additional_params.push_back(input_set);
225
226 keymaster_key_param_t* out_params;
227 size_t out_params_count;
228 keymaster_error_t error =
229 device()->begin(device(), purpose, &blob_, additional_params.data(),
230 additional_params.size(), &out_params, &out_params_count, &op_handle_);
231 if (error == KM_ERROR_OK) {
232 if (output_set) {
233 output_set->Reinitialize(out_params, out_params_count);
234 } else {
235 EXPECT_EQ(0, out_params_count);
236 EXPECT_TRUE(out_params == NULL);
237 }
238 keymaster_free_param_values(out_params, out_params_count);
239 free(out_params);
240 }
241 return error;
242}
243
244keymaster_error_t Keymaster1Test::UpdateOperation(const string& message, string* output,
245 size_t* input_consumed) {
246 uint8_t* out_tmp = NULL;
247 size_t out_length;
248 EXPECT_NE(op_handle_, OP_HANDLE_SENTINEL);
249 keymaster_error_t error =
250 device()->update(device(), op_handle_, NULL /* params */, 0 /* params_count */,
251 reinterpret_cast<const uint8_t*>(message.c_str()), message.length(),
252 input_consumed, &out_tmp, &out_length);
253 if (error == KM_ERROR_OK && out_tmp)
254 output->append(reinterpret_cast<char*>(out_tmp), out_length);
255 free(out_tmp);
256 return error;
257}
258
259keymaster_error_t Keymaster1Test::UpdateOperation(const AuthorizationSet& additional_params,
260 const string& message, string* output,
261 size_t* input_consumed) {
262 uint8_t* out_tmp = NULL;
263 size_t out_length;
264 EXPECT_NE(op_handle_, OP_HANDLE_SENTINEL);
265 keymaster_error_t error =
266 device()->update(device(), op_handle_, additional_params.data(), additional_params.size(),
267 reinterpret_cast<const uint8_t*>(message.c_str()), message.length(),
268 input_consumed, &out_tmp, &out_length);
269 if (error == KM_ERROR_OK && out_tmp)
270 output->append(reinterpret_cast<char*>(out_tmp), out_length);
271 free(out_tmp);
272 return error;
273}
274
275keymaster_error_t Keymaster1Test::FinishOperation(string* output) {
276 return FinishOperation("", output);
277}
278
279keymaster_error_t Keymaster1Test::FinishOperation(const string& signature, string* output) {
280 AuthorizationSet additional_params;
281 return FinishOperation(additional_params, signature, output);
282}
283
284keymaster_error_t Keymaster1Test::FinishOperation(const AuthorizationSet& additional_params,
285 const string& signature, string* output) {
286 uint8_t* out_tmp = NULL;
287 size_t out_length;
288 keymaster_error_t error =
289 device()->finish(device(), op_handle_, additional_params.data(), additional_params.size(),
290 reinterpret_cast<const uint8_t*>(signature.c_str()), signature.length(),
291 &out_tmp, &out_length);
292 if (out_tmp)
293 output->append(reinterpret_cast<char*>(out_tmp), out_length);
294 free(out_tmp);
295 return error;
296}
297
298keymaster_error_t Keymaster1Test::AbortOperation() {
299 return device()->abort(device(), op_handle_);
300}
301
302string Keymaster1Test::ProcessMessage(keymaster_purpose_t purpose, const string& message) {
303 AuthorizationSet input_params;
304 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose, input_params, NULL /* output_params */));
305
306 string result;
307 size_t input_consumed;
308 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
309 EXPECT_EQ(message.size(), input_consumed);
310 EXPECT_EQ(KM_ERROR_OK, FinishOperation(&result));
311 return result;
312}
313
314string Keymaster1Test::ProcessMessage(keymaster_purpose_t purpose, const string& message,
315 const AuthorizationSet& begin_params,
316 const AuthorizationSet& update_params,
317 AuthorizationSet* output_params) {
318 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose, begin_params, output_params));
319
320 string result;
321 size_t input_consumed;
322 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(update_params, message, &result, &input_consumed));
323 EXPECT_EQ(message.size(), input_consumed);
324 EXPECT_EQ(KM_ERROR_OK, FinishOperation(update_params, "", &result));
325 return result;
326}
327
328string Keymaster1Test::ProcessMessage(keymaster_purpose_t purpose, const string& message,
329 const string& signature) {
330 AuthorizationSet input_params;
331 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose, input_params, NULL /* output_params */));
332
333 string result;
334 size_t input_consumed;
335 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
336 EXPECT_EQ(message.size(), input_consumed);
337 EXPECT_EQ(KM_ERROR_OK, FinishOperation(signature, &result));
338 return result;
339}
340
341void Keymaster1Test::SignMessage(const string& message, string* signature) {
342 SCOPED_TRACE("SignMessage");
343 *signature = ProcessMessage(KM_PURPOSE_SIGN, message);
344 EXPECT_GT(signature->size(), 0);
345}
346
347void Keymaster1Test::VerifyMessage(const string& message, const string& signature) {
348 SCOPED_TRACE("VerifyMessage");
349 ProcessMessage(KM_PURPOSE_VERIFY, message, signature);
350}
351
352string Keymaster1Test::EncryptMessage(const string& message, string* generated_nonce) {
353 AuthorizationSet update_params;
354 return EncryptMessage(update_params, message, generated_nonce);
355}
356
357string Keymaster1Test::EncryptMessage(const AuthorizationSet& update_params, const string& message,
358 string* generated_nonce) {
359 SCOPED_TRACE("EncryptMessage");
360 AuthorizationSet begin_params, output_params;
361 string ciphertext =
362 ProcessMessage(KM_PURPOSE_ENCRYPT, message, begin_params, update_params, &output_params);
363 if (generated_nonce) {
364 keymaster_blob_t nonce_blob;
365 EXPECT_TRUE(output_params.GetTagValue(TAG_NONCE, &nonce_blob));
366 *generated_nonce = make_string(nonce_blob.data, nonce_blob.data_length);
367 } else {
368 EXPECT_EQ(-1, output_params.find(TAG_NONCE));
369 }
370 return ciphertext;
371}
372
373string Keymaster1Test::EncryptMessageWithParams(const string& message,
374 const AuthorizationSet& begin_params,
375 const AuthorizationSet& update_params,
376 AuthorizationSet* output_params) {
377 SCOPED_TRACE("EncryptMessageWithParams");
378 return ProcessMessage(KM_PURPOSE_ENCRYPT, message, begin_params, update_params, output_params);
379}
380
381string Keymaster1Test::DecryptMessage(const string& ciphertext) {
382 SCOPED_TRACE("DecryptMessage");
383 return ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext);
384}
385
386string Keymaster1Test::DecryptMessage(const string& ciphertext, const string& nonce) {
387 SCOPED_TRACE("DecryptMessage");
388 AuthorizationSet update_params;
389 return DecryptMessage(update_params, ciphertext, nonce);
390}
391
392string Keymaster1Test::DecryptMessage(const AuthorizationSet& update_params,
393 const string& ciphertext, const string& nonce) {
394 SCOPED_TRACE("DecryptMessage");
395 AuthorizationSet begin_params;
396 begin_params.push_back(TAG_NONCE, nonce.data(), nonce.size());
397 return ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext, begin_params, update_params);
398}
399
400keymaster_error_t Keymaster1Test::GetCharacteristics() {
401 FreeCharacteristics();
402 return device()->get_key_characteristics(device(), &blob_, &client_id_, NULL /* app_data */,
403 &characteristics_);
404}
405
406keymaster_error_t Keymaster1Test::ExportKey(keymaster_key_format_t format, string* export_data) {
407 uint8_t* export_data_tmp;
408 size_t export_data_length;
409
410 keymaster_error_t error =
411 device()->export_key(device(), format, &blob_, &client_id_, NULL /* app_data */,
412 &export_data_tmp, &export_data_length);
413
414 if (error != KM_ERROR_OK)
415 return error;
416
417 *export_data = string(reinterpret_cast<char*>(export_data_tmp), export_data_length);
418 free(export_data_tmp);
419 return error;
420}
421
422keymaster_error_t
423Keymaster1Test::Rescope(const AuthorizationSet& new_params, keymaster_key_blob_t* rescoped_blob,
424 keymaster_key_characteristics_t** rescoped_characteristics) {
425 return device()->rescope(device(), new_params.data(), new_params.size(), &blob_, &client_id_,
426 NULL /* app data */, rescoped_blob, rescoped_characteristics);
427}
428
429void Keymaster1Test::CheckHmacTestVector(string key, string message, keymaster_digest_t digest,
430 string expected_mac) {
431 ASSERT_EQ(KM_ERROR_OK, ImportKey(AuthorizationSetBuilder().HmacKey(key.size() * 8, digest,
432 expected_mac.size()),
433 KM_KEY_FORMAT_RAW, key));
434 string signature;
435 SignMessage(message, &signature);
436 EXPECT_EQ(expected_mac, signature) << "Test vector didn't match for digest " << digest;
437}
438
439void Keymaster1Test::CheckAesOcbTestVector(const string& key, const string& nonce,
440 const string& associated_data, const string& message,
441 const string& expected_ciphertext) {
442 ASSERT_EQ(KM_ERROR_OK, ImportKey(AuthorizationSetBuilder()
443 .AesEncryptionKey(key.size() * 8)
444 .OcbMode(4096 /* chunk length */, 16 /* tag length */)
445 .Authorization(TAG_CALLER_NONCE),
446 KM_KEY_FORMAT_RAW, key));
447
448 AuthorizationSet begin_params, update_params, output_params;
449 begin_params.push_back(TAG_NONCE, nonce.data(), nonce.size());
450 update_params.push_back(TAG_ASSOCIATED_DATA, associated_data.data(), associated_data.size());
451 string ciphertext =
452 EncryptMessageWithParams(message, begin_params, update_params, &output_params);
453 EXPECT_EQ(expected_ciphertext, ciphertext);
454}
455
Thai Duong20d725d2015-03-24 17:49:58 -0700456void Keymaster1Test::CheckAesCtrTestVector(const string& key, const string& nonce,
457 const string& message,
458 const string& expected_ciphertext) {
459 ASSERT_EQ(KM_ERROR_OK, ImportKey(AuthorizationSetBuilder()
460 .AesEncryptionKey(key.size() * 8)
461 .Authorization(TAG_BLOCK_MODE, KM_MODE_CTR)
462 .Authorization(TAG_CALLER_NONCE),
463 KM_KEY_FORMAT_RAW, key));
464
465 AuthorizationSet begin_params, update_params, output_params;
466 begin_params.push_back(TAG_NONCE, nonce.data(), nonce.size());
467 string ciphertext =
468 EncryptMessageWithParams(message, begin_params, update_params, &output_params);
469 EXPECT_EQ(expected_ciphertext, ciphertext);
470}
471
Shawn Willden95dda362015-02-27 10:58:37 -0700472AuthorizationSet Keymaster1Test::hw_enforced() {
473 EXPECT_TRUE(characteristics_ != NULL);
474 return AuthorizationSet(characteristics_->hw_enforced);
475}
476
477AuthorizationSet Keymaster1Test::sw_enforced() {
478 EXPECT_TRUE(characteristics_ != NULL);
479 return AuthorizationSet(characteristics_->sw_enforced);
480}
481
482void Keymaster1Test::FreeCharacteristics() {
483 keymaster_free_characteristics(characteristics_);
484 free(characteristics_);
485 characteristics_ = NULL;
486}
487
488void Keymaster1Test::FreeKeyBlob() {
489 free(const_cast<uint8_t*>(blob_.key_material));
490 blob_.key_material = NULL;
491}
492
493void Keymaster1Test::corrupt_key_blob() {
494 assert(blob_.key_material);
495 uint8_t* tmp = const_cast<uint8_t*>(blob_.key_material);
496 ++tmp[blob_.key_material_size / 2];
497}
498
499} // namespace test
Shawn Willden76364712014-08-11 17:48:04 -0600500} // namespace keymaster