commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ggreg...@apache.org
Subject [2/2] commons-crypto git commit: [CRYPTO-94] Consistently camel-case type names: OpenSsl* (native and more)
Date Thu, 30 Jun 2016 16:31:08 GMT
[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 <ggregory@apache.org>
Authored: Thu Jun 30 09:31:02 2016 -0700
Committer: Gary Gregory <ggregory@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);
-  }
-}


Mime
View raw message