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  

View as plain text