common HKDF

This commit is contained in:
orignal 2019-03-15 12:25:20 -04:00
parent 8ec12a1b65
commit aa4bddd6ec
4 changed files with 37 additions and 16 deletions

View File

@ -8,11 +8,14 @@
#include <openssl/crypto.h>
#include "TunnelBase.h"
#include <openssl/ssl.h>
#include "Crypto.h"
#if OPENSSL_HKDF
#include <openssl/kdf.h>
#endif
#if !OPENSSL_AEAD_CHACHA20_POLY1305
#include "ChaCha20.h"
#include "Poly1305.h"
#endif
#include "Crypto.h"
#include "Ed25519.h"
#include "I2PEndian.h"
#include "Log.h"
@ -1245,6 +1248,30 @@ namespace crypto
#endif
}
void HKDF (const uint8_t * salt, const uint8_t * key, size_t keyLen, const std::string& info, uint8_t * out)
{
#if OPENSSL_HKDF
EVP_PKEY_CTX * pctx = EVP_PKEY_CTX_new_id (EVP_PKEY_HKDF, NULL);
EVP_PKEY_derive_init (pctx);
EVP_PKEY_CTX_set_hkdf_md (pctx, EVP_sha256());
EVP_PKEY_CTX_set1_hkdf_salt (pctx, salt, 32);
EVP_PKEY_CTX_set1_hkdf_key (pctx, key, keyLen);
if (info.length () > 0)
EVP_PKEY_CTX_add1_hkdf_info (pctx, info.c_str (), info.length ());
size_t outlen = 64;
EVP_PKEY_derive (pctx, out, &outlen);
EVP_PKEY_CTX_free (pctx);
#else
uint8_t prk[32]; unsigned int len;
HMAC(EVP_sha256(), salt, 32, key, keyLen, prk, &len);
auto l = info.length ();
memcpy (out, info.c_str (), l); out[l] = 0x01;
HMAC(EVP_sha256(), prk, 32, out, l + 1, out, &len);
memcpy (out + 32, info.c_str (), l); out[l + 32] = 0x02;
HMAC(EVP_sha256(), prk, 32, out, l + 33, out + 32, &len);
#endif
}
// init and terminate
/* std::vector <std::unique_ptr<std::mutex> > m_OpenSSLMutexes;

View File

@ -27,6 +27,7 @@
# define X509_getm_notAfter X509_get_notAfter
#else
# define LEGACY_OPENSSL 0
# define OPENSSL_HKDF 1
# if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1
# define OPENSSL_EDDSA 1
# define OPENSSL_X25519 1
@ -290,8 +291,13 @@ namespace crypto
void AEADChaCha20Poly1305Encrypt (const std::vector<std::pair<uint8_t *, size_t> >& bufs, const uint8_t * key, const uint8_t * nonce, uint8_t * mac); // encrypt multiple buffers with zero ad
// ChaCha20
void ChaCha20 (const uint8_t * msg, size_t msgLen, const uint8_t * key, const uint8_t * nonce, uint8_t * out);
// HKDF
void HKDF (const uint8_t * salt, const uint8_t * key, size_t keyLen, const std::string& info, uint8_t * out); // salt - 32, out - 64, info <= 32
// init and terminate
void InitCrypto (bool precomputation);
void TerminateCrypto ();

View File

@ -494,7 +494,7 @@ namespace data
// outerSalt = outerCiphertext[0:32]
// keys = HKDF(outerSalt, outerInput, "ELS2_L1K", 44)
uint8_t keys[64]; // 44 bytes actual data
HKDF (outerCiphertext, {subcredential, 36}, "ELS2_L1K", keys);
i2p::crypto::HKDF (outerCiphertext, subcredential, 36, "ELS2_L1K", keys);
// decrypt Layer 1
// outerKey = keys[0:31]
// outerIV = keys[32:43]
@ -505,7 +505,7 @@ namespace data
// innerSalt = innerCiphertext[0:32]
// keys = HKDF(innerSalt, innerInput, "ELS2_L2K", 44)
// skip 1 byte flags
HKDF (outerPlainText.data () + 1, {subcredential, 36}, "ELS2_L2K", keys); // no authCookie
i2p::crypto::HKDF (outerPlainText.data () + 1, subcredential, 36, "ELS2_L2K", keys); // no authCookie
// decrypt Layer 2
// innerKey = keys[0:31]
// innerIV = keys[32:43]
@ -535,24 +535,13 @@ namespace data
SHA256_Final (hash, &ctx);
}
void LeaseSet2::HKDF (const uint8_t * salt, const std::pair<const uint8_t *, size_t>& ikm, const std::string& info, uint8_t * out)
{
uint8_t prk[32]; unsigned int len;
HMAC(EVP_sha256(), salt, 32, ikm.first, ikm.second, prk, &len);
auto l = info.length ();
memcpy (out, info.c_str (), l); out[l] = 0x01;
HMAC(EVP_sha256(), prk, 32, out, l + 1, out, &len);
memcpy (out + 32, info.c_str (), l); out[l + 32] = 0x02;
HMAC(EVP_sha256(), prk, 32, out, l + 33, out + 32, &len);
}
void LeaseSet2::BlindPublicKey (std::shared_ptr<const IdentityEx> identity, const char * date, SigningKeyType blindedKeyType, uint8_t * blindedKey)
{
uint16_t stA = htobe16 (identity->GetSigningKeyType ()), stA1 = htobe16 (blindedKeyType);
uint8_t salt[32], seed[64];
//seed = HKDF(H("I2PGenerateAlpha", keydata), datestring || secret, "i2pblinding1", 64)
H ("I2PGenerateAlpha", { {identity->GetSigningPublicKeyBuffer (), identity->GetSigningPublicKeyLen ()}, {(const uint8_t *)&stA, 2}, {(const uint8_t *)&stA1, 2} }, salt);
HKDF (salt, { (const uint8_t *)date, 8 }, "i2pblinding1", seed);
i2p::crypto::HKDF (salt, (const uint8_t *)date, 8, "i2pblinding1", seed);
i2p::crypto::GetEd25519 ()->BlindPublicKey (identity->GetSigningPublicKeyBuffer (), seed, blindedKey);
}

View File

@ -158,7 +158,6 @@ namespace data
// for encrypted LS
static void H (const std::string& p, const std::vector<std::pair<const uint8_t *, size_t> >& bufs, uint8_t * hash);
static void HKDF (const uint8_t * salt, const std::pair<const uint8_t *, size_t>& ikm, const std::string& info, uint8_t * out); // salt - 32, out - 64, info <= 32
static void BlindPublicKey (std::shared_ptr<const IdentityEx> identity, const char * date, SigningKeyType blindedKeyType, uint8_t * blindedKey); // blinded key 32 bytes, date is 8 chars "YYYYMMDD"
private: