added encryption routine for FT

This commit is contained in:
mr-alice 2016-10-19 21:30:37 +02:00
parent 997154f9c5
commit 3ad0a81d8f
5 changed files with 144 additions and 13 deletions

View File

@ -307,18 +307,18 @@ static void print(const chacha20_state& s)
static void add(chacha20_state& s,const chacha20_state& t) { for(uint32_t i=0;i<16;++i) s.c[i] += t.c[i] ; }
static uint8_t read16bits(char s)
{
if(s >= '0' && s <= '9')
return s - '0' ;
else if(s >= 'a' && s <= 'f')
return s - 'a' + 10 ;
else if(s >= 'A' && s <= 'F')
return s - 'A' + 10 ;
else
throw std::runtime_error("Not an hex string!") ;
}
// static uint8_t read16bits(char s)
// {
// if(s >= '0' && s <= '9')
// return s - '0' ;
// else if(s >= 'a' && s <= 'f')
// return s - 'a' + 10 ;
// else if(s >= 'A' && s <= 'F')
// return s - 'A' + 10 ;
// else
// throw std::runtime_error("Not an hex string!") ;
// }
//
// static uint256_32 create_256bit_int(const std::string& s)
// {
// uint256_32 r(0,0,0,0,0,0,0,0) ;
@ -431,6 +431,12 @@ void poly1305_tag(uint8_t key[32],uint8_t *message,uint32_t size,uint8_t tag[16]
tag[12] = (acc.b[3] >> 0) & 0xff ; tag[13] = (acc.b[3] >> 8) & 0xff ; tag[14] = (acc.b[3] >>16) & 0xff ; tag[15] = (acc.b[3] >>24) & 0xff ;
}
void AEAD_chacha20_poly1305(uint8_t key[32], uint8_t nonce[12],uint8_t *data,uint32_t data_size,uint8_t *aad,uint32_t aad_size,uint8_t tag[16])
{
#warning this part is not implemented yet.
memset(tag,0xff,16) ;
}
void perform_tests()
{
std::cerr << "Testing Chacha20" << std::endl;

View File

@ -62,7 +62,18 @@ namespace librs
* \param size size of the data
* \param tag generated poly1305 tag.
*/
static void AEAD_chacha20_poly1305(uint8_t key[32], uint8_t nonce[12],uint8_t *data,uint32_t data_size,uint8_t *aad,uint8_t *aad_size,uint8_t tag[16]) ;
static void AEAD_chacha20_poly1305(uint8_t key[32], uint8_t nonce[12],uint8_t *data,uint32_t data_size,uint8_t *aad,uint32_t aad_size,uint8_t tag[16]) ;
/*!
* \brief constant_time_memcmp
* Provides a constant time comparison of two memory chunks. The implementation comes from the FreeBSD implementation.
*
* \param m1 memory block 1
* \param m2 memory block 2
* \param size common size of m1 and m2
* \return
*/
static bool constant_time_memcmp(const uint8_t *m1,const uint8_t *m2,uint32_t size) ;
/*!
* \brief perform_tests

View File

@ -27,6 +27,8 @@
#include <time.h>
#include "util/rsdebug.h"
#include "util/rsdir.h"
#include "util/rsprint.h"
#include "crypto/chacha20.h"
#include "retroshare/rstypes.h"
#include "retroshare/rspeers.h"
const int ftserverzone = 29539;
@ -984,6 +986,113 @@ bool ftServer::sendData(const RsPeerId& peerId, const RsFileHash& hash, uint64_t
return true;
}
// Encrypts the given item using aead-chacha20-poly1305
//
// The format is the following
//
// [encryption format] [random initialization vector] [encrypted data size] [encrypted data] [authentication tag]
// 4 bytes 12 bytes 4 bytes variable 16 bytes
//
// +-------------------- authenticated data part ----------------------+
//
//
// Encryption format:
// ae ad 00 01 : encryption using AEAD, format 00, version 01
//
//
void ftServer::deriveEncryptionKey(const RsFileHash& hash, uint8_t *key)
{
// The encryption key is simply the 256 hash of the
SHA256_CTX sha_ctx ;
if(SHA256_DIGEST_LENGTH != 32)
throw std::runtime_error("Warning: can't compute Sha1Sum with sum size != 32") ;
SHA256_Init(&sha_ctx);
SHA256_Update(&sha_ctx, hash.toByteArray(), hash.SIZE_IN_BYTES);
SHA256_Final (key, &sha_ctx);
}
bool ftServer::encryptItem(RsTurtleGenericTunnelItem *clear_item,const RsFileHash& hash,RsTurtleGenericDataItem *& encrypted_item)
{
static const uint32_t ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE = 12 ;
static const uint32_t ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE = 16 ;
static const uint32_t ENCRYPTED_FT_HEADER_SIZE = 4 ;
static const uint32_t ENCRYPTED_FT_EDATA_SIZE = 4 ;
uint8_t initialization_vector[ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE] ;
RSRandom::random_bytes(initialization_vector,ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE) ;
std::cerr << "ftServer::Encrypting ft item." << std::endl;
std::cerr << " random nonce : " << RsUtil::BinToHex(initialization_vector,ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE) << std::endl;
uint32_t total_data_size = ENCRYPTED_FT_HEADER_SIZE + ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE + clear_item->serial_size() + ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE ;
std::cerr << " clear part size : " << clear_item->serial_size() << std::endl;
std::cerr << " total item size : " << total_data_size << std::endl;
encrypted_item = new RsTurtleGenericDataItem ;
encrypted_item->data_bytes = rs_malloc( total_data_size ) ;
encrypted_item->data_size = total_data_size ;
if(encrypted_item->data_bytes == NULL)
return false ;
uint8_t *edata = (uint8_t*)encrypted_item->data_bytes ;
uint32_t edata_size = clear_item->serial_size() ;
uint32_t offset = 0;
edata[0] = 0xae ;
edata[1] = 0xad ;
edata[2] = 0x00 ;
edata[3] = 0x01 ;
offset += ENCRYPTED_FT_HEADER_SIZE;
uint32_t aad_offset = offset ;
uint32_t aad_size = ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE + ENCRYPTED_FT_EDATA_SIZE ;
memcpy(&edata[offset], initialization_vector, ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE) ;
offset += ENCRYPTED_FT_INITIALIZATION_VECTOR_SIZE ;
edata[offset+0] = (edata_size >> 0) & 0xff ;
edata[offset+1] = (edata_size >> 8) & 0xff ;
edata[offset+2] = (edata_size >> 16) & 0xff ;
edata[offset+3] = (edata_size >> 24) & 0xff ;
offset += ENCRYPTED_FT_EDATA_SIZE ;
uint32_t ser_size = (uint32_t)((int)total_data_size - (int)offset);
clear_item->serialize(&edata[offset], ser_size);
std::cerr << " clear item : " << RsUtil::BinToHex(&edata[offset],std::min(50,(int)total_data_size-(int)offset)) << "(...)" << std::endl;
uint32_t clear_item_offset = offset ;
offset += edata_size ;
uint32_t authentication_tag_offset = offset ;
assert(ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE + offset == total_data_size) ;
uint8_t encryption_key[32] ;
deriveEncryptionKey(hash,encryption_key) ;
librs::crypto::AEAD_chacha20_poly1305(encryption_key,initialization_vector,&edata[clear_item_offset],edata_size, &edata[aad_offset],aad_size, &edata[authentication_tag_offset]) ;
std::cerr << " encryption key : " << RsUtil::BinToHex(encryption_key,32) << std::endl;
std::cerr << " authen. tag : " << RsUtil::BinToHex(&edata[authentication_tag_offset],ENCRYPTED_FT_AUTHENTICATION_TAG_SIZE) << std::endl;
std::cerr << " final item : " << RsUtil::BinToHex(&edata[0],std::min(50u,total_data_size)) << "(...)" << std::endl;
return true ;
}
// Decrypts the given item using aead-chacha20-poly1305
bool ftServer::decryptItem(RsTurtleGenericTunnelItem *encrypted_item,const RsFileHash& hash,RsTurtleGenericDataItem *& decrypted_item)
{
decrypted_item = NULL ;
}
// Dont delete the item. The client (p3turtle) is doing it after calling this.
//
void ftServer::receiveTurtleData(RsTurtleGenericTunnelItem *i,

View File

@ -224,6 +224,10 @@ public:
virtual bool sendSingleChunkCRCRequest(const RsPeerId& peer_id,const RsFileHash& hash,uint32_t chunk_number) ;
virtual bool sendSingleChunkCRC(const RsPeerId& peer_id,const RsFileHash& hash,uint32_t chunk_number,const Sha1CheckSum& crc) ;
static void deriveEncryptionKey(const RsFileHash& hash, uint8_t *key);
static bool encryptItem(RsTurtleGenericTunnelItem *clear_item,const RsFileHash& hash,RsTurtleGenericDataItem *& encrypted_item);
static bool decryptItem(RsTurtleGenericTunnelItem *encrypted_item,const RsFileHash& hash,RsTurtleGenericDataItem *& decrypted_item);
/*************** Internal Transfer Fns *************************/
virtual int tick();

View File

@ -35,6 +35,7 @@ class RsTurtleItem: public RsItem
public:
RsTurtleItem(uint8_t turtle_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_TURTLE,turtle_subtype) {}
#warning we need some consts here
virtual bool serialize(void *data,uint32_t& size) = 0 ; // Isn't it better that items can serialize themselves ?
virtual uint32_t serial_size() = 0 ; // deserialise is handled using a constructor