ostp/ostp-core/src/crypto/aead.rs

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
}