blob: ecaee62f29966b68deffeaf3523ad2c781ebf61c
1 | /* |
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 "android_keymaster_test_utils.h" |
18 | |
19 | #include <algorithm> |
20 | |
21 | #include <openssl/rand.h> |
22 | |
23 | #include <keymaster/android_keymaster_messages.h> |
24 | #include <keymaster/android_keymaster_utils.h> |
25 | |
26 | using std::copy_if; |
27 | using std::find_if; |
28 | using std::is_permutation; |
29 | using std::ostream; |
30 | using std::string; |
31 | using std::vector; |
32 | |
33 | #ifndef KEYMASTER_NAME_TAGS |
34 | #error Keymaster test code requires that KEYMASTER_NAME_TAGS is defined |
35 | #endif |
36 | |
37 | std::ostream& operator<<(std::ostream& os, const keymaster_key_param_t& param) { |
38 | os << "Tag: " << keymaster::StringifyTag(param.tag); |
39 | switch (keymaster_tag_get_type(param.tag)) { |
40 | case KM_INVALID: |
41 | os << " Invalid"; |
42 | break; |
43 | case KM_UINT_REP: |
44 | os << " (Rep)"; |
45 | /* Falls through */ |
46 | case KM_UINT: |
47 | os << " Int: " << param.integer; |
48 | break; |
49 | case KM_ENUM_REP: |
50 | os << " (Rep)"; |
51 | /* Falls through */ |
52 | case KM_ENUM: |
53 | os << " Enum: " << param.enumerated; |
54 | break; |
55 | case KM_ULONG_REP: |
56 | os << " (Rep)"; |
57 | /* Falls through */ |
58 | case KM_ULONG: |
59 | os << " Long: " << param.long_integer; |
60 | break; |
61 | case KM_DATE: |
62 | os << " Date: " << param.date_time; |
63 | break; |
64 | case KM_BOOL: |
65 | os << " Bool: " << param.boolean; |
66 | break; |
67 | case KM_BIGNUM: |
68 | os << " Bignum: "; |
69 | if (!param.blob.data) |
70 | os << "(null)"; |
71 | else |
72 | for (size_t i = 0; i < param.blob.data_length; ++i) |
73 | os << std::hex << std::setw(2) << static_cast<int>(param.blob.data[i]) << std::dec; |
74 | break; |
75 | case KM_BYTES: |
76 | os << " Bytes: "; |
77 | if (!param.blob.data) |
78 | os << "(null)"; |
79 | else |
80 | for (size_t i = 0; i < param.blob.data_length; ++i) |
81 | os << std::hex << std::setw(2) << static_cast<int>(param.blob.data[i]) << std::dec; |
82 | break; |
83 | } |
84 | return os; |
85 | } |
86 | |
87 | bool operator==(const keymaster_key_param_t& a, const keymaster_key_param_t& b) { |
88 | if (a.tag != b.tag) { |
89 | return false; |
90 | } |
91 | |
92 | switch (keymaster_tag_get_type(a.tag)) { |
93 | case KM_INVALID: |
94 | return true; |
95 | case KM_UINT_REP: |
96 | case KM_UINT: |
97 | return a.integer == b.integer; |
98 | case KM_ENUM_REP: |
99 | case KM_ENUM: |
100 | return a.enumerated == b.enumerated; |
101 | case KM_ULONG: |
102 | case KM_ULONG_REP: |
103 | return a.long_integer == b.long_integer; |
104 | case KM_DATE: |
105 | return a.date_time == b.date_time; |
106 | case KM_BOOL: |
107 | return a.boolean == b.boolean; |
108 | case KM_BIGNUM: |
109 | case KM_BYTES: |
110 | if ((a.blob.data == NULL || b.blob.data == NULL) && a.blob.data != b.blob.data) |
111 | return false; |
112 | return a.blob.data_length == b.blob.data_length && |
113 | (memcmp(a.blob.data, b.blob.data, a.blob.data_length) == 0); |
114 | } |
115 | |
116 | return false; |
117 | } |
118 | |
119 | static char hex_value[256] = { |
120 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
121 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
122 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, // '0'..'9' |
123 | 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 'A'..'F' |
124 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 0, |
125 | 0, 0, 0, 0, 0, 0, 0, 0, // 'a'..'f' |
126 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
127 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
128 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
129 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
130 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
131 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; |
132 | |
133 | string hex2str(string a) { |
134 | string b; |
135 | size_t num = a.size() / 2; |
136 | b.resize(num); |
137 | for (size_t i = 0; i < num; i++) { |
138 | b[i] = (hex_value[a[i * 2] & 0xFF] << 4) + (hex_value[a[i * 2 + 1] & 0xFF]); |
139 | } |
140 | return b; |
141 | } |
142 | |
143 | namespace keymaster { |
144 | |
145 | bool operator==(const AuthorizationSet& a, const AuthorizationSet& b) { |
146 | if (a.size() != b.size()) |
147 | return false; |
148 | |
149 | for (size_t i = 0; i < a.size(); ++i) |
150 | if (!(a[i] == b[i])) |
151 | return false; |
152 | return true; |
153 | } |
154 | |
155 | bool operator!=(const AuthorizationSet& a, const AuthorizationSet& b) { |
156 | return !(a == b); |
157 | } |
158 | |
159 | std::ostream& operator<<(std::ostream& os, const AuthorizationSet& set) { |
160 | if (set.size() == 0) |
161 | os << "(Empty)" << std::endl; |
162 | else { |
163 | os << "\n"; |
164 | for (size_t i = 0; i < set.size(); ++i) |
165 | os << set[i] << std::endl; |
166 | } |
167 | return os; |
168 | } |
169 | |
170 | namespace test { |
171 | |
172 | Keymaster2Test::Keymaster2Test() : op_handle_(OP_HANDLE_SENTINEL) { |
173 | memset(&characteristics_, 0, sizeof(characteristics_)); |
174 | blob_.key_material = nullptr; |
175 | RAND_seed("foobar", 6); |
176 | blob_.key_material = 0; |
177 | device_ = GetParam()->CreateDevice(); |
178 | } |
179 | |
180 | Keymaster2Test::~Keymaster2Test() { |
181 | FreeCharacteristics(); |
182 | FreeKeyBlob(); |
183 | device_->common.close(reinterpret_cast<hw_device_t*>(device_)); |
184 | } |
185 | |
186 | keymaster2_device_t* Keymaster2Test::device() { |
187 | return device_; |
188 | } |
189 | |
190 | keymaster_error_t Keymaster2Test::GenerateKey(const AuthorizationSetBuilder& builder) { |
191 | AuthorizationSet params(builder.build()); |
192 | params.push_back(UserAuthParams()); |
193 | params.push_back(ClientParams()); |
194 | |
195 | FreeKeyBlob(); |
196 | FreeCharacteristics(); |
197 | return device()->generate_key(device(), ¶ms, &blob_, &characteristics_); |
198 | } |
199 | |
200 | keymaster_error_t Keymaster2Test::DeleteKey() { |
201 | return device()->delete_key(device(), &blob_); |
202 | } |
203 | |
204 | keymaster_error_t Keymaster2Test::ImportKey(const AuthorizationSetBuilder& builder, |
205 | keymaster_key_format_t format, |
206 | const string& key_material) { |
207 | AuthorizationSet params(builder.build()); |
208 | params.push_back(UserAuthParams()); |
209 | params.push_back(ClientParams()); |
210 | |
211 | FreeKeyBlob(); |
212 | FreeCharacteristics(); |
213 | keymaster_blob_t key = {reinterpret_cast<const uint8_t*>(key_material.c_str()), |
214 | key_material.length()}; |
215 | return device()->import_key(device(), ¶ms, format, &key, &blob_, &characteristics_); |
216 | } |
217 | |
218 | AuthorizationSet Keymaster2Test::UserAuthParams() { |
219 | AuthorizationSet set; |
220 | set.push_back(TAG_USER_ID, 7); |
221 | set.push_back(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD); |
222 | set.push_back(TAG_AUTH_TIMEOUT, 300); |
223 | return set; |
224 | } |
225 | |
226 | AuthorizationSet Keymaster2Test::ClientParams() { |
227 | AuthorizationSet set; |
228 | set.push_back(TAG_APPLICATION_ID, "app_id", 6); |
229 | return set; |
230 | } |
231 | |
232 | keymaster_error_t Keymaster2Test::BeginOperation(keymaster_purpose_t purpose) { |
233 | AuthorizationSet in_params(client_params()); |
234 | keymaster_key_param_set_t out_params; |
235 | keymaster_error_t error = |
236 | device()->begin(device(), purpose, &blob_, &in_params, &out_params, &op_handle_); |
237 | EXPECT_EQ(0U, out_params.length); |
238 | EXPECT_TRUE(out_params.params == nullptr); |
239 | return error; |
240 | } |
241 | |
242 | keymaster_error_t Keymaster2Test::BeginOperation(keymaster_purpose_t purpose, |
243 | const AuthorizationSet& input_set, |
244 | AuthorizationSet* output_set) { |
245 | keymaster_key_param_set_t out_params; |
246 | keymaster_error_t error = |
247 | device()->begin(device(), purpose, &blob_, &input_set, &out_params, &op_handle_); |
248 | if (error == KM_ERROR_OK) { |
249 | if (output_set) { |
250 | output_set->Reinitialize(out_params); |
251 | } else { |
252 | EXPECT_EQ(0U, out_params.length); |
253 | EXPECT_TRUE(out_params.params == nullptr); |
254 | } |
255 | keymaster_free_param_set(&out_params); |
256 | } |
257 | return error; |
258 | } |
259 | |
260 | keymaster_error_t Keymaster2Test::UpdateOperation(const string& message, string* output, |
261 | size_t* input_consumed) { |
262 | EXPECT_NE(op_handle_, OP_HANDLE_SENTINEL); |
263 | keymaster_blob_t input = {reinterpret_cast<const uint8_t*>(message.c_str()), message.length()}; |
264 | keymaster_blob_t out_tmp; |
265 | keymaster_key_param_set_t out_params; |
266 | keymaster_error_t error = device()->update(device(), op_handle_, nullptr /* params */, &input, |
267 | input_consumed, &out_params, &out_tmp); |
268 | if (error == KM_ERROR_OK && out_tmp.data) |
269 | output->append(reinterpret_cast<const char*>(out_tmp.data), out_tmp.data_length); |
270 | free(const_cast<uint8_t*>(out_tmp.data)); |
271 | return error; |
272 | } |
273 | |
274 | keymaster_error_t Keymaster2Test::UpdateOperation(const AuthorizationSet& additional_params, |
275 | const string& message, |
276 | AuthorizationSet* output_params, string* output, |
277 | size_t* input_consumed) { |
278 | EXPECT_NE(op_handle_, OP_HANDLE_SENTINEL); |
279 | keymaster_blob_t input = {reinterpret_cast<const uint8_t*>(message.c_str()), message.length()}; |
280 | keymaster_blob_t out_tmp; |
281 | keymaster_key_param_set_t out_params; |
282 | keymaster_error_t error = device()->update(device(), op_handle_, &additional_params, &input, |
283 | input_consumed, &out_params, &out_tmp); |
284 | if (error == KM_ERROR_OK && out_tmp.data) |
285 | output->append(reinterpret_cast<const char*>(out_tmp.data), out_tmp.data_length); |
286 | free((void*)out_tmp.data); |
287 | if (output_params) |
288 | output_params->Reinitialize(out_params); |
289 | keymaster_free_param_set(&out_params); |
290 | return error; |
291 | } |
292 | |
293 | keymaster_error_t Keymaster2Test::FinishOperation(string* output) { |
294 | return FinishOperation("", output); |
295 | } |
296 | |
297 | keymaster_error_t Keymaster2Test::FinishOperation(const string& signature, string* output) { |
298 | AuthorizationSet additional_params; |
299 | AuthorizationSet output_params; |
300 | return FinishOperation(additional_params, signature, &output_params, output); |
301 | } |
302 | |
303 | keymaster_error_t Keymaster2Test::FinishOperation(const AuthorizationSet& additional_params, |
304 | const string& signature, |
305 | AuthorizationSet* output_params, string* output) { |
306 | keymaster_blob_t sig = {reinterpret_cast<const uint8_t*>(signature.c_str()), |
307 | signature.length()}; |
308 | keymaster_blob_t out_tmp; |
309 | keymaster_key_param_set_t out_params; |
310 | keymaster_error_t error = device()->finish(device(), op_handle_, &additional_params, |
311 | nullptr /* input */, &sig, &out_params, &out_tmp); |
312 | if (error != KM_ERROR_OK) { |
313 | EXPECT_TRUE(out_tmp.data == nullptr); |
314 | EXPECT_TRUE(out_params.params == nullptr); |
315 | return error; |
316 | } |
317 | |
318 | if (out_tmp.data) |
319 | output->append(reinterpret_cast<const char*>(out_tmp.data), out_tmp.data_length); |
320 | free((void*)out_tmp.data); |
321 | if (output_params) |
322 | output_params->Reinitialize(out_params); |
323 | keymaster_free_param_set(&out_params); |
324 | return error; |
325 | } |
326 | |
327 | keymaster_error_t Keymaster2Test::AbortOperation() { |
328 | return device()->abort(device(), op_handle_); |
329 | } |
330 | |
331 | keymaster_error_t Keymaster2Test::AttestKey(const string& attest_challenge, |
332 | keymaster_cert_chain_t* cert_chain) { |
333 | AuthorizationSet attest_params; |
334 | attest_params.push_back(UserAuthParams()); |
335 | attest_params.push_back(ClientParams()); |
336 | attest_params.push_back(TAG_ATTESTATION_CHALLENGE, attest_challenge.data(), |
337 | attest_challenge.length()); |
338 | return device()->attest_key(device(), &blob_, &attest_params, cert_chain); |
339 | } |
340 | |
341 | keymaster_error_t Keymaster2Test::UpgradeKey(const AuthorizationSet& upgrade_params) { |
342 | keymaster_key_blob_t upgraded_blob; |
343 | keymaster_error_t error = |
344 | device()->upgrade_key(device(), &blob_, &upgrade_params, &upgraded_blob); |
345 | if (error == KM_ERROR_OK) { |
346 | FreeKeyBlob(); |
347 | blob_ = upgraded_blob; |
348 | } |
349 | return error; |
350 | } |
351 | |
352 | string Keymaster2Test::ProcessMessage(keymaster_purpose_t purpose, const string& message) { |
353 | EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose, client_params(), NULL /* output_params */)); |
354 | |
355 | string result; |
356 | size_t input_consumed; |
357 | EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed)); |
358 | EXPECT_EQ(message.size(), input_consumed); |
359 | EXPECT_EQ(KM_ERROR_OK, FinishOperation(&result)); |
360 | return result; |
361 | } |
362 | |
363 | string Keymaster2Test::ProcessMessage(keymaster_purpose_t purpose, const string& message, |
364 | const AuthorizationSet& begin_params, |
365 | const AuthorizationSet& update_params, |
366 | AuthorizationSet* begin_out_params) { |
367 | EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose, begin_params, begin_out_params)); |
368 | |
369 | string result; |
370 | size_t input_consumed; |
371 | EXPECT_EQ(KM_ERROR_OK, UpdateOperation(update_params, message, nullptr /* output_params */, |
372 | &result, &input_consumed)); |
373 | EXPECT_EQ(message.size(), input_consumed); |
374 | EXPECT_EQ(KM_ERROR_OK, FinishOperation(update_params, "", &result)); |
375 | return result; |
376 | } |
377 | |
378 | string Keymaster2Test::ProcessMessage(keymaster_purpose_t purpose, const string& message, |
379 | const string& signature, const AuthorizationSet& begin_params, |
380 | const AuthorizationSet& update_params, |
381 | AuthorizationSet* output_params) { |
382 | EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose, begin_params, output_params)); |
383 | |
384 | string result; |
385 | size_t input_consumed; |
386 | EXPECT_EQ(KM_ERROR_OK, UpdateOperation(update_params, message, nullptr /* output_params */, |
387 | &result, &input_consumed)); |
388 | EXPECT_EQ(message.size(), input_consumed); |
389 | EXPECT_EQ(KM_ERROR_OK, FinishOperation(update_params, signature, &result)); |
390 | return result; |
391 | } |
392 | |
393 | string Keymaster2Test::ProcessMessage(keymaster_purpose_t purpose, const string& message, |
394 | const string& signature) { |
395 | EXPECT_EQ(KM_ERROR_OK, BeginOperation(purpose, client_params(), NULL /* output_params */)); |
396 | |
397 | string result; |
398 | size_t input_consumed; |
399 | EXPECT_EQ(KM_ERROR_OK, UpdateOperation(message, &result, &input_consumed)); |
400 | EXPECT_EQ(message.size(), input_consumed); |
401 | EXPECT_EQ(KM_ERROR_OK, FinishOperation(signature, &result)); |
402 | return result; |
403 | } |
404 | |
405 | void Keymaster2Test::SignMessage(const string& message, string* signature, |
406 | keymaster_digest_t digest) { |
407 | SCOPED_TRACE("SignMessage"); |
408 | AuthorizationSet input_params(AuthorizationSet(client_params_, array_length(client_params_))); |
409 | input_params.push_back(TAG_DIGEST, digest); |
410 | AuthorizationSet update_params; |
411 | AuthorizationSet output_params; |
412 | *signature = |
413 | ProcessMessage(KM_PURPOSE_SIGN, message, input_params, update_params, &output_params); |
414 | EXPECT_GT(signature->size(), 0U); |
415 | } |
416 | |
417 | void Keymaster2Test::SignMessage(const string& message, string* signature, |
418 | keymaster_digest_t digest, keymaster_padding_t padding) { |
419 | SCOPED_TRACE("SignMessage"); |
420 | AuthorizationSet input_params(AuthorizationSet(client_params_, array_length(client_params_))); |
421 | input_params.push_back(TAG_DIGEST, digest); |
422 | input_params.push_back(TAG_PADDING, padding); |
423 | AuthorizationSet update_params; |
424 | AuthorizationSet output_params; |
425 | *signature = |
426 | ProcessMessage(KM_PURPOSE_SIGN, message, input_params, update_params, &output_params); |
427 | EXPECT_GT(signature->size(), 0U); |
428 | } |
429 | |
430 | void Keymaster2Test::MacMessage(const string& message, string* signature, size_t mac_length) { |
431 | SCOPED_TRACE("SignMessage"); |
432 | AuthorizationSet input_params(AuthorizationSet(client_params_, array_length(client_params_))); |
433 | input_params.push_back(TAG_MAC_LENGTH, mac_length); |
434 | AuthorizationSet update_params; |
435 | AuthorizationSet output_params; |
436 | *signature = |
437 | ProcessMessage(KM_PURPOSE_SIGN, message, input_params, update_params, &output_params); |
438 | EXPECT_GT(signature->size(), 0U); |
439 | } |
440 | |
441 | void Keymaster2Test::VerifyMessage(const string& message, const string& signature, |
442 | keymaster_digest_t digest) { |
443 | SCOPED_TRACE("VerifyMessage"); |
444 | AuthorizationSet input_params(client_params()); |
445 | input_params.push_back(TAG_DIGEST, digest); |
446 | AuthorizationSet update_params; |
447 | AuthorizationSet output_params; |
448 | ProcessMessage(KM_PURPOSE_VERIFY, message, signature, input_params, update_params, |
449 | &output_params); |
450 | } |
451 | |
452 | void Keymaster2Test::VerifyMessage(const string& message, const string& signature, |
453 | keymaster_digest_t digest, keymaster_padding_t padding) { |
454 | SCOPED_TRACE("VerifyMessage"); |
455 | AuthorizationSet input_params(client_params()); |
456 | input_params.push_back(TAG_DIGEST, digest); |
457 | input_params.push_back(TAG_PADDING, padding); |
458 | AuthorizationSet update_params; |
459 | AuthorizationSet output_params; |
460 | ProcessMessage(KM_PURPOSE_VERIFY, message, signature, input_params, update_params, |
461 | &output_params); |
462 | } |
463 | |
464 | void Keymaster2Test::VerifyMac(const string& message, const string& signature) { |
465 | SCOPED_TRACE("VerifyMac"); |
466 | ProcessMessage(KM_PURPOSE_VERIFY, message, signature); |
467 | } |
468 | |
469 | string Keymaster2Test::EncryptMessage(const string& message, keymaster_padding_t padding, |
470 | string* generated_nonce) { |
471 | SCOPED_TRACE("EncryptMessage"); |
472 | AuthorizationSet begin_params(client_params()), output_params; |
473 | begin_params.push_back(TAG_PADDING, padding); |
474 | AuthorizationSet update_params; |
475 | string ciphertext = |
476 | ProcessMessage(KM_PURPOSE_ENCRYPT, message, begin_params, update_params, &output_params); |
477 | if (generated_nonce) { |
478 | keymaster_blob_t nonce_blob; |
479 | EXPECT_TRUE(output_params.GetTagValue(TAG_NONCE, &nonce_blob)); |
480 | *generated_nonce = make_string(nonce_blob.data, nonce_blob.data_length); |
481 | } else { |
482 | EXPECT_EQ(-1, output_params.find(TAG_NONCE)); |
483 | } |
484 | return ciphertext; |
485 | } |
486 | |
487 | string Keymaster2Test::EncryptMessage(const string& message, keymaster_digest_t digest, |
488 | keymaster_padding_t padding, string* generated_nonce) { |
489 | AuthorizationSet update_params; |
490 | return EncryptMessage(update_params, message, digest, padding, generated_nonce); |
491 | } |
492 | |
493 | string Keymaster2Test::EncryptMessage(const string& message, keymaster_block_mode_t block_mode, |
494 | keymaster_padding_t padding, string* generated_nonce) { |
495 | AuthorizationSet update_params; |
496 | return EncryptMessage(update_params, message, block_mode, padding, generated_nonce); |
497 | } |
498 | |
499 | string Keymaster2Test::EncryptMessage(const AuthorizationSet& update_params, const string& message, |
500 | keymaster_digest_t digest, keymaster_padding_t padding, |
501 | string* generated_nonce) { |
502 | SCOPED_TRACE("EncryptMessage"); |
503 | AuthorizationSet begin_params(client_params()), output_params; |
504 | begin_params.push_back(TAG_PADDING, padding); |
505 | begin_params.push_back(TAG_DIGEST, digest); |
506 | string ciphertext = |
507 | ProcessMessage(KM_PURPOSE_ENCRYPT, message, begin_params, update_params, &output_params); |
508 | if (generated_nonce) { |
509 | keymaster_blob_t nonce_blob; |
510 | EXPECT_TRUE(output_params.GetTagValue(TAG_NONCE, &nonce_blob)); |
511 | *generated_nonce = make_string(nonce_blob.data, nonce_blob.data_length); |
512 | } else { |
513 | EXPECT_EQ(-1, output_params.find(TAG_NONCE)); |
514 | } |
515 | return ciphertext; |
516 | } |
517 | |
518 | string Keymaster2Test::EncryptMessage(const AuthorizationSet& update_params, const string& message, |
519 | keymaster_block_mode_t block_mode, |
520 | keymaster_padding_t padding, string* generated_nonce) { |
521 | SCOPED_TRACE("EncryptMessage"); |
522 | AuthorizationSet begin_params(client_params()), output_params; |
523 | begin_params.push_back(TAG_PADDING, padding); |
524 | begin_params.push_back(TAG_BLOCK_MODE, block_mode); |
525 | string ciphertext = |
526 | ProcessMessage(KM_PURPOSE_ENCRYPT, message, begin_params, update_params, &output_params); |
527 | if (generated_nonce) { |
528 | keymaster_blob_t nonce_blob; |
529 | EXPECT_TRUE(output_params.GetTagValue(TAG_NONCE, &nonce_blob)); |
530 | *generated_nonce = make_string(nonce_blob.data, nonce_blob.data_length); |
531 | } else { |
532 | EXPECT_EQ(-1, output_params.find(TAG_NONCE)); |
533 | } |
534 | return ciphertext; |
535 | } |
536 | |
537 | string Keymaster2Test::EncryptMessageWithParams(const string& message, |
538 | const AuthorizationSet& begin_params, |
539 | const AuthorizationSet& update_params, |
540 | AuthorizationSet* output_params) { |
541 | SCOPED_TRACE("EncryptMessageWithParams"); |
542 | return ProcessMessage(KM_PURPOSE_ENCRYPT, message, begin_params, update_params, output_params); |
543 | } |
544 | |
545 | string Keymaster2Test::DecryptMessage(const string& ciphertext, keymaster_padding_t padding) { |
546 | SCOPED_TRACE("DecryptMessage"); |
547 | AuthorizationSet begin_params(client_params()); |
548 | begin_params.push_back(TAG_PADDING, padding); |
549 | AuthorizationSet update_params; |
550 | return ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext, begin_params, update_params); |
551 | } |
552 | |
553 | string Keymaster2Test::DecryptMessage(const string& ciphertext, keymaster_digest_t digest, |
554 | keymaster_padding_t padding) { |
555 | SCOPED_TRACE("DecryptMessage"); |
556 | AuthorizationSet begin_params(client_params()); |
557 | begin_params.push_back(TAG_PADDING, padding); |
558 | begin_params.push_back(TAG_DIGEST, digest); |
559 | AuthorizationSet update_params; |
560 | return ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext, begin_params, update_params); |
561 | } |
562 | |
563 | string Keymaster2Test::DecryptMessage(const string& ciphertext, keymaster_block_mode_t block_mode, |
564 | keymaster_padding_t padding) { |
565 | SCOPED_TRACE("DecryptMessage"); |
566 | AuthorizationSet begin_params(client_params()); |
567 | begin_params.push_back(TAG_PADDING, padding); |
568 | begin_params.push_back(TAG_BLOCK_MODE, block_mode); |
569 | AuthorizationSet update_params; |
570 | return ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext, begin_params, update_params); |
571 | } |
572 | |
573 | string Keymaster2Test::DecryptMessage(const string& ciphertext, keymaster_digest_t digest, |
574 | keymaster_padding_t padding, const string& nonce) { |
575 | SCOPED_TRACE("DecryptMessage"); |
576 | AuthorizationSet begin_params(client_params()); |
577 | begin_params.push_back(TAG_PADDING, padding); |
578 | begin_params.push_back(TAG_DIGEST, digest); |
579 | begin_params.push_back(TAG_NONCE, nonce.data(), nonce.size()); |
580 | AuthorizationSet update_params; |
581 | return ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext, begin_params, update_params); |
582 | } |
583 | |
584 | string Keymaster2Test::DecryptMessage(const string& ciphertext, keymaster_block_mode_t block_mode, |
585 | keymaster_padding_t padding, const string& nonce) { |
586 | SCOPED_TRACE("DecryptMessage"); |
587 | AuthorizationSet begin_params(client_params()); |
588 | begin_params.push_back(TAG_PADDING, padding); |
589 | begin_params.push_back(TAG_BLOCK_MODE, block_mode); |
590 | begin_params.push_back(TAG_NONCE, nonce.data(), nonce.size()); |
591 | AuthorizationSet update_params; |
592 | return ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext, begin_params, update_params); |
593 | } |
594 | |
595 | string Keymaster2Test::DecryptMessage(const AuthorizationSet& update_params, |
596 | const string& ciphertext, keymaster_digest_t digest, |
597 | keymaster_padding_t padding, const string& nonce) { |
598 | SCOPED_TRACE("DecryptMessage"); |
599 | AuthorizationSet begin_params(client_params()); |
600 | begin_params.push_back(TAG_PADDING, padding); |
601 | begin_params.push_back(TAG_DIGEST, digest); |
602 | begin_params.push_back(TAG_NONCE, nonce.data(), nonce.size()); |
603 | return ProcessMessage(KM_PURPOSE_DECRYPT, ciphertext, begin_params, update_params); |
604 | } |
605 | |
606 | keymaster_error_t Keymaster2Test::GetCharacteristics() { |
607 | FreeCharacteristics(); |
608 | return device()->get_key_characteristics(device(), &blob_, &client_id_, NULL /* app_data */, |
609 | &characteristics_); |
610 | } |
611 | |
612 | keymaster_error_t Keymaster2Test::ExportKey(keymaster_key_format_t format, string* export_data) { |
613 | keymaster_blob_t export_tmp; |
614 | keymaster_error_t error = device()->export_key(device(), format, &blob_, &client_id_, |
615 | NULL /* app_data */, &export_tmp); |
616 | |
617 | if (error != KM_ERROR_OK) |
618 | return error; |
619 | |
620 | *export_data = string(reinterpret_cast<const char*>(export_tmp.data), export_tmp.data_length); |
621 | free((void*)export_tmp.data); |
622 | return error; |
623 | } |
624 | |
625 | void Keymaster2Test::CheckHmacTestVector(const string& key, const string& message, keymaster_digest_t digest, |
626 | string expected_mac) { |
627 | ASSERT_EQ(KM_ERROR_OK, ImportKey(AuthorizationSetBuilder() |
628 | .HmacKey(key.size() * 8) |
629 | .Authorization(TAG_MIN_MAC_LENGTH, expected_mac.size() * 8) |
630 | .Digest(digest), |
631 | KM_KEY_FORMAT_RAW, key)); |
632 | string signature; |
633 | MacMessage(message, &signature, expected_mac.size() * 8); |
634 | EXPECT_EQ(expected_mac, signature) << "Test vector didn't match for digest " << (int)digest; |
635 | } |
636 | |
637 | void Keymaster2Test::CheckAesCtrTestVector(const string& key, const string& nonce, |
638 | const string& message, |
639 | const string& expected_ciphertext) { |
640 | ASSERT_EQ(KM_ERROR_OK, ImportKey(AuthorizationSetBuilder() |
641 | .AesEncryptionKey(key.size() * 8) |
642 | .Authorization(TAG_BLOCK_MODE, KM_MODE_CTR) |
643 | .Authorization(TAG_CALLER_NONCE) |
644 | .Padding(KM_PAD_NONE), |
645 | KM_KEY_FORMAT_RAW, key)); |
646 | |
647 | AuthorizationSet begin_params(client_params()), update_params, output_params; |
648 | begin_params.push_back(TAG_NONCE, nonce.data(), nonce.size()); |
649 | begin_params.push_back(TAG_BLOCK_MODE, KM_MODE_CTR); |
650 | begin_params.push_back(TAG_PADDING, KM_PAD_NONE); |
651 | string ciphertext = |
652 | EncryptMessageWithParams(message, begin_params, update_params, &output_params); |
653 | EXPECT_EQ(expected_ciphertext, ciphertext); |
654 | } |
655 | |
656 | AuthorizationSet Keymaster2Test::hw_enforced() { |
657 | return AuthorizationSet(characteristics_.hw_enforced); |
658 | } |
659 | |
660 | AuthorizationSet Keymaster2Test::sw_enforced() { |
661 | return AuthorizationSet(characteristics_.sw_enforced); |
662 | } |
663 | |
664 | void Keymaster2Test::FreeCharacteristics() { |
665 | keymaster_free_characteristics(&characteristics_); |
666 | } |
667 | |
668 | void Keymaster2Test::FreeKeyBlob() { |
669 | free(const_cast<uint8_t*>(blob_.key_material)); |
670 | blob_.key_material = NULL; |
671 | } |
672 | |
673 | void Keymaster2Test::corrupt_key_blob() { |
674 | assert(blob_.key_material); |
675 | uint8_t* tmp = const_cast<uint8_t*>(blob_.key_material); |
676 | ++tmp[blob_.key_material_size / 2]; |
677 | } |
678 | |
679 | class Sha256OnlyWrapper { |
680 | public: |
681 | explicit Sha256OnlyWrapper(const keymaster1_device_t* wrapped_device) : wrapped_device_(wrapped_device) { |
682 | |
683 | new_module = *wrapped_device_->common.module; |
684 | new_module_name = std::string("SHA 256-only ") + wrapped_device_->common.module->name; |
685 | new_module.name = new_module_name.c_str(); |
686 | |
687 | memset(&device_, 0, sizeof(device_)); |
688 | device_.common.module = &new_module; |
689 | |
690 | device_.common.close = close_device; |
691 | device_.get_supported_algorithms = get_supported_algorithms; |
692 | device_.get_supported_block_modes = get_supported_block_modes; |
693 | device_.get_supported_padding_modes = get_supported_padding_modes; |
694 | device_.get_supported_digests = get_supported_digests; |
695 | device_.get_supported_import_formats = get_supported_import_formats; |
696 | device_.get_supported_export_formats = get_supported_export_formats; |
697 | device_.add_rng_entropy = add_rng_entropy; |
698 | device_.generate_key = generate_key; |
699 | device_.get_key_characteristics = get_key_characteristics; |
700 | device_.import_key = import_key; |
701 | device_.export_key = export_key; |
702 | device_.begin = begin; |
703 | device_.update = update; |
704 | device_.finish = finish; |
705 | device_.abort = abort; |
706 | } |
707 | |
708 | keymaster1_device_t* keymaster_device() { return &device_; } |
709 | |
710 | static bool is_supported(keymaster_digest_t digest) { |
711 | return digest == KM_DIGEST_NONE || digest == KM_DIGEST_SHA_2_256; |
712 | } |
713 | |
714 | static bool all_digests_supported(const keymaster_key_param_set_t* params) { |
715 | for (size_t i = 0; i < params->length; ++i) |
716 | if (params->params[i].tag == TAG_DIGEST) |
717 | if (!is_supported(static_cast<keymaster_digest_t>(params->params[i].enumerated))) |
718 | return false; |
719 | return true; |
720 | } |
721 | |
722 | static const keymaster_key_param_t* |
723 | get_algorithm_param(const keymaster_key_param_set_t* params) { |
724 | keymaster_key_param_t* end = params->params + params->length; |
725 | auto alg_ptr = std::find_if(params->params, end, [](keymaster_key_param_t& p) { |
726 | return p.tag == KM_TAG_ALGORITHM; |
727 | }); |
728 | if (alg_ptr == end) |
729 | return nullptr; |
730 | return alg_ptr; |
731 | } |
732 | |
733 | static int close_device(hw_device_t* dev) { |
734 | Sha256OnlyWrapper* wrapper = reinterpret_cast<Sha256OnlyWrapper*>(dev); |
735 | const keymaster1_device_t* wrapped_device = wrapper->wrapped_device_; |
736 | delete wrapper; |
737 | return wrapped_device->common.close(const_cast<hw_device_t*>(&wrapped_device->common)); |
738 | } |
739 | |
740 | static const keymaster1_device_t* unwrap(const keymaster1_device_t* dev) { |
741 | return reinterpret_cast<const Sha256OnlyWrapper*>(dev)->wrapped_device_; |
742 | } |
743 | |
744 | static keymaster_error_t get_supported_algorithms(const struct keymaster1_device* dev, |
745 | keymaster_algorithm_t** algorithms, |
746 | size_t* algorithms_length) { |
747 | return unwrap(dev)->get_supported_algorithms(unwrap(dev), algorithms, algorithms_length); |
748 | } |
749 | static keymaster_error_t get_supported_block_modes(const struct keymaster1_device* dev, |
750 | keymaster_algorithm_t algorithm, |
751 | keymaster_purpose_t purpose, |
752 | keymaster_block_mode_t** modes, |
753 | size_t* modes_length) { |
754 | return unwrap(dev)->get_supported_block_modes(unwrap(dev), algorithm, purpose, modes, |
755 | modes_length); |
756 | } |
757 | static keymaster_error_t get_supported_padding_modes(const struct keymaster1_device* dev, |
758 | keymaster_algorithm_t algorithm, |
759 | keymaster_purpose_t purpose, |
760 | keymaster_padding_t** modes, |
761 | size_t* modes_length) { |
762 | return unwrap(dev)->get_supported_padding_modes(unwrap(dev), algorithm, purpose, modes, |
763 | modes_length); |
764 | } |
765 | |
766 | static keymaster_error_t get_supported_digests(const keymaster1_device_t* dev, |
767 | keymaster_algorithm_t algorithm, |
768 | keymaster_purpose_t purpose, |
769 | keymaster_digest_t** digests, |
770 | size_t* digests_length) { |
771 | keymaster_error_t error = unwrap(dev)->get_supported_digests( |
772 | unwrap(dev), algorithm, purpose, digests, digests_length); |
773 | if (error != KM_ERROR_OK) |
774 | return error; |
775 | |
776 | std::vector<keymaster_digest_t> filtered_digests; |
777 | std::copy_if(*digests, *digests + *digests_length, std::back_inserter(filtered_digests), |
778 | [](keymaster_digest_t digest) { return is_supported(digest); }); |
779 | |
780 | free(*digests); |
781 | *digests_length = filtered_digests.size(); |
782 | *digests = reinterpret_cast<keymaster_digest_t*>( |
783 | malloc(*digests_length * sizeof(keymaster_digest_t))); |
784 | std::copy(filtered_digests.begin(), filtered_digests.end(), *digests); |
785 | |
786 | return KM_ERROR_OK; |
787 | } |
788 | |
789 | static keymaster_error_t get_supported_import_formats(const struct keymaster1_device* dev, |
790 | keymaster_algorithm_t algorithm, |
791 | keymaster_key_format_t** formats, |
792 | size_t* formats_length) { |
793 | return unwrap(dev)->get_supported_import_formats(unwrap(dev), algorithm, formats, |
794 | formats_length); |
795 | } |
796 | static keymaster_error_t get_supported_export_formats(const struct keymaster1_device* dev, |
797 | keymaster_algorithm_t algorithm, |
798 | keymaster_key_format_t** formats, |
799 | size_t* formats_length) { |
800 | return unwrap(dev)->get_supported_export_formats(unwrap(dev), algorithm, formats, |
801 | formats_length); |
802 | } |
803 | static keymaster_error_t add_rng_entropy(const struct keymaster1_device* dev, |
804 | const uint8_t* data, size_t data_length) { |
805 | return unwrap(dev)->add_rng_entropy(unwrap(dev), data, data_length); |
806 | } |
807 | |
808 | static keymaster_error_t generate_key(const keymaster1_device_t* dev, |
809 | const keymaster_key_param_set_t* params, |
810 | keymaster_key_blob_t* key_blob, |
811 | keymaster_key_characteristics_t** characteristics) { |
812 | auto alg_ptr = get_algorithm_param(params); |
813 | if (!alg_ptr) |
814 | return KM_ERROR_UNSUPPORTED_ALGORITHM; |
815 | if (alg_ptr->enumerated == KM_ALGORITHM_HMAC && !all_digests_supported(params)) |
816 | return KM_ERROR_UNSUPPORTED_DIGEST; |
817 | |
818 | return unwrap(dev)->generate_key(unwrap(dev), params, key_blob, characteristics); |
819 | } |
820 | |
821 | static keymaster_error_t |
822 | get_key_characteristics(const struct keymaster1_device* dev, |
823 | const keymaster_key_blob_t* key_blob, const keymaster_blob_t* client_id, |
824 | const keymaster_blob_t* app_data, |
825 | keymaster_key_characteristics_t** characteristics) { |
826 | return unwrap(dev)->get_key_characteristics(unwrap(dev), key_blob, client_id, app_data, |
827 | characteristics); |
828 | } |
829 | |
830 | static keymaster_error_t |
831 | import_key(const keymaster1_device_t* dev, const keymaster_key_param_set_t* params, |
832 | keymaster_key_format_t key_format, const keymaster_blob_t* key_data, |
833 | keymaster_key_blob_t* key_blob, keymaster_key_characteristics_t** characteristics) { |
834 | auto alg_ptr = get_algorithm_param(params); |
835 | if (!alg_ptr) |
836 | return KM_ERROR_UNSUPPORTED_ALGORITHM; |
837 | if (alg_ptr->enumerated == KM_ALGORITHM_HMAC && !all_digests_supported(params)) |
838 | return KM_ERROR_UNSUPPORTED_DIGEST; |
839 | |
840 | return unwrap(dev)->import_key(unwrap(dev), params, key_format, key_data, key_blob, |
841 | characteristics); |
842 | } |
843 | |
844 | static keymaster_error_t export_key(const struct keymaster1_device* dev, // |
845 | keymaster_key_format_t export_format, |
846 | const keymaster_key_blob_t* key_to_export, |
847 | const keymaster_blob_t* client_id, |
848 | const keymaster_blob_t* app_data, |
849 | keymaster_blob_t* export_data) { |
850 | return unwrap(dev)->export_key(unwrap(dev), export_format, key_to_export, client_id, |
851 | app_data, export_data); |
852 | } |
853 | |
854 | static keymaster_error_t begin(const keymaster1_device_t* dev, // |
855 | keymaster_purpose_t purpose, const keymaster_key_blob_t* key, |
856 | const keymaster_key_param_set_t* in_params, |
857 | keymaster_key_param_set_t* out_params, |
858 | keymaster_operation_handle_t* operation_handle) { |
859 | if (!all_digests_supported(in_params)) |
860 | return KM_ERROR_UNSUPPORTED_DIGEST; |
861 | return unwrap(dev)->begin(unwrap(dev), purpose, key, in_params, out_params, |
862 | operation_handle); |
863 | } |
864 | |
865 | static keymaster_error_t update(const keymaster1_device_t* dev, |
866 | keymaster_operation_handle_t operation_handle, |
867 | const keymaster_key_param_set_t* in_params, |
868 | const keymaster_blob_t* input, size_t* input_consumed, |
869 | keymaster_key_param_set_t* out_params, |
870 | keymaster_blob_t* output) { |
871 | return unwrap(dev)->update(unwrap(dev), operation_handle, in_params, input, input_consumed, |
872 | out_params, output); |
873 | } |
874 | |
875 | static keymaster_error_t finish(const struct keymaster1_device* dev, // |
876 | keymaster_operation_handle_t operation_handle, |
877 | const keymaster_key_param_set_t* in_params, |
878 | const keymaster_blob_t* signature, |
879 | keymaster_key_param_set_t* out_params, |
880 | keymaster_blob_t* output) { |
881 | return unwrap(dev)->finish(unwrap(dev), operation_handle, in_params, signature, out_params, |
882 | output); |
883 | } |
884 | |
885 | static keymaster_error_t abort(const struct keymaster1_device* dev, |
886 | keymaster_operation_handle_t operation_handle) { |
887 | return unwrap(dev)->abort(unwrap(dev), operation_handle); |
888 | } |
889 | |
890 | private: |
891 | keymaster1_device_t device_; |
892 | const keymaster1_device_t* wrapped_device_; |
893 | hw_module_t new_module; |
894 | string new_module_name; |
895 | }; |
896 | |
897 | keymaster1_device_t* make_device_sha256_only(keymaster1_device_t* device) { |
898 | return (new Sha256OnlyWrapper(device))->keymaster_device(); |
899 | } |
900 | |
901 | } // namespace test |
902 | } // namespace keymaster |
903 |