gchq/CyberChef · error · OperationError

Invalid BIT padding.

Error message

Invalid BIT padding.

What it means

TEA's removePadding BIT case at TEA.mjs:250. BIT padding marks the start of padding with a 0x80 byte followed by zero bytes; walking backwards, the first non-zero byte encountered must be the 0x80 sentinel. This throw fires when a non-zero, non-0x80 byte is found before the sentinel — meaning the tail is not a well-formed BIT pad.

Source

Thrown at src/core/lib/TEA.mjs:250

            return message;

        case "PKCS5": {
            const padByte = message[message.length - 1];
            if (padByte > 0 && padByte <= BLOCK_SIZE) {
                for (let i = 0; i < padByte; i++) {
                    if (message[message.length - 1 - i] !== padByte) {
                        throw new OperationError("Invalid PKCS#5 padding.");
                    }
                }
                return message.slice(0, message.length - padByte);
            }
            throw new OperationError("Invalid PKCS#5 padding.");
        }

        case "BIT": {
            for (let i = message.length - 1; i >= 0; i--) {
                if (message[i] === 0x80) return message.slice(0, i);
                if (message[i] !== 0) throw new OperationError("Invalid BIT padding.");
            }
            throw new OperationError("Invalid BIT padding.");
        }

        default:
            throw new OperationError(`Unknown padding type: ${padding}`);
    }
}

/**
 * Encrypt with block cipher modes
 *
 * @param {number[]} message - Plaintext bytes
 * @param {number[]} key - 16-byte key
 * @param {number[]} iv - 8-byte IV (ignored for ECB)
 * @param {string} mode - "ECB", "CBC", "CFB", "OFB", "CTR"
 * @param {string} padding - "PKCS5", "NO", "ZERO", "RANDOM", "BIT"
 * @param {Function} encryptBlockFn - Block encrypt function

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Confirm the key and IV match the encrypt side.
  2. Verify the encrypt-time padding was 'BIT'.
  3. Decrypt with 'NO' padding and inspect the tail bytes to identify the actual scheme.

Example fix

// before
const pt = decryptWithBlockMode(ct, key, iv, "CBC", "BIT");
// after: data was PKCS5-padded
const pt = decryptWithBlockMode(ct, key, iv, "CBC", "PKCS5");
Defensive patterns

Strategy: validation

Validate before calling

function looksLikeValidBitPad(plain) {
  let sawSentinel = false;
  for (let i = plain.length - 1; i >= 0; i--) {
    const b = plain[i];
    if (b === 0x80) { sawSentinel = true; break; }
    if (b !== 0) return false;
  }
  return sawSentinel;
}

Type guard

function isWellFormedBitPad(plain) {
  let sawSentinel = false;
  for (let i = plain.length - 1; i >= 0; i--) {
    const b = plain[i];
    if (b === 0x80) { sawSentinel = true; break; }
    if (b !== 0) return false;
  }
  return sawSentinel;
}

Try / catch

import OperationError from "../errors/OperationError.mjs";
try {
  const pt = decryptWithBlockMode(ct, key, iv, mode, "BIT");
} catch (e) {
  if (e instanceof OperationError && /Invalid BIT padding/.test(e.message)) {
    // wrong key/IV or padding-scheme mismatch; do not return partial plaintext
  } else throw e;
}

Prevention

When it happens

Trigger: Decryption with padding='BIT' where the trailing bytes contain a non-zero, non-0x80 value before the 0x80 sentinel is reached. Causes: wrong key producing random plaintext in the tail; partial corruption of the last block; encryptor used a different padding scheme but decryptor expects BIT.

Common situations: Key/IV mismatch; encrypt/decrypt padding scheme mismatch; bit-flip in the last ciphertext block producing a random tail.

Related errors


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