| 1 | /* SHA.java -- Class implementing the SHA-1 algorithm as specified in [1].
|
|---|
| 2 | Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
|
|---|
| 3 |
|
|---|
| 4 | This file is part of GNU Classpath.
|
|---|
| 5 |
|
|---|
| 6 | GNU Classpath is free software; you can redistribute it and/or modify
|
|---|
| 7 | it under the terms of the GNU General Public License as published by
|
|---|
| 8 | the Free Software Foundation; either version 2, or (at your option)
|
|---|
| 9 | any later version.
|
|---|
| 10 |
|
|---|
| 11 | GNU Classpath is distributed in the hope that it will be useful, but
|
|---|
| 12 | WITHOUT ANY WARRANTY; without even the implied warranty of
|
|---|
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|---|
| 14 | General Public License for more details.
|
|---|
| 15 |
|
|---|
| 16 | You should have received a copy of the GNU General Public License
|
|---|
| 17 | along with GNU Classpath; see the file COPYING. If not, write to the
|
|---|
| 18 | Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
|---|
| 19 | 02111-1307 USA.
|
|---|
| 20 |
|
|---|
| 21 | Linking this library statically or dynamically with other modules is
|
|---|
| 22 | making a combined work based on this library. Thus, the terms and
|
|---|
| 23 | conditions of the GNU General Public License cover the whole
|
|---|
| 24 | combination.
|
|---|
| 25 |
|
|---|
| 26 | As a special exception, the copyright holders of this library give you
|
|---|
| 27 | permission to link this library with independent modules to produce an
|
|---|
| 28 | executable, regardless of the license terms of these independent
|
|---|
| 29 | modules, and to copy and distribute the resulting executable under
|
|---|
| 30 | terms of your choice, provided that you also meet, for each linked
|
|---|
| 31 | independent module, the terms and conditions of the license of that
|
|---|
| 32 | module. An independent module is a module which is not derived from
|
|---|
| 33 | or based on this library. If you modify this library, you may extend
|
|---|
| 34 | this exception to your version of the library, but you are not
|
|---|
| 35 | obligated to do so. If you do not wish to do so, delete this
|
|---|
| 36 | exception statement from your version. */
|
|---|
| 37 |
|
|---|
| 38 |
|
|---|
| 39 | package gnu.java.security.provider;
|
|---|
| 40 |
|
|---|
| 41 | import java.security.MessageDigest;
|
|---|
| 42 |
|
|---|
| 43 | /**
|
|---|
| 44 | This class implements the SHA-1 algorithm as described in [1].
|
|---|
| 45 |
|
|---|
| 46 | [1] Federal Information Processing Standards Publication 180-1.
|
|---|
| 47 | Specifications for the Secure Hash Standard. April 17, 1995.
|
|---|
| 48 |
|
|---|
| 49 | @see java.security.MessageDigest
|
|---|
| 50 | */
|
|---|
| 51 | public class SHA extends MessageDigest implements Cloneable
|
|---|
| 52 | {
|
|---|
| 53 | public SHA ()
|
|---|
| 54 | {
|
|---|
| 55 | super("SHA");
|
|---|
| 56 | engineReset ();
|
|---|
| 57 | }
|
|---|
| 58 |
|
|---|
| 59 | public int engineGetDigestLength()
|
|---|
| 60 | {
|
|---|
| 61 | return 20;
|
|---|
| 62 | }
|
|---|
| 63 |
|
|---|
| 64 | public void engineUpdate (byte b)
|
|---|
| 65 | {
|
|---|
| 66 | int i = ((int)bytecount) & 0x3f; //wgs
|
|---|
| 67 | int shift = (3 - i % 4) << 3;
|
|---|
| 68 | int idx = i / 4;
|
|---|
| 69 |
|
|---|
| 70 | i = (int)b;
|
|---|
| 71 | W[idx] = (W[idx] & ~(0xff << shift)) | ((i & 0xff) << shift);
|
|---|
| 72 |
|
|---|
| 73 | // if we've filled up a block, then process it
|
|---|
| 74 | if (((++bytecount) & 0x3f) == 0)
|
|---|
| 75 | munch ();
|
|---|
| 76 | }
|
|---|
| 77 |
|
|---|
| 78 | // This could be optimized.
|
|---|
| 79 | public void engineUpdate (byte bytes[], int off, int len)
|
|---|
| 80 | {
|
|---|
| 81 | if (len < 0)
|
|---|
| 82 | throw new ArrayIndexOutOfBoundsException ();
|
|---|
| 83 |
|
|---|
| 84 | int end = off + len;
|
|---|
| 85 | while (off < end)
|
|---|
| 86 | engineUpdate (bytes[off++]);
|
|---|
| 87 | }
|
|---|
| 88 |
|
|---|
| 89 | public void engineReset ()
|
|---|
| 90 | {
|
|---|
| 91 | bytecount = 0;
|
|---|
| 92 | // magic numbers from [1] p. 10.
|
|---|
| 93 | H0 = 0x67452301;
|
|---|
| 94 | H1 = 0xefcdab89;
|
|---|
| 95 | H2 = 0x98badcfe;
|
|---|
| 96 | H3 = 0x10325476;
|
|---|
| 97 | H4 = 0xc3d2e1f0;
|
|---|
| 98 | }
|
|---|
| 99 |
|
|---|
| 100 | public byte[] engineDigest ()
|
|---|
| 101 | {
|
|---|
| 102 | long bitcount = bytecount << 3;
|
|---|
| 103 | engineUpdate ((byte)0x80); // 10000000 in binary; the start of the padding
|
|---|
| 104 |
|
|---|
| 105 | // add the rest of the padding to fill this block out, but leave 8
|
|---|
| 106 | // bytes to put in the original bytecount
|
|---|
| 107 | while ((bytecount & 0x3f) != 56)
|
|---|
| 108 | engineUpdate ((byte)0);
|
|---|
| 109 |
|
|---|
| 110 | // add the length of the original, unpadded block to the end of
|
|---|
| 111 | // the padding
|
|---|
| 112 | W[14] = (int)(bitcount >>> 32);
|
|---|
| 113 | W[15] = (int)bitcount;
|
|---|
| 114 | bytecount += 8;
|
|---|
| 115 |
|
|---|
| 116 | // digest the fully padded block
|
|---|
| 117 | munch ();
|
|---|
| 118 |
|
|---|
| 119 | byte[] result
|
|---|
| 120 | = new byte[] {(byte)(H0 >>> 24), (byte)(H0 >>> 16),
|
|---|
| 121 | (byte)(H0 >>> 8), (byte)H0,
|
|---|
| 122 | (byte)(H1 >>> 24), (byte)(H1 >>> 16),
|
|---|
| 123 | (byte)(H1 >>> 8), (byte)H1,
|
|---|
| 124 | (byte)(H2 >>> 24), (byte)(H2 >>> 16),
|
|---|
| 125 | (byte)(H2 >>> 8), (byte)H2,
|
|---|
| 126 | (byte)(H3 >>> 24), (byte)(H3 >>> 16),
|
|---|
| 127 | (byte)(H3 >>> 8), (byte)H3,
|
|---|
| 128 | (byte)(H4 >>> 24), (byte)(H4 >>> 16),
|
|---|
| 129 | (byte)(H4 >>> 8), (byte)H4};
|
|---|
| 130 |
|
|---|
| 131 | engineReset ();
|
|---|
| 132 | return result;
|
|---|
| 133 | }
|
|---|
| 134 |
|
|---|
| 135 | // Process a single block. This is pretty much copied verbatim from
|
|---|
| 136 | // [1] pp. 9, 10.
|
|---|
| 137 | private void munch ()
|
|---|
| 138 | {
|
|---|
| 139 | for (int t = 16; t < 80; ++ t)
|
|---|
| 140 | {
|
|---|
| 141 | int Wt = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16];
|
|---|
| 142 | W[t] = Wt << 1 | Wt >>> 31;
|
|---|
| 143 | }
|
|---|
| 144 |
|
|---|
| 145 | int A = H0;
|
|---|
| 146 | int B = H1;
|
|---|
| 147 | int C = H2;
|
|---|
| 148 | int D = H3;
|
|---|
| 149 | int E = H4;
|
|---|
| 150 |
|
|---|
| 151 | for (int t = 0; t < 20; ++ t)
|
|---|
| 152 | {
|
|---|
| 153 | int TEMP = (A << 5 | A >>> 27) // S^5(A)
|
|---|
| 154 | + ((B & C) | (~B & D)) // f_t(B,C,D)
|
|---|
| 155 | + E + W[t]
|
|---|
| 156 | + 0x5a827999; // K_t
|
|---|
| 157 |
|
|---|
| 158 | E = D;
|
|---|
| 159 | D = C;
|
|---|
| 160 | C = B << 30 | B >>> 2; // S^30(B)
|
|---|
| 161 | B = A;
|
|---|
| 162 | A = TEMP;
|
|---|
| 163 | }
|
|---|
| 164 |
|
|---|
| 165 | for (int t = 20; t < 40; ++ t)
|
|---|
| 166 | {
|
|---|
| 167 | int TEMP = (A << 5 | A >>> 27) // S^5(A)
|
|---|
| 168 | + (B ^ C ^ D) // f_t(B,C,D)
|
|---|
| 169 | + E + W[t]
|
|---|
| 170 | + 0x6ed9eba1; // K_t
|
|---|
| 171 |
|
|---|
| 172 | E = D;
|
|---|
| 173 | D = C;
|
|---|
| 174 | C = B << 30 | B >>> 2; // S^30(B)
|
|---|
| 175 | B = A;
|
|---|
| 176 | A = TEMP;
|
|---|
| 177 | }
|
|---|
| 178 |
|
|---|
| 179 | for (int t = 40; t < 60; ++ t)
|
|---|
| 180 | {
|
|---|
| 181 | int TEMP = (A << 5 | A >>> 27) // S^5(A)
|
|---|
| 182 | + (B & C | B & D | C & D) // f_t(B,C,D)
|
|---|
| 183 | + E + W[t]
|
|---|
| 184 | + 0x8f1bbcdc; // K_t
|
|---|
| 185 |
|
|---|
| 186 | E = D;
|
|---|
| 187 | D = C;
|
|---|
| 188 | C = B << 30 | B >>> 2; // S^30(B)
|
|---|
| 189 | B = A;
|
|---|
| 190 | A = TEMP;
|
|---|
| 191 | }
|
|---|
| 192 |
|
|---|
| 193 | for (int t = 60; t < 80; ++ t)
|
|---|
| 194 | {
|
|---|
| 195 | int TEMP = (A << 5 | A >>> 27) // S^5(A)
|
|---|
| 196 | + (B ^ C ^ D) // f_t(B,C,D)
|
|---|
| 197 | + E + W[t]
|
|---|
| 198 | + 0xca62c1d6; // K_t
|
|---|
| 199 |
|
|---|
| 200 | E = D;
|
|---|
| 201 | D = C;
|
|---|
| 202 | C = B << 30 | B >>> 2; // S^30(B)
|
|---|
| 203 | B = A;
|
|---|
| 204 | A = TEMP;
|
|---|
| 205 | }
|
|---|
| 206 |
|
|---|
| 207 | H0 += A;
|
|---|
| 208 | H1 += B;
|
|---|
| 209 | H2 += C;
|
|---|
| 210 | H3 += D;
|
|---|
| 211 | H4 += E;
|
|---|
| 212 |
|
|---|
| 213 | // Reset W by clearing it.
|
|---|
| 214 | for (int t = 0; t < 80; ++ t)
|
|---|
| 215 | W[t] = 0;
|
|---|
| 216 | }
|
|---|
| 217 |
|
|---|
| 218 | public Object clone ()
|
|---|
| 219 | {
|
|---|
| 220 | return new SHA (this);
|
|---|
| 221 | }
|
|---|
| 222 |
|
|---|
| 223 | private SHA (SHA copy)
|
|---|
| 224 | {
|
|---|
| 225 | this ();
|
|---|
| 226 | bytecount = copy.bytecount;
|
|---|
| 227 | H0 = copy.H0;
|
|---|
| 228 | H1 = copy.H1;
|
|---|
| 229 | H2 = copy.H2;
|
|---|
| 230 | H3 = copy.H3;
|
|---|
| 231 | H4 = copy.H4;
|
|---|
| 232 | System.arraycopy (copy.W, 0, W, 0, 80);
|
|---|
| 233 | }
|
|---|
| 234 |
|
|---|
| 235 | private final int W[] = new int[80];
|
|---|
| 236 | private long bytecount;
|
|---|
| 237 | private int H0;
|
|---|
| 238 | private int H1;
|
|---|
| 239 | private int H2;
|
|---|
| 240 | private int H3;
|
|---|
| 241 | private int H4;
|
|---|
| 242 | }
|
|---|