You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by cm...@apache.org on 2014/07/12 03:29:27 UTC
svn commit: r1609874 - in
/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common:
./ src/ src/main/java/org/apache/hadoop/crypto/
src/main/java/org/apache/hadoop/crypto/random/
src/main/java/org/apache/hadoop/fs/ src/main/native/src/...
Author: cmccabe
Date: Sat Jul 12 01:29:26 2014
New Revision: 1609874
URL: http://svn.apache.org/r1609874
Log:
HADOOP-10734. Implement high-performance secure random number sources. (Yi Liu via Colin Patrick McCabe)
Added:
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/random/
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/random/OpensslSecureRandom.java
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/random/OsSecureRandom.java
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/crypto/random/
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/crypto/random/OpensslSecureRandom.c
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/crypto/random/org_apache_hadoop_crypto_random.h
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/random/
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/random/TestOpensslSecureRandom.java
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/random/TestOsSecureRandom.java
Modified:
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/CHANGES-fs-encryption.txt
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/pom.xml
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/CMakeLists.txt
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/JceAesCtrCryptoCodec.java
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/OpensslAesCtrCryptoCodec.java
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeys.java
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeysPublic.java
hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml
Modified: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/CHANGES-fs-encryption.txt
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/CHANGES-fs-encryption.txt?rev=1609874&r1=1609873&r2=1609874&view=diff
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/CHANGES-fs-encryption.txt (original)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/CHANGES-fs-encryption.txt Sat Jul 12 01:29:26 2014
@@ -6,6 +6,9 @@ fs-encryption (Unreleased)
NEW FEATURES
+ HADOOP-10734. Implement high-performance secure random number sources.
+ (Yi Liu via Colin Patrick McCabe)
+
IMPROVEMENTS
HADOOP-10603. Crypto input and output streams implementing Hadoop stream
Modified: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/pom.xml
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/pom.xml?rev=1609874&r1=1609873&r2=1609874&view=diff
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/pom.xml (original)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/pom.xml Sat Jul 12 01:29:26 2014
@@ -542,6 +542,7 @@
<javahClassName>org.apache.hadoop.io.compress.lz4.Lz4Compressor</javahClassName>
<javahClassName>org.apache.hadoop.io.compress.lz4.Lz4Decompressor</javahClassName>
<javahClassName>org.apache.hadoop.crypto.OpensslCipher</javahClassName>
+ <javahClassName>org.apache.hadoop.crypto.random.OpensslSecureRandom</javahClassName>
<javahClassName>org.apache.hadoop.util.NativeCrc32</javahClassName>
<javahClassName>org.apache.hadoop.net.unix.DomainSocket</javahClassName>
<javahClassName>org.apache.hadoop.net.unix.DomainSocketWatcher</javahClassName>
@@ -657,6 +658,7 @@
<javahClassName>org.apache.hadoop.io.compress.lz4.Lz4Compressor</javahClassName>
<javahClassName>org.apache.hadoop.io.compress.lz4.Lz4Decompressor</javahClassName>
<javahClassName>org.apache.hadoop.crypto.OpensslCipher</javahClassName>
+ <javahClassName>org.apache.hadoop.crypto.random.OpensslSecureRandom</javahClassName>
<javahClassName>org.apache.hadoop.util.NativeCrc32</javahClassName>
</javahClassNames>
<javahOutputDirectory>${project.build.directory}/native/javah</javahOutputDirectory>
Modified: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/CMakeLists.txt
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/CMakeLists.txt?rev=1609874&r1=1609873&r2=1609874&view=diff
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/CMakeLists.txt (original)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/CMakeLists.txt Sat Jul 12 01:29:26 2014
@@ -167,7 +167,8 @@ find_path(OPENSSL_INCLUDE_DIR
if (OPENSSL_LIBRARY AND OPENSSL_INCLUDE_DIR)
GET_FILENAME_COMPONENT(HADOOP_OPENSSL_LIBRARY ${OPENSSL_LIBRARY} NAME)
SET(OPENSSL_SOURCE_FILES
- "${D}/crypto/OpensslCipher.c")
+ "${D}/crypto/OpensslCipher.c"
+ "${D}/crypto/random/OpensslSecureRandom.c")
else (OPENSSL_LIBRARY AND OPENSSL_INCLUDE_DIR)
SET(OPENSSL_INCLUDE_DIR "")
SET(OPENSSL_SOURCE_FILES "")
Modified: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/JceAesCtrCryptoCodec.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/JceAesCtrCryptoCodec.java?rev=1609874&r1=1609873&r2=1609874&view=diff
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/JceAesCtrCryptoCodec.java (original)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/JceAesCtrCryptoCodec.java Sat Jul 12 01:29:26 2014
@@ -32,8 +32,8 @@ import org.apache.hadoop.conf.Configurat
import com.google.common.base.Preconditions;
import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_CRYPTO_JCE_PROVIDER_KEY;
-import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_SECURE_RANDOM_ALGORITHM_KEY;
-import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_SECURE_RANDOM_ALGORITHM_DEFAULT;
+import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_JAVA_SECURE_RANDOM_ALGORITHM_KEY;
+import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_JAVA_SECURE_RANDOM_ALGORITHM_DEFAULT;
/**
* Implement the AES-CTR crypto codec using JCE provider.
@@ -57,8 +57,8 @@ public class JceAesCtrCryptoCodec extend
this.conf = conf;
provider = conf.get(HADOOP_SECURITY_CRYPTO_JCE_PROVIDER_KEY);
final String secureRandomAlg = conf.get(
- HADOOP_SECURITY_SECURE_RANDOM_ALGORITHM_KEY,
- HADOOP_SECURITY_SECURE_RANDOM_ALGORITHM_DEFAULT);
+ HADOOP_SECURITY_JAVA_SECURE_RANDOM_ALGORITHM_KEY,
+ HADOOP_SECURITY_JAVA_SECURE_RANDOM_ALGORITHM_DEFAULT);
try {
random = (provider != null) ?
SecureRandom.getInstance(secureRandomAlg, provider) :
Modified: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/OpensslAesCtrCryptoCodec.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/OpensslAesCtrCryptoCodec.java?rev=1609874&r1=1609873&r2=1609874&view=diff
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/OpensslAesCtrCryptoCodec.java (original)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/OpensslAesCtrCryptoCodec.java Sat Jul 12 01:29:26 2014
@@ -17,23 +17,34 @@
*/
package org.apache.hadoop.crypto;
+import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_SECURE_RANDOM_IMPL_KEY;
+
+import java.io.Closeable;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
+import java.util.Random;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.conf.Configuration;
import com.google.common.base.Preconditions;
+import org.apache.hadoop.crypto.random.OsSecureRandom;
+import org.apache.hadoop.util.ReflectionUtils;
/**
* Implement the AES-CTR crypto codec using JNI into OpenSSL.
*/
@InterfaceAudience.Private
public class OpensslAesCtrCryptoCodec extends AesCtrCryptoCodec {
+ private static final Log LOG =
+ LogFactory.getLog(OpensslAesCtrCryptoCodec.class.getName());
+
private Configuration conf;
- private SecureRandom random = new SecureRandom();
+ private Random random;
public OpensslAesCtrCryptoCodec() {
}
@@ -41,6 +52,26 @@ public class OpensslAesCtrCryptoCodec ex
@Override
public void setConf(Configuration conf) {
this.conf = conf;
+ final Class<? extends Random> klass = conf.getClass(
+ HADOOP_SECURITY_SECURE_RANDOM_IMPL_KEY, OsSecureRandom.class,
+ Random.class);
+ try {
+ random = ReflectionUtils.newInstance(klass, conf);
+ } catch (Exception e) {
+ LOG.info("Unable to use " + klass.getName() + ". Falling back to " +
+ "Java SecureRandom.", e);
+ this.random = new SecureRandom();
+ }
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ Closeable r = (Closeable) this.random;
+ r.close();
+ } catch (ClassCastException e) {
+ }
+ super.finalize();
}
@Override
Added: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/random/OpensslSecureRandom.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/random/OpensslSecureRandom.java?rev=1609874&view=auto
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/random/OpensslSecureRandom.java (added)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/random/OpensslSecureRandom.java Sat Jul 12 01:29:26 2014
@@ -0,0 +1,119 @@
+/**
+ * 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.hadoop.crypto.random;
+
+import java.util.Random;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.util.NativeCodeLoader;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * OpenSSL secure random using JNI.
+ * This implementation is thread-safe.
+ * <p/>
+ *
+ * If using an Intel chipset with RDRAND, the high-performance hardware
+ * random number generator will be used and it's much faster than
+ * {@link java.security.SecureRandom}. If RDRAND is unavailable, default
+ * OpenSSL secure random generator will be used. It's still faster
+ * and can generate strong random bytes.
+ * <p/>
+ * @see https://wiki.openssl.org/index.php/Random_Numbers
+ * @see http://en.wikipedia.org/wiki/RdRand
+ */
+@InterfaceAudience.Private
+public class OpensslSecureRandom extends Random {
+ private static final long serialVersionUID = -7828193502768789584L;
+ private static final Log LOG =
+ LogFactory.getLog(OpensslSecureRandom.class.getName());
+
+ /** If native SecureRandom unavailable, use java SecureRandom */
+ private java.security.SecureRandom fallback = null;
+ private static boolean nativeEnabled = false;
+ static {
+ if (NativeCodeLoader.isNativeCodeLoaded() &&
+ NativeCodeLoader.buildSupportsOpenssl()) {
+ try {
+ initSR();
+ nativeEnabled = true;
+ } catch (Throwable t) {
+ LOG.error("Failed to load Openssl SecureRandom", t);
+ }
+ }
+ }
+
+ public static boolean isNativeCodeLoaded() {
+ return nativeEnabled;
+ }
+
+ public OpensslSecureRandom() {
+ if (!nativeEnabled) {
+ fallback = new java.security.SecureRandom();
+ }
+ }
+
+ /**
+ * Generates a user-specified number of random bytes.
+ * It's thread-safe.
+ *
+ * @param bytes the array to be filled in with random bytes.
+ */
+ @Override
+ public void nextBytes(byte[] bytes) {
+ if (!nativeEnabled || !nextRandBytes(bytes)) {
+ fallback.nextBytes(bytes);
+ }
+ }
+
+ @Override
+ public void setSeed(long seed) {
+ // Self-seeding.
+ }
+
+ /**
+ * Generates an integer containing the user-specified number of
+ * random bits (right justified, with leading zeros).
+ *
+ * @param numBits number of random bits to be generated, where
+ * 0 <= <code>numBits</code> <= 32.
+ *
+ * @return int an <code>int</code> containing the user-specified number
+ * of random bits (right justified, with leading zeros).
+ */
+ @Override
+ final protected int next(int numBits) {
+ Preconditions.checkArgument(numBits >= 0 && numBits <= 32);
+ int numBytes = (numBits + 7) / 8;
+ byte b[] = new byte[numBytes];
+ int next = 0;
+
+ nextBytes(b);
+ for (int i = 0; i < numBytes; i++) {
+ next = (next << 8) + (b[i] & 0xFF);
+ }
+
+ return next >>> (numBytes * 8 - numBits);
+ }
+
+ private native static void initSR();
+ private native boolean nextRandBytes(byte[] bytes);
+}
Added: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/random/OsSecureRandom.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/random/OsSecureRandom.java?rev=1609874&view=auto
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/random/OsSecureRandom.java (added)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/random/OsSecureRandom.java Sat Jul 12 01:29:26 2014
@@ -0,0 +1,115 @@
+/**
+ * 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.hadoop.crypto.random;
+
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Random;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.conf.Configurable;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.io.IOUtils;
+
+import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_SECURE_RANDOM_DEVICE_FILE_PATH_KEY;
+import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_SECURE_RANDOM_DEVICE_FILE_PATH_DEFAULT;
+
+/**
+ * A Random implementation that uses random bytes sourced from the
+ * operating system.
+ */
+@InterfaceAudience.Private
+public class OsSecureRandom extends Random implements Closeable, Configurable {
+
+ private Configuration conf;
+
+ private final int RESERVOIR_LENGTH = 8192;
+
+ private String randomDevPath;
+
+ private FileInputStream stream;
+
+ private final byte[] reservoir = new byte[RESERVOIR_LENGTH];
+
+ private int pos = reservoir.length;
+
+ private void fillReservoir(int min) {
+ if (pos >= reservoir.length - min) {
+ try {
+ IOUtils.readFully(stream, reservoir, 0, reservoir.length);
+ } catch (IOException e) {
+ throw new RuntimeException("failed to fill reservoir", e);
+ }
+ pos = 0;
+ }
+ }
+
+ public OsSecureRandom() {
+ }
+
+ @Override
+ public void setConf(Configuration conf) {
+ this.conf = conf;
+ this.randomDevPath = conf.get(
+ HADOOP_SECURITY_SECURE_RANDOM_DEVICE_FILE_PATH_KEY,
+ HADOOP_SECURITY_SECURE_RANDOM_DEVICE_FILE_PATH_DEFAULT);
+ File randomDevFile = new File(randomDevPath);
+ try {
+ this.stream = new FileInputStream(randomDevFile);
+ fillReservoir(0);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public Configuration getConf() {
+ return conf;
+ }
+
+ @Override
+ synchronized public void nextBytes(byte[] bytes) {
+ int off = 0;
+ int n = 0;
+ while (off < bytes.length) {
+ fillReservoir(0);
+ n = Math.min(bytes.length - off, reservoir.length - pos);
+ System.arraycopy(reservoir, pos, bytes, off, n);
+ off += n;
+ pos += n;
+ }
+ }
+
+ @Override
+ synchronized protected int next(int nbits) {
+ fillReservoir(4);
+ int n = reservoir[pos] |
+ (reservoir[pos + 1] << 8) |
+ (reservoir[pos + 2] << 16) |
+ (reservoir[pos + 3] << 24);
+ pos += 4;
+ return n & (0xffffffff >> (32 - nbits));
+ }
+
+ @Override
+ public void close() throws IOException {
+ stream.close();
+ }
+}
Modified: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeys.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeys.java?rev=1609874&r1=1609873&r2=1609874&view=diff
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeys.java (original)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeys.java Sat Jul 12 01:29:26 2014
@@ -280,5 +280,4 @@ public class CommonConfigurationKeys ext
public static final String NFS_EXPORTS_ALLOWED_HOSTS_SEPARATOR = ";";
public static final String NFS_EXPORTS_ALLOWED_HOSTS_KEY = "nfs.exports.allowed.hosts";
public static final String NFS_EXPORTS_ALLOWED_HOSTS_KEY_DEFAULT = "* rw";
-
}
Modified: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeysPublic.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeysPublic.java?rev=1609874&r1=1609873&r2=1609874&view=diff
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeysPublic.java (original)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeysPublic.java Sat Jul 12 01:29:26 2014
@@ -297,10 +297,16 @@ public class CommonConfigurationKeysPubl
public static final String HADOOP_SECURITY_IMPERSONATION_PROVIDER_CLASS =
"hadoop.security.impersonation.provider.class";
/** See <a href="{@docRoot}/../core-default.html">core-default.xml</a> */
- public static final String HADOOP_SECURITY_SECURE_RANDOM_ALGORITHM_KEY =
- "hadoop.security.secure.random.algorithm";
- /** Defalt value for HADOOP_SECURITY_SECURE_RANDOM_ALGORITHM_KEY */
- public static final String HADOOP_SECURITY_SECURE_RANDOM_ALGORITHM_DEFAULT =
+ public static final String HADOOP_SECURITY_JAVA_SECURE_RANDOM_ALGORITHM_KEY =
+ "hadoop.security.java.secure.random.algorithm";
+ /** Defalt value for HADOOP_SECURITY_JAVA_SECURE_RANDOM_ALGORITHM_KEY */
+ public static final String HADOOP_SECURITY_JAVA_SECURE_RANDOM_ALGORITHM_DEFAULT =
"SHA1PRNG";
+ public static final String HADOOP_SECURITY_SECURE_RANDOM_IMPL_KEY =
+ "hadoop.security.secure.random.impl";
+ public static final String HADOOP_SECURITY_SECURE_RANDOM_DEVICE_FILE_PATH_KEY =
+ "hadoop.security.random.device.file.path";
+ public static final String HADOOP_SECURITY_SECURE_RANDOM_DEVICE_FILE_PATH_DEFAULT =
+ "/dev/urandom";
}
Added: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/crypto/random/OpensslSecureRandom.c
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/crypto/random/OpensslSecureRandom.c?rev=1609874&view=auto
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/crypto/random/OpensslSecureRandom.c (added)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/crypto/random/OpensslSecureRandom.c Sat Jul 12 01:29:26 2014
@@ -0,0 +1,335 @@
+/**
+ * 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_hadoop_crypto_random.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef UNIX
+#include <pthread.h>
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#endif
+
+#ifdef WINDOWS
+#include <windows.h>
+#endif
+
+#include "org_apache_hadoop_crypto_random_OpensslSecureRandom.h"
+
+#ifdef UNIX
+static void * (*dlsym_CRYPTO_malloc) (int, const char *, int);
+static void (*dlsym_CRYPTO_free) (void *);
+static int (*dlsym_CRYPTO_num_locks) (void);
+static void (*dlsym_CRYPTO_set_locking_callback) (void (*)());
+static void (*dlsym_CRYPTO_set_id_callback) (unsigned long (*)());
+static void (*dlsym_ENGINE_load_rdrand) (void);
+static ENGINE * (*dlsym_ENGINE_by_id) (const char *);
+static int (*dlsym_ENGINE_init) (ENGINE *);
+static int (*dlsym_ENGINE_set_default) (ENGINE *, unsigned int);
+static int (*dlsym_ENGINE_finish) (ENGINE *);
+static int (*dlsym_ENGINE_free) (ENGINE *);
+static void (*dlsym_ENGINE_cleanup) (void);
+static int (*dlsym_RAND_bytes) (unsigned char *, int);
+static unsigned long (*dlsym_ERR_get_error) (void);
+#endif
+
+#ifdef WINDOWS
+typedef void * (__cdecl *__dlsym_CRYPTO_malloc) (int, const char *, int);
+typedef void (__cdecl *__dlsym_CRYPTO_free) (void *);
+typedef int (__cdecl *__dlsym_CRYPTO_num_locks) (void);
+typedef void (__cdecl *__dlsym_CRYPTO_set_locking_callback) \
+ (void (*)(int, int, char *, int);
+typedef void (__cdecl *__dlsym_ENGINE_load_rdrand) (void);
+typedef ENGINE * (__cdecl *__dlsym_ENGINE_by_id) (const char *);
+typedef int (__cdecl *__dlsym_ENGINE_init) (ENGINE *);
+typedef int (__cdecl *__dlsym_ENGINE_set_default) (ENGINE *, unsigned int);
+typedef int (__cdecl *__dlsym_ENGINE_finish) (ENGINE *);
+typedef int (__cdecl *__dlsym_ENGINE_free) (ENGINE *);
+typedef void (__cdecl *__dlsym_ENGINE_cleanup) (void);
+typedef int (__cdecl *__dlsym_RAND_bytes) (unsigned char *, int);
+typedef unsigned long (__cdecl *__dlsym_ERR_get_error) (void);
+static __dlsym_CRYPTO_malloc dlsym_CRYPTO_malloc;
+static __dlsym_CRYPTO_free dlsym_CRYPTO_free;
+static __dlsym_CRYPTO_num_locks dlsym_CRYPTO_num_locks;
+static __dlsym_CRYPTO_set_locking_callback dlsym_CRYPTO_set_locking_callback;
+static __dlsym_ENGINE_load_rdrand dlsym_ENGINE_load_rdrand;
+static __dlsym_ENGINE_by_id dlsym_ENGINE_by_id;
+static __dlsym_ENGINE_init dlsym_ENGINE_init;
+static __dlsym_ENGINE_set_default dlsym_ENGINE_set_default;
+static __dlsym_ENGINE_finish dlsym_ENGINE_finish;
+static __dlsym_ENGINE_free dlsym_ENGINE_free;
+static __dlsym_ENGINE_cleanup dlsym_ENGINE_cleanup;
+static __dlsym_RAND_bytes dlsym_RAND_bytes;
+static __dlsym_ERR_get_error dlsym_ERR_get_error;
+#endif
+
+static ENGINE * openssl_rand_init();
+static void openssl_rand_clean(ENGINE *eng, int clean_locks);
+static int openssl_rand_bytes(unsigned char *buf, int num);
+
+JNIEXPORT void JNICALL Java_org_apache_hadoop_crypto_random_OpensslSecureRandom_initSR
+ (JNIEnv *env, jclass clazz)
+{
+ char msg[1000];
+#ifdef UNIX
+ void *openssl = dlopen(HADOOP_OPENSSL_LIBRARY, RTLD_LAZY | RTLD_GLOBAL);
+#endif
+
+#ifdef WINDOWS
+ HMODULE openssl = LoadLibrary(HADOOP_OPENSSL_LIBRARY);
+#endif
+
+ if (!openssl) {
+ snprintf(msg, sizeof(msg), "Cannot load %s (%s)!", HADOOP_OPENSSL_LIBRARY, \
+ dlerror());
+ THROW(env, "java/lang/UnsatisfiedLinkError", msg);
+ return;
+ }
+
+#ifdef UNIX
+ dlerror(); // Clear any existing error
+ LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_malloc, env, openssl, "CRYPTO_malloc");
+ LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_free, env, openssl, "CRYPTO_free");
+ LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_num_locks, env, openssl, "CRYPTO_num_locks");
+ LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_set_locking_callback, \
+ env, openssl, "CRYPTO_set_locking_callback");
+ LOAD_DYNAMIC_SYMBOL(dlsym_CRYPTO_set_id_callback, env, \
+ openssl, "CRYPTO_set_id_callback");
+ LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_load_rdrand, env, \
+ openssl, "ENGINE_load_rdrand");
+ LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_by_id, env, openssl, "ENGINE_by_id");
+ LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_init, env, openssl, "ENGINE_init");
+ LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_set_default, env, \
+ openssl, "ENGINE_set_default");
+ LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_finish, env, openssl, "ENGINE_finish");
+ LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_free, env, openssl, "ENGINE_free");
+ LOAD_DYNAMIC_SYMBOL(dlsym_ENGINE_cleanup, env, openssl, "ENGINE_cleanup");
+ LOAD_DYNAMIC_SYMBOL(dlsym_RAND_bytes, env, openssl, "RAND_bytes");
+ LOAD_DYNAMIC_SYMBOL(dlsym_ERR_get_error, env, openssl, "ERR_get_error");
+#endif
+
+#ifdef WINDOWS
+ LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_malloc, dlsym_CRYPTO_malloc, \
+ env, openssl, "CRYPTO_malloc");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_free, dlsym_CRYPTO_free, \
+ env, openssl, "CRYPTO_free");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_num_locks, dlsym_CRYPTO_num_locks, \
+ env, openssl, "CRYPTO_num_locks");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_CRYPTO_set_locking_callback, \
+ dlsym_CRYPTO_set_locking_callback, \
+ env, openssl, "CRYPTO_set_locking_callback");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_load_rdrand, dlsym_ENGINE_load_rdrand, \
+ env, openssl, "ENGINE_load_rdrand");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_by_id, dlsym_ENGINE_by_id, \
+ env, openssl, "ENGINE_by_id");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_init, dlsym_ENGINE_init, \
+ env, openssl, "ENGINE_init");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_set_default, dlsym_ENGINE_set_default, \
+ env, openssl, "ENGINE_set_default");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_finish, dlsym_ENGINE_finish, \
+ env, openssl, "ENGINE_finish");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_free, dlsym_ENGINE_free, \
+ env, openssl, "ENGINE_free");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_ENGINE_cleanup, dlsym_ENGINE_cleanup, \
+ env, openssl, "ENGINE_cleanup");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_RAND_bytes, dlsym_RAND_bytes, \
+ env, openssl, "RAND_bytes");
+ LOAD_DYNAMIC_SYMBOL(__dlsym_ERR_get_error, dlsym_ERR_get_error, \
+ env, openssl, "ERR_get_error");
+#endif
+
+ openssl_rand_init(env);
+}
+
+JNIEXPORT jboolean JNICALL Java_org_apache_hadoop_crypto_random_OpensslSecureRandom_nextRandBytes___3B
+ (JNIEnv *env, jobject object, jbyteArray bytes)
+{
+ if (NULL == bytes) {
+ THROW(env, "java/lang/NullPointerException", "Buffer cannot be null.");
+ return JNI_FALSE;
+ }
+ jbyte *b = (*env)->GetByteArrayElements(env, bytes, NULL);
+ if (NULL == b) {
+ THROW(env, "java/lang/InternalError", "Cannot get bytes array.");
+ return JNI_FALSE;
+ }
+ int b_len = (*env)->GetArrayLength(env, bytes);
+ int ret = openssl_rand_bytes((unsigned char *)b, b_len);
+ (*env)->ReleaseByteArrayElements(env, bytes, b, 0);
+
+ if (1 != ret) {
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+/**
+ * To ensure thread safety for random number generators, we need to call
+ * CRYPTO_set_locking_callback.
+ * http://wiki.openssl.org/index.php/Random_Numbers
+ * Example: crypto/threads/mttest.c
+ */
+
+#ifdef WINDOWS
+static void windows_locking_callback(int mode, int type, char *file, int line);
+static HANDLE *lock_cs;
+
+static void locks_setup(void)
+{
+ int i;
+ lock_cs = dlsym_CRYPTO_malloc(dlsym_CRYPTO_num_locks() * sizeof(HANDLE), \
+ __FILE__, __LINE__);
+
+ for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) {
+ lock_cs[i] = CreateMutex(NULL, FALSE, NULL);
+ }
+ dlsym_CRYPTO_set_locking_callback((void (*)(int, int, char *, int)) \
+ windows_locking_callback);
+ /* id callback defined */
+}
+
+static void locks_cleanup(void)
+{
+ int i;
+ dlsym_CRYPTO_set_locking_callback(NULL);
+
+ for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) {
+ CloseHandle(lock_cs[i]);
+ }
+ dlsym_CRYPTO_free(lock_cs);
+}
+
+static void windows_locking_callback(int mode, int type, char *file, int line)
+{
+ UNUSED(file), UNUSED(line);
+
+ if (mode & CRYPTO_LOCK) {
+ WaitForSingleObject(lock_cs[type], INFINITE);
+ } else {
+ ReleaseMutex(lock_cs[type]);
+ }
+}
+#endif /* WINDOWS */
+
+#ifdef UNIX
+static void pthreads_locking_callback(int mode, int type, char *file, int line);
+static unsigned long pthreads_thread_id(void);
+static pthread_mutex_t *lock_cs;
+
+static void locks_setup(void)
+{
+ int i;
+ lock_cs = dlsym_CRYPTO_malloc(dlsym_CRYPTO_num_locks() * \
+ sizeof(pthread_mutex_t), __FILE__, __LINE__);
+
+ for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) {
+ pthread_mutex_init(&(lock_cs[i]), NULL);
+ }
+
+ dlsym_CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);
+ dlsym_CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);
+}
+
+static void locks_cleanup(void)
+{
+ int i;
+ dlsym_CRYPTO_set_locking_callback(NULL);
+
+ for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) {
+ pthread_mutex_destroy(&(lock_cs[i]));
+ }
+
+ dlsym_CRYPTO_free(lock_cs);
+}
+
+static void pthreads_locking_callback(int mode, int type, char *file, int line)
+{
+ UNUSED(file), UNUSED(line);
+
+ if (mode & CRYPTO_LOCK) {
+ pthread_mutex_lock(&(lock_cs[type]));
+ } else {
+ pthread_mutex_unlock(&(lock_cs[type]));
+ }
+}
+
+static unsigned long pthreads_thread_id(void)
+{
+ return (unsigned long)syscall(SYS_gettid);
+}
+
+#endif /* UNIX */
+
+/**
+ * If using an Intel chipset with RDRAND, the high-performance hardware
+ * random number generator will be used.
+ */
+static ENGINE * openssl_rand_init()
+{
+ locks_setup();
+
+ dlsym_ENGINE_load_rdrand();
+ ENGINE *eng = dlsym_ENGINE_by_id("rdrand");
+
+ int ret = -1;
+ do {
+ if (NULL == eng) {
+ break;
+ }
+
+ int rc = dlsym_ENGINE_init(eng);
+ if (0 == rc) {
+ break;
+ }
+
+ rc = dlsym_ENGINE_set_default(eng, ENGINE_METHOD_RAND);
+ if (0 == rc) {
+ break;
+ }
+
+ ret = 0;
+ } while(0);
+
+ if (ret == -1) {
+ openssl_rand_clean(eng, 0);
+ }
+
+ return eng;
+}
+
+static void openssl_rand_clean(ENGINE *eng, int clean_locks)
+{
+ if (NULL != eng) {
+ dlsym_ENGINE_finish(eng);
+ dlsym_ENGINE_free(eng);
+ }
+
+ dlsym_ENGINE_cleanup();
+ if (clean_locks) {
+ locks_cleanup();
+ }
+}
+
+static int openssl_rand_bytes(unsigned char *buf, int num)
+{
+ return dlsym_RAND_bytes(buf, num);
+}
\ No newline at end of file
Added: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/crypto/random/org_apache_hadoop_crypto_random.h
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/crypto/random/org_apache_hadoop_crypto_random.h?rev=1609874&view=auto
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/crypto/random/org_apache_hadoop_crypto_random.h (added)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/native/src/org/apache/hadoop/crypto/random/org_apache_hadoop_crypto_random.h Sat Jul 12 01:29:26 2014
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ORG_APACHE_HADOOP_CRYPTO_RANDOM_H
+#define ORG_APACHE_HADOOP_CRYPTO_RANDOM_H
+
+#include "org_apache_hadoop.h"
+
+#ifdef UNIX
+#include <dlfcn.h>
+#include "config.h"
+#endif
+
+#ifdef WINDOWS
+#include "winutils.h"
+#endif
+
+#define UNUSED(x) ((void)(x))
+
+#include <openssl/crypto.h>
+#include <openssl/engine.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+
+#endif //ORG_APACHE_HADOOP_CRYPTO_RANDOM_H
\ No newline at end of file
Modified: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml?rev=1609874&r1=1609873&r2=1609874&view=diff
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml (original)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml Sat Jul 12 01:29:26 2014
@@ -1477,10 +1477,26 @@ for ldap providers in the same way as ab
</property>
<property>
- <name>hadoop.security.secure.random.algorithm</name>
+ <name>hadoop.security.java.secure.random.algorithm</name>
<value></value>
<description>
- The secure random algorithm.
+ The java secure random algorithm.
+ </description>
+</property>
+
+<property>
+ <name>hadoop.security.secure.random.impl</name>
+ <value></value>
+ <description>
+ Implementation of secure random.
+ </description>
+</property>
+
+<property>
+ <name>hadoop.security.random.device.file.path</name>
+ <value></value>
+ <description>
+ OS security random dev path, it's /dev/urandom in linux.
</description>
</property>
Added: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/random/TestOpensslSecureRandom.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/random/TestOpensslSecureRandom.java?rev=1609874&view=auto
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/random/TestOpensslSecureRandom.java (added)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/random/TestOpensslSecureRandom.java Sat Jul 12 01:29:26 2014
@@ -0,0 +1,114 @@
+/**
+ * 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.hadoop.crypto.random;
+
+import java.util.Arrays;
+
+import org.junit.Test;
+
+public class TestOpensslSecureRandom {
+
+ @Test(timeout=120000)
+ public void testRandomBytes() throws Exception {
+ OpensslSecureRandom random = new OpensslSecureRandom();
+
+ // len = 16
+ checkRandomBytes(random, 16);
+ // len = 32
+ checkRandomBytes(random, 32);
+ // len = 128
+ checkRandomBytes(random, 128);
+ // len = 256
+ checkRandomBytes(random, 256);
+ }
+
+ /**
+ * Test will timeout if secure random implementation always returns a
+ * constant value.
+ */
+ private void checkRandomBytes(OpensslSecureRandom random, int len) {
+ byte[] bytes = new byte[len];
+ byte[] bytes1 = new byte[len];
+ random.nextBytes(bytes);
+ random.nextBytes(bytes1);
+
+ while (Arrays.equals(bytes, bytes1)) {
+ random.nextBytes(bytes1);
+ }
+ }
+
+ /**
+ * Test will timeout if secure random implementation always returns a
+ * constant value.
+ */
+ @Test(timeout=120000)
+ public void testRandomInt() throws Exception {
+ OpensslSecureRandom random = new OpensslSecureRandom();
+
+ int rand1 = random.nextInt();
+ int rand2 = random.nextInt();
+ while (rand1 == rand2) {
+ rand2 = random.nextInt();
+ }
+ }
+
+ /**
+ * Test will timeout if secure random implementation always returns a
+ * constant value.
+ */
+ @Test(timeout=120000)
+ public void testRandomLong() throws Exception {
+ OpensslSecureRandom random = new OpensslSecureRandom();
+
+ long rand1 = random.nextLong();
+ long rand2 = random.nextLong();
+ while (rand1 == rand2) {
+ rand2 = random.nextLong();
+ }
+ }
+
+ /**
+ * Test will timeout if secure random implementation always returns a
+ * constant value.
+ */
+ @Test(timeout=120000)
+ public void testRandomFloat() throws Exception {
+ OpensslSecureRandom random = new OpensslSecureRandom();
+
+ float rand1 = random.nextFloat();
+ float rand2 = random.nextFloat();
+ while (rand1 == rand2) {
+ rand2 = random.nextFloat();
+ }
+ }
+
+ /**
+ * Test will timeout if secure random implementation always returns a
+ * constant value.
+ */
+ @Test(timeout=120000)
+ public void testRandomDouble() throws Exception {
+ OpensslSecureRandom random = new OpensslSecureRandom();
+
+ double rand1 = random.nextDouble();
+ double rand2 = random.nextDouble();
+ while (rand1 == rand2) {
+ rand2 = random.nextDouble();
+ }
+ }
+}
\ No newline at end of file
Added: hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/random/TestOsSecureRandom.java
URL: http://svn.apache.org/viewvc/hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/random/TestOsSecureRandom.java?rev=1609874&view=auto
==============================================================================
--- hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/random/TestOsSecureRandom.java (added)
+++ hadoop/common/branches/fs-encryption/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/crypto/random/TestOsSecureRandom.java Sat Jul 12 01:29:26 2014
@@ -0,0 +1,139 @@
+/**
+ * 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.hadoop.crypto.random;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+import org.apache.commons.lang.SystemUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.junit.Assume;
+import org.junit.Test;
+
+public class TestOsSecureRandom {
+
+ private static OsSecureRandom getOsSecureRandom() throws IOException {
+ Assume.assumeTrue(SystemUtils.IS_OS_LINUX);
+ OsSecureRandom random = new OsSecureRandom();
+ random.setConf(new Configuration());
+ return random;
+ }
+
+ @Test(timeout=120000)
+ public void testRandomBytes() throws Exception {
+ OsSecureRandom random = getOsSecureRandom();
+ // len = 16
+ checkRandomBytes(random, 16);
+ // len = 32
+ checkRandomBytes(random, 32);
+ // len = 128
+ checkRandomBytes(random, 128);
+ // len = 256
+ checkRandomBytes(random, 256);
+ random.close();
+ }
+
+ /**
+ * Test will timeout if secure random implementation always returns a
+ * constant value.
+ */
+ private void checkRandomBytes(OsSecureRandom random, int len) {
+ byte[] bytes = new byte[len];
+ byte[] bytes1 = new byte[len];
+ random.nextBytes(bytes);
+ random.nextBytes(bytes1);
+
+ while (Arrays.equals(bytes, bytes1)) {
+ random.nextBytes(bytes1);
+ }
+ }
+
+ /**
+ * Test will timeout if secure random implementation always returns a
+ * constant value.
+ */
+ @Test(timeout=120000)
+ public void testRandomInt() throws Exception {
+ OsSecureRandom random = getOsSecureRandom();
+
+ int rand1 = random.nextInt();
+ int rand2 = random.nextInt();
+ while (rand1 == rand2) {
+ rand2 = random.nextInt();
+ }
+ random.close();
+ }
+
+ /**
+ * Test will timeout if secure random implementation always returns a
+ * constant value.
+ */
+ @Test(timeout=120000)
+ public void testRandomLong() throws Exception {
+ OsSecureRandom random = getOsSecureRandom();
+
+ long rand1 = random.nextLong();
+ long rand2 = random.nextLong();
+ while (rand1 == rand2) {
+ rand2 = random.nextLong();
+ }
+ random.close();
+ }
+
+ /**
+ * Test will timeout if secure random implementation always returns a
+ * constant value.
+ */
+ @Test(timeout=120000)
+ public void testRandomFloat() throws Exception {
+ OsSecureRandom random = getOsSecureRandom();
+
+ float rand1 = random.nextFloat();
+ float rand2 = random.nextFloat();
+ while (rand1 == rand2) {
+ rand2 = random.nextFloat();
+ }
+ random.close();
+ }
+
+ /**
+ * Test will timeout if secure random implementation always returns a
+ * constant value.
+ */
+ @Test(timeout=120000)
+ public void testRandomDouble() throws Exception {
+ OsSecureRandom random = getOsSecureRandom();
+
+ double rand1 = random.nextDouble();
+ double rand2 = random.nextDouble();
+ while (rand1 == rand2) {
+ rand2 = random.nextDouble();
+ }
+ random.close();
+ }
+
+ @Test(timeout=120000)
+ public void testRefillReservoir() throws Exception {
+ OsSecureRandom random = getOsSecureRandom();
+
+ for (int i = 0; i < 8196; i++) {
+ random.nextLong();
+ }
+ random.close();
+ }
+}