1 /* Sha384.java -- 2 Copyright (C) 2003, 2006 Free Software Foundation, Inc. 3 4 This file is a 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 of the License, or (at 9 your option) 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; if not, write to the Free Software 18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 19 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.hash; 40 41 import gnu.java.security.Registry; 42 import gnu.java.security.util.Util; 43 44 /** 45 * Implementation of SHA2-2 [SHA-384] per the IETF Draft Specification. 46 * <p> 47 * References: 48 * <ol> 49 * <li><a href="http://ftp.ipv4.heanet.ie/pub/ietf/internet-drafts/draft-ietf-ipsec-ciph-aes-cbc-03.txt"> 50 * Descriptions of SHA-256, SHA-384, and SHA-512</a>,</li> 51 * <li>http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf</li> 52 * </ol> 53 */ 54 public class Sha384 55 extends BaseHash 56 { 57 private static final long[] k = { 58 0x428a2f98d728ae22L, 0x7137449123ef65cdL, 0xb5c0fbcfec4d3b2fL, 59 0xe9b5dba58189dbbcL, 0x3956c25bf348b538L, 0x59f111f1b605d019L, 60 0x923f82a4af194f9bL, 0xab1c5ed5da6d8118L, 0xd807aa98a3030242L, 61 0x12835b0145706fbeL, 0x243185be4ee4b28cL, 0x550c7dc3d5ffb4e2L, 62 0x72be5d74f27b896fL, 0x80deb1fe3b1696b1L, 0x9bdc06a725c71235L, 63 0xc19bf174cf692694L, 0xe49b69c19ef14ad2L, 0xefbe4786384f25e3L, 64 0x0fc19dc68b8cd5b5L, 0x240ca1cc77ac9c65L, 0x2de92c6f592b0275L, 65 0x4a7484aa6ea6e483L, 0x5cb0a9dcbd41fbd4L, 0x76f988da831153b5L, 66 0x983e5152ee66dfabL, 0xa831c66d2db43210L, 0xb00327c898fb213fL, 67 0xbf597fc7beef0ee4L, 0xc6e00bf33da88fc2L, 0xd5a79147930aa725L, 68 0x06ca6351e003826fL, 0x142929670a0e6e70L, 0x27b70a8546d22ffcL, 69 0x2e1b21385c26c926L, 0x4d2c6dfc5ac42aedL, 0x53380d139d95b3dfL, 70 0x650a73548baf63deL, 0x766a0abb3c77b2a8L, 0x81c2c92e47edaee6L, 71 0x92722c851482353bL, 0xa2bfe8a14cf10364L, 0xa81a664bbc423001L, 72 0xc24b8b70d0f89791L, 0xc76c51a30654be30L, 0xd192e819d6ef5218L, 73 0xd69906245565a910L, 0xf40e35855771202aL, 0x106aa07032bbd1b8L, 74 0x19a4c116b8d2d0c8L, 0x1e376c085141ab53L, 0x2748774cdf8eeb99L, 75 0x34b0bcb5e19b48a8L, 0x391c0cb3c5c95a63L, 0x4ed8aa4ae3418acbL, 76 0x5b9cca4f7763e373L, 0x682e6ff3d6b2b8a3L, 0x748f82ee5defb2fcL, 77 0x78a5636f43172f60L, 0x84c87814a1f0ab72L, 0x8cc702081a6439ecL, 78 0x90befffa23631e28L, 0xa4506cebde82bde9L, 0xbef9a3f7b2c67915L, 79 0xc67178f2e372532bL, 0xca273eceea26619cL, 0xd186b8c721c0c207L, 80 0xeada7dd6cde0eb1eL, 0xf57d4f7fee6ed178L, 0x06f067aa72176fbaL, 81 0x0a637dc5a2c898a6L, 0x113f9804bef90daeL, 0x1b710b35131c471bL, 82 0x28db77f523047d84L, 0x32caab7b40c72493L, 0x3c9ebe0a15c9bebcL, 83 0x431d67c49c100d4cL, 0x4cc5d4becb3e42b6L, 0x597f299cfc657e2aL, 84 0x5fcb6fab3ad6faecL, 0x6c44198c4a475817L }; 85 86 private static final int BLOCK_SIZE = 128; // inner block size in bytes 87 88 private static final String DIGEST0 = 89 "CB00753F45A35E8BB5A03D699AC65007272C32AB0EDED1631A8B605A43FF5BED" 90 + "8086072BA1E7CC2358BAECA134C825A7"; 91 92 private static final long[] w = new long[80]; 93 94 /** caches the result of the correctness test, once executed. */ 95 private static Boolean valid; 96 97 /** 512-bit interim result. */ 98 private long h0, h1, h2, h3, h4, h5, h6, h7; 99 100 /** Trivial 0-arguments constructor. */ Sha384()101 public Sha384() 102 { 103 super(Registry.SHA384_HASH, 48, BLOCK_SIZE); 104 } 105 106 /** 107 * Private constructor for cloning purposes. 108 * 109 * @param md the instance to clone. 110 */ Sha384(Sha384 md)111 private Sha384(Sha384 md) 112 { 113 this(); 114 115 this.h0 = md.h0; 116 this.h1 = md.h1; 117 this.h2 = md.h2; 118 this.h3 = md.h3; 119 this.h4 = md.h4; 120 this.h5 = md.h5; 121 this.h6 = md.h6; 122 this.h7 = md.h7; 123 this.count = md.count; 124 this.buffer = (byte[]) md.buffer.clone(); 125 } 126 G(long hh0, long hh1, long hh2, long hh3, long hh4, long hh5, long hh6, long hh7, byte[] in, int offset)127 public static final long[] G(long hh0, long hh1, long hh2, long hh3, 128 long hh4, long hh5, long hh6, long hh7, 129 byte[] in, int offset) 130 { 131 return sha(hh0, hh1, hh2, hh3, hh4, hh5, hh6, hh7, in, offset); 132 } 133 clone()134 public Object clone() 135 { 136 return new Sha384(this); 137 } 138 transform(byte[] in, int offset)139 protected void transform(byte[] in, int offset) 140 { 141 long[] result = sha(h0, h1, h2, h3, h4, h5, h6, h7, in, offset); 142 h0 = result[0]; 143 h1 = result[1]; 144 h2 = result[2]; 145 h3 = result[3]; 146 h4 = result[4]; 147 h5 = result[5]; 148 h6 = result[6]; 149 h7 = result[7]; 150 } 151 padBuffer()152 protected byte[] padBuffer() 153 { 154 int n = (int)(count % BLOCK_SIZE); 155 int padding = (n < 112) ? (112 - n) : (240 - n); 156 byte[] result = new byte[padding + 16]; 157 // padding is always binary 1 followed by binary 0s 158 result[0] = (byte) 0x80; 159 // save number of bits, casting the long to an array of 8 bytes 160 // TODO: FIX Only ~35 bits of 128 bit counter usable this way 161 long bits = count << 3; 162 padding += 8; 163 result[padding++] = (byte)(bits >>> 56); 164 result[padding++] = (byte)(bits >>> 48); 165 result[padding++] = (byte)(bits >>> 40); 166 result[padding++] = (byte)(bits >>> 32); 167 result[padding++] = (byte)(bits >>> 24); 168 result[padding++] = (byte)(bits >>> 16); 169 result[padding++] = (byte)(bits >>> 8); 170 result[padding ] = (byte) bits; 171 return result; 172 } 173 getResult()174 protected byte[] getResult() 175 { 176 return new byte[] { 177 (byte)(h0 >>> 56), (byte)(h0 >>> 48), (byte)(h0 >>> 40), (byte)(h0 >>> 32), 178 (byte)(h0 >>> 24), (byte)(h0 >>> 16), (byte)(h0 >>> 8), (byte) h0, 179 (byte)(h1 >>> 56), (byte)(h1 >>> 48), (byte)(h1 >>> 40), (byte)(h1 >>> 32), 180 (byte)(h1 >>> 24), (byte)(h1 >>> 16), (byte)(h1 >>> 8), (byte) h1, 181 (byte)(h2 >>> 56), (byte)(h2 >>> 48), (byte)(h2 >>> 40), (byte)(h2 >>> 32), 182 (byte)(h2 >>> 24), (byte)(h2 >>> 16), (byte)(h2 >>> 8), (byte) h2, 183 (byte)(h3 >>> 56), (byte)(h3 >>> 48), (byte)(h3 >>> 40), (byte)(h3 >>> 32), 184 (byte)(h3 >>> 24), (byte)(h3 >>> 16), (byte)(h3 >>> 8), (byte) h3, 185 (byte)(h4 >>> 56), (byte)(h4 >>> 48), (byte)(h4 >>> 40), (byte)(h4 >>> 32), 186 (byte)(h4 >>> 24), (byte)(h4 >>> 16), (byte)(h4 >>> 8), (byte) h4, 187 (byte)(h5 >>> 56), (byte)(h5 >>> 48), (byte)(h5 >>> 40), (byte)(h5 >>> 32), 188 (byte)(h5 >>> 24), (byte)(h5 >>> 16), (byte)(h5 >>> 8), (byte) h5 }; 189 } 190 resetContext()191 protected void resetContext() 192 { 193 // magic SHA-384 initialisation constants 194 h0 = 0xcbbb9d5dc1059ed8L; 195 h1 = 0x629a292a367cd507L; 196 h2 = 0x9159015a3070dd17L; 197 h3 = 0x152fecd8f70e5939L; 198 h4 = 0x67332667ffc00b31L; 199 h5 = 0x8eb44a8768581511L; 200 h6 = 0xdb0c2e0d64f98fa7L; 201 h7 = 0x47b5481dbefa4fa4L; 202 } 203 selfTest()204 public boolean selfTest() 205 { 206 if (valid == null) 207 { 208 Sha384 md = new Sha384(); 209 md.update((byte) 0x61); // a 210 md.update((byte) 0x62); // b 211 md.update((byte) 0x63); // c 212 String result = Util.toString(md.digest()); 213 valid = Boolean.valueOf(DIGEST0.equals(result)); 214 } 215 return valid.booleanValue(); 216 } 217 sha(long hh0, long hh1, long hh2, long hh3, long hh4, long hh5, long hh6, long hh7, byte[] in, int offset)218 private static synchronized final long[] sha(long hh0, long hh1, long hh2, 219 long hh3, long hh4, long hh5, 220 long hh6, long hh7, byte[] in, 221 int offset) 222 { 223 long A = hh0; 224 long B = hh1; 225 long C = hh2; 226 long D = hh3; 227 long E = hh4; 228 long F = hh5; 229 long G = hh6; 230 long H = hh7; 231 long T, T2; 232 int r; 233 for (r = 0; r < 16; r++) 234 w[r] = (long) in[offset++] << 56 235 | ((long) in[offset++] & 0xFF) << 48 236 | ((long) in[offset++] & 0xFF) << 40 237 | ((long) in[offset++] & 0xFF) << 32 238 | ((long) in[offset++] & 0xFF) << 24 239 | ((long) in[offset++] & 0xFF) << 16 240 | ((long) in[offset++] & 0xFF) << 8 241 | ((long) in[offset++] & 0xFF); 242 for (r = 16; r < 80; r++) 243 { 244 T = w[r - 2]; 245 T2 = w[r - 15]; 246 w[r] = (((T >>> 19) | (T << 45)) ^ ((T >>> 61) | (T << 3)) ^ (T >>> 6)) 247 + w[r - 7] 248 + (((T2 >>> 1) | (T2 << 63)) 249 ^ ((T2 >>> 8) | (T2 << 56)) 250 ^ (T2 >>> 7)) 251 + w[r - 16]; 252 } 253 for (r = 0; r < 80; r++) 254 { 255 256 T = H 257 + (((E >>> 14) | (E << 50)) 258 ^ ((E >>> 18) | (E << 46)) 259 ^ ((E >>> 41) | (E << 23))) 260 + ((E & F) ^ ((~E) & G)) + k[r] + w[r]; 261 // T IS INCORRECT SOMEHOW 262 T2 = (((A >>> 28) | (A << 36)) 263 ^ ((A >>> 34) | (A << 30)) 264 ^ ((A >>> 39) | (A << 25))) 265 + ((A & B) ^ (A & C) ^ (B & C)); 266 H = G; 267 G = F; 268 F = E; 269 E = D + T; 270 D = C; 271 C = B; 272 B = A; 273 A = T + T2; 274 } 275 return new long[] { 276 hh0 + A, hh1 + B, hh2 + C, hh3 + D, 277 hh4 + E, hh5 + F, hh6 + G, hh7 + H }; 278 } 279 } 280