wlan_rsn/keywrap/
aes.rs

1// Copyright 2018 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::aes::{self, KeyUnwrapIo, KeyWrapIo, SizedKey};
6use crate::keywrap::Algorithm;
7use crate::Error;
8
9/// RFC 3394 AES key wrapping.
10pub struct NistAes;
11
12impl Algorithm for NistAes {
13    /// RFC 3394, 2.2.1 AES key wrapping.
14    // NOTE: The IV is never used in this implementation.
15    fn wrap_key(&self, key: &[u8], _iv: &[u8; 16], p: &[u8]) -> Result<Vec<u8>, Error> {
16        let key = SizedKey::try_from_slice(key)?;
17        let kio = KeyWrapIo::try_from_input(p)?;
18        let wrapped = aes::wrap_key(&key, None, kio)?;
19        Ok(wrapped)
20    }
21
22    /// RFC 3394, 2.2.2 AES key unwrapping.
23    // NOTE: The IV is never used in this implementation.
24    fn unwrap_key(&self, key: &[u8], _iv: &[u8; 16], c: &[u8]) -> Result<Vec<u8>, Error> {
25        let key = SizedKey::try_from_slice(key)?;
26        let kio = KeyUnwrapIo::try_from_input(c)?;
27        let unwrapped = aes::unwrap_key(&key, None, kio)?;
28        Ok(unwrapped)
29    }
30}
31
32// TODO: Move some of these tests into the `rsn::aes` module.
33#[cfg(test)]
34mod tests {
35    use super::*;
36    use hex::FromHex;
37
38    fn test_wrap_unwrap<T: AsRef<[u8]>>(kek_hex: T, data_hex: T, expected_hex: T) {
39        let kek = Vec::from_hex(kek_hex).unwrap();
40        let data = Vec::from_hex(data_hex).unwrap();
41        let keywrap = NistAes;
42        let result = keywrap.wrap_key(&kek[..], &[0u8; 16], &data[..]);
43        assert_eq!(result.is_ok(), true);
44        let expected = Vec::from_hex(expected_hex).unwrap();
45        assert_eq!(result.unwrap(), expected);
46        let plain = keywrap.unwrap_key(&kek[..], &[0u8; 16], &expected[..]);
47        assert_eq!(plain.is_ok(), true);
48        assert_eq!(data, plain.unwrap());
49    }
50
51    // RFC 3394, 4.1 Wrap 128 bits of Key Data with a 128-bit KEK
52    #[test]
53    fn test_128_data_128_kek() {
54        test_wrap_unwrap(
55            "000102030405060708090A0B0C0D0E0F",
56            "00112233445566778899AABBCCDDEEFF",
57            "1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5",
58        );
59    }
60
61    // RFC 3394, 4.2 Wrap 128 bits of Key Data with a 192-bit KEK
62    #[test]
63    fn test_128_data_192_kek() {
64        test_wrap_unwrap(
65            "000102030405060708090A0B0C0D0E0F1011121314151617",
66            "00112233445566778899AABBCCDDEEFF",
67            "96778B25AE6CA435F92B5B97C050AED2468AB8A17AD84E5D",
68        );
69    }
70
71    // RFC 3394, 4.3 Wrap 128 bits of Key Data with a 256-bit KEK
72    #[test]
73    fn test_128_data_256_kek() {
74        test_wrap_unwrap(
75            "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F",
76            "00112233445566778899AABBCCDDEEFF",
77            "64E8C3F9CE0F5BA263E9777905818A2A93C8191E7D6E8AE7",
78        );
79    }
80    // RFC 3394, 4.4 Wrap 192 bits of Key Data with a 192-bit KEK
81    #[test]
82    fn test_192_data_192_kek() {
83        test_wrap_unwrap(
84            "000102030405060708090A0B0C0D0E0F1011121314151617",
85            "00112233445566778899AABBCCDDEEFF0001020304050607",
86            "031D33264E15D33268F24EC260743EDCE1C6C7DDEE725A936BA814915C6762D2",
87        );
88    }
89
90    // RFC 3394, 4.5 Wrap 192 bits of Key Data with a 256-bit KEK
91    #[test]
92    fn test_192_data_256_kek() {
93        test_wrap_unwrap(
94            "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F",
95            "00112233445566778899AABBCCDDEEFF0001020304050607",
96            "A8F9BC1612C68B3FF6E6F4FBE30E71E4769C8B80A32CB8958CD5D17D6B254DA1",
97        );
98    }
99
100    // RFC 3394, 4.6 Wrap 256 bits of Key Data with a 256-bit KEK
101    #[test]
102    fn test_256_data_256_kek() {
103        test_wrap_unwrap(
104            "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F",
105            "00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F",
106            "28C9F404C4B810F4CBCCB35CFB87F8263F5786E2D80ED326CBC7F0E71A99F43BFB988B9B7A02DD21",
107        );
108    }
109
110    #[test]
111    fn test_invalid_key_length() {
112        let kek = Vec::from_hex("0102030405060708090A0B0C0D0E0F").unwrap(); // 240bit
113        let data = Vec::from_hex("00112233445566778899AABBCCDDEEFF").unwrap();
114        let keywrap = NistAes;
115        let result = keywrap.wrap_key(&kek[..], &[0; 16], &data[..]);
116        assert_eq!(result.is_err(), true);
117        let plain = keywrap.unwrap_key(&kek[..], &[0; 16], &data[..]);
118        assert_eq!(plain.is_err(), true);
119    }
120
121    #[test]
122    fn test_invalid_data_length() {
123        let kek = Vec::from_hex("000102030405060708090A0B0C0D0E0F").unwrap();
124        let data =
125            Vec::from_hex("012345678912345601234567891234560123456789123456012345678912345614")
126                .unwrap();
127        let keywrap = NistAes;
128        let result = keywrap.wrap_key(&kek[..], &[0; 16], &data[..]);
129        assert_eq!(result.is_err(), true);
130        let plain = keywrap.unwrap_key(&kek[..], &[0; 16], &data[..]);
131        assert_eq!(plain.is_err(), true);
132    }
133
134    #[test]
135    fn test_unwrap_wrong_key() {
136        let mut kek = Vec::from_hex("000102030405060708090A0B0C0D0E0F").unwrap();
137        let data = Vec::from_hex("00112233445566778899AABBCCDDEEFF").unwrap();
138        let keywrap = NistAes;
139        let result = keywrap.wrap_key(&kek[..], &[0; 16], &data[..]);
140        assert_eq!(result.is_ok(), true);
141        kek[0] = 0xFF;
142        let plain = keywrap.unwrap_key(&kek[..], &[0; 16], &data[..]);
143        assert_eq!(plain.is_err(), true);
144    }
145
146    #[test]
147    fn test_too_short_data() {
148        let kek = Vec::from_hex("000102030405060708090A0B0C0D0E0F").unwrap();
149        let data = Vec::from_hex("0011223344556677").unwrap();
150        let keywrap = NistAes;
151        let result = keywrap.wrap_key(&kek[..], &[0; 16], &data[..]);
152        assert_eq!(result.is_err(), true);
153        let plain = keywrap.unwrap_key(&kek[..], &[0; 16], &data[..]);
154        assert_eq!(plain.is_err(), true);
155    }
156
157    #[test]
158    fn test_iv_unused() {
159        let kek = Vec::from_hex("000102030405060708090A0B0C0D0E0F").unwrap();
160        let data = Vec::from_hex("00112233445566778899AABBCCDDEEFF").unwrap();
161        let iv = [0xab; 16];
162        let keywrap = NistAes;
163        let result = keywrap.wrap_key(&kek[..], &iv, &data[..]);
164        assert_eq!(result.is_ok(), true);
165        let expected = Vec::from_hex("1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5").unwrap();
166        assert_eq!(result.unwrap(), expected);
167        let plain = keywrap.unwrap_key(&kek[..], &iv, &expected[..]);
168        assert_eq!(plain.is_ok(), true);
169        assert_eq!(data, plain.unwrap());
170    }
171}