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