#ifndef _CORECRYPTO_CCMODE_INTERNAL_H_
#define _CORECRYPTO_CCMODE_INTERNAL_H_
#include <corecrypto/ccmode.h>
#include <corecrypto/ccmode_factory.h>
#include <corecrypto/cc_priv.h>
#include <corecrypto/cc_macros.h>
#define CCMODE_INVALID_INPUT -1
#define CCMODE_INVALID_CALL_SEQUENCE -2
#define CCMODE_INTEGRITY_FAILURE -3
#define CCMODE_NOT_SUPPORTED -4
#define CCMODE_INTERNAL_ERROR -5
#if \
((CCAES_INTEL_ASM && defined(__x86_64__)) || (CCAES_ARM_ASM && defined(__ARM_NEON__)))
#define CCMODE_GCM_VNG_SPEEDUP 1
#else
#define CCMODE_GCM_VNG_SPEEDUP 0
#endif
#define CCMODE_GCM_USE_GF_LOOKUP_TABLES 1
void ccmode_xts_mult_alpha(cc_unit *tweak);
#define _CCMODE_CBC_KEY(K) ((struct _ccmode_cbc_key *)(K))
#define _CCMODE_CBC_KEY_CONST(K) ((const struct _ccmode_cbc_key *)(K))
#define CCMODE_CBC_KEY_ECB(K) (_CCMODE_CBC_KEY(K)->ecb)
#define CCMODE_CBC_KEY_ECB_KEY(K) ((ccecb_ctx *)&_CCMODE_CBC_KEY(K)->u[0])
CC_CONST CC_INLINE
const struct ccmode_ecb * ccmode_cbc_key_ecb(const cccbc_ctx *K) {
return ((const struct _ccmode_cbc_key *)K)->ecb;
}
CC_CONST CC_INLINE
const ccecb_ctx * ccmode_cbc_key_ecb_key(const cccbc_ctx *K) {
return (const ccecb_ctx *)&((const struct _ccmode_cbc_key *)K)->u[0];
}
#define _CCMODE_CFB_KEY(K) ((struct _ccmode_cfb_key *)(K))
#define CCMODE_CFB_KEY_ECB(K) (_CCMODE_CFB_KEY(K)->ecb)
#define CCMODE_CFB_KEY_PAD_LEN(K) (_CCMODE_CFB_KEY(K)->pad_len)
#define CCMODE_CFB_KEY_PAD(K) (&_CCMODE_CFB_KEY(K)->u[0])
#define CCMODE_CFB_KEY_IV(K) (&_CCMODE_CFB_KEY(K)->u[ccn_nof_size(CCMODE_CFB_KEY_ECB(K)->block_size)])
#define CCMODE_CFB_KEY_ECB_KEY(K) ((ccecb_ctx *)&_CCMODE_CFB_KEY(K)->u[2 * ccn_nof_size(CCMODE_CFB_KEY_ECB(K)->block_size)])
#define _CCMODE_CFB8_KEY(K) ((struct _ccmode_cfb8_key *)(K))
#define CCMODE_CFB8_KEY_ECB(K) (_CCMODE_CFB8_KEY(K)->ecb)
#define CCMODE_CFB8_KEY_PAD(K) (&_CCMODE_CFB8_KEY(K)->u[0])
#define CCMODE_CFB8_KEY_IV(K) (&_CCMODE_CFB8_KEY(K)->u[ccn_nof_size(CCMODE_CFB8_KEY_ECB(K)->block_size)])
#define CCMODE_CFB8_KEY_ECB_KEY(K) ((ccecb_ctx *)&_CCMODE_CFB8_KEY(K)->u[2 * ccn_nof_size(CCMODE_CFB8_KEY_ECB(K)->block_size)])
#define _CCMODE_CTR_KEY(K) ((struct _ccmode_ctr_key *)(K))
#define CCMODE_CTR_KEY_ECB(K) (_CCMODE_CTR_KEY(K)->ecb)
#define CCMODE_CTR_KEY_PAD_OFFSET(K) (_CCMODE_CTR_KEY(K)->pad_offset)
#define CCMODE_CTR_KEY_PAD(K) (&_CCMODE_CTR_KEY(K)->u[0])
#define CCMODE_CTR_KEY_CTR(K) (&_CCMODE_CTR_KEY(K)->u[ccn_nof_size(CCMODE_CTR_KEY_ECB(K)->block_size)])
#define CCMODE_CTR_KEY_ECB_KEY(K) ((ccecb_ctx *)&_CCMODE_CTR_KEY(K)->u[2 * ccn_nof_size(CCMODE_CTR_KEY_ECB(K)->block_size)])
CC_INLINE int ccctr_setctr(const struct ccmode_ctr *mode, ccctr_ctx *ctx, const void *ctr)
{
return mode->setctr(mode, ctx, ctr);
}
#define _CCMODE_OFB_KEY(K) ((struct _ccmode_ofb_key *)(K))
#define CCMODE_OFB_KEY_ECB(K) (_CCMODE_OFB_KEY(K)->ecb)
#define CCMODE_OFB_KEY_PAD_LEN(K) (_CCMODE_OFB_KEY(K)->pad_len)
#define CCMODE_OFB_KEY_IV(K) (&_CCMODE_OFB_KEY(K)->u[0])
#define CCMODE_OFB_KEY_ECB_KEY(K) ((ccecb_ctx *)&_CCMODE_OFB_KEY(K)->u[ccn_nof_size(CCMODE_OFB_KEY_ECB(K)->block_size)])
#define _CCMODE_XTS_KEY(K) ((struct _ccmode_xts_key *)(K))
#define CCMODE_XTS_KEY_ECB(K) (_CCMODE_XTS_KEY(K)->ecb)
#define CCMODE_XTS_KEY_ECB_ENCRYPT(K) (_CCMODE_XTS_KEY(K)->ecb_encrypt)
#define CCMODE_XTS_KEY_DATA_KEY(K) ((ccecb_ctx *)&_CCMODE_XTS_KEY(K)->u[0])
#define CCMODE_XTS_KEY_TWEAK_KEY(K) ((ccecb_ctx *)&_CCMODE_XTS_KEY(K)->u[ccn_nof_size(CCMODE_XTS_KEY_ECB(K)->size)])
CC_CONST CC_INLINE
const struct ccmode_ecb * ccmode_xts_key_ecb(const ccxts_ctx *K) {
return ((const struct _ccmode_xts_key *)K)->ecb;
}
CC_CONST CC_INLINE
const struct ccmode_ecb * ccmode_xts_key_ecb_encrypt(const ccxts_ctx *K) {
return ((const struct _ccmode_xts_key *)K)->ecb_encrypt;
}
CC_CONST CC_INLINE
const ccecb_ctx * ccmode_xts_key_data_key(const ccxts_ctx *K) {
return (const ccecb_ctx *)&((const struct _ccmode_xts_key *)K)->u[0];
}
CC_CONST CC_INLINE
const ccecb_ctx * ccmode_xts_key_tweak_key(const ccxts_ctx *K) {
return (const ccecb_ctx *)&((const struct _ccmode_xts_key *)K)->u[ccn_nof_size(ccmode_xts_key_ecb(K)->size)];
}
#define _CCMODE_XTS_TWEAK(T) ((struct _ccmode_xts_tweak *)(T))
#define CCMODE_XTS_TWEAK_BLOCK_PROCESSED(T)(_CCMODE_XTS_TWEAK(T)->blocks_processed)
#define CCMODE_XTS_TWEAK_VALUE(T) (_CCMODE_XTS_TWEAK(T)->u)
#define _CCMODE_GCM_KEY(K) ((struct _ccmode_gcm_key *)(K))
#define CCMODE_GCM_KEY_H(K) (_CCMODE_GCM_KEY(K)->H)
#define CCMODE_GCM_KEY_X(K) (_CCMODE_GCM_KEY(K)->X)
#define CCMODE_GCM_KEY_Y(K) (_CCMODE_GCM_KEY(K)->Y)
#define CCMODE_GCM_KEY_Y_0(K) (_CCMODE_GCM_KEY(K)->Y_0)
#define CCMODE_GCM_KEY_PAD_LEN(K) (_CCMODE_GCM_KEY(K)->buf_nbytes)
#define CCMODE_GCM_KEY_PAD(K) (_CCMODE_GCM_KEY(K)->buf)
#define _CCMODE_GCM_ECB_MODE(K) ((struct _ccmode_gcm_key *)(K))
#define CCMODE_GCM_KEY_ECB(K) (_CCMODE_GCM_ECB_MODE(K)->ecb)
#define CCMODE_GCM_KEY_ECB_KEY(K) ((ccecb_ctx *)_CCMODE_GCM_ECB_MODE(K)->ecb_key) // set in init function
#define CCMODE_GCM_STATE_IV 1
#define CCMODE_GCM_STATE_AAD 2
#define CCMODE_GCM_STATE_TEXT 3
#define CCMODE_GCM_STATE_FINAL 4
#define CCMODE_STATE_INIT 2 //first call to init
#define CCMODE_STATE_IV_START 3 //first call to set_iv
#define CCMODE_STATE_IV_CONT CCMODE_STATE_IV_START
#define CCMODE_STATE_AAD 4
#define CCMODE_STATE_TEXT 5
#define CCMODE_CCM_STATE_IV 1
void ccmode_gcm_gf_mult(const unsigned char *a, const unsigned char *b,
unsigned char *c);
void ccmode_gcm_mult_h(ccgcm_ctx *key, unsigned char *I);
#define _CCMODE_CCM_KEY(K) ((struct _ccmode_ccm_key *)(K))
#define CCMODE_CCM_KEY_ECB(K) (_CCMODE_CCM_KEY(K)->ecb)
#define CCMODE_CCM_KEY_ECB_KEY(K) ((ccecb_ctx *)&_CCMODE_CCM_KEY(K)->u[0])
#define _CCMODE_CCM_NONCE(N) ((struct _ccmode_ccm_nonce *)(N))
#define CCMODE_CCM_KEY_MAC(N) (_CCMODE_CCM_NONCE(N)->MAC)
#define CCMODE_CCM_KEY_A_I(N) (_CCMODE_CCM_NONCE(N)->A_i)
#define CCMODE_CCM_KEY_B_I(N) (_CCMODE_CCM_NONCE(N)->B_i)
#define CCMODE_CCM_KEY_PAD_LEN(N) (_CCMODE_CCM_NONCE(N)->buflen)
#define CCMODE_CCM_KEY_PAD(N) (_CCMODE_CCM_NONCE(N)->buf)
#define CCMODE_CCM_KEY_MAC_LEN(N) (_CCMODE_CCM_NONCE(N)->mac_size)
#define CCMODE_CCM_KEY_NONCE_LEN(N) (_CCMODE_CCM_NONCE(N)->nonce_size)
#define CCMODE_CCM_KEY_AUTH_LEN(N) (_CCMODE_CCM_NONCE(N)->b_i_len)
#define _CCMODE_OMAC_KEY(K) ((struct _ccmode_omac_key *)(K))
#define CCMODE_OMAC_KEY_ECB(K) (_CCMODE_OMAC_KEY(K)->ecb)
#define CCMODE_OMAC_KEY_TWEAK_LEN(K) (_CCMODE_OMAC_KEY(K)->tweak_len)
#define CCMODE_OMAC_KEY_ECB_KEY(K) ((ccecb_ctx *)&_CCMODE_OMAC_KEY(K)->u[0])
CC_INLINE void inc_uint(uint8_t *buf, size_t nbytes)
{
size_t i;
for (i = 0; i < nbytes; i += 1) {
if (++buf[nbytes-1-i] & 255) { break; }
}
}
CC_INLINE void ccmode_gcm_update_pad(ccgcm_ctx *key)
{
inc_uint(CCMODE_GCM_KEY_Y(key) + 12, 4);
CCMODE_GCM_KEY_ECB(key)->ecb(CCMODE_GCM_KEY_ECB_KEY(key), 1,
CCMODE_GCM_KEY_Y(key),
CCMODE_GCM_KEY_PAD(key));
}
CC_INLINE void ccmode_gcm_aad_finalize(ccgcm_ctx *key)
{
if (_CCMODE_GCM_KEY(key)->state == CCMODE_GCM_STATE_AAD) {
if (_CCMODE_GCM_KEY(key)->aad_nbytes % CCGCM_BLOCK_NBYTES > 0) {
ccmode_gcm_mult_h(key, CCMODE_GCM_KEY_X(key));
}
_CCMODE_GCM_KEY(key)->state = CCMODE_GCM_STATE_TEXT;
}
}
CC_INLINE void xor_128bits(unsigned char *r, const unsigned char *a, const unsigned char *b)
{
cc_unit *r1 = (cc_unit *)r;
const cc_unit *a1 = (const cc_unit *)a;
const cc_unit *b1 = (const cc_unit *)b;
for (int i=0; i<128/(CCN_UNIT_SIZE*8); i++) {
r1[i] = a1[i] ^ b1[i];
}
}
#endif