Remove hash table lookups from ex_data.

Instead, each module defines a static CRYPTO_EX_DATA_CLASS to hold the values.
This makes CRYPTO_cleanup_all_ex_data a no-op as spreading the
CRYPTO_EX_DATA_CLASSes across modules (and across crypto and ssl) makes cleanup
slightly trickier. We can make it do something if needbe, but it's probably not
worth the trouble.

Change-Id: Ib6f6fd39a51d8ba88649f0fa29c66db540610c76
Reviewed-on: https://boringssl-review.googlesource.com/4375
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c
index de210f5..4db1f03 100644
--- a/ssl/ssl_sess.c
+++ b/ssl/ssl_sess.c
@@ -150,6 +150,8 @@
  * that it needs to asynchronously fetch session information. */
 static const char g_pending_session_magic = 0;
 
+static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
+
 static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s);
 static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s);
 static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck);
@@ -172,8 +174,12 @@
 int SSL_SESSION_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
                                  CRYPTO_EX_dup *dup_func,
                                  CRYPTO_EX_free *free_func) {
-  return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_SESSION, argl, argp,
-                                 new_func, dup_func, free_func);
+  int index;
+  if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, new_func,
+                               dup_func, free_func)) {
+    return -1;
+  }
+  return index;
 }
 
 int SSL_SESSION_set_ex_data(SSL_SESSION *s, int idx, void *arg) {
@@ -198,7 +204,7 @@
   ss->references = 1;
   ss->timeout = SSL_DEFAULT_SESSION_TIMEOUT;
   ss->time = (unsigned long)time(NULL);
-  CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data);
+  CRYPTO_new_ex_data(&g_ex_data_class, ss, &ss->ex_data);
   return ss;
 }
 
@@ -622,7 +628,7 @@
     return;
   }
 
-  CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data);
+  CRYPTO_free_ex_data(&g_ex_data_class, ss, &ss->ex_data);
 
   OPENSSL_cleanse(ss->master_key, sizeof ss->master_key);
   OPENSSL_cleanse(ss->session_id, sizeof ss->session_id);