Add new padding algorithms 50/323950/7 tizen
authorJakub Wlostowski <j.wlostowski@samsung.com>
Fri, 9 May 2025 11:45:14 +0000 (13:45 +0200)
committerJakub Wlostowski <j.wlostowski@samsung.com>
Thu, 15 May 2025 11:49:00 +0000 (13:49 +0200)
Change-Id: I214952d4463a887c88c41fc4cfd45ae35e16688c

ta/include/crypto_padding.h
ta/include/km_ta_defines.h
ta/src/cmd_exec.c
ta/src/crypto_derive.c
ta/src/crypto_padding.c

index 74fa3c8358c607948c72f6f87196fbbb29f4e183..bf94e2ddfcceacf935f5bee632d40edf9b1c682c 100644 (file)
 #include <stddef.h>
 #include <stdint.h>
 
-typedef enum
-{
-       KM_PADDING_ZERO = 1, // not reversable - should be used only for hashes/keys, not for data
-       KM_PADDING_PKCS7,
-} PaddingMode;
+#include <km_ta_defines.h>
+#include <tee_internal_api.h>
+#include <internal.h>
 
-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
index 49cf1d1f8007e75c6a76617d85070299cfcf538e..14c473c947dba7e0ea7573e76ebd1edbfc4adbb9 100644 (file)
@@ -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
  *
index 25f597769f496fa4fb8e0ff7a7febfa26907edc9..72ffd1d0beda5d4b351dc65fdd30198789367a2f 100644 (file)
@@ -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) {
index e8a20e0a000bd59cd9633023251a747bf0323751..62d62f5c66169ce04d826343e6f7f7646c84c4fa 100644 (file)
@@ -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);
        }
index e7cda64c8e871ff6d4faac4c85dd73c4138f274e..376e2fbcd647bb7444f14bcfedf94542c7efaa3b 100644 (file)
 
 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