#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)
{
// 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);
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;
}
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;
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;
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;
// 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);
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;
}
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;
+ }
}
}
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) {
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: {
}
}
-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)
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;
}
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;
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) {
}
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