
/*
 * =====================================================================================
 *
 *       Filename:  hdm_drk.h
 *
 *    Description:  HDM definitions for DRK manipulation
 *
 *        Version:  1.0
 *        Created:  09/16/2019 15:26:11 PM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *        Company:  Samsung Electronics
 *        Copyright (c) 2015 by Samsung Electronics, All rights reserved.
 *
 * =====================================================================================
 */

#ifndef _HDM_DRK_H
#define _HDM_DRK_H

/**
 * HDM includes
 */
#include "tz_hdm_interface.h"
#include "hdm_defs.h"
#include "hdm_hash.h"

/**
 * External includes
 */
#include "openssl/bio.h"
#include "openssl/pem.h"

/**
 * DRKv2 certificate tags
 */
#define DRK_CERT_KEY_TYPE_RSA_CERT        0x01
#define DRK_CERT_KEY_TYPE_RSA_PRIVATE     0x03
#define DRK_CERT_KEY_TYPE_TL_NAME         0x04

/**
 * DRKv2 certificate UID field tags
 */
#define DRK_V2_CERTIFICATE_UID_DRK_TAG    "DRK_V2"
#define DRK_V2_CERTIFICATE_UID_SEPARATOR  ':'

/**
 * Lengths
 */
#define RESPONSE_SIGNATURE_LEN  256

/**
 * DRKv2 certificates chain
 */
#define DRK_CERT_MAX_CERTS	      3
#define DRK_CERT_MAX_CERT_LENGTH  2500

/**
 * Check uint
 */
#define CHECK_UINT_BEFORE_ADD(a, b) ((((a) + (b)) >= a) ? 1 : 0)
#define CHECK_UINT_BEFORE_SUB(a, b) ((a) > (b) ? 1 : 0)

/**
 * DRK RSA private key
 */
typedef struct{
        uint8_t *modulus;
        uint32_t modulus_len;
        uint8_t *priv_expo;
        uint32_t priv_expo_len;
        uint8_t *pub_expo;
        uint32_t pub_expo_len;
} drk_rsa_private_key_t;

/**
 * DRK certificates chain
 */
typedef struct{
        uint8_t certificate[DRK_CERT_MAX_CERT_LENGTH];
        uint32_t certificate_len;
} drk_cert_chain_t;

/**
 * DRK parsed object
 */
typedef struct{
        drk_cert_chain_t drk_cert_chain[DRK_CERT_MAX_CERTS];
        uint32_t num_certificates;
        drk_rsa_private_key_t drk_rsa_private_key;
} drk_parsed_object_t;

/**
 * @brief
 * get_b64_hash
 * Parse Unwrap object(DRK) and get b64 from DRK (b64( H( H(IMEI) | H(SERIAL))))
 *
 * @param[in]      *unwrap_object   - pointer to DRK unwrap object
 * @param[in]       unwrap_len      - length of unwrap object
 * @param[in/out]   b64_IMEI_SERIAL - pointer to b64_IMEI_SERIAL / b64_IMEI_SERIAL value
 *
 * @return HDM status code
 */
hdm_return_code_t get_b64_hash(uint8_t *unwrap_object, int unwrap_len, char *b64_IMEI_SERIAL);

/**
 * @brief
 * get_cert_chain_rsakey
 * Parse Unwrap object(DRK) and get certificate chain and pvt key from DRK
 *
 * @param[in]      *unwrap_object     - pointer to DRK unwrap object
 * @param[in]       unwrap_len        - length of unwrap object
 * @param[in/out]   drk_parsed_object - pointer to drk_parsed_object / drk_parsed_object value
 *
 * @return HDM status code
 */
hdm_return_code_t get_cert_chain_rsakey(uint8_t *unwrap_object, int unwrap_len, drk_parsed_object_t *drk_parsed_object);

/**
 * @brief
 * validate_drk_device_id
 *
 * @param[in]      unwrapped_drk_id   - unwrapped DRK device id
 * @param[in]      nwd_info           - info from the NWd
 *
 * @return HDM status code
 */
hdm_return_code_t validate_drk_device_id(uint8_t *unwrapped_drk_id, hdm_nwd_info_t *nwd_info);
#endif /* _HDM_DRK_H */
