+++ /dev/null
-/** @file\r
- TDES Wrapper Implementation over OpenSSL.\r
-\r
-Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "InternalCryptLib.h"\r
-#include <openssl/des.h>\r
-\r
-/**\r
- Retrieves the size, in bytes, of the context buffer required for TDES operations.\r
-\r
- @return The size, in bytes, of the context buffer required for TDES operations.\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-TdesGetContextSize (\r
- VOID\r
- )\r
-{\r
- //\r
- // Memory for 3 copies of DES_key_schedule is allocated, for K1, K2 and K3 each.\r
- //\r
- return (UINTN) (3 * sizeof (DES_key_schedule));\r
-}\r
-\r
-/**\r
- Initializes user-supplied memory as TDES context for subsequent use.\r
-\r
- This function initializes user-supplied memory pointed by TdesContext as TDES context.\r
- In addition, it sets up all TDES key materials for subsequent encryption and decryption\r
- operations.\r
- There are 3 key options as follows:\r
- KeyLength = 64, Keying option 1: K1 == K2 == K3 (Backward compatibility with DES)\r
- KeyLength = 128, Keying option 2: K1 != K2 and K3 = K1 (Less Security)\r
- KeyLength = 192 Keying option 3: K1 != K2 != K3 (Strongest)\r
-\r
- If TdesContext is NULL, then return FALSE.\r
- If Key is NULL, then return FALSE.\r
- If KeyLength is not valid, then return FALSE.\r
-\r
- @param[out] TdesContext Pointer to TDES context being initialized.\r
- @param[in] Key Pointer to the user-supplied TDES key.\r
- @param[in] KeyLength Length of TDES key in bits.\r
-\r
- @retval TRUE TDES context initialization succeeded.\r
- @retval FALSE TDES context initialization failed.\r
-\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-TdesInit (\r
- OUT VOID *TdesContext,\r
- IN CONST UINT8 *Key,\r
- IN UINTN KeyLength\r
- )\r
-{\r
- DES_key_schedule *KeySchedule;\r
-\r
- //\r
- // Check input parameters.\r
- //\r
- if (TdesContext == NULL || Key == NULL || (KeyLength != 64 && KeyLength != 128 && KeyLength != 192)) {\r
- return FALSE;\r
- }\r
-\r
- KeySchedule = (DES_key_schedule *) TdesContext;\r
-\r
- //\r
- // If input Key is a weak key, return error.\r
- //\r
- if (DES_is_weak_key ((const_DES_cblock *) Key) == 1) {\r
- return FALSE;\r
- }\r
-\r
- DES_set_key_unchecked ((const_DES_cblock *) Key, KeySchedule);\r
-\r
- if (KeyLength == 64) {\r
- CopyMem (KeySchedule + 1, KeySchedule, sizeof (DES_key_schedule));\r
- CopyMem (KeySchedule + 2, KeySchedule, sizeof (DES_key_schedule));\r
- return TRUE;\r
- }\r
-\r
- if (DES_is_weak_key ((const_DES_cblock *) (Key + 8)) == 1) {\r
- return FALSE;\r
- }\r
-\r
- DES_set_key_unchecked ((const_DES_cblock *) (Key + 8), KeySchedule + 1);\r
-\r
- if (KeyLength == 128) {\r
- CopyMem (KeySchedule + 2, KeySchedule, sizeof (DES_key_schedule));\r
- return TRUE;\r
- }\r
-\r
- if (DES_is_weak_key ((const_DES_cblock *) (Key + 16)) == 1) {\r
- return FALSE;\r
- }\r
-\r
- DES_set_key_unchecked ((const_DES_cblock *) (Key + 16), KeySchedule + 2);\r
-\r
- return TRUE;\r
-}\r
-\r
-/**\r
- Performs TDES encryption on a data buffer of the specified size in ECB mode.\r
-\r
- This function performs TDES encryption on data buffer pointed by Input, of specified\r
- size of InputSize, in ECB mode.\r
- InputSize must be multiple of block size (8 bytes). This function does not perform\r
- padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
- TdesContext should be already correctly initialized by TdesInit(). Behavior with\r
- invalid TDES context is undefined.\r
-\r
- If TdesContext is NULL, then return FALSE.\r
- If Input is NULL, then return FALSE.\r
- If InputSize is not multiple of block size (8 bytes), then return FALSE.\r
- If Output is NULL, then return FALSE.\r
-\r
- @param[in] TdesContext Pointer to the TDES context.\r
- @param[in] Input Pointer to the buffer containing the data to be encrypted.\r
- @param[in] InputSize Size of the Input buffer in bytes.\r
- @param[out] Output Pointer to a buffer that receives the TDES encryption output.\r
-\r
- @retval TRUE TDES encryption succeeded.\r
- @retval FALSE TDES encryption failed.\r
-\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-TdesEcbEncrypt (\r
- IN VOID *TdesContext,\r
- IN CONST UINT8 *Input,\r
- IN UINTN InputSize,\r
- OUT UINT8 *Output\r
- )\r
-{\r
- DES_key_schedule *KeySchedule;\r
-\r
- //\r
- // Check input parameters.\r
- //\r
- if (TdesContext == NULL || Input == NULL || (InputSize % TDES_BLOCK_SIZE) != 0 || Output == NULL) {\r
- return FALSE;\r
- }\r
-\r
- KeySchedule = (DES_key_schedule *) TdesContext;\r
-\r
- while (InputSize > 0) {\r
- DES_ecb3_encrypt (\r
- (const_DES_cblock *) Input,\r
- (DES_cblock *) Output,\r
- KeySchedule,\r
- KeySchedule + 1,\r
- KeySchedule + 2,\r
- DES_ENCRYPT\r
- );\r
- Input += TDES_BLOCK_SIZE;\r
- Output += TDES_BLOCK_SIZE;\r
- InputSize -= TDES_BLOCK_SIZE;\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-/**\r
- Performs TDES decryption on a data buffer of the specified size in ECB mode.\r
-\r
- This function performs TDES decryption on data buffer pointed by Input, of specified\r
- size of InputSize, in ECB mode.\r
- InputSize must be multiple of block size (8 bytes). This function does not perform\r
- padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
- TdesContext should be already correctly initialized by TdesInit(). Behavior with\r
- invalid TDES context is undefined.\r
-\r
- If TdesContext is NULL, then return FALSE.\r
- If Input is NULL, then return FALSE.\r
- If InputSize is not multiple of block size (8 bytes), then return FALSE.\r
- If Output is NULL, then return FALSE.\r
-\r
- @param[in] TdesContext Pointer to the TDES context.\r
- @param[in] Input Pointer to the buffer containing the data to be decrypted.\r
- @param[in] InputSize Size of the Input buffer in bytes.\r
- @param[out] Output Pointer to a buffer that receives the TDES decryption output.\r
-\r
- @retval TRUE TDES decryption succeeded.\r
- @retval FALSE TDES decryption failed.\r
-\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-TdesEcbDecrypt (\r
- IN VOID *TdesContext,\r
- IN CONST UINT8 *Input,\r
- IN UINTN InputSize,\r
- OUT UINT8 *Output\r
- )\r
-{\r
- DES_key_schedule *KeySchedule;\r
-\r
- //\r
- // Check input parameters.\r
- //\r
- if (TdesContext == NULL || Input == NULL || (InputSize % TDES_BLOCK_SIZE) != 0 || Output == NULL) {\r
- return FALSE;\r
- }\r
-\r
- KeySchedule = (DES_key_schedule *) TdesContext;\r
-\r
- while (InputSize > 0) {\r
- DES_ecb3_encrypt (\r
- (const_DES_cblock *) Input,\r
- (DES_cblock *) Output,\r
- KeySchedule,\r
- KeySchedule + 1,\r
- KeySchedule + 2,\r
- DES_DECRYPT\r
- );\r
- Input += TDES_BLOCK_SIZE;\r
- Output += TDES_BLOCK_SIZE;\r
- InputSize -= TDES_BLOCK_SIZE;\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-/**\r
- Performs TDES encryption on a data buffer of the specified size in CBC mode.\r
-\r
- This function performs TDES encryption on data buffer pointed by Input, of specified\r
- size of InputSize, in CBC mode.\r
- InputSize must be multiple of block size (8 bytes). This function does not perform\r
- padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
- Initialization vector should be one block size (8 bytes).\r
- TdesContext should be already correctly initialized by TdesInit(). Behavior with\r
- invalid TDES context is undefined.\r
-\r
- If TdesContext is NULL, then return FALSE.\r
- If Input is NULL, then return FALSE.\r
- If InputSize is not multiple of block size (8 bytes), then return FALSE.\r
- If Ivec is NULL, then return FALSE.\r
- If Output is NULL, then return FALSE.\r
-\r
- @param[in] TdesContext Pointer to the TDES context.\r
- @param[in] Input Pointer to the buffer containing the data to be encrypted.\r
- @param[in] InputSize Size of the Input buffer in bytes.\r
- @param[in] Ivec Pointer to initialization vector.\r
- @param[out] Output Pointer to a buffer that receives the TDES encryption output.\r
-\r
- @retval TRUE TDES encryption succeeded.\r
- @retval FALSE TDES encryption failed.\r
-\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-TdesCbcEncrypt (\r
- IN VOID *TdesContext,\r
- IN CONST UINT8 *Input,\r
- IN UINTN InputSize,\r
- IN CONST UINT8 *Ivec,\r
- OUT UINT8 *Output\r
- )\r
-{\r
- DES_key_schedule *KeySchedule;\r
- UINT8 IvecBuffer[TDES_BLOCK_SIZE];\r
-\r
- //\r
- // Check input parameters.\r
- //\r
- if (TdesContext == NULL || Input == NULL || (InputSize % TDES_BLOCK_SIZE) != 0) {\r
- return FALSE;\r
- }\r
-\r
- if (Ivec == NULL || Output == NULL || InputSize > INT_MAX) {\r
- return FALSE;\r
- }\r
-\r
- KeySchedule = (DES_key_schedule *) TdesContext;\r
- CopyMem (IvecBuffer, Ivec, TDES_BLOCK_SIZE);\r
-\r
- DES_ede3_cbc_encrypt (\r
- Input,\r
- Output,\r
- (UINT32) InputSize,\r
- KeySchedule,\r
- KeySchedule + 1,\r
- KeySchedule + 2,\r
- (DES_cblock *) IvecBuffer,\r
- DES_ENCRYPT\r
- );\r
-\r
- return TRUE;\r
-}\r
-\r
-/**\r
- Performs TDES decryption on a data buffer of the specified size in CBC mode.\r
-\r
- This function performs TDES decryption on data buffer pointed by Input, of specified\r
- size of InputSize, in CBC mode.\r
- InputSize must be multiple of block size (8 bytes). This function does not perform\r
- padding. Caller must perform padding, if necessary, to ensure valid input data size.\r
- Initialization vector should be one block size (8 bytes).\r
- TdesContext should be already correctly initialized by TdesInit(). Behavior with\r
- invalid TDES context is undefined.\r
-\r
- If TdesContext is NULL, then return FALSE.\r
- If Input is NULL, then return FALSE.\r
- If InputSize is not multiple of block size (8 bytes), then return FALSE.\r
- If Ivec is NULL, then return FALSE.\r
- If Output is NULL, then return FALSE.\r
-\r
- @param[in] TdesContext Pointer to the TDES context.\r
- @param[in] Input Pointer to the buffer containing the data to be encrypted.\r
- @param[in] InputSize Size of the Input buffer in bytes.\r
- @param[in] Ivec Pointer to initialization vector.\r
- @param[out] Output Pointer to a buffer that receives the TDES encryption output.\r
-\r
- @retval TRUE TDES decryption succeeded.\r
- @retval FALSE TDES decryption failed.\r
-\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-TdesCbcDecrypt (\r
- IN VOID *TdesContext,\r
- IN CONST UINT8 *Input,\r
- IN UINTN InputSize,\r
- IN CONST UINT8 *Ivec,\r
- OUT UINT8 *Output\r
- )\r
-{\r
- DES_key_schedule *KeySchedule;\r
- UINT8 IvecBuffer[TDES_BLOCK_SIZE];\r
-\r
- //\r
- // Check input parameters.\r
- //\r
- if (TdesContext == NULL || Input == NULL || (InputSize % TDES_BLOCK_SIZE) != 0) {\r
- return FALSE;\r
- }\r
-\r
- if (Ivec == NULL || Output == NULL || InputSize > INT_MAX) {\r
- return FALSE;\r
- }\r
-\r
- KeySchedule = (DES_key_schedule *) TdesContext;\r
- CopyMem (IvecBuffer, Ivec, TDES_BLOCK_SIZE);\r
-\r
- DES_ede3_cbc_encrypt (\r
- Input,\r
- Output,\r
- (UINT32) InputSize,\r
- KeySchedule,\r
- KeySchedule + 1,\r
- KeySchedule + 2,\r
- (DES_cblock *) IvecBuffer,\r
- DES_DECRYPT\r
- );\r
-\r
- return TRUE;\r
-}\r
-\r