Skip to content

Commit 1724138

Browse files
rscpull[bot]
authored andcommitted
lib/fips140: add directory and test
This directory will hold the fips140 snapshots. Add a README, helpful Makefile, and a test that the checksums are correct (once we have zip files). Change-Id: I735540ad1ce7da9a24c3a0b57b054c8340708da1 Reviewed-on: https://go-review.googlesource.com/c/go/+/629955 Reviewed-by: Filippo Valsorda <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Michael Matloob <[email protected]>
1 parent 9c5887b commit 1724138

File tree

4 files changed

+168
-0
lines changed

4 files changed

+168
-0
lines changed

lib/fips140/Makefile

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
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+
# Rules for building and testing new FIPS snapshots.
6+
# For example:
7+
#
8+
# make v1.2.3.zip
9+
# make v1.2.3.test
10+
#
11+
# and then if changes are needed, check them into master
12+
# and run 'make v1.2.3.rm' and repeat.
13+
#
14+
# Note that once published a snapshot zip file should never
15+
# be modified. We record the sha256 hashes of the zip files
16+
# in fips140.sum, and the cmd/go/internal/fips test checks
17+
# that the zips match.
18+
#
19+
# When the zip file is finalized, run 'make updatesum' to update
20+
# fips140.sum.
21+
22+
default:
23+
@echo nothing to make
24+
25+
# make v1.2.3.zip builds a v1.2.3.zip file
26+
# from the current origin/master.
27+
# copy and edit the 'go run' command by hand to use a different branch.
28+
v%.zip:
29+
git fetch origin master
30+
go run ../../src/cmd/go/internal/fips/mkzip.go -b master v$*
31+
32+
# normally mkzip refuses to overwrite an existing zip file.
33+
# make v1.2.3.rm removes the zip file and and unpacked
34+
# copy from the module cache.
35+
v%.rm:
36+
rm -f v$*.zip
37+
chmod -R u+w $$(go env GOMODCACHE)/golang.org/fips140@v$* 2>/dev/null || true
38+
rm -rf $$(go env GOMODCACHE)/golang.org/fips140@v$*
39+
40+
# make v1.2.3.test runs the crypto tests using that snapshot.
41+
v%.test:
42+
GOFIPS140=v$* go test -short crypto...
43+
44+
# make updatesum updates the fips140.sum file.
45+
updatesum:
46+
go test cmd/go/internal/fips -update

lib/fips140/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
This directory holds snapshots of the crypto/internal/fips tree
2+
that are being validated and certified for FIPS-140 use.
3+
The file x.txt (for example, inprocess.txt, certified.txt)
4+
defines the meaning of the FIPS version alias x, listing
5+
the exact version to use.
6+
7+
The zip files are created by cmd/go/internal/fips/mkzip.go.
8+
The fips140.sum file lists checksums for the zip files.
9+
See the Makefile for recipes.

lib/fips140/fips140.sum

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# SHA256 checksums of snapshot zip files in this directory.
2+
# These checksums are included in the FIPS security policy
3+
# (validation instructions sent to the lab) and MUST NOT CHANGE.
4+
# That is, the zip files themselves must not change.
5+
#
6+
# It is okay to add new zip files to the list, and it is okay to
7+
# remove zip files from the list when they are removed from
8+
# this directory. To update this file:
9+
#
10+
# go test cmd/go/internal/fips -update
11+
#

src/cmd/go/internal/fips/fips_test.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
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 fips
6+
7+
import (
8+
"crypto/sha256"
9+
"flag"
10+
"fmt"
11+
"internal/testenv"
12+
"maps"
13+
"os"
14+
"path/filepath"
15+
"slices"
16+
"strings"
17+
"testing"
18+
)
19+
20+
var update = flag.Bool("update", false, "update GOROOT/lib/fips140/fips140.sum")
21+
22+
func TestSums(t *testing.T) {
23+
lib := filepath.Join(testenv.GOROOT(t), "lib/fips140")
24+
file := filepath.Join(lib, "fips140.sum")
25+
sums, err := os.ReadFile(file)
26+
if err != nil {
27+
t.Fatal(err)
28+
}
29+
lines := strings.SplitAfter(string(sums), "\n")
30+
31+
zips, err := filepath.Glob(filepath.Join(lib, "*.zip"))
32+
if err != nil {
33+
t.Fatal(err)
34+
}
35+
36+
format := func(name string, sum [32]byte) string {
37+
return fmt.Sprintf("%s %x\n", name, sum[:])
38+
}
39+
40+
want := make(map[string]string)
41+
for _, zip := range zips {
42+
data, err := os.ReadFile(zip)
43+
if err != nil {
44+
t.Fatal(err)
45+
}
46+
name := filepath.Base(zip)
47+
want[name] = format(name, sha256.Sum256(data))
48+
}
49+
50+
// Process diff, deleting or correcting stale lines.
51+
var diff []string
52+
have := make(map[string]bool)
53+
for i, line := range lines {
54+
if line == "" {
55+
continue
56+
}
57+
if strings.HasPrefix(line, "#") || line == "\n" {
58+
// comment, preserve
59+
diff = append(diff, " "+line)
60+
continue
61+
}
62+
name, _, _ := strings.Cut(line, " ")
63+
if want[name] == "" {
64+
lines[i] = ""
65+
diff = append(diff, "-"+line)
66+
continue
67+
}
68+
have[name] = true
69+
fixed := want[name]
70+
delete(want, name)
71+
if line == fixed {
72+
diff = append(diff, " "+line)
73+
} else {
74+
// zip hashes should never change once listed
75+
t.Errorf("policy violation: zip file hash is changing:\n-%s+%s", line, fixed)
76+
lines[i] = fixed
77+
diff = append(diff, "-"+line, "+"+fixed)
78+
}
79+
}
80+
81+
// Add missing lines.
82+
// Sort keys to avoid non-determinism, but overall file is not sorted.
83+
// It will end up time-ordered instead.
84+
for _, name := range slices.Sorted(maps.Keys(want)) {
85+
line := want[name]
86+
lines = append(lines, line)
87+
diff = append(diff, "+"+line)
88+
}
89+
90+
// Show diffs or update file.
91+
fixed := strings.Join(lines, "")
92+
if fixed != string(sums) {
93+
if *update && !t.Failed() {
94+
t.Logf("updating GOROOT/lib/fips140/fips140.sum:\n%s", strings.Join(diff, ""))
95+
if err := os.WriteFile(file, []byte(fixed), 0666); err != nil {
96+
t.Fatal(err)
97+
}
98+
return
99+
}
100+
t.Errorf("GOROOT/lib/fips140/fips140.sum out of date. changes needed:\n%s", strings.Join(diff, ""))
101+
}
102+
}

0 commit comments

Comments
 (0)