summaryrefslogtreecommitdiff
path: root/gnu/javax/crypto/mac/UMac32.java
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/javax/crypto/mac/UMac32.java')
-rw-r--r--gnu/javax/crypto/mac/UMac32.java287
1 files changed, 107 insertions, 180 deletions
diff --git a/gnu/javax/crypto/mac/UMac32.java b/gnu/javax/crypto/mac/UMac32.java
index 013888856..8e913db71 100644
--- a/gnu/javax/crypto/mac/UMac32.java
+++ b/gnu/javax/crypto/mac/UMac32.java
@@ -53,123 +53,105 @@ import java.util.HashMap;
import java.util.Map;
/**
- * <p>The implementation of the <i>UMAC</i> (Universal Message Authentication
- * Code).</p>
- *
- * <p>The <i>UMAC</i> algorithms described are <i>parameterized</i>. This means
+ * The implementation of the <i>UMAC</i> (Universal Message Authentication
+ * Code).
+ * <p>
+ * The <i>UMAC</i> algorithms described are <i>parameterized</i>. This means
* that various low-level choices, like the endian convention and the underlying
* cryptographic primitive, have not been fixed. One must choose values for
* these parameters before the authentication tag generated by <i>UMAC</i> (for
- * a given message, key, and nonce) becomes fully-defined. In this document
- * we provide two collections of parameter settings, and have named the sets
- * <i>UMAC16</i> and <i>UMAC32</i>. The parameter sets have been chosen based on
- * experimentation and provide good performance on a wide variety of processors.
- * <i>UMAC16</i> is designed to excel on processors which provide small-scale
- * SIMD parallelism of the type found in Intel's MMX and Motorola's AltiVec
- * instruction sets, while <i>UMAC32</i> is designed to do well on processors
- * with good 32- and 64- bit support. <i>UMAC32</i> may take advantage of SIMD
- * parallelism in future processors.</p>
- *
- * <p><i>UMAC</i> has been designed to allow implementations which accommodate
- * <i>on-line</i> authentication. This means that pieces of the message may
- * be presented to <i>UMAC</i> at different times (but in correct order) and an
+ * a given message, key, and nonce) becomes fully-defined. In this document we
+ * provide two collections of parameter settings, and have named the sets
+ * <i>UMAC16</i> and <i>UMAC32</i>. The parameter sets have been chosen based
+ * on experimentation and provide good performance on a wide variety of
+ * processors. <i>UMAC16</i> is designed to excel on processors which provide
+ * small-scale SIMD parallelism of the type found in Intel's MMX and Motorola's
+ * AltiVec instruction sets, while <i>UMAC32</i> is designed to do well on
+ * processors with good 32- and 64- bit support. <i>UMAC32</i> may take
+ * advantage of SIMD parallelism in future processors.
+ * <p>
+ * <i>UMAC</i> has been designed to allow implementations which accommodate
+ * <i>on-line</i> authentication. This means that pieces of the message may be
+ * presented to <i>UMAC</i> at different times (but in correct order) and an
* on-line implementation will be able to process the message correctly without
* the need to buffer more than a few dozen bytes of the message. For
* simplicity, the algorithms in this specification are presented as if the
- * entire message being authenticated were available at once.</p>
- *
- * <p>To authenticate a message, <code>Msg</code>, one first applies the
+ * entire message being authenticated were available at once.
+ * <p>
+ * To authenticate a message, <code>Msg</code>, one first applies the
* universal hash function, resulting in a string which is typically much
- * shorter than the original message. The pseudorandom function is applied to a
+ * shorter than the original message. The pseudorandom function is applied to a
* nonce, and the result is used in the manner of a Vernam cipher: the
* authentication tag is the xor of the output from the hash function and the
* output from the pseudorandom function. Thus, an authentication tag is
- * generated as</p>
- *
+ * generated as
* <pre>
- * AuthTag = f(Nonce) xor h(Msg)
+ * AuthTag = f(Nonce) xor h(Msg)
* </pre>
- *
- * <p>Here <code>f</code> is the pseudorandom function shared between the sender
+ * <p>
+ * Here <code>f</code> is the pseudorandom function shared between the sender
* and the receiver, and h is a universal hash function shared by the sender and
* the receiver. In <i>UMAC</i>, a shared key is used to key the pseudorandom
* function <code>f</code>, and then <code>f</code> is used for both tag
* generation and internally to generate all of the bits needed by the universal
- * hash function.</p>
- *
- * <p>The universal hash function that we use is called <code>UHASH</code>. It
+ * hash function.
+ * <p>
+ * The universal hash function that we use is called <code>UHASH</code>. It
* combines several software-optimized algorithms into a multi-layered
* structure. The algorithm is moderately complex. Some of this complexity comes
- * from extensive speed optimizations.</p>
- *
- * <p>For the pseudorandom function we use the block cipher of the <i>Advanced
- * Encryption Standard</i> (AES).</p>
- *
- * <p>The UMAC32 parameters, considered in this implementation are:</p>
+ * from extensive speed optimizations.
+ * <p>
+ * For the pseudorandom function we use the block cipher of the <i>Advanced
+ * Encryption Standard</i> (AES).
+ * <p>
+ * The UMAC32 parameters, considered in this implementation are:
* <pre>
- * UMAC32
- * ------
- * WORD-LEN 4
- * UMAC-OUTPUT-LEN 8
- * L1-KEY-LEN 1024
- * UMAC-KEY-LEN 16
- * ENDIAN-FAVORITE BIG *
- * L1-OPERATIONS-SIGN UNSIGNED
+ * UMAC32
+ * ------
+ * WORD-LEN 4
+ * UMAC-OUTPUT-LEN 8
+ * L1-KEY-LEN 1024
+ * UMAC-KEY-LEN 16
+ * ENDIAN-FAVORITE BIG *
+ * L1-OPERATIONS-SIGN UNSIGNED
* </pre>
- *
- * <p>Please note that this UMAC32 differs from the one described in the paper
- * by the <i>ENDIAN-FAVORITE</i> value.</p>
- *
- * <p>References:</p>
- *
+ * <p>
+ * Please note that this UMAC32 differs from the one described in the paper by
+ * the <i>ENDIAN-FAVORITE</i> value.
+ * <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 UMac32 extends BaseMac
+public class UMac32
+ extends BaseMac
{
-
- // Constants and variables
- // -------------------------------------------------------------------------
-
/**
* Property name of the user-supplied <i>Nonce</i>. The value associated to
* this property name is taken to be a byte array.
*/
public static final String NONCE_MATERIAL = "gnu.crypto.umac.nonce.material";
-
/** Known test vector. */
- // private static final String TV1 = "3E5A0E09198B0F94";
- // private static final String TV1 = "5FD764A6D3A9FD9D";
- // private static final String TV1 = "48658DE1D9A70304";
+ // private static final String TV1 = "3E5A0E09198B0F94";
+ // private static final String TV1 = "5FD764A6D3A9FD9D";
+ // private static final String TV1 = "48658DE1D9A70304";
private static final String TV1 = "455ED214A6909F20";
-
private static final BigInteger MAX_NONCE_ITERATIONS = BigInteger.ONE.shiftLeft(16 * 8);
-
// UMAC32 parameters
static final int OUTPUT_LEN = 8;
-
static final int L1_KEY_LEN = 1024;
-
static final int KEY_LEN = 16;
-
/** caches the result of the correctness test, once executed. */
private static Boolean valid;
-
private byte[] nonce;
-
private UHash32 uhash32;
-
private BigInteger nonceReuseCount;
-
/** The authentication key for this instance. */
private transient byte[] K;
- // Constructor(s)
- // -------------------------------------------------------------------------
-
/** Trivial 0-arguments constructor. */
public UMac32()
{
@@ -177,8 +159,8 @@ public class UMac32 extends BaseMac
}
/**
- * <p>Private constructor for cloning purposes.</p>
- *
+ * Private constructor for cloning purposes.
+ *
* @param that the instance to clone.
*/
private UMac32(UMac32 that)
@@ -186,136 +168,103 @@ public class UMac32 extends BaseMac
this();
if (that.K != null)
- {
- this.K = (byte[]) that.K.clone();
- }
+ this.K = (byte[]) that.K.clone();
if (that.nonce != null)
- {
- this.nonce = (byte[]) that.nonce.clone();
- }
+ this.nonce = (byte[]) that.nonce.clone();
if (that.uhash32 != null)
- {
- this.uhash32 = (UHash32) that.uhash32.clone();
- }
+ this.uhash32 = (UHash32) that.uhash32.clone();
this.nonceReuseCount = that.nonceReuseCount;
}
- // Class methods
- // -------------------------------------------------------------------------
-
- // Instance methods
- // -------------------------------------------------------------------------
-
- // java.lang.Cloneable interface implementation ----------------------------
-
public Object clone()
{
return new UMac32(this);
}
- // gnu.crypto.mac.IMac interface implementation ----------------------------
-
public int macSize()
{
return OUTPUT_LEN;
}
/**
- * <p>Initialising a <i>UMAC</i> instance consists of defining values for
- * the following parameters:</p>
- *
+ * Initialising a <i>UMAC</i> instance consists of defining values for the
+ * following parameters:
* <ol>
- * <li>Key Material: as the value of the attribute entry keyed by
- * {@link #MAC_KEY_MATERIAL}. The value is taken to be a byte array
- * containing the user-specified key material. The length of this array,
- * if/when defined SHOULD be exactly equal to {@link #KEY_LEN}.</li>
- *
- * <li>Nonce Material: as the value of the attribute entry keyed by
- * {@link #NONCE_MATERIAL}. The value is taken to be a byte array
- * containing the user-specified nonce material. The length of this array,
- * if/when defined SHOULD be (a) greater than zero, and (b) less or equal
- * to 16 (the size of the AES block).</li>
+ * <li>Key Material: as the value of the attribute entry keyed by
+ * {@link #MAC_KEY_MATERIAL}. The value is taken to be a byte array
+ * containing the user-specified key material. The length of this array,
+ * if/when defined SHOULD be exactly equal to {@link #KEY_LEN}.</li>
+ * <li>Nonce Material: as the value of the attribute entry keyed by
+ * {@link #NONCE_MATERIAL}. The value is taken to be a byte array containing
+ * the user-specified nonce material. The length of this array, if/when
+ * defined SHOULD be (a) greater than zero, and (b) less or equal to 16 (the
+ * size of the AES block).</li>
* </ol>
- *
- * <p>For convenience, this implementation accepts that not both parameters
- * be always specified.</p>
- *
+ * <p>
+ * For convenience, this implementation accepts that not both parameters be
+ * always specified.
* <ul>
- * <li>If the <i>Key Material</i> is specified, but the <i>Nonce Material</i>
- * is not, then this implementation, re-uses the previously set <i>Nonce
- * Material</i> after (a) converting the bytes to an unsigned integer,
- * (b) incrementing the number by one, and (c) converting it back to 16
- * bytes.</li>
- *
- * <li>If the <i>Nonce Material</i> is specified, but the <i>Key Material</i>
- * is not, then this implementation re-uses the previously set <i>Key
- * Material</i>.</li>
+ * <li>If the <i>Key Material</i> is specified, but the <i>Nonce Material</i>
+ * is not, then this implementation, re-uses the previously set <i>Nonce
+ * Material</i> after (a) converting the bytes to an unsigned integer, (b)
+ * incrementing the number by one, and (c) converting it back to 16 bytes.</li>
+ * <li>If the <i>Nonce Material</i> is specified, but the <i>Key Material</i>
+ * is not, then this implementation re-uses the previously set <i>Key Material</i>.
+ * </li>
* </ul>
- *
- * <p>This method throws an exception if no <i>Key Material</i> is specified
- * in the input map, and there is no previously set/defined <i>Key Material</i>
+ * <p>
+ * This method throws an exception if no <i>Key Material</i> is specified in
+ * the input map, and there is no previously set/defined <i>Key Material</i>
* (from an earlier invocation of this method). If a <i>Key Material</i> can
- * be used, but no <i>Nonce Material</i> is defined or previously set/defined,
- * then a default value of all-zeroes shall be used.</p>
- *
+ * be used, but no <i>Nonce Material</i> is defined or previously
+ * set/defined, then a default value of all-zeroes shall be used.
+ *
* @param attributes one or both of required parameters.
* @throws InvalidKeyException the key material specified is not of the
- * correct length.
+ * correct length.
*/
public void init(Map attributes) throws InvalidKeyException,
IllegalStateException
{
byte[] key = (byte[]) attributes.get(MAC_KEY_MATERIAL);
byte[] n = (byte[]) attributes.get(NONCE_MATERIAL);
-
boolean newKey = (key != null);
boolean newNonce = (n != null);
-
if (newKey)
{
if (key.length != KEY_LEN)
- {
- throw new InvalidKeyException("Key length: "
- + String.valueOf(key.length));
- }
+ throw new InvalidKeyException("Key length: "
+ + String.valueOf(key.length));
K = key;
}
else
{
if (K == null)
- {
- throw new InvalidKeyException("Null Key");
- }
+ throw new InvalidKeyException("Null Key");
}
-
if (newNonce)
{
if (n.length < 1 || n.length > 16)
+ throw new IllegalArgumentException("Invalid Nonce length: "
+ + String.valueOf(n.length));
+ if (n.length < 16) // pad with zeroes
{
- throw new IllegalArgumentException("Invalid Nonce length: "
- + String.valueOf(n.length));
- }
-
- if (n.length < 16)
- { // pad with zeroes
byte[] newN = new byte[16];
System.arraycopy(n, 0, newN, 0, n.length);
nonce = newN;
}
else
- {
- nonce = n;
- }
+ nonce = n;
nonceReuseCount = BigInteger.ZERO;
}
- else if (nonce == null)
- { // use all-0 nonce if 1st time
+ else if (nonce == null) // use all-0 nonce if 1st time
+ {
nonce = new byte[16];
nonceReuseCount = BigInteger.ZERO;
}
- else if (!newKey)
- { // increment nonce if still below max count
+ else if (! newKey) // increment nonce if still below max count
+ {
nonceReuseCount = nonceReuseCount.add(BigInteger.ONE);
if (nonceReuseCount.compareTo(MAX_NONCE_ITERATIONS) >= 0)
{
@@ -326,9 +275,7 @@ public class UMac32 extends BaseMac
N = N.add(BigInteger.ONE).mod(MAX_NONCE_ITERATIONS);
n = N.toByteArray();
if (n.length == 16)
- {
- nonce = n;
- }
+ nonce = n;
else if (n.length < 16)
{
nonce = new byte[16];
@@ -340,15 +287,11 @@ public class UMac32 extends BaseMac
System.arraycopy(n, n.length - 16, nonce, 0, 16);
}
}
- else
- { // do nothing, re-use old nonce value
- nonceReuseCount = BigInteger.ZERO;
- }
+ else // do nothing, re-use old nonce value
+ nonceReuseCount = BigInteger.ZERO;
if (uhash32 == null)
- {
- uhash32 = new UHash32();
- }
+ uhash32 = new UHash32();
Map map = new HashMap();
map.put(MAC_KEY_MATERIAL, K);
@@ -370,9 +313,7 @@ public class UMac32 extends BaseMac
byte[] result = uhash32.digest();
byte[] pad = pdf(); // pdf(K, nonce);
for (int i = 0; i < OUTPUT_LEN; i++)
- {
- result[i] = (byte) (result[i] ^ pad[i]);
- }
+ result[i] = (byte)(result[i] ^ pad[i]);
return result;
}
@@ -380,9 +321,7 @@ public class UMac32 extends BaseMac
public void reset()
{
if (uhash32 != null)
- {
- uhash32.reset();
- }
+ uhash32.reset();
}
public boolean selfTest()
@@ -412,43 +351,32 @@ public class UMac32 extends BaseMac
x.printStackTrace(System.err);
return false;
}
-
byte[] data = new byte[128];
data[0] = (byte) 0x80;
-
mac.update(data, 0, 128);
byte[] result = mac.digest();
- // System.out.println("UMAC test vector: "+Util.toString(result));
valid = Boolean.valueOf(TV1.equals(Util.toString(result)));
}
return valid.booleanValue();
}
- // helper methods ----------------------------------------------------------
-
/**
- *
* @return byte array of length 8 (or OUTPUT_LEN) bytes.
*/
private byte[] pdf()
{
// Make Nonce 16 bytes by prepending zeroes. done (see init())
-
// one AES invocation is enough for more than one PDF invocation
// number of index bits needed = 1
-
// Extract index bits and zero low bits of Nonce
BigInteger Nonce = new BigInteger(1, nonce);
int nlowbitsnum = Nonce.testBit(0) ? 1 : 0;
Nonce = Nonce.clearBit(0);
-
// Generate subkey, AES and extract indexed substring
IRandom kdf = new UMacGenerator();
Map map = new HashMap();
map.put(IBlockCipher.KEY_MATERIAL, K);
- // map.put(IBlockCipher.CIPHER_BLOCK_SIZE, new Integer(128/8));
- map.put(UMacGenerator.INDEX, new Integer(128));
- // map.put(UMacGenerator.CIPHER, Registry.AES_CIPHER);
+ map.put(UMacGenerator.INDEX, Integer.valueOf(128));
kdf.init(map);
byte[] Kp = new byte[KEY_LEN];
try
@@ -485,7 +413,6 @@ public class UMac32 extends BaseMac
aes.encryptBlock(nonce, 0, T, 0);
byte[] result = new byte[OUTPUT_LEN];
System.arraycopy(T, nlowbitsnum, result, 0, OUTPUT_LEN);
-
return result;
}
-} \ No newline at end of file
+}