From d18c33d6df42032d772d91948d6d16ede40329e1 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Fri, 5 Jun 2020 22:18:58 -0700 Subject: [PATCH] Code cleanup, Linux build fixes. --- core/AES.cpp | 12 +-- core/AES.hpp | 177 ++++++++++++++++++++------------------- core/Address.hpp | 36 ++++---- core/Constants.hpp | 40 ++------- core/Dictionary.cpp | 50 ----------- core/Dictionary.hpp | 29 ------- core/Endpoint.hpp | 14 +++- osdep/LinuxNetLink.cpp | 11 +-- osdep/LinuxNetLink.hpp | 4 +- serviceiocore/GoGlue.cpp | 4 +- 10 files changed, 142 insertions(+), 235 deletions(-) diff --git a/core/AES.cpp b/core/AES.cpp index 9d92c65ab..aecd2c159 100644 --- a/core/AES.cpp +++ b/core/AES.cpp @@ -996,14 +996,14 @@ void AES::_initSW(const uint8_t key[32]) noexcept rk[7] = readuint32_t(key + 28); for (int i = 0;;) { uint32_t temp = rk[7]; - rk[8] = rk[0] ^ (Te2[(temp >> 16U) & 0xff] & 0xff000000) ^ (Te3[(temp >> 8U) & 0xff] & 0x00ff0000) ^ (Te0[(temp) & 0xff] & 0x0000ff00) ^ (Te1[(temp >> 24U)] & 0x000000ff) ^ rcon[i]; + rk[8] = rk[0] ^ (Te2[(temp >> 16U) & 0xffU] & 0xff000000U) ^ (Te3[(temp >> 8U) & 0xffU] & 0x00ff0000U) ^ (Te0[(temp) & 0xffU] & 0x0000ff00U) ^ (Te1[(temp >> 24U)] & 0x000000ffU) ^ rcon[i]; rk[9] = rk[1] ^ rk[8]; rk[10] = rk[2] ^ rk[9]; rk[11] = rk[3] ^ rk[10]; if (++i == 7) break; temp = rk[11]; - rk[12] = rk[4] ^ (Te2[(temp >> 24U)] & 0xff000000) ^ (Te3[(temp >> 16U) & 0xff] & 0x00ff0000) ^ (Te0[(temp >> 8U) & 0xff] & 0x0000ff00) ^ (Te1[(temp) & 0xff] & 0x000000ff); + rk[12] = rk[4] ^ (Te2[(temp >> 24U)] & 0xff000000U) ^ (Te3[(temp >> 16U) & 0xffU] & 0x00ff0000U) ^ (Te0[(temp >> 8U) & 0xffU] & 0x0000ff00U) ^ (Te1[(temp) & 0xffU] & 0x000000ffU); rk[13] = rk[5] ^ rk[12]; rk[14] = rk[6] ^ rk[13]; rk[15] = rk[7] ^ rk[14]; @@ -1037,10 +1037,10 @@ void AES::_initSW(const uint8_t key[32]) noexcept } for (int i = 1; i < 14; ++i) { rk += 4; - rk[0] = Td0[Te4[(rk[0] >> 24U)] & 0xff] ^ Td1[Te4[(rk[0] >> 16U) & 0xffU] & 0xff] ^ Td2[Te4[(rk[0] >> 8U) & 0xffU] & 0xffU] ^ Td3[Te4[(rk[0]) & 0xffU] & 0xffU]; - rk[1] = Td0[Te4[(rk[1] >> 24U)] & 0xff] ^ Td1[Te4[(rk[1] >> 16U) & 0xffU] & 0xff] ^ Td2[Te4[(rk[1] >> 8U) & 0xffU] & 0xffU] ^ Td3[Te4[(rk[1]) & 0xffU] & 0xffU]; - rk[2] = Td0[Te4[(rk[2] >> 24U)] & 0xff] ^ Td1[Te4[(rk[2] >> 16U) & 0xffU] & 0xff] ^ Td2[Te4[(rk[2] >> 8U) & 0xffU] & 0xffU] ^ Td3[Te4[(rk[2]) & 0xffU] & 0xffU]; - rk[3] = Td0[Te4[(rk[3] >> 24U)] & 0xff] ^ Td1[Te4[(rk[3] >> 16U) & 0xffU] & 0xff] ^ Td2[Te4[(rk[3] >> 8U) & 0xffU] & 0xffU] ^ Td3[Te4[(rk[3]) & 0xffU] & 0xffU]; + rk[0] = Td0[Te4[(rk[0] >> 24U)] & 0xffU] ^ Td1[Te4[(rk[0] >> 16U) & 0xffU] & 0xffU] ^ Td2[Te4[(rk[0] >> 8U) & 0xffU] & 0xffU] ^ Td3[Te4[(rk[0]) & 0xffU] & 0xffU]; + rk[1] = Td0[Te4[(rk[1] >> 24U)] & 0xffU] ^ Td1[Te4[(rk[1] >> 16U) & 0xffU] & 0xffU] ^ Td2[Te4[(rk[1] >> 8U) & 0xffU] & 0xffU] ^ Td3[Te4[(rk[1]) & 0xffU] & 0xffU]; + rk[2] = Td0[Te4[(rk[2] >> 24U)] & 0xffU] ^ Td1[Te4[(rk[2] >> 16U) & 0xffU] & 0xffU] ^ Td2[Te4[(rk[2] >> 8U) & 0xffU] & 0xffU] ^ Td3[Te4[(rk[2]) & 0xffU] & 0xffU]; + rk[3] = Td0[Te4[(rk[3] >> 24U)] & 0xffU] ^ Td1[Te4[(rk[3] >> 16U) & 0xffU] & 0xffU] ^ Td2[Te4[(rk[3] >> 8U) & 0xffU] & 0xffU] ^ Td3[Te4[(rk[3]) & 0xffU] & 0xffU]; } } diff --git a/core/AES.hpp b/core/AES.hpp index dc3549d2e..d5ff0a355 100644 --- a/core/AES.hpp +++ b/core/AES.hpp @@ -18,17 +18,9 @@ #include "Utils.hpp" #include "SHA512.hpp" -#include -#include - -#ifndef ZT_AES_NO_ACCEL -#ifdef ZT_ARCH_X64 -#include -#include -#include +#if !defined(ZT_AES_NO_ACCEL) && defined(ZT_ARCH_X64) #define ZT_AES_AESNI 1 #endif -#endif namespace ZeroTier { @@ -56,7 +48,8 @@ public: /** * Create an un-initialized AES instance (must call init() before use) */ - ZT_INLINE AES() noexcept {} + ZT_INLINE AES() noexcept + {} /** * Create an AES instance with the given key @@ -70,7 +63,7 @@ public: ZT_INLINE ~AES() { - Utils::burn(&_k,sizeof(_k)); + Utils::burn(&_k, sizeof(_k)); } /** @@ -95,15 +88,15 @@ public: * @param in Input block * @param out Output block (can be same as input) */ - ZT_INLINE void encrypt(const void *const in,void *const out) const noexcept + ZT_INLINE void encrypt(const void *const in, void *const out) const noexcept { #ifdef ZT_AES_AESNI if (likely(Utils::CPUID.aes)) { - _encrypt_aesni(in,out); + _encrypt_aesni(in, out); return; } #endif - _encryptSW(reinterpret_cast(in),reinterpret_cast(out)); + _encryptSW(reinterpret_cast(in), reinterpret_cast(out)); } /** @@ -112,18 +105,19 @@ public: * @param in Input block * @param out Output block (can be same as input) */ - ZT_INLINE void decrypt(const void *const in,void *const out) const noexcept + ZT_INLINE void decrypt(const void *const in, void *const out) const noexcept { #ifdef ZT_AES_AESNI if (likely(Utils::CPUID.aes)) { - _decrypt_aesni(in,out); + _decrypt_aesni(in, out); return; } #endif - _decryptSW(reinterpret_cast(in),reinterpret_cast(out)); + _decryptSW(reinterpret_cast(in), reinterpret_cast(out)); } class GMACSIVEncryptor; + class GMACSIVDecryptor; /** @@ -132,6 +126,7 @@ public: class GMAC { friend class GMACSIVEncryptor; + friend class GMACSIVDecryptor; public: @@ -140,7 +135,8 @@ public: * * @param aes Keyed AES instance to use */ - ZT_INLINE GMAC(const AES &aes) : _aes(aes) {} + ZT_INLINE GMAC(const AES &aes) : _aes(aes) + {} /** * Reset and initialize for a new GMAC calculation @@ -176,7 +172,7 @@ public: * @param data Bytes to process * @param len Length of input */ - void update(const void *data,unsigned int len) noexcept; + void update(const void *data, unsigned int len) noexcept; /** * Process any remaining cached bytes and generate tag @@ -205,10 +201,12 @@ public: class CTR { friend class GMACSIVEncryptor; + friend class GMACSIVDecryptor; public: - ZT_INLINE CTR(const AES &aes) noexcept : _aes(aes) {} + ZT_INLINE CTR(const AES &aes) noexcept: _aes(aes) + {} /** * Initialize this CTR instance to encrypt a new stream @@ -216,9 +214,9 @@ public: * @param iv Unique initialization vector and initial 32-bit counter (least significant 32 bits, big-endian) * @param output Buffer to which to store output (MUST be large enough for total bytes processed!) */ - ZT_INLINE void init(const uint8_t iv[16],void *const output) noexcept + ZT_INLINE void init(const uint8_t iv[16], void *const output) noexcept { - Utils::copy<16>(_ctr,iv); + Utils::copy< 16 >(_ctr, iv); _out = reinterpret_cast(output); _len = 0; } @@ -230,9 +228,9 @@ public: * @param ic Initial counter (must be in big-endian byte order!) * @param output Buffer to which to store output (MUST be large enough for total bytes processed!) */ - ZT_INLINE void init(const uint8_t iv[12],const uint32_t ic,void *const output) noexcept + ZT_INLINE void init(const uint8_t iv[12], const uint32_t ic, void *const output) noexcept { - Utils::copy<12>(_ctr,iv); + Utils::copy< 12 >(_ctr, iv); reinterpret_cast(_ctr)[3] = ic; _out = reinterpret_cast(output); _len = 0; @@ -244,7 +242,7 @@ public: * @param input Input data * @param len Length of input */ - void crypt(const void *input,unsigned int len) noexcept; + void crypt(const void *input, unsigned int len) noexcept; /** * Finish any remaining bytes if total bytes processed wasn't a multiple of 16 @@ -280,9 +278,10 @@ public: * @param k0 First of two AES instances keyed with K0 * @param k1 Second of two AES instances keyed with K1 */ - ZT_INLINE GMACSIVEncryptor(const AES &k0,const AES &k1) noexcept : + ZT_INLINE GMACSIVEncryptor(const AES &k0, const AES &k1) noexcept: _gmac(k0), - _ctr(k1) {} + _ctr(k1) + {} /** * Initialize AES-GMAC-SIV @@ -290,7 +289,7 @@ public: * @param iv IV in network byte order (byte order in which it will appear on the wire) * @param output Pointer to buffer to receive ciphertext, must be large enough for all to-be-processed data! */ - ZT_INLINE void init(const uint64_t iv,void *const output) noexcept + ZT_INLINE void init(const uint64_t iv, void *const output) noexcept { // Output buffer to receive the result of AES-CTR encryption. _output = output; @@ -312,15 +311,15 @@ public: * @param aad Additional authenticated data * @param len Length of AAD in bytes */ - ZT_INLINE void aad(const void *const aad,unsigned int len) noexcept + ZT_INLINE void aad(const void *const aad, unsigned int len) noexcept { // Feed ADD into GMAC first - _gmac.update(aad,len); + _gmac.update(aad, len); // End of AAD is padded to a multiple of 16 bytes to ensure unique encoding. len &= 0xfU; if (len != 0) - _gmac.update(Utils::ZERO256,16 - len); + _gmac.update(Utils::ZERO256, 16 - len); } /** @@ -329,9 +328,9 @@ public: * @param input Plaintext chunk * @param len Length of plaintext chunk */ - ZT_INLINE void update1(const void *const input,const unsigned int len) noexcept + ZT_INLINE void update1(const void *const input, const unsigned int len) noexcept { - _gmac.update(input,len); + _gmac.update(input, len); } /** @@ -350,7 +349,7 @@ public: // packet and then recombined on receipt for legacy reasons (but with no // cryptographic or performance impact). _tag[1] = tmp[0] ^ tmp[1]; - _ctr._aes.encrypt(_tag,_tag); + _ctr._aes.encrypt(_tag, _tag); // Initialize CTR with 96-bit CTR nonce and 32-bit counter. The counter // incorporates 31 more bits of entropy which should raise our security margin @@ -362,7 +361,7 @@ public: // and so 2^31 should be considered the input limit. tmp[0] = _tag[0]; tmp[1] = _tag[1] & ZT_CONST_TO_BE_UINT64(0xffffffff7fffffffULL); - _ctr.init(reinterpret_cast(tmp),_output); + _ctr.init(reinterpret_cast(tmp), _output); } /** @@ -374,9 +373,9 @@ public: * @param input Plaintext chunk * @param len Length of plaintext chunk */ - ZT_INLINE void update2(const void *const input,const unsigned int len) noexcept + ZT_INLINE void update2(const void *const input, const unsigned int len) noexcept { - _ctr.crypt(input,len); + _ctr.crypt(input, len); } /** @@ -408,9 +407,10 @@ public: class GMACSIVDecryptor { public: - ZT_INLINE GMACSIVDecryptor(const AES &k0,const AES &k1) noexcept : + ZT_INLINE GMACSIVDecryptor(const AES &k0, const AES &k1) noexcept: _ctr(k1), - _gmac(k0) {} + _gmac(k0) + {} /** * Initialize decryptor for a new message @@ -418,14 +418,14 @@ public: * @param tag 128-bit combined IV/MAC originally created by GMAC-SIV encryption * @param output Buffer in which to write output plaintext (must be large enough!) */ - ZT_INLINE void init(const uint64_t tag[2],void *const output) noexcept + ZT_INLINE void init(const uint64_t tag[2], void *const output) noexcept { uint64_t tmp[2]; tmp[0] = tag[0]; tmp[1] = tag[1] & ZT_CONST_TO_BE_UINT64(0xffffffff7fffffffULL); - _ctr.init(reinterpret_cast(tmp),output); + _ctr.init(reinterpret_cast(tmp), output); - _ctr._aes.decrypt(tag,_ivMac); + _ctr._aes.decrypt(tag, _ivMac); tmp[0] = _ivMac[0]; tmp[1] = 0; @@ -441,12 +441,12 @@ public: * @param aad Additional authenticated data * @param len Length of AAD in bytes */ - ZT_INLINE void aad(const void *const aad,unsigned int len) noexcept + ZT_INLINE void aad(const void *const aad, unsigned int len) noexcept { - _gmac.update(aad,len); + _gmac.update(aad, len); len &= 0xfU; if (len != 0) - _gmac.update(Utils::ZERO256,16 - len); + _gmac.update(Utils::ZERO256, 16 - len); } /** @@ -457,9 +457,9 @@ public: * @param input Input ciphertext * @param len Length of ciphertext */ - ZT_INLINE void update(const void *const input,const unsigned int len) noexcept + ZT_INLINE void update(const void *const input, const unsigned int len) noexcept { - _ctr.crypt(input,len); + _ctr.crypt(input, len); _decryptedLen += len; } @@ -473,7 +473,7 @@ public: _ctr.finish(); uint64_t gmacTag[2]; - _gmac.update(_output,_decryptedLen); + _gmac.update(_output, _decryptedLen); _gmac.finish(reinterpret_cast(gmacTag)); return (gmacTag[0] ^ gmacTag[1]) == _ivMac[1]; } @@ -500,18 +500,23 @@ private: static const uint32_t rcon[10]; void _initSW(const uint8_t key[32]) noexcept; - void _encryptSW(const uint8_t in[16],uint8_t out[16]) const noexcept; - void _decryptSW(const uint8_t in[16],uint8_t out[16]) const noexcept; - union { + void _encryptSW(const uint8_t in[16], uint8_t out[16]) const noexcept; + + void _decryptSW(const uint8_t in[16], uint8_t out[16]) const noexcept; + + union + { #ifdef ZT_AES_AESNI - struct { + struct + { __m128i k[28]; __m128i h[4]; // h, hh, hhh, hhhh } ni; #endif - struct { + struct + { uint64_t h[2]; uint32_t ek[60]; uint32_t dk[60]; @@ -519,47 +524,49 @@ private: } _k; #ifdef ZT_AES_AESNI + void _init_aesni(const uint8_t key[32]) noexcept; - ZT_INLINE void _encrypt_aesni(const void *const in,void *const out) const noexcept + ZT_INLINE void _encrypt_aesni(const void *const in, void *const out) const noexcept { __m128i tmp = _mm_loadu_si128((const __m128i *)in); - tmp = _mm_xor_si128(tmp,_k.ni.k[0]); - tmp = _mm_aesenc_si128(tmp,_k.ni.k[1]); - tmp = _mm_aesenc_si128(tmp,_k.ni.k[2]); - tmp = _mm_aesenc_si128(tmp,_k.ni.k[3]); - tmp = _mm_aesenc_si128(tmp,_k.ni.k[4]); - tmp = _mm_aesenc_si128(tmp,_k.ni.k[5]); - tmp = _mm_aesenc_si128(tmp,_k.ni.k[6]); - tmp = _mm_aesenc_si128(tmp,_k.ni.k[7]); - tmp = _mm_aesenc_si128(tmp,_k.ni.k[8]); - tmp = _mm_aesenc_si128(tmp,_k.ni.k[9]); - tmp = _mm_aesenc_si128(tmp,_k.ni.k[10]); - tmp = _mm_aesenc_si128(tmp,_k.ni.k[11]); - tmp = _mm_aesenc_si128(tmp,_k.ni.k[12]); - tmp = _mm_aesenc_si128(tmp,_k.ni.k[13]); - _mm_storeu_si128((__m128i *)out,_mm_aesenclast_si128(tmp,_k.ni.k[14])); + tmp = _mm_xor_si128(tmp, _k.ni.k[0]); + tmp = _mm_aesenc_si128(tmp, _k.ni.k[1]); + tmp = _mm_aesenc_si128(tmp, _k.ni.k[2]); + tmp = _mm_aesenc_si128(tmp, _k.ni.k[3]); + tmp = _mm_aesenc_si128(tmp, _k.ni.k[4]); + tmp = _mm_aesenc_si128(tmp, _k.ni.k[5]); + tmp = _mm_aesenc_si128(tmp, _k.ni.k[6]); + tmp = _mm_aesenc_si128(tmp, _k.ni.k[7]); + tmp = _mm_aesenc_si128(tmp, _k.ni.k[8]); + tmp = _mm_aesenc_si128(tmp, _k.ni.k[9]); + tmp = _mm_aesenc_si128(tmp, _k.ni.k[10]); + tmp = _mm_aesenc_si128(tmp, _k.ni.k[11]); + tmp = _mm_aesenc_si128(tmp, _k.ni.k[12]); + tmp = _mm_aesenc_si128(tmp, _k.ni.k[13]); + _mm_storeu_si128((__m128i *)out, _mm_aesenclast_si128(tmp, _k.ni.k[14])); } - ZT_INLINE void _decrypt_aesni(const void *in,void *out) const noexcept + ZT_INLINE void _decrypt_aesni(const void *in, void *out) const noexcept { __m128i tmp = _mm_loadu_si128((const __m128i *)in); - tmp = _mm_xor_si128(tmp,_k.ni.k[14]); - tmp = _mm_aesdec_si128(tmp,_k.ni.k[15]); - tmp = _mm_aesdec_si128(tmp,_k.ni.k[16]); - tmp = _mm_aesdec_si128(tmp,_k.ni.k[17]); - tmp = _mm_aesdec_si128(tmp,_k.ni.k[18]); - tmp = _mm_aesdec_si128(tmp,_k.ni.k[19]); - tmp = _mm_aesdec_si128(tmp,_k.ni.k[20]); - tmp = _mm_aesdec_si128(tmp,_k.ni.k[21]); - tmp = _mm_aesdec_si128(tmp,_k.ni.k[22]); - tmp = _mm_aesdec_si128(tmp,_k.ni.k[23]); - tmp = _mm_aesdec_si128(tmp,_k.ni.k[24]); - tmp = _mm_aesdec_si128(tmp,_k.ni.k[25]); - tmp = _mm_aesdec_si128(tmp,_k.ni.k[26]); - tmp = _mm_aesdec_si128(tmp,_k.ni.k[27]); - _mm_storeu_si128((__m128i *)out,_mm_aesdeclast_si128(tmp,_k.ni.k[0])); + tmp = _mm_xor_si128(tmp, _k.ni.k[14]); + tmp = _mm_aesdec_si128(tmp, _k.ni.k[15]); + tmp = _mm_aesdec_si128(tmp, _k.ni.k[16]); + tmp = _mm_aesdec_si128(tmp, _k.ni.k[17]); + tmp = _mm_aesdec_si128(tmp, _k.ni.k[18]); + tmp = _mm_aesdec_si128(tmp, _k.ni.k[19]); + tmp = _mm_aesdec_si128(tmp, _k.ni.k[20]); + tmp = _mm_aesdec_si128(tmp, _k.ni.k[21]); + tmp = _mm_aesdec_si128(tmp, _k.ni.k[22]); + tmp = _mm_aesdec_si128(tmp, _k.ni.k[23]); + tmp = _mm_aesdec_si128(tmp, _k.ni.k[24]); + tmp = _mm_aesdec_si128(tmp, _k.ni.k[25]); + tmp = _mm_aesdec_si128(tmp, _k.ni.k[26]); + tmp = _mm_aesdec_si128(tmp, _k.ni.k[27]); + _mm_storeu_si128((__m128i *)out, _mm_aesdeclast_si128(tmp, _k.ni.k[0])); } + #endif }; diff --git a/core/Address.hpp b/core/Address.hpp index da7d059f6..e8f464257 100644 --- a/core/Address.hpp +++ b/core/Address.hpp @@ -40,7 +40,7 @@ public: {} explicit ZT_INLINE Address(const uint8_t b[5]) noexcept: - _a(((uint64_t) b[0] << 32U) | ((uint64_t) b[1] << 24U) | ((uint64_t) b[2] << 16U) | ((uint64_t) b[3] << 8U) | (uint64_t) b[4]) + _a(((uint64_t)b[0] << 32U) | ((uint64_t)b[1] << 24U) | ((uint64_t)b[2] << 16U) | ((uint64_t)b[3] << 8U) | (uint64_t)b[4]) {} ZT_INLINE Address &operator=(const uint64_t a) noexcept @@ -55,7 +55,7 @@ public: */ ZT_INLINE void setTo(const uint8_t b[5]) noexcept { - _a = ((uint64_t) b[0] << 32U) | ((uint64_t) b[1] << 24U) | ((uint64_t) b[2] << 16U) | ((uint64_t) b[3] << 8U) | (uint64_t) b[4]; + _a = ((uint64_t)b[0] << 32U) | ((uint64_t)b[1] << 24U) | ((uint64_t)b[2] << 16U) | ((uint64_t)b[3] << 8U) | (uint64_t)b[4]; } /** @@ -65,11 +65,11 @@ public: ZT_INLINE void copyTo(uint8_t b[5]) const noexcept { const uint64_t a = _a; - b[0] = (uint8_t) (a >> 32U); - b[1] = (uint8_t) (a >> 24U); - b[2] = (uint8_t) (a >> 16U); - b[3] = (uint8_t) (a >> 8U); - b[4] = (uint8_t) a; + b[0] = (uint8_t)(a >> 32U); + b[1] = (uint8_t)(a >> 24U); + b[2] = (uint8_t)(a >> 16U); + b[3] = (uint8_t)(a >> 8U); + b[4] = (uint8_t)a; } /** @@ -92,16 +92,16 @@ public: { const uint64_t a = _a; const unsigned int m = 0xf; - s[0] = Utils::HEXCHARS[(unsigned int) (a >> 36U) & m]; - s[1] = Utils::HEXCHARS[(unsigned int) (a >> 32U) & m]; - s[2] = Utils::HEXCHARS[(unsigned int) (a >> 28U) & m]; - s[3] = Utils::HEXCHARS[(unsigned int) (a >> 24U) & m]; - s[4] = Utils::HEXCHARS[(unsigned int) (a >> 20U) & m]; - s[5] = Utils::HEXCHARS[(unsigned int) (a >> 16U) & m]; - s[6] = Utils::HEXCHARS[(unsigned int) (a >> 12U) & m]; - s[7] = Utils::HEXCHARS[(unsigned int) (a >> 8U) & m]; - s[8] = Utils::HEXCHARS[(unsigned int) (a >> 4U) & m]; - s[9] = Utils::HEXCHARS[(unsigned int) a & m]; + s[0] = Utils::HEXCHARS[(unsigned int)(a >> 36U) & m]; + s[1] = Utils::HEXCHARS[(unsigned int)(a >> 32U) & m]; + s[2] = Utils::HEXCHARS[(unsigned int)(a >> 28U) & m]; + s[3] = Utils::HEXCHARS[(unsigned int)(a >> 24U) & m]; + s[4] = Utils::HEXCHARS[(unsigned int)(a >> 20U) & m]; + s[5] = Utils::HEXCHARS[(unsigned int)(a >> 16U) & m]; + s[6] = Utils::HEXCHARS[(unsigned int)(a >> 12U) & m]; + s[7] = Utils::HEXCHARS[(unsigned int)(a >> 8U) & m]; + s[8] = Utils::HEXCHARS[(unsigned int)(a >> 4U) & m]; + s[9] = Utils::HEXCHARS[(unsigned int)a & m]; s[10] = 0; return s; } @@ -126,7 +126,7 @@ public: { return ((!_a) || ((_a >> 32U) == ZT_ADDRESS_RESERVED_PREFIX)); } ZT_INLINE unsigned long hashCode() const noexcept - { return (unsigned long) _a; } + { return (unsigned long)_a; } ZT_INLINE operator bool() const noexcept { return (_a != 0); } diff --git a/core/Constants.hpp b/core/Constants.hpp index 914ae0c07..f1ae08432 100644 --- a/core/Constants.hpp +++ b/core/Constants.hpp @@ -29,11 +29,11 @@ /** * Version bit packed into four 16-bit fields in a 64-bit unsigned integer. */ -#define ZT_VERSION_PACKED ( \ - ((uint64_t)ZEROTIER_VERSION_MAJOR << 48U) | \ - ((uint64_t)ZEROTIER_VERSION_MINOR << 32U) | \ +#define ZT_VERSION_PACKED ( \ + ((uint64_t)ZEROTIER_VERSION_MAJOR << 48U) | \ + ((uint64_t)ZEROTIER_VERSION_MINOR << 32U) | \ ((uint64_t)ZEROTIER_VERSION_REVISION << 16U) | \ - (uint64_t)ZEROTIER_VERSION_BUILD ) + ((uint64_t)ZEROTIER_VERSION_BUILD) ) /** * Length of a ZeroTier address in bytes @@ -91,7 +91,7 @@ #define ZT_SYMMETRIC_KEY_TTL 1800000 /** - * Maximum number of messages over which a key should be considered usable. + * Maximum number of messages per symmetric key. */ #define ZT_SYMMETRIC_KEY_TTL_MESSAGES 2147483648 @@ -178,7 +178,7 @@ #define ZT_PEER_PRIORITIZE_PATHS_INTERVAL 5000 /** - * Number of previous endpoints to cache for root-less re-establishment + * Number of previous endpoints to cache in peer records. */ #define ZT_PEER_ENDPOINT_CACHE_SIZE 8 @@ -201,11 +201,6 @@ */ #define ZT_MAX_BRIDGE_ROUTES 16777216 -/** - * If there is no known L2 bridging route, spam to up to this many active bridges - */ -#define ZT_MAX_BRIDGE_SPAM 32 - /** * WHOIS rate limit (we allow these to be pretty fast) */ @@ -221,30 +216,11 @@ */ #define ZT_PEER_PROBE_RESPONSE_RATE_LIMIT 5000 -/** - * Don't do expensive identity validation more often than this - * - * IPv4 and IPv6 address prefixes are hashed down to 14-bit (0-16383) integers - * using the first 24 bits for IPv4 or the first 48 bits for IPv6. These are - * then rate limited to one identity validation per this often milliseconds. - */ -#if (defined(__amd64) || defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || defined(__AMD64) || defined(__AMD64__) || defined(_M_X64) || defined(_M_AMD64)) -// AMD64 machines can do anywhere from one every 50ms to one every 10ms. This provides plenty of margin. -#define ZT_IDENTITY_VALIDATION_SOURCE_RATE_LIMIT 2000 -#else -#if (defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(_M_IX86) || defined(_X86_) || defined(__I86__)) -// 32-bit Intel machines usually average about one every 100ms -#define ZT_IDENTITY_VALIDATION_SOURCE_RATE_LIMIT 5000 -#else -// This provides a safe margin for ARM, MIPS, etc. that usually average one every 250-400ms -#define ZT_IDENTITY_VALIDATION_SOURCE_RATE_LIMIT 10000 -#endif -#endif - /** * Size of a buffer to store either a C25519 or an ECC P-384 signature * - * This must be large enough to hold all signature types. + * This must be large enough to hold all signature types, which right now is + * Curve25519 EDDSA and NIST P-384 ECDSA. */ #define ZT_SIGNATURE_BUFFER_SIZE 96 diff --git a/core/Dictionary.cpp b/core/Dictionary.cpp index ac7c9ae0e..15777a584 100644 --- a/core/Dictionary.cpp +++ b/core/Dictionary.cpp @@ -12,7 +12,6 @@ /****/ #include "Dictionary.hpp" -#include "Identity.hpp" namespace ZeroTier { @@ -124,55 +123,6 @@ char *Dictionary::getS(const char *k, char *v, const unsigned int cap) const return v; } -bool Dictionary::sign(const Identity &signer) -{ - Vector data; - encode(data, true); - uint8_t sig[ZT_SIGNATURE_BUFFER_SIZE]; - const unsigned int siglen = signer.sign(data.data(), (unsigned int) data.size(), sig, ZT_SIGNATURE_BUFFER_SIZE); - if (siglen == 0) - return false; - - uint8_t fp[ZT_ADDRESS_LENGTH + ZT_FINGERPRINT_HASH_SIZE]; - Address(signer.fingerprint().address).copyTo(fp); - Utils::copy(fp + ZT_ADDRESS_LENGTH, signer.fingerprint().hash); - - m_entries[s_signatureFingerprint].assign(fp, fp + ZT_ADDRESS_LENGTH + ZT_FINGERPRINT_HASH_SIZE); - m_entries[s_signatureData].assign(sig, sig + siglen); - - return true; -} - -Fingerprint Dictionary::signer() const -{ - SortedMap, Vector >::const_iterator sigfp(m_entries.find(s_signatureFingerprint)); - Fingerprint fp; - if ((sigfp != m_entries.end()) && (sigfp->second.size() == (ZT_ADDRESS_LENGTH + ZT_FINGERPRINT_HASH_SIZE))) { - fp.address = Address(sigfp->second.data()); - Utils::copy(fp.hash, sigfp->second.data() + ZT_ADDRESS_LENGTH); - } - return fp; -} - -bool Dictionary::verify(const Identity &signer) const -{ - SortedMap< FCV, Vector >::const_iterator sigfp(m_entries.find(s_signatureFingerprint)); - if ( - (sigfp == m_entries.end()) || - (sigfp->second.size() != (ZT_ADDRESS_LENGTH + ZT_FINGERPRINT_HASH_SIZE)) || - (Address(sigfp->second.data()) != signer.address()) || - (memcmp(sigfp->second.data() + ZT_ADDRESS_LENGTH,signer.fingerprint().hash,ZT_FINGERPRINT_HASH_SIZE) != 0)) - return false; - - SortedMap< FCV, Vector >::const_iterator sig(m_entries.find(s_signatureData)); - if ((sig == m_entries.end()) || (sig->second.empty())) - return false; - - Vector data; - encode(data, true); - return signer.verify(data.data(),(unsigned int)data.size(),sig->second.data(),(unsigned int)sig->second.size()); -} - void Dictionary::clear() { m_entries.clear(); diff --git a/core/Dictionary.hpp b/core/Dictionary.hpp index e74e3a2d5..21644226f 100644 --- a/core/Dictionary.hpp +++ b/core/Dictionary.hpp @@ -19,8 +19,6 @@ #include "Address.hpp" #include "Buf.hpp" #include "FCV.hpp" -#include "SHA512.hpp" -#include "Fingerprint.hpp" #include "Containers.hpp" namespace ZeroTier { @@ -141,33 +139,6 @@ public: return (obj.unmarshal(d.data(),(unsigned int)d.size()) > 0); } - /** - * Sign this identity - * - * This adds two fields: - * "@Si" contains the fingerprint (address followed by hash) of the signer - * "@Ss" contains the signature - * - * @param signer Signing identity (must contain secret) - * @return True if signature was successful - */ - bool sign(const Identity &signer); - - /** - * Get the signer's fingerprint for this dictionary or a NIL fingerprint if not signed. - * - * @return Signer - */ - Fingerprint signer() const; - - /** - * Verify this identity's signature - * - * @param signer - * @return - */ - bool verify(const Identity &signer) const; - /** * Erase all entries in dictionary */ diff --git a/core/Endpoint.hpp b/core/Endpoint.hpp index 495b8c00c..a4f4f1753 100644 --- a/core/Endpoint.hpp +++ b/core/Endpoint.hpp @@ -52,7 +52,7 @@ public: { memoryZero(this); } ZT_INLINE Endpoint(const ZT_Endpoint &ep) noexcept - { *this = ep; } + { Utils::copy< sizeof(ZT_Endpoint) >((ZT_Endpoint *)this, &ep); } /** * Create an endpoint for a type that uses an IP @@ -64,7 +64,7 @@ public: { if (inaddr) { this->type = et; - Utils::copy(&(this->value.ss), &(inaddr.as.ss)); + Utils::copy< sizeof(struct sockaddr_storage) >(&(this->value.ss), &(inaddr.as.ss)); } else { memoryZero(this); } @@ -139,7 +139,7 @@ public: case ZT_ENDPOINT_TYPE_IP_UDP: case ZT_ENDPOINT_TYPE_IP_TCP: case ZT_ENDPOINT_TYPE_IP_HTTP: - switch(ep.type) { + switch (ep.type) { case ZT_ENDPOINT_TYPE_IP: case ZT_ENDPOINT_TYPE_IP_UDP: case ZT_ENDPOINT_TYPE_IP_TCP: @@ -200,7 +200,11 @@ public: char *toString(char s[ZT_ENDPOINT_STRING_SIZE_MAX]) const noexcept; - ZT_INLINE String toString() const { char tmp[ZT_ENDPOINT_STRING_SIZE_MAX]; return String(toString(tmp)); } + ZT_INLINE String toString() const + { + char tmp[ZT_ENDPOINT_STRING_SIZE_MAX]; + return String(toString(tmp)); + } bool fromString(const char *s) noexcept; @@ -228,6 +232,8 @@ public: { return !(*this < ep); } }; +static_assert(sizeof(Endpoint) == sizeof(ZT_Endpoint), "size mismatch"); + } // namespace ZeroTier #endif diff --git a/osdep/LinuxNetLink.cpp b/osdep/LinuxNetLink.cpp index c1acaa37f..a62de9ee1 100644 --- a/osdep/LinuxNetLink.cpp +++ b/osdep/LinuxNetLink.cpp @@ -419,7 +419,7 @@ void LinuxNetLink::_linkDeleted(struct nlmsghdr *nlp) { Mutex::Lock l(_if_m); - if(_interfaces.contains(ifip->ifi_index)) { + if(_interfaces.find(ifip->ifi_index) != _interfaces.end()) { _interfaces.erase(ifip->ifi_index); } } @@ -1057,12 +1057,9 @@ int LinuxNetLink::_indexForInterface(const char *iface) { Mutex::Lock l(_if_m); int interface_index = -1; - Hashtable::Iterator iter(_interfaces); - int *k = NULL; - iface_entry *v = NULL; - while(iter.next(k,v)) { - if(strcmp(iface, v->ifacename) == 0) { - interface_index = v->index; + for(std::map::iterator i(_interfaces.begin());i!=_interfaces.end();++i) { + if (strcmp(iface, i->second.ifacename) == 0) { + interface_index = i->second.index; break; } } diff --git a/osdep/LinuxNetLink.hpp b/osdep/LinuxNetLink.hpp index e0ccf8829..4f4d2acb9 100644 --- a/osdep/LinuxNetLink.hpp +++ b/osdep/LinuxNetLink.hpp @@ -29,10 +29,8 @@ #include "../core/InetAddress.hpp" #include "../core/MAC.hpp" #include "Thread.hpp" -#include "../core/Hashtable.hpp" #include "../core/Mutex.hpp" - namespace ZeroTier { struct route_entry { @@ -107,7 +105,7 @@ private: char mac_bin[6]; unsigned int mtu; }; - Hashtable _interfaces; + std::map _interfaces; Mutex _if_m; // socket communication vars; diff --git a/serviceiocore/GoGlue.cpp b/serviceiocore/GoGlue.cpp index 9df07a9a8..1f938b32a 100644 --- a/serviceiocore/GoGlue.cpp +++ b/serviceiocore/GoGlue.cpp @@ -32,7 +32,9 @@ #include #include #include +#if __has_include() #include +#endif #include #include #ifdef __LINUX__ @@ -689,7 +691,7 @@ extern "C" void ZT_GoTap_setMtu(ZT_GoTap *tap,unsigned int mtu) extern "C" int ZT_isTemporaryV6Address(const char *ifname,const struct sockaddr_storage *a) { -#ifndef __WINDOWS__ +#ifdef IN6_IFF_TEMPORARY static ZT_SOCKET s_tmpV6Socket = ZT_INVALID_SOCKET; static std::mutex s_lock; std::lock_guard l(s_lock);