-
Notifications
You must be signed in to change notification settings - Fork 18k
x/crypto/curve25519: pure Go implementation mismatch with BoringSSL #30095
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Change https://golang.org/cl/161257 mentions this issue: |
Change https://golang.org/cl/161277 mentions this issue: |
Re-opening this as a reminder to update the version vendored into the standard library. @FiloSottile is it ok to wait for 1.13 for that or does it need to happen in 1.12? |
Let's do it in 1.13, there seems to be no security implication. |
This diff extends the curve25519 test suite with some test vectors generated from BoringSSL. Updates golang/go#30095 Change-Id: I4e871378c77b46167d162e9eec75fc412596ff7c Reviewed-on: https://go-review.googlesource.com/c/crypto/+/161277 Reviewed-by: Filippo Valsorda <[email protected]> Run-TryBot: Filippo Valsorda <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
This got imported in Go 1.13.
|
Comparison against BoringSSL-generated test vectors showed mismatches with the pure Go implementation of curve25519. The problem was narrowed down to a missing mask in feFromBytes(). This diff adds the mask, bringing this back in line with the reference implementation and RFC 7748: When receiving such an array, implementations of X25519 (but not X448) MUST mask the most significant bit in the final byte. This is done to preserve compatibility with point formats that reserve the sign bit for use in other protocols and to increase resistance to implementation fingerprinting. Fixes golang/go#30095 Change-Id: If7efc0e2acd6efb761d6e3cb89cec359d7d81cb1 Reviewed-on: https://go-review.googlesource.com/c/161257 Run-TryBot: Filippo Valsorda <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Filippo Valsorda <[email protected]>
Comparison against BoringSSL-generated test vectors showed mismatches with the pure Go implementation of curve25519. The problem was narrowed down to a missing mask in feFromBytes(). This diff adds the mask, bringing this back in line with the reference implementation and RFC 7748: When receiving such an array, implementations of X25519 (but not X448) MUST mask the most significant bit in the final byte. This is done to preserve compatibility with point formats that reserve the sign bit for use in other protocols and to increase resistance to implementation fingerprinting. Fixes golang/go#30095 Change-Id: If7efc0e2acd6efb761d6e3cb89cec359d7d81cb1 Reviewed-on: https://go-review.googlesource.com/c/161257 Run-TryBot: Filippo Valsorda <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Filippo Valsorda <[email protected]>
Comparison against BoringSSL-generated test vectors showed mismatches with the pure Go implementation of curve25519. The problem was narrowed down to a missing mask in feFromBytes(). This diff adds the mask, bringing this back in line with the reference implementation and RFC 7748: When receiving such an array, implementations of X25519 (but not X448) MUST mask the most significant bit in the final byte. This is done to preserve compatibility with point formats that reserve the sign bit for use in other protocols and to increase resistance to implementation fingerprinting. Fixes golang/go#30095 Change-Id: If7efc0e2acd6efb761d6e3cb89cec359d7d81cb1 Reviewed-on: https://go-review.googlesource.com/c/161257 Run-TryBot: Filippo Valsorda <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Filippo Valsorda <[email protected]>
Comparison against BoringSSL-generated test vectors showed mismatches with the pure Go implementation of curve25519. The problem was narrowed down to a missing mask in feFromBytes(). This diff adds the mask, bringing this back in line with the reference implementation and RFC 7748: When receiving such an array, implementations of X25519 (but not X448) MUST mask the most significant bit in the final byte. This is done to preserve compatibility with point formats that reserve the sign bit for use in other protocols and to increase resistance to implementation fingerprinting. Fixes golang/go#30095 Change-Id: If7efc0e2acd6efb761d6e3cb89cec359d7d81cb1 Reviewed-on: https://go-review.googlesource.com/c/161257 Run-TryBot: Filippo Valsorda <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Filippo Valsorda <[email protected]>
Comparison against BoringSSL-generated test vectors showed mismatches with the pure Go implementation of curve25519. The problem was narrowed down to a missing mask in feFromBytes(). This diff adds the mask, bringing this back in line with the reference implementation and RFC 7748: When receiving such an array, implementations of X25519 (but not X448) MUST mask the most significant bit in the final byte. This is done to preserve compatibility with point formats that reserve the sign bit for use in other protocols and to increase resistance to implementation fingerprinting. Fixes golang/go#30095 Change-Id: If7efc0e2acd6efb761d6e3cb89cec359d7d81cb1 Reviewed-on: https://go-review.googlesource.com/c/161257 Run-TryBot: Filippo Valsorda <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Filippo Valsorda <[email protected]>
Comparison against BoringSSL-generated test vectors showed mismatches with the pure Go implementation of curve25519. The problem was narrowed down to a missing mask in feFromBytes(). This diff adds the mask, bringing this back in line with the reference implementation and RFC 7748: When receiving such an array, implementations of X25519 (but not X448) MUST mask the most significant bit in the final byte. This is done to preserve compatibility with point formats that reserve the sign bit for use in other protocols and to increase resistance to implementation fingerprinting. Fixes golang/go#30095 Change-Id: If7efc0e2acd6efb761d6e3cb89cec359d7d81cb1 Reviewed-on: https://go-review.googlesource.com/c/161257 Run-TryBot: Filippo Valsorda <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Filippo Valsorda <[email protected]>
I believe there is a bug in the pure Go implementation of curve25519. Comparison between the pure Go and assembly implementations demonstrated a mismatch. Further testing showed that the pure Go version fails test vectors generated with BoringSSL. Full details are in the mmcloughlin/bug25519 repository, but the salient points are below.
Problem
BoringSSL test vectors pass on the
amd64
architecture (assembly implementation):However the pure Go version does not (induced with the
appengine
tag)Approximately half of the test vectors fail.
Fix
Comparison of the individual
fe*()
functions against theref10
implementation suggests the problem is infeFromBytes()
. By eye we see the Go implementation is missing a mask. The following patch appears to fix the problem.See the corresponding line in the reference implementation. Note also that RFC 7748 specifies:
The text was updated successfully, but these errors were encountered: