| /* |
| ************************************************************************* |
| * 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 */ |