gchq/CyberChef · error · OperationError

Invalid IV length: ${iv.length} bytes SM4 uses an IV length

Error message

Invalid IV length: ${iv.length} bytes

SM4 uses an IV length of 16 bytes (128 bits).
Make sure you have specified the type correctly (e.g. Hex vs UTF8).

What it means

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.

Source

Thrown at src/core/operations/SM4Decrypt.mjs:76

        ];
    }

    /**
     * @param {string} input
     * @param {Object[]} args
     * @returns {string}
     */
    run(input, args) {
        const key = Utils.convertToByteArray(args[0].string, args[0].option),
            iv = Utils.convertToByteArray(args[1].string, args[1].option),
            [,, mode, inputType, outputType] = args;

        if (key.length !== 16)
            throw new OperationError(`Invalid key length: ${key.length} bytes

SM4 uses a key length of 16 bytes (128 bits).`);
        if (iv.length !== 16 && !mode.startsWith("ECB"))
            throw new OperationError(`Invalid IV length: ${iv.length} bytes

SM4 uses an IV length of 16 bytes (128 bits).
Make sure you have specified the type correctly (e.g. Hex vs UTF8).`);

        input = Utils.convertToByteArray(input, inputType);
        const output = decryptSM4(input, key, iv, mode.substring(0, 3), mode.endsWith("NoPadding"));
        return outputType === "Hex" ? toHex(output) : Utils.byteArrayToUtf8(output);
    }

}

export default SM4Decrypt;

View on GitHub (pinned to 4290ea7539)

Solutions

  1. 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.
  2. If you intentionally want no IV, select an ECB mode (ECB or ECB/NoPadding).
  3. Verify the IV toggle matches the IV string's encoding.

Example fix

// before: IV left empty in CBC mode
sm4Decrypt.run(ct, [keyArg, {string:"", option:"Hex"}, "CBC", ...])
// after
sm4Decrypt.run(ct, [keyArg, {string:"00112233445566778899aabbccddeeff", option:"Hex"}, "CBC", ...])
Defensive patterns

Strategy: validation

Validate before calling

const iv = Utils.convertToByteArray(ivArg.string, ivArg.option);
const isEcb = String(mode).startsWith("ECB");
if (!isEcb && iv.length !== 16) {
  throw new Error(`SM4 IV must be 16 bytes for ${mode}, got ${iv.length}`);
}

Type guard

function isSm4IvValid(ivArg, mode) {
  if (String(mode).startsWith("ECB")) return true;
  return Utils.convertToByteArray(ivArg.string, ivArg.option).length === 16;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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'.

Related errors


AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13). Data as JSON: /api/errors/e84e8534f64540d5. Report an issue: GitHub.