gchq/CyberChef · error · OperationError

No padding requested but input is not a ${blockSize}-byte mu

Error message

No padding requested but input is not a ${blockSize}-byte multiple.

What it means

applyPadding with padding='NO' requires the message length to already be a multiple of the cipher block size (8 bytes for PRESENT). When remainder != 0 the function refuses to invent padding and throws, telling the caller the input is misaligned. This protects against silently truncating or extending plaintext.

Source

Thrown at src/core/lib/Present.mjs:238

 * @param {number} blockSize - Block size in bytes
 * @returns {number[]} - Padded message
 */
function applyPadding(message, padding, blockSize) {
    const remainder = message.length % blockSize;
    let nPadding = remainder === 0 ? 0 : blockSize - remainder;

    // For PKCS5, always add at least one byte (full block if already aligned)
    if (padding === "PKCS5" && remainder === 0) {
        nPadding = blockSize;
    }

    if (nPadding === 0) return [...message];

    const paddedMessage = [...message];

    switch (padding) {
        case "NO":
            throw new OperationError(`No padding requested but input is not a ${blockSize}-byte multiple.`);

        case "PKCS5":
            for (let i = 0; i < nPadding; i++) {
                paddedMessage.push(nPadding);
            }
            break;

        case "ZERO":
            for (let i = 0; i < nPadding; i++) {
                paddedMessage.push(0);
            }
            break;

        case "RANDOM":
            for (let i = 0; i < nPadding; i++) {
                paddedMessage.push(Math.floor(Math.random() * 256));
            }
            break;

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Switch padding to 'PKCS5' (default and most interoperable) or 'BIT' (ISO 7816-4).
  2. Pre-pad/align the message to a multiple of 8 bytes yourself before using 'NO'.
  3. Use 'ZERO' padding if the receiver can tolerate trailing zero bytes.
  4. Confirm PRESENT's 8-byte block size matches the peer implementation's expectation.

Example fix

// before
encryptPRESENT([1,2,3], key, iv, 'ECB', 'NO'); // 3 bytes -> error

// after
encryptPRESENT([1,2,3], key, iv, 'ECB', 'PKCS5'); // auto-padded to 8
// or align manually:
const padded = [...msg];
while (padded.length % 8) padded.push(0);
encryptPRESENT(padded, key, iv, 'ECB', 'NO');
Defensive patterns

Strategy: validation

Validate before calling

const BLOCKSIZE = 8;
function encryptPresentSafe(msg, key, iv, mode, padding) {
  if (padding === 'NO' && msg.length % BLOCKSIZE !== 0) {
    throw new Error('Input is not a multiple of 8 bytes; use PKCS5 or align manually.');
  }
  return encryptPRESENT(msg, key, iv, mode, padding);
}

Try / catch

try {
  return encryptPRESENT(msg, key, iv, mode, padding);
} catch (e) {
  if (/No padding requested/.test(e.message)) {
    // recover by switching to PKCS5
    return encryptPRESENT(msg, key, iv, mode, 'PKCS5');
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling encryptPRESENT(message, key, iv, 'ECB'|'CBC', 'NO') where message.length % 8 !== 0. Typical with arbitrary-length text or partial buffers.

Common situations: User selects 'No padding' in a recipe but supplies non-block-aligned input; interop with another cipher implementation that expects zero-padding; forgetting that PRESENT block size is 8 bytes (not 16 like AES).

Related errors


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