Add data storage operations 76/188976/22
authorTomasz Swierczek <t.swierczek@samsung.com>
Thu, 13 Sep 2018 12:05:23 +0000 (14:05 +0200)
committerTomasz Swierczek <t.swierczek@samsung.com>
Wed, 3 Oct 2018 10:37:22 +0000 (12:37 +0200)
Change-Id: Ieb0363d19d2b6f53783fce517a37e1b63d7759f3

serialization/include/km_serialization.h
serialization/src/km_serialization.c
ta/include/cmd_exec.h
ta/include/internal.h
ta/include/km_ta_defines.h
ta/src/cmd_exec.c
ta/src/internal.c
ta/src/km_ta.c

index c796bdc8e325fdc6eafd0329b6696c218baaa3bf..80a95df08406f8d61271d0ebe6ef345bd8e7e65c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2017 - 2018 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -17,7 +17,8 @@
  * @file        serialization.h
  * @author      Rafał Tyminski (r.tyminski@partner.samsung.com)
  * @author      Lukasz Kostyra (l.kostyra@samsung.com)
- * @version     1.0
+ * @author      Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version     2.0
  * @brief       Implementaion of tee commands parameters serialization
  */
 #ifndef __KM_SERIALIZATION_H__
@@ -371,6 +372,44 @@ int KM_ParamsSerializePwdData(KM_SymmetricInput *self, const void *pwd, uint32_t
                                                        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);
 
+/*
+ * Serialization data & functions for storing arbitrary data
+ */
+typedef struct KM_BinaryData_ {
+       uint32_t data_size;
+       void *data;
+} KM_BinaryData;
+
+/*
+ * Below functions assume 'buffer' is already of proper size & size_guard contains number of bytes left in the buffer till its end;
+ * all functions copy memory to the buffer, move the 'buffer' pointer forward for further serialization & decrease size_guard if its possible;
+ * return 0 on success, non-zero on error
+ */
+int KM_Serialize(void **buffer, uint32_t *size_guard, const void *data_to_serialize, uint32_t size_to_serialize);
+int KM_SerializeFlag(void **buffer, uint32_t *size_guard, uint32_t flag);
+int KM_SerializeBinaryData(void **buffer, uint32_t *size_guard, const KM_BinaryData *data);
+int KM_SerializePwdDataRaw(void **buffer, uint32_t *size_guard, 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);
+int KM_SerializePwdData(void **buffer, uint32_t *size_guard, const KM_PwdData *data);
+
+/*
+ * Functions don't copy memory, just set destination structure/data pointer properly, move 'buffer' accordingly for further deserialization
+ * & decrease size_guard; only deserialization of a flag actually copies some data;
+ * return 0 on success, non-zero on error
+ */
+int KM_Deserialize(void **buffer, uint32_t *size_guard, void **destination_location, uint32_t *size_to_deserialize);
+int KM_DeserializeFlag(void **buffer, uint32_t *size_guard, uint32_t *flag);
+int KM_DeserializeBinaryData(void **buffer, uint32_t *size_guard, KM_BinaryData *data);
+int KM_DeserializePwdData(void **buffer, uint32_t *size_guard, KM_PwdData *data);
+
+/*
+ * Functions related to size calculations - needed to calcualte size of shared memory to be used for communication
+ */
+uint32_t KM_SizeOfFlag(void);
+uint32_t KM_SizeOfBinaryData(KM_BinaryData* data);
+uint32_t KM_SizeOfPwdData(KM_PwdData* data);
+
 #ifdef __cplusplus
 }
 #endif
index acdd89b674a7a8f402b4543b6a8dff6f4ae359f1..621463dce3d4cf555500f9e3d4939c9214f204c0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2017 - 2018 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -17,7 +17,8 @@
  * @file        serialization.c
  * @author      Rafał Tyminski (r.tyminski@partner.samsung.com)
  * @author      Lukasz Kostyra (l.kostyra@samsung.com)
- * @version     1.0
+ * @author      Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version     2.0
  * @brief       Implementaion of tee commands parameters serialization
  */
 
@@ -554,3 +555,180 @@ int KM_ParamsSerializePwdData(KM_SymmetricInput *self, const void *pwd, uint32_t
 
        return 0;
 }
+
+int KM_Serialize(void **buffer, uint32_t *size_guard, const void *data_to_serialize, uint32_t size_to_serialize)
+{
+       unsigned char **ptr = (unsigned char **)buffer;
+       if (!buffer || !(*ptr) || !size_guard) {
+               LOG("Invalid usage of serialization.");
+               return -2;
+       }
+       if (*size_guard < size_to_serialize + sizeof(size_to_serialize)) {
+               LOG("Cannot serialize - buffer too small.");
+               return -1;
+       }
+       memcpy(*ptr, &size_to_serialize, sizeof(size_to_serialize));
+       *ptr += sizeof(size_to_serialize);
+       if (data_to_serialize != NULL) {
+               memcpy(*ptr, data_to_serialize, size_to_serialize);
+       } // else - its not an error; it will be used to prepare output buffer of given size, but (on CA side), there will be no content yet
+       *ptr += size_to_serialize;
+       *size_guard -= size_to_serialize + sizeof(size_to_serialize);
+       return 0;
+}
+
+int KM_SerializeFlag(void **buffer, uint32_t *size_guard, uint32_t flag)
+{
+       unsigned char **ptr = (unsigned char **)buffer;
+       if (!buffer || !(*ptr) || !size_guard) {
+               LOG("Invalid usage of serialization.");
+               return -2;
+       }
+       if (*size_guard < sizeof(flag)) {
+               LOG("Cannot serialize - buffer too small.");
+               return -1;
+       }
+       memcpy(*ptr, &flag, sizeof(flag));
+       *ptr += sizeof(flag);
+       *size_guard -= sizeof(flag);
+       return 0;
+}
+
+int KM_SerializeBinaryData(void **buffer, uint32_t *size_guard, const KM_BinaryData *data)
+{
+       if (!data) {
+               LOG("Invalid usage of serialization.");
+               return -1;
+       }
+       return KM_Serialize(buffer, size_guard, data->data, data->data_size);
+}
+
+int KM_SerializePwdDataRaw(void **buffer, uint32_t *size_guard, 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)
+{
+       if (KM_Serialize(buffer, size_guard, pwd, pwd_size))
+               return -2;
+       if (KM_Serialize(buffer, size_guard, iv, iv_size))
+               return -3;
+       if (KM_Serialize(buffer, size_guard, tag, tag_size))
+               return -4;
+       if (KM_SerializeFlag(buffer, size_guard, derive_len_bits))
+               return -5;
+       if (KM_SerializeFlag(buffer, size_guard, it_count))
+               return -6;
+       if (KM_SerializeFlag(buffer, size_guard, tag_len_bits))
+               return -7;
+       return 0;
+}
+
+int KM_SerializePwdData(void **buffer, uint32_t *size_guard, const KM_PwdData *data)
+{
+       if (!data) {
+               LOG("Invalid usage of serialization.");
+               return -1;
+       }
+       return KM_SerializePwdDataRaw(buffer, size_guard, data->pwd, data->pwd_size,
+                                                                       data->iv, data->iv_size, data->tag, data->tag_size,
+                                                                       data->derive_len_bits, data->it_count, data->tag_len_bits);
+}
+
+// Doesn't copy memory, just sets destination structure/data pointer properly & moves 'buffer' accordingly for further deserialization
+int KM_Deserialize(void **buffer, uint32_t *size_guard, void **destination_location, uint32_t *size_to_deserialize)
+{
+       unsigned char **ptr = (unsigned char **)buffer;
+       unsigned char **ptr_dest = (unsigned char **)destination_location;
+       if (!buffer || !(*ptr)|| !size_guard || !destination_location || !size_to_deserialize) {
+               LOG("Invalid usage of deserialization.");
+               return -2;
+       }
+       if (*size_guard < sizeof(*size_to_deserialize)) {
+               LOG("Cannot deserialize data, not enough data in the buffer.");
+               return -3;
+       }
+       memcpy(size_to_deserialize, *ptr, sizeof(*size_to_deserialize));
+       *size_guard -= sizeof(*size_to_deserialize);
+       if (*size_guard < *size_to_deserialize) {
+               LOG("Cannot deserialize data, not enough data in the buffer.");
+               return -4;
+       }
+       *ptr += sizeof(*size_to_deserialize);
+       *ptr_dest = *ptr;
+       *ptr += *size_to_deserialize;
+       *size_guard -= *size_to_deserialize;
+       return 0;
+}
+
+int KM_DeserializeFlag(void **buffer, uint32_t *size_guard, uint32_t *flag)
+{
+       unsigned char **ptr = (unsigned char **)buffer;
+       if (!buffer || !(*ptr)|| !size_guard || !flag) {
+               LOG("Invalid usage of deserialization.");
+               return -1;
+       }
+
+       if (*size_guard < sizeof(*flag)) {
+               LOG("Cannot deserialize data, not enough data in the buffer.");
+               return -2;
+       }
+       memcpy(flag, *ptr, sizeof(*flag));
+       *ptr += sizeof(*flag);
+       *size_guard -= sizeof(*flag);
+       return 0;
+}
+
+int KM_DeserializeBinaryData(void **buffer, uint32_t *size_guard, KM_BinaryData *data)
+{
+       if (!data) {
+               LOG("Invalid usage of deserialization.");
+               return -1;
+       }
+       return KM_Deserialize(buffer, size_guard, &(data->data), &(data->data_size));
+}
+
+int KM_DeserializePwdData(void **buffer, uint32_t *size_guard, KM_PwdData *data)
+{
+       if (!data) {
+               LOG("Invalid usage of deserialization.");
+               return -1;
+       }
+       if (KM_Deserialize(buffer, size_guard, &data->pwd, &data->pwd_size))
+               return -2;
+       if (KM_Deserialize(buffer, size_guard, &data->iv, &data->iv_size))
+               return -3;
+       if (KM_Deserialize(buffer, size_guard, &data->tag, &data->tag_size))
+               return -4;
+       if (KM_DeserializeFlag(buffer, size_guard, &data->derive_len_bits))
+               return -5;
+       if (KM_DeserializeFlag(buffer, size_guard, &data->it_count))
+               return -6;
+       if (KM_DeserializeFlag(buffer, size_guard, &data->tag_len_bits))
+               return -7;
+       return 0;
+}
+
+uint32_t KM_SizeOfFlag(void)
+{
+       return sizeof(uint32_t);
+}
+
+uint32_t KM_SizeOfBinaryData(KM_BinaryData* data)
+{
+       if (!data) {
+               LOG("Invalid usage of serialization KM_SizeOf*.");
+               return 0;
+       }
+       return data->data_size + sizeof(data->data_size);
+}
+
+uint32_t KM_SizeOfPwdData(KM_PwdData* data)
+{
+       if (!data) {
+               LOG("Invalid usage of serialization KM_SizeOf*.");
+               return 0;
+       }
+       return data->pwd_size + sizeof(data->pwd_size) +
+               data->iv_size + sizeof(data->iv_size) +
+               data->tag_size + sizeof(data->tag_size) +
+               KM_SizeOfFlag() * 3;
+}
index 37856fff511d6d538373c4158387e3b42acc157b..31028b1677e72a72bc7ad9c60b16fa3512717047 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2017 - 2018 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -15,8 +15,8 @@
  */
 /*
  * @file        cmd_exec.h
- * @author      Rafał Tyminski (r.tyminski@partner.samsung.com)
- * @version     1.0
+ * @author      Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version     2.0
  * @brief
  */
 #ifndef __CMD_EXEC_H__
@@ -40,4 +40,12 @@ TEE_Result KM_ExecCmdSign(TEE_Param param[4]);
 
 TEE_Result KM_ExecCmdDestroyKey(TEE_Param param[4]);
 
+TEE_Result KM_ExecCmdSaveData(TEE_Param param[4]);
+
+TEE_Result KM_ExecCmdGetData(TEE_Param param[4]);
+
+TEE_Result KM_ExecCmdGetDataSize(TEE_Param param[4]);
+
+TEE_Result KM_ExecCmdDestroyData(TEE_Param param[4]);
+
 #endif // __CMD_EXEC_H__
index 5d8e59fb35954c17352a55740dcdb13673e2fa79..7535d457471f5abf789a435cfcc97c4cfe5f16ef 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2017 - 2018 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -16,7 +16,8 @@
 /*
  * @file        internal.h
  * @author      Rafał Tyminski (r.tyminski@partner.samsung.com)
- * @version     1.0
+ * @author      Tomasz Swierczek (t.swierczek@partner.samsung.com)
+ * @version     2.0
  * @brief
  */
 #ifndef __INTERNAL_H__
@@ -72,4 +73,12 @@ void KM_DestroyKey(void *objId, uint32_t objId_size);
 
 void KM_GenerateIV(void *iv, uint32_t iv_size);
 
+TEE_Result KM_SaveData(void *data, uint32_t data_size, void *objId, uint32_t objId_size);
+
+TEE_Result KM_GetData(void *data, uint32_t expected_data_size, void *objId, uint32_t objId_size);
+
+TEE_Result KM_GetDataSize(uint32_t *data_size, void *objId, uint32_t objId_size);
+
+void KM_DestroyData(void *objId, uint32_t objId_size);
+
 #endif // __INTERNAL_H__
index 3947b028fbad66ff57f8ff72517ec638d1626f54..934acef98546fa3f8941f88463824f8a6b973e80 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2017 - 2018 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -17,7 +17,8 @@
  * @file        km_ta_defines.h
  * @author      Rafał Tyminski (r.tyminski@partner.samsung.com)
  * @author      Lukasz Kostyra (l.kostyra@samsung.com)
- * @version     1.0
+ * @author      Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version     2.0
  * @brief
  */
 #ifndef __KM_TA_DEFINES_H__
@@ -164,6 +165,45 @@ typedef enum {
                             ///< Output:
                             ///<    [0].value.a - return code
 
+       CMD_IMPORT_DATA,        ///< Key Manager binary data saving to persistent storage
+                            ///< TA will encrypt data with password if provided
+                            ///< Parameters:
+                            ///<    [1].memref  - reference to serialized buffer:
+                            ///<        KM_BinaryData with binary data
+                            ///<               uint32_t boolean value - true if password is provided
+                            ///<        KM_PwdData with password (optional)
+                            ///< Output:
+                            ///<    [0].value.a - return code
+                            ///<    [2].memref  - reference to serialized buffer:
+                            ///<        KM_BinaryData with data id
+                            ///<        KM_BinaryData with tag id (optional, if password was provided)
+
+       CMD_GET_DATA,           ///< Key Manager binary data retrieving from persistent storage
+                            ///< TA will decrypt data with password if provided
+                            ///< Parameters:
+                            ///<    [1].memref  - reference to serialized buffer:
+                            ///<        KM_BinaryData with object ID
+                            ///<               uint32_t boolean value - true if password is provided
+                            ///<        KM_PwdData with password (optional)
+                            ///< Output:
+                            ///<    [0].value.a - return code
+                            ///<    [2].memref  - reference to serialized buffer:
+                            ///<        KM_BinaryData with binary data (size pre-set on CA side)
+
+       CMD_GET_DATA_SIZE,      ///< Key Manager binary data size to be retrieved from persistent storage
+                            ///< Parameters:
+                            ///<    [1].memref  - reference to serialized buffer:
+                            ///<        KM_BinaryData with object ID
+                            ///< Output:
+                            ///<    [0].value.a - return code
+                            ///<    [0].value.b - size of buffer to be passed from CA
+
+       CMD_DESTROY_DATA        ///< Key Manager binary data removal from persistent storage
+                            ///< Parameters:
+                            ///<    [1].memref  - reference to serialized buffer:
+                            ///<        KM_BinaryData with object ID
+                            ///< Output:
+                            ///<    [0].value.a - return code
 } tz_command;
 
 /** \enum tz_algo_type
@@ -202,8 +242,9 @@ typedef enum {
        HASH_SHA512,
 } tz_hash_type;
 
-// TODO this must be somehow confronted with TEE_OBJECT_ID_MAX_LEN
+// TODO these must be somehow confronted with TEE_OBJECT_ID_MAX_LEN
 #define KM_KEY_ID_SIZE 64
+#define KM_DATA_ID_SIZE 64
 
 // Errors
 #define KM_TA_SUCCESS 0
index a7cc672e38f78144637ce986feeb1ca4ef010236..fa88b145499c0c0a3b22a9aa4c399de71945ea80 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2017 - 2018 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -16,7 +16,8 @@
 /*
  * @file        ta_km.c
  * @author      Rafał Tyminski (r.tyminski@partner.samsung.com)
- * @version     1.0
+ * @author      Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version     2.0
  * @brief
  */
 
@@ -857,3 +858,206 @@ TEE_Result KM_ExecCmdDestroyKey(TEE_Param param[4])
 clean:
        return ret;
 }
+
+
+TEE_Result KM_ExecCmdSaveData(TEE_Param param[4])
+{
+       TEE_Result ret = TEE_SUCCESS;
+       KM_BinaryData dataToSave;
+       KM_BinaryData encData;
+       KM_BinaryData objId;
+       KM_BinaryData tag;
+       KM_PwdData pwdData;
+       uint32_t with_pwd = 0;
+       void *in_buffer = param[1].memref.buffer;
+       void *out_buffer = param[2].memref.buffer;
+       uint32_t in_size_guard = param[1].memref.size;
+       uint32_t out_size_guard = param[2].memref.size;
+
+       encData.data = objId.data = tag.data = NULL;
+
+       if (KM_DeserializeBinaryData(&in_buffer, &in_size_guard, &dataToSave)) {
+               LOG("Error in deserialization");
+               ret = TEE_ERROR_BAD_PARAMETERS;
+               goto clean;
+       }
+       if (KM_DeserializeFlag(&in_buffer, &in_size_guard, &with_pwd)) {
+               LOG("Error in deserialization");
+               ret = TEE_ERROR_BAD_PARAMETERS;
+               goto clean;
+       }
+
+       if (with_pwd) {
+               if (KM_DeserializePwdData(&in_buffer, &in_size_guard, &pwdData)) {
+                       LOG("Error in deserialization");
+                       ret = TEE_ERROR_BAD_PARAMETERS;
+                       goto clean;
+               }
+               tag.data_size = pwdData.tag_len_bits / 8;
+               tag.data = malloc(tag.data_size);
+               if (tag.data == NULL) {
+                       LOG("Failed to allocate memory for data encryption key's tag");
+                       ret = TEE_ERROR_OUT_OF_MEMORY;
+                       goto clean;
+               }
+               // Probing for needed buffer size
+               encData.data = NULL;
+               encData.data_size = 0;
+               ret = KM_EncryptDataWithPwd(&pwdData, dataToSave.data, dataToSave.data_size,
+                                                                   encData.data, &encData.data_size, tag.data, &tag.data_size);
+
+               // We should get SHORT_BUFFER, but simulator tends to return TEE_SUCCESS
+               if (ret != TEE_ERROR_SHORT_BUFFER && ret != TEE_SUCCESS) {
+                       LOG("Failed to probe for needed data size");
+                       ret = TEE_ERROR_GENERIC;
+                       goto clean;
+               }
+               encData.data = malloc(encData.data_size);
+               if (encData.data == NULL) {
+                       LOG("Failed to allocate object buffer for encrypting data");
+                       ret = TEE_ERROR_OUT_OF_MEMORY;
+                       goto clean;
+               }
+               ret = KM_EncryptDataWithPwd(&pwdData, dataToSave.data, dataToSave.data_size,
+                                                                   encData.data, &encData.data_size, tag.data, &tag.data_size);
+               if (ret != TEE_SUCCESS) {
+                       LOG("Failed to encrypt data for storage");
+                       goto clean;
+               }
+               dataToSave = encData;
+       }
+
+
+       objId.data_size = TEE_OBJECT_ID_MAX_LEN;
+       objId.data = malloc(objId.data_size);
+
+       if (objId.data == NULL) {
+               LOG("Failed to allocate object ID buffer");
+               ret =  TEE_ERROR_OUT_OF_MEMORY;
+               goto clean;
+       }
+
+       // ObjectID generation
+       TEE_GenerateRandom(objId.data, objId.data_size);
+
+       ret = KM_SaveData(dataToSave.data, dataToSave.data_size, objId.data, objId.data_size);
+       if (ret != TEE_SUCCESS) {
+               LOG("Failed to save data to storage");
+       }
+
+       // Output data - ID of the object
+       if (KM_Serialize(&out_buffer, &out_size_guard, objId.data, objId.data_size)) {
+               LOG("Error in serialization");
+               ret = TEE_ERROR_BAD_PARAMETERS;
+               goto clean;
+       }
+       // If needed, also the tag ID
+       if (with_pwd) {
+               if (KM_Serialize(&out_buffer, &out_size_guard, tag.data, tag.data_size)) {
+                       LOG("Error in serialization");
+                       ret = TEE_ERROR_BAD_PARAMETERS;
+               }
+       }
+
+clean:
+       free(objId.data);
+       free(encData.data);
+       free(tag.data);
+       return ret;
+}
+
+TEE_Result KM_ExecCmdGetData(TEE_Param param[4])
+{
+       TEE_Result ret = TEE_SUCCESS;
+       KM_BinaryData objId;
+       KM_PwdData pwdData;
+       KM_BinaryData outData;
+       KM_BinaryData readData;
+       void *in_buffer = param[1].memref.buffer;
+       void *out_buffer = param[2].memref.buffer;
+       uint32_t in_size_guard = param[1].memref.size;
+       uint32_t out_size_guard = param[2].memref.size;
+       uint32_t with_pwd = 0;
+
+       readData.data = NULL;
+
+       if (KM_DeserializeBinaryData(&in_buffer, &in_size_guard, &objId)) {
+               LOG("Error in deserialization");
+               ret = TEE_ERROR_BAD_PARAMETERS;
+               goto clean;
+       }
+       if (KM_DeserializeFlag(&in_buffer, &in_size_guard, &with_pwd)) {
+               LOG("Error in deserialization");
+               ret = TEE_ERROR_BAD_PARAMETERS;
+               goto clean;
+       }
+       // doing this will read the size of data to read (assuming it was retrieved in prev. call to TA)
+       if (KM_DeserializeBinaryData(&out_buffer, &out_size_guard, &outData)) {
+               LOG("Error in deserialization");
+               ret = TEE_ERROR_BAD_PARAMETERS;
+               goto clean;
+       }
+       if (with_pwd) {
+               if (KM_DeserializePwdData(&in_buffer, &in_size_guard, &pwdData)) {
+                       LOG("Error in deserialization");
+                       ret = TEE_ERROR_BAD_PARAMETERS;
+                       goto clean;
+               }
+               readData.data = malloc(outData.data_size);
+               if (readData.data == NULL) {
+                       LOG("Failed to allocate object buffer for decrypting data");
+                       ret = TEE_ERROR_OUT_OF_MEMORY;
+                       goto clean;
+               }
+               readData.data_size = outData.data_size;
+               ret = KM_GetData(readData.data, readData.data_size, objId.data, objId.data_size);
+               if (ret != TEE_SUCCESS) {
+                       LOG("Failed to read object data from storage");
+                       goto clean;
+               }
+               ret = KM_DecryptDataWithPwd(&pwdData, readData.data, readData.data_size, outData.data, &outData.data_size);
+               if (ret != TEE_SUCCESS) {
+                       LOG("Failed to decrypt data with pwd");
+               }
+       } else {
+               ret = KM_GetData(outData.data, outData.data_size, objId.data, objId.data_size);
+               if (ret != TEE_SUCCESS) {
+                       LOG("Failed to read object data from storage");
+               }
+       }
+
+clean:
+       free(readData.data);
+       return ret;
+}
+
+TEE_Result KM_ExecCmdGetDataSize(TEE_Param param[4])
+{
+       TEE_Result ret = TEE_SUCCESS;
+       KM_BinaryData objId;
+       void *buffer = param[1].memref.buffer;
+       uint32_t in_size_guard = param[1].memref.size;
+       uint32_t data_size = 0;
+
+       if (KM_DeserializeBinaryData(&buffer, &in_size_guard, &objId)) {
+               LOG("Error in deserialization");
+               return TEE_ERROR_BAD_PARAMETERS;
+       }
+       ret = KM_GetDataSize(&data_size, objId.data, objId.data_size);
+       param[0].value.b = data_size;
+
+       return ret;
+}
+
+TEE_Result KM_ExecCmdDestroyData(TEE_Param param[4])
+{
+       KM_BinaryData objectId;
+       void *buffer = param[1].memref.buffer;
+       uint32_t in_size_guard = param[1].memref.size;
+       if (KM_DeserializeBinaryData(&buffer, &in_size_guard, &objectId)) {
+               LOG("Error in deserialization");
+               return TEE_ERROR_BAD_PARAMETERS;
+       }
+       KM_DestroyData(objectId.data, objectId.data_size);
+       return TEE_SUCCESS;
+}
index 481db37b6d1793e0edfa3528dd662b3fa089f77b..d9ebeef671bb177fc72f4985151ee74170666177 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2017 - 2018 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -16,7 +16,8 @@
 /*
  * @file        internal.c
  * @author      Rafał Tyminski (r.tyminski@partner.samsung.com)
- * @version     1.0
+ * @author      Tomasz Swierczek (t.swierczek@samsung.com)
+ * @version     2.0
  * @brief
  */
 
@@ -494,3 +495,96 @@ void KM_GenerateIV(void *iv, uint32_t iv_size)
 {
        TEE_GenerateRandom(iv, iv_size);
 }
+
+TEE_Result KM_SaveData(void *data, uint32_t data_size, void *objId, uint32_t objId_size)
+{
+       TEE_Result ret = TEE_SUCCESS;
+       TEE_ObjectHandle handl;
+       uint32_t flags = 0;
+
+       ret = TEE_CreatePersistentObject(TEE_STORAGE_PRIVATE, objId, objId_size, flags,
+                                                                       TEE_HANDLE_NULL, data, data_size, &handl);
+       TEE_CloseObject(handl);
+
+       if (TEE_SUCCESS != ret) {
+               LOG("TEE_CreatePersistentObject has failed with=%x.", ret);
+       }
+       return ret;
+}
+
+TEE_Result KM_GetData(void *data, uint32_t expected_data_size, void *objId, uint32_t objId_size)
+{
+       TEE_Result ret = TEE_SUCCESS;
+       uint32_t flags = TEE_DATA_FLAG_ACCESS_READ;
+       TEE_ObjectHandle hndl;
+       TEE_ObjectInfo info;
+       unsigned char *buffer = NULL;
+       uint32_t readBytes = 0;
+       ret = TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE, objId, objId_size, flags, &hndl);
+       if (TEE_SUCCESS != ret) {
+               LOG("TEE_OpenPersistentObject has failed with=%x.", ret);
+               return ret;
+       }
+
+       TEE_GetObjectInfo(hndl, &info);
+
+       if (info.dataSize != expected_data_size) {
+               LOG("TEE_GetObjectInfo has returned object with invalid data size; expected: %u, found: %u.",
+                       expected_data_size, info.dataSize);
+               TEE_CloseObject(hndl);
+               return TEE_ERROR_BAD_PARAMETERS;
+       }
+
+       buffer = (unsigned char*) data;
+
+       ret = TEE_ReadObjectData(hndl, buffer, info.dataSize, &readBytes);
+       if (TEE_SUCCESS != ret) {
+               LOG("TEE_ReadObjectData has failed with=%x.", ret);
+               TEE_CloseObject(hndl);
+               return ret;
+       }
+
+       TEE_CloseObject(hndl);
+
+       return ret;
+}
+
+TEE_Result KM_GetDataSize(uint32_t *data_size, void *objId, uint32_t objId_size)
+{
+       TEE_Result ret = TEE_SUCCESS;
+       uint32_t flags = TEE_DATA_FLAG_ACCESS_READ;
+       TEE_ObjectHandle hndl;
+       TEE_ObjectInfo info;
+       ret = TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE, objId, objId_size, flags, &hndl);
+       if (TEE_SUCCESS != ret) {
+               LOG("TEE_OpenPersistentObject has failed with=%x.", ret);
+               return ret;
+       }
+
+       TEE_GetObjectInfo(hndl, &info);
+       *data_size = info.dataSize;
+
+       TEE_CloseObject(hndl);
+
+       return ret;
+}
+
+void KM_DestroyData(void *objId, uint32_t objId_size)
+{
+       TEE_Result ret = TEE_SUCCESS;
+       TEE_ObjectHandle handl;
+
+       // open the object to check if it exists
+       ret = TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE, objId, objId_size,
+                                                               TEE_DATA_FLAG_ACCESS_WRITE_META, &handl);
+       if (ret != TEE_SUCCESS) {
+               if (ret == TEE_ERROR_ITEM_NOT_FOUND) {
+                       return;
+               }
+
+               LOG("Failed to open persistent object: %x", ret);
+               return;
+       }
+
+       TEE_CloseAndDeletePersistentObject(handl);
+}
index 252257d64081621c945680b1193c9e9b36b158b9..64759a0464085ac8d5c8b30481f3225b7c78c569 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2017 - 2018 Samsung Electronics Co., Ltd All Rights Reserved
  *
  *  Licensed under the Apache License, Version 2.0 (the "License");
  *  you may not use this file except in compliance with the License.
@@ -136,6 +136,26 @@ TEE_Result TA_InvokeCommandEntryPoint(
                ret = KM_ExecCmdDestroyKey(param);
                break;
        }
+       case CMD_IMPORT_DATA: {
+               LOGD("!!! Importing data to storage !!!");
+               ret = KM_ExecCmdSaveData(param);
+               break;
+       }
+       case CMD_GET_DATA_SIZE: {
+               LOGD("!!! Getting data size from storage !!!");
+               ret = KM_ExecCmdGetDataSize(param);
+               break;
+       }
+       case CMD_GET_DATA: {
+               LOGD("!!! Getting data from storage !!!");
+               ret = KM_ExecCmdGetData(param);
+               break;
+       }
+       case CMD_DESTROY_DATA: {
+               LOGD("!!! Destroying data from storage !!!");
+               ret = KM_ExecCmdDestroyData(param);
+               break;
+       }
        default: {
                LOG("Unknown commandID=%d.", commandID);
                ret = TEE_ERROR_BAD_PARAMETERS;