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 };