gchq/CyberChef · error · OperationError

Invalid block cipher mode: ${mode}

Error message

Invalid block cipher mode: ${mode}

What it means

Default branch of the mode switch inside encryptRC6 (RC6.mjs:528). After the padding step, the function dispatches on mode; any value outside {ECB, CBC, CFB, OFB, CTR} reaches this throw and reports the bad mode string.

Source

Thrown at src/core/lib/RC6.mjs:528

            }
            return cipherText.slice(0, messageLength);
        }

        case "CTR": {
            let counter = [...iv];
            for (let i = 0; i < paddedMessage.length; i += blockSize) {
                const encrypted = encryptBlock(counter, S, rounds, w);
                const block = paddedMessage.slice(i, i + blockSize);
                // Pad block if shorter than blockSize
                while (block.length < blockSize) block.push(0);
                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 RC6 cipher with specified block mode
 *
 * @param {number[]} cipherText - Ciphertext as byte array
 * @param {number[]} key - Key as byte array
 * @param {number[]} iv - IV (block size 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")
 * @param {number} rounds - Number of rounds (default: 20)
 * @param {number} w - Word size in bits (default: 32)
 * @returns {number[]} - Plaintext as byte array
 */
export function decryptRC6(cipherText, key, iv, mode = "ECB", padding = "PKCS5", rounds = 20, w = 32) {

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Pass one of: 'ECB', 'CBC', 'CFB', 'OFB', 'CTR'.
  2. Normalise and validate the mode string (trim + uppercase) against an allowlist before calling encryptRC6.
  3. If you need an AEAD mode, RC6 in this library does not provide it — pick a different cipher or mode.

Example fix

// before
const ct = encryptRC6(msg, key, iv, "gcm");
// after
const ct = encryptRC6(msg, key, iv, "CTR");
Defensive patterns

Strategy: validation

Validate before calling

const RC6_MODES = new Set(["ECB", "CBC", "CFB", "OFB", "CTR"]);
function normaliseMode(m) {
  const v = String(m).trim().toUpperCase();
  if (!RC6_MODES.has(v)) throw new TypeError(`Unsupported RC6 mode: ${JSON.stringify(m)}`);
  return v;
}

Type guard

function isRc6Mode(v) {
  return typeof v === "string" &&
    ["ECB","CBC","CFB","OFB","CTR"].includes(v.trim().toUpperCase());
}

Try / catch

try {
  encryptRC6(msg, key, iv, normaliseMode(mode), padding);
} catch (e) {
  if (e instanceof TypeError && /Unsupported RC6 mode/.test(e.message)) {
    // report unsupported mode to caller
  } else throw e;
}

Prevention

When it happens

Trigger: encryptRC6 is called with a mode argument that is not one of the five supported literals. Examples: 'CBC/PKCS7', 'GCM' (RC6 here does not implement AEAD), 'ctr' (lowercase), an empty string, or undefined leaking through from an unconfigured recipe field.

Common situations: User-typed mode string passed unvalidated; mode coming from a config file with different naming convention; assumption that an AEAD mode like GCM is supported when only the five classic modes are.

Related errors


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