mirror of https://github.com/ospab/ostp.git
64 lines
1.7 KiB
Rust
64 lines
1.7 KiB
Rust
use chacha20poly1305::aead::{Aead, KeyInit};
|
|
use chacha20poly1305::{ChaCha20Poly1305, Key, Nonce};
|
|
|
|
use crate::protocol::ProtocolError;
|
|
|
|
const NONCE_LEN: usize = 12;
|
|
|
|
pub struct SessionCipher {
|
|
inner: ChaCha20Poly1305,
|
|
}
|
|
|
|
impl SessionCipher {
|
|
pub fn new(key_material: &[u8; 32]) -> Self {
|
|
let key = Key::from_slice(key_material);
|
|
Self {
|
|
inner: ChaCha20Poly1305::new(key),
|
|
}
|
|
}
|
|
|
|
pub fn encrypt(
|
|
&self,
|
|
nonce_counter: u64,
|
|
plaintext: &[u8],
|
|
aad: &[u8],
|
|
) -> Result<Vec<u8>, ProtocolError> {
|
|
let nonce_bytes = nonce_from_counter(nonce_counter);
|
|
let nonce = Nonce::from_slice(&nonce_bytes);
|
|
self.inner
|
|
.encrypt(
|
|
nonce,
|
|
chacha20poly1305::aead::Payload {
|
|
msg: plaintext,
|
|
aad,
|
|
},
|
|
)
|
|
.map_err(|_| ProtocolError::Crypto("aead-encrypt".to_string()))
|
|
}
|
|
|
|
pub fn decrypt(
|
|
&self,
|
|
nonce_counter: u64,
|
|
ciphertext: &[u8],
|
|
aad: &[u8],
|
|
) -> Result<Vec<u8>, ProtocolError> {
|
|
let nonce_bytes = nonce_from_counter(nonce_counter);
|
|
let nonce = Nonce::from_slice(&nonce_bytes);
|
|
self.inner
|
|
.decrypt(
|
|
nonce,
|
|
chacha20poly1305::aead::Payload {
|
|
msg: ciphertext,
|
|
aad,
|
|
},
|
|
)
|
|
.map_err(|_| ProtocolError::Crypto("aead-decrypt".to_string()))
|
|
}
|
|
}
|
|
|
|
fn nonce_from_counter(counter: u64) -> [u8; NONCE_LEN] {
|
|
let mut nonce = [0_u8; NONCE_LEN];
|
|
nonce[4..].copy_from_slice(&counter.to_be_bytes());
|
|
nonce
|
|
}
|