001    package railo.runtime.crypt;
002    
003    public final class SHA1 {
004    
005    
006    
007         
008    
009        /** size of a SHA-1 digest in octets */
010    
011        public final static int DIGEST_SIZE = 20;
012    
013    
014    
015    
016    
017        // members
018    
019        private int[]  m_state;
020    
021        private long   m_lCount;
022    
023        private byte[] m_digestBits;
024    
025        private int[]  m_block;
026    
027        private int    m_nBlockIndex;
028    
029    
030    
031    
032    
033        /**
034    
035          * constructor
036    
037          */
038    
039        public SHA1() {
040    
041          m_state = new int[5];
042    
043          m_block = new int[16];
044    
045          m_digestBits = new byte[DIGEST_SIZE];
046    
047          reset(); 
048    
049        };
050    
051    
052    
053    
054    
055        /**
056    
057          * clears all data, use reset() to start again
058    
059          */
060    
061        public void clear() {
062    
063          int nI;
064    
065          for (nI = 0; nI < m_state.length; nI++) 
066    
067            m_state[nI] = 0;
068    
069          m_lCount = 0;
070    
071          for (nI = 0; nI < m_digestBits.length; nI++) 
072    
073            m_digestBits[nI] = 0;
074    
075          for (nI = 0; nI < m_block.length; nI++) 
076    
077            m_block[nI] = 0;
078    
079          m_nBlockIndex = 0;
080    
081        };  
082    
083     
084    
085    
086    
087    
088    
089        // some helper methods...
090    
091    
092    
093        final int rol(int nValue,
094    
095                     int nBits) {
096    
097    
098    
099          return ((nValue << nBits) | (nValue >>> (32 - nBits)));
100    
101        };
102    
103    
104    
105        final int blk0(int nI) {
106    
107          return (m_block[nI] = (rol(m_block[nI],24) & 0xff00ff00) | 
108    
109                                (rol(m_block[nI], 8) & 0x00ff00ff));
110    
111        };
112    
113    
114    
115        final int blk(int nI) {
116    
117          return (m_block[nI & 15] = rol(m_block[(nI +  13) & 15] ^ m_block[(nI + 8) & 15] ^
118    
119                                         m_block[(nI + 2) & 15] ^ m_block[nI & 15], 1));
120    
121        };
122    
123    
124    
125        final void r0(int data[],
126    
127                      int nV,
128    
129                      int nW, 
130    
131                      int nX ,
132    
133                      int nY,
134    
135                      int nZ,
136    
137                      int nI) {
138    
139          data[nZ] += ((data[nW] & (data[nX] ^ data[nY])) ^ data[nY]) +
140    
141                      blk0(nI) + 
142    
143                      0x5a827999 +
144    
145                      rol(data[nV] ,5);
146    
147          data[nW] = rol(data[nW], 30);
148    
149        };
150    
151    
152    
153        final void r1(int data[], 
154    
155                      int nV, 
156    
157                      int nW,
158    
159                      int nX, 
160    
161                      int nY, 
162    
163                      int nZ,
164    
165                      int nI) {
166    
167          data[nZ] += ((data[nW] & (data[nX] ^ data[nY])) ^ data[nY]) +
168    
169                      blk(nI) +
170    
171                      0x5a827999 + 
172    
173                      rol(data[nV] ,5);
174    
175          data[nW] = rol(data[nW], 30);
176    
177        };
178    
179    
180    
181        final void r2(int data[], 
182    
183                      int nV, 
184    
185                      int nW,
186    
187                      int nX, 
188    
189                      int nY, 
190    
191                      int nZ,
192    
193                      int nI) {
194    
195          data[nZ] += (data[nW] ^ data[nX] ^ data[nY]) +
196    
197                      blk(nI) +
198    
199                      0x6eD9eba1 +
200    
201                      rol(data[nV] ,5);
202    
203          data[nW] = rol(data[nW], 30);
204    
205        };
206    
207    
208    
209        final void r3(int data[], 
210    
211                      int nV, 
212    
213                      int nW,
214    
215                      int nX, 
216    
217                      int nY, 
218    
219                      int nZ,
220    
221                      int nI) {
222    
223          data[nZ] += (((data[nW] | data[nX]) & data[nY]) | (data[nW] & data[nX])) +
224    
225                      blk(nI) +
226    
227                      0x8f1bbcdc +
228    
229                      rol(data[nV] ,5);
230    
231          data[nW] = rol(data[nW], 30);
232    
233        };
234    
235    
236    
237        final void r4(int data[], 
238    
239                      int nV, 
240    
241                      int nW,
242    
243                      int nX, 
244    
245                      int nY, 
246    
247                      int nZ,
248    
249                      int nI) {
250    
251          data[nZ] += (data[nW] ^ data[nX] ^ data[nY]) +
252    
253                      blk(nI) +
254    
255                      0xca62c1d6 +
256    
257                      rol(data[nV] ,5);
258    
259          data[nW] = rol(data[nW], 30);
260    
261        };
262    
263    
264    
265        void transform() {
266    
267              
268    
269            int[] dd = new int[5];
270    
271            dd[0] = m_state[0];
272    
273            dd[1] = m_state[1];
274    
275            dd[2] = m_state[2];
276    
277            dd[3] = m_state[3];
278    
279            dd[4] = m_state[4];
280    
281            r0(dd, 0, 1, 2, 3, 4, 0); r0(dd, 4, 0, 1, 2, 3, 1);
282    
283            r0(dd, 3, 4, 0, 1, 2, 2); r0(dd, 2, 3, 4, 0, 1, 3);
284    
285            r0(dd, 1, 2, 3, 4, 0, 4); r0(dd, 0, 1, 2, 3, 4, 5);
286    
287            r0(dd, 4, 0, 1, 2, 3, 6); r0(dd, 3, 4, 0, 1, 2, 7);
288    
289            r0(dd, 2, 3, 4, 0, 1, 8); r0(dd, 1, 2, 3, 4, 0, 9);
290    
291            r0(dd, 0, 1, 2, 3, 4, 10); r0(dd, 4, 0, 1, 2, 3, 11);
292    
293            r0(dd, 3, 4, 0, 1, 2, 12); r0(dd, 2, 3, 4, 0, 1, 13);
294    
295            r0(dd, 1, 2, 3, 4, 0, 14); r0(dd, 0, 1, 2, 3, 4, 15);
296    
297            r1(dd, 4, 0, 1, 2, 3, 16); r1(dd, 3, 4, 0, 1, 2, 17);
298    
299            r1(dd, 2, 3, 4, 0, 1, 18); r1(dd, 1, 2, 3, 4, 0, 19);
300    
301            r2(dd, 0, 1, 2, 3, 4, 20); r2(dd, 4, 0, 1, 2, 3, 21); 
302    
303            r2(dd, 3, 4, 0, 1, 2, 22); r2(dd, 2, 3, 4, 0, 1, 23);
304    
305            r2(dd, 1, 2, 3, 4, 0, 24); r2(dd, 0, 1, 2, 3, 4, 25);
306    
307            r2(dd, 4, 0, 1, 2, 3, 26); r2(dd, 3, 4, 0, 1, 2, 27);
308    
309            r2(dd, 2, 3, 4, 0, 1, 28); r2(dd, 1, 2, 3, 4, 0, 29); 
310    
311            r2(dd, 0, 1, 2, 3, 4, 30); r2(dd, 4, 0, 1, 2, 3, 31);
312    
313            r2(dd, 3, 4, 0, 1, 2, 32); r2(dd, 2, 3, 4, 0, 1, 33); 
314    
315            r2(dd, 1, 2, 3, 4, 0, 34); r2(dd, 0, 1, 2, 3, 4, 35);
316    
317            r2(dd, 4, 0, 1, 2, 3, 36); r2(dd, 3, 4, 0, 1, 2, 37); 
318    
319            r2(dd, 2, 3, 4, 0, 1, 38); r2(dd, 1, 2, 3, 4, 0, 39);
320    
321            r3(dd, 0, 1, 2, 3, 4, 40); r3(dd, 4, 0, 1, 2, 3, 41); 
322    
323            r3(dd, 3, 4, 0, 1, 2, 42); r3(dd, 2, 3, 4, 0, 1, 43);
324    
325            r3(dd, 1, 2, 3, 4, 0, 44); r3(dd, 0, 1, 2, 3, 4, 45); 
326    
327            r3(dd, 4, 0, 1, 2, 3, 46); r3(dd, 3, 4, 0, 1, 2, 47);
328    
329            r3(dd, 2, 3, 4, 0, 1, 48); r3(dd, 1, 2, 3, 4, 0, 49); 
330    
331            r3(dd, 0, 1, 2, 3, 4, 50); r3(dd, 4, 0, 1, 2, 3, 51);
332    
333            r3(dd, 3, 4, 0, 1, 2, 52); r3(dd, 2, 3, 4, 0, 1, 53); 
334    
335            r3(dd, 1, 2, 3, 4, 0, 54); r3(dd, 0, 1, 2, 3, 4, 55);
336    
337            r3(dd, 4, 0, 1, 2, 3, 56); r3(dd, 3, 4, 0, 1, 2, 57); 
338    
339            r3(dd, 2, 3, 4, 0, 1, 58); r3(dd, 1, 2, 3, 4, 0, 59);
340    
341            r4(dd, 0, 1, 2, 3, 4, 60); r4(dd, 4, 0, 1, 2, 3, 61); 
342    
343            r4(dd, 3, 4, 0, 1, 2, 62); r4(dd, 2, 3, 4, 0, 1, 63);
344    
345            r4(dd, 1, 2, 3, 4, 0, 64); r4(dd, 0, 1, 2, 3, 4, 65); 
346    
347            r4(dd, 4, 0, 1, 2, 3, 66); r4(dd, 3, 4, 0, 1, 2, 67);
348    
349            r4(dd, 2, 3, 4, 0, 1, 68); r4(dd, 1, 2, 3, 4, 0, 69); 
350    
351            r4(dd, 0, 1, 2, 3, 4, 70); r4(dd, 4, 0, 1, 2, 3, 71);
352    
353            r4(dd, 3, 4, 0, 1, 2, 72); r4(dd, 2, 3, 4, 0, 1, 73); 
354    
355            r4(dd, 1, 2, 3, 4, 0, 74); r4(dd, 0, 1, 2, 3, 4, 75);
356    
357            r4(dd, 4, 0, 1, 2, 3, 76); r4(dd, 3, 4, 0, 1, 2, 77); 
358    
359            r4(dd, 2, 3, 4, 0, 1, 78); r4(dd, 1, 2, 3, 4, 0, 79);
360    
361            m_state[0] += dd[0];
362    
363            m_state[1] += dd[1];
364    
365            m_state[2] += dd[2];
366    
367            m_state[3] += dd[3];
368    
369            m_state[4] += dd[4];
370    
371        }
372    
373    
374    
375    
376    
377        /**
378    
379          * initializes or resets the hasher for a new session respectively
380    
381          */
382    
383        public void reset() {
384    
385    
386    
387          m_state[0] = 0x67452301;
388    
389          m_state[1] = 0xefcdab89;
390    
391          m_state[2] = 0x98badcfe;
392    
393          m_state[3] = 0x10325476;
394    
395          m_state[4] = 0xc3d2e1f0;
396    
397          m_lCount = 0;
398    
399          m_digestBits = new byte[20];
400    
401          m_nBlockIndex = 0;
402    
403        };
404    
405    
406    
407    
408    
409        /**
410    
411          * adds a single byte to the digest
412    
413          */
414    
415        public void update(byte bB) {
416    
417    
418    
419            int nMask = (m_nBlockIndex & 3) << 3;
420    
421    
422    
423            m_lCount += 8;
424    
425            m_block[m_nBlockIndex >> 2] &= ~(0xff << nMask);
426    
427            m_block[m_nBlockIndex >> 2] |= (bB & 0xff) << nMask;
428    
429            m_nBlockIndex++;
430    
431            if (m_nBlockIndex == 64) {
432    
433              transform();
434    
435              m_nBlockIndex = 0;
436    
437            };
438    
439        };
440    
441    
442    
443     
444    
445        /**
446    
447          * adds a byte array to the digest
448    
449          */
450    
451        public void update(byte[] data) {
452    
453         
454    
455          for (int nI = 0; nI < data.length; nI++)
456    
457            update(data[nI]);
458    
459        };
460    
461     
462    
463    
464    
465        /**
466    
467          * adds an ASCII string to the digest
468    
469          */
470    
471        public void update(String sData) {
472    
473         
474    
475          for (int nI = 0; nI < sData.length(); nI++)
476    
477            update((byte)(sData.charAt(nI) & 0x0ff));
478    
479        };
480    
481     
482    
483    
484    
485    
486    
487        /**
488    
489          * finalizes the digest
490    
491          */
492    
493        public void finalize() {
494    
495    
496    
497            int nI;
498    
499            byte bits[] = new byte[8];
500    
501    
502    
503            for (nI = 0; nI < 8; nI++) {
504    
505              bits[nI] = (byte)((m_lCount >>> (((7 - nI) << 3))) & 0xff);
506    
507            };
508    
509    
510    
511            update((byte) 128);
512    
513            while (m_nBlockIndex != 56)
514    
515              update((byte) 0);
516    
517    
518    
519            for (nI = 0; nI < bits.length; nI++)
520    
521              update(bits[nI]);
522    
523    
524    
525            for (nI = 0; nI < 20; nI++) {
526    
527              m_digestBits[nI] = (byte)((m_state[nI >> 2] >> ((3 - (nI & 3)) << 3)) & 0xff);
528    
529            };
530    
531        };
532    
533    
534    
535         
536    
537        /**
538    
539          * gets the digest
540    
541          * @return the digst bytes as an array if DIGEST_SIZE bytes
542    
543          */
544    
545        public byte[] getDigest() {
546    
547    
548    
549           // deliver a _copy_
550    
551           byte[] result = new byte[DIGEST_SIZE];
552    
553           System.arraycopy(m_digestBits, 0, result, 0, DIGEST_SIZE);
554    
555           return result;
556    
557        };
558    
559    
560    
561    
562    
563        // we need this table for the following method
564    
565        private final static String HEXTAB = "0123456789abcdef";
566    
567    
568    
569    
570    
571        /**
572    
573          * makes a binhex string representation of the current digest
574    
575          * @return the string representation
576    
577          */
578    
579        public String toString() {  
580    
581          
582    
583          StringBuffer buf = new StringBuffer(DIGEST_SIZE * 2);       
584    
585    
586    
587          for (int nI = 0; nI < DIGEST_SIZE; nI++) {
588    
589            buf.append(HEXTAB.charAt((m_digestBits[nI] >>> 4) & 0x0f));
590    
591            buf.append(HEXTAB.charAt(m_digestBits[nI] & 0x0f));
592    
593          }; 
594    
595          return buf.toString();
596    
597        }; 
598    
599    
600    
601    
602    
603    
604    
605    
606    
607        // references for the selftest
608    
609    
610    
611        private final static String SELFTEST_MESSAGE =
612    
613          "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
614    
615    
616    
617        private final static byte[] SELFTEST_DIGEST = {
618    
619          (byte)0x84, (byte)0x98, (byte)0x3e, (byte)0x44, (byte)0x1c,
620    
621          (byte)0x3b, (byte)0xd2, (byte)0x6e, (byte)0xba, (byte)0xae,
622    
623          (byte)0x4a, (byte)0xa1, (byte)0xf9, (byte)0x51, (byte)0x29, 
624    
625          (byte)0xE5, (byte)0xe5, (byte)0x46, (byte)0x70, (byte)0xf1 
626    
627        }; 
628    
629    
630    
631    
632    
633        /**
634    
635          * runs a selftest
636    
637          * @return true: selftest passed / false: selftest failed
638    
639          */
640    
641        public boolean selfTest() {
642    
643    
644    
645          SHA1 tester = new SHA1();
646    
647          tester.update(SELFTEST_MESSAGE);
648    
649          tester.finalize();
650    
651          byte[] digest = tester.getDigest(); 
652    
653          tester.clear();
654    
655          for (int nI = 0; nI < DIGEST_SIZE; nI++)
656    
657            if (digest[nI] != SELFTEST_DIGEST[nI])
658    
659              return false;
660    
661        
662    
663          // test passed
664    
665          return true;
666    
667        };   
668    
669    
670    
671    };
672    
673    
674    
675