{"record":{"id":"e712e010320f4c91","repo":"slackhq/nebula","slug":"pki-use-of-curve25519-is-not-allowed-in-fips-140","errorCode":null,"errorMessage":"pki: use of Curve25519 is not allowed in FIPS 140-only mode","messagePattern":"pki: use of Curve25519 is not allowed in FIPS 140-only mode","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pki.go","lineNumber":250,"sourceCode":"\tcase cert.Version1:\n\t\treturn cs.v1Cert\n\tcase cert.Version2:\n\t\treturn cs.v2Cert\n\t}\n\n\treturn nil\n}\n\n// newCipherSuite builds the noise.CipherSuite for the given curve and cipher.\n// When fips140Enforced is true (FIPS 140-only mode), non-approved algorithms\n// (Curve25519 and ChaChaPoly) are rejected with an error. Callers pass\n// fips140.Enforced() for fips140Enforced.\nfunc newCipherSuite(curve cert.Curve, pkcs11backed bool, cipher string, fips140Enforced bool) (noise.CipherSuite, error) {\n\tvar dhFunc noise.DHFunc\n\tswitch curve {\n\tcase cert.Curve_CURVE25519:\n\t\tif fips140Enforced {\n\t\t\treturn nil, errors.New(\"pki: use of Curve25519 is not allowed in FIPS 140-only mode\")\n\t\t}\n\t\tdhFunc = noise.DH25519\n\tcase cert.Curve_P256:\n\t\tif pkcs11backed {\n\t\t\tdhFunc = noiseutil.DHP256PKCS11\n\t\t} else {\n\t\t\tdhFunc = noiseutil.DHP256\n\t\t}\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unsupported curve: %s\", curve)\n\t}\n\n\tif cipher == \"chachapoly\" {\n\t\tif fips140Enforced {\n\t\t\treturn nil, errors.New(\"pki: use of ChaChaPoly is not allowed in FIPS 140-only mode\")\n\t\t}\n\t\treturn noise.NewCipherSuite(dhFunc, noise.CipherChaChaPoly, noise.HashSHA256), nil\n\t}","sourceCodeStart":232,"sourceCodeEnd":268,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/pki.go#L232-L268","documentation":"newCipherSuite refuses to use Curve25519 as the Noise DH function when FIPS 140-only mode is enforced, because Curve25519 is not an approved primitive under FIPS 140-3. The caller (newCertState) passes fips140Enforced (derived from crypto/fips140.Enforced()) and this check runs before any key exchange is set up.","triggerScenarios":"Starting a node whose certificate/curve configuration selects cert.Curve_CURVE25519 while the process runs with FIPS 140-only mode enabled (e.g. GODEBUG=fips140=only, or FIPS-enforcing environment), so newCipherSuite returns this error at cipher-suite construction time.","commonSituations":"Deploying on FIPS-mandated hosts (RHEL/Fedora FIPS mode, gov clouds) with a default pki config that still uses Curve25519; upgrading a binary with FIPS enforcement newly enabled; copying a non-FIPS config into a FIPS cluster.","solutions":["Switch the pki curve configuration from CURVE25519 to cert.Curve_P256, which is FIPS-approved.","Disable FIPS 140-only mode (remove GODEBUG=fips140=only / disable OS FIPS mode) only if policy permits.","Regenerate/reissue node certificates signed for P256 so handshakes negotiate the compliant curve.","Validate config at startup: fail fast with a clear message when FIPS mode and Curve25519 are combined.","Update fleet provisioning templates so FIPS environments always emit P256 curve settings."],"exampleFix":"// before: config.toml on a FIPS host\npki = { curve = \"CURVE25519\" }\n// after\npki = { curve = \"P256\" }\n// or startup validation:\nif fips140Enforced && curve == cert.Curve_CURVE25519 {\n    return fmt.Errorf(\"config error: curve25519 is not FIPS approved; set pki.curve = P256\")\n}","handlingStrategy":"fallback","validationCode":"// Go: reject unsafe config before starting\nif fips140Enforced && curve == cert.Curve_CURVE25519 {\n    return fmt.Errorf(\"pki.curve CURVE25519 is not allowed in FIPS mode; use P256\")\n}","typeGuard":null,"tryCatchPattern":"cs, err := newCipherSuite(curve, pkcs11backed, cipher, fips140.Enforced())\nif err != nil && strings.Contains(err.Error(), \"Curve25519 is not allowed in FIPS\") {\n    log.Warn(\"falling back to P256 for FIPS compliance\")\n    cs, err = newCipherSuite(cert.Curve_P256, pkcs11backed, cipher, fips140Enforced)\n}\nif err != nil {\n    return err\n}","preventionTips":["Set pki curve to P256 on any FIPS-enforced host before deployment.","Derive the enforced flag from crypto/fips140.Enforced() rather than a manual flag.","Validate the full cipher/curve config against FIPS policy at process start.","Keep separate config templates for FIPS and non-FIPS fleets."],"tags":["fips","crypto","curve25519","noise","pki"],"backgroundTag":"fips-algorithm-not-allowed","analyzedSha":"dd8f660c0ac37903ec4080ca4d3c861ba9342ceb","analyzedAt":"2026-09-03T11:13:55.444Z","contentChangedAt":"2026-09-03T11:13:55.444Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}