gchq/CyberChef · error · OperationError

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

Error message

Invalid IV length: ${iv.length} bytes

XTEA uses an IV length of ${TEA_BLOCK_SIZE} bytes (${TEA_BLOCK_SIZE * 8} bits).
Make sure you have specified the type correctly (e.g. Hex vs UTF8).

What it means

Thrown by XTEAEncrypt.run when the IV is not the TEA block size, not zero, and mode is not ECB. Mirrors the decrypt guard: empty IV is allowed (auto zero-padded), ECB ignores it, and all other modes need an 8-byte IV.

Source

Thrown at src/core/operations/XTEAEncrypt.mjs:90

    /**
     * @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, padding, rounds] = args;

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

XTEA requires a key length of 16 bytes (128 bits).
Make sure you have specified the type correctly (e.g. Hex vs UTF8).`);

        if (iv.length !== TEA_BLOCK_SIZE && iv.length !== 0 && mode !== "ECB")
            throw new OperationError(`Invalid IV length: ${iv.length} bytes

XTEA uses an IV length of ${TEA_BLOCK_SIZE} bytes (${TEA_BLOCK_SIZE * 8} bits).
Make sure you have specified the type correctly (e.g. Hex vs UTF8).`);

        if (!Number.isInteger(rounds) || rounds < 1 || rounds > 255)
            throw new OperationError(`Invalid number of rounds: ${rounds}

Rounds must be an integer between 1 and 255. Standard XTEA uses 32 rounds.`);

        // Default IV to null bytes if empty (like AES)
        const actualIv = iv.length === 0 ? new Array(TEA_BLOCK_SIZE).fill(0) : iv;

        input = Utils.convertToByteArray(input, inputType);
        const output = encryptXTEA(input, key, actualIv, mode, padding, rounds);
        return outputType === "Hex" ? toHex(output, "") : Utils.byteArrayToUtf8(output);
    }

}

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Provide an 8-byte IV (16 hex chars) for CBC/CFB/OFB modes.
  2. Leave IV empty to auto-zero-pad.
  3. Set mode to 'ECB' when you have no IV.
  4. Keep the IV format option consistent with the IV encoding.

Example fix

// before
args:[key,{string:"<32 hex>",option:"Hex"}, "CBC", ...]
// after
args:[key,{string:"<16 hex>",option:"Hex"}, "CBC", ...]
Defensive patterns

Strategy: validation

Validate before calling

function xteaIvRecipe(ivStr, ivOption, mode) {
  if (mode === "ECB") return {string:ivStr, option:ivOption};
  const iv = Utils.convertToByteArray(ivStr, ivOption);
  if (iv.length !== 0 && iv.length !== 8) throw new Error("IV must be 8 bytes or empty");
  return {string:ivStr, option:ivOption};
}

Type guard

const isValidXteaIv = (bytes, mode) => mode === "ECB" || bytes.length === 0 || bytes.length === 8;

Try / catch

try { chef.bake(data, recipe); } catch (e) { if (/Invalid IV length/.test(e.message) && /XTEA/.test(e.message)) { /* fix iv */ } else throw e; }

Prevention

When it happens

Trigger: A non-zero IV whose length != TEA_BLOCK_SIZE (8) is supplied while mode is not ECB. Common: a 16-byte AES IV reused for XTEA CBC.

Common situations: Cross-cipher IV reuse; ECB/CBC mode mismatch between the encryption recipe and the decrypting party; IV format option mismatch.

Related errors


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