]> git.proxmox.com Git - mirror_edk2.git/blob - SecurityPkg/RandomNumberGenerator/RngDxe/AesCore.c
Add UEFI RNG Protocol support. The driver will leverage Intel Secure Key technology...
[mirror_edk2.git] / SecurityPkg / RandomNumberGenerator / RngDxe / AesCore.c
1 /** @file
2 Core Primitive Implementation of the Advanced Encryption Standard (AES) algorithm.
3 Refer to FIPS PUB 197 ("Advanced Encryption Standard (AES)") for detailed algorithm
4 description of AES.
5
6 Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
11
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
15 **/
16
17 #include "AesCore.h"
18
19 //
20 // Number of columns (32-bit words) comprising the State.
21 // AES_NB is a constant (value = 4) for NIST FIPS-197.
22 //
23 #define AES_NB 4
24
25 //
26 // Pre-computed AES Forward Table: AES_ETABLE[t] = AES_SBOX[t].[02, 01, 01, 03]
27 // This is to speed up execution of the cipher by combining SubBytes and
28 // ShiftRows with MixColumns steps and transforming them into table lookups.
29 //
30 GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 AES_FTABLE[] = {
31 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, 0xfff2f20d, 0xd66b6bbd,
32 0xde6f6fb1, 0x91c5c554, 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
33 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a, 0x8fcaca45, 0x1f82829d,
34 0x89c9c940, 0xfa7d7d87, 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
35 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, 0x239c9cbf, 0x53a4a4f7,
36 0xe4727296, 0x9bc0c05b, 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
37 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f, 0x6834345c, 0x51a5a5f4,
38 0xd1e5e534, 0xf9f1f108, 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
39 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, 0x30181828, 0x379696a1,
40 0x0a05050f, 0x2f9a9ab5, 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
41 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f, 0x1209091b, 0x1d83839e,
42 0x582c2c74, 0x341a1a2e, 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
43 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, 0x5229297b, 0xdde3e33e,
44 0x5e2f2f71, 0x13848497, 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
45 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed, 0xd46a6abe, 0x8dcbcb46,
46 0x67bebed9, 0x7239394b, 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
47 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, 0x864343c5, 0x9a4d4dd7,
48 0x66333355, 0x11858594, 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
49 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3, 0xa25151f3, 0x5da3a3fe,
50 0x804040c0, 0x058f8f8a, 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
51 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, 0x20101030, 0xe5ffff1a,
52 0xfdf3f30e, 0xbfd2d26d, 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
53 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739, 0x93c4c457, 0x55a7a7f2,
54 0xfc7e7e82, 0x7a3d3d47, 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
55 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, 0x44222266, 0x542a2a7e,
56 0x3b9090ab, 0x0b888883, 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
57 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76, 0xdbe0e03b, 0x64323256,
58 0x743a3a4e, 0x140a0a1e, 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
59 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, 0x399191a8, 0x319595a4,
60 0xd3e4e437, 0xf279798b, 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
61 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0, 0xd86c6cb4, 0xac5656fa,
62 0xf3f4f407, 0xcfeaea25, 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
63 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, 0x381c1c24, 0x57a6a6f1,
64 0x73b4b4c7, 0x97c6c651, 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
65 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85, 0xe0707090, 0x7c3e3e42,
66 0x71b5b5c4, 0xcc6666aa, 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
67 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, 0x17868691, 0x99c1c158,
68 0x3a1d1d27, 0x279e9eb9, 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
69 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7, 0x2d9b9bb6, 0x3c1e1e22,
70 0x15878792, 0xc9e9e920, 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
71 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17, 0x65bfbfda, 0xd7e6e631,
72 0x844242c6, 0xd06868b8, 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
73 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a
74 };
75
76 //
77 // Pre-computed AES Reverse Table: AES_DTABLE[t] = AES_INV_SBOX[t].[0e, 09, 0d, 0b]
78 //
79 GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 AES_RTABLE[] = {
80 0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, 0x3bab6bcb, 0x1f9d45f1,
81 0xacfa58ab, 0x4be30393, 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
82 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f, 0xdeb15a49, 0x25ba1b67,
83 0x45ea0e98, 0x5dfec0e1, 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
84 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, 0xd4be832d, 0x587421d3,
85 0x49e06929, 0x8ec9c844, 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
86 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4, 0x63df4a18, 0xe51a3182,
87 0x97513360, 0x62537f45, 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
88 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, 0xab73d323, 0x724b02e2,
89 0xe31f8f57, 0x6655ab2a, 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
90 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c, 0x8acf1c2b, 0xa779b492,
91 0xf307f2f0, 0x4e69e2a1, 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
92 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75, 0x0b83ec39, 0x4060efaa,
93 0x5e719f06, 0xbd6e1051, 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
94 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff, 0x1998fb24, 0xd6bde997,
95 0x894043cc, 0x67d99e77, 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
96 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000, 0x09808683, 0x322bed48,
97 0x1e1170ac, 0x6c5a724e, 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
98 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a, 0x0c0a67b1, 0x9357e70f,
99 0xb4ee96d2, 0x1b9b919e, 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
100 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, 0x0e090d0b, 0xf28bc7ad,
101 0x2db6a8b9, 0x141ea9c8, 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
102 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34, 0x8b432976, 0xcb23c6dc,
103 0xb6edfc68, 0xb8e4f163, 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
104 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, 0x1d9e2f4b, 0xdcb230f3,
105 0x0d8652ec, 0x77c1e3d0, 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
106 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef, 0x87494ec7, 0xd938d1c1,
107 0x8ccaa2fe, 0x98d40b36, 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
108 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, 0xf68d13c2, 0x90d8b8e8,
109 0x2e39f75e, 0x82c3aff5, 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
110 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b, 0xcd267809, 0x6e5918f4,
111 0xec9ab701, 0x834f9aa8, 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
112 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, 0x31a4b2af, 0x2a3f2331,
113 0xc6a59430, 0x35a266c0, 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
114 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f, 0x764dd68d, 0x43efb04d,
115 0xccaa4d54, 0xe49604df, 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
116 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e, 0xb3671d5a, 0x92dbd252,
117 0xe9105633, 0x6dd64713, 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
118 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c, 0x9cd2df59, 0x55f2733f,
119 0x1814ce79, 0x73c737bf, 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
120 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, 0x161dc372, 0xbce2250c,
121 0x283c498b, 0xff0d9541, 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
122 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742
123 };
124
125 //
126 // AES Inverse S-Box (Defined in sec 5.3.2 of FIPS PUB 197).
127 //
128 GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 AES_INV_SBOX[256] = {
129 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
130 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
131 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
132 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
133 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
134 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
135 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
136 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
137 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
138 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
139 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
140 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
141 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
142 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
143 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
144 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
145 };
146
147 //
148 // Round constant word array used in AES key expansion.
149 //
150 GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 Rcon[] = {
151 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
152 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000
153 };
154
155 //
156 // Rotates x right n bits (circular right shift operation)
157 //
158 #define ROTATE_RIGHT32(x, n) (((x) >> (n)) | ((x) << (32-(n))))
159
160 //
161 // Loading & Storing 32-bit words in big-endian format: y[3..0] --> x; x --> y[3..0];
162 //
163 #define LOAD32H(x, y) { x = ((UINT32)((y)[0] & 0xFF) << 24) | ((UINT32)((y)[1] & 0xFF) << 16) | \
164 ((UINT32)((y)[2] & 0xFF) << 8) | ((UINT32)((y)[3] & 0xFF)); }
165 #define STORE32H(x, y) { (y)[0] = (UINT8)(((x) >> 24) & 0xFF); (y)[1] = (UINT8)(((x) >> 16) & 0xFF); \
166 (y)[2] = (UINT8)(((x) >> 8) & 0xFF); (y)[3] = (UINT8)((x) & 0xFF); }
167
168 //
169 // Wrap macros for AES forward and reverse tables lookups
170 //
171 #define AES_FT0(x) AES_FTABLE[x]
172 #define AES_FT1(x) ROTATE_RIGHT32(AES_FTABLE[x], 8)
173 #define AES_FT2(x) ROTATE_RIGHT32(AES_FTABLE[x], 16)
174 #define AES_FT3(x) ROTATE_RIGHT32(AES_FTABLE[x], 24)
175
176 #define AES_RT0(x) AES_RTABLE[x]
177 #define AES_RT1(x) ROTATE_RIGHT32(AES_RTABLE[x], 8)
178 #define AES_RT2(x) ROTATE_RIGHT32(AES_RTABLE[x], 16)
179 #define AES_RT3(x) ROTATE_RIGHT32(AES_RTABLE[x], 24)
180
181 ///
182 /// AES Key Schedule which is expanded from symmetric key [Size 60 = 4 * ((Max AES Round, 14) + 1)].
183 ///
184 typedef struct {
185 UINTN Nk; // Number of Cipher Key (in 32-bit words);
186 UINT32 eKey[60]; // Expanded AES encryption key
187 UINT32 dKey[60]; // Expanded AES decryption key (Not used here)
188 } AES_KEY;
189
190 /**
191 AES Key Expansion.
192 This function expands the cipher key into encryption schedule.
193
194 @param[in] Key AES symmetric key buffer.
195 @param[in] KeyLenInBits Key length in bits (128, 192, or 256).
196 @param[out] AesKey Expanded AES Key schedule for encryption.
197
198 @retval EFI_SUCCESS AES key expansion succeeded.
199 @retval EFI_INVALID_PARAMETER Unsupported key length.
200
201 **/
202 EFI_STATUS
203 EFIAPI
204 AesExpandKey (
205 IN UINT8 *Key,
206 IN UINTN KeyLenInBits,
207 OUT AES_KEY *AesKey
208 )
209 {
210 UINTN Nk, Nr, NW;
211 UINTN i, j, k;
212 UINT32 *Ek;
213 UINT32 Temp;
214
215 //
216 // Nk - Number of 32-bit words comprising the cipher key. (Nk = 4, 6 or 8)
217 // Nr - Number of rounds. (Nr = 10, 12, or 14), which is dependent on the key size.
218 //
219 Nk = KeyLenInBits >> 5;
220 if (Nk != 4 && Nk != 6 && Nk != 8) {
221 return EFI_INVALID_PARAMETER;
222 }
223 Nr = Nk + 6;
224 NW = AES_NB * (Nr + 1); // Key Expansion generates a total of Nb * (Nr + 1) words
225 AesKey->Nk = Nk;
226
227 //
228 // Load initial symmetric AES key;
229 // Note that AES was designed on big-endian systems.
230 //
231 Ek = AesKey->eKey;
232 for (i = j = 0; i < Nk; i++, j+=4) {
233 LOAD32H (Ek[i], Key + j);
234 }
235
236 //
237 // Initialize the encryption key scheduler
238 //
239 for (j = Nk, k = 0; j < NW; j+=Nk, k++) {
240 Temp = Ek[j - 1];
241 Ek[j] = Ek[j - Nk] ^ (AES_FT2((Temp >> 16) & 0xFF) & 0xFF000000) ^
242 (AES_FT3((Temp >> 8) & 0xFF) & 0x00FF0000) ^
243 (AES_FT0((Temp) & 0xFF) & 0x0000FF00) ^
244 (AES_FT1((Temp >> 24) & 0xFF) & 0x000000FF) ^
245 Rcon[k];
246 if (Nk <= 6) {
247 //
248 // If AES Cipher Key is 128 or 192 bits
249 //
250 for (i = 1; i < Nk && (i + j) < NW; i++) {
251 Ek [i + j] = Ek [i + j - Nk] ^ Ek[i + j - 1];
252 }
253 } else {
254 //
255 // Different routine for key expansion If Cipher Key is 256 bits,
256 //
257 for (i = 1; i < 4 && (i + j) < NW; i++) {
258 Ek [i + j] = Ek[i + j - Nk] ^ Ek[i + j - 1];
259 }
260 if (j + 4 < NW) {
261 Temp = Ek[j + 3];
262 Ek[j + 4] = Ek[j + 4 - Nk] ^ (AES_FT2((Temp >> 24) & 0xFF) & 0xFF000000) ^
263 (AES_FT3((Temp >> 16) & 0xFF) & 0x00FF0000) ^
264 (AES_FT0((Temp >> 8) & 0xFF) & 0x0000FF00) ^
265 (AES_FT1((Temp) & 0xFF) & 0x000000FF);
266 }
267
268 for (i = 5; i < Nk && (i + j) < NW; i++) {
269 Ek[i + j] = Ek[i + j - Nk] ^ Ek[i + j - 1];
270 }
271 }
272 }
273
274 return EFI_SUCCESS;
275 }
276
277 /**
278 Encrypts one single block data (128 bits) with AES algorithm.
279
280 @param[in] Key AES symmetric key buffer.
281 @param[in] InData One block of input plaintext to be encrypted.
282 @param[out] OutData Encrypted output ciphertext.
283
284 @retval EFI_SUCCESS AES Block Encryption succeeded.
285 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
286
287 **/
288 EFI_STATUS
289 EFIAPI
290 AesEncrypt (
291 IN UINT8 *Key,
292 IN UINT8 *InData,
293 OUT UINT8 *OutData
294 )
295 {
296 AES_KEY AesKey;
297 UINTN Nr;
298 UINT32 *Ek, s[4], t[4], *x, *y, *Temp;
299 UINTN Index, k, Round;
300
301 if ((Key == NULL) || (InData == NULL) || (OutData == NULL)) {
302 return EFI_INVALID_PARAMETER;
303 }
304
305 //
306 // Expands AES Key for encryption.
307 //
308 AesExpandKey (Key, 128, &AesKey);
309
310 Nr = AesKey.Nk + 6;
311 Ek = AesKey.eKey;
312
313 //
314 // Initialize the cipher State array with the initial round key
315 //
316 for (Index = 0; Index < AES_NB; Index++) {
317 LOAD32H (s[Index], InData + 4 * Index);
318 s[Index] ^= Ek[Index];
319 }
320
321 k = AES_NB;
322 x = s;
323 y = t;
324 //
325 // AES Cipher transformation rounds (Nr - 1 rounds), in which SubBytes(),
326 // ShiftRows() and MixColumns() operations were combined by a sequence of
327 // table lookups to speed up the execution.
328 //
329 for (Round = 1; Round < Nr; Round++) {
330 y[0] = AES_FT0 ((x[0] >> 24) ) ^ AES_FT1 ((x[1] >> 16) & 0xFF) ^
331 AES_FT2 ((x[2] >> 8) & 0xFF) ^ AES_FT3 ((x[3] ) & 0xFF) ^ Ek[k];
332 y[1] = AES_FT0 ((x[1] >> 24) ) ^ AES_FT1 ((x[2] >> 16) & 0xFF) ^
333 AES_FT2 ((x[3] >> 8) & 0xFF) ^ AES_FT3 ((x[0] ) & 0xFF) ^ Ek[k + 1];
334 y[2] = AES_FT0 ((x[2] >> 24) ) ^ AES_FT1 ((x[3] >> 16) & 0xFF) ^
335 AES_FT2 ((x[0] >> 8) & 0xFF) ^ AES_FT3 ((x[1] ) & 0xFF) ^ Ek[k + 2];
336 y[3] = AES_FT0 ((x[3] >> 24) ) ^ AES_FT1 ((x[0] >> 16) & 0xFF) ^
337 AES_FT2 ((x[1] >> 8) & 0xFF) ^ AES_FT3 ((x[2] ) & 0xFF) ^ Ek[k + 3];
338
339 k += 4;
340 Temp = x; x = y; y = Temp;
341 }
342
343 //
344 // Apply the final round, which does not include MixColumns() transformation
345 //
346 y[0] = (AES_FT2 ((x[0] >> 24) ) & 0xFF000000) ^ (AES_FT3 ((x[1] >> 16) & 0xFF) & 0x00FF0000) ^
347 (AES_FT0 ((x[2] >> 8) & 0xFF) & 0x0000FF00) ^ (AES_FT1 ((x[3] ) & 0xFF) & 0x000000FF) ^
348 Ek[k];
349 y[1] = (AES_FT2 ((x[1] >> 24) ) & 0xFF000000) ^ (AES_FT3 ((x[2] >> 16) & 0xFF) & 0x00FF0000) ^
350 (AES_FT0 ((x[3] >> 8) & 0xFF) & 0x0000FF00) ^ (AES_FT1 ((x[0] ) & 0xFF) & 0x000000FF) ^
351 Ek[k + 1];
352 y[2] = (AES_FT2 ((x[2] >> 24) ) & 0xFF000000) ^ (AES_FT3 ((x[3] >> 16) & 0xFF) & 0x00FF0000) ^
353 (AES_FT0 ((x[0] >> 8) & 0xFF) & 0x0000FF00) ^ (AES_FT1 ((x[1] ) & 0xFF) & 0x000000FF) ^
354 Ek[k + 2];
355 y[3] = (AES_FT2 ((x[3] >> 24) ) & 0xFF000000) ^ (AES_FT3 ((x[0] >> 16) & 0xFF) & 0x00FF0000) ^
356 (AES_FT0 ((x[1] >> 8) & 0xFF) & 0x0000FF00) ^ (AES_FT1 ((x[2] ) & 0xFF) & 0x000000FF) ^
357 Ek[k + 3];
358
359 //
360 // Output the transformed result;
361 //
362 for (Index = 0; Index < AES_NB; Index++) {
363 STORE32H (y[Index], OutData + 4 * Index);
364 }
365
366 return EFI_SUCCESS;
367 }