Commit 502c117e8ef for nodejs

commit 502c117e8ef08410d7ed6a4ac87d109be56b69f6
Author: Filip Skokan <panva.ip@gmail.com>
Date:   Thu Oct 29 14:21:12 2026 +0100

    src: make crypto backend checks explicit

    Reject unsupported backends at compile time so OpenSSL 1.1.1 backports
    cannot silently use a BoringSSL or provider-specific path.

    Signed-off-by: Filip Skokan <panva.ip@gmail.com>
    PR-URL: https://github.com/nodejs/node/pull/67056
    Reviewed-By: Richard Lau <richard.lau@ibm.com>
    Reviewed-By: Tim Perry <pimterry@gmail.com>

diff --git a/deps/ncrypto/ncrypto.cc b/deps/ncrypto/ncrypto.cc
index a28b9cd209e..025857fd541 100644
--- a/deps/ncrypto/ncrypto.cc
+++ b/deps/ncrypto/ncrypto.cc
@@ -62,6 +62,8 @@ const EVP_CIPHER* GetCipherCtxCipher(const EVP_CIPHER_CTX* ctx) {
   return EVP_CIPHER_CTX_get0_cipher(ctx);
 #elif NCRYPTO_USE_BORINGSSL
   return EVP_CIPHER_CTX_cipher(ctx);
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -730,6 +732,8 @@ int BignumPointer::isPrime(int nchecks,
     return -1;
   }
   return is_probably_prime;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -1174,6 +1178,8 @@ bool PrintGeneralName(const BIOPointer& out, const GENERAL_NAME* gen) {
       return BIOPointer::PrintfAll(out, "<invalid length=%d>", ip_len);
 #elif NCRYPTO_USE_BORINGSSL
       return BIOPointer::WriteAll(out, "<invalid>");
+#else
+#error "Unsupported crypto backend"
 #endif
     }
   } else if (gen->type == GEN_RID) {
@@ -1468,8 +1474,10 @@ bool IsX509TimePrintable(const ASN1_TIME* time) {
   // path as its printer so the fallback is selected before writing output.
   int64_t ignored{};
   return ASN1_TIME_to_posix(time, &ignored) == 1;
-#else
+#elif NCRYPTO_USE_OPENSSL_PROVIDER
   return ASN1_TIME_check(time) == 1;
+#else
+#error "Unsupported crypto backend"
 #endif
 }
 }  // namespace
@@ -1538,10 +1546,12 @@ std::optional<int64_t> X509View::getValidToTime() const {
   int64_t tp{};
   if (ASN1_TIME_to_posix(time, &tp) != 1) return std::nullopt;
   return tp;
-#else
+#elif NCRYPTO_USE_OPENSSL_PROVIDER
   struct tm tp {};
   if (ASN1_TIME_to_tm(time, &tp) != 1) return std::nullopt;
   return PortableTimeGM(&tp);
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -1554,10 +1564,12 @@ std::optional<int64_t> X509View::getValidFromTime() const {
   int64_t tp{};
   if (ASN1_TIME_to_posix(time, &tp) != 1) return std::nullopt;
   return tp;
-#else
+#elif NCRYPTO_USE_OPENSSL_PROVIDER
   struct tm tp {};
   if (ASN1_TIME_to_tm(time, &tp) != 1) return std::nullopt;
   return PortableTimeGM(&tp);
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -1768,6 +1780,8 @@ bool X509View::ifRsa(KeyCallback<Rsa> callback) const {
       rsa.emplace(pkey);
 #elif NCRYPTO_USE_BORINGSSL
       rsa.emplace(EVP_PKEY_get0_RSA(pkey));
+#else
+#error "Unsupported crypto backend"
 #endif
     }
     if (!*rsa) [[unlikely]]
@@ -1793,6 +1807,8 @@ bool X509View::ifEc(KeyCallback<Ec> callback) const {
       ec.emplace(pkey);
 #elif NCRYPTO_USE_BORINGSSL
       ec.emplace(EVP_PKEY_get0_EC_KEY(pkey));
+#else
+#error "Unsupported crypto backend"
 #endif
     }
     if (!*ec) [[unlikely]]
@@ -1826,6 +1842,8 @@ X509Pointer X509Pointer::PeerFrom(const SSLPointer& ssl) {
   return X509Pointer(SSL_get1_peer_certificate(ssl.get()));
 #elif NCRYPTO_USE_BORINGSSL
   return X509Pointer(SSL_get_peer_certificate(ssl.get()));
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -2137,6 +2155,8 @@ DHPointer::DHPointer(BignumPointer&& p,
     : p_(std::move(p)), g_(std::move(g)), group_name_(group_name) {}
 #elif NCRYPTO_USE_BORINGSSL
 DHPointer::DHPointer(DH* dh) : dh_(dh) {}
+#else
+#error "Unsupported crypto backend"
 #endif

 DHPointer::DHPointer(DHPointer&& other) noexcept
@@ -2152,6 +2172,8 @@ DHPointer::DHPointer(DHPointer&& other) noexcept
 #elif NCRYPTO_USE_BORINGSSL
     : dh_(other.release()) {
 }
+#else
+#error "Unsupported crypto backend"
 #endif

 DHPointer& DHPointer::operator=(DHPointer&& other) noexcept {
@@ -2169,6 +2191,8 @@ void DHPointer::reset(
     EVP_PKEY* dh
 #elif NCRYPTO_USE_BORINGSSL
     DH* dh
+#else
+#error "Unsupported crypto backend"
 #endif
 ) {
   dh_.reset(dh);
@@ -2202,6 +2226,8 @@ EVP_PKEY* DHPointer::release() {
 DH* DHPointer::release() {
   return dh_.release();
 }
+#else
+#error "Unsupported crypto backend"
 #endif

 BignumPointer DHPointer::FindGroup(const std::string_view name,
@@ -2245,6 +2271,8 @@ DHPointer DHPointer::FromGroup(const std::string_view name,
   return DHPointer(std::move(group), std::move(generator), group_name);
 #elif NCRYPTO_USE_BORINGSSL
   return New(std::move(group), std::move(generator));
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -2270,6 +2298,8 @@ DHPointer DHPointer::New(BignumPointer&& p, BignumPointer&& g) {
   g.release();

   return dh;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -2293,6 +2323,8 @@ DHPointer DHPointer::New(size_t bits, unsigned int generator) {
   }

   return dh;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -2332,6 +2364,8 @@ DHPointer::CheckResult DHPointer::check() {
   if (DH_check(dh_.get(), &codes) != 1)
     return DHPointer::CheckResult::CHECK_FAILED;
   return static_cast<CheckResult>(codes);
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -2403,6 +2437,8 @@ DHPointer::CheckPublicKeyResult DHPointer::checkPublicKey(
     return DHPointer::CheckPublicKeyResult::INVALID;
   }
   return CheckPublicKeyResult::NONE;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -2419,6 +2455,8 @@ DataPointer DHPointer::getPrime() const {
   const BIGNUM* p;
   DH_get0_pqg(dh_.get(), &p, nullptr, nullptr);
   return BignumPointer::Encode(p);
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -2435,6 +2473,8 @@ size_t DHPointer::getPrimeBits() const {
   const BIGNUM* p;
   DH_get0_pqg(dh_.get(), &p, nullptr, nullptr);
   return BignumPointer::GetBitCount(p);
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -2451,6 +2491,8 @@ DataPointer DHPointer::getGenerator() const {
   const BIGNUM* g;
   DH_get0_pqg(dh_.get(), nullptr, nullptr, &g);
   return BignumPointer::Encode(g);
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -2467,6 +2509,8 @@ DataPointer DHPointer::getPublicKey() const {
   const BIGNUM* pub_key;
   DH_get0_key(dh_.get(), &pub_key, nullptr);
   return BignumPointer::Encode(pub_key);
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -2483,6 +2527,8 @@ DataPointer DHPointer::getPrivateKey() const {
   const BIGNUM* pvt_key;
   DH_get0_key(dh_.get(), nullptr, &pvt_key);
   return BignumPointer::Encode(pvt_key);
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -2499,6 +2545,8 @@ bool DHPointer::hasPrivateKey() const {
   const BIGNUM* pvt_key = nullptr;
   DH_get0_key(dh_.get(), nullptr, &pvt_key);
   return pvt_key != nullptr;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -2568,6 +2616,8 @@ DataPointer DHPointer::generateKeys() {
   if (!DH_generate_key(dh_.get())) return {};

   return getPublicKey();
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -2583,6 +2633,8 @@ size_t DHPointer::size() const {
   // DH_size can return a -1 on error but we just want to return a 0
   // in that case so we don't wrap around when returning the size_t.
   return ret >= 0 ? static_cast<size_t>(ret) : 0;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -2653,6 +2705,8 @@ DataPointer DHPointer::computeSecret(const BignumPointer& peer) const {
   }

   return dp;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -2690,6 +2744,8 @@ bool DHPointer::setPublicKey(BignumPointer&& key) {
     return true;
   }
   return false;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -2727,6 +2783,8 @@ bool DHPointer::setPrivateKey(BignumPointer&& key) {
     return true;
   }
   return false;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -2882,6 +2940,8 @@ DataPointer hkdf(const Digest& md,
           ctx.get(), static_cast<unsigned char*>(buf.get()), &length) <= 0) {
     return {};
   }
+#else
+#error "Unsupported crypto backend"
 #endif

   return buf;
@@ -2938,6 +2998,8 @@ bool checkScryptParams(uint64_t N, uint64_t r, uint64_t p, uint64_t maxmem) {
 #elif NCRYPTO_USE_BORINGSSL
   return EVP_PBE_scrypt(nullptr, 0, nullptr, 0, N, r, p, maxmem, nullptr, 0) ==
          1;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -2967,6 +3029,8 @@ DataPointer scrypt(const Buffer<const char>& pass,
                            maxmem,
                            reinterpret_cast<unsigned char*>(dp.get()),
                            length)) {
+#else
+#error "Unsupported crypto backend"
 #endif
     return dp;
   }
@@ -3033,6 +3097,8 @@ DataPointer pbkdf2(const Digest& md,
                               reinterpret_cast<unsigned char*>(dp.get()))) {
     return dp;
   }
+#else
+#error "Unsupported crypto backend"
 #endif

   return {};
@@ -3364,6 +3430,8 @@ EVPKeyPointer EVPKeyPointer::NewRawPublic(
   const auto* alg = GetBoringSSLKeyAlgorithm(algorithm);
   if (alg == nullptr) return {};
   return EVPKeyPointer(EVP_PKEY_from_raw_public_key(alg, data.data, data.len));
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -3376,6 +3444,8 @@ EVPKeyPointer EVPKeyPointer::NewRawPrivate(
   const auto* alg = GetBoringSSLKeyAlgorithm(algorithm);
   if (alg == nullptr) return {};
   return EVPKeyPointer(EVP_PKEY_from_raw_private_key(alg, data.data, data.len));
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -3387,7 +3457,7 @@ EVPKeyPointer EVPKeyPointer::NewRawSeed(
   if (seed_alg == nullptr) return {};
   return EVPKeyPointer(
       EVP_PKEY_from_private_seed(seed_alg, data.data, data.len));
-#else
+#elif NCRYPTO_USE_OPENSSL_PROVIDER
   // ML-DSA and ML-KEM both use the provider parameter "seed".
   OSSL_PARAM params[] = {
       OSSL_PARAM_construct_octet_string(
@@ -3401,6 +3471,8 @@ EVPKeyPointer EVPKeyPointer::NewRawSeed(
     return {};
   }
   return EVPKeyPointer(pkey);
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -3415,6 +3487,8 @@ EVPKeyPointer EVPKeyPointer::NewDH(DHPointer&& dh) {
     dh.release();
   }
   return key;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -3482,6 +3556,8 @@ EVPKeyPointer EVPKeyPointer::NewRSA(RSAPointer&& rsa) {
   }
   return key;
 }
+#else
+#error "Unsupported crypto backend"
 #endif  // NCRYPTO_USE_OPENSSL_PROVIDER

 EVPKeyPointer::EVPKeyPointer(EVP_PKEY* pkey) : pkey_(pkey) {}
@@ -3516,6 +3592,8 @@ bool EVPKeyPointer::isA(const EVP_PKEY* key, const char* name) {
 #elif NCRYPTO_USE_BORINGSSL
   const int id = GetBoringSSLKeyId(name);
   return id != NID_undef && EVP_PKEY_id(key) == id;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -3576,6 +3654,8 @@ const KeyAlgorithm* EVPKeyPointer::getAlgorithm() const {
   for (const auto& algorithm : kBoringSSLKeyAlgorithms) {
     if (id == algorithm.id) return KeyAlgorithm::FromName(algorithm.name);
   }
+#else
+#error "Unsupported crypto backend"
 #endif
   return nullptr;
 }
@@ -3610,6 +3690,8 @@ bool EVPKeyPointer::supportsContextString() const {
           OSSL_PARAM_locate_const(params, kSignatureInstance) != nullptr);
 #elif NCRYPTO_USE_BORINGSSL
   return algorithm->isPqc();
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -3795,10 +3877,12 @@ DataPointer GetRawSeed(EVP_PKEY* key, size_t seed_len) {
   size_t len = data.size();
 #if NCRYPTO_USE_BORINGSSL
   if (EVP_PKEY_get_private_seed(key, buf.data, &len) != 1) return {};
-#else
+#elif NCRYPTO_USE_OPENSSL_PROVIDER
   if (EVP_PKEY_get_octet_string_param(key, "seed", buf.data, buf.len, &len) !=
       1)
     return {};
+#else
+#error "Unsupported crypto backend"
 #endif
   return data;
 }
@@ -3880,6 +3964,8 @@ bool EVPKeyPointer::assign(const ECKeyPointer& eckey) {
   return set(eckey);
 #elif NCRYPTO_USE_BORINGSSL
   return EVP_PKEY_assign_EC_KEY(pkey_.get(), eckey.get());
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -3944,6 +4030,8 @@ bool EVPKeyPointer::set(const ECKeyPointer& eckey) {
   return true;
 #elif NCRYPTO_USE_BORINGSSL
   return EVP_PKEY_set1_EC_KEY(pkey_.get(), eckey);
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -3994,6 +4082,8 @@ EVP_PKEY* DecodeRsaPublicKey(const unsigned char** data, size_t length) {
   return result == 1 ? key.release() : nullptr;
 #elif NCRYPTO_USE_BORINGSSL
   return d2i_PublicKey(NID_rsaEncryption, nullptr, data, length);
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -4334,7 +4424,7 @@ EVPKeyPointer::ParseKeyResult EVPKeyPointer::TryLoadPrivateKeyFromStore(
     const StorePrivateKeyConfig& config) {
 #if NCRYPTO_USE_BORINGSSL
   return ParseKeyResult(PKParseError::FAILED);
-#else
+#elif NCRYPTO_USE_OPENSSL_PROVIDER
   // The error queue is left populated on failure so the caller can surface a
   // `code` and an `opensslErrorStack`, matching TryParsePrivateKey(), and is
   // cleared on success because decoders leave entries behind either way.
@@ -4420,6 +4510,8 @@ EVPKeyPointer::ParseKeyResult EVPKeyPointer::TryLoadPrivateKeyFromStore(
     return failed(passphrase_data.missing_passphrase);
   }
   return ParseKeyResult(PKParseError::NOT_RECOGNIZED);
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -4484,6 +4576,8 @@ Result<BIOPointer, bool> EVPKeyPointer::writePrivateKey(
           return Result<BIOPointer, bool>(false);
         }
       }
+#else
+#error "Unsupported crypto backend"
 #endif
       break;
     }
@@ -4572,6 +4666,8 @@ Result<BIOPointer, bool> EVPKeyPointer::writePrivateKey(
           return Result<BIOPointer, bool>(false);
         }
       }
+#else
+#error "Unsupported crypto backend"
 #endif
       break;
     }
@@ -4629,6 +4725,8 @@ Result<BIOPointer, bool> EVPKeyPointer::writePublicKey(
                                       mark_pop_error_on_return.peekError());
     }
     return bio;
+#else
+#error "Unsupported crypto backend"
 #endif
   }

@@ -4663,6 +4761,8 @@ Result<BIOPointer, bool> EVPKeyPointer::writePublicKey(
       return Result<BIOPointer, bool>(false,
                                       mark_pop_error_on_return.peekError());
     }
+#else
+#error "Unsupported crypto backend"
 #endif
     return bio;
   }
@@ -4712,6 +4812,8 @@ std::optional<uint32_t> EVPKeyPointer::getBytesOfRS() const {
       }
     }
     if (!has_bits) return std::nullopt;
+#else
+#error "Unsupported crypto backend"
 #endif
   } else if (isA(KeyAlgorithm::EC)) {
 #if NCRYPTO_USE_OPENSSL_PROVIDER
@@ -4722,6 +4824,8 @@ std::optional<uint32_t> EVPKeyPointer::getBytesOfRS() const {
     const EC_GROUP* group = ECKeyPointer::GetGroup(ec_key);
     if (group == nullptr) return std::nullopt;
     bits = EC_GROUP_order_bits(group);
+#else
+#error "Unsupported crypto backend"
 #endif
   } else {
     return std::nullopt;
@@ -4741,6 +4845,8 @@ EVPKeyPointer::operator Rsa() const {
   OSSL3_CONST RSA* rsa = EVP_PKEY_get0_RSA(get());
   if (rsa == nullptr) return {};
   return Rsa(rsa);
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -4753,6 +4859,8 @@ EVPKeyPointer::operator Dsa() const {
   OSSL3_CONST DSA* dsa = EVP_PKEY_get0_DSA(get());
   if (dsa == nullptr) return {};
   return Dsa(dsa);
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -4783,6 +4891,8 @@ bool EVPKeyPointer::validateDsaParameters() const {
     if (p == nullptr || q == nullptr) return false;
     const BIGNUM* p_value = p;
     const BIGNUM* q_value = q;
+#else
+#error "Unsupported crypto backend"
 #endif
     int L = BignumPointer::GetBitCount(p_value);
     int N = BignumPointer::GetBitCount(q_value);
@@ -5158,6 +5268,8 @@ DigestCache::Result DigestCache::lookup(const char* name,
   static_cast<void>(name);
   static_cast<void>(generation);
   return {};
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -5205,6 +5317,8 @@ DigestCache::Result DigestCache::insert(const char* name,
   static_cast<void>(digest);
   static_cast<void>(generation);
   return {};
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -5224,6 +5338,8 @@ const DigestCache::AliasMap& DigestCache::aliases() const {
 #elif NCRYPTO_USE_BORINGSSL
   static const AliasMap empty;
   return empty;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -5243,6 +5359,8 @@ const EVP_CIPHER* CipherCache::lookup(const char* name, uint64_t generation) {
   static_cast<void>(name);
   static_cast<void>(generation);
   return nullptr;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -5349,6 +5467,8 @@ const Cipher Cipher::FromName(const char* name, CipherCache* cache) {
 #elif NCRYPTO_USE_BORINGSSL
   static_cast<void>(cache);
   return Cipher();
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -5379,6 +5499,8 @@ const Cipher Cipher::FromNid(int nid, CipherCache* cache) {
   if (name != nullptr) return FromName(name, cache);
 #elif NCRYPTO_USE_BORINGSSL
   static_cast<void>(cache);
+#else
+#error "Unsupported crypto backend"
 #endif

   return Cipher();
@@ -5488,6 +5610,8 @@ bool Cipher::isCtsMode() const {
   return (EVP_CIPHER_get_flags(cipher_) & EVP_CIPH_FLAG_CTS) != 0;
 #elif NCRYPTO_USE_BORINGSSL
   return false;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -5502,6 +5626,8 @@ bool Cipher::isSivMode() const {
   return getMode() == EVP_CIPH_SIV_MODE;
 #elif NCRYPTO_USE_BORINGSSL
   return false;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -5599,6 +5725,8 @@ const char* Cipher::getName() const {
   return EVP_CIPHER_get0_name(cipher_);
 #elif NCRYPTO_USE_BORINGSSL
   return {};
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -5726,6 +5854,8 @@ bool CipherCtxPointer::setCtsMode(const char* mode) {
 #elif NCRYPTO_USE_BORINGSSL
   static_cast<void>(mode);
   return false;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -5740,6 +5870,8 @@ bool CipherCtxPointer::setXtsStandard(const char* standard) {
 #elif NCRYPTO_USE_BORINGSSL
   static_cast<void>(standard);
   return false;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -5789,6 +5921,8 @@ bool CipherCtxPointer::isSivMode() const {
   return getMode() == EVP_CIPH_SIV_MODE;
 #elif NCRYPTO_USE_BORINGSSL
   return false;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -5992,7 +6126,7 @@ bool ECKeyPointer::checkPrivateKey() const {
          EC_POINT_cmp(group, expected.get(), pub, nullptr) == 0;
 }

-#if NCRYPTO_USE_LEGACY_KEY_TYPES
+#if NCRYPTO_USE_BORINGSSL
 ECKeyPointer::ECKeyPointer() : key_(nullptr) {}

 ECKeyPointer::ECKeyPointer(const EVPKeyPointer& key) : key_(nullptr) {
@@ -6147,7 +6281,7 @@ ECKeyPointer ECKeyPointer::New(const EC_GROUP* group) {
   if (!EC_KEY_set_group(ptr.get(), group)) return {};
   return ptr;
 }
-#else
+#elif NCRYPTO_USE_OPENSSL_PROVIDER
 ECKeyPointer::ECKeyPointer() : group_(nullptr), pub_(nullptr), priv_(nullptr) {}

 ECKeyPointer::ECKeyPointer(const EVPKeyPointer& key) : ECKeyPointer() {
@@ -6404,7 +6538,9 @@ ECKeyPointer ECKeyPointer::New(const EC_GROUP* group) {
   }
   return ret;
 }
-#endif  // NCRYPTO_USE_LEGACY_KEY_TYPES
+#else
+#error "Unsupported crypto backend"
+#endif  // NCRYPTO_USE_BORINGSSL

 // ============================================================================

@@ -6448,6 +6584,8 @@ EVPKeyCtxPointer EVPKeyCtxPointer::NewFromName(const char* name) {
   // DSA keys are not supported with BoringSSL.
   if (id == EVP_PKEY_DSA) return {};
   return EVPKeyCtxPointer(EVP_PKEY_CTX_new_id(id, nullptr));
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -6541,6 +6679,8 @@ bool EVPKeyCtxPointer::setEcParameters(const char* group_name, int encoding) {
   return curve != NID_undef &&
          EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx_.get(), curve) == 1 &&
          EVP_PKEY_CTX_set_ec_param_enc(ctx_.get(), encoding) == 1;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -6589,6 +6729,8 @@ bool EVPKeyCtxPointer::setRsaKeygenPubExp(BignumPointer&& e) {
     return true;
   }
   return false;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -6990,6 +7132,8 @@ Rsa::Rsa(const EVP_PKEY* pkey, Selection selection) : Rsa() {
 #elif NCRYPTO_USE_BORINGSSL
 Rsa::Rsa() : rsa_(nullptr) {}
 Rsa::Rsa(OSSL3_CONST RSA* ptr) : rsa_(ptr) {}
+#else
+#error "Unsupported crypto backend"
 #endif

 Rsa Rsa::PublicOnly(const EVPKeyPointer& key) {
@@ -6997,6 +7141,8 @@ Rsa Rsa::PublicOnly(const EVPKeyPointer& key) {
   return Rsa(key.get(), Selection::Public);
 #elif NCRYPTO_USE_BORINGSSL
   return key;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -7009,6 +7155,8 @@ const Rsa::PublicKey Rsa::getPublicKey() const {
   PublicKey key;
   RSA_get0_key(rsa_, &key.n, &key.e, &key.d);
   return key;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -7022,6 +7170,8 @@ const Rsa::PrivateKey Rsa::getPrivateKey() const {
   RSA_get0_factors(rsa_, &key.p, &key.q);
   RSA_get0_crt_params(rsa_, &key.dp, &key.dq, &key.qi);
   return key;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -7092,6 +7242,8 @@ const std::optional<Rsa::PssParams> Rsa::getPssParams() const {
     }
   }
   return ret;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -7131,6 +7283,8 @@ BIOPointer Rsa::derPublicKey() const {
   if (i2d_X509_PUBKEY_bio(bio.get(), pubkey.get()) != 1) return {};
 #elif NCRYPTO_USE_BORINGSSL
   if (rsa_ == nullptr || i2d_RSA_PUBKEY_bio(bio.get(), rsa_) != 1) return {};
+#else
+#error "Unsupported crypto backend"
 #endif
   return bio;
 }
@@ -7149,6 +7303,8 @@ bool Rsa::setPublicKey(BignumPointer&& n, BignumPointer&& e) {
     return true;
   }
   return false;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -7195,6 +7351,8 @@ bool Rsa::setPrivateKey(BignumPointer&& d,

   if (!other_prime_infos.empty()) return false;
   return true;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -7324,6 +7482,8 @@ void array_push_back(const TypeName* evp_ref,
   auto& cb = *(static_cast<CipherCallbackContext*>(arg));
   cb(from);
 }
+#else
+#error "Unsupported crypto backend"
 #endif
 }  // namespace

@@ -7347,6 +7507,8 @@ void Cipher::ForEach(Cipher::CipherNameCallback callback) {
                       EVP_CIPHER_get0_name>,
 #elif NCRYPTO_USE_BORINGSSL
       array_push_back<EVP_CIPHER>,
+#else
+#error "Unsupported crypto backend"
 #endif
       &context);
 #if NCRYPTO_USE_OPENSSL_PROVIDER
@@ -7426,6 +7588,8 @@ Ec::Ec(const EVP_PKEY* pkey) : Ec() {
 #elif NCRYPTO_USE_BORINGSSL
 Ec::Ec() : ec_(nullptr) {}
 Ec::Ec(OSSL3_CONST EC_KEY* key) : ec_(key) {}
+#else
+#error "Unsupported crypto backend"
 #endif

 const EC_GROUP* Ec::getGroup() const {
@@ -7433,6 +7597,8 @@ const EC_GROUP* Ec::getGroup() const {
   return ec_.get();
 #elif NCRYPTO_USE_BORINGSSL
   return ECKeyPointer::GetGroup(ec_);
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -7441,6 +7607,8 @@ const EC_POINT* Ec::getPublicKey() const {
   return pub_.get();
 #elif NCRYPTO_USE_BORINGSSL
   return ECKeyPointer::GetPublicKey(ec_);
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -7449,6 +7617,8 @@ point_conversion_form_t Ec::getPointConversionForm() const {
   return form_;
 #elif NCRYPTO_USE_BORINGSSL
   return EC_KEY_get_conv_form(ec_);
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -7596,6 +7766,8 @@ int Ec::GetCurveId(const EVPKeyPointer& key) {
   if (ec == nullptr) return NID_undef;
   const EC_GROUP* group = EC_KEY_get0_group(ec);
   return group == nullptr ? NID_undef : EC_GROUP_get_curve_name(group);
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -7623,6 +7795,8 @@ std::optional<std::string> Ec::GetCurveName(const EVPKeyPointer& key) {
   const int nid = GetCurveId(key);
   if (nid == NID_undef) return std::nullopt;
   return std::string(OBJ_nid2sn(nid));
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -7647,6 +7821,8 @@ bool Ec::CheckCurveName(const char* name) {
   return IsAvailableEcGroup(name);
 #elif NCRYPTO_USE_BORINGSSL
   return false;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -8447,6 +8623,8 @@ Dsa::Dsa(const EVP_PKEY* pkey) : Dsa() {
 #elif NCRYPTO_USE_BORINGSSL
 Dsa::Dsa() : dsa_(nullptr) {}
 Dsa::Dsa(OSSL3_CONST DSA* dsa) : dsa_(dsa) {}
+#else
+#error "Unsupported crypto backend"
 #endif

 const BIGNUM* Dsa::getP() const {
@@ -8458,6 +8636,8 @@ const BIGNUM* Dsa::getP() const {
   const BIGNUM* p;
   DSA_get0_pqg(dsa_, &p, nullptr, nullptr);
   return p;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -8470,6 +8650,8 @@ const BIGNUM* Dsa::getQ() const {
   const BIGNUM* q;
   DSA_get0_pqg(dsa_, nullptr, &q, nullptr);
   return q;
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -8478,6 +8660,8 @@ size_t Dsa::getModulusLength() const {
   if (!dsa_) return 0;
 #elif NCRYPTO_USE_BORINGSSL
   if (dsa_ == nullptr) return 0;
+#else
+#error "Unsupported crypto backend"
 #endif
   return BignumPointer::GetBitCount(getP());
 }
@@ -8487,6 +8671,8 @@ size_t Dsa::getDivisorLength() const {
   if (!dsa_) return 0;
 #elif NCRYPTO_USE_BORINGSSL
   if (dsa_ == nullptr) return 0;
+#else
+#error "Unsupported crypto backend"
 #endif
   return BignumPointer::GetBitCount(getQ());
 }
diff --git a/deps/ncrypto/ncrypto.h b/deps/ncrypto/ncrypto.h
index e45807ec179..afb780da7cc 100644
--- a/deps/ncrypto/ncrypto.h
+++ b/deps/ncrypto/ncrypto.h
@@ -52,9 +52,11 @@
 #ifdef OPENSSL_IS_BORINGSSL
 #define NCRYPTO_USE_BORINGSSL 1
 #define NCRYPTO_USE_OPENSSL_PROVIDER 0
-#else
+#elif OPENSSL_VERSION_PREREQ(3, 0)
 #define NCRYPTO_USE_BORINGSSL 0
 #define NCRYPTO_USE_OPENSSL_PROVIDER 1
+#else
+#error "Unsupported crypto backend"
 #endif

 #define NCRYPTO_USE_LEGACY_KEY_TYPES NCRYPTO_USE_BORINGSSL
@@ -404,6 +406,8 @@ class DigestCache final {
     static_cast<void>(id);
     static_cast<void>(generation);
     return {};
+#else
+#error "Unsupported crypto backend"
 #endif
   }
   Result insert(const char* name, const EVP_MD* digest, uint64_t generation);
@@ -591,6 +595,8 @@ class Dsa final {
   explicit Dsa(const EVP_PKEY* pkey);
 #elif NCRYPTO_USE_BORINGSSL
   Dsa(OSSL3_CONST DSA* dsa);
+#else
+#error "Unsupported crypto backend"
 #endif
   NCRYPTO_DISALLOW_COPY_AND_MOVE(Dsa)

@@ -600,6 +606,8 @@ class Dsa final {
   }
 #elif NCRYPTO_USE_BORINGSSL
   inline operator bool() const { return dsa_ != nullptr; }
+#else
+#error "Unsupported crypto backend"
 #endif
 #if NCRYPTO_USE_LEGACY_KEY_TYPES
   inline operator OSSL3_CONST DSA*() const { return dsa_; }
@@ -617,6 +625,8 @@ class Dsa final {
   DeleteFnPtr<BIGNUM, BN_free> q_;
 #elif NCRYPTO_USE_BORINGSSL
   OSSL3_CONST DSA* dsa_;
+#else
+#error "Unsupported crypto backend"
 #endif
 };

@@ -632,6 +642,8 @@ class Rsa final {
   explicit Rsa(const EVP_PKEY* pkey, Selection selection = Selection::Private);
 #elif NCRYPTO_USE_BORINGSSL
   Rsa(OSSL3_CONST RSA* rsa);
+#else
+#error "Unsupported crypto backend"
 #endif
   NCRYPTO_DISALLOW_COPY_AND_MOVE(Rsa)

@@ -641,6 +653,8 @@ class Rsa final {
   }
 #elif NCRYPTO_USE_BORINGSSL
   inline operator bool() const { return rsa_ != nullptr; }
+#else
+#error "Unsupported crypto backend"
 #endif
 #if NCRYPTO_USE_LEGACY_KEY_TYPES
   inline operator OSSL3_CONST RSA*() const { return rsa_; }
@@ -724,6 +738,8 @@ class Rsa final {
   std::optional<PssParams> pss_params_;
 #elif NCRYPTO_USE_BORINGSSL
   OSSL3_CONST RSA* rsa_;
+#else
+#error "Unsupported crypto backend"
 #endif
 };

@@ -734,6 +750,8 @@ class Ec final {
   explicit Ec(const EVP_PKEY* pkey);
 #elif NCRYPTO_USE_BORINGSSL
   Ec(OSSL3_CONST EC_KEY* key);
+#else
+#error "Unsupported crypto backend"
 #endif
   NCRYPTO_DISALLOW_COPY_AND_MOVE(Ec)

@@ -772,6 +790,8 @@ class Ec final {
   point_conversion_form_t form_ = POINT_CONVERSION_UNCOMPRESSED;
 #elif NCRYPTO_USE_BORINGSSL
   OSSL3_CONST EC_KEY* ec_ = nullptr;
+#else
+#error "Unsupported crypto backend"
 #endif
 };

@@ -1216,6 +1236,8 @@ class EVPKeyPointer final {
   static EVPKeyPointer NewRSA(const Rsa& rsa);
 #elif NCRYPTO_USE_BORINGSSL
   static EVPKeyPointer NewRSA(RSAPointer&& rsa);
+#else
+#error "Unsupported crypto backend"
 #endif

   enum class PKEncodingType {
@@ -1404,6 +1426,8 @@ class DHPointer final {
   DHPointer(BignumPointer&& p, BignumPointer&& g, const char* group_name);
 #elif NCRYPTO_USE_BORINGSSL
   explicit DHPointer(DH* dh);
+#else
+#error "Unsupported crypto backend"
 #endif
   DHPointer(DHPointer&& other) noexcept;
   DHPointer& operator=(DHPointer&& other) noexcept;
@@ -1420,17 +1444,21 @@ class DHPointer final {
 #elif NCRYPTO_USE_BORINGSSL
   inline bool operator==(std::nullptr_t) noexcept { return dh_ == nullptr; }
   inline operator bool() const { return dh_ != nullptr; }
+#else
+#error "Unsupported crypto backend"
 #endif
-#if NCRYPTO_USE_LEGACY_KEY_TYPES
+#if NCRYPTO_USE_BORINGSSL
   inline DH* get() const { return dh_.get(); }
   void reset(DH* dh = nullptr);
   DH* release();
-#else
+#elif NCRYPTO_USE_OPENSSL_PROVIDER
   inline EVP_PKEY* get() const {
     return dh_.get();
   }
   void reset(EVP_PKEY* dh = nullptr);
   EVP_PKEY* release();
+#else
+#error "Unsupported crypto backend"
 #endif

   enum class CheckResult {
@@ -1488,6 +1516,8 @@ class DHPointer final {
   const char* group_name_ = nullptr;
 #elif NCRYPTO_USE_BORINGSSL
   DeleteFnPtr<DH, DH_free> dh_;
+#else
+#error "Unsupported crypto backend"
 #endif
 };

@@ -1824,14 +1854,18 @@ class ECKeyPointer final {
 #elif NCRYPTO_USE_BORINGSSL
   inline bool operator==(std::nullptr_t) noexcept { return key_ == nullptr; }
   inline operator bool() const { return key_ != nullptr; }
+#else
+#error "Unsupported crypto backend"
 #endif
-#if NCRYPTO_USE_LEGACY_KEY_TYPES
+#if NCRYPTO_USE_BORINGSSL
   inline EC_KEY* get() const { return key_.get(); }
   inline operator EC_KEY*() const { return key_.get(); }
   void reset(EC_KEY* key = nullptr);
   EC_KEY* release();
-#else
+#elif NCRYPTO_USE_OPENSSL_PROVIDER
   void reset();
+#else
+#error "Unsupported crypto backend"
 #endif

   ECKeyPointer clone() const;
@@ -1865,6 +1899,8 @@ class ECKeyPointer final {
   DeleteFnPtr<BIGNUM, BN_clear_free> priv_;
 #elif NCRYPTO_USE_BORINGSSL
   DeleteFnPtr<EC_KEY, EC_KEY_free> key_;
+#else
+#error "Unsupported crypto backend"
 #endif
 };

diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc
index beef99a8f1c..1c038641d12 100644
--- a/src/crypto/crypto_context.cc
+++ b/src/crypto/crypto_context.cc
@@ -1876,6 +1876,8 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
                                        TicketCompatibilityCallback);
 #elif NCRYPTO_USE_BORINGSSL
   SSL_CTX_set_tlsext_ticket_key_cb(sc->ctx_.get(), TicketCompatibilityCallback);
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -2140,6 +2142,8 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
     if (params && params.isA(KeyAlgorithm::DH)) dh.reset(params.release());
 #elif NCRYPTO_USE_BORINGSSL
     dh.reset(PEM_read_bio_DHparams(bio.get(), nullptr, nullptr, nullptr));
+#else
+#error "Unsupported crypto backend"
 #endif
   }

@@ -2164,6 +2168,8 @@ void SecureContext::SetDHParam(const FunctionCallbackInfo<Value>& args) {
   if (!SSL_CTX_set0_tmp_dh_pkey(sc->ctx_.get(), dh_pkey.get())) {
 #elif NCRYPTO_USE_BORINGSSL
   if (!SSL_CTX_set_tmp_dh(sc->ctx_.get(), dh.get())) {
+#else
+#error "Unsupported crypto backend"
 #endif
     return THROW_ERR_CRYPTO_OPERATION_FAILED(
         env, "Error setting temp DH parameter");
@@ -2515,6 +2521,8 @@ void SecureContext::EnableTicketKeyCallback(
   SSL_CTX_set_tlsext_ticket_key_evp_cb(wrap->ctx_.get(), TicketKeyCallback);
 #elif NCRYPTO_USE_BORINGSSL
   SSL_CTX_set_tlsext_ticket_key_cb(wrap->ctx_.get(), TicketKeyCallback);
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -2536,6 +2544,8 @@ bool InitTicketHmac(EVP_MAC_CTX* hctx,
 bool InitTicketHmac(HMAC_CTX* hctx, const unsigned char* key, size_t key_len) {
   return HMAC_Init_ex(hctx, key, key_len, Digest::SHA256, nullptr) == 1;
 }
+#else
+#error "Unsupported crypto backend"
 #endif
 }  // namespace

@@ -2547,6 +2557,8 @@ int SecureContext::TicketKeyCallback(SSL* ssl,
                                      EVP_MAC_CTX* hctx,
 #elif NCRYPTO_USE_BORINGSSL
                                      HMAC_CTX* hctx,
+#else
+#error "Unsupported crypto backend"
 #endif
                                      int enc) {
   static const int kTicketPartSize = 16;
@@ -2644,6 +2656,8 @@ int SecureContext::TicketCompatibilityCallback(SSL* ssl,
                                                EVP_MAC_CTX* hctx,
 #elif NCRYPTO_USE_BORINGSSL
                                                HMAC_CTX* hctx,
+#else
+#error "Unsupported crypto backend"
 #endif
                                                int enc) {
   SecureContext* sc = static_cast<SecureContext*>(
diff --git a/src/crypto/crypto_context.h b/src/crypto/crypto_context.h
index 285f8657eb4..8912b26d657 100644
--- a/src/crypto/crypto_context.h
+++ b/src/crypto/crypto_context.h
@@ -170,6 +170,8 @@ class SecureContext final : public BaseObject {
                                EVP_MAC_CTX* hctx,
 #elif NCRYPTO_USE_BORINGSSL
                                HMAC_CTX* hctx,
+#else
+#error "Unsupported crypto backend"
 #endif
                                int enc);

@@ -181,6 +183,8 @@ class SecureContext final : public BaseObject {
                                          EVP_MAC_CTX* hctx,
 #elif NCRYPTO_USE_BORINGSSL
                                          HMAC_CTX* hctx,
+#else
+#error "Unsupported crypto backend"
 #endif
                                          int enc);

diff --git a/src/crypto/crypto_hash.cc b/src/crypto/crypto_hash.cc
index 11274d98568..5ff56a322a1 100644
--- a/src/crypto/crypto_hash.cc
+++ b/src/crypto/crypto_hash.cc
@@ -235,6 +235,8 @@ void SaveSupportedHashAlgorithms(const EVP_MD* md,
   Environment* env = static_cast<Environment*>(arg);
   env->supported_hash_algorithms.push_back(from);
 }
+#else
+#error "Unsupported crypto backend"
 #endif  // NCRYPTO_USE_OPENSSL_PROVIDER

 const std::vector<std::string>& GetSupportedHashAlgorithms(Environment* env) {
@@ -255,6 +257,8 @@ const std::vector<std::string>& GetSupportedHashAlgorithms(Environment* env) {
       EVP_MD_do_all_provided(nullptr, SaveSupportedProviderHashAlgorithms, env);
 #elif NCRYPTO_USE_BORINGSSL
       EVP_MD_do_all_sorted(SaveSupportedHashAlgorithms, env);
+#else
+#error "Unsupported crypto backend"
 #endif
 #if NCRYPTO_USE_BORINGSSL
       // SHA-3 descriptors are not included in BoringSSL's name registry.
@@ -354,6 +358,8 @@ const EVP_MD* GetDigestImplementation(
 #elif NCRYPTO_USE_BORINGSSL
   Utf8Value utf8(env->isolate(), algorithm);
   return ncrypto::getDigestByName(*utf8);
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -362,6 +368,8 @@ void MarkInvalidXofLength() {
   ERR_raise(ERR_LIB_EVP, EVP_R_NOT_XOF_OR_INVALID_LENGTH);
 #elif NCRYPTO_USE_BORINGSSL
   EVPerr(EVP_F_EVP_DIGESTFINALXOF, EVP_R_NOT_XOF_OR_INVALID_LENGTH);
+#else
+#error "Unsupported crypto backend"
 #endif
 }

@@ -379,6 +387,8 @@ bool IsShakeDigest(const EVP_MD* md) {
   const char* name = OBJ_nid2sn(EVP_MD_type(md));
   return name != nullptr &&
          (strcmp(name, "SHAKE128") == 0 || strcmp(name, "SHAKE256") == 0);
+#else
+#error "Unsupported crypto backend"
 #endif
 }
 #endif
@@ -550,6 +560,8 @@ void Hash::OneShotDigest(const FunctionCallbackInfo<Value>& args) {
     Utf8Value utf8(env->isolate(), args[0]);
     return OneShotDigestWithMD(
         env, args, ncrypto::getDigestByName(*utf8), nullptr);
+#else
+#error "Unsupported crypto backend"
 #endif
   }

diff --git a/src/crypto/crypto_rsa.cc b/src/crypto/crypto_rsa.cc
index 1ec3a487dfe..353148d3cdd 100644
--- a/src/crypto/crypto_rsa.cc
+++ b/src/crypto/crypto_rsa.cc
@@ -53,6 +53,8 @@ bool IsRsaPssDigestEncodable(const Digest& digest) {
 #elif NCRYPTO_USE_BORINGSSL
   static_cast<void>(digest);
   return true;
+#else
+#error "Unsupported crypto backend"
 #endif
 }
 }  // namespace
@@ -403,6 +405,8 @@ KeyObjectData ImportJWKRsaKey(Environment* env, Local<Object> jwk) {
   }

   ncrypto::Rsa rsa_view(rsa.get());
+#else
+#error "Unsupported crypto backend"
 #endif

   ByteSource n = ByteSource::FromEncodedString(env, n_value.As<String>());
@@ -511,6 +515,8 @@ KeyObjectData ImportJWKRsaKey(Environment* env, Local<Object> jwk) {
   auto pkey = EVPKeyPointer::NewRSA(rsa_view);
 #elif NCRYPTO_USE_BORINGSSL
   auto pkey = EVPKeyPointer::NewRSA(std::move(rsa));
+#else
+#error "Unsupported crypto backend"
 #endif
   if (!pkey) {
     THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Unable to create key pointer");
diff --git a/src/crypto/crypto_tls.cc b/src/crypto/crypto_tls.cc
index 5792de0515d..075ab9241b9 100644
--- a/src/crypto/crypto_tls.cc
+++ b/src/crypto/crypto_tls.cc
@@ -955,6 +955,8 @@ void TLSWrap::ClearOut() {
           const char* fs = nullptr;
 #elif NCRYPTO_USE_BORINGSSL
           const char* fs = ERR_func_error_string(ssl_err);
+#else
+#error "Unsupported crypto backend"
 #endif
           const char* rs = ERR_reason_error_string(ssl_err);
           if (!Set(env(), obj, env()->library_string(), ls) ||
diff --git a/src/crypto/crypto_util.cc b/src/crypto/crypto_util.cc
index d8700e3c85b..783620c1210 100644
--- a/src/crypto/crypto_util.cc
+++ b/src/crypto/crypto_util.cc
@@ -886,6 +886,8 @@ Maybe<void> Decorate(Environment* env,
   const char* fs = nullptr;
 #elif NCRYPTO_USE_BORINGSSL
   const char* fs = ERR_func_error_string(err);
+#else
+#error "Unsupported crypto backend"
 #endif
   const char* rs = ERR_reason_error_string(err);

diff --git a/test/cctest/test_node_crypto.cc b/test/cctest/test_node_crypto.cc
index 45d5b7facc3..55c619fb09a 100644
--- a/test/cctest/test_node_crypto.cc
+++ b/test/cctest/test_node_crypto.cc
@@ -455,6 +455,8 @@ TEST(NodeCrypto, EcKeyComponents) {
     EXPECT_EQ(memcmp(raw_public.get(), point.get(), point.size()), 0);
 #elif NCRYPTO_USE_BORINGSSL
     EXPECT_FALSE(raw_public);
+#else
+#error "Unsupported crypto backend"
 #endif
     EXPECT_FALSE(
         ncrypto::Ec::TryExportPublic(key, POINT_CONVERSION_COMPRESSED));
@@ -1015,6 +1017,8 @@ TEST(NodeCrypto, X509FormattingPreservesUnrelatedErrors) {
   ERR_raise(ERR_LIB_USER, 1);
 #elif NCRYPTO_USE_BORINGSSL
   ERR_put_error(ERR_LIB_USER, 0, 1, __FILE__, __LINE__);
+#else
+#error "Unsupported crypto backend"
 #endif
   const unsigned long expected = ERR_peek_error();  // NOLINT(runtime/int)
   ASSERT_NE(expected, 0UL);
@@ -1147,6 +1151,8 @@ TEST(NodeCrypto, X509KeyVisitorsHandleMissingPublicKey) {
   ERR_raise(ERR_LIB_USER, 1);
 #elif NCRYPTO_USE_BORINGSSL
   ERR_put_error(ERR_LIB_USER, 0, 1, __FILE__, __LINE__);
+#else
+#error "Unsupported crypto backend"
 #endif
   const unsigned long expected = ERR_peek_error();  // NOLINT(runtime/int)
   ASSERT_NE(expected, 0UL);
@@ -1179,6 +1185,8 @@ TEST(NodeCrypto, X509UsageVisitorPreservesCallbackErrors) {
     ERR_raise(ERR_LIB_USER, 1);
 #elif NCRYPTO_USE_BORINGSSL
     ERR_put_error(ERR_LIB_USER, 0, 1, __FILE__, __LINE__);
+#else
+#error "Unsupported crypto backend"
 #endif
   }));
   EXPECT_EQ(calls, 1);