1 // Integration test.
2 #![cfg(soong)]
3
4 // Explicitly include alloc because macros from `kmr_common` assume it.
5 extern crate alloc;
6
7 use kmr_common::{crypto, crypto::Rng, expect_err, keyblob, keyblob::legacy::KeyBlob};
8 use kmr_crypto_boring::aes::BoringAes;
9 use kmr_crypto_boring::eq::BoringEq;
10 use kmr_crypto_boring::hmac::BoringHmac;
11 use kmr_crypto_boring::rng::BoringRng;
12 use kmr_wire::{keymint, keymint::KeyParam};
13
14 #[test]
test_encrypted_keyblob_roundtrip()15 fn test_encrypted_keyblob_roundtrip() {
16 let aes = BoringAes;
17 let hmac = BoringHmac;
18 let mut rng = BoringRng;
19 let mut root_key = crypto::RawKeyMaterial(vec![0u8; 32]);
20 rng.fill_bytes(&mut root_key.0);
21 let plaintext_keyblob = keyblob::PlaintextKeyBlob {
22 characteristics: vec![keymint::KeyCharacteristics {
23 security_level: keymint::SecurityLevel::TrustedEnvironment,
24 authorizations: vec![
25 KeyParam::Algorithm(keymint::Algorithm::Aes),
26 KeyParam::BlockMode(keymint::BlockMode::Ecb),
27 KeyParam::Padding(keymint::PaddingMode::None),
28 ],
29 }],
30 key_material: crypto::KeyMaterial::Aes(crypto::aes::Key::Aes128([0u8; 16]).into()),
31 };
32 let hidden = vec![
33 KeyParam::ApplicationId(b"app_id".to_vec()),
34 KeyParam::ApplicationData(b"app_data".to_vec()),
35 ];
36
37 let encrypted_keyblob = keyblob::encrypt(
38 keymint::SecurityLevel::TrustedEnvironment,
39 None,
40 &aes,
41 &hmac,
42 &mut rng,
43 &root_key,
44 &[],
45 plaintext_keyblob.clone(),
46 hidden.clone(),
47 )
48 .unwrap();
49
50 let recovered_keyblob =
51 keyblob::decrypt(None, &aes, &hmac, &root_key, encrypted_keyblob, hidden).unwrap();
52 assert_eq!(plaintext_keyblob, recovered_keyblob);
53 }
54
55 #[test]
test_serialize_authenticated_legacy_keyblob()56 fn test_serialize_authenticated_legacy_keyblob() {
57 let hidden = kmr_common::keyblob::legacy::hidden(&[], &[b"SW"]).unwrap();
58 let tests = vec![(
59 concat!(
60 "00", // version
61 "02000000",
62 "bbbb", // key material
63 concat!(
64 "00000000", // no blob data
65 "00000000", // no params
66 "00000000", // zero size of params
67 ),
68 concat!(
69 "00000000", // no blob data
70 "00000000", // no params
71 "00000000", // zero size of params
72 ),
73 "0000000000000000", // hmac
74 ),
75 KeyBlob { key_material: vec![0xbb, 0xbb], hw_enforced: vec![], sw_enforced: vec![] },
76 )];
77 for (hex_data, want) in tests {
78 let mut data = hex::decode(hex_data).unwrap();
79
80 // Key blob cannot be deserialized without a correct MAC.
81 let hmac = BoringHmac {};
82 let result = KeyBlob::deserialize(&hmac, &data, &hidden, BoringEq);
83 expect_err!(result, "invalid key blob");
84
85 fix_hmac(&mut data, &hidden);
86 let got = KeyBlob::deserialize(&hmac, &data, &hidden, BoringEq).unwrap();
87 assert_eq!(got, want);
88 let new_data = got.serialize(&hmac, &hidden).unwrap();
89 assert_eq!(new_data, data);
90 }
91 }
92
93 #[test]
test_deserialize_authenticated_legacy_keyblob_fail()94 fn test_deserialize_authenticated_legacy_keyblob_fail() {
95 let hidden = kmr_common::keyblob::legacy::hidden(&[], &[b"SW"]).unwrap();
96 let tests = vec![
97 (
98 concat!(
99 "02", // version
100 "02000000",
101 "bbbb", // key material
102 concat!(
103 "00000000", // no blob data
104 "00000000", // no params
105 "00000000", // zero size of params
106 ),
107 concat!(
108 "00000000", // no blob data
109 "00000000", // no params
110 "00000000", // zero size of params
111 ),
112 "0000000000000000", // hmac
113 ),
114 "unexpected blob version 2",
115 ),
116 (
117 concat!(
118 "00", // version
119 "02000000",
120 "bbbb", // key material
121 concat!(
122 "00000000", // no blob data
123 "00000000", // no params
124 "00000000", // zero size of params
125 ),
126 concat!(
127 "00000000", // no blob data
128 "00000000", // no params
129 "00000000", // zero size of params
130 ),
131 "00", // bonus byte
132 "0000000000000000", // hmac
133 ),
134 "extra data (len 1)",
135 ),
136 ];
137 let hmac = BoringHmac {};
138 for (hex_data, msg) in tests {
139 let mut data = hex::decode(hex_data).unwrap();
140 fix_hmac(&mut data, &hidden);
141 let result = KeyBlob::deserialize(&hmac, &data, &hidden, BoringEq);
142 expect_err!(result, msg);
143 }
144 }
145
146 #[test]
test_deserialize_authenticated_legacy_keyblob_truncated()147 fn test_deserialize_authenticated_legacy_keyblob_truncated() {
148 let hidden = kmr_common::keyblob::legacy::hidden(&[], &[b"SW"]).unwrap();
149 let mut data = hex::decode(concat!(
150 "00", // version
151 "02000000",
152 "bbbb", // key material
153 concat!(
154 "00000000", // no blob data
155 "00000000", // no params
156 "00000000", // zero size of params
157 ),
158 concat!(
159 "00000000", // no blob data
160 "00000000", // no params
161 "00000000", // zero size of params
162 ),
163 "0000000000000000", // hmac
164 ))
165 .unwrap();
166 fix_hmac(&mut data, &hidden);
167 let hmac = BoringHmac {};
168 assert!(KeyBlob::deserialize(&hmac, &data, &hidden, BoringEq).is_ok());
169
170 for len in 0..data.len() - 1 {
171 // Any truncation of this data is invalid.
172 assert!(
173 KeyBlob::deserialize(&hmac, &data[..len], &hidden, BoringEq).is_err(),
174 "deserialize of data[..{}] subset (len={}) unexpectedly succeeded",
175 len,
176 data.len()
177 );
178 }
179 }
180
fix_hmac(data: &mut [u8], hidden: &[KeyParam])181 fn fix_hmac(data: &mut [u8], hidden: &[KeyParam]) {
182 let hmac = BoringHmac {};
183 let mac_offset = data.len() - KeyBlob::MAC_LEN;
184 let mac = KeyBlob::compute_hmac(&hmac, &data[..mac_offset], hidden).unwrap();
185 data[mac_offset..].copy_from_slice(&mac);
186 }
187