321 lines
9.4 KiB
Diff
321 lines
9.4 KiB
Diff
|
From 28ffc15c56ac0edccb5b0147ff942127720ca083 Mon Sep 17 00:00:00 2001
|
|||
|
From: =?UTF-8?q?Alejandro=20S=C3=A1ez?= <asm@redhat.com>
|
|||
|
Date: Wed, 8 Jun 2022 19:27:19 +0200
|
|||
|
Subject: [PATCH] Backport CVE-2022-28327 fix from go1.17
|
|||
|
|
|||
|
---
|
|||
|
src/crypto/elliptic/elliptic_test.go | 92 ---------------
|
|||
|
src/crypto/elliptic/p256.go | 2 +-
|
|||
|
src/crypto/elliptic/p256_test.go | 169 +++++++++++++++++++++++++++
|
|||
|
3 files changed, 170 insertions(+), 93 deletions(-)
|
|||
|
create mode 100644 src/crypto/elliptic/p256_test.go
|
|||
|
|
|||
|
diff --git a/src/crypto/elliptic/elliptic_test.go b/src/crypto/elliptic/elliptic_test.go
|
|||
|
index bb16b0d163..516a321273 100644
|
|||
|
--- a/src/crypto/elliptic/elliptic_test.go
|
|||
|
+++ b/src/crypto/elliptic/elliptic_test.go
|
|||
|
@@ -301,29 +301,6 @@ var p224BaseMultTests = []baseMultTest{
|
|||
|
},
|
|||
|
}
|
|||
|
|
|||
|
-type scalarMultTest struct {
|
|||
|
- k string
|
|||
|
- xIn, yIn string
|
|||
|
- xOut, yOut string
|
|||
|
-}
|
|||
|
-
|
|||
|
-var p256MultTests = []scalarMultTest{
|
|||
|
- {
|
|||
|
- "2a265f8bcbdcaf94d58519141e578124cb40d64a501fba9c11847b28965bc737",
|
|||
|
- "023819813ac969847059028ea88a1f30dfbcde03fc791d3a252c6b41211882ea",
|
|||
|
- "f93e4ae433cc12cf2a43fc0ef26400c0e125508224cdb649380f25479148a4ad",
|
|||
|
- "4d4de80f1534850d261075997e3049321a0864082d24a917863366c0724f5ae3",
|
|||
|
- "a22d2b7f7818a3563e0f7a76c9bf0921ac55e06e2e4d11795b233824b1db8cc0",
|
|||
|
- },
|
|||
|
- {
|
|||
|
- "313f72ff9fe811bf573176231b286a3bdb6f1b14e05c40146590727a71c3bccd",
|
|||
|
- "cc11887b2d66cbae8f4d306627192522932146b42f01d3c6f92bd5c8ba739b06",
|
|||
|
- "a2f08a029cd06b46183085bae9248b0ed15b70280c7ef13a457f5af382426031",
|
|||
|
- "831c3f6b5f762d2f461901577af41354ac5f228c2591f84f8a6e51e2e3f17991",
|
|||
|
- "93f90934cd0ef2c698cc471c60a93524e87ab31ca2412252337f364513e43684",
|
|||
|
- },
|
|||
|
-}
|
|||
|
-
|
|||
|
func TestBaseMult(t *testing.T) {
|
|||
|
p224 := P224()
|
|||
|
for i, e := range p224BaseMultTests {
|
|||
|
@@ -359,65 +336,6 @@ func TestGenericBaseMult(t *testing.T) {
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
-func TestP256BaseMult(t *testing.T) {
|
|||
|
- p256 := P256()
|
|||
|
- p256Generic := p256.Params()
|
|||
|
-
|
|||
|
- scalars := make([]*big.Int, 0, len(p224BaseMultTests)+1)
|
|||
|
- for _, e := range p224BaseMultTests {
|
|||
|
- k, _ := new(big.Int).SetString(e.k, 10)
|
|||
|
- scalars = append(scalars, k)
|
|||
|
- }
|
|||
|
- k := new(big.Int).SetInt64(1)
|
|||
|
- k.Lsh(k, 500)
|
|||
|
- scalars = append(scalars, k)
|
|||
|
-
|
|||
|
- for i, k := range scalars {
|
|||
|
- x, y := p256.ScalarBaseMult(k.Bytes())
|
|||
|
- x2, y2 := p256Generic.ScalarBaseMult(k.Bytes())
|
|||
|
- if x.Cmp(x2) != 0 || y.Cmp(y2) != 0 {
|
|||
|
- t.Errorf("#%d: got (%x, %x), want (%x, %x)", i, x, y, x2, y2)
|
|||
|
- }
|
|||
|
-
|
|||
|
- if testing.Short() && i > 5 {
|
|||
|
- break
|
|||
|
- }
|
|||
|
- }
|
|||
|
-}
|
|||
|
-
|
|||
|
-func TestP256Mult(t *testing.T) {
|
|||
|
- p256 := P256()
|
|||
|
- p256Generic := p256.Params()
|
|||
|
-
|
|||
|
- for i, e := range p224BaseMultTests {
|
|||
|
- x, _ := new(big.Int).SetString(e.x, 16)
|
|||
|
- y, _ := new(big.Int).SetString(e.y, 16)
|
|||
|
- k, _ := new(big.Int).SetString(e.k, 10)
|
|||
|
-
|
|||
|
- xx, yy := p256.ScalarMult(x, y, k.Bytes())
|
|||
|
- xx2, yy2 := p256Generic.ScalarMult(x, y, k.Bytes())
|
|||
|
- if xx.Cmp(xx2) != 0 || yy.Cmp(yy2) != 0 {
|
|||
|
- t.Errorf("#%d: got (%x, %x), want (%x, %x)", i, xx, yy, xx2, yy2)
|
|||
|
- }
|
|||
|
- if testing.Short() && i > 5 {
|
|||
|
- break
|
|||
|
- }
|
|||
|
- }
|
|||
|
-
|
|||
|
- for i, e := range p256MultTests {
|
|||
|
- x, _ := new(big.Int).SetString(e.xIn, 16)
|
|||
|
- y, _ := new(big.Int).SetString(e.yIn, 16)
|
|||
|
- k, _ := new(big.Int).SetString(e.k, 16)
|
|||
|
- expectedX, _ := new(big.Int).SetString(e.xOut, 16)
|
|||
|
- expectedY, _ := new(big.Int).SetString(e.yOut, 16)
|
|||
|
-
|
|||
|
- xx, yy := p256.ScalarMult(x, y, k.Bytes())
|
|||
|
- if xx.Cmp(expectedX) != 0 || yy.Cmp(expectedY) != 0 {
|
|||
|
- t.Errorf("#%d: got (%x, %x), want (%x, %x)", i, xx, yy, expectedX, expectedY)
|
|||
|
- }
|
|||
|
- }
|
|||
|
-}
|
|||
|
-
|
|||
|
func testInfinity(t *testing.T, curve Curve) {
|
|||
|
_, x, y, _ := GenerateKey(curve, rand.Reader)
|
|||
|
x, y = curve.ScalarMult(x, y, curve.Params().N.Bytes())
|
|||
|
@@ -477,16 +395,6 @@ func TestInfinity(t *testing.T) {
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
-type synthCombinedMult struct {
|
|||
|
- Curve
|
|||
|
-}
|
|||
|
-
|
|||
|
-func (s synthCombinedMult) CombinedMult(bigX, bigY *big.Int, baseScalar, scalar []byte) (x, y *big.Int) {
|
|||
|
- x1, y1 := s.ScalarBaseMult(baseScalar)
|
|||
|
- x2, y2 := s.ScalarMult(bigX, bigY, scalar)
|
|||
|
- return s.Add(x1, y1, x2, y2)
|
|||
|
-}
|
|||
|
-
|
|||
|
func TestCombinedMult(t *testing.T) {
|
|||
|
type combinedMult interface {
|
|||
|
Curve
|
|||
|
diff --git a/src/crypto/elliptic/p256.go b/src/crypto/elliptic/p256.go
|
|||
|
index c23e414156..787e3e7444 100644
|
|||
|
--- a/src/crypto/elliptic/p256.go
|
|||
|
+++ b/src/crypto/elliptic/p256.go
|
|||
|
@@ -51,7 +51,7 @@ func p256GetScalar(out *[32]byte, in []byte) {
|
|||
|
n := new(big.Int).SetBytes(in)
|
|||
|
var scalarBytes []byte
|
|||
|
|
|||
|
- if n.Cmp(p256Params.N) >= 0 {
|
|||
|
+ if n.Cmp(p256Params.N) >= 0 || len(in) > len(out) {
|
|||
|
n.Mod(n, p256Params.N)
|
|||
|
scalarBytes = n.Bytes()
|
|||
|
} else {
|
|||
|
diff --git a/src/crypto/elliptic/p256_test.go b/src/crypto/elliptic/p256_test.go
|
|||
|
new file mode 100644
|
|||
|
index 0000000000..694186df81
|
|||
|
--- /dev/null
|
|||
|
+++ b/src/crypto/elliptic/p256_test.go
|
|||
|
@@ -0,0 +1,169 @@
|
|||
|
+// Copyright 2021 The Go Authors. All rights reserved.
|
|||
|
+// Use of this source code is governed by a BSD-style
|
|||
|
+// license that can be found in the LICENSE file.
|
|||
|
+
|
|||
|
+package elliptic
|
|||
|
+
|
|||
|
+import (
|
|||
|
+ "math/big"
|
|||
|
+ "testing"
|
|||
|
+)
|
|||
|
+
|
|||
|
+type scalarMultTest struct {
|
|||
|
+ k string
|
|||
|
+ xIn, yIn string
|
|||
|
+ xOut, yOut string
|
|||
|
+}
|
|||
|
+
|
|||
|
+var p256MultTests = []scalarMultTest{
|
|||
|
+ {
|
|||
|
+ "2a265f8bcbdcaf94d58519141e578124cb40d64a501fba9c11847b28965bc737",
|
|||
|
+ "023819813ac969847059028ea88a1f30dfbcde03fc791d3a252c6b41211882ea",
|
|||
|
+ "f93e4ae433cc12cf2a43fc0ef26400c0e125508224cdb649380f25479148a4ad",
|
|||
|
+ "4d4de80f1534850d261075997e3049321a0864082d24a917863366c0724f5ae3",
|
|||
|
+ "a22d2b7f7818a3563e0f7a76c9bf0921ac55e06e2e4d11795b233824b1db8cc0",
|
|||
|
+ },
|
|||
|
+ {
|
|||
|
+ "313f72ff9fe811bf573176231b286a3bdb6f1b14e05c40146590727a71c3bccd",
|
|||
|
+ "cc11887b2d66cbae8f4d306627192522932146b42f01d3c6f92bd5c8ba739b06",
|
|||
|
+ "a2f08a029cd06b46183085bae9248b0ed15b70280c7ef13a457f5af382426031",
|
|||
|
+ "831c3f6b5f762d2f461901577af41354ac5f228c2591f84f8a6e51e2e3f17991",
|
|||
|
+ "93f90934cd0ef2c698cc471c60a93524e87ab31ca2412252337f364513e43684",
|
|||
|
+ },
|
|||
|
+}
|
|||
|
+
|
|||
|
+func TestP256BaseMult(t *testing.T) {
|
|||
|
+ p256 := P256()
|
|||
|
+ p256Generic := p256.Params()
|
|||
|
+
|
|||
|
+ scalars := make([]*big.Int, 0, len(p224BaseMultTests)+1)
|
|||
|
+ for _, e := range p224BaseMultTests {
|
|||
|
+ k, _ := new(big.Int).SetString(e.k, 10)
|
|||
|
+ scalars = append(scalars, k)
|
|||
|
+ }
|
|||
|
+ k := new(big.Int).SetInt64(1)
|
|||
|
+ k.Lsh(k, 500)
|
|||
|
+ scalars = append(scalars, k)
|
|||
|
+
|
|||
|
+ for i, k := range scalars {
|
|||
|
+ x, y := p256.ScalarBaseMult(k.Bytes())
|
|||
|
+ x2, y2 := p256Generic.ScalarBaseMult(k.Bytes())
|
|||
|
+ if x.Cmp(x2) != 0 || y.Cmp(y2) != 0 {
|
|||
|
+ t.Errorf("#%d: got (%x, %x), want (%x, %x)", i, x, y, x2, y2)
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ if testing.Short() && i > 5 {
|
|||
|
+ break
|
|||
|
+ }
|
|||
|
+ }
|
|||
|
+}
|
|||
|
+
|
|||
|
+func TestP256Mult(t *testing.T) {
|
|||
|
+ p256 := P256()
|
|||
|
+ p256Generic := p256.Params()
|
|||
|
+
|
|||
|
+ for i, e := range p224BaseMultTests {
|
|||
|
+ x, _ := new(big.Int).SetString(e.x, 16)
|
|||
|
+ y, _ := new(big.Int).SetString(e.y, 16)
|
|||
|
+ k, _ := new(big.Int).SetString(e.k, 10)
|
|||
|
+
|
|||
|
+ xx, yy := p256.ScalarMult(x, y, k.Bytes())
|
|||
|
+ xx2, yy2 := p256Generic.ScalarMult(x, y, k.Bytes())
|
|||
|
+ if xx.Cmp(xx2) != 0 || yy.Cmp(yy2) != 0 {
|
|||
|
+ t.Errorf("#%d: got (%x, %x), want (%x, %x)", i, xx, yy, xx2, yy2)
|
|||
|
+ }
|
|||
|
+ if testing.Short() && i > 5 {
|
|||
|
+ break
|
|||
|
+ }
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ for i, e := range p256MultTests {
|
|||
|
+ x, _ := new(big.Int).SetString(e.xIn, 16)
|
|||
|
+ y, _ := new(big.Int).SetString(e.yIn, 16)
|
|||
|
+ k, _ := new(big.Int).SetString(e.k, 16)
|
|||
|
+ expectedX, _ := new(big.Int).SetString(e.xOut, 16)
|
|||
|
+ expectedY, _ := new(big.Int).SetString(e.yOut, 16)
|
|||
|
+
|
|||
|
+ xx, yy := p256.ScalarMult(x, y, k.Bytes())
|
|||
|
+ if xx.Cmp(expectedX) != 0 || yy.Cmp(expectedY) != 0 {
|
|||
|
+ t.Errorf("#%d: got (%x, %x), want (%x, %x)", i, xx, yy, expectedX, expectedY)
|
|||
|
+ }
|
|||
|
+ }
|
|||
|
+}
|
|||
|
+
|
|||
|
+type synthCombinedMult struct {
|
|||
|
+ Curve
|
|||
|
+}
|
|||
|
+
|
|||
|
+func (s synthCombinedMult) CombinedMult(bigX, bigY *big.Int, baseScalar, scalar []byte) (x, y *big.Int) {
|
|||
|
+ x1, y1 := s.ScalarBaseMult(baseScalar)
|
|||
|
+ x2, y2 := s.ScalarMult(bigX, bigY, scalar)
|
|||
|
+ return s.Add(x1, y1, x2, y2)
|
|||
|
+}
|
|||
|
+
|
|||
|
+func TestP256CombinedMult(t *testing.T) {
|
|||
|
+ type combinedMult interface {
|
|||
|
+ Curve
|
|||
|
+ CombinedMult(bigX, bigY *big.Int, baseScalar, scalar []byte) (x, y *big.Int)
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ p256, ok := P256().(combinedMult)
|
|||
|
+ if !ok {
|
|||
|
+ p256 = &synthCombinedMult{P256()}
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ gx := p256.Params().Gx
|
|||
|
+ gy := p256.Params().Gy
|
|||
|
+
|
|||
|
+ zero := make([]byte, 32)
|
|||
|
+ one := make([]byte, 32)
|
|||
|
+ one[31] = 1
|
|||
|
+ two := make([]byte, 32)
|
|||
|
+ two[31] = 2
|
|||
|
+
|
|||
|
+ // 0×G + 0×G = ∞
|
|||
|
+ x, y := p256.CombinedMult(gx, gy, zero, zero)
|
|||
|
+ if x.Sign() != 0 || y.Sign() != 0 {
|
|||
|
+ t.Errorf("0×G + 0×G = (%d, %d), should be ∞", x, y)
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ // 1×G + 0×G = G
|
|||
|
+ x, y = p256.CombinedMult(gx, gy, one, zero)
|
|||
|
+ if x.Cmp(gx) != 0 || y.Cmp(gy) != 0 {
|
|||
|
+ t.Errorf("1×G + 0×G = (%d, %d), should be (%d, %d)", x, y, gx, gy)
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ // 0×G + 1×G = G
|
|||
|
+ x, y = p256.CombinedMult(gx, gy, zero, one)
|
|||
|
+ if x.Cmp(gx) != 0 || y.Cmp(gy) != 0 {
|
|||
|
+ t.Errorf("0×G + 1×G = (%d, %d), should be (%d, %d)", x, y, gx, gy)
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ // 1×G + 1×G = 2×G
|
|||
|
+ x, y = p256.CombinedMult(gx, gy, one, one)
|
|||
|
+ ggx, ggy := p256.ScalarBaseMult(two)
|
|||
|
+ if x.Cmp(ggx) != 0 || y.Cmp(ggy) != 0 {
|
|||
|
+ t.Errorf("1×G + 1×G = (%d, %d), should be (%d, %d)", x, y, ggx, ggy)
|
|||
|
+ }
|
|||
|
+
|
|||
|
+ minusOne := new(big.Int).Sub(p256.Params().N, big.NewInt(1))
|
|||
|
+ // 1×G + (-1)×G = ∞
|
|||
|
+ x, y = p256.CombinedMult(gx, gy, one, minusOne.Bytes())
|
|||
|
+ if x.Sign() != 0 || y.Sign() != 0 {
|
|||
|
+ t.Errorf("1×G + (-1)×G = (%d, %d), should be ∞", x, y)
|
|||
|
+ }
|
|||
|
+}
|
|||
|
+
|
|||
|
+func TestIssue52075(t *testing.T) {
|
|||
|
+ Gx, Gy := P256().Params().Gx, P256().Params().Gy
|
|||
|
+ scalar := make([]byte, 33)
|
|||
|
+ scalar[32] = 1
|
|||
|
+ x, y := P256().ScalarBaseMult(scalar)
|
|||
|
+ if x.Cmp(Gx) != 0 || y.Cmp(Gy) != 0 {
|
|||
|
+ t.Errorf("unexpected output (%v,%v)", x, y)
|
|||
|
+ }
|
|||
|
+ x, y = P256().ScalarMult(Gx, Gy, scalar)
|
|||
|
+ if x.Cmp(Gx) != 0 || y.Cmp(Gy) != 0 {
|
|||
|
+ t.Errorf("unexpected output (%v,%v)", x, y)
|
|||
|
+ }
|
|||
|
+}
|
|||
|
--
|
|||
|
2.35.3
|
|||
|
|