]> git.proxmox.com Git - mirror_edk2.git/blame - CryptoPkg/Library/BaseCryptLib/Cipher/CryptAes.c
CryptoPkg/BaseCryptLib: Retire Aes Ecb mode algorithm
[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
a8c44645 81/**\r
82 Performs AES encryption on a data buffer of the specified size in CBC mode.\r
83\r
84 This function performs AES encryption on data buffer pointed by Input, of specified\r
85 size of InputSize, in CBC 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 Initialization vector should be one block size (16 bytes).\r
89 AesContext should be already correctly initialized by AesInit(). Behavior with\r
90 invalid AES context is undefined.\r
91\r
16d2c32c 92 If AesContext is NULL, then return FALSE.\r
93 If Input is NULL, then return FALSE.\r
94 If InputSize is not multiple of block size (16 bytes), then return FALSE.\r
95 If Ivec is NULL, then return FALSE.\r
96 If Output is NULL, then return FALSE.\r
a8c44645 97\r
98 @param[in] AesContext Pointer to the AES context.\r
99 @param[in] Input Pointer to the buffer containing the data to be encrypted.\r
100 @param[in] InputSize Size of the Input buffer in bytes.\r
101 @param[in] Ivec Pointer to initialization vector.\r
102 @param[out] Output Pointer to a buffer that receives the AES encryption output.\r
103\r
104 @retval TRUE AES encryption succeeded.\r
105 @retval FALSE AES encryption failed.\r
106\r
107**/\r
108BOOLEAN\r
109EFIAPI\r
110AesCbcEncrypt (\r
111 IN VOID *AesContext,\r
112 IN CONST UINT8 *Input,\r
113 IN UINTN InputSize,\r
114 IN CONST UINT8 *Ivec,\r
115 OUT UINT8 *Output\r
116 )\r
117{\r
118 AES_KEY *AesKey;\r
119 UINT8 IvecBuffer[AES_BLOCK_SIZE];\r
120\r
16d2c32c 121 //\r
122 // Check input parameters.\r
123 //\r
dda39f3a 124 if (AesContext == NULL || Input == NULL || (InputSize % AES_BLOCK_SIZE) != 0) {\r
125 return FALSE;\r
126 }\r
127\r
128 if (Ivec == NULL || Output == NULL || InputSize > INT_MAX) {\r
16d2c32c 129 return FALSE;\r
130 }\r
a8c44645 131\r
132 AesKey = (AES_KEY *) AesContext;\r
133 CopyMem (IvecBuffer, Ivec, AES_BLOCK_SIZE);\r
134\r
135 //\r
136 // Perform AES data encryption with CBC mode\r
137 //\r
138 AES_cbc_encrypt (Input, Output, (UINT32) InputSize, AesKey, IvecBuffer, AES_ENCRYPT);\r
139\r
140 return TRUE;\r
141}\r
142\r
143/**\r
144 Performs AES decryption on a data buffer of the specified size in CBC mode.\r
145\r
146 This function performs AES decryption on data buffer pointed by Input, of specified\r
147 size of InputSize, in CBC mode.\r
148 InputSize must be multiple of block size (16 bytes). This function does not perform\r
149 padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
150 Initialization vector should be one block size (16 bytes).\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 Ivec is NULL, then return FALSE.\r
158 If Output is NULL, then return FALSE.\r
a8c44645 159\r
160 @param[in] AesContext Pointer to the AES context.\r
161 @param[in] Input Pointer to the buffer containing the data to be encrypted.\r
162 @param[in] InputSize Size of the Input buffer in bytes.\r
163 @param[in] Ivec Pointer to initialization vector.\r
164 @param[out] Output Pointer to a buffer that receives the AES encryption output.\r
165\r
166 @retval TRUE AES decryption succeeded.\r
167 @retval FALSE AES decryption failed.\r
168\r
169**/\r
170BOOLEAN\r
171EFIAPI\r
172AesCbcDecrypt (\r
173 IN VOID *AesContext,\r
174 IN CONST UINT8 *Input,\r
175 IN UINTN InputSize,\r
176 IN CONST UINT8 *Ivec,\r
177 OUT UINT8 *Output\r
178 )\r
179{\r
180 AES_KEY *AesKey;\r
181 UINT8 IvecBuffer[AES_BLOCK_SIZE];\r
16d2c32c 182\r
183 //\r
184 // Check input parameters.\r
185 //\r
dda39f3a 186 if (AesContext == NULL || Input == NULL || (InputSize % AES_BLOCK_SIZE) != 0) {\r
187 return FALSE;\r
188 }\r
189\r
190 if (Ivec == NULL || Output == NULL || InputSize > INT_MAX) {\r
16d2c32c 191 return FALSE;\r
192 }\r
a8c44645 193\r
194 AesKey = (AES_KEY *) AesContext;\r
195 CopyMem (IvecBuffer, Ivec, AES_BLOCK_SIZE);\r
196\r
197 //\r
198 // Perform AES data decryption with CBC mode\r
199 //\r
200 AES_cbc_encrypt (Input, Output, (UINT32) InputSize, AesKey + 1, IvecBuffer, AES_DECRYPT);\r
201\r
202 return TRUE;\r
203}\r