/**
* \file CommLayerData.h
* \brief Private defines and types. This file is shared between SWd and NWd.
* \author Dmytro Podgornyi (d.podgornyi@samsung.com)
* \version 0.1
* \date Created May 28, 2013
* \par In Samsung Ukraine R&D Center (SURC) under a contract between
* \par LLC "Samsung Electronics Ukraine Company" (Kiev, Ukraine) and
* \par "Samsung Elecrtronics Co", Ltd (Seoul, Republic of Korea)
* \par Copyright: (c) Samsung Electronics Co, Ltd 2012. All rights reserved.
**/

#ifndef __COMMLAYERDATA_H_INCLUDED__
#define __COMMLAYERDATA_H_INCLUDED__

#include "stdint.h"
#include "CommLayerDataPublic.h"

//// Sizes of data and limits
#define MAX_TRANSFER_SIZE 8192
#define MAX_FILE_PATH_LEN 256
#define MAX_TEXT_LINE 256
#define IV_SIZE 16
#define KEK_LENGTH 32
#define AES_256_KEY_SIZE 32
#define AES_128_KEY_SIZE 16
#define AES_GCM_TAG_SIZE 16
#define MAX_RSA_LEN 1300
#define MAX_SYM_KEY_LEN 32
#define MAX_RSA_CERT_LEN 1300
#define RSA_SIZE 256
#define RSA_EXPONENT 65537
#define HEADER_AND_MAC_LEN 116   // Must leave at least 144 extra bytes for the header and MAC, as per the API spec.
#define EC_KEY_BIT_SIZE 256
#define TIMESTAMP_LEN 15
#define BID_LEN 3
#define UID_SEPARATOR_LEN 1
#define IMEI_LEN	16
#define FACTORY_ID_LEN  16

#define TAG_FIELD_SIZE     0x01
#define LENGTH_FIELD_SIZE  0x02
#define TAGLENGTH_FIELD_SIZE (TAG_FIELD_SIZE + LENGTH_FIELD_SIZE)

//// Path on FS to acess files
#define PROV_DIR            "prov_data"

#define PROV_DIR_PATH       COMMON_DIR_PATH "/" PROV_DIR

#define DRK_DIR_PATH        PROV_DIR_PATH "/dev_root"
#define DRK_BLOB_PATH       DRK_DIR_PATH "/dev_root.dat"
#define DRK_KEYPAIR_PATH    DRK_DIR_PATH "/dev_root_key.dat"
#define SYMM_KEY_PATH       DRK_DIR_PATH "/sym_key.dat"
#define LOCK_FILE_PATH      COMMON_DIR_PATH "/prov/libdevkm.lock"

#include "PlatformConfig.h"
#include "SystemConfig.h"

#ifndef NWD_SYNC_DRIVER
    #define NWD_SYNC_DRIVER NWD_SYNC_DRIVER_NONE
#endif

/*******************************************
 * 
 * NWD-SWD Command list.
 *
 *******************************************/
// Install key. 
#define INSTALL_RSA_DRK_KEY_CMD        0x100
#define INSTALL_EC_DRK_KEY_CMD         0x101
#define INSTALL_SYMM_KEY_CMD           0x102
#define INSTALL_DRK_CERT_CMD           0x103
#define GENERATE_DRK_KEYPAIR_CMD       0x104

// Generate service key.
#define GENERATE_RSA_SERVICE_KEY_CMD   0x110
#define GENERATE_EC_SERVICE_KEY_CMD    0x111 // EC key will be signed by RSA if EC DRK is not exist
#define GENERATE_SYMM_SERVICE_KEY_CMD  0x112

// Verify keys.
#define VERIFY_RSA_DRK_CMD             0x120
#define VERIFY_EC_DRK_CMD              0x121
#define VERIFY_DRK_SYMM_KEY_CMD        0x122
#define VERIFY_RSA_SERVICE_KEY_CMD     0x123
#define VERIFY_EC_SERVICE_KEY_CMD      0x124
#define VERIFY_SYMM_SERVICE_KEY_CMD    0x125

// Special functions.
#define GET_DRK_UID_CMD                0x130
#define GET_ROOT_CA_PUBKEY_CMD         0x131
#define GET_DRK_CSR_CMD                0x132

// Only Qualcomm depened commands.
#define SHARE_DRK_CMD                  0x200
#define SHARE_SYMM_KEY_CMD             0x201
#define SHARE_SERVICE_KEY_CMD          0x202
#define IMPORT_DRK_KEY_CMD             0x203
#define IMPORT_SYMM_KEY_CMD            0x204
#define GET_ENCAPSULATED_KEY_SIZE      0x205
#define GET_ENCAPSULATED_KEY           0x206

// Test funtions.
#define GET_RAW_CERT_DEV_CMD           0x400
#define GET_RAW_PRIV_DEV_CMD           0x401
#define GET_RAW_CERT_SERVICE_CMD       0x402
#define GET_RAW_PRIV_SERVICE_CMD       0x403

//// NWD specific defines
/* timeout in milliseconds: how long to wait for SWD access before reportig
 * error */
#define NWD_SYNC_TIMEOUT 3000L

//// Certificate specific defines
/* time (in months) when certificate is valid   *
 * Note: Number of years should be rounded to 4 *
 * due to keep valid Feb 29 date in leap year   */
#define TIME_OF_CERT_USE (12 * 12)


/* Dual TA means existing of another copy of TA due to FOTA update performed */
typedef enum {
    SINGLE_TA,
    DUAL_TA,
    MAX_TA_SUPPORT_TYPE,
} teeTASupportType_t;

/* Type of FS logic used on TEE platform */
typedef enum
{
    USE_NWD_FS = 1,      // Save encryption key via APIs in normal world.
    USE_SFS,             // Save key via QCOM SFS
    USE_SHARED_SFS,      // Save key via QCOM SFS and DRK key is saved on Prov TA.
} teeFsType_t;

/* Forward declaration of TEE specific TA context */
typedef struct teeNativeHandle teeNativeHandle_t;

/* XXX: sizeof(cmd_req_t) must equal to sizeof(cmd_rsp_t) */
//// Request struct
typedef struct cmd_req
{
    uint32_t cmd_id;
    uint32_t dataLen;
    uint8_t data[MAX_TRANSFER_SIZE];
} cmd_req_t;

//// Response struct
typedef struct cmd_rsp
{
    int32_t status;
    uint32_t dataLen;
    uint8_t data[MAX_TRANSFER_SIZE];
} cmd_rsp_t;

#define GET_UINT16T_LE(N, ARR) (uint16_t) ( ((uint16_t)ARR[N]) | ((uint16_t)ARR[N + 1] << 8) )
/* set 16bit number and increment N */
#define SET_UINT16T_LE_INC(N, INTG, ARR) \
    do { \
        ARR[N++] = (uint8_t)((INTG) & 0xFF); \
        ARR[N++] = (uint8_t)(((INTG) >> 8) & 0xFF); \
    } while (0);


#define UNUSED(x) (void)x

//// Standard values if they aren't defined

#ifndef BOOL
typedef int BOOL;
#endif

#ifndef TRUE
#define TRUE 1
#endif

#ifndef FALSE
#define FALSE 0
#endif

#ifndef NULL
#define NULL ((void*)0)
#endif

#ifndef ARRAY_SIZE
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif

//// TESTS

/* Functional tests for SWd. If defined tests will be performed */
#if defined(DEBUG)
#define RUN_FUNC_TESTS
#endif

/* Build API for access to raw certificates and private keys.
 * It's used for certificate validation tests in NWd. Must be removed for
 * relese buidls */
/* XXX: Important: don't define it for release builds, may cause backdoors */
#ifndef DEBUG
#if defined(INCLUDE_RAW_ACCESSORS)
#error INVALID CONFIGURATION, INCLUDE_RAW_ACCESSORS must be set to FALSE
#endif
#endif

#define CHECK_NOT_ERROR(res) \
    if (res != NOT_ERROR) \
    { \
        LOGE("%s: res=%d", __FUNCTION__, res); \
        return res; \
    }

#define CHECK_DAEMON_ERROR(res) \
    if (res > 0) \
    { \
        LOGE("%s: this is error from cs daemon/client, not from libdevkm, %d", __FUNCTION__, res); \
        return SKM_DAEMON_ERROR; \
    }

#endif /* __COMMLAYERDATA_H_INCLUDED__ */
