001: /*
002: * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright
003: * notice. All rights reserved.
004: */
005:
006: package com.tc.object.bytecode;
007:
008: import com.tc.asm.ClassVisitor;
009: import com.tc.asm.commons.SerialVersionUIDAdder;
010:
011: /**
012: * <code>SerialVersionUIDAdder</code> not using JCE API. Using SHA1Digest
013: * implementation from the Bouncy Castle framework.
014: *
015: * @see SerialVersionUIDAdder
016: * @see http://www.bouncycastle.org/
017: */
018: public class SafeSerialVersionUIDAdder extends SerialVersionUIDAdder {
019:
020: public SafeSerialVersionUIDAdder(ClassVisitor cv) {
021: super (cv);
022: }
023:
024: protected byte[] computeSHAdigest(final byte[] value) {
025: return update(value, 0, value.length);
026: }
027:
028: /*
029: * implementation of SHA-1 as outlined in "Handbook of Applied
030: * Cryptography", pages 346 - 349.
031: *
032: * Copyright (c) 2000 - 2006 The Legion Of The Bouncy Castle
033: * (http://www.bouncycastle.org)
034: *
035: * Permission is hereby granted, free of charge, to any person obtaining a
036: * copy of this software and associated documentation files (the
037: * "Software"), to deal in the Software without restriction, including
038: * without limitation the rights to use, copy, modify, merge, publish,
039: * distribute, sublicense, and/or sell copies of the Software, and to permit
040: * persons to whom the Software is furnished to do so, subject to the
041: * following conditions:
042: *
043: * The above copyright notice and this permission notice shall be included
044: * in all copies or substantial portions of the Software.
045: *
046: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
047: * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
048: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
049: * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
050: * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
051: * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
052: * USE OR OTHER DEALINGS IN THE SOFTWARE.
053: */
054:
055: private int H1 = 0x67452301;
056: private int H2 = 0xefcdab89;
057: private int H3 = 0x98badcfe;
058: private int H4 = 0x10325476;
059: private int H5 = 0xc3d2e1f0;
060:
061: private int[] X = new int[80];
062: private int xOff = 0;
063:
064: private byte[] xBuf = new byte[4];
065: private int xBufOff = 0;
066:
067: private long byteCount = 0;
068:
069: private byte[] update(byte[] in, int inOff, int len) {
070: // fill the current word
071: while ((xBufOff != 0) && (len > 0)) {
072: update(in[inOff]);
073:
074: inOff++;
075: len--;
076: }
077:
078: // process whole words.
079: while (len > xBuf.length) {
080: processWord(in, inOff);
081:
082: inOff += xBuf.length;
083: len -= xBuf.length;
084: byteCount += xBuf.length;
085: }
086:
087: // load in the remainder.
088: while (len > 0) {
089: update(in[inOff]);
090:
091: inOff++;
092: len--;
093: }
094:
095: long bitLength = (byteCount << 3);
096:
097: // add the pad bytes.
098: update((byte) 128);
099:
100: while (xBufOff != 0) {
101: update((byte) 0);
102: }
103:
104: processLength(bitLength);
105:
106: processBlock();
107:
108: byte[] out = new byte[20];
109: unpackWord(H1, out, 0);
110: unpackWord(H2, out, 4);
111: unpackWord(H3, out, 8);
112: unpackWord(H4, out, 12);
113: unpackWord(H5, out, 16);
114: return out;
115: }
116:
117: private void update(byte in) {
118: xBuf[xBufOff++] = in;
119:
120: if (xBufOff == xBuf.length) {
121: processWord(xBuf, 0);
122: xBufOff = 0;
123: }
124:
125: byteCount++;
126: }
127:
128: private void processWord(byte[] in, int inOff) {
129: X[xOff++] = (in[inOff] & 0xff) << 24
130: | (in[inOff + 1] & 0xff) << 16
131: | (in[inOff + 2] & 0xff) << 8 | in[inOff + 3] & 0xff;
132:
133: if (xOff == 16) {
134: processBlock();
135: }
136: }
137:
138: private void unpackWord(int word, byte[] out, int outOff) {
139: out[outOff++] = (byte) (word >>> 24);
140: out[outOff++] = (byte) (word >>> 16);
141: out[outOff++] = (byte) (word >>> 8);
142: out[outOff++] = (byte) word;
143: }
144:
145: protected void processLength(long bitLength) {
146: if (xOff > 14) {
147: processBlock();
148: }
149:
150: X[14] = (int) (bitLength >>> 32);
151: X[15] = (int) (bitLength & 0xffffffff);
152: }
153:
154: private static final int Y1 = 0x5a827999;
155: private static final int Y2 = 0x6ed9eba1;
156: private static final int Y3 = 0x8f1bbcdc;
157: private static final int Y4 = 0xca62c1d6;
158:
159: private int f(int u, int v, int w) {
160: return ((u & v) | ((~u) & w));
161: }
162:
163: private int h(int u, int v, int w) {
164: return (u ^ v ^ w);
165: }
166:
167: private int g(int u, int v, int w) {
168: return ((u & v) | (u & w) | (v & w));
169: }
170:
171: protected void processBlock() {
172: // expand 16 word block into 80 word block.
173: for (int i = 16; i < 80; i++) {
174: int t = X[i - 3] ^ X[i - 8] ^ X[i - 14] ^ X[i - 16];
175: X[i] = t << 1 | t >>> 31;
176: }
177:
178: // set up working variables.
179: int A = H1;
180: int B = H2;
181: int C = H3;
182: int D = H4;
183: int E = H5;
184:
185: // round 1
186: int idx = 0;
187:
188: for (int j = 0; j < 4; j++) {
189: // E = rotateLeft(A, 5) + f(B, C, D) + E + X[idx++] + Y1
190: // B = rotateLeft(B, 30)
191: E += (A << 5 | A >>> 27) + f(B, C, D) + X[idx++] + Y1;
192: B = B << 30 | B >>> 2;
193:
194: D += (E << 5 | E >>> 27) + f(A, B, C) + X[idx++] + Y1;
195: A = A << 30 | A >>> 2;
196:
197: C += (D << 5 | D >>> 27) + f(E, A, B) + X[idx++] + Y1;
198: E = E << 30 | E >>> 2;
199:
200: B += (C << 5 | C >>> 27) + f(D, E, A) + X[idx++] + Y1;
201: D = D << 30 | D >>> 2;
202:
203: A += (B << 5 | B >>> 27) + f(C, D, E) + X[idx++] + Y1;
204: C = C << 30 | C >>> 2;
205: }
206:
207: // round 2
208: for (int j = 0; j < 4; j++) {
209: // E = rotateLeft(A, 5) + h(B, C, D) + E + X[idx++] + Y2
210: // B = rotateLeft(B, 30)
211: E += (A << 5 | A >>> 27) + h(B, C, D) + X[idx++] + Y2;
212: B = B << 30 | B >>> 2;
213:
214: D += (E << 5 | E >>> 27) + h(A, B, C) + X[idx++] + Y2;
215: A = A << 30 | A >>> 2;
216:
217: C += (D << 5 | D >>> 27) + h(E, A, B) + X[idx++] + Y2;
218: E = E << 30 | E >>> 2;
219:
220: B += (C << 5 | C >>> 27) + h(D, E, A) + X[idx++] + Y2;
221: D = D << 30 | D >>> 2;
222:
223: A += (B << 5 | B >>> 27) + h(C, D, E) + X[idx++] + Y2;
224: C = C << 30 | C >>> 2;
225: }
226:
227: // round 3
228: for (int j = 0; j < 4; j++) {
229: // E = rotateLeft(A, 5) + g(B, C, D) + E + X[idx++] + Y3
230: // B = rotateLeft(B, 30)
231: E += (A << 5 | A >>> 27) + g(B, C, D) + X[idx++] + Y3;
232: B = B << 30 | B >>> 2;
233:
234: D += (E << 5 | E >>> 27) + g(A, B, C) + X[idx++] + Y3;
235: A = A << 30 | A >>> 2;
236:
237: C += (D << 5 | D >>> 27) + g(E, A, B) + X[idx++] + Y3;
238: E = E << 30 | E >>> 2;
239:
240: B += (C << 5 | C >>> 27) + g(D, E, A) + X[idx++] + Y3;
241: D = D << 30 | D >>> 2;
242:
243: A += (B << 5 | B >>> 27) + g(C, D, E) + X[idx++] + Y3;
244: C = C << 30 | C >>> 2;
245: }
246:
247: // round 4
248: for (int j = 0; j <= 3; j++) {
249: // E = rotateLeft(A, 5) + h(B, C, D) + E + X[idx++] + Y4
250: // B = rotateLeft(B, 30)
251: E += (A << 5 | A >>> 27) + h(B, C, D) + X[idx++] + Y4;
252: B = B << 30 | B >>> 2;
253:
254: D += (E << 5 | E >>> 27) + h(A, B, C) + X[idx++] + Y4;
255: A = A << 30 | A >>> 2;
256:
257: C += (D << 5 | D >>> 27) + h(E, A, B) + X[idx++] + Y4;
258: E = E << 30 | E >>> 2;
259:
260: B += (C << 5 | C >>> 27) + h(D, E, A) + X[idx++] + Y4;
261: D = D << 30 | D >>> 2;
262:
263: A += (B << 5 | B >>> 27) + h(C, D, E) + X[idx++] + Y4;
264: C = C << 30 | C >>> 2;
265: }
266:
267: H1 += A;
268: H2 += B;
269: H3 += C;
270: H4 += D;
271: H5 += E;
272:
273: // reset start of the buffer.
274: xOff = 0;
275: for (int i = 0; i < 16; i++) {
276: X[i] = 0;
277: }
278: }
279:
280: }
|