Merge pull request #256 from libtom/fix/256
OCB3 is not according to RFC7253
This commit is contained in:
commit
05f7393067
@ -1273,7 +1273,7 @@ static void time_encmacs_(unsigned long MAC_SIZE)
|
||||
t_start();
|
||||
t1 = t_read();
|
||||
z = 16;
|
||||
if ((err = ocb3_encrypt_authenticate_memory(cipher_idx, key, 16, IV, 16, (unsigned char*)"", 0, buf, MAC_SIZE*1024, buf, tag, &z)) != CRYPT_OK) {
|
||||
if ((err = ocb3_encrypt_authenticate_memory(cipher_idx, key, 16, IV, 15, (unsigned char*)"", 0, buf, MAC_SIZE*1024, buf, tag, &z)) != CRYPT_OK) {
|
||||
fprintf(stderr, "\nOCB3 error... %s\n", error_to_string(err));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
@ -420,7 +420,7 @@ void ocb_gen(void)
|
||||
void ocb3_gen(void)
|
||||
{
|
||||
#ifdef LTC_OCB3_MODE
|
||||
int err, kl, x, y1, z;
|
||||
int err, kl, x, y1, z, noncelen;
|
||||
FILE *out;
|
||||
unsigned char key[MAXBLOCKSIZE], nonce[MAXBLOCKSIZE*2],
|
||||
plaintext[MAXBLOCKSIZE*2], tag[MAXBLOCKSIZE];
|
||||
@ -448,7 +448,8 @@ void ocb3_gen(void)
|
||||
}
|
||||
|
||||
/* fixed nonce */
|
||||
for (z = 0; z < cipher_descriptor[x].block_length; z++) {
|
||||
noncelen = MIN(15, cipher_descriptor[x].block_length);
|
||||
for (z = 0; z < noncelen; z++) {
|
||||
nonce[z] = z;
|
||||
}
|
||||
|
||||
@ -456,8 +457,8 @@ void ocb3_gen(void)
|
||||
for (z = 0; z < y1; z++) {
|
||||
plaintext[z] = (unsigned char)(z & 255);
|
||||
}
|
||||
len = sizeof(tag);
|
||||
if ((err = ocb3_encrypt_authenticate_memory(x, key, kl, nonce, cipher_descriptor[x].block_length, (unsigned char*)"AAD", 3, plaintext, y1, plaintext, tag, &len)) != CRYPT_OK) {
|
||||
len = 16;
|
||||
if ((err = ocb3_encrypt_authenticate_memory(x, key, kl, nonce, noncelen, (unsigned char*)"AAD", 3, plaintext, y1, plaintext, tag, &len)) != CRYPT_OK) {
|
||||
printf("Error OCB'ing: %s\n", error_to_string(err));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
@ -798,14 +798,6 @@
|
||||
RelativePath="src\encauth\ocb3\ocb3_init.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="src\encauth\ocb3\ocb3_int_aad_add_block.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="src\encauth\ocb3\ocb3_int_calc_offset_zero.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="src\encauth\ocb3\ocb3_int_ntz.c"
|
||||
>
|
||||
|
@ -61,10 +61,9 @@ src/encauth/ocb/ocb_shift_xor.o src/encauth/ocb/ocb_test.o src/encauth/ocb/s_ocb
|
||||
src/encauth/ocb3/ocb3_add_aad.o src/encauth/ocb3/ocb3_decrypt.o src/encauth/ocb3/ocb3_decrypt_last.o \
|
||||
src/encauth/ocb3/ocb3_decrypt_verify_memory.o src/encauth/ocb3/ocb3_done.o \
|
||||
src/encauth/ocb3/ocb3_encrypt.o src/encauth/ocb3/ocb3_encrypt_authenticate_memory.o \
|
||||
src/encauth/ocb3/ocb3_encrypt_last.o src/encauth/ocb3/ocb3_init.o \
|
||||
src/encauth/ocb3/ocb3_int_aad_add_block.o src/encauth/ocb3/ocb3_int_calc_offset_zero.o \
|
||||
src/encauth/ocb3/ocb3_int_ntz.o src/encauth/ocb3/ocb3_int_xor_blocks.o src/encauth/ocb3/ocb3_test.o \
|
||||
src/hashes/blake2b.o src/hashes/blake2s.o src/hashes/chc/chc.o src/hashes/helper/hash_file.o \
|
||||
src/encauth/ocb3/ocb3_encrypt_last.o src/encauth/ocb3/ocb3_init.o src/encauth/ocb3/ocb3_int_ntz.o \
|
||||
src/encauth/ocb3/ocb3_int_xor_blocks.o src/encauth/ocb3/ocb3_test.o src/hashes/blake2b.o \
|
||||
src/hashes/blake2s.o src/hashes/chc/chc.o src/hashes/helper/hash_file.o \
|
||||
src/hashes/helper/hash_filehandle.o src/hashes/helper/hash_memory.o \
|
||||
src/hashes/helper/hash_memory_multi.o src/hashes/md2.o src/hashes/md4.o src/hashes/md5.o \
|
||||
src/hashes/rmd128.o src/hashes/rmd160.o src/hashes/rmd256.o src/hashes/rmd320.o src/hashes/sha1.o \
|
||||
|
@ -54,10 +54,9 @@ src/encauth/ocb/ocb_shift_xor.obj src/encauth/ocb/ocb_test.obj src/encauth/ocb/s
|
||||
src/encauth/ocb3/ocb3_add_aad.obj src/encauth/ocb3/ocb3_decrypt.obj src/encauth/ocb3/ocb3_decrypt_last.obj \
|
||||
src/encauth/ocb3/ocb3_decrypt_verify_memory.obj src/encauth/ocb3/ocb3_done.obj \
|
||||
src/encauth/ocb3/ocb3_encrypt.obj src/encauth/ocb3/ocb3_encrypt_authenticate_memory.obj \
|
||||
src/encauth/ocb3/ocb3_encrypt_last.obj src/encauth/ocb3/ocb3_init.obj \
|
||||
src/encauth/ocb3/ocb3_int_aad_add_block.obj src/encauth/ocb3/ocb3_int_calc_offset_zero.obj \
|
||||
src/encauth/ocb3/ocb3_int_ntz.obj src/encauth/ocb3/ocb3_int_xor_blocks.obj src/encauth/ocb3/ocb3_test.obj \
|
||||
src/hashes/blake2b.obj src/hashes/blake2s.obj src/hashes/chc/chc.obj src/hashes/helper/hash_file.obj \
|
||||
src/encauth/ocb3/ocb3_encrypt_last.obj src/encauth/ocb3/ocb3_init.obj src/encauth/ocb3/ocb3_int_ntz.obj \
|
||||
src/encauth/ocb3/ocb3_int_xor_blocks.obj src/encauth/ocb3/ocb3_test.obj src/hashes/blake2b.obj \
|
||||
src/hashes/blake2s.obj src/hashes/chc/chc.obj src/hashes/helper/hash_file.obj \
|
||||
src/hashes/helper/hash_filehandle.obj src/hashes/helper/hash_memory.obj \
|
||||
src/hashes/helper/hash_memory_multi.obj src/hashes/md2.obj src/hashes/md4.obj src/hashes/md5.obj \
|
||||
src/hashes/rmd128.obj src/hashes/rmd160.obj src/hashes/rmd256.obj src/hashes/rmd320.obj src/hashes/sha1.obj \
|
||||
|
@ -71,10 +71,9 @@ src/encauth/ocb/ocb_shift_xor.o src/encauth/ocb/ocb_test.o src/encauth/ocb/s_ocb
|
||||
src/encauth/ocb3/ocb3_add_aad.o src/encauth/ocb3/ocb3_decrypt.o src/encauth/ocb3/ocb3_decrypt_last.o \
|
||||
src/encauth/ocb3/ocb3_decrypt_verify_memory.o src/encauth/ocb3/ocb3_done.o \
|
||||
src/encauth/ocb3/ocb3_encrypt.o src/encauth/ocb3/ocb3_encrypt_authenticate_memory.o \
|
||||
src/encauth/ocb3/ocb3_encrypt_last.o src/encauth/ocb3/ocb3_init.o \
|
||||
src/encauth/ocb3/ocb3_int_aad_add_block.o src/encauth/ocb3/ocb3_int_calc_offset_zero.o \
|
||||
src/encauth/ocb3/ocb3_int_ntz.o src/encauth/ocb3/ocb3_int_xor_blocks.o src/encauth/ocb3/ocb3_test.o \
|
||||
src/hashes/blake2b.o src/hashes/blake2s.o src/hashes/chc/chc.o src/hashes/helper/hash_file.o \
|
||||
src/encauth/ocb3/ocb3_encrypt_last.o src/encauth/ocb3/ocb3_init.o src/encauth/ocb3/ocb3_int_ntz.o \
|
||||
src/encauth/ocb3/ocb3_int_xor_blocks.o src/encauth/ocb3/ocb3_test.o src/hashes/blake2b.o \
|
||||
src/hashes/blake2s.o src/hashes/chc/chc.o src/hashes/helper/hash_file.o \
|
||||
src/hashes/helper/hash_filehandle.o src/hashes/helper/hash_memory.o \
|
||||
src/hashes/helper/hash_memory_multi.o src/hashes/md2.o src/hashes/md4.o src/hashes/md5.o \
|
||||
src/hashes/rmd128.o src/hashes/rmd160.o src/hashes/rmd256.o src/hashes/rmd320.o src/hashes/sha1.o \
|
||||
|
@ -205,10 +205,9 @@ src/encauth/ocb/ocb_shift_xor.o src/encauth/ocb/ocb_test.o src/encauth/ocb/s_ocb
|
||||
src/encauth/ocb3/ocb3_add_aad.o src/encauth/ocb3/ocb3_decrypt.o src/encauth/ocb3/ocb3_decrypt_last.o \
|
||||
src/encauth/ocb3/ocb3_decrypt_verify_memory.o src/encauth/ocb3/ocb3_done.o \
|
||||
src/encauth/ocb3/ocb3_encrypt.o src/encauth/ocb3/ocb3_encrypt_authenticate_memory.o \
|
||||
src/encauth/ocb3/ocb3_encrypt_last.o src/encauth/ocb3/ocb3_init.o \
|
||||
src/encauth/ocb3/ocb3_int_aad_add_block.o src/encauth/ocb3/ocb3_int_calc_offset_zero.o \
|
||||
src/encauth/ocb3/ocb3_int_ntz.o src/encauth/ocb3/ocb3_int_xor_blocks.o src/encauth/ocb3/ocb3_test.o \
|
||||
src/hashes/blake2b.o src/hashes/blake2s.o src/hashes/chc/chc.o src/hashes/helper/hash_file.o \
|
||||
src/encauth/ocb3/ocb3_encrypt_last.o src/encauth/ocb3/ocb3_init.o src/encauth/ocb3/ocb3_int_ntz.o \
|
||||
src/encauth/ocb3/ocb3_int_xor_blocks.o src/encauth/ocb3/ocb3_test.o src/hashes/blake2b.o \
|
||||
src/hashes/blake2s.o src/hashes/chc/chc.o src/hashes/helper/hash_file.o \
|
||||
src/hashes/helper/hash_filehandle.o src/hashes/helper/hash_memory.o \
|
||||
src/hashes/helper/hash_memory_multi.o src/hashes/md2.o src/hashes/md4.o src/hashes/md5.o \
|
||||
src/hashes/rmd128.o src/hashes/rmd160.o src/hashes/rmd256.o src/hashes/rmd320.o src/hashes/sha1.o \
|
||||
|
1038
notes/ocb3_tv.txt
1038
notes/ocb3_tv.txt
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
@ -29,10 +55,8 @@ int ocb3_add_aad(ocb3_state *ocb, const unsigned char *aad, unsigned long aadlen
|
||||
unsigned long datalen, l;
|
||||
|
||||
LTC_ARGCHK(ocb != NULL);
|
||||
if (aad == NULL) LTC_ARGCHK(aadlen == 0);
|
||||
if (aadlen == 0) LTC_ARGCHK(aad == NULL);
|
||||
|
||||
if (aad == NULL || aadlen == 0) return CRYPT_OK;
|
||||
if (aadlen == 0) return CRYPT_OK;
|
||||
LTC_ARGCHK(aad != NULL);
|
||||
|
||||
if (ocb->adata_buffer_bytes > 0) {
|
||||
l = ocb->block_len - ocb->adata_buffer_bytes;
|
||||
@ -41,7 +65,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 +86,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; x<full_blocks; x++) {
|
||||
if ((err = ocb3_int_aad_add_block(ocb, data+x*ocb->block_len)) != CRYPT_OK) {
|
||||
if ((err = _ocb3_int_aad_add_block(ocb, data+x*ocb->block_len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
@ -30,8 +30,12 @@ int ocb3_decrypt(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen,
|
||||
unsigned char *pt_b, *ct_b;
|
||||
|
||||
LTC_ARGCHK(ocb != NULL);
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
if (ct == NULL) LTC_ARGCHK(ctlen == 0);
|
||||
if (ctlen != 0) {
|
||||
LTC_ARGCHK(ct != NULL);
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
}
|
||||
|
||||
if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
@ -30,7 +30,12 @@ int ocb3_decrypt_last(ocb3_state *ocb, const unsigned char *ct, unsigned long ct
|
||||
int err, x, full_blocks, full_blocks_len, last_block_len;
|
||||
|
||||
LTC_ARGCHK(ocb != NULL);
|
||||
if (ct == NULL) LTC_ARGCHK(ctlen == 0);
|
||||
if (ctlen != 0) {
|
||||
LTC_ARGCHK(ct != NULL);
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
}
|
||||
|
||||
if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
@ -46,16 +46,14 @@ 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;
|
||||
|
||||
/* limit taglen */
|
||||
taglen = MIN(taglen, MAXBLOCKSIZE);
|
||||
|
||||
/* allocate memory */
|
||||
buf = XMALLOC(taglen);
|
||||
ocb = XMALLOC(sizeof(ocb3_state));
|
||||
@ -69,7 +67,7 @@ int ocb3_decrypt_verify_memory(int cipher,
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
if ((err = ocb3_init(ocb, cipher, key, keylen, nonce, noncelen)) != CRYPT_OK) {
|
||||
if ((err = ocb3_init(ocb, cipher, key, keylen, nonce, noncelen, taglen)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
|
@ -30,8 +30,12 @@ int ocb3_encrypt(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen,
|
||||
unsigned char *pt_b, *ct_b;
|
||||
|
||||
LTC_ARGCHK(ocb != NULL);
|
||||
if (pt == NULL) LTC_ARGCHK(ptlen == 0);
|
||||
if (ptlen != 0) {
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
LTC_ARGCHK(ct != NULL);
|
||||
}
|
||||
|
||||
if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
@ -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 */
|
||||
@ -55,7 +50,7 @@ int ocb3_encrypt_authenticate_memory(int cipher,
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
if ((err = ocb3_init(ocb, cipher, key, keylen, nonce, noncelen)) != CRYPT_OK) {
|
||||
if ((err = ocb3_init(ocb, cipher, key, keylen, nonce, noncelen, *taglen)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,12 @@ int ocb3_encrypt_last(ocb3_state *ocb, const unsigned char *pt, unsigned long pt
|
||||
int err, x, full_blocks, full_blocks_len, last_block_len;
|
||||
|
||||
LTC_ARGCHK(ocb != NULL);
|
||||
if (pt == NULL) LTC_ARGCHK(ptlen == 0);
|
||||
if (ptlen != 0) {
|
||||
LTC_ARGCHK(pt != NULL);
|
||||
LTC_ARGCHK(ct != NULL);
|
||||
}
|
||||
|
||||
if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
@ -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];
|
||||
@ -41,7 +92,8 @@ static const struct {
|
||||
*/
|
||||
int ocb3_init(ocb3_state *ocb, int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *nonce, unsigned long noncelen)
|
||||
const unsigned char *nonce, unsigned long noncelen,
|
||||
unsigned long taglen)
|
||||
{
|
||||
int poly, x, y, m, err;
|
||||
unsigned char *previous, *current;
|
||||
@ -56,6 +108,17 @@ int ocb3_init(ocb3_state *ocb, int cipher,
|
||||
}
|
||||
ocb->cipher = cipher;
|
||||
|
||||
/* Valid Nonce?
|
||||
* As of RFC7253: "string of no more than 120 bits" */
|
||||
if (noncelen > (120/8)) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* Make sure taglen isn't too long */
|
||||
if (taglen > (unsigned long)cipher_descriptor[cipher].block_length) {
|
||||
taglen = cipher_descriptor[cipher].block_length;
|
||||
}
|
||||
|
||||
/* determine which polys to use */
|
||||
ocb->block_len = cipher_descriptor[cipher].block_length;
|
||||
x = (int)(sizeof(polys)/sizeof(polys[0]));
|
||||
@ -108,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);
|
||||
_ocb3_int_calc_offset_zero(ocb, nonce, noncelen, taglen);
|
||||
|
||||
/* initialize checksum to all zeros */
|
||||
zeromem(ocb->checksum, ocb->block_len);
|
||||
|
@ -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$ */
|
@ -1,72 +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)
|
||||
{
|
||||
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;
|
||||
|
||||
/* 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$ */
|
@ -27,7 +27,7 @@ int ocb3_test(void)
|
||||
/* test vectors from: http://tools.ietf.org/html/draft-krovetz-ocb-03 */
|
||||
unsigned char key[16] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F };
|
||||
unsigned char nonce[12] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B };
|
||||
static const struct {
|
||||
const struct {
|
||||
int ptlen;
|
||||
int aadlen;
|
||||
unsigned char pt[64], aad[64], ct[64], tag[16];
|
||||
@ -163,6 +163,44 @@ int ocb3_test(void)
|
||||
},
|
||||
|
||||
};
|
||||
/* As of RFC 7253 - 'Appendix A. Sample Results'
|
||||
* The next tuple shows a result with a tag length of 96 bits and a
|
||||
different key.
|
||||
|
||||
K: 0F0E0D0C0B0A09080706050403020100
|
||||
|
||||
N: BBAA9988776655443322110D
|
||||
A: 000102030405060708090A0B0C0D0E0F1011121314151617
|
||||
18191A1B1C1D1E1F2021222324252627
|
||||
P: 000102030405060708090A0B0C0D0E0F1011121314151617
|
||||
18191A1B1C1D1E1F2021222324252627
|
||||
C: 1792A4E31E0755FB03E31B22116E6C2DDF9EFD6E33D536F1
|
||||
A0124B0A55BAE884ED93481529C76B6AD0C515F4D1CDD4FD
|
||||
AC4F02AA
|
||||
|
||||
The C has been split up in C and T (tag)
|
||||
*/
|
||||
const unsigned char K[] = { 0x0F,0x0E,0x0D,0x0C,0x0B,0x0A,0x09,0x08,
|
||||
0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00 };
|
||||
const unsigned char N[] = { 0xBB,0xAA,0x99,0x88,0x77,0x66,0x55,0x44,
|
||||
0x33,0x22,0x11,0x0D };
|
||||
const unsigned char A[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
|
||||
0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
|
||||
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
|
||||
0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
|
||||
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 };
|
||||
const unsigned char P[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
|
||||
0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
|
||||
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
|
||||
0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
|
||||
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 };
|
||||
const unsigned char C[] = { 0x17,0x92,0xA4,0xE3,0x1E,0x07,0x55,0xFB,
|
||||
0x03,0xE3,0x1B,0x22,0x11,0x6E,0x6C,0x2D,
|
||||
0xDF,0x9E,0xFD,0x6E,0x33,0xD5,0x36,0xF1,
|
||||
0xA0,0x12,0x4B,0x0A,0x55,0xBA,0xE8,0x84,
|
||||
0xED,0x93,0x48,0x15,0x29,0xC7,0x6B,0x6A };
|
||||
const unsigned char T[] = { 0xD0,0xC5,0x15,0xF4,0xD1,0xCD,0xD4,0xFD,
|
||||
0xAC,0x4F,0x02,0xAA };
|
||||
|
||||
int err, x, idx, res;
|
||||
unsigned long len;
|
||||
@ -181,8 +219,8 @@ int ocb3_test(void)
|
||||
key, sizeof(key),
|
||||
nonce, sizeof(nonce),
|
||||
tests[x].aadlen != 0 ? tests[x].aad : NULL, tests[x].aadlen,
|
||||
tests[x].pt, tests[x].ptlen,
|
||||
outct, outtag, &len)) != CRYPT_OK) {
|
||||
tests[x].ptlen != 0 ? tests[x].pt : NULL, tests[x].ptlen,
|
||||
tests[x].ptlen != 0 ? outct : NULL, outtag, &len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -195,8 +233,8 @@ int ocb3_test(void)
|
||||
key, sizeof(key),
|
||||
nonce, sizeof(nonce),
|
||||
tests[x].aadlen != 0 ? tests[x].aad : NULL, tests[x].aadlen,
|
||||
outct, tests[x].ptlen,
|
||||
outct, tests[x].tag, len, &res)) != CRYPT_OK) {
|
||||
tests[x].ptlen != 0 ? outct : NULL, tests[x].ptlen,
|
||||
tests[x].ptlen != 0 ? outct : NULL, tests[x].tag, len, &res)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if ((res != 1) || compare_testvector(outct, tests[x].ptlen, tests[x].pt, tests[x].ptlen, "OCB3", x)) {
|
||||
@ -206,6 +244,36 @@ int ocb3_test(void)
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
}
|
||||
x = 99;
|
||||
len = 12;
|
||||
if ((err = ocb3_encrypt_authenticate_memory(idx,
|
||||
K, sizeof(K),
|
||||
N, sizeof(N),
|
||||
A, sizeof(A),
|
||||
P, sizeof(P),
|
||||
outct, outtag, &len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (compare_testvector(outtag, len, T, sizeof(T), "OCB3 Tag", x) ||
|
||||
compare_testvector(outct, sizeof(P), C, sizeof(C), "OCB3 CT", x)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
if ((err = ocb3_decrypt_verify_memory(idx,
|
||||
K, sizeof(K),
|
||||
N, sizeof(N),
|
||||
A, sizeof(A),
|
||||
C, sizeof(C),
|
||||
outct, T, sizeof(T), &res)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if ((res != 1) || compare_testvector(outct, sizeof(C), P, sizeof(P), "OCB3", x)) {
|
||||
#ifdef LTC_TEST_DBG
|
||||
printf("\n\nOCB3: Failure-decrypt - res = %d\n", res);
|
||||
#endif
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
#endif /* LTC_TEST */
|
||||
}
|
||||
|
@ -271,7 +271,8 @@ typedef struct {
|
||||
|
||||
int ocb3_init(ocb3_state *ocb, int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *nonce, unsigned long noncelen);
|
||||
const unsigned char *nonce, unsigned long noncelen,
|
||||
unsigned long taglen);
|
||||
|
||||
int ocb3_encrypt(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct);
|
||||
int ocb3_decrypt(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt);
|
||||
@ -301,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);
|
||||
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 */
|
||||
|
Loading…
Reference in New Issue
Block a user