You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by va...@apache.org on 2019/08/28 20:56:35 UTC

[commons-crypto] branch master updated: CRYPTO-137: Fix compilation + support OpenSSL 1.1 on Windows. (#94)

This is an automated email from the ASF dual-hosted git repository.

vanzin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-crypto.git


The following commit(s) were added to refs/heads/master by this push:
     new 83f1a72  CRYPTO-137: Fix compilation + support OpenSSL 1.1 on Windows. (#94)
83f1a72 is described below

commit 83f1a72e3fdc5e0faed548aece394b0410456e23
Author: aremily <ar...@users.noreply.github.com>
AuthorDate: Wed Aug 28 16:56:31 2019 -0400

    CRYPTO-137: Fix compilation + support OpenSSL 1.1 on Windows. (#94)
    
    Addresses CRYPTO-137 and in the process cleans up a lot of changes introduced in the 1.1 support branch merge. Build has been tested and passes for OpenSSL versions 1.0 and 1.1 on Windows and Linux, and 1.1 on OSX. Might also address CRYPTO-139.
---
 .travis.yml                                        |  15 +-
 Makefile.common                                    |   8 +-
 .../org/apache/commons/crypto/OpenSslInfoNative.c  |  82 ++++---
 .../apache/commons/crypto/cipher/OpenSslNative.c   |  95 ++++----
 .../commons/crypto/org_apache_commons_crypto.h     |  21 +-
 .../crypto/random/OpenSslCryptoRandomNative.c      | 238 ++++++++++-----------
 6 files changed, 254 insertions(+), 205 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index d6f4782..796de8e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -18,13 +18,23 @@ language: java
 
 matrix:
   include:
-    - name: "Linux / Java 8"
+    - name: "Ubuntu 14.04 / Java 8 / OpenSSL 1.0.x"
       os: linux
+      dist: trusty
       before_install:
         - "curl -L --cookie 'oraclelicense=accept-securebackup-cookie;'  http://download.oracle.com/otn-pub/java/jce/8/jce_policy-8.zip -o /tmp/policy.zip && sudo unzip -j -o /tmp/policy.zip *.jar -d `jdk_switcher home oraclejdk8`/jre/lib/security && rm /tmp/policy.zip"
+        - openssl version -a
       after_success:
         - mvn clean test jacoco:report coveralls:report
-
+    - name: "OS X / Java 8 / LibreSSL"
+      os: osx
+      osx_image: xcode9.3
+      before_install:
+        - "curl -L --cookie 'oraclelicense=accept-securebackup-cookie;'  http://download.oracle.com/otn-pub/java/jce/8/jce_policy-8.zip -o /tmp/policy.zip && sudo unzip -j -o /tmp/policy.zip *.jar -d /Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/jre/lib/security && rm /tmp/policy.zip"
+        - openssl version -a
+      after_success:
+        - mvn clean test jacoco:report coveralls:report
+      
 jdk:
   - oraclejdk8
 
@@ -32,3 +42,4 @@ script:
   - mvn apache-rat:check
   - mvn verify
   - mvn site
+  - mvn clirr:check
diff --git a/Makefile.common b/Makefile.common
index f5ce5b7..7a41d71 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -199,8 +199,8 @@ FreeBSD-x86_64_COMMONS_CRYPTO_FLAGS :=
 Windows-x86_CC           := $(CROSS_PREFIX)gcc
 Windows-x86_CXX          := $(CROSS_PREFIX)g++
 Windows-x86_STRIP        := $(CROSS_PREFIX)strip
-Windows-x86_CFLAGS       := -I"$(JAVA_HOME)/include" -Ilib/inc_win -O2
-Windows-x86_CXXFLAGS     := -I"$(JAVA_HOME)/include" -Ilib/inc_win -O2
+Windows-x86_CFLAGS       := -I"$(JAVA_HOME)/include" -I"$(OPENSSL_HOME)/include" -Ilib/inc_win -O2 -fno-inline
+Windows-x86_CXXFLAGS     := -I"$(JAVA_HOME)/include" -I"$(OPENSSL_HOME)/include" -Ilib/inc_win -O2 -fno-inline
 Windows-x86_LINKFLAGS    := -Wl,--kill-at -shared -static
 Windows-x86_LIBNAME      := commons-crypto.dll
 Windows-x86_COMMONS_CRYPTO_FLAGS :=
@@ -208,8 +208,8 @@ Windows-x86_COMMONS_CRYPTO_FLAGS :=
 Windows-x86_64_CC           := $(CROSS_PREFIX)gcc
 Windows-x86_64_CXX          := $(CROSS_PREFIX)g++
 Windows-x86_64_STRIP        := $(CROSS_PREFIX)strip
-Windows-x86_64_CFLAGS       := -I"$(JAVA_HOME)/include" -Ilib/inc_win -O2 -fno-inline
-Windows-x86_64_CXXFLAGS     := -I"$(JAVA_HOME)/include" -Ilib/inc_win -O2 -fno-inline
+Windows-x86_64_CFLAGS       := -I"$(JAVA_HOME)/include" -I"$(OPENSSL_HOME)/include" -Ilib/inc_win -O2 -fno-inline
+Windows-x86_64_CXXFLAGS     := -I"$(JAVA_HOME)/include" -I"$(OPENSSL_HOME)/include" -Ilib/inc_win -O2 -fno-inline
 Windows-x86_64_LINKFLAGS    := -Wl,--kill-at -shared -static
 Windows-x86_64_LIBNAME      := commons-crypto.dll
 Windows-x86_64_COMMONS-CRYPTO_FLAGS :=
diff --git a/src/main/native/org/apache/commons/crypto/OpenSslInfoNative.c b/src/main/native/org/apache/commons/crypto/OpenSslInfoNative.c
index 937fc28..50365b1 100644
--- a/src/main/native/org/apache/commons/crypto/OpenSslInfoNative.c
+++ b/src/main/native/org/apache/commons/crypto/OpenSslInfoNative.c
@@ -41,88 +41,102 @@
 #ifdef UNIX
 static unsigned long (*dlsym_OpenSSL_version_num) (void);
 static const char * (*dlsym_OpenSSL_version) (int);
-static void *openssl;
 #endif
 
 #ifdef WINDOWS
-typedef unsigned long (__cdecl *__dlsym_OpenSSL) (void);
-static __dlsym_OpenSSL dlsym_OpenSSL;
+typedef unsigned long (__cdecl *__dlsym_OpenSSL_version_num) (void);
 typedef char * (__cdecl *__dlsym_OpenSSL_version) (int);
-static __dlsym_OpenSSL dlsym_OpenSSL;
+static __dlsym_OpenSSL_version_num dlsym_OpenSSL_version_num;
 static __dlsym_OpenSSL_version dlsym_OpenSSL_version;
-HMODULE openssl;
 #endif
 
+#ifdef UNIX
+static void get_methods(JNIEnv *env, void *openssl)
+#endif
+#ifdef WINDOWS
+static void get_methods(JNIEnv *env, HMODULE openssl)
+#endif
+{
+  LOAD_OPENSSL_VERSION_FUNCTION(dlsym_OpenSSL_version_num, env, openssl);
+#ifdef UNIX
+  if (dlsym_OpenSSL_version_num() > VERSION_1_1_X) {
+    LOAD_DYNAMIC_SYMBOL(dlsym_OpenSSL_version, env, openssl, "OpenSSL_version");
+  } else {
+    LOAD_DYNAMIC_SYMBOL(dlsym_OpenSSL_version, env, openssl, "SSLeay_version");
+  }
+#endif
+#ifdef WINDOWS
+  if (dlsym_OpenSSL_version_num() > VERSION_1_1_X) {
+    LOAD_DYNAMIC_SYMBOL(__dlsym_OpenSSL_version, dlsym_OpenSSL_version, env, openssl, "OpenSSL_version");
+  } else {
+    LOAD_DYNAMIC_SYMBOL(__dlsym_OpenSSL_version, dlsym_OpenSSL_version, env, openssl, "SSLeay_version");
+  }
+#endif
+}
+
 static int load_library(JNIEnv *env)
 {
-    char msg[100];
+  char msg[100];
 #ifdef UNIX
-  openssl = dlopen(COMMONS_CRYPTO_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
+  void *openssl = dlopen(COMMONS_CRYPTO_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
 #endif
 
 #ifdef WINDOWS
-  openssl = LoadLibrary(TEXT(COMMONS_CRYPTO_OPENSSL_LIBRARY));
+  HMODULE openssl = LoadLibrary(TEXT(COMMONS_CRYPTO_OPENSSL_LIBRARY));
 #endif
 
   if (!openssl) {
 #ifdef UNIX
     snprintf(msg, sizeof(msg), "Cannot load %s (%s)!", COMMONS_CRYPTO_OPENSSL_LIBRARY,  \
-        dlerror());
+    dlerror());
 #endif
 #ifdef WINDOWS
     snprintf(msg, sizeof(msg), "Cannot load %s (%d)!", COMMONS_CRYPTO_OPENSSL_LIBRARY,  \
-        GetLastError());
+    GetLastError());
 #endif
     THROW(env, "java/lang/UnsatisfiedLinkError", msg);
     return 0;
   }
-#ifdef UNIX
-  LOAD_OPENSSL_VERSION_FUNCTION(dlsym_OpenSSL_version_num, env, openssl);
-#endif
+  get_methods(env, openssl);
   return 1;
 }
 
 JNIEXPORT jstring JNICALL Java_org_apache_commons_crypto_OpenSslInfoNative_NativeVersion
-    (JNIEnv *env, jobject object)
+  (JNIEnv *env, jobject object)
 {
-    return (*env)->NewStringUTF(env, VERSION);
+  return (*env)->NewStringUTF(env, VERSION);
 }
 
 JNIEXPORT jstring JNICALL Java_org_apache_commons_crypto_OpenSslInfoNative_NativeTimeStamp
-    (JNIEnv *env, jobject object)
+  (JNIEnv *env, jobject object)
 {
-    return (*env)->NewStringUTF(env, __DATE__);
+  return (*env)->NewStringUTF(env, __DATE__);
 }
 
 JNIEXPORT jstring JNICALL Java_org_apache_commons_crypto_OpenSslInfoNative_NativeName
-    (JNIEnv *env, jobject object)
+  (JNIEnv *env, jobject object)
 {
-    return (*env)->NewStringUTF(env, PROJECT_NAME);
+  return (*env)->NewStringUTF(env, PROJECT_NAME);
 }
 
 JNIEXPORT jlong JNICALL Java_org_apache_commons_crypto_OpenSslInfoNative_OpenSSL
   (JNIEnv *env, jclass clazz)
 {
-    if (!load_library(env)) {
-        return 0;
-    }
-    jlong version_num = (jlong)dlsym_OpenSSL_version_num();
-    return version_num;
+  if (!load_library(env)) {
+    return 0;
+  }
+  jlong version_num = (jlong)dlsym_OpenSSL_version_num();
+  return version_num;
 }
 
 JNIEXPORT jstring JNICALL Java_org_apache_commons_crypto_OpenSslInfoNative_OpenSSLVersion
   (JNIEnv *env, jclass clazz, jint type)
 {
-    if (!load_library(env)) {
-        return NULL;
-    }
-    if (dlsym_OpenSSL_version_num() > VERSION_1_1_X) {
-    	dlsym_OpenSSL_version = do_dlsym(env, openssl, "OpenSSL_version");
-    } else {
-    	dlsym_OpenSSL_version = do_dlsym(env, openssl, "SSLeay_version");
-    }
-    jstring answer = (*env)->NewStringUTF(env,dlsym_OpenSSL_version(type));
-    return answer;
+  if (!load_library(env)) {
+    return NULL;
+  }
+  jstring answer = (*env)->NewStringUTF(env,dlsym_OpenSSL_version(type));
+  return answer;
 }
 
 
diff --git a/src/main/native/org/apache/commons/crypto/cipher/OpenSslNative.c b/src/main/native/org/apache/commons/crypto/cipher/OpenSslNative.c
index 25b4a06..ddeaf80 100644
--- a/src/main/native/org/apache/commons/crypto/cipher/OpenSslNative.c
+++ b/src/main/native/org/apache/commons/crypto/cipher/OpenSslNative.c
@@ -52,15 +52,17 @@ static EVP_CIPHER * (*dlsym_EVP_aes_128_cbc)(void);
 static EVP_CIPHER * (*dlsym_EVP_aes_256_gcm)(void);
 static EVP_CIPHER * (*dlsym_EVP_aes_192_gcm)(void);
 static EVP_CIPHER * (*dlsym_EVP_aes_128_gcm)(void);
-static void *openssl;
 #endif
 
 #ifdef WINDOWS
 typedef EVP_CIPHER_CTX * (__cdecl *__dlsym_EVP_CIPHER_CTX_new)(void);
 typedef void (__cdecl *__dlsym_EVP_CIPHER_CTX_free)(EVP_CIPHER_CTX *);
-typedef int (__cdecl *__dlsym_EVP_CIPHER_CTX_reset)(EVP_CIPHER_CTX *);
 typedef int (__cdecl *__dlsym_EVP_CIPHER_CTX_set_padding)(EVP_CIPHER_CTX *, int);
 typedef int (__cdecl *__dlsym_EVP_CIPHER_CTX_ctrl)(EVP_CIPHER_CTX *, int, int, void *);
+typedef int (__cdecl *__dlsym_EVP_CIPHER_CTX_block_size)(EVP_CIPHER_CTX *);
+typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_CIPHER_CTX_cipher)(EVP_CIPHER_CTX *);
+typedef unsigned long (__cdecl *__dlsym_EVP_CIPHER_flags)(const EVP_CIPHER *);
+typedef int (__cdecl *__dlsym_EVP_CIPHER_CTX_test_flags)(const EVP_CIPHER_CTX *, int);
 typedef int (__cdecl *__dlsym_EVP_CipherInit_ex)(EVP_CIPHER_CTX *,  \
              const EVP_CIPHER *, ENGINE *, const unsigned char *,  \
              const unsigned char *, int);
@@ -79,9 +81,12 @@ typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_192_gcm)(void);
 typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_128_gcm)(void);
 static __dlsym_EVP_CIPHER_CTX_new dlsym_EVP_CIPHER_CTX_new;
 static __dlsym_EVP_CIPHER_CTX_free dlsym_EVP_CIPHER_CTX_free;
-static __dlsym_EVP_CIPHER_CTX_reset dlsym_EVP_CIPHER_CTX_reset;
 static __dlsym_EVP_CIPHER_CTX_set_padding dlsym_EVP_CIPHER_CTX_set_padding;
 static __dlsym_EVP_CIPHER_CTX_ctrl dlsym_EVP_CIPHER_CTX_ctrl;
+static __dlsym_EVP_CIPHER_CTX_block_size dlsym_EVP_CIPHER_CTX_block_size;
+static __dlsym_EVP_CIPHER_CTX_cipher dlsym_EVP_CIPHER_CTX_cipher;
+static __dlsym_EVP_CIPHER_flags dlsym_EVP_CIPHER_flags;
+static __dlsym_EVP_CIPHER_CTX_test_flags dlsym_EVP_CIPHER_CTX_test_flags;
 static __dlsym_EVP_CipherInit_ex dlsym_EVP_CipherInit_ex;
 static __dlsym_EVP_CipherUpdate dlsym_EVP_CipherUpdate;
 static __dlsym_EVP_CipherFinal_ex dlsym_EVP_CipherFinal_ex;
@@ -97,7 +102,7 @@ static __dlsym_EVP_aes_128_gcm dlsym_EVP_aes_128_gcm;
 #endif
 
 #ifdef UNIX
-static void loadAes(JNIEnv *env)
+static void loadAes(JNIEnv *env, void *openssl)
 #endif
 
 #ifdef WINDOWS
@@ -143,7 +148,7 @@ JNIEXPORT void JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_initI
 {
   char msg[1000];
 #ifdef UNIX
-  openssl = dlopen(COMMONS_CRYPTO_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
+  void *openssl = dlopen(COMMONS_CRYPTO_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
 #endif
 
 #ifdef WINDOWS
@@ -153,11 +158,11 @@ JNIEXPORT void JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_initI
   if (!openssl) {
 #ifdef UNIX
     snprintf(msg, sizeof(msg), "Cannot load %s (%s)!", COMMONS_CRYPTO_OPENSSL_LIBRARY,  \
-        dlerror());
+    dlerror());
 #endif
 #ifdef WINDOWS
     snprintf(msg, sizeof(msg), "Cannot load %s (%d)!", COMMONS_CRYPTO_OPENSSL_LIBRARY,  \
-        GetLastError());
+    GetLastError());
 #endif
     THROW(env, "java/lang/UnsatisfiedLinkError", msg);
     return;
@@ -183,12 +188,18 @@ JNIEXPORT void JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_initI
                       env, openssl, "EVP_CIPHER_CTX_new");
   LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CIPHER_CTX_free, dlsym_EVP_CIPHER_CTX_free,  \
                       env, openssl, "EVP_CIPHER_CTX_free");
-  LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CIPHER_CTX_reset,  \
-                      dlsym_EVP_CIPHER_CTX_reset, env,
-                      openssl, "EVP_CIPHER_CTX_reset");
-  LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CIPHER_CTX_set_padding,  \
-                      dlsym_EVP_CIPHER_CTX_set_padding, env,  \
-                      openssl, "EVP_CIPHER_CTX_set_padding");
+  LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CIPHER_CTX_set_padding, dlsym_EVP_CIPHER_CTX_set_padding,  \
+                      env, openssl, "EVP_CIPHER_CTX_set_padding");
+  LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CIPHER_CTX_ctrl, dlsym_EVP_CIPHER_CTX_ctrl,  \
+                      env, openssl, "EVP_CIPHER_CTX_ctrl");
+  LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CIPHER_CTX_block_size, dlsym_EVP_CIPHER_CTX_block_size,  \
+                      env, openssl, "EVP_CIPHER_CTX_block_size");
+  LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CIPHER_CTX_cipher, dlsym_EVP_CIPHER_CTX_cipher,  \
+                      env, openssl, "EVP_CIPHER_CTX_cipher");
+  LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CIPHER_flags, dlsym_EVP_CIPHER_flags,  \
+                      env, openssl, "EVP_CIPHER_flags");
+  LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CIPHER_CTX_test_flags, dlsym_EVP_CIPHER_CTX_test_flags,  \
+                      env, openssl, "EVP_CIPHER_CTX_test_flags");
   LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CipherInit_ex, dlsym_EVP_CipherInit_ex,  \
                       env, openssl, "EVP_CipherInit_ex");
   LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CipherUpdate, dlsym_EVP_CipherUpdate,  \
@@ -197,12 +208,12 @@ JNIEXPORT void JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_initI
                       env, openssl, "EVP_CipherFinal_ex");
 #endif
 
-  loadAes(env);
+  loadAes(env, openssl);
   jthrowable jthr = (*env)->ExceptionOccurred(env);
   if (jthr) {
     (*env)->DeleteLocalRef(env, jthr);
     THROW(env, "java/lang/UnsatisfiedLinkError",  \
-        "Cannot find AES-CTR support, is your version of Openssl new enough?");
+    "Cannot find AES-CTR support, is your version of Openssl new enough?");
     return;
   }
 }
@@ -277,23 +288,23 @@ JNIEXPORT jlong JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_init
   }
 
   if (dlsym_EVP_aes_256_ctr == NULL ||
-        dlsym_EVP_aes_192_ctr == NULL || dlsym_EVP_aes_128_ctr == NULL) {
+      dlsym_EVP_aes_192_ctr == NULL || dlsym_EVP_aes_128_ctr == NULL) {
     THROW(env, "java/security/NoSuchAlgorithmException",  \
-        "Doesn't support AES CTR.");
+    "Doesn't support AES CTR.");
     return (jlong)0;
   }
 
   if (dlsym_EVP_aes_256_cbc == NULL ||
-        dlsym_EVP_aes_192_cbc == NULL || dlsym_EVP_aes_128_cbc == NULL) {
+      dlsym_EVP_aes_192_cbc == NULL || dlsym_EVP_aes_128_cbc == NULL) {
     THROW(env, "java/security/NoSuchAlgorithmException",  \
-        "Doesn't support AES CBC.");
+    "Doesn't support AES CBC.");
     return (jlong)0;
   }
 
   if (dlsym_EVP_aes_256_gcm == NULL ||
-    dlsym_EVP_aes_192_gcm == NULL || dlsym_EVP_aes_128_gcm == NULL) {
+      dlsym_EVP_aes_192_gcm == NULL || dlsym_EVP_aes_128_gcm == NULL) {
     THROW(env, "java/security/NoSuchAlgorithmException",  \
-       "Doesn't support AES GCM.");
+    "Doesn't support AES GCM.");
     return (jlong)0;
   }
 
@@ -334,8 +345,8 @@ static EVP_CIPHER * getEvpCipher(int alg, int keyLen)
 }
 
 JNIEXPORT jlong JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_init
-    (JNIEnv *env, jclass clazz, jlong ctx, jint mode, jint alg, jint padding,
-    jbyteArray key, jbyteArray iv)
+  (JNIEnv *env, jclass clazz, jlong ctx, jint mode, jint alg, jint padding,
+   jbyteArray key, jbyteArray iv)
 {
   EVP_CTX_Wrapper *wrapper = CTX_WRAPPER(ctx);
   int is_new_context = 0;
@@ -353,7 +364,7 @@ JNIEXPORT jlong JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_init
   int jKeyLen = (*env)->GetArrayLength(env, key);
   int jIvLen = (*env)->GetArrayLength(env, iv);
   if (jKeyLen != KEY_LENGTH_128 && jKeyLen != KEY_LENGTH_192
-        && jKeyLen != KEY_LENGTH_256) {
+      && jKeyLen != KEY_LENGTH_256) {
     char str[64] = {0};
     snprintf(str, sizeof(str), "Invalid AES key length: %d bytes", jKeyLen);
     THROW(env, "java/security/InvalidKeyException", str);
@@ -404,7 +415,7 @@ JNIEXPORT jlong JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_init
   }
 
   rc = dlsym_EVP_CipherInit_ex(context, NULL, NULL, \
-         (unsigned char *)jKey, (unsigned char *)jIv, mode == ENCRYPT_MODE);
+       (unsigned char *)jKey, (unsigned char *)jIv, mode == ENCRYPT_MODE);
   if (rc == 0) {
     THROW(env, "java/lang/InternalError", "Error in EVP_CipherInit_ex.");
     goto cleanup;
@@ -435,8 +446,8 @@ cleanup:
 }
 
 JNIEXPORT jint JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_update
-    (JNIEnv *env, jclass clazz, jlong ctx, jobject input, jint input_offset,
-    jint input_len, jobject output, jint output_offset, jint max_output_len)
+  (JNIEnv *env, jclass clazz, jlong ctx, jobject input, jint input_offset,
+   jint input_len, jobject output, jint output_offset, jint max_output_len)
 {
   EVP_CIPHER_CTX *context = get_context(env, ctx);
   if (context == NULL) {
@@ -445,7 +456,7 @@ JNIEXPORT jint JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_updat
 
   if (!check_update_max_output_len(CTX_WRAPPER(ctx), input_len, max_output_len)) {
     THROW(env, "javax/crypto/ShortBufferException",  \
-        "Output buffer is not sufficient.");
+    "Output buffer is not sufficient.");
     return 0;
   }
   unsigned char *input_bytes = (*env)->GetDirectBufferAddress(env, input);
@@ -467,8 +478,8 @@ JNIEXPORT jint JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_updat
 }
 
 JNIEXPORT jint JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_updateByteArray
-    (JNIEnv *env, jclass clazz, jlong ctx, jbyteArray input, jint input_offset,
-    jint input_len, jbyteArray output, jint output_offset, jint max_output_len)
+  (JNIEnv *env, jclass clazz, jlong ctx, jbyteArray input, jint input_offset,
+   jint input_len, jbyteArray output, jint output_offset, jint max_output_len)
 {
   EVP_CIPHER_CTX *context = get_context(env, ctx);
   if (context == NULL) {
@@ -515,8 +526,8 @@ cleanup:
 }
 
 JNIEXPORT jint JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_updateByteArrayByteBuffer
-    (JNIEnv *env, jclass clazz, jlong ctx, jbyteArray input, jint input_offset,
-    jint input_len, jobject output, jint output_offset, jint max_output_len)
+  (JNIEnv *env, jclass clazz, jlong ctx, jbyteArray input, jint input_offset,
+   jint input_len, jobject output, jint output_offset, jint max_output_len)
 {
   EVP_CIPHER_CTX *context = get_context(env, ctx);
   if (context == NULL) {
@@ -525,7 +536,7 @@ JNIEXPORT jint JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_updat
 
   if (!check_update_max_output_len(CTX_WRAPPER(ctx), input_len, max_output_len)) {
     THROW(env, "javax/crypto/ShortBufferException",  \
-        "Output buffer is not sufficient.");
+    "Output buffer is not sufficient.");
     return 0;
   }
 
@@ -552,8 +563,8 @@ cleanup:
 }
 
 JNIEXPORT jint JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_doFinal
-    (JNIEnv *env, jclass clazz, jlong ctx, jobject output, jint offset,
-    jint max_output_len)
+  (JNIEnv *env, jclass clazz, jlong ctx, jobject output, jint offset,
+   jint max_output_len)
 {
   EVP_CIPHER_CTX *context = get_context(env, ctx);
   if (context == NULL) {
@@ -562,7 +573,7 @@ JNIEXPORT jint JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_doFin
 
   if (!check_doFinal_max_output_len(env, context, max_output_len)) {
     THROW(env, "javax/crypto/ShortBufferException",  \
-        "Output buffer is not sufficient.");
+    "Output buffer is not sufficient.");
     return 0;
   }
   unsigned char *output_bytes = (*env)->GetDirectBufferAddress(env, output);
@@ -586,8 +597,8 @@ JNIEXPORT jint JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_doFin
 }
 
 JNIEXPORT jint JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_doFinalByteArray
-    (JNIEnv *env, jclass clazz, jlong ctx, jbyteArray output, jint offset,
-     jint max_output_len)
+  (JNIEnv *env, jclass clazz, jlong ctx, jbyteArray output, jint offset,
+   jint max_output_len)
 {
   EVP_CIPHER_CTX *context = get_context(env, ctx);
   if (context == NULL) {
@@ -596,7 +607,7 @@ JNIEXPORT jint JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_doFin
 
   if (!check_doFinal_max_output_len(env, context, max_output_len)) {
     THROW(env, "javax/crypto/ShortBufferException",  \
-        "Output buffer is not sufficient.");
+    "Output buffer is not sufficient.");
     return 0;
   }
   unsigned char *output_bytes = (unsigned char *) (*env)->GetByteArrayElements(env, output, 0);
@@ -623,7 +634,7 @@ JNIEXPORT jint JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_doFin
 }
 
 JNIEXPORT jint JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_ctrl
-    (JNIEnv *env, jclass clazz, jlong ctx, jint type, jint arg, jbyteArray data)
+  (JNIEnv *env, jclass clazz, jlong ctx, jint type, jint arg, jbyteArray data)
 {
   EVP_CIPHER_CTX *context = get_context(env, ctx);
   if (context == NULL) {
@@ -671,7 +682,7 @@ exit_:
 
 
 JNIEXPORT void JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_clean
-    (JNIEnv *env, jclass clazz, jlong ctx)
+  (JNIEnv *env, jclass clazz, jlong ctx)
 {
   EVP_CTX_Wrapper *wrapper = CTX_WRAPPER(ctx);
   free_context_wrapper(wrapper);
@@ -721,5 +732,3 @@ static int is_bad_tag(EVP_CTX_Wrapper *wrapper)
   }
   return 0;
 }
-
-
diff --git a/src/main/native/org/apache/commons/crypto/org_apache_commons_crypto.h b/src/main/native/org/apache/commons/crypto/org_apache_commons_crypto.h
index d0b43ef..9c5916e 100644
--- a/src/main/native/org/apache/commons/crypto/org_apache_commons_crypto.h
+++ b/src/main/native/org/apache/commons/crypto/org_apache_commons_crypto.h
@@ -134,7 +134,7 @@ void *do_version_dlsym(JNIEnv *env, void *handle) {
 
 /* Microsoft C Compiler does not support the C99 inline keyword */
 #ifndef __cplusplus
-#define inline __inline;
+//#define inline __inline;
 #endif // _cplusplus
 
 /* Optimization macros supported by GCC but for which there is no
@@ -187,6 +187,25 @@ static FARPROC WINAPI do_dlsym(JNIEnv *env, HMODULE handle, LPCSTR symbol) {
   }
   return func_ptr;
 }
+
+static FARPROC WINAPI do_version_dlsym(JNIEnv *env, HMODULE handle) {
+  FARPROC func_ptr = NULL;
+  if (!env || !handle) {
+    THROW(env, "java/lang/InternalError", NULL);
+    return NULL;
+  }
+  func_ptr = GetProcAddress(handle, "OpenSSL_version_num");
+  if (func_ptr == NULL) {
+    func_ptr = GetProcAddress(handle, "SSLeay");
+  }
+  return func_ptr;
+}
+
+/* A macro to dlsym the appropriate OpenSSL version number function. */
+#define LOAD_OPENSSL_VERSION_FUNCTION(func_ptr, env, handle) \
+  if ((func_ptr = (__dlsym_OpenSSL_version_num) do_version_dlsym(env, handle)) == NULL) { \
+    THROW(env, "java/lang/Error", NULL); \
+  }
 #endif
 // Windows part end
 
diff --git a/src/main/native/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.c b/src/main/native/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.c
index 9f6078d..fdc72f6 100644
--- a/src/main/native/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.c
+++ b/src/main/native/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.c
@@ -51,7 +51,14 @@ static int (*dlsym_ENGINE_free) (ENGINE *);
 static int (*dlsym_RAND_bytes) (unsigned char *, int);
 static unsigned long (*dlsym_ERR_get_error) (void);
 static unsigned long (*dlsym_OpenSSL_version_num)(void);
-static void *openssl;
+static int (*dlsym_CRYPTO_num_locks) (void);
+static void (*dlsym_CRYPTO_set_id_callback) (unsigned long (*)());
+static void (*dlsym_CRYPTO_set_locking_callback) (void (*)());
+static void (*dlsym_ENGINE_load_rdrand) (void);
+static void (*dlsym_ENGINE_cleanup) (void);
+static void pthreads_locking_callback(int mode, int type, char *file, int line);
+static unsigned long pthreads_thread_id(void);
+static pthread_mutex_t *lock_cs;
 #endif
 
 #ifdef WINDOWS
@@ -64,6 +71,11 @@ typedef int (__cdecl *__dlsym_ENGINE_finish) (ENGINE *);
 typedef int (__cdecl *__dlsym_ENGINE_free) (ENGINE *);
 typedef int (__cdecl *__dlsym_RAND_bytes) (unsigned char *, int);
 typedef unsigned long (__cdecl *__dlsym_ERR_get_error) (void);
+typedef unsigned long (__cdecl *__dlsym_OpenSSL_version_num) (void);
+typedef int (__cdecl *__dlsym_CRYPTO_num_locks) (void);
+typedef void (__cdecl *__dlsym_CRYPTO_set_locking_callback) (void (*)());
+typedef void (__cdecl *__dlsym_ENGINE_load_rdrand) (void);
+typedef void (__cdecl *__dlsym_ENGINE_cleanup) (void);
 static __dlsym_CRYPTO_malloc dlsym_CRYPTO_malloc;
 static __dlsym_CRYPTO_free dlsym_CRYPTO_free;
 static __dlsym_ENGINE_by_id dlsym_ENGINE_by_id;
@@ -73,21 +85,24 @@ static __dlsym_ENGINE_finish dlsym_ENGINE_finish;
 static __dlsym_ENGINE_free dlsym_ENGINE_free;
 static __dlsym_RAND_bytes dlsym_RAND_bytes;
 static __dlsym_ERR_get_error dlsym_ERR_get_error;
+static __dlsym_OpenSSL_version_num dlsym_OpenSSL_version_num;
+static __dlsym_CRYPTO_num_locks dlsym_CRYPTO_num_locks;
+static __dlsym_CRYPTO_set_locking_callback dlsym_CRYPTO_set_locking_callback;
+static __dlsym_ENGINE_load_rdrand dlsym_ENGINE_load_rdrand;
+static __dlsym_ENGINE_cleanup dlsym_ENGINE_cleanup;
+static void windows_locking_callback(int mode, int type, char *file, int line);
+static HANDLE *lock_cs;
 #endif
 
-static ENGINE * openssl_rand_init(JNIEnv *env);
-static void openssl_rand_clean(JNIEnv *env, ENGINE *eng, int clean_locks);
+static ENGINE * openssl_rand_init(void);
+static void openssl_rand_clean(ENGINE *eng, int clean_locks);
 static int openssl_rand_bytes(unsigned char *buf, int num);
-static void pthreads_locking_callback(int mode, int type, char *file, int line);
-static unsigned long pthreads_thread_id(void);
-static pthread_mutex_t *lock_cs;
 
-JNIEXPORT void JNICALL Java_org_apache_commons_crypto_random_OpenSslCryptoRandomNative_initSR
-    (JNIEnv *env, jclass clazz)
+JNIEXPORT void JNICALL Java_org_apache_commons_crypto_random_OpenSslCryptoRandomNative_initSR (JNIEnv *env, jclass clazz)
 {
   char msg[1000];
 #ifdef UNIX
-  openssl = dlopen(COMMONS_CRYPTO_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
+  void *openssl = dlopen(COMMONS_CRYPTO_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
 #endif
 
 #ifdef WINDOWS
@@ -96,54 +111,54 @@ JNIEXPORT void JNICALL Java_org_apache_commons_crypto_random_OpenSslCryptoRandom
 
   if (!openssl) {
 #ifdef UNIX
-    snprintf(msg, sizeof(msg), "Cannot load %s (%s)!", COMMONS_CRYPTO_OPENSSL_LIBRARY,  \
-        dlerror());
+    snprintf(msg, sizeof(msg), "Cannot load %s (%s)!", COMMONS_CRYPTO_OPENSSL_LIBRARY, dlerror());
 #endif
 #ifdef WINDOWS
-    snprintf(msg, sizeof(msg), "Cannot load %s (%d)!", COMMONS_CRYPTO_OPENSSL_LIBRARY,  \
-        GetLastError());
+    snprintf(msg, sizeof(msg), "Cannot load %s (%d)!", COMMONS_CRYPTO_OPENSSL_LIBRARY, GetLastError());
 #endif
     THROW(env, "java/lang/UnsatisfiedLinkError", msg);
     return;
   }
-
+  LOAD_OPENSSL_VERSION_FUNCTION(dlsym_OpenSSL_version_num, env, openssl);
 #ifdef UNIX
   dlerror();  // Clear any existing error
   LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_malloc, env, openssl, "CRYPTO_malloc");
   LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_free, env, openssl, "CRYPTO_free");
   LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_by_id, env, openssl, "ENGINE_by_id");
   LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_init, env, openssl, "ENGINE_init");
-  LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_set_default, env,  \
-                      openssl, "ENGINE_set_default");
+  LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_set_default, env, openssl, "ENGINE_set_default");
   LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_finish, env, openssl, "ENGINE_finish");
   LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_free, env, openssl, "ENGINE_free");
   LOAD_DYNAMIC_SYMBOL(dlsym_RAND_bytes, env, openssl, "RAND_bytes");
   LOAD_DYNAMIC_SYMBOL(dlsym_ERR_get_error, env, openssl, "ERR_get_error");
-  LOAD_OPENSSL_VERSION_FUNCTION(dlsym_OpenSSL_version_num, env, openssl);
+  if (dlsym_OpenSSL_version_num() < VERSION_1_1_X) {
+    LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_num_locks, env, openssl, "CRYPTO_num_locks");
+    LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_set_id_callback, env, openssl, "CRYPTO_set_id_callback");
+    LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_set_locking_callback, env, openssl, "CRYPTO_set_locking_callback");
+    LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_load_rdrand, env, openssl, "ENGINE_load_rdrand");
+    LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_cleanup, env, openssl, "ENGINE_cleanup");
+  }
 #endif
 
 #ifdef WINDOWS
-  LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_malloc, dlsym_CRYPTO_malloc,  \
-                      env, openssl, "CRYPTO_malloc");
-  LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_free, dlsym_CRYPTO_free,  \
-                      env, openssl, "CRYPTO_free");
-  LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_by_id, dlsym_ENGINE_by_id,  \
-                      env, openssl, "ENGINE_by_id");
-  LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_init, dlsym_ENGINE_init,  \
-                      env, openssl, "ENGINE_init");
-  LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_set_default, dlsym_ENGINE_set_default,  \
-                      env, openssl, "ENGINE_set_default");
-  LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_finish, dlsym_ENGINE_finish,  \
-                      env, openssl, "ENGINE_finish");
-  LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_free, dlsym_ENGINE_free,  \
-                      env, openssl, "ENGINE_free");
-  LOAD_DYNAMIC_SYMBOL(__dlsym_RAND_bytes, dlsym_RAND_bytes,  \
-                      env, openssl, "RAND_bytes");
-  LOAD_DYNAMIC_SYMBOL(__dlsym_ERR_get_error, dlsym_ERR_get_error,  \
-                      env, openssl, "ERR_get_error");
+  LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_malloc, dlsym_CRYPTO_malloc, env, openssl, "CRYPTO_malloc");
+  LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_free, dlsym_CRYPTO_free, env, openssl, "CRYPTO_free");
+  LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_by_id, dlsym_ENGINE_by_id, env, openssl, "ENGINE_by_id");
+  LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_init, dlsym_ENGINE_init, env, openssl, "ENGINE_init");
+  LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_set_default, dlsym_ENGINE_set_default, env, openssl, "ENGINE_set_default");
+  LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_finish, dlsym_ENGINE_finish, env, openssl, "ENGINE_finish");
+  LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_free, dlsym_ENGINE_free, env, openssl, "ENGINE_free");
+  LOAD_DYNAMIC_SYMBOL(__dlsym_RAND_bytes, dlsym_RAND_bytes, env, openssl, "RAND_bytes");
+  LOAD_DYNAMIC_SYMBOL(__dlsym_ERR_get_error, dlsym_ERR_get_error, env, openssl, "ERR_get_error");
+  if (dlsym_OpenSSL_version_num() < VERSION_1_1_X) {
+    LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_num_locks, dlsym_CRYPTO_num_locks, env, openssl, "CRYPTO_num_locks");
+    LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_set_locking_callback, dlsym_CRYPTO_set_locking_callback, env, openssl, "CRYPTO_set_locking_callback");
+    LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_load_rdrand, dlsym_ENGINE_load_rdrand, env, openssl, "ENGINE_load_rdrand");
+    LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_cleanup, dlsym_ENGINE_cleanup, env, openssl, "ENGINE_cleanup");
+  }
 #endif
 
-  openssl_rand_init(env);
+  openssl_rand_init();
 }
 
 JNIEXPORT jboolean JNICALL Java_org_apache_commons_crypto_random_OpenSslCryptoRandomNative_nextRandBytes___3B
@@ -174,118 +189,103 @@ JNIEXPORT jboolean JNICALL Java_org_apache_commons_crypto_random_OpenSslCryptoRa
  * http://wiki.openssl.org/index.php/Random_Numbers
  * Example: crypto/threads/mttest.c
  */
+#ifdef UNIX
+static void pthreads_locking_callback(int mode, int type, char *file, int line)
+{
+  UNUSED(file), UNUSED(line);
 
-#ifdef WINDOWS
-static void windows_locking_callback(int mode, int type, char *file, int line);
-static HANDLE *lock_cs;
+  if (mode & CRYPTO_LOCK) {
+    pthread_mutex_lock(&(lock_cs[type]));
+  } else {
+    pthread_mutex_unlock(&(lock_cs[type]));
+  }
+}
+
+static unsigned long pthreads_thread_id(void)
+{
+  return (unsigned long)syscall(SYS_gettid);
+}
 
 static void locks_setup(void)
 {
-  int i;
-  lock_cs = dlsym_CRYPTO_malloc(dlsym_CRYPTO_num_locks() * sizeof(HANDLE),  \
-      __FILE__, __LINE__);
+  if (dlsym_OpenSSL_version_num() < VERSION_1_1_X) {
+    int i;
+    lock_cs = dlsym_CRYPTO_malloc(dlsym_CRYPTO_num_locks() * sizeof(pthread_mutex_t), __FILE__, __LINE__);
 
-  for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) {
-    lock_cs[i] = CreateMutex(NULL, FALSE, NULL);
+    for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) {
+      pthread_mutex_init(&(lock_cs[i]), NULL);
+    }
+
+    dlsym_CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
+    dlsym_CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);
   }
-  dlsym_CRYPTO_set_locking_callback((void (*)(int, int, char *, int))  \
-      windows_locking_callback);
-  /* id callback defined */
 }
 
 static void locks_cleanup(void)
 {
-  int i;
-  dlsym_CRYPTO_set_locking_callback(NULL);
+  if (dlsym_OpenSSL_version_num() < VERSION_1_1_X) {
+    int i;
+    dlsym_CRYPTO_set_locking_callback(NULL);
+
+    for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) {
+      pthread_mutex_destroy(&(lock_cs[i]));
+    }
 
-  for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) {
-    CloseHandle(lock_cs[i]);
+    dlsym_CRYPTO_free(lock_cs);
   }
-  dlsym_CRYPTO_free(lock_cs);
 }
+#endif /* UNIX */
 
-static void windows_locking_callback(int mode, int type, char *file, int line)
+#ifdef WINDOWS
+static void locks_setup(void)
 {
-  UNUSED(file), UNUSED(line);
+  if (dlsym_OpenSSL_version_num() < VERSION_1_1_X) {
+    int i;
+    lock_cs = dlsym_CRYPTO_malloc(dlsym_CRYPTO_num_locks() * sizeof(HANDLE),  \
+      __FILE__, __LINE__);
 
-  if (mode & CRYPTO_LOCK) {
-    WaitForSingleObject(lock_cs[type], INFINITE);
-  } else {
-    ReleaseMutex(lock_cs[type]);
+    for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) {
+      lock_cs[i] = CreateMutex(NULL, FALSE, NULL);
+    }
+    dlsym_CRYPTO_set_locking_callback((void (*)(int, int, char *, int))  \
+      windows_locking_callback);
+    /* id callback defined */
   }
 }
-#endif /* WINDOWS */
-
-#ifdef UNIX
-static void pthreads_locking_callback(int mode, int type, char *file, int line);
-static unsigned long pthreads_thread_id(void);
-static pthread_mutex_t *lock_cs;
 
-static void locks_setup(JNIEnv *env)
+static void locks_cleanup(void)
 {
-  int i;
-  static int (*dlsym_CRYPTO_num_locks) (void);
-  dlsym_CRYPTO_num_locks = do_dlsym(env, openssl, "CRYPTO_num_locks");
-  lock_cs = dlsym_CRYPTO_malloc(dlsym_CRYPTO_num_locks() *  \
-      sizeof(pthread_mutex_t), __FILE__, __LINE__);
-
-  for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) {
-    pthread_mutex_init(&(lock_cs[i]), NULL);
-  }
-
-  static void (*dlsym_CRYPTO_set_id_callback) (unsigned long (*)());
-  dlsym_CRYPTO_set_id_callback = do_dlsym(env, openssl, "CRYPTO_set_id_callback");
-  static void (*dlsym_CRYPTO_set_locking_callback) (void (*)());
-  dlsym_CRYPTO_set_locking_callback = do_dlsym(env, openssl, "CRYPTO_set_locking_callback");
-
-  dlsym_CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
-  dlsym_CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);
-}
+  if (dlsym_OpenSSL_version_num() < VERSION_1_1_X) {
+    int i;
+    dlsym_CRYPTO_set_locking_callback(NULL);
 
-static void locks_cleanup(JNIEnv *env)
-{
-  int i;
-  static int (*dlsym_CRYPTO_num_locks) (void);
-  dlsym_CRYPTO_num_locks = do_dlsym(env, openssl, "CRYPTO_num_locks");
-  static void (*dlsym_CRYPTO_set_locking_callback) (void (*)());
-  dlsym_CRYPTO_set_locking_callback = do_dlsym(env, openssl, "CRYPTO_set_locking_callback");
-  dlsym_CRYPTO_set_locking_callback(NULL);
-
-  for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) {
-    pthread_mutex_destroy(&(lock_cs[i]));
+    for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) {
+      CloseHandle(lock_cs[i]);
+    }
+    dlsym_CRYPTO_free(lock_cs);
   }
-
-  dlsym_CRYPTO_free(lock_cs);
 }
 
-static void pthreads_locking_callback(int mode, int type, char *file, int line)
+static void windows_locking_callback(int mode, int type, char *file, int line)
 {
   UNUSED(file), UNUSED(line);
 
   if (mode & CRYPTO_LOCK) {
-    pthread_mutex_lock(&(lock_cs[type]));
+    WaitForSingleObject(lock_cs[type], INFINITE);
   } else {
-    pthread_mutex_unlock(&(lock_cs[type]));
+    ReleaseMutex(lock_cs[type]);
   }
 }
-
-static unsigned long pthreads_thread_id(void)
-{
-  return (unsigned long)syscall(SYS_gettid);
-}
-
-#endif /* UNIX */
+#endif /* WINDOWS */
 
 /**
  * If using an Intel chipset with RDRAND, the high-performance hardware
  * random number generator will be used.
  */
-static ENGINE * openssl_rand_init(JNIEnv *env)
+static ENGINE * openssl_rand_init(void)
 {
   if (dlsym_OpenSSL_version_num() < VERSION_1_1_X) {
-    locks_setup(env);
-    static void (*dlsym_ENGINE_load_rdrand) (void);
-    dlsym_ENGINE_load_rdrand = do_dlsym(env, openssl, "ENGINE_load_rdrand");
+    locks_setup();
     dlsym_ENGINE_load_rdrand();
   }
 
@@ -311,27 +311,23 @@ static ENGINE * openssl_rand_init(JNIEnv *env)
   } while(0);
 
   if (ret == -1) {
-    openssl_rand_clean(env, eng, 0);
+    openssl_rand_clean(eng, 0);
   }
 
   return eng;
 }
 
-static void openssl_rand_clean(JNIEnv *env, ENGINE *eng, int clean_locks)
+static void openssl_rand_clean(ENGINE *eng, int clean_locks)
 {
   if (NULL != eng) {
     dlsym_ENGINE_finish(eng);
     dlsym_ENGINE_free(eng);
-  }
 
-  if (dlsym_OpenSSL_version_num() < VERSION_1_1_X) {
-    static void (*dlsym_ENGINE_cleanup) (void);
-    if((dlsym_ENGINE_cleanup = do_dlsym(env, openssl, "ENGINE_cleanup")) == NULL) {
-	THROW(env, "java/lang/UnsatisfiedLinkError", "ENGINE_cleanup");
-    }
-    dlsym_ENGINE_cleanup();
-    if (clean_locks) {
-      locks_cleanup(env);
+    if (dlsym_OpenSSL_version_num() < VERSION_1_1_X) {
+      dlsym_ENGINE_cleanup();
+      if (clean_locks) {
+        locks_cleanup();
+      }
     }
   }
 }