/*
* @file serialization.h
* @author Rafał Tyminski (r.tyminski@partner.samsung.com)
+ * @author Lukasz Kostyra (l.kostyra@samsung.com)
* @version 1.0
* @brief Implementaion of tee commands parameters serialization
*/
-#ifndef __PARAMS_SERIALIZATION_H__
-#define __PARAMS_SERIALIZATION_H__
+#ifndef __KM_SERIALIZATION_H__
+#define __KM_SERIALIZATION_H__
#include <stdint.h>
typedef enum KM_ParamsMagic {
PSMagic_SymmetricInput = 0x542345,
PSMagic_InputData = 0x575445,
+ PSMagic_PwdData = 0x707764,
PSMagic_IVData = 0x445234,
PSMagic_AEData = 0x810891,
PSMagic_OutData = 0x721513,
PSMagic_TagData = 0x721513,
- PSMagic_Key = 0x946704,
PSMagic_KeyId = 0x946704
-} PSMagic;
+} KM_PSMagic;
-typedef struct Data_ {
+typedef struct KM_Data_ {
uint32_t magic;
uint32_t data_size;
void *data;
-} Data;
+} KM_Data;
-typedef struct Data_ InputData;
+typedef struct KM_Data_ KM_InputData;
-typedef struct Data_ OutData;
+typedef struct KM_Data_ KM_OutData;
-typedef struct Data_ IVData;
+typedef struct KM_Data_ KM_IVData;
-typedef struct Data_ KeyId;
+typedef struct KM_Data_ KM_KeyId;
-typedef struct Data_ TagData;
+typedef struct KM_Data_ KM_TagData;
-typedef struct AEData_ {
- Data aad;
- uint32_t tagLen;
- uint32_t payloadLen;
-} AEData;
+typedef struct KM_AEData_ {
+ KM_Data aad;
+ uint32_t tag_len;
+ uint32_t payload_len;
+} KM_AEData;
-typedef struct Key_ {
- Data key;
- uint32_t key_bits_size;
-} Key;
-
-typedef struct SymmetricInput_ {
+typedef struct KM_PwdData_ {
+ uint32_t magic;
+ uint32_t pwd_size;
+ uint32_t iv_size;
+ uint32_t tag_size;
+ uint32_t derive_len_bits;
+ uint32_t it_count;
+ uint32_t tag_len_bits;
+ void *pwd;
+ void *iv;
+ void *tag;
+} KM_PwdData;
+
+typedef struct KM_SymmetricInput_ {
uint32_t magic;
uint32_t buffer_size;
- uint32_t key_data_offset;
uint32_t key_id_data_offset;
uint32_t input_data_offset;
+ uint32_t pwd_data_offset;
uint32_t iv_data_offset;
uint32_t ae_data_offset;
uint32_t out_data_offset;
uint32_t tag_data_offset;
uint32_t global_offset;
-} SymmetricInput;
-
-void KM_ParamsDump(SymmetricInput *input, InputData *input_data, IVData *iv_data,
- Key *key_data, KeyId *key_id_data, AEData *ae_data, OutData *out_data,
- TagData *tag_data);
-uint32_t KM_GetSerializedBufferRealSize(SymmetricInput *buffer);
-uint32_t KM_PrecalculateBufferSize(uint32_t input_size, uint32_t iv_size, uint32_t with_ae_data,
- uint32_t aad_size, uint32_t out_size, uint32_t tag_size,
- uint32_t key_size, uint32_t key_id_size);
-
-int KM_ParamsDeserializationInit(void *buffer, uint32_t buffer_size, SymmetricInput **out);
-int KM_ParamsDeserializeInputData(SymmetricInput *self, InputData **out);
-int KM_ParamsDeserializeIVData(SymmetricInput *self, IVData **out);
-int KM_ParamsDeserializeAEData(SymmetricInput *self, AEData **out);
-int KM_ParamsDeserializeOutData(SymmetricInput *self, OutData **out);
-int KM_ParamsDeserializeTagData(SymmetricInput *self, TagData **out);
-int KM_ParamsDeserializeKey(SymmetricInput *self, Key **out);
-int KM_ParamsDeserializeKeyId(SymmetricInput *self, KeyId **out);
-
-int KM_ParamsSerializationInit(void *buffer, uint32_t buffer_size, SymmetricInput **out);
-int KM_ParamsSerializeInputData(SymmetricInput *self, const void *data, uint32_t data_size);
-int KM_ParamsSerializeIVData(SymmetricInput *self, const void *data, uint32_t data_size);
-int KM_ParamsSerializeAEData(SymmetricInput *self, uint32_t tagLen, uint32_t payloadLen,
+} KM_SymmetricInput;
+
+typedef struct KM_BufferSizeDesc_ {
+ uint32_t input_size;
+ uint32_t with_pwd_data;
+ uint32_t pwd_size;
+ uint32_t pwd_iv_size;
+ uint32_t pwd_tag_size;
+ uint32_t iv_size;
+ uint32_t with_ae_data;
+ uint32_t aad_size;
+ uint32_t out_size;
+ uint32_t tag_size;
+ uint32_t key_id_size;
+} KM_BufferSizeDesc;
+
+void KM_ParamsDump(KM_SymmetricInput *input, KM_InputData *input_data, KM_PwdData* pwd_data,
+ KM_IVData *iv_data, KM_KeyId *key_data, KM_AEData *ae_data,
+ KM_OutData *out_data, KM_TagData *tag_data);
+uint32_t KM_GetSerializedBufferRealSize(KM_SymmetricInput *buffer);
+uint32_t KM_CalcBufferSize(KM_BufferSizeDesc desc);
+
+int KM_ParamsDeserializationInit(void *buffer, uint32_t buffer_size, KM_SymmetricInput **out);
+int KM_ParamsDeserializeInputData(KM_SymmetricInput *self, KM_InputData **out);
+int KM_ParamsDeserializeIVData(KM_SymmetricInput *self, KM_IVData **out);
+int KM_ParamsDeserializeAEData(KM_SymmetricInput *self, KM_AEData **out);
+int KM_ParamsDeserializeOutData(KM_SymmetricInput *self, KM_OutData **out);
+int KM_ParamsDeserializeTagData(KM_SymmetricInput *self, KM_TagData **out);
+int KM_ParamsDeserializeKeyId(KM_SymmetricInput *self, KM_KeyId **out);
+int KM_ParamsDeserializePwdData(KM_SymmetricInput *self, KM_PwdData **out);
+
+int KM_ParamsSerializationInit(void *buffer, uint32_t buffer_size, KM_SymmetricInput **out);
+int KM_ParamsSerializeInputData(KM_SymmetricInput *self, const void *data, uint32_t data_size);
+int KM_ParamsSerializeIVData(KM_SymmetricInput *self, const void *data, uint32_t data_size);
+int KM_ParamsSerializeAEData(KM_SymmetricInput *self, uint32_t tagLen, uint32_t payloadLen,
const void *aad, uint32_t aad_size);
-int KM_ParamsSerializeOutData(SymmetricInput *self, const void *data, uint32_t data_size);
-
-int KM_ParamsSerializeTagData(SymmetricInput *self, const void *data, size_t data_size);
-
-int KM_ParamsSerializeKey(SymmetricInput *self, const void *data, size_t data_size,
- uint32_t bits_size);
-
-int KM_ParamsSerializeKeyId(SymmetricInput *self, const void *data, size_t data_size);
-
+int KM_ParamsSerializeOutData(KM_SymmetricInput *self, const void *data, uint32_t data_size);
+int KM_ParamsSerializeTagData(KM_SymmetricInput *self, const void *data, size_t data_size);
+int KM_ParamsSerializeKeyId(KM_SymmetricInput *self, const void *data, size_t data_size);
+int KM_ParamsSerializePwdData(KM_SymmetricInput *self, const void *pwd, uint32_t pwd_size,
+ const void *iv, uint32_t iv_size, const void *tag, uint32_t tag_size,
+ uint32_t derive_len_bits, uint32_t it_count, uint32_t tag_len_bits);
#ifdef __cplusplus
}
#endif
-#endif //__PARAMS_SERIALIZATION_H__
+#endif //__KM_SERIALIZATION_H__
/*
* @file serialization.c
* @author Rafał Tyminski (r.tyminski@partner.samsung.com)
+ * @author Lukasz Kostyra (l.kostyra@samsung.com)
* @version 1.0
* @brief Implementaion of tee commands parameters serialization
*/
static int KM_ParamsDeserializeData(void *self, uint32_t offset, uint32_t magic,
- uint32_t size, Data **out)
+ uint32_t size, KM_Data **out)
{
- uint32_t curr_ptr = 0;
- Data *ptr = NULL;
+ uint8_t *curr_ptr = 0;
+ KM_Data *ptr = NULL;
if (NULL == self || NULL == out) {
LOG("Invalid input.");
return -1;
if (0 == offset) {
// There's no data so we return gently
+ *out = NULL;
return 0;
}
- curr_ptr = ((uint32_t) self) + offset;
- ptr = (Data *) curr_ptr;
+ curr_ptr = ((uint8_t *) self) + offset;
+ ptr = (KM_Data *)curr_ptr;
if (magic != ptr->magic) {
LOG("Invalid magic.");
return 0;
}
-static int KM_ParamsSerializeData(SymmetricInput *self, const void *data, size_t data_size,
- uint32_t size, uint32_t magic, Data **ptr)
+static int KM_ParamsSerializeData(KM_SymmetricInput *self, const void *data, size_t data_size,
+ uint32_t size, uint32_t magic, KM_Data **ptr)
{
uint8_t* curr_ptr = 0;
- Data *tmp = NULL;
+ KM_Data *tmp = NULL;
if (self == NULL) {
LOG("Provided NULL serialization pointer");
return -1;
self->buffer_size, self->global_offset + size + data_size);
return -1;
}
- curr_ptr = ((uint8_t*)self) + self->global_offset;
- tmp = (Data*)curr_ptr;
+ curr_ptr = ((uint8_t *)self) + self->global_offset;
+ tmp = (KM_Data*)curr_ptr;
tmp->magic = magic;
tmp->data_size = data_size;
// UTILITY FUNCTIONS
-void KM_ParamsDump(SymmetricInput *input, InputData *input_data, IVData *iv_data,
- Key *key_data, KeyId *key_id_data, AEData *ae_data, OutData *out_data,
- TagData *tag_data)
+void KM_ParamsDump(KM_SymmetricInput *input, KM_InputData *input_data, KM_PwdData *pwd_data,
+ KM_IVData *iv_data, KM_KeyId *key_id_data, KM_AEData *ae_data,
+ KM_OutData *out_data, KM_TagData *tag_data)
{
if (input) {
- LOG("buffer_size=%d key_data_offset=%d key_id_data_offset=%d input_data_offset=%d "
- "iv_data_offset=%d ae_data_offset=%d out_data_offset=%d tag_data_offset=%d| "
- "global_offset=%d", input->buffer_size, input->key_data_offset,
- input->key_id_data_offset, input->input_data_offset, input->iv_data_offset,
- input->ae_data_offset, input->out_data_offset, input->tag_data_offset,
- input->global_offset);
- }
- if (key_data) {
- LOG("Key=%p, key_size=%d, key_bits_size=%d", key_data->key.data, key_data->key.data_size,
- key_data->key_bits_size);
+ LOG("buffer_size=%d key_id_data_offset=%d input_data_offset=%d "
+ "pwd_data_offset=%d iv_data_offset=%d ae_data_offset=%d "
+ "out_data_offset=%d tag_data_offset=%d | global_offset=%d",
+ input->buffer_size, input->key_id_data_offset, input->input_data_offset,
+ input->pwd_data_offset, input->iv_data_offset, input->ae_data_offset,
+ input->out_data_offset, input->tag_data_offset, input->global_offset);
}
if (key_id_data) {
LOG("Key_id=%p, key_id_size=%d", key_id_data->data, key_id_data->data_size);
if (input_data) {
LOG("Input=%p, input_size=%d", input_data->data, input_data->data_size);
}
+ if (pwd_data) {
+ LOG("Pwd_size=%d, iv_size=%d, tag_size=%d, derive_len=%d",
+ pwd_data->pwd_size, pwd_data->iv_size, pwd_data->tag_size, pwd_data->derive_len_bits);
+ LOG("it_count=%d, tag_len=%d pwd=%p, iv=%p, tag=%p",
+ pwd_data->it_count, pwd_data->tag_len_bits, pwd_data->pwd, pwd_data->iv, pwd_data->tag);
+ }
if (ae_data) {
- LOG("aad.data=%p, aad.size=%d, tagLen=%d, payloadLen=%d", ae_data->aad.data,
- ae_data->aad.data_size, ae_data->tagLen, ae_data->payloadLen);
+ LOG("aad.data=%p, aad.size=%d, tag_len=%d, payload_len=%d", ae_data->aad.data,
+ ae_data->aad.data_size, ae_data->tag_len, ae_data->payload_len);
}
if (out_data) {
LOG("Out=%p, out_size=%d", out_data->data, out_data->data_size);
}
}
-uint32_t KM_GetSerializedBufferRealSize(SymmetricInput *buffer)
+uint32_t KM_GetSerializedBufferRealSize(KM_SymmetricInput *buffer)
{
if (buffer == NULL) {
LOG("Incorrect buffer provided");
return buffer->global_offset;
}
-uint32_t KM_PrecalculateBufferSize(uint32_t input_size, uint32_t iv_size, uint32_t with_ae_data,
- uint32_t aad_size, uint32_t out_size, uint32_t tag_size,
- uint32_t key_size, uint32_t key_id_size)
+uint32_t KM_CalcBufferSize(KM_BufferSizeDesc desc)
{
- uint32_t size = sizeof(SymmetricInput);
+ uint32_t size = sizeof(KM_SymmetricInput);
- if (input_size > 0)
- size += sizeof(InputData) + addAlignment(input_size);
+ if (desc.input_size > 0)
+ size += addAlignment(sizeof(KM_InputData) + desc.input_size);
- if (iv_size > 0)
- size += sizeof(IVData) + addAlignment(iv_size);
+ if (desc.with_pwd_data) {
+ uint32_t pwdsize = sizeof(KM_PwdData);
+ if (desc.pwd_size > 0) pwdsize += desc.pwd_size;
+ if (desc.pwd_iv_size > 0) pwdsize += desc.pwd_iv_size;
+ if (desc.pwd_tag_size > 0) pwdsize += desc.pwd_tag_size;
+ size += addAlignment(pwdsize);
+ }
- if (with_ae_data > 0)
- size += sizeof(AEData) + sizeof(Data) + addAlignment(aad_size);
+ if (desc.iv_size > 0)
+ size += addAlignment(sizeof(KM_IVData) + desc.iv_size);
- if (out_size > 0)
- size += sizeof(OutData) + addAlignment(out_size);
+ if (desc.with_ae_data) {
+ uint32_t aesize = sizeof(KM_AEData);
+ if (desc.aad_size > 0) aesize += desc.aad_size;
+ size += addAlignment(aesize);
+ }
- if (tag_size > 0)
- size += sizeof(TagData) + addAlignment(tag_size);
+ if (desc.out_size > 0)
+ size += addAlignment(sizeof(KM_OutData) + desc.out_size);
- if (key_size > 0)
- size += sizeof(Key) + addAlignment(key_size);
+ if (desc.tag_size > 0)
+ size += addAlignment(sizeof(KM_TagData) + desc.tag_size);
- if (key_id_size > 0)
- size += sizeof(KeyId) + addAlignment(key_id_size);
+ if (desc.key_id_size > 0)
+ size += addAlignment(sizeof(KM_KeyId) + desc.key_id_size);
return size;
}
// DESERIALIZATORS
-int KM_ParamsDeserializationInit(void *buffer, size_t buffer_size, SymmetricInput **out)
+int KM_ParamsDeserializationInit(void *buffer, size_t buffer_size, KM_SymmetricInput **out)
{
- SymmetricInput *self = (SymmetricInput *) buffer;
+ KM_SymmetricInput *self = (KM_SymmetricInput *)buffer;
if (buffer == NULL) {
LOG("Invalid input buffer");
return -1;
}
- if (sizeof(SymmetricInput) > buffer_size) {
+ if (sizeof(KM_SymmetricInput) > buffer_size) {
LOG("Serialization buffer not big enough.");
return -1;
}
return 0;
}
-int KM_ParamsDeserializeInputData(SymmetricInput *self, InputData **out)
+int KM_ParamsDeserializeInputData(KM_SymmetricInput *self, KM_InputData **out)
{
return KM_ParamsDeserializeData((void *)self, self->input_data_offset, PSMagic_InputData,
- sizeof(InputData), (Data**) out);
+ sizeof(KM_InputData), (KM_Data**) out);
}
-int KM_ParamsDeserializeIVData(SymmetricInput *self, IVData **out)
+int KM_ParamsDeserializeIVData(KM_SymmetricInput *self, KM_IVData **out)
{
return KM_ParamsDeserializeData((void *)self, self->iv_data_offset, PSMagic_IVData,
- sizeof(IVData), (Data**) out);
+ sizeof(KM_IVData), (KM_Data**) out);
}
-int KM_ParamsDeserializeAEData(SymmetricInput *self, AEData **out)
+int KM_ParamsDeserializeAEData(KM_SymmetricInput *self, KM_AEData **out)
{
return KM_ParamsDeserializeData((void *)self, self->ae_data_offset, PSMagic_AEData,
- sizeof(AEData), (Data**) out);
+ sizeof(KM_AEData), (KM_Data**) out);
}
-int KM_ParamsDeserializeOutData(SymmetricInput *self, OutData **out)
+int KM_ParamsDeserializeOutData(KM_SymmetricInput *self, KM_OutData **out)
{
return KM_ParamsDeserializeData((void *)self, self->out_data_offset, PSMagic_OutData,
- sizeof(OutData), (Data**) out);
+ sizeof(KM_OutData), (KM_Data**) out);
}
-int KM_ParamsDeserializeTagData(SymmetricInput *self, TagData **out)
+int KM_ParamsDeserializeTagData(KM_SymmetricInput *self, KM_TagData **out)
{
return KM_ParamsDeserializeData((void *)self, self->tag_data_offset, PSMagic_TagData,
- sizeof(TagData), (Data**) out);
+ sizeof(KM_TagData), (KM_Data**) out);
}
-int KM_ParamsDeserializeKey(SymmetricInput *self, Key **out)
+int KM_ParamsDeserializeKeyId(KM_SymmetricInput *self, KM_KeyId **out)
{
- return KM_ParamsDeserializeData((void *)self, self->key_data_offset, PSMagic_Key,
- sizeof(Key), (Data**) out);
+ return KM_ParamsDeserializeData((void *)self, self->key_id_data_offset, PSMagic_KeyId,
+ sizeof(KM_KeyId), (KM_Data**) out);
}
-int KM_ParamsDeserializeKeyId(SymmetricInput *self, KeyId **out)
+int KM_ParamsDeserializePwdData(KM_SymmetricInput *self, KM_PwdData **out)
{
- return KM_ParamsDeserializeData((void *)self, self->key_id_data_offset, PSMagic_KeyId,
- sizeof(KeyId), (Data**) out);
+ uint8_t *curr_ptr = 0;
+ KM_PwdData *ptr = NULL;
+ if (NULL == self || NULL == out) {
+ LOG("Invalid input.");
+ return -1;
+ }
+
+ if (self->pwd_data_offset == 0) {
+ // There's no data so we return gently
+ *out = NULL;
+ return 0;
+ }
+
+ curr_ptr = ((uint8_t *)self) + self->pwd_data_offset;
+ ptr = (KM_PwdData *)curr_ptr;
+
+ if (ptr->magic != PSMagic_PwdData) {
+ LOG("Invalid magic.");
+ return -1;
+ }
+
+ curr_ptr += sizeof(KM_PwdData);
+ if (ptr->pwd_size > 0) {
+ ptr->pwd = (void *)curr_ptr;
+ } else {
+ ptr->pwd = NULL;
+ }
+
+ curr_ptr += ptr->pwd_size;
+ if (ptr->iv_size > 0) {
+ ptr->iv = (void *)curr_ptr;
+ } else {
+ ptr->iv = NULL;
+ }
+
+ curr_ptr += ptr->iv_size;
+ if (ptr->tag_size > 0) {
+ ptr->tag = (void *)curr_ptr;
+ } else {
+ ptr->tag = NULL;
+ }
+
+ *out = ptr;
+ return 0;
}
// SERIALIZATORS
-int KM_ParamsSerializationInit(void *buffer, size_t buffer_size, SymmetricInput **out)
+int KM_ParamsSerializationInit(void *buffer, size_t buffer_size, KM_SymmetricInput **out)
{
- SymmetricInput *self = (SymmetricInput *) buffer;
+ KM_SymmetricInput *self = (KM_SymmetricInput *)buffer;
if (buffer == NULL) {
LOG("Invalid input buffer");
return -1;
}
- if (sizeof(SymmetricInput) > buffer_size) {
+ if (sizeof(KM_SymmetricInput) > buffer_size) {
LOG("Serialization buffer not big enough");
return -1;
}
- memset(self, 0, sizeof(SymmetricInput));
+ memset(self, 0, sizeof(KM_SymmetricInput));
self->magic = PSMagic_SymmetricInput;
self->buffer_size = buffer_size;
- self->global_offset = sizeof(SymmetricInput);
+ self->global_offset = sizeof(KM_SymmetricInput);
*out = self;
return 0;
}
-int KM_ParamsSerializeInputData(SymmetricInput *self, const void *data, size_t data_size)
+int KM_ParamsSerializeInputData(KM_SymmetricInput *self, const void *data, size_t data_size)
{
- Data *ptr = NULL;
+ KM_Data *ptr = NULL;
uint32_t ret = 0;
- if (0 != self->input_data_offset) {
+
+ if (data_size == 0) {
+ return 0;
+ }
+
+ if (self->input_data_offset != 0) {
LOG("Invalid parameters. (data=%p|data_size=%d|self->input_data_offset=%d",
data, data_size, self->input_data_offset);
return -1;
}
- ret = KM_ParamsSerializeData(self, data, data_size, sizeof(InputData),
+ ret = KM_ParamsSerializeData(self, data, data_size, sizeof(KM_InputData),
PSMagic_InputData, &ptr);
if (ret != 0) {
return ret;
}
self->input_data_offset = self->global_offset;
- self->global_offset += sizeof(InputData) + addAlignment(data_size);
+ self->global_offset += sizeof(KM_InputData) + addAlignment(data_size);
return 0;
}
-int KM_ParamsSerializeIVData(SymmetricInput *self, const void *data, size_t data_size)
+int KM_ParamsSerializeIVData(KM_SymmetricInput *self, const void *data, size_t data_size)
{
- Data *ptr = NULL;
+ KM_Data *ptr = NULL;
uint32_t ret = 0;
- if (0 != self->iv_data_offset) {
+
+ if (data_size == 0) {
+ return 0;
+ }
+
+ if (self->iv_data_offset != 0) {
LOG("Invalid parameters. (data=%p|data_size=%d|self->iv_data_offset=%d",
data, data_size, self->iv_data_offset);
return -1;
}
- ret = KM_ParamsSerializeData(self, data, data_size, sizeof(IVData), PSMagic_IVData,
+ ret = KM_ParamsSerializeData(self, data, data_size, sizeof(KM_IVData), PSMagic_IVData,
&ptr);
if (ret != 0) {
return ret;
}
self->iv_data_offset = self->global_offset;
- self->global_offset += sizeof(IVData) + addAlignment(data_size);
+ self->global_offset += sizeof(KM_IVData) + addAlignment(data_size);
return 0;
}
-int KM_ParamsSerializeAEData(SymmetricInput *self, uint32_t tagLen, uint32_t payloadLen,
+int KM_ParamsSerializeAEData(KM_SymmetricInput *self, uint32_t tagLen, uint32_t payloadLen,
const void *aad, uint32_t aad_size)
{
- AEData *ptr = NULL;
+ KM_AEData *ptr = NULL;
uint32_t ret = 0;
- if (0 != self->ae_data_offset) {
+
+ if (self->ae_data_offset != 0) {
LOG("Invalid parameters. (self->ae_data_offset=%d", self->ae_data_offset);
return -1;
}
- ret = KM_ParamsSerializeData(self, aad, aad_size, sizeof(AEData), PSMagic_AEData,
- (Data **) &ptr);
+ ret = KM_ParamsSerializeData(self, aad, aad_size, sizeof(KM_AEData), PSMagic_AEData,
+ (KM_Data **) &ptr);
if (ret != 0) {
return ret;
}
- ptr->tagLen = tagLen;
- ptr->payloadLen = payloadLen;
+ ptr->tag_len = tagLen;
+ ptr->payload_len = payloadLen;
self->ae_data_offset = self->global_offset;
- self->global_offset += sizeof(AEData) + addAlignment(aad_size);
+ self->global_offset += sizeof(KM_AEData) + addAlignment(aad_size);
return 0;
}
-int KM_ParamsSerializeOutData(SymmetricInput *self, const void *data, size_t data_size)
+int KM_ParamsSerializeOutData(KM_SymmetricInput *self, const void *data, size_t data_size)
{
- Data *ptr = NULL;
+ KM_Data *ptr = NULL;
uint32_t ret = 0;
- if (0 != self->out_data_offset) {
+
+ if (data_size == 0) {
+ return 0;
+ }
+
+ if (self->out_data_offset != 0) {
LOG("Invalid parameters. (data=%p|data_size=%d|self->out_data_offset=%d",
data, data_size, self->out_data_offset);
return -1;
}
- ret = KM_ParamsSerializeData(self, data, data_size, sizeof(OutData), PSMagic_OutData,
+ ret = KM_ParamsSerializeData(self, data, data_size, sizeof(KM_OutData), PSMagic_OutData,
&ptr);
if (ret != 0) {
return ret;
}
self->out_data_offset = self->global_offset;
- self->global_offset += sizeof(OutData) + addAlignment(data_size);
+ self->global_offset += sizeof(KM_OutData) + addAlignment(data_size);
return 0;
}
-int KM_ParamsSerializeTagData(SymmetricInput *self, const void *data, size_t data_size)
+int KM_ParamsSerializeTagData(KM_SymmetricInput *self, const void *data, size_t data_size)
{
- Data *ptr = NULL;
+ KM_Data *ptr = NULL;
uint32_t ret = 0;
- if (0 != self->tag_data_offset) {
+
+ if (data_size == 0) {
+ return 0;
+ }
+
+ if (self->tag_data_offset != 0) {
LOG("Invalid parameters. (data=%p|data_size=%d|self->tag_data_offset=%d",
data, data_size, self->tag_data_offset);
return -1;
}
- ret = KM_ParamsSerializeData(self, data, data_size, sizeof(TagData), PSMagic_TagData,
+ ret = KM_ParamsSerializeData(self, data, data_size, sizeof(KM_TagData), PSMagic_TagData,
&ptr);
if (ret != 0) {
return ret;
}
self->tag_data_offset = self->global_offset;
- self->global_offset += sizeof(TagData) + addAlignment(data_size);
+ self->global_offset += sizeof(KM_TagData) + addAlignment(data_size);
return 0;
}
-int KM_ParamsSerializeKey(SymmetricInput *self, const void *data, size_t data_size,
- uint32_t bits_size)
+int KM_ParamsSerializeKeyId(KM_SymmetricInput *self, const void *data, size_t data_size)
{
- Key *ptr = NULL;
+ KM_KeyId *ptr = NULL;
uint32_t ret = 0;
- if (0 != self->key_data_offset) {
+
+ if (data_size == 0) {
+ return 0;
+ }
+
+ if (self->key_id_data_offset != 0) {
LOG("Invalid parameters. (data=%p|data_size=%d|self->key_data_offset=%d",
- data, data_size, self->key_data_offset);
+ data, data_size, self->key_id_data_offset);
return -1;
}
- ret = KM_ParamsSerializeData(self, data, data_size, sizeof(Key), PSMagic_Key,
- (Data **) &ptr);
+ ret = KM_ParamsSerializeData(self, data, data_size, sizeof(KM_KeyId), PSMagic_KeyId, &ptr);
if (ret != 0) {
return ret;
}
- ptr->key_bits_size = bits_size;
- self->key_data_offset = self->global_offset;
- self->global_offset += sizeof(Key) + addAlignment(data_size);
+ self->key_id_data_offset = self->global_offset;
+ self->global_offset += sizeof(KM_KeyId) + addAlignment(data_size);
return 0;
}
-int KM_ParamsSerializeKeyId(SymmetricInput *self, const void *data, size_t data_size)
+int KM_ParamsSerializePwdData(KM_SymmetricInput *self, const void *pwd, uint32_t pwd_size,
+ const void *iv, uint32_t iv_size, const void *tag, uint32_t tag_size,
+ uint32_t derive_len_bits, uint32_t it_count, uint32_t tag_len_bits)
{
- KeyId *ptr = NULL;
- uint32_t ret = 0;
- if (0 != self->key_id_data_offset) {
- LOG("Invalid parameters. (data=%p|data_size=%d|self->key_data_offset=%d",
- data, data_size, self->key_id_data_offset);
+ KM_PwdData *ptr = NULL;
+ uint8_t* curr_ptr = 0;
+ uint32_t pwd_data_total_size = 0;
+
+ if (pwd_size == 0) {
+ return 0;
+ }
+
+ if (self->pwd_data_offset != 0) {
+ LOG("Buffer already contains pwd data");
return -1;
}
- ret = KM_ParamsSerializeData(self, data, data_size, sizeof(KeyId), PSMagic_KeyId, &ptr);
- if (ret != 0) {
- return ret;
+
+ if (self->buffer_size <
+ self->global_offset + sizeof(KM_PwdData) + pwd_size + iv_size + tag_size) {
+ LOG("Not enough space for data. (self->buffer_size < data_size = %d < %d)",
+ self->buffer_size, self->global_offset + sizeof(KM_PwdData) + pwd_size + iv_size + tag_size);
+ return -1;
}
- self->key_id_data_offset = self->global_offset;
- self->global_offset += sizeof(KeyId) + addAlignment(data_size);
+ curr_ptr = ((uint8_t *)self) + self->global_offset;
+ ptr = (KM_PwdData *)curr_ptr;
+ ptr->magic = PSMagic_PwdData;
+ ptr->pwd_size = pwd_size;
+ ptr->iv_size = iv_size;
+ ptr->tag_size = tag_size;
+ ptr->derive_len_bits = derive_len_bits;
+ ptr->it_count = it_count;
+ ptr->tag_len_bits = tag_len_bits;
+
+ curr_ptr += sizeof(KM_PwdData);
+ pwd_data_total_size += sizeof(KM_PwdData);
+ if (pwd_size > 0) {
+ ptr->pwd = (void *)(curr_ptr);
+ memcpy(ptr->pwd, pwd, pwd_size);
+ } else {
+ ptr->pwd = NULL;
+ }
+
+ curr_ptr += pwd_size;
+ pwd_data_total_size += pwd_size;
+ if (iv_size > 0) {
+ ptr->iv = (void *)(curr_ptr);
+ memcpy(ptr->iv, iv, iv_size);
+ } else {
+ ptr->iv = NULL;
+ }
+
+ curr_ptr += iv_size;
+ pwd_data_total_size += iv_size;
+ if (tag_size > 0) {
+ ptr->tag = (void *)(curr_ptr);
+ memcpy(ptr->tag, tag, tag_size);
+ } else {
+ ptr->tag = NULL;
+ }
+
+ pwd_data_total_size += tag_size;
+
+ self->pwd_data_offset = self->global_offset;
+ self->global_offset += addAlignment(pwd_data_total_size);
return 0;
}
TEE_Result KM_ExecCmdVerify(TEE_Param param[4]);
+TEE_Result KM_ExecCmdDestroyKey(TEE_Param param[4]);
+
#endif // __CMD_EXEC_H__
\ No newline at end of file
#include <tee_internal_api.h>
-TEE_Result KM_AuthEncrypt(TEE_OperationHandle hndl, void *iv, uint32_t iv_size, uint32_t tagLen,
- uint32_t payloadLen, void *data, uint32_t data_size,
+TEE_Result KM_AuthEncrypt(TEE_OperationHandle hndl, void *iv, uint32_t iv_size, uint32_t tag_len_bits,
+ uint32_t payload_len_bits, void *data, uint32_t data_size,
void *aad, uint32_t aad_size, void *out, uint32_t *out_size,
void *tag, uint32_t *tag_size);
-TEE_Result KM_AuthDecrypt(TEE_OperationHandle hndl, void *iv, uint32_t iv_size, uint32_t tagLen,
- uint32_t payloadLen, void *data, uint32_t data_size,
+TEE_Result KM_AuthDecrypt(TEE_OperationHandle hndl, void *iv, uint32_t iv_size, uint32_t tag_len_bits,
+ uint32_t payload_len_bits, void *data, uint32_t data_size,
void *aad, uint32_t aad_size, void *tag, uint32_t tag_size,
void *out, uint32_t *out_size);
#endif // __CRYPTO_AUTH_H__
#include <tee_internal_api.h>
// separate function for AES CFB - not supported by pure GP API
-TEE_Result KM_SymmetricCrypt_AES_CFB(void *key_id, uint32_t key_id_size, uint32_t mode,
+TEE_Result KM_SymmetricCrypt_AES_CFB(TEE_ObjectHandle key, uint32_t mode,
void *iv, uint32_t iv_size, void *input, uint32_t input_size,
void *output, uint32_t *output_size);
#define __INTERNAL_H__
#include <tee_internal_api.h>
+#include <km_serialization.h>
-int KM_CheckAESMode(uint32_t algo, uint32_t tagLen);
+int KM_CheckAuthAESMode(uint32_t algo, uint32_t tagLen);
TEE_Result KM_CreateKey(uint32_t tee_key_type, uint32_t key_bits_size, void *key, size_t key_size,
TEE_ObjectHandle *hndl);
TEE_Result KM_CreateRandomKey(uint32_t tee_key_type, uint32_t key_bits_size, TEE_ObjectHandle *hndl);
-TEE_Result KM_CreateOperation(TEE_ObjectHandle op_key_hndl, uint32_t algo, uint32_t mode,
- uint32_t key_bits_size, TEE_OperationHandle *hndl);
+TEE_Result KM_EncryptKey(TEE_ObjectHandle keyHndl, KM_PwdData *pwd, TEE_ObjectHandle *encKeyHndl,
+ void *tag, uint32_t *tag_size);
+
+TEE_Result KM_DecryptKey(void *id, size_t id_size, KM_PwdData* pwd, TEE_ObjectHandle *decKeyHndl);
+
+TEE_Result KM_CreateOperation(TEE_ObjectHandle op_key_hndl, uint32_t algo,
+ uint32_t mode, TEE_OperationHandle *hndl);
TEE_Result KM_CreateOperationWithKey(void *key, uint32_t key_size, uint32_t type, uint32_t mode,
- uint32_t algo, uint32_t key_bits_size,
- TEE_OperationHandle *oper_hndl);
+ uint32_t algo, uint32_t key_bits_size,
+ TEE_OperationHandle *oper_hndl);
TEE_Result KM_CreateOperationWithKeyId(void *key_id, uint32_t key_id_size, uint32_t mode,
uint32_t algo, TEE_OperationHandle *oper_hndl);
TEE_Result KM_ImportKey(TEE_ObjectHandle hndl, uint32_t tee_key_type, void *buffer,
size_t *buffer_size);
+void KM_DestroyKey(void *objId, size_t objId_size);
+
void KM_GenerateIV(void *iv, size_t iv_size);
#endif // __INTERNAL_H__
CMD_VERIFY,
CMD_GENERATE_IV,
CMD_GENERATE_KEY_PWD,
+ CMD_DESTROY_KEY,
} tz_command;
typedef enum {
}
}
-static TEE_Result KM_DeserializeInput(void* buffer, uint32_t buffer_size, SymmetricInput **input,
- InputData **input_data, IVData **iv_data,
- KeyId **key_id_data, Key **key_data,
- AEData **ae_data, TagData **tag_data)
+static TEE_Result KM_DeserializeInput(void* buffer, uint32_t buffer_size, KM_SymmetricInput **input,
+ KM_InputData **input_data, KM_PwdData **pwd_data, KM_IVData **iv_data,
+ KM_KeyId **key_id_data, KM_AEData **ae_data, KM_TagData **tag_data)
{
if (buffer == NULL) {
LOG("Provided invalid buffer for deserialization");
return TEE_ERROR_BAD_PARAMETERS;
}
- if (input_data == NULL) {
- LOG("Invalid input buffer deserialization structure");
- return TEE_ERROR_BAD_PARAMETERS;
+ if (input_data != NULL) {
+ if (KM_ParamsDeserializeInputData(*input, input_data) != 0) {
+ LOG("Failed to deserialize input data");
+ return TEE_ERROR_BAD_PARAMETERS;
+ }
}
- if (KM_ParamsDeserializeInputData(*input, input_data) != 0) {
- LOG("Failed to deserialize input data");
- return TEE_ERROR_BAD_PARAMETERS;
+ if (pwd_data != NULL) {
+ if (KM_ParamsDeserializePwdData(*input, pwd_data) != 0) {
+ LOG("Failed to deserialize password data");
+ return TEE_ERROR_BAD_PARAMETERS;
+ }
}
if (iv_data != NULL) {
}
}
- if (key_data != NULL) {
- if (KM_ParamsDeserializeKey(*input, key_data) != 0) {
- LOG("Failed to deserialize key data");
- return TEE_ERROR_BAD_PARAMETERS;
- }
- }
-
if (ae_data != NULL) {
if (KM_ParamsDeserializeAEData(*input, ae_data) != 0) {
LOG("Failed to deserialize AE data");
}
}
- if (*input_data == NULL) {
- LOG("No InputData in input buffer");
- return TEE_ERROR_BAD_PARAMETERS;
- }
-
- if (key_data != NULL && key_id_data != NULL) {
- if (((*key_data) != NULL && (*key_id_data) != NULL) ||
- ((*key_data) == NULL && (*key_id_data) == NULL)) {
- LOG("You need to specify key or keyId. At least one and only one.");
- return TEE_ERROR_BAD_PARAMETERS;
- }
- }
-
return TEE_SUCCESS;
}
{
TEE_Result ret = TEE_SUCCESS;
TEE_ObjectHandle hndl = TEE_HANDLE_NULL;
- SymmetricInput *input = NULL;
+ KM_SymmetricInput *input = NULL;
uint32_t type = KM_AlgoType2TeeType(param[0].value.a);
uint32_t key_bits_size = param[0].value.b;
TEE_GenerateRandom(objId, objId_size);
if (0 != KM_ParamsSerializationInit(param[1].memref.buffer, param[1].memref.size,
- &input) || 0 != KM_ParamsSerializeKeyId(input, objId, objId_size)) {
+ &input) || 0 != KM_ParamsSerializeOutData(input, objId, objId_size)) {
LOG("Failed to serialize key to output buffer");
ret = TEE_ERROR_BAD_PARAMETERS;
goto clean;
TEE_Result KM_ExecCmdGenerateKeyPwd(TEE_Param param[4])
{
TEE_Result ret = TEE_SUCCESS;
- TEE_ObjectHandle derivedKey = TEE_HANDLE_NULL;
- SymmetricInput *input = NULL;
- InputData *input_data = NULL;
- IVData *iv_data = NULL;
+ TEE_ObjectHandle key = TEE_HANDLE_NULL;
+ KM_SymmetricInput *input = NULL;
+ KM_PwdData *pwd_data = NULL;
+ uint32_t type = KM_AlgoType2TeeType(param[0].value.a);
uint32_t key_bits_size = param[0].value.b;
+ uint32_t tag_size = 0;
+ void *tag = NULL;
uint32_t objId_size = TEE_OBJECT_ID_MAX_LEN;
uint32_t *objId = (uint32_t*)malloc(objId_size);
if (objId == NULL) {
}
ret = KM_DeserializeInput(param[1].memref.buffer, param[1].memref.size,
- &input, &input_data, &iv_data, NULL, NULL, NULL, NULL);
+ &input, NULL, &pwd_data, NULL, NULL, NULL, NULL);
if (ret != TEE_SUCCESS) {
LOG("Failed to deserialize data from input buffer");
ret = TEE_ERROR_BAD_PARAMETERS;
goto clean;
}
+ // Tag will be generated during encryption, so we don't check for it
+ if (pwd_data == NULL || pwd_data->pwd == NULL || pwd_data->iv == NULL) {
+ LOG("To generate a key with password, a password and IV are required.");
+ ret = TEE_ERROR_BAD_PARAMETERS;
+ goto clean;
+ }
- ret = KM_DeriveKey(input_data->data, input_data->data_size, iv_data->data, iv_data->data_size,
- PBKDF2_ITERATIONS, TEE_TYPE_AES, key_bits_size, &derivedKey);
- if (ret != TEE_SUCCESS) {
- LOG("Failed to derive key: %x", ret);
+ tag_size = pwd_data->tag_len_bits / 8;
+ tag = malloc(tag_size);
+ if (tag == NULL) {
+ LOG("Failed to allocate memory for key's tag");
+ ret = TEE_ERROR_OUT_OF_MEMORY;
+ goto clean;
+ }
+
+ ret = KM_CreateRandomKey(type, key_bits_size, &key);
+ if (TEE_SUCCESS != ret) {
+ LOG("Failed to randomize new key");
+ goto clean;
+ }
+
+ ret = KM_EncryptKey(key, pwd_data, &key, tag, &tag_size);
+ if (TEE_SUCCESS != ret) {
+ LOG("Failed to encrypt new key");
goto clean;
}
- // ObjectID generation
TEE_GenerateRandom(objId, objId_size);
- if (KM_ParamsSerializationInit(param[2].memref.buffer, param[2].memref.size,
- &input) != 0 || KM_ParamsSerializeKeyId(input, objId, objId_size) != 0) {
+ if (KM_ParamsSerializationInit(param[2].memref.buffer, param[2].memref.size, &input) != 0 ||
+ KM_ParamsSerializeOutData(input, objId, objId_size) != 0 ||
+ KM_ParamsSerializeTagData(input, tag, tag_size) != 0) {
LOG("Failed to serialize output data");
ret = TEE_ERROR_BAD_PARAMETERS;
goto clean;
}
- ret = KM_SaveKey(NULL, 0, derivedKey, objId, objId_size);
+ ret = KM_SaveKey(NULL, 0, key, objId, objId_size);
if (ret != TEE_SUCCESS) {
- LOG("Failed to save derived key: %x", ret);
+ LOG("Failed to save generated encrypted key: %x", ret);
goto clean;
}
clean:
- TEE_FreeTransientObject(derivedKey);
+ TEE_FreeTransientObject(key);
+ free(tag);
free(objId);
return ret;
}
TEE_Result KM_ExecCmdImportKey(TEE_Param param[4])
{
TEE_Result ret = TEE_SUCCESS;
- TEE_ObjectHandle hndl = TEE_HANDLE_NULL;
- SymmetricInput *input = NULL;
- InputData* inKey = NULL;
- SymmetricInput *output = NULL;
+ TEE_ObjectHandle key = TEE_HANDLE_NULL;
+ TEE_ObjectHandle oldKey = TEE_HANDLE_NULL;
+ KM_SymmetricInput *input = NULL;
+ KM_SymmetricInput *output = NULL;
+ KM_InputData *input_data = NULL;
+ KM_PwdData *pwd_data = NULL;
uint32_t type = KM_AlgoType2TeeType(param[0].value.a);
uint32_t key_bits_size = param[0].value.b;
+ uint32_t tag_size = 0;
+ void *tag = NULL;
uint32_t objId_size = KM_KEY_ID_SIZE;
uint32_t *objId = (uint32_t*)malloc(objId_size);
-
if (objId == NULL) {
LOG("Failed to allocate object ID buffer");
ret = TEE_ERROR_OUT_OF_MEMORY;
}
ret = KM_DeserializeInput(param[1].memref.buffer, param[1].memref.size,
- &input, &inKey, NULL, NULL, NULL, NULL, NULL);
+ &input, &input_data, &pwd_data, NULL, NULL, NULL, NULL);
if (ret != TEE_SUCCESS) {
LOG("Failed to deserialize data from input buffer");
ret = TEE_ERROR_BAD_PARAMETERS;
goto clean;
}
- ret = KM_CreateKey(type, key_bits_size, inKey->data, inKey->data_size, &hndl);
+ ret = KM_CreateKey(type, key_bits_size, input_data->data, input_data->data_size, &key);
if (ret != TEE_SUCCESS) {
LOG("Failed to create key");
goto clean;
}
- // ObjectID generation
+ if (pwd_data != NULL) {
+ oldKey = key;
+
+ tag_size = pwd_data->tag_len_bits / 8;
+ tag = malloc(tag_size);
+ if (tag == NULL) {
+ LOG("Failed to allocate memory for key's tag");
+ ret = TEE_ERROR_OUT_OF_MEMORY;
+ goto clean;
+ }
+
+ ret = KM_EncryptKey(key, pwd_data, &key, tag, &tag_size);
+ if (TEE_SUCCESS != ret) {
+ LOG("Failed to encrypt new key");
+ goto clean;
+ }
+ }
+
TEE_GenerateRandom(objId, objId_size);
- if (0 != KM_ParamsSerializationInit(param[2].memref.buffer, param[2].memref.size,
- &output) || 0 != KM_ParamsSerializeKeyId(output, objId, objId_size)) {
+ if (KM_ParamsSerializationInit(param[2].memref.buffer, param[2].memref.size, &output) != 0 ||
+ KM_ParamsSerializeOutData(output, objId, objId_size) != 0) {
LOG("Failed to serialize key to output buffer");
ret = TEE_ERROR_BAD_PARAMETERS;
goto clean;
}
- ret = KM_SaveKey(NULL, 0, hndl, objId, objId_size);
+ if (tag != NULL) {
+ if (KM_ParamsSerializeTagData(output, tag, tag_size) != 0) {
+ LOG("Failed to serialize key's tag to output buffer");
+ ret = TEE_ERROR_BAD_PARAMETERS;
+ goto clean;
+ }
+ }
+
+ ret = KM_SaveKey(NULL, 0, key, objId, objId_size);
if (TEE_SUCCESS != ret) {
LOG("Failed to save generated key");
goto clean;
}
clean:
- TEE_FreeTransientObject(hndl);
+ TEE_CloseObject(oldKey);
+ TEE_CloseObject(key);
free(objId);
+ free(tag);
return ret;
}
TEE_Result KM_ExecCmdSymmetric(uint32_t commandID, TEE_Param param[4])
{
TEE_Result ret = TEE_SUCCESS;
+ TEE_ObjectHandle key = TEE_HANDLE_NULL;
TEE_OperationHandle operation = TEE_HANDLE_NULL;
- SymmetricInput *input = NULL;
- SymmetricInput *output = NULL;
- InputData *input_data = NULL;
- IVData *iv_data = NULL;
- KeyId *key_id_data = NULL;
- Key *key_data = NULL;
+ KM_SymmetricInput *input = NULL;
+ KM_SymmetricInput *output = NULL;
+ KM_InputData *input_data = NULL;
+ KM_PwdData *pwd_data = NULL;
+ KM_IVData *iv_data = NULL;
+ KM_KeyId *key_id_data = NULL;
void *in_padded = NULL;
uint32_t in_padded_size = 0;
void *out = NULL;
uint32_t out_size = 0;
- uint32_t type = 0;
uint32_t algo = KM_Algo2TeeAlgo(param[0].value.a);
uint32_t mode = KM_Cmd2TeeMode(commandID);
}
ret = KM_DeserializeInput(param[1].memref.buffer, param[1].memref.size,
- &input, &input_data, &iv_data, &key_id_data,
- &key_data, NULL, NULL);
+ &input, &input_data, &pwd_data, &iv_data,
+ &key_id_data, NULL, NULL);
if (ret != TEE_SUCCESS) {
LOG("Failed to deserialize data from input buffer");
return TEE_ERROR_BAD_PARAMETERS;
}
+ if (pwd_data != NULL) {
+ if (pwd_data->pwd == NULL || pwd_data->iv == NULL || pwd_data->tag == NULL) {
+ LOG("Not enough data to successfully decrypt key");
+ ret = TEE_ERROR_BAD_PARAMETERS;
+ goto clean;
+ }
+ }
+
out_size = KM_CalculatePaddedSize(KM_PADDING_PKCS7, AES_BLOCK_SIZE, input_data->data_size);
out = malloc(out_size);
if (out == NULL) {
}
// GCM and CTR modes does not need to be padded
- if (CMD_ENCRYPT == commandID &&
- TEE_ALG_AES_GCM != algo && TEE_ALG_AES_CTR_NOPAD != algo) {
+ if (commandID == CMD_ENCRYPT &&
+ algo != TEE_ALG_AES_GCM &&
+ algo != TEE_ALG_AES_CTR_NOPAD) {
in_padded_size = out_size;
in_padded = malloc(in_padded_size);
if (in_padded == NULL) {
goto clean;
}
- if (KM_PadBuffer(PADDING_MODE, AES_BLOCK_SIZE, input_data->data, input_data->data_size,
- in_padded, &in_padded_size)) {
+ if (KM_PadBuffer(PADDING_MODE, AES_BLOCK_SIZE, input_data->data,
+ input_data->data_size, in_padded, &in_padded_size)) {
LOG("Error during padding operation");
ret = TEE_ERROR_GENERIC;
goto clean;
}
}
+ // open key and (if needed) decrypt it
+ if (pwd_data != NULL) {
+ ret = KM_DecryptKey(key_id_data->data, key_id_data->data_size, pwd_data, &key);
+ } else {
+ ret = KM_OpenKey(key_id_data->data, key_id_data->data_size, NULL, &key);
+ }
+
+ if (ret != TEE_SUCCESS) {
+ LOG("Failed to acquire key for crypto operation: %x", ret);
+ goto clean;
+ }
+
if (algo == KM_TA_ALG_AES_CFB) {
if (CMD_ENCRYPT == commandID) {
- ret = KM_SymmetricCrypt_AES_CFB(key_id_data->data, key_id_data->data_size, mode,
- iv_data->data, iv_data->data_size,
+ ret = KM_SymmetricCrypt_AES_CFB(key, mode, iv_data->data, iv_data->data_size,
in_padded, in_padded_size, out, &out_size);
} else {
- ret = KM_SymmetricCrypt_AES_CFB(key_id_data->data, key_id_data->data_size, mode,
- iv_data->data, iv_data->data_size,
+ ret = KM_SymmetricCrypt_AES_CFB(key, mode, iv_data->data, iv_data->data_size,
input_data->data, input_data->data_size, out, &out_size);
}
} else {
- if (key_id_data) {
- ret = KM_CreateOperationWithKeyId(key_id_data->data, key_id_data->data_size, mode, algo, &operation);
- } else if (key_data) {
- type = KM_AlgoType2TeeType(param[0].value.a);
- ret = KM_CreateOperationWithKey(key_data->key.data, key_data->key.data_size, type, mode,
- algo, key_data->key_bits_size, &operation);
- }
-
+ ret = KM_CreateOperation(key, algo, mode, &operation);
if (TEE_SUCCESS != ret) {
goto clean;
}
- if (CMD_ENCRYPT == commandID && TEE_ALG_AES_GCM != algo && TEE_ALG_AES_CTR_NOPAD != algo) {
+ if (commandID == CMD_ENCRYPT &&
+ algo != TEE_ALG_AES_GCM &&
+ algo != TEE_ALG_AES_CTR_NOPAD) {
ret = KM_SymmetricCrypt(operation, iv_data->data, iv_data->data_size,
in_padded, in_padded_size, out, &out_size);
} else {
}
}
- LOGD("Serializing output");
if (0 != KM_ParamsSerializationInit(param[2].memref.buffer, param[2].memref.size, &output)
|| 0 != KM_ParamsSerializeOutData(output, out, out_size)) {
ret = TEE_ERROR_BAD_PARAMETERS;
goto clean;
}
- LOGD("Done serializing output");
-
clean:
free(in_padded);
free(out);
+ TEE_CloseObject(key);
if (operation != TEE_HANDLE_NULL) TEE_FreeOperation(operation);
return ret;
}
TEE_Result KM_ExecCmdAuth(uint32_t commandID, TEE_Param param[4])
{
TEE_Result ret = TEE_SUCCESS;
- TEE_OperationHandle hndl = TEE_HANDLE_NULL;
- SymmetricInput *input = NULL;
- InputData *input_data = NULL;
- IVData *iv_data = NULL;
- KeyId *key_id_data = NULL;
- Key *key_data = NULL;
- AEData *ae_data = NULL;
- TagData *tag_data = NULL;
+ TEE_ObjectHandle key = TEE_HANDLE_NULL;
+ TEE_OperationHandle op = TEE_HANDLE_NULL;
+ KM_SymmetricInput *input = NULL;
+ KM_InputData *input_data = NULL;
+ KM_PwdData *pwd_data = NULL;
+ KM_IVData *iv_data = NULL;
+ KM_KeyId *key_id_data = NULL;
+ KM_AEData *ae_data = NULL;
+ KM_TagData *tag_data = NULL;
void *out = NULL;
uint32_t out_size = 0;
void *tag = NULL;
uint32_t tag_size = 0;
- uint32_t type = 0;
uint32_t algo = KM_Algo2TeeAlgo(param[0].value.a);
uint32_t mode = KM_Cmd2TeeMode(commandID);
}
ret = KM_DeserializeInput(param[1].memref.buffer, param[1].memref.size,
- &input, &input_data, &iv_data, &key_id_data,
- &key_data, &ae_data, &tag_data);
+ &input, &input_data, &pwd_data, &iv_data,
+ &key_id_data, &ae_data, &tag_data);
if (ret != TEE_SUCCESS) {
LOG("Failed to deserialize data from input buffer");
return TEE_ERROR_BAD_PARAMETERS;
}
+ if (pwd_data != NULL) {
+ if (pwd_data->pwd == NULL || pwd_data->iv == NULL || pwd_data->tag == NULL) {
+ LOG("Not enough data to successfully decrypt key");
+ ret = TEE_ERROR_BAD_PARAMETERS;
+ goto clean;
+ }
+ }
+
if (commandID == CMD_DECRYPT && !tag_data) {
LOG("Tag data is needed for verification");
return TEE_ERROR_BAD_PARAMETERS;
}
- if (!KM_CheckAESMode(algo, ae_data->tagLen)) {
- LOG("Tag has invalid length. (tagLen=%d)", ae_data->tagLen);
+ if (!KM_CheckAuthAESMode(algo, ae_data->tag_len)) {
+ LOG("Tag has invalid length. (tagLen=%d)", ae_data->tag_len);
return TEE_ERROR_BAD_PARAMETERS;
}
- if (key_id_data) {
- ret = KM_CreateOperationWithKeyId(key_id_data->data, key_id_data->data_size, mode, algo,
- &hndl);
- } else if (key_data) {
- type = KM_AlgoType2TeeType(param[0].value.a);
- ret = KM_CreateOperationWithKey(key_data->key.data, key_data->key.data_size, type, mode,
- algo, key_data->key_bits_size, &hndl);
+ // open key and (if needed) decrypt it
+ if (pwd_data != NULL) {
+ ret = KM_DecryptKey(key_id_data->data, key_id_data->data_size, pwd_data, &key);
+ } else {
+ ret = KM_OpenKey(key_id_data->data, key_id_data->data_size, NULL, &key);
}
if (TEE_SUCCESS != ret) {
goto clean;
out_size = KM_CalculatePaddedSize(KM_PADDING_PKCS7, AES_BLOCK_SIZE, input_data->data_size);
out = malloc(out_size);
+ ret = KM_CreateOperation(key, algo, mode, &op);
+ if (TEE_SUCCESS != ret) {
+ LOG("Failed to create auth crypto operation: %x", ret);
+ goto clean;
+ }
+
if (CMD_ENCRYPT == commandID) {
- tag_size = ae_data->tagLen / 8; // convert tag size to bytes
+ tag_size = ae_data->tag_len / 8; // convert tag size to bytes
tag = malloc(tag_size);
if (tag == NULL) {
LOG("Failed to allocate tag buffer");
ret = TEE_ERROR_OUT_OF_MEMORY;
goto clean;
}
- ret = KM_AuthEncrypt(hndl, iv_data->data, iv_data->data_size, ae_data->tagLen,
- ae_data->payloadLen, input_data->data,
+
+ ret = KM_AuthEncrypt(op, iv_data->data, iv_data->data_size, ae_data->tag_len,
+ ae_data->payload_len, input_data->data,
input_data->data_size, ae_data->aad.data,
ae_data->aad.data_size, out, &out_size, tag, &tag_size);
} else {
- ret = KM_AuthDecrypt(hndl, iv_data->data, iv_data->data_size, ae_data->tagLen,
- ae_data->payloadLen, input_data->data,
+ ret = KM_AuthDecrypt(op, iv_data->data, iv_data->data_size, ae_data->tag_len,
+ ae_data->payload_len, input_data->data,
input_data->data_size, ae_data->aad.data,
ae_data->aad.data_size, tag_data->data, tag_data->data_size,
out, &out_size);
}
}
+ LOG("Crypto auth finished");
clean:
free(out);
free(tag);
- if (hndl != TEE_HANDLE_NULL) TEE_FreeOperation(hndl);
+ TEE_CloseObject(key);
+ if (op != TEE_HANDLE_NULL) TEE_FreeOperation(op);
return ret;
}
{
TEE_Result ret = TEE_SUCCESS;
TEE_OperationHandle operation = TEE_HANDLE_NULL;
- SymmetricInput *input = NULL;
- InputData *input_data = NULL;
- KeyId *key_id_data = NULL;
- Key *key_data = NULL;
+ KM_SymmetricInput *input = NULL;
+ KM_InputData *input_data = NULL;
+ KM_KeyId *key_id_data = NULL;
void *out = NULL;
uint32_t out_size = RSA_BLOCK_SIZE;
- uint32_t type = 0;
uint32_t algo = KM_Algo2TeeAlgo(param[0].value.a);
uint32_t mode = KM_Cmd2TeeMode(commandID);
}
ret = KM_DeserializeInput(param[1].memref.buffer, param[1].memref.size,
- &input, &input_data, NULL, &key_id_data,
- &key_data, NULL, NULL);
+ &input, &input_data, NULL, NULL,
+ &key_id_data, NULL, NULL);
if (ret != TEE_SUCCESS) {
LOG("Failed to deserialize data from input buffer");
return TEE_ERROR_BAD_PARAMETERS;
}
- if (key_id_data) {
- ret = KM_CreateOperationWithKeyId(key_id_data->data, key_id_data->data_size, mode, algo,
- &operation);
- } else if (key_data) {
- type = KM_AlgoType2TeeType(param[0].value.a);
- ret = KM_CreateOperationWithKey(key_data->key.data, key_data->key.data_size, type, mode,
- algo, key_data->key_bits_size, &operation);
- }
+ ret = KM_CreateOperationWithKeyId(key_id_data->data, key_id_data->data_size,
+ mode, algo, &operation);
if (TEE_SUCCESS != ret) {
return ret;
}
TEE_Result ret = TEE_SUCCESS;
TEE_OperationHandle digestOperation = TEE_HANDLE_NULL;
TEE_OperationHandle operation = TEE_HANDLE_NULL;
- SymmetricInput *input = NULL;
- InputData *input_data = NULL;
- KeyId *key_id_data = NULL;
- Key *key_data = NULL;
+ KM_SymmetricInput *input = NULL;
+ KM_InputData *input_data = NULL;
+ KM_KeyId *key_id_data = NULL;
void *digest = NULL;
uint32_t digest_size = 0;
uint32_t out_size = 0;
uint32_t out_size_pad = 0;
- uint32_t type = 0;
uint32_t algo = KM_AlgoHash2SignVerifyAlgo(param[0].value.a, param[0].value.b);
if (algo == 0) {
return TEE_ERROR_BAD_PARAMETERS;
}
- if (0 != KM_ParamsDeserializationInit(param[1].memref.buffer, param[1].memref.size, &input)
- || 0 != KM_ParamsDeserializeInputData(input, &input_data)
- || 0 != KM_ParamsDeserializeKeyId(input, &key_id_data)
- || 0 != KM_ParamsDeserializeKey(input, &key_data)) {
+ ret = KM_DeserializeInput(param[1].memref.buffer, param[1].memref.size,
+ &input, &input_data, NULL, NULL,
+ &key_id_data, NULL, NULL);
+ if (ret != TEE_SUCCESS) {
+ LOG("Failed to deserialize data from input buffer");
return TEE_ERROR_BAD_PARAMETERS;
}
- KM_ParamsDump(input, input_data, NULL, key_data, key_id_data, NULL, NULL, NULL);
-
if (!input_data) {
LOG("There needs to be InputData!");
return TEE_ERROR_BAD_PARAMETERS;
}
- if ((NULL != key_data && NULL != key_id_data) || (NULL == key_data && NULL == key_id_data)) {
- LOG("You need to specify key or keyId. At least one and only one.");
- return TEE_ERROR_BAD_PARAMETERS;
- }
-
- if (key_id_data) {
- ret = KM_CreateOperationWithKeyId(key_id_data->data, key_id_data->data_size,
+ ret = KM_CreateOperationWithKeyId(key_id_data->data, key_id_data->data_size,
TEE_MODE_SIGN, algo, &operation);
- } else if (key_data) {
- type = KM_AlgoType2TeeType(param[0].value.a);
- ret = KM_CreateOperationWithKey(key_data->key.data, key_data->key.data_size, type,
- TEE_MODE_SIGN, algo, key_data->key_bits_size, &operation);
- }
ret = KM_CreateDigestOperation(KM_Hash2TeeAlgo(param[0].value.b), &digestOperation);
if (TEE_SUCCESS != ret) {
TEE_Result ret = TEE_ERROR_NOT_IMPLEMENTED;
TEE_OperationHandle digestOperation = TEE_HANDLE_NULL;
TEE_OperationHandle operation = TEE_HANDLE_NULL;
- SymmetricInput *input = NULL;
- InputData *input_data = NULL;
- IVData *iv_data = NULL;
- KeyId *key_id_data = NULL;
- Key *key_data = NULL;
+ KM_SymmetricInput *input = NULL;
+ KM_InputData *input_data = NULL;
+ KM_IVData *iv_data = NULL;
+ KM_KeyId *key_id_data = NULL;
void* digest = NULL;
uint32_t digest_size = 0;
-
- uint32_t type = 0;
uint32_t algo = KM_AlgoHash2SignVerifyAlgo(param[0].value.a, param[0].value.b);
if (algo == 0) {
return TEE_ERROR_BAD_PARAMETERS;
}
- if (0 != KM_ParamsDeserializationInit(param[1].memref.buffer, param[1].memref.size, &input)
- || 0 != KM_ParamsDeserializeInputData(input, &input_data)
- || 0 != KM_ParamsDeserializeIVData(input, &iv_data)
- || 0 != KM_ParamsDeserializeKeyId(input, &key_id_data)
- || 0 != KM_ParamsDeserializeKey(input, &key_data)) {
+ ret = KM_DeserializeInput(param[1].memref.buffer, param[1].memref.size,
+ &input, &input_data, NULL, NULL,
+ &key_id_data, NULL, NULL);
+ if (ret != TEE_SUCCESS) {
+ LOG("Failed to deserialize data from input buffer");
return TEE_ERROR_BAD_PARAMETERS;
}
- KM_ParamsDump(input, input_data, iv_data, key_data, key_id_data, NULL, NULL, NULL);
-
if (!input_data) {
LOG("There needs to be InputData!");
return TEE_ERROR_BAD_PARAMETERS;
}
- if ((NULL != key_data && NULL != key_id_data) || (NULL == key_data && NULL == key_id_data)) {
- LOG("You need to specify key or keyId. At least one and only one.");
- return TEE_ERROR_BAD_PARAMETERS;
- }
-
ret = KM_CreateDigestOperation(KM_Hash2TeeAlgo(param[0].value.b), &digestOperation);
if (TEE_SUCCESS != ret) {
LOG("Failed to create digest operation");
goto clean;
}
- if (key_id_data) {
- ret = KM_CreateOperationWithKeyId(key_id_data->data, key_id_data->data_size,
- TEE_MODE_VERIFY, algo, &operation);
- } else if (key_data) {
- type = KM_AlgoType2TeeType(param[0].value.a);
- ret = KM_CreateOperationWithKey(key_data->key.data, key_data->key.data_size, type,
- TEE_MODE_VERIFY, algo, key_data->key_bits_size, &operation);
- }
+ ret = KM_CreateOperationWithKeyId(key_id_data->data, key_id_data->data_size,
+ TEE_MODE_VERIFY, algo, &operation);
digest_size = KM_DigestSizeFromHash(param[0].value.b);
digest = malloc(digest_size);
if (operation != TEE_HANDLE_NULL) TEE_FreeOperation(operation);
return ret;
}
+
+TEE_Result KM_ExecCmdDestroyKey(TEE_Param param[4])
+{
+ TEE_Result ret = TEE_SUCCESS;
+ KM_SymmetricInput *input = NULL;
+ KM_InputData *input_data = NULL;
+
+ ret = KM_DeserializeInput(param[1].memref.buffer, param[1].memref.size,
+ &input, &input_data, NULL, NULL, NULL, NULL, NULL);
+ if (ret != TEE_SUCCESS) {
+ LOG("Failed to deserialize data from input buffer");
+ ret = TEE_ERROR_BAD_PARAMETERS;
+ goto clean;
+ }
+
+ KM_DestroyKey(input_data->data, input_data->data_size);
+
+clean:
+ return ret;
+}
#include <crypto_auth.h>
#include <log.h>
-TEE_Result KM_AuthEncrypt(TEE_OperationHandle hndl, void *iv, uint32_t iv_size, uint32_t tagLen,
- uint32_t payloadLen, void *data, uint32_t data_size,
+TEE_Result KM_AuthEncrypt(TEE_OperationHandle hndl, void *iv, uint32_t iv_size, uint32_t tag_len_bits,
+ uint32_t payload_len_bits, void *data, uint32_t data_size,
void *aad, uint32_t aad_size, void *out, uint32_t *out_size,
void *tag, uint32_t *tag_size)
{
return TEE_ERROR_NOT_SUPPORTED;
}
- ret = TEE_AEInit(hndl, iv, (size_t) iv_size, tagLen, aad_size, payloadLen);
+ ret = TEE_AEInit(hndl, iv, (size_t)iv_size, tag_len_bits, aad_size, payload_len_bits);
if (TEE_SUCCESS != ret) {
LOG("TEE_AEInit failed with error=%x.", ret);
return ret;
return ret;
}
-TEE_Result KM_AuthDecrypt(TEE_OperationHandle hndl, void *iv, uint32_t iv_size, uint32_t tagLen,
- uint32_t payloadLen, void *data, uint32_t data_size,
+TEE_Result KM_AuthDecrypt(TEE_OperationHandle hndl, void *iv, uint32_t iv_size, uint32_t tag_len_bits,
+ uint32_t payload_len_bits, void *data, uint32_t data_size,
void *aad, uint32_t aad_size, void *tag, uint32_t tag_size,
void *out, uint32_t *out_size)
{
TEE_Result ret = TEE_SUCCESS;
- ret = TEE_AEInit(hndl, iv, (size_t) iv_size, tagLen, aad_size, payloadLen);
+ ret = TEE_AEInit(hndl, iv, (size_t)iv_size, tag_len_bits, aad_size, payload_len_bits);
if (TEE_SUCCESS != ret) {
LOG("TEE_AEInit failed with error=%x.", ret);
return ret;
extern const uint32_t AES_BLOCK_SIZE;
-TEE_Result KM_SymmetricCrypt_AES_CFB(void *key_id, uint32_t key_id_size, uint32_t mode,
+TEE_Result KM_SymmetricCrypt_AES_CFB(TEE_ObjectHandle key, uint32_t mode,
void *iv, uint32_t iv_size, void *input, uint32_t input_size,
void *output, uint32_t *output_size)
{
}
// CFB always uses AES in encryption mode
- ret = KM_CreateOperationWithKeyId(key_id, key_id_size, TEE_MODE_ENCRYPT, TEE_ALG_AES_ECB_NOPAD, &op);
+ ret = KM_CreateOperation(key, TEE_ALG_AES_ECB_NOPAD, TEE_MODE_ENCRYPT, &op);
if (ret != TEE_SUCCESS) {
LOG("Failed to create AES CFB operation: %x", ret);
goto clean;
#include <log.h>
#include <stdlib.h>
+#include <crypto_padding.h>
+#include <crypto_derive.h>
+#include <crypto_symmetric.h>
+#include <crypto_auth.h>
#ifndef TEE_DATA_FLAG_OVERWRITE
#define TEE_DATA_FLAG_OVERWRITE TEE_DATA_FLAG_EXCLUSIVE
#endif
-int KM_CheckAESMode(uint32_t algo, uint32_t tagLen)
+int KM_CheckAuthAESMode(uint32_t algo, uint32_t tagLen)
{
+ LOGD("Auth aes tag len: %d for algo %x", tagLen, algo);
switch (algo) {
case TEE_ALG_AES_GCM: {
switch (tagLen) {
TEE_Attribute attr;
TEE_Result ret = TEE_SUCCESS;
+ // TODO According to tef-simulator, here we should provide size in bits,
+ // not bytes. Is it the same on other TEF implementations?
TEE_InitRefAttribute(&attr, TEE_ATTR_SECRET_VALUE, key, key_bits_size);
ret = TEE_AllocateTransientObject(tee_key_type, key_bits_size, hndl);
if (TEE_SUCCESS != ret) {
return ret;
}
-TEE_Result KM_CreateOperation(TEE_ObjectHandle op_key_hndl, uint32_t algo, uint32_t mode,
- uint32_t key_bits_size, TEE_OperationHandle *hndl)
+TEE_Result KM_EncryptDataWithPwd(KM_PwdData *pwd, void *in, size_t in_size,
+ void *out, uint32_t *out_size, void *tag, uint32_t *tag_size)
{
TEE_Result ret = TEE_SUCCESS;
+ TEE_ObjectHandle key = TEE_HANDLE_NULL;
+ TEE_OperationHandle op = TEE_HANDLE_NULL;
+
+ ret = KM_DeriveKey(pwd->pwd, pwd->pwd_size, pwd->iv, pwd->iv_size,
+ pwd->it_count, TEE_TYPE_AES, pwd->derive_len_bits, &key);
+ if (ret != TEE_SUCCESS) {
+ LOG("Failed to derive key from password: %x", ret);
+ goto out;
+ }
+
+ ret = KM_CreateOperation(key, TEE_ALG_AES_GCM, TEE_MODE_ENCRYPT, &op);
+ if (ret != TEE_SUCCESS) {
+ LOG("Failed to create operation: %x", ret);
+ goto out;
+ }
+
+ ret = KM_AuthEncrypt(op, pwd->iv, pwd->iv_size, pwd->tag_len_bits, 0, in, in_size,
+ NULL, 0, out, out_size, tag, tag_size);
+ if (ret != TEE_SUCCESS) {
+ LOG("Failed to encrypt key: %x", ret);
+ goto out;
+ }
+
+out:
+ TEE_FreeOperation(op);
+ TEE_FreeTransientObject(key);
+ return ret;
+}
+
+TEE_Result KM_EncryptKey(TEE_ObjectHandle keyHndl, KM_PwdData *pwd,
+ TEE_ObjectHandle *encKeyHndl, void *tag, uint32_t *tag_size)
+{
+ TEE_Result ret = TEE_SUCCESS;
+ TEE_ObjectInfo objInfo;
+ void* keyBuf = NULL;
+ size_t keyBufSize = 0;
+ void* encKeyBuf = NULL;
+ uint32_t encKeyBufSize = 0;
+
+ if (encKeyHndl == NULL) {
+ LOG("Output key handle not valid");
+ return TEE_ERROR_BAD_PARAMETERS;
+ }
+
+ TEE_GetObjectInfo(keyHndl, &objInfo);
+ if (objInfo.objectSize == 0) {
+ LOG("Key provided for encryption is not initialized");
+ return TEE_ERROR_BAD_PARAMETERS;
+ }
+
+ if (tag == NULL) {
+ LOG("Tag is needed to encrypt key");
+ return TEE_ERROR_BAD_PARAMETERS;
+ }
+
+ keyBufSize = objInfo.objectSize;
+ keyBuf = malloc(keyBufSize);
+ if (keyBuf == NULL) {
+ LOG("Failed to allocate memory for key encryption");
+ ret = TEE_ERROR_OUT_OF_MEMORY;
+ goto out;
+ }
+
+ encKeyBufSize = (uint32_t)keyBufSize;
+ encKeyBuf = malloc(encKeyBufSize);
+ if (keyBuf == NULL) {
+ LOG("Failed to allocate memory for key encryption");
+ ret = TEE_ERROR_OUT_OF_MEMORY;
+ goto out;
+ }
+
+ // extract key
+ ret = TEE_GetObjectBufferAttribute(keyHndl, TEE_ATTR_SECRET_VALUE,
+ keyBuf, &keyBufSize);
+ if (ret != TEE_SUCCESS) {
+ LOG("Failed to acquire key from object: %x", ret);
+ goto out;
+ }
+
+ // encrypt key
+ ret = KM_EncryptDataWithPwd(pwd, keyBuf, keyBufSize, encKeyBuf, &encKeyBufSize,
+ tag, tag_size);
+ if (ret != TEE_SUCCESS) {
+ LOG("Failed to encrypt key: %x", ret);
+ goto out;
+ }
+
+ // create new key from encrypted one
+ ret = KM_CreateKey(objInfo.objectType, objInfo.objectSize,
+ encKeyBuf, encKeyBufSize, encKeyHndl);
+ if (ret != TEE_SUCCESS) {
+ LOG("Failed to create new key from encrypted");
+ goto out;
+ }
+
+out:
+ free(encKeyBuf);
+ free(keyBuf);
+ return ret;
+}
+
+TEE_Result KM_DecryptDataWithPwd(KM_PwdData* pwd, void *in, size_t in_size,
+ void *out, uint32_t *out_size)
+{
+ TEE_Result ret = TEE_SUCCESS;
+ TEE_ObjectHandle key = TEE_HANDLE_NULL;
+ TEE_OperationHandle op = TEE_HANDLE_NULL;
+
+ ret = KM_DeriveKey(pwd->pwd, pwd->pwd_size, pwd->iv, pwd->iv_size,
+ pwd->it_count, TEE_TYPE_AES, pwd->derive_len_bits, &key);
+ if (ret != TEE_SUCCESS) {
+ LOG("Failed to derive key from password: %x", ret);
+ goto out;
+ }
+
+ ret = KM_CreateOperation(key, TEE_ALG_AES_GCM, TEE_MODE_DECRYPT, &op);
+ if (ret != TEE_SUCCESS) {
+ LOG("Failed to create operation: %x", ret);
+ goto out;
+ }
- LOG("Operation key size: %d", key_bits_size);
- ret = TEE_AllocateOperation(hndl, algo, mode, key_bits_size);
+ ret = KM_AuthDecrypt(op, pwd->iv, pwd->iv_size, pwd->tag_len_bits, 0, in, in_size,
+ NULL, 0, pwd->tag, pwd->tag_size, out, out_size);
+ if (ret != TEE_SUCCESS) {
+ LOG("Failed to decrypt key: %x", ret);
+ goto out;
+ }
+
+out:
+ TEE_FreeOperation(op);
+ TEE_FreeTransientObject(key);
+ return ret;
+}
+
+TEE_Result KM_DecryptKey(void *id, size_t id_size, KM_PwdData* pwd,
+ TEE_ObjectHandle *decKeyHndl)
+{
+ TEE_Result ret = TEE_SUCCESS;
+ TEE_ObjectInfo objInfo;
+ TEE_ObjectHandle objHandle;
+ void* keyBuf = NULL;
+ size_t keyBufSize = 0;
+ void* decKeyBuf = NULL;
+ uint32_t decKeyBufSize = 0;
+
+ if (decKeyHndl == NULL) {
+ LOG("Output key handle not valid");
+ return TEE_ERROR_BAD_PARAMETERS;
+ }
+
+ ret = KM_OpenKey(id, id_size, NULL, &objHandle);
+
+ TEE_GetObjectInfo(objHandle, &objInfo);
+ if (objInfo.objectSize == 0) {
+ LOG("Key provided for encryption is not initialized");
+ return TEE_ERROR_BAD_PARAMETERS;
+ }
+
+ keyBufSize = (uint32_t)objInfo.objectSize;
+ keyBuf = malloc(keyBufSize);
+ if (keyBuf == NULL) {
+ LOG("Failed to allocate memory for key encryption");
+ ret = TEE_ERROR_OUT_OF_MEMORY;
+ goto out;
+ }
+
+ decKeyBufSize = keyBufSize;
+ decKeyBuf = malloc(decKeyBufSize);
+ if (keyBuf == NULL) {
+ LOG("Failed to allocate memory for key decryption");
+ ret = TEE_ERROR_OUT_OF_MEMORY;
+ goto out;
+ }
+
+ // extract key
+ ret = TEE_GetObjectBufferAttribute(objHandle, TEE_ATTR_SECRET_VALUE,
+ keyBuf, &keyBufSize);
+ if (ret != TEE_SUCCESS) {
+ LOG("Failed to acquire key from object: %x", ret);
+ goto out;
+ }
+
+ // decrypt key
+ ret = KM_DecryptDataWithPwd(pwd, keyBuf, keyBufSize, decKeyBuf, &decKeyBufSize);
+ if (ret != TEE_SUCCESS) {
+ LOG("Failed to decrypt key: %x", ret);
+ goto out;
+ }
+
+ // create new key from decrypted one
+ ret = KM_CreateKey(objInfo.objectType, objInfo.objectSize,
+ decKeyBuf, decKeyBufSize, decKeyHndl);
+ if (ret != TEE_SUCCESS) {
+ LOG("Failed to create new key from decrypted");
+ goto out;
+ }
+
+out:
+ TEE_CloseObject(objHandle);
+ free(decKeyBuf);
+ free(keyBuf);
+ return ret;
+}
+
+TEE_Result KM_CreateOperation(TEE_ObjectHandle op_key_hndl, uint32_t algo,
+ uint32_t mode, TEE_OperationHandle *hndl)
+{
+ TEE_Result ret = TEE_SUCCESS;
+ TEE_ObjectInfo info;
+
+ TEE_GetObjectInfo(op_key_hndl, &info);
+
+ LOGD("Operation key size: %d", info.objectSize);
+ ret = TEE_AllocateOperation(hndl, algo, mode, info.objectSize);
if (TEE_SUCCESS != ret) {
LOG("TEE_AllocateOperation has failed with=%x.", ret);
return ret;
}
TEE_Result KM_CreateOperationWithKey(void *key, uint32_t key_size, uint32_t type, uint32_t mode,
- uint32_t algo, uint32_t key_bits_size,
- TEE_OperationHandle *oper_hndl)
+ uint32_t algo, uint32_t key_bits_size,
+ TEE_OperationHandle *oper_hndl)
{
TEE_Result ret = TEE_SUCCESS;
TEE_ObjectHandle hndl = TEE_HANDLE_NULL;
return ret;
}
- ret = KM_CreateOperation(hndl, algo, mode, key_bits_size, oper_hndl);
+ ret = KM_CreateOperation(hndl, algo, mode, oper_hndl);
TEE_FreeTransientObject(hndl);
-
if (TEE_SUCCESS != ret) {
LOG("Failed to create operation: %x", ret);
+ return ret;
}
+
return ret;
}
TEE_GetObjectInfo(key, &keyInfo);
- ret = KM_CreateOperation(key, algo, mode, keyInfo.objectSize, oper_hndl);
+ ret = KM_CreateOperation(key, algo, mode, oper_hndl);
TEE_CloseObject(key);
if (TEE_SUCCESS != ret) {
return ret;
}
- TEE_GetObjectInfo(*hndl, &info);
- *key_bits_size = info.objectSize;
+ if (key_bits_size) {
+ TEE_GetObjectInfo(*hndl, &info);
+ *key_bits_size = info.objectSize;
+ }
return ret;
}
return ret;
}
+void KM_DestroyKey(void *objId, size_t objId_size)
+{
+ TEE_Result ret = TEE_SUCCESS;
+ TEE_ObjectHandle key;
+
+ // open the object to check if it exists
+ ret = TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE, objId, objId_size,
+ TEE_DATA_FLAG_ACCESS_WRITE_META, &key);
+ if (ret != TEE_SUCCESS) {
+ if (ret == TEE_ERROR_ITEM_NOT_FOUND) {
+ return;
+ }
+
+ LOG("Failed to open persistent object: %x", ret);
+ return;
+ }
+
+ TEE_CloseAndDeletePersistentObject(key);
+}
+
void KM_GenerateIV(void *iv, size_t iv_size)
{
TEE_GenerateRandom(iv, iv_size);
break;
}
case CMD_GENERATE_KEY_PWD: {
- LOGD("!!! Generate Key from PWD !!!");
- LOGD("Alg: %x", param[0].value.a);
+ LOGD("!!! Generate Key with PWD !!!");
ret = KM_ExecCmdGenerateKeyPwd(param);
break;
}
ret = KM_ExecCmdVerify(param);
break;
}
+ case CMD_DESTROY_KEY: {
+ LOGD("!!! Destroy !!!");
+ ret = KM_ExecCmdDestroyKey(param);
+ break;
+ }
default: {
LOG("Unknown commandID=%d.", commandID);
ret = TEE_ERROR_BAD_PARAMETERS;