- supported.conf: Added sparse_keymap (eeepc_laptop depends on it)
[linux-flexiantxendom0-3.2.10.git] / drivers / staging / rt3090 / common / crypt_aes.c
1 /*
2  *************************************************************************
3  * Ralink Tech Inc.
4  * 5F., No.36, Taiyuan St., Jhubei City,
5  * Hsinchu County 302,
6  * Taiwan, R.O.C.
7  *
8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
9  *
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.                                   *
14  *                                                                       *
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.                          *
19  *                                                                       *
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.             *
24  *                                                                       *
25  *************************************************************************
26
27         Module Name:
28         crypt_aes.c
29
30         Abstract:
31
32         Revision History:
33         Who                     When                    What
34         --------        ----------              ----------------------------------------------
35         Eddy        2009/01/19      Create AES-128, AES-192, AES-256, AES-CBC
36 */
37
38 #include "crypt_aes.h"
39
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};
45
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 */
64 };
65
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 */
84 };
85
86 /* ArrayIndex*{02} */
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 */
105 };
106
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 */
126 };
127
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 */
147 };
148
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 */
168 };
169
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 */
189 };
190
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 */
210 };
211
212
213 /* For AES_CMAC */
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};
219
220
221 /*
222 ========================================================================
223 Routine Description:
224     AES key expansion (key schedule)
225
226 Arguments:
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
230
231 Return Value:
232     paes_ctx         Retrun the KeyWordExpansion of AES_CTX_STRUC
233
234 Note:
235     Pseudo code for key expansion
236     ------------------------------------------
237        Nk = (key length/4);
238
239        while (i < Nk)
240            KeyWordExpansion[i] = word(key[4*i], key[4*i + 1], key[4*i + 2], key[4*i + 3]);
241            i++;
242        end while
243
244        while (i < ((key length/4 + 6 + 1)*4) )
245            temp = KeyWordExpansion[i - 1];
246            if (i % Nk ==0)
247                temp = SubWord(RotWord(temp)) ^ Rcon[i/Nk];
248            else if ((Nk > 6) && (i % 4 == 4))
249                temp = SubWord(temp);
250            end if
251
252            KeyWordExpansion[i] = KeyWordExpansion[i - Nk]^ temp;
253            i++;
254        end while
255 ========================================================================
256 */
257 VOID AES_KeyExpansion (
258     IN UINT8 Key[],
259     IN UINT KeyLength,
260     INOUT AES_CTX_STRUC *paes_ctx)
261 {
262     UINT KeyIndex = 0;
263     UINT NumberOfWordOfKey, NumberOfWordOfKeyExpansion;
264     UINT8  TempWord[AES_KEY_ROWS], Temp;
265     UINT32 Temprcon;
266
267     NumberOfWordOfKey = KeyLength >> 2;
268     while (KeyIndex < NumberOfWordOfKey)
269     {
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];
274         KeyIndex++;
275     } /* End of while */
276
277     NumberOfWordOfKeyExpansion = ((UINT) AES_KEY_ROWS) * ((KeyLength >> 2) + 6 + 1);
278     while (KeyIndex < NumberOfWordOfKeyExpansion)
279     {
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);
290             TempWord[0] = Temp;
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]];
296             TempWord[0] = Temp;
297         }
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];
302         KeyIndex++;
303     } /* End of while */
304 } /* End of AES_KeyExpansion */
305
306
307 /*
308 ========================================================================
309 Routine Description:
310     AES encryption
311
312 Arguments:
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
318
319 Return Value:
320     CipherBlock      Return cipher text
321     CipherBlockSize  Return the length of real used cipher block in bytes
322
323 Note:
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;
332
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);
339        end for
340
341        SubBytes(state block)
342        ShiftRows(state block)
343        AddRoundKey(state block, key);
344
345        cipher block = state block;
346 ========================================================================
347 */
348 VOID AES_Encrypt (
349     IN UINT8 PlainBlock[],
350     IN UINT PlainBlockSize,
351     IN UINT8 Key[],
352     IN UINT KeyLength,
353     OUT UINT8 CipherBlock[],
354     INOUT UINT *CipherBlockSize)
355 {
356     AES_CTX_STRUC aes_ctx;
357     UINT RowIndex, ColumnIndex;
358     UINT RoundIndex, NumberOfRound = 0;
359     UINT8 Temp, Row0, Row1, Row2, Row3;
360
361     /*
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)
363      */
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));
367         return;
368     } /* End of if */
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));
372         return;
373     } /* End of if */
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));
377         return;
378     } /* End of if */
379
380     /*
381      * 2. Transfer the plain block to state block
382      */
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];
386
387     /*
388      *  3. Main encryption rounds
389      */
390     AES_KeyExpansion(Key, KeyLength, &aes_ctx);
391     NumberOfRound = (KeyLength >> 2) + 6;
392
393     /* AES_AddRoundKey */
394     RoundIndex = 0;
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];
398
399     for (RoundIndex = 1; RoundIndex < NumberOfRound;RoundIndex++)
400     {
401         /* AES_SubBytes */
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]];
405
406         /* AES_ShiftRows */
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;
423
424         /* AES_MixColumns */
425         for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
426         {
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];
435         }
436
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];
441     } /* End of for */
442
443     /* AES_SubBytes */
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]];
447     /* AES_ShiftRows */
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];
468
469     /*
470      * 4. Transfer the state block to cipher block
471      */
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];
475
476     *CipherBlockSize = ((UINT) AES_STATE_ROWS)*((UINT) AES_STATE_COLUMNS);
477 } /* End of AES_Encrypt */
478
479
480 /*
481 ========================================================================
482 Routine Description:
483     AES decryption
484
485 Arguments:
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
491
492 Return Value:
493     PlainBlock       Return plain text
494     PlainBlockSize  Return the length of real used plain block in bytes
495
496 Note:
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;
505
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);
512        end for
513
514        InvSubBytes(state block)
515        InvShiftRows(state block)
516        AddRoundKey(state block, key);
517
518        plain block = state block;
519 ========================================================================
520 */
521 VOID AES_Decrypt (
522     IN UINT8 CipherBlock[],
523     IN UINT CipherBlockSize,
524     IN UINT8 Key[],
525     IN UINT KeyLength,
526     OUT UINT8 PlainBlock[],
527     INOUT UINT *PlainBlockSize)
528 {
529     AES_CTX_STRUC aes_ctx;
530     UINT RowIndex, ColumnIndex;
531     UINT RoundIndex, NumberOfRound = 0;
532     UINT8 Temp, Row0, Row1, Row2, Row3;
533
534     /*
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)
536      */
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));
540         return;
541     } /* End of if */
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));
545         return;
546     } /* End of if */
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));
550         return;
551     } /* End of if */
552
553     /*
554      * 2. Transfer the cipher block to state block
555      */
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];
559
560     /*
561      *  3. Main decryption rounds
562      */
563     AES_KeyExpansion(Key, KeyLength, &aes_ctx);
564     NumberOfRound = (KeyLength >> 2) + 6;
565
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];
571
572     for (RoundIndex = (NumberOfRound - 1); RoundIndex > 0 ;RoundIndex--)
573     {
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;
591
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]];
596
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];
601
602         /* AES_InvMixColumns */
603         for (ColumnIndex = 0; ColumnIndex < AES_STATE_COLUMNS;ColumnIndex++)
604         {
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];
613         }
614     } /* End of for */
615
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];
641
642     /*
643      * 4. Transfer the state block to plain block
644      */
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];
648
649     *PlainBlockSize = ((UINT) AES_STATE_ROWS)*((UINT) AES_STATE_COLUMNS);
650 } /* End of AES_Decrypt */
651
652
653 /*
654 ========================================================================
655 Routine Description:
656     AES-CBC encryption
657
658 Arguments:
659     PlainText        Plain text
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
666
667 Return Value:
668     CipherText       Return cipher text
669     CipherTextLength Return the length of real used cipher text in bytes
670
671 Note:
672     Reference to RFC 3602 and NIST 800-38A
673 ========================================================================
674 */
675 VOID AES_CBC_Encrypt (
676     IN UINT8 PlainText[],
677     IN UINT PlainTextLength,
678     IN UINT8 Key[],
679     IN UINT KeyLength,
680     IN UINT8 IV[],
681     IN UINT IVLength,
682     OUT UINT8 CipherText[],
683     INOUT UINT *CipherTextLength)
684 {
685     UINT PaddingSize, PlainBlockStart, CipherBlockStart, CipherBlockSize;
686     UINT Index;
687     UINT8 Block[AES_BLOCK_SIZES];
688
689     /*
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)
694      */
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));
699         return;
700     } /* End of if */
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));
704         return;
705     } /* End of if */
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));
709         return;
710     } /* End of if */
711
712
713     /*
714      * 2. Main algorithm
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.
719      *
720      *    - Padding method: The remainder bytes will be filled with padding size (1 byte)
721      */
722     PlainBlockStart = 0;
723     CipherBlockStart = 0;
724     while ((PlainTextLength - PlainBlockStart) >= AES_BLOCK_SIZES)
725     {
726         if (CipherBlockStart == 0) {
727             for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
728                 Block[Index] = PlainText[PlainBlockStart + Index]^IV[Index];
729         } else {
730             for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
731                 Block[Index] = PlainText[PlainBlockStart + Index]^CipherText[CipherBlockStart - ((UINT) AES_BLOCK_SIZES) + Index];
732         } /* End of if */
733
734         CipherBlockSize = *CipherTextLength - CipherBlockStart;
735         AES_Encrypt(Block, AES_BLOCK_SIZES , Key, KeyLength, CipherText + CipherBlockStart, &CipherBlockSize);
736
737         PlainBlockStart += ((UINT) AES_BLOCK_SIZES);
738         CipherBlockStart += CipherBlockSize;
739     } /* End of while */
740
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];
746     } else {
747        for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
748            Block[Index] ^= CipherText[CipherBlockStart - ((UINT) AES_BLOCK_SIZES) + Index];
749     } /* End of if */
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 */
755
756
757 /*
758 ========================================================================
759 Routine Description:
760     AES-CBC decryption
761
762 Arguments:
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
770
771 Return Value:
772     PlainText        Return plain text
773     PlainTextLength  Return the length of real used plain text in bytes
774
775 Note:
776     Reference to RFC 3602 and NIST 800-38A
777 ========================================================================
778 */
779 VOID AES_CBC_Decrypt (
780     IN UINT8 CipherText[],
781     IN UINT CipherTextLength,
782     IN UINT8 Key[],
783     IN UINT KeyLength,
784     IN UINT8 IV[],
785     IN UINT IVLength,
786     OUT UINT8 PlainText[],
787     INOUT UINT *PlainTextLength)
788 {
789     UINT PaddingSize, PlainBlockStart, CipherBlockStart, PlainBlockSize;
790     UINT Index;
791
792     /*
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)
797      */
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));
801         return;
802     } /* End of if */
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));
806         return;
807     } /* End of if */
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));
811         return;
812     } /* End of if */
813
814
815     /*
816      * 2. Main algorithm
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
820      */
821     CipherBlockStart = 0;
822     PlainBlockStart = 0;
823     while ((CipherTextLength - CipherBlockStart) >= AES_BLOCK_SIZES)
824     {
825         PlainBlockSize = *PlainTextLength - PlainBlockStart;
826         AES_Decrypt(CipherText + CipherBlockStart, AES_BLOCK_SIZES , Key, KeyLength, PlainText + PlainBlockStart, &PlainBlockSize);
827
828         if (PlainBlockStart == 0) {
829             for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
830                 PlainText[PlainBlockStart + Index] ^= IV[Index];
831         } else {
832             for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
833                 PlainText[PlainBlockStart + Index] ^= CipherText[CipherBlockStart + Index - ((UINT) AES_BLOCK_SIZES)];
834         } /* End of if */
835
836         CipherBlockStart += AES_BLOCK_SIZES;
837         PlainBlockStart += PlainBlockSize;
838     } /* End of while */
839
840     PaddingSize = (UINT8) PlainText[PlainBlockStart -1];
841     *PlainTextLength = PlainBlockStart - PaddingSize;
842
843 } /* End of AES_CBC_Encrypt */
844
845
846
847 /*
848 ========================================================================
849 Routine Description:
850     AES-CMAC generate subkey
851
852 Arguments:
853     Key        Cipher key 128 bits
854     KeyLength  The length of Cipher key in bytes
855
856 Return Value:
857     SubKey1    SubKey 1 128 bits
858     SubKey2    SubKey 2 128 bits
859
860 Note:
861     Reference to RFC 4493
862
863     Step 1.  L := AES-128(K, const_Zero);
864     Step 2.  if MSB(L) is equal to 0
865                 then    K1 := L << 1;
866                 else    K1 := (L << 1) XOR const_Rb;
867     Step 3.  if MSB(K1) is equal to 0
868                 then    K2 := K1 << 1;
869                 else    K2 := (K1 << 1) XOR const_Rb;
870     Step 4.  return K1, K2;
871 ========================================================================
872 */
873 VOID AES_CMAC_GenerateSubKey (
874     IN UINT8 Key[],
875     IN UINT KeyLength,
876     OUT UINT8 SubKey1[],
877     OUT UINT8 SubKey2[])
878 {
879     UINT8 MSB_L = 0, MSB_K1 = 0, Top_Bit = 0;
880     UINT  SubKey1_Length = 0;
881     INT   Index = 0;
882
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));
886         return;
887     } /* End of if */
888
889     /* Step 1: L := AES-128(K, const_Zero); */
890     SubKey1_Length = 16;
891     AES_Encrypt(Const_Zero, sizeof(Const_Zero), Key, KeyLength, SubKey1, &SubKey1_Length);
892
893     /*
894      * Step 2.  if MSB(L) is equal to 0
895      *           then    K1 := L << 1;
896      *           else    K1 := (L << 1) XOR const_Rb;
897      */
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;
903     }
904     SubKey1[15] <<= 1;
905     if (MSB_L > 0) {
906         for(Index = 0; Index < 16; Index++)
907             SubKey1[Index] ^= Const_Rb[Index];
908     } /* End of if */
909
910     /*
911      * Step 3.  if MSB(K1) is equal to 0
912      *           then    K2 := K1 << 1;
913      *           else    K2 := (K1 << 1) XOR const_Rb;
914      */
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;
920     }
921     SubKey2[15] = SubKey1[15] << 1;
922     if (MSB_K1 > 0) {
923         for(Index = 0; Index < 16; Index++)
924             SubKey2[Index] ^= Const_Rb[Index];
925     } /* End of if */
926 } /* End of AES_CMAC_GenerateSubKey */
927
928
929 /*
930 ========================================================================
931 Routine Description:
932     AES-CMAC
933
934 Arguments:
935     PlainText        Plain text
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
940
941 Return Value:
942     MACText       Message authentication code (128-bit string)
943     MACTextLength Return the length of Message authentication code in bytes
944
945 Note:
946     Reference to RFC 4493
947 ========================================================================
948 */
949 VOID AES_CMAC (
950     IN UINT8 PlainText[],
951     IN UINT PlainTextLength,
952     IN UINT8 Key[],
953     IN UINT KeyLength,
954     OUT UINT8 MACText[],
955     INOUT UINT *MACTextLength)
956 {
957     UINT  PlainBlockStart;
958     UINT8 X[AES_BLOCK_SIZES], Y[AES_BLOCK_SIZES];
959     UINT8 SubKey1[16];
960     UINT8 SubKey2[16];
961     INT X_Length, Index;
962
963     if (*MACTextLength < AES_MAC_LENGTH) {
964         DBGPRINT(RT_DEBUG_ERROR, ("AES_CMAC: MAC text length is less than %d bytes).\n",
965             AES_MAC_LENGTH));
966         return;
967     } /* End of if */
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));
971         return;
972     } /* End of if */
973
974     /* Step 1.  (K1,K2) := Generate_Subkey(K); */
975     NdisZeroMemory(SubKey1, 16);
976     NdisZeroMemory(SubKey2, 16);
977     AES_CMAC_GenerateSubKey(Key, KeyLength, SubKey1, SubKey2);
978
979     /*
980      * 2. Main algorithm
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.
984      */
985     PlainBlockStart = 0;
986     NdisMoveMemory(X, Const_Zero, AES_BLOCK_SIZES);
987     while ((PlainTextLength - PlainBlockStart) > AES_BLOCK_SIZES)
988     {
989         for (Index = 0; Index < AES_BLOCK_SIZES; Index++)
990                 Y[Index] = PlainText[PlainBlockStart + Index]^X[Index];
991
992         X_Length = sizeof(X);
993         AES_Encrypt(Y, sizeof(Y) , Key, KeyLength, X, &X_Length);
994         PlainBlockStart += ((UINT) AES_BLOCK_SIZES);
995     } /* End of while */
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];
999     } else {
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];
1005     } /* End of if */
1006     AES_Encrypt(Y, sizeof(Y) , Key, KeyLength, MACText, MACTextLength);
1007 } /* End of AES_CMAC */