This patch fixes the multithreading issues I was having when an RSA struct was being used by multiple threads simultaneously with blinding enabled.

It adds _r versions of the convert/invert functions to save the unblinding value, and does the update in the convert step. rsa_eay.c uses the RSA_BLINDING lock to make the convert-and-update step atomic.

The patch is for 0.9.6i.

Tom
--
Tom Wu
Chief Security Architect
Arcot Systems
(408) 969-6124
diff -r -c2 openssl-0.9.6i/crypto/bn/bn.h openssl-0.9.6i-new/crypto/bn/bn.h
*** openssl-0.9.6i/crypto/bn/bn.h       Sun Nov  3 22:25:38 2002
--- openssl-0.9.6i-new/crypto/bn/bn.h   Thu Mar 27 16:52:08 2003
***************
*** 421,425 ****
--- 421,427 ----
  int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx);
  int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *r, BN_CTX *ctx);
+ int BN_BLINDING_convert_r(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx);
  int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
+ int BN_BLINDING_invert_r(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx);
  
  void BN_set_params(int mul,int high,int low,int mont);
diff -r -c2 openssl-0.9.6i/crypto/bn/bn_blind.c openssl-0.9.6i-new/crypto/bn/bn_blind.c
*** openssl-0.9.6i/crypto/bn/bn_blind.c Thu Jun  1 15:17:44 2000
--- openssl-0.9.6i-new/crypto/bn/bn_blind.c     Thu Mar 27 16:52:35 2003
***************
*** 125,128 ****
--- 125,144 ----
        }
  
+ int BN_BLINDING_convert_r(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx)
+       {
+       int ret;
+       bn_check_top(n);
+ 
+       if ((b->A == NULL) || (b->Ai == NULL))
+               {
+               BNerr(BN_F_BN_BLINDING_CONVERT,BN_R_NOT_INITIALIZED);
+               return(0);
+               }
+       BN_copy(r,b->Ai);
+       ret = BN_mod_mul(n,n,b->A,b->mod,ctx);
+       BN_BLINDING_update(b,ctx);
+       return ret;
+       }
+ 
  int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx)
        {
***************
*** 143,144 ****
--- 159,171 ----
        }
  
+ int BN_BLINDING_invert_r(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx)
+       {
+       bn_check_top(n);
+       if ((b->A == NULL) || (b->Ai == NULL))
+               {
+               BNerr(BN_F_BN_BLINDING_INVERT,BN_R_NOT_INITIALIZED);
+               return(0);
+               }
+       return(BN_mod_mul(n,n,r,b->mod,ctx));
+       }
+ 
diff -r -c2 openssl-0.9.6i/crypto/rsa/rsa_eay.c openssl-0.9.6i-new/crypto/rsa/rsa_eay.c
*** openssl-0.9.6i/crypto/rsa/rsa_eay.c Thu Nov 28 00:06:23 2002
--- openssl-0.9.6i-new/crypto/rsa/rsa_eay.c     Thu Mar 27 16:57:59 2003
***************
*** 196,199 ****
--- 196,200 ----
        {
        BIGNUM f,ret;
+       BIGNUM br;
        int i,j,k,num=0,r= -1;
        unsigned char *buf=NULL;
***************
*** 202,205 ****
--- 203,207 ----
        BN_init(&f);
        BN_init(&ret);
+       BN_init(&br);
  
        if ((ctx=BN_CTX_new()) == NULL) goto err;
***************
*** 237,242 ****
        if ((rsa->flags & RSA_FLAG_BLINDING) && (rsa->blinding == NULL))
                RSA_blinding_on(rsa,ctx);
!       if (rsa->flags & RSA_FLAG_BLINDING)
!               if (!BN_BLINDING_convert(&f,rsa->blinding,ctx)) goto err;
  
        if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
--- 239,248 ----
        if ((rsa->flags & RSA_FLAG_BLINDING) && (rsa->blinding == NULL))
                RSA_blinding_on(rsa,ctx);
!       if (rsa->flags & RSA_FLAG_BLINDING) {
!               CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING);
!               j = BN_BLINDING_convert_r(&f,&br,rsa->blinding,ctx);
!               CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING);
!               if (!j) goto err;
!       }
  
        if ( (rsa->flags & RSA_FLAG_EXT_PKEY) ||
***************
*** 253,257 ****
  
        if (rsa->flags & RSA_FLAG_BLINDING)
!               if (!BN_BLINDING_invert(&ret,rsa->blinding,ctx)) goto err;
  
        /* put in leading 0 bytes if the number is less than the
--- 259,263 ----
  
        if (rsa->flags & RSA_FLAG_BLINDING)
!               if (!BN_BLINDING_invert_r(&ret,&br,rsa->blinding,ctx)) goto err;
  
        /* put in leading 0 bytes if the number is less than the
***************
*** 267,270 ****
--- 273,277 ----
        BN_clear_free(&ret);
        BN_clear_free(&f);
+       BN_clear_free(&br);
        if (buf != NULL)
                {
***************
*** 279,282 ****
--- 286,290 ----
        {
        BIGNUM f,ret;
+       BIGNUM br;
        int j,num=0,r= -1;
        unsigned char *p;
***************
*** 286,289 ****
--- 294,298 ----
        BN_init(&f);
        BN_init(&ret);
+       BN_init(&br);
        ctx=BN_CTX_new();
        if (ctx == NULL) goto err;
***************
*** 316,321 ****
        if ((rsa->flags & RSA_FLAG_BLINDING) && (rsa->blinding == NULL))
                RSA_blinding_on(rsa,ctx);
!       if (rsa->flags & RSA_FLAG_BLINDING)
!               if (!BN_BLINDING_convert(&f,rsa->blinding,ctx)) goto err;
  
        /* do the decrypt */
--- 325,334 ----
        if ((rsa->flags & RSA_FLAG_BLINDING) && (rsa->blinding == NULL))
                RSA_blinding_on(rsa,ctx);
!       if (rsa->flags & RSA_FLAG_BLINDING) {
!               CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING);
!               j = BN_BLINDING_convert_r(&f,&br,rsa->blinding,ctx);
!               CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING);
!               if (!j) goto err;
!       }
  
        /* do the decrypt */
***************
*** 334,338 ****
  
        if (rsa->flags & RSA_FLAG_BLINDING)
!               if (!BN_BLINDING_invert(&ret,rsa->blinding,ctx)) goto err;
  
        p=buf;
--- 347,351 ----
  
        if (rsa->flags & RSA_FLAG_BLINDING)
!               if (!BN_BLINDING_invert_r(&ret,&br,rsa->blinding,ctx)) goto err;
  
        p=buf;
***************
*** 366,369 ****
--- 379,383 ----
        BN_clear_free(&f);
        BN_clear_free(&ret);
+       BN_clear_free(&br);
        if (buf != NULL)
                {
diff -r -c2 openssl-0.9.6i/include/openssl/bn.h openssl-0.9.6i-new/include/openssl/bn.h
*** openssl-0.9.6i/include/openssl/bn.h Sun Nov  3 22:25:38 2002
--- openssl-0.9.6i-new/include/openssl/bn.h     Thu Mar 27 16:52:08 2003
***************
*** 421,425 ****
--- 421,427 ----
  int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx);
  int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *r, BN_CTX *ctx);
+ int BN_BLINDING_convert_r(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx);
  int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
+ int BN_BLINDING_invert_r(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx);
  
  void BN_set_params(int mul,int high,int low,int mont);

Reply via email to