gchq/CyberChef · error · OperationError
Invalid block cipher mode: ${mode}
Error message
Invalid block cipher mode: ${mode} What it means
Thrown by encryptTwofish() in Twofish.mjs (the encrypt switch `default` branch) when `mode` is not one of ECB, CBC, CFB, OFB, CTR. After padding is applied (for ECB/CBC) the function dispatches on mode; an unknown value is rejected rather than encrypting under an unspecified behaviour. Note the pad-then-dispatch ordering means a bad mode still triggers padding work first.
Source
Thrown at src/core/lib/Twofish.mjs:514
const block = paddedMessage.slice(i, i + BLOCKSIZE);
cipherText.push(...xorBlocks(ivBlock, block));
}
return cipherText.slice(0, messageLength);
}
case "CTR": {
let counter = [...iv];
for (let i = 0; i < paddedMessage.length; i += BLOCKSIZE) {
const encrypted = encryptBlock(counter, keyData);
const block = paddedMessage.slice(i, i + BLOCKSIZE);
cipherText.push(...xorBlocks(encrypted, block));
counter = incrementCounter(counter);
}
return cipherText.slice(0, messageLength);
}
default:
throw new OperationError(`Invalid block cipher mode: ${mode}`);
}
return cipherText;
}
/**
* Decrypt using Twofish cipher with specified block mode
*
* @param {number[]} cipherText - Ciphertext as byte array
* @param {number[]} key - Key (16, 24, or 32 bytes)
* @param {number[]} iv - IV (16 bytes, not used for ECB)
* @param {string} mode - Block cipher mode ("ECB", "CBC", "CFB", "OFB", "CTR")
* @param {string} padding - Padding type ("NO", "PKCS5", "ZERO", "RANDOM", "BIT")
* @returns {number[]} - Plaintext as byte array
*/
export function decryptTwofish(cipherText, key, iv, mode = "ECB", padding = "PKCS5") {
const originalLength = cipherText.length;
if (originalLength === 0) return [];View on GitHub (pinned to 4290ea7539)
Solutions
- Pass one of the exactly-cased supported modes: "ECB", "CBC", "CFB", "OFB", "CTR".
- Normalise the value (trim + toUpperCase) and validate against the whitelist before calling encryptTwofish.
- If you need an AEAD mode like GCM, Twofish is not implemented here — use a different cipher or library.
Example fix
// before encryptTwofish(msg, key, iv, "gcm", "PKCS5"); // after encryptTwofish(msg, key, iv, "CTR", "PKCS5");
Defensive patterns
Strategy: validation
Validate before calling
const MODES = ["ECB", "CBC", "CFB", "OFB", "CTR"];
const safeMode = String(mode ?? "").trim().toUpperCase();
if (!MODES.includes(safeMode)) {
throw new Error(`Unsupported Twofish mode: '${mode}'. Use one of ${MODES.join(", ")}`);
}
encryptTwofish(msg, key, iv, safeMode, padding); Type guard
function isTwofishMode(m) {
return typeof m === "string" &&
["ECB", "CBC", "CFB", "OFB", "CTR"].includes(m);
} Try / catch
try {
ct = encryptTwofish(msg, key, iv, mode, padding);
} catch (e) {
if (e instanceof OperationError && /Invalid block cipher mode/.test(e.message)) {
return { error: `Mode '${mode}' not supported by Twofish.` };
}
throw e;
} Prevention
- Centralise mode constants and import them at every call site.
- Whitelist and normalise user/config mode values before they reach the cipher.
- Twofish here has no AEAD mode — do not pass GCM/CCM.
When it happens
Trigger: Calling encryptTwofish() with a mode string other than the exact supported tokens: typos, wrong casing ("cbc"), unsupported modes ("GCM", "CCM", "PCBC"), or undefined. Distinct from the TEA equivalent only by library.
Common situations: Recipe/config value not whitelisted; cross-cipher copy of a mode constant; refactor that introduced a new spelling; default parameter overridden with an invalid value.
Related errors
- Invalid block cipher mode: ${mode}
- No padding requested but input is not a ${blockSize}-byte mu
- Unknown padding type: ${padding}
- Invalid ciphertext length: ${originalLength} bytes. Must be
- Invalid ciphertext length: ${originalLength} bytes. Must be
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/1ce4eefaf8554811.
Report an issue: GitHub.