Updated changelog
This commit is contained in:
		
							parent
							
								
									953cdabb1e
								
							
						
					
					
						commit
						fcffb56425
					
				@ -5,11 +5,9 @@
 | 
			
		||||
#include <ed25519/ed25519.h>
 | 
			
		||||
#include <ed25519/ge.h>
 | 
			
		||||
#include <log/LogUtils.h>
 | 
			
		||||
#include "../misc/base64.h"
 | 
			
		||||
#include "misc/memtracker.h"
 | 
			
		||||
#include "misc/digest.h"
 | 
			
		||||
#include "CryptionHandler.h"
 | 
			
		||||
#include "../misc/sassert.h"
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
using namespace ts;
 | 
			
		||||
@ -29,7 +27,7 @@ void CryptionHandler::reset() {
 | 
			
		||||
	this->useDefaultChipherKeyNonce = true;
 | 
			
		||||
	this->iv_struct_length = 0;
 | 
			
		||||
	memset(this->iv_struct, 0, sizeof(this->iv_struct));
 | 
			
		||||
	memcpy(this->current_mac, CryptionHandler::default_mac, sizeof(CryptionHandler::default_mac));
 | 
			
		||||
	memcpy(this->current_mac, this->default_mac, sizeof(this->default_mac));
 | 
			
		||||
 | 
			
		||||
	for(auto& cache : this->cache_key_client)
 | 
			
		||||
		cache.generation = 0xFFEF;
 | 
			
		||||
@ -37,40 +35,38 @@ void CryptionHandler::reset() {
 | 
			
		||||
		cache.generation = 0xFFEF;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define SHARED_KEY_BUFFER_LENGTH (256)
 | 
			
		||||
bool CryptionHandler::setupSharedSecret(const std::string& alpha, const std::string& beta, ecc_key *publicKey, ecc_key *ownKey, std::string &error) {
 | 
			
		||||
	size_t buffer_length = SHARED_KEY_BUFFER_LENGTH;
 | 
			
		||||
	uint8_t buffer[SHARED_KEY_BUFFER_LENGTH];
 | 
			
		||||
	size_t bufferLength = 128;
 | 
			
		||||
	uint8_t* buffer = new uint8_t[bufferLength];
 | 
			
		||||
	int err;
 | 
			
		||||
	if((err = ecc_shared_secret(ownKey, publicKey, buffer, (unsigned long*) &buffer_length)) != CRYPT_OK){
 | 
			
		||||
	if((err = ecc_shared_secret(ownKey, publicKey, buffer, (unsigned long*) &bufferLength)) != CRYPT_OK){
 | 
			
		||||
		delete[] buffer;
 | 
			
		||||
		error = "Could not calculate shared secret. Message: " + string(error_to_string(err));
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	auto result = this->setupSharedSecret(alpha, beta, string((const char*) buffer, buffer_length), error);
 | 
			
		||||
	auto result = this->setupSharedSecret(alpha, beta, string((const char*) buffer, bufferLength), error);
 | 
			
		||||
	delete[] buffer;
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool CryptionHandler::setupSharedSecret(const std::string& alpha, const std::string& beta, const std::string& sharedKey, std::string &error) {
 | 
			
		||||
bool CryptionHandler::setupSharedSecret(const std::string& alpha, const std::string& beta, const std::string &sharedKey, std::string &error) {
 | 
			
		||||
	auto secret_hash = digest::sha1(sharedKey);
 | 
			
		||||
	assert(secret_hash.length() == SHA_DIGEST_LENGTH);
 | 
			
		||||
 | 
			
		||||
	uint8_t iv_buffer[SHA_DIGEST_LENGTH];
 | 
			
		||||
	memcpy(iv_buffer, alpha.data(), 10);
 | 
			
		||||
	memcpy(&iv_buffer[10], beta.data(), 10);
 | 
			
		||||
	char ivStruct[SHA_DIGEST_LENGTH];
 | 
			
		||||
	memcpy(ivStruct, alpha.data(), 10);
 | 
			
		||||
	memcpy(&ivStruct[10], beta.data(), 10);
 | 
			
		||||
 | 
			
		||||
	for (int index = 0; index < SHA_DIGEST_LENGTH; index++) {
 | 
			
		||||
		iv_buffer[index] ^= (uint8_t) secret_hash[index];
 | 
			
		||||
		ivStruct[index] ^= (uint8_t) secret_hash[index];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	{
 | 
			
		||||
		lock_guard lock(this->cache_key_lock);
 | 
			
		||||
		memcpy(this->iv_struct, iv_buffer, SHA_DIGEST_LENGTH);
 | 
			
		||||
		memcpy(this->iv_struct, ivStruct, SHA_DIGEST_LENGTH);
 | 
			
		||||
		this->iv_struct_length = SHA_DIGEST_LENGTH;
 | 
			
		||||
 | 
			
		||||
		uint8_t mac_buffer[SHA_DIGEST_LENGTH];
 | 
			
		||||
		digest::sha1((const char*) iv_buffer, SHA_DIGEST_LENGTH, mac_buffer);
 | 
			
		||||
		memcpy(this->current_mac, mac_buffer, 8);
 | 
			
		||||
		auto iv_hash = digest::sha1(ivStruct, SHA_DIGEST_LENGTH);
 | 
			
		||||
		memcpy(this->current_mac, iv_hash.data(), 8);
 | 
			
		||||
 | 
			
		||||
		this->useDefaultChipherKeyNonce = false;
 | 
			
		||||
	}
 | 
			
		||||
@ -111,21 +107,6 @@ void _fe_neg(fe h, const fe f) {
 | 
			
		||||
	h[8] = h8;
 | 
			
		||||
	h[9] = h9;
 | 
			
		||||
}
 | 
			
		||||
/*
 | 
			
		||||
inline void keyMul(uint8_t(& target_buffer)[32], const uint8_t* publicKey /* compressed, const uint8_t* privateKey /* uncompressed, bool negate){
 | 
			
		||||
	ge_p3 keyA{};
 | 
			
		||||
	ge_p2 result{};
 | 
			
		||||
 | 
			
		||||
	ge_frombytes_negate_vartime(&keyA, publicKey);
 | 
			
		||||
	if(negate) {
 | 
			
		||||
		_fe_neg(*(fe*) &keyA.X, *(const fe*) &keyA.X); /* undo negate /
 | 
			
		||||
		_fe_neg(*(fe*) &keyA.T, *(const fe*) &keyA.T); /* undo negate /
 | 
			
		||||
	}
 | 
			
		||||
	ge_scalarmult_vartime(&result, privateKey, &keyA);
 | 
			
		||||
 | 
			
		||||
	ge_tobytes(target_buffer, &result);
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
inline std::string keyMul(const uint8_t* publicKey /* compressed */, const uint8_t* privateKey /* uncompressed */, bool negate){
 | 
			
		||||
	ge_p3 keyA{};
 | 
			
		||||
@ -143,19 +124,10 @@ inline std::string keyMul(const uint8_t* publicKey /* compressed */, const uint8
 | 
			
		||||
	return string(buffer, 32);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool CryptionHandler::setupSharedSecretNew(const std::string &alpha, const std::string &beta, const char* privateKey /* uncompressed */, const char* publicKey /* compressed */) {
 | 
			
		||||
	if(alpha.length() != 10 || beta.length() != 54)
 | 
			
		||||
		return false;
 | 
			
		||||
	assert(alpha.length() == 10);
 | 
			
		||||
	assert(beta.length() == 54);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	uint8_t shared[32];
 | 
			
		||||
	uint8_t shared_iv[64];
 | 
			
		||||
 | 
			
		||||
	ed25519_key_exchange(shared, (uint8_t*) publicKey, (uint8_t*) privateKey);
 | 
			
		||||
	keyMul(shared, reinterpret_cast<const uint8_t *>(publicKey), reinterpret_cast<const uint8_t *>(privateKey), true); //Remote key get negated
 | 
			
		||||
	digest::sha512((char*) shared, 32, shared_iv);
 | 
			
		||||
	*/
 | 
			
		||||
	string shared;
 | 
			
		||||
	string sharedIv;
 | 
			
		||||
	shared.resize(32, '\0');
 | 
			
		||||
@ -164,23 +136,17 @@ bool CryptionHandler::setupSharedSecretNew(const std::string &alpha, const std::
 | 
			
		||||
	shared = keyMul(reinterpret_cast<const uint8_t *>(publicKey), reinterpret_cast<const uint8_t *>(privateKey), true); //Remote key get negated
 | 
			
		||||
	sharedIv = digest::sha512(shared);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	auto xor_key = alpha + beta;
 | 
			
		||||
	for(int i = 0; i < 64; i++)
 | 
			
		||||
		//shared_iv[i] ^= xor_key[i];
 | 
			
		||||
		sharedIv[i] ^= xor_key[i];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	{
 | 
			
		||||
		lock_guard lock(this->cache_key_lock);
 | 
			
		||||
		//memcpy(this->iv_struct, shared_iv, 64);
 | 
			
		||||
		memcpy(this->iv_struct, sharedIv.data(), 64);
 | 
			
		||||
		this->iv_struct_length = 64;
 | 
			
		||||
 | 
			
		||||
		uint8_t mac_buffer[SHA_DIGEST_LENGTH];
 | 
			
		||||
		digest::sha1((char*) this->iv_struct, 64, mac_buffer);
 | 
			
		||||
		memcpy(this->current_mac, mac_buffer, 8);
 | 
			
		||||
		auto digest_buffer = digest::sha1((char*) this->iv_struct, 64);
 | 
			
		||||
		memcpy(this->current_mac, digest_buffer.data(), 8);
 | 
			
		||||
		this->useDefaultChipherKeyNonce = false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -199,7 +165,6 @@ bool CryptionHandler::generate_key_nonce(protocol::BasicPacket* packet, bool use
 | 
			
		||||
	);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define GENERATE_BUFFER_LENGTH (128)
 | 
			
		||||
bool CryptionHandler::generate_key_nonce(
 | 
			
		||||
		bool to_server, /* its from the client to the server */
 | 
			
		||||
		protocol::PacketType type,
 | 
			
		||||
@ -210,8 +175,8 @@ bool CryptionHandler::generate_key_nonce(
 | 
			
		||||
		uint8_t (& nonce)[16]
 | 
			
		||||
) {
 | 
			
		||||
	if (this->useDefaultChipherKeyNonce || use_default) {
 | 
			
		||||
		memcpy(key, CryptionHandler::default_key, 16);
 | 
			
		||||
		memcpy(nonce, CryptionHandler::default_nonce, 16);
 | 
			
		||||
		memcpy(key, this->default_key, 16);
 | 
			
		||||
		memcpy(nonce, this->default_nonce, 16);
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -224,10 +189,8 @@ bool CryptionHandler::generate_key_nonce(
 | 
			
		||||
	auto& key_cache = key_cache_array[type];
 | 
			
		||||
	if(key_cache.generation != generation) {
 | 
			
		||||
		const size_t buffer_length = 6 + this->iv_struct_length;
 | 
			
		||||
		sassert(buffer_length < GENERATE_BUFFER_LENGTH);
 | 
			
		||||
 | 
			
		||||
		char buffer[GENERATE_BUFFER_LENGTH];
 | 
			
		||||
		memset(buffer, 0, buffer_length);
 | 
			
		||||
		char* buffer = new char[buffer_length];
 | 
			
		||||
		memset(buffer, 0, 6 + this->iv_struct_length);
 | 
			
		||||
 | 
			
		||||
		if (to_server) {
 | 
			
		||||
			buffer[0] = 0x31;
 | 
			
		||||
@ -238,13 +201,13 @@ bool CryptionHandler::generate_key_nonce(
 | 
			
		||||
 | 
			
		||||
		le2be32(generation, buffer, 2);
 | 
			
		||||
		memcpy(&buffer[6], this->iv_struct, this->iv_struct_length);
 | 
			
		||||
		digest::sha256(buffer, buffer_length, key_cache.key_nonce);
 | 
			
		||||
		auto key_nonce = digest::sha256(buffer, 6 + this->iv_struct_length);
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
		memcpy(key_cache.key, key_nonce.data(), 16);
 | 
			
		||||
		memcpy(key_cache.nonce, key_nonce.data() + 16, 16);
 | 
			
		||||
		*/
 | 
			
		||||
		key_cache.generation = generation;
 | 
			
		||||
 | 
			
		||||
		delete[] buffer;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	memcpy(key, key_cache.key, 16);
 | 
			
		||||
@ -271,10 +234,9 @@ bool CryptionHandler::verify_encryption(const pipes::buffer_view &packet, uint16
 | 
			
		||||
 | 
			
		||||
	auto length = data.length();
 | 
			
		||||
 | 
			
		||||
	/* static shareable void buffer */
 | 
			
		||||
	const static unsigned long void_target_length = 2048;
 | 
			
		||||
	static uint8_t void_target_buffer[2048];
 | 
			
		||||
	if(void_target_length < length)
 | 
			
		||||
	const unsigned long target_length = 2048;
 | 
			
		||||
	uint8_t target_buffer[2048];
 | 
			
		||||
	if(target_length < length)
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	err = eax_decrypt_verify_memory(find_cipher("rijndael"),
 | 
			
		||||
@ -286,7 +248,7 @@ bool CryptionHandler::verify_encryption(const pipes::buffer_view &packet, uint16
 | 
			
		||||
	                                (unsigned long) header.length(), /* header length */
 | 
			
		||||
	                                (const unsigned char *) data.data_ptr(),
 | 
			
		||||
	                                (unsigned long) data.length(),
 | 
			
		||||
	                                (unsigned char *) void_target_buffer,
 | 
			
		||||
	                                (unsigned char *) target_buffer,
 | 
			
		||||
	                                (unsigned char *) mac.data_ptr(),
 | 
			
		||||
	                                (unsigned long) mac.length(),
 | 
			
		||||
	                                &success
 | 
			
		||||
@ -308,6 +270,14 @@ bool CryptionHandler::decryptPacket(protocol::BasicPacket *packet, std::string &
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	size_t target_length = 2048;
 | 
			
		||||
	uint8_t target_buffer[2048];
 | 
			
		||||
	auto length = data.length();
 | 
			
		||||
	if(target_length < length) {
 | 
			
		||||
		error = "buffer too large";
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = eax_decrypt_verify_memory(find_cipher("rijndael"),
 | 
			
		||||
	                                (uint8_t *) key, /* the key */
 | 
			
		||||
	                                (unsigned long)    16, /* key is 16 bytes */
 | 
			
		||||
@ -317,7 +287,7 @@ bool CryptionHandler::decryptPacket(protocol::BasicPacket *packet, std::string &
 | 
			
		||||
	                                (unsigned long) header.length(), /* header length */
 | 
			
		||||
	                                (const unsigned char *) data.data_ptr(),
 | 
			
		||||
	                                (unsigned long) data.length(),
 | 
			
		||||
	                                (unsigned char *) data.data_ptr(),
 | 
			
		||||
	                                (unsigned char *) target_buffer,
 | 
			
		||||
	                                (unsigned char *) packet->mac().data_ptr(),
 | 
			
		||||
	                                (unsigned long) packet->mac().length(),
 | 
			
		||||
	                                &success
 | 
			
		||||
@ -332,6 +302,7 @@ bool CryptionHandler::decryptPacket(protocol::BasicPacket *packet, std::string &
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	packet->data(pipes::buffer_view{target_buffer, length});
 | 
			
		||||
	packet->setEncrypted(false);
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
@ -365,10 +336,9 @@ bool CryptionHandler::encryptPacket(protocol::BasicPacket *packet, std::string &
 | 
			
		||||
	                                          (unsigned long) packet->header().length(), /* header length */
 | 
			
		||||
	                                          (uint8_t *) packet->data().data_ptr(), /* The plain text */
 | 
			
		||||
	                                          (unsigned long) packet->data().length(), /* Plain text length */
 | 
			
		||||
			// (uint8_t *) packet->data().data_ptr(), /* The result buffer */
 | 
			
		||||
			                                  (uint8_t *) target_buffer, /* The result buffer */
 | 
			
		||||
			                                  (uint8_t *) tag_buffer,
 | 
			
		||||
			                                  (unsigned long *)  &tag_length
 | 
			
		||||
	                                          (uint8_t *) target_buffer, /* The result buffer */
 | 
			
		||||
	                                          (uint8_t *) tag_buffer,
 | 
			
		||||
	                                          (unsigned long *)  &tag_length
 | 
			
		||||
	)) != CRYPT_OK){
 | 
			
		||||
		error = "eax_encrypt_authenticate_memory(...) returned " + to_string(err) + "/" + error_to_string(err);
 | 
			
		||||
		return false;
 | 
			
		||||
@ -383,7 +353,7 @@ bool CryptionHandler::encryptPacket(protocol::BasicPacket *packet, std::string &
 | 
			
		||||
 | 
			
		||||
bool CryptionHandler::progressPacketIn(protocol::BasicPacket* packet, std::string& error, bool use_default) {
 | 
			
		||||
	while(blocked)
 | 
			
		||||
		this_thread::yield();
 | 
			
		||||
		this_thread::sleep_for(chrono::microseconds(100));
 | 
			
		||||
 | 
			
		||||
	if(packet->isEncrypted()){
 | 
			
		||||
		bool success = decryptPacket(packet, error, use_default);
 | 
			
		||||
@ -395,7 +365,7 @@ bool CryptionHandler::progressPacketIn(protocol::BasicPacket* packet, std::strin
 | 
			
		||||
 | 
			
		||||
bool CryptionHandler::progressPacketOut(protocol::BasicPacket* packet, std::string& error, bool use_default) {
 | 
			
		||||
	while(blocked)
 | 
			
		||||
		this_thread::yield();
 | 
			
		||||
		this_thread::sleep_for(chrono::microseconds(100));
 | 
			
		||||
 | 
			
		||||
	if(packet->has_flag(PacketFlag::Unencrypted)) {
 | 
			
		||||
		packet->mac().write(this->current_mac, 8);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user