ComboAddress ret = address;
+#if OPENSSL_VERSION_MAJOR >= 3
+ auto ctx = std::unique_ptr<EVP_CIPHER_CTX, decltype(&EVP_CIPHER_CTX_free)>(EVP_CIPHER_CTX_new(), &EVP_CIPHER_CTX_free);
+ if (ctx == nullptr) {
+ throw pdns::OpenSSL::error("decryptCA6: Could not initialize cipher context");
+ }
+
+ auto aes128cbc = std::unique_ptr<EVP_CIPHER, decltype(&EVP_CIPHER_free)>(EVP_CIPHER_fetch(nullptr, "AES-128-CBC", nullptr), &EVP_CIPHER_free);
+
+ // NOLINTNEXTLINE(*-cast): Using OpenSSL C APIs.
+ if (EVP_DecryptInit(ctx.get(), aes128cbc.get(), reinterpret_cast<const unsigned char*>(key.c_str()), nullptr) == 0) {
+ throw pdns::OpenSSL::error("decryptCA6: Could not initialize decryption 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<const unsigned char*>(&address.sin6.sin6_addr.s6_addr);
+ // NOLINTNEXTLINE(*-cast): Using OpenSSL C APIs.
+ auto* output = reinterpret_cast<unsigned char*>(&ret.sin6.sin6_addr.s6_addr);
+ if (EVP_DecryptUpdate(ctx.get(), output, &updateLen, input, static_cast<int>(inSize)) == 0) {
+ throw pdns::OpenSSL::error("decryptCA6: Could not decrypt address");
+ }
+
+ int finalLen = 0;
+ if (EVP_DecryptFinal_ex(ctx.get(), output + updateLen, &finalLen) == 0) {
+ throw pdns::OpenSSL::error("decryptCA6: Could not finalize address decryption");
+ }
+
+ assert(updateLen + finalLen == inSize);
+#else
AES_KEY wctx;
AES_set_decrypt_key((const unsigned char*)key.c_str(), 128, &wctx);
AES_decrypt((const unsigned char*)&address.sin6.sin6_addr.s6_addr,
(unsigned char*)&ret.sin6.sin6_addr.s6_addr, &wctx);
+#endif
return ret;
}