1 // Copyright 2023, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 use crate::keystore2_client_test_utils::{
16 app_attest_key_feature_exists, delete_app_key, get_vsr_api_level,
17 perform_sample_asym_sign_verify_op, perform_sample_hmac_sign_verify_op,
18 perform_sample_sym_key_decrypt_op, perform_sample_sym_key_encrypt_op,
19 verify_certificate_serial_num, verify_certificate_subject_name, SAMPLE_PLAIN_TEXT,
20 };
21 use crate::{require_keymint, skip_test_if_no_app_attest_key_feature};
22 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
23 Algorithm::Algorithm, BlockMode::BlockMode, Digest::Digest, EcCurve::EcCurve,
24 ErrorCode::ErrorCode, KeyPurpose::KeyPurpose, PaddingMode::PaddingMode,
25 SecurityLevel::SecurityLevel, Tag::Tag,
26 };
27 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
28 HardwareAuthToken::HardwareAuthToken, HardwareAuthenticatorType::HardwareAuthenticatorType,
29 KeyParameter::KeyParameter, KeyParameterValue::KeyParameterValue,
30 };
31 use android_hardware_security_secureclock::aidl::android::hardware::security::secureclock::{
32 Timestamp::Timestamp
33 };
34 use android_system_keystore2::aidl::android::system::keystore2::{
35 Domain::Domain, KeyDescriptor::KeyDescriptor, KeyMetadata::KeyMetadata,
36 ResponseCode::ResponseCode,
37 };
38 use bssl_crypto::digest;
39 use keystore_attestation::{AttestationExtension, ATTESTATION_EXTENSION_OID};
40 use keystore2_test_utils::ffi_test_utils::get_value_from_attest_record;
41 use keystore2_test_utils::{
42 authorizations, get_keystore_auth_service, key_generations,
43 key_generations::Error, SecLevel,
44 };
45 use openssl::bn::{BigNum, MsbOption};
46 use openssl::x509::X509NameBuilder;
47 use std::time::SystemTime;
48 use x509_cert::{certificate::Certificate, der::Decode};
49
gen_key_including_unique_id(sl: &SecLevel, alias: &str) -> Option<Vec<u8>>50 fn gen_key_including_unique_id(sl: &SecLevel, alias: &str) -> Option<Vec<u8>> {
51 let gen_params = authorizations::AuthSetBuilder::new()
52 .no_auth_required()
53 .algorithm(Algorithm::EC)
54 .purpose(KeyPurpose::SIGN)
55 .purpose(KeyPurpose::VERIFY)
56 .digest(Digest::SHA_2_256)
57 .ec_curve(EcCurve::P_256)
58 .attestation_challenge(b"foo".to_vec())
59 .include_unique_id();
60
61 let key_metadata =
62 key_generations::map_ks_error(key_generations::generate_key(sl, &gen_params, alias))
63 .unwrap()?;
64
65 let unique_id = get_value_from_attest_record(
66 key_metadata.certificate.as_ref().unwrap(),
67 Tag::UNIQUE_ID,
68 key_metadata.keySecurityLevel,
69 )
70 .expect("Unique id not found.");
71 assert!(!unique_id.is_empty());
72 Some(unique_id)
73 }
74
generate_key_and_perform_sign_verify_op_max_times( sl: &SecLevel, gen_params: &authorizations::AuthSetBuilder, alias: &str, max_usage_count: i32, ) -> binder::Result<Option<KeyMetadata>>75 fn generate_key_and_perform_sign_verify_op_max_times(
76 sl: &SecLevel,
77 gen_params: &authorizations::AuthSetBuilder,
78 alias: &str,
79 max_usage_count: i32,
80 ) -> binder::Result<Option<KeyMetadata>> {
81 let Some(key_metadata) = key_generations::generate_key(sl, gen_params, alias)? else {
82 return Ok(None);
83 };
84
85 // Use above generated key `max_usage_count` times.
86 for _ in 0..max_usage_count {
87 perform_sample_asym_sign_verify_op(
88 &sl.binder,
89 &key_metadata,
90 None,
91 Some(Digest::SHA_2_256),
92 );
93 }
94
95 Ok(Some(key_metadata))
96 }
97
98 /// Generate a key with `USAGE_COUNT_LIMIT` and verify the key characteristics. Test should be able
99 /// to use the key successfully `max_usage_count` times. After exceeding key usage `max_usage_count`
100 /// times subsequent attempts to use the key in test should fail with response code `KEY_NOT_FOUND`.
101 /// Test should also verify that the attest record includes `USAGE_COUNT_LIMIT` for attested keys.
generate_key_and_perform_op_with_max_usage_limit( sl: &SecLevel, gen_params: &authorizations::AuthSetBuilder, alias: &str, max_usage_count: i32, check_attestation: bool, )102 fn generate_key_and_perform_op_with_max_usage_limit(
103 sl: &SecLevel,
104 gen_params: &authorizations::AuthSetBuilder,
105 alias: &str,
106 max_usage_count: i32,
107 check_attestation: bool,
108 ) {
109 // Generate a key and use the key for `max_usage_count` times.
110 let Some(key_metadata) =
111 generate_key_and_perform_sign_verify_op_max_times(sl, gen_params, alias, max_usage_count)
112 .unwrap()
113 else {
114 return;
115 };
116
117 let auth = key_generations::get_key_auth(&key_metadata.authorizations, Tag::USAGE_COUNT_LIMIT)
118 .unwrap();
119 if check_attestation && sl.is_keymint() {
120 // Check usage-count-limit is included in attest-record.
121 // `USAGE_COUNT_LIMIT` is supported from KeyMint1.0
122 assert_ne!(
123 gen_params.iter().filter(|kp| kp.tag == Tag::ATTESTATION_CHALLENGE).count(),
124 0,
125 "Attestation challenge is missing in generated key parameters."
126 );
127 let result = get_value_from_attest_record(
128 key_metadata.certificate.as_ref().unwrap(),
129 Tag::USAGE_COUNT_LIMIT,
130 auth.securityLevel,
131 )
132 .expect("Attest id verification failed.");
133 let usage_count: i32 = std::str::from_utf8(&result).unwrap().parse().unwrap();
134 assert_eq!(usage_count, max_usage_count);
135 }
136 if max_usage_count == 1 {
137 assert!(matches!(
138 auth.securityLevel,
139 SecurityLevel::KEYSTORE | SecurityLevel::TRUSTED_ENVIRONMENT
140 ));
141 } else {
142 assert_eq!(auth.securityLevel, SecurityLevel::KEYSTORE);
143 }
144
145 // Try to use the key one more time.
146 let result = key_generations::map_ks_error(sl.binder.createOperation(
147 &key_metadata.key,
148 &authorizations::AuthSetBuilder::new().purpose(KeyPurpose::SIGN).digest(Digest::SHA_2_256),
149 false,
150 ));
151 assert!(result.is_err());
152 assert_eq!(Error::Rc(ResponseCode::KEY_NOT_FOUND), result.unwrap_err());
153 }
154
155 /// Generate a key with `ACTIVE_DATETIME` set to current time. Test should successfully generate
156 /// a key and verify the key characteristics. Test should be able to create a sign operation using
157 /// the generated key successfully.
158 #[test]
keystore2_gen_key_auth_active_datetime_test_success()159 fn keystore2_gen_key_auth_active_datetime_test_success() {
160 let sl = SecLevel::tee();
161
162 let duration_since_epoch = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
163 let active_datetime = duration_since_epoch.as_millis();
164 let gen_params = authorizations::AuthSetBuilder::new()
165 .no_auth_required()
166 .algorithm(Algorithm::EC)
167 .purpose(KeyPurpose::SIGN)
168 .purpose(KeyPurpose::VERIFY)
169 .digest(Digest::SHA_2_256)
170 .ec_curve(EcCurve::P_256)
171 .active_date_time(active_datetime.try_into().unwrap());
172
173 let alias = "ks_test_auth_tags_test";
174 let result = key_generations::create_key_and_operation(
175 &sl,
176 &gen_params,
177 &authorizations::AuthSetBuilder::new().purpose(KeyPurpose::SIGN).digest(Digest::SHA_2_256),
178 alias,
179 );
180 assert!(result.is_ok());
181 delete_app_key(&sl.keystore2, alias).unwrap();
182 }
183
184 /// Generate a key with `ACTIVE_DATETIME` set to future date and time. Test should successfully
185 /// generate a key and verify the key characteristics. Try to create a sign operation
186 /// using the generated key, test should fail to create an operation with error code
187 /// `KEY_NOT_YET_VALID`.
188 #[test]
keystore2_gen_key_auth_future_active_datetime_test_op_fail()189 fn keystore2_gen_key_auth_future_active_datetime_test_op_fail() {
190 let sl = SecLevel::tee();
191
192 let duration_since_epoch = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
193 let future_active_datetime = duration_since_epoch.as_millis() + (24 * 60 * 60 * 1000);
194 let gen_params = authorizations::AuthSetBuilder::new()
195 .no_auth_required()
196 .algorithm(Algorithm::EC)
197 .purpose(KeyPurpose::SIGN)
198 .purpose(KeyPurpose::VERIFY)
199 .digest(Digest::SHA_2_256)
200 .ec_curve(EcCurve::P_256)
201 .active_date_time(future_active_datetime.try_into().unwrap());
202
203 let alias = "ks_test_auth_tags_test";
204 let result = key_generations::map_ks_error(key_generations::create_key_and_operation(
205 &sl,
206 &gen_params,
207 &authorizations::AuthSetBuilder::new().purpose(KeyPurpose::SIGN).digest(Digest::SHA_2_256),
208 alias,
209 ));
210 assert!(result.is_err());
211 assert_eq!(Error::Km(ErrorCode::KEY_NOT_YET_VALID), result.unwrap_err());
212 delete_app_key(&sl.keystore2, alias).unwrap();
213 }
214
215 /// Generate a key with `ORIGINATION_EXPIRE_DATETIME` set to future date and time. Test should
216 /// successfully generate a key and verify the key characteristics. Test should be able to create
217 /// sign operation using the generated key successfully.
218 #[test]
keystore2_gen_key_auth_future_origination_expire_datetime_test_success()219 fn keystore2_gen_key_auth_future_origination_expire_datetime_test_success() {
220 let sl = SecLevel::tee();
221
222 let duration_since_epoch = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
223 let origination_expire_datetime = duration_since_epoch.as_millis() + (24 * 60 * 60 * 1000);
224 let gen_params = authorizations::AuthSetBuilder::new()
225 .no_auth_required()
226 .algorithm(Algorithm::EC)
227 .purpose(KeyPurpose::SIGN)
228 .purpose(KeyPurpose::VERIFY)
229 .digest(Digest::SHA_2_256)
230 .ec_curve(EcCurve::P_256)
231 .origination_expire_date_time(origination_expire_datetime.try_into().unwrap());
232
233 let alias = "ks_test_auth_tags_test";
234 let result = key_generations::create_key_and_operation(
235 &sl,
236 &gen_params,
237 &authorizations::AuthSetBuilder::new().purpose(KeyPurpose::SIGN).digest(Digest::SHA_2_256),
238 alias,
239 );
240 assert!(result.is_ok());
241 delete_app_key(&sl.keystore2, alias).unwrap();
242 }
243
244 /// Generate a key with `ORIGINATION_EXPIRE_DATETIME` set to current date and time. Test should
245 /// successfully generate a key and verify the key characteristics. Try to create a sign operation
246 /// using the generated key, test should fail to create an operation with error code
247 /// `KEY_EXPIRED`.
248 #[test]
keystore2_gen_key_auth_origination_expire_datetime_test_op_fail()249 fn keystore2_gen_key_auth_origination_expire_datetime_test_op_fail() {
250 let sl = SecLevel::tee();
251
252 let duration_since_epoch = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
253 let origination_expire_datetime = duration_since_epoch.as_millis();
254 let gen_params = authorizations::AuthSetBuilder::new()
255 .no_auth_required()
256 .algorithm(Algorithm::EC)
257 .purpose(KeyPurpose::SIGN)
258 .purpose(KeyPurpose::VERIFY)
259 .digest(Digest::SHA_2_256)
260 .ec_curve(EcCurve::P_256)
261 .origination_expire_date_time(origination_expire_datetime.try_into().unwrap());
262
263 let alias = "ks_test_auth_tags_test";
264 let result = key_generations::map_ks_error(key_generations::create_key_and_operation(
265 &sl,
266 &gen_params,
267 &authorizations::AuthSetBuilder::new().purpose(KeyPurpose::SIGN).digest(Digest::SHA_2_256),
268 alias,
269 ));
270 assert!(result.is_err());
271 assert_eq!(Error::Km(ErrorCode::KEY_EXPIRED), result.unwrap_err());
272 delete_app_key(&sl.keystore2, alias).unwrap();
273 }
274
275 /// Generate a HMAC key with `USAGE_EXPIRE_DATETIME` set to future date and time. Test should
276 /// successfully generate a key and verify the key characteristics. Test should be able to create
277 /// sign and verify operations using the generated key successfully.
278 #[test]
keystore2_gen_key_auth_future_usage_expire_datetime_hmac_verify_op_success()279 fn keystore2_gen_key_auth_future_usage_expire_datetime_hmac_verify_op_success() {
280 let sl = SecLevel::tee();
281
282 let duration_since_epoch = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
283 let usage_expire_datetime = duration_since_epoch.as_millis() + (24 * 60 * 60 * 1000);
284 let gen_params = authorizations::AuthSetBuilder::new()
285 .no_auth_required()
286 .algorithm(Algorithm::HMAC)
287 .purpose(KeyPurpose::SIGN)
288 .purpose(KeyPurpose::VERIFY)
289 .key_size(128)
290 .min_mac_length(256)
291 .digest(Digest::SHA_2_256)
292 .usage_expire_date_time(usage_expire_datetime.try_into().unwrap());
293
294 let alias = "ks_test_auth_tags_hmac_verify_success";
295 let Some(key_metadata) = key_generations::generate_key(&sl, &gen_params, alias).unwrap() else {
296 return;
297 };
298
299 perform_sample_hmac_sign_verify_op(&sl.binder, &key_metadata.key);
300 delete_app_key(&sl.keystore2, alias).unwrap();
301 }
302
303 /// Generate a key with `USAGE_EXPIRE_DATETIME` set to current date and time. Test should
304 /// successfully generate a key and verify the key characteristics. Test should be able to create
305 /// sign operation successfully and fail while performing verify operation with error code
306 /// `KEY_EXPIRED`.
307 #[test]
keystore2_gen_key_auth_usage_expire_datetime_hmac_verify_op_fail()308 fn keystore2_gen_key_auth_usage_expire_datetime_hmac_verify_op_fail() {
309 let sl = SecLevel::tee();
310
311 let duration_since_epoch = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
312 let usage_expire_datetime = duration_since_epoch.as_millis();
313 let gen_params = authorizations::AuthSetBuilder::new()
314 .no_auth_required()
315 .algorithm(Algorithm::HMAC)
316 .purpose(KeyPurpose::SIGN)
317 .purpose(KeyPurpose::VERIFY)
318 .key_size(128)
319 .min_mac_length(256)
320 .digest(Digest::SHA_2_256)
321 .usage_expire_date_time(usage_expire_datetime.try_into().unwrap());
322
323 let alias = "ks_test_auth_tags_hamc_verify_fail";
324 let Some(key_metadata) = key_generations::generate_key(&sl, &gen_params, alias).unwrap() else {
325 return;
326 };
327
328 let result = key_generations::map_ks_error(
329 sl.binder.createOperation(
330 &key_metadata.key,
331 &authorizations::AuthSetBuilder::new()
332 .purpose(KeyPurpose::VERIFY)
333 .digest(Digest::SHA_2_256),
334 false,
335 ),
336 );
337 assert!(result.is_err());
338 assert_eq!(Error::Km(ErrorCode::KEY_EXPIRED), result.unwrap_err());
339 delete_app_key(&sl.keystore2, alias).unwrap();
340 }
341
342 /// Generate AES key with `USAGE_EXPIRE_DATETIME` set to future date and time. Test should
343 /// successfully generate a key and verify the key characteristics. Test should be able to create
344 /// Encrypt and Decrypt operations successfully.
345 #[test]
keystore2_gen_key_auth_usage_future_expire_datetime_decrypt_op_success()346 fn keystore2_gen_key_auth_usage_future_expire_datetime_decrypt_op_success() {
347 let sl = SecLevel::tee();
348
349 let duration_since_epoch = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
350 let usage_expire_datetime = duration_since_epoch.as_millis() + (24 * 60 * 60 * 1000);
351 let gen_params = authorizations::AuthSetBuilder::new()
352 .no_auth_required()
353 .algorithm(Algorithm::AES)
354 .purpose(KeyPurpose::ENCRYPT)
355 .purpose(KeyPurpose::DECRYPT)
356 .key_size(128)
357 .padding_mode(PaddingMode::PKCS7)
358 .block_mode(BlockMode::ECB)
359 .usage_expire_date_time(usage_expire_datetime.try_into().unwrap());
360
361 let alias = "ks_test_auth_tags_test";
362 let Some(key_metadata) = key_generations::generate_key(&sl, &gen_params, alias).unwrap() else {
363 return;
364 };
365 let cipher_text = perform_sample_sym_key_encrypt_op(
366 &sl.binder,
367 PaddingMode::PKCS7,
368 BlockMode::ECB,
369 &mut None,
370 None,
371 &key_metadata.key,
372 )
373 .unwrap();
374
375 assert!(cipher_text.is_some());
376
377 let plain_text = perform_sample_sym_key_decrypt_op(
378 &sl.binder,
379 &cipher_text.unwrap(),
380 PaddingMode::PKCS7,
381 BlockMode::ECB,
382 &mut None,
383 None,
384 &key_metadata.key,
385 )
386 .unwrap();
387 assert!(plain_text.is_some());
388 assert_eq!(plain_text.unwrap(), SAMPLE_PLAIN_TEXT.to_vec());
389 delete_app_key(&sl.keystore2, alias).unwrap();
390 }
391
392 /// Generate AES key with `USAGE_EXPIRE_DATETIME` set to current date and time. Test should
393 /// successfully generate a key and verify the key characteristics. Test should be able to create
394 /// Encrypt operation successfully and fail while performing decrypt operation with error code
395 /// `KEY_EXPIRED`.
396 #[test]
keystore2_gen_key_auth_usage_expire_datetime_decrypt_op_fail()397 fn keystore2_gen_key_auth_usage_expire_datetime_decrypt_op_fail() {
398 let sl = SecLevel::tee();
399
400 let duration_since_epoch = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
401 let usage_expire_datetime = duration_since_epoch.as_millis();
402 let gen_params = authorizations::AuthSetBuilder::new()
403 .no_auth_required()
404 .algorithm(Algorithm::AES)
405 .purpose(KeyPurpose::ENCRYPT)
406 .purpose(KeyPurpose::DECRYPT)
407 .key_size(128)
408 .padding_mode(PaddingMode::PKCS7)
409 .block_mode(BlockMode::ECB)
410 .usage_expire_date_time(usage_expire_datetime.try_into().unwrap());
411
412 let alias = "ks_test_auth_tags_test";
413 let Some(key_metadata) = key_generations::generate_key(&sl, &gen_params, alias).unwrap() else {
414 return;
415 };
416 let cipher_text = perform_sample_sym_key_encrypt_op(
417 &sl.binder,
418 PaddingMode::PKCS7,
419 BlockMode::ECB,
420 &mut None,
421 None,
422 &key_metadata.key,
423 )
424 .unwrap();
425
426 assert!(cipher_text.is_some());
427
428 let result = key_generations::map_ks_error(perform_sample_sym_key_decrypt_op(
429 &sl.binder,
430 &cipher_text.unwrap(),
431 PaddingMode::PKCS7,
432 BlockMode::ECB,
433 &mut None,
434 None,
435 &key_metadata.key,
436 ));
437 assert!(result.is_err());
438 assert_eq!(Error::Km(ErrorCode::KEY_EXPIRED), result.unwrap_err());
439 delete_app_key(&sl.keystore2, alias).unwrap();
440 }
441
442 /// Generate a key with `EARLY_BOOT_ONLY`. Test should successfully generate
443 /// a key and verify the key characteristics. Test should fail with error code `EARLY_BOOT_ENDED`
444 /// during creation of an operation using this key.
445 #[test]
keystore2_gen_key_auth_early_boot_only_op_fail()446 fn keystore2_gen_key_auth_early_boot_only_op_fail() {
447 let sl = SecLevel::tee();
448 require_keymint!(sl);
449
450 let gen_params = authorizations::AuthSetBuilder::new()
451 .no_auth_required()
452 .algorithm(Algorithm::EC)
453 .purpose(KeyPurpose::SIGN)
454 .purpose(KeyPurpose::VERIFY)
455 .digest(Digest::SHA_2_256)
456 .ec_curve(EcCurve::P_256)
457 .early_boot_only();
458
459 let alias = "ks_test_auth_tags_test";
460 let result = key_generations::map_ks_error(key_generations::create_key_and_operation(
461 &sl,
462 &gen_params,
463 &authorizations::AuthSetBuilder::new().purpose(KeyPurpose::SIGN).digest(Digest::SHA_2_256),
464 alias,
465 ));
466 assert!(result.is_err());
467 assert_eq!(Error::Km(ErrorCode::EARLY_BOOT_ENDED), result.unwrap_err());
468 delete_app_key(&sl.keystore2, alias).unwrap();
469 }
470
471 /// Generate a key with `MAX_USES_PER_BOOT`. Test should successfully generate
472 /// a key and verify the key characteristics. Test should be able to use the key successfully
473 /// `MAX_USES_COUNT` times. After exceeding key usage `MAX_USES_COUNT` times
474 /// subsequent attempts to use the key in test should fail with error code MAX_OPS_EXCEEDED.
475 #[test]
keystore2_gen_key_auth_max_uses_per_boot()476 fn keystore2_gen_key_auth_max_uses_per_boot() {
477 let sl = SecLevel::tee();
478 if sl.is_keymaster() {
479 // Older devices with Keymaster implementation may use the key during generateKey to export
480 // the generated public key (EC Key), leading to an unnecessary increment of the
481 // key-associated counter. This can cause the test to fail, so skipping this test on older
482 // devices to avoid test failure.
483 return;
484 }
485 const MAX_USES_COUNT: i32 = 3;
486
487 let gen_params = authorizations::AuthSetBuilder::new()
488 .no_auth_required()
489 .algorithm(Algorithm::EC)
490 .purpose(KeyPurpose::SIGN)
491 .purpose(KeyPurpose::VERIFY)
492 .digest(Digest::SHA_2_256)
493 .ec_curve(EcCurve::P_256)
494 .max_uses_per_boot(MAX_USES_COUNT);
495
496 let alias = "ks_test_auth_tags_test";
497 // Generate a key and use the key for `MAX_USES_COUNT` times.
498 let Some(key_metadata) =
499 generate_key_and_perform_sign_verify_op_max_times(&sl, &gen_params, alias, MAX_USES_COUNT)
500 .unwrap()
501 else {
502 return;
503 };
504
505 // Try to use the key one more time.
506 let result = key_generations::map_ks_error(sl.binder.createOperation(
507 &key_metadata.key,
508 &authorizations::AuthSetBuilder::new().purpose(KeyPurpose::SIGN).digest(Digest::SHA_2_256),
509 false,
510 ));
511 assert!(result.is_err());
512 assert_eq!(Error::Km(ErrorCode::KEY_MAX_OPS_EXCEEDED), result.unwrap_err());
513 delete_app_key(&sl.keystore2, alias).unwrap();
514 }
515
516 /// Generate a key with `USAGE_COUNT_LIMIT`. Test should successfully generate
517 /// a key and verify the key characteristics. Test should be able to use the key successfully
518 /// `MAX_USES_COUNT` times. After exceeding key usage `MAX_USES_COUNT` times
519 /// subsequent attempts to use the key in test should fail with response code `KEY_NOT_FOUND`.
520 /// Test should also verify that the attest record includes `USAGE_COUNT_LIMIT`.
521 #[test]
keystore2_gen_key_auth_usage_count_limit()522 fn keystore2_gen_key_auth_usage_count_limit() {
523 let sl = SecLevel::tee();
524 if sl.is_keymaster() {
525 // `USAGE_COUNT_LIMIT` is supported from KeyMint1.0
526 return;
527 }
528 const MAX_USES_COUNT: i32 = 3;
529
530 let gen_params = authorizations::AuthSetBuilder::new()
531 .no_auth_required()
532 .algorithm(Algorithm::EC)
533 .purpose(KeyPurpose::SIGN)
534 .purpose(KeyPurpose::VERIFY)
535 .digest(Digest::SHA_2_256)
536 .ec_curve(EcCurve::P_256)
537 .attestation_challenge(b"foo".to_vec())
538 .usage_count_limit(MAX_USES_COUNT);
539
540 let alias = "ks_test_auth_tags_test";
541 generate_key_and_perform_op_with_max_usage_limit(&sl, &gen_params, alias, MAX_USES_COUNT, true);
542 }
543
544 /// Generate a key with `USAGE_COUNT_LIMIT`. Test should successfully generate
545 /// a key and verify the key characteristics. Test should be able to use the key successfully
546 /// `MAX_USES_COUNT` times. After exceeding key usage `MAX_USES_COUNT` times
547 /// subsequent attempts to use the key in test should fail with response code `KEY_NOT_FOUND`.
548 /// Test should also verify that the attest record includes `USAGE_COUNT_LIMIT`.
549 #[test]
keystore2_gen_key_auth_usage_count_limit_one()550 fn keystore2_gen_key_auth_usage_count_limit_one() {
551 let sl = SecLevel::tee();
552 if sl.is_keymaster() {
553 // `USAGE_COUNT_LIMIT` is supported from KeyMint1.0
554 return;
555 }
556 const MAX_USES_COUNT: i32 = 1;
557
558 let gen_params = authorizations::AuthSetBuilder::new()
559 .no_auth_required()
560 .algorithm(Algorithm::EC)
561 .purpose(KeyPurpose::SIGN)
562 .purpose(KeyPurpose::VERIFY)
563 .digest(Digest::SHA_2_256)
564 .ec_curve(EcCurve::P_256)
565 .attestation_challenge(b"foo".to_vec())
566 .usage_count_limit(MAX_USES_COUNT);
567
568 let alias = "ks_test_auth_tags_test";
569 generate_key_and_perform_op_with_max_usage_limit(&sl, &gen_params, alias, MAX_USES_COUNT, true);
570 }
571
572 /// Generate a non-attested key with `USAGE_COUNT_LIMIT`. Test should successfully generate
573 /// a key and verify the key characteristics. Test should be able to use the key successfully
574 /// `MAX_USES_COUNT` times. After exceeding key usage `MAX_USES_COUNT` times
575 /// subsequent attempts to use the key in test should fail with response code `KEY_NOT_FOUND`.
576 #[test]
keystore2_gen_non_attested_key_auth_usage_count_limit()577 fn keystore2_gen_non_attested_key_auth_usage_count_limit() {
578 let sl = SecLevel::tee();
579 if sl.is_keymaster() {
580 // `USAGE_COUNT_LIMIT` is supported from KeyMint1.0
581 return;
582 }
583 const MAX_USES_COUNT: i32 = 2;
584
585 let gen_params = authorizations::AuthSetBuilder::new()
586 .no_auth_required()
587 .algorithm(Algorithm::EC)
588 .purpose(KeyPurpose::SIGN)
589 .purpose(KeyPurpose::VERIFY)
590 .digest(Digest::SHA_2_256)
591 .ec_curve(EcCurve::P_256)
592 .usage_count_limit(MAX_USES_COUNT);
593
594 let alias = "ks_test_auth_tags_test";
595 generate_key_and_perform_op_with_max_usage_limit(
596 &sl,
597 &gen_params,
598 alias,
599 MAX_USES_COUNT,
600 false,
601 );
602 }
603
604 /// Try to generate a key with `Tag::CREATION_DATETIME` set to valid value. Test should fail
605 /// to generate a key with `INVALID_ARGUMENT` error as Keystore2 backend doesn't allow user to
606 /// specify `CREATION_DATETIME`.
607 #[test]
keystore2_gen_key_auth_creation_date_time_test_fail_with_invalid_arg_error()608 fn keystore2_gen_key_auth_creation_date_time_test_fail_with_invalid_arg_error() {
609 let sl = SecLevel::tee();
610
611 let duration_since_epoch = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
612 let creation_datetime = duration_since_epoch.as_millis();
613 let gen_params = authorizations::AuthSetBuilder::new()
614 .no_auth_required()
615 .algorithm(Algorithm::EC)
616 .purpose(KeyPurpose::SIGN)
617 .purpose(KeyPurpose::VERIFY)
618 .digest(Digest::SHA_2_256)
619 .ec_curve(EcCurve::P_256)
620 .creation_date_time(creation_datetime.try_into().unwrap());
621
622 let alias = "ks_test_auth_tags_test";
623 let result = key_generations::map_ks_error(sl.binder.generateKey(
624 &KeyDescriptor {
625 domain: Domain::APP,
626 nspace: -1,
627 alias: Some(alias.to_string()),
628 blob: None,
629 },
630 None,
631 &gen_params,
632 0,
633 b"entropy",
634 ));
635
636 assert!(result.is_err());
637 assert_eq!(Error::Rc(ResponseCode::INVALID_ARGUMENT), result.unwrap_err());
638 }
639
640 /// Generate a key with `Tag::INCLUDE_UNIQUE_ID` set. Test should verify that `Tag::UNIQUE_ID` is
641 /// included in attest record and it remains the same for new keys generated.
642 #[test]
keystore2_gen_key_auth_include_unique_id_success()643 fn keystore2_gen_key_auth_include_unique_id_success() {
644 let sl = SecLevel::tee();
645 if sl.is_keymaster() {
646 // b/387208956 - Some older devices with Keymaster implementations fail to generate an
647 // attestation key with `INCLUDE_UNIQUE_ID`, but this was not previously tested. Skip this
648 // test on devices with Keymaster implementation.
649 return;
650 }
651
652 let alias_first = "ks_test_auth_tags_test_1";
653 if let Some(unique_id_first) = gen_key_including_unique_id(&sl, alias_first) {
654 let alias_second = "ks_test_auth_tags_test_2";
655 let unique_id_second = gen_key_including_unique_id(&sl, alias_second).unwrap();
656
657 assert_eq!(unique_id_first, unique_id_second);
658
659 delete_app_key(&sl.keystore2, alias_first).unwrap();
660 delete_app_key(&sl.keystore2, alias_second).unwrap();
661 }
662 }
663
664 /// Generate a key with `APPLICATION_DATA` and `APPLICATION_ID`. Test should create an operation
665 /// successfully using the same `APPLICATION_DATA` and `APPLICATION_ID`.
666 #[test]
keystore2_gen_key_auth_app_data_app_id_test_success()667 fn keystore2_gen_key_auth_app_data_app_id_test_success() {
668 let sl = SecLevel::tee();
669 if sl.is_keymaster() && get_vsr_api_level() < 35 {
670 // `APPLICATION_DATA` key-parameter is causing the error on older devices, so skipping this
671 // test to run on older devices.
672 return;
673 }
674
675 let gen_params = authorizations::AuthSetBuilder::new()
676 .no_auth_required()
677 .algorithm(Algorithm::EC)
678 .purpose(KeyPurpose::SIGN)
679 .purpose(KeyPurpose::VERIFY)
680 .digest(Digest::NONE)
681 .ec_curve(EcCurve::P_256)
682 .app_data(b"app-data".to_vec())
683 .app_id(b"app-id".to_vec());
684
685 let alias = "ks_test_auth_tags_test";
686 let result = key_generations::create_key_and_operation(
687 &sl,
688 &gen_params,
689 &authorizations::AuthSetBuilder::new()
690 .purpose(KeyPurpose::SIGN)
691 .digest(Digest::NONE)
692 .app_data(b"app-data".to_vec())
693 .app_id(b"app-id".to_vec()),
694 alias,
695 );
696 assert!(result.is_ok());
697 delete_app_key(&sl.keystore2, alias).unwrap();
698 }
699
700 /// Generate a key with `APPLICATION_DATA` and `APPLICATION_ID`. Try to create an operation using
701 /// the different `APPLICATION_DATA` and `APPLICATION_ID`, test should fail to create an operation.
702 #[test]
keystore2_op_auth_invalid_app_data_app_id_test_fail()703 fn keystore2_op_auth_invalid_app_data_app_id_test_fail() {
704 let sl = SecLevel::tee();
705 if sl.is_keymaster() && get_vsr_api_level() < 35 {
706 // `APPLICATION_DATA` key-parameter is causing the error on older devices, so skipping this
707 // test to run on older devices.
708 return;
709 }
710
711 let gen_params = authorizations::AuthSetBuilder::new()
712 .no_auth_required()
713 .algorithm(Algorithm::EC)
714 .purpose(KeyPurpose::SIGN)
715 .purpose(KeyPurpose::VERIFY)
716 .digest(Digest::NONE)
717 .ec_curve(EcCurve::P_256)
718 .app_data(b"app-data".to_vec())
719 .app_id(b"app-id".to_vec());
720
721 let alias = "ks_test_auth_tags_test";
722 let result = key_generations::map_ks_error(key_generations::create_key_and_operation(
723 &sl,
724 &gen_params,
725 &authorizations::AuthSetBuilder::new()
726 .purpose(KeyPurpose::SIGN)
727 .digest(Digest::NONE)
728 .app_data(b"invalid-app-data".to_vec())
729 .app_id(b"invalid-app-id".to_vec()),
730 alias,
731 ));
732 assert!(result.is_err());
733 assert_eq!(Error::Km(ErrorCode::INVALID_KEY_BLOB), result.unwrap_err());
734 delete_app_key(&sl.keystore2, alias).unwrap();
735 }
736
737 /// Generate a key with `APPLICATION_DATA` and `APPLICATION_ID`. Try to create an operation using
738 /// only `APPLICATION_ID`, test should fail to create an operation.
739 #[test]
keystore2_op_auth_missing_app_data_test_fail()740 fn keystore2_op_auth_missing_app_data_test_fail() {
741 let sl = SecLevel::tee();
742 if sl.is_keymaster() && get_vsr_api_level() < 35 {
743 // `APPLICATION_DATA` key-parameter is causing the error on older devices, so skipping this
744 // test to run on older devices.
745 return;
746 }
747
748 let gen_params = authorizations::AuthSetBuilder::new()
749 .no_auth_required()
750 .algorithm(Algorithm::EC)
751 .purpose(KeyPurpose::SIGN)
752 .purpose(KeyPurpose::VERIFY)
753 .digest(Digest::NONE)
754 .ec_curve(EcCurve::P_256)
755 .app_id(b"app-id".to_vec())
756 .app_data(b"app-data".to_vec());
757
758 let alias = "ks_test_auth_tags_test";
759 let result = key_generations::map_ks_error(key_generations::create_key_and_operation(
760 &sl,
761 &gen_params,
762 &authorizations::AuthSetBuilder::new()
763 .purpose(KeyPurpose::SIGN)
764 .digest(Digest::NONE)
765 .app_id(b"app-id".to_vec()),
766 alias,
767 ));
768
769 assert!(result.is_err());
770 assert_eq!(Error::Km(ErrorCode::INVALID_KEY_BLOB), result.unwrap_err());
771 delete_app_key(&sl.keystore2, alias).unwrap();
772 }
773
774 /// Generate a key with `APPLICATION_DATA` and `APPLICATION_ID`. Try to create an operation using
775 /// only `APPLICATION_DATA`, test should fail to create an operation.
776 #[test]
keystore2_op_auth_missing_app_id_test_fail()777 fn keystore2_op_auth_missing_app_id_test_fail() {
778 let sl = SecLevel::tee();
779 if sl.is_keymaster() && get_vsr_api_level() < 35 {
780 // `APPLICATION_DATA` key-parameter is causing the error on older devices, so skipping this
781 // test to run on older devices.
782 return;
783 }
784
785 let gen_params = authorizations::AuthSetBuilder::new()
786 .no_auth_required()
787 .algorithm(Algorithm::EC)
788 .purpose(KeyPurpose::SIGN)
789 .purpose(KeyPurpose::VERIFY)
790 .digest(Digest::NONE)
791 .ec_curve(EcCurve::P_256)
792 .app_data(b"app-data".to_vec())
793 .app_id(b"app-id".to_vec());
794
795 let alias = "ks_test_auth_tags_test";
796 let result = key_generations::map_ks_error(key_generations::create_key_and_operation(
797 &sl,
798 &gen_params,
799 &authorizations::AuthSetBuilder::new()
800 .purpose(KeyPurpose::SIGN)
801 .digest(Digest::NONE)
802 .app_data(b"app-data".to_vec()),
803 alias,
804 ));
805 assert!(result.is_err());
806 assert_eq!(Error::Km(ErrorCode::INVALID_KEY_BLOB), result.unwrap_err());
807 delete_app_key(&sl.keystore2, alias).unwrap();
808 }
809
810 /// Generate an attestation-key without specifying `APPLICATION_ID` and `APPLICATION_DATA`.
811 /// Test should be able to generate a new key with specifying app-id and app-data using previously
812 /// generated attestation-key.
813 #[test]
keystore2_gen_attested_key_auth_app_id_app_data_test_success()814 fn keystore2_gen_attested_key_auth_app_id_app_data_test_success() {
815 skip_test_if_no_app_attest_key_feature!();
816 let sl = SecLevel::tee();
817 if sl.is_keymaster() && get_vsr_api_level() < 35 {
818 // `APPLICATION_DATA` key-parameter is causing the error on older devices, so skipping this
819 // test to run on older devices.
820 return;
821 }
822
823 // Generate attestation key.
824 let attest_gen_params = authorizations::AuthSetBuilder::new()
825 .no_auth_required()
826 .algorithm(Algorithm::EC)
827 .purpose(KeyPurpose::ATTEST_KEY)
828 .digest(Digest::SHA_2_256)
829 .ec_curve(EcCurve::P_256)
830 .attestation_challenge(b"foo".to_vec());
831 let attest_alias = "ks_test_auth_tags_attest_key";
832 let Some(attest_key_metadata) =
833 key_generations::generate_key(&sl, &attest_gen_params, attest_alias).unwrap()
834 else {
835 return;
836 };
837
838 // Generate attested key.
839 let alias = "ks_test_auth_tags_attested_key";
840 let gen_params = authorizations::AuthSetBuilder::new()
841 .no_auth_required()
842 .algorithm(Algorithm::EC)
843 .purpose(KeyPurpose::SIGN)
844 .purpose(KeyPurpose::VERIFY)
845 .digest(Digest::SHA_2_256)
846 .ec_curve(EcCurve::P_256)
847 .attestation_challenge(b"bar".to_vec())
848 .app_id(b"app-id".to_vec())
849 .app_data(b"app-data".to_vec());
850
851 let result = sl.binder.generateKey(
852 &KeyDescriptor {
853 domain: Domain::APP,
854 nspace: -1,
855 alias: Some(alias.to_string()),
856 blob: None,
857 },
858 Some(&attest_key_metadata.key),
859 &gen_params,
860 0,
861 b"entropy",
862 );
863
864 assert!(result.is_ok());
865 delete_app_key(&sl.keystore2, alias).unwrap();
866 delete_app_key(&sl.keystore2, attest_alias).unwrap();
867 }
868
869 /// Generate an attestation-key with specifying `APPLICATION_ID` and `APPLICATION_DATA`.
870 /// Test should try to generate an attested key using previously generated attestation-key without
871 /// specifying app-id and app-data. Test should fail to generate a new key.
872 /// It is an oversight of the Keystore API that `APPLICATION_ID` and `APPLICATION_DATA` tags cannot
873 /// be provided to generateKey for an attestation key that was generated with them.
874 #[test]
keystore2_gen_attestation_key_with_auth_app_id_app_data_test_fail()875 fn keystore2_gen_attestation_key_with_auth_app_id_app_data_test_fail() {
876 skip_test_if_no_app_attest_key_feature!();
877 let sl = SecLevel::tee();
878 if sl.is_keymaster() && get_vsr_api_level() < 35 {
879 // `APPLICATION_DATA` key-parameter is causing the error on older devices, so skipping this
880 // test to run on older devices.
881 return;
882 }
883
884 // Generate attestation key.
885 let attest_gen_params = authorizations::AuthSetBuilder::new()
886 .no_auth_required()
887 .algorithm(Algorithm::EC)
888 .purpose(KeyPurpose::ATTEST_KEY)
889 .digest(Digest::SHA_2_256)
890 .ec_curve(EcCurve::P_256)
891 .attestation_challenge(b"foo".to_vec())
892 .app_id(b"app-id".to_vec())
893 .app_data(b"app-data".to_vec());
894 let attest_alias = "ks_test_auth_tags_attest_key";
895 let Some(attest_key_metadata) =
896 key_generations::generate_key(&sl, &attest_gen_params, attest_alias).unwrap()
897 else {
898 return;
899 };
900
901 // Generate new key using above generated attestation key without providing app-id and app-data.
902 let alias = "ks_test_auth_tags_attested_key";
903 let gen_params = authorizations::AuthSetBuilder::new()
904 .no_auth_required()
905 .algorithm(Algorithm::EC)
906 .purpose(KeyPurpose::SIGN)
907 .purpose(KeyPurpose::VERIFY)
908 .digest(Digest::SHA_2_256)
909 .ec_curve(EcCurve::P_256)
910 .attestation_challenge(b"foo".to_vec());
911
912 let result = key_generations::map_ks_error(sl.binder.generateKey(
913 &KeyDescriptor {
914 domain: Domain::APP,
915 nspace: -1,
916 alias: Some(alias.to_string()),
917 blob: None,
918 },
919 Some(&attest_key_metadata.key),
920 &gen_params,
921 0,
922 b"entropy",
923 ));
924
925 assert!(result.is_err());
926 assert_eq!(Error::Km(ErrorCode::INVALID_KEY_BLOB), result.unwrap_err());
927 delete_app_key(&sl.keystore2, attest_alias).unwrap();
928 }
929
add_hardware_token(auth_type: HardwareAuthenticatorType)930 fn add_hardware_token(auth_type: HardwareAuthenticatorType) {
931 let keystore_auth = get_keystore_auth_service();
932
933 let token = HardwareAuthToken {
934 challenge: 0,
935 userId: 0,
936 authenticatorId: 0,
937 authenticatorType: auth_type,
938 timestamp: Timestamp { milliSeconds: 500 },
939 mac: vec![],
940 };
941 keystore_auth.addAuthToken(&token).unwrap();
942 }
943
944 #[test]
keystore2_get_last_auth_password_success()945 fn keystore2_get_last_auth_password_success() {
946 let keystore_auth = get_keystore_auth_service();
947
948 add_hardware_token(HardwareAuthenticatorType::PASSWORD);
949 assert!(keystore_auth.getLastAuthTime(0, &[HardwareAuthenticatorType::PASSWORD]).unwrap() > 0);
950 }
951
952 #[test]
keystore2_get_last_auth_fingerprint_success()953 fn keystore2_get_last_auth_fingerprint_success() {
954 let keystore_auth = get_keystore_auth_service();
955
956 add_hardware_token(HardwareAuthenticatorType::FINGERPRINT);
957 assert!(
958 keystore_auth.getLastAuthTime(0, &[HardwareAuthenticatorType::FINGERPRINT]).unwrap() > 0
959 );
960 }
961
962 /// Generate a key with specifying `CERTIFICATE_SUBJECT and CERTIFICATE_SERIAL`. Test should
963 /// generate a key successfully and verify the specified key parameters.
964 #[test]
keystore2_gen_key_auth_serial_number_subject_test_success()965 fn keystore2_gen_key_auth_serial_number_subject_test_success() {
966 let sl = SecLevel::tee();
967 require_keymint!(sl);
968
969 let cert_subject = "test cert subject";
970 let mut x509_name = X509NameBuilder::new().unwrap();
971 x509_name.append_entry_by_text("CN", cert_subject).unwrap();
972 let x509_name = x509_name.build().to_der().unwrap();
973
974 let mut serial = BigNum::new().unwrap();
975 serial.rand(159, MsbOption::MAYBE_ZERO, false).unwrap();
976
977 let gen_params = authorizations::AuthSetBuilder::new()
978 .no_auth_required()
979 .algorithm(Algorithm::EC)
980 .purpose(KeyPurpose::SIGN)
981 .purpose(KeyPurpose::VERIFY)
982 .digest(Digest::SHA_2_256)
983 .ec_curve(EcCurve::P_256)
984 .cert_subject_name(x509_name)
985 .cert_serial(serial.to_vec());
986
987 let alias = "ks_test_auth_tags_test";
988 let Some(key_metadata) = key_generations::generate_key(&sl, &gen_params, alias).unwrap() else {
989 return;
990 };
991 verify_certificate_subject_name(
992 key_metadata.certificate.as_ref().unwrap(),
993 cert_subject.as_bytes(),
994 );
995 verify_certificate_serial_num(key_metadata.certificate.as_ref().unwrap(), &serial);
996 delete_app_key(&sl.keystore2, alias).unwrap();
997 }
998
999 #[test]
test_supplementary_attestation_info()1000 fn test_supplementary_attestation_info() {
1001 if !keystore2_flags::attest_modules() {
1002 // Module info is only populated if the flag is set.
1003 return;
1004 }
1005
1006 // Test should not run before MODULE_HASH supplementary info is populated.
1007 assert!(rustutils::system_properties::read_bool("keystore.module_hash.sent", false)
1008 .unwrap_or(false));
1009
1010 let sl = SecLevel::tee();
1011
1012 // Retrieve the input value that gets hashed into the attestation.
1013 let module_info = sl
1014 .keystore2
1015 .getSupplementaryAttestationInfo(Tag::MODULE_HASH)
1016 .expect("supplementary info for MODULE_HASH should be populated during startup");
1017 let again = sl.keystore2.getSupplementaryAttestationInfo(Tag::MODULE_HASH).unwrap();
1018 assert_eq!(again, module_info);
1019 let want_hash = digest::Sha256::hash(&module_info).to_vec();
1020
1021 // Requesting other types of information should fail.
1022 let result = key_generations::map_ks_error(
1023 sl.keystore2.getSupplementaryAttestationInfo(Tag::BLOCK_MODE),
1024 );
1025 assert!(result.is_err());
1026 assert_eq!(result.unwrap_err(), Error::Rc(ResponseCode::INVALID_ARGUMENT));
1027
1028 if sl.get_keymint_version() < 400 {
1029 // Module hash will only be populated in KeyMint if the underlying device is KeyMint V4+.
1030 return;
1031 }
1032
1033 // Generate an attestation.
1034 let alias = "ks_module_info_test";
1035 let params = authorizations::AuthSetBuilder::new()
1036 .no_auth_required()
1037 .algorithm(Algorithm::EC)
1038 .purpose(KeyPurpose::SIGN)
1039 .purpose(KeyPurpose::VERIFY)
1040 .digest(Digest::SHA_2_256)
1041 .ec_curve(EcCurve::P_256)
1042 .attestation_challenge(b"froop".to_vec());
1043 let metadata = key_generations::generate_key(&sl, ¶ms, alias)
1044 .expect("failed key generation")
1045 .expect("no metadata");
1046 let cert_data = metadata.certificate.as_ref().unwrap();
1047 let cert = Certificate::from_der(cert_data).expect("failed to parse X509 cert");
1048 let exts = cert.tbs_certificate.extensions.expect("no X.509 extensions");
1049 let ext = exts
1050 .iter()
1051 .find(|ext| ext.extn_id == ATTESTATION_EXTENSION_OID)
1052 .expect("no attestation extension");
1053 let ext = AttestationExtension::from_der(ext.extn_value.as_bytes())
1054 .expect("failed to parse attestation extension");
1055
1056 // Find the attested module hash value.
1057 let mut got_hash = None;
1058 for auth in ext.sw_enforced.auths.into_owned().iter() {
1059 if let KeyParameter { tag: Tag::MODULE_HASH, value: KeyParameterValue::Blob(hash) } = auth {
1060 got_hash = Some(hash.clone());
1061 }
1062 }
1063 let got_hash = got_hash.expect("no MODULE_HASH in sw_enforced");
1064 assert_eq!(hex::encode(got_hash), hex::encode(want_hash));
1065 }
1066