Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions lib/plug/crypto.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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(<<x, left::binary>>, <<y, right::binary>>, acc) do
import Bitwise
xorred = bxor(x, y)
legacy_secure_compare(left, right, acc ||| xorred)
end
defp legacy_secure_compare(<<x, left::binary>>, <<y, right::binary>>, 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 """
Expand Down