Table of Contents

CbcModeTransform Class

Definition

Namespace
Bodu.Security.Cryptography
Assembly
Bodu.Security.Cryptography.dll
Package
Bodu.Security.Cryptography 1.2.0
Source
CbcModeTransform.cs

Applies the Cipher Block Chaining (CBC) mode transformation to an underlying IBlockCipher.

public sealed class CbcModeTransform : IBlockCipherModeTransform, IDisposable
Inheritance
CbcModeTransform
Implements
Inherited Members
Extension Methods

Examples

using System.Security.Cryptography;
using Bodu.Security.Cryptography;

// Most callers should set SymmetricAlgorithm.Mode = CipherBlockMode.CBC instead of using this directly.
using IBlockCipher cipher = new AesBlockCipher(key);
byte[] iv = RandomNumberGenerator.GetBytes(cipher.BlockSize / 8); // unique per message
IBlockCipherModeTransform cbc = new CbcModeTransform(cipher, iv);
byte[] ciphertext = new byte[paddedPlaintext.Length];
int written = cbc.Transform(paddedPlaintext, ciphertext, encrypt: true);

Remarks

CBC panel - each plaintext block is XORed with the previous ciphertext before encryption; the first block uses the IV.

Encryption computes Cᵢ = E(Pᵢ ⊕ Cᵢ₋₁) with C₋₁ = IV, and decryption inverts this as Pᵢ = D(Cᵢ) ⊕ Cᵢ₋₁. See panel 2 of the diagram above: the dashed feedback line feeds each ciphertext block forward into the XOR that precedes the next encryption, and the IV supplies that feedback for the very first block.

The initialization vector must equal the cipher block size in length and should be unpredictable for each message; repeating an IV under the same key weakens confidentiality. The instance retains the most recent ciphertext block as the chaining value, so successive calls to Transform(ReadOnlySpan<byte>, Span<byte>, bool) continue the stream.

When to use CBC. The traditional confidentiality-only mode - the right pick when interoperating with legacy protocols (TLS up to 1.2, JCE defaults, many file formats) or when an authenticated mode is impractical. CBC requires plaintext to be a multiple of the block size, so it is almost always paired with Pkcs7Padding. For new designs prefer GcmModeTransform or EaxModeTransform, both of which authenticate as well as encrypt; CBC plus a separate MAC is fragile and easy to misuse. Decryption with strippable padding is vulnerable to padding-oracle attacks. The pad-byte validation is constant-time (each padding strategy's Unpad - see Pkcs7Padding - walks the full final block with branchless masks), but that alone is not a complete defence - the depadded length still varies with the pad count and an invalid block throws. Callers must authenticate the ciphertext (a MAC verified with FixedTimeEquals(ReadOnlySpan<byte>, ReadOnlySpan<byte>), or an AEAD mode) before depadding, so a padding failure is never observable to an attacker.

CBC is sequential - neither encryption nor decryption parallelizes across blocks within a single message. Random access into the ciphertext is not supported.

Constructors

CbcModeTransform(IBlockCipher, byte[])

Initializes a new instance of the CbcModeTransform class with the specified cipher and initialization vector.

public CbcModeTransform(IBlockCipher cipher, byte[] iv)

Parameters

cipher IBlockCipher

The block cipher over which CBC is applied.

iv byte[]

The initialization vector used as the chaining value for the first block. A defensive copy is taken.

Exceptions

ArgumentNullException

Thrown if cipher or iv is null.

Methods

Dispose()

Releases the resources used by this instance and zeroes the running chaining vector so that key-equivalent IV state does not linger in memory after disposal. The underlying IBlockCipher is not disposed by this type - ownership remains with the caller.

public void Dispose()

Remarks

Idempotent.

Transform(ReadOnlySpan<byte>, Span<byte>, bool)

Transforms input under the mode's chaining strategy and writes the result to output.

public int Transform(ReadOnlySpan<byte> input, Span<byte> output, bool encrypt)

Parameters

input ReadOnlySpan<byte>

The input data to transform. Its length must be a positive multiple of the underlying cipher block size.

output Span<byte>

The destination span. Its length must be greater than or equal to the length of input.

encrypt bool

true to encrypt the input; false to decrypt.

Returns

int

The number of bytes written to output.

Exceptions

ArgumentException

Thrown when input's length is not a multiple of the block size or when output is too small.

Applies to

ProductVersions
.NET8, 10

See Also