mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-04-26 17:03:43 +02:00
Build fixes.
This commit is contained in:
parent
4a9938dfd3
commit
5fd0e2998b
5 changed files with 62 additions and 53 deletions
|
@ -8,6 +8,7 @@
|
|||
|
||||
use std::io::Write;
|
||||
use std::mem::{MaybeUninit, size_of};
|
||||
use crate::util::{array_range, array_range_mut};
|
||||
|
||||
use crate::util::pool::PoolFactory;
|
||||
|
||||
|
@ -62,12 +63,18 @@ impl<const L: usize> Buffer<L> {
|
|||
#[inline(always)]
|
||||
pub fn as_bytes_mut(&mut self) -> &mut [u8] { &mut self.1[0..self.0] }
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_range_fixed<const START: usize, const LEN: usize>(&self) -> &[u8; LEN] { array_range::<u8, L, START, LEN>(&self.1) }
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_ptr(&self) -> *const u8 { self.1.as_ptr() }
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_mut_ptr(&mut self) -> *mut u8 { self.1.as_mut_ptr() }
|
||||
|
||||
#[inline(always)]
|
||||
pub fn as_mut_range_fixed<const START: usize, const LEN: usize>(&mut self) -> &mut [u8; LEN] { array_range_mut::<u8, L, START, LEN>(&mut self.1) }
|
||||
|
||||
/// Get all bytes after a given position.
|
||||
#[inline(always)]
|
||||
pub fn as_bytes_starting_at(&self, start: usize) -> std::io::Result<&[u8]> {
|
||||
|
|
|
@ -22,6 +22,13 @@ pub(crate) fn array_range<T, const A: usize, const START: usize, const LEN: usiz
|
|||
unsafe { &*a.as_ptr().add(START).cast::<[T; LEN]>() }
|
||||
}
|
||||
|
||||
/// Obtain a reference to a sub-array within an existing array.
|
||||
#[inline(always)]
|
||||
pub(crate) fn array_range_mut<T, const A: usize, const START: usize, const LEN: usize>(a: &mut [T; A]) -> &mut [T; LEN] {
|
||||
assert!((START + LEN) <= A);
|
||||
unsafe { &mut *a.as_mut_ptr().add(START).cast::<[T; LEN]>() }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn u64_as_bytes(i: &u64) -> &[u8; 8] { unsafe { &*(i as *const u64).cast() } }
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ impl Identity {
|
|||
let mut address;
|
||||
let mut c25519;
|
||||
let mut c25519_pub;
|
||||
let mut genmem_pool_obj = unsafe { FRANKENHASH_POW_MEMORY_POOL.get() };
|
||||
let mut genmem_pool_obj = unsafe { ADDRESS_DERVIATION_MEMORY_POOL.get() };
|
||||
loop {
|
||||
c25519 = C25519KeyPair::generate(false);
|
||||
c25519_pub = c25519.public_bytes();
|
||||
|
@ -130,7 +130,7 @@ impl Identity {
|
|||
sha.update(&c25519_pub);
|
||||
sha.update(&ed25519_pub);
|
||||
let mut digest = sha.finish();
|
||||
zt_frankenhash(&mut digest, &mut genmem_pool_obj);
|
||||
zt_address_derivation_memory_intensive_hash(&mut digest, &mut genmem_pool_obj);
|
||||
|
||||
if digest[0] < IDENTITY_V1_POW_THRESHOLD {
|
||||
let addr = Address::from_bytes(&digest[59..64]);
|
||||
|
@ -234,8 +234,8 @@ impl Identity {
|
|||
sha.update(&self.c25519);
|
||||
sha.update(&self.ed25519);
|
||||
let mut digest = sha.finish();
|
||||
let mut genmem_pool_obj = unsafe { FRANKENHASH_POW_MEMORY_POOL.get() };
|
||||
zt_frankenhash(&mut digest, &mut genmem_pool_obj);
|
||||
let mut genmem_pool_obj = unsafe { ADDRESS_DERVIATION_MEMORY_POOL.get() };
|
||||
zt_address_derivation_memory_intensive_hash(&mut digest, &mut genmem_pool_obj);
|
||||
drop(genmem_pool_obj);
|
||||
|
||||
return digest[0] < pow_threshold && Address::from_bytes(&digest[59..64]).map_or(false, |a| a == self.address);
|
||||
|
@ -286,13 +286,14 @@ impl Identity {
|
|||
|
||||
pub fn marshal<const BL: usize>(&self, buf: &mut Buffer<BL>, include_cipher_suites: u8, include_private: bool) -> std::io::Result<()> {
|
||||
let cipher_suites = self.cipher_suites() & include_cipher_suites;
|
||||
let secret = self.secret.as_ref();
|
||||
|
||||
buf.append_bytes_fixed(&self.address.to_bytes())?;
|
||||
buf.append_u8(IDENTITY_CIPHER_SUITE_X25519)?;
|
||||
buf.append_bytes_fixed(&self.c25519)?;
|
||||
buf.append_bytes_fixed(&self.ed25519)?;
|
||||
if include_private && self.secret.is_some() {
|
||||
let secret = self.secret.as_ref().unwrap();
|
||||
if include_private && secret.is_some() {
|
||||
let secret = secret.unwrap();
|
||||
buf.append_u8((C25519_SECRET_KEY_SIZE + ED25519_SECRET_KEY_SIZE) as u8)?;
|
||||
buf.append_bytes_fixed(&secret.c25519.secret_bytes().0)?;
|
||||
buf.append_bytes_fixed(&secret.ed25519.secret_bytes().0)?;
|
||||
|
@ -302,7 +303,7 @@ impl Identity {
|
|||
|
||||
if (cipher_suites & IDENTITY_CIPHER_SUITE_EC_NIST_P521) == IDENTITY_CIPHER_SUITE_EC_NIST_P521 && self.p521.is_some() {
|
||||
let p521 = self.p521.as_ref().unwrap();
|
||||
let size = if include_private && self.secret.map_or(false, |s| s.p521.is_some()) {
|
||||
let size = if include_private && secret.map_or(false, |s| s.p521.is_some()) {
|
||||
(P521_PUBLIC_KEY_SIZE + P521_PUBLIC_KEY_SIZE + P521_ECDSA_SIGNATURE_SIZE + ED25519_SIGNATURE_SIZE + P521_SECRET_KEY_SIZE + P521_SECRET_KEY_SIZE) as u16
|
||||
} else {
|
||||
(P521_PUBLIC_KEY_SIZE + P521_PUBLIC_KEY_SIZE + P521_ECDSA_SIGNATURE_SIZE + ED25519_SIGNATURE_SIZE) as u16
|
||||
|
@ -314,7 +315,7 @@ impl Identity {
|
|||
buf.append_bytes_fixed(&p521.ecdsa_self_signature)?;
|
||||
buf.append_bytes_fixed(&p521.ed25519_self_signature)?;
|
||||
if size > (P521_PUBLIC_KEY_SIZE + P521_PUBLIC_KEY_SIZE + P521_ECDSA_SIGNATURE_SIZE + ED25519_SIGNATURE_SIZE) as u16 {
|
||||
let p521s = self.secret.as_ref().unwrap().p521.as_ref().unwrap();
|
||||
let p521s = secret.unwrap().p521.as_ref().unwrap();
|
||||
buf.append_bytes_fixed(&p521s.ecdh.secret_key_bytes().0)?;
|
||||
buf.append_bytes_fixed(&p521s.ecdsa.secret_key_bytes().0)?;
|
||||
}
|
||||
|
@ -589,8 +590,8 @@ impl PartialEq for Identity {
|
|||
self.address == other.address &&
|
||||
self.c25519 == other.c25519 &&
|
||||
self.ed25519 == other.ed25519 &&
|
||||
self.p521.map_or(other.p521.is_none(), |p521| {
|
||||
other.p521.map_or(false, |other_p521| {
|
||||
self.p521.as_ref().map_or(other.p521.is_none(), |p521| {
|
||||
other.p521.as_ref().map_or(false, |other_p521| {
|
||||
p521.ecdh == other_p521.ecdh && p521.ecdsa == other_p521.ecdsa
|
||||
})
|
||||
})
|
||||
|
@ -614,7 +615,7 @@ impl PartialOrd for Identity {
|
|||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }
|
||||
}
|
||||
|
||||
const FRANKENHASH_POW_MEMORY_SIZE: usize = 2097152;
|
||||
const ADDRESS_DERIVATION_HASH_MEMORY_SIZE: usize = 2097152;
|
||||
|
||||
/// This is a compound hasher used for the work function that derives an address.
|
||||
///
|
||||
|
@ -622,26 +623,26 @@ const FRANKENHASH_POW_MEMORY_SIZE: usize = 2097152;
|
|||
/// what truly determines node identity. For FIPS purposes this can be considered a
|
||||
/// non-cryptographic hash. Its memory hardness and use in a work function is a defense
|
||||
/// in depth feature rather than a primary security feature.
|
||||
fn zt_frankenhash(digest: &mut [u8; 64], genmem_pool_obj: &mut Pooled<FrankenhashMemory, FrankenhashMemoryFactory>) {
|
||||
fn zt_address_derivation_memory_intensive_hash(digest: &mut [u8; 64], genmem_pool_obj: &mut Pooled<AddressDerivationMemory, AddressDerivationMemoryFactory>) {
|
||||
let genmem_ptr = genmem_pool_obj.0.as_mut_ptr().cast::<u8>();
|
||||
let (genmem, genmem_alias_hack) = unsafe { (&mut *slice_from_raw_parts_mut(genmem_ptr, FRANKENHASH_POW_MEMORY_SIZE), &*slice_from_raw_parts(genmem_ptr, FRANKENHASH_POW_MEMORY_SIZE)) };
|
||||
let (genmem, genmem_alias_hack) = unsafe { (&mut *slice_from_raw_parts_mut(genmem_ptr, ADDRESS_DERIVATION_HASH_MEMORY_SIZE), &*slice_from_raw_parts(genmem_ptr, ADDRESS_DERIVATION_HASH_MEMORY_SIZE)) };
|
||||
let genmem_u64_ptr = genmem_ptr.cast::<u64>();
|
||||
|
||||
let mut s20 = Salsa::new(&digest[0..32], &digest[32..40], false).unwrap();
|
||||
|
||||
s20.crypt(&crate::util::ZEROES[0..64], &mut genmem[0..64]);
|
||||
let mut i: usize = 64;
|
||||
while i < FRANKENHASH_POW_MEMORY_SIZE {
|
||||
while i < ADDRESS_DERIVATION_HASH_MEMORY_SIZE {
|
||||
let ii = i + 64;
|
||||
s20.crypt(&genmem_alias_hack[(i - 64)..i], &mut genmem[i..ii]);
|
||||
i = ii;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while i < (FRANKENHASH_POW_MEMORY_SIZE / 8) {
|
||||
while i < (ADDRESS_DERIVATION_HASH_MEMORY_SIZE / 8) {
|
||||
unsafe {
|
||||
let idx1 = (((*genmem_u64_ptr.add(i)).to_be() & 7) * 8) as usize;
|
||||
let idx2 = ((*genmem_u64_ptr.add(i + 1)).to_be() % (FRANKENHASH_POW_MEMORY_SIZE as u64 / 8)) as usize;
|
||||
let idx2 = ((*genmem_u64_ptr.add(i + 1)).to_be() % (ADDRESS_DERIVATION_HASH_MEMORY_SIZE as u64 / 8)) as usize;
|
||||
let genmem_u64_at_idx2_ptr = genmem_u64_ptr.add(idx2);
|
||||
let tmp = *genmem_u64_at_idx2_ptr;
|
||||
let digest_u64_ptr = digest.as_mut_ptr().add(idx1).cast::<u64>();
|
||||
|
@ -654,20 +655,20 @@ fn zt_frankenhash(digest: &mut [u8; 64], genmem_pool_obj: &mut Pooled<Frankenhas
|
|||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
struct FrankenhashMemory([u128; FRANKENHASH_POW_MEMORY_SIZE / 16]); // use u128 to align by 16 bytes
|
||||
struct AddressDerivationMemory([u128; ADDRESS_DERIVATION_HASH_MEMORY_SIZE / 16]); // use u128 to align by 16 bytes
|
||||
|
||||
struct FrankenhashMemoryFactory;
|
||||
struct AddressDerivationMemoryFactory;
|
||||
|
||||
impl PoolFactory<FrankenhashMemory> for FrankenhashMemoryFactory {
|
||||
impl PoolFactory<AddressDerivationMemory> for AddressDerivationMemoryFactory {
|
||||
#[inline(always)]
|
||||
fn create(&self) -> FrankenhashMemory { FrankenhashMemory([0_u128; FRANKENHASH_POW_MEMORY_SIZE / 16]) }
|
||||
fn create(&self) -> AddressDerivationMemory { AddressDerivationMemory([0_u128; ADDRESS_DERIVATION_HASH_MEMORY_SIZE / 16]) }
|
||||
|
||||
#[inline(always)]
|
||||
fn reset(&self, _: &mut FrankenhashMemory) {}
|
||||
fn reset(&self, _: &mut AddressDerivationMemory) {}
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref FRANKENHASH_POW_MEMORY_POOL: Pool<FrankenhashMemory, FrankenhashMemoryFactory> = Pool::new(0, FrankenhashMemoryFactory);
|
||||
static ref ADDRESS_DERVIATION_MEMORY_POOL: Pool<AddressDerivationMemory, AddressDerivationMemoryFactory> = Pool::new(0, AddressDerivationMemoryFactory);
|
||||
}
|
||||
|
||||
/// Purge the memory pool used to verify identities. This can be called periodically
|
||||
|
@ -675,5 +676,5 @@ lazy_static! {
|
|||
/// verification.
|
||||
#[inline(always)]
|
||||
pub(crate) fn purge_verification_memory_pool() {
|
||||
unsafe { FRANKENHASH_POW_MEMORY_POOL.purge() };
|
||||
unsafe { ADDRESS_DERVIATION_MEMORY_POOL.purge() };
|
||||
}
|
||||
|
|
|
@ -403,34 +403,26 @@ impl Peer {
|
|||
/// If explicit_endpoint is not None the packet will be sent directly to this endpoint.
|
||||
/// Otherwise it will be sent via the best direct or indirect path known.
|
||||
pub(crate) fn send_hello<CI: NodeInterface>(&self, ci: &CI, node: &Node, explicit_endpoint: Option<&Endpoint>) -> bool {
|
||||
let (path, endpoint) = if explicit_endpoint.is_some() {
|
||||
(None, explicit_endpoint.unwrap())
|
||||
} else {
|
||||
let p = self.path(node);
|
||||
if p.is_none() {
|
||||
return false;
|
||||
}
|
||||
(p, p.as_ref().unwrap().endpoint())
|
||||
};
|
||||
|
||||
let mut packet: Buffer<{ PACKET_SIZE_MAX }> = Buffer::new();
|
||||
let time_ticks = ci.time_ticks();
|
||||
|
||||
let message_id = self.next_message_id();
|
||||
let packet_header: &mut PacketHeader = packet.append_struct_get_mut().unwrap();
|
||||
let hello_fixed_headers: &mut message_component_structs::HelloFixedHeaderFields = packet.append_struct_get_mut().unwrap();
|
||||
|
||||
packet_header.id = message_id.to_ne_bytes(); // packet ID and message ID are the same when Poly1305 MAC is used
|
||||
packet_header.dest = self.identity.address.to_bytes();
|
||||
packet_header.src = node.address().to_bytes();
|
||||
packet_header.flags_cipher_hops = CIPHER_NOCRYPT_POLY1305;
|
||||
|
||||
hello_fixed_headers.verb = VERB_VL1_HELLO | VERB_FLAG_EXTENDED_AUTHENTICATION;
|
||||
hello_fixed_headers.version_proto = VERSION_PROTO;
|
||||
hello_fixed_headers.version_major = VERSION_MAJOR;
|
||||
hello_fixed_headers.version_minor = VERSION_MINOR;
|
||||
hello_fixed_headers.version_revision = (VERSION_REVISION as u16).to_be_bytes();
|
||||
hello_fixed_headers.timestamp = (time_ticks as u64).to_be_bytes();
|
||||
{
|
||||
let packet_header: &mut PacketHeader = packet.append_struct_get_mut().unwrap();
|
||||
packet_header.id = message_id.to_ne_bytes(); // packet ID and message ID are the same when Poly1305 MAC is used
|
||||
packet_header.dest = self.identity.address.to_bytes();
|
||||
packet_header.src = node.address().to_bytes();
|
||||
packet_header.flags_cipher_hops = CIPHER_NOCRYPT_POLY1305;
|
||||
}
|
||||
{
|
||||
let hello_fixed_headers: &mut message_component_structs::HelloFixedHeaderFields = packet.append_struct_get_mut().unwrap();
|
||||
hello_fixed_headers.verb = VERB_VL1_HELLO | VERB_FLAG_EXTENDED_AUTHENTICATION;
|
||||
hello_fixed_headers.version_proto = VERSION_PROTO;
|
||||
hello_fixed_headers.version_major = VERSION_MAJOR;
|
||||
hello_fixed_headers.version_minor = VERSION_MINOR;
|
||||
hello_fixed_headers.version_revision = (VERSION_REVISION as u16).to_be_bytes();
|
||||
hello_fixed_headers.timestamp = (time_ticks as u64).to_be_bytes();
|
||||
}
|
||||
|
||||
assert!(self.identity.marshal(&mut packet, IDENTITY_CIPHER_SUITE_INCLUDE_ALL, false).is_ok());
|
||||
if self.identity.cipher_suites() == IDENTITY_CIPHER_SUITE_X25519 {
|
||||
|
@ -462,16 +454,18 @@ impl Peer {
|
|||
// LEGACY: set MAC field in header to poly1305 for older nodes.
|
||||
let (_, mut poly) = salsa_poly_create(&self.static_secret, packet.struct_at::<PacketHeader>(0).unwrap(), packet.len());
|
||||
poly.update(packet.as_bytes_starting_at(PACKET_HEADER_SIZE).unwrap());
|
||||
packet_header.mac.copy_from_slice(&poly.finish()[0..8]);
|
||||
packet.as_mut_range_fixed::<HEADER_MAC_FIELD_INDEX, { HEADER_MAC_FIELD_INDEX + 8 }>().copy_from_slice(&poly.finish()[0..8]);
|
||||
|
||||
self.last_send_time_ticks.store(time_ticks, Ordering::Relaxed);
|
||||
self.total_bytes_sent.fetch_add(packet.len() as u64, Ordering::Relaxed);
|
||||
|
||||
path.as_ref().map_or_else(|| {
|
||||
explicit_endpoint.map_or_else(|| {
|
||||
self.path(node).map_or(false, |path| {
|
||||
path.log_send(time_ticks);
|
||||
self.send_to_endpoint(ci, path.endpoint(), path.local_socket(), path.local_interface(), &packet)
|
||||
})
|
||||
}, |endpoint| {
|
||||
self.send_to_endpoint(ci, endpoint, None, None, &packet)
|
||||
}, |path| {
|
||||
path.log_send(time_ticks);
|
||||
self.send_to_endpoint(ci, endpoint, path.local_socket(), path.local_interface(), &packet)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ pub fn ms_monotonic() -> i64 {
|
|||
unsafe {
|
||||
let mut tb: mach::mach_time::mach_timebase_info_data_t = std::mem::zeroed();
|
||||
if mach::mach_time::mach_timebase_info(&mut tb) == 0 {
|
||||
let mt = mach::mach_time::mach_continuous_approximate_time();
|
||||
let mt = mach::mach_time::mach_continuous_approximate_time(); // ZT doesn't need it to be *that* exact, and this is faster
|
||||
(((mt as u128) * tb.numer as u128 * 1000000_u128) / (tb.denom as u128)) as i64 // milliseconds since X
|
||||
} else {
|
||||
panic!("FATAL: mach_timebase_info() failed");
|
||||
|
|
Loading…
Add table
Reference in a new issue