Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ build/linux/amd64/pkg build/linux/arm64/pkg: build config
mkdir -pv pkg/etc/$(NAME) && \
mkdir -pv pkg/usr/bin && \
cp -lv $(NAME) pkg/usr/bin/ && \
ln -sfv $(NAME) pkg/usr/bin/$(NAME)-acvp && \
cp -lv ../../../$(NAME)/config.yml pkg/etc/$(NAME)/config.yml.example


Expand Down
16 changes: 16 additions & 0 deletions cmd/clickhouse-backup/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import (
"fmt"
stdlog "log"
"os"
"path/filepath"
"runtime"
"strings"

"github.com/rs/zerolog/log"
"github.com/urfave/cli"

"github.com/Altinity/clickhouse-backup/v2/pkg/acvpwrapper"
"github.com/Altinity/clickhouse-backup/v2/pkg/backup"
"github.com/Altinity/clickhouse-backup/v2/pkg/config"
"github.com/Altinity/clickhouse-backup/v2/pkg/log_helper"
Expand All @@ -30,6 +32,12 @@ func main() {
log.Logger = log_helper.SetupLogger(os.Stderr)
//log.Logger = zerolog.New(os.Stdout).With().Timestamp().Caller().Logger()
stdlog.SetOutput(log.Logger)
if filepath.Base(os.Args[0]) == "clickhouse-backup-acvp" {
if err := acvpwrapper.Run(os.Stdin, os.Stdout); err != nil {
log.Fatal().Stack().Err(err).Send()
}
return
}
cliapp := cli.NewApp()
cliapp.Name = "clickhouse-backup"
cliapp.Usage = "Tool for easy backup of ClickHouse with cloud support"
Expand Down Expand Up @@ -788,6 +796,14 @@ func main() {
},
),
},
{
Name: "acvp",
Usage: "Run ACVP wrapper protocol over stdin/stdout",
UsageText: "clickhouse-backup acvp",
Action: func(*cli.Context) error {
return acvpwrapper.Run(os.Stdin, os.Stdout)
},
},
{
Name: "server",
Usage: "Run API server",
Expand Down
351 changes: 0 additions & 351 deletions go.sum

Large diffs are not rendered by default.

129 changes: 129 additions & 0 deletions pkg/acvpwrapper/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# ACVP Wrapper Repro Guide

This folder contains the embedded ACVP wrapper used by `clickhouse-backup-acvp`
and `clickhouse-backup acvp`.

The tracked config for public-Go-API validation is:

- `pkg/acvpwrapper/acvp_test_fips140v1.26.public.config.json`

It intentionally excludes `ML-KEM` and `ML-DSA` vector suites because those
ACVP paths rely on internal Go crypto APIs that are not publicly exposed in
Go 1.26.

## Compliance Scope

- This wrapper is a reproducibility harness for ACVP expected-output tests.
- It is **not** itself a CMVP certificate artifact.
- The compliance-relevant cryptographic implementation is Go's native
`crypto/internal/fips140/...` module when run with `GODEBUG=fips140=on`
(or `only`), per Go's FIPS documentation.

## Certificate And Security Policy Context

- Go's official FIPS status and validation lifecycle is documented here:
[FIPS 140-3 Compliance (Go docs)](https://go.dev/doc/security/fips140).
- As documented by Go, module validations are tracked in CMVP lists; at the time
of writing, v1.26.0 is listed as "Implementation Under Test" and v1.0.0 is
listed as "In Process" (with CAVP certificate A6650).
- Go's published FIPS documentation and blog post are the authoritative public
references for certificate/security-policy context:
- [The FIPS 140-3 Go Cryptographic Module (Go blog)](https://go.dev/blog/fips140)
- [CMVP Modules In Process List](https://csrc.nist.gov/Projects/cryptographic-module-validation-program/modules-in-process/modules-in-process-list)
- [CMVP Validated Modules Search (Go Cryptographic Module)](https://csrc.nist.gov/projects/cryptographic-module-validation-program/validated-modules/search?SearchMode=Basic&ModuleName=Go+Cryptographic+Module&CertificateStatus=Active&ValidationYear=0)
- [CAVP Certificate A6650](https://csrc.nist.gov/projects/cryptographic-algorithm-validation-program/details?validation=39260)

## Reference Traceability (Claim -> Source)

| Claim | Source |
| --- | --- |
| Go supports native FIPS 140-3 mode in the standard toolchain and documents `GODEBUG=fips140=...` behavior. | [Go FIPS 140-3 compliance docs](https://go.dev/doc/security/fips140) |
| The relevant cryptographic implementation is Go's `crypto/internal/fips140/...` module in FIPS mode. | [Go FIPS 140-3 compliance docs](https://go.dev/doc/security/fips140) |
| Go module-validation lifecycle/status is tracked via CMVP lists (Validated / In Process / IUT). | [Go FIPS 140-3 compliance docs](https://go.dev/doc/security/fips140), [CMVP MIP list](https://csrc.nist.gov/Projects/cryptographic-module-validation-program/modules-in-process/modules-in-process-list), [CMVP validated modules search](https://csrc.nist.gov/projects/cryptographic-module-validation-program/validated-modules/search?SearchMode=Basic&ModuleName=Go+Cryptographic+Module&CertificateStatus=Active&ValidationYear=0) |
| Go Cryptographic Module v1.0.0 has CAVP certificate A6650 and entered CMVP in-process workflow. | [Go FIPS blog](https://go.dev/blog/fips140), [CAVP A6650](https://csrc.nist.gov/projects/cryptographic-algorithm-validation-program/details?validation=39260), [CMVP MIP list](https://csrc.nist.gov/Projects/cryptographic-module-validation-program/modules-in-process/modules-in-process-list) |
| Pins used by this repo's ACVP repro (`baaf868e6e8f`, `d893de8b8b1c`) come from upstream Go `fips140test` ACVP test constants. | Upstream Go source: `src/crypto/internal/fips140test/acvp_test.go` (constants `bsslVersion` and `goAcvpVersion`) |
| This repo's tracked config is a public-API-only derivative of Go's v1.26 ACVP config. | Upstream Go source: `src/crypto/internal/fips140test/acvp_test_fips140v1.26.config.json`, local tracked file `pkg/acvpwrapper/acvp_test_fips140v1.26.public.config.json` |
| The reproducibility result target in this repo is `38 ACVP tests matched expectations`. | Local reproducibility flow in `pkg/acvpwrapper/run.sh` and command output from `check_expected.go` |

## Pinned Version Provenance

Pins used by `run.sh` are taken from upstream Go's ACVP test setup for the
v1.26 stream:

- `boringssl` commit: `baaf868e6e8f`
- From `bsslVersion = v0.0.0-20251111011041-baaf868e6e8f` in Go
`crypto/internal/fips140test/acvp_test.go`.
- `acvp-testdata` commit: `d893de8b8b1c`
- From `goAcvpVersion = v0.0.0-20251201200548-d893de8b8b1c` in the same Go test.
- Upstream config source:
- `src/crypto/internal/fips140test/acvp_test_fips140v1.26.config.json`
in Go source.
- This repo's tracked config:
- `pkg/acvpwrapper/acvp_test_fips140v1.26.public.config.json`
- Derived from Go's v1.26 config, with `ML-KEM` and `ML-DSA` suites removed
to keep the run strictly on public Go crypto APIs.

## Reproduce The Current Result

Run from the repository root.

### One-command repro

```bash
bash pkg/acvpwrapper/run.sh
```

Expected output includes:

- `38 ACVP tests matched expectations`

### Manual step-by-step

### 1) Build the wrapper binary

```bash
docker run --rm \
-v "$PWD:/work" \
-w /work \
golang:1.26-alpine \
sh -lc 'export PATH=$PATH:/usr/local/go/bin && CGO_ENABLED=0 go build -o clickhouse-backup ./cmd/clickhouse-backup && ln -sf clickhouse-backup clickhouse-backup-acvp'
```

### 2) Fetch pinned upstream inputs

```bash
rm -rf /tmp/boringssl /tmp/acvp-testdata
git clone https://boringssl.googlesource.com/boringssl /tmp/boringssl
git -C /tmp/boringssl checkout baaf868e6e8f

git clone https://github.com/geomys/acvp-testdata /tmp/acvp-testdata
git -C /tmp/acvp-testdata checkout d893de8b8b1c
```

### 3) Build pinned `acvptool`

```bash
docker run --rm \
-v /tmp/boringssl:/src \
-w /src \
golang:1.26-alpine \
sh -lc 'export PATH=$PATH:/usr/local/go/bin && go build -o /src/acvptool-pinned ./util/fipstools/acvp/acvptool'
```

### 4) Run the expected-output check

```bash
docker run --rm \
-e ACVP_WRAPPER=1 \
-e GODEBUG=fips140=on \
-v "$PWD:/work" \
-v /tmp/boringssl:/tmp/boringssl:ro \
-v /tmp/acvp-testdata:/tmp/acvp-testdata:rw \
-w /tmp/acvp-testdata \
golang:1.26-alpine \
sh -lc 'export PATH=$PATH:/usr/local/go/bin && go run /tmp/boringssl/util/fipstools/acvp/acvptool/test/check_expected.go -tool /tmp/boringssl/acvptool-pinned -module-wrappers go:/work/clickhouse-backup-acvp -tests /work/pkg/acvpwrapper/acvp_test_fips140v1.26.public.config.json'
```

Expected output includes:

- `38 ACVP tests matched expectations`
55 changes: 55 additions & 0 deletions pkg/acvpwrapper/acvp_test_fips140v1.26.public.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
[
{"Wrapper": "go", "In": "vectors/SHA2-224.bz2", "Out": "expected/SHA2-224.bz2"},
{"Wrapper": "go", "In": "vectors/SHA2-256.bz2", "Out": "expected/SHA2-256.bz2"},
{"Wrapper": "go", "In": "vectors/SHA2-384.bz2", "Out": "expected/SHA2-384.bz2"},
{"Wrapper": "go", "In": "vectors/SHA2-512.bz2", "Out": "expected/SHA2-512.bz2"},
{"Wrapper": "go", "In": "vectors/SHA2-512-224.bz2", "Out": "expected/SHA2-512-224.bz2"},
{"Wrapper": "go", "In": "vectors/SHA2-512-256.bz2", "Out": "expected/SHA2-512-256.bz2"},

{"Wrapper": "go", "In": "vectors/SHA3-224.bz2", "Out": "expected/SHA3-224.bz2"},
{"Wrapper": "go", "In": "vectors/SHA3-256.bz2", "Out": "expected/SHA3-256.bz2"},
{"Wrapper": "go", "In": "vectors/SHA3-384.bz2", "Out": "expected/SHA3-384.bz2"},
{"Wrapper": "go", "In": "vectors/SHA3-512.bz2", "Out": "expected/SHA3-512.bz2"},

{"Wrapper": "go", "In": "vectors/SHAKE-128.bz2", "Out": "expected/SHAKE-128.bz2"},
{"Wrapper": "go", "In": "vectors/SHAKE-256.bz2", "Out": "expected/SHAKE-256.bz2"},
{"Wrapper": "go", "In": "vectors/cSHAKE-128.bz2", "Out": "expected/cSHAKE-128.bz2"},
{"Wrapper": "go", "In": "vectors/cSHAKE-256.bz2", "Out": "expected/cSHAKE-256.bz2"},

{"Wrapper": "go", "In": "vectors/HMAC-SHA2-224.bz2", "Out": "expected/HMAC-SHA2-224.bz2"},
{"Wrapper": "go", "In": "vectors/HMAC-SHA2-256.bz2", "Out": "expected/HMAC-SHA2-256.bz2"},
{"Wrapper": "go", "In": "vectors/HMAC-SHA2-384.bz2", "Out": "expected/HMAC-SHA2-384.bz2"},
{"Wrapper": "go", "In": "vectors/HMAC-SHA2-512.bz2", "Out": "expected/HMAC-SHA2-512.bz2"},
{"Wrapper": "go", "In": "vectors/HMAC-SHA2-512-224.bz2", "Out": "expected/HMAC-SHA2-512-224.bz2"},
{"Wrapper": "go", "In": "vectors/HMAC-SHA2-512-256.bz2", "Out": "expected/HMAC-SHA2-512-256.bz2"},

{"Wrapper": "go", "In": "vectors/KDA.bz2", "Out": "expected/KDA.bz2"},

{"Wrapper": "go", "In": "vectors/HMAC-SHA3-224.bz2", "Out": "expected/HMAC-SHA3-224.bz2"},
{"Wrapper": "go", "In": "vectors/HMAC-SHA3-256.bz2", "Out": "expected/HMAC-SHA3-256.bz2"},
{"Wrapper": "go", "In": "vectors/HMAC-SHA3-384.bz2", "Out": "expected/HMAC-SHA3-384.bz2"},
{"Wrapper": "go", "In": "vectors/HMAC-SHA3-512.bz2", "Out": "expected/HMAC-SHA3-512.bz2"},

{"Wrapper": "go", "In": "vectors/PBKDF.bz2", "Out": "expected/PBKDF.bz2"},

{"Wrapper": "go", "In": "vectors/hmacDRBG.bz2", "Out": "expected/hmacDRBG.bz2"},

{"Wrapper": "go", "In": "vectors/ctrDRBG.bz2", "Out": "expected/ctrDRBG.bz2"},

{"Wrapper": "go", "In": "vectors/EDDSA.bz2", "Out": "expected/EDDSA.bz2"},

{"Wrapper": "go", "In": "vectors/ECDSA.bz2", "Out": "expected/ECDSA.bz2"},

{"Wrapper": "go", "In": "vectors/ACVP-AES-CBC.bz2", "Out": "expected/ACVP-AES-CBC.bz2"},
{"Wrapper": "go", "In": "vectors/ACVP-AES-CTR.bz2", "Out": "expected/ACVP-AES-CTR.bz2"},
{"Wrapper": "go", "In": "vectors/ACVP-AES-GCM.bz2", "Out": "expected/ACVP-AES-GCM.bz2"},

{"Wrapper": "go", "In": "vectors/CMAC-AES.bz2", "Out": "expected/CMAC-AES.bz2"},

{"Wrapper": "go", "In": "vectors/TLS-v1.2.bz2", "Out": "expected/TLS-v1.2.bz2"},
{"Wrapper": "go", "In": "vectors/TLS-v1.3.bz2", "Out": "expected/TLS-v1.3.bz2"},

{"Wrapper": "go", "In": "vectors/kdf-components.bz2", "Out": "expected/kdf-components.bz2"},

{"Wrapper": "go", "In": "vectors/RSA.bz2", "Out": "expected/RSA.bz2"}
]
8 changes: 8 additions & 0 deletions pkg/acvpwrapper/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Package acvpwrapper implements ACVP module-wrapper protocol handlers that
// are embedded into the clickhouse-backup binary.
//
// Files are split by concern:
// - wrapper.go: base modulewrapper command set and protocol loop.
// - official_compat.go: shared command handlers modeled after Go fips140test
// behavior where public APIs allow.
package acvpwrapper
Loading
Loading