bramble-transport 0.1.0

Bramble Transport Protocol
Documentation
//! BTP rotation mode

use super::{Keychain, RotateKeys};
use crate::Result;
use bramble_common::transport::{Id, Latency};
use bramble_crypto::{kdf, Role, SymmetricKey};
use futures::{AsyncRead, AsyncWrite};
use std::marker::PhantomData;

/// Key rotator for handshake mode
pub struct HandshakeKeys<T>
where
    T: Id + Latency + AsyncRead + AsyncWrite,
{
    root_key: SymmetricKey,
    role: Role,
    transport: PhantomData<T>,
}

impl<T> RotateKeys for HandshakeKeys<T>
where
    T: Id + Latency + AsyncRead + AsyncWrite,
{
    fn outgoing_keys_for(&mut self, period: u64) -> Result<Keychain> {
        Ok(self.derive_outgoing_keys(period))
    }

    fn incoming_keys_for(&mut self, period: u64) -> Result<Keychain> {
        Ok(self.derive_incoming_keys(period))
    }
}

impl<T> HandshakeKeys<T>
where
    T: Id + Latency + AsyncRead + AsyncWrite,
{
    /// Creates a new handshake mode key rotator
    pub fn new(root_key: SymmetricKey, role: Role) -> Self {
        Self {
            root_key,
            role,
            transport: PhantomData,
        }
    }

    fn derive_outgoing_keys(&self, period: u64) -> Keychain {
        let (our_tag_key_label, our_header_key_label) = match self.role {
            Role::Alice => (
                ALICE_HANDSHAKE_TAG_KEY_LABEL,
                ALICE_HANDSHAKE_HEADER_KEY_LABEL,
            ),
            Role::Bob => (BOB_HANDSHAKE_TAG_KEY_LABEL, BOB_HANDSHAKE_HEADER_KEY_LABEL),
        };
        self.derive_keys(period, our_tag_key_label, our_header_key_label)
    }

    fn derive_incoming_keys(&self, period: u64) -> Keychain {
        let (their_tag_key_label, their_header_key_label) = match self.role {
            Role::Alice => (BOB_HANDSHAKE_TAG_KEY_LABEL, BOB_HANDSHAKE_HEADER_KEY_LABEL),
            Role::Bob => (
                ALICE_HANDSHAKE_TAG_KEY_LABEL,
                ALICE_HANDSHAKE_HEADER_KEY_LABEL,
            ),
        };
        self.derive_keys(period, their_tag_key_label, their_header_key_label)
    }

    fn derive_keys(
        &self,
        period: u64,
        tag_key_label: &'static [u8],
        header_key_label: &'static [u8],
    ) -> Keychain {
        Keychain::new(
            kdf(
                tag_key_label,
                &self.root_key,
                &[T::ID, &period.to_be_bytes()],
            ),
            kdf(
                header_key_label,
                &self.root_key,
                &[T::ID, &period.to_be_bytes()],
            ),
        )
    }
}

const ALICE_HANDSHAKE_TAG_KEY_LABEL: &[u8] =
    b"org.briarproject.bramble.transport/ALICE_HANDSHAKE_TAG_KEY";
const ALICE_HANDSHAKE_HEADER_KEY_LABEL: &[u8] =
    b"org.briarproject.bramble.transport/ALICE_HANDSHAKE_HEADER_KEY";
const BOB_HANDSHAKE_TAG_KEY_LABEL: &[u8] =
    b"org.briarproject.bramble.transport/BOB_HANDSHAKE_TAG_KEY";
const BOB_HANDSHAKE_HEADER_KEY_LABEL: &[u8] =
    b"org.briarproject.bramble.transport/BOB_HANDSHAKE_HEADER_KEY";