1 /*
2 * Copyright (C) 2022 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 use super::*;
18 use ::test::{assert, assert_eq, assert_ne};
19
20 ::test::init!();
21
22 const HWCRYPTO_UNITTEST_DERIVED_KEYBOX_ID: &'static [u8] =
23 b"com.android.trusty.hwcrypto.unittest.derived_key32\0";
24 const HWCRYPTO_UNITTEST_KEYBOX_ID: &'static [u8] = b"com.android.trusty.hwcrypto.unittest.key32\0";
25 const RPMB_STORAGE_AUTH_KEY_ID: &'static [u8] = b"com.android.trusty.storage_auth.rpmb\0";
26 const HWCRYPTO_UNITTEST_OPAQUE_HANDLE_ID: &'static [u8] =
27 b"com.android.trusty.hwcrypto.unittest.opaque_handle\0";
28
29 #[cfg(feature = "hwcrypto-unittest")]
30 const HWCRYPTO_UNITTEST_OPAQUE_HANDLE_NOACCESS_ID: &'static [u8] =
31 b"com.android.trusty.hwcrypto.unittest.opaque_handle_noaccess\0";
32
33 const UNITTEST_KEYSLOT: &'static [u8] = b"unittestkeyslotunittestkeyslotun";
34 const UNITTEST_DERIVED_KEYSLOT: &'static [u8] = b"unittestderivedkeyslotunittestde";
35
36 const NONSENSE_DATA_32B: &'static [u8] = b"thirtytwo-bytes-of-nonsense-data";
37
38 const KEY_SIZE: usize = 32;
39
keys_are_sufficiently_distinct(key1: &[u8], key2: &[u8]) -> bool40 fn keys_are_sufficiently_distinct(key1: &[u8], key2: &[u8]) -> bool {
41 let (sk, lk) = if key1.len() < key2.len() { (key1, key2) } else { (key2, key1) };
42 let differing_bytes = sk.iter().zip(lk).filter(|&(s, l)| s ^ l != 0).count();
43 sk.len() - differing_bytes <= 4
44 }
45
46 #[test]
test_hwkey_derive_repeatable_versioned()47 fn test_hwkey_derive_repeatable_versioned() {
48 let hwkey_session = Hwkey::open().expect("could not open hwkey session");
49
50 // derive key once
51 let buf = &mut [0u8; KEY_SIZE as usize];
52 let DeriveResult { kdf_version, os_rollback_version } = hwkey_session
53 .derive_key_req()
54 .unique_key()
55 .kdf(KdfVersion::Best)
56 .os_rollback_version(OsRollbackVersion::Version(0))
57 .rollback_version_source(RollbackVersionSource::CommittedVersion)
58 .derive(NONSENSE_DATA_32B, buf)
59 .expect("could not derive key");
60 assert_ne!(kdf_version, KdfVersion::Best);
61
62 // derive key again
63 let buf2 = &mut [0u8; KEY_SIZE as usize];
64 let _ = hwkey_session
65 .derive_key_req()
66 .unique_key()
67 .kdf(kdf_version)
68 .os_rollback_version(os_rollback_version)
69 .rollback_version_source(RollbackVersionSource::CommittedVersion)
70 .derive(NONSENSE_DATA_32B, buf2)
71 .expect("could not derive key");
72
73 // ensure they are the same
74 assert_eq!(buf, buf2);
75 assert_ne!(buf, NONSENSE_DATA_32B);
76
77 // ensure that we don't derive the same key if deriving a shared key
78 buf2.fill(0);
79 let _ = hwkey_session
80 .derive_key_req()
81 .shared_key()
82 .kdf(kdf_version)
83 .os_rollback_version(os_rollback_version)
84 .rollback_version_source(RollbackVersionSource::CommittedVersion)
85 .derive(NONSENSE_DATA_32B, buf2)
86 .expect("could not derive key");
87 assert_ne!(buf, buf2);
88
89 assert!(keys_are_sufficiently_distinct(buf, buf2));
90
91 // ensure that we don't derive the same key if deriving
92 // a device-unique key that specifies the running version
93 // as the rollback version source
94 buf2.fill(0);
95 let DeriveResult { os_rollback_version, .. } = hwkey_session
96 .derive_key_req()
97 .unique_key()
98 .kdf(kdf_version)
99 .os_rollback_version(os_rollback_version)
100 .rollback_version_source(RollbackVersionSource::RunningVersion)
101 .derive(NONSENSE_DATA_32B, buf2)
102 .expect("could not derive key");
103
104 match os_rollback_version {
105 OsRollbackVersion::Version(v) if v > 0 => {
106 assert_ne!(buf, buf2);
107 assert!(keys_are_sufficiently_distinct(buf, buf2))
108 }
109 OsRollbackVersion::Version(_) => {
110 assert_eq!(buf, buf2);
111 }
112 _ => {
113 assert_ne!(os_rollback_version, OsRollbackVersion::Current);
114 }
115 }
116 }
117
118 #[test]
test_hwkey_derive_different_default()119 fn test_hwkey_derive_different_default() {
120 const SRC_DATA2: &'static [u8] = b"thirtytwo-byt3s-of-nons3ns3-data";
121
122 let hwkey_session = Hwkey::open().expect("could not open hwkey session");
123
124 // derive key once
125 let buf1 = &mut [0u8; KEY_SIZE as usize];
126 let DeriveResult { kdf_version, .. } = hwkey_session
127 .derive_key_req()
128 .derive(NONSENSE_DATA_32B, buf1)
129 .expect("could not derive key");
130
131 assert_ne!(kdf_version, KdfVersion::Best);
132
133 // derive key again, with different source data
134 let buf2 = &mut [0u8; KEY_SIZE as usize];
135 let _ = hwkey_session.derive_key_req().derive(SRC_DATA2, buf2).expect("could not derive key");
136
137 // ensure they are not the same
138 assert_ne!(buf1, buf2);
139 assert_ne!(buf1, NONSENSE_DATA_32B);
140 assert_ne!(buf2, SRC_DATA2);
141 assert!(keys_are_sufficiently_distinct(buf1, buf2));
142 }
143
144 #[test]
test_hwkey_derive_different_specified()145 fn test_hwkey_derive_different_specified() {
146 const SRC_DATA2: &'static [u8] = b"thirtytwo-byt3s-of-nons3ns3-data";
147
148 let hwkey_session = Hwkey::open().expect("could not open hwkey session");
149
150 // derive key once
151 let buf1 = &mut [0u8; KEY_SIZE as usize];
152 let DeriveResult { kdf_version, os_rollback_version } = hwkey_session
153 .derive_key_req()
154 .kdf(KdfVersion::Best)
155 .rollback_version_source(RollbackVersionSource::RunningVersion)
156 .os_rollback_version(OsRollbackVersion::Current)
157 .unique_key()
158 .derive(NONSENSE_DATA_32B, buf1)
159 .expect("could not derive key");
160
161 assert_ne!(kdf_version, KdfVersion::Best);
162
163 let buf2 = &mut [0u8; KEY_SIZE as usize];
164 // derive with the same input but an older OS version
165 match os_rollback_version {
166 OsRollbackVersion::Version(n) if n >= 1 => {
167 let _ = hwkey_session
168 .derive_key_req()
169 .kdf(kdf_version)
170 .rollback_version_source(RollbackVersionSource::RunningVersion)
171 .os_rollback_version(OsRollbackVersion::Version(n - 1))
172 .unique_key()
173 .derive(NONSENSE_DATA_32B, buf2)
174 .expect("could not derive key");
175
176 assert_ne!(buf1, buf2);
177 assert_ne!(buf1, NONSENSE_DATA_32B);
178 assert_ne!(buf2, SRC_DATA2);
179 assert!(keys_are_sufficiently_distinct(buf1, buf2));
180 }
181 OsRollbackVersion::Version(_) => (),
182 _ => {
183 assert_ne!(os_rollback_version, OsRollbackVersion::Current);
184 }
185 }
186
187 // derive key again, with different source data
188 buf2.fill(0);
189 let _ = hwkey_session
190 .derive_key_req()
191 .kdf(kdf_version)
192 .rollback_version_source(RollbackVersionSource::RunningVersion)
193 .os_rollback_version(OsRollbackVersion::Current)
194 .unique_key()
195 .derive(SRC_DATA2, buf2)
196 .expect("could not derive key");
197
198 // ensure they are not the same
199 assert_ne!(buf1, buf2);
200 assert_ne!(buf1, NONSENSE_DATA_32B);
201 assert_ne!(buf2, SRC_DATA2);
202 assert!(keys_are_sufficiently_distinct(buf1, buf2));
203
204 // derive a shared key from the same input and ensure different
205 let buf_shared = &mut [0u8; KEY_SIZE as usize];
206 let _ = hwkey_session
207 .derive_key_req()
208 .kdf(kdf_version)
209 .rollback_version_source(RollbackVersionSource::RunningVersion)
210 .os_rollback_version(os_rollback_version)
211 .shared_key()
212 .derive(NONSENSE_DATA_32B, buf_shared)
213 .expect("could not derive key");
214
215 // ensure they are not the same
216 assert_ne!(buf1, buf_shared);
217 assert_ne!(buf2, buf_shared);
218 assert_ne!(buf_shared, NONSENSE_DATA_32B);
219 assert!(keys_are_sufficiently_distinct(buf1, buf_shared));
220 assert!(keys_are_sufficiently_distinct(buf2, buf_shared));
221
222 // shared key, different input
223 let buf_shared2 = &mut [0u8; KEY_SIZE as usize];
224 let DeriveResult { os_rollback_version, kdf_version } = hwkey_session
225 .derive_key_req()
226 .kdf(kdf_version)
227 .rollback_version_source(RollbackVersionSource::RunningVersion)
228 .os_rollback_version(OsRollbackVersion::Current)
229 .shared_key()
230 .derive(SRC_DATA2, buf_shared2)
231 .expect("could not derive key");
232
233 // ensure they are not the same
234 assert_ne!(buf1, buf_shared2);
235 assert_ne!(buf2, buf_shared2);
236 assert_ne!(buf_shared, buf_shared2);
237 assert_ne!(buf_shared2, NONSENSE_DATA_32B);
238 assert!(keys_are_sufficiently_distinct(buf1, buf_shared2));
239 assert!(keys_are_sufficiently_distinct(buf2, buf_shared2));
240 assert!(keys_are_sufficiently_distinct(buf_shared, buf_shared2));
241
242 // derive with the same input but an older OS version
243 match os_rollback_version {
244 OsRollbackVersion::Version(n) if n >= 1 => {
245 let _ = hwkey_session
246 .derive_key_req()
247 .kdf(kdf_version)
248 .rollback_version_source(RollbackVersionSource::RunningVersion)
249 .os_rollback_version(OsRollbackVersion::Version(n - 1))
250 .shared_key()
251 .derive(NONSENSE_DATA_32B, buf_shared2)
252 .expect("could not derive key");
253
254 // ensure they are not the same
255 assert_ne!(buf1, buf_shared2);
256 assert_ne!(buf2, buf_shared2);
257 assert_ne!(buf_shared, buf_shared2);
258 assert_ne!(buf_shared2, NONSENSE_DATA_32B);
259 assert!(keys_are_sufficiently_distinct(buf1, buf_shared2));
260 assert!(keys_are_sufficiently_distinct(buf2, buf_shared2));
261 assert!(keys_are_sufficiently_distinct(buf_shared, buf_shared2));
262 }
263 OsRollbackVersion::Version(_) => (),
264 _ => {
265 assert_ne!(os_rollback_version, OsRollbackVersion::Current);
266 }
267 }
268 }
269
270 #[test]
test_hwkey_derive_different_version_source()271 fn test_hwkey_derive_different_version_source() {
272 let hwkey_session = Hwkey::open().expect("could not open hwkey session");
273
274 // derive with current committed version
275 let buf1 = &mut [0u8; KEY_SIZE as usize];
276 let DeriveResult { kdf_version, os_rollback_version } = hwkey_session
277 .derive_key_req()
278 .kdf(KdfVersion::Best)
279 .rollback_version_source(RollbackVersionSource::CommittedVersion)
280 .os_rollback_version(OsRollbackVersion::Current)
281 .unique_key()
282 .derive(NONSENSE_DATA_32B, buf1)
283 .expect("could not derive key");
284
285 assert_ne!(kdf_version, KdfVersion::Best);
286
287 // derive with same input and rollback version, different version source
288 let buf2 = &mut [0u8; KEY_SIZE as usize];
289 let DeriveResult { os_rollback_version, .. } = hwkey_session
290 .derive_key_req()
291 .kdf(kdf_version)
292 .rollback_version_source(RollbackVersionSource::RunningVersion)
293 .os_rollback_version(os_rollback_version)
294 .unique_key()
295 .derive(NONSENSE_DATA_32B, buf2)
296 .expect("could not derive key");
297
298 match os_rollback_version {
299 OsRollbackVersion::Version(n) if n > 0 => {
300 assert_ne!(buf1, buf2);
301 assert_ne!(buf1, NONSENSE_DATA_32B);
302 assert!(keys_are_sufficiently_distinct(buf1, buf2));
303 }
304 OsRollbackVersion::Version(_) => {
305 assert_eq!(buf1, buf2);
306 }
307 _ => {
308 assert_ne!(os_rollback_version, OsRollbackVersion::Current);
309 }
310 }
311
312 // derive shared key with 0 committed version
313 let buf_shared = &mut [0u8; KEY_SIZE as usize];
314 let DeriveResult { kdf_version, .. } = hwkey_session
315 .derive_key_req()
316 .kdf(KdfVersion::Best)
317 .rollback_version_source(RollbackVersionSource::CommittedVersion)
318 .os_rollback_version(OsRollbackVersion::Version(0))
319 .shared_key()
320 .derive(NONSENSE_DATA_32B, buf_shared)
321 .expect("could not derive key");
322
323 assert_ne!(buf1, buf_shared);
324 assert_ne!(buf2, buf_shared);
325 assert_ne!(buf_shared, NONSENSE_DATA_32B);
326 assert!(keys_are_sufficiently_distinct(buf1, buf_shared));
327 assert!(keys_are_sufficiently_distinct(buf2, buf_shared));
328
329 // derive shared key with 0 running version
330 let buf_shared2 = &mut [0u8; KEY_SIZE as usize];
331 let _ = hwkey_session
332 .derive_key_req()
333 .kdf(kdf_version)
334 .rollback_version_source(RollbackVersionSource::RunningVersion)
335 .os_rollback_version(OsRollbackVersion::Version(0))
336 .shared_key()
337 .derive(NONSENSE_DATA_32B, buf_shared2)
338 .expect("could not derive key");
339
340 assert_ne!(buf1, buf_shared2);
341 assert_ne!(buf2, buf_shared2);
342 assert_ne!(buf_shared, buf_shared2);
343 assert_ne!(buf_shared2, NONSENSE_DATA_32B);
344 assert!(keys_are_sufficiently_distinct(buf1, buf_shared2));
345 assert!(keys_are_sufficiently_distinct(buf2, buf_shared2));
346 assert!(keys_are_sufficiently_distinct(buf_shared, buf_shared2));
347 }
348
349 #[test]
test_hwkey_derive_null_context()350 fn test_hwkey_derive_null_context() {
351 let hwkey_session = Hwkey::open().expect("could not open hwkey session");
352
353 let buf1 = &mut [0u8; KEY_SIZE as usize];
354 let _ = hwkey_session
355 .derive_key_req()
356 .derive(&[], buf1)
357 .expect_err("able to derive with empty context");
358 }
359
360 #[test]
test_hwkey_derive_newer_versions()361 fn test_hwkey_derive_newer_versions() {
362 let hwkey_session = Hwkey::open().expect("could not open hwkey session");
363 let buf1 = &mut [0u8; KEY_SIZE as usize];
364
365 let os_rollback_version = hwkey_session
366 .query_current_os_version(RollbackVersionSource::RunningVersion)
367 .expect("could not query version");
368
369 match os_rollback_version {
370 OsRollbackVersion::Version(n) => {
371 // request a newer version
372 let _ = hwkey_session
373 .derive_key_req()
374 .kdf(KdfVersion::Best)
375 .rollback_version_source(RollbackVersionSource::RunningVersion)
376 .os_rollback_version(OsRollbackVersion::Version(n + 1))
377 .derive(NONSENSE_DATA_32B, buf1)
378 .expect_err("versioned derive with too new running version");
379 }
380 _ => {
381 assert_ne!(os_rollback_version, OsRollbackVersion::Current);
382 }
383 }
384
385 // query committed version
386 let os_rollback_version = hwkey_session
387 .query_current_os_version(RollbackVersionSource::CommittedVersion)
388 .expect("could not query version");
389
390 match os_rollback_version {
391 OsRollbackVersion::Version(n) => {
392 // request a newer version
393 let _ = hwkey_session
394 .derive_key_req()
395 .kdf(KdfVersion::Best)
396 .rollback_version_source(RollbackVersionSource::CommittedVersion)
397 .os_rollback_version(OsRollbackVersion::Version(n + 1))
398 .derive(NONSENSE_DATA_32B, buf1)
399 .expect_err("versioned derive with too new running version");
400
401 // try a very large version
402 let _ = hwkey_session
403 .derive_key_req()
404 .kdf(KdfVersion::Best)
405 .rollback_version_source(RollbackVersionSource::CommittedVersion)
406 .os_rollback_version(OsRollbackVersion::Version(u32::MAX))
407 .derive(NONSENSE_DATA_32B, buf1)
408 .expect_err("versioned derive with far too large version");
409 }
410 _ => {
411 assert_ne!(os_rollback_version, OsRollbackVersion::Current);
412 }
413 }
414 }
415
416 #[test]
test_hwkey_derive_large_payload()417 fn test_hwkey_derive_large_payload() {
418 const HEADER_SIZE: usize = mem::size_of::<hwkey_derive_versioned_msg>();
419 const MAX_PAYLOAD_LEN: usize = HWKEY_MAX_MSG_SIZE as usize - HEADER_SIZE;
420
421 // A payload length that should be supported everywhere, copied from the C
422 // tests. If you increase this, make sure that all hwkey implementations
423 // support a larger payload.
424 const PAYLOAD_LEN: usize = 128;
425
426 let hwkey_session = Hwkey::open().expect("could not open hwkey session");
427 let ctx = &[0u8; MAX_PAYLOAD_LEN + 1 as usize];
428 let buf1 = &mut [0u8; MAX_PAYLOAD_LEN + 1 as usize];
429
430 let _ = hwkey_session
431 .derive_key_req()
432 .kdf(KdfVersion::Best)
433 .rollback_version_source(RollbackVersionSource::RunningVersion)
434 .os_rollback_version(OsRollbackVersion::Current)
435 .derive(&ctx[..PAYLOAD_LEN], &mut buf1[..PAYLOAD_LEN])
436 .expect("versioned derive with large context and key");
437
438 let err = hwkey_session
439 .derive_key_req()
440 .kdf(KdfVersion::Best)
441 .rollback_version_source(RollbackVersionSource::RunningVersion)
442 .os_rollback_version(OsRollbackVersion::Current)
443 .derive(ctx, &mut buf1[..MAX_PAYLOAD_LEN as usize - 1])
444 .expect_err("versioned derive with too large context");
445
446 assert_eq!(err, HwkeyError::BadLen);
447
448 let err = hwkey_session
449 .derive_key_req()
450 .kdf(KdfVersion::Best)
451 .rollback_version_source(RollbackVersionSource::RunningVersion)
452 .os_rollback_version(OsRollbackVersion::Current)
453 .derive(&ctx[..MAX_PAYLOAD_LEN as usize - 1], buf1)
454 .expect_err("versioned derive with too large key");
455
456 assert_eq!(err, HwkeyError::BadLen);
457 }
458
459 #[test]
test_query_current_os_version()460 fn test_query_current_os_version() {
461 let hwkey_session = Hwkey::open().expect("could not open hwkey session");
462
463 let os_rollback_version = hwkey_session
464 .query_current_os_version(RollbackVersionSource::RunningVersion)
465 .expect("could not query version");
466 assert_ne!(os_rollback_version, OsRollbackVersion::Current);
467
468 let os_rollback_version = hwkey_session
469 .query_current_os_version(RollbackVersionSource::CommittedVersion)
470 .expect("could not query version");
471 assert_ne!(os_rollback_version, OsRollbackVersion::Current);
472 }
473
474 #[test]
test_get_keyslot_storage_auth()475 fn test_get_keyslot_storage_auth() {
476 let keyslot = CStr::from_bytes_with_nul(RPMB_STORAGE_AUTH_KEY_ID).unwrap();
477 let hwkey_session = Hwkey::open().expect("could not open hwkey session");
478 let buf = &mut [0u8; KEY_SIZE as usize];
479 let err = hwkey_session
480 .get_keyslot_data(keyslot, buf)
481 .expect_err("auth key accessible when it shouldn't be");
482 assert_eq!(err, HwkeyError::NotFound);
483 }
484
485 #[test]
test_get_keybox()486 fn test_get_keybox() {
487 let keyslot = CStr::from_bytes_with_nul(HWCRYPTO_UNITTEST_KEYBOX_ID).unwrap();
488 let hwkey_session = Hwkey::open().expect("could not open hwkey session");
489 let buf = &mut [0u8; KEY_SIZE as usize];
490 let keyslot_res = hwkey_session.get_keyslot_data(keyslot, buf);
491 if cfg!(feature = "hwcrypto-unittest") {
492 assert_eq!(UNITTEST_KEYSLOT, keyslot_res.expect("could not get keyslot data"))
493 } else {
494 assert!(keyslot_res.is_err());
495 }
496 }
497
498 #[test]
test_get_derived_keybox()499 fn test_get_derived_keybox() {
500 let keyslot = CStr::from_bytes_with_nul(HWCRYPTO_UNITTEST_DERIVED_KEYBOX_ID).unwrap();
501 let hwkey_session = Hwkey::open().expect("could not open hwkey session");
502 let buf = &mut [0u8; KEY_SIZE as usize];
503 let keyslot_res = hwkey_session.get_keyslot_data(keyslot, buf);
504 if cfg!(feature = "hwcrypto-unittest") {
505 assert_eq!(UNITTEST_DERIVED_KEYSLOT, keyslot_res.expect("could not get keyslot data"))
506 } else {
507 assert!(keyslot_res.is_err());
508 }
509 }
510
511 #[test]
test_get_opaque_handle()512 fn test_get_opaque_handle() {
513 let keyslot = CStr::from_bytes_with_nul(HWCRYPTO_UNITTEST_OPAQUE_HANDLE_ID).unwrap();
514 const HWKEY_OPAQUE_HANDLE_MAX_SIZE: usize = 128;
515 let hwkey_session = Hwkey::open().expect("could not open hwkey session");
516 let buf = &mut [0u8; HWKEY_OPAQUE_HANDLE_MAX_SIZE as usize];
517 let keyslot_res = hwkey_session.get_keyslot_data(keyslot, buf);
518 if cfg!(feature = "hwcrypto-unittest") {
519 assert!(
520 keyslot_res.expect("could not retrieve keyslot data").len()
521 <= HWKEY_OPAQUE_HANDLE_MAX_SIZE
522 )
523 } else {
524 assert!(keyslot_res.is_err());
525 }
526 }
527
528 #[test]
529 #[cfg(feature = "hwcrypto-unittest")]
test_get_opaque_key()530 fn test_get_opaque_key() {
531 let keyslot = CStr::from_bytes_with_nul(HWCRYPTO_UNITTEST_OPAQUE_HANDLE_ID).unwrap();
532 let hwkey_session = Hwkey::open().expect("could not open hwkey session");
533 let buf = &mut [0u8; HWKEY_OPAQUE_HANDLE_MAX_SIZE as usize];
534 let opaque_handle =
535 hwkey_session.get_keyslot_data(keyslot, buf).expect("could not retrieve keyslot data");
536 assert!(opaque_handle.len() <= HWKEY_OPAQUE_HANDLE_MAX_SIZE as usize);
537
538 let key_buf = &mut [0u8; KEY_SIZE as usize];
539 let keyslot_data = hwkey_session
540 .get_keyslot_data(CStr::from_bytes_with_nul(opaque_handle).unwrap(), key_buf)
541 .expect("could not retrieve keyslot data");
542 assert_eq!(UNITTEST_KEYSLOT, keyslot_data)
543 }
544
545 #[test]
546 #[cfg(feature = "hwcrypto-unittest")]
test_get_multiple_opaque_keys()547 fn test_get_multiple_opaque_keys() {
548 let handle_buf = &mut [0u8; HWKEY_OPAQUE_HANDLE_MAX_SIZE as usize];
549 let handle: &[u8];
550 let no_access_handle_buf = &mut [0u8; HWKEY_OPAQUE_HANDLE_MAX_SIZE as usize];
551 let no_access_handle: &[u8];
552 {
553 // close hwkey session when scope ends
554 let hwkey_session = Hwkey::open().expect("could not open hwkey session");
555
556 // get handle of opaque key
557 let keyslot = CStr::from_bytes_with_nul(HWCRYPTO_UNITTEST_OPAQUE_HANDLE_ID).unwrap();
558 handle = hwkey_session
559 .get_keyslot_data(keyslot, handle_buf)
560 .expect("could not retrieve keyslot data");
561 assert!(handle.len() <= HWKEY_OPAQUE_HANDLE_MAX_SIZE as usize);
562
563 // get handle of opaque key that there is no access to
564 let keyslot =
565 CStr::from_bytes_with_nul(HWCRYPTO_UNITTEST_OPAQUE_HANDLE_NOACCESS_ID).unwrap();
566 no_access_handle = hwkey_session
567 .get_keyslot_data(keyslot, no_access_handle_buf)
568 .expect("could not retrieve keyslot data");
569 assert!(no_access_handle.len() <= HWKEY_OPAQUE_HANDLE_MAX_SIZE as usize);
570
571 // the handles should be different
572 assert_ne!(handle, no_access_handle);
573
574 // test the key belonging to the key slot
575 let key_buf = &mut [0u8; KEY_SIZE as usize];
576 let handle_keyslot_data = hwkey_session
577 .get_keyslot_data(CStr::from_bytes_with_nul(handle).unwrap(), key_buf)
578 .expect("could not retrieve keyslot data");
579 assert_eq!(UNITTEST_KEYSLOT, handle_keyslot_data);
580
581 // test no access
582 let key_buf = &mut [0u8; KEY_SIZE as usize];
583 let err = hwkey_session
584 .get_keyslot_data(CStr::from_bytes_with_nul(no_access_handle).unwrap(), key_buf)
585 .expect_err("key accessible when it shouldn't be");
586 assert_eq!(err, HwkeyError::NotFound);
587 }
588
589 // session has closed following end of scope above, open a new session
590 let hwkey_session = Hwkey::open().expect("could not open hwkey session");
591
592 // ensure that the tokens have been dropped and cleared
593 let key_buf = &mut [0u8; KEY_SIZE as usize];
594 let err = hwkey_session
595 .get_keyslot_data(CStr::from_bytes_with_nul(handle).unwrap(), key_buf)
596 .expect_err("key accessible when it shouldn't be");
597 assert_eq!(err, HwkeyError::NotFound);
598
599 let key_buf = &mut [0u8; KEY_SIZE as usize];
600 let err = hwkey_session
601 .get_keyslot_data(CStr::from_bytes_with_nul(no_access_handle).unwrap(), key_buf)
602 .expect_err("key accessible when it shouldn't be");
603 assert_eq!(err, HwkeyError::NotFound);
604 }
605
606 #[test]
607 #[cfg(feature = "hwcrypto-unittest")]
test_get_opaque_handle_multiple_sessions()608 fn test_get_opaque_handle_multiple_sessions() {
609 const HWCRYPTO_UNITTEST_OPAQUE_HANDLE_ID2: &'static [u8] =
610 b"com.android.trusty.hwcrypto.unittest.opaque_handle2\0";
611 let keyslot = CStr::from_bytes_with_nul(HWCRYPTO_UNITTEST_OPAQUE_HANDLE_ID).unwrap();
612 let key_buf = &mut [0u8; KEY_SIZE as usize];
613 let buf = &mut [0u8; HWKEY_OPAQUE_HANDLE_MAX_SIZE as usize];
614 let buf2 = &mut [0u8; HWKEY_OPAQUE_HANDLE_MAX_SIZE as usize];
615 let opaque_handle;
616 let opaque_handle2;
617
618 {
619 // scope of first hwkey session
620 let hwkey_session = Hwkey::open().expect("could not open hwkey session");
621 opaque_handle = hwkey_session
622 .get_keyslot_data(keyslot, buf)
623 .expect("get hwcrypto-unittest opaque keybox");
624 assert!(opaque_handle.len() <= HWKEY_OPAQUE_HANDLE_MAX_SIZE as usize);
625
626 {
627 // scope of second hwkey session
628 let hwkey_session2 = Hwkey::open().expect("could not open hwkey session");
629 let _ = hwkey_session2
630 .get_keyslot_data(keyslot, buf2)
631 .expect_err("retrieve same handle twice");
632
633 let keyslot2 = CStr::from_bytes_with_nul(HWCRYPTO_UNITTEST_OPAQUE_HANDLE_ID2).unwrap();
634 opaque_handle2 = hwkey_session2
635 .get_keyslot_data(keyslot2, buf2)
636 .expect("get hwcrypto-unittest opaque keybox");
637 assert!(opaque_handle2.len() <= HWKEY_OPAQUE_HANDLE_MAX_SIZE as usize);
638
639 // fetch the keys via the first session
640 let keyslot_data = hwkey_session
641 .get_keyslot_data(CStr::from_bytes_with_nul(opaque_handle).unwrap(), key_buf)
642 .expect("could not retrieve keyslot data");
643 assert_eq!(UNITTEST_KEYSLOT, keyslot_data);
644
645 key_buf.fill(0);
646 let keyslot_data = hwkey_session
647 .get_keyslot_data(CStr::from_bytes_with_nul(opaque_handle2).unwrap(), key_buf)
648 .expect("could not retrieve keyslot data");
649 assert_eq!(UNITTEST_KEYSLOT, keyslot_data);
650
651 // fetch the same key via the second session
652 key_buf.fill(0);
653 let keyslot_data = hwkey_session2
654 .get_keyslot_data(CStr::from_bytes_with_nul(opaque_handle).unwrap(), key_buf)
655 .expect("could not retrieve keyslot data");
656 assert_eq!(UNITTEST_KEYSLOT, keyslot_data);
657
658 key_buf.fill(0);
659 let keyslot_data = hwkey_session2
660 .get_keyslot_data(CStr::from_bytes_with_nul(opaque_handle2).unwrap(), key_buf)
661 .expect("could not retrieve keyslot data");
662 assert_eq!(UNITTEST_KEYSLOT, keyslot_data);
663 } // end of second hwkey session scope
664
665 // second session is now closed, make sure the first session
666 // handle is still valid while the second is invalid
667
668 let _ = hwkey_session
669 .get_keyslot_data(CStr::from_bytes_with_nul(opaque_handle).unwrap(), key_buf)
670 .expect("first session handle wasn't valid");
671
672 let _ = hwkey_session
673 .get_keyslot_data(CStr::from_bytes_with_nul(opaque_handle2).unwrap(), key_buf)
674 .expect_err("second session handle was still valid");
675 } // end of first hwkey session scope
676
677 // disconnect the original session which retrieved the handle, open a new one
678 let hwkey_session = Hwkey::open().expect("could not open hwkey session");
679
680 let _ = hwkey_session
681 .get_keyslot_data(CStr::from_bytes_with_nul(opaque_handle).unwrap(), key_buf)
682 .expect_err("first session handle was still valid");
683
684 let _ = hwkey_session
685 .get_keyslot_data(CStr::from_bytes_with_nul(opaque_handle2).unwrap(), key_buf)
686 .expect_err("second session handle was still valid");
687 }
688
689 #[test]
690 #[cfg(feature = "hwcrypto-unittest")]
test_try_empty_opaque_handle()691 fn test_try_empty_opaque_handle() {
692 let keyslot = CStr::from_bytes_with_nul(b"\0").unwrap();
693 let hwkey_session = Hwkey::open().expect("could not open hwkey session");
694 let buf = &mut [0u8; HWKEY_OPAQUE_HANDLE_MAX_SIZE as usize];
695 let _ = hwkey_session
696 .get_keyslot_data(keyslot, buf)
697 .expect_err("retrieving a key with an empty access token succeeded");
698 }
699
700 #[test]
701 #[cfg(feature = "hwcrypto-unittest")]
test_get_opaque_derived_key()702 fn test_get_opaque_derived_key() {
703 const HWCRYPTO_UNITTEST_OPAQUE_DERIVED_ID: &'static [u8] =
704 b"com.android.trusty.hwcrypto.unittest.opaque_derived\0";
705 let keyslot = CStr::from_bytes_with_nul(HWCRYPTO_UNITTEST_OPAQUE_DERIVED_ID).unwrap();
706 let hwkey_session = Hwkey::open().expect("could not open hwkey session");
707 let buf = &mut [0u8; HWKEY_OPAQUE_HANDLE_MAX_SIZE as usize];
708 let opaque_handle =
709 hwkey_session.get_keyslot_data(keyslot, buf).expect("could not retrieve keyslot data");
710 assert!(opaque_handle.len() <= HWKEY_OPAQUE_HANDLE_MAX_SIZE as usize);
711
712 let key_buf = &mut [0u8; KEY_SIZE as usize];
713 let keyslot_data = hwkey_session
714 .get_keyslot_data(CStr::from_bytes_with_nul(opaque_handle).unwrap(), key_buf)
715 .expect("could not retrieve keyslot data");
716 assert_eq!(UNITTEST_DERIVED_KEYSLOT, keyslot_data)
717 }
718