
#ifndef __GP_API_H__
#define __GP_API_H__

typedef union {
    struct {
        void* buffer;
        size_t size;
    } memref;

    struct {
        uint32_t a;
        uint32_t b;
    } value;
} TEE_Param;

#define TEE_PARAM_TYPES(t0, t1, t2, t3) \
    ((t0) | ((t1) << 4) | ((t2) << 8) | ((t3) << 12))

#define TA_EXPORT

/** Definition of an UUID (from RFC 4122 http://www.ietf.org/rfc/rfc4122.txt) */
typedef struct TEE_UUID {
    uint32_t timeLow;
    uint16_t timeMid;
    uint16_t timeHiAndVersion;
    uint8_t clockSeqAndNode[8];
} TEE_UUID;
typedef TEE_UUID TEEC_UUID;

typedef enum {
    TEE_MODE_ENCRYPT,
    TEE_MODE_DECRYPT,
    TEE_MODE_SIGN,
    TEE_MODE_VERIFY,
    TEE_MODE_MAC,
    TEE_MODE_DIGEST,
    TEE_MODE_DERIVE
} TEE_OperationMode;

typedef struct {
    uint32_t attributeID;
    union {
        struct {
            void* buffer;
            size_t length;
        } ref;
        struct {
            uint32_t a, b;
        } value;
    } content;
} TEE_Attribute;

typedef void* TEE_OperationHandle;
typedef void* TEE_ObjectHandle;

/*------------------------------------------------------------------------------
         Constants
------------------------------------------------------------------------------*/
#define TEE_MEMORY_ACCESS_READ           0x00000001
#define TEE_MEMORY_ACCESS_WRITE          0x00000002
#define TEE_MEMORY_ACCESS_ANY_OWNER      0x00000004

/* Allocation hints */
#define TEE_ALLOCATION_HINT_ZEROED       0x00000000

/* Parameter types */
#define TEE_PARAM_TYPE_NONE              0x0
#define TEE_PARAM_TYPE_VALUE_INPUT       0x1
#define TEE_PARAM_TYPE_VALUE_OUTPUT      0x2
#define TEE_PARAM_TYPE_VALUE_INOUT       0x3
#define TEE_PARAM_TYPE_MEMREF_INPUT      0x5
#define TEE_PARAM_TYPE_MEMREF_OUTPUT     0x6
#define TEE_PARAM_TYPE_MEMREF_INOUT      0x7

/* Crypto Algorithm Constants */
#define TEE_ALG_RSASSA_PKCS1_V1_5_SHA256 0x70004830
#define TEE_ALG_SHA1                     0x50000002
#define TEE_ALG_SHA256                   0x50000004

/* Storage ID Values */
#define TEE_STORAGE_PRIVATE              0x00000001

/* Data Flags */
#define TEE_DATA_FLAG_ACCESS_READ        0x00000001
#define TEE_DATA_FLAG_ACCESS_WRITE       0x00000002
#define TEE_DATA_FLAG_ACCESS_WRITE_META  0x00000004

//deprecated in gp1.1 specification
//#define TEE_DATA_FLAG_CREATE             0x00000200

/* Object Types */
#define TEE_TYPE_RSA_PUBLIC_KEY          0xA0000030
#define TEE_TYPE_RSA_KEYPAIR             0xA1000030

// Object or Operation Attributes
#define TEE_ATTR_RSA_MODULUS             0xD0000130
#define TEE_ATTR_RSA_PUBLIC_EXPONENT     0xD0000230
#define TEE_ATTR_RSA_PRIVATE_EXPONENT    0xC0000330

/*------------------------------------------------------------------------------
         Error codes
------------------------------------------------------------------------------*/
#define TEE_SUCCESS                      ((TEE_Result)0x00000000)

#define TEE_ERROR_CORRUPT_OBJECT         ((TEE_Result)0xF0100001)
#define TEE_ERROR_CORRUPT_OBJECT_2       ((TEE_Result)0xF0100002)

/**
 * Generic error code : Generic error
 **/
#define TEE_ERROR_GENERIC                ((TEE_Result)0xFFFF0000)

/**
 * Generic error code : The underlying security system denies the access to the
 * object
 **/
#define TEE_ERROR_ACCESS_DENIED          ((TEE_Result)0xFFFF0001)

/**
 * Generic error code : The pending operation is cancelled.
 **/
#define TEE_ERROR_CANCEL                 ((TEE_Result)0xFFFF0002)

/**
 * Generic error code : The underlying system detects a conflict
 **/
#define TEE_ERROR_ACCESS_CONFLICT        ((TEE_Result)0xFFFF0003)

/**
 * Generic error code : Too much data for the operation or some data remain
 * unprocessed by the operation.
 **/
#define TEE_ERROR_EXCESS_DATA            ((TEE_Result)0xFFFF0004)

/**
 * Generic error code : Error of data format
 **/
#define TEE_ERROR_BAD_FORMAT             ((TEE_Result)0xFFFF0005)

/**
 * Generic error code : The specified parameters are invalid
 **/
#define TEE_ERROR_BAD_PARAMETERS         ((TEE_Result)0xFFFF0006)


/**
 * Generic error code : Illegal state for the operation.
 **/
#define TEE_ERROR_BAD_STATE              ((TEE_Result)0xFFFF0007)

/**
 * Generic error code : The item is not found
 **/
#define TEE_ERROR_ITEM_NOT_FOUND         ((TEE_Result)0xFFFF0008)

/**
 * Generic error code : The specified operation is not implemented
 **/
#define TEE_ERROR_NOT_IMPLEMENTED        ((TEE_Result)0xFFFF0009)

/**
 * Generic error code : The specified operation is not supported
 **/
#define TEE_ERROR_NOT_SUPPORTED          ((TEE_Result)0xFFFF000A)

/**
 * Generic error code : Insufficient data is available for the operation.
 **/
#define TEE_ERROR_NO_DATA                ((TEE_Result)0xFFFF000B)

/**
 * Generic error code : Not enough memory to perform the operation
 **/
#define TEE_ERROR_OUT_OF_MEMORY          ((TEE_Result)0xFFFF000C)

/**
 * Generic error code : The service is currently unable to handle the request;
 * try later
 **/
#define TEE_ERROR_BUSY                   ((TEE_Result)0xFFFF000D)

/**
 * Generic communication error
 **/
#define TEE_ERROR_COMMUNICATION          ((TEE_Result)0xFFFF000E)

/**
 * Generic error code : security violation
 **/
#define TEE_ERROR_SECURITY               ((TEE_Result)0xFFFF000F)

/**
 * Generic error code : the buffer is too short
 **/
#define TEE_ERROR_SHORT_BUFFER           ((TEE_Result)0xFFFF0010)

/**
 * Generic error code : The pending operation is cancelled.
 */
#define TEE_ERROR_EXTERNAL_CANCEL        ((TEE_Result)0xFFFF0011)

/**
 * Generic error code : the operation is not terminated
 **/
#define TEE_PENDING                      ((TEE_Result)0xFFFF2000)

/**
 * Generic error code : A timeout occurred
 **/
#define TEE_ERROR_TIMEOUT                ((TEE_Result)0xFFFF3001)

/**
 * Generic error code : Overflow
 **/
#define TEE_ERROR_OVERFLOW               ((TEE_Result)0xFFFF300F)

/**
 * Error of communication: The target of the connection is dead
 **/
#define TEE_ERROR_TARGET_DEAD            ((TEE_Result)0xFFFF3024)

/*------------------------------------------------------------------------------
   Storage Error Codes
------------------------------------------------------------------------------*/

/** File system error code: not enough space to complete the operation. */
#define TEE_ERROR_STORAGE_NO_SPACE       ((TEE_Result)0xFFFF3041)

/*------------------------------------------------------------------------------
   Crypto error codes
------------------------------------------------------------------------------*/

#define TEE_ERROR_MAC_INVALID            ((TEE_Result)0xFFFF3071)

#define TEE_ERROR_SIGNATURE_INVALID      ((TEE_Result)0xFFFF3072)

/*------------------------------------------------------------------------------
   Date error codes
------------------------------------------------------------------------------*/

#define TEE_ERROR_TIME_NOT_SET           ((TEE_Result)0xFFFF5000)

#define TEE_ERROR_TIME_NEEDS_RESET       ((TEE_Result)0xFFFF5001)

/*------------------------------------------------------------------------------
         Functions
------------------------------------------------------------------------------*/
EXTERNC TEE_Result TEE_CheckMemoryAccessRights(
        uint32_t accessFlags,
        void* buffer, size_t size);

EXTERNC void TEE_Free(void* buffer);

EXTERNC TEE_Result TEE_AllocateOperation(
        TEE_OperationHandle* operation,
        uint32_t             algorithm,
        uint32_t             mode,
        uint32_t             maxKeySize);

EXTERNC void TEE_FreeOperation(TEE_OperationHandle operation);

EXTERNC TEE_Result TEE_SetOperationKey(
        TEE_OperationHandle operation,
        TEE_ObjectHandle    key);

EXTERNC void TEE_DigestUpdate(
        TEE_OperationHandle operation,
        void*               chunk,
        size_t              chunkSize);

EXTERNC TEE_Result TEE_DigestDoFinal(
        TEE_OperationHandle operation,
        void*               chunk,
        size_t              chunkLen,
        void*               hash,
        size_t*             hashLen);

EXTERNC TEE_Result TEE_AsymmetricEncrypt(
        TEE_OperationHandle operation,
        TEE_Attribute*      params,
        uint32_t            paramCount,
        void*               srcData,
        size_t              srcLen,
        void*               destData,
        size_t*             destLen);

EXTERNC TEE_Result TEE_AsymmetricDecrypt(
        TEE_OperationHandle operation,
        TEE_Attribute*      params,
        uint32_t            paramCount,
        void*               srcData,
        size_t              srcLen,
        void*               destData,
        size_t*             destLen);

EXTERNC TEE_Result TEE_AsymmetricSignDigest(
        TEE_OperationHandle operation,
        TEE_Attribute*      params,
        uint32_t            paramCount,
        void*               digest,
        size_t              digestLen,
        void*               signature,
        size_t*             signatureLen);

EXTERNC TEE_Result TEE_AsymmetricVerifyDigest(
        TEE_OperationHandle operation,
        TEE_Attribute*      params,
        uint32_t            paramCount,
        void*               digest,
        size_t              digestLen,
        void*               signature,
        size_t              signatureLen);

EXTERNC void TEE_GenerateRandom(
        void*  randomBuffer,
        size_t randomBufferLen);

EXTERNC TEE_Result TEE_GetObjectBufferAttribute(
        TEE_ObjectHandle object,
        uint32_t         attributeID,
        void*            buffer,
        size_t*          size);

EXTERNC void TEE_CloseObject(
        TEE_ObjectHandle object);

EXTERNC TEE_Result TEE_AllocateTransientObject(
        uint32_t          objectType,
        uint32_t          maxObjectSize,
        TEE_ObjectHandle* object);

EXTERNC void TEE_FreeTransientObject(
        TEE_ObjectHandle object);

EXTERNC TEE_Result TEE_PopulateTransientObject(
        TEE_ObjectHandle object,
        TEE_Attribute*   attrs,
        uint32_t         attrCount);

EXTERNC void TEE_InitRefAttribute(
        TEE_Attribute* attr,
        uint32_t       attributeID,
        void*          buffer,
        size_t         length);

EXTERNC TEE_Result TEE_GenerateKey(
        TEE_ObjectHandle object,
        uint32_t         keySize,
        TEE_Attribute*   params,
        uint32_t         paramCount);

EXTERNC TEE_Result TEE_CreatePersistentObject(
        uint32_t          storageID,
        void*             objectID,
        size_t            objectIDLen,
        uint32_t          flags,
        TEE_ObjectHandle  attributes,
        void*             initialData,
        size_t            initialDataLen,
        TEE_ObjectHandle* object);

EXTERNC TEE_Result TEE_OpenPersistentObject(
        uint32_t          storageID,
        void*             objectID,
        size_t            objectIDLen,
        uint32_t          flags,
        TEE_ObjectHandle* object);

EXTERNC void TEE_CloseAndDeletePersistentObject(TEE_ObjectHandle object);

EXTERNC TEE_Result TEE_ReadObjectData(
        TEE_ObjectHandle object,
        void*            buffer,
        size_t           size,
        uint32_t*        count);

EXTERNC TEE_Result TEE_WriteObjectData(
        TEE_ObjectHandle object,
        void*            buffer,
        size_t           size);

#endif // GP_API_H
