SSH SFTP Updater Support - Version 0.4

Version Description

  • fix an E_NOTICE (thanks, runblip!)
  • make it so keys that are copy / pasted in are saved with HTML5's localStorage (thanks, kkzk!)
  • update phpseclib to latest Git
Download this release

Release Info

Developer TerraFrost
Plugin Icon wp plugin SSH SFTP Updater Support
Version 0.4
Comparing to
See all releases

Code changes from version 0.3 to 0.4

phpseclib/Crypt/AES.php CHANGED
@@ -66,7 +66,9 @@
66
  /**
67
  * Include Crypt_Rijndael
68
  */
69
- require_once 'Rijndael.php';
 
 
70
 
71
  /**#@+
72
  * @access public
@@ -178,10 +180,7 @@ class Crypt_AES extends Crypt_Rijndael {
178
  {
179
  if ( !defined('CRYPT_AES_MODE') ) {
180
  switch (true) {
181
- case extension_loaded('mcrypt'):
182
- // i'd check to see if aes was supported, by doing in_array('des', mcrypt_list_algorithms('')),
183
- // but since that can be changed after the object has been created, there doesn't seem to be
184
- // a lot of point...
185
  define('CRYPT_AES_MODE', CRYPT_AES_MODE_MCRYPT);
186
  break;
187
  default:
@@ -215,8 +214,6 @@ class Crypt_AES extends Crypt_Rijndael {
215
  $this->mode = MCRYPT_MODE_CBC;
216
  }
217
 
218
- $this->debuffer = $this->enbuffer = '';
219
-
220
  break;
221
  default:
222
  switch ($mode) {
@@ -312,18 +309,20 @@ class Crypt_AES extends Crypt_Rijndael {
312
  // re: http://phpseclib.sourceforge.net/cfb-demo.phps
313
  // using mcrypt's default handing of CFB the above would output two different things. using phpseclib's
314
  // rewritten CFB implementation the above outputs the same thing twice.
315
- if ($this->mode == 'ncfb') {
316
  if ($changed) {
317
  $this->ecb = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
318
  mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
319
  }
320
 
321
- if (strlen($this->enbuffer)) {
322
- $ciphertext = $plaintext ^ substr($this->encryptIV, strlen($this->enbuffer));
323
- $this->enbuffer.= $ciphertext;
324
- if (strlen($this->enbuffer) == 16) {
325
- $this->encryptIV = $this->enbuffer;
326
- $this->enbuffer = '';
 
 
327
  mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
328
  }
329
  $plaintext = substr($plaintext, strlen($ciphertext));
@@ -332,15 +331,15 @@ class Crypt_AES extends Crypt_Rijndael {
332
  }
333
 
334
  $last_pos = strlen($plaintext) & 0xFFFFFFF0;
335
- $ciphertext.= $last_pos ? mcrypt_generic($this->enmcrypt, substr($plaintext, 0, $last_pos)) : '';
 
 
 
336
 
337
  if (strlen($plaintext) & 0xF) {
338
- if (strlen($ciphertext)) {
339
- $this->encryptIV = substr($ciphertext, -16);
340
- }
341
  $this->encryptIV = mcrypt_generic($this->ecb, $this->encryptIV);
342
- $this->enbuffer = substr($plaintext, $last_pos) ^ $this->encryptIV;
343
- $ciphertext.= $this->enbuffer;
344
  }
345
 
346
  return $ciphertext;
@@ -387,19 +386,21 @@ class Crypt_AES extends Crypt_Rijndael {
387
  return $plaintext;
388
  }
389
  */
390
- if ($this->mode == 'ncfb') {
391
  if ($changed) {
392
  $this->ecb = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
393
  mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
394
  }
395
 
396
- if (strlen($this->debuffer)) {
397
- $plaintext = $ciphertext ^ substr($this->decryptIV, strlen($this->debuffer));
398
 
399
- $this->debuffer.= substr($ciphertext, 0, strlen($plaintext));
400
- if (strlen($this->debuffer) == 16) {
401
- $this->decryptIV = $this->debuffer;
402
- $this->debuffer = '';
 
 
 
403
  mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
404
  }
405
  $ciphertext = substr($ciphertext, strlen($plaintext));
@@ -408,15 +409,15 @@ class Crypt_AES extends Crypt_Rijndael {
408
  }
409
 
410
  $last_pos = strlen($ciphertext) & 0xFFFFFFF0;
411
- $plaintext.= $last_pos ? mdecrypt_generic($this->demcrypt, substr($ciphertext, 0, $last_pos)) : '';
 
 
 
 
412
 
413
  if (strlen($ciphertext) & 0xF) {
414
- if (strlen($plaintext)) {
415
- $this->decryptIV = substr($ciphertext, $last_pos - 16, 16);
416
- }
417
- $this->decryptIV = mcrypt_generic($this->ecb, $this->decryptIV);
418
- $this->debuffer = substr($ciphertext, $last_pos);
419
- $plaintext.= $this->debuffer ^ $this->decryptIV;
420
  }
421
 
422
  return $plaintext;
@@ -527,7 +528,7 @@ class Crypt_AES extends Crypt_Rijndael {
527
  // shiftRows + subWord + mixColumns + addRoundKey
528
  // we could loop unroll this and use if statements to do more rounds as necessary, but, in my tests, that yields
529
  // only a marginal improvement. since that also, imho, hinders the readability of the code, i've opted not to do it.
530
- for ($round = 1; $round < $this->Nr; $round++) {
531
  $state = array(
532
  $t0[$state[0] & 0xFF000000] ^ $t1[$state[1] & 0x00FF0000] ^ $t2[$state[2] & 0x0000FF00] ^ $t3[$state[3] & 0x000000FF] ^ $w[$round][0],
533
  $t0[$state[1] & 0xFF000000] ^ $t1[$state[2] & 0x00FF0000] ^ $t2[$state[3] & 0x0000FF00] ^ $t3[$state[0] & 0x000000FF] ^ $w[$round][1],
@@ -587,7 +588,7 @@ class Crypt_AES extends Crypt_Rijndael {
587
 
588
 
589
  // invShiftRows + invSubBytes + invMixColumns + addRoundKey
590
- for ($round = $this->Nr - 1; $round > 0; $round--) {
591
  $state = array(
592
  $dt0[$state[0] & 0xFF000000] ^ $dt1[$state[3] & 0x00FF0000] ^ $dt2[$state[2] & 0x0000FF00] ^ $dt3[$state[1] & 0x000000FF] ^ $dw[$round][0],
593
  $dt0[$state[1] & 0xFF000000] ^ $dt1[$state[0] & 0x00FF0000] ^ $dt2[$state[3] & 0x0000FF00] ^ $dt3[$state[2] & 0x000000FF] ^ $dw[$round][1],
@@ -606,6 +607,24 @@ class Crypt_AES extends Crypt_Rijndael {
606
 
607
  return pack('N*', $state[0], $state[1], $state[2], $state[3]);
608
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
609
  }
610
 
611
  // vim: ts=4:sw=4:et:
66
  /**
67
  * Include Crypt_Rijndael
68
  */
69
+ if (!class_exists('Crypt_Rijndael')) {
70
+ require_once 'Rijndael.php';
71
+ }
72
 
73
  /**#@+
74
  * @access public
180
  {
181
  if ( !defined('CRYPT_AES_MODE') ) {
182
  switch (true) {
183
+ case extension_loaded('mcrypt') && in_array('rijndael-128', mcrypt_list_algorithms()):
 
 
 
184
  define('CRYPT_AES_MODE', CRYPT_AES_MODE_MCRYPT);
185
  break;
186
  default:
214
  $this->mode = MCRYPT_MODE_CBC;
215
  }
216
 
 
 
217
  break;
218
  default:
219
  switch ($mode) {
309
  // re: http://phpseclib.sourceforge.net/cfb-demo.phps
310
  // using mcrypt's default handing of CFB the above would output two different things. using phpseclib's
311
  // rewritten CFB implementation the above outputs the same thing twice.
312
+ if ($this->mode == 'ncfb' && $this->continuousBuffer) {
313
  if ($changed) {
314
  $this->ecb = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
315
  mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
316
  }
317
 
318
+ $buffer = &$this->enbuffer['encrypted'];
319
+
320
+ if (strlen($buffer)) {
321
+ $ciphertext = $plaintext ^ substr($this->encryptIV, strlen($buffer));
322
+ $buffer.= $ciphertext;
323
+ if (strlen($buffer) == 16) {
324
+ $this->encryptIV = $buffer;
325
+ $buffer = '';
326
  mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
327
  }
328
  $plaintext = substr($plaintext, strlen($ciphertext));
331
  }
332
 
333
  $last_pos = strlen($plaintext) & 0xFFFFFFF0;
334
+ if ($last_pos) {
335
+ $ciphertext.= mcrypt_generic($this->enmcrypt, substr($plaintext, 0, $last_pos));
336
+ $this->encryptIV = substr($ciphertext, -16);
337
+ }
338
 
339
  if (strlen($plaintext) & 0xF) {
 
 
 
340
  $this->encryptIV = mcrypt_generic($this->ecb, $this->encryptIV);
341
+ $buffer = substr($plaintext, $last_pos) ^ $this->encryptIV;
342
+ $ciphertext.= $buffer;
343
  }
344
 
345
  return $ciphertext;
386
  return $plaintext;
387
  }
388
  */
389
+ if ($this->mode == 'ncfb' && $this->continuousBuffer) {
390
  if ($changed) {
391
  $this->ecb = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_ECB, '');
392
  mcrypt_generic_init($this->ecb, $this->key, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
393
  }
394
 
395
+ $buffer = &$this->debuffer['ciphertext'];
 
396
 
397
+ if (strlen($buffer)) {
398
+ $plaintext = $ciphertext ^ substr($this->decryptIV, strlen($buffer));
399
+
400
+ $buffer.= substr($ciphertext, 0, strlen($plaintext));
401
+ if (strlen($buffer) == 16) {
402
+ $this->decryptIV = $buffer;
403
+ $buffer = '';
404
  mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
405
  }
406
  $ciphertext = substr($ciphertext, strlen($plaintext));
409
  }
410
 
411
  $last_pos = strlen($ciphertext) & 0xFFFFFFF0;
412
+ if ($last_pos) {
413
+ $plaintext = mdecrypt_generic($this->demcrypt, substr($ciphertext, 0, $last_pos));
414
+ $this->decryptIV = substr($ciphertext, $last_pos - 16, 16);
415
+ $this->decryptIV = mcrypt_generic($this->ecb, $this->decryptIV);
416
+ }
417
 
418
  if (strlen($ciphertext) & 0xF) {
419
+ $buffer = substr($ciphertext, $last_pos);
420
+ $plaintext.= $buffer ^ $this->decryptIV;
 
 
 
 
421
  }
422
 
423
  return $plaintext;
528
  // shiftRows + subWord + mixColumns + addRoundKey
529
  // we could loop unroll this and use if statements to do more rounds as necessary, but, in my tests, that yields
530
  // only a marginal improvement. since that also, imho, hinders the readability of the code, i've opted not to do it.
531
+ for ($round = 1; $round < $Nr; $round++) {
532
  $state = array(
533
  $t0[$state[0] & 0xFF000000] ^ $t1[$state[1] & 0x00FF0000] ^ $t2[$state[2] & 0x0000FF00] ^ $t3[$state[3] & 0x000000FF] ^ $w[$round][0],
534
  $t0[$state[1] & 0xFF000000] ^ $t1[$state[2] & 0x00FF0000] ^ $t2[$state[3] & 0x0000FF00] ^ $t3[$state[0] & 0x000000FF] ^ $w[$round][1],
588
 
589
 
590
  // invShiftRows + invSubBytes + invMixColumns + addRoundKey
591
+ for ($round = $Nr - 1; $round > 0; $round--) {
592
  $state = array(
593
  $dt0[$state[0] & 0xFF000000] ^ $dt1[$state[3] & 0x00FF0000] ^ $dt2[$state[2] & 0x0000FF00] ^ $dt3[$state[1] & 0x000000FF] ^ $dw[$round][0],
594
  $dt0[$state[1] & 0xFF000000] ^ $dt1[$state[0] & 0x00FF0000] ^ $dt2[$state[3] & 0x0000FF00] ^ $dt3[$state[2] & 0x000000FF] ^ $dw[$round][1],
607
 
608
  return pack('N*', $state[0], $state[1], $state[2], $state[3]);
609
  }
610
+
611
+ /**
612
+ * Treat consecutive packets as if they are a discontinuous buffer.
613
+ *
614
+ * The default behavior.
615
+ *
616
+ * @see Crypt_Rijndael::enableContinuousBuffer()
617
+ * @access public
618
+ */
619
+ function disableContinuousBuffer()
620
+ {
621
+ parent::disableContinuousBuffer();
622
+
623
+ if (CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT) {
624
+ mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv);
625
+ mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);
626
+ }
627
+ }
628
  }
629
 
630
  // vim: ts=4:sw=4:et:
phpseclib/Crypt/DES.php CHANGED
@@ -291,14 +291,11 @@ class Crypt_DES {
291
  * @return Crypt_DES
292
  * @access public
293
  */
294
- function Crypt_DES($mode = CRYPT_MODE_DES_CBC)
295
  {
296
  if ( !defined('CRYPT_DES_MODE') ) {
297
  switch (true) {
298
- case extension_loaded('mcrypt'):
299
- // i'd check to see if des was supported, by doing in_array('des', mcrypt_list_algorithms('')),
300
- // but since that can be changed after the object has been created, there doesn't seem to be
301
- // a lot of point...
302
  define('CRYPT_DES_MODE', CRYPT_DES_MODE_MCRYPT);
303
  break;
304
  default:
@@ -374,7 +371,7 @@ class Crypt_DES {
374
  *
375
  * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows:
376
  * {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2}:
377
- * $hash, $salt, $method
378
  *
379
  * @param String $password
380
  * @param optional String $method
@@ -392,7 +389,7 @@ class Crypt_DES {
392
  }
393
  // WPA and WPA use the SSID as the salt
394
  if (!isset($salt)) {
395
- $salt = 'phpseclib';
396
  }
397
  // RFC2898#section-4.2 uses 1,000 iterations by default
398
  // WPA and WPA2 use 4,096.
@@ -600,7 +597,7 @@ class Crypt_DES {
600
  }
601
  break;
602
  case CRYPT_DES_MODE_CFB:
603
- if (!empty($buffer['xor'])) {
604
  $ciphertext = $plaintext ^ $buffer['xor'];
605
  $iv = $buffer['encrypted'] . $ciphertext;
606
  $start = strlen($ciphertext);
@@ -726,7 +723,7 @@ class Crypt_DES {
726
  mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
727
  }
728
 
729
- return $this->mode != 'ctr' ? $this->_unpad($plaintext) : $plaintext;
730
  }
731
 
732
  if (!is_array($this->keys)) {
@@ -777,15 +774,17 @@ class Crypt_DES {
777
  }
778
  break;
779
  case CRYPT_DES_MODE_CFB:
780
- if (!empty($buffer['ciphertext'])) {
781
  $plaintext = $ciphertext ^ substr($this->decryptIV, strlen($buffer['ciphertext']));
782
  $buffer['ciphertext'].= substr($ciphertext, 0, strlen($plaintext));
783
- if (strlen($buffer['ciphertext']) == 8) {
 
 
 
784
  $xor = $this->_processBlock($buffer['ciphertext'], CRYPT_DES_ENCRYPT);
785
  $buffer['ciphertext'] = '';
786
  }
787
  $start = strlen($plaintext);
788
- $block = $this->decryptIV;
789
  } else {
790
  $plaintext = '';
791
  $xor = $this->_processBlock($this->decryptIV, CRYPT_DES_ENCRYPT);
@@ -940,7 +939,7 @@ class Crypt_DES {
940
  if (($length & 7) == 0) {
941
  return $text;
942
  } else {
943
- user_error("The plaintext's length ($length) is not a multiple of the block size (8)", E_USER_NOTICE);
944
  $this->padding = true;
945
  }
946
  }
291
  * @return Crypt_DES
292
  * @access public
293
  */
294
+ function Crypt_DES($mode = CRYPT_DES_MODE_CBC)
295
  {
296
  if ( !defined('CRYPT_DES_MODE') ) {
297
  switch (true) {
298
+ case extension_loaded('mcrypt') && in_array('des', mcrypt_list_algorithms()):
 
 
 
299
  define('CRYPT_DES_MODE', CRYPT_DES_MODE_MCRYPT);
300
  break;
301
  default:
371
  *
372
  * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows:
373
  * {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2}:
374
+ * $hash, $salt, $count
375
  *
376
  * @param String $password
377
  * @param optional String $method
389
  }
390
  // WPA and WPA use the SSID as the salt
391
  if (!isset($salt)) {
392
+ $salt = 'phpseclib/salt';
393
  }
394
  // RFC2898#section-4.2 uses 1,000 iterations by default
395
  // WPA and WPA2 use 4,096.
597
  }
598
  break;
599
  case CRYPT_DES_MODE_CFB:
600
+ if (strlen($buffer['xor'])) {
601
  $ciphertext = $plaintext ^ $buffer['xor'];
602
  $iv = $buffer['encrypted'] . $ciphertext;
603
  $start = strlen($ciphertext);
723
  mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
724
  }
725
 
726
+ return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
727
  }
728
 
729
  if (!is_array($this->keys)) {
774
  }
775
  break;
776
  case CRYPT_DES_MODE_CFB:
777
+ if (strlen($buffer['ciphertext'])) {
778
  $plaintext = $ciphertext ^ substr($this->decryptIV, strlen($buffer['ciphertext']));
779
  $buffer['ciphertext'].= substr($ciphertext, 0, strlen($plaintext));
780
+ if (strlen($buffer['ciphertext']) != 8) {
781
+ $block = $this->decryptIV;
782
+ } else {
783
+ $block = $buffer['ciphertext'];
784
  $xor = $this->_processBlock($buffer['ciphertext'], CRYPT_DES_ENCRYPT);
785
  $buffer['ciphertext'] = '';
786
  }
787
  $start = strlen($plaintext);
 
788
  } else {
789
  $plaintext = '';
790
  $xor = $this->_processBlock($this->decryptIV, CRYPT_DES_ENCRYPT);
939
  if (($length & 7) == 0) {
940
  return $text;
941
  } else {
942
+ user_error("The plaintext's length ($length) is not a multiple of the block size (8)");
943
  $this->padding = true;
944
  }
945
  }
phpseclib/Crypt/Hash.php CHANGED
@@ -1,825 +1,825 @@
1
- <?php
2
- /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
-
4
- /**
5
- * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
6
- *
7
- * Uses hash() or mhash() if available and an internal implementation, otherwise. Currently supports the following:
8
- *
9
- * md2, md5, md5-96, sha1, sha1-96, sha256, sha384, and sha512
10
- *
11
- * If {@link Crypt_Hash::setKey() setKey()} is called, {@link Crypt_Hash::hash() hash()} will return the HMAC as opposed to
12
- * the hash. If no valid algorithm is provided, sha1 will be used.
13
- *
14
- * PHP versions 4 and 5
15
- *
16
- * {@internal The variable names are the same as those in
17
- * {@link http://tools.ietf.org/html/rfc2104#section-2 RFC2104}.}}
18
- *
19
- * Here's a short example of how to use this library:
20
- * <code>
21
- * <?php
22
- * include('Crypt/Hash.php');
23
- *
24
- * $hash = new Crypt_Hash('sha1');
25
- *
26
- * $hash->setKey('abcdefg');
27
- *
28
- * echo base64_encode($hash->hash('abcdefg'));
29
- * ?>
30
- * </code>
31
- *
32
- * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
33
- * of this software and associated documentation files (the "Software"), to deal
34
- * in the Software without restriction, including without limitation the rights
35
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
36
- * copies of the Software, and to permit persons to whom the Software is
37
- * furnished to do so, subject to the following conditions:
38
- *
39
- * The above copyright notice and this permission notice shall be included in
40
- * all copies or substantial portions of the Software.
41
- *
42
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
43
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
44
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
45
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
46
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
47
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
48
- * THE SOFTWARE.
49
- *
50
- * @category Crypt
51
- * @package Crypt_Hash
52
- * @author Jim Wigginton <terrafrost@php.net>
53
- * @copyright MMVII Jim Wigginton
54
- * @license http://www.opensource.org/licenses/mit-license.html MIT License
55
- * @version $Id: Hash.php,v 1.6 2009/11/23 23:37:07 terrafrost Exp $
56
- * @link http://phpseclib.sourceforge.net
57
- */
58
-
59
- /**#@+
60
- * @access private
61
- * @see Crypt_Hash::Crypt_Hash()
62
- */
63
- /**
64
- * Toggles the internal implementation
65
- */
66
- define('CRYPT_HASH_MODE_INTERNAL', 1);
67
- /**
68
- * Toggles the mhash() implementation, which has been deprecated on PHP 5.3.0+.
69
- */
70
- define('CRYPT_HASH_MODE_MHASH', 2);
71
- /**
72
- * Toggles the hash() implementation, which works on PHP 5.1.2+.
73
- */
74
- define('CRYPT_HASH_MODE_HASH', 3);
75
- /**#@-*/
76
-
77
- /**
78
- * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
79
- *
80
- * @author Jim Wigginton <terrafrost@php.net>
81
- * @version 0.1.0
82
- * @access public
83
- * @package Crypt_Hash
84
- */
85
- class Crypt_Hash {
86
- /**
87
- * Byte-length of compression blocks / key (Internal HMAC)
88
- *
89
- * @see Crypt_Hash::setAlgorithm()
90
- * @var Integer
91
- * @access private
92
- */
93
- var $b;
94
-
95
- /**
96
- * Byte-length of hash output (Internal HMAC)
97
- *
98
- * @see Crypt_Hash::setHash()
99
- * @var Integer
100
- * @access private
101
- */
102
- var $l = false;
103
-
104
- /**
105
- * Hash Algorithm
106
- *
107
- * @see Crypt_Hash::setHash()
108
- * @var String
109
- * @access private
110
- */
111
- var $hash;
112
-
113
- /**
114
- * Key
115
- *
116
- * @see Crypt_Hash::setKey()
117
- * @var String
118
- * @access private
119
- */
120
- var $key = '';
121
-
122
- /**
123
- * Outer XOR (Internal HMAC)
124
- *
125
- * @see Crypt_Hash::setKey()
126
- * @var String
127
- * @access private
128
- */
129
- var $opad;
130
-
131
- /**
132
- * Inner XOR (Internal HMAC)
133
- *
134
- * @see Crypt_Hash::setKey()
135
- * @var String
136
- * @access private
137
- */
138
- var $ipad;
139
-
140
- /**
141
- * Default Constructor.
142
- *
143
- * @param optional String $hash
144
- * @return Crypt_Hash
145
- * @access public
146
- */
147
- function Crypt_Hash($hash = 'sha1')
148
- {
149
- if ( !defined('CRYPT_HASH_MODE') ) {
150
- switch (true) {
151
- case extension_loaded('hash'):
152
- define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_HASH);
153
- break;
154
- case extension_loaded('mhash'):
155
- define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_MHASH);
156
- break;
157
- default:
158
- define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_INTERNAL);
159
- }
160
- }
161
-
162
- $this->setHash($hash);
163
- }
164
-
165
- /**
166
- * Sets the key for HMACs
167
- *
168
- * Keys can be of any length.
169
- *
170
- * @access public
171
- * @param String $key
172
- */
173
- function setKey($key)
174
- {
175
- $this->key = $key;
176
- }
177
-
178
- /**
179
- * Sets the hash function.
180
- *
181
- * @access public
182
- * @param String $hash
183
- */
184
- function setHash($hash)
185
- {
186
- $hash = strtolower($hash);
187
- switch ($hash) {
188
- case 'md5-96':
189
- case 'sha1-96':
190
- $this->l = 12; // 96 / 8 = 12
191
- break;
192
- case 'md2':
193
- case 'md5':
194
- $this->l = 16;
195
- break;
196
- case 'sha1':
197
- $this->l = 20;
198
- break;
199
- case 'sha256':
200
- $this->l = 32;
201
- break;
202
- case 'sha384':
203
- $this->l = 48;
204
- break;
205
- case 'sha512':
206
- $this->l = 64;
207
- }
208
-
209
- switch ($hash) {
210
- case 'md2':
211
- $mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_HASH && in_array('md2', hash_algos()) ?
212
- CRYPT_HASH_MODE_HASH : CRYPT_HASH_MODE_INTERNAL;
213
- break;
214
- case 'sha384':
215
- case 'sha512':
216
- $mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_MHASH ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
217
- break;
218
- default:
219
- $mode = CRYPT_HASH_MODE;
220
- }
221
-
222
- switch ( $mode ) {
223
- case CRYPT_HASH_MODE_MHASH:
224
- switch ($hash) {
225
- case 'md5':
226
- case 'md5-96':
227
- $this->hash = MHASH_MD5;
228
- break;
229
- case 'sha256':
230
- $this->hash = MHASH_SHA256;
231
- break;
232
- case 'sha1':
233
- case 'sha1-96':
234
- default:
235
- $this->hash = MHASH_SHA1;
236
- }
237
- return;
238
- case CRYPT_HASH_MODE_HASH:
239
- switch ($hash) {
240
- case 'md5':
241
- case 'md5-96':
242
- $this->hash = 'md5';
243
- return;
244
- case 'md2':
245
- case 'sha256':
246
- case 'sha384':
247
- case 'sha512':
248
- $this->hash = $hash;
249
- return;
250
- case 'sha1':
251
- case 'sha1-96':
252
- default:
253
- $this->hash = 'sha1';
254
- }
255
- return;
256
- }
257
-
258
- switch ($hash) {
259
- case 'md2':
260
- $this->b = 16;
261
- $this->hash = array($this, '_md2');
262
- break;
263
- case 'md5':
264
- case 'md5-96':
265
- $this->b = 64;
266
- $this->hash = array($this, '_md5');
267
- break;
268
- case 'sha256':
269
- $this->b = 64;
270
- $this->hash = array($this, '_sha256');
271
- break;
272
- case 'sha384':
273
- case 'sha512':
274
- $this->b = 128;
275
- $this->hash = array($this, '_sha512');
276
- break;
277
- case 'sha1':
278
- case 'sha1-96':
279
- default:
280
- $this->b = 64;
281
- $this->hash = array($this, '_sha1');
282
- }
283
-
284
- $this->ipad = str_repeat(chr(0x36), $this->b);
285
- $this->opad = str_repeat(chr(0x5C), $this->b);
286
- }
287
-
288
- /**
289
- * Compute the HMAC.
290
- *
291
- * @access public
292
- * @param String $text
293
- * @return String
294
- */
295
- function hash($text)
296
- {
297
- $mode = is_array($this->hash) ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
298
-
299
- if (!empty($this->key)) {
300
- switch ( $mode ) {
301
- case CRYPT_HASH_MODE_MHASH:
302
- $output = mhash($this->hash, $text, $this->key);
303
- break;
304
- case CRYPT_HASH_MODE_HASH:
305
- $output = hash_hmac($this->hash, $text, $this->key, true);
306
- break;
307
- case CRYPT_HASH_MODE_INTERNAL:
308
- /* "Applications that use keys longer than B bytes will first hash the key using H and then use the
309
- resultant L byte string as the actual key to HMAC."
310
-
311
- -- http://tools.ietf.org/html/rfc2104#section-2 */
312
- $key = strlen($this->key) > $this->b ? call_user_func($this->hash, $this->key) : $this->key;
313
-
314
- $key = str_pad($key, $this->b, chr(0)); // step 1
315
- $temp = $this->ipad ^ $key; // step 2
316
- $temp .= $text; // step 3
317
- $temp = call_user_func($this->hash, $temp); // step 4
318
- $output = $this->opad ^ $key; // step 5
319
- $output.= $temp; // step 6
320
- $output = call_user_func($this->hash, $output); // step 7
321
- }
322
- } else {
323
- switch ( $mode ) {
324
- case CRYPT_HASH_MODE_MHASH:
325
- $output = mhash($this->hash, $text);
326
- break;
327
- case CRYPT_HASH_MODE_HASH:
328
- $output = hash($this->hash, $text, true);
329
- break;
330
- case CRYPT_HASH_MODE_INTERNAL:
331
- $output = call_user_func($this->hash, $text);
332
- }
333
- }
334
-
335
- return substr($output, 0, $this->l);
336
- }
337
-
338
- /**
339
- * Returns the hash length (in bytes)
340
- *
341
- * @access public
342
- * @return Integer
343
- */
344
- function getLength()
345
- {
346
- return $this->l;
347
- }
348
-
349
- /**
350
- * Wrapper for MD5
351
- *
352
- * @access private
353
- * @param String $text
354
- */
355
- function _md5($m)
356
- {
357
- return pack('H*', md5($m));
358
- }
359
-
360
- /**
361
- * Wrapper for SHA1
362
- *
363
- * @access private
364
- * @param String $text
365
- */
366
- function _sha1($m)
367
- {
368
- return pack('H*', sha1($m));
369
- }
370
-
371
- /**
372
- * Pure-PHP implementation of MD2
373
- *
374
- * See {@link http://tools.ietf.org/html/rfc1319 RFC1319}.
375
- *
376
- * @access private
377
- * @param String $text
378
- */
379
- function _md2($m)
380
- {
381
- static $s = array(
382
- 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
383
- 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
384
- 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
385
- 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
386
- 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
387
- 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
388
- 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
389
- 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
390
- 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
391
- 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
392
- 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
393
- 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
394
- 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
395
- 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
396
- 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
397
- 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
398
- 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
399
- 31, 26, 219, 153, 141, 51, 159, 17, 131, 20
400
- );
401
-
402
- // Step 1. Append Padding Bytes
403
- $pad = 16 - (strlen($m) & 0xF);
404
- $m.= str_repeat(chr($pad), $pad);
405
-
406
- $length = strlen($m);
407
-
408
- // Step 2. Append Checksum
409
- $c = str_repeat(chr(0), 16);
410
- $l = chr(0);
411
- for ($i = 0; $i < $length; $i+= 16) {
412
- for ($j = 0; $j < 16; $j++) {
413
- // RFC1319 incorrectly states that C[j] should be set to S[c xor L]
414
- //$c[$j] = chr($s[ord($m[$i + $j] ^ $l)]);
415
- // per <http://www.rfc-editor.org/errata_search.php?rfc=1319>, however, C[j] should be set to S[c xor L] xor C[j]
416
- $c[$j] = chr($s[ord($m[$i + $j] ^ $l)] ^ ord($c[$j]));
417
- $l = $c[$j];
418
- }
419
- }
420
- $m.= $c;
421
-
422
- $length+= 16;
423
-
424
- // Step 3. Initialize MD Buffer
425
- $x = str_repeat(chr(0), 48);
426
-
427
- // Step 4. Process Message in 16-Byte Blocks
428
- for ($i = 0; $i < $length; $i+= 16) {
429
- for ($j = 0; $j < 16; $j++) {
430
- $x[$j + 16] = $m[$i + $j];
431
- $x[$j + 32] = $x[$j + 16] ^ $x[$j];
432
- }
433
- $t = chr(0);
434
- for ($j = 0; $j < 18; $j++) {
435
- for ($k = 0; $k < 48; $k++) {
436
- $x[$k] = $t = $x[$k] ^ chr($s[ord($t)]);
437
- //$t = $x[$k] = $x[$k] ^ chr($s[ord($t)]);
438
- }
439
- $t = chr(ord($t) + $j);
440
- }
441
- }
442
-
443
- // Step 5. Output
444
- return substr($x, 0, 16);
445
- }
446
-
447
- /**
448
- * Pure-PHP implementation of SHA256
449
- *
450
- * See {@link http://en.wikipedia.org/wiki/SHA_hash_functions#SHA-256_.28a_SHA-2_variant.29_pseudocode SHA-256 (a SHA-2 variant) pseudocode - Wikipedia}.
451
- *
452
- * @access private
453
- * @param String $text
454
- */
455
- function _sha256($m)
456
- {
457
- if (extension_loaded('suhosin')) {
458
- return pack('H*', sha256($m));
459
- }
460
-
461
- // Initialize variables
462
- $hash = array(
463
- 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
464
- );
465
- // Initialize table of round constants
466
- // (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)
467
- static $k = array(
468
- 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
469
- 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
470
- 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
471
- 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
472
- 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
473
- 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
474
- 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
475
- 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
476
- );
477
-
478
- // Pre-processing
479
- $length = strlen($m);
480
- // to round to nearest 56 mod 64, we'll add 64 - (length + (64 - 56)) % 64
481
- $m.= str_repeat(chr(0), 64 - (($length + 8) & 0x3F));
482
- $m[$length] = chr(0x80);
483
- // we don't support hashing strings 512MB long
484
- $m.= pack('N2', 0, $length << 3);
485
-
486
- // Process the message in successive 512-bit chunks
487
- $chunks = str_split($m, 64);
488
- foreach ($chunks as $chunk) {
489
- $w = array();
490
- for ($i = 0; $i < 16; $i++) {
491
- extract(unpack('Ntemp', $this->_string_shift($chunk, 4)));
492
- $w[] = $temp;
493
- }
494
-
495
- // Extend the sixteen 32-bit words into sixty-four 32-bit words
496
- for ($i = 16; $i < 64; $i++) {
497
- $s0 = $this->_rightRotate($w[$i - 15], 7) ^
498
- $this->_rightRotate($w[$i - 15], 18) ^
499
- $this->_rightShift( $w[$i - 15], 3);
500
- $s1 = $this->_rightRotate($w[$i - 2], 17) ^
501
- $this->_rightRotate($w[$i - 2], 19) ^
502
- $this->_rightShift( $w[$i - 2], 10);
503
- $w[$i] = $this->_add($w[$i - 16], $s0, $w[$i - 7], $s1);
504
-
505
- }
506
-
507
- // Initialize hash value for this chunk
508
- list($a, $b, $c, $d, $e, $f, $g, $h) = $hash;
509
-
510
- // Main loop
511
- for ($i = 0; $i < 64; $i++) {
512
- $s0 = $this->_rightRotate($a, 2) ^
513
- $this->_rightRotate($a, 13) ^
514
- $this->_rightRotate($a, 22);
515
- $maj = ($a & $b) ^
516
- ($a & $c) ^
517
- ($b & $c);
518
- $t2 = $this->_add($s0, $maj);
519
-
520
- $s1 = $this->_rightRotate($e, 6) ^
521
- $this->_rightRotate($e, 11) ^
522
- $this->_rightRotate($e, 25);
523
- $ch = ($e & $f) ^
524
- ($this->_not($e) & $g);
525
- $t1 = $this->_add($h, $s1, $ch, $k[$i], $w[$i]);
526
-
527
- $h = $g;
528
- $g = $f;
529
- $f = $e;
530
- $e = $this->_add($d, $t1);
531
- $d = $c;
532
- $c = $b;
533
- $b = $a;
534
- $a = $this->_add($t1, $t2);
535
- }
536
-
537
- // Add this chunk's hash to result so far
538
- $hash = array(
539
- $this->_add($hash[0], $a),
540
- $this->_add($hash[1], $b),
541
- $this->_add($hash[2], $c),
542
- $this->_add($hash[3], $d),
543
- $this->_add($hash[4], $e),
544
- $this->_add($hash[5], $f),
545
- $this->_add($hash[6], $g),
546
- $this->_add($hash[7], $h)
547
- );
548
- }
549
-
550
- // Produce the final hash value (big-endian)
551
- return pack('N8', $hash[0], $hash[1], $hash[2], $hash[3], $hash[4], $hash[5], $hash[6], $hash[7]);
552
- }
553
-
554
- /**
555
- * Pure-PHP implementation of SHA384 and SHA512
556
- *
557
- * @access private
558
- * @param String $text
559
- */
560
- function _sha512($m)
561
- {
562
- if (!class_exists('Math_BigInteger')) {
563
- require_once('Math/BigInteger.php');
564
- }
565
-
566
- static $init384, $init512, $k;
567
-
568
- if (!isset($k)) {
569
- // Initialize variables
570
- $init384 = array( // initial values for SHA384
571
- 'cbbb9d5dc1059ed8', '629a292a367cd507', '9159015a3070dd17', '152fecd8f70e5939',
572
- '67332667ffc00b31', '8eb44a8768581511', 'db0c2e0d64f98fa7', '47b5481dbefa4fa4'
573
- );
574
- $init512 = array( // initial values for SHA512
575
- '6a09e667f3bcc908', 'bb67ae8584caa73b', '3c6ef372fe94f82b', 'a54ff53a5f1d36f1',
576
- '510e527fade682d1', '9b05688c2b3e6c1f', '1f83d9abfb41bd6b', '5be0cd19137e2179'
577
- );
578
-
579
- for ($i = 0; $i < 8; $i++) {
580
- $init384[$i] = new Math_BigInteger($init384[$i], 16);
581
- $init384[$i]->setPrecision(64);
582
- $init512[$i] = new Math_BigInteger($init512[$i], 16);
583
- $init512[$i]->setPrecision(64);
584
- }
585
-
586
- // Initialize table of round constants
587
- // (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409)
588
- $k = array(
589
- '428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc',
590
- '3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118',
591
- 'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2',
592
- '72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694',
593
- 'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65',
594
- '2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5',
595
- '983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4',
596
- 'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70',
597
- '27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df',
598
- '650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b',
599
- 'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30',
600
- 'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8',
601
- '19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8',
602
- '391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3',
603
- '748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec',
604
- '90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b',
605
- 'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178',
606
- '06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b',
607
- '28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c',
608
- '4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817'
609
- );
610
-
611
- for ($i = 0; $i < 80; $i++) {
612
- $k[$i] = new Math_BigInteger($k[$i], 16);
613
- }
614
- }
615
-
616
- $hash = $this->l == 48 ? $init384 : $init512;
617
-
618
- // Pre-processing
619
- $length = strlen($m);
620
- // to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128
621
- $m.= str_repeat(chr(0), 128 - (($length + 16) & 0x7F));
622
- $m[$length] = chr(0x80);
623
- // we don't support hashing strings 512MB long
624
- $m.= pack('N4', 0, 0, 0, $length << 3);
625
-
626
- // Process the message in successive 1024-bit chunks
627
- $chunks = str_split($m, 128);
628
- foreach ($chunks as $chunk) {
629
- $w = array();
630
- for ($i = 0; $i < 16; $i++) {
631
- $temp = new Math_BigInteger($this->_string_shift($chunk, 8), 256);
632
- $temp->setPrecision(64);
633
- $w[] = $temp;
634
- }
635
-
636
- // Extend the sixteen 32-bit words into eighty 32-bit words
637
- for ($i = 16; $i < 80; $i++) {
638
- $temp = array(
639
- $w[$i - 15]->bitwise_rightRotate(1),
640
- $w[$i - 15]->bitwise_rightRotate(8),
641
- $w[$i - 15]->bitwise_rightShift(7)
642
- );
643
- $s0 = $temp[0]->bitwise_xor($temp[1]);
644
- $s0 = $s0->bitwise_xor($temp[2]);
645
- $temp = array(
646
- $w[$i - 2]->bitwise_rightRotate(19),
647
- $w[$i - 2]->bitwise_rightRotate(61),
648
- $w[$i - 2]->bitwise_rightShift(6)
649
- );
650
- $s1 = $temp[0]->bitwise_xor($temp[1]);
651
- $s1 = $s1->bitwise_xor($temp[2]);
652
- $w[$i] = $w[$i - 16]->copy();
653
- $w[$i] = $w[$i]->add($s0);
654
- $w[$i] = $w[$i]->add($w[$i - 7]);
655
- $w[$i] = $w[$i]->add($s1);
656
- }
657
-
658
- // Initialize hash value for this chunk
659
- $a = $hash[0]->copy();
660
- $b = $hash[1]->copy();
661
- $c = $hash[2]->copy();
662
- $d = $hash[3]->copy();
663
- $e = $hash[4]->copy();
664
- $f = $hash[5]->copy();
665
- $g = $hash[6]->copy();
666
- $h = $hash[7]->copy();
667
-
668
- // Main loop
669
- for ($i = 0; $i < 80; $i++) {
670
- $temp = array(
671
- $a->bitwise_rightRotate(28),
672
- $a->bitwise_rightRotate(34),
673
- $a->bitwise_rightRotate(39)
674
- );
675
- $s0 = $temp[0]->bitwise_xor($temp[1]);
676
- $s0 = $s0->bitwise_xor($temp[2]);
677
- $temp = array(
678
- $a->bitwise_and($b),
679
- $a->bitwise_and($c),
680
- $b->bitwise_and($c)
681
- );
682
- $maj = $temp[0]->bitwise_xor($temp[1]);
683
- $maj = $maj->bitwise_xor($temp[2]);
684
- $t2 = $s0->add($maj);
685
-
686
- $temp = array(
687
- $e->bitwise_rightRotate(14),
688
- $e->bitwise_rightRotate(18),
689
- $e->bitwise_rightRotate(41)
690
- );
691
- $s1 = $temp[0]->bitwise_xor($temp[1]);
692
- $s1 = $s1->bitwise_xor($temp[2]);
693
- $temp = array(
694
- $e->bitwise_and($f),
695
- $g->bitwise_and($e->bitwise_not())
696
- );
697
- $ch = $temp[0]->bitwise_xor($temp[1]);
698
- $t1 = $h->add($s1);
699
- $t1 = $t1->add($ch);
700
- $t1 = $t1->add($k[$i]);
701
- $t1 = $t1->add($w[$i]);
702
-
703
- $h = $g->copy();
704
- $g = $f->copy();
705
- $f = $e->copy();
706
- $e = $d->add($t1);
707
- $d = $c->copy();
708
- $c = $b->copy();
709
- $b = $a->copy();
710
- $a = $t1->add($t2);
711
- }
712
-
713
- // Add this chunk's hash to result so far
714
- $hash = array(
715
- $hash[0]->add($a),
716
- $hash[1]->add($b),
717
- $hash[2]->add($c),
718
- $hash[3]->add($d),
719
- $hash[4]->add($e),
720
- $hash[5]->add($f),
721
- $hash[6]->add($g),
722
- $hash[7]->add($h)
723
- );
724
- }
725
-
726
- // Produce the final hash value (big-endian)
727
- // (Crypt_Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here)
728
- $temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() .
729
- $hash[4]->toBytes() . $hash[5]->toBytes();
730
- if ($this->l != 48) {
731
- $temp.= $hash[6]->toBytes() . $hash[7]->toBytes();
732
- }
733
-
734
- return $temp;
735
- }
736
-
737
- /**
738
- * Right Rotate
739
- *
740
- * @access private
741
- * @param Integer $int
742
- * @param Integer $amt
743
- * @see _sha256()
744
- * @return Integer
745
- */
746
- function _rightRotate($int, $amt)
747
- {
748
- $invamt = 32 - $amt;
749
- $mask = (1 << $invamt) - 1;
750
- return (($int << $invamt) & 0xFFFFFFFF) | (($int >> $amt) & $mask);
751
- }
752
-
753
- /**
754
- * Right Shift
755
- *
756
- * @access private
757
- * @param Integer $int
758
- * @param Integer $amt
759
- * @see _sha256()
760
- * @return Integer
761
- */
762
- function _rightShift($int, $amt)
763
- {
764
- $mask = (1 << (32 - $amt)) - 1;
765
- return ($int >> $amt) & $mask;
766
- }
767
-
768
- /**
769
- * Not
770
- *
771
- * @access private
772
- * @param Integer $int
773
- * @see _sha256()
774
- * @return Integer
775
- */
776
- function _not($int)
777
- {
778
- return ~$int & 0xFFFFFFFF;
779
- }
780
-
781
- /**
782
- * Add
783
- *
784
- * _sha256() adds multiple unsigned 32-bit integers. Since PHP doesn't support unsigned integers and since the
785
- * possibility of overflow exists, care has to be taken. Math_BigInteger() could be used but this should be faster.
786
- *
787
- * @param String $string
788
- * @param optional Integer $index
789
- * @return String
790
- * @see _sha256()
791
- * @access private
792
- */
793
- function _add()
794
- {
795
- static $mod;
796
- if (!isset($mod)) {
797
- $mod = pow(2, 32);
798
- }
799
-
800
- $result = 0;
801
- $arguments = func_get_args();
802
- foreach ($arguments as $argument) {
803
- $result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;
804
- }
805
-
806
- return fmod($result, $mod);
807
- }
808
-
809
- /**
810
- * String Shift
811
- *
812
- * Inspired by array_shift
813
- *
814
- * @param String $string
815
- * @param optional Integer $index
816
- * @return String
817
- * @access private
818
- */
819
- function _string_shift(&$string, $index = 1)
820
- {
821
- $substr = substr($string, 0, $index);
822
- $string = substr($string, $index);
823
- return $substr;
824
- }
825
- }
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
6
+ *
7
+ * Uses hash() or mhash() if available and an internal implementation, otherwise. Currently supports the following:
8
+ *
9
+ * md2, md5, md5-96, sha1, sha1-96, sha256, sha384, and sha512
10
+ *
11
+ * If {@link Crypt_Hash::setKey() setKey()} is called, {@link Crypt_Hash::hash() hash()} will return the HMAC as opposed to
12
+ * the hash. If no valid algorithm is provided, sha1 will be used.
13
+ *
14
+ * PHP versions 4 and 5
15
+ *
16
+ * {@internal The variable names are the same as those in
17
+ * {@link http://tools.ietf.org/html/rfc2104#section-2 RFC2104}.}}
18
+ *
19
+ * Here's a short example of how to use this library:
20
+ * <code>
21
+ * <?php
22
+ * include('Crypt/Hash.php');
23
+ *
24
+ * $hash = new Crypt_Hash('sha1');
25
+ *
26
+ * $hash->setKey('abcdefg');
27
+ *
28
+ * echo base64_encode($hash->hash('abcdefg'));
29
+ * ?>
30
+ * </code>
31
+ *
32
+ * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
33
+ * of this software and associated documentation files (the "Software"), to deal
34
+ * in the Software without restriction, including without limitation the rights
35
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
36
+ * copies of the Software, and to permit persons to whom the Software is
37
+ * furnished to do so, subject to the following conditions:
38
+ *
39
+ * The above copyright notice and this permission notice shall be included in
40
+ * all copies or substantial portions of the Software.
41
+ *
42
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
43
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
44
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
45
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
46
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
47
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
48
+ * THE SOFTWARE.
49
+ *
50
+ * @category Crypt
51
+ * @package Crypt_Hash
52
+ * @author Jim Wigginton <terrafrost@php.net>
53
+ * @copyright MMVII Jim Wigginton
54
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
55
+ * @version $Id: Hash.php,v 1.6 2009/11/23 23:37:07 terrafrost Exp $
56
+ * @link http://phpseclib.sourceforge.net
57
+ */
58
+
59
+ /**#@+
60
+ * @access private
61
+ * @see Crypt_Hash::Crypt_Hash()
62
+ */
63
+ /**
64
+ * Toggles the internal implementation
65
+ */
66
+ define('CRYPT_HASH_MODE_INTERNAL', 1);
67
+ /**
68
+ * Toggles the mhash() implementation, which has been deprecated on PHP 5.3.0+.
69
+ */
70
+ define('CRYPT_HASH_MODE_MHASH', 2);
71
+ /**
72
+ * Toggles the hash() implementation, which works on PHP 5.1.2+.
73
+ */
74
+ define('CRYPT_HASH_MODE_HASH', 3);
75
+ /**#@-*/
76
+
77
+ /**
78
+ * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
79
+ *
80
+ * @author Jim Wigginton <terrafrost@php.net>
81
+ * @version 0.1.0
82
+ * @access public
83
+ * @package Crypt_Hash
84
+ */
85
+ class Crypt_Hash {
86
+ /**
87
+ * Byte-length of compression blocks / key (Internal HMAC)
88
+ *
89
+ * @see Crypt_Hash::setAlgorithm()
90
+ * @var Integer
91
+ * @access private
92
+ */
93
+ var $b;
94
+
95
+ /**
96
+ * Byte-length of hash output (Internal HMAC)
97
+ *
98
+ * @see Crypt_Hash::setHash()
99
+ * @var Integer
100
+ * @access private
101
+ */
102
+ var $l = false;
103
+
104
+ /**
105
+ * Hash Algorithm
106
+ *
107
+ * @see Crypt_Hash::setHash()
108
+ * @var String
109
+ * @access private
110
+ */
111
+ var $hash;
112
+
113
+ /**
114
+ * Key
115
+ *
116
+ * @see Crypt_Hash::setKey()
117
+ * @var String
118
+ * @access private
119
+ */
120
+ var $key = false;
121
+
122
+ /**
123
+ * Outer XOR (Internal HMAC)
124
+ *
125
+ * @see Crypt_Hash::setKey()
126
+ * @var String
127
+ * @access private
128
+ */
129
+ var $opad;
130
+
131
+ /**
132
+ * Inner XOR (Internal HMAC)
133
+ *
134
+ * @see Crypt_Hash::setKey()
135
+ * @var String
136
+ * @access private
137
+ */
138
+ var $ipad;
139
+
140
+ /**
141
+ * Default Constructor.
142
+ *
143
+ * @param optional String $hash
144
+ * @return Crypt_Hash
145
+ * @access public
146
+ */
147
+ function Crypt_Hash($hash = 'sha1')
148
+ {
149
+ if ( !defined('CRYPT_HASH_MODE') ) {
150
+ switch (true) {
151
+ case extension_loaded('hash'):
152
+ define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_HASH);
153
+ break;
154
+ case extension_loaded('mhash'):
155
+ define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_MHASH);
156
+ break;
157
+ default:
158
+ define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_INTERNAL);
159
+ }
160
+ }
161
+
162
+ $this->setHash($hash);
163
+ }
164
+
165
+ /**
166
+ * Sets the key for HMACs
167
+ *
168
+ * Keys can be of any length.
169
+ *
170
+ * @access public
171
+ * @param String $key
172
+ */
173
+ function setKey($key = false)
174
+ {
175
+ $this->key = $key;
176
+ }
177
+
178
+ /**
179
+ * Sets the hash function.
180
+ *
181
+ * @access public
182
+ * @param String $hash
183
+ */
184
+ function setHash($hash)
185
+ {
186
+ $hash = strtolower($hash);
187
+ switch ($hash) {
188
+ case 'md5-96':
189
+ case 'sha1-96':
190
+ $this->l = 12; // 96 / 8 = 12
191
+ break;
192
+ case 'md2':
193
+ case 'md5':
194
+ $this->l = 16;
195
+ break;
196
+ case 'sha1':
197
+ $this->l = 20;
198
+ break;
199
+ case 'sha256':
200
+ $this->l = 32;
201
+ break;
202
+ case 'sha384':
203
+ $this->l = 48;
204
+ break;
205
+ case 'sha512':
206
+ $this->l = 64;
207
+ }
208
+
209
+ switch ($hash) {
210
+ case 'md2':
211
+ $mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_HASH && in_array('md2', hash_algos()) ?
212
+ CRYPT_HASH_MODE_HASH : CRYPT_HASH_MODE_INTERNAL;
213
+ break;
214
+ case 'sha384':
215
+ case 'sha512':
216
+ $mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_MHASH ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
217
+ break;
218
+ default:
219
+ $mode = CRYPT_HASH_MODE;
220
+ }
221
+
222
+ switch ( $mode ) {
223
+ case CRYPT_HASH_MODE_MHASH:
224
+ switch ($hash) {
225
+ case 'md5':
226
+ case 'md5-96':
227
+ $this->hash = MHASH_MD5;
228
+ break;
229
+ case 'sha256':
230
+ $this->hash = MHASH_SHA256;
231
+ break;
232
+ case 'sha1':
233
+ case 'sha1-96':
234
+ default:
235
+ $this->hash = MHASH_SHA1;
236
+ }
237
+ return;
238
+ case CRYPT_HASH_MODE_HASH:
239
+ switch ($hash) {
240
+ case 'md5':
241
+ case 'md5-96':
242
+ $this->hash = 'md5';
243
+ return;
244
+ case 'md2':
245
+ case 'sha256':
246
+ case 'sha384':
247
+ case 'sha512':
248
+ $this->hash = $hash;
249
+ return;
250
+ case 'sha1':
251
+ case 'sha1-96':
252
+ default:
253
+ $this->hash = 'sha1';
254
+ }
255
+ return;
256
+ }
257
+
258
+ switch ($hash) {
259
+ case 'md2':
260
+ $this->b = 16;
261
+ $this->hash = array($this, '_md2');
262
+ break;
263
+ case 'md5':
264
+ case 'md5-96':
265
+ $this->b = 64;
266
+ $this->hash = array($this, '_md5');
267
+ break;
268
+ case 'sha256':
269
+ $this->b = 64;
270
+ $this->hash = array($this, '_sha256');
271
+ break;
272
+ case 'sha384':
273
+ case 'sha512':
274
+ $this->b = 128;
275
+ $this->hash = array($this, '_sha512');
276
+ break;
277
+ case 'sha1':
278
+ case 'sha1-96':
279
+ default:
280
+ $this->b = 64;
281
+ $this->hash = array($this, '_sha1');
282
+ }
283
+
284
+ $this->ipad = str_repeat(chr(0x36), $this->b);
285
+ $this->opad = str_repeat(chr(0x5C), $this->b);
286
+ }
287
+
288
+ /**
289
+ * Compute the HMAC.
290
+ *
291
+ * @access public
292
+ * @param String $text
293
+ * @return String
294
+ */
295
+ function hash($text)
296
+ {
297
+ $mode = is_array($this->hash) ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
298
+
299
+ if (!empty($this->key) || is_string($this->key)) {
300
+ switch ( $mode ) {
301
+ case CRYPT_HASH_MODE_MHASH:
302
+ $output = mhash($this->hash, $text, $this->key);
303
+ break;
304
+ case CRYPT_HASH_MODE_HASH:
305
+ $output = hash_hmac($this->hash, $text, $this->key, true);
306
+ break;
307
+ case CRYPT_HASH_MODE_INTERNAL:
308
+ /* "Applications that use keys longer than B bytes will first hash the key using H and then use the
309
+ resultant L byte string as the actual key to HMAC."
310
+
311
+ -- http://tools.ietf.org/html/rfc2104#section-2 */
312
+ $key = strlen($this->key) > $this->b ? call_user_func($this->hash, $this->key) : $this->key;
313
+
314
+ $key = str_pad($key, $this->b, chr(0)); // step 1
315
+ $temp = $this->ipad ^ $key; // step 2
316
+ $temp .= $text; // step 3
317
+ $temp = call_user_func($this->hash, $temp); // step 4
318
+ $output = $this->opad ^ $key; // step 5
319
+ $output.= $temp; // step 6
320
+ $output = call_user_func($this->hash, $output); // step 7
321
+ }
322
+ } else {
323
+ switch ( $mode ) {
324
+ case CRYPT_HASH_MODE_MHASH:
325
+ $output = mhash($this->hash, $text);
326
+ break;
327
+ case CRYPT_HASH_MODE_HASH:
328
+ $output = hash($this->hash, $text, true);
329
+ break;
330
+ case CRYPT_HASH_MODE_INTERNAL:
331
+ $output = call_user_func($this->hash, $text);
332
+ }
333
+ }
334
+
335
+ return substr($output, 0, $this->l);
336
+ }
337
+
338
+ /**
339
+ * Returns the hash length (in bytes)
340
+ *
341
+ * @access public
342
+ * @return Integer
343
+ */
344
+ function getLength()
345
+ {
346
+ return $this->l;
347
+ }
348
+
349
+ /**
350
+ * Wrapper for MD5
351
+ *
352
+ * @access private
353
+ * @param String $text
354
+ */
355
+ function _md5($m)
356
+ {
357
+ return pack('H*', md5($m));
358
+ }
359
+
360
+ /**
361
+ * Wrapper for SHA1
362
+ *
363
+ * @access private
364
+ * @param String $text
365
+ */
366
+ function _sha1($m)
367
+ {
368
+ return pack('H*', sha1($m));
369
+ }
370
+
371
+ /**
372
+ * Pure-PHP implementation of MD2
373
+ *
374
+ * See {@link http://tools.ietf.org/html/rfc1319 RFC1319}.
375
+ *
376
+ * @access private
377
+ * @param String $text
378
+ */
379
+ function _md2($m)
380
+ {
381
+ static $s = array(
382
+ 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
383
+ 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
384
+ 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
385
+ 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
386
+ 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
387
+ 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
388
+ 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
389
+ 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
390
+ 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
391
+ 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
392
+ 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
393
+ 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
394
+ 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
395
+ 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
396
+ 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
397
+ 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
398
+ 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
399
+ 31, 26, 219, 153, 141, 51, 159, 17, 131, 20
400
+ );
401
+
402
+ // Step 1. Append Padding Bytes
403
+ $pad = 16 - (strlen($m) & 0xF);
404
+ $m.= str_repeat(chr($pad), $pad);
405
+
406
+ $length = strlen($m);
407
+
408
+ // Step 2. Append Checksum
409
+ $c = str_repeat(chr(0), 16);
410
+ $l = chr(0);
411
+ for ($i = 0; $i < $length; $i+= 16) {
412
+ for ($j = 0; $j < 16; $j++) {
413
+ // RFC1319 incorrectly states that C[j] should be set to S[c xor L]
414
+ //$c[$j] = chr($s[ord($m[$i + $j] ^ $l)]);
415
+ // per <http://www.rfc-editor.org/errata_search.php?rfc=1319>, however, C[j] should be set to S[c xor L] xor C[j]
416
+ $c[$j] = chr($s[ord($m[$i + $j] ^ $l)] ^ ord($c[$j]));
417
+ $l = $c[$j];
418
+ }
419
+ }
420
+ $m.= $c;
421
+
422
+ $length+= 16;
423
+
424
+ // Step 3. Initialize MD Buffer
425
+ $x = str_repeat(chr(0), 48);
426
+
427
+ // Step 4. Process Message in 16-Byte Blocks
428
+ for ($i = 0; $i < $length; $i+= 16) {
429
+ for ($j = 0; $j < 16; $j++) {
430
+ $x[$j + 16] = $m[$i + $j];
431
+ $x[$j + 32] = $x[$j + 16] ^ $x[$j];
432
+ }
433
+ $t = chr(0);
434
+ for ($j = 0; $j < 18; $j++) {
435
+ for ($k = 0; $k < 48; $k++) {
436
+ $x[$k] = $t = $x[$k] ^ chr($s[ord($t)]);
437
+ //$t = $x[$k] = $x[$k] ^ chr($s[ord($t)]);
438
+ }
439
+ $t = chr(ord($t) + $j);
440
+ }
441
+ }
442
+
443
+ // Step 5. Output
444
+ return substr($x, 0, 16);
445
+ }
446
+
447
+ /**
448
+ * Pure-PHP implementation of SHA256
449
+ *
450
+ * See {@link http://en.wikipedia.org/wiki/SHA_hash_functions#SHA-256_.28a_SHA-2_variant.29_pseudocode SHA-256 (a SHA-2 variant) pseudocode - Wikipedia}.
451
+ *
452
+ * @access private
453
+ * @param String $text
454
+ */
455
+ function _sha256($m)
456
+ {
457
+ if (extension_loaded('suhosin')) {
458
+ return pack('H*', sha256($m));
459
+ }
460
+
461
+ // Initialize variables
462
+ $hash = array(
463
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
464
+ );
465
+ // Initialize table of round constants
466
+ // (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)
467
+ static $k = array(
468
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
469
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
470
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
471
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
472
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
473
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
474
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
475
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
476
+ );
477
+
478
+ // Pre-processing
479
+ $length = strlen($m);
480
+ // to round to nearest 56 mod 64, we'll add 64 - (length + (64 - 56)) % 64
481
+ $m.= str_repeat(chr(0), 64 - (($length + 8) & 0x3F));
482
+ $m[$length] = chr(0x80);
483
+ // we don't support hashing strings 512MB long
484
+ $m.= pack('N2', 0, $length << 3);
485
+
486
+ // Process the message in successive 512-bit chunks
487
+ $chunks = str_split($m, 64);
488
+ foreach ($chunks as $chunk) {
489
+ $w = array();
490
+ for ($i = 0; $i < 16; $i++) {
491
+ extract(unpack('Ntemp', $this->_string_shift($chunk, 4)));
492
+ $w[] = $temp;
493
+ }
494
+
495
+ // Extend the sixteen 32-bit words into sixty-four 32-bit words
496
+ for ($i = 16; $i < 64; $i++) {
497
+ $s0 = $this->_rightRotate($w[$i - 15], 7) ^
498
+ $this->_rightRotate($w[$i - 15], 18) ^
499
+ $this->_rightShift( $w[$i - 15], 3);
500
+ $s1 = $this->_rightRotate($w[$i - 2], 17) ^
501
+ $this->_rightRotate($w[$i - 2], 19) ^
502
+ $this->_rightShift( $w[$i - 2], 10);
503
+ $w[$i] = $this->_add($w[$i - 16], $s0, $w[$i - 7], $s1);
504
+
505
+ }
506
+
507
+ // Initialize hash value for this chunk
508
+ list($a, $b, $c, $d, $e, $f, $g, $h) = $hash;
509
+
510
+ // Main loop
511
+ for ($i = 0; $i < 64; $i++) {
512
+ $s0 = $this->_rightRotate($a, 2) ^
513
+ $this->_rightRotate($a, 13) ^
514
+ $this->_rightRotate($a, 22);
515
+ $maj = ($a & $b) ^
516
+ ($a & $c) ^
517
+ ($b & $c);
518
+ $t2 = $this->_add($s0, $maj);
519
+
520
+ $s1 = $this->_rightRotate($e, 6) ^
521
+ $this->_rightRotate($e, 11) ^
522
+ $this->_rightRotate($e, 25);
523
+ $ch = ($e & $f) ^
524
+ ($this->_not($e) & $g);
525
+ $t1 = $this->_add($h, $s1, $ch, $k[$i], $w[$i]);
526
+
527
+ $h = $g;
528
+ $g = $f;
529
+ $f = $e;
530
+ $e = $this->_add($d, $t1);
531
+ $d = $c;
532
+ $c = $b;
533
+ $b = $a;
534
+ $a = $this->_add($t1, $t2);
535
+ }
536
+
537
+ // Add this chunk's hash to result so far
538
+ $hash = array(
539
+ $this->_add($hash[0], $a),
540
+ $this->_add($hash[1], $b),
541
+ $this->_add($hash[2], $c),
542
+ $this->_add($hash[3], $d),
543
+ $this->_add($hash[4], $e),
544
+ $this->_add($hash[5], $f),
545
+ $this->_add($hash[6], $g),
546
+ $this->_add($hash[7], $h)
547
+ );
548
+ }
549
+
550
+ // Produce the final hash value (big-endian)
551
+ return pack('N8', $hash[0], $hash[1], $hash[2], $hash[3], $hash[4], $hash[5], $hash[6], $hash[7]);
552
+ }
553
+
554
+ /**
555
+ * Pure-PHP implementation of SHA384 and SHA512
556
+ *
557
+ * @access private
558
+ * @param String $text
559
+ */
560
+ function _sha512($m)
561
+ {
562
+ if (!class_exists('Math_BigInteger')) {
563
+ require_once('Math/BigInteger.php');
564
+ }
565
+
566
+ static $init384, $init512, $k;
567
+
568
+ if (!isset($k)) {
569
+ // Initialize variables
570
+ $init384 = array( // initial values for SHA384
571
+ 'cbbb9d5dc1059ed8', '629a292a367cd507', '9159015a3070dd17', '152fecd8f70e5939',
572
+ '67332667ffc00b31', '8eb44a8768581511', 'db0c2e0d64f98fa7', '47b5481dbefa4fa4'
573
+ );
574
+ $init512 = array( // initial values for SHA512
575
+ '6a09e667f3bcc908', 'bb67ae8584caa73b', '3c6ef372fe94f82b', 'a54ff53a5f1d36f1',
576
+ '510e527fade682d1', '9b05688c2b3e6c1f', '1f83d9abfb41bd6b', '5be0cd19137e2179'
577
+ );
578
+
579
+ for ($i = 0; $i < 8; $i++) {
580
+ $init384[$i] = new Math_BigInteger($init384[$i], 16);
581
+ $init384[$i]->setPrecision(64);
582
+ $init512[$i] = new Math_BigInteger($init512[$i], 16);
583
+ $init512[$i]->setPrecision(64);
584
+ }
585
+
586
+ // Initialize table of round constants
587
+ // (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409)
588
+ $k = array(
589
+ '428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc',
590
+ '3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118',
591
+ 'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2',
592
+ '72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694',
593
+ 'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65',
594
+ '2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5',
595
+ '983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4',
596
+ 'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70',
597
+ '27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df',
598
+ '650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b',
599
+ 'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30',
600
+ 'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8',
601
+ '19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8',
602
+ '391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3',
603
+ '748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec',
604
+ '90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b',
605
+ 'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178',
606
+ '06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b',
607
+ '28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c',
608
+ '4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817'
609
+ );
610
+
611
+ for ($i = 0; $i < 80; $i++) {
612
+ $k[$i] = new Math_BigInteger($k[$i], 16);
613
+ }
614
+ }
615
+
616
+ $hash = $this->l == 48 ? $init384 : $init512;
617
+
618
+ // Pre-processing
619
+ $length = strlen($m);
620
+ // to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128
621
+ $m.= str_repeat(chr(0), 128 - (($length + 16) & 0x7F));
622
+ $m[$length] = chr(0x80);
623
+ // we don't support hashing strings 512MB long
624
+ $m.= pack('N4', 0, 0, 0, $length << 3);
625
+
626
+ // Process the message in successive 1024-bit chunks
627
+ $chunks = str_split($m, 128);
628
+ foreach ($chunks as $chunk) {
629
+ $w = array();
630
+ for ($i = 0; $i < 16; $i++) {
631
+ $temp = new Math_BigInteger($this->_string_shift($chunk, 8), 256);
632
+ $temp->setPrecision(64);
633
+ $w[] = $temp;
634
+ }
635
+
636
+ // Extend the sixteen 32-bit words into eighty 32-bit words
637
+ for ($i = 16; $i < 80; $i++) {
638
+ $temp = array(
639
+ $w[$i - 15]->bitwise_rightRotate(1),
640
+ $w[$i - 15]->bitwise_rightRotate(8),
641
+ $w[$i - 15]->bitwise_rightShift(7)
642
+ );
643
+ $s0 = $temp[0]->bitwise_xor($temp[1]);
644
+ $s0 = $s0->bitwise_xor($temp[2]);
645
+ $temp = array(
646
+ $w[$i - 2]->bitwise_rightRotate(19),
647
+ $w[$i - 2]->bitwise_rightRotate(61),
648
+ $w[$i - 2]->bitwise_rightShift(6)
649
+ );
650
+ $s1 = $temp[0]->bitwise_xor($temp[1]);
651
+ $s1 = $s1->bitwise_xor($temp[2]);
652
+ $w[$i] = $w[$i - 16]->copy();
653
+ $w[$i] = $w[$i]->add($s0);
654
+ $w[$i] = $w[$i]->add($w[$i - 7]);
655
+ $w[$i] = $w[$i]->add($s1);
656
+ }
657
+
658
+ // Initialize hash value for this chunk
659
+ $a = $hash[0]->copy();
660
+ $b = $hash[1]->copy();
661
+ $c = $hash[2]->copy();
662
+ $d = $hash[3]->copy();
663
+ $e = $hash[4]->copy();
664
+ $f = $hash[5]->copy();
665
+ $g = $hash[6]->copy();
666
+ $h = $hash[7]->copy();
667
+
668
+ // Main loop
669
+ for ($i = 0; $i < 80; $i++) {
670
+ $temp = array(
671
+ $a->bitwise_rightRotate(28),
672
+ $a->bitwise_rightRotate(34),
673
+ $a->bitwise_rightRotate(39)
674
+ );
675
+ $s0 = $temp[0]->bitwise_xor($temp[1]);
676
+ $s0 = $s0->bitwise_xor($temp[2]);
677
+ $temp = array(
678
+ $a->bitwise_and($b),
679
+ $a->bitwise_and($c),
680
+ $b->bitwise_and($c)
681
+ );
682
+ $maj = $temp[0]->bitwise_xor($temp[1]);
683
+ $maj = $maj->bitwise_xor($temp[2]);
684
+ $t2 = $s0->add($maj);
685
+
686
+ $temp = array(
687
+ $e->bitwise_rightRotate(14),
688
+ $e->bitwise_rightRotate(18),
689
+ $e->bitwise_rightRotate(41)
690
+ );
691
+ $s1 = $temp[0]->bitwise_xor($temp[1]);
692
+ $s1 = $s1->bitwise_xor($temp[2]);
693
+ $temp = array(
694
+ $e->bitwise_and($f),
695
+ $g->bitwise_and($e->bitwise_not())
696
+ );
697
+ $ch = $temp[0]->bitwise_xor($temp[1]);
698
+ $t1 = $h->add($s1);
699
+ $t1 = $t1->add($ch);
700
+ $t1 = $t1->add($k[$i]);
701
+ $t1 = $t1->add($w[$i]);
702
+
703
+ $h = $g->copy();
704
+ $g = $f->copy();
705
+ $f = $e->copy();
706
+ $e = $d->add($t1);
707
+ $d = $c->copy();
708
+ $c = $b->copy();
709
+ $b = $a->copy();
710
+ $a = $t1->add($t2);
711
+ }
712
+
713
+ // Add this chunk's hash to result so far
714
+ $hash = array(
715
+ $hash[0]->add($a),
716
+ $hash[1]->add($b),
717
+ $hash[2]->add($c),
718
+ $hash[3]->add($d),
719
+ $hash[4]->add($e),
720
+ $hash[5]->add($f),
721
+ $hash[6]->add($g),
722
+ $hash[7]->add($h)
723
+ );
724
+ }
725
+
726
+ // Produce the final hash value (big-endian)
727
+ // (Crypt_Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here)
728
+ $temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() .
729
+ $hash[4]->toBytes() . $hash[5]->toBytes();
730
+ if ($this->l != 48) {
731
+ $temp.= $hash[6]->toBytes() . $hash[7]->toBytes();
732
+ }
733
+
734
+ return $temp;
735
+ }
736
+
737
+ /**
738
+ * Right Rotate
739
+ *
740
+ * @access private
741
+ * @param Integer $int
742
+ * @param Integer $amt
743
+ * @see _sha256()
744
+ * @return Integer
745
+ */
746
+ function _rightRotate($int, $amt)
747
+ {
748
+ $invamt = 32 - $amt;
749
+ $mask = (1 << $invamt) - 1;
750
+ return (($int << $invamt) & 0xFFFFFFFF) | (($int >> $amt) & $mask);
751
+ }
752
+
753
+ /**
754
+ * Right Shift
755
+ *
756
+ * @access private
757
+ * @param Integer $int
758
+ * @param Integer $amt
759
+ * @see _sha256()
760
+ * @return Integer
761
+ */
762
+ function _rightShift($int, $amt)
763
+ {
764
+ $mask = (1 << (32 - $amt)) - 1;
765
+ return ($int >> $amt) & $mask;
766
+ }
767
+
768
+ /**
769
+ * Not
770
+ *
771
+ * @access private
772
+ * @param Integer $int
773
+ * @see _sha256()
774
+ * @return Integer
775
+ */
776
+ function _not($int)
777
+ {
778
+ return ~$int & 0xFFFFFFFF;
779
+ }
780
+
781
+ /**
782
+ * Add
783
+ *
784
+ * _sha256() adds multiple unsigned 32-bit integers. Since PHP doesn't support unsigned integers and since the
785
+ * possibility of overflow exists, care has to be taken. Math_BigInteger() could be used but this should be faster.
786
+ *
787
+ * @param String $string
788
+ * @param optional Integer $index
789
+ * @return String
790
+ * @see _sha256()
791
+ * @access private
792
+ */
793
+ function _add()
794
+ {
795
+ static $mod;
796
+ if (!isset($mod)) {
797
+ $mod = pow(2, 32);
798
+ }
799
+
800
+ $result = 0;
801
+ $arguments = func_get_args();
802
+ foreach ($arguments as $argument) {
803
+ $result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;
804
+ }
805
+
806
+ return fmod($result, $mod);
807
+ }
808
+
809
+ /**
810
+ * String Shift
811
+ *
812
+ * Inspired by array_shift
813
+ *
814
+ * @param String $string
815
+ * @param optional Integer $index
816
+ * @return String
817
+ * @access private
818
+ */
819
+ function _string_shift(&$string, $index = 1)
820
+ {
821
+ $substr = substr($string, 0, $index);
822
+ $string = substr($string, $index);
823
+ return $substr;
824
+ }
825
+ }
phpseclib/Crypt/RC4.php CHANGED
@@ -1,564 +1,531 @@
1
- <?php
2
- /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
-
4
- /**
5
- * Pure-PHP implementation of RC4.
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://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt ARCFOUR Algorithm}
14
- * - {@link http://en.wikipedia.org/wiki/RC4 - Wikipedia: RC4}
15
- *
16
- * RC4 is also known as ARCFOUR or ARC4. The reason is elaborated upon at Wikipedia. This class is named RC4 and not
17
- * ARCFOUR or ARC4 because RC4 is how it is refered to in the SSH1 specification.
18
- *
19
- * Here's a short example of how to use this library:
20
- * <code>
21
- * <?php
22
- * include('Crypt/RC4.php');
23
- *
24
- * $rc4 = new Crypt_RC4();
25
- *
26
- * $rc4->setKey('abcdefgh');
27
- *
28
- * $size = 10 * 1024;
29
- * $plaintext = '';
30
- * for ($i = 0; $i < $size; $i++) {
31
- * $plaintext.= 'a';
32
- * }
33
- *
34
- * echo $rc4->decrypt($rc4->encrypt($plaintext));
35
- * ?>
36
- * </code>
37
- *
38
- * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
39
- * of this software and associated documentation files (the "Software"), to deal
40
- * in the Software without restriction, including without limitation the rights
41
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
42
- * copies of the Software, and to permit persons to whom the Software is
43
- * furnished to do so, subject to the following conditions:
44
- *
45
- * The above copyright notice and this permission notice shall be included in
46
- * all copies or substantial portions of the Software.
47
- *
48
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
49
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
50
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
51
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
52
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
53
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
54
- * THE SOFTWARE.
55
- *
56
- * @category Crypt
57
- * @package Crypt_RC4
58
- * @author Jim Wigginton <terrafrost@php.net>
59
- * @copyright MMVII Jim Wigginton
60
- * @license http://www.opensource.org/licenses/mit-license.html MIT License
61
- * @version $Id: RC4.php,v 1.8 2009/06/09 04:00:38 terrafrost Exp $
62
- * @link http://phpseclib.sourceforge.net
63
- */
64
-
65
- /**#@+
66
- * @access private
67
- * @see Crypt_RC4::Crypt_RC4()
68
- */
69
- /**
70
- * Toggles the internal implementation
71
- */
72
- define('CRYPT_RC4_MODE_INTERNAL', 1);
73
- /**
74
- * Toggles the mcrypt implementation
75
- */
76
- define('CRYPT_RC4_MODE_MCRYPT', 2);
77
- /**#@-*/
78
-
79
- /**#@+
80
- * @access private
81
- * @see Crypt_RC4::_crypt()
82
- */
83
- define('CRYPT_RC4_ENCRYPT', 0);
84
- define('CRYPT_RC4_DECRYPT', 1);
85
- /**#@-*/
86
-
87
- /**
88
- * Pure-PHP implementation of RC4.
89
- *
90
- * @author Jim Wigginton <terrafrost@php.net>
91
- * @version 0.1.0
92
- * @access public
93
- * @package Crypt_RC4
94
- */
95
- class Crypt_RC4 {
96
- /**
97
- * The Key
98
- *
99
- * @see Crypt_RC4::setKey()
100
- * @var String
101
- * @access private
102
- */
103
- var $key = "\0";
104
-
105
- /**
106
- * The Key Stream for encryption
107
- *
108
- * If CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT, this will be equal to the mcrypt object
109
- *
110
- * @see Crypt_RC4::setKey()
111
- * @var Array
112
- * @access private
113
- */
114
- var $encryptStream = false;
115
-
116
- /**
117
- * The Key Stream for decryption
118
- *
119
- * If CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT, this will be equal to the mcrypt object
120
- *
121
- * @see Crypt_RC4::setKey()
122
- * @var Array
123
- * @access private
124
- */
125
- var $decryptStream = false;
126
-
127
- /**
128
- * The $i and $j indexes for encryption
129
- *
130
- * @see Crypt_RC4::_crypt()
131
- * @var Integer
132
- * @access private
133
- */
134
- var $encryptIndex = 0;
135
-
136
- /**
137
- * The $i and $j indexes for decryption
138
- *
139
- * @see Crypt_RC4::_crypt()
140
- * @var Integer
141
- * @access private
142
- */
143
- var $decryptIndex = 0;
144
-
145
- /**
146
- * MCrypt parameters
147
- *
148
- * @see Crypt_RC4::setMCrypt()
149
- * @var Array
150
- * @access private
151
- */
152
- var $mcrypt = array('', '');
153
-
154
- /**
155
- * The Encryption Algorithm
156
- *
157
- * Only used if CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT. Only possible values are MCRYPT_RC4 or MCRYPT_ARCFOUR.
158
- *
159
- * @see Crypt_RC4::Crypt_RC4()
160
- * @var Integer
161
- * @access private
162
- */
163
- var $mode;
164
-
165
- /**
166
- * Continuous Buffer status
167
- *
168
- * @see Crypt_RC4::enableContinuousBuffer()
169
- * @var Boolean
170
- * @access private
171
- */
172
- var $continuousBuffer = false;
173
-
174
- /**
175
- * Default Constructor.
176
- *
177
- * Determines whether or not the mcrypt extension should be used.
178
- *
179
- * @param optional Integer $mode
180
- * @return Crypt_RC4
181
- * @access public
182
- */
183
- function Crypt_RC4()
184
- {
185
- if ( !defined('CRYPT_RC4_MODE') ) {
186
- switch (true) {
187
- case extension_loaded('mcrypt') && (defined('MCRYPT_ARCFOUR') || defined('MCRYPT_RC4')):
188
- // i'd check to see if rc4 was supported, by doing in_array('arcfour', mcrypt_list_algorithms('')),
189
- // but since that can be changed after the object has been created, there doesn't seem to be
190
- // a lot of point...
191
- define('CRYPT_RC4_MODE', CRYPT_RC4_MODE_MCRYPT);
192
- break;
193
- default:
194
- define('CRYPT_RC4_MODE', CRYPT_RC4_MODE_INTERNAL);
195
- }
196
- }
197
-
198
- switch ( CRYPT_RC4_MODE ) {
199
- case CRYPT_RC4_MODE_MCRYPT:
200
- switch (true) {
201
- case defined('MCRYPT_ARCFOUR'):
202
- $this->mode = MCRYPT_ARCFOUR;
203
- break;
204
- case defined('MCRYPT_RC4');
205
- $this->mode = MCRYPT_RC4;
206
- }
207
- }
208
- }
209
-
210
- /**
211
- * Sets the key.
212
- *
213
- * Keys can be between 1 and 256 bytes long. If they are longer then 256 bytes, the first 256 bytes will
214
- * be used. If no key is explicitly set, it'll be assumed to be a single null byte.
215
- *
216
- * @access public
217
- * @param String $key
218
- */
219
- function setKey($key)
220
- {
221
- $this->key = $key;
222
-
223
- if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT ) {
224
- return;
225
- }
226
-
227
- $keyLength = strlen($key);
228
- $keyStream = array();
229
- for ($i = 0; $i < 256; $i++) {
230
- $keyStream[$i] = $i;
231
- }
232
- $j = 0;
233
- for ($i = 0; $i < 256; $i++) {
234
- $j = ($j + $keyStream[$i] + ord($key[$i % $keyLength])) & 255;
235
- $temp = $keyStream[$i];
236
- $keyStream[$i] = $keyStream[$j];
237
- $keyStream[$j] = $temp;
238
- }
239
-
240
- $this->encryptIndex = $this->decryptIndex = array(0, 0);
241
- $this->encryptStream = $this->decryptStream = $keyStream;
242
- }
243
-
244
- /**
245
- * Sets the password.
246
- *
247
- * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows:
248
- * {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2}:
249
- * $hash, $salt, $method, $dkLen
250
- *
251
- * @param String $password
252
- * @param optional String $method
253
- * @access public
254
- */
255
- function setPassword($password, $method = 'pbkdf2')
256
- {
257
- $key = '';
258
-
259
- switch ($method) {
260
- default: // 'pbkdf2'
261
- list(, , $hash, $salt, $count) = func_get_args();
262
- if (!isset($hash)) {
263
- $hash = 'sha1';
264
- }
265
- // WPA and WPA use the SSID as the salt
266
- if (!isset($salt)) {
267
- $salt = 'phpseclib';
268
- }
269
- // RFC2898#section-4.2 uses 1,000 iterations by default
270
- // WPA and WPA2 use 4,096.
271
- if (!isset($count)) {
272
- $count = 1000;
273
- }
274
- if (!isset($count)) {
275
- $count = 1000;
276
- }
277
- if (!isset($dkLen)) {
278
- $count = 1000;
279
- }
280
-
281
- if (!class_exists('Crypt_Hash')) {
282
- require_once('Crypt/Hash.php');
283
- }
284
-
285
- $i = 1;
286
- while (strlen($key) < $dkLen) {
287
- //$dk.= $this->_pbkdf($password, $salt, $count, $i++);
288
- $hmac = new Crypt_Hash();
289
- $hmac->setHash($hash);
290
- $hmac->setKey($password);
291
- $f = $u = $hmac->hash($salt . pack('N', $i++));
292
- for ($j = 2; $j <= $count; $j++) {
293
- $u = $hmac->hash($u);
294
- $f^= $u;
295
- }
296
- $key.= $f;
297
- }
298
- }
299
-
300
- $this->setKey(substr($key, 0, $dkLen));
301
- }
302
-
303
- /**
304
- * Dummy function.
305
- *
306
- * Some protocols, such as WEP, prepend an "initialization vector" to the key, effectively creating a new key [1].
307
- * If you need to use an initialization vector in this manner, feel free to prepend it to the key, yourself, before
308
- * calling setKey().
309
- *
310
- * [1] WEP's initialization vectors (IV's) are used in a somewhat insecure way. Since, in that protocol,
311
- * the IV's are relatively easy to predict, an attack described by
312
- * {@link http://www.drizzle.com/~aboba/IEEE/rc4_ksaproc.pdf Scott Fluhrer, Itsik Mantin, and Adi Shamir}
313
- * can be used to quickly guess at the rest of the key. The following links elaborate:
314
- *
315
- * {@link http://www.rsa.com/rsalabs/node.asp?id=2009 http://www.rsa.com/rsalabs/node.asp?id=2009}
316
- * {@link http://en.wikipedia.org/wiki/Related_key_attack http://en.wikipedia.org/wiki/Related_key_attack}
317
- *
318
- * @param String $iv
319
- * @see Crypt_RC4::setKey()
320
- * @access public
321
- */
322
- function setIV($iv)
323
- {
324
- }
325
-
326
- /**
327
- * Sets MCrypt parameters. (optional)
328
- *
329
- * If MCrypt is being used, empty strings will be used, unless otherwise specified.
330
- *
331
- * @link http://php.net/function.mcrypt-module-open#function.mcrypt-module-open
332
- * @access public
333
- * @param optional Integer $algorithm_directory
334
- * @param optional Integer $mode_directory
335
- */
336
- function setMCrypt($algorithm_directory = '', $mode_directory = '')
337
- {
338
- if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT ) {
339
- $this->mcrypt = array($algorithm_directory, $mode_directory);
340
- $this->_closeMCrypt();
341
- }
342
- }
343
-
344
- /**
345
- * Encrypts a message.
346
- *
347
- * @see Crypt_RC4::_crypt()
348
- * @access public
349
- * @param String $plaintext
350
- */
351
- function encrypt($plaintext)
352
- {
353
- return $this->_crypt($plaintext, CRYPT_RC4_ENCRYPT);
354
- }
355
-
356
- /**
357
- * Decrypts a message.
358
- *
359
- * $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)).
360
- * Atleast if the continuous buffer is disabled.
361
- *
362
- * @see Crypt_RC4::_crypt()
363
- * @access public
364
- * @param String $ciphertext
365
- */
366
- function decrypt($ciphertext)
367
- {
368
- return $this->_crypt($ciphertext, CRYPT_RC4_DECRYPT);
369
- }
370
-
371
- /**
372
- * Encrypts or decrypts a message.
373
- *
374
- * @see Crypt_RC4::encrypt()
375
- * @see Crypt_RC4::decrypt()
376
- * @access private
377
- * @param String $text
378
- * @param Integer $mode
379
- */
380
- function _crypt($text, $mode)
381
- {
382
- if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT ) {
383
- $keyStream = $mode == CRYPT_RC4_ENCRYPT ? 'encryptStream' : 'decryptStream';
384
-
385
- if ($this->$keyStream === false) {
386
- $this->$keyStream = mcrypt_module_open($this->mode, $this->mcrypt[0], MCRYPT_MODE_STREAM, $this->mcrypt[1]);
387
- mcrypt_generic_init($this->$keyStream, $this->key, '');
388
- } else if (!$this->continuousBuffer) {
389
- mcrypt_generic_init($this->$keyStream, $this->key, '');
390
- }
391
- $newText = mcrypt_generic($this->$keyStream, $text);
392
- if (!$this->continuousBuffer) {
393
- mcrypt_generic_deinit($this->$keyStream);
394
- }
395
-
396
- return $newText;
397
- }
398
-
399
- if ($this->encryptStream === false) {
400
- $this->setKey($this->key);
401
- }
402
-
403
- switch ($mode) {
404
- case CRYPT_RC4_ENCRYPT:
405
- $keyStream = $this->encryptStream;
406
- list($i, $j) = $this->encryptIndex;
407
- break;
408
- case CRYPT_RC4_DECRYPT:
409
- $keyStream = $this->decryptStream;
410
- list($i, $j) = $this->decryptIndex;
411
- }
412
-
413
- $newText = '';
414
- for ($k = 0; $k < strlen($text); $k++) {
415
- $i = ($i + 1) & 255;
416
- $j = ($j + $keyStream[$i]) & 255;
417
- $temp = $keyStream[$i];
418
- $keyStream[$i] = $keyStream[$j];
419
- $keyStream[$j] = $temp;
420
- $temp = $keyStream[($keyStream[$i] + $keyStream[$j]) & 255];
421
- $newText.= chr(ord($text[$k]) ^ $temp);
422
- }
423
-
424
- if ($this->continuousBuffer) {
425
- switch ($mode) {
426
- case CRYPT_RC4_ENCRYPT:
427
- $this->encryptStream = $keyStream;
428
- $this->encryptIndex = array($i, $j);
429
- break;
430
- case CRYPT_RC4_DECRYPT:
431
- $this->decryptStream = $keyStream;
432
- $this->decryptIndex = array($i, $j);
433
- }
434
- }
435
-
436
- return $newText;
437
- }
438
-
439
- /**
440
- * Treat consecutive "packets" as if they are a continuous buffer.
441
- *
442
- * Say you have a 16-byte plaintext $plaintext. Using the default behavior, the two following code snippets
443
- * will yield different outputs:
444
- *
445
- * <code>
446
- * echo $rc4->encrypt(substr($plaintext, 0, 8));
447
- * echo $rc4->encrypt(substr($plaintext, 8, 8));
448
- * </code>
449
- * <code>
450
- * echo $rc4->encrypt($plaintext);
451
- * </code>
452
- *
453
- * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates
454
- * another, as demonstrated with the following:
455
- *
456
- * <code>
457
- * $rc4->encrypt(substr($plaintext, 0, 8));
458
- * echo $rc4->decrypt($des->encrypt(substr($plaintext, 8, 8)));
459
- * </code>
460
- * <code>
461
- * echo $rc4->decrypt($des->encrypt(substr($plaintext, 8, 8)));
462
- * </code>
463
- *
464
- * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different
465
- * outputs. The reason is due to the fact that the initialization vector's change after every encryption /
466
- * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
467
- *
468
- * Put another way, when the continuous buffer is enabled, the state of the Crypt_DES() object changes after each
469
- * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
470
- * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
471
- * however, they are also less intuitive and more likely to cause you problems.
472
- *
473
- * @see Crypt_RC4::disableContinuousBuffer()
474
- * @access public
475
- */
476
- function enableContinuousBuffer()
477
- {
478
- $this->continuousBuffer = true;
479
- }
480
-
481
- /**
482
- * Treat consecutive packets as if they are a discontinuous buffer.
483
- *
484
- * The default behavior.
485
- *
486
- * @see Crypt_RC4::enableContinuousBuffer()
487
- * @access public
488
- */
489
- function disableContinuousBuffer()
490
- {
491
- if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_INTERNAL ) {
492
- $this->encryptIndex = $this->decryptIndex = array(0, 0);
493
- $this->setKey($this->key);
494
- }
495
-
496
- $this->continuousBuffer = false;
497
- }
498
-
499
- /**
500
- * Dummy function.
501
- *
502
- * Since RC4 is a stream cipher and not a block cipher, no padding is necessary. The only reason this function is
503
- * included is so that you can switch between a block cipher and a stream cipher transparently.
504
- *
505
- * @see Crypt_RC4::disablePadding()
506
- * @access public
507
- */
508
- function enablePadding()
509
- {
510
- }
511
-
512
- /**
513
- * Dummy function.
514
- *
515
- * @see Crypt_RC4::enablePadding()
516
- * @access public
517
- */
518
- function disablePadding()
519
- {
520
- }
521
-
522
- /**
523
- * Class destructor.
524
- *
525
- * Will be called, automatically, if you're using PHP5. If you're using PHP4, call it yourself. Only really
526
- * needs to be called if mcrypt is being used.
527
- *
528
- * @access public
529
- */
530
- function __destruct()
531
- {
532
- if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT ) {
533
- $this->_closeMCrypt();
534
- }
535
- }
536
-
537
- /**
538
- * Properly close the MCrypt objects.
539
- *
540
- * @access prviate
541
- */
542
- function _closeMCrypt()
543
- {
544
- if ( $this->encryptStream !== false ) {
545
- if ( $this->continuousBuffer ) {
546
- mcrypt_generic_deinit($this->encryptStream);
547
- }
548
-
549
- mcrypt_module_close($this->encryptStream);
550
-
551
- $this->encryptStream = false;
552
- }
553
-
554
- if ( $this->decryptStream !== false ) {
555
- if ( $this->continuousBuffer ) {
556
- mcrypt_generic_deinit($this->decryptStream);
557
- }
558
-
559
- mcrypt_module_close($this->decryptStream);
560
-
561
- $this->decryptStream = false;
562
- }
563
- }
564
- }
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * Pure-PHP implementation of RC4.
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://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt ARCFOUR Algorithm}
14
+ * - {@link http://en.wikipedia.org/wiki/RC4 - Wikipedia: RC4}
15
+ *
16
+ * RC4 is also known as ARCFOUR or ARC4. The reason is elaborated upon at Wikipedia. This class is named RC4 and not
17
+ * ARCFOUR or ARC4 because RC4 is how it is refered to in the SSH1 specification.
18
+ *
19
+ * Here's a short example of how to use this library:
20
+ * <code>
21
+ * <?php
22
+ * include('Crypt/RC4.php');
23
+ *
24
+ * $rc4 = new Crypt_RC4();
25
+ *
26
+ * $rc4->setKey('abcdefgh');
27
+ *
28
+ * $size = 10 * 1024;
29
+ * $plaintext = '';
30
+ * for ($i = 0; $i < $size; $i++) {
31
+ * $plaintext.= 'a';
32
+ * }
33
+ *
34
+ * echo $rc4->decrypt($rc4->encrypt($plaintext));
35
+ * ?>
36
+ * </code>
37
+ *
38
+ * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
39
+ * of this software and associated documentation files (the "Software"), to deal
40
+ * in the Software without restriction, including without limitation the rights
41
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
42
+ * copies of the Software, and to permit persons to whom the Software is
43
+ * furnished to do so, subject to the following conditions:
44
+ *
45
+ * The above copyright notice and this permission notice shall be included in
46
+ * all copies or substantial portions of the Software.
47
+ *
48
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
49
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
50
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
51
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
52
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
53
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
54
+ * THE SOFTWARE.
55
+ *
56
+ * @category Crypt
57
+ * @package Crypt_RC4
58
+ * @author Jim Wigginton <terrafrost@php.net>
59
+ * @copyright MMVII Jim Wigginton
60
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
61
+ * @version $Id: RC4.php,v 1.8 2009/06/09 04:00:38 terrafrost Exp $
62
+ * @link http://phpseclib.sourceforge.net
63
+ */
64
+
65
+ /**#@+
66
+ * @access private
67
+ * @see Crypt_RC4::Crypt_RC4()
68
+ */
69
+ /**
70
+ * Toggles the internal implementation
71
+ */
72
+ define('CRYPT_RC4_MODE_INTERNAL', 1);
73
+ /**
74
+ * Toggles the mcrypt implementation
75
+ */
76
+ define('CRYPT_RC4_MODE_MCRYPT', 2);
77
+ /**#@-*/
78
+
79
+ /**#@+
80
+ * @access private
81
+ * @see Crypt_RC4::_crypt()
82
+ */
83
+ define('CRYPT_RC4_ENCRYPT', 0);
84
+ define('CRYPT_RC4_DECRYPT', 1);
85
+ /**#@-*/
86
+
87
+ /**
88
+ * Pure-PHP implementation of RC4.
89
+ *
90
+ * @author Jim Wigginton <terrafrost@php.net>
91
+ * @version 0.1.0
92
+ * @access public
93
+ * @package Crypt_RC4
94
+ */
95
+ class Crypt_RC4 {
96
+ /**
97
+ * The Key
98
+ *
99
+ * @see Crypt_RC4::setKey()
100
+ * @var String
101
+ * @access private
102
+ */
103
+ var $key = "\0";
104
+
105
+ /**
106
+ * The Key Stream for encryption
107
+ *
108
+ * If CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT, this will be equal to the mcrypt object
109
+ *
110
+ * @see Crypt_RC4::setKey()
111
+ * @var Array
112
+ * @access private
113
+ */
114
+ var $encryptStream = false;
115
+
116
+ /**
117
+ * The Key Stream for decryption
118
+ *
119
+ * If CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT, this will be equal to the mcrypt object
120
+ *
121
+ * @see Crypt_RC4::setKey()
122
+ * @var Array
123
+ * @access private
124
+ */
125
+ var $decryptStream = false;
126
+
127
+ /**
128
+ * The $i and $j indexes for encryption
129
+ *
130
+ * @see Crypt_RC4::_crypt()
131
+ * @var Integer
132
+ * @access private
133
+ */
134
+ var $encryptIndex = 0;
135
+
136
+ /**
137
+ * The $i and $j indexes for decryption
138
+ *
139
+ * @see Crypt_RC4::_crypt()
140
+ * @var Integer
141
+ * @access private
142
+ */
143
+ var $decryptIndex = 0;
144
+
145
+ /**
146
+ * The Encryption Algorithm
147
+ *
148
+ * Only used if CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT. Only possible values are MCRYPT_RC4 or MCRYPT_ARCFOUR.
149
+ *
150
+ * @see Crypt_RC4::Crypt_RC4()
151
+ * @var Integer
152
+ * @access private
153
+ */
154
+ var $mode;
155
+
156
+ /**
157
+ * Continuous Buffer status
158
+ *
159
+ * @see Crypt_RC4::enableContinuousBuffer()
160
+ * @var Boolean
161
+ * @access private
162
+ */
163
+ var $continuousBuffer = false;
164
+
165
+ /**
166
+ * Default Constructor.
167
+ *
168
+ * Determines whether or not the mcrypt extension should be used.
169
+ *
170
+ * @param optional Integer $mode
171
+ * @return Crypt_RC4
172
+ * @access public
173
+ */
174
+ function Crypt_RC4()
175
+ {
176
+ if ( !defined('CRYPT_RC4_MODE') ) {
177
+ switch (true) {
178
+ case extension_loaded('mcrypt') && (defined('MCRYPT_ARCFOUR') || defined('MCRYPT_RC4')) && in_array('arcfour', mcrypt_list_algorithms()):
179
+ define('CRYPT_RC4_MODE', CRYPT_RC4_MODE_MCRYPT);
180
+ break;
181
+ default:
182
+ define('CRYPT_RC4_MODE', CRYPT_RC4_MODE_INTERNAL);
183
+ }
184
+ }
185
+
186
+ switch ( CRYPT_RC4_MODE ) {
187
+ case CRYPT_RC4_MODE_MCRYPT:
188
+ switch (true) {
189
+ case defined('MCRYPT_ARCFOUR'):
190
+ $this->mode = MCRYPT_ARCFOUR;
191
+ break;
192
+ case defined('MCRYPT_RC4');
193
+ $this->mode = MCRYPT_RC4;
194
+ }
195
+ }
196
+ }
197
+
198
+ /**
199
+ * Sets the key.
200
+ *
201
+ * Keys can be between 1 and 256 bytes long. If they are longer then 256 bytes, the first 256 bytes will
202
+ * be used. If no key is explicitly set, it'll be assumed to be a single null byte.
203
+ *
204
+ * @access public
205
+ * @param String $key
206
+ */
207
+ function setKey($key)
208
+ {
209
+ $this->key = $key;
210
+
211
+ if ( CRYPT_RC4_MODE == CRYPT_RC4_MODE_MCRYPT ) {
212
+ return;
213
+ }
214
+
215
+ $keyLength = strlen($key);
216
+ $keyStream = array();
217
+ for ($i = 0; $i < 256; $i++) {
218
+ $keyStream[$i] = $i;
219
+ }
220
+ $j = 0;
221
+ for ($i = 0; $i < 256; $i++) {
222
+ $j = ($j + $keyStream[$i] + ord($key[$i % $keyLength])) & 255;
223
+ $temp = $keyStream[$i];
224
+ $keyStream[$i] = $keyStream[$j];
225
+ $keyStream[$j] = $temp;
226
+ }
227
+
228
+ $this->encryptIndex = $this->decryptIndex = array(0, 0);
229
+ $this->encryptStream = $this->decryptStream = $keyStream;
230
+ }
231
+
232
+ /**
233
+ * Sets the password.
234
+ *
235
+ * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows:
236
+ * {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2}:
237
+ * $hash, $salt, $count, $dkLen
238
+ *
239
+ * @param String $password
240
+ * @param optional String $method
241
+ * @access public
242
+ */
243
+ function setPassword($password, $method = 'pbkdf2')
244
+ {
245
+ $key = '';
246
+
247
+ switch ($method) {
248
+ default: // 'pbkdf2'
249
+ list(, , $hash, $salt, $count) = func_get_args();
250
+ if (!isset($hash)) {
251
+ $hash = 'sha1';
252
+ }
253
+ // WPA and WPA use the SSID as the salt
254
+ if (!isset($salt)) {
255
+ $salt = 'phpseclib/salt';
256
+ }
257
+ // RFC2898#section-4.2 uses 1,000 iterations by default
258
+ // WPA and WPA2 use 4,096.
259
+ if (!isset($count)) {
260
+ $count = 1000;
261
+ }
262
+ if (!isset($dkLen)) {
263
+ $dkLen = 128;
264
+ }
265
+
266
+ if (!class_exists('Crypt_Hash')) {
267
+ require_once('Crypt/Hash.php');
268
+ }
269
+
270
+ $i = 1;
271
+ while (strlen($key) < $dkLen) {
272
+ //$dk.= $this->_pbkdf($password, $salt, $count, $i++);
273
+ $hmac = new Crypt_Hash();
274
+ $hmac->setHash($hash);
275
+ $hmac->setKey($password);
276
+ $f = $u = $hmac->hash($salt . pack('N', $i++));
277
+ for ($j = 2; $j <= $count; $j++) {
278
+ $u = $hmac->hash($u);
279
+ $f^= $u;
280
+ }
281
+ $key.= $f;
282
+ }
283
+ }
284
+
285
+ $this->setKey(substr($key, 0, $dkLen));
286
+ }
287
+
288
+ /**
289
+ * Dummy function.
290
+ *
291
+ * Some protocols, such as WEP, prepend an "initialization vector" to the key, effectively creating a new key [1].
292
+ * If you need to use an initialization vector in this manner, feel free to prepend it to the key, yourself, before
293
+ * calling setKey().
294
+ *
295
+ * [1] WEP's initialization vectors (IV's) are used in a somewhat insecure way. Since, in that protocol,
296
+ * the IV's are relatively easy to predict, an attack described by
297
+ * {@link http://www.drizzle.com/~aboba/IEEE/rc4_ksaproc.pdf Scott Fluhrer, Itsik Mantin, and Adi Shamir}
298
+ * can be used to quickly guess at