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