This commit is contained in:
Grant Limberg 2020-09-10 11:38:25 -07:00
commit 7d0f6933d6
No known key found for this signature in database
GPG key ID: 2BA62CCABBB4095A
5 changed files with 46 additions and 30 deletions

View file

@ -65,8 +65,8 @@ ifeq ($(ZT_SANITIZE),1)
SANFLAGS+=-fsanitize=address -DASAN_OPTIONS=symbolize=1 SANFLAGS+=-fsanitize=address -DASAN_OPTIONS=symbolize=1
endif endif
ifeq ($(ZT_DEBUG),1) ifeq ($(ZT_DEBUG),1)
override CFLAGS+=-Wall -Wno-deprecated -g -pthread $(INCLUDES) $(DEFS) override CFLAGS+=-Wall -Wno-deprecated -g -O -pthread $(INCLUDES) $(DEFS)
override CXXFLAGS+=-Wall -Wno-deprecated -g -std=c++11 -pthread $(INCLUDES) $(DEFS) override CXXFLAGS+=-Wall -Wno-deprecated -g -O -std=c++11 -pthread $(INCLUDES) $(DEFS)
ZT_TRACE=1 ZT_TRACE=1
STRIP?=echo STRIP?=echo
# The following line enables optimization for the crypto code, since # The following line enables optimization for the crypto code, since
@ -112,12 +112,6 @@ ifeq ($(ZT_VAULT_SUPPORT),1)
override LDLIBS+=-lcurl override LDLIBS+=-lcurl
endif endif
# Uncomment for gprof profile build
#CFLAGS=-Wall -g -pg -pthread $(INCLUDES) $(DEFS)
#CXXFLAGS=-Wall -g -pg -pthread $(INCLUDES) $(DEFS)
#LDFLAGS=
#STRIP=echo
# Determine system build architecture from compiler target # Determine system build architecture from compiler target
CC_MACH=$(shell $(CC) -dumpmachine | cut -d '-' -f 1) CC_MACH=$(shell $(CC) -dumpmachine | cut -d '-' -f 1)
ZT_ARCHITECTURE=999 ZT_ARCHITECTURE=999
@ -125,13 +119,15 @@ ifeq ($(CC_MACH),x86_64)
ZT_ARCHITECTURE=2 ZT_ARCHITECTURE=2
ZT_USE_X64_ASM_SALSA=1 ZT_USE_X64_ASM_SALSA=1
ZT_USE_X64_ASM_ED25519=1 ZT_USE_X64_ASM_ED25519=1
override CFLAGS+=-msse -msse2 -mssse3 -msse4 -msse4.1 -maes -mpclmul override CFLAGS+=-msse -msse2 -mssse3 -msse4 -msse4.1 -msse4.2 -maes -mpclmul
override CXXFLAGS+=-msse -msse2 -mssse3 -msse4 -msse4.1 -msse4.2 -maes -mpclmul
endif endif
ifeq ($(CC_MACH),amd64) ifeq ($(CC_MACH),amd64)
ZT_ARCHITECTURE=2 ZT_ARCHITECTURE=2
ZT_USE_X64_ASM_SALSA=1 ZT_USE_X64_ASM_SALSA=1
ZT_USE_X64_ASM_ED25519=1 ZT_USE_X64_ASM_ED25519=1
override CFLAGS+=-msse -msse2 -mssse3 -msse4 -msse4.1 -maes -mpclmul override CFLAGS+=-msse -msse2 -mssse3 -msse4 -msse4.1 -msse4.2 -maes -mpclmul
override CXXFLAGS+=-msse -msse2 -mssse3 -msse4 -msse4.1 -msse4.2 -maes -mpclmul
endif endif
ifeq ($(CC_MACH),powerpc64le) ifeq ($(CC_MACH),powerpc64le)
ZT_ARCHITECTURE=8 ZT_ARCHITECTURE=8

View file

@ -67,7 +67,7 @@ bool IncomingPacket::tryDecode(const RuntimeEnvironment *RR,void *tPtr,int32_t f
const SharedPtr<Peer> peer(RR->topology->getPeer(tPtr,sourceAddress)); const SharedPtr<Peer> peer(RR->topology->getPeer(tPtr,sourceAddress));
if (peer) { if (peer) {
if (!trusted) { if (!trusted) {
if (!dearmor(peer->key())) { if (!dearmor(peer->key(), peer->aesKeysIfSupported())) {
RR->t->incomingPacketMessageAuthenticationFailure(tPtr,_path,packetId(),sourceAddress,hops(),"invalid MAC"); RR->t->incomingPacketMessageAuthenticationFailure(tPtr,_path,packetId(),sourceAddress,hops(),"invalid MAC");
peer->recordIncomingInvalidPacket(_path); peer->recordIncomingInvalidPacket(_path);
return true; return true;
@ -288,7 +288,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,void *tPtr,const bool
uint8_t key[ZT_PEER_SECRET_KEY_LENGTH]; uint8_t key[ZT_PEER_SECRET_KEY_LENGTH];
if (RR->identity.agree(id,key,ZT_PEER_SECRET_KEY_LENGTH)) { if (RR->identity.agree(id,key,ZT_PEER_SECRET_KEY_LENGTH)) {
if (dearmor(key)) { // ensure packet is authentic, otherwise drop if (dearmor(key, peer->aesKeysIfSupported())) { // ensure packet is authentic, otherwise drop
RR->t->incomingPacketDroppedHELLO(tPtr,_path,pid,fromAddress,"address collision"); RR->t->incomingPacketDroppedHELLO(tPtr,_path,pid,fromAddress,"address collision");
Packet outp(id.address(),RR->identity.address(),Packet::VERB_ERROR); Packet outp(id.address(),RR->identity.address(),Packet::VERB_ERROR);
outp.append((uint8_t)Packet::VERB_HELLO); outp.append((uint8_t)Packet::VERB_HELLO);
@ -307,7 +307,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,void *tPtr,const bool
} else { } else {
// Identity is the same as the one we already have -- check packet integrity // Identity is the same as the one we already have -- check packet integrity
if (!dearmor(peer->key())) { if (!dearmor(peer->key(), peer->aesKeysIfSupported())) {
RR->t->incomingPacketMessageAuthenticationFailure(tPtr,_path,pid,fromAddress,hops(),"invalid MAC"); RR->t->incomingPacketMessageAuthenticationFailure(tPtr,_path,pid,fromAddress,hops(),"invalid MAC");
return true; return true;
} }
@ -332,7 +332,7 @@ bool IncomingPacket::_doHELLO(const RuntimeEnvironment *RR,void *tPtr,const bool
// Check packet integrity and MAC (this is faster than locallyValidate() so do it first to filter out total crap) // Check packet integrity and MAC (this is faster than locallyValidate() so do it first to filter out total crap)
SharedPtr<Peer> newPeer(new Peer(RR,RR->identity,id)); SharedPtr<Peer> newPeer(new Peer(RR,RR->identity,id));
if (!dearmor(newPeer->key())) { if (!dearmor(newPeer->key(), newPeer->aesKeysIfSupported())) {
RR->t->incomingPacketMessageAuthenticationFailure(tPtr,_path,pid,fromAddress,hops(),"invalid MAC"); RR->t->incomingPacketMessageAuthenticationFailure(tPtr,_path,pid,fromAddress,hops(),"invalid MAC");
return true; return true;
} }

View file

@ -901,14 +901,16 @@ void Packet::armor(const void *key,bool encryptPayload,const AES aesKeys[2])
*reinterpret_cast<uint64_t *>(data + ZT_PACKET_IDX_MAC) = tag[1]; *reinterpret_cast<uint64_t *>(data + ZT_PACKET_IDX_MAC) = tag[1];
#endif #endif
} else { } else {
uint8_t mangledKey[32];
setCipher(encryptPayload ? ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012 : ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_NONE); setCipher(encryptPayload ? ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012 : ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_NONE);
uint8_t mangledKey[32];
_salsa20MangleKey((const unsigned char *)key,mangledKey); _salsa20MangleKey((const unsigned char *)key,mangledKey);
if (ZT_HAS_FAST_CRYPTO()) { if (ZT_HAS_FAST_CRYPTO()) {
const unsigned int encryptLen = (encryptPayload) ? (size() - ZT_PACKET_IDX_VERB) : 0; const unsigned int payloadLen = (encryptPayload) ? (size() - ZT_PACKET_IDX_VERB) : 0;
uint64_t keyStream[(ZT_PROTO_MAX_PACKET_LENGTH + 64 + 8) / 8]; uint64_t keyStream[(ZT_PROTO_MAX_PACKET_LENGTH + 64 + 8) / 8];
ZT_FAST_SINGLE_PASS_SALSA2012(keyStream,encryptLen + 64,(data + ZT_PACKET_IDX_IV),mangledKey); ZT_FAST_SINGLE_PASS_SALSA2012(keyStream,payloadLen + 64,(data + ZT_PACKET_IDX_IV),mangledKey);
Salsa20::memxor(data + ZT_PACKET_IDX_VERB,reinterpret_cast<const uint8_t *>(keyStream + 8),encryptLen); Salsa20::memxor(data + ZT_PACKET_IDX_VERB,reinterpret_cast<const uint8_t *>(keyStream + 8),payloadLen);
uint64_t mac[2]; uint64_t mac[2];
Poly1305::compute(mac,data + ZT_PACKET_IDX_VERB,size() - ZT_PACKET_IDX_VERB,keyStream); Poly1305::compute(mac,data + ZT_PACKET_IDX_VERB,size() - ZT_PACKET_IDX_VERB,keyStream);
#ifdef ZT_NO_TYPE_PUNNING #ifdef ZT_NO_TYPE_PUNNING
@ -934,15 +936,33 @@ void Packet::armor(const void *key,bool encryptPayload,const AES aesKeys[2])
} }
} }
bool Packet::dearmor(const void *key) bool Packet::dearmor(const void *key,const AES aesKeys[2])
{ {
uint8_t mangledKey[32];
uint8_t *const data = reinterpret_cast<uint8_t *>(unsafeData()); uint8_t *const data = reinterpret_cast<uint8_t *>(unsafeData());
const unsigned int payloadLen = size() - ZT_PACKET_IDX_VERB; const unsigned int payloadLen = size() - ZT_PACKET_IDX_VERB;
unsigned char *const payload = data + ZT_PACKET_IDX_VERB; unsigned char *const payload = data + ZT_PACKET_IDX_VERB;
const unsigned int cs = cipher(); const unsigned int cs = cipher();
if ((cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_NONE)||(cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012)) { if (cs == ZT_PROTO_CIPHER_SUITE__AES_GMAC_SIV) {
if (aesKeys) {
AES::GMACSIVDecryptor dec(aesKeys[0],aesKeys[1]);
uint64_t tag[2];
#ifdef ZT_NO_UNALIGNED_ACCESS
Utils::copy<8>(tag, data);
Utils::copy<8>(tag + 1, data + ZT_PACKET_IDX_MAC);
#else
tag[0] = *reinterpret_cast<uint64_t *>(data);
tag[1] = *reinterpret_cast<uint64_t *>(data + ZT_PACKET_IDX_MAC);
#endif
dec.init(tag, payload);
dec.aad(data + ZT_PACKET_IDX_DEST,11);
dec.update(payload, payloadLen);
return dec.finish();
}
} else if ((cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_NONE)||(cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012)) {
uint8_t mangledKey[32];
_salsa20MangleKey((const unsigned char *)key,mangledKey); _salsa20MangleKey((const unsigned char *)key,mangledKey);
if (ZT_HAS_FAST_CRYPTO()) { if (ZT_HAS_FAST_CRYPTO()) {
uint64_t keyStream[(ZT_PROTO_MAX_PACKET_LENGTH + 64 + 8) / 8]; uint64_t keyStream[(ZT_PROTO_MAX_PACKET_LENGTH + 64 + 8) / 8];
@ -974,11 +994,10 @@ bool Packet::dearmor(const void *key)
if (cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012) if (cs == ZT_PROTO_CIPHER_SUITE__C25519_POLY1305_SALSA2012)
s20.crypt12(payload,payload,payloadLen); s20.crypt12(payload,payload,payloadLen);
} }
return true; return true;
} else {
return false; // unrecognized cipher suite
} }
return false;
} }
void Packet::cryptField(const void *key,unsigned int start,unsigned int len) void Packet::cryptField(const void *key,unsigned int start,unsigned int len)

View file

@ -1313,7 +1313,7 @@ public:
* *
* @param key 32-byte key * @param key 32-byte key
* @param encryptPayload If true, encrypt packet payload, else just MAC * @param encryptPayload If true, encrypt packet payload, else just MAC
* @param aes Use new AES-GMAC-SIV constrution * @param aesKeys If non-NULL these are the two keys for AES-GMAC-SIV
*/ */
void armor(const void *key,bool encryptPayload,const AES aesKeys[2]); void armor(const void *key,bool encryptPayload,const AES aesKeys[2]);
@ -1325,9 +1325,10 @@ public:
* address and MAC field match a trusted path. * address and MAC field match a trusted path.
* *
* @param key 32-byte key * @param key 32-byte key
* @param aesKeys If non-NULL these are the two keys for AES-GMAC-SIV
* @return False if packet is invalid or failed MAC authenticity check * @return False if packet is invalid or failed MAC authenticity check
*/ */
bool dearmor(const void *key); bool dearmor(const void *key,const AES aesKeys[2]);
/** /**
* Encrypt/decrypt a separately armored portion of a packet * Encrypt/decrypt a separately armored portion of a packet

View file

@ -533,11 +533,11 @@ public:
*/ */
inline int8_t bondingPolicy() { return _bondingPolicy; } inline int8_t bondingPolicy() { return _bondingPolicy; }
const AES *aesKeysIfSupported() const
{ return (const AES *)0; }
//const AES *aesKeysIfSupported() const //const AES *aesKeysIfSupported() const
//{ return (_vProto >= 10) ? _aesKeys : (const AES *)0; } //{ return (const AES *)0; }
const AES *aesKeysIfSupported() const
{ return (_vProto >= 10) ? _aesKeys : (const AES *)0; }
private: private:
struct _PeerPath struct _PeerPath