{"record":{"id":"5fe73fcb7eb18a65","repo":"gchq/CyberChef","slug":"invalid-bit-padding-5fe73f","errorCode":null,"errorMessage":"Invalid BIT padding.","messagePattern":"Invalid BIT padding\\.","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/lib/Twofish.mjs","lineNumber":424,"sourceCode":"            if (padByte > 0 && padByte <= blockSize) {\n                // Verify padding\n                for (let i = 0; i < padByte; i++) {\n                    if (message[message.length - 1 - i] !== padByte) {\n                        throw new OperationError(\"Invalid PKCS#5 padding.\");\n                    }\n                }\n                return message.slice(0, message.length - padByte);\n            }\n            throw new OperationError(\"Invalid PKCS#5 padding.\");\n        }\n\n        case \"BIT\": {\n            // Find 0x80 byte working backwards, skipping zeros\n            for (let i = message.length - 1; i >= 0; i--) {\n                if (message[i] === 0x80) {\n                    return message.slice(0, i);\n                } else if (message[i] !== 0) {\n                    throw new OperationError(\"Invalid BIT padding.\");\n                }\n            }\n            throw new OperationError(\"Invalid BIT padding.\");\n        }\n\n        default:\n            throw new OperationError(`Unknown padding type: ${padding}`);\n    }\n}\n\n/**\n * Encrypt using Twofish cipher with specified block mode\n *\n * @param {number[]} message - Plaintext 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\")","sourceCodeStart":406,"sourceCodeEnd":442,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/lib/Twofish.mjs#L406-L442","documentation":"Thrown by removePadding() in Twofish.mjs in the BIT (ISO/IEC 9797-1 padding method 1) branch when scanning backwards from the end of the message: a non-zero byte other than the 0x80 terminator is encountered before the terminator is found. BIT padding is 0x80 followed by zero bytes; finding any other non-zero value means the padding is malformed.","triggerScenarios":"Calling decryptTwofish() with padding \"BIT\" on ECB/CBC output where the decrypted tail contains a non-zero, non-0x80 byte before the expected terminator. Causes: wrong key/IV, mode mismatch, the data was not BIT-padded, or the terminator was itself corrupted.","commonSituations":"Decrypting data encrypted with a different padding (PKCS5/ZERO) but declaring \"BIT\"; bit errors in the final block; interop with a system that uses a different bit-padding convention.","solutions":["Confirm the encrypt side used BIT padding and the same mode/key/IV.","If the encrypt side used a different padding scheme, set the decrypt padding argument to match (PKCS5, ZERO, NO).","If the plaintext genuinely ends in 0x80 followed by non-zero data, BIT padding is ambiguous for that data — choose PKCS5 instead."],"exampleFix":"// before: data was PKCS5-padded, decrypt declares BIT\ndecryptTwofish(ct, key, iv, \"CBC\", \"BIT\"); // throws on non-zero tail byte\n// after\ndecryptTwofish(ct, key, iv, \"CBC\", \"PKCS5\");","handlingStrategy":"try-catch","validationCode":"function isValidBitPadding(bytes) {\n    let i = bytes.length - 1;\n    while (i >= 0 && bytes[i] === 0) i--;\n    return i >= 0 && bytes[i] === 0x80;\n}\nconst probe = decryptTwofish(ct, key, iv, mode, \"NO\");\nif (!isValidBitPadding(probe)) {\n    throw new Error(\"Decrypted output has invalid BIT padding; verify key/IV/mode and that BIT padding was applied.\");\n}","typeGuard":"function isValidBitPadding(bytes) {\n    let i = bytes.length - 1;\n    while (i >= 0 && bytes[i] === 0) i--;\n    return i >= 0 && bytes[i] === 0x80;\n}","tryCatchPattern":"try {\n    pt = decryptTwofish(ct, key, iv, \"CBC\", \"BIT\");\n} catch (e) {\n    if (e instanceof OperationError && /Invalid BIT padding/.test(e.message)) {\n        return { error: \"Wrong key/IV/mode, or data was not BIT-padded.\" };\n    }\n    throw e;\n}","preventionTips":["Only use BIT padding when you can guarantee the plaintext never legitimately ends in 0x80 + zeros; prefer PKCS5 otherwise.","Ensure encrypt and decrypt agree on the padding scheme.","Treat BIT-padding failures as key/IV/mode suspects first."],"tags":["crypto","twofish","padding","decryption","data-integrity"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}