Rewrite symmetric crypto code to support key encryption 15/161315/1
authorLukasz Kostyra <l.kostyra@samsung.com>
Wed, 15 Nov 2017 11:04:12 +0000 (12:04 +0100)
committerLukasz Kostyra <l.kostyra@samsung.com>
Wed, 22 Nov 2017 17:54:21 +0000 (18:54 +0100)
Change-Id: I0bc9b507e146192f9ae2c75332227cafa9502c49

12 files changed:
serialization/include/km_serialization.h
serialization/src/km_serialization.c
ta/include/cmd_exec.h
ta/include/crypto_auth.h
ta/include/crypto_symmetric.h
ta/include/internal.h
ta/include/km_ta_defines.h
ta/src/cmd_exec.c
ta/src/crypto_auth.c
ta/src/crypto_symmetric.c
ta/src/internal.c
ta/src/km_ta.c

index 884592f006fd7f614f16f106580690127ad8e40c..7dbd5d1c3c05b0ed10d730bac6424c1a7d374641 100644 (file)
 /*
  * @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>
 
@@ -32,88 +33,105 @@ extern "C"
 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__
index 166e94c6a9aa27b19a804b78e4d350d1bee9c1a7..bf341247d1de05a1d73b5c9fe3d738039e662b85 100644 (file)
@@ -16,6 +16,7 @@
 /*
  * @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
  */
@@ -39,10 +40,10 @@ static size_t addAlignment(size_t size)
 
 
 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;
@@ -50,11 +51,12 @@ static int KM_ParamsDeserializeData(void *self, uint32_t offset, uint32_t magic,
 
        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.");
@@ -70,11 +72,11 @@ static int KM_ParamsDeserializeData(void *self, uint32_t offset, uint32_t 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;
@@ -86,8 +88,8 @@ static int KM_ParamsSerializeData(SymmetricInput *self, const void *data, size_t
                        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;
@@ -105,21 +107,17 @@ static int KM_ParamsSerializeData(SymmetricInput *self, const void *data, size_t
 
 // 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);
@@ -130,9 +128,15 @@ void KM_ParamsDump(SymmetricInput *input, InputData *input_data, IVData *iv_data
        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);
@@ -142,7 +146,7 @@ void KM_ParamsDump(SymmetricInput *input, InputData *input_data, IVData *iv_data
        }
 }
 
-uint32_t KM_GetSerializedBufferRealSize(SymmetricInput *buffer)
+uint32_t KM_GetSerializedBufferRealSize(KM_SymmetricInput *buffer)
 {
        if (buffer == NULL) {
                LOG("Incorrect buffer provided");
@@ -152,32 +156,38 @@ uint32_t KM_GetSerializedBufferRealSize(SymmetricInput *buffer)
        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;
 }
@@ -186,14 +196,14 @@ uint32_t KM_PrecalculateBufferSize(uint32_t input_size, uint32_t iv_size, uint32
 
 // 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;
        }
@@ -210,219 +220,333 @@ int KM_ParamsDeserializationInit(void *buffer, size_t buffer_size, SymmetricInpu
        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;
 }
index 343ca8b124c56e7c2482f85af4a6ab33caf7e0ca..b3de375dbbc9c54aab677d4c46f2bbd31335761b 100644 (file)
@@ -40,4 +40,6 @@ TEE_Result KM_ExecCmdSign(TEE_Param param[4]);
 
 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
index fa9efef74b14cb63f42b66739c2050a49d97072e..dbb7d9d409c1166a308e56664473e82d6287a28c 100644 (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__
index 3ceccc3dadd0968404dca862406ab6eb0f5c37c4..4c3873a092d9dfc3e4f15a67c89aa66a4648332c 100644 (file)
@@ -25,7 +25,7 @@
 #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);
 
index f7bdb2e3a3bcab640e1a92a2e614f31fcfc98e54..caa0447e4f5daf9f1029fe00c45cf1a9e0d7fb5a 100644 (file)
 #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);
@@ -52,6 +58,8 @@ TEE_Result KM_OpenKey(void *objId, size_t objId_size, uint32_t *key_bits_size,
 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__
index be48875560bf91cb885086bdb27ee4c571cb1f2e..2c40807c63b82e3c1016cb355ab5a6923aad7e25 100644 (file)
@@ -34,6 +34,7 @@ typedef enum {
        CMD_VERIFY,
        CMD_GENERATE_IV,
        CMD_GENERATE_KEY_PWD,
+       CMD_DESTROY_KEY,
 } tz_command;
 
 typedef enum {
index 6adf961f3af4309d731e28c148ebe53c4f7abfa2..b209eacf17a4fd2d9b9d8fcad29dc20590ea6529 100644 (file)
@@ -78,10 +78,9 @@ static uint32_t KM_Algo2TeeAlgo(int algo)
        }
 }
 
-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");
@@ -98,14 +97,18 @@ static TEE_Result KM_DeserializeInput(void* buffer, uint32_t buffer_size, Symmet
                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) {
@@ -122,13 +125,6 @@ static TEE_Result KM_DeserializeInput(void* buffer, uint32_t buffer_size, Symmet
                }
        }
 
-       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");
@@ -143,19 +139,6 @@ static TEE_Result KM_DeserializeInput(void* buffer, uint32_t buffer_size, Symmet
                }
        }
 
-       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;
 }
 
@@ -243,7 +226,7 @@ TEE_Result KM_ExecCmdGenerateKey(TEE_Param param[4])
 {
        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;
@@ -272,7 +255,7 @@ TEE_Result KM_ExecCmdGenerateKey(TEE_Param param[4])
        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;
@@ -293,12 +276,14 @@ 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) {
@@ -308,39 +293,59 @@ TEE_Result KM_ExecCmdGenerateKeyPwd(TEE_Param param[4])
        }
 
        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;
 }
@@ -348,16 +353,19 @@ clean:
 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;
@@ -371,58 +379,85 @@ TEE_Result KM_ExecCmdImportKey(TEE_Param param[4])
        }
 
        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);
 
@@ -432,13 +467,21 @@ TEE_Result KM_ExecCmdSymmetric(uint32_t commandID, TEE_Param param[4])
        }
 
        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) {
@@ -448,8 +491,9 @@ TEE_Result KM_ExecCmdSymmetric(uint32_t commandID, TEE_Param param[4])
        }
 
        // 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) {
@@ -458,38 +502,43 @@ TEE_Result KM_ExecCmdSymmetric(uint32_t commandID, TEE_Param param[4])
                        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 {
@@ -510,18 +559,16 @@ TEE_Result KM_ExecCmdSymmetric(uint32_t commandID, TEE_Param param[4])
                }
        }
 
-       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;
 }
@@ -529,21 +576,21 @@ clean:
 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);
 
@@ -558,30 +605,36 @@ TEE_Result KM_ExecCmdAuth(uint32_t commandID, TEE_Param param[4])
        }
 
        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;
@@ -590,21 +643,28 @@ TEE_Result KM_ExecCmdAuth(uint32_t commandID, TEE_Param param[4])
        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);
@@ -626,10 +686,12 @@ TEE_Result KM_ExecCmdAuth(uint32_t commandID, TEE_Param param[4])
                }
        }
 
+       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;
 }
 
@@ -637,15 +699,13 @@ TEE_Result KM_ExecCmdAsymmetric(uint32_t commandID, TEE_Param param[4])
 {
        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);
 
@@ -655,21 +715,15 @@ TEE_Result KM_ExecCmdAsymmetric(uint32_t commandID, TEE_Param param[4])
        }
 
        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;
        }
@@ -708,10 +762,9 @@ TEE_Result KM_ExecCmdSign(TEE_Param param[4])
        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;
@@ -719,7 +772,6 @@ TEE_Result KM_ExecCmdSign(TEE_Param param[4])
        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) {
@@ -727,33 +779,21 @@ TEE_Result KM_ExecCmdSign(TEE_Param param[4])
                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) {
@@ -807,16 +847,13 @@ TEE_Result KM_ExecCmdVerify(TEE_Param param[4])
        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) {
@@ -824,40 +861,27 @@ TEE_Result KM_ExecCmdVerify(TEE_Param param[4])
                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);
@@ -882,3 +906,23 @@ clean:
        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;
+}
index 6d100a221d49de4a9523b361b5d3791863ab061f..c8b1270bb7e1a0113acd528915821a38849024c5 100644 (file)
@@ -23,8 +23,8 @@
 #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)
 {
@@ -35,7 +35,7 @@ TEE_Result KM_AuthEncrypt(TEE_OperationHandle hndl, void *iv, uint32_t iv_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;
@@ -54,14 +54,14 @@ TEE_Result KM_AuthEncrypt(TEE_OperationHandle hndl, void *iv, uint32_t iv_size,
        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;
index e80cc7e59756cc4a7e2ed9a0f81bbbc143c63857..4e346c5e87eb27f7bf504b7ec63145f17805d2f9 100644 (file)
@@ -31,7 +31,7 @@
 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)
 {
@@ -57,7 +57,7 @@ TEE_Result KM_SymmetricCrypt_AES_CFB(void *key_id, uint32_t key_id_size, uint32_
        }
 
        // 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;
index b2268a08f292aa2e42a774409aded5b65133738e..58234dc06f298132e0b88b947a95112028f2ef11 100644 (file)
 #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) {
@@ -69,6 +74,8 @@ TEE_Result KM_CreateKey(uint32_t tee_key_type, uint32_t key_bits_size, void *key
        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) {
@@ -108,13 +115,224 @@ TEE_Result KM_CreateRandomKey(uint32_t tee_key_type, uint32_t key_bits_size, TEE
        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;
@@ -131,8 +349,8 @@ TEE_Result KM_CreateOperation(TEE_ObjectHandle op_key_hndl, uint32_t algo, uint3
 }
 
 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;
@@ -143,12 +361,13 @@ TEE_Result KM_CreateOperationWithKey(void *key, uint32_t key_size, uint32_t type
                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;
 }
 
@@ -168,7 +387,7 @@ TEE_Result KM_CreateOperationWithKeyId(void *key_id, uint32_t key_id_size, uint3
 
        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) {
@@ -221,8 +440,10 @@ TEE_Result KM_OpenKey(void *objId, size_t objId_size, uint32_t *key_bits_size,
                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;
 }
 
@@ -253,6 +474,26 @@ TEE_Result KM_ImportKey(TEE_ObjectHandle hndl, uint32_t tee_key_type, void *buff
        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);
index d4bc2ab38baf0af15e940d2f2b5658f247af0cf9..98d515fc78949d775e79c06a32714e0e4063112d 100644 (file)
@@ -74,8 +74,7 @@ TEE_Result TA_InvokeCommandEntryPoint(void *sessionContext, uint32_t commandID,
                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;
        }
@@ -138,6 +137,11 @@ TEE_Result TA_InvokeCommandEntryPoint(void *sessionContext, uint32_t commandID,
                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;