From: Fred Morcos Date: Thu, 3 Nov 2022 08:03:52 +0000 (+0100) Subject: OpenSSL 3.0: encryptCA6 X-Git-Tag: dnsdist-1.8.0-rc1~121^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9b81c9139da71aef204104aacb94e062677bbe42;p=thirdparty%2Fpdns.git OpenSSL 3.0: encryptCA6 --- diff --git a/pdns/ipcipher.cc b/pdns/ipcipher.cc index dc9eff7647..4cd9b09602 100644 --- a/pdns/ipcipher.cc +++ b/pdns/ipcipher.cc @@ -1,5 +1,6 @@ #include "ipcipher.hh" #include "ext/ipcrypt/ipcrypt.h" +#include #include #include @@ -59,10 +60,47 @@ static ComboAddress encryptCA6(const ComboAddress& address, const std::string& k ComboAddress ret = address; +#if OPENSSL_VERSION_MAJOR >= 3 + auto ctx = std::unique_ptr(EVP_CIPHER_CTX_new(), &EVP_CIPHER_CTX_free); + if (ctx == nullptr) { + throw pdns::OpenSSL::error("encryptCA6: Could not initialize cipher context"); + } + + auto aes128cbc = std::unique_ptr(EVP_CIPHER_fetch(nullptr, "AES-128-CBC", nullptr), &EVP_CIPHER_free); + + // NOLINTNEXTLINE(*-cast): Using OpenSSL C APIs. + if (EVP_EncryptInit(ctx.get(), aes128cbc.get(), reinterpret_cast(key.c_str()), nullptr) == 0) { + throw pdns::OpenSSL::error("encryptCA6: Could not initialize encryption algorithm"); + } + + // Disable padding + const auto inSize = sizeof(address.sin6.sin6_addr.s6_addr); + static_assert(inSize == 16, "We disable padding and so we must assume a data size of 16 bytes"); + const auto blockSize = EVP_CIPHER_get_block_size(aes128cbc.get()); + assert(blockSize == 16); + EVP_CIPHER_CTX_set_padding(ctx.get(), 0); + + int updateLen = 0; + // NOLINTNEXTLINE(*-cast): Using OpenSSL C APIs. + const auto* input = reinterpret_cast(&address.sin6.sin6_addr.s6_addr); + // NOLINTNEXTLINE(*-cast): Using OpenSSL C APIs. + auto* output = reinterpret_cast(&ret.sin6.sin6_addr.s6_addr); + if (EVP_EncryptUpdate(ctx.get(), output, &updateLen, input, static_cast(inSize)) == 0) { + throw pdns::OpenSSL::error("encryptCA6: Could not encrypt address"); + } + + int finalLen = 0; + if (EVP_EncryptFinal_ex(ctx.get(), output + updateLen, &finalLen) == 0) { + throw pdns::OpenSSL::error("encryptCA6: Could not finalize address encryption"); + } + + assert(updateLen + finalLen == inSize); +#else AES_KEY wctx; AES_set_encrypt_key((const unsigned char*)key.c_str(), 128, &wctx); AES_encrypt((const unsigned char*)&address.sin6.sin6_addr.s6_addr, (unsigned char*)&ret.sin6.sin6_addr.s6_addr, &wctx); +#endif return ret; }