diff --git a/node/ECC.hpp b/node/ECC.hpp index 6fd21a5ea..a5de9d4d8 100644 --- a/node/ECC.hpp +++ b/node/ECC.hpp @@ -35,6 +35,7 @@ #include #include +#define ZT_ECC_EPHEMERAL_PUBLIC_KEY_LEN 97 /* Single ECC P-384 key */ #define ZT_ECC_PUBLIC_KEY_SET_LEN (97 * 2) /* Two ECC P-384 keys */ #define ZT_ECC_PRIVATE_KEY_SET_LEN (48 * 2) /* Two ECC P-384 secret keys */ #define ZT_ECC_SIGNATURE_LEN 96 /* NIST P-384 ECDSA signature */ @@ -52,9 +53,10 @@ class ECC namespace ZeroTier { -#define ZT_ECC_PUBLIC_KEY_SET_LEN 64 -#define ZT_ECC_PRIVATE_KEY_SET_LEN 64 -#define ZT_ECC_SIGNATURE_LEN 96 +#define ZT_ECC_EPHEMERAL_PUBLIC_KEY_LEN 32 /* Single C25519 ECDH key */ +#define ZT_ECC_PUBLIC_KEY_SET_LEN 64 /* C25519 and Ed25519 keys */ +#define ZT_ECC_PRIVATE_KEY_SET_LEN 64 /* C25519 and Ed25519 secret keys */ +#define ZT_ECC_SIGNATURE_LEN 96 /* Ed25519 signature plus (not necessary) hash */ class ECC { diff --git a/node/Packet.cpp b/node/Packet.cpp index f0430c297..fdf9edb3f 100644 --- a/node/Packet.cpp +++ b/node/Packet.cpp @@ -1009,7 +1009,6 @@ void Packet::armor(const void *key,bool encryptPayload,const AES aesKeys[2]) { uint8_t *const data = reinterpret_cast(unsafeData()); if ((aesKeys) && (encryptPayload)) { - //char tmp0[16],tmp1[16]; setCipher(ZT_PROTO_CIPHER_SUITE__AES_GMAC_SIV); uint8_t *const payload = data + ZT_PACKET_IDX_VERB; diff --git a/node/Packet.hpp b/node/Packet.hpp index f607d1f52..930bc477a 100644 --- a/node/Packet.hpp +++ b/node/Packet.hpp @@ -59,10 +59,15 @@ * 10 - 1.4.0 ... 1.4.6 * 11 - 1.4.7 ... 1.4.8 * + Multipath capability and load balancing (beta) - * 12 - 1.4.8 ... CURRENT (1.4 series) + * 12 - 1.4.8 ... 1.16.0 * + AES-GMAC-SIV backported for faster peer-to-peer crypto + * 13 - 1.16.0 ... CURRENT + * + Old deprecated "encrypted" flag removed + * + Ephemeral keying with second encryption pass to hide HELLO etc. + * + Encrypted HELLO packets to anyone but roots + * + Remove deprecated parsing of LAN announcements */ -#define ZT_PROTO_VERSION 12 +#define ZT_PROTO_VERSION 13 /** * Minimum supported protocol version @@ -100,6 +105,18 @@ */ #define ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012 1 +/** + * Cipher suite: NONE + * + * This differs from POLY1305/NONE in that *no* crypto is done, not even + * authentication. This is for trusted local LAN interconnects for internal + * SDN use within a data center. + * + * For this mode the MAC field becomes a trusted path ID and must match the + * configured ID of a trusted path or the packet is discarded. + */ +#define ZT_PROTO_CIPHER_SUITE__NO_CRYPTO_TRUSTED_PATH 2 + /** * AES-GMAC-SIV backported from 2.x */ @@ -116,23 +133,15 @@ #define ZT_KBKDF_LABEL_AES_GMAC_SIV_K1 '1' /** - * Cipher suite: NONE - * - * This differs from POLY1305/NONE in that *no* crypto is done, not even - * authentication. This is for trusted local LAN interconnects for internal - * SDN use within a data center. + * Header flag indicating ephemeral keying and second encryption pass. * - * For this mode the MAC field becomes a trusted path ID and must match the - * configured ID of a trusted path or the packet is discarded. - */ -#define ZT_PROTO_CIPHER_SUITE__NO_CRYPTO_TRUSTED_PATH 2 - -/** - * DEPRECATED payload encrypted flag, may be re-used in the future. + * If this is set, the packet will have an ephemeral key appended to it its payload + * will be encrypted with AES-CTR using this ephemeral key and the packet's header + * as an IV. * - * This has been replaced by the three-bit cipher suite selection field. + * Note that this is a reuse of a flag that has long been deprecated and ignored. */ -#define ZT_PROTO_FLAG_ENCRYPTED 0x80 +#define ZT_PROTO_FLAG_EXTENDED_ARMOR 0x80 /** * Header flag indicating that a packet is fragmented @@ -147,66 +156,8 @@ */ #define ZT_PROTO_VERB_FLAG_COMPRESSED 0x80 -/** - * Rounds used for Salsa20 encryption in ZT - * - * Discussion: - * - * DJB (Salsa20's designer) designed Salsa20 with a significant margin of 20 - * rounds, but has said repeatedly that 12 is likely sufficient. So far (as of - * July 2015) there are no published attacks against 12 rounds, let alone 20. - * - * In cryptography, a "break" means something different from what it means in - * common discussion. If a cipher is 256 bits strong and someone finds a way - * to reduce key search to 254 bits, this constitutes a "break" in the academic - * literature. 254 bits is still far beyond what can be leveraged to accomplish - * a "break" as most people would understand it -- the actual decryption and - * reading of traffic. - * - * Nevertheless, "attacks only get better" as cryptographers like to say. As - * a result, they recommend not using anything that's shown any weakness even - * if that weakness is so far only meaningful to academics. It may be a sign - * of a deeper problem. - * - * So why choose a lower round count? - * - * Turns out the speed difference is nontrivial. On a Macbook Pro (Core i3) 20 - * rounds of SSE-optimized Salsa20 achieves ~508mb/sec/core, while 12 rounds - * hits ~832mb/sec/core. ZeroTier is designed for multiple objectives: - * security, simplicity, and performance. In this case a deference was made - * for performance. - * - * Meta discussion: - * - * The cipher is not the thing you should be paranoid about. - * - * I'll qualify that. If the cipher is known to be weak, like RC4, or has a - * key size that is too small, like DES, then yes you should worry about - * the cipher. - * - * But if the cipher is strong and your adversary is anyone other than the - * intelligence apparatus of a major superpower, you are fine in that - * department. - * - * Go ahead. Search for the last ten vulnerabilities discovered in SSL. Not - * a single one involved the breaking of a cipher. Now broaden your search. - * Look for issues with SSH, IPSec, etc. The only cipher-related issues you - * will find might involve the use of RC4 or MD5, algorithms with known - * issues or small key/digest sizes. But even weak ciphers are difficult to - * exploit in the real world -- you usually need a lot of data and a lot of - * compute time. No, virtually EVERY security vulnerability you will find - * involves a problem with the IMPLEMENTATION not with the cipher. - * - * A flaw in ZeroTier's protocol or code is incredibly, unbelievably - * more likely than a flaw in Salsa20 or any other cipher or cryptographic - * primitive it uses. We're talking odds of dying in a car wreck vs. odds of - * being personally impacted on the head by a meteorite. Nobody without a - * billion dollar budget is going to break into your network by actually - * cracking Salsa20/12 (or even /8) in the field. - * - * So stop worrying about the cipher unless you are, say, the Kremlin and your - * adversary is the NSA and the GCHQ. In that case... well that's above my - * pay grade. I'll just say defense in depth. +/* + * Rounds used for deprecated Salsa20 encryption */ #define ZT_PROTO_SALSA20_ROUNDS 12 @@ -795,7 +746,7 @@ class Packet : public Buffer * <[8] 64-bit network ID> * <[2] 16-bit length of error-related data (optional)> * <[...] error-related data (optional)> - * + * * Error related data is a Dictionary containing things like a URL * for authentication or a human-readable error message, and is * optional and may be absent or empty. @@ -1267,12 +1218,6 @@ class Packet : public Buffer { unsigned char &b = (*this)[ZT_PACKET_IDX_FLAGS]; b = (b & 0xc7) | (unsigned char)((c << 3) & 0x38); // bits: FFCCCHHH - // Set DEPRECATED "encrypted" flag -- used by pre-1.0.3 peers - if (c == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012) { - b |= ZT_PROTO_FLAG_ENCRYPTED; - } else { - b &= (~ZT_PROTO_FLAG_ENCRYPTED); - } } /** diff --git a/node/Switch.cpp b/node/Switch.cpp index 7664f7a48..06f3a476f 100644 --- a/node/Switch.cpp +++ b/node/Switch.cpp @@ -83,31 +83,7 @@ void Switch::onRemotePacket(void *tPtr,const int64_t localSocket,const InetAddre const SharedPtr path(RR->topology->getPath(localSocket,fromAddr)); path->received(now); - if (len == 13) { - /* LEGACY: before VERB_PUSH_DIRECT_PATHS, peers used broadcast - * announcements on the LAN to solve the 'same network problem.' We - * no longer send these, but we'll listen for them for a while to - * locate peers with versions <1.0.4. */ - - const Address beaconAddr(reinterpret_cast(data) + 8,5); - if (beaconAddr == RR->identity.address()) { - return; - } - if (!RR->node->shouldUsePathForZeroTierTraffic(tPtr,beaconAddr,localSocket,fromAddr)) { - return; - } - const SharedPtr peer(RR->topology->getPeer(tPtr,beaconAddr)); - if (peer) { // we'll only respond to beacons from known peers - if ((now - _lastBeaconResponse) >= 2500) { // limit rate of responses - _lastBeaconResponse = now; - Packet outp(peer->address(),RR->identity.address(),Packet::VERB_NOP); - outp.armor(peer->key(),true,peer->aesKeysIfSupported()); - Metrics::pkt_nop_out++; - path->send(RR,tPtr,outp.data(),outp.size(),now); - } - } - - } else if (len > ZT_PROTO_MIN_FRAGMENT_LENGTH) { // SECURITY: min length check is important since we do some C-style stuff below! + if (len > ZT_PROTO_MIN_FRAGMENT_LENGTH) { if (reinterpret_cast(data)[ZT_PACKET_FRAGMENT_IDX_FRAGMENT_INDICATOR] == ZT_PACKET_FRAGMENT_INDICATOR) { // Handle fragment ----------------------------------------------------