]> git.proxmox.com Git - mirror_edk2.git/blame - CryptoPkg/Library/BaseCryptLib/Cipher/CryptAes.c
CorebootPayloadPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / CryptoPkg / Library / BaseCryptLib / Cipher / CryptAes.c
CommitLineData
a8c44645 1/** @file\r
2 AES Wrapper Implementation over OpenSSL.\r
3\r
630f67dd 4Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>\r
a8c44645 5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "InternalCryptLib.h"\r
16#include <openssl/aes.h>\r
17\r
18/**\r
19 Retrieves the size, in bytes, of the context buffer required for AES operations.\r
20\r
21 @return The size, in bytes, of the context buffer required for AES operations.\r
22\r
23**/\r
24UINTN\r
25EFIAPI\r
26AesGetContextSize (\r
27 VOID\r
28 )\r
29{\r
30 //\r
31 // AES uses different key contexts for encryption and decryption, so here memory\r
32 // for 2 copies of AES_KEY is allocated.\r
33 //\r
34 return (UINTN) (2 * sizeof (AES_KEY));\r
35}\r
36\r
37/**\r
38 Initializes user-supplied memory as AES context for subsequent use.\r
39\r
40 This function initializes user-supplied memory pointed by AesContext as AES context.\r
6b8ebcb8 41 In addition, it sets up all AES key materials for subsequent encryption and decryption\r
a8c44645 42 operations.\r
43 There are 3 options for key length, 128 bits, 192 bits, and 256 bits.\r
44\r
16d2c32c 45 If AesContext is NULL, then return FALSE.\r
46 If Key is NULL, then return FALSE.\r
47 If KeyLength is not valid, then return FALSE.\r
a8c44645 48\r
49 @param[out] AesContext Pointer to AES context being initialized.\r
50 @param[in] Key Pointer to the user-supplied AES key.\r
51 @param[in] KeyLength Length of AES key in bits.\r
52\r
53 @retval TRUE AES context initialization succeeded.\r
54 @retval FALSE AES context initialization failed.\r
55\r
56**/\r
57BOOLEAN\r
58EFIAPI\r
59AesInit (\r
60 OUT VOID *AesContext,\r
61 IN CONST UINT8 *Key,\r
62 IN UINTN KeyLength\r
63 )\r
64{\r
65 AES_KEY *AesKey;\r
66\r
a8c44645 67 //\r
16d2c32c 68 // Check input parameters.\r
a8c44645 69 //\r
16d2c32c 70 if (AesContext == NULL || Key == NULL || (KeyLength != 128 && KeyLength != 192 && KeyLength != 256)) {\r
71 return FALSE;\r
72 }\r
a8c44645 73\r
74 //\r
75 // Initialize AES encryption & decryption key schedule.\r
76 //\r
77 AesKey = (AES_KEY *) AesContext;\r
78 if (AES_set_encrypt_key (Key, (UINT32) KeyLength, AesKey) != 0) {\r
79 return FALSE;\r
80 }\r
81 if (AES_set_decrypt_key (Key, (UINT32) KeyLength, AesKey + 1) != 0) {\r
82 return FALSE;\r
83 }\r
84 return TRUE;\r
85}\r
86\r
87/**\r
88 Performs AES encryption on a data buffer of the specified size in ECB mode.\r
89\r
90 This function performs AES encryption on data buffer pointed by Input, of specified\r
91 size of InputSize, in ECB mode.\r
92 InputSize must be multiple of block size (16 bytes). This function does not perform\r
93 padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
94 AesContext should be already correctly initialized by AesInit(). Behavior with\r
95 invalid AES context is undefined.\r
96\r
16d2c32c 97 If AesContext is NULL, then return FALSE.\r
98 If Input is NULL, then return FALSE.\r
99 If InputSize is not multiple of block size (16 bytes), then return FALSE.\r
100 If Output is NULL, then return FALSE.\r
a8c44645 101\r
102 @param[in] AesContext Pointer to the AES context.\r
103 @param[in] Input Pointer to the buffer containing the data to be encrypted.\r
104 @param[in] InputSize Size of the Input buffer in bytes.\r
105 @param[out] Output Pointer to a buffer that receives the AES encryption output.\r
106\r
107 @retval TRUE AES encryption succeeded.\r
108 @retval FALSE AES encryption failed.\r
109\r
110**/\r
111BOOLEAN\r
112EFIAPI\r
113AesEcbEncrypt (\r
114 IN VOID *AesContext,\r
115 IN CONST UINT8 *Input,\r
116 IN UINTN InputSize,\r
117 OUT UINT8 *Output\r
118 )\r
119{\r
120 AES_KEY *AesKey;\r
a8c44645 121\r
16d2c32c 122 //\r
123 // Check input parameters.\r
124 //\r
125 if (AesContext == NULL || Input == NULL || (InputSize % AES_BLOCK_SIZE) != 0 || Output == NULL) {\r
126 return FALSE;\r
127 }\r
630f67dd 128\r
a8c44645 129 AesKey = (AES_KEY *) AesContext;\r
130\r
131 //\r
132 // Perform AES data encryption with ECB mode (block-by-block)\r
133 //\r
134 while (InputSize > 0) {\r
135 AES_ecb_encrypt (Input, Output, AesKey, AES_ENCRYPT);\r
136 Input += AES_BLOCK_SIZE;\r
137 Output += AES_BLOCK_SIZE;\r
138 InputSize -= AES_BLOCK_SIZE;\r
139 }\r
140\r
141 return TRUE;\r
142}\r
143\r
144/**\r
145 Performs AES decryption on a data buffer of the specified size in ECB mode.\r
146\r
147 This function performs AES decryption on data buffer pointed by Input, of specified\r
148 size of InputSize, in ECB mode.\r
149 InputSize must be multiple of block size (16 bytes). This function does not perform\r
150 padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
151 AesContext should be already correctly initialized by AesInit(). Behavior with\r
152 invalid AES context is undefined.\r
153\r
16d2c32c 154 If AesContext is NULL, then return FALSE.\r
155 If Input is NULL, then return FALSE.\r
156 If InputSize is not multiple of block size (16 bytes), then return FALSE.\r
157 If Output is NULL, then return FALSE.\r
a8c44645 158\r
159 @param[in] AesContext Pointer to the AES context.\r
160 @param[in] Input Pointer to the buffer containing the data to be decrypted.\r
161 @param[in] InputSize Size of the Input buffer in bytes.\r
162 @param[out] Output Pointer to a buffer that receives the AES decryption output.\r
163\r
164 @retval TRUE AES decryption succeeded.\r
165 @retval FALSE AES decryption failed.\r
166\r
167**/\r
168BOOLEAN\r
169EFIAPI\r
170AesEcbDecrypt (\r
171 IN VOID *AesContext,\r
172 IN CONST UINT8 *Input,\r
173 IN UINTN InputSize,\r
174 OUT UINT8 *Output\r
175 )\r
176{\r
177 AES_KEY *AesKey;\r
16d2c32c 178\r
179 //\r
180 // Check input parameters.\r
181 //\r
182 if (AesContext == NULL || Input == NULL || (InputSize % AES_BLOCK_SIZE) != 0 || Output == NULL) {\r
183 return FALSE;\r
184 }\r
a8c44645 185\r
186 AesKey = (AES_KEY *) AesContext;\r
187\r
188 //\r
189 // Perform AES data decryption with ECB mode (block-by-block)\r
190 //\r
191 while (InputSize > 0) {\r
192 AES_ecb_encrypt (Input, Output, AesKey + 1, AES_DECRYPT);\r
193 Input += AES_BLOCK_SIZE;\r
194 Output += AES_BLOCK_SIZE;\r
195 InputSize -= AES_BLOCK_SIZE;\r
196 }\r
197\r
198 return TRUE;\r
199}\r
200\r
201/**\r
202 Performs AES encryption on a data buffer of the specified size in CBC mode.\r
203\r
204 This function performs AES encryption on data buffer pointed by Input, of specified\r
205 size of InputSize, in CBC mode.\r
206 InputSize must be multiple of block size (16 bytes). This function does not perform\r
207 padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
208 Initialization vector should be one block size (16 bytes).\r
209 AesContext should be already correctly initialized by AesInit(). Behavior with\r
210 invalid AES context is undefined.\r
211\r
16d2c32c 212 If AesContext is NULL, then return FALSE.\r
213 If Input is NULL, then return FALSE.\r
214 If InputSize is not multiple of block size (16 bytes), then return FALSE.\r
215 If Ivec is NULL, then return FALSE.\r
216 If Output is NULL, then return FALSE.\r
a8c44645 217\r
218 @param[in] AesContext Pointer to the AES context.\r
219 @param[in] Input Pointer to the buffer containing the data to be encrypted.\r
220 @param[in] InputSize Size of the Input buffer in bytes.\r
221 @param[in] Ivec Pointer to initialization vector.\r
222 @param[out] Output Pointer to a buffer that receives the AES encryption output.\r
223\r
224 @retval TRUE AES encryption succeeded.\r
225 @retval FALSE AES encryption failed.\r
226\r
227**/\r
228BOOLEAN\r
229EFIAPI\r
230AesCbcEncrypt (\r
231 IN VOID *AesContext,\r
232 IN CONST UINT8 *Input,\r
233 IN UINTN InputSize,\r
234 IN CONST UINT8 *Ivec,\r
235 OUT UINT8 *Output\r
236 )\r
237{\r
238 AES_KEY *AesKey;\r
239 UINT8 IvecBuffer[AES_BLOCK_SIZE];\r
240\r
16d2c32c 241 //\r
242 // Check input parameters.\r
243 //\r
dda39f3a 244 if (AesContext == NULL || Input == NULL || (InputSize % AES_BLOCK_SIZE) != 0) {\r
245 return FALSE;\r
246 }\r
247\r
248 if (Ivec == NULL || Output == NULL || InputSize > INT_MAX) {\r
16d2c32c 249 return FALSE;\r
250 }\r
a8c44645 251\r
252 AesKey = (AES_KEY *) AesContext;\r
253 CopyMem (IvecBuffer, Ivec, AES_BLOCK_SIZE);\r
254\r
255 //\r
256 // Perform AES data encryption with CBC mode\r
257 //\r
258 AES_cbc_encrypt (Input, Output, (UINT32) InputSize, AesKey, IvecBuffer, AES_ENCRYPT);\r
259\r
260 return TRUE;\r
261}\r
262\r
263/**\r
264 Performs AES decryption on a data buffer of the specified size in CBC mode.\r
265\r
266 This function performs AES decryption on data buffer pointed by Input, of specified\r
267 size of InputSize, in CBC mode.\r
268 InputSize must be multiple of block size (16 bytes). This function does not perform\r
269 padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
270 Initialization vector should be one block size (16 bytes).\r
271 AesContext should be already correctly initialized by AesInit(). Behavior with\r
272 invalid AES context is undefined.\r
273\r
16d2c32c 274 If AesContext is NULL, then return FALSE.\r
275 If Input is NULL, then return FALSE.\r
276 If InputSize is not multiple of block size (16 bytes), then return FALSE.\r
277 If Ivec is NULL, then return FALSE.\r
278 If Output is NULL, then return FALSE.\r
a8c44645 279\r
280 @param[in] AesContext Pointer to the AES context.\r
281 @param[in] Input Pointer to the buffer containing the data to be encrypted.\r
282 @param[in] InputSize Size of the Input buffer in bytes.\r
283 @param[in] Ivec Pointer to initialization vector.\r
284 @param[out] Output Pointer to a buffer that receives the AES encryption output.\r
285\r
286 @retval TRUE AES decryption succeeded.\r
287 @retval FALSE AES decryption failed.\r
288\r
289**/\r
290BOOLEAN\r
291EFIAPI\r
292AesCbcDecrypt (\r
293 IN VOID *AesContext,\r
294 IN CONST UINT8 *Input,\r
295 IN UINTN InputSize,\r
296 IN CONST UINT8 *Ivec,\r
297 OUT UINT8 *Output\r
298 )\r
299{\r
300 AES_KEY *AesKey;\r
301 UINT8 IvecBuffer[AES_BLOCK_SIZE];\r
16d2c32c 302\r
303 //\r
304 // Check input parameters.\r
305 //\r
dda39f3a 306 if (AesContext == NULL || Input == NULL || (InputSize % AES_BLOCK_SIZE) != 0) {\r
307 return FALSE;\r
308 }\r
309\r
310 if (Ivec == NULL || Output == NULL || InputSize > INT_MAX) {\r
16d2c32c 311 return FALSE;\r
312 }\r
a8c44645 313\r
314 AesKey = (AES_KEY *) AesContext;\r
315 CopyMem (IvecBuffer, Ivec, AES_BLOCK_SIZE);\r
316\r
317 //\r
318 // Perform AES data decryption with CBC mode\r
319 //\r
320 AES_cbc_encrypt (Input, Output, (UINT32) InputSize, AesKey + 1, IvecBuffer, AES_DECRYPT);\r
321\r
322 return TRUE;\r
323}\r