diff options
author | Raif S. Naffah <raif@swiftdsl.com.au> | 2006-07-02 03:01:19 +0000 |
---|---|---|
committer | Raif S. Naffah <raif@swiftdsl.com.au> | 2006-07-02 03:01:19 +0000 |
commit | 6b3542ebfe554f365d92403d072963c5b6190120 (patch) | |
tree | 55bcb220a3f78b26ff8489f0f0a3ca45973b20a3 | |
parent | 4851e34db00190b161b648d15c2de98622351179 (diff) | |
download | classpath-6b3542ebfe554f365d92403d072963c5b6190120.tar.gz |
2006-07-02 Raif S. Naffah <raif@swiftdsl.com.au>
* gnu/javax/crypto/prng/ARCFour.java: Source formatting.
* gnu/javax/crypto/prng/CSPRNG.java: Likewise.
* gnu/javax/crypto/prng/Fortuna.java: Likewise.
* gnu/javax/crypto/prng/ICMGenerator.java: Likewise.
* gnu/javax/crypto/prng/PBKDF2.java: Likewise.
* gnu/javax/crypto/prng/PRNGFactory.java: Likewise.
* gnu/javax/crypto/prng/UMacGenerator.java: Likewise.
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | gnu/javax/crypto/prng/ARCFour.java | 88 | ||||
-rw-r--r-- | gnu/javax/crypto/prng/CSPRNG.java | 813 | ||||
-rw-r--r-- | gnu/javax/crypto/prng/Fortuna.java | 110 | ||||
-rw-r--r-- | gnu/javax/crypto/prng/ICMGenerator.java | 252 | ||||
-rw-r--r-- | gnu/javax/crypto/prng/PBKDF2.java | 103 | ||||
-rw-r--r-- | gnu/javax/crypto/prng/PRNGFactory.java | 66 | ||||
-rw-r--r-- | gnu/javax/crypto/prng/UMacGenerator.java | 136 |
8 files changed, 576 insertions, 1002 deletions
@@ -1,5 +1,15 @@ 2006-07-02 Raif S. Naffah <raif@swiftdsl.com.au> + * gnu/javax/crypto/prng/ARCFour.java: Source formatting. + * gnu/javax/crypto/prng/CSPRNG.java: Likewise. + * gnu/javax/crypto/prng/Fortuna.java: Likewise. + * gnu/javax/crypto/prng/ICMGenerator.java: Likewise. + * gnu/javax/crypto/prng/PBKDF2.java: Likewise. + * gnu/javax/crypto/prng/PRNGFactory.java: Likewise. + * gnu/javax/crypto/prng/UMacGenerator.java: Likewise. + +2006-07-02 Raif S. Naffah <raif@swiftdsl.com.au> + * gnu/javax/crypto/pad/BasePad.java: Source formatting. * gnu/javax/crypto/pad/IPad.java: Likewise. * gnu/javax/crypto/pad/PadFactory.java: Likewise. diff --git a/gnu/javax/crypto/prng/ARCFour.java b/gnu/javax/crypto/prng/ARCFour.java index 22316ec8b..b72652942 100644 --- a/gnu/javax/crypto/prng/ARCFour.java +++ b/gnu/javax/crypto/prng/ARCFour.java @@ -45,88 +45,65 @@ import gnu.java.security.prng.LimitReachedException; import java.util.Map; /** - * RC4 is a stream cipher developed by Ron Rivest. Until 1994 RC4 was a - * trade secret of RSA Data Security, Inc., when it was released - * anonymously to a mailing list. This version is a descendent of that - * code, and since there is no proof that the leaked version was in fact - * RC4 and because "RC4" is a trademark, it is called "ARCFOUR", short for - * "Allegedly RC4". - * - * <p>This class only implements the <i>keystream</i> of ARCFOUR. To use - * this as a stream cipher, one would say:</p> - * - * <pre> out = in ^ arcfour.nextByte();</pre> - * - * <p>This operation works for encryption and decryption.</p> - * - * <p>References:</p> - * + * RC4 is a stream cipher developed by Ron Rivest. Until 1994 RC4 was a trade + * secret of RSA Data Security, Inc., when it was released anonymously to a + * mailing list. This version is a descendent of that code, and since there is + * no proof that the leaked version was in fact RC4 and because "RC4" is a + * trademark, it is called "ARCFOUR", short for "Allegedly RC4". + * <p> + * This class only implements the <i>keystream</i> of ARCFOUR. To use this as a + * stream cipher, one would say: + * <pre> + * out = in ˆ arcfour.nextByte(); + * </pre> + * <p> + * This operation works for encryption and decryption. + * <p> + * References: * <ol> - * <li>Schneier, Bruce: <i>Applied Cryptography: Protocols, Algorithms, - * and Source Code in C, Second Edition.</i> (1996 John Wiley and Sons), - * pp. 397--398. ISBN 0-471-11709-9</li> + * <li>Schneier, Bruce: <i>Applied Cryptography: Protocols, Algorithms, and + * Source Code in C, Second Edition.</i> (1996 John Wiley and Sons), pp. + * 397--398. ISBN 0-471-11709-9</li> * <li>K. Kaukonen and R. Thayer, "A Stream Cipher Encryption Algorithm * 'Arcfour'", Internet Draft (expired), <a * href="http://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt">draft-kaukonen-cipher-arcfour-03.txt</a></li> * </ol> */ -public class ARCFour extends BasePRNG implements Cloneable +public class ARCFour + extends BasePRNG + implements Cloneable { - - // Constants and variables. - // ----------------------------------------------------------------------- - /** The attributes property name for the key bytes. */ public static final String ARCFOUR_KEY_MATERIAL = "gnu.crypto.prng.arcfour.key-material"; - /** The size of the internal S-box. */ public static final int ARCFOUR_SBOX_SIZE = 256; - /** The S-box. */ private byte[] s; - private byte m, n; - // Constructors. - // ----------------------------------------------------------------------- - /** Default 0-arguments constructor. */ public ARCFour() { super(Registry.ARCFOUR_PRNG); } - // Methods implementing BasePRNG. - // ----------------------------------------------------------------------- - public void setup(Map attributes) { byte[] kb = (byte[]) attributes.get(ARCFOUR_KEY_MATERIAL); - if (kb == null) - { - throw new IllegalArgumentException("ARCFOUR needs a key"); - } - + throw new IllegalArgumentException("ARCFOUR needs a key"); s = new byte[ARCFOUR_SBOX_SIZE]; m = n = 0; byte[] k = new byte[ARCFOUR_SBOX_SIZE]; - for (int i = 0; i < ARCFOUR_SBOX_SIZE; i++) - { - s[i] = (byte) i; - } - + s[i] = (byte) i; if (kb.length > 0) - { - for (int i = 0, j = 0; i < ARCFOUR_SBOX_SIZE; i++) - { - k[i] = kb[j++]; - if (j >= kb.length) - j = 0; - } - } - + for (int i = 0, j = 0; i < ARCFOUR_SBOX_SIZE; i++) + { + k[i] = kb[j++]; + if (j >= kb.length) + j = 0; + } for (int i = 0, j = 0; i < ARCFOUR_SBOX_SIZE; i++) { j = j + s[i] + k[i]; @@ -134,7 +111,6 @@ public class ARCFour extends BasePRNG implements Cloneable s[i] = s[j & 0xff]; s[j & 0xff] = temp; } - buffer = new byte[ARCFOUR_SBOX_SIZE]; try { @@ -150,12 +126,12 @@ public class ARCFour extends BasePRNG implements Cloneable for (int i = 0; i < buffer.length; i++) { m++; - n = (byte) (n + s[m & 0xff]); + n = (byte)(n + s[m & 0xff]); byte temp = s[m & 0xff]; s[m & 0xff] = s[n & 0xff]; s[n & 0xff] = temp; - temp = (byte) (s[m & 0xff] + s[n & 0xff]); + temp = (byte)(s[m & 0xff] + s[n & 0xff]); buffer[i] = s[temp & 0xff]; } } -}
\ No newline at end of file +} diff --git a/gnu/javax/crypto/prng/CSPRNG.java b/gnu/javax/crypto/prng/CSPRNG.java index 910d15fec..2cf75a966 100644 --- a/gnu/javax/crypto/prng/CSPRNG.java +++ b/gnu/javax/crypto/prng/CSPRNG.java @@ -73,102 +73,81 @@ import java.util.logging.Level; import java.util.logging.Logger; /** - * <p>An entropy pool-based pseudo-random number generator based on the PRNG - * in Peter Gutmann's cryptlib (<a - * href="http://www.cs.auckland.ac.nz/~pgut001/cryptlib/">http://www.cs.auckland.ac.nz/~pgut001/cryptlib/</a>).</p> - * - * <p>The basic properties of this generator are:</p> - * + * An entropy pool-based pseudo-random number generator based on the PRNG in + * Peter Gutmann's cryptlib (<a + * href="http://www.cs.auckland.ac.nz/~pgut001/cryptlib/">http://www.cs.auckland.ac.nz/~pgut001/cryptlib/</a>). + * <p> + * The basic properties of this generator are: * <ol> * <li>The internal state cannot be determined by knowledge of the input.</li> * <li>It is resistant to bias introduced by specific inputs.</li> * <li>The output does not reveal the state of the generator.</li> * </ol> */ -public class CSPRNG extends BasePRNG +public class CSPRNG + extends BasePRNG { private static final Logger log = Logger.getLogger(CSPRNG.class.getName()); /** - * Property name for the list of files to read for random values. The - * mapped value is a list with the following values: - * + * Property name for the list of files to read for random values. The mapped + * value is a list with the following values: * <ol> * <li>A {@link Double}, indicating the suggested <i>quality</i> of this * source. This value must be between 0 and 100.</li> - * <li>An {@link Integer}, indicating the number of bytes to skip in the file - * before reading bytes. This can be any nonnegative value.</li> + * <li>An {@link Integer}, indicating the number of bytes to skip in the + * file before reading bytes. This can be any nonnegative value.</li> * <li>An {@link Integer}, indicating the number of bytes to read.</li> * <li>A {@link String}, indicating the path to the file.</li> * </ol> - * + * * @see gnu.java.security.util.SimpleList */ public static final String FILE_SOURCES = "gnu.crypto.prng.pool.files"; - /** - * Property name for the list of URLs to poll for random values. The - * mapped value is a list formatted similarly as in {@link #FILE_SOURCES}, - * but the fourth member is a {@link URL}. + * Property name for the list of URLs to poll for random values. The mapped + * value is a list formatted similarly as in {@link #FILE_SOURCES}, but the + * fourth member is a {@link URL}. */ public static final String URL_SOURCES = "gnu.crypto.prng.pool.urls"; - /** - * Property name for the list of programs to execute, and use the output - * as new random bytes. The mapped property is formatted similarly an in - * {@link #FILE_SOURCES} and {@link #URL_SOURCES}, except the fourth - * member is a {@link String} of the program to execute. + * Property name for the list of programs to execute, and use the output as + * new random bytes. The mapped property is formatted similarly an in + * {@link #FILE_SOURCES} and {@link #URL_SOURCES}, except the fourth member + * is a {@link String} of the program to execute. */ public static final String PROGRAM_SOURCES = "gnu.crypto.prng.pool.programs"; - /** - * Property name for a list of other sources of entropy. The mapped - * value must be a list of {@link EntropySource} objects. + * Property name for a list of other sources of entropy. The mapped value must + * be a list of {@link EntropySource} objects. */ public static final String OTHER_SOURCES = "gnu.crypto.prng.pool.other"; - /** - * Property name for whether or not to wait for the slow poll to - * complete, passed as a {@link Boolean}. The default value is true. + * Property name for whether or not to wait for the slow poll to complete, + * passed as a {@link Boolean}. The default value is true. */ public static final String BLOCKING = "gnu.crypto.prng.pool.blocking"; - private static final String FILES = "gnu.crypto.csprng.file."; - private static final String URLS = "gnu.crypto.csprng.url."; - private static final String PROGS = "gnu.crypto.csprng.program."; - private static final String OTHER = "gnu.crypto.csprng.other."; - private static final String BLOCK = "gnu.crypto.csprng.blocking"; - private static final int POOL_SIZE = 256; - private static final int ALLOC_SIZE = 260; - private static final int OUTPUT_SIZE = POOL_SIZE / 2; - private static final int X917_POOL_SIZE = 16; - private static final String HASH_FUNCTION = Registry.SHA160_HASH; - private static final String CIPHER = Registry.AES_CIPHER; - private static final int MIX_COUNT = 10; - private static final int X917_LIFETIME = 8192; - // FIXME this should be configurable. private static final int SPINNER_COUNT = 8; - /** * The spinner group singleton. We use this to add a small amount of - * randomness (in addition to the current time and the amount of - * free memory) based on the randomness (if any) present due to - * system load and thread scheduling. + * randomness (in addition to the current time and the amount of free memory) + * based on the randomness (if any) present due to system load and thread + * scheduling. */ private static final Spinner[] SPINNERS = new Spinner[SPINNER_COUNT]; - private static final Thread[] SPINNER_THREADS = new Thread[SPINNER_COUNT]; static { @@ -181,87 +160,38 @@ public class CSPRNG extends BasePRNG SPINNER_THREADS[i].start(); } } - - /** - * The message digest (SHA-1) used in the mixing function. - */ + /** The message digest (SHA-1) used in the mixing function. */ private final IMessageDigest hash; - - /** - * The cipher (AES) used in the output masking function. - */ + /** The cipher (AES) used in the output masking function. */ private final IBlockCipher cipher; - - /** - * The number of times the pool has been mixed. - */ + /** The number of times the pool has been mixed. */ private int mixCount; - - /** - * The entropy pool. - */ + /** The entropy pool. */ private final byte[] pool; - - /** - * The quality of the random pool (percentage). - */ + /** The quality of the random pool (percentage). */ private double quality; - - /** - * The index of the next byte in the entropy pool. - */ + /** The index of the next byte in the entropy pool. */ private int index; - - /** - * The pool for the X9.17-like generator. - */ + /** The pool for the X9.17-like generator. */ private byte[] x917pool; - - /** - * The number of iterations of the X9.17-like generators. - */ + /** The number of iterations of the X9.17-like generators. */ private int x917count; - - /** - * Whether or not the X9.17-like generator is initialized. - */ + /** Whether or not the X9.17-like generator is initialized. */ private boolean x917init; - - /** - * The list of file soures. - */ + /** The list of file soures. */ private final List files; - - /** - * The list of URL sources. - */ + /** The list of URL sources. */ private final List urls; - - /** - * The list of program sources. - */ + /** The list of program sources. */ private final List progs; - - /** - * The list of other sources. - */ + /** The list of other sources. */ private final List other; - - /** - * Whether or not to wait for the slow poll to complete. - */ + /** Whether or not to wait for the slow poll to complete. */ private boolean blocking; - - /** - * The thread that polls for random data. - */ + /** The thread that polls for random data. */ private Poller poller; - private Thread pollerThread; - // Constructor. - // ------------------------------------------------------------------------- - public CSPRNG() { super("CSPRNG"); @@ -281,69 +211,75 @@ public class CSPRNG extends BasePRNG other = new LinkedList(); } - // Class methods. - // ------------------------------------------------------------------------- - /** - * <p>Create and initialize a CSPRNG instance with the "system" parameters; - * the files, URLs, programs, and {@link EntropySource} sources used by - * the instance are derived from properties set in the system {@link - * Properties}.</p> - * - * <p>All properties are of the from <i>name</i>.</i>N</i>, where <i>name</i> + * Create and initialize a CSPRNG instance with the "system" parameters; the + * files, URLs, programs, and {@link EntropySource} sources used by the + * instance are derived from properties set in the system {@link Properties}. + * <p> + * All properties are of the from <i>name</i>.</i>N</i>, where <i>name</i> * is the name of the source, and <i>N</i> is an integer (staring at 1) that - * indicates the preference number for that source.</p> - * - * <p>The following vales for <i>name</i> are used here:</p> - * + * indicates the preference number for that source. + * <p> + * The following vales for <i>name</i> are used here: * <dl> * <dt>gnu.crypto.csprng.file</dt> - * <dd><p>These properties are file sources, passed as the {@link #FILE_SOURCES} - * parameter of the instance. The property value is a 4-tuple formatted as:</p> - * + * <dd> + * <p> + * These properties are file sources, passed as the {@link #FILE_SOURCES} + * parameter of the instance. The property value is a 4-tuple formatted as: + * </p> * <blockquote><i>quality</i> ; <i>offset</i> ; <i>count</i> ; <i>path</i></blockquote> - * - * <p>The parameters are mapped to the parameters defined for {@link - * #FILE_SOURCES}. Leading or trailing spaces on any item are trimmed - * off.</p></dd> - * + * <p> + * The parameters are mapped to the parameters defined for {@link + * #FILE_SOURCES}. Leading or trailing spaces on any item are trimmed off. + * </p> + * </dd> * <dt>gnu.crypto.csprng.url</dt> - * <dd><p>These properties are URL sources, passed as the {@link #URL_SOURCES} + * <dd> + * <p> + * These properties are URL sources, passed as the {@link #URL_SOURCES} * parameter of the instance. The property is formatted the same way as file - * sources, but the <i>path</i> argument must be a valid URL.</p></dd> - * + * sources, but the <i>path</i> argument must be a valid URL. + * </p> + * </dd> * <dt>gnu.crypto.csprng.program</dt> - * <dd><p>These properties are program sources, passed as the {@link - * #PROGRAM_SOURCES} parameter of the instance. This property is formatted - * the same way as file and URL sources, but the last argument is a program - * and its arguments.</p></dd> - * + * <dd> + * <p> + * These properties are program sources, passed as the {@link + * #PROGRAM_SOURCES} parameter of the instance. This property is formatted the + * same way as file and URL sources, but the last argument is a program and + * its arguments. + * </p> + * </dd> * <dt>gnu.crypto.cspring.other</dt> - * <dd><p>These properties are other sources, passed as the {@link #OTHER_SOURCES} - * parameter of the instance. The property value must be the full name - * of a class that implements the {@link EntropySource} interface and has a - * public no-argument constructor.</p></dd> + * <dd> + * <p> + * These properties are other sources, passed as the {@link #OTHER_SOURCES} + * parameter of the instance. The property value must be the full name of a + * class that implements the {@link EntropySource} interface and has a public + * no-argument constructor. + * </p> + * </dd> * </dl> - * - * <p>Finally, a boolean property "gnu.crypto.csprng.blocking" can be set to - * the desired value of {@link #BLOCKING}.</p> - * - * <p>An example of valid properties would be:</p> - * + * <p> + * Finally, a boolean property "gnu.crypto.csprng.blocking" can be set to the + * desired value of {@link #BLOCKING}. + * <p> + * An example of valid properties would be: * <pre> - * gnu.crypto.csprng.blocking=true - * - * gnu.crypto.csprng.file.1=75.0;0;256;/dev/random - * gnu.crypto.csprng.file.2=10.0;0;100;/home/user/file - * - * gnu.crypto.csprng.url.1=5.0;0;256;http://www.random.org/cgi-bin/randbyte?nbytes=256 - * gnu.crypto.csprng.url.2=0;256;256;http://slashdot.org/ - * - * gnu.crypto.csprng.program.1=0.5;0;10;last -n 50 - * gnu.crypto.csprng.program.2=0.5;0;10;tcpdump -c 5 - * - * gnu.crypto.csprng.other.1=foo.bar.MyEntropySource - * gnu.crypto.csprng.other.2=com.company.OtherEntropySource + * gnu.crypto.csprng.blocking=true + * + * gnu.crypto.csprng.file.1=75.0;0;256;/dev/random + * gnu.crypto.csprng.file.2=10.0;0;100;/home/user/file + * + * gnu.crypto.csprng.url.1=5.0;0;256;http://www.random.org/cgi-bin/randbyte?nbytes=256 + * gnu.crypto.csprng.url.2=0;256;256;http://slashdot.org/ + * + * gnu.crypto.csprng.program.1=0.5;0;10;last -n 50 + * gnu.crypto.csprng.program.2=0.5;0;10;tcpdump -c 5 + * + * gnu.crypto.csprng.other.1=foo.bar.MyEntropySource + * gnu.crypto.csprng.other.2=com.company.OtherEntropySource * </pre> */ public static IRandom getSystemInstance() throws ClassNotFoundException, @@ -353,70 +289,57 @@ public class CSPRNG extends BasePRNG HashMap attrib = new HashMap(); attrib.put(BLOCKING, Boolean.valueOf(getProperty(BLOCK))); String s = null; - // Get each file source "gnu.crypto.csprng.file.N". List l = new LinkedList(); for (int i = 0; (s = getProperty(FILES + i)) != null; i++) - { - try - { - l.add(parseString(s.trim())); - } - catch (NumberFormatException nfe) - { - } - } + try + { + l.add(parseString(s.trim())); + } + catch (NumberFormatException nfe) + { + } attrib.put(FILE_SOURCES, l); - l = new LinkedList(); for (int i = 0; (s = getProperty(URLS + i)) != null; i++) - { - try - { - l.add(parseURL(s.trim())); - } - catch (NumberFormatException nfe) - { - } - catch (MalformedURLException mue) - { - } - } + try + { + l.add(parseURL(s.trim())); + } + catch (NumberFormatException nfe) + { + } + catch (MalformedURLException mue) + { + } attrib.put(URL_SOURCES, l); - l = new LinkedList(); for (int i = 0; (s = getProperty(PROGS + i)) != null; i++) - { - try - { - l.add(parseString(s.trim())); - } - catch (NumberFormatException nfe) - { - } - } + try + { + l.add(parseString(s.trim())); + } + catch (NumberFormatException nfe) + { + } attrib.put(PROGRAM_SOURCES, l); - l = new LinkedList(); for (int i = 0; (s = getProperty(OTHER + i)) != null; i++) - { - try - { - Class c = Class.forName(s.trim()); - l.add(c.newInstance()); - } - catch (ClassNotFoundException cnfe) - { - } - catch (InstantiationException ie) - { - } - catch (IllegalAccessException iae) - { - } - } + try + { + Class c = Class.forName(s.trim()); + l.add(c.newInstance()); + } + catch (ClassNotFoundException cnfe) + { + } + catch (InstantiationException ie) + { + } + catch (IllegalAccessException iae) + { + } attrib.put(OTHER_SOURCES, l); - instance.init(attrib); return instance; } @@ -436,9 +359,7 @@ public class CSPRNG extends BasePRNG { StringTokenizer tok = new StringTokenizer(s, ";"); if (tok.countTokens() != 4) - { - throw new IllegalArgumentException("malformed property"); - } + throw new IllegalArgumentException("malformed property"); Double quality = new Double(tok.nextToken()); Integer offset = new Integer(tok.nextToken()); Integer length = new Integer(tok.nextToken()); @@ -451,9 +372,7 @@ public class CSPRNG extends BasePRNG { StringTokenizer tok = new StringTokenizer(s, ";"); if (tok.countTokens() != 4) - { - throw new IllegalArgumentException("malformed property"); - } + throw new IllegalArgumentException("malformed property"); Double quality = new Double(tok.nextToken()); Integer offset = new Integer(tok.nextToken()); Integer length = new Integer(tok.nextToken()); @@ -461,9 +380,6 @@ public class CSPRNG extends BasePRNG return new SimpleList(quality, offset, length, url); } - // Instance methods. - // ------------------------------------------------------------------------- - public Object clone() { return new CSPRNG(); @@ -507,7 +423,6 @@ public class CSPRNG extends BasePRNG log.log(Level.FINE, "bad file list", cce); throw new IllegalArgumentException("invalid file list"); } - try { list = (List) attrib.get(URL_SOURCES); @@ -541,7 +456,6 @@ public class CSPRNG extends BasePRNG log.log(Level.FINE, "bad URL list", cce); throw new IllegalArgumentException("invalid URL list"); } - try { list = (List) attrib.get(PROGRAM_SOURCES); @@ -575,7 +489,6 @@ public class CSPRNG extends BasePRNG log.log(Level.FINE, "bad program list", cce); throw new IllegalArgumentException("invalid program list"); } - try { list = (List) attrib.get(OTHER_SOURCES); @@ -590,9 +503,7 @@ public class CSPRNG extends BasePRNG if (Configuration.DEBUG) log.fine("src=" + src); if (src == null) - { - throw new NullPointerException("null source in source list"); - } + throw new NullPointerException("null source in source list"); other.add(src); } } @@ -606,19 +517,14 @@ public class CSPRNG extends BasePRNG { Boolean block = (Boolean) attrib.get(BLOCKING); if (block != null) - { - blocking = block.booleanValue(); - } + blocking = block.booleanValue(); else - { - blocking = true; - } + blocking = true; } catch (ClassCastException cce) { throw new IllegalArgumentException("invalid blocking parameter"); } - poller = new Poller(files, urls, progs, other, this); try { @@ -640,15 +546,13 @@ public class CSPRNG extends BasePRNG log.fine("doing slow poll"); slowPoll(); } - do { fastPoll(); mixRandomPool(); } while (mixCount < MIX_COUNT); - - if (!x917init || x917count >= X917_LIFETIME) + if (! x917init || x917count >= X917_LIFETIME) { mixRandomPool(pool); Map attr = new HashMap(); @@ -664,55 +568,41 @@ public class CSPRNG extends BasePRNG { throw new Error(ike.toString()); } - mixRandomPool(pool); generateX917(pool); mixRandomPool(pool); generateX917(pool); - if (x917init) - { - quality = 0.0; - } + quality = 0.0; x917init = true; x917count = 0; } - byte[] export = new byte[ALLOC_SIZE]; for (int i = 0; i < ALLOC_SIZE; i++) - { - export[i] = (byte) (pool[i] ^ 0xFF); - } - + export[i] = (byte)(pool[i] ^ 0xFF); mixRandomPool(); mixRandomPool(export); - generateX917(export); - for (int i = 0; i < OUTPUT_SIZE; i++) - { - buffer[i] = (byte) (export[i] ^ export[i + OUTPUT_SIZE]); - } + buffer[i] = (byte)(export[i] ^ export[i + OUTPUT_SIZE]); Arrays.fill(export, (byte) 0); } /** - * Add an array of bytes into the randomness pool. Note that this method - * will <i>not</i> increment the pool's quality counter (this can only be - * done via a source provided to the setup method). - * + * Add an array of bytes into the randomness pool. Note that this method will + * <i>not</i> increment the pool's quality counter (this can only be done via + * a source provided to the setup method). + * * @param buf The byte array. * @param off The offset from whence to start reading bytes. * @param len The number of bytes to add. * @throws ArrayIndexOutOfBoundsException If <i>off</i> or <i>len</i> are - * out of the range of <i>buf</i>. + * out of the range of <i>buf</i>. */ public synchronized void addRandomBytes(byte[] buf, int off, int len) { if (off < 0 || len < 0 || off + len > buf.length) - { - throw new ArrayIndexOutOfBoundsException(); - } + throw new ArrayIndexOutOfBoundsException(); if (Configuration.DEBUG) { log.fine("adding random bytes:"); @@ -731,10 +621,10 @@ public class CSPRNG extends BasePRNG } /** - * Add a single random byte to the randomness pool. Note that this method - * will <i>not</i> increment the pool's quality counter (this can only be - * done via a source provided to the setup method). - * + * Add a single random byte to the randomness pool. Note that this method will + * <i>not</i> increment the pool's quality counter (this can only be done via + * a source provided to the setup method). + * * @param b The byte to add. */ public synchronized void addRandomByte(byte b) @@ -749,17 +639,12 @@ public class CSPRNG extends BasePRNG } } - // Package methods. - // ------------------------------------------------------------------------- - synchronized void addQuality(double quality) { if (Configuration.DEBUG) log.fine("adding quality " + quality); if (this.quality < 100) - { - this.quality += quality; - } + this.quality += quality; if (Configuration.DEBUG) log.fine("quality now " + this.quality); } @@ -769,13 +654,10 @@ public class CSPRNG extends BasePRNG return quality; } - // Own methods. - // ------------------------------------------------------------------------- - /** - * The mix operation. This method will, for every 20-byte block in the - * random pool, hash that block, the previous 20 bytes, and the next - * 44 bytes with SHA-1, writing the result back into that block. + * The mix operation. This method will, for every 20-byte block in the random + * pool, hash that block, the previous 20 bytes, and the next 44 bytes with + * SHA-1, writing the result back into that block. */ private void mixRandomPool(byte[] buf) { @@ -784,25 +666,17 @@ public class CSPRNG extends BasePRNG { // First update the bytes [p-19..p-1]. if (i == 0) - { - hash.update(buf, buf.length - hashSize, hashSize); - } + hash.update(buf, buf.length - hashSize, hashSize); else - { - hash.update(buf, i - hashSize, hashSize); - } - + hash.update(buf, i - hashSize, hashSize); // Now the next 64 bytes. if (i + 64 < buf.length) - { - hash.update(buf, i, 64); - } + hash.update(buf, i, 64); else { hash.update(buf, i, buf.length - i); hash.update(buf, 0, 64 - (buf.length - i)); } - byte[] digest = hash.digest(); System.arraycopy(digest, 0, buf, i, hashSize); } @@ -821,28 +695,22 @@ public class CSPRNG extends BasePRNG { int copy = Math.min(buf.length - i, X917_POOL_SIZE); for (int j = 0; j < copy; j++) - { - x917pool[j] ^= pool[off + j]; - } - + x917pool[j] ^= pool[off + j]; cipher.encryptBlock(x917pool, 0, x917pool, 0); System.arraycopy(x917pool, 0, buf, off, copy); cipher.encryptBlock(x917pool, 0, x917pool, 0); - off += copy; x917count++; } } /** - * Add random data always immediately available into the random pool, such - * as the values of the eight asynchronous counters, the current time, the - * current memory usage, the calling thread name, and the current stack - * trace. - * - * <p>This method does not alter the quality counter, and is provided more - * to maintain randomness, not to seriously improve the current random - * state. + * Add random data always immediately available into the random pool, such as + * the values of the eight asynchronous counters, the current time, the + * current memory usage, the calling thread name, and the current stack trace. + * <p> + * This method does not alter the quality counter, and is provided more to + * maintain randomness, not to seriously improve the current random state. */ private void fastPoll() { @@ -852,14 +720,12 @@ public class CSPRNG extends BasePRNG addRandomByte(b); addRandomByte((byte) System.currentTimeMillis()); addRandomByte((byte) Runtime.getRuntime().freeMemory()); - String s = Thread.currentThread().getName(); if (s != null) { byte[] buf = s.getBytes(); addRandomBytes(buf, 0, buf.length); } - ByteArrayOutputStream bout = new ByteArrayOutputStream(1024); PrintStream pout = new PrintStream(bout); Throwable t = new Throwable(); @@ -874,7 +740,7 @@ public class CSPRNG extends BasePRNG if (Configuration.DEBUG) log.fine("poller is alive? " + (pollerThread == null ? false : pollerThread.isAlive())); - if (pollerThread == null || !pollerThread.isAlive()) + if (pollerThread == null || ! pollerThread.isAlive()) { boolean interrupted = false; pollerThread = new Thread(poller); @@ -882,20 +748,17 @@ public class CSPRNG extends BasePRNG pollerThread.setPriority(Thread.NORM_PRIORITY - 1); pollerThread.start(); if (blocking) - { - try - { - pollerThread.join(); - } - catch (InterruptedException ie) - { - interrupted = true; - } - } - + try + { + pollerThread.join(); + } + catch (InterruptedException ie) + { + interrupted = true; + } // If the full slow poll has completed after we waited for it, // and there in insufficient randomness, throw an exception. - if (!interrupted && blocking && quality < 100.0) + if (! interrupted && blocking && quality < 100.0) { if (Configuration.DEBUG) log.fine("insufficient quality: " + quality); @@ -917,33 +780,21 @@ public class CSPRNG extends BasePRNG Arrays.fill(buffer, (byte) 0); } - // Inner classes. - // ------------------------------------------------------------------------- - /** - * A simple thread that constantly updates a byte counter. This class is - * used in a group of lowest-priority threads and the values of their - * counters (updated in competition with all other threads) is used as a - * source of entropy bits. + * A simple thread that constantly updates a byte counter. This class is used + * in a group of lowest-priority threads and the values of their counters + * (updated in competition with all other threads) is used as a source of + * entropy bits. */ - private static class Spinner implements Runnable + private static class Spinner + implements Runnable { - - // Field. - // ----------------------------------------------------------------------- - protected byte counter; - // Constructor. - // ----------------------------------------------------------------------- - private Spinner() { } - // Instance methods. - // ----------------------------------------------------------------------- - public void run() { while (true) @@ -960,27 +811,16 @@ public class CSPRNG extends BasePRNG } } - private final class Poller implements Runnable + private final class Poller + implements Runnable { - - // Fields. - // ----------------------------------------------------------------------- - private final List files; - private final List urls; - private final List progs; - private final List other; - private final CSPRNG pool; - private boolean running; - // Constructor. - // ----------------------------------------------------------------------- - Poller(List files, List urls, List progs, List other, CSPRNG pool) { super(); @@ -991,9 +831,6 @@ public class CSPRNG extends BasePRNG this.pool = pool; } - // Instance methods. - // ----------------------------------------------------------------------- - public void run() { running = true; @@ -1011,164 +848,132 @@ public class CSPRNG extends BasePRNG while (files_it.hasNext() || urls_it.hasNext() || prog_it.hasNext() || other_it.hasNext()) { - // There is enough random data. Go away. - if (pool.getQuality() >= 100.0 || !running) - { - return; - } - + if (pool.getQuality() >= 100.0 || ! running) + return; if (files_it.hasNext()) - { - try - { - List l = (List) files_it.next(); - if (Configuration.DEBUG) - log.fine(l.toString()); - double qual = ((Double) l.get(0)).doubleValue(); - int offset = ((Integer) l.get(1)).intValue(); - int count = ((Integer) l.get(2)).intValue(); - String src = (String) l.get(3); - InputStream in = new FileInputStream(src); - byte[] buf = new byte[count]; - if (offset > 0) - { - in.skip(offset); - } - int len = in.read(buf); - if (len >= 0) - { - pool.addRandomBytes(buf, 0, len); - pool.addQuality(qual * ((double) len / (double) count)); - } - if (Configuration.DEBUG) - log.fine("got " + len + " bytes from " + src); - } - catch (Exception x) - { - if (Configuration.DEBUG) - log.throwing(this.getClass().getName(), "run", x); - } - } - - if (pool.getQuality() >= 100.0 || !running) - { - return; - } - + try + { + List l = (List) files_it.next(); + if (Configuration.DEBUG) + log.fine(l.toString()); + double qual = ((Double) l.get(0)).doubleValue(); + int offset = ((Integer) l.get(1)).intValue(); + int count = ((Integer) l.get(2)).intValue(); + String src = (String) l.get(3); + InputStream in = new FileInputStream(src); + byte[] buf = new byte[count]; + if (offset > 0) + in.skip(offset); + int len = in.read(buf); + if (len >= 0) + { + pool.addRandomBytes(buf, 0, len); + pool.addQuality(qual * ((double) len / (double) count)); + } + if (Configuration.DEBUG) + log.fine("got " + len + " bytes from " + src); + } + catch (Exception x) + { + if (Configuration.DEBUG) + log.throwing(this.getClass().getName(), "run", x); + } + if (pool.getQuality() >= 100.0 || ! running) + return; if (urls_it.hasNext()) - { - try - { - List l = (List) urls_it.next(); - if (Configuration.DEBUG) - log.fine(l.toString()); - double qual = ((Double) l.get(0)).doubleValue(); - int offset = ((Integer) l.get(1)).intValue(); - int count = ((Integer) l.get(2)).intValue(); - URL src = (URL) l.get(3); - InputStream in = src.openStream(); - byte[] buf = new byte[count]; - if (offset > 0) - { - in.skip(offset); - } - int len = in.read(buf); - if (len >= 0) - { - pool.addRandomBytes(buf, 0, len); - pool.addQuality(qual * ((double) len / (double) count)); - } - if (Configuration.DEBUG) - log.fine("got " + len + " bytes from " + src); - } - catch (Exception x) - { - if (Configuration.DEBUG) - log.throwing(this.getClass().getName(), "run", x); - } - } - - if (pool.getQuality() >= 100.0 || !running) - { - return; - } - + try + { + List l = (List) urls_it.next(); + if (Configuration.DEBUG) + log.fine(l.toString()); + double qual = ((Double) l.get(0)).doubleValue(); + int offset = ((Integer) l.get(1)).intValue(); + int count = ((Integer) l.get(2)).intValue(); + URL src = (URL) l.get(3); + InputStream in = src.openStream(); + byte[] buf = new byte[count]; + if (offset > 0) + in.skip(offset); + int len = in.read(buf); + if (len >= 0) + { + pool.addRandomBytes(buf, 0, len); + pool.addQuality(qual * ((double) len / (double) count)); + } + if (Configuration.DEBUG) + log.fine("got " + len + " bytes from " + src); + } + catch (Exception x) + { + if (Configuration.DEBUG) + log.throwing(this.getClass().getName(), "run", x); + } + if (pool.getQuality() >= 100.0 || ! running) + return; Process proc = null; if (prog_it.hasNext()) - { - try - { - List l = (List) prog_it.next(); - if (Configuration.DEBUG) - log.finer(l.toString()); - double qual = ((Double) l.get(0)).doubleValue(); - int offset = ((Integer) l.get(1)).intValue(); - int count = ((Integer) l.get(2)).intValue(); - String src = (String) l.get(3); - proc = null; - proc = Runtime.getRuntime().exec(src); - InputStream in = proc.getInputStream(); - byte[] buf = new byte[count]; - if (offset > 0) - { - in.skip(offset); - } - int len = in.read(buf); - if (len >= 0) - { - pool.addRandomBytes(buf, 0, len); - pool.addQuality(qual * ((double) len / (double) count)); - } - proc.destroy(); - proc.waitFor(); - if (Configuration.DEBUG) - log.fine("got " + len + " bytes from " + src); - } - catch (Exception x) - { - if (Configuration.DEBUG) - log.throwing(this.getClass().getName(), "run", x); - try - { - if (proc != null) - { - proc.destroy(); - proc.waitFor(); - } - } - catch (Exception ignored) - { - } - } - } - - if (pool.getQuality() >= 100.0 || !running) - { - return; - } - + try + { + List l = (List) prog_it.next(); + if (Configuration.DEBUG) + log.finer(l.toString()); + double qual = ((Double) l.get(0)).doubleValue(); + int offset = ((Integer) l.get(1)).intValue(); + int count = ((Integer) l.get(2)).intValue(); + String src = (String) l.get(3); + proc = null; + proc = Runtime.getRuntime().exec(src); + InputStream in = proc.getInputStream(); + byte[] buf = new byte[count]; + if (offset > 0) + in.skip(offset); + int len = in.read(buf); + if (len >= 0) + { + pool.addRandomBytes(buf, 0, len); + pool.addQuality(qual * ((double) len / (double) count)); + } + proc.destroy(); + proc.waitFor(); + if (Configuration.DEBUG) + log.fine("got " + len + " bytes from " + src); + } + catch (Exception x) + { + if (Configuration.DEBUG) + log.throwing(this.getClass().getName(), "run", x); + try + { + if (proc != null) + { + proc.destroy(); + proc.waitFor(); + } + } + catch (Exception ignored) + { + } + } + if (pool.getQuality() >= 100.0 || ! running) + return; if (other_it.hasNext()) - { - try - { - EntropySource src = (EntropySource) other_it.next(); - byte[] buf = src.nextBytes(); - if (pool == null) - { - return; - } - pool.addRandomBytes(buf, 0, buf.length); - pool.addQuality(src.quality()); - if (Configuration.DEBUG) - log.fine("got " + buf.length + " bytes from " + src); - } - catch (Exception x) - { - if (Configuration.DEBUG) - log.throwing(this.getClass().getName(), "run", x); - } - } + try + { + EntropySource src = (EntropySource) other_it.next(); + byte[] buf = src.nextBytes(); + if (pool == null) + return; + pool.addRandomBytes(buf, 0, buf.length); + pool.addQuality(src.quality()); + if (Configuration.DEBUG) + log.fine("got " + buf.length + " bytes from " + src); + } + catch (Exception x) + { + if (Configuration.DEBUG) + log.throwing(this.getClass().getName(), "run", x); + } } } @@ -1177,4 +982,4 @@ public class CSPRNG extends BasePRNG running = false; } } -}
\ No newline at end of file +} diff --git a/gnu/javax/crypto/prng/Fortuna.java b/gnu/javax/crypto/prng/Fortuna.java index 69ce860f4..8aec9ab7d 100644 --- a/gnu/javax/crypto/prng/Fortuna.java +++ b/gnu/javax/crypto/prng/Fortuna.java @@ -45,7 +45,6 @@ import gnu.java.security.prng.BasePRNG; import gnu.java.security.prng.LimitReachedException; import gnu.java.security.prng.RandomEvent; import gnu.java.security.prng.RandomEventListener; - import gnu.javax.crypto.cipher.CipherFactory; import gnu.javax.crypto.cipher.IBlockCipher; @@ -53,9 +52,7 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; - import java.security.InvalidKeyException; - import java.util.Arrays; import java.util.Collections; import java.util.Iterator; @@ -63,68 +60,54 @@ import java.util.Map; /** * The Fortuna continuously-seeded pseudo-random number generator. This - * generator is composed of two major pieces: the entropy accumulator - * and the generator function. The former takes in random bits and - * incorporates them into the generator's state. The latter takes this - * base entropy and generates pseudo-random bits from it. - * - * <p>There are some things users of this class <em>must</em> be aware of: - * + * generator is composed of two major pieces: the entropy accumulator and the + * generator function. The former takes in random bits and incorporates them + * into the generator's state. The latter takes this base entropy and generates + * pseudo-random bits from it. + * <p> + * There are some things users of this class <em>must</em> be aware of: * <dl> * <dt>Adding Random Data</dt> * <dd>This class does not do any polling of random sources, but rather - * provides an interface for adding random events. Applications that use - * this code <em>must</em> provide this mechanism. We use this design - * because an application writer who knows the system he is targeting - * is in a better position to judge what random data is available.</dd> - * + * provides an interface for adding random events. Applications that use this + * code <em>must</em> provide this mechanism. We use this design because an + * application writer who knows the system he is targeting is in a better + * position to judge what random data is available.</dd> * <dt>Storing the Seed</dt> - * <dd>This class implements {@link Serializable} in such a way that it - * writes a 64 byte seed to the stream, and reads it back again when being - * deserialized. This is the extent of seed file management, however, and - * those using this class are encouraged to think deeply about when, how - * often, and where to store the seed.</dd> + * <dd>This class implements {@link Serializable} in such a way that it writes + * a 64 byte seed to the stream, and reads it back again when being + * deserialized. This is the extent of seed file management, however, and those + * using this class are encouraged to think deeply about when, how often, and + * where to store the seed.</dd> * </dl> - * - * <p><b>References:</b></p> - * + * <p> + * <b>References:</b> * <ul> - * <li>Niels Ferguson and Bruce Schneier, <i>Practical Cryptography</i>, - * pp. 155--184. Wiley Publishing, Indianapolis. (2003 Niels Ferguson and - * Bruce Schneier). ISBN 0-471-22357-3.</li> + * <li>Niels Ferguson and Bruce Schneier, <i>Practical Cryptography</i>, pp. + * 155--184. Wiley Publishing, Indianapolis. (2003 Niels Ferguson and Bruce + * Schneier). ISBN 0-471-22357-3.</li> * </ul> */ -public class Fortuna extends BasePRNG implements Serializable, - RandomEventListener +public class Fortuna + extends BasePRNG + implements Serializable, RandomEventListener { - private static final long serialVersionUID = 0xFACADE; - private static final int SEED_FILE_SIZE = 64; - private static final int NUM_POOLS = 32; - private static final int MIN_POOL_SIZE = 64; - private final Generator generator; - private final IMessageDigest[] pools; - private long lastReseed; - private int pool; - private int pool0Count; - private int reseedCount; - public static final String SEED = "gnu.crypto.prng.fortuna.seed"; public Fortuna() { super(Registry.FORTUNA_PRNG); - generator = new Generator( - CipherFactory.getInstance(Registry.RIJNDAEL_CIPHER), + generator = new Generator(CipherFactory.getInstance(Registry.RIJNDAEL_CIPHER), HashFactory.getInstance(Registry.SHA256_HASH)); pools = new IMessageDigest[NUM_POOLS]; for (int i = 0; i < NUM_POOLS; i++) @@ -144,11 +127,11 @@ public class Fortuna extends BasePRNG implements Serializable, generator.init(attributes); try { - fillBlock (); + fillBlock(); } catch (LimitReachedException shouldNotHappen) { - throw new RuntimeException (shouldNotHappen); + throw new RuntimeException(shouldNotHappen); } } @@ -160,10 +143,8 @@ public class Fortuna extends BasePRNG implements Serializable, reseedCount++; byte[] seed = new byte[0]; for (int i = 0; i < NUM_POOLS; i++) - { - if (reseedCount % (1 << i) == 0) - generator.addRandomBytes(pools[i].digest()); - } + if (reseedCount % (1 << i) == 0) + generator.addRandomBytes(pools[i].digest()); lastReseed = System.currentTimeMillis(); pool0Count = 0; } @@ -223,23 +204,19 @@ public class Fortuna extends BasePRNG implements Serializable, } /** - * The Fortuna generator function. The generator is a PRNG in its own - * right; Fortuna itself is basically a wrapper around this generator - * that manages reseeding in a secure way. + * The Fortuna generator function. The generator is a PRNG in its own right; + * Fortuna itself is basically a wrapper around this generator that manages + * reseeding in a secure way. */ - public static class Generator extends BasePRNG implements Cloneable + public static class Generator + extends BasePRNG + implements Cloneable { - private static final int LIMIT = 1 << 20; - private final IBlockCipher cipher; - private final IMessageDigest hash; - private final byte[] counter; - private final byte[] key; - private boolean seeded; public Generator(final IBlockCipher cipher, final IMessageDigest hash) @@ -270,9 +247,8 @@ public class Fortuna extends BasePRNG implements Serializable, public void nextBytes(byte[] out, int offset, int length) { - if (!seeded) + if (! seeded) throw new IllegalStateException("generator not seeded"); - int count = 0; do { @@ -286,7 +262,6 @@ public class Fortuna extends BasePRNG implements Serializable, throw new Error(shouldNeverHappen); } count += amount; - for (int i = 0; i < key.length; i += counter.length) { fillBlock(); @@ -318,7 +293,7 @@ public class Fortuna extends BasePRNG implements Serializable, public void fillBlock() { - if (!seeded) + if (! seeded) throw new IllegalStateException("generator not seeded"); cipher.encryptBlock(counter, 0, buffer, 0); incrementCounter(); @@ -332,13 +307,12 @@ public class Fortuna extends BasePRNG implements Serializable, byte[] seed = (byte[]) attributes.get(SEED); if (seed != null) addRandomBytes(seed); - fillBlock (); + fillBlock(); } /** - * Resets the cipher's key. This is done after every reseed, which - * combines the old key and the seed, and processes that throigh the - * hash function. + * Resets the cipher's key. This is done after every reseed, which combines + * the old key and the seed, and processes that throigh the hash function. */ private void resetKey() { @@ -359,8 +333,8 @@ public class Fortuna extends BasePRNG implements Serializable, } /** - * Increment `counter' as a sixteen-byte little-endian unsigned integer - * by one. + * Increment `counter' as a sixteen-byte little-endian unsigned integer by + * one. */ private void incrementCounter() { @@ -372,4 +346,4 @@ public class Fortuna extends BasePRNG implements Serializable, } } } -}
\ No newline at end of file +} diff --git a/gnu/javax/crypto/prng/ICMGenerator.java b/gnu/javax/crypto/prng/ICMGenerator.java index 1bfba64d6..5b0bd4f8b 100644 --- a/gnu/javax/crypto/prng/ICMGenerator.java +++ b/gnu/javax/crypto/prng/ICMGenerator.java @@ -41,9 +41,8 @@ package gnu.javax.crypto.prng; import gnu.java.security.Registry; import gnu.java.security.prng.BasePRNG; import gnu.java.security.prng.LimitReachedException; - -import gnu.javax.crypto.cipher.IBlockCipher; import gnu.javax.crypto.cipher.CipherFactory; +import gnu.javax.crypto.cipher.IBlockCipher; import java.math.BigInteger; import java.security.InvalidKeyException; @@ -51,171 +50,132 @@ import java.util.HashMap; import java.util.Map; /** - * <p>Counter Mode is a way to define a pseudorandom keystream generator using - * a block cipher. The keystream can be used for additive encryption, key - * derivation, or any other application requiring pseudorandom data.</p> - * - * <p>In ICM, the keystream is logically broken into segments. Each segment is + * Counter Mode is a way to define a pseudorandom keystream generator using a + * block cipher. The keystream can be used for additive encryption, key + * derivation, or any other application requiring pseudorandom data. + * <p> + * In ICM, the keystream is logically broken into segments. Each segment is * identified with a segment index, and the segments have equal lengths. This * segmentation makes ICM especially appropriate for securing packet-based - * protocols.</p> - * - * <p>This implementation adheres to the definition of the ICM keystream - * generation function that allows for any symetric key block cipher algorithm - * (initialisation parameter <code>gnu.crypto.prng.icm.cipher.name</code> taken - * to be an instance of {@link java.lang.String}) to be used. If such a + * protocols. + * <p> + * This implementation adheres to the definition of the ICM keystream generation + * function that allows for any symetric key block cipher algorithm + * (initialisation parameter <code>gnu.crypto.prng.icm.cipher.name</code> + * taken to be an instance of {@link java.lang.String}) to be used. If such a * parameter is not defined/included in the initialisation <code>Map</code>, * then the "Rijndael" algorithm is used. Furthermore, if the initialisation * parameter <code>gnu.crypto.cipher.block.size</code> (taken to be a instance * of {@link java.lang.Integer}) is missing or undefined in the initialisation - * <code>Map</code>, then the cipher's <em>default</em> block size is used.</p> - * - * <p>The practical limits and constraints of such generator are:</p> + * <code>Map</code>, then the cipher's <em>default</em> block size is used. + * <p> + * The practical limits and constraints of such generator are: * <ul> - * <li>The number of blocks in any segment <b>MUST NOT</b> exceed <code> - * 256 ** BLOCK_INDEX_LENGTH</code>. The number of segments <b>MUST NOT</b> - * exceed <code>256 ** SEGMENT_INDEX_LENGTH</code>. These restrictions ensure - * the uniqueness of each block cipher input.</li> - * - * <li>Each segment contains <code>SEGMENT_LENGTH</code> octets; this value - * <b>MUST NOT</b> exceed the value <code>(256 ** BLOCK_INDEX_LENGTH) * + * <li>The number of blocks in any segment <b>MUST NOT</b> exceed <code> + * 256 ** BLOCK_INDEX_LENGTH</code>. + * The number of segments <b>MUST NOT</b> exceed + * <code>256 ** SEGMENT_INDEX_LENGTH</code>. These restrictions ensure the + * uniqueness of each block cipher input.</li> + * <li>Each segment contains <code>SEGMENT_LENGTH</code> octets; this value + * <b>MUST NOT</b> exceed the value <code>(256 ** BLOCK_INDEX_LENGTH) * * BLOCK_LENGTH</code>.</li> - * - * <li>The sum of <code>SEGMENT_INDEX_LENGTH</code> and - * <code>BLOCK_INDEX_LENGTH</code> <b>MUST NOT</b> exceed <code>BLOCK_LENGTH - * / 2</code>. This requirement protects the ICM keystream generator from - * potentially failing to be pseudorandom.</li> + * <li>The sum of <code>SEGMENT_INDEX_LENGTH</code> and + * <code>BLOCK_INDEX_LENGTH</code> <b>MUST NOT</b> exceed <code>BLOCK_LENGTH + * / 2</code>. + * This requirement protects the ICM keystream generator from potentially + * failing to be pseudorandom.</li> * </ul> - * - * <p><b>NOTE</b>: Rijndael is used as the default symmetric key block cipher + * <p> + * <b>NOTE</b>: Rijndael is used as the default symmetric key block cipher * algorithm because, with its default block and key sizes, it is the AES. Yet * being Rijndael, the algorithm offers more versatile block and key sizes which - * may prove to be useful for generating <em>longer</em> key streams.</p> - * - * <p>References:</p> - * + * may prove to be useful for generating <em>longer</em> key streams. + * <p> + * References: * <ol> - * <li><a href="http://www.ietf.org/internet-drafts/draft-mcgrew-saag-icm-00.txt"> - * Integer Counter Mode</a>, David A. McGrew.</li> + * <li><a + * href="http://www.ietf.org/internet-drafts/draft-mcgrew-saag-icm-00.txt"> + * Integer Counter Mode</a>, David A. McGrew.</li> * </ol> */ -public class ICMGenerator extends BasePRNG implements Cloneable +public class ICMGenerator + extends BasePRNG + implements Cloneable { - - // Constants and variables - // ------------------------------------------------------------------------- - /** Property name of underlying block cipher for this ICM generator. */ public static final String CIPHER = "gnu.crypto.prng.icm.cipher.name"; - /** Property name of ICM's block index length. */ - public static final String BLOCK_INDEX_LENGTH = "gnu.crypto.prng.icm.block.index.length"; - + public static final String BLOCK_INDEX_LENGTH = + "gnu.crypto.prng.icm.block.index.length"; /** Property name of ICM's segment index length. */ - public static final String SEGMENT_INDEX_LENGTH = "gnu.crypto.prng.icm.segment.index.length"; - + public static final String SEGMENT_INDEX_LENGTH = + "gnu.crypto.prng.icm.segment.index.length"; /** Property name of ICM's offset. */ public static final String OFFSET = "gnu.crypto.prng.icm.offset"; - /** Property name of ICM's segment index. */ public static final String SEGMENT_INDEX = "gnu.crypto.prng.icm.segment.index"; - /** The integer value 256 as a BigInteger. */ private static final BigInteger TWO_FIFTY_SIX = new BigInteger("256"); - /** The underlying cipher implementation. */ private IBlockCipher cipher; - /** This keystream block index length in bytes. */ private int blockNdxLength = -1; - /** This keystream segment index length in bytes. */ private int segmentNdxLength = -1; - /** The index of the next block for a given keystream segment. */ private BigInteger blockNdx = BigInteger.ZERO; - /** The segment index for this keystream. */ private BigInteger segmentNdx; - /** The initial counter for a given keystream segment. */ private BigInteger C0; - // Constructor(s) - // ------------------------------------------------------------------------- - /** Trivial 0-arguments constructor. */ public ICMGenerator() { super(Registry.ICM_PRNG); } - // Class methods - // ------------------------------------------------------------------------- - - // Instance methods - // ------------------------------------------------------------------------- - - // Implementation of abstract methods in BasePRNG -------------------------- - - // Conceptually, ICM is a keystream generator that takes a secret key - // and a segment index as an input and then outputs a keystream - // segment. The segmentation lends itself to packet encryption, as - // each keystream segment can be used to encrypt a distinct packet. - // - // An ICM key consists of the block cipher key and an Offset. The - // Offset is an integer with BLOCK_LENGTH octets... + // Conceptually, ICM is a keystream generator that takes a secret key and a + // segment index as an input and then outputs a keystream segment. The + // segmentation lends itself to packet encryption, as each keystream segment + // can be used to encrypt a distinct packet. // + // An ICM key consists of the block cipher key and an Offset. The Offset is + // an integer with BLOCK_LENGTH octets... public void setup(Map attributes) { // find out which cipher algorithm to use boolean newCipher = true; String underlyingCipher = (String) attributes.get(CIPHER); if (underlyingCipher == null) - { - if (cipher == null) - { // happy birthday - // ensure we have a reliable implementation of this cipher - cipher = CipherFactory.getInstance(Registry.RIJNDAEL_CIPHER); - } - else - { // we already have one. use it as is - newCipher = false; - } - } - else - { // ensure we have a reliable implementation of this cipher - cipher = CipherFactory.getInstance(underlyingCipher); - } + if (cipher == null) // happy birthday + // ensure we have a reliable implementation of this cipher + cipher = CipherFactory.getInstance(Registry.RIJNDAEL_CIPHER); + else + // we already have one. use it as is + newCipher = false; + else // ensure we have a reliable implementation of this cipher + cipher = CipherFactory.getInstance(underlyingCipher); // find out what block size we should use it in int cipherBlockSize = 0; Integer bs = (Integer) attributes.get(IBlockCipher.CIPHER_BLOCK_SIZE); if (bs != null) - { - cipherBlockSize = bs.intValue(); - } + cipherBlockSize = bs.intValue(); else { - if (newCipher) - { // assume we'll use its default block size - cipherBlockSize = cipher.defaultBlockSize(); - } // else use as is + if (newCipher) // assume we'll use its default block size + cipherBlockSize = cipher.defaultBlockSize(); + // else use as is } - // get the key material byte[] key = (byte[]) attributes.get(IBlockCipher.KEY_MATERIAL); if (key == null) - { - throw new IllegalArgumentException(IBlockCipher.KEY_MATERIAL); - } - + throw new IllegalArgumentException(IBlockCipher.KEY_MATERIAL); // now initialise the cipher HashMap map = new HashMap(); - if (cipherBlockSize != 0) - { // only needed if new or changed - map.put(IBlockCipher.CIPHER_BLOCK_SIZE, Integer.valueOf(cipherBlockSize)); - } + if (cipherBlockSize != 0) // only needed if new or changed + map.put(IBlockCipher.CIPHER_BLOCK_SIZE, Integer.valueOf(cipherBlockSize)); map.put(IBlockCipher.KEY_MATERIAL, key); try { @@ -225,135 +185,96 @@ public class ICMGenerator extends BasePRNG implements Cloneable { throw new IllegalArgumentException(IBlockCipher.KEY_MATERIAL); } - // at this point we have an initialised (new or otherwise) cipher // ensure that remaining params make sense - cipherBlockSize = cipher.currentBlockSize(); BigInteger counterRange = TWO_FIFTY_SIX.pow(cipherBlockSize); - // offset, like the underlying cipher key is not cloneable // always look for it and throw an exception if it's not there Object obj = attributes.get(OFFSET); // allow either a byte[] or a BigInteger BigInteger r; if (obj instanceof BigInteger) + r = (BigInteger) obj; + else // assume byte[]. should be same length as cipher block size { - r = (BigInteger) obj; - } - else - { // assume byte[]. should be same length as cipher block size byte[] offset = (byte[]) obj; if (offset.length != cipherBlockSize) - { - throw new IllegalArgumentException(OFFSET); - } - + throw new IllegalArgumentException(OFFSET); r = new BigInteger(1, offset); } - int wantBlockNdxLength = -1; // number of octets in the block index Integer i = (Integer) attributes.get(BLOCK_INDEX_LENGTH); if (i != null) { wantBlockNdxLength = i.intValue(); if (wantBlockNdxLength < 1) - { - throw new IllegalArgumentException(BLOCK_INDEX_LENGTH); - } + throw new IllegalArgumentException(BLOCK_INDEX_LENGTH); } - int wantSegmentNdxLength = -1; // number of octets in the segment index i = (Integer) attributes.get(SEGMENT_INDEX_LENGTH); if (i != null) { wantSegmentNdxLength = i.intValue(); if (wantSegmentNdxLength < 1) - { - throw new IllegalArgumentException(SEGMENT_INDEX_LENGTH); - } + throw new IllegalArgumentException(SEGMENT_INDEX_LENGTH); } - // if both are undefined check if it's a reuse if ((wantBlockNdxLength == -1) && (wantSegmentNdxLength == -1)) { - if (blockNdxLength == -1) - { // new instance - throw new IllegalArgumentException(BLOCK_INDEX_LENGTH + ", " - + SEGMENT_INDEX_LENGTH); - } // else reuse old values + if (blockNdxLength == -1) // new instance + throw new IllegalArgumentException(BLOCK_INDEX_LENGTH + ", " + + SEGMENT_INDEX_LENGTH); + // else reuse old values } - else - { // only one is undefined, set it to BLOCK_LENGTH/2 minus the other + else // only one is undefined, set it to BLOCK_LENGTH/2 minus the other + { int limit = cipherBlockSize / 2; if (wantBlockNdxLength == -1) - { - wantBlockNdxLength = limit - wantSegmentNdxLength; - } + wantBlockNdxLength = limit - wantSegmentNdxLength; else if (wantSegmentNdxLength == -1) - { - wantSegmentNdxLength = limit - wantBlockNdxLength; - } + wantSegmentNdxLength = limit - wantBlockNdxLength; else if ((wantSegmentNdxLength + wantBlockNdxLength) > limit) - { - throw new IllegalArgumentException(BLOCK_INDEX_LENGTH + ", " - + SEGMENT_INDEX_LENGTH); - } + throw new IllegalArgumentException(BLOCK_INDEX_LENGTH + ", " + + SEGMENT_INDEX_LENGTH); // save new values blockNdxLength = wantBlockNdxLength; segmentNdxLength = wantSegmentNdxLength; } - // get the segment index as a BigInteger BigInteger s = (BigInteger) attributes.get(SEGMENT_INDEX); if (s == null) { - if (segmentNdx == null) - { // segment index was never set - throw new IllegalArgumentException(SEGMENT_INDEX); - } + if (segmentNdx == null) // segment index was never set + throw new IllegalArgumentException(SEGMENT_INDEX); // reuse; check if still valid if (segmentNdx.compareTo(TWO_FIFTY_SIX.pow(segmentNdxLength)) > 0) - { - throw new IllegalArgumentException(SEGMENT_INDEX); - } + throw new IllegalArgumentException(SEGMENT_INDEX); } else { if (s.compareTo(TWO_FIFTY_SIX.pow(segmentNdxLength)) > 0) - { - throw new IllegalArgumentException(SEGMENT_INDEX); - } + throw new IllegalArgumentException(SEGMENT_INDEX); segmentNdx = s; } - // The initial counter of the keystream segment with segment index s is // defined as follows, where r denotes the Offset: // // C[0] = (s * (256^BLOCK_INDEX_LENGTH) + r) modulo (256^BLOCK_LENGTH) - // - C0 = segmentNdx.multiply(TWO_FIFTY_SIX.pow(blockNdxLength)).add(r).modPow( - BigInteger.ONE, - counterRange); + C0 = segmentNdx.multiply(TWO_FIFTY_SIX.pow(blockNdxLength)) + .add(r).modPow(BigInteger.ONE, counterRange); } public void fillBlock() throws LimitReachedException { if (C0 == null) - { - throw new IllegalStateException(); - } + throw new IllegalStateException(); if (blockNdx.compareTo(TWO_FIFTY_SIX.pow(blockNdxLength)) >= 0) - { - throw new LimitReachedException(); - } - + throw new LimitReachedException(); int cipherBlockSize = cipher.currentBlockSize(); BigInteger counterRange = TWO_FIFTY_SIX.pow(cipherBlockSize); - // encrypt the counter for the current blockNdx // C[i] = (C[0] + i) modulo (256^BLOCK_LENGTH). - BigInteger Ci = C0.add(blockNdx).modPow(BigInteger.ONE, counterRange); buffer = Ci.toByteArray(); int limit = buffer.length; @@ -370,7 +291,6 @@ public class ICMGenerator extends BasePRNG implements Cloneable cipherBlockSize); buffer = data; } - cipher.encryptBlock(buffer, 0, buffer, 0); blockNdx = blockNdx.add(BigInteger.ONE); // increment blockNdx } diff --git a/gnu/javax/crypto/prng/PBKDF2.java b/gnu/javax/crypto/prng/PBKDF2.java index d39cd0a65..0f91d4add 100644 --- a/gnu/javax/crypto/prng/PBKDF2.java +++ b/gnu/javax/crypto/prng/PBKDF2.java @@ -49,51 +49,42 @@ import java.util.HashMap; import java.util.Map; /** - * <p>An implementation of the <i>key derivation function</i> KDF2 from PKCS #5: + * An implementation of the <i>key derivation function</i> KDF2 from PKCS #5: * Password-Based Cryptography (<b>PBE</b>). This KDF is essentially a way to * transform a password and a salt into a stream of random bytes, which may then - * be used to initialize a cipher or a MAC.</p> - * - * <p>This version uses a MAC as its pseudo-random function, and the password is - * used as the key.</p> - * - * <p>References:</p> + * be used to initialize a cipher or a MAC. + * <p> + * This version uses a MAC as its pseudo-random function, and the password is + * used as the key. + * <p> + * References: * <ol> - * <li>B. Kaliski, <a href="http://www.ietf.org/rfc/rfc2898.txt">RFC 2898: - * Password-Based Cryptography Specification, Version 2.0</a></li> + * <li>B. Kaliski, <a href="http://www.ietf.org/rfc/rfc2898.txt">RFC 2898: + * Password-Based Cryptography Specification, Version 2.0</a></li> * </ol> */ -public class PBKDF2 extends BasePRNG implements Cloneable +public class PBKDF2 + extends BasePRNG + implements Cloneable { - - // Contstants and variables - // ------------------------------------------------------------------------- - /** - * The bytes fed into the MAC. This is initially the concatenation of the - * salt and the block number. + * The bytes fed into the MAC. This is initially the concatenation of the salt + * and the block number. */ private byte[] in; - /** The iteration count. */ private int iterationCount; - /** The salt. */ private byte[] salt; - /** The MAC (the pseudo-random function we use). */ private IMac mac; - /** The number of hLen-sized blocks generated. */ private long count; - // Constructor(s) - // ------------------------------------------------------------------------- - /** - * <p>Creates a new PBKDF2 object. The argument is the MAC that will serve as - * the pseudo-random function. The MAC does not need to be initialized.</p> - * + * Creates a new PBKDF2 object. The argument is the MAC that will serve as the + * pseudo-random function. The MAC does not need to be initialized. + * * @param mac The pseudo-random function. */ public PBKDF2(IMac mac) @@ -103,30 +94,19 @@ public class PBKDF2 extends BasePRNG implements Cloneable iterationCount = -1; } - // Class methods - // ------------------------------------------------------------------------- - - // Instance methods - // ------------------------------------------------------------------------- - public void setup(Map attributes) { Map macAttrib = new HashMap(); macAttrib.put(HMac.USE_WITH_PKCS5_V2, Boolean.TRUE); - byte[] s = (byte[]) attributes.get(IPBE.SALT); if (s == null) { if (salt == null) - { - throw new IllegalArgumentException("no salt specified"); - } // Otherwise re-use. + throw new IllegalArgumentException("no salt specified"); + // Otherwise re-use. } else - { - salt = s; - } - + salt = s; byte[] macKeyMaterial; char[] password = (char[]) attributes.get(IPBE.PASSWORD); if (password != null) @@ -136,7 +116,6 @@ public class PBKDF2 extends BasePRNG implements Cloneable encoding = IPBE.DEFAULT_PASSWORD_ENCODING; else encoding = encoding.trim(); - try { macKeyMaterial = new String(password).getBytes(encoding); @@ -152,10 +131,10 @@ public class PBKDF2 extends BasePRNG implements Cloneable if (macKeyMaterial != null) macAttrib.put(IMac.MAC_KEY_MATERIAL, macKeyMaterial); - else if (!initialised) - throw new IllegalArgumentException("Neither password nor key-material were specified"); + else if (! initialised) + throw new IllegalArgumentException( + "Neither password nor key-material were specified"); // otherwise re-use previous password/key-material - try { mac.init(macAttrib); @@ -164,27 +143,19 @@ public class PBKDF2 extends BasePRNG implements Cloneable { throw new IllegalArgumentException(x.getMessage()); } - Integer ic = (Integer) attributes.get(IPBE.ITERATION_COUNT); if (ic != null) - { - iterationCount = ic.intValue(); - } + iterationCount = ic.intValue(); if (iterationCount <= 0) - { - throw new IllegalArgumentException("bad iteration count"); - } - + throw new IllegalArgumentException("bad iteration count"); count = 0L; buffer = new byte[mac.macSize()]; try { fillBlock(); - // } catch (Exception x) { } catch (LimitReachedException x) { - // x.printStackTrace(System.err); throw new Error(x.getMessage()); } } @@ -192,34 +163,22 @@ public class PBKDF2 extends BasePRNG implements Cloneable public void fillBlock() throws LimitReachedException { if (++count > ((1L << 32) - 1)) - { - throw new LimitReachedException(); - } - // for (int i = 0; i < buffer.length; i++) { - // buffer[i] = 0; - // } + throw new LimitReachedException(); Arrays.fill(buffer, (byte) 0x00); int limit = salt.length; - // in = new byte[salt.length + 4]; in = new byte[limit + 4]; System.arraycopy(salt, 0, in, 0, salt.length); - // in[salt.length ] = (byte)(count >>> 24); - // in[salt.length+1] = (byte)(count >>> 16); - // in[salt.length+2] = (byte)(count >>> 8); - // in[salt.length+3] = (byte) count; - in[limit++] = (byte) (count >>> 24); - in[limit++] = (byte) (count >>> 16); - in[limit++] = (byte) (count >>> 8); - in[limit] = (byte) count; + in[limit++] = (byte)(count >>> 24); + in[limit++] = (byte)(count >>> 16); + in[limit++] = (byte)(count >>> 8); + in[limit ] = (byte) count; for (int i = 0; i < iterationCount; i++) { mac.reset(); mac.update(in, 0, in.length); in = mac.digest(); for (int j = 0; j < buffer.length; j++) - { - buffer[j] ^= in[j]; - } + buffer[j] ^= in[j]; } } } diff --git a/gnu/javax/crypto/prng/PRNGFactory.java b/gnu/javax/crypto/prng/PRNGFactory.java index 9ff6558b0..ee75f8d8a 100644 --- a/gnu/javax/crypto/prng/PRNGFactory.java +++ b/gnu/javax/crypto/prng/PRNGFactory.java @@ -40,11 +40,9 @@ package gnu.javax.crypto.prng; import gnu.java.security.Registry; import gnu.java.security.prng.IRandom; - - +import gnu.javax.crypto.mac.HMacFactory; import gnu.javax.crypto.mac.IMac; import gnu.javax.crypto.mac.MacFactory; -import gnu.javax.crypto.mac.HMacFactory; import java.util.Collections; import java.util.HashSet; @@ -52,92 +50,66 @@ import java.util.Iterator; import java.util.Set; /** - * <p>A Factory to instantiate pseudo random number generators.</p> + * A Factory to instantiate pseudo random number generators. */ -public class PRNGFactory implements Registry +public class PRNGFactory + implements Registry { - - // Constants and variables - // ------------------------------------------------------------------------- - - // Constructor(s) - // ------------------------------------------------------------------------- - /** Trivial constructor to enforce <i>Singleton</i> pattern. */ private PRNGFactory() { } - // Class methods - // ------------------------------------------------------------------------- - /** - * <p>Returns an instance of a padding algorithm given its name.</p> - * + * Returns an instance of a padding algorithm given its name. + * * @param prng the case-insensitive name of the PRNG. * @return an instance of the pseudo-random number generator. * @exception InternalError if the implementation does not pass its self- - * test. + * test. */ public static IRandom getInstance(String prng) { if (prng == null) - { - return null; - } - + return null; prng = prng.trim(); IRandom result = null; if (prng.equalsIgnoreCase(ARCFOUR_PRNG) || prng.equalsIgnoreCase(RC4_PRNG)) - { - result = new ARCFour(); - } + result = new ARCFour(); else if (prng.equalsIgnoreCase(ICM_PRNG)) - { - result = new ICMGenerator(); - } + result = new ICMGenerator(); else if (prng.equalsIgnoreCase(UMAC_PRNG)) - { - result = new UMacGenerator(); - } + result = new UMacGenerator(); else if (prng.toLowerCase().startsWith(PBKDF2_PRNG_PREFIX)) { String macName = prng.substring(PBKDF2_PRNG_PREFIX.length()); IMac mac = MacFactory.getInstance(macName); if (mac == null) - { - return null; - } + return null; result = new PBKDF2(mac); } if (result != null) return result; - return gnu.java.security.prng.PRNGFactory.getInstance (prng); + return gnu.java.security.prng.PRNGFactory.getInstance(prng); } /** - * <p>Returns a {@link Set} of names of padding algorithms supported by this - * <i>Factory</i>.</p> - * + * Returns a {@link Set} of names of padding algorithms supported by this + * <i>Factory</i>. + * * @return a {@link Set} of pseudo-random number generator algorithm names - * (Strings). + * (Strings). */ public static Set getNames() { - HashSet hs = new HashSet (gnu.java.security.prng.PRNGFactory.getNames ()); + HashSet hs = new HashSet(gnu.java.security.prng.PRNGFactory.getNames()); hs.add(ICM_PRNG); hs.add(UMAC_PRNG); // add all hmac implementations as candidate PBKDF2 ones too for (Iterator it = HMacFactory.getNames().iterator(); it.hasNext();) - { - hs.add(PBKDF2_PRNG_PREFIX + ((String) it.next())); - } - + hs.add(PBKDF2_PRNG_PREFIX + ((String) it.next())); return Collections.unmodifiableSet(hs); } - - // Instance methods - // ------------------------------------------------------------------------- } diff --git a/gnu/javax/crypto/prng/UMacGenerator.java b/gnu/javax/crypto/prng/UMacGenerator.java index f7b7a16a0..39c99f73a 100644 --- a/gnu/javax/crypto/prng/UMacGenerator.java +++ b/gnu/javax/crypto/prng/UMacGenerator.java @@ -50,121 +50,90 @@ import java.util.Map; import java.security.InvalidKeyException; /** - * <p><i>KDF</i>s (Key Derivation Functions) are used to stretch user-supplied - * key material to specific size(s) required by high level cryptographic - * primitives. Described in the <A + * <i>KDF</i>s (Key Derivation Functions) are used to stretch user-supplied key + * material to specific size(s) required by high level cryptographic primitives. + * Described in the <A * HREF="http://www.ietf.org/internet-drafts/draft-krovetz-umac-01.txt">UMAC</A> * paper, this function basically operates an underlying <em>symmetric key block * cipher</em> instance in output feedback mode (OFB), as a <b>strong</b> - * pseudo-random number generator.</p> - * - * <p><code>UMacGenerator</code> requires an <em>index</em> parameter + * pseudo-random number generator. + * <p> + * <code>UMacGenerator</code> requires an <em>index</em> parameter * (initialisation parameter <code>gnu.crypto.prng.umac.kdf.index</code> taken - * to be an instance of {@link java.lang.Integer} with a value between - * <code>0</code> and <code>255</code>). Using the same key, but different - * indices, generates different pseudorandom outputs.</p> - * - * <p>This implementation generalises the definition of the - * <code>UmacGenerator</code> algorithm to allow for other than the AES symetric - * key block cipher algorithm (initialisation parameter + * to be an instance of {@link Integer} with a value between <code>0</code> and + * <code>255</code>). Using the same key, but different indices, generates + * different pseudorandom outputs. + * <p> + * This implementation generalises the definition of the + * <code>UmacGenerator</code> algorithm to allow for other than the AES + * symetric key block cipher algorithm (initialisation parameter * <code>gnu.crypto.prng.umac.cipher.name</code> taken to be an instance of - * {@link java.lang.String}). If such a parameter is not defined/included in the + * {@link String}). If such a parameter is not defined/included in the * initialisation <code>Map</code>, then the "Rijndael" algorithm is used. * Furthermore, if the initialisation parameter - * <code>gnu.crypto.cipher.block.size</code> (taken to be a instance of {@link - * java.lang.Integer}) is missing or undefined in the initialisation <code>Map - * </code>, then the cipher's <em>default</em> block size is used.</p> - * - * <p><b>NOTE</b>: Rijndael is used as the default symmetric key block cipher + * <code>gnu.crypto.cipher.block.size</code> (taken to be a instance of + * {@link Integer}) is missing or undefined in the initialisation + * <code>Map</code>, then the cipher's <em>default</em> block size is used. + * <p> + * <b>NOTE</b>: Rijndael is used as the default symmetric key block cipher * algorithm because, with its default block and key sizes, it is the AES. Yet * being Rijndael, the algorithm offers more versatile block and key sizes which - * may prove to be useful for generating "longer" key streams.</p> - * - * <p>References:</p> - * + * may prove to be useful for generating "longer" key streams. + * <p> + * References: * <ol> - * <li><a href="http://www.ietf.org/internet-drafts/draft-krovetz-umac-01.txt"> - * UMAC</a>: Message Authentication Code using Universal Hashing.<br> - * T. Krovetz, J. Black, S. Halevi, A. Hevia, H. Krawczyk, and P. Rogaway.</li> + * <li><a href="http://www.ietf.org/internet-drafts/draft-krovetz-umac-01.txt"> + * UMAC</a>: Message Authentication Code using Universal Hashing.<br> + * T. Krovetz, J. Black, S. Halevi, A. Hevia, H. Krawczyk, and P. Rogaway.</li> * </ol> */ -public class UMacGenerator extends BasePRNG implements Cloneable +public class UMacGenerator + extends BasePRNG + implements Cloneable { - - // Constants and variables - // ------------------------------------------------------------------------- - /** - * <p>Property name of the KDF <code>index</code> value to use in this + * Property name of the KDF <code>index</code> value to use in this * instance. The value is taken to be an {@link Integer} less than - * <code>256</code>.</p> + * <code>256</code>. */ public static final String INDEX = "gnu.crypto.prng.umac.index"; - /** The name of the underlying symmetric key block cipher algorithm. */ public static final String CIPHER = "gnu.crypto.prng.umac.cipher.name"; - /** The generator's underlying block cipher. */ private IBlockCipher cipher; - // Constructor(s) - // ------------------------------------------------------------------------- - /** Trivial 0-arguments constructor. */ public UMacGenerator() { super(Registry.UMAC_PRNG); } - // Class methods - // ------------------------------------------------------------------------- - - // Instance methods - // ------------------------------------------------------------------------- - - // Implementation of abstract methods in BasePRNG -------------------------- - public void setup(Map attributes) { boolean newCipher = true; String cipherName = (String) attributes.get(CIPHER); if (cipherName == null) - { - if (cipher == null) - { // happy birthday - cipher = CipherFactory.getInstance(Registry.RIJNDAEL_CIPHER); - } - else - { // we already have one. use it as is - newCipher = false; - } - } + if (cipher == null) // happy birthday + cipher = CipherFactory.getInstance(Registry.RIJNDAEL_CIPHER); + else // we already have one. use it as is + newCipher = false; else - { - cipher = CipherFactory.getInstance(cipherName); - } - + cipher = CipherFactory.getInstance(cipherName); // find out what block size we should use it in int cipherBlockSize = 0; Integer bs = (Integer) attributes.get(IBlockCipher.CIPHER_BLOCK_SIZE); if (bs != null) - { - cipherBlockSize = bs.intValue(); - } + cipherBlockSize = bs.intValue(); else { - if (newCipher) - { // assume we'll use its default block size - cipherBlockSize = cipher.defaultBlockSize(); - } // else use as is + if (newCipher) // assume we'll use its default block size + cipherBlockSize = cipher.defaultBlockSize(); + // else use as is } - // get the key material byte[] key = (byte[]) attributes.get(IBlockCipher.KEY_MATERIAL); if (key == null) - { - throw new IllegalArgumentException(IBlockCipher.KEY_MATERIAL); - } + throw new IllegalArgumentException(IBlockCipher.KEY_MATERIAL); int keyLength = key.length; // ensure that keyLength is valid for the chosen underlying cipher @@ -173,15 +142,10 @@ public class UMacGenerator extends BasePRNG implements Cloneable { ok = (keyLength == ((Integer) it.next()).intValue()); if (ok) - { - break; - } + break; } - if (!ok) - { - throw new IllegalArgumentException("key length"); - } - + if (! ok) + throw new IllegalArgumentException("key length"); // ensure that remaining params make sense int index = -1; Integer i = (Integer) attributes.get(INDEX); @@ -189,17 +153,12 @@ public class UMacGenerator extends BasePRNG implements Cloneable { index = i.intValue(); if (index < 0 || index > 255) - { - throw new IllegalArgumentException(INDEX); - } + throw new IllegalArgumentException(INDEX); } - // now initialise the underlying cipher Map map = new HashMap(); - if (cipherBlockSize != 0) - { // only needed if new or changed - map.put(IBlockCipher.CIPHER_BLOCK_SIZE, Integer.valueOf(cipherBlockSize)); - } + if (cipherBlockSize != 0) // only needed if new or changed + map.put(IBlockCipher.CIPHER_BLOCK_SIZE, Integer.valueOf(cipherBlockSize)); map.put(IBlockCipher.KEY_MATERIAL, key); try { @@ -209,7 +168,6 @@ public class UMacGenerator extends BasePRNG implements Cloneable { throw new IllegalArgumentException(IBlockCipher.KEY_MATERIAL); } - buffer = new byte[cipher.currentBlockSize()]; buffer[cipher.currentBlockSize() - 1] = (byte) index; try @@ -225,4 +183,4 @@ public class UMacGenerator extends BasePRNG implements Cloneable { cipher.encryptBlock(buffer, 0, buffer, 0); } -}
\ No newline at end of file +} |