From 8c9eaccc11e573fa821d3b02efcb4b9f925d214b Mon Sep 17 00:00:00 2001 From: orignal Date: Tue, 5 Jun 2018 15:37:08 -0400 Subject: [PATCH] KeyDerivationFunction for NTCP2 --- libi2pd/Ed25519.cpp | 8 ++++++++ libi2pd/Ed25519.h | 1 + libi2pd/NTCP2.cpp | 31 +++++++++++++++++++++++++++++++ libi2pd/NTCP2.h | 1 + 4 files changed, 41 insertions(+) diff --git a/libi2pd/Ed25519.cpp b/libi2pd/Ed25519.cpp index e921bada..8258d33c 100644 --- a/libi2pd/Ed25519.cpp +++ b/libi2pd/Ed25519.cpp @@ -411,6 +411,14 @@ namespace crypto } } + void Ed25519::Mul (const uint8_t * p, const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const + { + auto P = DecodePublicKey (p, ctx); + BIGNUM * e1 = DecodeBN<32> (e); + EncodePublicKey (Mul (P, e1, ctx), buf, ctx); + BN_free (e1); + } + void Ed25519::ExpandPrivateKey (const uint8_t * key, uint8_t * expandedKey) { SHA512 (key, EDDSA25519_PRIVATE_KEY_LENGTH, expandedKey); diff --git a/libi2pd/Ed25519.h b/libi2pd/Ed25519.h index c3b162a7..cbf14bfd 100644 --- a/libi2pd/Ed25519.h +++ b/libi2pd/Ed25519.h @@ -75,6 +75,7 @@ namespace crypto EDDSAPoint GeneratePublicKey (const uint8_t * expandedPrivateKey, BN_CTX * ctx) const; EDDSAPoint DecodePublicKey (const uint8_t * buf, BN_CTX * ctx) const; void EncodePublicKey (const EDDSAPoint& publicKey, uint8_t * buf, BN_CTX * ctx) const; + void Mul (const uint8_t * p, const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const; // p is point, e is number bool Verify (const EDDSAPoint& publicKey, const uint8_t * digest, const uint8_t * signature) const; void Sign (const uint8_t * expandedPrivateKey, const uint8_t * publicKeyEncoded, const uint8_t * buf, size_t len, uint8_t * signature) const; diff --git a/libi2pd/NTCP2.cpp b/libi2pd/NTCP2.cpp index 907e1fd8..e6072207 100644 --- a/libi2pd/NTCP2.cpp +++ b/libi2pd/NTCP2.cpp @@ -1,4 +1,6 @@ #include +#include +#include #include "Crypto.h" #include "Ed25519.h" #include "ChaCha20.h" @@ -18,6 +20,35 @@ namespace transport { } + bool NTCP2Session::KeyDerivationFunction (const uint8_t * rs, const uint8_t * pub, uint8_t * derived) + { + static const char protocolName[] = "Noise_XK_25519_ChaChaPoly_SHA256"; // 32 bytes + uint8_t h[64], ck[33]; + SHA256 ((const uint8_t *)protocolName, 32, h); + memcpy (ck, h, 32); + // h = SHA256(h || rs) + memcpy (h + 32, rs, 32); + SHA256 (h, 64, h); + // h = SHA256(h || pub) + memcpy (h + 32, pub, 32); + SHA256 (h, 64, h); + // x25519 between rs and priv + uint8_t inputKeyMaterial[32]; + BN_CTX * ctx = BN_CTX_new (); + i2p::crypto::GetEd25519 ()->Mul (rs, m_ExpandedPrivateKey, inputKeyMaterial, ctx); // rs*priv + BN_CTX_free (ctx); + // temp_key = HMAC-SHA256(ck, input_key_material) + uint8_t tempKey[32]; unsigned int len; + HMAC(EVP_sha256(), ck, 32, inputKeyMaterial, 32, tempKey, &len); + // ck = HMAC-SHA256(temp_key, byte(0x01)) + inputKeyMaterial[0] = 1; + HMAC(EVP_sha256(), tempKey, 32, inputKeyMaterial, 1, ck, &len); + // derived = HMAC-SHA256(temp_key, ck || byte(0x02)) + ck[32] = 2; + HMAC(EVP_sha256(), tempKey, 32, ck, 33, derived, &len); + return true; + } + void NTCP2Session::CreateEphemeralKey (uint8_t * pub) { uint8_t key[32]; diff --git a/libi2pd/NTCP2.h b/libi2pd/NTCP2.h index 6dfea8ae..11bb2674 100644 --- a/libi2pd/NTCP2.h +++ b/libi2pd/NTCP2.h @@ -19,6 +19,7 @@ namespace transport private: + bool KeyDerivationFunction (const uint8_t * rs, const uint8_t * pub, uint8_t * derived); void CreateEphemeralKey (uint8_t * pub); void SendSessionRequest (const uint8_t * iv);