PageRenderTime 114ms CodeModel.GetById 48ms app.highlight 52ms RepoModel.GetById 1ms app.codeStats 1ms

/lib/phpseclib/Crypt/Blowfish.php

https://github.com/floviolleau/Raspcontrol
PHP | 1468 lines | 980 code | 88 blank | 400 comment | 118 complexity | 6532278087028f910bc2f5bb55748e12 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1<?php
   2/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
   3
   4/**
   5 * Pure-PHP implementation of Blowfish.
   6 *
   7 * Uses mcrypt, if available, and an internal implementation, otherwise.
   8 *
   9 * PHP versions 4 and 5
  10 *
  11 * Useful resources are as follows:
  12 *
  13 *  - {@link http://en.wikipedia.org/wiki/Blowfish Wikipedia description of Blowfish}
  14 *
  15 * Here's a short example of how to use this library:
  16 * <code>
  17 * <?php
  18 *    include('Crypt/Blowfish.php');
  19 *
  20 *    $blowfish = new Crypt_Blowfish();
  21 *
  22 *    $blowfish->setKey('12345678901234567890123456789012');
  23 *
  24 *    $plaintext = str_repeat('a', 1024);
  25 *
  26 *    echo $blowfish->decrypt($blowfish->encrypt($plaintext));
  27 * ?>
  28 * </code>
  29 *
  30 * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
  31 * of this software and associated documentation files (the "Software"), to deal
  32 * in the Software without restriction, including without limitation the rights
  33 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  34 * copies of the Software, and to permit persons to whom the Software is
  35 * furnished to do so, subject to the following conditions:
  36 *
  37 * The above copyright notice and this permission notice shall be included in
  38 * all copies or substantial portions of the Software.
  39 *
  40 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  41 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  42 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  43 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  44 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  45 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  46 * THE SOFTWARE.
  47 *
  48 * @category   Crypt
  49 * @package    Crypt_Blowfish
  50 * @author     Jim Wigginton <terrafrost@php.net>
  51 * @author     Hans-Juergen Petrich <petrich@tronic-media.com>
  52 * @copyright  MMVII Jim Wigginton
  53 * @license    http://www.opensource.org/licenses/mit-license.html  MIT License
  54 * @version    1.0
  55 * @link       http://phpseclib.sourceforge.net
  56 */
  57
  58/**#@+
  59 * @access public
  60 * @see Crypt_Blowfish::encrypt()
  61 * @see Crypt_Blowfish::decrypt()
  62 */
  63/**
  64 * Encrypt / decrypt using the Counter mode.
  65 *
  66 * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
  67 *
  68 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
  69 */
  70define('CRYPT_BLOWFISH_MODE_CTR', -1);
  71/**
  72 * Encrypt / decrypt using the Electronic Code Book mode.
  73 *
  74 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
  75 */
  76define('CRYPT_BLOWFISH_MODE_ECB', 1);
  77/**
  78 * Encrypt / decrypt using the Code Book Chaining mode.
  79 *
  80 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
  81 */
  82define('CRYPT_BLOWFISH_MODE_CBC', 2);
  83/**
  84 * Encrypt / decrypt using the Cipher Feedback mode.
  85 *
  86 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
  87 */
  88define('CRYPT_BLOWFISH_MODE_CFB', 3);
  89/**
  90 * Encrypt / decrypt using the Cipher Feedback mode.
  91 *
  92 * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
  93 */
  94define('CRYPT_BLOWFISH_MODE_OFB', 4);
  95/**#@-*/
  96
  97/**#@+
  98 * @access private
  99 * @see Crypt_Blowfish::Crypt_Blowfish()
 100 */
 101/**
 102 * Toggles the internal implementation
 103 */
 104define('CRYPT_BLOWFISH_MODE_INTERNAL', 1);
 105/**
 106 * Toggles the mcrypt implementation
 107 */
 108define('CRYPT_BLOWFISH_MODE_MCRYPT', 2);
 109/**#@-*/
 110
 111/**
 112 * Pure-PHP implementation of Blowfish.
 113 *
 114 * @author  Jim Wigginton <terrafrost@php.net>
 115 * @author  Hans-Juergen Petrich <petrich@tronic-media.com>
 116 * @version 1.0
 117 * @access  public
 118 * @package Crypt_Blowfish
 119 */
 120class Crypt_Blowfish {
 121    /**
 122     * The Key as String
 123     *
 124     * @see Crypt_Blowfish::setKey()
 125     * @var Array
 126     * @access private
 127     */
 128    var $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
 129
 130    /**
 131     * The Encryption Mode
 132     *
 133     * @see Crypt_Blowfish::Crypt_Blowfish()
 134     * @var Integer
 135     * @access private
 136     */
 137    var $mode;
 138
 139    /**
 140     * Continuous Buffer status
 141     *
 142     * @see Crypt_Blowfish::enableContinuousBuffer()
 143     * @var Boolean
 144     * @access private
 145     */
 146    var $continuousBuffer = false;
 147
 148    /**
 149     * Padding status
 150     *
 151     * @see Crypt_Blowfish::enablePadding()
 152     * @var Boolean
 153     * @access private
 154     */
 155    var $padding = true;
 156
 157    /**
 158     * The Initialization Vector
 159     *
 160     * @see Crypt_Blowfish::setIV()
 161     * @var String
 162     * @access private
 163     */
 164    var $iv = "\0\0\0\0\0\0\0\0";
 165
 166    /**
 167     * A "sliding" Initialization Vector
 168     *
 169     * @see Crypt_Blowfish::enableContinuousBuffer()
 170     * @var String
 171     * @access private
 172     */
 173    var $encryptIV = "\0\0\0\0\0\0\0\0";
 174
 175    /**
 176     * A "sliding" Initialization Vector
 177     *
 178     * @see Crypt_Blowfish::enableContinuousBuffer()
 179     * @var String
 180     * @access private
 181     */
 182    var $decryptIV = "\0\0\0\0\0\0\0\0";
 183
 184    /**
 185     * mcrypt resource for encryption
 186     *
 187     * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
 188     * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
 189     *
 190     * @see Crypt_Blowfish::encrypt()
 191     * @var String
 192     * @access private
 193     */
 194    var $enmcrypt;
 195
 196    /**
 197     * mcrypt resource for decryption
 198     *
 199     * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
 200     * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
 201     *
 202     * @see Crypt_Blowfish::decrypt()
 203     * @var String
 204     * @access private
 205     */
 206    var $demcrypt;
 207
 208    /**
 209     * Does the enmcrypt resource need to be (re)initialized?
 210     *
 211     * @see Crypt_Blowfish::setKey()
 212     * @see Crypt_Blowfish::setIV()
 213     * @var Boolean
 214     * @access private
 215     */
 216    var $enchanged = true;
 217
 218    /**
 219     * Does the demcrypt resource need to be (re)initialized?
 220     *
 221     * @see Crypt_Blowfish::setKey()
 222     * @see Crypt_Blowfish::setIV()
 223     * @var Boolean
 224     * @access private
 225     */
 226    var $dechanged = true;
 227
 228    /**
 229     * Is the mode one that is paddable?
 230     *
 231     * @see Crypt_Blowfish::Crypt_Blowfish()
 232     * @var Boolean
 233     * @access private
 234     */
 235    var $paddable = false;
 236
 237    /**
 238     * Encryption buffer for CTR, OFB and CFB modes
 239     *
 240     * @see Crypt_Blowfish::encrypt()
 241     * @var Array
 242     * @access private
 243     */
 244    var $enbuffer = array('encrypted' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);
 245
 246    /**
 247     * Decryption buffer for CTR, OFB and CFB modes
 248     *
 249     * @see Crypt_Blowfish::decrypt()
 250     * @var Array
 251     * @access private
 252     */
 253    var $debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'demcrypt_init' => true);
 254
 255    /**
 256     * mcrypt resource for CFB mode
 257     *
 258     * @see Crypt_Blowfish::encrypt()
 259     * @see Crypt_Blowfish::decrypt()
 260     * @var String
 261     * @access private
 262     */
 263    var $ecb;
 264
 265    /**
 266     * Performance-optimized callback function for en/decrypt()
 267     *
 268     * @var Callback
 269     * @access private
 270     */
 271    var $inline_crypt;
 272
 273    /**
 274     * The fixed subkeys boxes ($sbox0 - $sbox3) with 256 entries each
 275     *
 276     * S-Box 1
 277     *
 278     * @access private
 279     * @var    array
 280     */
 281    var $sbox0 = array (
 282        0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
 283        0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
 284        0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
 285        0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
 286        0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
 287        0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
 288        0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
 289        0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
 290        0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
 291        0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
 292        0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
 293        0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
 294        0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
 295        0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
 296        0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
 297        0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
 298        0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
 299        0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
 300        0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
 301        0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
 302        0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
 303        0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
 304        0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
 305        0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
 306        0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
 307        0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
 308        0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
 309        0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
 310        0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
 311        0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
 312        0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
 313        0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
 314    );
 315
 316    /**
 317     * S-Box 1
 318     *
 319     * @access private
 320     * @var    array
 321     */
 322    var $sbox1 = array(
 323        0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
 324        0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
 325        0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
 326        0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
 327        0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
 328        0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
 329        0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
 330        0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
 331        0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
 332        0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
 333        0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
 334        0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
 335        0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
 336        0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
 337        0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
 338        0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
 339        0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
 340        0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
 341        0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
 342        0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
 343        0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
 344        0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
 345        0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
 346        0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
 347        0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
 348        0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
 349        0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
 350        0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
 351        0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
 352        0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
 353        0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
 354        0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
 355    );
 356
 357    /**
 358     * S-Box 2
 359     *
 360     * @access private
 361     * @var    array
 362     */
 363    var $sbox2 = array(
 364        0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
 365        0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
 366        0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
 367        0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
 368        0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
 369        0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
 370        0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
 371        0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
 372        0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
 373        0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
 374        0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
 375        0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
 376        0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
 377        0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
 378        0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
 379        0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
 380        0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
 381        0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
 382        0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
 383        0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
 384        0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
 385        0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
 386        0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
 387        0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
 388        0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
 389        0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
 390        0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
 391        0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
 392        0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
 393        0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
 394        0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
 395        0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
 396    );
 397
 398    /**
 399     * S-Box 3
 400     *
 401     * @access private
 402     * @var    array
 403     */
 404    var $sbox3 = array(
 405        0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
 406        0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
 407        0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
 408        0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
 409        0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
 410        0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
 411        0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
 412        0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
 413        0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
 414        0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
 415        0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
 416        0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
 417        0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
 418        0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
 419        0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
 420        0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
 421        0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
 422        0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
 423        0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
 424        0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
 425        0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
 426        0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
 427        0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
 428        0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
 429        0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
 430        0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
 431        0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
 432        0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
 433        0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
 434        0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
 435        0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
 436        0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
 437    );
 438
 439    /**
 440     * P-Array consists of 18 32-bit subkeys
 441     *
 442     * @var array $parray
 443     * @access private
 444     */
 445    var $parray = array(
 446        0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0,
 447        0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
 448        0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b
 449    );
 450
 451    /**
 452     * The BCTX-working Array
 453     *
 454     * Holds the expanded key [p] and the key-depended s-boxes [sb]
 455     *
 456     * @var array $bctx
 457     * @access private
 458     */
 459    var $bctx = array();
 460
 461    /**
 462     * Default Constructor.
 463     *
 464     * Determines whether or not the mcrypt extension should be used.
 465     * If not explictly set, CRYPT_BLOWFISH_MODE_CBC will be used.
 466     *
 467     * @param optional Integer $mode
 468     * @access public
 469     */
 470    function Crypt_Blowfish($mode = CRYPT_BLOWFISH_MODE_CBC)
 471    {
 472        if ( !defined('CRYPT_BLOWFISH_MODE') ) {
 473            switch (true) {
 474                case extension_loaded('mcrypt') && in_array('blowfish', mcrypt_list_algorithms()):
 475                    define('CRYPT_BLOWFISH_MODE', CRYPT_BLOWFISH_MODE_MCRYPT);
 476                    break;
 477                default:
 478                    define('CRYPT_BLOWFISH_MODE', CRYPT_BLOWFISH_MODE_INTERNAL);
 479            }
 480        }
 481
 482        switch ( CRYPT_BLOWFISH_MODE ) {
 483            case CRYPT_BLOWFISH_MODE_MCRYPT:
 484                switch ($mode) {
 485                    case CRYPT_BLOWFISH_MODE_ECB:
 486                        $this->paddable = true;
 487                        $this->mode = MCRYPT_MODE_ECB;
 488                        break;
 489                    case CRYPT_BLOWFISH_MODE_CTR:
 490                        $this->mode = 'ctr';
 491                        break;
 492                    case CRYPT_BLOWFISH_MODE_CFB:
 493                        $this->mode = 'ncfb';
 494                        $this->ecb = mcrypt_module_open(MCRYPT_BLOWFISH, '', MCRYPT_MODE_ECB, '');
 495                        break;
 496                    case CRYPT_BLOWFISH_MODE_OFB:
 497                        $this->mode = MCRYPT_MODE_NOFB;
 498                        break;
 499                    case CRYPT_BLOWFISH_MODE_CBC:
 500                    default:
 501                        $this->paddable = true;
 502                        $this->mode = MCRYPT_MODE_CBC;
 503                }
 504                $this->enmcrypt = mcrypt_module_open(MCRYPT_BLOWFISH, '', $this->mode, '');
 505                $this->demcrypt = mcrypt_module_open(MCRYPT_BLOWFISH, '', $this->mode, '');
 506
 507                break;
 508            default:
 509                switch ($mode) {
 510                    case CRYPT_BLOWFISH_MODE_ECB:
 511                    case CRYPT_BLOWFISH_MODE_CBC:
 512                        $this->paddable = true;
 513                        $this->mode = $mode;
 514                        break;
 515                    case CRYPT_BLOWFISH_MODE_CTR:
 516                    case CRYPT_BLOWFISH_MODE_CFB:
 517                    case CRYPT_BLOWFISH_MODE_OFB:
 518                        $this->mode = $mode;
 519                        break;
 520                    default:
 521                        $this->paddable = true;
 522                        $this->mode = CRYPT_BLOWFISH_MODE_CBC;
 523                }
 524                $this->inline_crypt_setup();
 525        }
 526    }
 527
 528    /**
 529     * Sets the key.
 530     *
 531     * Keys can be of any length.  Blowfish, itself, requires the use of a key between 32 and max. 448-bits long.
 532     * If the key is less than 32-bits we NOT fill the key to 32bit but let the key as it is to be compatible
 533     * with mcrypt because mcrypt act this way with blowfish key's < 32 bits.
 534     *
 535     * If the key is more than 448-bits, we trim the excess bits.
 536     *
 537     * If the key is not explicitly set, or empty, it'll be assumed a 128 bits key to be all null bytes.
 538     *
 539     * @access public
 540     * @param String $key
 541     */
 542    function setKey($key)
 543    {
 544        $keylength = strlen($key);
 545
 546        if (!$keylength) {
 547            $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
 548        }
 549        elseif ($keylength > 56) {
 550            $key = substr($key, 0, 56);
 551        }
 552
 553        $this->key = $key;
 554
 555        $this->enchanged = true;
 556        $this->dechanged = true;
 557
 558        if (CRYPT_BLOWFISH_MODE == CRYPT_BLOWFISH_MODE_MCRYPT) {
 559            return;
 560        }
 561
 562        /* key-expanding p[] and S-Box building sb[] */
 563        $this->bctx = array(
 564            'p'  => array(),
 565            'sb' => array(
 566                $this->sbox0,
 567                $this->sbox1,
 568                $this->sbox2,
 569                $this->sbox3
 570            )
 571        );
 572
 573        // unpack binary string in unsigned chars
 574        $key  = array_values(unpack('C*', $key));
 575        $keyl = count($key);
 576        for ($j = 0, $i = 0; $i < 18; ++$i) {
 577            // xor P1 with the first 32-bits of the key, xor P2 with the second 32-bits ...
 578            for ($data = 0, $k = 0; $k < 4; ++$k) {
 579                $data = ($data << 8) | $key[$j];
 580                if (++$j >= $keyl) {
 581                    $j = 0;
 582                }
 583            }
 584            $this->bctx['p'][] = $this->parray[$i] ^ $data;
 585        }
 586
 587        // encrypt the zero-string, replace P1 and P2 with the encrypted data,
 588        // encrypt P3 and P4 with the new P1 and P2, do it with all P-array and subkeys
 589        $datal = 0;
 590        $datar = 0;
 591        for ($i = 0; $i < 18; $i += 2) {
 592            $this->_encryptBlock($datal, $datar);
 593            $this->bctx['p'][$i    ] = $datal;
 594            $this->bctx['p'][$i + 1] = $datar;
 595        }
 596        for ($i = 0; $i < 4; ++$i) {
 597            for ($j = 0; $j < 256; $j += 2) {
 598                $this->_encryptBlock($datal, $datar);
 599                $this->bctx['sb'][$i][$j    ] = $datal;
 600                $this->bctx['sb'][$i][$j + 1] = $datar;
 601            }
 602        }
 603    }
 604
 605    /**
 606     * Encrypt the block.
 607     *
 608     * @access private
 609     * @param  int $Xl left  uInt32 part of the block
 610     * @param  int $Xr right uInt32 part of the block
 611     * @return void
 612     */
 613    function _encryptBlock(&$Xl, &$Xr)
 614    {
 615        $p = $this->bctx['p'];
 616        $sb_0 = $this->bctx['sb'][0];
 617        $sb_1 = $this->bctx['sb'][1];
 618        $sb_2 = $this->bctx['sb'][2];
 619        $sb_3 = $this->bctx['sb'][3];
 620        $l = $Xl;
 621        $r = $Xr;
 622
 623        $i = -1;
 624        while ($i < 15) {
 625            $l^= $p[++$i];
 626            $r^= ($sb_0[$l >> 24 & 0xff]  +
 627                  $sb_1[$l >> 16 & 0xff]  ^
 628                  $sb_2[$l >>  8 & 0xff]) +
 629                  $sb_3[$l       & 0xff];
 630
 631            $r^= $p[++$i];
 632            $l^= ($sb_0[$r >> 24 & 0xff]  +
 633                  $sb_1[$r >> 16 & 0xff]  ^
 634                  $sb_2[$r >>  8 & 0xff]) +
 635                  $sb_3[$r       & 0xff];
 636
 637        }
 638        $Xr = $l ^ $p[16];
 639        $Xl = $r ^ $p[17];
 640    }
 641
 642    /**
 643     * Sets the password.
 644     *
 645     * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows:
 646     *     {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2}:
 647     *         $hash, $salt, $count
 648     *
 649     * @param String $password
 650     * @param optional String $method
 651     * @access public
 652     */
 653    function setPassword($password, $method = 'pbkdf2')
 654    {
 655        $key = '';
 656
 657        switch ($method) {
 658            default: // 'pbkdf2'
 659                list(, , $hash, $salt, $count) = func_get_args();
 660                if (!isset($hash)) {
 661                    $hash = 'sha1';
 662                }
 663                // WPA and WPA2 use the SSID as the salt
 664                if (!isset($salt)) {
 665                    $salt = 'phpseclib/salt';
 666                }
 667                // RFC2898#section-4.2 uses 1,000 iterations by default
 668                // WPA and WPA2 use 4,096.
 669                if (!isset($count)) {
 670                    $count = 1000;
 671                }
 672
 673                if (!class_exists('Crypt_Hash')) {
 674                    require_once('Crypt/Hash.php');
 675                }
 676
 677                $i = 1;
 678                while (strlen($key) < 56) {
 679                    //$dk.= $this->_pbkdf($password, $salt, $count, $i++);
 680                    $hmac = new Crypt_Hash();
 681                    $hmac->setHash($hash);
 682                    $hmac->setKey($password);
 683                    $f = $u = $hmac->hash($salt . pack('N', $i++));
 684                    for ($j = 2; $j <= $count; $j++) {
 685                        $u = $hmac->hash($u);
 686                        $f^= $u;
 687                    }
 688                    $key.= $f;
 689                }
 690        }
 691
 692        $this->setKey($key);
 693    }
 694
 695    /**
 696     * Sets the initialization vector. (optional)
 697     *
 698     * SetIV is not required when CRYPT_BLOWFISH_MODE_ECB is being used.  If not explictly set, it'll be assumed
 699     * to be all null bytes.
 700     *
 701     * @access public
 702     * @param String $iv
 703     */
 704    function setIV($iv)
 705    {
 706        $this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($iv, 0, 8), 8, chr(0));
 707        $this->enchanged = true;
 708        $this->dechanged = true;
 709    }
 710
 711    /**
 712     * Encrypts a message.
 713     *
 714     * $plaintext will be padded with up to 8 additional bytes.  Other Blowfish implementations may or may not pad in the
 715     * same manner.  Other common approaches to padding and the reasons why it's necessary are discussed in the following
 716     * URL:
 717     *
 718     * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
 719     *
 720     * An alternative to padding is to, separately, send the length of the file.  This is what SSH, in fact, does.
 721     * strlen($plaintext) will still need to be a multiple of 8, however, arbitrary values can be added to make it that
 722     * length.
 723     *
 724     * @see Crypt_Blowfish::decrypt()
 725     * @access public
 726     * @param String $plaintext
 727     */
 728    function encrypt($plaintext)
 729    {
 730        if ( CRYPT_BLOWFISH_MODE == CRYPT_BLOWFISH_MODE_MCRYPT ) {
 731            if ($this->paddable) {
 732                $plaintext = $this->_pad($plaintext);
 733            }
 734
 735            if ($this->enchanged) {
 736                mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
 737                if ($this->mode == 'ncfb') {
 738                    mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0");
 739                }
 740                $this->enchanged = false;
 741            }
 742
 743            if ($this->mode != 'ncfb' || !$this->continuousBuffer) {
 744                $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
 745            } else {
 746                $iv = &$this->encryptIV;
 747                $pos = &$this->enbuffer['pos'];
 748                $len = strlen($plaintext);
 749                $ciphertext = '';
 750                $i = 0;
 751                if ($pos) {
 752                    $orig_pos = $pos;
 753                    $max = 8 - $pos;
 754                    if ($len >= $max) {
 755                        $i = $max;
 756                        $len-= $max;
 757                        $pos = 0;
 758                    } else {
 759                        $i = $len;
 760                        $pos+= $len;
 761                        $len = 0;
 762                    }
 763                    $ciphertext = substr($iv, $orig_pos) ^ $plaintext;
 764                    $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
 765                    $this->enbuffer['enmcrypt_init'] = true;
 766                }
 767                if ($len >= 8) {
 768                    if ($this->enbuffer['enmcrypt_init'] === false || $len > 600) {
 769                        if ($this->enbuffer['enmcrypt_init'] === true) {
 770                            mcrypt_generic_init($this->enmcrypt, $this->key, $iv);
 771                            $this->enbuffer['enmcrypt_init'] = false;
 772                        }
 773                        $ciphertext.= mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % 8));
 774                        $iv = substr($ciphertext, -8);
 775                        $len%= 8;
 776                    } else {
 777                        while ($len >= 8) {
 778                            $iv = mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, 8);
 779                            $ciphertext.= $iv;
 780                            $len-= 8;
 781                            $i+= 8;
 782                        }
 783                    }
 784                }
 785                if ($len) {
 786                    $iv = mcrypt_generic($this->ecb, $iv);
 787                    $block = $iv ^ substr($plaintext, -$len);
 788                    $iv = substr_replace($iv, $block, 0, $len);
 789                    $ciphertext.= $block;
 790                    $pos = $len;
 791                }
 792                return $ciphertext;
 793            }
 794
 795            if (!$this->continuousBuffer) {
 796                mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
 797            }
 798
 799            return $ciphertext;
 800        }
 801
 802        if (empty($this->bctx)) {
 803            $this->setKey($this->key);
 804        }
 805
 806        $inline = $this->inline_crypt;
 807        return $inline('encrypt', $this, $plaintext);
 808    }
 809
 810    /**
 811     * Decrypts a message.
 812     *
 813     * If strlen($ciphertext) is not a multiple of 8, null bytes will be added to the end of the string until it is.
 814     *
 815     * @see Crypt_Blowfish::encrypt()
 816     * @access public
 817     * @param String $ciphertext
 818     */
 819    function decrypt($ciphertext)
 820    {
 821        if ( CRYPT_BLOWFISH_MODE == CRYPT_BLOWFISH_MODE_MCRYPT ) {
 822            if ($this->paddable) {
 823                // we pad with chr(0) since that's what mcrypt_generic does.  to quote from http://php.net/function.mcrypt-generic :
 824                // "The data is padded with "\0" to make sure the length of the data is n * blocksize."
 825                $ciphertext = str_pad($ciphertext, strlen($ciphertext) + (8 - strlen($ciphertext) % 8) % 8, chr(0));
 826            }
 827
 828            if ($this->dechanged) {
 829                mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
 830                if ($this->mode == 'ncfb') {
 831                    mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0");
 832                }
 833                $this->dechanged = false;
 834            }
 835
 836            if ($this->mode != 'ncfb' || !$this->continuousBuffer) {
 837                $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
 838            } else {
 839                $iv = &$this->decryptIV;
 840                $pos = &$this->debuffer['pos'];
 841                $len = strlen($ciphertext);
 842                $plaintext = '';
 843                $i = 0;
 844                if ($pos) {
 845                    $orig_pos = $pos;
 846                    $max = 8 - $pos;
 847                    if ($len >= $max) {
 848                        $i = $max;
 849                        $len-= $max;
 850                        $pos = 0;
 851                    } else {
 852                        $i = $len;
 853                        $pos+= $len;
 854                        $len = 0;
 855                    }
 856                    $plaintext = substr($iv, $orig_pos) ^ $ciphertext;
 857                    $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
 858                }
 859                if ($len >= 8) {
 860                    $cb = substr($ciphertext, $i, $len - $len % 8);
 861                    $plaintext.= mcrypt_generic($this->ecb, $iv . $cb) ^ $cb;
 862                    $iv = substr($cb, -8);
 863                    $len%= 8;
 864                }
 865                if ($len) {
 866                    $iv = mcrypt_generic($this->ecb, $iv);
 867                    $plaintext.= $iv ^ substr($ciphertext, -$len);
 868                    $iv = substr_replace($iv, substr($ciphertext, -$len), 0, $len);
 869                    $pos = $len;
 870                }
 871                return $plaintext;
 872            }
 873
 874            if (!$this->continuousBuffer) {
 875                mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
 876            }
 877
 878            return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
 879        }
 880
 881        if (empty($this->bctx)) {
 882            $this->setKey($this->key);
 883        }
 884
 885        $inline = $this->inline_crypt;
 886        return $inline('decrypt', $this, $ciphertext);
 887    }
 888
 889    /**
 890     * Treat consecutive "packets" as if they are a continuous buffer.
 891     *
 892     * @see Crypt_Blowfish::disableContinuousBuffer()
 893     * @access public
 894     */
 895    function enableContinuousBuffer()
 896    {
 897        $this->continuousBuffer = true;
 898    }
 899
 900    /**
 901     * Treat consecutive packets as if they are a discontinuous buffer.
 902     *
 903     * The default behavior.
 904     *
 905     * @see Crypt_Blowfish::enableContinuousBuffer()
 906     * @access public
 907     */
 908    function disableContinuousBuffer()
 909    {
 910        $this->continuousBuffer = false;
 911        $this->encryptIV = $this->iv;
 912        $this->decryptIV = $this->iv;
 913        $this->enbuffer = array('encrypted' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);
 914        $this->debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'demcrypt_init' => true);
 915
 916        if (CRYPT_BLOWFISH_MODE == CRYPT_BLOWFISH_MODE_MCRYPT) {
 917            mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv);
 918            mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);
 919        }
 920    }
 921
 922    /**
 923     * Pad "packets".
 924     *
 925     * Blowfish works by encrypting 8 bytes at a time.  If you ever need to encrypt or decrypt something that's not
 926     * a multiple of 8, it becomes necessary to pad the input so that it's length is a multiple of eight.
 927     *
 928     * Padding is enabled by default.  Sometimes, however, it is undesirable to pad strings.  Such is the case in SSH1,
 929     * where "packets" are padded with random bytes before being encrypted.  Unpad these packets and you risk stripping
 930     * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is
 931     * transmitted separately)
 932     *
 933     * @see Crypt_Blowfish::disablePadding()
 934     * @access public
 935     */
 936    function enablePadding()
 937    {
 938        $this->padding = true;
 939    }
 940
 941    /**
 942     * Do not pad packets.
 943     *
 944     * @see Crypt_Blowfish::enablePadding()
 945     * @access public
 946     */
 947    function disablePadding()
 948    {
 949        $this->padding = false;
 950    }
 951
 952    /**
 953     * Pads a string
 954     *
 955     * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize (8).
 956     *
 957     * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless
 958     * and padding will, hence forth, be enabled.
 959     *
 960     * @see Crypt_Blowfish::_unpad()
 961     * @access private
 962     */
 963    function _pad($text)
 964    {
 965        $length = strlen($text);
 966
 967        if (!$this->padding) {
 968            if ($length % 8 == 0) {
 969                return $text;
 970            } else {
 971                user_error("The plaintext's length ($length) is not a multiple of the block size (8)");
 972                $this->padding = true;
 973            }
 974        }
 975
 976        $pad = 8 - ($length % 8);
 977
 978        return str_pad($text, $length + $pad, chr($pad));
 979    }
 980
 981    /**
 982     * Unpads a string
 983     *
 984     * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong
 985     * and false will be returned.
 986     *
 987     * @see Crypt_Blowfish::_pad()
 988     * @access private
 989     */
 990    function _unpad($text)
 991    {
 992        if (!$this->padding) {
 993            return $text;
 994        }
 995
 996        $length = ord($text[strlen($text) - 1]);
 997
 998        if (!$length || $length > 8) {
 999            return false;
1000        }
1001
1002        return substr($text, 0, -$length);
1003    }
1004
1005    /**
1006     * String Shift
1007     *
1008     * Inspired by array_shift
1009     *
1010     * @param String $string
1011     * @return String
1012     * @access private
1013     */
1014    function _string_shift(&$string)
1015    {
1016        $substr = substr($string, 0, 8);
1017        $string = substr($string, 8);
1018        return $substr;
1019    }
1020
1021    /**
1022     * Generate CTR XOR encryption key
1023     *
1024     * Encrypt the output of this and XOR it against the ciphertext / plaintext to get the
1025     * plaintext / ciphertext in CTR mode.
1026     *
1027     * @see Crypt_Blowfish::decrypt()
1028     * @see Crypt_Blowfish::encrypt()
1029     * @access public
1030     * @param String $iv
1031     */
1032    function _generate_xor(&$iv)
1033    {
1034        $xor = $iv;
1035        for ($j = 4; $j <= 8; $j+=4) {
1036            $temp = substr($iv, -$j, 4);
1037            switch ($temp) {
1038                case "\xFF\xFF\xFF\xFF":
1039                    $iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4);
1040                    break;
1041                case "\x7F\xFF\xFF\xFF":
1042                    $iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4);
1043                    break 2;
1044                default:
1045                    extract(unpack('Ncount', $temp));
1046                    $iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);
1047                    break 2;
1048            }
1049        }
1050
1051        return $xor;
1052    }
1053
1054    /**
1055     * Creates performance-optimized function for de/encrypt(), storing it in $this->inline_crypt
1056     *
1057     * @access private
1058     */
1059    function inline_crypt_setup()
1060    {/*{{{*/
1061        $lambda_functions =& Crypt_Blowfish::get_lambda_functions();
1062        $block_size = 8;
1063        $mode = $this->mode;
1064        $code_hash = "$mode";
1065
1066        if (!isset($lambda_functions[$code_hash])) {
1067            $init_cryptBlock = '
1068                extract($self->bctx["p"],  EXTR_PREFIX_ALL, "p");
1069                extract($self->bctx["sb"], EXTR_PREFIX_ALL, "sb");
1070            ';
1071
1072            // Generating encrypt code:
1073            $_encryptBlock = '
1074                $in = unpack("N*", $in);
1075                $l = $in[1];
1076                $r = $in[2];
1077            ';
1078            for ($i = 0; $i < 16; $i+= 2) {
1079                $_encryptBlock.= '
1080                    $l^= $p_'.($i).';
1081                    $r^= ($sb_0[$l >> 24 & 0xff]  +
1082                          $sb_1[$l >> 16 & 0xff]  ^
1083                          $sb_2[$l >>  8 & 0xff]) +
1084                          $sb_3[$l       & 0xff];
1085
1086                    $r^= $p_'.($i + 1).';
1087                    $l^= ($sb_0[$r >> 24 & 0xff]  +
1088                          $sb_1[$r >> 16 & 0xff]  ^
1089                          $sb_2[$r >>  8 & 0xff]) +
1090                          $sb_3[$r       & 0xff];
1091                ';
1092            }
1093            $_encryptBlock.= '
1094                $in = pack("N*", $r ^ $p_17, $l ^ $p_16);
1095            ';
1096
1097            // Generating decrypt code:
1098            $_decryptBlock = '
1099                $in = unpack("N*", $in);
1100                $l = $in[1];
1101                $r = $in[2];
1102            ';
1103
1104            for ($i = 17; $i > 2; $i-= 2) {
1105                $_decryptBlock.= '
1106                    $l^= $p_'.($i).';
1107                    $r^= ($sb_0[$l >> 24 & 0xff]  +
1108                          $sb_1[$l >> 16 & 0xff]  ^
1109                          $sb_2[$l >>  8 & 0xff]) +
1110                          $sb_3[$l       & 0xff];
1111
1112                    $r^= $p_'.($i - 1).';
1113                    $l^= ($sb_0[$r >> 24 & 0xff]  +
1114                          $sb_1[$r >> 16 & 0xff]  ^
1115                          $sb_2[$r >>  8 & 0xff]) +
1116                          $sb_3[$r       & 0xff];
1117                ';
1118            }
1119
1120            $_decryptBlock.= '
1121                $in = pack("N*", $r ^ $p_0, $l ^ $p_1);
1122            ';
1123
1124            // Generating mode of operation code:
1125            switch ($mode) {
1126                case CRYPT_BLOWFISH_MODE_ECB:
1127                    $encrypt = '
1128                        $ciphertext = "";
1129                        $text = $self->_pad($text);
1130                        $plaintext_len = strlen($text);
1131
1132                        for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
1133                            $in = substr($text, $i, '.$block_size.');
1134                            '.$_encryptBlock.'
1135                            $ciphertext.= $in;
1136                        }
1137                        return $ciphertext;
1138                        ';
1139
1140                    $decrypt = '
1141                        $plaintext = "";
1142                        $text = str_pad($text, strlen($text) + ('.$block_size.' - strlen($text) % '.$block_size.') % '.$block_size.', chr(0));
1143                        $ciphertext_len = strlen($text);
1144
1145                        for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
1146                            $in = substr($text, $i, '.$block_size.');
1147                            '.$_decryptBlock.'
1148                            $plaintext.= $in;
1149                        }
1150
1151                        return $self->_unpad($plaintext);
1152                        ';
1153                    break;
1154                case CRYPT_BLOWFISH_MODE_CBC:
1155                    $encrypt = '
1156                        $ciphertext = "";
1157                        $text = $self->_pad($text);
1158                        $plaintext_len = strlen($text);
1159
1160                        $in = $self->encryptIV;
1161
1162                        for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
1163                            $in = substr($text, $i, '.$block_size.') ^ $in;
1164                            '.$_encryptBlock.'
1165                            $ciphertext.= $in;
1166                        }
1167
1168                        if ($self->continuousBuffer) {
1169                            $self->encryptIV = $in;
1170                        }
1171
1172                        return $ciphertext;
1173                        ';
1174
1175                    $decrypt = '
1176                        $plaintext = "";
1177                        $text = str_pad($text, strlen($text) + ('.$block_size.' - strlen($text) % '.$block_size.') % '.$block_size.', chr(0));
1178                        $ciphertext_len = strlen($text);
1179
1180                        $iv = $self->decryptIV;
1181
1182                        for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
1183                            $in = $block = substr($text, $i, '.$block_size.');
1184                            '.$_decryptBlock.'
1185                            $plaintext.= $in ^ $iv;
1186                            $iv = $block;
1187                        }
1188
1189                        if ($self->continuousBuffer) {
1190                            $self->decryptIV = $iv;
1191                        }
1192
1193                        return $self->_unpad($plaintext);
1194                        ';
1195                    break;
1196                case CRYPT_BLOWFISH_MODE_CTR:
1197                    $encrypt = '
1198                        $ciphertext = "";
1199                        $plaintext_len = strlen($text);
1200                        $xor = $self->encryptIV;
1201                        $buffer = &$self->enbuffer;
1202
1203                        if (strlen($buffer["encrypted"])) {
1204                            for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
1205                                $block = substr($text, $i, '.$block_size.');
1206                                if (strlen($block) > strlen($buffer["encrypted"])) {
1207                                    $in = $self->_generate_xor($xor);
1208                                    '.$_encryptBlock.'
1209                                    $buffer["encrypted"].= $in;
1210                                }
1211                                $key = $self->_string_shift($buffer["encrypted"]);
1212                                $ciphertext.= $block ^ $key;
1213                            }
1214                        } else {
1215                            for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
1216                                $block = substr($text, $i, '.$block_size.');
1217                                $in = $self->_generate_xor($xor);
1218                                '.$_encryptBlock.'
1219                                $key = $in;
1220                                $ciphertext.= $block ^ $key;
1221                            }
1222                        }
1223                        if ($self->continuousBuffer) {
1224                            $self->encryptIV = $xor;
1225                            if ($start = $plaintext_len % '.$block_size.') {
1226                                $buffer["encrypted"] = substr($key, $start) . $buffer["encrypted"];
1227                            }
1228                        }
1229
1230                        return $ciphertext;
1231                    ';
1232
1233                    $decrypt = '
1234                        $plaintext = "";
1235                        $ciphertext_len = strlen($text);
1236                        $xor = $self->decryptIV;
1237                        $buffer = &$self->debuffer;
1238
1239                        if (strlen($buffer["ciphertext"])) {
1240                            for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
1241                                $block = substr($text, $i, '.$block_size.');
1242                                if (strlen($block) > strlen($buffer["ciphertext"])) {
1243                                    $in = $self->_generate_xor($xor);
1244                                    '.$_encryptBlock.'
1245                                    $buffer["ciphertext"].= $in;
1246                                }
1247                                $key = $self->_string_shift($buffer["ciphertext"]);
1248  

Large files files are truncated, but you can click here to view the full file