/*
 *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
 *
 *  Contact: Krzysztof Jackiewicz <k.jackiewicz@samsung.com>
 *
 *  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
 */


/**
 * @file yaca_crypto.h
 * @brief Non crypto related functions.
 */


#ifndef YACA_CRYPTO_H
#define YACA_CRYPTO_H


#include <stddef.h>
#include <yaca_types.h>


#ifdef __cplusplus
extern "C" {
#endif


/**
 * @addtogroup CAPI_YACA_ENCRYPTION_MODULE
 * @{
 */


/**
 * @brief Definition for NULL value for the crypto context.
 * @since_tizen 3.0
 */
#define YACA_CONTEXT_NULL ((yaca_context_h) NULL)


/**
 * @brief Initializes the library. Must be called before any other crypto
 *        function. Should be called once in each thread that uses yaca.
 * @since_tizen 3.0
 * @return #YACA_ERROR_NONE on success,
 *         negative on error
 * @retval #YACA_ERROR_NONE Successful
 * @retval #YACA_ERROR_OUT_OF_MEMORY Out of memory error
 * @retval #YACA_ERROR_INTERNAL Internal error
 * @see yaca_cleanup()
 */
int yaca_initialize(void);


/**
 * @brief Cleans up the library. Must be called before exiting the thread that called yaca_initialize().
 * @since_tizen 3.0
 * @see yaca_initialize()
 */
void yaca_cleanup(void);


/**
 * @brief Allocates the memory.
 * @since_tizen 3.0
 * @remarks The @a memory should be freed using yaca_free().
 * @param[in] size Size of the allocation (bytes)
 * @param[out] memory Allocated memory
 * @return #YACA_ERROR_NONE on success,
 *         negative on error
 * @retval #YACA_ERROR_NONE Successful
 * @retval #YACA_ERROR_INVALID_PARAMETER Required parameters have incorrect values (NULL, 0)
 * @retval #YACA_ERROR_OUT_OF_MEMORY Out of memory error
 * @see yaca_zalloc()
 * @see yaca_realloc()
 * @see yaca_free()
 */
int yaca_malloc(size_t size, void **memory);


/**
 * @brief Allocates the zeroed memory.
 * @since_tizen 3.0
 * @remarks The @a memory should be freed using yaca_free().
 * @param[in] size Size of the allocation (bytes)
 * @param[out] memory Allocated memory
 * @return #YACA_ERROR_NONE on success,
 *         negative on error
 * @retval #YACA_ERROR_NONE Successful
 * @retval #YACA_ERROR_INVALID_PARAMETER Required parameters have incorrect values (NULL, 0)
 * @retval #YACA_ERROR_OUT_OF_MEMORY Out of memory error
 * @see yaca_malloc()
 * @see yaca_realloc()
 * @see yaca_free()
 */
int yaca_zalloc(size_t size, void **memory);


/**
 * @brief Re-allocates the memory.
 * @since_tizen 3.0
 * @remarks In case of failure the function doesn't free the memory pointed by @a memory.
 * @remarks If @a memory is NULL then the call is equivalent to yaca_malloc().
 * @remarks If the function fails the contents of @a memory will be left unchanged.
 * @remarks The @a memory should be freed using yaca_free().
 * @param[in] size Size of the new allocation (bytes)
 * @param[in,out] memory  Memory to be reallocated
 * @return #YACA_ERROR_NONE on success,
 *         negative on error
 * @retval #YACA_ERROR_NONE Successful
 * @retval #YACA_ERROR_INVALID_PARAMETER Required parameters have incorrect values (NULL, 0)
 * @retval #YACA_ERROR_OUT_OF_MEMORY Out of memory error
 * @see yaca_malloc()
 * @see yaca_zalloc()
 * @see yaca_free()
 */
int yaca_realloc(size_t size, void **memory);


/**
 * @brief Frees the memory allocated by yaca_malloc(), yaca_zalloc(),
 *        yaca_realloc() or one of the cryptographic operations.
 * @since_tizen 3.0
 * @param[in] memory Pointer to the memory to be freed
 * @see yaca_malloc()
 * @see yaca_zalloc()
 * @see yaca_realloc()
 */
void yaca_free(void *memory);


/**
 * @brief Safely compares first @a len bytes of two buffers.
 * @since_tizen 3.0
 * @param[in] first Pointer to the first buffer
 * @param[in] second Pointer to the second buffer
 * @param[in] len Length to compare
 * @return #YACA_ERROR_NONE when buffers are equal,
 *         otherwise #YACA_ERROR_DATA_MISMATCH
 * @retval #YACA_ERROR_NONE Successful
 * @retval #YACA_ERROR_INVALID_PARAMETER Required parameters have incorrect values (NULL, 0)
 * @retval #YACA_ERROR_DATA_MISMATCH Buffers are different
 */
int yaca_memcmp(const void *first, const void *second, size_t len);


/**
 * @brief Generates random data.
 * @since_tizen 3.0
 * @param[in,out] data Pointer to the memory to be randomized
 * @param[in] data_len Length of the memory to be randomized
 * @return #YACA_ERROR_NONE on success,
 *         negative on error
 * @retval #YACA_ERROR_NONE Successful
 * @retval #YACA_ERROR_INVALID_PARAMETER Required parameters have incorrect values (NULL, 0)
 * @retval #YACA_ERROR_INTERNAL Internal error
 */
int yaca_randomize_bytes(char *data, size_t data_len);


/**
 * @brief Sets the non-standard context properties. Can only be called on an initialized context.
 * @since_tizen 3.0
 * @remarks The @a value has to be of type appropriate for given property. See #yaca_property_e
 *          for details on corresponding types.
 * @param[in,out] ctx Previously initialized crypto context
 * @param[in] property Property to be set
 * @param[in] value Property value
 * @param[in] value_len Length of the property value
 * @return #YACA_ERROR_NONE on success,
 *         negative on error
 * @retval #YACA_ERROR_NONE Successful
 * @retval #YACA_ERROR_INVALID_PARAMETER Required parameters have incorrect values (NULL, 0,
 *                                       invalid @a ctx or @a property)
 * @retval #YACA_ERROR_INTERNAL Internal error
 * @see #yaca_property_e
 * @see yaca_context_get_property()
 */
int yaca_context_set_property(yaca_context_h ctx, yaca_property_e property, const void *value, size_t value_len);


/**
 * @brief Returns the non-standard context properties. Can only be called on an initialized context.
 * @since_tizen 3.0
 * @remarks The @a value should be freed using yaca_free().
 * @remarks The @a value has to be of type appropriate for given property. See #yaca_property_e
 *          for details on corresponding types.
 * @remarks The @a value_len can be NULL if returned @a value is a single object (i.e. not an array/buffer).
 * @param[in] ctx Previously initialized crypto context
 * @param[in] property Property to be read
 * @param[out] value Copy of the property value
 * @param[out] value_len Length of the property value will be returned here
 * @return #YACA_ERROR_NONE on success,
 *         negative on error
 * @retval #YACA_ERROR_NONE Successful
 * @retval #YACA_ERROR_INVALID_PARAMETER Required parameters have incorrect values (NULL,
 *                                       invalid @a ctx or @a property)
 * @retval #YACA_ERROR_OUT_OF_MEMORY Out of memory error
 * @retval #YACA_ERROR_INTERNAL Internal error
 * @see #yaca_property_e
 * @see yaca_context_set_property()
 * @see yaca_free()
 */
int yaca_context_get_property(const yaca_context_h ctx, yaca_property_e property, void **value, size_t *value_len);


/**
 * @brief Returns the minimum required size of the output buffer for a single crypto function call.
 * @since_tizen 3.0
 * @remarks This function should be used to learn the required size of the output buffer
 *          for a single function call (eg. *_update or *_finalize). The actual output length
 *          (number of bytes that has been used) will be returned by the function call itself.
 * @remarks In case the function call has no output (e.g. yaca_sign_update(),
 *          yaca_digest_update()), there is no need to use this function.
 * @remarks In case the function call has no input (eg. *_finalize), the value of
 *          @a input_len has to be set to 0.
 * @param[in] ctx Previously initialized crypto context
 * @param[in] input_len Length of the input data to be processed
 * @param[out] output_len Required length of the output
 * @return #YACA_ERROR_NONE on success,
 *         negative on error
 * @retval #YACA_ERROR_NONE Successful
 * @retval #YACA_ERROR_INVALID_PARAMETER Required parameters have incorrect values (NULL,
 *                                       invalid @a ctx or too big @a input_len)
 * @retval #YACA_ERROR_INTERNAL Internal error
 */
int yaca_context_get_output_length(const yaca_context_h ctx, size_t input_len, size_t *output_len);


/**
 * @brief Destroys the crypto context. Must be called on all contexts that are no longer used.
 *        Passing #YACA_CONTEXT_NULL is allowed.
 * @since_tizen 3.0
 * @param[in,out] ctx  Crypto context
 * @see #yaca_context_h
 */
void yaca_context_destroy(yaca_context_h ctx);


/**
 * @}
 */


#ifdef __cplusplus
} /* extern */
#endif


#endif /* YACA_CRYPTO_H */
