19 #ifdef ENABLE_CRYPTO_OPENSSL
21 #ifndef HEADER_CRYPTO_OPENSSL_HPP
22 #define HEADER_CRYPTO_OPENSSL_HPP
23 #define CRYPTO_AES_GCM_32BIT_TAG
25 #include "utils/log.hpp"
27 #include <enet/enet.h>
29 #define OPENSSL_API_COMPAT 0x09800000L
30 #include <openssl/evp.h>
31 #include <openssl/rand.h>
49 static std::string m_client_key;
51 static std::string m_client_iv;
53 std::array<uint8_t, 12> m_iv;
55 uint32_t m_packet_counter;
57 EVP_CIPHER_CTX* m_encrypt;
59 EVP_CIPHER_CTX* m_decrypt;
61 std::mutex m_crypto_mutex;
63 const size_t m_tag_size;
66 static size_t calcDecodeLength(
const std::string& input)
70 const size_t len = input.
size();
71 if (input[len - 1] ==
'=' && input[len - 2] ==
'=')
76 else if (input[len - 1] ==
'=')
81 return (len * 3) / 4 - padding;
85 static std::string base64(
const std::vector<uint8_t>& input);
87 static std::vector<uint8_t> decode64(std::string input);
89 static std::array<uint8_t, 32>
sha256(
const std::string& input);
91 static std::unique_ptr<Crypto> getClientCrypto(
size_t tag_size = 4)
93 assert(!m_client_key.empty());
94 assert(!m_client_iv.empty());
95 assert(tag_size == 4 || tag_size == 16);
96 auto c = std::unique_ptr<Crypto>(
new Crypto(decode64(m_client_key),
97 decode64(m_client_iv), tag_size));
98 c->m_packet_counter = 0;
102 static void initClientAES()
104 std::random_device rd;
105 std::mt19937 g(rd());
108 std::vector<uint8_t> key;
109 for (
int i = 0; i < 16; i++)
110 key.push_back((uint8_t)(g() % 255));
111 std::vector<uint8_t> iv;
112 for (
int i = 0; i < 12; i++)
113 iv.push_back((uint8_t)(g() % 255));
114 if (!RAND_bytes(key.data(), 16))
117 "Failed to generate cryptographically strong key");
119 m_client_key = base64(key);
120 m_client_iv = base64(iv);
123 static void resetClientAES()
129 static const std::string& getClientKey() {
return m_client_key; }
131 static const std::string& getClientIV() {
return m_client_iv; }
133 Crypto(
const std::vector<uint8_t>& key,
134 const std::vector<uint8_t>& iv,
135 size_t tag_size = 4) : m_tag_size(tag_size)
137 assert(key.size() == 16);
138 assert(iv.size() == 12);
139 assert(m_tag_size == 4 || m_tag_size == 16);
140 std::copy_n(iv.begin(), 12, m_iv.begin());
141 m_packet_counter = 0;
142 m_encrypt = EVP_CIPHER_CTX_new();
143 EVP_CIPHER_CTX_init(m_encrypt);
144 EVP_EncryptInit_ex(m_encrypt, EVP_aes_128_gcm(), NULL, key.data(),
146 m_decrypt = EVP_CIPHER_CTX_new();
147 EVP_CIPHER_CTX_init(m_decrypt);
148 EVP_DecryptInit_ex(m_decrypt, EVP_aes_128_gcm(), NULL, key.data(),
154 EVP_CIPHER_CTX_free(m_encrypt);
155 EVP_CIPHER_CTX_free(m_decrypt);
Describes a chain of 8-bit unsigned integers.
Definition: network_string.hpp:53
unsigned int size() const
Returns the remaining length of the network string.
Definition: network_string.hpp:191
A new implementation of NetworkString, which has a fixed format: Byte 0: The type of the message,...
Definition: network_string.hpp:422
CScriptArray * sha256(std::string *input)
Return a sha256 checksum of string in an array of integers of size 32.
Definition: script_utils.cpp:163