Closed falko17 closed 2 years ago
huh. great detective work! thanks, just came back from afk time. will have a look at this asap. btw any idea why did the test-vectors not catch this?
btw any idea why did the test-vectors not catch this?
I'm not sure, actually. I didn't have to modify them either to pass the tests, so they don't seem to catch any changes here, which is weird—the only thing I can think of is that the first problem (state parameter re-use) isn't necessarily easily reproducible, and perhaps doesn't occur in the test environment for some reason? As for the second problem (key length), maybe the HMAC itself is not something that's covered by the test vectors? This is pure speculation, though.
thank you very much for this great contribution!
Summary
This pull request fixes two bugs which lead to an incorrect
client_mac
being calculated: the first bug was about reusing a state parameter which has already been "used up", the second was using an incorrect key length.Details
State parameter reuse
The function
calc_preamble
ends by callingcrypto_hash_sha512_final
on it. After this (according to the libsodium documentation) the passed-in state parameter must not be re-used. However, in our case the parameter was re-used, because thepreamble_state
was used not only for theserver_mac
, but also for theclient_mac
—hence, the SHA512 sum that was calculated before this commit was incorrect.This bug has been fixed by copying the state parameter before passing it to
crypto_hash_sha512_final
. That way, the caller ofcalc_preamble
can still use the state and the correct SHA512 sum will be calculated.Incorrect key length
The function
crypto_auth_hmacsha512
was used inRecoverCredentials
andCreateCredentialResponse
. This was a problem because the function (i.e., libsodium) uses 32-byte keys by default, while OPAQUE specifies a key length of 64 bytes.The problem has been fixed by replacing this function call with
opaque_hmacsha512
, which uses the correct key length.Testing procedure / Background
I noticed these two bugs in the first place because I was using
opaque-ke
on one side andlibopaque
on the other. Trying to make these two libraries work together was a little difficult due to the relative complexity of pinning down why a certain step failed, but when using the version oflibopaque
from this pull request and the latest commit ofopaque-ke
[^1], the login flow finally completes successfully.In other words, it should now be possible to use
libopaque
andopaque-ke
together without any problems.(I've also run the tests generated by
make tests
to make sure I didn't break anything.)[^1]: Before this commit (which is not yet released in the crate itself),
opaque-ke
used a non-standard salt length, which also made it impossible to combine it withlibopaque
.