Source file src/crypto/subtle/dit.go
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 _ "unsafe" 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 // Any goroutine spawned by f will also have data independent timing enabled for 17 // its lifetime, as well as any of their descendant goroutines. 18 // 19 // Any C code called via cgo from within f, or from a goroutine spawned by f, will 20 // also have data independent timing enabled for the duration of the call. If the 21 // C code disables data independent timing, it will be re-enabled on return to Go. 22 // 23 // If C code called via cgo, from f or elsewhere, enables or disables data 24 // independent timing then calling into Go will preserve that state for the 25 // duration of the call. 26 // 27 // WithDataIndependentTiming should only be used when f is written to make use 28 // of constant-time operations. WithDataIndependentTiming does not make 29 // variable-time code constant-time. 30 // 31 // Calls to WithDataIndependentTiming may be nested. 32 // 33 // On Arm64 processors with FEAT_DIT, WithDataIndependentTiming enables 34 // PSTATE.DIT. See https://developer.arm.com/documentation/ka005181/1-0/?lang=en. 35 // 36 // Currently, on all other architectures WithDataIndependentTiming executes f immediately 37 // with no other side-effects. 38 // 39 //go:noinline 40 func WithDataIndependentTiming(f func()) { 41 if !sys.DITSupported { 42 f() 43 return 44 } 45 46 alreadyEnabled := setDITEnabled() 47 48 // disableDIT is called in a deferred function so that if f panics we will 49 // still disable DIT, in case the panic is recovered further up the stack. 50 defer func() { 51 if !alreadyEnabled { 52 setDITDisabled() 53 } 54 }() 55 56 f() 57 } 58 59 //go:linkname setDITEnabled 60 func setDITEnabled() bool 61 62 //go:linkname setDITDisabled 63 func setDITDisabled() 64