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