2 * Copyright (c) 2004 Sam Leffler, Errno Consulting
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * Alternatively, this software may be distributed under the terms of the
17 * GNU General Public License ("GPL") version 2 as published by the Free
18 * Software Foundation.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 * Test vectors come from section I.7.4 of P802.11i/D7.0, October 2003.
39 * To use this tester load the net80211 layer (either as a module or
40 * by statically configuring it into your kernel), then kldload this
41 * module. It should automatically run all test cases and print
42 * information for each. To run one or more tests you can specify a
43 * tests parameter to the module that is a bit mask of the set of tests
44 * you want; e.g. insmod ccmp_test tests=7 will run only test mpdu's
47 #include <sys/param.h>
48 #include <sys/kernel.h>
49 #include <sys/systm.h>
51 #include <sys/module.h>
53 #include <sys/socket.h>
56 #include <net/if_var.h>
57 #include <net/if_media.h>
59 #include <net80211/ieee80211_var.h>
62 ==== CCMP test mpdu 1 ====
67 8 Type = 2 SubType = 0 Data
69 10 MoreFrag = 0 Retry = 1
70 11 PwrMgt = 0 moreData = 0
74 15 A1 = 0f-d2-e1-28-a5-7c DA
75 16 A2 = 50-30-f1-84-44-08 SA
76 17 A3 = ab-ae-a5-b8-fc-ba BSSID
78 19 seqNum = 824 (0x0338) fraqNum = 0 (0x00)
79 20 Algorithm = AES_CCM
81 22 TK = c9 7c 1f 67 ce 37 11 85 51 4a 8a 19 f2 bd d5 2f
82 23 PN = 199027030681356 (0xB5039776E70C)
83 24 802.11 Header = 08 48 c3 2c 0f d2 e1 28 a5 7c 50 30 f1 84 44 08
84 25 ab ae a5 b8 fc ba 80 33
85 26 Muted 802.11 Header = 08 40 0f d2 e1 28 a5 7c 50 30 f1 84 44 08
86 27 ab ae a5 b8 fc ba 00 00
87 28 CCMP Header = 0c e7 00 20 76 97 03 b5
88 29 CCM Nonce = 00 50 30 f1 84 44 08 b5 03 97 76 e7 0c
89 30 Plaintext Data = f8 ba 1a 55 d0 2f 85 ae 96 7b b6 2f b6 cd a8 eb
91 2 CCM MIC = 78 45 ce 0b 16 f9 76 23
92 3 -- Encrypted MPDU with FCS
93 4 08 48 c3 2c 0f d2 e1 28 a5 7c 50 30 f1 84 44 08 ab ae a5 b8 fc ba
94 5 80 33 0c e7 00 20 76 97 03 b5 f3 d0 a2 fe 9a 3d bf 23 42 a6 43 e4
95 6 32 46 e8 0c 3c 04 d0 19 78 45 ce 0b 16 f9 76 23 1d 99 f0 66
97 static const u_int8_t test1_key[] = { /* TK */
98 0xc9, 0x7c, 0x1f, 0x67, 0xce, 0x37, 0x11, 0x85, 0x51, 0x4a, 0x8a,
99 0x19, 0xf2, 0xbd, 0xd5, 0x2f
101 static const u_int8_t test1_plaintext[] = { /* Plaintext MPDU w/o MIC */
102 0x08, 0x48, 0xc3, 0x2c, 0x0f, 0xd2, 0xe1, 0x28, /* 802.11 Header */
103 0xa5, 0x7c, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08,
104 0xab, 0xae, 0xa5, 0xb8, 0xfc, 0xba, 0x80, 0x33,
105 0xf8, 0xba, 0x1a, 0x55, 0xd0, 0x2f, 0x85, 0xae, /* Plaintext Data */
106 0x96, 0x7b, 0xb6, 0x2f, 0xb6, 0xcd, 0xa8, 0xeb,
107 0x7e, 0x78, 0xa0, 0x50,
109 static const u_int8_t test1_encrypted[] = { /* Encrypted MPDU with MIC */
110 0x08, 0x48, 0xc3, 0x2c, 0x0f, 0xd2, 0xe1, 0x28,
111 0xa5, 0x7c, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08,
112 0xab, 0xae, 0xa5, 0xb8, 0xfc, 0xba, 0x80, 0x33,
113 0x0c, 0xe7, 0x00, 0x20, 0x76, 0x97, 0x03, 0xb5,
114 0xf3, 0xd0, 0xa2, 0xfe, 0x9a, 0x3d, 0xbf, 0x23,
115 0x42, 0xa6, 0x43, 0xe4, 0x32, 0x46, 0xe8, 0x0c,
116 0x3c, 0x04, 0xd0, 0x19, 0x78, 0x45, 0xce, 0x0b,
117 0x16, 0xf9, 0x76, 0x23,
121 ==== CCMP test mpdu 2 ====
126 10 Type = 2 SubType = 3 Data+CF-Ack+CF-Poll
127 11 ToDS = 0 FromDS = 0
128 12 MoreFrag = 0 Retry = 0
129 13 PwrMgt = 0 moreData = 0
133 17 A1 = ea-10-0c-84-68-50 DA
134 18 A2 = ee-c1-76-2c-88-de SA
135 19 A3 = af-2e-e9-f4-6a-07 BSSID
137 21 seqNum = 3278 (0x0CCE) fraqNum = 0 (0x00)
138 22 Algorithm = AES_CCM
140 24 TK = 8f 7a 05 3f a5 77 a5 59 75 29 27 20 97 a6 03 d5
141 25 PN = 54923164817386 (0x31F3CBBA97EA)
142 26 802.11 Header = 38 c0 6a 51 ea 10 0c 84 68 50 ee c1 76 2c 88 de
143 27 af 2e e9 f4 6a 07 e0 cc
144 28 Muted 802.11 Header = 08 c0 ea 10 0c 84 68 50 ee c1 76 2c 88 de
145 29 af 2e e9 f4 6a 07 00 00
146 30 CCMP Header = ea 97 00 a0 ba cb f3 31
147 31 CCM Nonce = 00 ee c1 76 2c 88 de 31 f3 cb ba 97 ea
148 32 Plaintext Data = 83 a0 63 4b 5e d7 62 7e b9 df 22 5e 05 74 03 42
150 34 CCM MIC = 54 2f bf 8d a0 6a a4 ae
151 35 -- Encrypted MPDU with FCS
152 36 38 c0 6a 51 ea 10 0c 84 68 50 ee c1 76 2c 88 de af 2e e9 f4 6a 07
153 37 e0 cc ea 97 00 a0 ba cb f3 31 81 4b 69 65 d0 5b f2 b2 ed 38 d4 be
154 38 b0 69 fe 82 71 4a 61 0b 54 2f bf 8d a0 6a a4 ae 25 3c 47 38
156 static const u_int8_t test2_key[] = { /* TK */
157 0x8f, 0x7a, 0x05, 0x3f, 0xa5, 0x77, 0xa5, 0x59, 0x75, 0x29, 0x27,
158 0x20, 0x97, 0xa6, 0x03, 0xd5
160 static const u_int8_t test2_plaintext[] = { /* Plaintext MPDU w/o MIC */
161 0x38, 0xc0, 0x6a, 0x51, 0xea, 0x10, 0x0c, 0x84, 0x68, 0x50, 0xee,
162 0xc1, 0x76, 0x2c, 0x88, 0xde, 0xaf, 0x2e, 0xe9, 0xf4, 0x6a, 0x07,
164 0x83, 0xa0, 0x63, 0x4b, 0x5e, 0xd7, 0x62, 0x7e, 0xb9, 0xdf, 0x22,
165 0x5e, 0x05, 0x74, 0x03, 0x42, 0xde, 0x19, 0x41, 0x17
167 static const u_int8_t test2_encrypted[] = { /* Encrypted MPDU with MIC */
168 0x38, 0xc0, 0x6a, 0x51, 0xea, 0x10, 0x0c, 0x84, 0x68, 0x50, 0xee,
169 0xc1, 0x76, 0x2c, 0x88, 0xde, 0xaf, 0x2e, 0xe9, 0xf4, 0x6a, 0x07,
170 0xe0, 0xcc, 0xea, 0x97, 0x00, 0xa0, 0xba, 0xcb, 0xf3, 0x31, 0x81,
171 0x4b, 0x69, 0x65, 0xd0, 0x5b, 0xf2, 0xb2, 0xed, 0x38, 0xd4, 0xbe,
172 0xb0, 0x69, 0xfe, 0x82, 0x71, 0x4a, 0x61, 0x0b, 0x54, 0x2f, 0xbf,
173 0x8d, 0xa0, 0x6a, 0xa4, 0xae,
177 ==== CCMP test mpdu 3 ====
182 42 Type = 2 SubType = 11
183 43 ToDS = 0 FromDS = 0
184 44 MoreFrag = 0 Retry = 1
185 45 PwrMgt = 0 moreData = 0
189 49 A1 = d9-57-7d-f7-63-c8 DA
190 50 A2 = b6-a8-8a-df-36-91 SA
191 1 A3 = dc-4a-8b-ca-94-dd BSSID
193 3 seqNum = 2086 (0x0826) fraqNum = 0 (0x00)
195 5 MSDU Priority = 0 (0x0)
196 6 Algorithm = AES_CCM
198 8 TK = 40 cf b7 a6 2e 88 01 3b d6 d3 af fc c1 91 04 1e
199 9 PN = 52624639632814 (0x2FDCA0F3A5AE)
200 10 802.11 Header = b8 c8 dc 61 d9 57 7d f7 63 c8 b6 a8 8a df 36 91
201 11 dc 4a 8b ca 94 dd 60 82 20 85
202 12 Muted 802.11 Header = 88 c0 d9 57 7d f7 63 c8 b6 a8 8a df 36 91
203 13 dc 4a 8b ca 94 dd 00 00 00 00
204 14 CCMP Header = ae a5 00 a0 f3 a0 dc 2f
205 15 CCM Nonce = 00 b6 a8 8a df 36 91 2f dc a0 f3 a5 ae
206 16 Plaintext Data = 2c 1b d0 36 83 1c 95 49 6c 5f 4d bf 3d 55 9e 72
208 18 CCM MIC = fd 1f 1f 61 a9 fb 4b b3
209 19 -- Encrypted MPDU with FCS
210 20 b8 c8 dc 61 d9 57 7d f7 63 c8 b6 a8 8a df 36 91 dc 4a 8b ca 94 dd
211 21 60 82 20 85 ae a5 00 a0 f3 a0 dc 2f 89 d8 58 03 40 b6 26 a0 b6 d4
212 22 d0 13 bf 18 f2 91 b8 96 46 c8 fd 1f 1f 61 a9 fb 4b b3 60 3f 5a ad
214 static const u_int8_t test3_key[] = { /* TK */
215 0x40, 0xcf, 0xb7, 0xa6, 0x2e, 0x88, 0x01, 0x3b, 0xd6, 0xd3,
216 0xaf, 0xfc, 0xc1, 0x91, 0x04, 0x1e
218 static const u_int8_t test3_plaintext[] = { /* Plaintext MPDU w/o MIC */
219 0xb8, 0xc8, 0xdc, 0x61, 0xd9, 0x57, 0x7d, 0xf7, 0x63, 0xc8,
220 0xb6, 0xa8, 0x8a, 0xdf, 0x36, 0x91, 0xdc, 0x4a, 0x8b, 0xca,
221 0x94, 0xdd, 0x60, 0x82, 0x20, 0x85,
222 0x2c, 0x1b, 0xd0, 0x36, 0x83, 0x1c, 0x95, 0x49, 0x6c, 0x5f,
223 0x4d, 0xbf, 0x3d, 0x55, 0x9e, 0x72, 0xde, 0x80, 0x2a, 0x18
225 static const u_int8_t test3_encrypted[] = { /* Encrypted MPDU with MIC */
226 0xb8, 0xc8, 0xdc, 0x61, 0xd9, 0x57, 0x7d, 0xf7, 0x63, 0xc8,
227 0xb6, 0xa8, 0x8a, 0xdf, 0x36, 0x91, 0xdc, 0x4a, 0x8b, 0xca,
228 0x94, 0xdd, 0x60, 0x82, 0x20, 0x85, 0xae, 0xa5, 0x00, 0xa0,
229 0xf3, 0xa0, 0xdc, 0x2f, 0x89, 0xd8, 0x58, 0x03, 0x40, 0xb6,
230 0x26, 0xa0, 0xb6, 0xd4, 0xd0, 0x13, 0xbf, 0x18, 0xf2, 0x91,
231 0xb8, 0x96, 0x46, 0xc8, 0xfd, 0x1f, 0x1f, 0x61, 0xa9, 0xfb,
236 ==== CCMP test mpdu 4 ====
240 26 Type = 2 SubType = 10
241 27 ToDS = 0 FromDS = 1
242 28 MoreFrag = 0 Retry = 1
243 29 PwrMgt = 0 moreData = 0
247 33 A1 = 71-2a-9d-df-11-db DA
248 34 A2 = 8e-f8-22-73-47-01 BSSID
249 35 A3 = 59-14-0d-d6-46-a2 SA
251 37 seqNum = 764 (0x02FC) fraqNum = 0 (0x00)
253 39 MSDU Priority = 7 (0x0)
254 40 Algorithm = AES_CCM
256 42 TK = 8c 89 a2 eb c9 6c 76 02 70 7f cf 24 b3 2d 38 33
257 43 PN = 270963670912995 (0xF670A55A0FE3)
258 44 802.11 Header = a8 ca 3a 11 71 2a 9d df 11 db 8e f8 22 73 47 01
259 45 59 14 0d d6 46 a2 c0 2f 67 a5
260 46 Muted 802.11 Header = 88 c2 71 2a 9d df 11 db 8e f8 22 73 47 01
261 47 59 14 0d d6 46 a2 00 00 07 00
262 48 CCMP Header = e3 0f 00 20 5a a5 70 f6
263 49 CCM Nonce = 07 8e f8 22 73 47 01 f6 70 a5 5a 0f e3
264 50 Plaintext Data = 4f ad 2b 1c 29 0f a5 eb d8 72 fb c3 f3 a0 74 89
266 52 CCM MIC = 31 fc 88 00 4f 35 ee 3d
267 -- Encrypted MPDU with FCS
268 2 a8 ca 3a 11 71 2a 9d df 11 db 8e f8 22 73 47 01 59 14 0d d6 46 a2
269 3 c0 2f 67 a5 e3 0f 00 20 5a a5 70 f6 9d 59 b1 5f 37 14 48 c2 30 f4
270 4 d7 39 05 2e 13 ab 3b 1a 7b 10 31 fc 88 00 4f 35 ee 3d 45 a7 4a 30
272 static const u_int8_t test4_key[] = { /* TK */
273 0x8c, 0x89, 0xa2, 0xeb, 0xc9, 0x6c, 0x76, 0x02,
274 0x70, 0x7f, 0xcf, 0x24, 0xb3, 0x2d, 0x38, 0x33,
276 static const u_int8_t test4_plaintext[] = { /* Plaintext MPDU w/o MIC */
277 0xa8, 0xca, 0x3a, 0x11, 0x71, 0x2a, 0x9d, 0xdf, 0x11, 0xdb,
278 0x8e, 0xf8, 0x22, 0x73, 0x47, 0x01, 0x59, 0x14, 0x0d, 0xd6,
279 0x46, 0xa2, 0xc0, 0x2f, 0x67, 0xa5,
280 0x4f, 0xad, 0x2b, 0x1c, 0x29, 0x0f, 0xa5, 0xeb, 0xd8, 0x72,
281 0xfb, 0xc3, 0xf3, 0xa0, 0x74, 0x89, 0x8f, 0x8b, 0x2f, 0xbb,
283 static const u_int8_t test4_encrypted[] = { /* Encrypted MPDU with MIC */
284 0xa8, 0xca, 0x3a, 0x11, 0x71, 0x2a, 0x9d, 0xdf, 0x11, 0xdb,
285 0x8e, 0xf8, 0x22, 0x73, 0x47, 0x01, 0x59, 0x14, 0x0d, 0xd6,
286 0x46, 0xa2, 0xc0, 0x2f, 0x67, 0xa5, 0xe3, 0x0f, 0x00, 0x20,
287 0x5a, 0xa5, 0x70, 0xf6, 0x9d, 0x59, 0xb1, 0x5f, 0x37, 0x14,
288 0x48, 0xc2, 0x30, 0xf4, 0xd7, 0x39, 0x05, 0x2e, 0x13, 0xab,
289 0x3b, 0x1a, 0x7b, 0x10, 0x31, 0xfc, 0x88, 0x00, 0x4f, 0x35,
294 ==== CCMP test mpdu 5 ====
299 8 Type = 2 SubType = 8
300 9 ToDS = 0 FromDS = 1
301 10 MoreFrag = 0 Retry = 1
302 11 PwrMgt = 1 moreData = 0
306 15 A1 = 45-de-c6-9a-74-80 DA
307 16 A2 = f3-51-94-6b-c9-6b BSSID
308 17 A3 = e2-76-fb-e6-c1-27 SA
310 19 seqNum = 3880 (0x0F28) fraqNum = 0 (0x00)
312 21 MSDU Priority = 0 (0x0)
313 22 Algorithm = AES_CCM
315 24 TK = a5 74 d5 14 3b b2 5e fd de ff 30 12 2f df d0 66
316 25 PN = 184717420531255 (0xA7FFE03C0E37)
317 26 802.11 Header = 88 da 18 41 45 de c6 9a 74 80 f3 51 94 6b c9 6b
318 27 e2 76 fb e6 c1 27 80 f2 4b 19
319 28 Muted 802.11 Header = 88 c2 45 de c6 9a 74 80 f3 51 94 6b c9 6b
320 29 e2 76 fb e6 c1 27 00 00 0b 00
321 30 CCMP Header = 37 0e 00 a0 3c e0 ff a7
322 31 CCM Nonce = 0b f3 51 94 6b c9 6b a7 ff e0 3c 0e 37
323 32 Plaintext Data = 28 96 9b 95 4f 26 3a 80 18 a9 ef 70 a8 b0 51 46
325 34 CCM MIC = ce 0c 3b e1 97 d3 05 eb
326 35 -- Encrypted MPDU with FCS
327 36 88 da 18 41 45 de c6 9a 74 80 f3 51 94 6b c9 6b e2 76 fb e6 c1 27
328 37 80 f2 4b 19 37 0e 00 a0 3c e0 ff a7 eb 4a e4 95 6a 80 1d a9 62 4b
329 38 7e 0c 18 b2 3e 61 5e c0 3a f6 ce 0c 3b e1 97 d3 05 eb c8 9e a1 b5
331 static const u_int8_t test5_key[] = { /* TK */
332 0xa5, 0x74, 0xd5, 0x14, 0x3b, 0xb2, 0x5e, 0xfd,
333 0xde, 0xff, 0x30, 0x12, 0x2f, 0xdf, 0xd0, 0x66,
335 static const u_int8_t test5_plaintext[] = { /* Plaintext MPDU w/o MIC */
336 0x88, 0xda, 0x18, 0x41, 0x45, 0xde, 0xc6, 0x9a, 0x74, 0x80,
337 0xf3, 0x51, 0x94, 0x6b, 0xc9, 0x6b, 0xe2, 0x76, 0xfb, 0xe6,
338 0xc1, 0x27, 0x80, 0xf2, 0x4b, 0x19,
339 0x28, 0x96, 0x9b, 0x95, 0x4f, 0x26, 0x3a, 0x80, 0x18, 0xa9,
340 0xef, 0x70, 0xa8, 0xb0, 0x51, 0x46, 0x24, 0x81, 0x92, 0x2e,
342 static const u_int8_t test5_encrypted[] = { /* Encrypted MPDU with MIC */
343 0x88, 0xda, 0x18, 0x41, 0x45, 0xde, 0xc6, 0x9a, 0x74, 0x80,
344 0xf3, 0x51, 0x94, 0x6b, 0xc9, 0x6b, 0xe2, 0x76, 0xfb, 0xe6,
345 0xc1, 0x27, 0x80, 0xf2, 0x4b, 0x19, 0x37, 0x0e, 0x00, 0xa0,
346 0x3c, 0xe0, 0xff, 0xa7, 0xeb, 0x4a, 0xe4, 0x95, 0x6a, 0x80,
347 0x1d, 0xa9, 0x62, 0x4b, 0x7e, 0x0c, 0x18, 0xb2, 0x3e, 0x61,
348 0x5e, 0xc0, 0x3a, 0xf6, 0xce, 0x0c, 0x3b, 0xe1, 0x97, 0xd3,
353 ==== CCMP test mpdu 6 ====
358 42 Type = 2 SubType = 8
359 43 ToDS = 0 FromDS = 1
360 44 MoreFrag = 0 Retry = 0
361 45 PwrMgt = 1 moreData = 0
365 49 A1 = 5a-f2-84-30-fd-ab DA
366 50 A2 = bf-f9-43-b9-f9-a6 BSSID
367 1 A3 = ab-1d-98-c7-fe-73 SA
369 3 seqNum = 1813 (0x0715) fraqNum = 0 (0x00)
371 5 PSDU Priority = 13 (0xd)
372 6 Algorithm = AES_CCM
374 8 TK = f7 1e ea 4e 1f 58 80 4b 97 17 23 0a d0 61 46 41
375 9 PN = 118205765159305 (0x6B81ECA48989)
376 10 802.11 Header = 88 52 e1 1f 5a f2 84 30 fd ab bf f9 43 b9 f9 a6
377 11 ab 1d 98 c7 fe 73 50 71 3d 6a
378 12 Muted 802.11 Header = 88 42 5a f2 84 30 fd ab bf f9 43 b9 f9 a6
379 13 ab 1d 98 c7 fe 73 00 00 0d 00
380 14 CCMP Header = 89 89 00 60 a4 ec 81 6b
381 15 CCM Nonce = 0d bf f9 43 b9 f9 a6 6b 81 ec a4 89 89
382 16 Plaintext Data = ab fd a2 2d 3a 0b fc 9c c1 fc 07 93 63 c2 fc a1
384 18 CCM MIC = 30 9a 8d 5c 46 6b bb 71
385 19 -- Encrypted MPDU with FCS
386 20 88 52 e1 1f 5a f2 84 30 fd ab bf f9 43 b9 f9 a6 ab 1d 98 c7 fe 73
387 21 50 71 3d 6a 89 89 00 60 a4 ec 81 6b 9a 70 9b 60 a3 9d 40 b1 df b6
388 22 12 e1 8b 5f 11 4b ad b6 cc 86 30 9a 8d 5c 46 6b bb 71 86 c0 4e 97
390 static const u_int8_t test6_key[] = { /* TK */
391 0xf7, 0x1e, 0xea, 0x4e, 0x1f, 0x58, 0x80, 0x4b,
392 0x97, 0x17, 0x23, 0x0a, 0xd0, 0x61, 0x46, 0x41,
394 static const u_int8_t test6_plaintext[] = { /* Plaintext MPDU w/o MIC */
395 0x88, 0x52, 0xe1, 0x1f, 0x5a, 0xf2, 0x84, 0x30, 0xfd, 0xab,
396 0xbf, 0xf9, 0x43, 0xb9, 0xf9, 0xa6, 0xab, 0x1d, 0x98, 0xc7,
397 0xfe, 0x73, 0x50, 0x71, 0x3d, 0x6a,
398 0xab, 0xfd, 0xa2, 0x2d, 0x3a, 0x0b, 0xfc, 0x9c, 0xc1, 0xfc,
399 0x07, 0x93, 0x63, 0xc2, 0xfc, 0xa1, 0x43, 0xe6, 0xeb, 0x1d,
401 static const u_int8_t test6_encrypted[] = { /* Encrypted MPDU with MIC */
402 0x88, 0x52, 0xe1, 0x1f, 0x5a, 0xf2, 0x84, 0x30, 0xfd, 0xab,
403 0xbf, 0xf9, 0x43, 0xb9, 0xf9, 0xa6, 0xab, 0x1d, 0x98, 0xc7,
404 0xfe, 0x73, 0x50, 0x71, 0x3d, 0x6a, 0x89, 0x89, 0x00, 0x60,
405 0xa4, 0xec, 0x81, 0x6b, 0x9a, 0x70, 0x9b, 0x60, 0xa3, 0x9d,
406 0x40, 0xb1, 0xdf, 0xb6, 0x12, 0xe1, 0x8b, 0x5f, 0x11, 0x4b,
407 0xad, 0xb6, 0xcc, 0x86, 0x30, 0x9a, 0x8d, 0x5c, 0x46, 0x6b,
412 ==== CCMP test mpdu 7 ====
417 26 Type = 2 SubType = 1 Data+CF-Ack
418 27 ToDS = 1 FromDS = 0
419 28 MoreFrag = 0 Retry = 1
420 29 PwrMgt = 1 moreData = 1
424 33 A1 = 9b-50-f4-fd-56-f6 BSSID
425 34 A2 = ef-ec-95-20-16-91 SA
426 35 A3 = 83-57-0c-4c-cd-ee DA
428 37 seqNum = 2562 (0x0A02) fraqNum = 0 (0x00)
429 38 Algorithm = AES_CCM
431 40 TK = 1b db 34 98 0e 03 81 24 a1 db 1a 89 2b ec 36 6a
432 41 PN = 104368786630435 (0x5EEC4073E723)
433 42 Header = 18 79 81 46 9b 50 f4 fd 56 f6 ef ec 95 20 16 91 83 57
435 44 Muted MAC Header = 08 41 9b 50 f4 fd 56 f6 ef ec 95 20 16 91
436 45 83 57 0c 4c cd ee 00 00
437 46 CCMP Header = 23 e7 00 e0 73 40 ec 5e
438 47 CCM Nonce = 00 ef ec 95 20 16 91 5e ec 40 73 e7 23
439 48 Plaintext Data = 98 be ca 86 f4 b3 8d a2 0c fd f2 47 24 c5 8e b8
441 50 CCM MIC = 2d 09 57 ec fa be 95 b9
442 -- Encrypted MPDU with FCS
443 1 18 79 81 46 9b 50 f4 fd 56 f6 ef ec 95 20 16 91 83 57 0c 4c cd ee
444 2 20 a0 23 e7 00 e0 73 40 ec 5e 12 c5 37 eb f3 ab 58 4e f1 fe f9 a1
445 3 f3 54 7a 8c 13 b3 22 5a 2d 09 57 ec fa be 95 b9 aa fa 0c c8
447 static const u_int8_t test7_key[] = { /* TK */
448 0x1b, 0xdb, 0x34, 0x98, 0x0e, 0x03, 0x81, 0x24,
449 0xa1, 0xdb, 0x1a, 0x89, 0x2b, 0xec, 0x36, 0x6a,
451 static const u_int8_t test7_plaintext[] = { /* Plaintext MPDU w/o MIC */
452 0x18, 0x79, 0x81, 0x46, 0x9b, 0x50, 0xf4, 0xfd, 0x56, 0xf6,
453 0xef, 0xec, 0x95, 0x20, 0x16, 0x91, 0x83, 0x57, 0x0c, 0x4c,
454 0xcd, 0xee, 0x20, 0xa0,
455 0x98, 0xbe, 0xca, 0x86, 0xf4, 0xb3, 0x8d, 0xa2, 0x0c, 0xfd,
456 0xf2, 0x47, 0x24, 0xc5, 0x8e, 0xb8, 0x35, 0x66, 0x53, 0x39,
458 static const u_int8_t test7_encrypted[] = { /* Encrypted MPDU with MIC */
459 0x18, 0x79, 0x81, 0x46, 0x9b, 0x50, 0xf4, 0xfd, 0x56, 0xf6,
460 0xef, 0xec, 0x95, 0x20, 0x16, 0x91, 0x83, 0x57, 0x0c, 0x4c,
461 0xcd, 0xee, 0x20, 0xa0, 0x23, 0xe7, 0x00, 0xe0, 0x73, 0x40,
462 0xec, 0x5e, 0x12, 0xc5, 0x37, 0xeb, 0xf3, 0xab, 0x58, 0x4e,
463 0xf1, 0xfe, 0xf9, 0xa1, 0xf3, 0x54, 0x7a, 0x8c, 0x13, 0xb3,
464 0x22, 0x5a, 0x2d, 0x09, 0x57, 0xec, 0xfa, 0xbe, 0x95, 0xb9,
468 ==== CCMP test mpdu 8 ====
473 7 Type = 2 SubType = 11
474 8 ToDS = 1 FromDS = 0
475 9 MoreFrag = 0 Retry = 1
476 10 PwrMgt = 1 moreData = 0
480 14 A1 = 55-2d-5f-72-bb-70 BSSID
481 15 A2 = ca-3f-3a-ae-60-c4 SA
482 16 A3 = 8b-a9-b5-f8-2c-2f DA
484 18 seqNum = 3765 (0x0EB5) fraqNum = 0 (0x00)
486 20 MSDU Priority = 10 (0xa)
487 21 Algorithm = AES_CCM
489 23 TK = 6e ac 1b f5 4b d5 4e db 23 21 75 43 03 02 4c 71
490 24 PN = 227588596223197 (0xCEFD996ECCDD)
491 25 802.11 Header = b8 d9 4c 72 55 2d 5f 72 bb 70 ca 3f 3a ae 60 c4
492 26 8b a9 b5 f8 2c 2f 50 eb 2a 55
493 27 Muted 802.11 Header = 88 c1 55 2d 5f 72 bb 70 ca 3f 3a ae 60 c4
494 28 8b a9 b5 f8 2c 2f 00 00 0a 00
495 29 CCMP Header = dd cc 00 a0 6e 99 fd ce
496 30 CCM Nonce = 0a ca 3f 3a ae 60 c4 ce fd 99 6e cc dd
497 31 Plaintext Data = 57 cb 5c 0e 5f cd 88 5e 9a 42 39 e9 b9 ca d6 0d
499 33 CCM MIC = 6d ba 8e f7 f0 80 87 dd
500 -- Encrypted MPDU with FCS
501 35 b8 d9 4c 72 55 2d 5f 72 bb 70 ca 3f 3a ae 60 c4 8b a9 b5 f8 2c 2f
502 36 50 eb 2a 55 dd cc 00 a0 6e 99 fd ce 4b f2 81 ef 8e c7 73 9f 91 59
503 37 1b 97 a8 7d c1 4b 3f a1 74 62 6d ba 8e f7 f0 80 87 dd 0c 65 74 3f
505 static const u_int8_t test8_key[] = { /* TK */
506 0x6e, 0xac, 0x1b, 0xf5, 0x4b, 0xd5, 0x4e, 0xdb,
507 0x23, 0x21, 0x75, 0x43, 0x03, 0x02, 0x4c, 0x71,
509 static const u_int8_t test8_plaintext[] = { /* Plaintext MPDU w/o MIC */
510 0xb8, 0xd9, 0x4c, 0x72, 0x55, 0x2d, 0x5f, 0x72, 0xbb, 0x70,
511 0xca, 0x3f, 0x3a, 0xae, 0x60, 0xc4, 0x8b, 0xa9, 0xb5, 0xf8,
512 0x2c, 0x2f, 0x50, 0xeb, 0x2a, 0x55,
513 0x57, 0xcb, 0x5c, 0x0e, 0x5f, 0xcd, 0x88, 0x5e, 0x9a, 0x42,
514 0x39, 0xe9, 0xb9, 0xca, 0xd6, 0x0d, 0x64, 0x37, 0x59, 0x79,
516 static const u_int8_t test8_encrypted[] = { /* Encrypted MPDU with MIC */
517 0xb8, 0xd9, 0x4c, 0x72, 0x55, 0x2d, 0x5f, 0x72, 0xbb, 0x70,
518 0xca, 0x3f, 0x3a, 0xae, 0x60, 0xc4, 0x8b, 0xa9, 0xb5, 0xf8,
519 0x2c, 0x2f, 0x50, 0xeb, 0x2a, 0x55, 0xdd, 0xcc, 0x00, 0xa0,
520 0x6e, 0x99, 0xfd, 0xce, 0x4b, 0xf2, 0x81, 0xef, 0x8e, 0xc7,
521 0x73, 0x9f, 0x91, 0x59, 0x1b, 0x97, 0xa8, 0x7d, 0xc1, 0x4b,
522 0x3f, 0xa1, 0x74, 0x62, 0x6d, 0xba, 0x8e, 0xf7, 0xf0, 0x80,
526 #define TEST(n,name,cipher,keyix,pn) { \
527 name, IEEE80211_CIPHER_##cipher,keyix, pn##LL, \
528 test##n##_key, sizeof(test##n##_key), \
529 test##n##_plaintext, sizeof(test##n##_plaintext), \
530 test##n##_encrypted, sizeof(test##n##_encrypted) \
540 const u_int8_t *plaintext;
541 size_t plaintext_len;
542 const u_int8_t *encrypted;
543 size_t encrypted_len;
545 TEST(1, "CCMP test mpdu 1", AES_CCM, 0, 199027030681356),
546 TEST(2, "CCMP test mpdu 2", AES_CCM, 2, 54923164817386),
547 TEST(3, "CCMP test mpdu 3", AES_CCM, 2, 52624639632814),
548 TEST(4, "CCMP test mpdu 4", AES_CCM, 0, 270963670912995),
549 TEST(5, "CCMP test mpdu 5", AES_CCM, 2, 184717420531255),
550 TEST(6, "CCMP test mpdu 6", AES_CCM, 1, 118205765159305),
551 TEST(7, "CCMP test mpdu 7", AES_CCM, 3, 104368786630435),
552 TEST(8, "CCMP test mpdu 8", AES_CCM, 2, 227588596223197),
556 dumpdata(const char *tag, const void *p, size_t len)
560 printf("%s: 0x%p len %u", tag, p, len);
561 for (i = 0; i < len; i++) {
563 printf("\n%03d:", i);
564 printf(" %02x", ((const u_int8_t *)p)[i]);
570 cmpfail(const void *gen, size_t genlen, const void *ref, size_t reflen)
574 for (i = 0; i < genlen; i++)
575 if (((const u_int8_t *)gen)[i] != ((const u_int8_t *)ref)[i]) {
576 printf("first difference at byte %u\n", i);
579 dumpdata("Generated", gen, genlen);
580 dumpdata("Reference", ref, reflen);
584 printtest(const struct ciphertest *t)
586 printf("keyix %u pn %llu key_len %u plaintext_len %u\n"
595 runtest(struct ieee80211vap *vap, struct ciphertest *t)
597 struct ieee80211_key *key = &vap->iv_nw_keys[t->keyix];
598 struct mbuf *m = NULL;
599 const struct ieee80211_cipher *cip;
602 printf("%s: ", t->name);
607 memset(key, 0, sizeof(*key));
608 key->wk_flags = IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV;
609 key->wk_cipher = &ieee80211_cipher_none;
610 if (!ieee80211_crypto_newkey(vap, t->cipher,
611 IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV, key)) {
612 printf("FAIL: ieee80211_crypto_newkey failed\n");
616 memcpy(key->wk_key, t->key, t->key_len);
617 key->wk_keylen = t->key_len;
618 memset(key->wk_keyrsc, 0, sizeof(key->wk_keyrsc));
619 key->wk_keytsc = t->pn-1; /* PN-1 since we do encap */
620 if (!ieee80211_crypto_setkey(vap, key)) {
621 printf("FAIL: ieee80211_crypto_setkey failed\n");
626 * Craft frame from plaintext data.
628 cip = key->wk_cipher;
629 m = m_getcl(M_NOWAIT, MT_HEADER, M_PKTHDR);
630 m->m_data += cip->ic_header;
631 memcpy(mtod(m, void *), t->plaintext, t->plaintext_len);
632 m->m_len = t->plaintext_len;
633 m->m_pkthdr.len = m->m_len;
634 hdrlen = ieee80211_anyhdrsize(mtod(m, void *));
637 * Encrypt frame w/ MIC.
639 if (!cip->ic_encap(key, m)) {
641 printf("FAIL: ccmp encap failed\n");
645 * Verify: frame length, frame contents.
647 if (m->m_pkthdr.len != t->encrypted_len) {
648 printf("FAIL: encap data length mismatch\n");
650 cmpfail(mtod(m, const void *), m->m_pkthdr.len,
651 t->encrypted, t->encrypted_len);
653 } else if (memcmp(mtod(m, const void *), t->encrypted, t->encrypted_len)) {
654 printf("FAIL: encrypt data does not compare\n");
656 cmpfail(mtod(m, const void *), m->m_pkthdr.len,
657 t->encrypted, t->encrypted_len);
658 dumpdata("Plaintext", t->plaintext, t->plaintext_len);
663 * Decrypt frame; strip MIC.
665 if (!cip->ic_decap(key, m, hdrlen)) {
666 printf("FAIL: ccmp decap failed\n");
668 cmpfail(mtod(m, const void *), m->m_len,
669 t->plaintext, t->plaintext_len);
673 * Verify: frame length, frame contents.
675 if (m->m_pkthdr.len != t->plaintext_len) {
676 printf("FAIL: decap botch; length mismatch\n");
678 cmpfail(mtod(m, const void *), m->m_pkthdr.len,
679 t->plaintext, t->plaintext_len);
681 } else if (memcmp(mtod(m, const void *), t->plaintext, t->plaintext_len)) {
682 printf("FAIL: decap botch; data does not compare\n");
684 cmpfail(mtod(m, const void *), m->m_pkthdr.len,
685 t->plaintext, t->plaintext_len);
689 ieee80211_crypto_delkey(vap, key);
695 ieee80211_crypto_delkey(vap, key);
703 static int tests = -1;
704 static int debug = 0;
707 init_crypto_ccmp_test(void)
709 struct ieee80211com ic;
710 struct ieee80211vap vap;
714 memset(&ic, 0, sizeof(ic));
715 memset(&vap, 0, sizeof(vap));
716 memset(&ifp, 0, sizeof(ifp));
718 ieee80211_crypto_attach(&ic);
720 /* some minimal initialization */
721 strncpy(ifp.if_xname, "test_ccmp", sizeof(ifp.if_xname));
725 vap.iv_debug = IEEE80211_MSG_CRYPTO;
726 ieee80211_crypto_vattach(&vap);
730 for (i = 0; i < nitems(ccmptests); i++)
731 if (tests & (1<<i)) {
733 pass += runtest(&vap, &ccmptests[i]);
735 printf("%u of %u 802.11i AES-CCMP test vectors passed\n", pass, total);
737 ieee80211_crypto_vdetach(&vap);
738 ieee80211_crypto_detach(&ic);
740 return (pass == total ? 0 : -1);
744 test_ccmp_modevent(module_t mod, int type, void *unused)
748 (void) init_crypto_ccmp_test();
756 static moduledata_t test_ccmp_mod = {
761 DECLARE_MODULE(test_ccmp, test_ccmp_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
762 MODULE_VERSION(test_ccmp, 1);
763 MODULE_DEPEND(test_ccmp, wlan, 1, 1, 1);