Hi friends,
This is my fisrt message here!
I'm making a parallel version of BN_mod_exp_mont.
However I am encountering many problems when using
pthreads.

#include <openssl/crypto.h>
#include <openssl/rsa.h>
#include <openssl/bn.h>
#include <openssl/ossl_typ.h>
#include <openssl/objects.h>
#include <openssl/err.h>

/* To use as callback in 'pthread_create()' */
void BN_mod_exp_mont_call( void * args[6] );
/* BN_mod_exp_mont Parallel version */
int BN_mod_exp_mont_t2(BIGNUM *r, const BIGNUM *a, const BIGNUM *e,
                       const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
int BN_split( const BIGNUM * e,  BIGNUM * e1, BIGNUM * e2 );

/* Lock Features */
void CRYPTO_thread_setup(void);
void CRYPTO_thread_cleanup(void);

static unsigned long pthreads_thread_id(void );
static pthread_mutex_t *lock_cs;
static long *lock_count;
static void pthreads_locking_callback(int mode,int type,char *file,int
line);

void CRYPTO_thread_setup(void) {
    int i;
    lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
    lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
    for (i=0; i<CRYPTO_num_locks(); i++) {
        lock_count[i]=0;
        pthread_mutex_init(&(lock_cs[i]),NULL);
    }

    CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
    CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);
}
void CRYPTO_thread_cleanup(void) {
    int i;
    CRYPTO_set_locking_callback(NULL);
    for (i=0; i<CRYPTO_num_locks(); i++)
        {
        pthread_mutex_destroy(&(lock_cs[i]));
        }
    OPENSSL_free(lock_cs);
    OPENSSL_free(lock_count);
}
void pthreads_locking_callback(int mode, int type, char *file, int line) {
    if (mode & CRYPTO_LOCK) {
        pthread_mutex_lock(&(lock_cs[type]));
        lock_count[type]++;
    } else
        pthread_mutex_unlock(&(lock_cs[type]));
}
unsigned long pthreads_thread_id(void) {
    unsigned long ret;
    ret=(unsigned long)pthread_self();
    return(ret);
}
int BN_split( const BIGNUM * e,  BIGNUM * e1, BIGNUM * e2 ) {
    int r = (BN_num_bits( e ) + 1) / 2;
    BN_copy( e1, e );
    BN_mask_bits( e1, r );
    BN_rshift( e2, e, r );
    return r;
}
int BN_mod_exp_mont_t2(BIGNUM *r, const BIGNUM *a, const BIGNUM *e,
                       const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) {
    BIGNUM * e1, * e2, * a1, * a2;
    BIGNUM * tmp;
    int t = 0;

    BN_CTX_start( ctx );
    e1 = BN_CTX_get( ctx );
    e2 = BN_CTX_get( ctx );
    a1 = BN_CTX_get( ctx );
    a2 = BN_CTX_get( ctx );
    tmp = BN_CTX_get( ctx );

    t = BN_split( e, e1, e2 );
    BN_lshift( tmp, BN_value_one(), t );

    void * args[6];
    pthread_t th;
    args[0] = (void *) a1;
    args[1] = (void *) a;
    args[2] = (void *) e1;
    args[3] = (void *) m;
    args[4] = (void *) ctx;
    args[5] = (void *) m_ctx;
    pthread_create( &th, NULL, (void *)BN_mod_exp_mont_call, (void *) args
);
    //BN_mod_exp_mont_call( args );
    BN_mod_exp_mont( a2, a, tmp, m, ctx, m_ctx );
    BN_mod_exp_mont( a2, a2, e2, m, ctx, m_ctx );
    pthread_join( th, NULL ); 
    BN_mod_mul( r, a1, a2, m, ctx );
    BN_CTX_end( ctx );
}
void BN_mod_exp_mont_call( void * args[6] ) {
    BN_mod_exp_mont( (BIGNUM *) args[0], (BIGNUM *)args[1], (BIGNUM
*)args[2], 
                     (BIGNUM *)args[3], (BN_CTX *) args[4], (BN_MONT_CTX
*)args[5] );
}
int TestEncrypt() {
    RSA * key;

    unsigned char ctext[256];
    unsigned char ptext[256];
    static unsigned char ptext_ex[] = "\x25\x44\x65\x66";

    key = RSA_generate_key( 512, RSA_F4, NULL, NULL );
    key->meth->bn_mod_exp = BN_mod_exp_mont_t2;

    int clen = RSA_private_encrypt( sizeof( ptext_ex ) - 1, ptext_ex, ctext,
key, RSA_PKCS1_PADDING );

    if( clen == -1 ) { fprintf( stderr, "Bad encrypt\n"); return -1; }

    int plen = RSA_public_decrypt( clen, ctext, ptext, key,
RSA_PKCS1_PADDING );

    if( plen == -1 ) { fprintf( stderr, "Bad decrypt\n"); return -1; }

    if( memcmp( ptext, ptext_ex, plen ) != 0 ) {
        fprintf( stderr,"Diffs ptext's\n");
        return -1;
    } else 
        return 0;
}
int main( int argc, char ** argv ) {
    CRYPTO_thread_setup();
        if( TestEncrypt() == 0 ){ fprintf( stdout, "Encrypt Ok!\n"); }
    CRYPTO_thread_cleanup();
    return 0;
}

Obs: 
For the test, I do 

key-> meth-> bn_mod_exp = BN_mod_exp_mont_t2;

Thus the attribute 'meth' of RSA struct can not be const.
-- 
View this message in context: 
http://www.nabble.com/Problem-with-pthread-and-OpenSSL-tp24073660p24073660.html
Sent from the OpenSSL - User mailing list archive at Nabble.com.
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to