8156213: Remove SHA-1 and 3KeyTDEA algorithms from DRBG

Reviewed-by: wetmore, xuelei
This commit is contained in:
Weijun Wang 2016-05-12 13:06:03 +08:00
parent 1a854bcc1e
commit 07f2c9d05f
7 changed files with 31 additions and 91 deletions

View File

@ -196,10 +196,9 @@ import java.util.Objects;
* of the JDK reference implementation.
* <p>
* This implementation supports the Hash_DRBG and HMAC_DRBG mechanisms with
* DRBG algorithm SHA-1, SHA-224, SHA-512/224, SHA-256, SHA-512/256,
* SHA-384 and SHA-512, and CTR_DRBG (both using derivation function and
* not using derivation function) with DRBG algorithm 3KeyTDEA
* (also known as DESede in JCE), AES-128, AES-192 and AES-256.
* DRBG algorithm SHA-224, SHA-512/224, SHA-256, SHA-512/256, SHA-384 and
* SHA-512, and CTR_DRBG (both using derivation function and not using
* derivation function) with DRBG algorithm AES-128, AES-192 and AES-256.
* <p>
* The mechanism name and DRBG algorithm name are determined by the
* {@linkplain Security#getProperty(String) security property}

View File

@ -267,10 +267,9 @@ public abstract class AbstractDrbg extends SecureRandomSpi {
* {@code DEFAULT_STRENGTH} is 128) for HashDRBG:
* <pre>
* requested effective
* (SHA-1, -1) (SHA-1,128)
* (SHA-1, 112) (SHA-1,112)
* (SHA-1, 192) IAE
* (SHA-224, 256) IAE
* (SHA-256, -1) (SHA-256,128)
* (SHA-256, 112) (SHA-256,112)
* (SHA-256, 128) (SHA-256,128)
* (SHA-3, -1) IAE
* (null, -1) (SHA-256,128)

View File

@ -39,8 +39,6 @@ public abstract class AbstractHashDrbg extends AbstractDrbg {
private static int alg2strength(String algorithm) {
switch (algorithm.toUpperCase(Locale.ROOT)) {
case "SHA-1":
return 128;
case "SHA-224":
case "SHA-512/224":
return 192;
@ -82,10 +80,6 @@ public abstract class AbstractHashDrbg extends AbstractDrbg {
this.securityStrength = tryStrength;
}
switch (algorithm.toUpperCase(Locale.ROOT)) {
case "SHA-1":
this.seedLen = 440 / 8;
this.outLen = 160 / 8;
break;
case "SHA-224":
case "SHA-512/224":
this.seedLen = 440 / 8;

View File

@ -27,7 +27,6 @@ package sun.security.provider;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.security.*;
@ -68,11 +67,6 @@ public class CtrDrbg extends AbstractDrbg {
private static int alg2strength(String algorithm) {
switch (algorithm.toUpperCase(Locale.ROOT)) {
case "TDEA":
case "3KEYTDEA":
case "3 KEY TDEA":
case "DESEDE":
return 112;
case "AES-128":
return 128;
case "AES-192":
@ -120,16 +114,6 @@ public class CtrDrbg extends AbstractDrbg {
this.securityStrength = tryStrength;
}
switch (algorithm.toUpperCase(Locale.ROOT)) {
case "TDEA":
case "3KEYTDEA":
case "3 KEY TDEA":
case "DESEDE":
algorithm = "DESede";
this.keyAlg = "DESede";
this.cipherAlg = "DESede/ECB/NoPadding";
this.blockLen = 64 / 8;
this.keyLen = 168 / 8;
break;
case "AES-128":
case "AES-192":
case "AES-256":
@ -224,7 +208,7 @@ public class CtrDrbg extends AbstractDrbg {
// Step 2.1. Increment
addOne(v, ctrLen);
// Step 2.2. Block_Encrypt
cipher.init(Cipher.ENCRYPT_MODE, getKey(keyAlg, k));
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(k, keyAlg));
// Step 2.3. Encrypt into right position, no need to cat
cipher.doFinal(v, 0, blockLen, temp, i * blockLen);
}
@ -316,7 +300,7 @@ public class CtrDrbg extends AbstractDrbg {
for (int i = 0; i * blockLen < seedLen; i++) {
try {
cipher.init(Cipher.ENCRYPT_MODE, getKey(keyAlg, k));
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(k, keyAlg));
int tailLen = temp.length - blockLen*i;
if (tailLen > blockLen) {
tailLen = blockLen;
@ -340,7 +324,7 @@ public class CtrDrbg extends AbstractDrbg {
inputBlock[j] ^= chain[j];
}
try {
cipher.init(Cipher.ENCRYPT_MODE, getKey(keyAlg, k));
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(k, keyAlg));
chain = cipher.doFinal(inputBlock);
} catch (GeneralSecurityException e) {
throw new InternalError(e);
@ -456,7 +440,7 @@ public class CtrDrbg extends AbstractDrbg {
addOne(v, ctrLen);
try {
// Step 4.2. Encrypt
cipher.init(Cipher.ENCRYPT_MODE, getKey(keyAlg, k));
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(k, keyAlg));
byte[] out = cipher.doFinal(v);
// Step 4.3 and 5. Cat bytes and leftmost
@ -479,43 +463,6 @@ public class CtrDrbg extends AbstractDrbg {
// Step 8. Return
}
private static void des7to8(
byte[] key56, int off56, byte[] key64, int off64) {
key64[off64 + 0] = (byte)
(key56[off56 + 0] & 0xFE); // << 0
key64[off64 + 1] = (byte)
((key56[off56 + 0] << 7) | ((key56[off56 + 1] & 0xFF) >>> 1));
key64[off64 + 2] = (byte)
((key56[off56 + 1] << 6) | ((key56[off56 + 2] & 0xFF) >>> 2));
key64[off64 + 3] = (byte)
((key56[off56 + 2] << 5) | ((key56[off56 + 3] & 0xFF) >>> 3));
key64[off64 + 4] = (byte)
((key56[off56 + 3] << 4) | ((key56[off56 + 4] & 0xFF) >>> 4));
key64[off64 + 5] = (byte)
((key56[off56 + 4] << 3) | ((key56[off56 + 5] & 0xFF) >>> 5));
key64[off64 + 6] = (byte)
((key56[off56 + 5] << 2) | ((key56[off56 + 6] & 0xFF) >>> 6));
key64[off64 + 7] = (byte)
(key56[off56 + 6] << 1);
for (int i = 0; i < 8; i++) {
// if even # bits, make uneven, XOR with 1 (uneven & 1)
// for uneven # bits, make even, XOR with 0 (even & 1)
key64[off64 + i] ^= Integer.bitCount(key64[off64 + i] ^ 1) & 1;
}
}
private static SecretKey getKey(String keyAlg, byte[] k) {
if (keyAlg.equals("DESede")) {
byte[] k2 = new byte[24];
des7to8(k, 0, k2, 0);
des7to8(k, 7, k2, 8);
des7to8(k, 14, k2, 16);
k = k2;
}
return new SecretKeySpec(k, keyAlg);
}
private void readObject(java.io.ObjectInputStream s)
throws IOException, ClassNotFoundException {
s.defaultReadObject ();

View File

@ -206,16 +206,15 @@ securerandom.strongAlgorithms=NativePRNGBlocking:SUN,DRBG:SUN
# "Hash_DRBG" | "HMAC_DRBG" | "CTR_DRBG"
#
# // The DRBG algorithm name. The "SHA-***" names are for Hash_DRBG and
# // HMAC_DRBG, default "SHA-256". "3KeyTDEA" and "AES-***" names are for
# // CTR_DRBG, default "AES-128" when using the limited cryptographic
# // or "AES-256" when using the unlimited.
# // HMAC_DRBG, default "SHA-256". The "AES-***" names are for CTR_DRBG,
# // default "AES-128" when using the limited cryptographic or "AES-256"
# // when using the unlimited.
# algorithm_name:
# "SHA-1" | "SHA-224" | "SHA-512/224" | "SHA-256" |
# "SHA-224" | "SHA-512/224" | "SHA-256" |
# "SHA-512/256" | "SHA-384" | "SHA-512" |
# "3KeyTDEA" | "AES-128" | "AES-192" | "AES-256"
# "AES-128" | "AES-192" | "AES-256"
#
# // Security strength requested. Default "128", or "112"
# // if mech_name is CTR_DRBG and algorithm_name is "3KeyTDEA"
# // Security strength requested. Default "128"
# strength:
# "112" | "128" | "192" | "256"
#
@ -234,7 +233,7 @@ securerandom.strongAlgorithms=NativePRNGBlocking:SUN,DRBG:SUN
# "use_df" | "no_df"
#
# Examples,
# securerandom.drbg.config=Hash_DRBG,SHA-1,112,none
# securerandom.drbg.config=Hash_DRBG,SHA-224,112,none
# securerandom.drbg.config=CTR_DRBG,AES-256,192,pr_and_reseed,use_df
#
# The default value is an empty string, which is equivalent to

View File

@ -47,7 +47,6 @@ public class DRBGAlg {
check(null, "Hash_DRBG", "SHA-256", "reseed_only", ",128");
check("", "Hash_DRBG", "SHA-256", "reseed_only", ",128");
check("sha-1", "Hash_DRBG", "SHA-1", "reseed_only", ",128");
check("sha-256", "Hash_DRBG", "SHA-256", "reseed_only", ",128");
check("SHA-3");
check("hash_drbg", "Hash_DRBG", "SHA-256", "reseed_only", ",128");
@ -61,20 +60,20 @@ public class DRBGAlg {
"Hash_DRBG", "SHA-512", "pr_and_reseed", ",192");
check("Hash_DRBG,Hmac_DRBG");
check("SHA-1,SHA-256");
check("SHA-224,SHA-256");
check("128,256");
check("none,reseed_only");
check("use_df,no_df");
check("Hash_DRBG,,SHA-1");
check("Hash_DRBG,,SHA-256");
check(null, DrbgParameters.instantiation(112, PR_AND_RESEED, null),
"Hash_DRBG", "SHA-256", "pr_and_reseed", ",112");
check(null, DrbgParameters.instantiation(256, PR_AND_RESEED, null),
"Hash_DRBG", "SHA-256", "pr_and_reseed", ",256");
check(null, DrbgParameters.instantiation(384, PR_AND_RESEED, null));
check("sha-1", DrbgParameters.instantiation(112, PR_AND_RESEED, null),
"Hash_DRBG", "SHA-1", "pr_and_reseed", ",112");
check("sha-1", DrbgParameters.instantiation(192, PR_AND_RESEED, null));
check("sha-224", DrbgParameters.instantiation(112, PR_AND_RESEED, null),
"Hash_DRBG", "SHA-224", "pr_and_reseed", ",112");
check("sha-224", DrbgParameters.instantiation(256, PR_AND_RESEED, null));
check("hash_drbg,sha-512,Pr_and_Reseed,192",
DrbgParameters.instantiation(112, NONE, null),
"Hash_DRBG", "SHA-512", "reseed_only", ",112");
@ -86,23 +85,23 @@ public class DRBGAlg {
DrbgParameters.instantiation(192, PR_AND_RESEED, null),
"Hash_DRBG", "SHA-256", "pr_and_reseed", ",192");
check("hash_drbg,sha-1", new MoreDrbgParameters(
check("hash_drbg,sha-224", new MoreDrbgParameters(
null, null, "sha-512", null, false,
DrbgParameters.instantiation(-1, NONE, null)),
"Hash_DRBG", "SHA-512");
check("hash_drbg,sha-1", new MoreDrbgParameters(
check("hash_drbg,sha-224", new MoreDrbgParameters(
null, null, null, null, false,
DrbgParameters.instantiation(-1, NONE, null)),
"Hash_DRBG", "SHA-1");
"Hash_DRBG", "SHA-224");
check("hash_drbg", new MoreDrbgParameters(
null, "hmac_drbg", null, null, false,
DrbgParameters.instantiation(-1, NONE, null)),
"HMAC_DRBG", "SHA-256");
check("hash_drbg,sha-1", new MoreDrbgParameters(
check("hash_drbg,sha-224", new MoreDrbgParameters(
null, null, "sha-3", null, false,
DrbgParameters.instantiation(-1, NONE, null)));
check("hash_drbg,sha-1", new MoreDrbgParameters(
check("hash_drbg,sha-224", new MoreDrbgParameters(
null, "Unknown_DRBG", null, null, false,
DrbgParameters.instantiation(-1, NONE, null)));
}

View File

@ -278,10 +278,13 @@ public class DrbgCavp {
ps)),
"SUN");
} catch (NoSuchAlgorithmException iae) {
// We don't support SHA-1 and 3KeyTDEA. AES-192 or
// AES-256 might not be available. This is OK.
if ((algorithm.equals("AES-192")
if (algorithm.equals("SHA-1") ||
algorithm.equals("3KeyTDEA") ||
((algorithm.equals("AES-192")
|| algorithm.equals("AES-256"))
&& AES_LIMIT == 128) {
&& AES_LIMIT == 128)) {
hd = null;
} else {
throw iae;