/*
 * Copyright (C) 2016 Samsung Electronics. Co. Ltd,
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef __SKPM_H__
#define __SKPM_H__

#include "tz_log.h"
#include "platform.h"

#define WRAPPED_SERVICE_KEY_BLOB_SIZE           7000
#define WRAPPED_MAX_LEAF_KEY_BLOB_SIZE          2000
#define WRAPPED_KEY_INFO_SIZE                   10000
#define MAX_CERT_SIZE                           2048
#define MAX_SIGNATURE_INPUT_SIZE                100
#define MAX_SIGNATURE_SIZE                      300

/**
 * Key injection type
*/
#define INJECTION_TYPE_FACTORY                  0x01
#define INJECTION_TYPE_OTA_CSR                  0x02
#define INJECTION_TYPE_OTA_WB                   0x04

/**
 * Key type
*/
#define KEY_TYPE_ECC_P256                       0x01
#define KEY_TYPE_RSA_2048                       0x02

/**
 * Cert type
*/
#define CERT_TYPE_X509                          0x01
#define CERT_TYPE_CASD                          0x02
#define CERT_TYPE_RAW_PUBKEY                    0x04

/**
 * Root cert ID
*/
#define ROOT_CERT_DRK                           0x01
#define ROOT_CERT_OCF                           0x02
#define ROOT_CERT_SAMSUNG                       0x04
#define ROOT_CERT_SCP11N                        0x08
#define ROOT_CERT_SCP11T                        0x10

#define ROOT_CERT_OCF_TEST                      0x80
#define ROOT_CERT_SAMSUNG_TEST                  0x81
#define ROOT_CERT_SCP11N_TEST                   0x82
#define ROOT_CERT_SCP11T_TEST                   0x84

#define ROOT_CERT_SKPM_TEST                     0x88

#define VERIFY_INPUT_SIZE_MAX                   100

#define MAX_KEY_LIST_INFO                       50

/*
  * Start of whiltelist structure
  * Do not change whiltelist structure definition and variables
*/
#define MAX_KEY_NAME_SIZE                       50
#define MAX_QSEE_ID_SIZE                        20
#define TID_SIZE                                16

typedef struct key_list_info_st {
    uint8_t key_name[MAX_KEY_NAME_SIZE];

    uint8_t injection_type;
    uint8_t key_type;
    uint8_t cert_type;
    uint8_t root_cert_id;

    uint8_t key_id_qsee[MAX_QSEE_ID_SIZE];
    uint8_t key_id_mobicore[TID_SIZE];
    uint8_t key_id_blowfish[TID_SIZE];

    uint8_t key_id_extension[TID_SIZE];
} __attribute__((packed)) key_list_info_t, *p_key_list_info_t;
/*
  * End of whiltelist structure
*/

// Check key list and make key list info
void getDefaultKeyListInfo(key_list_info_t keyListInfo[MAX_KEY_LIST_INFO], uint32_t *keyListInfo_size);
void check_key_list(p_cmd_t cmd, p_rsp_t rsp);
void check_caller_list(p_cmd_t cmd, p_rsp_t rsp);

// Key Injection
void factoryKeyInjection(p_cmd_t cmd, p_rsp_t rsp);
void otaKeyInjection(p_cmd_t cmd, p_rsp_t rsp);

// Verify and share the injected key
int parseLenth(uint8_t lengthBytes[3], uint16_t *len);
int getPublicKeyFromCert(uint8_t* leaf_cert_block, const uint32_t leaf_cert_blockSize,
    uint8_t publicKey_block[MAX_CERT_SIZE], uint16_t *publicKey_blockSize);
int leaKeyPairVerification(uint8_t outDataBlob[WRAPPED_KEY_INFO_SIZE], uint32_t outDataBlobSize);
void injectedKeyVerification(p_cmd_t cmd, p_rsp_t rsp);
void injectedKeySharing(p_cmd_t cmd, p_rsp_t rsp);

void readInjectedKeyUID(p_cmd_t cmd, p_rsp_t rsp);

// Generate and get Leaf key, make signature with leaf key
void generateLeafEccKeyPair(p_rsp_t rsp);
void getLeafEccPubkey(p_cmd_t cmd, p_rsp_t rsp);
void signWithLeafEccKey(p_cmd_t cmd, p_rsp_t rsp);

void generateLeafRsaKeyPair(p_rsp_t rsp);
void getLeafRsaPubkey(p_cmd_t cmd, p_rsp_t rsp);
void signWithLeafRsaKey(p_cmd_t cmd, p_rsp_t rsp);

// Read board name
void readBoardName(p_rsp_t rsp);

#ifdef SUPPORT_GUARDIAN_M
// Support Guardian M
void guardianmGetTlsSessionInfo(p_rsp_t rsp);
void guardianmGetCertificates(p_rsp_t rsp);
uint16_t guardianmSignWithClientKey(uint8_t md_type, uint8_t *in, uint32_t inLen,
    uint8_t *sigAsn1Encoded, uint32_t *sigAsn1EncodedLen);
#endif

#endif

