@ -14,20 +14,20 @@
namespace i2p
namespace i2p
{
{
namespace crypto
namespace crypto
{
{
const uint8_t elgp_ [ 256 ] =
const uint8_t elgp_ [ 256 ] =
{
{
0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xC9 , 0x0F , 0xDA , 0xA2 , 0x21 , 0x68 , 0xC2 , 0x34 ,
0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xC9 , 0x0F , 0xDA , 0xA2 , 0x21 , 0x68 , 0xC2 , 0x34 ,
0xC4 , 0xC6 , 0x62 , 0x8B , 0x80 , 0xDC , 0x1C , 0xD1 , 0x29 , 0x02 , 0x4E , 0x08 , 0x8A , 0x67 , 0xCC , 0x74 ,
0xC4 , 0xC6 , 0x62 , 0x8B , 0x80 , 0xDC , 0x1C , 0xD1 , 0x29 , 0x02 , 0x4E , 0x08 , 0x8A , 0x67 , 0xCC , 0x74 ,
0x02 , 0x0B , 0xBE , 0xA6 , 0x3B , 0x13 , 0x9B , 0x22 , 0x51 , 0x4A , 0x08 , 0x79 , 0x8E , 0x34 , 0x04 , 0xDD ,
0x02 , 0x0B , 0xBE , 0xA6 , 0x3B , 0x13 , 0x9B , 0x22 , 0x51 , 0x4A , 0x08 , 0x79 , 0x8E , 0x34 , 0x04 , 0xDD ,
0xEF , 0x95 , 0x19 , 0xB3 , 0xCD , 0x3A , 0x43 , 0x1B , 0x30 , 0x2B , 0x0A , 0x6D , 0xF2 , 0x5F , 0x14 , 0x37 ,
0xEF , 0x95 , 0x19 , 0xB3 , 0xCD , 0x3A , 0x43 , 0x1B , 0x30 , 0x2B , 0x0A , 0x6D , 0xF2 , 0x5F , 0x14 , 0x37 ,
0x4F , 0xE1 , 0x35 , 0x6D , 0x6D , 0x51 , 0xC2 , 0x45 , 0xE4 , 0x85 , 0xB5 , 0x76 , 0x62 , 0x5E , 0x7E , 0xC6 ,
0x4F , 0xE1 , 0x35 , 0x6D , 0x6D , 0x51 , 0xC2 , 0x45 , 0xE4 , 0x85 , 0xB5 , 0x76 , 0x62 , 0x5E , 0x7E , 0xC6 ,
0xF4 , 0x4C , 0x42 , 0xE9 , 0xA6 , 0x37 , 0xED , 0x6B , 0x0B , 0xFF , 0x5C , 0xB6 , 0xF4 , 0x06 , 0xB7 , 0xED ,
0xF4 , 0x4C , 0x42 , 0xE9 , 0xA6 , 0x37 , 0xED , 0x6B , 0x0B , 0xFF , 0x5C , 0xB6 , 0xF4 , 0x06 , 0xB7 , 0xED ,
0xEE , 0x38 , 0x6B , 0xFB , 0x5A , 0x89 , 0x9F , 0xA5 , 0xAE , 0x9F , 0x24 , 0x11 , 0x7C , 0x4B , 0x1F , 0xE6 ,
0xEE , 0x38 , 0x6B , 0xFB , 0x5A , 0x89 , 0x9F , 0xA5 , 0xAE , 0x9F , 0x24 , 0x11 , 0x7C , 0x4B , 0x1F , 0xE6 ,
0x49 , 0x28 , 0x66 , 0x51 , 0xEC , 0xE4 , 0x5B , 0x3D , 0xC2 , 0x00 , 0x7C , 0xB8 , 0xA1 , 0x63 , 0xBF , 0x05 ,
0x49 , 0x28 , 0x66 , 0x51 , 0xEC , 0xE4 , 0x5B , 0x3D , 0xC2 , 0x00 , 0x7C , 0xB8 , 0xA1 , 0x63 , 0xBF , 0x05 ,
0x98 , 0xDA , 0x48 , 0x36 , 0x1C , 0x55 , 0xD3 , 0x9A , 0x69 , 0x16 , 0x3F , 0xA8 , 0xFD , 0x24 , 0xCF , 0x5F ,
0x98 , 0xDA , 0x48 , 0x36 , 0x1C , 0x55 , 0xD3 , 0x9A , 0x69 , 0x16 , 0x3F , 0xA8 , 0xFD , 0x24 , 0xCF , 0x5F ,
0x83 , 0x65 , 0x5D , 0x23 , 0xDC , 0xA3 , 0xAD , 0x96 , 0x1C , 0x62 , 0xF3 , 0x56 , 0x20 , 0x85 , 0x52 , 0xBB ,
0x83 , 0x65 , 0x5D , 0x23 , 0xDC , 0xA3 , 0xAD , 0x96 , 0x1C , 0x62 , 0xF3 , 0x56 , 0x20 , 0x85 , 0x52 , 0xBB ,
0x9E , 0xD5 , 0x29 , 0x07 , 0x70 , 0x96 , 0x96 , 0x6D , 0x67 , 0x0C , 0x35 , 0x4E , 0x4A , 0xBC , 0x98 , 0x04 ,
0x9E , 0xD5 , 0x29 , 0x07 , 0x70 , 0x96 , 0x96 , 0x6D , 0x67 , 0x0C , 0x35 , 0x4E , 0x4A , 0xBC , 0x98 , 0x04 ,
0xF1 , 0x74 , 0x6C , 0x08 , 0xCA , 0x18 , 0x21 , 0x7C , 0x32 , 0x90 , 0x5E , 0x46 , 0x2E , 0x36 , 0xCE , 0x3B ,
0xF1 , 0x74 , 0x6C , 0x08 , 0xCA , 0x18 , 0x21 , 0x7C , 0x32 , 0x90 , 0x5E , 0x46 , 0x2E , 0x36 , 0xCE , 0x3B ,
0xE3 , 0x9E , 0x77 , 0x2C , 0x18 , 0x0E , 0x86 , 0x03 , 0x9B , 0x27 , 0x83 , 0xA2 , 0xEC , 0x07 , 0xA2 , 0x8F ,
0xE3 , 0x9E , 0x77 , 0x2C , 0x18 , 0x0E , 0x86 , 0x03 , 0x9B , 0x27 , 0x83 , 0xA2 , 0xEC , 0x07 , 0xA2 , 0x8F ,
0xB5 , 0xC5 , 0x5D , 0xF0 , 0x6F , 0x4C , 0x52 , 0xC9 , 0xDE , 0x2B , 0xCB , 0xF6 , 0x95 , 0x58 , 0x17 , 0x18 ,
0xB5 , 0xC5 , 0x5D , 0xF0 , 0x6F , 0x4C , 0x52 , 0xC9 , 0xDE , 0x2B , 0xCB , 0xF6 , 0x95 , 0x58 , 0x17 , 0x18 ,
@ -36,7 +36,7 @@ namespace crypto
} ;
} ;
const int elgg_ = 2 ;
const int elgg_ = 2 ;
const uint8_t dsap_ [ 128 ] =
const uint8_t dsap_ [ 128 ] =
{
{
0x9c , 0x05 , 0xb2 , 0xaa , 0x96 , 0x0d , 0x9b , 0x97 , 0xb8 , 0x93 , 0x19 , 0x63 , 0xc9 , 0xcc , 0x9e , 0x8c ,
0x9c , 0x05 , 0xb2 , 0xaa , 0x96 , 0x0d , 0x9b , 0x97 , 0xb8 , 0x93 , 0x19 , 0x63 , 0xc9 , 0xcc , 0x9e , 0x8c ,
@ -45,7 +45,7 @@ namespace crypto
0x76 , 0x55 , 0xc4 , 0x96 , 0x4a , 0xfa , 0xa2 , 0xb3 , 0x37 , 0xe9 , 0x6a , 0xd3 , 0x16 , 0xb9 , 0xfb , 0x1c ,
0x76 , 0x55 , 0xc4 , 0x96 , 0x4a , 0xfa , 0xa2 , 0xb3 , 0x37 , 0xe9 , 0x6a , 0xd3 , 0x16 , 0xb9 , 0xfb , 0x1c ,
0xc5 , 0x64 , 0xb5 , 0xae , 0xc5 , 0xb6 , 0x9a , 0x9f , 0xf6 , 0xc3 , 0xe4 , 0x54 , 0x87 , 0x07 , 0xfe , 0xf8 ,
0xc5 , 0x64 , 0xb5 , 0xae , 0xc5 , 0xb6 , 0x9a , 0x9f , 0xf6 , 0xc3 , 0xe4 , 0x54 , 0x87 , 0x07 , 0xfe , 0xf8 ,
0x50 , 0x3d , 0x91 , 0xdd , 0x86 , 0x02 , 0xe8 , 0x67 , 0xe6 , 0xd3 , 0x5d , 0x22 , 0x35 , 0xc1 , 0x86 , 0x9c ,
0x50 , 0x3d , 0x91 , 0xdd , 0x86 , 0x02 , 0xe8 , 0x67 , 0xe6 , 0xd3 , 0x5d , 0x22 , 0x35 , 0xc1 , 0x86 , 0x9c ,
0xe2 , 0x47 , 0x9c , 0x3b , 0x9d , 0x54 , 0x01 , 0xde , 0x04 , 0xe0 , 0x72 , 0x7f , 0xb3 , 0x3d , 0x65 , 0x11 ,
0xe2 , 0x47 , 0x9c , 0x3b , 0x9d , 0x54 , 0x01 , 0xde , 0x04 , 0xe0 , 0x72 , 0x7f , 0xb3 , 0x3d , 0x65 , 0x11 ,
0x28 , 0x5d , 0x4c , 0xf2 , 0x95 , 0x38 , 0xd9 , 0xe3 , 0xb6 , 0x05 , 0x1f , 0x5b , 0x22 , 0xcc , 0x1c , 0x93
0x28 , 0x5d , 0x4c , 0xf2 , 0x95 , 0x38 , 0xd9 , 0xe3 , 0xb6 , 0x05 , 0x1f , 0x5b , 0x22 , 0xcc , 0x1c , 0x93
} ;
} ;
@ -63,27 +63,27 @@ namespace crypto
0x3c , 0x43 , 0x1f , 0x46 , 0x98 , 0x59 , 0x9d , 0xda , 0x02 , 0x45 , 0x18 , 0x24 , 0xff , 0x36 , 0x97 , 0x52 ,
0x3c , 0x43 , 0x1f , 0x46 , 0x98 , 0x59 , 0x9d , 0xda , 0x02 , 0x45 , 0x18 , 0x24 , 0xff , 0x36 , 0x97 , 0x52 ,
0x59 , 0x36 , 0x47 , 0xcc , 0x3d , 0xdc , 0x19 , 0x7d , 0xe9 , 0x85 , 0xe4 , 0x3d , 0x13 , 0x6c , 0xdc , 0xfc ,
0x59 , 0x36 , 0x47 , 0xcc , 0x3d , 0xdc , 0x19 , 0x7d , 0xe9 , 0x85 , 0xe4 , 0x3d , 0x13 , 0x6c , 0xdc , 0xfc ,
0x6b , 0xd5 , 0x40 , 0x9c , 0xd2 , 0xf4 , 0x50 , 0x82 , 0x11 , 0x42 , 0xa5 , 0xe6 , 0xf8 , 0xeb , 0x1c , 0x3a ,
0x6b , 0xd5 , 0x40 , 0x9c , 0xd2 , 0xf4 , 0x50 , 0x82 , 0x11 , 0x42 , 0xa5 , 0xe6 , 0xf8 , 0xeb , 0x1c , 0x3a ,
0xb5 , 0xd0 , 0x48 , 0x4b , 0x81 , 0x29 , 0xfc , 0xf1 , 0x7b , 0xce , 0x4f , 0x7f , 0x33 , 0x32 , 0x1c , 0x3c ,
0xb5 , 0xd0 , 0x48 , 0x4b , 0x81 , 0x29 , 0xfc , 0xf1 , 0x7b , 0xce , 0x4f , 0x7f , 0x33 , 0x32 , 0x1c , 0x3c ,
0xb3 , 0xdb , 0xb1 , 0x4a , 0x90 , 0x5e , 0x7b , 0x2b , 0x3e , 0x93 , 0xbe , 0x47 , 0x08 , 0xcb , 0xcc , 0x82
0xb3 , 0xdb , 0xb1 , 0x4a , 0x90 , 0x5e , 0x7b , 0x2b , 0x3e , 0x93 , 0xbe , 0x47 , 0x08 , 0xcb , 0xcc , 0x82
} ;
} ;
const int rsae_ = 65537 ;
const int rsae_ = 65537 ;
struct CryptoConstants
struct CryptoConstants
{
{
// DH/ElGamal
// DH/ElGamal
BIGNUM * elgp ;
BIGNUM * elgp ;
BIGNUM * elgg ;
BIGNUM * elgg ;
// DSA
// DSA
BIGNUM * dsap ;
BIGNUM * dsap ;
BIGNUM * dsaq ;
BIGNUM * dsaq ;
BIGNUM * dsag ;
BIGNUM * dsag ;
// RSA
// RSA
BIGNUM * rsae ;
BIGNUM * rsae ;
CryptoConstants ( const uint8_t * elgp_ , int elgg_ , const uint8_t * dsap_ ,
CryptoConstants ( const uint8_t * elgp_ , int elgg_ , const uint8_t * dsap_ ,
const uint8_t * dsaq_ , const uint8_t * dsag_ , int rsae_ )
const uint8_t * dsaq_ , const uint8_t * dsag_ , int rsae_ )
{
{
elgp = BN_new ( ) ;
elgp = BN_new ( ) ;
@ -99,18 +99,18 @@ namespace crypto
rsae = BN_new ( ) ;
rsae = BN_new ( ) ;
BN_set_word ( rsae , rsae_ ) ;
BN_set_word ( rsae , rsae_ ) ;
}
}
~ CryptoConstants ( )
~ CryptoConstants ( )
{
{
BN_free ( elgp ) ; BN_free ( elgg ) ; BN_free ( dsap ) ; BN_free ( dsaq ) ; BN_free ( dsag ) ; BN_free ( rsae ) ;
BN_free ( elgp ) ; BN_free ( elgg ) ; BN_free ( dsap ) ; BN_free ( dsaq ) ; BN_free ( dsag ) ; BN_free ( rsae ) ;
}
}
} ;
} ;
static const CryptoConstants & GetCryptoConstants ( )
static const CryptoConstants & GetCryptoConstants ( )
{
{
static CryptoConstants cryptoConstants ( elgp_ , elgg_ , dsap_ , dsaq_ , dsag_ , rsae_ ) ;
static CryptoConstants cryptoConstants ( elgp_ , elgg_ , dsap_ , dsaq_ , dsag_ , rsae_ ) ;
return cryptoConstants ;
return cryptoConstants ;
}
}
bool bn2buf ( const BIGNUM * bn , uint8_t * buf , size_t len )
bool bn2buf ( const BIGNUM * bn , uint8_t * buf , size_t len )
{
{
@ -119,34 +119,34 @@ namespace crypto
BN_bn2bin ( bn , buf + offset ) ;
BN_bn2bin ( bn , buf + offset ) ;
memset ( buf , 0 , offset ) ;
memset ( buf , 0 , offset ) ;
return true ;
return true ;
}
}
// RSA
// RSA
# define rsae GetCryptoConstants ().rsae
# define rsae GetCryptoConstants ().rsae
const BIGNUM * GetRSAE ( )
const BIGNUM * GetRSAE ( )
{
{
return rsae ;
return rsae ;
}
}
// DSA
// DSA
# define dsap GetCryptoConstants ().dsap
# define dsap GetCryptoConstants ().dsap
# define dsaq GetCryptoConstants ().dsaq
# define dsaq GetCryptoConstants ().dsaq
# define dsag GetCryptoConstants ().dsag
# define dsag GetCryptoConstants ().dsag
DSA * CreateDSA ( )
DSA * CreateDSA ( )
{
{
DSA * dsa = DSA_new ( ) ;
DSA * dsa = DSA_new ( ) ;
DSA_set0_pqg ( dsa , BN_dup ( dsap ) , BN_dup ( dsaq ) , BN_dup ( dsag ) ) ;
DSA_set0_pqg ( dsa , BN_dup ( dsap ) , BN_dup ( dsaq ) , BN_dup ( dsag ) ) ;
DSA_set0_key ( dsa , NULL , NULL ) ;
DSA_set0_key ( dsa , NULL , NULL ) ;
return dsa ;
return dsa ;
}
}
// DH/ElGamal
// DH/ElGamal
const int ELGAMAL_SHORT_EXPONENT_NUM_BITS = 226 ;
const int ELGAMAL_SHORT_EXPONENT_NUM_BITS = 226 ;
const int ELGAMAL_SHORT_EXPONENT_NUM_BYTES = ELGAMAL_SHORT_EXPONENT_NUM_BITS / 8 + 1 ;
const int ELGAMAL_SHORT_EXPONENT_NUM_BYTES = ELGAMAL_SHORT_EXPONENT_NUM_BITS / 8 + 1 ;
const int ELGAMAL_FULL_EXPONENT_NUM_BITS = 2048 ;
const int ELGAMAL_FULL_EXPONENT_NUM_BITS = 2048 ;
const int ELGAMAL_FULL_EXPONENT_NUM_BYTES = ELGAMAL_FULL_EXPONENT_NUM_BITS / 8 ;
const int ELGAMAL_FULL_EXPONENT_NUM_BYTES = ELGAMAL_FULL_EXPONENT_NUM_BITS / 8 ;
# define elgp GetCryptoConstants ().elgp
# define elgp GetCryptoConstants ().elgp
# define elgg GetCryptoConstants ().elgg
# define elgg GetCryptoConstants ().elgg
@ -156,14 +156,14 @@ namespace crypto
if ( len < = 0 ) return ;
if ( len < = 0 ) return ;
BN_CTX * ctx = BN_CTX_new ( ) ;
BN_CTX * ctx = BN_CTX_new ( ) ;
g_MontCtx = BN_MONT_CTX_new ( ) ;
g_MontCtx = BN_MONT_CTX_new ( ) ;
BN_MONT_CTX_set ( g_MontCtx , elgp , ctx ) ;
BN_MONT_CTX_set ( g_MontCtx , elgp , ctx ) ;
auto montCtx = BN_MONT_CTX_new ( ) ;
auto montCtx = BN_MONT_CTX_new ( ) ;
BN_MONT_CTX_copy ( montCtx , g_MontCtx ) ;
BN_MONT_CTX_copy ( montCtx , g_MontCtx ) ;
for ( int i = 0 ; i < len ; i + + )
for ( int i = 0 ; i < len ; i + + )
{
{
table [ i ] [ 0 ] = BN_new ( ) ;
table [ i ] [ 0 ] = BN_new ( ) ;
if ( ! i )
if ( ! i )
BN_to_montgomery ( table [ 0 ] [ 0 ] , elgg , montCtx , ctx ) ;
BN_to_montgomery ( table [ 0 ] [ 0 ] , elgg , montCtx , ctx ) ;
else
else
BN_mod_mul_montgomery ( table [ i ] [ 0 ] , table [ i - 1 ] [ 254 ] , table [ i - 1 ] [ 0 ] , montCtx , ctx ) ;
BN_mod_mul_montgomery ( table [ i ] [ 0 ] , table [ i - 1 ] [ 254 ] , table [ i - 1 ] [ 0 ] , montCtx , ctx ) ;
for ( int j = 1 ; j < 255 ; j + + )
for ( int j = 1 ; j < 255 ; j + + )
@ -174,7 +174,7 @@ namespace crypto
}
}
BN_MONT_CTX_free ( montCtx ) ;
BN_MONT_CTX_free ( montCtx ) ;
BN_CTX_free ( ctx ) ;
BN_CTX_free ( ctx ) ;
}
}
static void DestroyElggTable ( BIGNUM * table [ ] [ 255 ] , int len )
static void DestroyElggTable ( BIGNUM * table [ ] [ 255 ] , int len )
{
{
@ -186,9 +186,9 @@ namespace crypto
}
}
BN_MONT_CTX_free ( g_MontCtx ) ;
BN_MONT_CTX_free ( g_MontCtx ) ;
}
}
static BIGNUM * ElggPow ( const uint8_t * exp , int len , BIGNUM * table [ ] [ 255 ] , BN_CTX * ctx )
static BIGNUM * ElggPow ( const uint8_t * exp , int len , BIGNUM * table [ ] [ 255 ] , BN_CTX * ctx )
// exp is in Big Endian
// exp is in Big Endian
{
{
if ( len < = 0 ) return nullptr ;
if ( len < = 0 ) return nullptr ;
auto montCtx = BN_MONT_CTX_new ( ) ;
auto montCtx = BN_MONT_CTX_new ( ) ;
@ -200,15 +200,15 @@ namespace crypto
{
{
if ( exp [ i ] )
if ( exp [ i ] )
BN_mod_mul_montgomery ( res , res , table [ len - 1 - i ] [ exp [ i ] - 1 ] , montCtx , ctx ) ;
BN_mod_mul_montgomery ( res , res , table [ len - 1 - i ] [ exp [ i ] - 1 ] , montCtx , ctx ) ;
}
}
else if ( exp [ i ] )
else if ( exp [ i ] )
res = BN_dup ( table [ len - i - 1 ] [ exp [ i ] - 1 ] ) ;
res = BN_dup ( table [ len - i - 1 ] [ exp [ i ] - 1 ] ) ;
}
}
if ( res )
if ( res )
BN_from_montgomery ( res , res , montCtx , ctx ) ;
BN_from_montgomery ( res , res , montCtx , ctx ) ;
BN_MONT_CTX_free ( montCtx ) ;
BN_MONT_CTX_free ( montCtx ) ;
return res ;
return res ;
}
}
static BIGNUM * ElggPow ( const BIGNUM * exp , BIGNUM * table [ ] [ 255 ] , BN_CTX * ctx )
static BIGNUM * ElggPow ( const BIGNUM * exp , BIGNUM * table [ ] [ 255 ] , BN_CTX * ctx )
{
{
@ -218,64 +218,64 @@ namespace crypto
auto ret = ElggPow ( buf , len , table , ctx ) ;
auto ret = ElggPow ( buf , len , table , ctx ) ;
delete [ ] buf ;
delete [ ] buf ;
return ret ;
return ret ;
}
}
static BIGNUM * ( * g_ElggTable ) [ 255 ] = nullptr ;
static BIGNUM * ( * g_ElggTable ) [ 255 ] = nullptr ;
// DH
// DH
DHKeys : : DHKeys ( )
DHKeys : : DHKeys ( )
{
{
m_DH = DH_new ( ) ;
m_DH = DH_new ( ) ;
DH_set0_pqg ( m_DH , BN_dup ( elgp ) , NULL , BN_dup ( elgg ) ) ;
DH_set0_pqg ( m_DH , BN_dup ( elgp ) , NULL , BN_dup ( elgg ) ) ;
DH_set0_key ( m_DH , NULL , NULL ) ;
DH_set0_key ( m_DH , NULL , NULL ) ;
}
}
DHKeys : : ~ DHKeys ( )
DHKeys : : ~ DHKeys ( )
{
{
DH_free ( m_DH ) ;
DH_free ( m_DH ) ;
}
}
void DHKeys : : GenerateKeys ( )
void DHKeys : : GenerateKeys ( )
{
{
BIGNUM * priv_key = NULL , * pub_key = NULL ;
BIGNUM * priv_key = NULL , * pub_key = NULL ;
# if !defined(__x86_64__) // use short exponent for non x64
# if !defined(__x86_64__) // use short exponent for non x64
priv_key = BN_new ( ) ;
priv_key = BN_new ( ) ;
BN_rand ( priv_key , ELGAMAL_SHORT_EXPONENT_NUM_BITS , 0 , 1 ) ;
BN_rand ( priv_key , ELGAMAL_SHORT_EXPONENT_NUM_BITS , 0 , 1 ) ;
# endif
# endif
if ( g_ElggTable )
if ( g_ElggTable )
{
{
# if defined(__x86_64__)
# if defined(__x86_64__)
priv_key = BN_new ( ) ;
priv_key = BN_new ( ) ;
BN_rand ( priv_key , ELGAMAL_FULL_EXPONENT_NUM_BITS , 0 , 1 ) ;
BN_rand ( priv_key , ELGAMAL_FULL_EXPONENT_NUM_BITS , 0 , 1 ) ;
# endif
# endif
auto ctx = BN_CTX_new ( ) ;
auto ctx = BN_CTX_new ( ) ;
pub_key = ElggPow ( priv_key , g_ElggTable , ctx ) ;
pub_key = ElggPow ( priv_key , g_ElggTable , ctx ) ;
DH_set0_key ( m_DH , pub_key , priv_key ) ;
DH_set0_key ( m_DH , pub_key , priv_key ) ;
BN_CTX_free ( ctx ) ;
BN_CTX_free ( ctx ) ;
}
}
else
else
{
{
DH_set0_key ( m_DH , NULL , priv_key ) ;
DH_set0_key ( m_DH , NULL , priv_key ) ;
DH_generate_key ( m_DH ) ;
DH_generate_key ( m_DH ) ;
DH_get0_key ( m_DH , ( const BIGNUM * * ) & pub_key , ( const BIGNUM * * ) & priv_key ) ;
DH_get0_key ( m_DH , ( const BIGNUM * * ) & pub_key , ( const BIGNUM * * ) & priv_key ) ;
}
}
bn2buf ( pub_key , m_PublicKey , 256 ) ;
bn2buf ( pub_key , m_PublicKey , 256 ) ;
}
}
void DHKeys : : Agree ( const uint8_t * pub , uint8_t * shared )
void DHKeys : : Agree ( const uint8_t * pub , uint8_t * shared )
{
{
BIGNUM * pk = BN_bin2bn ( pub , 256 , NULL ) ;
BIGNUM * pk = BN_bin2bn ( pub , 256 , NULL ) ;
DH_compute_key ( shared , pk , m_DH ) ;
DH_compute_key ( shared , pk , m_DH ) ;
BN_free ( pk ) ;
BN_free ( pk ) ;
}
}
// ElGamal
// ElGamal
void ElGamalEncrypt ( const uint8_t * key , const uint8_t * data , uint8_t * encrypted , BN_CTX * ctx , bool zeroPadding )
void ElGamalEncrypt ( const uint8_t * key , const uint8_t * data , uint8_t * encrypted , BN_CTX * ctx , bool zeroPadding )
{
{
BN_CTX_start ( ctx ) ;
BN_CTX_start ( ctx ) ;
// everything, but a, because a might come from table
// everything, but a, because a might come from table
BIGNUM * k = BN_CTX_get ( ctx ) ;
BIGNUM * k = BN_CTX_get ( ctx ) ;
BIGNUM * y = BN_CTX_get ( ctx ) ;
BIGNUM * y = BN_CTX_get ( ctx ) ;
BIGNUM * b1 = BN_CTX_get ( ctx ) ;
BIGNUM * b1 = BN_CTX_get ( ctx ) ;
@ -285,13 +285,13 @@ namespace crypto
BN_rand ( k , ELGAMAL_FULL_EXPONENT_NUM_BITS , - 1 , 1 ) ; // full exponent for x64
BN_rand ( k , ELGAMAL_FULL_EXPONENT_NUM_BITS , - 1 , 1 ) ; // full exponent for x64
# else
# else
BN_rand ( k , ELGAMAL_SHORT_EXPONENT_NUM_BITS , - 1 , 1 ) ; // short exponent of 226 bits
BN_rand ( k , ELGAMAL_SHORT_EXPONENT_NUM_BITS , - 1 , 1 ) ; // short exponent of 226 bits
# endif
# endif
// calculate a
// calculate a
BIGNUM * a ;
BIGNUM * a ;
if ( g_ElggTable )
if ( g_ElggTable )
a = ElggPow ( k , g_ElggTable , ctx ) ;
a = ElggPow ( k , g_ElggTable , ctx ) ;
else
else
{
{
a = BN_new ( ) ;
a = BN_new ( ) ;
BN_mod_exp ( a , elgg , k , elgp , ctx ) ;
BN_mod_exp ( a , elgg , k , elgp , ctx ) ;
}
}
@ -315,17 +315,17 @@ namespace crypto
bn2buf ( a , encrypted + 1 , 256 ) ;
bn2buf ( a , encrypted + 1 , 256 ) ;
encrypted [ 257 ] = 0 ;
encrypted [ 257 ] = 0 ;
bn2buf ( b , encrypted + 258 , 256 ) ;
bn2buf ( b , encrypted + 258 , 256 ) ;
}
}
else
else
{
{
bn2buf ( a , encrypted , 256 ) ;
bn2buf ( a , encrypted , 256 ) ;
bn2buf ( b , encrypted + 256 , 256 ) ;
bn2buf ( b , encrypted + 256 , 256 ) ;
}
}
BN_free ( a ) ;
BN_free ( a ) ;
BN_CTX_end ( ctx ) ;
BN_CTX_end ( ctx ) ;
}
}
bool ElGamalDecrypt ( const uint8_t * key , const uint8_t * encrypted ,
bool ElGamalDecrypt ( const uint8_t * key , const uint8_t * encrypted ,
uint8_t * data , BN_CTX * ctx , bool zeroPadding )
uint8_t * data , BN_CTX * ctx , bool zeroPadding )
{
{
BN_CTX_start ( ctx ) ;
BN_CTX_start ( ctx ) ;
@ -334,11 +334,11 @@ namespace crypto
BN_sub ( x , elgp , x ) ; BN_sub_word ( x , 1 ) ; // x = elgp - x- 1
BN_sub ( x , elgp , x ) ; BN_sub_word ( x , 1 ) ; // x = elgp - x- 1
BN_bin2bn ( zeroPadding ? encrypted + 1 : encrypted , 256 , a ) ;
BN_bin2bn ( zeroPadding ? encrypted + 1 : encrypted , 256 , a ) ;
BN_bin2bn ( zeroPadding ? encrypted + 258 : encrypted + 256 , 256 , b ) ;
BN_bin2bn ( zeroPadding ? encrypted + 258 : encrypted + 256 , 256 , b ) ;
// m = b*(a^x mod p) mod p
// m = b*(a^x mod p) mod p
BN_mod_exp ( x , a , x , elgp , ctx ) ;
BN_mod_exp ( x , a , x , elgp , ctx ) ;
BN_mod_mul ( b , b , x , elgp , ctx ) ;
BN_mod_mul ( b , b , x , elgp , ctx ) ;
uint8_t m [ 255 ] ;
uint8_t m [ 255 ] ;
bn2buf ( b , m , 255 ) ;
bn2buf ( b , m , 255 ) ;
BN_CTX_end ( ctx ) ;
BN_CTX_end ( ctx ) ;
uint8_t hash [ 32 ] ;
uint8_t hash [ 32 ] ;
SHA256 ( m + 33 , 222 , hash ) ;
SHA256 ( m + 33 , 222 , hash ) ;
@ -346,14 +346,14 @@ namespace crypto
{
{
LogPrint ( eLogError , " ElGamal decrypt hash doesn't match " ) ;
LogPrint ( eLogError , " ElGamal decrypt hash doesn't match " ) ;
return false ;
return false ;
}
}
memcpy ( data , m + 33 , 222 ) ;
memcpy ( data , m + 33 , 222 ) ;
return true ;
return true ;
}
}
void GenerateElGamalKeyPair ( uint8_t * priv , uint8_t * pub )
void GenerateElGamalKeyPair ( uint8_t * priv , uint8_t * pub )
{
{
# if defined(__x86_64__) || defined(__i386__) || defined(_MSC_VER)
# if defined(__x86_64__) || defined(__i386__) || defined(_MSC_VER)
RAND_bytes ( priv , 256 ) ;
RAND_bytes ( priv , 256 ) ;
# else
# else
// lower 226 bits (28 bytes and 2 bits) only. short exponent
// lower 226 bits (28 bytes and 2 bits) only. short exponent
@ -364,10 +364,10 @@ namespace crypto
priv [ numZeroBytes ] & = 0x03 ;
priv [ numZeroBytes ] & = 0x03 ;
# endif
# endif
BN_CTX * ctx = BN_CTX_new ( ) ;
BN_CTX * ctx = BN_CTX_new ( ) ;
BIGNUM * p = BN_new ( ) ;
BIGNUM * p = BN_new ( ) ;
BN_bin2bn ( priv , 256 , p ) ;
BN_bin2bn ( priv , 256 , p ) ;
BN_mod_exp ( p , elgg , p , elgp , ctx ) ;
BN_mod_exp ( p , elgg , p , elgp , ctx ) ;
bn2buf ( p , pub , 256 ) ;
bn2buf ( p , pub , 256 ) ;
BN_free ( p ) ;
BN_free ( p ) ;
BN_CTX_free ( ctx ) ;
BN_CTX_free ( ctx ) ;
}
}
@ -385,15 +385,15 @@ namespace crypto
auto p = EC_POINT_new ( curve ) ;
auto p = EC_POINT_new ( curve ) ;
EC_POINT_mul ( curve , p , k , nullptr , nullptr , ctx ) ;
EC_POINT_mul ( curve , p , k , nullptr , nullptr , ctx ) ;
BIGNUM * x = BN_CTX_get ( ctx ) , * y = BN_CTX_get ( ctx ) ;
BIGNUM * x = BN_CTX_get ( ctx ) , * y = BN_CTX_get ( ctx ) ;
EC_POINT_get_affine_coordinates_GFp ( curve , p , x , y , nullptr ) ;
EC_POINT_get_affine_coordinates_GFp ( curve , p , x , y , nullptr ) ;
encrypted [ 0 ] = 0 ;
encrypted [ 0 ] = 0 ;
bn2buf ( x , encrypted + 1 , len ) ;
bn2buf ( x , encrypted + 1 , len ) ;
bn2buf ( y , encrypted + 1 + len , len ) ;
bn2buf ( y , encrypted + 1 + len , len ) ;
RAND_bytes ( encrypted + 1 + 2 * len , 256 - 2 * len ) ;
RAND_bytes ( encrypted + 1 + 2 * len , 256 - 2 * len ) ;
// ecryption key and iv
// ecryption key and iv
EC_POINT_mul ( curve , p , nullptr , key , k , ctx ) ;
EC_POINT_mul ( curve , p , nullptr , key , k , ctx ) ;
EC_POINT_get_affine_coordinates_GFp ( curve , p , x , y , nullptr ) ;
EC_POINT_get_affine_coordinates_GFp ( curve , p , x , y , nullptr ) ;
uint8_t keyBuf [ 64 ] , iv [ 64 ] , shared [ 32 ] ;
uint8_t keyBuf [ 64 ] , iv [ 64 ] , shared [ 32 ] ;
bn2buf ( x , keyBuf , len ) ;
bn2buf ( x , keyBuf , len ) ;
bn2buf ( y , iv , len ) ;
bn2buf ( y , iv , len ) ;
SHA256 ( keyBuf , len , shared ) ;
SHA256 ( keyBuf , len , shared ) ;
@ -421,16 +421,16 @@ namespace crypto
int len = BN_num_bytes ( q ) ;
int len = BN_num_bytes ( q ) ;
// point for shared secret
// point for shared secret
BIGNUM * x = BN_CTX_get ( ctx ) , * y = BN_CTX_get ( ctx ) ;
BIGNUM * x = BN_CTX_get ( ctx ) , * y = BN_CTX_get ( ctx ) ;
BN_bin2bn ( encrypted + 1 , len , x ) ;
BN_bin2bn ( encrypted + 1 , len , x ) ;
BN_bin2bn ( encrypted + 1 + len , len , y ) ;
BN_bin2bn ( encrypted + 1 + len , len , y ) ;
auto p = EC_POINT_new ( curve ) ;
auto p = EC_POINT_new ( curve ) ;
if ( EC_POINT_set_affine_coordinates_GFp ( curve , p , x , y , nullptr ) )
if ( EC_POINT_set_affine_coordinates_GFp ( curve , p , x , y , nullptr ) )
{
{
auto s = EC_POINT_new ( curve ) ;
auto s = EC_POINT_new ( curve ) ;
EC_POINT_mul ( curve , s , nullptr , p , key , ctx ) ;
EC_POINT_mul ( curve , s , nullptr , p , key , ctx ) ;
EC_POINT_get_affine_coordinates_GFp ( curve , s , x , y , nullptr ) ;
EC_POINT_get_affine_coordinates_GFp ( curve , s , x , y , nullptr ) ;
EC_POINT_free ( s ) ;
EC_POINT_free ( s ) ;
uint8_t keyBuf [ 64 ] , iv [ 64 ] , shared [ 32 ] ;
uint8_t keyBuf [ 64 ] , iv [ 64 ] , shared [ 32 ] ;
bn2buf ( x , keyBuf , len ) ;
bn2buf ( x , keyBuf , len ) ;
bn2buf ( y , iv , len ) ;
bn2buf ( y , iv , len ) ;
SHA256 ( keyBuf , len , shared ) ;
SHA256 ( keyBuf , len , shared ) ;
@ -442,21 +442,21 @@ namespace crypto
decryption . Decrypt ( encrypted + 258 , 256 , m ) ;
decryption . Decrypt ( encrypted + 258 , 256 , m ) ;
// verify and copy
// verify and copy
uint8_t hash [ 32 ] ;
uint8_t hash [ 32 ] ;
SHA256 ( m + 33 , 222 , hash ) ;
SHA256 ( m + 33 , 222 , hash ) ;
if ( ! memcmp ( m + 1 , hash , 32 ) )
if ( ! memcmp ( m + 1 , hash , 32 ) )
memcpy ( data , m + 33 , 222 ) ;
memcpy ( data , m + 33 , 222 ) ;
else
else
{
{
LogPrint ( eLogError , " ECIES decrypt hash doesn't match " ) ;
LogPrint ( eLogError , " ECIES decrypt hash doesn't match " ) ;
ret = false ;
ret = false ;
}
}
}
}
else
else
{
{
LogPrint ( eLogError , " ECIES decrypt point is invalid " ) ;
LogPrint ( eLogError , " ECIES decrypt point is invalid " ) ;
ret = false ;
ret = false ;
}
}
EC_POINT_free ( p ) ;
EC_POINT_free ( p ) ;
BN_CTX_end ( ctx ) ;
BN_CTX_end ( ctx ) ;
return ret ;
return ret ;
@ -468,7 +468,7 @@ namespace crypto
BIGNUM * q = BN_new ( ) ;
BIGNUM * q = BN_new ( ) ;
EC_GROUP_get_order ( curve , q , ctx ) ;
EC_GROUP_get_order ( curve , q , ctx ) ;
priv = BN_new ( ) ;
priv = BN_new ( ) ;
BN_rand_range ( priv , q ) ;
BN_rand_range ( priv , q ) ;
pub = EC_POINT_new ( curve ) ;
pub = EC_POINT_new ( curve ) ;
EC_POINT_mul ( curve , pub , priv , nullptr , nullptr , ctx ) ;
EC_POINT_mul ( curve , pub , priv , nullptr , nullptr , ctx ) ;
BN_free ( q ) ;
BN_free ( q ) ;
@ -477,17 +477,17 @@ namespace crypto
// HMAC
// HMAC
const uint64_t IPAD = 0x3636363636363636 ;
const uint64_t IPAD = 0x3636363636363636 ;
const uint64_t OPAD = 0x5C5C5C5C5C5C5C5C ;
const uint64_t OPAD = 0x5C5C5C5C5C5C5C5C ;
# if defined(__AVX__)
# if defined(__AVX__)
static const uint64_t ipads [ ] = { IPAD , IPAD , IPAD , IPAD } ;
static const uint64_t ipads [ ] = { IPAD , IPAD , IPAD , IPAD } ;
static const uint64_t opads [ ] = { OPAD , OPAD , OPAD , OPAD } ;
static const uint64_t opads [ ] = { OPAD , OPAD , OPAD , OPAD } ;
# endif
# endif
void HMACMD5Digest ( uint8_t * msg , size_t len , const MACKey & key , uint8_t * digest )
void HMACMD5Digest ( uint8_t * msg , size_t len , const MACKey & key , uint8_t * digest )
// key is 32 bytes
// key is 32 bytes
// digest is 16 bytes
// digest is 16 bytes
// block size is 64 bytes
// block size is 64 bytes
{
{
uint64_t buf [ 256 ] ;
uint64_t buf [ 256 ] ;
uint64_t hash [ 12 ] ; // 96 bytes
uint64_t hash [ 12 ] ; // 96 bytes
@ -498,53 +498,53 @@ namespace crypto
" vmovups %[ipad], %%ymm1 \n "
" vmovups %[ipad], %%ymm1 \n "
" vmovups %%ymm1, 32(%[buf]) \n "
" vmovups %%ymm1, 32(%[buf]) \n "
" vxorps %%ymm0, %%ymm1, %%ymm1 \n "
" vxorps %%ymm0, %%ymm1, %%ymm1 \n "
" vmovups %%ymm1, (%[buf]) \n "
" vmovups %%ymm1, (%[buf]) \n "
" vmovups %[opad], %%ymm1 \n "
" vmovups %[opad], %%ymm1 \n "
" vmovups %%ymm1, 32(%[hash]) \n "
" vmovups %%ymm1, 32(%[hash]) \n "
" vxorps %%ymm0, %%ymm1, %%ymm1 \n "
" vxorps %%ymm0, %%ymm1, %%ymm1 \n "
" vmovups %%ymm1, (%[hash]) \n "
" vmovups %%ymm1, (%[hash]) \n "
" vzeroall \n " // end of AVX
" vzeroall \n " // end of AVX
" movups %%xmm0, 80(%[hash]) \n " // zero last 16 bytes
" movups %%xmm0, 80(%[hash]) \n " // zero last 16 bytes
:
:
: [ key ] " m " ( * ( const uint8_t * ) key ) , [ ipad ] " m " ( * ipads ) , [ opad ] " m " ( * opads ) ,
: [ key ] " m " ( * ( const uint8_t * ) key ) , [ ipad ] " m " ( * ipads ) , [ opad ] " m " ( * opads ) ,
[ buf ] " r " ( buf ) , [ hash ] " r " ( hash )
[ buf ] " r " ( buf ) , [ hash ] " r " ( hash )
: " memory " , " %xmm0 " // TODO: change to %ymm0 later
: " memory " , " %xmm0 " // TODO: change to %ymm0 later
) ;
) ;
# else
# else
// ikeypad
// ikeypad
buf [ 0 ] = key . GetLL ( ) [ 0 ] ^ IPAD ;
buf [ 0 ] = key . GetLL ( ) [ 0 ] ^ IPAD ;
buf [ 1 ] = key . GetLL ( ) [ 1 ] ^ IPAD ;
buf [ 1 ] = key . GetLL ( ) [ 1 ] ^ IPAD ;
buf [ 2 ] = key . GetLL ( ) [ 2 ] ^ IPAD ;
buf [ 2 ] = key . GetLL ( ) [ 2 ] ^ IPAD ;
buf [ 3 ] = key . GetLL ( ) [ 3 ] ^ IPAD ;
buf [ 3 ] = key . GetLL ( ) [ 3 ] ^ IPAD ;
buf [ 4 ] = IPAD ;
buf [ 4 ] = IPAD ;
buf [ 5 ] = IPAD ;
buf [ 5 ] = IPAD ;
buf [ 6 ] = IPAD ;
buf [ 6 ] = IPAD ;
buf [ 7 ] = IPAD ;
buf [ 7 ] = IPAD ;
// okeypad
// okeypad
hash [ 0 ] = key . GetLL ( ) [ 0 ] ^ OPAD ;
hash [ 0 ] = key . GetLL ( ) [ 0 ] ^ OPAD ;
hash [ 1 ] = key . GetLL ( ) [ 1 ] ^ OPAD ;
hash [ 1 ] = key . GetLL ( ) [ 1 ] ^ OPAD ;
hash [ 2 ] = key . GetLL ( ) [ 2 ] ^ OPAD ;
hash [ 2 ] = key . GetLL ( ) [ 2 ] ^ OPAD ;
hash [ 3 ] = key . GetLL ( ) [ 3 ] ^ OPAD ;
hash [ 3 ] = key . GetLL ( ) [ 3 ] ^ OPAD ;
hash [ 4 ] = OPAD ;
hash [ 4 ] = OPAD ;
hash [ 5 ] = OPAD ;
hash [ 5 ] = OPAD ;
hash [ 6 ] = OPAD ;
hash [ 6 ] = OPAD ;
hash [ 7 ] = OPAD ;
hash [ 7 ] = OPAD ;
// fill last 16 bytes with zeros (first hash size assumed 32 bytes in I2P)
// fill last 16 bytes with zeros (first hash size assumed 32 bytes in I2P)
memset ( hash + 10 , 0 , 16 ) ;
memset ( hash + 10 , 0 , 16 ) ;
# endif
# endif
// concatenate with msg
// concatenate with msg
memcpy ( buf + 8 , msg , len ) ;
memcpy ( buf + 8 , msg , len ) ;
// calculate first hash
// calculate first hash
MD5 ( ( uint8_t * ) buf , len + 64 , ( uint8_t * ) ( hash + 8 ) ) ; // 16 bytes
MD5 ( ( uint8_t * ) buf , len + 64 , ( uint8_t * ) ( hash + 8 ) ) ; // 16 bytes
// calculate digest
// calculate digest
MD5 ( ( uint8_t * ) hash , 96 , digest ) ;
MD5 ( ( uint8_t * ) hash , 96 , digest ) ;
}
}
// AES
// AES
# ifdef AESNI
# ifdef AESNI
# define KeyExpansion256(round0,round1) \
# define KeyExpansion256(round0,round1) \
" pshufd $0xff, %%xmm2, %%xmm2 \n " \
" pshufd $0xff, %%xmm2, %%xmm2 \n " \
" movaps %%xmm1, %%xmm4 \n " \
" movaps %%xmm1, %%xmm4 \n " \
@ -566,7 +566,7 @@ namespace crypto
" pslldq $4, %%xmm4 \n " \
" pslldq $4, %%xmm4 \n " \
" pxor %%xmm4, %%xmm3 \n " \
" pxor %%xmm4, %%xmm3 \n " \
" pxor %%xmm2, %%xmm3 \n " \
" pxor %%xmm2, %%xmm3 \n " \
" movaps %%xmm3, " # round1 " (%[sched]) \n "
" movaps %%xmm3, " # round1 " (%[sched]) \n "
void ECBCryptoAESNI : : ExpandKey ( const AESKey & key )
void ECBCryptoAESNI : : ExpandKey ( const AESKey & key )
{
{
@ -591,7 +591,7 @@ namespace crypto
" aeskeygenassist $64, %%xmm3, %%xmm2 \n "
" aeskeygenassist $64, %%xmm3, %%xmm2 \n "
// key expansion final
// key expansion final
" pshufd $0xff, %%xmm2, %%xmm2 \n "
" pshufd $0xff, %%xmm2, %%xmm2 \n "
" movaps %%xmm1, %%xmm4 \n "
" movaps %%xmm1, %%xmm4 \n "
" pslldq $4, %%xmm4 \n "
" pslldq $4, %%xmm4 \n "
" pxor %%xmm4, %%xmm1 \n "
" pxor %%xmm4, %%xmm1 \n "
" pslldq $4, %%xmm4 \n "
" pslldq $4, %%xmm4 \n "
@ -622,17 +622,17 @@ namespace crypto
" aesenc 192(%[ " # sched " ]), %%xmm0 \n " \
" aesenc 192(%[ " # sched " ]), %%xmm0 \n " \
" aesenc 208(%[ " # sched " ]), %%xmm0 \n " \
" aesenc 208(%[ " # sched " ]), %%xmm0 \n " \
" aesenclast 224(%[ " # sched " ]), %%xmm0 \n "
" aesenclast 224(%[ " # sched " ]), %%xmm0 \n "
void ECBEncryptionAESNI : : Encrypt ( const ChipherBlock * in , ChipherBlock * out )
void ECBEncryptionAESNI : : Encrypt ( const ChipherBlock * in , ChipherBlock * out )
{
{
__asm__
__asm__
(
(
" movups (%[in]), %%xmm0 \n "
" movups (%[in]), %%xmm0 \n "
EncryptAES256 ( sched )
EncryptAES256 ( sched )
" movups %%xmm0, (%[out]) \n "
" movups %%xmm0, (%[out]) \n "
: : [ sched ] " r " ( GetKeySchedule ( ) ) , [ in ] " r " ( in ) , [ out ] " r " ( out ) : " %xmm0 " , " memory "
: : [ sched ] " r " ( GetKeySchedule ( ) ) , [ in ] " r " ( in ) , [ out ] " r " ( out ) : " %xmm0 " , " memory "
) ;
) ;
}
}
# define DecryptAES256(sched) \
# define DecryptAES256(sched) \
" pxor 224(%[ " # sched " ]), %%xmm0 \n " \
" pxor 224(%[ " # sched " ]), %%xmm0 \n " \
@ -650,22 +650,22 @@ namespace crypto
" aesdec 32(%[ " # sched " ]), %%xmm0 \n " \
" aesdec 32(%[ " # sched " ]), %%xmm0 \n " \
" aesdec 16(%[ " # sched " ]), %%xmm0 \n " \
" aesdec 16(%[ " # sched " ]), %%xmm0 \n " \
" aesdeclast (%[ " # sched " ]), %%xmm0 \n "
" aesdeclast (%[ " # sched " ]), %%xmm0 \n "
void ECBDecryptionAESNI : : Decrypt ( const ChipherBlock * in , ChipherBlock * out )
void ECBDecryptionAESNI : : Decrypt ( const ChipherBlock * in , ChipherBlock * out )
{
{
__asm__
__asm__
(
(
" movups (%[in]), %%xmm0 \n "
" movups (%[in]), %%xmm0 \n "
DecryptAES256 ( sched )
DecryptAES256 ( sched )
" movups %%xmm0, (%[out]) \n "
" movups %%xmm0, (%[out]) \n "
: : [ sched ] " r " ( GetKeySchedule ( ) ) , [ in ] " r " ( in ) , [ out ] " r " ( out ) : " %xmm0 " , " memory "
: : [ sched ] " r " ( GetKeySchedule ( ) ) , [ in ] " r " ( in ) , [ out ] " r " ( out ) : " %xmm0 " , " memory "
) ;
) ;
}
}
# define CallAESIMC(offset) \
# define CallAESIMC(offset) \
" movaps " # offset " (%[shed]), %%xmm0 \n " \
" movaps " # offset " (%[shed]), %%xmm0 \n " \
" aesimc %%xmm0, %%xmm0 \n " \
" aesimc %%xmm0, %%xmm0 \n " \
" movaps %%xmm0, " # offset " (%[shed]) \n "
" movaps %%xmm0, " # offset " (%[shed]) \n "
void ECBDecryptionAESNI : : SetKey ( const AESKey & key )
void ECBDecryptionAESNI : : SetKey ( const AESKey & key )
{
{
@ -690,7 +690,7 @@ namespace crypto
) ;
) ;
}
}
# endif
# endif
void CBCEncryption : : Encrypt ( int numBlocks , const ChipherBlock * in , ChipherBlock * out )
void CBCEncryption : : Encrypt ( int numBlocks , const ChipherBlock * in , ChipherBlock * out )
@ -698,31 +698,31 @@ namespace crypto
# ifdef AESNI
# ifdef AESNI
__asm__
__asm__
(
(
" movups (%[iv]), %%xmm1 \n "
" movups (%[iv]), %%xmm1 \n "
" 1: \n "
" 1: \n "
" movups (%[in]), %%xmm0 \n "
" movups (%[in]), %%xmm0 \n "
" pxor %%xmm1, %%xmm0 \n "
" pxor %%xmm1, %%xmm0 \n "
EncryptAES256 ( sched )
EncryptAES256 ( sched )
" movaps %%xmm0, %%xmm1 \n "
" movaps %%xmm0, %%xmm1 \n "
" movups %%xmm0, (%[out]) \n "
" movups %%xmm0, (%[out]) \n "
" add $16, %[in] \n "
" add $16, %[in] \n "
" add $16, %[out] \n "
" add $16, %[out] \n "
" dec %[num] \n "
" dec %[num] \n "
" jnz 1b \n "
" jnz 1b \n "
" movups %%xmm1, (%[iv]) \n "
" movups %%xmm1, (%[iv]) \n "
:
:
: [ iv ] " r " ( ( uint8_t * ) m_LastBlock ) , [ sched ] " r " ( m_ECBEncryption . GetKeySchedule ( ) ) ,
: [ iv ] " r " ( ( uint8_t * ) m_LastBlock ) , [ sched ] " r " ( m_ECBEncryption . GetKeySchedule ( ) ) ,
[ in ] " r " ( in ) , [ out ] " r " ( out ) , [ num ] " r " ( numBlocks )
[ in ] " r " ( in ) , [ out ] " r " ( out ) , [ num ] " r " ( numBlocks )
: " %xmm0 " , " %xmm1 " , " cc " , " memory "
: " %xmm0 " , " %xmm1 " , " cc " , " memory "
) ;
) ;
# else
# else
for ( int i = 0 ; i < numBlocks ; i + + )
for ( int i = 0 ; i < numBlocks ; i + + )
{
{
* m_LastBlock . GetChipherBlock ( ) ^ = in [ i ] ;
* m_LastBlock . GetChipherBlock ( ) ^ = in [ i ] ;
m_ECBEncryption . Encrypt ( m_LastBlock . GetChipherBlock ( ) , m_LastBlock . GetChipherBlock ( ) ) ;
m_ECBEncryption . Encrypt ( m_LastBlock . GetChipherBlock ( ) , m_LastBlock . GetChipherBlock ( ) ) ;
out [ i ] = * m_LastBlock . GetChipherBlock ( ) ;
out [ i ] = * m_LastBlock . GetChipherBlock ( ) ;
}
}
# endif
# endif
}
}
void CBCEncryption : : Encrypt ( const uint8_t * in , std : : size_t len , uint8_t * out )
void CBCEncryption : : Encrypt ( const uint8_t * in , std : : size_t len , uint8_t * out )
@ -730,7 +730,7 @@ namespace crypto
// len/16
// len/16
int numBlocks = len > > 4 ;
int numBlocks = len > > 4 ;
if ( numBlocks > 0 )
if ( numBlocks > 0 )
Encrypt ( numBlocks , ( const ChipherBlock * ) in , ( ChipherBlock * ) out ) ;
Encrypt ( numBlocks , ( const ChipherBlock * ) in , ( ChipherBlock * ) out ) ;
}
}
void CBCEncryption : : Encrypt ( const uint8_t * in , uint8_t * out )
void CBCEncryption : : Encrypt ( const uint8_t * in , uint8_t * out )
@ -740,17 +740,17 @@ namespace crypto
(
(
" movups (%[iv]), %%xmm1 \n "
" movups (%[iv]), %%xmm1 \n "
" movups (%[in]), %%xmm0 \n "
" movups (%[in]), %%xmm0 \n "
" pxor %%xmm1, %%xmm0 \n "
" pxor %%xmm1, %%xmm0 \n "
EncryptAES256 ( sched )
EncryptAES256 ( sched )
" movups %%xmm0, (%[out]) \n "
" movups %%xmm0, (%[out]) \n "
" movups %%xmm0, (%[iv]) \n "
" movups %%xmm0, (%[iv]) \n "
:
:
: [ iv ] " r " ( ( uint8_t * ) m_LastBlock ) , [ sched ] " r " ( m_ECBEncryption . GetKeySchedule ( ) ) ,
: [ iv ] " r " ( ( uint8_t * ) m_LastBlock ) , [ sched ] " r " ( m_ECBEncryption . GetKeySchedule ( ) ) ,
[ in ] " r " ( in ) , [ out ] " r " ( out )
[ in ] " r " ( in ) , [ out ] " r " ( out )
: " %xmm0 " , " %xmm1 " , " memory "
: " %xmm0 " , " %xmm1 " , " memory "
) ;
) ;
# else
# else
Encrypt ( 1 , ( const ChipherBlock * ) in , ( ChipherBlock * ) out ) ;
Encrypt ( 1 , ( const ChipherBlock * ) in , ( ChipherBlock * ) out ) ;
# endif
# endif
}
}
@ -760,23 +760,23 @@ namespace crypto
__asm__
__asm__
(
(
" movups (%[iv]), %%xmm1 \n "
" movups (%[iv]), %%xmm1 \n "
" 1: \n "
" 1: \n "
" movups (%[in]), %%xmm0 \n "
" movups (%[in]), %%xmm0 \n "
" movaps %%xmm0, %%xmm2 \n "
" movaps %%xmm0, %%xmm2 \n "
DecryptAES256 ( sched )
DecryptAES256 ( sched )
" pxor %%xmm1, %%xmm0 \n "
" pxor %%xmm1, %%xmm0 \n "
" movups %%xmm0, (%[out]) \n "
" movups %%xmm0, (%[out]) \n "
" movaps %%xmm2, %%xmm1 \n "
" movaps %%xmm2, %%xmm1 \n "
" add $16, %[in] \n "
" add $16, %[in] \n "
" add $16, %[out] \n "
" add $16, %[out] \n "
" dec %[num] \n "
" dec %[num] \n "
" jnz 1b \n "
" jnz 1b \n "
" movups %%xmm1, (%[iv]) \n "
" movups %%xmm1, (%[iv]) \n "
:
:
: [ iv ] " r " ( ( uint8_t * ) m_IV ) , [ sched ] " r " ( m_ECBDecryption . GetKeySchedule ( ) ) ,
: [ iv ] " r " ( ( uint8_t * ) m_IV ) , [ sched ] " r " ( m_ECBDecryption . GetKeySchedule ( ) ) ,
[ in ] " r " ( in ) , [ out ] " r " ( out ) , [ num ] " r " ( numBlocks )
[ in ] " r " ( in ) , [ out ] " r " ( out ) , [ num ] " r " ( numBlocks )
: " %xmm0 " , " %xmm1 " , " %xmm2 " , " cc " , " memory "
: " %xmm0 " , " %xmm1 " , " %xmm2 " , " cc " , " memory "
) ;
) ;
# else
# else
for ( int i = 0 ; i < numBlocks ; i + + )
for ( int i = 0 ; i < numBlocks ; i + + )
{
{
@ -792,7 +792,7 @@ namespace crypto
{
{
int numBlocks = len > > 4 ;
int numBlocks = len > > 4 ;
if ( numBlocks > 0 )
if ( numBlocks > 0 )
Decrypt ( numBlocks , ( const ChipherBlock * ) in , ( ChipherBlock * ) out ) ;
Decrypt ( numBlocks , ( const ChipherBlock * ) in , ( ChipherBlock * ) out ) ;
}
}
void CBCDecryption : : Decrypt ( const uint8_t * in , uint8_t * out )
void CBCDecryption : : Decrypt ( const uint8_t * in , uint8_t * out )
@ -801,18 +801,18 @@ namespace crypto
__asm__
__asm__
(
(
" movups (%[iv]), %%xmm1 \n "
" movups (%[iv]), %%xmm1 \n "
" movups (%[in]), %%xmm0 \n "
" movups (%[in]), %%xmm0 \n "
" movups %%xmm0, (%[iv]) \n "
" movups %%xmm0, (%[iv]) \n "
DecryptAES256 ( sched )
DecryptAES256 ( sched )
" pxor %%xmm1, %%xmm0 \n "
" pxor %%xmm1, %%xmm0 \n "
" movups %%xmm0, (%[out]) \n "
" movups %%xmm0, (%[out]) \n "
:
:
: [ iv ] " r " ( ( uint8_t * ) m_IV ) , [ sched ] " r " ( m_ECBDecryption . GetKeySchedule ( ) ) ,
: [ iv ] " r " ( ( uint8_t * ) m_IV ) , [ sched ] " r " ( m_ECBDecryption . GetKeySchedule ( ) ) ,
[ in ] " r " ( in ) , [ out ] " r " ( out )
[ in ] " r " ( in ) , [ out ] " r " ( out )
: " %xmm0 " , " %xmm1 " , " memory "
: " %xmm0 " , " %xmm1 " , " memory "
) ;
) ;
# else
# else
Decrypt ( 1 , ( const ChipherBlock * ) in , ( ChipherBlock * ) out ) ;
Decrypt ( 1 , ( const ChipherBlock * ) in , ( ChipherBlock * ) out ) ;
# endif
# endif
}
}
@ -821,7 +821,7 @@ namespace crypto
# ifdef AESNI
# ifdef AESNI
__asm__
__asm__
(
(
// encrypt IV
// encrypt IV
" movups (%[in]), %%xmm0 \n "
" movups (%[in]), %%xmm0 \n "
EncryptAES256 ( sched_iv )
EncryptAES256 ( sched_iv )
" movaps %%xmm0, %%xmm1 \n "
" movaps %%xmm0, %%xmm1 \n "
@ -831,16 +831,16 @@ namespace crypto
// encrypt data, IV is xmm1
// encrypt data, IV is xmm1
" 1: \n "
" 1: \n "
" add $16, %[in] \n "
" add $16, %[in] \n "
" add $16, %[out] \n "
" add $16, %[out] \n "
" movups (%[in]), %%xmm0 \n "
" movups (%[in]), %%xmm0 \n "
" pxor %%xmm1, %%xmm0 \n "
" pxor %%xmm1, %%xmm0 \n "
EncryptAES256 ( sched_l )
EncryptAES256 ( sched_l )
" movaps %%xmm0, %%xmm1 \n "
" movaps %%xmm0, %%xmm1 \n "
" movups %%xmm0, (%[out]) \n "
" movups %%xmm0, (%[out]) \n "
" dec %[num] \n "
" dec %[num] \n "
" jnz 1b \n "
" jnz 1b \n "
:
:
: [ sched_iv ] " r " ( m_IVEncryption . GetKeySchedule ( ) ) , [ sched_l ] " r " ( m_LayerEncryption . GetKeySchedule ( ) ) ,
: [ sched_iv ] " r " ( m_IVEncryption . GetKeySchedule ( ) ) , [ sched_l ] " r " ( m_LayerEncryption . GetKeySchedule ( ) ) ,
[ in ] " r " ( in ) , [ out ] " r " ( out ) , [ num ] " r " ( 63 ) // 63 blocks = 1008 bytes
[ in ] " r " ( in ) , [ out ] " r " ( out ) , [ num ] " r " ( 63 ) // 63 blocks = 1008 bytes
: " %xmm0 " , " %xmm1 " , " cc " , " memory "
: " %xmm0 " , " %xmm1 " , " cc " , " memory "
) ;
) ;
@ -857,7 +857,7 @@ namespace crypto
# ifdef AESNI
# ifdef AESNI
__asm__
__asm__
(
(
// decrypt IV
// decrypt IV
" movups (%[in]), %%xmm0 \n "
" movups (%[in]), %%xmm0 \n "
DecryptAES256 ( sched_iv )
DecryptAES256 ( sched_iv )
" movaps %%xmm0, %%xmm1 \n "
" movaps %%xmm0, %%xmm1 \n "
@ -867,27 +867,27 @@ namespace crypto
// decrypt data, IV is xmm1
// decrypt data, IV is xmm1
" 1: \n "
" 1: \n "
" add $16, %[in] \n "
" add $16, %[in] \n "
" add $16, %[out] \n "
" add $16, %[out] \n "
" movups (%[in]), %%xmm0 \n "
" movups (%[in]), %%xmm0 \n "
" movaps %%xmm0, %%xmm2 \n "
" movaps %%xmm0, %%xmm2 \n "
DecryptAES256 ( sched_l )
DecryptAES256 ( sched_l )
" pxor %%xmm1, %%xmm0 \n "
" pxor %%xmm1, %%xmm0 \n "
" movups %%xmm0, (%[out]) \n "
" movups %%xmm0, (%[out]) \n "
" movaps %%xmm2, %%xmm1 \n "
" movaps %%xmm2, %%xmm1 \n "
" dec %[num] \n "
" dec %[num] \n "
" jnz 1b \n "
" jnz 1b \n "
:
:
: [ sched_iv ] " r " ( m_IVDecryption . GetKeySchedule ( ) ) , [ sched_l ] " r " ( m_LayerDecryption . GetKeySchedule ( ) ) ,
: [ sched_iv ] " r " ( m_IVDecryption . GetKeySchedule ( ) ) , [ sched_l ] " r " ( m_LayerDecryption . GetKeySchedule ( ) ) ,
[ in ] " r " ( in ) , [ out ] " r " ( out ) , [ num ] " r " ( 63 ) // 63 blocks = 1008 bytes
[ in ] " r " ( in ) , [ out ] " r " ( out ) , [ num ] " r " ( 63 ) // 63 blocks = 1008 bytes
: " %xmm0 " , " %xmm1 " , " %xmm2 " , " cc " , " memory "
: " %xmm0 " , " %xmm1 " , " %xmm2 " , " cc " , " memory "
) ;
) ;
# else
# else
m_IVDecryption . Decrypt ( ( const ChipherBlock * ) in , ( ChipherBlock * ) out ) ; // iv
m_IVDecryption . Decrypt ( ( const ChipherBlock * ) in , ( ChipherBlock * ) out ) ; // iv
m_LayerDecryption . SetIV ( out ) ;
m_LayerDecryption . SetIV ( out ) ;
m_LayerDecryption . Decrypt ( in + 16 , i2p : : tunnel : : TUNNEL_DATA_ENCRYPTED_SIZE , out + 16 ) ; // data
m_LayerDecryption . Decrypt ( in + 16 , i2p : : tunnel : : TUNNEL_DATA_ENCRYPTED_SIZE , out + 16 ) ; // data
m_IVDecryption . Decrypt ( ( ChipherBlock * ) out , ( ChipherBlock * ) out ) ; // double iv
m_IVDecryption . Decrypt ( ( ChipherBlock * ) out , ( ChipherBlock * ) out ) ; // double iv
# endif
# endif
}
}
/* std::vector <std::unique_ptr<std::mutex> > m_OpenSSLMutexes;
/* std::vector <std::unique_ptr<std::mutex> > m_OpenSSLMutexes;
static void OpensslLockingCallback ( int mode , int type , const char * file , int line )
static void OpensslLockingCallback ( int mode , int type , const char * file , int line )
@ -898,45 +898,44 @@ namespace crypto
m_OpenSSLMutexes [ type ] - > lock ( ) ;
m_OpenSSLMutexes [ type ] - > lock ( ) ;
else
else
m_OpenSSLMutexes [ type ] - > unlock ( ) ;
m_OpenSSLMutexes [ type ] - > unlock ( ) ;
}
}
} */
} */
void InitCrypto ( bool precomputation )
void InitCrypto ( bool precomputation )
{
{
SSL_library_init ( ) ;
SSL_library_init ( ) ;
/* auto numLocks = CRYPTO_num_locks();
/* auto numLocks = CRYPTO_num_locks();
for ( int i = 0 ; i < numLocks ; i + + )
for ( int i = 0 ; i < numLocks ; i + + )
m_OpenSSLMutexes . emplace_back ( new std : : mutex ) ;
m_OpenSSLMutexes . emplace_back ( new std : : mutex ) ;
CRYPTO_set_locking_callback ( OpensslLockingCallback ) ; */
CRYPTO_set_locking_callback ( OpensslLockingCallback ) ; */
if ( precomputation )
if ( precomputation )
{
{
# if defined(__x86_64__)
# if defined(__x86_64__)
g_ElggTable = new BIGNUM * [ ELGAMAL_FULL_EXPONENT_NUM_BYTES ] [ 255 ] ;
g_ElggTable = new BIGNUM * [ ELGAMAL_FULL_EXPONENT_NUM_BYTES ] [ 255 ] ;
PrecalculateElggTable ( g_ElggTable , ELGAMAL_FULL_EXPONENT_NUM_BYTES ) ;
PrecalculateElggTable ( g_ElggTable , ELGAMAL_FULL_EXPONENT_NUM_BYTES ) ;
# else
# else
g_ElggTable = new BIGNUM * [ ELGAMAL_SHORT_EXPONENT_NUM_BYTES ] [ 255 ] ;
g_ElggTable = new BIGNUM * [ ELGAMAL_SHORT_EXPONENT_NUM_BYTES ] [ 255 ] ;
PrecalculateElggTable ( g_ElggTable , ELGAMAL_SHORT_EXPONENT_NUM_BYTES ) ;
PrecalculateElggTable ( g_ElggTable , ELGAMAL_SHORT_EXPONENT_NUM_BYTES ) ;
# endif
# endif
}
}
}
}
void TerminateCrypto ( )
void TerminateCrypto ( )
{
{
if ( g_ElggTable )
if ( g_ElggTable )
{
{
DestroyElggTable ( g_ElggTable ,
DestroyElggTable ( g_ElggTable ,
# if defined(__x86_64__)
# if defined(__x86_64__)
ELGAMAL_FULL_EXPONENT_NUM_BYTES
ELGAMAL_FULL_EXPONENT_NUM_BYTES
# else
# else
ELGAMAL_SHORT_EXPONENT_NUM_BYTES
ELGAMAL_SHORT_EXPONENT_NUM_BYTES
# endif
# endif
) ;
) ;
delete [ ] g_ElggTable ; g_ElggTable = nullptr ;
delete [ ] g_ElggTable ; g_ElggTable = nullptr ;
}
}
/* CRYPTO_set_locking_callback (nullptr);
/* CRYPTO_set_locking_callback (nullptr);
m_OpenSSLMutexes . clear ( ) ; */
m_OpenSSLMutexes . clear ( ) ; */
}
}
}
}
}
}