Fix some typo and coding style issues in BaseCryptLib instances.
[mirror_edk2.git] / CryptoPkg / Library / BaseCryptLib / Cipher / CryptAes.c
1 /** @file\r
2   AES Wrapper Implementation over OpenSSL.\r
3 \r
4 Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>\r
5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution.  The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9 \r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT 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
24 UINTN\r
25 EFIAPI\r
26 AesGetContextSize (\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
41   In addition, it sets up all AES key materials for subsequent encryption and decryption\r
42   operations.\r
43   There are 3 options for key length, 128 bits, 192 bits, and 256 bits.\r
44 \r
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
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
57 BOOLEAN\r
58 EFIAPI\r
59 AesInit (\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
67   //\r
68   // Check input parameters.\r
69   //\r
70   if (AesContext == NULL || Key == NULL || (KeyLength != 128 && KeyLength != 192 && KeyLength != 256)) {\r
71     return FALSE;\r
72   }\r
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
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
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
111 BOOLEAN\r
112 EFIAPI\r
113 AesEcbEncrypt (\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
121 \r
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
128   \r
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
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
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
168 BOOLEAN\r
169 EFIAPI\r
170 AesEcbDecrypt (\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
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
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
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
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
228 BOOLEAN\r
229 EFIAPI\r
230 AesCbcEncrypt (\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
241   //\r
242   // Check input parameters.\r
243   //\r
244   if (AesContext == NULL || Input == NULL || (InputSize % AES_BLOCK_SIZE) != 0 || Ivec == NULL || Output == NULL) {\r
245     return FALSE;\r
246   }\r
247 \r
248   AesKey = (AES_KEY *) AesContext;\r
249   CopyMem (IvecBuffer, Ivec, AES_BLOCK_SIZE);\r
250 \r
251   //\r
252   // Perform AES data encryption with CBC mode\r
253   //\r
254   AES_cbc_encrypt (Input, Output, (UINT32) InputSize, AesKey, IvecBuffer, AES_ENCRYPT);\r
255 \r
256   return TRUE;\r
257 }\r
258 \r
259 /**\r
260   Performs AES decryption on a data buffer of the specified size in CBC mode.\r
261 \r
262   This function performs AES decryption on data buffer pointed by Input, of specified\r
263   size of InputSize, in CBC mode.\r
264   InputSize must be multiple of block size (16 bytes). This function does not perform\r
265   padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
266   Initialization vector should be one block size (16 bytes).\r
267   AesContext should be already correctly initialized by AesInit(). Behavior with\r
268   invalid AES context is undefined.\r
269 \r
270   If AesContext is NULL, then return FALSE.\r
271   If Input is NULL, then return FALSE.\r
272   If InputSize is not multiple of block size (16 bytes), then return FALSE.\r
273   If Ivec is NULL, then return FALSE.\r
274   If Output is NULL, then return FALSE.\r
275 \r
276   @param[in]   AesContext  Pointer to the AES context.\r
277   @param[in]   Input       Pointer to the buffer containing the data to be encrypted.\r
278   @param[in]   InputSize   Size of the Input buffer in bytes.\r
279   @param[in]   Ivec        Pointer to initialization vector.\r
280   @param[out]  Output      Pointer to a buffer that receives the AES encryption output.\r
281 \r
282   @retval TRUE   AES decryption succeeded.\r
283   @retval FALSE  AES decryption failed.\r
284 \r
285 **/\r
286 BOOLEAN\r
287 EFIAPI\r
288 AesCbcDecrypt (\r
289   IN   VOID         *AesContext,\r
290   IN   CONST UINT8  *Input,\r
291   IN   UINTN        InputSize,\r
292   IN   CONST UINT8  *Ivec,\r
293   OUT  UINT8        *Output\r
294   )\r
295 {\r
296   AES_KEY  *AesKey;\r
297   UINT8    IvecBuffer[AES_BLOCK_SIZE];\r
298 \r
299   //\r
300   // Check input parameters.\r
301   //\r
302   if (AesContext == NULL || Input == NULL || (InputSize % AES_BLOCK_SIZE) != 0 || Ivec == NULL || Output == NULL) {\r
303     return FALSE;\r
304   }\r
305 \r
306   AesKey = (AES_KEY *) AesContext;\r
307   CopyMem (IvecBuffer, Ivec, AES_BLOCK_SIZE);\r
308 \r
309   //\r
310   // Perform AES data decryption with CBC mode\r
311   //\r
312   AES_cbc_encrypt (Input, Output, (UINT32) InputSize, AesKey + 1, IvecBuffer, AES_DECRYPT);\r
313 \r
314   return TRUE;\r
315 }\r