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 667 Version = 0 678 Type = 2 SubType = 0 Data 689 ToDS = 0 FromDS = 0 6910 MoreFrag = 0 Retry = 1 7011 PwrMgt = 0 moreData = 0 7112 Encrypt = 1 7213 Order = 0 7314 Duration = 11459 7415 A1 = 0f-d2-e1-28-a5-7c DA 7516 A2 = 50-30-f1-84-44-08 SA 7617 A3 = ab-ae-a5-b8-fc-ba BSSID 7718 SC = 0x3380 7819 seqNum = 824 (0x0338) fraqNum = 0 (0x00) 7920 Algorithm = AES_CCM 8021 Key ID = 0 8122 TK = c9 7c 1f 67 ce 37 11 85 51 4a 8a 19 f2 bd d5 2f 8223 PN = 199027030681356 (0xB5039776E70C) 8324 802.11 Header = 08 48 c3 2c 0f d2 e1 28 a5 7c 50 30 f1 84 44 08 8425 ab ae a5 b8 fc ba 80 33 8526 Muted 802.11 Header = 08 40 0f d2 e1 28 a5 7c 50 30 f1 84 44 08 8627 ab ae a5 b8 fc ba 00 00 8728 CCMP Header = 0c e7 00 20 76 97 03 b5 8829 CCM Nonce = 00 50 30 f1 84 44 08 b5 03 97 76 e7 0c 8930 Plaintext Data = f8 ba 1a 55 d0 2f 85 ae 96 7b b6 2f b6 cd a8 eb 901 7e 78 a0 50 912 CCM MIC = 78 45 ce 0b 16 f9 76 23 923 -- Encrypted MPDU with FCS 934 08 48 c3 2c 0f d2 e1 28 a5 7c 50 30 f1 84 44 08 ab ae a5 b8 fc ba 945 80 33 0c e7 00 20 76 97 03 b5 f3 d0 a2 fe 9a 3d bf 23 42 a6 43 e4 956 32 46 e8 0c 3c 04 d0 19 78 45 ce 0b 16 f9 76 23 1d 99 f0 66 96*/ 97static 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}; 101static 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}; 109static 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 12610 Type = 2 SubType = 3 Data+CF-Ack+CF-Poll 12711 ToDS = 0 FromDS = 0 12812 MoreFrag = 0 Retry = 0 12913 PwrMgt = 0 moreData = 0 13014 Encrypt = 1 13115 Order = 1 13216 Duration = 20842 13317 A1 = ea-10-0c-84-68-50 DA 13418 A2 = ee-c1-76-2c-88-de SA 13519 A3 = af-2e-e9-f4-6a-07 BSSID 13620 SC = 0xCCE0 13721 seqNum = 3278 (0x0CCE) fraqNum = 0 (0x00) 13822 Algorithm = AES_CCM 13923 Key ID = 2 14024 TK = 8f 7a 05 3f a5 77 a5 59 75 29 27 20 97 a6 03 d5 14125 PN = 54923164817386 (0x31F3CBBA97EA) 14226 802.11 Header = 38 c0 6a 51 ea 10 0c 84 68 50 ee c1 76 2c 88 de 14327 af 2e e9 f4 6a 07 e0 cc 14428 Muted 802.11 Header = 08 c0 ea 10 0c 84 68 50 ee c1 76 2c 88 de 14529 af 2e e9 f4 6a 07 00 00 14630 CCMP Header = ea 97 00 a0 ba cb f3 31 14731 CCM Nonce = 00 ee c1 76 2c 88 de 31 f3 cb ba 97 ea 14832 Plaintext Data = 83 a0 63 4b 5e d7 62 7e b9 df 22 5e 05 74 03 42 14933 de 19 41 17 15034 CCM MIC = 54 2f bf 8d a0 6a a4 ae 15135 -- Encrypted MPDU with FCS 15236 38 c0 6a 51 ea 10 0c 84 68 50 ee c1 76 2c 88 de af 2e e9 f4 6a 07 15337 e0 cc ea 97 00 a0 ba cb f3 31 81 4b 69 65 d0 5b f2 b2 ed 38 d4 be 15438 b0 69 fe 82 71 4a 61 0b 54 2f bf 8d a0 6a a4 ae 25 3c 47 38 155*/ 156static 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}; 160static 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}; 167static 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 18141 Version = 0 18242 Type = 2 SubType = 11 18343 ToDS = 0 FromDS = 0 18444 MoreFrag = 0 Retry = 1 18545 PwrMgt = 0 moreData = 0 18646 Encrypt = 1 18747 Order = 1 18848 Duration = 25052 18949 A1 = d9-57-7d-f7-63-c8 DA 19050 A2 = b6-a8-8a-df-36-91 SA 1911 A3 = dc-4a-8b-ca-94-dd BSSID 1922 SC = 0x8260 1933 seqNum = 2086 (0x0826) fraqNum = 0 (0x00) 1944 QC = 0x0000 1955 MSDU Priority = 0 (0x0) 1966 Algorithm = AES_CCM 1977 Key ID = 2 1988 TK = 40 cf b7 a6 2e 88 01 3b d6 d3 af fc c1 91 04 1e 1999 PN = 52624639632814 (0x2FDCA0F3A5AE) 20010 802.11 Header = b8 c8 dc 61 d9 57 7d f7 63 c8 b6 a8 8a df 36 91 20111 dc 4a 8b ca 94 dd 60 82 20 85 20212 Muted 802.11 Header = 88 c0 d9 57 7d f7 63 c8 b6 a8 8a df 36 91 20313 dc 4a 8b ca 94 dd 00 00 00 00 20414 CCMP Header = ae a5 00 a0 f3 a0 dc 2f 20515 CCM Nonce = 00 b6 a8 8a df 36 91 2f dc a0 f3 a5 ae 20616 Plaintext Data = 2c 1b d0 36 83 1c 95 49 6c 5f 4d bf 3d 55 9e 72 20717 de 80 2a 18 20818 CCM MIC = fd 1f 1f 61 a9 fb 4b b3 20919 -- Encrypted MPDU with FCS 21020 b8 c8 dc 61 d9 57 7d f7 63 c8 b6 a8 8a df 36 91 dc 4a 8b ca 94 dd 21121 60 82 20 85 ae a5 00 a0 f3 a0 dc 2f 89 d8 58 03 40 b6 26 a0 b6 d4 21222 d0 13 bf 18 f2 91 b8 96 46 c8 fd 1f 1f 61 a9 fb 4b b3 60 3f 5a ad 213*/ 214static 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}; 218static 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}; 225static 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 23925 Version = 0 24026 Type = 2 SubType = 10 24127 ToDS = 0 FromDS = 1 24228 MoreFrag = 0 Retry = 1 24329 PwrMgt = 0 moreData = 0 24430 Encrypt = 1 24531 Order = 1 24632 Duration = 4410 24733 A1 = 71-2a-9d-df-11-db DA 24834 A2 = 8e-f8-22-73-47-01 BSSID 24935 A3 = 59-14-0d-d6-46-a2 SA 25036 SC = 0x2FC0 25137 seqNum = 764 (0x02FC) fraqNum = 0 (0x00) 25238 QC = 0x0007 25339 MSDU Priority = 7 (0x0) 25440 Algorithm = AES_CCM 25541 Key ID = 0 25642 TK = 8c 89 a2 eb c9 6c 76 02 70 7f cf 24 b3 2d 38 33 25743 PN = 270963670912995 (0xF670A55A0FE3) 25844 802.11 Header = a8 ca 3a 11 71 2a 9d df 11 db 8e f8 22 73 47 01 25945 59 14 0d d6 46 a2 c0 2f 67 a5 26046 Muted 802.11 Header = 88 c2 71 2a 9d df 11 db 8e f8 22 73 47 01 26147 59 14 0d d6 46 a2 00 00 07 00 26248 CCMP Header = e3 0f 00 20 5a a5 70 f6 26349 CCM Nonce = 07 8e f8 22 73 47 01 f6 70 a5 5a 0f e3 26450 Plaintext Data = 4f ad 2b 1c 29 0f a5 eb d8 72 fb c3 f3 a0 74 89 26551 8f 8b 2f bb 26652 CCM MIC = 31 fc 88 00 4f 35 ee 3d 267-- Encrypted MPDU with FCS 2682 a8 ca 3a 11 71 2a 9d df 11 db 8e f8 22 73 47 01 59 14 0d d6 46 a2 2693 c0 2f 67 a5 e3 0f 00 20 5a a5 70 f6 9d 59 b1 5f 37 14 48 c2 30 f4 2704 d7 39 05 2e 13 ab 3b 1a 7b 10 31 fc 88 00 4f 35 ee 3d 45 a7 4a 30 271*/ 272static 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}; 276static 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}; 283static 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 2987 Version = 0 2998 Type = 2 SubType = 8 3009 ToDS = 0 FromDS = 1 30110 MoreFrag = 0 Retry = 1 30211 PwrMgt = 1 moreData = 0 30312 Encrypt = 1 30413 Order = 1 30514 Duration = 16664 30615 A1 = 45-de-c6-9a-74-80 DA 30716 A2 = f3-51-94-6b-c9-6b BSSID 30817 A3 = e2-76-fb-e6-c1-27 SA 30918 SC = 0xF280 31019 seqNum = 3880 (0x0F28) fraqNum = 0 (0x00) 31120 QC = 0x000b 31221 MSDU Priority = 0 (0x0) 31322 Algorithm = AES_CCM 31423 Key ID = 2 31524 TK = a5 74 d5 14 3b b2 5e fd de ff 30 12 2f df d0 66 31625 PN = 184717420531255 (0xA7FFE03C0E37) 31726 802.11 Header = 88 da 18 41 45 de c6 9a 74 80 f3 51 94 6b c9 6b 31827 e2 76 fb e6 c1 27 80 f2 4b 19 31928 Muted 802.11 Header = 88 c2 45 de c6 9a 74 80 f3 51 94 6b c9 6b 32029 e2 76 fb e6 c1 27 00 00 0b 00 32130 CCMP Header = 37 0e 00 a0 3c e0 ff a7 32231 CCM Nonce = 0b f3 51 94 6b c9 6b a7 ff e0 3c 0e 37 32332 Plaintext Data = 28 96 9b 95 4f 26 3a 80 18 a9 ef 70 a8 b0 51 46 32433 24 81 92 2e 32534 CCM MIC = ce 0c 3b e1 97 d3 05 eb 32635 -- Encrypted MPDU with FCS 32736 88 da 18 41 45 de c6 9a 74 80 f3 51 94 6b c9 6b e2 76 fb e6 c1 27 32837 80 f2 4b 19 37 0e 00 a0 3c e0 ff a7 eb 4a e4 95 6a 80 1d a9 62 4b 32938 7e 0c 18 b2 3e 61 5e c0 3a f6 ce 0c 3b e1 97 d3 05 eb c8 9e a1 b5 330*/ 331static 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}; 335static 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}; 342static 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 35741 Version = 0 35842 Type = 2 SubType = 8 35943 ToDS = 0 FromDS = 1 36044 MoreFrag = 0 Retry = 0 36145 PwrMgt = 1 moreData = 0 36246 Encrypt = 1 36347 Order = 0 36448 Duration = 8161 36549 A1 = 5a-f2-84-30-fd-ab DA 36650 A2 = bf-f9-43-b9-f9-a6 BSSID 3671 A3 = ab-1d-98-c7-fe-73 SA 3682 SC = 0x7150 3693 seqNum = 1813 (0x0715) fraqNum = 0 (0x00) 3704 QC = 0x000d 3715 PSDU Priority = 13 (0xd) 3726 Algorithm = AES_CCM 3737 Key ID = 1 3748 TK = f7 1e ea 4e 1f 58 80 4b 97 17 23 0a d0 61 46 41 3759 PN = 118205765159305 (0x6B81ECA48989) 37610 802.11 Header = 88 52 e1 1f 5a f2 84 30 fd ab bf f9 43 b9 f9 a6 37711 ab 1d 98 c7 fe 73 50 71 3d 6a 37812 Muted 802.11 Header = 88 42 5a f2 84 30 fd ab bf f9 43 b9 f9 a6 37913 ab 1d 98 c7 fe 73 00 00 0d 00 38014 CCMP Header = 89 89 00 60 a4 ec 81 6b 38115 CCM Nonce = 0d bf f9 43 b9 f9 a6 6b 81 ec a4 89 89 38216 Plaintext Data = ab fd a2 2d 3a 0b fc 9c c1 fc 07 93 63 c2 fc a1 38317 43 e6 eb 1d 38418 CCM MIC = 30 9a 8d 5c 46 6b bb 71 38519 -- Encrypted MPDU with FCS 38620 88 52 e1 1f 5a f2 84 30 fd ab bf f9 43 b9 f9 a6 ab 1d 98 c7 fe 73 38721 50 71 3d 6a 89 89 00 60 a4 ec 81 6b 9a 70 9b 60 a3 9d 40 b1 df b6 38822 12 e1 8b 5f 11 4b ad b6 cc 86 30 9a 8d 5c 46 6b bb 71 86 c0 4e 97 389*/ 390static 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}; 394static 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}; 401static 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 41625 Version = 0 41726 Type = 2 SubType = 1 Data+CF-Ack 41827 ToDS = 1 FromDS = 0 41928 MoreFrag = 0 Retry = 1 42029 PwrMgt = 1 moreData = 1 42130 Encrypt = 1 42231 Order = 0 42332 Duration = 18049 42433 A1 = 9b-50-f4-fd-56-f6 BSSID 42534 A2 = ef-ec-95-20-16-91 SA 42635 A3 = 83-57-0c-4c-cd-ee DA 42736 SC = 0xA020 42837 seqNum = 2562 (0x0A02) fraqNum = 0 (0x00) 42938 Algorithm = AES_CCM 43039 Key ID = 3 43140 TK = 1b db 34 98 0e 03 81 24 a1 db 1a 89 2b ec 36 6a 43241 PN = 104368786630435 (0x5EEC4073E723) 43342 Header = 18 79 81 46 9b 50 f4 fd 56 f6 ef ec 95 20 16 91 83 57 43443 0c 4c cd ee 20 a0 43544 Muted MAC Header = 08 41 9b 50 f4 fd 56 f6 ef ec 95 20 16 91 43645 83 57 0c 4c cd ee 00 00 43746 CCMP Header = 23 e7 00 e0 73 40 ec 5e 43847 CCM Nonce = 00 ef ec 95 20 16 91 5e ec 40 73 e7 23 43948 Plaintext Data = 98 be ca 86 f4 b3 8d a2 0c fd f2 47 24 c5 8e b8 44049 35 66 53 39 44150 CCM MIC = 2d 09 57 ec fa be 95 b9 442-- Encrypted MPDU with FCS 4431 18 79 81 46 9b 50 f4 fd 56 f6 ef ec 95 20 16 91 83 57 0c 4c cd ee 4442 20 a0 23 e7 00 e0 73 40 ec 5e 12 c5 37 eb f3 ab 58 4e f1 fe f9 a1 4453 f3 54 7a 8c 13 b3 22 5a 2d 09 57 ec fa be 95 b9 aa fa 0c c8 446*/ 447static 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}; 451static 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}; 458static 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 4726 Version = 0 4737 Type = 2 SubType = 11 4748 ToDS = 1 FromDS = 0 4759 MoreFrag = 0 Retry = 1 47610 PwrMgt = 1 moreData = 0 47711 Encrypt = 1 47812 Order = 1 47913 Duration = 29260 48014 A1 = 55-2d-5f-72-bb-70 BSSID 48115 A2 = ca-3f-3a-ae-60-c4 SA 48216 A3 = 8b-a9-b5-f8-2c-2f DA 48317 SC = 0xEB50 48418 seqNum = 3765 (0x0EB5) fraqNum = 0 (0x00) 48519 QC = 0x000a 48620 MSDU Priority = 10 (0xa) 48721 Algorithm = AES_CCM 48822 Key ID = 2 48923 TK = 6e ac 1b f5 4b d5 4e db 23 21 75 43 03 02 4c 71 49024 PN = 227588596223197 (0xCEFD996ECCDD) 49125 802.11 Header = b8 d9 4c 72 55 2d 5f 72 bb 70 ca 3f 3a ae 60 c4 49226 8b a9 b5 f8 2c 2f 50 eb 2a 55 49327 Muted 802.11 Header = 88 c1 55 2d 5f 72 bb 70 ca 3f 3a ae 60 c4 49428 8b a9 b5 f8 2c 2f 00 00 0a 00 49529 CCMP Header = dd cc 00 a0 6e 99 fd ce 49630 CCM Nonce = 0a ca 3f 3a ae 60 c4 ce fd 99 6e cc dd 49731 Plaintext Data = 57 cb 5c 0e 5f cd 88 5e 9a 42 39 e9 b9 ca d6 0d 49832 64 37 59 79 49933 CCM MIC = 6d ba 8e f7 f0 80 87 dd 500-- Encrypted MPDU with FCS 50135 b8 d9 4c 72 55 2d 5f 72 bb 70 ca 3f 3a ae 60 c4 8b a9 b5 f8 2c 2f 50236 50 eb 2a 55 dd cc 00 a0 6e 99 fd ce 4b f2 81 ef 8e c7 73 9f 91 59 50337 1b 97 a8 7d c1 4b 3f a1 74 62 6d ba 8e f7 f0 80 87 dd 0c 65 74 3f 504*/ 505static 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}; 509static 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}; 516static 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 533struct 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 555static void 556dumpdata(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 569static void 570cmpfail(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 583static void 584printtest(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 594static int 595runtest(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; 692bad: 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 703static int tests = -1; 704static int debug = 0; 705 706static int 707init_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 = ⁣ 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 743static int 744test_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 756static moduledata_t test_ccmp_mod = { 757 "test_ccmp", 758 test_ccmp_modevent, 759 0 760}; 761DECLARE_MODULE(test_ccmp, test_ccmp_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST); 762MODULE_VERSION(test_ccmp, 1); 763MODULE_DEPEND(test_ccmp, wlan, 1, 1, 1); 764