golang/go · error

crypto/ed25519: only crypto/rand.Reader is allowed in FIPS 1

Error message

crypto/ed25519: only crypto/rand.Reader is allowed in FIPS 140-only mode

What it means

Thrown by ed25519.GenerateKey (ed25519.go:164) when FIPS 140-only mode is active and the supplied random reader is not the approved crypto/rand.Reader (fips140only.ApprovedRandomReader returns false). FIPS 140 requires entropy from the approved DRBG/cryptorand.Reader; custom or testing readers are rejected.

Source

Thrown at src/crypto/ed25519/ed25519.go:164

// restored with GODEBUG=cryptocustomrand=1. This setting will be removed in a
// future Go release. Instead, use [testing/cryptotest.SetGlobalRandom].)
//
// The output of this function is deterministic, and equivalent to reading
// [SeedSize] bytes from random, and passing them to [NewKeyFromSeed].
func GenerateKey(random io.Reader) (PublicKey, PrivateKey, error) {
	if random == nil {
		if cryptocustomrand.Value() == "1" {
			random = cryptorand.Reader
			if !rand.IsDefaultReader(random) {
				cryptocustomrand.IncNonDefault()
			}
		} else {
			random = rand.Reader
		}
	}

	if fips140only.Enforced() && !fips140only.ApprovedRandomReader(random) {
		return nil, nil, errors.New("crypto/ed25519: only crypto/rand.Reader is allowed in FIPS 140-only mode")
	}

	if rand.IsDefaultReader(random) {
		privateKey, err := ed25519.GenerateKey()
		if err != nil {
			return nil, nil, err
		}
		publicKey := PublicKey(privateKey.PublicKey())
		return publicKey, PrivateKey(privateKey.Bytes()), nil
	}

	seed := make([]byte, SeedSize)
	if _, err := io.ReadFull(random, seed); err != nil {
		return nil, nil, err
	}

	privateKey := NewKeyFromSeed(seed)
	publicKey := privateKey.Public().(PublicKey)

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Pass crypto/rand.Reader (or nil, which resolves to the default reader) for key generation under FIPS builds.
  2. For deterministic test keys, use testing/cryptotest.SetGlobalRandom instead of injecting a custom reader, or gate the test reader behind !fips140only.Enforced().
  3. Ensure no reader-wrapping layer sits between your code and crypto/rand.Reader in FIPS builds.

Example fix

// before
reader := mathrand.New(mathrand.NewSource(1)) // not approved
pub, priv, err := ed25519.GenerateKey(reader, reader) // FIPS-only -> error 250

// after
pub, priv, err := ed25519.GenerateKey(nil, nil) // uses crypto/rand.Reader
Defensive patterns

Strategy: validation

Validate before calling

if fips140only.Enforced() && !fips140only.ApprovedRandomReader(random) {
    return errors.New("only crypto/rand.Reader is allowed in FIPS 140-only mode")
}

Prevention

When it happens

Trigger: Calling ed25519.GenerateKey(rand.Reader, nonDefaultReader) — passing a deterministic test reader, math/rand, or a wrapped reader — while FIPS 140-only is enforced. fips140only.ApprovedRandomReader(random) must be true to proceed.

Common situations: Tests that inject a deterministic reader for reproducibility; code that wraps rand.Reader for logging/metering; enabling FIPS mode without auditing all GenerateKey call sites. GODEBUG=cryptocustomrand=1 also interacts here.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/df8a32b3dc474296. Report an issue: GitHub.