xref: /freebsd/tools/regression/net80211/ccmp/test_ccmp.c (revision b3e7694832e81d7a904a10f525f8797b753bf0d3)
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
dumpdata(const char * tag,const void * p,size_t len)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
cmpfail(const void * gen,size_t genlen,const void * ref,size_t reflen)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
printtest(const struct ciphertest * t)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
runtest(struct ieee80211vap * vap,struct ciphertest * t)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
init_crypto_ccmp_test(void)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
test_ccmp_modevent(module_t mod,int type,void * unused)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