From 08e4c90cc26cc7420bd723fbfaf38e6497b2b7d1 Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 16 Feb 2016 22:36:22 -0500 Subject: [PATCH] added single-block multiple encryption --- libretroshare/src/gxs/gxssecurity.cc | 145 +++++++++++++++++++++++++++ libretroshare/src/gxs/gxssecurity.h | 41 ++++---- 2 files changed, 166 insertions(+), 20 deletions(-) diff --git a/libretroshare/src/gxs/gxssecurity.cc b/libretroshare/src/gxs/gxssecurity.cc index 1a0c7d33e..7261068e4 100644 --- a/libretroshare/src/gxs/gxssecurity.cc +++ b/libretroshare/src/gxs/gxssecurity.cc @@ -34,6 +34,8 @@ * #define GXS_SECURITY_DEBUG 1 ***/ +static const uint32_t HEADER_MULTI_ENCRYPTION_FORMAT_v001 = 0xFACE; + static RsGxsId getRsaKeyFingerprint(RSA *pubkey) { int lenn = BN_num_bytes(pubkey -> n); @@ -631,6 +633,149 @@ bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, u return true; } +bool GxsSecurity::encrypt(uint8_t *& out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, const std::vector& keys) +{ +#ifdef DISTRIB_DEBUG + std::cerr << "GxsSecurity::encrypt() " << std::endl; +#endif + // Encrypts (in,inlen) into (out,outlen) using the given RSA public key. + // The format of the encrypted data is: + // + // [--- ID ---|--- number of encrypted keys---| n * (--- Encrypted session key length ---|--- Encrypted session keys ---) |--- IV ---|---- Encrypted data ---] + // 2 bytes 2 byte = n 1 byte = X X bytes EVP_MAX_IV_LENGTH Rest of packet + // + + out = NULL ; + + try + { + std::vector public_keys(keys.size(),NULL); + + for(uint32_t i=0;i ek(keys.size(),NULL) ; + std::vector eklen(keys.size(),0) ; + + for(uint32_t i=0;i> 8) & 0xff ; + + // number of keys + + out[out_offset++] = keys.size() & 0xff ; + out[out_offset++] = (keys.size() >> 8) & 0xff ; + + // encrypted keys, each preceeded with its length + + for(uint32_t i=0;i 0xff) + { + std::cerr << "(EE) eklen[i]=" << eklen[i] << " in " << __PRETTY_FUNCTION__ << " for key id " << keys[i].keyId << ". This is unexpected. Cannot encrypt." << std::endl; + throw std::runtime_error("Encryption error") ; + } + out[out_offset++] = (unsigned char)eklen[i] ; + + memcpy((unsigned char*)out + out_offset, ek[i],eklen[i]) ; + out_offset += eklen[i] ; + } + + memcpy((unsigned char*)out + out_offset, iv, EVP_MAX_IV_LENGTH); + out_offset += EVP_MAX_IV_LENGTH; + + int out_currOffset = 0; + + // now encrypt actual data + if(!EVP_SealUpdate(&ctx, (unsigned char*) out + out_offset, &out_currOffset, (unsigned char*) in, inlen)) + throw std::runtime_error("Encryption error in SealUpdate()") ; + + // move along to partial block space + out_offset += out_currOffset; + + // add padding + if(!EVP_SealFinal(&ctx, (unsigned char*) out + out_offset, &out_currOffset)) + throw std::runtime_error("Encryption error in SealFinal()") ; + + // move to end + out_offset += out_currOffset; + + // make sure offset has not gone passed valid memory bounds + + if(out_offset > max_outlen) + throw std::runtime_error("Memory used by encryption exceeds allocated memory block") ; + + // free encrypted key data + + for(uint32_t i=0;i& keys) ; /*! * Encrypts/decrypt data using envelope encryption using the key pre-computed in the encryption context passed as * parameter. */ - static bool initEncryption(MultiEncryptionContext& encryption_context, const std::vector &keys) ; - static bool initDecryption(MultiEncryptionContext& encryption_context, const RsTlvSecurityKey& key, unsigned char *IV, uint32_t IV_size, unsigned char *encrypted_session_key, uint32_t encrypted_session_key_size) ; + static bool initEncryption(MultiEncryptionContext& encryption_context, const std::vector &keys) ; + static bool initDecryption(MultiEncryptionContext& encryption_context, const RsTlvSecurityKey& key, unsigned char *IV, uint32_t IV_size, unsigned char *encrypted_session_key, uint32_t encrypted_session_key_size) ; /*! * Encrypts/decrypt data using envelope encryption using the key pre-computed in the encryption context passed as * parameter. */ - static bool encrypt(uint8_t *&out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, MultiEncryptionContext& encryption_context) ; - static bool decrypt(uint8_t *&out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, MultiEncryptionContext& encryption_context) ; + static bool encrypt(uint8_t *&out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, MultiEncryptionContext& encryption_context) ; + static bool decrypt(uint8_t *&out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, MultiEncryptionContext& encryption_context) ; /** * Decrypts data using evelope decryption (taken from open ssl's evp_sealinit ) @@ -135,7 +136,7 @@ class GxsSecurity * @param inlen * @return false if encryption failed */ - static bool decrypt(uint8_t *&out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, const RsTlvSecurityKey& key) ; + static bool decrypt(uint8_t *&out, uint32_t &outlen, const uint8_t *in, uint32_t inlen, const RsTlvSecurityKey& key) ; /*! * uses grp signature to check if group has been