CVE-2017-8932 (published 2017-07-06T16:29Z)

A bug in the standard library ScalarMult implementation of curve P-256 for amd64 architectures in Go before 1.7.6 and 1.8.x before 1.8.2 causes incorrect results to be generated for specific input points. An adaptive attack can be mounted to progressively extract the scalar input to ScalarMult by submitting crafted points and observing failures to the derive correct output. This leads to a full key recovery attack against static ECDH, as used in popular JWT libraries.

Severity: MEDIUM
CVSS v2 base score: 4.3 (AV:N/AC:M/Au:N/C:P/I:N/A:N)
CVSS v3 base score: 5.9, MEDIUM (CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N)

Weakness information:
cwe_id: CWE-682
cwe_name: Incorrect Calculation
description: The product performs a calculation that generates incorrect or unintended results that are later used in security-critical decisions or resource management.
extended_description: When product performs a security-critical calculation incorrectly, it might lead to incorrect resource allocations, incorrect privilege assignments, or failed comparisons among other things. Many of the direct results of an incorrect calculation can lead to even larger problems such as failed protection mechanisms or even arbitrary code execution.
         

Fix information:
repo_url: https://github.com/golang/go
commit_details: repo_url: https://github.com/golang/go
author: Adam Langley
author_date: 2017-04-19 10:00:32-07:00
msg: crypto/elliptic: fix carry bug in x86-64 P-256 implementation.

Patch from Vlad Krasnov and confirmed to be under CLA.

Fixes #20040.

Change-Id: Ieb8436c4dcb6669a1620f1e0d257efd047b1b87c
Reviewed-on: https://go-review.googlesource.com/41070
Run-TryBot: Adam Langley <agl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
repository: repo_url: https://github.com/golang/go
repo_name: golang/go
description: The Go programming language
repo_language: Go
owner: golang
file_changes: filename: elliptic_test.go
change_type: ModificationType.MODIFY
diff: @@ -300,6 +300,29 @@ 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 {
@@ -379,6 +402,19 @@ func TestP256Mult(t *testing.T) {
 			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) {

programming_language: Go
filename: p256_asm_amd64.s
change_type: ModificationType.MODIFY
diff: @@ -1314,12 +1314,12 @@ TEXT p256SubInternal(SB),NOSPLIT,$0
 	ADCQ p256const0<>(SB), acc5
 	ADCQ $0, acc6
 	ADCQ p256const1<>(SB), acc7
-	ADCQ $0, mul0
+	ANDQ $1, mul0
 
-	CMOVQNE acc0, acc4
-	CMOVQNE acc1, acc5
-	CMOVQNE acc2, acc6
-	CMOVQNE acc3, acc7
+	CMOVQEQ acc0, acc4
+	CMOVQEQ acc1, acc5
+	CMOVQEQ acc2, acc6
+	CMOVQEQ acc3, acc7
 
 	RET
 /* ---------------------------------------*/

programming_language: Go