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