summaryrefslogtreecommitdiffstats
path: root/libjava/classpath/gnu/javax/crypto/jce/prng
diff options
context:
space:
mode:
authormark <mark@138bc75d-0d04-0410-961f-82ee72b054a4>2006-03-10 21:46:48 +0000
committermark <mark@138bc75d-0d04-0410-961f-82ee72b054a4>2006-03-10 21:46:48 +0000
commitce57ab760f69de6db452def7ffbf5b114a2d8694 (patch)
treeea38c56431c5d4528fb54254c3f8e50f517bede3 /libjava/classpath/gnu/javax/crypto/jce/prng
parent50996fe55769882de3f410896032c887f0ff0d04 (diff)
downloadppe42-gcc-ce57ab760f69de6db452def7ffbf5b114a2d8694.tar.gz
ppe42-gcc-ce57ab760f69de6db452def7ffbf5b114a2d8694.zip
Imported GNU Classpath 0.90
* scripts/makemake.tcl: Set gnu/java/awt/peer/swing to ignore. * gnu/classpath/jdwp/VMFrame.java (SIZE): New constant. * java/lang/VMCompiler.java: Use gnu.java.security.hash.MD5. * java/lang/Math.java: New override file. * java/lang/Character.java: Merged from Classpath. (start, end): Now 'int's. (canonicalName): New field. (CANONICAL_NAME, NO_SPACES_NAME, CONSTANT_NAME): New constants. (UnicodeBlock): Added argument. (of): New overload. (forName): New method. Updated unicode blocks. (sets): Updated. * sources.am: Regenerated. * Makefile.in: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@111942 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/classpath/gnu/javax/crypto/jce/prng')
-rw-r--r--libjava/classpath/gnu/javax/crypto/jce/prng/ARCFourRandomSpi.java120
-rw-r--r--libjava/classpath/gnu/javax/crypto/jce/prng/CSPRNGSpi.java114
-rw-r--r--libjava/classpath/gnu/javax/crypto/jce/prng/FortunaImpl.java85
-rw-r--r--libjava/classpath/gnu/javax/crypto/jce/prng/ICMRandomSpi.java260
-rw-r--r--libjava/classpath/gnu/javax/crypto/jce/prng/UMacRandomSpi.java207
5 files changed, 786 insertions, 0 deletions
diff --git a/libjava/classpath/gnu/javax/crypto/jce/prng/ARCFourRandomSpi.java b/libjava/classpath/gnu/javax/crypto/jce/prng/ARCFourRandomSpi.java
new file mode 100644
index 00000000000..0c071561b6f
--- /dev/null
+++ b/libjava/classpath/gnu/javax/crypto/jce/prng/ARCFourRandomSpi.java
@@ -0,0 +1,120 @@
+/* ARCFourRandomSpi.java --
+ Copyright (C) 2002, 2003, 2006 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.crypto.jce.prng;
+
+import gnu.java.security.Registry;
+import gnu.javax.crypto.prng.ARCFour;
+import gnu.java.security.prng.IRandom;
+import gnu.java.security.prng.LimitReachedException;
+import gnu.javax.crypto.prng.PRNGFactory;
+
+import java.security.SecureRandomSpi;
+import java.util.HashMap;
+
+/**
+ * Implementation of the <i>Service Provider Interface</i> (<b>SPI</b>)
+ * for the ARCFOUR keystream generator.
+ */
+public class ARCFourRandomSpi extends SecureRandomSpi
+{
+
+ // Constants and variables
+ // -------------------------------------------------------------------------
+
+ /** Our underlying prng instance. */
+ private IRandom adaptee;
+
+ /** Have we been initialized? */
+ private boolean virgin;
+
+ // Constructor(s)
+ // -------------------------------------------------------------------------
+
+ /**
+ * Default 0-arguments constructor.
+ */
+ public ARCFourRandomSpi()
+ {
+ super();
+ adaptee = PRNGFactory.getInstance(Registry.ARCFOUR_PRNG);
+ virgin = true;
+ }
+
+ // Class methods
+ // -------------------------------------------------------------------------
+
+ // Instance methods
+ // -------------------------------------------------------------------------
+
+ // java.security.SecureRandomSpi interface implementation ------------------
+
+ public byte[] engineGenerateSeed(int numBytes)
+ {
+ if (numBytes < 1)
+ {
+ return new byte[0];
+ }
+ byte[] result = new byte[numBytes];
+ this.engineNextBytes(result);
+ return result;
+ }
+
+ public void engineNextBytes(byte[] bytes)
+ {
+ if (virgin)
+ {
+ this.engineSetSeed(new byte[0]);
+ }
+ try
+ {
+ adaptee.nextBytes(bytes, 0, bytes.length);
+ }
+ catch (LimitReachedException ignored)
+ {
+ }
+ }
+
+ public void engineSetSeed(byte[] seed)
+ {
+ HashMap attributes = new HashMap();
+ attributes.put(ARCFour.ARCFOUR_KEY_MATERIAL, seed);
+ adaptee.init(attributes);
+ virgin = false;
+ }
+} \ No newline at end of file
diff --git a/libjava/classpath/gnu/javax/crypto/jce/prng/CSPRNGSpi.java b/libjava/classpath/gnu/javax/crypto/jce/prng/CSPRNGSpi.java
new file mode 100644
index 00000000000..c0aa015b065
--- /dev/null
+++ b/libjava/classpath/gnu/javax/crypto/jce/prng/CSPRNGSpi.java
@@ -0,0 +1,114 @@
+/* CSPRNGSpi.java --
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.crypto.jce.prng;
+
+import gnu.java.security.Registry;
+import gnu.javax.crypto.prng.CSPRNG;
+import gnu.java.security.prng.IRandom;
+import gnu.java.security.prng.LimitReachedException;
+
+import java.net.MalformedURLException;
+import java.security.SecureRandomSpi;
+
+/**
+ * The implementation of the continuously-seeded SecureRandom
+ * <i>Service Provider Interface</i> (<b>SPI</b>) adapter.<p>
+ */
+public class CSPRNGSpi extends SecureRandomSpi
+{
+
+ // Constants and variables
+ // -------------------------------------------------------------------------
+
+ private final IRandom adaptee;
+
+ // Constructor(s)
+ // -------------------------------------------------------------------------
+
+ public CSPRNGSpi() throws ClassNotFoundException, MalformedURLException,
+ NumberFormatException
+ {
+ super();
+
+ adaptee = CSPRNG.getSystemInstance();
+ }
+
+ // Instance methods
+ // -------------------------------------------------------------------------
+
+ protected byte[] engineGenerateSeed(final int count)
+ {
+ if (count < 0)
+ {
+ throw new IllegalArgumentException("count must be nonnegative");
+ }
+ byte[] buf = new byte[count];
+ if (count == 0)
+ {
+ return buf;
+ }
+ engineNextBytes(buf);
+ return buf;
+ }
+
+ protected void engineNextBytes(final byte[] buffer)
+ {
+ if (buffer == null)
+ {
+ throw new NullPointerException();
+ }
+ try
+ {
+ adaptee.nextBytes(buffer, 0, buffer.length);
+ }
+ catch (LimitReachedException lre)
+ {
+ throw new RuntimeException("random-number generator has been exhausted");
+ }
+ }
+
+ protected void engineSetSeed(final byte[] seed)
+ {
+ if (seed == null)
+ {
+ throw new NullPointerException();
+ }
+ adaptee.addRandomBytes(seed, 0, seed.length);
+ }
+} \ No newline at end of file
diff --git a/libjava/classpath/gnu/javax/crypto/jce/prng/FortunaImpl.java b/libjava/classpath/gnu/javax/crypto/jce/prng/FortunaImpl.java
new file mode 100644
index 00000000000..7006bbbaddc
--- /dev/null
+++ b/libjava/classpath/gnu/javax/crypto/jce/prng/FortunaImpl.java
@@ -0,0 +1,85 @@
+/* FortunaImpl.java -- Fortuna SecureRandom adapter.
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.crypto.jce.prng;
+
+import gnu.java.security.prng.LimitReachedException;
+import gnu.javax.crypto.prng.Fortuna;
+import java.security.SecureRandomSpi;
+import java.util.Collections;
+
+public final class FortunaImpl extends SecureRandomSpi
+{
+ private final Fortuna adaptee;
+
+ public FortunaImpl ()
+ {
+ adaptee = new Fortuna ();
+ adaptee.init (Collections.singletonMap (Fortuna.SEED, new byte[0]));
+ }
+
+ protected void engineSetSeed (byte[] seed)
+ {
+ synchronized (adaptee)
+ {
+ adaptee.addRandomBytes (seed);
+ }
+ }
+
+ protected void engineNextBytes(byte[] buffer)
+ {
+ synchronized (adaptee)
+ {
+ try
+ {
+ adaptee.nextBytes (buffer);
+ }
+ catch (LimitReachedException shouldNotHappen)
+ {
+ throw new Error (shouldNotHappen);
+ }
+ }
+ }
+
+ protected byte[] engineGenerateSeed (int numbytes)
+ {
+ byte[] seed = new byte[numbytes];
+ engineNextBytes (seed);
+ return seed;
+ }
+} \ No newline at end of file
diff --git a/libjava/classpath/gnu/javax/crypto/jce/prng/ICMRandomSpi.java b/libjava/classpath/gnu/javax/crypto/jce/prng/ICMRandomSpi.java
new file mode 100644
index 00000000000..d04b782f9f5
--- /dev/null
+++ b/libjava/classpath/gnu/javax/crypto/jce/prng/ICMRandomSpi.java
@@ -0,0 +1,260 @@
+/* ICMRandomSpi.java --
+ Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.crypto.jce.prng;
+
+import gnu.java.security.Registry;
+import gnu.javax.crypto.cipher.IBlockCipher;
+import gnu.javax.crypto.prng.ICMGenerator;
+import gnu.java.security.prng.LimitReachedException;
+
+import java.io.PrintWriter;
+import java.math.BigInteger;
+import java.security.SecureRandomSpi;
+import java.util.HashMap;
+import java.util.Random;
+
+/**
+ * <p>An <em>Adapter</em> class around {@link ICMGenerator} to allow using this
+ * algorithm as a JCE {@link java.security.SecureRandom}.</p>
+ */
+public class ICMRandomSpi extends SecureRandomSpi
+{
+
+ // Debugging methods and variables
+ // -------------------------------------------------------------------------
+
+ private static final String NAME = "ICMRandomSpi";
+
+ private static final boolean DEBUG = false;
+
+ private static final int debuglevel = 0;
+
+ private static final PrintWriter err = new PrintWriter(System.out, true);
+
+ private static void debug(String s)
+ {
+ err.println(">>> " + NAME + ": " + s);
+ }
+
+ // Constants and variables
+ // -------------------------------------------------------------------------
+
+ /** Class-wide prng to generate random material for the underlying prng.*/
+ private static final ICMGenerator prng; // blank final
+ static
+ {
+ prng = new ICMGenerator();
+ resetLocalPRNG();
+ }
+
+ // error messages
+ private static final String MSG = "Exception while setting up an "
+ + Registry.ICM_PRNG + " SPI: ";
+
+ private static final String RETRY = "Retry...";
+
+ private static final String LIMIT_REACHED_MSG = "Limit reached: ";
+
+ private static final String RESEED = "Re-seed...";
+
+ /** Our underlying prng instance. */
+ private ICMGenerator adaptee = new ICMGenerator();
+
+ // Constructor(s)
+ // -------------------------------------------------------------------------
+
+ // default 0-arguments constructor
+
+ // Class methods
+ // -------------------------------------------------------------------------
+
+ private static void resetLocalPRNG()
+ {
+ if (DEBUG && debuglevel > 8)
+ debug(">>> resetLocalPRNG()");
+ HashMap attributes = new HashMap();
+ attributes.put(ICMGenerator.CIPHER, Registry.AES_CIPHER);
+ byte[] key = new byte[128 / 8]; // AES default key size
+ Random rand = new Random(System.currentTimeMillis());
+ rand.nextBytes(key);
+ attributes.put(IBlockCipher.KEY_MATERIAL, key);
+ int aesBlockSize = 128 / 8; // AES block size in bytes
+ byte[] offset = new byte[aesBlockSize];
+ rand.nextBytes(offset);
+ attributes.put(ICMGenerator.OFFSET, offset);
+ int ndxLen = 0; // the segment length
+ // choose a random value between 1 and aesBlockSize / 2
+ int limit = aesBlockSize / 2;
+ while (ndxLen < 1 || ndxLen > limit)
+ {
+ ndxLen = rand.nextInt(limit + 1);
+ }
+ attributes.put(ICMGenerator.SEGMENT_INDEX_LENGTH, new Integer(ndxLen));
+ byte[] index = new byte[ndxLen];
+ rand.nextBytes(index);
+ attributes.put(ICMGenerator.SEGMENT_INDEX, new BigInteger(1, index));
+
+ prng.setup(attributes);
+ if (DEBUG && debuglevel > 8)
+ debug("<<< resetLocalPRNG()");
+ }
+
+ // Instance methods
+ // -------------------------------------------------------------------------
+
+ // java.security.SecureRandomSpi interface implementation ------------------
+
+ public byte[] engineGenerateSeed(int numBytes)
+ {
+ if (DEBUG && debuglevel > 8)
+ debug(">>> engineGenerateSeed()");
+ if (numBytes < 1)
+ {
+ if (DEBUG && debuglevel > 8)
+ debug("<<< engineGenerateSeed()");
+ return new byte[0];
+ }
+ byte[] result = new byte[numBytes];
+ this.engineNextBytes(result);
+ if (DEBUG && debuglevel > 8)
+ debug("<<< engineGenerateSeed()");
+ return result;
+ }
+
+ public void engineNextBytes(byte[] bytes)
+ {
+ if (DEBUG && debuglevel > 8)
+ debug(">>> engineNextBytes()");
+ if (!adaptee.isInitialised())
+ {
+ this.engineSetSeed(new byte[0]);
+ }
+
+ while (true)
+ {
+ try
+ {
+ adaptee.nextBytes(bytes, 0, bytes.length);
+ break;
+ }
+ catch (LimitReachedException x)
+ { // reseed the generator
+ if (DEBUG)
+ {
+ debug(LIMIT_REACHED_MSG + String.valueOf(x));
+ x.printStackTrace(err);
+ debug(RESEED);
+ }
+ resetLocalPRNG();
+ }
+ }
+ if (DEBUG && debuglevel > 8)
+ debug("<<< engineNextBytes()");
+ }
+
+ public void engineSetSeed(byte[] seed)
+ {
+ if (DEBUG && debuglevel > 8)
+ debug(">>> engineSetSeed()");
+ // compute the total number of random bytes required to setup adaptee
+ int materialLength = 0;
+ materialLength += 16; // key material size
+ materialLength += 16; // offset size
+ materialLength += 8; // index size == half of an AES block
+ byte[] material = new byte[materialLength];
+
+ // use as much as possible bytes from the seed
+ int materialOffset = 0;
+ int materialLeft = material.length;
+ if (seed.length > 0)
+ { // copy some bytes into key and update indices
+ int lenToCopy = Math.min(materialLength, seed.length);
+ System.arraycopy(seed, 0, material, 0, lenToCopy);
+ materialOffset += lenToCopy;
+ materialLeft -= lenToCopy;
+ }
+ if (materialOffset > 0)
+ { // generate the rest
+ while (true)
+ {
+ try
+ {
+ prng.nextBytes(material, materialOffset, materialLeft);
+ break;
+ }
+ catch (IllegalStateException x)
+ { // should not happen
+ throw new InternalError(MSG + String.valueOf(x));
+ }
+ catch (LimitReachedException x)
+ {
+ if (DEBUG)
+ {
+ debug(MSG + String.valueOf(x));
+ debug(RETRY);
+ }
+ }
+ }
+ }
+
+ // setup the underlying adaptee instance
+ HashMap attributes = new HashMap();
+
+ // use AES cipher with 128-bit block size
+ attributes.put(ICMGenerator.CIPHER, Registry.AES_CIPHER);
+ // use an index the size of quarter of an AES block
+ attributes.put(ICMGenerator.SEGMENT_INDEX_LENGTH, new Integer(4));
+ // specify the key
+ byte[] key = new byte[16];
+ System.arraycopy(material, 0, key, 0, 16);
+ attributes.put(IBlockCipher.KEY_MATERIAL, key);
+ // specify the offset
+ byte[] offset = new byte[16];
+ System.arraycopy(material, 16, offset, 0, 16);
+ attributes.put(ICMGenerator.OFFSET, offset);
+ // specify the index
+ byte[] index = new byte[8];
+ System.arraycopy(material, 32, index, 0, 8);
+ attributes.put(ICMGenerator.SEGMENT_INDEX, new BigInteger(1, index));
+
+ adaptee.init(attributes);
+ if (DEBUG && debuglevel > 8)
+ debug("<<< engineSetSeed()");
+ }
+} \ No newline at end of file
diff --git a/libjava/classpath/gnu/javax/crypto/jce/prng/UMacRandomSpi.java b/libjava/classpath/gnu/javax/crypto/jce/prng/UMacRandomSpi.java
new file mode 100644
index 00000000000..7dad68b2f95
--- /dev/null
+++ b/libjava/classpath/gnu/javax/crypto/jce/prng/UMacRandomSpi.java
@@ -0,0 +1,207 @@
+/* UMacRandomSpi.java --
+ Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc.
+
+This file is a part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+USA
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package gnu.javax.crypto.jce.prng;
+
+import gnu.java.security.Registry;
+import gnu.javax.crypto.cipher.IBlockCipher;
+import gnu.java.security.prng.LimitReachedException;
+import gnu.javax.crypto.prng.UMacGenerator;
+
+import java.io.PrintWriter;
+import java.security.SecureRandomSpi;
+import java.util.HashMap;
+import java.util.Random;
+
+/**
+ * <p>An <em>Adapter</em> class around {@link UMacGenerator} to allow using this
+ * algorithm as a JCE {@link java.security.SecureRandom}.</p>
+ */
+public class UMacRandomSpi extends SecureRandomSpi
+{
+
+ // Debugging methods and variables
+ // -------------------------------------------------------------------------
+
+ private static final String NAME = "UMacRandomSpi";
+
+ private static final boolean DEBUG = false;
+
+ private static final PrintWriter err = new PrintWriter(System.out, true);
+
+ private static void debug(String s)
+ {
+ err.println(">>> " + NAME + ": " + s);
+ }
+
+ // Constants and variables
+ // -------------------------------------------------------------------------
+
+ /** Class-wide prng to generate random material for the underlying prng.*/
+ private static final UMacGenerator prng; // blank final
+ static
+ {
+ prng = new UMacGenerator();
+ resetLocalPRNG();
+ }
+
+ // error messages
+ private static final String MSG = "Exception while setting up a "
+ + Registry.UMAC_PRNG + " SPI: ";
+
+ private static final String RETRY = "Retry...";
+
+ /** Our underlying prng instance. */
+ private UMacGenerator adaptee = new UMacGenerator();
+
+ // Constructor(s)
+ // -------------------------------------------------------------------------
+
+ // default 0-arguments constructor
+
+ // Class methods
+ // -------------------------------------------------------------------------
+
+ private static void resetLocalPRNG()
+ {
+ HashMap attributes = new HashMap();
+ attributes.put(UMacGenerator.CIPHER, Registry.AES_CIPHER);
+ byte[] key = new byte[128 / 8]; // AES default key size
+ Random rand = new Random(System.currentTimeMillis());
+ rand.nextBytes(key);
+ attributes.put(IBlockCipher.KEY_MATERIAL, key);
+ int index = rand.nextInt() & 0xFF;
+ attributes.put(UMacGenerator.INDEX, new Integer(index));
+
+ prng.setup(attributes);
+ }
+
+ // Instance methods
+ // -------------------------------------------------------------------------
+
+ // java.security.SecureRandomSpi interface implementation ------------------
+
+ public byte[] engineGenerateSeed(int numBytes)
+ {
+ if (numBytes < 1)
+ {
+ return new byte[0];
+ }
+ byte[] result = new byte[numBytes];
+ this.engineNextBytes(result);
+ return result;
+ }
+
+ public void engineNextBytes(byte[] bytes)
+ {
+ if (!adaptee.isInitialised())
+ {
+ this.engineSetSeed(new byte[0]);
+ }
+
+ while (true)
+ {
+ try
+ {
+ adaptee.nextBytes(bytes, 0, bytes.length);
+ break;
+ }
+ catch (LimitReachedException x)
+ { // reseed the generator
+ resetLocalPRNG();
+ }
+ }
+ }
+
+ public void engineSetSeed(byte[] seed)
+ {
+ // compute the total number of random bytes required to setup adaptee
+ int materialLength = 0;
+ materialLength += 16; // key material size
+ materialLength++; // index size
+ byte[] material = new byte[materialLength];
+
+ // use as much as possible bytes from the seed
+ int materialOffset = 0;
+ int materialLeft = material.length;
+ if (seed.length > 0)
+ { // copy some bytes into key and update indices
+ int lenToCopy = Math.min(materialLength, seed.length);
+ System.arraycopy(seed, 0, material, 0, lenToCopy);
+ materialOffset += lenToCopy;
+ materialLeft -= lenToCopy;
+ }
+ if (materialOffset > 0)
+ { // generate the rest
+ while (true)
+ {
+ try
+ {
+ prng.nextBytes(material, materialOffset, materialLeft);
+ break;
+ }
+ catch (IllegalStateException x)
+ { // should not happen
+ throw new InternalError(MSG + String.valueOf(x));
+ }
+ catch (LimitReachedException x)
+ {
+ if (DEBUG)
+ {
+ debug(MSG + String.valueOf(x));
+ debug(RETRY);
+ }
+ }
+ }
+ }
+
+ // setup the underlying adaptee instance
+ HashMap attributes = new HashMap();
+
+ // use AES cipher with 128-bit block size
+ attributes.put(UMacGenerator.CIPHER, Registry.AES_CIPHER);
+ // specify the key
+ byte[] key = new byte[16];
+ System.arraycopy(material, 0, key, 0, 16);
+ attributes.put(IBlockCipher.KEY_MATERIAL, key);
+ // use a 1-byte index
+ attributes.put(UMacGenerator.INDEX, new Integer(material[16] & 0xFF));
+
+ adaptee.init(attributes);
+ }
+} \ No newline at end of file
OpenPOWER on IntegriCloud