/*
 * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
 *
 * This software is dual-licensed to you under the MIT License (MIT) and
 * the Universal Permissive License (UPL). See the LICENSE file in the root
 * directory for license terms. You may choose either license, or both.
 */

/**
 * @file iotcs_port_crypto.h
 * @brief The file contains porting layer for cryptography.
 */

#ifndef IOTCS_PORT_CRYPTO_H
#define	IOTCS_PORT_CRYPTO_H


#ifdef	__cplusplus
extern "C" {
#endif

#include "iotcs.h"

#define IOTCS_MD5_DIGEST_LENGTH 32

    /**
     * @brief Encodes the input buffer and writes the result to output buffer
     * @note Mandatory API. Called by the Library in any configuration.
     * @param output an output buffer
     * @param output_length IN  : length of the output buffer
     *                      OUT : number of bytes written to the output buffer
     * @param input an input buffer
     * @param input_length a length of the input buffer
     * @return IOTCS_RESULT_OK success
     * @return IOTCS_RESULT_FAIL otherwise
     */
    iotcs_result iotcs_port_crypto_encode_base64(char* output, size_t* output_length, const char* input, size_t input_length);

    /**
     * @brief Decodes the input buffer and writes the result to output buffer
     * @note Mandatory API. Called by the Library in any configuration.
     * @param output an output buffer
     * @param output_length IN  : length of the output buffer
     *                      OUT : number of bytes written to the output buffer
     * @param input an input buffer
     * @param input_length a length of the input buffer
     * @return IOTCS_RESULT_OK success
     * @return IOTCS_RESULT_FAIL otherwise
     */
    iotcs_result iotcs_port_crypto_decode_base64(char* output, size_t* output_length, const char* input, size_t input_length);

    /**
     * @brief Initializes cryptography related functionality
     * @note Mandatory API. Called by the Library in any configuration.
     * @return IOTCS_RESULT_OK success
     * @return IOTCS_RESULT_FAIL otherwise
     */
    iotcs_result iotcs_port_crypto_init(void);

    /**
     * @brief Finalizes cryptography related functionality
     * @note Mandatory API. Called by the Library in any configuration.
     */
    void iotcs_port_crypto_finalize(void);

    /**
     * @typedef iotcs_port_get_next_string_func
     * @brief Handler for function used in iotcs_port_md5 method.
     */
    typedef const char* (*iotcs_port_get_next_string_func)(void*);

    /**
     * @brief Computes MD5 message digest
     * Calculate MD5 digest for NULL-terminated strings returned by \a func(data)
     * where \a func and \a data are given as arguments.
     * Calculation stops when \a func(data) returns NULL. The calculated MD5
     * digest is saved to \a output_buffer which is guaranteed to be at least
     * IOTCS_MD5_DIGEST_LENGTH bytes in size.
     * @note Mandatory API. Called by the Library in any configuration.
     * @param output_buffer buffer to write output which size is IOTCS_MD5_DIGEST_LENGTH bytes
     * @param func a function that provides strings for MD5 from data container
     * @param data to be passed to 'func' as an argument
     * @return IOTCS_RESULT_OK success
     * @return IOTCS_RESULT_FAIL otherwise
     */
    iotcs_result iotcs_port_md5(unsigned char *output_buffer, iotcs_port_get_next_string_func func, void *data);

#ifdef	__cplusplus
}
#endif

#endif	/* IOTCS_PORT_CRYPTO_H */

