0N/A/*
2362N/A * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.security.provider;
0N/A
0N/Aimport static sun.security.provider.ByteArrayAccess.*;
0N/A
0N/A/**
0N/A * This class implements the Secure Hash Algorithm (SHA) developed by
0N/A * the National Institute of Standards and Technology along with the
0N/A * National Security Agency. This is the updated version of SHA
0N/A * fip-180 as superseded by fip-180-1.
0N/A *
0N/A * <p>It implement JavaSecurity MessageDigest, and can be used by in
0N/A * the Java Security framework, as a pluggable implementation, as a
0N/A * filter for the digest stream classes.
0N/A *
0N/A * @author Roger Riggs
0N/A * @author Benjamin Renaud
0N/A * @author Andreas Sterbenz
0N/A */
0N/Apublic final class SHA extends DigestBase {
0N/A
0N/A // Buffer of int's and count of characters accumulated
0N/A // 64 bytes are included in each hash block so the low order
0N/A // bits of count are used to know how to pack the bytes into ints
0N/A // and to know when to compute the block and start the next one.
0N/A private final int[] W;
0N/A
0N/A // state of this
0N/A private final int[] state;
0N/A
0N/A /**
0N/A * Creates a new SHA object.
0N/A */
0N/A public SHA() {
0N/A super("SHA-1", 20, 64);
0N/A state = new int[5];
0N/A W = new int[80];
0N/A implReset();
0N/A }
0N/A
0N/A /**
0N/A * Creates a SHA object.with state (for cloning) */
0N/A private SHA(SHA base) {
0N/A super(base);
0N/A this.state = base.state.clone();
0N/A this.W = new int[80];
0N/A }
0N/A
0N/A /*
0N/A * Clones this object.
0N/A */
0N/A public Object clone() {
0N/A return new SHA(this);
0N/A }
0N/A
0N/A /**
0N/A * Resets the buffers and hash value to start a new hash.
0N/A */
0N/A void implReset() {
0N/A state[0] = 0x67452301;
0N/A state[1] = 0xefcdab89;
0N/A state[2] = 0x98badcfe;
0N/A state[3] = 0x10325476;
0N/A state[4] = 0xc3d2e1f0;
0N/A }
0N/A
0N/A /**
0N/A * Computes the final hash and copies the 20 bytes to the output array.
0N/A */
0N/A void implDigest(byte[] out, int ofs) {
0N/A long bitsProcessed = bytesProcessed << 3;
0N/A
0N/A int index = (int)bytesProcessed & 0x3f;
0N/A int padLen = (index < 56) ? (56 - index) : (120 - index);
0N/A engineUpdate(padding, 0, padLen);
0N/A
0N/A i2bBig4((int)(bitsProcessed >>> 32), buffer, 56);
0N/A i2bBig4((int)bitsProcessed, buffer, 60);
0N/A implCompress(buffer, 0);
0N/A
0N/A i2bBig(state, 0, out, ofs, 20);
0N/A }
0N/A
0N/A // Constants for each round
0N/A private final static int round1_kt = 0x5a827999;
0N/A private final static int round2_kt = 0x6ed9eba1;
0N/A private final static int round3_kt = 0x8f1bbcdc;
0N/A private final static int round4_kt = 0xca62c1d6;
0N/A
0N/A /**
0N/A * Compute a the hash for the current block.
0N/A *
0N/A * This is in the same vein as Peter Gutmann's algorithm listed in
0N/A * the back of Applied Cryptography, Compact implementation of
0N/A * "old" NIST Secure Hash Algorithm.
0N/A */
0N/A void implCompress(byte[] buf, int ofs) {
0N/A b2iBig64(buf, ofs, W);
0N/A
0N/A // The first 16 ints have the byte stream, compute the rest of
0N/A // the buffer
0N/A for (int t = 16; t <= 79; t++) {
0N/A int temp = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
0N/A W[t] = (temp << 1) | (temp >>> 31);
0N/A }
0N/A
0N/A int a = state[0];
0N/A int b = state[1];
0N/A int c = state[2];
0N/A int d = state[3];
0N/A int e = state[4];
0N/A
0N/A // Round 1
0N/A for (int i = 0; i < 20; i++) {
0N/A int temp = ((a<<5) | (a>>>(32-5))) +
0N/A ((b&c)|((~b)&d))+ e + W[i] + round1_kt;
0N/A e = d;
0N/A d = c;
0N/A c = ((b<<30) | (b>>>(32-30)));
0N/A b = a;
0N/A a = temp;
0N/A }
0N/A
0N/A // Round 2
0N/A for (int i = 20; i < 40; i++) {
0N/A int temp = ((a<<5) | (a>>>(32-5))) +
0N/A (b ^ c ^ d) + e + W[i] + round2_kt;
0N/A e = d;
0N/A d = c;
0N/A c = ((b<<30) | (b>>>(32-30)));
0N/A b = a;
0N/A a = temp;
0N/A }
0N/A
0N/A // Round 3
0N/A for (int i = 40; i < 60; i++) {
0N/A int temp = ((a<<5) | (a>>>(32-5))) +
0N/A ((b&c)|(b&d)|(c&d)) + e + W[i] + round3_kt;
0N/A e = d;
0N/A d = c;
0N/A c = ((b<<30) | (b>>>(32-30)));
0N/A b = a;
0N/A a = temp;
0N/A }
0N/A
0N/A // Round 4
0N/A for (int i = 60; i < 80; i++) {
0N/A int temp = ((a<<5) | (a>>>(32-5))) +
0N/A (b ^ c ^ d) + e + W[i] + round4_kt;
0N/A e = d;
0N/A d = c;
0N/A c = ((b<<30) | (b>>>(32-30)));
0N/A b = a;
0N/A a = temp;
0N/A }
0N/A state[0] += a;
0N/A state[1] += b;
0N/A state[2] += c;
0N/A state[3] += d;
0N/A state[4] += e;
0N/A }
0N/A
0N/A}