Source file src/crypto/fips140/enforcement_test.go

     1  // Copyright 2025 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_test
     6  
     7  import (
     8  	"crypto/des"
     9  	"crypto/fips140"
    10  	"crypto/internal/cryptotest"
    11  	"internal/testenv"
    12  	"testing"
    13  )
    14  
    15  func expectAllowed(t *testing.T, why string, expected bool) {
    16  	t.Helper()
    17  	result := isAllowed()
    18  	if result != expected {
    19  		t.Fatalf("%v: expected: %v, got: %v", why, expected, result)
    20  	}
    21  }
    22  
    23  func isAllowed() bool {
    24  	_, err := des.NewCipher(make([]byte, 8))
    25  	return err == nil
    26  }
    27  
    28  func TestWithoutEnforcement(t *testing.T) {
    29  	cryptotest.MustSupportFIPS140(t)
    30  	if !fips140.Enforced() {
    31  		cmd := testenv.Command(t, testenv.Executable(t), "-test.run=^TestWithoutEnforcement$", "-test.v")
    32  		cmd.Env = append(cmd.Environ(), "GODEBUG=fips140=only")
    33  		out, err := cmd.CombinedOutput()
    34  		t.Logf("running with GODEBUG=fips140=only:\n%s", out)
    35  		if err != nil {
    36  			t.Errorf("fips140=only subprocess failed: %v", err)
    37  		}
    38  		return
    39  	}
    40  
    41  	t.Run("Disabled", func(t *testing.T) {
    42  		expectAllowed(t, "before enforcement disabled", false)
    43  		fips140.WithoutEnforcement(func() {
    44  			expectAllowed(t, "inside WithoutEnforcement", true)
    45  		})
    46  		// make sure that bypass doesn't live on after returning
    47  		expectAllowed(t, "after WithoutEnforcement", false)
    48  	})
    49  
    50  	t.Run("Nested", func(t *testing.T) {
    51  		expectAllowed(t, "before enforcement bypass", false)
    52  		fips140.WithoutEnforcement(func() {
    53  			fips140.WithoutEnforcement(func() {
    54  				expectAllowed(t, "inside nested WithoutEnforcement", true)
    55  			})
    56  			expectAllowed(t, "inside nested WithoutEnforcement", true)
    57  		})
    58  		expectAllowed(t, "after enforcement bypass", false)
    59  	})
    60  
    61  	t.Run("GoroutineInherit", func(t *testing.T) {
    62  		ch := make(chan bool, 2)
    63  		expectAllowed(t, "before enforcement bypass", false)
    64  		fips140.WithoutEnforcement(func() {
    65  			go func() {
    66  				ch <- isAllowed()
    67  			}()
    68  		})
    69  		allowed := <-ch
    70  		if !allowed {
    71  			t.Fatal("goroutine didn't inherit enforcement bypass")
    72  		}
    73  		go func() {
    74  			ch <- isAllowed()
    75  		}()
    76  		allowed = <-ch
    77  		if allowed {
    78  			t.Fatal("goroutine inherited bypass after WithoutEnforcement return")
    79  		}
    80  	})
    81  }
    82  

View as plain text