1008 lines
48 KiB
C
1008 lines
48 KiB
C
|
/*
|
||
|
*************************************************************************
|
||
|
* Ralink Tech Inc.
|
||
|
* 5F., No.36, Taiyuan St., Jhubei City,
|
||
|
* Hsinchu County 302,
|
||
|
* Taiwan, R.O.C.
|
||
|
*
|
||
|
* (c) Copyright 2002-2007, Ralink Technology, Inc.
|
||
|
*
|
||
|
* This program is free software; you can redistribute it and/or modify *
|
||
|
* it under the terms of the GNU General Public License as published by *
|
||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||
|
* (at your option) any later version. *
|
||
|
* *
|
||
|
* This program is distributed in the hope that it will be useful, *
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||
|
* GNU General Public License for more details. *
|
||
|
* *
|
||
|
* You should have received a copy of the GNU General Public License *
|
||
|
* along with this program; if not, write to the *
|
||
|
* Free Software Foundation, Inc., *
|
||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||
|
* *
|
||
|
*************************************************************************
|
||
|
|
||
|
Module Name:
|
||
|
crypt_aes.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Revision History:
|
||
|
Who When What
|
||
|
-------- ---------- ----------------------------------------------
|
||
|
Eddy 2009/01/19 Create AES-128, AES-192, AES-256, AES-CBC
|
||
|
*/
|
||
|
|
||
|
#include "crypt_aes.h"
|
||
|
|
||
|
/* The value given by [x^(i-1),{00},{00},{00}], with x^(i-1) being powers of x in the field GF(2^8). */
|
||
|
static const UINT32 aes_rcon[] = {
|
||
|
0x00000000, 0x01000000, 0x02000000, 0x04000000,
|
||
|
0x08000000, 0x10000000, 0x20000000, 0x40000000,
|
||
|
0x80000000, 0x1B000000, 0x36000000};
|
||
|
|
||
|
static const UINT8 aes_sbox_enc[] = {
|
||
|
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
|
||
|
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7 ,0xab, 0x76, /* 0 */
|
||
|
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4 ,0x72, 0xc0, /* 1 */
|
||
|
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8 ,0x31, 0x15, /* 2 */
|
||
|
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27 ,0xb2, 0x75, /* 3 */
|
||
|
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3 ,0x2f, 0x84, /* 4 */
|
||
|
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c ,0x58, 0xcf, /* 5 */
|
||
|
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c ,0x9f, 0xa8, /* 6 */
|
||
|
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff ,0xf3, 0xd2, /* 7 */
|
||
|
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d ,0x19, 0x73, /* 8 */
|
||
|
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e ,0x0b, 0xdb, /* 9 */
|
||
|
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95 ,0xe4, 0x79, /* a */
|
||
|
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a ,0xae, 0x08, /* b */
|
||
|
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd ,0x8b, 0x8a, /* c */
|
||
|
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1 ,0x1d, 0x9e, /* d */
|
||
|
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55 ,0x28, 0xdf, /* e */
|
||
|
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54 ,0xbb, 0x16, /* f */
|
||
|
};
|
||
|
|
||
|
static const UINT8 aes_sbox_dec[] = {
|
||
|
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
|
||
|
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, /* 0 */
|
||
|
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, /* 1 */
|
||
|
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, /* 2 */
|
||
|
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, /* 3 */
|
||
|
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, /* 4 */
|
||
|
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, /* 5 */
|
||
|
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, /* 6 */
|
||
|
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, /* 7 */
|
||
|
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, /* 8 */
|
||
|
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, /* 9 */
|
||
|
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, /* a */
|
||
|
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, /* b */
|
||
|
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, /* c */
|
||
|
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, /* d */
|
||
|
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, /* e */
|
||
|
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d, /* f */
|
||
|
};
|
||
|
|
||
|
/* ArrayIndex*{02} */
|
||
|
static const UINT8 aes_mul_2[] = {
|
||
|
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
|
||
|
0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, /* 0 */
|
||
|
0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, /* 1 */
|
||
|
0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, /* 2 */
|
||
|
0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e, /* 3 */
|
||
|
0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, /* 4 */
|
||
|
0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, /* 5 */
|
||
|
0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, /* 6 */
|
||
|
0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, /* 7 */
|
||
|
0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05, /* 8 */
|
||
|
0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25, /* 9 */
|
||
|
0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45, /* a */
|
||
|
0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65, /* b */
|
||
|
0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85, /* c */
|
||
|
0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, /* d */
|
||
|
0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5, /* e */
|
||
|
0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5, /* f */
|
||
|
};
|
||
|
|
||
|
/* ArrayIndex*{03} */
|
||
|
static const UINT8 aes_mul_3[] = {
|
||
|
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
|
||
|
0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11, /* 0 */
|
||
|
0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, /* 1 */
|
||
|
0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71, /* 2 */
|
||
|
0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41, /* 3 */
|
||
|
0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1, /* 4 */
|
||
|
0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1, /* 5 */
|
||
|
0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1, /* 6 */
|
||
|
0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81, /* 7 */
|
||
|
0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a, /* 8 */
|
||
|
0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba, /* 9 */
|
||
|
0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea, /* a */
|
||
|
0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda, /* b */
|
||
|
0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a, /* c */
|
||
|
0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a, /* d */
|
||
|
0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a, /* e */
|
||
|
0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a, /* f */
|
||
|
};
|
||
|
|
||
|
/* ArrayIndex*{09} */
|
||
|
static const UINT8 aes_mul_9[] = {
|
||
|
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
|
||
|
0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77, /* 0 */
|
||
|
0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7, /* 1 */
|
||
|
0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c, /* 2 */
|
||
|
0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc, /* 3 */
|
||
|
0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49, 0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01, /* 4 */
|
||
|
0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91, /* 5 */
|
||
|
0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a, /* 6 */
|
||
|
0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2, 0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa, /* 7 */
|
||
|
0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b, /* 8 */
|
||
|
0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b, /* 9 */
|
||
|
0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8, 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0, /* a */
|
||
|
0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30, /* b */
|
||
|
0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed, /* c */
|
||
|
0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35, 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d, /* d */
|
||
|
0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6, /* e */
|
||
|
0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46, /* f */
|
||
|
};
|
||
|
|
||
|
/* ArrayIndex*{0b} */
|
||
|
static const UINT8 aes_mul_b[] = {
|
||
|
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
|
||
|
0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69, /* 0 */
|
||
|
0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9, /* 1 */
|
||
|
0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12, /* 2 */
|
||
|
0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2, /* 3 */
|
||
|
0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7, 0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f, /* 4 */
|
||
|
0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f, /* 5 */
|
||
|
0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4, /* 6 */
|
||
|
0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c, 0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54, /* 7 */
|
||
|
0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e, /* 8 */
|
||
|
0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e, /* 9 */
|
||
|
0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd, 0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5, /* a */
|
||
|
0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55, /* b */
|
||
|
0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68, /* c */
|
||
|
0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8, /* d */
|
||
|
0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13, /* e */
|
||
|
0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3, /* f */
|
||
|
};
|
||
|
|
||
|
/* ArrayIndex*{0d} */
|
||
|
static const UINT8 aes_mul_d[] = {
|
||
|
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
|
||
|
0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b, /* 0 */
|
||
|
0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b, /* 1 */
|
||
|
0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0, /* 2 */
|
||
|
0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20, /* 3 */
|
||
|
0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e, 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26, /* 4 */
|
||
|
0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6, /* 5 */
|
||
|
0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d, /* 6 */
|
||
|
0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25, 0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d, /* 7 */
|
||
|
0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91, /* 8 */
|
||
|
0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41, /* 9 */
|
||
|
0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42, 0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a, /* a */
|
||
|
0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa, /* b */
|
||
|
0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc, /* c */
|
||
|
0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c, /* d */
|
||
|
0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47, /* e */
|
||
|
0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97, /* f */
|
||
|
};
|
||
|
|
||
|
/* ArrayIndex*{0e} */
|
||
|
static const UINT8 aes_mul_e[] = {
|
||
|
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
|
||
|
0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a, /* 0 */
|
||
|
0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba, /* 1 */
|
||
|
0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81, /* 2 */
|
||
|
0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61, /* 3 */
|
||
|
0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87, 0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7, /* 4 */
|
||
|
0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17, /* 5 */
|
||
|
0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c, /* 6 */
|
||
|
0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc, 0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc, /* 7 */
|
||
|
0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b, /* 8 */
|
||
|
0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb, /* 9 */
|
||
|
0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0, 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0, /* a */
|
||
|
0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20, /* b */
|
||
|
0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6, /* c */
|
||
|
0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56, /* d */
|
||
|
0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d, /* e */
|
||
|
0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d, /* f */
|
||
|
};
|
||
|
|
||
|
|
||
|
/* For AES_CMAC */
|
||
|
#define AES_MAC_LENGTH 16 /* 128-bit string */
|
||
|
static UINT8 Const_Zero[16] = {
|
||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||
|
static UINT8 Const_Rb[16] = {
|
||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87};
|
||
|
|
||
|
|
||
|
/*
|
||
|
========================================================================
|
||
|
Routine Description:
|
||
|
AES key expansion (key schedule)
|
||
|
|
||
|
Arguments:
|
||
|
Key Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits)
|
||
|
KeyLength The length of cipher key in bytes
|
||
|
paes_ctx Pointer to AES_CTX_STRUC
|
||
|
|
||
|
Return Value:
|
||
|
paes_ctx Retrun the KeyWordExpansion of AES_CTX_STRUC
|
||
|
|
||
|
Note:
|
||
|
Pseudo code for key expansion
|
||
|
------------------------------------------
|
||
|
Nk = (key length/4);
|
||
|
|
||
|
while (i < Nk)
|
||
|
KeyWordExpansion[i] = word(key[4*i], key[4*i + 1], key[4*i + 2], key[4*i + 3]);
|
||
|
i++;
|
||
|
end while
|
||
|
|
||
|
while (i < ((key length/4 + 6 + 1)*4) )
|
||
|
temp = KeyWordExpansion[i - 1];
|
||
|
if (i % Nk ==0)
|
||
|
temp = SubWord(RotWord(temp)) ^ Rcon[i/Nk];
|
||
|
else if ((Nk > 6) && (i % 4 == 4))
|
||
|
temp = SubWord(temp);
|
||
|
end if
|
||
|
|
||
|
KeyWordExpansion[i] = KeyWordExpansion[i - Nk]^ temp;
|
||
|
i++;
|
||
|
end while
|
||
|
========================================================================
|
||
|
*/
|
||
|
VOID AES_KeyExpansion (
|
||
|
IN UINT8 Key[],
|
||
|
IN UINT KeyLength,
|
||
|
INOUT AES_CTX_STRUC *paes_ctx)
|
||
|
{
|
||
|
UINT KeyIndex = 0;
|
||
|
UINT NumberOfWordOfKey, NumberOfWordOfKeyExpansion;
|
||
|
UINT8 TempWord[AES_KEY_ROWS], Temp;
|
||
|
UINT32 Temprcon;
|
||
|
|
||
|
NumberOfWordOfKey = KeyLength >> 2;
|
||
|
while (KeyIndex < NumberOfWordOfKey)
|
||
|
{
|
||
|
paes_ctx->KeyWordExpansion[0][KeyIndex] = Key[4*KeyIndex];
|
||
|
paes_ctx->KeyWordExpansion[1][KeyIndex] = Key[4*KeyIndex + 1];
|
||
|
paes_ctx->KeyWordExpansion[2][KeyIndex] = Key[4*KeyIndex + 2];
|
||
|
paes_ctx->KeyWordExpansion[3][KeyIndex] = Key[4*KeyIndex + 3];
|
||
|
KeyIndex++;
|
||
|
} /* End of while */
|
||
|
|
||
|
NumberOfWordOfKeyExpansion = ((UINT) AES_KEY_ROWS) * ((KeyLength >> 2) + 6 + 1);
|
||
|
while (KeyIndex < NumberOfWordOfKeyExpansion)
|
||
|
{
|
||
|
TempWord[0] = paes_ctx->KeyWordExpansion[0][KeyIndex - 1];
|
||
|
TempWord[1] = paes_ctx->KeyWordExpansion[1][KeyIndex - 1];
|
||
|
TempWord[2] = paes_ctx->KeyWordExpansion[2][KeyIndex - 1];
|
||
|
TempWord[3] = paes_ctx->KeyWordExpansion[3][KeyIndex - 1];
|
||
|
if ((KeyIndex % NumberOfWordOfKey) == 0) {
|
||
|
Temprcon = aes_rcon[KeyIndex/NumberOfWordOfKey];
|
||
|
Temp = aes_sbox_enc[TempWord[1]]^((Temprcon >> 24) & 0xff);
|
||
|
TempWord[1] = aes_sbox_enc[TempWord[2]]^((Temprcon >> 16) & 0xff);
|
||
|
TempWord[2] = aes_sbox_enc[TempWord[3]]^((Temprcon >> 8) & 0xff);
|
||
|
TempWord[3] = aes_sbox_enc[TempWord[0]]^((Temprcon ) & 0xff);
|
||
|
TempWord[0] = Temp;
|
||
|
} else if ((NumberOfWordOfKey > 6) && ((KeyIndex % NumberOfWordOfKey) == 4)) {
|
||
|
Temp = aes_sbox_enc[TempWord[0]];
|
||
|
TempWord[1] = aes_sbox_enc[TempWord[1]];
|
||
|
TempWord[2] = aes_sbox_enc[TempWord[2]];
|
||
|
TempWord[3] = aes_sbox_enc[TempWord[3]];
|
||
|
TempWord[0] = Temp;
|
||
|
}
|
||
|
paes_ctx->KeyWordExpansion[0][KeyIndex] = paes_ctx->KeyWordExpansion[0][KeyIndex - NumberOfWordOfKey]^TempWord[0];
|
||
|
paes_ctx->KeyWordExpansion[1][KeyIndex] = paes_ctx->KeyWordExpansion[1][KeyIndex - NumberOfWordOfKey]^TempWord[1];
|
||
|
paes_ctx->KeyWordExpansion[2][KeyIndex] = paes_ctx->KeyWordExpansion[2][KeyIndex - NumberOfWordOfKey]^TempWord[2];
|
||
|
paes_ctx->KeyWordExpansion[3][KeyIndex] = paes_ctx->KeyWordExpansion[3][KeyIndex - NumberOfWordOfKey]^TempWord[3];
|
||
|
KeyIndex++;
|
||
|
} /* End of while */
|
||
|
} /* End of AES_KeyExpansion */
|
||
|
|
||
|
|
||
|
/*
|
||
|
========================================================================
|
||
|
Routine Description:
|
||
|
AES encryption
|
||
|
|
||
|
Arguments:
|
||
|
PlainBlock The block of plain text, 16 bytes(128 bits) each block
|
||
|
PlainBlockSize The length of block of plain text in bytes
|
||
|
Key Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits)
|
||
|
KeyLength The length of cipher key in bytes
|
||
|
CipherBlockSize The length of allocated cipher block in bytes
|
||
|
|
||
|
Return Value:
|
||
|
CipherBlock Return cipher text
|
||
|
CipherBlockSize Return the length of real used cipher block in bytes
|
||
|
|
||
|
Note:
|
||
|
Reference to FIPS-PUB 197
|
||
|
1. Check if block size is 16 bytes(128 bits) and if key length is 16, 24, or 32 bytes(128, 192, or 256 bits)
|
||
|
2. Transfer the plain block to state block
|
||
|
3. Main encryption rounds
|
||
|
4. Transfer the state block to cipher block
|
||
|
------------------------------------------
|
||
|
NumberOfRound = (key length / 4) + 6;
|
||
|
state block = plain block;
|
||
|
|
||
|
AddRoundKey(state block, key);
|
||
|
for round = 1 to NumberOfRound
|
||
|
SubBytes(state block)
|
||
|
ShiftRows(state block)
|
||
|
MixColumns(state block)
|
||
|
AddRoundKey(state block, key);
|
||
|
end for
|
||
|
|
||
|
SubBytes(state block)
|
||
|
ShiftRows(state block)
|
||
|
AddRoundKey(state block, key);
|
||
|
|
||
|
cipher block = state block;
|
||
|
========================================================================
|
||
|
*/
|
||
|
VOID AES_Encrypt (
|
||
|
IN UINT8 PlainBlock[],
|
||
|
IN UINT PlainBlockSize,
|
||
|
IN UINT8 Key[],
|
||
|
IN UINT KeyLength,
|
||
|
OUT UINT8 CipherBlock[],
|
||
|
INOUT UINT *CipherBlockSize)
|
||
|
{
|
||
|
AES_CTX_STRUC aes_ctx;
|
||
|
UINT RowIndex, ColumnIndex;
|
||
|
UINT RoundIndex, NumberOfRound = 0;
|
||
|
UINT8 Temp, Row0, Row1, Row2, Row3;
|
||
|
|
||
|
/*
|
||
|
* 1. Check if block size is 16 bytes(128 bits) and if key length is 16, 24, or 32 bytes(128, 192, or 256 bits)
|
||
|
*/
|
||
|
if (PlainBlockSize != AES_BLOCK_SIZES) {
|
||
|
DBGPRINT(RT_DEBUG_ERROR, ("AES_Encrypt: plain block size is %d bytes, it must be %d bytes(128 bits).\n",
|
||
|
PlainBlockSize, AES_BLOCK_SIZES));
|
||
|
return;
|
||
|
} /* End of if */
|
||
|
if ((KeyLength != AES_KEY128_LENGTH) && (KeyLength != AES_KEY192_LENGTH) && (KeyLength != AES_KEY256_LENGTH)) {
|
||
|
DBGPRINT(RT_DEBUG_ERROR, ("AES_Encrypt: key length is %d bytes, it must be %d, %d, or %d bytes(128, 192, or 256 bits).\n",
|
||
|
KeyLength, AES_KEY128_LENGTH, AES_KEY192_LENGTH, AES_KEY256_LENGTH));
|
||
|
return;
|
||
|
} /* End of if */
|
||
|
if (*CipherBlockSize < AES_BLOCK_SIZES) {
|
||
|
DBGPRINT(RT_DEBUG_ERROR, ("AES_Encrypt: cipher block size is %d bytes, it must be %d bytes(128 bits).\n",
|
||
|
*CipherBlockSize, AES_BLOCK_SIZES));
|
||
|
return;
|
||
|
} /* End of if */
|
||
|
|
||
|
/*
|
||
|
* 2. Transfer the plain block to state block
|
||
|
*/
|
||
|
for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
|
||
|
for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
|
||
|
aes_ctx.State[RowIndex][ColumnIndex] = PlainBlock[RowIndex + 4*ColumnIndex];
|
||
|
|
||
|
/*
|
||
|
* 3. Main encryption rounds
|
||
|
*/
|
||
|
AES_KeyExpansion(Key, KeyLength, &aes_ctx);
|
||
|
NumberOfRound = (KeyLength >> 2) + 6;
|
||
|
|
||
|
/* AES_AddRoundKey */
|
||
|
RoundIndex = 0;
|
||
|
for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
|
||
|
for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
|
||
|
aes_ctx.State[RowIndex][ColumnIndex] ^= aes_ctx.KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex];
|
||
|
|
||
|
for (RoundIndex = 1; RoundIndex < NumberOfRound;RoundIndex++)
|
||
|
{
|
||
|
/* AES_SubBytes */
|
||
|
for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
|
||
|
for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
|
||
|
aes_ctx.State[RowIndex][ColumnIndex] = aes_sbox_enc[aes_ctx.State[RowIndex][ColumnIndex]];
|
||
|
|
||
|
/* AES_ShiftRows */
|
||
|
Temp = aes_ctx.State[1][0];
|
||
|
aes_ctx.State[1][0] = aes_ctx.State[1][1];
|
||
|
aes_ctx.State[1][1] = aes_ctx.State[1][2];
|
||
|
aes_ctx.State[1][2] = aes_ctx.State[1][3];
|
||
|
aes_ctx.State[1][3] = Temp;
|
||
|
Temp = aes_ctx.State[2][0];
|
||
|
aes_ctx.State[2][0] = aes_ctx.State[2][2];
|
||
|
aes_ctx.State[2][2] = Temp;
|
||
|
Temp = aes_ctx.State[2][1];
|
||
|
aes_ctx.State[2][1] = aes_ctx.State[2][3];
|
||
|
aes_ctx.State[2][3] = Temp;
|
||
|
Temp = aes_ctx.State[3][3];
|
||
|
aes_ctx.State[3][3] = aes_ctx.State[3][2];
|
||
|
aes_ctx.State[3][2] = aes_ctx.State[3][1];
|
||
|
aes_ctx.State[3][1] = aes_ctx.State[3][0];
|
||
|
aes_ctx.State[3][0] = Temp;
|
||
|
|
||
|
/* AES_MixColumns */
|
||
|
for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
|
||
|
{
|
||
|
Row0 = aes_ctx.State[0][ColumnIndex];
|
||
|
Row1 = aes_ctx.State[1][ColumnIndex];
|
||
|
Row2 = aes_ctx.State[2][ColumnIndex];
|
||
|
Row3 = aes_ctx.State[3][ColumnIndex];
|
||
|
aes_ctx.State[0][ColumnIndex] = aes_mul_2[Row0]^aes_mul_3[Row1]^Row2^Row3;
|
||
|
aes_ctx.State[1][ColumnIndex] = Row0^aes_mul_2[Row1]^aes_mul_3[Row2]^Row3;
|
||
|
aes_ctx.State[2][ColumnIndex] = Row0^Row1^aes_mul_2[Row2]^aes_mul_3[Row3];
|
||
|
aes_ctx.State[3][ColumnIndex] = aes_mul_3[Row0]^Row1^Row2^aes_mul_2[Row3];
|
||
|
}
|
||
|
|
||
|
/* AES_AddRoundKey */
|
||
|
for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
|
||
|
for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
|
||
|
aes_ctx.State[RowIndex][ColumnIndex] ^= aes_ctx.KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex];
|
||
|
} /* End of for */
|
||
|
|
||
|
/* AES_SubBytes */
|
||
|
for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
|
||
|
for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
|
||
|
aes_ctx.State[RowIndex][ColumnIndex] = aes_sbox_enc[aes_ctx.State[RowIndex][ColumnIndex]];
|
||
|
/* AES_ShiftRows */
|
||
|
Temp = aes_ctx.State[1][0];
|
||
|
aes_ctx.State[1][0] = aes_ctx.State[1][1];
|
||
|
aes_ctx.State[1][1] = aes_ctx.State[1][2];
|
||
|
aes_ctx.State[1][2] = aes_ctx.State[1][3];
|
||
|
aes_ctx.State[1][3] = Temp;
|
||
|
Temp = aes_ctx.State[2][0];
|
||
|
aes_ctx.State[2][0] = aes_ctx.State[2][2];
|
||
|
aes_ctx.State[2][2] = Temp;
|
||
|
Temp = aes_ctx.State[2][1];
|
||
|
aes_ctx.State[2][1] = aes_ctx.State[2][3];
|
||
|
aes_ctx.State[2][3] = Temp;
|
||
|
Temp = aes_ctx.State[3][3];
|
||
|
aes_ctx.State[3][3] = aes_ctx.State[3][2];
|
||
|
aes_ctx.State[3][2] = aes_ctx.State[3][1];
|
||
|
aes_ctx.State[3][1] = aes_ctx.State[3][0];
|
||
|
aes_ctx.State[3][0] = Temp;
|
||
|
/* AES_AddRoundKey */
|
||
|
for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
|
||
|
for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
|
||
|
aes_ctx.State[RowIndex][ColumnIndex] ^= aes_ctx.KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex];
|
||
|
|
||
|
/*
|
||
|
* 4. Transfer the state block to cipher block
|
||
|
*/
|
||
|
for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
|
||
|
for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
|
||
|
CipherBlock[RowIndex + 4*ColumnIndex] = aes_ctx.State[RowIndex][ColumnIndex];
|
||
|
|
||
|
*CipherBlockSize = ((UINT) AES_STATE_ROWS)*((UINT) AES_STATE_COLUMNS);
|
||
|
} /* End of AES_Encrypt */
|
||
|
|
||
|
|
||
|
/*
|
||
|
========================================================================
|
||
|
Routine Description:
|
||
|
AES decryption
|
||
|
|
||
|
Arguments:
|
||
|
CipherBlock The block of cipher text, 16 bytes(128 bits) each block
|
||
|
CipherBlockSize The length of block of cipher text in bytes
|
||
|
Key Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits)
|
||
|
KeyLength The length of cipher key in bytes
|
||
|
PlainBlockSize The length of allocated plain block in bytes
|
||
|
|
||
|
Return Value:
|
||
|
PlainBlock Return plain text
|
||
|
PlainBlockSize Return the length of real used plain block in bytes
|
||
|
|
||
|
Note:
|
||
|
Reference to FIPS-PUB 197
|
||
|
1. Check if block size is 16 bytes(128 bits) and if key length is 16, 24, or 32 bytes(128, 192, or 256 bits)
|
||
|
2. Transfer the cipher block to state block
|
||
|
3. Main decryption rounds
|
||
|
4. Transfer the state block to plain block
|
||
|
------------------------------------------
|
||
|
NumberOfRound = (key length / 4) + 6;
|
||
|
state block = cipher block;
|
||
|
|
||
|
AddRoundKey(state block, key);
|
||
|
for round = NumberOfRound to 1
|
||
|
InvSubBytes(state block)
|
||
|
InvShiftRows(state block)
|
||
|
InvMixColumns(state block)
|
||
|
AddRoundKey(state block, key);
|
||
|
end for
|
||
|
|
||
|
InvSubBytes(state block)
|
||
|
InvShiftRows(state block)
|
||
|
AddRoundKey(state block, key);
|
||
|
|
||
|
plain block = state block;
|
||
|
========================================================================
|
||
|
*/
|
||
|
VOID AES_Decrypt (
|
||
|
IN UINT8 CipherBlock[],
|
||
|
IN UINT CipherBlockSize,
|
||
|
IN UINT8 Key[],
|
||
|
IN UINT KeyLength,
|
||
|
OUT UINT8 PlainBlock[],
|
||
|
INOUT UINT *PlainBlockSize)
|
||
|
{
|
||
|
AES_CTX_STRUC aes_ctx;
|
||
|
UINT RowIndex, ColumnIndex;
|
||
|
UINT RoundIndex, NumberOfRound = 0;
|
||
|
UINT8 Temp, Row0, Row1, Row2, Row3;
|
||
|
|
||
|
/*
|
||
|
* 1. Check if block size is 16 bytes(128 bits) and if key length is 16, 24, or 32 bytes(128, 192, or 256 bits)
|
||
|
*/
|
||
|
if (*PlainBlockSize < AES_BLOCK_SIZES) {
|
||
|
DBGPRINT(RT_DEBUG_ERROR, ("AES_Decrypt: plain block size is %d bytes, it must be %d bytes(128 bits).\n",
|
||
|
*PlainBlockSize, AES_BLOCK_SIZES));
|
||
|
return;
|
||
|
} /* End of if */
|
||
|
if ((KeyLength != AES_KEY128_LENGTH) && (KeyLength != AES_KEY192_LENGTH) && (KeyLength != AES_KEY256_LENGTH)) {
|
||
|
DBGPRINT(RT_DEBUG_ERROR, ("AES_Decrypt: key length is %d bytes, it must be %d, %d, or %d bytes(128, 192, or 256 bits).\n",
|
||
|
KeyLength, AES_KEY128_LENGTH, AES_KEY192_LENGTH, AES_KEY256_LENGTH));
|
||
|
return;
|
||
|
} /* End of if */
|
||
|
if (CipherBlockSize != AES_BLOCK_SIZES) {
|
||
|
DBGPRINT(RT_DEBUG_ERROR, ("AES_Decrypt: cipher block size is %d bytes, it must be %d bytes(128 bits).\n",
|
||
|
CipherBlockSize, AES_BLOCK_SIZES));
|
||
|
return;
|
||
|
} /* End of if */
|
||
|
|
||
|
/*
|
||
|
* 2. Transfer the cipher block to state block
|
||
|
*/
|
||
|
for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
|
||
|
for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
|
||
|
aes_ctx.State[RowIndex][ColumnIndex] = CipherBlock[RowIndex + 4*ColumnIndex];
|
||
|
|
||
|
/*
|
||
|
* 3. Main decryption rounds
|
||
|
*/
|
||
|
AES_KeyExpansion(Key, KeyLength, &aes_ctx);
|
||
|
NumberOfRound = (KeyLength >> 2) + 6;
|
||
|
|
||
|
/* AES_AddRoundKey */
|
||
|
RoundIndex = NumberOfRound;
|
||
|
for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
|
||
|
for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
|
||
|
aes_ctx.State[RowIndex][ColumnIndex] ^= aes_ctx.KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex];
|
||
|
|
||
|
for (RoundIndex = (NumberOfRound - 1); RoundIndex > 0 ;RoundIndex--)
|
||
|
{
|
||
|
/* AES_InvShiftRows */
|
||
|
Temp = aes_ctx.State[1][3];
|
||
|
aes_ctx.State[1][3] = aes_ctx.State[1][2];
|
||
|
aes_ctx.State[1][2] = aes_ctx.State[1][1];
|
||
|
aes_ctx.State[1][1] = aes_ctx.State[1][0];
|
||
|
aes_ctx.State[1][0] = Temp;
|
||
|
Temp = aes_ctx.State[2][0];
|
||
|
aes_ctx.State[2][0] = aes_ctx.State[2][2];
|
||
|
aes_ctx.State[2][2] = Temp;
|
||
|
Temp = aes_ctx.State[2][1];
|
||
|
aes_ctx.State[2][1] = aes_ctx.State[2][3];
|
||
|
aes_ctx.State[2][3] = Temp;
|
||
|
Temp = aes_ctx.State[3][0];
|
||
|
aes_ctx.State[3][0] = aes_ctx.State[3][1];
|
||
|
aes_ctx.State[3][1] = aes_ctx.State[3][2];
|
||
|
aes_ctx.State[3][2] = aes_ctx.State[3][3];
|
||
|
aes_ctx.State[3][3] = Temp;
|
||
|
|
||
|
/* AES_InvSubBytes */
|
||
|
for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
|
||
|
for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
|
||
|
aes_ctx.State[RowIndex][ColumnIndex] = aes_sbox_dec[aes_ctx.State[RowIndex][ColumnIndex]];
|
||
|
|
||
|
/* AES_AddRoundKey */
|
||
|
for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
|
||
|
for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
|
||
|
aes_ctx.State[RowIndex][ColumnIndex] ^= aes_ctx.KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex];
|
||
|
|
||
|
/* AES_InvMixColumns */
|
||
|
for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
|
||
|
{
|
||
|
Row0 = aes_ctx.State[0][ColumnIndex];
|
||
|
Row1 = aes_ctx.State[1][ColumnIndex];
|
||
|
Row2 = aes_ctx.State[2][ColumnIndex];
|
||
|
Row3 = aes_ctx.State[3][ColumnIndex];
|
||
|
aes_ctx.State[0][ColumnIndex] = aes_mul_e[Row0]^aes_mul_b[Row1]^aes_mul_d[Row2]^aes_mul_9[Row3];
|
||
|
aes_ctx.State[1][ColumnIndex] = aes_mul_9[Row0]^aes_mul_e[Row1]^aes_mul_b[Row2]^aes_mul_d[Row3];
|
||
|
aes_ctx.State[2][ColumnIndex] = aes_mul_d[Row0]^aes_mul_9[Row1]^aes_mul_e[Row2]^aes_mul_b[Row3];
|
||
|
aes_ctx.State[3][ColumnIndex] = aes_mul_b[Row0]^aes_mul_d[Row1]^aes_mul_9[Row2]^aes_mul_e[Row3];
|
||
|
}
|
||
|
} /* End of for */
|
||
|
|
||
|
/* AES_InvShiftRows */
|
||
|
Temp = aes_ctx.State[1][3];
|
||
|
aes_ctx.State[1][3] = aes_ctx.State[1][2];
|
||
|
aes_ctx.State[1][2] = aes_ctx.State[1][1];
|
||
|
aes_ctx.State[1][1] = aes_ctx.State[1][0];
|
||
|
aes_ctx.State[1][0] = Temp;
|
||
|
Temp = aes_ctx.State[2][0];
|
||
|
aes_ctx.State[2][0] = aes_ctx.State[2][2];
|
||
|
aes_ctx.State[2][2] = Temp;
|
||
|
Temp = aes_ctx.State[2][1];
|
||
|
aes_ctx.State[2][1] = aes_ctx.State[2][3];
|
||
|
aes_ctx.State[2][3] = Temp;
|
||
|
Temp = aes_ctx.State[3][0];
|
||
|
aes_ctx.State[3][0] = aes_ctx.State[3][1];
|
||
|
aes_ctx.State[3][1] = aes_ctx.State[3][2];
|
||
|
aes_ctx.State[3][2] = aes_ctx.State[3][3];
|
||
|
aes_ctx.State[3][3] = Temp;
|
||
|
/* AES_InvSubBytes */
|
||
|
for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
|
||
|
for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
|
||
|
aes_ctx.State[RowIndex][ColumnIndex] = aes_sbox_dec[aes_ctx.State[RowIndex][ColumnIndex]];
|
||
|
/* AES_AddRoundKey */
|
||
|
for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
|
||
|
for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
|
||
|
aes_ctx.State[RowIndex][ColumnIndex] ^= aes_ctx.KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex];
|
||
|
|
||
|
/*
|
||
|
* 4. Transfer the state block to plain block
|
||
|
*/
|
||
|
for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
|
||
|
for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
|
||
|
PlainBlock[RowIndex + 4*ColumnIndex] = aes_ctx.State[RowIndex][ColumnIndex];
|
||
|
|
||
|
*PlainBlockSize = ((UINT) AES_STATE_ROWS)*((UINT) AES_STATE_COLUMNS);
|
||
|
} /* End of AES_Decrypt */
|
||
|
|
||
|
|
||
|
/*
|
||
|
========================================================================
|
||
|
Routine Description:
|
||
|
AES-CBC encryption
|
||
|
|
||
|
Arguments:
|
||
|
PlainText Plain text
|
||
|
PlainTextLength The length of plain text in bytes
|
||
|
Key Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits)
|
||
|
KeyLength The length of cipher key in bytes
|
||
|
IV Initialization vector, it may be 16 bytes (128 bits)
|
||
|
IVLength The length of initialization vector in bytes
|
||
|
CipherTextLength The length of allocated cipher text in bytes
|
||
|
|
||
|
Return Value:
|
||
|
CipherText Return cipher text
|
||
|
CipherTextLength Return the length of real used cipher text in bytes
|
||
|
|
||
|
Note:
|
||
|
Reference to RFC 3602 and NIST 800-38A
|
||
|
========================================================================
|
||
|
*/
|
||
|
VOID AES_CBC_Encrypt (
|
||
|
IN UINT8 PlainText[],
|
||
|
IN UINT PlainTextLength,
|
||
|
IN UINT8 Key[],
|
||
|
IN UINT KeyLength,
|
||
|
IN UINT8 IV[],
|
||
|
IN UINT IVLength,
|
||
|
OUT UINT8 CipherText[],
|
||
|
INOUT UINT *CipherTextLength)
|
||
|
{
|
||
|
UINT PaddingSize, PlainBlockStart, CipherBlockStart, CipherBlockSize;
|
||
|
UINT Index;
|
||
|
UINT8 Block[AES_BLOCK_SIZES];
|
||
|
|
||
|
/*
|
||
|
* 1. Check the input parameters
|
||
|
* - CipherTextLength > (PlainTextLength + Padding size), Padding size = block size - (PlainTextLength % block size)
|
||
|
* - Key length must be 16, 24, or 32 bytes(128, 192, or 256 bits)
|
||
|
* - IV length must be 16 bytes(128 bits)
|
||
|
*/
|
||
|
PaddingSize = ((UINT) AES_BLOCK_SIZES) - (PlainTextLength % ((UINT)AES_BLOCK_SIZES));
|
||
|
if (*CipherTextLength < (PlainTextLength + PaddingSize)) {
|
||
|
DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Encrypt: cipher text length is %d bytes < (plain text length %d bytes + padding size %d bytes).\n",
|
||
|
*CipherTextLength, PlainTextLength, PaddingSize));
|
||
|
return;
|
||
|
} /* End of if */
|
||
|
if ((KeyLength != AES_KEY128_LENGTH) && (KeyLength != AES_KEY192_LENGTH) && (KeyLength != AES_KEY256_LENGTH)) {
|
||
|
DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Encrypt: key length is %d bytes, it must be %d, %d, or %d bytes(128, 192, or 256 bits).\n",
|
||
|
KeyLength, AES_KEY128_LENGTH, AES_KEY192_LENGTH, AES_KEY256_LENGTH));
|
||
|
return;
|
||
|
} /* End of if */
|
||
|
if (IVLength != AES_CBC_IV_LENGTH) {
|
||
|
DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Encrypt: IV length is %d bytes, it must be %d bytes(128bits).\n",
|
||
|
IVLength, AES_CBC_IV_LENGTH));
|
||
|
return;
|
||
|
} /* End of if */
|
||
|
|
||
|
|
||
|
/*
|
||
|
* 2. Main algorithm
|
||
|
* - Plain text divide into serveral blocks (16 bytes/block)
|
||
|
* - If plain text is divided with no remainder by block, add a new block and padding size = block(16 bytes)
|
||
|
* - If plain text is not divided with no remainder by block, padding size = (block - remainder plain text)
|
||
|
* - Execute AES_Encrypt procedure.
|
||
|
*
|
||
|
* - Padding method: The remainder bytes will be filled with padding size (1 byte)
|
||
|
*/
|
||
|
PlainBlockStart = 0;
|
||
|
CipherBlockStart = 0;
|
||
|
while ((PlainTextLength - PlainBlockStart) >= AES_BLOCK_SIZES)
|
||
|
{
|
||
|
if (CipherBlockStart == 0) {
|
||
|
for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
|
||
|
Block[Index] = PlainText[PlainBlockStart + Index]^IV[Index];
|
||
|
} else {
|
||
|
for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
|
||
|
Block[Index] = PlainText[PlainBlockStart + Index]^CipherText[CipherBlockStart - ((UINT) AES_BLOCK_SIZES) + Index];
|
||
|
} /* End of if */
|
||
|
|
||
|
CipherBlockSize = *CipherTextLength - CipherBlockStart;
|
||
|
AES_Encrypt(Block, AES_BLOCK_SIZES , Key, KeyLength, CipherText + CipherBlockStart, &CipherBlockSize);
|
||
|
|
||
|
PlainBlockStart += ((UINT) AES_BLOCK_SIZES);
|
||
|
CipherBlockStart += CipherBlockSize;
|
||
|
} /* End of while */
|
||
|
|
||
|
NdisMoveMemory(Block, (&PlainText[0] + PlainBlockStart), (PlainTextLength - PlainBlockStart));
|
||
|
NdisFillMemory((Block + (((UINT) AES_BLOCK_SIZES) -PaddingSize)), PaddingSize, (UINT8) PaddingSize);
|
||
|
if (CipherBlockStart == 0) {
|
||
|
for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
|
||
|
Block[Index] ^= IV[Index];
|
||
|
} else {
|
||
|
for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
|
||
|
Block[Index] ^= CipherText[CipherBlockStart - ((UINT) AES_BLOCK_SIZES) + Index];
|
||
|
} /* End of if */
|
||
|
CipherBlockSize = *CipherTextLength - CipherBlockStart;
|
||
|
AES_Encrypt(Block, AES_BLOCK_SIZES , Key, KeyLength, CipherText + CipherBlockStart, &CipherBlockSize);
|
||
|
CipherBlockStart += CipherBlockSize;
|
||
|
*CipherTextLength = CipherBlockStart;
|
||
|
} /* End of AES_CBC_Encrypt */
|
||
|
|
||
|
|
||
|
/*
|
||
|
========================================================================
|
||
|
Routine Description:
|
||
|
AES-CBC decryption
|
||
|
|
||
|
Arguments:
|
||
|
CipherText Cipher text
|
||
|
CipherTextLength The length of cipher text in bytes
|
||
|
Key Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits)
|
||
|
KeyLength The length of cipher key in bytes
|
||
|
IV Initialization vector, it may be 16 bytes (128 bits)
|
||
|
IVLength The length of initialization vector in bytes
|
||
|
PlainTextLength The length of allocated plain text in bytes
|
||
|
|
||
|
Return Value:
|
||
|
PlainText Return plain text
|
||
|
PlainTextLength Return the length of real used plain text in bytes
|
||
|
|
||
|
Note:
|
||
|
Reference to RFC 3602 and NIST 800-38A
|
||
|
========================================================================
|
||
|
*/
|
||
|
VOID AES_CBC_Decrypt (
|
||
|
IN UINT8 CipherText[],
|
||
|
IN UINT CipherTextLength,
|
||
|
IN UINT8 Key[],
|
||
|
IN UINT KeyLength,
|
||
|
IN UINT8 IV[],
|
||
|
IN UINT IVLength,
|
||
|
OUT UINT8 PlainText[],
|
||
|
INOUT UINT *PlainTextLength)
|
||
|
{
|
||
|
UINT PaddingSize, PlainBlockStart, CipherBlockStart, PlainBlockSize;
|
||
|
UINT Index;
|
||
|
|
||
|
/*
|
||
|
* 1. Check the input parameters
|
||
|
* - CipherTextLength must be divided with no remainder by block
|
||
|
* - Key length must be 16, 24, or 32 bytes(128, 192, or 256 bits)
|
||
|
* - IV length must be 16 bytes(128 bits)
|
||
|
*/
|
||
|
if ((CipherTextLength % AES_BLOCK_SIZES) != 0) {
|
||
|
DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Decrypt: cipher text length is %d bytes, it can't be divided with no remainder by block size(%d).\n",
|
||
|
CipherTextLength, AES_BLOCK_SIZES));
|
||
|
return;
|
||
|
} /* End of if */
|
||
|
if ((KeyLength != AES_KEY128_LENGTH) && (KeyLength != AES_KEY192_LENGTH) && (KeyLength != AES_KEY256_LENGTH)) {
|
||
|
DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Decrypt: key length is %d bytes, it must be %d, %d, or %d bytes(128, 192, or 256 bits).\n",
|
||
|
KeyLength, AES_KEY128_LENGTH, AES_KEY192_LENGTH, AES_KEY256_LENGTH));
|
||
|
return;
|
||
|
} /* End of if */
|
||
|
if (IVLength != AES_CBC_IV_LENGTH) {
|
||
|
DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Decrypt: IV length is %d bytes, it must be %d bytes(128bits).\n",
|
||
|
IVLength, AES_CBC_IV_LENGTH));
|
||
|
return;
|
||
|
} /* End of if */
|
||
|
|
||
|
|
||
|
/*
|
||
|
* 2. Main algorithm
|
||
|
* - Cypher text divide into serveral blocks (16 bytes/block)
|
||
|
* - Execute AES_Decrypt procedure.
|
||
|
* - Remove padding bytes, padding size is the last byte of plain text
|
||
|
*/
|
||
|
CipherBlockStart = 0;
|
||
|
PlainBlockStart = 0;
|
||
|
while ((CipherTextLength - CipherBlockStart) >= AES_BLOCK_SIZES)
|
||
|
{
|
||
|
PlainBlockSize = *PlainTextLength - PlainBlockStart;
|
||
|
AES_Decrypt(CipherText + CipherBlockStart, AES_BLOCK_SIZES , Key, KeyLength, PlainText + PlainBlockStart, &PlainBlockSize);
|
||
|
|
||
|
if (PlainBlockStart == 0) {
|
||
|
for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
|
||
|
PlainText[PlainBlockStart + Index] ^= IV[Index];
|
||
|
} else {
|
||
|
for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
|
||
|
PlainText[PlainBlockStart + Index] ^= CipherText[CipherBlockStart + Index - ((UINT) AES_BLOCK_SIZES)];
|
||
|
} /* End of if */
|
||
|
|
||
|
CipherBlockStart += AES_BLOCK_SIZES;
|
||
|
PlainBlockStart += PlainBlockSize;
|
||
|
} /* End of while */
|
||
|
|
||
|
PaddingSize = (UINT8) PlainText[PlainBlockStart -1];
|
||
|
*PlainTextLength = PlainBlockStart - PaddingSize;
|
||
|
|
||
|
} /* End of AES_CBC_Encrypt */
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
========================================================================
|
||
|
Routine Description:
|
||
|
AES-CMAC generate subkey
|
||
|
|
||
|
Arguments:
|
||
|
Key Cipher key 128 bits
|
||
|
KeyLength The length of Cipher key in bytes
|
||
|
|
||
|
Return Value:
|
||
|
SubKey1 SubKey 1 128 bits
|
||
|
SubKey2 SubKey 2 128 bits
|
||
|
|
||
|
Note:
|
||
|
Reference to RFC 4493
|
||
|
|
||
|
Step 1. L := AES-128(K, const_Zero);
|
||
|
Step 2. if MSB(L) is equal to 0
|
||
|
then K1 := L << 1;
|
||
|
else K1 := (L << 1) XOR const_Rb;
|
||
|
Step 3. if MSB(K1) is equal to 0
|
||
|
then K2 := K1 << 1;
|
||
|
else K2 := (K1 << 1) XOR const_Rb;
|
||
|
Step 4. return K1, K2;
|
||
|
========================================================================
|
||
|
*/
|
||
|
VOID AES_CMAC_GenerateSubKey (
|
||
|
IN UINT8 Key[],
|
||
|
IN UINT KeyLength,
|
||
|
OUT UINT8 SubKey1[],
|
||
|
OUT UINT8 SubKey2[])
|
||
|
{
|
||
|
UINT8 MSB_L = 0, MSB_K1 = 0, Top_Bit = 0;
|
||
|
UINT SubKey1_Length = 0;
|
||
|
INT Index = 0;
|
||
|
|
||
|
if (KeyLength != AES_KEY128_LENGTH) {
|
||
|
DBGPRINT(RT_DEBUG_ERROR, ("AES_CMAC_GenerateSubKey: key length is %d bytes, it must be %d bytes(128 bits).\n",
|
||
|
KeyLength, AES_KEY128_LENGTH));
|
||
|
return;
|
||
|
} /* End of if */
|
||
|
|
||
|
/* Step 1: L := AES-128(K, const_Zero); */
|
||
|
SubKey1_Length = 16;
|
||
|
AES_Encrypt(Const_Zero, sizeof(Const_Zero), Key, KeyLength, SubKey1, &SubKey1_Length);
|
||
|
|
||
|
/*
|
||
|
* Step 2. if MSB(L) is equal to 0
|
||
|
* then K1 := L << 1;
|
||
|
* else K1 := (L << 1) XOR const_Rb;
|
||
|
*/
|
||
|
MSB_L = SubKey1[0] & 0x80;
|
||
|
for(Index = 0; Index < 15; Index++) {
|
||
|
Top_Bit = (SubKey1[Index + 1] & 0x80)?1:0;
|
||
|
SubKey1[Index] <<= 1;
|
||
|
SubKey1[Index] |= Top_Bit;
|
||
|
}
|
||
|
SubKey1[15] <<= 1;
|
||
|
if (MSB_L > 0) {
|
||
|
for(Index = 0; Index < 16; Index++)
|
||
|
SubKey1[Index] ^= Const_Rb[Index];
|
||
|
} /* End of if */
|
||
|
|
||
|
/*
|
||
|
* Step 3. if MSB(K1) is equal to 0
|
||
|
* then K2 := K1 << 1;
|
||
|
* else K2 := (K1 << 1) XOR const_Rb;
|
||
|
*/
|
||
|
MSB_K1 = SubKey1[0] & 0x80;
|
||
|
for(Index = 0; Index < 15; Index++) {
|
||
|
Top_Bit = (SubKey1[Index + 1] & 0x80)?1:0;
|
||
|
SubKey2[Index] = SubKey1[Index] << 1;
|
||
|
SubKey2[Index] |= Top_Bit;
|
||
|
}
|
||
|
SubKey2[15] = SubKey1[15] << 1;
|
||
|
if (MSB_K1 > 0) {
|
||
|
for(Index = 0; Index < 16; Index++)
|
||
|
SubKey2[Index] ^= Const_Rb[Index];
|
||
|
} /* End of if */
|
||
|
} /* End of AES_CMAC_GenerateSubKey */
|
||
|
|
||
|
|
||
|
/*
|
||
|
========================================================================
|
||
|
Routine Description:
|
||
|
AES-CMAC
|
||
|
|
||
|
Arguments:
|
||
|
PlainText Plain text
|
||
|
PlainTextLength The length of plain text in bytes
|
||
|
Key Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits)
|
||
|
KeyLength The length of cipher key in bytes
|
||
|
MACTextLength The length of allocated memory spaces in bytes
|
||
|
|
||
|
Return Value:
|
||
|
MACText Message authentication code (128-bit string)
|
||
|
MACTextLength Return the length of Message authentication code in bytes
|
||
|
|
||
|
Note:
|
||
|
Reference to RFC 4493
|
||
|
========================================================================
|
||
|
*/
|
||
|
VOID AES_CMAC (
|
||
|
IN UINT8 PlainText[],
|
||
|
IN UINT PlainTextLength,
|
||
|
IN UINT8 Key[],
|
||
|
IN UINT KeyLength,
|
||
|
OUT UINT8 MACText[],
|
||
|
INOUT UINT *MACTextLength)
|
||
|
{
|
||
|
UINT PlainBlockStart;
|
||
|
UINT8 X[AES_BLOCK_SIZES], Y[AES_BLOCK_SIZES];
|
||
|
UINT8 SubKey1[16];
|
||
|
UINT8 SubKey2[16];
|
||
|
INT X_Length, Index;
|
||
|
|
||
|
if (*MACTextLength < AES_MAC_LENGTH) {
|
||
|
DBGPRINT(RT_DEBUG_ERROR, ("AES_CMAC: MAC text length is less than %d bytes).\n",
|
||
|
AES_MAC_LENGTH));
|
||
|
return;
|
||
|
} /* End of if */
|
||
|
if (KeyLength != AES_KEY128_LENGTH) {
|
||
|
DBGPRINT(RT_DEBUG_ERROR, ("AES_CMAC: key length is %d bytes, it must be %d bytes(128 bits).\n",
|
||
|
KeyLength, AES_KEY128_LENGTH));
|
||
|
return;
|
||
|
} /* End of if */
|
||
|
|
||
|
/* Step 1. (K1,K2) := Generate_Subkey(K); */
|
||
|
NdisZeroMemory(SubKey1, 16);
|
||
|
NdisZeroMemory(SubKey2, 16);
|
||
|
AES_CMAC_GenerateSubKey(Key, KeyLength, SubKey1, SubKey2);
|
||
|
|
||
|
/*
|
||
|
* 2. Main algorithm
|
||
|
* - Plain text divide into serveral blocks (16 bytes/block)
|
||
|
* - If plain text is not divided with no remainder by block, padding size = (block - remainder plain text)
|
||
|
* - Execute AES_Encrypt procedure.
|
||
|
*/
|
||
|
PlainBlockStart = 0;
|
||
|
NdisMoveMemory(X, Const_Zero, AES_BLOCK_SIZES);
|
||
|
while ((PlainTextLength - PlainBlockStart) > AES_BLOCK_SIZES)
|
||
|
{
|
||
|
for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
|
||
|
Y[Index] = PlainText[PlainBlockStart + Index]^X[Index];
|
||
|
|
||
|
X_Length = sizeof(X);
|
||
|
AES_Encrypt(Y, sizeof(Y) , Key, KeyLength, X, &X_Length);
|
||
|
PlainBlockStart += ((UINT) AES_BLOCK_SIZES);
|
||
|
} /* End of while */
|
||
|
if ((PlainTextLength - PlainBlockStart) == AES_BLOCK_SIZES) {
|
||
|
for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
|
||
|
Y[Index] = PlainText[PlainBlockStart + Index]^X[Index]^SubKey1[Index];
|
||
|
} else {
|
||
|
NdisZeroMemory(Y, AES_BLOCK_SIZES);
|
||
|
NdisMoveMemory(Y, &PlainText[PlainBlockStart], (PlainTextLength - PlainBlockStart));
|
||
|
Y[(PlainTextLength - PlainBlockStart)] = 0x80;
|
||
|
for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
|
||
|
Y[Index] = Y[Index]^X[Index]^SubKey2[Index];
|
||
|
} /* End of if */
|
||
|
AES_Encrypt(Y, sizeof(Y) , Key, KeyLength, MACText, MACTextLength);
|
||
|
} /* End of AES_CMAC */
|