#ifndef _CORECRYPTO_CCMODE_SIV_H_
#define _CORECRYPTO_CCMODE_SIV_H_
#include <corecrypto/cc.h>
#include <corecrypto/ccmode.h>
#include <corecrypto/ccmode_impl.h>
#include <corecrypto/cccmac.h>
cc_aligned_struct(16) ccsiv_ctx;
struct ccmode_siv {
size_t size;
size_t block_size;
int (*init)(const struct ccmode_siv *siv, ccsiv_ctx *ctx,
size_t key_len, const uint8_t *key);
int (*set_nonce)(ccsiv_ctx *ctx, size_t nbytes, const uint8_t *in); int (*auth)(ccsiv_ctx *ctx, size_t nbytes, const uint8_t *in); int (*crypt)(ccsiv_ctx *ctx, size_t nbytes, const uint8_t *in, uint8_t *out);
int (*reset)(ccsiv_ctx *ctx);
const struct ccmode_cbc *cbc;
const struct ccmode_ctr *ctr;
};
#define ccsiv_ctx_decl(_size_, _name_) cc_ctx_decl(ccsiv_ctx, _size_, _name_)
#define ccsiv_ctx_clear(_size_, _name_) cc_clear(_size_, _name_)
CC_INLINE size_t ccsiv_context_size(const struct ccmode_siv *mode)
{
return mode->size;
}
CC_INLINE size_t ccsiv_block_size(const struct ccmode_siv *mode)
{
return mode->block_size;
}
CC_INLINE size_t ccsiv_ciphertext_size(const struct ccmode_siv *mode,
size_t plaintext_size)
{
return plaintext_size+mode->cbc->block_size;
}
CC_INLINE size_t ccsiv_plaintext_size(const struct ccmode_siv *mode,
size_t ciphertext_size)
{
if (ciphertext_size<mode->cbc->block_size) {
return 0; }
return ciphertext_size-mode->cbc->block_size;
}
CC_INLINE int ccsiv_init(const struct ccmode_siv *mode, ccsiv_ctx *ctx,
size_t key_byte_len, const uint8_t *key)
{
return mode->init(mode, ctx, key_byte_len, key);
}
CC_INLINE int ccsiv_set_nonce(const struct ccmode_siv *mode, ccsiv_ctx *ctx,
size_t nbytes, const uint8_t *in)
{
return mode->set_nonce(ctx, nbytes, in);
}
CC_INLINE int ccsiv_aad(const struct ccmode_siv *mode, ccsiv_ctx *ctx,
size_t nbytes, const uint8_t *in)
{
return mode->auth(ctx, nbytes, in);
}
CC_INLINE int ccsiv_crypt(const struct ccmode_siv *mode, ccsiv_ctx *ctx,
size_t nbytes, const uint8_t *in, uint8_t *out)
{
return mode->crypt(ctx, nbytes, in, out);
}
CC_INLINE int ccsiv_reset(const struct ccmode_siv *mode, ccsiv_ctx *ctx)
{
return mode->reset(ctx);
}
CC_INLINE int ccsiv_one_shot(const struct ccmode_siv *mode,
size_t key_len, const uint8_t *key,
unsigned nonce_nbytes, const uint8_t* nonce,
unsigned adata_nbytes, const uint8_t* adata,
size_t in_nbytes, const uint8_t *in, uint8_t *out)
{
int rc;
ccsiv_ctx_decl(mode->size, ctx);
rc=mode->init(mode, ctx, key_len, key);
if (rc) {return rc;}
rc=mode->set_nonce(ctx, nonce_nbytes, nonce);
if (rc) {return rc;}
rc=mode->auth(ctx, adata_nbytes, adata);
if (rc) {return rc;}
rc=mode->crypt(ctx, in_nbytes, in, out);
if (rc) {return rc;}
ccsiv_ctx_clear(mode->size, ctx);
return rc;
}
void ccmode_factory_siv_encrypt(struct ccmode_siv *siv,
const struct ccmode_cbc *cbc,
const struct ccmode_ctr *ctr);
void ccmode_factory_siv_decrypt(struct ccmode_siv *siv,
const struct ccmode_cbc *cbc,
const struct ccmode_ctr *ctr);
#endif