Docs, code cleanup, and protect the extra new fields of HELLO with encryption as a precaution.

This commit is contained in:
Adam Ierymenko 2017-02-05 16:19:03 -08:00
commit 43182f8f57
13 changed files with 163 additions and 116 deletions

View file

@ -293,6 +293,11 @@
*/
#define ZT_PEER_PATH_EXPIRATION ((ZT_PEER_PING_PERIOD * 4) + 3000)
/**
* Send a full HELLO every this often (ms)
*/
#define ZT_PEER_SEND_FULL_HELLO_EVERY (ZT_PEER_PING_PERIOD * 2)
/**
* How often to retry expired paths that we're still remembering
*/

View file

@ -46,7 +46,7 @@ static inline void _computeMemoryHardHash(const void *publicKey,unsigned int pub
// but is not what we want for sequential memory-harndess.
memset(genmem,0,ZT_IDENTITY_GEN_MEMORY);
Salsa20 s20(digest,256,(char *)digest + 32);
s20.encrypt20((char *)genmem,(char *)genmem,64);
s20.crypt20((char *)genmem,(char *)genmem,64);
for(unsigned long i=64;i<ZT_IDENTITY_GEN_MEMORY;i+=64) {
unsigned long k = i - 64;
*((uint64_t *)((char *)genmem + i)) = *((uint64_t *)((char *)genmem + k));
@ -57,7 +57,7 @@ static inline void _computeMemoryHardHash(const void *publicKey,unsigned int pub
*((uint64_t *)((char *)genmem + i + 40)) = *((uint64_t *)((char *)genmem + k + 40));
*((uint64_t *)((char *)genmem + i + 48)) = *((uint64_t *)((char *)genmem + k + 48));
*((uint64_t *)((char *)genmem + i + 56)) = *((uint64_t *)((char *)genmem + k + 56));
s20.encrypt20((char *)genmem + i,(char *)genmem + i,64);
s20.crypt20((char *)genmem + i,(char *)genmem + i,64);
}
// Render final digest using genmem as a lookup table
@ -67,7 +67,7 @@ static inline void _computeMemoryHardHash(const void *publicKey,unsigned int pub
uint64_t tmp = ((uint64_t *)genmem)[idx2];
((uint64_t *)genmem)[idx2] = ((uint64_t *)digest)[idx1];
((uint64_t *)digest)[idx1] = tmp;
s20.encrypt20(digest,digest,64);
s20.crypt20(digest,digest,64);
}
}

View file

@ -213,44 +213,19 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,const bool alreadyAut
const unsigned int vRevision = at<uint16_t>(ZT_PROTO_VERB_HELLO_IDX_REVISION);
const uint64_t timestamp = at<uint64_t>(ZT_PROTO_VERB_HELLO_IDX_TIMESTAMP);
Identity id;
InetAddress externalSurfaceAddress;
uint64_t planetWorldId = 0;
uint64_t planetWorldTimestamp = 0;
std::vector< std::pair<uint64_t,uint64_t> > moonIdsAndTimestamps;
{
unsigned int ptr = ZT_PROTO_VERB_HELLO_IDX_IDENTITY + id.deserialize(*this,ZT_PROTO_VERB_HELLO_IDX_IDENTITY);
// Get external surface address if present (was not in old versions)
if (ptr < size())
ptr += externalSurfaceAddress.deserialize(*this,ptr);
// Get primary planet world ID and world timestamp if present
if ((ptr + 16) <= size()) {
planetWorldId = at<uint64_t>(ptr); ptr += 8;
planetWorldTimestamp = at<uint64_t>(ptr);
}
// Get moon IDs and timestamps if present
if ((ptr + 2) <= size()) {
unsigned int numMoons = at<uint16_t>(ptr); ptr += 2;
for(unsigned int i=0;i<numMoons;++i) {
if ((World::Type)(*this)[ptr++] == World::TYPE_MOON)
moonIdsAndTimestamps.push_back(std::pair<uint64_t,uint64_t>(at<uint64_t>(ptr),at<uint64_t>(ptr + 8)));
ptr += 16;
}
}
}
if (fromAddress != id.address()) {
TRACE("dropped HELLO from %s(%s): identity not for sending address",fromAddress.toString().c_str(),_path->address().toString().c_str());
return true;
}
if (protoVersion < ZT_PROTO_VERSION_MIN) {
TRACE("dropped HELLO from %s(%s): protocol version too old",id.address().toString().c_str(),_path->address().toString().c_str());
return true;
}
Identity id;
unsigned int ptr = ZT_PROTO_VERB_HELLO_IDX_IDENTITY + id.deserialize(*this,ZT_PROTO_VERB_HELLO_IDX_IDENTITY);
if (fromAddress != id.address()) {
TRACE("dropped HELLO from %s(%s): identity does not match packet source address",fromAddress.toString().c_str(),_path->address().toString().c_str());
return true;
}
SharedPtr<Peer> peer(RR->topology->getPeer(id.address()));
if (peer) {
// We already have an identity with this address -- check for collisions
@ -324,6 +299,43 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,const bool alreadyAut
// VALID -- if we made it here, packet passed identity and authenticity checks!
// Get external surface address if present (was not in old versions)
InetAddress externalSurfaceAddress;
if (ptr < size())
ptr += externalSurfaceAddress.deserialize(*this,ptr);
// Get primary planet world ID and world timestamp if present
uint64_t planetWorldId = 0;
uint64_t planetWorldTimestamp = 0;
if ((ptr + 16) <= size()) {
planetWorldId = at<uint64_t>(ptr); ptr += 8;
planetWorldTimestamp = at<uint64_t>(ptr);
}
std::vector< std::pair<uint64_t,uint64_t> > moonIdsAndTimestamps;
if (ptr < size()) {
// Remainder of packet, if present, is encrypted
cryptField(peer->key(),ptr,size() - ptr);
// Get moon IDs and timestamps if present
if ((ptr + 2) <= size()) {
unsigned int numMoons = at<uint16_t>(ptr); ptr += 2;
for(unsigned int i=0;i<numMoons;++i) {
if ((World::Type)(*this)[ptr++] == World::TYPE_MOON)
moonIdsAndTimestamps.push_back(std::pair<uint64_t,uint64_t>(at<uint64_t>(ptr),at<uint64_t>(ptr + 8)));
ptr += 16;
}
}
// Handle COR if present (older versions don't send this)
if ((ptr + 2) <= size()) {
//const unsigned int corSize = at<uint16_t>(ptr); ptr += 2;
ptr += 2;
CertificateOfRepresentation cor;
ptr += cor.deserialize(*this,ptr);
}
}
// Learn our external surface address from other peers to help us negotiate symmetric NATs
// and detect changes to our global IP that can trigger path renegotiation.
if ((externalSurfaceAddress)&&(hops() == 0))
@ -337,6 +349,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,const bool alreadyAut
outp.append((unsigned char)ZEROTIER_ONE_VERSION_MAJOR);
outp.append((unsigned char)ZEROTIER_ONE_VERSION_MINOR);
outp.append((uint16_t)ZEROTIER_ONE_VERSION_REVISION);
if (protoVersion >= 5) {
_path->address().serialize(outp);
} else {
@ -387,6 +400,11 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,const bool alreadyAut
}
outp.setAt<uint16_t>(worldUpdateSizeAt,(uint16_t)(outp.size() - (worldUpdateSizeAt + 2)));
const unsigned int corSizeAt = outp.size();
outp.addSize(2);
RR->topology->appendCertificateOfRepresentation(outp);
outp.setAt(corSizeAt,(uint16_t)(outp.size() - (corSizeAt + 2)));
outp.armor(peer->key(),true);
_path->send(RR,outp.data(),outp.size(),now);
@ -586,7 +604,7 @@ bool IncomingPacket::_doRENDEZVOUS(const RuntimeEnvironment *RR,const SharedPtr<
const InetAddress atAddr(field(ZT_PROTO_VERB_RENDEZVOUS_IDX_ADDRESS,addrlen),addrlen,port);
if (RR->node->shouldUsePathForZeroTierTraffic(with,_path->localAddress(),atAddr)) {
RR->node->putPacket(_path->localAddress(),atAddr,"ABRE",4,2); // send low-TTL junk packet to 'open' local NAT(s) and stateful firewalls
rendezvousWith->attemptToContactAt(_path->localAddress(),atAddr,RR->node->now());
rendezvousWith->attemptToContactAt(_path->localAddress(),atAddr,RR->node->now(),false);
TRACE("RENDEZVOUS from %s says %s might be at %s, sent verification attempt",peer->address().toString().c_str(),with.toString().c_str(),atAddr.toString().c_str());
} else {
TRACE("RENDEZVOUS from %s says %s might be at %s, ignoring since path is not suitable",peer->address().toString().c_str(),with.toString().c_str(),atAddr.toString().c_str());
@ -1155,7 +1173,7 @@ bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,const Sha
if ( ((flags & ZT_PUSH_DIRECT_PATHS_FLAG_FORGET_PATH) == 0) && (!redundant) && (RR->node->shouldUsePathForZeroTierTraffic(peer->address(),_path->localAddress(),a)) ) {
if (++countPerScope[(int)a.ipScope()][0] <= ZT_PUSH_DIRECT_PATHS_MAX_PER_SCOPE_AND_FAMILY) {
TRACE("attempting to contact %s at pushed direct path %s",peer->address().toString().c_str(),a.toString().c_str());
peer->attemptToContactAt(InetAddress(),a,now);
peer->attemptToContactAt(InetAddress(),a,now,false);
} else {
TRACE("ignoring contact for %s at %s -- too many per scope",peer->address().toString().c_str(),a.toString().c_str());
}
@ -1174,7 +1192,7 @@ bool IncomingPacket::_doPUSH_DIRECT_PATHS(const RuntimeEnvironment *RR,const Sha
if ( ((flags & ZT_PUSH_DIRECT_PATHS_FLAG_FORGET_PATH) == 0) && (!redundant) && (RR->node->shouldUsePathForZeroTierTraffic(peer->address(),_path->localAddress(),a)) ) {
if (++countPerScope[(int)a.ipScope()][1] <= ZT_PUSH_DIRECT_PATHS_MAX_PER_SCOPE_AND_FAMILY) {
TRACE("attempting to contact %s at pushed direct path %s",peer->address().toString().c_str(),a.toString().c_str());
peer->attemptToContactAt(InetAddress(),a,now);
peer->attemptToContactAt(InetAddress(),a,now,false);
} else {
TRACE("ignoring contact for %s at %s -- too many per scope",peer->address().toString().c_str(),a.toString().c_str());
}

View file

@ -70,7 +70,7 @@ Node::Node(void *uptr,const struct ZT_Node_Callbacks *callbacks,uint64_t now) :
Utils::getSecureRandom(foo,32);
_prng.init(foo,256,foo);
memset(_prngStream,0,sizeof(_prngStream));
_prng.encrypt12(_prngStream,_prngStream,sizeof(_prngStream));
_prng.crypt12(_prngStream,_prngStream,sizeof(_prngStream));
std::string idtmp(dataStoreGet("identity.secret"));
if ((!idtmp.length())||(!RR->identity.fromString(idtmp))||(!RR->identity.hasPrivate())) {
@ -686,7 +686,7 @@ uint64_t Node::prng()
{
unsigned int p = (++_prngStreamPtr % ZT_NODE_PRNG_BUF_SIZE);
if (!p)
_prng.encrypt12(_prngStream,_prngStream,sizeof(_prngStream));
_prng.crypt12(_prngStream,_prngStream,sizeof(_prngStream));
return _prngStream[p];
}

View file

@ -18,9 +18,21 @@
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "Packet.hpp"
#ifdef _MSC_VER
#define FORCE_INLINE static __forceinline
#include <intrin.h>
#pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
#pragma warning(disable : 4293) /* disable: C4293: too large shift (32-bits) */
#else
#define FORCE_INLINE static inline
#endif
namespace ZeroTier {
/************************************************************************** */
@ -367,7 +379,7 @@ LZ4_decompress_*_continue() :
#define LZ4_HASH_SIZE_U32 (1 << LZ4_HASHLOG) /* required as macro for static allocation */
#if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
#include <stdint.h>
//#include <stdint.h>
typedef struct {
uint32_t hashTable[LZ4_HASH_SIZE_U32];
@ -536,6 +548,7 @@ union LZ4_streamDecode_u {
/*-************************************
* Compiler Options
**************************************/
#if 0
#ifdef _MSC_VER /* Visual Studio */
# define FORCE_INLINE static __forceinline
# include <intrin.h>
@ -550,6 +563,7 @@ union LZ4_streamDecode_u {
# define FORCE_INLINE static
# endif
#endif /* _MSC_VER */
#endif
#if (defined(__GNUC__) && (__GNUC__ >= 3)) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 800)) || defined(__clang__)
# define expect(expr,value) (__builtin_expect ((expr),(value)) )
@ -564,38 +578,39 @@ union LZ4_streamDecode_u {
/*-************************************
* Memory routines
**************************************/
#include <stdlib.h> /* malloc, calloc, free */
//#include <stdlib.h> /* malloc, calloc, free */
#define ALLOCATOR(n,s) calloc(n,s)
#define FREEMEM free
#include <string.h> /* memset, memcpy */
//#include <string.h> /* memset, memcpy */
#define MEM_INIT memset
/*-************************************
* Basic Types
**************************************/
#if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
# include <stdint.h>
//#if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
//# include <stdint.h>
typedef uint8_t BYTE;
typedef uint16_t U16;
typedef uint32_t U32;
typedef int32_t S32;
typedef uint64_t U64;
typedef uintptr_t uptrval;
#else
/*#else
typedef unsigned char BYTE;
typedef unsigned short U16;
typedef unsigned int U32;
typedef signed int S32;
typedef unsigned long long U64;
typedef size_t uptrval; /* generally true, except OpenVMS-64 */
#endif
typedef size_t uptrval;
#endif */
#if defined(__x86_64__)
typedef U64 reg_t; /* 64-bits in x32 mode */
#else
typedef size_t reg_t; /* 32-bits in x32 mode */
#endif
typedef uintptr_t reg_t;
//#if defined(__x86_64__)
// typedef U64 reg_t; /* 64-bits in x32 mode */
//#else
// typedef size_t reg_t; /* 32-bits in x32 mode */
//#endif
/*-************************************
* Reading and writing into memory
@ -606,7 +621,6 @@ static unsigned LZ4_isLittleEndian(void)
return one.c[0];
}
#if defined(LZ4_FORCE_MEMORY_ACCESS) && (LZ4_FORCE_MEMORY_ACCESS==2)
/* lie to the compiler about data alignment; use with caution */
@ -1975,10 +1989,10 @@ void Packet::armor(const void *key,bool encryptPayload)
// MAC key is always the first 32 bytes of the Salsa20 key stream
// This is the same construction DJB's NaCl library uses
s20.encrypt12(ZERO_KEY,macKey,sizeof(macKey));
s20.crypt12(ZERO_KEY,macKey,sizeof(macKey));
if (encryptPayload)
s20.encrypt12(payload,payload,payloadLen);
s20.crypt12(payload,payload,payloadLen);
Poly1305::compute(mac,payload,payloadLen,macKey);
memcpy(field(ZT_PACKET_IDX_MAC,8),mac,8);
@ -1995,20 +2009,30 @@ bool Packet::dearmor(const void *key)
if ((cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_NONE)||(cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012)) {
_salsa20MangleKey((const unsigned char *)key,mangledKey);
Salsa20 s20(mangledKey,256,field(ZT_PACKET_IDX_IV,8)/*,ZT_PROTO_SALSA20_ROUNDS*/);
Salsa20 s20(mangledKey,256,field(ZT_PACKET_IDX_IV,8));
s20.encrypt12(ZERO_KEY,macKey,sizeof(macKey));
s20.crypt12(ZERO_KEY,macKey,sizeof(macKey));
Poly1305::compute(mac,payload,payloadLen,macKey);
if (!Utils::secureEq(mac,field(ZT_PACKET_IDX_MAC,8),8))
return false;
if (cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012)
s20.decrypt12(payload,payload,payloadLen);
s20.crypt12(payload,payload,payloadLen);
return true;
} else return false; // unrecognized cipher suite
}
void Packet::cryptField(const void *key,unsigned int start,unsigned int len)
{
unsigned char mangledKey[32];
uint64_t iv = Utils::hton((uint64_t)start ^ at<uint64_t>(ZT_PACKET_IDX_IV));
_salsa20MangleKey((const unsigned char *)key,mangledKey);
Salsa20 s20(mangledKey,256,&iv);
unsigned char *const ptr = field(start,len);
s20.crypt12(ptr,ptr,len);
}
bool Packet::compress()
{
unsigned char buf[ZT_PROTO_MAX_PACKET_LENGTH * 2];

View file

@ -542,6 +542,7 @@ public:
* [<[...] destination address to which packet was sent>]
* <[8] 64-bit world ID of current planet>
* <[8] 64-bit timestamp of current planet>
* [... remainder if packet is encrypted using cryptField() ...]
* <[2] 16-bit number of moons>
* [<[1] 8-bit type ID of moon>]
* [<[8] 64-bit world ID of moon>]
@ -550,9 +551,10 @@ public:
* <[2] 16-bit length of certificate of representation>
* [... certificate of representation ...]
*
* HELLO is sent in the clear, and therefore cannot contain anything
* secret or highly confidential. It should contain nothing that is
* not either public or easy to obtain via other means.
* The initial fields of HELLO are sent in the clear. Fields after the
* planet definition (which are common knowledge) are however encrypted
* using the cryptField() function. The packet is MAC'd as usual using
* the same MAC construct as other packets.
*
* The destination address is the wire address to which this packet is
* being sent, and in OK is *also* the destination address of the OK
@ -566,7 +568,7 @@ public:
* 0x04 - 6-byte IPv4 UDP address/port -- format: <[4] IP>, <[2] port>
* 0x06 - 18-byte IPv6 UDP address/port -- format: <[16] IP>, <[2] port>
*
* OK payload:
* OK payload (note that OK is encrypted):
* <[8] timestamp (echoed from original HELLO)>
* <[1] protocol version (of responder)>
* <[1] software major version (of responder)>
@ -576,6 +578,8 @@ public:
* [<[...] destination address>]
* <[2] 16-bit length of world update or 0 if none>
* [[...] updates to planets and/or moons]
* <[2] 16-bit length of certificate of representation (of responder)>
* [... certificate of representation ...]
*
* ERROR has no payload.
*/
@ -1348,6 +1352,25 @@ public:
*/
bool dearmor(const void *key);
/**
* Encrypt/decrypt a separately armored portion of a packet
*
* This keys using the same key in the same way as armor/dearmor, but
* uses a different IV computed from the packet's IV plus the starting
* point index.
*
* This currently uses Salsa20/12, but any message that uses this should
* incorporate a cipher selector to permit this to be changed later.
*
* This is currently only used to mask portions of HELLO as an extra
* security precation since most of that message is sent in the clear.
*
* @param key 32-byte key
* @param start Start of encrypted portion
* @param len Length of encrypted portion
*/
void cryptField(const void *key,unsigned int start,unsigned int len);
/**
* Attempt to compress payload if not already (must be unencrypted)
*

View file

@ -203,7 +203,7 @@ void Peer::received(
#endif
} else {
TRACE("got %s via unknown path %s(%s), confirming...",Packet::verbString(verb),_id.address().toString().c_str(),path->address().toString().c_str());
attemptToContactAt(path->localAddress(),path->address(),now);
attemptToContactAt(path->localAddress(),path->address(),now,true);
path->sent(now);
}
}
@ -357,6 +357,8 @@ void Peer::sendHELLO(const InetAddress &localAddr,const InetAddress &atAddress,u
outp.append((uint64_t)RR->topology->planetWorldId());
outp.append((uint64_t)RR->topology->planetWorldTimestamp());
const unsigned int startCryptedPortionAt = outp.size();
std::vector<World> moons(RR->topology->moons());
outp.append((uint16_t)moons.size());
for(std::vector<World>::const_iterator m(moons.begin());m!=moons.end();++m) {
@ -368,21 +370,23 @@ void Peer::sendHELLO(const InetAddress &localAddr,const InetAddress &atAddress,u
const unsigned int corSizeAt = outp.size();
outp.addSize(2);
RR->topology->appendCertificateOfRepresentation(outp);
outp.setAt(corSizeAt,(uint16_t)((outp.size() - corSizeAt) - 2));
outp.setAt(corSizeAt,(uint16_t)(outp.size() - (corSizeAt + 2)));
outp.cryptField(_key,startCryptedPortionAt,outp.size() - startCryptedPortionAt);
RR->node->expectReplyTo(outp.packetId());
if (atAddress) {
outp.armor(_key,false);
outp.armor(_key,false); // false == don't encrypt full payload, but add MAC
RR->node->putPacket(localAddr,atAddress,outp.data(),outp.size());
} else {
RR->sw->send(outp,false);
RR->sw->send(outp,false); // false == don't encrypt full payload, but add MAC
}
}
void Peer::attemptToContactAt(const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now)
void Peer::attemptToContactAt(const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now,bool sendFullHello)
{
if ( (_vProto >= 5) && ( !((_vMajor == 1)&&(_vMinor == 1)&&(_vRevision == 0)) ) ) {
if ( (!sendFullHello) && (_vProto >= 5) && (!((_vMajor == 1)&&(_vMinor == 1)&&(_vRevision == 0))) ) {
Packet outp(_id.address(),RR->identity.address(),Packet::VERB_ECHO);
RR->node->expectReplyTo(outp.packetId());
outp.armor(_key,true);
@ -398,7 +402,7 @@ void Peer::tryMemorizedPath(uint64_t now)
_lastTriedMemorizedPath = now;
InetAddress mp;
if (RR->node->externalPathLookup(_id.address(),-1,mp))
attemptToContactAt(InetAddress(),mp,now);
attemptToContactAt(InetAddress(),mp,now,true);
}
}
@ -420,7 +424,7 @@ bool Peer::doPingAndKeepalive(uint64_t now,int inetAddressFamily)
if (bestp >= 0) {
if ( ((now - _paths[bestp].lastReceive) >= ZT_PEER_PING_PERIOD) || (_paths[bestp].path->needsHeartbeat(now)) ) {
attemptToContactAt(_paths[bestp].path->localAddress(),_paths[bestp].path->address(),now);
attemptToContactAt(_paths[bestp].path->localAddress(),_paths[bestp].path->address(),now,false);
_paths[bestp].path->sent(now);
}
return true;
@ -444,7 +448,7 @@ void Peer::resetWithinScope(InetAddress::IpScope scope,int inetAddressFamily,uin
Mutex::Lock _l(_paths_m);
for(unsigned int p=0;p<_numPaths;++p) {
if ( (_paths[p].path->address().ss_family == inetAddressFamily) && (_paths[p].path->address().ipScope() == scope) ) {
attemptToContactAt(_paths[p].path->localAddress(),_paths[p].path->address(),now);
attemptToContactAt(_paths[p].path->localAddress(),_paths[p].path->address(),now,false);
_paths[p].path->sent(now);
_paths[p].lastReceive = 0; // path will not be used unless it speaks again
}

View file

@ -161,8 +161,9 @@ public:
* @param localAddr Local address
* @param atAddress Destination address
* @param now Current time
* @param sendFullHello If true, always send a full HELLO instead of just an ECHO
*/
void attemptToContactAt(const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now);
void attemptToContactAt(const InetAddress &localAddr,const InetAddress &atAddress,uint64_t now,bool sendFullHello);
/**
* Try a memorized or statically defined path if any are known

View file

@ -123,7 +123,7 @@ void Salsa20::init(const void *key,unsigned int kbits,const void *iv)
#endif
}
void Salsa20::encrypt12(const void *in,void *out,unsigned int bytes)
void Salsa20::crypt12(const void *in,void *out,unsigned int bytes)
throw()
{
uint8_t tmp[64];
@ -623,7 +623,7 @@ void Salsa20::encrypt12(const void *in,void *out,unsigned int bytes)
}
}
void Salsa20::encrypt20(const void *in,void *out,unsigned int bytes)
void Salsa20::crypt20(const void *in,void *out,unsigned int bytes)
throw()
{
uint8_t tmp[64];

View file

@ -56,51 +56,25 @@ public:
throw();
/**
* Encrypt data using Salsa20/12
* Encrypt/decrypt data using Salsa20/12
*
* @param in Input data
* @param out Output buffer
* @param bytes Length of data
*/
void encrypt12(const void *in,void *out,unsigned int bytes)
void crypt12(const void *in,void *out,unsigned int bytes)
throw();
/**
* Encrypt data using Salsa20/20
* Encrypt/decrypt data using Salsa20/20
*
* @param in Input data
* @param out Output buffer
* @param bytes Length of data
*/
void encrypt20(const void *in,void *out,unsigned int bytes)
void crypt20(const void *in,void *out,unsigned int bytes)
throw();
/**
* Decrypt data
*
* @param in Input data
* @param out Output buffer
* @param bytes Length of data
*/
inline void decrypt12(const void *in,void *out,unsigned int bytes)
throw()
{
encrypt12(in,out,bytes);
}
/**
* Decrypt data
*
* @param in Input data
* @param out Output buffer
* @param bytes Length of data
*/
inline void decrypt20(const void *in,void *out,unsigned int bytes)
throw()
{
encrypt20(in,out,bytes);
}
private:
union {
#ifdef ZT_SALSA20_SSE

View file

@ -777,7 +777,7 @@ bool Switch::_trySend(Packet &packet,bool encrypt)
if ((clusterMostRecentMemberId < 0)||(viaPath->lastIn() > clusterMostRecentTs)) {
#endif
if ((now - viaPath->lastOut()) > std::max((now - viaPath->lastIn()) * 4,(uint64_t)ZT_PATH_MIN_REACTIVATE_INTERVAL)) {
peer->attemptToContactAt(viaPath->localAddress(),viaPath->address(),now);
peer->attemptToContactAt(viaPath->localAddress(),viaPath->address(),now,false);
viaPath->sent(now);
}
#ifdef ZT_ENABLE_CLUSTER

View file

@ -182,7 +182,7 @@ void Utils::getSecureRandom(void *buf,unsigned int bytes)
#else // not __WINDOWS__
static char randomBuf[131072];
static char randomBuf[65536];
static unsigned int randomPtr = sizeof(randomBuf);
static int devURandomFd = -1;
@ -215,7 +215,7 @@ void Utils::getSecureRandom(void *buf,unsigned int bytes)
#endif // __WINDOWS__ or not
s20.encrypt12(buf,buf,bytes);
s20.crypt12(buf,buf,bytes);
}
bool Utils::scopy(char *dest,unsigned int len,const char *src)