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:34 UTC

[6/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/java/com/intel/chimera/stream/output/StreamOutput.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/stream/output/StreamOutput.java b/src/main/java/com/intel/chimera/stream/output/StreamOutput.java
deleted file mode 100644
index fdf0f03..0000000
--- a/src/main/java/com/intel/chimera/stream/output/StreamOutput.java
+++ /dev/null
@@ -1,101 +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 com.intel.chimera.stream.output;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.nio.ByteBuffer;
-
-/**
- * The StreamOutput class takes a <code>OutputStream</code> object and wraps it as 
- * <code>Output</code> object acceptable by <code>CryptoOutputStream</code> as the output target.
- */
-public class StreamOutput implements Output {
-  private byte[] buf;
-  private int bufferSize;
-  protected OutputStream out;
-
-  /**
-   * Constructs a {@link com.intel.chimera.stream.output.StreamOutput}.
-   *
-   * @param out the OutputStream object.
-   * @param bufferSize the buffersize.
-   */
-  public StreamOutput(OutputStream out, int bufferSize) {
-    this.out = out;
-    this.bufferSize = bufferSize;
-  }
-
-  /**
-   * Overrides the {@link com.intel.chimera.stream.output.Output#write(ByteBuffer)}.
-   * Writes a sequence of bytes to this output from the given buffer.
-   *
-   * @param  src
-   *         The buffer from which bytes are to be retrieved.
-   *
-   * @return The number of bytes written, possibly zero.
-   * @throws IOException if an I/O error occurs.
-   */
-  @Override
-  public int write(ByteBuffer src) throws IOException {
-    final int len = src.remaining();
-    final byte[] buf = getBuf();
-    
-    int remaining = len;
-    while(remaining > 0) {
-      final int n = Math.min(remaining, bufferSize);
-      src.get(buf, 0, n);
-      out.write(buf, 0, n);
-      remaining = src.remaining();
-    }
-    
-    return len;
-  }
-
-  /**
-   * Overrides the {@link Output#flush()}.
-   * Flushes this output and forces any buffered output bytes
-   * to be written out if the under layer output method support.
-   *
-   * @throws IOException if an I/O error occurs.
-   */
-  @Override
-  public void flush() throws IOException {
-    out.flush();
-  }
-
-  /**
-   * Overrides the {@link Output#close()}.
-   * Closes this output and releases any system resources associated
-   * with the under layer output.
-   *
-   * @throws IOException if an I/O error occurs.
-   */
-  @Override
-  public void close() throws IOException {
-    out.close();
-  }
-  
-  private byte[] getBuf() {
-    if (buf == null) {
-      buf = new byte[bufferSize];
-    }
-    return buf;
-  }
-
-}

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/utils/IOUtils.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/utils/IOUtils.java b/src/main/java/com/intel/chimera/utils/IOUtils.java
deleted file mode 100644
index 05986fb..0000000
--- a/src/main/java/com/intel/chimera/utils/IOUtils.java
+++ /dev/null
@@ -1,96 +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 com.intel.chimera.utils;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import com.intel.chimera.stream.input.Input;
-import org.apache.commons.logging.Log;
-
-/**
- * General utility methods for working with IO.
- */
-public class IOUtils {
-
-  /**
-   * Does the readFully based on the Input read.
-   *
-   * @param in the input stream of bytes.
-   * @param buf the buffer to be read.
-   * @param off the start offset in array buffer.
-   * @param len the maximum number of bytes to read.
-   * @throws IOException if an I/O error occurs.
-   */
-  public static void readFully(InputStream in, byte buf[],
-      int off, int len) throws IOException {
-    int toRead = len;
-    while (toRead > 0) {
-      int ret = in.read(buf, off, toRead);
-      if (ret < 0) {
-        throw new IOException( "Premature EOF from inputStream");
-      }
-      toRead -= ret;
-      off += ret;
-    }
-  }
-
-  /**
-   * Does the readFully based on Input's positioned read.
-   * This does not change the current offset of the stream and is thread-safe.
-   *
-   * @param in the input source.
-   * @param position the given position.
-   * @param buffer the buffer to be read.
-   * @param length the maximum number of bytes to read.
-   * @param offset the start offset in array buffer.
-   * @throws IOException if an I/O error occurs.
-   */
-  public static void readFully(Input in, long position,
-      byte[] buffer, int offset, int length) throws IOException {
-    int nread = 0;
-    while (nread < length) {
-      int nbytes = in.read(position+nread, buffer, offset+nread, length-nread);
-      if (nbytes < 0) {
-        throw new IOException("End of stream reached before reading fully.");
-      }
-      nread += nbytes;
-    }
-  }
-
-  /**
-   * Closes the Closeable objects and <b>ignore</b> any {@link IOException} or
-   * null pointers. Must only be used for cleanup in exception handlers.
-   *
-   * @param log the log to record problems to at debug level. Can be null.
-   * @param closeables the objects to close.
-   */
-  public static void cleanup(Log log, java.io.Closeable... closeables) {
-    for (java.io.Closeable c : closeables) {
-      if (c != null) {
-        try {
-          c.close();
-        } catch(Throwable e) {
-          if (log != null && log.isDebugEnabled()) {
-            log.debug("Exception in closing " + c, e);
-          }
-        }
-      }
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/utils/NativeCodeLoader.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/utils/NativeCodeLoader.java b/src/main/java/com/intel/chimera/utils/NativeCodeLoader.java
deleted file mode 100644
index 224750a..0000000
--- a/src/main/java/com/intel/chimera/utils/NativeCodeLoader.java
+++ /dev/null
@@ -1,279 +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 com.intel.chimera.utils;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.Properties;
-import java.util.UUID;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-
-/**
- * A helper to load the native code i.e. libchimera.so.
- * This handles the fallback to either the bundled libchimera-Linux-i386-32.so
- * or the default java implementations where appropriate.
- */
-public class NativeCodeLoader {
-
-  private static final Log LOG =
-    LogFactory.getLog(NativeCodeLoader.class);
-  
-  private static boolean nativeCodeLoaded = false;
-  
-  static {
-    // Try to load native library and set fallback flag appropriately
-    if(LOG.isDebugEnabled()) {
-      LOG.debug("Trying to load the custom-built native-chimera library...");
-    }
-
-    try {
-      File nativeLibFile = findNativeLibrary();
-      if (nativeLibFile != null) {
-        // Load extracted or specified native library.
-        System.load(nativeLibFile.getAbsolutePath());
-      } else {
-        // Load preinstalled library (in the path -Djava.library.path)
-        System.loadLibrary("chimera");
-      }
-      LOG.debug("Loaded the native library");
-      nativeCodeLoaded = true;
-    } catch (Throwable t) {
-      // Ignore failure to load
-      if(LOG.isDebugEnabled()) {
-        LOG.debug("Failed to load native library with error: " + t);
-        LOG.debug("java.library.path=" +
-            System.getProperty("java.library.path"));
-      }
-    }
-
-    if (!nativeCodeLoaded) {
-      LOG.warn("Unable to load native library for the platform... " +
-               "using builtin-java classes where applicable");
-    }
-  }
-
-  static File findNativeLibrary() {
-    // Try to load the library in chimera.lib.path */
-    String nativeLibraryPath = Utils
-        .getLibPath();
-    String nativeLibraryName = Utils
-        .getLibName();
-
-    // Resolve the library file name with a suffix (e.g., dll, .so, etc.)
-    if (nativeLibraryName == null)
-      nativeLibraryName = System.mapLibraryName("chimera");
-
-    if (nativeLibraryPath != null) {
-      File nativeLib = new File(nativeLibraryPath,
-          nativeLibraryName);
-      if (nativeLib.exists())
-        return nativeLib;
-    }
-
-    // Load an OS-dependent native library inside a jar file
-    nativeLibraryPath = "/com/intel/chimera/native/"
-        + OSInfo.getNativeLibFolderPathForCurrentOS();
-    boolean hasNativeLib = hasResource(nativeLibraryPath + "/"
-        + nativeLibraryName);
-    if(!hasNativeLib) {
-      if (OSInfo.getOSName().equals("Mac")) {
-        // Fix for openjdk7 for Mac
-        String altName = "libchimera.jnilib";
-        if (hasResource(nativeLibraryPath + "/" + altName)) {
-          nativeLibraryName = altName;
-          hasNativeLib = true;
-        }
-      }
-    }
-
-    if (!hasNativeLib) {
-      String errorMessage = String.format(
-          "no native library is found for os.name=%s and os.arch=%s",
-          OSInfo.getOSName(), OSInfo.getArchName());
-      throw new RuntimeException(errorMessage);
-    }
-
-    // Temporary folder for the native lib. Use the value of
-    // chimera.tempdir or java.io.tmpdir
-    String tempFolder = new File(Utils.getTmpDir())
-        .getAbsolutePath();
-
-    // Extract and load a native library inside the jar file
-    return extractLibraryFile(nativeLibraryPath,
-        nativeLibraryName, tempFolder);
-  }
-
-  /**
-   * Extracts the specified library file to the target folder.
-   * 
-   * @param libFolderForCurrentOS the library in chimera.lib.path.
-   * @param libraryFileName the library name.
-   * @param targetFolder Target folder for the native lib. Use the value of
-   *                     chimera.tempdir or java.io.tmpdir.
-   * @return the library file.
-   */
-  private static File extractLibraryFile(String libFolderForCurrentOS,
-      String libraryFileName, String targetFolder) {
-    String nativeLibraryFilePath = libFolderForCurrentOS + "/"
-        + libraryFileName;
-
-    // Attach UUID to the native library file to ensure multiple class loaders
-    // can read the libchimera multiple times.
-    String uuid = UUID.randomUUID().toString();
-    String extractedLibFileName = String.format("chimera-%s-%s-%s", getVersion(), uuid,
-        libraryFileName);
-    File extractedLibFile = new File(targetFolder, extractedLibFileName);
-
-    InputStream reader = null;
-    try {
-      // Extract a native library file into the target directory
-      reader = NativeCodeLoader.class.getResourceAsStream(nativeLibraryFilePath);
-      FileOutputStream writer = new FileOutputStream(extractedLibFile);
-      try {
-        byte[] buffer = new byte[8192];
-        int bytesRead;
-        while ((bytesRead = reader.read(buffer)) != -1) {
-          writer.write(buffer, 0, bytesRead);
-        }
-      } finally {
-        // Delete the extracted lib file on JVM exit.
-        extractedLibFile.deleteOnExit();
-
-        if (writer != null){
-          writer.close();
-        }
-
-        if (reader != null) {
-          reader.close();
-          reader = null;
-        }
-      }
-
-      // Set executable (x) flag to enable Java to load the native library
-      if (!extractedLibFile.setReadable(true) || !extractedLibFile.setExecutable(true)
-          || !extractedLibFile.setWritable(true, true)) {
-        throw new RuntimeException("Invalid path for library path");
-      }
-
-      // Check whether the contents are properly copied from the resource folder
-      {
-        InputStream nativeIn = null;
-        InputStream extractedLibIn = null;
-        try {
-          nativeIn =
-              NativeCodeLoader.class.getResourceAsStream(nativeLibraryFilePath);
-          extractedLibIn = new FileInputStream(extractedLibFile);
-          if (!contentsEquals(nativeIn, extractedLibIn))
-            throw new RuntimeException(String.format(
-                    "Failed to write a native library file at %s",
-                    extractedLibFile));
-        } finally {
-          if (nativeIn != null)
-            nativeIn.close();
-          if (extractedLibIn != null)
-            extractedLibIn.close();
-        }
-      }
-
-      return new File(targetFolder, extractedLibFileName);
-    } catch (IOException e) {
-      e.printStackTrace(System.err);
-      return null;
-    } finally{
-      if(reader != null){
-        try {
-          reader.close();
-        } catch (IOException e) {
-          e.printStackTrace();
-        }
-      }
-    }
-  }
-
-  /**
-   * Gets the version by reading pom.properties embedded in jar.
-   * This version data is used as a suffix of a dll file extracted from the
-   * jar.
-   * 
-   * @return the version string
-   */
-  public static String getVersion() {
-    URL versionFile = NativeCodeLoader.class
-        .getResource("/META-INF/maven/com.intel.chimera/chimera/pom.properties");
-    if (versionFile == null)
-      versionFile = NativeCodeLoader.class
-          .getResource("/com/intel/chimera/VERSION");
-
-    String version = "unknown";
-    try {
-      if (versionFile != null) {
-        Properties versionData = new Properties();
-        versionData.load(versionFile.openStream());
-        version = versionData.getProperty("version", version);
-        if (version.equals("unknown"))
-          version = versionData.getProperty("VERSION", version);
-        version = version.trim().replaceAll("[^0-9M\\.]", "");
-      }
-    } catch (IOException e) {
-      System.err.println(e);
-    }
-    return version;
-  }
-
-  private static boolean contentsEquals(InputStream in1, InputStream in2)
-      throws IOException {
-    if (!(in1 instanceof BufferedInputStream)) {
-      in1 = new BufferedInputStream(in1);
-    }
-    if (!(in2 instanceof BufferedInputStream)) {
-      in2 = new BufferedInputStream(in2);
-    }
-
-    int ch = in1.read();
-    while (ch != -1) {
-      int ch2 = in2.read();
-      if (ch != ch2)
-        return false;
-      ch = in1.read();
-    }
-    int ch2 = in2.read();
-    return ch2 == -1;
-  }
-
-  private static boolean hasResource(String path) {
-    return NativeCodeLoader.class.getResource(path) != null;
-  }
-
-  /**
-   * Checks whether native code is loaded for this platform.
-   * 
-   * @return <code>true</code> if native is loaded, 
-   *         else <code>false</code>.
-   */
-  public static boolean isNativeCodeLoaded() {
-    return nativeCodeLoaded;
-  }
-}

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/utils/OSInfo.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/utils/OSInfo.java b/src/main/java/com/intel/chimera/utils/OSInfo.java
deleted file mode 100644
index c979599..0000000
--- a/src/main/java/com/intel/chimera/utils/OSInfo.java
+++ /dev/null
@@ -1,190 +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 com.intel.chimera.utils;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Locale;
-
-/**
- * Provides OS name and architecture name.
- */
-public class OSInfo {
-  private static HashMap<String, String> archMapping = new HashMap<String, String>();
-
-  /**
-   * The constant string represents for X86 architecture, the value is: {@value #X86}.*/
-  public static final String X86 = "x86";
-
-  /**
-   * The constant string represents for X86_64 architecture, the value is:{@value #X86_64}.*/
-  public static final String X86_64 = "x86_64";
-
-  /**
-   * The constant string represents for IA64_32 architecture, the value is:{@value #IA64_32}.*/
-  public static final String IA64_32 = "ia64_32";
-
-  /**
-   * The constant string represents for IA64 architecture, the value is:{@value #IA64}.*/
-  public static final String IA64 = "ia64";
-
-  /**
-   * The constant string represents for PPC architecture, the value is:{@value #PPC}.*/
-  public static final String PPC = "ppc";
-
-  /**
-   * The constant string represents for PPC64 architecture, the value is:{@value #PPC64}.*/
-  public static final String PPC64 = "ppc64";
-
-  static {
-    // x86 mappings
-    archMapping.put(X86, X86);
-    archMapping.put("i386", X86);
-    archMapping.put("i486", X86);
-    archMapping.put("i586", X86);
-    archMapping.put("i686", X86);
-    archMapping.put("pentium", X86);
-
-    // x86_64 mappings
-    archMapping.put(X86_64, X86_64);
-    archMapping.put("amd64", X86_64);
-    archMapping.put("em64t", X86_64);
-    archMapping.put("universal", X86_64); // Needed for openjdk7 in Mac
-
-    // Itenium 64-bit mappings
-    archMapping.put(IA64, IA64);
-    archMapping.put("ia64w", IA64);
-
-    // Itenium 32-bit mappings, usually an HP-UX construct
-    archMapping.put(IA64_32, IA64_32);
-    archMapping.put("ia64n", IA64_32);
-
-    // PowerPC mappings
-    archMapping.put(PPC, PPC);
-    archMapping.put("power", PPC);
-    archMapping.put("powerpc", PPC);
-    archMapping.put("power_pc", PPC);
-    archMapping.put("power_rs", PPC);
-
-    // TODO: PowerPC 64bit mappings
-    archMapping.put(PPC64, PPC64);
-    archMapping.put("power64", PPC64);
-    archMapping.put("powerpc64", PPC64);
-    archMapping.put("power_pc64", PPC64);
-    archMapping.put("power_rs64", PPC64);
-  }
-
-  public static void main(String[] args) {
-    if (args.length >= 1) {
-      if ("--os".equals(args[0])) {
-        System.out.print(getOSName());
-        return;
-      } else if ("--arch".equals(args[0])) {
-        System.out.print(getArchName());
-        return;
-      }
-    }
-
-    System.out.print(getNativeLibFolderPathForCurrentOS());
-  }
-
-  /**
-   * Gets the native lib folder.
-   *
-   * @return the current OS's native lib folder.
-   */
-  public static String getNativeLibFolderPathForCurrentOS() {
-    return getOSName() + "/" + getArchName();
-  }
-
-  /**
-   * Gets the OS name.
-   *
-   * @return the OS name.
-   */
-  public static String getOSName() {
-    return translateOSNameToFolderName(System.getProperty("os.name"));
-  }
-
-  /**
-   * Gets the architecture name.
-   *
-   * @return the architecture name.
-   */
-  public static String getArchName() {
-    // if running Linux on ARM, need to determine ABI of JVM
-    String osArch = System.getProperty("os.arch");
-    if (osArch.startsWith("arm")
-        && System.getProperty("os.name").contains("Linux")) {
-      String javaHome = System.getProperty("java.home");
-      try {
-        // determine if first JVM found uses ARM hard-float ABI
-        String[] cmdarray = {
-            "/bin/sh",
-            "-c",
-            "find '" + javaHome
-                + "' -name 'libjvm.so' | head -1 | xargs readelf -A | "
-                + "grep 'Tag_ABI_VFP_args: VFP registers'" };
-        int exitCode = Runtime.getRuntime().exec(cmdarray).waitFor();
-        if (exitCode == 0)
-          return "armhf";
-      } catch (IOException e) {
-        // ignored: fall back to "arm" arch (soft-float ABI)
-      } catch (InterruptedException e) {
-        // ignored: fall back to "arm" arch (soft-float ABI)
-      }
-    } else {
-      String lc = osArch.toLowerCase(Locale.US);
-      if (archMapping.containsKey(lc))
-        return archMapping.get(lc);
-    }
-    return translateArchNameToFolderName(osArch);
-  }
-
-  /**
-   * Translates the OS name to folder name.
-   *
-   * @param osName the OS name.
-   * @return the folder name.
-   */
-  static String translateOSNameToFolderName(String osName) {
-    if (osName.contains("Windows")) {
-      return "Windows";
-    } else if (osName.contains("Mac")) {
-      return "Mac";
-    } else if (osName.contains("Linux")) {
-      return "Linux";
-    } else if (osName.contains("AIX")) {
-      return "AIX";
-    }
-
-    else {
-      return osName.replaceAll("\\W", "");
-    }
-  }
-
-  /**
-   * Translates the architecture name to folder name.
-   *
-   * @param archName the architecture name.
-   * @return the folder name.
-   */
-  static String translateArchNameToFolderName(String archName) {
-    return archName.replaceAll("\\W", "");
-  }
-}

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/utils/ReflectionUtils.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/utils/ReflectionUtils.java b/src/main/java/com/intel/chimera/utils/ReflectionUtils.java
deleted file mode 100644
index d40937a..0000000
--- a/src/main/java/com/intel/chimera/utils/ReflectionUtils.java
+++ /dev/null
@@ -1,204 +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 com.intel.chimera.utils;
-
-import java.lang.ref.WeakReference;
-import java.lang.reflect.Constructor;
-import java.util.Collections;
-import java.util.Map;
-import java.util.WeakHashMap;
-
-import com.intel.chimera.cipher.Cipher;
-
-/**
- * General utility methods for working with reflection.
- */
-public class ReflectionUtils {
-
-  private static final Map<ClassLoader, Map<String, WeakReference<Class<?>>>>
-    CACHE_CLASSES = new WeakHashMap<ClassLoader, Map<String, WeakReference<Class<?>>>>();
-
-  private static ClassLoader classLoader;
-  static {
-    classLoader = Thread.currentThread().getContextClassLoader();
-    if (classLoader == null) {
-      classLoader = Cipher.class.getClassLoader();
-    }
-  }
-
-  /**
-   * Sentinel value to store negative cache results in {@link #CACHE_CLASSES}.
-   */
-  private static final Class<?> NEGATIVE_CACHE_SENTINEL =
-    NegativeCacheSentinel.class;
-
-  /**
-   * A unique class which is used as a sentinel value in the caching
-   * for getClassByName. {@link Cipher#getClassByNameOrNull(String)}.
-   */
-  private static abstract class NegativeCacheSentinel {}
-
-  /**
-   * Uses the constructor represented by this {@code Constructor} object to
-   * create and initialize a new instance of the constructor's
-   * declaring class, with the specified initialization parameters.
-   *
-   * @param klass the Class object.
-   * @param args array of objects to be passed as arguments to
-   *             the constructor call.
-   * @return a new object created by calling the constructor
-   *            this object represents.
-   */
-  @SuppressWarnings("rawtypes")
-  public static <T> T newInstance(Class<T> klass, Object ... args) {
-    try {
-      Constructor<T> ctor = null;
-
-      if (args.length == 0) {
-        ctor = klass.getDeclaredConstructor(new Class[] {});
-      } else {
-        Class[] argClses = new Class[args.length];
-        for (int i = 0; i < args.length; i++) {
-          argClses[i] = args[i].getClass();
-        }
-        ctor = klass.getDeclaredConstructor(argClses);
-      }
-      ctor.setAccessible(true);
-      return ctor.newInstance(args);
-    } catch (Exception e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  /** 
-   * Gets the value of the <code>name</code> property as a <code>Class</code>
-   * implementing the interface specified by <code>xface</code>.
-   * If no such property is specified, then <code>defaultValue</code> is 
-   * returned.An exception is thrown if the returned class does not
-   * implement the named interface.
-   * 
-   * @param name the class name of default implementation.
-   * @param defaultValue default value.
-   * @param xface the interface implemented by the named class.
-   * @return property value as a <code>Class</code>, 
-   *         or <code>defaultValue</code>.
-   */
-  public static <U> Class<? extends U> getClass(String name, 
-                                         Class<? extends U> defaultValue, 
-                                         Class<U> xface) {
-    try {
-      Class<?> theClass = null;
-      if (name != null && !name.isEmpty()) {
-        theClass = getClassByName(name);
-      }
-      if (theClass == null) {
-        theClass = defaultValue;
-      }
-      if (theClass != null && !xface.isAssignableFrom(theClass))
-        throw new RuntimeException(theClass+" not "+xface.getName());
-      else if (theClass != null)
-        return theClass.asSubclass(xface);
-      else
-        return null;
-    } catch (Exception e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  /** 
-   * Gets the value of the <code>name</code> property as a <code>Class</code>.
-   * If no such property is specified, then <code>defaultValue</code> is 
-   * returned.
-   * 
-   * @param name the class name.
-   * @param defaultValue default value.
-   * @return property value as a <code>Class</code>, 
-   *         or <code>defaultValue</code>. 
-   */
-  public static Class<?> getClass(String name, Class<?> defaultValue) {
-    String valueString = System.getProperty(name);
-    if (valueString == null)
-      return defaultValue;
-    try {
-      return getClassByName(valueString);
-    } catch (ClassNotFoundException e) {
-      throw new RuntimeException(e);
-    }
-  }
-
-  /**
-   * Loads a class by name.
-   * 
-   * @param name the class name.
-   * @return the class object.
-   * @throws ClassNotFoundException if the class is not found.
-   */
-  public static Class<?> getClassByName(String name)
-      throws ClassNotFoundException {
-    Class<?> ret = getClassByNameOrNull(name);
-    if (ret == null) {
-      throw new ClassNotFoundException("Class " + name + " not found");
-    }
-    return ret;
-  }
-  
-  /**
-   * Loads a class by name, returning null rather than throwing an exception
-   * if it couldn't be loaded. This is to avoid the overhead of creating
-   * an exception.
-   * 
-   * @param name the class name.
-   * @return the class object, or null if it could not be found.
-   */
-  private static Class<?> getClassByNameOrNull(String name) {
-    Map<String, WeakReference<Class<?>>> map;
-
-    synchronized (CACHE_CLASSES) {
-      map = CACHE_CLASSES.get(classLoader);
-      if (map == null) {
-        map = Collections.synchronizedMap(
-          new WeakHashMap<String, WeakReference<Class<?>>>());
-        CACHE_CLASSES.put(classLoader, map);
-      }
-    }
-
-    Class<?> clazz = null;
-    WeakReference<Class<?>> ref = map.get(name); 
-    if (ref != null) {
-       clazz = ref.get();
-    }
-     
-    if (clazz == null) {
-      try {
-        clazz = Class.forName(name, true, classLoader);
-      } catch (ClassNotFoundException e) {
-        // Leave a marker that the class isn't found
-        map.put(name, new WeakReference<Class<?>>(NEGATIVE_CACHE_SENTINEL));
-        return null;
-      }
-      // two putters can race here, but they'll put the same class
-      map.put(name, new WeakReference<Class<?>>(clazz));
-      return clazz;
-    } else if (clazz == NEGATIVE_CACHE_SENTINEL) {
-      return null; // not found
-    } else {
-      // cache hit
-      return clazz;
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/utils/Utils.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/utils/Utils.java b/src/main/java/com/intel/chimera/utils/Utils.java
deleted file mode 100644
index ae0eecc..0000000
--- a/src/main/java/com/intel/chimera/utils/Utils.java
+++ /dev/null
@@ -1,362 +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 com.intel.chimera.utils;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.security.GeneralSecurityException;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Properties;
-
-import com.intel.chimera.cipher.Cipher;
-import com.intel.chimera.cipher.CipherFactory;
-import com.intel.chimera.cipher.CipherTransformation;
-
-import static com.intel.chimera.conf.ConfigurationKeys.CHIMERA_CRYPTO_STREAM_BUFFER_SIZE_DEFAULT;
-import static com.intel.chimera.conf.ConfigurationKeys.CHIMERA_CRYPTO_STREAM_BUFFER_SIZE_KEY;
-import static com.intel.chimera.conf.ConfigurationKeys.CHIMERA_CRYPTO_CIPHER_CLASSES_DEFAULT;
-import static com.intel.chimera.conf.ConfigurationKeys.CHIMERA_CRYPTO_CIPHER_CLASSES_KEY;
-import static com.intel.chimera.conf.ConfigurationKeys.CHIMERA_CRYPTO_CIPHER_JCE_PROVIDER_KEY;
-import static com.intel.chimera.conf.ConfigurationKeys.CHIMERA_CRYPTO_LIB_NAME_KEY;
-import static com.intel.chimera.conf.ConfigurationKeys.CHIMERA_CRYPTO_LIB_PATH_KEY;
-import static com.intel.chimera.conf.ConfigurationKeys.CHIMERA_CRYPTO_SECURE_RANDOM_DEVICE_FILE_PATH_DEFAULT;
-import static com.intel.chimera.conf.ConfigurationKeys.CHIMERA_CRYPTO_SECURE_RANDOM_DEVICE_FILE_PATH_KEY;
-import static com.intel.chimera.conf.ConfigurationKeys.CHIMERA_SYSTEM_PROPERTIES_FILE;
-import static com.intel.chimera.conf.ConfigurationKeys.CHIMERA_CRYPTO_LIB_TEMPDIR_KEY;
-
-/**
- * General utility methods.
- */
-public class Utils {
-  private static final int MIN_BUFFER_SIZE = 512;
-
-  protected static final CipherTransformation AES_CTR_NOPADDING = CipherTransformation.AES_CTR_NOPADDING;
-
-  /**
-   * For AES, the algorithm block is fixed size of 128 bits.
-   * @see http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
-   */
-  private static final int AES_BLOCK_SIZE = AES_CTR_NOPADDING.getAlgorithmBlockSize();
-
-  static {
-    loadChimeraSystemProperties();
-  }
-
-  /**
-   * loads system properties when configuration file of the name
-   * {@link #CHIMERA_SYSTEM_PROPERTIES_FILE} is found.
-   */
-  private static void loadChimeraSystemProperties() {
-    try {
-      InputStream is = Thread.currentThread().getContextClassLoader()
-          .getResourceAsStream(CHIMERA_SYSTEM_PROPERTIES_FILE);
-
-      if (is == null)
-        return; // no configuration file is found
-
-      // Load property file
-      Properties props = new Properties();
-      props.load(is);
-      is.close();
-      Enumeration<?> names = props.propertyNames();
-      while (names.hasMoreElements()) {
-        String name = (String) names.nextElement();
-        if (name.startsWith("chimera.")) {
-          if (System.getProperty(name) == null) {
-            System.setProperty(name, props.getProperty(name));
-          }
-        }
-      }
-    } catch (Throwable ex) {
-      System.err.println("Could not load '"
-          + CHIMERA_SYSTEM_PROPERTIES_FILE + "' from classpath: "
-          + ex.toString());
-    }
-  }
-
-  /**
-   * Forcibly free the direct buffer.
-   *
-   * @param buffer the bytebuffer to be freed.
-   */
-  public static void freeDirectBuffer(ByteBuffer buffer) {
-    if (buffer instanceof sun.nio.ch.DirectBuffer) {
-      final sun.misc.Cleaner bufferCleaner =
-          ((sun.nio.ch.DirectBuffer) buffer).cleaner();
-      bufferCleaner.clean();
-    }
-  }
-
-  /**
-   * Reads crypto buffer size.
-   *
-   * @param props The <code>Properties</code> class represents a set of
-   *              properties.
-   * @return the buffer size.
-   * */
-  public static int getBufferSize(Properties props) {
-    String bufferSizeStr = props.getProperty(
-        CHIMERA_CRYPTO_STREAM_BUFFER_SIZE_KEY);
-    if (bufferSizeStr == null || bufferSizeStr.isEmpty()) {
-      bufferSizeStr = System
-        .getProperty(CHIMERA_CRYPTO_STREAM_BUFFER_SIZE_KEY);
-    }
-    if (bufferSizeStr == null || bufferSizeStr.isEmpty()) {
-      return CHIMERA_CRYPTO_STREAM_BUFFER_SIZE_DEFAULT;
-    } else {
-      return Integer.parseInt(bufferSizeStr);
-    }
-  }
-
-  /**
-   * Gets the cipher class.
-   *
-   * @param props The <code>Properties</code> class represents a set of
-   *              properties.
-   * @return the cipher class based on the props.
-   */
-  public static String getCipherClassString(Properties props) {
-    final String configName = CHIMERA_CRYPTO_CIPHER_CLASSES_KEY;
-    return props.getProperty(configName) != null ? props.getProperty(configName) : System
-        .getProperty(configName, CHIMERA_CRYPTO_CIPHER_CLASSES_DEFAULT);
-  }
-
-  /**
-   * Gets the Jce provider.
-   *
-   * @param props The <code>Properties</code> class represents a set of
-   *              properties.
-   * @return the jce provider based on the props.
-   */
-  public static String getJCEProvider(Properties props) {
-    return props.getProperty(CHIMERA_CRYPTO_CIPHER_JCE_PROVIDER_KEY) != null ?
-        props.getProperty(CHIMERA_CRYPTO_CIPHER_JCE_PROVIDER_KEY) :
-        System.getProperty(CHIMERA_CRYPTO_CIPHER_JCE_PROVIDER_KEY);
-  }
-
-  /**
-   * Gets the random device path.
-   *
-   * @param props The <code>Properties</code> class represents a set of
-   *              properties.
-   * @return the random device path based on the props.
-   */
-  public static String getRandomDevPath(Properties props) {
-    String devPath = props.getProperty(
-        CHIMERA_CRYPTO_SECURE_RANDOM_DEVICE_FILE_PATH_KEY);
-    if (devPath == null) {
-      devPath = System.getProperty(
-          CHIMERA_CRYPTO_SECURE_RANDOM_DEVICE_FILE_PATH_KEY,
-          CHIMERA_CRYPTO_SECURE_RANDOM_DEVICE_FILE_PATH_DEFAULT);
-    }
-    return devPath;
-  }
-
-  /**
-   * Gets path of native library.
-   *
-   * @return the path of native library.
-   */
-  public static String getLibPath() {
-    return System.getProperty(CHIMERA_CRYPTO_LIB_PATH_KEY);
-  }
-
-  /**
-   * Gets the file name of native library.
-   *
-   * @return the file name of native library.
-   */
-  public static String getLibName() {
-    return System.getProperty(CHIMERA_CRYPTO_LIB_NAME_KEY);
-  }
-
-  /**
-   * Gets the temp directory for extracting crypto library.
-   *
-   * @return the temp directory.
-   */
-  public static String getTmpDir() {
-    return System.getProperty(CHIMERA_CRYPTO_LIB_TEMPDIR_KEY,
-        System.getProperty("java.io.tmpdir"));
-  }
-
-  /**
-   * Checks whether the cipher is supported streaming.
-   *
-   * @param cipher the {@link com.intel.chimera.cipher.Cipher} instance.
-   * @throws IOException if an I/O error occurs.
-   */
-  public static void checkStreamCipher(Cipher cipher) throws IOException {
-    if (cipher.getTransformation() != CipherTransformation.AES_CTR_NOPADDING) {
-      throw new IOException("AES/CTR/NoPadding is required");
-    }
-  }
-
-  /**
-   * Checks and floors buffer size.
-   *
-   * @param cipher the {@link com.intel.chimera.cipher.Cipher} instance.
-   * @param bufferSize the buffer size.
-   * @return the remaining buffer size.
-   */
-  public static int checkBufferSize(Cipher cipher, int bufferSize) {
-    checkArgument(bufferSize >= MIN_BUFFER_SIZE,
-        "Minimum value of buffer size is " + MIN_BUFFER_SIZE + ".");
-    return bufferSize - bufferSize % cipher.getTransformation()
-        .getAlgorithmBlockSize();
-  }
-
-  /**
-   * This method is only for Counter (CTR) mode. Generally the Cipher calculates the
-   * IV and maintain encryption context internally.For example a
-   * {@link javax.crypto.Cipher} will maintain its encryption context internally
-   * when we do encryption/decryption using the Cipher#update interface.
-   * <p/>
-   * Encryption/Decryption is not always on the entire file. For example,
-   * in Hadoop, a node may only decrypt a portion of a file (i.e. a split).
-   * In these situations, the counter is derived from the file position.
-   * <p/>
-   * The IV can be calculated by combining the initial IV and the counter with
-   * a lossless operation (concatenation, addition, or XOR).
-   * @see http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_.28CTR.29
-   *
-   * @param initIV initial IV
-   * @param counter counter for input stream position
-   * @param IV the IV for input stream position
-   */
-  public static void calculateIV(byte[] initIV, long counter, byte[] IV) {
-    checkArgument(initIV.length == AES_BLOCK_SIZE);
-    checkArgument(IV.length == AES_BLOCK_SIZE);
-
-    int i = IV.length; // IV length
-    int j = 0; // counter bytes index
-    int sum = 0;
-    while (i-- > 0) {
-      // (sum >>> Byte.SIZE) is the carry for addition
-      sum = (initIV[i] & 0xff) + (sum >>> Byte.SIZE);
-      if (j++ < 8) { // Big-endian, and long is 8 bytes length
-        sum += (byte) counter & 0xff;
-        counter >>>= 8;
-      }
-      IV[i] = (byte) sum;
-    }
-  }
-
-  /**
-   * Helper method to create a Cipher instance and throws only IOException.
-   *
-   * @param props The <code>Properties</code> class represents a set of
-   *              properties.
-   * @param transformation the CipherTransformation instance.
-   * @return the Cipher instance.
-   * @throws IOException if an I/O error occurs.
-   */
-  public static Cipher getCipherInstance(CipherTransformation transformation,
-      Properties props) throws IOException {
-    try {
-      return CipherFactory.getInstance(transformation, props);
-    } catch (GeneralSecurityException e) {
-      throw new IOException(e);
-    }
-  }
-
-  /**
-   * Ensures the truth of an expression involving one or more parameters to
-   * the calling method.
-   *
-   * @param expression a boolean expression.
-   * @throws IllegalArgumentException if expression is false.
-   */
-  public static void checkArgument(boolean expression) {
-    if(!expression) {
-      throw new IllegalArgumentException();
-    }
-  }
-
-  /**
-   * Checks the truth of an expression.
-   *
-   * @param expression   a boolean expression.
-   * @param errorMessage the exception message to use if the check fails;
-   *                     will be converted to a string using <code>String
-   *                     .valueOf(Object)</code>.
-   * @throws IllegalArgumentException if expression is false.
-   */
-  public static void checkArgument(boolean expression, Object errorMessage) {
-    if (!expression) {
-      throw new IllegalArgumentException(String.valueOf(errorMessage));
-    }
-  }
-
-  /**
-   * Ensures that an object reference passed as a parameter to the calling
-   * method is not null.
-   *
-   * @param reference an object reference.
-   * @return the non-null reference that was validated.
-   * @throws NullPointerException if reference is null.
-   */
-  public static <T> T checkNotNull(T reference) {
-    if(reference == null) {
-      throw new NullPointerException();
-    } else {
-      return reference;
-    }
-  }
-
-  /**
-   * Ensures the truth of an expression involving the state of the calling
-   * instance, but not involving any parameters to the calling method.
-   *
-   * @param expression a boolean expression.
-   * @throws IllegalStateException if expression is false.
-   */
-  public static void checkState(boolean expression) {
-    if(!expression) {
-      throw new IllegalStateException();
-    }
-  }
-
-  /**
-   * Splits class names sequence into substrings, Trim each substring into an
-   * entry,and returns an list of the entries.
-   *
-   * @param clazzNames a string consist of a list of the entries joined by a
-   *                   delimiter.
-   * @param separator  a delimiter for the input string.
-   * @return a list of class entries.
-   */
-  public static List<String> splitClassNames(String clazzNames,
-      String separator) {
-    List<String> res = new ArrayList<String>();
-    if (clazzNames == null || clazzNames.isEmpty()) {
-      return res;
-    }
-
-    for (String clazzName : clazzNames.split(separator)) {
-      clazzName = clazzName.trim();
-      if (!clazzName.isEmpty()) {
-        res.add(clazzName);
-      }
-    }
-    return res;
-  }
-}

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/com/intel/chimera/utils/package-info.java
----------------------------------------------------------------------
diff --git a/src/main/java/com/intel/chimera/utils/package-info.java b/src/main/java/com/intel/chimera/utils/package-info.java
deleted file mode 100644
index d1d9483..0000000
--- a/src/main/java/com/intel/chimera/utils/package-info.java
+++ /dev/null
@@ -1,21 +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.
- */
-/**
- * Utils classes
- */
-package com.intel.chimera.utils;

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/VERSION
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/VERSION b/src/main/java/org/apache/commons/crypto/VERSION
new file mode 100644
index 0000000..baca170
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/VERSION
@@ -0,0 +1 @@
+VERSION=1.0.0-SNAPSHOT

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/cipher/Cipher.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/cipher/Cipher.java b/src/main/java/org/apache/commons/crypto/cipher/Cipher.java
new file mode 100644
index 0000000..5f0f42b
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/cipher/Cipher.java
@@ -0,0 +1,155 @@
+/**
+ * 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.io.Closeable;
+import java.nio.ByteBuffer;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.util.Properties;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.ShortBufferException;
+
+/**
+ * The interface of cryptographic cipher for encryption and decryption.
+ */
+public interface Cipher extends Closeable {
+
+  /**
+   * A constant representing encrypt mode.  The mode constant to be used
+   * when calling init method of the Cipher.
+   */
+  int ENCRYPT_MODE = 1;
+
+  /**
+   * A constant representing decrypt mode.  The mode constant to be used 
+   * when calling init method of the Cipher.
+   */
+  int DECRYPT_MODE = 0;
+
+  /**
+   * Gets the CipherTransformation for this cipher.
+   *
+   * @return the CipherTransformation for this cipher.
+   */
+  CipherTransformation getTransformation();
+
+  /**
+   * Gets the properties for this cipher.
+   * 
+   * @return the properties for this cipher.
+   */
+  Properties getProperties();
+
+  /**
+   * Initializes the cipher with mode, key and iv.
+   * 
+   * @param mode {@link #ENCRYPT_MODE} or {@link #DECRYPT_MODE}
+   * @param key crypto key for the cipher
+   * @param iv Initialization vector for the cipher
+   * @throws InvalidKeyException if the given key is inappropriate for
+   * initializing this cipher, or its keysize exceeds the maximum allowable
+   * keysize (as determined from the configured jurisdiction policy files).
+   * @throws InvalidAlgorithmParameterException if the given algorithm
+   * parameters are inappropriate for this cipher, or this cipher requires
+   * algorithm parameters and <code>params</code> is null, or the given
+   * algorithm parameters imply a cryptographic strength that would exceed
+   * the legal limits (as determined from the configured jurisdiction
+   * policy files).
+   */
+  void init(int mode, byte[] key, byte[] iv)
+      throws InvalidKeyException, InvalidAlgorithmParameterException;
+
+  /**
+   * Continues a multiple-part encryption/decryption operation. The data
+   * is encrypted or decrypted, depending on how this cipher was initialized.
+   * 
+   * @param inBuffer the input ByteBuffer
+   * @param outBuffer the output ByteBuffer
+   * @return int number of bytes stored in <code>output</code>
+   * @throws ShortBufferException if there is insufficient space
+   * in the output buffer
+   */
+  int update(ByteBuffer inBuffer, ByteBuffer outBuffer)
+      throws ShortBufferException;
+
+  /**
+   * Continues a multiple-part encryption/decryption operation. The data
+   * is encrypted or decrypted, depending on how this cipher was initialized.
+   *
+   * @param input the input byte array
+   * @param inputOffset the offset in input where the input starts
+   * @param inputLen the input length
+   * @param output the byte array for the result
+   * @param outputOffset the offset in output where the result is stored
+   * @return the number of bytes stored in output
+   * @throws ShortBufferException if there is insufficient space in the output byte array
+   */
+  int update(byte[] input, int inputOffset, int inputLen,
+      byte[] output, int outputOffset)
+      throws ShortBufferException;
+
+  /**
+   * Encrypts or decrypts data in a single-part operation, or finishes a
+   * multiple-part operation.
+   * 
+   * @param inBuffer the input ByteBuffer
+   * @param outBuffer the output ByteBuffer
+   * @return int number of bytes stored in <code>output</code>
+   * @throws BadPaddingException if this cipher is in decryption mode,
+   * and (un)padding has been requested, but the decrypted data is not
+   * bounded by the appropriate padding bytes
+   * @throws IllegalBlockSizeException if this cipher is a block cipher,
+   * no padding has been requested (only in encryption mode), and the total
+   * input length of the data processed by this cipher is not a multiple of
+   * block size; or if this encryption algorithm is unable to
+   * process the input data provided.
+   * @throws ShortBufferException if the given output buffer is too small
+   * to hold the result
+   */
+  int doFinal(ByteBuffer inBuffer, ByteBuffer outBuffer)
+      throws ShortBufferException, IllegalBlockSizeException,
+      BadPaddingException;
+
+  /**
+   * Encrypts or decrypts data in a single-part operation, or finishes a
+   * multiple-part operation.
+   *
+   * @param input the input byte array
+   * @param inputOffset the offset in input where the input starts
+   * @param inputLen the input length
+   * @param output the byte array for the result
+   * @param outputOffset the offset in output where the result is stored
+   * @return the number of bytes stored in output
+   * @throws ShortBufferException if the given output byte array is too small
+   * to hold the result
+   * @throws BadPaddingException if this cipher is in decryption mode,
+   * and (un)padding has been requested, but the decrypted data is not
+   * bounded by the appropriate padding bytes
+   * @throws IllegalBlockSizeException if this cipher is a block cipher,
+   * no padding has been requested (only in encryption mode), and the total
+   * input length of the data processed by this cipher is not a multiple of
+   * block size; or if this encryption algorithm is unable to
+   * process the input data provided.
+   */
+  int doFinal(byte[] input, int inputOffset, int inputLen,
+      byte[] output, int outputOffset)
+      throws ShortBufferException, IllegalBlockSizeException, BadPaddingException;
+}

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/cipher/CipherFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/cipher/CipherFactory.java b/src/main/java/org/apache/commons/crypto/cipher/CipherFactory.java
new file mode 100644
index 0000000..c8272a6
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/cipher/CipherFactory.java
@@ -0,0 +1,105 @@
+/**
+ * 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.security.GeneralSecurityException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.commons.crypto.utils.ReflectionUtils;
+import org.apache.commons.crypto.utils.Utils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This is the factory class used for creating cipher class
+ */
+public class CipherFactory {
+  
+  /** LOG instance for {@CipherFactory} */
+  public final static Logger LOG = LoggerFactory.getLogger(CipherFactory.class);
+
+  /**
+   * Gets a cipher instance for specified algorithm/mode/padding.
+   *
+   * @param props
+   *          the configuration properties
+   * @param transformation
+   *          algorithm/mode/padding
+   * @return Cipher the cipher. Null value will be returned if no
+   *         cipher classes with transformation configured.
+   */
+  public static Cipher getInstance(CipherTransformation transformation,
+      Properties props) throws GeneralSecurityException {
+    List<Class<? extends Cipher>> klasses = getCipherClasses(props);
+    Cipher cipher = null;
+    if (klasses != null) {
+      for (Class<? extends Cipher> klass : klasses) {
+        try {
+          cipher = ReflectionUtils.newInstance(klass, props, transformation);
+          if (cipher != null) {
+            LOG.debug("Using cipher {} for transformation {}.", klass.getName(),
+                transformation.getName());
+            break;
+          }
+        } catch (Exception e) {
+          LOG.error("Cipher {} is not available or transformation {} is not " +
+            "supported.", klass.getName(), transformation.getName());
+        }
+      }
+    }
+
+    return (cipher == null) ? new JceCipher(props, transformation) : cipher;
+  }
+
+  /**
+   * Gets a cipher for algorithm/mode/padding in config value
+   * chimera.crypto.cipher.transformation
+   *
+   * @return Cipher the cipher object Null value will be returned if no
+   *         cipher classes with transformation configured.
+   */
+  public static Cipher getInstance(CipherTransformation transformation)
+      throws GeneralSecurityException {
+    return getInstance(transformation, null);
+  }
+
+  private static List<Class<? extends Cipher>> getCipherClasses(Properties props) {
+    List<Class<? extends Cipher>> result = new ArrayList<Class<? extends
+        Cipher>>();
+    String cipherClassString = Utils.getCipherClassString(props);
+    if (cipherClassString == null) {
+      LOG.debug("No cipher classes configured.");
+      return null;
+    }
+    for (String c : Utils.splitClassNames(cipherClassString, ",")) {
+      try {
+        Class<?> cls = ReflectionUtils.getClassByName(c);
+        result.add(cls.asSubclass(Cipher.class));
+      } catch (ClassCastException e) {
+        LOG.error("Class {} is not a Cipher.", c);
+      } catch (ClassNotFoundException e) {
+        LOG.error("Cipher {} not found.", c);
+      }
+    }
+
+    return result;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/cipher/CipherTransformation.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/cipher/CipherTransformation.java b/src/main/java/org/apache/commons/crypto/cipher/CipherTransformation.java
new file mode 100644
index 0000000..4bf0883
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/cipher/CipherTransformation.java
@@ -0,0 +1,96 @@
+/**
+ * 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;
+
+/**
+ * Defines properties of a CipherTransformation. Modeled after the ciphers in
+ * {@link javax.crypto.Cipher}.
+ */
+public enum CipherTransformation {
+
+  /** A crypto transformation representing AES/CTR/NoPadding */
+  AES_CTR_NOPADDING("AES/CTR/NoPadding", 16),
+  /** A crypto transformation representing AES/CBC/NoPadding */
+  AES_CBC_NOPADDING("AES/CBC/NoPadding", 16),
+  /** A crypto transformation representing AES/CBC/PKCS5Padding */
+  AES_CBC_PKCS5PADDING("AES/CBC/PKCS5Padding", 16);
+
+  private final String name;
+  private final int algorithmBlockSize;
+
+  /**
+   * Constructor for CipherTransformation.  Initalizes the cipher with algorithm
+   * name and block size of the algorithm.
+   *
+   * @param name the name of cipher algorithm
+   * @param algorithmBlockSize the blockSize of cipher algorithm
+   */
+  CipherTransformation(String name, int algorithmBlockSize) {
+    this.name = name;
+    this.algorithmBlockSize = algorithmBlockSize;
+  }
+
+  /**
+   * Gets the algorithm name of cipher.
+   *
+   * @return name of cipher transformation, as in {@link javax.crypto.Cipher}
+   */
+  public String getName() {
+    return name;
+  }
+
+  /**
+   * Gets the algorithm block size of cipher.
+   *
+   * @return size of an algorithm block in bytes.
+   */
+  public int getAlgorithmBlockSize() {
+    return algorithmBlockSize;
+  }
+
+  /**
+   * Overrides {@link java.lang.Enum#toString()}
+   *
+   * @return the name of cipher algorithm and blocksize.
+   */
+  @Override
+  public String toString() {
+    StringBuilder builder = new StringBuilder("{");
+    builder.append("name: " + name);
+    builder.append(", algorithmBlockSize: " + algorithmBlockSize);
+    builder.append("}");
+    return builder.toString();
+  }
+
+  /**
+   * Converts to CipherTransformation from name, {@link #algorithmBlockSize} 
+   * is fixed for certain cipher transformation, just need to compare the name.
+   *
+   * @param name cipher transformation name
+   * @return CipherTransformation cipher transformation
+   */
+  public static CipherTransformation fromName(String name) {
+    CipherTransformation[] transformations = CipherTransformation.values();
+    for (CipherTransformation transformation : transformations) {
+      if (transformation.getName().equals(name)) {
+        return transformation;
+      }
+    }
+    throw new IllegalArgumentException("Invalid transformation name: " + name);
+  }
+}

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/cipher/JceCipher.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/cipher/JceCipher.java b/src/main/java/org/apache/commons/crypto/cipher/JceCipher.java
new file mode 100644
index 0000000..99a70bd
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/cipher/JceCipher.java
@@ -0,0 +1,207 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.crypto.cipher;
+
+import java.nio.ByteBuffer;
+import java.security.GeneralSecurityException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.util.Properties;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.ShortBufferException;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.commons.crypto.utils.Utils;
+
+/**
+ * Implements the {@link org.apache.commons.crypto.cipher.Cipher} using JCE provider.
+ */
+public class JceCipher implements Cipher {
+  private final Properties props;
+  private final CipherTransformation transformation;
+  private final javax.crypto.Cipher cipher;
+
+  /**
+   * Constructs a {@link org.apache.commons.crypto.cipher.Cipher} based on JCE
+   * Cipher {@link javax.crypto.Cipher}.
+   * @param props properties for JCE cipher
+   * @param transformation transformation for JCE cipher
+   * @throws GeneralSecurityException if JCE cipher initialize failed
+   */
+  public JceCipher(Properties props, CipherTransformation transformation)
+      throws GeneralSecurityException {
+    this.props = props;
+    this.transformation = transformation;
+
+    String provider = Utils.getJCEProvider(props);
+    if (provider == null || provider.isEmpty()) {
+      cipher = javax.crypto.Cipher.getInstance(transformation.getName());
+    } else {
+      cipher = javax.crypto.Cipher.getInstance(transformation.getName(), provider);
+    }
+  }
+
+  /**
+   * Gets the CipherTransformation for the jce cipher.
+   *
+   * @return the CipherTransformation for this cipher
+   */
+  @Override
+  public CipherTransformation getTransformation() {
+    return transformation;
+  }
+
+  /**
+   * Gets the properties for the jce cipher.
+   *
+   * @return the properties for this cipher.
+   */
+  @Override
+  public Properties getProperties() {
+    return props;
+  }
+
+  /**
+   * Initializes the cipher with mode, key and iv.
+   * 
+   * @param mode {@link #ENCRYPT_MODE} or {@link #DECRYPT_MODE}
+   * @param key crypto key for the cipher
+   * @param iv Initialization vector for the cipher
+   * @throws InvalidAlgorithmParameterException if the given algorithm
+   * parameters are inappropriate for this cipher, or this cipher requires
+   * algorithm parameters and <code>params</code> is null, or the given
+   * algorithm parameters imply a cryptographic strength that would exceed
+   * the legal limits (as determined from the configured jurisdiction
+   * policy files).
+   */
+  @Override
+  public void init(int mode, byte[] key, byte[] iv)
+      throws InvalidKeyException, InvalidAlgorithmParameterException {
+    Utils.checkNotNull(key);
+    Utils.checkNotNull(iv);
+
+    int cipherMode = javax.crypto.Cipher.DECRYPT_MODE;
+    if (mode == ENCRYPT_MODE)
+      cipherMode = javax.crypto.Cipher.ENCRYPT_MODE;
+
+    cipher.init(cipherMode, new SecretKeySpec(key, "AES"),
+        new IvParameterSpec(iv));
+  }
+
+  /**
+   * Continues a multiple-part encryption/decryption operation. The data
+   * is encrypted or decrypted, depending on how this cipher was initialized.
+   * 
+   * @param inBuffer the input ByteBuffer
+   * @param outBuffer the output ByteBuffer
+   * @return int number of bytes stored in <code>output</code>
+   * @throws ShortBufferException if there is insufficient space
+   * in the output buffer
+   */
+  @Override
+  public int update(ByteBuffer inBuffer, ByteBuffer outBuffer)
+      throws ShortBufferException {
+    return cipher.update(inBuffer, outBuffer);
+  }
+
+  /**
+   * Continues a multiple-part encryption/decryption operation. The data
+   * is encrypted or decrypted, depending on how this cipher was initialized.
+   *
+   * @param input the input byte array
+   * @param inputOffset the offset in input where the input starts
+   * @param inputLen the input length
+   * @param output the byte array for the result
+   * @param outputOffset the offset in output where the result is stored
+   * @return the number of bytes stored in output
+   * @throws ShortBufferException if there is insufficient space in the output byte array
+   */
+  @Override
+  public int update(byte[] input, int inputOffset, int inputLen,
+      byte[] output, int outputOffset)
+      throws ShortBufferException {
+    return cipher.update(input, inputOffset, inputLen,
+                         output, outputOffset);
+  }
+
+  /**
+   * Encrypts or decrypts data in a single-part operation, or finishes a
+   * multiple-part operation. The data is encrypted or decrypted, depending
+   * on how this cipher was initialized.
+   *
+   * @param inBuffer the input ByteBuffer
+   * @param outBuffer the output ByteBuffer
+   * @return int number of bytes stored in <code>output</code>
+   * @throws BadPaddingException if this cipher is in decryption mode,
+   * and (un)padding has been requested, but the decrypted data is not
+   * bounded by the appropriate padding bytes
+   * @throws IllegalBlockSizeException if this cipher is a block cipher,
+   * no padding has been requested (only in encryption mode), and the total
+   * input length of the data processed by this cipher is not a multiple of
+   * block size; or if this encryption algorithm is unable to
+   * process the input data provided.
+   * @throws ShortBufferException if the given output buffer is too small
+   * to hold the result
+   */
+  @Override
+  public int doFinal(ByteBuffer inBuffer, ByteBuffer outBuffer)
+      throws ShortBufferException, IllegalBlockSizeException,
+      BadPaddingException {
+    return cipher.doFinal(inBuffer, outBuffer);
+  }
+
+  /**
+   * Encrypts or decrypts data in a single-part operation, or finishes a
+   * multiple-part operation.
+   *
+   * @param input the input byte array
+   * @param inputOffset the offset in input where the input starts
+   * @param inputLen the input length
+   * @param output the byte array for the result
+   * @param outputOffset the offset in output where the result is stored
+   * @return the number of bytes stored in output
+   * @throws ShortBufferException if the given output byte array is too small
+   * to hold the result
+   * @throws BadPaddingException if this cipher is in decryption mode,
+   * and (un)padding has been requested, but the decrypted data is not
+   * bounded by the appropriate padding bytes
+   * @throws IllegalBlockSizeException if this cipher is a block cipher,
+   * no padding has been requested (only in encryption mode), and the total
+   * input length of the data processed by this cipher is not a multiple of
+   * block size; or if this encryption algorithm is unable to
+   * process the input data provided.
+   */
+  @Override
+  public int doFinal(byte[] input, int inputOffset, int inputLen,
+      byte[] output, int outputOffset)
+      throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
+    return cipher.doFinal(input, inputOffset, inputLen,
+                          output, outputOffset);
+  }
+
+  /**
+   * Closes Jce cipher.
+   */
+  @Override
+  public void close() {
+    // Do nothing
+  }
+}

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/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
new file mode 100644
index 0000000..9365859
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/cipher/Openssl.java
@@ -0,0 +1,320 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.crypto.cipher;
+
+import java.nio.ByteBuffer;
+import java.security.NoSuchAlgorithmException;
+import java.util.StringTokenizer;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.ShortBufferException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.commons.crypto.utils.NativeCodeLoader;
+import org.apache.commons.crypto.utils.Utils;
+
+/**
+ * OpenSSL cryptographic wrapper using JNI.
+ * Currently only AES-CTR is supported. It's flexible to add
+ * other crypto algorithms/modes.
+ */
+public final class Openssl {
+  private static final Log LOG = LogFactory.getLog(Openssl.class.getName());
+
+  // Mode constant defined by Openssl JNI
+  public static final int ENCRYPT_MODE = 1;
+  public static final int DECRYPT_MODE = 0;
+
+  /** Currently only support AES/CTR/NoPadding. */
+  private static enum AlgorithmMode {
+    AES_CTR,
+    AES_CBC;
+
+    static int get(String algorithm, String mode)
+        throws NoSuchAlgorithmException {
+      try {
+        return AlgorithmMode.valueOf(algorithm + "_" + mode).ordinal();
+      } catch (Exception e) {
+        throw new NoSuchAlgorithmException("Doesn't support algorithm: " +
+            algorithm + " and mode: " + mode);
+      }
+    }
+  }
+
+  private static enum Padding {
+    NoPadding,
+    PKCS5Padding;
+
+    static int get(String padding) throws NoSuchPaddingException {
+      try {
+        return Padding.valueOf(padding).ordinal();
+      } catch (Exception e) {
+        throw new NoSuchPaddingException("Doesn't support padding: " + padding);
+      }
+    }
+  }
+
+  private long context = 0;
+  private final int algorithm;
+  private final int padding;
+
+  private static final String loadingFailureReason;
+
+  static {
+    String loadingFailure = null;
+    try {
+      if (NativeCodeLoader.isNativeCodeLoaded()) {
+        OpensslNative.initIDs();
+      }
+    } catch (Throwable t) {
+      loadingFailure = t.getMessage();
+      LOG.debug("Failed to load OpenSSL Cipher.", t);
+    } finally {
+      loadingFailureReason = loadingFailure;
+    }
+  }
+
+  /**
+   * Gets the failure reason when loading Openssl native.
+   * @return the failure reason.
+   */
+  public static String getLoadingFailureReason() {
+    return loadingFailureReason;
+  }
+
+  private Openssl(long context, int algorithm, int padding) {
+    this.context = context;
+    this.algorithm = algorithm;
+    this.padding = padding;
+  }
+
+  /**
+   * Return an <code>OpensslCipher<code> object that implements the specified
+   * transformation.
+   *
+   * @param transformation the name of the transformation, e.g.,
+   * AES/CTR/NoPadding.
+   * @return OpensslCipher an <code>OpensslCipher<code> object
+   * @throws NoSuchAlgorithmException if <code>transformation</code> is null,
+   * empty, in an invalid format, or if Openssl doesn't implement the
+   * specified algorithm.
+   * @throws NoSuchPaddingException if <code>transformation</code> contains
+   * a padding scheme that is not available.
+   */
+  public static final Openssl getInstance(String transformation)
+      throws NoSuchAlgorithmException, NoSuchPaddingException {
+    Transform transform = tokenizeTransformation(transformation);
+    int algorithmMode = AlgorithmMode.get(transform.algorithm, transform.mode);
+    int padding = Padding.get(transform.padding);
+    long context = OpensslNative.initContext(algorithmMode, padding);
+    return new Openssl(context, algorithmMode, padding);
+  }
+
+  /** Nested class for algorithm, mode and padding. */
+  private static class Transform {
+    final String algorithm;
+    final String mode;
+    final String padding;
+
+    public Transform(String algorithm, String mode, String padding) {
+      this.algorithm = algorithm;
+      this.mode = mode;
+      this.padding = padding;
+    }
+  }
+
+  private static Transform tokenizeTransformation(String transformation)
+      throws NoSuchAlgorithmException {
+    if (transformation == null) {
+      throw new NoSuchAlgorithmException("No transformation given.");
+    }
+
+    /*
+     * Array containing the components of a Cipher transformation:
+     *
+     * index 0: algorithm (e.g., AES)
+     * index 1: mode (e.g., CTR)
+     * index 2: padding (e.g., NoPadding)
+     */
+    String[] parts = new String[3];
+    int count = 0;
+    StringTokenizer parser = new StringTokenizer(transformation, "/");
+    while (parser.hasMoreTokens() && count < 3) {
+      parts[count++] = parser.nextToken().trim();
+    }
+    if (count != 3 || parser.hasMoreTokens()) {
+      throw new NoSuchAlgorithmException("Invalid transformation format: " +
+          transformation);
+    }
+    return new Transform(parts[0], parts[1], parts[2]);
+  }
+
+  /**
+   * Initialize this cipher with a key and IV.
+   *
+   * @param mode {@link #ENCRYPT_MODE} or {@link #DECRYPT_MODE}
+   * @param key crypto key
+   * @param iv crypto iv
+   */
+  public void init(int mode, byte[] key, byte[] iv) {
+    context = OpensslNative.init(context, mode, algorithm, padding, key, iv);
+  }
+
+  /**
+   * Continues a multiple-part encryption or decryption operation. The data
+   * is encrypted or decrypted, depending on how this cipher was initialized.
+   * <p/>
+   *
+   * All <code>input.remaining()</code> bytes starting at
+   * <code>input.position()</code> are processed. The result is stored in
+   * the output buffer.
+   * <p/>
+   *
+   * Upon return, the input buffer's position will be equal to its limit;
+   * its limit will not have changed. The output buffer's position will have
+   * advanced by n, when n is the value returned by this method; the output
+   * buffer's limit will not have changed.
+   * <p/>
+   *
+   * If <code>output.remaining()</code> bytes are insufficient to hold the
+   * result, a <code>ShortBufferException</code> is thrown.
+   *
+   * @param input the input ByteBuffer
+   * @param output the output ByteBuffer
+   * @return int number of bytes stored in <code>output</code>
+   * @throws ShortBufferException if there is insufficient space in the
+   * output buffer
+   */
+  public int update(ByteBuffer input, ByteBuffer output)
+      throws ShortBufferException {
+    checkState();
+    Utils.checkArgument(input.isDirect() && output.isDirect(),
+        "Direct buffers are required.");
+    int len = OpensslNative.update(context, input, input.position(),
+        input.remaining(), output, output.position(), output.remaining());
+    input.position(input.limit());
+    output.position(output.position() + len);
+    return len;
+  }
+
+  /**
+   * Continues a multiple-part encryption/decryption operation. The data
+   * is encrypted or decrypted, depending on how this cipher was initialized.
+   *
+   * @param input the input byte array
+   * @param inputOffset the offset in input where the input starts
+   * @param inputLen the input length
+   * @param output the byte array for the result
+   * @param outputOffset the offset in output where the result is stored
+   * @return the number of bytes stored in output
+   * @throws ShortBufferException if there is insufficient space in the output byte array
+   */
+  public int update(byte[] input, int inputOffset, int inputLen,
+      byte[] output, int outputOffset)
+      throws ShortBufferException {
+    checkState();
+    return OpensslNative.updateByteArray(context, input, inputOffset, inputLen,
+        output, outputOffset, output.length - outputOffset);
+  }
+
+  /**
+   * Finishes a multiple-part operation. The data is encrypted or decrypted,
+   * depending on how this cipher was initialized.
+   * <p/>
+   *
+   * The result is stored in the output buffer. Upon return, the output buffer's
+   * position will have advanced by n, where n is the value returned by this
+   * method; the output buffer's limit will not have changed.
+   * <p/>
+   *
+   * If <code>output.remaining()</code> bytes are insufficient to hold the result,
+   * a <code>ShortBufferException</code> is thrown.
+   * <p/>
+   *
+   * Upon finishing, this method resets this cipher object to the state it was
+   * in when previously initialized. That is, the object is available to encrypt
+   * or decrypt more data.
+   * <p/>
+   *
+   * If any exception is thrown, this cipher object need to be reset before it
+   * can be used again.
+   *
+   * @param output the output ByteBuffer
+   * @return int number of bytes stored in <code>output</code>
+   * @throws ShortBufferException
+   * @throws IllegalBlockSizeException
+   * @throws BadPaddingException
+   */
+  public int doFinal(ByteBuffer output)
+      throws ShortBufferException, IllegalBlockSizeException,
+      BadPaddingException {
+    checkState();
+    Utils.checkArgument(output.isDirect(), "Direct buffer is required.");
+    int len = OpensslNative.doFinal(context, output, output.position(), output.remaining());
+    output.position(output.position() + len);
+    return len;
+  }
+
+  /**
+   * Encrypts or decrypts data in a single-part operation, or finishes a
+   * multiple-part operation.
+   *
+   * @param output the byte array for the result
+   * @param outputOffset the offset in output where the result is stored
+   * @return the number of bytes stored in output
+   * @throws ShortBufferException if the given output byte array is too small
+   * to hold the result
+   * @throws BadPaddingException if this cipher is in decryption mode,
+   * and (un)padding has been requested, but the decrypted data is not
+   * bounded by the appropriate padding bytes
+   * @throws IllegalBlockSizeException if this cipher is a block cipher,
+   * no padding has been requested (only in encryption mode), and the total
+   * input length of the data processed by this cipher is not a multiple of
+   * block size; or if this encryption algorithm is unable to
+   * process the input data provided.
+   */
+  public int doFinal(byte[] output, int outputOffset)
+      throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
+    checkState();
+    return OpensslNative.doFinalByteArray(context,
+        output, outputOffset, output.length - outputOffset);
+  }
+
+  /** Forcibly clean the context. */
+  public void clean() {
+    if (context != 0) {
+      OpensslNative.clean(context);
+      context = 0;
+    }
+  }
+
+  /** Checks whether context is initialized. */
+  private void checkState() {
+    Utils.checkState(context != 0);
+  }
+
+  @Override
+  protected void finalize() throws Throwable {
+    clean();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/commons-crypto/blob/4920d272/src/main/java/org/apache/commons/crypto/cipher/OpensslCipher.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/crypto/cipher/OpensslCipher.java b/src/main/java/org/apache/commons/crypto/cipher/OpensslCipher.java
new file mode 100644
index 0000000..52b2bf3
--- /dev/null
+++ b/src/main/java/org/apache/commons/crypto/cipher/OpensslCipher.java
@@ -0,0 +1,196 @@
+/**
+ * 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.io.IOException;
+import java.nio.ByteBuffer;
+import java.security.GeneralSecurityException;
+import java.util.Properties;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.ShortBufferException;
+
+import org.apache.commons.crypto.utils.Utils;
+
+/**
+ * Implements the Cipher using JNI into OpenSSL.
+ */
+public class OpensslCipher implements Cipher {
+  private final Properties props;
+  private final CipherTransformation transformation;
+  private final Openssl cipher;
+
+  /**
+   * Constructs a {@link org.apache.commons.crypto.cipher.Cipher} using JNI into OpenSSL
+   * 
+   * @param props properties for OpenSSL cipher
+   * @param transformation transformation for OpenSSL cipher
+   * @throws GeneralSecurityException if OpenSSL cipher initialize failed
+   */
+  public OpensslCipher(Properties props, CipherTransformation transformation)
+      throws GeneralSecurityException {
+    this.props = props;
+    this.transformation = transformation;
+
+    String loadingFailureReason = Openssl.getLoadingFailureReason();
+    if (loadingFailureReason != null) {
+      throw new RuntimeException(loadingFailureReason);
+    }
+
+    cipher = Openssl.getInstance(transformation.getName());
+  }
+
+  /**
+   * Gets the CipherTransformation for the openssl cipher.
+   *
+   * @return the CipherTransformation for this cipher
+   */
+  @Override
+  public CipherTransformation getTransformation() {
+    return transformation;
+  }
+
+  /**
+   * Gets the properties for the openssl cipher.
+   *
+   * @return the properties for this cipher.
+   */
+  @Override
+  public Properties getProperties() {
+    return props;
+  }
+
+  /**
+   * Initializes the cipher with mode, key and iv.
+   * @param mode {@link #ENCRYPT_MODE} or {@link #DECRYPT_MODE}
+   * @param key crypto key for the cipher
+   * @param iv Initialization vector for the cipher
+   * @throws IOException if cipher initialize fails
+   */
+  @Override
+  public void init(int mode, byte[] key, byte[] iv) {
+    Utils.checkNotNull(key);
+    Utils.checkNotNull(iv);
+
+    int cipherMode = Openssl.DECRYPT_MODE;
+    if (mode == ENCRYPT_MODE)
+      cipherMode = Openssl.ENCRYPT_MODE;
+
+    cipher.init(cipherMode, key, iv);
+  }
+
+  /**
+   * Continues a multiple-part encryption/decryption operation. The data
+   * is encrypted or decrypted, depending on how this cipher was initialized.
+   * @param inBuffer the input ByteBuffer
+   * @param outBuffer the output ByteBuffer
+   * @return int number of bytes stored in <code>output</code>
+   * @throws ShortBufferException if there is insufficient space
+   * in the output buffer
+   */
+  @Override
+  public int update(ByteBuffer inBuffer, ByteBuffer outBuffer)
+      throws ShortBufferException {
+    return cipher.update(inBuffer, outBuffer);
+  }
+
+  /**
+   * Continues a multiple-part encryption/decryption operation. The data
+   * is encrypted or decrypted, depending on how this cipher was initialized.
+   *
+   * @param input the input byte array
+   * @param inputOffset the offset in input where the input starts
+   * @param inputLen the input length
+   * @param output the byte array for the result
+   * @param outputOffset the offset in output where the result is stored
+   * @return the number of bytes stored in output
+   * @throws ShortBufferException if there is insufficient space in the output byte array
+   */
+  @Override
+  public int update(byte[] input, int inputOffset, int inputLen,
+      byte[] output, int outputOffset)
+      throws ShortBufferException {
+    return cipher.update(input, inputOffset, inputLen,
+                         output, outputOffset);
+  }
+
+  /**
+   * Encrypts or decrypts data in a single-part operation, or finishes a
+   * multiple-part operation. The data is encrypted or decrypted, depending
+   * on how this cipher was initialized.
+   * @param inBuffer the input ByteBuffer
+   * @param outBuffer the output ByteBuffer
+   * @return int number of bytes stored in <code>output</code>
+   * @throws BadPaddingException if this cipher is in decryption mode,
+   * and (un)padding has been requested, but the decrypted data is not
+   * bounded by the appropriate padding bytes
+   * @throws IllegalBlockSizeException if this cipher is a block cipher,
+   * no padding has been requested (only in encryption mode), and the total
+   * input length of the data processed by this cipher is not a multiple of
+   * block size; or if this encryption algorithm is unable to
+   * process the input data provided.
+   * @throws ShortBufferException if the given output buffer is too small
+   * to hold the result
+   */
+  @Override
+  public int doFinal(ByteBuffer inBuffer, ByteBuffer outBuffer)
+      throws ShortBufferException, IllegalBlockSizeException,
+      BadPaddingException {
+    int n = cipher.update(inBuffer, outBuffer);
+    return n + cipher.doFinal(outBuffer);
+  }
+
+  /**
+   * Encrypts or decrypts data in a single-part operation, or finishes a
+   * multiple-part operation.
+   *
+   * @param input the input byte array
+   * @param inputOffset the offset in input where the input starts
+   * @param inputLen the input length
+   * @param output the byte array for the result
+   * @param outputOffset the offset in output where the result is stored
+   * @return the number of bytes stored in output
+   * @throws ShortBufferException if the given output byte array is too small
+   * to hold the result
+   * @throws BadPaddingException if this cipher is in decryption mode,
+   * and (un)padding has been requested, but the decrypted data is not
+   * bounded by the appropriate padding bytes
+   * @throws IllegalBlockSizeException if this cipher is a block cipher,
+   * no padding has been requested (only in encryption mode), and the total
+   * input length of the data processed by this cipher is not a multiple of
+   * block size; or if this encryption algorithm is unable to
+   * process the input data provided.
+   */
+  @Override
+  public int doFinal(byte[] input, int inputOffset, int inputLen,
+      byte[] output, int outputOffset)
+      throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
+    int n = cipher.update(input, inputOffset, inputLen,
+                          output, outputOffset);
+    return n + cipher.doFinal(output, outputOffset + n);
+  }
+
+  /**
+   * Closes the OpenSSL cipher. Clean the Openssl native context.
+   */
+  @Override
+  public void close() {
+    cipher.clean();
+  }
+}