Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update forward secrecy nonce creation counter #60

Merged
merged 1 commit into from
Sep 5, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions protocol/src/fschacha20poly1305.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::chacha20poly1305::ChaCha20Poly1305;
/// Message lengths are encoded in three bytes.
const LENGTH_BYTES: u32 = 3;
/// Ciphers are re-keyed after 224 messages (or chunks).
const REKEY_INTERVAL: u32 = 224;
const REKEY_INTERVAL: u64 = 224;
/// Static four byte prefix used on every re-key.
const REKEY_INITIAL_NONCE: [u8; 4] = [0xFF, 0xFF, 0xFF, 0xFF];

Expand Down Expand Up @@ -45,7 +45,7 @@ impl std::error::Error for Error {
#[derive(Clone, Debug)]
pub struct FSChaCha20Poly1305 {
key: [u8; 32],
message_counter: u32,
message_counter: u64,
}

impl FSChaCha20Poly1305 {
Expand All @@ -58,11 +58,13 @@ impl FSChaCha20Poly1305 {

/// Derive current nonce.
fn nonce(&self) -> [u8; 12] {
let counter_div = (self.message_counter / REKEY_INTERVAL).to_le_bytes();
let counter_mod = (self.message_counter % REKEY_INTERVAL).to_le_bytes();
let mut nonce = [0u8; 12];
// The 32-bit little-endian encoding of the number of messages with the current key.
let counter_mod = ((self.message_counter % REKEY_INTERVAL) as u32).to_le_bytes();
nonce[0..4].copy_from_slice(&counter_mod);
nonce[4..8].copy_from_slice(&counter_div);
// The 64-bit little-endian encoding of the number of rekeyings performed.
let counter_div = (self.message_counter / REKEY_INTERVAL).to_le_bytes();
nonce[4..12].copy_from_slice(&counter_div);

nonce
}
Expand Down Expand Up @@ -146,14 +148,14 @@ impl FSChaCha20 {

/// Encrypt or decrypt the 3-byte length encodings.
pub fn crypt(&mut self, chunk: &mut [u8; LENGTH_BYTES as usize]) {
let counter_mod = (self.chunk_counter / REKEY_INTERVAL).to_le_bytes();
let counter_mod = (self.chunk_counter / REKEY_INTERVAL as u32).to_le_bytes();
let mut nonce = [0u8; 12];
nonce[4..8].copy_from_slice(&counter_mod);
let mut cipher = ChaCha20::new(self.key, nonce, 0);
cipher.seek(self.block_counter);
cipher.apply_keystream(chunk);
self.block_counter += LENGTH_BYTES;
if (self.chunk_counter + 1) % REKEY_INTERVAL == 0 {
if (self.chunk_counter + 1) % REKEY_INTERVAL as u32 == 0 {
let mut key_buffer = [0u8; 32];
cipher.seek(self.block_counter);
cipher.apply_keystream(&mut key_buffer);
Expand Down
Loading