summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoss Burton <ross.burton@arm.com>2023-03-27 13:03:35 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2023-03-28 22:28:45 +0100
commit985f1b883fe78af47f0956d9c7b5d5780e1baf0e (patch)
tree646a48518d310a03777ff3f4361d42a2efff3b29
parent13d4b2a4552cb4f2c95e5793592ec4ba810702c8 (diff)
downloadpoky-985f1b883fe78af47f0956d9c7b5d5780e1baf0e.tar.gz
go: fix CVE-2023-2453
Backport a security fix, can be removed once we have 1.20.2 onwards. (From OE-Core rev: 06df8350c3bc6f56013a0bff20b64cfdbb81cfca) Signed-off-by: Ross Burton <ross.burton@arm.com> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-devtools/go/go-1.20.1.inc1
-rw-r--r--meta/recipes-devtools/go/go/CVE-2023-24532.patch208
2 files changed, 209 insertions, 0 deletions
diff --git a/meta/recipes-devtools/go/go-1.20.1.inc b/meta/recipes-devtools/go/go-1.20.1.inc
index ffde7ed732..b1f569212d 100644
--- a/meta/recipes-devtools/go/go-1.20.1.inc
+++ b/meta/recipes-devtools/go/go-1.20.1.inc
@@ -15,5 +15,6 @@ SRC_URI += "\
15 file://0008-src-cmd-dist-buildgo.go-do-not-hardcode-host-compile.patch \ 15 file://0008-src-cmd-dist-buildgo.go-do-not-hardcode-host-compile.patch \
16 file://0009-go-Filter-build-paths-on-staticly-linked-arches.patch \ 16 file://0009-go-Filter-build-paths-on-staticly-linked-arches.patch \
17 file://0010-cmd-compile-re-compile-instantiated-generic-methods-.patch \ 17 file://0010-cmd-compile-re-compile-instantiated-generic-methods-.patch \
18 file://CVE-2023-24532.patch \
18" 19"
19SRC_URI[main.sha256sum] = "b5c1a3af52c385a6d1c76aed5361cf26459023980d0320de7658bae3915831a2" 20SRC_URI[main.sha256sum] = "b5c1a3af52c385a6d1c76aed5361cf26459023980d0320de7658bae3915831a2"
diff --git a/meta/recipes-devtools/go/go/CVE-2023-24532.patch b/meta/recipes-devtools/go/go/CVE-2023-24532.patch
new file mode 100644
index 0000000000..22f080dbd4
--- /dev/null
+++ b/meta/recipes-devtools/go/go/CVE-2023-24532.patch
@@ -0,0 +1,208 @@
1From 602eeaab387f24a4b28c5eccbb50fa934f3bc3c4 Mon Sep 17 00:00:00 2001
2From: Filippo Valsorda <filippo@golang.org>
3Date: Mon, 13 Feb 2023 15:16:27 +0100
4Subject: [PATCH] [release-branch.go1.20] crypto/internal/nistec: reduce P-256
5 scalar
6
7Unlike the rest of nistec, the P-256 assembly doesn't use complete
8addition formulas, meaning that p256PointAdd[Affine]Asm won't return the
9correct value if the two inputs are equal.
10
11This was (undocumentedly) ignored in the scalar multiplication loops
12because as long as the input point is not the identity and the scalar is
13lower than the order of the group, the addition inputs can't be the same.
14
15As part of the math/big rewrite, we went however from always reducing
16the scalar to only checking its length, under the incorrect assumption
17that the scalar multiplication loop didn't require reduction.
18
19Added a reduction, and while at it added it in P256OrdInverse, too, to
20enforce a universal reduction invariant on p256OrdElement values.
21
22Note that if the input point is the infinity, the code currently still
23relies on undefined behavior, but that's easily tested to behave
24acceptably, and will be addressed in a future CL.
25
26Updates #58647
27Fixes #58720
28Fixes CVE-2023-24532
29
30(Filed with the "safe APIs like complete addition formulas are good" dept.)
31
32Change-Id: I7b2c75238440e6852be2710fad66ff1fdc4e2b24
33Reviewed-on: https://go-review.googlesource.com/c/go/+/471255
34TryBot-Result: Gopher Robot <gobot@golang.org>
35Reviewed-by: Roland Shoemaker <roland@golang.org>
36Run-TryBot: Filippo Valsorda <filippo@golang.org>
37Auto-Submit: Filippo Valsorda <filippo@golang.org>
38Reviewed-by: Damien Neil <dneil@google.com>
39(cherry picked from commit 203e59ad41bd288e1d92b6f617c2f55e70d3c8e3)
40Reviewed-on: https://go-review.googlesource.com/c/go/+/471695
41Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
42Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
43Reviewed-by: Filippo Valsorda <filippo@golang.org>
44Run-TryBot: Roland Shoemaker <roland@golang.org>
45
46CVE: CVE-2023-24532
47Upstream-Status: Backport [602eeaab387f24a4b28c5eccbb50fa934f3bc3c4]
48Signed-off-by: Ross Burton <ross.burton@arm.com>
49
50---
51 src/crypto/internal/nistec/nistec_test.go | 81 +++++++++++++++++++++++
52 src/crypto/internal/nistec/p256_asm.go | 17 +++++
53 src/crypto/internal/nistec/p256_ordinv.go | 1 +
54 3 files changed, 99 insertions(+)
55
56diff --git a/src/crypto/internal/nistec/nistec_test.go b/src/crypto/internal/nistec/nistec_test.go
57index 309f68be16a9f..9103608c18a0f 100644
58--- a/src/crypto/internal/nistec/nistec_test.go
59+++ b/src/crypto/internal/nistec/nistec_test.go
60@@ -8,6 +8,7 @@ import (
61 "bytes"
62 "crypto/elliptic"
63 "crypto/internal/nistec"
64+ "fmt"
65 "internal/testenv"
66 "math/big"
67 "math/rand"
68@@ -165,6 +166,86 @@ func testEquivalents[P nistPoint[P]](t *testing.T, newPoint func() P, c elliptic
69 }
70 }
71
72+func TestScalarMult(t *testing.T) {
73+ t.Run("P224", func(t *testing.T) {
74+ testScalarMult(t, nistec.NewP224Point, elliptic.P224())
75+ })
76+ t.Run("P256", func(t *testing.T) {
77+ testScalarMult(t, nistec.NewP256Point, elliptic.P256())
78+ })
79+ t.Run("P384", func(t *testing.T) {
80+ testScalarMult(t, nistec.NewP384Point, elliptic.P384())
81+ })
82+ t.Run("P521", func(t *testing.T) {
83+ testScalarMult(t, nistec.NewP521Point, elliptic.P521())
84+ })
85+}
86+
87+func testScalarMult[P nistPoint[P]](t *testing.T, newPoint func() P, c elliptic.Curve) {
88+ G := newPoint().SetGenerator()
89+ checkScalar := func(t *testing.T, scalar []byte) {
90+ p1, err := newPoint().ScalarBaseMult(scalar)
91+ fatalIfErr(t, err)
92+ p2, err := newPoint().ScalarMult(G, scalar)
93+ fatalIfErr(t, err)
94+ if !bytes.Equal(p1.Bytes(), p2.Bytes()) {
95+ t.Error("[k]G != ScalarBaseMult(k)")
96+ }
97+
98+ d := new(big.Int).SetBytes(scalar)
99+ d.Sub(c.Params().N, d)
100+ d.Mod(d, c.Params().N)
101+ g1, err := newPoint().ScalarBaseMult(d.FillBytes(make([]byte, len(scalar))))
102+ fatalIfErr(t, err)
103+ g1.Add(g1, p1)
104+ if !bytes.Equal(g1.Bytes(), newPoint().Bytes()) {
105+ t.Error("[N - k]G + [k]G != ∞")
106+ }
107+ }
108+
109+ byteLen := len(c.Params().N.Bytes())
110+ bitLen := c.Params().N.BitLen()
111+ t.Run("0", func(t *testing.T) { checkScalar(t, make([]byte, byteLen)) })
112+ t.Run("1", func(t *testing.T) {
113+ checkScalar(t, big.NewInt(1).FillBytes(make([]byte, byteLen)))
114+ })
115+ t.Run("N-1", func(t *testing.T) {
116+ checkScalar(t, new(big.Int).Sub(c.Params().N, big.NewInt(1)).Bytes())
117+ })
118+ t.Run("N", func(t *testing.T) { checkScalar(t, c.Params().N.Bytes()) })
119+ t.Run("N+1", func(t *testing.T) {
120+ checkScalar(t, new(big.Int).Add(c.Params().N, big.NewInt(1)).Bytes())
121+ })
122+ t.Run("all1s", func(t *testing.T) {
123+ s := new(big.Int).Lsh(big.NewInt(1), uint(bitLen))
124+ s.Sub(s, big.NewInt(1))
125+ checkScalar(t, s.Bytes())
126+ })
127+ if testing.Short() {
128+ return
129+ }
130+ for i := 0; i < bitLen; i++ {
131+ t.Run(fmt.Sprintf("1<<%d", i), func(t *testing.T) {
132+ s := new(big.Int).Lsh(big.NewInt(1), uint(i))
133+ checkScalar(t, s.FillBytes(make([]byte, byteLen)))
134+ })
135+ }
136+ // Test N+1...N+32 since they risk overlapping with precomputed table values
137+ // in the final additions.
138+ for i := int64(2); i <= 32; i++ {
139+ t.Run(fmt.Sprintf("N+%d", i), func(t *testing.T) {
140+ checkScalar(t, new(big.Int).Add(c.Params().N, big.NewInt(i)).Bytes())
141+ })
142+ }
143+}
144+
145+func fatalIfErr(t *testing.T, err error) {
146+ t.Helper()
147+ if err != nil {
148+ t.Fatal(err)
149+ }
150+}
151+
152 func BenchmarkScalarMult(b *testing.B) {
153 b.Run("P224", func(b *testing.B) {
154 benchmarkScalarMult(b, nistec.NewP224Point().SetGenerator(), 28)
155diff --git a/src/crypto/internal/nistec/p256_asm.go b/src/crypto/internal/nistec/p256_asm.go
156index 6ea161eb49953..99a22b833f028 100644
157--- a/src/crypto/internal/nistec/p256_asm.go
158+++ b/src/crypto/internal/nistec/p256_asm.go
159@@ -364,6 +364,21 @@ func p256PointDoubleAsm(res, in *P256Point)
160 // Montgomery domain (with R 2²⁵⁶) as four uint64 limbs in little-endian order.
161 type p256OrdElement [4]uint64
162
163+// p256OrdReduce ensures s is in the range [0, ord(G)-1].
164+func p256OrdReduce(s *p256OrdElement) {
165+ // Since 2 * ord(G) > 2²⁵⁶, we can just conditionally subtract ord(G),
166+ // keeping the result if it doesn't underflow.
167+ t0, b := bits.Sub64(s[0], 0xf3b9cac2fc632551, 0)
168+ t1, b := bits.Sub64(s[1], 0xbce6faada7179e84, b)
169+ t2, b := bits.Sub64(s[2], 0xffffffffffffffff, b)
170+ t3, b := bits.Sub64(s[3], 0xffffffff00000000, b)
171+ tMask := b - 1 // zero if subtraction underflowed
172+ s[0] ^= (t0 ^ s[0]) & tMask
173+ s[1] ^= (t1 ^ s[1]) & tMask
174+ s[2] ^= (t2 ^ s[2]) & tMask
175+ s[3] ^= (t3 ^ s[3]) & tMask
176+}
177+
178 // Add sets q = p1 + p2, and returns q. The points may overlap.
179 func (q *P256Point) Add(r1, r2 *P256Point) *P256Point {
180 var sum, double P256Point
181@@ -393,6 +408,7 @@ func (r *P256Point) ScalarBaseMult(scalar []byte) (*P256Point, error) {
182 }
183 scalarReversed := new(p256OrdElement)
184 p256OrdBigToLittle(scalarReversed, (*[32]byte)(scalar))
185+ p256OrdReduce(scalarReversed)
186
187 r.p256BaseMult(scalarReversed)
188 return r, nil
189@@ -407,6 +423,7 @@ func (r *P256Point) ScalarMult(q *P256Point, scalar []byte) (*P256Point, error)
190 }
191 scalarReversed := new(p256OrdElement)
192 p256OrdBigToLittle(scalarReversed, (*[32]byte)(scalar))
193+ p256OrdReduce(scalarReversed)
194
195 r.Set(q).p256ScalarMult(scalarReversed)
196 return r, nil
197diff --git a/src/crypto/internal/nistec/p256_ordinv.go b/src/crypto/internal/nistec/p256_ordinv.go
198index 86a7a230bdce8..1274fb7fd3f5c 100644
199--- a/src/crypto/internal/nistec/p256_ordinv.go
200+++ b/src/crypto/internal/nistec/p256_ordinv.go
201@@ -25,6 +25,7 @@ func P256OrdInverse(k []byte) ([]byte, error) {
202
203 x := new(p256OrdElement)
204 p256OrdBigToLittle(x, (*[32]byte)(k))
205+ p256OrdReduce(x)
206
207 // Inversion is implemented as exponentiation by n - 2, per Fermat's little theorem.
208 //