1 /*
   2  * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.security.provider;
  27 
  28 import static sun.security.provider.ByteArrayAccess.*;
  29 
  30 /**
  31  * This class implements the Secure Hash Algorithm (SHA) developed by
  32  * the National Institute of Standards and Technology along with the
  33  * National Security Agency.  This is the updated version of SHA
  34  * fip-180 as superseded by fip-180-1.
  35  *
  36  * <p>It implement JavaSecurity MessageDigest, and can be used by in
  37  * the Java Security framework, as a pluggable implementation, as a
  38  * filter for the digest stream classes.
  39  *
  40  * @author      Roger Riggs
  41  * @author      Benjamin Renaud
  42  * @author      Andreas Sterbenz
  43  */
  44 public final class SHA extends DigestBase {
  45 
  46     // Buffer of int's and count of characters accumulated
  47     // 64 bytes are included in each hash block so the low order
  48     // bits of count are used to know how to pack the bytes into ints
  49     // and to know when to compute the block and start the next one.
  50     private int[] W;
  51 
  52     // state of this
  53     private int[] state;
  54 
  55     /**
  56      * Creates a new SHA object.
  57      */
  58     public SHA() {
  59         super("SHA-1", 20, 64);
  60         state = new int[5];
  61         W = new int[80];
  62         implReset();
  63     }
  64 
  65     /*
  66      * Clones this object.
  67      */
  68     public Object clone() throws CloneNotSupportedException {
  69         SHA copy = (SHA) super.clone();
  70         copy.state = copy.state.clone();
  71         copy.W = new int[80];
  72         return copy;
  73     }
  74 
  75     /**
  76      * Resets the buffers and hash value to start a new hash.
  77      */
  78     void implReset() {
  79         state[0] = 0x67452301;
  80         state[1] = 0xefcdab89;
  81         state[2] = 0x98badcfe;
  82         state[3] = 0x10325476;
  83         state[4] = 0xc3d2e1f0;
  84     }
  85 
  86     /**
  87      * Computes the final hash and copies the 20 bytes to the output array.
  88      */
  89     void implDigest(byte[] out, int ofs) {
  90         long bitsProcessed = bytesProcessed << 3;
  91 
  92         int index = (int)bytesProcessed & 0x3f;
  93         int padLen = (index < 56) ? (56 - index) : (120 - index);
  94         engineUpdate(padding, 0, padLen);
  95 
  96         i2bBig4((int)(bitsProcessed >>> 32), buffer, 56);
  97         i2bBig4((int)bitsProcessed, buffer, 60);
  98         implCompress(buffer, 0);
  99 
 100         i2bBig(state, 0, out, ofs, 20);
 101     }
 102 
 103     // Constants for each round
 104     private final static int round1_kt = 0x5a827999;
 105     private final static int round2_kt = 0x6ed9eba1;
 106     private final static int round3_kt = 0x8f1bbcdc;
 107     private final static int round4_kt = 0xca62c1d6;
 108 
 109     /**
 110      * Compute a the hash for the current block.
 111      *
 112      * This is in the same vein as Peter Gutmann's algorithm listed in
 113      * the back of Applied Cryptography, Compact implementation of
 114      * "old" NIST Secure Hash Algorithm.
 115      */
 116     void implCompress(byte[] buf, int ofs) {
 117         b2iBig64(buf, ofs, W);
 118 
 119         // The first 16 ints have the byte stream, compute the rest of
 120         // the buffer
 121         for (int t = 16; t <= 79; t++) {
 122             int temp = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
 123             W[t] = (temp << 1) | (temp >>> 31);
 124         }
 125 
 126         int a = state[0];
 127         int b = state[1];
 128         int c = state[2];
 129         int d = state[3];
 130         int e = state[4];
 131 
 132         // Round 1
 133         for (int i = 0; i < 20; i++) {
 134             int temp = ((a<<5) | (a>>>(32-5))) +
 135                 ((b&c)|((~b)&d))+ e + W[i] + round1_kt;
 136             e = d;
 137             d = c;
 138             c = ((b<<30) | (b>>>(32-30)));
 139             b = a;
 140             a = temp;
 141         }
 142 
 143         // Round 2
 144         for (int i = 20; i < 40; i++) {
 145             int temp = ((a<<5) | (a>>>(32-5))) +
 146                 (b ^ c ^ d) + e + W[i] + round2_kt;
 147             e = d;
 148             d = c;
 149             c = ((b<<30) | (b>>>(32-30)));
 150             b = a;
 151             a = temp;
 152         }
 153 
 154         // Round 3
 155         for (int i = 40; i < 60; i++) {
 156             int temp = ((a<<5) | (a>>>(32-5))) +
 157                 ((b&c)|(b&d)|(c&d)) + e + W[i] + round3_kt;
 158             e = d;
 159             d = c;
 160             c = ((b<<30) | (b>>>(32-30)));
 161             b = a;
 162             a = temp;
 163         }
 164 
 165         // Round 4
 166         for (int i = 60; i < 80; i++) {
 167             int temp = ((a<<5) | (a>>>(32-5))) +
 168                 (b ^ c ^ d) + e + W[i] + round4_kt;
 169             e = d;
 170             d = c;
 171             c = ((b<<30) | (b>>>(32-30)));
 172             b = a;
 173             a = temp;
 174         }
 175         state[0] += a;
 176         state[1] += b;
 177         state[2] += c;
 178         state[3] += d;
 179         state[4] += e;
 180     }
 181 
 182 }