Convert BN_MONT_CTX to new-style locking.

This introduces a per-RSA/DSA/DH lock. This is good for lock contention,
although pthread locks are depressingly bloated.

Change-Id: I07c4d1606fc35135fc141ebe6ba904a28c8f8a0c
Reviewed-on: https://boringssl-review.googlesource.com/4324
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/include/openssl/bn.h b/include/openssl/bn.h
index 838870d..917beaf 100644
--- a/include/openssl/bn.h
+++ b/include/openssl/bn.h
@@ -124,6 +124,7 @@
 #define OPENSSL_HEADER_BN_H
 
 #include <openssl/base.h>
+#include <openssl/thread.h>
 
 #include <stdio.h>  /* for FILE* */
 
@@ -711,15 +712,13 @@
 OPENSSL_EXPORT int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod,
                                    BN_CTX *ctx);
 
-/* BN_MONT_CTX_set_locked takes the lock indicated by |lock| and checks whether
- * |*pmont| is NULL. If so, it creates a new |BN_MONT_CTX| and sets the modulus
- * for it to |mod|. It then stores it as |*pmont| and returns it, or NULL on
- * error.
+/* BN_MONT_CTX_set_locked takes |lock| and checks whether |*pmont| is NULL. If
+ * so, it creates a new |BN_MONT_CTX| and sets the modulus for it to |mod|. It
+ * then stores it as |*pmont| and returns it, or NULL on error.
  *
  * If |*pmont| is already non-NULL then the existing value is returned. */
-OPENSSL_EXPORT BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont,
-                                                   int lock, const BIGNUM *mod,
-                                                   BN_CTX *ctx);
+BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_MUTEX *lock,
+                                    const BIGNUM *mod, BN_CTX *bn_ctx);
 
 /* BN_to_montgomery sets |ret| equal to |a| in the Montgomery domain. It
  * returns one on success and zero on error. */
diff --git a/include/openssl/dh.h b/include/openssl/dh.h
index 3c8f290..39614ff 100644
--- a/include/openssl/dh.h
+++ b/include/openssl/dh.h
@@ -61,6 +61,7 @@
 
 #include <openssl/engine.h>
 #include <openssl/ex_data.h>
+#include <openssl/thread.h>
 
 #if defined(__cplusplus)
 extern "C" {
@@ -236,6 +237,8 @@
   /* priv_length contains the length, in bits, of the private value. If zero,
    * the private value will be the same length as |p|. */
   unsigned priv_length;
+
+  CRYPTO_MUTEX method_mont_p_lock;
   BN_MONT_CTX *method_mont_p;
 
   /* Place holders if we want to do X9.42 DH */
diff --git a/include/openssl/dsa.h b/include/openssl/dsa.h
index 69dd56b..47270f8 100644
--- a/include/openssl/dsa.h
+++ b/include/openssl/dsa.h
@@ -64,6 +64,7 @@
 
 #include <openssl/engine.h>
 #include <openssl/ex_data.h>
+#include <openssl/thread.h>
 
 #if defined(__cplusplus)
 extern "C" {
@@ -351,6 +352,7 @@
 
   int flags;
   /* Normally used to cache montgomery values */
+  CRYPTO_MUTEX method_mont_p_lock;
   BN_MONT_CTX *method_mont_p;
   int references;
   CRYPTO_EX_DATA ex_data;
diff --git a/include/openssl/rsa.h b/include/openssl/rsa.h
index f49eb14..889ad19 100644
--- a/include/openssl/rsa.h
+++ b/include/openssl/rsa.h
@@ -61,6 +61,7 @@
 
 #include <openssl/engine.h>
 #include <openssl/ex_data.h>
+#include <openssl/thread.h>
 
 #if defined(__cplusplus)
 extern "C" {
@@ -471,18 +472,21 @@
   int references;
   int flags;
 
-  /* Used to cache montgomery values */
+  CRYPTO_MUTEX lock;
+
+  /* Used to cache montgomery values. The creation of these values is protected
+   * by |lock|. */
   BN_MONT_CTX *_method_mod_n;
   BN_MONT_CTX *_method_mod_p;
   BN_MONT_CTX *_method_mod_q;
 
   /* num_blindings contains the size of the |blindings| and |blindings_inuse|
    * arrays. This member and the |blindings_inuse| array are protected by
-   * CRYPTO_LOCK_RSA_BLINDING. */
+   * |lock|. */
   unsigned num_blindings;
   /* blindings is an array of BN_BLINDING structures that can be reserved by a
-   * thread by locking CRYPTO_LOCK_RSA_BLINDING and changing the corresponding
-   * element in |blindings_inuse| from 0 to 1. */
+   * thread by locking |lock| and changing the corresponding element in
+   * |blindings_inuse| from 0 to 1. */
   BN_BLINDING **blindings;
   unsigned char *blindings_inuse;
 };