RT2163: Remove some unneeded #include's
[openssl.git] / crypto / bn / bn_mont.c
index 5bf1f0213c17ed2219d0cec85a0ce7db4a9e4b3c..e41f849479a9fe1be09f208f4f163a4af6bbea29 100644 (file)
 
 #define OPENSSL_FIPSAPI
 
-#include <stdio.h>
 #include "cryptlib.h"
 #include "bn_lcl.h"
 
@@ -196,17 +195,14 @@ static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
        /* clear the top words of T */
 #if 1
        for (i=r->top; i<max; i++) /* memset? XXX */
-               r->d[i]=0;
+               rp[i]=0;
 #else
-       memset(&(r->d[r->top]),0,(max-r->top)*sizeof(BN_ULONG)); 
+       memset(&(rp[r->top]),0,(max-r->top)*sizeof(BN_ULONG)); 
 #endif
 
        r->top=max;
        n0=mont->n0[0];
 
-#ifdef BN_COUNT
-       fprintf(stderr,"word BN_from_montgomery_word %d * %d\n",nl,nl);
-#endif
        for (carry=0, i=0; i<nl; i++, rp++)
                {
 #ifdef __TANDEM
@@ -225,10 +221,10 @@ static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
 #else
                v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2);
 #endif
-               if ((rp[nl] = (rp[nl]+v+carry)&BN_MASK2) < v)
-                       carry = 1;
-               else
-                       carry = 0;
+               v = (v+carry+rp[nl])&BN_MASK2;
+               carry |= (v != rp[nl]);
+               carry &= (v <= rp[nl]);
+               rp[nl]=v;
                }
 
        if (bn_wexpand(ret,nl) == NULL) return(0);
@@ -480,32 +476,38 @@ BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from)
 BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
                                        const BIGNUM *mod, BN_CTX *ctx)
        {
-       int got_write_lock = 0;
        BN_MONT_CTX *ret;
 
        CRYPTO_r_lock(lock);
-       if (!*pmont)
+       ret = *pmont;
+       CRYPTO_r_unlock(lock);
+       if (ret)
+               return ret;
+
+       /* We don't want to serialise globally while doing our lazy-init math in
+        * BN_MONT_CTX_set. That punishes threads that are doing independent
+        * things. Instead, punish the case where more than one thread tries to
+        * lazy-init the same 'pmont', by having each do the lazy-init math work
+        * independently and only use the one from the thread that wins the race
+        * (the losers throw away the work they've done). */
+       ret = BN_MONT_CTX_new();
+       if (!ret)
+               return NULL;
+       if (!BN_MONT_CTX_set(ret, mod, ctx))
                {
-               CRYPTO_r_unlock(lock);
-               CRYPTO_w_lock(lock);
-               got_write_lock = 1;
+               BN_MONT_CTX_free(ret);
+               return NULL;
+               }
 
-               if (!*pmont)
-                       {
-                       ret = BN_MONT_CTX_new();
-                       if (ret && !BN_MONT_CTX_set(ret, mod, ctx))
-                               BN_MONT_CTX_free(ret);
-                       else
-                               *pmont = ret;
-                       }
+       /* The locked compare-and-set, after the local work is done. */
+       CRYPTO_w_lock(lock);
+       if (*pmont)
+               {
+               BN_MONT_CTX_free(ret);
+               ret = *pmont;
                }
-       
-       ret = *pmont;
-       
-       if (got_write_lock)
-               CRYPTO_w_unlock(lock);
        else
-               CRYPTO_r_unlock(lock);
-               
+               *pmont = ret;
+       CRYPTO_w_unlock(lock);
        return ret;
        }