/*
 * Copyright (C) 2019 SAMSUNG S.LSI
 *
 * 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 __GRDM_APP__H
#define __GRDM_APP__H

/**
 * @defgroup vendor Vendor
 * @brief Vendor header files.
 */

/**
 * @ingroup vendor
 * @defgroup grdm GRDM
 * @brief GuardianM header files.
 */

/**
 * @file grdm_app.h
 * @brief GuardianM eSE application APIs.
 */

/**
 * @ingroup grdm
 * @defgroup grdm_app GRDM_App
 * @brief GuardianM eSE application APIs.
 *
 * This API provides functions to use GuardianM eSE.
 * @{
 */

#include <grdm_common.h>
/**
 * @brief Get information
 *
 * - API to get basic information of Guardian M
 * - Guardian M shall return chip identifier and current status.
 * - Current status shall be one of SELECTABLE, PERSONALIZED, RESET, and BLOCKED
 * - Limitations
 *  -# chipid     : Must be 12 bytes
 *
 * @param[out] grdm_status   : current status of Guardian M
 * @param[out] chipid        : Guardian M chip identifier
 * @param[out] chipid_len    : Length of Guardian M chip identifier
 * @param[out] fwVersion     : current Guardian M firmware version
 * @param[out] fwVersion_len : length of current Guardian M firmware version
 * @return Returns ::GRDM_NO_ERROR if succeeded and other value if failed
 */
GRDM_RESULT grdm_getinfo (uint8_t* grdm_status, uint8_t* chipid, uint32_t* chipid_len,
		uint8_t* fwVersion, uint32_t* fwVersion_len);
/**
 * @brief Initialization to put key
 *
 * - API to check if a target domain has been personalized.
 * - Every input parameter shall not be null
 * - If domain_authkey is injected, LSB set to 1, and for else, LSB set to 0.
 * @param[in]  domain_index : index of domain
 * @param[out] keyflag      : The flag on whether a domain_authkey of input domain index has been injected.
 * @return Returns ::GRDM_NO_ERROR if succeeded and other value if failed.
 */
GRDM_RESULT grdm_domain_putkey_init(uint8_t domain_index, uint8_t* keyflag);
/**
 * @breif Put Key Master Key
 *
 * - API to put 32-byte domain_authkey for DOMAIN_INDEX_KM (KM_authkey)
 * - This process shall be performed only one time.
 * - It is strongly recommended that this API should be called and success fully performed during
 *   factory process by Key Master TA
 * - Limiataions
 *  -# domain_authkey    : Must be 32 bytes
 *
 * @param[in] domain_authkey	: KM_authkey
 * @param[in] domain_authkey_len: length of KM_authkey
 */
GRDM_RESULT grdm_KM_putKey (uint8_t* domain_authkey, uint32_t domain_authkey_len);
/**
 * @breif Put ICCC Key
 *
 * - API to put 32-byte domain_authkey for DOMAIN_INDEX_ICCC (ICCC_authkey)
 * - This process shall be performed only one time.
 * - It is strongly recommended that this API should be called and success fully performed during
 *   factory process by ICCC TA
 * - Limiataions
 *  -# domain_authkey    : Must be 32 bytes
 *
 * @param[in] domain_authkey	: ICCC_authkey
 * @param[in] domain_authkey_len: length of ICCC_authkey
 */
GRDM_RESULT grdm_ICCC_putKey (uint8_t* domain_authkey, uint32_t domain_authkey_len);
/**
 * @brief Put key
 *
 * - API to put domain authentication to Guardian M.
 * - This process shall be performed only one thime.
 * - Limitations
 *  -# domain_authkey     : Must be 32 bytes
 *
 * @param[in] admin_authkey        : admin_authkey, resulted by grdm_provisionAdmin
 * @param[in] admin_authkey_len    : Length of \p admin_authkey
 * @param[in] domain_index         : index of domain to put domain_key
 * @param[in] domain_authkey       : new domain_key
 * @param[in] domain_authkey_len   : Length of \p domain_authkey
 * @return Returns ::GRDM_NO_ERROR if succeeded and other value if failed
 */
GRDM_RESULT grdm_subdomain_putKey (uint8_t* admin_authkey, uint8_t admin_authkey_len,
		uint8_t subdomain_index, uint8_t* domain_authkey, uint32_t domain_authkey_len);
/**
 * @brief Provision Admin Key
 *
 * - API for admin application to provision admin key.
 * - Every input parameter shall not be null.
 *
 * @param[in] apid               : Application ID
 * @param[in] apid_len           : Length of \p apid
 * @param[out] admin_authkey     : Admin authentication key
 * @param[out] admin_authkey_len : Length of \p admin_authkey
 * @return Returns ::GRDM_NO_ERROR if succeeded and other value if failed.
 */
GRDM_RESULT grdm_provisionAdmin(uint8_t* apid, uint32_t apid_len,
		uint8_t *admin_authkey, uint32_t *admin_authkey_len);
/**
 * @brief Inject IMEI to eSE
 *
 * - API for admin application to inject information of IMEI.
 * - Every input parameter shall not be null.
 * - Limitations
 * -# admin_authkey     : Must be 32 bytes
 *
 * @param[in] admin_authkey     : admin_authkey, resulted by grdm_provisionAdmin
 * @param[in] admin_authkey_len : Length of \p admin_authkey
 * @param[in] data              : Device IMEI
 * @param[in] data_len          : Length of \p data
 * @return Returns ::GRDM_NO_ERROR if succeeded and other value if failed.
 */
GRDM_RESULT grdm_injectIMEI (uint8_t* admin_authkey,
		uint8_t admin_authkey_len, uint8_t* data, uint32_t data_len);
/**
 * @brief Get IMEI from eSE
 *
 * - API to get IMEI.
 * - Limitations
 *
 * @param[out] data     : Device IMEI
 * @param[out] data_len : Length of \p data
 * @return Returns ::GRDM_NO_ERROR if succeeded and other value if failed.
 */
GRDM_RESULT grdm_getIMEI(uint8_t* data, uint32_t* data_len);
/**
 * @brief Get credential from BL Area for authorized accessors
 *
 * - API for authorized accessors to read BL credential data. Authorized accessor shall authenticate
 * - itself to Guardian M by its authkey.
 * - Details on access rights to BL credentials can be found in API spec.
 * - Prerequisite: Before requesting, authorized accessor must personalize Guardian M by calling
 * - proper putkey API, such as grdm_ICCC_putkey and grdm_KM_putkey
 * - This operation shall be performed via secure channel.
 * - Every input parameter shall not be null.
 *
 * @param[in]  accessor				: accessor Index to read BL credential
 * @param[in]  domain_authkey		: accessor's authkey byte array. This parameter shall not be null
 * @param[in]  domain_authkey_len	: Length of accessor's authkey
 * @param[in]  BLcredential_index	: Targeted credential index
 * @param[out] data					: credential
 * @param[out] data_len				: Length of data
 * @return Returns ::GRDM_NO_ERROR if succeeded and other value if failed.
 */
GRDM_RESULT grdm_getBLCredential (uint8_t accessor, uint8_t* domain_authkey,
		uint8_t domain_authkey_len, uint8_t BLcredential_index, uint8_t* data, uint32_t* data_len);
/**
 * @brief Get credential from eSE
 *
 * - API for permissioned application to read credential.
 * - This operation shall be performed via secure channel.
 * - Every input parameter shall not be null.
 *
 * @param[in]  domain_index       : Index for target domain*
 * @param[in]  domain_authkey     : Domain authkey for target domain
 * @param[in]  domain_authkey_len : Length of \p key
 * @param[in]  credential_index   : Targeted credential index
 * @param[out] data               : credential
 * @param[out] data_len           : Length of \p data
 * @return Returns ::GRDM_NO_ERROR if succeeded and other value if failed.
 */
GRDM_RESULT grdm_getCredential(uint8_t domain_index,
		uint8_t* domain_authkey,uint32_t domain_authkey_len,
		uint8_t credential_index, uint8_t* data, uint32_t* data_len);
/**
 * @brief Store credential from eSE
 *
 * - API for permissioned application to store credential.
 * - This operation shall be performed via secure channel.
 * - Every input parameter shall not be null.
 *
 * @param[in]  domain_index       : Index for target domain*
 * @param[in]  domain_authkey     : Domain authkey for target domain
 * @param[in]  domain_authkey_len : Length of \p key
 * @param[in]  credential_index   : Targeted credential index
 * @param[in] data               : credential
 * @param[in] data_len           : Length of \p data
 * @return Returns ::GRDM_NO_ERROR if succeeded and other value if failed.
 */
GRDM_RESULT grdm_storeCredential (uint8_t domain_index,
		uint8_t* domain_authkey, uint8_t domain_authkey_len,
		uint8_t credential_index, uint8_t* data, uint32_t data_len);
/**
 * @brief Delete credential from eSE
 *
 * - API for permissioned application to delete credential.
 * - This operation shall be performed via secure channel.
 * - Every input parameter shall not be null.
 *  - Limitations
 * -# credential_index : If credential_index is MAX_CREDENTIAL_INDEX, then
 * all of credential data in a target domain shall be deleted at the same time.
 *
 * @param[in] domain_index       : Index for target domain*
 * @param[in] domain_authkey     : Domain authkey for target domain
 * @param[in] domain_authkey_len : Length of \p key
 * @param[in] credential_index   : Targeted credential index
 * @return Returns ::GRDM_NO_ERROR if succeeded and other value if failed.
 */
GRDM_RESULT grdm_deleteCredential (uint8_t domain_index,
		uint8_t* domain_authkey, uint8_t domain_authkey_len, uint8_t credential_index);
/**
 * @brief Get attestation certificate from eSE
 *
 * - API to get the DER-encoded certificate injected in Guardian M.
 *
 * @param[in]  index     : Index of certificate
 * @param[out] cert_data : Received certificate
 * @param[out] cert_len  : Length of \p cert_data
 * @return Returns ::GRDM_NO_ERROR if succeeded and other value if failed.
 */
GRDM_RESULT grdm_getAttesCertificate(uint8_t index, uint8_t* cert_data, uint32_t* cert_len);
/**
 * @brief Get attestation public key from eSE
 *
 * - API to get ECC public key certificate injected in Guardian M.
 *
 * @param[in]  index  : Index of certificate
 * @param[out] pk     : Received public key with uncompressed form
 * @param[out] pk_len : Length of \p pk
 * @return Returns ::GRDM_NO_ERROR if succeeded and other value if failed.
 */
GRDM_RESULT grdm_getAttesPublicKey(uint8_t index, uint8_t* pk, uint32_t* pk_len);
/**
 * @brief Get device attestation from eSE
 *
 * - API to get the signature injected in Guardian M.
 *
 * @param[in]  attestation_type : Attestation type (simple mode = 0, end-to-end encryption mode = 1)
 * @param[in]  challenge        : Challenge value
 * @param[in]  challenge_len    : Length of \p challenge
 * @param[in]  time             : Byte encoding of a string year(2bytes)||month(2)||day(2)||hour(2)||min(2)||sec(2)
 * @param[in]  time_len         : Length of \p time
 * @param[out] signeddata       : Received signature
 * @param[out] signeddata_len   : Length of \p signeddata
 * @return Returns ::GRDM_NO_ERROR if succeeded and other value if failed.
 */
GRDM_RESULT grdm_getDeviceAttestation(uint8_t attestation_type,
		uint8_t* challenge, uint32_t challenge_len,
		uint8_t* time, uint8_t time_len,
		uint8_t* signeddata, uint32_t* signeddata_len);
/**
 * @brief Get ECDSA signature with attestation key
 *
 * - API to get ECDSA with SHA256 signature generated with injected attestation key.
 * - The signing operation includes  message digest operation.
 * - Hash algorithm is automatically chosen by the target key length.
 *   (256-bit key ->  Sha256, 384-bit key -> Sha384, 521-bit key -> Sha512 .
 *
 * @param[in]  attesKey_index: index of injected key, used to be signed. This must be ATTESTATION_ENDENTITY
 * @param[in]  message       : Message to be signed
 * @param[in]  message_len   : Length of \p message
 * @param[out] signature     : DER-encoded signature data (r, s), complies with X9.62
 * @param[out] signature_len : Length of \p signature
 * @return Returns ::GRDM_NO_ERROR if succeeded and other value if failed.
 */
GRDM_RESULT grdm_ecdsaWithHash_AttesKey(uint8_t attesKey_index,
		uint8_t* message, uint32_t message_len,
		uint8_t* signature, uint32_t* signature_len);
/**
 * @brief Get ECDSA signature with attestation key
 *
 * - API to get ECDSA signature generated with injected attestation key.
 * - The signing operation do not include message digest operation.
 *   Hence, hashed message shall be come as the message digest input parameter.
 *
 * @param[in]  attesKey_index   : index of injected key, used to be signed. This must be ATTESTATION_ENDENTITY
 * @param[in]  messagedigest    : Message digest to be signed after hashing
 * @param[in]  messagedigest_len: Length of \p message, in this case,
 *                             this value must be equal to the length of hashed output.
 *                             (256-bit key -> 32, 384-bit key -> 48, 521-bit key -> 64)
 * @param[out] signature        : DER-encoded signature data (r, s), complies with X9.62
 * @param[out] signature_len    : Length of \p signature
 * @return Returns ::GRDM_NO_ERROR if succeeded and other value if failed.
 */
GRDM_RESULT grdm_ecdsa_AttesKey(uint8_t attesKey_index,
		uint8_t* messagedigest, uint32_t messagedigest_len,
		uint8_t* signature, uint32_t* signature_len);
/**
 * @brief Get ECDSA signature with injected SAK
 *
 * - API to get ECDSA signature generated with injected SAK.
 * - This operation is allowed to ONLY Key Master TA.
 * - Prerequisite: KM_authkey mush have been injected by calling grdm_KM_putkey.
 * - The signing operation do not include message digest operation,
 *   Hence, hashed message shall be come as the message digest input parameter.
 *
 * @param[in] domain_index      : it must be DOMAIN_INDEX_KM
 * @param[in] domain_authkey    : KM_authkey
 * @param[in] domain_authkey_len: Length of domain_authkey
 * @param[in] messagedigest     : Message digest to be signed after hashing
 * @param[in] messagedigest_len : Length of \p message, in this case,
 *                             this value must be equal to the length of hashed output.
 *                             (256-bit key -> 32, 384-bit key -> 48, 521-bit key -> 64)
 * @param[out] signature        : DER-encoded signature data (r, s), complies with X9.62
 * @param[out] signature_len    : Length of \p signature
 * @return Returns ::GRDM_NO_ERROR if succeeded and other value if failed.
 */
GRDM_RESULT grdm_ecdsa_SAK(uint8_t domain_index,
		uint8_t* domain_authkey, uint32_t domain_authkey_len,
		uint8_t* messagedigest, uint32_t messagedigest_len,
		uint8_t* signature, uint32_t* signature_len);
/**
 * @}
 */
#endif
