mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-25 08:27:39 +02:00
More refactoring to consolidate protocol V1 stuff.
This commit is contained in:
parent
de506dc48b
commit
75f407c137
4 changed files with 48 additions and 60 deletions
|
@ -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.
|
||||
|
|
|
@ -7,7 +7,6 @@ mod mac;
|
|||
mod path;
|
||||
mod peer;
|
||||
mod rootset;
|
||||
mod symmetricsecret;
|
||||
|
||||
pub(crate) mod node;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue