TheAlgorithms/C-Sharp · error · ArgumentException

Pad block corrupted

Error message

Pad block corrupted

What it means

GetPaddingCount runs a constant-time scan for the first padding byte and throws ArgumentException('Pad block corrupted') when the computed paddingStartIndex is negative — meaning no valid 0x80 marker was found or the padding structure is inconsistent. Like the RemovePadding check, it detects corrupted or forged data without leaking timing information.

Solutions

  1. Confirm matching padding schemes and keys on both sides
  2. Adopt authenticated encryption to reject corrupted ciphertext before unpadding
  3. Catch ArgumentException and surface a uniform cryptographic-failure error to callers

Example fix

// before
var count = padding.GetPaddingCount(decrypted);
// after
try { var count = padding.GetPaddingCount(decrypted); }
catch (ArgumentException) { throw new CryptographicException("Bad padding"); }
Defensive patterns

Strategy: try-catch

Validate before calling

if (input == null || input.Length == 0)
    throw new CryptographicException("Nothing to unpad");

Try / catch

try { count = padding.GetPaddingCount(input); }
catch (ArgumentException) { throw new CryptographicException("Pad block corrupted"); }

Prevention

When it happens

Trigger: Input containing no 0x80 padding marker anywhere valid; decrypted garbage from a wrong key; tampered ciphertext during constant-time unpadding.

Common situations: Padding-oracle probing, ciphertext corruption in transit, key/mode mismatch producing plaintext without the marker byte.

Related errors


AI-assisted analysis of TheAlgorithms/C-Sharp@96e2905cab (2026-09-13). Data as JSON: /api/errors/29cd5e8060594640. Report an issue: GitHub.

Appendix: source

Thrown at Algorithms/Crypto/Paddings/Iso7816D4Padding.cs:146

            // Compute a mask to indicate if the current byte is 0x80.
            var isPaddingStartMask = ((currentByte ^ 0x80) - 1) >> 31;

            // Update the index of the first padding byte using bitwise operations.
            // If the current byte is 0x80 and still part of the padding, set the index to the current index.
            // Otherwise, keep the previous index.
            paddingStartIndex ^= (currentIndex ^ paddingStartIndex) & (stillPaddingMask & isPaddingStartMask);

            // Update the mask to indicate if the current byte is still part of the padding using bitwise operations.
            // If the current byte is 0x00, keep the previous mask.
            // Otherwise, set the mask to 0.
            stillPaddingMask &= isZeroMask;
        }

        // Check if the index of the first padding byte is valid.
        if (paddingStartIndex < 0)
        {
            throw new ArgumentException("Pad block corrupted");
        }

        // Return the number of padding bytes.
        return input.Length - paddingStartIndex;
    }
}

View on GitHub (pinned to 96e2905cab)