From: Jakub Wlostowski Date: Fri, 9 May 2025 11:45:14 +0000 (+0200) Subject: Add new padding algorithms X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fheads%2Ftizen;p=platform%2Fcore%2Fsecurity%2Ftrusted%2Fkey-manager-ta.git Add new padding algorithms Change-Id: I214952d4463a887c88c41fc4cfd45ae35e16688c --- diff --git a/ta/include/crypto_padding.h b/ta/include/crypto_padding.h index 74fa3c8..bf94e2d 100644 --- a/ta/include/crypto_padding.h +++ b/ta/include/crypto_padding.h @@ -26,15 +26,13 @@ #include #include -typedef enum -{ - KM_PADDING_ZERO = 1, // not reversable - should be used only for hashes/keys, not for data - KM_PADDING_PKCS7, -} PaddingMode; +#include +#include +#include -uint32_t KM_CalculatePaddedSize(PaddingMode padding, uint32_t block_size, uint32_t data_size); -int KM_PadBuffer(PaddingMode padding, uint32_t block_size, void *in, uint32_t in_size, +uint32_t KM_CalculatePaddedSize(tz_padding_type padding, uint32_t block_size, uint32_t data_size); +int KM_PadBuffer(tz_padding_type padding, uint32_t block_size, void *in, uint32_t in_size, void *out, uint32_t *out_size); -int KM_UnpadBuffer(PaddingMode padding, void *buffer, uint32_t *buffer_size); +int KM_UnpadBuffer(tz_padding_type padding, void *buffer, uint32_t *buffer_size); #endif // _CRYPTO_PADDING_H_ \ No newline at end of file diff --git a/ta/include/km_ta_defines.h b/ta/include/km_ta_defines.h index 49cf1d1..14c473c 100644 --- a/ta/include/km_ta_defines.h +++ b/ta/include/km_ta_defines.h @@ -113,6 +113,18 @@ typedef enum { HASH_SHA512, } tz_hash_type; +/** \enum tz_padding_type + * \brief tz_padding_type contains padding function definitions + * + * Each enum corresponds to padding function that will be used in AES-CBC operations. + */ +typedef enum { + PADDING_NONE, /** None */ + PADDING_PKCS7, /** PKCS#7 */ + PADDING_ISO9797_M2, /** ISO9797 method 2 padding */ + PADDING_ZERO, /** Zero padding */ +} tz_padding_type; + /** \enum tz_data_type * \brief tz_data_type contains definitions of supported data types * diff --git a/ta/src/cmd_exec.c b/ta/src/cmd_exec.c index 25f5977..72ffd1d 100644 --- a/ta/src/cmd_exec.c +++ b/ta/src/cmd_exec.c @@ -42,7 +42,6 @@ #define KM_TA_ALG_AES_CFB 0x50005050 const uint32_t PBKDF2_ITERATIONS = 1024; -const PaddingMode PADDING_MODE = KM_PADDING_PKCS7; void randombytes(uint8_t* buffer, size_t bufferLen) { @@ -1795,7 +1794,7 @@ static TEE_Result KM_DoCipherWrappedKeyWithAes(TEE_ObjectHandle wkey, // Only CBC is a block cipher and needs to be padded if (tee_enc_mode == TEE_MODE_ENCRYPT && tee_algo == TEE_ALG_AES_CBC_NOPAD) { - out_size = KM_CalculatePaddedSize(KM_PADDING_PKCS7, AES_BLOCK_SIZE, input->data_size); + out_size = KM_CalculatePaddedSize(PADDING_PKCS7, AES_BLOCK_SIZE, input->data_size); in_padded_size = out_size; in_padded = TEE_Malloc(in_padded_size, 0); @@ -1805,7 +1804,7 @@ static TEE_Result KM_DoCipherWrappedKeyWithAes(TEE_ObjectHandle wkey, goto clean; } - if (KM_PadBuffer(PADDING_MODE, AES_BLOCK_SIZE, input->data, + if (KM_PadBuffer(PADDING_PKCS7, AES_BLOCK_SIZE, input->data, input->data_size, in_padded, &in_padded_size)) { LOG("Error during padding operation"); ret = TEE_ERROR_GENERIC; @@ -1844,7 +1843,7 @@ static TEE_Result KM_DoCipherWrappedKeyWithAes(TEE_ObjectHandle wkey, } if (tee_enc_mode == TEE_MODE_DECRYPT && tee_algo == TEE_ALG_AES_CBC_NOPAD) { - if (KM_UnpadBuffer(PADDING_MODE, out, &out_size)) { + if (KM_UnpadBuffer(PADDING_PKCS7, out, &out_size)) { LOG("Error during unpadding operation"); ret = TEE_ERROR_GENERIC; goto clean; @@ -2167,6 +2166,7 @@ TEE_Result KM_ExecCmdSymmetric(uint32_t commandID, TEE_Param param[4]) KM_BinaryData input_data; uint32_t with_pwd = 0; KM_PwdData pwd_data; + uint32_t padding; void *in_padded = NULL; uint32_t in_padded_size = 0; @@ -2199,6 +2199,12 @@ TEE_Result KM_ExecCmdSymmetric(uint32_t commandID, TEE_Param param[4]) goto clean; } + if (KM_DeserializeFlag(&in_buffer, &in_size_guard, &padding)) { + LOG("Error in deserialization"); + ret = TEE_ERROR_BAD_PARAMETERS; + goto clean; + } + if (KM_DeserializeBinaryData(&in_buffer, &in_size_guard, &iv)) { LOG("Error in deserialization"); ret = TEE_ERROR_BAD_PARAMETERS; @@ -2215,7 +2221,15 @@ TEE_Result KM_ExecCmdSymmetric(uint32_t commandID, TEE_Param param[4]) // Only CBC is a block cipher and needs to be padded if (commandID == CMD_ENCRYPT && algo == TEE_ALG_AES_CBC_NOPAD) { - out_size = KM_CalculatePaddedSize(KM_PADDING_PKCS7, AES_BLOCK_SIZE, input_data.data_size); + if (padding == PADDING_NONE) { + if (input_data.data_size % AES_BLOCK_SIZE) { + LOG("No padding enabled, data doesn't fit in the block"); + ret = TEE_ERROR_BAD_PARAMETERS; + goto clean; + } + } + + out_size = KM_CalculatePaddedSize(padding, AES_BLOCK_SIZE, input_data.data_size); in_padded_size = out_size; in_padded = TEE_Malloc(in_padded_size, 0); @@ -2225,7 +2239,7 @@ TEE_Result KM_ExecCmdSymmetric(uint32_t commandID, TEE_Param param[4]) goto clean; } - if (KM_PadBuffer(PADDING_MODE, AES_BLOCK_SIZE, input_data.data, + if (KM_PadBuffer(padding, AES_BLOCK_SIZE, input_data.data, input_data.data_size, in_padded, &in_padded_size)) { LOG("Error during padding operation"); ret = TEE_ERROR_GENERIC; @@ -2275,10 +2289,12 @@ TEE_Result KM_ExecCmdSymmetric(uint32_t commandID, TEE_Param param[4]) } if (CMD_DECRYPT == commandID && algo == TEE_ALG_AES_CBC_NOPAD) { - if (KM_UnpadBuffer(PADDING_MODE, out, &out_size)) { - LOG("Error during unpadding operation"); - ret = TEE_ERROR_GENERIC; - goto clean; + if (padding != PADDING_NONE) { + ret = KM_UnpadBuffer(padding, out, &out_size); + if (ret) { + LOG("Error during unpadding operation"); + goto clean; + } } } @@ -2398,7 +2414,7 @@ TEE_Result KM_ExecCmdAuth(uint32_t commandID, TEE_Param param[4]) goto clean; } - out_size = KM_CalculatePaddedSize(KM_PADDING_PKCS7, AES_BLOCK_SIZE, input.data_size); + out_size = KM_CalculatePaddedSize(PADDING_PKCS7, AES_BLOCK_SIZE, input.data_size); out = TEE_Malloc(out_size, 0); if (out == NULL) { diff --git a/ta/src/crypto_derive.c b/ta/src/crypto_derive.c index e8a20e0..62d62f5 100644 --- a/ta/src/crypto_derive.c +++ b/ta/src/crypto_derive.c @@ -112,7 +112,7 @@ TEE_Result KM_DeriveKey(void *pwd, uint32_t pwd_size, void *salt, uint32_t salt_ return TEE_ERROR_OUT_OF_MEMORY; } if (pwd_size < 10) { - KM_PadBuffer(KM_PADDING_ZERO, 10, pwd, pwd_size, hmacKeyBuffer, &hmacKeySize); + KM_PadBuffer(PADDING_ZERO, 10, pwd, pwd_size, hmacKeyBuffer, &hmacKeySize); } else { memcpy(hmacKeyBuffer, pwd, pwd_size); } diff --git a/ta/src/crypto_padding.c b/ta/src/crypto_padding.c index e7cda64..376e2fb 100644 --- a/ta/src/crypto_padding.c +++ b/ta/src/crypto_padding.c @@ -26,21 +26,31 @@ void KM_PadBuffer_Zero(void *in, uint32_t in_size, void *out, unsigned char to_pad); void KM_PadBuffer_PKCS7(void *in, uint32_t in_size, void *out, unsigned char to_pad); -void KM_UnpadBuffer_PKCS7(void *buffer, uint32_t buffer_size, uint32_t *was_padded); +int KM_UnpadBuffer_PKCS7(void *buffer, uint32_t buffer_size, uint32_t *was_padded); +int KM_UnpadBuffer_ISO9797_M2(void *buffer, uint32_t buffer_size, uint32_t *was_padded); -uint32_t KM_CalculatePaddedSize(PaddingMode padding, uint32_t block_size, uint32_t data_size) +uint32_t KM_CalculatePaddedSize(tz_padding_type padding, uint32_t block_size, uint32_t data_size) { uint32_t toPad = 0; - switch (padding) { - case KM_PADDING_ZERO: { + case PADDING_NONE: { + if (data_size % block_size) { + LOG("Data size must be multiple of block size when using no padding mode! \ + Data size: %d, block size: %d", data_size, block_size); + return 0; + } + + return data_size; + } + case PADDING_PKCS7: + case PADDING_ISO9797_M2: { toPad = block_size - (data_size % block_size); + if (toPad == 0) toPad = block_size; return data_size + toPad; } - case KM_PADDING_PKCS7: { + case PADDING_ZERO: { toPad = block_size - (data_size % block_size); - if (toPad == 0) toPad = block_size; return data_size + toPad; } default: { @@ -50,10 +60,9 @@ uint32_t KM_CalculatePaddedSize(PaddingMode padding, uint32_t block_size, uint32 } } -void KM_PadBuffer_Zero(void *in, uint32_t in_size, void *out, unsigned char to_pad) +void KM_PadBuffer_None(void *in, uint32_t in_size, void *out) { memcpy(out, in, in_size); - memset(&((unsigned char*)out)[in_size], 0x0, to_pad); } void KM_PadBuffer_PKCS7(void *in, uint32_t in_size, void *out, unsigned char to_pad) @@ -62,7 +71,20 @@ void KM_PadBuffer_PKCS7(void *in, uint32_t in_size, void *out, unsigned char to_ memset(&((unsigned char*)out)[in_size], to_pad, to_pad); } -int KM_PadBuffer(PaddingMode padding, uint32_t block_size, void *in, uint32_t in_size, +void KM_PadBuffer_ISO9797_M2(void *in, uint32_t in_size, void *out, unsigned char to_pad) +{ + memcpy(out, in, in_size); + memset(&((unsigned char*)out)[in_size], 0x80, 1); + memset(&((unsigned char*)out)[in_size + 1], 0x00, to_pad - 1); +} + +void KM_PadBuffer_Zero(void *in, uint32_t in_size, void *out, unsigned char to_pad) +{ + memcpy(out, in, in_size); + memset(&((unsigned char*)out)[in_size], 0x0, to_pad); +} + +int KM_PadBuffer(tz_padding_type padding, uint32_t block_size, void *in, uint32_t in_size, void *out, uint32_t *out_size) { uint32_t outputSize = 0; @@ -89,14 +111,22 @@ int KM_PadBuffer(PaddingMode padding, uint32_t block_size, void *in, uint32_t in } switch (padding) { - case KM_PADDING_ZERO: { - KM_PadBuffer_Zero(in, in_size, out, outputSize - in_size); + case PADDING_NONE: { + KM_PadBuffer_None(in, in_size, out); break; } - case KM_PADDING_PKCS7: { + case PADDING_PKCS7: { KM_PadBuffer_PKCS7(in, in_size, out, outputSize - in_size); break; } + case PADDING_ISO9797_M2: { + KM_PadBuffer_ISO9797_M2(in, in_size, out, outputSize - in_size); + break; + } + case PADDING_ZERO: { + KM_PadBuffer_Zero(in, in_size, out, outputSize - in_size); + break; + } default: { LOG("Unsupported padding requested"); return -1; @@ -107,13 +137,52 @@ int KM_PadBuffer(PaddingMode padding, uint32_t block_size, void *in, uint32_t in return 0; } -void KM_UnpadBuffer_PKCS7(void *buffer, uint32_t buffer_size, uint32_t *was_padded) +int KM_UnpadBuffer_PKCS7(void *buffer, uint32_t buffer_size, uint32_t *was_padded) { + if (!buffer || buffer_size % AES_BLOCK_SIZE) + return TEE_ERROR_BAD_PARAMETERS; + *was_padded = ((unsigned char*)buffer)[buffer_size - 1]; + + if (*was_padded > AES_BLOCK_SIZE || *was_padded == 0x00) + return TEE_ERROR_BAD_PARAMETERS; + + for (uint32_t i = *was_padded; i > 1; i--) { + if (((unsigned char*)buffer)[buffer_size - i] != *was_padded) + return TEE_ERROR_BAD_PARAMETERS; + } + + return 0; +} + +int KM_UnpadBuffer_ISO9797_M2(void *buffer, uint32_t buffer_size, uint32_t *was_padded) +{ + if (!buffer || buffer_size % AES_BLOCK_SIZE) + return TEE_ERROR_BAD_PARAMETERS; + + uint32_t index = buffer_size - 1; + uint32_t it = AES_BLOCK_SIZE; + while (it--) { + unsigned char last = ((unsigned char*)buffer)[index]; + if (last == 0x80) { + *was_padded = *was_padded + 1; + return 0; + } else if (last == 0x00) { + *was_padded = *was_padded + 1; + index--; + continue; + } else { + LOG("Padding type mismatch, ISO9797_M2 expected"); + return TEE_ERROR_BAD_PARAMETERS; + } + } + + return TEE_ERROR_BAD_PARAMETERS; } -int KM_UnpadBuffer(PaddingMode padding, void *buffer, uint32_t *buffer_size) +int KM_UnpadBuffer(tz_padding_type padding, void *buffer, uint32_t *buffer_size) { + int ret; uint32_t wasPadded = 0; if (buffer == NULL || buffer_size == NULL) { @@ -122,14 +191,17 @@ int KM_UnpadBuffer(PaddingMode padding, void *buffer, uint32_t *buffer_size) } switch (padding) { - case KM_PADDING_PKCS7: - KM_UnpadBuffer_PKCS7(buffer, *buffer_size, &wasPadded); + case PADDING_PKCS7: + ret = KM_UnpadBuffer_PKCS7(buffer, *buffer_size, &wasPadded); + break; + case PADDING_ISO9797_M2: + ret = KM_UnpadBuffer_ISO9797_M2(buffer, *buffer_size, &wasPadded); break; default: LOG("Unsupported padding requested"); - return -1; + return TEE_ERROR_GENERIC; } *buffer_size -= wasPadded; - return 0; + return ret; } \ No newline at end of file