mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
crypto/internal/constanttime: expose intrinsics to the FIPS 140-3 packages
Intrinsifying things inside the module (crypto/internal/fips140/subtle) is asking for trouble, as the import paths are rewritten by the GOFIPS140 mechanism, and we might have to support multiple modules in the future. Importing crypto/subtle from inside a FIPS 140-3 module is not allowed, and is basically asking for circular dependencies. Instead, break off the intrinsics into their own package (crypto/internal/constanttime), and keep the byte slice operations in crypto/internal/fips140/subtle. crypto/subtle then becomes a thin dispatch layer. Change-Id: I6a6a6964cd5cb5ad06e9d1679201447f5a811da4 Reviewed-on: https://go-review.googlesource.com/c/go/+/716120 Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Keith Randall <khr@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Filippo Valsorda <filippo@golang.org> Reviewed-by: Jorropo <jorropo.pgm@gmail.com>
This commit is contained in:
parent
388c41c412
commit
00ee1860ce
14 changed files with 110 additions and 100 deletions
|
|
@ -1603,10 +1603,10 @@ func initIntrinsics(cfg *intrinsicBuildConfig) {
|
||||||
},
|
},
|
||||||
sys.AMD64)
|
sys.AMD64)
|
||||||
|
|
||||||
/******** crypto/subtle ********/
|
/******** crypto/internal/constanttime ********/
|
||||||
// We implement a superset of the ConstantTimeSelect promise:
|
// We implement a superset of the Select promise:
|
||||||
// ConstantTimeSelect returns x if v != 0 and y if v == 0.
|
// Select returns x if v != 0 and y if v == 0.
|
||||||
add("crypto/subtle", "ConstantTimeSelect",
|
add("crypto/internal/constanttime", "Select",
|
||||||
func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
|
func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
|
||||||
v, x, y := args[0], args[1], args[2]
|
v, x, y := args[0], args[1], args[2]
|
||||||
|
|
||||||
|
|
@ -1627,7 +1627,7 @@ func initIntrinsics(cfg *intrinsicBuildConfig) {
|
||||||
return s.newValue3(ssa.OpCondSelect, types.Types[types.TINT], x, y, check)
|
return s.newValue3(ssa.OpCondSelect, types.Types[types.TINT], x, y, check)
|
||||||
},
|
},
|
||||||
sys.ArchAMD64, sys.ArchARM64, sys.ArchLoong64, sys.ArchPPC64, sys.ArchPPC64LE, sys.ArchWasm) // all with CMOV support.
|
sys.ArchAMD64, sys.ArchARM64, sys.ArchLoong64, sys.ArchPPC64, sys.ArchPPC64LE, sys.ArchWasm) // all with CMOV support.
|
||||||
add("crypto/subtle", "constantTimeBoolToUint8",
|
add("crypto/internal/constanttime", "boolToUint8",
|
||||||
func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
|
func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
|
||||||
return s.newValue1(ssa.OpCvtBoolToUint8, types.Types[types.TUINT8], args[0])
|
return s.newValue1(ssa.OpCvtBoolToUint8, types.Types[types.TUINT8], args[0])
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ var wantIntrinsics = map[testIntrinsicKey]struct{}{
|
||||||
{"386", "math/bits", "TrailingZeros8"}: struct{}{},
|
{"386", "math/bits", "TrailingZeros8"}: struct{}{},
|
||||||
{"386", "runtime", "KeepAlive"}: struct{}{},
|
{"386", "runtime", "KeepAlive"}: struct{}{},
|
||||||
{"386", "runtime", "slicebytetostringtmp"}: struct{}{},
|
{"386", "runtime", "slicebytetostringtmp"}: struct{}{},
|
||||||
{"386", "crypto/subtle", "constantTimeBoolToUint8"}: struct{}{},
|
{"386", "crypto/internal/constanttime", "boolToUint8"}: struct{}{},
|
||||||
{"amd64", "internal/runtime/atomic", "And"}: struct{}{},
|
{"amd64", "internal/runtime/atomic", "And"}: struct{}{},
|
||||||
{"amd64", "internal/runtime/atomic", "And32"}: struct{}{},
|
{"amd64", "internal/runtime/atomic", "And32"}: struct{}{},
|
||||||
{"amd64", "internal/runtime/atomic", "And64"}: struct{}{},
|
{"amd64", "internal/runtime/atomic", "And64"}: struct{}{},
|
||||||
|
|
@ -189,8 +189,8 @@ var wantIntrinsics = map[testIntrinsicKey]struct{}{
|
||||||
{"amd64", "sync/atomic", "SwapUint32"}: struct{}{},
|
{"amd64", "sync/atomic", "SwapUint32"}: struct{}{},
|
||||||
{"amd64", "sync/atomic", "SwapUint64"}: struct{}{},
|
{"amd64", "sync/atomic", "SwapUint64"}: struct{}{},
|
||||||
{"amd64", "sync/atomic", "SwapUintptr"}: struct{}{},
|
{"amd64", "sync/atomic", "SwapUintptr"}: struct{}{},
|
||||||
{"amd64", "crypto/subtle", "ConstantTimeSelect"}: struct{}{},
|
{"amd64", "crypto/internal/constanttime", "Select"}: struct{}{},
|
||||||
{"amd64", "crypto/subtle", "constantTimeBoolToUint8"}: struct{}{},
|
{"amd64", "crypto/internal/constanttime", "boolToUint8"}: struct{}{},
|
||||||
{"arm", "internal/runtime/sys", "Bswap32"}: struct{}{},
|
{"arm", "internal/runtime/sys", "Bswap32"}: struct{}{},
|
||||||
{"arm", "internal/runtime/sys", "Bswap64"}: struct{}{},
|
{"arm", "internal/runtime/sys", "Bswap64"}: struct{}{},
|
||||||
{"arm", "internal/runtime/sys", "GetCallerPC"}: struct{}{},
|
{"arm", "internal/runtime/sys", "GetCallerPC"}: struct{}{},
|
||||||
|
|
@ -219,7 +219,7 @@ var wantIntrinsics = map[testIntrinsicKey]struct{}{
|
||||||
{"arm", "math/bits", "TrailingZeros8"}: struct{}{},
|
{"arm", "math/bits", "TrailingZeros8"}: struct{}{},
|
||||||
{"arm", "runtime", "KeepAlive"}: struct{}{},
|
{"arm", "runtime", "KeepAlive"}: struct{}{},
|
||||||
{"arm", "runtime", "slicebytetostringtmp"}: struct{}{},
|
{"arm", "runtime", "slicebytetostringtmp"}: struct{}{},
|
||||||
{"arm", "crypto/subtle", "constantTimeBoolToUint8"}: struct{}{},
|
{"arm", "crypto/internal/constanttime", "boolToUint8"}: struct{}{},
|
||||||
{"arm64", "internal/runtime/atomic", "And"}: struct{}{},
|
{"arm64", "internal/runtime/atomic", "And"}: struct{}{},
|
||||||
{"arm64", "internal/runtime/atomic", "And32"}: struct{}{},
|
{"arm64", "internal/runtime/atomic", "And32"}: struct{}{},
|
||||||
{"arm64", "internal/runtime/atomic", "And64"}: struct{}{},
|
{"arm64", "internal/runtime/atomic", "And64"}: struct{}{},
|
||||||
|
|
@ -364,8 +364,8 @@ var wantIntrinsics = map[testIntrinsicKey]struct{}{
|
||||||
{"arm64", "sync/atomic", "SwapUint32"}: struct{}{},
|
{"arm64", "sync/atomic", "SwapUint32"}: struct{}{},
|
||||||
{"arm64", "sync/atomic", "SwapUint64"}: struct{}{},
|
{"arm64", "sync/atomic", "SwapUint64"}: struct{}{},
|
||||||
{"arm64", "sync/atomic", "SwapUintptr"}: struct{}{},
|
{"arm64", "sync/atomic", "SwapUintptr"}: struct{}{},
|
||||||
{"arm64", "crypto/subtle", "ConstantTimeSelect"}: struct{}{},
|
{"arm64", "crypto/internal/constanttime", "Select"}: struct{}{},
|
||||||
{"arm64", "crypto/subtle", "constantTimeBoolToUint8"}: struct{}{},
|
{"arm64", "crypto/internal/constanttime", "boolToUint8"}: struct{}{},
|
||||||
{"loong64", "internal/runtime/atomic", "And"}: struct{}{},
|
{"loong64", "internal/runtime/atomic", "And"}: struct{}{},
|
||||||
{"loong64", "internal/runtime/atomic", "And32"}: struct{}{},
|
{"loong64", "internal/runtime/atomic", "And32"}: struct{}{},
|
||||||
{"loong64", "internal/runtime/atomic", "And64"}: struct{}{},
|
{"loong64", "internal/runtime/atomic", "And64"}: struct{}{},
|
||||||
|
|
@ -512,8 +512,8 @@ var wantIntrinsics = map[testIntrinsicKey]struct{}{
|
||||||
{"loong64", "sync/atomic", "SwapUint32"}: struct{}{},
|
{"loong64", "sync/atomic", "SwapUint32"}: struct{}{},
|
||||||
{"loong64", "sync/atomic", "SwapUint64"}: struct{}{},
|
{"loong64", "sync/atomic", "SwapUint64"}: struct{}{},
|
||||||
{"loong64", "sync/atomic", "SwapUintptr"}: struct{}{},
|
{"loong64", "sync/atomic", "SwapUintptr"}: struct{}{},
|
||||||
{"loong64", "crypto/subtle", "ConstantTimeSelect"}: struct{}{},
|
{"loong64", "crypto/internal/constanttime", "Select"}: struct{}{},
|
||||||
{"loong64", "crypto/subtle", "constantTimeBoolToUint8"}: struct{}{},
|
{"loong64", "crypto/internal/constanttime", "boolToUint8"}: struct{}{},
|
||||||
{"mips", "internal/runtime/atomic", "And"}: struct{}{},
|
{"mips", "internal/runtime/atomic", "And"}: struct{}{},
|
||||||
{"mips", "internal/runtime/atomic", "And8"}: struct{}{},
|
{"mips", "internal/runtime/atomic", "And8"}: struct{}{},
|
||||||
{"mips", "internal/runtime/atomic", "Cas"}: struct{}{},
|
{"mips", "internal/runtime/atomic", "Cas"}: struct{}{},
|
||||||
|
|
@ -585,7 +585,7 @@ var wantIntrinsics = map[testIntrinsicKey]struct{}{
|
||||||
{"mips", "sync/atomic", "SwapInt32"}: struct{}{},
|
{"mips", "sync/atomic", "SwapInt32"}: struct{}{},
|
||||||
{"mips", "sync/atomic", "SwapUint32"}: struct{}{},
|
{"mips", "sync/atomic", "SwapUint32"}: struct{}{},
|
||||||
{"mips", "sync/atomic", "SwapUintptr"}: struct{}{},
|
{"mips", "sync/atomic", "SwapUintptr"}: struct{}{},
|
||||||
{"mips", "crypto/subtle", "constantTimeBoolToUint8"}: struct{}{},
|
{"mips", "crypto/internal/constanttime", "boolToUint8"}: struct{}{},
|
||||||
{"mips64", "internal/runtime/atomic", "And"}: struct{}{},
|
{"mips64", "internal/runtime/atomic", "And"}: struct{}{},
|
||||||
{"mips64", "internal/runtime/atomic", "And8"}: struct{}{},
|
{"mips64", "internal/runtime/atomic", "And8"}: struct{}{},
|
||||||
{"mips64", "internal/runtime/atomic", "Cas"}: struct{}{},
|
{"mips64", "internal/runtime/atomic", "Cas"}: struct{}{},
|
||||||
|
|
@ -674,7 +674,7 @@ var wantIntrinsics = map[testIntrinsicKey]struct{}{
|
||||||
{"mips64", "sync/atomic", "SwapUint32"}: struct{}{},
|
{"mips64", "sync/atomic", "SwapUint32"}: struct{}{},
|
||||||
{"mips64", "sync/atomic", "SwapUint64"}: struct{}{},
|
{"mips64", "sync/atomic", "SwapUint64"}: struct{}{},
|
||||||
{"mips64", "sync/atomic", "SwapUintptr"}: struct{}{},
|
{"mips64", "sync/atomic", "SwapUintptr"}: struct{}{},
|
||||||
{"mips64", "crypto/subtle", "constantTimeBoolToUint8"}: struct{}{},
|
{"mips64", "crypto/internal/constanttime", "boolToUint8"}: struct{}{},
|
||||||
{"mips64le", "internal/runtime/atomic", "And"}: struct{}{},
|
{"mips64le", "internal/runtime/atomic", "And"}: struct{}{},
|
||||||
{"mips64le", "internal/runtime/atomic", "And8"}: struct{}{},
|
{"mips64le", "internal/runtime/atomic", "And8"}: struct{}{},
|
||||||
{"mips64le", "internal/runtime/atomic", "Cas"}: struct{}{},
|
{"mips64le", "internal/runtime/atomic", "Cas"}: struct{}{},
|
||||||
|
|
@ -763,7 +763,7 @@ var wantIntrinsics = map[testIntrinsicKey]struct{}{
|
||||||
{"mips64le", "sync/atomic", "SwapUint32"}: struct{}{},
|
{"mips64le", "sync/atomic", "SwapUint32"}: struct{}{},
|
||||||
{"mips64le", "sync/atomic", "SwapUint64"}: struct{}{},
|
{"mips64le", "sync/atomic", "SwapUint64"}: struct{}{},
|
||||||
{"mips64le", "sync/atomic", "SwapUintptr"}: struct{}{},
|
{"mips64le", "sync/atomic", "SwapUintptr"}: struct{}{},
|
||||||
{"mips64le", "crypto/subtle", "constantTimeBoolToUint8"}: struct{}{},
|
{"mips64le", "crypto/internal/constanttime", "boolToUint8"}: struct{}{},
|
||||||
{"mipsle", "internal/runtime/atomic", "And"}: struct{}{},
|
{"mipsle", "internal/runtime/atomic", "And"}: struct{}{},
|
||||||
{"mipsle", "internal/runtime/atomic", "And8"}: struct{}{},
|
{"mipsle", "internal/runtime/atomic", "And8"}: struct{}{},
|
||||||
{"mipsle", "internal/runtime/atomic", "Cas"}: struct{}{},
|
{"mipsle", "internal/runtime/atomic", "Cas"}: struct{}{},
|
||||||
|
|
@ -835,7 +835,7 @@ var wantIntrinsics = map[testIntrinsicKey]struct{}{
|
||||||
{"mipsle", "sync/atomic", "SwapInt32"}: struct{}{},
|
{"mipsle", "sync/atomic", "SwapInt32"}: struct{}{},
|
||||||
{"mipsle", "sync/atomic", "SwapUint32"}: struct{}{},
|
{"mipsle", "sync/atomic", "SwapUint32"}: struct{}{},
|
||||||
{"mipsle", "sync/atomic", "SwapUintptr"}: struct{}{},
|
{"mipsle", "sync/atomic", "SwapUintptr"}: struct{}{},
|
||||||
{"mipsle", "crypto/subtle", "constantTimeBoolToUint8"}: struct{}{},
|
{"mipsle", "crypto/internal/constanttime", "boolToUint8"}: struct{}{},
|
||||||
{"ppc64", "internal/runtime/atomic", "And"}: struct{}{},
|
{"ppc64", "internal/runtime/atomic", "And"}: struct{}{},
|
||||||
{"ppc64", "internal/runtime/atomic", "And8"}: struct{}{},
|
{"ppc64", "internal/runtime/atomic", "And8"}: struct{}{},
|
||||||
{"ppc64", "internal/runtime/atomic", "Cas"}: struct{}{},
|
{"ppc64", "internal/runtime/atomic", "Cas"}: struct{}{},
|
||||||
|
|
@ -960,8 +960,8 @@ var wantIntrinsics = map[testIntrinsicKey]struct{}{
|
||||||
{"ppc64", "sync/atomic", "SwapUint32"}: struct{}{},
|
{"ppc64", "sync/atomic", "SwapUint32"}: struct{}{},
|
||||||
{"ppc64", "sync/atomic", "SwapUint64"}: struct{}{},
|
{"ppc64", "sync/atomic", "SwapUint64"}: struct{}{},
|
||||||
{"ppc64", "sync/atomic", "SwapUintptr"}: struct{}{},
|
{"ppc64", "sync/atomic", "SwapUintptr"}: struct{}{},
|
||||||
{"ppc64", "crypto/subtle", "ConstantTimeSelect"}: struct{}{},
|
{"ppc64", "crypto/internal/constanttime", "Select"}: struct{}{},
|
||||||
{"ppc64", "crypto/subtle", "constantTimeBoolToUint8"}: struct{}{},
|
{"ppc64", "crypto/internal/constanttime", "boolToUint8"}: struct{}{},
|
||||||
{"ppc64le", "internal/runtime/atomic", "And"}: struct{}{},
|
{"ppc64le", "internal/runtime/atomic", "And"}: struct{}{},
|
||||||
{"ppc64le", "internal/runtime/atomic", "And8"}: struct{}{},
|
{"ppc64le", "internal/runtime/atomic", "And8"}: struct{}{},
|
||||||
{"ppc64le", "internal/runtime/atomic", "Cas"}: struct{}{},
|
{"ppc64le", "internal/runtime/atomic", "Cas"}: struct{}{},
|
||||||
|
|
@ -1086,8 +1086,8 @@ var wantIntrinsics = map[testIntrinsicKey]struct{}{
|
||||||
{"ppc64le", "sync/atomic", "SwapUint32"}: struct{}{},
|
{"ppc64le", "sync/atomic", "SwapUint32"}: struct{}{},
|
||||||
{"ppc64le", "sync/atomic", "SwapUint64"}: struct{}{},
|
{"ppc64le", "sync/atomic", "SwapUint64"}: struct{}{},
|
||||||
{"ppc64le", "sync/atomic", "SwapUintptr"}: struct{}{},
|
{"ppc64le", "sync/atomic", "SwapUintptr"}: struct{}{},
|
||||||
{"ppc64le", "crypto/subtle", "ConstantTimeSelect"}: struct{}{},
|
{"ppc64le", "crypto/internal/constanttime", "Select"}: struct{}{},
|
||||||
{"ppc64le", "crypto/subtle", "constantTimeBoolToUint8"}: struct{}{},
|
{"ppc64le", "crypto/internal/constanttime", "boolToUint8"}: struct{}{},
|
||||||
{"riscv64", "internal/runtime/atomic", "And"}: struct{}{},
|
{"riscv64", "internal/runtime/atomic", "And"}: struct{}{},
|
||||||
{"riscv64", "internal/runtime/atomic", "And8"}: struct{}{},
|
{"riscv64", "internal/runtime/atomic", "And8"}: struct{}{},
|
||||||
{"riscv64", "internal/runtime/atomic", "Cas"}: struct{}{},
|
{"riscv64", "internal/runtime/atomic", "Cas"}: struct{}{},
|
||||||
|
|
@ -1208,7 +1208,7 @@ var wantIntrinsics = map[testIntrinsicKey]struct{}{
|
||||||
{"riscv64", "sync/atomic", "SwapUint32"}: struct{}{},
|
{"riscv64", "sync/atomic", "SwapUint32"}: struct{}{},
|
||||||
{"riscv64", "sync/atomic", "SwapUint64"}: struct{}{},
|
{"riscv64", "sync/atomic", "SwapUint64"}: struct{}{},
|
||||||
{"riscv64", "sync/atomic", "SwapUintptr"}: struct{}{},
|
{"riscv64", "sync/atomic", "SwapUintptr"}: struct{}{},
|
||||||
{"riscv64", "crypto/subtle", "constantTimeBoolToUint8"}: struct{}{},
|
{"riscv64", "crypto/internal/constanttime", "boolToUint8"}: struct{}{},
|
||||||
{"s390x", "internal/runtime/atomic", "And"}: struct{}{},
|
{"s390x", "internal/runtime/atomic", "And"}: struct{}{},
|
||||||
{"s390x", "internal/runtime/atomic", "And8"}: struct{}{},
|
{"s390x", "internal/runtime/atomic", "And8"}: struct{}{},
|
||||||
{"s390x", "internal/runtime/atomic", "Cas"}: struct{}{},
|
{"s390x", "internal/runtime/atomic", "Cas"}: struct{}{},
|
||||||
|
|
@ -1327,7 +1327,7 @@ var wantIntrinsics = map[testIntrinsicKey]struct{}{
|
||||||
{"s390x", "sync/atomic", "SwapUint32"}: struct{}{},
|
{"s390x", "sync/atomic", "SwapUint32"}: struct{}{},
|
||||||
{"s390x", "sync/atomic", "SwapUint64"}: struct{}{},
|
{"s390x", "sync/atomic", "SwapUint64"}: struct{}{},
|
||||||
{"s390x", "sync/atomic", "SwapUintptr"}: struct{}{},
|
{"s390x", "sync/atomic", "SwapUintptr"}: struct{}{},
|
||||||
{"s390x", "crypto/subtle", "constantTimeBoolToUint8"}: struct{}{},
|
{"s390x", "crypto/internal/constanttime", "boolToUint8"}: struct{}{},
|
||||||
{"wasm", "internal/runtime/sys", "GetCallerPC"}: struct{}{},
|
{"wasm", "internal/runtime/sys", "GetCallerPC"}: struct{}{},
|
||||||
{"wasm", "internal/runtime/sys", "GetCallerSP"}: struct{}{},
|
{"wasm", "internal/runtime/sys", "GetCallerSP"}: struct{}{},
|
||||||
{"wasm", "internal/runtime/sys", "GetClosurePtr"}: struct{}{},
|
{"wasm", "internal/runtime/sys", "GetClosurePtr"}: struct{}{},
|
||||||
|
|
@ -1363,8 +1363,8 @@ var wantIntrinsics = map[testIntrinsicKey]struct{}{
|
||||||
{"wasm", "math/bits", "TrailingZeros8"}: struct{}{},
|
{"wasm", "math/bits", "TrailingZeros8"}: struct{}{},
|
||||||
{"wasm", "runtime", "KeepAlive"}: struct{}{},
|
{"wasm", "runtime", "KeepAlive"}: struct{}{},
|
||||||
{"wasm", "runtime", "slicebytetostringtmp"}: struct{}{},
|
{"wasm", "runtime", "slicebytetostringtmp"}: struct{}{},
|
||||||
{"wasm", "crypto/subtle", "ConstantTimeSelect"}: struct{}{},
|
{"wasm", "crypto/internal/constanttime", "Select"}: struct{}{},
|
||||||
{"wasm", "crypto/subtle", "constantTimeBoolToUint8"}: struct{}{},
|
{"wasm", "crypto/internal/constanttime", "boolToUint8"}: struct{}{},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIntrinsics(t *testing.T) {
|
func TestIntrinsics(t *testing.T) {
|
||||||
|
|
|
||||||
42
src/crypto/internal/constanttime/constant_time.go
Normal file
42
src/crypto/internal/constanttime/constant_time.go
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
// Copyright 2025 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 constanttime
|
||||||
|
|
||||||
|
// The functions in this package are compiler intrinsics for constant-time
|
||||||
|
// operations. They are exposed by crypto/subtle and used directly by the
|
||||||
|
// FIPS 140-3 module.
|
||||||
|
|
||||||
|
// Select returns x if v == 1 and y if v == 0.
|
||||||
|
// Its behavior is undefined if v takes any other value.
|
||||||
|
func Select(v, x, y int) int {
|
||||||
|
// This is intrinsicified on arches with CMOV.
|
||||||
|
// It implements the following superset behavior:
|
||||||
|
// ConstantTimeSelect returns x if v != 0 and y if v == 0.
|
||||||
|
// Do the same here to avoid non portable UB.
|
||||||
|
v = int(boolToUint8(v != 0))
|
||||||
|
return ^(v-1)&x | (v-1)&y
|
||||||
|
}
|
||||||
|
|
||||||
|
// ByteEq returns 1 if x == y and 0 otherwise.
|
||||||
|
func ByteEq(x, y uint8) int {
|
||||||
|
return int(boolToUint8(x == y))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Eq returns 1 if x == y and 0 otherwise.
|
||||||
|
func Eq(x, y int32) int {
|
||||||
|
return int(boolToUint8(x == y))
|
||||||
|
}
|
||||||
|
|
||||||
|
// LessOrEq returns 1 if x <= y and 0 otherwise.
|
||||||
|
// Its behavior is undefined if x or y are negative or > 2**31 - 1.
|
||||||
|
func LessOrEq(x, y int) int {
|
||||||
|
return int(boolToUint8(x <= y))
|
||||||
|
}
|
||||||
|
|
||||||
|
// boolToUint8 is a compiler intrinsic.
|
||||||
|
// It returns 1 for true and 0 for false.
|
||||||
|
func boolToUint8(b bool) uint8 {
|
||||||
|
panic("unreachable; must be intrinsicified")
|
||||||
|
}
|
||||||
|
|
@ -4,9 +4,7 @@
|
||||||
|
|
||||||
package edwards25519
|
package edwards25519
|
||||||
|
|
||||||
import (
|
import "crypto/internal/constanttime"
|
||||||
"crypto/internal/fips140/subtle"
|
|
||||||
)
|
|
||||||
|
|
||||||
// A dynamic lookup table for variable-base, constant-time scalar muls.
|
// A dynamic lookup table for variable-base, constant-time scalar muls.
|
||||||
type projLookupTable struct {
|
type projLookupTable struct {
|
||||||
|
|
@ -95,7 +93,7 @@ func (v *projLookupTable) SelectInto(dest *projCached, x int8) {
|
||||||
dest.Zero()
|
dest.Zero()
|
||||||
for j := 1; j <= 8; j++ {
|
for j := 1; j <= 8; j++ {
|
||||||
// Set dest = j*Q if |x| = j
|
// Set dest = j*Q if |x| = j
|
||||||
cond := subtle.ConstantTimeByteEq(xabs, uint8(j))
|
cond := constanttime.ByteEq(xabs, uint8(j))
|
||||||
dest.Select(&v.points[j-1], dest, cond)
|
dest.Select(&v.points[j-1], dest, cond)
|
||||||
}
|
}
|
||||||
// Now dest = |x|*Q, conditionally negate to get x*Q
|
// Now dest = |x|*Q, conditionally negate to get x*Q
|
||||||
|
|
@ -111,7 +109,7 @@ func (v *affineLookupTable) SelectInto(dest *affineCached, x int8) {
|
||||||
dest.Zero()
|
dest.Zero()
|
||||||
for j := 1; j <= 8; j++ {
|
for j := 1; j <= 8; j++ {
|
||||||
// Set dest = j*Q if |x| = j
|
// Set dest = j*Q if |x| = j
|
||||||
cond := subtle.ConstantTimeByteEq(xabs, uint8(j))
|
cond := constanttime.ByteEq(xabs, uint8(j))
|
||||||
dest.Select(&v.points[j-1], dest, cond)
|
dest.Select(&v.points[j-1], dest, cond)
|
||||||
}
|
}
|
||||||
// Now dest = |x|*Q, conditionally negate to get x*Q
|
// Now dest = |x|*Q, conditionally negate to get x*Q
|
||||||
|
|
|
||||||
|
|
@ -140,8 +140,8 @@ const tmplNISTEC = `// Copyright 2022 The Go Authors. All rights reserved.
|
||||||
package nistec
|
package nistec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/internal/constanttime"
|
||||||
"crypto/internal/fips140/nistec/fiat"
|
"crypto/internal/fips140/nistec/fiat"
|
||||||
"crypto/internal/fips140/subtle"
|
|
||||||
"errors"
|
"errors"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
@ -467,7 +467,7 @@ func (table *{{.p}}Table) Select(p *{{.P}}Point, n uint8) {
|
||||||
}
|
}
|
||||||
p.Set(New{{.P}}Point())
|
p.Set(New{{.P}}Point())
|
||||||
for i := uint8(1); i < 16; i++ {
|
for i := uint8(1); i < 16; i++ {
|
||||||
cond := subtle.ConstantTimeByteEq(i, n)
|
cond := constanttime.ByteEq(i, n)
|
||||||
p.Select(table[i-1], p, cond)
|
p.Select(table[i-1], p, cond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@
|
||||||
package nistec
|
package nistec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/internal/constanttime"
|
||||||
"crypto/internal/fips140/nistec/fiat"
|
"crypto/internal/fips140/nistec/fiat"
|
||||||
"crypto/internal/fips140/subtle"
|
|
||||||
"errors"
|
"errors"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
@ -333,7 +333,7 @@ func (table *p224Table) Select(p *P224Point, n uint8) {
|
||||||
}
|
}
|
||||||
p.Set(NewP224Point())
|
p.Set(NewP224Point())
|
||||||
for i := uint8(1); i < 16; i++ {
|
for i := uint8(1); i < 16; i++ {
|
||||||
cond := subtle.ConstantTimeByteEq(i, n)
|
cond := constanttime.ByteEq(i, n)
|
||||||
p.Select(table[i-1], p, cond)
|
p.Select(table[i-1], p, cond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@
|
||||||
package nistec
|
package nistec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/internal/constanttime"
|
||||||
"crypto/internal/fips140/nistec/fiat"
|
"crypto/internal/fips140/nistec/fiat"
|
||||||
"crypto/internal/fips140/subtle"
|
|
||||||
"crypto/internal/fips140deps/byteorder"
|
"crypto/internal/fips140deps/byteorder"
|
||||||
"crypto/internal/fips140deps/cpu"
|
"crypto/internal/fips140deps/cpu"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
@ -458,7 +458,7 @@ func (table *p256Table) Select(p *P256Point, n uint8) {
|
||||||
}
|
}
|
||||||
p.Set(NewP256Point())
|
p.Set(NewP256Point())
|
||||||
for i := uint8(1); i <= 16; i++ {
|
for i := uint8(1); i <= 16; i++ {
|
||||||
cond := subtle.ConstantTimeByteEq(i, n)
|
cond := constanttime.ByteEq(i, n)
|
||||||
p.Select(&table[i-1], p, cond)
|
p.Select(&table[i-1], p, cond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -553,7 +553,7 @@ func (table *p256AffineTable) Select(p *p256AffinePoint, n uint8) {
|
||||||
panic("nistec: internal error: p256AffineTable.Select called with out-of-bounds value")
|
panic("nistec: internal error: p256AffineTable.Select called with out-of-bounds value")
|
||||||
}
|
}
|
||||||
for i := uint8(1); i <= 32; i++ {
|
for i := uint8(1); i <= 32; i++ {
|
||||||
cond := subtle.ConstantTimeByteEq(i, n)
|
cond := constanttime.ByteEq(i, n)
|
||||||
p.x.Select(&table[i-1].x, &p.x, cond)
|
p.x.Select(&table[i-1].x, &p.x, cond)
|
||||||
p.y.Select(&table[i-1].y, &p.y, cond)
|
p.y.Select(&table[i-1].y, &p.y, cond)
|
||||||
}
|
}
|
||||||
|
|
@ -618,7 +618,7 @@ func (p *P256Point) ScalarBaseMult(scalar []byte) (*P256Point, error) {
|
||||||
// the point at infinity (because infinity can't be represented in affine
|
// the point at infinity (because infinity can't be represented in affine
|
||||||
// coordinates). Here we conditionally set p to the infinity if sel is zero.
|
// coordinates). Here we conditionally set p to the infinity if sel is zero.
|
||||||
// In the loop, that's handled by AddAffine.
|
// In the loop, that's handled by AddAffine.
|
||||||
selIsZero := subtle.ConstantTimeByteEq(sel, 0)
|
selIsZero := constanttime.ByteEq(sel, 0)
|
||||||
p.Select(NewP256Point(), t.Projective(), selIsZero)
|
p.Select(NewP256Point(), t.Projective(), selIsZero)
|
||||||
|
|
||||||
for index >= 5 {
|
for index >= 5 {
|
||||||
|
|
@ -636,7 +636,7 @@ func (p *P256Point) ScalarBaseMult(scalar []byte) (*P256Point, error) {
|
||||||
table := &p256GeneratorTables[(index+1)/6]
|
table := &p256GeneratorTables[(index+1)/6]
|
||||||
table.Select(t, sel)
|
table.Select(t, sel)
|
||||||
t.Negate(sign)
|
t.Negate(sign)
|
||||||
selIsZero := subtle.ConstantTimeByteEq(sel, 0)
|
selIsZero := constanttime.ByteEq(sel, 0)
|
||||||
p.AddAffine(p, t, selIsZero)
|
p.AddAffine(p, t, selIsZero)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@
|
||||||
package nistec
|
package nistec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/internal/constanttime"
|
||||||
"crypto/internal/fips140/nistec/fiat"
|
"crypto/internal/fips140/nistec/fiat"
|
||||||
"crypto/internal/fips140/subtle"
|
|
||||||
"errors"
|
"errors"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
@ -333,7 +333,7 @@ func (table *p384Table) Select(p *P384Point, n uint8) {
|
||||||
}
|
}
|
||||||
p.Set(NewP384Point())
|
p.Set(NewP384Point())
|
||||||
for i := uint8(1); i < 16; i++ {
|
for i := uint8(1); i < 16; i++ {
|
||||||
cond := subtle.ConstantTimeByteEq(i, n)
|
cond := constanttime.ByteEq(i, n)
|
||||||
p.Select(table[i-1], p, cond)
|
p.Select(table[i-1], p, cond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@
|
||||||
package nistec
|
package nistec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/internal/constanttime"
|
||||||
"crypto/internal/fips140/nistec/fiat"
|
"crypto/internal/fips140/nistec/fiat"
|
||||||
"crypto/internal/fips140/subtle"
|
|
||||||
"errors"
|
"errors"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
@ -333,7 +333,7 @@ func (table *p521Table) Select(p *P521Point, n uint8) {
|
||||||
}
|
}
|
||||||
p.Set(NewP521Point())
|
p.Set(NewP521Point())
|
||||||
for i := uint8(1); i < 16; i++ {
|
for i := uint8(1); i < 16; i++ {
|
||||||
cond := subtle.ConstantTimeByteEq(i, n)
|
cond := constanttime.ByteEq(i, n)
|
||||||
p.Select(table[i-1], p, cond)
|
p.Select(table[i-1], p, cond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ package rsa
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"crypto/internal/constanttime"
|
||||||
"crypto/internal/fips140"
|
"crypto/internal/fips140"
|
||||||
"crypto/internal/fips140/drbg"
|
"crypto/internal/fips140/drbg"
|
||||||
"crypto/internal/fips140/sha256"
|
"crypto/internal/fips140/sha256"
|
||||||
|
|
@ -432,7 +433,7 @@ func DecryptOAEP(hash, mgfHash hash.Hash, priv *PrivateKey, ciphertext []byte, l
|
||||||
hash.Write(label)
|
hash.Write(label)
|
||||||
lHash := hash.Sum(nil)
|
lHash := hash.Sum(nil)
|
||||||
|
|
||||||
firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0)
|
firstByteIsZero := constanttime.ByteEq(em[0], 0)
|
||||||
|
|
||||||
seed := em[1 : hash.Size()+1]
|
seed := em[1 : hash.Size()+1]
|
||||||
db := em[hash.Size()+1:]
|
db := em[hash.Size()+1:]
|
||||||
|
|
@ -458,11 +459,11 @@ func DecryptOAEP(hash, mgfHash hash.Hash, priv *PrivateKey, ciphertext []byte, l
|
||||||
rest := db[hash.Size():]
|
rest := db[hash.Size():]
|
||||||
|
|
||||||
for i := 0; i < len(rest); i++ {
|
for i := 0; i < len(rest); i++ {
|
||||||
equals0 := subtle.ConstantTimeByteEq(rest[i], 0)
|
equals0 := constanttime.ByteEq(rest[i], 0)
|
||||||
equals1 := subtle.ConstantTimeByteEq(rest[i], 1)
|
equals1 := constanttime.ByteEq(rest[i], 1)
|
||||||
index = subtle.ConstantTimeSelect(lookingForIndex&equals1, i, index)
|
index = constanttime.Select(lookingForIndex&equals1, i, index)
|
||||||
lookingForIndex = subtle.ConstantTimeSelect(equals1, 0, lookingForIndex)
|
lookingForIndex = constanttime.Select(equals1, 0, lookingForIndex)
|
||||||
invalid = subtle.ConstantTimeSelect(lookingForIndex&^equals0, 1, invalid)
|
invalid = constanttime.Select(lookingForIndex&^equals0, 1, invalid)
|
||||||
}
|
}
|
||||||
|
|
||||||
if firstByteIsZero&lHash2Good&^invalid&^lookingForIndex != 1 {
|
if firstByteIsZero&lHash2Good&^invalid&^lookingForIndex != 1 {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package subtle
|
package subtle
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/internal/constanttime"
|
||||||
"crypto/internal/fips140deps/byteorder"
|
"crypto/internal/fips140deps/byteorder"
|
||||||
"math/bits"
|
"math/bits"
|
||||||
)
|
)
|
||||||
|
|
@ -24,7 +25,7 @@ func ConstantTimeCompare(x, y []byte) int {
|
||||||
v |= x[i] ^ y[i]
|
v |= x[i] ^ y[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
return ConstantTimeByteEq(v, 0)
|
return constanttime.ByteEq(v, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConstantTimeLessOrEqBytes returns 1 if x <= y and 0 otherwise. The comparison
|
// ConstantTimeLessOrEqBytes returns 1 if x <= y and 0 otherwise. The comparison
|
||||||
|
|
@ -58,20 +59,6 @@ func ConstantTimeLessOrEqBytes(x, y []byte) int {
|
||||||
return int(b ^ 1)
|
return int(b ^ 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConstantTimeSelect returns x if v == 1 and y if v == 0.
|
|
||||||
// Its behavior is undefined if v takes any other value.
|
|
||||||
func ConstantTimeSelect(v, x, y int) int { return ^(v-1)&x | (v-1)&y }
|
|
||||||
|
|
||||||
// ConstantTimeByteEq returns 1 if x == y and 0 otherwise.
|
|
||||||
func ConstantTimeByteEq(x, y uint8) int {
|
|
||||||
return int((uint32(x^y) - 1) >> 31)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConstantTimeEq returns 1 if x == y and 0 otherwise.
|
|
||||||
func ConstantTimeEq(x, y int32) int {
|
|
||||||
return int((uint64(uint32(x^y)) - 1) >> 63)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConstantTimeCopy copies the contents of y into x (a slice of equal length)
|
// ConstantTimeCopy copies the contents of y into x (a slice of equal length)
|
||||||
// if v == 1. If v == 0, x is left unchanged. Its behavior is undefined if v
|
// if v == 1. If v == 0, x is left unchanged. Its behavior is undefined if v
|
||||||
// takes any other value.
|
// takes any other value.
|
||||||
|
|
@ -86,11 +73,3 @@ func ConstantTimeCopy(v int, x, y []byte) {
|
||||||
x[i] = x[i]&xmask | y[i]&ymask
|
x[i] = x[i]&xmask | y[i]&ymask
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConstantTimeLessOrEq returns 1 if x <= y and 0 otherwise.
|
|
||||||
// Its behavior is undefined if x or y are negative or > 2**31 - 1.
|
|
||||||
func ConstantTimeLessOrEq(x, y int) int {
|
|
||||||
x32 := int32(x)
|
|
||||||
y32 := int32(y)
|
|
||||||
return int(((x32 - y32 - 1) >> 31) & 1)
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,9 @@ var AllowedInternalPackages = map[string]bool{
|
||||||
|
|
||||||
// randutil.MaybeReadByte is used in non-FIPS mode by GenerateKey functions.
|
// randutil.MaybeReadByte is used in non-FIPS mode by GenerateKey functions.
|
||||||
"crypto/internal/randutil": true,
|
"crypto/internal/randutil": true,
|
||||||
|
|
||||||
|
// constanttime are the constant-time intrinsics.
|
||||||
|
"crypto/internal/constanttime": true,
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestImports(t *testing.T) {
|
func TestImports(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -6,63 +6,47 @@
|
||||||
// code but require careful thought to use correctly.
|
// code but require careful thought to use correctly.
|
||||||
package subtle
|
package subtle
|
||||||
|
|
||||||
import "crypto/internal/fips140/subtle"
|
import (
|
||||||
|
"crypto/internal/constanttime"
|
||||||
|
"crypto/internal/fips140/subtle"
|
||||||
|
)
|
||||||
|
|
||||||
|
// These functions are forwarded to crypto/internal/constanttime for intrinsified
|
||||||
|
// operations, and to crypto/internal/fips140/subtle for byte slice operations.
|
||||||
|
|
||||||
// ConstantTimeCompare returns 1 if the two slices, x and y, have equal contents
|
// ConstantTimeCompare returns 1 if the two slices, x and y, have equal contents
|
||||||
// and 0 otherwise. The time taken is a function of the length of the slices and
|
// and 0 otherwise. The time taken is a function of the length of the slices and
|
||||||
// is independent of the contents. If the lengths of x and y do not match it
|
// is independent of the contents. If the lengths of x and y do not match it
|
||||||
// returns 0 immediately.
|
// returns 0 immediately.
|
||||||
func ConstantTimeCompare(x, y []byte) int {
|
func ConstantTimeCompare(x, y []byte) int {
|
||||||
if len(x) != len(y) {
|
return subtle.ConstantTimeCompare(x, y)
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
var v byte
|
|
||||||
|
|
||||||
for i := 0; i < len(x); i++ {
|
|
||||||
v |= x[i] ^ y[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
return ConstantTimeByteEq(v, 0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConstantTimeSelect returns x if v == 1 and y if v == 0.
|
// ConstantTimeSelect returns x if v == 1 and y if v == 0.
|
||||||
// Its behavior is undefined if v takes any other value.
|
// Its behavior is undefined if v takes any other value.
|
||||||
func ConstantTimeSelect(v, x, y int) int {
|
func ConstantTimeSelect(v, x, y int) int {
|
||||||
// This is intrinsicified on arches with CMOV.
|
return constanttime.Select(v, x, y)
|
||||||
// It implements the following superset behavior:
|
|
||||||
// ConstantTimeSelect returns x if v != 0 and y if v == 0.
|
|
||||||
// Do the same here to avoid non portable UB.
|
|
||||||
v = int(constantTimeBoolToUint8(v != 0))
|
|
||||||
return ^(v-1)&x | (v-1)&y
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConstantTimeByteEq returns 1 if x == y and 0 otherwise.
|
// ConstantTimeByteEq returns 1 if x == y and 0 otherwise.
|
||||||
func ConstantTimeByteEq(x, y uint8) int {
|
func ConstantTimeByteEq(x, y uint8) int {
|
||||||
return int(constantTimeBoolToUint8(x == y))
|
return constanttime.ByteEq(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConstantTimeEq returns 1 if x == y and 0 otherwise.
|
// ConstantTimeEq returns 1 if x == y and 0 otherwise.
|
||||||
func ConstantTimeEq(x, y int32) int {
|
func ConstantTimeEq(x, y int32) int {
|
||||||
return int(constantTimeBoolToUint8(x == y))
|
return constanttime.Eq(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConstantTimeCopy copies the contents of y into x (a slice of equal length)
|
// ConstantTimeCopy copies the contents of y into x (a slice of equal length)
|
||||||
// if v == 1. If v == 0, x is left unchanged. Its behavior is undefined if v
|
// if v == 1. If v == 0, x is left unchanged. Its behavior is undefined if v
|
||||||
// takes any other value.
|
// takes any other value.
|
||||||
func ConstantTimeCopy(v int, x, y []byte) {
|
func ConstantTimeCopy(v int, x, y []byte) {
|
||||||
// Forward this one since it gains nothing from compiler intrinsics.
|
|
||||||
subtle.ConstantTimeCopy(v, x, y)
|
subtle.ConstantTimeCopy(v, x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConstantTimeLessOrEq returns 1 if x <= y and 0 otherwise.
|
// ConstantTimeLessOrEq returns 1 if x <= y and 0 otherwise.
|
||||||
// Its behavior is undefined if x or y are negative or > 2**31 - 1.
|
// Its behavior is undefined if x or y are negative or > 2**31 - 1.
|
||||||
func ConstantTimeLessOrEq(x, y int) int {
|
func ConstantTimeLessOrEq(x, y int) int {
|
||||||
return int(constantTimeBoolToUint8(x <= y))
|
return constanttime.LessOrEq(x, y)
|
||||||
}
|
|
||||||
|
|
||||||
// constantTimeBoolToUint8 is a compiler intrinsic.
|
|
||||||
// It returns 1 for true and 0 for false.
|
|
||||||
func constantTimeBoolToUint8(b bool) uint8 {
|
|
||||||
panic("unreachable; must be intrinsicified")
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -479,6 +479,8 @@ var depsRules = `
|
||||||
|
|
||||||
io, math/rand/v2 < crypto/internal/randutil;
|
io, math/rand/v2 < crypto/internal/randutil;
|
||||||
|
|
||||||
|
NONE < crypto/internal/constanttime;
|
||||||
|
|
||||||
STR < crypto/internal/impl;
|
STR < crypto/internal/impl;
|
||||||
|
|
||||||
OS < crypto/internal/sysrand
|
OS < crypto/internal/sysrand
|
||||||
|
|
@ -496,6 +498,7 @@ var depsRules = `
|
||||||
crypto/internal/impl,
|
crypto/internal/impl,
|
||||||
crypto/internal/entropy,
|
crypto/internal/entropy,
|
||||||
crypto/internal/randutil,
|
crypto/internal/randutil,
|
||||||
|
crypto/internal/constanttime,
|
||||||
crypto/internal/entropy/v1.0.0,
|
crypto/internal/entropy/v1.0.0,
|
||||||
crypto/internal/fips140deps/byteorder,
|
crypto/internal/fips140deps/byteorder,
|
||||||
crypto/internal/fips140deps/cpu,
|
crypto/internal/fips140deps/cpu,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue