From 42f6f26820d5e3e395910b3c179d612717d05a23 Mon Sep 17 00:00:00 2001 From: mr-alice Date: Wed, 26 Oct 2016 14:36:35 +0200 Subject: [PATCH] fixed bug in AEAD --- libretroshare/src/crypto/chacha20.cpp | 122 +++++++++++++++++++++++--- 1 file changed, 110 insertions(+), 12 deletions(-) diff --git a/libretroshare/src/crypto/chacha20.cpp b/libretroshare/src/crypto/chacha20.cpp index 6c48957c1..756bbdc32 100644 --- a/libretroshare/src/crypto/chacha20.cpp +++ b/libretroshare/src/crypto/chacha20.cpp @@ -33,6 +33,7 @@ #include #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; }