]> git.proxmox.com Git - mirror_edk2.git/blob - CryptoPkg/Library/BaseCryptLib/Cipher/CryptAes.c
Update CryptoPkg for new ciphers (HMAC, Block Cipher, etc) supports.
[mirror_edk2.git] / CryptoPkg / Library / BaseCryptLib / Cipher / CryptAes.c
1 /** @file
2 AES Wrapper Implementation over OpenSSL.
3
4 Copyright (c) 2010, 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 ASSERT().
46 If Key is NULL, then ASSERT().
47 If KeyLength is not valid, then ASSERT().
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 ASSERT (AesContext != NULL);
68 //
69 // AES Key Checking
70 //
71 ASSERT (Key != NULL);
72 ASSERT ((KeyLength == 128) || (KeyLength == 192) || (KeyLength == 256));
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 ASSERT().
98 If Input is NULL, then ASSERT().
99 If InputSize is not multiple of block size (16 bytes), then ASSERT().
100 If Output is NULL, then ASSERT().
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 ASSERT (AesContext != NULL);
123 ASSERT (Input != NULL);
124 ASSERT ((InputSize % AES_BLOCK_SIZE) == 0);
125 ASSERT (Output != NULL);
126
127 AesKey = (AES_KEY *) AesContext;
128
129 //
130 // Perform AES data encryption with ECB mode (block-by-block)
131 //
132 while (InputSize > 0) {
133 AES_ecb_encrypt (Input, Output, AesKey, AES_ENCRYPT);
134 Input += AES_BLOCK_SIZE;
135 Output += AES_BLOCK_SIZE;
136 InputSize -= AES_BLOCK_SIZE;
137 }
138
139 return TRUE;
140 }
141
142 /**
143 Performs AES decryption on a data buffer of the specified size in ECB mode.
144
145 This function performs AES decryption on data buffer pointed by Input, of specified
146 size of InputSize, in ECB mode.
147 InputSize must be multiple of block size (16 bytes). This function does not perform
148 padding. Caller must perform padding, if necessary, to ensure valid input data size.
149 AesContext should be already correctly initialized by AesInit(). Behavior with
150 invalid AES context is undefined.
151
152 If AesContext is NULL, then ASSERT().
153 If Input is NULL, then ASSERT().
154 If InputSize is not multiple of block size (16 bytes), then ASSERT().
155 If Output is NULL, then ASSERT().
156
157 @param[in] AesContext Pointer to the AES context.
158 @param[in] Input Pointer to the buffer containing the data to be decrypted.
159 @param[in] InputSize Size of the Input buffer in bytes.
160 @param[out] Output Pointer to a buffer that receives the AES decryption output.
161
162 @retval TRUE AES decryption succeeded.
163 @retval FALSE AES decryption failed.
164
165 **/
166 BOOLEAN
167 EFIAPI
168 AesEcbDecrypt (
169 IN VOID *AesContext,
170 IN CONST UINT8 *Input,
171 IN UINTN InputSize,
172 OUT UINT8 *Output
173 )
174 {
175 AES_KEY *AesKey;
176
177 ASSERT (AesContext != NULL);
178 ASSERT (Input != NULL);
179 ASSERT ((InputSize % AES_BLOCK_SIZE) == 0);
180 ASSERT (Output != NULL);
181
182 AesKey = (AES_KEY *) AesContext;
183
184 //
185 // Perform AES data decryption with ECB mode (block-by-block)
186 //
187 while (InputSize > 0) {
188 AES_ecb_encrypt (Input, Output, AesKey + 1, AES_DECRYPT);
189 Input += AES_BLOCK_SIZE;
190 Output += AES_BLOCK_SIZE;
191 InputSize -= AES_BLOCK_SIZE;
192 }
193
194 return TRUE;
195 }
196
197 /**
198 Performs AES encryption on a data buffer of the specified size in CBC mode.
199
200 This function performs AES encryption on data buffer pointed by Input, of specified
201 size of InputSize, in CBC mode.
202 InputSize must be multiple of block size (16 bytes). This function does not perform
203 padding. Caller must perform padding, if necessary, to ensure valid input data size.
204 Initialization vector should be one block size (16 bytes).
205 AesContext should be already correctly initialized by AesInit(). Behavior with
206 invalid AES context is undefined.
207
208 If AesContext is NULL, then ASSERT().
209 If Input is NULL, then ASSERT().
210 If InputSize is not multiple of block size (16 bytes), then ASSERT().
211 If Ivec is NULL, then ASSERT().
212 If Output is NULL, then ASSERT().
213
214 @param[in] AesContext Pointer to the AES context.
215 @param[in] Input Pointer to the buffer containing the data to be encrypted.
216 @param[in] InputSize Size of the Input buffer in bytes.
217 @param[in] Ivec Pointer to initialization vector.
218 @param[out] Output Pointer to a buffer that receives the AES encryption output.
219
220 @retval TRUE AES encryption succeeded.
221 @retval FALSE AES encryption failed.
222
223 **/
224 BOOLEAN
225 EFIAPI
226 AesCbcEncrypt (
227 IN VOID *AesContext,
228 IN CONST UINT8 *Input,
229 IN UINTN InputSize,
230 IN CONST UINT8 *Ivec,
231 OUT UINT8 *Output
232 )
233 {
234 AES_KEY *AesKey;
235 UINT8 IvecBuffer[AES_BLOCK_SIZE];
236
237 ASSERT (AesContext != NULL);
238 ASSERT (Input != NULL);
239 ASSERT ((InputSize % AES_BLOCK_SIZE) == 0);
240 ASSERT (Ivec != NULL);
241 ASSERT (Output != NULL);
242
243 AesKey = (AES_KEY *) AesContext;
244 CopyMem (IvecBuffer, Ivec, AES_BLOCK_SIZE);
245
246 //
247 // Perform AES data encryption with CBC mode
248 //
249 AES_cbc_encrypt (Input, Output, (UINT32) InputSize, AesKey, IvecBuffer, AES_ENCRYPT);
250
251 return TRUE;
252 }
253
254 /**
255 Performs AES decryption on a data buffer of the specified size in CBC mode.
256
257 This function performs AES decryption on data buffer pointed by Input, of specified
258 size of InputSize, in CBC mode.
259 InputSize must be multiple of block size (16 bytes). This function does not perform
260 padding. Caller must perform padding, if necessary, to ensure valid input data size.
261 Initialization vector should be one block size (16 bytes).
262 AesContext should be already correctly initialized by AesInit(). Behavior with
263 invalid AES context is undefined.
264
265 If AesContext is NULL, then ASSERT().
266 If Input is NULL, then ASSERT().
267 If InputSize is not multiple of block size (16 bytes), then ASSERT().
268 If Ivec is NULL, then ASSERT().
269 If Output is NULL, then ASSERT().
270
271 @param[in] AesContext Pointer to the AES context.
272 @param[in] Input Pointer to the buffer containing the data to be encrypted.
273 @param[in] InputSize Size of the Input buffer in bytes.
274 @param[in] Ivec Pointer to initialization vector.
275 @param[out] Output Pointer to a buffer that receives the AES encryption output.
276
277 @retval TRUE AES decryption succeeded.
278 @retval FALSE AES decryption failed.
279
280 **/
281 BOOLEAN
282 EFIAPI
283 AesCbcDecrypt (
284 IN VOID *AesContext,
285 IN CONST UINT8 *Input,
286 IN UINTN InputSize,
287 IN CONST UINT8 *Ivec,
288 OUT UINT8 *Output
289 )
290 {
291 AES_KEY *AesKey;
292 UINT8 IvecBuffer[AES_BLOCK_SIZE];
293
294 ASSERT (AesContext != NULL);
295 ASSERT (Input != NULL);
296 ASSERT ((InputSize % AES_BLOCK_SIZE) == 0);
297 ASSERT (Ivec != NULL);
298 ASSERT (Output != NULL);
299
300 AesKey = (AES_KEY *) AesContext;
301 CopyMem (IvecBuffer, Ivec, AES_BLOCK_SIZE);
302
303 //
304 // Perform AES data decryption with CBC mode
305 //
306 AES_cbc_encrypt (Input, Output, (UINT32) InputSize, AesKey + 1, IvecBuffer, AES_DECRYPT);
307
308 return TRUE;
309 }