summaryrefslogtreecommitdiff
path: root/lib/libutee/tee_api_objects.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libutee/tee_api_objects.c')
-rw-r--r--lib/libutee/tee_api_objects.c797
1 files changed, 797 insertions, 0 deletions
diff --git a/lib/libutee/tee_api_objects.c b/lib/libutee/tee_api_objects.c
new file mode 100644
index 0000000..93c204e
--- /dev/null
+++ b/lib/libutee/tee_api_objects.c
@@ -0,0 +1,797 @@
+/*
+ * Copyright (c) 2014, STMicroelectronics International N.V.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdlib.h>
+#include <string.h>
+
+#include <tee_api.h>
+#include <utee_syscalls.h>
+#include "tee_api_private.h"
+
+#define TEE_USAGE_DEFAULT 0xffffffff
+
+#define TEE_ATTR_BIT_VALUE (1 << 29)
+#define TEE_ATTR_BIT_PROTECTED (1 << 28)
+
+void __utee_from_attr(struct utee_attribute *ua, const TEE_Attribute *attrs,
+ uint32_t attr_count)
+{
+ size_t n;
+
+ for (n = 0; n < attr_count; n++) {
+ ua[n].attribute_id = attrs[n].attributeID;
+ if (attrs[n].attributeID & TEE_ATTR_BIT_VALUE) {
+ ua[n].a = attrs[n].content.value.a;
+ ua[n].b = attrs[n].content.value.b;
+ } else {
+ ua[n].a = (uintptr_t)attrs[n].content.ref.buffer;
+ ua[n].b = attrs[n].content.ref.length;
+ }
+ }
+}
+
+/* Data and Key Storage API - Generic Object Functions */
+/*
+ * Use of this function is deprecated
+ * new code SHOULD use the TEE_GetObjectInfo1 function instead
+ * These functions will be removed at some future major revision of
+ * this specification
+ */
+void TEE_GetObjectInfo(TEE_ObjectHandle object, TEE_ObjectInfo *objectInfo)
+{
+ TEE_Result res;
+
+ res = utee_cryp_obj_get_info((unsigned long)object, objectInfo);
+
+ if (res != TEE_SUCCESS)
+ TEE_Panic(res);
+
+ if (objectInfo->objectType == TEE_TYPE_CORRUPTED_OBJECT) {
+ objectInfo->keySize = 0;
+ objectInfo->maxKeySize = 0;
+ objectInfo->objectUsage = 0;
+ objectInfo->dataSize = 0;
+ objectInfo->dataPosition = 0;
+ objectInfo->handleFlags = 0;
+ }
+}
+
+TEE_Result TEE_GetObjectInfo1(TEE_ObjectHandle object, TEE_ObjectInfo *objectInfo)
+{
+ TEE_Result res;
+
+ res = utee_cryp_obj_get_info((unsigned long)object, objectInfo);
+
+ if (res != TEE_SUCCESS &&
+ res != TEE_ERROR_CORRUPT_OBJECT &&
+ res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
+ TEE_Panic(res);
+
+ return res;
+}
+
+/*
+ * Use of this function is deprecated
+ * new code SHOULD use the TEE_RestrictObjectUsage1 function instead
+ * These functions will be removed at some future major revision of
+ * this specification
+ */
+void TEE_RestrictObjectUsage(TEE_ObjectHandle object, uint32_t objectUsage)
+{
+ TEE_Result res;
+ TEE_ObjectInfo objectInfo;
+
+ res = utee_cryp_obj_get_info((unsigned long)object, &objectInfo);
+ if (objectInfo.objectType == TEE_TYPE_CORRUPTED_OBJECT)
+ return;
+
+ res = TEE_RestrictObjectUsage1(object, objectUsage);
+
+ if (res != TEE_SUCCESS)
+ TEE_Panic(res);
+}
+
+TEE_Result TEE_RestrictObjectUsage1(TEE_ObjectHandle object, uint32_t objectUsage)
+{
+ TEE_Result res;
+
+ res = utee_cryp_obj_restrict_usage((unsigned long)object, objectUsage);
+
+ if (res != TEE_SUCCESS &&
+ res != TEE_ERROR_CORRUPT_OBJECT &&
+ res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
+ TEE_Panic(res);
+
+ return res;
+}
+
+TEE_Result TEE_GetObjectBufferAttribute(TEE_ObjectHandle object,
+ uint32_t attributeID, void *buffer,
+ uint32_t *size)
+{
+ TEE_Result res;
+ TEE_ObjectInfo info;
+ uint64_t sz;
+
+ res = utee_cryp_obj_get_info((unsigned long)object, &info);
+ if (res != TEE_SUCCESS)
+ goto exit;
+
+ /* This function only supports reference attributes */
+ if ((attributeID & TEE_ATTR_BIT_VALUE)) {
+ res = TEE_ERROR_BAD_PARAMETERS;
+ goto exit;
+ }
+
+ sz = *size;
+ res = utee_cryp_obj_get_attr((unsigned long)object, attributeID,
+ buffer, &sz);
+ *size = sz;
+
+exit:
+ if (res != TEE_SUCCESS &&
+ res != TEE_ERROR_ITEM_NOT_FOUND &&
+ res != TEE_ERROR_SHORT_BUFFER &&
+ res != TEE_ERROR_CORRUPT_OBJECT &&
+ res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
+ TEE_Panic(res);
+
+ return res;
+}
+
+TEE_Result TEE_GetObjectValueAttribute(TEE_ObjectHandle object,
+ uint32_t attributeID, uint32_t *a,
+ uint32_t *b)
+{
+ TEE_Result res;
+ TEE_ObjectInfo info;
+ uint32_t buf[2];
+ uint64_t size = sizeof(buf);
+
+ res = utee_cryp_obj_get_info((unsigned long)object, &info);
+ if (res != TEE_SUCCESS)
+ goto exit;
+
+ /* This function only supports value attributes */
+ if (!(attributeID & TEE_ATTR_BIT_VALUE)) {
+ res = TEE_ERROR_BAD_PARAMETERS;
+ goto exit;
+ }
+
+ res = utee_cryp_obj_get_attr((unsigned long)object, attributeID, buf,
+ &size);
+
+exit:
+ if (res != TEE_SUCCESS &&
+ res != TEE_ERROR_ITEM_NOT_FOUND &&
+ res != TEE_ERROR_CORRUPT_OBJECT &&
+ res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
+ TEE_Panic(res);
+
+ if (size != sizeof(buf))
+ TEE_Panic(0);
+
+ if (res == TEE_SUCCESS) {
+ if (a)
+ *a = buf[0];
+ if (b)
+ *b = buf[1];
+ }
+
+ return res;
+}
+
+void TEE_CloseObject(TEE_ObjectHandle object)
+{
+ TEE_Result res;
+
+ if (object == TEE_HANDLE_NULL)
+ return;
+
+ res = utee_cryp_obj_close((unsigned long)object);
+ if (res != TEE_SUCCESS)
+ TEE_Panic(res);
+}
+
+/* Data and Key Storage API - Transient Object Functions */
+
+TEE_Result TEE_AllocateTransientObject(TEE_ObjectType objectType,
+ uint32_t maxKeySize,
+ TEE_ObjectHandle *object)
+{
+ TEE_Result res;
+ uint32_t obj;
+
+ res = utee_cryp_obj_alloc(objectType, maxKeySize, &obj);
+
+ if (res != TEE_SUCCESS &&
+ res != TEE_ERROR_OUT_OF_MEMORY &&
+ res != TEE_ERROR_NOT_SUPPORTED)
+ TEE_Panic(res);
+
+ if (res == TEE_SUCCESS)
+ *object = (TEE_ObjectHandle)(uintptr_t)obj;
+
+ return res;
+}
+
+void TEE_FreeTransientObject(TEE_ObjectHandle object)
+{
+ TEE_Result res;
+ TEE_ObjectInfo info;
+
+ if (object == TEE_HANDLE_NULL)
+ return;
+
+ res = utee_cryp_obj_get_info((unsigned long)object, &info);
+ if (res != TEE_SUCCESS)
+ TEE_Panic(res);
+
+ if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
+ TEE_Panic(0);
+
+ res = utee_cryp_obj_close((unsigned long)object);
+ if (res != TEE_SUCCESS)
+ TEE_Panic(res);
+}
+
+void TEE_ResetTransientObject(TEE_ObjectHandle object)
+{
+ TEE_Result res;
+ TEE_ObjectInfo info;
+
+ if (object == TEE_HANDLE_NULL)
+ return;
+
+ res = utee_cryp_obj_get_info((unsigned long)object, &info);
+ if (res != TEE_SUCCESS)
+ TEE_Panic(res);
+
+ if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
+ TEE_Panic(0);
+
+ res = utee_cryp_obj_reset((unsigned long)object);
+ if (res != TEE_SUCCESS)
+ TEE_Panic(res);
+}
+
+TEE_Result TEE_PopulateTransientObject(TEE_ObjectHandle object,
+ const TEE_Attribute *attrs,
+ uint32_t attrCount)
+{
+ TEE_Result res;
+ TEE_ObjectInfo info;
+ struct utee_attribute ua[attrCount];
+
+ res = utee_cryp_obj_get_info((unsigned long)object, &info);
+ if (res != TEE_SUCCESS)
+ TEE_Panic(res);
+
+ /* Must be a transient object */
+ if ((info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT) != 0)
+ TEE_Panic(0);
+
+ /* Must not be initialized already */
+ if ((info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED) != 0)
+ TEE_Panic(0);
+
+ __utee_from_attr(ua, attrs, attrCount);
+ res = utee_cryp_obj_populate((unsigned long)object, ua, attrCount);
+ if (res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS)
+ TEE_Panic(res);
+ return res;
+}
+
+void TEE_InitRefAttribute(TEE_Attribute *attr, uint32_t attributeID,
+ const void *buffer, uint32_t length)
+{
+ if (attr == NULL)
+ TEE_Panic(0);
+ if ((attributeID & TEE_ATTR_BIT_VALUE) != 0)
+ TEE_Panic(0);
+ attr->attributeID = attributeID;
+ attr->content.ref.buffer = (void *)buffer;
+ attr->content.ref.length = length;
+}
+
+void TEE_InitValueAttribute(TEE_Attribute *attr, uint32_t attributeID,
+ uint32_t a, uint32_t b)
+{
+ if (attr == NULL)
+ TEE_Panic(0);
+ if ((attributeID & TEE_ATTR_BIT_VALUE) == 0)
+ TEE_Panic(0);
+ attr->attributeID = attributeID;
+ attr->content.value.a = a;
+ attr->content.value.b = b;
+}
+
+/*
+ * Use of this function is deprecated
+ * new code SHOULD use the TEE_CopyObjectAttributes1 function instead
+ * These functions will be removed at some future major revision of
+ * this specification
+ */
+void TEE_CopyObjectAttributes(TEE_ObjectHandle destObject,
+ TEE_ObjectHandle srcObject)
+{
+ TEE_Result res;
+ TEE_ObjectInfo src_info;
+
+ res = utee_cryp_obj_get_info((unsigned long)srcObject, &src_info);
+ if (src_info.objectType == TEE_TYPE_CORRUPTED_OBJECT)
+ return;
+
+ res = TEE_CopyObjectAttributes1(destObject, srcObject);
+ if (res != TEE_SUCCESS)
+ TEE_Panic(res);
+}
+
+TEE_Result TEE_CopyObjectAttributes1(TEE_ObjectHandle destObject,
+ TEE_ObjectHandle srcObject)
+{
+ TEE_Result res;
+ TEE_ObjectInfo dst_info;
+ TEE_ObjectInfo src_info;
+
+ res = utee_cryp_obj_get_info((unsigned long)destObject, &dst_info);
+ if (res != TEE_SUCCESS)
+ goto exit;
+
+ res = utee_cryp_obj_get_info((unsigned long)srcObject, &src_info);
+ if (res != TEE_SUCCESS)
+ goto exit;
+
+ if (!(src_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED))
+ TEE_Panic(0);
+
+ if ((dst_info.handleFlags & TEE_HANDLE_FLAG_PERSISTENT))
+ TEE_Panic(0);
+
+ if ((dst_info.handleFlags & TEE_HANDLE_FLAG_INITIALIZED))
+ TEE_Panic(0);
+
+ res = utee_cryp_obj_copy((unsigned long)destObject,
+ (unsigned long)srcObject);
+
+exit:
+ if (res != TEE_SUCCESS &&
+ res != TEE_ERROR_CORRUPT_OBJECT &&
+ res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
+ TEE_Panic(res);
+
+ return res;
+}
+
+TEE_Result TEE_GenerateKey(TEE_ObjectHandle object, uint32_t keySize,
+ const TEE_Attribute *params, uint32_t paramCount)
+{
+ TEE_Result res;
+ struct utee_attribute ua[paramCount];
+
+ __utee_from_attr(ua, params, paramCount);
+ res = utee_cryp_obj_generate_key((unsigned long)object, keySize,
+ ua, paramCount);
+
+ if (res != TEE_SUCCESS && res != TEE_ERROR_BAD_PARAMETERS)
+ TEE_Panic(res);
+
+ return res;
+}
+
+/* Data and Key Storage API - Persistent Object Functions */
+
+TEE_Result TEE_OpenPersistentObject(uint32_t storageID, const void *objectID,
+ uint32_t objectIDLen, uint32_t flags,
+ TEE_ObjectHandle *object)
+{
+ TEE_Result res;
+ uint32_t obj;
+
+ if (!objectID) {
+ res = TEE_ERROR_ITEM_NOT_FOUND;
+ goto out;
+ }
+
+ if (objectIDLen > TEE_OBJECT_ID_MAX_LEN) {
+ res = TEE_ERROR_BAD_PARAMETERS;
+ goto out;
+ }
+
+ if (!object) {
+ res = TEE_ERROR_BAD_PARAMETERS;
+ goto out;
+ }
+
+ res = utee_storage_obj_open(storageID, objectID, objectIDLen, flags,
+ &obj);
+ if (res == TEE_SUCCESS)
+ *object = (TEE_ObjectHandle)(uintptr_t)obj;
+
+out:
+ if (res != TEE_SUCCESS &&
+ res != TEE_ERROR_ITEM_NOT_FOUND &&
+ res != TEE_ERROR_ACCESS_CONFLICT &&
+ res != TEE_ERROR_OUT_OF_MEMORY &&
+ res != TEE_ERROR_CORRUPT_OBJECT &&
+ res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
+ TEE_Panic(res);
+
+ return res;
+}
+
+TEE_Result TEE_CreatePersistentObject(uint32_t storageID, const void *objectID,
+ uint32_t objectIDLen, uint32_t flags,
+ TEE_ObjectHandle attributes,
+ const void *initialData,
+ uint32_t initialDataLen,
+ TEE_ObjectHandle *object)
+{
+ TEE_Result res;
+ uint32_t obj;
+
+ if (!objectID) {
+ res = TEE_ERROR_ITEM_NOT_FOUND;
+ goto err;
+ }
+
+ if (objectIDLen > TEE_OBJECT_ID_MAX_LEN) {
+ res = TEE_ERROR_BAD_PARAMETERS;
+ goto err;
+ }
+
+ res = utee_storage_obj_create(storageID, objectID, objectIDLen, flags,
+ (unsigned long)attributes, initialData,
+ initialDataLen, &obj);
+ if (res == TEE_SUCCESS) {
+ if (object)
+ *object = (TEE_ObjectHandle)(uintptr_t)obj;
+ else
+ res = utee_cryp_obj_close(obj);
+ if (res == TEE_SUCCESS)
+ goto out;
+ }
+err:
+ if (object)
+ *object = TEE_HANDLE_NULL;
+ if (res == TEE_ERROR_ITEM_NOT_FOUND ||
+ res == TEE_ERROR_ACCESS_CONFLICT ||
+ res == TEE_ERROR_OUT_OF_MEMORY ||
+ res == TEE_ERROR_STORAGE_NO_SPACE ||
+ res == TEE_ERROR_CORRUPT_OBJECT ||
+ res == TEE_ERROR_STORAGE_NOT_AVAILABLE)
+ return res;
+ TEE_Panic(res);
+out:
+ return TEE_SUCCESS;
+}
+
+/*
+ * Use of this function is deprecated
+ * new code SHOULD use the TEE_CloseAndDeletePersistentObject1 function instead
+ * These functions will be removed at some future major revision of
+ * this specification
+ */
+void TEE_CloseAndDeletePersistentObject(TEE_ObjectHandle object)
+{
+ TEE_Result res;
+
+ if (object == TEE_HANDLE_NULL)
+ return;
+
+ res = TEE_CloseAndDeletePersistentObject1(object);
+
+ if (res != TEE_SUCCESS)
+ TEE_Panic(0);
+}
+
+TEE_Result TEE_CloseAndDeletePersistentObject1(TEE_ObjectHandle object)
+{
+ TEE_Result res;
+
+ if (object == TEE_HANDLE_NULL)
+ return TEE_ERROR_STORAGE_NOT_AVAILABLE;
+
+ res = utee_storage_obj_del((unsigned long)object);
+
+ if (res != TEE_SUCCESS && res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
+ TEE_Panic(res);
+
+ return res;
+}
+
+
+TEE_Result TEE_RenamePersistentObject(TEE_ObjectHandle object,
+ const void *newObjectID,
+ uint32_t newObjectIDLen)
+{
+ TEE_Result res;
+
+ if (object == TEE_HANDLE_NULL) {
+ res = TEE_ERROR_ITEM_NOT_FOUND;
+ goto out;
+ }
+
+ if (!newObjectID) {
+ res = TEE_ERROR_BAD_PARAMETERS;
+ goto out;
+ }
+
+ if (newObjectIDLen > TEE_OBJECT_ID_MAX_LEN) {
+ res = TEE_ERROR_BAD_PARAMETERS;
+ goto out;
+ }
+
+ res = utee_storage_obj_rename((unsigned long)object, newObjectID,
+ newObjectIDLen);
+
+out:
+ if (res != TEE_SUCCESS &&
+ res != TEE_ERROR_ACCESS_CONFLICT &&
+ res != TEE_ERROR_CORRUPT_OBJECT &&
+ res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
+ TEE_Panic(res);
+
+ return res;
+}
+
+TEE_Result TEE_AllocatePersistentObjectEnumerator(TEE_ObjectEnumHandle *
+ objectEnumerator)
+{
+ TEE_Result res;
+ uint32_t oe;
+
+ if (!objectEnumerator)
+ return TEE_ERROR_BAD_PARAMETERS;
+
+ res = utee_storage_alloc_enum(&oe);
+
+ if (res != TEE_SUCCESS)
+ oe = TEE_HANDLE_NULL;
+
+ *objectEnumerator = (TEE_ObjectEnumHandle)(uintptr_t)oe;
+
+ if (res != TEE_SUCCESS &&
+ res != TEE_ERROR_ACCESS_CONFLICT)
+ TEE_Panic(res);
+
+ return res;
+}
+
+void TEE_FreePersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator)
+{
+ TEE_Result res;
+
+ if (objectEnumerator == TEE_HANDLE_NULL)
+ return;
+
+ res = utee_storage_free_enum((unsigned long)objectEnumerator);
+
+ if (res != TEE_SUCCESS)
+ TEE_Panic(res);
+}
+
+void TEE_ResetPersistentObjectEnumerator(TEE_ObjectEnumHandle objectEnumerator)
+{
+ TEE_Result res;
+
+ if (objectEnumerator == TEE_HANDLE_NULL)
+ return;
+
+ res = utee_storage_reset_enum((unsigned long)objectEnumerator);
+
+ if (res != TEE_SUCCESS)
+ TEE_Panic(res);
+}
+
+TEE_Result TEE_StartPersistentObjectEnumerator(TEE_ObjectEnumHandle
+ objectEnumerator,
+ uint32_t storageID)
+{
+ TEE_Result res;
+
+ res = utee_storage_start_enum((unsigned long)objectEnumerator,
+ storageID);
+
+ if (res != TEE_SUCCESS &&
+ res != TEE_ERROR_ITEM_NOT_FOUND &&
+ res != TEE_ERROR_CORRUPT_OBJECT &&
+ res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
+ TEE_Panic(res);
+
+ return res;
+}
+
+TEE_Result TEE_GetNextPersistentObject(TEE_ObjectEnumHandle objectEnumerator,
+ TEE_ObjectInfo *objectInfo,
+ void *objectID, uint32_t *objectIDLen)
+{
+ TEE_Result res;
+ uint64_t len;
+ TEE_ObjectInfo local_info;
+ TEE_ObjectInfo *pt_info;
+
+ if (!objectID) {
+ res = TEE_ERROR_BAD_PARAMETERS;
+ goto out;
+ }
+
+ if (!objectIDLen) {
+ res = TEE_ERROR_BAD_PARAMETERS;
+ goto out;
+ }
+
+ if (objectInfo)
+ pt_info = objectInfo;
+ else
+ pt_info = &local_info;
+ len = *objectIDLen;
+ res = utee_storage_next_enum((unsigned long)objectEnumerator,
+ pt_info, objectID, &len);
+ *objectIDLen = len;
+
+out:
+ if (res != TEE_SUCCESS &&
+ res != TEE_ERROR_ITEM_NOT_FOUND &&
+ res != TEE_ERROR_CORRUPT_OBJECT &&
+ res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
+ TEE_Panic(res);
+
+ return res;
+}
+
+/* Data and Key Storage API - Data Stream Access Functions */
+
+TEE_Result TEE_ReadObjectData(TEE_ObjectHandle object, void *buffer,
+ uint32_t size, uint32_t *count)
+{
+ TEE_Result res;
+ uint64_t cnt64;
+
+ if (object == TEE_HANDLE_NULL) {
+ res = TEE_ERROR_BAD_PARAMETERS;
+ goto out;
+ }
+
+ cnt64 = *count;
+ res = utee_storage_obj_read((unsigned long)object, buffer, size,
+ &cnt64);
+ *count = cnt64;
+
+out:
+ if (res != TEE_SUCCESS &&
+ res != TEE_ERROR_CORRUPT_OBJECT &&
+ res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
+ TEE_Panic(res);
+
+ return res;
+}
+
+TEE_Result TEE_WriteObjectData(TEE_ObjectHandle object, const void *buffer,
+ uint32_t size)
+{
+ TEE_Result res;
+
+ if (object == TEE_HANDLE_NULL) {
+ res = TEE_ERROR_BAD_PARAMETERS;
+ goto out;
+ }
+
+ if (size > TEE_DATA_MAX_POSITION) {
+ res = TEE_ERROR_OVERFLOW;
+ goto out;
+ }
+
+ res = utee_storage_obj_write((unsigned long)object, buffer, size);
+
+out:
+ if (res != TEE_SUCCESS &&
+ res != TEE_ERROR_STORAGE_NO_SPACE &&
+ res != TEE_ERROR_OVERFLOW &&
+ res != TEE_ERROR_CORRUPT_OBJECT &&
+ res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
+ TEE_Panic(res);
+
+ return res;
+}
+
+TEE_Result TEE_TruncateObjectData(TEE_ObjectHandle object, uint32_t size)
+{
+ TEE_Result res;
+
+ if (object == TEE_HANDLE_NULL) {
+ res = TEE_ERROR_BAD_PARAMETERS;
+ goto out;
+ }
+
+ res = utee_storage_obj_trunc((unsigned long)object, size);
+
+out:
+ if (res != TEE_SUCCESS &&
+ res != TEE_ERROR_STORAGE_NO_SPACE &&
+ res != TEE_ERROR_CORRUPT_OBJECT &&
+ res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
+ TEE_Panic(res);
+
+ return res;
+}
+
+TEE_Result TEE_SeekObjectData(TEE_ObjectHandle object, int32_t offset,
+ TEE_Whence whence)
+{
+ TEE_Result res;
+ TEE_ObjectInfo info;
+
+ if (object == TEE_HANDLE_NULL) {
+ res = TEE_ERROR_BAD_PARAMETERS;
+ goto out;
+ }
+
+ res = utee_cryp_obj_get_info((unsigned long)object, &info);
+ if (res != TEE_SUCCESS)
+ goto out;
+
+ switch (whence) {
+ case TEE_DATA_SEEK_SET:
+ if (offset > 0 && (uint32_t)offset > TEE_DATA_MAX_POSITION) {
+ res = TEE_ERROR_OVERFLOW;
+ goto out;
+ }
+ break;
+ case TEE_DATA_SEEK_CUR:
+ if (offset > 0 &&
+ ((uint32_t)offset + info.dataPosition >
+ TEE_DATA_MAX_POSITION ||
+ (uint32_t)offset + info.dataPosition <
+ info.dataPosition)) {
+ res = TEE_ERROR_OVERFLOW;
+ goto out;
+ }
+ break;
+ case TEE_DATA_SEEK_END:
+ if (offset > 0 &&
+ ((uint32_t)offset + info.dataSize > TEE_DATA_MAX_POSITION ||
+ (uint32_t)offset + info.dataSize < info.dataSize)) {
+ res = TEE_ERROR_OVERFLOW;
+ goto out;
+ }
+ break;
+ default:
+ res = TEE_ERROR_ITEM_NOT_FOUND;
+ goto out;
+ }
+
+ res = utee_storage_obj_seek((unsigned long)object, offset, whence);
+
+out:
+ if (res != TEE_SUCCESS &&
+ res != TEE_ERROR_OVERFLOW &&
+ res != TEE_ERROR_CORRUPT_OBJECT &&
+ res != TEE_ERROR_STORAGE_NOT_AVAILABLE)
+ TEE_Panic(res);
+
+ return res;
+}