fixed bug in AEAD

This commit is contained in:
mr-alice 2016-10-26 14:36:35 +02:00
parent 177752e6af
commit 42f6f26820

View File

@ -33,6 +33,7 @@
#include <stdlib.h>
#include "crypto/chacha20.h"
#include "util/rsprint.h"
#define rotl(x,n) { x = (x << n) | (x >> (-n & 31)) ;}
@ -425,8 +426,12 @@ static void poly1305_init(poly1305_state& s,uint8_t key[32])
// Warning: each call will automatically *pad* the data to a multiple of 16 bytes.
//
static void poly1305_add(poly1305_state& s,uint8_t *message,uint32_t size)
static void poly1305_add(poly1305_state& s,uint8_t *message,uint32_t size,bool pad_to_16_bytes=false)
{
#ifdef DEBUG_CHACHA20
std::cerr << "Poly1305: digesting " << RsUtil::BinToHex(message,size) << std::endl;
#endif
for(uint32_t i=0;i<(size+15)/16;++i)
{
uint256_32 block ;
@ -435,7 +440,10 @@ static void poly1305_add(poly1305_state& s,uint8_t *message,uint32_t size)
for(j=0;j<16 && i*16+j < size;++j)
block.b[j/4] += ((uint64_t)message[i*16+j]) << (8*(j & 0x3)) ;
block.b[j/4] += 0x01 << (8*(j& 0x3));
if(pad_to_16_bytes)
block.b[4] += 0x01 ;
else
block.b[j/4] += 0x01 << (8*(j& 0x3));
s.a += block ;
s.a *= s.r ;
@ -461,7 +469,7 @@ void poly1305_tag(uint8_t key[32],uint8_t *message,uint32_t size,uint8_t tag[16]
poly1305_state s;
poly1305_init (s,key);
poly1305_add (s,message,size);
poly1305_add(s,message,size) ;
poly1305_finish(s,tag);
}
@ -505,9 +513,9 @@ bool AEAD_chacha20_poly1305(uint8_t key[32], uint8_t nonce[12],uint8_t *data,uin
poly1305_init(pls,session_key);
poly1305_add(pls,aad,aad_size); // add and pad the aad
poly1305_add(pls,data,data_size); // add and pad the cipher text
poly1305_add(pls,lengths_vector,16); // add the lengths
poly1305_add(pls,aad,aad_size,true); // add and pad the aad
poly1305_add(pls,data,data_size,true); // add and pad the cipher text
poly1305_add(pls,lengths_vector,16,true); // add the lengths
poly1305_finish(pls,tag);
return true ;
@ -519,9 +527,9 @@ bool AEAD_chacha20_poly1305(uint8_t key[32], uint8_t nonce[12],uint8_t *data,uin
poly1305_init(pls,session_key);
poly1305_add(pls,aad,aad_size); // add and pad the aad
poly1305_add(pls,data,data_size); // add and pad the cipher text
poly1305_add(pls,lengths_vector,16); // add the lengths
poly1305_add(pls,aad,aad_size,true); // add and pad the aad
poly1305_add(pls,data,data_size,true); // add and pad the cipher text
poly1305_add(pls,lengths_vector,16,true); // add the lengths
poly1305_finish(pls,computed_tag);
@ -982,6 +990,59 @@ bool perform_tests()
}
std::cerr << " RFC7539 - 2.6.2 OK" << std::endl;
// RFC7539 - Poly1305 key generation. Test vector #1
//
{
uint8_t key[32] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
uint8_t nonce[12] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
uint8_t session_key[32] ;
uint8_t test_session_key[32] = { 0x76,0xb8,0xe0,0xad,0xa0,0xf1,0x3d,0x90,0x40,0x5d,0x6a,0xe5,0x53,0x86,0xbd,0x28,
0xbd,0xd2,0x19,0xb8,0xa0,0x8d,0xed,0x1a,0xa8,0x36,0xef,0xcc,0x8b,0x77,0x0d,0xc7 };
poly1305_key_gen(key,nonce,session_key) ;
if(!constant_time_memory_compare(session_key,test_session_key,32)) return false ;
}
std::cerr << " RFC7539 poly1305 key gen. TVec #1 OK" << std::endl;
// RFC7539 - Poly1305 key generation. Test vector #2
//
{
uint8_t key[32] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01 };
uint8_t nonce[12] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02 };
uint8_t session_key[32] ;
uint8_t test_session_key[32] = { 0xec,0xfa,0x25,0x4f,0x84,0x5f,0x64,0x74,0x73,0xd3,0xcb,0x14,0x0d,0xa9,0xe8,0x76,
0x06,0xcb,0x33,0x06,0x6c,0x44,0x7b,0x87,0xbc,0x26,0x66,0xdd,0xe3,0xfb,0xb7,0x39 };
poly1305_key_gen(key,nonce,session_key) ;
if(!constant_time_memory_compare(session_key,test_session_key,32)) return false ;
}
std::cerr << " RFC7539 poly1305 key gen. TVec #2 OK" << std::endl;
// RFC7539 - Poly1305 key generation. Test vector #3
//
{
uint8_t key[32] = { 0x1c,0x92,0x40,0xa5,0xeb,0x55,0xd3,0x8a,0xf3,0x33,0x88,0x86,0x04,0xf6,0xb5,0xf0,
0x47,0x39,0x17,0xc1,0x40,0x2b,0x80,0x09,0x9d,0xca,0x5c,0xbc,0x20,0x70,0x75,0xc0 };
uint8_t nonce[12] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02 };
uint8_t session_key[32] ;
uint8_t test_session_key[32] = { 0x96,0x5e,0x3b,0xc6,0xf9,0xec,0x7e,0xd9,0x56,0x08,0x08,0xf4,0xd2,0x29,0xf9,0x4b,
0x13,0x7f,0xf2,0x75,0xca,0x9b,0x3f,0xcb,0xdd,0x59,0xde,0xaa,0xd2,0x33,0x10,0xae };
poly1305_key_gen(key,nonce,session_key) ;
if(!constant_time_memory_compare(session_key,test_session_key,32)) return false ;
}
std::cerr << " RFC7539 poly1305 key gen. TVec #3 OK" << std::endl;
// RFC7539 - 2.8.2
//
{
@ -1013,16 +1074,53 @@ bool perform_tests()
uint8_t tag[16] ;
uint8_t test_tag[16] = { 0x1a,0xe1,0x0b,0x59,0x4f,0x09,0xe2,0x6a,0x7e,0x90,0x2e,0xcb,0xd0,0x60,0x06,0x91 };
librs::crypto::AEAD_chacha20_poly1305(key,nonce,msg,7*16+2,aad,12,tag,true) ;
AEAD_chacha20_poly1305(key,nonce,msg,7*16+2,aad,12,tag,true) ;
if(!constant_time_memory_compare(msg,test_msg,7*16+2)) return false ;
if(!constant_time_memory_compare(tag,test_tag,16)) return false ;
bool res = librs::crypto::AEAD_chacha20_poly1305(key,nonce,msg,7*16+2,aad,12,tag,false) ;
bool res = AEAD_chacha20_poly1305(key,nonce,msg,7*16+2,aad,12,tag,false) ;
if(!res) return false ;
}
std::cerr << " RFC7539 - 2.8.2305 OK" << std::endl;
std::cerr << " RFC7539 - 2.8.2 OK" << std::endl;
// RFC7539 - AEAD checking and decryption
//
{
uint8_t key[32] = { 0x1c,0x92,0x40,0xa5,0xeb,0x55,0xd3,0x8a,0xf3,0x33,0x88,0x86,0x04,0xf6,0xb5,0xf0,
0x47,0x39,0x17,0xc1,0x40,0x2b,0x80,0x09,0x9d,0xca,0x5c,0xbc,0x20,0x70,0x75,0xc0 };
uint8_t nonce[12] = { 0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08 };
uint8_t ciphertext[16*16 + 9] = {
0x64,0xa0,0x86,0x15,0x75,0x86,0x1a,0xf4,0x60,0xf0,0x62,0xc7,0x9b,0xe6,0x43,0xbd,
0x5e,0x80,0x5c,0xfd,0x34,0x5c,0xf3,0x89,0xf1,0x08,0x67,0x0a,0xc7,0x6c,0x8c,0xb2,
0x4c,0x6c,0xfc,0x18,0x75,0x5d,0x43,0xee,0xa0,0x9e,0xe9,0x4e,0x38,0x2d,0x26,0xb0,
0xbd,0xb7,0xb7,0x3c,0x32,0x1b,0x01,0x00,0xd4,0xf0,0x3b,0x7f,0x35,0x58,0x94,0xcf,
0x33,0x2f,0x83,0x0e,0x71,0x0b,0x97,0xce,0x98,0xc8,0xa8,0x4a,0xbd,0x0b,0x94,0x81,
0x14,0xad,0x17,0x6e,0x00,0x8d,0x33,0xbd,0x60,0xf9,0x82,0xb1,0xff,0x37,0xc8,0x55,
0x97,0x97,0xa0,0x6e,0xf4,0xf0,0xef,0x61,0xc1,0x86,0x32,0x4e,0x2b,0x35,0x06,0x38,
0x36,0x06,0x90,0x7b,0x6a,0x7c,0x02,0xb0,0xf9,0xf6,0x15,0x7b,0x53,0xc8,0x67,0xe4,
0xb9,0x16,0x6c,0x76,0x7b,0x80,0x4d,0x46,0xa5,0x9b,0x52,0x16,0xcd,0xe7,0xa4,0xe9,
0x90,0x40,0xc5,0xa4,0x04,0x33,0x22,0x5e,0xe2,0x82,0xa1,0xb0,0xa0,0x6c,0x52,0x3e,
0xaf,0x45,0x34,0xd7,0xf8,0x3f,0xa1,0x15,0x5b,0x00,0x47,0x71,0x8c,0xbc,0x54,0x6a,
0x0d,0x07,0x2b,0x04,0xb3,0x56,0x4e,0xea,0x1b,0x42,0x22,0x73,0xf5,0x48,0x27,0x1a,
0x0b,0xb2,0x31,0x60,0x53,0xfa,0x76,0x99,0x19,0x55,0xeb,0xd6,0x31,0x59,0x43,0x4e,
0xce,0xbb,0x4e,0x46,0x6d,0xae,0x5a,0x10,0x73,0xa6,0x72,0x76,0x27,0x09,0x7a,0x10,
0x49,0xe6,0x17,0xd9,0x1d,0x36,0x10,0x94,0xfa,0x68,0xf0,0xff,0x77,0x98,0x71,0x30,
0x30,0x5b,0xea,0xba,0x2e,0xda,0x04,0xdf,0x99,0x7b,0x71,0x4d,0x6c,0x6f,0x2c,0x29,
0xa6,0xad,0x5c,0xb4,0x02,0x2b,0x02,0x70,0x9b };
uint8_t aad[12] = { 0xf3,0x33,0x88,0x86,0x00,0x00,0x00,0x00,0x00,0x00,0x4e,0x91 };
uint8_t received_tag[16] = { 0xee,0xad,0x9d,0x67,0x89,0x0c,0xbb,0x22,0x39,0x23,0x36,0xfe,0xa1,0x85,0x1f,0x38 };
if(!AEAD_chacha20_poly1305(key,nonce,ciphertext,16*16+9,aad,12,received_tag,false))
return false ;
}
std::cerr << " RFC7539 AEAD test vector #1 OK" << std::endl;
return true;
}