cbc

Generic Cipher Block Chaining (CBC) block cipher mode of operation for Rust, built on the RustCrypto cipher traits.

Library
Cargo
v0.2.1
96stars
MIT OR Apache-2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
45/100Fair
Development Activity52
Maintenance4
Community48
Maturity56
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
74/100Good
Architecture80
Code Quality78
Innovation72
Learning Curve65

cbc is a pure-Rust implementation of the Cipher Block Chaining (CBC) block cipher mode of operation, part of the RustCrypto organization’s block-modes collection. It is generic over any block cipher that implements the RustCrypto cipher crate’s traits, so it works out of the box with AES, Camellia, or any other compatible cipher without reimplementing the mode logic per algorithm.

The crate exposes separate Encryptor and Decryptor types with in-place, buffer-to-buffer, and (with the alloc feature) allocating convenience APIs, plus optional PKCS7 padding via the block-padding feature. It is no_std by default, making it usable in embedded and constrained environments, and does not itself provide ciphertext authentication — it is explicitly documented as a low-level (‘hazmat’) primitive intended to be paired with a MAC or used through an AEAD construction for integrity-sensitive use cases.

What You Get

  • Encryptor<C> and Decryptor<C> generic types that wrap any block cipher implementing the RustCrypto cipher traits
  • In-place, buffer-to-buffer, and allocating (alloc feature) encrypt/decrypt APIs for padded and unpadded data
  • Optional PKCS7 padding support gated behind the block-padding feature (enabled by default)
  • no_std compatibility for embedded and resource-constrained targets
  • SetIvState/IvState trait implementations for saving and restoring mode state mid-stream
  • Optional zeroize feature to zero out sensitive key/IV material on drop

Common Use Cases

  • Encrypting data at rest with AES-CBC in a Rust application that already depends on the aes crate
  • Implementing legacy or interop-required protocols (e.g. TLS 1.0/1.1-era ciphersuites, PKCS#5/7-padded file formats) that mandate CBC mode specifically
  • Building embedded or no_std firmware that needs a block cipher mode without pulling in a heap allocator
  • Composing CBC with a separate MAC (e.g. HMAC) to build a custom encrypt-then-MAC construction where an off-the-shelf AEAD isn’t suitable

Under The Hood

Architecture The crate is a thin, single-purpose implementation split across src/lib.rs, src/encrypt.rs, and src/decrypt.rs (roughly 500 lines total). lib.rs defines a small shared xor helper over generic byte arrays and re-exports the cipher crate so downstream users don’t need a separate dependency. Encryptor<C> and Decryptor<C> are generic structs holding an inner cipher instance C and the current IV/feedback block; each implements the cipher crate’s BlockSizeUser, InnerIvInit, IvState, SetIvState, and BlockModeEncrypt/BlockModeDecrypt traits, so the actual CBC chaining logic (XOR-then-encrypt for encryption, decrypt-then-XOR for decryption) lives in trait method bodies (encrypt_with_backend/decrypt_with_backend) that the cipher crate’s higher-level buffer/padding helpers call into. This trait-based design means cbc contains almost no cipher-specific code itself — it is a mode-of-operation layer that composes with any conforming block cipher crate.

Tech Stack The only runtime dependency is cipher 0.5.2 (the RustCrypto trait ecosystem), and dev-dependencies add hex-literal and the aes crate for tests/examples. The crate targets Rust edition 2024 with an MSRV of 1.85, is #![no_std] by default, and exposes three additive Cargo features: block-padding (PKCS7 padding, on by default), alloc (allocating convenience methods), and zeroize (drop-time zeroing of key/IV material) — each simply forwarding to the identically-named feature on the cipher crate.

Code Quality Tests are split between tests/aes_cavp.rs, which runs NIST CAVP known-answer vectors for AES-CBC against the cipher crate’s shared test-vector macros, and tests/iv_state.rs, which exercises the IvState/SetIvState save-and-resume behavior. Coverage is narrow but targeted at correctness-critical paths (cryptographic KATs) rather than broad API surface testing; there is no dedicated error-handling code to speak of since the crate’s public API is largely infallible except for padding validation, which is delegated to the cipher crate’s UnpadError. Naming is consistent with the rest of the RustCrypto ecosystem (Encryptor/Decryptor, *_padded, *_padded_vec, *_padded_b2b), and the crate carries a [lints] workspace = true entry, meaning it inherits the RustCrypto workspace’s shared, presumably strict, lint configuration.

API Design The public surface is deliberately minimal: two generic types with constructor (new/inner_iv_init), and encrypt/decrypt methods across three buffer strategies (in-place, buffer-to-buffer, and allocating). Method names follow a predictable <verb>_padded[_vec|_b2b] convention that generalizes across the whole RustCrypto block-modes family, so once a developer learns one crate in the family (e.g. ctr or ofb), cbc’s API requires no relearning. The crate’s docs.rs page and root doc comment include copy-pasteable, runnable examples for both in-place and allocating usage with AES-128, keeping the barrier to a first working encrypt/decrypt call low despite the type-level genericity.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search