#ifndef __REMOTE_ATTESTATION_H__
#define __REMOTE_ATTESTATION_H__

#include <sgx_urts.h>
#include <sgx_key_exchange.h>
#include <sgx_ukey_exchange.h>

/**
 * Initialize the remote attestation.
 *
 * @param enclave_id The identifier of the enclave facilitating the remote
 * attestation.
 * @param use_platform_services If true, the enclave establishes a session with
 * the PSE before initializing the attestation context. This provides
 * additional nonce replay protection and a reliable monotonic counter.
 * @param key_challenger ECDSA public key of the challenger with the 8 magic
 * bytes removed, and X and Y components changed to little-endian.
 * @param context The variable receiving the context constructed during
 * initialization.
 *
 * @return Status code indicative of the outcome of the operation.
 */
sgx_status_t initialize_remote_attestation(
    // Inputs
    sgx_enclave_id_t enclave_id,
    bool use_platform_services,
    sgx_ec256_public_t *key_challenger,

    // Outputs
    sgx_ra_context_t* context
);

/**
 * Clean up and finalize the remote attestation process.
 *
 * @param enclave_id The identifier of the enclave facilitating the remote
 * attestation.
 * @param context The context constructed during initialization.
 *
 * @return SGX_SUCCESS if successful, or SGX_ERROR_INVALID_PARAMETER if
 * an invalid context is provided.
 */
sgx_status_t finalize_remote_attestation(
    sgx_enclave_id_t enclave_id,
    sgx_ra_context_t context
);

/**
 * Get the public key of the application enclave, and the identifier of the
 * EPID group the platform belongs to.
 *
 * @param enclave_id The identifier of the application enclave.
 * @param context The context constructed during initialization.
 * @param public_key Variable receiving the elliptic curve public key of the
 * application enclave, based on the NIST P-256 elliptic curve..
 * @param group_id Variable receiving the identifier of the platform's EPID
 * group.
 * @param max_retry_count The maximum number of times to retry the operation.
 * @param retry_wait_in_secs The number of seconds to wait between each retry.
 *
 * @return SGX_SUCCESS if successful, otherwise an error code indicative of
 * what went wrong.
 */
sgx_status_t get_public_key_and_group_identifier(
    // Inputs
    sgx_enclave_id_t enclave_id,
    sgx_ra_context_t context,

    // Outputs
    sgx_ec256_public_t *public_key,
    sgx_epid_group_id_t *group_id,

    // Retry logic
    int max_retry_count,
    unsigned int retry_wait_in_secs
);

/**
 * Process details received from the challenger via the service provider, and
 * generate quote. If the service provider accepts the quote, negotiated
 * session keys between the application enclave and the challenger are ready
 * for use. However, if it fails, the application should notify the service
 * provider of the error or the service provider needs a time-out mechanism to
 * terminate the remote attestation transaction when it does not receive the
 * message.
 *
 * @param enclave_id The identifier of the application enclave.
 * @param context The context constructed during initialization.
 * @param challenger_public_key The public key of the challenger.
 * @param service_provider_id The identifier of the service provider.
 * @param quote_type Indicates the quote type, linkable (1) or unlinkable (0).
 * @param key_derivation_function The ID of the key derivation function used.
 * @param signature An ECDSA signature over the challenger and application
 * enclave's public keys.
 * @param mac A 128-bit AES-CMAC generated by the service provider.
 * @param revocation_list_size The size of revocation_list, in bytes.
 * @param revocation_list The signature revocation list certificate of the
 * Intel EPID group identified by the group identifier in message 1.
 * @param enclave_mac AES-CMAC generated by the enclave.
 * @param enclave_public_key Variable receiving the public key of the
 * application enclave.
 * @param security_properties Variable receiving the security properties of the
 * Intel SGX platform service. If the security property information is not
 * required in the remote attestation and key exchange process, this field will
 * be all zeros.
 * @param quote Variable receiving a pointer to the quote returned from
 * sgx_get_quote. This should be freed after use.
 * @param quote_size Variable receiving the size of the quote.
 * @param max_retry_count The maximum number of times to retry the operation.
 * @param retry_wait_in_secs The number of seconds to wait between each retry.
 *
 * @return SGX_SUCCESS if successful, otherwise an error code indicative of
 * what went wrong.
 */
sgx_status_t process_challenger_details_and_generate_quote(
    // Inputs
    sgx_enclave_id_t enclave_id,
    sgx_ra_context_t context,
    sgx_ec256_public_t *challenger_public_key,
    sgx_spid_t *service_provider_id,
    uint16_t quote_type,
    uint16_t key_derivation_function,
    sgx_ec256_signature_t *signature,
    sgx_mac_t *challenger_mac,
    uint32_t revocation_list_size,
    uint8_t *revocation_list,

    // Outputs
    sgx_mac_t *enclave_mac,
    sgx_ec256_public_t *enclave_public_key,
    sgx_ps_sec_prop_desc_t *security_properties,
    uint8_t **quote,
    size_t *quote_size,

    // Retry logic
    int max_retry_count,
    unsigned int retry_wait_in_secs
);

/**
 * Verify attestation response from service provider.
 *
 * @param enclave_id The identifier of the application enclave.
 * @param context The context constructed during initialization.
 * @param message The received attestation result message.
 * @param message_size The size of the attestation result message.
 * @param cmac The CMAC computed over the attestation result message.
 * @param cmac_size The size of the CMAC.
 * @param secret The encrypted secret provisioned by the challenger.
 * @param secret_size The size of the encrypted secret.
 * @param gcm_iv The 12-byte initialization vector used in the decryption.
 * @param gcm_mac The GCM-MAC generated over the secret.
 * @param gcm_mac_size The size of the GCM-MAC.
 * @param sealed_secret Pre-allocated buffer receiving the sealed secret.
 * @param sealed_secret_size The size of the sealed secret.
 * @param cmac_status The variable receiving the outcome of the CMAC check.
 *
 * @return SGX_SUCCESS if successful, otherwise an error code indicative of
 * what went wrong.
 */
sgx_status_t verify_attestation_response(
    // Inputs
    sgx_enclave_id_t enclave_id,
    sgx_ra_context_t context,
    uint8_t *message,
    size_t message_size,
    uint8_t *cmac,
    size_t cmac_size,
    uint8_t *secret,
    size_t secret_size,
    uint8_t *gcm_iv,
    uint8_t *gcm_mac,
    size_t gcm_mac_size,

    // Outputs
    uint8_t *sealed_secret,
    size_t *sealed_secret_size,
    sgx_status_t *cmac_status
);

#endif /* __REMOTE_ATTESTATION_H__ */