diff options
| author | Paul E. Murphy <murp@ibm.com> | 2024-08-27 14:44:16 -0500 |
|---|---|---|
| committer | Paul Murphy <murp@ibm.com> | 2024-09-23 18:27:32 +0000 |
| commit | bc047b62b2ec0c6eae3437a26410039c82365f60 (patch) | |
| tree | 8ee74fd287d91309ef5478ec3eba43f7990823db /src/crypto/internal | |
| parent | a92c80eb40e72385257fc714143e0278e110aa1a (diff) | |
| download | go-bc047b62b2ec0c6eae3437a26410039c82365f60.tar.xz | |
crypto/internal/nistec: fix p256Select (PPC64) and p256SelectAffine (PPC64/s390x)
They are constant time, but some constants were incorrect. This
resulting in reading beyond the tables.
I've added linux specific tests which verify these functions are not
reading beyond the limits of their table.
Thank you Sun Yimin, @emmansun for catching this bug and suggesting
corrected constants.
Fixes #69080
Cq-Include-Trybots: luci.golang.try:gotip-linux-ppc64_power10,gotip-linux-ppc64_power8,gotip-linux-ppc64le_power10,gotip-linux-ppc64le_power8,gotip-linux-ppc64le_power9
Change-Id: Id37e0e22b2278ea20adaa1c84cbb32c3f20d4cf7
Reviewed-on: https://go-review.googlesource.com/c/go/+/608816
Run-TryBot: Paul Murphy <murp@ibm.com>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Archana Ravindar <aravinda@redhat.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src/crypto/internal')
| -rw-r--r-- | src/crypto/internal/nistec/p256_asm_ppc64le.s | 4 | ||||
| -rw-r--r-- | src/crypto/internal/nistec/p256_asm_s390x.s | 2 | ||||
| -rw-r--r-- | src/crypto/internal/nistec/p256_asm_test.go | 53 |
3 files changed, 56 insertions, 3 deletions
diff --git a/src/crypto/internal/nistec/p256_asm_ppc64le.s b/src/crypto/internal/nistec/p256_asm_ppc64le.s index 1475dfb1d9..a21e638662 100644 --- a/src/crypto/internal/nistec/p256_asm_ppc64le.s +++ b/src/crypto/internal/nistec/p256_asm_ppc64le.s @@ -291,7 +291,7 @@ TEXT ·p256Select(SB), NOSPLIT, $0-24 VSPLTB $7, SEL1, IDX // splat byte VSPLTISB $1, ONE // VREPIB $1, ONE VSPLTISB $1, SEL2 // VREPIB $1, SEL2 - MOVD $17, COUNT + MOVD $16, COUNT // len(p256Table) MOVD COUNT, CTR // set up ctr VSPLTISB $0, X1H // VZERO X1H @@ -441,7 +441,7 @@ TEXT ·p256SelectAffine(SB), NOSPLIT, $0-24 VSPLTISB $1, ONE // Vector with byte 1s VSPLTISB $1, SEL2 // Vector with byte 1s - MOVD $64, COUNT + MOVD $32, COUNT // len(p256AffineTable) MOVD COUNT, CTR // loop count VSPLTISB $0, X1H // VZERO X1H diff --git a/src/crypto/internal/nistec/p256_asm_s390x.s b/src/crypto/internal/nistec/p256_asm_s390x.s index 77c9f63349..6ff4cb3f5f 100644 --- a/src/crypto/internal/nistec/p256_asm_s390x.s +++ b/src/crypto/internal/nistec/p256_asm_s390x.s @@ -508,7 +508,7 @@ loop_select: VAB SEL2, ONE, SEL2 ADDW $1, COUNT ADD $64, P1ptr - CMPW COUNT, $65 + CMPW COUNT, $33 // len(p256AffineTable) + 1 BLT loop_select VST X1H, 0(P3ptr) VST X1L, 16(P3ptr) diff --git a/src/crypto/internal/nistec/p256_asm_test.go b/src/crypto/internal/nistec/p256_asm_test.go new file mode 100644 index 0000000000..71edb9575c --- /dev/null +++ b/src/crypto/internal/nistec/p256_asm_test.go @@ -0,0 +1,53 @@ +// Copyright 2024 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. + +//go:build (amd64 || arm64 || ppc64le || s390x) && !purego && linux + +package nistec + +import ( + "syscall" + "testing" + "unsafe" +) + +// Lightly adapted from the bytes test package. Allocate a pair of T one at the start of a page, another at the +// end. Any access beyond or before the page boundary should cause a fault. This is linux specific. +func dangerousObjs[T any](t *testing.T) (start *T, end *T) { + pagesize := syscall.Getpagesize() + b, err := syscall.Mmap(0, 0, 3*pagesize, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_ANONYMOUS|syscall.MAP_PRIVATE) + if err != nil { + t.Fatalf("mmap failed %s", err) + } + err = syscall.Mprotect(b[:pagesize], syscall.PROT_NONE) + if err != nil { + t.Fatalf("mprotect low failed %s\n", err) + } + err = syscall.Mprotect(b[2*pagesize:], syscall.PROT_NONE) + if err != nil { + t.Fatalf("mprotect high failed %s\n", err) + } + b = b[pagesize : 2*pagesize] + end = (*T)(unsafe.Pointer(&b[len(b)-(int)(unsafe.Sizeof(*end))])) + start = (*T)(unsafe.Pointer(&b[0])) + return start, end +} + +func TestP256SelectAffinePageBoundary(t *testing.T) { + var out p256AffinePoint + begintp, endtp := dangerousObjs[p256AffineTable](t) + for i := 0; i < 31; i++ { + p256SelectAffine(&out, begintp, i) + p256SelectAffine(&out, endtp, i) + } +} + +func TestP256SelectPageBoundary(t *testing.T) { + var out P256Point + begintp, endtp := dangerousObjs[p256Table](t) + for i := 0; i < 15; i++ { + p256Select(&out, begintp, i) + p256Select(&out, endtp, i) + } +} |
