Skip to content

Commit 4969237

Browse files
committed
chacha20: add support for rfc 7539 12-byte nonces
1 parent 5ec378e commit 4969237

File tree

1 file changed

+42
-1
lines changed

1 file changed

+42
-1
lines changed

chacha20/src/lib.rs

+42-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ extern crate stream_cipher;
66
#[cfg(cargo_feature = "zeroize")]
77
extern crate zeroize;
88

9-
use block_cipher_trait::generic_array::typenum::{U32, U8};
9+
use block_cipher_trait::generic_array::typenum::{U12, U32, U8};
1010
use block_cipher_trait::generic_array::{ArrayLength, GenericArray};
1111
use stream_cipher::{NewStreamCipher, StreamCipher, SyncStreamCipherSeek};
1212

@@ -148,6 +148,30 @@ impl NewStreamCipher for ChaChaState<U8> {
148148
}
149149
}
150150

151+
impl NewStreamCipher for ChaChaState<U12> {
152+
/// Key size in bytes
153+
type KeySize = U32;
154+
/// Nonce size in bytes
155+
type NonceSize = U12;
156+
157+
fn new(key: &GenericArray<u8, Self::KeySize>, iv: &GenericArray<u8, Self::NonceSize>) -> Self {
158+
let exp_iv = &iv[0..4];
159+
let base_iv = &iv[4..12];
160+
161+
let mut ccs = ChaChaState {
162+
state: SalsaFamilyState::new(key, GenericArray::from_slice(base_iv)),
163+
phantom: core::marker::PhantomData,
164+
};
165+
166+
ccs.state.block_idx = (exp_iv[0] as u64 & 0xff) << 32
167+
| (exp_iv[1] as u64 & 0xff) << 40
168+
| (exp_iv[2] as u64 & 0xff) << 48
169+
| (exp_iv[3] as u64 & 0xff) << 56;
170+
171+
ccs
172+
}
173+
}
174+
151175
impl<N: ArrayLength<u8>> SyncStreamCipherSeek for ChaChaState<N> {
152176
fn current_pos(&self) -> u64 {
153177
self.state.current_pos()
@@ -205,6 +229,23 @@ impl NewStreamCipher for ChaCha20<U8> {
205229
}
206230
}
207231

232+
impl NewStreamCipher for ChaCha20<U12> {
233+
/// Key size in bytes
234+
type KeySize = U32;
235+
/// Nonce size in bytes
236+
type NonceSize = U12;
237+
238+
fn new(key: &GenericArray<u8, Self::KeySize>, iv: &GenericArray<u8, Self::NonceSize>) -> Self {
239+
let mut out = ChaCha20 {
240+
state: ChaChaState::new(key, iv),
241+
};
242+
243+
out.gen_block();
244+
245+
out
246+
}
247+
}
248+
208249
impl<N: ArrayLength<u8>> SyncStreamCipherSeek for ChaCha20<N> {
209250
fn current_pos(&self) -> u64 {
210251
self.state.current_pos()

0 commit comments

Comments
 (0)