1
2
3
4
5
6
7
8
9
10
11
12
13 package check
14
15 import (
16 "crypto/internal/fips/hmac"
17 "crypto/internal/fips/sha256"
18 "internal/byteorder"
19 "internal/godebug"
20 "io"
21 "runtime"
22 "unsafe"
23 )
24
25
26
27
28 func Enabled() bool {
29 return enabled
30 }
31
32 var enabled bool
33 var verified bool
34
35
36 func supported() bool {
37
38 switch {
39 case runtime.GOARCH == "wasm",
40 runtime.GOOS == "windows" && runtime.GOARCH == "386",
41 runtime.GOOS == "windows" && runtime.GOARCH == "arm",
42 runtime.GOOS == "windows" && runtime.GOARCH == "arm64",
43 runtime.GOOS == "aix":
44 return false
45 }
46 return true
47 }
48
49
50
51
52
53 var linkinfo struct {
54 Magic [16]byte
55 Sum [32]byte
56 Self uintptr
57 Sects [4]struct {
58
59
60
61
62 Start unsafe.Pointer
63 End unsafe.Pointer
64 }
65 }
66
67
68
69
70 const fipsMagic = " Go fipsinfo \xff\x00"
71
72 var zeroSum [32]byte
73
74 func init() {
75 v := godebug.New("#fips140").Value()
76 enabled = v != "" && v != "off"
77 if !enabled {
78 return
79 }
80
81 switch v {
82 case "on", "only", "debug":
83
84 default:
85 panic("fips140: unknown GODEBUG setting fips140=" + v)
86 }
87
88 if !supported() {
89 panic("fips140: unavailable on " + runtime.GOOS + "-" + runtime.GOARCH)
90 }
91
92 if linkinfo.Magic[0] != 0xff || string(linkinfo.Magic[1:]) != fipsMagic || linkinfo.Sum == zeroSum {
93 panic("fips140: no verification checksum found")
94 }
95
96 h := hmac.New(sha256.New, make([]byte, 32))
97 w := io.Writer(h)
98
99
109
110 w.Write([]byte("go fips object v1\n"))
111
112 var nbuf [8]byte
113 for _, sect := range linkinfo.Sects {
114 n := uintptr(sect.End) - uintptr(sect.Start)
115 byteorder.BePutUint64(nbuf[:], uint64(n))
116 w.Write(nbuf[:])
117 w.Write(unsafe.Slice((*byte)(sect.Start), n))
118 }
119 sum := h.Sum(nil)
120
121 if [32]byte(sum) != linkinfo.Sum {
122 panic("fips140: verification mismatch")
123 }
124
125 if v == "debug" {
126 println("fips140: verified code+data")
127 }
128
129 verified = true
130 }
131
View as plain text