From 0c2ff4a1b0262fd6e8c773abf1437aa1e395db34 Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Wed, 2 Aug 2017 18:55:34 +0200 Subject: [PATCH] OCBv3: small review * better LTC_ARGCHK() * move unnecessary functions from API to be static * limit malloc'ed data in ocb3_decrypt_verify_memory() --- src/encauth/ocb3/ocb3_add_aad.c | 30 +++++++- src/encauth/ocb3/ocb3_decrypt_last.c | 1 + src/encauth/ocb3/ocb3_decrypt_verify_memory.c | 7 +- .../ocb3/ocb3_encrypt_authenticate_memory.c | 5 -- src/encauth/ocb3/ocb3_init.c | 53 +++++++++++++- src/encauth/ocb3/ocb3_int_aad_add_block.c | 49 ------------- src/encauth/ocb3/ocb3_int_calc_offset_zero.c | 73 ------------------- src/headers/tomcrypt_mac.h | 2 - 8 files changed, 82 insertions(+), 138 deletions(-) delete mode 100644 src/encauth/ocb3/ocb3_int_aad_add_block.c delete mode 100644 src/encauth/ocb3/ocb3_int_calc_offset_zero.c diff --git a/src/encauth/ocb3/ocb3_add_aad.c b/src/encauth/ocb3/ocb3_add_aad.c index 755ec4c..98a285d 100644 --- a/src/encauth/ocb3/ocb3_add_aad.c +++ b/src/encauth/ocb3/ocb3_add_aad.c @@ -15,6 +15,32 @@ #ifdef LTC_OCB3_MODE +/** + Add one block of AAD data (internal function) + @param ocb The OCB state + @param aad_block [in] AAD data (block_len size) + @return CRYPT_OK if successful +*/ +static int _ocb3_int_aad_add_block(ocb3_state *ocb, const unsigned char *aad_block) +{ + unsigned char tmp[MAXBLOCKSIZE]; + int err; + + /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ + ocb3_int_xor_blocks(ocb->aOffset_current, ocb->aOffset_current, ocb->L_[ocb3_int_ntz(ocb->ablock_index)], ocb->block_len); + + /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ + ocb3_int_xor_blocks(tmp, aad_block, ocb->aOffset_current, ocb->block_len); + if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) { + return err; + } + ocb3_int_xor_blocks(ocb->aSum_current, ocb->aSum_current, tmp, ocb->block_len); + + ocb->ablock_index++; + + return CRYPT_OK; +} + /** Add AAD - additional associated data @param ocb The OCB state @@ -41,7 +67,7 @@ int ocb3_add_aad(ocb3_state *ocb, const unsigned char *aad, unsigned long aadlen ocb->adata_buffer_bytes += l; if (ocb->adata_buffer_bytes == ocb->block_len) { - if ((err = ocb3_int_aad_add_block(ocb, ocb->adata_buffer)) != CRYPT_OK) { + if ((err = _ocb3_int_aad_add_block(ocb, ocb->adata_buffer)) != CRYPT_OK) { return err; } ocb->adata_buffer_bytes = 0; @@ -62,7 +88,7 @@ int ocb3_add_aad(ocb3_state *ocb, const unsigned char *aad, unsigned long aadlen last_block_len = datalen - full_blocks_len; for (x=0; xblock_len)) != CRYPT_OK) { + if ((err = _ocb3_int_aad_add_block(ocb, data+x*ocb->block_len)) != CRYPT_OK) { return err; } } diff --git a/src/encauth/ocb3/ocb3_decrypt_last.c b/src/encauth/ocb3/ocb3_decrypt_last.c index 3477f23..bc99094 100644 --- a/src/encauth/ocb3/ocb3_decrypt_last.c +++ b/src/encauth/ocb3/ocb3_decrypt_last.c @@ -31,6 +31,7 @@ int ocb3_decrypt_last(ocb3_state *ocb, const unsigned char *ct, unsigned long ct LTC_ARGCHK(ocb != NULL); LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(pt != NULL); if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) { goto LBL_ERR; } diff --git a/src/encauth/ocb3/ocb3_decrypt_verify_memory.c b/src/encauth/ocb3/ocb3_decrypt_verify_memory.c index 9288d33..486168d 100644 --- a/src/encauth/ocb3/ocb3_decrypt_verify_memory.c +++ b/src/encauth/ocb3/ocb3_decrypt_verify_memory.c @@ -46,18 +46,13 @@ int ocb3_decrypt_verify_memory(int cipher, unsigned char *buf; unsigned long buflen; - LTC_ARGCHK(key != NULL); - LTC_ARGCHK(nonce != NULL); - LTC_ARGCHK(pt != NULL); - LTC_ARGCHK(ct != NULL); - LTC_ARGCHK(tag != NULL); LTC_ARGCHK(stat != NULL); /* default to zero */ *stat = 0; /* allocate memory */ - buf = XMALLOC(taglen); + buf = XMALLOC(MIN(taglen, MAXBLOCKSIZE)); ocb = XMALLOC(sizeof(ocb3_state)); if (ocb == NULL || buf == NULL) { if (ocb != NULL) { diff --git a/src/encauth/ocb3/ocb3_encrypt_authenticate_memory.c b/src/encauth/ocb3/ocb3_encrypt_authenticate_memory.c index 10d1617..efc1a8f 100644 --- a/src/encauth/ocb3/ocb3_encrypt_authenticate_memory.c +++ b/src/encauth/ocb3/ocb3_encrypt_authenticate_memory.c @@ -42,11 +42,6 @@ int ocb3_encrypt_authenticate_memory(int cipher, int err; ocb3_state *ocb; - LTC_ARGCHK(key != NULL); - LTC_ARGCHK(nonce != NULL); - LTC_ARGCHK(pt != NULL); - LTC_ARGCHK(ct != NULL); - LTC_ARGCHK(tag != NULL); LTC_ARGCHK(taglen != NULL); /* allocate memory */ diff --git a/src/encauth/ocb3/ocb3_init.c b/src/encauth/ocb3/ocb3_init.c index 9cea63d..573fe15 100644 --- a/src/encauth/ocb3/ocb3_init.c +++ b/src/encauth/ocb3/ocb3_init.c @@ -15,6 +15,57 @@ #ifdef LTC_OCB3_MODE +/** + Sets 'ocb->Offset_current' to 'Offset_0' value (internal function) + @param ocb The OCB state + @param nonce The session nonce + @param noncelen The length of the session nonce (octets) +*/ +static void _ocb3_int_calc_offset_zero(ocb3_state *ocb, const unsigned char *nonce, unsigned long noncelen, unsigned long taglen) +{ + int x, y, bottom; + int idx, shift; + unsigned char iNonce[MAXBLOCKSIZE]; + unsigned char iKtop[MAXBLOCKSIZE]; + unsigned char iStretch[MAXBLOCKSIZE+8]; + + /* Nonce = zeros(127-bitlen(N)) || 1 || N */ + zeromem(iNonce, sizeof(iNonce)); + for (x = ocb->block_len-1, y=0; y<(int)noncelen; x--, y++) { + iNonce[x] = nonce[noncelen-y-1]; + } + iNonce[x] = 0x01; + iNonce[0] |= ((taglen*8) % 128) << 1; + + /* bottom = str2num(Nonce[123..128]) */ + bottom = iNonce[ocb->block_len-1] & 0x3F; + + /* Ktop = ENCIPHER(K, Nonce[1..122] || zeros(6)) */ + iNonce[ocb->block_len-1] = iNonce[ocb->block_len-1] & 0xC0; + if ((cipher_descriptor[ocb->cipher].ecb_encrypt(iNonce, iKtop, &ocb->key)) != CRYPT_OK) { + zeromem(ocb->Offset_current, ocb->block_len); + return; + } + + /* Stretch = Ktop || (Ktop[1..64] xor Ktop[9..72]) */ + for (x = 0; x < ocb->block_len; x++) { + iStretch[x] = iKtop[x]; + } + for (y = 0; y < 8; y++) { + iStretch[x+y] = iKtop[y] ^ iKtop[y+1]; + } + + /* Offset_0 = Stretch[1+bottom..128+bottom] */ + idx = bottom / 8; + shift = (bottom % 8); + for (x = 0; x < ocb->block_len; x++) { + ocb->Offset_current[x] = iStretch[idx+x] << shift; + if (shift > 0) { + ocb->Offset_current[x] |= iStretch[idx+x+1] >> (8-shift); + } + } +} + static const struct { int len; unsigned char poly_mul[MAXBLOCKSIZE]; @@ -120,7 +171,7 @@ int ocb3_init(ocb3_state *ocb, int cipher, } /* initialize ocb->Offset_current = Offset_0 */ - ocb3_int_calc_offset_zero(ocb, nonce, noncelen, taglen); + _ocb3_int_calc_offset_zero(ocb, nonce, noncelen, taglen); /* initialize checksum to all zeros */ zeromem(ocb->checksum, ocb->block_len); diff --git a/src/encauth/ocb3/ocb3_int_aad_add_block.c b/src/encauth/ocb3/ocb3_int_aad_add_block.c deleted file mode 100644 index 7f86ab0..0000000 --- a/src/encauth/ocb3/ocb3_int_aad_add_block.c +++ /dev/null @@ -1,49 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - */ - -/** - @file ocb3_int_aad_add_block.c - OCB implementation, INTERNALL ONLY helper, by Karel Miko -*/ -#include "tomcrypt.h" - -#ifdef LTC_OCB3_MODE - -/** - Add one block of AAD data (internal function) - @param ocb The OCB state - @param aad_block [in] AAD data (block_len size) - @return CRYPT_OK if successful -*/ -int ocb3_int_aad_add_block(ocb3_state *ocb, const unsigned char *aad_block) -{ - unsigned char tmp[MAXBLOCKSIZE]; - int err; - - /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ - ocb3_int_xor_blocks(ocb->aOffset_current, ocb->aOffset_current, ocb->L_[ocb3_int_ntz(ocb->ablock_index)], ocb->block_len); - - /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ - ocb3_int_xor_blocks(tmp, aad_block, ocb->aOffset_current, ocb->block_len); - if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) { - return err; - } - ocb3_int_xor_blocks(ocb->aSum_current, ocb->aSum_current, tmp, ocb->block_len); - - ocb->ablock_index++; - - return CRYPT_OK; -} - -#endif - - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/src/encauth/ocb3/ocb3_int_calc_offset_zero.c b/src/encauth/ocb3/ocb3_int_calc_offset_zero.c deleted file mode 100644 index a80c6b7..0000000 --- a/src/encauth/ocb3/ocb3_int_calc_offset_zero.c +++ /dev/null @@ -1,73 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - */ - -/** - @file ocb3_int_calc_offset_zero.c - OCB implementation, INTERNAL ONLY helper, by Karel Miko -*/ -#include "tomcrypt.h" - -#ifdef LTC_OCB3_MODE - -/** - Sets 'ocb->Offset_current' to 'Offset_0' value (internal function) - @param ocb The OCB state - @param nonce The session nonce - @param noncelen The length of the session nonce (octets) -*/ -void ocb3_int_calc_offset_zero(ocb3_state *ocb, const unsigned char *nonce, unsigned long noncelen, unsigned long taglen) -{ - int x, y, bottom; - int idx, shift; - unsigned char iNonce[MAXBLOCKSIZE]; - unsigned char iKtop[MAXBLOCKSIZE]; - unsigned char iStretch[MAXBLOCKSIZE+8]; - - /* Nonce = zeros(127-bitlen(N)) || 1 || N */ - zeromem(iNonce, sizeof(iNonce)); - for (x = ocb->block_len-1, y=0; y<(int)noncelen; x--, y++) { - iNonce[x] = nonce[noncelen-y-1]; - } - iNonce[x] = 0x01; - iNonce[0] |= ((taglen*8) % 128) << 1; - - /* bottom = str2num(Nonce[123..128]) */ - bottom = iNonce[ocb->block_len-1] & 0x3F; - - /* Ktop = ENCIPHER(K, Nonce[1..122] || zeros(6)) */ - iNonce[ocb->block_len-1] = iNonce[ocb->block_len-1] & 0xC0; - if ((cipher_descriptor[ocb->cipher].ecb_encrypt(iNonce, iKtop, &ocb->key)) != CRYPT_OK) { - zeromem(ocb->Offset_current, ocb->block_len); - return; - } - - /* Stretch = Ktop || (Ktop[1..64] xor Ktop[9..72]) */ - for (x = 0; x < ocb->block_len; x++) { - iStretch[x] = iKtop[x]; - } - for (y = 0; y < 8; y++) { - iStretch[x+y] = iKtop[y] ^ iKtop[y+1]; - } - - /* Offset_0 = Stretch[1+bottom..128+bottom] */ - idx = bottom / 8; - shift = (bottom % 8); - for (x = 0; x < ocb->block_len; x++) { - ocb->Offset_current[x] = iStretch[idx+x] << shift; - if (shift > 0) { - ocb->Offset_current[x] |= iStretch[idx+x+1] >> (8-shift); - } - } -} - -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/src/headers/tomcrypt_mac.h b/src/headers/tomcrypt_mac.h index b74761c..2a2a011 100644 --- a/src/headers/tomcrypt_mac.h +++ b/src/headers/tomcrypt_mac.h @@ -302,8 +302,6 @@ int ocb3_test(void); #ifdef LTC_SOURCE /* internal helper functions */ -int ocb3_int_aad_add_block(ocb3_state *ocb, const unsigned char *aad_block); -void ocb3_int_calc_offset_zero(ocb3_state *ocb, const unsigned char *nonce, unsigned long noncelen, unsigned long taglen); int ocb3_int_ntz(unsigned long x); void ocb3_int_xor_blocks(unsigned char *out, const unsigned char *block_a, const unsigned char *block_b, unsigned long block_len); #endif /* LTC_SOURCE */