{"record":{"id":"1ce4eefaf8554811","repo":"gchq/CyberChef","slug":"invalid-block-cipher-mode-mode-1ce4ee","errorCode":null,"errorMessage":"Invalid block cipher mode: ${mode}","messagePattern":"Invalid block cipher mode: (.+?)","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/lib/Twofish.mjs","lineNumber":514,"sourceCode":"                const block = paddedMessage.slice(i, i + BLOCKSIZE);\n                cipherText.push(...xorBlocks(ivBlock, block));\n            }\n            return cipherText.slice(0, messageLength);\n        }\n\n        case \"CTR\": {\n            let counter = [...iv];\n            for (let i = 0; i < paddedMessage.length; i += BLOCKSIZE) {\n                const encrypted = encryptBlock(counter, keyData);\n                const block = paddedMessage.slice(i, i + BLOCKSIZE);\n                cipherText.push(...xorBlocks(encrypted, block));\n                counter = incrementCounter(counter);\n            }\n            return cipherText.slice(0, messageLength);\n        }\n\n        default:\n            throw new OperationError(`Invalid block cipher mode: ${mode}`);\n    }\n\n    return cipherText;\n}\n\n/**\n * Decrypt using Twofish cipher with specified block mode\n *\n * @param {number[]} cipherText - Ciphertext as byte array\n * @param {number[]} key - Key (16, 24, or 32 bytes)\n * @param {number[]} iv - IV (16 bytes, not used for ECB)\n * @param {string} mode - Block cipher mode (\"ECB\", \"CBC\", \"CFB\", \"OFB\", \"CTR\")\n * @param {string} padding - Padding type (\"NO\", \"PKCS5\", \"ZERO\", \"RANDOM\", \"BIT\")\n * @returns {number[]} - Plaintext as byte array\n */\nexport function decryptTwofish(cipherText, key, iv, mode = \"ECB\", padding = \"PKCS5\") {\n    const originalLength = cipherText.length;\n    if (originalLength === 0) return [];","sourceCodeStart":496,"sourceCodeEnd":532,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/lib/Twofish.mjs#L496-L532","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nencryptTwofish(msg, key, iv, \"gcm\", \"PKCS5\");\n// after\nencryptTwofish(msg, key, iv, \"CTR\", \"PKCS5\");","handlingStrategy":"validation","validationCode":"const MODES = [\"ECB\", \"CBC\", \"CFB\", \"OFB\", \"CTR\"];\nconst safeMode = String(mode ?? \"\").trim().toUpperCase();\nif (!MODES.includes(safeMode)) {\n    throw new Error(`Unsupported Twofish mode: '${mode}'. Use one of ${MODES.join(\", \")}`);\n}\nencryptTwofish(msg, key, iv, safeMode, padding);","typeGuard":"function isTwofishMode(m) {\n    return typeof m === \"string\" &&\n        [\"ECB\", \"CBC\", \"CFB\", \"OFB\", \"CTR\"].includes(m);\n}","tryCatchPattern":"try {\n    ct = encryptTwofish(msg, key, iv, mode, padding);\n} catch (e) {\n    if (e instanceof OperationError && /Invalid block cipher mode/.test(e.message)) {\n        return { error: `Mode '${mode}' not supported by Twofish.` };\n    }\n    throw e;\n}","preventionTips":["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."],"tags":["crypto","twofish","block-cipher-mode","argument-validation"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}