diff options
Diffstat (limited to 'gnu/javax/crypto/mac/UMac32.java')
-rw-r--r-- | gnu/javax/crypto/mac/UMac32.java | 287 |
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 +} |