Source file src/crypto/internal/fips140/indicator.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 fips140 6 7 import _ "unsafe" // for go:linkname 8 9 // The service indicator lets users of the module query whether invoked services 10 // are approved. Three states are stored in a per-goroutine value by the 11 // runtime. The indicator starts at indicatorUnset after a reset. Invoking an 12 // approved service transitions to indicatorTrue. Invoking a non-approved 13 // service transitions to indicatorFalse, and it can't leave that state until a 14 // reset. The idea is that functions can "delegate" checks to inner functions, 15 // and if there's anything non-approved in the stack, the final result is 16 // negative. Finally, we expose indicatorUnset as negative to the user, so that 17 // we don't need to explicitly annotate fully non-approved services. 18 19 //go:linkname getIndicator crypto/internal/fips140.getIndicator 20 func getIndicator() uint8 21 22 //go:linkname setIndicator crypto/internal/fips140.setIndicator 23 func setIndicator(uint8) 24 25 const ( 26 indicatorUnset uint8 = iota 27 indicatorFalse 28 indicatorTrue 29 ) 30 31 // ResetServiceIndicator clears the service indicator for the running goroutine. 32 func ResetServiceIndicator() { 33 setIndicator(indicatorUnset) 34 } 35 36 // ServiceIndicator returns true if and only if all services invoked by this 37 // goroutine since the last ResetServiceIndicator call are approved. 38 // 39 // If ResetServiceIndicator was not called before by this goroutine, its return 40 // value is undefined. 41 func ServiceIndicator() bool { 42 return getIndicator() == indicatorTrue 43 } 44 45 // RecordApproved is an internal function that records the use of an approved 46 // service. It does not override RecordNonApproved calls in the same span. 47 // 48 // It should be called by exposed functions that perform a whole cryptographic 49 // alrgorithm (e.g. by Sum, not by New, unless a cryptographic Instantiate 50 // algorithm is performed) and should be called after any checks that may cause 51 // the function to error out or panic. 52 func RecordApproved() { 53 if getIndicator() == indicatorUnset { 54 setIndicator(indicatorTrue) 55 } 56 } 57 58 // RecordNonApproved is an internal function that records the use of a 59 // non-approved service. It overrides any RecordApproved calls in the same span. 60 func RecordNonApproved() { 61 setIndicator(indicatorFalse) 62 } 63