]> git.proxmox.com Git - mirror_edk2.git/blame - CryptoPkg/Library/BaseCryptLib/Cipher/CryptTdes.c
Update CryptoPkg for new ciphers (HMAC, Block Cipher, etc) supports.
[mirror_edk2.git] / CryptoPkg / Library / BaseCryptLib / Cipher / CryptTdes.c
CommitLineData
a8c44645 1/** @file\r
2 TDES Wrapper Implementation over OpenSSL.\r
3\r
4Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT 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/des.h>\r
17\r
18/**\r
19 Retrieves the size, in bytes, of the context buffer required for TDES operations.\r
20\r
21 @return The size, in bytes, of the context buffer required for TDES operations.\r
22\r
23**/\r
24UINTN\r
25EFIAPI\r
26TdesGetContextSize (\r
27 VOID\r
28 )\r
29{\r
30 //\r
31 // Memory for 3 copies of DES_key_schedule is allocated, for K1, K2 and K3 each.\r
32 //\r
33 return (UINTN) (3 * sizeof (DES_key_schedule));\r
34}\r
35\r
36/**\r
37 Initializes user-supplied memory as TDES context for subsequent use.\r
38\r
39 This function initializes user-supplied memory pointed by TdesContext as TDES context.\r
40 In addtion, it sets up all TDES key materials for subsequent encryption and decryption\r
41 operations.\r
42 There are 3 key options as follows:\r
43 KeyLength = 64, Keying option 1: K1 == K2 == K3 (Backward compatibility with DES)\r
44 KeyLength = 128, Keying option 2: K1 != K2 and K3 = K1 (Less Security)\r
45 KeyLength = 192 Keying option 3: K1 != K2 != K3 (Strongest)\r
46\r
47 If TdesContext is NULL, then ASSERT().\r
48 If Key is NULL, then ASSERT().\r
49 If KeyLength is not valid, then ASSERT().\r
50\r
51 @param[out] TdesContext Pointer to TDES context being initialized.\r
52 @param[in] Key Pointer to the user-supplied TDES key.\r
53 @param[in] KeyLength Length of TDES key in bits.\r
54\r
55 @retval TRUE TDES context initialization succeeded.\r
56 @retval FALSE TDES context initialization failed.\r
57\r
58**/\r
59BOOLEAN\r
60EFIAPI\r
61TdesInit (\r
62 OUT VOID *TdesContext,\r
63 IN CONST UINT8 *Key,\r
64 IN UINTN KeyLength\r
65 )\r
66{\r
67 DES_key_schedule *KeySchedule;\r
68\r
69 ASSERT (TdesContext != NULL);\r
70 ASSERT (Key != NULL);\r
71 ASSERT ((KeyLength == 64) || (KeyLength == 128) || (KeyLength == 192));\r
72\r
73 KeySchedule = (DES_key_schedule *) TdesContext;\r
74\r
75 //\r
76 // \r
77 //\r
78 if (DES_is_weak_key ((const_DES_cblock *) Key)) {\r
79 return FALSE;\r
80 }\r
81\r
82 DES_set_key_unchecked ((const_DES_cblock *) Key, KeySchedule);\r
83\r
84 if (KeyLength == 64) {\r
85 CopyMem (KeySchedule + 1, KeySchedule, sizeof (DES_key_schedule));\r
86 CopyMem (KeySchedule + 2, KeySchedule, sizeof (DES_key_schedule));\r
87 return TRUE;\r
88 }\r
89\r
90 if (DES_is_weak_key ((const_DES_cblock *) Key + 8)) {\r
91 return FALSE;\r
92 }\r
93\r
94 DES_set_key_unchecked ((const_DES_cblock *) (Key + 8), KeySchedule + 1);\r
95\r
96 if (KeyLength == 128) {\r
97 CopyMem (KeySchedule + 2, KeySchedule, sizeof (DES_key_schedule));\r
98 return TRUE;\r
99 }\r
100\r
101 if (DES_is_weak_key ((const_DES_cblock *) Key + 16)) {\r
102 return FALSE;\r
103 }\r
104\r
105 DES_set_key_unchecked ((const_DES_cblock *) (Key + 16), KeySchedule + 2);\r
106\r
107 return TRUE;\r
108}\r
109\r
110/**\r
111 Performs TDES encryption on a data buffer of the specified size in ECB mode.\r
112\r
113 This function performs TDES encryption on data buffer pointed by Input, of specified\r
114 size of InputSize, in ECB mode.\r
115 InputSize must be multiple of block size (8 bytes). This function does not perform\r
116 padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
117 TdesContext should be already correctly initialized by TdesInit(). Behavior with\r
118 invalid TDES context is undefined.\r
119\r
120 If TdesContext is NULL, then ASSERT().\r
121 If Input is NULL, then ASSERT().\r
122 If InputSize is not multiple of block size (8 bytes), then ASSERT().\r
123 If Output is NULL, then ASSERT().\r
124\r
125 @param[in] TdesContext Pointer to the TDES context.\r
126 @param[in] Input Pointer to the buffer containing the data to be encrypted.\r
127 @param[in] InputSize Size of the Input buffer in bytes.\r
128 @param[out] Output Pointer to a buffer that receives the TDES encryption output.\r
129\r
130 @retval TRUE TDES encryption succeeded.\r
131 @retval FALSE TDES encryption failed.\r
132\r
133**/\r
134BOOLEAN\r
135EFIAPI\r
136TdesEcbEncrypt (\r
137 IN VOID *TdesContext,\r
138 IN CONST UINT8 *Input,\r
139 IN UINTN InputSize,\r
140 OUT UINT8 *Output\r
141 )\r
142{\r
143 DES_key_schedule *KeySchedule;\r
144\r
145 ASSERT (TdesContext != NULL);\r
146 ASSERT (Input != NULL);\r
147 ASSERT ((InputSize % TDES_BLOCK_SIZE) == 0);\r
148 ASSERT (Output != NULL);\r
149\r
150 KeySchedule = (DES_key_schedule *) TdesContext;\r
151\r
152 while (InputSize > 0) {\r
153 DES_ecb3_encrypt (\r
154 (const_DES_cblock *) Input,\r
155 (DES_cblock *) Output,\r
156 KeySchedule,\r
157 KeySchedule + 1,\r
158 KeySchedule + 2,\r
159 DES_ENCRYPT\r
160 );\r
161 Input += TDES_BLOCK_SIZE;\r
162 Output += TDES_BLOCK_SIZE;\r
163 InputSize -= TDES_BLOCK_SIZE;\r
164 }\r
165\r
166 return TRUE;\r
167}\r
168\r
169/**\r
170 Performs TDES decryption on a data buffer of the specified size in ECB mode.\r
171\r
172 This function performs TDES decryption on data buffer pointed by Input, of specified\r
173 size of InputSize, in ECB mode.\r
174 InputSize must be multiple of block size (8 bytes). This function does not perform\r
175 padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
176 TdesContext should be already correctly initialized by TdesInit(). Behavior with\r
177 invalid TDES context is undefined.\r
178\r
179 If TdesContext is NULL, then ASSERT().\r
180 If Input is NULL, then ASSERT().\r
181 If InputSize is not multiple of block size (8 bytes), then ASSERT().\r
182 If Output is NULL, then ASSERT().\r
183\r
184 @param[in] TdesContext Pointer to the TDES context.\r
185 @param[in] Input Pointer to the buffer containing the data to be decrypted.\r
186 @param[in] InputSize Size of the Input buffer in bytes.\r
187 @param[out] Output Pointer to a buffer that receives the TDES decryption output.\r
188\r
189 @retval TRUE TDES decryption succeeded.\r
190 @retval FALSE TDES decryption failed.\r
191\r
192**/\r
193BOOLEAN\r
194EFIAPI\r
195TdesEcbDecrypt (\r
196 IN VOID *TdesContext,\r
197 IN CONST UINT8 *Input,\r
198 IN UINTN InputSize,\r
199 OUT UINT8 *Output\r
200 )\r
201{\r
202 DES_key_schedule *KeySchedule;\r
203\r
204 ASSERT (TdesContext != NULL);\r
205 ASSERT (Input != NULL);\r
206 ASSERT ((InputSize % TDES_BLOCK_SIZE) == 0);\r
207 ASSERT (Output != NULL);\r
208\r
209 KeySchedule = (DES_key_schedule *) TdesContext;\r
210\r
211 while (InputSize > 0) {\r
212 DES_ecb3_encrypt (\r
213 (const_DES_cblock *) Input,\r
214 (DES_cblock *) Output,\r
215 KeySchedule,\r
216 KeySchedule + 1,\r
217 KeySchedule + 2,\r
218 DES_DECRYPT\r
219 );\r
220 Input += TDES_BLOCK_SIZE;\r
221 Output += TDES_BLOCK_SIZE;\r
222 InputSize -= TDES_BLOCK_SIZE;\r
223 }\r
224\r
225 return TRUE;\r
226}\r
227\r
228/**\r
229 Performs TDES encryption on a data buffer of the specified size in CBC mode.\r
230\r
231 This function performs TDES encryption on data buffer pointed by Input, of specified\r
232 size of InputSize, in CBC mode.\r
233 InputSize must be multiple of block size (8 bytes). This function does not perform\r
234 padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
235 Initialization vector should be one block size (8 bytes).\r
236 TdesContext should be already correctly initialized by TdesInit(). Behavior with\r
237 invalid TDES context is undefined.\r
238\r
239 If TdesContext is NULL, then ASSERT().\r
240 If Input is NULL, then ASSERT().\r
241 If InputSize is not multiple of block size (8 bytes), then ASSERT().\r
242 If Ivec is NULL, then ASSERT().\r
243 If Output is NULL, then ASSERT().\r
244\r
245 @param[in] TdesContext Pointer to the TDES context.\r
246 @param[in] Input Pointer to the buffer containing the data to be encrypted.\r
247 @param[in] InputSize Size of the Input buffer in bytes.\r
248 @param[in] Ivec Pointer to initialization vector.\r
249 @param[out] Output Pointer to a buffer that receives the TDES encryption output.\r
250\r
251 @retval TRUE TDES encryption succeeded.\r
252 @retval FALSE TDES encryption failed.\r
253\r
254**/\r
255BOOLEAN\r
256EFIAPI\r
257TdesCbcEncrypt (\r
258 IN VOID *TdesContext,\r
259 IN CONST UINT8 *Input,\r
260 IN UINTN InputSize,\r
261 IN CONST UINT8 *Ivec,\r
262 OUT UINT8 *Output\r
263 )\r
264{\r
265 DES_key_schedule *KeySchedule;\r
266 UINT8 IvecBuffer[TDES_BLOCK_SIZE];\r
267\r
268 ASSERT (TdesContext != NULL);\r
269 ASSERT (Input != NULL);\r
270 ASSERT ((InputSize % TDES_BLOCK_SIZE) == 0);\r
271 ASSERT (Ivec != NULL);\r
272 ASSERT (Output != NULL);\r
273\r
274 KeySchedule = (DES_key_schedule *) TdesContext;\r
275 CopyMem (IvecBuffer, Ivec, TDES_BLOCK_SIZE);\r
276\r
277 DES_ede3_cbc_encrypt (\r
278 Input,\r
279 Output,\r
280 (UINT32) InputSize,\r
281 KeySchedule,\r
282 KeySchedule + 1,\r
283 KeySchedule + 2,\r
284 (DES_cblock *) IvecBuffer,\r
285 DES_ENCRYPT\r
286 );\r
287\r
288 return TRUE;\r
289}\r
290\r
291/**\r
292 Performs TDES decryption on a data buffer of the specified size in CBC mode.\r
293\r
294 This function performs TDES decryption on data buffer pointed by Input, of specified\r
295 size of InputSize, in CBC mode.\r
296 InputSize must be multiple of block size (8 bytes). This function does not perform\r
297 padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
298 Initialization vector should be one block size (8 bytes).\r
299 TdesContext should be already correctly initialized by TdesInit(). Behavior with\r
300 invalid TDES context is undefined.\r
301\r
302 If TdesContext is NULL, then ASSERT().\r
303 If Input is NULL, then ASSERT().\r
304 If InputSize is not multiple of block size (8 bytes), then ASSERT().\r
305 If Ivec is NULL, then ASSERT().\r
306 If Output is NULL, then ASSERT().\r
307\r
308 @param[in] TdesContext Pointer to the TDES context.\r
309 @param[in] Input Pointer to the buffer containing the data to be encrypted.\r
310 @param[in] InputSize Size of the Input buffer in bytes.\r
311 @param[in] Ivec Pointer to initialization vector.\r
312 @param[out] Output Pointer to a buffer that receives the TDES encryption output.\r
313\r
314 @retval TRUE TDES decryption succeeded.\r
315 @retval FALSE TDES decryption failed.\r
316\r
317**/\r
318BOOLEAN\r
319EFIAPI\r
320TdesCbcDecrypt (\r
321 IN VOID *TdesContext,\r
322 IN CONST UINT8 *Input,\r
323 IN UINTN InputSize,\r
324 IN CONST UINT8 *Ivec,\r
325 OUT UINT8 *Output\r
326 )\r
327{\r
328 DES_key_schedule *KeySchedule;\r
329 UINT8 IvecBuffer[TDES_BLOCK_SIZE];\r
330\r
331 ASSERT (TdesContext != NULL);\r
332 ASSERT (Input != NULL);\r
333 ASSERT ((InputSize % TDES_BLOCK_SIZE) == 0);\r
334 ASSERT (Ivec != NULL);\r
335 ASSERT (Output != NULL);\r
336\r
337 KeySchedule = (DES_key_schedule *) TdesContext;\r
338 CopyMem (IvecBuffer, Ivec, TDES_BLOCK_SIZE);\r
339\r
340 DES_ede3_cbc_encrypt (\r
341 Input,\r
342 Output,\r
343 (UINT32) InputSize,\r
344 KeySchedule,\r
345 KeySchedule + 1,\r
346 KeySchedule + 2,\r
347 (DES_cblock *) IvecBuffer,\r
348 DES_DECRYPT\r
349 );\r
350\r
351 return TRUE;\r
352}\r
353\r