@ -1,5 +1,5 @@
/*
/*
* Copyright ( c ) 2013 - 2022 , The PurpleI2P Project
* Copyright ( c ) 2013 - 2023 , The PurpleI2P Project
*
*
* This file is part of Purple i2pd project and licensed under BSD3
* This file is part of Purple i2pd project and licensed under BSD3
*
*
@ -28,6 +28,12 @@
# include "I2PEndian.h"
# include "I2PEndian.h"
# include "Log.h"
# include "Log.h"
# if defined(__AES__) && !defined(_MSC_VER) && ((defined(_M_AMD64) || defined(__x86_64__)) || (defined(_M_IX86) || defined(__i386__)))
# define SUPPORTS_AES 1
# else
# define SUPPORTS_AES 0
# endif
namespace i2p
namespace i2p
{
{
namespace crypto
namespace crypto
@ -361,7 +367,7 @@ namespace crypto
BIGNUM * b1 = BN_CTX_get ( ctx ) ;
BIGNUM * b1 = BN_CTX_get ( ctx ) ;
BIGNUM * b = BN_CTX_get ( ctx ) ;
BIGNUM * b = BN_CTX_get ( ctx ) ;
// select random k
// select random k
# if defined(__x86_64__)
# if (defined(_M_AMD64) || defined(__x86_64__) )
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
@ -428,7 +434,7 @@ namespace crypto
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(_M_AMD64) || defined(__x86_64__)) || (defined(_M_IX86 ) || 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
@ -555,7 +561,7 @@ namespace crypto
}
}
// AES
// AES
# if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
# if SUPPORTS_AES
# 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 " \
@ -580,7 +586,7 @@ namespace crypto
" movaps %%xmm3, " # round1 " (%[sched]) \n "
" movaps %%xmm3, " # round1 " (%[sched]) \n "
# endif
# endif
# if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
# if SUPPORTS_AES
void ECBCryptoAESNI : : ExpandKey ( const AESKey & key )
void ECBCryptoAESNI : : ExpandKey ( const AESKey & key )
{
{
__asm__
__asm__
@ -621,7 +627,7 @@ namespace crypto
# endif
# endif
# if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
# if SUPPORTS_AES
# define EncryptAES256(sched) \
# define EncryptAES256(sched) \
" pxor (%[ " # sched " ]), %%xmm0 \n " \
" pxor (%[ " # sched " ]), %%xmm0 \n " \
" aesenc 16(%[ " # sched " ]), %%xmm0 \n " \
" aesenc 16(%[ " # sched " ]), %%xmm0 \n " \
@ -642,7 +648,7 @@ namespace crypto
void ECBEncryption : : Encrypt ( const ChipherBlock * in , ChipherBlock * out )
void ECBEncryption : : Encrypt ( const ChipherBlock * in , ChipherBlock * out )
{
{
# if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
# if SUPPORTS_AES
if ( i2p : : cpu : : aesni )
if ( i2p : : cpu : : aesni )
{
{
__asm__
__asm__
@ -650,7 +656,9 @@ namespace crypto
" 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 "
) ;
) ;
}
}
else
else
@ -660,7 +668,7 @@ namespace crypto
}
}
}
}
# if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
# if SUPPORTS_AES
# define DecryptAES256(sched) \
# define DecryptAES256(sched) \
" pxor 224(%[ " # sched " ]), %%xmm0 \n " \
" pxor 224(%[ " # sched " ]), %%xmm0 \n " \
" aesdec 208(%[ " # sched " ]), %%xmm0 \n " \
" aesdec 208(%[ " # sched " ]), %%xmm0 \n " \
@ -681,7 +689,7 @@ namespace crypto
void ECBDecryption : : Decrypt ( const ChipherBlock * in , ChipherBlock * out )
void ECBDecryption : : Decrypt ( const ChipherBlock * in , ChipherBlock * out )
{
{
# if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
# if SUPPORTS_AES
if ( i2p : : cpu : : aesni )
if ( i2p : : cpu : : aesni )
{
{
__asm__
__asm__
@ -689,7 +697,9 @@ namespace crypto
" 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 "
) ;
) ;
}
}
else
else
@ -699,7 +709,7 @@ namespace crypto
}
}
}
}
# if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
# if SUPPORTS_AES
# define CallAESIMC(offset) \
# define CallAESIMC(offset) \
" movaps " # offset " (%[shed]), %%xmm0 \n " \
" movaps " # offset " (%[shed]), %%xmm0 \n " \
" aesimc %%xmm0, %%xmm0 \n " \
" aesimc %%xmm0, %%xmm0 \n " \
@ -708,7 +718,7 @@ namespace crypto
void ECBEncryption : : SetKey ( const AESKey & key )
void ECBEncryption : : SetKey ( const AESKey & key )
{
{
# if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
# if SUPPORTS_AES
if ( i2p : : cpu : : aesni )
if ( i2p : : cpu : : aesni )
{
{
ExpandKey ( key ) ;
ExpandKey ( key ) ;
@ -722,7 +732,7 @@ namespace crypto
void ECBDecryption : : SetKey ( const AESKey & key )
void ECBDecryption : : SetKey ( const AESKey & key )
{
{
# if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
# if SUPPORTS_AES
if ( i2p : : cpu : : aesni )
if ( i2p : : cpu : : aesni )
{
{
ExpandKey ( key ) ; // expand encryption key first
ExpandKey ( key ) ; // expand encryption key first
@ -742,7 +752,9 @@ namespace crypto
CallAESIMC ( 176 )
CallAESIMC ( 176 )
CallAESIMC ( 192 )
CallAESIMC ( 192 )
CallAESIMC ( 208 )
CallAESIMC ( 208 )
: : [ shed ] " r " ( GetKeySchedule ( ) ) : " %xmm0 " , " memory "
:
: [ shed ] " r " ( GetKeySchedule ( ) )
: " %xmm0 " , " memory "
) ;
) ;
}
}
else
else
@ -754,7 +766,7 @@ namespace crypto
void CBCEncryption : : Encrypt ( int numBlocks , const ChipherBlock * in , ChipherBlock * out )
void CBCEncryption : : Encrypt ( int numBlocks , const ChipherBlock * in , ChipherBlock * out )
{
{
# if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
# if SUPPORTS_AES
if ( i2p : : cpu : : aesni )
if ( i2p : : cpu : : aesni )
{
{
__asm__
__asm__
@ -799,7 +811,7 @@ namespace crypto
void CBCEncryption : : Encrypt ( const uint8_t * in , uint8_t * out )
void CBCEncryption : : Encrypt ( const uint8_t * in , uint8_t * out )
{
{
# if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
# if SUPPORTS_AES
if ( i2p : : cpu : : aesni )
if ( i2p : : cpu : : aesni )
{
{
__asm__
__asm__
@ -823,7 +835,7 @@ namespace crypto
void CBCDecryption : : Decrypt ( int numBlocks , const ChipherBlock * in , ChipherBlock * out )
void CBCDecryption : : Decrypt ( int numBlocks , const ChipherBlock * in , ChipherBlock * out )
{
{
# if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
# if SUPPORTS_AES
if ( i2p : : cpu : : aesni )
if ( i2p : : cpu : : aesni )
{
{
__asm__
__asm__
@ -869,7 +881,7 @@ namespace crypto
void CBCDecryption : : Decrypt ( const uint8_t * in , uint8_t * out )
void CBCDecryption : : Decrypt ( const uint8_t * in , uint8_t * out )
{
{
# if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
# if SUPPORTS_AES
if ( i2p : : cpu : : aesni )
if ( i2p : : cpu : : aesni )
{
{
__asm__
__asm__
@ -893,7 +905,7 @@ namespace crypto
void TunnelEncryption : : Encrypt ( const uint8_t * in , uint8_t * out )
void TunnelEncryption : : Encrypt ( const uint8_t * in , uint8_t * out )
{
{
# if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
# if SUPPORTS_AES
if ( i2p : : cpu : : aesni )
if ( i2p : : cpu : : aesni )
{
{
__asm__
__asm__
@ -934,7 +946,7 @@ namespace crypto
void TunnelDecryption : : Decrypt ( const uint8_t * in , uint8_t * out )
void TunnelDecryption : : Decrypt ( const uint8_t * in , uint8_t * out )
{
{
# if defined(__AES__) && (defined(__x86_64__) || defined(__i386__))
# if SUPPORTS_AES
if ( i2p : : cpu : : aesni )
if ( i2p : : cpu : : aesni )
{
{
__asm__
__asm__
@ -1285,9 +1297,9 @@ namespace crypto
}
}
} */
} */
void InitCrypto ( bool precomputation , bool aesni , bool avx , bool force )
void InitCrypto ( bool precomputation , bool aesni , bool force )
{
{
i2p : : cpu : : Detect ( aesni , avx , force ) ;
i2p : : cpu : : Detect ( aesni , force ) ;
# if LEGACY_OPENSSL
# if LEGACY_OPENSSL
SSL_library_init ( ) ;
SSL_library_init ( ) ;
# endif
# endif
@ -1297,7 +1309,7 @@ namespace crypto
CRYPTO_set_locking_callback ( OpensslLockingCallback ) ; */
CRYPTO_set_locking_callback ( OpensslLockingCallback ) ; */
if ( precomputation )
if ( precomputation )
{
{
# if defined(__x86_64__)
# if (defined(_M_AMD64) || 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
@ -1312,7 +1324,7 @@ namespace crypto
if ( g_ElggTable )
if ( g_ElggTable )
{
{
DestroyElggTable ( g_ElggTable ,
DestroyElggTable ( g_ElggTable ,
# if defined(__x86_64__)
# if (defined(_M_AMD64) || 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