aes_ccmp.c revision 659b4d97fff5c9acb8596d85777ae0023e2539b8
1/* 2 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. 3 * All rights reserved. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * 20 * File: aes_ccmp.c 21 * 22 * Purpose: AES_CCMP decryption 23 * 24 * Author: Warren Hsu 25 * 26 * Date: Feb 15, 2005 27 * 28 * Functions: 29 * AESbGenCCMP - Parsing RX-packet 30 * 31 * 32 * Revision History: 33 * 34 */ 35 36#include "device.h" 37#include "80211hdr.h" 38 39/*--------------------- Static Definitions -------------------------*/ 40 41/*--------------------- Static Classes ----------------------------*/ 42 43/*--------------------- Static Variables --------------------------*/ 44 45/* 46 * SBOX Table 47 */ 48 49unsigned char sbox_table[256] = 50{ 51 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 52 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 53 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 54 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 55 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 56 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 57 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 58 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 59 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 60 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 61 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 62 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 63 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 64 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 65 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 66 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 67}; 68 69unsigned char dot2_table[256] = { 70 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, 71 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 72 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, 73 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e, 74 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, 75 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, 76 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, 77 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, 78 0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05, 79 0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25, 80 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45, 81 0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65, 82 0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85, 83 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, 84 0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5, 85 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5 86}; 87 88unsigned char dot3_table[256] = { 89 0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11, 90 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, 91 0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71, 92 0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41, 93 0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1, 94 0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1, 95 0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1, 96 0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81, 97 0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a, 98 0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba, 99 0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea, 100 0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda, 101 0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a, 102 0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a, 103 0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a, 104 0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a 105}; 106 107/*--------------------- Static Functions --------------------------*/ 108 109/*--------------------- Export Variables --------------------------*/ 110 111/*--------------------- Export Functions --------------------------*/ 112 113void xor_128(unsigned char *a, unsigned char *b, unsigned char *out) 114{ 115 unsigned long *dwPtrA = (unsigned long *)a; 116 unsigned long *dwPtrB = (unsigned long *)b; 117 unsigned long *dwPtrOut = (unsigned long *)out; 118 119 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); 120 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); 121 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); 122 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); 123} 124 125 126void xor_32(unsigned char *a, unsigned char *b, unsigned char *out) 127{ 128 unsigned long *dwPtrA = (unsigned long *)a; 129 unsigned long *dwPtrB = (unsigned long *)b; 130 unsigned long *dwPtrOut = (unsigned long *)out; 131 132 (*dwPtrOut++) = (*dwPtrA++) ^ (*dwPtrB++); 133} 134 135void AddRoundKey(unsigned char *key, int round) 136{ 137 unsigned char sbox_key[4]; 138 unsigned char rcon_table[10] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36}; 139 140 sbox_key[0] = sbox_table[key[13]]; 141 sbox_key[1] = sbox_table[key[14]]; 142 sbox_key[2] = sbox_table[key[15]]; 143 sbox_key[3] = sbox_table[key[12]]; 144 145 key[0] = key[0] ^ rcon_table[round]; 146 xor_32(&key[0], sbox_key, &key[0]); 147 148 xor_32(&key[4], &key[0], &key[4]); 149 xor_32(&key[8], &key[4], &key[8]); 150 xor_32(&key[12], &key[8], &key[12]); 151} 152 153void SubBytes(unsigned char *in, unsigned char *out) 154{ 155 int i; 156 157 for (i = 0; i < 16; i++) 158 { 159 out[i] = sbox_table[in[i]]; 160 } 161} 162 163void ShiftRows(unsigned char *in, unsigned char *out) 164{ 165 out[0] = in[0]; 166 out[1] = in[5]; 167 out[2] = in[10]; 168 out[3] = in[15]; 169 out[4] = in[4]; 170 out[5] = in[9]; 171 out[6] = in[14]; 172 out[7] = in[3]; 173 out[8] = in[8]; 174 out[9] = in[13]; 175 out[10] = in[2]; 176 out[11] = in[7]; 177 out[12] = in[12]; 178 out[13] = in[1]; 179 out[14] = in[6]; 180 out[15] = in[11]; 181} 182 183void MixColumns(unsigned char *in, unsigned char *out) 184{ 185 186 out[0] = dot2_table[in[0]] ^ dot3_table[in[1]] ^ in[2] ^ in[3]; 187 out[1] = in[0] ^ dot2_table[in[1]] ^ dot3_table[in[2]] ^ in[3]; 188 out[2] = in[0] ^ in[1] ^ dot2_table[in[2]] ^ dot3_table[in[3]]; 189 out[3] = dot3_table[in[0]] ^ in[1] ^ in[2] ^ dot2_table[in[3]]; 190} 191 192 193void AESv128(unsigned char *key, unsigned char *data, unsigned char *ciphertext) 194{ 195 int i; 196 int round; 197 unsigned char TmpdataA[16]; 198 unsigned char TmpdataB[16]; 199 unsigned char abyRoundKey[16]; 200 201 for (i = 0; i < 16; i++) 202 abyRoundKey[i] = key[i]; 203 204 for (round = 0; round < 11; round++) 205 { 206 if (round == 0) 207 { 208 xor_128(abyRoundKey, data, ciphertext); 209 AddRoundKey(abyRoundKey, round); 210 } 211 else if (round == 10) 212 { 213 SubBytes(ciphertext, TmpdataA); 214 ShiftRows(TmpdataA, TmpdataB); 215 xor_128(TmpdataB, abyRoundKey, ciphertext); 216 } 217 else // round 1 ~ 9 218 { 219 SubBytes(ciphertext, TmpdataA); 220 ShiftRows(TmpdataA, TmpdataB); 221 MixColumns(&TmpdataB[0], &TmpdataA[0]); 222 MixColumns(&TmpdataB[4], &TmpdataA[4]); 223 MixColumns(&TmpdataB[8], &TmpdataA[8]); 224 MixColumns(&TmpdataB[12], &TmpdataA[12]); 225 xor_128(TmpdataA, abyRoundKey, ciphertext); 226 AddRoundKey(abyRoundKey, round); 227 } 228 } 229 230} 231 232/* 233 * Description: AES decryption 234 * 235 * Parameters: 236 * In: 237 * pbyRxKey - The key used to decrypt 238 * pbyFrame - Starting address of packet header 239 * wFrameSize - Total packet size including CRC 240 * Out: 241 * none 242 * 243 * Return Value: MIC compare result 244 * 245 */ 246bool AESbGenCCMP(unsigned char *pbyRxKey, unsigned char *pbyFrame, unsigned short wFrameSize) 247{ 248 unsigned char abyNonce[13]; 249 unsigned char MIC_IV[16]; 250 unsigned char MIC_HDR1[16]; 251 unsigned char MIC_HDR2[16]; 252 unsigned char abyMIC[16]; 253 unsigned char abyCTRPLD[16]; 254 unsigned char abyTmp[16]; 255 unsigned char abyPlainText[16]; 256 unsigned char abyLastCipher[16]; 257 258 PS802_11Header pMACHeader = (PS802_11Header) pbyFrame; 259 unsigned char *pbyIV; 260 unsigned char *pbyPayload; 261 unsigned short wHLen = 22; 262 unsigned short wPayloadSize = wFrameSize - 8 - 8 - 4 - WLAN_HDR_ADDR3_LEN;//8 is IV, 8 is MIC, 4 is CRC 263 bool bA4 = false; 264 unsigned char byTmp; 265 unsigned short wCnt; 266 int ii, jj, kk; 267 268 269 pbyIV = pbyFrame + WLAN_HDR_ADDR3_LEN; 270 if (WLAN_GET_FC_TODS(*(unsigned short *)pbyFrame) && 271 WLAN_GET_FC_FROMDS(*(unsigned short *)pbyFrame)) { 272 bA4 = true; 273 pbyIV += 6; // 6 is 802.11 address4 274 wHLen += 6; 275 wPayloadSize -= 6; 276 } 277 pbyPayload = pbyIV + 8; //IV-length 278 279 abyNonce[0] = 0x00; //now is 0, if Qos here will be priority 280 memcpy(&(abyNonce[1]), pMACHeader->abyAddr2, ETH_ALEN); 281 abyNonce[7] = pbyIV[7]; 282 abyNonce[8] = pbyIV[6]; 283 abyNonce[9] = pbyIV[5]; 284 abyNonce[10] = pbyIV[4]; 285 abyNonce[11] = pbyIV[1]; 286 abyNonce[12] = pbyIV[0]; 287 288 //MIC_IV 289 MIC_IV[0] = 0x59; 290 memcpy(&(MIC_IV[1]), &(abyNonce[0]), 13); 291 MIC_IV[14] = (unsigned char)(wPayloadSize >> 8); 292 MIC_IV[15] = (unsigned char)(wPayloadSize & 0xff); 293 294 //MIC_HDR1 295 MIC_HDR1[0] = (unsigned char)(wHLen >> 8); 296 MIC_HDR1[1] = (unsigned char)(wHLen & 0xff); 297 byTmp = (unsigned char)(pMACHeader->wFrameCtl & 0xff); 298 MIC_HDR1[2] = byTmp & 0x8f; 299 byTmp = (unsigned char)(pMACHeader->wFrameCtl >> 8); 300 byTmp &= 0x87; 301 MIC_HDR1[3] = byTmp | 0x40; 302 memcpy(&(MIC_HDR1[4]), pMACHeader->abyAddr1, ETH_ALEN); 303 memcpy(&(MIC_HDR1[10]), pMACHeader->abyAddr2, ETH_ALEN); 304 305 //MIC_HDR2 306 memcpy(&(MIC_HDR2[0]), pMACHeader->abyAddr3, ETH_ALEN); 307 byTmp = (unsigned char)(pMACHeader->wSeqCtl & 0xff); 308 MIC_HDR2[6] = byTmp & 0x0f; 309 MIC_HDR2[7] = 0; 310 if (bA4) { 311 memcpy(&(MIC_HDR2[8]), pMACHeader->abyAddr4, ETH_ALEN); 312 } else { 313 MIC_HDR2[8] = 0x00; 314 MIC_HDR2[9] = 0x00; 315 MIC_HDR2[10] = 0x00; 316 MIC_HDR2[11] = 0x00; 317 MIC_HDR2[12] = 0x00; 318 MIC_HDR2[13] = 0x00; 319 } 320 MIC_HDR2[14] = 0x00; 321 MIC_HDR2[15] = 0x00; 322 323 //CCMP 324 AESv128(pbyRxKey, MIC_IV, abyMIC); 325 for (kk = 0; kk < 16; kk++) { 326 abyTmp[kk] = MIC_HDR1[kk] ^ abyMIC[kk]; 327 } 328 AESv128(pbyRxKey, abyTmp, abyMIC); 329 for (kk = 0; kk < 16; kk++) { 330 abyTmp[kk] = MIC_HDR2[kk] ^ abyMIC[kk]; 331 } 332 AESv128(pbyRxKey, abyTmp, abyMIC); 333 334 wCnt = 1; 335 abyCTRPLD[0] = 0x01; 336 memcpy(&(abyCTRPLD[1]), &(abyNonce[0]), 13); 337 338 for (jj = wPayloadSize; jj > 16; jj = jj - 16) { 339 340 abyCTRPLD[14] = (unsigned char)(wCnt >> 8); 341 abyCTRPLD[15] = (unsigned char)(wCnt & 0xff); 342 343 AESv128(pbyRxKey, abyCTRPLD, abyTmp); 344 345 for (kk = 0; kk < 16; kk++) { 346 abyPlainText[kk] = abyTmp[kk] ^ pbyPayload[kk]; 347 } 348 for (kk = 0; kk < 16; kk++) { 349 abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk]; 350 } 351 AESv128(pbyRxKey, abyTmp, abyMIC); 352 353 memcpy(pbyPayload, abyPlainText, 16); 354 wCnt++; 355 pbyPayload += 16; 356 } //for wPayloadSize 357 358 //last payload 359 memcpy(&(abyLastCipher[0]), pbyPayload, jj); 360 for (ii = jj; ii < 16; ii++) { 361 abyLastCipher[ii] = 0x00; 362 } 363 364 abyCTRPLD[14] = (unsigned char)(wCnt >> 8); 365 abyCTRPLD[15] = (unsigned char)(wCnt & 0xff); 366 367 AESv128(pbyRxKey, abyCTRPLD, abyTmp); 368 for (kk = 0; kk < 16; kk++) { 369 abyPlainText[kk] = abyTmp[kk] ^ abyLastCipher[kk]; 370 } 371 memcpy(pbyPayload, abyPlainText, jj); 372 pbyPayload += jj; 373 374 //for MIC calculation 375 for (ii = jj; ii < 16; ii++) { 376 abyPlainText[ii] = 0x00; 377 } 378 for (kk = 0; kk < 16; kk++) { 379 abyTmp[kk] = abyMIC[kk] ^ abyPlainText[kk]; 380 } 381 AESv128(pbyRxKey, abyTmp, abyMIC); 382 383 //=>above is the calculate MIC 384 //-------------------------------------------- 385 386 wCnt = 0; 387 abyCTRPLD[14] = (unsigned char)(wCnt >> 8); 388 abyCTRPLD[15] = (unsigned char)(wCnt & 0xff); 389 AESv128(pbyRxKey, abyCTRPLD, abyTmp); 390 for (kk = 0; kk < 8; kk++) { 391 abyTmp[kk] = abyTmp[kk] ^ pbyPayload[kk]; 392 } 393 //=>above is the dec-MIC from packet 394 //-------------------------------------------- 395 396 if (!memcmp(abyMIC, abyTmp, 8)) { 397 return true; 398 } else { 399 return false; 400 } 401 402} 403