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