close <div id="moderation_required">Attachments you submit will be routed for moderation. If you have an account, please <a href="/login">log in</a> first.</div>

Ticket #2658: encryption_patch.diff

File encryption_patch.diff, 3.3 KB (added by sadface, 7 years ago)
  • libtransmission/crypto.c

    old new  
    6969
    7070#define PRIME_LEN 96
    7171
     72#define DH_PRIVKEY_LEN_MIN 16
     73#define DH_PRIVKEY_LEN 20
     74
    7275static const uint8_t dh_P[PRIME_LEN] =
    7376{
    7477    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
     
    9396    tr_bool         mySecretIsSet;
    9497    uint8_t         myPublicKey[KEY_LEN];
    9598    uint8_t         mySecret[KEY_LEN];
     99    DH *            dh;
    96100};
    97101
    98102/**
     
    108112        } \
    109113    } while( 0 )
    110114
    111 static DH*
    112 getSharedDH( void )
     115static void
     116ensureKeyExists( tr_crypto * crypto)
    113117{
    114     static DH * dh = NULL;
    115 
    116     if( dh == NULL )
     118    if( crypto->dh == NULL )
    117119    {
    118         dh = DH_new( );
     120        int len, offset;
     121        DH * dh = DH_new( );
    119122
    120123        dh->p = BN_bin2bn( dh_P, sizeof( dh_P ), NULL );
    121124        if( dh->p == NULL )
     
    125128        if( dh->g == NULL )
    126129            logErrorFromSSL( );
    127130
     131        /* private DH value: strong random BN of DH_PRIVKEY_LEN*8 bits */
     132        dh->priv_key = BN_new( );
     133        do {
     134            if( BN_rand( dh->priv_key, DH_PRIVKEY_LEN * 8, -1, 0 ) != 1 )
     135                logErrorFromSSL( );
     136        } while ( BN_num_bits( dh->priv_key ) < DH_PRIVKEY_LEN_MIN * 8 );
     137
    128138        if( !DH_generate_key( dh ) )
    129139            logErrorFromSSL( );
    130     }
    131140
    132     return dh;
     141        /* DH can generate key sizes that are smaller than the size of
     142           P with exponentially decreasing probability, in which case
     143           the msb's of myPublicKey need to be zeroed appropriately. */
     144        len = BN_num_bytes( dh->pub_key );
     145        offset = KEY_LEN - len;
     146        assert( len <= KEY_LEN );
     147        memset( crypto->myPublicKey, 0, offset );
     148        BN_bn2bin( dh->pub_key, crypto->myPublicKey + offset );
     149
     150        crypto->dh = dh;
     151    }
    133152}
    134153
    135154tr_crypto *
    136155tr_cryptoNew( const uint8_t * torrentHash,
    137156              int             isIncoming )
    138157{
    139     int         len, offset;
    140158    tr_crypto * crypto;
    141     DH *        dh = getSharedDH( );
    142159
    143160    crypto = tr_new0( tr_crypto, 1 );
    144161    crypto->isIncoming = isIncoming ? 1 : 0;
    145162    tr_cryptoSetTorrentHash( crypto, torrentHash );
    146 
    147     /* DH can generate key sizes that are smaller than the size of
    148        P with exponentially decreasing probability, in which case
    149        the msb's of myPublicKey need to be zeroed appropriately. */
    150     len = DH_size( dh );
    151     offset = KEY_LEN - len;
    152     assert( len <= KEY_LEN );
    153     memset( crypto->myPublicKey, 0, offset );
    154     BN_bn2bin( dh->pub_key, crypto->myPublicKey + offset );
     163    crypto->dh = NULL;
    155164
    156165    return crypto;
    157166}
     
    159168void
    160169tr_cryptoFree( tr_crypto * crypto )
    161170{
     171    if( crypto->dh != NULL )
     172        DH_free( crypto->dh );
    162173    tr_free( crypto );
    163174}
    164175
     
    173184    int      len;
    174185    uint8_t  secret[KEY_LEN];
    175186    BIGNUM * bn = BN_bin2bn( peerPublicKey, KEY_LEN, NULL );
    176     DH *     dh = getSharedDH( );
     187    DH *     dh;
     188
     189    ensureKeyExists( crypto );
     190    dh = crypto->dh;
    177191
    178192    assert( DH_size( dh ) == KEY_LEN );
    179193
     
    197211tr_cryptoGetMyPublicKey( const tr_crypto * crypto,
    198212                         int *             setme_len )
    199213{
     214    ensureKeyExists( (tr_crypto *) crypto );
    200215    *setme_len = KEY_LEN;
    201216    return crypto->myPublicKey;
    202217}