Thread-safety fixes
authorBodo Möller <bodo@openssl.org>
Wed, 14 Jun 2006 08:55:23 +0000 (08:55 +0000)
committerBodo Möller <bodo@openssl.org>
Wed, 14 Jun 2006 08:55:23 +0000 (08:55 +0000)
CHANGES
LICENSE
crypto/bn/bn_mont.c
crypto/err/err.c
crypto/rsa/rsa_eay.c
ssl/ssl_cert.c
ssl/ssl_ciph.c

diff --git a/CHANGES b/CHANGES
index 33c9186..037c916 100644 (file)
--- a/CHANGES
+++ b/CHANGES
 
  Changes between 0.9.8b and 0.9.8c  [xx XXX xxxx]
 
+  *) Fix RSA blinding Heisenbug (problems sometimes occured on
+     dual-core machines) and other potential thread-safety issues.
+     [Bodo Moeller]
+
   *) Add the symmetric cipher Camellia (128-bit, 192-bit, 256-bit key
      versions), which is now available for royalty-free use
      (see http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html).
 
  Changes between 0.9.7h and 0.9.8  [05 Jul 2005]
 
+  [NB: OpenSSL 0.9.7i and later 0.9.7 patch levels were released after
+  OpenSSL 0.9.8.]
+
   *) Add libcrypto.pc and libssl.pc for those who feel they need them.
      [Richard Levitte]
 
      differing sizes.
      [Richard Levitte]
 
+ Changes between 0.9.7j and 0.9.7k  [xx XXX xxxx]
+
+  *) Fix RSA blinding Heisenbug (problems sometimes occured on
+     dual-core machines) and other potential thread-safety issues.
+     [Bodo Moeller]
+
+ Changes between 0.9.7i and 0.9.7j  [04 May 2006]
+
+  *) Adapt fipsld and the build system to link against the validated FIPS
+     module in FIPS mode.
+     [Steve Henson]
+
+  *) Fixes for VC++ 2005 build under Windows.
+     [Steve Henson]
+
+  *) Add new Windows build target VC-32-GMAKE for VC++. This uses GNU make 
+     from a Windows bash shell such as MSYS. It is autodetected from the
+     "config" script when run from a VC++ environment. Modify standard VC++
+     build to use fipscanister.o from the GNU make build. 
+     [Steve Henson]
+
  Changes between 0.9.7h and 0.9.7i  [14 Oct 2005]
 
   *) Wrapped the definition of EVP_MAX_MD_SIZE in a #ifdef OPENSSL_FIPS.
diff --git a/LICENSE b/LICENSE
index e6afecc..c21f132 100644 (file)
--- a/LICENSE
+++ b/LICENSE
@@ -12,7 +12,7 @@
   ---------------
 
 /* ====================================================================
- * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
index c2cfecf..b532305 100644 (file)
  * copied and put under another distribution licence
  * [including the GNU Public Licence.]
  */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
 
 /*
  * Details about Montgomery multiplication algorithms can be found at
@@ -427,18 +480,30 @@ 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)
        {
-       if (*pmont)
-               return *pmont;
-       CRYPTO_w_lock(lock);
+       int got_write_lock = 0;
+
+       CRYPTO_r_lock(lock);
        if (!*pmont)
                {
-               BN_MONT_CTX *mtmp;
-               mtmp = BN_MONT_CTX_new();
-               if (mtmp && !BN_MONT_CTX_set(mtmp, mod, ctx))
-                       BN_MONT_CTX_free(mtmp);
-               else
-                       *pmont = mtmp;
+               CRYPTO_r_unlock(lock);
+               CRYPTO_w_lock(lock);
+               got_write_lock = 1;
+
+               if (!*pmont)
+                       {
+                       BN_MONT_CTX *mtmp;
+                       mtmp = BN_MONT_CTX_new();
+                       if (mtmp && !BN_MONT_CTX_set(mtmp, mod, ctx))
+                               BN_MONT_CTX_free(mtmp);
+                       else
+                               *pmont = mtmp;
+                       }
                }
-       CRYPTO_w_unlock(lock);
+       
+       if (got_write_lock)
+               CRYPTO_w_unlock(lock);
+       else
+               CRYPTO_r_unlock(lock);
+               
        return *pmont;
        }
index 8474132..3367a75 100644 (file)
@@ -550,9 +550,20 @@ static void build_SYS_str_reasons(void)
        int i;
        static int init = 1;
 
-       if (!init) return;
-
+       CRYPTO_r_lock(CRYPTO_LOCK_ERR);
+       if (!init)
+               {
+               CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
+               return;
+               }
+       
+       CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
        CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+       if (!init)
+               {
+               CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+               return;
+               }
 
        for (i = 1; i <= NUM_SYS_STR_REASONS; i++)
                {
index 56da944..69cabd2 100644 (file)
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -238,40 +238,63 @@ err:
        return(r);
        }
 
-static BN_BLINDING *rsa_get_blinding(RSA *rsa, BIGNUM **r, int *local, BN_CTX *ctx)
+static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx)
 {
        BN_BLINDING *ret;
+       int got_write_lock = 0;
+
+       CRYPTO_r_lock(CRYPTO_LOCK_RSA);
 
        if (rsa->blinding == NULL)
                {
+               CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
+               CRYPTO_w_lock(CRYPTO_LOCK_RSA);
+               got_write_lock = 1;
+
                if (rsa->blinding == NULL)
-                       {
-                       CRYPTO_w_lock(CRYPTO_LOCK_RSA);
-                       if (rsa->blinding == NULL)
-                               rsa->blinding = RSA_setup_blinding(rsa, ctx);
-                       CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
-                       }
+                       rsa->blinding = RSA_setup_blinding(rsa, ctx);
                }
 
        ret = rsa->blinding;
        if (ret == NULL)
-               return NULL;
+               goto err;
 
-       if (BN_BLINDING_get_thread_id(ret) != CRYPTO_thread_id())
+       if (BN_BLINDING_get_thread_id(ret) == CRYPTO_thread_id())
                {
-               *local = 0;
+               /* rsa->blinding is ours! */
+
+               *local = 1;
+               }
+       else
+               {
+               /* resort to rsa->mt_blinding instead */
+
+               *local = 0; /* instructs rsa_blinding_convert(), rsa_blinding_invert()
+                            * that the BN_BLINDING is shared, meaning that accesses
+                            * require locks, and that the blinding factor must be
+                            * stored outside the BN_BLINDING
+                            */
+
                if (rsa->mt_blinding == NULL)
                        {
-                       CRYPTO_w_lock(CRYPTO_LOCK_RSA);
+                       if (!got_write_lock)
+                               {
+                               CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
+                               CRYPTO_w_lock(CRYPTO_LOCK_RSA);
+                               got_write_lock = 1;
+                               }
+                       
                        if (rsa->mt_blinding == NULL)
                                rsa->mt_blinding = RSA_setup_blinding(rsa, ctx);
-                       CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
                        }
                ret = rsa->mt_blinding;
                }
-       else
-               *local = 1;
 
+ err:
+       if (got_write_lock)
+               CRYPTO_w_unlock(CRYPTO_LOCK_RSA);
+       else
+               CRYPTO_r_unlock(CRYPTO_LOCK_RSA);
        return ret;
 }
 
@@ -358,7 +381,7 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from,
 
        if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
                {
-               blinding = rsa_get_blinding(rsa, &br, &local_blinding, ctx);
+               blinding = rsa_get_blinding(rsa, &local_blinding, ctx);
                if (blinding == NULL)
                        {
                        RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR);
@@ -479,7 +502,7 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from,
 
        if (!(rsa->flags & RSA_FLAG_NO_BLINDING))
                {
-               blinding = rsa_get_blinding(rsa, &br, &local_blinding, ctx);
+               blinding = rsa_get_blinding(rsa, &local_blinding, ctx);
                if (blinding == NULL)
                        {
                        RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR);
index 452a082..fb08009 100644 (file)
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * 3. All advertising materials mentioning features or use of this
  *    software must display the following acknowledgment:
  *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
  *
  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  *    endorse or promote products derived from this software without
  *    prior written permission. For written permission, please contact
- *    openssl-core@OpenSSL.org.
+ *    openssl-core@openssl.org.
  *
  * 5. Products derived from this software may not be called "OpenSSL"
  *    nor may "OpenSSL" appear in their names without prior written
@@ -87,7 +87,7 @@
  * 6. Redistributions of any form whatsoever must retain the following
  *    acknowledgment:
  *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
  *
  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  * OF THE POSSIBILITY OF SUCH DAMAGE.
  * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
  */
 /* ====================================================================
  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
 int SSL_get_ex_data_X509_STORE_CTX_idx(void)
        {
        static volatile int ssl_x509_store_ctx_idx= -1;
+       int got_write_lock = 0;
+
+       CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
 
        if (ssl_x509_store_ctx_idx < 0)
                {
-               /* any write lock will do; usually this branch
-                * will only be taken once anyway */
+               CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
                CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
+               got_write_lock = 1;
                
                if (ssl_x509_store_ctx_idx < 0)
                        {
                        ssl_x509_store_ctx_idx=X509_STORE_CTX_get_ex_new_index(
                                0,"SSL for verify callback",NULL,NULL,NULL);
                        }
-               
-               CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
                }
+
+       if (got_write_lock)
+               CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
+       else
+               CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
+       
        return ssl_x509_store_ctx_idx;
        }
 
index 6bf337b..5453037 100644 (file)
  * copied and put under another distribution licence
  * [including the GNU Public Licence.]
  */
+/* ====================================================================
+ * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
 /* ====================================================================
  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
  * ECC cipher suite support in OpenSSL originally developed by 
@@ -243,36 +296,46 @@ static int sk_comp_cmp(const SSL_COMP * const *a,
 
 static void load_builtin_compressions(void)
        {
-       if (ssl_comp_methods != NULL)
-               return;
+       int got_write_lock = 0;
 
-       CRYPTO_w_lock(CRYPTO_LOCK_SSL);
+       CRYPTO_r_lock(CRYPTO_LOCK_SSL);
        if (ssl_comp_methods == NULL)
                {
-               SSL_COMP *comp = NULL;
-
-               MemCheck_off();
-               ssl_comp_methods=sk_SSL_COMP_new(sk_comp_cmp);
-               if (ssl_comp_methods != NULL)
+               CRYPTO_r_unlock(CRYPTO_LOCK_SSL);
+               CRYPTO_w_lock(CRYPTO_LOCK_SSL);
+               got_write_lock = 1;
+               
+               if (ssl_comp_methods == NULL)
                        {
-                       comp=(SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP));
-                       if (comp != NULL)
+                       SSL_COMP *comp = NULL;
+
+                       MemCheck_off();
+                       ssl_comp_methods=sk_SSL_COMP_new(sk_comp_cmp);
+                       if (ssl_comp_methods != NULL)
                                {
-                               comp->method=COMP_zlib();
-                               if (comp->method
-                                       && comp->method->type == NID_undef)
-                                       OPENSSL_free(comp);
-                               else
+                               comp=(SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP));
+                               if (comp != NULL)
                                        {
-                                       comp->id=SSL_COMP_ZLIB_IDX;
-                                       comp->name=comp->method->name;
-                                       sk_SSL_COMP_push(ssl_comp_methods,comp);
+                                       comp->method=COMP_zlib();
+                                       if (comp->method
+                                               && comp->method->type == NID_undef)
+                                               OPENSSL_free(comp);
+                                       else
+                                               {
+                                               comp->id=SSL_COMP_ZLIB_IDX;
+                                               comp->name=comp->method->name;
+                                               sk_SSL_COMP_push(ssl_comp_methods,comp);
+                                               }
                                        }
                                }
+                       MemCheck_on();
                        }
-               MemCheck_on();
                }
-       CRYPTO_w_unlock(CRYPTO_LOCK_SSL);
+       
+       if (got_write_lock)
+               CRYPTO_w_unlock(CRYPTO_LOCK_SSL);
+       else
+               CRYPTO_r_unlock(CRYPTO_LOCK_SSL);
        }
 #endif