1 /*-
2  * Copyright (c) 2004 Sam Leffler, Errno Consulting
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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.
15  *
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.
19  *
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.
30  *
31  * $FreeBSD$
32  */
33 
34 /*
35  * CCMP test module.
36  *
37  * Test vectors come from section I.7.4 of P802.11i/D7.0, October 2003.
38  *
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
45  * 1, 2, and 3.
46  */
47 #include <sys/param.h>
48 #include <sys/kernel.h>
49 #include <sys/systm.h>
50 #include <sys/mbuf.h>
51 #include <sys/module.h>
52 
53 #include <sys/socket.h>
54 
55 #include <net/if.h>
56 #include <net/if_var.h>
57 #include <net/if_media.h>
58 
59 #include <net80211/ieee80211_var.h>
60 
61 /*
62 ==== CCMP test mpdu   1 ====
63 
64 -- MPDU Fields
65 
66 7  Version  = 0
67 8  Type     = 2   SubType  = 0  Data
68 9  ToDS     = 0   FromDS   = 0
69 10  MoreFrag = 0   Retry    = 1
70 11  PwrMgt   = 0   moreData = 0
71 12  Encrypt  = 1
72 13  Order    = 0
73 14  Duration = 11459
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
77 18  SC = 0x3380
78 19  seqNum = 824 (0x0338)  fraqNum = 0 (0x00)
79 20  Algorithm = AES_CCM
80 21  Key ID = 0
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
90 1	7e 78 a0 50
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
96 */
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
100 };
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,
108 };
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,
118 };
119 
120 /*
121 ==== CCMP test mpdu   2 ====
122 
123 -- MPDU Fields
124 
125  9  Version  = 0
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
130 14  Encrypt  = 1
131 15  Order    = 1
132 16  Duration = 20842
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
136 20  SC = 0xCCE0
137 21  seqNum = 3278 (0x0CCE)  fraqNum = 0 (0x00)
138 22  Algorithm = AES_CCM
139 23  Key ID = 2
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
149 33  	de 19 41 17
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
155 */
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
159 };
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,
163 	0xe0, 0xcc,
164 	0x83, 0xa0, 0x63, 0x4b, 0x5e, 0xd7, 0x62, 0x7e, 0xb9, 0xdf, 0x22,
165 	0x5e, 0x05, 0x74, 0x03, 0x42, 0xde, 0x19, 0x41, 0x17
166 };
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,
174 };
175 
176 /*
177 ==== CCMP test mpdu   3 ====
178 
179 -- MPDU Fields
180 
181 41  Version  = 0
182 42  Type     = 2   SubType  = 11
183 43  ToDS     = 0   FromDS   = 0
184 44  MoreFrag = 0   Retry    = 1
185 45  PwrMgt   = 0   moreData = 0
186 46  Encrypt  = 1
187 47  Order    = 1
188 48  Duration = 25052
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
192 2  SC = 0x8260
193 3  seqNum = 2086 (0x0826)  fraqNum = 0 (0x00)
194 4  QC = 0x0000
195 5  MSDU Priority = 0 (0x0)
196 6  Algorithm = AES_CCM
197 7  Key ID = 2
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
207 17  	de 80 2a 18
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
213 */
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
217 };
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
224 };
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,
232 	0x4b, 0xb3,
233 };
234 
235 /*
236 ==== CCMP test mpdu  4 ====
237 
238 -- MPDU Fields
239 25  Version  = 0
240 26  Type     = 2   SubType  = 10
241 27  ToDS     = 0   FromDS   = 1
242 28  MoreFrag = 0   Retry    = 1
243 29  PwrMgt   = 0   moreData = 0
244 30  Encrypt  = 1
245 31  Order    = 1
246 32  Duration = 4410
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
250 36  SC = 0x2FC0
251 37  seqNum = 764 (0x02FC)  fraqNum = 0 (0x00)
252 38  QC = 0x0007
253 39  MSDU Priority = 7 (0x0)
254 40  Algorithm = AES_CCM
255 41  Key ID = 0
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
265 51  	8f 8b 2f bb
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
271 */
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,
275 };
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,
282 };
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,
290 	0xee, 0x3d,
291 };
292 
293 /*
294 ==== CCMP test mpdu   5 ====
295 
296 -- MPDU Fields
297 
298 7  Version  = 0
299 8  Type     = 2   SubType  = 8
300 9  ToDS     = 0   FromDS   = 1
301 10  MoreFrag = 0   Retry    = 1
302 11  PwrMgt   = 1   moreData = 0
303 12  Encrypt  = 1
304 13  Order    = 1
305 14  Duration = 16664
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
309 18  SC = 0xF280
310 19  seqNum = 3880 (0x0F28)  fraqNum = 0 (0x00)
311 20  QC = 0x000b
312 21  MSDU Priority = 0 (0x0)
313 22  Algorithm = AES_CCM
314 23  Key ID = 2
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
324 33  	24 81 92 2e
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
330 */
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,
334 };
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,
341 };
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,
349 	0x05, 0xeb,
350 };
351 
352 /*
353 ==== CCMP test mpdu   6 ====
354 
355 -- MPDU Fields
356 
357 41  Version  = 0
358 42  Type     = 2   SubType  = 8
359 43  ToDS     = 0   FromDS   = 1
360 44  MoreFrag = 0   Retry    = 0
361 45  PwrMgt   = 1   moreData = 0
362 46  Encrypt  = 1
363 47  Order    = 0
364 48  Duration = 8161
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
368 2  SC = 0x7150
369 3  seqNum = 1813 (0x0715)  fraqNum = 0 (0x00)
370 4  QC = 0x000d
371 5  PSDU Priority = 13 (0xd)
372 6  Algorithm = AES_CCM
373 7  Key ID = 1
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
383 17  	43 e6 eb 1d
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
389 */
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,
393 };
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,
400 };
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,
408 	0xbb, 0x71,
409 };
410 
411 /*
412 ==== CCMP test mpdu   7 ====
413 
414 -- MPDU Fields
415 
416 25  Version  = 0
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
421 30  Encrypt  = 1
422 31  Order    = 0
423 32  Duration = 18049
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
427 36  SC = 0xA020
428 37  seqNum = 2562 (0x0A02)  fraqNum = 0 (0x00)
429 38  Algorithm = AES_CCM
430 39  Key ID = 3
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
434 43  	0c 4c cd ee 20 a0
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
440 49  	35 66 53 39
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
446 */
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,
450 };
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,
457 };
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,
465 };
466 
467 /*
468 ==== CCMP test mpdu   8 ====
469 
470 -- MPDU Fields
471 
472 6  Version  = 0
473 7  Type     = 2   SubType  = 11
474 8  ToDS     = 1   FromDS   = 0
475 9  MoreFrag = 0   Retry    = 1
476 10  PwrMgt   = 1   moreData = 0
477 11  Encrypt  = 1
478 12  Order    = 1
479 13  Duration = 29260
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
483 17  SC = 0xEB50
484 18  seqNum = 3765 (0x0EB5)  fraqNum = 0 (0x00)
485 19  QC = 0x000a
486 20  MSDU Priority = 10 (0xa)
487 21  Algorithm = AES_CCM
488 22  Key ID = 2
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
498 32  	64 37 59 79
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
504 */
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,
508 };
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,
515 };
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,
523 	0x87, 0xdd,
524 };
525 
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) \
531 }
532 
533 struct ciphertest {
534 	const char	*name;
535 	int		cipher;
536 	int		keyix;
537 	u_int64_t	pn;
538 	const u_int8_t	*key;
539 	size_t		key_len;
540 	const u_int8_t	*plaintext;
541 	size_t		plaintext_len;
542 	const u_int8_t	*encrypted;
543 	size_t		encrypted_len;
544 } ccmptests[] = {
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),
553 };
554 
555 static void
556 dumpdata(const char *tag, const void *p, size_t len)
557 {
558 	int i;
559 
560 	printf("%s: 0x%p len %u", tag, p, len);
561 	for (i = 0; i < len; i++) {
562 		if ((i % 16) == 0)
563 			printf("\n%03d:", i);
564 		printf(" %02x", ((const u_int8_t *)p)[i]);
565 	}
566 	printf("\n");
567 }
568 
569 static void
570 cmpfail(const void *gen, size_t genlen, const void *ref, size_t reflen)
571 {
572 	int i;
573 
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);
577 			break;
578 		}
579 	dumpdata("Generated", gen, genlen);
580 	dumpdata("Reference", ref, reflen);
581 }
582 
583 static void
584 printtest(const struct ciphertest *t)
585 {
586 	printf("keyix %u pn %llu key_len %u plaintext_len %u\n"
587 		, t->keyix
588 		, t->pn
589 		, t->key_len
590 		, t->plaintext_len
591 	);
592 }
593 
594 static int
595 runtest(struct ieee80211vap *vap, struct ciphertest *t)
596 {
597 	struct ieee80211_key *key = &vap->iv_nw_keys[t->keyix];
598 	struct mbuf *m = NULL;
599 	const struct ieee80211_cipher *cip;
600 	int hdrlen;
601 
602 	printf("%s: ", t->name);
603 
604 	/*
605 	 * Setup key.
606 	 */
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");
613 		goto bad;
614 	}
615 
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");
622 		goto bad;
623 	}
624 
625 	/*
626 	 * Craft frame from plaintext data.
627 	 */
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 *));
635 
636 	/*
637 	 * Encrypt frame w/ MIC.
638 	 */
639 	if (!cip->ic_encap(key, m)) {
640 		printtest(t);
641 		printf("FAIL: ccmp encap failed\n");
642 		goto bad;
643 	}
644 	/*
645 	 * Verify: frame length, frame contents.
646 	 */
647 	if (m->m_pkthdr.len != t->encrypted_len) {
648 		printf("FAIL: encap data length mismatch\n");
649 		printtest(t);
650 		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
651 			t->encrypted, t->encrypted_len);
652 		goto bad;
653 	} else if (memcmp(mtod(m, const void *), t->encrypted, t->encrypted_len)) {
654 		printf("FAIL: encrypt data does not compare\n");
655 		printtest(t);
656 		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
657 			t->encrypted, t->encrypted_len);
658 		dumpdata("Plaintext", t->plaintext, t->plaintext_len);
659 		goto bad;
660 	}
661 
662 	/*
663 	 * Decrypt frame; strip MIC.
664 	 */
665 	if (!cip->ic_decap(key, m, hdrlen)) {
666 		printf("FAIL: ccmp decap failed\n");
667 		printtest(t);
668 		cmpfail(mtod(m, const void *), m->m_len,
669 			t->plaintext, t->plaintext_len);
670 		goto bad;
671 	}
672 	/*
673 	 * Verify: frame length, frame contents.
674 	 */
675 	if (m->m_pkthdr.len != t->plaintext_len) {
676 		printf("FAIL: decap botch; length mismatch\n");
677 		printtest(t);
678 		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
679 			t->plaintext, t->plaintext_len);
680 		goto bad;
681 	} else if (memcmp(mtod(m, const void *), t->plaintext, t->plaintext_len)) {
682 		printf("FAIL: decap botch; data does not compare\n");
683 		printtest(t);
684 		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
685 			t->plaintext, t->plaintext_len);
686 		goto bad;
687 	}
688 	m_freem(m);
689 	ieee80211_crypto_delkey(vap, key);
690 	printf("PASS\n");
691 	return 1;
692 bad:
693 	if (m != NULL)
694 		m_freem(m);
695 	ieee80211_crypto_delkey(vap, key);
696 	return 0;
697 }
698 
699 /*
700  * Module glue.
701  */
702 
703 static	int tests = -1;
704 static	int debug = 0;
705 
706 static int
707 init_crypto_ccmp_test(void)
708 {
709 	struct ieee80211com ic;
710 	struct ieee80211vap vap;
711 	struct ifnet ifp;
712 	int i, pass, total;
713 
714 	memset(&ic, 0, sizeof(ic));
715 	memset(&vap, 0, sizeof(vap));
716 	memset(&ifp, 0, sizeof(ifp));
717 
718 	ieee80211_crypto_attach(&ic);
719 
720 	/* some minimal initialization */
721 	strncpy(ifp.if_xname, "test_ccmp", sizeof(ifp.if_xname));
722 	vap.iv_ic = &ic;
723 	vap.iv_ifp = &ifp;
724 	if (debug)
725 		vap.iv_debug = IEEE80211_MSG_CRYPTO;
726 	ieee80211_crypto_vattach(&vap);
727 
728 	pass = 0;
729 	total = 0;
730 	for (i = 0; i < nitems(ccmptests); i++)
731 		if (tests & (1<<i)) {
732 			total++;
733 			pass += runtest(&vap, &ccmptests[i]);
734 		}
735 	printf("%u of %u 802.11i AES-CCMP test vectors passed\n", pass, total);
736 
737 	ieee80211_crypto_vdetach(&vap);
738 	ieee80211_crypto_detach(&ic);
739 
740 	return (pass == total ? 0 : -1);
741 }
742 
743 static int
744 test_ccmp_modevent(module_t mod, int type, void *unused)
745 {
746 	switch (type) {
747 	case MOD_LOAD:
748 		(void) init_crypto_ccmp_test();
749 		return 0;
750 	case MOD_UNLOAD:
751 		return 0;
752 	}
753 	return EINVAL;
754 }
755 
756 static moduledata_t test_ccmp_mod = {
757 	"test_ccmp",
758 	test_ccmp_modevent,
759 	0
760 };
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);
764