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

[3/8] commons-crypto git commit: CRYPTO-7: Rename source code in Chimera to Apache name space

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/native/com/intel/chimera/cipher/OpensslNative.c
----------------------------------------------------------------------
diff --git a/src/main/native/com/intel/chimera/cipher/OpensslNative.c b/src/main/native/com/intel/chimera/cipher/OpensslNative.c
deleted file mode 100644
index 4f87866..0000000
--- a/src/main/native/com/intel/chimera/cipher/OpensslNative.c
+++ /dev/null
@@ -1,467 +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 "com_intel_chimera.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#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_com_intel_chimera_cipher_OpensslNative_initIDs
-    (JNIEnv *env, jclass clazz)
-{
-  char msg[1000];
-#ifdef UNIX
-  openssl = dlopen(CHIMERA_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
-#endif
-
-#ifdef WINDOWS
-  openssl = LoadLibrary(CHIMERA_OPENSSL_LIBRARY);
-#endif
-
-  if (!openssl) {
-    snprintf(msg, sizeof(msg), "Cannot load %s (%s)!", CHIMERA_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_com_intel_chimera_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_com_intel_chimera_cipher_OpensslNative_init
-    (JNIEnv *env, jclass clazz, jlong ctx, jint mode, jint alg, jint padding,
-    jbyteArray key, jbyteArray iv)
-{
-  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) {
-    THROW(env, "java/security/InvalidKeyException", "Invalid key length.");
-    return (jlong)0;
-  }
-  if (jIvLen != IV_LENGTH) {
-    THROW(env, "java/security/InvalidAlgorithmParameterException", "Wrong IV length.");
-    return (jlong)0;
-  }
-
-  EVP_CIPHER_CTX *context = CONTEXT(ctx);
-  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;
-    }
-  }
-
-  jbyte *jKey = (*env)->GetByteArrayElements(env, key, NULL);
-  if (jKey == NULL) {
-    THROW(env, "java/lang/InternalError", "Cannot get bytes array for key.");
-    return (jlong)0;
-  }
-  jbyte *jIv = (*env)->GetByteArrayElements(env, iv, NULL);
-  if (jIv == NULL) {
-    (*env)->ReleaseByteArrayElements(env, key, jKey, 0);
-    THROW(env, "java/lang/InternalError", "Cannot get bytes array for iv.");
-    return (jlong)0;
-  }
-
-  if (!(alg == AES_CTR || alg == AES_CBC)) {
-    THROW(env, "java/security/NoSuchAlgorithmException", "The algorithm is not supported.");
-    return (jlong)0;
-  }
-
-  int rc = dlsym_EVP_CipherInit_ex(context, getEvpCipher(alg, jKeyLen),  \
-      NULL, (unsigned char *)jKey, (unsigned char *)jIv, mode == ENCRYPT_MODE);
-  (*env)->ReleaseByteArrayElements(env, key, jKey, 0);
-  (*env)->ReleaseByteArrayElements(env, iv, jIv, 0);
-  if (rc == 0) {
-    dlsym_EVP_CIPHER_CTX_cleanup(context);
-    THROW(env, "java/lang/InternalError", "Error in EVP_CipherInit_ex.");
-    return (jlong)0;
-  }
-
-  if (padding == NOPADDING) {
-    dlsym_EVP_CIPHER_CTX_set_padding(context, 0);
-  } else if (padding == PKCS5PADDING) {
-    dlsym_EVP_CIPHER_CTX_set_padding(context, 1);
-  }
-
-  return JLONG(context);
-}
-
-// 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_com_intel_chimera_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_com_intel_chimera_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 = (unsigned char *) (*env)->GetByteArrayElements(env, input, 0);
-  unsigned char *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.");
-    return 0;
-  }
-
-  int output_len = 0;
-  int rc = dlsym_EVP_CipherUpdate(context, output_bytes + output_offset, &output_len,  \
-      input_bytes + input_offset, input_len);
-
-  (*env)->ReleaseByteArrayElements(env, input, (jbyte *) input_bytes, 0);
-  (*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_CipherUpdate.");
-    return 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_com_intel_chimera_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_com_intel_chimera_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_com_intel_chimera_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/4920d272/src/main/native/com/intel/chimera/com_intel_chimera.h
----------------------------------------------------------------------
diff --git a/src/main/native/com/intel/chimera/com_intel_chimera.h b/src/main/native/com/intel/chimera/com_intel_chimera.h
deleted file mode 100644
index 1eb979e..0000000
--- a/src/main/native/com/intel/chimera/com_intel_chimera.h
+++ /dev/null
@@ -1,228 +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.
- */
-
-/**
- * This file includes some common utilities
- * for all native code used in chimera.
- */
-
-#if !defined COM_INTEL_CHIMERA_H
-#define COM_INTEL_CHIMERA_H
-
-#if defined(_WIN32)
-#undef UNIX
-#define WINDOWS
-#else
-#undef WINDOWS
-#define UNIX
-#endif
-
-/* A helper macro to 'throw' a java exception. */
-#define THROW(env, exception_name, message) \
-  { \
-	jclass ecls = (*env)->FindClass(env, exception_name); \
-	if (ecls) { \
-	  (*env)->ThrowNew(env, ecls, message); \
-	  (*env)->DeleteLocalRef(env, ecls); \
-	} \
-  }
-
-/* Helper macro to return if an exception is pending */
-#define PASS_EXCEPTIONS(env) \
-  { \
-    if ((*env)->ExceptionCheck(env)) return; \
-  }
-
-#define PASS_EXCEPTIONS_GOTO(env, target) \
-  { \
-    if ((*env)->ExceptionCheck(env)) goto target; \
-  }
-
-#define PASS_EXCEPTIONS_RET(env, ret) \
-  { \
-    if ((*env)->ExceptionCheck(env)) return (ret); \
-  }
-
-/**
- * Unix definitions
- */
-#ifdef UNIX
-#include <config.h>
-#include <dlfcn.h>
-#include <jni.h>
-
-/**
- * A helper function to dlsym a 'symbol' from a given library-handle.
- *
- * @param env jni handle to report contingencies.
- * @param handle handle to the dlopen'ed library.
- * @param symbol symbol to load.
- * @return returns the address where the symbol is loaded in memory,
- *         <code>NULL</code> on error.
- */
-static __attribute__ ((unused))
-void *do_dlsym(JNIEnv *env, void *handle, const char *symbol) {
-  if (!env || !handle || !symbol) {
-  	THROW(env, "java/lang/InternalError", NULL);
-  	return NULL;
-  }
-  char *error = NULL;
-  void *func_ptr = dlsym(handle, symbol);
-  if ((error = dlerror()) != NULL) {
-  	THROW(env, "java/lang/UnsatisfiedLinkError", symbol);
-  	return NULL;
-  }
-  return func_ptr;
-}
-
-/* A helper macro to dlsym the requisite dynamic symbol and bail-out on error. */
-#define LOAD_DYNAMIC_SYMBOL(func_ptr, env, handle, symbol) \
-  if ((func_ptr = do_dlsym(env, handle, symbol)) == NULL) { \
-    return; \
-  }
-#endif
-// Unix part end
-
-
-/**
- * Windows definitions
- */
-#ifdef WINDOWS
-
-/* Force using Unicode throughout the code */
-#ifndef UNICODE
-#define UNICODE
-#endif
-
-/* Microsoft C Compiler does not support the C99 inline keyword */
-#ifndef __cplusplus
-#define inline __inline;
-#endif // _cplusplus
-
-/* Optimization macros supported by GCC but for which there is no
-   direct equivalent in the Microsoft C compiler */
-#define likely(_c) (_c)
-#define unlikely(_c) (_c)
-
-/* Disable certain warnings in the native CRC32 code. */
-#pragma warning(disable:4018)		// Signed/unsigned mismatch.
-#pragma warning(disable:4244)		// Possible loss of data in conversion.
-#pragma warning(disable:4267)		// Possible loss of data.
-#pragma warning(disable:4996)		// Use of deprecated function.
-
-#include <Windows.h>
-#include <stdio.h>
-#include <jni.h>
-
-#define snprintf(a, b ,c, d) _snprintf_s((a), (b), _TRUNCATE, (c), (d))
-
-/* A helper macro to dlsym the requisite dynamic symbol and bail-out on error. */
-#define LOAD_DYNAMIC_SYMBOL(func_type, func_ptr, env, handle, symbol) \
-  if ((func_ptr = (func_type) do_dlsym(env, handle, symbol)) == NULL) { \
-    return; \
-  }
-
-/**
- * A helper function to dynamic load a 'symbol' from a given library-handle.
- *
- * @param env jni handle to report contingencies.
- * @param handle handle to the dynamic library.
- * @param symbol symbol to load.
- * @return returns the address where the symbol is loaded in memory,
- *         <code>NULL</code> on error.
- */
-static FARPROC WINAPI do_dlsym(JNIEnv *env, HMODULE handle, LPCSTR symbol) {
-  DWORD dwErrorCode = ERROR_SUCCESS;
-  FARPROC func_ptr = NULL;
-
-  if (!env || !handle || !symbol) {
-    THROW(env, "java/lang/InternalError", NULL);
-    return NULL;
-  }
-
-  func_ptr = GetProcAddress(handle, symbol);
-  if (func_ptr == NULL)
-  {
-    THROW(env, "java/lang/UnsatisfiedLinkError", symbol);
-  }
-  return func_ptr;
-}
-#endif
-// Windows part end
-
-
-#define LOCK_CLASS(env, clazz, classname) \
-  if ((*env)->MonitorEnter(env, clazz) != 0) { \
-    char exception_msg[128]; \
-    snprintf(exception_msg, 128, "Failed to lock %s", classname); \
-    THROW(env, "java/lang/InternalError", exception_msg); \
-  }
-
-#define UNLOCK_CLASS(env, clazz, classname) \
-  if ((*env)->MonitorExit(env, clazz) != 0) { \
-    char exception_msg[128]; \
-    snprintf(exception_msg, 128, "Failed to unlock %s", classname); \
-    THROW(env, "java/lang/InternalError", exception_msg); \
-  }
-
-#define RETRY_ON_EINTR(ret, expr) do { \
-  ret = expr; \
-} while ((ret == -1) && (errno == EINTR));
-
-#ifdef UNIX
-#include <dlfcn.h>
-#include "config.h"
-#endif
-
-#ifdef WINDOWS
-#include "winutils.h"
-#endif
-
-#include <openssl/aes.h>
-#include <openssl/evp.h>
-#include <openssl/err.h>
-
-/**
- * A helper macro to convert the java 'context-handle' 
- * to a EVP_CIPHER_CTX pointer. 
- */
-#define CONTEXT(context) ((EVP_CIPHER_CTX*)((ptrdiff_t)(context)))
-
-/**
- * A helper macro to convert the EVP_CIPHER_CTX pointer to the 
- * java 'context-handle'.
- */
-#define JLONG(context) ((jlong)((ptrdiff_t)(context)))
-
-#define KEY_LENGTH_128 16
-#define KEY_LENGTH_192 24
-#define KEY_LENGTH_256 32
-#define IV_LENGTH 16
-
-#define ENCRYPT_MODE 1
-#define DECRYPT_MODE 0
-
-/** Currently only support AES/CTR/NoPadding. */
-#define AES_CTR 0
-#define AES_CBC 1
-#define NOPADDING 0
-#define PKCS5PADDING 1
-
-#endif
-
-//vim: sw=2: ts=2: et

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/native/com/intel/chimera/exception.c
----------------------------------------------------------------------
diff --git a/src/main/native/com/intel/chimera/exception.c b/src/main/native/com/intel/chimera/exception.c
deleted file mode 100644
index fc072e8..0000000
--- a/src/main/native/com/intel/chimera/exception.c
+++ /dev/null
@@ -1,124 +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 "exception.h"
-
-#include <jni.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-jthrowable newExceptionV(JNIEnv* env, const char *name,
-                         const char *fmt, va_list ap)
-{
-  int need;
-  char buf[1], *msg = NULL;
-  va_list ap2;
-  jstring jstr = NULL;
-  jthrowable jthr;
-  jclass clazz;
-  jmethodID excCtor;
-
-  va_copy(ap2, ap);
-  clazz = (*env)->FindClass(env, name);
-  if (!clazz) {
-    jthr = (*env)->ExceptionOccurred(env);
-    (*env)->ExceptionClear(env);
-    goto done;
-  }
-  excCtor = (*env)->GetMethodID(env,
-        clazz, "<init>", "(Ljava/lang/String;)V");
-  if (!excCtor) {
-    jthr = (*env)->ExceptionOccurred(env);
-    (*env)->ExceptionClear(env);
-    goto done;
-  }
-  need = vsnprintf(buf, sizeof(buf), fmt, ap);
-  if (need < 0) {
-    fmt = "vsnprintf error";
-    need = strlen(fmt);
-  }
-  msg = malloc(need + 1);
-  vsnprintf(msg, need + 1, fmt, ap2);
-  jstr = (*env)->NewStringUTF(env, msg);
-  if (!jstr) {
-    jthr = (*env)->ExceptionOccurred(env);
-    (*env)->ExceptionClear(env);
-    goto done;
-  }
-  jthr = (*env)->NewObject(env, clazz, excCtor, jstr);
-  if (!jthr) {
-    jthr = (*env)->ExceptionOccurred(env);
-    (*env)->ExceptionClear(env);
-    goto done;
-  }
-
-done:
-  free(msg);
-  va_end(ap2);
-  (*env)->DeleteLocalRef(env, jstr);
-  return jthr;
-}
-
-jthrowable newException(JNIEnv* env, const char *name, const char *fmt, ...)
-{
-  va_list ap;
-  jthrowable jthr;
-
-  va_start(ap, fmt);
-  jthr = newExceptionV(env, name, fmt, ap);
-  va_end(ap);
-  return jthr;
-}
-
-jthrowable newRuntimeException(JNIEnv* env, const char *fmt, ...)
-{
-  va_list ap;
-  jthrowable jthr;
-
-  va_start(ap, fmt);
-  jthr = newExceptionV(env, "java/lang/RuntimeException", fmt, ap);
-  va_end(ap);
-  return jthr;
-}
-
-jthrowable newIOException(JNIEnv* env, const char *fmt, ...)
-{
-  va_list ap;
-  jthrowable jthr;
-
-  va_start(ap, fmt);
-  jthr = newExceptionV(env, "java/io/IOException", fmt, ap);
-  va_end(ap);
-  return jthr;
-}
-
-const char* terror(int errnum)
-{
-
-#if defined(__sun)
-// MT-Safe under Solaris which doesn't support sys_errlist/sys_nerr
-  return strerror(errnum); 
-#else
-  if ((errnum < 0) || (errnum >= sys_nerr)) {
-    return "unknown error.";
-  }
-  return sys_errlist[errnum];
-#endif
-}
-

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/native/com/intel/chimera/exception.h
----------------------------------------------------------------------
diff --git a/src/main/native/com/intel/chimera/exception.h b/src/main/native/com/intel/chimera/exception.h
deleted file mode 100644
index eace346..0000000
--- a/src/main/native/com/intel/chimera/exception.h
+++ /dev/null
@@ -1,104 +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.
- */
-#ifndef CHIMERA_NATIVE_SRC_EXCEPTION_H
-#define CHIMERA_NATIVE_SRC_EXCEPTION_H
-
-#include <jni.h> /* for jthrowable */
-#include <stdarg.h> /* for va_list */
-#include "com_intel_chimera.h"
-
-#ifdef WINDOWS
-/*
- * gcc-style type-checked format arguments are not supported on Windows, so just
- * stub this macro.
- */
-#define TYPE_CHECKED_PRINTF_FORMAT(formatArg, varArgs)
-# else
-/* Use gcc type-checked format arguments. */
-#define TYPE_CHECKED_PRINTF_FORMAT(formatArg, varArgs) \
-  __attribute__((format(printf, formatArg, varArgs)))
-#endif
-
-/**
- * Create a new Exception.
- *
- * No exceptions will be pending on return.
- *
- * @param env           The JNI environment
- * @param name          full name of the Java exception class
- * @param fmt           printf-style format string
- * @param ap            printf-style arguments
- *
- * @return              The RuntimeException
- */
-jthrowable newExceptionV(JNIEnv* env, const char *name,
-                         const char *fmt, va_list ap);
-
-/**
- * Create a new Exception.
- *
- * No exceptions will be pending on return.
- *
- * @param env           The JNI environment
- * @param name          full name of the Java exception class
- * @param fmt           printf-style format string
- * @param ...           printf-style arguments
- *
- * @return              The RuntimeException
- */
-jthrowable newException(JNIEnv* env, const char *name, const char *fmt, ...)
-    TYPE_CHECKED_PRINTF_FORMAT(3, 4);
-
-/**
- * Create a new RuntimeException.
- *
- * No exceptions will be pending on return.
- *
- * @param env           The JNI environment
- * @param fmt           printf-style format string
- * @param ...           printf-style arguments
- *
- * @return              The RuntimeException
- */
-jthrowable newRuntimeException(JNIEnv* env, const char *fmt, ...)
-    TYPE_CHECKED_PRINTF_FORMAT(2, 3);
-
-/**
- * Create a new IOException.
- *
- * No exceptions will be pending on return.
- *
- * @param env           The JNI environment
- * @param fmt           printf-style format string
- * @param ...           printf-style arguments
- *
- * @return              The IOException, or another exception if we failed
- *                      to create the NativeIOException.
- */
-jthrowable newIOException(JNIEnv* env, const char *fmt, ...)
-    TYPE_CHECKED_PRINTF_FORMAT(2, 3);
-
-/**
- * Thread-safe strerror alternative.
- *
- * @param errnum        Error number.
- * @return              Statically allocated error string.
- */
-const char* terror(int errnum);
-
-#undef TYPE_CHECKED_PRINTF_FORMAT
-#endif

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/native/com/intel/chimera/random/OpensslSecureRandomNative.c
----------------------------------------------------------------------
diff --git a/src/main/native/com/intel/chimera/random/OpensslSecureRandomNative.c b/src/main/native/com/intel/chimera/random/OpensslSecureRandomNative.c
deleted file mode 100644
index 96a4fc7..0000000
--- a/src/main/native/com/intel/chimera/random/OpensslSecureRandomNative.c
+++ /dev/null
@@ -1,335 +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 "com_intel_chimera_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
- 
-#include "OpensslSecureRandomNative.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_com_intel_chimera_random_OpensslSecureRandomNative_initSR
-    (JNIEnv *env, jclass clazz)
-{
-  char msg[1000];
-#ifdef UNIX
-  void *openssl = dlopen(CHIMERA_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
-#endif
-
-#ifdef WINDOWS
-  HMODULE openssl = LoadLibrary(CHIMERA_OPENSSL_LIBRARY);
-#endif
-
-  if (!openssl) {
-    snprintf(msg, sizeof(msg), "Cannot load %s (%s)!", CHIMERA_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_com_intel_chimera_random_OpensslSecureRandomNative_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/4920d272/src/main/native/com/intel/chimera/random/com_intel_chimera_random.h
----------------------------------------------------------------------
diff --git a/src/main/native/com/intel/chimera/random/com_intel_chimera_random.h b/src/main/native/com/intel/chimera/random/com_intel_chimera_random.h
deleted file mode 100644
index b011cde..0000000
--- a/src/main/native/com/intel/chimera/random/com_intel_chimera_random.h
+++ /dev/null
@@ -1,40 +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.
- */
- 
-#ifndef COM_INTEL_CHIMERA_RANDOM_H
-#define COM_INTEL_CHIMERA_RANDOM_H
-
-#include "com_intel_chimera.h"
-
-#ifdef UNIX
-#include <dlfcn.h>
-#include "config.h"
-#endif
-
-#ifdef WINDOWS
-#include "winutils.h"
-#endif
-
-#define UNUSED(x) ((void)(x))
-
-#include <openssl/crypto.h>
-#include <openssl/engine.h>
-#include <openssl/rand.h>
-#include <openssl/err.h>
-
-#endif //COM_INTEL_CHIMERA_RANDOM_H

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/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..552babd
--- /dev/null
+++ b/src/main/native/org/apache/commons/crypto/cipher/OpensslNative.c
@@ -0,0 +1,467 @@
+/**
+ * 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>
+
+#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(CHIMERA_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
+#endif
+
+#ifdef WINDOWS
+  openssl = LoadLibrary(CHIMERA_OPENSSL_LIBRARY);
+#endif
+
+  if (!openssl) {
+    snprintf(msg, sizeof(msg), "Cannot load %s (%s)!", CHIMERA_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)
+{
+  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) {
+    THROW(env, "java/security/InvalidKeyException", "Invalid key length.");
+    return (jlong)0;
+  }
+  if (jIvLen != IV_LENGTH) {
+    THROW(env, "java/security/InvalidAlgorithmParameterException", "Wrong IV length.");
+    return (jlong)0;
+  }
+
+  EVP_CIPHER_CTX *context = CONTEXT(ctx);
+  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;
+    }
+  }
+
+  jbyte *jKey = (*env)->GetByteArrayElements(env, key, NULL);
+  if (jKey == NULL) {
+    THROW(env, "java/lang/InternalError", "Cannot get bytes array for key.");
+    return (jlong)0;
+  }
+  jbyte *jIv = (*env)->GetByteArrayElements(env, iv, NULL);
+  if (jIv == NULL) {
+    (*env)->ReleaseByteArrayElements(env, key, jKey, 0);
+    THROW(env, "java/lang/InternalError", "Cannot get bytes array for iv.");
+    return (jlong)0;
+  }
+
+  if (!(alg == AES_CTR || alg == AES_CBC)) {
+    THROW(env, "java/security/NoSuchAlgorithmException", "The algorithm is not supported.");
+    return (jlong)0;
+  }
+
+  int rc = dlsym_EVP_CipherInit_ex(context, getEvpCipher(alg, jKeyLen),  \
+      NULL, (unsigned char *)jKey, (unsigned char *)jIv, mode == ENCRYPT_MODE);
+  (*env)->ReleaseByteArrayElements(env, key, jKey, 0);
+  (*env)->ReleaseByteArrayElements(env, iv, jIv, 0);
+  if (rc == 0) {
+    dlsym_EVP_CIPHER_CTX_cleanup(context);
+    THROW(env, "java/lang/InternalError", "Error in EVP_CipherInit_ex.");
+    return (jlong)0;
+  }
+
+  if (padding == NOPADDING) {
+    dlsym_EVP_CIPHER_CTX_set_padding(context, 0);
+  } else if (padding == PKCS5PADDING) {
+    dlsym_EVP_CIPHER_CTX_set_padding(context, 1);
+  }
+
+  return JLONG(context);
+}
+
+// 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 = (unsigned char *) (*env)->GetByteArrayElements(env, input, 0);
+  unsigned char *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.");
+    return 0;
+  }
+
+  int output_len = 0;
+  int rc = dlsym_EVP_CipherUpdate(context, output_bytes + output_offset, &output_len,  \
+      input_bytes + input_offset, input_len);
+
+  (*env)->ReleaseByteArrayElements(env, input, (jbyte *) input_bytes, 0);
+  (*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_CipherUpdate.");
+    return 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/4920d272/src/main/native/org/apache/commons/crypto/exception.c
----------------------------------------------------------------------
diff --git a/src/main/native/org/apache/commons/crypto/exception.c b/src/main/native/org/apache/commons/crypto/exception.c
new file mode 100644
index 0000000..fc072e8
--- /dev/null
+++ b/src/main/native/org/apache/commons/crypto/exception.c
@@ -0,0 +1,124 @@
+/**
+ * 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 "exception.h"
+
+#include <jni.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+jthrowable newExceptionV(JNIEnv* env, const char *name,
+                         const char *fmt, va_list ap)
+{
+  int need;
+  char buf[1], *msg = NULL;
+  va_list ap2;
+  jstring jstr = NULL;
+  jthrowable jthr;
+  jclass clazz;
+  jmethodID excCtor;
+
+  va_copy(ap2, ap);
+  clazz = (*env)->FindClass(env, name);
+  if (!clazz) {
+    jthr = (*env)->ExceptionOccurred(env);
+    (*env)->ExceptionClear(env);
+    goto done;
+  }
+  excCtor = (*env)->GetMethodID(env,
+        clazz, "<init>", "(Ljava/lang/String;)V");
+  if (!excCtor) {
+    jthr = (*env)->ExceptionOccurred(env);
+    (*env)->ExceptionClear(env);
+    goto done;
+  }
+  need = vsnprintf(buf, sizeof(buf), fmt, ap);
+  if (need < 0) {
+    fmt = "vsnprintf error";
+    need = strlen(fmt);
+  }
+  msg = malloc(need + 1);
+  vsnprintf(msg, need + 1, fmt, ap2);
+  jstr = (*env)->NewStringUTF(env, msg);
+  if (!jstr) {
+    jthr = (*env)->ExceptionOccurred(env);
+    (*env)->ExceptionClear(env);
+    goto done;
+  }
+  jthr = (*env)->NewObject(env, clazz, excCtor, jstr);
+  if (!jthr) {
+    jthr = (*env)->ExceptionOccurred(env);
+    (*env)->ExceptionClear(env);
+    goto done;
+  }
+
+done:
+  free(msg);
+  va_end(ap2);
+  (*env)->DeleteLocalRef(env, jstr);
+  return jthr;
+}
+
+jthrowable newException(JNIEnv* env, const char *name, const char *fmt, ...)
+{
+  va_list ap;
+  jthrowable jthr;
+
+  va_start(ap, fmt);
+  jthr = newExceptionV(env, name, fmt, ap);
+  va_end(ap);
+  return jthr;
+}
+
+jthrowable newRuntimeException(JNIEnv* env, const char *fmt, ...)
+{
+  va_list ap;
+  jthrowable jthr;
+
+  va_start(ap, fmt);
+  jthr = newExceptionV(env, "java/lang/RuntimeException", fmt, ap);
+  va_end(ap);
+  return jthr;
+}
+
+jthrowable newIOException(JNIEnv* env, const char *fmt, ...)
+{
+  va_list ap;
+  jthrowable jthr;
+
+  va_start(ap, fmt);
+  jthr = newExceptionV(env, "java/io/IOException", fmt, ap);
+  va_end(ap);
+  return jthr;
+}
+
+const char* terror(int errnum)
+{
+
+#if defined(__sun)
+// MT-Safe under Solaris which doesn't support sys_errlist/sys_nerr
+  return strerror(errnum); 
+#else
+  if ((errnum < 0) || (errnum >= sys_nerr)) {
+    return "unknown error.";
+  }
+  return sys_errlist[errnum];
+#endif
+}
+

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/native/org/apache/commons/crypto/exception.h
----------------------------------------------------------------------
diff --git a/src/main/native/org/apache/commons/crypto/exception.h b/src/main/native/org/apache/commons/crypto/exception.h
new file mode 100644
index 0000000..2d9a018
--- /dev/null
+++ b/src/main/native/org/apache/commons/crypto/exception.h
@@ -0,0 +1,104 @@
+/*
+ *  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.
+ */
+#ifndef CHIMERA_NATIVE_SRC_EXCEPTION_H
+#define CHIMERA_NATIVE_SRC_EXCEPTION_H
+
+#include <jni.h> /* for jthrowable */
+#include <stdarg.h> /* for va_list */
+#include "org_apache_commons_crypto.h"
+
+#ifdef WINDOWS
+/*
+ * gcc-style type-checked format arguments are not supported on Windows, so just
+ * stub this macro.
+ */
+#define TYPE_CHECKED_PRINTF_FORMAT(formatArg, varArgs)
+# else
+/* Use gcc type-checked format arguments. */
+#define TYPE_CHECKED_PRINTF_FORMAT(formatArg, varArgs) \
+  __attribute__((format(printf, formatArg, varArgs)))
+#endif
+
+/**
+ * Create a new Exception.
+ *
+ * No exceptions will be pending on return.
+ *
+ * @param env           The JNI environment
+ * @param name          full name of the Java exception class
+ * @param fmt           printf-style format string
+ * @param ap            printf-style arguments
+ *
+ * @return              The RuntimeException
+ */
+jthrowable newExceptionV(JNIEnv* env, const char *name,
+                         const char *fmt, va_list ap);
+
+/**
+ * Create a new Exception.
+ *
+ * No exceptions will be pending on return.
+ *
+ * @param env           The JNI environment
+ * @param name          full name of the Java exception class
+ * @param fmt           printf-style format string
+ * @param ...           printf-style arguments
+ *
+ * @return              The RuntimeException
+ */
+jthrowable newException(JNIEnv* env, const char *name, const char *fmt, ...)
+    TYPE_CHECKED_PRINTF_FORMAT(3, 4);
+
+/**
+ * Create a new RuntimeException.
+ *
+ * No exceptions will be pending on return.
+ *
+ * @param env           The JNI environment
+ * @param fmt           printf-style format string
+ * @param ...           printf-style arguments
+ *
+ * @return              The RuntimeException
+ */
+jthrowable newRuntimeException(JNIEnv* env, const char *fmt, ...)
+    TYPE_CHECKED_PRINTF_FORMAT(2, 3);
+
+/**
+ * Create a new IOException.
+ *
+ * No exceptions will be pending on return.
+ *
+ * @param env           The JNI environment
+ * @param fmt           printf-style format string
+ * @param ...           printf-style arguments
+ *
+ * @return              The IOException, or another exception if we failed
+ *                      to create the NativeIOException.
+ */
+jthrowable newIOException(JNIEnv* env, const char *fmt, ...)
+    TYPE_CHECKED_PRINTF_FORMAT(2, 3);
+
+/**
+ * Thread-safe strerror alternative.
+ *
+ * @param errnum        Error number.
+ * @return              Statically allocated error string.
+ */
+const char* terror(int errnum);
+
+#undef TYPE_CHECKED_PRINTF_FORMAT
+#endif

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/native/org/apache/commons/crypto/org_apache_commons_crypto.h
----------------------------------------------------------------------
diff --git a/src/main/native/org/apache/commons/crypto/org_apache_commons_crypto.h b/src/main/native/org/apache/commons/crypto/org_apache_commons_crypto.h
new file mode 100644
index 0000000..ae965c5
--- /dev/null
+++ b/src/main/native/org/apache/commons/crypto/org_apache_commons_crypto.h
@@ -0,0 +1,228 @@
+/**
+ * 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.
+ */
+
+/**
+ * This file includes some common utilities
+ * for all native code used in chimera.
+ */
+
+#if !defined ORG_APACHE_COMMONS_CRYPTO_H
+#define ORG_APACHE_COMMONS_CRYPTO_H
+
+#if defined(_WIN32)
+#undef UNIX
+#define WINDOWS
+#else
+#undef WINDOWS
+#define UNIX
+#endif
+
+/* A helper macro to 'throw' a java exception. */
+#define THROW(env, exception_name, message) \
+  { \
+	jclass ecls = (*env)->FindClass(env, exception_name); \
+	if (ecls) { \
+	  (*env)->ThrowNew(env, ecls, message); \
+	  (*env)->DeleteLocalRef(env, ecls); \
+	} \
+  }
+
+/* Helper macro to return if an exception is pending */
+#define PASS_EXCEPTIONS(env) \
+  { \
+    if ((*env)->ExceptionCheck(env)) return; \
+  }
+
+#define PASS_EXCEPTIONS_GOTO(env, target) \
+  { \
+    if ((*env)->ExceptionCheck(env)) goto target; \
+  }
+
+#define PASS_EXCEPTIONS_RET(env, ret) \
+  { \
+    if ((*env)->ExceptionCheck(env)) return (ret); \
+  }
+
+/**
+ * Unix definitions
+ */
+#ifdef UNIX
+#include <config.h>
+#include <dlfcn.h>
+#include <jni.h>
+
+/**
+ * A helper function to dlsym a 'symbol' from a given library-handle.
+ *
+ * @param env jni handle to report contingencies.
+ * @param handle handle to the dlopen'ed library.
+ * @param symbol symbol to load.
+ * @return returns the address where the symbol is loaded in memory,
+ *         <code>NULL</code> on error.
+ */
+static __attribute__ ((unused))
+void *do_dlsym(JNIEnv *env, void *handle, const char *symbol) {
+  if (!env || !handle || !symbol) {
+  	THROW(env, "java/lang/InternalError", NULL);
+  	return NULL;
+  }
+  char *error = NULL;
+  void *func_ptr = dlsym(handle, symbol);
+  if ((error = dlerror()) != NULL) {
+  	THROW(env, "java/lang/UnsatisfiedLinkError", symbol);
+  	return NULL;
+  }
+  return func_ptr;
+}
+
+/* A helper macro to dlsym the requisite dynamic symbol and bail-out on error. */
+#define LOAD_DYNAMIC_SYMBOL(func_ptr, env, handle, symbol) \
+  if ((func_ptr = do_dlsym(env, handle, symbol)) == NULL) { \
+    return; \
+  }
+#endif
+// Unix part end
+
+
+/**
+ * Windows definitions
+ */
+#ifdef WINDOWS
+
+/* Force using Unicode throughout the code */
+#ifndef UNICODE
+#define UNICODE
+#endif
+
+/* Microsoft C Compiler does not support the C99 inline keyword */
+#ifndef __cplusplus
+#define inline __inline;
+#endif // _cplusplus
+
+/* Optimization macros supported by GCC but for which there is no
+   direct equivalent in the Microsoft C compiler */
+#define likely(_c) (_c)
+#define unlikely(_c) (_c)
+
+/* Disable certain warnings in the native CRC32 code. */
+#pragma warning(disable:4018)		// Signed/unsigned mismatch.
+#pragma warning(disable:4244)		// Possible loss of data in conversion.
+#pragma warning(disable:4267)		// Possible loss of data.
+#pragma warning(disable:4996)		// Use of deprecated function.
+
+#include <Windows.h>
+#include <stdio.h>
+#include <jni.h>
+
+#define snprintf(a, b ,c, d) _snprintf_s((a), (b), _TRUNCATE, (c), (d))
+
+/* A helper macro to dlsym the requisite dynamic symbol and bail-out on error. */
+#define LOAD_DYNAMIC_SYMBOL(func_type, func_ptr, env, handle, symbol) \
+  if ((func_ptr = (func_type) do_dlsym(env, handle, symbol)) == NULL) { \
+    return; \
+  }
+
+/**
+ * A helper function to dynamic load a 'symbol' from a given library-handle.
+ *
+ * @param env jni handle to report contingencies.
+ * @param handle handle to the dynamic library.
+ * @param symbol symbol to load.
+ * @return returns the address where the symbol is loaded in memory,
+ *         <code>NULL</code> on error.
+ */
+static FARPROC WINAPI do_dlsym(JNIEnv *env, HMODULE handle, LPCSTR symbol) {
+  DWORD dwErrorCode = ERROR_SUCCESS;
+  FARPROC func_ptr = NULL;
+
+  if (!env || !handle || !symbol) {
+    THROW(env, "java/lang/InternalError", NULL);
+    return NULL;
+  }
+
+  func_ptr = GetProcAddress(handle, symbol);
+  if (func_ptr == NULL)
+  {
+    THROW(env, "java/lang/UnsatisfiedLinkError", symbol);
+  }
+  return func_ptr;
+}
+#endif
+// Windows part end
+
+
+#define LOCK_CLASS(env, clazz, classname) \
+  if ((*env)->MonitorEnter(env, clazz) != 0) { \
+    char exception_msg[128]; \
+    snprintf(exception_msg, 128, "Failed to lock %s", classname); \
+    THROW(env, "java/lang/InternalError", exception_msg); \
+  }
+
+#define UNLOCK_CLASS(env, clazz, classname) \
+  if ((*env)->MonitorExit(env, clazz) != 0) { \
+    char exception_msg[128]; \
+    snprintf(exception_msg, 128, "Failed to unlock %s", classname); \
+    THROW(env, "java/lang/InternalError", exception_msg); \
+  }
+
+#define RETRY_ON_EINTR(ret, expr) do { \
+  ret = expr; \
+} while ((ret == -1) && (errno == EINTR));
+
+#ifdef UNIX
+#include <dlfcn.h>
+#include "config.h"
+#endif
+
+#ifdef WINDOWS
+#include "winutils.h"
+#endif
+
+#include <openssl/aes.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+
+/**
+ * A helper macro to convert the java 'context-handle' 
+ * to a EVP_CIPHER_CTX pointer. 
+ */
+#define CONTEXT(context) ((EVP_CIPHER_CTX*)((ptrdiff_t)(context)))
+
+/**
+ * A helper macro to convert the EVP_CIPHER_CTX pointer to the 
+ * java 'context-handle'.
+ */
+#define JLONG(context) ((jlong)((ptrdiff_t)(context)))
+
+#define KEY_LENGTH_128 16
+#define KEY_LENGTH_192 24
+#define KEY_LENGTH_256 32
+#define IV_LENGTH 16
+
+#define ENCRYPT_MODE 1
+#define DECRYPT_MODE 0
+
+/** Currently only support AES/CTR/NoPadding. */
+#define AES_CTR 0
+#define AES_CBC 1
+#define NOPADDING 0
+#define PKCS5PADDING 1
+
+#endif
+
+//vim: sw=2: ts=2: et