chacha20/
legacy.rs

1//! Legacy version of ChaCha20 with a 64-bit nonce
2
3use super::{ChaChaCore, Key, Nonce};
4use cipher::{
5    consts::{U10, U32, U64, U8},
6    generic_array::GenericArray,
7    BlockSizeUser, IvSizeUser, KeyIvInit, KeySizeUser, StreamCipherCore, StreamCipherCoreWrapper,
8    StreamCipherSeekCore, StreamClosure,
9};
10
11#[cfg(feature = "zeroize")]
12use cipher::zeroize::ZeroizeOnDrop;
13
14/// Nonce type used by [`ChaCha20Legacy`].
15pub type LegacyNonce = GenericArray<u8, U8>;
16
17/// The ChaCha20 stream cipher (legacy "djb" construction with 64-bit nonce).
18///
19/// **WARNING:** this implementation uses 32-bit counter, while the original
20/// implementation uses 64-bit counter. In other words, it does
21/// not allow encrypting of more than 256 GiB of data.
22pub type ChaCha20Legacy = StreamCipherCoreWrapper<ChaCha20LegacyCore>;
23
24/// The ChaCha20 stream cipher (legacy "djb" construction with 64-bit nonce).
25pub struct ChaCha20LegacyCore(ChaChaCore<U10>);
26
27impl KeySizeUser for ChaCha20LegacyCore {
28    type KeySize = U32;
29}
30
31impl IvSizeUser for ChaCha20LegacyCore {
32    type IvSize = U8;
33}
34
35impl BlockSizeUser for ChaCha20LegacyCore {
36    type BlockSize = U64;
37}
38
39impl KeyIvInit for ChaCha20LegacyCore {
40    #[inline(always)]
41    fn new(key: &Key, iv: &LegacyNonce) -> Self {
42        let mut padded_iv = Nonce::default();
43        padded_iv[4..].copy_from_slice(iv);
44        ChaCha20LegacyCore(ChaChaCore::new(key, &padded_iv))
45    }
46}
47
48impl StreamCipherCore for ChaCha20LegacyCore {
49    #[inline(always)]
50    fn remaining_blocks(&self) -> Option<usize> {
51        self.0.remaining_blocks()
52    }
53
54    #[inline(always)]
55    fn process_with_backend(&mut self, f: impl StreamClosure<BlockSize = Self::BlockSize>) {
56        self.0.process_with_backend(f);
57    }
58}
59
60impl StreamCipherSeekCore for ChaCha20LegacyCore {
61    type Counter = u32;
62
63    #[inline(always)]
64    fn get_block_pos(&self) -> u32 {
65        self.0.get_block_pos()
66    }
67
68    #[inline(always)]
69    fn set_block_pos(&mut self, pos: u32) {
70        self.0.set_block_pos(pos);
71    }
72}
73
74#[cfg(feature = "zeroize")]
75#[cfg_attr(docsrs, doc(cfg(feature = "zeroize")))]
76impl ZeroizeOnDrop for ChaCha20LegacyCore {}