Make sure no IV is duplicated and allow using 32bit counter completely

This commit is contained in:
Benau
2018-09-15 16:36:01 +08:00
parent bbb618fe6b
commit 211def77a6
4 changed files with 34 additions and 18 deletions

View File

@@ -108,11 +108,15 @@ ENetPacket* Crypto::encryptSend(BareNetworkString& ns, bool reliable)
if (p == NULL)
return NULL;
std::array<uint8_t, 12> iv = m_iv;
std::array<uint8_t, 12> iv = {};
std::unique_lock<std::mutex> ul(m_crypto_mutex);
uint32_t val = NetworkConfig::get()->isClient() ?
m_packet_counter++ : m_packet_counter--;
memcpy(iv.data(), &val, 4);
uint32_t val = ++m_packet_counter;
if (NetworkConfig::get()->isClient())
memcpy(iv.data(), &val, 4);
else
memcpy(iv.data() + 4, &val, 4);
uint8_t* packet_start = p->data + 8;
gcm_aes128_set_iv(&m_aes_context, 12, iv.data());
@@ -121,7 +125,7 @@ ENetPacket* Crypto::encryptSend(BareNetworkString& ns, bool reliable)
gcm_aes128_digest(&m_aes_context, 4, p->data + 4);
ul.unlock();
memcpy(p->data, iv.data(), 4);
memcpy(p->data, &val, 4);
return p;
} // encryptSend
@@ -131,8 +135,12 @@ NetworkString* Crypto::decryptRecieve(ENetPacket* p)
int clen = (int)(p->dataLength - 8);
auto ns = std::unique_ptr<NetworkString>(new NetworkString(p->data, clen));
std::array<uint8_t, 12> iv = m_iv;
memcpy(iv.data(), p->data, 4);
std::array<uint8_t, 12> iv = {};
if (NetworkConfig::get()->isClient())
memcpy(iv.data() + 4, p->data, 4);
else
memcpy(iv.data(), p->data, 4);
uint8_t* packet_start = p->data + 8;
uint8_t* tag = p->data + 4;
std::array<uint8_t, 4> tag_after = {};

View File

@@ -95,7 +95,7 @@ public:
assert(!m_client_iv.empty());
auto c = std::unique_ptr<Crypto>(new Crypto(decode64(m_client_key),
decode64(m_client_iv)));
c->m_packet_counter = 1;
c->m_packet_counter = 0;
return c;
}
// ------------------------------------------------------------------------
@@ -131,7 +131,7 @@ public:
assert(key.size() == 16);
assert(iv.size() == 12);
std::copy_n(iv.begin(), 12, m_iv.begin());
m_packet_counter = (uint32_t)-1;
m_packet_counter = 0;
gcm_aes128_set_key(&m_aes_context, key.data());
gcm_aes128_set_iv(&m_aes_context, 12, iv.data());
}

View File

@@ -139,11 +139,15 @@ ENetPacket* Crypto::encryptSend(BareNetworkString& ns, bool reliable)
if (p == NULL)
return NULL;
std::array<uint8_t, 12> iv = m_iv;
std::array<uint8_t, 12> iv = {};
std::unique_lock<std::mutex> ul(m_crypto_mutex);
uint32_t val = NetworkConfig::get()->isClient() ?
m_packet_counter++ : m_packet_counter--;
memcpy(iv.data(), &val, 4);
uint32_t val = ++m_packet_counter;
if (NetworkConfig::get()->isClient())
memcpy(iv.data(), &val, 4);
else
memcpy(iv.data() + 4, &val, 4);
uint8_t* packet_start = p->data + 8;
if (EVP_EncryptInit_ex(m_encrypt, NULL, NULL, NULL, iv.data()) != 1)
@@ -172,7 +176,7 @@ ENetPacket* Crypto::encryptSend(BareNetworkString& ns, bool reliable)
}
ul.unlock();
memcpy(p->data, iv.data(), 4);
memcpy(p->data, &val, 4);
return p;
} // encryptSend
@@ -182,8 +186,12 @@ NetworkString* Crypto::decryptRecieve(ENetPacket* p)
int clen = (int)(p->dataLength - 8);
auto ns = std::unique_ptr<NetworkString>(new NetworkString(p->data, clen));
std::array<uint8_t, 12> iv = m_iv;
memcpy(iv.data(), p->data, 4);
std::array<uint8_t, 12> iv = {};
if (NetworkConfig::get()->isClient())
memcpy(iv.data() + 4, p->data, 4);
else
memcpy(iv.data(), p->data, 4);
uint8_t* packet_start = p->data + 8;
uint8_t* tag = p->data + 4;
if (EVP_DecryptInit_ex(m_decrypt, NULL, NULL, NULL, iv.data()) != 1)

View File

@@ -87,7 +87,7 @@ public:
assert(!m_client_iv.empty());
auto c = std::unique_ptr<Crypto>(new Crypto(decode64(m_client_key),
decode64(m_client_iv)));
c->m_packet_counter = 1;
c->m_packet_counter = 0;
return c;
}
// ------------------------------------------------------------------------
@@ -128,7 +128,7 @@ public:
assert(key.size() == 16);
assert(iv.size() == 12);
std::copy_n(iv.begin(), 12, m_iv.begin());
m_packet_counter = (uint32_t)-1;
m_packet_counter = 0;
m_encrypt = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX_init(m_encrypt);
EVP_EncryptInit_ex(m_encrypt, EVP_aes_128_gcm(), NULL, key.data(),