1
2
3
4
5 package fipstest
6
7 import (
8 "crypto/internal/boring"
9 . "crypto/internal/fips140/check"
10 "crypto/internal/fips140/check/checktest"
11 "fmt"
12 "internal/abi"
13 "internal/asan"
14 "internal/godebug"
15 "internal/testenv"
16 "os"
17 "runtime"
18 "testing"
19 "unicode"
20 "unsafe"
21 )
22
23 const enableFIPSTest = true
24
25 func TestFIPSCheckVerify(t *testing.T) {
26 if boring.Enabled {
27 t.Skip("not testing fips140 with boringcrypto enabled")
28 }
29
30 if Verified {
31 t.Logf("verified")
32 return
33 }
34
35 if godebug.New("#fips140").Value() == "on" {
36 t.Fatalf("GODEBUG=fips140=on but verification did not run")
37 }
38
39 if !enableFIPSTest {
40 return
41 }
42
43 if !Supported() {
44 t.Skipf("skipping on %s-%s", runtime.GOOS, runtime.GOARCH)
45 }
46 if asan.Enabled {
47
48 t.Skipf("skipping with -asan")
49 }
50
51 cmd := testenv.Command(t, os.Args[0], "-test.v", "-test.run=TestFIPSCheck")
52 cmd.Env = append(cmd.Environ(), "GODEBUG=fips140=on")
53 out, err := cmd.CombinedOutput()
54 if err != nil {
55 t.Fatalf("GODEBUG=fips140=on %v failed: %v\n%s", cmd.Args, err, out)
56 }
57 t.Logf("exec'ed GODEBUG=fips140=on and succeeded:\n%s", out)
58 }
59
60 func TestFIPSCheckInfo(t *testing.T) {
61 if !enableFIPSTest {
62 return
63 }
64
65 if !Supported() {
66 t.Skipf("skipping on %s-%s", runtime.GOOS, runtime.GOARCH)
67 }
68
69
70 if checktest.NOPTRDATA != 1 {
71 t.Errorf("checktest.NOPTRDATA = %d, want 1", checktest.NOPTRDATA)
72 }
73 if checktest.RODATA != 2 {
74 t.Errorf("checktest.RODATA = %d, want 2", checktest.RODATA)
75 }
76 if checktest.DATA.P != &checktest.NOPTRDATA {
77 t.Errorf("checktest.DATA.P = %p, want &checktest.NOPTRDATA (%p)", checktest.DATA.P, &checktest.NOPTRDATA)
78 }
79 if checktest.DATA.X != 3 {
80 t.Errorf("checktest.DATA.X = %d, want 3", checktest.DATA.X)
81 }
82 if checktest.NOPTRBSS != 0 {
83 t.Errorf("checktest.NOPTRBSS = %d, want 0", checktest.NOPTRBSS)
84 }
85 if checktest.BSS != nil {
86 t.Errorf("checktest.BSS = %p, want nil", checktest.BSS)
87 }
88 if p := checktest.PtrStaticData(); p != nil && *p != 10 {
89 t.Errorf("*checktest.PtrStaticData() = %d, want 10", *p)
90 }
91
92
93 sect := func(i int, name string, p unsafe.Pointer) {
94 s := Linkinfo.Sects[i]
95 if !(uintptr(s.Start) <= uintptr(p) && uintptr(p) < uintptr(s.End)) {
96 t.Errorf("checktest.%s (%#x) not in section #%d (%#x..%#x)", name, p, i, s.Start, s.End)
97 }
98 }
99 sect(0, "TEXT", unsafe.Pointer(abi.FuncPCABIInternal(checktest.TEXT)))
100 if p := checktest.PtrStaticText(); p != nil {
101 sect(0, "StaticText", p)
102 }
103 sect(1, "RODATA", unsafe.Pointer(&checktest.RODATA))
104 sect(2, "NOPTRDATA", unsafe.Pointer(&checktest.NOPTRDATA))
105 if p := checktest.PtrStaticData(); p != nil {
106 sect(2, "StaticData", unsafe.Pointer(p))
107 }
108 sect(3, "DATA", unsafe.Pointer(&checktest.DATA))
109
110
111 no := func(name string, p unsafe.Pointer, ix ...int) {
112 for _, i := range ix {
113 s := Linkinfo.Sects[i]
114 if uintptr(s.Start) <= uintptr(p) && uintptr(p) < uintptr(s.End) {
115 t.Errorf("%s (%#x) unexpectedly in section #%d (%#x..%#x)", name, p, i, s.Start, s.End)
116 }
117 }
118 }
119
120
121 no("checktest.TEXT", unsafe.Pointer(abi.FuncPCABIInternal(checktest.TEXT)), 1, 2, 3)
122 no("checktest.RODATA", unsafe.Pointer(&checktest.RODATA), 0, 2, 3)
123 no("checktest.NOPTRDATA", unsafe.Pointer(&checktest.NOPTRDATA), 0, 1, 3)
124 no("checktest.DATA", unsafe.Pointer(&checktest.DATA), 0, 1, 2)
125
126
127 no("fmt.Printf", unsafe.Pointer(abi.FuncPCABIInternal(fmt.Printf)), 0, 1, 2, 3)
128 no("unicode.Categories", unsafe.Pointer(&unicode.Categories), 0, 1, 2, 3)
129 no("unicode.ASCII_Hex_Digit", unsafe.Pointer(&unicode.ASCII_Hex_Digit), 0, 1, 2, 3)
130
131
132
133 n := uintptr(0)
134 for _, s := range Linkinfo.Sects {
135 n += uintptr(s.End) - uintptr(s.Start)
136 }
137 if n < 16*1024 {
138 t.Fatalf("fips sections not big enough: %d, want at least 16 kB", n)
139 }
140 }
141
View as plain text