2 *************************************************************************
4 * 5F., No.36, Taiyuan St., Jhubei City,
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 *************************************************************************
34 -------- ---------- ----------------------------------------------
35 Eddy 2009/01/19 Create AES-128, AES-192, AES-256, AES-CBC
38 #include "crypt_aes.h"
40 /* The value given by [x^(i-1),{00},{00},{00}], with x^(i-1) being powers of x in the field GF(2^8). */
41 static const UINT32 aes_rcon[] = {
42 0x00000000, 0x01000000, 0x02000000, 0x04000000,
43 0x08000000, 0x10000000, 0x20000000, 0x40000000,
44 0x80000000, 0x1B000000, 0x36000000};
46 static const UINT8 aes_sbox_enc[] = {
47 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
48 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7 ,0xab, 0x76, /* 0 */
49 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4 ,0x72, 0xc0, /* 1 */
50 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8 ,0x31, 0x15, /* 2 */
51 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27 ,0xb2, 0x75, /* 3 */
52 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3 ,0x2f, 0x84, /* 4 */
53 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c ,0x58, 0xcf, /* 5 */
54 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c ,0x9f, 0xa8, /* 6 */
55 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff ,0xf3, 0xd2, /* 7 */
56 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d ,0x19, 0x73, /* 8 */
57 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e ,0x0b, 0xdb, /* 9 */
58 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95 ,0xe4, 0x79, /* a */
59 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a ,0xae, 0x08, /* b */
60 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd ,0x8b, 0x8a, /* c */
61 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1 ,0x1d, 0x9e, /* d */
62 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55 ,0x28, 0xdf, /* e */
63 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54 ,0xbb, 0x16, /* f */
66 static const UINT8 aes_sbox_dec[] = {
67 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
68 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, /* 0 */
69 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, /* 1 */
70 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, /* 2 */
71 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, /* 3 */
72 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, /* 4 */
73 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, /* 5 */
74 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, /* 6 */
75 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, /* 7 */
76 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, /* 8 */
77 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, /* 9 */
78 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, /* a */
79 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, /* b */
80 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, /* c */
81 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, /* d */
82 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, /* e */
83 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d, /* f */
87 static const UINT8 aes_mul_2[] = {
88 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
89 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, /* 0 */
90 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, /* 1 */
91 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, /* 2 */
92 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e, /* 3 */
93 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, /* 4 */
94 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, /* 5 */
95 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, /* 6 */
96 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, /* 7 */
97 0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05, /* 8 */
98 0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25, /* 9 */
99 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45, /* a */
100 0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65, /* b */
101 0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85, /* c */
102 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, /* d */
103 0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5, /* e */
104 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5, /* f */
107 /* ArrayIndex*{03} */
108 static const UINT8 aes_mul_3[] = {
109 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
110 0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11, /* 0 */
111 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, /* 1 */
112 0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71, /* 2 */
113 0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41, /* 3 */
114 0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1, /* 4 */
115 0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1, /* 5 */
116 0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1, /* 6 */
117 0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81, /* 7 */
118 0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a, /* 8 */
119 0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba, /* 9 */
120 0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea, /* a */
121 0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda, /* b */
122 0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a, /* c */
123 0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a, /* d */
124 0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a, /* e */
125 0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a, /* f */
128 /* ArrayIndex*{09} */
129 static const UINT8 aes_mul_9[] = {
130 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
131 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77, /* 0 */
132 0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7, /* 1 */
133 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c, /* 2 */
134 0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc, /* 3 */
135 0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49, 0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01, /* 4 */
136 0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91, /* 5 */
137 0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a, /* 6 */
138 0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2, 0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa, /* 7 */
139 0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b, /* 8 */
140 0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b, /* 9 */
141 0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8, 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0, /* a */
142 0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30, /* b */
143 0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed, /* c */
144 0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35, 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d, /* d */
145 0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6, /* e */
146 0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46, /* f */
149 /* ArrayIndex*{0b} */
150 static const UINT8 aes_mul_b[] = {
151 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
152 0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69, /* 0 */
153 0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9, /* 1 */
154 0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12, /* 2 */
155 0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2, /* 3 */
156 0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7, 0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f, /* 4 */
157 0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f, /* 5 */
158 0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4, /* 6 */
159 0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c, 0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54, /* 7 */
160 0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e, /* 8 */
161 0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e, /* 9 */
162 0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd, 0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5, /* a */
163 0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55, /* b */
164 0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68, /* c */
165 0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8, /* d */
166 0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13, /* e */
167 0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3, /* f */
170 /* ArrayIndex*{0d} */
171 static const UINT8 aes_mul_d[] = {
172 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
173 0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b, /* 0 */
174 0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b, /* 1 */
175 0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0, /* 2 */
176 0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20, /* 3 */
177 0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e, 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26, /* 4 */
178 0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6, /* 5 */
179 0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d, /* 6 */
180 0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25, 0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d, /* 7 */
181 0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91, /* 8 */
182 0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41, /* 9 */
183 0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42, 0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a, /* a */
184 0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa, /* b */
185 0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc, /* c */
186 0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c, /* d */
187 0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47, /* e */
188 0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97, /* f */
191 /* ArrayIndex*{0e} */
192 static const UINT8 aes_mul_e[] = {
193 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
194 0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a, /* 0 */
195 0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba, /* 1 */
196 0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81, /* 2 */
197 0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61, /* 3 */
198 0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87, 0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7, /* 4 */
199 0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17, /* 5 */
200 0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c, /* 6 */
201 0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc, 0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc, /* 7 */
202 0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b, /* 8 */
203 0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb, /* 9 */
204 0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0, 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0, /* a */
205 0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20, /* b */
206 0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6, /* c */
207 0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56, /* d */
208 0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d, /* e */
209 0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d, /* f */
214 #define AES_MAC_LENGTH 16 /* 128-bit string */
215 static UINT8 Const_Zero[16] = {
216 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
217 static UINT8 Const_Rb[16] = {
218 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87};
222 ========================================================================
224 AES key expansion (key schedule)
227 Key Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits)
228 KeyLength The length of cipher key in bytes
229 paes_ctx Pointer to AES_CTX_STRUC
232 paes_ctx Retrun the KeyWordExpansion of AES_CTX_STRUC
235 Pseudo code for key expansion
236 ------------------------------------------
240 KeyWordExpansion[i] = word(key[4*i], key[4*i + 1], key[4*i + 2], key[4*i + 3]);
244 while (i < ((key length/4 + 6 + 1)*4) )
245 temp = KeyWordExpansion[i - 1];
247 temp = SubWord(RotWord(temp)) ^ Rcon[i/Nk];
248 else if ((Nk > 6) && (i % 4 == 4))
249 temp = SubWord(temp);
252 KeyWordExpansion[i] = KeyWordExpansion[i - Nk]^ temp;
255 ========================================================================
257 VOID AES_KeyExpansion (
260 INOUT AES_CTX_STRUC *paes_ctx)
263 UINT NumberOfWordOfKey, NumberOfWordOfKeyExpansion;
264 UINT8 TempWord[AES_KEY_ROWS], Temp;
267 NumberOfWordOfKey = KeyLength >> 2;
268 while (KeyIndex < NumberOfWordOfKey)
270 paes_ctx->KeyWordExpansion[0][KeyIndex] = Key[4*KeyIndex];
271 paes_ctx->KeyWordExpansion[1][KeyIndex] = Key[4*KeyIndex + 1];
272 paes_ctx->KeyWordExpansion[2][KeyIndex] = Key[4*KeyIndex + 2];
273 paes_ctx->KeyWordExpansion[3][KeyIndex] = Key[4*KeyIndex + 3];
277 NumberOfWordOfKeyExpansion = ((UINT) AES_KEY_ROWS) * ((KeyLength >> 2) + 6 + 1);
278 while (KeyIndex < NumberOfWordOfKeyExpansion)
280 TempWord[0] = paes_ctx->KeyWordExpansion[0][KeyIndex - 1];
281 TempWord[1] = paes_ctx->KeyWordExpansion[1][KeyIndex - 1];
282 TempWord[2] = paes_ctx->KeyWordExpansion[2][KeyIndex - 1];
283 TempWord[3] = paes_ctx->KeyWordExpansion[3][KeyIndex - 1];
284 if ((KeyIndex % NumberOfWordOfKey) == 0) {
285 Temprcon = aes_rcon[KeyIndex/NumberOfWordOfKey];
286 Temp = aes_sbox_enc[TempWord[1]]^((Temprcon >> 24) & 0xff);
287 TempWord[1] = aes_sbox_enc[TempWord[2]]^((Temprcon >> 16) & 0xff);
288 TempWord[2] = aes_sbox_enc[TempWord[3]]^((Temprcon >> 8) & 0xff);
289 TempWord[3] = aes_sbox_enc[TempWord[0]]^((Temprcon ) & 0xff);
291 } else if ((NumberOfWordOfKey > 6) && ((KeyIndex % NumberOfWordOfKey) == 4)) {
292 Temp = aes_sbox_enc[TempWord[0]];
293 TempWord[1] = aes_sbox_enc[TempWord[1]];
294 TempWord[2] = aes_sbox_enc[TempWord[2]];
295 TempWord[3] = aes_sbox_enc[TempWord[3]];
298 paes_ctx->KeyWordExpansion[0][KeyIndex] = paes_ctx->KeyWordExpansion[0][KeyIndex - NumberOfWordOfKey]^TempWord[0];
299 paes_ctx->KeyWordExpansion[1][KeyIndex] = paes_ctx->KeyWordExpansion[1][KeyIndex - NumberOfWordOfKey]^TempWord[1];
300 paes_ctx->KeyWordExpansion[2][KeyIndex] = paes_ctx->KeyWordExpansion[2][KeyIndex - NumberOfWordOfKey]^TempWord[2];
301 paes_ctx->KeyWordExpansion[3][KeyIndex] = paes_ctx->KeyWordExpansion[3][KeyIndex - NumberOfWordOfKey]^TempWord[3];
304 } /* End of AES_KeyExpansion */
308 ========================================================================
313 PlainBlock The block of plain text, 16 bytes(128 bits) each block
314 PlainBlockSize The length of block of plain text in bytes
315 Key Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits)
316 KeyLength The length of cipher key in bytes
317 CipherBlockSize The length of allocated cipher block in bytes
320 CipherBlock Return cipher text
321 CipherBlockSize Return the length of real used cipher block in bytes
324 Reference to FIPS-PUB 197
325 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)
326 2. Transfer the plain block to state block
327 3. Main encryption rounds
328 4. Transfer the state block to cipher block
329 ------------------------------------------
330 NumberOfRound = (key length / 4) + 6;
331 state block = plain block;
333 AddRoundKey(state block, key);
334 for round = 1 to NumberOfRound
335 SubBytes(state block)
336 ShiftRows(state block)
337 MixColumns(state block)
338 AddRoundKey(state block, key);
341 SubBytes(state block)
342 ShiftRows(state block)
343 AddRoundKey(state block, key);
345 cipher block = state block;
346 ========================================================================
349 IN UINT8 PlainBlock[],
350 IN UINT PlainBlockSize,
353 OUT UINT8 CipherBlock[],
354 INOUT UINT *CipherBlockSize)
356 AES_CTX_STRUC aes_ctx;
357 UINT RowIndex, ColumnIndex;
358 UINT RoundIndex, NumberOfRound = 0;
359 UINT8 Temp, Row0, Row1, Row2, Row3;
362 * 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)
364 if (PlainBlockSize != AES_BLOCK_SIZES) {
365 DBGPRINT(RT_DEBUG_ERROR, ("AES_Encrypt: plain block size is %d bytes, it must be %d bytes(128 bits).\n",
366 PlainBlockSize, AES_BLOCK_SIZES));
369 if ((KeyLength != AES_KEY128_LENGTH) && (KeyLength != AES_KEY192_LENGTH) && (KeyLength != AES_KEY256_LENGTH)) {
370 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",
371 KeyLength, AES_KEY128_LENGTH, AES_KEY192_LENGTH, AES_KEY256_LENGTH));
374 if (*CipherBlockSize < AES_BLOCK_SIZES) {
375 DBGPRINT(RT_DEBUG_ERROR, ("AES_Encrypt: cipher block size is %d bytes, it must be %d bytes(128 bits).\n",
376 *CipherBlockSize, AES_BLOCK_SIZES));
381 * 2. Transfer the plain block to state block
383 for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
384 for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
385 aes_ctx.State[RowIndex][ColumnIndex] = PlainBlock[RowIndex + 4*ColumnIndex];
388 * 3. Main encryption rounds
390 AES_KeyExpansion(Key, KeyLength, &aes_ctx);
391 NumberOfRound = (KeyLength >> 2) + 6;
393 /* AES_AddRoundKey */
395 for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
396 for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
397 aes_ctx.State[RowIndex][ColumnIndex] ^= aes_ctx.KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex];
399 for (RoundIndex = 1; RoundIndex < NumberOfRound;RoundIndex++)
402 for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
403 for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
404 aes_ctx.State[RowIndex][ColumnIndex] = aes_sbox_enc[aes_ctx.State[RowIndex][ColumnIndex]];
407 Temp = aes_ctx.State[1][0];
408 aes_ctx.State[1][0] = aes_ctx.State[1][1];
409 aes_ctx.State[1][1] = aes_ctx.State[1][2];
410 aes_ctx.State[1][2] = aes_ctx.State[1][3];
411 aes_ctx.State[1][3] = Temp;
412 Temp = aes_ctx.State[2][0];
413 aes_ctx.State[2][0] = aes_ctx.State[2][2];
414 aes_ctx.State[2][2] = Temp;
415 Temp = aes_ctx.State[2][1];
416 aes_ctx.State[2][1] = aes_ctx.State[2][3];
417 aes_ctx.State[2][3] = Temp;
418 Temp = aes_ctx.State[3][3];
419 aes_ctx.State[3][3] = aes_ctx.State[3][2];
420 aes_ctx.State[3][2] = aes_ctx.State[3][1];
421 aes_ctx.State[3][1] = aes_ctx.State[3][0];
422 aes_ctx.State[3][0] = Temp;
425 for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
427 Row0 = aes_ctx.State[0][ColumnIndex];
428 Row1 = aes_ctx.State[1][ColumnIndex];
429 Row2 = aes_ctx.State[2][ColumnIndex];
430 Row3 = aes_ctx.State[3][ColumnIndex];
431 aes_ctx.State[0][ColumnIndex] = aes_mul_2[Row0]^aes_mul_3[Row1]^Row2^Row3;
432 aes_ctx.State[1][ColumnIndex] = Row0^aes_mul_2[Row1]^aes_mul_3[Row2]^Row3;
433 aes_ctx.State[2][ColumnIndex] = Row0^Row1^aes_mul_2[Row2]^aes_mul_3[Row3];
434 aes_ctx.State[3][ColumnIndex] = aes_mul_3[Row0]^Row1^Row2^aes_mul_2[Row3];
437 /* AES_AddRoundKey */
438 for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
439 for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
440 aes_ctx.State[RowIndex][ColumnIndex] ^= aes_ctx.KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex];
444 for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
445 for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
446 aes_ctx.State[RowIndex][ColumnIndex] = aes_sbox_enc[aes_ctx.State[RowIndex][ColumnIndex]];
448 Temp = aes_ctx.State[1][0];
449 aes_ctx.State[1][0] = aes_ctx.State[1][1];
450 aes_ctx.State[1][1] = aes_ctx.State[1][2];
451 aes_ctx.State[1][2] = aes_ctx.State[1][3];
452 aes_ctx.State[1][3] = Temp;
453 Temp = aes_ctx.State[2][0];
454 aes_ctx.State[2][0] = aes_ctx.State[2][2];
455 aes_ctx.State[2][2] = Temp;
456 Temp = aes_ctx.State[2][1];
457 aes_ctx.State[2][1] = aes_ctx.State[2][3];
458 aes_ctx.State[2][3] = Temp;
459 Temp = aes_ctx.State[3][3];
460 aes_ctx.State[3][3] = aes_ctx.State[3][2];
461 aes_ctx.State[3][2] = aes_ctx.State[3][1];
462 aes_ctx.State[3][1] = aes_ctx.State[3][0];
463 aes_ctx.State[3][0] = Temp;
464 /* AES_AddRoundKey */
465 for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
466 for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
467 aes_ctx.State[RowIndex][ColumnIndex] ^= aes_ctx.KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex];
470 * 4. Transfer the state block to cipher block
472 for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
473 for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
474 CipherBlock[RowIndex + 4*ColumnIndex] = aes_ctx.State[RowIndex][ColumnIndex];
476 *CipherBlockSize = ((UINT) AES_STATE_ROWS)*((UINT) AES_STATE_COLUMNS);
477 } /* End of AES_Encrypt */
481 ========================================================================
486 CipherBlock The block of cipher text, 16 bytes(128 bits) each block
487 CipherBlockSize The length of block of cipher text in bytes
488 Key Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits)
489 KeyLength The length of cipher key in bytes
490 PlainBlockSize The length of allocated plain block in bytes
493 PlainBlock Return plain text
494 PlainBlockSize Return the length of real used plain block in bytes
497 Reference to FIPS-PUB 197
498 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)
499 2. Transfer the cipher block to state block
500 3. Main decryption rounds
501 4. Transfer the state block to plain block
502 ------------------------------------------
503 NumberOfRound = (key length / 4) + 6;
504 state block = cipher block;
506 AddRoundKey(state block, key);
507 for round = NumberOfRound to 1
508 InvSubBytes(state block)
509 InvShiftRows(state block)
510 InvMixColumns(state block)
511 AddRoundKey(state block, key);
514 InvSubBytes(state block)
515 InvShiftRows(state block)
516 AddRoundKey(state block, key);
518 plain block = state block;
519 ========================================================================
522 IN UINT8 CipherBlock[],
523 IN UINT CipherBlockSize,
526 OUT UINT8 PlainBlock[],
527 INOUT UINT *PlainBlockSize)
529 AES_CTX_STRUC aes_ctx;
530 UINT RowIndex, ColumnIndex;
531 UINT RoundIndex, NumberOfRound = 0;
532 UINT8 Temp, Row0, Row1, Row2, Row3;
535 * 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)
537 if (*PlainBlockSize < AES_BLOCK_SIZES) {
538 DBGPRINT(RT_DEBUG_ERROR, ("AES_Decrypt: plain block size is %d bytes, it must be %d bytes(128 bits).\n",
539 *PlainBlockSize, AES_BLOCK_SIZES));
542 if ((KeyLength != AES_KEY128_LENGTH) && (KeyLength != AES_KEY192_LENGTH) && (KeyLength != AES_KEY256_LENGTH)) {
543 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",
544 KeyLength, AES_KEY128_LENGTH, AES_KEY192_LENGTH, AES_KEY256_LENGTH));
547 if (CipherBlockSize != AES_BLOCK_SIZES) {
548 DBGPRINT(RT_DEBUG_ERROR, ("AES_Decrypt: cipher block size is %d bytes, it must be %d bytes(128 bits).\n",
549 CipherBlockSize, AES_BLOCK_SIZES));
554 * 2. Transfer the cipher block to state block
556 for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
557 for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
558 aes_ctx.State[RowIndex][ColumnIndex] = CipherBlock[RowIndex + 4*ColumnIndex];
561 * 3. Main decryption rounds
563 AES_KeyExpansion(Key, KeyLength, &aes_ctx);
564 NumberOfRound = (KeyLength >> 2) + 6;
566 /* AES_AddRoundKey */
567 RoundIndex = NumberOfRound;
568 for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
569 for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
570 aes_ctx.State[RowIndex][ColumnIndex] ^= aes_ctx.KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex];
572 for (RoundIndex = (NumberOfRound - 1); RoundIndex > 0 ;RoundIndex--)
574 /* AES_InvShiftRows */
575 Temp = aes_ctx.State[1][3];
576 aes_ctx.State[1][3] = aes_ctx.State[1][2];
577 aes_ctx.State[1][2] = aes_ctx.State[1][1];
578 aes_ctx.State[1][1] = aes_ctx.State[1][0];
579 aes_ctx.State[1][0] = Temp;
580 Temp = aes_ctx.State[2][0];
581 aes_ctx.State[2][0] = aes_ctx.State[2][2];
582 aes_ctx.State[2][2] = Temp;
583 Temp = aes_ctx.State[2][1];
584 aes_ctx.State[2][1] = aes_ctx.State[2][3];
585 aes_ctx.State[2][3] = Temp;
586 Temp = aes_ctx.State[3][0];
587 aes_ctx.State[3][0] = aes_ctx.State[3][1];
588 aes_ctx.State[3][1] = aes_ctx.State[3][2];
589 aes_ctx.State[3][2] = aes_ctx.State[3][3];
590 aes_ctx.State[3][3] = Temp;
592 /* AES_InvSubBytes */
593 for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
594 for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
595 aes_ctx.State[RowIndex][ColumnIndex] = aes_sbox_dec[aes_ctx.State[RowIndex][ColumnIndex]];
597 /* AES_AddRoundKey */
598 for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
599 for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
600 aes_ctx.State[RowIndex][ColumnIndex] ^= aes_ctx.KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex];
602 /* AES_InvMixColumns */
603 for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
605 Row0 = aes_ctx.State[0][ColumnIndex];
606 Row1 = aes_ctx.State[1][ColumnIndex];
607 Row2 = aes_ctx.State[2][ColumnIndex];
608 Row3 = aes_ctx.State[3][ColumnIndex];
609 aes_ctx.State[0][ColumnIndex] = aes_mul_e[Row0]^aes_mul_b[Row1]^aes_mul_d[Row2]^aes_mul_9[Row3];
610 aes_ctx.State[1][ColumnIndex] = aes_mul_9[Row0]^aes_mul_e[Row1]^aes_mul_b[Row2]^aes_mul_d[Row3];
611 aes_ctx.State[2][ColumnIndex] = aes_mul_d[Row0]^aes_mul_9[Row1]^aes_mul_e[Row2]^aes_mul_b[Row3];
612 aes_ctx.State[3][ColumnIndex] = aes_mul_b[Row0]^aes_mul_d[Row1]^aes_mul_9[Row2]^aes_mul_e[Row3];
616 /* AES_InvShiftRows */
617 Temp = aes_ctx.State[1][3];
618 aes_ctx.State[1][3] = aes_ctx.State[1][2];
619 aes_ctx.State[1][2] = aes_ctx.State[1][1];
620 aes_ctx.State[1][1] = aes_ctx.State[1][0];
621 aes_ctx.State[1][0] = Temp;
622 Temp = aes_ctx.State[2][0];
623 aes_ctx.State[2][0] = aes_ctx.State[2][2];
624 aes_ctx.State[2][2] = Temp;
625 Temp = aes_ctx.State[2][1];
626 aes_ctx.State[2][1] = aes_ctx.State[2][3];
627 aes_ctx.State[2][3] = Temp;
628 Temp = aes_ctx.State[3][0];
629 aes_ctx.State[3][0] = aes_ctx.State[3][1];
630 aes_ctx.State[3][1] = aes_ctx.State[3][2];
631 aes_ctx.State[3][2] = aes_ctx.State[3][3];
632 aes_ctx.State[3][3] = Temp;
633 /* AES_InvSubBytes */
634 for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
635 for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
636 aes_ctx.State[RowIndex][ColumnIndex] = aes_sbox_dec[aes_ctx.State[RowIndex][ColumnIndex]];
637 /* AES_AddRoundKey */
638 for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
639 for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
640 aes_ctx.State[RowIndex][ColumnIndex] ^= aes_ctx.KeyWordExpansion[RowIndex][(RoundIndex*((UINT) AES_STATE_COLUMNS)) + ColumnIndex];
643 * 4. Transfer the state block to plain block
645 for (RowIndex = 0; RowIndex < AES_STATE_ROWS;RowIndex++)
646 for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
647 PlainBlock[RowIndex + 4*ColumnIndex] = aes_ctx.State[RowIndex][ColumnIndex];
649 *PlainBlockSize = ((UINT) AES_STATE_ROWS)*((UINT) AES_STATE_COLUMNS);
650 } /* End of AES_Decrypt */
654 ========================================================================
660 PlainTextLength The length of plain text in bytes
661 Key Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits)
662 KeyLength The length of cipher key in bytes
663 IV Initialization vector, it may be 16 bytes (128 bits)
664 IVLength The length of initialization vector in bytes
665 CipherTextLength The length of allocated cipher text in bytes
668 CipherText Return cipher text
669 CipherTextLength Return the length of real used cipher text in bytes
672 Reference to RFC 3602 and NIST 800-38A
673 ========================================================================
675 VOID AES_CBC_Encrypt (
676 IN UINT8 PlainText[],
677 IN UINT PlainTextLength,
682 OUT UINT8 CipherText[],
683 INOUT UINT *CipherTextLength)
685 UINT PaddingSize, PlainBlockStart, CipherBlockStart, CipherBlockSize;
687 UINT8 Block[AES_BLOCK_SIZES];
690 * 1. Check the input parameters
691 * - CipherTextLength > (PlainTextLength + Padding size), Padding size = block size - (PlainTextLength % block size)
692 * - Key length must be 16, 24, or 32 bytes(128, 192, or 256 bits)
693 * - IV length must be 16 bytes(128 bits)
695 PaddingSize = ((UINT) AES_BLOCK_SIZES) - (PlainTextLength % ((UINT)AES_BLOCK_SIZES));
696 if (*CipherTextLength < (PlainTextLength + PaddingSize)) {
697 DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Encrypt: cipher text length is %d bytes < (plain text length %d bytes + padding size %d bytes).\n",
698 *CipherTextLength, PlainTextLength, PaddingSize));
701 if ((KeyLength != AES_KEY128_LENGTH) && (KeyLength != AES_KEY192_LENGTH) && (KeyLength != AES_KEY256_LENGTH)) {
702 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",
703 KeyLength, AES_KEY128_LENGTH, AES_KEY192_LENGTH, AES_KEY256_LENGTH));
706 if (IVLength != AES_CBC_IV_LENGTH) {
707 DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Encrypt: IV length is %d bytes, it must be %d bytes(128bits).\n",
708 IVLength, AES_CBC_IV_LENGTH));
715 * - Plain text divide into serveral blocks (16 bytes/block)
716 * - If plain text is divided with no remainder by block, add a new block and padding size = block(16 bytes)
717 * - If plain text is not divided with no remainder by block, padding size = (block - remainder plain text)
718 * - Execute AES_Encrypt procedure.
720 * - Padding method: The remainder bytes will be filled with padding size (1 byte)
723 CipherBlockStart = 0;
724 while ((PlainTextLength - PlainBlockStart) >= AES_BLOCK_SIZES)
726 if (CipherBlockStart == 0) {
727 for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
728 Block[Index] = PlainText[PlainBlockStart + Index]^IV[Index];
730 for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
731 Block[Index] = PlainText[PlainBlockStart + Index]^CipherText[CipherBlockStart - ((UINT) AES_BLOCK_SIZES) + Index];
734 CipherBlockSize = *CipherTextLength - CipherBlockStart;
735 AES_Encrypt(Block, AES_BLOCK_SIZES , Key, KeyLength, CipherText + CipherBlockStart, &CipherBlockSize);
737 PlainBlockStart += ((UINT) AES_BLOCK_SIZES);
738 CipherBlockStart += CipherBlockSize;
741 NdisMoveMemory(Block, (&PlainText[0] + PlainBlockStart), (PlainTextLength - PlainBlockStart));
742 NdisFillMemory((Block + (((UINT) AES_BLOCK_SIZES) -PaddingSize)), PaddingSize, (UINT8) PaddingSize);
743 if (CipherBlockStart == 0) {
744 for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
745 Block[Index] ^= IV[Index];
747 for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
748 Block[Index] ^= CipherText[CipherBlockStart - ((UINT) AES_BLOCK_SIZES) + Index];
750 CipherBlockSize = *CipherTextLength - CipherBlockStart;
751 AES_Encrypt(Block, AES_BLOCK_SIZES , Key, KeyLength, CipherText + CipherBlockStart, &CipherBlockSize);
752 CipherBlockStart += CipherBlockSize;
753 *CipherTextLength = CipherBlockStart;
754 } /* End of AES_CBC_Encrypt */
758 ========================================================================
763 CipherText Cipher text
764 CipherTextLength The length of cipher text in bytes
765 Key Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits)
766 KeyLength The length of cipher key in bytes
767 IV Initialization vector, it may be 16 bytes (128 bits)
768 IVLength The length of initialization vector in bytes
769 PlainTextLength The length of allocated plain text in bytes
772 PlainText Return plain text
773 PlainTextLength Return the length of real used plain text in bytes
776 Reference to RFC 3602 and NIST 800-38A
777 ========================================================================
779 VOID AES_CBC_Decrypt (
780 IN UINT8 CipherText[],
781 IN UINT CipherTextLength,
786 OUT UINT8 PlainText[],
787 INOUT UINT *PlainTextLength)
789 UINT PaddingSize, PlainBlockStart, CipherBlockStart, PlainBlockSize;
793 * 1. Check the input parameters
794 * - CipherTextLength must be divided with no remainder by block
795 * - Key length must be 16, 24, or 32 bytes(128, 192, or 256 bits)
796 * - IV length must be 16 bytes(128 bits)
798 if ((CipherTextLength % AES_BLOCK_SIZES) != 0) {
799 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",
800 CipherTextLength, AES_BLOCK_SIZES));
803 if ((KeyLength != AES_KEY128_LENGTH) && (KeyLength != AES_KEY192_LENGTH) && (KeyLength != AES_KEY256_LENGTH)) {
804 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",
805 KeyLength, AES_KEY128_LENGTH, AES_KEY192_LENGTH, AES_KEY256_LENGTH));
808 if (IVLength != AES_CBC_IV_LENGTH) {
809 DBGPRINT(RT_DEBUG_ERROR, ("AES_CBC_Decrypt: IV length is %d bytes, it must be %d bytes(128bits).\n",
810 IVLength, AES_CBC_IV_LENGTH));
817 * - Cypher text divide into serveral blocks (16 bytes/block)
818 * - Execute AES_Decrypt procedure.
819 * - Remove padding bytes, padding size is the last byte of plain text
821 CipherBlockStart = 0;
823 while ((CipherTextLength - CipherBlockStart) >= AES_BLOCK_SIZES)
825 PlainBlockSize = *PlainTextLength - PlainBlockStart;
826 AES_Decrypt(CipherText + CipherBlockStart, AES_BLOCK_SIZES , Key, KeyLength, PlainText + PlainBlockStart, &PlainBlockSize);
828 if (PlainBlockStart == 0) {
829 for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
830 PlainText[PlainBlockStart + Index] ^= IV[Index];
832 for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
833 PlainText[PlainBlockStart + Index] ^= CipherText[CipherBlockStart + Index - ((UINT) AES_BLOCK_SIZES)];
836 CipherBlockStart += AES_BLOCK_SIZES;
837 PlainBlockStart += PlainBlockSize;
840 PaddingSize = (UINT8) PlainText[PlainBlockStart -1];
841 *PlainTextLength = PlainBlockStart - PaddingSize;
843 } /* End of AES_CBC_Encrypt */
848 ========================================================================
850 AES-CMAC generate subkey
853 Key Cipher key 128 bits
854 KeyLength The length of Cipher key in bytes
857 SubKey1 SubKey 1 128 bits
858 SubKey2 SubKey 2 128 bits
861 Reference to RFC 4493
863 Step 1. L := AES-128(K, const_Zero);
864 Step 2. if MSB(L) is equal to 0
866 else K1 := (L << 1) XOR const_Rb;
867 Step 3. if MSB(K1) is equal to 0
869 else K2 := (K1 << 1) XOR const_Rb;
870 Step 4. return K1, K2;
871 ========================================================================
873 VOID AES_CMAC_GenerateSubKey (
879 UINT8 MSB_L = 0, MSB_K1 = 0, Top_Bit = 0;
880 UINT SubKey1_Length = 0;
883 if (KeyLength != AES_KEY128_LENGTH) {
884 DBGPRINT(RT_DEBUG_ERROR, ("AES_CMAC_GenerateSubKey: key length is %d bytes, it must be %d bytes(128 bits).\n",
885 KeyLength, AES_KEY128_LENGTH));
889 /* Step 1: L := AES-128(K, const_Zero); */
891 AES_Encrypt(Const_Zero, sizeof(Const_Zero), Key, KeyLength, SubKey1, &SubKey1_Length);
894 * Step 2. if MSB(L) is equal to 0
896 * else K1 := (L << 1) XOR const_Rb;
898 MSB_L = SubKey1[0] & 0x80;
899 for(Index = 0; Index < 15; Index++) {
900 Top_Bit = (SubKey1[Index + 1] & 0x80)?1:0;
901 SubKey1[Index] <<= 1;
902 SubKey1[Index] |= Top_Bit;
906 for(Index = 0; Index < 16; Index++)
907 SubKey1[Index] ^= Const_Rb[Index];
911 * Step 3. if MSB(K1) is equal to 0
912 * then K2 := K1 << 1;
913 * else K2 := (K1 << 1) XOR const_Rb;
915 MSB_K1 = SubKey1[0] & 0x80;
916 for(Index = 0; Index < 15; Index++) {
917 Top_Bit = (SubKey1[Index + 1] & 0x80)?1:0;
918 SubKey2[Index] = SubKey1[Index] << 1;
919 SubKey2[Index] |= Top_Bit;
921 SubKey2[15] = SubKey1[15] << 1;
923 for(Index = 0; Index < 16; Index++)
924 SubKey2[Index] ^= Const_Rb[Index];
926 } /* End of AES_CMAC_GenerateSubKey */
930 ========================================================================
936 PlainTextLength The length of plain text in bytes
937 Key Cipher key, it may be 16, 24, or 32 bytes (128, 192, or 256 bits)
938 KeyLength The length of cipher key in bytes
939 MACTextLength The length of allocated memory spaces in bytes
942 MACText Message authentication code (128-bit string)
943 MACTextLength Return the length of Message authentication code in bytes
946 Reference to RFC 4493
947 ========================================================================
950 IN UINT8 PlainText[],
951 IN UINT PlainTextLength,
955 INOUT UINT *MACTextLength)
957 UINT PlainBlockStart;
958 UINT8 X[AES_BLOCK_SIZES], Y[AES_BLOCK_SIZES];
963 if (*MACTextLength < AES_MAC_LENGTH) {
964 DBGPRINT(RT_DEBUG_ERROR, ("AES_CMAC: MAC text length is less than %d bytes).\n",
968 if (KeyLength != AES_KEY128_LENGTH) {
969 DBGPRINT(RT_DEBUG_ERROR, ("AES_CMAC: key length is %d bytes, it must be %d bytes(128 bits).\n",
970 KeyLength, AES_KEY128_LENGTH));
974 /* Step 1. (K1,K2) := Generate_Subkey(K); */
975 NdisZeroMemory(SubKey1, 16);
976 NdisZeroMemory(SubKey2, 16);
977 AES_CMAC_GenerateSubKey(Key, KeyLength, SubKey1, SubKey2);
981 * - Plain text divide into serveral blocks (16 bytes/block)
982 * - If plain text is not divided with no remainder by block, padding size = (block - remainder plain text)
983 * - Execute AES_Encrypt procedure.
986 NdisMoveMemory(X, Const_Zero, AES_BLOCK_SIZES);
987 while ((PlainTextLength - PlainBlockStart) > AES_BLOCK_SIZES)
989 for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
990 Y[Index] = PlainText[PlainBlockStart + Index]^X[Index];
992 X_Length = sizeof(X);
993 AES_Encrypt(Y, sizeof(Y) , Key, KeyLength, X, &X_Length);
994 PlainBlockStart += ((UINT) AES_BLOCK_SIZES);
996 if ((PlainTextLength - PlainBlockStart) == AES_BLOCK_SIZES) {
997 for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
998 Y[Index] = PlainText[PlainBlockStart + Index]^X[Index]^SubKey1[Index];
1000 NdisZeroMemory(Y, AES_BLOCK_SIZES);
1001 NdisMoveMemory(Y, &PlainText[PlainBlockStart], (PlainTextLength - PlainBlockStart));
1002 Y[(PlainTextLength - PlainBlockStart)] = 0x80;
1003 for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
1004 Y[Index] = Y[Index]^X[Index]^SubKey2[Index];
1006 AES_Encrypt(Y, sizeof(Y) , Key, KeyLength, MACText, MACTextLength);
1007 } /* End of AES_CMAC */