OpenNHP/opennhp · error
failed to create AES cipher
Error message
failed to create AES cipher: %w
What it means
AeadFromKey(GCM_AES256, key) wraps the error from aes.NewCipher(key[:]) when the key material cannot form an AES block cipher. Go's crypto/aes only fails when the key length is not 16, 24, or 32 bytes; since key is a *[SymmetricKeySize]byte (32 bytes), this error indicates the caller supplied a nil pointer, mis-sized buffer, or corrupted key derivation. It is a programming/key-derivation bug signal, not a runtime network condition.
Solutions
- Ensure the key array is fully populated by a successful ECDH/SharedSecret + KDF before calling AeadFromKey
- Check the wrapped error — with a fixed-size array it points to dependency-level or pointer-level problems
- Verify SymmetricKeySize is 32 (AES-256) and unchanged in your build
- Add a caller-side assert that the key is non-zero before use
- Run the cipher-suite tests (go test ./nhp/core/...) to reproduce with known-good keys
Example fix
// before
key := &[core.SymmetricKeySize]byte{}
aead, err := core.AeadFromKey(core.GCM_AES256, key)
// after
shared := ecdh.SharedSecret(peerPub)
if len(shared) == 0 {
return errors.New("key exchange produced empty shared secret")
}
var key [core.SymmetricKeySize]byte
utils.Memcpy(key[:], kdf(shared))
aead, err := core.AeadFromKey(core.GCM_AES256, &key)
if err != nil {
return fmt.Errorf("aead init: %w", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
if key == nil {
return errors.New("symmetric key not initialized")
}
if core.SymmetricKeySize != 16 && core.SymmetricKeySize != 24 && core.SymmetricKeySize != 32 {
return fmt.Errorf("SymmetricKeySize %d is not a valid AES key length", core.SymmetricKeySize)
} Try / catch
aead, err := core.AeadFromKey(core.GCM_AES256, &key)
if err != nil {
return fmt.Errorf("AES-GCM setup failed: %w", err)
}
// use aead.Seal / aead.Open only after this succeeds Prevention
- Complete ECDH + KDF before constructing any AEAD
- Never construct the key array from arbitrary-length slices
- Keep SymmetricKeySize at 32 and check after dependency upgrades
- Cover AeadFromKey with unit tests using known-good keys
When it happens
Trigger: Calling AeadFromKey with a *[SymmetricKeySize]byte that was never filled (all code paths normally pass exactly 32 bytes), or future refactors that change SymmetricKeySize to a non-AES-legal length, or passing a key derived from an ECDH shared-secret routine that returned garbage/empty data.
Common situations: A key-exchange step silently failed earlier and left the symmetric key zero-length or mis-sized; custom code constructs the array via unsafe casting of a shorter byte slice; tests exercising GCM with a stubbed key.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- failed to create AES-GCM
- failed to create AES cipher for CBC
- failed to create AES cipher for CBC decryption
- failed to create SM4 cipher
- failed to create SM4-GCM
AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07).
Data as JSON: /api/errors/b54fd115401c348c.
Report an issue: GitHub.
Appendix: source
Thrown at nhp/core/crypto.go:156
func NewECDH(t EccTypeEnum) (e Ecdh) {
switch t {
case ECC_CURVE25519:
e = curve.NewECDH()
case ECC_SM2:
e = gmsm.NewECDH()
}
return e
}
func AeadFromKey(t GcmTypeEnum, key *[SymmetricKeySize]byte) (cipher.AEAD, error) {
switch t {
case GCM_AES256:
aesBlock, err := aes.NewCipher(key[:])
if err != nil {
return nil, fmt.Errorf("failed to create AES cipher: %w", err)
}
aead, err := cipher.NewGCM(aesBlock)
if err != nil {
return nil, fmt.Errorf("failed to create AES-GCM: %w", err)
}
return aead, nil
case GCM_SM4:
sm4Block, err := sm4.NewCipher(key[:16])
if err != nil {
return nil, fmt.Errorf("failed to create SM4 cipher: %w", err)
}
aead, err := cipher.NewGCM(sm4Block)
if err != nil {
return nil, fmt.Errorf("failed to create SM4-GCM: %w", err)
}
return aead, nil
View on GitHub (pinned to 6e04ca5ff0)