1#![cfg_attr(all(feature = "getrandom", feature = "std"), doc = "```")]
10#![cfg_attr(not(all(feature = "getrandom", feature = "std")), doc = "```ignore")]
11#![cfg_attr(
43 all(feature = "getrandom", feature = "heapless", feature = "std"),
44 doc = "```"
45)]
46#![cfg_attr(
47 not(all(feature = "getrandom", feature = "heapless", feature = "std")),
48 doc = "```ignore"
49)]
50#![no_std]
82#![cfg_attr(docsrs, feature(doc_cfg))]
83#![doc(
84 html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg",
85 html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg"
86)]
87#![warn(missing_docs, rust_2018_idioms, unused_qualifications)]
88
89#[cfg(feature = "alloc")]
90extern crate alloc;
91
92pub mod siv;
93
94pub use aead::{self, AeadCore, AeadInPlace, Error, Key, KeyInit, KeySizeUser};
95
96use crate::siv::Siv;
97use aead::{
98 consts::{U0, U16, U32, U64},
99 generic_array::GenericArray,
100 Buffer,
101};
102use aes::{Aes128, Aes256};
103use cipher::{BlockCipher, BlockEncryptMut};
104use cmac::Cmac;
105use core::{marker::PhantomData, ops::Add};
106use digest::{FixedOutputReset, Mac};
107
108#[cfg(feature = "pmac")]
109use pmac::Pmac;
110
111pub type Nonce = GenericArray<u8, U16>;
113
114pub type Tag = GenericArray<u8, U16>;
116
117pub struct SivAead<C, M>
121where
122 Self: KeySizeUser,
123 C: BlockCipher<BlockSize = U16> + BlockEncryptMut + KeyInit + KeySizeUser,
124 M: Mac<OutputSize = U16> + FixedOutputReset + KeyInit,
125 <C as KeySizeUser>::KeySize: Add,
126{
127 key: GenericArray<u8, <Self as KeySizeUser>::KeySize>,
128 mac: PhantomData<M>, }
130
131pub type CmacSivAead<BlockCipher> = SivAead<BlockCipher, Cmac<BlockCipher>>;
133
134#[cfg(feature = "pmac")]
136#[cfg_attr(docsrs, doc(cfg(feature = "pmac")))]
137pub type PmacSivAead<BlockCipher> = SivAead<BlockCipher, Pmac<BlockCipher>>;
138
139pub type Aes128SivAead = CmacSivAead<Aes128>;
141
142pub type Aes256SivAead = CmacSivAead<Aes256>;
144
145#[cfg(feature = "pmac")]
147#[cfg_attr(docsrs, doc(cfg(feature = "pmac")))]
148pub type Aes128PmacSivAead = PmacSivAead<Aes128>;
149
150#[cfg(feature = "pmac")]
152#[cfg_attr(docsrs, doc(cfg(feature = "pmac")))]
153pub type Aes256PmacSivAead = PmacSivAead<Aes256>;
154
155impl<M> KeySizeUser for SivAead<Aes128, M>
156where
157 M: Mac<OutputSize = U16> + FixedOutputReset + KeyInit,
158{
159 type KeySize = U32;
160}
161
162impl<M> KeySizeUser for SivAead<Aes256, M>
163where
164 M: Mac<OutputSize = U16> + FixedOutputReset + KeyInit,
165{
166 type KeySize = U64;
167}
168
169impl<M> KeyInit for SivAead<Aes128, M>
170where
171 M: Mac<OutputSize = U16> + FixedOutputReset + KeyInit,
172{
173 fn new(key: &GenericArray<u8, Self::KeySize>) -> Self {
174 Self {
175 key: *key,
176 mac: PhantomData,
177 }
178 }
179}
180
181impl<M> KeyInit for SivAead<Aes256, M>
182where
183 M: Mac<OutputSize = U16> + FixedOutputReset + KeyInit,
184{
185 fn new(key: &GenericArray<u8, Self::KeySize>) -> Self {
186 Self {
187 key: *key,
188 mac: PhantomData,
189 }
190 }
191}
192
193impl<C, M> AeadCore for SivAead<C, M>
194where
195 Self: KeySizeUser,
196 C: BlockCipher<BlockSize = U16> + BlockEncryptMut + KeyInit + KeySizeUser,
197 M: Mac<OutputSize = U16> + FixedOutputReset + KeyInit,
198 <C as KeySizeUser>::KeySize: Add,
199{
200 type NonceSize = U16;
204 type TagSize = U16;
205 type CiphertextOverhead = U0;
206}
207
208impl<C, M> AeadInPlace for SivAead<C, M>
209where
210 Self: KeySizeUser,
211 Siv<C, M>: KeyInit + KeySizeUser<KeySize = <Self as KeySizeUser>::KeySize>,
212 C: BlockCipher<BlockSize = U16> + BlockEncryptMut + KeyInit + KeySizeUser,
213 M: Mac<OutputSize = U16> + FixedOutputReset + KeyInit,
214 <C as KeySizeUser>::KeySize: Add,
215{
216 fn encrypt_in_place(
217 &self,
218 nonce: &GenericArray<u8, Self::NonceSize>,
219 associated_data: &[u8],
220 buffer: &mut dyn Buffer,
221 ) -> Result<(), Error> {
222 Siv::<C, M>::new(&self.key).encrypt_in_place(&[associated_data, nonce.as_slice()], buffer)
228 }
229
230 fn encrypt_in_place_detached(
231 &self,
232 nonce: &GenericArray<u8, Self::NonceSize>,
233 associated_data: &[u8],
234 buffer: &mut [u8],
235 ) -> Result<GenericArray<u8, Self::TagSize>, Error> {
236 Siv::<C, M>::new(&self.key)
237 .encrypt_in_place_detached(&[associated_data, nonce.as_slice()], buffer)
238 }
239
240 fn decrypt_in_place(
241 &self,
242 nonce: &GenericArray<u8, Self::NonceSize>,
243 associated_data: &[u8],
244 buffer: &mut dyn Buffer,
245 ) -> Result<(), Error> {
246 Siv::<C, M>::new(&self.key).decrypt_in_place(&[associated_data, nonce.as_slice()], buffer)
247 }
248
249 fn decrypt_in_place_detached(
250 &self,
251 nonce: &GenericArray<u8, Self::NonceSize>,
252 associated_data: &[u8],
253 buffer: &mut [u8],
254 tag: &GenericArray<u8, Self::TagSize>,
255 ) -> Result<(), Error> {
256 Siv::<C, M>::new(&self.key).decrypt_in_place_detached(
257 &[associated_data, nonce.as_slice()],
258 buffer,
259 tag,
260 )
261 }
262}