block_modes/lib.rs
1//! This crate contains generic implementation of [block cipher modes of
2//! operation][1].
3//!
4//! Note that some block modes (such as CTR, CFB, and OFB) transform block ciphers
5//! into stream ciphers. Implementations in this crate require padding, so if you
6//! want use those modes as stream ciphers (i.e. without padding), then check out
7//! crates in the [RustCrypto/stream-ciphers][2] repository.
8//!
9//! # Usage example
10//! ```
11//! use aes::Aes128;
12//! use block_modes::{BlockMode, Cbc};
13//! use block_modes::block_padding::Pkcs7;
14//! use hex_literal::hex;
15//!
16//! // create an alias for convenience
17//! type Aes128Cbc = Cbc<Aes128, Pkcs7>;
18//!
19//! # fn main() {
20//! let key = hex!("000102030405060708090a0b0c0d0e0f");
21//! let iv = hex!("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff");
22//! let plaintext = b"Hello world!";
23//! let cipher = Aes128Cbc::new_from_slices(&key, &iv).unwrap();
24//!
25//! // buffer must have enough space for message+padding
26//! let mut buffer = [0u8; 32];
27//! // copy message to the buffer
28//! let pos = plaintext.len();
29//! buffer[..pos].copy_from_slice(plaintext);
30//! let ciphertext = cipher.encrypt(&mut buffer, pos).unwrap();
31//!
32//! assert_eq!(ciphertext, hex!("1b7a4c403124ae2fb52bedc534d82fa8"));
33//!
34//! // re-create cipher mode instance
35//! let cipher = Aes128Cbc::new_from_slices(&key, &iv).unwrap();
36//! let mut buf = ciphertext.to_vec();
37//! let decrypted_ciphertext = cipher.decrypt(&mut buf).unwrap();
38//!
39//! assert_eq!(decrypted_ciphertext, plaintext);
40//! # }
41//! ```
42//!
43//! With an enabled `alloc` feature (which is enabled by default) you can use
44//! `encrypt_vec` and `descrypt_vec` methods:
45//! ```
46//! # use aes::Aes128;
47//! # use block_modes::{BlockMode, Cbc};
48//! # use block_modes::block_padding::Pkcs7;
49//! # use hex_literal::hex;
50//! #
51//! # // create an alias for convenience
52//! # type Aes128Cbc = Cbc<Aes128, Pkcs7>;
53//! #
54//! # fn main() {
55//! # let key = hex!("000102030405060708090a0b0c0d0e0f");
56//! # let iv = hex!("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff");
57//! # let plaintext = b"Hello world!";
58//! let cipher = Aes128Cbc::new_from_slices(&key, &iv).unwrap();
59//! let ciphertext = cipher.encrypt_vec(plaintext);
60//!
61//! assert_eq!(ciphertext, hex!("1b7a4c403124ae2fb52bedc534d82fa8"));
62//!
63//! let cipher = Aes128Cbc::new_from_slices(&key, &iv).unwrap();
64//! let decrypted_ciphertext = cipher.decrypt_vec(&ciphertext).unwrap();
65//!
66//! assert_eq!(decrypted_ciphertext, plaintext);
67//! # }
68//! ```
69//!
70//! [1]: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation
71//! [2]: https://github.com/RustCrypto/stream-ciphers
72
73#![no_std]
74#![doc(
75 html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg",
76 html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg"
77)]
78#![deny(unsafe_code)]
79#![warn(missing_docs, rust_2018_idioms)]
80
81#[cfg(feature = "alloc")]
82extern crate alloc;
83#[cfg(feature = "std")]
84extern crate std;
85
86mod errors;
87mod traits;
88mod utils;
89
90mod cbc;
91mod cfb;
92mod cfb8;
93mod ecb;
94mod ige;
95mod ofb;
96mod pcbc;
97
98pub use block_padding;
99pub use cipher;
100
101pub use crate::{
102 cbc::Cbc,
103 cfb::Cfb,
104 cfb8::Cfb8,
105 ecb::Ecb,
106 errors::{BlockModeError, InvalidKeyIvLength},
107 ige::Ige,
108 ofb::Ofb,
109 pcbc::Pcbc,
110 traits::{BlockMode, IvState},
111};