blob: 0f5db5f33668b1d3f9f271d4e88a01db5bf40af5 [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
102namespace keymaster {
103
104bool operator==(const AuthorizationSet& a, const AuthorizationSet& b) {
105 if (a.size() != b.size())
106 return false;
107
108 for (size_t i = 0; i < a.size(); ++i)
109 if (!(a[i] == b[i]))
110 return false;
111 return true;
112}
113
Shawn Willden2c242002015-02-27 07:01:02 -0700114bool operator!=(const AuthorizationSet& a, const AuthorizationSet& b) {
115 return !(a == b);
116}
117
Shawn Willden76364712014-08-11 17:48:04 -0600118std::ostream& operator<<(std::ostream& os, const AuthorizationSet& set) {
119 if (set.size() == 0)
120 os << "(Empty)" << std::endl;
121 for (size_t i = 0; i < set.size(); ++i) {
122 os << set[i] << std::endl;
123 }
124 return os;
125}
126
Shawn Willden95dda362015-02-27 10:58:37 -0700127namespace test {
128
129Keymaster1Test::Keymaster1Test()
130 : device_(NULL), op_handle_(OP_HANDLE_SENTINEL), characteristics_(NULL) {
131 blob_.key_material = NULL;
132 RAND_seed("foobar", 6);
133 blob_.key_material = 0;
134}
135
136Keymaster1Test::~Keymaster1Test() {
137 FreeCharacteristics();
138 FreeKeyBlob();
139 device_->common.close(reinterpret_cast<hw_device_t*>(device_));
140}
141
142keymaster1_device_t* Keymaster1Test::device() {
143 return device_;
144}
145
146keymaster_error_t Keymaster1Test::GenerateKey(const AuthorizationSetBuilder& builder) {
147 AuthorizationSet params(builder.build());
148 params.push_back(UserAuthParams());
149 params.push_back(ClientParams());
150
151 FreeKeyBlob();
152 FreeCharacteristics();
153 return device()->generate_key(device(), params.data(), params.size(), &blob_,
154 &characteristics_);
155}
156
157keymaster_error_t Keymaster1Test::ImportKey(const AuthorizationSetBuilder& builder,
158 keymaster_key_format_t format,
159 const string& key_material) {
160 AuthorizationSet params(builder.build());
161 params.push_back(UserAuthParams());
162 params.push_back(ClientParams());
163
164 FreeKeyBlob();
165 FreeCharacteristics();
166 return device()->import_key(device(), params.data(), params.size(), format,
167 reinterpret_cast<const uint8_t*>(key_material.c_str()),
168 key_material.length(), &blob_, &characteristics_);
169}
170
171AuthorizationSet Keymaster1Test::UserAuthParams() {
172 AuthorizationSet set;
173 set.push_back(TAG_USER_ID, 7);
Shawn Willdeneb63b972015-03-14 08:01:12 -0600174 set.push_back(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD);
Shawn Willden95dda362015-02-27 10:58:37 -0700175 set.push_back(TAG_AUTH_TIMEOUT, 300);
176 return set;
177}
178
179AuthorizationSet Keymaster1Test::ClientParams() {
180 AuthorizationSet set;
181 set.push_back(TAG_APPLICATION_ID, "app_id", 6);
182 return set;
183}
184
185keymaster_error_t Keymaster1Test::BeginOperation(keymaster_purpose_t purpose) {
186 keymaster_key_param_t* out_params = NULL;
187 size_t out_params_count = 0;
188 keymaster_error_t error =
189 device()->begin(device(), purpose, &blob_, client_params_, array_length(client_params_),
190 &out_params, &out_params_count, &op_handle_);
191 EXPECT_EQ(0, out_params_count);
192 EXPECT_TRUE(out_params == NULL);
193 return error;
194}
195
196keymaster_error_t Keymaster1Test::BeginOperation(keymaster_purpose_t purpose,
197 const AuthorizationSet& input_set,
198 AuthorizationSet* output_set) {
199 AuthorizationSet additional_params(client_params_, array_length(client_params_));
200 additional_params.push_back(input_set);
201
202 keymaster_key_param_t* out_params;
203 size_t out_params_count;
204 keymaster_error_t error =
205 device()->begin(device(), purpose, &blob_, additional_params.data(),
206 additional_params.size(), &out_params, &out_params_count, &op_handle_);
207 if (error == KM_ERROR_OK) {
208 if (output_set) {
209 output_set->Reinitialize(out_params, out_params_count);
210 } else {
211 EXPECT_EQ(0, out_params_count);
212 EXPECT_TRUE(out_params == NULL);
213 }
214 keymaster_free_param_values(out_params, out_params_count);
215 free(out_params);
216 }
217 return error;
218}
219
220keymaster_error_t Keymaster1Test::UpdateOperation(const string& message, string* output,
221 size_t* input_consumed) {
222 uint8_t* out_tmp = NULL;
223 size_t out_length;
224 EXPECT_NE(op_handle_, OP_HANDLE_SENTINEL);
225 keymaster_error_t error =
226 device()->update(device(), op_handle_, NULL /* params */, 0 /* params_count */,
227 reinterpret_cast<const uint8_t*>(message.c_str()), message.length(),
228 input_consumed, &out_tmp, &out_length);
229 if (error == KM_ERROR_OK && out_tmp)
230 output->append(reinterpret_cast<char*>(out_tmp), out_length);
231 free(out_tmp);
232 return error;
233}
234
235keymaster_error_t Keymaster1Test::UpdateOperation(const AuthorizationSet& additional_params,
236 const string& message, string* output,
237 size_t* input_consumed) {
238 uint8_t* out_tmp = NULL;
239 size_t out_length;
240 EXPECT_NE(op_handle_, OP_HANDLE_SENTINEL);
241 keymaster_error_t error =
242 device()->update(device(), op_handle_, additional_params.data(), additional_params.size(),
243 reinterpret_cast<const uint8_t*>(message.c_str()), message.length(),
244 input_consumed, &out_tmp, &out_length);
245 if (error == KM_ERROR_OK && out_tmp)
246 output->append(reinterpret_cast<char*>(out_tmp), out_length);
247 free(out_tmp);
248 return error;
249}
250
251keymaster_error_t Keymaster1Test::FinishOperation(string* output) {
252 return FinishOperation("", output);
253}
254
255keymaster_error_t Keymaster1Test::FinishOperation(const string& signature, string* output) {
256 AuthorizationSet additional_params;
257 return FinishOperation(additional_params, signature, output);
258}
259
260keymaster_error_t Keymaster1Test::FinishOperation(const AuthorizationSet& additional_params,
261 const string& signature, string* output) {
262 uint8_t* out_tmp = NULL;
263 size_t out_length;
264 keymaster_error_t error =
265 device()->finish(device(), op_handle_, additional_params.data(), additional_params.size(),
266 reinterpret_cast<const uint8_t*>(signature.c_str()), signature.length(),
267 &out_tmp, &out_length);
268 if (out_tmp)
269 output->append(reinterpret_cast<char*>(out_tmp), out_length);
270 free(out_tmp);
271 return error;
272}
273
274keymaster_error_t Keymaster1Test::AbortOperation() {
275 return device()->abort(device(), op_handle_);
276}
277
278string Keymaster1Test::ProcessMessage(keymaster_purpose_t purpose, const string& message) {
279 AuthorizationSet input_params;
280 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose, input_params, NULL /* output_params */));
281
282 string result;
283 size_t input_consumed;
284 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
285 EXPECT_EQ(message.size(), input_consumed);
286 EXPECT_EQ(KM_ERROR_OK, FinishOperation(&result));
287 return result;
288}
289
290string Keymaster1Test::ProcessMessage(keymaster_purpose_t purpose, const string& message,
291 const AuthorizationSet& begin_params,
292 const AuthorizationSet& update_params,
293 AuthorizationSet* output_params) {
294 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose, begin_params, output_params));
295
296 string result;
297 size_t input_consumed;
298 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(update_params, message, &result, &input_consumed));
299 EXPECT_EQ(message.size(), input_consumed);
300 EXPECT_EQ(KM_ERROR_OK, FinishOperation(update_params, "", &result));
301 return result;
302}
303
304string Keymaster1Test::ProcessMessage(keymaster_purpose_t purpose, const string& message,
305 const string& signature) {
306 AuthorizationSet input_params;
307 EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose, input_params, NULL /* output_params */));
308
309 string result;
310 size_t input_consumed;
311 EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed));
312 EXPECT_EQ(message.size(), input_consumed);
313 EXPECT_EQ(KM_ERROR_OK, FinishOperation(signature, &result));
314 return result;
315}
316
317void Keymaster1Test::SignMessage(const string& message, string* signature) {
318 SCOPED_TRACE("SignMessage");
319 *signature = ProcessMessage(KM_PURPOSE_SIGN, message);
320 EXPECT_GT(signature->size(), 0);
321}
322
323void Keymaster1Test::VerifyMessage(const string& message, const string& signature) {
324 SCOPED_TRACE("VerifyMessage");
325 ProcessMessage(KM_PURPOSE_VERIFY, message, signature);
326}
327
328string Keymaster1Test::EncryptMessage(const string& message, string* generated_nonce) {
329 AuthorizationSet update_params;
330 return EncryptMessage(update_params, message, generated_nonce);
331}
332
333string Keymaster1Test::EncryptMessage(const AuthorizationSet& update_params, const string& message,
334 string* generated_nonce) {
335 SCOPED_TRACE("EncryptMessage");
336 AuthorizationSet begin_params, output_params;
337 string ciphertext =
338 ProcessMessage(KM_PURPOSE_ENCRYPT, message, begin_params, update_params, &output_params);
339 if (generated_nonce) {
340 keymaster_blob_t nonce_blob;
341 EXPECT_TRUE(output_params.GetTagValue(TAG_NONCE, &nonce_blob));
342 *generated_nonce = make_string(nonce_blob.data, nonce_blob.data_length);
343 } else {
344 EXPECT_EQ(-1, output_params.find(TAG_NONCE));
345 }
346 return ciphertext;
347}
348
349string Keymaster1Test::EncryptMessageWithParams(const string& message,
350 const AuthorizationSet& begin_params,
351 const AuthorizationSet& update_params,
352 AuthorizationSet* output_params) {
353 SCOPED_TRACE("EncryptMessageWithParams");
354 return ProcessMessage(KM_PURPOSE_ENCRYPT, message, begin_params, update_params, output_params);
355}
356
357string Keymaster1Test::DecryptMessage(const string& ciphertext) {
358 SCOPED_TRACE("DecryptMessage");
359 return ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext);
360}
361
362string Keymaster1Test::DecryptMessage(const string& ciphertext, const string& nonce) {
363 SCOPED_TRACE("DecryptMessage");
364 AuthorizationSet update_params;
365 return DecryptMessage(update_params, ciphertext, nonce);
366}
367
368string Keymaster1Test::DecryptMessage(const AuthorizationSet& update_params,
369 const string& ciphertext, const string& nonce) {
370 SCOPED_TRACE("DecryptMessage");
371 AuthorizationSet begin_params;
372 begin_params.push_back(TAG_NONCE, nonce.data(), nonce.size());
373 return ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext, begin_params, update_params);
374}
375
376keymaster_error_t Keymaster1Test::GetCharacteristics() {
377 FreeCharacteristics();
378 return device()->get_key_characteristics(device(), &blob_, &client_id_, NULL /* app_data */,
379 &characteristics_);
380}
381
382keymaster_error_t Keymaster1Test::ExportKey(keymaster_key_format_t format, string* export_data) {
383 uint8_t* export_data_tmp;
384 size_t export_data_length;
385
386 keymaster_error_t error =
387 device()->export_key(device(), format, &blob_, &client_id_, NULL /* app_data */,
388 &export_data_tmp, &export_data_length);
389
390 if (error != KM_ERROR_OK)
391 return error;
392
393 *export_data = string(reinterpret_cast<char*>(export_data_tmp), export_data_length);
394 free(export_data_tmp);
395 return error;
396}
397
398keymaster_error_t
399Keymaster1Test::Rescope(const AuthorizationSet& new_params, keymaster_key_blob_t* rescoped_blob,
400 keymaster_key_characteristics_t** rescoped_characteristics) {
401 return device()->rescope(device(), new_params.data(), new_params.size(), &blob_, &client_id_,
402 NULL /* app data */, rescoped_blob, rescoped_characteristics);
403}
404
405void Keymaster1Test::CheckHmacTestVector(string key, string message, keymaster_digest_t digest,
406 string expected_mac) {
407 ASSERT_EQ(KM_ERROR_OK, ImportKey(AuthorizationSetBuilder().HmacKey(key.size() * 8, digest,
408 expected_mac.size()),
409 KM_KEY_FORMAT_RAW, key));
410 string signature;
411 SignMessage(message, &signature);
412 EXPECT_EQ(expected_mac, signature) << "Test vector didn't match for digest " << digest;
413}
414
415void Keymaster1Test::CheckAesOcbTestVector(const string& key, const string& nonce,
416 const string& associated_data, const string& message,
417 const string& expected_ciphertext) {
418 ASSERT_EQ(KM_ERROR_OK, ImportKey(AuthorizationSetBuilder()
419 .AesEncryptionKey(key.size() * 8)
420 .OcbMode(4096 /* chunk length */, 16 /* tag length */)
421 .Authorization(TAG_CALLER_NONCE),
422 KM_KEY_FORMAT_RAW, key));
423
424 AuthorizationSet begin_params, update_params, output_params;
425 begin_params.push_back(TAG_NONCE, nonce.data(), nonce.size());
426 update_params.push_back(TAG_ASSOCIATED_DATA, associated_data.data(), associated_data.size());
427 string ciphertext =
428 EncryptMessageWithParams(message, begin_params, update_params, &output_params);
429 EXPECT_EQ(expected_ciphertext, ciphertext);
430}
431
432AuthorizationSet Keymaster1Test::hw_enforced() {
433 EXPECT_TRUE(characteristics_ != NULL);
434 return AuthorizationSet(characteristics_->hw_enforced);
435}
436
437AuthorizationSet Keymaster1Test::sw_enforced() {
438 EXPECT_TRUE(characteristics_ != NULL);
439 return AuthorizationSet(characteristics_->sw_enforced);
440}
441
442void Keymaster1Test::FreeCharacteristics() {
443 keymaster_free_characteristics(characteristics_);
444 free(characteristics_);
445 characteristics_ = NULL;
446}
447
448void Keymaster1Test::FreeKeyBlob() {
449 free(const_cast<uint8_t*>(blob_.key_material));
450 blob_.key_material = NULL;
451}
452
453void Keymaster1Test::corrupt_key_blob() {
454 assert(blob_.key_material);
455 uint8_t* tmp = const_cast<uint8_t*>(blob_.key_material);
456 ++tmp[blob_.key_material_size / 2];
457}
458
459} // namespace test
Shawn Willden76364712014-08-11 17:48:04 -0600460} // namespace keymaster