Skip to content

Commit b7391e9

Browse files
committed
salsa20/salsa: fix keystream loop in amd64 assembly when overflowing 32-bit counter
Fixes golang/go#30965 Change-Id: I83a804d555c048e0124c35f95c9e611b2c5bdb01 Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/436856 Reviewed-by: Adam Langley <[email protected]> Reviewed-on: https://go-review.googlesource.com/c/crypto/+/168406 Reviewed-by: Filippo Valsorda <[email protected]> Run-TryBot: Filippo Valsorda <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent a1f597e commit b7391e9

File tree

5 files changed

+50
-15
lines changed

5 files changed

+50
-15
lines changed

Diff for: salsa20/salsa/salsa20_amd64.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@
66

77
package salsa
88

9-
// This function is implemented in salsa2020_amd64.s.
10-
119
//go:noescape
1210

11+
// salsa2020XORKeyStream is implemented in salsa20_amd64.s.
1312
func salsa2020XORKeyStream(out, in *byte, n uint64, nonce, key *byte)
1413

1514
// XORKeyStream crypts bytes from in to out using the given key and counters.

Diff for: salsa20/salsa/salsa2020_amd64.s renamed to salsa20/salsa/salsa20_amd64.s

+1-7
Original file line numberDiff line numberDiff line change
@@ -99,30 +99,24 @@ TEXT ·salsa2020XORKeyStream(SB),0,$456-40 // frame = 424 + 32 byte alignment
9999
MOVL 36 (SP),CX
100100
MOVL DX,288(SP)
101101
MOVL CX,304(SP)
102-
ADDQ $1,DX
103102
SHLQ $32,CX
104103
ADDQ CX,DX
104+
ADDQ $1,DX
105105
MOVQ DX,CX
106106
SHRQ $32,CX
107107
MOVL DX, 292 (SP)
108108
MOVL CX, 308 (SP)
109109
ADDQ $1,DX
110-
SHLQ $32,CX
111-
ADDQ CX,DX
112110
MOVQ DX,CX
113111
SHRQ $32,CX
114112
MOVL DX, 296 (SP)
115113
MOVL CX, 312 (SP)
116114
ADDQ $1,DX
117-
SHLQ $32,CX
118-
ADDQ CX,DX
119115
MOVQ DX,CX
120116
SHRQ $32,CX
121117
MOVL DX, 300 (SP)
122118
MOVL CX, 316 (SP)
123119
ADDQ $1,DX
124-
SHLQ $32,CX
125-
ADDQ CX,DX
126120
MOVQ DX,CX
127121
SHRQ $32,CX
128122
MOVL DX,16(SP)

Diff for: salsa20/salsa/salsa20_amd64_test.go

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2019 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
// +build amd64,!appengine,!gccgo
6+
7+
package salsa
8+
9+
import (
10+
"bytes"
11+
"testing"
12+
)
13+
14+
func TestCounterOverflow(t *testing.T) {
15+
in := make([]byte, 4096)
16+
key := &[32]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5,
17+
6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2}
18+
for n, counter := range []*[16]byte{
19+
&[16]byte{0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0}, // zero counter
20+
&[16]byte{0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff}, // counter about to overflow 32 bits
21+
&[16]byte{0, 1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 0xff, 0xff, 0xff, 0xff}, // counter above 32 bits
22+
} {
23+
out := make([]byte, 4096)
24+
XORKeyStream(out, in, counter, key)
25+
outGeneric := make([]byte, 4096)
26+
genericXORKeyStream(outGeneric, in, counter, key)
27+
if !bytes.Equal(out, outGeneric) {
28+
t.Errorf("%d: assembly and go implementations disagree", n)
29+
}
30+
}
31+
}

Diff for: salsa20/salsa/salsa20_noasm.go

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright 2019 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
// +build !amd64 appengine gccgo
6+
7+
package salsa
8+
9+
// XORKeyStream crypts bytes from in to out using the given key and counters.
10+
// In and out must overlap entirely or not at all. Counter
11+
// contains the raw salsa20 counter bytes (both nonce and block counter).
12+
func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
13+
genericXORKeyStream(out, in, counter, key)
14+
}

Diff for: salsa20/salsa/salsa20_ref.go

+3-6
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
// +build !amd64 appengine gccgo
6-
75
package salsa
86

97
const rounds = 20
@@ -202,10 +200,9 @@ func core(out *[64]byte, in *[16]byte, k *[32]byte, c *[16]byte) {
202200
out[63] = byte(x15 >> 24)
203201
}
204202

205-
// XORKeyStream crypts bytes from in to out using the given key and counters.
206-
// In and out must overlap entirely or not at all. Counter
207-
// contains the raw salsa20 counter bytes (both nonce and block counter).
208-
func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
203+
// genericXORKeyStream is the generic implementation of XORKeyStream to be used
204+
// when no assembly implementation is available.
205+
func genericXORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) {
209206
var block [64]byte
210207
var counterCopy [16]byte
211208
copy(counterCopy[:], counter[:])

0 commit comments

Comments
 (0)