{"record":{"id":"e84e8534f64540d5","repo":"gchq/CyberChef","slug":"invalid-iv-length-iv-length-bytes-sm4-uses-an","errorCode":null,"errorMessage":"Invalid IV length: ${iv.length} bytes\n\nSM4 uses an IV length of 16 bytes (128 bits).\nMake sure you have specified the type correctly (e.g. Hex vs UTF8).","messagePattern":"Invalid IV length: (.+?) bytes\n\nSM4 uses an IV length of 16 bytes \\(128 bits\\)\\.\nMake sure you have specified the type correctly \\(e\\.g\\. Hex vs UTF8\\)\\.","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/SM4Decrypt.mjs","lineNumber":76,"sourceCode":"        ];\n    }\n\n    /**\n     * @param {string} input\n     * @param {Object[]} args\n     * @returns {string}\n     */\n    run(input, args) {\n        const key = Utils.convertToByteArray(args[0].string, args[0].option),\n            iv = Utils.convertToByteArray(args[1].string, args[1].option),\n            [,, mode, inputType, outputType] = args;\n\n        if (key.length !== 16)\n            throw new OperationError(`Invalid key length: ${key.length} bytes\n\nSM4 uses a key length of 16 bytes (128 bits).`);\n        if (iv.length !== 16 && !mode.startsWith(\"ECB\"))\n            throw new OperationError(`Invalid IV length: ${iv.length} bytes\n\nSM4 uses an IV length of 16 bytes (128 bits).\nMake sure you have specified the type correctly (e.g. Hex vs UTF8).`);\n\n        input = Utils.convertToByteArray(input, inputType);\n        const output = decryptSM4(input, key, iv, mode.substring(0, 3), mode.endsWith(\"NoPadding\"));\n        return outputType === \"Hex\" ? toHex(output) : Utils.byteArrayToUtf8(output);\n    }\n\n}\n\nexport default SM4Decrypt;\n","sourceCodeStart":58,"sourceCodeEnd":89,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/SM4Decrypt.mjs#L58-L89","documentation":"Thrown by SM4 Decrypt when the IV (decoded via the toggle option) is not 16 bytes AND the cipher mode does not start with 'ECB'. ECB modes do not use an IV, so the check is skipped for them; all other modes (CBC, CFB, OFB, CTR) require a 16-byte IV.","triggerScenarios":"Selecting CBC/CFB/OFB/CTR mode with an IV whose decoded length is not 16, or supplying a 16-byte IV while the toggle is wrong (e.g. hex IV with UTF8 toggle doubles the byte count). Also thrown if the IV field is left empty in a non-ECB mode.","commonSituations":"Format toggle mismatch on the IV field; leaving IV blank when mode is CBC; reusing an 8-byte DES IV; mode set to 'CBC/NoPadding' still requires the IV since it starts with 'CBC'.","solutions":["Provide a 16-byte IV for any non-ECB mode; if using a hex IV, set the toggle to 'Hex' so 32 chars decode to 16 bytes.","If you intentionally want no IV, select an ECB mode (ECB or ECB/NoPadding).","Verify the IV toggle matches the IV string's encoding."],"exampleFix":"// before: IV left empty in CBC mode\nsm4Decrypt.run(ct, [keyArg, {string:\"\", option:\"Hex\"}, \"CBC\", ...])\n// after\nsm4Decrypt.run(ct, [keyArg, {string:\"00112233445566778899aabbccddeeff\", option:\"Hex\"}, \"CBC\", ...])","handlingStrategy":"validation","validationCode":"const iv = Utils.convertToByteArray(ivArg.string, ivArg.option);\nconst isEcb = String(mode).startsWith(\"ECB\");\nif (!isEcb && iv.length !== 16) {\n  throw new Error(`SM4 IV must be 16 bytes for ${mode}, got ${iv.length}`);\n}","typeGuard":"function isSm4IvValid(ivArg, mode) {\n  if (String(mode).startsWith(\"ECB\")) return true;\n  return Utils.convertToByteArray(ivArg.string, ivArg.option).length === 16;\n}","tryCatchPattern":null,"preventionTips":["Use ECB mode if no IV is needed; otherwise supply a 16-byte IV.","Match the IV toggle to the IV encoding."],"tags":["crypto","sm4","cipher","iv","operation","validation"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}