package org.bouncycastle.crypto.prng.drbg; import java.util.Hashtable; import org.bouncycastle.crypto.Digest; import org.bouncycastle.crypto.Mac; import org.bouncycastle.util.Integers; class Utils { static final Hashtable maxSecurityStrengths = new Hashtable(); static { maxSecurityStrengths.put("SHA-1", Integers.valueOf(128)); maxSecurityStrengths.put("SHA-224", Integers.valueOf(192)); maxSecurityStrengths.put("SHA-256", Integers.valueOf(256)); maxSecurityStrengths.put("SHA-384", Integers.valueOf(256)); maxSecurityStrengths.put("SHA-512", Integers.valueOf(256)); maxSecurityStrengths.put("SHA-512/224", Integers.valueOf(192)); maxSecurityStrengths.put("SHA-512/256", Integers.valueOf(256)); } static int getMaxSecurityStrength(Digest d) { return ((Integer)maxSecurityStrengths.get(d.getAlgorithmName())).intValue(); } static int getMaxSecurityStrength(Mac m) { String name = m.getAlgorithmName(); return ((Integer)maxSecurityStrengths.get(name.substring(0, name.indexOf("/")))).intValue(); } /** * Used by both Dual EC and Hash. */ static byte[] hash_df(Digest digest, byte[] seedMaterial, int seedLength) { // 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. byte[] temp = new byte[(seedLength + 7) / 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; } static boolean isTooLarge(byte[] bytes, int maxBytes) { return bytes != null && bytes.length > maxBytes; } }