OpenNHP/opennhp · error
failed to create AES cipher for CBC
Error message
failed to create AES cipher for CBC: %w
What it means
CBCEncryption(GCM_AES256, key, ...) wraps aes.NewCipher(key[:]) failure as this message. As with the AEAD path, Go's aes.NewCipher only fails for key lengths other than 16/24/32 bytes; with the fixed 32-byte SymmetricKeySize array this is practically unreachable and points to nil/misformed key material or dependency issues. It occurs while setting up the AES-CBC block cipher (AES-256, IV taken from key[8:24]).
Solutions
- Populate the key array completely via a successful key-exchange/KDF before calling CBCEncryption
- Check the wrapped error for the underlying key-length complaint
- Keep SymmetricKeySize at 32 (or another AES-legal 16/24/32) and re-verify all call sites after any resize
- Remember ChaCha20-Poly1305 returns ErrNotApplicable for CBC — route those callers to an AEAD function instead
Example fix
// before
var key [core.SymmetricKeySize]byte // never filled
ciphertext, _ := core.CBCEncryption(core.GCM_AES256, &key, plaintext, false)
// after
shared := ecdh.SharedSecret(peerPub)
var key [core.SymmetricKeySize]byte
utils.Memcpy(key[:], kdf(shared))
ciphertext, err := core.CBCEncryption(core.GCM_AES256, &key, plaintext, false)
if err != nil {
return fmt.Errorf("cbc encrypt: %w", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
if key == nil {
return errors.New("CBC key not initialized")
}
if core.SymmetricKeySize != 16 && core.SymmetricKeySize != 24 && core.SymmetricKeySize != 32 {
return fmt.Errorf("SymmetricKeySize %d invalid for AES-CBC", core.SymmetricKeySize)
} Try / catch
ciphertext, err := core.CBCEncryption(core.GCM_AES256, &key, plaintext, false)
if err != nil {
if errors.Is(err, core.ErrNotApplicable) {
return errors.New("CBC not available for this cipher - use AEAD")
}
return fmt.Errorf("AES-CBC encrypt failed: %w", err)
} Prevention
- Complete key derivation before bulk CBC encryption
- Keep SymmetricKeySize at an AES-legal length (16/24/32)
- Use AEAD (AeadFromKey) for new code; CBC is legacy path with static IV from the key
When it happens
Trigger: Calling CBCEncryption with a nil *[SymmetricKeySize]byte, an under-filled key array, or after changing SymmetricKeySize to a value that is not 16/24/32; also via dependency corruption.
Common situations: Custom bulk-encryption code paths (e.g. DHP payload encryption) that receive a key before the ECDH/KDF step completed; refactors resizing SymmetricKeySize; forks altering the crypto stack.
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 cipher
- failed to create AES cipher for CBC decryption
- failed to create AES-GCM
- failed to create ChaCha20-Poly1305
- failed to create SM4 cipher for CBC
AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07).
Data as JSON: /api/errors/8d3fdfdf39a3d63f.
Report an issue: GitHub.
Appendix: source
Thrown at nhp/core/crypto.go:195
if err != nil {
return nil, fmt.Errorf("failed to create ChaCha20-Poly1305: %w", err)
}
return aead, nil
default:
return nil, fmt.Errorf("unsupported GCM type: %d", t)
}
}
func CBCEncryption(t GcmTypeEnum, key *[SymmetricKeySize]byte, plaintext []byte, inPlace bool) ([]byte, error) {
var block cipher.Block
var iv []byte
var err error
switch t {
case GCM_AES256:
block, err = aes.NewCipher(key[:])
if err != nil {
return nil, fmt.Errorf("failed to create AES cipher for CBC: %w", err)
}
iv = key[8:24]
case GCM_SM4:
block, err = sm4.NewCipher(key[:16])
if err != nil {
return nil, fmt.Errorf("failed to create SM4 cipher for CBC: %w", err)
}
iv = key[16:]
case GCM_CHACHA20POLY1305:
return nil, ErrNotApplicable
default:
return nil, fmt.Errorf("unsupported cipher type for CBC: %d", t)
}
var paddedPlainText []byteView on GitHub (pinned to 6e04ca5ff0)