Argon2.Verify() and the open-coded verification in the usage sample in README.md both use !hashB.Buffer.Where((b, i) => b != hashToVerify[i]).Any() to compare hashes for verification.
This is not a time-constant operation and aborts as soon as the first non-equal byte is encountered. As such, the time the verify operation takes depends on user-controlled input and enables an attacker to mount a timing attack (see eg. Wikipedia)
Argon2.Verify()
and the open-coded verification in the usage sample in README.md both use!hashB.Buffer.Where((b, i) => b != hashToVerify[i]).Any()
to compare hashes for verification.This is not a time-constant operation and aborts as soon as the first non-equal byte is encountered. As such, the time the verify operation takes depends on user-controlled input and enables an attacker to mount a timing attack (see eg. Wikipedia)
You can avoid this by using a time-constant buffer comparison. See eg. the reference implementation of Argon2: https://github.com/P-H-C/phc-winner-argon2/blob/f30e1f11f2e2619f07a4950abe1419218c4900be/src/argon2.c#L239
Argon2.Verify()
should either useCryptographicOperations.FixedTimeEquals()
or an open-coded version of this.