diff --git a/lib/plug/crypto.ex b/lib/plug/crypto.ex index 65e9d14..682ec05 100644 --- a/lib/plug/crypto.ex +++ b/lib/plug/crypto.ex @@ -133,22 +133,30 @@ defmodule Plug.Crypto do # TODO: remove when we require OTP 25.0 if Code.ensure_loaded?(:crypto) and function_exported?(:crypto, :hash_equals, 2) do defp crypto_hash_equals(x, y) do - :crypto.hash_equals(x, y) + # Depending on the linked OpenSSL library hash_equals is available. + # If not, we fall back to the legacy implementation. + try do + :crypto.hash_equals(x, y) + rescue + # Still can throw "Unsupported CRYPTO_memcmp" + ErlangError -> + legacy_secure_compare(x, y, 0) + end end else defp crypto_hash_equals(x, y) do legacy_secure_compare(x, y, 0) end + end - defp legacy_secure_compare(<>, <>, acc) do - import Bitwise - xorred = bxor(x, y) - legacy_secure_compare(left, right, acc ||| xorred) - end + defp legacy_secure_compare(<>, <>, acc) do + import Bitwise + xorred = bxor(x, y) + legacy_secure_compare(left, right, acc ||| xorred) + end - defp legacy_secure_compare(<<>>, <<>>, acc) do - acc === 0 - end + defp legacy_secure_compare(<<>>, <<>>, acc) do + acc === 0 end @doc """