{"record":{"id":"79b83ddc61f903fc","repo":"OpenNHP/opennhp","slug":"failed-to-create-sm4-cipher-for-cbc-w","errorCode":null,"errorMessage":"failed to create SM4 cipher for CBC: %w","messagePattern":"failed to create SM4 cipher for CBC: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nhp/core/crypto.go","lineNumber":202,"sourceCode":"\t}\n}\n\nfunc CBCEncryption(t GcmTypeEnum, key *[SymmetricKeySize]byte, plaintext []byte, inPlace bool) ([]byte, error) {\n\tvar block cipher.Block\n\tvar iv []byte\n\tvar err error\n\tswitch t {\n\tcase GCM_AES256:\n\t\tblock, err = aes.NewCipher(key[:])\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to create AES cipher for CBC: %w\", err)\n\t\t}\n\t\tiv = key[8:24]\n\n\tcase GCM_SM4:\n\t\tblock, err = sm4.NewCipher(key[:16])\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to create SM4 cipher for CBC: %w\", err)\n\t\t}\n\t\tiv = key[16:]\n\n\tcase GCM_CHACHA20POLY1305:\n\t\treturn nil, ErrNotApplicable\n\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unsupported cipher type for CBC: %d\", t)\n\t}\n\n\tvar paddedPlainText []byte\n\tif len(plaintext)%block.BlockSize() == 0 {\n\t\t// skip padding\n\t\tpaddedPlainText = plaintext\n\t} else {\n\t\tpkcs7 := padding.NewPKCS7Padding(uint(block.BlockSize()))\n\t\tpaddedPlainText = pkcs7.Pad(plaintext)\n\t}","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/OpenNHP/opennhp/blob/6e04ca5ff03222a699c24205cd4bf8fee9af7ffe/nhp/core/crypto.go#L184-L220","documentation":"CBCEncryption(GCM_SM4, key, ...) wraps sm4.NewCipher(key[:16]) failure as this message. gmsm's sm4.NewCipher fails only for key lengths other than 16 bytes; because OpenNHP slices the first 16 bytes of the fixed 32-byte key array, failure implies malformed/nil key material or a non-standard gmsm dependency. It occurs while initializing the SM4-CBC block cipher (IV from key[16:]).","triggerScenarios":"Calling CBCEncryption with GCM_SM4 and a nil pointer or improperly sized array (e.g. via unsafe casts), or after gmsm library changes to NewCipher semantics; not triggerable with correct 32-byte key arrays.","commonSituations":"GMSM-scheme bulk encryption paths where the SM2 key exchange silently failed leaving a zeroed key; custom code constructing shorter key buffers; pinning an incompatible emmansun/gmsm version.","solutions":["Ensure the SM2 ECDH/KDF step fully populated the 32-byte key before calling CBCEncryption","Log the wrapped error to capture sm4.NewCipher's underlying key-length message","Pin a known-good github.com/emmansun/gmsm version and run go mod tidy","Add a caller-side check that the key is non-zero before encryption","Verify with go test ./nhp/core/... (TestGMSharedKey covers SM4 paths)"],"exampleFix":"// before\nshared := sm2Ecdh.SharedSecret(peerPub) // empty on failed exchange\nciphertext, _ := core.CBCEncryption(core.GCM_SM4, (*[core.SymmetricKeySize]byte)(shared), plaintext, false)\n// after\nshared := sm2Ecdh.SharedSecret(peerPub)\nif len(shared) == 0 {\n    return errors.New(\"SM2 key exchange failed: empty shared secret\")\n}\nvar key [core.SymmetricKeySize]byte\nutils.Memcpy(key[:], kdf(shared))\nciphertext, err := core.CBCEncryption(core.GCM_SM4, &key, plaintext, false)\nif err != nil {\n    return fmt.Errorf(\"sm4 cbc encrypt: %w\", err)\n}","handlingStrategy":"validation","validationCode":"if key == nil {\n    return errors.New(\"SM4-CBC key not initialized\")\n}\nif len(sharedSecret) == 0 {\n    return errors.New(\"empty shared secret - SM2 key exchange failed\")\n}","typeGuard":null,"tryCatchPattern":"ciphertext, err := core.CBCEncryption(core.GCM_SM4, &key, plaintext, false)\nif err != nil {\n    if errors.Is(err, core.ErrNotApplicable) {\n        return errors.New(\"SM4-CBC not applicable for this cipher type\")\n    }\n    return fmt.Errorf(\"SM4-CBC encrypt failed: %w\", err)\n}","preventionTips":["Verify the SM2 ECDH exchange produced a non-empty shared secret before CBC encryption","Use the GMSM suite consistently via NewCipherSuite(common.CIPHER_SCHEME_GMSM)","Pin a tested github.com/emmansun/gmsm version","Note CBC derives its IV directly from key[16:] — never pass short keys"],"tags":["crypto","sm4","cbc","gmsm"],"backgroundTag":"invalid-argument-value","analyzedSha":"6e04ca5ff03222a699c24205cd4bf8fee9af7ffe","analyzedAt":"2026-09-07T15:44:59.941Z","contentChangedAt":"2026-09-07T15:44:59.941Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}