2020-05-22 13:18:41 +00:00
/*
2024-07-06 12:50:51 +00:00
* Copyright ( c ) 2013 - 2024 , The PurpleI2P Project
2020-05-22 13:18:41 +00:00
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
2015-11-03 14:15:49 +00:00
# ifndef CRYPTO_H__
# define CRYPTO_H__
2014-05-06 16:22:22 +00:00
# include <inttypes.h>
2015-11-03 14:15:49 +00:00
# include <string>
2018-11-30 19:41:14 +00:00
# include <vector>
2016-05-11 20:02:26 +00:00
# include <openssl/bn.h>
# include <openssl/dh.h>
# include <openssl/aes.h>
# include <openssl/dsa.h>
2016-11-09 20:59:01 +00:00
# include <openssl/ecdsa.h>
2016-11-04 14:59:55 +00:00
# include <openssl/rsa.h>
2016-05-11 20:02:26 +00:00
# include <openssl/sha.h>
2016-11-10 17:51:39 +00:00
# include <openssl/evp.h>
2016-05-11 20:02:26 +00:00
# include <openssl/rand.h>
2018-09-08 20:52:42 +00:00
# include <openssl/opensslv.h>
2016-06-28 00:00:00 +00:00
2015-11-03 14:15:49 +00:00
# include "Base.h"
2016-06-28 00:00:00 +00:00
# include "Tag.h"
2014-05-06 16:22:22 +00:00
2018-09-08 20:52:42 +00:00
// recognize openssl version and features
2024-07-06 12:50:51 +00:00
# if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1
# define OPENSSL_HKDF 1
# define OPENSSL_EDDSA 1
2024-07-30 12:13:24 +00:00
# if (!defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER != 0x030000000)) // 3.0.0, regression in SipHash, not implemented in LibreSSL
2024-07-06 12:50:51 +00:00
# define OPENSSL_SIPHASH 1
2022-05-20 16:56:05 +00:00
# endif
2018-09-08 20:52:42 +00:00
# endif
2014-05-06 16:22:22 +00:00
namespace i2p
{
namespace crypto
2015-11-03 14:15:49 +00:00
{
2015-12-18 15:09:25 +00:00
bool bn2buf ( const BIGNUM * bn , uint8_t * buf , size_t len ) ;
2015-11-03 14:15:49 +00:00
// DSA
2018-01-06 03:48:51 +00:00
DSA * CreateDSA ( ) ;
2015-11-03 14:15:49 +00:00
// RSA
2015-12-18 15:09:25 +00:00
const BIGNUM * GetRSAE ( ) ;
2015-11-03 14:15:49 +00:00
2018-09-08 20:52:42 +00:00
// x25519
class X25519Keys
{
public :
X25519Keys ( ) ;
2019-06-11 14:40:53 +00:00
X25519Keys ( const uint8_t * priv , const uint8_t * pub ) ; // if pub is null, derive from priv
2018-09-08 20:52:42 +00:00
~ X25519Keys ( ) ;
void GenerateKeys ( ) ;
const uint8_t * GetPublicKey ( ) const { return m_PublicKey ; } ;
2018-11-01 14:43:31 +00:00
void GetPrivateKey ( uint8_t * priv ) const ;
2020-06-03 20:05:19 +00:00
void SetPrivateKey ( const uint8_t * priv , bool calculatePublic = false ) ;
2021-01-01 20:03:11 +00:00
bool Agree ( const uint8_t * pub , uint8_t * shared ) ;
2018-09-08 20:52:42 +00:00
2020-06-30 17:00:41 +00:00
bool IsElligatorIneligible ( ) const { return m_IsElligatorIneligible ; }
void SetElligatorIneligible ( ) { m_IsElligatorIneligible = true ; }
2021-11-27 20:30:35 +00:00
2018-09-08 20:52:42 +00:00
private :
2020-03-01 10:25:50 +00:00
uint8_t m_PublicKey [ 32 ] ;
2018-09-08 20:52:42 +00:00
EVP_PKEY_CTX * m_Ctx ;
EVP_PKEY * m_Pkey ;
2021-11-12 16:33:51 +00:00
bool m_IsElligatorIneligible = false ; // true if definitely ineligible
2018-09-08 20:52:42 +00:00
} ;
2020-03-01 10:25:50 +00:00
2015-11-03 14:15:49 +00:00
// ElGamal
2021-11-27 20:30:35 +00:00
void ElGamalEncrypt ( const uint8_t * key , const uint8_t * data , uint8_t * encrypted ) ; // 222 bytes data, 514 bytes encrypted
2021-08-31 22:51:40 +00:00
bool ElGamalDecrypt ( const uint8_t * key , const uint8_t * encrypted , uint8_t * data ) ; // 514 bytes encrypted, 222 data
2015-11-03 14:15:49 +00:00
void GenerateElGamalKeyPair ( uint8_t * priv , uint8_t * pub ) ;
2017-11-06 18:40:58 +00:00
// ECIES
2021-09-03 17:30:01 +00:00
void ECIESEncrypt ( const EC_GROUP * curve , const EC_POINT * key , const uint8_t * data , uint8_t * encrypted ) ; // 222 bytes data, 514 bytes encrypted
2021-08-31 22:51:40 +00:00
bool ECIESDecrypt ( const EC_GROUP * curve , const BIGNUM * key , const uint8_t * encrypted , uint8_t * data ) ; // 514 bytes encrypted, 222 data
2017-11-06 18:40:58 +00:00
void GenerateECIESKeyPair ( const EC_GROUP * curve , BIGNUM * & priv , EC_POINT * & pub ) ;
2018-01-06 03:48:51 +00:00
2015-11-03 14:15:49 +00:00
// AES
2014-11-01 18:56:13 +00:00
typedef i2p : : data : : Tag < 32 > AESKey ;
2024-12-07 01:25:22 +00:00
2014-05-08 20:49:00 +00:00
class ECBEncryption
{
public :
2018-01-06 03:48:51 +00:00
2024-12-07 01:25:22 +00:00
ECBEncryption ( ) ;
~ ECBEncryption ( ) ;
2024-12-08 16:08:17 +00:00
void SetKey ( const uint8_t * key ) { m_Key = key ; } ;
2024-12-07 01:25:22 +00:00
void Encrypt ( const uint8_t * in , uint8_t * out ) ;
2018-06-27 09:09:46 +00:00
2024-12-07 01:25:22 +00:00
private :
2014-05-08 20:49:00 +00:00
2024-12-07 01:25:22 +00:00
AESKey m_Key ;
EVP_CIPHER_CTX * m_Ctx ;
2018-01-06 03:48:51 +00:00
} ;
2014-05-08 20:49:00 +00:00
class ECBDecryption
{
public :
2018-01-06 03:48:51 +00:00
2024-12-07 01:25:22 +00:00
ECBDecryption ( ) ;
~ ECBDecryption ( ) ;
2024-12-08 16:08:17 +00:00
void SetKey ( const uint8_t * key ) { m_Key = key ; } ;
2024-12-07 01:25:22 +00:00
void Decrypt ( const uint8_t * in , uint8_t * out ) ;
2014-05-08 20:49:00 +00:00
private :
2024-12-07 01:25:22 +00:00
AESKey m_Key ;
EVP_CIPHER_CTX * m_Ctx ;
2018-01-06 03:48:51 +00:00
} ;
2014-05-08 20:49:00 +00:00
2014-05-06 16:22:22 +00:00
class CBCEncryption
{
public :
2018-01-06 03:48:51 +00:00
2024-12-07 01:25:22 +00:00
CBCEncryption ( ) ;
~ CBCEncryption ( ) ;
2014-05-06 16:22:22 +00:00
2024-12-08 16:08:17 +00:00
void SetKey ( const uint8_t * key ) { m_Key = key ; } ; // 32 bytes
void Encrypt ( const uint8_t * in , size_t len , const uint8_t * iv , uint8_t * out ) ;
2024-12-07 01:25:22 +00:00
2014-05-06 16:22:22 +00:00
private :
2024-12-07 01:25:22 +00:00
AESKey m_Key ;
EVP_CIPHER_CTX * m_Ctx ;
2014-05-06 16:22:22 +00:00
} ;
class CBCDecryption
{
public :
2018-01-06 03:48:51 +00:00
2024-12-07 01:25:22 +00:00
CBCDecryption ( ) ;
~ CBCDecryption ( ) ;
2024-12-08 16:08:17 +00:00
void SetKey ( const uint8_t * key ) { m_Key = key ; } ; // 32 bytes
void Decrypt ( const uint8_t * in , size_t len , const uint8_t * iv , uint8_t * out ) ;
2018-06-27 09:09:46 +00:00
2014-05-06 16:22:22 +00:00
private :
2024-12-07 01:25:22 +00:00
AESKey m_Key ;
EVP_CIPHER_CTX * m_Ctx ;
2018-01-06 03:48:51 +00:00
} ;
2014-05-15 15:21:41 +00:00
class TunnelEncryption // with double IV encryption
{
public :
2014-11-02 01:53:45 +00:00
void SetKeys ( const AESKey & layerKey , const AESKey & ivKey )
2014-05-15 15:21:41 +00:00
{
m_LayerEncryption . SetKey ( layerKey ) ;
m_IVEncryption . SetKey ( ivKey ) ;
2018-01-06 03:48:51 +00:00
}
2014-05-15 15:21:41 +00:00
2018-01-06 03:48:51 +00:00
void Encrypt ( const uint8_t * in , uint8_t * out ) ; // 1024 bytes (16 IV + 1008 data)
2014-05-15 15:21:41 +00:00
private :
ECBEncryption m_IVEncryption ;
CBCEncryption m_LayerEncryption ;
} ;
class TunnelDecryption // with double IV encryption
{
public :
2014-11-02 01:53:45 +00:00
void SetKeys ( const AESKey & layerKey , const AESKey & ivKey )
2014-05-15 15:21:41 +00:00
{
m_LayerDecryption . SetKey ( layerKey ) ;
m_IVDecryption . SetKey ( ivKey ) ;
2018-01-06 03:48:51 +00:00
}
2014-05-15 15:21:41 +00:00
2018-01-06 03:48:51 +00:00
void Decrypt ( const uint8_t * in , uint8_t * out ) ; // 1024 bytes (16 IV + 1008 data)
2014-05-15 15:21:41 +00:00
private :
ECBDecryption m_IVDecryption ;
CBCDecryption m_LayerDecryption ;
2018-01-06 03:48:51 +00:00
} ;
2018-06-13 15:41:46 +00:00
// AEAD/ChaCha20/Poly1305
2018-06-27 09:09:46 +00:00
2024-12-10 01:59:59 +00:00
class AEADChaCha20Poly1305Encryptor
{
public :
AEADChaCha20Poly1305Encryptor ( ) ;
~ AEADChaCha20Poly1305Encryptor ( ) ;
bool Encrypt ( const uint8_t * msg , size_t msgLen , const uint8_t * ad , size_t adLen ,
const uint8_t * key , const uint8_t * nonce , uint8_t * buf , size_t len ) ; // msgLen is len without tag
void Encrypt ( 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
private :
2018-11-30 19:41:14 +00:00
2024-12-10 01:59:59 +00:00
EVP_CIPHER_CTX * m_Ctx ;
} ;
class AEADChaCha20Poly1305Decryptor
{
public :
AEADChaCha20Poly1305Decryptor ( ) ;
~ AEADChaCha20Poly1305Decryptor ( ) ;
bool Decrypt ( const uint8_t * msg , size_t msgLen , const uint8_t * ad , size_t adLen ,
const uint8_t * key , const uint8_t * nonce , uint8_t * buf , size_t len ) ; // msgLen is len without tag
private :
EVP_CIPHER_CTX * m_Ctx ;
} ;
bool AEADChaCha20Poly1305 ( const uint8_t * msg , size_t msgLen , const uint8_t * ad , size_t adLen ,
const uint8_t * key , const uint8_t * nonce , uint8_t * buf , size_t len , bool encrypt ) ; // msgLen is len without tag
2019-03-15 16:25:20 +00:00
// ChaCha20
2019-02-28 18:31:51 +00:00
void ChaCha20 ( const uint8_t * msg , size_t msgLen , const uint8_t * key , const uint8_t * nonce , uint8_t * out ) ;
2019-03-15 16:25:20 +00:00
// HKDF
2020-03-01 10:25:50 +00:00
void HKDF ( const uint8_t * salt , const uint8_t * key , size_t keyLen , const std : : string & info , uint8_t * out , size_t outLen = 64 ) ; // salt - 32, out - 32 or 64, info <= 32
2019-03-15 16:25:20 +00:00
2020-10-29 01:53:11 +00:00
// Noise
struct NoiseSymmetricState
{
uint8_t m_H [ 32 ] /*h*/ , m_CK [ 64 ] /*[ck, k]*/ ;
2020-11-14 22:31:20 +00:00
2020-10-29 01:53:11 +00:00
void MixHash ( const uint8_t * buf , size_t len ) ;
2022-03-07 23:20:06 +00:00
void MixHash ( const std : : vector < std : : pair < uint8_t * , size_t > > & bufs ) ;
2021-11-27 20:30:35 +00:00
void MixKey ( const uint8_t * sharedSecret ) ;
2020-11-14 22:31:20 +00:00
} ;
2020-12-03 22:58:37 +00:00
void InitNoiseNState ( NoiseSymmetricState & state , const uint8_t * pub ) ; // Noise_N (tunnels, router)
void InitNoiseXKState ( NoiseSymmetricState & state , const uint8_t * pub ) ; // Noise_XK (NTCP2)
2022-02-05 20:58:39 +00:00
void InitNoiseXKState1 ( NoiseSymmetricState & state , const uint8_t * pub ) ; // Noise_XK (SSU2)
2020-12-03 22:58:37 +00:00
void InitNoiseIKState ( NoiseSymmetricState & state , const uint8_t * pub ) ; // Noise_IK (ratchets)
2021-11-27 20:30:35 +00:00
2018-06-13 15:41:46 +00:00
// init and terminate
2024-12-07 20:27:23 +00:00
void InitCrypto ( bool precomputation ) ;
2015-12-31 21:02:10 +00:00
void TerminateCrypto ( ) ;
2018-01-06 03:48:51 +00:00
}
}
2016-10-12 16:31:27 +00:00
2014-05-06 16:22:22 +00:00
# endif