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