diff options
author | David Hook <dgh@cryptoworkshop.com> | 2013-05-11 03:48:37 +0400 |
---|---|---|
committer | David Hook <dgh@cryptoworkshop.com> | 2013-05-11 03:48:37 +0400 |
commit | f733f717fb13387a61dedc0a57d23487069d9b67 (patch) | |
tree | 6f32fad65a2fb78fb2aab2986a38553bce706e44 | |
parent | 299db0910a5a58f737d6feaa3386229a6135791d (diff) |
refactoring.
16 files changed, 347 insertions, 344 deletions
diff --git a/src/main/java/org/bouncycastle/crypto/prng/DRBGProvider.java b/src/main/java/org/bouncycastle/crypto/prng/DRBGProvider.java new file mode 100644 index 00000000..c39760c9 --- /dev/null +++ b/src/main/java/org/bouncycastle/crypto/prng/DRBGProvider.java @@ -0,0 +1,8 @@ +package org.bouncycastle.crypto.prng; + +import org.bouncycastle.crypto.prng.drbg.SP80090DRBG; + +interface DRBGProvider +{ + SP80090DRBG get(EntropySource entropySource); +} diff --git a/src/main/java/org/bouncycastle/crypto/random/SP800SecureRandom.java b/src/main/java/org/bouncycastle/crypto/prng/SP800SecureRandom.java index 0b54ac54..e1ec6c28 100644 --- a/src/main/java/org/bouncycastle/crypto/random/SP800SecureRandom.java +++ b/src/main/java/org/bouncycastle/crypto/prng/SP800SecureRandom.java @@ -1,9 +1,8 @@ -package org.bouncycastle.crypto.random; +package org.bouncycastle.crypto.prng; import java.security.SecureRandom; -import org.bouncycastle.crypto.prng.EntropySource; -import org.bouncycastle.crypto.prng.SP80090DRBG; +import org.bouncycastle.crypto.prng.drbg.SP80090DRBG; public class SP800SecureRandom extends SecureRandom @@ -55,7 +54,12 @@ public class SP800SecureRandom drbg = drbgProvider.get(entropySource); } - drbg.generate(bytes, null, predictionResistant); + // check if a reseed is required... + if (drbg.generate(bytes, null, predictionResistant) < 0) + { + drbg.reseed(entropySource.getEntropy()); + drbg.generate(bytes, null, predictionResistant); + } } } diff --git a/src/main/java/org/bouncycastle/crypto/random/SP800SecureRandomBuilder.java b/src/main/java/org/bouncycastle/crypto/prng/SP800SecureRandomBuilder.java index 10bd3505..c5c5827a 100644 --- a/src/main/java/org/bouncycastle/crypto/random/SP800SecureRandomBuilder.java +++ b/src/main/java/org/bouncycastle/crypto/prng/SP800SecureRandomBuilder.java @@ -1,18 +1,15 @@ -package org.bouncycastle.crypto.random; +package org.bouncycastle.crypto.prng; import java.security.SecureRandom; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Mac; -import org.bouncycastle.crypto.prng.BasicEntropySourceProvider; -import org.bouncycastle.crypto.prng.CTRSP800DRBG; -import org.bouncycastle.crypto.prng.DualECSP800DRBG; -import org.bouncycastle.crypto.prng.EntropySource; -import org.bouncycastle.crypto.prng.EntropySourceProvider; -import org.bouncycastle.crypto.prng.HMacSP800DRBG; -import org.bouncycastle.crypto.prng.HashSP800DRBG; -import org.bouncycastle.crypto.prng.SP80090DRBG; +import org.bouncycastle.crypto.prng.drbg.CTRSP800DRBG; +import org.bouncycastle.crypto.prng.drbg.DualECSP800DRBG; +import org.bouncycastle.crypto.prng.drbg.HMacSP800DRBG; +import org.bouncycastle.crypto.prng.drbg.HashSP800DRBG; +import org.bouncycastle.crypto.prng.drbg.SP80090DRBG; /** * Builder class for making SecureRandom objects based on SP 800-90A Deterministic Random Bit Generators (DRBG). diff --git a/src/main/java/org/bouncycastle/crypto/prng/VMPCRandomGenerator.java b/src/main/java/org/bouncycastle/crypto/prng/VMPCRandomGenerator.java index 9f9ff7b2..b882b796 100644 --- a/src/main/java/org/bouncycastle/crypto/prng/VMPCRandomGenerator.java +++ b/src/main/java/org/bouncycastle/crypto/prng/VMPCRandomGenerator.java @@ -124,5 +124,4 @@ public class VMPCRandomGenerator implements RandomGenerator }
}
}
-
}
diff --git a/src/main/java/org/bouncycastle/crypto/prng/CTRSP800DRBG.java b/src/main/java/org/bouncycastle/crypto/prng/drbg/CTRSP800DRBG.java index c3b33abb..50f70467 100644 --- a/src/main/java/org/bouncycastle/crypto/prng/CTRSP800DRBG.java +++ b/src/main/java/org/bouncycastle/crypto/prng/drbg/CTRSP800DRBG.java @@ -1,14 +1,15 @@ -package org.bouncycastle.crypto.prng; +package org.bouncycastle.crypto.prng.drbg; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.params.KeyParameter; +import org.bouncycastle.crypto.prng.EntropySource; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; public class CTRSP800DRBG implements SP80090DRBG { - private EntropySource _entropySource; + private EntropySource _entropySource; private BlockCipher _engine; private int _keySizeInBits; private int _seedLength; diff --git a/src/main/java/org/bouncycastle/crypto/prng/DualECSP800DRBG.java b/src/main/java/org/bouncycastle/crypto/prng/drbg/DualECSP800DRBG.java index caeac7a0..518ae04e 100644 --- a/src/main/java/org/bouncycastle/crypto/prng/DualECSP800DRBG.java +++ b/src/main/java/org/bouncycastle/crypto/prng/drbg/DualECSP800DRBG.java @@ -1,9 +1,10 @@ -package org.bouncycastle.crypto.prng; +package org.bouncycastle.crypto.prng.drbg; import java.math.BigInteger; import org.bouncycastle.asn1.nist.NISTNamedCurves; import org.bouncycastle.crypto.Digest; +import org.bouncycastle.crypto.prng.EntropySource; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECFieldElement; import org.bouncycastle.math.ec.ECPoint; @@ -35,7 +36,7 @@ public class DualECSP800DRBG private Digest _digest; private int _reseedCounter; - private EntropySource _entropySource; + private EntropySource _entropySource; private int _securityStrength; private int _seedlen; private int _outlen; diff --git a/src/main/java/org/bouncycastle/crypto/prng/HMacSP800DRBG.java b/src/main/java/org/bouncycastle/crypto/prng/drbg/HMacSP800DRBG.java index dd22f4c6..de448f7b 100644 --- a/src/main/java/org/bouncycastle/crypto/prng/HMacSP800DRBG.java +++ b/src/main/java/org/bouncycastle/crypto/prng/drbg/HMacSP800DRBG.java @@ -1,7 +1,8 @@ -package org.bouncycastle.crypto.prng; +package org.bouncycastle.crypto.prng.drbg; import org.bouncycastle.crypto.Mac; import org.bouncycastle.crypto.params.KeyParameter; +import org.bouncycastle.crypto.prng.EntropySource; import org.bouncycastle.util.Arrays; public class HMacSP800DRBG diff --git a/src/main/java/org/bouncycastle/crypto/prng/HashSP800DRBG.java b/src/main/java/org/bouncycastle/crypto/prng/drbg/HashSP800DRBG.java index c52dd917..489054b0 100644 --- a/src/main/java/org/bouncycastle/crypto/prng/HashSP800DRBG.java +++ b/src/main/java/org/bouncycastle/crypto/prng/drbg/HashSP800DRBG.java @@ -1,305 +1,306 @@ -package org.bouncycastle.crypto.prng;
-
-import java.util.Hashtable;
-
-import org.bouncycastle.crypto.Digest;
-import org.bouncycastle.util.Arrays;
-import org.bouncycastle.util.Integers;
-
-public class HashSP800DRBG implements SP80090DRBG
-{
- private final static byte[] ONE = { 0x01 };
- private final static int RESEED_MAX = 100000;
- private final static Hashtable seedlens = new Hashtable();
-
- static
- {
- seedlens.put("SHA-1", Integers.valueOf(440));
- seedlens.put("SHA-224", Integers.valueOf(440));
- seedlens.put("SHA-256", Integers.valueOf(440));
- seedlens.put("SHA-512/256", Integers.valueOf(440));
- seedlens.put("SHA-512/224", Integers.valueOf(440));
- seedlens.put("SHA-384", Integers.valueOf(888));
- seedlens.put("SHA-512", Integers.valueOf(888));
- }
-
- private Digest _digest;
- private byte[] _V;
- private byte[] _C;
- private int _reseedCounter;
- private EntropySource _entropySource;
- private int _securityStrength;
- private int _seedLength;
-
- public HashSP800DRBG(Digest digest, EntropySource entropySource, byte[] nonce,
- byte[] personalisationString, int securityStrength)
- {
- if (securityStrength > digest.getDigestSize() * 8) // TODO: this may, or may not be correct, but it's good enough for now
- {
- throw new IllegalStateException(
- "Security strength is not supported by the derivation function");
- }
-
- _digest = digest;
- _entropySource = entropySource;
- _securityStrength = securityStrength;
- _seedLength = ((Integer)seedlens.get(digest.getAlgorithmName())).intValue();
-
- // 1. seed_material = entropy_input || nonce || personalization_string.
- // 2. seed = Hash_df (seed_material, seedlen).
- // 3. V = seed.
- // 4. C = Hash_df ((0x00 || V), seedlen). Comment: Preceed V with a byte
- // of zeros.
- // 5. reseed_counter = 1.
- // 6. Return V, C, and reseed_counter as the initial_working_state
-
- byte[] entropy = entropySource.getEntropy();
- byte[] seedMaterial = Arrays.concatenate(entropy, nonce, personalisationString);
- byte[] seed = hash_df(seedMaterial, _seedLength);
-
- _V = seed;
- byte[] subV = new byte[_V.length + 1];
- System.arraycopy(_V, 0, subV, 1, _V.length);
- _C = hash_df(subV, _seedLength);
- _reseedCounter = 1;
-
-// System.out.println("Constructor V: "+ new String(Hex.encode(_V)));
-// System.out.println("Constructor C: "+ new String(Hex.encode(_C)));
-
- }
-
- // 1. If reseed_counter > reseed_interval, then return an indication that a
- // reseed is required.
- // 2. If (additional_input != Null), then do
- // 2.1 w = Hash (0x02 || V || additional_input).
- // 2.2 V = (V + w) mod 2^seedlen
- // .
- // 3. (returned_bits) = Hashgen (requested_number_of_bits, V).
- // 4. H = Hash (0x03 || V).
- // 5. V = (V + H + C + reseed_counter) mod 2^seedlen
- // .
- // 6. reseed_counter = reseed_counter + 1.
- // 7. Return SUCCESS, returned_bits, and the new values of V, C, and
- // reseed_counter for the new_working_state.
- public int generate(byte[] output, byte[] additionalInput, boolean predictionResistant)
- {
- int numberOfBits = output.length*8;
-
- if (predictionResistant || _reseedCounter > RESEED_MAX)
- {
- reseed(additionalInput);
- additionalInput = null;
- }
-
- // 2.
- if (additionalInput != null)
- {
- byte[] newInput = new byte[1 + _V.length + additionalInput.length];
- newInput[0] = 0x02;
- System.arraycopy(_V, 0, newInput, 1, _V.length);
- // TODO: inOff / inLength
- System.arraycopy(additionalInput, 0, newInput, 1 + _V.length, additionalInput.length);
- byte[] w = hash(newInput);
-
- addTo(_V, w);
- }
-
- // 3.
- byte[] rv = hashgen(_V, numberOfBits);
-
- // 4.
- byte[] subH = new byte[_V.length + 1];
- System.arraycopy(_V, 0, subH, 1, _V.length);
- subH[0] = 0x03;
-
- byte[] H = hash(subH);
-
- // 5.
- addTo(_V, H);
- addTo(_V, _C);
- byte[] c = new byte[4];
- c[0] = (byte)(_reseedCounter >> 24);
- c[1] = (byte)(_reseedCounter >> 16);
- c[2] = (byte)(_reseedCounter >> 8);
- c[3] = (byte)_reseedCounter;
-
- addTo(_V, c);
- _reseedCounter++;
-
- System.arraycopy(rv, 0, output, 0, output.length);
-// System.out.println("Generate V: "+ new String(Hex.encode(_V)));
-// System.out.println("Generate C: "+ new String(Hex.encode(_C)));
-
- return numberOfBits;
- }
-
- // this will always add the shorter length byte array mathematically to the
- // longer length byte array.
- // be careful....
- private void addTo(byte[] longer, byte[] shorter)
- {
- int carry = 0;
- for (int i=1;i <= shorter.length; i++) // warning
- {
- int res = (longer[longer.length-i] & 0xff) + (shorter[shorter.length-i] & 0xff) + carry;
- carry = (res > 0xff) ? 1 : 0;
- longer[longer.length-i] = (byte)res;
- }
-
- for (int i=shorter.length+1;i <= longer.length; i++) // warning
- {
- int res = (longer[longer.length-i] & 0xff) + carry;
- carry = (res > 0xff) ? 1 : 0;
- longer[longer.length-i] = (byte)res;
- }
- }
-
- // 1. seed_material = 0x01 || V || entropy_input || additional_input.
- //
- // 2. seed = Hash_df (seed_material, seedlen).
- //
- // 3. V = seed.
- //
- // 4. C = Hash_df ((0x00 || V), seedlen).
- //
- // 5. reseed_counter = 1.
- //
- // 6. Return V, C, and reseed_counter for the new_working_state.
- //
- // Comment: Precede with a byte of all zeros.
- public void reseed(byte[] additionalInput)
- {
- if (additionalInput == null)
- {
- additionalInput = new byte[0];
- }
-
- byte[] entropy = _entropySource.getEntropy();
-
-// System.out.println("Reseed Entropy: "+ new String(Hex.encode(entropy)));
-
- byte[] seedMaterial = Arrays.concatenate(ONE, _V, entropy, additionalInput);
-
-// System.out.println("Reseed SeedMaterial: "+ new String(Hex.encode(seedMaterial)));
-
- byte[] seed = hash_df(seedMaterial, _seedLength);
-
-// System.out.println("Reseed Seed: "+ new String(Hex.encode(seed)));
-
- _V = seed;
- byte[] subV = new byte[_V.length + 1];
- subV[0] = 0x00;
- System.arraycopy(_V, 0, subV, 1, _V.length);
- _C = hash_df(subV, _seedLength);
- _reseedCounter = 1;
-
-// System.out.println("Reseed V: "+ new String(Hex.encode(_V)));
-// System.out.println("Reseed C: "+ new String(Hex.encode(_C)));
- }
-
-
- // ---- Internal manipulation ---
- // ---- Migrating from the external HashDF class --
-
-
- // 1. temp = the Null string.
- // 2. .
- // 3. counter = an 8-bit binary value representing the integer "1".
- // 4. For i = 1 to len do
- // Comment : In step 4.1, no_of_bits_to_return
- // is used as a 32-bit string.
- // 4.1 temp = temp || Hash (counter || no_of_bits_to_return ||
- // input_string).
- // 4.2 counter = counter + 1.
- // 5. requested_bits = Leftmost (no_of_bits_to_return) of temp.
- // 6. Return SUCCESS and requested_bits.
- private byte[] hash_df(byte[] seedMaterial, int seedLength)
- {
- byte[] temp = new byte[seedLength / 8];
-
- int len = temp.length / _digest.getDigestSize();
- int counter = 1;
-
- byte[] dig = new byte[_digest.getDigestSize()];
-
- for (int i = 0; i <= len; i++)
- {
- _digest.update((byte)counter);
-
- _digest.update((byte)(seedLength >> 24));
- _digest.update((byte)(seedLength >> 16));
- _digest.update((byte)(seedLength >> 8));
- _digest.update((byte)seedLength);
-
- _digest.update(seedMaterial, 0, seedMaterial.length);
-
- _digest.doFinal(dig, 0);
-
- int bytesToCopy = ((temp.length - i * dig.length) > dig.length)
- ? dig.length
- : (temp.length - i * dig.length);
- System.arraycopy(dig, 0, temp, i * dig.length, bytesToCopy);
-
- counter++;
- }
-
- // do a left shift to get rid of excess bits.
- if (seedLength % 8 != 0)
- {
- int shift = 8 - (seedLength % 8);
- int carry = 0;
-
- for (int i = 0; i != temp.length; i++)
- {
- int b = temp[i] & 0xff;
- temp[i] = (byte)((b >>> shift) | (carry << (8 - shift)));
- carry = b;
- }
- }
-
- return temp;
- }
-
- private byte[] hash(byte[] input)
- {
- _digest.update(input, 0, input.length);
- byte[] hash = new byte[_digest.getDigestSize()];
- _digest.doFinal(hash, 0);
- return hash;
- }
-
- // 1. m = [requested_number_of_bits / outlen]
- // 2. data = V.
- // 3. W = the Null string.
- // 4. For i = 1 to m
- // 4.1 wi = Hash (data).
- // 4.2 W = W || wi.
- // 4.3 data = (data + 1) mod 2^seedlen
- // .
- // 5. returned_bits = Leftmost (requested_no_of_bits) bits of W.
- private byte[] hashgen(byte[] input, int lengthInBits)
- {
- int digestSize = _digest.getDigestSize();
- int m = (lengthInBits / 8) / digestSize;
-
- byte[] data = new byte[input.length];
- System.arraycopy(input, 0, data, 0, input.length);
-
- byte[] W = new byte[lengthInBits / 8];
-
- byte[] dig;
- for (int i = 0; i <= m; i++)
- {
- dig = hash(data);
-
- int bytesToCopy = ((W.length - i * dig.length) > dig.length)
- ? dig.length
- : (W.length - i * dig.length);
- System.arraycopy(dig, 0, W, i * dig.length, bytesToCopy);
-
- addTo(data, ONE);
- }
-
- return W;
- }
-}
+package org.bouncycastle.crypto.prng.drbg; + +import java.util.Hashtable; + +import org.bouncycastle.crypto.Digest; +import org.bouncycastle.crypto.prng.EntropySource; +import org.bouncycastle.util.Arrays; +import org.bouncycastle.util.Integers; + +public class HashSP800DRBG implements SP80090DRBG +{ + private final static byte[] ONE = { 0x01 }; + private final static int RESEED_MAX = 100000; + private final static Hashtable seedlens = new Hashtable(); + + static + { + seedlens.put("SHA-1", Integers.valueOf(440)); + seedlens.put("SHA-224", Integers.valueOf(440)); + seedlens.put("SHA-256", Integers.valueOf(440)); + seedlens.put("SHA-512/256", Integers.valueOf(440)); + seedlens.put("SHA-512/224", Integers.valueOf(440)); + seedlens.put("SHA-384", Integers.valueOf(888)); + seedlens.put("SHA-512", Integers.valueOf(888)); + } + + private Digest _digest; + private byte[] _V; + private byte[] _C; + private int _reseedCounter; + private EntropySource _entropySource; + private int _securityStrength; + private int _seedLength; + + public HashSP800DRBG(Digest digest, EntropySource entropySource, byte[] nonce, + byte[] personalisationString, int securityStrength) + { + if (securityStrength > digest.getDigestSize() * 8) // TODO: this may, or may not be correct, but it's good enough for now + { + throw new IllegalStateException( + "Security strength is not supported by the derivation function"); + } + + _digest = digest; + _entropySource = entropySource; + _securityStrength = securityStrength; + _seedLength = ((Integer)seedlens.get(digest.getAlgorithmName())).intValue(); + + // 1. seed_material = entropy_input || nonce || personalization_string. + // 2. seed = Hash_df (seed_material, seedlen). + // 3. V = seed. + // 4. C = Hash_df ((0x00 || V), seedlen). Comment: Preceed V with a byte + // of zeros. + // 5. reseed_counter = 1. + // 6. Return V, C, and reseed_counter as the initial_working_state + + byte[] entropy = entropySource.getEntropy(); + byte[] seedMaterial = Arrays.concatenate(entropy, nonce, personalisationString); + byte[] seed = hash_df(seedMaterial, _seedLength); + + _V = seed; + byte[] subV = new byte[_V.length + 1]; + System.arraycopy(_V, 0, subV, 1, _V.length); + _C = hash_df(subV, _seedLength); + _reseedCounter = 1; + +// System.out.println("Constructor V: "+ new String(Hex.encode(_V))); +// System.out.println("Constructor C: "+ new String(Hex.encode(_C))); + + } + + // 1. If reseed_counter > reseed_interval, then return an indication that a + // reseed is required. + // 2. If (additional_input != Null), then do + // 2.1 w = Hash (0x02 || V || additional_input). + // 2.2 V = (V + w) mod 2^seedlen + // . + // 3. (returned_bits) = Hashgen (requested_number_of_bits, V). + // 4. H = Hash (0x03 || V). + // 5. V = (V + H + C + reseed_counter) mod 2^seedlen + // . + // 6. reseed_counter = reseed_counter + 1. + // 7. Return SUCCESS, returned_bits, and the new values of V, C, and + // reseed_counter for the new_working_state. + public int generate(byte[] output, byte[] additionalInput, boolean predictionResistant) + { + int numberOfBits = output.length*8; + + if (predictionResistant || _reseedCounter > RESEED_MAX) + { + reseed(additionalInput); + additionalInput = null; + } + + // 2. + if (additionalInput != null) + { + byte[] newInput = new byte[1 + _V.length + additionalInput.length]; + newInput[0] = 0x02; + System.arraycopy(_V, 0, newInput, 1, _V.length); + // TODO: inOff / inLength + System.arraycopy(additionalInput, 0, newInput, 1 + _V.length, additionalInput.length); + byte[] w = hash(newInput); + + addTo(_V, w); + } + + // 3. + byte[] rv = hashgen(_V, numberOfBits); + + // 4. + byte[] subH = new byte[_V.length + 1]; + System.arraycopy(_V, 0, subH, 1, _V.length); + subH[0] = 0x03; + + byte[] H = hash(subH); + + // 5. + addTo(_V, H); + addTo(_V, _C); + byte[] c = new byte[4]; + c[0] = (byte)(_reseedCounter >> 24); + c[1] = (byte)(_reseedCounter >> 16); + c[2] = (byte)(_reseedCounter >> 8); + c[3] = (byte)_reseedCounter; + + addTo(_V, c); + _reseedCounter++; + + System.arraycopy(rv, 0, output, 0, output.length); +// System.out.println("Generate V: "+ new String(Hex.encode(_V))); +// System.out.println("Generate C: "+ new String(Hex.encode(_C))); + + return numberOfBits; + } + + // this will always add the shorter length byte array mathematically to the + // longer length byte array. + // be careful.... + private void addTo(byte[] longer, byte[] shorter) + { + int carry = 0; + for (int i=1;i <= shorter.length; i++) // warning + { + int res = (longer[longer.length-i] & 0xff) + (shorter[shorter.length-i] & 0xff) + carry; + carry = (res > 0xff) ? 1 : 0; + longer[longer.length-i] = (byte)res; + } + + for (int i=shorter.length+1;i <= longer.length; i++) // warning + { + int res = (longer[longer.length-i] & 0xff) + carry; + carry = (res > 0xff) ? 1 : 0; + longer[longer.length-i] = (byte)res; + } + } + + // 1. seed_material = 0x01 || V || entropy_input || additional_input. + // + // 2. seed = Hash_df (seed_material, seedlen). + // + // 3. V = seed. + // + // 4. C = Hash_df ((0x00 || V), seedlen). + // + // 5. reseed_counter = 1. + // + // 6. Return V, C, and reseed_counter for the new_working_state. + // + // Comment: Precede with a byte of all zeros. + public void reseed(byte[] additionalInput) + { + if (additionalInput == null) + { + additionalInput = new byte[0]; + } + + byte[] entropy = _entropySource.getEntropy(); + +// System.out.println("Reseed Entropy: "+ new String(Hex.encode(entropy))); + + byte[] seedMaterial = Arrays.concatenate(ONE, _V, entropy, additionalInput); + +// System.out.println("Reseed SeedMaterial: "+ new String(Hex.encode(seedMaterial))); + + byte[] seed = hash_df(seedMaterial, _seedLength); + +// System.out.println("Reseed Seed: "+ new String(Hex.encode(seed))); + + _V = seed; + byte[] subV = new byte[_V.length + 1]; + subV[0] = 0x00; + System.arraycopy(_V, 0, subV, 1, _V.length); + _C = hash_df(subV, _seedLength); + _reseedCounter = 1; + +// System.out.println("Reseed V: "+ new String(Hex.encode(_V))); +// System.out.println("Reseed C: "+ new String(Hex.encode(_C))); + } + + + // ---- Internal manipulation --- + // ---- Migrating from the external HashDF class -- + + + // 1. temp = the Null string. + // 2. . + // 3. counter = an 8-bit binary value representing the integer "1". + // 4. For i = 1 to len do + // Comment : In step 4.1, no_of_bits_to_return + // is used as a 32-bit string. + // 4.1 temp = temp || Hash (counter || no_of_bits_to_return || + // input_string). + // 4.2 counter = counter + 1. + // 5. requested_bits = Leftmost (no_of_bits_to_return) of temp. + // 6. Return SUCCESS and requested_bits. + private byte[] hash_df(byte[] seedMaterial, int seedLength) + { + byte[] temp = new byte[seedLength / 8]; + + int len = temp.length / _digest.getDigestSize(); + int counter = 1; + + byte[] dig = new byte[_digest.getDigestSize()]; + + for (int i = 0; i <= len; i++) + { + _digest.update((byte)counter); + + _digest.update((byte)(seedLength >> 24)); + _digest.update((byte)(seedLength >> 16)); + _digest.update((byte)(seedLength >> 8)); + _digest.update((byte)seedLength); + + _digest.update(seedMaterial, 0, seedMaterial.length); + + _digest.doFinal(dig, 0); + + int bytesToCopy = ((temp.length - i * dig.length) > dig.length) + ? dig.length + : (temp.length - i * dig.length); + System.arraycopy(dig, 0, temp, i * dig.length, bytesToCopy); + + counter++; + } + + // do a left shift to get rid of excess bits. + if (seedLength % 8 != 0) + { + int shift = 8 - (seedLength % 8); + int carry = 0; + + for (int i = 0; i != temp.length; i++) + { + int b = temp[i] & 0xff; + temp[i] = (byte)((b >>> shift) | (carry << (8 - shift))); + carry = b; + } + } + + return temp; + } + + private byte[] hash(byte[] input) + { + _digest.update(input, 0, input.length); + byte[] hash = new byte[_digest.getDigestSize()]; + _digest.doFinal(hash, 0); + return hash; + } + + // 1. m = [requested_number_of_bits / outlen] + // 2. data = V. + // 3. W = the Null string. + // 4. For i = 1 to m + // 4.1 wi = Hash (data). + // 4.2 W = W || wi. + // 4.3 data = (data + 1) mod 2^seedlen + // . + // 5. returned_bits = Leftmost (requested_no_of_bits) bits of W. + private byte[] hashgen(byte[] input, int lengthInBits) + { + int digestSize = _digest.getDigestSize(); + int m = (lengthInBits / 8) / digestSize; + + byte[] data = new byte[input.length]; + System.arraycopy(input, 0, data, 0, input.length); + + byte[] W = new byte[lengthInBits / 8]; + + byte[] dig; + for (int i = 0; i <= m; i++) + { + dig = hash(data); + + int bytesToCopy = ((W.length - i * dig.length) > dig.length) + ? dig.length + : (W.length - i * dig.length); + System.arraycopy(dig, 0, W, i * dig.length, bytesToCopy); + + addTo(data, ONE); + } + + return W; + } +} diff --git a/src/main/java/org/bouncycastle/crypto/prng/SP80090DRBG.java b/src/main/java/org/bouncycastle/crypto/prng/drbg/SP80090DRBG.java index 9fbd88f7..c93eb54c 100644 --- a/src/main/java/org/bouncycastle/crypto/prng/SP80090DRBG.java +++ b/src/main/java/org/bouncycastle/crypto/prng/drbg/SP80090DRBG.java @@ -1,4 +1,4 @@ -package org.bouncycastle.crypto.prng; +package org.bouncycastle.crypto.prng.drbg; public interface SP80090DRBG { diff --git a/src/main/java/org/bouncycastle/crypto/prng/package.html b/src/main/java/org/bouncycastle/crypto/prng/package.html index 99525fbf..bb583abd 100644 --- a/src/main/java/org/bouncycastle/crypto/prng/package.html +++ b/src/main/java/org/bouncycastle/crypto/prng/package.html @@ -1,5 +1,5 @@ <html> <body bgcolor="#ffffff"> -Lightweight psuedo-random number generators. +Lightweight psuedo-random number generators and SecureRandom builders. </body> </html> diff --git a/src/main/java/org/bouncycastle/crypto/random/DRBGProvider.java b/src/main/java/org/bouncycastle/crypto/random/DRBGProvider.java deleted file mode 100644 index f1ef83b2..00000000 --- a/src/main/java/org/bouncycastle/crypto/random/DRBGProvider.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.bouncycastle.crypto.random; - -import org.bouncycastle.crypto.prng.SP80090DRBG; -import org.bouncycastle.crypto.prng.EntropySource; - -interface DRBGProvider -{ - SP80090DRBG get(EntropySource entropySource); -} diff --git a/src/test/java/org/bouncycastle/crypto/random/test/SP800RandomTest.java b/src/test/java/org/bouncycastle/crypto/random/test/SP800RandomTest.java index c84b5744..5a7ad692 100644 --- a/src/test/java/org/bouncycastle/crypto/random/test/SP800RandomTest.java +++ b/src/test/java/org/bouncycastle/crypto/random/test/SP800RandomTest.java @@ -6,7 +6,7 @@ import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.engines.DESedeEngine; import org.bouncycastle.crypto.macs.HMac; -import org.bouncycastle.crypto.random.SP800SecureRandomBuilder; +import org.bouncycastle.crypto.prng.SP800SecureRandomBuilder; import org.bouncycastle.crypto.test.DRBGTestVector; import org.bouncycastle.crypto.test.TestEntropySourceProvider; import org.bouncycastle.util.Arrays; diff --git a/src/test/java/org/bouncycastle/crypto/test/CTRDRBGTest.java b/src/test/java/org/bouncycastle/crypto/test/CTRDRBGTest.java index 813bbed3..59d2177b 100644 --- a/src/test/java/org/bouncycastle/crypto/test/CTRDRBGTest.java +++ b/src/test/java/org/bouncycastle/crypto/test/CTRDRBGTest.java @@ -2,8 +2,8 @@ package org.bouncycastle.crypto.test; import org.bouncycastle.crypto.engines.AESFastEngine; import org.bouncycastle.crypto.engines.DESedeEngine; -import org.bouncycastle.crypto.prng.CTRSP800DRBG; -import org.bouncycastle.crypto.prng.SP80090DRBG; +import org.bouncycastle.crypto.prng.drbg.CTRSP800DRBG; +import org.bouncycastle.crypto.prng.drbg.SP80090DRBG; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; diff --git a/src/test/java/org/bouncycastle/crypto/test/DualECDRBGTest.java b/src/test/java/org/bouncycastle/crypto/test/DualECDRBGTest.java index 9161e6e5..8764b694 100644 --- a/src/test/java/org/bouncycastle/crypto/test/DualECDRBGTest.java +++ b/src/test/java/org/bouncycastle/crypto/test/DualECDRBGTest.java @@ -3,8 +3,8 @@ package org.bouncycastle.crypto.test; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA384Digest; import org.bouncycastle.crypto.digests.SHA512Digest; -import org.bouncycastle.crypto.prng.DualECSP800DRBG; -import org.bouncycastle.crypto.prng.SP80090DRBG; +import org.bouncycastle.crypto.prng.drbg.DualECSP800DRBG; +import org.bouncycastle.crypto.prng.drbg.SP80090DRBG; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; diff --git a/src/test/java/org/bouncycastle/crypto/test/HMacDRBGTest.java b/src/test/java/org/bouncycastle/crypto/test/HMacDRBGTest.java index e98d770c..06f2b25b 100644 --- a/src/test/java/org/bouncycastle/crypto/test/HMacDRBGTest.java +++ b/src/test/java/org/bouncycastle/crypto/test/HMacDRBGTest.java @@ -5,8 +5,8 @@ import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA384Digest; import org.bouncycastle.crypto.digests.SHA512Digest; import org.bouncycastle.crypto.macs.HMac; -import org.bouncycastle.crypto.prng.HMacSP800DRBG; -import org.bouncycastle.crypto.prng.SP80090DRBG; +import org.bouncycastle.crypto.prng.drbg.HMacSP800DRBG; +import org.bouncycastle.crypto.prng.drbg.SP80090DRBG; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; diff --git a/src/test/java/org/bouncycastle/crypto/test/HashDRBGTest.java b/src/test/java/org/bouncycastle/crypto/test/HashDRBGTest.java index 06304d72..93920d64 100644 --- a/src/test/java/org/bouncycastle/crypto/test/HashDRBGTest.java +++ b/src/test/java/org/bouncycastle/crypto/test/HashDRBGTest.java @@ -4,8 +4,8 @@ import org.bouncycastle.crypto.digests.SHA1Digest; import org.bouncycastle.crypto.digests.SHA256Digest; import org.bouncycastle.crypto.digests.SHA384Digest; import org.bouncycastle.crypto.digests.SHA512Digest; -import org.bouncycastle.crypto.prng.HashSP800DRBG; -import org.bouncycastle.crypto.prng.SP80090DRBG; +import org.bouncycastle.crypto.prng.drbg.HashSP800DRBG; +import org.bouncycastle.crypto.prng.drbg.SP80090DRBG; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.util.test.SimpleTest; |