|
9 | 9 |
|
10 | 10 | #include <string> |
11 | 11 | #include <cassert> |
| 12 | +#include <array> |
| 13 | +#include <cstring> |
| 14 | +#include <string_view> |
12 | 15 |
|
13 | 16 | namespace DB |
14 | 17 | { |
@@ -39,11 +42,47 @@ StringRef foldEncryptionKeyInMySQLCompatitableMode(size_t cipher_key_size, Strin |
39 | 42 |
|
40 | 43 | const EVP_CIPHER * getCipherByName(StringRef cipher_name) |
41 | 44 | { |
42 | | - // NOTE: cipher obtained not via EVP_CIPHER_fetch() would cause extra work on each context reset |
43 | | - // with EVP_CIPHER_CTX_reset() or EVP_EncryptInit_ex(), but using EVP_CIPHER_fetch() |
44 | | - // causes data race, so we stick to the slower but safer alternative here. |
| 45 | + using CipherGetter = const EVP_CIPHER *(*)(); |
| 46 | + struct Entry |
| 47 | + { |
| 48 | + std::string_view name; |
| 49 | + CipherGetter getter; |
| 50 | + }; |
| 51 | + |
| 52 | + /// Fast path to avoid OBJ/namemap lookups in EVP_get_cipherbyname(). |
| 53 | + /// Statically linked OpenSSL provides direct getters for common AES modes. |
| 54 | + static constexpr std::array<Entry, 21> fast_paths{{ |
| 55 | + {"aes-128-cbc", &EVP_aes_128_cbc}, |
| 56 | + {"aes-192-cbc", &EVP_aes_192_cbc}, |
| 57 | + {"aes-256-cbc", &EVP_aes_256_cbc}, |
| 58 | + {"aes-128-ecb", &EVP_aes_128_ecb}, |
| 59 | + {"aes-192-ecb", &EVP_aes_192_ecb}, |
| 60 | + {"aes-256-ecb", &EVP_aes_256_ecb}, |
| 61 | + {"aes-128-cfb", &EVP_aes_128_cfb}, |
| 62 | + {"aes-192-cfb", &EVP_aes_192_cfb}, |
| 63 | + {"aes-256-cfb", &EVP_aes_256_cfb}, |
| 64 | + {"aes-128-cfb8", &EVP_aes_128_cfb8}, |
| 65 | + {"aes-192-cfb8", &EVP_aes_192_cfb8}, |
| 66 | + {"aes-256-cfb8", &EVP_aes_256_cfb8}, |
| 67 | + {"aes-128-cfb1", &EVP_aes_128_cfb1}, |
| 68 | + {"aes-192-cfb1", &EVP_aes_192_cfb1}, |
| 69 | + {"aes-256-cfb1", &EVP_aes_256_cfb1}, |
| 70 | + {"aes-128-ofb", &EVP_aes_128_ofb}, |
| 71 | + {"aes-192-ofb", &EVP_aes_192_ofb}, |
| 72 | + {"aes-256-ofb", &EVP_aes_256_ofb}, |
| 73 | + {"aes-128-ctr", &EVP_aes_128_ctr}, |
| 74 | + {"aes-192-ctr", &EVP_aes_192_ctr}, |
| 75 | + {"aes-256-ctr", &EVP_aes_256_ctr}, |
| 76 | + }}; |
| 77 | + |
| 78 | + for (const auto & entry : fast_paths) |
| 79 | + { |
| 80 | + if (cipher_name.size == entry.name.size() |
| 81 | + && std::memcmp(cipher_name.data, entry.name.data(), entry.name.size()) == 0) |
| 82 | + return entry.getter(); |
| 83 | + } |
45 | 84 |
|
46 | | - /// We need zero-terminated string here: |
| 85 | + /// Fallback keeps compatibility with custom providers/algorithms. |
47 | 86 | return EVP_get_cipherbyname(cipher_name.toString().c_str()); |
48 | 87 | } |
49 | 88 |
|
|
0 commit comments