From 7aa08bfa6efdc7f3f0f082e6361705749b2b2a03 Mon Sep 17 00:00:00 2001 From: Rudolf Polzer Date: Tue, 25 Oct 2011 14:47:12 +0200 Subject: [PATCH] mutexify the internal bignum functions --- d0_bignum-gmp.c | 23 ++++++++++++++++++-- d0_bignum-openssl.c | 52 ++++++++++++++++++++++++++++++++++++++++----- d0_bignum-tommath.c | 36 ++++++++++++++++++++++++++++++- 3 files changed, 103 insertions(+), 8 deletions(-) diff --git a/d0_bignum-gmp.c b/d0_bignum-gmp.c index 5353704..153055e 100644 --- a/d0_bignum-gmp.c +++ b/d0_bignum-gmp.c @@ -56,8 +56,9 @@ struct d0_bignum_s mpz_t z; }; -static gmp_randstate_t RANDSTATE; // FIXME make threadsafe -static d0_bignum_t temp; // FIXME make threadsafe +static gmp_randstate_t RANDSTATE; +static d0_bignum_t temp; +static void *tempmutex = NULL; // hold this mutex when using RANDSTATE or temp #include #include @@ -67,6 +68,10 @@ D0_WARN_UNUSED_RESULT D0_BOOL d0_bignum_INITIALIZE(void) FILE *f; D0_BOOL ret = 1; unsigned char buf[256]; + + tempmutex = d0_createmutex(); + d0_lockmutex(tempmutex); + d0_bignum_init(&temp); gmp_randinit_mt(RANDSTATE); gmp_randseed_ui(RANDSTATE, time(NULL)); @@ -122,13 +127,21 @@ D0_WARN_UNUSED_RESULT D0_BOOL d0_bignum_INITIALIZE(void) mpz_import(temp.z, sizeof(buf), 1, 1, 0, 0, buf); gmp_randseed(RANDSTATE, temp.z); + d0_unlockmutex(tempmutex); + return ret; } void d0_bignum_SHUTDOWN(void) { + d0_lockmutex(tempmutex); + d0_bignum_clear(&temp); gmp_randclear(RANDSTATE); + + d0_unlockmutex(tempmutex); + d0_destroymutex(tempmutex); + tempmutex = NULL; } D0_BOOL d0_iobuf_write_bignum(d0_iobuf_t *buf, const d0_bignum_t *bignum) @@ -252,8 +265,10 @@ int d0_bignum_cmp(const d0_bignum_t *a, const d0_bignum_t *b) d0_bignum_t *d0_bignum_rand_range(d0_bignum_t *r, const d0_bignum_t *min, const d0_bignum_t *max) { if(!r) r = d0_bignum_new(); if(!r) return NULL; + d0_lockmutex(tempmutex); mpz_sub(temp.z, max->z, min->z); mpz_urandomm(r->z, RANDSTATE, temp.z); + d0_unlockmutex(tempmutex); mpz_add(r->z, r->z, min->z); return r; } @@ -261,14 +276,18 @@ d0_bignum_t *d0_bignum_rand_range(d0_bignum_t *r, const d0_bignum_t *min, const d0_bignum_t *d0_bignum_rand_bit_atmost(d0_bignum_t *r, size_t n) { if(!r) r = d0_bignum_new(); if(!r) return NULL; + d0_lockmutex(tempmutex); mpz_urandomb(r->z, RANDSTATE, n); + d0_unlockmutex(tempmutex); return r; } d0_bignum_t *d0_bignum_rand_bit_exact(d0_bignum_t *r, size_t n) { if(!r) r = d0_bignum_new(); if(!r) return NULL; + d0_lockmutex(tempmutex); mpz_urandomb(r->z, RANDSTATE, n-1); + d0_unlockmutex(tempmutex); mpz_setbit(r->z, n-1); return r; } diff --git a/d0_bignum-openssl.c b/d0_bignum-openssl.c index c5b2b65..da95c0b 100644 --- a/d0_bignum-openssl.c +++ b/d0_bignum-openssl.c @@ -57,24 +57,40 @@ struct d0_bignum_s BIGNUM z; }; -static d0_bignum_t temp; // FIXME make threadsafe -static BN_CTX *ctx; // FIXME make threadsafe +// FIXME implement http://www.openssl.org/docs/crypto/threads.html + +static d0_bignum_t temp; +static BN_CTX *ctx; +static void *tempmutex = NULL; // hold this mutex when using ctx or temp #include #include D0_WARN_UNUSED_RESULT D0_BOOL d0_bignum_INITIALIZE(void) { + tempmutex = d0_createmutex(); + d0_lockmutex(tempmutex); + ctx = BN_CTX_new(); d0_bignum_init(&temp); + + d0_unlockmutex(tempmutex); + return 1; + // FIXME initialize the RNG on Windows on UNIX it is done right already } void d0_bignum_SHUTDOWN(void) { + d0_lockmutex(tempmutex); + d0_bignum_clear(&temp); BN_CTX_free(ctx); ctx = NULL; + + d0_unlockmutex(tempmutex); + d0_destroymutex(tempmutex); + tempmutex = NULL; } D0_BOOL d0_iobuf_write_bignum(d0_iobuf_t *buf, const d0_bignum_t *bignum) @@ -174,8 +190,10 @@ int d0_bignum_cmp(const d0_bignum_t *a, const d0_bignum_t *b) d0_bignum_t *d0_bignum_rand_range(d0_bignum_t *r, const d0_bignum_t *min, const d0_bignum_t *max) { if(!r) r = d0_bignum_new(); if(!r) return NULL; + d0_lockmutex(tempmutex); BN_sub(&temp.z, &max->z, &min->z); BN_rand_range(&r->z, &temp.z); + d0_unlockmutex(tempmutex); BN_add(&r->z, &r->z, &min->z); return r; } @@ -262,7 +280,9 @@ d0_bignum_t *d0_bignum_sub(d0_bignum_t *r, const d0_bignum_t *a, const d0_bignum d0_bignum_t *d0_bignum_mul(d0_bignum_t *r, const d0_bignum_t *a, const d0_bignum_t *b) { if(!r) r = d0_bignum_new(); if(!r) return NULL; + d0_lockmutex(tempmutex); BN_mul(&r->z, &a->z, &b->z, ctx); + d0_unlockmutex(tempmutex); return r; } @@ -270,6 +290,7 @@ d0_bignum_t *d0_bignum_divmod(d0_bignum_t *q, d0_bignum_t *m, const d0_bignum_t { if(!q && !m) m = d0_bignum_new(); + d0_lockmutex(tempmutex); if(q) { if(m) @@ -280,6 +301,7 @@ d0_bignum_t *d0_bignum_divmod(d0_bignum_t *q, d0_bignum_t *m, const d0_bignum_t } else BN_nnmod(&m->z, &a->z, &b->z, ctx); + d0_unlockmutex(tempmutex); if(m) return m; else @@ -289,43 +311,59 @@ d0_bignum_t *d0_bignum_divmod(d0_bignum_t *q, d0_bignum_t *m, const d0_bignum_t d0_bignum_t *d0_bignum_mod_add(d0_bignum_t *r, const d0_bignum_t *a, const d0_bignum_t *b, const d0_bignum_t *m) { if(!r) r = d0_bignum_new(); if(!r) return NULL; + d0_lockmutex(tempmutex); BN_mod_add(&r->z, &a->z, &b->z, &m->z, ctx); + d0_unlockmutex(tempmutex); return r; } d0_bignum_t *d0_bignum_mod_sub(d0_bignum_t *r, const d0_bignum_t *a, const d0_bignum_t *b, const d0_bignum_t *m) { if(!r) r = d0_bignum_new(); if(!r) return NULL; + d0_lockmutex(tempmutex); BN_mod_sub(&r->z, &a->z, &b->z, &m->z, ctx); + d0_unlockmutex(tempmutex); return r; } d0_bignum_t *d0_bignum_mod_mul(d0_bignum_t *r, const d0_bignum_t *a, const d0_bignum_t *b, const d0_bignum_t *m) { if(!r) r = d0_bignum_new(); if(!r) return NULL; + d0_lockmutex(tempmutex); BN_mod_mul(&r->z, &a->z, &b->z, &m->z, ctx); + d0_unlockmutex(tempmutex); return r; } d0_bignum_t *d0_bignum_mod_pow(d0_bignum_t *r, const d0_bignum_t *a, const d0_bignum_t *b, const d0_bignum_t *m) { if(!r) r = d0_bignum_new(); if(!r) return NULL; + d0_lockmutex(tempmutex); BN_mod_exp(&r->z, &a->z, &b->z, &m->z, ctx); + d0_unlockmutex(tempmutex); return r; } D0_BOOL d0_bignum_mod_inv(d0_bignum_t *r, const d0_bignum_t *a, const d0_bignum_t *m) { // here, r MUST be set, as otherwise we cannot return error state! - return !!BN_mod_inverse(&r->z, &a->z, &m->z, ctx); + int ret; + d0_lockmutex(tempmutex); + ret = !!BN_mod_inverse(&r->z, &a->z, &m->z, ctx); + d0_unlockmutex(tempmutex); + return ret; } int d0_bignum_isprime(const d0_bignum_t *r, int param) { + int ret; + d0_lockmutex(tempmutex); if(param <= 0) - return BN_is_prime_fasttest(&r->z, 1, NULL, ctx, NULL, 1); + ret = BN_is_prime_fasttest(&r->z, 1, NULL, ctx, NULL, 1); else - return BN_is_prime(&r->z, param, NULL, ctx, NULL); + ret = BN_is_prime(&r->z, param, NULL, ctx, NULL); + d0_unlockmutex(tempmutex); + return ret; } d0_bignum_t *d0_bignum_gcd(d0_bignum_t *r, d0_bignum_t *s, d0_bignum_t *t, const d0_bignum_t *a, const d0_bignum_t *b) @@ -336,7 +374,11 @@ d0_bignum_t *d0_bignum_gcd(d0_bignum_t *r, d0_bignum_t *s, d0_bignum_t *t, const else if(t) assert(!"Extended gcd not implemented"); else + { + d0_lockmutex(tempmutex); BN_gcd(&r->z, &a->z, &b->z, ctx); + d0_unlockmutex(tempmutex); + } return r; } diff --git a/d0_bignum-tommath.c b/d0_bignum-tommath.c index b2a3913..d78329f 100644 --- a/d0_bignum-tommath.c +++ b/d0_bignum-tommath.c @@ -50,7 +50,8 @@ struct d0_bignum_s mp_int z; }; -static d0_bignum_t temp; // FIXME make threadsafe +static d0_bignum_t temp; +static void *tempmutex = NULL; // hold this mutex when using temp #include @@ -75,6 +76,10 @@ D0_WARN_UNUSED_RESULT D0_BOOL d0_bignum_INITIALIZE(void) { D0_BOOL ret = 1; unsigned char buf[256]; + + tempmutex = d0_createmutex(); + d0_lockmutex(tempmutex); + d0_bignum_init(&temp); #ifdef WIN32 { @@ -106,11 +111,15 @@ D0_WARN_UNUSED_RESULT D0_BOOL d0_bignum_INITIALIZE(void) } #endif + d0_unlockmutex(tempmutex); + return ret; } void d0_bignum_SHUTDOWN(void) { + d0_lockmutex(tempmutex); + d0_bignum_clear(&temp); #ifdef WIN32 if(hCryptProv) @@ -119,6 +128,10 @@ void d0_bignum_SHUTDOWN(void) hCryptProv = NULL; } #endif + + d0_unlockmutex(tempmutex); + d0_destroymutex(tempmutex); + tempmutex = NULL; } D0_BOOL d0_iobuf_write_bignum(d0_iobuf_t *buf, const d0_bignum_t *bignum) @@ -260,31 +273,52 @@ static d0_bignum_t *d0_bignum_rand_0_to_limit(d0_bignum_t *r, const d0_bignum_t d0_bignum_t *d0_bignum_rand_range(d0_bignum_t *r, const d0_bignum_t *min, const d0_bignum_t *max) { + d0_lockmutex(tempmutex); mp_sub((mp_int *) &max->z, (mp_int *) &min->z, &temp.z); r = d0_bignum_rand_0_to_limit(r, &temp); + d0_unlockmutex(tempmutex); mp_add((mp_int *) &r->z, (mp_int *) &min->z, &r->z); return r; } d0_bignum_t *d0_bignum_rand_bit_atmost(d0_bignum_t *r, size_t n) { + d0_lockmutex(tempmutex); if(!d0_bignum_one(&temp)) + { + d0_unlockmutex(tempmutex); return NULL; + } if(!d0_bignum_shl(&temp, &temp, n)) + { + d0_unlockmutex(tempmutex); return NULL; + } r = d0_bignum_rand_0_to_limit(r, &temp); + d0_unlockmutex(tempmutex); return r; } d0_bignum_t *d0_bignum_rand_bit_exact(d0_bignum_t *r, size_t n) { + d0_lockmutex(tempmutex); if(!d0_bignum_one(&temp)) + { + d0_unlockmutex(tempmutex); return NULL; + } if(!d0_bignum_shl(&temp, &temp, n-1)) + { + d0_unlockmutex(tempmutex); return NULL; + } r = d0_bignum_rand_0_to_limit(r, &temp); if(!d0_bignum_add(r, r, &temp)) + { + d0_unlockmutex(tempmutex); return NULL; + } + d0_unlockmutex(tempmutex); return r; } -- 2.39.2