]> git.proxmox.com Git - mirror_edk2.git/blame - CryptoPkg/Library/BaseCryptLib/Cipher/CryptTdes.c
1. Remove conducting ASSERT in BaseCryptLib.
[mirror_edk2.git] / CryptoPkg / Library / BaseCryptLib / Cipher / CryptTdes.c
CommitLineData
a8c44645 1/** @file\r
2 TDES Wrapper Implementation over OpenSSL.\r
3\r
16d2c32c 4Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>\r
a8c44645 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
16d2c32c 47 If TdesContext is NULL, then return FALSE.\r
48 If Key is NULL, then return FALSE.\r
49 If KeyLength is not valid, then return FALSE.\r
a8c44645 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
16d2c32c 69 //\r
70 // Check input parameters.\r
71 //\r
72 if (TdesContext == NULL || Key == NULL || (KeyLength != 64 && KeyLength != 128 && KeyLength != 192)) {\r
73 return FALSE;\r
74 }\r
a8c44645 75\r
76 KeySchedule = (DES_key_schedule *) TdesContext;\r
77\r
78 //\r
79 // \r
80 //\r
81 if (DES_is_weak_key ((const_DES_cblock *) Key)) {\r
82 return FALSE;\r
83 }\r
84\r
85 DES_set_key_unchecked ((const_DES_cblock *) Key, KeySchedule);\r
86\r
87 if (KeyLength == 64) {\r
88 CopyMem (KeySchedule + 1, KeySchedule, sizeof (DES_key_schedule));\r
89 CopyMem (KeySchedule + 2, KeySchedule, sizeof (DES_key_schedule));\r
90 return TRUE;\r
91 }\r
92\r
93 if (DES_is_weak_key ((const_DES_cblock *) Key + 8)) {\r
94 return FALSE;\r
95 }\r
96\r
97 DES_set_key_unchecked ((const_DES_cblock *) (Key + 8), KeySchedule + 1);\r
98\r
99 if (KeyLength == 128) {\r
100 CopyMem (KeySchedule + 2, KeySchedule, sizeof (DES_key_schedule));\r
101 return TRUE;\r
102 }\r
103\r
104 if (DES_is_weak_key ((const_DES_cblock *) Key + 16)) {\r
105 return FALSE;\r
106 }\r
107\r
108 DES_set_key_unchecked ((const_DES_cblock *) (Key + 16), KeySchedule + 2);\r
109\r
110 return TRUE;\r
111}\r
112\r
113/**\r
114 Performs TDES encryption on a data buffer of the specified size in ECB mode.\r
115\r
116 This function performs TDES encryption on data buffer pointed by Input, of specified\r
117 size of InputSize, in ECB mode.\r
118 InputSize must be multiple of block size (8 bytes). This function does not perform\r
119 padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
120 TdesContext should be already correctly initialized by TdesInit(). Behavior with\r
121 invalid TDES context is undefined.\r
122\r
16d2c32c 123 If TdesContext is NULL, then return FALSE.\r
124 If Input is NULL, then return FALSE.\r
125 If InputSize is not multiple of block size (8 bytes), then return FALSE.\r
126 If Output is NULL, then return FALSE.\r
a8c44645 127\r
128 @param[in] TdesContext Pointer to the TDES context.\r
129 @param[in] Input Pointer to the buffer containing the data to be encrypted.\r
130 @param[in] InputSize Size of the Input buffer in bytes.\r
131 @param[out] Output Pointer to a buffer that receives the TDES encryption output.\r
132\r
133 @retval TRUE TDES encryption succeeded.\r
134 @retval FALSE TDES encryption failed.\r
135\r
136**/\r
137BOOLEAN\r
138EFIAPI\r
139TdesEcbEncrypt (\r
140 IN VOID *TdesContext,\r
141 IN CONST UINT8 *Input,\r
142 IN UINTN InputSize,\r
143 OUT UINT8 *Output\r
144 )\r
145{\r
146 DES_key_schedule *KeySchedule;\r
147\r
16d2c32c 148 //\r
149 // Check input parameters.\r
150 //\r
151 if (TdesContext == NULL || Input == NULL || (InputSize % TDES_BLOCK_SIZE) != 0 || Output == NULL) {\r
152 return FALSE;\r
153 }\r
a8c44645 154\r
155 KeySchedule = (DES_key_schedule *) TdesContext;\r
156\r
157 while (InputSize > 0) {\r
158 DES_ecb3_encrypt (\r
159 (const_DES_cblock *) Input,\r
160 (DES_cblock *) Output,\r
161 KeySchedule,\r
162 KeySchedule + 1,\r
163 KeySchedule + 2,\r
164 DES_ENCRYPT\r
165 );\r
166 Input += TDES_BLOCK_SIZE;\r
167 Output += TDES_BLOCK_SIZE;\r
168 InputSize -= TDES_BLOCK_SIZE;\r
169 }\r
170\r
171 return TRUE;\r
172}\r
173\r
174/**\r
175 Performs TDES decryption on a data buffer of the specified size in ECB mode.\r
176\r
177 This function performs TDES decryption on data buffer pointed by Input, of specified\r
178 size of InputSize, in ECB mode.\r
179 InputSize must be multiple of block size (8 bytes). This function does not perform\r
180 padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
181 TdesContext should be already correctly initialized by TdesInit(). Behavior with\r
182 invalid TDES context is undefined.\r
183\r
16d2c32c 184 If TdesContext is NULL, then return FALSE.\r
185 If Input is NULL, then return FALSE.\r
186 If InputSize is not multiple of block size (8 bytes), then return FALSE.\r
187 If Output is NULL, then return FALSE.\r
a8c44645 188\r
189 @param[in] TdesContext Pointer to the TDES context.\r
190 @param[in] Input Pointer to the buffer containing the data to be decrypted.\r
191 @param[in] InputSize Size of the Input buffer in bytes.\r
192 @param[out] Output Pointer to a buffer that receives the TDES decryption output.\r
193\r
194 @retval TRUE TDES decryption succeeded.\r
195 @retval FALSE TDES decryption failed.\r
196\r
197**/\r
198BOOLEAN\r
199EFIAPI\r
200TdesEcbDecrypt (\r
201 IN VOID *TdesContext,\r
202 IN CONST UINT8 *Input,\r
203 IN UINTN InputSize,\r
204 OUT UINT8 *Output\r
205 )\r
206{\r
207 DES_key_schedule *KeySchedule;\r
208\r
16d2c32c 209 //\r
210 // Check input parameters.\r
211 //\r
212 if (TdesContext == NULL || Input == NULL || (InputSize % TDES_BLOCK_SIZE) != 0 || Output == NULL) {\r
213 return FALSE;\r
214 }\r
a8c44645 215\r
216 KeySchedule = (DES_key_schedule *) TdesContext;\r
217\r
218 while (InputSize > 0) {\r
219 DES_ecb3_encrypt (\r
220 (const_DES_cblock *) Input,\r
221 (DES_cblock *) Output,\r
222 KeySchedule,\r
223 KeySchedule + 1,\r
224 KeySchedule + 2,\r
225 DES_DECRYPT\r
226 );\r
227 Input += TDES_BLOCK_SIZE;\r
228 Output += TDES_BLOCK_SIZE;\r
229 InputSize -= TDES_BLOCK_SIZE;\r
230 }\r
231\r
232 return TRUE;\r
233}\r
234\r
235/**\r
236 Performs TDES encryption on a data buffer of the specified size in CBC mode.\r
237\r
238 This function performs TDES encryption on data buffer pointed by Input, of specified\r
239 size of InputSize, in CBC mode.\r
240 InputSize must be multiple of block size (8 bytes). This function does not perform\r
241 padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
242 Initialization vector should be one block size (8 bytes).\r
243 TdesContext should be already correctly initialized by TdesInit(). Behavior with\r
244 invalid TDES context is undefined.\r
245\r
16d2c32c 246 If TdesContext is NULL, then return FALSE.\r
247 If Input is NULL, then return FALSE.\r
248 If InputSize is not multiple of block size (8 bytes), then return FALSE.\r
249 If Ivec is NULL, then return FALSE.\r
250 If Output is NULL, then return FALSE.\r
a8c44645 251\r
252 @param[in] TdesContext Pointer to the TDES context.\r
253 @param[in] Input Pointer to the buffer containing the data to be encrypted.\r
254 @param[in] InputSize Size of the Input buffer in bytes.\r
255 @param[in] Ivec Pointer to initialization vector.\r
256 @param[out] Output Pointer to a buffer that receives the TDES encryption output.\r
257\r
258 @retval TRUE TDES encryption succeeded.\r
259 @retval FALSE TDES encryption failed.\r
260\r
261**/\r
262BOOLEAN\r
263EFIAPI\r
264TdesCbcEncrypt (\r
265 IN VOID *TdesContext,\r
266 IN CONST UINT8 *Input,\r
267 IN UINTN InputSize,\r
268 IN CONST UINT8 *Ivec,\r
269 OUT UINT8 *Output\r
270 )\r
271{\r
272 DES_key_schedule *KeySchedule;\r
273 UINT8 IvecBuffer[TDES_BLOCK_SIZE];\r
274\r
16d2c32c 275 //\r
276 // Check input parameters.\r
277 //\r
278 if (TdesContext == NULL || Input == NULL || (InputSize % TDES_BLOCK_SIZE) != 0 || Ivec == NULL || Output == NULL) {\r
279 return FALSE;\r
280 }\r
a8c44645 281\r
282 KeySchedule = (DES_key_schedule *) TdesContext;\r
283 CopyMem (IvecBuffer, Ivec, TDES_BLOCK_SIZE);\r
284\r
285 DES_ede3_cbc_encrypt (\r
286 Input,\r
287 Output,\r
288 (UINT32) InputSize,\r
289 KeySchedule,\r
290 KeySchedule + 1,\r
291 KeySchedule + 2,\r
292 (DES_cblock *) IvecBuffer,\r
293 DES_ENCRYPT\r
294 );\r
295\r
296 return TRUE;\r
297}\r
298\r
299/**\r
300 Performs TDES decryption on a data buffer of the specified size in CBC mode.\r
301\r
302 This function performs TDES decryption on data buffer pointed by Input, of specified\r
303 size of InputSize, in CBC mode.\r
304 InputSize must be multiple of block size (8 bytes). This function does not perform\r
305 padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
306 Initialization vector should be one block size (8 bytes).\r
307 TdesContext should be already correctly initialized by TdesInit(). Behavior with\r
308 invalid TDES context is undefined.\r
309\r
16d2c32c 310 If TdesContext is NULL, then return FALSE.\r
311 If Input is NULL, then return FALSE.\r
312 If InputSize is not multiple of block size (8 bytes), then return FALSE.\r
313 If Ivec is NULL, then return FALSE.\r
314 If Output is NULL, then return FALSE.\r
a8c44645 315\r
316 @param[in] TdesContext Pointer to the TDES context.\r
317 @param[in] Input Pointer to the buffer containing the data to be encrypted.\r
318 @param[in] InputSize Size of the Input buffer in bytes.\r
319 @param[in] Ivec Pointer to initialization vector.\r
320 @param[out] Output Pointer to a buffer that receives the TDES encryption output.\r
321\r
322 @retval TRUE TDES decryption succeeded.\r
323 @retval FALSE TDES decryption failed.\r
324\r
325**/\r
326BOOLEAN\r
327EFIAPI\r
328TdesCbcDecrypt (\r
329 IN VOID *TdesContext,\r
330 IN CONST UINT8 *Input,\r
331 IN UINTN InputSize,\r
332 IN CONST UINT8 *Ivec,\r
333 OUT UINT8 *Output\r
334 )\r
335{\r
336 DES_key_schedule *KeySchedule;\r
337 UINT8 IvecBuffer[TDES_BLOCK_SIZE];\r
338\r
16d2c32c 339 //\r
340 // Check input parameters.\r
341 //\r
342 if (TdesContext == NULL || Input == NULL || (InputSize % TDES_BLOCK_SIZE) != 0 || Ivec == NULL || Output == NULL) {\r
343 return FALSE;\r
344 }\r
a8c44645 345\r
346 KeySchedule = (DES_key_schedule *) TdesContext;\r
347 CopyMem (IvecBuffer, Ivec, TDES_BLOCK_SIZE);\r
348\r
349 DES_ede3_cbc_encrypt (\r
350 Input,\r
351 Output,\r
352 (UINT32) InputSize,\r
353 KeySchedule,\r
354 KeySchedule + 1,\r
355 KeySchedule + 2,\r
356 (DES_cblock *) IvecBuffer,\r
357 DES_DECRYPT\r
358 );\r
359\r
360 return TRUE;\r
361}\r
362\r