Skip to content

Commit 73aaa40

Browse files
committed
crypto/internal/fips140/subtle: re-add assembly implementation of xorBytes for mipsx
This CL reapplies CL 666275 , and fixes the previous implementation's unaligned access and panic on mipsx. Updates #74998 Change-Id: I26cd3fdeb54419407bdc0a2f9616924e2e825bc3 Reviewed-on: https://go-review.googlesource.com/c/go/+/696076 Reviewed-by: Keith Randall <khr@google.com> LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
1 parent a28f000 commit 73aaa40

3 files changed

Lines changed: 250 additions & 1 deletion

File tree

src/crypto/internal/fips140/subtle/xor_generic.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
//go:build (!amd64 && !arm64 && !loong64 && !ppc64 && !ppc64le && !riscv64) || purego
5+
//go:build (!amd64 && !arm64 && !loong64 && !mips && !mipsle && !ppc64 && !ppc64le && !riscv64) || purego
66

77
package subtle
88

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright 2025 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+
//go:build (mips || mipsle) && !purego
6+
7+
package subtle
8+
9+
import (
10+
"unsafe"
11+
)
12+
13+
const wordSize = unsafe.Sizeof(uintptr(0))
14+
15+
// dst,a,b,n, all be wordSize aligned, and n must be > 0 and a multiple of wordSize
16+
//
17+
//go:noescape
18+
func xorBytesAligned(dst, a, b *byte, n int)
19+
20+
func xorBytes(dstb, xb, yb *byte, n int) {
21+
xp := uintptr(unsafe.Pointer(xb)) % wordSize
22+
yp := uintptr(unsafe.Pointer(yb)) % wordSize
23+
dp := uintptr(unsafe.Pointer(dstb)) % wordSize
24+
if xp != yp || xp != dp {
25+
dst := unsafe.Slice(dstb, n)
26+
x := unsafe.Slice(xb, n)
27+
y := unsafe.Slice(yb, n)
28+
xorLoop(dst, x, y)
29+
return
30+
}
31+
for (uintptr(unsafe.Pointer(dstb))%wordSize) != 0 && n > 0 {
32+
*dstb = *xb ^ *yb
33+
dstb = (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(dstb)) + 1))
34+
xb = (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(xb)) + 1))
35+
yb = (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(yb)) + 1))
36+
n--
37+
}
38+
alignedN := n & -int(wordSize)
39+
if alignedN > 0 {
40+
xorBytesAligned(dstb, xb, yb, alignedN)
41+
dstb = (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(dstb)) + uintptr(alignedN)))
42+
xb = (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(xb)) + uintptr(alignedN)))
43+
yb = (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(yb)) + uintptr(alignedN)))
44+
n -= alignedN
45+
}
46+
for n > 0 {
47+
*dstb = *xb ^ *yb
48+
dstb = (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(dstb)) + 1))
49+
xb = (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(xb)) + 1))
50+
yb = (*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(yb)) + 1))
51+
n--
52+
}
53+
}
54+
55+
func xorLoop[T byte | uintptr](dst, x, y []T) {
56+
x = x[:len(dst)] // remove bounds check in loop
57+
y = y[:len(dst)] // remove bounds check in loop
58+
for i := range dst {
59+
dst[i] = x[i] ^ y[i]
60+
}
61+
}
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
// Copyright 2025 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+
//go:build (mips || mipsle) && !purego
6+
7+
#include "textflag.h"
8+
9+
// func xorBytesAligned(dst, a, b *byte, n int)
10+
TEXT ·xorBytesAligned(SB), NOSPLIT|NOFRAME, $0
11+
MOVW dst+0(FP), R1
12+
MOVW a+4(FP), R2
13+
MOVW b+8(FP), R3
14+
MOVW n+12(FP), R4
15+
16+
SGTU $64, R4, R5 // R5 = 1 if (64 > R4)
17+
BNE R5, xor_32_check
18+
xor_64:
19+
MOVW (R2), R6
20+
MOVW 4(R2), R7
21+
MOVW 8(R2), R8
22+
MOVW 12(R2), R9
23+
MOVW (R3), R10
24+
MOVW 4(R3), R11
25+
MOVW 8(R3), R12
26+
MOVW 12(R3), R13
27+
XOR R6, R10
28+
XOR R7, R11
29+
XOR R8, R12
30+
XOR R9, R13
31+
MOVW R10, (R1)
32+
MOVW R11, 4(R1)
33+
MOVW R12, 8(R1)
34+
MOVW R13, 12(R1)
35+
MOVW 16(R2), R6
36+
MOVW 20(R2), R7
37+
MOVW 24(R2), R8
38+
MOVW 28(R2), R9
39+
MOVW 16(R3), R10
40+
MOVW 20(R3), R11
41+
MOVW 24(R3), R12
42+
MOVW 28(R3), R13
43+
XOR R6, R10
44+
XOR R7, R11
45+
XOR R8, R12
46+
XOR R9, R13
47+
MOVW R10, 16(R1)
48+
MOVW R11, 20(R1)
49+
MOVW R12, 24(R1)
50+
MOVW R13, 28(R1)
51+
MOVW 32(R2), R6
52+
MOVW 36(R2), R7
53+
MOVW 40(R2), R8
54+
MOVW 44(R2), R9
55+
MOVW 32(R3), R10
56+
MOVW 36(R3), R11
57+
MOVW 40(R3), R12
58+
MOVW 44(R3), R13
59+
XOR R6, R10
60+
XOR R7, R11
61+
XOR R8, R12
62+
XOR R9, R13
63+
MOVW R10, 32(R1)
64+
MOVW R11, 36(R1)
65+
MOVW R12, 40(R1)
66+
MOVW R13, 44(R1)
67+
MOVW 48(R2), R6
68+
MOVW 52(R2), R7
69+
MOVW 56(R2), R8
70+
MOVW 60(R2), R9
71+
MOVW 48(R3), R10
72+
MOVW 52(R3), R11
73+
MOVW 56(R3), R12
74+
MOVW 60(R3), R13
75+
XOR R6, R10
76+
XOR R7, R11
77+
XOR R8, R12
78+
XOR R9, R13
79+
MOVW R10, 48(R1)
80+
MOVW R11, 52(R1)
81+
MOVW R12, 56(R1)
82+
MOVW R13, 60(R1)
83+
ADD $64, R2
84+
ADD $64, R3
85+
ADD $64, R1
86+
SUB $64, R4
87+
SGTU $64, R4, R5
88+
BEQ R5, xor_64
89+
BEQ R4, end
90+
91+
xor_32_check:
92+
SGTU $32, R4, R5
93+
BNE R5, xor_16_check
94+
xor_32:
95+
MOVW (R2), R6
96+
MOVW 4(R2), R7
97+
MOVW 8(R2), R8
98+
MOVW 12(R2), R9
99+
MOVW (R3), R10
100+
MOVW 4(R3), R11
101+
MOVW 8(R3), R12
102+
MOVW 12(R3), R13
103+
XOR R6, R10
104+
XOR R7, R11
105+
XOR R8, R12
106+
XOR R9, R13
107+
MOVW R10, (R1)
108+
MOVW R11, 4(R1)
109+
MOVW R12, 8(R1)
110+
MOVW R13, 12(R1)
111+
MOVW 16(R2), R6
112+
MOVW 20(R2), R7
113+
MOVW 24(R2), R8
114+
MOVW 28(R2), R9
115+
MOVW 16(R3), R10
116+
MOVW 20(R3), R11
117+
MOVW 24(R3), R12
118+
MOVW 28(R3), R13
119+
XOR R6, R10
120+
XOR R7, R11
121+
XOR R8, R12
122+
XOR R9, R13
123+
MOVW R10, 16(R1)
124+
MOVW R11, 20(R1)
125+
MOVW R12, 24(R1)
126+
MOVW R13, 28(R1)
127+
ADD $32, R2
128+
ADD $32, R3
129+
ADD $32, R1
130+
SUB $32, R4
131+
BEQ R4, end
132+
133+
xor_16_check:
134+
SGTU $16, R4, R5
135+
BNE R5, xor_8_check
136+
xor_16:
137+
MOVW (R2), R6
138+
MOVW 4(R2), R7
139+
MOVW 8(R2), R8
140+
MOVW 12(R2), R9
141+
MOVW (R3), R10
142+
MOVW 4(R3), R11
143+
MOVW 8(R3), R12
144+
MOVW 12(R3), R13
145+
XOR R6, R10
146+
XOR R7, R11
147+
XOR R8, R12
148+
XOR R9, R13
149+
MOVW R10, (R1)
150+
MOVW R11, 4(R1)
151+
MOVW R12, 8(R1)
152+
MOVW R13, 12(R1)
153+
ADD $16, R2
154+
ADD $16, R3
155+
ADD $16, R1
156+
SUB $16, R4
157+
BEQ R4, end
158+
159+
xor_8_check:
160+
SGTU $8, R4, R5
161+
BNE R5, xor_4
162+
xor_8:
163+
MOVW (R2), R6
164+
MOVW 4(R2), R7
165+
MOVW (R3), R8
166+
MOVW 4(R3), R9
167+
XOR R6, R8
168+
XOR R7, R9
169+
MOVW R8, (R1)
170+
MOVW R9, 4(R1)
171+
ADD $8, R1
172+
ADD $8, R2
173+
ADD $8, R3
174+
SUB $8, R4
175+
BEQ R4, end
176+
177+
xor_4:
178+
MOVW (R2), R6
179+
MOVW (R3), R7
180+
XOR R6, R7
181+
MOVW R7, (R1)
182+
ADD $4, R2
183+
ADD $4, R3
184+
ADD $4, R1
185+
SUB $4, R4
186+
187+
end:
188+
RET

0 commit comments

Comments
 (0)