/* * sESTATE_TweAES-128 * * * sESTATE_TweAES-128 ia a determinsitic AEAD based on the ESTATE mode * of operation and TweAES-128 tweakable block cipher. sESTATE uses the * 6-round variant of TweAES-128 in tag generation phase along with the * normal ESTATE mode of operation. It also uses tweak values 0x0f for * the tag generation phase, so that the tag generation and encryption * phase use tweaks with maximum distance codewords. * * Test Vector (in little endian format): * Key : 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 * Nonce: 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 * PT : * AD : * CT : A6 4C F6 A7 37 71 F2 AA 5C 4D 75 45 E0 46 5B 08 * */ #include "crypto_aead.h" #include "api.h" #include "estate.h" /********************************************************************** * * @name : xor_bytes * * @note : XORs "num" many bytes of "src" to "dest". * **********************************************************************/ static void xor_bytes(u8 *dest, const u8 *src, u8 num) { for(u8 i=0; i < num; i++) { dest[i] ^= src[i]; } } /********************************************************************** * * @name : memcpy_and_zero_one_pad * * @note : Copies src bytes to dest and pads with 10* to create * CRYPTO_BLOCKBYTES-oriented data. * **********************************************************************/ static void memcpy_and_zero_one_pad(u8* dest, const u8 *src, u8 len) { memset(dest, 0, CRYPTO_BLOCKBYTES); memcpy(dest, src, len); dest[len] ^= 0x01; } /********************************************************************** * * @name : fcbc_star * * @note : FCBC* processing of input with some iv given in tag * itself. * **********************************************************************/ static void fcbc_star(u8 *tag, const u8 (*round_keys)[16], const u8 *in, const u64 inlen, const u64 in_blocks, const u8 *twks) { u8 fifteen = 0x0f; u8 temp[CRYPTO_BLOCKBYTES]; // process intermediate blocks with round-reduced // block cipher using tweak value fifteen for(u64 j=0; j 0) { // process non-empty ad blocks twks[0] = ptlen != 0 ? 0x02 : 0x06; twks[1] = ptlen != 0 ? 0x03 : 0x07; fcbc_star(&tag[0], &round_keys[0], ad, adlen, ad_blocks, &twks[0]); } if(ptlen > 0) { // process non-empty pt blocks twks[0] = 0x04; twks[1] = 0x05; fcbc_star(&tag[0], &round_keys[0], pt, ptlen, pt_blocks, &twks[0]); } } /********************************************************************** * * @name : ofb * * @note : Ciphertext generation using OFB module. * **********************************************************************/ static void ofb(u8 *out, u64 *outlen, const u8 (*round_keys)[16], const u8 *iv, const u8 *in, const u64 inlen, const u64 in_blocks) { u8 twk = 0x00; u8 iv_[CRYPTO_BLOCKBYTES]; u8 temp[CRYPTO_BLOCKBYTES]; *outlen = 0; // process non-last blocks memcpy(iv_, iv, CRYPTO_BLOCKBYTES); for(u8 i=0; i