slackhq/nebula · error

use of Curve25519 is not allowed in FIPS 140-only mode

Error message

use of Curve25519 is not allowed in FIPS 140-only mode

What it means

In cmd/nebula-cert/keygen.go (keygen), selecting any Curve25519 alias while fips140.Enforced() is true makes the command fail immediately instead of calling x25519Keypair(). FIPS 140-only mode forbids non-validated primitives, so X25519 keypair generation is rejected.

Source

Thrown at cmd/nebula-cert/keygen.go:67

	}
	if err = mustFlagString("out-pub", cf.outPubPath); err != nil {
		return err
	}

	var pub, rawPriv []byte
	var curve cert.Curve
	if isP11 {
		switch *cf.curve {
		case "P256":
			curve = cert.Curve_P256
		default:
			return fmt.Errorf("invalid curve for PKCS#11: %s", *cf.curve)
		}
	} else {
		switch *cf.curve {
		case "25519", "X25519", "Curve25519", "CURVE25519":
			if fips140.Enforced() {
				return errors.New("use of Curve25519 is not allowed in FIPS 140-only mode")
			}
			pub, rawPriv = x25519Keypair()
			curve = cert.Curve_CURVE25519
		case "P256":
			pub, rawPriv = p256Keypair()
			curve = cert.Curve_P256
		default:
			return fmt.Errorf("invalid curve: %s", *cf.curve)
		}
	}

	var claims ioClaims
	if err := reserveOutputs(&claims,
		"out-key", *cf.outKeyPath,
		"out-pub", *cf.outPubPath,
	); err != nil {
		return err
	}

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Regenerate keys with an approved curve: nebula-cert keygen -curve P256.
  2. Disable FIPS 140-only mode if policy allows (unset fips140=only GODEBUG / non-FIPS binary).
  3. Use PKCS#11 hardware tokens that provide a FIPS-validated key generation path.
  4. Align deployment configs so the declared curve matches FIPS requirements.

Example fix

// before
$ nebula-cert keygen -curve 25519 -out-key node.key -out-pub node.pub

// after
$ nebula-cert keygen -curve P256 -out-key node.key -out-pub node.pub
Defensive patterns

Strategy: validation

Validate before calling

if fips140.Enforced() && strings.EqualFold(strings.TrimPrefix(strings.ToLower(cf.curve), "curve"), "25519") {
    return errors.New("keygen: select -curve P256 under FIPS 140-only mode")
}

Type guard

func isCurve25519Alias(c string) bool {
    switch c {
    case "25519", "X25519", "Curve25519", "CURVE25519":
        return true
    }
    return false
}

Try / catch

out, err := exec.Command("nebula-cert", "keygen", "-curve", curve).CombinedOutput()
if err != nil && strings.Contains(string(out), "FIPS 140-only") {
    out, err = exec.Command("nebula-cert", "keygen", "-curve", "P256").CombinedOutput()
}

Prevention

When it happens

Trigger: Running 'nebula-cert keygen -curve 25519/X25519/Curve25519/CURVE25519' on a FIPS 140-enforced build/environment (keygen.go:67 check).

Common situations: Automation scripts generating node keys on FIPS-hardened hosts; teams standardizing on 25519 hitting FIPS policy on new infrastructure.

Related errors


AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03). Data as JSON: /api/errors/ccf6aa689bef1ffb. Report an issue: GitHub.