opentelemetry-collector icon indicating copy to clipboard operation
opentelemetry-collector copied to clipboard

[fips140] `config/configtls.TestTPM_loadCertificate` unit test fails with `GODEBUG=fips140=only`

Open ycombinator opened this issue 1 month ago • 4 comments
trafficstars

Component(s)

No response

Describe the issue you're reporting

Running the config/configtls.TestTPM_loadCertificate unit test with GODEBUG=fips140=only exposes any calls (direct or indirect) to non-FIPS140-compliant algorithms.

Such calls may be made by the test's code or from collector code exercised by the test. Also, the calls may be true positives or false positives (e.g. using md5, which is not FIPS140-compliant for cryptographic uses, in a non-cryptographic context, e.g. hashing for checksums). Depending on where the calls are being made from (test code or collector code) and whether they're true or false positives, we may need to either a) provide an alternative implementation — using the requirefips build tag — for the calls with ones to FIPS-compliant algorithms, b) skip the test when GODEBUG=fips140=only (should be done only if the calls are being made from the test code itself), or c) disable the code paths leading to the calls when the module is built with the requirefips build tag and document this (least preferred option).

Related to https://github.com/open-telemetry/opentelemetry-collector/issues/13925 and https://github.com/open-telemetry/opentelemetry-collector/pull/13926.

Steps to reproduce

  1. Make sure OS is Linux and Go version is >= 1.24.6.
    $ go version
    go version go1.25.0 linux/arm64
    
  2. Run the configtls.TestTPM_loadCertificate unit test with GODEBUG=fips140=only.
    $ cd config/configtls/
    $ GODEBUG=fips140=only go test ./... -test.run TestTPM_loadCertificate
    

Observed output

--- FAIL: TestTPM_loadCertificate (0.00s)
panic: crypto/cipher: use of CFB is not allowed in FIPS 140-only mode [recovered, repanicked]

goroutine 7 [running]:
testing.tRunner.func1.2({0x6d3ea0, 0x7cd050})
	/usr/local/go/src/testing/testing.go:1872 +0x190
testing.tRunner.func1()
	/usr/local/go/src/testing/testing.go:1875 +0x31c
panic({0x6d3ea0?, 0x7cd050?})
	/usr/local/go/src/runtime/panic.go:783 +0x120
crypto/cipher.NewCFBEncrypter(...)
	/usr/local/go/src/crypto/cipher/cfb.go:65
github.com/google/go-tpm/tpm2.(*hmacSession).Encrypt(0x40000d0300, {0x40001c4802, 0x4, 0x3e})
	/home/shaunak/go/pkg/mod/github.com/google/[email protected]/tpm2/sessions.go:634 +0x26c
github.com/google/go-tpm/tpm2.cmdParameters[...]({0x7d0a38, 0x400019bc70}, {0x4000079c20, 0x2, 0x0})
	/home/shaunak/go/pkg/mod/github.com/google/[email protected]/tpm2/reflect.go:882 +0x21c
github.com/google/go-tpm/tpm2.execute[...]({0xffff619c1e20, 0x4000022c10}, {0x7d0a38, 0x400019bc70}, 0x4000198240, {0x4000026d18, 0x1, 0x4000026b80})
	/home/shaunak/go/pkg/mod/github.com/google/[email protected]/tpm2/reflect.go:49 +0x244
github.com/google/go-tpm/tpm2.Create.Execute({{0x7d06c0, 0x40001bba10}, {0x0}, {0x400002e960, {0x0, 0x0, 0x0}}, {{}, {0x0, 0x0, ...}}, ...}, ...)
	/home/shaunak/go/pkg/mod/github.com/google/[email protected]/tpm2/tpm2.go:193 +0x8c
github.com/foxboron/go-tpm-keyfiles.createKeyWithHandle(0x4000026df0, {0x80000000, {{}, {0x400001e5a0, 0x22, 0x22}}, {0x7d3958, 0x40000105b8}}, 0x0?, 0x100, ...)
	/home/shaunak/go/pkg/mod/github.com/foxboron/[email protected]/tpm.go:575 +0x64c
github.com/foxboron/go-tpm-keyfiles.NewLoadableKeyWithResponse({0x7d0ab0?, 0x4000022c10?}, 0x23, 0x100, {0xa54500, 0x0, 0x0}, {0x0?, 0x0?, 0x0?})
	/home/shaunak/go/pkg/mod/github.com/foxboron/[email protected]/loadablekey.go:31 +0x138
github.com/foxboron/go-tpm-keyfiles.NewLoadableKey(...)
	/home/shaunak/go/pkg/mod/github.com/foxboron/[email protected]/loadablekey.go:15
go.opentelemetry.io/collector/config/configtls.createTPMKeyCert(0x40000a6a80, {0x7d0ab0, 0x4000022c10})
	/home/shaunak/development/github/opentelemetry-collector/config/configtls/tpm_test.go:191 +0x60
go.opentelemetry.io/collector/config/configtls.TestTPM_loadCertificate(0x40000a6a80)
	/home/shaunak/development/github/opentelemetry-collector/config/configtls/tpm_test.go:41 +0xbc
testing.tRunner(0x40000a6a80, 0x76b4f0)
	/usr/local/go/src/testing/testing.go:1934 +0xc8
created by testing.(*T).Run in goroutine 1
	/usr/local/go/src/testing/testing.go:1997 +0x364
FAIL	go.opentelemetry.io/collector/config/configtls	0.009s
FAIL

Tip

React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding +1 or me too, to help us triage it. Learn more here.

ycombinator avatar Oct 10 '25 05:10 ycombinator

In this case, the call in question is made exclusively from test code, specifically over here: https://github.com/open-telemetry/opentelemetry-collector/blob/0f3b0c974e235da85282c6d6ff5734e55e8f4fbc/config/configtls/tpm_test.go#L191

I don't see this call being made from anywhere else in the collector core code.

The fix will need to be made in https://github.com/google/go-tpm, replacing calls to cipher.NewCFBEncrypter with cipher.NewCTR instead.

ycombinator avatar Oct 24 '25 16:10 ycombinator

The fix will need to be made in https://github.com/google/go-tpm, replacing calls to cipher.NewCFBEncrypter with cipher.NewCTR instead.

I tried to make this fix locally and using the replace directive for this module to point to my local one. The TestTPM_loadCertificate unit test now fails like so:

--- FAIL: TestTPM_loadCertificate (0.00s)
    tpm_test.go:224:
        	Error Trace:	/home/shaunak/development/github/opentelemetry-collector/config/configtls/tpm_test.go:224
        	            				/home/shaunak/development/github/opentelemetry-collector/config/configtls/tpm_test.go:41
        	Error:      	Received unexpected error:
        	            	failed getting handle: TPM_RC_INTEGRITY (parameter 1): integrity check failed
        	Test:       	TestTPM_loadCertificate

I'm unfamiliar with TPM. @pavolloffay, I see you added this test and associated helper code in #12801. Would you able to advise how to resolve this error? Thanks!

ycombinator avatar Oct 24 '25 17:10 ycombinator

An alternative to resolving would be to simply skip TestTPM_loadCertificate when GODEBUG=fips140=only is set (similar to what we're doing in https://github.com/open-telemetry/opentelemetry-collector/pull/14076) since the FIPS violation surfaced by this test is from the test code itself (as opposed to from OpenTelemetry Collector core code that the test is exercising).

ycombinator avatar Oct 24 '25 19:10 ycombinator

@ycombinator I am not sure why it is failing with the fips flag. Did you try changing the parameters in the createTPMKeyCert func to use FIPS compliant https://github.com/open-telemetry/opentelemetry-collector/blob/main/config/configtls/tpm_test.go#L190C6-L190C22 ?

pavolloffay avatar Nov 04 '25 18:11 pavolloffay