From ca3818b9df9115eb0e3c60cf4f9556a2464689c9 Mon Sep 17 00:00:00 2001 From: Sergio Benitez Date: Fri, 9 Aug 2024 04:49:32 -0700 Subject: [PATCH] add usage and rename to Xaes256gcm --- xaes-256-gcm/src/lib.rs | 86 ++++++++++++++++++++++++++------ xaes-256-gcm/tests/xaes256gcm.rs | 4 +- 2 files changed, 74 insertions(+), 16 deletions(-) diff --git a/xaes-256-gcm/src/lib.rs b/xaes-256-gcm/src/lib.rs index e6afcddb..6f6aee46 100644 --- a/xaes-256-gcm/src/lib.rs +++ b/xaes-256-gcm/src/lib.rs @@ -8,18 +8,67 @@ #![deny(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] -//! # TBD +//! # Usage +//! +//! Simple usage (allocating, no associated data): +//! +#![cfg_attr( + all(feature = "getrandom", feature = "heapless", feature = "std"), + doc = "```" +)] +#![cfg_attr( + not(all(feature = "getrandom", feature = "heapless", feature = "std")), + doc = "```ignore" +)] +//! use xaes_256_gcm::{ +//! Xaes256Gcm, Nonce, Key, +//! aead::{Aead, AeadCore, KeyInit, OsRng}, +//! }; +//! +//! # fn gen_key() -> Result<(), core::array::TryFromSliceError> { +//! // The encryption key can be generated randomly: +//! # #[cfg(all(feature = "getrandom", feature = "std"))] { +//! let key = Xaes256Gcm::generate_key().expect("generate key"); +//! # } +//! +//! // Transformed from a byte array: +//! let key: &[u8; 32] = &[42; 32]; +//! let key: &Key = key.into(); +//! +//! // Note that you can get byte array from slice using the `TryInto` trait: +//! let key: &[u8] = &[42; 32]; +//! let key: [u8; 32] = key.try_into()?; +//! # Ok(()) } +//! +//! # fn main() -> Result<(), Box> { +//! // Alternatively, the key can be transformed directly from a byte slice +//! // (panics on length mismatch): +//! # let key: &[u8] = &[42; 32]; +//! let key = ::from_slice(key); +//! +//! let cipher = Xaes256Gcm::new(&key); +//! let nonce = Xaes256Gcm::generate_nonce()?; // 192-bits +//! let ciphertext = cipher.encrypt(&nonce, b"plaintext message".as_ref())?; +//! let plaintext = cipher.decrypt(&nonce, ciphertext.as_ref())?; +//! assert_eq!(&plaintext, b"plaintext message"); +//! # Ok(()) +//! # } +//! ``` + +pub use aead; +pub use aes; +pub use aes_gcm; use core::ops::{Div, Mul}; -use aead::{array::Array, AeadCore, AeadInPlace, Error, Key, KeyInit, KeySizeUser}; +use aead::{array::Array, AeadCore, AeadInPlace, Error, KeyInit, KeySizeUser}; use aes::Aes256; -use aes_gcm::{Aes256Gcm, Nonce, Tag}; +use aes_gcm::Aes256Gcm; use cipher::{consts::U2, BlockCipherEncrypt, BlockSizeUser}; /// XAES-256-GCM #[derive(Clone)] -pub struct XaesGcm256 { +pub struct Xaes256Gcm { aes: Aes256, k1: Block, } @@ -30,6 +79,15 @@ type TagSize = ::TagSize; type CiphertextOverhead = ::CiphertextOverhead; type Block = Array::BlockSize>; +/// XAES-256-GCM nonce. +pub type Nonce = aes_gcm::Nonce; + +/// XAES-256-GCM key. +pub type Key = aes_gcm::Key; + +/// XAES-256-GCM tag. +pub type Tag = aes_gcm::Tag; + /// Maximum length of plaintext. pub const P_MAX: u64 = 1 << 36; @@ -40,19 +98,19 @@ pub const A_MAX: u64 = 1 << 36; /// Maximum length of ciphertext. pub const C_MAX: u64 = (1 << 36) + 16; -impl AeadCore for XaesGcm256 { +impl AeadCore for Xaes256Gcm { type NonceSize = NonceSize; type TagSize = TagSize; type CiphertextOverhead = CiphertextOverhead; } -impl KeySizeUser for XaesGcm256 { +impl KeySizeUser for Xaes256Gcm { type KeySize = KeySize; } -impl KeyInit for XaesGcm256 { +impl KeyInit for Xaes256Gcm { // Implements step 1 and 2 of the spec. - fn new(key: &Key) -> Self { + fn new(key: &Key) -> Self { let aes = Aes256::new(key); // L = AES-256ₖ(0¹²⁸) @@ -74,13 +132,13 @@ impl KeyInit for XaesGcm256 { } } -impl AeadInPlace for XaesGcm256 { +impl AeadInPlace for Xaes256Gcm { fn encrypt_in_place_detached( &self, - nonce: &Nonce, + nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - ) -> Result, Error> { + ) -> Result { if buffer.len() as u64 > P_MAX || associated_data.len() as u64 > A_MAX { return Err(Error); } @@ -92,10 +150,10 @@ impl AeadInPlace for XaesGcm256 { fn decrypt_in_place_detached( &self, - nonce: &Nonce, + nonce: &Nonce, associated_data: &[u8], buffer: &mut [u8], - tag: &Tag, + tag: &Tag, ) -> Result<(), Error> { if buffer.len() as u64 > C_MAX || associated_data.len() as u64 > A_MAX { return Err(Error); @@ -107,7 +165,7 @@ impl AeadInPlace for XaesGcm256 { } } -impl XaesGcm256 { +impl Xaes256Gcm { // Implements steps 3 - 5 of the spec. fn derive_key(&self, n1: &Nonce<>::Output>) -> Key { // M1 = 0x00 || 0x01 || X || 0x00 || N[:12] diff --git a/xaes-256-gcm/tests/xaes256gcm.rs b/xaes-256-gcm/tests/xaes256gcm.rs index 45a9b071..47d9bde7 100644 --- a/xaes-256-gcm/tests/xaes256gcm.rs +++ b/xaes-256-gcm/tests/xaes256gcm.rs @@ -7,7 +7,7 @@ mod common; use aes_gcm::aead::{array::Array, Aead, AeadInPlace, KeyInit, Payload}; use common::TestVector; use hex_literal::hex; -use xaes_256_gcm::XaesGcm256; +use xaes_256_gcm::Xaes256Gcm; /// C2SP XAES-256-GCM test vectors /// @@ -31,4 +31,4 @@ const TEST_VECTORS: &[TestVector<[u8; 32], [u8; 24]>] = &[ }, ]; -tests!(XaesGcm256, TEST_VECTORS); +tests!(Xaes256Gcm, TEST_VECTORS);