1*9860b763SAndroid Build Coastguard Worker // Copyright 2022, The Android Open Source Project
2*9860b763SAndroid Build Coastguard Worker //
3*9860b763SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*9860b763SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*9860b763SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*9860b763SAndroid Build Coastguard Worker //
7*9860b763SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0
8*9860b763SAndroid Build Coastguard Worker //
9*9860b763SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*9860b763SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*9860b763SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*9860b763SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*9860b763SAndroid Build Coastguard Worker // limitations under the License.
14*9860b763SAndroid Build Coastguard Worker
15*9860b763SAndroid Build Coastguard Worker use super::*;
16*9860b763SAndroid Build Coastguard Worker use crate::expect_err;
17*9860b763SAndroid Build Coastguard Worker use crate::tag::legacy::{consume_u32, consume_u64, consume_u8, consume_vec};
18*9860b763SAndroid Build Coastguard Worker use alloc::vec;
19*9860b763SAndroid Build Coastguard Worker
20*9860b763SAndroid Build Coastguard Worker #[test]
test_consume_u8()21*9860b763SAndroid Build Coastguard Worker fn test_consume_u8() {
22*9860b763SAndroid Build Coastguard Worker let buffer = [1, 2];
23*9860b763SAndroid Build Coastguard Worker let mut data = &buffer[..];
24*9860b763SAndroid Build Coastguard Worker assert_eq!(1u8, consume_u8(&mut data).unwrap());
25*9860b763SAndroid Build Coastguard Worker assert_eq!(2u8, consume_u8(&mut data).unwrap());
26*9860b763SAndroid Build Coastguard Worker let result = consume_u8(&mut data);
27*9860b763SAndroid Build Coastguard Worker expect_err!(result, "failed to find 1 byte");
28*9860b763SAndroid Build Coastguard Worker }
29*9860b763SAndroid Build Coastguard Worker
30*9860b763SAndroid Build Coastguard Worker #[test]
test_consume_u32()31*9860b763SAndroid Build Coastguard Worker fn test_consume_u32() {
32*9860b763SAndroid Build Coastguard Worker let buffer = [
33*9860b763SAndroid Build Coastguard Worker 0x01, 0x02, 0x03, 0x04, //
34*9860b763SAndroid Build Coastguard Worker 0x04, 0x03, 0x02, 0x01, //
35*9860b763SAndroid Build Coastguard Worker 0x11, 0x12, 0x13,
36*9860b763SAndroid Build Coastguard Worker ];
37*9860b763SAndroid Build Coastguard Worker let mut data = &buffer[..];
38*9860b763SAndroid Build Coastguard Worker assert_eq!(0x04030201u32, consume_u32(&mut data).unwrap());
39*9860b763SAndroid Build Coastguard Worker assert_eq!(0x01020304u32, consume_u32(&mut data).unwrap());
40*9860b763SAndroid Build Coastguard Worker let result = consume_u32(&mut data);
41*9860b763SAndroid Build Coastguard Worker expect_err!(result, "failed to find 4 bytes");
42*9860b763SAndroid Build Coastguard Worker }
43*9860b763SAndroid Build Coastguard Worker
44*9860b763SAndroid Build Coastguard Worker #[test]
test_consume_u64()45*9860b763SAndroid Build Coastguard Worker fn test_consume_u64() {
46*9860b763SAndroid Build Coastguard Worker let buffer = [
47*9860b763SAndroid Build Coastguard Worker 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, //
48*9860b763SAndroid Build Coastguard Worker 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, //
49*9860b763SAndroid Build Coastguard Worker 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
50*9860b763SAndroid Build Coastguard Worker ];
51*9860b763SAndroid Build Coastguard Worker let mut data = &buffer[..];
52*9860b763SAndroid Build Coastguard Worker assert_eq!(0x0807060504030201u64, consume_u64(&mut data).unwrap());
53*9860b763SAndroid Build Coastguard Worker assert_eq!(0x0102030405060708u64, consume_u64(&mut data).unwrap());
54*9860b763SAndroid Build Coastguard Worker let result = consume_u64(&mut data);
55*9860b763SAndroid Build Coastguard Worker expect_err!(result, "failed to find 8 bytes");
56*9860b763SAndroid Build Coastguard Worker }
57*9860b763SAndroid Build Coastguard Worker
58*9860b763SAndroid Build Coastguard Worker #[test]
test_consume_vec()59*9860b763SAndroid Build Coastguard Worker fn test_consume_vec() {
60*9860b763SAndroid Build Coastguard Worker let buffer = [
61*9860b763SAndroid Build Coastguard Worker 0x01, 0x00, 0x00, 0x00, 0xaa, //
62*9860b763SAndroid Build Coastguard Worker 0x00, 0x00, 0x00, 0x00, //
63*9860b763SAndroid Build Coastguard Worker 0x01, 0x00, 0x00, 0x00, 0xbb, //
64*9860b763SAndroid Build Coastguard Worker 0x07, 0x00, 0x00, 0x00, 0xbb, // not enough data
65*9860b763SAndroid Build Coastguard Worker ];
66*9860b763SAndroid Build Coastguard Worker let mut data = &buffer[..];
67*9860b763SAndroid Build Coastguard Worker assert_eq!(vec![0xaa], consume_vec(&mut data).unwrap());
68*9860b763SAndroid Build Coastguard Worker assert_eq!(Vec::<u8>::new(), consume_vec(&mut data).unwrap());
69*9860b763SAndroid Build Coastguard Worker assert_eq!(vec![0xbb], consume_vec(&mut data).unwrap());
70*9860b763SAndroid Build Coastguard Worker let result = consume_vec(&mut data);
71*9860b763SAndroid Build Coastguard Worker expect_err!(result, "failed to find 7 bytes");
72*9860b763SAndroid Build Coastguard Worker
73*9860b763SAndroid Build Coastguard Worker let buffer = [
74*9860b763SAndroid Build Coastguard Worker 0x01, 0x00, 0x00, //
75*9860b763SAndroid Build Coastguard Worker ];
76*9860b763SAndroid Build Coastguard Worker let mut data = &buffer[..];
77*9860b763SAndroid Build Coastguard Worker let result = consume_vec(&mut data);
78*9860b763SAndroid Build Coastguard Worker expect_err!(result, "failed to find 4 bytes");
79*9860b763SAndroid Build Coastguard Worker }
80*9860b763SAndroid Build Coastguard Worker
81*9860b763SAndroid Build Coastguard Worker #[test]
test_serialize_encrypted_keyblob()82*9860b763SAndroid Build Coastguard Worker fn test_serialize_encrypted_keyblob() {
83*9860b763SAndroid Build Coastguard Worker let tests = vec![
84*9860b763SAndroid Build Coastguard Worker (
85*9860b763SAndroid Build Coastguard Worker concat!(
86*9860b763SAndroid Build Coastguard Worker "00", // format
87*9860b763SAndroid Build Coastguard Worker "01000000",
88*9860b763SAndroid Build Coastguard Worker "aa", // nonce
89*9860b763SAndroid Build Coastguard Worker "02000000",
90*9860b763SAndroid Build Coastguard Worker "bbbb", // ciphertext
91*9860b763SAndroid Build Coastguard Worker "01000000",
92*9860b763SAndroid Build Coastguard Worker "cc", // tag
93*9860b763SAndroid Build Coastguard Worker concat!(
94*9860b763SAndroid Build Coastguard Worker "00000000", // no blob data
95*9860b763SAndroid Build Coastguard Worker "00000000", // no params
96*9860b763SAndroid Build Coastguard Worker "00000000", // zero size of params
97*9860b763SAndroid Build Coastguard Worker ),
98*9860b763SAndroid Build Coastguard Worker concat!(
99*9860b763SAndroid Build Coastguard Worker "00000000", // no blob data
100*9860b763SAndroid Build Coastguard Worker "00000000", // no params
101*9860b763SAndroid Build Coastguard Worker "00000000", // zero size of params
102*9860b763SAndroid Build Coastguard Worker ),
103*9860b763SAndroid Build Coastguard Worker ),
104*9860b763SAndroid Build Coastguard Worker EncryptedKeyBlob {
105*9860b763SAndroid Build Coastguard Worker format: AuthEncryptedBlobFormat::AesOcb,
106*9860b763SAndroid Build Coastguard Worker nonce: vec![0xaa],
107*9860b763SAndroid Build Coastguard Worker ciphertext: vec![0xbb, 0xbb],
108*9860b763SAndroid Build Coastguard Worker tag: vec![0xcc],
109*9860b763SAndroid Build Coastguard Worker kdf_version: None,
110*9860b763SAndroid Build Coastguard Worker addl_info: None,
111*9860b763SAndroid Build Coastguard Worker hw_enforced: vec![],
112*9860b763SAndroid Build Coastguard Worker sw_enforced: vec![],
113*9860b763SAndroid Build Coastguard Worker key_slot: None,
114*9860b763SAndroid Build Coastguard Worker },
115*9860b763SAndroid Build Coastguard Worker ),
116*9860b763SAndroid Build Coastguard Worker (
117*9860b763SAndroid Build Coastguard Worker concat!(
118*9860b763SAndroid Build Coastguard Worker "01", // format
119*9860b763SAndroid Build Coastguard Worker "01000000",
120*9860b763SAndroid Build Coastguard Worker "aa", // nonce
121*9860b763SAndroid Build Coastguard Worker "02000000",
122*9860b763SAndroid Build Coastguard Worker "bbbb", // ciphertext
123*9860b763SAndroid Build Coastguard Worker "01000000",
124*9860b763SAndroid Build Coastguard Worker "cc", // tag
125*9860b763SAndroid Build Coastguard Worker concat!(
126*9860b763SAndroid Build Coastguard Worker "00000000", // no blob data
127*9860b763SAndroid Build Coastguard Worker "00000000", // no params
128*9860b763SAndroid Build Coastguard Worker "00000000", // zero size of params
129*9860b763SAndroid Build Coastguard Worker ),
130*9860b763SAndroid Build Coastguard Worker concat!(
131*9860b763SAndroid Build Coastguard Worker "00000000", // no blob data
132*9860b763SAndroid Build Coastguard Worker "00000000", // no params
133*9860b763SAndroid Build Coastguard Worker "00000000", // zero size of params
134*9860b763SAndroid Build Coastguard Worker ),
135*9860b763SAndroid Build Coastguard Worker "06000000",
136*9860b763SAndroid Build Coastguard Worker ),
137*9860b763SAndroid Build Coastguard Worker EncryptedKeyBlob {
138*9860b763SAndroid Build Coastguard Worker format: AuthEncryptedBlobFormat::AesGcmWithSwEnforced,
139*9860b763SAndroid Build Coastguard Worker nonce: vec![0xaa],
140*9860b763SAndroid Build Coastguard Worker ciphertext: vec![0xbb, 0xbb],
141*9860b763SAndroid Build Coastguard Worker tag: vec![0xcc],
142*9860b763SAndroid Build Coastguard Worker kdf_version: None,
143*9860b763SAndroid Build Coastguard Worker addl_info: None,
144*9860b763SAndroid Build Coastguard Worker hw_enforced: vec![],
145*9860b763SAndroid Build Coastguard Worker sw_enforced: vec![],
146*9860b763SAndroid Build Coastguard Worker key_slot: Some(6),
147*9860b763SAndroid Build Coastguard Worker },
148*9860b763SAndroid Build Coastguard Worker ),
149*9860b763SAndroid Build Coastguard Worker (
150*9860b763SAndroid Build Coastguard Worker concat!(
151*9860b763SAndroid Build Coastguard Worker "03", // format
152*9860b763SAndroid Build Coastguard Worker "01000000",
153*9860b763SAndroid Build Coastguard Worker "aa", // nonce
154*9860b763SAndroid Build Coastguard Worker "02000000",
155*9860b763SAndroid Build Coastguard Worker "bbbb", // ciphertext
156*9860b763SAndroid Build Coastguard Worker "01000000",
157*9860b763SAndroid Build Coastguard Worker "cc", // tag
158*9860b763SAndroid Build Coastguard Worker "01010101", // kdf_version
159*9860b763SAndroid Build Coastguard Worker "04040404", // addl_info
160*9860b763SAndroid Build Coastguard Worker concat!(
161*9860b763SAndroid Build Coastguard Worker "00000000", // no blob data
162*9860b763SAndroid Build Coastguard Worker "00000000", // no params
163*9860b763SAndroid Build Coastguard Worker "00000000", // zero size of params
164*9860b763SAndroid Build Coastguard Worker ),
165*9860b763SAndroid Build Coastguard Worker concat!(
166*9860b763SAndroid Build Coastguard Worker "00000000", // no blob data
167*9860b763SAndroid Build Coastguard Worker "00000000", // no params
168*9860b763SAndroid Build Coastguard Worker "00000000", // zero size of params
169*9860b763SAndroid Build Coastguard Worker ),
170*9860b763SAndroid Build Coastguard Worker "06000000",
171*9860b763SAndroid Build Coastguard Worker ),
172*9860b763SAndroid Build Coastguard Worker EncryptedKeyBlob {
173*9860b763SAndroid Build Coastguard Worker format: AuthEncryptedBlobFormat::AesGcmWithSwEnforcedVersioned,
174*9860b763SAndroid Build Coastguard Worker nonce: vec![0xaa],
175*9860b763SAndroid Build Coastguard Worker ciphertext: vec![0xbb, 0xbb],
176*9860b763SAndroid Build Coastguard Worker tag: vec![0xcc],
177*9860b763SAndroid Build Coastguard Worker kdf_version: Some(0x01010101),
178*9860b763SAndroid Build Coastguard Worker addl_info: Some(0x04040404),
179*9860b763SAndroid Build Coastguard Worker hw_enforced: vec![],
180*9860b763SAndroid Build Coastguard Worker sw_enforced: vec![],
181*9860b763SAndroid Build Coastguard Worker key_slot: Some(6),
182*9860b763SAndroid Build Coastguard Worker },
183*9860b763SAndroid Build Coastguard Worker ),
184*9860b763SAndroid Build Coastguard Worker ];
185*9860b763SAndroid Build Coastguard Worker for (hex_data, want) in tests {
186*9860b763SAndroid Build Coastguard Worker let data = hex::decode(hex_data).unwrap();
187*9860b763SAndroid Build Coastguard Worker let got = EncryptedKeyBlob::deserialize(&data).unwrap();
188*9860b763SAndroid Build Coastguard Worker assert_eq!(got, want);
189*9860b763SAndroid Build Coastguard Worker let new_data = got.serialize().unwrap();
190*9860b763SAndroid Build Coastguard Worker assert_eq!(new_data, data);
191*9860b763SAndroid Build Coastguard Worker }
192*9860b763SAndroid Build Coastguard Worker }
193*9860b763SAndroid Build Coastguard Worker
194*9860b763SAndroid Build Coastguard Worker #[test]
test_deserialize_encrypted_keyblob_fail()195*9860b763SAndroid Build Coastguard Worker fn test_deserialize_encrypted_keyblob_fail() {
196*9860b763SAndroid Build Coastguard Worker let tests = vec![
197*9860b763SAndroid Build Coastguard Worker (
198*9860b763SAndroid Build Coastguard Worker concat!(
199*9860b763SAndroid Build Coastguard Worker "09", // format (invalid)
200*9860b763SAndroid Build Coastguard Worker "01000000",
201*9860b763SAndroid Build Coastguard Worker "aa", // nonce
202*9860b763SAndroid Build Coastguard Worker "02000000",
203*9860b763SAndroid Build Coastguard Worker "bbbb", // ciphertext
204*9860b763SAndroid Build Coastguard Worker "01000000",
205*9860b763SAndroid Build Coastguard Worker "cc", // tag
206*9860b763SAndroid Build Coastguard Worker concat!(
207*9860b763SAndroid Build Coastguard Worker "00000000", // no blob data
208*9860b763SAndroid Build Coastguard Worker "00000000", // no params
209*9860b763SAndroid Build Coastguard Worker "00000000", // zero size of params
210*9860b763SAndroid Build Coastguard Worker ),
211*9860b763SAndroid Build Coastguard Worker concat!(
212*9860b763SAndroid Build Coastguard Worker "00000000", // no blob data
213*9860b763SAndroid Build Coastguard Worker "00000000", // no params
214*9860b763SAndroid Build Coastguard Worker "00000000", // zero size of params
215*9860b763SAndroid Build Coastguard Worker ),
216*9860b763SAndroid Build Coastguard Worker ),
217*9860b763SAndroid Build Coastguard Worker "unexpected blob format 9",
218*9860b763SAndroid Build Coastguard Worker ),
219*9860b763SAndroid Build Coastguard Worker (
220*9860b763SAndroid Build Coastguard Worker concat!(
221*9860b763SAndroid Build Coastguard Worker "02", // format
222*9860b763SAndroid Build Coastguard Worker "01000000",
223*9860b763SAndroid Build Coastguard Worker "aa", // nonce
224*9860b763SAndroid Build Coastguard Worker "02000000",
225*9860b763SAndroid Build Coastguard Worker "bbbb", // ciphertext
226*9860b763SAndroid Build Coastguard Worker "01000000",
227*9860b763SAndroid Build Coastguard Worker "cc", // tag
228*9860b763SAndroid Build Coastguard Worker concat!(
229*9860b763SAndroid Build Coastguard Worker "00000000", // no blob data
230*9860b763SAndroid Build Coastguard Worker "00000000", // no params
231*9860b763SAndroid Build Coastguard Worker "00000000", // zero size of params
232*9860b763SAndroid Build Coastguard Worker ),
233*9860b763SAndroid Build Coastguard Worker concat!(
234*9860b763SAndroid Build Coastguard Worker "00000000", // no blob data
235*9860b763SAndroid Build Coastguard Worker "00000000", // no params
236*9860b763SAndroid Build Coastguard Worker "00000000", // zero size of params
237*9860b763SAndroid Build Coastguard Worker ),
238*9860b763SAndroid Build Coastguard Worker "060000",
239*9860b763SAndroid Build Coastguard Worker ),
240*9860b763SAndroid Build Coastguard Worker "unexpected remaining length 3",
241*9860b763SAndroid Build Coastguard Worker ),
242*9860b763SAndroid Build Coastguard Worker ];
243*9860b763SAndroid Build Coastguard Worker for (hex_data, msg) in tests {
244*9860b763SAndroid Build Coastguard Worker let data = hex::decode(hex_data).unwrap();
245*9860b763SAndroid Build Coastguard Worker let result = EncryptedKeyBlob::deserialize(&data);
246*9860b763SAndroid Build Coastguard Worker expect_err!(result, msg);
247*9860b763SAndroid Build Coastguard Worker }
248*9860b763SAndroid Build Coastguard Worker }
249*9860b763SAndroid Build Coastguard Worker
250*9860b763SAndroid Build Coastguard Worker #[test]
test_deserialize_encrypted_keyblob_truncated()251*9860b763SAndroid Build Coastguard Worker fn test_deserialize_encrypted_keyblob_truncated() {
252*9860b763SAndroid Build Coastguard Worker let data = hex::decode(concat!(
253*9860b763SAndroid Build Coastguard Worker "00", // format
254*9860b763SAndroid Build Coastguard Worker "01000000",
255*9860b763SAndroid Build Coastguard Worker "aa", // nonce
256*9860b763SAndroid Build Coastguard Worker "02000000",
257*9860b763SAndroid Build Coastguard Worker "bbbb", // ciphertext
258*9860b763SAndroid Build Coastguard Worker "01000000",
259*9860b763SAndroid Build Coastguard Worker "cc", // tag
260*9860b763SAndroid Build Coastguard Worker concat!(
261*9860b763SAndroid Build Coastguard Worker "00000000", // no blob data
262*9860b763SAndroid Build Coastguard Worker "00000000", // no params
263*9860b763SAndroid Build Coastguard Worker "00000000", // zero size of params
264*9860b763SAndroid Build Coastguard Worker ),
265*9860b763SAndroid Build Coastguard Worker concat!(
266*9860b763SAndroid Build Coastguard Worker "00000000", // no blob data
267*9860b763SAndroid Build Coastguard Worker "00000000", // no params
268*9860b763SAndroid Build Coastguard Worker "00000000", // zero size of params
269*9860b763SAndroid Build Coastguard Worker ),
270*9860b763SAndroid Build Coastguard Worker ))
271*9860b763SAndroid Build Coastguard Worker .unwrap();
272*9860b763SAndroid Build Coastguard Worker assert!(EncryptedKeyBlob::deserialize(&data).is_ok());
273*9860b763SAndroid Build Coastguard Worker for len in 0..data.len() - 1 {
274*9860b763SAndroid Build Coastguard Worker // Any truncation of this data is invalid.
275*9860b763SAndroid Build Coastguard Worker assert!(
276*9860b763SAndroid Build Coastguard Worker EncryptedKeyBlob::deserialize(&data[..len]).is_err(),
277*9860b763SAndroid Build Coastguard Worker "deserialize of data[..{}] subset (len={}) unexpectedly succeeded",
278*9860b763SAndroid Build Coastguard Worker len,
279*9860b763SAndroid Build Coastguard Worker data.len()
280*9860b763SAndroid Build Coastguard Worker );
281*9860b763SAndroid Build Coastguard Worker }
282*9860b763SAndroid Build Coastguard Worker }
283