SSH SFTP Updater Support - Version 0.7.2

Version Description

  • update phpseclib to latest version
Download this release

Release Info

Developer DavidAnderson
Plugin Icon wp plugin SSH SFTP Updater Support
Version 0.7.2
Comparing to
See all releases

Code changes from version 0.7.1 to 0.7.2

phpseclib/Crypt/AES.php CHANGED
@@ -7,17 +7,17 @@
7
  *
8
  * PHP versions 4 and 5
9
  *
10
- * NOTE: Since AES.php is (for compatibility and phpseclib-historical reasons) virtually
11
  * just a wrapper to Rijndael.php you may consider using Rijndael.php instead of
12
  * to save one include_once().
13
  *
14
- * If {@link Crypt_AES::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
15
- * {@link Crypt_AES::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's 136-bits
16
- * it'll be null-padded to 192-bits and 192 bits will be the key length until {@link Crypt_AES::setKey() setKey()}
17
  * is called, again, at which point, it'll be recalculated.
18
  *
19
  * Since Crypt_AES extends Crypt_Rijndael, some functions are available to be called that, in the context of AES, don't
20
- * make a whole lot of sense. {@link Crypt_AES::setBlockLength() setBlockLength()}, for instance. Calling that function,
21
  * however possible, won't do anything (AES has a fixed block length whereas Rijndael has a variable one).
22
  *
23
  * Here's a short example of how to use this library:
@@ -74,8 +74,8 @@ if (!class_exists('Crypt_Rijndael')) {
74
 
75
  /**#@+
76
  * @access public
77
- * @see Crypt_AES::encrypt()
78
- * @see Crypt_AES::decrypt()
79
  */
80
  /**
81
  * Encrypt / decrypt using the Counter mode.
@@ -124,7 +124,7 @@ class Crypt_AES extends Crypt_Rijndael
124
  * The namespace used by the cipher for its constants.
125
  *
126
  * @see Crypt_Base::const_namespace
127
- * @var String
128
  * @access private
129
  */
130
  var $const_namespace = 'AES';
@@ -136,7 +136,7 @@ class Crypt_AES extends Crypt_Rijndael
136
  *
137
  * @see Crypt_Rijndael::setBlockLength()
138
  * @access public
139
- * @param Integer $length
140
  */
141
  function setBlockLength($length)
142
  {
@@ -151,7 +151,7 @@ class Crypt_AES extends Crypt_Rijndael
151
  *
152
  * @see Crypt_Rijndael:setKeyLength()
153
  * @access public
154
- * @param Integer $length
155
  */
156
  function setKeyLength($length)
157
  {
@@ -173,7 +173,7 @@ class Crypt_AES extends Crypt_Rijndael
173
  * @see Crypt_Rijndael:setKey()
174
  * @see setKeyLength()
175
  * @access public
176
- * @param String $key
177
  */
178
  function setKey($key)
179
  {
@@ -183,13 +183,13 @@ class Crypt_AES extends Crypt_Rijndael
183
  $length = strlen($key);
184
  switch (true) {
185
  case $length <= 16:
186
- $this->key_size = 16;
187
  break;
188
  case $length <= 24:
189
- $this->key_size = 24;
190
  break;
191
  default:
192
- $this->key_size = 32;
193
  }
194
  $this->_setEngine();
195
  }
7
  *
8
  * PHP versions 4 and 5
9
  *
10
+ * NOTE: Since AES.php is (for compatibility and phpseclib-historical reasons) virtually
11
  * just a wrapper to Rijndael.php you may consider using Rijndael.php instead of
12
  * to save one include_once().
13
  *
14
+ * If {@link self::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
15
+ * {@link self::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's 136-bits
16
+ * it'll be null-padded to 192-bits and 192 bits will be the key length until {@link self::setKey() setKey()}
17
  * is called, again, at which point, it'll be recalculated.
18
  *
19
  * Since Crypt_AES extends Crypt_Rijndael, some functions are available to be called that, in the context of AES, don't
20
+ * make a whole lot of sense. {@link self::setBlockLength() setBlockLength()}, for instance. Calling that function,
21
  * however possible, won't do anything (AES has a fixed block length whereas Rijndael has a variable one).
22
  *
23
  * Here's a short example of how to use this library:
74
 
75
  /**#@+
76
  * @access public
77
+ * @see self::encrypt()
78
+ * @see self::decrypt()
79
  */
80
  /**
81
  * Encrypt / decrypt using the Counter mode.
124
  * The namespace used by the cipher for its constants.
125
  *
126
  * @see Crypt_Base::const_namespace
127
+ * @var string
128
  * @access private
129
  */
130
  var $const_namespace = 'AES';
136
  *
137
  * @see Crypt_Rijndael::setBlockLength()
138
  * @access public
139
+ * @param int $length
140
  */
141
  function setBlockLength($length)
142
  {
151
  *
152
  * @see Crypt_Rijndael:setKeyLength()
153
  * @access public
154
+ * @param int $length
155
  */
156
  function setKeyLength($length)
157
  {
173
  * @see Crypt_Rijndael:setKey()
174
  * @see setKeyLength()
175
  * @access public
176
+ * @param string $key
177
  */
178
  function setKey($key)
179
  {
183
  $length = strlen($key);
184
  switch (true) {
185
  case $length <= 16:
186
+ $this->key_length = 16;
187
  break;
188
  case $length <= 24:
189
+ $this->key_length = 24;
190
  break;
191
  default:
192
+ $this->key_length = 32;
193
  }
194
  $this->_setEngine();
195
  }
phpseclib/Crypt/Base.php CHANGED
@@ -1,2539 +1,2616 @@
1
- <?php
2
-
3
- /**
4
- * Base Class for all Crypt_* cipher classes
5
- *
6
- * PHP versions 4 and 5
7
- *
8
- * Internally for phpseclib developers:
9
- * If you plan to add a new cipher class, please note following rules:
10
- *
11
- * - The new Crypt_* cipher class should extend Crypt_Base
12
- *
13
- * - Following methods are then required to be overridden/overloaded:
14
- *
15
- * - _encryptBlock()
16
- *
17
- * - _decryptBlock()
18
- *
19
- * - _setupKey()
20
- *
21
- * - All other methods are optional to be overridden/overloaded
22
- *
23
- * - Look at the source code of the current ciphers how they extend Crypt_Base
24
- * and take one of them as a start up for the new cipher class.
25
- *
26
- * - Please read all the other comments/notes/hints here also for each class var/method
27
- *
28
- * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
29
- * of this software and associated documentation files (the "Software"), to deal
30
- * in the Software without restriction, including without limitation the rights
31
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
32
- * copies of the Software, and to permit persons to whom the Software is
33
- * furnished to do so, subject to the following conditions:
34
- *
35
- * The above copyright notice and this permission notice shall be included in
36
- * all copies or substantial portions of the Software.
37
- *
38
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
39
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
40
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
41
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
42
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
43
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
44
- * THE SOFTWARE.
45
- *
46
- * @category Crypt
47
- * @package Crypt_Base
48
- * @author Jim Wigginton <terrafrost@php.net>
49
- * @author Hans-Juergen Petrich <petrich@tronic-media.com>
50
- * @copyright 2007 Jim Wigginton
51
- * @license http://www.opensource.org/licenses/mit-license.html MIT License
52
- * @link http://phpseclib.sourceforge.net
53
- */
54
-
55
- /**#@+
56
- * @access public
57
- * @see Crypt_Base::encrypt()
58
- * @see Crypt_Base::decrypt()
59
- */
60
- /**
61
- * Encrypt / decrypt using the Counter mode.
62
- *
63
- * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
64
- *
65
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
66
- */
67
- define('CRYPT_MODE_CTR', -1);
68
- /**
69
- * Encrypt / decrypt using the Electronic Code Book mode.
70
- *
71
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
72
- */
73
- define('CRYPT_MODE_ECB', 1);
74
- /**
75
- * Encrypt / decrypt using the Code Book Chaining mode.
76
- *
77
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
78
- */
79
- define('CRYPT_MODE_CBC', 2);
80
- /**
81
- * Encrypt / decrypt using the Cipher Feedback mode.
82
- *
83
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
84
- */
85
- define('CRYPT_MODE_CFB', 3);
86
- /**
87
- * Encrypt / decrypt using the Output Feedback mode.
88
- *
89
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
90
- */
91
- define('CRYPT_MODE_OFB', 4);
92
- /**
93
- * Encrypt / decrypt using streaming mode.
94
- */
95
- define('CRYPT_MODE_STREAM', 5);
96
- /**#@-*/
97
-
98
- /**#@+
99
- * @access private
100
- * @see Crypt_Base::Crypt_Base()
101
- * @internal These constants are for internal use only
102
- */
103
- /**
104
- * Base value for the internal implementation $engine switch
105
- */
106
- define('CRYPT_ENGINE_INTERNAL', 1);
107
- /**
108
- * Base value for the mcrypt implementation $engine switch
109
- */
110
- define('CRYPT_ENGINE_MCRYPT', 2);
111
- /**
112
- * Base value for the OpenSSL implementation $engine switch
113
- */
114
- define('CRYPT_ENGINE_OPENSSL', 3);
115
- /**#@-*/
116
-
117
- /**
118
- * Base Class for all Crypt_* cipher classes
119
- *
120
- * @package Crypt_Base
121
- * @author Jim Wigginton <terrafrost@php.net>
122
- * @author Hans-Juergen Petrich <petrich@tronic-media.com>
123
- * @access public
124
- */
125
- class Crypt_Base
126
- {
127
- /**
128
- * The Encryption Mode
129
- *
130
- * @see Crypt_Base::Crypt_Base()
131
- * @var Integer
132
- * @access private
133
- */
134
- var $mode;
135
-
136
- /**
137
- * The Block Length of the block cipher
138
- *
139
- * @var Integer
140
- * @access private
141
- */
142
- var $block_size = 16;
143
-
144
- /**
145
- * The Key
146
- *
147
- * @see Crypt_Base::setKey()
148
- * @var String
149
- * @access private
150
- */
151
- var $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
152
-
153
- /**
154
- * The Initialization Vector
155
- *
156
- * @see Crypt_Base::setIV()
157
- * @var String
158
- * @access private
159
- */
160
- var $iv;
161
-
162
- /**
163
- * A "sliding" Initialization Vector
164
- *
165
- * @see Crypt_Base::enableContinuousBuffer()
166
- * @see Crypt_Base::_clearBuffers()
167
- * @var String
168
- * @access private
169
- */
170
- var $encryptIV;
171
-
172
- /**
173
- * A "sliding" Initialization Vector
174
- *
175
- * @see Crypt_Base::enableContinuousBuffer()
176
- * @see Crypt_Base::_clearBuffers()
177
- * @var String
178
- * @access private
179
- */
180
- var $decryptIV;
181
-
182
- /**
183
- * Continuous Buffer status
184
- *
185
- * @see Crypt_Base::enableContinuousBuffer()
186
- * @var Boolean
187
- * @access private
188
- */
189
- var $continuousBuffer = false;
190
-
191
- /**
192
- * Encryption buffer for CTR, OFB and CFB modes
193
- *
194
- * @see Crypt_Base::encrypt()
195
- * @see Crypt_Base::_clearBuffers()
196
- * @var Array
197
- * @access private
198
- */
199
- var $enbuffer;
200
-
201
- /**
202
- * Decryption buffer for CTR, OFB and CFB modes
203
- *
204
- * @see Crypt_Base::decrypt()
205
- * @see Crypt_Base::_clearBuffers()
206
- * @var Array
207
- * @access private
208
- */
209
- var $debuffer;
210
-
211
- /**
212
- * mcrypt resource for encryption
213
- *
214
- * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
215
- * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
216
- *
217
- * @see Crypt_Base::encrypt()
218
- * @var Resource
219
- * @access private
220
- */
221
- var $enmcrypt;
222
-
223
- /**
224
- * mcrypt resource for decryption
225
- *
226
- * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
227
- * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
228
- *
229
- * @see Crypt_Base::decrypt()
230
- * @var Resource
231
- * @access private
232
- */
233
- var $demcrypt;
234
-
235
- /**
236
- * Does the enmcrypt resource need to be (re)initialized?
237
- *
238
- * @see Crypt_Twofish::setKey()
239
- * @see Crypt_Twofish::setIV()
240
- * @var Boolean
241
- * @access private
242
- */
243
- var $enchanged = true;
244
-
245
- /**
246
- * Does the demcrypt resource need to be (re)initialized?
247
- *
248
- * @see Crypt_Twofish::setKey()
249
- * @see Crypt_Twofish::setIV()
250
- * @var Boolean
251
- * @access private
252
- */
253
- var $dechanged = true;
254
-
255
- /**
256
- * mcrypt resource for CFB mode
257
- *
258
- * mcrypt's CFB mode, in (and only in) buffered context,
259
- * is broken, so phpseclib implements the CFB mode by it self,
260
- * even when the mcrypt php extension is available.
261
- *
262
- * In order to do the CFB-mode work (fast) phpseclib
263
- * use a separate ECB-mode mcrypt resource.
264
- *
265
- * @link http://phpseclib.sourceforge.net/cfb-demo.phps
266
- * @see Crypt_Base::encrypt()
267
- * @see Crypt_Base::decrypt()
268
- * @see Crypt_Base::_setupMcrypt()
269
- * @var Resource
270
- * @access private
271
- */
272
- var $ecb;
273
-
274
- /**
275
- * Optimizing value while CFB-encrypting
276
- *
277
- * Only relevant if $continuousBuffer enabled
278
- * and $engine == CRYPT_ENGINE_MCRYPT
279
- *
280
- * It's faster to re-init $enmcrypt if
281
- * $buffer bytes > $cfb_init_len than
282
- * using the $ecb resource furthermore.
283
- *
284
- * This value depends of the chosen cipher
285
- * and the time it would be needed for it's
286
- * initialization [by mcrypt_generic_init()]
287
- * which, typically, depends on the complexity
288
- * on its internaly Key-expanding algorithm.
289
- *
290
- * @see Crypt_Base::encrypt()
291
- * @var Integer
292
- * @access private
293
- */
294
- var $cfb_init_len = 600;
295
-
296
- /**
297
- * Does internal cipher state need to be (re)initialized?
298
- *
299
- * @see setKey()
300
- * @see setIV()
301
- * @see disableContinuousBuffer()
302
- * @var Boolean
303
- * @access private
304
- */
305
- var $changed = true;
306
-
307
- /**
308
- * Padding status
309
- *
310
- * @see Crypt_Base::enablePadding()
311
- * @var Boolean
312
- * @access private
313
- */
314
- var $padding = true;
315
-
316
- /**
317
- * Is the mode one that is paddable?
318
- *
319
- * @see Crypt_Base::Crypt_Base()
320
- * @var Boolean
321
- * @access private
322
- */
323
- var $paddable = false;
324
-
325
- /**
326
- * Holds which crypt engine internaly should be use,
327
- * which will be determined automatically on __construct()
328
- *
329
- * Currently available $engines are:
330
- * - CRYPT_ENGINE_OPENSSL (very fast, php-extension: openssl, extension_loaded('openssl') required)
331
- * - CRYPT_ENGINE_MCRYPT (fast, php-extension: mcrypt, extension_loaded('mcrypt') required)
332
- * - CRYPT_ENGINE_INTERNAL (slower, pure php-engine, no php-extension required)
333
- *
334
- * @see Crypt_Base::_setEngine()
335
- * @see Crypt_Base::encrypt()
336
- * @see Crypt_Base::decrypt()
337
- * @var Integer
338
- * @access private
339
- */
340
- var $engine;
341
-
342
- /**
343
- * Holds the preferred crypt engine
344
- *
345
- * @see Crypt_Base::_setEngine()
346
- * @see Crypt_Base::setPreferredEngine()
347
- * @var Integer
348
- * @access private
349
- */
350
- var $preferredEngine;
351
-
352
- /**
353
- * The mcrypt specific name of the cipher
354
- *
355
- * Only used if $engine == CRYPT_ENGINE_MCRYPT
356
- *
357
- * @link http://www.php.net/mcrypt_module_open
358
- * @link http://www.php.net/mcrypt_list_algorithms
359
- * @see Crypt_Base::_setupMcrypt()
360
- * @var String
361
- * @access private
362
- */
363
- var $cipher_name_mcrypt;
364
-
365
- /**
366
- * The openssl specific name of the cipher
367
- *
368
- * Only used if $engine == CRYPT_ENGINE_OPENSSL
369
- *
370
- * @link http://www.php.net/openssl-get-cipher-methods
371
- * @var String
372
- * @access private
373
- */
374
- var $cipher_name_openssl;
375
-
376
- /**
377
- * The openssl specific name of the cipher in ECB mode
378
- *
379
- * If OpenSSL does not support the mode we're trying to use (CTR)
380
- * it can still be emulated with ECB mode.
381
- *
382
- * @link http://www.php.net/openssl-get-cipher-methods
383
- * @var String
384
- * @access private
385
- */
386
- var $cipher_name_openssl_ecb;
387
-
388
- /**
389
- * The default password key_size used by setPassword()
390
- *
391
- * @see Crypt_Base::setPassword()
392
- * @var Integer
393
- * @access private
394
- */
395
- var $password_key_size = 32;
396
-
397
- /**
398
- * The default salt used by setPassword()
399
- *
400
- * @see Crypt_Base::setPassword()
401
- * @var String
402
- * @access private
403
- */
404
- var $password_default_salt = 'phpseclib/salt';
405
-
406
- /**
407
- * The namespace used by the cipher for its constants.
408
- *
409
- * ie: AES.php is using CRYPT_AES_MODE_* for its constants
410
- * so $const_namespace is AES
411
- *
412
- * DES.php is using CRYPT_DES_MODE_* for its constants
413
- * so $const_namespace is DES... and so on
414
- *
415
- * All CRYPT_<$const_namespace>_MODE_* are aliases of
416
- * the generic CRYPT_MODE_* constants, so both could be used
417
- * for each cipher.
418
- *
419
- * Example:
420
- * $aes = new Crypt_AES(CRYPT_AES_MODE_CFB); // $aes will operate in cfb mode
421
- * $aes = new Crypt_AES(CRYPT_MODE_CFB); // identical
422
- *
423
- * @see Crypt_Base::Crypt_Base()
424
- * @var String
425
- * @access private
426
- */
427
- var $const_namespace;
428
-
429
- /**
430
- * The name of the performance-optimized callback function
431
- *
432
- * Used by encrypt() / decrypt()
433
- * only if $engine == CRYPT_ENGINE_INTERNAL
434
- *
435
- * @see Crypt_Base::encrypt()
436
- * @see Crypt_Base::decrypt()
437
- * @see Crypt_Base::_setupInlineCrypt()
438
- * @see Crypt_Base::$use_inline_crypt
439
- * @var Callback
440
- * @access private
441
- */
442
- var $inline_crypt;
443
-
444
- /**
445
- * Holds whether performance-optimized $inline_crypt() can/should be used.
446
- *
447
- * @see Crypt_Base::encrypt()
448
- * @see Crypt_Base::decrypt()
449
- * @see Crypt_Base::inline_crypt
450
- * @var mixed
451
- * @access private
452
- */
453
- var $use_inline_crypt;
454
-
455
- /**
456
- * If OpenSSL can be used in ECB but not in CTR we can emulate CTR
457
- *
458
- * @see Crypt_Base::_openssl_ctr_process()
459
- * @var Boolean
460
- * @access private
461
- */
462
- var $openssl_emulate_ctr = false;
463
-
464
- /**
465
- * Determines what options are passed to openssl_encrypt/decrypt
466
- *
467
- * @see Crypt_Base::isValidEngine()
468
- * @var mixed
469
- * @access private
470
- */
471
- var $openssl_options;
472
-
473
- /**
474
- * Default Constructor.
475
- *
476
- * Determines whether or not the mcrypt extension should be used.
477
- *
478
- * $mode could be:
479
- *
480
- * - CRYPT_MODE_ECB
481
- *
482
- * - CRYPT_MODE_CBC
483
- *
484
- * - CRYPT_MODE_CTR
485
- *
486
- * - CRYPT_MODE_CFB
487
- *
488
- * - CRYPT_MODE_OFB
489
- *
490
- * (or the alias constants of the chosen cipher, for example for AES: CRYPT_AES_MODE_ECB or CRYPT_AES_MODE_CBC ...)
491
- *
492
- * If not explicitly set, CRYPT_MODE_CBC will be used.
493
- *
494
- * @param optional Integer $mode
495
- * @access public
496
- */
497
- function Crypt_Base($mode = CRYPT_MODE_CBC)
498
- {
499
- // $mode dependent settings
500
- switch ($mode) {
501
- case CRYPT_MODE_ECB:
502
- $this->paddable = true;
503
- $this->mode = CRYPT_MODE_ECB;
504
- break;
505
- case CRYPT_MODE_CTR:
506
- case CRYPT_MODE_CFB:
507
- case CRYPT_MODE_OFB:
508
- case CRYPT_MODE_STREAM:
509
- $this->mode = $mode;
510
- break;
511
- case CRYPT_MODE_CBC:
512
- default:
513
- $this->paddable = true;
514
- $this->mode = CRYPT_MODE_CBC;
515
- }
516
-
517
- $this->_setEngine();
518
-
519
- // Determining whether inline crypting can be used by the cipher
520
- if ($this->use_inline_crypt !== false && function_exists('create_function')) {
521
- $this->use_inline_crypt = true;
522
- }
523
- }
524
-
525
- /**
526
- * Sets the initialization vector. (optional)
527
- *
528
- * SetIV is not required when CRYPT_MODE_ECB (or ie for AES: CRYPT_AES_MODE_ECB) is being used. If not explicitly set, it'll be assumed
529
- * to be all zero's.
530
- *
531
- * @access public
532
- * @param String $iv
533
- * @internal Can be overwritten by a sub class, but does not have to be
534
- */
535
- function setIV($iv)
536
- {
537
- if ($this->mode == CRYPT_MODE_ECB) {
538
- return;
539
- }
540
-
541
- $this->iv = $iv;
542
- $this->changed = true;
543
- }
544
-
545
- /**
546
- * Sets the key.
547
- *
548
- * The min/max length(s) of the key depends on the cipher which is used.
549
- * If the key not fits the length(s) of the cipher it will paded with null bytes
550
- * up to the closest valid key length. If the key is more than max length,
551
- * we trim the excess bits.
552
- *
553
- * If the key is not explicitly set, it'll be assumed to be all null bytes.
554
- *
555
- * @access public
556
- * @param String $key
557
- * @internal Could, but not must, extend by the child Crypt_* class
558
- */
559
- function setKey($key)
560
- {
561
- $this->key = $key;
562
- $this->changed = true;
563
- $this->_setEngine();
564
- }
565
-
566
- /**
567
- * Sets the password.
568
- *
569
- * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows:
570
- * {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2} or pbkdf1:
571
- * $hash, $salt, $count, $dkLen
572
- *
573
- * Where $hash (default = sha1) currently supports the following hashes: see: Crypt/Hash.php
574
- *
575
- * @see Crypt/Hash.php
576
- * @param String $password
577
- * @param optional String $method
578
- * @return Boolean
579
- * @access public
580
- * @internal Could, but not must, extend by the child Crypt_* class
581
- */
582
- function setPassword($password, $method = 'pbkdf2')
583
- {
584
- $key = '';
585
-
586
- switch ($method) {
587
- default: // 'pbkdf2' or 'pbkdf1'
588
- $func_args = func_get_args();
589
-
590
- // Hash function
591
- $hash = isset($func_args[2]) ? $func_args[2] : 'sha1';
592
-
593
- // WPA and WPA2 use the SSID as the salt
594
- $salt = isset($func_args[3]) ? $func_args[3] : $this->password_default_salt;
595
-
596
- // RFC2898#section-4.2 uses 1,000 iterations by default
597
- // WPA and WPA2 use 4,096.
598
- $count = isset($func_args[4]) ? $func_args[4] : 1000;
599
-
600
- // Keylength
601
- if (isset($func_args[5])) {
602
- $dkLen = $func_args[5];
603
- } else {
604
- $dkLen = $method == 'pbkdf1' ? 2 * $this->password_key_size : $this->password_key_size;
605
- }
606
-
607
- switch (true) {
608
- case $method == 'pbkdf1':
609
- if (!class_exists('Crypt_Hash')) {
610
- include_once 'Crypt/Hash.php';
611
- }
612
- $hashObj = new Crypt_Hash();
613
- $hashObj->setHash($hash);
614
- if ($dkLen > $hashObj->getLength()) {
615
- user_error('Derived key too long');
616
- return false;
617
- }
618
- $t = $password . $salt;
619
- for ($i = 0; $i < $count; ++$i) {
620
- $t = $hashObj->hash($t);
621
- }
622
- $key = substr($t, 0, $dkLen);
623
-
624
- $this->setKey(substr($key, 0, $dkLen >> 1));
625
- $this->setIV(substr($key, $dkLen >> 1));
626
-
627
- return true;
628
- // Determining if php[>=5.5.0]'s hash_pbkdf2() function avail- and useable
629
- case !function_exists('hash_pbkdf2'):
630
- case !function_exists('hash_algos'):
631
- case !in_array($hash, hash_algos()):
632
- if (!class_exists('Crypt_Hash')) {
633
- include_once 'Crypt/Hash.php';
634
- }
635
- $i = 1;
636
- while (strlen($key) < $dkLen) {
637
- $hmac = new Crypt_Hash();
638
- $hmac->setHash($hash);
639
- $hmac->setKey($password);
640
- $f = $u = $hmac->hash($salt . pack('N', $i++));
641
- for ($j = 2; $j <= $count; ++$j) {
642
- $u = $hmac->hash($u);
643
- $f^= $u;
644
- }
645
- $key.= $f;
646
- }
647
- $key = substr($key, 0, $dkLen);
648
- break;
649
- default:
650
- $key = hash_pbkdf2($hash, $password, $salt, $count, $dkLen, true);
651
- }
652
- }
653
-
654
- $this->setKey($key);
655
-
656
- return true;
657
- }
658
-
659
- /**
660
- * Encrypts a message.
661
- *
662
- * $plaintext will be padded with additional bytes such that it's length is a multiple of the block size. Other cipher
663
- * implementations may or may not pad in the same manner. Other common approaches to padding and the reasons why it's
664
- * necessary are discussed in the following
665
- * URL:
666
- *
667
- * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
668
- *
669
- * An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does.
670
- * strlen($plaintext) will still need to be a multiple of the block size, however, arbitrary values can be added to make it that
671
- * length.
672
- *
673
- * @see Crypt_Base::decrypt()
674
- * @access public
675
- * @param String $plaintext
676
- * @return String $ciphertext
677
- * @internal Could, but not must, extend by the child Crypt_* class
678
- */
679
- function encrypt($plaintext)
680
- {
681
- if ($this->paddable) {
682
- $plaintext = $this->_pad($plaintext);
683
- }
684
-
685
- if ($this->engine === CRYPT_ENGINE_OPENSSL) {
686
- if ($this->changed) {
687
- $this->_clearBuffers();
688
- $this->changed = false;
689
- }
690
- switch ($this->mode) {
691
- case CRYPT_MODE_STREAM:
692
- return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
693
- case CRYPT_MODE_ECB:
694
- $result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
695
- return !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result;
696
- case CRYPT_MODE_CBC:
697
- $result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->encryptIV);
698
- if ($this->continuousBuffer) {
699
- $this->encryptIV = substr($result, -$this->block_size);
700
- }
701
- return !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result;
702
- case CRYPT_MODE_CTR:
703
- return $this->_openssl_ctr_process($plaintext, $this->encryptIV, $this->enbuffer);
704
- case CRYPT_MODE_CFB:
705
- // cfb loosely routines inspired by openssl's:
706
- // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1}
707
- $ciphertext = '';
708
- if ($this->continuousBuffer) {
709
- $iv = &$this->encryptIV;
710
- $pos = &$this->enbuffer['pos'];
711
- } else {
712
- $iv = $this->encryptIV;
713
- $pos = 0;
714
- }
715
- $len = strlen($plaintext);
716
- $i = 0;
717
- if ($pos) {
718
- $orig_pos = $pos;
719
- $max = $this->block_size - $pos;
720
- if ($len >= $max) {
721
- $i = $max;
722
- $len-= $max;
723
- $pos = 0;
724
- } else {
725
- $i = $len;
726
- $pos+= $len;
727
- $len = 0;
728
- }
729
- // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize
730
- $ciphertext = substr($iv, $orig_pos) ^ $plaintext;
731
- $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
732
- $plaintext = substr($plaintext, $i);
733
- }
734
-
735
- $overflow = $len % $this->block_size;
736
-
737
- if ($overflow) {
738
- $ciphertext.= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
739
- $iv = $this->_string_pop($ciphertext, $this->block_size);
740
-
741
- $size = $len - $overflow;
742
- $block = $iv ^ substr($plaintext, -$overflow);
743
- $iv = substr_replace($iv, $block, 0, $overflow);
744
- $ciphertext.= $block;
745
- $pos = $overflow;
746
- } else if ($len) {
747
- $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
748
- $iv = substr($ciphertext, -$this->block_size);
749
- }
750
-
751
- return $ciphertext;
752
- case CRYPT_MODE_OFB:
753
- return $this->_openssl_ofb_process($plaintext, $this->encryptIV, $this->enbuffer);
754
- }
755
- }
756
-
757
- if ($this->engine === CRYPT_ENGINE_MCRYPT) {
758
- if ($this->changed) {
759
- $this->_setupMcrypt();
760
- $this->changed = false;
761
- }
762
- if ($this->enchanged) {
763
- mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
764
- $this->enchanged = false;
765
- }
766
-
767
- // re: {@link http://phpseclib.sourceforge.net/cfb-demo.phps}
768
- // using mcrypt's default handing of CFB the above would output two different things. using phpseclib's
769
- // rewritten CFB implementation the above outputs the same thing twice.
770
- if ($this->mode == CRYPT_MODE_CFB && $this->continuousBuffer) {
771
- $block_size = $this->block_size;
772
- $iv = &$this->encryptIV;
773
- $pos = &$this->enbuffer['pos'];
774
- $len = strlen($plaintext);
775
- $ciphertext = '';
776
- $i = 0;
777
- if ($pos) {
778
- $orig_pos = $pos;
779
- $max = $block_size - $pos;
780
- if ($len >= $max) {
781
- $i = $max;
782
- $len-= $max;
783
- $pos = 0;
784
- } else {
785
- $i = $len;
786
- $pos+= $len;
787
- $len = 0;
788
- }
789
- $ciphertext = substr($iv, $orig_pos) ^ $plaintext;
790
- $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
791
- $this->enbuffer['enmcrypt_init'] = true;
792
- }
793
- if ($len >= $block_size) {
794
- if ($this->enbuffer['enmcrypt_init'] === false || $len > $this->cfb_init_len) {
795
- if ($this->enbuffer['enmcrypt_init'] === true) {
796
- mcrypt_generic_init($this->enmcrypt, $this->key, $iv);
797
- $this->enbuffer['enmcrypt_init'] = false;
798
- }
799
- $ciphertext.= mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % $block_size));
800
- $iv = substr($ciphertext, -$block_size);
801
- $len%= $block_size;
802
- } else {
803
- while ($len >= $block_size) {
804
- $iv = mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, $block_size);
805
- $ciphertext.= $iv;
806
- $len-= $block_size;
807
- $i+= $block_size;
808
- }
809
- }
810
- }
811
-
812
- if ($len) {
813
- $iv = mcrypt_generic($this->ecb, $iv);
814
- $block = $iv ^ substr($plaintext, -$len);
815
- $iv = substr_replace($iv, $block, 0, $len);
816
- $ciphertext.= $block;
817
- $pos = $len;
818
- }
819
-
820
- return $ciphertext;
821
- }
822
-
823
- $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
824
-
825
- if (!$this->continuousBuffer) {
826
- mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
827
- }
828
-
829
- return $ciphertext;
830
- }
831
-
832
- if ($this->changed) {
833
- $this->_setup();
834
- $this->changed = false;
835
- }
836
- if ($this->use_inline_crypt) {
837
- $inline = $this->inline_crypt;
838
- return $inline('encrypt', $this, $plaintext);
839
- }
840
-
841
- $buffer = &$this->enbuffer;
842
- $block_size = $this->block_size;
843
- $ciphertext = '';
844
- switch ($this->mode) {
845
- case CRYPT_MODE_ECB:
846
- for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
847
- $ciphertext.= $this->_encryptBlock(substr($plaintext, $i, $block_size));
848
- }
849
- break;
850
- case CRYPT_MODE_CBC:
851
- $xor = $this->encryptIV;
852
- for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
853
- $block = substr($plaintext, $i, $block_size);
854
- $block = $this->_encryptBlock($block ^ $xor);
855
- $xor = $block;
856
- $ciphertext.= $block;
857
- }
858
- if ($this->continuousBuffer) {
859
- $this->encryptIV = $xor;
860
- }
861
- break;
862
- case CRYPT_MODE_CTR:
863
- $xor = $this->encryptIV;
864
- if (strlen($buffer['ciphertext'])) {
865
- for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
866
- $block = substr($plaintext, $i, $block_size);
867
- if (strlen($block) > strlen($buffer['ciphertext'])) {
868
- $buffer['ciphertext'].= $this->_encryptBlock($xor);
869
- }
870
- $this->_increment_str($xor);
871
- $key = $this->_string_shift($buffer['ciphertext'], $block_size);
872
- $ciphertext.= $block ^ $key;
873
- }
874
- } else {
875
- for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
876
- $block = substr($plaintext, $i, $block_size);
877
- $key = $this->_encryptBlock($xor);
878
- $this->_increment_str($xor);
879
- $ciphertext.= $block ^ $key;
880
- }
881
- }
882
- if ($this->continuousBuffer) {
883
- $this->encryptIV = $xor;
884
- if ($start = strlen($plaintext) % $block_size) {
885
- $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext'];
886
- }
887
- }
888
- break;
889
- case CRYPT_MODE_CFB:
890
- // cfb loosely routines inspired by openssl's:
891
- // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1}
892
- if ($this->continuousBuffer) {
893
- $iv = &$this->encryptIV;
894
- $pos = &$buffer['pos'];
895
- } else {
896
- $iv = $this->encryptIV;
897
- $pos = 0;
898
- }
899
- $len = strlen($plaintext);
900
- $i = 0;
901
- if ($pos) {
902
- $orig_pos = $pos;
903
- $max = $block_size - $pos;
904
- if ($len >= $max) {
905
- $i = $max;
906
- $len-= $max;
907
- $pos = 0;
908
- } else {
909
- $i = $len;
910
- $pos+= $len;
911
- $len = 0;
912
- }
913
- // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize
914
- $ciphertext = substr($iv, $orig_pos) ^ $plaintext;
915
- $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
916
- }
917
- while ($len >= $block_size) {
918
- $iv = $this->_encryptBlock($iv) ^ substr($plaintext, $i, $block_size);
919
- $ciphertext.= $iv;
920
- $len-= $block_size;
921
- $i+= $block_size;
922
- }
923
- if ($len) {
924
- $iv = $this->_encryptBlock($iv);
925
- $block = $iv ^ substr($plaintext, $i);
926
- $iv = substr_replace($iv, $block, 0, $len);
927
- $ciphertext.= $block;
928
- $pos = $len;
929
- }
930
- break;
931
- case CRYPT_MODE_OFB:
932
- $xor = $this->encryptIV;
933
- if (strlen($buffer['xor'])) {
934
- for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
935
- $block = substr($plaintext, $i, $block_size);
936
- if (strlen($block) > strlen($buffer['xor'])) {
937
- $xor = $this->_encryptBlock($xor);
938
- $buffer['xor'].= $xor;
939
- }
940
- $key = $this->_string_shift($buffer['xor'], $block_size);
941
- $ciphertext.= $block ^ $key;
942
- }
943
- } else {
944
- for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
945
- $xor = $this->_encryptBlock($xor);
946
- $ciphertext.= substr($plaintext, $i, $block_size) ^ $xor;
947
- }
948
- $key = $xor;
949
- }
950
- if ($this->continuousBuffer) {
951
- $this->encryptIV = $xor;
952
- if ($start = strlen($plaintext) % $block_size) {
953
- $buffer['xor'] = substr($key, $start) . $buffer['xor'];
954
- }
955
- }
956
- break;
957
- case CRYPT_MODE_STREAM:
958
- $ciphertext = $this->_encryptBlock($plaintext);
959
- break;
960
- }
961
-
962
- return $ciphertext;
963
- }
964
-
965
- /**
966
- * Decrypts a message.
967
- *
968
- * If strlen($ciphertext) is not a multiple of the block size, null bytes will be added to the end of the string until
969
- * it is.
970
- *
971
- * @see Crypt_Base::encrypt()
972
- * @access public
973
- * @param String $ciphertext
974
- * @return String $plaintext
975
- * @internal Could, but not must, extend by the child Crypt_* class
976
- */
977
- function decrypt($ciphertext)
978
- {
979
- if ($this->paddable) {
980
- // we pad with chr(0) since that's what mcrypt_generic does. to quote from {@link http://www.php.net/function.mcrypt-generic}:
981
- // "The data is padded with "\0" to make sure the length of the data is n * blocksize."
982
- $ciphertext = str_pad($ciphertext, strlen($ciphertext) + ($this->block_size - strlen($ciphertext) % $this->block_size) % $this->block_size, chr(0));
983
- }
984
-
985
- if ($this->engine === CRYPT_ENGINE_OPENSSL) {
986
- if ($this->changed) {
987
- $this->_clearBuffers();
988
- $this->changed = false;
989
- }
990
- switch ($this->mode) {
991
- case CRYPT_MODE_STREAM:
992
- $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
993
- break;
994
- case CRYPT_MODE_ECB:
995
- if (!defined('OPENSSL_RAW_DATA')) {
996
- $ciphetext.= openssl_encrypt('', $this->cipher_name_openssl_ecb, $this->key, true);
997
- }
998
- $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
999
- break;
1000
- case CRYPT_MODE_CBC:
1001
- if (!defined('OPENSSL_RAW_DATA')) {
1002
- $padding = str_repeat(chr($this->block_size), $this->block_size) ^ substr($ciphertext, -$this->block_size);
1003
- $ciphertext.= substr(openssl_encrypt($padding, $this->cipher_name_openssl_ecb, $this->key, true), 0, $this->block_size);
1004
- }
1005
- $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->decryptIV);
1006
- if ($this->continuousBuffer) {
1007
- $this->decryptIV = substr($ciphertext, -$this->block_size);
1008
- }
1009
- break;
1010
- case CRYPT_MODE_CTR:
1011
- $plaintext = $this->_openssl_ctr_process($ciphertext, $this->decryptIV, $this->debuffer);
1012
- break;
1013
- case CRYPT_MODE_CFB:
1014
- // cfb loosely routines inspired by openssl's:
1015
- // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1}
1016
- $plaintext = '';
1017
- if ($this->continuousBuffer) {
1018
- $iv = &$this->decryptIV;
1019
- $pos = &$this->buffer['pos'];
1020
- } else {
1021
- $iv = $this->decryptIV;
1022
- $pos = 0;
1023
- }
1024
- $len = strlen($ciphertext);
1025
- $i = 0;
1026
- if ($pos) {
1027
- $orig_pos = $pos;
1028
- $max = $this->block_size - $pos;
1029
- if ($len >= $max) {
1030
- $i = $max;
1031
- $len-= $max;
1032
- $pos = 0;
1033
- } else {
1034
- $i = $len;
1035
- $pos+= $len;
1036
- $len = 0;
1037
- }
1038
- // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $this->blocksize
1039
- $plaintext = substr($iv, $orig_pos) ^ $ciphertext;
1040
- $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
1041
- $ciphertext = substr($ciphertext, $i);
1042
- }
1043
- $overflow = $len % $this->block_size;
1044
- if ($overflow) {
1045
- $plaintext.= openssl_decrypt(substr($ciphertext, 0, -$overflow), $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
1046
- if ($len - $overflow) {
1047
- $iv = substr($ciphertext, -$overflow - $this->block_size, -$overflow);
1048
- }
1049
- $iv = openssl_encrypt(str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
1050
- $plaintext.= $iv ^ substr($ciphertext, -$overflow);
1051
- $iv = substr_replace($iv, substr($ciphertext, -$overflow), 0, $overflow);
1052
- $pos = $overflow;
1053
- } else if ($len) {
1054
- $plaintext.= openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
1055
- $iv = substr($ciphertext, -$this->block_size);
1056
- }
1057
- break;
1058
- case CRYPT_MODE_OFB:
1059
- $plaintext = $this->_openssl_ofb_process($ciphertext, $this->decryptIV, $this->debuffer);
1060
- }
1061
-
1062
- return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
1063
- }
1064
-
1065
- if ($this->engine === CRYPT_ENGINE_MCRYPT) {
1066
- $block_size = $this->block_size;
1067
- if ($this->changed) {
1068
- $this->_setupMcrypt();
1069
- $this->changed = false;
1070
- }
1071
- if ($this->dechanged) {
1072
- mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
1073
- $this->dechanged = false;
1074
- }
1075
-
1076
- if ($this->mode == CRYPT_MODE_CFB && $this->continuousBuffer) {
1077
- $iv = &$this->decryptIV;
1078
- $pos = &$this->debuffer['pos'];
1079
- $len = strlen($ciphertext);
1080
- $plaintext = '';
1081
- $i = 0;
1082
- if ($pos) {
1083
- $orig_pos = $pos;
1084
- $max = $block_size - $pos;
1085
- if ($len >= $max) {
1086
- $i = $max;
1087
- $len-= $max;
1088
- $pos = 0;
1089
- } else {
1090
- $i = $len;
1091
- $pos+= $len;
1092
- $len = 0;
1093
- }
1094
- // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize
1095
- $plaintext = substr($iv, $orig_pos) ^ $ciphertext;
1096
- $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
1097
- }
1098
- if ($len >= $block_size) {
1099
- $cb = substr($ciphertext, $i, $len - $len % $block_size);
1100
- $plaintext.= mcrypt_generic($this->ecb, $iv . $cb) ^ $cb;
1101
- $iv = substr($cb, -$block_size);
1102
- $len%= $block_size;
1103
- }
1104
- if ($len) {
1105
- $iv = mcrypt_generic($this->ecb, $iv);
1106
- $plaintext.= $iv ^ substr($ciphertext, -$len);
1107
- $iv = substr_replace($iv, substr($ciphertext, -$len), 0, $len);
1108
- $pos = $len;
1109
- }
1110
-
1111
- return $plaintext;
1112
- }
1113
-
1114
- $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
1115
-
1116
- if (!$this->continuousBuffer) {
1117
- mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
1118
- }
1119
-
1120
- return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
1121
- }
1122
-
1123
- if ($this->changed) {
1124
- $this->_setup();
1125
- $this->changed = false;
1126
- }
1127
- if ($this->use_inline_crypt) {
1128
- $inline = $this->inline_crypt;
1129
- return $inline('decrypt', $this, $ciphertext);
1130
- }
1131
-
1132
- $block_size = $this->block_size;
1133
-
1134
- $buffer = &$this->debuffer;
1135
- $plaintext = '';
1136
- switch ($this->mode) {
1137
- case CRYPT_MODE_ECB:
1138
- for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
1139
- $plaintext.= $this->_decryptBlock(substr($ciphertext, $i, $block_size));
1140
- }
1141
- break;
1142
- case CRYPT_MODE_CBC:
1143
- $xor = $this->decryptIV;
1144
- for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
1145
- $block = substr($ciphertext, $i, $block_size);
1146
- $plaintext.= $this->_decryptBlock($block) ^ $xor;
1147
- $xor = $block;
1148
- }
1149
- if ($this->continuousBuffer) {
1150
- $this->decryptIV = $xor;
1151
- }
1152
- break;
1153
- case CRYPT_MODE_CTR:
1154
- $xor = $this->decryptIV;
1155
- if (strlen($buffer['ciphertext'])) {
1156
- for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
1157
- $block = substr($ciphertext, $i, $block_size);
1158
- if (strlen($block) > strlen($buffer['ciphertext'])) {
1159
- $buffer['ciphertext'].= $this->_encryptBlock($xor);
1160
- $this->_increment_str($xor);
1161
- }
1162
- $key = $this->_string_shift($buffer['ciphertext'], $block_size);
1163
- $plaintext.= $block ^ $key;
1164
- }
1165
- } else {
1166
- for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
1167
- $block = substr($ciphertext, $i, $block_size);
1168
- $key = $this->_encryptBlock($xor);
1169
- $this->_increment_str($xor);
1170
- $plaintext.= $block ^ $key;
1171
- }
1172
- }
1173
- if ($this->continuousBuffer) {
1174
- $this->decryptIV = $xor;
1175
- if ($start = strlen($ciphertext) % $block_size) {
1176
- $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext'];
1177
- }
1178
- }
1179
- break;
1180
- case CRYPT_MODE_CFB:
1181
- if ($this->continuousBuffer) {
1182
- $iv = &$this->decryptIV;
1183
- $pos = &$buffer['pos'];
1184
- } else {
1185
- $iv = $this->decryptIV;
1186
- $pos = 0;
1187
- }
1188
- $len = strlen($ciphertext);
1189
- $i = 0;
1190
- if ($pos) {
1191
- $orig_pos = $pos;
1192
- $max = $block_size - $pos;
1193
- if ($len >= $max) {
1194
- $i = $max;
1195
- $len-= $max;
1196
- $pos = 0;
1197
- } else {
1198
- $i = $len;
1199
- $pos+= $len;
1200
- $len = 0;
1201
- }
1202
- // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize
1203
- $plaintext = substr($iv, $orig_pos) ^ $ciphertext;
1204
- $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
1205
- }
1206
- while ($len >= $block_size) {
1207
- $iv = $this->_encryptBlock($iv);
1208
- $cb = substr($ciphertext, $i, $block_size);
1209
- $plaintext.= $iv ^ $cb;
1210
- $iv = $cb;
1211
- $len-= $block_size;
1212
- $i+= $block_size;
1213
- }
1214
- if ($len) {
1215
- $iv = $this->_encryptBlock($iv);
1216
- $plaintext.= $iv ^ substr($ciphertext, $i);
1217
- $iv = substr_replace($iv, substr($ciphertext, $i), 0, $len);
1218
- $pos = $len;
1219
- }
1220
- break;
1221
- case CRYPT_MODE_OFB:
1222
- $xor = $this->decryptIV;
1223
- if (strlen($buffer['xor'])) {
1224
- for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
1225
- $block = substr($ciphertext, $i, $block_size);
1226
- if (strlen($block) > strlen($buffer['xor'])) {
1227
- $xor = $this->_encryptBlock($xor);
1228
- $buffer['xor'].= $xor;
1229
- }
1230
- $key = $this->_string_shift($buffer['xor'], $block_size);
1231
- $plaintext.= $block ^ $key;
1232
- }
1233
- } else {
1234
- for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
1235
- $xor = $this->_encryptBlock($xor);
1236
- $plaintext.= substr($ciphertext, $i, $block_size) ^ $xor;
1237
- }
1238
- $key = $xor;
1239
- }
1240
- if ($this->continuousBuffer) {
1241
- $this->decryptIV = $xor;
1242
- if ($start = strlen($ciphertext) % $block_size) {
1243
- $buffer['xor'] = substr($key, $start) . $buffer['xor'];
1244
- }
1245
- }
1246
- break;
1247
- case CRYPT_MODE_STREAM:
1248
- $plaintext = $this->_decryptBlock($ciphertext);
1249
- break;
1250
- }
1251
- return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
1252
- }
1253
-
1254
- /**
1255
- * OpenSSL CTR Processor
1256
- *
1257
- * PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream
1258
- * for CTR is the same for both encrypting and decrypting this function is re-used by both Crypt_Base::encrypt()
1259
- * and Crypt_Base::decrypt(). Also, OpenSSL doesn't implement CTR for all of it's symmetric ciphers so this
1260
- * function will emulate CTR with ECB when necesary.
1261
- *
1262
- * @see Crypt_Base::encrypt()
1263
- * @see Crypt_Base::decrypt()
1264
- * @param String $plaintext
1265
- * @param String $encryptIV
1266
- * @param Array $buffer
1267
- * @return String
1268
- * @access private
1269
- */
1270
- function _openssl_ctr_process($plaintext, &$encryptIV, &$buffer)
1271
- {
1272
- $ciphertext = '';
1273
-
1274
- $block_size = $this->block_size;
1275
- $key = $this->key;
1276
-
1277
- if ($this->openssl_emulate_ctr) {
1278
- $xor = $encryptIV;
1279
- if (strlen($buffer['ciphertext'])) {
1280
- for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
1281
- $block = substr($plaintext, $i, $block_size);
1282
- if (strlen($block) > strlen($buffer['ciphertext'])) {
1283
- $result = openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
1284
- $result = !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result;
1285
- $buffer['ciphertext'].= $result;
1286
- }
1287
- $this->_increment_str($xor);
1288
- $otp = $this->_string_shift($buffer['ciphertext'], $block_size);
1289
- $ciphertext.= $block ^ $otp;
1290
- }
1291
- } else {
1292
- for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
1293
- $block = substr($plaintext, $i, $block_size);
1294
- $otp = openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
1295
- $otp = !defined('OPENSSL_RAW_DATA') ? substr($otp, 0, -$this->block_size) : $otp;
1296
- $this->_increment_str($xor);
1297
- $ciphertext.= $block ^ $otp;
1298
- }
1299
- }
1300
- if ($this->continuousBuffer) {
1301
- $encryptIV = $xor;
1302
- if ($start = strlen($plaintext) % $block_size) {
1303
- $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext'];
1304
- }
1305
- }
1306
-
1307
- return $ciphertext;
1308
- }
1309
-
1310
- if (strlen($buffer['ciphertext'])) {
1311
- $ciphertext = $plaintext ^ $this->_string_shift($buffer['ciphertext'], strlen($plaintext));
1312
- $plaintext = substr($plaintext, strlen($ciphertext));
1313
-
1314
- if (!strlen($plaintext)) {
1315
- return $ciphertext;
1316
- }
1317
- }
1318
-
1319
- $overflow = strlen($plaintext) % $block_size;
1320
- if ($overflow) {
1321
- $plaintext2 = $this->_string_pop($plaintext, $overflow); // ie. trim $plaintext to a multiple of $block_size and put rest of $plaintext in $plaintext2
1322
- $encrypted = openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV);
1323
- $temp = $this->_string_pop($encrypted, $block_size);
1324
- $ciphertext.= $encrypted . ($plaintext2 ^ $temp);
1325
- if ($this->continuousBuffer) {
1326
- $buffer['ciphertext'] = substr($temp, $overflow);
1327
- $encryptIV = $temp;
1328
- }
1329
- } else if (!strlen($buffer['ciphertext'])) {
1330
- $ciphertext.= openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV);
1331
- $temp = $this->_string_pop($ciphertext, $block_size);
1332
- if ($this->continuousBuffer) {
1333
- $encryptIV = $temp;
1334
- }
1335
- }
1336
- if ($this->continuousBuffer) {
1337
- if (!defined('OPENSSL_RAW_DATA')) {
1338
- $encryptIV.= openssl_encrypt('', $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
1339
- }
1340
- $encryptIV = openssl_decrypt($encryptIV, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
1341
- if ($overflow) {
1342
- $this->_increment_str($encryptIV);
1343
- }
1344
- }
1345
-
1346
- return $ciphertext;
1347
- }
1348
-
1349
- /**
1350
- * OpenSSL OFB Processor
1351
- *
1352
- * PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream
1353
- * for OFB is the same for both encrypting and decrypting this function is re-used by both Crypt_Base::encrypt()
1354
- * and Crypt_Base::decrypt().
1355
- *
1356
- * @see Crypt_Base::encrypt()
1357
- * @see Crypt_Base::decrypt()
1358
- * @param String $plaintext
1359
- * @param String $encryptIV
1360
- * @param Array $buffer
1361
- * @return String
1362
- * @access private
1363
- */
1364
- function _openssl_ofb_process($plaintext, &$encryptIV, &$buffer)
1365
- {
1366
- if (strlen($buffer['xor'])) {
1367
- $ciphertext = $plaintext ^ $buffer['xor'];
1368
- $buffer['xor'] = substr($buffer['xor'], strlen($ciphertext));
1369
- $plaintext = substr($plaintext, strlen($ciphertext));
1370
- } else {
1371
- $ciphertext = '';
1372
- }
1373
-
1374
- $block_size = $this->block_size;
1375
-
1376
- $len = strlen($plaintext);
1377
- $key = $this->key;
1378
- $overflow = $len % $block_size;
1379
-
1380
- if (strlen($plaintext)) {
1381
- if ($overflow) {
1382
- $ciphertext.= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV);
1383
- $xor = $this->_string_pop($ciphertext, $block_size);
1384
- if ($this->continuousBuffer) {
1385
- $encryptIV = $xor;
1386
- }
1387
- $ciphertext.= $this->_string_shift($xor, $overflow) ^ substr($plaintext, -$overflow);
1388
- if ($this->continuousBuffer) {
1389
- $buffer['xor'] = $xor;
1390
- }
1391
- } else {
1392
- $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV);
1393
- if ($this->continuousBuffer) {
1394
- $encryptIV = substr($ciphertext, -$block_size) ^ substr($plaintext, -$block_size);
1395
- }
1396
- }
1397
- }
1398
-
1399
- return $ciphertext;
1400
- }
1401
-
1402
- /**
1403
- * phpseclib <-> OpenSSL Mode Mapper
1404
- *
1405
- * May need to be overwritten by classes extending this one in some cases
1406
- *
1407
- * @return Integer
1408
- * @access private
1409
- */
1410
- function _openssl_translate_mode()
1411
- {
1412
- switch ($this->mode) {
1413
- case CRYPT_MODE_ECB:
1414
- return 'ecb';
1415
- case CRYPT_MODE_CBC:
1416
- return 'cbc';
1417
- case CRYPT_MODE_CTR:
1418
- return 'ctr';
1419
- case CRYPT_MODE_CFB:
1420
- return 'cfb';
1421
- case CRYPT_MODE_OFB:
1422
- return 'ofb';
1423
- }
1424
- }
1425
-
1426
- /**
1427
- * Pad "packets".
1428
- *
1429
- * Block ciphers working by encrypting between their specified [$this->]block_size at a time
1430
- * If you ever need to encrypt or decrypt something that isn't of the proper length, it becomes necessary to
1431
- * pad the input so that it is of the proper length.
1432
- *
1433
- * Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH,
1434
- * where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping
1435
- * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is
1436
- * transmitted separately)
1437
- *
1438
- * @see Crypt_Base::disablePadding()
1439
- * @access public
1440
- */
1441
- function enablePadding()
1442
- {
1443
- $this->padding = true;
1444
- }
1445
-
1446
- /**
1447
- * Do not pad packets.
1448
- *
1449
- * @see Crypt_Base::enablePadding()
1450
- * @access public
1451
- */
1452
- function disablePadding()
1453
- {
1454
- $this->padding = false;
1455
- }
1456
-
1457
- /**
1458
- * Treat consecutive "packets" as if they are a continuous buffer.
1459
- *
1460
- * Say you have a 32-byte plaintext $plaintext. Using the default behavior, the two following code snippets
1461
- * will yield different outputs:
1462
- *
1463
- * <code>
1464
- * echo $rijndael->encrypt(substr($plaintext, 0, 16));
1465
- * echo $rijndael->encrypt(substr($plaintext, 16, 16));
1466
- * </code>
1467
- * <code>
1468
- * echo $rijndael->encrypt($plaintext);
1469
- * </code>
1470
- *
1471
- * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates
1472
- * another, as demonstrated with the following:
1473
- *
1474
- * <code>
1475
- * $rijndael->encrypt(substr($plaintext, 0, 16));
1476
- * echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16)));
1477
- * </code>
1478
- * <code>
1479
- * echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16)));
1480
- * </code>
1481
- *
1482
- * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different
1483
- * outputs. The reason is due to the fact that the initialization vector's change after every encryption /
1484
- * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
1485
- *
1486
- * Put another way, when the continuous buffer is enabled, the state of the Crypt_*() object changes after each
1487
- * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
1488
- * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
1489
- * however, they are also less intuitive and more likely to cause you problems.
1490
- *
1491
- * @see Crypt_Base::disableContinuousBuffer()
1492
- * @access public
1493
- * @internal Could, but not must, extend by the child Crypt_* class
1494
- */
1495
- function enableContinuousBuffer()
1496
- {
1497
- if ($this->mode == CRYPT_MODE_ECB) {
1498
- return;
1499
- }
1500
-
1501
- $this->continuousBuffer = true;
1502
-
1503
- $this->_setEngine();
1504
- }
1505
-
1506
- /**
1507
- * Treat consecutive packets as if they are a discontinuous buffer.
1508
- *
1509
- * The default behavior.
1510
- *
1511
- * @see Crypt_Base::enableContinuousBuffer()
1512
- * @access public
1513
- * @internal Could, but not must, extend by the child Crypt_* class
1514
- */
1515
- function disableContinuousBuffer()
1516
- {
1517
- if ($this->mode == CRYPT_MODE_ECB) {
1518
- return;
1519
- }
1520
- if (!$this->continuousBuffer) {
1521
- return;
1522
- }
1523
-
1524
- $this->continuousBuffer = false;
1525
- $this->changed = true;
1526
-
1527
- $this->_setEngine();
1528
- }
1529
-
1530
- /**
1531
- * Test for engine validity
1532
- *
1533
- * @see Crypt_Base::Crypt_Base()
1534
- * @param Integer $engine
1535
- * @access public
1536
- * @return Boolean
1537
- */
1538
- function isValidEngine($engine)
1539
- {
1540
- switch ($engine) {
1541
- case CRYPT_ENGINE_OPENSSL:
1542
- if ($this->mode == CRYPT_MODE_STREAM && $this->continuousBuffer) {
1543
- return false;
1544
- }
1545
- $this->openssl_emulate_ctr = false;
1546
- $result = $this->cipher_name_openssl &&
1547
- extension_loaded('openssl') &&
1548
- // PHP 5.3.0 - 5.3.2 did not let you set IV's
1549
- version_compare(PHP_VERSION, '5.3.3', '>=');
1550
- if (!$result) {
1551
- return false;
1552
- }
1553
-
1554
- // prior to PHP 5.4.0 OPENSSL_RAW_DATA and OPENSSL_ZERO_PADDING were not defined. instead of expecting an integer
1555
- // $options openssl_encrypt expected a boolean $raw_data.
1556
- if (!defined('OPENSSL_RAW_DATA')) {
1557
- $this->openssl_options = true;
1558
- } else {
1559
- $this->openssl_options = OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING;
1560
- }
1561
-
1562
- $methods = openssl_get_cipher_methods();
1563
- if (in_array($this->cipher_name_openssl, $methods)) {
1564
- return true;
1565
- }
1566
- // not all of openssl's symmetric cipher's support ctr. for those
1567
- // that don't we'll emulate it
1568
- switch ($this->mode) {
1569
- case CRYPT_MODE_CTR:
1570
- if (in_array($this->cipher_name_openssl_ecb, $methods)) {
1571
- $this->openssl_emulate_ctr = true;
1572
- return true;
1573
- }
1574
- }
1575
- return false;
1576
- case CRYPT_ENGINE_MCRYPT:
1577
- return $this->cipher_name_mcrypt &&
1578
- extension_loaded('mcrypt') &&
1579
- in_array($this->cipher_name_mcrypt, mcrypt_list_algorithms());
1580
- case CRYPT_ENGINE_INTERNAL:
1581
- return true;
1582
- }
1583
-
1584
- return false;
1585
- }
1586
-
1587
- /**
1588
- * Sets the preferred crypt engine
1589
- *
1590
- * Currently, $engine could be:
1591
- *
1592
- * - CRYPT_ENGINE_OPENSSL [very fast]
1593
- *
1594
- * - CRYPT_ENGINE_MCRYPT [fast]
1595
- *
1596
- * - CRYPT_ENGINE_INTERNAL [slow]
1597
- *
1598
- * If the preferred crypt engine is not available the fastest available one will be used
1599
- *
1600
- * @see Crypt_Base::Crypt_Base()
1601
- * @param Integer $engine
1602
- * @access public
1603
- */
1604
- function setPreferredEngine($engine)
1605
- {
1606
- switch ($engine) {
1607
- //case CRYPT_ENGINE_OPENSSL:
1608
- case CRYPT_ENGINE_MCRYPT:
1609
- case CRYPT_ENGINE_INTERNAL:
1610
- $this->preferredEngine = $engine;
1611
- break;
1612
- default:
1613
- $this->preferredEngine = CRYPT_ENGINE_OPENSSL;
1614
- }
1615
-
1616
- $this->_setEngine();
1617
- }
1618
-
1619
- /**
1620
- * Returns the engine currently being utilized
1621
- *
1622
- * @see Crypt_Base::_setEngine()
1623
- * @access public
1624
- */
1625
- function getEngine()
1626
- {
1627
- return $this->engine;
1628
- }
1629
-
1630
- /**
1631
- * Sets the engine as appropriate
1632
- *
1633
- * @see Crypt_Base::Crypt_Base()
1634
- * @access private
1635
- */
1636
- function _setEngine()
1637
- {
1638
- $this->engine = null;
1639
-
1640
- $candidateEngines = array(
1641
- $this->preferredEngine,
1642
- CRYPT_ENGINE_OPENSSL,
1643
- CRYPT_ENGINE_MCRYPT
1644
- );
1645
- foreach ($candidateEngines as $engine) {
1646
- if ($this->isValidEngine($engine)) {
1647
- $this->engine = $engine;
1648
- break;
1649
- }
1650
- }
1651
- if (!$this->engine) {
1652
- $this->engine = CRYPT_ENGINE_INTERNAL;
1653
- }
1654
-
1655
- if ($this->engine != CRYPT_ENGINE_MCRYPT && $this->enmcrypt) {
1656
- // Closing the current mcrypt resource(s). _mcryptSetup() will, if needed,
1657
- // (re)open them with the module named in $this->cipher_name_mcrypt
1658
- mcrypt_module_close($this->enmcrypt);
1659
- mcrypt_module_close($this->demcrypt);
1660
- $this->enmcrypt = null;
1661
- $this->demcrypt = null;
1662
-
1663
- if ($this->ecb) {
1664
- mcrypt_module_close($this->ecb);
1665
- $this->ecb = null;
1666
- }
1667
- }
1668
-
1669
- $this->changed = true;
1670
- }
1671
-
1672
- /**
1673
- * Encrypts a block
1674
- *
1675
- * @access private
1676
- * @param String $in
1677
- * @return String
1678
- * @internal Must be extended by the child Crypt_* class
1679
- */
1680
- function _encryptBlock($in)
1681
- {
1682
- user_error((version_compare(PHP_VERSION, '5.0.0', '>=') ? __METHOD__ : __FUNCTION__) . '() must extend by class ' . get_class($this), E_USER_ERROR);
1683
- }
1684
-
1685
- /**
1686
- * Decrypts a block
1687
- *
1688
- * @access private
1689
- * @param String $in
1690
- * @return String
1691
- * @internal Must be extended by the child Crypt_* class
1692
- */
1693
- function _decryptBlock($in)
1694
- {
1695
- user_error((version_compare(PHP_VERSION, '5.0.0', '>=') ? __METHOD__ : __FUNCTION__) . '() must extend by class ' . get_class($this), E_USER_ERROR);
1696
- }
1697
-
1698
- /**
1699
- * Setup the key (expansion)
1700
- *
1701
- * Only used if $engine == CRYPT_ENGINE_INTERNAL
1702
- *
1703
- * @see Crypt_Base::_setup()
1704
- * @access private
1705
- * @internal Must be extended by the child Crypt_* class
1706
- */
1707
- function _setupKey()
1708
- {
1709
- user_error((version_compare(PHP_VERSION, '5.0.0', '>=') ? __METHOD__ : __FUNCTION__) . '() must extend by class ' . get_class($this), E_USER_ERROR);
1710
- }
1711
-
1712
- /**
1713
- * Setup the CRYPT_ENGINE_INTERNAL $engine
1714
- *
1715
- * (re)init, if necessary, the internal cipher $engine and flush all $buffers
1716
- * Used (only) if $engine == CRYPT_ENGINE_INTERNAL
1717
- *
1718
- * _setup() will be called each time if $changed === true
1719
- * typically this happens when using one or more of following public methods:
1720
- *
1721
- * - setKey()
1722
- *
1723
- * - setIV()
1724
- *
1725
- * - disableContinuousBuffer()
1726
- *
1727
- * - First run of encrypt() / decrypt() with no init-settings
1728
- *
1729
- * @see setKey()
1730
- * @see setIV()
1731
- * @see disableContinuousBuffer()
1732
- * @access private
1733
- * @internal _setup() is always called before en/decryption.
1734
- * @internal Could, but not must, extend by the child Crypt_* class
1735
- */
1736
- function _setup()
1737
- {
1738
- $this->_clearBuffers();
1739
- $this->_setupKey();
1740
-
1741
- if ($this->use_inline_crypt) {
1742
- $this->_setupInlineCrypt();
1743
- }
1744
- }
1745
-
1746
- /**
1747
- * Setup the CRYPT_ENGINE_MCRYPT $engine
1748
- *
1749
- * (re)init, if necessary, the (ext)mcrypt resources and flush all $buffers
1750
- * Used (only) if $engine = CRYPT_ENGINE_MCRYPT
1751
- *
1752
- * _setupMcrypt() will be called each time if $changed === true
1753
- * typically this happens when using one or more of following public methods:
1754
- *
1755
- * - setKey()
1756
- *
1757
- * - setIV()
1758
- *
1759
- * - disableContinuousBuffer()
1760
- *
1761
- * - First run of encrypt() / decrypt()
1762
- *
1763
- * @see setKey()
1764
- * @see setIV()
1765
- * @see disableContinuousBuffer()
1766
- * @access private
1767
- * @internal Could, but not must, extend by the child Crypt_* class
1768
- */
1769
- function _setupMcrypt()
1770
- {
1771
- $this->_clearBuffers();
1772
- $this->enchanged = $this->dechanged = true;
1773
-
1774
- if (!isset($this->enmcrypt)) {
1775
- static $mcrypt_modes = array(
1776
- CRYPT_MODE_CTR => 'ctr',
1777
- CRYPT_MODE_ECB => MCRYPT_MODE_ECB,
1778
- CRYPT_MODE_CBC => MCRYPT_MODE_CBC,
1779
- CRYPT_MODE_CFB => 'ncfb',
1780
- CRYPT_MODE_OFB => MCRYPT_MODE_NOFB,
1781
- CRYPT_MODE_STREAM => MCRYPT_MODE_STREAM,
1782
- );
1783
-
1784
- $this->demcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], '');
1785
- $this->enmcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], '');
1786
-
1787
- // we need the $ecb mcrypt resource (only) in MODE_CFB with enableContinuousBuffer()
1788
- // to workaround mcrypt's broken ncfb implementation in buffered mode
1789
- // see: {@link http://phpseclib.sourceforge.net/cfb-demo.phps}
1790
- if ($this->mode == CRYPT_MODE_CFB) {
1791
- $this->ecb = mcrypt_module_open($this->cipher_name_mcrypt, '', MCRYPT_MODE_ECB, '');
1792
- }
1793
-
1794
- } // else should mcrypt_generic_deinit be called?
1795
-
1796
- if ($this->mode == CRYPT_MODE_CFB) {
1797
- mcrypt_generic_init($this->ecb, $this->key, str_repeat("\0", $this->block_size));
1798
- }
1799
- }
1800
-
1801
- /**
1802
- * Pads a string
1803
- *
1804
- * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize.
1805
- * $this->block_size - (strlen($text) % $this->block_size) bytes are added, each of which is equal to
1806
- * chr($this->block_size - (strlen($text) % $this->block_size)
1807
- *
1808
- * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless
1809
- * and padding will, hence forth, be enabled.
1810
- *
1811
- * @see Crypt_Base::_unpad()
1812
- * @param String $text
1813
- * @access private
1814
- * @return String
1815
- */
1816
- function _pad($text)
1817
- {
1818
- $length = strlen($text);
1819
-
1820
- if (!$this->padding) {
1821
- if ($length % $this->block_size == 0) {
1822
- return $text;
1823
- } else {
1824
- user_error("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size})");
1825
- $this->padding = true;
1826
- }
1827
- }
1828
-
1829
- $pad = $this->block_size - ($length % $this->block_size);
1830
-
1831
- return str_pad($text, $length + $pad, chr($pad));
1832
- }
1833
-
1834
- /**
1835
- * Unpads a string.
1836
- *
1837
- * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong
1838
- * and false will be returned.
1839
- *
1840
- * @see Crypt_Base::_pad()
1841
- * @param String $text
1842
- * @access private
1843
- * @return String
1844
- */
1845
- function _unpad($text)
1846
- {
1847
- if (!$this->padding) {
1848
- return $text;
1849
- }
1850
-
1851
- $length = ord($text[strlen($text) - 1]);
1852
-
1853
- if (!$length || $length > $this->block_size) {
1854
- return false;
1855
- }
1856
-
1857
- return substr($text, 0, -$length);
1858
- }
1859
-
1860
- /**
1861
- * Clears internal buffers
1862
- *
1863
- * Clearing/resetting the internal buffers is done everytime
1864
- * after disableContinuousBuffer() or on cipher $engine (re)init
1865
- * ie after setKey() or setIV()
1866
- *
1867
- * @access public
1868
- * @internal Could, but not must, extend by the child Crypt_* class
1869
- */
1870
- function _clearBuffers()
1871
- {
1872
- $this->enbuffer = $this->debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);
1873
-
1874
- // mcrypt's handling of invalid's $iv:
1875
- // $this->encryptIV = $this->decryptIV = strlen($this->iv) == $this->block_size ? $this->iv : str_repeat("\0", $this->block_size);
1876
- $this->encryptIV = $this->decryptIV = str_pad(substr($this->iv, 0, $this->block_size), $this->block_size, "\0");
1877
- }
1878
-
1879
- /**
1880
- * String Shift
1881
- *
1882
- * Inspired by array_shift
1883
- *
1884
- * @param String $string
1885
- * @param optional Integer $index
1886
- * @access private
1887
- * @return String
1888
- */
1889
- function _string_shift(&$string, $index = 1)
1890
- {
1891
- $substr = substr($string, 0, $index);
1892
- $string = substr($string, $index);
1893
- return $substr;
1894
- }
1895
-
1896
- /**
1897
- * String Pop
1898
- *
1899
- * Inspired by array_pop
1900
- *
1901
- * @param String $string
1902
- * @param optional Integer $index
1903
- * @access private
1904
- * @return String
1905
- */
1906
- function _string_pop(&$string, $index = 1)
1907
- {
1908
- $substr = substr($string, -$index);
1909
- $string = substr($string, 0, -$index);
1910
- return $substr;
1911
- }
1912
-
1913
- /**
1914
- * Increment the current string
1915
- *
1916
- * @see Crypt_Base::decrypt()
1917
- * @see Crypt_Base::encrypt()
1918
- * @param String $var
1919
- * @access private
1920
- */
1921
- function _increment_str(&$var)
1922
- {
1923
- for ($i = 4; $i <= strlen($var); $i+= 4) {
1924
- $temp = substr($var, -$i, 4);
1925
- switch ($temp) {
1926
- case "\xFF\xFF\xFF\xFF":
1927
- $var = substr_replace($var, "\x00\x00\x00\x00", -$i, 4);
1928
- break;
1929
- case "\x7F\xFF\xFF\xFF":
1930
- $var = substr_replace($var, "\x80\x00\x00\x00", -$i, 4);
1931
- return;
1932
- default:
1933
- $temp = unpack('Nnum', $temp);
1934
- $var = substr_replace($var, pack('N', $temp['num'] + 1), -$i, 4);
1935
- return;
1936
- }
1937
- }
1938
-
1939
- $remainder = strlen($var) % 4;
1940
-
1941
- if ($remainder == 0) {
1942
- return;
1943
- }
1944
-
1945
- $temp = unpack('Nnum', str_pad(substr($var, 0, $remainder), 4, "\0", STR_PAD_LEFT));
1946
- $temp = substr(pack('N', $temp['num'] + 1), -$remainder);
1947
- $var = substr_replace($var, $temp, 0, $remainder);
1948
- }
1949
-
1950
- /**
1951
- * Setup the performance-optimized function for de/encrypt()
1952
- *
1953
- * Stores the created (or existing) callback function-name
1954
- * in $this->inline_crypt
1955
- *
1956
- * Internally for phpseclib developers:
1957
- *
1958
- * _setupInlineCrypt() would be called only if:
1959
- *
1960
- * - $engine == CRYPT_ENGINE_INTERNAL and
1961
- *
1962
- * - $use_inline_crypt === true
1963
- *
1964
- * - each time on _setup(), after(!) _setupKey()
1965
- *
1966
- *
1967
- * This ensures that _setupInlineCrypt() has always a
1968
- * full ready2go initializated internal cipher $engine state
1969
- * where, for example, the keys allready expanded,
1970
- * keys/block_size calculated and such.
1971
- *
1972
- * It is, each time if called, the responsibility of _setupInlineCrypt():
1973
- *
1974
- * - to set $this->inline_crypt to a valid and fully working callback function
1975
- * as a (faster) replacement for encrypt() / decrypt()
1976
- *
1977
- * - NOT to create unlimited callback functions (for memory reasons!)
1978
- * no matter how often _setupInlineCrypt() would be called. At some
1979
- * point of amount they must be generic re-useable.
1980
- *
1981
- * - the code of _setupInlineCrypt() it self,
1982
- * and the generated callback code,
1983
- * must be, in following order:
1984
- * - 100% safe
1985
- * - 100% compatible to encrypt()/decrypt()
1986
- * - using only php5+ features/lang-constructs/php-extensions if
1987
- * compatibility (down to php4) or fallback is provided
1988
- * - readable/maintainable/understandable/commented and... not-cryptic-styled-code :-)
1989
- * - >= 10% faster than encrypt()/decrypt() [which is, by the way,
1990
- * the reason for the existence of _setupInlineCrypt() :-)]
1991
- * - memory-nice
1992
- * - short (as good as possible)
1993
- *
1994
- * Note: - _setupInlineCrypt() is using _createInlineCryptFunction() to create the full callback function code.
1995
- * - In case of using inline crypting, _setupInlineCrypt() must extend by the child Crypt_* class.
1996
- * - The following variable names are reserved:
1997
- * - $_* (all variable names prefixed with an underscore)
1998
- * - $self (object reference to it self. Do not use $this, but $self instead)
1999
- * - $in (the content of $in has to en/decrypt by the generated code)
2000
- * - The callback function should not use the 'return' statement, but en/decrypt'ing the content of $in only
2001
- *
2002
- *
2003
- * @see Crypt_Base::_setup()
2004
- * @see Crypt_Base::_createInlineCryptFunction()
2005
- * @see Crypt_Base::encrypt()
2006
- * @see Crypt_Base::decrypt()
2007
- * @access private
2008
- * @internal If a Crypt_* class providing inline crypting it must extend _setupInlineCrypt()
2009
- */
2010
- function _setupInlineCrypt()
2011
- {
2012
- // If, for any reason, an extending Crypt_Base() Crypt_* class
2013
- // not using inline crypting then it must be ensured that: $this->use_inline_crypt = false
2014
- // ie in the class var declaration of $use_inline_crypt in general for the Crypt_* class,
2015
- // in the constructor at object instance-time
2016
- // or, if it's runtime-specific, at runtime
2017
-
2018
- $this->use_inline_crypt = false;
2019
- }
2020
-
2021
- /**
2022
- * Creates the performance-optimized function for en/decrypt()
2023
- *
2024
- * Internally for phpseclib developers:
2025
- *
2026
- * _createInlineCryptFunction():
2027
- *
2028
- * - merge the $cipher_code [setup'ed by _setupInlineCrypt()]
2029
- * with the current [$this->]mode of operation code
2030
- *
2031
- * - create the $inline function, which called by encrypt() / decrypt()
2032
- * as its replacement to speed up the en/decryption operations.
2033
- *
2034
- * - return the name of the created $inline callback function
2035
- *
2036
- * - used to speed up en/decryption
2037
- *
2038
- *
2039
- *
2040
- * The main reason why can speed up things [up to 50%] this way are:
2041
- *
2042
- * - using variables more effective then regular.
2043
- * (ie no use of expensive arrays but integers $k_0, $k_1 ...
2044
- * or even, for example, the pure $key[] values hardcoded)
2045
- *
2046
- * - avoiding 1000's of function calls of ie _encryptBlock()
2047
- * but inlining the crypt operations.
2048
- * in the mode of operation for() loop.
2049
- *
2050
- * - full loop unroll the (sometimes key-dependent) rounds
2051
- * avoiding this way ++$i counters and runtime-if's etc...
2052
- *
2053
- * The basic code architectur of the generated $inline en/decrypt()
2054
- * lambda function, in pseudo php, is:
2055
- *
2056
- * <code>
2057
- * +----------------------------------------------------------------------------------------------+
2058
- * | callback $inline = create_function: |
2059
- * | lambda_function_0001_crypt_ECB($action, $text) |
2060
- * | { |
2061
- * | INSERT PHP CODE OF: |
2062
- * | $cipher_code['init_crypt']; // general init code. |
2063
- * | // ie: $sbox'es declarations used for |
2064
- * | // encrypt and decrypt'ing. |
2065
- * | |
2066
- * | switch ($action) { |
2067
- * | case 'encrypt': |
2068
- * | INSERT PHP CODE OF: |
2069
- * | $cipher_code['init_encrypt']; // encrypt sepcific init code. |
2070
- * | ie: specified $key or $box |
2071
- * | declarations for encrypt'ing. |
2072
- * | |
2073
- * | foreach ($ciphertext) { |
2074
- * | $in = $block_size of $ciphertext; |
2075
- * | |
2076
- * | INSERT PHP CODE OF: |
2077
- * | $cipher_code['encrypt_block']; // encrypt's (string) $in, which is always: |
2078
- * | // strlen($in) == $this->block_size |
2079
- * | // here comes the cipher algorithm in action |
2080
- * | // for encryption. |
2081
- * | // $cipher_code['encrypt_block'] has to |
2082
- * | // encrypt the content of the $in variable |
2083
- * | |
2084
- * | $plaintext .= $in; |
2085
- * | } |
2086
- * | return $plaintext; |
2087
- * | |
2088
- * | case 'decrypt': |
2089
- * | INSERT PHP CODE OF: |
2090
- * | $cipher_code['init_decrypt']; // decrypt sepcific init code |
2091
- * | ie: specified $key or $box |
2092
- * | declarations for decrypt'ing. |
2093
- * | foreach ($plaintext) { |
2094
- * | $in = $block_size of $plaintext; |
2095
- * | |
2096
- * | INSERT PHP CODE OF: |
2097
- * | $cipher_code['decrypt_block']; // decrypt's (string) $in, which is always |
2098
- * | // strlen($in) == $this->block_size |
2099
- * | // here comes the cipher algorithm in action |
2100
- * | // for decryption. |
2101
- * | // $cipher_code['decrypt_block'] has to |
2102
- * | // decrypt the content of the $in variable |
2103
- * | $ciphertext .= $in; |
2104
- * | } |
2105
- * | return $ciphertext; |
2106
- * | } |
2107
- * | } |
2108
- * +----------------------------------------------------------------------------------------------+
2109
- * </code>
2110
- *
2111
- * See also the Crypt_*::_setupInlineCrypt()'s for
2112
- * productive inline $cipher_code's how they works.
2113
- *
2114
- * Structure of:
2115
- * <code>
2116
- * $cipher_code = array(
2117
- * 'init_crypt' => (string) '', // optional
2118
- * 'init_encrypt' => (string) '', // optional
2119
- * 'init_decrypt' => (string) '', // optional
2120
- * 'encrypt_block' => (string) '', // required
2121
- * 'decrypt_block' => (string) '' // required
2122
- * );
2123
- * </code>
2124
- *
2125
- * @see Crypt_Base::_setupInlineCrypt()
2126
- * @see Crypt_Base::encrypt()
2127
- * @see Crypt_Base::decrypt()
2128
- * @param Array $cipher_code
2129
- * @access private
2130
- * @return String (the name of the created callback function)
2131
- */
2132
- function _createInlineCryptFunction($cipher_code)
2133
- {
2134
- $block_size = $this->block_size;
2135
-
2136
- // optional
2137
- $init_crypt = isset($cipher_code['init_crypt']) ? $cipher_code['init_crypt'] : '';
2138
- $init_encrypt = isset($cipher_code['init_encrypt']) ? $cipher_code['init_encrypt'] : '';
2139
- $init_decrypt = isset($cipher_code['init_decrypt']) ? $cipher_code['init_decrypt'] : '';
2140
- // required
2141
- $encrypt_block = $cipher_code['encrypt_block'];
2142
- $decrypt_block = $cipher_code['decrypt_block'];
2143
-
2144
- // Generating mode of operation inline code,
2145
- // merged with the $cipher_code algorithm
2146
- // for encrypt- and decryption.
2147
- switch ($this->mode) {
2148
- case CRYPT_MODE_ECB:
2149
- $encrypt = $init_encrypt . '
2150
- $_ciphertext = "";
2151
- $_plaintext_len = strlen($_text);
2152
-
2153
- for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
2154
- $in = substr($_text, $_i, '.$block_size.');
2155
- '.$encrypt_block.'
2156
- $_ciphertext.= $in;
2157
- }
2158
-
2159
- return $_ciphertext;
2160
- ';
2161
-
2162
- $decrypt = $init_decrypt . '
2163
- $_plaintext = "";
2164
- $_text = str_pad($_text, strlen($_text) + ('.$block_size.' - strlen($_text) % '.$block_size.') % '.$block_size.', chr(0));
2165
- $_ciphertext_len = strlen($_text);
2166
-
2167
- for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
2168
- $in = substr($_text, $_i, '.$block_size.');
2169
- '.$decrypt_block.'
2170
- $_plaintext.= $in;
2171
- }
2172
-
2173
- return $self->_unpad($_plaintext);
2174
- ';
2175
- break;
2176
- case CRYPT_MODE_CTR:
2177
- $encrypt = $init_encrypt . '
2178
- $_ciphertext = "";
2179
- $_plaintext_len = strlen($_text);
2180
- $_xor = $self->encryptIV;
2181
- $_buffer = &$self->enbuffer;
2182
- if (strlen($_buffer["ciphertext"])) {
2183
- for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
2184
- $_block = substr($_text, $_i, '.$block_size.');
2185
- if (strlen($_block) > strlen($_buffer["ciphertext"])) {
2186
- $in = $_xor;
2187
- '.$encrypt_block.'
2188
- $self->_increment_str($_xor);
2189
- $_buffer["ciphertext"].= $in;
2190
- }
2191
- $_key = $self->_string_shift($_buffer["ciphertext"], '.$block_size.');
2192
- $_ciphertext.= $_block ^ $_key;
2193
- }
2194
- } else {
2195
- for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
2196
- $_block = substr($_text, $_i, '.$block_size.');
2197
- $in = $_xor;
2198
- '.$encrypt_block.'
2199
- $self->_increment_str($_xor);
2200
- $_key = $in;
2201
- $_ciphertext.= $_block ^ $_key;
2202
- }
2203
- }
2204
- if ($self->continuousBuffer) {
2205
- $self->encryptIV = $_xor;
2206
- if ($_start = $_plaintext_len % '.$block_size.') {
2207
- $_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"];
2208
- }
2209
- }
2210
-
2211
- return $_ciphertext;
2212
- ';
2213
-
2214
- $decrypt = $init_encrypt . '
2215
- $_plaintext = "";
2216
- $_ciphertext_len = strlen($_text);
2217
- $_xor = $self->decryptIV;
2218
- $_buffer = &$self->debuffer;
2219
-
2220
- if (strlen($_buffer["ciphertext"])) {
2221
- for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
2222
- $_block = substr($_text, $_i, '.$block_size.');
2223
- if (strlen($_block) > strlen($_buffer["ciphertext"])) {
2224
- $in = $_xor;
2225
- '.$encrypt_block.'
2226
- $self->_increment_str($_xor);
2227
- $_buffer["ciphertext"].= $in;
2228
- }
2229
- $_key = $self->_string_shift($_buffer["ciphertext"], '.$block_size.');
2230
- $_plaintext.= $_block ^ $_key;
2231
- }
2232
- } else {
2233
- for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
2234
- $_block = substr($_text, $_i, '.$block_size.');
2235
- $in = $_xor;
2236
- '.$encrypt_block.'
2237
- $self->_increment_str($_xor);
2238
- $_key = $in;
2239
- $_plaintext.= $_block ^ $_key;
2240
- }
2241
- }
2242
- if ($self->continuousBuffer) {
2243
- $self->decryptIV = $_xor;
2244
- if ($_start = $_ciphertext_len % '.$block_size.') {
2245
- $_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"];
2246
- }
2247
- }
2248
-
2249
- return $_plaintext;
2250
- ';
2251
- break;
2252
- case CRYPT_MODE_CFB:
2253
- $encrypt = $init_encrypt . '
2254
- $_ciphertext = "";
2255
- $_buffer = &$self->enbuffer;
2256
-
2257
- if ($self->continuousBuffer) {
2258
- $_iv = &$self->encryptIV;
2259
- $_pos = &$_buffer["pos"];
2260
- } else {
2261
- $_iv = $self->encryptIV;
2262
- $_pos = 0;
2263
- }
2264
- $_len = strlen($_text);
2265
- $_i = 0;
2266
- if ($_pos) {
2267
- $_orig_pos = $_pos;
2268
- $_max = '.$block_size.' - $_pos;
2269
- if ($_len >= $_max) {
2270
- $_i = $_max;
2271
- $_len-= $_max;
2272
- $_pos = 0;
2273
- } else {
2274
- $_i = $_len;
2275
- $_pos+= $_len;
2276
- $_len = 0;
2277
- }
2278
- $_ciphertext = substr($_iv, $_orig_pos) ^ $_text;
2279
- $_iv = substr_replace($_iv, $_ciphertext, $_orig_pos, $_i);
2280
- }
2281
- while ($_len >= '.$block_size.') {
2282
- $in = $_iv;
2283
- '.$encrypt_block.';
2284
- $_iv = $in ^ substr($_text, $_i, '.$block_size.');
2285
- $_ciphertext.= $_iv;
2286
- $_len-= '.$block_size.';
2287
- $_i+= '.$block_size.';
2288
- }
2289
- if ($_len) {
2290
- $in = $_iv;
2291
- '.$encrypt_block.'
2292
- $_iv = $in;
2293
- $_block = $_iv ^ substr($_text, $_i);
2294
- $_iv = substr_replace($_iv, $_block, 0, $_len);
2295
- $_ciphertext.= $_block;
2296
- $_pos = $_len;
2297
- }
2298
- return $_ciphertext;
2299
- ';
2300
-
2301
- $decrypt = $init_encrypt . '
2302
- $_plaintext = "";
2303
- $_buffer = &$self->debuffer;
2304
-
2305
- if ($self->continuousBuffer) {
2306
- $_iv = &$self->decryptIV;
2307
- $_pos = &$_buffer["pos"];
2308
- } else {
2309
- $_iv = $self->decryptIV;
2310
- $_pos = 0;
2311
- }
2312
- $_len = strlen($_text);
2313
- $_i = 0;
2314
- if ($_pos) {
2315
- $_orig_pos = $_pos;
2316
- $_max = '.$block_size.' - $_pos;
2317
- if ($_len >= $_max) {
2318
- $_i = $_max;
2319
- $_len-= $_max;
2320
- $_pos = 0;
2321
- } else {
2322
- $_i = $_len;
2323
- $_pos+= $_len;
2324
- $_len = 0;
2325
- }
2326
- $_plaintext = substr($_iv, $_orig_pos) ^ $_text;
2327
- $_iv = substr_replace($_iv, substr($_text, 0, $_i), $_orig_pos, $_i);
2328
- }
2329
- while ($_len >= '.$block_size.') {
2330
- $in = $_iv;
2331
- '.$encrypt_block.'
2332
- $_iv = $in;
2333
- $cb = substr($_text, $_i, '.$block_size.');
2334
- $_plaintext.= $_iv ^ $cb;
2335
- $_iv = $cb;
2336
- $_len-= '.$block_size.';
2337
- $_i+= '.$block_size.';
2338
- }
2339
- if ($_len) {
2340
- $in = $_iv;
2341
- '.$encrypt_block.'
2342
- $_iv = $in;
2343
- $_plaintext.= $_iv ^ substr($_text, $_i);
2344
- $_iv = substr_replace($_iv, substr($_text, $_i), 0, $_len);
2345
- $_pos = $_len;
2346
- }
2347
-
2348
- return $_plaintext;
2349
- ';
2350
- break;
2351
- case CRYPT_MODE_OFB:
2352
- $encrypt = $init_encrypt . '
2353
- $_ciphertext = "";
2354
- $_plaintext_len = strlen($_text);
2355
- $_xor = $self->encryptIV;
2356
- $_buffer = &$self->enbuffer;
2357
-
2358
- if (strlen($_buffer["xor"])) {
2359
- for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
2360
- $_block = substr($_text, $_i, '.$block_size.');
2361
- if (strlen($_block) > strlen($_buffer["xor"])) {
2362
- $in = $_xor;
2363
- '.$encrypt_block.'
2364
- $_xor = $in;
2365
- $_buffer["xor"].= $_xor;
2366
- }
2367
- $_key = $self->_string_shift($_buffer["xor"], '.$block_size.');
2368
- $_ciphertext.= $_block ^ $_key;
2369
- }
2370
- } else {
2371
- for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
2372
- $in = $_xor;
2373
- '.$encrypt_block.'
2374
- $_xor = $in;
2375
- $_ciphertext.= substr($_text, $_i, '.$block_size.') ^ $_xor;
2376
- }
2377
- $_key = $_xor;
2378
- }
2379
- if ($self->continuousBuffer) {
2380
- $self->encryptIV = $_xor;
2381
- if ($_start = $_plaintext_len % '.$block_size.') {
2382
- $_buffer["xor"] = substr($_key, $_start) . $_buffer["xor"];
2383
- }
2384
- }
2385
- return $_ciphertext;
2386
- ';
2387
-
2388
- $decrypt = $init_encrypt . '
2389
- $_plaintext = "";
2390
- $_ciphertext_len = strlen($_text);
2391
- $_xor = $self->decryptIV;
2392
- $_buffer = &$self->debuffer;
2393
-
2394
- if (strlen($_buffer["xor"])) {
2395
- for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
2396
- $_block = substr($_text, $_i, '.$block_size.');
2397
- if (strlen($_block) > strlen($_buffer["xor"])) {
2398
- $in = $_xor;
2399
- '.$encrypt_block.'
2400
- $_xor = $in;
2401
- $_buffer["xor"].= $_xor;
2402
- }
2403
- $_key = $self->_string_shift($_buffer["xor"], '.$block_size.');
2404
- $_plaintext.= $_block ^ $_key;
2405
- }
2406
- } else {
2407
- for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
2408
- $in = $_xor;
2409
- '.$encrypt_block.'
2410
- $_xor = $in;
2411
- $_plaintext.= substr($_text, $_i, '.$block_size.') ^ $_xor;
2412
- }
2413
- $_key = $_xor;
2414
- }
2415
- if ($self->continuousBuffer) {
2416
- $self->decryptIV = $_xor;
2417
- if ($_start = $_ciphertext_len % '.$block_size.') {
2418
- $_buffer["xor"] = substr($_key, $_start) . $_buffer["xor"];
2419
- }
2420
- }
2421
- return $_plaintext;
2422
- ';
2423
- break;
2424
- case CRYPT_MODE_STREAM:
2425
- $encrypt = $init_encrypt . '
2426
- $_ciphertext = "";
2427
- '.$encrypt_block.'
2428
- return $_ciphertext;
2429
- ';
2430
- $decrypt = $init_decrypt . '
2431
- $_plaintext = "";
2432
- '.$decrypt_block.'
2433
- return $_plaintext;
2434
- ';
2435
- break;
2436
- // case CRYPT_MODE_CBC:
2437
- default:
2438
- $encrypt = $init_encrypt . '
2439
- $_ciphertext = "";
2440
- $_plaintext_len = strlen($_text);
2441
-
2442
- $in = $self->encryptIV;
2443
-
2444
- for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
2445
- $in = substr($_text, $_i, '.$block_size.') ^ $in;
2446
- '.$encrypt_block.'
2447
- $_ciphertext.= $in;
2448
- }
2449
-
2450
- if ($self->continuousBuffer) {
2451
- $self->encryptIV = $in;
2452
- }
2453
-
2454
- return $_ciphertext;
2455
- ';
2456
-
2457
- $decrypt = $init_decrypt . '
2458
- $_plaintext = "";
2459
- $_text = str_pad($_text, strlen($_text) + ('.$block_size.' - strlen($_text) % '.$block_size.') % '.$block_size.', chr(0));
2460
- $_ciphertext_len = strlen($_text);
2461
-
2462
- $_iv = $self->decryptIV;
2463
-
2464
- for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
2465
- $in = $_block = substr($_text, $_i, '.$block_size.');
2466
- '.$decrypt_block.'
2467
- $_plaintext.= $in ^ $_iv;
2468
- $_iv = $_block;
2469
- }
2470
-
2471
- if ($self->continuousBuffer) {
2472
- $self->decryptIV = $_iv;
2473
- }
2474
-
2475
- return $self->_unpad($_plaintext);
2476
- ';
2477
- break;
2478
- }
2479
-
2480
- // Create the $inline function and return its name as string. Ready to run!
2481
- return create_function('$_action, &$self, $_text', $init_crypt . 'if ($_action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' }');
2482
- }
2483
-
2484
- /**
2485
- * Holds the lambda_functions table (classwide)
2486
- *
2487
- * Each name of the lambda function, created from
2488
- * _setupInlineCrypt() && _createInlineCryptFunction()
2489
- * is stored, classwide (!), here for reusing.
2490
- *
2491
- * The string-based index of $function is a classwide
2492
- * uniqe value representing, at least, the $mode of
2493
- * operation (or more... depends of the optimizing level)
2494
- * for which $mode the lambda function was created.
2495
- *
2496
- * @access private
2497
- * @return Array &$functions
2498
- */
2499
- function &_getLambdaFunctions()
2500
- {
2501
- static $functions = array();
2502
- return $functions;
2503
- }
2504
-
2505
- /**
2506
- * Generates a digest from $bytes
2507
- *
2508
- * @see _setupInlineCrypt()
2509
- * @access private
2510
- * @param $bytes
2511
- * @return String
2512
- */
2513
- function _hashInlineCryptFunction($bytes)
2514
- {
2515
- if (!defined('CRYPT_BASE_WHIRLPOOL_AVAILABLE')) {
2516
- define('CRYPT_BASE_WHIRLPOOL_AVAILABLE', (bool)(extension_loaded('hash') && in_array('whirlpool', hash_algos())));
2517
- }
2518
-
2519
- $result = '';
2520
- $hash = $bytes;
2521
-
2522
- switch (true) {
2523
- case CRYPT_BASE_WHIRLPOOL_AVAILABLE:
2524
- foreach (str_split($bytes, 64) as $t) {
2525
- $hash = hash('whirlpool', $hash, true);
2526
- $result .= $t ^ $hash;
2527
- }
2528
- return $result . hash('whirlpool', $hash, true);
2529
- default:
2530
- $len = strlen($bytes);
2531
- for ($i = 0; $i < $len; $i+=20) {
2532
- $t = substr($bytes, $i, 20);
2533
- $hash = pack('H*', sha1($hash));
2534
- $result .= $t ^ $hash;
2535
- }
2536
- return $result . pack('H*', sha1($hash));
2537
- }
2538
- }
2539
- }