
/*
 * =====================================================================================
 *
 *       Filename:  pebble_defs.h
 *
 *    Description:  PEBBLE internal definitions
 *
 *        Version:  1.0
 *        Created:  06/02/2020
 *       Revision:  none
 *       Compiler:  gcc
 *
 *        Company:  Samsung Electronics
 *        Copyright (c) 2020 by Samsung Electronics, All rights reserved.
 *
 * =====================================================================================
 */

#ifndef _PEBBLE_DEFS_H_
#define _PEBBLE_DEFS_H_

/**
 * Custom QCOM includes
 */
#ifdef CONFIG_QSEE
#include <qsee_log.h>
#endif

/**
 * External includes
 */
#include <stdio.h>
#include "string.h"
#include "tee_internal_api.h"
#include <openssl/sha.h>

/**
 * PEBBLE Logging
 */
#define	LOG_ENTRY_SIZE	128
#define	LOG_MSG_SIZE	(LOG_ENTRY_SIZE - sizeof(uint32_t) - sizeof(uint32_t))
#define TAG "TA_PEBBLE : "

/**
 * JWS lengths
 */
#define HEADER_LEN    6144
#define PAYLOAD_LEN   2048
#define SIGNATURE_LEN 2048

/**
 * PEBBLE Fixed Values
 */
#define PEBBLE_MAGIC               0x87000111
#define PEBBLE_DEFAULT_POLICY      0x00000001
#define PEBBLE_ALLOW_ALL_POLICY    0x00000000
#define PEBBLE_STATUS_ALLOW_ALL    0x00000000
#define PEBBLE_STATUS_BLOCKED      0x00000001
#define JWS_RESPONSE_ALG_VALUE  "RS256"
#define DEVICE_ID_B64_LEN       44
#define MAX_INT32_CHARACTERS    11
#define PEBBLE_PROTOCOL_VERSION    "1.0"

/**
 * JWS header tags
 */
#define JWS_HEADER_SERVICE_NAME      "serviceName"
#define JWS_HEADER_ALG               "alg"
#define JWS_HEADER_PROTOCOL_VERSION  "protocolVersion"
#define JWS_HEADER_X5C               "x5c"
#define JWS_HEADER_REQ_ID            "requestId"

/**
 * JWS payload tags
 */
#define JWS_PAYLOAD_PEBBLE_ID            "pebbleId"
#define JWS_PAYLOAD_DEVICE_ID         "deviceId"
#define JWS_PAYLOAD_DEVICE_BLOCK      "deviceBlock"
#define JWS_PAYLOAD_COMPROMISE_BLOCK  "compromiseBlock"
#define JWS_PAYLOAD_POLICY_VERSION    "policyVersion"
#define JWS_PAYLOAD_RESULT_CODE       "resultCode"
#define JWS_PAYLOAD_RESULT_MSG        "resultMessage"
#define JWS_PAYLOAD_APPLIED_POLICY    "appliedPolicy"

/**
 * JWS header length
 */
#define JWS_HEADER_SERVICE_NAME_LEN           40
#define JWS_HEADER_ALG_LEN                    20
#define JWS_HEADER_PROTOCOL_VERSION_LEN       11
#define JWS_HEADER_X5C_LEN                    5000
#define JWS_HEADER_X5C_NUM                    3
#define JWS_HEADER_REQ_ID_LEN                 37

/**
 * JWS payload length
 */
#define JWS_PAYLOAD_DEVICE_ID_LEN   45 // sha256 hash in hex chars + '\0'

/**
 * PEBBLE JWS
 */
typedef struct {
        uint32_t header_len;
        uint8_t header[HEADER_LEN];
        uint32_t payload_len;
        uint8_t payload[PAYLOAD_LEN];
        uint32_t signature_len;
        uint8_t signature[SIGNATURE_LEN];
} tz_pebble_jws_t;

/**
 * PEBBLE JWS header x5c certificate chain
 */
typedef struct {
        int32_t certificate_len;
        uint8_t certificate[JWS_HEADER_X5C_LEN];
} __attribute__ ((packed)) tz_pebble_header_x5c_t;

/**
 * PEBBLE JWS header
 */
typedef struct tz_pebble_header {
        uint8_t service_name[JWS_HEADER_SERVICE_NAME_LEN];
        uint8_t request_id[JWS_HEADER_REQ_ID_LEN];
        uint8_t alg[JWS_HEADER_ALG_LEN];
        uint8_t protocol_version[JWS_HEADER_PROTOCOL_VERSION_LEN];
        uint32_t x5c_count;
        tz_pebble_header_x5c_t x5c[JWS_HEADER_X5C_NUM];
}__attribute__ ((packed)) tz_pebble_header_t;

/**
 * PEBBLE JWS payload
 */
typedef struct {
        uint32_t device_block;
        uint32_t compromise_block;
        uint32_t policy_version;
        uint8_t  device_id[JWS_PAYLOAD_DEVICE_ID_LEN];
} __attribute__ ((packed)) tz_pebble_payload_t;

/**
 * PEBBLE Signature
 */
typedef struct {
        uint32_t signature_len;
        uint8_t signature[SIGNATURE_LEN];
} __attribute__ ((packed)) tz_pebble_signature_t;

/**
 * PEBBLE Global JWS
 */
tz_pebble_header_t    header;
tz_pebble_payload_t   payload;
tz_pebble_signature_t signature;
uint32_t current_service_index;

/**
 * Possible values:
 * - PEBBLE_DEVICE_OK
 * - PEBBLE_DEVICE_COMPROMISED
 * - PEBBLE_APPLY_DEFAULT_POLICY
 */
uint32_t device_status;

/**
 * Logging
 */
char pebble_log_msg[LOG_MSG_SIZE];

#ifdef CONFIG_QSEE
#define PEBBLE_LOG(...)    do {                                     \
        snprintf(pebble_log_msg, LOG_MSG_SIZE - 1, TAG __VA_ARGS__); \
        pebble_log_msg[LOG_MSG_SIZE - 1] = '\0';                      \
        qsee_log(QSEE_LOG_MSG_ERROR, pebble_log_msg);                  \
} while(0);
#else
#define PEBBLE_LOG(...)    do {                                     \
        snprintf(pebble_log_msg, LOG_MSG_SIZE - 1, TAG __VA_ARGS__); \
        pebble_log_msg[LOG_MSG_SIZE - 1] = '\0';                      \
        printf(pebble_log_msg);                                        \
        printf("\n");                                                \
} while(0);
#endif

/**
 * Remove below comment for debugging logs
 */
#define DEBUG_PEBBLE

/**
 * Debugging
 */
#ifdef DEBUG_PEBBLE
#define PEBBLE_LOG_DEBUG(...) PEBBLE_LOG(__VA_ARGS__)
#else
#define PEBBLE_LOG_DEBUG(...)
#endif

#endif /* _PEBBLE_DEFS_H_ */
