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