Skip to content

Commit

Permalink
Add AES SIV examples
Browse files Browse the repository at this point in the history
  • Loading branch information
Christiaan676 committed Apr 9, 2024
1 parent dfe116c commit 082803a
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 2 deletions.
1 change: 1 addition & 0 deletions aes-siv/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ pub type Tag = Array<u8, U16>;
/// The `SivAead` type wraps the more powerful `Siv` interface in a more
/// commonly used Authenticated Encryption with Associated Data (AEAD) API,
/// which accepts a key, nonce, and associated data when encrypting/decrypting.
/// See the [`Siv`](mod@siv) module documentation for more information and examples.
pub struct SivAead<C, M, NonceSize = U16>
where
Self: KeySizeUser,
Expand Down
70 changes: 68 additions & 2 deletions aes-siv/src/siv.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,72 @@
//! The Synthetic Initialization Vector (SIV) misuse-resistant block cipher
//! mode of operation ([RFC 5297][1]).
//! mode of operation ([RFC 5297][1]). The interface is based on the [Rogaway paper][2].
//!
//! # Deterministic Authenticated Encryption Example
//! Deterministic encryption with additional data. Suitable for example for key wrapping.
//! Based on the test vector in [RFC 5297 Appendix: A1][3]
#![cfg_attr(feature = "std", doc = "```")]
#![cfg_attr(not(feature = "std"), doc = "```ignore")]
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! use aes_siv::{siv::Aes128Siv, KeyInit};
//! use hex_literal::hex;
//!
//! let key = hex!("fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff");
//! let ad = hex!("101112131415161718191a1b1c1d1e1f2021222324252627");
//! let plain_text = hex!("112233445566778899aabbccddee");
//!
//! let header = [&ad];
//! let encrypt = Aes128Siv::new(&key.into())
//! .encrypt(&header, &plain_text)?;
//!
//! assert_eq!(
//! hex!("85632d07c6e8f37f950acd320a2ecc9340c02b9690c4dc04daef7f6afe5c").to_vec(),
//! encrypt
//! );
//! let decrypted = Aes128Siv::new(&key.into())
//! .decrypt(&header, &encrypt)?;
//!
//! assert_eq!(plain_text.to_vec(), decrypted);
//! # Ok(())
//! # }
//! ```
//!
//! # Nonce-Based Authenticated Encryption Example
//! Nonce-based encryption with multiple additional data vectors.
//! Based on the test vector in [RFC 5297 Appendix: A2][4]
#![cfg_attr(feature = "std", doc = "```")]
#![cfg_attr(not(feature = "std"), doc = "```ignore")]
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! use aes_siv::{siv::Aes128Siv, KeyInit};
//! use hex_literal::hex;
//!
//! let key = hex!("7f7e7d7c7b7a79787776757473727170404142434445464748494a4b4c4d4e4f");
//! let ad1 = hex!("00112233445566778899aabbccddeeffdeaddadadeaddadaffeeddccbbaa99887766554433221100");
//! let ad2 = hex!("102030405060708090a0");
//! // Note that for production the nonce should be generated by for example: Aes256SivAead::generate_nonce
//! let nonce = hex!("09f911029d74e35bd84156c5635688c0");
//!
//! let plain_text = hex!("7468697320697320736f6d6520706c61696e7465787420746f20656e6372797074207573696e67205349562d414553");
//!
//! let header: [&[u8]; 3] = [&ad1, &ad2, &nonce];
//! let encrypt = Aes128Siv::new(&key.into())
//! .encrypt(&header, &plain_text)?;
//!
//! assert_eq!(
//! hex!("7bdb6e3b432667eb06f4d14bff2fbd0fcb900f2fddbe404326601965c889bf17dba77ceb094fa663b7a3f748ba8af829ea64ad544a272e9c485b62a3fd5c0d").to_vec(),
//! encrypt
//! );
//!
//! let decrypted = Aes128Siv::new(&key.into())
//! .decrypt(&header, &encrypt)?;
//!
//! assert_eq!(plain_text.to_vec(), decrypted);
//! # Ok(())
//! # }
//! ```
//! [1]: https://tools.ietf.org/html/rfc5297
//! [2]: https://web.cs.ucdavis.edu/~rogaway/papers/siv.pdf
//! [3]: https://datatracker.ietf.org/doc/html/rfc5297#appendix-A.1
//! [4]: https://datatracker.ietf.org/doc/html/rfc5297#appendix-A.2

use crate::Tag;
use aead::{
Expand Down Expand Up @@ -173,7 +238,8 @@ where
Ok(siv_tag)
}

/// Decrypt the given ciphertext, allocating and returning a Vec<u8> for the plaintext
/// Decrypt the given ciphertext, allocating and returning a `Vec<u8>` for the plaintext.
/// Or returning an error in the event the provided authentication tag does not match the given ciphertext.
#[cfg(feature = "alloc")]
pub fn decrypt<I, T>(&mut self, headers: I, ciphertext: &[u8]) -> Result<Vec<u8>, Error>
where
Expand Down

0 comments on commit 082803a

Please sign in to comment.