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