{"record":{"id":"5e4e627deba6fac0","repo":"gchq/CyberChef","slug":"invalid-iv-length-iv-length-bytes-sm4-uses-an-5e4e62","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/SM4Encrypt.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 = encryptSM4(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 SM4Encrypt;\n","sourceCodeStart":58,"sourceCodeEnd":89,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/SM4Encrypt.mjs#L58-L89","documentation":"Thrown by SM4 Encrypt when the decoded IV is not 16 bytes and the mode does not start with 'ECB'. ECB and ECB/NoPadding skip this check; CBC, CFB, OFB, CTR, and CBC/NoPadding all require a 16-byte IV.","triggerScenarios":"A non-ECB mode combined with an IV whose decoded length is not 16, or an empty IV field. Toggle mismatch (hex IV read as UTF8) is the most frequent cause.","commonSituations":"Forgetting the IV for CBC encryption; wrong toggle on the IV; reusing an IV from a different cipher; CBC/NoPadding mode still needing an IV.","solutions":["Supply a 16-byte IV for non-ECB modes; set the toggle correctly (Hex for hex IVs).","Use an ECB mode if no IV is intended.","Verify IV toggle matches IV encoding."],"exampleFix":"// before\nsm4Encrypt.run(pt, [keyArg, {string:\"\", option:\"Hex\"}, \"CBC\", ...])\n// after\nsm4Encrypt.run(pt, [keyArg, {string:\"00112233445566778899aabbccddeeff\", option:\"Hex\"}, \"CBC\", ...])","handlingStrategy":"validation","validationCode":"const iv = Utils.convertToByteArray(ivArg.string, ivArg.option);\nif (!String(mode).startsWith(\"ECB\") && iv.length !== 16) {\n  throw new Error(`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":["Provide a 16-byte IV for non-ECB modes; pick ECB to omit the IV.","Verify the IV toggle matches the 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"}