Implement extended armor throughout system but not turned on yet.

This commit is contained in:
Adam Ierymenko 2024-09-25 19:51:15 -04:00
parent 3de5cbd105
commit 6b078ee935
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
9 changed files with 1223 additions and 1203 deletions

View file

@ -18,6 +18,7 @@
#include <stdio.h>
#include "Packet.hpp"
#include "ECC.hpp"
#if defined(ZT_USE_X64_ASM_SALSA2012) && defined(ZT_ARCH_X64)
#include "../ext/x64-salsa2012-asm/salsa2012.h"
@ -1009,8 +1010,7 @@ void Packet::armor(const void *key,bool encryptPayload,bool extendedArmor,const
{
uint8_t *const data = reinterpret_cast<uint8_t *>(unsafeData());
if (extendedArmor) {
}
this->setExtendedArmor(extendedArmor);
if ((aesKeys) && (encryptPayload)) {
setCipher(ZT_PROTO_CIPHER_SUITE__AES_GMAC_SIV);
@ -1042,19 +1042,22 @@ void Packet::armor(const void *key,bool encryptPayload,bool extendedArmor,const
if (ZT_HAS_FAST_CRYPTO()) {
const unsigned int payloadLen = (encryptPayload) ? (size() - ZT_PACKET_IDX_VERB) : 0;
uint64_t keyStream[(ZT_PROTO_MAX_PACKET_LENGTH + 64 + 8) / 8];
uint64_t mac[2];
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),payloadLen);
uint64_t mac[2];
Poly1305::compute(mac,data + ZT_PACKET_IDX_VERB,size() - ZT_PACKET_IDX_VERB,keyStream);
#ifdef ZT_NO_TYPE_PUNNING
memcpy(data + ZT_PACKET_IDX_MAC,mac,8);
#else
(*reinterpret_cast<uint64_t *>(data + ZT_PACKET_IDX_MAC)) = mac[0];
#endif
} else {
Salsa20 s20(mangledKey,data + ZT_PACKET_IDX_IV);
uint64_t macKey[4];
uint64_t mac[2];
Salsa20 s20(mangledKey,data + ZT_PACKET_IDX_IV);
s20.crypt12(ZERO_KEY,macKey,sizeof(macKey));
uint8_t *const payload = data + ZT_PACKET_IDX_VERB;
@ -1062,17 +1065,51 @@ void Packet::armor(const void *key,bool encryptPayload,bool extendedArmor,const
if (encryptPayload) {
s20.crypt12(payload,payload,payloadLen);
}
uint64_t mac[2];
Poly1305::compute(mac,payload,payloadLen,macKey);
memcpy(data + ZT_PACKET_IDX_MAC,mac,8);
}
}
if (extendedArmor) {
ECC::Pair ephemeralKeyPair = ECC::generate();
uint8_t ephemeralSymmetric[32];
ECC::agree(ephemeralKeyPair, identity.publicKey(), ephemeralSymmetric, 32);
AES cipher(ephemeralSymmetric);
AES::CTR aesCtr(cipher);
aesCtr.init(data, 0, data + ZT_PACKET_IDX_EXTENDED_ARMOR_START);
aesCtr.crypt(data + ZT_PACKET_IDX_EXTENDED_ARMOR_START, size() - ZT_PACKET_IDX_EXTENDED_ARMOR_START);
this->append(ephemeralKeyPair.pub.data, ZT_ECC_EPHEMERAL_PUBLIC_KEY_LEN);
}
}
bool Packet::dearmor(const void *key,const AES aesKeys[2],const Identity &identity)
{
uint8_t *const data = reinterpret_cast<uint8_t *>(unsafeData());
if (extendedArmor()) {
if (size() < ZT_ECC_EPHEMERAL_PUBLIC_KEY_LEN) {
return false;
}
uint8_t ephemeralSymmetric[32];
ECC::Public ephemeralKey;
memcpy(ephemeralKey.data, data + (size() - ZT_ECC_EPHEMERAL_PUBLIC_KEY_LEN), ZT_ECC_EPHEMERAL_PUBLIC_KEY_LEN);
ECC::agree(identity.privateKeyPair(), ephemeralKey, ephemeralSymmetric, 32);
AES cipher(ephemeralSymmetric);
AES::CTR aesCtr(cipher);
aesCtr.init(data, 0, data + ZT_PACKET_IDX_EXTENDED_ARMOR_START);
aesCtr.crypt(data + ZT_PACKET_IDX_EXTENDED_ARMOR_START, size() - ZT_PACKET_IDX_EXTENDED_ARMOR_START);
this->setSize(size() - ZT_ECC_EPHEMERAL_PUBLIC_KEY_LEN);
/* Note: both the MAC and the data were encrypted with the ephemeral key. We don't need
* a separate MAC for the ephemeral encryption because the MAC check below is obviously
* going to fail if the ephemeral key was incorrect. */
}
const unsigned int payloadLen = size() - ZT_PACKET_IDX_VERB;
unsigned char *const payload = data + ZT_PACKET_IDX_VERB;
const unsigned int cs = cipher();
@ -1080,6 +1117,7 @@ bool Packet::dearmor(const void *key,const AES aesKeys[2],const Identity &identi
if (cs == ZT_PROTO_CIPHER_SUITE__AES_GMAC_SIV) {
if (aesKeys) {
uint64_t tag[2];
#ifdef ZT_NO_UNALIGNED_ACCESS
Utils::copy<8>(tag, data);
Utils::copy<8>(tag + 1, data + ZT_PACKET_IDX_MAC);