summaryrefslogtreecommitdiffstats
path: root/pki/base/util/src/netscape/security/provider/SHA.java
diff options
context:
space:
mode:
Diffstat (limited to 'pki/base/util/src/netscape/security/provider/SHA.java')
-rw-r--r--pki/base/util/src/netscape/security/provider/SHA.java510
1 files changed, 256 insertions, 254 deletions
diff --git a/pki/base/util/src/netscape/security/provider/SHA.java b/pki/base/util/src/netscape/security/provider/SHA.java
index 2e5ac328..632b4586 100644
--- a/pki/base/util/src/netscape/security/provider/SHA.java
+++ b/pki/base/util/src/netscape/security/provider/SHA.java
@@ -21,26 +21,28 @@ import java.security.DigestException;
import java.security.MessageDigestSpi;
/**
- * This class implements the Secure Hash Algorithm (SHA) developed by
- * the National Institute of Standards and Technology along with the
- * National Security Agency. This is the updated version of SHA
- * fip-180 as superseded by fip-180-1.
- *
- * <p>It implement JavaSecurity MessageDigest, and can be used by in
- * the Java Security framework, as a pluggable implementation, as a
- * filter for the digest stream classes.
+ * This class implements the Secure Hash Algorithm (SHA) developed by the
+ * National Institute of Standards and Technology along with the National
+ * Security Agency. This is the updated version of SHA fip-180 as superseded by
+ * fip-180-1.
*
- * @version 1.30 97/12/10
- * @author Roger Riggs
- * @author Benjamin Renaud
+ * <p>
+ * It implement JavaSecurity MessageDigest, and can be used by in the Java
+ * Security framework, as a pluggable implementation, as a filter for the digest
+ * stream classes.
+ *
+ * @version 1.30 97/12/10
+ * @author Roger Riggs
+ * @author Benjamin Renaud
*/
public class SHA extends MessageDigestSpi implements Cloneable {
- /* This private hookm controlled by the appropriate constructor,
- causes this class to implement the first version of SHA,
- as defined in FIPS 180, as opposed to FIPS 180-1. This was
- useful for DSA testing. */
+ /*
+ * This private hookm controlled by the appropriate constructor, causes this
+ * class to implement the first version of SHA, as defined in FIPS 180, as
+ * opposed to FIPS 180-1. This was useful for DSA testing.
+ */
private int version = 1;
private static final int SHA_LENGTH = 20;
@@ -52,213 +54,214 @@ public class SHA extends MessageDigestSpi implements Cloneable {
private int W[] = new int[80];
private long count = 0;
private final int countmax = 64;
- private final int countmask = (countmax-1);
+ private final int countmask = (countmax - 1);
private int AA, BB, CC, DD, EE;
/**
- * Creates a SHA object.with state (for cloning) */
+ * Creates a SHA object.with state (for cloning)
+ */
private SHA(SHA sha) {
- this();
- this.version = sha.version;
- System.arraycopy(sha.W, 0, this.W, 0, W.length);
- this.count = sha.count;
- this.AA = sha.AA;
- this.BB = sha.BB;
- this.CC = sha.CC;
- this.DD = sha.DD;
- this.EE = sha.EE;
+ this();
+ this.version = sha.version;
+ System.arraycopy(sha.W, 0, this.W, 0, W.length);
+ this.count = sha.count;
+ this.AA = sha.AA;
+ this.BB = sha.BB;
+ this.CC = sha.CC;
+ this.DD = sha.DD;
+ this.EE = sha.EE;
}
-
+
SHA(int version) {
- this();
- this.version = version;
+ this();
+ this.version = version;
}
/**
* Creates a new SHA object.
*/
public SHA() {
- init();
+ init();
}
/**
* Return the length of the digest in bytes
*/
protected int engineGetDigestLength() {
- return (SHA_LENGTH);
+ return (SHA_LENGTH);
}
public void engineUpdate(byte b) {
- engineUpdate((int)b);
+ engineUpdate((int) b);
}
/**
* Update a byte.
- *
- * @param b the byte
+ *
+ * @param b the byte
*/
- private void engineUpdate(int b) {
- int word;
- int offset;
-
- /* compute word offset and bit offset within word the low bits
- of count are inverted to make put the bytes in the write
- order */
- word = ((int)count & countmask) >>> 2;
- offset = (~(int)count & 3) << 3;
-
- W[word] = (W[word] & ~(0xff << offset)) | ((b & 0xff) << offset);
-
- /* If this is the last byte of a block, compute the partial hash */
- if (((int)count & countmask) == countmask) {
- computeBlock();
- }
- count++;
+ private void engineUpdate(int b) {
+ int word;
+ int offset;
+
+ /*
+ * compute word offset and bit offset within word the low bits of count
+ * are inverted to make put the bytes in the write order
+ */
+ word = ((int) count & countmask) >>> 2;
+ offset = (~(int) count & 3) << 3;
+
+ W[word] = (W[word] & ~(0xff << offset)) | ((b & 0xff) << offset);
+
+ /* If this is the last byte of a block, compute the partial hash */
+ if (((int) count & countmask) == countmask) {
+ computeBlock();
+ }
+ count++;
}
-
+
/**
* Update a buffer.
- *
- * @param b the data to be updated.
- * @param off the start offset in the data
- * @param len the number of bytes to be updated.
+ *
+ * @param b the data to be updated.
+ * @param off the start offset in the data
+ * @param len the number of bytes to be updated.
*/
public void engineUpdate(byte b[], int off, int len) {
- int word;
- int offset;
-
- if ((off < 0) || (len < 0) || (off + len > b.length))
- throw new ArrayIndexOutOfBoundsException();
-
- // Use single writes until integer aligned
- while ((len > 0) &&
- ((int)count & 3) != 0) {
- engineUpdate(b[off]);
- off++;
- len--;
- }
-
- /* Assemble groups of 4 bytes to be inserted in integer array */
- for (;len >= 4; len -= 4, off += 4) {
-
- word = ((int)count & countmask) >> 2;
-
- W[word] = ((b[off] & 0xff) << 24) |
- ((b[off+1] & 0xff) << 16) |
- ((b[off+2] & 0xff) << 8) |
- ((b[off+3] & 0xff) );
-
- count += 4;
- if (((int)count & countmask) == 0) {
- computeBlock();
- }
- }
-
- /* Use single writes for last few bytes */
- for (; len > 0; len--, off++) {
- engineUpdate(b[off]);
- }
+ int word;
+ int offset;
+
+ if ((off < 0) || (len < 0) || (off + len > b.length))
+ throw new ArrayIndexOutOfBoundsException();
+
+ // Use single writes until integer aligned
+ while ((len > 0) && ((int) count & 3) != 0) {
+ engineUpdate(b[off]);
+ off++;
+ len--;
+ }
+
+ /* Assemble groups of 4 bytes to be inserted in integer array */
+ for (; len >= 4; len -= 4, off += 4) {
+
+ word = ((int) count & countmask) >> 2;
+
+ W[word] = ((b[off] & 0xff) << 24) | ((b[off + 1] & 0xff) << 16)
+ | ((b[off + 2] & 0xff) << 8) | ((b[off + 3] & 0xff));
+
+ count += 4;
+ if (((int) count & countmask) == 0) {
+ computeBlock();
+ }
+ }
+
+ /* Use single writes for last few bytes */
+ for (; len > 0; len--, off++) {
+ engineUpdate(b[off]);
+ }
}
-
+
/**
* Resets the buffers and hash value to start a new hash.
*/
public void init() {
- AA = 0x67452301;
- BB = 0xefcdab89;
- CC = 0x98badcfe;
- DD = 0x10325476;
- EE = 0xc3d2e1f0;
-
- for (int i = 0; i < 80; i++)
- W[i] = 0;
- count = 0;
+ AA = 0x67452301;
+ BB = 0xefcdab89;
+ CC = 0x98badcfe;
+ DD = 0x10325476;
+ EE = 0xc3d2e1f0;
+
+ for (int i = 0; i < 80; i++)
+ W[i] = 0;
+ count = 0;
}
/**
* Resets the buffers and hash value to start a new hash.
*/
public void engineReset() {
- init();
+ init();
}
-
+
/**
- * Computes the final hash and returns the final value as a
- * byte[20] array. The object is reset to be ready for further
- * use, as specified in the JavaSecurity MessageDigest
- * specification. */
+ * Computes the final hash and returns the final value as a byte[20] array.
+ * The object is reset to be ready for further use, as specified in the
+ * JavaSecurity MessageDigest specification.
+ */
public byte[] engineDigest() {
- byte hashvalue[] = new byte[SHA_LENGTH];
-
- try {
- int outLen = engineDigest(hashvalue, 0, hashvalue.length);
- } catch (DigestException e) {
- throw new InternalError("");
- }
- return hashvalue;
+ byte hashvalue[] = new byte[SHA_LENGTH];
+
+ try {
+ int outLen = engineDigest(hashvalue, 0, hashvalue.length);
+ } catch (DigestException e) {
+ throw new InternalError("");
+ }
+ return hashvalue;
}
/**
- * Computes the final hash and returns the final value as a
- * byte[20] array. The object is reset to be ready for further
- * use, as specified in the JavaSecurity MessageDigest
- * specification. */
+ * Computes the final hash and returns the final value as a byte[20] array.
+ * The object is reset to be ready for further use, as specified in the
+ * JavaSecurity MessageDigest specification.
+ */
public int engineDigest(byte[] hashvalue, int offset, int len)
- throws DigestException {
-
- if (len < SHA_LENGTH)
- throw new DigestException("partial digests not returned");
- if (hashvalue.length - offset < SHA_LENGTH)
- throw new DigestException("insufficient space in the output " +
- "buffer to store the digest");
-
- /* The number of bits before padding occurs */
- long bits = count << 3;
-
- engineUpdate(0x80);
-
- /* Pad with zeros until length is a multiple of 448 (the last two
- 32 ints are used a holder for bits (see above). */
- while ((int)(count & countmask) != 56) {
- engineUpdate(0);
- }
-
- W[14] = (int)(bits >>> 32);
- W[15] = (int)(bits & 0xffffffff);
-
- count += 8;
- computeBlock();
-
- // Copy out the result
- hashvalue[offset + 0] = (byte)(AA >>> 24);
- hashvalue[offset + 1] = (byte)(AA >>> 16);
- hashvalue[offset + 2] = (byte)(AA >>> 8);
- hashvalue[offset + 3] = (byte)(AA >>> 0);
-
- hashvalue[offset + 4] = (byte)(BB >>> 24);
- hashvalue[offset + 5] = (byte)(BB >>> 16);
- hashvalue[offset + 6] = (byte)(BB >>> 8);
- hashvalue[offset + 7] = (byte)(BB >>> 0);
-
- hashvalue[offset + 8] = (byte)(CC >>> 24);
- hashvalue[offset + 9] = (byte)(CC >>> 16);
- hashvalue[offset + 10] = (byte)(CC >>> 8);
- hashvalue[offset + 11] = (byte)(CC >>> 0);
-
- hashvalue[offset + 12] = (byte)(DD >>> 24);
- hashvalue[offset + 13] = (byte)(DD >>> 16);
- hashvalue[offset + 14] = (byte)(DD >>> 8);
- hashvalue[offset + 15] = (byte)(DD >>> 0);
-
- hashvalue[offset + 16] = (byte)(EE >>> 24);
- hashvalue[offset + 17] = (byte)(EE >>> 16);
- hashvalue[offset + 18] = (byte)(EE >>> 8);
- hashvalue[offset + 19] = (byte)(EE >>> 0);
-
- engineReset(); // remove the evidence
-
- return SHA_LENGTH;
+ throws DigestException {
+
+ if (len < SHA_LENGTH)
+ throw new DigestException("partial digests not returned");
+ if (hashvalue.length - offset < SHA_LENGTH)
+ throw new DigestException("insufficient space in the output "
+ + "buffer to store the digest");
+
+ /* The number of bits before padding occurs */
+ long bits = count << 3;
+
+ engineUpdate(0x80);
+
+ /*
+ * Pad with zeros until length is a multiple of 448 (the last two 32
+ * ints are used a holder for bits (see above).
+ */
+ while ((int) (count & countmask) != 56) {
+ engineUpdate(0);
+ }
+
+ W[14] = (int) (bits >>> 32);
+ W[15] = (int) (bits & 0xffffffff);
+
+ count += 8;
+ computeBlock();
+
+ // Copy out the result
+ hashvalue[offset + 0] = (byte) (AA >>> 24);
+ hashvalue[offset + 1] = (byte) (AA >>> 16);
+ hashvalue[offset + 2] = (byte) (AA >>> 8);
+ hashvalue[offset + 3] = (byte) (AA >>> 0);
+
+ hashvalue[offset + 4] = (byte) (BB >>> 24);
+ hashvalue[offset + 5] = (byte) (BB >>> 16);
+ hashvalue[offset + 6] = (byte) (BB >>> 8);
+ hashvalue[offset + 7] = (byte) (BB >>> 0);
+
+ hashvalue[offset + 8] = (byte) (CC >>> 24);
+ hashvalue[offset + 9] = (byte) (CC >>> 16);
+ hashvalue[offset + 10] = (byte) (CC >>> 8);
+ hashvalue[offset + 11] = (byte) (CC >>> 0);
+
+ hashvalue[offset + 12] = (byte) (DD >>> 24);
+ hashvalue[offset + 13] = (byte) (DD >>> 16);
+ hashvalue[offset + 14] = (byte) (DD >>> 8);
+ hashvalue[offset + 15] = (byte) (DD >>> 0);
+
+ hashvalue[offset + 16] = (byte) (EE >>> 24);
+ hashvalue[offset + 17] = (byte) (EE >>> 16);
+ hashvalue[offset + 18] = (byte) (EE >>> 8);
+ hashvalue[offset + 19] = (byte) (EE >>> 0);
+
+ engineReset(); // remove the evidence
+
+ return SHA_LENGTH;
}
// Constants for each round
@@ -269,95 +272,94 @@ public class SHA extends MessageDigestSpi implements Cloneable {
/**
* Compute a the hash for the current block.
- *
- * This is in the same vein as Peter Gutmann's algorithm listed in
- * the back of Applied Cryptography, Compact implementation of
- * "old" NIST Secure Hash Algorithm.
- *
+ *
+ * This is in the same vein as Peter Gutmann's algorithm listed in the back
+ * of Applied Cryptography, Compact implementation of "old" NIST Secure Hash
+ * Algorithm.
+ *
*/
private void computeBlock() {
- int temp, a, b, c, d, e;
-
- // The first 16 ints have the byte stream, compute the rest of
- // the buffer
- for (int t = 16; t <= 79; t++) {
- if (version == 0) {
- W[t] = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
- } else {
- temp = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
- W[t] = ((temp << 1) | (temp >>>(32 - 1)));
- }
- }
-
- a = AA;
- b = BB;
- c = CC;
- d = DD;
- e = EE;
-
- // Round 1
- for (int i = 0; i < 20; i++) {
- temp = ((a<<5) | (a>>>(32-5))) +
- ((b&c)|((~b)&d))+ e + W[i] + round1_kt;
- e = d;
- d = c;
- c = ((b<<30) | (b>>>(32-30)));
- b = a;
- a = temp;
- }
-
- // Round 2
- for (int i = 20; i < 40; i++) {
- temp = ((a<<5) | (a>>>(32-5))) +
- (b ^ c ^ d) + e + W[i] + round2_kt;
- e = d;
- d = c;
- c = ((b<<30) | (b>>>(32-30)));
- b = a;
- a = temp;
- }
-
- // Round 3
- for (int i = 40; i < 60; i++) {
- temp = ((a<<5) | (a>>>(32-5))) +
- ((b&c)|(b&d)|(c&d)) + e + W[i] + round3_kt;
- e = d;
- d = c;
- c = ((b<<30) | (b>>>(32-30)));
- b = a;
- a = temp;
- }
-
- // Round 4
- for (int i = 60; i < 80; i++) {
- temp = ((a<<5) | (a>>>(32-5))) +
- (b ^ c ^ d) + e + W[i] + round4_kt;
- e = d;
- d = c;
- c = ((b<<30) | (b>>>(32-30)));
- b = a;
- a = temp;
- }
- AA += a;
- BB += b;
- CC += c;
- DD += d;
- EE += e;
+ int temp, a, b, c, d, e;
+
+ // The first 16 ints have the byte stream, compute the rest of
+ // the buffer
+ for (int t = 16; t <= 79; t++) {
+ if (version == 0) {
+ W[t] = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16];
+ } else {
+ temp = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16];
+ W[t] = ((temp << 1) | (temp >>> (32 - 1)));
+ }
+ }
+
+ a = AA;
+ b = BB;
+ c = CC;
+ d = DD;
+ e = EE;
+
+ // Round 1
+ for (int i = 0; i < 20; i++) {
+ temp = ((a << 5) | (a >>> (32 - 5))) + ((b & c) | ((~b) & d)) + e
+ + W[i] + round1_kt;
+ e = d;
+ d = c;
+ c = ((b << 30) | (b >>> (32 - 30)));
+ b = a;
+ a = temp;
+ }
+
+ // Round 2
+ for (int i = 20; i < 40; i++) {
+ temp = ((a << 5) | (a >>> (32 - 5))) + (b ^ c ^ d) + e + W[i]
+ + round2_kt;
+ e = d;
+ d = c;
+ c = ((b << 30) | (b >>> (32 - 30)));
+ b = a;
+ a = temp;
+ }
+
+ // Round 3
+ for (int i = 40; i < 60; i++) {
+ temp = ((a << 5) | (a >>> (32 - 5)))
+ + ((b & c) | (b & d) | (c & d)) + e + W[i] + round3_kt;
+ e = d;
+ d = c;
+ c = ((b << 30) | (b >>> (32 - 30)));
+ b = a;
+ a = temp;
+ }
+
+ // Round 4
+ for (int i = 60; i < 80; i++) {
+ temp = ((a << 5) | (a >>> (32 - 5))) + (b ^ c ^ d) + e + W[i]
+ + round4_kt;
+ e = d;
+ d = c;
+ c = ((b << 30) | (b >>> (32 - 30)));
+ b = a;
+ a = temp;
+ }
+ AA += a;
+ BB += b;
+ CC += c;
+ DD += d;
+ EE += e;
}
/*
* Clones this object.
*/
public Object clone() {
- SHA that = null;
- try {
- that = (SHA)super.clone();
- that.W = new int[80];
- System.arraycopy(this.W, 0, that.W, 0, W.length);
- return that;
- } catch (CloneNotSupportedException e) {
- }
- return that;
+ SHA that = null;
+ try {
+ that = (SHA) super.clone();
+ that.W = new int[80];
+ System.arraycopy(this.W, 0, that.W, 0, W.length);
+ return that;
+ } catch (CloneNotSupportedException e) {
+ }
+ return that;
}
}
-