001    package railo.runtime.crypt;
002    
003    //package maddany.crypto;
004    
005    
006    
007    /*   Coding by maddany@madloutre.org
008    
009     *   01-01-2000
010    
011     *
012    
013     *   This program is free software; you can redistribute it and/or modify
014    
015     *   it under the terms of the GNU General Public License as published by
016    
017     *   the Free Software Foundation; either version 2 of the License, or
018    
019     *   (at your option) any later version.
020    
021     *
022    
023     *   This program is distributed in the hope that it will be useful,
024    
025     *   but WITHOUT ANY WARRANTY; without even the implied warranty of
026    
027     *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
028    
029     *   GNU General Public License for more details.
030    
031     *
032    
033     *   You should have received a copy of the GNU General Public License
034    
035     *   along with this program; if not, write to the Free Software
036    
037     *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
038    
039     *
040    
041     */
042    
043    
044    
045    
046    public final class BlowfishCBC extends BlowfishECB {
047      // here we hold the CBC IV
048      long m_lCBCIV;
049      /**
050        * get the current CBC IV (for cipher resets)
051        * @return current CBC IV
052        */
053    
054      public long getCBCIV() {
055        return m_lCBCIV;
056      };
057      /**
058        * get the current CBC IV (for cipher resets)
059        * @param dest wher eto put current CBC IV in network byte ordered array
060        */
061      public void getCBCIV(byte[] dest) {
062        BinConverter.longToByteArray(m_lCBCIV, dest, 0);
063      };
064    
065      /**
066        * set the current CBC IV (for cipher resets)
067        * @param lNewCBCIV the new CBC IV
068        */
069      public void setCBCIV(long lNewCBCIV) {
070        m_lCBCIV = lNewCBCIV;
071      };
072    
073    
074    
075      /**
076    
077        * set the current CBC IV (for cipher resets)
078    
079        * @param newCBCIV the new CBC IV  in network byte ordered array
080    
081        */
082    
083      public void setCBCIV(byte[] newCBCIV) {
084    
085        m_lCBCIV = BinConverter.byteArrayToLong(newCBCIV, 0);
086    
087      };
088    
089    
090    
091    
092    
093    
094    
095    
096    
097      /**
098    
099        * constructor, stores a zero CBC IV
100    
101        * @param bfkey key material, up to MAXKEYLENGTH bytes
102    
103        */
104    
105      public BlowfishCBC(byte[] bfkey) {
106    
107    
108    
109        super(bfkey);
110    
111        // store zero CBCB IV
112    
113        setCBCIV(0);
114    
115      };
116    
117    
118    
119    
120    
121      /**
122    
123        * constructor
124    
125        * @param bfkey key material, up to MAXKEYLENGTH bytes
126    
127        * @param lInitCBCIV the CBC IV
128    
129        */
130    
131      public BlowfishCBC(byte[] bfkey,
132    
133                         long lInitCBCIV) {
134    
135    
136    
137        super(bfkey);
138    
139        // store the CBCB IV
140    
141        setCBCIV(lInitCBCIV);
142    
143      };
144    
145    
146    
147    
148    
149      /**
150    
151        * constructor
152    
153        * @param bfkey key material, up to MAXKEYLENGTH bytes
154    
155        * @param lInitCBCIV the CBC IV (array with min. BLOCKSIZE bytes)
156    
157        */
158    
159      public BlowfishCBC(byte[] bfkey,
160    
161                         byte[] initCBCIV) {
162    
163    
164    
165        super(bfkey);
166    
167        // store the CBCB IV
168    
169        setCBCIV(initCBCIV);
170    
171      };
172    
173    
174    
175    
176    
177      /**
178    
179        * cleans up all critical internals,
180    
181        * call this if you don't need an instance anymore
182    
183        */
184    
185      public void cleanUp() {
186    
187    
188    
189        m_lCBCIV = 0;
190    
191        super.cleanUp();
192    
193      };
194    
195    
196    
197    
198    
199      // internal routine to encrypt a block in CBC mode
200    
201      protected long encryptBlock(long lPlainblock) {
202    
203    
204    
205        // chain with the CBC IV
206    
207        lPlainblock ^= m_lCBCIV;
208    
209        // encrypt the block
210    
211        lPlainblock = super.encryptBlock(lPlainblock);
212    
213        // the encrypted block is the new CBC IV
214    
215        return (m_lCBCIV = lPlainblock);
216    
217      };
218    
219    
220    
221    
222    
223      // internal routine to decrypt a block in CBC mode
224    
225      protected long decryptBlock(long lCipherblock) {
226    
227    
228    
229        // save the current block
230    
231        long lTemp = lCipherblock;
232    
233        // decrypt the block
234    
235        lCipherblock = super.decryptBlock(lCipherblock);
236    
237        // dechain the block
238    
239        lCipherblock ^= m_lCBCIV;
240    
241        // set the new CBC IV
242    
243        m_lCBCIV = lTemp;
244    
245        // return the decrypted block
246    
247        return lCipherblock;
248    
249      };
250    
251    
252    
253    
254    
255    
256    
257      /**
258    
259        * encrypts a byte buffer (should be aligned to an 8 byte border)
260    
261        * to another buffer (of the same size or bigger)
262    
263        * @param inbuffer buffer with plaintext data
264    
265        * @param outbuffer buffer to get the ciphertext data
266    
267        */
268    
269      public void encrypt(byte[] inbuffer,
270    
271                          byte[] outbuffer) {
272    
273    
274    
275        int nLen = inbuffer.length;
276    
277        long lTemp;
278    
279        for (int nI = 0; nI < nLen; nI +=8) {
280    
281    
282    
283          // encrypt a temporary 64bit block
284    
285          lTemp = BinConverter.byteArrayToLong(inbuffer, nI);
286    
287          lTemp = encryptBlock(lTemp);
288    
289          BinConverter.longToByteArray(lTemp, outbuffer, nI);
290    
291        };
292    
293      };
294    
295    
296    
297    
298    
299    
300    
301      /**
302    
303        * encrypts a byte buffer (should be aligned to an 8 byte border) to itself
304    
305        * @param buffer buffer to encrypt
306    
307        */
308    
309      public void encrypt(byte[] buffer) {
310    
311    
312    
313        int nLen = buffer.length;
314    
315        long lTemp;
316    
317        for (int nI = 0; nI < nLen; nI +=8) {
318    
319    
320    
321          // encrypt a temporary 64bit block
322    
323          lTemp = BinConverter.byteArrayToLong(buffer, nI);
324    
325          lTemp = encryptBlock(lTemp);
326    
327          BinConverter.longToByteArray(lTemp, buffer, nI);
328    
329        };
330    
331      };
332    
333    
334    
335    
336    
337    
338    
339    
340    
341      /**
342    
343        * encrypts an int buffer (should be aligned to an
344    
345        * two integer border) to another int buffer (of the same
346    
347        * size or bigger)
348    
349        * @param inbuffer buffer with plaintext data
350    
351        * @param outBuffer buffer to get the ciphertext data
352    
353        */
354    
355      public void encrypt(int[] inbuffer,
356    
357                          int[] outbuffer) {
358    
359    
360    
361        int nLen = inbuffer.length;
362    
363        long lTemp;
364    
365        for (int nI = 0; nI < nLen; nI +=2) {
366    
367    
368    
369          // encrypt a temporary 64bit block
370    
371          lTemp = BinConverter.intArrayToLong(inbuffer, nI);
372    
373          lTemp = encryptBlock(lTemp);
374    
375          BinConverter.longToIntArray(lTemp, outbuffer, nI);
376    
377        };
378    
379      };
380    
381    
382    
383    
384    
385      /**
386    
387        * encrypts an integer buffer (should be aligned to an
388    
389        * @param buffer buffer to encrypt
390    
391        */
392    
393      public void encrypt(int[] buffer) {
394    
395    
396    
397        int nLen = buffer.length;
398    
399        long lTemp;
400    
401        for (int nI = 0; nI < nLen; nI +=2) {
402    
403    
404    
405          // encrypt a temporary 64bit block
406    
407          lTemp = BinConverter.intArrayToLong(buffer, nI);
408    
409          lTemp = encryptBlock(lTemp);
410    
411          BinConverter.longToIntArray(lTemp, buffer, nI);
412    
413        };
414    
415      };
416    
417    
418    
419    
420    
421    
422    
423      /**
424    
425        * encrypts a long buffer to another long buffer (of the same size or bigger)
426    
427        * @param inbuffer buffer with plaintext data
428    
429        * @param outbuffer buffer to get the ciphertext data
430    
431        */
432    
433      public void encrypt(long[] inbuffer,
434    
435                          long[] outbuffer) {
436    
437    
438    
439        int nLen = inbuffer.length;
440    
441        for (int nI = 0; nI < nLen; nI++)
442    
443          outbuffer[nI] = encryptBlock(inbuffer[nI]);
444    
445      };
446    
447    
448    
449    
450    
451    
452    
453      /**
454    
455        * encrypts a long buffer to itself
456    
457        * @param buffer buffer to encrypt
458    
459        */
460    
461      public void encrypt(long[] buffer) {
462    
463    
464    
465        int nLen = buffer.length;
466    
467        for (int nI = 0; nI < nLen; nI++) {
468    
469          buffer[nI] = encryptBlock(buffer[nI]);
470    
471        };
472    
473      };
474    
475    
476    
477    
478    
479    
480    
481      /**
482    
483        * decrypts a byte buffer (should be aligned to an 8 byte border)
484    
485        * to another buffer (of the same size or bigger)
486    
487        * @param inbuffer buffer with ciphertext data
488    
489        * @param outBuffer buffer to get the plaintext data
490    
491        */
492    
493      public void decrypt(byte[] inbuffer,
494    
495                          byte[] outbuffer) {
496    
497    
498    
499        int nLen = inbuffer.length;
500    
501        long lTemp;
502    
503        for (int nI = 0; nI < nLen; nI +=8) {
504    
505    
506    
507          // decrypt a temporary 64bit block
508    
509          lTemp = BinConverter.byteArrayToLong(inbuffer, nI);
510    
511          lTemp = decryptBlock(lTemp);
512    
513          BinConverter.longToByteArray(lTemp, outbuffer, nI);
514    
515        };
516    
517      };
518    
519    
520    
521    
522    
523    
524    
525      /**
526    
527        * decrypts a byte buffer (should be aligned to an 8 byte border) to itself
528    
529        * @param buffer buffer to decrypt
530    
531        */
532    
533      public void  decrypt(byte[] buffer) {
534    
535    
536    
537        int nLen = buffer.length;
538    
539        long lTemp;
540    
541        for (int nI = 0; nI < nLen; nI +=8) {
542    
543    
544    
545          // decrypt over a temporary 64bit block
546    
547          lTemp = BinConverter.byteArrayToLong(buffer, nI);
548    
549          lTemp = decryptBlock(lTemp);
550    
551          BinConverter.longToByteArray(lTemp, buffer, nI);
552    
553        };
554    
555      };
556    
557    
558    
559    
560    
561    
562    
563    
564    
565      /**
566    
567        * decrypts an integer buffer (should be aligned to an
568    
569        * two integer border) to another int buffer (of the same size or bigger)
570    
571        * @param inbuffer buffer with ciphertext data
572    
573        * @param outbuffer buffer to get the plaintext data
574    
575        */
576    
577      public void decrypt(int[] inbuffer,
578    
579                          int[] outbuffer) {
580    
581    
582    
583        int nLen = inbuffer.length;
584    
585        long lTemp;
586    
587        for (int nI = 0; nI < nLen; nI +=2) {
588    
589    
590    
591          // decrypt a temporary 64bit block
592    
593          lTemp = BinConverter.intArrayToLong(inbuffer, nI);
594    
595          lTemp = decryptBlock(lTemp);
596    
597          BinConverter.longToIntArray(lTemp, outbuffer, nI);
598    
599        };
600    
601      };
602    
603    
604    
605    
606    
607      /**
608    
609        * decrypts an int buffer (should be aligned to a
610    
611        * two integer border)
612    
613        * @param buffer buffer to decrypt
614    
615        */
616    
617      public void decrypt(int[] buffer) {
618    
619    
620    
621        int nLen = buffer.length;
622    
623        long lTemp;
624    
625        for (int nI = 0; nI < nLen; nI +=2) {
626    
627    
628    
629          // decrypt a temporary 64bit block
630    
631          lTemp = BinConverter.intArrayToLong(buffer, nI);
632    
633          lTemp = decryptBlock(lTemp);
634    
635          BinConverter.longToIntArray(lTemp, buffer, nI);
636    
637        };
638    
639      };
640    
641    
642    
643    
644    
645    
646    
647      /**
648    
649        * decrypts a long buffer to another long buffer (of the same size or bigger)
650    
651        * @param inbuffer buffer with ciphertext data
652    
653        * @param outbuffer buffer to get the plaintext data
654    
655        */
656    
657      public void decrypt(long[] inbuffer,
658    
659                          long[] outbuffer) {
660    
661    
662    
663        int nLen = inbuffer.length;
664    
665        for (int nI = 0; nI < nLen; nI++)
666    
667          outbuffer[nI] = decryptBlock(inbuffer[nI]);
668    
669      };
670    
671    
672    
673    
674    
675    
676    
677      /**
678    
679        * decrypts a long buffer to itself
680    
681        * @param buffer buffer to decrypt
682    
683        */
684    
685      public void decrypt(long[] buffer) {
686    
687    
688    
689        int nLen = buffer.length;
690    
691        for (int nI = 0; nI < nLen; nI++)
692    
693          buffer[nI] = decryptBlock(buffer[nI]);
694    
695      };
696    
697    
698    
699    
700    
701    };