Noise state Encrypt/Decrypt operations
Some checks are pending
Build Debian packages / bookworm (push) Waiting to run
Build Debian packages / bullseye (push) Waiting to run
Build Debian packages / buster (push) Waiting to run
Build on FreeBSD / with UPnP (push) Waiting to run
Build on OSX / With USE_UPNP=no (push) Waiting to run
Build on OSX / With USE_UPNP=yes (push) Waiting to run
Build on Windows / clang-x86_64 (push) Waiting to run
Build on Windows / i686 (push) Waiting to run
Build on Windows / ucrt-x86_64 (push) Waiting to run
Build on Windows / x86_64 (push) Waiting to run
Build on Windows / CMake clang-x86_64 (push) Waiting to run
Build on Windows / CMake i686 (push) Waiting to run
Build on Windows / CMake ucrt-x86_64 (push) Waiting to run
Build on Windows / CMake x86_64 (push) Waiting to run
Build on Windows / XP (push) Waiting to run
Build on Ubuntu / Make with USE_UPNP=no (push) Waiting to run
Build on Ubuntu / Make with USE_UPNP=yes (push) Waiting to run
Build on Ubuntu / CMake with -DWITH_UPNP=OFF (push) Waiting to run
Build on Ubuntu / CMake with -DWITH_UPNP=ON (push) Waiting to run
Build containers / Building container for linux/amd64 (push) Waiting to run
Build containers / Building container for linux/arm64 (push) Waiting to run
Build containers / Building container for linux/arm/v7 (push) Waiting to run
Build containers / Building container for linux/386 (push) Waiting to run
Build containers / Pushing merged manifest (push) Blocked by required conditions

This commit is contained in:
orignal 2025-04-07 18:47:53 -04:00
parent 3afe6455b2
commit 6b38085f27
3 changed files with 72 additions and 46 deletions

View file

@ -821,6 +821,18 @@ namespace crypto
// Noise // Noise
void NoiseSymmetricState::Init (const uint8_t * ck, const uint8_t * hh, const uint8_t * pub)
{
// pub is Bob's public static key, hh = SHA256(h)
memcpy (m_CK, ck, 32);
SHA256_CTX ctx;
SHA256_Init (&ctx);
SHA256_Update (&ctx, hh, 32);
SHA256_Update (&ctx, pub, 32);
SHA256_Final (m_H, &ctx); // h = MixHash(pub) = SHA256(hh || pub)
m_N = 0;
}
void NoiseSymmetricState::MixHash (const uint8_t * buf, size_t len) void NoiseSymmetricState::MixHash (const uint8_t * buf, size_t len)
{ {
SHA256_CTX ctx; SHA256_CTX ctx;
@ -844,20 +856,39 @@ namespace crypto
{ {
HKDF (m_CK, sharedSecret, 32, "", m_CK); HKDF (m_CK, sharedSecret, 32, "", m_CK);
// new ck is m_CK[0:31], key is m_CK[32:63] // new ck is m_CK[0:31], key is m_CK[32:63]
m_N = 0;
} }
static void InitNoiseState (NoiseSymmetricState& state, const uint8_t * ck, bool NoiseSymmetricState::Encrypt (const uint8_t * in, uint8_t * out, size_t len)
const uint8_t * hh, const uint8_t * pub)
{ {
// pub is Bob's public static key, hh = SHA256(h) uint8_t nonce[12];
memcpy (state.m_CK, ck, 32); if (m_N)
SHA256_CTX ctx; {
SHA256_Init (&ctx); memset (nonce, 0, 4);
SHA256_Update (&ctx, hh, 32); htole64buf (nonce + 4, m_N);
SHA256_Update (&ctx, pub, 32); }
SHA256_Final (state.m_H, &ctx); // h = MixHash(pub) = SHA256(hh || pub) else
memset (nonce, 0, 12);
auto ret = AEADChaCha20Poly1305 (in, len, m_H, 32, m_CK + 32, nonce, out, len + 16, true);
if (ret) m_N++;
return ret;
} }
bool NoiseSymmetricState::Decrypt (const uint8_t * in, uint8_t * out, size_t len)
{
uint8_t nonce[12];
if (m_N)
{
memset (nonce, 0, 4);
htole64buf (nonce + 4, m_N);
}
else
memset (nonce, 0, 12);
auto ret = AEADChaCha20Poly1305 (in, len, m_H, 32, m_CK + 32, nonce, out, len, false);
if (ret) m_N++;
return ret;
}
void InitNoiseNState (NoiseSymmetricState& state, const uint8_t * pub) void InitNoiseNState (NoiseSymmetricState& state, const uint8_t * pub)
{ {
static constexpr char protocolName[] = "Noise_N_25519_ChaChaPoly_SHA256"; // 31 chars static constexpr char protocolName[] = "Noise_N_25519_ChaChaPoly_SHA256"; // 31 chars
@ -866,7 +897,7 @@ namespace crypto
0x69, 0x4d, 0x52, 0x44, 0x5a, 0x27, 0xd9, 0xad, 0xfa, 0xd2, 0x9c, 0x76, 0x32, 0x39, 0x5d, 0xc1, 0x69, 0x4d, 0x52, 0x44, 0x5a, 0x27, 0xd9, 0xad, 0xfa, 0xd2, 0x9c, 0x76, 0x32, 0x39, 0x5d, 0xc1,
0xe4, 0x35, 0x4c, 0x69, 0xb4, 0xf9, 0x2e, 0xac, 0x8a, 0x1e, 0xe4, 0x6a, 0x9e, 0xd2, 0x15, 0x54 0xe4, 0x35, 0x4c, 0x69, 0xb4, 0xf9, 0x2e, 0xac, 0x8a, 0x1e, 0xe4, 0x6a, 0x9e, 0xd2, 0x15, 0x54
}; // hh = SHA256(protocol_name || 0) }; // hh = SHA256(protocol_name || 0)
InitNoiseState (state, (const uint8_t *)protocolName, hh, pub); // ck = protocol_name || 0 state.Init ((const uint8_t *)protocolName, hh, pub); // ck = protocol_name || 0
} }
void InitNoiseXKState (NoiseSymmetricState& state, const uint8_t * pub) void InitNoiseXKState (NoiseSymmetricState& state, const uint8_t * pub)
@ -881,7 +912,7 @@ namespace crypto
0x49, 0xff, 0x48, 0x3f, 0xc4, 0x04, 0xb9, 0xb2, 0x6b, 0x11, 0x94, 0x36, 0x72, 0xff, 0x05, 0xb5, 0x49, 0xff, 0x48, 0x3f, 0xc4, 0x04, 0xb9, 0xb2, 0x6b, 0x11, 0x94, 0x36, 0x72, 0xff, 0x05, 0xb5,
0x61, 0x27, 0x03, 0x31, 0xba, 0x89, 0xb8, 0xfc, 0x33, 0x15, 0x93, 0x87, 0x57, 0xdd, 0x3d, 0x1e 0x61, 0x27, 0x03, 0x31, 0xba, 0x89, 0xb8, 0xfc, 0x33, 0x15, 0x93, 0x87, 0x57, 0xdd, 0x3d, 0x1e
}; // SHA256 (protocolNameHash) }; // SHA256 (protocolNameHash)
InitNoiseState (state, protocolNameHash, hh, pub); state.Init (protocolNameHash, hh, pub);
} }
void InitNoiseXKState1 (NoiseSymmetricState& state, const uint8_t * pub) void InitNoiseXKState1 (NoiseSymmetricState& state, const uint8_t * pub)
@ -896,7 +927,7 @@ namespace crypto
0xdc, 0x85, 0xe6, 0xaf, 0x7b, 0x02, 0x65, 0x0c, 0xf1, 0xf9, 0x0d, 0x71, 0xfb, 0xc6, 0xd4, 0x53, 0xdc, 0x85, 0xe6, 0xaf, 0x7b, 0x02, 0x65, 0x0c, 0xf1, 0xf9, 0x0d, 0x71, 0xfb, 0xc6, 0xd4, 0x53,
0xa7, 0xcf, 0x6d, 0xbf, 0xbd, 0x52, 0x5e, 0xa5, 0xb5, 0x79, 0x1c, 0x47, 0xb3, 0x5e, 0xbc, 0x33 0xa7, 0xcf, 0x6d, 0xbf, 0xbd, 0x52, 0x5e, 0xa5, 0xb5, 0x79, 0x1c, 0x47, 0xb3, 0x5e, 0xbc, 0x33
}; // SHA256 (protocolNameHash) }; // SHA256 (protocolNameHash)
InitNoiseState (state, protocolNameHash, hh, pub); state.Init (protocolNameHash, hh, pub);
} }
void InitNoiseIKState (NoiseSymmetricState& state, const uint8_t * pub) void InitNoiseIKState (NoiseSymmetricState& state, const uint8_t * pub)
@ -911,7 +942,7 @@ namespace crypto
0x9c, 0xcf, 0x85, 0x2c, 0xc9, 0x3b, 0xb9, 0x50, 0x44, 0x41, 0xe9, 0x50, 0xe0, 0x1d, 0x52, 0x32, 0x9c, 0xcf, 0x85, 0x2c, 0xc9, 0x3b, 0xb9, 0x50, 0x44, 0x41, 0xe9, 0x50, 0xe0, 0x1d, 0x52, 0x32,
0x2e, 0x0d, 0x47, 0xad, 0xd1, 0xe9, 0xa5, 0x55, 0xf7, 0x55, 0xb5, 0x69, 0xae, 0x18, 0x3b, 0x5c 0x2e, 0x0d, 0x47, 0xad, 0xd1, 0xe9, 0xa5, 0x55, 0xf7, 0x55, 0xb5, 0x69, 0xae, 0x18, 0x3b, 0x5c
}; // SHA256 (protocolNameHash) }; // SHA256 (protocolNameHash)
InitNoiseState (state, protocolNameHash, hh, pub); state.Init (protocolNameHash, hh, pub);
} }
void InitNoiseIKStateMLKEM512 (NoiseSymmetricState& state, const uint8_t * pub) void InitNoiseIKStateMLKEM512 (NoiseSymmetricState& state, const uint8_t * pub)
@ -926,7 +957,7 @@ namespace crypto
0x95, 0x8d, 0xf6, 0x6c, 0x95, 0xce, 0xa9, 0xf7, 0x42, 0xfc, 0xfa, 0x62, 0x71, 0x36, 0x1e, 0xa7, 0x95, 0x8d, 0xf6, 0x6c, 0x95, 0xce, 0xa9, 0xf7, 0x42, 0xfc, 0xfa, 0x62, 0x71, 0x36, 0x1e, 0xa7,
0xdc, 0x7a, 0xc0, 0x75, 0x01, 0xcf, 0xf9, 0xfc, 0x9f, 0xdb, 0x4c, 0x68, 0x3a, 0x53, 0x49, 0xeb 0xdc, 0x7a, 0xc0, 0x75, 0x01, 0xcf, 0xf9, 0xfc, 0x9f, 0xdb, 0x4c, 0x68, 0x3a, 0x53, 0x49, 0xeb
}; // SHA256 (protocolNameHash) }; // SHA256 (protocolNameHash)
InitNoiseState (state, protocolNameHash, hh, pub); state.Init (protocolNameHash, hh, pub);
} }
// init and terminate // init and terminate

View file

@ -255,10 +255,16 @@ namespace crypto
struct NoiseSymmetricState struct NoiseSymmetricState
{ {
uint8_t m_H[32] /*h*/, m_CK[64] /*[ck, k]*/; uint8_t m_H[32] /*h*/, m_CK[64] /*[ck, k]*/;
uint64_t m_N;
void Init (const uint8_t * ck, const uint8_t * hh, const uint8_t * pub);
void MixHash (const uint8_t * buf, size_t len); void MixHash (const uint8_t * buf, size_t len);
void MixHash (const std::vector<std::pair<uint8_t *, size_t> >& bufs); void MixHash (const std::vector<std::pair<uint8_t *, size_t> >& bufs);
void MixKey (const uint8_t * sharedSecret); void MixKey (const uint8_t * sharedSecret);
bool Encrypt (const uint8_t * in, uint8_t * out, size_t len); // out length = len + 16
bool Decrypt (const uint8_t * in, uint8_t * out, size_t len); // len without 16 bytes tag
}; };
void InitNoiseNState (NoiseSymmetricState& state, const uint8_t * pub); // Noise_N (tunnels, router) void InitNoiseNState (NoiseSymmetricState& state, const uint8_t * pub); // Noise_N (tunnels, router)

View file

@ -559,29 +559,22 @@ namespace garlic
return false; return false;
} }
MixKey (sharedSecret); MixKey (sharedSecret);
uint64_t n = 0; // seqn
#if OPENSSL_PQ #if OPENSSL_PQ
if (m_RemoteStaticKeyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD) if (m_RemoteStaticKeyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD)
{ {
uint8_t encapsKey[i2p::crypto::MLKEM512_KEY_LENGTH]; uint8_t encapsKey[i2p::crypto::MLKEM512_KEY_LENGTH];
m_PQKeys->GetPublicKey (encapsKey); m_PQKeys->GetPublicKey (encapsKey);
// encrypt encapsKey // encrypt encapsKey
uint8_t nonce[12]; if (!Encrypt (encapsKey, out + offset, i2p::crypto::MLKEM512_KEY_LENGTH))
CreateNonce (n, nonce);
if (!i2p::crypto::AEADChaCha20Poly1305 (encapsKey, i2p::crypto::MLKEM512_KEY_LENGTH,
m_H, 32, m_CK + 32, nonce, out + offset, i2p::crypto::MLKEM512_KEY_LENGTH + 16, true)) // encrypt
{ {
LogPrint (eLogWarning, "Garlic: ML-KEM encap_key section AEAD encryption failed "); LogPrint (eLogWarning, "Garlic: ML-KEM encap_key section AEAD encryption failed ");
return false; return false;
} }
MixHash (out + offset, i2p::crypto::MLKEM512_KEY_LENGTH + 16); // h = SHA256(h || ciphertext) MixHash (out + offset, i2p::crypto::MLKEM512_KEY_LENGTH + 16); // h = SHA256(h || ciphertext)
offset += i2p::crypto::MLKEM512_KEY_LENGTH + 16; offset += i2p::crypto::MLKEM512_KEY_LENGTH + 16;
n++;
} }
#endif #endif
// encrypt flags/static key section // encrypt flags/static key section
uint8_t nonce[12];
CreateNonce (n, nonce);
const uint8_t * fs; const uint8_t * fs;
if (isStatic) if (isStatic)
fs = GetOwner ()->GetEncryptionPublicKey (m_RemoteStaticKeyType); fs = GetOwner ()->GetEncryptionPublicKey (m_RemoteStaticKeyType);
@ -590,7 +583,7 @@ namespace garlic
memset (out + offset, 0, 32); // all zeros flags section memset (out + offset, 0, 32); // all zeros flags section
fs = out + offset; fs = out + offset;
} }
if (!i2p::crypto::AEADChaCha20Poly1305 (fs, 32, m_H, 32, m_CK + 32, nonce, out + offset, 48, true)) // encrypt if (!Encrypt (fs, out + offset, 32))
{ {
LogPrint (eLogWarning, "Garlic: Flags/static section AEAD encryption failed "); LogPrint (eLogWarning, "Garlic: Flags/static section AEAD encryption failed ");
return false; return false;
@ -602,16 +595,10 @@ namespace garlic
if (isStatic) if (isStatic)
{ {
GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, m_RemoteStaticKeyType); // x25519 (ask, bpk) GetOwner ()->Decrypt (m_RemoteStaticKey, sharedSecret, m_RemoteStaticKeyType); // x25519 (ask, bpk)
MixKey (sharedSecret); MixKey (sharedSecret);
#if OPENSSL_PQ
if (m_RemoteStaticKeyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD)
CreateNonce (0, nonce); // reset nonce
#endif
} }
else
CreateNonce (1, nonce);
// encrypt payload // encrypt payload
if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_CK + 32, nonce, out + offset, len + 16, true)) // encrypt if (!Encrypt (payload, out + offset, len))
{ {
LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed"); LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed");
return false; return false;
@ -667,16 +654,13 @@ namespace garlic
} }
MixKey (sharedSecret); MixKey (sharedSecret);
uint8_t nonce[12];
CreateNonce (0, nonce);
#if OPENSSL_PQ #if OPENSSL_PQ
if (m_PQKeys) if (m_PQKeys)
{ {
uint8_t kemCiphertext[i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH]; uint8_t kemCiphertext[i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH];
m_PQKeys->Encaps (kemCiphertext, sharedSecret); m_PQKeys->Encaps (kemCiphertext, sharedSecret);
if (!i2p::crypto::AEADChaCha20Poly1305 (kemCiphertext, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH, if (!Encrypt (kemCiphertext, out + offset, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH))
m_H, 32, m_CK + 32, nonce, out + offset, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16, true)) // encrypt
{ {
LogPrint (eLogWarning, "Garlic: NSR ML-KEM ciphertext section AEAD encryption failed"); LogPrint (eLogWarning, "Garlic: NSR ML-KEM ciphertext section AEAD encryption failed");
return false; return false;
@ -687,7 +671,7 @@ namespace garlic
} }
#endif #endif
// calculate hash for zero length // calculate hash for zero length
if (!i2p::crypto::AEADChaCha20Poly1305 (nonce /* can be anything */, 0, m_H, 32, m_CK + 32, nonce, out + offset, 16, true)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad) if (!Encrypt (sharedSecret /* can be anything */, out + offset, 0)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad)
{ {
LogPrint (eLogWarning, "Garlic: Reply key section AEAD encryption failed"); LogPrint (eLogWarning, "Garlic: Reply key section AEAD encryption failed");
return false; return false;
@ -708,6 +692,7 @@ namespace garlic
GetOwner ()->GetNumRatchetInboundTags () : ECIESX25519_MIN_NUM_GENERATED_TAGS); GetOwner ()->GetNumRatchetInboundTags () : ECIESX25519_MIN_NUM_GENERATED_TAGS);
i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", m_NSRKey, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", m_NSRKey, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32)
// encrypt payload // encrypt payload
uint8_t nonce[12]; memset (nonce, 0, 12); // seqn = 0
if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + offset, len + 16, true)) // encrypt if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + offset, len + 16, true)) // encrypt
{ {
LogPrint (eLogWarning, "Garlic: NSR payload section AEAD encryption failed"); LogPrint (eLogWarning, "Garlic: NSR payload section AEAD encryption failed");
@ -729,16 +714,22 @@ namespace garlic
memcpy (m_H, m_NSRH, 32); memcpy (m_H, m_NSRH, 32);
MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag) MixHash ((const uint8_t *)&tag, 8); // h = SHA256(h || tag)
MixHash (m_EphemeralKeys->GetPublicKey (), 32); // h = SHA256(h || bepk) MixHash (m_EphemeralKeys->GetPublicKey (), 32); // h = SHA256(h || bepk)
uint8_t nonce[12]; m_N = 0;
CreateNonce (0, nonce); size_t offset = 40;
if (!i2p::crypto::AEADChaCha20Poly1305 (nonce /* can be anything */, 0, m_H, 32, m_CK + 32, nonce, out + 40, 16, true)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad) #if OPENSSL_PQ
if (m_PQKeys)
// TODO: encrypted ML-KEM section
offset += i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH + 16;
#endif
if (!Encrypt (m_NSRH /* can be anything */, out + offset, 0)) // encrypt, ciphertext = ENCRYPT(k, n, ZEROLEN, ad)
{ {
LogPrint (eLogWarning, "Garlic: Reply key section AEAD encryption failed"); LogPrint (eLogWarning, "Garlic: Reply key section AEAD encryption failed");
return false; return false;
} }
MixHash (out + 40, 16); // h = SHA256(h || ciphertext) MixHash (out + offset, 16); // h = SHA256(h || ciphertext)
// encrypt payload // encrypt payload
if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + 56, len + 16, true)) // encrypt uint8_t nonce[12]; memset (nonce, 0, 12);
if (!i2p::crypto::AEADChaCha20Poly1305 (payload, len, m_H, 32, m_NSRKey, nonce, out + offset + 16, len + 16, true)) // encrypt
{ {
LogPrint (eLogWarning, "Garlic: Next NSR payload section AEAD encryption failed"); LogPrint (eLogWarning, "Garlic: Next NSR payload section AEAD encryption failed");
return false; return false;
@ -773,15 +764,12 @@ namespace garlic
GetOwner ()->Decrypt (bepk, sharedSecret, m_RemoteStaticKeyType); // x25519 (ask, bepk) GetOwner ()->Decrypt (bepk, sharedSecret, m_RemoteStaticKeyType); // x25519 (ask, bepk)
MixKey (sharedSecret); MixKey (sharedSecret);
uint8_t nonce[12];
CreateNonce (0, nonce);
#if OPENSSL_PQ #if OPENSSL_PQ
if (m_RemoteStaticKeyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD) if (m_RemoteStaticKeyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD)
{ {
// decrypt kem_ciphertext section // decrypt kem_ciphertext section
uint8_t kemCiphertext[i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH]; uint8_t kemCiphertext[i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH];
if (!i2p::crypto::AEADChaCha20Poly1305 (buf, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH, if (!Decrypt (buf, kemCiphertext, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH))
m_H, 32, m_CK + 32, nonce, kemCiphertext, i2p::crypto::MLKEM512_CIPHER_TEXT_LENGTH, false)) // decrypt, DECRYPT(k, n, ZEROLEN, ad) verification only
{ {
LogPrint (eLogWarning, "Garlic: Reply ML-KEM ciphertext section AEAD decryption failed"); LogPrint (eLogWarning, "Garlic: Reply ML-KEM ciphertext section AEAD decryption failed");
return false; return false;
@ -795,7 +783,7 @@ namespace garlic
} }
#endif #endif
// calculate hash for zero length // calculate hash for zero length
if (!i2p::crypto::AEADChaCha20Poly1305 (buf, 0, m_H, 32, m_CK + 32, nonce, sharedSecret/* can be anything */, 0, false)) // decrypt, DECRYPT(k, n, ZEROLEN, ad) verification only if (!Decrypt (buf, sharedSecret/* can be anything */, 0)) // decrypt, DECRYPT(k, n, ZEROLEN, ad) verification only
{ {
LogPrint (eLogWarning, "Garlic: Reply key section AEAD decryption failed"); LogPrint (eLogWarning, "Garlic: Reply key section AEAD decryption failed");
return false; return false;
@ -820,6 +808,7 @@ namespace garlic
} }
i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32) i2p::crypto::HKDF (keydata + 32, nullptr, 0, "AttachPayloadKDF", keydata, 32); // k = HKDF(k_ba, ZEROLEN, "AttachPayloadKDF", 32)
// decrypt payload // decrypt payload
uint8_t nonce[12]; memset (nonce, 0, 12); // seqn = 0
if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_H, 32, keydata, nonce, buf, len - 16, false)) // decrypt if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_H, 32, keydata, nonce, buf, len - 16, false)) // decrypt
{ {
LogPrint (eLogWarning, "Garlic: Payload section AEAD decryption failed"); LogPrint (eLogWarning, "Garlic: Payload section AEAD decryption failed");