1 // Copyright 2024 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 package subtle
6 7 import (
8 "internal/runtime/sys"
9 "runtime"
10 )
11 12 // WithDataIndependentTiming enables architecture specific features which ensure
13 // that the timing of specific instructions is independent of their inputs
14 // before executing f. On f returning it disables these features.
15 //
16 // WithDataIndependentTiming should only be used when f is written to make use
17 // of constant-time operations. WithDataIndependentTiming does not make
18 // variable-time code constant-time.
19 //
20 // WithDataIndependentTiming may lock the current goroutine to the OS thread for
21 // the duration of f. Calls to WithDataIndependentTiming may be nested.
22 //
23 // On Arm64 processors with FEAT_DIT, WithDataIndependentTiming enables
24 // PSTATE.DIT. See https://developer.arm.com/documentation/ka005181/1-0/?lang=en.
25 //
26 // Currently, on all other architectures WithDataIndependentTiming executes f immediately
27 // with no other side-effects.
28 //
29 //go:noinline
30 func WithDataIndependentTiming(f func()) {
31 if !sys.DITSupported {
32 f()
33 return
34 }
35 36 runtime.LockOSThread()
37 defer runtime.UnlockOSThread()
38 39 alreadyEnabled := sys.EnableDIT()
40 41 // disableDIT is called in a deferred function so that if f panics we will
42 // still disable DIT, in case the panic is recovered further up the stack.
43 defer func() {
44 if !alreadyEnabled {
45 sys.DisableDIT()
46 }
47 }()
48 49 f()
50 }
51