Skip to content

Commit

Permalink
Add StatelessTransportState::initiator_key and responder_key
Browse files Browse the repository at this point in the history
Allows for saving and restoring of keys across re-keys.

This can be useful, for example, if you are working with UDP and
need to decrypt a packet that arrived after a rekey but was sent
before the rekey.
  • Loading branch information
ColonelThirtyTwo committed Apr 7, 2022
1 parent 02f3475 commit 88cab67
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/cipherstate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ impl StatelessCipherState {
pub fn rekey_manually(&mut self, key: &[u8]) {
self.cipher.set(key);
}

pub fn key(&self) -> &[u8] {
self.cipher.get()
}
}

impl From<CipherState> for StatelessCipherState {
Expand Down
8 changes: 8 additions & 0 deletions src/resolvers/default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,10 @@ impl Cipher for CipherAesGcm {
copy_slices!(key, &mut self.key)
}

fn get(&self) -> &[u8] {
&self.key
}

fn encrypt(&self, nonce: u64, authtext: &[u8], plaintext: &[u8], out: &mut [u8]) -> usize {
let aead = aes_gcm::Aes256Gcm::new(&self.key.into());

Expand Down Expand Up @@ -248,6 +252,10 @@ impl Cipher for CipherChaChaPoly {
copy_slices!(key, &mut self.key);
}

fn get(&self) -> &[u8] {
&self.key
}

fn encrypt(&self, nonce: u64, authtext: &[u8], plaintext: &[u8], out: &mut [u8]) -> usize {
let mut nonce_bytes = [0u8; 12];
copy_slices!(nonce.to_le_bytes(), &mut nonce_bytes[4..]);
Expand Down
18 changes: 18 additions & 0 deletions src/stateless_transportstate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,24 @@ impl StatelessTransportState {
pub fn is_initiator(&self) -> bool {
self.initiator
}

/// Gets the initiator's current symmetric key.
///
/// This can be passed to `rekey_initiator_manually` to restore the state to
/// before a reykeying, in case you need to work with messages that have come in
/// before then.
pub fn initiator_key(&self) -> &[u8] {
self.cipherstates.0.key()
}

/// Gets the responder's current symmetric key.
///
/// This can be passed to `rekey_responder_manually` to restore the state to
/// before a reykeying, in case you need to work with messages that have come in
/// before then.
pub fn responder_key(&self) -> &[u8] {
self.cipherstates.1.key()
}
}

impl fmt::Debug for StatelessTransportState {
Expand Down
3 changes: 3 additions & 0 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ pub trait Cipher: Send + Sync {
/// Set the key
fn set(&mut self, key: &[u8]);

/// Get the key
fn get(&self) -> &[u8];

/// Encrypt (with associated data) a given plaintext.
fn encrypt(&self, nonce: u64, authtext: &[u8], plaintext: &[u8], out: &mut [u8]) -> usize;

Expand Down

0 comments on commit 88cab67

Please sign in to comment.