gchq/CyberChef · error · OperationError
No padding requested in ${mode} mode but input is not a 16-b
Error message
No padding requested in ${mode} mode but input is not a 16-byte multiple. What it means
encryptSM4 at SM4.mjs:174 guards the noPadding path. In ECB/CBC the input must already be a whole number of 16-byte blocks because the cipher cannot stream or truncate; with noPadding=true and any remainder, encryption is refused rather than silently mis-padding.
Source
Thrown at src/core/lib/SM4.mjs:174
* @param {byteArray} key - The cipher key, 16 bytes.
* @param {byteArray} iv - The IV or nonce, 16 bytes (not used with ECB mode)
* @param {string} mode - The block cipher mode "CBC", "ECB", "CFB", "OFB", "CTR".
* @param {boolean} noPadding - Don't add PKCS#7 padding if set.
* @returns {byteArray} - The cipher text.
*/
export function encryptSM4(message, key, iv, mode="ECB", noPadding=false) {
const messageLength = message.length;
if (messageLength === 0)
return [];
const roundKey = initSM4RoundKey(bytesToInts(key, 0));
/* Pad with PKCS#7 if requested for ECB/CBC else add zeroes (which are sliced off at the end) */
let padByte = 0;
let nPadding = 16 - (message.length & 0xF);
if (mode === "ECB" || mode === "CBC") {
if (noPadding) {
if (nPadding !== 16)
throw new OperationError(`No padding requested in ${mode} mode but input is not a 16-byte multiple.`);
nPadding = 0;
} else
padByte = nPadding;
}
for (let i = 0; i < nPadding; i++)
message.push(padByte);
const cipherText = [];
switch (mode) {
case "ECB":
for (let i = 0; i < message.length; i += BLOCKSIZE)
Array.prototype.push.apply(cipherText, intsToBytes(encryptBlockSM4(bytesToInts(message, i), roundKey)));
break;
case "CBC":
iv = bytesToInts(iv, 0);
for (let i = 0; i < message.length; i += BLOCKSIZE) {
const block = bytesToInts(message, i);
block[0] ^= iv[0]; block[1] ^= iv[1];View on GitHub (pinned to 4290ea7539)
Solutions
- Pre-pad the message to a 16-byte multiple yourself (e.g. with explicit zero bytes) before calling encryptSM4 with noPadding=true.
- Or set noPadding=false to let the library apply PKCS#7 automatically.
- Validate message.length % 16 === 0 up front so the failure is reported at the trust boundary, not deep in the cipher.
Example fix
// before const ct = encryptSM4(msg, key, iv, "CBC", true); // msg is 17 bytes // after: align to block boundary explicitly const aligned = msg.concat(new Array((16 - msg.length % 16) % 16).fill(0)); const ct = encryptSM4(aligned, key, iv, "CBC", true);
Defensive patterns
Strategy: validation
Validate before calling
function assertSm4NoPaddingAligned(message, noPadding, mode) {
if (noPadding && (mode === "ECB" || mode === "CBC")) {
if (message.length & 0xF)
throw new TypeError(
`noPadding requires a 16-byte multiple; got ${message.length} bytes`);
}
} Type guard
function isSm4BlockAligned(bytes) {
return Number.isInteger(bytes.length) && (bytes.length & 0xF) === 0;
} Try / catch
import OperationError from "../errors/OperationError.mjs";
try {
assertSm4NoPaddingAligned(msg, noPadding, mode);
const ct = encryptSM4(msg, key, iv, mode, noPadding);
} catch (e) {
if (e instanceof OperationError && /No padding requested/.test(e.message)) {
// either pre-pad the message or enable PKCS#7
} else throw e;
} Prevention
- If you need noPadding in ECB/CBC, pre-align the message to a 16-byte multiple.
- Otherwise leave noPadding=false to use PKCS#7 automatically.
- Centralise the alignment rule so encrypt and decrypt cannot disagree.
When it happens
Trigger: encryptSM4(message, key, iv, mode='ECB'|'CBC', noPadding=true) where message.length % 16 != 0. Typical cause: caller deliberately disabled PKCS#7 padding but supplied a message that is not block-aligned.
Common situations: Protocol that requires no padding on the wire but the framing layer did not pre-pad to 16 bytes; toggling noPadding to avoid PKCS#7 overhead without aligning the payload; batch processing of variable-length records fed straight into ECB.
Related errors
- With ECB or CBC modes, the input must be divisible into 16 b
- No padding requested but input length (${message.length} byt
- Invalid ciphertext length: ${originalLength} bytes. Must be
- Invalid block cipher mode: ${mode}
- Invalid PKCS#7 padding.
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/0dfad9e7e5d17986.
Report an issue: GitHub.