{"record":{"id":"ae176c6b32d25ee1","repo":"gchq/CyberChef","slug":"incorrect-input-length-must-be-a-multiple-of-the","errorCode":null,"errorMessage":"Incorrect input length. Must be a multiple of the block size.","messagePattern":"Incorrect input length\\. Must be a multiple of the block size\\.","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/GOSTKeyUnwrap.mjs","lineNumber":134,"sourceCode":"        const algorithm = {\n            version: versionNum,\n            length: blockLength,\n            mode: \"KW\",\n            sBox: sBoxVal,\n            keyWrapping: keyWrapping\n        };\n\n        try {\n            const Hex = CryptoGost.coding.Hex;\n            algorithm.ukm = Hex.decode(ukm);\n\n            const cipher = GostEngine.getGostCipher(algorithm);\n            const out = Hex.encode(cipher.unwrapKey(Hex.decode(key), Hex.decode(input)));\n\n            return outputType === \"Hex\" ? out : Utils.byteArrayToChars(fromHex(out));\n        } catch (err) {\n            if (err.toString().includes(\"Invalid typed array length\")) {\n                throw new OperationError(\"Incorrect input length. Must be a multiple of the block size.\");\n            }\n            throw new OperationError(err);\n        }\n    }\n\n}\n\nexport default GOSTKeyUnwrap;\n","sourceCodeStart":116,"sourceCodeEnd":143,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/GOSTKeyUnwrap.mjs#L116-L143","documentation":"Specific, friendlier error surfaced by GOST Key Unwrap when crypto-gost-js throws \"Invalid typed array length\" during `cipher.unwrapKey`. That low-level message is produced when allocating the output buffer would require a non-integer or negative element count, which happens when the wrapped-key input length is not a whole multiple of the block size (8 bytes for Magma, 16 for Kuznyechik). The op catches that signature and rewrites it to this message.","triggerScenarios":"Feeding wrapped key material whose byte length is not a multiple of the block size; truncating/corrupting the wrapped key; using a Hex string of odd length so `Hex.decode` yields a half-byte shift; mismatching the algorithm (e.g. unwrapping Magma-wrapped data under Kuznyechik).","commonSituations":"Copy-paste truncation of a hex blob; line-wrapped hex losing characters; algorithm/block-size mismatch between wrap and unwrap; trailing whitespace/newline in the input.","solutions":["Ensure the wrapped key hex decodes to a byte length that is a multiple of 8 (Magma) or 16 (Kuznyechik).","Strip whitespace/newlines from the input before unwrapping.","Use the same algorithm variant that produced the wrapped key.","Verify the key (KEK) is 32 bytes and the UKM is the correct length."],"exampleFix":"// before\nwrappedKey = \"aabbcc\"; // 3 bytes, not a block multiple\n// after\nwrappedKey = \"aabbccddeeff0011\"; // 8 bytes, one Magma block","handlingStrategy":"validation","validationCode":"const blockBytes = (versionNum === 2015 && blockLength === 128) ? 16 : 8;\nconst inputBytes = hexInput.length / 2;\nif (!Number.isInteger(inputBytes) || inputBytes % blockBytes !== 0) {\n  throw new Error(`Wrapped key must be a multiple of ${blockBytes} bytes`);\n}","typeGuard":"function isBlockMultiple(hex, blockBytes){const b=hex.length/2;return Number.isInteger(b)&&b%blockBytes===0;}","tryCatchPattern":"try { chef.bake(input, recipe); }\ncatch (e) {\n  if (/multiple of the block size/i.test(e.message||\"\")) warn(\"Wrapped key length is not a block multiple\");\n  else throw e;\n}","preventionTips":["Strip whitespace/newlines from hex wrapped-key input.","Match the unwrap algorithm to the one used to wrap.","Verify the wrapped key byte length is a multiple of 8 (Magma) or 16 (Kuznyechik)."],"tags":["crypto","gost","key-wrap","input-length"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}