2017-11-06 20:54:18 +00:00
|
|
|
#include <string.h>
|
|
|
|
#include "Log.h"
|
2017-11-09 20:01:07 +00:00
|
|
|
#include "Gost.h"
|
2017-11-06 18:40:58 +00:00
|
|
|
#include "CryptoKey.h"
|
|
|
|
|
|
|
|
namespace i2p
|
|
|
|
{
|
|
|
|
namespace crypto
|
|
|
|
{
|
2017-11-06 20:54:18 +00:00
|
|
|
ElGamalEncryptor::ElGamalEncryptor (const uint8_t * pub)
|
|
|
|
{
|
|
|
|
memcpy (m_PublicKey, pub, 256);
|
|
|
|
}
|
|
|
|
|
2018-03-09 19:56:06 +00:00
|
|
|
void ElGamalEncryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding)
|
2017-11-06 20:54:18 +00:00
|
|
|
{
|
2020-02-21 02:05:07 +00:00
|
|
|
if (!ctx) return;
|
2018-03-09 19:56:06 +00:00
|
|
|
ElGamalEncrypt (m_PublicKey, data, encrypted, ctx, zeroPadding);
|
2017-11-06 20:54:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ElGamalDecryptor::ElGamalDecryptor (const uint8_t * priv)
|
|
|
|
{
|
|
|
|
memcpy (m_PrivateKey, priv, 256);
|
|
|
|
}
|
|
|
|
|
2018-03-09 19:56:06 +00:00
|
|
|
bool ElGamalDecryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding)
|
2017-11-06 20:54:18 +00:00
|
|
|
{
|
2020-02-21 02:05:07 +00:00
|
|
|
if (!ctx) return false;
|
2018-03-09 19:56:06 +00:00
|
|
|
return ElGamalDecrypt (m_PrivateKey, encrypted, data, ctx, zeroPadding);
|
2017-11-06 20:54:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ECIESP256Encryptor::ECIESP256Encryptor (const uint8_t * pub)
|
|
|
|
{
|
|
|
|
m_Curve = EC_GROUP_new_by_curve_name (NID_X9_62_prime256v1);
|
|
|
|
m_PublicKey = EC_POINT_new (m_Curve);
|
|
|
|
BIGNUM * x = BN_bin2bn (pub, 32, nullptr);
|
|
|
|
BIGNUM * y = BN_bin2bn (pub + 32, 32, nullptr);
|
|
|
|
if (!EC_POINT_set_affine_coordinates_GFp (m_Curve, m_PublicKey, x, y, nullptr))
|
|
|
|
LogPrint (eLogError, "ECICS P256 invalid public key");
|
|
|
|
BN_free (x); BN_free (y);
|
|
|
|
}
|
|
|
|
|
|
|
|
ECIESP256Encryptor::~ECIESP256Encryptor ()
|
|
|
|
{
|
|
|
|
if (m_Curve) EC_GROUP_free (m_Curve);
|
|
|
|
if (m_PublicKey) EC_POINT_free (m_PublicKey);
|
|
|
|
}
|
|
|
|
|
2018-03-09 19:56:06 +00:00
|
|
|
void ECIESP256Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding)
|
2017-11-06 20:54:18 +00:00
|
|
|
{
|
|
|
|
if (m_Curve && m_PublicKey)
|
2018-03-09 19:56:06 +00:00
|
|
|
ECIESEncrypt (m_Curve, m_PublicKey, data, encrypted, ctx, zeroPadding);
|
2017-11-06 20:54:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ECIESP256Decryptor::ECIESP256Decryptor (const uint8_t * priv)
|
|
|
|
{
|
|
|
|
m_Curve = EC_GROUP_new_by_curve_name (NID_X9_62_prime256v1);
|
|
|
|
m_PrivateKey = BN_bin2bn (priv, 32, nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
ECIESP256Decryptor::~ECIESP256Decryptor ()
|
|
|
|
{
|
|
|
|
if (m_Curve) EC_GROUP_free (m_Curve);
|
|
|
|
if (m_PrivateKey) BN_free (m_PrivateKey);
|
|
|
|
}
|
|
|
|
|
2018-03-09 19:56:06 +00:00
|
|
|
bool ECIESP256Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding)
|
2017-11-06 20:54:18 +00:00
|
|
|
{
|
|
|
|
if (m_Curve && m_PrivateKey)
|
2018-03-09 19:56:06 +00:00
|
|
|
return ECIESDecrypt (m_Curve, m_PrivateKey, encrypted, data, ctx, zeroPadding);
|
2017-11-09 20:01:07 +00:00
|
|
|
return false;
|
2017-11-06 20:54:18 +00:00
|
|
|
}
|
|
|
|
|
2017-11-06 18:40:58 +00:00
|
|
|
void CreateECIESP256RandomKeys (uint8_t * priv, uint8_t * pub)
|
|
|
|
{
|
|
|
|
EC_GROUP * curve = EC_GROUP_new_by_curve_name (NID_X9_62_prime256v1);
|
2018-01-06 03:48:51 +00:00
|
|
|
EC_POINT * p = nullptr;
|
2017-11-06 18:40:58 +00:00
|
|
|
BIGNUM * key = nullptr;
|
|
|
|
GenerateECIESKeyPair (curve, key, p);
|
|
|
|
bn2buf (key, priv, 32);
|
|
|
|
RAND_bytes (priv + 32, 224);
|
|
|
|
BN_free (key);
|
|
|
|
BIGNUM * x = BN_new (), * y = BN_new ();
|
|
|
|
EC_POINT_get_affine_coordinates_GFp (curve, p, x, y, NULL);
|
|
|
|
bn2buf (x, pub, 32);
|
2018-01-06 03:48:51 +00:00
|
|
|
bn2buf (y, pub + 32, 32);
|
2017-11-12 03:10:54 +00:00
|
|
|
RAND_bytes (pub + 64, 192);
|
2018-01-06 03:48:51 +00:00
|
|
|
EC_POINT_free (p);
|
2017-11-06 18:40:58 +00:00
|
|
|
BN_free (x); BN_free (y);
|
2018-01-06 03:48:51 +00:00
|
|
|
EC_GROUP_free (curve);
|
2017-11-06 18:40:58 +00:00
|
|
|
}
|
2017-11-09 20:01:07 +00:00
|
|
|
|
|
|
|
ECIESGOSTR3410Encryptor::ECIESGOSTR3410Encryptor (const uint8_t * pub)
|
|
|
|
{
|
|
|
|
auto& curve = GetGOSTR3410Curve (eGOSTR3410CryptoProA);
|
|
|
|
m_PublicKey = EC_POINT_new (curve->GetGroup ());
|
|
|
|
BIGNUM * x = BN_bin2bn (pub, 32, nullptr);
|
|
|
|
BIGNUM * y = BN_bin2bn (pub + 32, 32, nullptr);
|
|
|
|
if (!EC_POINT_set_affine_coordinates_GFp (curve->GetGroup (), m_PublicKey, x, y, nullptr))
|
|
|
|
LogPrint (eLogError, "ECICS GOST R 34.10 invalid public key");
|
|
|
|
BN_free (x); BN_free (y);
|
|
|
|
}
|
|
|
|
|
|
|
|
ECIESGOSTR3410Encryptor::~ECIESGOSTR3410Encryptor ()
|
|
|
|
{
|
|
|
|
if (m_PublicKey) EC_POINT_free (m_PublicKey);
|
|
|
|
}
|
|
|
|
|
2018-03-09 19:56:06 +00:00
|
|
|
void ECIESGOSTR3410Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding)
|
2017-11-09 20:01:07 +00:00
|
|
|
{
|
|
|
|
if (m_PublicKey)
|
2018-03-09 19:56:06 +00:00
|
|
|
ECIESEncrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PublicKey, data, encrypted, ctx, zeroPadding);
|
2017-11-09 20:01:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ECIESGOSTR3410Decryptor::ECIESGOSTR3410Decryptor (const uint8_t * priv)
|
|
|
|
{
|
|
|
|
m_PrivateKey = BN_bin2bn (priv, 32, nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
ECIESGOSTR3410Decryptor::~ECIESGOSTR3410Decryptor ()
|
|
|
|
{
|
|
|
|
if (m_PrivateKey) BN_free (m_PrivateKey);
|
|
|
|
}
|
|
|
|
|
2018-03-09 19:56:06 +00:00
|
|
|
bool ECIESGOSTR3410Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data, BN_CTX * ctx, bool zeroPadding)
|
2017-11-09 20:01:07 +00:00
|
|
|
{
|
|
|
|
if (m_PrivateKey)
|
2018-03-09 19:56:06 +00:00
|
|
|
return ECIESDecrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PrivateKey, encrypted, data, ctx, zeroPadding);
|
2017-11-09 20:01:07 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CreateECIESGOSTR3410RandomKeys (uint8_t * priv, uint8_t * pub)
|
|
|
|
{
|
|
|
|
auto& curve = GetGOSTR3410Curve (eGOSTR3410CryptoProA);
|
2018-01-06 03:48:51 +00:00
|
|
|
EC_POINT * p = nullptr;
|
2017-11-09 20:01:07 +00:00
|
|
|
BIGNUM * key = nullptr;
|
|
|
|
GenerateECIESKeyPair (curve->GetGroup (), key, p);
|
|
|
|
bn2buf (key, priv, 32);
|
|
|
|
RAND_bytes (priv + 32, 224);
|
|
|
|
BN_free (key);
|
|
|
|
BIGNUM * x = BN_new (), * y = BN_new ();
|
|
|
|
EC_POINT_get_affine_coordinates_GFp (curve->GetGroup (), p, x, y, NULL);
|
|
|
|
bn2buf (x, pub, 32);
|
2018-01-06 03:48:51 +00:00
|
|
|
bn2buf (y, pub + 32, 32);
|
2017-11-12 22:31:00 +00:00
|
|
|
RAND_bytes (pub + 64, 192);
|
2018-01-06 03:48:51 +00:00
|
|
|
EC_POINT_free (p);
|
2017-11-09 20:01:07 +00:00
|
|
|
BN_free (x); BN_free (y);
|
|
|
|
}
|
|
|
|
|
2019-12-19 20:59:15 +00:00
|
|
|
ECIESX25519AEADRatchetEncryptor::ECIESX25519AEADRatchetEncryptor (const uint8_t * pub)
|
|
|
|
{
|
|
|
|
memcpy (m_PublicKey, pub, 32);
|
|
|
|
}
|
|
|
|
|
2020-01-16 20:45:22 +00:00
|
|
|
void ECIESX25519AEADRatchetEncryptor::Encrypt (const uint8_t *, uint8_t * pub, BN_CTX *, bool)
|
2019-12-19 20:59:15 +00:00
|
|
|
{
|
2020-01-16 20:45:22 +00:00
|
|
|
memcpy (pub, m_PublicKey, 32);
|
2019-12-19 20:59:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ECIESX25519AEADRatchetDecryptor::ECIESX25519AEADRatchetDecryptor (const uint8_t * priv)
|
|
|
|
{
|
|
|
|
m_StaticKeys.SetPrivateKey (priv);
|
|
|
|
}
|
2019-12-11 18:38:36 +00:00
|
|
|
|
2019-12-17 21:18:40 +00:00
|
|
|
bool ECIESX25519AEADRatchetDecryptor::Decrypt (const uint8_t * epub, uint8_t * sharedSecret, BN_CTX * ctx, bool zeroPadding)
|
2019-12-11 18:38:36 +00:00
|
|
|
{
|
2019-12-17 21:18:40 +00:00
|
|
|
m_StaticKeys.Agree (epub, sharedSecret);
|
2019-12-11 18:38:36 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CreateECIESX25519AEADRatchetRandomKeys (uint8_t * priv, uint8_t * pub)
|
|
|
|
{
|
|
|
|
X25519Keys k;
|
|
|
|
k.GenerateKeys ();
|
|
|
|
k.GetPrivateKey (priv);
|
|
|
|
memcpy (pub, k.GetPublicKey (), 32);
|
|
|
|
}
|
2017-11-06 18:40:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|