Try sharing a DH so that we don't spend so many cpu cycles making new ones when we're working through the peers trying to find good ones.

This commit is contained in:
Charles Kerr 2007-10-13 23:15:43 +00:00
parent 341ebcb586
commit 4f33a8da42
2 changed files with 32 additions and 35 deletions

View File

@ -76,7 +76,6 @@ static const uint8_t dh_G[] = { 2 };
struct tr_crypto struct tr_crypto
{ {
DH * dh;
RC4_KEY dec_key; RC4_KEY dec_key;
RC4_KEY enc_key; RC4_KEY enc_key;
uint8_t torrentHash[SHA_DIGEST_LENGTH]; uint8_t torrentHash[SHA_DIGEST_LENGTH];
@ -85,55 +84,55 @@ struct tr_crypto
unsigned int mySecretIsSet : 1; unsigned int mySecretIsSet : 1;
uint8_t myPublicKey[KEY_LEN]; uint8_t myPublicKey[KEY_LEN];
uint8_t mySecret[KEY_LEN]; uint8_t mySecret[KEY_LEN];
}; };
static void
ensureKeyExists( tr_crypto * crypto )
{
if( crypto->dh == NULL )
{
int len, offset;
crypto->dh = DH_new( );
crypto->dh->p = BN_bin2bn( dh_P, sizeof(dh_P), NULL );
crypto->dh->g = BN_bin2bn( dh_G, sizeof(dh_G), NULL );
DH_generate_key( crypto->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 = DH_size( crypto->dh );
offset = KEY_LEN - len;
assert( len <= KEY_LEN );
memset( crypto->myPublicKey, 0, offset );
BN_bn2bin( crypto->dh->pub_key, crypto->myPublicKey + offset );
}
}
/** /**
*** ***
**/ **/
static DH*
getSharedDH( void )
{
static DH * dh = NULL;
if( dh == NULL )
{
dh = DH_new( );
dh->p = BN_bin2bn( dh_P, sizeof(dh_P), NULL );
dh->g = BN_bin2bn( dh_G, sizeof(dh_G), NULL );
DH_generate_key( dh );
}
return 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;
crypto->dh = NULL;
tr_cryptoSetTorrentHash( crypto, torrentHash ); tr_cryptoSetTorrentHash( crypto, torrentHash );
/* 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;
} }
void void
tr_cryptoFree( tr_crypto * crypto ) tr_cryptoFree( tr_crypto * crypto )
{ {
assert( crypto != NULL );
if( crypto->dh != NULL )
DH_free( crypto->dh );
tr_free( crypto ); tr_free( crypto );
} }
@ -148,11 +147,10 @@ tr_cryptoComputeSecret( tr_crypto * crypto,
int len, offset; int len, offset;
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( );
assert( DH_size(dh) == KEY_LEN );
ensureKeyExists( crypto ); len = DH_compute_key( secret, bn, dh );
assert( DH_size( crypto->dh ) == KEY_LEN );
len = DH_compute_key( secret, bn, crypto->dh );
assert( len <= KEY_LEN ); assert( len <= KEY_LEN );
offset = KEY_LEN - len; offset = KEY_LEN - len;
memset( crypto->mySecret, 0, offset ); memset( crypto->mySecret, 0, offset );
@ -167,7 +165,6 @@ tr_cryptoComputeSecret( tr_crypto * crypto,
const uint8_t* const uint8_t*
tr_cryptoGetMyPublicKey( const tr_crypto * crypto, int * setme_len ) tr_cryptoGetMyPublicKey( const tr_crypto * crypto, int * setme_len )
{ {
ensureKeyExists( (tr_crypto*) crypto );
*setme_len = KEY_LEN; *setme_len = KEY_LEN;
return crypto->myPublicKey; return crypto->myPublicKey;
} }

View File

@ -69,7 +69,7 @@ enum
KEEPALIVE_INTERVAL_SECS = 90, /* idle seconds before we send a keepalive */ KEEPALIVE_INTERVAL_SECS = 90, /* idle seconds before we send a keepalive */
PEX_INTERVAL = (60 * 1000), /* msec between calls to sendPex() */ PEX_INTERVAL = (60 * 1000), /* msec between calls to sendPex() */
PEER_PULSE_INTERVAL = (66), /* msec between calls to pulse() */ PEER_PULSE_INTERVAL = (20), /* msec between calls to pulse() */
RATE_PULSE_INTERVAL = (333), /* msec between calls to ratePulse() */ RATE_PULSE_INTERVAL = (333), /* msec between calls to ratePulse() */
}; };