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 
32 /*
33  * CCMP test module.
34  *
35  * Test vectors come from section I.7.4 of P802.11i/D7.0, October 2003.
36  *
37  * To use this tester load the net80211 layer (either as a module or
38  * by statically configuring it into your kernel), then kldload this
39  * module.  It should automatically run all test cases and print
40  * information for each.  To run one or more tests you can specify a
41  * tests parameter to the module that is a bit mask of the set of tests
42  * you want; e.g. insmod ccmp_test tests=7 will run only test mpdu's
43  * 1, 2, and 3.
44  */
45 #include <sys/param.h>
46 #include <sys/kernel.h>
47 #include <sys/systm.h>
48 #include <sys/mbuf.h>
49 #include <sys/module.h>
50 
51 #include <sys/socket.h>
52 
53 #include <net/if.h>
54 #include <net/if_var.h>
55 #include <net/if_media.h>
56 
57 #include <net80211/ieee80211_var.h>
58 
59 /*
60 ==== CCMP test mpdu   1 ====
61 
62 -- MPDU Fields
63 
64 7  Version  = 0
65 8  Type     = 2   SubType  = 0  Data
66 9  ToDS     = 0   FromDS   = 0
67 10  MoreFrag = 0   Retry    = 1
68 11  PwrMgt   = 0   moreData = 0
69 12  Encrypt  = 1
70 13  Order    = 0
71 14  Duration = 11459
72 15  A1 = 0f-d2-e1-28-a5-7c    DA
73 16  A2 = 50-30-f1-84-44-08    SA
74 17  A3 = ab-ae-a5-b8-fc-ba    BSSID
75 18  SC = 0x3380
76 19  seqNum = 824 (0x0338)  fraqNum = 0 (0x00)
77 20  Algorithm = AES_CCM
78 21  Key ID = 0
79 22  TK = c9 7c 1f 67 ce 37 11 85  51 4a 8a 19 f2 bd d5 2f
80 23  PN = 199027030681356  (0xB5039776E70C)
81 24  802.11 Header =  08 48 c3 2c 0f d2 e1 28 a5 7c 50 30 f1 84 44 08
82 25  	ab ae a5 b8 fc ba 80 33
83 26  Muted 802.11 Header =  08 40 0f d2 e1 28 a5 7c 50 30 f1 84 44 08
84 27  	ab ae a5 b8 fc ba 00 00
85 28  CCMP Header =  0c e7 00 20 76 97 03 b5
86 29  CCM Nonce = 00 50 30 f1 84 44 08 b5  03 97 76 e7 0c
87 30 Plaintext Data = f8 ba 1a 55 d0 2f 85 ae 96 7b b6 2f b6 cd a8 eb
88 1	7e 78 a0 50
89 2  CCM MIC =  78 45 ce 0b 16 f9 76 23
90 3  -- Encrypted MPDU with FCS
91 4  08 48 c3 2c 0f d2 e1 28 a5 7c 50 30 f1 84 44 08 ab ae a5 b8 fc ba
92 5  80 33 0c e7 00 20 76 97 03 b5 f3 d0 a2 fe 9a 3d bf 23 42 a6 43 e4
93 6  32 46 e8 0c 3c 04 d0 19 78 45 ce 0b 16 f9 76 23 1d 99 f0 66
94 */
95 static const u_int8_t test1_key[] = {		/* TK */
96 	0xc9, 0x7c, 0x1f, 0x67, 0xce, 0x37, 0x11, 0x85,  0x51, 0x4a, 0x8a,
97 	0x19, 0xf2, 0xbd, 0xd5, 0x2f
98 };
99 static const u_int8_t test1_plaintext[] = {	/* Plaintext MPDU w/o MIC */
100 	0x08, 0x48, 0xc3, 0x2c, 0x0f, 0xd2, 0xe1, 0x28,	/* 802.11 Header */
101 	0xa5, 0x7c, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08,
102 	0xab, 0xae, 0xa5, 0xb8, 0xfc, 0xba, 0x80, 0x33,
103 	0xf8, 0xba, 0x1a, 0x55, 0xd0, 0x2f, 0x85, 0xae,	/* Plaintext Data */
104 	0x96, 0x7b, 0xb6, 0x2f, 0xb6, 0xcd, 0xa8, 0xeb,
105 	0x7e, 0x78, 0xa0, 0x50,
106 };
107 static const u_int8_t test1_encrypted[] = {	/* Encrypted MPDU with MIC */
108 	0x08, 0x48, 0xc3, 0x2c, 0x0f, 0xd2, 0xe1, 0x28,
109 	0xa5, 0x7c, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08,
110 	0xab, 0xae, 0xa5, 0xb8, 0xfc, 0xba, 0x80, 0x33,
111 	0x0c, 0xe7, 0x00, 0x20, 0x76, 0x97, 0x03, 0xb5,
112 	0xf3, 0xd0, 0xa2, 0xfe, 0x9a, 0x3d, 0xbf, 0x23,
113 	0x42, 0xa6, 0x43, 0xe4, 0x32, 0x46, 0xe8, 0x0c,
114 	0x3c, 0x04, 0xd0, 0x19, 0x78, 0x45, 0xce, 0x0b,
115 	0x16, 0xf9, 0x76, 0x23,
116 };
117 
118 /*
119 ==== CCMP test mpdu   2 ====
120 
121 -- MPDU Fields
122 
123  9  Version  = 0
124 10  Type     = 2   SubType  = 3  Data+CF-Ack+CF-Poll
125 11  ToDS     = 0   FromDS   = 0
126 12  MoreFrag = 0   Retry    = 0
127 13  PwrMgt   = 0   moreData = 0
128 14  Encrypt  = 1
129 15  Order    = 1
130 16  Duration = 20842
131 17  A1 = ea-10-0c-84-68-50    DA
132 18  A2 = ee-c1-76-2c-88-de    SA
133 19  A3 = af-2e-e9-f4-6a-07    BSSID
134 20  SC = 0xCCE0
135 21  seqNum = 3278 (0x0CCE)  fraqNum = 0 (0x00)
136 22  Algorithm = AES_CCM
137 23  Key ID = 2
138 24  TK = 8f 7a 05 3f a5 77 a5 59  75 29 27 20 97 a6 03 d5
139 25  PN = 54923164817386  (0x31F3CBBA97EA)
140 26  802.11 Header =  38 c0 6a 51 ea 10 0c 84 68 50 ee c1 76 2c 88 de
141 27  	af 2e e9 f4 6a 07 e0 cc
142 28  Muted 802.11 Header =  08 c0 ea 10 0c 84 68 50 ee c1 76 2c 88 de
143 29  	af 2e e9 f4 6a 07 00 00
144 30  CCMP Header =  ea 97 00 a0 ba cb f3 31
145 31  CCM Nonce = 00 ee c1 76 2c 88 de 31  f3 cb ba 97 ea
146 32  Plaintext Data = 83 a0 63 4b 5e d7 62 7e b9 df 22 5e 05 74 03 42
147 33  	de 19 41 17
148 34  CCM MIC =  54 2f bf 8d a0 6a a4 ae
149 35  -- Encrypted MPDU with FCS
150 36  38 c0 6a 51 ea 10 0c 84 68 50 ee c1 76 2c 88 de af 2e e9 f4 6a 07
151 37  e0 cc ea 97 00 a0 ba cb f3 31 81 4b 69 65 d0 5b f2 b2 ed 38 d4 be
152 38  b0 69 fe 82 71 4a 61 0b 54 2f bf 8d a0 6a a4 ae 25 3c 47 38
153 */
154 static const u_int8_t test2_key[] = {		/* TK */
155 	0x8f, 0x7a, 0x05, 0x3f, 0xa5, 0x77, 0xa5, 0x59,  0x75, 0x29, 0x27,
156 	0x20, 0x97, 0xa6, 0x03, 0xd5
157 };
158 static const u_int8_t test2_plaintext[] = {	/* Plaintext MPDU w/o MIC */
159 	0x38, 0xc0, 0x6a, 0x51, 0xea, 0x10, 0x0c, 0x84, 0x68, 0x50, 0xee,
160 	0xc1, 0x76, 0x2c, 0x88, 0xde, 0xaf, 0x2e, 0xe9, 0xf4, 0x6a, 0x07,
161 	0xe0, 0xcc,
162 	0x83, 0xa0, 0x63, 0x4b, 0x5e, 0xd7, 0x62, 0x7e, 0xb9, 0xdf, 0x22,
163 	0x5e, 0x05, 0x74, 0x03, 0x42, 0xde, 0x19, 0x41, 0x17
164 };
165 static const u_int8_t test2_encrypted[] = {	/* Encrypted MPDU with MIC */
166 	0x38, 0xc0, 0x6a, 0x51, 0xea, 0x10, 0x0c, 0x84, 0x68, 0x50, 0xee,
167 	0xc1, 0x76, 0x2c, 0x88, 0xde, 0xaf, 0x2e, 0xe9, 0xf4, 0x6a, 0x07,
168 	0xe0, 0xcc, 0xea, 0x97, 0x00, 0xa0, 0xba, 0xcb, 0xf3, 0x31, 0x81,
169 	0x4b, 0x69, 0x65, 0xd0, 0x5b, 0xf2, 0xb2, 0xed, 0x38, 0xd4, 0xbe,
170 	0xb0, 0x69, 0xfe, 0x82, 0x71, 0x4a, 0x61, 0x0b, 0x54, 0x2f, 0xbf,
171 	0x8d, 0xa0, 0x6a, 0xa4, 0xae,
172 };
173 
174 /*
175 ==== CCMP test mpdu   3 ====
176 
177 -- MPDU Fields
178 
179 41  Version  = 0
180 42  Type     = 2   SubType  = 11
181 43  ToDS     = 0   FromDS   = 0
182 44  MoreFrag = 0   Retry    = 1
183 45  PwrMgt   = 0   moreData = 0
184 46  Encrypt  = 1
185 47  Order    = 1
186 48  Duration = 25052
187 49  A1 = d9-57-7d-f7-63-c8    DA
188 50 A2 = b6-a8-8a-df-36-91    SA
189 1  A3 = dc-4a-8b-ca-94-dd    BSSID
190 2  SC = 0x8260
191 3  seqNum = 2086 (0x0826)  fraqNum = 0 (0x00)
192 4  QC = 0x0000
193 5  MSDU Priority = 0 (0x0)
194 6  Algorithm = AES_CCM
195 7  Key ID = 2
196 8  TK = 40 cf b7 a6 2e 88 01 3b  d6 d3 af fc c1 91 04 1e
197 9  PN = 52624639632814  (0x2FDCA0F3A5AE)
198 10  802.11 Header =  b8 c8 dc 61 d9 57 7d f7 63 c8 b6 a8 8a df 36 91
199 11  	dc 4a 8b ca 94 dd 60 82 20 85
200 12  Muted 802.11 Header =  88 c0 d9 57 7d f7 63 c8 b6 a8 8a df 36 91
201 13  	dc 4a 8b ca 94 dd 00 00 00 00
202 14  CCMP Header =  ae a5 00 a0 f3 a0 dc 2f
203 15  CCM Nonce = 00 b6 a8 8a df 36 91 2f dc a0 f3 a5 ae
204 16  Plaintext Data  = 2c 1b d0 36 83 1c 95 49 6c 5f 4d bf 3d 55 9e 72
205 17  	de 80 2a 18
206 18  CCM MIC =  fd 1f 1f 61 a9 fb 4b b3
207 19  -- Encrypted MPDU with FCS
208 20  b8 c8 dc 61 d9 57 7d f7 63 c8 b6 a8 8a df 36 91 dc 4a 8b ca 94 dd
209 21  60 82 20 85 ae a5 00 a0 f3 a0 dc 2f 89 d8 58 03 40 b6 26 a0 b6 d4
210 22  d0 13 bf 18 f2 91 b8 96 46 c8 fd 1f 1f 61 a9 fb 4b b3 60 3f 5a ad
211 */
212 static const u_int8_t test3_key[] = {		/* TK */
213 	0x40, 0xcf, 0xb7, 0xa6, 0x2e, 0x88, 0x01, 0x3b,  0xd6, 0xd3,
214 	0xaf, 0xfc, 0xc1, 0x91, 0x04, 0x1e
215 };
216 static const u_int8_t test3_plaintext[] = {	/* Plaintext MPDU w/o MIC */
217 	0xb8, 0xc8, 0xdc, 0x61, 0xd9, 0x57, 0x7d, 0xf7, 0x63, 0xc8,
218 	0xb6, 0xa8, 0x8a, 0xdf, 0x36, 0x91, 0xdc, 0x4a, 0x8b, 0xca,
219 	0x94, 0xdd, 0x60, 0x82, 0x20, 0x85,
220 	0x2c, 0x1b, 0xd0, 0x36, 0x83, 0x1c, 0x95, 0x49, 0x6c, 0x5f,
221 	0x4d, 0xbf, 0x3d, 0x55, 0x9e, 0x72, 0xde, 0x80, 0x2a, 0x18
222 };
223 static const u_int8_t test3_encrypted[] = {	/* Encrypted MPDU with MIC */
224 	0xb8, 0xc8, 0xdc, 0x61, 0xd9, 0x57, 0x7d, 0xf7, 0x63, 0xc8,
225 	0xb6, 0xa8, 0x8a, 0xdf, 0x36, 0x91, 0xdc, 0x4a, 0x8b, 0xca,
226 	0x94, 0xdd, 0x60, 0x82, 0x20, 0x85, 0xae, 0xa5, 0x00, 0xa0,
227 	0xf3, 0xa0, 0xdc, 0x2f, 0x89, 0xd8, 0x58, 0x03, 0x40, 0xb6,
228 	0x26, 0xa0, 0xb6, 0xd4, 0xd0, 0x13, 0xbf, 0x18, 0xf2, 0x91,
229 	0xb8, 0x96, 0x46, 0xc8, 0xfd, 0x1f, 0x1f, 0x61, 0xa9, 0xfb,
230 	0x4b, 0xb3,
231 };
232 
233 /*
234 ==== CCMP test mpdu  4 ====
235 
236 -- MPDU Fields
237 25  Version  = 0
238 26  Type     = 2   SubType  = 10
239 27  ToDS     = 0   FromDS   = 1
240 28  MoreFrag = 0   Retry    = 1
241 29  PwrMgt   = 0   moreData = 0
242 30  Encrypt  = 1
243 31  Order    = 1
244 32  Duration = 4410
245 33  A1 = 71-2a-9d-df-11-db    DA
246 34  A2 = 8e-f8-22-73-47-01    BSSID
247 35  A3 = 59-14-0d-d6-46-a2    SA
248 36  SC = 0x2FC0
249 37  seqNum = 764 (0x02FC)  fraqNum = 0 (0x00)
250 38  QC = 0x0007
251 39  MSDU Priority = 7 (0x0)
252 40  Algorithm = AES_CCM
253 41  Key ID = 0
254 42  TK = 8c 89 a2 eb c9 6c 76 02  70 7f cf 24 b3 2d 38 33
255 43  PN = 270963670912995  (0xF670A55A0FE3)
256 44  802.11 Header =  a8 ca 3a 11 71 2a 9d df 11 db 8e f8 22 73 47 01
257 45  	59 14 0d d6 46 a2 c0 2f 67 a5
258 46  Muted 802.11 Header =  88 c2 71 2a 9d df 11 db 8e f8 22 73 47 01
259 47  	59 14 0d d6 46 a2 00 00 07 00
260 48  CCMP Header =  e3 0f 00 20 5a a5 70 f6
261 49  CCM Nonce = 07 8e f8 22 73 47 01 f6  70 a5 5a 0f e3
262 50  Plaintext Data = 4f ad 2b 1c 29 0f a5 eb d8 72 fb c3 f3 a0 74 89
263 51  	8f 8b 2f bb
264 52  CCM MIC =  31 fc 88 00 4f 35 ee 3d
265 -- Encrypted MPDU with FCS
266 2  a8 ca 3a 11 71 2a 9d df 11 db 8e f8 22 73 47 01 59 14 0d d6 46 a2
267 3  c0 2f 67 a5 e3 0f 00 20 5a a5 70 f6 9d 59 b1 5f 37 14 48 c2 30 f4
268 4  d7 39 05 2e 13 ab 3b 1a 7b 10 31 fc 88 00 4f 35 ee 3d 45 a7 4a 30
269 */
270 static const u_int8_t test4_key[] = {		/* TK */
271 	0x8c, 0x89, 0xa2, 0xeb, 0xc9, 0x6c, 0x76, 0x02,
272 	0x70, 0x7f, 0xcf, 0x24, 0xb3, 0x2d, 0x38, 0x33,
273 };
274 static const u_int8_t test4_plaintext[] = {	/* Plaintext MPDU w/o MIC */
275 	0xa8, 0xca, 0x3a, 0x11, 0x71, 0x2a, 0x9d, 0xdf, 0x11, 0xdb,
276 	0x8e, 0xf8, 0x22, 0x73, 0x47, 0x01, 0x59, 0x14, 0x0d, 0xd6,
277 	0x46, 0xa2, 0xc0, 0x2f, 0x67, 0xa5,
278 	0x4f, 0xad, 0x2b, 0x1c, 0x29, 0x0f, 0xa5, 0xeb, 0xd8, 0x72,
279 	0xfb, 0xc3, 0xf3, 0xa0, 0x74, 0x89, 0x8f, 0x8b, 0x2f, 0xbb,
280 };
281 static const u_int8_t test4_encrypted[] = {	/* Encrypted MPDU with MIC */
282 	0xa8, 0xca, 0x3a, 0x11, 0x71, 0x2a, 0x9d, 0xdf, 0x11, 0xdb,
283 	0x8e, 0xf8, 0x22, 0x73, 0x47, 0x01, 0x59, 0x14, 0x0d, 0xd6,
284 	0x46, 0xa2, 0xc0, 0x2f, 0x67, 0xa5, 0xe3, 0x0f, 0x00, 0x20,
285 	0x5a, 0xa5, 0x70, 0xf6, 0x9d, 0x59, 0xb1, 0x5f, 0x37, 0x14,
286 	0x48, 0xc2, 0x30, 0xf4, 0xd7, 0x39, 0x05, 0x2e, 0x13, 0xab,
287 	0x3b, 0x1a, 0x7b, 0x10, 0x31, 0xfc, 0x88, 0x00, 0x4f, 0x35,
288 	0xee, 0x3d,
289 };
290 
291 /*
292 ==== CCMP test mpdu   5 ====
293 
294 -- MPDU Fields
295 
296 7  Version  = 0
297 8  Type     = 2   SubType  = 8
298 9  ToDS     = 0   FromDS   = 1
299 10  MoreFrag = 0   Retry    = 1
300 11  PwrMgt   = 1   moreData = 0
301 12  Encrypt  = 1
302 13  Order    = 1
303 14  Duration = 16664
304 15  A1 = 45-de-c6-9a-74-80    DA
305 16  A2 = f3-51-94-6b-c9-6b    BSSID
306 17  A3 = e2-76-fb-e6-c1-27    SA
307 18  SC = 0xF280
308 19  seqNum = 3880 (0x0F28)  fraqNum = 0 (0x00)
309 20  QC = 0x000b
310 21  MSDU Priority = 0 (0x0)
311 22  Algorithm = AES_CCM
312 23  Key ID = 2
313 24  TK = a5 74 d5 14 3b b2 5e fd  de ff 30 12 2f df d0 66
314 25  PN = 184717420531255  (0xA7FFE03C0E37)
315 26  802.11 Header =  88 da 18 41 45 de c6 9a 74 80 f3 51 94 6b c9 6b
316 27  	e2 76 fb e6 c1 27 80 f2 4b 19
317 28  Muted 802.11 Header =  88 c2 45 de c6 9a 74 80 f3 51 94 6b c9 6b
318 29  	e2 76 fb e6 c1 27 00 00 0b 00
319 30  CCMP Header =  37 0e 00 a0 3c e0 ff a7
320 31  CCM Nonce = 0b f3 51 94 6b c9 6b a7 ff e0 3c 0e 37
321 32  Plaintext Data = 28 96 9b 95 4f 26 3a 80 18 a9 ef 70 a8 b0 51 46
322 33  	24 81 92 2e
323 34  CCM MIC =  ce 0c 3b e1 97 d3 05 eb
324 35  -- Encrypted MPDU with FCS
325 36  88 da 18 41 45 de c6 9a 74 80 f3 51 94 6b c9 6b e2 76 fb e6 c1 27
326 37  80 f2 4b 19 37 0e 00 a0 3c e0 ff a7 eb 4a e4 95 6a 80 1d a9 62 4b
327 38  7e 0c 18 b2 3e 61 5e c0 3a f6 ce 0c 3b e1 97 d3 05 eb c8 9e a1 b5
328 */
329 static const u_int8_t test5_key[] = {		/* TK */
330 	0xa5, 0x74, 0xd5, 0x14, 0x3b, 0xb2, 0x5e, 0xfd,
331 	0xde, 0xff, 0x30, 0x12, 0x2f, 0xdf, 0xd0, 0x66,
332 };
333 static const u_int8_t test5_plaintext[] = {	/* Plaintext MPDU w/o MIC */
334 	0x88, 0xda, 0x18, 0x41, 0x45, 0xde, 0xc6, 0x9a, 0x74, 0x80,
335 	0xf3, 0x51, 0x94, 0x6b, 0xc9, 0x6b, 0xe2, 0x76, 0xfb, 0xe6,
336 	0xc1, 0x27, 0x80, 0xf2, 0x4b, 0x19,
337 	0x28, 0x96, 0x9b, 0x95, 0x4f, 0x26, 0x3a, 0x80, 0x18, 0xa9,
338 	0xef, 0x70, 0xa8, 0xb0, 0x51, 0x46, 0x24, 0x81, 0x92, 0x2e,
339 };
340 static const u_int8_t test5_encrypted[] = {	/* Encrypted MPDU with MIC */
341 	0x88, 0xda, 0x18, 0x41, 0x45, 0xde, 0xc6, 0x9a, 0x74, 0x80,
342 	0xf3, 0x51, 0x94, 0x6b, 0xc9, 0x6b, 0xe2, 0x76, 0xfb, 0xe6,
343 	0xc1, 0x27, 0x80, 0xf2, 0x4b, 0x19, 0x37, 0x0e, 0x00, 0xa0,
344 	0x3c, 0xe0, 0xff, 0xa7, 0xeb, 0x4a, 0xe4, 0x95, 0x6a, 0x80,
345 	0x1d, 0xa9, 0x62, 0x4b, 0x7e, 0x0c, 0x18, 0xb2, 0x3e, 0x61,
346 	0x5e, 0xc0, 0x3a, 0xf6, 0xce, 0x0c, 0x3b, 0xe1, 0x97, 0xd3,
347 	0x05, 0xeb,
348 };
349 
350 /*
351 ==== CCMP test mpdu   6 ====
352 
353 -- MPDU Fields
354 
355 41  Version  = 0
356 42  Type     = 2   SubType  = 8
357 43  ToDS     = 0   FromDS   = 1
358 44  MoreFrag = 0   Retry    = 0
359 45  PwrMgt   = 1   moreData = 0
360 46  Encrypt  = 1
361 47  Order    = 0
362 48  Duration = 8161
363 49  A1 = 5a-f2-84-30-fd-ab    DA
364 50  A2 = bf-f9-43-b9-f9-a6    BSSID
365 1   A3 = ab-1d-98-c7-fe-73    SA
366 2  SC = 0x7150
367 3  seqNum = 1813 (0x0715)  fraqNum = 0 (0x00)
368 4  QC = 0x000d
369 5  PSDU Priority = 13 (0xd)
370 6  Algorithm = AES_CCM
371 7  Key ID = 1
372 8  TK = f7 1e ea 4e 1f 58 80 4b 97 17 23 0a d0 61 46 41
373 9  PN    = 118205765159305  (0x6B81ECA48989)
374 10  802.11 Header =  88 52 e1 1f 5a f2 84 30 fd ab bf f9 43 b9 f9 a6
375 11  	ab 1d 98 c7 fe 73 50 71  3d 6a
376 12  Muted 802.11 Header =  88 42 5a f2 84 30 fd ab bf f9 43 b9 f9 a6
377 13  	ab 1d 98 c7 fe 73 00 00 0d 00
378 14  CCMP Header =  89 89 00 60 a4 ec 81 6b
379 15  CCM Nonce = 0d bf f9 43 b9 f9 a6 6b  81 ec a4 89 89
380 16  Plaintext Data = ab fd a2 2d 3a 0b fc 9c c1 fc 07 93 63 c2 fc a1
381 17  	43 e6 eb 1d
382 18  CCM MIC =  30 9a 8d 5c 46 6b bb 71
383 19  -- Encrypted MPDU with FCS
384 20  88 52 e1 1f 5a f2 84 30 fd ab bf f9 43 b9 f9 a6 ab 1d 98 c7 fe 73
385 21  50 71 3d 6a 89 89 00 60 a4 ec 81 6b 9a 70 9b 60 a3 9d 40 b1 df b6
386 22  12 e1 8b 5f 11 4b ad b6 cc 86 30 9a 8d 5c 46 6b bb 71 86 c0 4e 97
387 */
388 static const u_int8_t test6_key[] = {		/* TK */
389 	0xf7, 0x1e, 0xea, 0x4e, 0x1f, 0x58, 0x80, 0x4b,
390 	0x97, 0x17, 0x23, 0x0a, 0xd0, 0x61, 0x46, 0x41,
391 };
392 static const u_int8_t test6_plaintext[] = {	/* Plaintext MPDU w/o MIC */
393 	0x88, 0x52, 0xe1, 0x1f, 0x5a, 0xf2, 0x84, 0x30, 0xfd, 0xab,
394 	0xbf, 0xf9, 0x43, 0xb9, 0xf9, 0xa6, 0xab, 0x1d, 0x98, 0xc7,
395 	0xfe, 0x73, 0x50, 0x71, 0x3d, 0x6a,
396 	0xab, 0xfd, 0xa2, 0x2d, 0x3a, 0x0b, 0xfc, 0x9c, 0xc1, 0xfc,
397 	0x07, 0x93, 0x63, 0xc2, 0xfc, 0xa1, 0x43, 0xe6, 0xeb, 0x1d,
398 };
399 static const u_int8_t test6_encrypted[] = {	/* Encrypted MPDU with MIC */
400 	0x88, 0x52, 0xe1, 0x1f, 0x5a, 0xf2, 0x84, 0x30, 0xfd, 0xab,
401 	0xbf, 0xf9, 0x43, 0xb9, 0xf9, 0xa6, 0xab, 0x1d, 0x98, 0xc7,
402 	0xfe, 0x73, 0x50, 0x71, 0x3d, 0x6a, 0x89, 0x89, 0x00, 0x60,
403 	0xa4, 0xec, 0x81, 0x6b, 0x9a, 0x70, 0x9b, 0x60, 0xa3, 0x9d,
404 	0x40, 0xb1, 0xdf, 0xb6, 0x12, 0xe1, 0x8b, 0x5f, 0x11, 0x4b,
405 	0xad, 0xb6, 0xcc, 0x86, 0x30, 0x9a, 0x8d, 0x5c, 0x46, 0x6b,
406 	0xbb, 0x71,
407 };
408 
409 /*
410 ==== CCMP test mpdu   7 ====
411 
412 -- MPDU Fields
413 
414 25  Version  = 0
415 26  Type     = 2   SubType  = 1  Data+CF-Ack
416 27  ToDS     = 1   FromDS   = 0
417 28  MoreFrag = 0   Retry    = 1
418 29  PwrMgt   = 1   moreData = 1
419 30  Encrypt  = 1
420 31  Order    = 0
421 32  Duration = 18049
422 33  A1 = 9b-50-f4-fd-56-f6    BSSID
423 34  A2 = ef-ec-95-20-16-91    SA
424 35  A3 = 83-57-0c-4c-cd-ee    DA
425 36  SC = 0xA020
426 37  seqNum = 2562 (0x0A02)  fraqNum = 0 (0x00)
427 38  Algorithm = AES_CCM
428 39  Key ID = 3
429 40  TK = 1b db 34 98 0e 03 81 24 a1 db 1a 89 2b ec 36 6a
430 41  PN = 104368786630435  (0x5EEC4073E723)
431 42  Header =  18 79 81 46 9b 50 f4 fd 56 f6 ef ec 95 20 16 91 83 57
432 43  	0c 4c cd ee 20 a0
433 44  Muted MAC Header =  08 41 9b 50 f4 fd 56 f6 ef ec 95 20 16 91
434 45  	83 57 0c 4c cd ee 00 00
435 46  CCMP Header =  23 e7 00 e0 73 40 ec 5e
436 47  CCM Nonce = 00 ef ec 95 20 16 91 5e ec 40 73 e7 23
437 48  Plaintext Data = 98 be ca 86 f4 b3 8d a2 0c fd f2 47 24 c5 8e b8
438 49  	35 66 53 39
439 50  CCM MIC =  2d 09 57 ec fa be 95 b9
440 -- Encrypted MPDU with FCS
441 1  18 79 81 46 9b 50 f4 fd 56 f6 ef ec 95 20 16 91 83 57 0c 4c cd ee
442 2  20 a0 23 e7 00 e0 73 40 ec 5e 12 c5 37 eb f3 ab 58 4e f1 fe f9 a1
443 3  f3 54 7a 8c 13 b3 22 5a 2d 09 57 ec fa be 95 b9 aa fa 0c c8
444 */
445 static const u_int8_t test7_key[] = {		/* TK */
446 	0x1b, 0xdb, 0x34, 0x98, 0x0e, 0x03, 0x81, 0x24,
447 	0xa1, 0xdb, 0x1a, 0x89, 0x2b, 0xec, 0x36, 0x6a,
448 };
449 static const u_int8_t test7_plaintext[] = {	/* Plaintext MPDU w/o MIC */
450 	0x18, 0x79, 0x81, 0x46, 0x9b, 0x50, 0xf4, 0xfd, 0x56, 0xf6,
451 	0xef, 0xec, 0x95, 0x20, 0x16, 0x91, 0x83, 0x57, 0x0c, 0x4c,
452 	0xcd, 0xee, 0x20, 0xa0,
453 	0x98, 0xbe, 0xca, 0x86, 0xf4, 0xb3, 0x8d, 0xa2, 0x0c, 0xfd,
454 	0xf2, 0x47, 0x24, 0xc5, 0x8e, 0xb8, 0x35, 0x66, 0x53, 0x39,
455 };
456 static const u_int8_t test7_encrypted[] = {	/* Encrypted MPDU with MIC */
457 	0x18, 0x79, 0x81, 0x46, 0x9b, 0x50, 0xf4, 0xfd, 0x56, 0xf6,
458 	0xef, 0xec, 0x95, 0x20, 0x16, 0x91, 0x83, 0x57, 0x0c, 0x4c,
459 	0xcd, 0xee, 0x20, 0xa0, 0x23, 0xe7, 0x00, 0xe0, 0x73, 0x40,
460 	0xec, 0x5e, 0x12, 0xc5, 0x37, 0xeb, 0xf3, 0xab, 0x58, 0x4e,
461 	0xf1, 0xfe, 0xf9, 0xa1, 0xf3, 0x54, 0x7a, 0x8c, 0x13, 0xb3,
462 	0x22, 0x5a, 0x2d, 0x09, 0x57, 0xec, 0xfa, 0xbe, 0x95, 0xb9,
463 };
464 
465 /*
466 ==== CCMP test mpdu   8 ====
467 
468 -- MPDU Fields
469 
470 6  Version  = 0
471 7  Type     = 2   SubType  = 11
472 8  ToDS     = 1   FromDS   = 0
473 9  MoreFrag = 0   Retry    = 1
474 10  PwrMgt   = 1   moreData = 0
475 11  Encrypt  = 1
476 12  Order    = 1
477 13  Duration = 29260
478 14  A1 = 55-2d-5f-72-bb-70    BSSID
479 15  A2 = ca-3f-3a-ae-60-c4    SA
480 16  A3 = 8b-a9-b5-f8-2c-2f    DA
481 17  SC = 0xEB50
482 18  seqNum = 3765 (0x0EB5)  fraqNum = 0 (0x00)
483 19  QC = 0x000a
484 20  MSDU Priority = 10 (0xa)
485 21  Algorithm = AES_CCM
486 22  Key ID = 2
487 23  TK = 6e ac 1b f5 4b d5 4e db 23 21 75 43 03 02 4c 71
488 24  PN    = 227588596223197  (0xCEFD996ECCDD)
489 25  802.11 Header =  b8 d9 4c 72 55 2d 5f 72 bb 70 ca 3f 3a ae 60 c4
490 26  	8b a9 b5 f8 2c 2f 50 eb 2a 55
491 27  Muted 802.11 Header =  88 c1 55 2d 5f 72 bb 70 ca 3f 3a ae 60 c4
492 28  	8b a9 b5 f8 2c 2f 00 00 0a 00
493 29  CCMP Header =  dd cc 00 a0 6e 99 fd ce
494 30  CCM Nonce = 0a ca 3f 3a ae 60 c4 ce fd 99 6e cc dd
495 31  Plaintext Data = 57 cb 5c 0e 5f cd 88 5e 9a 42 39 e9 b9 ca d6 0d
496 32  	64 37 59 79
497 33  CCM MIC =  6d ba 8e f7 f0 80 87 dd
498 -- Encrypted MPDU with FCS
499 35  b8 d9 4c 72 55 2d 5f 72 bb 70 ca 3f 3a ae 60 c4 8b a9 b5 f8 2c 2f
500 36  50 eb 2a 55 dd cc 00 a0 6e 99 fd ce 4b f2 81 ef 8e c7 73 9f 91 59
501 37  1b 97 a8 7d c1 4b 3f a1 74 62 6d ba 8e f7 f0 80 87 dd 0c 65 74 3f
502 */
503 static const u_int8_t test8_key[] = {		/* TK */
504 	0x6e, 0xac, 0x1b, 0xf5, 0x4b, 0xd5, 0x4e, 0xdb,
505 	0x23, 0x21, 0x75, 0x43, 0x03, 0x02, 0x4c, 0x71,
506 };
507 static const u_int8_t test8_plaintext[] = {	/* Plaintext MPDU w/o MIC */
508 	0xb8, 0xd9, 0x4c, 0x72, 0x55, 0x2d, 0x5f, 0x72, 0xbb, 0x70,
509 	0xca, 0x3f, 0x3a, 0xae, 0x60, 0xc4, 0x8b, 0xa9, 0xb5, 0xf8,
510 	0x2c, 0x2f, 0x50, 0xeb, 0x2a, 0x55,
511 	0x57, 0xcb, 0x5c, 0x0e, 0x5f, 0xcd, 0x88, 0x5e, 0x9a, 0x42,
512 	0x39, 0xe9, 0xb9, 0xca, 0xd6, 0x0d, 0x64, 0x37, 0x59, 0x79,
513 };
514 static const u_int8_t test8_encrypted[] = {	/* Encrypted MPDU with MIC */
515 	0xb8, 0xd9, 0x4c, 0x72, 0x55, 0x2d, 0x5f, 0x72, 0xbb, 0x70,
516 	0xca, 0x3f, 0x3a, 0xae, 0x60, 0xc4, 0x8b, 0xa9, 0xb5, 0xf8,
517 	0x2c, 0x2f, 0x50, 0xeb, 0x2a, 0x55, 0xdd, 0xcc, 0x00, 0xa0,
518 	0x6e, 0x99, 0xfd, 0xce, 0x4b, 0xf2, 0x81, 0xef, 0x8e, 0xc7,
519 	0x73, 0x9f, 0x91, 0x59, 0x1b, 0x97, 0xa8, 0x7d, 0xc1, 0x4b,
520 	0x3f, 0xa1, 0x74, 0x62, 0x6d, 0xba, 0x8e, 0xf7, 0xf0, 0x80,
521 	0x87, 0xdd,
522 };
523 
524 #define	TEST(n,name,cipher,keyix,pn) { \
525 	name, IEEE80211_CIPHER_##cipher,keyix, pn##LL, \
526 	test##n##_key,   sizeof(test##n##_key), \
527 	test##n##_plaintext, sizeof(test##n##_plaintext), \
528 	test##n##_encrypted, sizeof(test##n##_encrypted) \
529 }
530 
531 struct ciphertest {
532 	const char	*name;
533 	int		cipher;
534 	int		keyix;
535 	u_int64_t	pn;
536 	const u_int8_t	*key;
537 	size_t		key_len;
538 	const u_int8_t	*plaintext;
539 	size_t		plaintext_len;
540 	const u_int8_t	*encrypted;
541 	size_t		encrypted_len;
542 } ccmptests[] = {
543 	TEST(1, "CCMP test mpdu 1", AES_CCM, 0, 199027030681356),
544 	TEST(2, "CCMP test mpdu 2", AES_CCM, 2, 54923164817386),
545 	TEST(3, "CCMP test mpdu 3", AES_CCM, 2, 52624639632814),
546 	TEST(4, "CCMP test mpdu 4", AES_CCM, 0, 270963670912995),
547 	TEST(5, "CCMP test mpdu 5", AES_CCM, 2, 184717420531255),
548 	TEST(6, "CCMP test mpdu 6", AES_CCM, 1, 118205765159305),
549 	TEST(7, "CCMP test mpdu 7", AES_CCM, 3, 104368786630435),
550 	TEST(8, "CCMP test mpdu 8", AES_CCM, 2, 227588596223197),
551 };
552 
553 static void
554 dumpdata(const char *tag, const void *p, size_t len)
555 {
556 	int i;
557 
558 	printf("%s: 0x%p len %u", tag, p, len);
559 	for (i = 0; i < len; i++) {
560 		if ((i % 16) == 0)
561 			printf("\n%03d:", i);
562 		printf(" %02x", ((const u_int8_t *)p)[i]);
563 	}
564 	printf("\n");
565 }
566 
567 static void
568 cmpfail(const void *gen, size_t genlen, const void *ref, size_t reflen)
569 {
570 	int i;
571 
572 	for (i = 0; i < genlen; i++)
573 		if (((const u_int8_t *)gen)[i] != ((const u_int8_t *)ref)[i]) {
574 			printf("first difference at byte %u\n", i);
575 			break;
576 		}
577 	dumpdata("Generated", gen, genlen);
578 	dumpdata("Reference", ref, reflen);
579 }
580 
581 static void
582 printtest(const struct ciphertest *t)
583 {
584 	printf("keyix %u pn %llu key_len %u plaintext_len %u\n"
585 		, t->keyix
586 		, t->pn
587 		, t->key_len
588 		, t->plaintext_len
589 	);
590 }
591 
592 static int
593 runtest(struct ieee80211vap *vap, struct ciphertest *t)
594 {
595 	struct ieee80211_key *key = &vap->iv_nw_keys[t->keyix];
596 	struct mbuf *m = NULL;
597 	const struct ieee80211_cipher *cip;
598 	int hdrlen;
599 
600 	printf("%s: ", t->name);
601 
602 	/*
603 	 * Setup key.
604 	 */
605 	memset(key, 0, sizeof(*key));
606 	key->wk_flags = IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV;
607 	key->wk_cipher = &ieee80211_cipher_none;
608 	if (!ieee80211_crypto_newkey(vap, t->cipher,
609 	    IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV, key)) {
610 		printf("FAIL: ieee80211_crypto_newkey failed\n");
611 		goto bad;
612 	}
613 
614 	memcpy(key->wk_key, t->key, t->key_len);
615 	key->wk_keylen = t->key_len;
616 	memset(key->wk_keyrsc, 0, sizeof(key->wk_keyrsc));
617 	key->wk_keytsc = t->pn-1;	/* PN-1 since we do encap */
618 	if (!ieee80211_crypto_setkey(vap, key)) {
619 		printf("FAIL: ieee80211_crypto_setkey failed\n");
620 		goto bad;
621 	}
622 
623 	/*
624 	 * Craft frame from plaintext data.
625 	 */
626 	cip = key->wk_cipher;
627 	m = m_getcl(M_NOWAIT, MT_HEADER, M_PKTHDR);
628 	m->m_data += cip->ic_header;
629 	memcpy(mtod(m, void *), t->plaintext, t->plaintext_len);
630 	m->m_len = t->plaintext_len;
631 	m->m_pkthdr.len = m->m_len;
632 	hdrlen = ieee80211_anyhdrsize(mtod(m, void *));
633 
634 	/*
635 	 * Encrypt frame w/ MIC.
636 	 */
637 	if (!cip->ic_encap(key, m)) {
638 		printtest(t);
639 		printf("FAIL: ccmp encap failed\n");
640 		goto bad;
641 	}
642 	/*
643 	 * Verify: frame length, frame contents.
644 	 */
645 	if (m->m_pkthdr.len != t->encrypted_len) {
646 		printf("FAIL: encap data length mismatch\n");
647 		printtest(t);
648 		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
649 			t->encrypted, t->encrypted_len);
650 		goto bad;
651 	} else if (memcmp(mtod(m, const void *), t->encrypted, t->encrypted_len)) {
652 		printf("FAIL: encrypt data does not compare\n");
653 		printtest(t);
654 		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
655 			t->encrypted, t->encrypted_len);
656 		dumpdata("Plaintext", t->plaintext, t->plaintext_len);
657 		goto bad;
658 	}
659 
660 	/*
661 	 * Decrypt frame; strip MIC.
662 	 */
663 	if (!cip->ic_decap(key, m, hdrlen)) {
664 		printf("FAIL: ccmp decap failed\n");
665 		printtest(t);
666 		cmpfail(mtod(m, const void *), m->m_len,
667 			t->plaintext, t->plaintext_len);
668 		goto bad;
669 	}
670 	/*
671 	 * Verify: frame length, frame contents.
672 	 */
673 	if (m->m_pkthdr.len != t->plaintext_len) {
674 		printf("FAIL: decap botch; length mismatch\n");
675 		printtest(t);
676 		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
677 			t->plaintext, t->plaintext_len);
678 		goto bad;
679 	} else if (memcmp(mtod(m, const void *), t->plaintext, t->plaintext_len)) {
680 		printf("FAIL: decap botch; data does not compare\n");
681 		printtest(t);
682 		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
683 			t->plaintext, t->plaintext_len);
684 		goto bad;
685 	}
686 	m_freem(m);
687 	ieee80211_crypto_delkey(vap, key);
688 	printf("PASS\n");
689 	return 1;
690 bad:
691 	if (m != NULL)
692 		m_freem(m);
693 	ieee80211_crypto_delkey(vap, key);
694 	return 0;
695 }
696 
697 /*
698  * Module glue.
699  */
700 
701 static	int tests = -1;
702 static	int debug = 0;
703 
704 static int
705 init_crypto_ccmp_test(void)
706 {
707 	struct ieee80211com ic;
708 	struct ieee80211vap vap;
709 	struct ifnet ifp;
710 	int i, pass, total;
711 
712 	memset(&ic, 0, sizeof(ic));
713 	memset(&vap, 0, sizeof(vap));
714 	memset(&ifp, 0, sizeof(ifp));
715 
716 	ieee80211_crypto_attach(&ic);
717 
718 	/* some minimal initialization */
719 	strncpy(ifp.if_xname, "test_ccmp", sizeof(ifp.if_xname));
720 	vap.iv_ic = &ic;
721 	vap.iv_ifp = &ifp;
722 	if (debug)
723 		vap.iv_debug = IEEE80211_MSG_CRYPTO;
724 	ieee80211_crypto_vattach(&vap);
725 
726 	pass = 0;
727 	total = 0;
728 	for (i = 0; i < nitems(ccmptests); i++)
729 		if (tests & (1<<i)) {
730 			total++;
731 			pass += runtest(&vap, &ccmptests[i]);
732 		}
733 	printf("%u of %u 802.11i AES-CCMP test vectors passed\n", pass, total);
734 
735 	ieee80211_crypto_vdetach(&vap);
736 	ieee80211_crypto_detach(&ic);
737 
738 	return (pass == total ? 0 : -1);
739 }
740 
741 static int
742 test_ccmp_modevent(module_t mod, int type, void *unused)
743 {
744 	switch (type) {
745 	case MOD_LOAD:
746 		(void) init_crypto_ccmp_test();
747 		return 0;
748 	case MOD_UNLOAD:
749 		return 0;
750 	}
751 	return EINVAL;
752 }
753 
754 static moduledata_t test_ccmp_mod = {
755 	"test_ccmp",
756 	test_ccmp_modevent,
757 	0
758 };
759 DECLARE_MODULE(test_ccmp, test_ccmp_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
760 MODULE_VERSION(test_ccmp, 1);
761 MODULE_DEPEND(test_ccmp, wlan, 1, 1, 1);
762