1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2024-12-26 01:27:28 +00:00

(trunk libT) #2658 "encryption improvements" - patch by sadface to make DH handshake ~2x faster. yay!

This commit is contained in:
Charles Kerr 2009-12-12 03:51:36 +00:00
parent 5df69c898c
commit 196a7ccbb9

View file

@ -69,6 +69,9 @@ tr_sha1( uint8_t * setme,
#define PRIME_LEN 96 #define PRIME_LEN 96
#define DH_PRIVKEY_LEN_MIN 16
#define DH_PRIVKEY_LEN 20
static const uint8_t dh_P[PRIME_LEN] = static const uint8_t dh_P[PRIME_LEN] =
{ {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
@ -93,6 +96,7 @@ struct tr_crypto
tr_bool mySecretIsSet; tr_bool mySecretIsSet;
uint8_t myPublicKey[KEY_LEN]; uint8_t myPublicKey[KEY_LEN];
uint8_t mySecret[KEY_LEN]; uint8_t mySecret[KEY_LEN];
DH * dh;
}; };
/** /**
@ -108,14 +112,13 @@ struct tr_crypto
} \ } \
} while( 0 ) } while( 0 )
static DH* static void
getSharedDH( void ) ensureKeyExists( tr_crypto * crypto)
{ {
static DH * dh = NULL; if( crypto->dh == NULL )
if( dh == NULL )
{ {
dh = DH_new( ); int len, offset;
DH * dh = DH_new( );
dh->p = BN_bin2bn( dh_P, sizeof( dh_P ), NULL ); dh->p = BN_bin2bn( dh_P, sizeof( dh_P ), NULL );
if( dh->p == NULL ) if( dh->p == NULL )
@ -125,33 +128,39 @@ getSharedDH( void )
if( dh->g == NULL ) if( dh->g == NULL )
logErrorFromSSL( ); logErrorFromSSL( );
/* private DH value: strong random BN of DH_PRIVKEY_LEN*8 bits */
dh->priv_key = BN_new( );
do {
if( BN_rand( dh->priv_key, DH_PRIVKEY_LEN * 8, -1, 0 ) != 1 )
logErrorFromSSL( );
} while ( BN_num_bits( dh->priv_key ) < DH_PRIVKEY_LEN_MIN * 8 );
if( !DH_generate_key( dh ) ) if( !DH_generate_key( dh ) )
logErrorFromSSL( ); logErrorFromSSL( );
}
return dh; /* DH can generate key sizes that are smaller than the size of
P with exponentially decreasing probability, in which case
the msb's of myPublicKey need to be zeroed appropriately. */
len = BN_num_bytes( dh->pub_key );
offset = KEY_LEN - len;
assert( len <= KEY_LEN );
memset( crypto->myPublicKey, 0, offset );
BN_bn2bin( dh->pub_key, crypto->myPublicKey + offset );
crypto->dh = dh;
}
} }
tr_crypto * tr_crypto *
tr_cryptoNew( const uint8_t * torrentHash, tr_cryptoNew( const uint8_t * torrentHash,
int isIncoming ) int isIncoming )
{ {
int len, offset;
tr_crypto * crypto; tr_crypto * crypto;
DH * dh = getSharedDH( );
crypto = tr_new0( tr_crypto, 1 ); crypto = tr_new0( tr_crypto, 1 );
crypto->isIncoming = isIncoming ? 1 : 0; crypto->isIncoming = isIncoming ? 1 : 0;
tr_cryptoSetTorrentHash( crypto, torrentHash ); tr_cryptoSetTorrentHash( crypto, torrentHash );
crypto->dh = NULL;
/* DH can generate key sizes that are smaller than the size of
P with exponentially decreasing probability, in which case
the msb's of myPublicKey need to be zeroed appropriately. */
len = DH_size( dh );
offset = KEY_LEN - len;
assert( len <= KEY_LEN );
memset( crypto->myPublicKey, 0, offset );
BN_bn2bin( dh->pub_key, crypto->myPublicKey + offset );
return crypto; return crypto;
} }
@ -159,6 +168,8 @@ tr_cryptoNew( const uint8_t * torrentHash,
void void
tr_cryptoFree( tr_crypto * crypto ) tr_cryptoFree( tr_crypto * crypto )
{ {
if( crypto->dh != NULL )
DH_free( crypto->dh );
tr_free( crypto ); tr_free( crypto );
} }
@ -173,7 +184,10 @@ tr_cryptoComputeSecret( tr_crypto * crypto,
int len; int len;
uint8_t secret[KEY_LEN]; uint8_t secret[KEY_LEN];
BIGNUM * bn = BN_bin2bn( peerPublicKey, KEY_LEN, NULL ); BIGNUM * bn = BN_bin2bn( peerPublicKey, KEY_LEN, NULL );
DH * dh = getSharedDH( ); DH * dh;
ensureKeyExists( crypto );
dh = crypto->dh;
assert( DH_size( dh ) == KEY_LEN ); assert( DH_size( dh ) == KEY_LEN );
@ -197,6 +211,7 @@ const uint8_t*
tr_cryptoGetMyPublicKey( const tr_crypto * crypto, tr_cryptoGetMyPublicKey( const tr_crypto * crypto,
int * setme_len ) int * setme_len )
{ {
ensureKeyExists( (tr_crypto *) crypto );
*setme_len = KEY_LEN; *setme_len = KEY_LEN;
return crypto->myPublicKey; return crypto->myPublicKey;
} }