/*
 *  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_simple.h
 * @brief Simple API.
 * @details This is simple API.
 *          Design constraints:
 *          - All operations are single-shot (no streaming possible)
 *          - Context is not used
 *          - Only digest, signatures and symmetric ciphers are supported
 *          - Disabling PKCS#7 padding for ECB and CBC chaining is not supported
 *          - Changing the default PKCS#1 padding for sign/verify is not supported
 *          - GCM and CCM chaining is not supported
 *          - RC2 effective key bits property is not supported
 *          - All outputs are allocated by the library
 */


#ifndef YACA_SIMPLE_H
#define YACA_SIMPLE_H


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


#ifdef __cplusplus
extern "C" {
#endif


/**
 * @addtogroup CAPI_YACA_SIMPLE_MODULE
 * @{
 */


/**
 * @brief Encrypts data using a symmetric cipher.
 * @since_tizen 3.0
 * @remarks yaca_simple_encrypt() doesn't support #YACA_BCM_GCM and #YACA_BCM_CCM.
 * @remarks The @a ciphertext should be freed using yaca_free().
 * @remarks The @a plaintext can be NULL but then @a plaintext_len must be 0.
 * @param[in] algo Encryption algorithm (select #YACA_ENCRYPT_AES if unsure)
 * @param[in] bcm Chaining mode (select #YACA_BCM_CBC if unsure)
 * @param[in] sym_key Symmetric encryption key (see yaca_key.h for key generation functions)
 * @param[in] iv Initialization Vector
 * @param[in] plaintext Plaintext to be encrypted
 * @param[in] plaintext_len Length of the plaintext
 * @param[out] ciphertext Encrypted data, will be allocated by the library
 * @param[out] ciphertext_len Length of the encrypted data (may be larger than decrypted)
 * @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 algo, @a bcm, @a sym_key or @a iv)
 * @retval #YACA_ERROR_OUT_OF_MEMORY Out of memory error
 * @retval #YACA_ERROR_INTERNAL Internal error
 * @see #yaca_encrypt_algorithm_e
 * @see #yaca_block_cipher_mode_e
 * @see yaca_simple_decrypt()
 * @see yaca_free()
 */
int yaca_simple_encrypt(yaca_encrypt_algorithm_e algo, yaca_block_cipher_mode_e bcm, const yaca_key_h sym_key, const yaca_key_h iv, const char *plaintext,
						     size_t plaintext_len, char **ciphertext, size_t *ciphertext_len);


/**
 * @brief Decrypts data using a symmetric cipher.
 * @since_tizen 3.0
 * @remarks yaca_simple_decrypt() doesn't support #YACA_BCM_GCM and #YACA_BCM_CCM.
 * @remarks The @a plaintext should be freed using yaca_free().
 * @remarks The @a ciphertext can be NULL but then @a ciphertext_len must be 0.
 * @param[in] algo Decryption algorithm that was used to encrypt the data
 * @param[in] bcm Chaining mode that was used to encrypt the data
 * @param[in] sym_key Symmetric encryption key that was used to encrypt the data
 * @param[in] iv Initialization Vector that was used to encrypt the data
 * @param[in] ciphertext Ciphertext to be decrypted
 * @param[in] ciphertext_len Length of ciphertext
 * @param[out] plaintext Decrypted data, will be allocated by the library
 * @param[out] plaintext_len Length of the decrypted data
 * @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 algo, @a bcm, @a sym_key or @a iv)
 * @retval #YACA_ERROR_OUT_OF_MEMORY Out of memory error
 * @retval #YACA_ERROR_INTERNAL Internal error
 * @see #yaca_encrypt_algorithm_e
 * @see #yaca_block_cipher_mode_e
 * @see yaca_simple_encrypt()
 * @see yaca_free()
 */
int yaca_simple_decrypt(yaca_encrypt_algorithm_e algo, yaca_block_cipher_mode_e bcm, const yaca_key_h sym_key, const yaca_key_h iv, const char *ciphertext,
						       size_t ciphertext_len, char **plaintext, size_t *plaintext_len);


/**
 * @brief Calculates a digest of a message.
 * @since_tizen 3.0
 * @remarks The @a digest should be freed using yaca_free().
 * @remarks The @a message can be NULL but then @a message_len must be 0.
 * @param[in] algo Digest algorithm (select #YACA_DIGEST_SHA256 if unsure)
 * @param[in] message Message from which the digest is to be calculated
 * @param[in] message_len Length of the message
 * @param[out] digest Message digest, will be allocated by the library
 * @param[out] digest_len Length of message digest (depends on algorithm)
 * @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 algo)
 * @retval #YACA_ERROR_OUT_OF_MEMORY Out of memory error
 * @retval #YACA_ERROR_INTERNAL Internal error
 * @see #yaca_digest_algorithm_e
 * @see yaca_free()
 */
int yaca_simple_calculate_digest(yaca_digest_algorithm_e algo, const char *message, size_t message_len, char **digest, size_t *digest_len);


/**
 * @brief Creates a signature using asymmetric private key.
 * @since_tizen 3.0
 * @remarks For #YACA_DIGEST_SHA384 and #YACA_DIGEST_SHA512 the RSA key size must be bigger than
 *          #YACA_KEY_LENGTH_512BIT.
 * @remarks Using of #YACA_DIGEST_MD5 algorithm for DSA and ECDSA operations is prohibited.
 * @remarks The @a signature should be freed using yaca_free().
 * @remarks The @a message can be NULL but then @a message_len must be 0.
 * @param[in] algo Digest algorithm that will be used
 * @param[in] prv_key Private key that will be used, algorithm is
 *                    deduced based on key type, supported key types:
 *                    - #YACA_KEY_TYPE_RSA_PRIV,
 *                    - #YACA_KEY_TYPE_DSA_PRIV,
 *                    - #YACA_KEY_TYPE_EC_PRIV
 * @param[in] message Message to be signed
 * @param[in] message_len Length of the message
 * @param[out] signature Message signature, will be allocated by the library
 * @param[out] signature_len Length of the signature
 * @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 algo or @a prv_key)
 * @retval #YACA_ERROR_OUT_OF_MEMORY Out of memory error
 * @retval #YACA_ERROR_INTERNAL Internal error
 * @see #yaca_key_type_e
 * @see #yaca_digest_algorithm_e
 * @see yaca_simple_verify_signature()
 * @see yaca_free()
 */
int yaca_simple_calculate_signature(yaca_digest_algorithm_e algo, const yaca_key_h prv_key, const char *message, size_t message_len, char **signature, size_t *signature_len);


/**
 * @brief Verifies a signature using asymmetric public key.
 * @since_tizen 3.0
 * @remarks The @a message can be NULL but then @a message_len must be 0.
 * @param[in] algo Digest algorithm that will be used
 * @param[in] pub_key Public key that will be used, algorithm is
 *                    deduced based on key type, supported key types:
 *                    - #YACA_KEY_TYPE_RSA_PUB,
 *                    - #YACA_KEY_TYPE_DSA_PUB,
 *                    - #YACA_KEY_TYPE_EC_PUB
 * @param[in] message Message
 * @param[in] message_len Length of the message
 * @param[in] signature Message signature to be verified
 * @param[in] signature_len Length of the signature
 * @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 algo or @a pub_key)
 * @retval #YACA_ERROR_OUT_OF_MEMORY Out of memory error
 * @retval #YACA_ERROR_INTERNAL Internal error
 * @retval #YACA_ERROR_DATA_MISMATCH The verification failed
 * @see #yaca_key_type_e
 * @see #yaca_digest_algorithm_e
 * @see yaca_simple_calculate_signature()
 */
int yaca_simple_verify_signature(yaca_digest_algorithm_e algo, const yaca_key_h pub_key, const char *message, size_t message_len, const char *signature, size_t signature_len);


/**
 * @brief Calculates a HMAC of given message using symmetric key.
 * @since_tizen 3.0
 * @remarks For verification, calculate message HMAC and compare with received MAC using yaca_memcmp().
 * @remarks The @a mac should be freed using yaca_free().
 * @remarks The @a message can be NULL but then @a message_len must be 0.
 * @param[in] algo Digest algorithm that will be used
 * @param[in] sym_key Key that will be used, supported key types:
 *                    - #YACA_KEY_TYPE_SYMMETRIC,
 *                    - #YACA_KEY_TYPE_DES
 * @param[in] message Message to calculate HMAC from
 * @param[in] message_len Length of the message
 * @param[out] mac MAC, will be allocated by the library
 * @param[out] mac_len Length of the MAC
 * @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 algo or @a sym_key)
 * @retval #YACA_ERROR_OUT_OF_MEMORY Out of memory error
 * @retval #YACA_ERROR_INTERNAL Internal error
 * @see #yaca_key_type_e
 * @see #yaca_digest_algorithm_e
 * @see yaca_memcmp()
 * @see yaca_free()
 */
int yaca_simple_calculate_hmac(yaca_digest_algorithm_e algo, const yaca_key_h sym_key, const char *message, size_t message_len, char **mac, size_t *mac_len);


/**
 * @brief Calculates a CMAC of given message using symmetric key.
 * @since_tizen 3.0
 * @remarks For verification, calculate message CMAC and compare with received MAC using yaca_memcmp().
 * @remarks The @a mac should be freed using yaca_free().
 * @remarks The @a message can be NULL but then @a message_len must be 0.
 * @param[in] algo Encryption algorithm that will be used
 * @param[in] sym_key Key that will be used, supported key types:
 *                    - #YACA_KEY_TYPE_SYMMETRIC,
 *                    - #YACA_KEY_TYPE_DES
 * @param[in] message Message to calculate CMAC from
 * @param[in] message_len Length of the message
 * @param[out] mac MAC, will be allocated by the library
 * @param[out] mac_len Length of the MAC
 * @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 algo or @a sym_key)
 * @retval #YACA_ERROR_OUT_OF_MEMORY Out of memory error
 * @retval #YACA_ERROR_INTERNAL Internal error
 * @see #yaca_key_type_e
 * @see #yaca_encrypt_algorithm_e
 * @see yaca_memcmp()
 * @see yaca_free()
 */
int yaca_simple_calculate_cmac(yaca_encrypt_algorithm_e algo, const yaca_key_h sym_key, const char *message, size_t message_len, char **mac, size_t *mac_len);


/**
 * @}
 */


#ifdef __cplusplus
} /* extern */
#endif


#endif /* YACA_SIMPLE_H */
