#ifndef crypt_H_
#define crypt_H_

#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <tomcrypt.h>

#include "utils.h"

#define TAG_LEN 16

/* Operation context used during multi-step symmetric encryption*/
typedef struct cop_t {
    chacha20poly1305_state st;
    bool is_encrypt;
} cop_t;

/* -----------------------------------------------------------------------------
 * @brief   Starts symmetric crypto operation
 *
 * @param   ctx operation context. Caller must indicate wether he is going
 *              going to do encryption or decryption
 * @param   key pointer to the buffer with key
 * @param   iv pointer to the buffer with nonce
 *
 * @returns 1 on success and user can perform `crypt_update' or `crypt_finish'
 *          or 0 on failure. In case of failure user must not ctx anymore.
-------------------------------------------------------------------------------- */
int crypt_begin(
    cop_t* ctx,
    const buf_t* key,
    const buf_t* nonce);


/* -----------------------------------------------------------------------------
 * @brief   Caller uses this function to provide data that should be processed.
 *
 * @param   ctx Context initialized by crypt_begin
 * @param   in Pointer to buffer with data to be processed
 * @param   out [out] Buffer to which function will write processed data
 *              Length of this buffer must be exactly same as in_len (stream
 *              cipher is used)
 *
 * @return  1 on success, otherwise 0 and ctx is unusable.
 *
-------------------------------------------------------------------------------- */
int crypt_update(
    cop_t *ctx,
    const buf_t *in,
    uint8_t *out);


/* -----------------------------------------------------------------------------
 * @brief   Finishes crypto operation and authenticates the data.
 *          On encryption function will write authentication tag
 *          to the 'tag' buffer. On decryption function
 *          calculates MAC of the data and compers it with the one
 *          provided in 'tag' buffer.
 *
 * @param   ctx Context initialized by crypt_begin
 * @param   tag [in/out] Buffer with authentication tag
 *
 * @return  1 on success, othewise 0
 *
-------------------------------------------------------------------------------- */
int crypt_finish(
    cop_t *ctx,
    uint8_t tag[TAG_LEN]);

#endif /* _crypt_ */
