Wisepricer_Syncer - Version 1.1.2.6

Version Notes

wisepricer

Download this release

Release Info

Developer Moshe
Extension Wisepricer_Syncer
Version 1.1.2.6
Comparing to
See all releases


Code changes from version 1.1.2.5 to 1.1.2.6

app/code/local/Wisepricer/Syncer/Model/Mysql4/Mapping.php CHANGED
@@ -12,11 +12,12 @@ class Wisepricer_Syncer_Model_Mysql4_Mapping extends Mage_Core_Model_Mysql4_Abst
12
}
13
14
public function loadIdByWsfield(Wisepricer_Syncer_Model_Mapping $mapping, $wsfield, $testOnly = false)
15
- {
16
$adapter = $this->_getReadAdapter();
17
$bind = array('wsp_field' => $wsfield);
18
$select = $adapter->select()
19
- ->from('wisepricer_syncer_mapping')
20
->where('wsp_field = :wsp_field');
21
22
12
}
13
14
public function loadIdByWsfield(Wisepricer_Syncer_Model_Mapping $mapping, $wsfield, $testOnly = false)
15
+ {
16
$adapter = $this->_getReadAdapter();
17
+ $tableName = Mage::getSingleton('core/resource')->getTableName('wisepricer_syncer_mapping');
18
$bind = array('wsp_field' => $wsfield);
19
$select = $adapter->select()
20
+ ->from($tableName)
21
->where('wsp_field = :wsp_field');
22
23
app/code/local/Wisepricer/Syncer/controllers/ProductsController.php CHANGED
@@ -103,9 +103,10 @@ class Wisepricer_Syncer_ProductsController extends Mage_Core_Controller_Front_Ac
103
104
}elseif($field['wsp_field']=='shipping'){
105
106
- if(is_numeric($productOrigData['shipping'])){
107
$productData['shipping']=$field['magento_field'];
108
}else{
109
$productData['shipping']=$this->productOrigData[$field['magento_field']];
110
}
111
@@ -115,6 +116,7 @@ class Wisepricer_Syncer_ProductsController extends Mage_Core_Controller_Front_Ac
115
$productData[$field['wsp_field']]=$this->_calculateMinPrice($field);
116
117
}else{
118
$productData[$field['wsp_field']]=$this->productOrigData[$field['magento_field']];
119
}
120
}else{
@@ -128,7 +130,8 @@ class Wisepricer_Syncer_ProductsController extends Mage_Core_Controller_Front_Ac
128
$productData[$field['wsp_field']]=$attrLabel;
129
// echo '<pre>'.print_r($attr,true).'</pre>';//die;
130
}else{
131
- $productData[$field['wsp_field']]=$this->productOrigData[$field['magento_field']];
132
}
133
134
103
104
}elseif($field['wsp_field']=='shipping'){
105
106
+ if(is_numeric($this->productOrigData['shipping'])){
107
$productData['shipping']=$field['magento_field'];
108
}else{
109
+ if(!isset($this->productOrigData[$field['magento_field']])){continue;}
110
$productData['shipping']=$this->productOrigData[$field['magento_field']];
111
}
112
116
$productData[$field['wsp_field']]=$this->_calculateMinPrice($field);
117
118
}else{
119
+ if(!isset($this->productOrigData[$field['magento_field']])){continue;}
120
$productData[$field['wsp_field']]=$this->productOrigData[$field['magento_field']];
121
}
122
}else{
130
$productData[$field['wsp_field']]=$attrLabel;
131
// echo '<pre>'.print_r($attr,true).'</pre>';//die;
132
}else{
133
+ if(!isset($this->productOrigData[$field['magento_field']])){continue;}
134
+ $productData[$field['wsp_field']]=$this->productOrigData[$field['magento_field']];
135
}
136
137
app/code/local/Wisepricer/Syncer/lib/phpseclib/Crypt/AES.php CHANGED
@@ -1,479 +1,479 @@
1
- <?php
2
- /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
-
4
- /**
5
- * Pure-PHP implementation of AES.
6
- *
7
- * Uses mcrypt, if available, and an internal implementation, otherwise.
8
- *
9
- * PHP versions 4 and 5
10
- *
11
- * If {@link Crypt_AES::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
12
- * {@link Crypt_AES::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's 136-bits
13
- * it'll be null-padded to 160-bits and 160 bits will be the key length until {@link Crypt_Rijndael::setKey() setKey()}
14
- * is called, again, at which point, it'll be recalculated.
15
- *
16
- * Since Crypt_AES extends Crypt_Rijndael, some functions are available to be called that, in the context of AES, don't
17
- * make a whole lot of sense. {@link Crypt_AES::setBlockLength() setBlockLength()}, for instance. Calling that function,
18
- * however possible, won't do anything (AES has a fixed block length whereas Rijndael has a variable one).
19
- *
20
- * Here's a short example of how to use this library:
21
- * <code>
22
- * <?php
23
- * include('Crypt/AES.php');
24
- *
25
- * $aes = new Crypt_AES();
26
- *
27
- * $aes->setKey('abcdefghijklmnop');
28
- *
29
- * $size = 10 * 1024;
30
- * $plaintext = '';
31
- * for ($i = 0; $i < $size; $i++) {
32
- * $plaintext.= 'a';
33
- * }
34
- *
35
- * echo $aes->decrypt($aes->encrypt($plaintext));
36
- * ?>
37
- * </code>
38
- *
39
- * LICENSE: This library is free software; you can redistribute it and/or
40
- * modify it under the terms of the GNU Lesser General Public
41
- * License as published by the Free Software Foundation; either
42
- * version 2.1 of the License, or (at your option) any later version.
43
- *
44
- * This library is distributed in the hope that it will be useful,
45
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
46
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
47
- * Lesser General Public License for more details.
48
- *
49
- * You should have received a copy of the GNU Lesser General Public
50
- * License along with this library; if not, write to the Free Software
51
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
52
- * MA 02111-1307 USA
53
- *
54
- * @category Crypt
55
- * @package Crypt_AES
56
- * @author Jim Wigginton <terrafrost@php.net>
57
- * @copyright MMVIII Jim Wigginton
58
- * @license http://www.gnu.org/licenses/lgpl.txt
59
- * @version $Id: AES.php,v 1.7 2010/02/09 06:10:25 terrafrost Exp $
60
- * @link http://phpseclib.sourceforge.net
61
- */
62
-
63
- /**
64
- * Include Crypt_Rijndael
65
- */
66
- require_once 'Rijndael.php';
67
-
68
- /**#@+
69
- * @access public
70
- * @see Crypt_AES::encrypt()
71
- * @see Crypt_AES::decrypt()
72
- */
73
- /**
74
- * Encrypt / decrypt using the Counter mode.
75
- *
76
- * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
77
- *
78
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
79
- */
80
- define('CRYPT_AES_MODE_CTR', -1);
81
- /**
82
- * Encrypt / decrypt using the Electronic Code Book mode.
83
- *
84
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
85
- */
86
- define('CRYPT_AES_MODE_ECB', 1);
87
- /**
88
- * Encrypt / decrypt using the Code Book Chaining mode.
89
- *
90
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
91
- */
92
- define('CRYPT_AES_MODE_CBC', 2);
93
- /**#@-*/
94
-
95
- /**#@+
96
- * @access private
97
- * @see Crypt_AES::Crypt_AES()
98
- */
99
- /**
100
- * Toggles the internal implementation
101
- */
102
- define('CRYPT_AES_MODE_INTERNAL', 1);
103
- /**
104
- * Toggles the mcrypt implementation
105
- */
106
- define('CRYPT_AES_MODE_MCRYPT', 2);
107
- /**#@-*/
108
-
109
- /**
110
- * Pure-PHP implementation of AES.
111
- *
112
- * @author Jim Wigginton <terrafrost@php.net>
113
- * @version 0.1.0
114
- * @access public
115
- * @package Crypt_AES
116
- */
117
- class Crypt_AES extends Crypt_Rijndael {
118
- /**
119
- * mcrypt resource for encryption
120
- *
121
- * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
122
- * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
123
- *
124
- * @see Crypt_AES::encrypt()
125
- * @var String
126
- * @access private
127
- */
128
- var $enmcrypt;
129
-
130
- /**
131
- * mcrypt resource for decryption
132
- *
133
- * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
134
- * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
135
- *
136
- * @see Crypt_AES::decrypt()
137
- * @var String
138
- * @access private
139
- */
140
- var $demcrypt;
141
-
142
- /**
143
- * Default Constructor.
144
- *
145
- * Determines whether or not the mcrypt extension should be used. $mode should only, at present, be
146
- * CRYPT_AES_MODE_ECB or CRYPT_AES_MODE_CBC. If not explictly set, CRYPT_AES_MODE_CBC will be used.
147
- *
148
- * @param optional Integer $mode
149
- * @return Crypt_AES
150
- * @access public
151
- */
152
- function Crypt_AES($mode = CRYPT_AES_MODE_CBC)
153
- {
154
- if ( !defined('CRYPT_AES_MODE') ) {
155
- switch (true) {
156
- case extension_loaded('mcrypt'):
157
- // i'd check to see if aes was supported, by doing in_array('des', mcrypt_list_algorithms('')),
158
- // but since that can be changed after the object has been created, there doesn't seem to be
159
- // a lot of point...
160
- define('CRYPT_AES_MODE', CRYPT_AES_MODE_MCRYPT);
161
- break;
162
- default:
163
- define('CRYPT_AES_MODE', CRYPT_AES_MODE_INTERNAL);
164
- }
165
- }
166
-
167
- switch ( CRYPT_AES_MODE ) {
168
- case CRYPT_AES_MODE_MCRYPT:
169
- switch ($mode) {
170
- case CRYPT_AES_MODE_ECB:
171
- $this->mode = MCRYPT_MODE_ECB;
172
- break;
173
- case CRYPT_AES_MODE_CTR:
174
- // ctr doesn't have a constant associated with it even though it appears to be fairly widely
175
- // supported. in lieu of knowing just how widely supported it is, i've, for now, opted not to
176
- // include a compatibility layer. the layer has been implemented but, for now, is commented out.
177
- $this->mode = 'ctr';
178
- //$this->mode = in_array('ctr', mcrypt_list_modes()) ? 'ctr' : CRYPT_AES_MODE_CTR;
179
- break;
180
- case CRYPT_AES_MODE_CBC:
181
- default:
182
- $this->mode = MCRYPT_MODE_CBC;
183
- }
184
-
185
- break;
186
- default:
187
- switch ($mode) {
188
- case CRYPT_AES_MODE_ECB:
189
- $this->mode = CRYPT_RIJNDAEL_MODE_ECB;
190
- break;
191
- case CRYPT_AES_MODE_CTR:
192
- $this->mode = CRYPT_RIJNDAEL_MODE_CTR;
193
- break;
194
- case CRYPT_AES_MODE_CBC:
195
- default:
196
- $this->mode = CRYPT_RIJNDAEL_MODE_CBC;
197
- }
198
- }
199
-
200
- if (CRYPT_AES_MODE == CRYPT_AES_MODE_INTERNAL) {
201
- parent::Crypt_Rijndael($this->mode);
202
- }
203
- }
204
-
205
- /**
206
- * Dummy function
207
- *
208
- * Since Crypt_AES extends Crypt_Rijndael, this function is, technically, available, but it doesn't do anything.
209
- *
210
- * @access public
211
- * @param Integer $length
212
- */
213
- function setBlockLength($length)
214
- {
215
- return;
216
- }
217
-
218
- /**
219
- * Encrypts a message.
220
- *
221
- * $plaintext will be padded with up to 16 additional bytes. Other AES implementations may or may not pad in the
222
- * same manner. Other common approaches to padding and the reasons why it's necessary are discussed in the following
223
- * URL:
224
- *
225
- * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
226
- *
227
- * An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does.
228
- * strlen($plaintext) will still need to be a multiple of 16, however, arbitrary values can be added to make it that
229
- * length.
230
- *
231
- * @see Crypt_AES::decrypt()
232
- * @access public
233
- * @param String $plaintext
234
- */
235
- function encrypt($plaintext)
236
- {
237
- if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) {
238
- $this->_mcryptSetup();
239
- /*
240
- if ($this->mode == CRYPT_AES_MODE_CTR) {
241
- $iv = $this->encryptIV;
242
- $xor = mcrypt_generic($this->enmcrypt, $this->_generate_xor(strlen($plaintext), $iv));
243
- $ciphertext = $plaintext ^ $xor;
244
- if ($this->continuousBuffer) {
245
- $this->encryptIV = $iv;
246
- }
247
- return $ciphertext;
248
- }
249
- */
250
-
251
- if ($this->mode != 'ctr') {
252
- $plaintext = $this->_pad($plaintext);
253
- }
254
-
255
- $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
256
-
257
- if (!$this->continuousBuffer) {
258
- mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv);
259
- }
260
-
261
- return $ciphertext;
262
- }
263
-
264
- return parent::encrypt($plaintext);
265
- }
266
-
267
- /**
268
- * Decrypts a message.
269
- *
270
- * If strlen($ciphertext) is not a multiple of 16, null bytes will be added to the end of the string until it is.
271
- *
272
- * @see Crypt_AES::encrypt()
273
- * @access public
274
- * @param String $ciphertext
275
- */
276
- function decrypt($ciphertext)
277
- {
278
- if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) {
279
- $this->_mcryptSetup();
280
- /*
281
- if ($this->mode == CRYPT_AES_MODE_CTR) {
282
- $iv = $this->decryptIV;
283
- $xor = mcrypt_generic($this->enmcrypt, $this->_generate_xor(strlen($ciphertext), $iv));
284
- $plaintext = $ciphertext ^ $xor;
285
- if ($this->continuousBuffer) {
286
- $this->decryptIV = $iv;
287
- }
288
- return $plaintext;
289
- }
290
- */
291
-
292
- if ($this->mode != 'ctr') {
293
- // we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
294
- // "The data is padded with "\0" to make sure the length of the data is n * blocksize."
295
- $ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 15) & 0xFFFFFFF0, chr(0));
296
- }
297
-
298
- $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
299
-
300
- if (!$this->continuousBuffer) {
301
- mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);
302
- }
303
-
304
- return $this->mode != 'ctr' ? $this->_unpad($plaintext) : $plaintext;
305
- }
306
-
307
- return parent::decrypt($ciphertext);
308
- }
309
-
310
- /**
311
- * Setup mcrypt
312
- *
313
- * Validates all the variables.
314
- *
315
- * @access private
316
- */
317
- function _mcryptSetup()
318
- {
319
- if (!$this->changed) {
320
- return;
321
- }
322
-
323
- if (!$this->explicit_key_length) {
324
- // this just copied from Crypt_Rijndael::_setup()
325
- $length = strlen($this->key) >> 2;
326
- if ($length > 8) {
327
- $length = 8;
328
- } else if ($length < 4) {
329
- $length = 4;
330
- }
331
- $this->Nk = $length;
332
- $this->key_size = $length << 2;
333
- }
334
-
335
- switch ($this->Nk) {
336
- case 4: // 128
337
- $this->key_size = 16;
338
- break;
339
- case 5: // 160
340
- case 6: // 192
341
- $this->key_size = 24;
342
- break;
343
- case 7: // 224
344
- case 8: // 256
345
- $this->key_size = 32;
346
- }
347
-
348
- $this->key = substr($this->key, 0, $this->key_size);
349
- $this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($this->iv, 0, 16), 16, chr(0));
350
-
351
- if (!isset($this->enmcrypt)) {
352
- $mode = $this->mode;
353
- //$mode = $this->mode == CRYPT_AES_MODE_CTR ? MCRYPT_MODE_ECB : $this->mode;
354
-
355
- $this->demcrypt = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', $mode, '');
356
- $this->enmcrypt = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', $mode, '');
357
- } // else should mcrypt_generic_deinit be called?
358
-
359
- mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);
360
- mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv);
361
-
362
- $this->changed = false;
363
- }
364
-
365
- /**
366
- * Encrypts a block
367
- *
368
- * Optimized over Crypt_Rijndael's implementation by means of loop unrolling.
369
- *
370
- * @see Crypt_Rijndael::_encryptBlock()
371
- * @access private
372
- * @param String $in
373
- * @return String
374
- */
375
- function _encryptBlock($in)
376
- {
377
- $state = unpack('N*word', $in);
378
-
379
- $Nr = $this->Nr;
380
- $w = $this->w;
381
- $t0 = $this->t0;
382
- $t1 = $this->t1;
383
- $t2 = $this->t2;
384
- $t3 = $this->t3;
385
-
386
- // addRoundKey and reindex $state
387
- $state = array(
388
- $state['word1'] ^ $w[0][0],
389
- $state['word2'] ^ $w[0][1],
390
- $state['word3'] ^ $w[0][2],
391
- $state['word4'] ^ $w[0][3]
392
- );
393
-
394
- // shiftRows + subWord + mixColumns + addRoundKey
395
- // we could loop unroll this and use if statements to do more rounds as necessary, but, in my tests, that yields
396
- // only a marginal improvement. since that also, imho, hinders the readability of the code, i've opted not to do it.
397
- for ($round = 1; $round < $this->Nr; $round++) {
398
- $state = array(
399
- $t0[$state[0] & 0xFF000000] ^ $t1[$state[1] & 0x00FF0000] ^ $t2[$state[2] & 0x0000FF00] ^ $t3[$state[3] & 0x000000FF] ^ $w[$round][0],
400
- $t0[$state[1] & 0xFF000000] ^ $t1[$state[2] & 0x00FF0000] ^ $t2[$state[3] & 0x0000FF00] ^ $t3[$state[0] & 0x000000FF] ^ $w[$round][1],
401
- $t0[$state[2] & 0xFF000000] ^ $t1[$state[3] & 0x00FF0000] ^ $t2[$state[0] & 0x0000FF00] ^ $t3[$state[1] & 0x000000FF] ^ $w[$round][2],
402
- $t0[$state[3] & 0xFF000000] ^ $t1[$state[0] & 0x00FF0000] ^ $t2[$state[1] & 0x0000FF00] ^ $t3[$state[2] & 0x000000FF] ^ $w[$round][3]
403
- );
404
-
405
- }
406
-
407
- // subWord
408
- $state = array(
409
- $this->_subWord($state[0]),
410
- $this->_subWord($state[1]),
411
- $this->_subWord($state[2]),
412
- $this->_subWord($state[3])
413
- );
414
-
415
- // shiftRows + addRoundKey
416
- $state = array(
417
- ($state[0] & 0xFF000000) ^ ($state[1] & 0x00FF0000) ^ ($state[2] & 0x0000FF00) ^ ($state[3] & 0x000000FF) ^ $this->w[$this->Nr][0],
418
- ($state[1] & 0xFF000000) ^ ($state[2] & 0x00FF0000) ^ ($state[3] & 0x0000FF00) ^ ($state[0] & 0x000000FF) ^ $this->w[$this->Nr][1],
419
- ($state[2] & 0xFF000000) ^ ($state[3] & 0x00FF0000) ^ ($state[0] & 0x0000FF00) ^ ($state[1] & 0x000000FF) ^ $this->w[$this->Nr][2],
420
- ($state[3] & 0xFF000000) ^ ($state[0] & 0x00FF0000) ^ ($state[1] & 0x0000FF00) ^ ($state[2] & 0x000000FF) ^ $this->w[$this->Nr][3]
421
- );
422
-
423
- return pack('N*', $state[0], $state[1], $state[2], $state[3]);
424
- }
425
-
426
- /**
427
- * Decrypts a block
428
- *
429
- * Optimized over Crypt_Rijndael's implementation by means of loop unrolling.
430
- *
431
- * @see Crypt_Rijndael::_decryptBlock()
432
- * @access private
433
- * @param String $in
434
- * @return String
435
- */
436
- function _decryptBlock($in)
437
- {
438
- $state = unpack('N*word', $in);
439
-
440
- $Nr = $this->Nr;
441
- $dw = $this->dw;
442
- $dt0 = $this->dt0;
443
- $dt1 = $this->dt1;
444
- $dt2 = $this->dt2;
445
- $dt3 = $this->dt3;
446
-
447
- // addRoundKey and reindex $state
448
- $state = array(
449
- $state['word1'] ^ $dw[$this->Nr][0],
450
- $state['word2'] ^ $dw[$this->Nr][1],
451
- $state['word3'] ^ $dw[$this->Nr][2],
452
- $state['word4'] ^ $dw[$this->Nr][3]
453
- );
454
-
455
-
456
- // invShiftRows + invSubBytes + invMixColumns + addRoundKey
457
- for ($round = $this->Nr - 1; $round > 0; $round--) {
458
- $state = array(
459
- $dt0[$state[0] & 0xFF000000] ^ $dt1[$state[3] & 0x00FF0000] ^ $dt2[$state[2] & 0x0000FF00] ^ $dt3[$state[1] & 0x000000FF] ^ $dw[$round][0],
460
- $dt0[$state[1] & 0xFF000000] ^ $dt1[$state[0] & 0x00FF0000] ^ $dt2[$state[3] & 0x0000FF00] ^ $dt3[$state[2] & 0x000000FF] ^ $dw[$round][1],
461
- $dt0[$state[2] & 0xFF000000] ^ $dt1[$state[1] & 0x00FF0000] ^ $dt2[$state[0] & 0x0000FF00] ^ $dt3[$state[3] & 0x000000FF] ^ $dw[$round][2],
462
- $dt0[$state[3] & 0xFF000000] ^ $dt1[$state[2] & 0x00FF0000] ^ $dt2[$state[1] & 0x0000FF00] ^ $dt3[$state[0] & 0x000000FF] ^ $dw[$round][3]
463
- );
464
- }
465
-
466
- // invShiftRows + invSubWord + addRoundKey
467
- $state = array(
468
- $this->_invSubWord(($state[0] & 0xFF000000) ^ ($state[3] & 0x00FF0000) ^ ($state[2] & 0x0000FF00) ^ ($state[1] & 0x000000FF)) ^ $dw[0][0],
469
- $this->_invSubWord(($state[1] & 0xFF000000) ^ ($state[0] & 0x00FF0000) ^ ($state[3] & 0x0000FF00) ^ ($state[2] & 0x000000FF)) ^ $dw[0][1],
470
- $this->_invSubWord(($state[2] & 0xFF000000) ^ ($state[1] & 0x00FF0000) ^ ($state[0] & 0x0000FF00) ^ ($state[3] & 0x000000FF)) ^ $dw[0][2],
471
- $this->_invSubWord(($state[3] & 0xFF000000) ^ ($state[2] & 0x00FF0000) ^ ($state[1] & 0x0000FF00) ^ ($state[0] & 0x000000FF)) ^ $dw[0][3]
472
- );
473
-
474
- return pack('N*', $state[0], $state[1], $state[2], $state[3]);
475
- }
476
- }
477
-
478
- // vim: ts=4:sw=4:et:
479
- // vim6: fdl=1:
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * Pure-PHP implementation of AES.
6
+ *
7
+ * Uses mcrypt, if available, and an internal implementation, otherwise.
8
+ *
9
+ * PHP versions 4 and 5
10
+ *
11
+ * If {@link Crypt_AES::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
12
+ * {@link Crypt_AES::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's 136-bits
13
+ * it'll be null-padded to 160-bits and 160 bits will be the key length until {@link Crypt_Rijndael::setKey() setKey()}
14
+ * is called, again, at which point, it'll be recalculated.
15
+ *
16
+ * Since Crypt_AES extends Crypt_Rijndael, some functions are available to be called that, in the context of AES, don't
17
+ * make a whole lot of sense. {@link Crypt_AES::setBlockLength() setBlockLength()}, for instance. Calling that function,
18
+ * however possible, won't do anything (AES has a fixed block length whereas Rijndael has a variable one).
19
+ *
20
+ * Here's a short example of how to use this library:
21
+ * <code>
22
+ * <?php
23
+ * include('Crypt/AES.php');
24
+ *
25
+ * $aes = new Crypt_AES();
26
+ *
27
+ * $aes->setKey('abcdefghijklmnop');
28
+ *
29
+ * $size = 10 * 1024;
30
+ * $plaintext = '';
31
+ * for ($i = 0; $i < $size; $i++) {
32
+ * $plaintext.= 'a';
33
+ * }
34
+ *
35
+ * echo $aes->decrypt($aes->encrypt($plaintext));
36
+ * ?>
37
+ * </code>
38
+ *
39
+ * LICENSE: This library is free software; you can redistribute it and/or
40
+ * modify it under the terms of the GNU Lesser General Public
41
+ * License as published by the Free Software Foundation; either
42
+ * version 2.1 of the License, or (at your option) any later version.
43
+ *
44
+ * This library is distributed in the hope that it will be useful,
45
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
46
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
47
+ * Lesser General Public License for more details.
48
+ *
49
+ * You should have received a copy of the GNU Lesser General Public
50
+ * License along with this library; if not, write to the Free Software
51
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
52
+ * MA 02111-1307 USA
53
+ *
54
+ * @category Crypt
55
+ * @package Crypt_AES
56
+ * @author Jim Wigginton <terrafrost@php.net>
57
+ * @copyright MMVIII Jim Wigginton
58
+ * @license http://www.gnu.org/licenses/lgpl.txt
59
+ * @version $Id: AES.php,v 1.7 2010/02/09 06:10:25 terrafrost Exp $
60
+ * @link http://phpseclib.sourceforge.net
61
+ */
62
+
63
+ /**
64
+ * Include Crypt_Rijndael
65
+ */
66
+ require_once 'Rijndael.php';
67
+
68
+ /**#@+
69
+ * @access public
70
+ * @see Crypt_AES::encrypt()
71
+ * @see Crypt_AES::decrypt()
72
+ */
73
+ /**
74
+ * Encrypt / decrypt using the Counter mode.
75
+ *
76
+ * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
77
+ *
78
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
79
+ */
80
+ define('CRYPT_AES_MODE_CTR', -1);
81
+ /**
82
+ * Encrypt / decrypt using the Electronic Code Book mode.
83
+ *
84
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
85
+ */
86
+ define('CRYPT_AES_MODE_ECB', 1);
87
+ /**
88
+ * Encrypt / decrypt using the Code Book Chaining mode.
89
+ *
90
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
91
+ */
92
+ define('CRYPT_AES_MODE_CBC', 2);
93
+ /**#@-*/
94
+
95
+ /**#@+
96
+ * @access private
97
+ * @see Crypt_AES::Crypt_AES()
98
+ */
99
+ /**
100
+ * Toggles the internal implementation
101
+ */
102
+ define('CRYPT_AES_MODE_INTERNAL', 1);
103
+ /**
104
+ * Toggles the mcrypt implementation
105
+ */
106
+ define('CRYPT_AES_MODE_MCRYPT', 2);
107
+ /**#@-*/
108
+
109
+ /**
110
+ * Pure-PHP implementation of AES.
111
+ *
112
+ * @author Jim Wigginton <terrafrost@php.net>
113
+ * @version 0.1.0
114
+ * @access public
115
+ * @package Crypt_AES
116
+ */
117
+ class Crypt_AES extends Crypt_Rijndael {
118
+ /**
119
+ * mcrypt resource for encryption
120
+ *
121
+ * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
122
+ * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
123
+ *
124
+ * @see Crypt_AES::encrypt()
125
+ * @var String
126
+ * @access private
127
+ */
128
+ var $enmcrypt;
129
+
130
+ /**
131
+ * mcrypt resource for decryption
132
+ *
133
+ * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
134
+ * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
135
+ *
136
+ * @see Crypt_AES::decrypt()
137
+ * @var String
138
+ * @access private
139
+ */
140
+ var $demcrypt;
141
+
142
+ /**
143
+ * Default Constructor.
144
+ *
145
+ * Determines whether or not the mcrypt extension should be used. $mode should only, at present, be
146
+ * CRYPT_AES_MODE_ECB or CRYPT_AES_MODE_CBC. If not explictly set, CRYPT_AES_MODE_CBC will be used.
147
+ *
148
+ * @param optional Integer $mode
149
+ * @return Crypt_AES
150
+ * @access public
151
+ */
152
+ function Crypt_AES($mode = CRYPT_AES_MODE_CBC)
153
+ {
154
+ if ( !defined('CRYPT_AES_MODE') ) {
155
+ switch (true) {
156
+ case extension_loaded('mcrypt'):
157
+ // i'd check to see if aes was supported, by doing in_array('des', mcrypt_list_algorithms('')),
158
+ // but since that can be changed after the object has been created, there doesn't seem to be
159
+ // a lot of point...
160
+ define('CRYPT_AES_MODE', CRYPT_AES_MODE_MCRYPT);
161
+ break;
162
+ default:
163
+ define('CRYPT_AES_MODE', CRYPT_AES_MODE_INTERNAL);
164
+ }
165
+ }
166
+
167
+ switch ( CRYPT_AES_MODE ) {
168
+ case CRYPT_AES_MODE_MCRYPT:
169
+ switch ($mode) {
170
+ case CRYPT_AES_MODE_ECB:
171
+ $this->mode = MCRYPT_MODE_ECB;
172
+ break;
173
+ case CRYPT_AES_MODE_CTR:
174
+ // ctr doesn't have a constant associated with it even though it appears to be fairly widely
175
+ // supported. in lieu of knowing just how widely supported it is, i've, for now, opted not to
176
+ // include a compatibility layer. the layer has been implemented but, for now, is commented out.
177
+ $this->mode = 'ctr';
178
+ //$this->mode = in_array('ctr', mcrypt_list_modes()) ? 'ctr' : CRYPT_AES_MODE_CTR;
179
+ break;
180
+ case CRYPT_AES_MODE_CBC:
181
+ default:
182
+ $this->mode = MCRYPT_MODE_CBC;
183
+ }
184
+
185
+ break;
186
+ default:
187
+ switch ($mode) {
188
+ case CRYPT_AES_MODE_ECB:
189
+ $this->mode = CRYPT_RIJNDAEL_MODE_ECB;
190
+ break;
191
+ case CRYPT_AES_MODE_CTR:
192
+ $this->mode = CRYPT_RIJNDAEL_MODE_CTR;
193
+ break;
194
+ case CRYPT_AES_MODE_CBC:
195
+ default:
196
+ $this->mode = CRYPT_RIJNDAEL_MODE_CBC;
197
+ }
198
+ }
199
+
200
+ if (CRYPT_AES_MODE == CRYPT_AES_MODE_INTERNAL) {
201
+ parent::Crypt_Rijndael($this->mode);
202
+ }
203
+ }
204
+
205
+ /**
206
+ * Dummy function
207
+ *
208
+ * Since Crypt_AES extends Crypt_Rijndael, this function is, technically, available, but it doesn't do anything.
209
+ *
210
+ * @access public
211
+ * @param Integer $length
212
+ */
213
+ function setBlockLength($length)
214
+ {
215
+ return;
216
+ }
217
+
218
+ /**
219
+ * Encrypts a message.
220
+ *
221
+ * $plaintext will be padded with up to 16 additional bytes. Other AES implementations may or may not pad in the
222
+ * same manner. Other common approaches to padding and the reasons why it's necessary are discussed in the following
223
+ * URL:
224
+ *
225
+ * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
226
+ *
227
+ * An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does.
228
+ * strlen($plaintext) will still need to be a multiple of 16, however, arbitrary values can be added to make it that
229
+ * length.
230
+ *
231
+ * @see Crypt_AES::decrypt()
232
+ * @access public
233
+ * @param String $plaintext
234
+ */
235
+ function encrypt($plaintext)
236
+ {
237
+ if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) {
238
+ $this->_mcryptSetup();
239
+ /*
240
+ if ($this->mode == CRYPT_AES_MODE_CTR) {
241
+ $iv = $this->encryptIV;
242
+ $xor = mcrypt_generic($this->enmcrypt, $this->_generate_xor(strlen($plaintext), $iv));
243
+ $ciphertext = $plaintext ^ $xor;
244
+ if ($this->continuousBuffer) {
245
+ $this->encryptIV = $iv;
246
+ }
247
+ return $ciphertext;
248
+ }
249
+ */
250
+
251
+ if ($this->mode != 'ctr') {
252
+ $plaintext = $this->_pad($plaintext);
253
+ }
254
+
255
+ $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
256
+
257
+ if (!$this->continuousBuffer) {
258
+ mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv);
259
+ }
260
+
261
+ return $ciphertext;
262
+ }
263
+
264
+ return parent::encrypt($plaintext);
265
+ }
266
+
267
+ /**
268
+ * Decrypts a message.
269
+ *
270
+ * If strlen($ciphertext) is not a multiple of 16, null bytes will be added to the end of the string until it is.
271
+ *
272
+ * @see Crypt_AES::encrypt()
273
+ * @access public
274
+ * @param String $ciphertext
275
+ */
276
+ function decrypt($ciphertext)
277
+ {
278
+ if ( CRYPT_AES_MODE == CRYPT_AES_MODE_MCRYPT ) {
279
+ $this->_mcryptSetup();
280
+ /*
281
+ if ($this->mode == CRYPT_AES_MODE_CTR) {
282
+ $iv = $this->decryptIV;
283
+ $xor = mcrypt_generic($this->enmcrypt, $this->_generate_xor(strlen($ciphertext), $iv));
284
+ $plaintext = $ciphertext ^ $xor;
285
+ if ($this->continuousBuffer) {
286
+ $this->decryptIV = $iv;
287
+ }
288
+ return $plaintext;
289
+ }
290
+ */
291
+
292
+ if ($this->mode != 'ctr') {
293
+ // we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
294
+ // "The data is padded with "\0" to make sure the length of the data is n * blocksize."
295
+ $ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 15) & 0xFFFFFFF0, chr(0));
296
+ }
297
+
298
+ $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
299
+
300
+ if (!$this->continuousBuffer) {
301
+ mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);
302
+ }
303
+
304
+ return $this->mode != 'ctr' ? $this->_unpad($plaintext) : $plaintext;
305
+ }
306
+
307
+ return parent::decrypt($ciphertext);
308
+ }
309
+
310
+ /**
311
+ * Setup mcrypt
312
+ *
313
+ * Validates all the variables.
314
+ *
315
+ * @access private
316
+ */
317
+ function _mcryptSetup()
318
+ {
319
+ if (!$this->changed) {
320
+ return;
321
+ }
322
+
323
+ if (!$this->explicit_key_length) {
324
+ // this just copied from Crypt_Rijndael::_setup()
325
+ $length = strlen($this->key) >> 2;
326
+ if ($length > 8) {
327
+ $length = 8;
328
+ } else if ($length < 4) {
329
+ $length = 4;
330
+ }
331
+ $this->Nk = $length;
332
+ $this->key_size = $length << 2;
333
+ }
334
+
335
+ switch ($this->Nk) {
336
+ case 4: // 128
337
+ $this->key_size = 16;
338
+ break;
339
+ case 5: // 160
340
+ case 6: // 192
341
+ $this->key_size = 24;
342
+ break;
343
+ case 7: // 224
344
+ case 8: // 256
345
+ $this->key_size = 32;
346
+ }
347
+
348
+ $this->key = substr($this->key, 0, $this->key_size);
349
+ $this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($this->iv, 0, 16), 16, chr(0));
350
+
351
+ if (!isset($this->enmcrypt)) {
352
+ $mode = $this->mode;
353
+ //$mode = $this->mode == CRYPT_AES_MODE_CTR ? MCRYPT_MODE_ECB : $this->mode;
354
+
355
+ $this->demcrypt = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', $mode, '');
356
+ $this->enmcrypt = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', $mode, '');
357
+ } // else should mcrypt_generic_deinit be called?
358
+
359
+ mcrypt_generic_init($this->demcrypt, $this->key, $this->iv);
360
+ mcrypt_generic_init($this->enmcrypt, $this->key, $this->iv);
361
+
362
+ $this->changed = false;
363
+ }
364
+
365
+ /**
366
+ * Encrypts a block
367
+ *
368
+ * Optimized over Crypt_Rijndael's implementation by means of loop unrolling.
369
+ *
370
+ * @see Crypt_Rijndael::_encryptBlock()
371
+ * @access private
372
+ * @param String $in
373
+ * @return String
374
+ */
375
+ function _encryptBlock($in)
376
+ {
377
+ $state = unpack('N*word', $in);
378
+
379
+ $Nr = $this->Nr;
380
+ $w = $this->w;
381
+ $t0 = $this->t0;
382
+ $t1 = $this->t1;
383
+ $t2 = $this->t2;
384
+ $t3 = $this->t3;
385
+
386
+ // addRoundKey and reindex $state
387
+ $state = array(
388
+ $state['word1'] ^ $w[0][0],
389
+ $state['word2'] ^ $w[0][1],
390
+ $state['word3'] ^ $w[0][2],
391
+ $state['word4'] ^ $w[0][3]
392
+ );
393
+
394
+ // shiftRows + subWord + mixColumns + addRoundKey
395
+ // we could loop unroll this and use if statements to do more rounds as necessary, but, in my tests, that yields
396
+ // only a marginal improvement. since that also, imho, hinders the readability of the code, i've opted not to do it.
397
+ for ($round = 1; $round < $this->Nr; $round++) {
398
+ $state = array(
399
+ $t0[$state[0] & 0xFF000000] ^ $t1[$state[1] & 0x00FF0000] ^ $t2[$state[2] & 0x0000FF00] ^ $t3[$state[3] & 0x000000FF] ^ $w[$round][0],
400
+ $t0[$state[1] & 0xFF000000] ^ $t1[$state[2] & 0x00FF0000] ^ $t2[$state[3] & 0x0000FF00] ^ $t3[$state[0] & 0x000000FF] ^ $w[$round][1],
401
+ $t0[$state[2] & 0xFF000000] ^ $t1[$state[3] & 0x00FF0000] ^ $t2[$state[0] & 0x0000FF00] ^ $t3[$state[1] & 0x000000FF] ^ $w[$round][2],
402
+ $t0[$state[3] & 0xFF000000] ^ $t1[$state[0] & 0x00FF0000] ^ $t2[$state[1] & 0x0000FF00] ^ $t3[$state[2] & 0x000000FF] ^ $w[$round][3]
403
+ );
404
+
405
+ }
406
+
407
+ // subWord
408
+ $state = array(
409
+ $this->_subWord($state[0]),
410
+ $this->_subWord($state[1]),
411
+ $this->_subWord($state[2]),
412
+ $this->_subWord($state[3])
413
+ );
414
+
415
+ // shiftRows + addRoundKey
416
+ $state = array(
417
+ ($state[0] & 0xFF000000) ^ ($state[1] & 0x00FF0000) ^ ($state[2] & 0x0000FF00) ^ ($state[3] & 0x000000FF) ^ $this->w[$this->Nr][0],
418
+ ($state[1] & 0xFF000000) ^ ($state[2] & 0x00FF0000) ^ ($state[3] & 0x0000FF00) ^ ($state[0] & 0x000000FF) ^ $this->w[$this->Nr][1],
419
+ ($state[2] & 0xFF000000) ^ ($state[3] & 0x00FF0000) ^ ($state[0] & 0x0000FF00) ^ ($state[1] & 0x000000FF) ^ $this->w[$this->Nr][2],
420
+ ($state[3] & 0xFF000000) ^ ($state[0] & 0x00FF0000) ^ ($state[1] & 0x0000FF00) ^ ($state[2] & 0x000000FF) ^ $this->w[$this->Nr][3]
421
+ );
422
+
423
+ return pack('N*', $state[0], $state[1], $state[2], $state[3]);
424
+ }
425
+
426
+ /**
427
+ * Decrypts a block
428
+ *
429
+ * Optimized over Crypt_Rijndael's implementation by means of loop unrolling.
430
+ *
431
+ * @see Crypt_Rijndael::_decryptBlock()
432
+ * @access private
433
+ * @param String $in
434
+ * @return String
435
+ */
436
+ function _decryptBlock($in)
437
+ {
438
+ $state = unpack('N*word', $in);
439
+
440
+ $Nr = $this->Nr;
441
+ $dw = $this->dw;
442
+ $dt0 = $this->dt0;
443
+ $dt1 = $this->dt1;
444
+ $dt2 = $this->dt2;
445
+ $dt3 = $this->dt3;
446
+
447
+ // addRoundKey and reindex $state
448
+ $state = array(
449
+ $state['word1'] ^ $dw[$this->Nr][0],
450
+ $state['word2'] ^ $dw[$this->Nr][1],
451
+ $state['word3'] ^ $dw[$this->Nr][2],
452
+ $state['word4'] ^ $dw[$this->Nr][3]
453
+ );
454
+
455
+
456
+ // invShiftRows + invSubBytes + invMixColumns + addRoundKey
457
+ for ($round = $this->Nr - 1; $round > 0; $round--) {
458
+ $state = array(
459
+ $dt0[$state[0] & 0xFF000000] ^ $dt1[$state[3] & 0x00FF0000] ^ $dt2[$state[2] & 0x0000FF00] ^ $dt3[$state[1] & 0x000000FF] ^ $dw[$round][0],
460
+ $dt0[$state[1] & 0xFF000000] ^ $dt1[$state[0] & 0x00FF0000] ^ $dt2[$state[3] & 0x0000FF00] ^ $dt3[$state[2] & 0x000000FF] ^ $dw[$round][1],
461
+ $dt0[$state[2] & 0xFF000000] ^ $dt1[$state[1] & 0x00FF0000] ^ $dt2[$state[0] & 0x0000FF00] ^ $dt3[$state[3] & 0x000000FF] ^ $dw[$round][2],
462
+ $dt0[$state[3] & 0xFF000000] ^ $dt1[$state[2] & 0x00FF0000] ^ $dt2[$state[1] & 0x0000FF00] ^ $dt3[$state[0] & 0x000000FF] ^ $dw[$round][3]
463
+ );
464
+ }
465
+
466
+ // invShiftRows + invSubWord + addRoundKey
467
+ $state = array(
468
+ $this->_invSubWord(($state[0] & 0xFF000000) ^ ($state[3] & 0x00FF0000) ^ ($state[2] & 0x0000FF00) ^ ($state[1] & 0x000000FF)) ^ $dw[0][0],
469
+ $this->_invSubWord(($state[1] & 0xFF000000) ^ ($state[0] & 0x00FF0000) ^ ($state[3] & 0x0000FF00) ^ ($state[2] & 0x000000FF)) ^ $dw[0][1],
470
+ $this->_invSubWord(($state[2] & 0xFF000000) ^ ($state[1] & 0x00FF0000) ^ ($state[0] & 0x0000FF00) ^ ($state[3] & 0x000000FF)) ^ $dw[0][2],
471
+ $this->_invSubWord(($state[3] & 0xFF000000) ^ ($state[2] & 0x00FF0000) ^ ($state[1] & 0x0000FF00) ^ ($state[0] & 0x000000FF)) ^ $dw[0][3]
472
+ );
473
+
474
+ return pack('N*', $state[0], $state[1], $state[2], $state[3]);
475
+ }
476
+ }
477
+
478
+ // vim: ts=4:sw=4:et:
479
+ // vim6: fdl=1:
app/code/local/Wisepricer/Syncer/lib/phpseclib/Crypt/DES.php CHANGED
@@ -1,945 +1,945 @@
1
- <?php
2
- /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
-
4
- /**
5
- * Pure-PHP implementation of DES.
6
- *
7
- * Uses mcrypt, if available, and an internal implementation, otherwise.
8
- *
9
- * PHP versions 4 and 5
10
- *
11
- * Useful resources are as follows:
12
- *
13
- * - {@link http://en.wikipedia.org/wiki/DES_supplementary_material Wikipedia: DES supplementary material}
14
- * - {@link http://www.itl.nist.gov/fipspubs/fip46-2.htm FIPS 46-2 - (DES), Data Encryption Standard}
15
- * - {@link http://www.cs.eku.edu/faculty/styer/460/Encrypt/JS-DES.html JavaScript DES Example}
16
- *
17
- * Here's a short example of how to use this library:
18
- * <code>
19
- * <?php
20
- * include('Crypt/DES.php');
21
- *
22
- * $des = new Crypt_DES();
23
- *
24
- * $des->setKey('abcdefgh');
25
- *
26
- * $size = 10 * 1024;
27
- * $plaintext = '';
28
- * for ($i = 0; $i < $size; $i++) {
29
- * $plaintext.= 'a';
30
- * }
31
- *
32
- * echo $des->decrypt($des->encrypt($plaintext));
33
- * ?>
34
- * </code>
35
- *
36
- * LICENSE: This library is free software; you can redistribute it and/or
37
- * modify it under the terms of the GNU Lesser General Public
38
- * License as published by the Free Software Foundation; either
39
- * version 2.1 of the License, or (at your option) any later version.
40
- *
41
- * This library is distributed in the hope that it will be useful,
42
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
43
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
44
- * Lesser General Public License for more details.
45
- *
46
- * You should have received a copy of the GNU Lesser General Public
47
- * License along with this library; if not, write to the Free Software
48
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
49
- * MA 02111-1307 USA
50
- *
51
- * @category Crypt
52
- * @package Crypt_DES
53
- * @author Jim Wigginton <terrafrost@php.net>
54
- * @copyright MMVII Jim Wigginton
55
- * @license http://www.gnu.org/licenses/lgpl.txt
56
- * @version $Id: DES.php,v 1.12 2010/02/09 06:10:26 terrafrost Exp $
57
- * @link http://phpseclib.sourceforge.net
58
- */
59
-
60
- /**#@+
61
- * @access private
62
- * @see Crypt_DES::_prepareKey()
63
- * @see Crypt_DES::_processBlock()
64
- */
65
- /**
66
- * Contains array_reverse($keys[CRYPT_DES_DECRYPT])
67
- */
68
- define('CRYPT_DES_ENCRYPT', 0);
69
- /**
70
- * Contains array_reverse($keys[CRYPT_DES_ENCRYPT])
71
- */
72
- define('CRYPT_DES_DECRYPT', 1);
73
- /**#@-*/
74
-
75
- /**#@+
76
- * @access public
77
- * @see Crypt_DES::encrypt()
78
- * @see Crypt_DES::decrypt()
79
- */
80
- /**
81
- * Encrypt / decrypt using the Counter mode.
82
- *
83
- * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
84
- *
85
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
86
- */
87
- define('CRYPT_DES_MODE_CTR', -1);
88
- /**
89
- * Encrypt / decrypt using the Electronic Code Book mode.
90
- *
91
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
92
- */
93
- define('CRYPT_DES_MODE_ECB', 1);
94
- /**
95
- * Encrypt / decrypt using the Code Book Chaining mode.
96
- *
97
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
98
- */
99
- define('CRYPT_DES_MODE_CBC', 2);
100
- /**#@-*/
101
-
102
- /**#@+
103
- * @access private
104
- * @see Crypt_DES::Crypt_DES()
105
- */
106
- /**
107
- * Toggles the internal implementation
108
- */
109
- define('CRYPT_DES_MODE_INTERNAL', 1);
110
- /**
111
- * Toggles the mcrypt implementation
112
- */
113
- define('CRYPT_DES_MODE_MCRYPT', 2);
114
- /**#@-*/
115
-
116
- /**
117
- * Pure-PHP implementation of DES.
118
- *
119
- * @author Jim Wigginton <terrafrost@php.net>
120
- * @version 0.1.0
121
- * @access public
122
- * @package Crypt_DES
123
- */
124
- class Crypt_DES {
125
- /**
126
- * The Key Schedule
127
- *
128
- * @see Crypt_DES::setKey()
129
- * @var Array
130
- * @access private
131
- */
132
- var $keys = "\0\0\0\0\0\0\0\0";
133
-
134
- /**
135
- * The Encryption Mode
136
- *
137
- * @see Crypt_DES::Crypt_DES()
138
- * @var Integer
139
- * @access private
140
- */
141
- var $mode;
142
-
143
- /**
144
- * Continuous Buffer status
145
- *
146
- * @see Crypt_DES::enableContinuousBuffer()
147
- * @var Boolean
148
- * @access private
149
- */
150
- var $continuousBuffer = false;
151
-
152
- /**
153
- * Padding status
154
- *
155
- * @see Crypt_DES::enablePadding()
156
- * @var Boolean
157
- * @access private
158
- */
159
- var $padding = true;
160
-
161
- /**
162
- * The Initialization Vector
163
- *
164
- * @see Crypt_DES::setIV()
165
- * @var String
166
- * @access private
167
- */
168
- var $iv = "\0\0\0\0\0\0\0\0";
169
-
170
- /**
171
- * A "sliding" Initialization Vector
172
- *
173
- * @see Crypt_DES::enableContinuousBuffer()
174
- * @var String
175
- * @access private
176
- */
177
- var $encryptIV = "\0\0\0\0\0\0\0\0";
178
-
179
- /**
180
- * A "sliding" Initialization Vector
181
- *
182
- * @see Crypt_DES::enableContinuousBuffer()
183
- * @var String
184
- * @access private
185
- */
186
- var $decryptIV = "\0\0\0\0\0\0\0\0";
187
-
188
- /**
189
- * mcrypt resource for encryption
190
- *
191
- * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
192
- * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
193
- *
194
- * @see Crypt_AES::encrypt()
195
- * @var String
196
- * @access private
197
- */
198
- var $enmcrypt;
199
-
200
- /**
201
- * mcrypt resource for decryption
202
- *
203
- * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
204
- * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
205
- *
206
- * @see Crypt_AES::decrypt()
207
- * @var String
208
- * @access private
209
- */
210
- var $demcrypt;
211
-
212
- /**
213
- * Does the (en|de)mcrypt resource need to be (re)initialized?
214
- *
215
- * @see setKey()
216
- * @see setIV()
217
- * @var Boolean
218
- * @access private
219
- */
220
- var $changed = true;
221
-
222
- /**
223
- * Default Constructor.
224
- *
225
- * Determines whether or not the mcrypt extension should be used. $mode should only, at present, be
226
- * CRYPT_DES_MODE_ECB or CRYPT_DES_MODE_CBC. If not explictly set, CRYPT_DES_MODE_CBC will be used.
227
- *
228
- * @param optional Integer $mode
229
- * @return Crypt_DES
230
- * @access public
231
- */
232
- function Crypt_DES($mode = CRYPT_MODE_DES_CBC)
233
- {
234
- if ( !defined('CRYPT_DES_MODE') ) {
235
- switch (true) {
236
- case extension_loaded('mcrypt'):
237
- // i'd check to see if des was supported, by doing in_array('des', mcrypt_list_algorithms('')),
238
- // but since that can be changed after the object has been created, there doesn't seem to be
239
- // a lot of point...
240
- define('CRYPT_DES_MODE', CRYPT_DES_MODE_MCRYPT);
241
- break;
242
- default:
243
- define('CRYPT_DES_MODE', CRYPT_DES_MODE_INTERNAL);
244
- }
245
- }
246
-
247
- switch ( CRYPT_DES_MODE ) {
248
- case CRYPT_DES_MODE_MCRYPT:
249
- switch ($mode) {
250
- case CRYPT_DES_MODE_ECB:
251
- $this->mode = MCRYPT_MODE_ECB;
252
- break;
253
- case CRYPT_DES_MODE_CTR:
254
- $this->mode = 'ctr';
255
- //$this->mode = in_array('ctr', mcrypt_list_modes()) ? 'ctr' : CRYPT_DES_MODE_CTR;
256
- break;
257
- case CRYPT_DES_MODE_CBC:
258
- default:
259
- $this->mode = MCRYPT_MODE_CBC;
260
- }
261
-
262
- break;
263
- default:
264
- switch ($mode) {
265
- case CRYPT_DES_MODE_ECB:
266
- case CRYPT_DES_MODE_CTR:
267
- case CRYPT_DES_MODE_CBC:
268
- $this->mode = $mode;
269
- break;
270
- default:
271
- $this->mode = CRYPT_DES_MODE_CBC;
272
- }
273
- }
274
- }
275
-
276
- /**
277
- * Sets the key.
278
- *
279
- * Keys can be of any length. DES, itself, uses 64-bit keys (eg. strlen($key) == 8), however, we
280
- * only use the first eight, if $key has more then eight characters in it, and pad $key with the
281
- * null byte if it is less then eight characters long.
282
- *
283
- * DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
284
- *
285
- * If the key is not explicitly set, it'll be assumed to be all zero's.
286
- *
287
- * @access public
288
- * @param String $key
289
- */
290
- function setKey($key)
291
- {
292
- $this->keys = ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) ? substr($key, 0, 8) : $this->_prepareKey($key);
293
- $this->changed = true;
294
- }
295
-
296
- /**
297
- * Sets the initialization vector. (optional)
298
- *
299
- * SetIV is not required when CRYPT_DES_MODE_ECB is being used. If not explictly set, it'll be assumed
300
- * to be all zero's.
301
- *
302
- * @access public
303
- * @param String $iv
304
- */
305
- function setIV($iv)
306
- {
307
- $this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($iv, 0, 8), 8, chr(0));
308
- $this->changed = true;
309
- }
310
-
311
- /**
312
- * Generate CTR XOR encryption key
313
- *
314
- * Encrypt the output of this and XOR it against the ciphertext / plaintext to get the
315
- * plaintext / ciphertext in CTR mode.
316
- *
317
- * @see Crypt_DES::decrypt()
318
- * @see Crypt_DES::encrypt()
319
- * @access public
320
- * @param Integer $length
321
- * @param String $iv
322
- */
323
- function _generate_xor($length, &$iv)
324
- {
325
- $xor = '';
326
- $num_blocks = ($length + 7) >> 3;
327
- for ($i = 0; $i < $num_blocks; $i++) {
328
- $xor.= $iv;
329
- for ($j = 4; $j <= 8; $j+=4) {
330
- $temp = substr($iv, -$j, 4);
331
- switch ($temp) {
332
- case "\xFF\xFF\xFF\xFF":
333
- $iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4);
334
- break;
335
- case "\x7F\xFF\xFF\xFF":
336
- $iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4);
337
- break 2;
338
- default:
339
- extract(unpack('Ncount', $temp));
340
- $iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);
341
- break 2;
342
- }
343
- }
344
- }
345
-
346
- return $xor;
347
- }
348
-
349
- /**
350
- * Encrypts a message.
351
- *
352
- * $plaintext will be padded with up to 8 additional bytes. Other DES implementations may or may not pad in the
353
- * same manner. Other common approaches to padding and the reasons why it's necessary are discussed in the following
354
- * URL:
355
- *
356
- * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
357
- *
358
- * An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does.
359
- * strlen($plaintext) will still need to be a multiple of 8, however, arbitrary values can be added to make it that
360
- * length.
361
- *
362
- * @see Crypt_DES::decrypt()
363
- * @access public
364
- * @param String $plaintext
365
- */
366
- function encrypt($plaintext)
367
- {
368
- if ($this->mode != CRYPT_DES_MODE_CTR && $this->mode != 'ctr') {
369
- $plaintext = $this->_pad($plaintext);
370
- }
371
-
372
- if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
373
- if ($this->changed) {
374
- if (!isset($this->enmcrypt)) {
375
- $this->enmcrypt = mcrypt_module_open(MCRYPT_DES, '', $this->mode, '');
376
- }
377
- mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);
378
- $this->changed = false;
379
- }
380
-
381
- $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
382
-
383
- if (!$this->continuousBuffer) {
384
- mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);
385
- }
386
-
387
- return $ciphertext;
388
- }
389
-
390
- if (!is_array($this->keys)) {
391
- $this->keys = $this->_prepareKey("\0\0\0\0\0\0\0\0");
392
- }
393
-
394
- $ciphertext = '';
395
- switch ($this->mode) {
396
- case CRYPT_DES_MODE_ECB:
397
- for ($i = 0; $i < strlen($plaintext); $i+=8) {
398
- $ciphertext.= $this->_processBlock(substr($plaintext, $i, 8), CRYPT_DES_ENCRYPT);
399
- }
400
- break;
401
- case CRYPT_DES_MODE_CBC:
402
- $xor = $this->encryptIV;
403
- for ($i = 0; $i < strlen($plaintext); $i+=8) {
404
- $block = substr($plaintext, $i, 8);
405
- $block = $this->_processBlock($block ^ $xor, CRYPT_DES_ENCRYPT);
406
- $xor = $block;
407
- $ciphertext.= $block;
408
- }
409
- if ($this->continuousBuffer) {
410
- $this->encryptIV = $xor;
411
- }
412
- break;
413
- case CRYPT_DES_MODE_CTR:
414
- $xor = $this->encryptIV;
415
- for ($i = 0; $i < strlen($plaintext); $i+=8) {
416
- $block = substr($plaintext, $i, 8);
417
- $key = $this->_processBlock($this->_generate_xor(8, $xor), CRYPT_DES_ENCRYPT);
418
- $ciphertext.= $block ^ $key;
419
- }
420
- if ($this->continuousBuffer) {
421
- $this->encryptIV = $xor;
422
- }
423
- }
424
-
425
- return $ciphertext;
426
- }
427
-
428
- /**
429
- * Decrypts a message.
430
- *
431
- * If strlen($ciphertext) is not a multiple of 8, null bytes will be added to the end of the string until it is.
432
- *
433
- * @see Crypt_DES::encrypt()
434
- * @access public
435
- * @param String $ciphertext
436
- */
437
- function decrypt($ciphertext)
438
- {
439
- if ($this->mode != CRYPT_DES_MODE_CTR && $this->mode != 'ctr') {
440
- // we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
441
- // "The data is padded with "\0" to make sure the length of the data is n * blocksize."
442
- $ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, chr(0));
443
- }
444
-
445
- if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
446
- if ($this->changed) {
447
- if (!isset($this->demcrypt)) {
448
- $this->demcrypt = mcrypt_module_open(MCRYPT_DES, '', $this->mode, '');
449
- }
450
- mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
451
- $this->changed = false;
452
- }
453
-
454
- $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
455
-
456
- if (!$this->continuousBuffer) {
457
- mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
458
- }
459
-
460
- return $this->mode != 'ctr' ? $this->_unpad($plaintext) : $plaintext;
461
- }
462
-
463
- if (!is_array($this->keys)) {
464
- $this->keys = $this->_prepareKey("\0\0\0\0\0\0\0\0");
465
- }
466
-
467
- $plaintext = '';
468
- switch ($this->mode) {
469
- case CRYPT_DES_MODE_ECB:
470
- for ($i = 0; $i < strlen($ciphertext); $i+=8) {
471
- $plaintext.= $this->_processBlock(substr($ciphertext, $i, 8), CRYPT_DES_DECRYPT);
472
- }
473
- break;
474
- case CRYPT_DES_MODE_CBC:
475
- $xor = $this->decryptIV;
476
- for ($i = 0; $i < strlen($ciphertext); $i+=8) {
477
- $block = substr($ciphertext, $i, 8);
478
- $plaintext.= $this->_processBlock($block, CRYPT_DES_DECRYPT) ^ $xor;
479
- $xor = $block;
480
- }
481
- if ($this->continuousBuffer) {
482
- $this->decryptIV = $xor;
483
- }
484
- break;
485
- case CRYPT_DES_MODE_CTR:
486
- $xor = $this->decryptIV;
487
- for ($i = 0; $i < strlen($ciphertext); $i+=8) {
488
- $block = substr($ciphertext, $i, 8);
489
- $key = $this->_processBlock($this->_generate_xor(8, $xor), CRYPT_DES_ENCRYPT);
490
- $plaintext.= $block ^ $key;
491
- }
492
- if ($this->continuousBuffer) {
493
- $this->decryptIV = $xor;
494
- }
495
- }
496
-
497
- return $this->mode != CRYPT_DES_MODE_CTR ? $this->_unpad($plaintext) : $plaintext;
498
- }
499
-
500
- /**
501
- * Treat consecutive "packets" as if they are a continuous buffer.
502
- *
503
- * Say you have a 16-byte plaintext $plaintext. Using the default behavior, the two following code snippets
504
- * will yield different outputs:
505
- *
506
- * <code>
507
- * echo $des->encrypt(substr($plaintext, 0, 8));
508
- * echo $des->encrypt(substr($plaintext, 8, 8));
509
- * </code>
510
- * <code>
511
- * echo $des->encrypt($plaintext);
512
- * </code>
513
- *
514
- * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates
515
- * another, as demonstrated with the following:
516
- *
517
- * <code>
518
- * $des->encrypt(substr($plaintext, 0, 8));
519
- * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
520
- * </code>
521
- * <code>
522
- * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
523
- * </code>
524
- *
525
- * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different
526
- * outputs. The reason is due to the fact that the initialization vector's change after every encryption /
527
- * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
528
- *
529
- * Put another way, when the continuous buffer is enabled, the state of the Crypt_DES() object changes after each
530
- * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
531
- * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
532
- * however, they are also less intuitive and more likely to cause you problems.
533
- *
534
- * @see Crypt_DES::disableContinuousBuffer()
535
- * @access public
536
- */
537
- function enableContinuousBuffer()
538
- {
539
- $this->continuousBuffer = true;
540
- }
541
-
542
- /**
543
- * Treat consecutive packets as if they are a discontinuous buffer.
544
- *
545
- * The default behavior.
546
- *
547
- * @see Crypt_DES::enableContinuousBuffer()
548
- * @access public
549
- */
550
- function disableContinuousBuffer()
551
- {
552
- $this->continuousBuffer = false;
553
- $this->encryptIV = $this->iv;
554
- $this->decryptIV = $this->iv;
555
- }
556
-
557
- /**
558
- * Pad "packets".
559
- *
560
- * DES works by encrypting eight bytes at a time. If you ever need to encrypt or decrypt something that's not
561
- * a multiple of eight, it becomes necessary to pad the input so that it's length is a multiple of eight.
562
- *
563
- * Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH1,
564
- * where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping
565
- * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is
566
- * transmitted separately)
567
- *
568
- * @see Crypt_DES::disablePadding()
569
- * @access public
570
- */
571
- function enablePadding()
572
- {
573
- $this->padding = true;
574
- }
575
-
576
- /**
577
- * Do not pad packets.
578
- *
579
- * @see Crypt_DES::enablePadding()
580
- * @access public
581
- */
582
- function disablePadding()
583
- {
584
- $this->padding = false;
585
- }
586
-
587
- /**
588
- * Pads a string
589
- *
590
- * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize (8).
591
- * 8 - (strlen($text) & 7) bytes are added, each of which is equal to chr(8 - (strlen($text) & 7)
592
- *
593
- * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless
594
- * and padding will, hence forth, be enabled.
595
- *
596
- * @see Crypt_DES::_unpad()
597
- * @access private
598
- */
599
- function _pad($text)
600
- {
601
- $length = strlen($text);
602
-
603
- if (!$this->padding) {
604
- if (($length & 7) == 0) {
605
- return $text;
606
- } else {
607
- user_error("The plaintext's length ($length) is not a multiple of the block size (8)", E_USER_NOTICE);
608
- $this->padding = true;
609
- }
610
- }
611
-
612
- $pad = 8 - ($length & 7);
613
- return str_pad($text, $length + $pad, chr($pad));
614
- }
615
-
616
- /**
617
- * Unpads a string
618
- *
619
- * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong
620
- * and false will be returned.
621
- *
622
- * @see Crypt_DES::_pad()
623
- * @access private
624
- */
625
- function _unpad($text)
626
- {
627
- if (!$this->padding) {
628
- return $text;
629
- }
630
-
631
- $length = ord($text[strlen($text) - 1]);
632
-
633
- if (!$length || $length > 8) {
634
- return false;
635
- }
636
-
637
- return substr($text, 0, -$length);
638
- }
639
-
640
- /**
641
- * Encrypts or decrypts a 64-bit block
642
- *
643
- * $mode should be either CRYPT_DES_ENCRYPT or CRYPT_DES_DECRYPT. See
644
- * {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general
645
- * idea of what this function does.
646
- *
647
- * @access private
648
- * @param String $block
649
- * @param Integer $mode
650
- * @return String
651
- */
652
- function _processBlock($block, $mode)
653
- {
654
- // s-boxes. in the official DES docs, they're described as being matrices that
655
- // one accesses by using the first and last bits to determine the row and the
656
- // middle four bits to determine the column. in this implementation, they've
657
- // been converted to vectors
658
- static $sbox = array(
659
- array(
660
- 14, 0, 4, 15, 13, 7, 1, 4, 2, 14, 15, 2, 11, 13, 8, 1,
661
- 3, 10 ,10, 6, 6, 12, 12, 11, 5, 9, 9, 5, 0, 3, 7, 8,
662
- 4, 15, 1, 12, 14, 8, 8, 2, 13, 4, 6, 9, 2, 1, 11, 7,
663
- 15, 5, 12, 11, 9, 3, 7, 14, 3, 10, 10, 0, 5, 6, 0, 13
664
- ),
665
- array(
666
- 15, 3, 1, 13, 8, 4, 14, 7, 6, 15, 11, 2, 3, 8, 4, 14,
667
- 9, 12, 7, 0, 2, 1, 13, 10, 12, 6, 0, 9, 5, 11, 10, 5,
668
- 0, 13, 14, 8, 7, 10, 11, 1, 10, 3, 4, 15, 13, 4, 1, 2,
669
- 5, 11, 8, 6, 12, 7, 6, 12, 9, 0, 3, 5, 2, 14, 15, 9
670
- ),
671
- array(
672
- 10, 13, 0, 7, 9, 0, 14, 9, 6, 3, 3, 4, 15, 6, 5, 10,
673
- 1, 2, 13, 8, 12, 5, 7, 14, 11, 12, 4, 11, 2, 15, 8, 1,
674
- 13, 1, 6, 10, 4, 13, 9, 0, 8, 6, 15, 9, 3, 8, 0, 7,
675
- 11, 4, 1, 15, 2, 14, 12, 3, 5, 11, 10, 5, 14, 2, 7, 12
676
- ),
677
- array(
678
- 7, 13, 13, 8, 14, 11, 3, 5, 0, 6, 6, 15, 9, 0, 10, 3,
679
- 1, 4, 2, 7, 8, 2, 5, 12, 11, 1, 12, 10, 4, 14, 15, 9,
680
- 10, 3, 6, 15, 9, 0, 0, 6, 12, 10, 11, 1, 7, 13, 13, 8,
681
- 15, 9, 1, 4, 3, 5, 14, 11, 5, 12, 2, 7, 8, 2, 4, 14
682
- ),
683
- array(
684
- 2, 14, 12, 11, 4, 2, 1, 12, 7, 4, 10, 7, 11, 13, 6, 1,
685
- 8, 5, 5, 0, 3, 15, 15, 10, 13, 3, 0, 9, 14, 8, 9, 6,
686
- 4, 11, 2, 8, 1, 12, 11, 7, 10, 1, 13, 14, 7, 2, 8, 13,
687
- 15, 6, 9, 15, 12, 0, 5, 9, 6, 10, 3, 4, 0, 5, 14, 3
688
- ),
689
- array(
690
- 12, 10, 1, 15, 10, 4, 15, 2, 9, 7, 2, 12, 6, 9, 8, 5,
691
- 0, 6, 13, 1, 3, 13, 4, 14, 14, 0, 7, 11, 5, 3, 11, 8,
692
- 9, 4, 14, 3, 15, 2, 5, 12, 2, 9, 8, 5, 12, 15, 3, 10,
693
- 7, 11, 0, 14, 4, 1, 10, 7, 1, 6, 13, 0, 11, 8, 6, 13
694
- ),
695
- array(
696
- 4, 13, 11, 0, 2, 11, 14, 7, 15, 4, 0, 9, 8, 1, 13, 10,
697
- 3, 14, 12, 3, 9, 5, 7, 12, 5, 2, 10, 15, 6, 8, 1, 6,
698
- 1, 6, 4, 11, 11, 13, 13, 8, 12, 1, 3, 4, 7, 10, 14, 7,
699
- 10, 9, 15, 5, 6, 0, 8, 15, 0, 14, 5, 2, 9, 3, 2, 12
700
- ),
701
- array(
702
- 13, 1, 2, 15, 8, 13, 4, 8, 6, 10, 15, 3, 11, 7, 1, 4,
703
- 10, 12, 9, 5, 3, 6, 14, 11, 5, 0, 0, 14, 12, 9, 7, 2,
704
- 7, 2, 11, 1, 4, 14, 1, 7, 9, 4, 12, 10, 14, 8, 2, 13,
705
- 0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11
706
- )
707
- );
708
-
709
- $keys = $this->keys;
710
-
711
- $temp = unpack('Na/Nb', $block);
712
- $block = array($temp['a'], $temp['b']);
713
-
714
- // because php does arithmetic right shifts, if the most significant bits are set, right
715
- // shifting those into the correct position will add 1's - not 0's. this will intefere
716
- // with the | operation unless a second & is done. so we isolate these bits and left shift
717
- // them into place. we then & each block with 0x7FFFFFFF to prevennt 1's from being added
718
- // for any other shifts.
719
- $msb = array(
720
- ($block[0] >> 31) & 1,
721
- ($block[1] >> 31) & 1
722
- );
723
- $block[0] &= 0x7FFFFFFF;
724
- $block[1] &= 0x7FFFFFFF;
725
-
726
- // we isolate the appropriate bit in the appropriate integer and shift as appropriate. in
727
- // some cases, there are going to be multiple bits in the same integer that need to be shifted
728
- // in the same way. we combine those into one shift operation.
729
- $block = array(
730
- (($block[1] & 0x00000040) << 25) | (($block[1] & 0x00004000) << 16) |
731
- (($block[1] & 0x00400001) << 7) | (($block[1] & 0x40000100) >> 2) |
732
- (($block[0] & 0x00000040) << 21) | (($block[0] & 0x00004000) << 12) |
733
- (($block[0] & 0x00400001) << 3) | (($block[0] & 0x40000100) >> 6) |
734
- (($block[1] & 0x00000010) << 19) | (($block[1] & 0x00001000) << 10) |
735
- (($block[1] & 0x00100000) << 1) | (($block[1] & 0x10000000) >> 8) |
736
- (($block[0] & 0x00000010) << 15) | (($block[0] & 0x00001000) << 6) |
737
- (($block[0] & 0x00100000) >> 3) | (($block[0] & 0x10000000) >> 12) |
738
- (($block[1] & 0x00000004) << 13) | (($block[1] & 0x00000400) << 4) |
739
- (($block[1] & 0x00040000) >> 5) | (($block[1] & 0x04000000) >> 14) |
740
- (($block[0] & 0x00000004) << 9) | ( $block[0] & 0x00000400 ) |
741
- (($block[0] & 0x00040000) >> 9) | (($block[0] & 0x04000000) >> 18) |
742
- (($block[1] & 0x00010000) >> 11) | (($block[1] & 0x01000000) >> 20) |
743
- (($block[0] & 0x00010000) >> 15) | (($block[0] & 0x01000000) >> 24)
744
- ,
745
- (($block[1] & 0x00000080) << 24) | (($block[1] & 0x00008000) << 15) |
746
- (($block[1] & 0x00800002) << 6) | (($block[0] & 0x00000080) << 20) |
747
- (($block[0] & 0x00008000) << 11) | (($block[0] & 0x00800002) << 2) |
748
- (($block[1] & 0x00000020) << 18) | (($block[1] & 0x00002000) << 9) |
749
- ( $block[1] & 0x00200000 ) | (($block[1] & 0x20000000) >> 9) |
750
- (($block[0] & 0x00000020) << 14) | (($block[0] & 0x00002000) << 5) |
751
- (($block[0] & 0x00200000) >> 4) | (($block[0] & 0x20000000) >> 13) |
752
- (($block[1] & 0x00000008) << 12) | (($block[1] & 0x00000800) << 3) |
753
- (($block[1] & 0x00080000) >> 6) | (($block[1] & 0x08000000) >> 15) |
754
- (($block[0] & 0x00000008) << 8) | (($block[0] & 0x00000800) >> 1) |
755
- (($block[0] & 0x00080000) >> 10) | (($block[0] & 0x08000000) >> 19) |
756
- (($block[1] & 0x00000200) >> 3) | (($block[0] & 0x00000200) >> 7) |
757
- (($block[1] & 0x00020000) >> 12) | (($block[1] & 0x02000000) >> 21) |
758
- (($block[0] & 0x00020000) >> 16) | (($block[0] & 0x02000000) >> 25) |
759
- ($msb[1] << 28) | ($msb[0] << 24)
760
- );
761
-
762
- for ($i = 0; $i < 16; $i++) {
763
- // start of "the Feistel (F) function" - see the following URL:
764
- // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png
765
- $temp = (($sbox[0][((($block[1] >> 27) & 0x1F) | (($block[1] & 1) << 5)) ^ $keys[$mode][$i][0]]) << 28)
766
- | (($sbox[1][(($block[1] & 0x1F800000) >> 23) ^ $keys[$mode][$i][1]]) << 24)
767
- | (($sbox[2][(($block[1] & 0x01F80000) >> 19) ^ $keys[$mode][$i][2]]) << 20)
768
- | (($sbox[3][(($block[1] & 0x001F8000) >> 15) ^ $keys[$mode][$i][3]]) << 16)
769
- | (($sbox[4][(($block[1] & 0x0001F800) >> 11) ^ $keys[$mode][$i][4]]) << 12)
770
- | (($sbox[5][(($block[1] & 0x00001F80) >> 7) ^ $keys[$mode][$i][5]]) << 8)
771
- | (($sbox[6][(($block[1] & 0x000001F8) >> 3) ^ $keys[$mode][$i][6]]) << 4)
772
- | ( $sbox[7][((($block[1] & 0x1F) << 1) | (($block[1] >> 31) & 1)) ^ $keys[$mode][$i][7]]);
773
-
774
- $msb = ($temp >> 31) & 1;
775
- $temp &= 0x7FFFFFFF;
776
- $newBlock = (($temp & 0x00010000) << 15) | (($temp & 0x02020120) << 5)
777
- | (($temp & 0x00001800) << 17) | (($temp & 0x01000000) >> 10)
778
- | (($temp & 0x00000008) << 24) | (($temp & 0x00100000) << 6)
779
- | (($temp & 0x00000010) << 21) | (($temp & 0x00008000) << 9)
780
- | (($temp & 0x00000200) << 12) | (($temp & 0x10000000) >> 27)
781
- | (($temp & 0x00000040) << 14) | (($temp & 0x08000000) >> 8)
782
- | (($temp & 0x00004000) << 4) | (($temp & 0x00000002) << 16)
783
- | (($temp & 0x00442000) >> 6) | (($temp & 0x40800000) >> 15)
784
- | (($temp & 0x00000001) << 11) | (($temp & 0x20000000) >> 20)
785
- | (($temp & 0x00080000) >> 13) | (($temp & 0x00000004) << 3)
786
- | (($temp & 0x04000000) >> 22) | (($temp & 0x00000480) >> 7)
787
- | (($temp & 0x00200000) >> 19) | ($msb << 23);
788
- // end of "the Feistel (F) function" - $newBlock is F's output
789
-
790
- $temp = $block[1];
791
- $block[1] = $block[0] ^ $newBlock;
792
- $block[0] = $temp;
793
- }
794
-
795
- $msb = array(
796
- ($block[0] >> 31) & 1,
797
- ($block[1] >> 31) & 1
798
- );
799
- $block[0] &= 0x7FFFFFFF;
800
- $block[1] &= 0x7FFFFFFF;
801
-
802
- $block = array(
803
- (($block[0] & 0x01000004) << 7) | (($block[1] & 0x01000004) << 6) |
804
- (($block[0] & 0x00010000) << 13) | (($block[1] & 0x00010000) << 12) |
805
- (($block[0] & 0x00000100) << 19) | (($block[1] & 0x00000100) << 18) |
806
- (($block[0] & 0x00000001) << 25) | (($block[1] & 0x00000001) << 24) |
807
- (($block[0] & 0x02000008) >> 2) | (($block[1] & 0x02000008) >> 3) |
808
- (($block[0] & 0x00020000) << 4) | (($block[1] & 0x00020000) << 3) |
809
- (($block[0] & 0x00000200) << 10) | (($block[1] & 0x00000200) << 9) |
810
- (($block[0] & 0x00000002) << 16) | (($block[1] & 0x00000002) << 15) |
811
- (($block[0] & 0x04000000) >> 11) | (($block[1] & 0x04000000) >> 12) |
812
- (($block[0] & 0x00040000) >> 5) | (($block[1] & 0x00040000) >> 6) |
813
- (($block[0] & 0x00000400) << 1) | ( $block[1] & 0x00000400 ) |
814
- (($block[0] & 0x08000000) >> 20) | (($block[1] & 0x08000000) >> 21) |
815
- (($block[0] & 0x00080000) >> 14) | (($block[1] & 0x00080000) >> 15) |
816
- (($block[0] & 0x00000800) >> 8) | (($block[1] & 0x00000800) >> 9)
817
- ,
818
- (($block[0] & 0x10000040) << 3) | (($block[1] & 0x10000040) << 2) |
819
- (($block[0] & 0x00100000) << 9) | (($block[1] & 0x00100000) << 8) |
820
- (($block[0] & 0x00001000) << 15) | (($block[1] & 0x00001000) << 14) |
821
- (($block[0] & 0x00000010) << 21) | (($block[1] & 0x00000010) << 20) |
822
- (($block[0] & 0x20000080) >> 6) | (($block[1] & 0x20000080) >> 7) |
823
- ( $block[0] & 0x00200000 ) | (($block[1] & 0x00200000) >> 1) |
824
- (($block[0] & 0x00002000) << 6) | (($block[1] & 0x00002000) << 5) |
825
- (($block[0] & 0x00000020) << 12) | (($block[1] & 0x00000020) << 11) |
826
- (($block[0] & 0x40000000) >> 15) | (($block[1] & 0x40000000) >> 16) |
827
- (($block[0] & 0x00400000) >> 9) | (($block[1] & 0x00400000) >> 10) |
828
- (($block[0] & 0x00004000) >> 3) | (($block[1] & 0x00004000) >> 4) |
829
- (($block[0] & 0x00800000) >> 18) | (($block[1] & 0x00800000) >> 19) |
830
- (($block[0] & 0x00008000) >> 12) | (($block[1] & 0x00008000) >> 13) |
831
- ($msb[0] << 7) | ($msb[1] << 6)
832
- );
833
-
834
- return pack('NN', $block[0], $block[1]);
835
- }
836
-
837
- /**
838
- * Creates the key schedule.
839
- *
840
- * @access private
841
- * @param String $key
842
- * @return Array
843
- */
844
- function _prepareKey($key)
845
- {
846
- static $shifts = array( // number of key bits shifted per round
847
- 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
848
- );
849
-
850
- // pad the key and remove extra characters as appropriate.
851
- $key = str_pad(substr($key, 0, 8), 8, chr(0));
852
-
853
- $temp = unpack('Na/Nb', $key);
854
- $key = array($temp['a'], $temp['b']);
855
- $msb = array(
856
- ($key[0] >> 31) & 1,
857
- ($key[1] >> 31) & 1
858
- );
859
- $key[0] &= 0x7FFFFFFF;
860
- $key[1] &= 0x7FFFFFFF;
861
-
862
- $key = array(
863
- (($key[1] & 0x00000002) << 26) | (($key[1] & 0x00000204) << 17) |
864
- (($key[1] & 0x00020408) << 8) | (($key[1] & 0x02040800) >> 1) |
865
- (($key[0] & 0x00000002) << 22) | (($key[0] & 0x00000204) << 13) |
866
- (($key[0] & 0x00020408) << 4) | (($key[0] & 0x02040800) >> 5) |
867
- (($key[1] & 0x04080000) >> 10) | (($key[0] & 0x04080000) >> 14) |
868
- (($key[1] & 0x08000000) >> 19) | (($key[0] & 0x08000000) >> 23) |
869
- (($key[0] & 0x00000010) >> 1) | (($key[0] & 0x00001000) >> 10) |
870
- (($key[0] & 0x00100000) >> 19) | (($key[0] & 0x10000000) >> 28)
871
- ,
872
- (($key[1] & 0x00000080) << 20) | (($key[1] & 0x00008000) << 11) |
873
- (($key[1] & 0x00800000) << 2) | (($key[0] & 0x00000080) << 16) |
874
- (($key[0] & 0x00008000) << 7) | (($key[0] & 0x00800000) >> 2) |
875
- (($key[1] & 0x00000040) << 13) | (($key[1] & 0x00004000) << 4) |
876
- (($key[1] & 0x00400000) >> 5) | (($key[1] & 0x40000000) >> 14) |
877
- (($key[0] & 0x00000040) << 9) | ( $key[0] & 0x00004000 ) |
878
- (($key[0] & 0x00400000) >> 9) | (($key[0] & 0x40000000) >> 18) |
879
- (($key[1] & 0x00000020) << 6) | (($key[1] & 0x00002000) >> 3) |
880
- (($key[1] & 0x00200000) >> 12) | (($key[1] & 0x20000000) >> 21) |
881
- (($key[0] & 0x00000020) << 2) | (($key[0] & 0x00002000) >> 7) |
882
- (($key[0] & 0x00200000) >> 16) | (($key[0] & 0x20000000) >> 25) |
883
- (($key[1] & 0x00000010) >> 1) | (($key[1] & 0x00001000) >> 10) |
884
- (($key[1] & 0x00100000) >> 19) | (($key[1] & 0x10000000) >> 28) |
885
- ($msb[1] << 24) | ($msb[0] << 20)
886
- );
887
-
888
- $keys = array();
889
- for ($i = 0; $i < 16; $i++) {
890
- $key[0] <<= $shifts[$i];
891
- $temp = ($key[0] & 0xF0000000) >> 28;
892
- $key[0] = ($key[0] | $temp) & 0x0FFFFFFF;
893
-
894
- $key[1] <<= $shifts[$i];
895
- $temp = ($key[1] & 0xF0000000) >> 28;
896
- $key[1] = ($key[1] | $temp) & 0x0FFFFFFF;
897
-
898
- $temp = array(
899
- (($key[1] & 0x00004000) >> 9) | (($key[1] & 0x00000800) >> 7) |
900
- (($key[1] & 0x00020000) >> 14) | (($key[1] & 0x00000010) >> 2) |
901
- (($key[1] & 0x08000000) >> 26) | (($key[1] & 0x00800000) >> 23)
902
- ,
903
- (($key[1] & 0x02400000) >> 20) | (($key[1] & 0x00000001) << 4) |
904
- (($key[1] & 0x00002000) >> 10) | (($key[1] & 0x00040000) >> 18) |
905
- (($key[1] & 0x00000080) >> 6)
906
- ,
907
- ( $key[1] & 0x00000020 ) | (($key[1] & 0x00000200) >> 5) |
908
- (($key[1] & 0x00010000) >> 13) | (($key[1] & 0x01000000) >> 22) |
909
- (($key[1] & 0x00000004) >> 1) | (($key[1] & 0x00100000) >> 20)
910
- ,
911
- (($key[1] & 0x00001000) >> 7) | (($key[1] & 0x00200000) >> 17) |
912
- (($key[1] & 0x00000002) << 2) | (($key[1] & 0x00000100) >> 6) |
913
- (($key[1] & 0x00008000) >> 14) | (($key[1] & 0x04000000) >> 26)
914
- ,
915
- (($key[0] & 0x00008000) >> 10) | ( $key[0] & 0x00000010 ) |
916
- (($key[0] & 0x02000000) >> 22) | (($key[0] & 0x00080000) >> 17) |
917
- (($key[0] & 0x00000200) >> 8) | (($key[0] & 0x00000002) >> 1)
918
- ,
919
- (($key[0] & 0x04000000) >> 21) | (($key[0] & 0x00010000) >> 12) |
920
- (($key[0] & 0x00000020) >> 2) | (($key[0] & 0x00000800) >> 9) |
921
- (($key[0] & 0x00800000) >> 22) | (($key[0] & 0x00000100) >> 8)
922
- ,
923
- (($key[0] & 0x00001000) >> 7) | (($key[0] & 0x00000088) >> 3) |
924
- (($key[0] & 0x00020000) >> 14) | (($key[0] & 0x00000001) << 2) |
925
- (($key[0] & 0x00400000) >> 21)
926
- ,
927
- (($key[0] & 0x00000400) >> 5) | (($key[0] & 0x00004000) >> 10) |
928
- (($key[0] & 0x00000040) >> 3) | (($key[0] & 0x00100000) >> 18) |
929
- (($key[0] & 0x08000000) >> 26) | (($key[0] & 0x01000000) >> 24)
930
- );
931
-
932
- $keys[] = $temp;
933
- }
934
-
935
- $temp = array(
936
- CRYPT_DES_ENCRYPT => $keys,
937
- CRYPT_DES_DECRYPT => array_reverse($keys)
938
- );
939
-
940
- return $temp;
941
- }
942
- }
943
-
944
- // vim: ts=4:sw=4:et:
945
- // vim6: fdl=1:
1
+ <?php
2
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
+
4
+ /**
5
+ * Pure-PHP implementation of DES.
6
+ *
7
+ * Uses mcrypt, if available, and an internal implementation, otherwise.
8
+ *
9
+ * PHP versions 4 and 5
10
+ *
11
+ * Useful resources are as follows:
12
+ *
13
+ * - {@link http://en.wikipedia.org/wiki/DES_supplementary_material Wikipedia: DES supplementary material}
14
+ * - {@link http://www.itl.nist.gov/fipspubs/fip46-2.htm FIPS 46-2 - (DES), Data Encryption Standard}
15
+ * - {@link http://www.cs.eku.edu/faculty/styer/460/Encrypt/JS-DES.html JavaScript DES Example}
16
+ *
17
+ * Here's a short example of how to use this library:
18
+ * <code>
19
+ * <?php
20
+ * include('Crypt/DES.php');
21
+ *
22
+ * $des = new Crypt_DES();
23
+ *
24
+ * $des->setKey('abcdefgh');
25
+ *
26
+ * $size = 10 * 1024;
27
+ * $plaintext = '';
28
+ * for ($i = 0; $i < $size; $i++) {
29
+ * $plaintext.= 'a';
30
+ * }
31
+ *
32
+ * echo $des->decrypt($des->encrypt($plaintext));
33
+ * ?>
34
+ * </code>
35
+ *
36
+ * LICENSE: This library is free software; you can redistribute it and/or
37
+ * modify it under the terms of the GNU Lesser General Public
38
+ * License as published by the Free Software Foundation; either
39
+ * version 2.1 of the License, or (at your option) any later version.
40
+ *
41
+ * This library is distributed in the hope that it will be useful,
42
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
43
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
44
+ * Lesser General Public License for more details.
45
+ *
46
+ * You should have received a copy of the GNU Lesser General Public
47
+ * License along with this library; if not, write to the Free Software
48
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
49
+ * MA 02111-1307 USA
50
+ *
51
+ * @category Crypt
52
+ * @package Crypt_DES
53
+ * @author Jim Wigginton <terrafrost@php.net>
54
+ * @copyright MMVII Jim Wigginton
55
+ * @license http://www.gnu.org/licenses/lgpl.txt
56
+ * @version $Id: DES.php,v 1.12 2010/02/09 06:10:26 terrafrost Exp $
57
+ * @link http://phpseclib.sourceforge.net
58
+ */
59
+
60
+ /**#@+
61
+ * @access private
62
+ * @see Crypt_DES::_prepareKey()
63
+ * @see Crypt_DES::_processBlock()
64
+ */
65
+ /**
66
+ * Contains array_reverse($keys[CRYPT_DES_DECRYPT])
67
+ */
68
+ define('CRYPT_DES_ENCRYPT', 0);
69
+ /**
70
+ * Contains array_reverse($keys[CRYPT_DES_ENCRYPT])
71
+ */
72
+ define('CRYPT_DES_DECRYPT', 1);
73
+ /**#@-*/
74
+
75
+ /**#@+
76
+ * @access public
77
+ * @see Crypt_DES::encrypt()
78
+ * @see Crypt_DES::decrypt()
79
+ */
80
+ /**
81
+ * Encrypt / decrypt using the Counter mode.
82
+ *
83
+ * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
84
+ *
85
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
86
+ */
87
+ define('CRYPT_DES_MODE_CTR', -1);
88
+ /**
89
+ * Encrypt / decrypt using the Electronic Code Book mode.
90
+ *
91
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
92
+ */
93
+ define('CRYPT_DES_MODE_ECB', 1);
94
+ /**
95
+ * Encrypt / decrypt using the Code Book Chaining mode.
96
+ *
97
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
98
+ */
99
+ define('CRYPT_DES_MODE_CBC', 2);
100
+ /**#@-*/
101
+
102
+ /**#@+
103
+ * @access private
104
+ * @see Crypt_DES::Crypt_DES()
105
+ */
106
+ /**
107
+ * Toggles the internal implementation
108
+ */
109
+ define('CRYPT_DES_MODE_INTERNAL', 1);
110
+ /**
111
+ * Toggles the mcrypt implementation
112
+ */
113
+ define('CRYPT_DES_MODE_MCRYPT', 2);
114
+ /**#@-*/
115
+
116
+ /**
117
+ * Pure-PHP implementation of DES.
118
+ *
119
+ * @author Jim Wigginton <terrafrost@php.net>
120
+ * @version 0.1.0
121
+ * @access public
122
+ * @package Crypt_DES
123
+ */
124
+ class Crypt_DES {
125
+ /**
126
+ * The Key Schedule
127
+ *
128
+ * @see Crypt_DES::setKey()
129
+ * @var Array
130
+ * @access private
131
+ */
132
+ var $keys = "\0\0\0\0\0\0\0\0";
133
+
134
+ /**
135
+ * The Encryption Mode
136
+ *
137
+ * @see Crypt_DES::Crypt_DES()
138
+ * @var Integer
139
+ * @access private
140
+ */
141
+ var $mode;
142
+
143
+ /**
144
+ * Continuous Buffer status
145
+ *
146
+ * @see Crypt_DES::enableContinuousBuffer()
147
+ * @var Boolean
148
+ * @access private
149
+ */
150
+ var $continuousBuffer = false;
151
+
152
+ /**
153
+ * Padding status
154
+ *
155
+ * @see Crypt_DES::enablePadding()
156
+ * @var Boolean
157
+ * @access private
158
+ */
159
+ var $padding = true;
160
+
161
+ /**
162
+ * The Initialization Vector
163
+ *
164
+ * @see Crypt_DES::setIV()
165
+ * @var String
166
+ * @access private
167
+ */
168
+ var $iv = "\0\0\0\0\0\0\0\0";
169
+
170
+ /**
171
+ * A "sliding" Initialization Vector
172
+ *
173
+ * @see Crypt_DES::enableContinuousBuffer()
174
+ * @var String
175
+ * @access private
176
+ */
177
+ var $encryptIV = "\0\0\0\0\0\0\0\0";
178
+
179
+ /**
180
+ * A "sliding" Initialization Vector
181
+ *
182
+ * @see Crypt_DES::enableContinuousBuffer()
183
+ * @var String
184
+ * @access private
185
+ */
186
+ var $decryptIV = "\0\0\0\0\0\0\0\0";
187
+
188
+ /**
189
+ * mcrypt resource for encryption
190
+ *
191
+ * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
192
+ * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
193
+ *
194
+ * @see Crypt_AES::encrypt()
195
+ * @var String
196
+ * @access private
197
+ */
198
+ var $enmcrypt;
199
+
200
+ /**
201
+ * mcrypt resource for decryption
202
+ *
203
+ * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
204
+ * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
205
+ *
206
+ * @see Crypt_AES::decrypt()
207
+ * @var String
208
+ * @access private
209
+ */
210
+ var $demcrypt;
211
+
212
+ /**
213
+ * Does the (en|de)mcrypt resource need to be (re)initialized?
214
+ *
215
+ * @see setKey()
216
+ * @see setIV()
217
+ * @var Boolean
218
+ * @access private
219
+ */
220
+ var $changed = true;
221
+
222
+ /**
223
+ * Default Constructor.
224
+ *
225
+ * Determines whether or not the mcrypt extension should be used. $mode should only, at present, be
226
+ * CRYPT_DES_MODE_ECB or CRYPT_DES_MODE_CBC. If not explictly set, CRYPT_DES_MODE_CBC will be used.
227
+ *
228
+ * @param optional Integer $mode
229
+ * @return Crypt_DES
230
+ * @access public
231
+ */
232
+ function Crypt_DES($mode = CRYPT_MODE_DES_CBC)
233
+ {
234
+ if ( !defined('CRYPT_DES_MODE') ) {
235
+ switch (true) {
236
+ case extension_loaded('mcrypt'):
237
+ // i'd check to see if des was supported, by doing in_array('des', mcrypt_list_algorithms('')),
238
+ // but since that can be changed after the object has been created, there doesn't seem to be
239
+ // a lot of point...
240
+ define('CRYPT_DES_MODE', CRYPT_DES_MODE_MCRYPT);
241
+ break;
242
+ default:
243
+ define('CRYPT_DES_MODE', CRYPT_DES_MODE_INTERNAL);
244
+ }
245
+ }
246
+
247
+ switch ( CRYPT_DES_MODE ) {
248
+ case CRYPT_DES_MODE_MCRYPT:
249
+ switch ($mode) {
250
+ case CRYPT_DES_MODE_ECB:
251
+ $this->mode = MCRYPT_MODE_ECB;
252
+ break;
253
+ case CRYPT_DES_MODE_CTR:
254
+ $this->mode = 'ctr';
255
+ //$this->mode = in_array('ctr', mcrypt_list_modes()) ? 'ctr' : CRYPT_DES_MODE_CTR;
256
+ break;
257
+ case CRYPT_DES_MODE_CBC:
258
+ default:
259
+ $this->mode = MCRYPT_MODE_CBC;
260
+ }
261
+
262
+ break;
263
+ default:
264
+ switch ($mode) {
265
+ case CRYPT_DES_MODE_ECB:
266
+ case CRYPT_DES_MODE_CTR:
267
+ case CRYPT_DES_MODE_CBC:
268
+ $this->mode = $mode;
269
+ break;
270
+ default:
271
+ $this->mode = CRYPT_DES_MODE_CBC;
272
+ }
273
+ }
274
+ }
275
+
276
+ /**
277
+ * Sets the key.
278
+ *
279
+ * Keys can be of any length. DES, itself, uses 64-bit keys (eg. strlen($key) == 8), however, we
280
+ * only use the first eight, if $key has more then eight characters in it, and pad $key with the
281
+ * null byte if it is less then eight characters long.
282
+ *
283
+ * DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
284
+ *
285
+ * If the key is not explicitly set, it'll be assumed to be all zero's.
286
+ *
287
+ * @access public
288
+ * @param String $key
289
+ */
290
+ function setKey($key)
291
+ {
292
+ $this->keys = ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) ? substr($key, 0, 8) : $this->_prepareKey($key);
293
+ $this->changed = true;
294
+ }
295
+
296
+ /**
297
+ * Sets the initialization vector. (optional)
298
+ *
299
+ * SetIV is not required when CRYPT_DES_MODE_ECB is being used. If not explictly set, it'll be assumed
300
+ * to be all zero's.
301
+ *
302
+ * @access public
303
+ * @param String $iv
304
+ */
305
+ function setIV($iv)
306
+ {
307
+ $this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($iv, 0, 8), 8, chr(0));
308
+ $this->changed = true;
309
+ }
310
+
311
+ /**
312
+ * Generate CTR XOR encryption key
313
+ *
314
+ * Encrypt the output of this and XOR it against the ciphertext / plaintext to get the
315
+ * plaintext / ciphertext in CTR mode.
316
+ *
317
+ * @see Crypt_DES::decrypt()
318
+ * @see Crypt_DES::encrypt()
319
+ * @access public
320
+ * @param Integer $length
321
+ * @param String $iv
322
+ */
323
+ function _generate_xor($length, &$iv)
324
+ {
325
+ $xor = '';
326
+ $num_blocks = ($length + 7) >> 3;
327
+ for ($i = 0; $i < $num_blocks; $i++) {
328
+ $xor.= $iv;
329
+ for ($j = 4; $j <= 8; $j+=4) {
330
+ $temp = substr($iv, -$j, 4);
331
+ switch ($temp) {
332
+ case "\xFF\xFF\xFF\xFF":
333
+ $iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4);
334
+ break;
335
+ case "\x7F\xFF\xFF\xFF":
336
+ $iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4);
337
+ break 2;
338
+ default:
339
+ extract(unpack('Ncount', $temp));
340
+ $iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);
341
+ break 2;
342
+ }
343
+ }
344
+ }
345
+
346
+ return $xor;
347
+ }
348
+
349
+ /**
350
+ * Encrypts a message.
351
+ *
352
+ * $plaintext will be padded with up to 8 additional bytes. Other DES implementations may or may not pad in the
353
+ * same manner. Other common approaches to padding and the reasons why it's necessary are discussed in the following
354
+ * URL:
355
+ *
356
+ * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
357
+ *
358
+ * An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does.
359
+ * strlen($plaintext) will still need to be a multiple of 8, however, arbitrary values can be added to make it that
360
+ * length.
361
+ *
362
+ * @see Crypt_DES::decrypt()
363
+ * @access public
364
+ * @param String $plaintext
365
+ */
366
+ function encrypt($plaintext)
367
+ {
368
+ if ($this->mode != CRYPT_DES_MODE_CTR && $this->mode != 'ctr') {
369
+ $plaintext = $this->_pad($plaintext);
370
+ }
371
+
372
+ if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
373
+ if ($this->changed) {
374
+ if (!isset($this->enmcrypt)) {
375
+ $this->enmcrypt = mcrypt_module_open(MCRYPT_DES, '', $this->mode, '');
376
+ }
377
+ mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);
378
+ $this->changed = false;
379
+ }
380
+
381
+ $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
382
+
383
+ if (!$this->continuousBuffer) {
384
+ mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);
385
+ }
386
+
387
+ return $ciphertext;
388
+ }
389
+
390
+ if (!is_array($this->keys)) {
391
+ $this->keys = $this->_prepareKey("\0\0\0\0\0\0\0\0");
392
+ }
393
+
394
+ $ciphertext = '';
395
+ switch ($this->mode) {
396
+ case CRYPT_DES_MODE_ECB:
397
+ for ($i = 0; $i < strlen($plaintext); $i+=8) {
398
+ $ciphertext.= $this->_processBlock(substr($plaintext, $i, 8), CRYPT_DES_ENCRYPT);
399
+ }
400
+ break;
401
+ case CRYPT_DES_MODE_CBC:
402
+ $xor = $this->encryptIV;
403
+ for ($i = 0; $i < strlen($plaintext); $i+=8) {
404
+ $block = substr($plaintext, $i, 8);
405
+ $block = $this->_processBlock($block ^ $xor, CRYPT_DES_ENCRYPT);
406
+ $xor = $block;
407
+ $ciphertext.= $block;
408
+ }
409
+ if ($this->continuousBuffer) {
410
+ $this->encryptIV = $xor;
411
+ }
412
+ break;
413
+ case CRYPT_DES_MODE_CTR:
414
+ $xor = $this->encryptIV;
415
+ for ($i = 0; $i < strlen($plaintext); $i+=8) {
416
+ $block = substr($plaintext, $i, 8);
417
+ $key = $this->_processBlock($this->_generate_xor(8, $xor), CRYPT_DES_ENCRYPT);
418
+ $ciphertext.= $block ^ $key;
419
+ }
420
+ if ($this->continuousBuffer) {
421
+ $this->encryptIV = $xor;
422
+ }
423
+ }
424
+
425
+ return $ciphertext;
426
+ }
427
+
428
+ /**
429
+ * Decrypts a message.
430
+ *
431
+ * If strlen($ciphertext) is not a multiple of 8, null bytes will be added to the end of the string until it is.
432
+ *
433
+ * @see Crypt_DES::encrypt()
434
+ * @access public
435
+ * @param String $ciphertext
436
+ */
437
+ function decrypt($ciphertext)
438
+ {
439
+ if ($this->mode != CRYPT_DES_MODE_CTR && $this->mode != 'ctr') {
440
+ // we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
441
+ // "The data is padded with "\0" to make sure the length of the data is n * blocksize."
442
+ $ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, chr(0));
443
+ }
444
+
445
+ if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
446
+ if ($this->changed) {
447
+ if (!isset($this->demcrypt)) {
448
+ $this->demcrypt = mcrypt_module_open(MCRYPT_DES, '', $this->mode, '');
449
+ }
450
+ mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
451
+ $this->changed = false;
452
+ }
453
+
454
+ $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
455
+
456
+ if (!$this->continuousBuffer) {
457
+ mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
458
+ }
459
+
460
+ return $this->mode != 'ctr' ? $this->_unpad($plaintext) : $plaintext;
461
+ }
462
+
463
+ if (!is_array($this->keys)) {
464
+ $this->keys = $this->_prepareKey("\0\0\0\0\0\0\0\0");
465
+ }
466
+
467
+ $plaintext = '';
468
+ switch ($this->mode) {
469
+ case CRYPT_DES_MODE_ECB:
470
+ for ($i = 0; $i < strlen($ciphertext); $i+=8) {
471
+ $plaintext.= $this->_processBlock(substr($ciphertext, $i, 8), CRYPT_DES_DECRYPT);
472
+ }
473
+ break;
474
+ case CRYPT_DES_MODE_CBC:
475
+ $xor = $this->decryptIV;
476
+ for ($i = 0; $i < strlen($ciphertext); $i+=8) {
477
+ $block = substr($ciphertext, $i, 8);
478
+ $plaintext.= $this->_processBlock($block, CRYPT_DES_DECRYPT) ^ $xor;
479
+ $xor = $block;
480
+ }
481
+ if ($this->continuousBuffer) {
482
+ $this->decryptIV = $xor;
483
+ }
484
+ break;
485
+ case CRYPT_DES_MODE_CTR:
486
+ $xor = $this->decryptIV;
487
+ for ($i = 0; $i < strlen($ciphertext); $i+=8) {
488
+ $block = substr($ciphertext, $i, 8);
489
+ $key = $this->_processBlock($this->_generate_xor(8, $xor), CRYPT_DES_ENCRYPT);
490
+ $plaintext.= $block ^ $key;
491
+ }
492
+ if ($this->continuousBuffer) {
493
+ $this->decryptIV = $xor;
494
+ }
495
+ }
496
+
497
+ return $this->mode != CRYPT_DES_MODE_CTR ? $this->_unpad($plaintext) : $plaintext;
498
+ }
499
+
500
+ /**
501
+ * Treat consecutive "packets" as if they are a continuous buffer.
502
+ *
503
+ * Say you have a 16-byte plaintext $plaintext. Using the default behavior, the two following code snippets
504
+ * will yield different outputs:
505
+ *
506
+ * <code>
507
+ * echo $des->encrypt(substr($plaintext, 0, 8));
508
+ * echo $des->encrypt(substr($plaintext, 8, 8));
509
+ * </code>
510
+ * <code>
511
+ * echo $des->encrypt($plaintext);
512
+ * </code>
513
+ *
514
+ * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates
515
+ * another, as demonstrated with the following:
516
+ *
517
+ * <code>
518
+ * $des->encrypt(substr($plaintext, 0, 8));
519
+ * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
520
+ * </code>
521
+ * <code>
522
+ * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
523
+ * </code>
524
+ *
525
+ * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different
526
+ * outputs. The reason is due to the fact that the initialization vector's change after every encryption /
527
+ * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
528
+ *
529
+ * Put another way, when the continuous buffer is enabled, the state of the Crypt_DES() object changes after each
530
+ * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
531
+ * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
532
+ * however, they are also less intuitive and more likely to cause you problems.
533
+ *
534
+ * @see Crypt_DES::disableContinuousBuffer()
535
+ * @access public
536
+ */
537
+ function enableContinuousBuffer()
538
+ {
539
+ $this->continuousBuffer = true;
540
+ }
541
+
542
+ /**
543
+ * Treat consecutive packets as if they are a discontinuous buffer.
544
+ *
545
+ * The default behavior.
546
+ *
547
+ * @see Crypt_DES::enableContinuousBuffer()
548
+ * @access public
549
+ */
550
+ function disableContinuousBuffer()
551
+ {
552
+ $this->continuousBuffer = false;
553
+ $this->encryptIV = $this->iv;
554
+ $this->decryptIV = $this->iv;
555
+ }
556
+
557
+ /**
558
+ * Pad "packets".
559
+ *
560
+ * DES works by encrypting eight bytes at a time. If you ever need to encrypt or decrypt something that's not
561
+ * a multiple of eight, it becomes necessary to pad the input so that it's length is a multiple of eight.
562
+ *
563
+ * Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH1,
564
+ * where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping
565
+ * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is
566
+ * transmitted separately)
567
+ *
568
+ * @see Crypt_DES::disablePadding()
569
+ * @access public
570
+ */
571
+ function enablePadding()
572
+ {
573
+ $this->padding = true;
574
+ }
575
+
576
+ /**
577
+ * Do not pad packets.
578
+ *
579
+ * @see Crypt_DES::enablePadding()
580
+ * @access public
581
+ */
582
+ function disablePadding()
583
+ {
584
+ $this->padding = false;
585
+ }
586
+
587
+ /**
588
+ * Pads a string
589
+ *
590
+ * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize (8).
591
+ * 8 - (strlen($text) & 7) bytes are added, each of which is equal to chr(8 - (strlen($text) & 7)
592
+ *
593
+ * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless
594
+ * and padding will, hence forth, be enabled.
595
+ *
596
+ * @see Crypt_DES::_unpad()
597
+ * @access private
598
+ */
599
+ function _pad($text)
600
+ {
601
+ $length = strlen($text);
602
+
603
+ if (!$this->padding) {
604
+ if (($length & 7) == 0) {
605
+ return $text;
606
+ } else {
607
+ user_error("The plaintext's length ($length) is not a multiple of the block size (8)", E_USER_NOTICE);
608
+ $this->padding = true;
609
+ }
610
+ }
611
+
612
+ $pad = 8 - ($length & 7);
613
+ return str_pad($text, $length + $pad, chr($pad));
614
+ }
615
+
616
+ /**
617
+ * Unpads a string
618
+ *
619
+ * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong
620
+ * and false will be returned.
621
+ *
622
+ * @see Crypt_DES::_pad()
623
+ * @access private
624
+ */
625
+ function _unpad($text)
626
+ {
627
+ if (!$this->padding) {
628
+ return $text;
629
+ }
630
+
631
+ $length = ord($text[strlen($text) - 1]);
632
+
633
+ if (!$length || $length > 8) {
634
+ return false;
635
+ }
636
+
637
+ return substr($text, 0, -$length);
638
+ }
639
+
640
+ /**
641
+ * Encrypts or decrypts a 64-bit block
642
+ *
643
+ * $mode should be either CRYPT_DES_ENCRYPT or CRYPT_DES_DECRYPT. See
644
+ * {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general
645
+ * idea of what this function does.
646
+ *
647
+ * @access private
648
+ * @param String $block
649
+ * @param Integer $mode
650
+ * @return String
651
+ */
652
+ function _processBlock($block, $mode)
653
+ {
654
+ // s-boxes. in the official DES docs, they're described as being matrices that
655
+ // one accesses by using the first and last bits to determine the row and the
656
+ // middle four bits to determine the column. in this implementation, they've
657
+ // been converted to vectors
658
+ static $sbox = array(
659
+ array(
660
+ 14, 0, 4, 15, 13, 7, 1, 4, 2, 14, 15, 2, 11, 13, 8, 1,
661
+ 3, 10 ,10, 6, 6, 12, 12, 11, 5, 9, 9, 5, 0, 3, 7, 8,
662
+ 4, 15, 1, 12, 14, 8, 8, 2, 13, 4, 6, 9, 2, 1, 11, 7,
663
+ 15, 5, 12, 11, 9, 3, 7, 14, 3, 10, 10, 0, 5, 6, 0, 13
664
+ ),
665
+ array(
666
+ 15, 3, 1, 13, 8, 4, 14, 7, 6, 15, 11, 2, 3, 8, 4, 14,
667
+ 9, 12, 7, 0, 2, 1, 13, 10, 12, 6, 0, 9, 5, 11, 10, 5,
668
+ 0, 13, 14, 8, 7, 10, 11, 1, 10, 3, 4, 15, 13, 4, 1, 2,
669
+ 5, 11, 8, 6, 12, 7, 6, 12, 9, 0, 3, 5, 2, 14, 15, 9
670
+ ),
671
+ array(
672
+ 10, 13, 0, 7, 9, 0, 14, 9, 6, 3, 3, 4, 15, 6, 5, 10,
673
+ 1, 2, 13, 8, 12, 5, 7, 14, 11, 12, 4, 11, 2, 15, 8, 1,
674
+ 13, 1, 6, 10, 4, 13, 9, 0, 8, 6, 15, 9, 3, 8, 0, 7,
675
+ 11, 4, 1, 15, 2, 14, 12, 3, 5, 11, 10, 5, 14, 2, 7, 12
676
+ ),
677
+ array(
678
+ 7, 13, 13, 8, 14, 11, 3, 5, 0, 6, 6, 15, 9, 0, 10, 3,
679
+ 1, 4, 2, 7, 8, 2, 5, 12, 11, 1, 12, 10, 4, 14, 15, 9,
680
+ 10, 3, 6, 15, 9, 0, 0, 6, 12, 10, 11, 1, 7, 13, 13, 8,
681
+ 15, 9, 1, 4, 3, 5, 14, 11, 5, 12, 2, 7, 8, 2, 4, 14
682
+ ),
683
+ array(
684
+ 2, 14, 12, 11, 4, 2, 1, 12, 7, 4, 10, 7, 11, 13, 6, 1,
685
+ 8, 5, 5, 0, 3, 15, 15, 10, 13, 3, 0, 9, 14, 8, 9, 6,
686
+ 4, 11, 2, 8, 1, 12, 11, 7, 10, 1, 13, 14, 7, 2, 8, 13,
687
+ 15, 6, 9, 15, 12, 0, 5, 9, 6, 10, 3, 4, 0, 5, 14, 3
688
+ ),
689
+ array(
690
+ 12, 10, 1, 15, 10, 4, 15, 2, 9, 7, 2, 12, 6, 9, 8, 5,
691
+ 0, 6, 13, 1, 3, 13, 4, 14, 14, 0, 7, 11, 5, 3, 11, 8,
692
+ 9, 4, 14, 3, 15, 2, 5, 12, 2, 9, 8, 5, 12, 15, 3, 10,
693
+ 7, 11, 0, 14, 4, 1, 10, 7, 1, 6, 13, 0, 11, 8, 6, 13
694
+ ),
695
+ array(
696
+ 4, 13, 11, 0, 2, 11, 14, 7, 15, 4, 0, 9, 8, 1, 13, 10,
697
+ 3, 14, 12, 3, 9, 5, 7, 12, 5, 2, 10, 15, 6, 8, 1, 6,
698
+ 1, 6, 4, 11, 11, 13, 13, 8, 12, 1, 3, 4, 7, 10, 14, 7,
699
+ 10, 9, 15, 5, 6, 0, 8, 15, 0, 14, 5, 2, 9, 3, 2, 12
700
+ ),
701
+ array(
702
+ 13, 1, 2, 15, 8, 13, 4, 8, 6, 10, 15, 3, 11, 7, 1, 4,
703
+ 10, 12, 9, 5, 3, 6, 14, 11, 5, 0, 0, 14, 12, 9, 7, 2,
704
+ 7, 2, 11, 1, 4, 14, 1, 7, 9, 4, 12, 10, 14, 8, 2, 13,
705
+ 0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11
706
+ )
707
+ );
708
+
709
+ $keys = $this->keys;
710
+
711
+ $temp = unpack('Na/Nb', $block);
712
+ $block = array($temp['a'], $temp['b']);
713
+
714
+ // because php does arithmetic right shifts, if the most significant bits are set, right
715
+ // shifting those into the correct position will add 1's - not 0's. this will intefere
716
+ // with the | operation unless a second & is done. so we isolate these bits and left shift
717
+ // them into place. we then & each block with 0x7FFFFFFF to prevennt 1's from being added
718
+ // for any other shifts.
719
+ $msb = array(
720
+ ($block[0] >> 31) & 1,
721
+ ($block[1] >> 31) & 1
722
+ );
723
+ $block[0] &= 0x7FFFFFFF;
724
+ $block[1] &= 0x7FFFFFFF;
725
+
726
+ // we isolate the appropriate bit in the appropriate integer and shift as appropriate. in
727
+ // some cases, there are going to be multiple bits in the same integer that need to be shifted
728
+ // in the same way. we combine those into one shift operation.
729
+ $block = array(
730
+ (($block[1] & 0x00000040) << 25) | (($block[1] & 0x00004000) << 16) |
731
+ (($block[1] & 0x00400001) << 7) | (($block[1] & 0x40000100) >> 2) |
732
+ (($block[0] & 0x00000040) << 21) | (($block[0] & 0x00004000) << 12) |
733
+ (($block[0] & 0x00400001) << 3) | (($block[0] & 0x40000100) >> 6) |
734
+ (($block[1] & 0x00000010) << 19) | (($block[1] & 0x00001000) << 10) |
735
+ (($block[1] & 0x00100000) << 1) | (($block[1] & 0x10000000) >> 8) |
736
+ (($block[0] & 0x00000010) << 15) | (($block[0] & 0x00001000) << 6) |
737
+ (($block[0] & 0x00100000) >> 3) | (($block[0] & 0x10000000) >> 12) |
738
+ (($block[1] & 0x00000004) << 13) | (($block[1] & 0x00000400) << 4) |
739
+ (($block[1] & 0x00040000) >> 5) | (($block[1] & 0x04000000) >> 14) |
740
+ (($block[0] & 0x00000004) << 9) | ( $block[0] & 0x00000400 ) |
741
+ (($block[0] & 0x00040000) >> 9) | (($block[0] & 0x04000000) >> 18) |
742
+ (($block[1] & 0x00010000) >> 11) | (($block[1] & 0x01000000) >> 20) |
743
+ (($block[0] & 0x00010000) >> 15) | (($block[0] & 0x01000000) >> 24)
744
+ ,
745
+ (($block[1] & 0x00000080) << 24) | (($block[1] & 0x00008000) << 15) |
746
+ (($block[1] & 0x00800002) << 6) | (($block[0] & 0x00000080) << 20) |
747
+ (($block[0] & 0x00008000) << 11) | (($block[0] & 0x00800002) << 2) |
748
+ (($block[1] & 0x00000020) << 18) | (($block[1] & 0x00002000) << 9) |
749
+ ( $block[1] & 0x00200000 ) | (($block[1] & 0x20000000) >> 9) |
750
+ (($block[0] & 0x00000020) << 14) | (($block[0] & 0x00002000) << 5) |
751
+ (($block[0] & 0x00200000) >> 4) | (($block[0] & 0x20000000) >> 13) |
752
+ (($block[1] & 0x00000008) << 12) | (($block[1] & 0x00000800) << 3) |
753
+ (($block[1] & 0x00080000) >> 6) | (($block[1] & 0x08000000) >> 15) |
754
+ (($block[0] & 0x00000008) << 8) | (($block[0] & 0x00000800) >> 1) |
755
+ (($block[0] & 0x00080000) >> 10) | (($block[0] & 0x08000000) >> 19) |
756
+ (($block[1] & 0x00000200) >> 3) | (($block[0] & 0x00000200) >> 7) |
757
+ (($block[1] & 0x00020000) >> 12) | (($block[1] & 0x02000000) >> 21) |
758
+ (($block[0] & 0x00020000) >> 16) | (($block[0] & 0x02000000) >> 25) |
759
+ ($msb[1] << 28) | ($msb[0] << 24)
760
+ );
761
+
762
+ for ($i = 0; $i < 16; $i++) {
763
+ // start of "the Feistel (F) function" - see the following URL:
764
+ // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png
765
+ $temp = (($sbox[0][((($block[1] >> 27) & 0x1F) | (($block[1] & 1) << 5)) ^ $keys[$mode][$i][0]]) << 28)
766
+ | (($sbox[1][(($block[1] & 0x1F800000) >> 23) ^ $keys[$mode][$i][1]]) << 24)
767
+ | (($sbox[2][(($block[1] & 0x01F80000) >> 19) ^ $keys[$mode][$i][2]]) << 20)
768
+ | (($sbox[3][(($block[1] & 0x001F8000) >> 15) ^ $keys[$mode][$i][3]]) << 16)
769
+ | (($sbox[4][(($block[1] & 0x0001F800) >> 11) ^ $keys[$mode][$i][4]]) << 12)
770
+ | (($sbox[5][(($block[1] & 0x00001F80) >> 7) ^ $keys[$mode][$i][5]]) << 8)
771
+ | (($sbox[6][(($block[1] & 0x000001F8) >> 3) ^ $keys[$mode][$i][6]]) << 4)
772
+ | ( $sbox[7][((($block[1] & 0x1F) << 1) | (($block[1] >> 31) & 1)) ^ $keys[$mode][$i][7]]);
773
+
774
+ $msb = ($temp >> 31) & 1;
775
+ $temp &= 0x7FFFFFFF;
776
+ $newBlock = (($temp & 0x00010000) << 15) | (($temp & 0x02020120) << 5)
777
+ | (($temp & 0x00001800) << 17) | (($temp & 0x01000000) >> 10)
778
+ | (($temp & 0x00000008) << 24) | (($temp & 0x00100000) << 6)
779
+ | (($temp & 0x00000010) << 21) | (($temp & 0x00008000) << 9)
780
+ | (($temp & 0x00000200) << 12) | (($temp & 0x10000000) >> 27)
781
+ | (($temp & 0x00000040) << 14) | (($temp & 0x08000000) >> 8)
782
+ | (($temp & 0x00004000) << 4) | (($temp & 0x00000002) << 16)
783
+ | (($temp & 0x00442000) >> 6) | (($temp & 0x40800000) >> 15)
784
+ | (($temp & 0x00000001) << 11) | (($temp & 0x20000000) >> 20)
785
+ | (($temp & 0x00080000) >> 13) | (($temp & 0x00000004) << 3)
786
+ | (($temp & 0x04000000) >> 22) | (($temp & 0x00000480) >> 7)
787
+ | (($temp & 0x00200000) >> 19) | ($msb << 23);
788
+ // end of "the Feistel (F) function" - $newBlock is F's output
789
+
790
+ $temp = $block[1];
791
+ $block[1] = $block[0] ^ $newBlock;
792
+ $block[0] = $temp;
793
+ }
794
+
795
+ $msb = array(
796
+ ($block[0] >> 31) & 1,
797
+ ($block[1] >> 31) & 1
798
+ );
799
+ $block[0] &= 0x7FFFFFFF;
800
+ $block[1] &= 0x7FFFFFFF;
801
+
802
+ $block = array(
803
+ (($block[0] & 0x01000004) << 7) | (($block[1] & 0x01000004) << 6) |
804
+ (($block[0] & 0x00010000) << 13) | (($block[1] & 0x00010000) << 12) |
805
+ (($block[0] & 0x00000100) << 19) | (($block[1] & 0x00000100) << 18) |
806
+ (($block[0] & 0x00000001) << 25) | (($block[1] & 0x00000001) << 24) |
807
+ (($block[0] & 0x02000008) >> 2) | (($block[1] & 0x02000008) >> 3) |
808
+ (($block[0] & 0x00020000) << 4) | (($block[1] & 0x00020000) << 3) |
809
+ (($block[0] & 0x00000200) << 10) | (($block[1] & 0x00000200) << 9) |
810
+ (($block[0] & 0x00000002) << 16) | (($block[1] & 0x00000002) << 15) |
811
+ (($block[0] & 0x04000000) >> 11) | (($block[1] & 0x04000000) >> 12) |
812
+ (($block[0] & 0x00040000) >> 5) | (($block[1] & 0x00040000) >> 6) |
813
+ (($block[0] & 0x00000400) << 1) | ( $block[1] & 0x00000400 ) |
814
+ (($block[0] & 0x08000000) >> 20) | (($block[1] & 0x08000000) >> 21) |
815
+ (($block[0] & 0x00080000) >> 14) | (($block[1] & 0x00080000) >> 15) |
816
+ (($block[0] & 0x00000800) >> 8) | (($block[1] & 0x00000800) >> 9)
817
+ ,
818
+ (($block[0] & 0x10000040) << 3) | (($block[1] & 0x10000040) << 2) |
819
+ (($block[0] & 0x00100000) << 9) | (($block[1] & 0x00100000) << 8) |
820
+ (($block[0] & 0x00001000) << 15) | (($block[1] & 0x00001000) << 14) |
821
+ (($block[0] & 0x00000010) << 21) | (($block[1] & 0x00000010) << 20) |
822
+ (($block[0] & 0x20000080) >> 6) | (($block[1] & 0x20000080) >> 7) |
823
+ ( $block[0] & 0x00200000 ) | (($block[1] & 0x00200000) >> 1) |
824
+ (($block[0] & 0x00002000) << 6) | (($block[1] & 0x00002000) << 5) |
825
+ (($block[0] & 0x00000020) << 12) | (($block[1] & 0x00000020) << 11) |
826
+ (($block[0] & 0x40000000) >> 15) | (($block[1] & 0x40000000) >> 16) |
827
+ (($block[0] & 0x00400000) >> 9) | (($block[1] & 0x00400000) >> 10) |
828
+ (($block[0] & 0x00004000) >> 3) | (($block[1] & 0x00004000) >> 4) |
829
+ (($block[0] & 0x00800000) >> 18) | (($block[1] & 0x00800000) >> 19) |
830
+ (($block[0] & 0x00008000) >> 12) | (($block[1] & 0x00008000) >> 13) |
831
+ ($msb[0] << 7) | ($msb[1] << 6)
832
+ );
833
+
834
+ return pack('NN', $block[0], $block[1]);
835
+ }
836
+
837
+ /**
838
+ * Creates the key schedule.
839
+ *
840
+ * @access private
841
+ * @param String $key
842
+ * @return Array
843
+ */
844
+ function _prepareKey($key)
845
+ {
846
+ static $shifts = array( // number of key bits shifted per round
847
+ 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
848
+ );
849
+
850
+ // pad the key and remove extra characters as appropriate.
851
+ $key = str_pad(substr($key, 0, 8), 8, chr(0));
852
+
853
+ $temp = unpack('Na/Nb', $key);
854
+ $key = array($temp['a'], $temp['b']);
855
+ $msb = array(
856
+ ($key[0] >> 31) & 1,
857
+ ($key[1] >> 31) & 1
858
+ );
859
+ $key[0] &= 0x7FFFFFFF;
860
+ $key[1] &= 0x7FFFFFFF;
861
+
862
+ $key = array(
863
+ (($key[1] & 0x00000002) << 26) | (($key[1] & 0x00000204) << 17) |
864
+ (($key[1] & 0x00020408) << 8) | (($key[1] & 0x02040800) >> 1) |
865
+ (($key[0] & 0x00000002) << 22) | (($key[0] & 0x00000204) << 13) |
866
+ (($key[0] & 0x00020408) << 4) | (($key[0] & 0x02040800) >> 5) |
867
+ (($key[1] & 0x04080000) >> 10) | (($key[0] & 0x04080000) >> 14) |
868
+ (($key[1] & 0x08000000) >> 19) | (($key[0] & 0x08000000) >> 23) |
869
+ (($key[0] & 0x00000010) >> 1) | (($key[0] & 0x00001000) >> 10) |
870
+ (($key[0] & 0x00100000) >> 19) | (($key[0] & 0x10000000) >> 28)
871
+ ,
872
+ (($key[1] & 0x00000080) << 20) | (($key[1] & 0x00008000) << 11) |
873
+ (($key[1] & 0x00800000) << 2) | (($key[0] & 0x00000080) << 16) |
874
+ (($key[0] & 0x00008000) << 7) | (($key[0] & 0x00800000) >> 2) |
875
+ (($key[1] & 0x00000040) << 13) | (($key[1] & 0x00004000) << 4) |
876
+ (($key[1] & 0x00400000) >> 5) | (($key[1] & 0x40000000) >> 14) |
877
+ (($key[0] & 0x00000040) << 9) | ( $key[0] & 0x00004000 ) |
878
+ (($key[0] & 0x00400000) >> 9) | (($key[0] & 0x40000000) >> 18) |
879
+ (($key[1] & 0x00000020) << 6) | (($key[1] & 0x00002000) >> 3) |
880
+ (($key[1] & 0x00200000) >> 12) | (($key[1] & 0x20000000) >> 21) |
881
+ (($key[0] & 0x00000020) << 2) | (($key[0] & 0x00002000) >> 7) |
882
+ (($key[0] & 0x00200000) >> 16) | (($key[0] & 0x20000000) >> 25) |
883
+ (($key[1] & 0x00000010) >> 1) | (($key[1] & 0x00001000) >> 10) |
884
+ (($key[1] & 0x00100000) >> 19) | (($key[1] & 0x10000000) >> 28) |
885
+ ($msb[1] << 24) | ($msb[0] << 20)
886
+ );
887
+
888
+ $keys = array();
889
+ for ($i = 0; $i < 16; $i++) {
890
+ $key[0] <<= $shifts[$i];
891
+ $temp = ($key[0] & 0xF0000000) >> 28;
892
+ $key[0] = ($key[0] | $temp) & 0x0FFFFFFF;
893
+
894
+ $key[1] <<= $shifts[$i];
895
+ $temp = ($key[1] & 0xF0000000) >> 28;
896
+ $key[1] = ($key[1] | $temp) & 0x0FFFFFFF;
897
+
898
+ $temp = array(
899
+ (($key[1] & 0x00004000) >> 9) | (($key[1] & 0x00000800) >> 7) |
900
+ (($key[1] & 0x00020000) >> 14) | (($key[1] & 0x00000010) >> 2) |
901
+ (($key[1] & 0x08000000) >> 26) | (($key[1] & 0x00800000) >> 23)
902
+ ,
903
+ (($key[1] & 0x02400000) >> 20) | (($key[1] & 0x00000001) << 4) |
904
+ (($key[1] & 0x00002000) >> 10) | (($key[1] & 0x00040000) >> 18) |
905
+ (($key[1] & 0x00000080) >> 6)
906
+ ,
907
+ ( $key[1] & 0x00000020 ) | (($key[1] & 0x00000200) >> 5) |
908
+ (($key[1] & 0x00010000) >> 13) | (($key[1] & 0x01000000) >> 22) |
909
+ (($key[1] & 0x00000004) >> 1) | (($key[1] & 0x00100000) >> 20)
910
+ ,
911
+ (($key[1] & 0x00001000) >> 7) | (($key[1] & 0x00200000) >> 17) |
912
+ (($key[1] & 0x00000002) << 2) | (($key[1] & 0x00000100) >> 6) |
913
+ (($key[1] & 0x00008000) >> 14) | (($key[1] & 0x04000000) >> 26)
914
+ ,
915
+ (($key[0] & 0x00008000) >> 10) | ( $key[0] & 0x00000010 ) |
916
+ (($key[0] & 0x02000000) >> 22) | (($key[0] & 0x00080000) >> 17) |
917
+ (($key[0] & 0x00000200) >> 8) | (($key[0] & 0x00000002) >> 1)
918
+ ,
919
+ (($key[0] & 0x04000000) >> 21) | (($key[0] & 0x00010000) >> 12) |
920
+ (($key[0] & 0x00000020) >> 2) | (($key[0] & 0x00000800) >> 9) |
921
+ (($key[0] & 0x00800000) >> 22) | (($key[0] & 0x00000100) >> 8)
922
+ ,
923
+ (($key[0] & 0x00001000) >> 7) | (($key[0] & 0x00000088) >> 3) |
924
+ (($key[0] & 0x00020000) >> 14) | (($key[0] & 0x00000001) << 2) |
925
+ (($key[0] & 0x00400000) >> 21)
926
+ ,
927
+ (($key[0] & 0x00000400) >> 5) | (($key[0] & 0x00004000) >> 10) |
928
+ (($key[0] & 0x00000040) >> 3) | (($key[0] & 0x00100000) >> 18) |
929
+ (($key[0] & 0x08000000) >> 26) | (($key[0] & 0x01000000) >> 24)
930
+ );
931
+
932
+ $keys[] = $temp;
933
+ }
934
+
935
+ $temp = array(
936
+ CRYPT_DES_ENCRYPT => $keys,
937
+ CRYPT_DES_DECRYPT => array_reverse($keys)
938
+ );
939
+
940
+ return $temp;
941
+ }
942
+ }
943
+
944
+ // vim: ts=4:sw=4:et:
945
+ // vim6: fdl=1:
app/code/local/Wisepricer/Syncer/lib/phpseclib/Crypt/Hash.php CHANGED
@@ -1,816 +1,816 @@
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: This library is free software; you can redistribute it and/or
33
- * modify it under the terms of the GNU Lesser General Public
34
- * License as published by the Free Software Foundation; either
35
- * version 2.1 of the License, or (at your option) any later version.
36
- *
37
- * This library is distributed in the hope that it will be useful,
38
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
39
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
40
- * Lesser General Public License for more details.
41
- *
42
- * You should have received a copy of the GNU Lesser General Public
43
- * License along with this library; if not, write to the Free Software
44
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
45
- * MA 02111-1307 USA
46
- *
47
- * @category Crypt
48
- * @package Crypt_Hash
49
- * @author Jim Wigginton <terrafrost@php.net>
50
- * @copyright MMVII Jim Wigginton
51
- * @license http://www.gnu.org/licenses/lgpl.txt
52
- * @version $Id: Hash.php,v 1.6 2009/11/23 23:37:07 terrafrost Exp $
53
- * @link http://phpseclib.sourceforge.net
54
- */
55
-
56
- /**#@+
57
- * @access private
58
- * @see Crypt_Hash::Crypt_Hash()
59
- */
60
- /**
61
- * Toggles the internal implementation
62
- */
63
- define('CRYPT_HASH_MODE_INTERNAL', 1);
64
- /**
65
- * Toggles the mhash() implementation, which has been deprecated on PHP 5.3.0+.
66
- */
67
- define('CRYPT_HASH_MODE_MHASH', 2);
68
- /**
69
- * Toggles the hash() implementation, which works on PHP 5.1.2+.
70
- */
71
- define('CRYPT_HASH_MODE_HASH', 3);
72
- /**#@-*/
73
-
74
- /**
75
- * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
76
- *
77
- * @author Jim Wigginton <terrafrost@php.net>
78
- * @version 0.1.0
79
- * @access public
80
- * @package Crypt_Hash
81
- */
82
- class Crypt_Hash {
83
- /**
84
- * Byte-length of compression blocks / key (Internal HMAC)
85
- *
86
- * @see Crypt_Hash::setAlgorithm()
87
- * @var Integer
88
- * @access private
89
- */
90
- var $b;
91
-
92
- /**
93
- * Byte-length of hash output (Internal HMAC)
94
- *
95
- * @see Crypt_Hash::setHash()
96
- * @var Integer
97
- * @access private
98
- */
99
- var $l = false;
100
-
101
- /**
102
- * Hash Algorithm
103
- *
104
- * @see Crypt_Hash::setHash()
105
- * @var String
106
- * @access private
107
- */
108
- var $hash;
109
-
110
- /**
111
- * Key
112
- *
113
- * @see Crypt_Hash::setKey()
114
- * @var String
115
- * @access private
116
- */
117
- var $key = '';
118
-
119
- /**
120
- * Outer XOR (Internal HMAC)
121
- *
122
- * @see Crypt_Hash::setKey()
123
- * @var String
124
- * @access private
125
- */
126
- var $opad;
127
-
128
- /**
129
- * Inner XOR (Internal HMAC)
130
- *
131