Write to a dummy blocks instead of out of bounds pointer for AES

This commit is contained in:
Benau 2018-09-15 16:09:49 +08:00
parent 4cf9542be1
commit bbb618fe6b

View File

@ -26,6 +26,12 @@
#include <openssl/buffer.h> #include <openssl/buffer.h>
#include <openssl/hmac.h> #include <openssl/hmac.h>
// ============================================================================
// AES GCM modes never writes anything when finalize, it only handles the tag
// authentication, so we write to this dummy block instead of out of bounds
// pointer, and AES GCM mode has the same ciphertext and plaintext size due to
// block cipher in stream cipher mode.
std::array<uint8_t, 16> unused_16_blocks;
// ============================================================================ // ============================================================================
std::string Crypto::base64(const std::vector<uint8_t>& input) std::string Crypto::base64(const std::vector<uint8_t>& input)
{ {
@ -85,7 +91,7 @@ bool Crypto::encryptConnectionRequest(BareNetworkString& ns)
if (EVP_EncryptUpdate(m_encrypt, cipher.data() + 4, &elen, if (EVP_EncryptUpdate(m_encrypt, cipher.data() + 4, &elen,
ns.m_buffer.data(), (int)ns.m_buffer.size()) != 1) ns.m_buffer.data(), (int)ns.m_buffer.size()) != 1)
return false; return false;
if (EVP_EncryptFinal_ex(m_encrypt, cipher.data() + 4 + elen, &elen) != 1) if (EVP_EncryptFinal_ex(m_encrypt, unused_16_blocks.data(), &elen) != 1)
return false; return false;
if (EVP_CIPHER_CTX_ctrl(m_encrypt, EVP_CTRL_GCM_GET_TAG, 4, cipher.data()) if (EVP_CIPHER_CTX_ctrl(m_encrypt, EVP_CTRL_GCM_GET_TAG, 4, cipher.data())
!= 1) != 1)
@ -112,7 +118,7 @@ bool Crypto::decryptConnectionRequest(BareNetworkString& ns)
(int)(ns.m_buffer.size() - 4)) != 1) (int)(ns.m_buffer.size() - 4)) != 1)
return false; return false;
if (EVP_DecryptFinal_ex(m_decrypt, pt.data() + dlen, &dlen) > 0) if (EVP_DecryptFinal_ex(m_decrypt, unused_16_blocks.data(), &dlen) > 0)
{ {
assert(dlen == 0); assert(dlen == 0);
std::swap(ns.m_buffer, pt); std::swap(ns.m_buffer, pt);
@ -153,7 +159,7 @@ ENetPacket* Crypto::encryptSend(BareNetworkString& ns, bool reliable)
enet_packet_destroy(p); enet_packet_destroy(p);
return NULL; return NULL;
} }
if (EVP_EncryptFinal_ex(m_encrypt, packet_start, &elen) != 1) if (EVP_EncryptFinal_ex(m_encrypt, unused_16_blocks.data(), &elen) != 1)
{ {
enet_packet_destroy(p); enet_packet_destroy(p);
return NULL; return NULL;
@ -195,7 +201,7 @@ NetworkString* Crypto::decryptRecieve(ENetPacket* p)
{ {
throw std::runtime_error("Failed to decrypt."); throw std::runtime_error("Failed to decrypt.");
} }
if (EVP_DecryptFinal_ex(m_decrypt, ns->m_buffer.data() + dlen, &dlen) > 0) if (EVP_DecryptFinal_ex(m_decrypt, unused_16_blocks.data(), &dlen) > 0)
{ {
assert(dlen == 0); assert(dlen == 0);
NetworkString* result = ns.get(); NetworkString* result = ns.get();