-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
crypto/elliptic: IsOnCurve returns true for invalid field elements #50974
Comments
@gopherbot please open backport issues for this security fix. /cc @golang/security |
Backport issue(s) opened: #50977 (for 1.16), #50978 (for 1.17). Remember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://golang.org/wiki/MinorReleases. |
Change https://golang.org/cl/382455 mentions this issue: |
This comment was marked as duplicate.
This comment was marked as duplicate.
This comment was marked as duplicate.
This comment was marked as duplicate.
Change https://golang.org/cl/382854 mentions this issue: |
Change https://golang.org/cl/382855 mentions this issue: |
…for invalid field elements Updates #50974 Fixes #50978 Fixes CVE-2022-23806 Change-Id: I0201c2c88f13dd82910985a495973f1683af9259 Reviewed-on: https://go-review.googlesource.com/c/go/+/382854 Trust: Filippo Valsorda <filippo@golang.org> Run-TryBot: Filippo Valsorda <filippo@golang.org> Reviewed-by: Katie Hockman <katie@golang.org> Trust: Katie Hockman <katie@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org>
…for invalid field elements Updates #50974 Fixes #50977 Fixes CVE-2022-23806 Change-Id: I0201c2c88f13dd82910985a495973f1683af9259 Reviewed-on: https://go-review.googlesource.com/c/go/+/382855 Trust: Filippo Valsorda <filippo@golang.org> Run-TryBot: Filippo Valsorda <filippo@golang.org> Reviewed-by: Katie Hockman <katie@golang.org> Trust: Katie Hockman <katie@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org>
…for invalid field elements Updates golang#50974 Fixes golang#50977 Fixes CVE-2022-23806 Change-Id: I0201c2c88f13dd82910985a495973f1683af9259 Reviewed-on: https://go-review.googlesource.com/c/go/+/382855 Trust: Filippo Valsorda <filippo@golang.org> Run-TryBot: Filippo Valsorda <filippo@golang.org> Reviewed-by: Katie Hockman <katie@golang.org> Trust: Katie Hockman <katie@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org>
# AWS EKS Backported To: go-1.15.15-eks Backported On: Thu, 22 Sept 2022 Backported By: budris@amazon.com Backported From: release-branch.go1.16 Upstream Source Commit: golang@6b3e741 EKS Patch Source Commit: danbudris@d90d600 # Original Information Updates golang#50974 Fixes golang#50977 Fixes CVE-2022-23806 Change-Id: I0201c2c88f13dd82910985a495973f1683af9259 Reviewed-on: https://go-review.googlesource.com/c/go/+/382855 Trust: Filippo Valsorda <filippo@golang.org> Run-TryBot: Filippo Valsorda <filippo@golang.org> Reviewed-by: Katie Hockman <katie@golang.org> Trust: Katie Hockman <katie@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org>
# AWS EKS Backported To: go-1.15.15-eks Backported On: Thu, 22 Sept 2022 Backported By: budris@amazon.com Backported From: release-branch.go1.16 Upstream Source Commit: golang@6b3e741 EKS Patch Source Commit: danbudris@d90d600 # Original Information Updates golang#50974 Fixes golang#50977 Fixes CVE-2022-23806 Change-Id: I0201c2c88f13dd82910985a495973f1683af9259 Reviewed-on: https://go-review.googlesource.com/c/go/+/382855 Trust: Filippo Valsorda <filippo@golang.org> Run-TryBot: Filippo Valsorda <filippo@golang.org> Reviewed-by: Katie Hockman <katie@golang.org> Trust: Katie Hockman <katie@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org>
- Sender and receiver had different versions of schollz/pake. The old version in the receiver was broken in go 1.19 (golang/go#50974) - Upgrade other packages -
- Sender and receiver had different versions of schollz/pake. The old version in the receiver was broken in go 1.19 (golang/go#50974) - Upgrade other packages -
…der and receiver (#29) - Remove per-message size limit - Sender and receiver had different versions of schollz/pake. The old version in the receiver was broken in go 1.19 (golang/go#50974) - Update call to deprecated BubbleTea function - Upgrade other packages
Guido Vranken reported to us a pair of
big.Int
coordinates that returns true fromIsOnCurve
, and then causes a panic inScalarMult
. Our investigation concluded that there is a broader issue withbig.Int
s that are invalid representations of a field element.Background
First, a bit of context of how we got here. crypto/elliptic implements elliptic curves over prime-order finite fields, meaning coordinates are elements of the field composed of the integers from zero to P-1 for some prime P. Integers below zero (negative) or equal to or higher than P (overflowing) are as meaningless as coordinates as
float64(1.5)
orstring("hi")
would be.Regrettably, the crypto/elliptic API allows passing negative or overflowing
big.Int
s as coordinates.Similarly, an arbitrary pair of field elements
(x, y)
is not a valid point if they don't satisfy the curve equation, and doing group operations (like a scalar multiplication) on them is meaningless. (Worse, it's called an invalid curve attack and can leak bits of the scalar that an attacker can plug into the evergreen Chinese Remainder Theorem.)As you probably guessed, dear reader, crypto/elliptic will let us call
ScalarMult
on any pair ofbig.Int
s. Adding insult to injury, neitherelliptic.Marshal
nor the group operations (Add
,Double
,ScalarMult
) return an error, giving us no opportunity to reject nonsensical or radioactive inputs.The (implicit in Go 1.17, made explicit in Go 1.18 by my recent refactor) contract of crypto/elliptic is: you shall pass input points though
IsOnCurve
(Unmarshal
will do it for you); if it returns true, then all group operations will work and return valid points. IfIsOnCurve
returns false, behavior is undefined.(With one footnote:
(0, 0)
is not a valid point,Unmarshal
will not return it,IsOnCurve
will return false, andMarshal
will behave incorrectly, but it's what group operations return if the output is the point at infinity, which can't be represented with two abelian coordinates. Again, exposing the coordinates in the API is a mistake. See this Go 1.15 change and the linked issue for more info.)Current status
Cool. Now, let's look at what the actual behavior is for some invalid inputs: https://go.dev/play/p/GBMkROJLtDX
The results might look all over the place, especially in that they change at tip, but here are the patterns:
IsOnCurve
behaves according to the backend implementation.IsOnCurve
, the P-256 one, and the Go 1.17 fiat-crypto ones accept coordinates of any sign or size (such as(x - 1000P, y)
,(x - P, y)
, or(x + 1000P, y)
), as long as they reduce to a valid coordinate.IsOnCurve
returns false, but unintentionally, due to dropping the sign and the overflow. Go 1.18 is fixed for overflowing values but not negative ones.Marshal
panics on anything bigger than P in absolute value (by enough to overflow the slice length rounded up to the nearest byte), and it encodes the wrong value (P-x
instead ofx
) for a small but negative value.ScalarMult
also behaves according to the backend implementation.(x, y)
.(x, y)
.IsOnCurve
leads to an off-curve output is also very bad, as it leads to invalid curve attacks.Remediation
First, we will fix
IsOnCurve
as a security issue (CVE-2022-23806) to always return false for negative and overflowing values, because that's the function behaving inconsistently and the only one for which these inputs shouldn't be undefined behavior. I expect next to no one will get broken by this, because the rest of the operations rarely behave correctly on the values that incorrectly return true.This issue is being fixed on the PUBLIC track, since we found no paths for negative elements to get deserialized (ASN.1,
Unmarshal
, popular JOSE libraries) and the only curve where large positive elements lead to invalid curve operations is P-224, which is rarely used.Next, we need to decide what
Marshal
and the group operations should do for invalid field elements, and more broadly for invalid points (which are not discussed above, but generally will always return invalid outputs except for Go 1.18's nistec backend, which returns random values). I opened a separate issue (#50975) for that, which we will discuss for Go 1.19, as all that is undefined behavior onceIsOnCurve
behaves correctly.The text was updated successfully, but these errors were encountered: