mirror of
https://github.com/signalapp/libsignal.git
synced 2026-04-25 17:25:18 +02:00
47 lines
1.4 KiB
Rust
47 lines
1.4 KiB
Rust
//
|
|
// Copyright 2021 Signal Messenger, LLC.
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
//
|
|
|
|
use aes::Aes256;
|
|
use aes::cipher::typenum::Unsigned;
|
|
use aes::cipher::{InnerIvInit, KeyInit, StreamCipher, StreamCipherSeek};
|
|
|
|
use crate::error::{Error, Result};
|
|
|
|
/// A wrapper around [`ctr::Ctr32BE`] that uses a smaller nonce and supports an initial counter.
|
|
pub struct Aes256Ctr32(ctr::Ctr32BE<Aes256>);
|
|
|
|
impl Aes256Ctr32 {
|
|
pub const NONCE_SIZE: usize = <Aes256 as aes::cipher::BlockSizeUser>::BlockSize::USIZE - 4;
|
|
|
|
pub fn new(aes256: Aes256, nonce: &[u8], init_ctr: u32) -> Result<Self> {
|
|
if nonce.len() != Self::NONCE_SIZE {
|
|
return Err(Error::InvalidNonceSize);
|
|
}
|
|
|
|
let mut nonce_block = [0u8; <Aes256 as aes::cipher::BlockSizeUser>::BlockSize::USIZE];
|
|
nonce_block[0..Self::NONCE_SIZE].copy_from_slice(nonce);
|
|
|
|
let mut ctr =
|
|
ctr::Ctr32BE::from_core(ctr::CtrCore::inner_iv_init(aes256, &nonce_block.into()));
|
|
ctr.seek(
|
|
(<Aes256 as aes::cipher::BlockSizeUser>::BlockSize::USIZE as u64) * (init_ctr as u64),
|
|
);
|
|
|
|
Ok(Self(ctr))
|
|
}
|
|
|
|
pub fn from_key(key: &[u8], nonce: &[u8], init_ctr: u32) -> Result<Self> {
|
|
Self::new(
|
|
Aes256::new_from_slice(key).map_err(|_| Error::InvalidKeySize)?,
|
|
nonce,
|
|
init_ctr,
|
|
)
|
|
}
|
|
|
|
pub fn process(&mut self, buf: &mut [u8]) {
|
|
self.0.apply_keystream(buf);
|
|
}
|
|
}
|