blob: 1708b671a275339a527625ee6a6bb7621e978046 [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)) {
Shawn Willden76364712014-08-11 17:48:04 -060077 case KM_INVALID:
78 return true;
79 case KM_INT_REP:
80 case KM_INT:
81 return a.integer == b.integer;
82 case KM_ENUM_REP:
83 case KM_ENUM:
84 return a.enumerated == b.enumerated;
85 case KM_LONG:
Shawn Willden82114e72015-04-16 15:47:50 -060086 case KM_LONG_REP:
Shawn Willden76364712014-08-11 17:48:04 -060087 return a.long_integer == b.long_integer;
88 case KM_DATE:
89 return a.date_time == b.date_time;
90 case KM_BOOL:
91 return a.boolean == b.boolean;
92 case KM_BIGNUM:
93 case KM_BYTES:
94 if ((a.blob.data == NULL || b.blob.data == NULL) && a.blob.data != b.blob.data)
95 return false;
96 return a.blob.data_length == b.blob.data_length &&
97 (memcmp(a.blob.data, b.blob.data, a.blob.data_length) == 0);
98 }
Shawn Willden82114e72015-04-16 15:47:50 -060099
100 return false;
Shawn Willden76364712014-08-11 17:48:04 -0600101}
102
Thai Duong7689ed62015-03-20 16:50:18 -0700103static char hex_value[256] = {
Thai Duong20d725d2015-03-24 17:49:58 -0700104 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
106 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 -0700107 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 -0700108 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 0,
109 0, 0, 0, 0, 0, 0, 0, 0, // 'a'..'f'
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,
115 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 -0700116
117string hex2str(string a) {
118 string b;
Thai Duong20d725d2015-03-24 17:49:58 -0700119 size_t num = a.size() / 2;
Thai Duong7689ed62015-03-20 16:50:18 -0700120 b.resize(num);
121 for (size_t i = 0; i < num; i++) {
122 b[i] = (hex_value[a[i * 2] & 0xFF] << 4) + (hex_value[a[i * 2 + 1] & 0xFF]);
123 }
124 return b;
125}
126
Shawn Willden76364712014-08-11 17:48:04 -0600127namespace keymaster {
128
129bool operator==(const AuthorizationSet& a, const AuthorizationSet& b) {
130 if (a.size() != b.size())
131 return false;
132
133 for (size_t i = 0; i < a.size(); ++i)
134 if (!(a[i] == b[i]))
135 return false;
136 return true;
137}
138
Shawn Willden2c242002015-02-27 07:01:02 -0700139bool operator!=(const AuthorizationSet& a, const AuthorizationSet& b) {
140 return !(a == b);
141}
142
Shawn Willden76364712014-08-11 17:48:04 -0600143std::ostream& operator<<(std::ostream& os, const AuthorizationSet& set) {
144 if (set.size() == 0)
145 os << "(Empty)" << std::endl;
146 for (size_t i = 0; i < set.size(); ++i) {
147 os << set[i] << std::endl;
148 }
149 return os;
150}
151
Shawn Willden95dda362015-02-27 10:58:37 -0700152namespace test {
153
154Keymaster1Test::Keymaster1Test()
155 : device_(NULL), op_handle_(OP_HANDLE_SENTINEL), characteristics_(NULL) {
156 blob_.key_material = NULL;
157 RAND_seed("foobar", 6);
158 blob_.key_material = 0;
159}
160
161Keymaster1Test::~Keymaster1Test() {
162 FreeCharacteristics();
163 FreeKeyBlob();
164 device_->common.close(reinterpret_cast<hw_device_t*>(device_));
165}
166
167keymaster1_device_t* Keymaster1Test::device() {
168 return device_;
169}
170
171keymaster_error_t Keymaster1Test::GenerateKey(const AuthorizationSetBuilder& builder) {
172 AuthorizationSet params(builder.build());
173 params.push_back(UserAuthParams());
174 params.push_back(ClientParams());
175
176 FreeKeyBlob();
177 FreeCharacteristics();
178 return device()->generate_key(device(), params.data(), params.size(), &blob_,
179 &characteristics_);
180}
181
182keymaster_error_t Keymaster1Test::ImportKey(const AuthorizationSetBuilder& builder,
183 keymaster_key_format_t format,
184 const string& key_material) {
185 AuthorizationSet params(builder.build());
186 params.push_back(UserAuthParams());
187 params.push_back(ClientParams());
188
189 FreeKeyBlob();
190 FreeCharacteristics();
191 return device()->import_key(device(), params.data(), params.size(), format,
192 reinterpret_cast<const uint8_t*>(key_material.c_str()),
193 key_material.length(), &blob_, &characteristics_);
194}
195
196AuthorizationSet Keymaster1Test::UserAuthParams() {
197 AuthorizationSet set;
198 set.push_back(TAG_USER_ID, 7);
Shawn Willdeneb63b972015-03-14 08:01:12 -0600199 set.push_back(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD);
Shawn Willden95dda362015-02-27 10:58:37 -0700200 set.push_back(TAG_AUTH_TIMEOUT, 300);
201 return set;
202}
203
204AuthorizationSet Keymaster1Test::ClientParams() {
205 AuthorizationSet set;
206 set.push_back(TAG_APPLICATION_ID, "app_id", 6);
207 return set;
208}
209
210keymaster_error_t Keymaster1Test::BeginOperation(keymaster_purpose_t purpose) {
211 keymaster_key_param_t* out_params = NULL;
212 size_t out_params_count = 0;
213 keymaster_error_t error =
214 device()->begin(device(), purpose, &blob_, client_params_, array_length(client_params_),
215 &out_params, &out_params_count, &op_handle_);
Shawn Willden72a5fdd2015-03-17 20:04:33 -0600216 EXPECT_EQ(0U, out_params_count);
Shawn Willden95dda362015-02-27 10:58:37 -0700217 EXPECT_TRUE(out_params == NULL);
218 return error;
219}
220
221keymaster_error_t Keymaster1Test::BeginOperation(keymaster_purpose_t purpose,
222 const AuthorizationSet& input_set,
Shawn Willdend7a5c712015-04-09 16:33:52 -0600223 AuthorizationSet* output_set,
224 bool use_client_params) {
225 AuthorizationSet additional_params;
226 if (use_client_params)
227 additional_params.push_back(AuthorizationSet(client_params_, array_length(client_params_)));
Shawn Willden95dda362015-02-27 10:58:37 -0700228 additional_params.push_back(input_set);
229
230 keymaster_key_param_t* out_params;
231 size_t out_params_count;
232 keymaster_error_t error =
233 device()->begin(device(), purpose, &blob_, additional_params.data(),
234 additional_params.size(), &out_params, &out_params_count, &op_handle_);
235 if (error == KM_ERROR_OK) {
236 if (output_set) {
237 output_set->Reinitialize(out_params, out_params_count);
238 } else {
Shawn Willden72a5fdd2015-03-17 20:04:33 -0600239 EXPECT_EQ(0U, out_params_count);
Shawn Willden95dda362015-02-27 10:58:37 -0700240 EXPECT_TRUE(out_params == NULL);
241 }
242 keymaster_free_param_values(out_params, out_params_count);
243 free(out_params);
244 }
245 return error;
246}
247
248keymaster_error_t Keymaster1Test::UpdateOperation(const string& message, string* output,
249 size_t* input_consumed) {
250 uint8_t* out_tmp = NULL;
251 size_t out_length;
252 EXPECT_NE(op_handle_, OP_HANDLE_SENTINEL);
253 keymaster_error_t error =
254 device()->update(device(), op_handle_, NULL /* params */, 0 /* params_count */,
255 reinterpret_cast<const uint8_t*>(message.c_str()), message.length(),
256 input_consumed, &out_tmp, &out_length);
257 if (error == KM_ERROR_OK && out_tmp)
258 output->append(reinterpret_cast<char*>(out_tmp), out_length);
259 free(out_tmp);
260 return error;
261}
262
263keymaster_error_t Keymaster1Test::UpdateOperation(const AuthorizationSet& additional_params,
264 const string& message, string* output,
265 size_t* input_consumed) {
266 uint8_t* out_tmp = NULL;
267 size_t out_length;
268 EXPECT_NE(op_handle_, OP_HANDLE_SENTINEL);
269 keymaster_error_t error =
270 device()->update(device(), op_handle_, additional_params.data(), additional_params.size(),
271 reinterpret_cast<const uint8_t*>(message.c_str()), message.length(),
272 input_consumed, &out_tmp, &out_length);
273 if (error == KM_ERROR_OK && out_tmp)
274 output->append(reinterpret_cast<char*>(out_tmp), out_length);
275 free(out_tmp);
276 return error;
277}
278
279keymaster_error_t Keymaster1Test::FinishOperation(string* output) {
280 return FinishOperation("", output);
281}
282
283keymaster_error_t Keymaster1Test::FinishOperation(const string& signature, string* output) {
284 AuthorizationSet additional_params;
285 return FinishOperation(additional_params, signature, output);
286}
287
288keymaster_error_t Keymaster1Test::FinishOperation(const AuthorizationSet& additional_params,
289 const string& signature, string* output) {
290 uint8_t* out_tmp = NULL;
291 size_t out_length;
292 keymaster_error_t error =
293 device()->finish(device(), op_handle_, additional_params.data(), additional_params.size(),
294 reinterpret_cast<const uint8_t*>(signature.c_str()), signature.length(),
295 &out_tmp, &out_length);
296 if (out_tmp)
297 output->append(reinterpret_cast<char*>(out_tmp), out_length);
298 free(out_tmp);
299 return error;
300}
301
302keymaster_error_t Keymaster1Test::AbortOperation() {
303 return device()->abort(device(), op_handle_);
304}
305
Shawn Willdend7a5c712015-04-09 16:33:52 -0600306string Keymaster1Test::ProcessMessage(keymaster_purpose_t purpose, const string& message,
307 bool use_client_params) {
Shawn Willden95dda362015-02-27 10:58:37 -0700308 AuthorizationSet input_params;
Shawn Willdend7a5c712015-04-09 16:33:52 -0600309 EXPECT_EQ(KM_ERROR_OK,
310 BeginOperation(purpose, input_params, NULL /* output_params */, use_client_params));
Shawn Willden95dda362015-02-27 10:58:37 -0700311
312 string result;
313 size_t input_consumed;
314 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
315 EXPECT_EQ(message.size(), input_consumed);
316 EXPECT_EQ(KM_ERROR_OK, FinishOperation(&result));
317 return result;
318}
319
320string Keymaster1Test::ProcessMessage(keymaster_purpose_t purpose, const string& message,
321 const AuthorizationSet& begin_params,
322 const AuthorizationSet& update_params,
323 AuthorizationSet* output_params) {
324 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose, begin_params, output_params));
325
326 string result;
327 size_t input_consumed;
328 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(update_params, message, &result, &input_consumed));
329 EXPECT_EQ(message.size(), input_consumed);
330 EXPECT_EQ(KM_ERROR_OK, FinishOperation(update_params, "", &result));
331 return result;
332}
333
334string Keymaster1Test::ProcessMessage(keymaster_purpose_t purpose, const string& message,
Shawn Willdend7a5c712015-04-09 16:33:52 -0600335 const string& signature, bool use_client_params) {
Shawn Willden95dda362015-02-27 10:58:37 -0700336 AuthorizationSet input_params;
Shawn Willdend7a5c712015-04-09 16:33:52 -0600337 EXPECT_EQ(KM_ERROR_OK,
338 BeginOperation(purpose, input_params, NULL /* output_params */, use_client_params));
Shawn Willden95dda362015-02-27 10:58:37 -0700339
340 string result;
341 size_t input_consumed;
342 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
343 EXPECT_EQ(message.size(), input_consumed);
344 EXPECT_EQ(KM_ERROR_OK, FinishOperation(signature, &result));
345 return result;
346}
347
Shawn Willdend7a5c712015-04-09 16:33:52 -0600348void Keymaster1Test::SignMessage(const string& message, string* signature, bool use_client_params) {
Shawn Willden95dda362015-02-27 10:58:37 -0700349 SCOPED_TRACE("SignMessage");
Shawn Willdend7a5c712015-04-09 16:33:52 -0600350 *signature = ProcessMessage(KM_PURPOSE_SIGN, message, use_client_params);
Shawn Willden72a5fdd2015-03-17 20:04:33 -0600351 EXPECT_GT(signature->size(), 0U);
Shawn Willden95dda362015-02-27 10:58:37 -0700352}
353
Shawn Willdend7a5c712015-04-09 16:33:52 -0600354void Keymaster1Test::VerifyMessage(const string& message, const string& signature,
355 bool use_client_params) {
Shawn Willden95dda362015-02-27 10:58:37 -0700356 SCOPED_TRACE("VerifyMessage");
Shawn Willdend7a5c712015-04-09 16:33:52 -0600357 ProcessMessage(KM_PURPOSE_VERIFY, message, signature, use_client_params);
Shawn Willden95dda362015-02-27 10:58:37 -0700358}
359
360string Keymaster1Test::EncryptMessage(const string& message, string* generated_nonce) {
361 AuthorizationSet update_params;
362 return EncryptMessage(update_params, message, generated_nonce);
363}
364
365string Keymaster1Test::EncryptMessage(const AuthorizationSet& update_params, const string& message,
366 string* generated_nonce) {
367 SCOPED_TRACE("EncryptMessage");
368 AuthorizationSet begin_params, output_params;
369 string ciphertext =
370 ProcessMessage(KM_PURPOSE_ENCRYPT, message, begin_params, update_params, &output_params);
371 if (generated_nonce) {
372 keymaster_blob_t nonce_blob;
373 EXPECT_TRUE(output_params.GetTagValue(TAG_NONCE, &nonce_blob));
374 *generated_nonce = make_string(nonce_blob.data, nonce_blob.data_length);
375 } else {
376 EXPECT_EQ(-1, output_params.find(TAG_NONCE));
377 }
378 return ciphertext;
379}
380
381string Keymaster1Test::EncryptMessageWithParams(const string& message,
382 const AuthorizationSet& begin_params,
383 const AuthorizationSet& update_params,
384 AuthorizationSet* output_params) {
385 SCOPED_TRACE("EncryptMessageWithParams");
386 return ProcessMessage(KM_PURPOSE_ENCRYPT, message, begin_params, update_params, output_params);
387}
388
389string Keymaster1Test::DecryptMessage(const string& ciphertext) {
390 SCOPED_TRACE("DecryptMessage");
391 return ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext);
392}
393
394string Keymaster1Test::DecryptMessage(const string& ciphertext, const string& nonce) {
395 SCOPED_TRACE("DecryptMessage");
396 AuthorizationSet update_params;
397 return DecryptMessage(update_params, ciphertext, nonce);
398}
399
400string Keymaster1Test::DecryptMessage(const AuthorizationSet& update_params,
401 const string& ciphertext, const string& nonce) {
402 SCOPED_TRACE("DecryptMessage");
403 AuthorizationSet begin_params;
404 begin_params.push_back(TAG_NONCE, nonce.data(), nonce.size());
405 return ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext, begin_params, update_params);
406}
407
408keymaster_error_t Keymaster1Test::GetCharacteristics() {
409 FreeCharacteristics();
410 return device()->get_key_characteristics(device(), &blob_, &client_id_, NULL /* app_data */,
411 &characteristics_);
412}
413
414keymaster_error_t Keymaster1Test::ExportKey(keymaster_key_format_t format, string* export_data) {
415 uint8_t* export_data_tmp;
416 size_t export_data_length;
417
418 keymaster_error_t error =
419 device()->export_key(device(), format, &blob_, &client_id_, NULL /* app_data */,
420 &export_data_tmp, &export_data_length);
421
422 if (error != KM_ERROR_OK)
423 return error;
424
425 *export_data = string(reinterpret_cast<char*>(export_data_tmp), export_data_length);
426 free(export_data_tmp);
427 return error;
428}
429
430keymaster_error_t
431Keymaster1Test::Rescope(const AuthorizationSet& new_params, keymaster_key_blob_t* rescoped_blob,
432 keymaster_key_characteristics_t** rescoped_characteristics) {
433 return device()->rescope(device(), new_params.data(), new_params.size(), &blob_, &client_id_,
434 NULL /* app data */, rescoped_blob, rescoped_characteristics);
435}
436
437void Keymaster1Test::CheckHmacTestVector(string key, string message, keymaster_digest_t digest,
438 string expected_mac) {
439 ASSERT_EQ(KM_ERROR_OK, ImportKey(AuthorizationSetBuilder().HmacKey(key.size() * 8, digest,
440 expected_mac.size()),
441 KM_KEY_FORMAT_RAW, key));
442 string signature;
443 SignMessage(message, &signature);
Shawn Willden72a5fdd2015-03-17 20:04:33 -0600444 EXPECT_EQ(expected_mac, signature) << "Test vector didn't match for digest " << (int)digest;
Shawn Willden95dda362015-02-27 10:58:37 -0700445}
446
Thai Duong20d725d2015-03-24 17:49:58 -0700447void Keymaster1Test::CheckAesCtrTestVector(const string& key, const string& nonce,
448 const string& message,
449 const string& expected_ciphertext) {
450 ASSERT_EQ(KM_ERROR_OK, ImportKey(AuthorizationSetBuilder()
451 .AesEncryptionKey(key.size() * 8)
452 .Authorization(TAG_BLOCK_MODE, KM_MODE_CTR)
453 .Authorization(TAG_CALLER_NONCE),
454 KM_KEY_FORMAT_RAW, key));
455
456 AuthorizationSet begin_params, update_params, output_params;
457 begin_params.push_back(TAG_NONCE, nonce.data(), nonce.size());
458 string ciphertext =
459 EncryptMessageWithParams(message, begin_params, update_params, &output_params);
460 EXPECT_EQ(expected_ciphertext, ciphertext);
461}
462
Shawn Willden95dda362015-02-27 10:58:37 -0700463AuthorizationSet Keymaster1Test::hw_enforced() {
464 EXPECT_TRUE(characteristics_ != NULL);
465 return AuthorizationSet(characteristics_->hw_enforced);
466}
467
468AuthorizationSet Keymaster1Test::sw_enforced() {
469 EXPECT_TRUE(characteristics_ != NULL);
470 return AuthorizationSet(characteristics_->sw_enforced);
471}
472
473void Keymaster1Test::FreeCharacteristics() {
474 keymaster_free_characteristics(characteristics_);
475 free(characteristics_);
476 characteristics_ = NULL;
477}
478
479void Keymaster1Test::FreeKeyBlob() {
480 free(const_cast<uint8_t*>(blob_.key_material));
481 blob_.key_material = NULL;
482}
483
484void Keymaster1Test::corrupt_key_blob() {
485 assert(blob_.key_material);
486 uint8_t* tmp = const_cast<uint8_t*>(blob_.key_material);
487 ++tmp[blob_.key_material_size / 2];
488}
489
490} // namespace test
Shawn Willden76364712014-08-11 17:48:04 -0600491} // namespace keymaster