{"record":{"id":"643e53d686516608","repo":"OpenNHP/opennhp","slug":"invalid-key-length-for-sm4-gcm","errorCode":null,"errorMessage":"invalid key length for SM4-GCM","messagePattern":"invalid key length for SM4-GCM","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nhp/core/ztdo/noise.go","lineNumber":116,"sourceCode":"\tcase \"SM4-GCM-64\":\n\t\treturn SM4GCM64Tag, nil\n\tcase \"SM4-GCM-128\":\n\t\treturn SM4GCM128Tag, nil\n\tdefault:\n\t\treturn 0, fmt.Errorf(\"unknown symmetric mode name: %s\", mode)\n\t}\n}\nfunc (mode SymmetricCipherMode) newCipherBlock(key []byte) (cipher.Block, error) {\n\tswitch mode {\n\tcase AES256GCM64Tag, AES256GCM96Tag, AES256GCM104Tag,\n\t\tAES256GCM112Tag, AES256GCM120Tag, AES256GCM128Tag:\n\t\tif len(key) != 32 {\n\t\t\treturn nil, fmt.Errorf(\"invalid key length for AES-256-GCM\")\n\t\t}\n\t\treturn aes.NewCipher(key)\n\tcase SM4GCM64Tag, SM4GCM128Tag:\n\t\tif len(key) < 16 {\n\t\t\treturn nil, fmt.Errorf(\"invalid key length for SM4-GCM\")\n\t\t} else {\n\t\t\tkey = key[:16]\n\t\t}\n\t\treturn sm4.NewCipher(key)\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unsupported mode: %v\", mode)\n\t}\n}\n\nfunc (mode SymmetricCipherMode) Encrypt(key, nonce, plaintext, ad []byte) ([]byte, error) {\n\ttagSize := mode.TagSize()\n\n\tcipherBlock, err := mode.newCipherBlock(key)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\taead, err := cipher.NewGCMWithTagSize(cipherBlock, tagSize)","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/OpenNHP/opennhp/blob/6e04ca5ff03222a699c24205cd4bf8fee9af7ffe/nhp/core/ztdo/noise.go#L98-L134","documentation":"For SM4-GCM modes, newCipherBlock requires a key of at least 16 bytes; shorter keys return this error. Keys longer than 16 bytes are truncated to the first 16 bytes (SM4-128). Raised from Encrypt/Decrypt when an SM4 mode receives an undersized key.","triggerScenarios":"Encrypt or Decrypt invoked on SM4GCM64Tag or SM4GCM128Tag with len(key) < 16 (nhp/core/ztdo/noise.go:116).","commonSituations":"Deriving short keys from passwords without KDF, using 8-byte test keys, passing empty or partially initialized key slices after a failed decode.","solutions":["Supply a key of at least 16 bytes (extra bytes are truncated to the first 16)","Use a proper KDF (HKDF) to expand short secrets to 16+ bytes","Check that key decoding succeeded and the slice is not empty/truncated"],"exampleFix":"// before\nkey := []byte(\"short\") // <16 bytes -> error\n// after\nkey := hkdf.Expand(secret, 16) // or any >=16 byte key","handlingStrategy":"validation","validationCode":"if len(key) < 16 {\n\treturn fmt.Errorf(\"SM4-GCM requires at least a 16-byte key, got %d\", len(key))\n}","typeGuard":null,"tryCatchPattern":"ct, err := mode.Encrypt(key, nonce, plaintext, ad)\nif err != nil {\n\tif strings.Contains(err.Error(), \"invalid key length for SM4-GCM\") {\n\t\t// expand key via KDF to >=16 bytes and retry\n\t}\n\treturn err\n}","preventionTips":["Expand short secrets to 16+ bytes with a KDF","Verify decode success before slicing keys","Note keys longer than 16 bytes are truncated — generate exactly 16-byte keys for determinism"],"tags":["go","crypto","sm4","key-length"],"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"}