Merge "Always mix in additional entropy into keymaster." into mnc-dev
diff --git a/keystore/java/android/security/KeyStoreCipherSpi.java b/keystore/java/android/security/KeyStoreCipherSpi.java
index 28bc3d2..afa0c8e 100644
--- a/keystore/java/android/security/KeyStoreCipherSpi.java
+++ b/keystore/java/android/security/KeyStoreCipherSpi.java
@@ -634,10 +634,9 @@
if ((mIv == null) && (mEncrypting)) {
// IV was not provided by the caller and thus will be generated by keymaster.
// Mix in some additional entropy from the provided SecureRandom.
- if (mRng != null) {
- mAdditionalEntropyForBegin = new byte[mBlockSizeBytes];
- mRng.nextBytes(mAdditionalEntropyForBegin);
- }
+ mAdditionalEntropyForBegin =
+ KeyStoreCryptoOperationUtils.getRandomBytesToMixIntoKeystoreRng(
+ mRng, mBlockSizeBytes);
}
}
}
diff --git a/keystore/java/android/security/KeyStoreCryptoOperationUtils.java b/keystore/java/android/security/KeyStoreCryptoOperationUtils.java
index e5933ad..311278b 100644
--- a/keystore/java/android/security/KeyStoreCryptoOperationUtils.java
+++ b/keystore/java/android/security/KeyStoreCryptoOperationUtils.java
@@ -21,6 +21,7 @@
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
+import java.security.SecureRandom;
/**
* Assorted utility methods for implementing crypto operations on top of KeyStore.
@@ -28,6 +29,9 @@
* @hide
*/
abstract class KeyStoreCryptoOperationUtils {
+
+ private static volatile SecureRandom sRng;
+
private KeyStoreCryptoOperationUtils() {}
/**
@@ -81,4 +85,28 @@
// General cases
return getInvalidKeyExceptionForInit(keyStore, key, beginOpResultCode);
}
+
+ /**
+ * Returns the requested number of random bytes to mix into keystore/keymaster RNG.
+ *
+ * @param rng RNG from which to obtain the random bytes or {@code null} for the platform-default
+ * RNG.
+ */
+ static byte[] getRandomBytesToMixIntoKeystoreRng(SecureRandom rng, int sizeBytes) {
+ if (rng == null) {
+ rng = getRng();
+ }
+ byte[] result = new byte[sizeBytes];
+ rng.nextBytes(result);
+ return result;
+ }
+
+ private static SecureRandom getRng() {
+ // IMPLEMENTATION NOTE: It's OK to share a SecureRandom instance because SecureRandom is
+ // required to be thread-safe.
+ if (sRng == null) {
+ sRng = new SecureRandom();
+ }
+ return sRng;
+ }
}
diff --git a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
index e69648c..c265c46 100644
--- a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
+++ b/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
@@ -173,12 +173,9 @@
args.addBoolean(KeymasterDefs.KM_TAG_CALLER_NONCE);
}
- byte[] additionalEntropy = null;
- SecureRandom rng = mRng;
- if (rng != null) {
- additionalEntropy = new byte[(keySizeBits + 7) / 8];
- rng.nextBytes(additionalEntropy);
- }
+ byte[] additionalEntropy =
+ KeyStoreCryptoOperationUtils.getRandomBytesToMixIntoKeystoreRng(
+ mRng, (keySizeBits + 7) / 8);
int flags = spec.getFlags();
String keyAliasInKeystore = Credentials.USER_SECRET_KEY + spec.getKeystoreAlias();