You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2016/06/30 16:31:07 UTC

[1/2] commons-crypto git commit: [CRYPTO-94] Consistently camel-case type names: OpenSsl* (native and more)

Repository: commons-crypto
Updated Branches:
  refs/heads/master 859bdaa04 -> 4a19325fd


http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/main/native/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.c
----------------------------------------------------------------------
diff --git a/src/main/native/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.c b/src/main/native/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.c
new file mode 100644
index 0000000..07dd4f9
--- /dev/null
+++ b/src/main/native/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.c
@@ -0,0 +1,340 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "org_apache_commons_crypto_random.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef UNIX
+#include <pthread.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#endif
+
+#ifdef WINDOWS
+#include <windows.h>
+#endif
+
+// export the native interfaces
+#ifdef JNIEXPORT
+#undef JNIEXPORT
+#endif
+#define JNIEXPORT __attribute__((__visibility__("default")))
+#include "OpenSslCryptoRandomNative.h"
+
+#ifdef UNIX
+static void * (*dlsym_CRYPTO_malloc) (int, const char *, int);
+static void (*dlsym_CRYPTO_free) (void *);
+static int (*dlsym_CRYPTO_num_locks) (void);
+static void (*dlsym_CRYPTO_set_locking_callback) (void (*)());
+static void (*dlsym_CRYPTO_set_id_callback) (unsigned long (*)());
+static void (*dlsym_ENGINE_load_rdrand) (void);
+static ENGINE * (*dlsym_ENGINE_by_id) (const char *);
+static int (*dlsym_ENGINE_init) (ENGINE *);
+static int (*dlsym_ENGINE_set_default) (ENGINE *, unsigned int);
+static int (*dlsym_ENGINE_finish) (ENGINE *);
+static int (*dlsym_ENGINE_free) (ENGINE *);
+static void (*dlsym_ENGINE_cleanup) (void);
+static int (*dlsym_RAND_bytes) (unsigned char *, int);
+static unsigned long (*dlsym_ERR_get_error) (void);
+#endif
+
+#ifdef WINDOWS
+typedef void * (__cdecl *__dlsym_CRYPTO_malloc) (int, const char *, int);
+typedef void (__cdecl *__dlsym_CRYPTO_free) (void *);
+typedef int (__cdecl *__dlsym_CRYPTO_num_locks) (void);
+typedef void (__cdecl *__dlsym_CRYPTO_set_locking_callback)  \
+              (void (*)(int, int, char *, int);
+typedef void (__cdecl *__dlsym_ENGINE_load_rdrand) (void);
+typedef ENGINE * (__cdecl *__dlsym_ENGINE_by_id) (const char *);
+typedef int (__cdecl *__dlsym_ENGINE_init) (ENGINE *);
+typedef int (__cdecl *__dlsym_ENGINE_set_default) (ENGINE *, unsigned int);
+typedef int (__cdecl *__dlsym_ENGINE_finish) (ENGINE *);
+typedef int (__cdecl *__dlsym_ENGINE_free) (ENGINE *);
+typedef void (__cdecl *__dlsym_ENGINE_cleanup) (void);
+typedef int (__cdecl *__dlsym_RAND_bytes) (unsigned char *, int);
+typedef unsigned long (__cdecl *__dlsym_ERR_get_error) (void);
+static __dlsym_CRYPTO_malloc dlsym_CRYPTO_malloc;
+static __dlsym_CRYPTO_free dlsym_CRYPTO_free;
+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_by_id dlsym_ENGINE_by_id;
+static __dlsym_ENGINE_init dlsym_ENGINE_init;
+static __dlsym_ENGINE_set_default dlsym_ENGINE_set_default;
+static __dlsym_ENGINE_finish dlsym_ENGINE_finish;
+static __dlsym_ENGINE_free dlsym_ENGINE_free;
+static __dlsym_ENGINE_cleanup dlsym_ENGINE_cleanup;
+static __dlsym_RAND_bytes dlsym_RAND_bytes;
+static __dlsym_ERR_get_error dlsym_ERR_get_error;
+#endif
+
+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);
+
+JNIEXPORT void JNICALL Java_org_apache_commons_crypto_random_OpenSslCryptoRandomNative_initSR
+    (JNIEnv *env, jclass clazz)
+{
+  char msg[1000];
+#ifdef UNIX
+  void *openssl = dlopen(COMMONS_CRYPTO_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
+#endif
+
+#ifdef WINDOWS
+  HMODULE openssl = LoadLibrary(COMMONS_CRYPTO_OPENSSL_LIBRARY);
+#endif
+
+  if (!openssl) {
+    snprintf(msg, sizeof(msg), "Cannot load %s (%s)!", COMMONS_CRYPTO_OPENSSL_LIBRARY,  \
+        dlerror());
+    THROW(env, "java/lang/UnsatisfiedLinkError", msg);
+    return;
+  }
+
+#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_CRYPTO_num_locks, env, openssl, "CRYPTO_num_locks");
+  LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_set_locking_callback,  \
+                      env, openssl, "CRYPTO_set_locking_callback");
+  LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_set_id_callback, env,  \
+                      openssl, "CRYPTO_set_id_callback");
+  LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_load_rdrand, env,  \
+                      openssl, "ENGINE_load_rdrand");
+  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_finish, env, openssl, "ENGINE_finish");
+  LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_free, env, openssl, "ENGINE_free");
+  LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_cleanup, env, openssl, "ENGINE_cleanup");
+  LOAD_DYNAMIC_SYMBOL(dlsym_RAND_bytes, env, openssl, "RAND_bytes");
+  LOAD_DYNAMIC_SYMBOL(dlsym_ERR_get_error, env, openssl, "ERR_get_error");
+#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_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_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_ENGINE_cleanup, dlsym_ENGINE_cleanup,  \
+                      env, openssl, "ENGINE_cleanup");
+  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");
+#endif
+
+  openssl_rand_init();
+}
+
+JNIEXPORT jboolean JNICALL Java_org_apache_commons_crypto_random_OpenSslCryptoRandomNative_nextRandBytes___3B
+    (JNIEnv *env, jobject object, jbyteArray bytes)
+{
+  if (NULL == bytes) {
+    THROW(env, "java/lang/NullPointerException", "Buffer cannot be null.");
+    return JNI_FALSE;
+  }
+  jbyte *b = (*env)->GetByteArrayElements(env, bytes, NULL);
+  if (NULL == b) {
+    THROW(env, "java/lang/InternalError", "Cannot get bytes array.");
+    return JNI_FALSE;
+  }
+  int b_len = (*env)->GetArrayLength(env, bytes);
+  int ret = openssl_rand_bytes((unsigned char *)b, b_len);
+  (*env)->ReleaseByteArrayElements(env, bytes, b, 0);
+
+  if (1 != ret) {
+    return JNI_FALSE;
+  }
+  return JNI_TRUE;
+}
+
+/**
+ * To ensure thread safety for random number generators, we need to call
+ * CRYPTO_set_locking_callback.
+ * http://wiki.openssl.org/index.php/Random_Numbers
+ * Example: crypto/threads/mttest.c
+ */
+
+#ifdef WINDOWS
+static void windows_locking_callback(int mode, int type, char *file, int line);
+static HANDLE *lock_cs;
+
+static void locks_setup(void)
+{
+  int i;
+  lock_cs = dlsym_CRYPTO_malloc(dlsym_CRYPTO_num_locks() * sizeof(HANDLE),  \
+      __FILE__, __LINE__);
+
+  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 */
+}
+
+static void locks_cleanup(void)
+{
+  int i;
+  dlsym_CRYPTO_set_locking_callback(NULL);
+
+  for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) {
+    CloseHandle(lock_cs[i]);
+  }
+  dlsym_CRYPTO_free(lock_cs);
+}
+
+static void windows_locking_callback(int mode, int type, char *file, int line)
+{
+  UNUSED(file), UNUSED(line);
+
+  if (mode & CRYPTO_LOCK) {
+    WaitForSingleObject(lock_cs[type], INFINITE);
+  } else {
+    ReleaseMutex(lock_cs[type]);
+  }
+}
+#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(void)
+{
+  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++) {
+    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);
+}
+
+static void locks_cleanup(void)
+{
+  int i;
+  dlsym_CRYPTO_set_locking_callback(NULL);
+
+  for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) {
+    pthread_mutex_destroy(&(lock_cs[i]));
+  }
+
+  dlsym_CRYPTO_free(lock_cs);
+}
+
+static void pthreads_locking_callback(int mode, int type, char *file, int line)
+{
+  UNUSED(file), UNUSED(line);
+
+  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);
+}
+
+#endif /* UNIX */
+
+/**
+ * If using an Intel chipset with RDRAND, the high-performance hardware
+ * random number generator will be used.
+ */
+static ENGINE * openssl_rand_init(void)
+{
+  locks_setup();
+
+  dlsym_ENGINE_load_rdrand();
+  ENGINE *eng = dlsym_ENGINE_by_id("rdrand");
+
+  int ret = -1;
+  do {
+    if (NULL == eng) {
+      break;
+    }
+
+    int rc = dlsym_ENGINE_init(eng);
+    if (0 == rc) {
+      break;
+    }
+
+    rc = dlsym_ENGINE_set_default(eng, ENGINE_METHOD_RAND);
+    if (0 == rc) {
+      break;
+    }
+
+    ret = 0;
+  } while(0);
+
+  if (ret == -1) {
+    openssl_rand_clean(eng, 0);
+  }
+
+  return eng;
+}
+
+static void openssl_rand_clean(ENGINE *eng, int clean_locks)
+{
+  if (NULL != eng) {
+    dlsym_ENGINE_finish(eng);
+    dlsym_ENGINE_free(eng);
+  }
+
+  dlsym_ENGINE_cleanup();
+  if (clean_locks) {
+    locks_cleanup();
+  }
+}
+
+static int openssl_rand_bytes(unsigned char *buf, int num)
+{
+  return dlsym_RAND_bytes(buf, num);
+}

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/main/native/org/apache/commons/crypto/random/OpensslCryptoRandomNative.c
----------------------------------------------------------------------
diff --git a/src/main/native/org/apache/commons/crypto/random/OpensslCryptoRandomNative.c b/src/main/native/org/apache/commons/crypto/random/OpensslCryptoRandomNative.c
deleted file mode 100644
index 09c9af4..0000000
--- a/src/main/native/org/apache/commons/crypto/random/OpensslCryptoRandomNative.c
+++ /dev/null
@@ -1,340 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "org_apache_commons_crypto_random.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifdef UNIX
-#include <pthread.h>
-#include <unistd.h>
-#include <sys/syscall.h>
-#include <sys/types.h>
-#endif
-
-#ifdef WINDOWS
-#include <windows.h>
-#endif
-
-// export the native interfaces
-#ifdef JNIEXPORT
-#undef JNIEXPORT
-#endif
-#define JNIEXPORT __attribute__((__visibility__("default")))
-#include "OpensslCryptoRandomNative.h"
-
-#ifdef UNIX
-static void * (*dlsym_CRYPTO_malloc) (int, const char *, int);
-static void (*dlsym_CRYPTO_free) (void *);
-static int (*dlsym_CRYPTO_num_locks) (void);
-static void (*dlsym_CRYPTO_set_locking_callback) (void (*)());
-static void (*dlsym_CRYPTO_set_id_callback) (unsigned long (*)());
-static void (*dlsym_ENGINE_load_rdrand) (void);
-static ENGINE * (*dlsym_ENGINE_by_id) (const char *);
-static int (*dlsym_ENGINE_init) (ENGINE *);
-static int (*dlsym_ENGINE_set_default) (ENGINE *, unsigned int);
-static int (*dlsym_ENGINE_finish) (ENGINE *);
-static int (*dlsym_ENGINE_free) (ENGINE *);
-static void (*dlsym_ENGINE_cleanup) (void);
-static int (*dlsym_RAND_bytes) (unsigned char *, int);
-static unsigned long (*dlsym_ERR_get_error) (void);
-#endif
-
-#ifdef WINDOWS
-typedef void * (__cdecl *__dlsym_CRYPTO_malloc) (int, const char *, int);
-typedef void (__cdecl *__dlsym_CRYPTO_free) (void *);
-typedef int (__cdecl *__dlsym_CRYPTO_num_locks) (void);
-typedef void (__cdecl *__dlsym_CRYPTO_set_locking_callback)  \
-              (void (*)(int, int, char *, int);
-typedef void (__cdecl *__dlsym_ENGINE_load_rdrand) (void);
-typedef ENGINE * (__cdecl *__dlsym_ENGINE_by_id) (const char *);
-typedef int (__cdecl *__dlsym_ENGINE_init) (ENGINE *);
-typedef int (__cdecl *__dlsym_ENGINE_set_default) (ENGINE *, unsigned int);
-typedef int (__cdecl *__dlsym_ENGINE_finish) (ENGINE *);
-typedef int (__cdecl *__dlsym_ENGINE_free) (ENGINE *);
-typedef void (__cdecl *__dlsym_ENGINE_cleanup) (void);
-typedef int (__cdecl *__dlsym_RAND_bytes) (unsigned char *, int);
-typedef unsigned long (__cdecl *__dlsym_ERR_get_error) (void);
-static __dlsym_CRYPTO_malloc dlsym_CRYPTO_malloc;
-static __dlsym_CRYPTO_free dlsym_CRYPTO_free;
-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_by_id dlsym_ENGINE_by_id;
-static __dlsym_ENGINE_init dlsym_ENGINE_init;
-static __dlsym_ENGINE_set_default dlsym_ENGINE_set_default;
-static __dlsym_ENGINE_finish dlsym_ENGINE_finish;
-static __dlsym_ENGINE_free dlsym_ENGINE_free;
-static __dlsym_ENGINE_cleanup dlsym_ENGINE_cleanup;
-static __dlsym_RAND_bytes dlsym_RAND_bytes;
-static __dlsym_ERR_get_error dlsym_ERR_get_error;
-#endif
-
-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);
-
-JNIEXPORT void JNICALL Java_org_apache_commons_crypto_random_OpensslCryptoRandomNative_initSR
-    (JNIEnv *env, jclass clazz)
-{
-  char msg[1000];
-#ifdef UNIX
-  void *openssl = dlopen(COMMONS_CRYPTO_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
-#endif
-
-#ifdef WINDOWS
-  HMODULE openssl = LoadLibrary(COMMONS_CRYPTO_OPENSSL_LIBRARY);
-#endif
-
-  if (!openssl) {
-    snprintf(msg, sizeof(msg), "Cannot load %s (%s)!", COMMONS_CRYPTO_OPENSSL_LIBRARY,  \
-        dlerror());
-    THROW(env, "java/lang/UnsatisfiedLinkError", msg);
-    return;
-  }
-
-#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_CRYPTO_num_locks, env, openssl, "CRYPTO_num_locks");
-  LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_set_locking_callback,  \
-                      env, openssl, "CRYPTO_set_locking_callback");
-  LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_set_id_callback, env,  \
-                      openssl, "CRYPTO_set_id_callback");
-  LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_load_rdrand, env,  \
-                      openssl, "ENGINE_load_rdrand");
-  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_finish, env, openssl, "ENGINE_finish");
-  LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_free, env, openssl, "ENGINE_free");
-  LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_cleanup, env, openssl, "ENGINE_cleanup");
-  LOAD_DYNAMIC_SYMBOL(dlsym_RAND_bytes, env, openssl, "RAND_bytes");
-  LOAD_DYNAMIC_SYMBOL(dlsym_ERR_get_error, env, openssl, "ERR_get_error");
-#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_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_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_ENGINE_cleanup, dlsym_ENGINE_cleanup,  \
-                      env, openssl, "ENGINE_cleanup");
-  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");
-#endif
-
-  openssl_rand_init();
-}
-
-JNIEXPORT jboolean JNICALL Java_org_apache_commons_crypto_random_OpensslCryptoRandomNative_nextRandBytes___3B
-    (JNIEnv *env, jobject object, jbyteArray bytes)
-{
-  if (NULL == bytes) {
-    THROW(env, "java/lang/NullPointerException", "Buffer cannot be null.");
-    return JNI_FALSE;
-  }
-  jbyte *b = (*env)->GetByteArrayElements(env, bytes, NULL);
-  if (NULL == b) {
-    THROW(env, "java/lang/InternalError", "Cannot get bytes array.");
-    return JNI_FALSE;
-  }
-  int b_len = (*env)->GetArrayLength(env, bytes);
-  int ret = openssl_rand_bytes((unsigned char *)b, b_len);
-  (*env)->ReleaseByteArrayElements(env, bytes, b, 0);
-
-  if (1 != ret) {
-    return JNI_FALSE;
-  }
-  return JNI_TRUE;
-}
-
-/**
- * To ensure thread safety for random number generators, we need to call
- * CRYPTO_set_locking_callback.
- * http://wiki.openssl.org/index.php/Random_Numbers
- * Example: crypto/threads/mttest.c
- */
-
-#ifdef WINDOWS
-static void windows_locking_callback(int mode, int type, char *file, int line);
-static HANDLE *lock_cs;
-
-static void locks_setup(void)
-{
-  int i;
-  lock_cs = dlsym_CRYPTO_malloc(dlsym_CRYPTO_num_locks() * sizeof(HANDLE),  \
-      __FILE__, __LINE__);
-
-  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 */
-}
-
-static void locks_cleanup(void)
-{
-  int i;
-  dlsym_CRYPTO_set_locking_callback(NULL);
-
-  for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) {
-    CloseHandle(lock_cs[i]);
-  }
-  dlsym_CRYPTO_free(lock_cs);
-}
-
-static void windows_locking_callback(int mode, int type, char *file, int line)
-{
-  UNUSED(file), UNUSED(line);
-
-  if (mode & CRYPTO_LOCK) {
-    WaitForSingleObject(lock_cs[type], INFINITE);
-  } else {
-    ReleaseMutex(lock_cs[type]);
-  }
-}
-#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(void)
-{
-  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++) {
-    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);
-}
-
-static void locks_cleanup(void)
-{
-  int i;
-  dlsym_CRYPTO_set_locking_callback(NULL);
-
-  for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) {
-    pthread_mutex_destroy(&(lock_cs[i]));
-  }
-
-  dlsym_CRYPTO_free(lock_cs);
-}
-
-static void pthreads_locking_callback(int mode, int type, char *file, int line)
-{
-  UNUSED(file), UNUSED(line);
-
-  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);
-}
-
-#endif /* UNIX */
-
-/**
- * If using an Intel chipset with RDRAND, the high-performance hardware
- * random number generator will be used.
- */
-static ENGINE * openssl_rand_init(void)
-{
-  locks_setup();
-
-  dlsym_ENGINE_load_rdrand();
-  ENGINE *eng = dlsym_ENGINE_by_id("rdrand");
-
-  int ret = -1;
-  do {
-    if (NULL == eng) {
-      break;
-    }
-
-    int rc = dlsym_ENGINE_init(eng);
-    if (0 == rc) {
-      break;
-    }
-
-    rc = dlsym_ENGINE_set_default(eng, ENGINE_METHOD_RAND);
-    if (0 == rc) {
-      break;
-    }
-
-    ret = 0;
-  } while(0);
-
-  if (ret == -1) {
-    openssl_rand_clean(eng, 0);
-  }
-
-  return eng;
-}
-
-static void openssl_rand_clean(ENGINE *eng, int clean_locks)
-{
-  if (NULL != eng) {
-    dlsym_ENGINE_finish(eng);
-    dlsym_ENGINE_free(eng);
-  }
-
-  dlsym_ENGINE_cleanup();
-  if (clean_locks) {
-    locks_cleanup();
-  }
-}
-
-static int openssl_rand_bytes(unsigned char *buf, int num)
-{
-  return dlsym_RAND_bytes(buf, num);
-}

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/test/java/org/apache/commons/crypto/cipher/AbstractCipherTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/crypto/cipher/AbstractCipherTest.java b/src/test/java/org/apache/commons/crypto/cipher/AbstractCipherTest.java
index 9f5f3f3..11908a1 100644
--- a/src/test/java/org/apache/commons/crypto/cipher/AbstractCipherTest.java
+++ b/src/test/java/org/apache/commons/crypto/cipher/AbstractCipherTest.java
@@ -31,7 +31,7 @@ import javax.crypto.spec.SecretKeySpec;
 import javax.xml.bind.DatatypeConverter;
 
 import org.apache.commons.crypto.conf.ConfigurationKeys;
-import org.apache.commons.crypto.jna.OpensslJna;
+import org.apache.commons.crypto.jna.OpenSslJna;
 import org.apache.commons.crypto.utils.ReflectionUtils;
 import org.apache.commons.crypto.utils.Utils;
 import org.junit.Assert;
@@ -44,7 +44,7 @@ public abstract class AbstractCipherTest {
 
     public static final String JCE_CIPHER_CLASSNAME = JceCipher.class.getName();
 
-    public static final String OPENSSLJNA_CIPHER_CLASSNAME = OpensslJna.getCipherClass().getName();
+    public static final String OPENSSLJNA_CIPHER_CLASSNAME = OpenSslJna.getCipherClass().getName();
 
     // data
     public static final int BYTEBUFFER_SIZE = 1000;

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/test/java/org/apache/commons/crypto/cipher/OpenSslCipherTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/crypto/cipher/OpenSslCipherTest.java b/src/test/java/org/apache/commons/crypto/cipher/OpenSslCipherTest.java
new file mode 100644
index 0000000..d144228
--- /dev/null
+++ b/src/test/java/org/apache/commons/crypto/cipher/OpenSslCipherTest.java
@@ -0,0 +1,175 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.crypto.cipher;
+
+import java.nio.ByteBuffer;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.ShortBufferException;
+
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Test;
+
+public class OpenSslCipherTest extends AbstractCipherTest {
+
+    @Override
+    public void init() {
+        transformations = new String[] {
+                "AES/CBC/NoPadding",
+                "AES/CBC/PKCS5Padding",
+                "AES/CTR/NoPadding"};
+        cipherClass = OPENSSL_CIPHER_CLASSNAME;
+    }
+
+    @Test(expected = NoSuchAlgorithmException.class, timeout = 120000)
+    public void testInvalidAlgorithm() throws Exception {
+        Assume.assumeTrue(OpenSsl.getLoadingFailureReason() == null);
+
+        try {
+            OpenSsl.getInstance("AES2/CTR/NoPadding");
+            Assert.fail("Should specify correct algorithm.");
+        } catch (NoSuchAlgorithmException e) {
+            Assert.assertTrue(e.getMessage().contains(
+                    "Doesn't support algorithm: AES2 and mode: CTR"));
+            throw e;
+        }
+    }
+
+    @Test(expected = NoSuchPaddingException.class, timeout = 120000)
+    public void testInvalidPadding() throws Exception {
+        Assume.assumeTrue(OpenSsl.getLoadingFailureReason() == null);
+
+        try {
+            OpenSsl.getInstance("AES/CTR/NoPadding2");
+            Assert.fail("Should specify correct padding.");
+        } catch (NoSuchPaddingException e) {
+            Assert.assertTrue(e.getMessage().contains(
+                    "Doesn't support padding: NoPadding2"));
+            throw e;
+        }
+    }
+
+    @Test(expected = NoSuchAlgorithmException.class, timeout = 120000)
+    public void testInvalidMode() throws Exception {
+        try {
+            Assume.assumeTrue(OpenSsl.getLoadingFailureReason() == null);
+            OpenSsl.getInstance("AES/CTR2/NoPadding");
+            Assert.fail("java.security.NoSuchAlgorithmException should be thrown.");
+        } catch (NoSuchAlgorithmException e) {
+            Assert.assertTrue(e.getMessage().contains(
+                    "Doesn't support algorithm: AES and mode: CTR2"));
+            throw e;
+        }
+    }
+
+    @Test(timeout = 120000)
+    public void testUpdateArguments() throws Exception {
+        Assume.assumeTrue(OpenSsl.getLoadingFailureReason() == null);
+        OpenSsl cipher = OpenSsl
+                .getInstance("AES/CTR/NoPadding");
+        Assert.assertNotNull(cipher);
+
+        cipher.init(OpenSsl.ENCRYPT_MODE, KEY, IV);
+
+        // Require direct buffers
+        ByteBuffer input = ByteBuffer.allocate(1024);
+        ByteBuffer output = ByteBuffer.allocate(1024);
+
+        try {
+            cipher.update(input, output);
+            Assert.fail("Input and output buffer should be direct buffer.");
+        } catch (IllegalArgumentException e) {
+            Assert.assertTrue(e.getMessage().contains(
+                    "Direct buffers are required"));
+        }
+
+        // Output buffer length should be sufficient to store output data
+        input = ByteBuffer.allocateDirect(1024);
+        output = ByteBuffer.allocateDirect(1000);
+        try {
+            cipher.update(input, output);
+            Assert.fail("Output buffer length should be sufficient "
+                    + "to store output data");
+        } catch (ShortBufferException e) {
+            Assert.assertTrue(e.getMessage().contains(
+                    "Output buffer is not sufficient"));
+        }
+    }
+
+    @Test(timeout = 120000)
+    public void testDoFinalArguments() throws Exception {
+        Assume.assumeTrue(OpenSsl.getLoadingFailureReason() == null);
+        OpenSsl cipher = OpenSsl
+                .getInstance("AES/CTR/NoPadding");
+        Assert.assertNotNull(cipher);
+
+        cipher.init(OpenSsl.ENCRYPT_MODE, KEY, IV);
+
+        // Require direct buffer
+        ByteBuffer output = ByteBuffer.allocate(1024);
+
+        try {
+            cipher.doFinal(output);
+            Assert.fail("Output buffer should be direct buffer.");
+        } catch (IllegalArgumentException e) {
+            Assert.assertTrue(e.getMessage().contains(
+                    "Direct buffer is required"));
+        }
+    }
+
+    @Test(expected = InvalidKeyException.class, timeout = 120000)
+    public void testInvalidKey() throws Exception {
+        Assume.assumeTrue(OpenSsl.getLoadingFailureReason() == null);
+        OpenSsl cipher = OpenSsl
+                .getInstance("AES/CTR/NoPadding");
+        Assert.assertNotNull(cipher);
+
+        final byte[] invalidKey = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+                0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x11 };
+        try {
+            cipher.init(OpenSsl.ENCRYPT_MODE, invalidKey, IV);
+            Assert.fail("java.security.InvalidKeyException should be thrown.");
+        } catch (Exception e) {
+            Assert.assertTrue(e.getMessage().contains("Invalid AES key length: " + invalidKey.length + " bytes"));
+            throw e;
+        }
+    }
+
+    @Test(expected = InvalidAlgorithmParameterException.class, timeout = 120000)
+    public void testInvalidIV() throws Exception {
+        Assume.assumeTrue(OpenSsl.getLoadingFailureReason() == null);
+        OpenSsl cipher = OpenSsl
+                .getInstance("AES/CTR/NoPadding");
+        Assert.assertNotNull(cipher);
+
+        final byte[] invalidIV = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+                0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x11 };
+        try {
+            cipher.init(OpenSsl.ENCRYPT_MODE, KEY, invalidIV);
+            Assert.fail("java.security.InvalidAlgorithmParameterException should be thrown.");
+        } catch (Exception e) {
+            Assert.assertTrue(e.getMessage().contains("Wrong IV length: must be 16 bytes long"));
+            throw e;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/test/java/org/apache/commons/crypto/cipher/OpensslCipherTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/crypto/cipher/OpensslCipherTest.java b/src/test/java/org/apache/commons/crypto/cipher/OpensslCipherTest.java
deleted file mode 100644
index c5f0497..0000000
--- a/src/test/java/org/apache/commons/crypto/cipher/OpensslCipherTest.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.commons.crypto.cipher;
-
-import java.nio.ByteBuffer;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.ShortBufferException;
-
-import org.junit.Assert;
-import org.junit.Assume;
-import org.junit.Test;
-
-public class OpensslCipherTest extends AbstractCipherTest {
-
-    @Override
-    public void init() {
-        transformations = new String[] {
-                "AES/CBC/NoPadding",
-                "AES/CBC/PKCS5Padding",
-                "AES/CTR/NoPadding"};
-        cipherClass = OPENSSL_CIPHER_CLASSNAME;
-    }
-
-    @Test(expected = NoSuchAlgorithmException.class, timeout = 120000)
-    public void testInvalidAlgorithm() throws Exception {
-        Assume.assumeTrue(OpenSsl.getLoadingFailureReason() == null);
-
-        try {
-            OpenSsl.getInstance("AES2/CTR/NoPadding");
-            Assert.fail("Should specify correct algorithm.");
-        } catch (NoSuchAlgorithmException e) {
-            Assert.assertTrue(e.getMessage().contains(
-                    "Doesn't support algorithm: AES2 and mode: CTR"));
-            throw e;
-        }
-    }
-
-    @Test(expected = NoSuchPaddingException.class, timeout = 120000)
-    public void testInvalidPadding() throws Exception {
-        Assume.assumeTrue(OpenSsl.getLoadingFailureReason() == null);
-
-        try {
-            OpenSsl.getInstance("AES/CTR/NoPadding2");
-            Assert.fail("Should specify correct padding.");
-        } catch (NoSuchPaddingException e) {
-            Assert.assertTrue(e.getMessage().contains(
-                    "Doesn't support padding: NoPadding2"));
-            throw e;
-        }
-    }
-
-    @Test(expected = NoSuchAlgorithmException.class, timeout = 120000)
-    public void testInvalidMode() throws Exception {
-        try {
-            Assume.assumeTrue(OpenSsl.getLoadingFailureReason() == null);
-            OpenSsl.getInstance("AES/CTR2/NoPadding");
-            Assert.fail("java.security.NoSuchAlgorithmException should be thrown.");
-        } catch (NoSuchAlgorithmException e) {
-            Assert.assertTrue(e.getMessage().contains(
-                    "Doesn't support algorithm: AES and mode: CTR2"));
-            throw e;
-        }
-    }
-
-    @Test(timeout = 120000)
-    public void testUpdateArguments() throws Exception {
-        Assume.assumeTrue(OpenSsl.getLoadingFailureReason() == null);
-        OpenSsl cipher = OpenSsl
-                .getInstance("AES/CTR/NoPadding");
-        Assert.assertNotNull(cipher);
-
-        cipher.init(OpenSsl.ENCRYPT_MODE, KEY, IV);
-
-        // Require direct buffers
-        ByteBuffer input = ByteBuffer.allocate(1024);
-        ByteBuffer output = ByteBuffer.allocate(1024);
-
-        try {
-            cipher.update(input, output);
-            Assert.fail("Input and output buffer should be direct buffer.");
-        } catch (IllegalArgumentException e) {
-            Assert.assertTrue(e.getMessage().contains(
-                    "Direct buffers are required"));
-        }
-
-        // Output buffer length should be sufficient to store output data
-        input = ByteBuffer.allocateDirect(1024);
-        output = ByteBuffer.allocateDirect(1000);
-        try {
-            cipher.update(input, output);
-            Assert.fail("Output buffer length should be sufficient "
-                    + "to store output data");
-        } catch (ShortBufferException e) {
-            Assert.assertTrue(e.getMessage().contains(
-                    "Output buffer is not sufficient"));
-        }
-    }
-
-    @Test(timeout = 120000)
-    public void testDoFinalArguments() throws Exception {
-        Assume.assumeTrue(OpenSsl.getLoadingFailureReason() == null);
-        OpenSsl cipher = OpenSsl
-                .getInstance("AES/CTR/NoPadding");
-        Assert.assertNotNull(cipher);
-
-        cipher.init(OpenSsl.ENCRYPT_MODE, KEY, IV);
-
-        // Require direct buffer
-        ByteBuffer output = ByteBuffer.allocate(1024);
-
-        try {
-            cipher.doFinal(output);
-            Assert.fail("Output buffer should be direct buffer.");
-        } catch (IllegalArgumentException e) {
-            Assert.assertTrue(e.getMessage().contains(
-                    "Direct buffer is required"));
-        }
-    }
-
-    @Test(expected = InvalidKeyException.class, timeout = 120000)
-    public void testInvalidKey() throws Exception {
-        Assume.assumeTrue(OpenSsl.getLoadingFailureReason() == null);
-        OpenSsl cipher = OpenSsl
-                .getInstance("AES/CTR/NoPadding");
-        Assert.assertNotNull(cipher);
-
-        final byte[] invalidKey = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
-                0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x11 };
-        try {
-            cipher.init(OpenSsl.ENCRYPT_MODE, invalidKey, IV);
-            Assert.fail("java.security.InvalidKeyException should be thrown.");
-        } catch (Exception e) {
-            Assert.assertTrue(e.getMessage().contains("Invalid AES key length: " + invalidKey.length + " bytes"));
-            throw e;
-        }
-    }
-
-    @Test(expected = InvalidAlgorithmParameterException.class, timeout = 120000)
-    public void testInvalidIV() throws Exception {
-        Assume.assumeTrue(OpenSsl.getLoadingFailureReason() == null);
-        OpenSsl cipher = OpenSsl
-                .getInstance("AES/CTR/NoPadding");
-        Assert.assertNotNull(cipher);
-
-        final byte[] invalidIV = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
-                0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x11 };
-        try {
-            cipher.init(OpenSsl.ENCRYPT_MODE, KEY, invalidIV);
-            Assert.fail("java.security.InvalidAlgorithmParameterException should be thrown.");
-        } catch (Exception e) {
-            Assert.assertTrue(e.getMessage().contains("Wrong IV length: must be 16 bytes long"));
-            throw e;
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/test/java/org/apache/commons/crypto/jna/OpenSslJnaCipherTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/crypto/jna/OpenSslJnaCipherTest.java b/src/test/java/org/apache/commons/crypto/jna/OpenSslJnaCipherTest.java
new file mode 100644
index 0000000..6f5990a
--- /dev/null
+++ b/src/test/java/org/apache/commons/crypto/jna/OpenSslJnaCipherTest.java
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.crypto.jna;
+
+import org.apache.commons.crypto.cipher.AbstractCipherTest;
+import org.apache.commons.crypto.jna.OpenSslJnaCipher;
+
+public class OpenSslJnaCipherTest extends AbstractCipherTest {
+
+    @Override
+    public void init() {
+        transformations = new String[] {
+                "AES/CBC/NoPadding",
+                "AES/CBC/PKCS5Padding",
+                "AES/CTR/NoPadding"
+                };
+        cipherClass = OpenSslJnaCipher.class.getName();
+    }
+
+    @Override
+    public void closeTestRepeat() {
+        System.err.println("closeTestRepeat() Causes JVM crash");
+    }
+
+    @Override
+    public void reInitAfterClose() {
+        System.err.println("reInitAfterClose() Causes JVM crash");
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/test/java/org/apache/commons/crypto/jna/OpenSslJnaCryptoRandomTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/crypto/jna/OpenSslJnaCryptoRandomTest.java b/src/test/java/org/apache/commons/crypto/jna/OpenSslJnaCryptoRandomTest.java
new file mode 100644
index 0000000..990bfd2
--- /dev/null
+++ b/src/test/java/org/apache/commons/crypto/jna/OpenSslJnaCryptoRandomTest.java
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.crypto.jna;
+
+import java.security.GeneralSecurityException;
+import java.util.Properties;
+
+import org.apache.commons.crypto.conf.ConfigurationKeys;
+import org.apache.commons.crypto.jna.OpenSslJnaCryptoRandom;
+import org.apache.commons.crypto.random.AbstractRandomTest;
+import org.apache.commons.crypto.random.CryptoRandom;
+import org.apache.commons.crypto.random.CryptoRandomFactory;
+
+import static org.junit.Assert.fail;
+
+public class OpenSslJnaCryptoRandomTest extends AbstractRandomTest {
+
+    @Override
+    public CryptoRandom getCryptoRandom() throws GeneralSecurityException {
+        Properties props = new Properties();
+        props.setProperty(
+                ConfigurationKeys.SECURE_RANDOM_CLASSES_KEY,
+                OpenSslJnaCryptoRandom.class.getName());
+        CryptoRandom random = CryptoRandomFactory.getCryptoRandom(props);
+        if (!(random instanceof OpenSslJnaCryptoRandom)) {
+            fail("The CryptoRandom should be: "
+                    + OpenSslJnaCryptoRandom.class.getName());
+        }
+        return random;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/test/java/org/apache/commons/crypto/jna/OpensslJnaCipherTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/crypto/jna/OpensslJnaCipherTest.java b/src/test/java/org/apache/commons/crypto/jna/OpensslJnaCipherTest.java
deleted file mode 100644
index 30b7fde..0000000
--- a/src/test/java/org/apache/commons/crypto/jna/OpensslJnaCipherTest.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.commons.crypto.jna;
-
-import org.apache.commons.crypto.cipher.AbstractCipherTest;
-import org.apache.commons.crypto.jna.OpenSslJnaCipher;
-
-public class OpensslJnaCipherTest extends AbstractCipherTest {
-
-    @Override
-    public void init() {
-        transformations = new String[] {
-                "AES/CBC/NoPadding",
-                "AES/CBC/PKCS5Padding",
-                "AES/CTR/NoPadding"
-                };
-        cipherClass = OpenSslJnaCipher.class.getName();
-    }
-
-    @Override
-    public void closeTestRepeat() {
-        System.err.println("closeTestRepeat() Causes JVM crash");
-    }
-
-    @Override
-    public void reInitAfterClose() {
-        System.err.println("reInitAfterClose() Causes JVM crash");
-    }
-}

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/test/java/org/apache/commons/crypto/jna/OpensslJnaCryptoRandomTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/crypto/jna/OpensslJnaCryptoRandomTest.java b/src/test/java/org/apache/commons/crypto/jna/OpensslJnaCryptoRandomTest.java
deleted file mode 100644
index 550b4a6..0000000
--- a/src/test/java/org/apache/commons/crypto/jna/OpensslJnaCryptoRandomTest.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.crypto.jna;
-
-import java.security.GeneralSecurityException;
-import java.util.Properties;
-
-import org.apache.commons.crypto.conf.ConfigurationKeys;
-import org.apache.commons.crypto.jna.OpenSslJnaCryptoRandom;
-import org.apache.commons.crypto.random.AbstractRandomTest;
-import org.apache.commons.crypto.random.CryptoRandom;
-import org.apache.commons.crypto.random.CryptoRandomFactory;
-
-import static org.junit.Assert.fail;
-
-public class OpensslJnaCryptoRandomTest extends AbstractRandomTest {
-
-    @Override
-    public CryptoRandom getCryptoRandom() throws GeneralSecurityException {
-        Properties props = new Properties();
-        props.setProperty(
-                ConfigurationKeys.SECURE_RANDOM_CLASSES_KEY,
-                OpenSslJnaCryptoRandom.class.getName());
-        CryptoRandom random = CryptoRandomFactory.getCryptoRandom(props);
-        if (!(random instanceof OpenSslJnaCryptoRandom)) {
-            fail("The CryptoRandom should be: "
-                    + OpenSslJnaCryptoRandom.class.getName());
-        }
-        return random;
-    }
-
-}


[2/2] commons-crypto git commit: [CRYPTO-94] Consistently camel-case type names: OpenSsl* (native and more)

Posted by gg...@apache.org.
[CRYPTO-94] Consistently camel-case type names: OpenSsl* (native and
more)

Project: http://git-wip-us.apache.org/repos/asf/commons-crypto/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-crypto/commit/4a19325f
Tree: http://git-wip-us.apache.org/repos/asf/commons-crypto/tree/4a19325f
Diff: http://git-wip-us.apache.org/repos/asf/commons-crypto/diff/4a19325f

Branch: refs/heads/master
Commit: 4a19325fdffef571cadd05000e8a2e9c376cd6af
Parents: 859bdaa
Author: Gary Gregory <gg...@apache.org>
Authored: Thu Jun 30 09:31:02 2016 -0700
Committer: Gary Gregory <gg...@apache.org>
Committed: Thu Jun 30 09:31:02 2016 -0700

----------------------------------------------------------------------
 Makefile                                        |  14 +-
 .../apache/commons/crypto/cipher/OpenSsl.java   |  16 +-
 .../commons/crypto/cipher/OpenSslNative.java    | 128 +++++
 .../commons/crypto/cipher/OpensslNative.java    | 128 -----
 .../apache/commons/crypto/jna/OpenSslJna.java   |  35 ++
 .../commons/crypto/jna/OpenSslJnaCipher.java    |  36 +-
 .../crypto/jna/OpenSslJnaCryptoRandom.java      |  24 +-
 .../apache/commons/crypto/jna/OpensslJna.java   |  35 --
 .../commons/crypto/jna/OpensslNativeJna.java    |   2 +-
 .../crypto/random/OpenSslCryptoRandom.java      |   6 +-
 .../random/OpenSslCryptoRandomNative.java       |  48 ++
 .../random/OpensslCryptoRandomNative.java       |  48 --
 .../commons/crypto/cipher/OpenSslNative.c       | 500 +++++++++++++++++++
 .../commons/crypto/cipher/OpensslNative.c       | 500 -------------------
 .../crypto/random/OpenSslCryptoRandomNative.c   | 340 +++++++++++++
 .../crypto/random/OpensslCryptoRandomNative.c   | 340 -------------
 .../crypto/cipher/AbstractCipherTest.java       |   4 +-
 .../crypto/cipher/OpenSslCipherTest.java        | 175 +++++++
 .../crypto/cipher/OpensslCipherTest.java        | 175 -------
 .../crypto/jna/OpenSslJnaCipherTest.java        |  45 ++
 .../crypto/jna/OpenSslJnaCryptoRandomTest.java  |  47 ++
 .../crypto/jna/OpensslJnaCipherTest.java        |  45 --
 .../crypto/jna/OpensslJnaCryptoRandomTest.java  |  47 --
 23 files changed, 1369 insertions(+), 1369 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/Makefile
----------------------------------------------------------------------
diff --git a/Makefile b/Makefile
index 69ce464..8d7ecdf 100644
--- a/Makefile
+++ b/Makefile
@@ -20,7 +20,7 @@ include Makefile.common
 MVN:=mvn
 
 COMMONS_CRYPTO_OUT:=$(TARGET)/$(commons-crypto)-$(os_arch)
-COMMONS_CRYPTO_OBJ:=$(addprefix $(COMMONS_CRYPTO_OUT)/,OpensslCryptoRandom.o OpensslNative.o)
+COMMONS_CRYPTO_OBJ:=$(addprefix $(COMMONS_CRYPTO_OUT)/,OpensslCryptoRandom.o OpenSslNative.o)
 
 ifeq ($(OS_NAME),SunOS)
   TAR:= gtar
@@ -33,17 +33,17 @@ NATIVE_DLL:=$(NATIVE_TARGET_DIR)/$(LIBNAME)
 
 all: $(NATIVE_DLL)
 
-$(TARGET)/jni-classes/org/apache/commons/crypto/cipher/OpensslNative.h: $(TARGET)/classes/org/apache/commons/crypto/cipher/OpensslNative.class
-	$(JAVAH) -force -classpath $(TARGET)/jni-classes:$(TARGET)/classes -o $@ org.apache.commons.crypto.cipher.OpensslNative
+$(TARGET)/jni-classes/org/apache/commons/crypto/cipher/OpenSslNative.h: $(TARGET)/classes/org/apache/commons/crypto/cipher/OpenSslNative.class
+	$(JAVAH) -force -classpath $(TARGET)/jni-classes:$(TARGET)/classes -o $@ org.apache.commons.crypto.cipher.OpenSslNative
 
-$(TARGET)/jni-classes/org/apache/commons/crypto/random/OpensslCryptoRandomNative.h: $(TARGET)/classes/org/apache/commons/crypto/random/OpensslCryptoRandomNative.class
-	$(JAVAH) -force -classpath $(TARGET)/jni-classes:$(TARGET)/classes -o $@ org.apache.commons.crypto.random.OpensslCryptoRandomNative
+$(TARGET)/jni-classes/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.h: $(TARGET)/classes/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.class
+	$(JAVAH) -force -classpath $(TARGET)/jni-classes:$(TARGET)/classes -o $@ org.apache.commons.crypto.random.OpenSslCryptoRandomNative
 
-$(COMMONS_CRYPTO_OUT)/OpensslNative.o : $(SRC_NATIVE)/org/apache/commons/crypto/cipher/OpensslNative.c $(TARGET)/jni-classes/org/apache/commons/crypto/cipher/OpensslNative.h
+$(COMMONS_CRYPTO_OUT)/OpenSslNative.o : $(SRC_NATIVE)/org/apache/commons/crypto/cipher/OpenSslNative.c $(TARGET)/jni-classes/org/apache/commons/crypto/cipher/OpenSslNative.h
 	@mkdir -p $(@D)
 	$(CC) $(CFLAGS) -c $< -o $@
 
-$(COMMONS_CRYPTO_OUT)/OpensslCryptoRandom.o : $(SRC_NATIVE)/org/apache/commons/crypto/random/OpensslCryptoRandomNative.c $(TARGET)/jni-classes/org/apache/commons/crypto/random/OpensslCryptoRandomNative.h
+$(COMMONS_CRYPTO_OUT)/OpensslCryptoRandom.o : $(SRC_NATIVE)/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.c $(TARGET)/jni-classes/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.h
 	@mkdir -p $(@D)
 	$(CC) $(CFLAGS) -c $< -o $@
 

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/main/java/org/apache/commons/crypto/cipher/OpenSsl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/cipher/OpenSsl.java b/src/main/java/org/apache/commons/crypto/cipher/OpenSsl.java
index 6c72ea5..231c3bc 100644
--- a/src/main/java/org/apache/commons/crypto/cipher/OpenSsl.java
+++ b/src/main/java/org/apache/commons/crypto/cipher/OpenSsl.java
@@ -92,7 +92,7 @@ final class OpenSsl {
         String loadingFailure = null;
         try {
             if (Crypto.isNativeCodeLoaded()) {
-                OpensslNative.initIDs();
+                OpenSslNative.initIDs();
             }
         } catch (Exception t) {
             loadingFailure = t.getMessage();
@@ -142,7 +142,7 @@ final class OpenSsl {
         int algorithmMode = AlgorithmMode.get(transform.algorithm,
                 transform.mode);
         int padding = Padding.get(transform.padding);
-        long context = OpensslNative.initContext(algorithmMode, padding);
+        long context = OpenSslNative.initContext(algorithmMode, padding);
         return new OpenSsl(context, algorithmMode, padding);
     }
 
@@ -205,7 +205,7 @@ final class OpenSsl {
      * @param iv crypto iv
      */
     public void init(int mode, byte[] key, byte[] iv) {
-        context = OpensslNative
+        context = OpenSslNative
                 .init(context, mode, algorithm, padding, key, iv);
     }
 
@@ -242,7 +242,7 @@ final class OpenSsl {
         checkState();
         Utils.checkArgument(input.isDirect() && output.isDirect(),
                 "Direct buffers are required.");
-        int len = OpensslNative.update(context, input, input.position(),
+        int len = OpenSslNative.update(context, input, input.position(),
                 input.remaining(), output, output.position(),
                 output.remaining());
         input.position(input.limit());
@@ -266,7 +266,7 @@ final class OpenSsl {
     public int update(byte[] input, int inputOffset, int inputLen,
             byte[] output, int outputOffset) throws ShortBufferException {
         checkState();
-        return OpensslNative.updateByteArray(context, input, inputOffset,
+        return OpenSslNative.updateByteArray(context, input, inputOffset,
                 inputLen, output, outputOffset, output.length - outputOffset);
     }
 
@@ -313,7 +313,7 @@ final class OpenSsl {
             IllegalBlockSizeException, BadPaddingException {
         checkState();
         Utils.checkArgument(output.isDirect(), "Direct buffer is required.");
-        int len = OpensslNative.doFinal(context, output, output.position(),
+        int len = OpenSslNative.doFinal(context, output, output.position(),
                 output.remaining());
         output.position(output.position() + len);
         return len;
@@ -341,14 +341,14 @@ final class OpenSsl {
             throws ShortBufferException, IllegalBlockSizeException,
             BadPaddingException {
         checkState();
-        return OpensslNative.doFinalByteArray(context, output, outputOffset,
+        return OpenSslNative.doFinalByteArray(context, output, outputOffset,
                 output.length - outputOffset);
     }
 
     /** Forcibly clean the context. */
     public void clean() {
         if (context != 0) {
-            OpensslNative.clean(context);
+            OpenSslNative.clean(context);
             context = 0;
         }
     }

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/main/java/org/apache/commons/crypto/cipher/OpenSslNative.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/cipher/OpenSslNative.java b/src/main/java/org/apache/commons/crypto/cipher/OpenSslNative.java
new file mode 100644
index 0000000..c73be17
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/cipher/OpenSslNative.java
@@ -0,0 +1,128 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.crypto.cipher;
+
+import java.nio.ByteBuffer;
+
+/**
+ * JNI interface of {@link OpenSsl} implementation. The native method in this
+ * class is defined in OpenSslNative.h (generated by javah).
+ */
+class OpenSslNative {
+
+  /**
+   * The private constructor of {@link OpenSslNative}.
+   */
+    private OpenSslNative() {
+    }
+
+    /**
+     * Declares a native method to initialize JNI field and method IDs.
+     */
+    public native static void initIDs();
+
+    /**
+     * Declares a native method to initialize the cipher context.
+     *
+     * @param algorithm The algorithm name of cipher
+     * @param padding The padding name of cipher
+     * @return the context address of cipher
+     */
+    public native static long initContext(int algorithm, int padding);
+
+    /**
+     * Declares a native method to initialize the cipher context.
+     *
+     * @param context The cipher context address
+     * @param mode ENCRYPT_MODE or DECRYPT_MODE
+     * @param alg Algorithm Mode of OpenSsl
+     * @param padding the padding mode of OpenSsl cipher
+     * @param key crypto key
+     * @param iv crypto iv
+     * @return the context address of cipher
+     */
+    public native static long init(long context, int mode, int alg,
+            int padding, byte[] key, byte[] iv);
+
+    /**
+     * Continues a multiple-part encryption/decryption operation. The data is
+     * encrypted or decrypted, depending on how this cipher was initialized.
+     *
+     * @param context The cipher context address
+     * @param input The input byte buffer
+     * @param inputOffset The offset in input where the input starts
+     * @param inputLength The input length
+     * @param output The byte buffer for the result
+     * @param outputOffset The offset in output where the result is stored
+     * @param maxOutputLength The maximum length for output
+     * @return The number of bytes stored in output
+     */
+    public native static int update(long context, ByteBuffer input,
+            int inputOffset, int inputLength, ByteBuffer output,
+            int outputOffset, int maxOutputLength);
+
+    /**
+     * Continues a multiple-part encryption/decryption operation. The data is
+     * encrypted or decrypted, depending on how this cipher was initialized.
+     *
+     * @param context The cipher context address
+     * @param input The input byte array
+     * @param inputOffset The offset in input where the input starts
+     * @param inputLength The input length
+     * @param output The byte array for the result
+     * @param outputOffset The offset in output where the result is stored
+     * @param maxOutputLength The maximum length for output
+     * @return The number of bytes stored in output
+     */
+    public native static int updateByteArray(long context, byte[] input,
+            int inputOffset, int inputLength, byte[] output, int outputOffset,
+            int maxOutputLength);
+
+    /**
+     * Finishes a multiple-part operation. The data is encrypted or decrypted,
+     * depending on how this cipher was initialized.
+     *
+     * @param context The cipher context address
+     * @param output The byte buffer for the result
+     * @param offset The offset in output where the result is stored
+     * @param maxOutputLength The maximum length for output
+     * @return The number of bytes stored in output
+     */
+    public native static int doFinal(long context, ByteBuffer output,
+            int offset, int maxOutputLength);
+
+    /**
+     * Finishes a multiple-part operation. The data is encrypted or decrypted,
+     * depending on how this cipher was initialized.
+     *
+     * @param context The cipher context address
+     * @param output The byte array for the result
+     * @param offset The offset in output where the result is stored
+     * @param maxOutputLength The maximum length for output
+     * @return The number of bytes stored in output
+     */
+    public native static int doFinalByteArray(long context, byte[] output,
+            int offset, int maxOutputLength);
+
+    /**
+     * Cleans the context at native.
+     *
+     * @param context The cipher context address
+     */
+    public native static void clean(long context);
+}

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/main/java/org/apache/commons/crypto/cipher/OpensslNative.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/cipher/OpensslNative.java b/src/main/java/org/apache/commons/crypto/cipher/OpensslNative.java
deleted file mode 100644
index 9bac6dd..0000000
--- a/src/main/java/org/apache/commons/crypto/cipher/OpensslNative.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.crypto.cipher;
-
-import java.nio.ByteBuffer;
-
-/**
- * JNI interface of {@link OpenSsl} implementation. The native method in this
- * class is defined in OpensslNative.h (generated by javah).
- */
-class OpensslNative {
-
-  /**
-   * The private constructor of {@link OpensslNative}.
-   */
-    private OpensslNative() {
-    }
-
-    /**
-     * Declares a native method to initialize JNI field and method IDs.
-     */
-    public native static void initIDs();
-
-    /**
-     * Declares a native method to initialize the cipher context.
-     *
-     * @param algorithm The algorithm name of cipher
-     * @param padding The padding name of cipher
-     * @return the context address of cipher
-     */
-    public native static long initContext(int algorithm, int padding);
-
-    /**
-     * Declares a native method to initialize the cipher context.
-     *
-     * @param context The cipher context address
-     * @param mode ENCRYPT_MODE or DECRYPT_MODE
-     * @param alg Algorithm Mode of OpenSsl
-     * @param padding the padding mode of OpenSsl cipher
-     * @param key crypto key
-     * @param iv crypto iv
-     * @return the context address of cipher
-     */
-    public native static long init(long context, int mode, int alg,
-            int padding, byte[] key, byte[] iv);
-
-    /**
-     * Continues a multiple-part encryption/decryption operation. The data is
-     * encrypted or decrypted, depending on how this cipher was initialized.
-     *
-     * @param context The cipher context address
-     * @param input The input byte buffer
-     * @param inputOffset The offset in input where the input starts
-     * @param inputLength The input length
-     * @param output The byte buffer for the result
-     * @param outputOffset The offset in output where the result is stored
-     * @param maxOutputLength The maximum length for output
-     * @return The number of bytes stored in output
-     */
-    public native static int update(long context, ByteBuffer input,
-            int inputOffset, int inputLength, ByteBuffer output,
-            int outputOffset, int maxOutputLength);
-
-    /**
-     * Continues a multiple-part encryption/decryption operation. The data is
-     * encrypted or decrypted, depending on how this cipher was initialized.
-     *
-     * @param context The cipher context address
-     * @param input The input byte array
-     * @param inputOffset The offset in input where the input starts
-     * @param inputLength The input length
-     * @param output The byte array for the result
-     * @param outputOffset The offset in output where the result is stored
-     * @param maxOutputLength The maximum length for output
-     * @return The number of bytes stored in output
-     */
-    public native static int updateByteArray(long context, byte[] input,
-            int inputOffset, int inputLength, byte[] output, int outputOffset,
-            int maxOutputLength);
-
-    /**
-     * Finishes a multiple-part operation. The data is encrypted or decrypted,
-     * depending on how this cipher was initialized.
-     *
-     * @param context The cipher context address
-     * @param output The byte buffer for the result
-     * @param offset The offset in output where the result is stored
-     * @param maxOutputLength The maximum length for output
-     * @return The number of bytes stored in output
-     */
-    public native static int doFinal(long context, ByteBuffer output,
-            int offset, int maxOutputLength);
-
-    /**
-     * Finishes a multiple-part operation. The data is encrypted or decrypted,
-     * depending on how this cipher was initialized.
-     *
-     * @param context The cipher context address
-     * @param output The byte array for the result
-     * @param offset The offset in output where the result is stored
-     * @param maxOutputLength The maximum length for output
-     * @return The number of bytes stored in output
-     */
-    public native static int doFinalByteArray(long context, byte[] output,
-            int offset, int maxOutputLength);
-
-    /**
-     * Cleans the context at native.
-     *
-     * @param context The cipher context address
-     */
-    public native static void clean(long context);
-}

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/main/java/org/apache/commons/crypto/jna/OpenSslJna.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/jna/OpenSslJna.java b/src/main/java/org/apache/commons/crypto/jna/OpenSslJna.java
new file mode 100644
index 0000000..cfdff2e
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/jna/OpenSslJna.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * 
+ */
+package org.apache.commons.crypto.jna;
+
+import org.apache.commons.crypto.cipher.CryptoCipher;
+import org.apache.commons.crypto.random.CryptoRandom;
+
+/**
+ * Public class to give access to the package protected class objects
+ */
+public final class OpenSslJna {
+
+    public static Class<? extends CryptoCipher> getCipherClass() {
+        return OpenSslJnaCipher.class;
+    }
+
+    public static Class<? extends CryptoRandom> getRandomClass() {
+        return OpenSslJnaCryptoRandom.class;
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/main/java/org/apache/commons/crypto/jna/OpenSslJnaCipher.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/jna/OpenSslJnaCipher.java b/src/main/java/org/apache/commons/crypto/jna/OpenSslJnaCipher.java
index adef3cf..7b0b978 100644
--- a/src/main/java/org/apache/commons/crypto/jna/OpenSslJnaCipher.java
+++ b/src/main/java/org/apache/commons/crypto/jna/OpenSslJnaCipher.java
@@ -71,7 +71,7 @@ class OpenSslJnaCipher implements CryptoCipher {
         }
 
         padding = Padding.get(transform.padding);
-        context = OpensslNativeJna.EVP_CIPHER_CTX_new();
+        context = OpenSslNativeJna.EVP_CIPHER_CTX_new();
 
     }
 
@@ -89,9 +89,9 @@ class OpenSslJnaCipher implements CryptoCipher {
             throws InvalidKeyException, InvalidAlgorithmParameterException {
         Utils.checkNotNull(key);
         Utils.checkNotNull(params);
-        int cipherMode = OpensslNativeJna.OOSL_JNA_DECRYPT_MODE;
+        int cipherMode = OpenSslNativeJna.OOSL_JNA_DECRYPT_MODE;
         if (mode == Cipher.ENCRYPT_MODE) {
-            cipherMode = OpensslNativeJna.OOSL_JNA_ENCRYPT_MODE;
+            cipherMode = OpenSslNativeJna.OOSL_JNA_ENCRYPT_MODE;
         }
         byte[] iv;
         if (params instanceof IvParameterSpec) {
@@ -104,24 +104,24 @@ class OpenSslJnaCipher implements CryptoCipher {
         
        if(algMode == AlgorithmMode.AES_CBC) {
             switch(key.getEncoded().length) {
-                case 16: algo = OpensslNativeJna.EVP_aes_128_cbc(); break;
-                case 24: algo = OpensslNativeJna.EVP_aes_192_cbc(); break;
-                case 32: algo = OpensslNativeJna.EVP_aes_256_cbc(); break;
+                case 16: algo = OpenSslNativeJna.EVP_aes_128_cbc(); break;
+                case 24: algo = OpenSslNativeJna.EVP_aes_192_cbc(); break;
+                case 32: algo = OpenSslNativeJna.EVP_aes_256_cbc(); break;
                 default: throw new InvalidKeyException("keysize unsupported ("+key.getEncoded().length+")");
             }
 
         } else {
             switch(key.getEncoded().length) {
-                case 16: algo = OpensslNativeJna.EVP_aes_128_ctr(); break;
-                case 24: algo = OpensslNativeJna.EVP_aes_192_ctr(); break;
-                case 32: algo = OpensslNativeJna.EVP_aes_256_ctr(); break;
+                case 16: algo = OpenSslNativeJna.EVP_aes_128_ctr(); break;
+                case 24: algo = OpenSslNativeJna.EVP_aes_192_ctr(); break;
+                case 32: algo = OpenSslNativeJna.EVP_aes_256_ctr(); break;
                 default: throw new InvalidKeyException("keysize unsupported ("+key.getEncoded().length+")");
             }
         }
         
-        int retVal = OpensslNativeJna.EVP_CipherInit_ex(context, algo, null, key.getEncoded(), iv, cipherMode);
+        int retVal = OpenSslNativeJna.EVP_CipherInit_ex(context, algo, null, key.getEncoded(), iv, cipherMode);
         throwOnError(retVal);
-        OpensslNativeJna.EVP_CIPHER_CTX_set_padding(context, padding);
+        OpenSslNativeJna.EVP_CIPHER_CTX_set_padding(context, padding);
     }
 
     /**
@@ -138,7 +138,7 @@ class OpenSslJnaCipher implements CryptoCipher {
     public int update(ByteBuffer inBuffer, ByteBuffer outBuffer)
             throws ShortBufferException {
         int[] outlen = new int[1];
-        int retVal = OpensslNativeJna.EVP_CipherUpdate(context, outBuffer, outlen, inBuffer, inBuffer.remaining());
+        int retVal = OpenSslNativeJna.EVP_CipherUpdate(context, outBuffer, outlen, inBuffer, inBuffer.remaining());
         throwOnError(retVal);
         int len = outlen[0];
         inBuffer.position(inBuffer.limit());
@@ -191,7 +191,7 @@ class OpenSslJnaCipher implements CryptoCipher {
             BadPaddingException {
         int uptLen = update(inBuffer, outBuffer);
         int[] outlen = new int[1];
-        int retVal = OpensslNativeJna.EVP_CipherFinal_ex(context, outBuffer, outlen);
+        int retVal = OpenSslNativeJna.EVP_CipherFinal_ex(context, outBuffer, outlen);
         throwOnError(retVal);
         int len = uptLen + outlen[0];
         outBuffer.position(outBuffer.position() + outlen[0]);
@@ -234,18 +234,18 @@ class OpenSslJnaCipher implements CryptoCipher {
     @Override
     public void close() {
         if(context != null) {
-            OpensslNativeJna.EVP_CIPHER_CTX_cleanup(context);
-            OpensslNativeJna.EVP_CIPHER_CTX_free(context);
+            OpenSslNativeJna.EVP_CIPHER_CTX_cleanup(context);
+            OpenSslNativeJna.EVP_CIPHER_CTX_free(context);
         }
     }
     
     private void throwOnError(int retVal) {  
         if(retVal != 1) {
-            NativeLong err = OpensslNativeJna.ERR_peek_error();
-            String errdesc = OpensslNativeJna.ERR_error_string(err, null);
+            NativeLong err = OpenSslNativeJna.ERR_peek_error();
+            String errdesc = OpenSslNativeJna.ERR_error_string(err, null);
             
             if(context != null) {
-                OpensslNativeJna.EVP_CIPHER_CTX_cleanup(context);
+                OpenSslNativeJna.EVP_CIPHER_CTX_cleanup(context);
             }
             throw new RuntimeException("return code "+retVal+" from openssl. Err code is "+err+": "+errdesc);
         }

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/main/java/org/apache/commons/crypto/jna/OpenSslJnaCryptoRandom.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/jna/OpenSslJnaCryptoRandom.java b/src/main/java/org/apache/commons/crypto/jna/OpenSslJnaCryptoRandom.java
index 1f4e971..7ab0b48 100644
--- a/src/main/java/org/apache/commons/crypto/jna/OpenSslJnaCryptoRandom.java
+++ b/src/main/java/org/apache/commons/crypto/jna/OpenSslJnaCryptoRandom.java
@@ -62,14 +62,14 @@ class OpenSslJnaCryptoRandom extends Random implements CryptoRandom {
 
         boolean rdrandLoaded = false;
         try {
-            OpensslNativeJna.ENGINE_load_rdrand();
-            rdrandEngine = OpensslNativeJna.ENGINE_by_id("rdrand");
+            OpenSslNativeJna.ENGINE_load_rdrand();
+            rdrandEngine = OpenSslNativeJna.ENGINE_by_id("rdrand");
             int ENGINE_METHOD_RAND = 0x0008;
             if(rdrandEngine != null) {
-                int rc = OpensslNativeJna.ENGINE_init(rdrandEngine);
+                int rc = OpenSslNativeJna.ENGINE_init(rdrandEngine);
                 
                 if(rc != 0) {
-                    int rc2 = OpensslNativeJna.ENGINE_set_default(rdrandEngine, ENGINE_METHOD_RAND);
+                    int rc2 = OpenSslNativeJna.ENGINE_set_default(rdrandEngine, ENGINE_METHOD_RAND);
                     if(rc2 != 0) {
                         rdrandLoaded = true;
                     }
@@ -99,13 +99,13 @@ class OpenSslJnaCryptoRandom extends Random implements CryptoRandom {
             //this method is synchronized for now
             //to support multithreading https://wiki.openssl.org/index.php/Manual:Threads(3) needs to be done
             
-            if(rdrandEnabled && OpensslNativeJna.RAND_get_rand_method().equals(OpensslNativeJna.RAND_SSLeay())) {
+            if(rdrandEnabled && OpenSslNativeJna.RAND_get_rand_method().equals(OpenSslNativeJna.RAND_SSLeay())) {
                 close();
                 throw new RuntimeException("rdrand should be used but default is detected");
             }
             
             ByteBuffer buf = ByteBuffer.allocateDirect(bytes.length);
-            int retVal = OpensslNativeJna.RAND_bytes(buf, bytes.length);
+            int retVal = OpenSslNativeJna.RAND_bytes(buf, bytes.length);
             throwOnError(retVal);
             buf.rewind();
             buf.get(bytes,0, bytes.length);
@@ -155,18 +155,18 @@ class OpenSslJnaCryptoRandom extends Random implements CryptoRandom {
     @Override
     public void close() {
         closeRdrandEngine();
-        OpensslNativeJna.ENGINE_cleanup();
+        OpenSslNativeJna.ENGINE_cleanup();
         
         //cleanup locks
-        //OpensslNativeJna.CRYPTO_set_locking_callback(null);
+        //OpenSslNativeJna.CRYPTO_set_locking_callback(null);
         //LOCK.unlock();
     }
     
     private void closeRdrandEngine() {
         
         if(rdrandEngine != null) {
-            OpensslNativeJna.ENGINE_finish(rdrandEngine);
-            OpensslNativeJna.ENGINE_free(rdrandEngine);
+            OpenSslNativeJna.ENGINE_finish(rdrandEngine);
+            OpenSslNativeJna.ENGINE_free(rdrandEngine);
         }
     }
 
@@ -181,8 +181,8 @@ class OpenSslJnaCryptoRandom extends Random implements CryptoRandom {
     
     private void throwOnError(int retVal) {  
         if(retVal != 1) {
-            NativeLong err = OpensslNativeJna.ERR_peek_error();
-            String errdesc = OpensslNativeJna.ERR_error_string(err, null);
+            NativeLong err = OpenSslNativeJna.ERR_peek_error();
+            String errdesc = OpenSslNativeJna.ERR_error_string(err, null);
             close();
             throw new RuntimeException("return code "+retVal+" from openssl. Err code is "+err+": "+errdesc);
         }

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/main/java/org/apache/commons/crypto/jna/OpensslJna.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/jna/OpensslJna.java b/src/main/java/org/apache/commons/crypto/jna/OpensslJna.java
deleted file mode 100644
index 2d255ab..0000000
--- a/src/main/java/org/apache/commons/crypto/jna/OpensslJna.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * 
- */
-package org.apache.commons.crypto.jna;
-
-import org.apache.commons.crypto.cipher.CryptoCipher;
-import org.apache.commons.crypto.random.CryptoRandom;
-
-/**
- * Public class to give access to the package protected class objects
- */
-public final class OpensslJna {
-
-    public static Class<? extends CryptoCipher> getCipherClass() {
-        return OpenSslJnaCipher.class;
-    }
-
-    public static Class<? extends CryptoRandom> getRandomClass() {
-        return OpenSslJnaCryptoRandom.class;
-    }
-}

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/main/java/org/apache/commons/crypto/jna/OpensslNativeJna.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/jna/OpensslNativeJna.java b/src/main/java/org/apache/commons/crypto/jna/OpensslNativeJna.java
index 5ffa25b..6adddb2 100644
--- a/src/main/java/org/apache/commons/crypto/jna/OpensslNativeJna.java
+++ b/src/main/java/org/apache/commons/crypto/jna/OpensslNativeJna.java
@@ -24,7 +24,7 @@ import com.sun.jna.Native;
 import com.sun.jna.NativeLong;
 import com.sun.jna.ptr.PointerByReference;
 
-class OpensslNativeJna {
+class OpenSslNativeJna {
 
     static final int OPENSSL_INIT_ENGINE_RDRAND = 0x00000200;
 

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/main/java/org/apache/commons/crypto/random/OpenSslCryptoRandom.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/random/OpenSslCryptoRandom.java b/src/main/java/org/apache/commons/crypto/random/OpenSslCryptoRandom.java
index 15a85ab..b02139e 100644
--- a/src/main/java/org/apache/commons/crypto/random/OpenSslCryptoRandom.java
+++ b/src/main/java/org/apache/commons/crypto/random/OpenSslCryptoRandom.java
@@ -52,7 +52,7 @@ class OpenSslCryptoRandom extends Random implements CryptoRandom {
         boolean opensslLoaded = false;
         if (Crypto.isNativeCodeLoaded()) {
             try {
-                OpensslCryptoRandomNative.initSR();
+                OpenSslCryptoRandomNative.initSR();
                 opensslLoaded = true;
             } catch (Exception t) {// NOPMD
             }
@@ -82,7 +82,7 @@ class OpenSslCryptoRandom extends Random implements CryptoRandom {
     public OpenSslCryptoRandom(Properties props)
             throws NoSuchAlgorithmException {
         //fallback needs to be initialized here in any case cause even if
-        //nativeEnabled is true OpensslCryptoRandomNative.nextRandBytes may fail
+        //nativeEnabled is true OpenSslCryptoRandomNative.nextRandBytes may fail
         fallback = new JavaCryptoRandom(props);
     }
 
@@ -93,7 +93,7 @@ class OpenSslCryptoRandom extends Random implements CryptoRandom {
      */
     @Override
     public void nextBytes(byte[] bytes) {
-        if (!nativeEnabled || !OpensslCryptoRandomNative.nextRandBytes(bytes)) {
+        if (!nativeEnabled || !OpenSslCryptoRandomNative.nextRandBytes(bytes)) {
             fallback.nextBytes(bytes);
         }
     }

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/main/java/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.java b/src/main/java/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.java
new file mode 100644
index 0000000..84b92a6
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.java
@@ -0,0 +1,48 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.crypto.random;
+
+/**
+ * JNI interface of {@link CryptoRandom} implementation for OpenSSL.
+ * The native method in this class is defined in 
+ * OpenSslCryptoRandomNative.h (generated at build time by javah)
+ * and implemented in the file
+ * src/main/native/org/apache/commons/crypto/random/OpenSslCryptoRandomNative.c
+ */
+class OpenSslCryptoRandomNative {
+    /**
+     * The private constructor of {@link OpenSslCryptoRandomNative}.
+     */
+    private OpenSslCryptoRandomNative() {
+    }
+
+    /**
+     * Declares a native method to initialize SR.
+     */
+    public native static void initSR();
+
+    /**
+     * Judges whether use {@link OpenSslCryptoRandomNative} to generate the
+     * user-specified number of random bits.
+     *
+     * @param bytes the array to be filled in with random bytes.
+     * @return true if use {@link OpenSslCryptoRandomNative} to generate the
+     *         user-specified number of random bits.
+     */
+    public native static boolean nextRandBytes(byte[] bytes);
+}

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/main/java/org/apache/commons/crypto/random/OpensslCryptoRandomNative.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/random/OpensslCryptoRandomNative.java b/src/main/java/org/apache/commons/crypto/random/OpensslCryptoRandomNative.java
deleted file mode 100644
index 8c305e0..0000000
--- a/src/main/java/org/apache/commons/crypto/random/OpensslCryptoRandomNative.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.crypto.random;
-
-/**
- * JNI interface of {@link CryptoRandom} implementation for OpenSSL.
- * The native method in this class is defined in 
- * OpensslCryptoRandomNative.h (generated at build time by javah)
- * and implemented in the file
- * src/main/native/org/apache/commons/crypto/random/OpensslCryptoRandomNative.c
- */
-class OpensslCryptoRandomNative {
-    /**
-     * The private constructor of {@link OpensslCryptoRandomNative}.
-     */
-    private OpensslCryptoRandomNative() {
-    }
-
-    /**
-     * Declares a native method to initialize SR.
-     */
-    public native static void initSR();
-
-    /**
-     * Judges whether use {@link OpensslCryptoRandomNative} to generate the
-     * user-specified number of random bits.
-     *
-     * @param bytes the array to be filled in with random bytes.
-     * @return true if use {@link OpensslCryptoRandomNative} to generate the
-     *         user-specified number of random bits.
-     */
-    public native static boolean nextRandBytes(byte[] bytes);
-}

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/main/native/org/apache/commons/crypto/cipher/OpenSslNative.c
----------------------------------------------------------------------
diff --git a/src/main/native/org/apache/commons/crypto/cipher/OpenSslNative.c b/src/main/native/org/apache/commons/crypto/cipher/OpenSslNative.c
new file mode 100644
index 0000000..fd35f61
--- /dev/null
+++ b/src/main/native/org/apache/commons/crypto/cipher/OpenSslNative.c
@@ -0,0 +1,500 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "org_apache_commons_crypto.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+// export the native interfaces
+#ifdef JNIEXPORT
+#undef JNIEXPORT
+#endif
+#define JNIEXPORT __attribute__((__visibility__("default")))
+#include "OpenSslNative.h"
+
+#ifdef UNIX
+static EVP_CIPHER_CTX * (*dlsym_EVP_CIPHER_CTX_new)(void);
+static void (*dlsym_EVP_CIPHER_CTX_free)(EVP_CIPHER_CTX *);
+static int (*dlsym_EVP_CIPHER_CTX_cleanup)(EVP_CIPHER_CTX *);
+static void (*dlsym_EVP_CIPHER_CTX_init)(EVP_CIPHER_CTX *);
+static int (*dlsym_EVP_CIPHER_CTX_set_padding)(EVP_CIPHER_CTX *, int);
+static int (*dlsym_EVP_CipherInit_ex)(EVP_CIPHER_CTX *, const EVP_CIPHER *,  \
+           ENGINE *, const unsigned char *, const unsigned char *, int);
+static int (*dlsym_EVP_CipherUpdate)(EVP_CIPHER_CTX *, unsigned char *,  \
+           int *, const unsigned char *, int);
+static int (*dlsym_EVP_CipherFinal_ex)(EVP_CIPHER_CTX *, unsigned char *, int *);
+static EVP_CIPHER * (*dlsym_EVP_aes_256_ctr)(void);
+static EVP_CIPHER * (*dlsym_EVP_aes_192_ctr)(void);
+static EVP_CIPHER * (*dlsym_EVP_aes_128_ctr)(void);
+static EVP_CIPHER * (*dlsym_EVP_aes_256_cbc)(void);
+static EVP_CIPHER * (*dlsym_EVP_aes_192_cbc)(void);
+static EVP_CIPHER * (*dlsym_EVP_aes_128_cbc)(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_cleanup)(EVP_CIPHER_CTX *);
+typedef void (__cdecl *__dlsym_EVP_CIPHER_CTX_init)(EVP_CIPHER_CTX *);
+typedef int (__cdecl *__dlsym_EVP_CIPHER_CTX_set_padding)(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);
+typedef int (__cdecl *__dlsym_EVP_CipherUpdate)(EVP_CIPHER_CTX *,  \
+             unsigned char *, int *, const unsigned char *, int);
+typedef int (__cdecl *__dlsym_EVP_CipherFinal_ex)(EVP_CIPHER_CTX *,  \
+             unsigned char *, int *);
+typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_256_ctr)(void);
+typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_192_ctr)(void);
+typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_128_ctr)(void);
+typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_256_cbc)(void);
+typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_192_cbc)(void);
+typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_128_cbc)(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_cleanup dlsym_EVP_CIPHER_CTX_cleanup;
+static __dlsym_EVP_CIPHER_CTX_init dlsym_EVP_CIPHER_CTX_init;
+static __dlsym_EVP_CIPHER_CTX_set_padding dlsym_EVP_CIPHER_CTX_set_padding;
+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;
+static __dlsym_EVP_aes_256_ctr dlsym_EVP_aes_256_ctr;
+static __dlsym_EVP_aes_192_ctr dlsym_EVP_aes_192_ctr;
+static __dlsym_EVP_aes_128_ctr dlsym_EVP_aes_128_ctr;
+static __dlsym_EVP_aes_256_cbc dlsym_EVP_aes_256_cbc;
+static __dlsym_EVP_aes_192_cbc dlsym_EVP_aes_192_cbc;
+static __dlsym_EVP_aes_128_cbc dlsym_EVP_aes_128_cbc;
+static HMODULE openssl;
+#endif
+
+static void loadAes(JNIEnv *env)
+{
+#ifdef UNIX
+  LOAD_DYNAMIC_SYMBOL(dlsym_EVP_aes_256_ctr, env, openssl, "EVP_aes_256_ctr");
+  LOAD_DYNAMIC_SYMBOL(dlsym_EVP_aes_192_ctr, env, openssl, "EVP_aes_192_ctr");
+  LOAD_DYNAMIC_SYMBOL(dlsym_EVP_aes_128_ctr, env, openssl, "EVP_aes_128_ctr");
+  LOAD_DYNAMIC_SYMBOL(dlsym_EVP_aes_256_cbc, env, openssl, "EVP_aes_256_cbc");
+  LOAD_DYNAMIC_SYMBOL(dlsym_EVP_aes_192_cbc, env, openssl, "EVP_aes_192_cbc");
+  LOAD_DYNAMIC_SYMBOL(dlsym_EVP_aes_128_cbc, env, openssl, "EVP_aes_128_cbc");
+#endif
+
+#ifdef WINDOWS
+  LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_aes_256_ctr, dlsym_EVP_aes_256_ctr,  \
+                      env, openssl, "EVP_aes_256_ctr");
+  LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_aes_192_ctr, dlsym_EVP_aes_192_ctr,  \
+                      env, openssl, "EVP_aes_192_ctr");
+  LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_aes_128_ctr, dlsym_EVP_aes_128_ctr,  \
+                      env, openssl, "EVP_aes_128_ctr");
+  LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_aes_256_cbc, dlsym_EVP_aes_256_cbc,  \
+                      env, openssl, "EVP_aes_256_cbc");
+  LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_aes_192_cbc, dlsym_EVP_aes_192_cbc,  \
+                      env, openssl, "EVP_aes_192_cbc");
+  LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_aes_128_cbc, dlsym_EVP_aes_128_cbc,  \
+                      env, openssl, "EVP_aes_128_cbc");
+#endif
+}
+
+JNIEXPORT void JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_initIDs
+    (JNIEnv *env, jclass clazz)
+{
+  char msg[1000];
+#ifdef UNIX
+  openssl = dlopen(COMMONS_CRYPTO_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
+#endif
+
+#ifdef WINDOWS
+  openssl = LoadLibrary(COMMONS_CRYPTO_OPENSSL_LIBRARY);
+#endif
+
+  if (!openssl) {
+    snprintf(msg, sizeof(msg), "Cannot load %s (%s)!", COMMONS_CRYPTO_OPENSSL_LIBRARY,  \
+        dlerror());
+    THROW(env, "java/lang/UnsatisfiedLinkError", msg);
+    return;
+  }
+
+#ifdef UNIX
+  dlerror();  // Clear any existing error
+  LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CIPHER_CTX_new, env, openssl,  \
+                      "EVP_CIPHER_CTX_new");
+  LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CIPHER_CTX_free, env, openssl,  \
+                      "EVP_CIPHER_CTX_free");
+  LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CIPHER_CTX_cleanup, env, openssl,  \
+                      "EVP_CIPHER_CTX_cleanup");
+  LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CIPHER_CTX_init, env, openssl,  \
+                      "EVP_CIPHER_CTX_init");
+  LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CIPHER_CTX_set_padding, env, openssl,  \
+                      "EVP_CIPHER_CTX_set_padding");
+  LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CipherInit_ex, env, openssl,  \
+                      "EVP_CipherInit_ex");
+  LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CipherUpdate, env, openssl,  \
+                      "EVP_CipherUpdate");
+  LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CipherFinal_ex, env, openssl,  \
+                      "EVP_CipherFinal_ex");
+#endif
+
+#ifdef WINDOWS
+  LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CIPHER_CTX_new, dlsym_EVP_CIPHER_CTX_new,  \
+                      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_cleanup,  \
+                      dlsym_EVP_CIPHER_CTX_cleanup, env,
+                      openssl, "EVP_CIPHER_CTX_cleanup");
+  LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CIPHER_CTX_init, dlsym_EVP_CIPHER_CTX_init,  \
+                      env, openssl, "EVP_CIPHER_CTX_init");
+  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_CipherInit_ex, dlsym_EVP_CipherInit_ex,  \
+                      env, openssl, "EVP_CipherInit_ex");
+  LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CipherUpdate, dlsym_EVP_CipherUpdate,  \
+                      env, openssl, "EVP_CipherUpdate");
+  LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CipherFinal_ex, dlsym_EVP_CipherFinal_ex,  \
+                      env, openssl, "EVP_CipherFinal_ex");
+#endif
+
+  loadAes(env);
+  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?");
+    return;
+  }
+}
+
+JNIEXPORT jlong JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_initContext
+    (JNIEnv *env, jclass clazz, jint alg, jint padding)
+{
+  if (alg != AES_CTR && alg != AES_CBC) {
+    THROW(env, "java/security/NoSuchAlgorithmException", NULL);
+    return (jlong)0;
+  }
+  if (!(alg == AES_CTR && padding == NOPADDING)
+      && !(alg == AES_CBC && (padding == NOPADDING|| padding == PKCS5PADDING))) {
+    THROW(env, "javax/crypto/NoSuchPaddingException", NULL);
+    return (jlong)0;
+  }
+
+  if (dlsym_EVP_aes_256_ctr == NULL ||
+        dlsym_EVP_aes_192_ctr == NULL || dlsym_EVP_aes_128_ctr == NULL) {
+    THROW(env, "java/security/NoSuchAlgorithmException",  \
+        "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) {
+    THROW(env, "java/security/NoSuchAlgorithmException",  \
+        "Doesn't support AES CBC.");
+    return (jlong)0;
+  }
+
+  // Create and initialize a EVP_CIPHER_CTX
+  EVP_CIPHER_CTX *context = dlsym_EVP_CIPHER_CTX_new();
+  if (!context) {
+    THROW(env, "java/lang/OutOfMemoryError", NULL);
+    return (jlong)0;
+  }
+
+  return JLONG(context);
+}
+
+// Only supports AES-CTR and AES-CBC currently
+static EVP_CIPHER * getEvpCipher(int alg, int keyLen)
+{
+  EVP_CIPHER *cipher = NULL;
+  if (alg == AES_CTR) {
+    if (keyLen == KEY_LENGTH_256) {
+      cipher = dlsym_EVP_aes_256_ctr();
+    } else if (keyLen == KEY_LENGTH_192) {
+      cipher = dlsym_EVP_aes_192_ctr();
+    } else if (keyLen == KEY_LENGTH_128) {
+      cipher = dlsym_EVP_aes_128_ctr();
+    }
+  } else if (alg == AES_CBC) {
+    if (keyLen == KEY_LENGTH_256) {
+      cipher = dlsym_EVP_aes_256_cbc();
+    } else if (keyLen == KEY_LENGTH_192) {
+      cipher = dlsym_EVP_aes_192_cbc();
+    } else if (keyLen == KEY_LENGTH_128) {
+      cipher = dlsym_EVP_aes_128_cbc();
+    }
+  }
+  return cipher;
+}
+
+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)
+{
+  jlong result = 0L;
+  EVP_CIPHER_CTX *context = CONTEXT(ctx);
+
+  jbyte *jKey = NULL;
+  jbyte *jIv  = NULL;
+  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) {
+    char str[64] = {0};
+    snprintf(str, sizeof(str), "Invalid AES key length: %d bytes", jKeyLen);
+    THROW(env, "java/security/InvalidKeyException", str);
+    goto cleanup;
+  }
+  if (jIvLen != IV_LENGTH) {
+    THROW(env, "java/security/InvalidAlgorithmParameterException", "Wrong IV length: must be 16 bytes long");
+    goto cleanup;
+  }
+
+  if (context == 0) {
+    // Create and initialize a EVP_CIPHER_CTX
+    context = dlsym_EVP_CIPHER_CTX_new();
+    if (!context) {
+      THROW(env, "java/lang/OutOfMemoryError", NULL);
+      return (jlong)0;
+    }
+  }
+
+  jKey = (*env)->GetByteArrayElements(env, key, NULL);
+  if (jKey == NULL) {
+    THROW(env, "java/lang/InternalError", "Cannot get bytes array for key.");
+    goto cleanup;
+  }
+  jIv = (*env)->GetByteArrayElements(env, iv, NULL);
+  if (jIv == NULL) {
+    THROW(env, "java/lang/InternalError", "Cannot get bytes array for iv.");
+    goto cleanup;
+  }
+
+  if (!(alg == AES_CTR || alg == AES_CBC)) {
+    THROW(env, "java/security/NoSuchAlgorithmException", "The algorithm is not supported.");
+    goto cleanup;
+  }
+
+  int rc = dlsym_EVP_CipherInit_ex(context, getEvpCipher(alg, jKeyLen),  \
+      NULL, (unsigned char *)jKey, (unsigned char *)jIv, mode == ENCRYPT_MODE);
+  if (rc == 0) {
+    THROW(env, "java/lang/InternalError", "Error in EVP_CipherInit_ex.");
+    goto cleanup;
+  }
+
+  if (padding == NOPADDING) {
+    dlsym_EVP_CIPHER_CTX_set_padding(context, 0);
+  } else if (padding == PKCS5PADDING) {
+    dlsym_EVP_CIPHER_CTX_set_padding(context, 1);
+  }
+
+  // everything is OK,
+  result = JLONG(context);
+
+cleanup:
+  if (result == 0 && context != NULL) {
+    if (CONTEXT(ctx) != NULL) {
+      dlsym_EVP_CIPHER_CTX_cleanup(context);
+    } else {
+      dlsym_EVP_CIPHER_CTX_free(context);
+    }
+  }
+  if (jKey != NULL) {
+    (*env)->ReleaseByteArrayElements(env, key, jKey, 0);
+  }
+  if (jIv != NULL) {
+    (*env)->ReleaseByteArrayElements(env, iv, jIv, 0);
+  }
+
+  return result;
+}
+
+// https://www.openssl.org/docs/crypto/EVP_EncryptInit.html
+static int check_update_max_output_len(EVP_CIPHER_CTX *context, int input_len,
+    int max_output_len)
+{
+  if (context->flags & EVP_CIPH_NO_PADDING) {
+    if (max_output_len >= input_len) {
+      return 1;
+    }
+    return 0;
+  } else {
+    int b = context->cipher->block_size;
+    if (context->encrypt) {
+      if (max_output_len >= input_len + b - 1) {
+        return 1;
+      }
+    } else {
+      if (max_output_len >= input_len + b) {
+        return 1;
+      }
+    }
+
+    return 0;
+  }
+}
+
+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)
+{
+  EVP_CIPHER_CTX *context = CONTEXT(ctx);
+  if (!check_update_max_output_len(context, input_len, max_output_len)) {
+    THROW(env, "javax/crypto/ShortBufferException",  \
+        "Output buffer is not sufficient.");
+    return 0;
+  }
+  unsigned char *input_bytes = (*env)->GetDirectBufferAddress(env, input);
+  unsigned char *output_bytes = (*env)->GetDirectBufferAddress(env, output);
+  if (input_bytes == NULL || output_bytes == NULL) {
+    THROW(env, "java/lang/InternalError", "Cannot get buffer address.");
+    return 0;
+  }
+  input_bytes = input_bytes + input_offset;
+  output_bytes = output_bytes + output_offset;
+
+  int output_len = 0;
+  if (!dlsym_EVP_CipherUpdate(context, output_bytes, &output_len,  \
+      input_bytes, input_len)) {
+    dlsym_EVP_CIPHER_CTX_cleanup(context);
+    THROW(env, "java/lang/InternalError", "Error in EVP_CipherUpdate.");
+    return 0;
+  }
+  return output_len;
+}
+
+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)
+{
+  EVP_CIPHER_CTX *context = CONTEXT(ctx);
+  if (!check_update_max_output_len(context, input_len, max_output_len)) {
+    THROW(env, "javax/crypto/ShortBufferException",  \
+        "Output buffer is not sufficient.");
+    return 0;
+  }
+  unsigned char *input_bytes = NULL;
+  unsigned char *output_bytes = NULL;
+  int output_len = 0;
+
+  input_bytes = (unsigned char *) (*env)->GetByteArrayElements(env, input, 0);
+  output_bytes = (unsigned char *) (*env)->GetByteArrayElements(env, output, 0);
+  if (input_bytes == NULL || output_bytes == NULL) {
+    THROW(env, "java/lang/InternalError", "Cannot get buffer address.");
+    goto cleanup;
+  }
+
+  int rc = dlsym_EVP_CipherUpdate(context, output_bytes + output_offset, &output_len,  \
+      input_bytes + input_offset, input_len);
+  if (rc == 0) {
+    dlsym_EVP_CIPHER_CTX_cleanup(context);
+    THROW(env, "java/lang/InternalError", "Error in EVP_CipherUpdate.");
+    output_len = 0;
+  }
+
+cleanup:
+  if (input_bytes != NULL) {
+    (*env)->ReleaseByteArrayElements(env, input, (jbyte *) input_bytes, 0);
+  }
+  if (output_bytes != NULL) {
+    (*env)->ReleaseByteArrayElements(env, output, (jbyte *) output_bytes, 0);
+  }
+
+  return output_len;
+}
+
+// https://www.openssl.org/docs/crypto/EVP_EncryptInit.html
+static int check_doFinal_max_output_len(EVP_CIPHER_CTX *context,
+    int max_output_len)
+{
+  if (context->flags & EVP_CIPH_NO_PADDING) {
+    return 1;
+  } else {
+    int b = context->cipher->block_size;
+    if (max_output_len >= b) {
+      return 1;
+    }
+
+    return 0;
+  }
+}
+
+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)
+{
+  EVP_CIPHER_CTX *context = CONTEXT(ctx);
+  if (!check_doFinal_max_output_len(context, max_output_len)) {
+    THROW(env, "javax/crypto/ShortBufferException",  \
+        "Output buffer is not sufficient.");
+    return 0;
+  }
+  unsigned char *output_bytes = (*env)->GetDirectBufferAddress(env, output);
+  if (output_bytes == NULL) {
+    THROW(env, "java/lang/InternalError", "Cannot get buffer address.");
+    return 0;
+  }
+  output_bytes = output_bytes + offset;
+
+  int output_len = 0;
+  if (!dlsym_EVP_CipherFinal_ex(context, output_bytes, &output_len)) {
+    dlsym_EVP_CIPHER_CTX_cleanup(context);
+    THROW(env, "java/lang/InternalError", "Error in EVP_CipherFinal_ex.");
+    return 0;
+  }
+  return output_len;
+}
+
+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)
+{
+  EVP_CIPHER_CTX *context = CONTEXT(ctx);
+  if (!check_doFinal_max_output_len(context, max_output_len)) {
+    THROW(env, "javax/crypto/ShortBufferException",  \
+        "Output buffer is not sufficient.");
+    return 0;
+  }
+  unsigned char *output_bytes = (unsigned char *) (*env)->GetByteArrayElements(env, output, 0);
+  if (output_bytes == NULL) {
+    THROW(env, "java/lang/InternalError", "Cannot get buffer address.");
+    return 0;
+  }
+
+  int output_len = 0;
+  int rc = dlsym_EVP_CipherFinal_ex(context, output_bytes + offset, &output_len);
+
+  (*env)->ReleaseByteArrayElements(env, output, (jbyte *) output_bytes, 0);
+
+  if (rc == 0) {
+    dlsym_EVP_CIPHER_CTX_cleanup(context);
+    THROW(env, "java/lang/InternalError", "Error in EVP_CipherFinal_ex.");
+    return 0;
+  }
+  return output_len;
+}
+
+JNIEXPORT void JNICALL Java_org_apache_commons_crypto_cipher_OpenSslNative_clean
+    (JNIEnv *env, jclass clazz, jlong ctx)
+{
+  EVP_CIPHER_CTX *context = CONTEXT(ctx);
+  if (context) {
+    dlsym_EVP_CIPHER_CTX_free(context);
+  }
+}

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4a19325f/src/main/native/org/apache/commons/crypto/cipher/OpensslNative.c
----------------------------------------------------------------------
diff --git a/src/main/native/org/apache/commons/crypto/cipher/OpensslNative.c b/src/main/native/org/apache/commons/crypto/cipher/OpensslNative.c
deleted file mode 100644
index f409011..0000000
--- a/src/main/native/org/apache/commons/crypto/cipher/OpensslNative.c
+++ /dev/null
@@ -1,500 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "org_apache_commons_crypto.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-// export the native interfaces
-#ifdef JNIEXPORT
-#undef JNIEXPORT
-#endif
-#define JNIEXPORT __attribute__((__visibility__("default")))
-#include "OpensslNative.h"
-
-#ifdef UNIX
-static EVP_CIPHER_CTX * (*dlsym_EVP_CIPHER_CTX_new)(void);
-static void (*dlsym_EVP_CIPHER_CTX_free)(EVP_CIPHER_CTX *);
-static int (*dlsym_EVP_CIPHER_CTX_cleanup)(EVP_CIPHER_CTX *);
-static void (*dlsym_EVP_CIPHER_CTX_init)(EVP_CIPHER_CTX *);
-static int (*dlsym_EVP_CIPHER_CTX_set_padding)(EVP_CIPHER_CTX *, int);
-static int (*dlsym_EVP_CipherInit_ex)(EVP_CIPHER_CTX *, const EVP_CIPHER *,  \
-           ENGINE *, const unsigned char *, const unsigned char *, int);
-static int (*dlsym_EVP_CipherUpdate)(EVP_CIPHER_CTX *, unsigned char *,  \
-           int *, const unsigned char *, int);
-static int (*dlsym_EVP_CipherFinal_ex)(EVP_CIPHER_CTX *, unsigned char *, int *);
-static EVP_CIPHER * (*dlsym_EVP_aes_256_ctr)(void);
-static EVP_CIPHER * (*dlsym_EVP_aes_192_ctr)(void);
-static EVP_CIPHER * (*dlsym_EVP_aes_128_ctr)(void);
-static EVP_CIPHER * (*dlsym_EVP_aes_256_cbc)(void);
-static EVP_CIPHER * (*dlsym_EVP_aes_192_cbc)(void);
-static EVP_CIPHER * (*dlsym_EVP_aes_128_cbc)(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_cleanup)(EVP_CIPHER_CTX *);
-typedef void (__cdecl *__dlsym_EVP_CIPHER_CTX_init)(EVP_CIPHER_CTX *);
-typedef int (__cdecl *__dlsym_EVP_CIPHER_CTX_set_padding)(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);
-typedef int (__cdecl *__dlsym_EVP_CipherUpdate)(EVP_CIPHER_CTX *,  \
-             unsigned char *, int *, const unsigned char *, int);
-typedef int (__cdecl *__dlsym_EVP_CipherFinal_ex)(EVP_CIPHER_CTX *,  \
-             unsigned char *, int *);
-typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_256_ctr)(void);
-typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_192_ctr)(void);
-typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_128_ctr)(void);
-typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_256_cbc)(void);
-typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_192_cbc)(void);
-typedef EVP_CIPHER * (__cdecl *__dlsym_EVP_aes_128_cbc)(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_cleanup dlsym_EVP_CIPHER_CTX_cleanup;
-static __dlsym_EVP_CIPHER_CTX_init dlsym_EVP_CIPHER_CTX_init;
-static __dlsym_EVP_CIPHER_CTX_set_padding dlsym_EVP_CIPHER_CTX_set_padding;
-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;
-static __dlsym_EVP_aes_256_ctr dlsym_EVP_aes_256_ctr;
-static __dlsym_EVP_aes_192_ctr dlsym_EVP_aes_192_ctr;
-static __dlsym_EVP_aes_128_ctr dlsym_EVP_aes_128_ctr;
-static __dlsym_EVP_aes_256_cbc dlsym_EVP_aes_256_cbc;
-static __dlsym_EVP_aes_192_cbc dlsym_EVP_aes_192_cbc;
-static __dlsym_EVP_aes_128_cbc dlsym_EVP_aes_128_cbc;
-static HMODULE openssl;
-#endif
-
-static void loadAes(JNIEnv *env)
-{
-#ifdef UNIX
-  LOAD_DYNAMIC_SYMBOL(dlsym_EVP_aes_256_ctr, env, openssl, "EVP_aes_256_ctr");
-  LOAD_DYNAMIC_SYMBOL(dlsym_EVP_aes_192_ctr, env, openssl, "EVP_aes_192_ctr");
-  LOAD_DYNAMIC_SYMBOL(dlsym_EVP_aes_128_ctr, env, openssl, "EVP_aes_128_ctr");
-  LOAD_DYNAMIC_SYMBOL(dlsym_EVP_aes_256_cbc, env, openssl, "EVP_aes_256_cbc");
-  LOAD_DYNAMIC_SYMBOL(dlsym_EVP_aes_192_cbc, env, openssl, "EVP_aes_192_cbc");
-  LOAD_DYNAMIC_SYMBOL(dlsym_EVP_aes_128_cbc, env, openssl, "EVP_aes_128_cbc");
-#endif
-
-#ifdef WINDOWS
-  LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_aes_256_ctr, dlsym_EVP_aes_256_ctr,  \
-                      env, openssl, "EVP_aes_256_ctr");
-  LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_aes_192_ctr, dlsym_EVP_aes_192_ctr,  \
-                      env, openssl, "EVP_aes_192_ctr");
-  LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_aes_128_ctr, dlsym_EVP_aes_128_ctr,  \
-                      env, openssl, "EVP_aes_128_ctr");
-  LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_aes_256_cbc, dlsym_EVP_aes_256_cbc,  \
-                      env, openssl, "EVP_aes_256_cbc");
-  LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_aes_192_cbc, dlsym_EVP_aes_192_cbc,  \
-                      env, openssl, "EVP_aes_192_cbc");
-  LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_aes_128_cbc, dlsym_EVP_aes_128_cbc,  \
-                      env, openssl, "EVP_aes_128_cbc");
-#endif
-}
-
-JNIEXPORT void JNICALL Java_org_apache_commons_crypto_cipher_OpensslNative_initIDs
-    (JNIEnv *env, jclass clazz)
-{
-  char msg[1000];
-#ifdef UNIX
-  openssl = dlopen(COMMONS_CRYPTO_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
-#endif
-
-#ifdef WINDOWS
-  openssl = LoadLibrary(COMMONS_CRYPTO_OPENSSL_LIBRARY);
-#endif
-
-  if (!openssl) {
-    snprintf(msg, sizeof(msg), "Cannot load %s (%s)!", COMMONS_CRYPTO_OPENSSL_LIBRARY,  \
-        dlerror());
-    THROW(env, "java/lang/UnsatisfiedLinkError", msg);
-    return;
-  }
-
-#ifdef UNIX
-  dlerror();  // Clear any existing error
-  LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CIPHER_CTX_new, env, openssl,  \
-                      "EVP_CIPHER_CTX_new");
-  LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CIPHER_CTX_free, env, openssl,  \
-                      "EVP_CIPHER_CTX_free");
-  LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CIPHER_CTX_cleanup, env, openssl,  \
-                      "EVP_CIPHER_CTX_cleanup");
-  LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CIPHER_CTX_init, env, openssl,  \
-                      "EVP_CIPHER_CTX_init");
-  LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CIPHER_CTX_set_padding, env, openssl,  \
-                      "EVP_CIPHER_CTX_set_padding");
-  LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CipherInit_ex, env, openssl,  \
-                      "EVP_CipherInit_ex");
-  LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CipherUpdate, env, openssl,  \
-                      "EVP_CipherUpdate");
-  LOAD_DYNAMIC_SYMBOL(dlsym_EVP_CipherFinal_ex, env, openssl,  \
-                      "EVP_CipherFinal_ex");
-#endif
-
-#ifdef WINDOWS
-  LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CIPHER_CTX_new, dlsym_EVP_CIPHER_CTX_new,  \
-                      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_cleanup,  \
-                      dlsym_EVP_CIPHER_CTX_cleanup, env,
-                      openssl, "EVP_CIPHER_CTX_cleanup");
-  LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CIPHER_CTX_init, dlsym_EVP_CIPHER_CTX_init,  \
-                      env, openssl, "EVP_CIPHER_CTX_init");
-  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_CipherInit_ex, dlsym_EVP_CipherInit_ex,  \
-                      env, openssl, "EVP_CipherInit_ex");
-  LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CipherUpdate, dlsym_EVP_CipherUpdate,  \
-                      env, openssl, "EVP_CipherUpdate");
-  LOAD_DYNAMIC_SYMBOL(__dlsym_EVP_CipherFinal_ex, dlsym_EVP_CipherFinal_ex,  \
-                      env, openssl, "EVP_CipherFinal_ex");
-#endif
-
-  loadAes(env);
-  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?");
-    return;
-  }
-}
-
-JNIEXPORT jlong JNICALL Java_org_apache_commons_crypto_cipher_OpensslNative_initContext
-    (JNIEnv *env, jclass clazz, jint alg, jint padding)
-{
-  if (alg != AES_CTR && alg != AES_CBC) {
-    THROW(env, "java/security/NoSuchAlgorithmException", NULL);
-    return (jlong)0;
-  }
-  if (!(alg == AES_CTR && padding == NOPADDING)
-      && !(alg == AES_CBC && (padding == NOPADDING|| padding == PKCS5PADDING))) {
-    THROW(env, "javax/crypto/NoSuchPaddingException", NULL);
-    return (jlong)0;
-  }
-
-  if (dlsym_EVP_aes_256_ctr == NULL ||
-        dlsym_EVP_aes_192_ctr == NULL || dlsym_EVP_aes_128_ctr == NULL) {
-    THROW(env, "java/security/NoSuchAlgorithmException",  \
-        "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) {
-    THROW(env, "java/security/NoSuchAlgorithmException",  \
-        "Doesn't support AES CBC.");
-    return (jlong)0;
-  }
-
-  // Create and initialize a EVP_CIPHER_CTX
-  EVP_CIPHER_CTX *context = dlsym_EVP_CIPHER_CTX_new();
-  if (!context) {
-    THROW(env, "java/lang/OutOfMemoryError", NULL);
-    return (jlong)0;
-  }
-
-  return JLONG(context);
-}
-
-// Only supports AES-CTR and AES-CBC currently
-static EVP_CIPHER * getEvpCipher(int alg, int keyLen)
-{
-  EVP_CIPHER *cipher = NULL;
-  if (alg == AES_CTR) {
-    if (keyLen == KEY_LENGTH_256) {
-      cipher = dlsym_EVP_aes_256_ctr();
-    } else if (keyLen == KEY_LENGTH_192) {
-      cipher = dlsym_EVP_aes_192_ctr();
-    } else if (keyLen == KEY_LENGTH_128) {
-      cipher = dlsym_EVP_aes_128_ctr();
-    }
-  } else if (alg == AES_CBC) {
-    if (keyLen == KEY_LENGTH_256) {
-      cipher = dlsym_EVP_aes_256_cbc();
-    } else if (keyLen == KEY_LENGTH_192) {
-      cipher = dlsym_EVP_aes_192_cbc();
-    } else if (keyLen == KEY_LENGTH_128) {
-      cipher = dlsym_EVP_aes_128_cbc();
-    }
-  }
-  return cipher;
-}
-
-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)
-{
-  jlong result = 0L;
-  EVP_CIPHER_CTX *context = CONTEXT(ctx);
-
-  jbyte *jKey = NULL;
-  jbyte *jIv  = NULL;
-  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) {
-    char str[64] = {0};
-    snprintf(str, sizeof(str), "Invalid AES key length: %d bytes", jKeyLen);
-    THROW(env, "java/security/InvalidKeyException", str);
-    goto cleanup;
-  }
-  if (jIvLen != IV_LENGTH) {
-    THROW(env, "java/security/InvalidAlgorithmParameterException", "Wrong IV length: must be 16 bytes long");
-    goto cleanup;
-  }
-
-  if (context == 0) {
-    // Create and initialize a EVP_CIPHER_CTX
-    context = dlsym_EVP_CIPHER_CTX_new();
-    if (!context) {
-      THROW(env, "java/lang/OutOfMemoryError", NULL);
-      return (jlong)0;
-    }
-  }
-
-  jKey = (*env)->GetByteArrayElements(env, key, NULL);
-  if (jKey == NULL) {
-    THROW(env, "java/lang/InternalError", "Cannot get bytes array for key.");
-    goto cleanup;
-  }
-  jIv = (*env)->GetByteArrayElements(env, iv, NULL);
-  if (jIv == NULL) {
-    THROW(env, "java/lang/InternalError", "Cannot get bytes array for iv.");
-    goto cleanup;
-  }
-
-  if (!(alg == AES_CTR || alg == AES_CBC)) {
-    THROW(env, "java/security/NoSuchAlgorithmException", "The algorithm is not supported.");
-    goto cleanup;
-  }
-
-  int rc = dlsym_EVP_CipherInit_ex(context, getEvpCipher(alg, jKeyLen),  \
-      NULL, (unsigned char *)jKey, (unsigned char *)jIv, mode == ENCRYPT_MODE);
-  if (rc == 0) {
-    THROW(env, "java/lang/InternalError", "Error in EVP_CipherInit_ex.");
-    goto cleanup;
-  }
-
-  if (padding == NOPADDING) {
-    dlsym_EVP_CIPHER_CTX_set_padding(context, 0);
-  } else if (padding == PKCS5PADDING) {
-    dlsym_EVP_CIPHER_CTX_set_padding(context, 1);
-  }
-
-  // everything is OK,
-  result = JLONG(context);
-
-cleanup:
-  if (result == 0 && context != NULL) {
-    if (CONTEXT(ctx) != NULL) {
-      dlsym_EVP_CIPHER_CTX_cleanup(context);
-    } else {
-      dlsym_EVP_CIPHER_CTX_free(context);
-    }
-  }
-  if (jKey != NULL) {
-    (*env)->ReleaseByteArrayElements(env, key, jKey, 0);
-  }
-  if (jIv != NULL) {
-    (*env)->ReleaseByteArrayElements(env, iv, jIv, 0);
-  }
-
-  return result;
-}
-
-// https://www.openssl.org/docs/crypto/EVP_EncryptInit.html
-static int check_update_max_output_len(EVP_CIPHER_CTX *context, int input_len,
-    int max_output_len)
-{
-  if (context->flags & EVP_CIPH_NO_PADDING) {
-    if (max_output_len >= input_len) {
-      return 1;
-    }
-    return 0;
-  } else {
-    int b = context->cipher->block_size;
-    if (context->encrypt) {
-      if (max_output_len >= input_len + b - 1) {
-        return 1;
-      }
-    } else {
-      if (max_output_len >= input_len + b) {
-        return 1;
-      }
-    }
-
-    return 0;
-  }
-}
-
-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)
-{
-  EVP_CIPHER_CTX *context = CONTEXT(ctx);
-  if (!check_update_max_output_len(context, input_len, max_output_len)) {
-    THROW(env, "javax/crypto/ShortBufferException",  \
-        "Output buffer is not sufficient.");
-    return 0;
-  }
-  unsigned char *input_bytes = (*env)->GetDirectBufferAddress(env, input);
-  unsigned char *output_bytes = (*env)->GetDirectBufferAddress(env, output);
-  if (input_bytes == NULL || output_bytes == NULL) {
-    THROW(env, "java/lang/InternalError", "Cannot get buffer address.");
-    return 0;
-  }
-  input_bytes = input_bytes + input_offset;
-  output_bytes = output_bytes + output_offset;
-
-  int output_len = 0;
-  if (!dlsym_EVP_CipherUpdate(context, output_bytes, &output_len,  \
-      input_bytes, input_len)) {
-    dlsym_EVP_CIPHER_CTX_cleanup(context);
-    THROW(env, "java/lang/InternalError", "Error in EVP_CipherUpdate.");
-    return 0;
-  }
-  return output_len;
-}
-
-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)
-{
-  EVP_CIPHER_CTX *context = CONTEXT(ctx);
-  if (!check_update_max_output_len(context, input_len, max_output_len)) {
-    THROW(env, "javax/crypto/ShortBufferException",  \
-        "Output buffer is not sufficient.");
-    return 0;
-  }
-  unsigned char *input_bytes = NULL;
-  unsigned char *output_bytes = NULL;
-  int output_len = 0;
-
-  input_bytes = (unsigned char *) (*env)->GetByteArrayElements(env, input, 0);
-  output_bytes = (unsigned char *) (*env)->GetByteArrayElements(env, output, 0);
-  if (input_bytes == NULL || output_bytes == NULL) {
-    THROW(env, "java/lang/InternalError", "Cannot get buffer address.");
-    goto cleanup;
-  }
-
-  int rc = dlsym_EVP_CipherUpdate(context, output_bytes + output_offset, &output_len,  \
-      input_bytes + input_offset, input_len);
-  if (rc == 0) {
-    dlsym_EVP_CIPHER_CTX_cleanup(context);
-    THROW(env, "java/lang/InternalError", "Error in EVP_CipherUpdate.");
-    output_len = 0;
-  }
-
-cleanup:
-  if (input_bytes != NULL) {
-    (*env)->ReleaseByteArrayElements(env, input, (jbyte *) input_bytes, 0);
-  }
-  if (output_bytes != NULL) {
-    (*env)->ReleaseByteArrayElements(env, output, (jbyte *) output_bytes, 0);
-  }
-
-  return output_len;
-}
-
-// https://www.openssl.org/docs/crypto/EVP_EncryptInit.html
-static int check_doFinal_max_output_len(EVP_CIPHER_CTX *context,
-    int max_output_len)
-{
-  if (context->flags & EVP_CIPH_NO_PADDING) {
-    return 1;
-  } else {
-    int b = context->cipher->block_size;
-    if (max_output_len >= b) {
-      return 1;
-    }
-
-    return 0;
-  }
-}
-
-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)
-{
-  EVP_CIPHER_CTX *context = CONTEXT(ctx);
-  if (!check_doFinal_max_output_len(context, max_output_len)) {
-    THROW(env, "javax/crypto/ShortBufferException",  \
-        "Output buffer is not sufficient.");
-    return 0;
-  }
-  unsigned char *output_bytes = (*env)->GetDirectBufferAddress(env, output);
-  if (output_bytes == NULL) {
-    THROW(env, "java/lang/InternalError", "Cannot get buffer address.");
-    return 0;
-  }
-  output_bytes = output_bytes + offset;
-
-  int output_len = 0;
-  if (!dlsym_EVP_CipherFinal_ex(context, output_bytes, &output_len)) {
-    dlsym_EVP_CIPHER_CTX_cleanup(context);
-    THROW(env, "java/lang/InternalError", "Error in EVP_CipherFinal_ex.");
-    return 0;
-  }
-  return output_len;
-}
-
-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)
-{
-  EVP_CIPHER_CTX *context = CONTEXT(ctx);
-  if (!check_doFinal_max_output_len(context, max_output_len)) {
-    THROW(env, "javax/crypto/ShortBufferException",  \
-        "Output buffer is not sufficient.");
-    return 0;
-  }
-  unsigned char *output_bytes = (unsigned char *) (*env)->GetByteArrayElements(env, output, 0);
-  if (output_bytes == NULL) {
-    THROW(env, "java/lang/InternalError", "Cannot get buffer address.");
-    return 0;
-  }
-
-  int output_len = 0;
-  int rc = dlsym_EVP_CipherFinal_ex(context, output_bytes + offset, &output_len);
-
-  (*env)->ReleaseByteArrayElements(env, output, (jbyte *) output_bytes, 0);
-
-  if (rc == 0) {
-    dlsym_EVP_CIPHER_CTX_cleanup(context);
-    THROW(env, "java/lang/InternalError", "Error in EVP_CipherFinal_ex.");
-    return 0;
-  }
-  return output_len;
-}
-
-JNIEXPORT void JNICALL Java_org_apache_commons_crypto_cipher_OpensslNative_clean
-    (JNIEnv *env, jclass clazz, jlong ctx)
-{
-  EVP_CIPHER_CTX *context = CONTEXT(ctx);
-  if (context) {
-    dlsym_EVP_CIPHER_CTX_free(context);
-  }
-}