More refactoring to consolidate protocol V1 stuff.

This commit is contained in:
Adam Ierymenko 2022-09-29 14:03:38 -04:00
parent de506dc48b
commit 75f407c137
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
4 changed files with 48 additions and 60 deletions

View file

@ -6,7 +6,11 @@ use std::mem::MaybeUninit;
use crate::vl1::Address;
use zerotier_utils::buffer::{Buffer, PooledBufferFactory};
use zerotier_utils::pool::{Pool, Pooled};
use zerotier_utils::pool::{Pool, PoolFactory, Pooled};
use zerotier_crypto::aes_gmac_siv::AesGmacSiv;
use zerotier_crypto::hash::hmac_sha384;
use zerotier_crypto::secret::Secret;
/*
* Legacy V1 protocol versions:
@ -482,6 +486,41 @@ pub(crate) mod v1 {
}
}
}
/// A V1 symmetric secret with master key and sub-keys for AES-GMAC-SIV
pub(crate) struct SymmetricSecret {
pub key: Secret<64>,
pub aes_gmac_siv: Pool<AesGmacSiv, AesGmacSivPoolFactory>,
}
fn zt_kbkdf_hmac_sha384(key: &[u8], label: u8) -> Secret<48> {
Secret(hmac_sha384(key, &[0, 0, 0, 0, b'Z', b'T', label, 0, 0, 0, 0, 0x01, 0x80]))
}
impl SymmetricSecret {
/// Create a new symmetric secret, deriving all sub-keys and such.
pub fn new(key: Secret<64>) -> SymmetricSecret {
let aes_factory = AesGmacSivPoolFactory(
zt_kbkdf_hmac_sha384(&key.0[..48], v1::KBKDF_KEY_USAGE_LABEL_AES_GMAC_SIV_K0).first_n_clone(),
zt_kbkdf_hmac_sha384(&key.0[..48], v1::KBKDF_KEY_USAGE_LABEL_AES_GMAC_SIV_K1).first_n_clone(),
);
SymmetricSecret { key, aes_gmac_siv: Pool::new(2, aes_factory) }
}
}
pub(crate) struct AesGmacSivPoolFactory(Secret<32>, Secret<32>);
impl PoolFactory<AesGmacSiv> for AesGmacSivPoolFactory {
#[inline(always)]
fn create(&self) -> AesGmacSiv {
AesGmacSiv::new(self.0.as_bytes(), self.1.as_bytes())
}
#[inline(always)]
fn reset(&self, obj: &mut AesGmacSiv) {
obj.reset();
}
}
}
/// Maximum delta between the message ID of a sent packet and its response.

View file

@ -7,7 +7,6 @@ mod mac;
mod path;
mod peer;
mod rootset;
mod symmetricsecret;
pub(crate) mod node;

View file

@ -19,7 +19,6 @@ use crate::protocol::*;
use crate::vl1::address::Address;
use crate::vl1::debug_event;
use crate::vl1::node::*;
use crate::vl1::symmetricsecret::SymmetricSecret;
use crate::vl1::{Endpoint, Identity, Path};
use crate::{VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION};
@ -28,7 +27,7 @@ pub(crate) const SERVICE_INTERVAL_MS: i64 = 10000;
pub struct Peer<HostSystemImpl: HostSystem> {
pub identity: Identity,
static_symmetric_key: SymmetricSecret,
v1_proto_static_secret: v1::SymmetricSecret,
paths: Mutex<Vec<PeerPath<HostSystemImpl>>>,
pub(crate) last_send_time_ticks: AtomicI64,
@ -67,7 +66,7 @@ impl<HostSystemImpl: HostSystem> Peer<HostSystemImpl> {
this_node_identity.agree(&id).map(|static_secret| -> Self {
Self {
identity: id,
static_symmetric_key: SymmetricSecret::new(static_secret),
v1_proto_static_secret: v1::SymmetricSecret::new(static_secret),
paths: Mutex::new(Vec::with_capacity(4)),
last_send_time_ticks: AtomicI64::new(NEVER_HAPPENED_TICKS),
last_receive_time_ticks: AtomicI64::new(NEVER_HAPPENED_TICKS),
@ -294,7 +293,7 @@ impl<HostSystemImpl: HostSystem> Peer<HostSystemImpl> {
v1::CIPHER_AES_GMAC_SIV
};
let mut aes_gmac_siv = self.static_symmetric_key.aes_gmac_siv.get();
let mut aes_gmac_siv = self.v1_proto_static_secret.aes_gmac_siv.get();
aes_gmac_siv.encrypt_init(&self.v1_proto_next_message_id().to_ne_bytes());
aes_gmac_siv.encrypt_set_aad(&v1::get_packet_aad_bytes(
self.identity.address,
@ -325,7 +324,7 @@ impl<HostSystemImpl: HostSystem> Peer<HostSystemImpl> {
};
let (mut salsa, poly1305_otk) = v1_proto_salsa_poly_create(
&self.static_symmetric_key,
&self.v1_proto_static_secret,
{
let header = packet.struct_mut_at::<v1::PacketHeader>(0).unwrap();
header.id = self.v1_proto_next_message_id().to_ne_bytes();
@ -412,7 +411,7 @@ impl<HostSystemImpl: HostSystem> Peer<HostSystemImpl> {
assert!(node.identity.write_public(&mut packet, self.identity.p384.is_none()).is_ok());
let (_, poly1305_key) = v1_proto_salsa_poly_create(
&self.static_symmetric_key,
&self.v1_proto_static_secret,
packet.struct_at::<v1::PacketHeader>(0).unwrap(),
packet.len(),
);
@ -468,7 +467,7 @@ impl<HostSystemImpl: HostSystem> Peer<HostSystemImpl> {
let mut payload = PacketBuffer::new();
let message_id = if let Some(message_id2) = v1_proto_try_aead_decrypt(
&self.static_symmetric_key,
&self.v1_proto_static_secret,
packet_frag0_payload_bytes,
packet_header,
fragments,
@ -870,7 +869,7 @@ impl<HostSystemImpl: HostSystem> PartialEq for Peer<HostSystemImpl> {
impl<HostSystemImpl: HostSystem> Eq for Peer<HostSystemImpl> {}
fn v1_proto_try_aead_decrypt(
secret: &SymmetricSecret,
secret: &v1::SymmetricSecret,
packet_frag0_payload_bytes: &[u8],
packet_header: &v1::PacketHeader,
fragments: &[Option<PooledPacketBuffer>],
@ -952,7 +951,7 @@ fn v1_proto_try_aead_decrypt(
}
}
fn v1_proto_salsa_poly_create(secret: &SymmetricSecret, header: &v1::PacketHeader, packet_size: usize) -> (Salsa<12>, [u8; 32]) {
fn v1_proto_salsa_poly_create(secret: &v1::SymmetricSecret, header: &v1::PacketHeader, packet_size: usize) -> (Salsa<12>, [u8; 32]) {
// Create a per-packet key from the IV, source, destination, and packet size.
let mut key: Secret<32> = secret.key.first_n_clone();
let hb = header.as_bytes();

View file

@ -1,49 +0,0 @@
// (c) 2020-2022 ZeroTier, Inc. -- currently propritery pending actual release and licensing. See LICENSE.md.
use zerotier_crypto::aes_gmac_siv::AesGmacSiv;
use zerotier_crypto::hash::hmac_sha384;
use zerotier_crypto::secret::Secret;
use crate::protocol::*;
use zerotier_utils::pool::{Pool, PoolFactory};
/// A symmetric secret key negotiated between peers.
///
/// This contains the key and several sub-keys and ciphers keyed with sub-keys.
pub(crate) struct SymmetricSecret {
/// Master key from which other keys are derived.
pub key: Secret<64>,
/// Pool of keyed AES-GMAC-SIV engines (pooled to avoid AES re-init every time).
pub aes_gmac_siv: Pool<AesGmacSiv, AesGmacSivPoolFactory>,
}
fn zt_kbkdf_hmac_sha384(key: &[u8], label: u8) -> Secret<48> {
Secret(hmac_sha384(key, &[0, 0, 0, 0, b'Z', b'T', label, 0, 0, 0, 0, 0x01, 0x80]))
}
impl SymmetricSecret {
/// Create a new symmetric secret, deriving all sub-keys and such.
pub fn new(key: Secret<64>) -> SymmetricSecret {
let aes_factory = AesGmacSivPoolFactory(
zt_kbkdf_hmac_sha384(&key.0[..48], v1::KBKDF_KEY_USAGE_LABEL_AES_GMAC_SIV_K0).first_n_clone(),
zt_kbkdf_hmac_sha384(&key.0[..48], v1::KBKDF_KEY_USAGE_LABEL_AES_GMAC_SIV_K1).first_n_clone(),
);
SymmetricSecret { key, aes_gmac_siv: Pool::new(2, aes_factory) }
}
}
pub(crate) struct AesGmacSivPoolFactory(Secret<32>, Secret<32>);
impl PoolFactory<AesGmacSiv> for AesGmacSivPoolFactory {
#[inline(always)]
fn create(&self) -> AesGmacSiv {
AesGmacSiv::new(self.0.as_bytes(), self.1.as_bytes())
}
#[inline(always)]
fn reset(&self, obj: &mut AesGmacSiv) {
obj.reset();
}
}