SSH SFTP Updater Support - Version 0.6.1

Version Description

  • fix a few compatibility issues with 4.2
Download this release

Release Info

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

Code changes from version 0.5 to 0.6.1

phpseclib/Crypt/AES.php CHANGED
@@ -1,207 +1,197 @@
1
- <?php
2
-
3
- /**
4
- * Pure-PHP implementation of AES.
5
- *
6
- * Uses mcrypt, if available/possible, and an internal implementation, otherwise.
7
- *
8
- * PHP versions 4 and 5
9
- *
10
- * If {@link Crypt_AES::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
11
- * {@link Crypt_AES::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's 136-bits
12
- * it'll be null-padded to 192-bits and 192 bits will be the key length until {@link Crypt_AES::setKey() setKey()}
13
- * is called, again, at which point, it'll be recalculated.
14
- *
15
- * Since Crypt_AES extends Crypt_Rijndael, some functions are available to be called that, in the context of AES, don't
16
- * make a whole lot of sense. {@link Crypt_AES::setBlockLength() setBlockLength()}, for instance. Calling that function,
17
- * however possible, won't do anything (AES has a fixed block length whereas Rijndael has a variable one).
18
- *
19
- * Here's a short example of how to use this library:
20
- * <code>
21
- * <?php
22
- * include 'Crypt/AES.php';
23
- *
24
- * $aes = new Crypt_AES();
25
- *
26
- * $aes->setKey('abcdefghijklmnop');
27
- *
28
- * $size = 10 * 1024;
29
- * $plaintext = '';
30
- * for ($i = 0; $i < $size; $i++) {
31
- * $plaintext.= 'a';
32
- * }
33
- *
34
- * echo $aes->decrypt($aes->encrypt($plaintext));
35
- * ?>
36
- * </code>
37
- *
38
- * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
39
- * of this software and associated documentation files (the "Software"), to deal
40
- * in the Software without restriction, including without limitation the rights
41
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
42
- * copies of the Software, and to permit persons to whom the Software is
43
- * furnished to do so, subject to the following conditions:
44
- *
45
- * The above copyright notice and this permission notice shall be included in
46
- * all copies or substantial portions of the Software.
47
- *
48
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
49
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
50
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
51
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
52
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
53
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
54
- * THE SOFTWARE.
55
- *
56
- * @category Crypt
57
- * @package Crypt_AES
58
- * @author Jim Wigginton <terrafrost@php.net>
59
- * @copyright MMVIII Jim Wigginton
60
- * @license http://www.opensource.org/licenses/mit-license.html MIT License
61
- * @link http://phpseclib.sourceforge.net
62
- */
63
-
64
- /**
65
- * Include Crypt_Rijndael
66
- */
67
- if (!class_exists('Crypt_Rijndael')) {
68
- include_once 'Rijndael.php';
69
- }
70
-
71
- /**#@+
72
- * @access public
73
- * @see Crypt_AES::encrypt()
74
- * @see Crypt_AES::decrypt()
75
- */
76
- /**
77
- * Encrypt / decrypt using the Counter mode.
78
- *
79
- * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
80
- *
81
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
82
- */
83
- define('CRYPT_AES_MODE_CTR', CRYPT_MODE_CTR);
84
- /**
85
- * Encrypt / decrypt using the Electronic Code Book mode.
86
- *
87
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
88
- */
89
- define('CRYPT_AES_MODE_ECB', CRYPT_MODE_ECB);
90
- /**
91
- * Encrypt / decrypt using the Code Book Chaining mode.
92
- *
93
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
94
- */
95
- define('CRYPT_AES_MODE_CBC', CRYPT_MODE_CBC);
96
- /**
97
- * Encrypt / decrypt using the Cipher Feedback mode.
98
- *
99
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
100
- */
101
- define('CRYPT_AES_MODE_CFB', CRYPT_MODE_CFB);
102
- /**
103
- * Encrypt / decrypt using the Cipher Feedback mode.
104
- *
105
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
106
- */
107
- define('CRYPT_AES_MODE_OFB', CRYPT_MODE_OFB);
108
- /**#@-*/
109
-
110
- /**#@+
111
- * @access private
112
- * @see Crypt_Base::Crypt_Base()
113
- */
114
- /**
115
- * Toggles the internal implementation
116
- */
117
- define('CRYPT_AES_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
118
- /**
119
- * Toggles the mcrypt implementation
120
- */
121
- define('CRYPT_AES_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
122
- /**#@-*/
123
-
124
- /**
125
- * Pure-PHP implementation of AES.
126
- *
127
- * @package Crypt_AES
128
- * @author Jim Wigginton <terrafrost@php.net>
129
- * @access public
130
- */
131
- class Crypt_AES extends Crypt_Rijndael
132
- {
133
- /**
134
- * The namespace used by the cipher for its constants.
135
- *
136
- * @see Crypt_Base::const_namespace
137
- * @var String
138
- * @access private
139
- */
140
- var $const_namespace = 'AES';
141
-
142
- /**
143
- * Dummy function
144
- *
145
- * Since Crypt_AES extends Crypt_Rijndael, this function is, technically, available, but it doesn't do anything.
146
- *
147
- * @see Crypt_Rijndael::setBlockLength()
148
- * @access public
149
- * @param Integer $length
150
- */
151
- function setBlockLength($length)
152
- {
153
- return;
154
- }
155
-
156
- /**
157
- * Sets the key length
158
- *
159
- * Valid key lengths are 128, 192, and 256. If the length is less than 128, it will be rounded up to
160
- * 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount.
161
- *
162
- * @see Crypt_Rijndael:setKeyLength()
163
- * @access public
164
- * @param Integer $length
165
- */
166
- function setKeyLength($length)
167
- {
168
- switch ($length) {
169
- case 160:
170
- $length = 192;
171
- break;
172
- case 224:
173
- $length = 256;
174
- }
175
- parent::setKeyLength($length);
176
- }
177
-
178
- /**
179
- * Sets the key.
180
- *
181
- * Rijndael supports five different key lengths, AES only supports three.
182
- *
183
- * @see Crypt_Rijndael:setKey()
184
- * @see setKeyLength()
185
- * @access public
186
- * @param String $key
187
- */
188
- function setKey($key)
189
- {
190
- parent::setKey($key);
191
-
192
- if (!$this->explicit_key_length) {
193
- $length = strlen($key);
194
- switch (true) {
195
- case $length <= 16:
196
- $this->key_size = 16;
197
- break;
198
- case $length <= 24:
199
- $this->key_size = 24;
200
- break;
201
- default:
202
- $this->key_size = 32;
203
- }
204
- $this->_setupEngine();
205
- }
206
- }
207
- }
1
+ <?php
2
+
3
+ /**
4
+ * Pure-PHP implementation of AES.
5
+ *
6
+ * Uses mcrypt, if available/possible, and an internal implementation, otherwise.
7
+ *
8
+ * PHP versions 4 and 5
9
+ *
10
+ * NOTE: Since AES.php is (for compatibility and phpseclib-historical reasons) virtually
11
+ * just a wrapper to Rijndael.php you may consider using Rijndael.php instead of
12
+ * to save one include_once().
13
+ *
14
+ * If {@link Crypt_AES::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
15
+ * {@link Crypt_AES::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's 136-bits
16
+ * it'll be null-padded to 192-bits and 192 bits will be the key length until {@link Crypt_AES::setKey() setKey()}
17
+ * is called, again, at which point, it'll be recalculated.
18
+ *
19
+ * Since Crypt_AES extends Crypt_Rijndael, some functions are available to be called that, in the context of AES, don't
20
+ * make a whole lot of sense. {@link Crypt_AES::setBlockLength() setBlockLength()}, for instance. Calling that function,
21
+ * however possible, won't do anything (AES has a fixed block length whereas Rijndael has a variable one).
22
+ *
23
+ * Here's a short example of how to use this library:
24
+ * <code>
25
+ * <?php
26
+ * include 'Crypt/AES.php';
27
+ *
28
+ * $aes = new Crypt_AES();
29
+ *
30
+ * $aes->setKey('abcdefghijklmnop');
31
+ *
32
+ * $size = 10 * 1024;
33
+ * $plaintext = '';
34
+ * for ($i = 0; $i < $size; $i++) {
35
+ * $plaintext.= 'a';
36
+ * }
37
+ *
38
+ * echo $aes->decrypt($aes->encrypt($plaintext));
39
+ * ?>
40
+ * </code>
41
+ *
42
+ * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
43
+ * of this software and associated documentation files (the "Software"), to deal
44
+ * in the Software without restriction, including without limitation the rights
45
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
46
+ * copies of the Software, and to permit persons to whom the Software is
47
+ * furnished to do so, subject to the following conditions:
48
+ *
49
+ * The above copyright notice and this permission notice shall be included in
50
+ * all copies or substantial portions of the Software.
51
+ *
52
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
53
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
54
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
55
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
56
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
57
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
58
+ * THE SOFTWARE.
59
+ *
60
+ * @category Crypt
61
+ * @package Crypt_AES
62
+ * @author Jim Wigginton <terrafrost@php.net>
63
+ * @copyright 2008 Jim Wigginton
64
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
65
+ * @link http://phpseclib.sourceforge.net
66
+ */
67
+
68
+ /**
69
+ * Include Crypt_Rijndael
70
+ */
71
+ if (!class_exists('Crypt_Rijndael')) {
72
+ include_once 'Rijndael.php';
73
+ }
74
+
75
+ /**#@+
76
+ * @access public
77
+ * @see Crypt_AES::encrypt()
78
+ * @see Crypt_AES::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_AES_MODE_CTR', CRYPT_MODE_CTR);
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_AES_MODE_ECB', CRYPT_MODE_ECB);
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_AES_MODE_CBC', CRYPT_MODE_CBC);
100
+ /**
101
+ * Encrypt / decrypt using the Cipher Feedback mode.
102
+ *
103
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
104
+ */
105
+ define('CRYPT_AES_MODE_CFB', CRYPT_MODE_CFB);
106
+ /**
107
+ * Encrypt / decrypt using the Cipher Feedback mode.
108
+ *
109
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
110
+ */
111
+ define('CRYPT_AES_MODE_OFB', CRYPT_MODE_OFB);
112
+ /**#@-*/
113
+
114
+ /**
115
+ * Pure-PHP implementation of AES.
116
+ *
117
+ * @package Crypt_AES
118
+ * @author Jim Wigginton <terrafrost@php.net>
119
+ * @access public
120
+ */
121
+ class Crypt_AES extends Crypt_Rijndael
122
+ {
123
+ /**
124
+ * The namespace used by the cipher for its constants.
125
+ *
126
+ * @see Crypt_Base::const_namespace
127
+ * @var String
128
+ * @access private
129
+ */
130
+ var $const_namespace = 'AES';
131
+
132
+ /**
133
+ * Dummy function
134
+ *
135
+ * Since Crypt_AES extends Crypt_Rijndael, this function is, technically, available, but it doesn't do anything.
136
+ *
137
+ * @see Crypt_Rijndael::setBlockLength()
138
+ * @access public
139
+ * @param Integer $length
140
+ */
141
+ function setBlockLength($length)
142
+ {
143
+ return;
144
+ }
145
+
146
+ /**
147
+ * Sets the key length
148
+ *
149
+ * Valid key lengths are 128, 192, and 256. If the length is less than 128, it will be rounded up to
150
+ * 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount.
151
+ *
152
+ * @see Crypt_Rijndael:setKeyLength()
153
+ * @access public
154
+ * @param Integer $length
155
+ */
156
+ function setKeyLength($length)
157
+ {
158
+ switch ($length) {
159
+ case 160:
160
+ $length = 192;
161
+ break;
162
+ case 224:
163
+ $length = 256;
164
+ }
165
+ parent::setKeyLength($length);
166
+ }
167
+
168
+ /**
169
+ * Sets the key.
170
+ *
171
+ * Rijndael supports five different key lengths, AES only supports three.
172
+ *
173
+ * @see Crypt_Rijndael:setKey()
174
+ * @see setKeyLength()
175
+ * @access public
176
+ * @param String $key
177
+ */
178
+ function setKey($key)
179
+ {
180
+ parent::setKey($key);
181
+
182
+ if (!$this->explicit_key_length) {
183
+ $length = strlen($key);
184
+ switch (true) {
185
+ case $length <= 16:
186
+ $this->key_size = 16;
187
+ break;
188
+ case $length <= 24:
189
+ $this->key_size = 24;
190
+ break;
191
+ default:
192
+ $this->key_size = 32;
193
+ }
194
+ $this->_setEngine();
195
+ }
196
+ }
197
+ }
 
 
 
 
 
 
 
 
 
 
phpseclib/Crypt/Base.php CHANGED
@@ -1,2011 +1,2539 @@
1
- <?php
2
-
3
- /**
4
- * Base Class for all Crypt_* cipher classes
5
- *
6
- * PHP versions 4 and 5
7
- *
8
- * Internally for phpseclib developers:
9
- * If you plan to add a new cipher class, please note following rules:
10
- *
11
- * - The new Crypt_* cipher class should extend Crypt_Base
12
- *
13
- * - Following methods are then required to be overridden/overloaded:
14
- *
15
- * - _encryptBlock()
16
- *
17
- * - _decryptBlock()
18
- *
19
- * - _setupKey()
20
- *
21
- * - All other methods are optional to be overridden/overloaded
22
- *
23
- * - Look at the source code of the current ciphers how they extend Crypt_Base
24
- * and take one of them as a start up for the new cipher class.
25
- *
26
- * - Please read all the other comments/notes/hints here also for each class var/method
27
- *
28
- * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
29
- * of this software and associated documentation files (the "Software"), to deal
30
- * in the Software without restriction, including without limitation the rights
31
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
32
- * copies of the Software, and to permit persons to whom the Software is
33
- * furnished to do so, subject to the following conditions:
34
- *
35
- * The above copyright notice and this permission notice shall be included in
36
- * all copies or substantial portions of the Software.
37
- *
38
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
39
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
40
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
41
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
42
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
43
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
44
- * THE SOFTWARE.
45
- *
46
- * @category Crypt
47
- * @package Crypt_Base
48
- * @author Jim Wigginton <terrafrost@php.net>
49
- * @author Hans-Juergen Petrich <petrich@tronic-media.com>
50
- * @copyright MMVII Jim Wigginton
51
- * @license http://www.opensource.org/licenses/mit-license.html MIT License
52
- * @link http://phpseclib.sourceforge.net
53
- */
54
-
55
- /**#@+
56
- * @access public
57
- * @see Crypt_Base::encrypt()
58
- * @see Crypt_Base::decrypt()
59
- */
60
- /**
61
- * Encrypt / decrypt using the Counter mode.
62
- *
63
- * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
64
- *
65
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
66
- */
67
- define('CRYPT_MODE_CTR', -1);
68
- /**
69
- * Encrypt / decrypt using the Electronic Code Book mode.
70
- *
71
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
72
- */
73
- define('CRYPT_MODE_ECB', 1);
74
- /**
75
- * Encrypt / decrypt using the Code Book Chaining mode.
76
- *
77
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
78
- */
79
- define('CRYPT_MODE_CBC', 2);
80
- /**
81
- * Encrypt / decrypt using the Cipher Feedback mode.
82
- *
83
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
84
- */
85
- define('CRYPT_MODE_CFB', 3);
86
- /**
87
- * Encrypt / decrypt using the Output Feedback mode.
88
- *
89
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
90
- */
91
- define('CRYPT_MODE_OFB', 4);
92
- /**
93
- * Encrypt / decrypt using streaming mode.
94
- *
95
- */
96
- define('CRYPT_MODE_STREAM', 5);
97
- /**#@-*/
98
-
99
- /**#@+
100
- * @access private
101
- * @see Crypt_Base::Crypt_Base()
102
- */
103
- /**
104
- * Base value for the internal implementation $engine switch
105
- */
106
- define('CRYPT_MODE_INTERNAL', 1);
107
- /**
108
- * Base value for the mcrypt implementation $engine switch
109
- */
110
- define('CRYPT_MODE_MCRYPT', 2);
111
- /**#@-*/
112
-
113
- /**
114
- * Base Class for all Crypt_* cipher classes
115
- *
116
- * @package Crypt_Base
117
- * @author Jim Wigginton <terrafrost@php.net>
118
- * @author Hans-Juergen Petrich <petrich@tronic-media.com>
119
- * @access public
120
- */
121
- class Crypt_Base
122
- {
123
- /**
124
- * The Encryption Mode
125
- *
126
- * @see Crypt_Base::Crypt_Base()
127
- * @var Integer
128
- * @access private
129
- */
130
- var $mode;
131
-
132
- /**
133
- * The Block Length of the block cipher
134
- *
135
- * @var Integer
136
- * @access private
137
- */
138
- var $block_size = 16;
139
-
140
- /**
141
- * The Key
142
- *
143
- * @see Crypt_Base::setKey()
144
- * @var String
145
- * @access private
146
- */
147
- var $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
148
-
149
- /**
150
- * The Initialization Vector
151
- *
152
- * @see Crypt_Base::setIV()
153
- * @var String
154
- * @access private
155
- */
156
- var $iv;
157
-
158
- /**
159
- * A "sliding" Initialization Vector
160
- *
161
- * @see Crypt_Base::enableContinuousBuffer()
162
- * @see Crypt_Base::_clearBuffers()
163
- * @var String
164
- * @access private
165
- */
166
- var $encryptIV;
167
-
168
- /**
169
- * A "sliding" Initialization Vector
170
- *
171
- * @see Crypt_Base::enableContinuousBuffer()
172
- * @see Crypt_Base::_clearBuffers()
173
- * @var String
174
- * @access private
175
- */
176
- var $decryptIV;
177
-
178
- /**
179
- * Continuous Buffer status
180
- *
181
- * @see Crypt_Base::enableContinuousBuffer()
182
- * @var Boolean
183
- * @access private
184
- */
185
- var $continuousBuffer = false;
186
-
187
- /**
188
- * Encryption buffer for CTR, OFB and CFB modes
189
- *
190
- * @see Crypt_Base::encrypt()
191
- * @see Crypt_Base::_clearBuffers()
192
- * @var Array
193
- * @access private
194
- */
195
- var $enbuffer;
196
-
197
- /**
198
- * Decryption buffer for CTR, OFB and CFB modes
199
- *
200
- * @see Crypt_Base::decrypt()
201
- * @see Crypt_Base::_clearBuffers()
202
- * @var Array
203
- * @access private
204
- */
205
- var $debuffer;
206
-
207
- /**
208
- * mcrypt resource for encryption
209
- *
210
- * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
211
- * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
212
- *
213
- * @see Crypt_Base::encrypt()
214
- * @var Resource
215
- * @access private
216
- */
217
- var $enmcrypt;
218
-
219
- /**
220
- * mcrypt resource for decryption
221
- *
222
- * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
223
- * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
224
- *
225
- * @see Crypt_Base::decrypt()
226
- * @var Resource
227
- * @access private
228
- */
229
- var $demcrypt;
230
-
231
- /**
232
- * Does the enmcrypt resource need to be (re)initialized?
233
- *
234
- * @see Crypt_Twofish::setKey()
235
- * @see Crypt_Twofish::setIV()
236
- * @var Boolean
237
- * @access private
238
- */
239
- var $enchanged = true;
240
-
241
- /**
242
- * Does the demcrypt resource need to be (re)initialized?
243
- *
244
- * @see Crypt_Twofish::setKey()
245
- * @see Crypt_Twofish::setIV()
246
- * @var Boolean
247
- * @access private
248
- */
249
- var $dechanged = true;
250
-
251
- /**
252
- * mcrypt resource for CFB mode
253
- *
254
- * mcrypt's CFB mode, in (and only in) buffered context,
255
- * is broken, so phpseclib implements the CFB mode by it self,
256
- * even when the mcrypt php extension is available.
257
- *
258
- * In order to do the CFB-mode work (fast) phpseclib
259
- * use a separate ECB-mode mcrypt resource.
260
- *
261
- * @link http://phpseclib.sourceforge.net/cfb-demo.phps
262
- * @see Crypt_Base::encrypt()
263
- * @see Crypt_Base::decrypt()
264
- * @see Crypt_Base::_setupMcrypt()
265
- * @var Resource
266
- * @access private
267
- */
268
- var $ecb;
269
-
270
- /**
271
- * Optimizing value while CFB-encrypting
272
- *
273
- * Only relevant if $continuousBuffer enabled
274
- * and $engine == CRYPT_MODE_MCRYPT
275
- *
276
- * It's faster to re-init $enmcrypt if
277
- * $buffer bytes > $cfb_init_len than
278
- * using the $ecb resource furthermore.
279
- *
280
- * This value depends of the chosen cipher
281
- * and the time it would be needed for it's
282
- * initialization [by mcrypt_generic_init()]
283
- * which, typically, depends on the complexity
284
- * on its internaly Key-expanding algorithm.
285
- *
286
- * @see Crypt_Base::encrypt()
287
- * @var Integer
288
- * @access private
289
- */
290
- var $cfb_init_len = 600;
291
-
292
- /**
293
- * Does internal cipher state need to be (re)initialized?
294
- *
295
- * @see setKey()
296
- * @see setIV()
297
- * @see disableContinuousBuffer()
298
- * @var Boolean
299
- * @access private
300
- */
301
- var $changed = true;
302
-
303
- /**
304
- * Padding status
305
- *
306
- * @see Crypt_Base::enablePadding()
307
- * @var Boolean
308
- * @access private
309
- */
310
- var $padding = true;
311
-
312
- /**
313
- * Is the mode one that is paddable?
314
- *
315
- * @see Crypt_Base::Crypt_Base()
316
- * @var Boolean
317
- * @access private
318
- */
319
- var $paddable = false;
320
-
321
- /**
322
- * Holds which crypt engine internaly should be use,
323
- * which will be determined automatically on __construct()
324
- *
325
- * Currently available $engines are:
326
- * - CRYPT_MODE_MCRYPT (fast, php-extension: mcrypt, extension_loaded('mcrypt') required)
327
- * - CRYPT_MODE_INTERNAL (slower, pure php-engine, no php-extension required)
328
- *
329
- * In the pipeline... maybe. But currently not available:
330
- * - CRYPT_MODE_OPENSSL (very fast, php-extension: openssl, extension_loaded('openssl') required)
331
- *
332
- * If possible, CRYPT_MODE_MCRYPT will be used for each cipher.
333
- * Otherwise CRYPT_MODE_INTERNAL
334
- *
335
- * @see Crypt_Base::encrypt()
336
- * @see Crypt_Base::decrypt()
337
- * @var Integer
338
- * @access private
339
- */
340
- var $engine;
341
-
342
- /**
343
- * The mcrypt specific name of the cipher
344
- *
345
- * Only used if $engine == CRYPT_MODE_MCRYPT
346
- *
347
- * @link http://www.php.net/mcrypt_module_open
348
- * @link http://www.php.net/mcrypt_list_algorithms
349
- * @see Crypt_Base::_setupMcrypt()
350
- * @var String
351
- * @access private
352
- */
353
- var $cipher_name_mcrypt;
354
-
355
- /**
356
- * The default password key_size used by setPassword()
357
- *
358
- * @see Crypt_Base::setPassword()
359
- * @var Integer
360
- * @access private
361
- */
362
- var $password_key_size = 32;
363
-
364
- /**
365
- * The default salt used by setPassword()
366
- *
367
- * @see Crypt_Base::setPassword()
368
- * @var String
369
- * @access private
370
- */
371
- var $password_default_salt = 'phpseclib/salt';
372
-
373
- /**
374
- * The namespace used by the cipher for its constants.
375
- *
376
- * ie: AES.php is using CRYPT_AES_MODE_* for its constants
377
- * so $const_namespace is AES
378
- *
379
- * DES.php is using CRYPT_DES_MODE_* for its constants
380
- * so $const_namespace is DES... and so on
381
- *
382
- * All CRYPT_<$const_namespace>_MODE_* are aliases of
383
- * the generic CRYPT_MODE_* constants, so both could be used
384
- * for each cipher.
385
- *
386
- * Example:
387
- * $aes = new Crypt_AES(CRYPT_AES_MODE_CFB); // $aes will operate in cfb mode
388
- * $aes = new Crypt_AES(CRYPT_MODE_CFB); // identical
389
- *
390
- * @see Crypt_Base::Crypt_Base()
391
- * @var String
392
- * @access private
393
- */
394
- var $const_namespace;
395
-
396
- /**
397
- * The name of the performance-optimized callback function
398
- *
399
- * Used by encrypt() / decrypt()
400
- * only if $engine == CRYPT_MODE_INTERNAL
401
- *
402
- * @see Crypt_Base::encrypt()
403
- * @see Crypt_Base::decrypt()
404
- * @see Crypt_Base::_setupInlineCrypt()
405
- * @see Crypt_Base::$use_inline_crypt
406
- * @var Callback
407
- * @access private
408
- */
409
- var $inline_crypt;
410
-
411
- /**
412
- * Holds whether performance-optimized $inline_crypt() can/should be used.
413
- *
414
- * @see Crypt_Base::encrypt()
415
- * @see Crypt_Base::decrypt()
416
- * @see Crypt_Base::inline_crypt
417
- * @var mixed
418
- * @access private
419
- */
420
- var $use_inline_crypt;
421
-
422
- /**
423
- * Default Constructor.
424
- *
425
- * Determines whether or not the mcrypt extension should be used.
426
- *
427
- * $mode could be:
428
- *
429
- * - CRYPT_MODE_ECB
430
- *
431
- * - CRYPT_MODE_CBC
432
- *
433
- * - CRYPT_MODE_CTR
434
- *
435
- * - CRYPT_MODE_CFB
436
- *
437
- * - CRYPT_MODE_OFB
438
- *
439
- * (or the alias constants of the chosen cipher, for example for AES: CRYPT_AES_MODE_ECB or CRYPT_AES_MODE_CBC ...)
440
- *
441
- * If not explicitly set, CRYPT_MODE_CBC will be used.
442
- *
443
- * @param optional Integer $mode
444
- * @access public
445
- */
446
- function Crypt_Base($mode = CRYPT_MODE_CBC)
447
- {
448
- $const_crypt_mode = 'CRYPT_' . $this->const_namespace . '_MODE';
449
-
450
- // Determining the availibility of mcrypt support for the cipher
451
- if (!defined($const_crypt_mode)) {
452
- switch (true) {
453
- case extension_loaded('mcrypt') && in_array($this->cipher_name_mcrypt, mcrypt_list_algorithms()):
454
- define($const_crypt_mode, CRYPT_MODE_MCRYPT);
455
- break;
456
- default:
457
- define($const_crypt_mode, CRYPT_MODE_INTERNAL);
458
- }
459
- }
460
-
461
- // Determining which internal $engine should be used.
462
- // The fastes possible first.
463
- switch (true) {
464
- case empty($this->cipher_name_mcrypt): // The cipher module has no mcrypt-engine support at all so we force CRYPT_MODE_INTERNAL
465
- $this->engine = CRYPT_MODE_INTERNAL;
466
- break;
467
- case constant($const_crypt_mode) == CRYPT_MODE_MCRYPT:
468
- $this->engine = CRYPT_MODE_MCRYPT;
469
- break;
470
- default:
471
- $this->engine = CRYPT_MODE_INTERNAL;
472
- }
473
-
474
- // $mode dependent settings
475
- switch ($mode) {
476
- case CRYPT_MODE_ECB:
477
- $this->paddable = true;
478
- $this->mode = $mode;
479
- break;
480
- case CRYPT_MODE_CTR:
481
- case CRYPT_MODE_CFB:
482
- case CRYPT_MODE_OFB:
483
- case CRYPT_MODE_STREAM:
484
- $this->mode = $mode;
485
- break;
486
- case CRYPT_MODE_CBC:
487
- default:
488
- $this->paddable = true;
489
- $this->mode = CRYPT_MODE_CBC;
490
- }
491
-
492
- // Determining whether inline crypting can be used by the cipher
493
- if ($this->use_inline_crypt !== false && function_exists('create_function')) {
494
- $this->use_inline_crypt = true;
495
- }
496
- }
497
-
498
- /**
499
- * Sets the initialization vector. (optional)
500
- *
501
- * SetIV is not required when CRYPT_MODE_ECB (or ie for AES: CRYPT_AES_MODE_ECB) is being used. If not explicitly set, it'll be assumed
502
- * to be all zero's.
503
- *
504
- * Note: Could, but not must, extend by the child Crypt_* class
505
- *
506
- * @access public
507
- * @param String $iv
508
- */
509
- function setIV($iv)
510
- {
511
- if ($this->mode == CRYPT_MODE_ECB) {
512
- return;
513
- }
514
-
515
- $this->iv = $iv;
516
- $this->changed = true;
517
- }
518
-
519
- /**
520
- * Sets the key.
521
- *
522
- * The min/max length(s) of the key depends on the cipher which is used.
523
- * If the key not fits the length(s) of the cipher it will paded with null bytes
524
- * up to the closest valid key length. If the key is more than max length,
525
- * we trim the excess bits.
526
- *
527
- * If the key is not explicitly set, it'll be assumed to be all null bytes.
528
- *
529
- * Note: Could, but not must, extend by the child Crypt_* class
530
- *
531
- * @access public
532
- * @param String $key
533
- */
534
- function setKey($key)
535
- {
536
- $this->key = $key;
537
- $this->changed = true;
538
- }
539
-
540
- /**
541
- * Sets the password.
542
- *
543
- * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows:
544
- * {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2} or pbkdf1:
545
- * $hash, $salt, $count, $dkLen
546
- *
547
- * Where $hash (default = sha1) currently supports the following hashes: see: Crypt/Hash.php
548
- *
549
- * Note: Could, but not must, extend by the child Crypt_* class
550
- *
551
- * @see Crypt/Hash.php
552
- * @param String $password
553
- * @param optional String $method
554
- * @return Boolean
555
- * @access public
556
- */
557
- function setPassword($password, $method = 'pbkdf2')
558
- {
559
- $key = '';
560
-
561
- switch ($method) {
562
- default: // 'pbkdf2' or 'pbkdf1'
563
- $func_args = func_get_args();
564
-
565
- // Hash function
566
- $hash = isset($func_args[2]) ? $func_args[2] : 'sha1';
567
-
568
- // WPA and WPA2 use the SSID as the salt
569
- $salt = isset($func_args[3]) ? $func_args[3] : $this->password_default_salt;
570
-
571
- // RFC2898#section-4.2 uses 1,000 iterations by default
572
- // WPA and WPA2 use 4,096.
573
- $count = isset($func_args[4]) ? $func_args[4] : 1000;
574
-
575
- // Keylength
576
- if (isset($func_args[5])) {
577
- $dkLen = $func_args[5];
578
- } else {
579
- $dkLen = $method == 'pbkdf1' ? 2 * $this->password_key_size : $this->password_key_size;
580
- }
581
-
582
- switch (true) {
583
- case $method == 'pbkdf1':
584
- if (!class_exists('Crypt_Hash')) {
585
- include_once 'Crypt/Hash.php';
586
- }
587
- $hashObj = new Crypt_Hash();
588
- $hashObj->setHash($hash);
589
- if ($dkLen > $hashObj->getLength()) {
590
- user_error('Derived key too long');
591
- return false;
592
- }
593
- $t = $password . $salt;
594
- for ($i = 0; $i < $count; ++$i) {
595
- $t = $hashObj->hash($t);
596
- }
597
- $key = substr($t, 0, $dkLen);
598
-
599
- $this->setKey(substr($key, 0, $dkLen >> 1));
600
- $this->setIV(substr($key, $dkLen >> 1));
601
-
602
- return true;
603
- // Determining if php[>=5.5.0]'s hash_pbkdf2() function avail- and useable
604
- case !function_exists('hash_pbkdf2'):
605
- case !function_exists('hash_algos'):
606
- case !in_array($hash, hash_algos()):
607
- if (!class_exists('Crypt_Hash')) {
608
- include_once 'Crypt/Hash.php';
609
- }
610
- $i = 1;
611
- while (strlen($key) < $dkLen) {
612
- $hmac = new Crypt_Hash();
613
- $hmac->setHash($hash);
614
- $hmac->setKey($password);
615
- $f = $u = $hmac->hash($salt . pack('N', $i++));
616
- for ($j = 2; $j <= $count; ++$j) {
617
- $u = $hmac->hash($u);
618
- $f^= $u;
619
- }
620
- $key.= $f;
621
- }
622
- $key = substr($key, 0, $dkLen);
623
- break;
624
- default:
625
- $key = hash_pbkdf2($hash, $password, $salt, $count, $dkLen, true);
626
- }
627
- }
628
-
629
- $this->setKey($key);
630
-
631
- return true;
632
- }
633
-
634
- /**
635
- * Encrypts a message.
636
- *
637
- * $plaintext will be padded with additional bytes such that it's length is a multiple of the block size. Other cipher
638
- * implementations may or may not pad in the same manner. Other common approaches to padding and the reasons why it's
639
- * necessary are discussed in the following
640
- * URL:
641
- *
642
- * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
643
- *
644
- * An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does.
645
- * strlen($plaintext) will still need to be a multiple of the block size, however, arbitrary values can be added to make it that
646
- * length.
647
- *
648
- * Note: Could, but not must, extend by the child Crypt_* class
649
- *
650
- * @see Crypt_Base::decrypt()
651
- * @access public
652
- * @param String $plaintext
653
- * @return String $cipertext
654
- */
655
- function encrypt($plaintext)
656
- {
657
- if ($this->engine == CRYPT_MODE_MCRYPT) {
658
- if ($this->changed) {
659
- $this->_setupMcrypt();
660
- $this->changed = false;
661
- }
662
- if ($this->enchanged) {
663
- mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
664
- $this->enchanged = false;
665
- }
666
-
667
- // re: {@link http://phpseclib.sourceforge.net/cfb-demo.phps}
668
- // using mcrypt's default handing of CFB the above would output two different things. using phpseclib's
669
- // rewritten CFB implementation the above outputs the same thing twice.
670
- if ($this->mode == CRYPT_MODE_CFB && $this->continuousBuffer) {
671
- $block_size = $this->block_size;
672
- $iv = &$this->encryptIV;
673
- $pos = &$this->enbuffer['pos'];
674
- $len = strlen($plaintext);
675
- $ciphertext = '';
676
- $i = 0;
677
- if ($pos) {
678
- $orig_pos = $pos;
679
- $max = $block_size - $pos;
680
- if ($len >= $max) {
681
- $i = $max;
682
- $len-= $max;
683
- $pos = 0;
684
- } else {
685
- $i = $len;
686
- $pos+= $len;
687
- $len = 0;
688
- }
689
- $ciphertext = substr($iv, $orig_pos) ^ $plaintext;
690
- $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
691
- $this->enbuffer['enmcrypt_init'] = true;
692
- }
693
- if ($len >= $block_size) {
694
- if ($this->enbuffer['enmcrypt_init'] === false || $len > $this->cfb_init_len) {
695
- if ($this->enbuffer['enmcrypt_init'] === true) {
696
- mcrypt_generic_init($this->enmcrypt, $this->key, $iv);
697
- $this->enbuffer['enmcrypt_init'] = false;
698
- }
699
- $ciphertext.= mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % $block_size));
700
- $iv = substr($ciphertext, -$block_size);
701
- $len%= $block_size;
702
- } else {
703
- while ($len >= $block_size) {
704
- $iv = mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, $block_size);
705
- $ciphertext.= $iv;
706
- $len-= $block_size;
707
- $i+= $block_size;
708
- }
709
- }
710
- }
711
-
712
- if ($len) {
713
- $iv = mcrypt_generic($this->ecb, $iv);
714
- $block = $iv ^ substr($plaintext, -$len);
715
- $iv = substr_replace($iv, $block, 0, $len);
716
- $ciphertext.= $block;
717
- $pos = $len;
718
- }
719
-
720
- return $ciphertext;
721
- }
722
-
723
- if ($this->paddable) {
724
- $plaintext = $this->_pad($plaintext);
725
- }
726
-
727
- $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
728
-
729
- if (!$this->continuousBuffer) {
730
- mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
731
- }
732
-
733
- return $ciphertext;
734
- }
735
-
736
- if ($this->changed) {
737
- $this->_setup();
738
- $this->changed = false;
739
- }
740
- if ($this->use_inline_crypt) {
741
- $inline = $this->inline_crypt;
742
- return $inline('encrypt', $this, $plaintext);
743
- }
744
- if ($this->paddable) {
745
- $plaintext = $this->_pad($plaintext);
746
- }
747
-
748
- $buffer = &$this->enbuffer;
749
- $block_size = $this->block_size;
750
- $ciphertext = '';
751
- switch ($this->mode) {
752
- case CRYPT_MODE_ECB:
753
- for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
754
- $ciphertext.= $this->_encryptBlock(substr($plaintext, $i, $block_size));
755
- }
756
- break;
757
- case CRYPT_MODE_CBC:
758
- $xor = $this->encryptIV;
759
- for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
760
- $block = substr($plaintext, $i, $block_size);
761
- $block = $this->_encryptBlock($block ^ $xor);
762
- $xor = $block;
763
- $ciphertext.= $block;
764
- }
765
- if ($this->continuousBuffer) {
766
- $this->encryptIV = $xor;
767
- }
768
- break;
769
- case CRYPT_MODE_CTR:
770
- $xor = $this->encryptIV;
771
- if (strlen($buffer['encrypted'])) {
772
- for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
773
- $block = substr($plaintext, $i, $block_size);
774
- if (strlen($block) > strlen($buffer['encrypted'])) {
775
- $buffer['encrypted'].= $this->_encryptBlock($this->_generateXor($xor, $block_size));
776
- }
777
- $key = $this->_stringShift($buffer['encrypted'], $block_size);
778
- $ciphertext.= $block ^ $key;
779
- }
780
- } else {
781
- for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
782
- $block = substr($plaintext, $i, $block_size);
783
- $key = $this->_encryptBlock($this->_generateXor($xor, $block_size));
784
- $ciphertext.= $block ^ $key;
785
- }
786
- }
787
- if ($this->continuousBuffer) {
788
- $this->encryptIV = $xor;
789
- if ($start = strlen($plaintext) % $block_size) {
790
- $buffer['encrypted'] = substr($key, $start) . $buffer['encrypted'];
791
- }
792
- }
793
- break;
794
- case CRYPT_MODE_CFB:
795
- // cfb loosely routines inspired by openssl's:
796
- // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1}
797
- if ($this->continuousBuffer) {
798
- $iv = &$this->encryptIV;
799
- $pos = &$buffer['pos'];
800
- } else {
801
- $iv = $this->encryptIV;
802
- $pos = 0;
803
- }
804
- $len = strlen($plaintext);
805
- $i = 0;
806
- if ($pos) {
807
- $orig_pos = $pos;
808
- $max = $block_size - $pos;
809
- if ($len >= $max) {
810
- $i = $max;
811
- $len-= $max;
812
- $pos = 0;
813
- } else {
814
- $i = $len;
815
- $pos+= $len;
816
- $len = 0;
817
- }
818
- // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize
819
- $ciphertext = substr($iv, $orig_pos) ^ $plaintext;
820
- $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
821
- }
822
- while ($len >= $block_size) {
823
- $iv = $this->_encryptBlock($iv) ^ substr($plaintext, $i, $block_size);
824
- $ciphertext.= $iv;
825
- $len-= $block_size;
826
- $i+= $block_size;
827
- }
828
- if ($len) {
829
- $iv = $this->_encryptBlock($iv);
830
- $block = $iv ^ substr($plaintext, $i);
831
- $iv = substr_replace($iv, $block, 0, $len);
832
- $ciphertext.= $block;
833
- $pos = $len;
834
- }
835
- break;
836
- case CRYPT_MODE_OFB:
837
- $xor = $this->encryptIV;
838
- if (strlen($buffer['xor'])) {
839
- for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
840
- $block = substr($plaintext, $i, $block_size);
841
- if (strlen($block) > strlen($buffer['xor'])) {
842
- $xor = $this->_encryptBlock($xor);
843
- $buffer['xor'].= $xor;
844
- }
845
- $key = $this->_stringShift($buffer['xor'], $block_size);
846
- $ciphertext.= $block ^ $key;
847
- }
848
- } else {
849
- for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
850
- $xor = $this->_encryptBlock($xor);
851
- $ciphertext.= substr($plaintext, $i, $block_size) ^ $xor;
852
- }
853
- $key = $xor;
854
- }
855
- if ($this->continuousBuffer) {
856
- $this->encryptIV = $xor;
857
- if ($start = strlen($plaintext) % $block_size) {
858
- $buffer['xor'] = substr($key, $start) . $buffer['xor'];
859
- }
860
- }
861
- break;
862
- case CRYPT_MODE_STREAM:
863
- $ciphertext = $this->_encryptBlock($plaintext);
864
- break;
865
- }
866
-
867
- return $ciphertext;
868
- }
869
-
870
- /**
871
- * Decrypts a message.
872
- *
873
- * If strlen($ciphertext) is not a multiple of the block size, null bytes will be added to the end of the string until
874
- * it is.
875
- *
876
- * Note: Could, but not must, extend by the child Crypt_* class
877
- *
878
- * @see Crypt_Base::encrypt()
879
- * @access public
880
- * @param String $ciphertext
881
- * @return String $plaintext
882
- */
883
- function decrypt($ciphertext)
884
- {
885
- if ($this->engine == CRYPT_MODE_MCRYPT) {
886
- $block_size = $this->block_size;
887
- if ($this->changed) {
888
- $this->_setupMcrypt();
889
- $this->changed = false;
890
- }
891
- if ($this->dechanged) {
892
- mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
893
- $this->dechanged = false;
894
- }
895
-
896
- if ($this->mode == CRYPT_MODE_CFB && $this->continuousBuffer) {
897
- $iv = &$this->decryptIV;
898
- $pos = &$this->debuffer['pos'];
899
- $len = strlen($ciphertext);
900
- $plaintext = '';
901
- $i = 0;
902
- if ($pos) {
903
- $orig_pos = $pos;
904
- $max = $block_size - $pos;
905
- if ($len >= $max) {
906
- $i = $max;
907
- $len-= $max;
908
- $pos = 0;
909
- } else {
910
- $i = $len;
911
- $pos+= $len;
912
- $len = 0;
913
- }
914
- // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize
915
- $plaintext = substr($iv, $orig_pos) ^ $ciphertext;
916
- $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
917
- }
918
- if ($len >= $block_size) {
919
- $cb = substr($ciphertext, $i, $len - $len % $block_size);
920
- $plaintext.= mcrypt_generic($this->ecb, $iv . $cb) ^ $cb;
921
- $iv = substr($cb, -$block_size);
922
- $len%= $block_size;
923
- }
924
- if ($len) {
925
- $iv = mcrypt_generic($this->ecb, $iv);
926
- $plaintext.= $iv ^ substr($ciphertext, -$len);
927
- $iv = substr_replace($iv, substr($ciphertext, -$len), 0, $len);
928
- $pos = $len;
929
- }
930
-
931
- return $plaintext;
932
- }
933
-
934
- if ($this->paddable) {
935
- // we pad with chr(0) since that's what mcrypt_generic does. to quote from {@link http://www.php.net/function.mcrypt-generic}:
936
- // "The data is padded with "\0" to make sure the length of the data is n * blocksize."
937
- $ciphertext = str_pad($ciphertext, strlen($ciphertext) + ($block_size - strlen($ciphertext) % $block_size) % $block_size, chr(0));
938
- }
939
-
940
- $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
941
-
942
- if (!$this->continuousBuffer) {
943
- mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
944
- }
945
-
946
- return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
947
- }
948
-
949
- if ($this->changed) {
950
- $this->_setup();
951
- $this->changed = false;
952
- }
953
- if ($this->use_inline_crypt) {
954
- $inline = $this->inline_crypt;
955
- return $inline('decrypt', $this, $ciphertext);
956
- }
957
-
958
- $block_size = $this->block_size;
959
- if ($this->paddable) {
960
- // we pad with chr(0) since that's what mcrypt_generic does [...]
961
- $ciphertext = str_pad($ciphertext, strlen($ciphertext) + ($block_size - strlen($ciphertext) % $block_size) % $block_size, chr(0));
962
- }
963
-
964
- $buffer = &$this->debuffer;
965
- $plaintext = '';
966
- switch ($this->mode) {
967
- case CRYPT_MODE_ECB:
968
- for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
969
- $plaintext.= $this->_decryptBlock(substr($ciphertext, $i, $block_size));
970
- }
971
- break;
972
- case CRYPT_MODE_CBC:
973
- $xor = $this->decryptIV;
974
- for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
975
- $block = substr($ciphertext, $i, $block_size);
976
- $plaintext.= $this->_decryptBlock($block) ^ $xor;
977
- $xor = $block;
978
- }
979
- if ($this->continuousBuffer) {
980
- $this->decryptIV = $xor;
981
- }
982
- break;
983
- case CRYPT_MODE_CTR:
984
- $xor = $this->decryptIV;
985
- if (strlen($buffer['ciphertext'])) {
986
- for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
987
- $block = substr($ciphertext, $i, $block_size);
988
- if (strlen($block) > strlen($buffer['ciphertext'])) {
989
- $buffer['ciphertext'].= $this->_encryptBlock($this->_generateXor($xor, $block_size));
990
- }
991
- $key = $this->_stringShift($buffer['ciphertext'], $block_size);
992
- $plaintext.= $block ^ $key;
993
- }
994
- } else {
995
- for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
996
- $block = substr($ciphertext, $i, $block_size);
997
- $key = $this->_encryptBlock($this->_generateXor($xor, $block_size));
998
- $plaintext.= $block ^ $key;
999
- }
1000
- }
1001
- if ($this->continuousBuffer) {
1002
- $this->decryptIV = $xor;
1003
- if ($start = strlen($ciphertext) % $block_size) {
1004
- $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext'];
1005
- }
1006
- }
1007
- break;
1008
- case CRYPT_MODE_CFB:
1009
- if ($this->continuousBuffer) {
1010
- $iv = &$this->decryptIV;
1011
- $pos = &$buffer['pos'];
1012
- } else {
1013
- $iv = $this->decryptIV;
1014
- $pos = 0;
1015
- }
1016
- $len = strlen($ciphertext);
1017
- $i = 0;
1018
- if ($pos) {
1019
- $orig_pos = $pos;
1020
- $max = $block_size - $pos;
1021
- if ($len >= $max) {
1022
- $i = $max;
1023
- $len-= $max;
1024
- $pos = 0;
1025
- } else {
1026
- $i = $len;
1027
- $pos+= $len;
1028
- $len = 0;
1029
- }
1030
- // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize
1031
- $plaintext = substr($iv, $orig_pos) ^ $ciphertext;
1032
- $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
1033
- }
1034
- while ($len >= $block_size) {
1035
- $iv = $this->_encryptBlock($iv);
1036
- $cb = substr($ciphertext, $i, $block_size);
1037
- $plaintext.= $iv ^ $cb;
1038
- $iv = $cb;
1039
- $len-= $block_size;
1040
- $i+= $block_size;
1041
- }
1042
- if ($len) {
1043
- $iv = $this->_encryptBlock($iv);
1044
- $plaintext.= $iv ^ substr($ciphertext, $i);
1045
- $iv = substr_replace($iv, substr($ciphertext, $i), 0, $len);
1046
- $pos = $len;
1047
- }
1048
- break;
1049
- case CRYPT_MODE_OFB:
1050
- $xor = $this->decryptIV;
1051
- if (strlen($buffer['xor'])) {
1052
- for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
1053
- $block = substr($ciphertext, $i, $block_size);
1054
- if (strlen($block) > strlen($buffer['xor'])) {
1055
- $xor = $this->_encryptBlock($xor);
1056
- $buffer['xor'].= $xor;
1057
- }
1058
- $key = $this->_stringShift($buffer['xor'], $block_size);
1059
- $plaintext.= $block ^ $key;
1060
- }
1061
- } else {
1062
- for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
1063
- $xor = $this->_encryptBlock($xor);
1064
- $plaintext.= substr($ciphertext, $i, $block_size) ^ $xor;
1065
- }
1066
- $key = $xor;
1067
- }
1068
- if ($this->continuousBuffer) {
1069
- $this->decryptIV = $xor;
1070
- if ($start = strlen($ciphertext) % $block_size) {
1071
- $buffer['xor'] = substr($key, $start) . $buffer['xor'];
1072
- }
1073
- }
1074
- break;
1075
- case CRYPT_MODE_STREAM:
1076
- $plaintext = $this->_decryptBlock($ciphertext);
1077
- break;
1078
- }
1079
- return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
1080
- }
1081
-
1082
- /**
1083
- * Pad "packets".
1084
- *
1085
- * Block ciphers working by encrypting between their specified [$this->]block_size at a time
1086
- * If you ever need to encrypt or decrypt something that isn't of the proper length, it becomes necessary to
1087
- * pad the input so that it is of the proper length.
1088
- *
1089
- * Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH,
1090
- * where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping
1091
- * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is
1092
- * transmitted separately)
1093
- *
1094
- * @see Crypt_Base::disablePadding()
1095
- * @access public
1096
- */
1097
- function enablePadding()
1098
- {
1099
- $this->padding = true;
1100
- }
1101
-
1102
- /**
1103
- * Do not pad packets.
1104
- *
1105
- * @see Crypt_Base::enablePadding()
1106
- * @access public
1107
- */
1108
- function disablePadding()
1109
- {
1110
- $this->padding = false;
1111
- }
1112
-
1113
- /**
1114
- * Treat consecutive "packets" as if they are a continuous buffer.
1115
- *
1116
- * Say you have a 32-byte plaintext $plaintext. Using the default behavior, the two following code snippets
1117
- * will yield different outputs:
1118
- *
1119
- * <code>
1120
- * echo $rijndael->encrypt(substr($plaintext, 0, 16));
1121
- * echo $rijndael->encrypt(substr($plaintext, 16, 16));
1122
- * </code>
1123
- * <code>
1124
- * echo $rijndael->encrypt($plaintext);
1125
- * </code>
1126
- *
1127
- * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates
1128
- * another, as demonstrated with the following:
1129
- *
1130
- * <code>
1131
- * $rijndael->encrypt(substr($plaintext, 0, 16));
1132
- * echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16)));
1133
- * </code>
1134
- * <code>
1135
- * echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16)));
1136
- * </code>
1137
- *
1138
- * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different
1139
- * outputs. The reason is due to the fact that the initialization vector's change after every encryption /
1140
- * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
1141
- *
1142
- * Put another way, when the continuous buffer is enabled, the state of the Crypt_*() object changes after each
1143
- * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
1144
- * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
1145
- * however, they are also less intuitive and more likely to cause you problems.
1146
- *
1147
- * Note: Could, but not must, extend by the child Crypt_* class
1148
- *
1149
- * @see Crypt_Base::disableContinuousBuffer()
1150
- * @access public
1151
- */
1152
- function enableContinuousBuffer()
1153
- {
1154
- if ($this->mode == CRYPT_MODE_ECB) {
1155
- return;
1156
- }
1157
-
1158
- $this->continuousBuffer = true;
1159
- }
1160
-
1161
- /**
1162
- * Treat consecutive packets as if they are a discontinuous buffer.
1163
- *
1164
- * The default behavior.
1165
- *
1166
- * Note: Could, but not must, extend by the child Crypt_* class
1167
- *
1168
- * @see Crypt_Base::enableContinuousBuffer()
1169
- * @access public
1170
- */
1171
- function disableContinuousBuffer()
1172
- {
1173
- if ($this->mode == CRYPT_MODE_ECB) {
1174
- return;
1175
- }
1176
- if (!$this->continuousBuffer) {
1177
- return;
1178
- }
1179
-
1180
- $this->continuousBuffer = false;
1181
- $this->changed = true;
1182
- }
1183
-
1184
- /**
1185
- * Encrypts a block
1186
- *
1187
- * Note: Must extend by the child Crypt_* class
1188
- *
1189
- * @access private
1190
- * @param String $in
1191
- * @return String
1192
- */
1193
- function _encryptBlock($in)
1194
- {
1195
- user_error((version_compare(PHP_VERSION, '5.0.0', '>=') ? __METHOD__ : __FUNCTION__) . '() must extend by class ' . get_class($this), E_USER_ERROR);
1196
- }
1197
-
1198
- /**
1199
- * Decrypts a block
1200
- *
1201
- * Note: Must extend by the child Crypt_* class
1202
- *
1203
- * @access private
1204
- * @param String $in
1205
- * @return String
1206
- */
1207
- function _decryptBlock($in)
1208
- {
1209
- user_error((version_compare(PHP_VERSION, '5.0.0', '>=') ? __METHOD__ : __FUNCTION__) . '() must extend by class ' . get_class($this), E_USER_ERROR);
1210
- }
1211
-
1212
- /**
1213
- * Setup the key (expansion)
1214
- *
1215
- * Only used if $engine == CRYPT_MODE_INTERNAL
1216
- *
1217
- * Note: Must extend by the child Crypt_* class
1218
- *
1219
- * @see Crypt_Base::_setup()
1220
- * @access private
1221
- */
1222
- function _setupKey()
1223
- {
1224
- user_error((version_compare(PHP_VERSION, '5.0.0', '>=') ? __METHOD__ : __FUNCTION__) . '() must extend by class ' . get_class($this), E_USER_ERROR);
1225
- }
1226
-
1227
- /**
1228
- * Setup the CRYPT_MODE_INTERNAL $engine
1229
- *
1230
- * (re)init, if necessary, the internal cipher $engine and flush all $buffers
1231
- * Used (only) if $engine == CRYPT_MODE_INTERNAL
1232
- *
1233
- * _setup() will be called each time if $changed === true
1234
- * typically this happens when using one or more of following public methods:
1235
- *
1236
- * - setKey()
1237
- *
1238
- * - setIV()
1239
- *
1240
- * - disableContinuousBuffer()
1241
- *
1242
- * - First run of encrypt() / decrypt() with no init-settings
1243
- *
1244
- * Internally: _setup() is called always before(!) en/decryption.
1245
- *
1246
- * Note: Could, but not must, extend by the child Crypt_* class
1247
- *
1248
- * @see setKey()
1249
- * @see setIV()
1250
- * @see disableContinuousBuffer()
1251
- * @access private
1252
- */
1253
- function _setup()
1254
- {
1255
- $this->_clearBuffers();
1256
- $this->_setupKey();
1257
-
1258
- if ($this->use_inline_crypt) {
1259
- $this->_setupInlineCrypt();
1260
- }
1261
- }
1262
-
1263
- /**
1264
- * Setup the CRYPT_MODE_MCRYPT $engine
1265
- *
1266
- * (re)init, if necessary, the (ext)mcrypt resources and flush all $buffers
1267
- * Used (only) if $engine = CRYPT_MODE_MCRYPT
1268
- *
1269
- * _setupMcrypt() will be called each time if $changed === true
1270
- * typically this happens when using one or more of following public methods:
1271
- *
1272
- * - setKey()
1273
- *
1274
- * - setIV()
1275
- *
1276
- * - disableContinuousBuffer()
1277
- *
1278
- * - First run of encrypt() / decrypt()
1279
- *
1280
- *
1281
- * Note: Could, but not must, extend by the child Crypt_* class
1282
- *
1283
- * @see setKey()
1284
- * @see setIV()
1285
- * @see disableContinuousBuffer()
1286
- * @access private
1287
- */
1288
- function _setupMcrypt()
1289
- {
1290
- $this->_clearBuffers();
1291
- $this->enchanged = $this->dechanged = true;
1292
-
1293
- if (!isset($this->enmcrypt)) {
1294
- static $mcrypt_modes = array(
1295
- CRYPT_MODE_CTR => 'ctr',
1296
- CRYPT_MODE_ECB => MCRYPT_MODE_ECB,
1297
- CRYPT_MODE_CBC => MCRYPT_MODE_CBC,
1298
- CRYPT_MODE_CFB => 'ncfb',
1299
- CRYPT_MODE_OFB => MCRYPT_MODE_NOFB,
1300
- CRYPT_MODE_STREAM => MCRYPT_MODE_STREAM,
1301
- );
1302
-
1303
- $this->demcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], '');
1304
- $this->enmcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], '');
1305
-
1306
- // we need the $ecb mcrypt resource (only) in MODE_CFB with enableContinuousBuffer()
1307
- // to workaround mcrypt's broken ncfb implementation in buffered mode
1308
- // see: {@link http://phpseclib.sourceforge.net/cfb-demo.phps}
1309
- if ($this->mode == CRYPT_MODE_CFB) {
1310
- $this->ecb = mcrypt_module_open($this->cipher_name_mcrypt, '', MCRYPT_MODE_ECB, '');
1311
- }
1312
-
1313
- } // else should mcrypt_generic_deinit be called?
1314
-
1315
- if ($this->mode == CRYPT_MODE_CFB) {
1316
- mcrypt_generic_init($this->ecb, $this->key, str_repeat("\0", $this->block_size));
1317
- }
1318
- }
1319
-
1320
- /**
1321
- * Pads a string
1322
- *
1323
- * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize.
1324
- * $this->block_size - (strlen($text) % $this->block_size) bytes are added, each of which is equal to
1325
- * chr($this->block_size - (strlen($text) % $this->block_size)
1326
- *
1327
- * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless
1328
- * and padding will, hence forth, be enabled.
1329
- *
1330
- * @see Crypt_Base::_unpad()
1331
- * @param String $text
1332
- * @access private
1333
- * @return String
1334
- */
1335
- function _pad($text)
1336
- {
1337
- $length = strlen($text);
1338
-
1339
- if (!$this->padding) {
1340
- if ($length % $this->block_size == 0) {
1341
- return $text;
1342
- } else {
1343
- user_error("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size})");
1344
- $this->padding = true;
1345
- }
1346
- }
1347
-
1348
- $pad = $this->block_size - ($length % $this->block_size);
1349
-
1350
- return str_pad($text, $length + $pad, chr($pad));
1351
- }
1352
-
1353
- /**
1354
- * Unpads a string.
1355
- *
1356
- * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong
1357
- * and false will be returned.
1358
- *
1359
- * @see Crypt_Base::_pad()
1360
- * @param String $text
1361
- * @access private
1362
- * @return String
1363
- */
1364
- function _unpad($text)
1365
- {
1366
- if (!$this->padding) {
1367
- return $text;
1368
- }
1369
-
1370
- $length = ord($text[strlen($text) - 1]);
1371
-
1372
- if (!$length || $length > $this->block_size) {
1373
- return false;
1374
- }
1375
-
1376
- return substr($text, 0, -$length);
1377
- }
1378
-
1379
- /**
1380
- * Clears internal buffers
1381
- *
1382
- * Clearing/resetting the internal buffers is done everytime
1383
- * after disableContinuousBuffer() or on cipher $engine (re)init
1384
- * ie after setKey() or setIV()
1385
- *
1386
- * Note: Could, but not must, extend by the child Crypt_* class
1387
- *
1388
- * @access public
1389
- */
1390
- function _clearBuffers()
1391
- {
1392
- $this->enbuffer = array('encrypted' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);
1393
- $this->debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'demcrypt_init' => true);
1394
-
1395
- // mcrypt's handling of invalid's $iv:
1396
- // $this->encryptIV = $this->decryptIV = strlen($this->iv) == $this->block_size ? $this->iv : str_repeat("\0", $this->block_size);
1397
- $this->encryptIV = $this->decryptIV = str_pad(substr($this->iv, 0, $this->block_size), $this->block_size, "\0");
1398
- }
1399
-
1400
- /**
1401
- * String Shift
1402
- *
1403
- * Inspired by array_shift
1404
- *
1405
- * @param String $string
1406
- * @param optional Integer $index
1407
- * @access private
1408
- * @return String
1409
- */
1410
- function _stringShift(&$string, $index = 1)
1411
- {
1412
- $substr = substr($string, 0, $index);
1413
- $string = substr($string, $index);
1414
- return $substr;
1415
- }
1416
-
1417
- /**
1418
- * Generate CTR XOR encryption key
1419
- *
1420
- * Encrypt the output of this and XOR it against the ciphertext / plaintext to get the
1421
- * plaintext / ciphertext in CTR mode.
1422
- *
1423
- * @see Crypt_Base::decrypt()
1424
- * @see Crypt_Base::encrypt()
1425
- * @param String $iv
1426
- * @param Integer $length
1427
- * @access private
1428
- * @return String $xor
1429
- */
1430
- function _generateXor(&$iv, $length)
1431
- {
1432
- $xor = '';
1433
- $block_size = $this->block_size;
1434
- $num_blocks = floor(($length + ($block_size - 1)) / $block_size);
1435
- for ($i = 0; $i < $num_blocks; $i++) {
1436
- $xor.= $iv;
1437
- for ($j = 4; $j <= $block_size; $j+= 4) {
1438
- $temp = substr($iv, -$j, 4);
1439
- switch ($temp) {
1440
- case "\xFF\xFF\xFF\xFF":
1441
- $iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4);
1442
- break;
1443
- case "\x7F\xFF\xFF\xFF":
1444
- $iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4);
1445
- break 2;
1446
- default:
1447
- extract(unpack('Ncount', $temp));
1448
- $iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);
1449
- break 2;
1450
- }
1451
- }
1452
- }
1453
-
1454
- return $xor;
1455
- }
1456
-
1457
- /**
1458
- * Setup the performance-optimized function for de/encrypt()
1459
- *
1460
- * Stores the created (or existing) callback function-name
1461
- * in $this->inline_crypt
1462
- *
1463
- * Internally for phpseclib developers:
1464
- *
1465
- * _setupInlineCrypt() would be called only if:
1466
- *
1467
- * - $engine == CRYPT_MODE_INTERNAL and
1468
- *
1469
- * - $use_inline_crypt === true
1470
- *
1471
- * - each time on _setup(), after(!) _setupKey()
1472
- *
1473
- *
1474
- * This ensures that _setupInlineCrypt() has always a
1475
- * full ready2go initializated internal cipher $engine state
1476
- * where, for example, the keys allready expanded,
1477
- * keys/block_size calculated and such.
1478
- *
1479
- * It is, each time if called, the responsibility of _setupInlineCrypt():
1480
- *
1481
- * - to set $this->inline_crypt to a valid and fully working callback function
1482
- * as a (faster) replacement for encrypt() / decrypt()
1483
- *
1484
- * - NOT to create unlimited callback functions (for memory reasons!)
1485
- * no matter how often _setupInlineCrypt() would be called. At some
1486
- * point of amount they must be generic re-useable.
1487
- *
1488
- * - the code of _setupInlineCrypt() it self,
1489
- * and the generated callback code,
1490
- * must be, in following order:
1491
- * - 100% safe
1492
- * - 100% compatible to encrypt()/decrypt()
1493
- * - using only php5+ features/lang-constructs/php-extensions if
1494
- * compatibility (down to php4) or fallback is provided
1495
- * - readable/maintainable/understandable/commented and... not-cryptic-styled-code :-)
1496
- * - >= 10% faster than encrypt()/decrypt() [which is, by the way,
1497
- * the reason for the existence of _setupInlineCrypt() :-)]
1498
- * - memory-nice
1499
- * - short (as good as possible)
1500
- *
1501
- * Note: - _setupInlineCrypt() is using _createInlineCryptFunction() to create the full callback function code.
1502
- * - In case of using inline crypting, _setupInlineCrypt() must extend by the child Crypt_* class.
1503
- * - The following variable names are reserved:
1504
- * - $_* (all variable names prefixed with an underscore)
1505
- * - $self (object reference to it self. Do not use $this, but $self instead)
1506
- * - $in (the content of $in has to en/decrypt by the generated code)
1507
- * - The callback function should not use the 'return' statement, but en/decrypt'ing the content of $in only
1508
- *
1509
- *
1510
- * @see Crypt_Base::_setup()
1511
- * @see Crypt_Base::_createInlineCryptFunction()
1512
- * @see Crypt_Base::encrypt()
1513
- * @see Crypt_Base::decrypt()
1514
- * @access private
1515
- */
1516
- function _setupInlineCrypt()
1517
- {
1518
- // If a Crypt_* class providing inline crypting it must extend _setupInlineCrypt()
1519
-
1520
- // If, for any reason, an extending Crypt_Base() Crypt_* class
1521
- // not using inline crypting then it must be ensured that: $this->use_inline_crypt = false
1522
- // ie in the class var declaration of $use_inline_crypt in general for the Crypt_* class,
1523
- // in the constructor at object instance-time
1524
- // or, if it's runtime-specific, at runtime
1525
-
1526
- $this->use_inline_crypt = false;
1527
- }
1528
-
1529
- /**
1530
- * Creates the performance-optimized function for en/decrypt()
1531
- *
1532
- * Internally for phpseclib developers:
1533
- *
1534
- * _createInlineCryptFunction():
1535
- *
1536
- * - merge the $cipher_code [setup'ed by _setupInlineCrypt()]
1537
- * with the current [$this->]mode of operation code
1538
- *
1539
- * - create the $inline function, which called by encrypt() / decrypt()
1540
- * as its replacement to speed up the en/decryption operations.
1541
- *
1542
- * - return the name of the created $inline callback function
1543
- *
1544
- * - used to speed up en/decryption
1545
- *
1546
- *
1547
- *
1548
- * The main reason why can speed up things [up to 50%] this way are:
1549
- *
1550
- * - using variables more effective then regular.
1551
- * (ie no use of expensive arrays but integers $k_0, $k_1 ...
1552
- * or even, for example, the pure $key[] values hardcoded)
1553
- *
1554
- * - avoiding 1000's of function calls of ie _encryptBlock()
1555
- * but inlining the crypt operations.
1556
- * in the mode of operation for() loop.
1557
- *
1558
- * - full loop unroll the (sometimes key-dependent) rounds
1559
- * avoiding this way ++$i counters and runtime-if's etc...
1560
- *
1561
- * The basic code architectur of the generated $inline en/decrypt()
1562
- * lambda function, in pseudo php, is:
1563
- *
1564
- * <code>
1565
- * +----------------------------------------------------------------------------------------------+
1566
- * | callback $inline = create_function: |
1567
- * | lambda_function_0001_crypt_ECB($action, $text) |
1568
- * | { |
1569
- * | INSERT PHP CODE OF: |
1570
- * | $cipher_code['init_crypt']; // general init code. |
1571
- * | // ie: $sbox'es declarations used for |
1572
- * | // encrypt and decrypt'ing. |
1573
- * | |
1574
- * | switch ($action) { |
1575
- * | case 'encrypt': |
1576
- * | INSERT PHP CODE OF: |
1577
- * | $cipher_code['init_encrypt']; // encrypt sepcific init code. |
1578
- * | ie: specified $key or $box |
1579
- * | declarations for encrypt'ing. |
1580
- * | |
1581
- * | foreach ($ciphertext) { |
1582
- * | $in = $block_size of $ciphertext; |
1583
- * | |
1584
- * | INSERT PHP CODE OF: |
1585
- * | $cipher_code['encrypt_block']; // encrypt's (string) $in, which is always: |
1586
- * | // strlen($in) == $this->block_size |
1587
- * | // here comes the cipher algorithm in action |
1588
- * | // for encryption. |
1589
- * | // $cipher_code['encrypt_block'] has to |
1590
- * | // encrypt the content of the $in variable |
1591
- * | |
1592
- * | $plaintext .= $in; |
1593
- * | } |
1594
- * | return $plaintext; |
1595
- * | |
1596
- * | case 'decrypt': |
1597
- * | INSERT PHP CODE OF: |
1598
- * | $cipher_code['init_decrypt']; // decrypt sepcific init code |
1599
- * | ie: specified $key or $box |
1600
- * | declarations for decrypt'ing. |
1601
- * | foreach ($plaintext) { |
1602
- * | $in = $block_size of $plaintext; |
1603
- * | |
1604
- * | INSERT PHP CODE OF: |
1605
- * | $cipher_code['decrypt_block']; // decrypt's (string) $in, which is always |
1606
- * | // strlen($in) == $this->block_size |
1607
- * | // here comes the cipher algorithm in action |
1608
- * | // for decryption. |
1609
- * | // $cipher_code['decrypt_block'] has to |
1610
- * | // decrypt the content of the $in variable |
1611
- * | $ciphertext .= $in; |
1612
- * | } |
1613
- * | return $ciphertext; |
1614
- * | } |
1615
- * | } |
1616
- * +----------------------------------------------------------------------------------------------+
1617
- * </code>
1618
- *
1619
- * See also the Crypt_*::_setupInlineCrypt()'s for
1620
- * productive inline $cipher_code's how they works.
1621
- *
1622
- * Structure of:
1623
- * <code>
1624
- * $cipher_code = array(
1625
- * 'init_crypt' => (string) '', // optional
1626
- * 'init_encrypt' => (string) '', // optional
1627
- * 'init_decrypt' => (string) '', // optional
1628
- * 'encrypt_block' => (string) '', // required
1629
- * 'decrypt_block' => (string) '' // required
1630
- * );
1631
- * </code>
1632
- *
1633
- * @see Crypt_Base::_setupInlineCrypt()
1634
- * @see Crypt_Base::encrypt()
1635
- * @see Crypt_Base::decrypt()
1636
- * @param Array $cipher_code
1637
- * @access private
1638
- * @return String (the name of the created callback function)
1639
- */
1640
- function _createInlineCryptFunction($cipher_code)
1641
- {
1642
- $block_size = $this->block_size;
1643
-
1644
- // optional
1645
- $init_crypt = isset($cipher_code['init_crypt']) ? $cipher_code['init_crypt'] : '';
1646
- $init_encrypt = isset($cipher_code['init_encrypt']) ? $cipher_code['init_encrypt'] : '';
1647
- $init_decrypt = isset($cipher_code['init_decrypt']) ? $cipher_code['init_decrypt'] : '';
1648
- // required
1649
- $encrypt_block = $cipher_code['encrypt_block'];
1650
- $decrypt_block = $cipher_code['decrypt_block'];
1651
-
1652
- // Generating mode of operation inline code,
1653
- // merged with the $cipher_code algorithm
1654
- // for encrypt- and decryption.
1655
- switch ($this->mode) {
1656
- case CRYPT_MODE_ECB:
1657
- $encrypt = $init_encrypt . '
1658
- $_ciphertext = "";
1659
- $_text = $self->_pad($_text);
1660
- $_plaintext_len = strlen($_text);
1661
-
1662
- for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
1663
- $in = substr($_text, $_i, '.$block_size.');
1664
- '.$encrypt_block.'
1665
- $_ciphertext.= $in;
1666
- }
1667
-
1668
- return $_ciphertext;
1669
- ';
1670
-
1671
- $decrypt = $init_decrypt . '
1672
- $_plaintext = "";
1673
- $_text = str_pad($_text, strlen($_text) + ('.$block_size.' - strlen($_text) % '.$block_size.') % '.$block_size.', chr(0));
1674
- $_ciphertext_len = strlen($_text);
1675
-
1676
- for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
1677
- $in = substr($_text, $_i, '.$block_size.');
1678
- '.$decrypt_block.'
1679
- $_plaintext.= $in;
1680
- }
1681
-
1682
- return $self->_unpad($_plaintext);
1683
- ';
1684
- break;
1685
- case CRYPT_MODE_CTR:
1686
- $encrypt = $init_encrypt . '
1687
- $_ciphertext = "";
1688
- $_plaintext_len = strlen($_text);
1689
- $_xor = $self->encryptIV;
1690
- $_buffer = &$self->enbuffer;
1691
-
1692
- if (strlen($_buffer["encrypted"])) {
1693
- for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
1694
- $_block = substr($_text, $_i, '.$block_size.');
1695
- if (strlen($_block) > strlen($_buffer["encrypted"])) {
1696
- $in = $self->_generateXor($_xor, '.$block_size.');
1697
- '.$encrypt_block.'
1698
- $_buffer["encrypted"].= $in;
1699
- }
1700
- $_key = $self->_stringShift($_buffer["encrypted"], '.$block_size.');
1701
- $_ciphertext.= $_block ^ $_key;
1702
- }
1703
- } else {
1704
- for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
1705
- $_block = substr($_text, $_i, '.$block_size.');
1706
- $in = $self->_generateXor($_xor, '.$block_size.');
1707
- '.$encrypt_block.'
1708
- $_key = $in;
1709
- $_ciphertext.= $_block ^ $_key;
1710
- }
1711
- }
1712
- if ($self->continuousBuffer) {
1713
- $self->encryptIV = $_xor;
1714
- if ($_start = $_plaintext_len % '.$block_size.') {
1715
- $_buffer["encrypted"] = substr($_key, $_start) . $_buffer["encrypted"];
1716
- }
1717
- }
1718
-
1719
- return $_ciphertext;
1720
- ';
1721
-
1722
- $decrypt = $init_encrypt . '
1723
- $_plaintext = "";
1724
- $_ciphertext_len = strlen($_text);
1725
- $_xor = $self->decryptIV;
1726
- $_buffer = &$self->debuffer;
1727
-
1728
- if (strlen($_buffer["ciphertext"])) {
1729
- for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
1730
- $_block = substr($_text, $_i, '.$block_size.');
1731
- if (strlen($_block) > strlen($_buffer["ciphertext"])) {
1732
- $in = $self->_generateXor($_xor, '.$block_size.');
1733
- '.$encrypt_block.'
1734
- $_buffer["ciphertext"].= $in;
1735
- }
1736
- $_key = $self->_stringShift($_buffer["ciphertext"], '.$block_size.');
1737
- $_plaintext.= $_block ^ $_key;
1738
- }
1739
- } else {
1740
- for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
1741
- $_block = substr($_text, $_i, '.$block_size.');
1742
- $in = $self->_generateXor($_xor, '.$block_size.');
1743
- '.$encrypt_block.'
1744
- $_key = $in;
1745
- $_plaintext.= $_block ^ $_key;
1746
- }
1747
- }
1748
- if ($self->continuousBuffer) {
1749
- $self->decryptIV = $_xor;
1750
- if ($_start = $_ciphertext_len % '.$block_size.') {
1751
- $_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"];
1752
- }
1753
- }
1754
-
1755
- return $_plaintext;
1756
- ';
1757
- break;
1758
- case CRYPT_MODE_CFB:
1759
- $encrypt = $init_encrypt . '
1760
- $_ciphertext = "";
1761
- $_buffer = &$self->enbuffer;
1762
-
1763
- if ($self->continuousBuffer) {
1764
- $_iv = &$self->encryptIV;
1765
- $_pos = &$_buffer["pos"];
1766
- } else {
1767
- $_iv = $self->encryptIV;
1768
- $_pos = 0;
1769
- }
1770
- $_len = strlen($_text);
1771
- $_i = 0;
1772
- if ($_pos) {
1773
- $_orig_pos = $_pos;
1774
- $_max = '.$block_size.' - $_pos;
1775
- if ($_len >= $_max) {
1776
- $_i = $_max;
1777
- $_len-= $_max;
1778
- $_pos = 0;
1779
- } else {
1780
- $_i = $_len;
1781
- $_pos+= $_len;
1782
- $_len = 0;
1783
- }
1784
- $_ciphertext = substr($_iv, $_orig_pos) ^ $_text;
1785
- $_iv = substr_replace($_iv, $_ciphertext, $_orig_pos, $_i);
1786
- }
1787
- while ($_len >= '.$block_size.') {
1788
- $in = $_iv;
1789
- '.$encrypt_block.';
1790
- $_iv = $in ^ substr($_text, $_i, '.$block_size.');
1791
- $_ciphertext.= $_iv;
1792
- $_len-= '.$block_size.';
1793
- $_i+= '.$block_size.';
1794
- }
1795
- if ($_len) {
1796
- $in = $_iv;
1797
- '.$encrypt_block.'
1798
- $_iv = $in;
1799
- $_block = $_iv ^ substr($_text, $_i);
1800
- $_iv = substr_replace($_iv, $_block, 0, $_len);
1801
- $_ciphertext.= $_block;
1802
- $_pos = $_len;
1803
- }
1804
- return $_ciphertext;
1805
- ';
1806
-
1807
- $decrypt = $init_encrypt . '
1808
- $_plaintext = "";
1809
- $_buffer = &$self->debuffer;
1810
-
1811
- if ($self->continuousBuffer) {
1812
- $_iv = &$self->decryptIV;
1813
- $_pos = &$_buffer["pos"];
1814
- } else {
1815
- $_iv = $self->decryptIV;
1816
- $_pos = 0;
1817
- }
1818
- $_len = strlen($_text);
1819
- $_i = 0;
1820
- if ($_pos) {
1821
- $_orig_pos = $_pos;
1822
- $_max = '.$block_size.' - $_pos;
1823
- if ($_len >= $_max) {
1824
- $_i = $_max;
1825
- $_len-= $_max;
1826
- $_pos = 0;
1827
- } else {
1828
- $_i = $_len;
1829
- $_pos+= $_len;
1830
- $_len = 0;
1831
- }
1832
- $_plaintext = substr($_iv, $_orig_pos) ^ $_text;
1833
- $_iv = substr_replace($_iv, substr($_text, 0, $_i), $_orig_pos, $_i);
1834
- }
1835
- while ($_len >= '.$block_size.') {
1836
- $in = $_iv;
1837
- '.$encrypt_block.'
1838
- $_iv = $in;
1839
- $cb = substr($_text, $_i, '.$block_size.');
1840
- $_plaintext.= $_iv ^ $cb;
1841
- $_iv = $cb;
1842
- $_len-= '.$block_size.';
1843
- $_i+= '.$block_size.';
1844
- }
1845
- if ($_len) {
1846
- $in = $_iv;
1847
- '.$encrypt_block.'
1848
- $_iv = $in;
1849
- $_plaintext.= $_iv ^ substr($_text, $_i);
1850
- $_iv = substr_replace($_iv, substr($_text, $_i), 0, $_len);
1851
- $_pos = $_len;
1852
- }
1853
-
1854
- return $_plaintext;
1855
- ';
1856
- break;
1857
- case CRYPT_MODE_OFB:
1858
- $encrypt = $init_encrypt . '
1859
- $_ciphertext = "";
1860
- $_plaintext_len = strlen($_text);
1861
- $_xor = $self->encryptIV;
1862
- $_buffer = &$self->enbuffer;
1863
-
1864
- if (strlen($_buffer["xor"])) {
1865
- for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
1866
- $_block = substr($_text, $_i, '.$block_size.');
1867
- if (strlen($_block) > strlen($_buffer["xor"])) {
1868
- $in = $_xor;
1869
- '.$encrypt_block.'
1870
- $_xor = $in;
1871
- $_buffer["xor"].= $_xor;
1872
- }
1873
- $_key = $self->_stringShift($_buffer["xor"], '.$block_size.');
1874
- $_ciphertext.= $_block ^ $_key;
1875
- }
1876
- } else {
1877
- for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
1878
- $in = $_xor;
1879
- '.$encrypt_block.'
1880
- $_xor = $in;
1881
- $_ciphertext.= substr($_text, $_i, '.$block_size.') ^ $_xor;
1882
- }
1883
- $_key = $_xor;
1884
- }
1885
- if ($self->continuousBuffer) {
1886
- $self->encryptIV = $_xor;
1887
- if ($_start = $_plaintext_len % '.$block_size.') {
1888
- $_buffer["xor"] = substr($_key, $_start) . $_buffer["xor"];
1889
- }
1890
- }
1891
- return $_ciphertext;
1892
- ';
1893
-
1894
- $decrypt = $init_encrypt . '
1895
- $_plaintext = "";
1896
- $_ciphertext_len = strlen($_text);
1897
- $_xor = $self->decryptIV;
1898
- $_buffer = &$self->debuffer;
1899
-
1900
- if (strlen($_buffer["xor"])) {
1901
- for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
1902
- $_block = substr($_text, $_i, '.$block_size.');
1903
- if (strlen($_block) > strlen($_buffer["xor"])) {
1904
- $in = $_xor;
1905
- '.$encrypt_block.'
1906
- $_xor = $in;
1907
- $_buffer["xor"].= $_xor;
1908
- }
1909
- $_key = $self->_stringShift($_buffer["xor"], '.$block_size.');
1910
- $_plaintext.= $_block ^ $_key;
1911
- }
1912
- } else {
1913
- for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
1914
- $in = $_xor;
1915
- '.$encrypt_block.'
1916
- $_xor = $in;
1917
- $_plaintext.= substr($_text, $_i, '.$block_size.') ^ $_xor;
1918
- }
1919
- $_key = $_xor;
1920
- }
1921
- if ($self->continuousBuffer) {
1922
- $self->decryptIV = $_xor;
1923
- if ($_start = $_ciphertext_len % '.$block_size.') {
1924
- $_buffer["xor"] = substr($_key, $_start) . $_buffer["xor"];
1925
- }
1926
- }
1927
- return $_plaintext;
1928
- ';
1929
- break;
1930
- case CRYPT_MODE_STREAM:
1931
- $encrypt = $init_encrypt . '
1932
- $_ciphertext = "";
1933
- '.$encrypt_block.'
1934
- return $_ciphertext;
1935
- ';
1936
- $decrypt = $init_decrypt . '
1937
- $_plaintext = "";
1938
- '.$decrypt_block.'
1939
- return $_plaintext;
1940
- ';
1941
- break;
1942
- // case CRYPT_MODE_CBC:
1943
- default:
1944
- $encrypt = $init_encrypt . '
1945
- $_ciphertext = "";
1946
- $_text = $self->_pad($_text);
1947
- $_plaintext_len = strlen($_text);
1948
-
1949
- $in = $self->encryptIV;
1950
-
1951
- for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
1952
- $in = substr($_text, $_i, '.$block_size.') ^ $in;
1953
- '.$encrypt_block.'
1954
- $_ciphertext.= $in;
1955
- }
1956
-
1957
- if ($self->continuousBuffer) {
1958
- $self->encryptIV = $in;
1959
- }
1960
-
1961
- return $_ciphertext;
1962
- ';
1963
-
1964
- $decrypt = $init_decrypt . '
1965
- $_plaintext = "";
1966
- $_text = str_pad($_text, strlen($_text) + ('.$block_size.' - strlen($_text) % '.$block_size.') % '.$block_size.', chr(0));
1967
- $_ciphertext_len = strlen($_text);
1968
-
1969
- $_iv = $self->decryptIV;
1970
-
1971
- for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
1972
- $in = $_block = substr($_text, $_i, '.$block_size.');
1973
- '.$decrypt_block.'
1974
- $_plaintext.= $in ^ $_iv;
1975
- $_iv = $_block;
1976
- }
1977
-
1978
- if ($self->continuousBuffer) {
1979
- $self->decryptIV = $_iv;
1980
- }
1981
-
1982
- return $self->_unpad($_plaintext);
1983
- ';
1984
- break;
1985
- }
1986
-
1987
- // Create the $inline function and return its name as string. Ready to run!
1988
- return create_function('$_action, &$self, $_text', $init_crypt . 'if ($_action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' }');
1989
- }
1990
-
1991
- /**
1992
- * Holds the lambda_functions table (classwide)
1993
- *
1994
- * Each name of the lambda function, created from
1995
- * _setupInlineCrypt() && _createInlineCryptFunction()
1996
- * is stored, classwide (!), here for reusing.
1997
- *
1998
- * The string-based index of $function is a classwide
1999
- * uniqe value representing, at least, the $mode of
2000
- * operation (or more... depends of the optimizing level)
2001
- * for which $mode the lambda function was created.
2002
- *
2003
- * @access private
2004
- * @return &Array
2005
- */
2006
- function &_getLambdaFunctions()
2007
- {
2008
- static $functions = array();
2009
- return $functions;
2010
- }
2011
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Base Class for all Crypt_* cipher classes
5
+ *
6
+ * PHP versions 4 and 5
7
+ *
8
+ * Internally for phpseclib developers:
9
+ * If you plan to add a new cipher class, please note following rules:
10
+ *
11
+ * - The new Crypt_* cipher class should extend Crypt_Base
12
+ *
13
+ * - Following methods are then required to be overridden/overloaded:
14
+ *
15
+ * - _encryptBlock()
16
+ *
17
+ * - _decryptBlock()
18
+ *
19
+ * - _setupKey()
20
+ *
21
+ * - All other methods are optional to be overridden/overloaded
22
+ *
23
+ * - Look at the source code of the current ciphers how they extend Crypt_Base
24
+ * and take one of them as a start up for the new cipher class.
25
+ *
26
+ * - Please read all the other comments/notes/hints here also for each class var/method
27
+ *
28
+ * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
29
+ * of this software and associated documentation files (the "Software"), to deal
30
+ * in the Software without restriction, including without limitation the rights
31
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
32
+ * copies of the Software, and to permit persons to whom the Software is
33
+ * furnished to do so, subject to the following conditions:
34
+ *
35
+ * The above copyright notice and this permission notice shall be included in
36
+ * all copies or substantial portions of the Software.
37
+ *
38
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
39
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
40
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
41
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
42
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
43
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
44
+ * THE SOFTWARE.
45
+ *
46
+ * @category Crypt
47
+ * @package Crypt_Base
48
+ * @author Jim Wigginton <terrafrost@php.net>
49
+ * @author Hans-Juergen Petrich <petrich@tronic-media.com>
50
+ * @copyright 2007 Jim Wigginton
51
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
52
+ * @link http://phpseclib.sourceforge.net
53
+ */
54
+
55
+ /**#@+
56
+ * @access public
57
+ * @see Crypt_Base::encrypt()
58
+ * @see Crypt_Base::decrypt()
59
+ */
60
+ /**
61
+ * Encrypt / decrypt using the Counter mode.
62
+ *
63
+ * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
64
+ *
65
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
66
+ */
67
+ define('CRYPT_MODE_CTR', -1);
68
+ /**
69
+ * Encrypt / decrypt using the Electronic Code Book mode.
70
+ *
71
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
72
+ */
73
+ define('CRYPT_MODE_ECB', 1);
74
+ /**
75
+ * Encrypt / decrypt using the Code Book Chaining mode.
76
+ *
77
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
78
+ */
79
+ define('CRYPT_MODE_CBC', 2);
80
+ /**
81
+ * Encrypt / decrypt using the Cipher Feedback mode.
82
+ *
83
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
84
+ */
85
+ define('CRYPT_MODE_CFB', 3);
86
+ /**
87
+ * Encrypt / decrypt using the Output Feedback mode.
88
+ *
89
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
90
+ */
91
+ define('CRYPT_MODE_OFB', 4);
92
+ /**
93
+ * Encrypt / decrypt using streaming mode.
94
+ */
95
+ define('CRYPT_MODE_STREAM', 5);
96
+ /**#@-*/
97
+
98
+ /**#@+
99
+ * @access private
100
+ * @see Crypt_Base::Crypt_Base()
101
+ * @internal These constants are for internal use only
102
+ */
103
+ /**
104
+ * Base value for the internal implementation $engine switch
105
+ */
106
+ define('CRYPT_ENGINE_INTERNAL', 1);
107
+ /**
108
+ * Base value for the mcrypt implementation $engine switch
109
+ */
110
+ define('CRYPT_ENGINE_MCRYPT', 2);
111
+ /**
112
+ * Base value for the OpenSSL implementation $engine switch
113
+ */
114
+ define('CRYPT_ENGINE_OPENSSL', 3);
115
+ /**#@-*/
116
+
117
+ /**
118
+ * Base Class for all Crypt_* cipher classes
119
+ *
120
+ * @package Crypt_Base
121
+ * @author Jim Wigginton <terrafrost@php.net>
122
+ * @author Hans-Juergen Petrich <petrich@tronic-media.com>
123
+ * @access public
124
+ */
125
+ class Crypt_Base
126
+ {
127
+ /**
128
+ * The Encryption Mode
129
+ *
130
+ * @see Crypt_Base::Crypt_Base()
131
+ * @var Integer
132
+ * @access private
133
+ */
134
+ var $mode;
135
+
136
+ /**
137
+ * The Block Length of the block cipher
138
+ *
139
+ * @var Integer
140
+ * @access private
141
+ */
142
+ var $block_size = 16;
143
+
144
+ /**
145
+ * The Key
146
+ *
147
+ * @see Crypt_Base::setKey()
148
+ * @var String
149
+ * @access private
150
+ */
151
+ var $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
152
+
153
+ /**
154
+ * The Initialization Vector
155
+ *
156
+ * @see Crypt_Base::setIV()
157
+ * @var String
158
+ * @access private
159
+ */
160
+ var $iv;
161
+
162
+ /**
163
+ * A "sliding" Initialization Vector
164
+ *
165
+ * @see Crypt_Base::enableContinuousBuffer()
166
+ * @see Crypt_Base::_clearBuffers()
167
+ * @var String
168
+ * @access private
169
+ */
170
+ var $encryptIV;
171
+
172
+ /**
173
+ * A "sliding" Initialization Vector
174
+ *
175
+ * @see Crypt_Base::enableContinuousBuffer()
176
+ * @see Crypt_Base::_clearBuffers()
177
+ * @var String
178
+ * @access private
179
+ */
180
+ var $decryptIV;
181
+
182
+ /**
183
+ * Continuous Buffer status
184
+ *
185
+ * @see Crypt_Base::enableContinuousBuffer()
186
+ * @var Boolean
187
+ * @access private
188
+ */
189
+ var $continuousBuffer = false;
190
+
191
+ /**
192
+ * Encryption buffer for CTR, OFB and CFB modes
193
+ *
194
+ * @see Crypt_Base::encrypt()
195
+ * @see Crypt_Base::_clearBuffers()
196
+ * @var Array
197
+ * @access private
198
+ */
199
+ var $enbuffer;
200
+
201
+ /**
202
+ * Decryption buffer for CTR, OFB and CFB modes
203
+ *
204
+ * @see Crypt_Base::decrypt()
205
+ * @see Crypt_Base::_clearBuffers()
206
+ * @var Array
207
+ * @access private
208
+ */
209
+ var $debuffer;
210
+
211
+ /**
212
+ * mcrypt resource for encryption
213
+ *
214
+ * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
215
+ * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
216
+ *
217
+ * @see Crypt_Base::encrypt()
218
+ * @var Resource
219
+ * @access private
220
+ */
221
+ var $enmcrypt;
222
+
223
+ /**
224
+ * mcrypt resource for decryption
225
+ *
226
+ * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
227
+ * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
228
+ *
229
+ * @see Crypt_Base::decrypt()
230
+ * @var Resource
231
+ * @access private
232
+ */
233
+ var $demcrypt;
234
+
235
+ /**
236
+ * Does the enmcrypt resource need to be (re)initialized?
237
+ *
238
+ * @see Crypt_Twofish::setKey()
239
+ * @see Crypt_Twofish::setIV()
240
+ * @var Boolean
241
+ * @access private
242
+ */
243
+ var $enchanged = true;
244
+
245
+ /**
246
+ * Does the demcrypt resource need to be (re)initialized?
247
+ *
248
+ * @see Crypt_Twofish::setKey()
249
+ * @see Crypt_Twofish::setIV()
250
+ * @var Boolean
251
+ * @access private
252
+ */
253
+ var $dechanged = true;
254
+
255
+ /**
256
+ * mcrypt resource for CFB mode
257
+ *
258
+ * mcrypt's CFB mode, in (and only in) buffered context,
259
+ * is broken, so phpseclib implements the CFB mode by it self,
260
+ * even when the mcrypt php extension is available.
261
+ *
262
+ * In order to do the CFB-mode work (fast) phpseclib
263
+ * use a separate ECB-mode mcrypt resource.
264
+ *
265
+ * @link http://phpseclib.sourceforge.net/cfb-demo.phps
266
+ * @see Crypt_Base::encrypt()
267
+ * @see Crypt_Base::decrypt()
268
+ * @see Crypt_Base::_setupMcrypt()
269
+ * @var Resource
270
+ * @access private
271
+ */
272
+ var $ecb;
273
+
274
+ /**
275
+ * Optimizing value while CFB-encrypting
276
+ *
277
+ * Only relevant if $continuousBuffer enabled
278
+ * and $engine == CRYPT_ENGINE_MCRYPT
279
+ *
280
+ * It's faster to re-init $enmcrypt if
281
+ * $buffer bytes > $cfb_init_len than
282
+ * using the $ecb resource furthermore.
283
+ *
284
+ * This value depends of the chosen cipher
285
+ * and the time it would be needed for it's
286
+ * initialization [by mcrypt_generic_init()]
287
+ * which, typically, depends on the complexity
288
+ * on its internaly Key-expanding algorithm.
289
+ *
290
+ * @see Crypt_Base::encrypt()
291
+ * @var Integer
292
+ * @access private
293
+ */
294
+ var $cfb_init_len = 600;
295
+
296
+ /**
297
+ * Does internal cipher state need to be (re)initialized?
298
+ *
299
+ * @see setKey()
300
+ * @see setIV()
301
+ * @see disableContinuousBuffer()
302
+ * @var Boolean
303
+ * @access private
304
+ */
305
+ var $changed = true;
306
+
307
+ /**
308
+ * Padding status
309
+ *
310
+ * @see Crypt_Base::enablePadding()
311
+ * @var Boolean
312
+ * @access private
313
+ */
314
+ var $padding = true;
315
+
316
+ /**
317
+ * Is the mode one that is paddable?
318
+ *
319
+ * @see Crypt_Base::Crypt_Base()
320
+ * @var Boolean
321
+ * @access private
322
+ */
323
+ var $paddable = false;
324
+
325
+ /**
326
+ * Holds which crypt engine internaly should be use,
327
+ * which will be determined automatically on __construct()
328
+ *
329
+ * Currently available $engines are:
330
+ * - CRYPT_ENGINE_OPENSSL (very fast, php-extension: openssl, extension_loaded('openssl') required)
331
+ * - CRYPT_ENGINE_MCRYPT (fast, php-extension: mcrypt, extension_loaded('mcrypt') required)
332
+ * - CRYPT_ENGINE_INTERNAL (slower, pure php-engine, no php-extension required)
333
+ *
334
+ * @see Crypt_Base::_setEngine()
335
+ * @see Crypt_Base::encrypt()
336
+ * @see Crypt_Base::decrypt()
337
+ * @var Integer
338
+ * @access private
339
+ */
340
+ var $engine;
341
+
342
+ /**
343
+ * Holds the preferred crypt engine
344
+ *
345
+ * @see Crypt_Base::_setEngine()
346
+ * @see Crypt_Base::setPreferredEngine()
347
+ * @var Integer
348
+ * @access private
349
+ */
350
+ var $preferredEngine;
351
+
352
+ /**
353
+ * The mcrypt specific name of the cipher
354
+ *
355
+ * Only used if $engine == CRYPT_ENGINE_MCRYPT
356
+ *
357
+ * @link http://www.php.net/mcrypt_module_open
358
+ * @link http://www.php.net/mcrypt_list_algorithms
359
+ * @see Crypt_Base::_setupMcrypt()
360
+ * @var String
361
+ * @access private
362
+ */
363
+ var $cipher_name_mcrypt;
364
+
365
+ /**
366
+ * The openssl specific name of the cipher
367
+ *
368
+ * Only used if $engine == CRYPT_ENGINE_OPENSSL
369
+ *
370
+ * @link http://www.php.net/openssl-get-cipher-methods
371
+ * @var String
372
+ * @access private
373
+ */
374
+ var $cipher_name_openssl;
375
+
376
+ /**
377
+ * The openssl specific name of the cipher in ECB mode
378
+ *
379
+ * If OpenSSL does not support the mode we're trying to use (CTR)
380
+ * it can still be emulated with ECB mode.
381
+ *
382
+ * @link http://www.php.net/openssl-get-cipher-methods
383
+ * @var String
384
+ * @access private
385
+ */
386
+ var $cipher_name_openssl_ecb;
387
+
388
+ /**
389
+ * The default password key_size used by setPassword()
390
+ *
391
+ * @see Crypt_Base::setPassword()
392
+ * @var Integer
393
+ * @access private
394
+ */
395
+ var $password_key_size = 32;
396
+
397
+ /**
398
+ * The default salt used by setPassword()
399
+ *
400
+ * @see Crypt_Base::setPassword()
401
+ * @var String
402
+ * @access private
403
+ */
404
+ var $password_default_salt = 'phpseclib/salt';
405
+
406
+ /**
407
+ * The namespace used by the cipher for its constants.
408
+ *
409
+ * ie: AES.php is using CRYPT_AES_MODE_* for its constants
410
+ * so $const_namespace is AES
411
+ *
412
+ * DES.php is using CRYPT_DES_MODE_* for its constants
413
+ * so $const_namespace is DES... and so on
414
+ *
415
+ * All CRYPT_<$const_namespace>_MODE_* are aliases of
416
+ * the generic CRYPT_MODE_* constants, so both could be used
417
+ * for each cipher.
418
+ *
419
+ * Example:
420
+ * $aes = new Crypt_AES(CRYPT_AES_MODE_CFB); // $aes will operate in cfb mode
421
+ * $aes = new Crypt_AES(CRYPT_MODE_CFB); // identical
422
+ *
423
+ * @see Crypt_Base::Crypt_Base()
424
+ * @var String
425
+ * @access private
426
+ */
427
+ var $const_namespace;
428
+
429
+ /**
430
+ * The name of the performance-optimized callback function
431
+ *
432
+ * Used by encrypt() / decrypt()
433
+ * only if $engine == CRYPT_ENGINE_INTERNAL
434
+ *
435
+ * @see Crypt_Base::encrypt()
436
+ * @see Crypt_Base::decrypt()
437
+ * @see Crypt_Base::_setupInlineCrypt()
438
+ * @see Crypt_Base::$use_inline_crypt
439
+ * @var Callback
440
+ * @access private
441
+ */
442
+ var $inline_crypt;
443
+
444
+ /**
445
+ * Holds whether performance-optimized $inline_crypt() can/should be used.
446
+ *
447
+ * @see Crypt_Base::encrypt()
448
+ * @see Crypt_Base::decrypt()
449
+ * @see Crypt_Base::inline_crypt
450
+ * @var mixed
451
+ * @access private
452
+ */
453
+ var $use_inline_crypt;
454
+
455
+ /**
456
+ * If OpenSSL can be used in ECB but not in CTR we can emulate CTR
457
+ *
458
+ * @see Crypt_Base::_openssl_ctr_process()
459
+ * @var Boolean
460
+ * @access private
461
+ */
462
+ var $openssl_emulate_ctr = false;
463
+
464
+ /**
465
+ * Determines what options are passed to openssl_encrypt/decrypt
466
+ *
467
+ * @see Crypt_Base::isValidEngine()
468
+ * @var mixed
469
+ * @access private
470
+ */
471
+ var $openssl_options;
472
+
473
+ /**
474
+ * Default Constructor.
475
+ *
476
+ * Determines whether or not the mcrypt extension should be used.
477
+ *
478
+ * $mode could be:
479
+ *
480
+ * - CRYPT_MODE_ECB
481
+ *
482
+ * - CRYPT_MODE_CBC
483
+ *
484
+ * - CRYPT_MODE_CTR
485
+ *
486
+ * - CRYPT_MODE_CFB
487
+ *
488
+ * - CRYPT_MODE_OFB
489
+ *
490
+ * (or the alias constants of the chosen cipher, for example for AES: CRYPT_AES_MODE_ECB or CRYPT_AES_MODE_CBC ...)
491
+ *
492
+ * If not explicitly set, CRYPT_MODE_CBC will be used.
493
+ *
494
+ * @param optional Integer $mode
495
+ * @access public
496
+ */
497
+ function Crypt_Base($mode = CRYPT_MODE_CBC)
498
+ {
499
+ // $mode dependent settings
500
+ switch ($mode) {
501
+ case CRYPT_MODE_ECB:
502
+ $this->paddable = true;
503
+ $this->mode = CRYPT_MODE_ECB;
504
+ break;
505
+ case CRYPT_MODE_CTR:
506
+ case CRYPT_MODE_CFB:
507
+ case CRYPT_MODE_OFB:
508
+ case CRYPT_MODE_STREAM:
509
+ $this->mode = $mode;
510
+ break;
511
+ case CRYPT_MODE_CBC:
512
+ default:
513
+ $this->paddable = true;
514
+ $this->mode = CRYPT_MODE_CBC;
515
+ }
516
+
517
+ $this->_setEngine();
518
+
519
+ // Determining whether inline crypting can be used by the cipher
520
+ if ($this->use_inline_crypt !== false && function_exists('create_function')) {
521
+ $this->use_inline_crypt = true;
522
+ }
523
+ }
524
+
525
+ /**
526
+ * Sets the initialization vector. (optional)
527
+ *
528
+ * SetIV is not required when CRYPT_MODE_ECB (or ie for AES: CRYPT_AES_MODE_ECB) is being used. If not explicitly set, it'll be assumed
529
+ * to be all zero's.
530
+ *
531
+ * @access public
532
+ * @param String $iv
533
+ * @internal Can be overwritten by a sub class, but does not have to be
534
+ */
535
+ function setIV($iv)
536
+ {
537
+ if ($this->mode == CRYPT_MODE_ECB) {
538
+ return;
539
+ }
540
+
541
+ $this->iv = $iv;
542
+ $this->changed = true;
543
+ }
544
+
545
+ /**
546
+ * Sets the key.
547
+ *
548
+ * The min/max length(s) of the key depends on the cipher which is used.
549
+ * If the key not fits the length(s) of the cipher it will paded with null bytes
550
+ * up to the closest valid key length. If the key is more than max length,
551
+ * we trim the excess bits.
552
+ *
553
+ * If the key is not explicitly set, it'll be assumed to be all null bytes.
554
+ *
555
+ * @access public
556
+ * @param String $key
557
+ * @internal Could, but not must, extend by the child Crypt_* class
558
+ */
559
+ function setKey($key)
560
+ {
561
+ $this->key = $key;
562
+ $this->changed = true;
563
+ $this->_setEngine();
564
+ }
565
+
566
+ /**
567
+ * Sets the password.
568
+ *
569
+ * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows:
570
+ * {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2} or pbkdf1:
571
+ * $hash, $salt, $count, $dkLen
572
+ *
573
+ * Where $hash (default = sha1) currently supports the following hashes: see: Crypt/Hash.php
574
+ *
575
+ * @see Crypt/Hash.php
576
+ * @param String $password
577
+ * @param optional String $method
578
+ * @return Boolean
579
+ * @access public
580
+ * @internal Could, but not must, extend by the child Crypt_* class
581
+ */
582
+ function setPassword($password, $method = 'pbkdf2')
583
+ {
584
+ $key = '';
585
+
586
+ switch ($method) {
587
+ default: // 'pbkdf2' or 'pbkdf1'
588
+ $func_args = func_get_args();
589
+
590
+ // Hash function
591
+ $hash = isset($func_args[2]) ? $func_args[2] : 'sha1';
592
+
593
+ // WPA and WPA2 use the SSID as the salt
594
+ $salt = isset($func_args[3]) ? $func_args[3] : $this->password_default_salt;
595
+
596
+ // RFC2898#section-4.2 uses 1,000 iterations by default
597
+ // WPA and WPA2 use 4,096.
598
+ $count = isset($func_args[4]) ? $func_args[4] : 1000;
599
+
600
+ // Keylength
601
+ if (isset($func_args[5])) {
602
+ $dkLen = $func_args[5];
603
+ } else {
604
+ $dkLen = $method == 'pbkdf1' ? 2 * $this->password_key_size : $this->password_key_size;
605
+ }
606
+
607
+ switch (true) {
608
+ case $method == 'pbkdf1':
609
+ if (!class_exists('Crypt_Hash')) {
610
+ include_once 'Crypt/Hash.php';
611
+ }
612
+ $hashObj = new Crypt_Hash();
613
+ $hashObj->setHash($hash);
614
+ if ($dkLen > $hashObj->getLength()) {
615
+ user_error('Derived key too long');
616
+ return false;
617
+ }
618
+ $t = $password . $salt;
619
+ for ($i = 0; $i < $count; ++$i) {
620
+ $t = $hashObj->hash($t);
621
+ }
622
+ $key = substr($t, 0, $dkLen);
623
+
624
+ $this->setKey(substr($key, 0, $dkLen >> 1));
625
+ $this->setIV(substr($key, $dkLen >> 1));
626
+
627
+ return true;
628
+ // Determining if php[>=5.5.0]'s hash_pbkdf2() function avail- and useable
629
+ case !function_exists('hash_pbkdf2'):
630
+ case !function_exists('hash_algos'):
631
+ case !in_array($hash, hash_algos()):
632
+ if (!class_exists('Crypt_Hash')) {
633
+ include_once 'Crypt/Hash.php';
634
+ }
635
+ $i = 1;
636
+ while (strlen($key) < $dkLen) {
637
+ $hmac = new Crypt_Hash();
638
+ $hmac->setHash($hash);
639
+ $hmac->setKey($password);
640
+ $f = $u = $hmac->hash($salt . pack('N', $i++));
641
+ for ($j = 2; $j <= $count; ++$j) {
642
+ $u = $hmac->hash($u);
643
+ $f^= $u;
644
+ }
645
+ $key.= $f;
646
+ }
647
+ $key = substr($key, 0, $dkLen);
648
+ break;
649
+ default:
650
+ $key = hash_pbkdf2($hash, $password, $salt, $count, $dkLen, true);
651
+ }
652
+ }
653
+
654
+ $this->setKey($key);
655
+
656
+ return true;
657
+ }
658
+
659
+ /**
660
+ * Encrypts a message.
661
+ *
662
+ * $plaintext will be padded with additional bytes such that it's length is a multiple of the block size. Other cipher
663
+ * implementations may or may not pad in the same manner. Other common approaches to padding and the reasons why it's
664
+ * necessary are discussed in the following
665
+ * URL:
666
+ *
667
+ * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
668
+ *
669
+ * An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does.
670
+ * strlen($plaintext) will still need to be a multiple of the block size, however, arbitrary values can be added to make it that
671
+ * length.
672
+ *
673
+ * @see Crypt_Base::decrypt()
674
+ * @access public
675
+ * @param String $plaintext
676
+ * @return String $ciphertext
677
+ * @internal Could, but not must, extend by the child Crypt_* class
678
+ */
679
+ function encrypt($plaintext)
680
+ {
681
+ if ($this->paddable) {
682
+ $plaintext = $this->_pad($plaintext);
683
+ }
684
+
685
+ if ($this->engine === CRYPT_ENGINE_OPENSSL) {
686
+ if ($this->changed) {
687
+ $this->_clearBuffers();
688
+ $this->changed = false;
689
+ }
690
+ switch ($this->mode) {
691
+ case CRYPT_MODE_STREAM:
692
+ return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
693
+ case CRYPT_MODE_ECB:
694
+ $result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
695
+ return !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result;
696
+ case CRYPT_MODE_CBC:
697
+ $result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->encryptIV);
698
+ if ($this->continuousBuffer) {
699
+ $this->encryptIV = substr($result, -$this->block_size);
700
+ }
701
+ return !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result;
702
+ case CRYPT_MODE_CTR:
703
+ return $this->_openssl_ctr_process($plaintext, $this->encryptIV, $this->enbuffer);
704
+ case CRYPT_MODE_CFB:
705
+ // cfb loosely routines inspired by openssl's:
706
+ // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1}
707
+ $ciphertext = '';
708
+ if ($this->continuousBuffer) {
709
+ $iv = &$this->encryptIV;
710
+ $pos = &$this->enbuffer['pos'];
711
+ } else {
712
+ $iv = $this->encryptIV;
713
+ $pos = 0;
714
+ }
715
+ $len = strlen($plaintext);
716
+ $i = 0;
717
+ if ($pos) {
718
+ $orig_pos = $pos;
719
+ $max = $this->block_size - $pos;
720
+ if ($len >= $max) {
721
+ $i = $max;
722
+ $len-= $max;
723
+ $pos = 0;
724
+ } else {
725
+ $i = $len;
726
+ $pos+= $len;
727
+ $len = 0;
728
+ }
729
+ // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize
730
+ $ciphertext = substr($iv, $orig_pos) ^ $plaintext;
731
+ $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
732
+ $plaintext = substr($plaintext, $i);
733
+ }
734
+
735
+ $overflow = $len % $this->block_size;
736
+
737
+ if ($overflow) {
738
+ $ciphertext.= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
739
+ $iv = $this->_string_pop($ciphertext, $this->block_size);
740
+
741
+ $size = $len - $overflow;
742
+ $block = $iv ^ substr($plaintext, -$overflow);
743
+ $iv = substr_replace($iv, $block, 0, $overflow);
744
+ $ciphertext.= $block;
745
+ $pos = $overflow;
746
+ } else if ($len) {
747
+ $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
748
+ $iv = substr($ciphertext, -$this->block_size);
749
+ }
750
+
751
+ return $ciphertext;
752
+ case CRYPT_MODE_OFB:
753
+ return $this->_openssl_ofb_process($plaintext, $this->encryptIV, $this->enbuffer);
754
+ }
755
+ }
756
+
757
+ if ($this->engine === CRYPT_ENGINE_MCRYPT) {
758
+ if ($this->changed) {
759
+ $this->_setupMcrypt();
760
+ $this->changed = false;
761
+ }
762
+ if ($this->enchanged) {
763
+ mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
764
+ $this->enchanged = false;
765
+ }
766
+
767
+ // re: {@link http://phpseclib.sourceforge.net/cfb-demo.phps}
768
+ // using mcrypt's default handing of CFB the above would output two different things. using phpseclib's
769
+ // rewritten CFB implementation the above outputs the same thing twice.
770
+ if ($this->mode == CRYPT_MODE_CFB && $this->continuousBuffer) {
771
+ $block_size = $this->block_size;
772
+ $iv = &$this->encryptIV;
773
+ $pos = &$this->enbuffer['pos'];
774
+ $len = strlen($plaintext);
775
+ $ciphertext = '';
776
+ $i = 0;
777
+ if ($pos) {
778
+ $orig_pos = $pos;
779
+ $max = $block_size - $pos;
780
+ if ($len >= $max) {
781
+ $i = $max;
782
+ $len-= $max;
783
+ $pos = 0;
784
+ } else {
785
+ $i = $len;
786
+ $pos+= $len;
787
+ $len = 0;
788
+ }
789
+ $ciphertext = substr($iv, $orig_pos) ^ $plaintext;
790
+ $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
791
+ $this->enbuffer['enmcrypt_init'] = true;
792
+ }
793
+ if ($len >= $block_size) {
794
+ if ($this->enbuffer['enmcrypt_init'] === false || $len > $this->cfb_init_len) {
795
+ if ($this->enbuffer['enmcrypt_init'] === true) {
796
+ mcrypt_generic_init($this->enmcrypt, $this->key, $iv);
797
+ $this->enbuffer['enmcrypt_init'] = false;
798
+ }
799
+ $ciphertext.= mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % $block_size));
800
+ $iv = substr($ciphertext, -$block_size);
801
+ $len%= $block_size;
802
+ } else {
803
+ while ($len >= $block_size) {
804
+ $iv = mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, $block_size);
805
+ $ciphertext.= $iv;
806
+ $len-= $block_size;
807
+ $i+= $block_size;
808
+ }
809
+ }
810
+ }
811
+
812
+ if ($len) {
813
+ $iv = mcrypt_generic($this->ecb, $iv);
814
+ $block = $iv ^ substr($plaintext, -$len);
815
+ $iv = substr_replace($iv, $block, 0, $len);
816
+ $ciphertext.= $block;
817
+ $pos = $len;
818
+ }
819
+
820
+ return $ciphertext;
821
+ }
822
+
823
+ $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
824
+
825
+ if (!$this->continuousBuffer) {
826
+ mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
827
+ }
828
+
829
+ return $ciphertext;
830
+ }
831
+
832
+ if ($this->changed) {
833
+ $this->_setup();
834
+ $this->changed = false;
835
+ }
836
+ if ($this->use_inline_crypt) {
837
+ $inline = $this->inline_crypt;
838
+ return $inline('encrypt', $this, $plaintext);
839
+ }
840
+
841
+ $buffer = &$this->enbuffer;
842
+ $block_size = $this->block_size;
843
+ $ciphertext = '';
844
+ switch ($this->mode) {
845
+ case CRYPT_MODE_ECB:
846
+ for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
847
+ $ciphertext.= $this->_encryptBlock(substr($plaintext, $i, $block_size));
848
+ }
849
+ break;
850
+ case CRYPT_MODE_CBC:
851
+ $xor = $this->encryptIV;
852
+ for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
853
+ $block = substr($plaintext, $i, $block_size);
854
+ $block = $this->_encryptBlock($block ^ $xor);
855
+ $xor = $block;
856
+ $ciphertext.= $block;
857
+ }
858
+ if ($this->continuousBuffer) {
859
+ $this->encryptIV = $xor;
860
+ }
861
+ break;
862
+ case CRYPT_MODE_CTR:
863
+ $xor = $this->encryptIV;
864
+ if (strlen($buffer['ciphertext'])) {
865
+ for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
866
+ $block = substr($plaintext, $i, $block_size);
867
+ if (strlen($block) > strlen($buffer['ciphertext'])) {
868
+ $buffer['ciphertext'].= $this->_encryptBlock($xor);
869
+ }
870
+ $this->_increment_str($xor);
871
+ $key = $this->_string_shift($buffer['ciphertext'], $block_size);
872
+ $ciphertext.= $block ^ $key;
873
+ }
874
+ } else {
875
+ for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
876
+ $block = substr($plaintext, $i, $block_size);
877
+ $key = $this->_encryptBlock($xor);
878
+ $this->_increment_str($xor);
879
+ $ciphertext.= $block ^ $key;
880
+ }
881
+ }
882
+ if ($this->continuousBuffer) {
883
+ $this->encryptIV = $xor;
884
+ if ($start = strlen($plaintext) % $block_size) {
885
+ $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext'];
886
+ }
887
+ }
888
+ break;
889
+ case CRYPT_MODE_CFB:
890
+ // cfb loosely routines inspired by openssl's:
891
+ // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1}
892
+ if ($this->continuousBuffer) {
893
+ $iv = &$this->encryptIV;
894
+ $pos = &$buffer['pos'];
895
+ } else {
896
+ $iv = $this->encryptIV;
897
+ $pos = 0;
898
+ }
899
+ $len = strlen($plaintext);
900
+ $i = 0;
901
+ if ($pos) {
902
+ $orig_pos = $pos;
903
+ $max = $block_size - $pos;
904
+ if ($len >= $max) {
905
+ $i = $max;
906
+ $len-= $max;
907
+ $pos = 0;
908
+ } else {
909
+ $i = $len;
910
+ $pos+= $len;
911
+ $len = 0;
912
+ }
913
+ // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize
914
+ $ciphertext = substr($iv, $orig_pos) ^ $plaintext;
915
+ $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
916
+ }
917
+ while ($len >= $block_size) {
918
+ $iv = $this->_encryptBlock($iv) ^ substr($plaintext, $i, $block_size);
919
+ $ciphertext.= $iv;
920
+ $len-= $block_size;
921
+ $i+= $block_size;
922
+ }
923
+ if ($len) {
924
+ $iv = $this->_encryptBlock($iv);
925
+ $block = $iv ^ substr($plaintext, $i);
926
+ $iv = substr_replace($iv, $block, 0, $len);
927
+ $ciphertext.= $block;
928
+ $pos = $len;
929
+ }
930
+ break;
931
+ case CRYPT_MODE_OFB:
932
+ $xor = $this->encryptIV;
933
+ if (strlen($buffer['xor'])) {
934
+ for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
935
+ $block = substr($plaintext, $i, $block_size);
936
+ if (strlen($block) > strlen($buffer['xor'])) {
937
+ $xor = $this->_encryptBlock($xor);
938
+ $buffer['xor'].= $xor;
939
+ }
940
+ $key = $this->_string_shift($buffer['xor'], $block_size);
941
+ $ciphertext.= $block ^ $key;
942
+ }
943
+ } else {
944
+ for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
945
+ $xor = $this->_encryptBlock($xor);
946
+ $ciphertext.= substr($plaintext, $i, $block_size) ^ $xor;
947
+ }
948
+ $key = $xor;
949
+ }
950
+ if ($this->continuousBuffer) {
951
+ $this->encryptIV = $xor;
952
+ if ($start = strlen($plaintext) % $block_size) {
953
+ $buffer['xor'] = substr($key, $start) . $buffer['xor'];
954
+ }
955
+ }
956
+ break;
957
+ case CRYPT_MODE_STREAM:
958
+ $ciphertext = $this->_encryptBlock($plaintext);
959
+ break;
960
+ }
961
+
962
+ return $ciphertext;
963
+ }
964
+
965
+ /**
966
+ * Decrypts a message.
967
+ *
968
+ * If strlen($ciphertext) is not a multiple of the block size, null bytes will be added to the end of the string until
969
+ * it is.
970
+ *
971
+ * @see Crypt_Base::encrypt()
972
+ * @access public
973
+ * @param String $ciphertext
974
+ * @return String $plaintext
975
+ * @internal Could, but not must, extend by the child Crypt_* class
976
+ */
977
+ function decrypt($ciphertext)
978
+ {
979
+ if ($this->paddable) {
980
+ // we pad with chr(0) since that's what mcrypt_generic does. to quote from {@link http://www.php.net/function.mcrypt-generic}:
981
+ // "The data is padded with "\0" to make sure the length of the data is n * blocksize."
982
+ $ciphertext = str_pad($ciphertext, strlen($ciphertext) + ($this->block_size - strlen($ciphertext) % $this->block_size) % $this->block_size, chr(0));
983
+ }
984
+
985
+ if ($this->engine === CRYPT_ENGINE_OPENSSL) {
986
+ if ($this->changed) {
987
+ $this->_clearBuffers();
988
+ $this->changed = false;
989
+ }
990
+ switch ($this->mode) {
991
+ case CRYPT_MODE_STREAM:
992
+ $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
993
+ break;
994
+ case CRYPT_MODE_ECB:
995
+ if (!defined('OPENSSL_RAW_DATA')) {
996
+ $ciphetext.= openssl_encrypt('', $this->cipher_name_openssl_ecb, $this->key, true);
997
+ }
998
+ $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
999
+ break;
1000
+ case CRYPT_MODE_CBC:
1001
+ if (!defined('OPENSSL_RAW_DATA')) {
1002
+ $padding = str_repeat(chr($this->block_size), $this->block_size) ^ substr($ciphertext, -$this->block_size);
1003
+ $ciphertext.= substr(openssl_encrypt($padding, $this->cipher_name_openssl_ecb, $this->key, true), 0, $this->block_size);
1004
+ }
1005
+ $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->decryptIV);
1006
+ if ($this->continuousBuffer) {
1007
+ $this->decryptIV = substr($ciphertext, -$this->block_size);
1008
+ }
1009
+ break;
1010
+ case CRYPT_MODE_CTR:
1011
+ $plaintext = $this->_openssl_ctr_process($ciphertext, $this->decryptIV, $this->debuffer);
1012
+ break;
1013
+ case CRYPT_MODE_CFB:
1014
+ // cfb loosely routines inspired by openssl's:
1015
+ // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1}
1016
+ $plaintext = '';
1017
+ if ($this->continuousBuffer) {
1018
+ $iv = &$this->decryptIV;
1019
+ $pos = &$this->buffer['pos'];
1020
+ } else {
1021
+ $iv = $this->decryptIV;
1022
+ $pos = 0;
1023
+ }
1024
+ $len = strlen($ciphertext);
1025
+ $i = 0;
1026
+ if ($pos) {
1027
+ $orig_pos = $pos;
1028
+ $max = $this->block_size - $pos;
1029
+ if ($len >= $max) {
1030
+ $i = $max;
1031
+ $len-= $max;
1032
+ $pos = 0;
1033
+ } else {
1034
+ $i = $len;
1035
+ $pos+= $len;
1036
+ $len = 0;
1037
+ }
1038
+ // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $this->blocksize
1039
+ $plaintext = substr($iv, $orig_pos) ^ $ciphertext;
1040
+ $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
1041
+ $ciphertext = substr($ciphertext, $i);
1042
+ }
1043
+ $overflow = $len % $this->block_size;
1044
+ if ($overflow) {
1045
+ $plaintext.= openssl_decrypt(substr($ciphertext, 0, -$overflow), $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
1046
+ if ($len - $overflow) {
1047
+ $iv = substr($ciphertext, -$overflow - $this->block_size, -$overflow);
1048
+ }
1049
+ $iv = openssl_encrypt(str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
1050
+ $plaintext.= $iv ^ substr($ciphertext, -$overflow);
1051
+ $iv = substr_replace($iv, substr($ciphertext, -$overflow), 0, $overflow);
1052
+ $pos = $overflow;
1053
+ } else if ($len) {
1054
+ $plaintext.= openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
1055
+ $iv = substr($ciphertext, -$this->block_size);
1056
+ }
1057
+ break;
1058
+ case CRYPT_MODE_OFB:
1059
+ $plaintext = $this->_openssl_ofb_process($ciphertext, $this->decryptIV, $this->debuffer);
1060
+ }
1061
+
1062
+ return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
1063
+ }
1064
+
1065
+ if ($this->engine === CRYPT_ENGINE_MCRYPT) {
1066
+ $block_size = $this->block_size;
1067
+ if ($this->changed) {
1068
+ $this->_setupMcrypt();
1069
+ $this->changed = false;
1070
+ }
1071
+ if ($this->dechanged) {
1072
+ mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
1073
+ $this->dechanged = false;
1074
+ }
1075
+
1076
+ if ($this->mode == CRYPT_MODE_CFB && $this->continuousBuffer) {
1077
+ $iv = &$this->decryptIV;
1078
+ $pos = &$this->debuffer['pos'];
1079
+ $len = strlen($ciphertext);
1080
+ $plaintext = '';
1081
+ $i = 0;
1082
+ if ($pos) {
1083
+ $orig_pos = $pos;
1084
+ $max = $block_size - $pos;
1085
+ if ($len >= $max) {
1086
+ $i = $max;
1087
+ $len-= $max;
1088
+ $pos = 0;
1089
+ } else {
1090
+ $i = $len;
1091
+ $pos+= $len;
1092
+ $len = 0;
1093
+ }
1094
+ // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize
1095
+ $plaintext = substr($iv, $orig_pos) ^ $ciphertext;
1096
+ $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
1097
+ }
1098
+ if ($len >= $block_size) {
1099
+ $cb = substr($ciphertext, $i, $len - $len % $block_size);
1100
+ $plaintext.= mcrypt_generic($this->ecb, $iv . $cb) ^ $cb;
1101
+ $iv = substr($cb, -$block_size);
1102
+ $len%= $block_size;
1103
+ }
1104
+ if ($len) {
1105
+ $iv = mcrypt_generic($this->ecb, $iv);
1106
+ $plaintext.= $iv ^ substr($ciphertext, -$len);
1107
+ $iv = substr_replace($iv, substr($ciphertext, -$len), 0, $len);
1108
+ $pos = $len;
1109
+ }
1110
+
1111
+ return $plaintext;
1112
+ }
1113
+
1114
+ $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
1115
+
1116
+ if (!$this->continuousBuffer) {
1117
+ mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
1118
+ }
1119
+
1120
+ return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
1121
+ }
1122
+
1123
+ if ($this->changed) {
1124
+ $this->_setup();
1125
+ $this->changed = false;
1126
+ }
1127
+ if ($this->use_inline_crypt) {
1128
+ $inline = $this->inline_crypt;
1129
+ return $inline('decrypt', $this, $ciphertext);
1130
+ }
1131
+
1132
+ $block_size = $this->block_size;
1133
+
1134
+ $buffer = &$this->debuffer;
1135
+ $plaintext = '';
1136
+ switch ($this->mode) {
1137
+ case CRYPT_MODE_ECB:
1138
+ for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
1139
+ $plaintext.= $this->_decryptBlock(substr($ciphertext, $i, $block_size));
1140
+ }
1141
+ break;
1142
+ case CRYPT_MODE_CBC:
1143
+ $xor = $this->decryptIV;
1144
+ for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
1145
+ $block = substr($ciphertext, $i, $block_size);
1146
+ $plaintext.= $this->_decryptBlock($block) ^ $xor;
1147
+ $xor = $block;
1148
+ }
1149
+ if ($this->continuousBuffer) {
1150
+ $this->decryptIV = $xor;
1151
+ }
1152
+ break;
1153
+ case CRYPT_MODE_CTR:
1154
+ $xor = $this->decryptIV;
1155
+ if (strlen($buffer['ciphertext'])) {
1156
+ for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
1157
+ $block = substr($ciphertext, $i, $block_size);
1158
+ if (strlen($block) > strlen($buffer['ciphertext'])) {
1159
+ $buffer['ciphertext'].= $this->_encryptBlock($xor);
1160
+ $this->_increment_str($xor);
1161
+ }
1162
+ $key = $this->_string_shift($buffer['ciphertext'], $block_size);
1163
+ $plaintext.= $block ^ $key;
1164
+ }
1165
+ } else {
1166
+ for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
1167
+ $block = substr($ciphertext, $i, $block_size);
1168
+ $key = $this->_encryptBlock($xor);
1169
+ $this->_increment_str($xor);
1170
+ $plaintext.= $block ^ $key;
1171
+ }
1172
+ }
1173
+ if ($this->continuousBuffer) {
1174
+ $this->decryptIV = $xor;
1175
+ if ($start = strlen($ciphertext) % $block_size) {
1176
+ $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext'];
1177
+ }
1178
+ }
1179
+ break;
1180
+ case CRYPT_MODE_CFB:
1181
+ if ($this->continuousBuffer) {
1182
+ $iv = &$this->decryptIV;
1183
+ $pos = &$buffer['pos'];
1184
+ } else {
1185
+ $iv = $this->decryptIV;
1186
+ $pos = 0;
1187
+ }
1188
+ $len = strlen($ciphertext);
1189
+ $i = 0;
1190
+ if ($pos) {
1191
+ $orig_pos = $pos;
1192
+ $max = $block_size - $pos;
1193
+ if ($len >= $max) {
1194
+ $i = $max;
1195
+ $len-= $max;
1196
+ $pos = 0;
1197
+ } else {
1198
+ $i = $len;
1199
+ $pos+= $len;
1200
+ $len = 0;
1201
+ }
1202
+ // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize
1203
+ $plaintext = substr($iv, $orig_pos) ^ $ciphertext;
1204
+ $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
1205
+ }
1206
+ while ($len >= $block_size) {
1207
+ $iv = $this->_encryptBlock($iv);
1208
+ $cb = substr($ciphertext, $i, $block_size);
1209
+ $plaintext.= $iv ^ $cb;
1210
+ $iv = $cb;
1211
+ $len-= $block_size;
1212
+ $i+= $block_size;
1213
+ }
1214
+ if ($len) {
1215
+ $iv = $this->_encryptBlock($iv);
1216
+ $plaintext.= $iv ^ substr($ciphertext, $i);
1217
+ $iv = substr_replace($iv, substr($ciphertext, $i), 0, $len);
1218
+ $pos = $len;
1219
+ }
1220
+ break;
1221
+ case CRYPT_MODE_OFB:
1222
+ $xor = $this->decryptIV;
1223
+ if (strlen($buffer['xor'])) {
1224
+ for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
1225
+ $block = substr($ciphertext, $i, $block_size);
1226
+ if (strlen($block) > strlen($buffer['xor'])) {
1227
+ $xor = $this->_encryptBlock($xor);
1228
+ $buffer['xor'].= $xor;
1229
+ }
1230
+ $key = $this->_string_shift($buffer['xor'], $block_size);
1231
+ $plaintext.= $block ^ $key;
1232
+ }
1233
+ } else {
1234
+ for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
1235
+ $xor = $this->_encryptBlock($xor);
1236
+ $plaintext.= substr($ciphertext, $i, $block_size) ^ $xor;
1237
+ }
1238
+ $key = $xor;
1239
+ }
1240
+ if ($this->continuousBuffer) {
1241
+ $this->decryptIV = $xor;
1242
+ if ($start = strlen($ciphertext) % $block_size) {
1243
+ $buffer['xor'] = substr($key, $start) . $buffer['xor'];
1244
+ }
1245
+ }
1246
+ break;
1247
+ case CRYPT_MODE_STREAM:
1248
+ $plaintext = $this->_decryptBlock($ciphertext);
1249
+ break;
1250
+ }
1251
+ return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
1252
+ }
1253
+
1254
+ /**
1255
+ * OpenSSL CTR Processor
1256
+ *
1257
+ * PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream
1258
+ * for CTR is the same for both encrypting and decrypting this function is re-used by both Crypt_Base::encrypt()
1259
+ * and Crypt_Base::decrypt(). Also, OpenSSL doesn't implement CTR for all of it's symmetric ciphers so this
1260
+ * function will emulate CTR with ECB when necesary.
1261
+ *
1262
+ * @see Crypt_Base::encrypt()
1263
+ * @see Crypt_Base::decrypt()
1264
+ * @param String $plaintext
1265
+ * @param String $encryptIV
1266
+ * @param Array $buffer
1267
+ * @return String
1268
+ * @access private
1269
+ */
1270
+ function _openssl_ctr_process($plaintext, &$encryptIV, &$buffer)
1271
+ {
1272
+ $ciphertext = '';
1273
+
1274
+ $block_size = $this->block_size;
1275
+ $key = $this->key;
1276
+
1277
+ if ($this->openssl_emulate_ctr) {
1278
+ $xor = $encryptIV;
1279
+ if (strlen($buffer['ciphertext'])) {
1280
+ for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
1281
+ $block = substr($plaintext, $i, $block_size);
1282
+ if (strlen($block) > strlen($buffer['ciphertext'])) {
1283
+ $result = openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
1284
+ $result = !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result;
1285
+ $buffer['ciphertext'].= $result;
1286
+ }
1287
+ $this->_increment_str($xor);
1288
+ $otp = $this->_string_shift($buffer['ciphertext'], $block_size);
1289
+ $ciphertext.= $block ^ $otp;
1290
+ }
1291
+ } else {
1292
+ for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
1293
+ $block = substr($plaintext, $i, $block_size);
1294
+ $otp = openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
1295
+ $otp = !defined('OPENSSL_RAW_DATA') ? substr($otp, 0, -$this->block_size) : $otp;
1296
+ $this->_increment_str($xor);
1297
+ $ciphertext.= $block ^ $otp;
1298
+ }
1299
+ }
1300
+ if ($this->continuousBuffer) {
1301
+ $encryptIV = $xor;
1302
+ if ($start = strlen($plaintext) % $block_size) {
1303
+ $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext'];
1304
+ }
1305
+ }
1306
+
1307
+ return $ciphertext;
1308
+ }
1309
+
1310
+ if (strlen($buffer['ciphertext'])) {
1311
+ $ciphertext = $plaintext ^ $this->_string_shift($buffer['ciphertext'], strlen($plaintext));
1312
+ $plaintext = substr($plaintext, strlen($ciphertext));
1313
+
1314
+ if (!strlen($plaintext)) {
1315
+ return $ciphertext;
1316
+ }
1317
+ }
1318
+
1319
+ $overflow = strlen($plaintext) % $block_size;
1320
+ if ($overflow) {
1321
+ $plaintext2 = $this->_string_pop($plaintext, $overflow); // ie. trim $plaintext to a multiple of $block_size and put rest of $plaintext in $plaintext2
1322
+ $encrypted = openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV);
1323
+ $temp = $this->_string_pop($encrypted, $block_size);
1324
+ $ciphertext.= $encrypted . ($plaintext2 ^ $temp);
1325
+ if ($this->continuousBuffer) {
1326
+ $buffer['ciphertext'] = substr($temp, $overflow);
1327
+ $encryptIV = $temp;
1328
+ }
1329
+ } else if (!strlen($buffer['ciphertext'])) {
1330
+ $ciphertext.= openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV);
1331
+ $temp = $this->_string_pop($ciphertext, $block_size);
1332
+ if ($this->continuousBuffer) {
1333
+ $encryptIV = $temp;
1334
+ }
1335
+ }
1336
+ if ($this->continuousBuffer) {
1337
+ if (!defined('OPENSSL_RAW_DATA')) {
1338
+ $encryptIV.= openssl_encrypt('', $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
1339
+ }
1340
+ $encryptIV = openssl_decrypt($encryptIV, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
1341
+ if ($overflow) {
1342
+ $this->_increment_str($encryptIV);
1343
+ }
1344
+ }
1345
+
1346
+ return $ciphertext;
1347
+ }
1348
+
1349
+ /**
1350
+ * OpenSSL OFB Processor
1351
+ *
1352
+ * PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream
1353
+ * for OFB is the same for both encrypting and decrypting this function is re-used by both Crypt_Base::encrypt()
1354
+ * and Crypt_Base::decrypt().
1355
+ *
1356
+ * @see Crypt_Base::encrypt()
1357
+ * @see Crypt_Base::decrypt()
1358
+ * @param String $plaintext
1359
+ * @param String $encryptIV
1360
+ * @param Array $buffer
1361
+ * @return String
1362
+ * @access private
1363
+ */
1364
+ function _openssl_ofb_process($plaintext, &$encryptIV, &$buffer)
1365
+ {
1366
+ if (strlen($buffer['xor'])) {
1367
+ $ciphertext = $plaintext ^ $buffer['xor'];
1368
+ $buffer['xor'] = substr($buffer['xor'], strlen($ciphertext));
1369
+ $plaintext = substr($plaintext, strlen($ciphertext));
1370
+ } else {
1371
+ $ciphertext = '';
1372
+ }
1373
+
1374
+ $block_size = $this->block_size;
1375
+
1376
+ $len = strlen($plaintext);
1377
+ $key = $this->key;
1378
+ $overflow = $len % $block_size;
1379
+
1380
+ if (strlen($plaintext)) {
1381
+ if ($overflow) {
1382
+ $ciphertext.= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV);
1383
+ $xor = $this->_string_pop($ciphertext, $block_size);
1384
+ if ($this->continuousBuffer) {
1385
+ $encryptIV = $xor;
1386
+ }
1387
+ $ciphertext.= $this->_string_shift($xor, $overflow) ^ substr($plaintext, -$overflow);
1388
+ if ($this->continuousBuffer) {
1389
+ $buffer['xor'] = $xor;
1390
+ }
1391
+ } else {
1392
+ $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV);
1393
+ if ($this->continuousBuffer) {
1394
+ $encryptIV = substr($ciphertext, -$block_size) ^ substr($plaintext, -$block_size);
1395
+ }
1396
+ }
1397
+ }
1398
+
1399
+ return $ciphertext;
1400
+ }
1401
+
1402
+ /**
1403
+ * phpseclib <-> OpenSSL Mode Mapper
1404
+ *
1405
+ * May need to be overwritten by classes extending this one in some cases
1406
+ *
1407
+ * @return Integer
1408
+ * @access private
1409
+ */
1410
+ function _openssl_translate_mode()
1411
+ {
1412
+ switch ($this->mode) {
1413
+ case CRYPT_MODE_ECB:
1414
+ return 'ecb';
1415
+ case CRYPT_MODE_CBC:
1416
+ return 'cbc';
1417
+ case CRYPT_MODE_CTR:
1418
+ return 'ctr';
1419
+ case CRYPT_MODE_CFB:
1420
+ return 'cfb';
1421
+ case CRYPT_MODE_OFB:
1422
+ return 'ofb';
1423
+ }
1424
+ }
1425
+
1426
+ /**
1427
+ * Pad "packets".
1428
+ *
1429
+ * Block ciphers working by encrypting between their specified [$this->]block_size at a time
1430
+ * If you ever need to encrypt or decrypt something that isn't of the proper length, it becomes necessary to
1431
+ * pad the input so that it is of the proper length.
1432
+ *
1433
+ * Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH,
1434
+ * where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping
1435
+ * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is
1436
+ * transmitted separately)
1437
+ *
1438
+ * @see Crypt_Base::disablePadding()
1439
+ * @access public
1440
+ */
1441
+ function enablePadding()
1442
+ {
1443
+ $this->padding = true;
1444
+ }
1445
+
1446
+ /**
1447
+ * Do not pad packets.
1448
+ *
1449
+ * @see Crypt_Base::enablePadding()
1450
+ * @access public
1451
+ */
1452
+ function disablePadding()
1453
+ {
1454
+ $this->padding = false;
1455
+ }
1456
+
1457
+ /**
1458
+ * Treat consecutive "packets" as if they are a continuous buffer.
1459
+ *
1460
+ * Say you have a 32-byte plaintext $plaintext. Using the default behavior, the two following code snippets
1461
+ * will yield different outputs:
1462
+ *
1463
+ * <code>
1464
+ * echo $rijndael->encrypt(substr($plaintext, 0, 16));
1465
+ * echo $rijndael->encrypt(substr($plaintext, 16, 16));
1466
+ * </code>
1467
+ * <code>
1468
+ * echo $rijndael->encrypt($plaintext);
1469
+ * </code>
1470
+ *
1471
+ * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates
1472
+ * another, as demonstrated with the following:
1473
+ *
1474
+ * <code>
1475
+ * $rijndael->encrypt(substr($plaintext, 0, 16));
1476
+ * echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16)));
1477
+ * </code>
1478
+ * <code>
1479
+ * echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16)));
1480
+ * </code>
1481
+ *
1482
+ * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different
1483
+ * outputs. The reason is due to the fact that the initialization vector's change after every encryption /
1484
+ * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
1485
+ *
1486
+ * Put another way, when the continuous buffer is enabled, the state of the Crypt_*() object changes after each
1487
+ * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
1488
+ * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
1489
+ * however, they are also less intuitive and more likely to cause you problems.
1490
+ *
1491
+ * @see Crypt_Base::disableContinuousBuffer()
1492
+ * @access public
1493
+ * @internal Could, but not must, extend by the child Crypt_* class
1494
+ */
1495
+ function enableContinuousBuffer()
1496
+ {
1497
+ if ($this->mode == CRYPT_MODE_ECB) {
1498
+ return;
1499
+ }
1500
+
1501
+ $this->continuousBuffer = true;
1502
+
1503
+ $this->_setEngine();
1504
+ }
1505
+
1506
+ /**
1507
+ * Treat consecutive packets as if they are a discontinuous buffer.
1508
+ *
1509
+ * The default behavior.
1510
+ *
1511
+ * @see Crypt_Base::enableContinuousBuffer()
1512
+ * @access public
1513
+ * @internal Could, but not must, extend by the child Crypt_* class
1514
+ */
1515
+ function disableContinuousBuffer()
1516
+ {
1517
+ if ($this->mode == CRYPT_MODE_ECB) {
1518
+ return;
1519
+ }
1520
+ if (!$this->continuousBuffer) {
1521
+ return;
1522
+ }
1523
+
1524
+ $this->continuousBuffer = false;
1525
+ $this->changed = true;
1526
+
1527
+ $this->_setEngine();
1528
+ }
1529
+
1530
+ /**
1531
+ * Test for engine validity
1532
+ *
1533
+ * @see Crypt_Base::Crypt_Base()
1534
+ * @param Integer $engine
1535
+ * @access public
1536
+ * @return Boolean
1537
+ */
1538
+ function isValidEngine($engine)
1539
+ {
1540
+ switch ($engine) {
1541
+ case CRYPT_ENGINE_OPENSSL:
1542
+ if ($this->mode == CRYPT_MODE_STREAM && $this->continuousBuffer) {
1543
+ return false;
1544
+ }
1545
+ $this->openssl_emulate_ctr = false;
1546
+ $result = $this->cipher_name_openssl &&
1547
+ extension_loaded('openssl') &&
1548
+ // PHP 5.3.0 - 5.3.2 did not let you set IV's
1549
+ version_compare(PHP_VERSION, '5.3.3', '>=');
1550
+ if (!$result) {
1551
+ return false;
1552
+ }
1553
+
1554
+ // prior to PHP 5.4.0 OPENSSL_RAW_DATA and OPENSSL_ZERO_PADDING were not defined. instead of expecting an integer
1555
+ // $options openssl_encrypt expected a boolean $raw_data.
1556
+ if (!defined('OPENSSL_RAW_DATA')) {
1557
+ $this->openssl_options = true;
1558
+ } else {
1559
+ $this->openssl_options = OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING;
1560
+ }
1561
+
1562
+ $methods = openssl_get_cipher_methods();
1563
+ if (in_array($this->cipher_name_openssl, $methods)) {
1564
+ return true;
1565
+ }
1566
+ // not all of openssl's symmetric cipher's support ctr. for those
1567
+ // that don't we'll emulate it
1568
+ switch ($this->mode) {
1569
+ case CRYPT_MODE_CTR:
1570
+ if (in_array($this->cipher_name_openssl_ecb, $methods)) {
1571
+ $this->openssl_emulate_ctr = true;
1572
+ return true;
1573
+ }
1574
+ }
1575
+ return false;
1576
+ case CRYPT_ENGINE_MCRYPT:
1577
+ return $this->cipher_name_mcrypt &&
1578
+ extension_loaded('mcrypt') &&
1579
+ in_array($this->cipher_name_mcrypt, mcrypt_list_algorithms());
1580
+ case CRYPT_ENGINE_INTERNAL:
1581
+ return true;
1582
+ }
1583
+
1584
+ return false;
1585
+ }
1586
+
1587
+ /**
1588
+ * Sets the preferred crypt engine
1589
+ *
1590
+ * Currently, $engine could be:
1591
+ *
1592
+ * - CRYPT_ENGINE_OPENSSL [very fast]
1593
+ *
1594
+ * - CRYPT_ENGINE_MCRYPT [fast]
1595
+ *
1596
+ * - CRYPT_ENGINE_INTERNAL [slow]
1597
+ *
1598
+ * If the preferred crypt engine is not available the fastest available one will be used
1599
+ *
1600
+ * @see Crypt_Base::Crypt_Base()
1601
+ * @param Integer $engine
1602
+ * @access public
1603
+ */
1604
+ function setPreferredEngine($engine)
1605
+ {
1606
+ switch ($engine) {
1607
+ //case CRYPT_ENGINE_OPENSSL:
1608
+ case CRYPT_ENGINE_MCRYPT:
1609
+ case CRYPT_ENGINE_INTERNAL:
1610
+ $this->preferredEngine = $engine;
1611
+ break;
1612
+ default:
1613
+ $this->preferredEngine = CRYPT_ENGINE_OPENSSL;
1614
+ }
1615
+
1616
+ $this->_setEngine();
1617
+ }
1618
+
1619
+ /**
1620
+ * Returns the engine currently being utilized
1621
+ *
1622
+ * @see Crypt_Base::_setEngine()
1623
+ * @access public
1624
+ */
1625
+ function getEngine()
1626
+ {
1627
+ return $this->engine;
1628
+ }
1629
+
1630
+ /**
1631
+ * Sets the engine as appropriate
1632
+ *
1633
+ * @see Crypt_Base::Crypt_Base()
1634
+ * @access private
1635
+ */
1636
+ function _setEngine()
1637
+ {
1638
+ $this->engine = null;
1639
+
1640
+ $candidateEngines = array(
1641
+ $this->preferredEngine,
1642
+ CRYPT_ENGINE_OPENSSL,
1643
+ CRYPT_ENGINE_MCRYPT
1644
+ );
1645
+ foreach ($candidateEngines as $engine) {
1646
+ if ($this->isValidEngine($engine)) {
1647
+ $this->engine = $engine;
1648
+ break;
1649
+ }
1650
+ }
1651
+ if (!$this->engine) {
1652
+ $this->engine = CRYPT_ENGINE_INTERNAL;
1653
+ }
1654
+
1655
+ if ($this->engine != CRYPT_ENGINE_MCRYPT && $this->enmcrypt) {
1656
+ // Closing the current mcrypt resource(s). _mcryptSetup() will, if needed,
1657
+ // (re)open them with the module named in $this->cipher_name_mcrypt
1658
+ mcrypt_module_close($this->enmcrypt);
1659
+ mcrypt_module_close($this->demcrypt);
1660
+ $this->enmcrypt = null;
1661
+ $this->demcrypt = null;
1662
+
1663
+ if ($this->ecb) {
1664
+ mcrypt_module_close($this->ecb);
1665
+ $this->ecb = null;
1666
+ }
1667
+ }
1668
+
1669
+ $this->changed = true;
1670
+ }
1671
+
1672
+ /**
1673
+ * Encrypts a block
1674
+ *
1675
+ * @access private
1676
+ * @param String $in
1677
+ * @return String
1678
+ * @internal Must be extended by the child Crypt_* class
1679
+ */
1680
+ function _encryptBlock($in)
1681
+ {
1682
+ user_error((version_compare(PHP_VERSION, '5.0.0', '>=') ? __METHOD__ : __FUNCTION__) . '() must extend by class ' . get_class($this), E_USER_ERROR);
1683
+ }
1684
+
1685
+ /**
1686
+ * Decrypts a block
1687
+ *
1688
+ * @access private
1689
+ * @param String $in
1690
+ * @return String
1691
+ * @internal Must be extended by the child Crypt_* class
1692
+ */
1693
+ function _decryptBlock($in)
1694
+ {
1695
+ user_error((version_compare(PHP_VERSION, '5.0.0', '>=') ? __METHOD__ : __FUNCTION__) . '() must extend by class ' . get_class($this), E_USER_ERROR);
1696
+ }
1697
+
1698
+ /**
1699
+ * Setup the key (expansion)
1700
+ *
1701
+ * Only used if $engine == CRYPT_ENGINE_INTERNAL
1702
+ *
1703
+ * @see Crypt_Base::_setup()
1704
+ * @access private
1705
+ * @internal Must be extended by the child Crypt_* class
1706
+ */
1707
+ function _setupKey()
1708
+ {
1709
+ user_error((version_compare(PHP_VERSION, '5.0.0', '>=') ? __METHOD__ : __FUNCTION__) . '() must extend by class ' . get_class($this), E_USER_ERROR);
1710
+ }
1711
+
1712
+ /**
1713
+ * Setup the CRYPT_ENGINE_INTERNAL $engine
1714
+ *
1715
+ * (re)init, if necessary, the internal cipher $engine and flush all $buffers
1716
+ * Used (only) if $engine == CRYPT_ENGINE_INTERNAL
1717
+ *
1718
+ * _setup() will be called each time if $changed === true
1719
+ * typically this happens when using one or more of following public methods:
1720
+ *
1721
+ * - setKey()
1722
+ *
1723
+ * - setIV()
1724
+ *
1725
+ * - disableContinuousBuffer()
1726
+ *
1727
+ * - First run of encrypt() / decrypt() with no init-settings
1728
+ *
1729
+ * @see setKey()
1730
+ * @see setIV()
1731
+ * @see disableContinuousBuffer()
1732
+ * @access private
1733
+ * @internal _setup() is always called before en/decryption.
1734
+ * @internal Could, but not must, extend by the child Crypt_* class
1735
+ */
1736
+ function _setup()
1737
+ {
1738
+ $this->_clearBuffers();
1739
+ $this->_setupKey();
1740
+
1741
+ if ($this->use_inline_crypt) {
1742
+ $this->_setupInlineCrypt();
1743
+ }
1744
+ }
1745
+
1746
+ /**
1747
+ * Setup the CRYPT_ENGINE_MCRYPT $engine
1748
+ *
1749
+ * (re)init, if necessary, the (ext)mcrypt resources and flush all $buffers
1750
+ * Used (only) if $engine = CRYPT_ENGINE_MCRYPT
1751
+ *
1752
+ * _setupMcrypt() will be called each time if $changed === true
1753
+ * typically this happens when using one or more of following public methods:
1754
+ *
1755
+ * - setKey()
1756
+ *
1757
+ * - setIV()
1758
+ *
1759
+ * - disableContinuousBuffer()
1760
+ *
1761
+ * - First run of encrypt() / decrypt()
1762
+ *
1763
+ * @see setKey()
1764
+ * @see setIV()
1765
+ * @see disableContinuousBuffer()
1766
+ * @access private
1767
+ * @internal Could, but not must, extend by the child Crypt_* class
1768
+ */
1769
+ function _setupMcrypt()
1770
+ {
1771
+ $this->_clearBuffers();
1772
+ $this->enchanged = $this->dechanged = true;
1773
+
1774
+ if (!isset($this->enmcrypt)) {
1775
+ static $mcrypt_modes = array(
1776
+ CRYPT_MODE_CTR => 'ctr',
1777
+ CRYPT_MODE_ECB => MCRYPT_MODE_ECB,
1778
+ CRYPT_MODE_CBC => MCRYPT_MODE_CBC,
1779
+ CRYPT_MODE_CFB => 'ncfb',
1780
+ CRYPT_MODE_OFB => MCRYPT_MODE_NOFB,
1781
+ CRYPT_MODE_STREAM => MCRYPT_MODE_STREAM,
1782
+ );
1783
+
1784
+ $this->demcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], '');
1785
+ $this->enmcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], '');
1786
+
1787
+ // we need the $ecb mcrypt resource (only) in MODE_CFB with enableContinuousBuffer()
1788
+ // to workaround mcrypt's broken ncfb implementation in buffered mode
1789
+ // see: {@link http://phpseclib.sourceforge.net/cfb-demo.phps}
1790
+ if ($this->mode == CRYPT_MODE_CFB) {
1791
+ $this->ecb = mcrypt_module_open($this->cipher_name_mcrypt, '', MCRYPT_MODE_ECB, '');
1792
+ }
1793
+
1794
+ } // else should mcrypt_generic_deinit be called?
1795
+
1796
+ if ($this->mode == CRYPT_MODE_CFB) {
1797
+ mcrypt_generic_init($this->ecb, $this->key, str_repeat("\0", $this->block_size));
1798
+ }
1799
+ }
1800
+
1801
+ /**
1802
+ * Pads a string
1803
+ *
1804
+ * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize.
1805
+ * $this->block_size - (strlen($text) % $this->block_size) bytes are added, each of which is equal to
1806
+ * chr($this->block_size - (strlen($text) % $this->block_size)
1807
+ *
1808
+ * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless
1809
+ * and padding will, hence forth, be enabled.
1810
+ *
1811
+ * @see Crypt_Base::_unpad()
1812
+ * @param String $text
1813
+ * @access private
1814
+ * @return String
1815
+ */
1816
+ function _pad($text)
1817
+ {
1818
+ $length = strlen($text);
1819
+
1820
+ if (!$this->padding) {
1821
+ if ($length % $this->block_size == 0) {
1822
+ return $text;
1823
+ } else {
1824
+ user_error("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size})");
1825
+ $this->padding = true;
1826
+ }
1827
+ }
1828
+
1829
+ $pad = $this->block_size - ($length % $this->block_size);
1830
+
1831
+ return str_pad($text, $length + $pad, chr($pad));
1832
+ }
1833
+
1834
+ /**
1835
+ * Unpads a string.
1836
+ *
1837
+ * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong
1838
+ * and false will be returned.
1839
+ *
1840
+ * @see Crypt_Base::_pad()
1841
+ * @param String $text
1842
+ * @access private
1843
+ * @return String
1844
+ */
1845
+ function _unpad($text)
1846
+ {
1847
+ if (!$this->padding) {
1848
+ return $text;
1849
+ }
1850
+
1851
+ $length = ord($text[strlen($text) - 1]);
1852
+
1853
+ if (!$length || $length > $this->block_size) {
1854
+ return false;
1855
+ }
1856
+
1857
+ return substr($text, 0, -$length);
1858
+ }
1859
+
1860
+ /**
1861
+ * Clears internal buffers
1862
+ *
1863
+ * Clearing/resetting the internal buffers is done everytime
1864
+ * after disableContinuousBuffer() or on cipher $engine (re)init
1865
+ * ie after setKey() or setIV()
1866
+ *
1867
+ * @access public
1868
+ * @internal Could, but not must, extend by the child Crypt_* class
1869
+ */
1870
+ function _clearBuffers()
1871
+ {
1872
+ $this->enbuffer = $this->debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);
1873
+
1874
+ // mcrypt's handling of invalid's $iv:
1875
+ // $this->encryptIV = $this->decryptIV = strlen($this->iv) == $this->block_size ? $this->iv : str_repeat("\0", $this->block_size);
1876
+ $this->encryptIV = $this->decryptIV = str_pad(substr($this->iv, 0, $this->block_size), $this->block_size, "\0");
1877
+ }
1878
+
1879
+ /**
1880
+ * String Shift
1881
+ *
1882
+ * Inspired by array_shift
1883
+ *
1884
+ * @param String $string
1885
+ * @param optional Integer $index
1886
+ * @access private
1887
+ * @return String
1888
+ */
1889
+ function _string_shift(&$string, $index = 1)
1890
+ {
1891
+ $substr = substr($string, 0, $index);
1892
+ $string = substr($string, $index);
1893
+ return $substr;
1894
+ }
1895
+
1896
+ /**
1897
+ * String Pop
1898
+ *
1899
+ * Inspired by array_pop
1900
+ *
1901
+ * @param String $string
1902
+ * @param optional Integer $index
1903
+ * @access private
1904
+ * @return String
1905
+ */
1906
+ function _string_pop(&$string, $index = 1)
1907
+ {
1908
+ $substr = substr($string, -$index);
1909
+ $string = substr($string, 0, -$index);
1910
+ return $substr;
1911
+ }
1912
+
1913
+ /**
1914
+ * Increment the current string
1915
+ *
1916
+ * @see Crypt_Base::decrypt()
1917
+ * @see Crypt_Base::encrypt()
1918
+ * @param String $var
1919
+ * @access private
1920
+ */
1921
+ function _increment_str(&$var)
1922
+ {
1923
+ for ($i = 4; $i <= strlen($var); $i+= 4) {
1924
+ $temp = substr($var, -$i, 4);
1925
+ switch ($temp) {
1926
+ case "\xFF\xFF\xFF\xFF":
1927
+ $var = substr_replace($var, "\x00\x00\x00\x00", -$i, 4);
1928
+ break;
1929
+ case "\x7F\xFF\xFF\xFF":
1930
+ $var = substr_replace($var, "\x80\x00\x00\x00", -$i, 4);
1931
+ return;
1932
+ default:
1933
+ $temp = unpack('Nnum', $temp);
1934
+ $var = substr_replace($var, pack('N', $temp['num'] + 1), -$i, 4);
1935
+ return;
1936
+ }
1937
+ }
1938
+
1939
+ $remainder = strlen($var) % 4;
1940
+
1941
+ if ($remainder == 0) {
1942
+ return;
1943
+ }
1944
+
1945
+ $temp = unpack('Nnum', str_pad(substr($var, 0, $remainder), 4, "\0", STR_PAD_LEFT));
1946
+ $temp = substr(pack('N', $temp['num'] + 1), -$remainder);
1947
+ $var = substr_replace($var, $temp, 0, $remainder);
1948
+ }
1949
+
1950
+ /**
1951
+ * Setup the performance-optimized function for de/encrypt()
1952
+ *
1953
+ * Stores the created (or existing) callback function-name
1954
+ * in $this->inline_crypt
1955
+ *
1956
+ * Internally for phpseclib developers:
1957
+ *
1958
+ * _setupInlineCrypt() would be called only if:
1959
+ *
1960
+ * - $engine == CRYPT_ENGINE_INTERNAL and
1961
+ *
1962
+ * - $use_inline_crypt === true
1963
+ *
1964
+ * - each time on _setup(), after(!) _setupKey()
1965
+ *
1966
+ *
1967
+ * This ensures that _setupInlineCrypt() has always a
1968
+ * full ready2go initializated internal cipher $engine state
1969
+ * where, for example, the keys allready expanded,
1970
+ * keys/block_size calculated and such.
1971
+ *
1972
+ * It is, each time if called, the responsibility of _setupInlineCrypt():
1973
+ *
1974
+ * - to set $this->inline_crypt to a valid and fully working callback function
1975
+ * as a (faster) replacement for encrypt() / decrypt()
1976
+ *
1977
+ * - NOT to create unlimited callback functions (for memory reasons!)
1978
+ * no matter how often _setupInlineCrypt() would be called. At some
1979
+ * point of amount they must be generic re-useable.
1980
+ *
1981
+ * - the code of _setupInlineCrypt() it self,
1982
+ * and the generated callback code,
1983
+ * must be, in following order:
1984
+ * - 100% safe
1985
+ * - 100% compatible to encrypt()/decrypt()
1986
+ * - using only php5+ features/lang-constructs/php-extensions if
1987
+ * compatibility (down to php4) or fallback is provided
1988
+ * - readable/maintainable/understandable/commented and... not-cryptic-styled-code :-)
1989
+ * - >= 10% faster than encrypt()/decrypt() [which is, by the way,
1990
+ * the reason for the existence of _setupInlineCrypt() :-)]
1991
+ * - memory-nice
1992
+ * - short (as good as possible)
1993
+ *
1994
+ * Note: - _setupInlineCrypt() is using _createInlineCryptFunction() to create the full callback function code.
1995
+ * - In case of using inline crypting, _setupInlineCrypt() must extend by the child Crypt_* class.
1996
+ * - The following variable names are reserved:
1997
+ * - $_* (all variable names prefixed with an underscore)
1998
+ * - $self (object reference to it self. Do not use $this, but $self instead)
1999
+ * - $in (the content of $in has to en/decrypt by the generated code)
2000
+ * - The callback function should not use the 'return' statement, but en/decrypt'ing the content of $in only
2001
+ *
2002
+ *
2003
+ * @see Crypt_Base::_setup()
2004
+ * @see Crypt_Base::_createInlineCryptFunction()
2005
+ * @see Crypt_Base::encrypt()
2006
+ * @see Crypt_Base::decrypt()
2007
+ * @access private
2008
+ * @internal If a Crypt_* class providing inline crypting it must extend _setupInlineCrypt()
2009
+ */
2010
+ function _setupInlineCrypt()
2011
+ {
2012
+ // If, for any reason, an extending Crypt_Base() Crypt_* class
2013
+ // not using inline crypting then it must be ensured that: $this->use_inline_crypt = false
2014
+ // ie in the class var declaration of $use_inline_crypt in general for the Crypt_* class,
2015
+ // in the constructor at object instance-time
2016
+ // or, if it's runtime-specific, at runtime
2017
+
2018
+ $this->use_inline_crypt = false;
2019
+ }
2020
+
2021
+ /**
2022
+ * Creates the performance-optimized function for en/decrypt()
2023
+ *
2024
+ * Internally for phpseclib developers:
2025
+ *
2026
+ * _createInlineCryptFunction():
2027
+ *
2028
+ * - merge the $cipher_code [setup'ed by _setupInlineCrypt()]
2029
+ * with the current [$this->]mode of operation code
2030
+ *
2031
+ * - create the $inline function, which called by encrypt() / decrypt()
2032
+ * as its replacement to speed up the en/decryption operations.
2033
+ *
2034
+ * - return the name of the created $inline callback function
2035
+ *
2036
+ * - used to speed up en/decryption
2037
+ *
2038
+ *
2039
+ *
2040
+ * The main reason why can speed up things [up to 50%] this way are:
2041
+ *
2042
+ * - using variables more effective then regular.
2043
+ * (ie no use of expensive arrays but integers $k_0, $k_1 ...
2044
+ * or even, for example, the pure $key[] values hardcoded)
2045
+ *
2046
+ * - avoiding 1000's of function calls of ie _encryptBlock()
2047
+ * but inlining the crypt operations.
2048
+ * in the mode of operation for() loop.
2049
+ *
2050
+ * - full loop unroll the (sometimes key-dependent) rounds
2051
+ * avoiding this way ++$i counters and runtime-if's etc...
2052
+ *
2053
+ * The basic code architectur of the generated $inline en/decrypt()
2054
+ * lambda function, in pseudo php, is:
2055
+ *
2056
+ * <code>
2057
+ * +----------------------------------------------------------------------------------------------+
2058
+ * | callback $inline = create_function: |
2059
+ * | lambda_function_0001_crypt_ECB($action, $text) |
2060
+ * | { |
2061
+ * | INSERT PHP CODE OF: |
2062
+ * | $cipher_code['init_crypt']; // general init code. |
2063
+ * | // ie: $sbox'es declarations used for |
2064
+ * | // encrypt and decrypt'ing. |
2065
+ * | |
2066
+ * | switch ($action) { |
2067
+ * | case 'encrypt': |
2068
+ * | INSERT PHP CODE OF: |
2069
+ * | $cipher_code['init_encrypt']; // encrypt sepcific init code. |
2070
+ * | ie: specified $key or $box |
2071
+ * | declarations for encrypt'ing. |
2072
+ * | |
2073
+ * | foreach ($ciphertext) { |
2074
+ * | $in = $block_size of $ciphertext; |
2075
+ * | |
2076
+ * | INSERT PHP CODE OF: |
2077
+ * | $cipher_code['encrypt_block']; // encrypt's (string) $in, which is always: |
2078
+ * | // strlen($in) == $this->block_size |
2079
+ * | // here comes the cipher algorithm in action |
2080
+ * | // for encryption. |
2081
+ * | // $cipher_code['encrypt_block'] has to |
2082
+ * | // encrypt the content of the $in variable |
2083
+ * | |
2084
+ * | $plaintext .= $in; |
2085
+ * | } |
2086
+ * | return $plaintext; |
2087
+ * | |
2088
+ * | case 'decrypt': |
2089
+ * | INSERT PHP CODE OF: |
2090
+ * | $cipher_code['init_decrypt']; // decrypt sepcific init code |
2091
+ * | ie: specified $key or $box |
2092
+ * | declarations for decrypt'ing. |
2093
+ * | foreach ($plaintext) { |
2094
+ * | $in = $block_size of $plaintext; |
2095
+ * | |
2096
+ * | INSERT PHP CODE OF: |
2097
+ * | $cipher_code['decrypt_block']; // decrypt's (string) $in, which is always |
2098
+ * | // strlen($in) == $this->block_size |
2099
+ * | // here comes the cipher algorithm in action |
2100
+ * | // for decryption. |
2101
+ * | // $cipher_code['decrypt_block'] has to |
2102
+ * | // decrypt the content of the $in variable |
2103
+ * | $ciphertext .= $in; |
2104
+ * | } |
2105
+ * | return $ciphertext; |
2106
+ * | } |
2107
+ * | } |
2108
+ * +----------------------------------------------------------------------------------------------+
2109
+ * </code>
2110
+ *
2111
+ * See also the Crypt_*::_setupInlineCrypt()'s for
2112
+ * productive inline $cipher_code's how they works.
2113
+ *
2114
+ * Structure of:
2115
+ * <code>
2116
+ * $cipher_code = array(
2117
+ * 'init_crypt' => (string) '', // optional
2118
+ * 'init_encrypt' => (string) '', // optional
2119
+ * 'init_decrypt' => (string) '', // optional
2120
+ * 'encrypt_block' => (string) '', // required
2121
+ * 'decrypt_block' => (string) '' // required
2122
+ * );
2123
+ * </code>
2124
+ *
2125
+ * @see Crypt_Base::_setupInlineCrypt()
2126
+ * @see Crypt_Base::encrypt()
2127
+ * @see Crypt_Base::decrypt()
2128
+ * @param Array $cipher_code
2129
+ * @access private
2130
+ * @return String (the name of the created callback function)
2131
+ */
2132
+ function _createInlineCryptFunction($cipher_code)
2133
+ {
2134
+ $block_size = $this->block_size;
2135
+
2136
+ // optional
2137
+ $init_crypt = isset($cipher_code['init_crypt']) ? $cipher_code['init_crypt'] : '';
2138
+ $init_encrypt = isset($cipher_code['init_encrypt']) ? $cipher_code['init_encrypt'] : '';
2139
+ $init_decrypt = isset($cipher_code['init_decrypt']) ? $cipher_code['init_decrypt'] : '';
2140
+ // required
2141
+ $encrypt_block = $cipher_code['encrypt_block'];
2142
+ $decrypt_block = $cipher_code['decrypt_block'];
2143
+
2144
+ // Generating mode of operation inline code,
2145
+ // merged with the $cipher_code algorithm
2146
+ // for encrypt- and decryption.
2147
+ switch ($this->mode) {
2148
+ case CRYPT_MODE_ECB:
2149
+ $encrypt = $init_encrypt . '
2150
+ $_ciphertext = "";
2151
+ $_plaintext_len = strlen($_text);
2152
+
2153
+ for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
2154
+ $in = substr($_text, $_i, '.$block_size.');
2155
+ '.$encrypt_block.'
2156
+ $_ciphertext.= $in;
2157
+ }
2158
+
2159
+ return $_ciphertext;
2160
+ ';
2161
+
2162
+ $decrypt = $init_decrypt . '
2163
+ $_plaintext = "";
2164
+ $_text = str_pad($_text, strlen($_text) + ('.$block_size.' - strlen($_text) % '.$block_size.') % '.$block_size.', chr(0));
2165
+ $_ciphertext_len = strlen($_text);
2166
+
2167
+ for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
2168
+ $in = substr($_text, $_i, '.$block_size.');
2169
+ '.$decrypt_block.'
2170
+ $_plaintext.= $in;
2171
+ }
2172
+
2173
+ return $self->_unpad($_plaintext);
2174
+ ';
2175
+ break;
2176
+ case CRYPT_MODE_CTR:
2177
+ $encrypt = $init_encrypt . '
2178
+ $_ciphertext = "";
2179
+ $_plaintext_len = strlen($_text);
2180
+ $_xor = $self->encryptIV;
2181
+ $_buffer = &$self->enbuffer;
2182
+ if (strlen($_buffer["ciphertext"])) {
2183
+ for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
2184
+ $_block = substr($_text, $_i, '.$block_size.');
2185
+ if (strlen($_block) > strlen($_buffer["ciphertext"])) {
2186
+ $in = $_xor;
2187
+ '.$encrypt_block.'
2188
+ $self->_increment_str($_xor);
2189
+ $_buffer["ciphertext"].= $in;
2190
+ }
2191
+ $_key = $self->_string_shift($_buffer["ciphertext"], '.$block_size.');
2192
+ $_ciphertext.= $_block ^ $_key;
2193
+ }
2194
+ } else {
2195
+ for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
2196
+ $_block = substr($_text, $_i, '.$block_size.');
2197
+ $in = $_xor;
2198
+ '.$encrypt_block.'
2199
+ $self->_increment_str($_xor);
2200
+ $_key = $in;
2201
+ $_ciphertext.= $_block ^ $_key;
2202
+ }
2203
+ }
2204
+ if ($self->continuousBuffer) {
2205
+ $self->encryptIV = $_xor;
2206
+ if ($_start = $_plaintext_len % '.$block_size.') {
2207
+ $_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"];
2208
+ }
2209
+ }
2210
+
2211
+ return $_ciphertext;
2212
+ ';
2213
+
2214
+ $decrypt = $init_encrypt . '
2215
+ $_plaintext = "";
2216
+ $_ciphertext_len = strlen($_text);
2217
+ $_xor = $self->decryptIV;
2218
+ $_buffer = &$self->debuffer;
2219
+
2220
+ if (strlen($_buffer["ciphertext"])) {
2221
+ for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
2222
+ $_block = substr($_text, $_i, '.$block_size.');
2223
+ if (strlen($_block) > strlen($_buffer["ciphertext"])) {
2224
+ $in = $_xor;
2225
+ '.$encrypt_block.'
2226
+ $self->_increment_str($_xor);
2227
+ $_buffer["ciphertext"].= $in;
2228
+ }
2229
+ $_key = $self->_string_shift($_buffer["ciphertext"], '.$block_size.');
2230
+ $_plaintext.= $_block ^ $_key;
2231
+ }
2232
+ } else {
2233
+ for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
2234
+ $_block = substr($_text, $_i, '.$block_size.');
2235
+ $in = $_xor;
2236
+ '.$encrypt_block.'
2237
+ $self->_increment_str($_xor);
2238
+ $_key = $in;
2239
+ $_plaintext.= $_block ^ $_key;
2240
+ }
2241
+ }
2242
+ if ($self->continuousBuffer) {
2243
+ $self->decryptIV = $_xor;
2244
+ if ($_start = $_ciphertext_len % '.$block_size.') {
2245
+ $_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"];
2246
+ }
2247
+ }
2248
+
2249
+ return $_plaintext;
2250
+ ';
2251
+ break;
2252
+ case CRYPT_MODE_CFB:
2253
+ $encrypt = $init_encrypt . '
2254
+ $_ciphertext = "";
2255
+ $_buffer = &$self->enbuffer;
2256
+
2257
+ if ($self->continuousBuffer) {
2258
+ $_iv = &$self->encryptIV;
2259
+ $_pos = &$_buffer["pos"];
2260
+ } else {
2261
+ $_iv = $self->encryptIV;
2262
+ $_pos = 0;
2263
+ }
2264
+ $_len = strlen($_text);
2265
+ $_i = 0;
2266
+ if ($_pos) {
2267
+ $_orig_pos = $_pos;
2268
+ $_max = '.$block_size.' - $_pos;
2269
+ if ($_len >= $_max) {
2270
+ $_i = $_max;
2271
+ $_len-= $_max;
2272
+ $_pos = 0;
2273
+ } else {
2274
+ $_i = $_len;
2275
+ $_pos+= $_len;
2276
+ $_len = 0;
2277
+ }
2278
+ $_ciphertext = substr($_iv, $_orig_pos) ^ $_text;
2279
+ $_iv = substr_replace($_iv, $_ciphertext, $_orig_pos, $_i);
2280
+ }
2281
+ while ($_len >= '.$block_size.') {
2282
+ $in = $_iv;
2283
+ '.$encrypt_block.';
2284
+ $_iv = $in ^ substr($_text, $_i, '.$block_size.');
2285
+ $_ciphertext.= $_iv;
2286
+ $_len-= '.$block_size.';
2287
+ $_i+= '.$block_size.';
2288
+ }
2289
+ if ($_len) {
2290
+ $in = $_iv;
2291
+ '.$encrypt_block.'
2292
+ $_iv = $in;
2293
+ $_block = $_iv ^ substr($_text, $_i);
2294
+ $_iv = substr_replace($_iv, $_block, 0, $_len);
2295
+ $_ciphertext.= $_block;
2296
+ $_pos = $_len;
2297
+ }
2298
+ return $_ciphertext;
2299
+ ';
2300
+
2301
+ $decrypt = $init_encrypt . '
2302
+ $_plaintext = "";
2303
+ $_buffer = &$self->debuffer;
2304
+
2305
+ if ($self->continuousBuffer) {
2306
+ $_iv = &$self->decryptIV;
2307
+ $_pos = &$_buffer["pos"];
2308
+ } else {
2309
+ $_iv = $self->decryptIV;
2310
+ $_pos = 0;
2311
+ }
2312
+ $_len = strlen($_text);
2313
+ $_i = 0;
2314
+ if ($_pos) {
2315
+ $_orig_pos = $_pos;
2316
+ $_max = '.$block_size.' - $_pos;
2317
+ if ($_len >= $_max) {
2318
+ $_i = $_max;
2319
+ $_len-= $_max;
2320
+ $_pos = 0;
2321
+ } else {
2322
+ $_i = $_len;
2323
+ $_pos+= $_len;
2324
+ $_len = 0;
2325
+ }
2326
+ $_plaintext = substr($_iv, $_orig_pos) ^ $_text;
2327
+ $_iv = substr_replace($_iv, substr($_text, 0, $_i), $_orig_pos, $_i);
2328
+ }
2329
+ while ($_len >= '.$block_size.') {
2330
+ $in = $_iv;
2331
+ '.$encrypt_block.'
2332
+ $_iv = $in;
2333
+ $cb = substr($_text, $_i, '.$block_size.');
2334
+ $_plaintext.= $_iv ^ $cb;
2335
+ $_iv = $cb;
2336
+ $_len-= '.$block_size.';
2337
+ $_i+= '.$block_size.';
2338
+ }
2339
+ if ($_len) {
2340
+ $in = $_iv;
2341
+ '.$encrypt_block.'
2342
+ $_iv = $in;
2343
+ $_plaintext.= $_iv ^ substr($_text, $_i);
2344
+ $_iv = substr_replace($_iv, substr($_text, $_i), 0, $_len);
2345
+ $_pos = $_len;
2346
+ }
2347
+
2348
+ return $_plaintext;
2349
+ ';
2350
+ break;
2351
+ case CRYPT_MODE_OFB:
2352
+ $encrypt = $init_encrypt . '
2353
+ $_ciphertext = "";
2354
+ $_plaintext_len = strlen($_text);
2355
+ $_xor = $self->encryptIV;
2356
+ $_buffer = &$self->enbuffer;
2357
+
2358
+ if (strlen($_buffer["xor"])) {
2359
+ for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
2360
+ $_block = substr($_text, $_i, '.$block_size.');
2361
+ if (strlen($_block) > strlen($_buffer["xor"])) {
2362
+ $in = $_xor;
2363
+ '.$encrypt_block.'
2364
+ $_xor = $in;
2365
+ $_buffer["xor"].= $_xor;
2366
+ }
2367
+ $_key = $self->_string_shift($_buffer["xor"], '.$block_size.');
2368
+ $_ciphertext.= $_block ^ $_key;
2369
+ }
2370
+ } else {
2371
+ for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
2372
+ $in = $_xor;
2373
+ '.$encrypt_block.'
2374
+ $_xor = $in;
2375
+ $_ciphertext.= substr($_text, $_i, '.$block_size.') ^ $_xor;
2376
+ }
2377
+ $_key = $_xor;
2378
+ }
2379
+ if ($self->continuousBuffer) {
2380
+ $self->encryptIV = $_xor;
2381
+ if ($_start = $_plaintext_len % '.$block_size.') {
2382
+ $_buffer["xor"] = substr($_key, $_start) . $_buffer["xor"];
2383
+ }
2384
+ }
2385
+ return $_ciphertext;
2386
+ ';
2387
+
2388
+ $decrypt = $init_encrypt . '
2389
+ $_plaintext = "";
2390
+ $_ciphertext_len = strlen($_text);
2391
+ $_xor = $self->decryptIV;
2392
+ $_buffer = &$self->debuffer;
2393
+
2394
+ if (strlen($_buffer["xor"])) {
2395
+ for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
2396
+ $_block = substr($_text, $_i, '.$block_size.');
2397
+ if (strlen($_block) > strlen($_buffer["xor"])) {
2398
+ $in = $_xor;
2399
+ '.$encrypt_block.'
2400
+ $_xor = $in;
2401
+ $_buffer["xor"].= $_xor;
2402
+ }
2403
+ $_key = $self->_string_shift($_buffer["xor"], '.$block_size.');
2404
+ $_plaintext.= $_block ^ $_key;
2405
+ }
2406
+ } else {
2407
+ for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
2408
+ $in = $_xor;
2409
+ '.$encrypt_block.'
2410
+ $_xor = $in;
2411
+ $_plaintext.= substr($_text, $_i, '.$block_size.') ^ $_xor;
2412
+ }
2413
+ $_key = $_xor;
2414
+ }
2415
+ if ($self->continuousBuffer) {
2416
+ $self->decryptIV = $_xor;
2417
+ if ($_start = $_ciphertext_len % '.$block_size.') {
2418
+ $_buffer["xor"] = substr($_key, $_start) . $_buffer["xor"];
2419
+ }
2420
+ }
2421
+ return $_plaintext;
2422
+ ';
2423
+ break;
2424
+ case CRYPT_MODE_STREAM:
2425
+ $encrypt = $init_encrypt . '
2426
+ $_ciphertext = "";
2427
+ '.$encrypt_block.'
2428
+ return $_ciphertext;
2429
+ ';
2430
+ $decrypt = $init_decrypt . '
2431
+ $_plaintext = "";
2432
+ '.$decrypt_block.'
2433
+ return $_plaintext;
2434
+ ';
2435
+ break;
2436
+ // case CRYPT_MODE_CBC:
2437
+ default:
2438
+ $encrypt = $init_encrypt . '
2439
+ $_ciphertext = "";
2440
+ $_plaintext_len = strlen($_text);
2441
+
2442
+ $in = $self->encryptIV;
2443
+
2444
+ for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
2445
+ $in = substr($_text, $_i, '.$block_size.') ^ $in;
2446
+ '.$encrypt_block.'
2447
+ $_ciphertext.= $in;
2448
+ }
2449
+
2450
+ if ($self->continuousBuffer) {
2451
+ $self->encryptIV = $in;
2452
+ }
2453
+
2454
+ return $_ciphertext;
2455
+ ';
2456
+
2457
+ $decrypt = $init_decrypt . '
2458
+ $_plaintext = "";
2459
+ $_text = str_pad($_text, strlen($_text) + ('.$block_size.' - strlen($_text) % '.$block_size.') % '.$block_size.', chr(0));
2460
+ $_ciphertext_len = strlen($_text);
2461
+
2462
+ $_iv = $self->decryptIV;
2463
+
2464
+ for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
2465
+ $in = $_block = substr($_text, $_i, '.$block_size.');
2466
+ '.$decrypt_block.'
2467
+ $_plaintext.= $in ^ $_iv;
2468
+ $_iv = $_block;
2469
+ }
2470
+
2471
+ if ($self->continuousBuffer) {
2472
+ $self->decryptIV = $_iv;
2473
+ }
2474
+
2475
+ return $self->_unpad($_plaintext);
2476
+ ';
2477
+ break;
2478
+ }
2479
+
2480
+ // Create the $inline function and return its name as string. Ready to run!
2481
+ return create_function('$_action, &$self, $_text', $init_crypt . 'if ($_action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' }');
2482
+ }
2483
+
2484
+ /**
2485
+ * Holds the lambda_functions table (classwide)
2486
+ *
2487
+ * Each name of the lambda function, created from
2488
+ * _setupInlineCrypt() && _createInlineCryptFunction()
2489
+ * is stored, classwide (!), here for reusing.
2490
+ *
2491
+ * The string-based index of $function is a classwide
2492
+ * uniqe value representing, at least, the $mode of
2493
+ * operation (or more... depends of the optimizing level)
2494
+ * for which $mode the lambda function was created.
2495
+ *
2496
+ * @access private
2497
+ * @return Array &$functions
2498
+ */
2499
+ function &_getLambdaFunctions()
2500
+ {
2501
+ static $functions = array();
2502
+ return $functions;
2503
+ }
2504
+
2505
+ /**
2506
+ * Generates a digest from $bytes
2507
+ *
2508
+ * @see _setupInlineCrypt()
2509
+ * @access private
2510
+ * @param $bytes
2511
+ * @return String
2512
+ */
2513
+ function _hashInlineCryptFunction($bytes)
2514
+ {
2515
+ if (!defined('CRYPT_BASE_WHIRLPOOL_AVAILABLE')) {
2516
+ define('CRYPT_BASE_WHIRLPOOL_AVAILABLE', (bool)(extension_loaded('hash') && in_array('whirlpool', hash_algos())));
2517
+ }
2518
+
2519
+ $result = '';
2520
+ $hash = $bytes;
2521
+
2522
+ switch (true) {
2523
+ case CRYPT_BASE_WHIRLPOOL_AVAILABLE:
2524
+ foreach (str_split($bytes, 64) as $t) {
2525
+ $hash = hash('whirlpool', $hash, true);
2526
+ $result .= $t ^ $hash;
2527
+ }
2528
+ return $result . hash('whirlpool', $hash, true);
2529
+ default:
2530
+ $len = strlen($bytes);
2531
+ for ($i = 0; $i < $len; $i+=20) {
2532
+ $t = substr($bytes, $i, 20);
2533
+ $hash = pack('H*', sha1($hash));
2534
+ $result .= $t ^ $hash;
2535
+ }
2536
+ return $result . pack('H*', sha1($hash));
2537
+ }
2538
+ }
2539
+ }
phpseclib/Crypt/Blowfish.php CHANGED
@@ -1,644 +1,651 @@
1
- <?php
2
-
3
- /**
4
- * Pure-PHP implementation of Blowfish.
5
- *
6
- * Uses mcrypt, if available, and an internal implementation, otherwise.
7
- *
8
- * PHP versions 4 and 5
9
- *
10
- * Useful resources are as follows:
11
- *
12
- * - {@link http://en.wikipedia.org/wiki/Blowfish_(cipher) Wikipedia description of Blowfish}
13
- *
14
- * Here's a short example of how to use this library:
15
- * <code>
16
- * <?php
17
- * include 'Crypt/Blowfish.php';
18
- *
19
- * $blowfish = new Crypt_Blowfish();
20
- *
21
- * $blowfish->setKey('12345678901234567890123456789012');
22
- *
23
- * $plaintext = str_repeat('a', 1024);
24
- *
25
- * echo $blowfish->decrypt($blowfish->encrypt($plaintext));
26
- * ?>
27
- * </code>
28
- *
29
- * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
30
- * of this software and associated documentation files (the "Software"), to deal
31
- * in the Software without restriction, including without limitation the rights
32
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
33
- * copies of the Software, and to permit persons to whom the Software is
34
- * furnished to do so, subject to the following conditions:
35
- *
36
- * The above copyright notice and this permission notice shall be included in
37
- * all copies or substantial portions of the Software.
38
- *
39
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
40
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
41
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
42
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
43
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
44
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
45
- * THE SOFTWARE.
46
- *
47
- * @category Crypt
48
- * @package Crypt_Blowfish
49
- * @author Jim Wigginton <terrafrost@php.net>
50
- * @author Hans-Juergen Petrich <petrich@tronic-media.com>
51
- * @copyright MMVII Jim Wigginton
52
- * @license http://www.opensource.org/licenses/mit-license.html MIT License
53
- * @link http://phpseclib.sourceforge.net
54
- */
55
-
56
- /**
57
- * Include Crypt_Base
58
- *
59
- * Base cipher class
60
- */
61
- if (!class_exists('Crypt_Base')) {
62
- include_once 'Base.php';
63
- }
64
-
65
- /**#@+
66
- * @access public
67
- * @see Crypt_Blowfish::encrypt()
68
- * @see Crypt_Blowfish::decrypt()
69
- */
70
- /**
71
- * Encrypt / decrypt using the Counter mode.
72
- *
73
- * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
74
- *
75
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
76
- */
77
- define('CRYPT_BLOWFISH_MODE_CTR', CRYPT_MODE_CTR);
78
- /**
79
- * Encrypt / decrypt using the Electronic Code Book mode.
80
- *
81
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
82
- */
83
- define('CRYPT_BLOWFISH_MODE_ECB', CRYPT_MODE_ECB);
84
- /**
85
- * Encrypt / decrypt using the Code Book Chaining mode.
86
- *
87
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
88
- */
89
- define('CRYPT_BLOWFISH_MODE_CBC', CRYPT_MODE_CBC);
90
- /**
91
- * Encrypt / decrypt using the Cipher Feedback mode.
92
- *
93
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
94
- */
95
- define('CRYPT_BLOWFISH_MODE_CFB', CRYPT_MODE_CFB);
96
- /**
97
- * Encrypt / decrypt using the Cipher Feedback mode.
98
- *
99
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
100
- */
101
- define('CRYPT_BLOWFISH_MODE_OFB', CRYPT_MODE_OFB);
102
- /**#@-*/
103
-
104
- /**#@+
105
- * @access private
106
- * @see Crypt_Base::Crypt_Base()
107
- */
108
- /**
109
- * Toggles the internal implementation
110
- */
111
- define('CRYPT_BLOWFISH_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
112
- /**
113
- * Toggles the mcrypt implementation
114
- */
115
- define('CRYPT_BLOWFISH_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
116
- /**#@-*/
117
-
118
- /**
119
- * Pure-PHP implementation of Blowfish.
120
- *
121
- * @package Crypt_Blowfish
122
- * @author Jim Wigginton <terrafrost@php.net>
123
- * @author Hans-Juergen Petrich <petrich@tronic-media.com>
124
- * @access public
125
- */
126
- class Crypt_Blowfish extends Crypt_Base
127
- {
128
- /**
129
- * Block Length of the cipher
130
- *
131
- * @see Crypt_Base::block_size
132
- * @var Integer
133
- * @access private
134
- */
135
- var $block_size = 8;
136
-
137
- /**
138
- * The default password key_size used by setPassword()
139
- *
140
- * @see Crypt_Base::password_key_size
141
- * @see Crypt_Base::setPassword()
142
- * @var Integer
143
- * @access private
144
- */
145
- var $password_key_size = 56;
146
-
147
- /**
148
- * The namespace used by the cipher for its constants.
149
- *
150
- * @see Crypt_Base::const_namespace
151
- * @var String
152
- * @access private
153
- */
154
- var $const_namespace = 'BLOWFISH';
155
-
156
- /**
157
- * The mcrypt specific name of the cipher
158
- *
159
- * @see Crypt_Base::cipher_name_mcrypt
160
- * @var String
161
- * @access private
162
- */
163
- var $cipher_name_mcrypt = 'blowfish';
164
-
165
- /**
166
- * Optimizing value while CFB-encrypting
167
- *
168
- * @see Crypt_Base::cfb_init_len
169
- * @var Integer
170
- * @access private
171
- */
172
- var $cfb_init_len = 500;
173
-
174
- /**
175
- * The fixed subkeys boxes ($sbox0 - $sbox3) with 256 entries each
176
- *
177
- * S-Box 1
178
- *
179
- * @access private
180
- * @var array
181
- */
182
- var $sbox0 = array (
183
- 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
184
- 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
185
- 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
186
- 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
187
- 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
188
- 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
189
- 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
190
- 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
191
- 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
192
- 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
193
- 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
194
- 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
195
- 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
196
- 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
197
- 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
198
- 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
199
- 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
200
- 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
201
- 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
202
- 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
203
- 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
204
- 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
205
- 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
206
- 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
207
- 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
208
- 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
209
- 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
210
- 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
211
- 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
212
- 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
213
- 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
214
- 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
215
- );
216
-
217
- /**
218
- * S-Box 1
219
- *
220
- * @access private
221
- * @var array
222
- */
223
- var $sbox1 = array(
224
- 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
225
- 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
226
- 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
227
- 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
228
- 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
229
- 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
230
- 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
231
- 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
232
- 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
233
- 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
234
- 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
235
- 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
236
- 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
237
- 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
238
- 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
239
- 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
240
- 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
241
- 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
242
- 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
243
- 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
244
- 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
245
- 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
246
- 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
247
- 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
248
- 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
249
- 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
250
- 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
251
- 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
252
- 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
253
- 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
254
- 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
255
- 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
256
- );
257
-
258
- /**
259
- * S-Box 2
260
- *
261
- * @access private
262
- * @var array
263
- */
264
- var $sbox2 = array(
265
- 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
266
- 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
267
- 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
268
- 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
269
- 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
270
- 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
271
- 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
272
- 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
273
- 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
274
- 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
275
- 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
276
- 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
277
- 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
278
- 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
279
- 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
280
- 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
281
- 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
282
- 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
283
- 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
284
- 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
285
- 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
286
- 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
287
- 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
288
- 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
289
- 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
290
- 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
291
- 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
292
- 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
293
- 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
294
- 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
295
- 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
296
- 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
297
- );
298
-
299
- /**
300
- * S-Box 3
301
- *
302
- * @access private
303
- * @var array
304
- */
305
- var $sbox3 = array(
306
- 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
307
- 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
308
- 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
309
- 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
310
- 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
311
- 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
312
- 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
313
- 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
314
- 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
315
- 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
316
- 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
317
- 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
318
- 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
319
- 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
320
- 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
321
- 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
322
- 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
323
- 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
324
- 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
325
- 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
326
- 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
327
- 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
328
- 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
329
- 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
330
- 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
331
- 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
332
- 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
333
- 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
334
- 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
335
- 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
336
- 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
337
- 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
338
- );
339
-
340
- /**
341
- * P-Array consists of 18 32-bit subkeys
342
- *
343
- * @var array $parray
344
- * @access private
345
- */
346
- var $parray = array(
347
- 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0,
348
- 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
349
- 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b
350
- );
351
-
352
- /**
353
- * The BCTX-working Array
354
- *
355
- * Holds the expanded key [p] and the key-depended s-boxes [sb]
356
- *
357
- * @var array $bctx
358
- * @access private
359
- */
360
- var $bctx;
361
-
362
- /**
363
- * Holds the last used key
364
- *
365
- * @var Array
366
- * @access private
367
- */
368
- var $kl;
369
-
370
- /**
371
- * Sets the key.
372
- *
373
- * Keys can be of any length. Blowfish, itself, requires the use of a key between 32 and max. 448-bits long.
374
- * If the key is less than 32-bits we NOT fill the key to 32bit but let the key as it is to be compatible
375
- * with mcrypt because mcrypt act this way with blowfish key's < 32 bits.
376
- *
377
- * If the key is more than 448-bits, we trim the excess bits.
378
- *
379
- * If the key is not explicitly set, or empty, it'll be assumed a 128 bits key to be all null bytes.
380
- *
381
- * @access public
382
- * @see Crypt_Base::setKey()
383
- * @param String $key
384
- */
385
- function setKey($key)
386
- {
387
- $keylength = strlen($key);
388
-
389
- if (!$keylength) {
390
- $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
391
- } elseif ($keylength > 56) {
392
- $key = substr($key, 0, 56);
393
- }
394
-
395
- parent::setKey($key);
396
- }
397
-
398
- /**
399
- * Setup the key (expansion)
400
- *
401
- * @see Crypt_Base::_setupKey()
402
- * @access private
403
- */
404
- function _setupKey()
405
- {
406
- if (isset($this->kl['key']) && $this->key === $this->kl['key']) {
407
- // already expanded
408
- return;
409
- }
410
- $this->kl = array('key' => $this->key);
411
-
412
- /* key-expanding p[] and S-Box building sb[] */
413
- $this->bctx = array(
414
- 'p' => array(),
415
- 'sb' => array(
416
- $this->sbox0,
417
- $this->sbox1,
418
- $this->sbox2,
419
- $this->sbox3
420
- )
421
- );
422
-
423
- // unpack binary string in unsigned chars
424
- $key = array_values(unpack('C*', $this->key));
425
- $keyl = count($key);
426
- for ($j = 0, $i = 0; $i < 18; ++$i) {
427
- // xor P1 with the first 32-bits of the key, xor P2 with the second 32-bits ...
428
- for ($data = 0, $k = 0; $k < 4; ++$k) {
429
- $data = ($data << 8) | $key[$j];
430
- if (++$j >= $keyl) {
431
- $j = 0;
432
- }
433
- }
434
- $this->bctx['p'][] = $this->parray[$i] ^ $data;
435
- }
436
-
437
- // encrypt the zero-string, replace P1 and P2 with the encrypted data,
438
- // encrypt P3 and P4 with the new P1 and P2, do it with all P-array and subkeys
439
- $data = "\0\0\0\0\0\0\0\0";
440
- for ($i = 0; $i < 18; $i += 2) {
441
- list($l, $r) = array_values(unpack('N*', $data = $this->_encryptBlock($data)));
442
- $this->bctx['p'][$i ] = $l;
443
- $this->bctx['p'][$i + 1] = $r;
444
- }
445
- for ($i = 0; $i < 4; ++$i) {
446
- for ($j = 0; $j < 256; $j += 2) {
447
- list($l, $r) = array_values(unpack('N*', $data = $this->_encryptBlock($data)));
448
- $this->bctx['sb'][$i][$j ] = $l;
449
- $this->bctx['sb'][$i][$j + 1] = $r;
450
- }
451
- }
452
- }
453
-
454
- /**
455
- * Encrypts a block
456
- *
457
- * @access private
458
- * @param String $in
459
- * @return String
460
- */
461
- function _encryptBlock($in)
462
- {
463
- $p = $this->bctx["p"];
464
- // extract($this->bctx["sb"], EXTR_PREFIX_ALL, "sb"); // slower
465
- $sb_0 = $this->bctx["sb"][0];
466
- $sb_1 = $this->bctx["sb"][1];
467
- $sb_2 = $this->bctx["sb"][2];
468
- $sb_3 = $this->bctx["sb"][3];
469
-
470
- $in = unpack("N*", $in);
471
- $l = $in[1];
472
- $r = $in[2];
473
-
474
- for ($i = 0; $i < 16; $i+= 2) {
475
- $l^= $p[$i];
476
- $r^= ($sb_0[$l >> 24 & 0xff] +
477
- $sb_1[$l >> 16 & 0xff] ^
478
- $sb_2[$l >> 8 & 0xff]) +
479
- $sb_3[$l & 0xff];
480
-
481
- $r^= $p[$i + 1];
482
- $l^= ($sb_0[$r >> 24 & 0xff] +
483
- $sb_1[$r >> 16 & 0xff] ^
484
- $sb_2[$r >> 8 & 0xff]) +
485
- $sb_3[$r & 0xff];
486
- }
487
- return pack("N*", $r ^ $p[17], $l ^ $p[16]);
488
- }
489
-
490
- /**
491
- * Decrypts a block
492
- *
493
- * @access private
494
- * @param String $in
495
- * @return String
496
- */
497
- function _decryptBlock($in)
498
- {
499
- $p = $this->bctx["p"];
500
- $sb_0 = $this->bctx["sb"][0];
501
- $sb_1 = $this->bctx["sb"][1];
502
- $sb_2 = $this->bctx["sb"][2];
503
- $sb_3 = $this->bctx["sb"][3];
504
-
505
- $in = unpack("N*", $in);
506
- $l = $in[1];
507
- $r = $in[2];
508
-
509
- for ($i = 17; $i > 2; $i-= 2) {
510
- $l^= $p[$i];
511
- $r^= ($sb_0[$l >> 24 & 0xff] +
512
- $sb_1[$l >> 16 & 0xff] ^
513
- $sb_2[$l >> 8 & 0xff]) +
514
- $sb_3[$l & 0xff];
515
-
516
- $r^= $p[$i - 1];
517
- $l^= ($sb_0[$r >> 24 & 0xff] +
518
- $sb_1[$r >> 16 & 0xff] ^
519
- $sb_2[$r >> 8 & 0xff]) +
520
- $sb_3[$r & 0xff];
521
- }
522
-
523
- return pack("N*", $r ^ $p[0], $l ^ $p[1]);
524
- }
525
-
526
- /**
527
- * Setup the performance-optimized function for de/encrypt()
528
- *
529
- * @see Crypt_Base::_setupInlineCrypt()
530
- * @access private
531
- */
532
- function _setupInlineCrypt()
533
- {
534
- $lambda_functions =& Crypt_Blowfish::_getLambdaFunctions();
535
-
536
- // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
537
- // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one.
538
- $gen_hi_opt_code = (bool)( count($lambda_functions) < 10);
539
-
540
- switch (true) {
541
- case $gen_hi_opt_code:
542
- $code_hash = md5(str_pad("Crypt_Blowfish, {$this->mode}, ", 32, "\0") . $this->key);
543
- break;
544
- default:
545
- $code_hash = "Crypt_Blowfish, {$this->mode}";
546
- }
547
-
548
- if (!isset($lambda_functions[$code_hash])) {
549
- switch (true) {
550
- case $gen_hi_opt_code:
551
- $p = $this->bctx['p'];
552
- $init_crypt = '
553
- static $sb_0, $sb_1, $sb_2, $sb_3;
554
- if (!$sb_0) {
555
- $sb_0 = $self->bctx["sb"][0];
556
- $sb_1 = $self->bctx["sb"][1];
557
- $sb_2 = $self->bctx["sb"][2];
558
- $sb_3 = $self->bctx["sb"][3];
559
- }
560
- ';
561
- break;
562
- default:
563
- $p = array();
564
- for ($i = 0; $i < 18; ++$i) {
565
- $p[] = '$p_' . $i;
566
- }
567
- $init_crypt = '
568
- list($sb_0, $sb_1, $sb_2, $sb_3) = $self->bctx["sb"];
569
- list(' . implode(',', $p) . ') = $self->bctx["p"];
570
-
571
- ';
572
- }
573
-
574
- // Generating encrypt code:
575
- $encrypt_block = '
576
- $in = unpack("N*", $in);
577
- $l = $in[1];
578
- $r = $in[2];
579
- ';
580
- for ($i = 0; $i < 16; $i+= 2) {
581
- $encrypt_block.= '
582
- $l^= ' . $p[$i] . ';
583
- $r^= ($sb_0[$l >> 24 & 0xff] +
584
- $sb_1[$l >> 16 & 0xff] ^
585
- $sb_2[$l >> 8 & 0xff]) +
586
- $sb_3[$l & 0xff];
587
-
588
- $r^= ' . $p[$i + 1] . ';
589
- $l^= ($sb_0[$r >> 24 & 0xff] +
590
- $sb_1[$r >> 16 & 0xff] ^
591
- $sb_2[$r >> 8 & 0xff]) +
592
- $sb_3[$r & 0xff];
593
- ';
594
- }
595
- $encrypt_block.= '
596
- $in = pack("N*",
597
- $r ^ ' . $p[17] . ',
598
- $l ^ ' . $p[16] . '
599
- );
600
- ';
601
-
602
- // Generating decrypt code:
603
- $decrypt_block = '
604
- $in = unpack("N*", $in);
605
- $l = $in[1];
606
- $r = $in[2];
607
- ';
608
-
609
- for ($i = 17; $i > 2; $i-= 2) {
610
- $decrypt_block.= '
611
- $l^= ' . $p[$i] . ';
612
- $r^= ($sb_0[$l >> 24 & 0xff] +
613
- $sb_1[$l >> 16 & 0xff] ^
614
- $sb_2[$l >> 8 & 0xff]) +
615
- $sb_3[$l & 0xff];
616
-
617
- $r^= ' . $p[$i - 1] . ';
618
- $l^= ($sb_0[$r >> 24 & 0xff] +
619
- $sb_1[$r >> 16 & 0xff] ^
620
- $sb_2[$r >> 8 & 0xff]) +
621
- $sb_3[$r & 0xff];
622
- ';
623
- }
624
-
625
- $decrypt_block.= '
626
- $in = pack("N*",
627
- $r ^ ' . $p[0] . ',
628
- $l ^ ' . $p[1] . '
629
- );
630
- ';
631
-
632
- $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
633
- array(
634
- 'init_crypt' => $init_crypt,
635
- 'init_encrypt' => '',
636
- 'init_decrypt' => '',
637
- 'encrypt_block' => $encrypt_block,
638
- 'decrypt_block' => $decrypt_block
639
- )
640
- );
641
- }
642
- $this->inline_crypt = $lambda_functions[$code_hash];
643
- }
644
- }
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Pure-PHP implementation of Blowfish.
5
+ *
6
+ * Uses mcrypt, if available, and an internal implementation, otherwise.
7
+ *
8
+ * PHP versions 4 and 5
9
+ *
10
+ * Useful resources are as follows:
11
+ *
12
+ * - {@link http://en.wikipedia.org/wiki/Blowfish_(cipher) Wikipedia description of Blowfish}
13
+ *
14
+ * Here's a short example of how to use this library:
15
+ * <code>
16
+ * <?php
17
+ * include 'Crypt/Blowfish.php';
18
+ *
19
+ * $blowfish = new Crypt_Blowfish();
20
+ *
21
+ * $blowfish->setKey('12345678901234567890123456789012');
22
+ *
23
+ * $plaintext = str_repeat('a', 1024);
24
+ *
25
+ * echo $blowfish->decrypt($blowfish->encrypt($plaintext));
26
+ * ?>
27
+ * </code>
28
+ *
29
+ * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
30
+ * of this software and associated documentation files (the "Software"), to deal
31
+ * in the Software without restriction, including without limitation the rights
32
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
33
+ * copies of the Software, and to permit persons to whom the Software is
34
+ * furnished to do so, subject to the following conditions:
35
+ *
36
+ * The above copyright notice and this permission notice shall be included in
37
+ * all copies or substantial portions of the Software.
38
+ *
39
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
40
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
41
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
42
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
43
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
44
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
45
+ * THE SOFTWARE.
46
+ *
47
+ * @category Crypt
48
+ * @package Crypt_Blowfish
49
+ * @author Jim Wigginton <terrafrost@php.net>
50
+ * @author Hans-Juergen Petrich <petrich@tronic-media.com>
51
+ * @copyright 2007 Jim Wigginton
52
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
53
+ * @link http://phpseclib.sourceforge.net
54
+ */
55
+
56
+ /**
57
+ * Include Crypt_Base
58
+ *
59
+ * Base cipher class
60
+ */
61
+ if (!class_exists('Crypt_Base')) {
62
+ include_once 'Base.php';
63
+ }
64
+
65
+ /**#@+
66
+ * @access public
67
+ * @see Crypt_Blowfish::encrypt()
68
+ * @see Crypt_Blowfish::decrypt()
69
+ */
70
+ /**
71
+ * Encrypt / decrypt using the Counter mode.
72
+ *
73
+ * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
74
+ *
75
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
76
+ */
77
+ define('CRYPT_BLOWFISH_MODE_CTR', CRYPT_MODE_CTR);
78
+ /**
79
+ * Encrypt / decrypt using the Electronic Code Book mode.
80
+ *
81
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
82
+ */
83
+ define('CRYPT_BLOWFISH_MODE_ECB', CRYPT_MODE_ECB);
84
+ /**
85
+ * Encrypt / decrypt using the Code Book Chaining mode.
86
+ *
87
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
88
+ */
89
+ define('CRYPT_BLOWFISH_MODE_CBC', CRYPT_MODE_CBC);
90
+ /**
91
+ * Encrypt / decrypt using the Cipher Feedback mode.
92
+ *
93
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
94
+ */
95
+ define('CRYPT_BLOWFISH_MODE_CFB', CRYPT_MODE_CFB);
96
+ /**
97
+ * Encrypt / decrypt using the Cipher Feedback mode.
98
+ *
99
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
100
+ */
101
+ define('CRYPT_BLOWFISH_MODE_OFB', CRYPT_MODE_OFB);
102
+ /**#@-*/
103
+
104
+ /**
105
+ * Pure-PHP implementation of Blowfish.
106
+ *
107
+ * @package Crypt_Blowfish
108
+ * @author Jim Wigginton <terrafrost@php.net>
109
+ * @author Hans-Juergen Petrich <petrich@tronic-media.com>
110
+ * @access public
111
+ */
112
+ class Crypt_Blowfish extends Crypt_Base
113
+ {
114
+ /**
115
+ * Block Length of the cipher
116
+ *
117
+ * @see Crypt_Base::block_size
118
+ * @var Integer
119
+ * @access private
120
+ */
121
+ var $block_size = 8;
122
+
123
+ /**
124
+ * The default password key_size used by setPassword()
125
+ *
126
+ * @see Crypt_Base::password_key_size
127
+ * @see Crypt_Base::setPassword()
128
+ * @var Integer
129
+ * @access private
130
+ */
131
+ var $password_key_size = 56;
132
+
133
+ /**
134
+ * The namespace used by the cipher for its constants.
135
+ *
136
+ * @see Crypt_Base::const_namespace
137
+ * @var String
138
+ * @access private
139
+ */
140
+ var $const_namespace = 'BLOWFISH';
141
+
142
+ /**
143
+ * The mcrypt specific name of the cipher
144
+ *
145
+ * @see Crypt_Base::cipher_name_mcrypt
146
+ * @var String
147
+ * @access private
148
+ */
149
+ var $cipher_name_mcrypt = 'blowfish';
150
+
151
+ /**
152
+ * Optimizing value while CFB-encrypting
153
+ *
154
+ * @see Crypt_Base::cfb_init_len
155
+ * @var Integer
156
+ * @access private
157
+ */
158
+ var $cfb_init_len = 500;
159
+
160
+ /**
161
+ * The fixed subkeys boxes ($sbox0 - $sbox3) with 256 entries each
162
+ *
163
+ * S-Box 0
164
+ *
165
+ * @access private
166
+ * @var array
167
+ */
168
+ var $sbox0 = array (
169
+ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
170
+ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
171
+ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
172
+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
173
+ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
174
+ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
175
+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
176
+ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
177
+ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
178
+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
179
+ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
180
+ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
181
+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
182
+ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
183
+ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
184
+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
185
+ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
186
+ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
187
+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
188
+ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
189
+ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
190
+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
191
+ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
192
+ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
193
+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
194
+ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
195
+ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
196
+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
197
+ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
198
+ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
199
+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
200
+ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
201
+ );
202
+
203
+ /**
204
+ * S-Box 1
205
+ *
206
+ * @access private
207
+ * @var array
208
+ */
209
+ var $sbox1 = array(
210
+ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
211
+ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
212
+ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
213
+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
214
+ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
215
+ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
216
+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
217
+ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
218
+ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
219
+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
220
+ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
221
+ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
222
+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
223
+ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
224
+ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
225
+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
226
+ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
227
+ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
228
+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
229
+ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
230
+ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
231
+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
232
+ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
233
+ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
234
+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
235
+ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
236
+ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
237
+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
238
+ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
239
+ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
240
+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
241
+ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
242
+ );
243
+
244
+ /**
245
+ * S-Box 2
246
+ *
247
+ * @access private
248
+ * @var array
249
+ */
250
+ var $sbox2 = array(
251
+ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
252
+ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
253
+ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
254
+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
255
+ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
256
+ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
257
+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
258
+ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
259
+ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
260
+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
261
+ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
262
+ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
263
+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
264
+ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
265
+ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
266
+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
267
+ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
268
+ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
269
+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
270
+ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
271
+ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
272
+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
273
+ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
274
+ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
275
+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
276
+ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
277
+ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
278
+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
279
+ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
280
+ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
281
+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
282
+ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
283
+ );
284
+
285
+ /**
286
+ * S-Box 3
287
+ *
288
+ * @access private
289
+ * @var array
290
+ */
291
+ var $sbox3 = array(
292
+ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
293
+ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
294
+ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
295
+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
296
+ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
297
+ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
298
+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
299
+ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
300
+ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
301
+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
302
+ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
303
+ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
304
+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
305
+ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
306
+ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
307
+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
308
+ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
309
+ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
310
+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
311
+ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
312
+ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
313
+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
314
+ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
315
+ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
316
+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
317
+ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
318
+ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
319
+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
320
+ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
321
+ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
322
+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
323
+ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
324
+ );
325
+
326
+ /**
327
+ * P-Array consists of 18 32-bit subkeys
328
+ *
329
+ * @var array
330
+ * @access private
331
+ */
332
+ var $parray = array(
333
+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0,
334
+ 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
335
+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b
336
+ );
337
+
338
+ /**
339
+ * The BCTX-working Array
340
+ *
341
+ * Holds the expanded key [p] and the key-depended s-boxes [sb]
342
+ *
343
+ * @var array
344
+ * @access private
345
+ */
346
+ var $bctx;
347
+
348
+ /**
349
+ * Holds the last used key
350
+ *
351
+ * @var Array
352
+ * @access private
353
+ */
354
+ var $kl;
355
+
356
+ /**
357
+ * Sets the key.
358
+ *
359
+ * Keys can be of any length. Blowfish, itself, requires the use of a key between 32 and max. 448-bits long.
360
+ * If the key is less than 32-bits we NOT fill the key to 32bit but let the key as it is to be compatible
361
+ * with mcrypt because mcrypt act this way with blowfish key's < 32 bits.
362
+ *
363
+ * If the key is more than 448-bits, we trim the excess bits.
364
+ *
365
+ * If the key is not explicitly set, or empty, it'll be assumed a 128 bits key to be all null bytes.
366
+ *
367
+ * @access public
368
+ * @see Crypt_Base::setKey()
369
+ * @param String $key
370
+ */
371
+ function setKey($key)
372
+ {
373
+ $keylength = strlen($key);
374
+
375
+ if (!$keylength) {
376
+ $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
377
+ } elseif ($keylength > 56) {
378
+ $key = substr($key, 0, 56);
379
+ }
380
+
381
+ parent::setKey($key);
382
+ }
383
+
384
+ /**
385
+ * Test for engine validity
386
+ *
387
+ * This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine()
388
+ *
389
+ * @see Crypt_Base::isValidEngine()
390
+ * @param Integer $engine
391
+ * @access public
392
+ * @return Boolean
393
+ */
394
+ function isValidEngine($engine)
395
+ {
396
+ if ($engine == CRYPT_ENGINE_OPENSSL) {
397
+ if (strlen($this->key) != 16) {
398
+ return false;
399
+ }
400
+ $this->cipher_name_openssl_ecb = 'bf-ecb';
401
+ $this->cipher_name_openssl = 'bf-' . $this->_openssl_translate_mode();
402
+ }
403
+
404
+ return parent::isValidEngine($engine);
405
+ }
406
+
407
+ /**
408
+ * Setup the key (expansion)
409
+ *
410
+ * @see Crypt_Base::_setupKey()
411
+ * @access private
412
+ */
413
+ function _setupKey()
414
+ {
415
+ if (isset($this->kl['key']) && $this->key === $this->kl['key']) {
416
+ // already expanded
417
+ return;
418
+ }
419
+ $this->kl = array('key' => $this->key);
420
+
421
+ /* key-expanding p[] and S-Box building sb[] */
422
+ $this->bctx = array(
423
+ 'p' => array(),
424
+ 'sb' => array(
425
+ $this->sbox0,
426
+ $this->sbox1,
427
+ $this->sbox2,
428
+ $this->sbox3
429
+ )
430
+ );
431
+
432
+ // unpack binary string in unsigned chars
433
+ $key = array_values(unpack('C*', $this->key));
434
+ $keyl = count($key);
435
+ for ($j = 0, $i = 0; $i < 18; ++$i) {
436
+ // xor P1 with the first 32-bits of the key, xor P2 with the second 32-bits ...
437
+ for ($data = 0, $k = 0; $k < 4; ++$k) {
438
+ $data = ($data << 8) | $key[$j];
439
+ if (++$j >= $keyl) {
440
+ $j = 0;
441
+ }
442
+ }
443
+ $this->bctx['p'][] = $this->parray[$i] ^ $data;
444
+ }
445
+
446
+ // encrypt the zero-string, replace P1 and P2 with the encrypted data,
447
+ // encrypt P3 and P4 with the new P1 and P2, do it with all P-array and subkeys
448
+ $data = "\0\0\0\0\0\0\0\0";
449
+ for ($i = 0; $i < 18; $i += 2) {
450
+ list($l, $r) = array_values(unpack('N*', $data = $this->_encryptBlock($data)));
451
+ $this->bctx['p'][$i ] = $l;
452
+ $this->bctx['p'][$i + 1] = $r;
453
+ }
454
+ for ($i = 0; $i < 4; ++$i) {
455
+ for ($j = 0; $j < 256; $j += 2) {
456
+ list($l, $r) = array_values(unpack('N*', $data = $this->_encryptBlock($data)));
457
+ $this->bctx['sb'][$i][$j ] = $l;
458
+ $this->bctx['sb'][$i][$j + 1] = $r;
459
+ }
460
+ }
461
+ }
462
+
463
+ /**
464
+ * Encrypts a block
465
+ *
466
+ * @access private
467
+ * @param String $in
468
+ * @return String
469
+ */
470
+ function _encryptBlock($in)
471
+ {
472
+ $p = $this->bctx["p"];
473
+ // extract($this->bctx["sb"], EXTR_PREFIX_ALL, "sb"); // slower
474
+ $sb_0 = $this->bctx["sb"][0];
475
+ $sb_1 = $this->bctx["sb"][1];
476
+ $sb_2 = $this->bctx["sb"][2];
477
+ $sb_3 = $this->bctx["sb"][3];
478
+
479
+ $in = unpack("N*", $in);
480
+ $l = $in[1];
481
+ $r = $in[2];
482
+
483
+ for ($i = 0; $i < 16; $i+= 2) {
484
+ $l^= $p[$i];
485
+ $r^= ($sb_0[$l >> 24 & 0xff] +
486
+ $sb_1[$l >> 16 & 0xff] ^
487
+ $sb_2[$l >> 8 & 0xff]) +
488
+ $sb_3[$l & 0xff];
489
+
490
+ $r^= $p[$i + 1];
491
+ $l^= ($sb_0[$r >> 24 & 0xff] +
492
+ $sb_1[$r >> 16 & 0xff] ^
493
+ $sb_2[$r >> 8 & 0xff]) +
494
+ $sb_3[$r & 0xff];
495
+ }
496
+ return pack("N*", $r ^ $p[17], $l ^ $p[16]);
497
+ }
498
+
499
+ /**
500
+ * Decrypts a block
501
+ *
502
+ * @access private
503
+ * @param String $in
504
+ * @return String
505
+ */
506
+ function _decryptBlock($in)
507
+ {
508
+ $p = $this->bctx["p"];
509
+ $sb_0 = $this->bctx["sb"][0];
510
+ $sb_1 = $this->bctx["sb"][1];
511
+ $sb_2 = $this->bctx["sb"][2];
512
+ $sb_3 = $this->bctx["sb"][3];
513
+
514
+ $in = unpack("N*", $in);
515
+ $l = $in[1];
516
+ $r = $in[2];
517
+
518
+ for ($i = 17; $i > 2; $i-= 2) {
519
+ $l^= $p[$i];
520
+ $r^= ($sb_0[$l >> 24 & 0xff] +
521
+ $sb_1[$l >> 16 & 0xff] ^
522
+ $sb_2[$l >> 8 & 0xff]) +
523
+ $sb_3[$l & 0xff];
524
+
525
+ $r^= $p[$i - 1];
526
+ $l^= ($sb_0[$r >> 24 & 0xff] +
527
+ $sb_1[$r >> 16 & 0xff] ^
528
+ $sb_2[$r >> 8 & 0xff]) +
529
+ $sb_3[$r & 0xff];
530
+ }
531
+ return pack("N*", $r ^ $p[0], $l ^ $p[1]);
532
+ }
533
+
534
+ /**
535
+ * Setup the performance-optimized function for de/encrypt()
536
+ *
537
+ * @see Crypt_Base::_setupInlineCrypt()
538
+ * @access private
539
+ */
540
+ function _setupInlineCrypt()
541
+ {
542
+ $lambda_functions =& Crypt_Blowfish::_getLambdaFunctions();
543
+
544
+ // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
545
+ // (Currently, for Crypt_Blowfish, one generated $lambda_function cost on php5.5@32bit ~100kb unfreeable mem and ~180kb on php5.5@64bit)
546
+ // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one.
547
+ $gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
548
+
549
+ // Generation of a unique hash for our generated code
550
+ $code_hash = "Crypt_Blowfish, {$this->mode}";
551
+ if ($gen_hi_opt_code) {
552
+ $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
553
+ }
554
+
555
+ if (!isset($lambda_functions[$code_hash])) {
556
+ switch (true) {
557
+ case $gen_hi_opt_code:
558
+ $p = $this->bctx['p'];
559
+ $init_crypt = '
560
+ static $sb_0, $sb_1, $sb_2, $sb_3;
561
+ if (!$sb_0) {
562
+ $sb_0 = $self->bctx["sb"][0];
563
+ $sb_1 = $self->bctx["sb"][1];
564
+ $sb_2 = $self->bctx["sb"][2];
565
+ $sb_3 = $self->bctx["sb"][3];
566
+ }
567
+ ';
568
+ break;
569
+ default:
570
+ $p = array();
571
+ for ($i = 0; $i < 18; ++$i) {
572
+ $p[] = '$p_' . $i;
573
+ }
574
+ $init_crypt = '
575
+ list($sb_0, $sb_1, $sb_2, $sb_3) = $self->bctx["sb"];
576
+ list(' . implode(',', $p) . ') = $self->bctx["p"];
577
+
578
+ ';
579
+ }
580
+
581
+ // Generating encrypt code:
582
+ $encrypt_block = '
583
+ $in = unpack("N*", $in);
584
+ $l = $in[1];
585
+ $r = $in[2];
586
+ ';
587
+ for ($i = 0; $i < 16; $i+= 2) {
588
+ $encrypt_block.= '
589
+ $l^= ' . $p[$i] . ';
590
+ $r^= ($sb_0[$l >> 24 & 0xff] +
591
+ $sb_1[$l >> 16 & 0xff] ^
592
+ $sb_2[$l >> 8 & 0xff]) +
593
+ $sb_3[$l & 0xff];
594
+
595
+ $r^= ' . $p[$i + 1] . ';
596
+ $l^= ($sb_0[$r >> 24 & 0xff] +
597
+ $sb_1[$r >> 16 & 0xff] ^
598
+ $sb_2[$r >> 8 & 0xff]) +
599
+ $sb_3[$r & 0xff];
600
+ ';
601
+ }
602
+ $encrypt_block.= '
603
+ $in = pack("N*",
604
+ $r ^ ' . $p[17] . ',
605
+ $l ^ ' . $p[16] . '
606
+ );
607
+ ';
608
+
609
+ // Generating decrypt code:
610
+ $decrypt_block = '
611
+ $in = unpack("N*", $in);
612
+ $l = $in[1];
613
+ $r = $in[2];
614
+ ';
615
+
616
+ for ($i = 17; $i > 2; $i-= 2) {
617
+ $decrypt_block.= '
618
+ $l^= ' . $p[$i] . ';
619
+ $r^= ($sb_0[$l >> 24 & 0xff] +
620
+ $sb_1[$l >> 16 & 0xff] ^
621
+ $sb_2[$l >> 8 & 0xff]) +
622
+ $sb_3[$l & 0xff];
623
+
624
+ $r^= ' . $p[$i - 1] . ';
625
+ $l^= ($sb_0[$r >> 24 & 0xff] +
626
+ $sb_1[$r >> 16 & 0xff] ^
627
+ $sb_2[$r >> 8 & 0xff]) +
628
+ $sb_3[$r & 0xff];
629
+ ';
630
+ }
631
+
632
+ $decrypt_block.= '
633
+ $in = pack("N*",
634
+ $r ^ ' . $p[0] . ',
635
+ $l ^ ' . $p[1] . '
636
+ );
637
+ ';
638
+
639
+ $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
640
+ array(
641
+ 'init_crypt' => $init_crypt,
642
+ 'init_encrypt' => '',
643
+ 'init_decrypt' => '',
644
+ 'encrypt_block' => $encrypt_block,
645
+ 'decrypt_block' => $decrypt_block
646
+ )
647
+ );
648
+ }
649
+ $this->inline_crypt = $lambda_functions[$code_hash];
650
+ }
651
+ }
phpseclib/Crypt/DES.php CHANGED
@@ -1,1506 +1,1528 @@
1
- <?php
2
-
3
- /**
4
- * Pure-PHP implementation of DES.
5
- *
6
- * Uses mcrypt, if available, and an internal implementation, otherwise.
7
- *
8
- * PHP versions 4 and 5
9
- *
10
- * Useful resources are as follows:
11
- *
12
- * - {@link http://en.wikipedia.org/wiki/DES_supplementary_material Wikipedia: DES supplementary material}
13
- * - {@link http://www.itl.nist.gov/fipspubs/fip46-2.htm FIPS 46-2 - (DES), Data Encryption Standard}
14
- * - {@link http://www.cs.eku.edu/faculty/styer/460/Encrypt/JS-DES.html JavaScript DES Example}
15
- *
16
- * Here's a short example of how to use this library:
17
- * <code>
18
- * <?php
19
- * include 'Crypt/DES.php';
20
- *
21
- * $des = new Crypt_DES();
22
- *
23
- * $des->setKey('abcdefgh');
24
- *
25
- * $size = 10 * 1024;
26
- * $plaintext = '';
27
- * for ($i = 0; $i < $size; $i++) {
28
- * $plaintext.= 'a';
29
- * }
30
- *
31
- * echo $des->decrypt($des->encrypt($plaintext));
32
- * ?>
33
- * </code>
34
- *
35
- * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
36
- * of this software and associated documentation files (the "Software"), to deal
37
- * in the Software without restriction, including without limitation the rights
38
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
39
- * copies of the Software, and to permit persons to whom the Software is
40
- * furnished to do so, subject to the following conditions:
41
- *
42
- * The above copyright notice and this permission notice shall be included in
43
- * all copies or substantial portions of the Software.
44
- *
45
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
46
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
47
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
48
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
49
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
50
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
51
- * THE SOFTWARE.
52
- *
53
- * @category Crypt
54
- * @package Crypt_DES
55
- * @author Jim Wigginton <terrafrost@php.net>
56
- * @copyright MMVII Jim Wigginton
57
- * @license http://www.opensource.org/licenses/mit-license.html MIT License
58
- * @link http://phpseclib.sourceforge.net
59
- */
60
-
61
- /**
62
- * Include Crypt_Base
63
- *
64
- * Base cipher class
65
- */
66
- if (!class_exists('Crypt_Base')) {
67
- include_once 'Base.php';
68
- }
69
-
70
- /**#@+
71
- * @access private
72
- * @see Crypt_DES::_setupKey()
73
- * @see Crypt_DES::_processBlock()
74
- */
75
- /**
76
- * Contains $keys[CRYPT_DES_ENCRYPT]
77
- */
78
- define('CRYPT_DES_ENCRYPT', 0);
79
- /**
80
- * Contains $keys[CRYPT_DES_DECRYPT]
81
- */
82
- define('CRYPT_DES_DECRYPT', 1);
83
- /**#@-*/
84
-
85
- /**#@+
86
- * @access public
87
- * @see Crypt_DES::encrypt()
88
- * @see Crypt_DES::decrypt()
89
- */
90
- /**
91
- * Encrypt / decrypt using the Counter mode.
92
- *
93
- * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
94
- *
95
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
96
- */
97
- define('CRYPT_DES_MODE_CTR', CRYPT_MODE_CTR);
98
- /**
99
- * Encrypt / decrypt using the Electronic Code Book mode.
100
- *
101
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
102
- */
103
- define('CRYPT_DES_MODE_ECB', CRYPT_MODE_ECB);
104
- /**
105
- * Encrypt / decrypt using the Code Book Chaining mode.
106
- *
107
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
108
- */
109
- define('CRYPT_DES_MODE_CBC', CRYPT_MODE_CBC);
110
- /**
111
- * Encrypt / decrypt using the Cipher Feedback mode.
112
- *
113
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
114
- */
115
- define('CRYPT_DES_MODE_CFB', CRYPT_MODE_CFB);
116
- /**
117
- * Encrypt / decrypt using the Cipher Feedback mode.
118
- *
119
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
120
- */
121
- define('CRYPT_DES_MODE_OFB', CRYPT_MODE_OFB);
122
- /**#@-*/
123
-
124
- /**#@+
125
- * @access private
126
- * @see Crypt_Base::Crypt_Base()
127
- */
128
- /**
129
- * Toggles the internal implementation
130
- */
131
- define('CRYPT_DES_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
132
- /**
133
- * Toggles the mcrypt implementation
134
- */
135
- define('CRYPT_DES_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
136
- /**#@-*/
137
-
138
- /**
139
- * Pure-PHP implementation of DES.
140
- *
141
- * @package Crypt_DES
142
- * @author Jim Wigginton <terrafrost@php.net>
143
- * @access public
144
- */
145
- class Crypt_DES extends Crypt_Base
146
- {
147
- /**
148
- * Block Length of the cipher
149
- *
150
- * @see Crypt_Base::block_size
151
- * @var Integer
152
- * @access private
153
- */
154
- var $block_size = 8;
155
-
156
- /**
157
- * The Key
158
- *
159
- * @see Crypt_Base::key
160
- * @see setKey()
161
- * @var String
162
- * @access private
163
- */
164
- var $key = "\0\0\0\0\0\0\0\0";
165
-
166
- /**
167
- * The default password key_size used by setPassword()
168
- *
169
- * @see Crypt_Base::password_key_size
170
- * @see Crypt_Base::setPassword()
171
- * @var Integer
172
- * @access private
173
- */
174
- var $password_key_size = 8;
175
-
176
- /**
177
- * The namespace used by the cipher for its constants.
178
- *
179
- * @see Crypt_Base::const_namespace
180
- * @var String
181
- * @access private
182
- */
183
- var $const_namespace = 'DES';
184
-
185
- /**
186
- * The mcrypt specific name of the cipher
187
- *
188
- * @see Crypt_Base::cipher_name_mcrypt
189
- * @var String
190
- * @access private
191
- */
192
- var $cipher_name_mcrypt = 'des';
193
-
194
- /**
195
- * Optimizing value while CFB-encrypting
196
- *
197
- * @see Crypt_Base::cfb_init_len
198
- * @var Integer
199
- * @access private
200
- */
201
- var $cfb_init_len = 500;
202
-
203
- /**
204
- * Switch for DES/3DES encryption
205
- *
206
- * Used only if $engine == CRYPT_DES_MODE_INTERNAL
207
- *
208
- * @see Crypt_DES::_setupKey()
209
- * @see Crypt_DES::_processBlock()
210
- * @var Integer
211
- * @access private
212
- */
213
- var $des_rounds = 1;
214
-
215
- /**
216
- * max possible size of $key
217
- *
218
- * @see Crypt_DES::setKey()
219
- * @var String
220
- * @access private
221
- */
222
- var $key_size_max = 8;
223
-
224
- /**
225
- * The Key Schedule
226
- *
227
- * @see Crypt_DES::_setupKey()
228
- * @var Array
229
- * @access private
230
- */
231
- var $keys;
232
-
233
- /**
234
- * Shuffle table.
235
- *
236
- * For each byte value index, the entry holds an 8-byte string
237
- * with each byte containing all bits in the same state as the
238
- * corresponding bit in the index value.
239
- *
240
- * @see Crypt_DES::_processBlock()
241
- * @see Crypt_DES::_setupKey()
242
- * @var Array
243
- * @access private
244
- */
245
- var $shuffle = array(
246
- "\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\xFF",
247
- "\x00\x00\x00\x00\x00\x00\xFF\x00", "\x00\x00\x00\x00\x00\x00\xFF\xFF",
248
- "\x00\x00\x00\x00\x00\xFF\x00\x00", "\x00\x00\x00\x00\x00\xFF\x00\xFF",
249
- "\x00\x00\x00\x00\x00\xFF\xFF\x00", "\x00\x00\x00\x00\x00\xFF\xFF\xFF",
250
- "\x00\x00\x00\x00\xFF\x00\x00\x00", "\x00\x00\x00\x00\xFF\x00\x00\xFF",
251
- "\x00\x00\x00\x00\xFF\x00\xFF\x00", "\x00\x00\x00\x00\xFF\x00\xFF\xFF",
252
- "\x00\x00\x00\x00\xFF\xFF\x00\x00", "\x00\x00\x00\x00\xFF\xFF\x00\xFF",
253
- "\x00\x00\x00\x00\xFF\xFF\xFF\x00", "\x00\x00\x00\x00\xFF\xFF\xFF\xFF",
254
- "\x00\x00\x00\xFF\x00\x00\x00\x00", "\x00\x00\x00\xFF\x00\x00\x00\xFF",
255
- "\x00\x00\x00\xFF\x00\x00\xFF\x00", "\x00\x00\x00\xFF\x00\x00\xFF\xFF",
256
- "\x00\x00\x00\xFF\x00\xFF\x00\x00", "\x00\x00\x00\xFF\x00\xFF\x00\xFF",
257
- "\x00\x00\x00\xFF\x00\xFF\xFF\x00", "\x00\x00\x00\xFF\x00\xFF\xFF\xFF",
258
- "\x00\x00\x00\xFF\xFF\x00\x00\x00", "\x00\x00\x00\xFF\xFF\x00\x00\xFF",
259
- "\x00\x00\x00\xFF\xFF\x00\xFF\x00", "\x00\x00\x00\xFF\xFF\x00\xFF\xFF",
260
- "\x00\x00\x00\xFF\xFF\xFF\x00\x00", "\x00\x00\x00\xFF\xFF\xFF\x00\xFF",
261
- "\x00\x00\x00\xFF\xFF\xFF\xFF\x00", "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF",
262
- "\x00\x00\xFF\x00\x00\x00\x00\x00", "\x00\x00\xFF\x00\x00\x00\x00\xFF",
263
- "\x00\x00\xFF\x00\x00\x00\xFF\x00", "\x00\x00\xFF\x00\x00\x00\xFF\xFF",
264
- "\x00\x00\xFF\x00\x00\xFF\x00\x00", "\x00\x00\xFF\x00\x00\xFF\x00\xFF",
265
- "\x00\x00\xFF\x00\x00\xFF\xFF\x00", "\x00\x00\xFF\x00\x00\xFF\xFF\xFF",
266
- "\x00\x00\xFF\x00\xFF\x00\x00\x00", "\x00\x00\xFF\x00\xFF\x00\x00\xFF",
267
- "\x00\x00\xFF\x00\xFF\x00\xFF\x00", "\x00\x00\xFF\x00\xFF\x00\xFF\xFF",
268
- "\x00\x00\xFF\x00\xFF\xFF\x00\x00", "\x00\x00\xFF\x00\xFF\xFF\x00\xFF",
269
- "\x00\x00\xFF\x00\xFF\xFF\xFF\x00", "\x00\x00\xFF\x00\xFF\xFF\xFF\xFF",
270
- "\x00\x00\xFF\xFF\x00\x00\x00\x00", "\x00\x00\xFF\xFF\x00\x00\x00\xFF",
271
- "\x00\x00\xFF\xFF\x00\x00\xFF\x00", "\x00\x00\xFF\xFF\x00\x00\xFF\xFF",
272
- "\x00\x00\xFF\xFF\x00\xFF\x00\x00", "\x00\x00\xFF\xFF\x00\xFF\x00\xFF",
273
- "\x00\x00\xFF\xFF\x00\xFF\xFF\x00", "\x00\x00\xFF\xFF\x00\xFF\xFF\xFF",
274
- "\x00\x00\xFF\xFF\xFF\x00\x00\x00", "\x00\x00\xFF\xFF\xFF\x00\x00\xFF",
275
- "\x00\x00\xFF\xFF\xFF\x00\xFF\x00", "\x00\x00\xFF\xFF\xFF\x00\xFF\xFF",
276
- "\x00\x00\xFF\xFF\xFF\xFF\x00\x00", "\x00\x00\xFF\xFF\xFF\xFF\x00\xFF",
277
- "\x00\x00\xFF\xFF\xFF\xFF\xFF\x00", "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF",
278
- "\x00\xFF\x00\x00\x00\x00\x00\x00", "\x00\xFF\x00\x00\x00\x00\x00\xFF",
279
- "\x00\xFF\x00\x00\x00\x00\xFF\x00", "\x00\xFF\x00\x00\x00\x00\xFF\xFF",
280
- "\x00\xFF\x00\x00\x00\xFF\x00\x00", "\x00\xFF\x00\x00\x00\xFF\x00\xFF",
281
- "\x00\xFF\x00\x00\x00\xFF\xFF\x00", "\x00\xFF\x00\x00\x00\xFF\xFF\xFF",
282
- "\x00\xFF\x00\x00\xFF\x00\x00\x00", "\x00\xFF\x00\x00\xFF\x00\x00\xFF",
283
- "\x00\xFF\x00\x00\xFF\x00\xFF\x00", "\x00\xFF\x00\x00\xFF\x00\xFF\xFF",
284
- "\x00\xFF\x00\x00\xFF\xFF\x00\x00", "\x00\xFF\x00\x00\xFF\xFF\x00\xFF",
285
- "\x00\xFF\x00\x00\xFF\xFF\xFF\x00", "\x00\xFF\x00\x00\xFF\xFF\xFF\xFF",
286
- "\x00\xFF\x00\xFF\x00\x00\x00\x00", "\x00\xFF\x00\xFF\x00\x00\x00\xFF",
287
- "\x00\xFF\x00\xFF\x00\x00\xFF\x00", "\x00\xFF\x00\xFF\x00\x00\xFF\xFF",
288
- "\x00\xFF\x00\xFF\x00\xFF\x00\x00", "\x00\xFF\x00\xFF\x00\xFF\x00\xFF",
289
- "\x00\xFF\x00\xFF\x00\xFF\xFF\x00", "\x00\xFF\x00\xFF\x00\xFF\xFF\xFF",
290
- "\x00\xFF\x00\xFF\xFF\x00\x00\x00", "\x00\xFF\x00\xFF\xFF\x00\x00\xFF",
291
- "\x00\xFF\x00\xFF\xFF\x00\xFF\x00", "\x00\xFF\x00\xFF\xFF\x00\xFF\xFF",
292
- "\x00\xFF\x00\xFF\xFF\xFF\x00\x00", "\x00\xFF\x00\xFF\xFF\xFF\x00\xFF",
293
- "\x00\xFF\x00\xFF\xFF\xFF\xFF\x00", "\x00\xFF\x00\xFF\xFF\xFF\xFF\xFF",
294
- "\x00\xFF\xFF\x00\x00\x00\x00\x00", "\x00\xFF\xFF\x00\x00\x00\x00\xFF",
295
- "\x00\xFF\xFF\x00\x00\x00\xFF\x00", "\x00\xFF\xFF\x00\x00\x00\xFF\xFF",
296
- "\x00\xFF\xFF\x00\x00\xFF\x00\x00", "\x00\xFF\xFF\x00\x00\xFF\x00\xFF",
297
- "\x00\xFF\xFF\x00\x00\xFF\xFF\x00", "\x00\xFF\xFF\x00\x00\xFF\xFF\xFF",
298
- "\x00\xFF\xFF\x00\xFF\x00\x00\x00", "\x00\xFF\xFF\x00\xFF\x00\x00\xFF",
299
- "\x00\xFF\xFF\x00\xFF\x00\xFF\x00", "\x00\xFF\xFF\x00\xFF\x00\xFF\xFF",
300
- "\x00\xFF\xFF\x00\xFF\xFF\x00\x00", "\x00\xFF\xFF\x00\xFF\xFF\x00\xFF",
301
- "\x00\xFF\xFF\x00\xFF\xFF\xFF\x00", "\x00\xFF\xFF\x00\xFF\xFF\xFF\xFF",
302
- "\x00\xFF\xFF\xFF\x00\x00\x00\x00", "\x00\xFF\xFF\xFF\x00\x00\x00\xFF",
303
- "\x00\xFF\xFF\xFF\x00\x00\xFF\x00", "\x00\xFF\xFF\xFF\x00\x00\xFF\xFF",
304
- "\x00\xFF\xFF\xFF\x00\xFF\x00\x00", "\x00\xFF\xFF\xFF\x00\xFF\x00\xFF",
305
- "\x00\xFF\xFF\xFF\x00\xFF\xFF\x00", "\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF",
306
- "\x00\xFF\xFF\xFF\xFF\x00\x00\x00", "\x00\xFF\xFF\xFF\xFF\x00\x00\xFF",
307
- "\x00\xFF\xFF\xFF\xFF\x00\xFF\x00", "\x00\xFF\xFF\xFF\xFF\x00\xFF\xFF",
308
- "\x00\xFF\xFF\xFF\xFF\xFF\x00\x00", "\x00\xFF\xFF\xFF\xFF\xFF\x00\xFF",
309
- "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
310
- "\xFF\x00\x00\x00\x00\x00\x00\x00", "\xFF\x00\x00\x00\x00\x00\x00\xFF",
311
- "\xFF\x00\x00\x00\x00\x00\xFF\x00", "\xFF\x00\x00\x00\x00\x00\xFF\xFF",
312
- "\xFF\x00\x00\x00\x00\xFF\x00\x00", "\xFF\x00\x00\x00\x00\xFF\x00\xFF",
313
- "\xFF\x00\x00\x00\x00\xFF\xFF\x00", "\xFF\x00\x00\x00\x00\xFF\xFF\xFF",
314
- "\xFF\x00\x00\x00\xFF\x00\x00\x00", "\xFF\x00\x00\x00\xFF\x00\x00\xFF",
315
- "\xFF\x00\x00\x00\xFF\x00\xFF\x00", "\xFF\x00\x00\x00\xFF\x00\xFF\xFF",
316
- "\xFF\x00\x00\x00\xFF\xFF\x00\x00", "\xFF\x00\x00\x00\xFF\xFF\x00\xFF",
317
- "\xFF\x00\x00\x00\xFF\xFF\xFF\x00", "\xFF\x00\x00\x00\xFF\xFF\xFF\xFF",
318
- "\xFF\x00\x00\xFF\x00\x00\x00\x00", "\xFF\x00\x00\xFF\x00\x00\x00\xFF",
319
- "\xFF\x00\x00\xFF\x00\x00\xFF\x00", "\xFF\x00\x00\xFF\x00\x00\xFF\xFF",
320
- "\xFF\x00\x00\xFF\x00\xFF\x00\x00", "\xFF\x00\x00\xFF\x00\xFF\x00\xFF",
321
- "\xFF\x00\x00\xFF\x00\xFF\xFF\x00", "\xFF\x00\x00\xFF\x00\xFF\xFF\xFF",
322
- "\xFF\x00\x00\xFF\xFF\x00\x00\x00", "\xFF\x00\x00\xFF\xFF\x00\x00\xFF",
323
- "\xFF\x00\x00\xFF\xFF\x00\xFF\x00", "\xFF\x00\x00\xFF\xFF\x00\xFF\xFF",
324
- "\xFF\x00\x00\xFF\xFF\xFF\x00\x00", "\xFF\x00\x00\xFF\xFF\xFF\x00\xFF",
325
- "\xFF\x00\x00\xFF\xFF\xFF\xFF\x00", "\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF",
326
- "\xFF\x00\xFF\x00\x00\x00\x00\x00", "\xFF\x00\xFF\x00\x00\x00\x00\xFF",
327
- "\xFF\x00\xFF\x00\x00\x00\xFF\x00", "\xFF\x00\xFF\x00\x00\x00\xFF\xFF",
328
- "\xFF\x00\xFF\x00\x00\xFF\x00\x00", "\xFF\x00\xFF\x00\x00\xFF\x00\xFF",
329
- "\xFF\x00\xFF\x00\x00\xFF\xFF\x00", "\xFF\x00\xFF\x00\x00\xFF\xFF\xFF",
330
- "\xFF\x00\xFF\x00\xFF\x00\x00\x00", "\xFF\x00\xFF\x00\xFF\x00\x00\xFF",
331
- "\xFF\x00\xFF\x00\xFF\x00\xFF\x00", "\xFF\x00\xFF\x00\xFF\x00\xFF\xFF",
332
- "\xFF\x00\xFF\x00\xFF\xFF\x00\x00", "\xFF\x00\xFF\x00\xFF\xFF\x00\xFF",
333
- "\xFF\x00\xFF\x00\xFF\xFF\xFF\x00", "\xFF\x00\xFF\x00\xFF\xFF\xFF\xFF",
334
- "\xFF\x00\xFF\xFF\x00\x00\x00\x00", "\xFF\x00\xFF\xFF\x00\x00\x00\xFF",
335
- "\xFF\x00\xFF\xFF\x00\x00\xFF\x00", "\xFF\x00\xFF\xFF\x00\x00\xFF\xFF",
336
- "\xFF\x00\xFF\xFF\x00\xFF\x00\x00", "\xFF\x00\xFF\xFF\x00\xFF\x00\xFF",
337
- "\xFF\x00\xFF\xFF\x00\xFF\xFF\x00", "\xFF\x00\xFF\xFF\x00\xFF\xFF\xFF",
338
- "\xFF\x00\xFF\xFF\xFF\x00\x00\x00", "\xFF\x00\xFF\xFF\xFF\x00\x00\xFF",
339
- "\xFF\x00\xFF\xFF\xFF\x00\xFF\x00", "\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF",
340
- "\xFF\x00\xFF\xFF\xFF\xFF\x00\x00", "\xFF\x00\xFF\xFF\xFF\xFF\x00\xFF",
341
- "\xFF\x00\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF",
342
- "\xFF\xFF\x00\x00\x00\x00\x00\x00", "\xFF\xFF\x00\x00\x00\x00\x00\xFF",
343
- "\xFF\xFF\x00\x00\x00\x00\xFF\x00", "\xFF\xFF\x00\x00\x00\x00\xFF\xFF",
344
- "\xFF\xFF\x00\x00\x00\xFF\x00\x00", "\xFF\xFF\x00\x00\x00\xFF\x00\xFF",
345
- "\xFF\xFF\x00\x00\x00\xFF\xFF\x00", "\xFF\xFF\x00\x00\x00\xFF\xFF\xFF",
346
- "\xFF\xFF\x00\x00\xFF\x00\x00\x00", "\xFF\xFF\x00\x00\xFF\x00\x00\xFF",
347
- "\xFF\xFF\x00\x00\xFF\x00\xFF\x00", "\xFF\xFF\x00\x00\xFF\x00\xFF\xFF",
348
- "\xFF\xFF\x00\x00\xFF\xFF\x00\x00", "\xFF\xFF\x00\x00\xFF\xFF\x00\xFF",
349
- "\xFF\xFF\x00\x00\xFF\xFF\xFF\x00", "\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF",
350
- "\xFF\xFF\x00\xFF\x00\x00\x00\x00", "\xFF\xFF\x00\xFF\x00\x00\x00\xFF",
351
- "\xFF\xFF\x00\xFF\x00\x00\xFF\x00", "\xFF\xFF\x00\xFF\x00\x00\xFF\xFF",
352
- "\xFF\xFF\x00\xFF\x00\xFF\x00\x00", "\xFF\xFF\x00\xFF\x00\xFF\x00\xFF",
353
- "\xFF\xFF\x00\xFF\x00\xFF\xFF\x00", "\xFF\xFF\x00\xFF\x00\xFF\xFF\xFF",
354
- "\xFF\xFF\x00\xFF\xFF\x00\x00\x00", "\xFF\xFF\x00\xFF\xFF\x00\x00\xFF",
355
- "\xFF\xFF\x00\xFF\xFF\x00\xFF\x00", "\xFF\xFF\x00\xFF\xFF\x00\xFF\xFF",
356
- "\xFF\xFF\x00\xFF\xFF\xFF\x00\x00", "\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF",
357
- "\xFF\xFF\x00\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF",
358
- "\xFF\xFF\xFF\x00\x00\x00\x00\x00", "\xFF\xFF\xFF\x00\x00\x00\x00\xFF",
359
- "\xFF\xFF\xFF\x00\x00\x00\xFF\x00", "\xFF\xFF\xFF\x00\x00\x00\xFF\xFF",
360
- "\xFF\xFF\xFF\x00\x00\xFF\x00\x00", "\xFF\xFF\xFF\x00\x00\xFF\x00\xFF",
361
- "\xFF\xFF\xFF\x00\x00\xFF\xFF\x00", "\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF",
362
- "\xFF\xFF\xFF\x00\xFF\x00\x00\x00", "\xFF\xFF\xFF\x00\xFF\x00\x00\xFF",
363
- "\xFF\xFF\xFF\x00\xFF\x00\xFF\x00", "\xFF\xFF\xFF\x00\xFF\x00\xFF\xFF",
364
- "\xFF\xFF\xFF\x00\xFF\xFF\x00\x00", "\xFF\xFF\xFF\x00\xFF\xFF\x00\xFF",
365
- "\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF",
366
- "\xFF\xFF\xFF\xFF\x00\x00\x00\x00", "\xFF\xFF\xFF\xFF\x00\x00\x00\xFF",
367
- "\xFF\xFF\xFF\xFF\x00\x00\xFF\x00", "\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF",
368
- "\xFF\xFF\xFF\xFF\x00\xFF\x00\x00", "\xFF\xFF\xFF\xFF\x00\xFF\x00\xFF",
369
- "\xFF\xFF\xFF\xFF\x00\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF",
370
- "\xFF\xFF\xFF\xFF\xFF\x00\x00\x00", "\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF",
371
- "\xFF\xFF\xFF\xFF\xFF\x00\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF",
372
- "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF",
373
- "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
374
- );
375
-
376
- /**
377
- * IP mapping helper table.
378
- *
379
- * Indexing this table with each source byte performs the initial bit permutation.
380
- *
381
- * @var Array
382
- * @access private
383
- */
384
- var $ipmap = array(
385
- 0x00, 0x10, 0x01, 0x11, 0x20, 0x30, 0x21, 0x31,
386
- 0x02, 0x12, 0x03, 0x13, 0x22, 0x32, 0x23, 0x33,
387
- 0x40, 0x50, 0x41, 0x51, 0x60, 0x70, 0x61, 0x71,
388
- 0x42, 0x52, 0x43, 0x53, 0x62, 0x72, 0x63, 0x73,
389
- 0x04, 0x14, 0x05, 0x15, 0x24, 0x34, 0x25, 0x35,
390
- 0x06, 0x16, 0x07, 0x17, 0x26, 0x36, 0x27, 0x37,
391
- 0x44, 0x54, 0x45, 0x55, 0x64, 0x74, 0x65, 0x75,
392
- 0x46, 0x56, 0x47, 0x57, 0x66, 0x76, 0x67, 0x77,
393
- 0x80, 0x90, 0x81, 0x91, 0xA0, 0xB0, 0xA1, 0xB1,
394
- 0x82, 0x92, 0x83, 0x93, 0xA2, 0xB2, 0xA3, 0xB3,
395
- 0xC0, 0xD0, 0xC1, 0xD1, 0xE0, 0xF0, 0xE1, 0xF1,
396
- 0xC2, 0xD2, 0xC3, 0xD3, 0xE2, 0xF2, 0xE3, 0xF3,
397
- 0x84, 0x94, 0x85, 0x95, 0xA4, 0xB4, 0xA5, 0xB5,
398
- 0x86, 0x96, 0x87, 0x97, 0xA6, 0xB6, 0xA7, 0xB7,
399
- 0xC4, 0xD4, 0xC5, 0xD5, 0xE4, 0xF4, 0xE5, 0xF5,
400
- 0xC6, 0xD6, 0xC7, 0xD7, 0xE6, 0xF6, 0xE7, 0xF7,
401
- 0x08, 0x18, 0x09, 0x19, 0x28, 0x38, 0x29, 0x39,
402
- 0x0A, 0x1A, 0x0B, 0x1B, 0x2A, 0x3A, 0x2B, 0x3B,
403
- 0x48, 0x58, 0x49, 0x59, 0x68, 0x78, 0x69, 0x79,
404
- 0x4A, 0x5A, 0x4B, 0x5B, 0x6A, 0x7A, 0x6B, 0x7B,
405
- 0x0C, 0x1C, 0x0D, 0x1D, 0x2C, 0x3C, 0x2D, 0x3D,
406
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
407
- 0x4C, 0x5C, 0x4D, 0x5D, 0x6C, 0x7C, 0x6D, 0x7D,
408
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
409
- 0x88, 0x98, 0x89, 0x99, 0xA8, 0xB8, 0xA9, 0xB9,
410
- 0x8A, 0x9A, 0x8B, 0x9B, 0xAA, 0xBA, 0xAB, 0xBB,
411
- 0xC8, 0xD8, 0xC9, 0xD9, 0xE8, 0xF8, 0xE9, 0xF9,
412
- 0xCA, 0xDA, 0xCB, 0xDB, 0xEA, 0xFA, 0xEB, 0xFB,
413
- 0x8C, 0x9C, 0x8D, 0x9D, 0xAC, 0xBC, 0xAD, 0xBD,
414
- 0x8E, 0x9E, 0x8F, 0x9F, 0xAE, 0xBE, 0xAF, 0xBF,
415
- 0xCC, 0xDC, 0xCD, 0xDD, 0xEC, 0xFC, 0xED, 0xFD,
416
- 0xCE, 0xDE, 0xCF, 0xDF, 0xEE, 0xFE, 0xEF, 0xFF
417
- );
418
-
419
- /**
420
- * Inverse IP mapping helper table.
421
- * Indexing this table with a byte value reverses the bit order.
422
- *
423
- * @var Array
424
- * @access private
425
- */
426
- var $invipmap = array(
427
- 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
428
- 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
429
- 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
430
- 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
431
- 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
432
- 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
433
- 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
434
- 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
435
- 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
436
- 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
437
- 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
438
- 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
439
- 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
440
- 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
441
- 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
442
- 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
443
- 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
444
- 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
445
- 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
446
- 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
447
- 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
448
- 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
449
- 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
450
- 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
451
- 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
452
- 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
453
- 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
454
- 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
455
- 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
456
- 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
457
- 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
458
- 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
459
- );
460
-
461
- /**
462
- * Pre-permuted S-box1
463
- *
464
- * Each box ($sbox1-$sbox8) has been vectorized, then each value pre-permuted using the
465
- * P table: concatenation can then be replaced by exclusive ORs.
466
- *
467
- * @var Array
468
- * @access private
469
- */
470
- var $sbox1 = array(
471
- 0x00808200, 0x00000000, 0x00008000, 0x00808202,
472
- 0x00808002, 0x00008202, 0x00000002, 0x00008000,
473
- 0x00000200, 0x00808200, 0x00808202, 0x00000200,
474
- 0x00800202, 0x00808002, 0x00800000, 0x00000002,
475
- 0x00000202, 0x00800200, 0x00800200, 0x00008200,
476
- 0x00008200, 0x00808000, 0x00808000, 0x00800202,
477
- 0x00008002, 0x00800002, 0x00800002, 0x00008002,
478
- 0x00000000, 0x00000202, 0x00008202, 0x00800000,
479
- 0x00008000, 0x00808202, 0x00000002, 0x00808000,
480
- 0x00808200, 0x00800000, 0x00800000, 0x00000200,
481
- 0x00808002, 0x00008000, 0x00008200, 0x00800002,
482
- 0x00000200, 0x00000002, 0x00800202, 0x00008202,
483
- 0x00808202, 0x00008002, 0x00808000, 0x00800202,
484
- 0x00800002, 0x00000202, 0x00008202, 0x00808200,
485
- 0x00000202, 0x00800200, 0x00800200, 0x00000000,
486
- 0x00008002, 0x00008200, 0x00000000, 0x00808002
487
- );
488
-
489
- /**
490
- * Pre-permuted S-box2
491
- *
492
- * @var Array
493
- * @access private
494
- */
495
- var $sbox2 = array(
496
- 0x40084010, 0x40004000, 0x00004000, 0x00084010,
497
- 0x00080000, 0x00000010, 0x40080010, 0x40004010,
498
- 0x40000010, 0x40084010, 0x40084000, 0x40000000,
499
- 0x40004000, 0x00080000, 0x00000010, 0x40080010,
500
- 0x00084000, 0x00080010, 0x40004010, 0x00000000,
501
- 0x40000000, 0x00004000, 0x00084010, 0x40080000,
502
- 0x00080010, 0x40000010, 0x00000000, 0x00084000,
503
- 0x00004010, 0x40084000, 0x40080000, 0x00004010,
504
- 0x00000000, 0x00084010, 0x40080010, 0x00080000,
505
- 0x40004010, 0x40080000, 0x40084000, 0x00004000,
506
- 0x40080000, 0x40004000, 0x00000010, 0x40084010,
507
- 0x00084010, 0x00000010, 0x00004000, 0x40000000,
508
- 0x00004010, 0x40084000, 0x00080000, 0x40000010,
509
- 0x00080010, 0x40004010, 0x40000010, 0x00080010,
510
- 0x00084000, 0x00000000, 0x40004000, 0x00004010,
511
- 0x40000000, 0x40080010, 0x40084010, 0x00084000
512
- );
513
-
514
- /**
515
- * Pre-permuted S-box3
516
- *
517
- * @var Array
518
- * @access private
519
- */
520
- var $sbox3 = array(
521
- 0x00000104, 0x04010100, 0x00000000, 0x04010004,
522
- 0x04000100, 0x00000000, 0x00010104, 0x04000100,
523
- 0x00010004, 0x04000004, 0x04000004, 0x00010000,
524
- 0x04010104, 0x00010004, 0x04010000, 0x00000104,
525
- 0x04000000, 0x00000004, 0x04010100, 0x00000100,
526
- 0x00010100, 0x04010000, 0x04010004, 0x00010104,
527
- 0x04000104, 0x00010100, 0x00010000, 0x04000104,
528
- 0x00000004, 0x04010104, 0x00000100, 0x04000000,
529
- 0x04010100, 0x04000000, 0x00010004, 0x00000104,
530
- 0x00010000, 0x04010100, 0x04000100, 0x00000000,
531
- 0x00000100, 0x00010004, 0x04010104, 0x04000100,
532
- 0x04000004, 0x00000100, 0x00000000, 0x04010004,
533
- 0x04000104, 0x00010000, 0x04000000, 0x04010104,
534
- 0x00000004, 0x00010104, 0x00010100, 0x04000004,
535
- 0x04010000, 0x04000104, 0x00000104, 0x04010000,
536
- 0x00010104, 0x00000004, 0x04010004, 0x00010100
537
- );
538
-
539
- /**
540
- * Pre-permuted S-box4
541
- *
542
- * @var Array
543
- * @access private
544
- */
545
- var $sbox4 = array(
546
- 0x80401000, 0x80001040, 0x80001040, 0x00000040,
547
- 0x00401040, 0x80400040, 0x80400000, 0x80001000,
548
- 0x00000000, 0x00401000, 0x00401000, 0x80401040,
549
- 0x80000040, 0x00000000, 0x00400040, 0x80400000,
550
- 0x80000000, 0x00001000, 0x00400000, 0x80401000,
551
- 0x00000040, 0x00400000, 0x80001000, 0x00001040,
552
- 0x80400040, 0x80000000, 0x00001040, 0x00400040,
553
- 0x00001000, 0x00401040, 0x80401040, 0x80000040,
554
- 0x00400040, 0x80400000, 0x00401000, 0x80401040,
555
- 0x80000040, 0x00000000, 0x00000000, 0x00401000,
556
- 0x00001040, 0x00400040, 0x80400040, 0x80000000,
557
- 0x80401000, 0x80001040, 0x80001040, 0x00000040,
558
- 0x80401040, 0x80000040, 0x80000000, 0x00001000,
559
- 0x80400000, 0x80001000, 0x00401040, 0x80400040,
560
- 0x80001000, 0x00001040, 0x00400000, 0x80401000,
561
- 0x00000040, 0x00400000, 0x00001000, 0x00401040
562
- );
563
-
564
- /**
565
- * Pre-permuted S-box5
566
- *
567
- * @var Array
568
- * @access private
569
- */
570
- var $sbox5 = array(
571
- 0x00000080, 0x01040080, 0x01040000, 0x21000080,
572
- 0x00040000, 0x00000080, 0x20000000, 0x01040000,
573
- 0x20040080, 0x00040000, 0x01000080, 0x20040080,
574
- 0x21000080, 0x21040000, 0x00040080, 0x20000000,
575
- 0x01000000, 0x20040000, 0x20040000, 0x00000000,
576
- 0x20000080, 0x21040080, 0x21040080, 0x01000080,
577
- 0x21040000, 0x20000080, 0x00000000, 0x21000000,
578
- 0x01040080, 0x01000000, 0x21000000, 0x00040080,
579
- 0x00040000, 0x21000080, 0x00000080, 0x01000000,
580
- 0x20000000, 0x01040000, 0x21000080, 0x20040080,
581
- 0x01000080, 0x20000000, 0x21040000, 0x01040080,
582
- 0x20040080, 0x00000080, 0x01000000, 0x21040000,
583
- 0x21040080, 0x00040080, 0x21000000, 0x21040080,
584
- 0x01040000, 0x00000000, 0x20040000, 0x21000000,
585
- 0x00040080, 0x01000080, 0x20000080, 0x00040000,
586
- 0x00000000, 0x20040000, 0x01040080, 0x20000080
587
- );
588
-
589
- /**
590
- * Pre-permuted S-box6
591
- *
592
- * @var Array
593
- * @access private
594
- */
595
- var $sbox6 = array(
596
- 0x10000008, 0x10200000, 0x00002000, 0x10202008,
597
- 0x10200000, 0x00000008, 0x10202008, 0x00200000,
598
- 0x10002000, 0x00202008, 0x00200000, 0x10000008,
599
- 0x00200008, 0x10002000, 0x10000000, 0x00002008,
600
- 0x00000000, 0x00200008, 0x10002008, 0x00002000,
601
- 0x00202000, 0x10002008, 0x00000008, 0x10200008,
602
- 0x10200008, 0x00000000, 0x00202008, 0x10202000,
603
- 0x00002008, 0x00202000, 0x10202000, 0x10000000,
604
- 0x10002000, 0x00000008, 0x10200008, 0x00202000,
605
- 0x10202008, 0x00200000, 0x00002008, 0x10000008,
606
- 0x00200000, 0x10002000, 0x10000000, 0x00002008,
607
- 0x10000008, 0x10202008, 0x00202000, 0x10200000,
608
- 0x00202008, 0x10202000, 0x00000000, 0x10200008,
609
- 0x00000008, 0x00002000, 0x10200000, 0x00202008,
610
- 0x00002000, 0x00200008, 0x10002008, 0x00000000,
611
- 0x10202000, 0x10000000, 0x00200008, 0x10002008
612
- );
613
-
614
- /**
615
- * Pre-permuted S-box7
616
- *
617
- * @var Array
618
- * @access private
619
- */
620
- var $sbox7 = array(
621
- 0x00100000, 0x02100001, 0x02000401, 0x00000000,
622
- 0x00000400, 0x02000401, 0x00100401, 0x02100400,
623
- 0x02100401, 0x00100000, 0x00000000, 0x02000001,
624
- 0x00000001, 0x02000000, 0x02100001, 0x00000401,
625
- 0x02000400, 0x00100401, 0x00100001, 0x02000400,
626
- 0x02000001, 0x02100000, 0x02100400, 0x00100001,
627
- 0x02100000, 0x00000400, 0x00000401, 0x02100401,
628
- 0x00100400, 0x00000001, 0x02000000, 0x00100400,
629
- 0x02000000, 0x00100400, 0x00100000, 0x02000401,
630
- 0x02000401, 0x02100001, 0x02100001, 0x00000001,
631
- 0x00100001, 0x02000000, 0x02000400, 0x00100000,
632
- 0x02100400, 0x00000401, 0x00100401, 0x02100400,
633
- 0x00000401, 0x02000001, 0x02100401, 0x02100000,
634
- 0x00100400, 0x00000000, 0x00000001, 0x02100401,
635
- 0x00000000, 0x00100401, 0x02100000, 0x00000400,
636
- 0x02000001, 0x02000400, 0x00000400, 0x00100001
637
- );
638
-
639
- /**
640
- * Pre-permuted S-box8
641
- *
642
- * @var Array
643
- * @access private
644
- */
645
- var $sbox8 = array(
646
- 0x08000820, 0x00000800, 0x00020000, 0x08020820,
647
- 0x08000000, 0x08000820, 0x00000020, 0x08000000,
648
- 0x00020020, 0x08020000, 0x08020820, 0x00020800,
649
- 0x08020800, 0x00020820, 0x00000800, 0x00000020,
650
- 0x08020000, 0x08000020, 0x08000800, 0x00000820,
651
- 0x00020800, 0x00020020, 0x08020020, 0x08020800,
652
- 0x00000820, 0x00000000, 0x00000000, 0x08020020,
653
- 0x08000020, 0x08000800, 0x00020820, 0x00020000,
654
- 0x00020820, 0x00020000, 0x08020800, 0x00000800,
655
- 0x00000020, 0x08020020, 0x00000800, 0x00020820,
656
- 0x08000800, 0x00000020, 0x08000020, 0x08020000,
657
- 0x08020020, 0x08000000, 0x00020000, 0x08000820,
658
- 0x00000000, 0x08020820, 0x00020020, 0x08000020,
659
- 0x08020000, 0x08000800, 0x08000820, 0x00000000,
660
- 0x08020820, 0x00020800, 0x00020800, 0x00000820,
661
- 0x00000820, 0x00020020, 0x08000000, 0x08020800
662
- );
663
-
664
- /**
665
- * Sets the key.
666
- *
667
- * Keys can be of any length. DES, itself, uses 64-bit keys (eg. strlen($key) == 8), however, we
668
- * only use the first eight, if $key has more then eight characters in it, and pad $key with the
669
- * null byte if it is less then eight characters long.
670
- *
671
- * DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
672
- *
673
- * If the key is not explicitly set, it'll be assumed to be all zero's.
674
- *
675
- * @see Crypt_Base::setKey()
676
- * @access public
677
- * @param String $key
678
- */
679
- function setKey($key)
680
- {
681
- // We check/cut here only up to max length of the key.
682
- // Key padding to the proper length will be done in _setupKey()
683
- if (strlen($key) > $this->key_size_max) {
684
- $key = substr($key, 0, $this->key_size_max);
685
- }
686
-
687
- // Sets the key
688
- parent::setKey($key);
689
- }
690
-
691
- /**
692
- * Encrypts a block
693
- *
694
- * @see Crypt_Base::_encryptBlock()
695
- * @see Crypt_Base::encrypt()
696
- * @see Crypt_DES::encrypt()
697
- * @access private
698
- * @param String $in
699
- * @return String
700
- */
701
- function _encryptBlock($in)
702
- {
703
- return $this->_processBlock($in, CRYPT_DES_ENCRYPT);
704
- }
705
-
706
- /**
707
- * Decrypts a block
708
- *
709
- * @see Crypt_Base::_decryptBlock()
710
- * @see Crypt_Base::decrypt()
711
- * @see Crypt_DES::decrypt()
712
- * @access private
713
- * @param String $in
714
- * @return String
715
- */
716
- function _decryptBlock($in)
717
- {
718
- return $this->_processBlock($in, CRYPT_DES_DECRYPT);
719
- }
720
-
721
- /**
722
- * Encrypts or decrypts a 64-bit block
723
- *
724
- * $mode should be either CRYPT_DES_ENCRYPT or CRYPT_DES_DECRYPT. See
725
- * {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general
726
- * idea of what this function does.
727
- *
728
- * @see Crypt_DES::_encryptBlock()
729
- * @see Crypt_DES::_decryptBlock()
730
- * @access private
731
- * @param String $block
732
- * @param Integer $mode
733
- * @return String
734
- */
735
- function _processBlock($block, $mode)
736
- {
737
- static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip;
738
- if (!$sbox1) {
739
- $sbox1 = array_map("intval", $this->sbox1);
740
- $sbox2 = array_map("intval", $this->sbox2);
741
- $sbox3 = array_map("intval", $this->sbox3);
742
- $sbox4 = array_map("intval", $this->sbox4);
743
- $sbox5 = array_map("intval", $this->sbox5);
744
- $sbox6 = array_map("intval", $this->sbox6);
745
- $sbox7 = array_map("intval", $this->sbox7);
746
- $sbox8 = array_map("intval", $this->sbox8);
747
- /* Merge $shuffle with $[inv]ipmap */
748
- for ($i = 0; $i < 256; ++$i) {
749
- $shuffleip[] = $this->shuffle[$this->ipmap[$i]];
750
- $shuffleinvip[] = $this->shuffle[$this->invipmap[$i]];
751
- }
752
- }
753
-
754
- $keys = $this->keys[$mode];
755
- $ki = -1;
756
-
757
- // Do the initial IP permutation.
758
- $t = unpack('Nl/Nr', $block);
759
- list($l, $r) = array($t['l'], $t['r']);
760
- $block = ($shuffleip[ $r & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
761
- ($shuffleip[($r >> 8) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
762
- ($shuffleip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
763
- ($shuffleip[($r >> 24) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
764
- ($shuffleip[ $l & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
765
- ($shuffleip[($l >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
766
- ($shuffleip[($l >> 16) & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
767
- ($shuffleip[($l >> 24) & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01");
768
-
769
- // Extract L0 and R0.
770
- $t = unpack('Nl/Nr', $block);
771
- list($l, $r) = array($t['l'], $t['r']);
772
-
773
- for ($des_round = 0; $des_round < $this->des_rounds; ++$des_round) {
774
- // Perform the 16 steps.
775
- for ($i = 0; $i < 16; $i++) {
776
- // start of "the Feistel (F) function" - see the following URL:
777
- // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png
778
- // Merge key schedule.
779
- $b1 = (($r >> 3) & 0x1FFFFFFF) ^ ($r << 29) ^ $keys[++$ki];
780
- $b2 = (($r >> 31) & 0x00000001) ^ ($r << 1) ^ $keys[++$ki];
781
-
782
- // S-box indexing.
783
- $t = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^
784
- $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^
785
- $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^
786
- $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ $l;
787
- // end of "the Feistel (F) function"
788
-
789
- $l = $r;
790
- $r = $t;
791
- }
792
-
793
- // Last step should not permute L & R.
794
- $t = $l;
795
- $l = $r;
796
- $r = $t;
797
- }
798
-
799
- // Perform the inverse IP permutation.
800
- return ($shuffleinvip[($r >> 24) & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
801
- ($shuffleinvip[($l >> 24) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
802
- ($shuffleinvip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
803
- ($shuffleinvip[($l >> 16) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
804
- ($shuffleinvip[($r >> 8) & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
805
- ($shuffleinvip[($l >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
806
- ($shuffleinvip[ $r & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
807
- ($shuffleinvip[ $l & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01");
808
- }
809
-
810
- /**
811
- * Creates the key schedule
812
- *
813
- * @see Crypt_Base::_setupKey()
814
- * @access private
815
- */
816
- function _setupKey()
817
- {
818
- if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->des_rounds === $this->kl['des_rounds']) {
819
- // already expanded
820
- return;
821
- }
822
- $this->kl = array('key' => $this->key, 'des_rounds' => $this->des_rounds);
823
-
824
- static $shifts = array( // number of key bits shifted per round
825
- 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
826
- );
827
-
828
- static $pc1map = array(
829
- 0x00, 0x00, 0x08, 0x08, 0x04, 0x04, 0x0C, 0x0C,
830
- 0x02, 0x02, 0x0A, 0x0A, 0x06, 0x06, 0x0E, 0x0E,
831
- 0x10, 0x10, 0x18, 0x18, 0x14, 0x14, 0x1C, 0x1C,
832
- 0x12, 0x12, 0x1A, 0x1A, 0x16, 0x16, 0x1E, 0x1E,
833
- 0x20, 0x20, 0x28, 0x28, 0x24, 0x24, 0x2C, 0x2C,
834
- 0x22, 0x22, 0x2A, 0x2A, 0x26, 0x26, 0x2E, 0x2E,
835
- 0x30, 0x30, 0x38, 0x38, 0x34, 0x34, 0x3C, 0x3C,
836
- 0x32, 0x32, 0x3A, 0x3A, 0x36, 0x36, 0x3E, 0x3E,
837
- 0x40, 0x40, 0x48, 0x48, 0x44, 0x44, 0x4C, 0x4C,
838
- 0x42, 0x42, 0x4A, 0x4A, 0x46, 0x46, 0x4E, 0x4E,
839
- 0x50, 0x50, 0x58, 0x58, 0x54, 0x54, 0x5C, 0x5C,
840
- 0x52, 0x52, 0x5A, 0x5A, 0x56, 0x56, 0x5E, 0x5E,
841
- 0x60, 0x60, 0x68, 0x68, 0x64, 0x64, 0x6C, 0x6C,
842
- 0x62, 0x62, 0x6A, 0x6A, 0x66, 0x66, 0x6E, 0x6E,
843
- 0x70, 0x70, 0x78, 0x78, 0x74, 0x74, 0x7C, 0x7C,
844
- 0x72, 0x72, 0x7A, 0x7A, 0x76, 0x76, 0x7E, 0x7E,
845
- 0x80, 0x80, 0x88, 0x88, 0x84, 0x84, 0x8C, 0x8C,
846
- 0x82, 0x82, 0x8A, 0x8A, 0x86, 0x86, 0x8E, 0x8E,
847
- 0x90, 0x90, 0x98, 0x98, 0x94, 0x94, 0x9C, 0x9C,
848
- 0x92, 0x92, 0x9A, 0x9A, 0x96, 0x96, 0x9E, 0x9E,
849
- 0xA0, 0xA0, 0xA8, 0xA8, 0xA4, 0xA4, 0xAC, 0xAC,
850
- 0xA2, 0xA2, 0xAA, 0xAA, 0xA6, 0xA6, 0xAE, 0xAE,
851
- 0xB0, 0xB0, 0xB8, 0xB8, 0xB4, 0xB4, 0xBC, 0xBC,
852
- 0xB2, 0xB2, 0xBA, 0xBA, 0xB6, 0xB6, 0xBE, 0xBE,
853
- 0xC0, 0xC0, 0xC8, 0xC8, 0xC4, 0xC4, 0xCC, 0xCC,
854
- 0xC2, 0xC2, 0xCA, 0xCA, 0xC6, 0xC6, 0xCE, 0xCE,
855
- 0xD0, 0xD0, 0xD8, 0xD8, 0xD4, 0xD4, 0xDC, 0xDC,
856
- 0xD2, 0xD2, 0xDA, 0xDA, 0xD6, 0xD6, 0xDE, 0xDE,
857
- 0xE0, 0xE0, 0xE8, 0xE8, 0xE4, 0xE4, 0xEC, 0xEC,
858
- 0xE2, 0xE2, 0xEA, 0xEA, 0xE6, 0xE6, 0xEE, 0xEE,
859
- 0xF0, 0xF0, 0xF8, 0xF8, 0xF4, 0xF4, 0xFC, 0xFC,
860
- 0xF2, 0xF2, 0xFA, 0xFA, 0xF6, 0xF6, 0xFE, 0xFE
861
- );
862
-
863
- // Mapping tables for the PC-2 transformation.
864
- static $pc2mapc1 = array(
865
- 0x00000000, 0x00000400, 0x00200000, 0x00200400,
866
- 0x00000001, 0x00000401, 0x00200001, 0x00200401,
867
- 0x02000000, 0x02000400, 0x02200000, 0x02200400,
868
- 0x02000001, 0x02000401, 0x02200001, 0x02200401
869
- );
870
- static $pc2mapc2 = array(
871
- 0x00000000, 0x00000800, 0x08000000, 0x08000800,
872
- 0x00010000, 0x00010800, 0x08010000, 0x08010800,
873
- 0x00000000, 0x00000800, 0x08000000, 0x08000800,
874
- 0x00010000, 0x00010800, 0x08010000, 0x08010800,
875
- 0x00000100, 0x00000900, 0x08000100, 0x08000900,
876
- 0x00010100, 0x00010900, 0x08010100, 0x08010900,
877
- 0x00000100, 0x00000900, 0x08000100, 0x08000900,
878
- 0x00010100, 0x00010900, 0x08010100, 0x08010900,
879
- 0x00000010, 0x00000810, 0x08000010, 0x08000810,
880
- 0x00010010, 0x00010810, 0x08010010, 0x08010810,
881
- 0x00000010, 0x00000810, 0x08000010, 0x08000810,
882
- 0x00010010, 0x00010810, 0x08010010, 0x08010810,
883
- 0x00000110, 0x00000910, 0x08000110, 0x08000910,
884
- 0x00010110, 0x00010910, 0x08010110, 0x08010910,
885
- 0x00000110, 0x00000910, 0x08000110, 0x08000910,
886
- 0x00010110, 0x00010910, 0x08010110, 0x08010910,
887
- 0x00040000, 0x00040800, 0x08040000, 0x08040800,
888
- 0x00050000, 0x00050800, 0x08050000, 0x08050800,
889
- 0x00040000, 0x00040800, 0x08040000, 0x08040800,
890
- 0x00050000, 0x00050800, 0x08050000, 0x08050800,
891
- 0x00040100, 0x00040900, 0x08040100, 0x08040900,
892
- 0x00050100, 0x00050900, 0x08050100, 0x08050900,
893
- 0x00040100, 0x00040900, 0x08040100, 0x08040900,
894
- 0x00050100, 0x00050900, 0x08050100, 0x08050900,
895
- 0x00040010, 0x00040810, 0x08040010, 0x08040810,
896
- 0x00050010, 0x00050810, 0x08050010, 0x08050810,
897
- 0x00040010, 0x00040810, 0x08040010, 0x08040810,
898
- 0x00050010, 0x00050810, 0x08050010, 0x08050810,
899
- 0x00040110, 0x00040910, 0x08040110, 0x08040910,
900
- 0x00050110, 0x00050910, 0x08050110, 0x08050910,
901
- 0x00040110, 0x00040910, 0x08040110, 0x08040910,
902
- 0x00050110, 0x00050910, 0x08050110, 0x08050910,
903
- 0x01000000, 0x01000800, 0x09000000, 0x09000800,
904
- 0x01010000, 0x01010800, 0x09010000, 0x09010800,
905
- 0x01000000, 0x01000800, 0x09000000, 0x09000800,
906
- 0x01010000, 0x01010800, 0x09010000, 0x09010800,
907
- 0x01000100, 0x01000900, 0x09000100, 0x09000900,
908
- 0x01010100, 0x01010900, 0x09010100, 0x09010900,
909
- 0x01000100, 0x01000900, 0x09000100, 0x09000900,
910
- 0x01010100, 0x01010900, 0x09010100, 0x09010900,
911
- 0x01000010, 0x01000810, 0x09000010, 0x09000810,
912
- 0x01010010, 0x01010810, 0x09010010, 0x09010810,
913
- 0x01000010, 0x01000810, 0x09000010, 0x09000810,
914
- 0x01010010, 0x01010810, 0x09010010, 0x09010810,
915
- 0x01000110, 0x01000910, 0x09000110, 0x09000910,
916
- 0x01010110, 0x01010910, 0x09010110, 0x09010910,
917
- 0x01000110, 0x01000910, 0x09000110, 0x09000910,
918
- 0x01010110, 0x01010910, 0x09010110, 0x09010910,
919
- 0x01040000, 0x01040800, 0x09040000, 0x09040800,
920
- 0x01050000, 0x01050800, 0x09050000, 0x09050800,
921
- 0x01040000, 0x01040800, 0x09040000, 0x09040800,
922
- 0x01050000, 0x01050800, 0x09050000, 0x09050800,
923
- 0x01040100, 0x01040900, 0x09040100, 0x09040900,
924
- 0x01050100, 0x01050900, 0x09050100, 0x09050900,
925
- 0x01040100, 0x01040900, 0x09040100, 0x09040900,
926
- 0x01050100, 0x01050900, 0x09050100, 0x09050900,
927
- 0x01040010, 0x01040810, 0x09040010, 0x09040810,
928
- 0x01050010, 0x01050810, 0x09050010, 0x09050810,
929
- 0x01040010, 0x01040810, 0x09040010, 0x09040810,
930
- 0x01050010, 0x01050810, 0x09050010, 0x09050810,
931
- 0x01040110, 0x01040910, 0x09040110, 0x09040910,
932
- 0x01050110, 0x01050910, 0x09050110, 0x09050910,
933
- 0x01040110, 0x01040910, 0x09040110, 0x09040910,
934
- 0x01050110, 0x01050910, 0x09050110, 0x09050910
935
- );
936
- static $pc2mapc3 = array(
937
- 0x00000000, 0x00000004, 0x00001000, 0x00001004,
938
- 0x00000000, 0x00000004, 0x00001000, 0x00001004,
939
- 0x10000000, 0x10000004, 0x10001000, 0x10001004,
940
- 0x10000000, 0x10000004, 0x10001000, 0x10001004,
941
- 0x00000020, 0x00000024, 0x00001020, 0x00001024,
942
- 0x00000020, 0x00000024, 0x00001020, 0x00001024,
943
- 0x10000020, 0x10000024, 0x10001020, 0x10001024,
944
- 0x10000020, 0x10000024, 0x10001020, 0x10001024,
945
- 0x00080000, 0x00080004, 0x00081000, 0x00081004,
946
- 0x00080000, 0x00080004, 0x00081000, 0x00081004,
947
- 0x10080000, 0x10080004, 0x10081000, 0x10081004,
948
- 0x10080000, 0x10080004, 0x10081000, 0x10081004,
949
- 0x00080020, 0x00080024, 0x00081020, 0x00081024,
950
- 0x00080020, 0x00080024, 0x00081020, 0x00081024,
951
- 0x10080020, 0x10080024, 0x10081020, 0x10081024,
952
- 0x10080020, 0x10080024, 0x10081020, 0x10081024,
953
- 0x20000000, 0x20000004, 0x20001000, 0x20001004,
954
- 0x20000000, 0x20000004, 0x20001000, 0x20001004,
955
- 0x30000000, 0x30000004, 0x30001000, 0x30001004,
956
- 0x30000000, 0x30000004, 0x30001000, 0x30001004,
957
- 0x20000020, 0x20000024, 0x20001020, 0x20001024,
958
- 0x20000020, 0x20000024, 0x20001020, 0x20001024,
959
- 0x30000020, 0x30000024, 0x30001020, 0x30001024,
960
- 0x30000020, 0x30000024, 0x30001020, 0x30001024,
961
- 0x20080000, 0x20080004, 0x20081000, 0x20081004,
962
- 0x20080000, 0x20080004, 0x20081000, 0x20081004,
963
- 0x30080000, 0x30080004, 0x30081000, 0x30081004,
964
- 0x30080000, 0x30080004, 0x30081000, 0x30081004,
965
- 0x20080020, 0x20080024, 0x20081020, 0x20081024,
966
- 0x20080020, 0x20080024, 0x20081020, 0x20081024,
967
- 0x30080020, 0x30080024, 0x30081020, 0x30081024,
968
- 0x30080020, 0x30080024, 0x30081020, 0x30081024,
969
- 0x00000002, 0x00000006, 0x00001002, 0x00001006,
970
- 0x00000002, 0x00000006, 0x00001002, 0x00001006,
971
- 0x10000002, 0x10000006, 0x10001002, 0x10001006,
972
- 0x10000002, 0x10000006, 0x10001002, 0x10001006,
973
- 0x00000022, 0x00000026, 0x00001022, 0x00001026,
974
- 0x00000022, 0x00000026, 0x00001022, 0x00001026,
975
- 0x10000022, 0x10000026, 0x10001022, 0x10001026,
976
- 0x10000022, 0x10000026, 0x10001022, 0x10001026,
977
- 0x00080002, 0x00080006, 0x00081002, 0x00081006,
978
- 0x00080002, 0x00080006, 0x00081002, 0x00081006,
979
- 0x10080002, 0x10080006, 0x10081002, 0x10081006,
980
- 0x10080002, 0x10080006, 0x10081002, 0x10081006,
981
- 0x00080022, 0x00080026, 0x00081022, 0x00081026,
982
- 0x00080022, 0x00080026, 0x00081022, 0x00081026,
983
- 0x10080022, 0x10080026, 0x10081022, 0x10081026,
984
- 0x10080022, 0x10080026, 0x10081022, 0x10081026,
985
- 0x20000002, 0x20000006, 0x20001002, 0x20001006,
986
- 0x20000002, 0x20000006, 0x20001002, 0x20001006,
987
- 0x30000002, 0x30000006, 0x30001002, 0x30001006,
988
- 0x30000002, 0x30000006, 0x30001002, 0x30001006,
989
- 0x20000022, 0x20000026, 0x20001022, 0x20001026,
990
- 0x20000022, 0x20000026, 0x20001022, 0x20001026,
991
- 0x30000022, 0x30000026, 0x30001022, 0x30001026,
992
- 0x30000022, 0x30000026, 0x30001022, 0x30001026,
993
- 0x20080002, 0x20080006, 0x20081002, 0x20081006,
994
- 0x20080002, 0x20080006, 0x20081002, 0x20081006,
995
- 0x30080002, 0x30080006, 0x30081002, 0x30081006,
996
- 0x30080002, 0x30080006, 0x30081002, 0x30081006,
997
- 0x20080022, 0x20080026, 0x20081022, 0x20081026,
998
- 0x20080022, 0x20080026, 0x20081022, 0x20081026,
999
- 0x30080022, 0x30080026, 0x30081022, 0x30081026,
1000
- 0x30080022, 0x30080026, 0x30081022, 0x30081026
1001
- );
1002
- static $pc2mapc4 = array(
1003
- 0x00000000, 0x00100000, 0x00000008, 0x00100008,
1004
- 0x00000200, 0x00100200, 0x00000208, 0x00100208,
1005
- 0x00000000, 0x00100000, 0x00000008, 0x00100008,
1006
- 0x00000200, 0x00100200, 0x00000208, 0x00100208,
1007
- 0x04000000, 0x04100000, 0x04000008, 0x04100008,
1008
- 0x04000200, 0x04100200, 0x04000208, 0x04100208,
1009
- 0x04000000, 0x04100000, 0x04000008, 0x04100008,
1010
- 0x04000200, 0x04100200, 0x04000208, 0x04100208,
1011
- 0x00002000, 0x00102000, 0x00002008, 0x00102008,
1012
- 0x00002200, 0x00102200, 0x00002208, 0x00102208,
1013
- 0x00002000, 0x00102000, 0x00002008, 0x00102008,
1014
- 0x00002200, 0x00102200, 0x00002208, 0x00102208,
1015
- 0x04002000, 0x04102000, 0x04002008, 0x04102008,
1016
- 0x04002200, 0x04102200, 0x04002208, 0x04102208,
1017
- 0x04002000, 0x04102000, 0x04002008, 0x04102008,
1018
- 0x04002200, 0x04102200, 0x04002208, 0x04102208,
1019
- 0x00000000, 0x00100000, 0x00000008, 0x00100008,
1020
- 0x00000200, 0x00100200, 0x00000208, 0x00100208,
1021
- 0x00000000, 0x00100000, 0x00000008, 0x00100008,
1022
- 0x00000200, 0x00100200, 0x00000208, 0x00100208,
1023
- 0x04000000, 0x04100000, 0x04000008, 0x04100008,
1024
- 0x04000200, 0x04100200, 0x04000208, 0x04100208,
1025
- 0x04000000, 0x04100000, 0x04000008, 0x04100008,
1026
- 0x04000200, 0x04100200, 0x04000208, 0x04100208,
1027
- 0x00002000, 0x00102000, 0x00002008, 0x00102008,
1028
- 0x00002200, 0x00102200, 0x00002208, 0x00102208,
1029
- 0x00002000, 0x00102000, 0x00002008, 0x00102008,
1030
- 0x00002200, 0x00102200, 0x00002208, 0x00102208,
1031
- 0x04002000, 0x04102000, 0x04002008, 0x04102008,
1032
- 0x04002200, 0x04102200, 0x04002208, 0x04102208,
1033
- 0x04002000, 0x04102000, 0x04002008, 0x04102008,
1034
- 0x04002200, 0x04102200, 0x04002208, 0x04102208,
1035
- 0x00020000, 0x00120000, 0x00020008, 0x00120008,
1036
- 0x00020200, 0x00120200, 0x00020208, 0x00120208,
1037
- 0x00020000, 0x00120000, 0x00020008, 0x00120008,
1038
- 0x00020200, 0x00120200, 0x00020208, 0x00120208,
1039
- 0x04020000, 0x04120000, 0x04020008, 0x04120008,
1040
- 0x04020200, 0x04120200, 0x04020208, 0x04120208,
1041
- 0x04020000, 0x04120000, 0x04020008, 0x04120008,
1042
- 0x04020200, 0x04120200, 0x04020208, 0x04120208,
1043
- 0x00022000, 0x00122000, 0x00022008, 0x00122008,
1044
- 0x00022200, 0x00122200, 0x00022208, 0x00122208,
1045
- 0x00022000, 0x00122000, 0x00022008, 0x00122008,
1046
- 0x00022200, 0x00122200, 0x00022208, 0x00122208,
1047
- 0x04022000, 0x04122000, 0x04022008, 0x04122008,
1048
- 0x04022200, 0x04122200, 0x04022208, 0x04122208,
1049
- 0x04022000, 0x04122000, 0x04022008, 0x04122008,
1050
- 0x04022200, 0x04122200, 0x04022208, 0x04122208,
1051
- 0x00020000, 0x00120000, 0x00020008, 0x00120008,
1052
- 0x00020200, 0x00120200, 0x00020208, 0x00120208,
1053
- 0x00020000, 0x00120000, 0x00020008, 0x00120008,
1054
- 0x00020200, 0x00120200, 0x00020208, 0x00120208,
1055
- 0x04020000, 0x04120000, 0x04020008, 0x04120008,
1056
- 0x04020200, 0x04120200, 0x04020208, 0x04120208,
1057
- 0x04020000, 0x04120000, 0x04020008, 0x04120008,
1058
- 0x04020200, 0x04120200, 0x04020208, 0x04120208,
1059
- 0x00022000, 0x00122000, 0x00022008, 0x00122008,
1060
- 0x00022200, 0x00122200, 0x00022208, 0x00122208,
1061
- 0x00022000, 0x00122000, 0x00022008, 0x00122008,
1062
- 0x00022200, 0x00122200, 0x00022208, 0x00122208,
1063
- 0x04022000, 0x04122000, 0x04022008, 0x04122008,
1064
- 0x04022200, 0x04122200, 0x04022208, 0x04122208,
1065
- 0x04022000, 0x04122000, 0x04022008, 0x04122008,
1066
- 0x04022200, 0x04122200, 0x04022208, 0x04122208
1067
- );
1068
- static $pc2mapd1 = array(
1069
- 0x00000000, 0x00000001, 0x08000000, 0x08000001,
1070
- 0x00200000, 0x00200001, 0x08200000, 0x08200001,
1071
- 0x00000002, 0x00000003, 0x08000002, 0x08000003,
1072
- 0x00200002, 0x00200003, 0x08200002, 0x08200003
1073
- );
1074
- static $pc2mapd2 = array(
1075
- 0x00000000, 0x00100000, 0x00000800, 0x00100800,
1076
- 0x00000000, 0x00100000, 0x00000800, 0x00100800,
1077
- 0x04000000, 0x04100000, 0x04000800, 0x04100800,
1078
- 0x04000000, 0x04100000, 0x04000800, 0x04100800,
1079
- 0x00000004, 0x00100004, 0x00000804, 0x00100804,
1080
- 0x00000004, 0x00100004, 0x00000804, 0x00100804,
1081
- 0x04000004, 0x04100004, 0x04000804, 0x04100804,
1082
- 0x04000004, 0x04100004, 0x04000804, 0x04100804,
1083
- 0x00000000, 0x00100000, 0x00000800, 0x00100800,
1084
- 0x00000000, 0x00100000, 0x00000800, 0x00100800,
1085
- 0x04000000, 0x04100000, 0x04000800, 0x04100800,
1086
- 0x04000000, 0x04100000, 0x04000800, 0x04100800,
1087
- 0x00000004, 0x00100004, 0x00000804, 0x00100804,
1088
- 0x00000004, 0x00100004, 0x00000804, 0x00100804,
1089
- 0x04000004, 0x04100004, 0x04000804, 0x04100804,
1090
- 0x04000004, 0x04100004, 0x04000804, 0x04100804,
1091
- 0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
1092
- 0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
1093
- 0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
1094
- 0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
1095
- 0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
1096
- 0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
1097
- 0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
1098
- 0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
1099
- 0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
1100
- 0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
1101
- 0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
1102
- 0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
1103
- 0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
1104
- 0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
1105
- 0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
1106
- 0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
1107
- 0x00020000, 0x00120000, 0x00020800, 0x00120800,
1108
- 0x00020000, 0x00120000, 0x00020800, 0x00120800,
1109
- 0x04020000, 0x04120000, 0x04020800, 0x04120800,
1110
- 0x04020000, 0x04120000, 0x04020800, 0x04120800,
1111
- 0x00020004, 0x00120004, 0x00020804, 0x00120804,
1112
- 0x00020004, 0x00120004, 0x00020804, 0x00120804,
1113
- 0x04020004, 0x04120004, 0x04020804, 0x04120804,
1114
- 0x04020004, 0x04120004, 0x04020804, 0x04120804,
1115
- 0x00020000, 0x00120000, 0x00020800, 0x00120800,
1116
- 0x00020000, 0x00120000, 0x00020800, 0x00120800,
1117
- 0x04020000, 0x04120000, 0x04020800, 0x04120800,
1118
- 0x04020000, 0x04120000, 0x04020800, 0x04120800,
1119
- 0x00020004, 0x00120004, 0x00020804, 0x00120804,
1120
- 0x00020004, 0x00120004, 0x00020804, 0x00120804,
1121
- 0x04020004, 0x04120004, 0x04020804, 0x04120804,
1122
- 0x04020004, 0x04120004, 0x04020804, 0x04120804,
1123
- 0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
1124
- 0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
1125
- 0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
1126
- 0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
1127
- 0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
1128
- 0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
1129
- 0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
1130
- 0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
1131
- 0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
1132
- 0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
1133
- 0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
1134
- 0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
1135
- 0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
1136
- 0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
1137
- 0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
1138
- 0x04020204, 0x04120204, 0x04020A04, 0x04120A04
1139
- );
1140
- static $pc2mapd3 = array(
1141
- 0x00000000, 0x00010000, 0x02000000, 0x02010000,
1142
- 0x00000020, 0x00010020, 0x02000020, 0x02010020,
1143
- 0x00040000, 0x00050000, 0x02040000, 0x02050000,
1144
- 0x00040020, 0x00050020, 0x02040020, 0x02050020,
1145
- 0x00002000, 0x00012000, 0x02002000, 0x02012000,
1146
- 0x00002020, 0x00012020, 0x02002020, 0x02012020,
1147
- 0x00042000, 0x00052000, 0x02042000, 0x02052000,
1148
- 0x00042020, 0x00052020, 0x02042020, 0x02052020,
1149
- 0x00000000, 0x00010000, 0x02000000, 0x02010000,
1150
- 0x00000020, 0x00010020, 0x02000020, 0x02010020,
1151
- 0x00040000, 0x00050000, 0x02040000, 0x02050000,
1152
- 0x00040020, 0x00050020, 0x02040020, 0x02050020,
1153
- 0x00002000, 0x00012000, 0x02002000, 0x02012000,
1154
- 0x00002020, 0x00012020, 0x02002020, 0x02012020,
1155
- 0x00042000, 0x00052000, 0x02042000, 0x02052000,
1156
- 0x00042020, 0x00052020, 0x02042020, 0x02052020,
1157
- 0x00000010, 0x00010010, 0x02000010, 0x02010010,
1158
- 0x00000030, 0x00010030, 0x02000030, 0x02010030,
1159
- 0x00040010, 0x00050010, 0x02040010, 0x02050010,
1160
- 0x00040030, 0x00050030, 0x02040030, 0x02050030,
1161
- 0x00002010, 0x00012010, 0x02002010, 0x02012010,
1162
- 0x00002030, 0x00012030, 0x02002030, 0x02012030,
1163
- 0x00042010, 0x00052010, 0x02042010, 0x02052010,
1164
- 0x00042030, 0x00052030, 0x02042030, 0x02052030,
1165
- 0x00000010, 0x00010010, 0x02000010, 0x02010010,
1166
- 0x00000030, 0x00010030, 0x02000030, 0x02010030,
1167
- 0x00040010, 0x00050010, 0x02040010, 0x02050010,
1168
- 0x00040030, 0x00050030, 0x02040030, 0x02050030,
1169
- 0x00002010, 0x00012010, 0x02002010, 0x02012010,
1170
- 0x00002030, 0x00012030, 0x02002030, 0x02012030,
1171
- 0x00042010, 0x00052010, 0x02042010, 0x02052010,
1172
- 0x00042030, 0x00052030, 0x02042030, 0x02052030,
1173
- 0x20000000, 0x20010000, 0x22000000, 0x22010000,
1174
- 0x20000020, 0x20010020, 0x22000020, 0x22010020,
1175
- 0x20040000, 0x20050000, 0x22040000, 0x22050000,
1176
- 0x20040020, 0x20050020, 0x22040020, 0x22050020,
1177
- 0x20002000, 0x20012000, 0x22002000, 0x22012000,
1178
- 0x20002020, 0x20012020, 0x22002020, 0x22012020,
1179
- 0x20042000, 0x20052000, 0x22042000, 0x22052000,
1180
- 0x20042020, 0x20052020, 0x22042020, 0x22052020,
1181
- 0x20000000, 0x20010000, 0x22000000, 0x22010000,
1182
- 0x20000020, 0x20010020, 0x22000020, 0x22010020,
1183
- 0x20040000, 0x20050000, 0x22040000, 0x22050000,
1184
- 0x20040020, 0x20050020, 0x22040020, 0x22050020,
1185
- 0x20002000, 0x20012000, 0x22002000, 0x22012000,
1186
- 0x20002020, 0x20012020, 0x22002020, 0x22012020,
1187
- 0x20042000, 0x20052000, 0x22042000, 0x22052000,
1188
- 0x20042020, 0x20052020, 0x22042020, 0x22052020,
1189
- 0x20000010, 0x20010010, 0x22000010, 0x22010010,
1190
- 0x20000030, 0x20010030, 0x22000030, 0x22010030,
1191
- 0x20040010, 0x20050010, 0x22040010, 0x22050010,
1192
- 0x20040030, 0x20050030, 0x22040030, 0x22050030,
1193
- 0x20002010, 0x20012010, 0x22002010, 0x22012010,
1194
- 0x20002030, 0x20012030, 0x22002030, 0x22012030,
1195
- 0x20042010, 0x20052010, 0x22042010, 0x22052010,
1196
- 0x20042030, 0x20052030, 0x22042030, 0x22052030,
1197
- 0x20000010, 0x20010010, 0x22000010, 0x22010010,
1198
- 0x20000030, 0x20010030, 0x22000030, 0x22010030,
1199
- 0x20040010, 0x20050010, 0x22040010, 0x22050010,
1200
- 0x20040030, 0x20050030, 0x22040030, 0x22050030,
1201
- 0x20002010, 0x20012010, 0x22002010, 0x22012010,
1202
- 0x20002030, 0x20012030, 0x22002030, 0x22012030,
1203
- 0x20042010, 0x20052010, 0x22042010, 0x22052010,
1204
- 0x20042030, 0x20052030, 0x22042030, 0x22052030
1205
- );
1206
- static $pc2mapd4 = array(
1207
- 0x00000000, 0x00000400, 0x01000000, 0x01000400,
1208
- 0x00000000, 0x00000400, 0x01000000, 0x01000400,
1209
- 0x00000100, 0x00000500, 0x01000100, 0x01000500,
1210
- 0x00000100, 0x00000500, 0x01000100, 0x01000500,
1211
- 0x10000000, 0x10000400, 0x11000000, 0x11000400,
1212
- 0x10000000, 0x10000400, 0x11000000, 0x11000400,
1213
- 0x10000100, 0x10000500, 0x11000100, 0x11000500,
1214
- 0x10000100, 0x10000500, 0x11000100, 0x11000500,
1215
- 0x00080000, 0x00080400, 0x01080000, 0x01080400,
1216
- 0x00080000, 0x00080400, 0x01080000, 0x01080400,
1217
- 0x00080100, 0x00080500, 0x01080100, 0x01080500,
1218
- 0x00080100, 0x00080500, 0x01080100, 0x01080500,
1219
- 0x10080000, 0x10080400, 0x11080000, 0x11080400,
1220
- 0x10080000, 0x10080400, 0x11080000, 0x11080400,
1221
- 0x10080100, 0x10080500, 0x11080100, 0x11080500,
1222
- 0x10080100, 0x10080500, 0x11080100, 0x11080500,
1223
- 0x00000008, 0x00000408, 0x01000008, 0x01000408,
1224
- 0x00000008, 0x00000408, 0x01000008, 0x01000408,
1225
- 0x00000108, 0x00000508, 0x01000108, 0x01000508,
1226
- 0x00000108, 0x00000508, 0x01000108, 0x01000508,
1227
- 0x10000008, 0x10000408, 0x11000008, 0x11000408,
1228
- 0x10000008, 0x10000408, 0x11000008, 0x11000408,
1229
- 0x10000108, 0x10000508, 0x11000108, 0x11000508,
1230
- 0x10000108, 0x10000508, 0x11000108, 0x11000508,
1231
- 0x00080008, 0x00080408, 0x01080008, 0x01080408,
1232
- 0x00080008, 0x00080408, 0x01080008, 0x01080408,
1233
- 0x00080108, 0x00080508, 0x01080108, 0x01080508,
1234
- 0x00080108, 0x00080508, 0x01080108, 0x01080508,
1235
- 0x10080008, 0x10080408, 0x11080008, 0x11080408,
1236
- 0x10080008, 0x10080408, 0x11080008, 0x11080408,
1237
- 0x10080108, 0x10080508, 0x11080108, 0x11080508,
1238
- 0x10080108, 0x10080508, 0x11080108, 0x11080508,
1239
- 0x00001000, 0x00001400, 0x01001000, 0x01001400,
1240
- 0x00001000, 0x00001400, 0x01001000, 0x01001400,
1241
- 0x00001100, 0x00001500, 0x01001100, 0x01001500,
1242
- 0x00001100, 0x00001500, 0x01001100, 0x01001500,
1243
- 0x10001000, 0x10001400, 0x11001000, 0x11001400,
1244
- 0x10001000, 0x10001400, 0x11001000, 0x11001400,
1245
- 0x10001100, 0x10001500, 0x11001100, 0x11001500,
1246
- 0x10001100, 0x10001500, 0x11001100, 0x11001500,
1247
- 0x00081000, 0x00081400, 0x01081000, 0x01081400,
1248
- 0x00081000, 0x00081400, 0x01081000, 0x01081400,
1249
- 0x00081100, 0x00081500, 0x01081100, 0x01081500,
1250
- 0x00081100, 0x00081500, 0x01081100, 0x01081500,
1251
- 0x10081000, 0x10081400, 0x11081000, 0x11081400,
1252
- 0x10081000, 0x10081400, 0x11081000, 0x11081400,
1253
- 0x10081100, 0x10081500, 0x11081100, 0x11081500,
1254
- 0x10081100, 0x10081500, 0x11081100, 0x11081500,
1255
- 0x00001008, 0x00001408, 0x01001008, 0x01001408,
1256
- 0x00001008, 0x00001408, 0x01001008, 0x01001408,
1257
- 0x00001108, 0x00001508, 0x01001108, 0x01001508,
1258
- 0x00001108, 0x00001508, 0x01001108, 0x01001508,
1259
- 0x10001008, 0x10001408, 0x11001008, 0x11001408,
1260
- 0x10001008, 0x10001408, 0x11001008, 0x11001408,
1261
- 0x10001108, 0x10001508, 0x11001108, 0x11001508,
1262
- 0x10001108, 0x10001508, 0x11001108, 0x11001508,
1263
- 0x00081008, 0x00081408, 0x01081008, 0x01081408,
1264
- 0x00081008, 0x00081408, 0x01081008, 0x01081408,
1265
- 0x00081108, 0x00081508, 0x01081108, 0x01081508,
1266
- 0x00081108, 0x00081508, 0x01081108, 0x01081508,
1267
- 0x10081008, 0x10081408, 0x11081008, 0x11081408,
1268
- 0x10081008, 0x10081408, 0x11081008, 0x11081408,
1269
- 0x10081108, 0x10081508, 0x11081108, 0x11081508,
1270
- 0x10081108, 0x10081508, 0x11081108, 0x11081508
1271
- );
1272
-
1273
- $keys = array();
1274
- for ($des_round = 0; $des_round < $this->des_rounds; ++$des_round) {
1275
- // pad the key and remove extra characters as appropriate.
1276
- $key = str_pad(substr($this->key, $des_round * 8, 8), 8, "\0");
1277
-
1278
- // Perform the PC/1 transformation and compute C and D.
1279
- $t = unpack('Nl/Nr', $key);
1280
- list($l, $r) = array($t['l'], $t['r']);
1281
- $key = ($this->shuffle[$pc1map[ $r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x00") |
1282
- ($this->shuffle[$pc1map[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x00") |
1283
- ($this->shuffle[$pc1map[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x00") |
1284
- ($this->shuffle[$pc1map[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x00") |
1285
- ($this->shuffle[$pc1map[ $l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x00") |
1286
- ($this->shuffle[$pc1map[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x00") |
1287
- ($this->shuffle[$pc1map[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x00") |
1288
- ($this->shuffle[$pc1map[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x00");
1289
- $key = unpack('Nc/Nd', $key);
1290
- $c = ( $key['c'] >> 4) & 0x0FFFFFFF;
1291
- $d = (($key['d'] >> 4) & 0x0FFFFFF0) | ($key['c'] & 0x0F);
1292
-
1293
- $keys[$des_round] = array(
1294
- CRYPT_DES_ENCRYPT => array(),
1295
- CRYPT_DES_DECRYPT => array_fill(0, 32, 0)
1296
- );
1297
- for ($i = 0, $ki = 31; $i < 16; ++$i, $ki-= 2) {
1298
- $c <<= $shifts[$i];
1299
- $c = ($c | ($c >> 28)) & 0x0FFFFFFF;
1300
- $d <<= $shifts[$i];
1301
- $d = ($d | ($d >> 28)) & 0x0FFFFFFF;
1302
-
1303
- // Perform the PC-2 transformation.
1304
- $cp = $pc2mapc1[ $c >> 24 ] | $pc2mapc2[($c >> 16) & 0xFF] |
1305
- $pc2mapc3[($c >> 8) & 0xFF] | $pc2mapc4[ $c & 0xFF];
1306
- $dp = $pc2mapd1[ $d >> 24 ] | $pc2mapd2[($d >> 16) & 0xFF] |
1307
- $pc2mapd3[($d >> 8) & 0xFF] | $pc2mapd4[ $d & 0xFF];
1308
-
1309
- // Reorder: odd bytes/even bytes. Push the result in key schedule.
1310
- $val1 = ( $cp & 0xFF000000) | (($cp << 8) & 0x00FF0000) |
1311
- (($dp >> 16) & 0x0000FF00) | (($dp >> 8) & 0x000000FF);
1312
- $val2 = (($cp << 8) & 0xFF000000) | (($cp << 16) & 0x00FF0000) |
1313
- (($dp >> 8) & 0x0000FF00) | ( $dp & 0x000000FF);
1314
- $keys[$des_round][CRYPT_DES_ENCRYPT][ ] = $val1;
1315
- $keys[$des_round][CRYPT_DES_DECRYPT][$ki - 1] = $val1;
1316
- $keys[$des_round][CRYPT_DES_ENCRYPT][ ] = $val2;
1317
- $keys[$des_round][CRYPT_DES_DECRYPT][$ki ] = $val2;
1318
- }
1319
- }
1320
-
1321
- switch ($this->des_rounds) {
1322
- case 3: // 3DES keys
1323
- $this->keys = array(
1324
- CRYPT_DES_ENCRYPT => array_merge(
1325
- $keys[0][CRYPT_DES_ENCRYPT],
1326
- $keys[1][CRYPT_DES_DECRYPT],
1327
- $keys[2][CRYPT_DES_ENCRYPT]
1328
- ),
1329
- CRYPT_DES_DECRYPT => array_merge(
1330
- $keys[2][CRYPT_DES_DECRYPT],
1331
- $keys[1][CRYPT_DES_ENCRYPT],
1332
- $keys[0][CRYPT_DES_DECRYPT]
1333
- )
1334
- );
1335
- break;
1336
- // case 1: // DES keys
1337
- default:
1338
- $this->keys = array(
1339
- CRYPT_DES_ENCRYPT => $keys[0][CRYPT_DES_ENCRYPT],
1340
- CRYPT_DES_DECRYPT => $keys[0][CRYPT_DES_DECRYPT]
1341
- );
1342
- }
1343
- }
1344
-
1345
- /**
1346
- * Setup the performance-optimized function for de/encrypt()
1347
- *
1348
- * @see Crypt_Base::_setupInlineCrypt()
1349
- * @access private
1350
- */
1351
- function _setupInlineCrypt()
1352
- {
1353
- $lambda_functions =& Crypt_DES::_getLambdaFunctions();
1354
-
1355
- // Engine configuration for:
1356
- // - DES ($des_rounds == 1) or
1357
- // - 3DES ($des_rounds == 3)
1358
- $des_rounds = $this->des_rounds;
1359
-
1360
- // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
1361
- // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one
1362
- $gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
1363
-
1364
- // Generation of a uniqe hash for our generated code
1365
- switch (true) {
1366
- case $gen_hi_opt_code:
1367
- // For hi-optimized code, we create for each combination of
1368
- // $mode, $des_rounds and $this->key its own encrypt/decrypt function.
1369
- $code_hash = md5(str_pad("Crypt_DES, $des_rounds, {$this->mode}, ", 32, "\0") . $this->key);
1370
- break;
1371
- default:
1372
- // After max 10 hi-optimized functions, we create generic
1373
- // (still very fast.. but not ultra) functions for each $mode/$des_rounds
1374
- // Currently 2 * 5 generic functions will be then max. possible.
1375
- $code_hash = "Crypt_DES, $des_rounds, {$this->mode}";
1376
- }
1377
-
1378
- // Is there a re-usable $lambda_functions in there? If not, we have to create it.
1379
- if (!isset($lambda_functions[$code_hash])) {
1380
- // Init code for both, encrypt and decrypt.
1381
- $init_crypt = 'static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip;
1382
- if (!$sbox1) {
1383
- $sbox1 = array_map("intval", $self->sbox1);
1384
- $sbox2 = array_map("intval", $self->sbox2);
1385
- $sbox3 = array_map("intval", $self->sbox3);
1386
- $sbox4 = array_map("intval", $self->sbox4);
1387
- $sbox5 = array_map("intval", $self->sbox5);
1388
- $sbox6 = array_map("intval", $self->sbox6);
1389
- $sbox7 = array_map("intval", $self->sbox7);
1390
- $sbox8 = array_map("intval", $self->sbox8);'
1391
- /* Merge $shuffle with $[inv]ipmap */ . '
1392
- for ($i = 0; $i < 256; ++$i) {
1393
- $shuffleip[] = $self->shuffle[$self->ipmap[$i]];
1394
- $shuffleinvip[] = $self->shuffle[$self->invipmap[$i]];
1395
- }
1396
- }
1397
- ';
1398
-
1399
- switch (true) {
1400
- case $gen_hi_opt_code:
1401
- // In Hi-optimized code mode, we use our [3]DES key schedule as hardcoded integers.
1402
- // No futher initialisation of the $keys schedule is necessary.
1403
- // That is the extra performance boost.
1404
- $k = array(
1405
- CRYPT_DES_ENCRYPT => $this->keys[CRYPT_DES_ENCRYPT],
1406
- CRYPT_DES_DECRYPT => $this->keys[CRYPT_DES_DECRYPT]
1407
- );
1408
- $init_encrypt = '';
1409
- $init_decrypt = '';
1410
- break;
1411
- default:
1412
- // In generic optimized code mode, we have to use, as the best compromise [currently],
1413
- // our key schedule as $ke/$kd arrays. (with hardcoded indexes...)
1414
- $k = array(
1415
- CRYPT_DES_ENCRYPT => array(),
1416
- CRYPT_DES_DECRYPT => array()
1417
- );
1418
- for ($i = 0, $c = count($this->keys[CRYPT_DES_ENCRYPT]); $i < $c; ++$i) {
1419
- $k[CRYPT_DES_ENCRYPT][$i] = '$ke[' . $i . ']';
1420
- $k[CRYPT_DES_DECRYPT][$i] = '$kd[' . $i . ']';
1421
- }
1422
- $init_encrypt = '$ke = $self->keys[CRYPT_DES_ENCRYPT];';
1423
- $init_decrypt = '$kd = $self->keys[CRYPT_DES_DECRYPT];';
1424
- break;
1425
- }
1426
-
1427
- // Creating code for en- and decryption.
1428
- $crypt_block = array();
1429
- foreach (array(CRYPT_DES_ENCRYPT, CRYPT_DES_DECRYPT) as $c) {
1430
-
1431
- /* Do the initial IP permutation. */
1432
- $crypt_block[$c] = '
1433
- $in = unpack("N*", $in);
1434
- $l = $in[1];
1435
- $r = $in[2];
1436
- $in = unpack("N*",
1437
- ($shuffleip[ $r & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
1438
- ($shuffleip[($r >> 8) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
1439
- ($shuffleip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
1440
- ($shuffleip[($r >> 24) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
1441
- ($shuffleip[ $l & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
1442
- ($shuffleip[($l >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
1443
- ($shuffleip[($l >> 16) & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
1444
- ($shuffleip[($l >> 24) & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01")
1445
- );
1446
- ' . /* Extract L0 and R0 */ '
1447
- $l = $in[1];
1448
- $r = $in[2];
1449
- ';
1450
-
1451
- $l = '$l';
1452
- $r = '$r';
1453
-
1454
- // Perform DES or 3DES.
1455
- for ($ki = -1, $des_round = 0; $des_round < $des_rounds; ++$des_round) {
1456
- // Perform the 16 steps.
1457
- for ($i = 0; $i < 16; ++$i) {
1458
- // start of "the Feistel (F) function" - see the following URL:
1459
- // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png
1460
- // Merge key schedule.
1461
- $crypt_block[$c].= '
1462
- $b1 = ((' . $r . ' >> 3) & 0x1FFFFFFF) ^ (' . $r . ' << 29) ^ ' . $k[$c][++$ki] . ';
1463
- $b2 = ((' . $r . ' >> 31) & 0x00000001) ^ (' . $r . ' << 1) ^ ' . $k[$c][++$ki] . ';' .
1464
- /* S-box indexing. */
1465
- $l . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^
1466
- $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^
1467
- $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^
1468
- $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ ' . $l . ';
1469
- ';
1470
- // end of "the Feistel (F) function"
1471
-
1472
- // swap L & R
1473
- list($l, $r) = array($r, $l);
1474
- }
1475
- list($l, $r) = array($r, $l);
1476
- }
1477
-
1478
- // Perform the inverse IP permutation.
1479
- $crypt_block[$c].= '$in =
1480
- ($shuffleinvip[($l >> 24) & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
1481
- ($shuffleinvip[($r >> 24) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
1482
- ($shuffleinvip[($l >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
1483
- ($shuffleinvip[($r >> 16) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
1484
- ($shuffleinvip[($l >> 8) & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
1485
- ($shuffleinvip[($r >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
1486
- ($shuffleinvip[ $l & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
1487
- ($shuffleinvip[ $r & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01");
1488
- ';
1489
- }
1490
-
1491
- // Creates the inline-crypt function
1492
- $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
1493
- array(
1494
- 'init_crypt' => $init_crypt,
1495
- 'init_encrypt' => $init_encrypt,
1496
- 'init_decrypt' => $init_decrypt,
1497
- 'encrypt_block' => $crypt_block[CRYPT_DES_ENCRYPT],
1498
- 'decrypt_block' => $crypt_block[CRYPT_DES_DECRYPT]
1499
- )
1500
- );
1501
- }
1502
-
1503
- // Set the inline-crypt function as callback in: $this->inline_crypt
1504
- $this->inline_crypt = $lambda_functions[$code_hash];
1505
- }
1506
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Pure-PHP implementation of DES.
5
+ *
6
+ * Uses mcrypt, if available, and an internal implementation, otherwise.
7
+ *
8
+ * PHP versions 4 and 5
9
+ *
10
+ * Useful resources are as follows:
11
+ *
12
+ * - {@link http://en.wikipedia.org/wiki/DES_supplementary_material Wikipedia: DES supplementary material}
13
+ * - {@link http://www.itl.nist.gov/fipspubs/fip46-2.htm FIPS 46-2 - (DES), Data Encryption Standard}
14
+ * - {@link http://www.cs.eku.edu/faculty/styer/460/Encrypt/JS-DES.html JavaScript DES Example}
15
+ *
16
+ * Here's a short example of how to use this library:
17
+ * <code>
18
+ * <?php
19
+ * include 'Crypt/DES.php';
20
+ *
21
+ * $des = new Crypt_DES();
22
+ *
23
+ * $des->setKey('abcdefgh');
24
+ *
25
+ * $size = 10 * 1024;
26
+ * $plaintext = '';
27
+ * for ($i = 0; $i < $size; $i++) {
28
+ * $plaintext.= 'a';
29
+ * }
30
+ *
31
+ * echo $des->decrypt($des->encrypt($plaintext));
32
+ * ?>
33
+ * </code>
34
+ *
35
+ * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
36
+ * of this software and associated documentation files (the "Software"), to deal
37
+ * in the Software without restriction, including without limitation the rights
38
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
39
+ * copies of the Software, and to permit persons to whom the Software is
40
+ * furnished to do so, subject to the following conditions:
41
+ *
42
+ * The above copyright notice and this permission notice shall be included in
43
+ * all copies or substantial portions of the Software.
44
+ *
45
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
46
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
47
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
48
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
49
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
50
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
51
+ * THE SOFTWARE.
52
+ *
53
+ * @category Crypt
54
+ * @package Crypt_DES
55
+ * @author Jim Wigginton <terrafrost@php.net>
56
+ * @copyright 2007 Jim Wigginton
57
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
58
+ * @link http://phpseclib.sourceforge.net
59
+ */
60
+
61
+ /**
62
+ * Include Crypt_Base
63
+ *
64
+ * Base cipher class
65
+ */
66
+ if (!class_exists('Crypt_Base')) {
67
+ include_once 'Base.php';
68
+ }
69
+
70
+ /**#@+
71
+ * @access private
72
+ * @see Crypt_DES::_setupKey()
73
+ * @see Crypt_DES::_processBlock()
74
+ */
75
+ /**
76
+ * Contains $keys[CRYPT_DES_ENCRYPT]
77
+ */
78
+ define('CRYPT_DES_ENCRYPT', 0);
79
+ /**
80
+ * Contains $keys[CRYPT_DES_DECRYPT]
81
+ */
82
+ define('CRYPT_DES_DECRYPT', 1);
83
+ /**#@-*/
84
+
85
+ /**#@+
86
+ * @access public
87
+ * @see Crypt_DES::encrypt()
88
+ * @see Crypt_DES::decrypt()
89
+ */
90
+ /**
91
+ * Encrypt / decrypt using the Counter mode.
92
+ *
93
+ * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
94
+ *
95
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
96
+ */
97
+ define('CRYPT_DES_MODE_CTR', CRYPT_MODE_CTR);
98
+ /**
99
+ * Encrypt / decrypt using the Electronic Code Book mode.
100
+ *
101
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
102
+ */
103
+ define('CRYPT_DES_MODE_ECB', CRYPT_MODE_ECB);
104
+ /**
105
+ * Encrypt / decrypt using the Code Book Chaining mode.
106
+ *
107
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
108
+ */
109
+ define('CRYPT_DES_MODE_CBC', CRYPT_MODE_CBC);
110
+ /**
111
+ * Encrypt / decrypt using the Cipher Feedback mode.
112
+ *
113
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
114
+ */
115
+ define('CRYPT_DES_MODE_CFB', CRYPT_MODE_CFB);
116
+ /**
117
+ * Encrypt / decrypt using the Cipher Feedback mode.
118
+ *
119
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
120
+ */
121
+ define('CRYPT_DES_MODE_OFB', CRYPT_MODE_OFB);
122
+ /**#@-*/
123
+
124
+ /**
125
+ * Pure-PHP implementation of DES.
126
+ *
127
+ * @package Crypt_DES
128
+ * @author Jim Wigginton <terrafrost@php.net>
129
+ * @access public
130
+ */
131
+ class Crypt_DES extends Crypt_Base
132
+ {
133
+ /**
134
+ * Block Length of the cipher
135
+ *
136
+ * @see Crypt_Base::block_size
137
+ * @var Integer
138
+ * @access private
139
+ */
140
+ var $block_size = 8;
141
+
142
+ /**
143
+ * The Key
144
+ *
145
+ * @see Crypt_Base::key
146
+ * @see setKey()
147
+ * @var String
148
+ * @access private
149
+ */
150
+ var $key = "\0\0\0\0\0\0\0\0";
151
+
152
+ /**
153
+ * The default password key_size used by setPassword()
154
+ *
155
+ * @see Crypt_Base::password_key_size
156
+ * @see Crypt_Base::setPassword()
157
+ * @var Integer
158
+ * @access private
159
+ */
160
+ var $password_key_size = 8;
161
+
162
+ /**
163
+ * The namespace used by the cipher for its constants.
164
+ *
165
+ * @see Crypt_Base::const_namespace
166
+ * @var String
167
+ * @access private
168
+ */
169
+ var $const_namespace = 'DES';
170
+
171
+ /**
172
+ * The mcrypt specific name of the cipher
173
+ *
174
+ * @see Crypt_Base::cipher_name_mcrypt
175
+ * @var String
176
+ * @access private
177
+ */
178
+ var $cipher_name_mcrypt = 'des';
179
+
180
+ /**
181
+ * The OpenSSL names of the cipher / modes
182
+ *
183
+ * @see Crypt_Base::openssl_mode_names
184
+ * @var Array
185
+ * @access private
186
+ */
187
+ var $openssl_mode_names = array(
188
+ CRYPT_MODE_ECB => 'des-ecb',
189
+ CRYPT_MODE_CBC => 'des-cbc',
190
+ CRYPT_MODE_CFB => 'des-cfb',
191
+ CRYPT_MODE_OFB => 'des-ofb'
192
+ // CRYPT_MODE_CTR is undefined for DES
193
+ );
194
+
195
+ /**
196
+ * Optimizing value while CFB-encrypting
197
+ *
198
+ * @see Crypt_Base::cfb_init_len
199
+ * @var Integer
200
+ * @access private
201
+ */
202
+ var $cfb_init_len = 500;
203
+
204
+ /**
205
+ * Switch for DES/3DES encryption
206
+ *
207
+ * Used only if $engine == CRYPT_DES_MODE_INTERNAL
208
+ *
209
+ * @see Crypt_DES::_setupKey()
210
+ * @see Crypt_DES::_processBlock()
211
+ * @var Integer
212
+ * @access private
213
+ */
214
+ var $des_rounds = 1;
215
+
216
+ /**
217
+ * max possible size of $key
218
+ *
219
+ * @see Crypt_DES::setKey()
220
+ * @var String
221
+ * @access private
222
+ */
223
+ var $key_size_max = 8;
224
+
225
+ /**
226
+ * The Key Schedule
227
+ *
228
+ * @see Crypt_DES::_setupKey()
229
+ * @var Array
230
+ * @access private
231
+ */
232
+ var $keys;
233
+
234
+ /**
235
+ * Shuffle table.
236
+ *
237
+ * For each byte value index, the entry holds an 8-byte string
238
+ * with each byte containing all bits in the same state as the
239
+ * corresponding bit in the index value.
240
+ *
241
+ * @see Crypt_DES::_processBlock()
242
+ * @see Crypt_DES::_setupKey()
243
+ * @var Array
244
+ * @access private
245
+ */
246
+ var $shuffle = array(
247
+ "\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\xFF",
248
+ "\x00\x00\x00\x00\x00\x00\xFF\x00", "\x00\x00\x00\x00\x00\x00\xFF\xFF",
249
+ "\x00\x00\x00\x00\x00\xFF\x00\x00", "\x00\x00\x00\x00\x00\xFF\x00\xFF",
250
+ "\x00\x00\x00\x00\x00\xFF\xFF\x00", "\x00\x00\x00\x00\x00\xFF\xFF\xFF",
251
+ "\x00\x00\x00\x00\xFF\x00\x00\x00", "\x00\x00\x00\x00\xFF\x00\x00\xFF",
252
+ "\x00\x00\x00\x00\xFF\x00\xFF\x00", "\x00\x00\x00\x00\xFF\x00\xFF\xFF",
253
+ "\x00\x00\x00\x00\xFF\xFF\x00\x00", "\x00\x00\x00\x00\xFF\xFF\x00\xFF",
254
+ "\x00\x00\x00\x00\xFF\xFF\xFF\x00", "\x00\x00\x00\x00\xFF\xFF\xFF\xFF",
255
+ "\x00\x00\x00\xFF\x00\x00\x00\x00", "\x00\x00\x00\xFF\x00\x00\x00\xFF",
256
+ "\x00\x00\x00\xFF\x00\x00\xFF\x00", "\x00\x00\x00\xFF\x00\x00\xFF\xFF",
257
+ "\x00\x00\x00\xFF\x00\xFF\x00\x00", "\x00\x00\x00\xFF\x00\xFF\x00\xFF",
258
+ "\x00\x00\x00\xFF\x00\xFF\xFF\x00", "\x00\x00\x00\xFF\x00\xFF\xFF\xFF",
259
+ "\x00\x00\x00\xFF\xFF\x00\x00\x00", "\x00\x00\x00\xFF\xFF\x00\x00\xFF",
260
+ "\x00\x00\x00\xFF\xFF\x00\xFF\x00", "\x00\x00\x00\xFF\xFF\x00\xFF\xFF",
261
+ "\x00\x00\x00\xFF\xFF\xFF\x00\x00", "\x00\x00\x00\xFF\xFF\xFF\x00\xFF",
262
+ "\x00\x00\x00\xFF\xFF\xFF\xFF\x00", "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF",
263
+ "\x00\x00\xFF\x00\x00\x00\x00\x00", "\x00\x00\xFF\x00\x00\x00\x00\xFF",
264
+ "\x00\x00\xFF\x00\x00\x00\xFF\x00", "\x00\x00\xFF\x00\x00\x00\xFF\xFF",
265
+ "\x00\x00\xFF\x00\x00\xFF\x00\x00", "\x00\x00\xFF\x00\x00\xFF\x00\xFF",
266
+ "\x00\x00\xFF\x00\x00\xFF\xFF\x00", "\x00\x00\xFF\x00\x00\xFF\xFF\xFF",
267
+ "\x00\x00\xFF\x00\xFF\x00\x00\x00", "\x00\x00\xFF\x00\xFF\x00\x00\xFF",
268
+ "\x00\x00\xFF\x00\xFF\x00\xFF\x00", "\x00\x00\xFF\x00\xFF\x00\xFF\xFF",
269
+ "\x00\x00\xFF\x00\xFF\xFF\x00\x00", "\x00\x00\xFF\x00\xFF\xFF\x00\xFF",
270
+ "\x00\x00\xFF\x00\xFF\xFF\xFF\x00", "\x00\x00\xFF\x00\xFF\xFF\xFF\xFF",
271
+ "\x00\x00\xFF\xFF\x00\x00\x00\x00", "\x00\x00\xFF\xFF\x00\x00\x00\xFF",
272
+ "\x00\x00\xFF\xFF\x00\x00\xFF\x00", "\x00\x00\xFF\xFF\x00\x00\xFF\xFF",
273
+ "\x00\x00\xFF\xFF\x00\xFF\x00\x00", "\x00\x00\xFF\xFF\x00\xFF\x00\xFF",
274
+ "\x00\x00\xFF\xFF\x00\xFF\xFF\x00", "\x00\x00\xFF\xFF\x00\xFF\xFF\xFF",
275
+ "\x00\x00\xFF\xFF\xFF\x00\x00\x00", "\x00\x00\xFF\xFF\xFF\x00\x00\xFF",
276
+ "\x00\x00\xFF\xFF\xFF\x00\xFF\x00", "\x00\x00\xFF\xFF\xFF\x00\xFF\xFF",
277
+ "\x00\x00\xFF\xFF\xFF\xFF\x00\x00", "\x00\x00\xFF\xFF\xFF\xFF\x00\xFF",
278
+ "\x00\x00\xFF\xFF\xFF\xFF\xFF\x00", "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF",
279
+ "\x00\xFF\x00\x00\x00\x00\x00\x00", "\x00\xFF\x00\x00\x00\x00\x00\xFF",
280
+ "\x00\xFF\x00\x00\x00\x00\xFF\x00", "\x00\xFF\x00\x00\x00\x00\xFF\xFF",
281
+ "\x00\xFF\x00\x00\x00\xFF\x00\x00", "\x00\xFF\x00\x00\x00\xFF\x00\xFF",
282
+ "\x00\xFF\x00\x00\x00\xFF\xFF\x00", "\x00\xFF\x00\x00\x00\xFF\xFF\xFF",
283
+ "\x00\xFF\x00\x00\xFF\x00\x00\x00", "\x00\xFF\x00\x00\xFF\x00\x00\xFF",
284
+ "\x00\xFF\x00\x00\xFF\x00\xFF\x00", "\x00\xFF\x00\x00\xFF\x00\xFF\xFF",
285
+ "\x00\xFF\x00\x00\xFF\xFF\x00\x00", "\x00\xFF\x00\x00\xFF\xFF\x00\xFF",
286
+ "\x00\xFF\x00\x00\xFF\xFF\xFF\x00", "\x00\xFF\x00\x00\xFF\xFF\xFF\xFF",
287
+ "\x00\xFF\x00\xFF\x00\x00\x00\x00", "\x00\xFF\x00\xFF\x00\x00\x00\xFF",
288
+ "\x00\xFF\x00\xFF\x00\x00\xFF\x00", "\x00\xFF\x00\xFF\x00\x00\xFF\xFF",
289
+ "\x00\xFF\x00\xFF\x00\xFF\x00\x00", "\x00\xFF\x00\xFF\x00\xFF\x00\xFF",
290
+ "\x00\xFF\x00\xFF\x00\xFF\xFF\x00", "\x00\xFF\x00\xFF\x00\xFF\xFF\xFF",
291
+ "\x00\xFF\x00\xFF\xFF\x00\x00\x00", "\x00\xFF\x00\xFF\xFF\x00\x00\xFF",
292
+ "\x00\xFF\x00\xFF\xFF\x00\xFF\x00", "\x00\xFF\x00\xFF\xFF\x00\xFF\xFF",
293
+ "\x00\xFF\x00\xFF\xFF\xFF\x00\x00", "\x00\xFF\x00\xFF\xFF\xFF\x00\xFF",
294
+ "\x00\xFF\x00\xFF\xFF\xFF\xFF\x00", "\x00\xFF\x00\xFF\xFF\xFF\xFF\xFF",
295
+ "\x00\xFF\xFF\x00\x00\x00\x00\x00", "\x00\xFF\xFF\x00\x00\x00\x00\xFF",
296
+ "\x00\xFF\xFF\x00\x00\x00\xFF\x00", "\x00\xFF\xFF\x00\x00\x00\xFF\xFF",
297
+ "\x00\xFF\xFF\x00\x00\xFF\x00\x00", "\x00\xFF\xFF\x00\x00\xFF\x00\xFF",
298
+ "\x00\xFF\xFF\x00\x00\xFF\xFF\x00", "\x00\xFF\xFF\x00\x00\xFF\xFF\xFF",
299
+ "\x00\xFF\xFF\x00\xFF\x00\x00\x00", "\x00\xFF\xFF\x00\xFF\x00\x00\xFF",
300
+ "\x00\xFF\xFF\x00\xFF\x00\xFF\x00", "\x00\xFF\xFF\x00\xFF\x00\xFF\xFF",
301
+ "\x00\xFF\xFF\x00\xFF\xFF\x00\x00", "\x00\xFF\xFF\x00\xFF\xFF\x00\xFF",
302
+ "\x00\xFF\xFF\x00\xFF\xFF\xFF\x00", "\x00\xFF\xFF\x00\xFF\xFF\xFF\xFF",
303
+ "\x00\xFF\xFF\xFF\x00\x00\x00\x00", "\x00\xFF\xFF\xFF\x00\x00\x00\xFF",
304
+ "\x00\xFF\xFF\xFF\x00\x00\xFF\x00", "\x00\xFF\xFF\xFF\x00\x00\xFF\xFF",
305
+ "\x00\xFF\xFF\xFF\x00\xFF\x00\x00", "\x00\xFF\xFF\xFF\x00\xFF\x00\xFF",
306
+ "\x00\xFF\xFF\xFF\x00\xFF\xFF\x00", "\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF",
307
+ "\x00\xFF\xFF\xFF\xFF\x00\x00\x00", "\x00\xFF\xFF\xFF\xFF\x00\x00\xFF",
308
+ "\x00\xFF\xFF\xFF\xFF\x00\xFF\x00", "\x00\xFF\xFF\xFF\xFF\x00\xFF\xFF",
309
+ "\x00\xFF\xFF\xFF\xFF\xFF\x00\x00", "\x00\xFF\xFF\xFF\xFF\xFF\x00\xFF",
310
+ "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
311
+ "\xFF\x00\x00\x00\x00\x00\x00\x00", "\xFF\x00\x00\x00\x00\x00\x00\xFF",
312
+ "\xFF\x00\x00\x00\x00\x00\xFF\x00", "\xFF\x00\x00\x00\x00\x00\xFF\xFF",
313
+ "\xFF\x00\x00\x00\x00\xFF\x00\x00", "\xFF\x00\x00\x00\x00\xFF\x00\xFF",
314
+ "\xFF\x00\x00\x00\x00\xFF\xFF\x00", "\xFF\x00\x00\x00\x00\xFF\xFF\xFF",
315
+ "\xFF\x00\x00\x00\xFF\x00\x00\x00", "\xFF\x00\x00\x00\xFF\x00\x00\xFF",
316
+ "\xFF\x00\x00\x00\xFF\x00\xFF\x00", "\xFF\x00\x00\x00\xFF\x00\xFF\xFF",
317
+ "\xFF\x00\x00\x00\xFF\xFF\x00\x00", "\xFF\x00\x00\x00\xFF\xFF\x00\xFF",
318
+ "\xFF\x00\x00\x00\xFF\xFF\xFF\x00", "\xFF\x00\x00\x00\xFF\xFF\xFF\xFF",
319
+ "\xFF\x00\x00\xFF\x00\x00\x00\x00", "\xFF\x00\x00\xFF\x00\x00\x00\xFF",
320
+ "\xFF\x00\x00\xFF\x00\x00\xFF\x00", "\xFF\x00\x00\xFF\x00\x00\xFF\xFF",
321
+ "\xFF\x00\x00\xFF\x00\xFF\x00\x00", "\xFF\x00\x00\xFF\x00\xFF\x00\xFF",
322
+ "\xFF\x00\x00\xFF\x00\xFF\xFF\x00", "\xFF\x00\x00\xFF\x00\xFF\xFF\xFF",
323
+ "\xFF\x00\x00\xFF\xFF\x00\x00\x00", "\xFF\x00\x00\xFF\xFF\x00\x00\xFF",
324
+ "\xFF\x00\x00\xFF\xFF\x00\xFF\x00", "\xFF\x00\x00\xFF\xFF\x00\xFF\xFF",
325
+ "\xFF\x00\x00\xFF\xFF\xFF\x00\x00", "\xFF\x00\x00\xFF\xFF\xFF\x00\xFF",
326
+ "\xFF\x00\x00\xFF\xFF\xFF\xFF\x00", "\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF",
327
+ "\xFF\x00\xFF\x00\x00\x00\x00\x00", "\xFF\x00\xFF\x00\x00\x00\x00\xFF",
328
+ "\xFF\x00\xFF\x00\x00\x00\xFF\x00", "\xFF\x00\xFF\x00\x00\x00\xFF\xFF",
329
+ "\xFF\x00\xFF\x00\x00\xFF\x00\x00", "\xFF\x00\xFF\x00\x00\xFF\x00\xFF",
330
+ "\xFF\x00\xFF\x00\x00\xFF\xFF\x00", "\xFF\x00\xFF\x00\x00\xFF\xFF\xFF",
331
+ "\xFF\x00\xFF\x00\xFF\x00\x00\x00", "\xFF\x00\xFF\x00\xFF\x00\x00\xFF",
332
+ "\xFF\x00\xFF\x00\xFF\x00\xFF\x00", "\xFF\x00\xFF\x00\xFF\x00\xFF\xFF",
333
+ "\xFF\x00\xFF\x00\xFF\xFF\x00\x00", "\xFF\x00\xFF\x00\xFF\xFF\x00\xFF",
334
+ "\xFF\x00\xFF\x00\xFF\xFF\xFF\x00", "\xFF\x00\xFF\x00\xFF\xFF\xFF\xFF",
335
+ "\xFF\x00\xFF\xFF\x00\x00\x00\x00", "\xFF\x00\xFF\xFF\x00\x00\x00\xFF",
336
+ "\xFF\x00\xFF\xFF\x00\x00\xFF\x00", "\xFF\x00\xFF\xFF\x00\x00\xFF\xFF",
337
+ "\xFF\x00\xFF\xFF\x00\xFF\x00\x00", "\xFF\x00\xFF\xFF\x00\xFF\x00\xFF",
338
+ "\xFF\x00\xFF\xFF\x00\xFF\xFF\x00", "\xFF\x00\xFF\xFF\x00\xFF\xFF\xFF",
339
+ "\xFF\x00\xFF\xFF\xFF\x00\x00\x00", "\xFF\x00\xFF\xFF\xFF\x00\x00\xFF",
340
+ "\xFF\x00\xFF\xFF\xFF\x00\xFF\x00", "\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF",
341
+ "\xFF\x00\xFF\xFF\xFF\xFF\x00\x00", "\xFF\x00\xFF\xFF\xFF\xFF\x00\xFF",
342
+ "\xFF\x00\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF",
343
+ "\xFF\xFF\x00\x00\x00\x00\x00\x00", "\xFF\xFF\x00\x00\x00\x00\x00\xFF",
344
+ "\xFF\xFF\x00\x00\x00\x00\xFF\x00", "\xFF\xFF\x00\x00\x00\x00\xFF\xFF",
345
+ "\xFF\xFF\x00\x00\x00\xFF\x00\x00", "\xFF\xFF\x00\x00\x00\xFF\x00\xFF",
346
+ "\xFF\xFF\x00\x00\x00\xFF\xFF\x00", "\xFF\xFF\x00\x00\x00\xFF\xFF\xFF",
347
+ "\xFF\xFF\x00\x00\xFF\x00\x00\x00", "\xFF\xFF\x00\x00\xFF\x00\x00\xFF",
348
+ "\xFF\xFF\x00\x00\xFF\x00\xFF\x00", "\xFF\xFF\x00\x00\xFF\x00\xFF\xFF",
349
+ "\xFF\xFF\x00\x00\xFF\xFF\x00\x00", "\xFF\xFF\x00\x00\xFF\xFF\x00\xFF",
350
+ "\xFF\xFF\x00\x00\xFF\xFF\xFF\x00", "\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF",
351
+ "\xFF\xFF\x00\xFF\x00\x00\x00\x00", "\xFF\xFF\x00\xFF\x00\x00\x00\xFF",
352
+ "\xFF\xFF\x00\xFF\x00\x00\xFF\x00", "\xFF\xFF\x00\xFF\x00\x00\xFF\xFF",
353
+ "\xFF\xFF\x00\xFF\x00\xFF\x00\x00", "\xFF\xFF\x00\xFF\x00\xFF\x00\xFF",
354
+ "\xFF\xFF\x00\xFF\x00\xFF\xFF\x00", "\xFF\xFF\x00\xFF\x00\xFF\xFF\xFF",
355
+ "\xFF\xFF\x00\xFF\xFF\x00\x00\x00", "\xFF\xFF\x00\xFF\xFF\x00\x00\xFF",
356
+ "\xFF\xFF\x00\xFF\xFF\x00\xFF\x00", "\xFF\xFF\x00\xFF\xFF\x00\xFF\xFF",
357
+ "\xFF\xFF\x00\xFF\xFF\xFF\x00\x00", "\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF",
358
+ "\xFF\xFF\x00\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF",
359
+ "\xFF\xFF\xFF\x00\x00\x00\x00\x00", "\xFF\xFF\xFF\x00\x00\x00\x00\xFF",
360
+ "\xFF\xFF\xFF\x00\x00\x00\xFF\x00", "\xFF\xFF\xFF\x00\x00\x00\xFF\xFF",
361
+ "\xFF\xFF\xFF\x00\x00\xFF\x00\x00", "\xFF\xFF\xFF\x00\x00\xFF\x00\xFF",
362
+ "\xFF\xFF\xFF\x00\x00\xFF\xFF\x00", "\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF",
363
+ "\xFF\xFF\xFF\x00\xFF\x00\x00\x00", "\xFF\xFF\xFF\x00\xFF\x00\x00\xFF",
364
+ "\xFF\xFF\xFF\x00\xFF\x00\xFF\x00", "\xFF\xFF\xFF\x00\xFF\x00\xFF\xFF",
365
+ "\xFF\xFF\xFF\x00\xFF\xFF\x00\x00", "\xFF\xFF\xFF\x00\xFF\xFF\x00\xFF",
366
+ "\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF",
367
+ "\xFF\xFF\xFF\xFF\x00\x00\x00\x00", "\xFF\xFF\xFF\xFF\x00\x00\x00\xFF",
368
+ "\xFF\xFF\xFF\xFF\x00\x00\xFF\x00", "\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF",
369
+ "\xFF\xFF\xFF\xFF\x00\xFF\x00\x00", "\xFF\xFF\xFF\xFF\x00\xFF\x00\xFF",
370
+ "\xFF\xFF\xFF\xFF\x00\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF",
371
+ "\xFF\xFF\xFF\xFF\xFF\x00\x00\x00", "\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF",
372
+ "\xFF\xFF\xFF\xFF\xFF\x00\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF",
373
+ "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF",
374
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
375
+ );
376
+
377
+ /**
378
+ * IP mapping helper table.
379
+ *
380
+ * Indexing this table with each source byte performs the initial bit permutation.
381
+ *
382
+ * @var Array
383
+ * @access private
384
+ */
385
+ var $ipmap = array(
386
+ 0x00, 0x10, 0x01, 0x11, 0x20, 0x30, 0x21, 0x31,
387
+ 0x02, 0x12, 0x03, 0x13, 0x22, 0x32, 0x23, 0x33,
388
+ 0x40, 0x50, 0x41, 0x51, 0x60, 0x70, 0x61, 0x71,
389
+ 0x42, 0x52, 0x43, 0x53, 0x62, 0x72, 0x63, 0x73,
390
+ 0x04, 0x14, 0x05, 0x15, 0x24, 0x34, 0x25, 0x35,
391
+ 0x06, 0x16, 0x07, 0x17, 0x26, 0x36, 0x27, 0x37,
392
+ 0x44, 0x54, 0x45, 0x55, 0x64, 0x74, 0x65, 0x75,
393
+ 0x46, 0x56, 0x47, 0x57, 0x66, 0x76, 0x67, 0x77,
394
+ 0x80, 0x90, 0x81, 0x91, 0xA0, 0xB0, 0xA1, 0xB1,
395
+ 0x82, 0x92, 0x83, 0x93, 0xA2, 0xB2, 0xA3, 0xB3,
396
+ 0xC0, 0xD0, 0xC1, 0xD1, 0xE0, 0xF0, 0xE1, 0xF1,
397
+ 0xC2, 0xD2, 0xC3, 0xD3, 0xE2, 0xF2, 0xE3, 0xF3,
398
+ 0x84, 0x94, 0x85, 0x95, 0xA4, 0xB4, 0xA5, 0xB5,
399
+ 0x86, 0x96, 0x87, 0x97, 0xA6, 0xB6, 0xA7, 0xB7,
400
+ 0xC4, 0xD4, 0xC5, 0xD5, 0xE4, 0xF4, 0xE5, 0xF5,
401
+ 0xC6, 0xD6, 0xC7, 0xD7, 0xE6, 0xF6, 0xE7, 0xF7,
402
+ 0x08, 0x18, 0x09, 0x19, 0x28, 0x38, 0x29, 0x39,
403
+ 0x0A, 0x1A, 0x0B, 0x1B, 0x2A, 0x3A, 0x2B, 0x3B,
404
+ 0x48, 0x58, 0x49, 0x59, 0x68, 0x78, 0x69, 0x79,
405
+ 0x4A, 0x5A, 0x4B, 0x5B, 0x6A, 0x7A, 0x6B, 0x7B,
406
+ 0x0C, 0x1C, 0x0D, 0x1D, 0x2C, 0x3C, 0x2D, 0x3D,
407
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
408
+ 0x4C, 0x5C, 0x4D, 0x5D, 0x6C, 0x7C, 0x6D, 0x7D,
409
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
410
+ 0x88, 0x98, 0x89, 0x99, 0xA8, 0xB8, 0xA9, 0xB9,
411
+ 0x8A, 0x9A, 0x8B, 0x9B, 0xAA, 0xBA, 0xAB, 0xBB,
412
+ 0xC8, 0xD8, 0xC9, 0xD9, 0xE8, 0xF8, 0xE9, 0xF9,
413
+ 0xCA, 0xDA, 0xCB, 0xDB, 0xEA, 0xFA, 0xEB, 0xFB,
414
+ 0x8C, 0x9C, 0x8D, 0x9D, 0xAC, 0xBC, 0xAD, 0xBD,
415
+ 0x8E, 0x9E, 0x8F, 0x9F, 0xAE, 0xBE, 0xAF, 0xBF,
416
+ 0xCC, 0xDC, 0xCD, 0xDD, 0xEC, 0xFC, 0xED, 0xFD,
417
+ 0xCE, 0xDE, 0xCF, 0xDF, 0xEE, 0xFE, 0xEF, 0xFF
418
+ );
419
+
420
+ /**
421
+ * Inverse IP mapping helper table.
422
+ * Indexing this table with a byte value reverses the bit order.
423
+ *
424
+ * @var Array
425
+ * @access private
426
+ */
427
+ var $invipmap = array(
428
+ 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
429
+ 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
430
+ 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
431
+ 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
432
+ 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
433
+ 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
434
+ 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
435
+ 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
436
+ 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
437
+ 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
438
+ 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
439
+ 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
440
+ 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
441
+ 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
442
+ 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
443
+ 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
444
+ 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
445
+ 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
446
+ 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
447
+ 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
448
+ 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
449
+ 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
450
+ 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
451
+ 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
452
+ 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
453
+ 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
454
+ 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
455
+ 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
456
+ 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
457
+ 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
458
+ 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
459
+ 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
460
+ );
461
+
462
+ /**
463
+ * Pre-permuted S-box1
464
+ *
465
+ * Each box ($sbox1-$sbox8) has been vectorized, then each value pre-permuted using the
466
+ * P table: concatenation can then be replaced by exclusive ORs.
467
+ *
468
+ * @var Array
469
+ * @access private
470
+ */
471
+ var $sbox1 = array(
472
+ 0x00808200, 0x00000000, 0x00008000, 0x00808202,
473
+ 0x00808002, 0x00008202, 0x00000002, 0x00008000,
474
+ 0x00000200, 0x00808200, 0x00808202, 0x00000200,
475
+ 0x00800202, 0x00808002, 0x00800000, 0x00000002,
476
+ 0x00000202, 0x00800200, 0x00800200, 0x00008200,
477
+ 0x00008200, 0x00808000, 0x00808000, 0x00800202,
478
+ 0x00008002, 0x00800002, 0x00800002, 0x00008002,
479
+ 0x00000000, 0x00000202, 0x00008202, 0x00800000,
480
+ 0x00008000, 0x00808202, 0x00000002, 0x00808000,
481
+ 0x00808200, 0x00800000, 0x00800000, 0x00000200,
482
+ 0x00808002, 0x00008000, 0x00008200, 0x00800002,
483
+ 0x00000200, 0x00000002, 0x00800202, 0x00008202,
484
+ 0x00808202, 0x00008002, 0x00808000, 0x00800202,
485
+ 0x00800002, 0x00000202, 0x00008202, 0x00808200,
486
+ 0x00000202, 0x00800200, 0x00800200, 0x00000000,
487
+ 0x00008002, 0x00008200, 0x00000000, 0x00808002
488
+ );
489
+
490
+ /**
491
+ * Pre-permuted S-box2
492
+ *
493
+ * @var Array
494
+ * @access private
495
+ */
496
+ var $sbox2 = array(
497
+ 0x40084010, 0x40004000, 0x00004000, 0x00084010,
498
+ 0x00080000, 0x00000010, 0x40080010, 0x40004010,
499
+ 0x40000010, 0x40084010, 0x40084000, 0x40000000,
500
+ 0x40004000, 0x00080000, 0x00000010, 0x40080010,
501
+ 0x00084000, 0x00080010, 0x40004010, 0x00000000,
502
+ 0x40000000, 0x00004000, 0x00084010, 0x40080000,
503
+ 0x00080010, 0x40000010, 0x00000000, 0x00084000,
504
+ 0x00004010, 0x40084000, 0x40080000, 0x00004010,
505
+ 0x00000000, 0x00084010, 0x40080010, 0x00080000,
506
+ 0x40004010, 0x40080000, 0x40084000, 0x00004000,
507
+ 0x40080000, 0x40004000, 0x00000010, 0x40084010,
508
+ 0x00084010, 0x00000010, 0x00004000, 0x40000000,
509
+ 0x00004010, 0x40084000, 0x00080000, 0x40000010,
510
+ 0x00080010, 0x40004010, 0x40000010, 0x00080010,
511
+ 0x00084000, 0x00000000, 0x40004000, 0x00004010,
512
+ 0x40000000, 0x40080010, 0x40084010, 0x00084000
513
+ );
514
+
515
+ /**
516
+ * Pre-permuted S-box3
517
+ *
518
+ * @var Array
519
+ * @access private
520
+ */
521
+ var $sbox3 = array(
522
+ 0x00000104, 0x04010100, 0x00000000, 0x04010004,
523
+ 0x04000100, 0x00000000, 0x00010104, 0x04000100,
524
+ 0x00010004, 0x04000004, 0x04000004, 0x00010000,
525
+ 0x04010104, 0x00010004, 0x04010000, 0x00000104,
526
+ 0x04000000, 0x00000004, 0x04010100, 0x00000100,
527
+ 0x00010100, 0x04010000, 0x04010004, 0x00010104,
528
+ 0x04000104, 0x00010100, 0x00010000, 0x04000104,
529
+ 0x00000004, 0x04010104, 0x00000100, 0x04000000,
530
+ 0x04010100, 0x04000000, 0x00010004, 0x00000104,
531
+ 0x00010000, 0x04010100, 0x04000100, 0x00000000,
532
+ 0x00000100, 0x00010004, 0x04010104, 0x04000100,
533
+ 0x04000004, 0x00000100, 0x00000000, 0x04010004,
534
+ 0x04000104, 0x00010000, 0x04000000, 0x04010104,
535
+ 0x00000004, 0x00010104, 0x00010100, 0x04000004,
536
+ 0x04010000, 0x04000104, 0x00000104, 0x04010000,
537
+ 0x00010104, 0x00000004, 0x04010004, 0x00010100
538
+ );
539
+
540
+ /**
541
+ * Pre-permuted S-box4
542
+ *
543
+ * @var Array
544
+ * @access private
545
+ */
546
+ var $sbox4 = array(
547
+ 0x80401000, 0x80001040, 0x80001040, 0x00000040,
548
+ 0x00401040, 0x80400040, 0x80400000, 0x80001000,
549
+ 0x00000000, 0x00401000, 0x00401000, 0x80401040,
550
+ 0x80000040, 0x00000000, 0x00400040, 0x80400000,
551
+ 0x80000000, 0x00001000, 0x00400000, 0x80401000,
552
+ 0x00000040, 0x00400000, 0x80001000, 0x00001040,
553
+ 0x80400040, 0x80000000, 0x00001040, 0x00400040,
554
+ 0x00001000, 0x00401040, 0x80401040, 0x80000040,
555
+ 0x00400040, 0x80400000, 0x00401000, 0x80401040,
556
+ 0x80000040, 0x00000000, 0x00000000, 0x00401000,
557
+ 0x00001040, 0x00400040, 0x80400040, 0x80000000,
558
+ 0x80401000, 0x80001040, 0x80001040, 0x00000040,
559
+ 0x80401040, 0x80000040, 0x80000000, 0x00001000,
560
+ 0x80400000, 0x80001000, 0x00401040, 0x80400040,
561
+ 0x80001000, 0x00001040, 0x00400000, 0x80401000,
562
+ 0x00000040, 0x00400000, 0x00001000, 0x00401040
563
+ );
564
+
565
+ /**
566
+ * Pre-permuted S-box5
567
+ *
568
+ * @var Array
569
+ * @access private
570
+ */
571
+ var $sbox5 = array(
572
+ 0x00000080, 0x01040080, 0x01040000, 0x21000080,
573
+ 0x00040000, 0x00000080, 0x20000000, 0x01040000,
574
+ 0x20040080, 0x00040000, 0x01000080, 0x20040080,
575
+ 0x21000080, 0x21040000, 0x00040080, 0x20000000,
576
+ 0x01000000, 0x20040000, 0x20040000, 0x00000000,
577
+ 0x20000080, 0x21040080, 0x21040080, 0x01000080,
578
+ 0x21040000, 0x20000080, 0x00000000, 0x21000000,
579
+ 0x01040080, 0x01000000, 0x21000000, 0x00040080,
580
+ 0x00040000, 0x21000080, 0x00000080, 0x01000000,
581
+ 0x20000000, 0x01040000, 0x21000080, 0x20040080,
582
+ 0x01000080, 0x20000000, 0x21040000, 0x01040080,
583
+ 0x20040080, 0x00000080, 0x01000000, 0x21040000,
584
+ 0x21040080, 0x00040080, 0x21000000, 0x21040080,
585
+ 0x01040000, 0x00000000, 0x20040000, 0x21000000,
586
+ 0x00040080, 0x01000080, 0x20000080, 0x00040000,
587
+ 0x00000000, 0x20040000, 0x01040080, 0x20000080
588
+ );
589
+
590
+ /**
591
+ * Pre-permuted S-box6
592
+ *
593
+ * @var Array
594
+ * @access private
595
+ */
596
+ var $sbox6 = array(
597
+ 0x10000008, 0x10200000, 0x00002000, 0x10202008,
598
+ 0x10200000, 0x00000008, 0x10202008, 0x00200000,
599
+ 0x10002000, 0x00202008, 0x00200000, 0x10000008,
600
+ 0x00200008, 0x10002000, 0x10000000, 0x00002008,
601
+ 0x00000000, 0x00200008, 0x10002008, 0x00002000,
602
+ 0x00202000, 0x10002008, 0x00000008, 0x10200008,
603
+ 0x10200008, 0x00000000, 0x00202008, 0x10202000,
604
+ 0x00002008, 0x00202000, 0x10202000, 0x10000000,
605
+ 0x10002000, 0x00000008, 0x10200008, 0x00202000,
606
+ 0x10202008, 0x00200000, 0x00002008, 0x10000008,
607
+ 0x00200000, 0x10002000, 0x10000000, 0x00002008,
608
+ 0x10000008, 0x10202008, 0x00202000, 0x10200000,
609
+ 0x00202008, 0x10202000, 0x00000000, 0x10200008,
610
+ 0x00000008, 0x00002000, 0x10200000, 0x00202008,
611
+ 0x00002000, 0x00200008, 0x10002008, 0x00000000,
612
+ 0x10202000, 0x10000000, 0x00200008, 0x10002008
613
+ );
614
+
615
+ /**
616
+ * Pre-permuted S-box7
617
+ *
618
+ * @var Array
619
+ * @access private
620
+ */
621
+ var $sbox7 = array(
622
+ 0x00100000, 0x02100001, 0x02000401, 0x00000000,
623
+ 0x00000400, 0x02000401, 0x00100401, 0x02100400,
624
+ 0x02100401, 0x00100000, 0x00000000, 0x02000001,
625
+ 0x00000001, 0x02000000, 0x02100001, 0x00000401,
626
+ 0x02000400, 0x00100401, 0x00100001, 0x02000400,
627
+ 0x02000001, 0x02100000, 0x02100400, 0x00100001,
628
+ 0x02100000, 0x00000400, 0x00000401, 0x02100401,
629
+ 0x00100400, 0x00000001, 0x02000000, 0x00100400,
630
+ 0x02000000, 0x00100400, 0x00100000, 0x02000401,
631
+ 0x02000401, 0x02100001, 0x02100001, 0x00000001,
632
+ 0x00100001, 0x02000000, 0x02000400, 0x00100000,
633
+ 0x02100400, 0x00000401, 0x00100401, 0x02100400,
634
+ 0x00000401, 0x02000001, 0x02100401, 0x02100000,
635
+ 0x00100400, 0x00000000, 0x00000001, 0x02100401,
636
+ 0x00000000, 0x00100401, 0x02100000, 0x00000400,
637
+ 0x02000001, 0x02000400, 0x00000400, 0x00100001
638
+ );
639
+
640
+ /**
641
+ * Pre-permuted S-box8
642
+ *
643
+ * @var Array
644
+ * @access private
645
+ */
646
+ var $sbox8 = array(
647
+ 0x08000820, 0x00000800, 0x00020000, 0x08020820,
648
+ 0x08000000, 0x08000820, 0x00000020, 0x08000000,
649
+ 0x00020020, 0x08020000, 0x08020820, 0x00020800,
650
+ 0x08020800, 0x00020820, 0x00000800, 0x00000020,
651
+ 0x08020000, 0x08000020, 0x08000800, 0x00000820,
652
+ 0x00020800, 0x00020020, 0x08020020, 0x08020800,
653
+ 0x00000820, 0x00000000, 0x00000000, 0x08020020,
654
+ 0x08000020, 0x08000800, 0x00020820, 0x00020000,
655
+ 0x00020820, 0x00020000, 0x08020800, 0x00000800,
656
+ 0x00000020, 0x08020020, 0x00000800, 0x00020820,
657
+ 0x08000800, 0x00000020, 0x08000020, 0x08020000,
658
+ 0x08020020, 0x08000000, 0x00020000, 0x08000820,
659
+ 0x00000000, 0x08020820, 0x00020020, 0x08000020,
660
+ 0x08020000, 0x08000800, 0x08000820, 0x00000000,
661
+ 0x08020820, 0x00020800, 0x00020800, 0x00000820,
662
+ 0x00000820, 0x00020020, 0x08000000, 0x08020800
663
+ );
664
+
665
+ /**
666
+ * Test for engine validity
667
+ *
668
+ * This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine()
669
+ *
670
+ * @see Crypt_Base::isValidEngine()
671
+ * @param Integer $engine
672
+ * @access public
673
+ * @return Boolean
674
+ */
675
+ function isValidEngine($engine)
676
+ {
677
+ if ($this->key_size_max == 8) {
678
+ if ($engine == CRYPT_ENGINE_OPENSSL) {
679
+ $this->cipher_name_openssl_ecb = 'des-ecb';
680
+ $this->cipher_name_openssl = 'des-' . $this->_openssl_translate_mode();
681
+ }
682
+ }
683
+
684
+ return parent::isValidEngine($engine);
685
+ }
686
+
687
+ /**
688
+ * Sets the key.
689
+ *
690
+ * Keys can be of any length. DES, itself, uses 64-bit keys (eg. strlen($key) == 8), however, we
691
+ * only use the first eight, if $key has more then eight characters in it, and pad $key with the
692
+ * null byte if it is less then eight characters long.
693
+ *
694
+ * DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
695
+ *
696
+ * If the key is not explicitly set, it'll be assumed to be all zero's.
697
+ *
698
+ * @see Crypt_Base::setKey()
699
+ * @access public
700
+ * @param String $key
701
+ */
702
+ function setKey($key)
703
+ {
704
+ // We check/cut here only up to max length of the key.
705
+ // Key padding to the proper length will be done in _setupKey()
706
+ if (strlen($key) > $this->key_size_max) {
707
+ $key = substr($key, 0, $this->key_size_max);
708
+ }
709
+
710
+ // Sets the key
711
+ parent::setKey($key);
712
+ }
713
+
714
+ /**
715
+ * Encrypts a block
716
+ *
717
+ * @see Crypt_Base::_encryptBlock()
718
+ * @see Crypt_Base::encrypt()
719
+ * @see Crypt_DES::encrypt()
720
+ * @access private
721
+ * @param String $in
722
+ * @return String
723
+ */
724
+ function _encryptBlock($in)
725
+ {
726
+ return $this->_processBlock($in, CRYPT_DES_ENCRYPT);
727
+ }
728
+
729
+ /**
730
+ * Decrypts a block
731
+ *
732
+ * @see Crypt_Base::_decryptBlock()
733
+ * @see Crypt_Base::decrypt()
734
+ * @see Crypt_DES::decrypt()
735
+ * @access private
736
+ * @param String $in
737
+ * @return String
738
+ */
739
+ function _decryptBlock($in)
740
+ {
741
+ return $this->_processBlock($in, CRYPT_DES_DECRYPT);
742
+ }
743
+
744
+ /**
745
+ * Encrypts or decrypts a 64-bit block
746
+ *
747
+ * $mode should be either CRYPT_DES_ENCRYPT or CRYPT_DES_DECRYPT. See
748
+ * {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general
749
+ * idea of what this function does.
750
+ *
751
+ * @see Crypt_DES::_encryptBlock()
752
+ * @see Crypt_DES::_decryptBlock()
753
+ * @access private
754
+ * @param String $block
755
+ * @param Integer $mode
756
+ * @return String
757
+ */
758
+ function _processBlock($block, $mode)
759
+ {
760
+ static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip;
761
+ if (!$sbox1) {
762
+ $sbox1 = array_map("intval", $this->sbox1);
763
+ $sbox2 = array_map("intval", $this->sbox2);
764
+ $sbox3 = array_map("intval", $this->sbox3);
765
+ $sbox4 = array_map("intval", $this->sbox4);
766
+ $sbox5 = array_map("intval", $this->sbox5);
767
+ $sbox6 = array_map("intval", $this->sbox6);
768
+ $sbox7 = array_map("intval", $this->sbox7);
769
+ $sbox8 = array_map("intval", $this->sbox8);
770
+ /* Merge $shuffle with $[inv]ipmap */
771
+ for ($i = 0; $i < 256; ++$i) {
772
+ $shuffleip[] = $this->shuffle[$this->ipmap[$i]];
773
+ $shuffleinvip[] = $this->shuffle[$this->invipmap[$i]];
774
+ }
775
+ }
776
+
777
+ $keys = $this->keys[$mode];
778
+ $ki = -1;
779
+
780
+ // Do the initial IP permutation.
781
+ $t = unpack('Nl/Nr', $block);
782
+ list($l, $r) = array($t['l'], $t['r']);
783
+ $block = ($shuffleip[ $r & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
784
+ ($shuffleip[($r >> 8) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
785
+ ($shuffleip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
786
+ ($shuffleip[($r >> 24) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
787
+ ($shuffleip[ $l & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
788
+ ($shuffleip[($l >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
789
+ ($shuffleip[($l >> 16) & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
790
+ ($shuffleip[($l >> 24) & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01");
791
+
792
+ // Extract L0 and R0.
793
+ $t = unpack('Nl/Nr', $block);
794
+ list($l, $r) = array($t['l'], $t['r']);
795
+
796
+ for ($des_round = 0; $des_round < $this->des_rounds; ++$des_round) {
797
+ // Perform the 16 steps.
798
+ for ($i = 0; $i < 16; $i++) {
799
+ // start of "the Feistel (F) function" - see the following URL:
800
+ // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png
801
+ // Merge key schedule.
802
+ $b1 = (($r >> 3) & 0x1FFFFFFF) ^ ($r << 29) ^ $keys[++$ki];
803
+ $b2 = (($r >> 31) & 0x00000001) ^ ($r << 1) ^ $keys[++$ki];
804
+
805
+ // S-box indexing.
806
+ $t = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^
807
+ $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^
808
+ $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^
809
+ $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ $l;
810
+ // end of "the Feistel (F) function"
811
+
812
+ $l = $r;
813
+ $r = $t;
814
+ }
815
+
816
+ // Last step should not permute L & R.
817
+ $t = $l;
818
+ $l = $r;
819
+ $r = $t;
820
+ }
821
+
822
+ // Perform the inverse IP permutation.
823
+ return ($shuffleinvip[($r >> 24) & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
824
+ ($shuffleinvip[($l >> 24) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
825
+ ($shuffleinvip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
826
+ ($shuffleinvip[($l >> 16) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
827
+ ($shuffleinvip[($r >> 8) & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
828
+ ($shuffleinvip[($l >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
829
+ ($shuffleinvip[ $r & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
830
+ ($shuffleinvip[ $l & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01");
831
+ }
832
+
833
+ /**
834
+ * Creates the key schedule
835
+ *
836
+ * @see Crypt_Base::_setupKey()
837
+ * @access private
838
+ */
839
+ function _setupKey()
840
+ {
841
+ if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->des_rounds === $this->kl['des_rounds']) {
842
+ // already expanded
843
+ return;
844
+ }
845
+ $this->kl = array('key' => $this->key, 'des_rounds' => $this->des_rounds);
846
+
847
+ static $shifts = array( // number of key bits shifted per round
848
+ 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
849
+ );
850
+
851
+ static $pc1map = array(
852
+ 0x00, 0x00, 0x08, 0x08, 0x04, 0x04, 0x0C, 0x0C,
853
+ 0x02, 0x02, 0x0A, 0x0A, 0x06, 0x06, 0x0E, 0x0E,
854
+ 0x10, 0x10, 0x18, 0x18, 0x14, 0x14, 0x1C, 0x1C,
855
+ 0x12, 0x12, 0x1A, 0x1A, 0x16, 0x16, 0x1E, 0x1E,
856
+ 0x20, 0x20, 0x28, 0x28, 0x24, 0x24, 0x2C, 0x2C,
857
+ 0x22, 0x22, 0x2A, 0x2A, 0x26, 0x26, 0x2E, 0x2E,
858
+ 0x30, 0x30, 0x38, 0x38, 0x34, 0x34, 0x3C, 0x3C,
859
+ 0x32, 0x32, 0x3A, 0x3A, 0x36, 0x36, 0x3E, 0x3E,
860
+ 0x40, 0x40, 0x48, 0x48, 0x44, 0x44, 0x4C, 0x4C,
861
+ 0x42, 0x42, 0x4A, 0x4A, 0x46, 0x46, 0x4E, 0x4E,
862
+ 0x50, 0x50, 0x58, 0x58, 0x54, 0x54, 0x5C, 0x5C,
863
+ 0x52, 0x52, 0x5A, 0x5A, 0x56, 0x56, 0x5E, 0x5E,
864
+ 0x60, 0x60, 0x68, 0x68, 0x64, 0x64, 0x6C, 0x6C,
865
+ 0x62, 0x62, 0x6A, 0x6A, 0x66, 0x66, 0x6E, 0x6E,
866
+ 0x70, 0x70, 0x78, 0x78, 0x74, 0x74, 0x7C, 0x7C,
867
+ 0x72, 0x72, 0x7A, 0x7A, 0x76, 0x76, 0x7E, 0x7E,
868
+ 0x80, 0x80, 0x88, 0x88, 0x84, 0x84, 0x8C, 0x8C,
869
+ 0x82, 0x82, 0x8A, 0x8A, 0x86, 0x86, 0x8E, 0x8E,
870
+ 0x90, 0x90, 0x98, 0x98, 0x94, 0x94, 0x9C, 0x9C,
871
+ 0x92, 0x92, 0x9A, 0x9A, 0x96, 0x96, 0x9E, 0x9E,
872
+ 0xA0, 0xA0, 0xA8, 0xA8, 0xA4, 0xA4, 0xAC, 0xAC,
873
+ 0xA2, 0xA2, 0xAA, 0xAA, 0xA6, 0xA6, 0xAE, 0xAE,
874
+ 0xB0, 0xB0, 0xB8, 0xB8, 0xB4, 0xB4, 0xBC, 0xBC,
875
+ 0xB2, 0xB2, 0xBA, 0xBA, 0xB6, 0xB6, 0xBE, 0xBE,
876
+ 0xC0, 0xC0, 0xC8, 0xC8, 0xC4, 0xC4, 0xCC, 0xCC,
877
+ 0xC2, 0xC2, 0xCA, 0xCA, 0xC6, 0xC6, 0xCE, 0xCE,
878
+ 0xD0, 0xD0, 0xD8, 0xD8, 0xD4, 0xD4, 0xDC, 0xDC,
879
+ 0xD2, 0xD2, 0xDA, 0xDA, 0xD6, 0xD6, 0xDE, 0xDE,
880
+ 0xE0, 0xE0, 0xE8, 0xE8, 0xE4, 0xE4, 0xEC, 0xEC,
881
+ 0xE2, 0xE2, 0xEA, 0xEA, 0xE6, 0xE6, 0xEE, 0xEE,
882
+ 0xF0, 0xF0, 0xF8, 0xF8, 0xF4, 0xF4, 0xFC, 0xFC,
883
+ 0xF2, 0xF2, 0xFA, 0xFA, 0xF6, 0xF6, 0xFE, 0xFE
884
+ );
885
+
886
+ // Mapping tables for the PC-2 transformation.
887
+ static $pc2mapc1 = array(
888
+ 0x00000000, 0x00000400, 0x00200000, 0x00200400,
889
+ 0x00000001, 0x00000401, 0x00200001, 0x00200401,
890
+ 0x02000000, 0x02000400, 0x02200000, 0x02200400,
891
+ 0x02000001, 0x02000401, 0x02200001, 0x02200401
892
+ );
893
+ static $pc2mapc2 = array(
894
+ 0x00000000, 0x00000800, 0x08000000, 0x08000800,
895
+ 0x00010000, 0x00010800, 0x08010000, 0x08010800,
896
+ 0x00000000, 0x00000800, 0x08000000, 0x08000800,
897
+ 0x00010000, 0x00010800, 0x08010000, 0x08010800,
898
+ 0x00000100, 0x00000900, 0x08000100, 0x08000900,
899
+ 0x00010100, 0x00010900, 0x08010100, 0x08010900,
900
+ 0x00000100, 0x00000900, 0x08000100, 0x08000900,
901
+ 0x00010100, 0x00010900, 0x08010100, 0x08010900,
902
+ 0x00000010, 0x00000810, 0x08000010, 0x08000810,
903
+ 0x00010010, 0x00010810, 0x08010010, 0x08010810,
904
+ 0x00000010, 0x00000810, 0x08000010, 0x08000810,
905
+ 0x00010010, 0x00010810, 0x08010010, 0x08010810,
906
+ 0x00000110, 0x00000910, 0x08000110, 0x08000910,
907
+ 0x00010110, 0x00010910, 0x08010110, 0x08010910,
908
+ 0x00000110, 0x00000910, 0x08000110, 0x08000910,
909
+ 0x00010110, 0x00010910, 0x08010110, 0x08010910,
910
+ 0x00040000, 0x00040800, 0x08040000, 0x08040800,
911
+ 0x00050000, 0x00050800, 0x08050000, 0x08050800,
912
+ 0x00040000, 0x00040800, 0x08040000, 0x08040800,
913
+ 0x00050000, 0x00050800, 0x08050000, 0x08050800,
914
+ 0x00040100, 0x00040900, 0x08040100, 0x08040900,
915
+ 0x00050100, 0x00050900, 0x08050100, 0x08050900,
916
+ 0x00040100, 0x00040900, 0x08040100, 0x08040900,
917
+ 0x00050100, 0x00050900, 0x08050100, 0x08050900,
918
+ 0x00040010, 0x00040810, 0x08040010, 0x08040810,
919
+ 0x00050010, 0x00050810, 0x08050010, 0x08050810,
920
+ 0x00040010, 0x00040810, 0x08040010, 0x08040810,
921
+ 0x00050010, 0x00050810, 0x08050010, 0x08050810,
922
+ 0x00040110, 0x00040910, 0x08040110, 0x08040910,
923
+ 0x00050110, 0x00050910, 0x08050110, 0x08050910,
924
+ 0x00040110, 0x00040910, 0x08040110, 0x08040910,
925
+ 0x00050110, 0x00050910, 0x08050110, 0x08050910,
926
+ 0x01000000, 0x01000800, 0x09000000, 0x09000800,
927
+ 0x01010000, 0x01010800, 0x09010000, 0x09010800,
928
+ 0x01000000, 0x01000800, 0x09000000, 0x09000800,
929
+ 0x01010000, 0x01010800, 0x09010000, 0x09010800,
930
+ 0x01000100, 0x01000900, 0x09000100, 0x09000900,
931
+ 0x01010100, 0x01010900, 0x09010100, 0x09010900,
932
+ 0x01000100, 0x01000900, 0x09000100, 0x09000900,
933
+ 0x01010100, 0x01010900, 0x09010100, 0x09010900,
934
+ 0x01000010, 0x01000810, 0x09000010, 0x09000810,
935
+ 0x01010010, 0x01010810, 0x09010010, 0x09010810,
936
+ 0x01000010, 0x01000810, 0x09000010, 0x09000810,
937
+ 0x01010010, 0x01010810, 0x09010010, 0x09010810,
938
+ 0x01000110, 0x01000910, 0x09000110, 0x09000910,
939
+ 0x01010110, 0x01010910, 0x09010110, 0x09010910,
940
+ 0x01000110, 0x01000910, 0x09000110, 0x09000910,
941
+ 0x01010110, 0x01010910, 0x09010110, 0x09010910,
942
+ 0x01040000, 0x01040800, 0x09040000, 0x09040800,
943
+ 0x01050000, 0x01050800, 0x09050000, 0x09050800,
944
+ 0x01040000, 0x01040800, 0x09040000, 0x09040800,
945
+ 0x01050000, 0x01050800, 0x09050000, 0x09050800,
946
+ 0x01040100, 0x01040900, 0x09040100, 0x09040900,
947
+ 0x01050100, 0x01050900, 0x09050100, 0x09050900,
948
+ 0x01040100, 0x01040900, 0x09040100, 0x09040900,
949
+ 0x01050100, 0x01050900, 0x09050100, 0x09050900,
950
+ 0x01040010, 0x01040810, 0x09040010, 0x09040810,
951
+ 0x01050010, 0x01050810, 0x09050010, 0x09050810,
952
+ 0x01040010, 0x01040810, 0x09040010, 0x09040810,
953
+ 0x01050010, 0x01050810, 0x09050010, 0x09050810,
954
+ 0x01040110, 0x01040910, 0x09040110, 0x09040910,
955
+ 0x01050110, 0x01050910, 0x09050110, 0x09050910,
956
+ 0x01040110, 0x01040910, 0x09040110, 0x09040910,
957
+ 0x01050110, 0x01050910, 0x09050110, 0x09050910
958
+ );
959
+ static $pc2mapc3 = array(
960
+ 0x00000000, 0x00000004, 0x00001000, 0x00001004,
961
+ 0x00000000, 0x00000004, 0x00001000, 0x00001004,
962
+ 0x10000000, 0x10000004, 0x10001000, 0x10001004,
963
+ 0x10000000, 0x10000004, 0x10001000, 0x10001004,
964
+ 0x00000020, 0x00000024, 0x00001020, 0x00001024,
965
+ 0x00000020, 0x00000024, 0x00001020, 0x00001024,
966
+ 0x10000020, 0x10000024, 0x10001020, 0x10001024,
967
+ 0x10000020, 0x10000024, 0x10001020, 0x10001024,
968
+ 0x00080000, 0x00080004, 0x00081000, 0x00081004,
969
+ 0x00080000, 0x00080004, 0x00081000, 0x00081004,
970
+ 0x10080000, 0x10080004, 0x10081000, 0x10081004,
971
+ 0x10080000, 0x10080004, 0x10081000, 0x10081004,
972
+ 0x00080020, 0x00080024, 0x00081020, 0x00081024,
973
+ 0x00080020, 0x00080024, 0x00081020, 0x00081024,
974
+ 0x10080020, 0x10080024, 0x10081020, 0x10081024,
975
+ 0x10080020, 0x10080024, 0x10081020, 0x10081024,
976
+ 0x20000000, 0x20000004, 0x20001000, 0x20001004,
977
+ 0x20000000, 0x20000004, 0x20001000, 0x20001004,
978
+ 0x30000000, 0x30000004, 0x30001000, 0x30001004,
979
+ 0x30000000, 0x30000004, 0x30001000, 0x30001004,
980
+ 0x20000020, 0x20000024, 0x20001020, 0x20001024,
981
+ 0x20000020, 0x20000024, 0x20001020, 0x20001024,
982
+ 0x30000020, 0x30000024, 0x30001020, 0x30001024,
983
+ 0x30000020, 0x30000024, 0x30001020, 0x30001024,
984
+ 0x20080000, 0x20080004, 0x20081000, 0x20081004,
985
+ 0x20080000, 0x20080004, 0x20081000, 0x20081004,
986
+ 0x30080000, 0x30080004, 0x30081000, 0x30081004,
987
+ 0x30080000, 0x30080004, 0x30081000, 0x30081004,
988
+ 0x20080020, 0x20080024, 0x20081020, 0x20081024,
989
+ 0x20080020, 0x20080024, 0x20081020, 0x20081024,
990
+ 0x30080020, 0x30080024, 0x30081020, 0x30081024,
991
+ 0x30080020, 0x30080024, 0x30081020, 0x30081024,
992
+ 0x00000002, 0x00000006, 0x00001002, 0x00001006,
993
+ 0x00000002, 0x00000006, 0x00001002, 0x00001006,
994
+ 0x10000002, 0x10000006, 0x10001002, 0x10001006,
995
+ 0x10000002, 0x10000006, 0x10001002, 0x10001006,
996
+ 0x00000022, 0x00000026, 0x00001022, 0x00001026,
997
+ 0x00000022, 0x00000026, 0x00001022, 0x00001026,
998
+ 0x10000022, 0x10000026, 0x10001022, 0x10001026,
999
+ 0x10000022, 0x10000026, 0x10001022, 0x10001026,
1000
+ 0x00080002, 0x00080006, 0x00081002, 0x00081006,
1001
+ 0x00080002, 0x00080006, 0x00081002, 0x00081006,
1002
+ 0x10080002, 0x10080006, 0x10081002, 0x10081006,
1003
+ 0x10080002, 0x10080006, 0x10081002, 0x10081006,
1004
+ 0x00080022, 0x00080026, 0x00081022, 0x00081026,
1005
+ 0x00080022, 0x00080026, 0x00081022, 0x00081026,
1006
+ 0x10080022, 0x10080026, 0x10081022, 0x10081026,
1007
+ 0x10080022, 0x10080026, 0x10081022, 0x10081026,
1008
+ 0x20000002, 0x20000006, 0x20001002, 0x20001006,
1009
+ 0x20000002, 0x20000006, 0x20001002, 0x20001006,
1010
+ 0x30000002, 0x30000006, 0x30001002, 0x30001006,
1011
+ 0x30000002, 0x30000006, 0x30001002, 0x30001006,
1012
+ 0x20000022, 0x20000026, 0x20001022, 0x20001026,
1013
+ 0x20000022, 0x20000026, 0x20001022, 0x20001026,
1014
+ 0x30000022, 0x30000026, 0x30001022, 0x30001026,
1015
+ 0x30000022, 0x30000026, 0x30001022, 0x30001026,
1016
+ 0x20080002, 0x20080006, 0x20081002, 0x20081006,
1017
+ 0x20080002, 0x20080006, 0x20081002, 0x20081006,
1018
+ 0x30080002, 0x30080006, 0x30081002, 0x30081006,
1019
+ 0x30080002, 0x30080006, 0x30081002, 0x30081006,
1020
+ 0x20080022, 0x20080026, 0x20081022, 0x20081026,
1021
+ 0x20080022, 0x20080026, 0x20081022, 0x20081026,
1022
+ 0x30080022, 0x30080026, 0x30081022, 0x30081026,
1023
+ 0x30080022, 0x30080026, 0x30081022, 0x30081026
1024
+ );
1025
+ static $pc2mapc4 = array(
1026
+ 0x00000000, 0x00100000, 0x00000008, 0x00100008,
1027
+ 0x00000200, 0x00100200, 0x00000208, 0x00100208,
1028
+ 0x00000000, 0x00100000, 0x00000008, 0x00100008,
1029
+ 0x00000200, 0x00100200, 0x00000208, 0x00100208,
1030
+ 0x04000000, 0x04100000, 0x04000008, 0x04100008,
1031
+ 0x04000200, 0x04100200, 0x04000208, 0x04100208,
1032
+ 0x04000000, 0x04100000, 0x04000008, 0x04100008,
1033
+ 0x04000200, 0x04100200, 0x04000208, 0x04100208,
1034
+ 0x00002000, 0x00102000, 0x00002008, 0x00102008,
1035
+ 0x00002200, 0x00102200, 0x00002208, 0x00102208,
1036
+ 0x00002000, 0x00102000, 0x00002008, 0x00102008,
1037
+ 0x00002200, 0x00102200, 0x00002208, 0x00102208,
1038
+ 0x04002000, 0x04102000, 0x04002008, 0x04102008,
1039
+ 0x04002200, 0x04102200, 0x04002208, 0x04102208,
1040
+ 0x04002000, 0x04102000, 0x04002008, 0x04102008,
1041
+ 0x04002200, 0x04102200, 0x04002208, 0x04102208,
1042
+ 0x00000000, 0x00100000, 0x00000008, 0x00100008,
1043
+ 0x00000200, 0x00100200, 0x00000208, 0x00100208,
1044
+ 0x00000000, 0x00100000, 0x00000008, 0x00100008,
1045
+ 0x00000200, 0x00100200, 0x00000208, 0x00100208,
1046
+ 0x04000000, 0x04100000, 0x04000008, 0x04100008,
1047
+ 0x04000200, 0x04100200, 0x04000208, 0x04100208,
1048
+ 0x04000000, 0x04100000, 0x04000008, 0x04100008,
1049
+ 0x04000200, 0x04100200, 0x04000208, 0x04100208,
1050
+ 0x00002000, 0x00102000, 0x00002008, 0x00102008,
1051
+ 0x00002200, 0x00102200, 0x00002208, 0x00102208,
1052
+ 0x00002000, 0x00102000, 0x00002008, 0x00102008,
1053
+ 0x00002200, 0x00102200, 0x00002208, 0x00102208,
1054
+ 0x04002000, 0x04102000, 0x04002008, 0x04102008,
1055
+ 0x04002200, 0x04102200, 0x04002208, 0x04102208,
1056
+ 0x04002000, 0x04102000, 0x04002008, 0x04102008,
1057
+ 0x04002200, 0x04102200, 0x04002208, 0x04102208,
1058
+ 0x00020000, 0x00120000, 0x00020008, 0x00120008,
1059
+ 0x00020200, 0x00120200, 0x00020208, 0x00120208,
1060
+ 0x00020000, 0x00120000, 0x00020008, 0x00120008,
1061
+ 0x00020200, 0x00120200, 0x00020208, 0x00120208,
1062
+ 0x04020000, 0x04120000, 0x04020008, 0x04120008,
1063
+ 0x04020200, 0x04120200, 0x04020208, 0x04120208,
1064
+ 0x04020000, 0x04120000, 0x04020008, 0x04120008,
1065
+ 0x04020200, 0x04120200, 0x04020208, 0x04120208,
1066
+ 0x00022000, 0x00122000, 0x00022008, 0x00122008,
1067
+ 0x00022200, 0x00122200, 0x00022208, 0x00122208,
1068
+ 0x00022000, 0x00122000, 0x00022008, 0x00122008,
1069
+ 0x00022200, 0x00122200, 0x00022208, 0x00122208,
1070
+ 0x04022000, 0x04122000, 0x04022008, 0x04122008,
1071
+ 0x04022200, 0x04122200, 0x04022208, 0x04122208,
1072
+ 0x04022000, 0x04122000, 0x04022008, 0x04122008,
1073
+ 0x04022200, 0x04122200, 0x04022208, 0x04122208,
1074
+ 0x00020000, 0x00120000, 0x00020008, 0x00120008,
1075
+ 0x00020200, 0x00120200, 0x00020208, 0x00120208,
1076
+ 0x00020000, 0x00120000, 0x00020008, 0x00120008,
1077
+ 0x00020200, 0x00120200, 0x00020208, 0x00120208,
1078
+ 0x04020000, 0x04120000, 0x04020008, 0x04120008,
1079
+ 0x04020200, 0x04120200, 0x04020208, 0x04120208,
1080
+ 0x04020000, 0x04120000, 0x04020008, 0x04120008,
1081
+ 0x04020200, 0x04120200, 0x04020208, 0x04120208,
1082
+ 0x00022000, 0x00122000, 0x00022008, 0x00122008,
1083
+ 0x00022200, 0x00122200, 0x00022208, 0x00122208,
1084
+ 0x00022000, 0x00122000, 0x00022008, 0x00122008,
1085
+ 0x00022200, 0x00122200, 0x00022208, 0x00122208,
1086
+ 0x04022000, 0x04122000, 0x04022008, 0x04122008,
1087
+ 0x04022200, 0x04122200, 0x04022208, 0x04122208,
1088
+ 0x04022000, 0x04122000, 0x04022008, 0x04122008,
1089
+ 0x04022200, 0x04122200, 0x04022208, 0x04122208
1090
+ );
1091
+ static $pc2mapd1 = array(
1092
+ 0x00000000, 0x00000001, 0x08000000, 0x08000001,
1093
+ 0x00200000, 0x00200001, 0x08200000, 0x08200001,
1094
+ 0x00000002, 0x00000003, 0x08000002, 0x08000003,
1095
+ 0x00200002, 0x00200003, 0x08200002, 0x08200003
1096
+ );
1097
+ static $pc2mapd2 = array(
1098
+ 0x00000000, 0x00100000, 0x00000800, 0x00100800,
1099
+ 0x00000000, 0x00100000, 0x00000800, 0x00100800,
1100
+ 0x04000000, 0x04100000, 0x04000800, 0x04100800,
1101
+ 0x04000000, 0x04100000, 0x04000800, 0x04100800,
1102
+ 0x00000004, 0x00100004, 0x00000804, 0x00100804,
1103
+ 0x00000004, 0x00100004, 0x00000804, 0x00100804,
1104
+ 0x04000004, 0x04100004, 0x04000804, 0x04100804,
1105
+ 0x04000004, 0x04100004, 0x04000804, 0x04100804,
1106
+ 0x00000000, 0x00100000, 0x00000800, 0x00100800,
1107
+ 0x00000000, 0x00100000, 0x00000800, 0x00100800,
1108
+ 0x04000000, 0x04100000, 0x04000800, 0x04100800,
1109
+ 0x04000000, 0x04100000, 0x04000800, 0x04100800,
1110
+ 0x00000004, 0x00100004, 0x00000804, 0x00100804,
1111
+ 0x00000004, 0x00100004, 0x00000804, 0x00100804,
1112
+ 0x04000004, 0x04100004, 0x04000804, 0x04100804,
1113
+ 0x04000004, 0x04100004, 0x04000804, 0x04100804,
1114
+ 0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
1115
+ 0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
1116
+ 0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
1117
+ 0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
1118
+ 0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
1119
+ 0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
1120
+ 0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
1121
+ 0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
1122
+ 0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
1123
+ 0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
1124
+ 0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
1125
+ 0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
1126
+ 0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
1127
+ 0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
1128
+ 0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
1129
+ 0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
1130
+ 0x00020000, 0x00120000, 0x00020800, 0x00120800,
1131
+ 0x00020000, 0x00120000, 0x00020800, 0x00120800,
1132
+ 0x04020000, 0x04120000, 0x04020800, 0x04120800,
1133
+ 0x04020000, 0x04120000, 0x04020800, 0x04120800,
1134
+ 0x00020004, 0x00120004, 0x00020804, 0x00120804,
1135
+ 0x00020004, 0x00120004, 0x00020804, 0x00120804,
1136
+ 0x04020004, 0x04120004, 0x04020804, 0x04120804,
1137
+ 0x04020004, 0x04120004, 0x04020804, 0x04120804,
1138
+ 0x00020000, 0x00120000, 0x00020800, 0x00120800,
1139
+ 0x00020000, 0x00120000, 0x00020800, 0x00120800,
1140
+ 0x04020000, 0x04120000, 0x04020800, 0x04120800,
1141
+ 0x04020000, 0x04120000, 0x04020800, 0x04120800,
1142
+ 0x00020004, 0x00120004, 0x00020804, 0x00120804,
1143
+ 0x00020004, 0x00120004, 0x00020804, 0x00120804,
1144
+ 0x04020004, 0x04120004, 0x04020804, 0x04120804,
1145
+ 0x04020004, 0x04120004, 0x04020804, 0x04120804,
1146
+ 0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
1147
+ 0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
1148
+ 0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
1149
+ 0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
1150
+ 0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
1151
+ 0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
1152
+ 0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
1153
+ 0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
1154
+ 0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
1155
+ 0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
1156
+ 0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
1157
+ 0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
1158
+ 0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
1159
+ 0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
1160
+ 0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
1161
+ 0x04020204, 0x04120204, 0x04020A04, 0x04120A04
1162
+ );
1163
+ static $pc2mapd3 = array(
1164
+ 0x00000000, 0x00010000, 0x02000000, 0x02010000,
1165
+ 0x00000020, 0x00010020, 0x02000020, 0x02010020,
1166
+ 0x00040000, 0x00050000, 0x02040000, 0x02050000,
1167
+ 0x00040020, 0x00050020, 0x02040020, 0x02050020,
1168
+ 0x00002000, 0x00012000, 0x02002000, 0x02012000,
1169
+ 0x00002020, 0x00012020, 0x02002020, 0x02012020,
1170
+ 0x00042000, 0x00052000, 0x02042000, 0x02052000,
1171
+ 0x00042020, 0x00052020, 0x02042020, 0x02052020,
1172
+ 0x00000000, 0x00010000, 0x02000000, 0x02010000,
1173
+ 0x00000020, 0x00010020, 0x02000020, 0x02010020,
1174
+ 0x00040000, 0x00050000, 0x02040000, 0x02050000,
1175
+ 0x00040020, 0x00050020, 0x02040020, 0x02050020,
1176
+ 0x00002000, 0x00012000, 0x02002000, 0x02012000,
1177
+ 0x00002020, 0x00012020, 0x02002020, 0x02012020,
1178
+ 0x00042000, 0x00052000, 0x02042000, 0x02052000,
1179
+ 0x00042020, 0x00052020, 0x02042020, 0x02052020,
1180
+ 0x00000010, 0x00010010, 0x02000010, 0x02010010,
1181
+ 0x00000030, 0x00010030, 0x02000030, 0x02010030,
1182
+ 0x00040010, 0x00050010, 0x02040010, 0x02050010,
1183
+ 0x00040030, 0x00050030, 0x02040030, 0x02050030,
1184
+ 0x00002010, 0x00012010, 0x02002010, 0x02012010,
1185
+ 0x00002030, 0x00012030, 0x02002030, 0x02012030,
1186
+ 0x00042010, 0x00052010, 0x02042010, 0x02052010,
1187
+ 0x00042030, 0x00052030, 0x02042030, 0x02052030,
1188
+ 0x00000010, 0x00010010, 0x02000010, 0x02010010,
1189
+ 0x00000030, 0x00010030, 0x02000030, 0x02010030,
1190
+ 0x00040010, 0x00050010, 0x02040010, 0x02050010,
1191
+ 0x00040030, 0x00050030, 0x02040030, 0x02050030,
1192
+ 0x00002010, 0x00012010, 0x02002010, 0x02012010,
1193
+ 0x00002030, 0x00012030, 0x02002030, 0x02012030,
1194
+ 0x00042010, 0x00052010, 0x02042010, 0x02052010,
1195
+ 0x00042030, 0x00052030, 0x02042030, 0x02052030,
1196
+ 0x20000000, 0x20010000, 0x22000000, 0x22010000,
1197
+ 0x20000020, 0x20010020, 0x22000020, 0x22010020,
1198
+ 0x20040000, 0x20050000, 0x22040000, 0x22050000,
1199
+ 0x20040020, 0x20050020, 0x22040020, 0x22050020,
1200
+ 0x20002000, 0x20012000, 0x22002000, 0x22012000,
1201
+ 0x20002020, 0x20012020, 0x22002020, 0x22012020,
1202
+ 0x20042000, 0x20052000, 0x22042000, 0x22052000,
1203
+ 0x20042020, 0x20052020, 0x22042020, 0x22052020,
1204
+ 0x20000000, 0x20010000, 0x22000000, 0x22010000,
1205
+ 0x20000020, 0x20010020, 0x22000020, 0x22010020,
1206
+ 0x20040000, 0x20050000, 0x22040000, 0x22050000,
1207
+ 0x20040020, 0x20050020, 0x22040020, 0x22050020,
1208
+ 0x20002000, 0x20012000, 0x22002000, 0x22012000,
1209
+ 0x20002020, 0x20012020, 0x22002020, 0x22012020,
1210
+ 0x20042000, 0x20052000, 0x22042000, 0x22052000,
1211
+ 0x20042020, 0x20052020, 0x22042020, 0x22052020,
1212
+ 0x20000010, 0x20010010, 0x22000010, 0x22010010,
1213
+ 0x20000030, 0x20010030, 0x22000030, 0x22010030,
1214
+ 0x20040010, 0x20050010, 0x22040010, 0x22050010,
1215
+ 0x20040030, 0x20050030, 0x22040030, 0x22050030,
1216
+ 0x20002010, 0x20012010, 0x22002010, 0x22012010,
1217
+ 0x20002030, 0x20012030, 0x22002030, 0x22012030,
1218
+ 0x20042010, 0x20052010, 0x22042010, 0x22052010,
1219
+ 0x20042030, 0x20052030, 0x22042030, 0x22052030,
1220
+ 0x20000010, 0x20010010, 0x22000010, 0x22010010,
1221
+ 0x20000030, 0x20010030, 0x22000030, 0x22010030,
1222
+ 0x20040010, 0x20050010, 0x22040010, 0x22050010,
1223
+ 0x20040030, 0x20050030, 0x22040030, 0x22050030,
1224
+ 0x20002010, 0x20012010, 0x22002010, 0x22012010,
1225
+ 0x20002030, 0x20012030, 0x22002030, 0x22012030,
1226
+ 0x20042010, 0x20052010, 0x22042010, 0x22052010,
1227
+ 0x20042030, 0x20052030, 0x22042030, 0x22052030
1228
+ );
1229
+ static $pc2mapd4 = array(
1230
+ 0x00000000, 0x00000400, 0x01000000, 0x01000400,
1231
+ 0x00000000, 0x00000400, 0x01000000, 0x01000400,
1232
+ 0x00000100, 0x00000500, 0x01000100, 0x01000500,
1233
+ 0x00000100, 0x00000500, 0x01000100, 0x01000500,
1234
+ 0x10000000, 0x10000400, 0x11000000, 0x11000400,
1235
+ 0x10000000, 0x10000400, 0x11000000, 0x11000400,
1236
+ 0x10000100, 0x10000500, 0x11000100, 0x11000500,
1237
+ 0x10000100, 0x10000500, 0x11000100, 0x11000500,
1238
+ 0x00080000, 0x00080400, 0x01080000, 0x01080400,
1239
+ 0x00080000, 0x00080400, 0x01080000, 0x01080400,
1240
+ 0x00080100, 0x00080500, 0x01080100, 0x01080500,
1241
+ 0x00080100, 0x00080500, 0x01080100, 0x01080500,
1242
+ 0x10080000, 0x10080400, 0x11080000, 0x11080400,
1243
+ 0x10080000, 0x10080400, 0x11080000, 0x11080400,
1244
+ 0x10080100, 0x10080500, 0x11080100, 0x11080500,
1245
+ 0x10080100, 0x10080500, 0x11080100, 0x11080500,
1246
+ 0x00000008, 0x00000408, 0x01000008, 0x01000408,
1247
+ 0x00000008, 0x00000408, 0x01000008, 0x01000408,
1248
+ 0x00000108, 0x00000508, 0x01000108, 0x01000508,
1249
+ 0x00000108, 0x00000508, 0x01000108, 0x01000508,
1250
+ 0x10000008, 0x10000408, 0x11000008, 0x11000408,
1251
+ 0x10000008, 0x10000408, 0x11000008, 0x11000408,
1252
+ 0x10000108, 0x10000508, 0x11000108, 0x11000508,
1253
+ 0x10000108, 0x10000508, 0x11000108, 0x11000508,
1254
+ 0x00080008, 0x00080408, 0x01080008, 0x01080408,
1255
+ 0x00080008, 0x00080408, 0x01080008, 0x01080408,
1256
+ 0x00080108, 0x00080508, 0x01080108, 0x01080508,
1257
+ 0x00080108, 0x00080508, 0x01080108, 0x01080508,
1258
+ 0x10080008, 0x10080408, 0x11080008, 0x11080408,
1259
+ 0x10080008, 0x10080408, 0x11080008, 0x11080408,
1260
+ 0x10080108, 0x10080508, 0x11080108, 0x11080508,
1261
+ 0x10080108, 0x10080508, 0x11080108, 0x11080508,
1262
+ 0x00001000, 0x00001400, 0x01001000, 0x01001400,
1263
+ 0x00001000, 0x00001400, 0x01001000, 0x01001400,
1264
+ 0x00001100, 0x00001500, 0x01001100, 0x01001500,
1265
+ 0x00001100, 0x00001500, 0x01001100, 0x01001500,
1266
+ 0x10001000, 0x10001400, 0x11001000, 0x11001400,
1267
+ 0x10001000, 0x10001400, 0x11001000, 0x11001400,
1268
+ 0x10001100, 0x10001500, 0x11001100, 0x11001500,
1269
+ 0x10001100, 0x10001500, 0x11001100, 0x11001500,
1270
+ 0x00081000, 0x00081400, 0x01081000, 0x01081400,
1271
+ 0x00081000, 0x00081400, 0x01081000, 0x01081400,
1272
+ 0x00081100, 0x00081500, 0x01081100, 0x01081500,
1273
+ 0x00081100, 0x00081500, 0x01081100, 0x01081500,
1274
+ 0x10081000, 0x10081400, 0x11081000, 0x11081400,
1275
+ 0x10081000, 0x10081400, 0x11081000, 0x11081400,
1276
+ 0x10081100, 0x10081500, 0x11081100, 0x11081500,
1277
+ 0x10081100, 0x10081500, 0x11081100, 0x11081500,
1278
+ 0x00001008, 0x00001408, 0x01001008, 0x01001408,
1279
+ 0x00001008, 0x00001408, 0x01001008, 0x01001408,
1280
+ 0x00001108, 0x00001508, 0x01001108, 0x01001508,
1281
+ 0x00001108, 0x00001508, 0x01001108, 0x01001508,
1282
+ 0x10001008, 0x10001408, 0x11001008, 0x11001408,
1283
+ 0x10001008, 0x10001408, 0x11001008, 0x11001408,
1284
+ 0x10001108, 0x10001508, 0x11001108, 0x11001508,
1285
+ 0x10001108, 0x10001508, 0x11001108, 0x11001508,
1286
+ 0x00081008, 0x00081408, 0x01081008, 0x01081408,
1287
+ 0x00081008, 0x00081408, 0x01081008, 0x01081408,
1288
+ 0x00081108, 0x00081508, 0x01081108, 0x01081508,
1289
+ 0x00081108, 0x00081508, 0x01081108, 0x01081508,
1290
+ 0x10081008, 0x10081408, 0x11081008, 0x11081408,
1291
+ 0x10081008, 0x10081408, 0x11081008, 0x11081408,
1292
+ 0x10081108, 0x10081508, 0x11081108, 0x11081508,
1293
+ 0x10081108, 0x10081508, 0x11081108, 0x11081508
1294
+ );
1295
+
1296
+ $keys = array();
1297
+ for ($des_round = 0; $des_round < $this->des_rounds; ++$des_round) {
1298
+ // pad the key and remove extra characters as appropriate.
1299
+ $key = str_pad(substr($this->key, $des_round * 8, 8), 8, "\0");
1300
+
1301
+ // Perform the PC/1 transformation and compute C and D.
1302
+ $t = unpack('Nl/Nr', $key);
1303
+ list($l, $r) = array($t['l'], $t['r']);
1304
+ $key = ($this->shuffle[$pc1map[ $r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x00") |
1305
+ ($this->shuffle[$pc1map[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x00") |
1306
+ ($this->shuffle[$pc1map[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x00") |
1307
+ ($this->shuffle[$pc1map[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x00") |
1308
+ ($this->shuffle[$pc1map[ $l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x00") |
1309
+ ($this->shuffle[$pc1map[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x00") |
1310
+ ($this->shuffle[$pc1map[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x00") |
1311
+ ($this->shuffle[$pc1map[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x00");
1312
+ $key = unpack('Nc/Nd', $key);
1313
+ $c = ( $key['c'] >> 4) & 0x0FFFFFFF;
1314
+ $d = (($key['d'] >> 4) & 0x0FFFFFF0) | ($key['c'] & 0x0F);
1315
+
1316
+ $keys[$des_round] = array(
1317
+ CRYPT_DES_ENCRYPT => array(),
1318
+ CRYPT_DES_DECRYPT => array_fill(0, 32, 0)
1319
+ );
1320
+ for ($i = 0, $ki = 31; $i < 16; ++$i, $ki-= 2) {
1321
+ $c <<= $shifts[$i];
1322
+ $c = ($c | ($c >> 28)) & 0x0FFFFFFF;
1323
+ $d <<= $shifts[$i];
1324
+ $d = ($d | ($d >> 28)) & 0x0FFFFFFF;
1325
+
1326
+ // Perform the PC-2 transformation.
1327
+ $cp = $pc2mapc1[ $c >> 24 ] | $pc2mapc2[($c >> 16) & 0xFF] |
1328
+ $pc2mapc3[($c >> 8) & 0xFF] | $pc2mapc4[ $c & 0xFF];
1329
+ $dp = $pc2mapd1[ $d >> 24 ] | $pc2mapd2[($d >> 16) & 0xFF] |
1330
+ $pc2mapd3[($d >> 8) & 0xFF] | $pc2mapd4[ $d & 0xFF];
1331
+
1332
+ // Reorder: odd bytes/even bytes. Push the result in key schedule.
1333
+ $val1 = ( $cp & 0xFF000000) | (($cp << 8) & 0x00FF0000) |
1334
+ (($dp >> 16) & 0x0000FF00) | (($dp >> 8) & 0x000000FF);
1335
+ $val2 = (($cp << 8) & 0xFF000000) | (($cp << 16) & 0x00FF0000) |
1336
+ (($dp >> 8) & 0x0000FF00) | ( $dp & 0x000000FF);
1337
+ $keys[$des_round][CRYPT_DES_ENCRYPT][ ] = $val1;
1338
+ $keys[$des_round][CRYPT_DES_DECRYPT][$ki - 1] = $val1;
1339
+ $keys[$des_round][CRYPT_DES_ENCRYPT][ ] = $val2;
1340
+ $keys[$des_round][CRYPT_DES_DECRYPT][$ki ] = $val2;
1341
+ }
1342
+ }
1343
+
1344
+ switch ($this->des_rounds) {
1345
+ case 3: // 3DES keys
1346
+ $this->keys = array(
1347
+ CRYPT_DES_ENCRYPT => array_merge(
1348
+ $keys[0][CRYPT_DES_ENCRYPT],
1349
+ $keys[1][CRYPT_DES_DECRYPT],
1350
+ $keys[2][CRYPT_DES_ENCRYPT]
1351
+ ),
1352
+ CRYPT_DES_DECRYPT => array_merge(
1353
+ $keys[2][CRYPT_DES_DECRYPT],
1354
+ $keys[1][CRYPT_DES_ENCRYPT],
1355
+ $keys[0][CRYPT_DES_DECRYPT]
1356
+ )
1357
+ );
1358
+ break;
1359
+ // case 1: // DES keys
1360
+ default:
1361
+ $this->keys = array(
1362
+ CRYPT_DES_ENCRYPT => $keys[0][CRYPT_DES_ENCRYPT],
1363
+ CRYPT_DES_DECRYPT => $keys[0][CRYPT_DES_DECRYPT]
1364
+ );
1365
+ }
1366
+ }
1367
+
1368
+ /**
1369
+ * Setup the performance-optimized function for de/encrypt()
1370
+ *
1371
+ * @see Crypt_Base::_setupInlineCrypt()
1372
+ * @access private
1373
+ */
1374
+ function _setupInlineCrypt()
1375
+ {
1376
+ $lambda_functions =& Crypt_DES::_getLambdaFunctions();
1377
+
1378
+ // Engine configuration for:
1379
+ // - DES ($des_rounds == 1) or
1380
+ // - 3DES ($des_rounds == 3)
1381
+ $des_rounds = $this->des_rounds;
1382
+
1383
+ // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
1384
+ // (Currently, for Crypt_DES, one generated $lambda_function cost on php5.5@32bit ~135kb unfreeable mem and ~230kb on php5.5@64bit)
1385
+ // (Currently, for Crypt_TripleDES, one generated $lambda_function cost on php5.5@32bit ~240kb unfreeable mem and ~340kb on php5.5@64bit)
1386
+ // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one
1387
+ $gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
1388
+
1389
+ // Generation of a uniqe hash for our generated code
1390
+ $code_hash = "Crypt_DES, $des_rounds, {$this->mode}";
1391
+ if ($gen_hi_opt_code) {
1392
+ // For hi-optimized code, we create for each combination of
1393
+ // $mode, $des_rounds and $this->key its own encrypt/decrypt function.
1394
+ // After max 10 hi-optimized functions, we create generic
1395
+ // (still very fast.. but not ultra) functions for each $mode/$des_rounds
1396
+ // Currently 2 * 5 generic functions will be then max. possible.
1397
+ $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
1398
+ }
1399
+
1400
+ // Is there a re-usable $lambda_functions in there? If not, we have to create it.
1401
+ if (!isset($lambda_functions[$code_hash])) {
1402
+ // Init code for both, encrypt and decrypt.
1403
+ $init_crypt = 'static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip;
1404
+ if (!$sbox1) {
1405
+ $sbox1 = array_map("intval", $self->sbox1);
1406
+ $sbox2 = array_map("intval", $self->sbox2);
1407
+ $sbox3 = array_map("intval", $self->sbox3);
1408
+ $sbox4 = array_map("intval", $self->sbox4);
1409
+ $sbox5 = array_map("intval", $self->sbox5);
1410
+ $sbox6 = array_map("intval", $self->sbox6);
1411
+ $sbox7 = array_map("intval", $self->sbox7);
1412
+ $sbox8 = array_map("intval", $self->sbox8);'
1413
+ /* Merge $shuffle with $[inv]ipmap */ . '
1414
+ for ($i = 0; $i < 256; ++$i) {
1415
+ $shuffleip[] = $self->shuffle[$self->ipmap[$i]];
1416
+ $shuffleinvip[] = $self->shuffle[$self->invipmap[$i]];
1417
+ }
1418
+ }
1419
+ ';
1420
+
1421
+ switch (true) {
1422
+ case $gen_hi_opt_code:
1423
+ // In Hi-optimized code mode, we use our [3]DES key schedule as hardcoded integers.
1424
+ // No futher initialisation of the $keys schedule is necessary.
1425
+ // That is the extra performance boost.
1426
+ $k = array(
1427
+ CRYPT_DES_ENCRYPT => $this->keys[CRYPT_DES_ENCRYPT],
1428
+ CRYPT_DES_DECRYPT => $this->keys[CRYPT_DES_DECRYPT]
1429
+ );
1430
+ $init_encrypt = '';
1431
+ $init_decrypt = '';
1432
+ break;
1433
+ default:
1434
+ // In generic optimized code mode, we have to use, as the best compromise [currently],
1435
+ // our key schedule as $ke/$kd arrays. (with hardcoded indexes...)
1436
+ $k = array(
1437
+ CRYPT_DES_ENCRYPT => array(),
1438
+ CRYPT_DES_DECRYPT => array()
1439
+ );
1440
+ for ($i = 0, $c = count($this->keys[CRYPT_DES_ENCRYPT]); $i < $c; ++$i) {
1441
+ $k[CRYPT_DES_ENCRYPT][$i] = '$ke[' . $i . ']';
1442
+ $k[CRYPT_DES_DECRYPT][$i] = '$kd[' . $i . ']';
1443
+ }
1444
+ $init_encrypt = '$ke = $self->keys[CRYPT_DES_ENCRYPT];';
1445
+ $init_decrypt = '$kd = $self->keys[CRYPT_DES_DECRYPT];';
1446
+ break;
1447
+ }
1448
+
1449
+ // Creating code for en- and decryption.
1450
+ $crypt_block = array();
1451
+ foreach (array(CRYPT_DES_ENCRYPT, CRYPT_DES_DECRYPT) as $c) {
1452
+
1453
+ /* Do the initial IP permutation. */
1454
+ $crypt_block[$c] = '
1455
+ $in = unpack("N*", $in);
1456
+ $l = $in[1];
1457
+ $r = $in[2];
1458
+ $in = unpack("N*",
1459
+ ($shuffleip[ $r & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
1460
+ ($shuffleip[($r >> 8) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
1461
+ ($shuffleip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
1462
+ ($shuffleip[($r >> 24) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
1463
+ ($shuffleip[ $l & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
1464
+ ($shuffleip[($l >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
1465
+ ($shuffleip[($l >> 16) & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
1466
+ ($shuffleip[($l >> 24) & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01")
1467
+ );
1468
+ ' . /* Extract L0 and R0 */ '
1469
+ $l = $in[1];
1470
+ $r = $in[2];
1471
+ ';
1472
+
1473
+ $l = '$l';
1474
+ $r = '$r';
1475
+
1476
+ // Perform DES or 3DES.
1477
+ for ($ki = -1, $des_round = 0; $des_round < $des_rounds; ++$des_round) {
1478
+ // Perform the 16 steps.
1479
+ for ($i = 0; $i < 16; ++$i) {
1480
+ // start of "the Feistel (F) function" - see the following URL:
1481
+ // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png
1482
+ // Merge key schedule.
1483
+ $crypt_block[$c].= '
1484
+ $b1 = ((' . $r . ' >> 3) & 0x1FFFFFFF) ^ (' . $r . ' << 29) ^ ' . $k[$c][++$ki] . ';
1485
+ $b2 = ((' . $r . ' >> 31) & 0x00000001) ^ (' . $r . ' << 1) ^ ' . $k[$c][++$ki] . ';' .
1486
+ /* S-box indexing. */
1487
+ $l . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^
1488
+ $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^
1489
+ $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^
1490
+ $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ ' . $l . ';
1491
+ ';
1492
+ // end of "the Feistel (F) function"
1493
+
1494
+ // swap L & R
1495
+ list($l, $r) = array($r, $l);
1496
+ }
1497
+ list($l, $r) = array($r, $l);
1498
+ }
1499
+
1500
+ // Perform the inverse IP permutation.
1501
+ $crypt_block[$c].= '$in =
1502
+ ($shuffleinvip[($l >> 24) & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
1503
+ ($shuffleinvip[($r >> 24) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
1504
+ ($shuffleinvip[($l >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
1505
+ ($shuffleinvip[($r >> 16) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
1506
+ ($shuffleinvip[($l >> 8) & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
1507
+ ($shuffleinvip[($r >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
1508
+ ($shuffleinvip[ $l & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
1509
+ ($shuffleinvip[ $r & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01");
1510
+ ';
1511
+ }
1512
+
1513
+ // Creates the inline-crypt function
1514
+ $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
1515
+ array(
1516
+ 'init_crypt' => $init_crypt,
1517
+ 'init_encrypt' => $init_encrypt,
1518
+ 'init_decrypt' => $init_decrypt,
1519
+ 'encrypt_block' => $crypt_block[CRYPT_DES_ENCRYPT],
1520
+ 'decrypt_block' => $crypt_block[CRYPT_DES_DECRYPT]
1521
+ )
1522
+ );
1523
+ }
1524
+
1525
+ // Set the inline-crypt function as callback in: $this->inline_crypt
1526
+ $this->inline_crypt = $lambda_functions[$code_hash];
1527
+ }
1528
+ }
phpseclib/Crypt/Hash.php CHANGED
@@ -1,841 +1,841 @@
1
- <?php
2
-
3
- /**
4
- * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
5
- *
6
- * Uses hash() or mhash() if available and an internal implementation, otherwise. Currently supports the following:
7
- *
8
- * md2, md5, md5-96, sha1, sha1-96, sha256, sha256-96, sha384, and sha512, sha512-96
9
- *
10
- * If {@link Crypt_Hash::setKey() setKey()} is called, {@link Crypt_Hash::hash() hash()} will return the HMAC as opposed to
11
- * the hash. If no valid algorithm is provided, sha1 will be used.
12
- *
13
- * PHP versions 4 and 5
14
- *
15
- * {@internal The variable names are the same as those in
16
- * {@link http://tools.ietf.org/html/rfc2104#section-2 RFC2104}.}}
17
- *
18
- * Here's a short example of how to use this library:
19
- * <code>
20
- * <?php
21
- * include 'Crypt/Hash.php';
22
- *
23
- * $hash = new Crypt_Hash('sha1');
24
- *
25
- * $hash->setKey('abcdefg');
26
- *
27
- * echo base64_encode($hash->hash('abcdefg'));
28
- * ?>
29
- * </code>
30
- *
31
- * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
32
- * of this software and associated documentation files (the "Software"), to deal
33
- * in the Software without restriction, including without limitation the rights
34
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
35
- * copies of the Software, and to permit persons to whom the Software is
36
- * furnished to do so, subject to the following conditions:
37
- *
38
- * The above copyright notice and this permission notice shall be included in
39
- * all copies or substantial portions of the Software.
40
- *
41
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
44
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
46
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
47
- * THE SOFTWARE.
48
- *
49
- * @category Crypt
50
- * @package Crypt_Hash
51
- * @author Jim Wigginton <terrafrost@php.net>
52
- * @copyright MMVII Jim Wigginton
53
- * @license http://www.opensource.org/licenses/mit-license.html MIT License
54
- * @link http://phpseclib.sourceforge.net
55
- */
56
-
57
- /**#@+
58
- * @access private
59
- * @see Crypt_Hash::Crypt_Hash()
60
- */
61
- /**
62
- * Toggles the internal implementation
63
- */
64
- define('CRYPT_HASH_MODE_INTERNAL', 1);
65
- /**
66
- * Toggles the mhash() implementation, which has been deprecated on PHP 5.3.0+.
67
- */
68
- define('CRYPT_HASH_MODE_MHASH', 2);
69
- /**
70
- * Toggles the hash() implementation, which works on PHP 5.1.2+.
71
- */
72
- define('CRYPT_HASH_MODE_HASH', 3);
73
- /**#@-*/
74
-
75
- /**
76
- * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
77
- *
78
- * @package Crypt_Hash
79
- * @author Jim Wigginton <terrafrost@php.net>
80
- * @access public
81
- */
82
- class Crypt_Hash
83
- {
84
- /**
85
- * Hash Parameter
86
- *
87
- * @see Crypt_Hash::setHash()
88
- * @var Integer
89
- * @access private
90
- */
91
- var $hashParam;
92
-
93
- /**
94
- * Byte-length of compression blocks / key (Internal HMAC)
95
- *
96
- * @see Crypt_Hash::setAlgorithm()
97
- * @var Integer
98
- * @access private
99
- */
100
- var $b;
101
-
102
- /**
103
- * Byte-length of hash output (Internal HMAC)
104
- *
105
- * @see Crypt_Hash::setHash()
106
- * @var Integer
107
- * @access private
108
- */
109
- var $l = false;
110
-
111
- /**
112
- * Hash Algorithm
113
- *
114
- * @see Crypt_Hash::setHash()
115
- * @var String
116
- * @access private
117
- */
118
- var $hash;
119
-
120
- /**
121
- * Key
122
- *
123
- * @see Crypt_Hash::setKey()
124
- * @var String
125
- * @access private
126
- */
127
- var $key = false;
128
-
129
- /**
130
- * Outer XOR (Internal HMAC)
131
- *
132
- * @see Crypt_Hash::setKey()
133
- * @var String
134
- * @access private
135
- */
136
- var $opad;
137
-
138
- /**
139
- * Inner XOR (Internal HMAC)
140
- *
141
- * @see Crypt_Hash::setKey()
142
- * @var String
143
- * @access private
144
- */
145
- var $ipad;
146
-
147
- /**
148
- * Default Constructor.
149
- *
150
- * @param optional String $hash
151
- * @return Crypt_Hash
152
- * @access public
153
- */
154
- function Crypt_Hash($hash = 'sha1')
155
- {
156
- if ( !defined('CRYPT_HASH_MODE') ) {
157
- switch (true) {
158
- case extension_loaded('hash'):
159
- define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_HASH);
160
- break;
161
- case extension_loaded('mhash'):
162
- define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_MHASH);
163
- break;
164
- default:
165
- define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_INTERNAL);
166
- }
167
- }
168
-
169
- $this->setHash($hash);
170
- }
171
-
172
- /**
173
- * Sets the key for HMACs
174
- *
175
- * Keys can be of any length.
176
- *
177
- * @access public
178
- * @param optional String $key
179
- */
180
- function setKey($key = false)
181
- {
182
- $this->key = $key;
183
- }
184
-
185
- /**
186
- * Gets the hash function.
187
- *
188
- * As set by the constructor or by the setHash() method.
189
- *
190
- * @access public
191
- * @return String
192
- */
193
- function getHash()
194
- {
195
- return $this->hashParam;
196
- }
197
-
198
- /**
199
- * Sets the hash function.
200
- *
201
- * @access public
202
- * @param String $hash
203
- */
204
- function setHash($hash)
205
- {
206
- $this->hashParam = $hash = strtolower($hash);
207
- switch ($hash) {
208
- case 'md5-96':
209
- case 'sha1-96':
210
- case 'sha256-96':
211
- case 'sha512-96':
212
- $hash = substr($hash, 0, -3);
213
- $this->l = 12; // 96 / 8 = 12
214
- break;
215
- case 'md2':
216
- case 'md5':
217
- $this->l = 16;
218
- break;
219
- case 'sha1':
220
- $this->l = 20;
221
- break;
222
- case 'sha256':
223
- $this->l = 32;
224
- break;
225
- case 'sha384':
226
- $this->l = 48;
227
- break;
228
- case 'sha512':
229
- $this->l = 64;
230
- }
231
-
232
- switch ($hash) {
233
- case 'md2':
234
- $mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_HASH && in_array('md2', hash_algos()) ?
235
- CRYPT_HASH_MODE_HASH : CRYPT_HASH_MODE_INTERNAL;
236
- break;
237
- case 'sha384':
238
- case 'sha512':
239
- $mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_MHASH ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
240
- break;
241
- default:
242
- $mode = CRYPT_HASH_MODE;
243
- }
244
-
245
- switch ( $mode ) {
246
- case CRYPT_HASH_MODE_MHASH:
247
- switch ($hash) {
248
- case 'md5':
249
- $this->hash = MHASH_MD5;
250
- break;
251
- case 'sha256':
252
- $this->hash = MHASH_SHA256;
253
- break;
254
- case 'sha1':
255
- default:
256
- $this->hash = MHASH_SHA1;
257
- }
258
- return;
259
- case CRYPT_HASH_MODE_HASH:
260
- switch ($hash) {
261
- case 'md5':
262
- $this->hash = 'md5';
263
- return;
264
- case 'md2':
265
- case 'sha256':
266
- case 'sha384':
267
- case 'sha512':
268
- $this->hash = $hash;
269
- return;
270
- case 'sha1':
271
- default:
272
- $this->hash = 'sha1';
273
- }
274
- return;
275
- }
276
-
277
- switch ($hash) {
278
- case 'md2':
279
- $this->b = 16;
280
- $this->hash = array($this, '_md2');
281
- break;
282
- case 'md5':
283
- $this->b = 64;
284
- $this->hash = array($this, '_md5');
285
- break;
286
- case 'sha256':
287
- $this->b = 64;
288
- $this->hash = array($this, '_sha256');
289
- break;
290
- case 'sha384':
291
- case 'sha512':
292
- $this->b = 128;
293
- $this->hash = array($this, '_sha512');
294
- break;
295
- case 'sha1':
296
- default:
297
- $this->b = 64;
298
- $this->hash = array($this, '_sha1');
299
- }
300
-
301
- $this->ipad = str_repeat(chr(0x36), $this->b);
302
- $this->opad = str_repeat(chr(0x5C), $this->b);
303
- }
304
-
305
- /**
306
- * Compute the HMAC.
307
- *
308
- * @access public
309
- * @param String $text
310
- * @return String
311
- */
312
- function hash($text)
313
- {
314
- $mode = is_array($this->hash) ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
315
-
316
- if (!empty($this->key) || is_string($this->key)) {
317
- switch ( $mode ) {
318
- case CRYPT_HASH_MODE_MHASH:
319
- $output = mhash($this->hash, $text, $this->key);
320
- break;
321
- case CRYPT_HASH_MODE_HASH:
322
- $output = hash_hmac($this->hash, $text, $this->key, true);
323
- break;
324
- case CRYPT_HASH_MODE_INTERNAL:
325
- /* "Applications that use keys longer than B bytes will first hash the key using H and then use the
326
- resultant L byte string as the actual key to HMAC."
327
-
328
- -- http://tools.ietf.org/html/rfc2104#section-2 */
329
- $key = strlen($this->key) > $this->b ? call_user_func($this->hash, $this->key) : $this->key;
330
-
331
- $key = str_pad($key, $this->b, chr(0)); // step 1
332
- $temp = $this->ipad ^ $key; // step 2
333
- $temp .= $text; // step 3
334
- $temp = call_user_func($this->hash, $temp); // step 4
335
- $output = $this->opad ^ $key; // step 5
336
- $output.= $temp; // step 6
337
- $output = call_user_func($this->hash, $output); // step 7
338
- }
339
- } else {
340
- switch ( $mode ) {
341
- case CRYPT_HASH_MODE_MHASH:
342
- $output = mhash($this->hash, $text);
343
- break;
344
- case CRYPT_HASH_MODE_HASH:
345
- $output = hash($this->hash, $text, true);
346
- break;
347
- case CRYPT_HASH_MODE_INTERNAL:
348
- $output = call_user_func($this->hash, $text);
349
- }
350
- }
351
-
352
- return substr($output, 0, $this->l);
353
- }
354
-
355
- /**
356
- * Returns the hash length (in bytes)
357
- *
358
- * @access public
359
- * @return Integer
360
- */
361
- function getLength()
362
- {
363
- return $this->l;
364
- }
365
-
366
- /**
367
- * Wrapper for MD5
368
- *
369
- * @access private
370
- * @param String $m
371
- */
372
- function _md5($m)
373
- {
374
- return pack('H*', md5($m));
375
- }
376
-
377
- /**
378
- * Wrapper for SHA1
379
- *
380
- * @access private
381
- * @param String $m
382
- */
383
- function _sha1($m)
384
- {
385
- return pack('H*', sha1($m));
386
- }
387
-
388
- /**
389
- * Pure-PHP implementation of MD2
390
- *
391
- * See {@link http://tools.ietf.org/html/rfc1319 RFC1319}.
392
- *
393
- * @access private
394
- * @param String $m
395
- */
396
- function _md2($m)
397
- {
398
- static $s = array(
399
- 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
400
- 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
401
- 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
402
- 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
403
- 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
404
- 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
405
- 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
406
- 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
407
- 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
408
- 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
409
- 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
410
- 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
411
- 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
412
- 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
413
- 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
414
- 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
415
- 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
416
- 31, 26, 219, 153, 141, 51, 159, 17, 131, 20
417
- );
418
-
419
- // Step 1. Append Padding Bytes
420
- $pad = 16 - (strlen($m) & 0xF);
421
- $m.= str_repeat(chr($pad), $pad);
422
-
423
- $length = strlen($m);
424
-
425
- // Step 2. Append Checksum
426
- $c = str_repeat(chr(0), 16);
427
- $l = chr(0);
428
- for ($i = 0; $i < $length; $i+= 16) {
429
- for ($j = 0; $j < 16; $j++) {
430
- // RFC1319 incorrectly states that C[j] should be set to S[c xor L]
431
- //$c[$j] = chr($s[ord($m[$i + $j] ^ $l)]);
432
- // per <http://www.rfc-editor.org/errata_search.php?rfc=1319>, however, C[j] should be set to S[c xor L] xor C[j]
433
- $c[$j] = chr($s[ord($m[$i + $j] ^ $l)] ^ ord($c[$j]));
434
- $l = $c[$j];
435
- }
436
- }
437
- $m.= $c;
438
-
439
- $length+= 16;
440
-
441
- // Step 3. Initialize MD Buffer
442
- $x = str_repeat(chr(0), 48);
443
-
444
- // Step 4. Process Message in 16-Byte Blocks
445
- for ($i = 0; $i < $length; $i+= 16) {
446
- for ($j = 0; $j < 16; $j++) {
447
- $x[$j + 16] = $m[$i + $j];
448
- $x[$j + 32] = $x[$j + 16] ^ $x[$j];
449
- }
450
- $t = chr(0);
451
- for ($j = 0; $j < 18; $j++) {
452
- for ($k = 0; $k < 48; $k++) {
453
- $x[$k] = $t = $x[$k] ^ chr($s[ord($t)]);
454
- //$t = $x[$k] = $x[$k] ^ chr($s[ord($t)]);
455
- }
456
- $t = chr(ord($t) + $j);
457
- }
458
- }
459
-
460
- // Step 5. Output
461
- return substr($x, 0, 16);
462
- }
463
-
464
- /**
465
- * Pure-PHP implementation of SHA256
466
- *
467
- * See {@link http://en.wikipedia.org/wiki/SHA_hash_functions#SHA-256_.28a_SHA-2_variant.29_pseudocode SHA-256 (a SHA-2 variant) pseudocode - Wikipedia}.
468
- *
469
- * @access private
470
- * @param String $m
471
- */
472
- function _sha256($m)
473
- {
474
- if (extension_loaded('suhosin')) {
475
- return pack('H*', sha256($m));
476
- }
477
-
478
- // Initialize variables
479
- $hash = array(
480
- 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
481
- );
482
- // Initialize table of round constants
483
- // (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)
484
- static $k = array(
485
- 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
486
- 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
487
- 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
488
- 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
489
- 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
490
- 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
491
- 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
492
- 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
493
- );
494
-
495
- // Pre-processing
496
- $length = strlen($m);
497
- // to round to nearest 56 mod 64, we'll add 64 - (length + (64 - 56)) % 64
498
- $m.= str_repeat(chr(0), 64 - (($length + 8) & 0x3F));
499
- $m[$length] = chr(0x80);
500
- // we don't support hashing strings 512MB long
501
- $m.= pack('N2', 0, $length << 3);
502
-
503
- // Process the message in successive 512-bit chunks
504
- $chunks = str_split($m, 64);
505
- foreach ($chunks as $chunk) {
506
- $w = array();
507
- for ($i = 0; $i < 16; $i++) {
508
- extract(unpack('Ntemp', $this->_string_shift($chunk, 4)));
509
- $w[] = $temp;
510
- }
511
-
512
- // Extend the sixteen 32-bit words into sixty-four 32-bit words
513
- for ($i = 16; $i < 64; $i++) {
514
- $s0 = $this->_rightRotate($w[$i - 15], 7) ^
515
- $this->_rightRotate($w[$i - 15], 18) ^
516
- $this->_rightShift( $w[$i - 15], 3);
517
- $s1 = $this->_rightRotate($w[$i - 2], 17) ^
518
- $this->_rightRotate($w[$i - 2], 19) ^
519
- $this->_rightShift( $w[$i - 2], 10);
520
- $w[$i] = $this->_add($w[$i - 16], $s0, $w[$i - 7], $s1);
521
-
522
- }
523
-
524
- // Initialize hash value for this chunk
525
- list($a, $b, $c, $d, $e, $f, $g, $h) = $hash;
526
-
527
- // Main loop
528
- for ($i = 0; $i < 64; $i++) {
529
- $s0 = $this->_rightRotate($a, 2) ^
530
- $this->_rightRotate($a, 13) ^
531
- $this->_rightRotate($a, 22);
532
- $maj = ($a & $b) ^
533
- ($a & $c) ^
534
- ($b & $c);
535
- $t2 = $this->_add($s0, $maj);
536
-
537
- $s1 = $this->_rightRotate($e, 6) ^
538
- $this->_rightRotate($e, 11) ^
539
- $this->_rightRotate($e, 25);
540
- $ch = ($e & $f) ^
541
- ($this->_not($e) & $g);
542
- $t1 = $this->_add($h, $s1, $ch, $k[$i], $w[$i]);
543
-
544
- $h = $g;
545
- $g = $f;
546
- $f = $e;
547
- $e = $this->_add($d, $t1);
548
- $d = $c;
549
- $c = $b;
550
- $b = $a;
551
- $a = $this->_add($t1, $t2);
552
- }
553
-
554
- // Add this chunk's hash to result so far
555
- $hash = array(
556
- $this->_add($hash[0], $a),
557
- $this->_add($hash[1], $b),
558
- $this->_add($hash[2], $c),
559
- $this->_add($hash[3], $d),
560
- $this->_add($hash[4], $e),
561
- $this->_add($hash[5], $f),
562
- $this->_add($hash[6], $g),
563
- $this->_add($hash[7], $h)
564
- );
565
- }
566
-
567
- // Produce the final hash value (big-endian)
568
- return pack('N8', $hash[0], $hash[1], $hash[2], $hash[3], $hash[4], $hash[5], $hash[6], $hash[7]);
569
- }
570
-
571
- /**
572
- * Pure-PHP implementation of SHA384 and SHA512
573
- *
574
- * @access private
575
- * @param String $m
576
- */
577
- function _sha512($m)
578
- {
579
- if (!class_exists('Math_BigInteger')) {
580
- include_once 'Math/BigInteger.php';
581
- }
582
-
583
- static $init384, $init512, $k;
584
-
585
- if (!isset($k)) {
586
- // Initialize variables
587
- $init384 = array( // initial values for SHA384
588
- 'cbbb9d5dc1059ed8', '629a292a367cd507', '9159015a3070dd17', '152fecd8f70e5939',
589
- '67332667ffc00b31', '8eb44a8768581511', 'db0c2e0d64f98fa7', '47b5481dbefa4fa4'
590
- );
591
- $init512 = array( // initial values for SHA512
592
- '6a09e667f3bcc908', 'bb67ae8584caa73b', '3c6ef372fe94f82b', 'a54ff53a5f1d36f1',
593
- '510e527fade682d1', '9b05688c2b3e6c1f', '1f83d9abfb41bd6b', '5be0cd19137e2179'
594
- );
595
-
596
- for ($i = 0; $i < 8; $i++) {
597
- $init384[$i] = new Math_BigInteger($init384[$i], 16);
598
- $init384[$i]->setPrecision(64);
599
- $init512[$i] = new Math_BigInteger($init512[$i], 16);
600
- $init512[$i]->setPrecision(64);
601
- }
602
-
603
- // Initialize table of round constants
604
- // (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409)
605
- $k = array(
606
- '428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc',
607
- '3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118',
608
- 'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2',
609
- '72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694',
610
- 'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65',
611
- '2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5',
612
- '983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4',
613
- 'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70',
614
- '27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df',
615
- '650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b',
616
- 'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30',
617
- 'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8',
618
- '19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8',
619
- '391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3',
620
- '748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec',
621
- '90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b',
622
- 'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178',
623
- '06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b',
624
- '28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c',
625
- '4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817'
626
- );
627
-
628
- for ($i = 0; $i < 80; $i++) {
629
- $k[$i] = new Math_BigInteger($k[$i], 16);
630
- }
631
- }
632
-
633
- $hash = $this->l == 48 ? $init384 : $init512;
634
-
635
- // Pre-processing
636
- $length = strlen($m);
637
- // to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128
638
- $m.= str_repeat(chr(0), 128 - (($length + 16) & 0x7F));
639
- $m[$length] = chr(0x80);
640
- // we don't support hashing strings 512MB long
641
- $m.= pack('N4', 0, 0, 0, $length << 3);
642
-
643
- // Process the message in successive 1024-bit chunks
644
- $chunks = str_split($m, 128);
645
- foreach ($chunks as $chunk) {
646
- $w = array();
647
- for ($i = 0; $i < 16; $i++) {
648
- $temp = new Math_BigInteger($this->_string_shift($chunk, 8), 256);
649
- $temp->setPrecision(64);
650
- $w[] = $temp;
651
- }
652
-
653
- // Extend the sixteen 32-bit words into eighty 32-bit words
654
- for ($i = 16; $i < 80; $i++) {
655
- $temp = array(
656
- $w[$i - 15]->bitwise_rightRotate(1),
657
- $w[$i - 15]->bitwise_rightRotate(8),
658
- $w[$i - 15]->bitwise_rightShift(7)
659
- );
660
- $s0 = $temp[0]->bitwise_xor($temp[1]);
661
- $s0 = $s0->bitwise_xor($temp[2]);
662
- $temp = array(
663
- $w[$i - 2]->bitwise_rightRotate(19),
664
- $w[$i - 2]->bitwise_rightRotate(61),
665
- $w[$i - 2]->bitwise_rightShift(6)
666
- );
667
- $s1 = $temp[0]->bitwise_xor($temp[1]);
668
- $s1 = $s1->bitwise_xor($temp[2]);
669
- $w[$i] = $w[$i - 16]->copy();
670
- $w[$i] = $w[$i]->add($s0);
671
- $w[$i] = $w[$i]->add($w[$i - 7]);
672
- $w[$i] = $w[$i]->add($s1);
673
- }
674
-
675
- // Initialize hash value for this chunk
676
- $a = $hash[0]->copy();
677
- $b = $hash[1]->copy();
678
- $c = $hash[2]->copy();
679
- $d = $hash[3]->copy();
680
- $e = $hash[4]->copy();
681
- $f = $hash[5]->copy();
682
- $g = $hash[6]->copy();
683
- $h = $hash[7]->copy();
684
-
685
- // Main loop
686
- for ($i = 0; $i < 80; $i++) {
687
- $temp = array(
688
- $a->bitwise_rightRotate(28),
689
- $a->bitwise_rightRotate(34),
690
- $a->bitwise_rightRotate(39)
691
- );
692
- $s0 = $temp[0]->bitwise_xor($temp[1]);
693
- $s0 = $s0->bitwise_xor($temp[2]);
694
- $temp = array(
695
- $a->bitwise_and($b),
696
- $a->bitwise_and($c),
697
- $b->bitwise_and($c)
698
- );
699
- $maj = $temp[0]->bitwise_xor($temp[1]);
700
- $maj = $maj->bitwise_xor($temp[2]);
701
- $t2 = $s0->add($maj);
702
-
703
- $temp = array(
704
- $e->bitwise_rightRotate(14),
705
- $e->bitwise_rightRotate(18),
706
- $e->bitwise_rightRotate(41)
707
- );
708
- $s1 = $temp[0]->bitwise_xor($temp[1]);
709
- $s1 = $s1->bitwise_xor($temp[2]);
710
- $temp = array(
711
- $e->bitwise_and($f),
712
- $g->bitwise_and($e->bitwise_not())
713
- );
714
- $ch = $temp[0]->bitwise_xor($temp[1]);
715
- $t1 = $h->add($s1);
716
- $t1 = $t1->add($ch);
717
- $t1 = $t1->add($k[$i]);
718
- $t1 = $t1->add($w[$i]);
719
-
720
- $h = $g->copy();
721
- $g = $f->copy();
722
- $f = $e->copy();
723
- $e = $d->add($t1);
724
- $d = $c->copy();
725
- $c = $b->copy();
726
- $b = $a->copy();
727
- $a = $t1->add($t2);
728
- }
729
-
730
- // Add this chunk's hash to result so far
731
- $hash = array(
732
- $hash[0]->add($a),
733
- $hash[1]->add($b),
734
- $hash[2]->add($c),
735
- $hash[3]->add($d),
736
- $hash[4]->add($e),
737
- $hash[5]->add($f),
738
- $hash[6]->add($g),
739
- $hash[7]->add($h)
740
- );
741
- }
742
-
743
- // Produce the final hash value (big-endian)
744
- // (Crypt_Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here)
745
- $temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() .
746
- $hash[4]->toBytes() . $hash[5]->toBytes();
747
- if ($this->l != 48) {
748
- $temp.= $hash[6]->toBytes() . $hash[7]->toBytes();
749
- }
750
-
751
- return $temp;
752
- }
753
-
754
- /**
755
- * Right Rotate
756
- *
757
- * @access private
758
- * @param Integer $int
759
- * @param Integer $amt
760
- * @see _sha256()
761
- * @return Integer
762
- */
763
- function _rightRotate($int, $amt)
764
- {
765
- $invamt = 32 - $amt;
766
- $mask = (1 << $invamt) - 1;
767
- return (($int << $invamt) & 0xFFFFFFFF) | (($int >> $amt) & $mask);
768
- }
769
-
770
- /**
771
- * Right Shift
772
- *
773
- * @access private
774
- * @param Integer $int
775
- * @param Integer $amt
776
- * @see _sha256()
777
- * @return Integer
778
- */
779
- function _rightShift($int, $amt)
780
- {
781
- $mask = (1 << (32 - $amt)) - 1;
782
- return ($int >> $amt) & $mask;
783
- }
784
-
785
- /**
786
- * Not
787
- *
788
- * @access private
789
- * @param Integer $int
790
- * @see _sha256()
791
- * @return Integer
792
- */
793
- function _not($int)
794
- {
795
- return ~$int & 0xFFFFFFFF;
796
- }
797
-
798
- /**
799
- * Add
800
- *
801
- * _sha256() adds multiple unsigned 32-bit integers. Since PHP doesn't support unsigned integers and since the
802
- * possibility of overflow exists, care has to be taken. Math_BigInteger() could be used but this should be faster.
803
- *
804
- * @param Integer $...
805
- * @return Integer
806
- * @see _sha256()
807
- * @access private
808
- */
809
- function _add()
810
- {
811
- static $mod;
812
- if (!isset($mod)) {
813
- $mod = pow(2, 32);
814
- }
815
-
816
- $result = 0;
817
- $arguments = func_get_args();
818
- foreach ($arguments as $argument) {
819
- $result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;
820
- }
821
-
822
- return fmod($result, $mod);
823
- }
824
-
825
- /**
826
- * String Shift
827
- *
828
- * Inspired by array_shift
829
- *
830
- * @param String $string
831
- * @param optional Integer $index
832
- * @return String
833
- * @access private
834
- */
835
- function _string_shift(&$string, $index = 1)
836
- {
837
- $substr = substr($string, 0, $index);
838
- $string = substr($string, $index);
839
- return $substr;
840
- }
841
- }
1
+ <?php
2
+
3
+ /**
4
+ * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
5
+ *
6
+ * Uses hash() or mhash() if available and an internal implementation, otherwise. Currently supports the following:
7
+ *
8
+ * md2, md5, md5-96, sha1, sha1-96, sha256, sha256-96, sha384, and sha512, sha512-96
9
+ *
10
+ * If {@link Crypt_Hash::setKey() setKey()} is called, {@link Crypt_Hash::hash() hash()} will return the HMAC as opposed to
11
+ * the hash. If no valid algorithm is provided, sha1 will be used.
12
+ *
13
+ * PHP versions 4 and 5
14
+ *
15
+ * {@internal The variable names are the same as those in
16
+ * {@link http://tools.ietf.org/html/rfc2104#section-2 RFC2104}.}}
17
+ *
18
+ * Here's a short example of how to use this library:
19
+ * <code>
20
+ * <?php
21
+ * include 'Crypt/Hash.php';
22
+ *
23
+ * $hash = new Crypt_Hash('sha1');
24
+ *
25
+ * $hash->setKey('abcdefg');
26
+ *
27
+ * echo base64_encode($hash->hash('abcdefg'));
28
+ * ?>
29
+ * </code>
30
+ *
31
+ * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
32
+ * of this software and associated documentation files (the "Software"), to deal
33
+ * in the Software without restriction, including without limitation the rights
34
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
35
+ * copies of the Software, and to permit persons to whom the Software is
36
+ * furnished to do so, subject to the following conditions:
37
+ *
38
+ * The above copyright notice and this permission notice shall be included in
39
+ * all copies or substantial portions of the Software.
40
+ *
41
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
44
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
46
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
47
+ * THE SOFTWARE.
48
+ *
49
+ * @category Crypt
50
+ * @package Crypt_Hash
51
+ * @author Jim Wigginton <terrafrost@php.net>
52
+ * @copyright 2007 Jim Wigginton
53
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
54
+ * @link http://phpseclib.sourceforge.net
55
+ */
56
+
57
+ /**#@+
58
+ * @access private
59
+ * @see Crypt_Hash::Crypt_Hash()
60
+ */
61
+ /**
62
+ * Toggles the internal implementation
63
+ */
64
+ define('CRYPT_HASH_MODE_INTERNAL', 1);
65
+ /**
66
+ * Toggles the mhash() implementation, which has been deprecated on PHP 5.3.0+.
67
+ */
68
+ define('CRYPT_HASH_MODE_MHASH', 2);
69
+ /**
70
+ * Toggles the hash() implementation, which works on PHP 5.1.2+.
71
+ */
72
+ define('CRYPT_HASH_MODE_HASH', 3);
73
+ /**#@-*/
74
+
75
+ /**
76
+ * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
77
+ *
78
+ * @package Crypt_Hash
79
+ * @author Jim Wigginton <terrafrost@php.net>
80
+ * @access public
81
+ */
82
+ class Crypt_Hash
83
+ {
84
+ /**
85
+ * Hash Parameter
86
+ *
87
+ * @see Crypt_Hash::setHash()
88
+ * @var Integer
89
+ * @access private
90
+ */
91
+ var $hashParam;
92
+
93
+ /**
94
+ * Byte-length of compression blocks / key (Internal HMAC)
95
+ *
96
+ * @see Crypt_Hash::setAlgorithm()
97
+ * @var Integer
98
+ * @access private
99
+ */
100
+ var $b;
101
+
102
+ /**
103
+ * Byte-length of hash output (Internal HMAC)
104
+ *
105
+ * @see Crypt_Hash::setHash()
106
+ * @var Integer
107
+ * @access private
108
+ */
109
+ var $l = false;
110
+
111
+ /**
112
+ * Hash Algorithm
113
+ *
114
+ * @see Crypt_Hash::setHash()
115
+ * @var String
116
+ * @access private
117
+ */
118
+ var $hash;
119
+
120
+ /**
121
+ * Key
122
+ *
123
+ * @see Crypt_Hash::setKey()
124
+ * @var String
125
+ * @access private
126
+ */
127
+ var $key = false;
128
+
129
+ /**
130
+ * Outer XOR (Internal HMAC)
131
+ *
132
+ * @see Crypt_Hash::setKey()
133
+ * @var String
134
+ * @access private
135
+ */
136
+ var $opad;
137
+
138
+ /**
139
+ * Inner XOR (Internal HMAC)
140
+ *
141
+ * @see Crypt_Hash::setKey()
142
+ * @var String
143
+ * @access private
144
+ */
145
+ var $ipad;
146
+
147
+ /**
148
+ * Default Constructor.
149
+ *
150
+ * @param optional String $hash
151
+ * @return Crypt_Hash
152
+ * @access public
153
+ */
154
+ function Crypt_Hash($hash = 'sha1')
155
+ {
156
+ if ( !defined('CRYPT_HASH_MODE') ) {
157
+ switch (true) {
158
+ case extension_loaded('hash'):
159
+ define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_HASH);
160
+ break;
161
+ case extension_loaded('mhash'):
162
+ define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_MHASH);
163
+ break;
164
+ default:
165
+ define('CRYPT_HASH_MODE', CRYPT_HASH_MODE_INTERNAL);
166
+ }
167
+ }
168
+
169
+ $this->setHash($hash);
170
+ }
171
+
172
+ /**
173
+ * Sets the key for HMACs
174
+ *
175
+ * Keys can be of any length.
176
+ *
177
+ * @access public
178
+ * @param optional String $key
179
+ */
180
+ function setKey($key = false)
181
+ {
182
+ $this->key = $key;
183
+ }
184
+
185
+ /**
186
+ * Gets the hash function.
187
+ *
188
+ * As set by the constructor or by the setHash() method.
189
+ *
190
+ * @access public
191
+ * @return String
192
+ */
193
+ function getHash()
194
+ {
195
+ return $this->hashParam;
196
+ }
197
+
198
+ /**
199
+ * Sets the hash function.
200
+ *
201
+ * @access public
202
+ * @param String $hash
203
+ */
204
+ function setHash($hash)
205
+ {
206
+ $this->hashParam = $hash = strtolower($hash);
207
+ switch ($hash) {
208
+ case 'md5-96':
209
+ case 'sha1-96':
210
+ case 'sha256-96':
211
+ case 'sha512-96':
212
+ $hash = substr($hash, 0, -3);
213
+ $this->l = 12; // 96 / 8 = 12
214
+ break;
215
+ case 'md2':
216
+ case 'md5':
217
+ $this->l = 16;
218
+ break;
219
+ case 'sha1':
220
+ $this->l = 20;
221
+ break;
222
+ case 'sha256':
223
+ $this->l = 32;
224
+ break;
225
+ case 'sha384':
226
+ $this->l = 48;
227
+ break;
228
+ case 'sha512':
229
+ $this->l = 64;
230
+ }
231
+
232
+ switch ($hash) {
233
+ case 'md2':
234
+ $mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_HASH && in_array('md2', hash_algos()) ?
235
+ CRYPT_HASH_MODE_HASH : CRYPT_HASH_MODE_INTERNAL;
236
+ break;
237
+ case 'sha384':
238
+ case 'sha512':
239
+ $mode = CRYPT_HASH_MODE == CRYPT_HASH_MODE_MHASH ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
240
+ break;
241
+ default:
242
+ $mode = CRYPT_HASH_MODE;
243
+ }
244
+
245
+ switch ( $mode ) {
246
+ case CRYPT_HASH_MODE_MHASH:
247
+ switch ($hash) {
248
+ case 'md5':
249
+ $this->hash = MHASH_MD5;
250
+ break;
251
+ case 'sha256':
252
+ $this->hash = MHASH_SHA256;
253
+ break;
254
+ case 'sha1':
255
+ default:
256
+ $this->hash = MHASH_SHA1;
257
+ }
258
+ return;
259
+ case CRYPT_HASH_MODE_HASH:
260
+ switch ($hash) {
261
+ case 'md5':
262
+ $this->hash = 'md5';
263
+ return;
264
+ case 'md2':
265
+ case 'sha256':
266
+ case 'sha384':
267
+ case 'sha512':
268
+ $this->hash = $hash;
269
+ return;
270
+ case 'sha1':
271
+ default:
272
+ $this->hash = 'sha1';
273
+ }
274
+ return;
275
+ }
276
+
277
+ switch ($hash) {
278
+ case 'md2':
279
+ $this->b = 16;
280
+ $this->hash = array($this, '_md2');
281
+ break;
282
+ case 'md5':
283
+ $this->b = 64;
284
+ $this->hash = array($this, '_md5');
285
+ break;
286
+ case 'sha256':
287
+ $this->b = 64;
288
+ $this->hash = array($this, '_sha256');
289
+ break;
290
+ case 'sha384':
291
+ case 'sha512':
292
+ $this->b = 128;
293
+ $this->hash = array($this, '_sha512');
294
+ break;
295
+ case 'sha1':
296
+ default:
297
+ $this->b = 64;
298
+ $this->hash = array($this, '_sha1');
299
+ }
300
+
301
+ $this->ipad = str_repeat(chr(0x36), $this->b);
302
+ $this->opad = str_repeat(chr(0x5C), $this->b);
303
+ }
304
+
305
+ /**
306
+ * Compute the HMAC.
307
+ *
308
+ * @access public
309
+ * @param String $text
310
+ * @return String
311
+ */
312
+ function hash($text)
313
+ {
314
+ $mode = is_array($this->hash) ? CRYPT_HASH_MODE_INTERNAL : CRYPT_HASH_MODE;
315
+
316
+ if (!empty($this->key) || is_string($this->key)) {
317
+ switch ( $mode ) {
318
+ case CRYPT_HASH_MODE_MHASH:
319
+ $output = mhash($this->hash, $text, $this->key);
320
+ break;
321
+ case CRYPT_HASH_MODE_HASH:
322
+ $output = hash_hmac($this->hash, $text, $this->key, true);
323
+ break;
324
+ case CRYPT_HASH_MODE_INTERNAL:
325
+ /* "Applications that use keys longer than B bytes will first hash the key using H and then use the
326
+ resultant L byte string as the actual key to HMAC."
327
+
328
+ -- http://tools.ietf.org/html/rfc2104#section-2 */
329
+ $key = strlen($this->key) > $this->b ? call_user_func($this->hash, $this->key) : $this->key;
330
+
331
+ $key = str_pad($key, $this->b, chr(0)); // step 1
332
+ $temp = $this->ipad ^ $key; // step 2
333
+ $temp .= $text; // step 3
334
+ $temp = call_user_func($this->hash, $temp); // step 4
335
+ $output = $this->opad ^ $key; // step 5
336
+ $output.= $temp; // step 6
337
+ $output = call_user_func($this->hash, $output); // step 7
338
+ }
339
+ } else {
340
+ switch ( $mode ) {
341
+ case CRYPT_HASH_MODE_MHASH:
342
+ $output = mhash($this->hash, $text);
343
+ break;
344
+ case CRYPT_HASH_MODE_HASH:
345
+ $output = hash($this->hash, $text, true);
346
+ break;
347
+ case CRYPT_HASH_MODE_INTERNAL:
348
+ $output = call_user_func($this->hash, $text);
349
+ }
350
+ }
351
+
352
+ return substr($output, 0, $this->l);
353
+ }
354
+
355
+ /**
356
+ * Returns the hash length (in bytes)
357
+ *
358
+ * @access public
359
+ * @return Integer
360
+ */
361
+ function getLength()
362
+ {
363
+ return $this->l;
364
+ }
365
+
366
+ /**
367
+ * Wrapper for MD5
368
+ *
369
+ * @access private
370
+ * @param String $m
371
+ */
372
+ function _md5($m)
373
+ {
374
+ return pack('H*', md5($m));
375
+ }
376
+
377
+ /**
378
+ * Wrapper for SHA1
379
+ *
380
+ * @access private
381
+ * @param String $m
382
+ */
383
+ function _sha1($m)
384
+ {
385
+ return pack('H*', sha1($m));
386
+ }
387
+
388
+ /**
389
+ * Pure-PHP implementation of MD2
390
+ *
391
+ * See {@link http://tools.ietf.org/html/rfc1319 RFC1319}.
392
+ *
393
+ * @access private
394
+ * @param String $m
395
+ */
396
+ function _md2($m)
397
+ {
398
+ static $s = array(
399
+ 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
400
+ 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
401
+ 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
402
+ 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
403
+ 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
404
+ 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
405
+ 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
406
+ 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
407
+ 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
408
+ 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
409
+ 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
410
+ 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
411
+ 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
412
+ 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
413
+ 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
414
+ 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
415
+ 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
416
+ 31, 26, 219, 153, 141, 51, 159, 17, 131, 20
417
+ );
418
+
419
+ // Step 1. Append Padding Bytes
420
+ $pad = 16 - (strlen($m) & 0xF);
421
+ $m.= str_repeat(chr($pad), $pad);
422
+
423
+ $length = strlen($m);
424
+
425
+ // Step 2. Append Checksum
426
+ $c = str_repeat(chr(0), 16);
427
+ $l = chr(0);
428
+ for ($i = 0; $i < $length; $i+= 16) {
429
+ for ($j = 0; $j < 16; $j++) {
430
+ // RFC1319 incorrectly states that C[j] should be set to S[c xor L]
431
+ //$c[$j] = chr($s[ord($m[$i + $j] ^ $l)]);
432
+ // per <http://www.rfc-editor.org/errata_search.php?rfc=1319>, however, C[j] should be set to S[c xor L] xor C[j]
433
+ $c[$j] = chr($s[ord($m[$i + $j] ^ $l)] ^ ord($c[$j]));
434
+ $l = $c[$j];
435
+ }
436
+ }
437
+ $m.= $c;
438
+
439
+ $length+= 16;
440
+
441
+ // Step 3. Initialize MD Buffer
442
+ $x = str_repeat(chr(0), 48);
443
+
444
+ // Step 4. Process Message in 16-Byte Blocks
445
+ for ($i = 0; $i < $length; $i+= 16) {
446
+ for ($j = 0; $j < 16; $j++) {
447
+ $x[$j + 16] = $m[$i + $j];
448
+ $x[$j + 32] = $x[$j + 16] ^ $x[$j];
449
+ }
450
+ $t = chr(0);
451
+ for ($j = 0; $j < 18; $j++) {
452
+ for ($k = 0; $k < 48; $k++) {
453
+ $x[$k] = $t = $x[$k] ^ chr($s[ord($t)]);
454
+ //$t = $x[$k] = $x[$k] ^ chr($s[ord($t)]);
455
+ }
456
+ $t = chr(ord($t) + $j);
457
+ }
458
+ }
459
+
460
+ // Step 5. Output
461
+ return substr($x, 0, 16);
462
+ }
463
+
464
+ /**
465
+ * Pure-PHP implementation of SHA256
466
+ *
467
+ * See {@link http://en.wikipedia.org/wiki/SHA_hash_functions#SHA-256_.28a_SHA-2_variant.29_pseudocode SHA-256 (a SHA-2 variant) pseudocode - Wikipedia}.
468
+ *
469
+ * @access private
470
+ * @param String $m
471
+ */
472
+ function _sha256($m)
473
+ {
474
+ if (extension_loaded('suhosin')) {
475
+ return pack('H*', sha256($m));
476
+ }
477
+
478
+ // Initialize variables
479
+ $hash = array(
480
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
481
+ );
482
+ // Initialize table of round constants
483
+ // (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)
484
+ static $k = array(
485
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
486
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
487
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
488
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
489
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
490
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
491
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
492
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
493
+ );
494
+
495
+ // Pre-processing
496
+ $length = strlen($m);
497
+ // to round to nearest 56 mod 64, we'll add 64 - (length + (64 - 56)) % 64
498
+ $m.= str_repeat(chr(0), 64 - (($length + 8) & 0x3F));
499
+ $m[$length] = chr(0x80);
500
+ // we don't support hashing strings 512MB long
501
+ $m.= pack('N2', 0, $length << 3);
502
+
503
+ // Process the message in successive 512-bit chunks
504
+ $chunks = str_split($m, 64);
505
+ foreach ($chunks as $chunk) {
506
+ $w = array();
507
+ for ($i = 0; $i < 16; $i++) {
508
+ extract(unpack('Ntemp', $this->_string_shift($chunk, 4)));
509
+ $w[] = $temp;
510
+ }
511
+
512
+ // Extend the sixteen 32-bit words into sixty-four 32-bit words
513
+ for ($i = 16; $i < 64; $i++) {
514
+ $s0 = $this->_rightRotate($w[$i - 15], 7) ^
515
+ $this->_rightRotate($w[$i - 15], 18) ^
516
+ $this->_rightShift( $w[$i - 15], 3);
517
+ $s1 = $this->_rightRotate($w[$i - 2], 17) ^
518
+ $this->_rightRotate($w[$i - 2], 19) ^
519
+ $this->_rightShift( $w[$i - 2], 10);
520
+ $w[$i] = $this->_add($w[$i - 16], $s0, $w[$i - 7], $s1);
521
+
522
+ }
523
+
524
+ // Initialize hash value for this chunk
525
+ list($a, $b, $c, $d, $e, $f, $g, $h) = $hash;
526
+
527
+ // Main loop
528
+ for ($i = 0; $i < 64; $i++) {
529
+ $s0 = $this->_rightRotate($a, 2) ^
530
+ $this->_rightRotate($a, 13) ^
531
+ $this->_rightRotate($a, 22);
532
+ $maj = ($a & $b) ^
533
+ ($a & $c) ^
534
+ ($b & $c);
535
+ $t2 = $this->_add($s0, $maj);
536
+
537
+ $s1 = $this->_rightRotate($e, 6) ^
538
+ $this->_rightRotate($e, 11) ^
539
+ $this->_rightRotate($e, 25);
540
+ $ch = ($e & $f) ^
541
+ ($this->_not($e) & $g);
542
+ $t1 = $this->_add($h, $s1, $ch, $k[$i], $w[$i]);
543
+
544
+ $h = $g;
545
+ $g = $f;
546
+ $f = $e;
547
+ $e = $this->_add($d, $t1);
548
+ $d = $c;
549
+ $c = $b;
550
+ $b = $a;
551
+ $a = $this->_add($t1, $t2);
552
+ }
553
+
554
+ // Add this chunk's hash to result so far
555
+ $hash = array(
556
+ $this->_add($hash[0], $a),
557
+ $this->_add($hash[1], $b),
558
+ $this->_add($hash[2], $c),
559
+ $this->_add($hash[3], $d),
560
+ $this->_add($hash[4], $e),
561
+ $this->_add($hash[5], $f),
562
+ $this->_add($hash[6], $g),
563
+ $this->_add($hash[7], $h)
564
+ );
565
+ }
566
+
567
+ // Produce the final hash value (big-endian)
568
+ return pack('N8', $hash[0], $hash[1], $hash[2], $hash[3], $hash[4], $hash[5], $hash[6], $hash[7]);
569
+ }
570
+
571
+ /**
572
+ * Pure-PHP implementation of SHA384 and SHA512
573
+ *
574
+ * @access private
575
+ * @param String $m
576
+ */
577
+ function _sha512($m)
578
+ {
579
+ if (!class_exists('Math_BigInteger')) {
580
+ include_once 'Math/BigInteger.php';
581
+ }
582
+
583
+ static $init384, $init512, $k;
584
+
585
+ if (!isset($k)) {
586
+ // Initialize variables
587
+ $init384 = array( // initial values for SHA384
588
+ 'cbbb9d5dc1059ed8', '629a292a367cd507', '9159015a3070dd17', '152fecd8f70e5939',
589
+ '67332667ffc00b31', '8eb44a8768581511', 'db0c2e0d64f98fa7', '47b5481dbefa4fa4'
590
+ );
591
+ $init512 = array( // initial values for SHA512
592
+ '6a09e667f3bcc908', 'bb67ae8584caa73b', '3c6ef372fe94f82b', 'a54ff53a5f1d36f1',
593
+ '510e527fade682d1', '9b05688c2b3e6c1f', '1f83d9abfb41bd6b', '5be0cd19137e2179'
594
+ );
595
+
596
+ for ($i = 0; $i < 8; $i++) {
597
+ $init384[$i] = new Math_BigInteger($init384[$i], 16);
598
+ $init384[$i]->setPrecision(64);
599
+ $init512[$i] = new Math_BigInteger($init512[$i], 16);
600
+ $init512[$i]->setPrecision(64);
601
+ }
602
+
603
+ // Initialize table of round constants
604
+ // (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409)
605
+ $k = array(
606
+ '428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc',
607
+ '3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118',
608
+ 'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2',
609
+ '72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694',
610
+ 'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65',
611
+ '2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5',
612
+ '983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4',
613
+ 'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70',
614
+ '27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df',
615
+ '650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b',
616
+ 'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30',
617
+ 'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8',
618
+ '19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8',
619
+ '391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3',
620
+ '748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec',
621
+ '90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b',
622
+ 'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178',
623
+ '06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b',
624
+ '28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c',
625
+ '4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817'
626
+ );
627
+
628
+ for ($i = 0; $i < 80; $i++) {
629
+ $k[$i] = new Math_BigInteger($k[$i], 16);
630
+ }
631
+ }
632
+
633
+ $hash = $this->l == 48 ? $init384 : $init512;
634
+
635
+ // Pre-processing
636
+ $length = strlen($m);
637
+ // to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128
638
+ $m.= str_repeat(chr(0), 128 - (($length + 16) & 0x7F));
639
+ $m[$length] = chr(0x80);
640
+ // we don't support hashing strings 512MB long
641
+ $m.= pack('N4', 0, 0, 0, $length << 3);
642
+
643
+ // Process the message in successive 1024-bit chunks
644
+ $chunks = str_split($m, 128);
645
+ foreach ($chunks as $chunk) {
646
+ $w = array();
647
+ for ($i = 0; $i < 16; $i++) {
648
+ $temp = new Math_BigInteger($this->_string_shift($chunk, 8), 256);
649
+ $temp->setPrecision(64);
650
+ $w[] = $temp;
651
+ }
652
+
653
+ // Extend the sixteen 32-bit words into eighty 32-bit words
654
+ for ($i = 16; $i < 80; $i++) {
655
+ $temp = array(
656
+ $w[$i - 15]->bitwise_rightRotate(1),
657
+ $w[$i - 15]->bitwise_rightRotate(8),
658
+ $w[$i - 15]->bitwise_rightShift(7)
659
+ );
660
+ $s0 = $temp[0]->bitwise_xor($temp[1]);
661
+ $s0 = $s0->bitwise_xor($temp[2]);
662
+ $temp = array(
663
+ $w[$i - 2]->bitwise_rightRotate(19),
664
+ $w[$i - 2]->bitwise_rightRotate(61),
665
+ $w[$i - 2]->bitwise_rightShift(6)
666
+ );
667
+ $s1 = $temp[0]->bitwise_xor($temp[1]);
668
+ $s1 = $s1->bitwise_xor($temp[2]);
669
+ $w[$i] = $w[$i - 16]->copy();
670
+ $w[$i] = $w[$i]->add($s0);
671
+ $w[$i] = $w[$i]->add($w[$i - 7]);
672
+ $w[$i] = $w[$i]->add($s1);
673
+ }
674
+
675
+ // Initialize hash value for this chunk
676
+ $a = $hash[0]->copy();
677
+ $b = $hash[1]->copy();
678
+ $c = $hash[2]->copy();
679
+ $d = $hash[3]->copy();
680
+ $e = $hash[4]->copy();
681
+ $f = $hash[5]->copy();
682
+ $g = $hash[6]->copy();
683
+ $h = $hash[7]->copy();
684
+
685
+ // Main loop
686
+ for ($i = 0; $i < 80; $i++) {
687
+ $temp = array(
688
+ $a->bitwise_rightRotate(28),
689
+ $a->bitwise_rightRotate(34),
690
+ $a->bitwise_rightRotate(39)
691
+ );
692
+ $s0 = $temp[0]->bitwise_xor($temp[1]);
693
+ $s0 = $s0->bitwise_xor($temp[2]);
694
+ $temp = array(
695
+ $a->bitwise_and($b),
696
+ $a->bitwise_and($c),
697
+ $b->bitwise_and($c)
698
+ );
699
+ $maj = $temp[0]->bitwise_xor($temp[1]);
700
+ $maj = $maj->bitwise_xor($temp[2]);
701
+ $t2 = $s0->add($maj);
702
+
703
+ $temp = array(
704
+ $e->bitwise_rightRotate(14),
705
+ $e->bitwise_rightRotate(18),
706
+ $e->bitwise_rightRotate(41)
707
+ );
708
+ $s1 = $temp[0]->bitwise_xor($temp[1]);
709
+ $s1 = $s1->bitwise_xor($temp[2]);
710
+ $temp = array(
711
+ $e->bitwise_and($f),
712
+ $g->bitwise_and($e->bitwise_not())
713
+ );
714
+ $ch = $temp[0]->bitwise_xor($temp[1]);
715
+ $t1 = $h->add($s1);
716
+ $t1 = $t1->add($ch);
717
+ $t1 = $t1->add($k[$i]);
718
+ $t1 = $t1->add($w[$i]);
719
+
720
+ $h = $g->copy();
721
+ $g = $f->copy();
722
+ $f = $e->copy();
723
+ $e = $d->add($t1);
724
+ $d = $c->copy();
725
+ $c = $b->copy();
726
+ $b = $a->copy();
727
+ $a = $t1->add($t2);
728
+ }
729
+
730
+ // Add this chunk's hash to result so far
731
+ $hash = array(
732
+ $hash[0]->add($a),
733
+ $hash[1]->add($b),
734
+ $hash[2]->add($c),
735
+ $hash[3]->add($d),
736
+ $hash[4]->add($e),
737
+ $hash[5]->add($f),
738
+ $hash[6]->add($g),
739
+ $hash[7]->add($h)
740
+ );
741
+ }
742
+
743
+ // Produce the final hash value (big-endian)
744
+ // (Crypt_Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here)
745
+ $temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() .
746
+ $hash[4]->toBytes() . $hash[5]->toBytes();
747
+ if ($this->l != 48) {
748
+ $temp.= $hash[6]->toBytes() . $hash[7]->toBytes();
749
+ }
750
+
751
+ return $temp;
752
+ }
753
+
754
+ /**
755
+ * Right Rotate
756
+ *
757
+ * @access private
758
+ * @param Integer $int
759
+ * @param Integer $amt
760
+ * @see _sha256()
761
+ * @return Integer
762
+ */
763
+ function _rightRotate($int, $amt)
764
+ {
765
+ $invamt = 32 - $amt;
766
+ $mask = (1 << $invamt) - 1;
767
+ return (($int << $invamt) & 0xFFFFFFFF) | (($int >> $amt) & $mask);
768
+ }
769
+
770
+ /**
771
+ * Right Shift
772
+ *
773
+ * @access private
774
+ * @param Integer $int
775
+ * @param Integer $amt
776
+ * @see _sha256()
777
+ * @return Integer
778
+ */
779
+ function _rightShift($int, $amt)
780
+ {
781
+ $mask = (1 << (32 - $amt)) - 1;
782
+ return ($int >> $amt) & $mask;
783
+ }
784
+
785
+ /**
786
+ * Not
787
+ *
788
+ * @access private
789
+ * @param Integer $int
790
+ * @see _sha256()
791
+ * @return Integer
792
+ */
793
+ function _not($int)
794
+ {
795
+ return ~$int & 0xFFFFFFFF;
796
+ }
797
+
798
+ /**
799
+ * Add
800
+ *
801
+ * _sha256() adds multiple unsigned 32-bit integers. Since PHP doesn't support unsigned integers and since the
802
+ * possibility of overflow exists, care has to be taken. Math_BigInteger() could be used but this should be faster.
803
+ *
804
+ * @param Integer $...
805
+ * @return Integer
806
+ * @see _sha256()
807
+ * @access private
808
+ */
809
+ function _add()
810
+ {
811
+ static $mod;
812
+ if (!isset($mod)) {
813
+ $mod = pow(2, 32);
814
+ }
815
+
816
+ $result = 0;
817
+ $arguments = func_get_args();
818
+ foreach ($arguments as $argument) {
819
+ $result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;
820
+ }
821
+
822
+ return fmod($result, $mod);
823
+ }
824
+
825
+ /**
826
+ * String Shift
827
+ *
828
+ * Inspired by array_shift
829
+ *
830
+ * @param String $string
831
+ * @param optional Integer $index
832
+ * @return String
833
+ * @access private
834
+ */
835
+ function _string_shift(&$string, $index = 1)
836
+ {
837
+ $substr = substr($string, 0, $index);
838
+ $string = substr($string, $index);
839
+ return $substr;
840
+ }
841
+ }
phpseclib/Crypt/RC4.php CHANGED
@@ -1,329 +1,347 @@
1
- <?php
2
-
3
- /**
4
- * Pure-PHP implementation of RC4.
5
- *
6
- * Uses mcrypt, if available, and an internal implementation, otherwise.
7
- *
8
- * PHP versions 4 and 5
9
- *
10
- * Useful resources are as follows:
11
- *
12
- * - {@link http://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt ARCFOUR Algorithm}
13
- * - {@link http://en.wikipedia.org/wiki/RC4 - Wikipedia: RC4}
14
- *
15
- * RC4 is also known as ARCFOUR or ARC4. The reason is elaborated upon at Wikipedia. This class is named RC4 and not
16
- * ARCFOUR or ARC4 because RC4 is how it is referred to in the SSH1 specification.
17
- *
18
- * Here's a short example of how to use this library:
19
- * <code>
20
- * <?php
21
- * include 'Crypt/RC4.php';
22
- *
23
- * $rc4 = new Crypt_RC4();
24
- *
25
- * $rc4->setKey('abcdefgh');
26
- *
27
- * $size = 10 * 1024;
28
- * $plaintext = '';
29
- * for ($i = 0; $i < $size; $i++) {
30
- * $plaintext.= 'a';
31
- * }
32
- *
33
- * echo $rc4->decrypt($rc4->encrypt($plaintext));
34
- * ?>
35
- * </code>
36
- *
37
- * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
38
- * of this software and associated documentation files (the "Software"), to deal
39
- * in the Software without restriction, including without limitation the rights
40
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
41
- * copies of the Software, and to permit persons to whom the Software is
42
- * furnished to do so, subject to the following conditions:
43
- *
44
- * The above copyright notice and this permission notice shall be included in
45
- * all copies or substantial portions of the Software.
46
- *
47
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
48
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
49
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
50
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
51
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
52
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
53
- * THE SOFTWARE.
54
- *
55
- * @category Crypt
56
- * @package Crypt_RC4
57
- * @author Jim Wigginton <terrafrost@php.net>
58
- * @copyright MMVII Jim Wigginton
59
- * @license http://www.opensource.org/licenses/mit-license.html MIT License
60
- * @link http://phpseclib.sourceforge.net
61
- */
62
-
63
- /**
64
- * Include Crypt_Base
65
- *
66
- * Base cipher class
67
- */
68
- if (!class_exists('Crypt_Base')) {
69
- include_once 'Base.php';
70
- }
71
-
72
- /**#@+
73
- * @access private
74
- * @see Crypt_RC4::Crypt_RC4()
75
- */
76
- /**
77
- * Toggles the internal implementation
78
- */
79
- define('CRYPT_RC4_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
80
- /**
81
- * Toggles the mcrypt implementation
82
- */
83
- define('CRYPT_RC4_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
84
- /**#@-*/
85
-
86
- /**#@+
87
- * @access private
88
- * @see Crypt_RC4::_crypt()
89
- */
90
- define('CRYPT_RC4_ENCRYPT', 0);
91
- define('CRYPT_RC4_DECRYPT', 1);
92
- /**#@-*/
93
-
94
- /**
95
- * Pure-PHP implementation of RC4.
96
- *
97
- * @package Crypt_RC4
98
- * @author Jim Wigginton <terrafrost@php.net>
99
- * @access public
100
- */
101
- class Crypt_RC4 extends Crypt_Base
102
- {
103
- /**
104
- * Block Length of the cipher
105
- *
106
- * RC4 is a stream cipher
107
- * so we the block_size to 0
108
- *
109
- * @see Crypt_Base::block_size
110
- * @var Integer
111
- * @access private
112
- */
113
- var $block_size = 0;
114
-
115
- /**
116
- * The default password key_size used by setPassword()
117
- *
118
- * @see Crypt_Base::password_key_size
119
- * @see Crypt_Base::setPassword()
120
- * @var Integer
121
- * @access private
122
- */
123
- var $password_key_size = 128; // = 1024 bits
124
-
125
- /**
126
- * The namespace used by the cipher for its constants.
127
- *
128
- * @see Crypt_Base::const_namespace
129
- * @var String
130
- * @access private
131
- */
132
- var $const_namespace = 'RC4';
133
-
134
- /**
135
- * The mcrypt specific name of the cipher
136
- *
137
- * @see Crypt_Base::cipher_name_mcrypt
138
- * @var String
139
- * @access private
140
- */
141
- var $cipher_name_mcrypt = 'arcfour';
142
-
143
- /**
144
- * Holds whether performance-optimized $inline_crypt() can/should be used.
145
- *
146
- * @see Crypt_Base::inline_crypt
147
- * @var mixed
148
- * @access private
149
- */
150
- var $use_inline_crypt = false; // currently not available
151
-
152
- /**
153
- * The Key
154
- *
155
- * @see Crypt_RC4::setKey()
156
- * @var String
157
- * @access private
158
- */
159
- var $key = "\0";
160
-
161
- /**
162
- * The Key Stream for decryption and encryption
163
- *
164
- * @see Crypt_RC4::setKey()
165
- * @var Array
166
- * @access private
167
- */
168
- var $stream;
169
-
170
- /**
171
- * Default Constructor.
172
- *
173
- * Determines whether or not the mcrypt extension should be used.
174
- *
175
- * @see Crypt_Base::Crypt_Base()
176
- * @return Crypt_RC4
177
- * @access public
178
- */
179
- function Crypt_RC4()
180
- {
181
- parent::Crypt_Base(CRYPT_MODE_STREAM);
182
- }
183
-
184
- /**
185
- * Dummy function.
186
- *
187
- * Some protocols, such as WEP, prepend an "initialization vector" to the key, effectively creating a new key [1].
188
- * If you need to use an initialization vector in this manner, feel free to prepend it to the key, yourself, before
189
- * calling setKey().
190
- *
191
- * [1] WEP's initialization vectors (IV's) are used in a somewhat insecure way. Since, in that protocol,
192
- * the IV's are relatively easy to predict, an attack described by
193
- * {@link http://www.drizzle.com/~aboba/IEEE/rc4_ksaproc.pdf Scott Fluhrer, Itsik Mantin, and Adi Shamir}
194
- * can be used to quickly guess at the rest of the key. The following links elaborate:
195
- *
196
- * {@link http://www.rsa.com/rsalabs/node.asp?id=2009 http://www.rsa.com/rsalabs/node.asp?id=2009}
197
- * {@link http://en.wikipedia.org/wiki/Related_key_attack http://en.wikipedia.org/wiki/Related_key_attack}
198
- *
199
- * @param String $iv
200
- * @see Crypt_RC4::setKey()
201
- * @access public
202
- */
203
- function setIV($iv)
204
- {
205
- }
206
-
207
- /**
208
- * Sets the key.
209
- *
210
- * Keys can be between 1 and 256 bytes long. If they are longer then 256 bytes, the first 256 bytes will
211
- * be used. If no key is explicitly set, it'll be assumed to be a single null byte.
212
- *
213
- * @access public
214
- * @see Crypt_Base::setKey()
215
- * @param String $key
216
- */
217
- function setKey($key)
218
- {
219
- parent::setKey(substr($key, 0, 256));
220
- }
221
-
222
- /**
223
- * Encrypts a message.
224
- *
225
- * @see Crypt_Base::decrypt()
226
- * @see Crypt_RC4::_crypt()
227
- * @access public
228
- * @param String $plaintext
229
- * @return String $ciphertext
230
- */
231
- function encrypt($plaintext)
232
- {
233
- if ($this->engine == CRYPT_MODE_MCRYPT) {
234
- return parent::encrypt($plaintext);
235
- }
236
- return $this->_crypt($plaintext, CRYPT_RC4_ENCRYPT);
237
- }
238
-
239
- /**
240
- * Decrypts a message.
241
- *
242
- * $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)).
243
- * At least if the continuous buffer is disabled.
244
- *
245
- * @see Crypt_Base::encrypt()
246
- * @see Crypt_RC4::_crypt()
247
- * @access public
248
- * @param String $ciphertext
249
- * @return String $plaintext
250
- */
251
- function decrypt($ciphertext)
252
- {
253
- if ($this->engine == CRYPT_MODE_MCRYPT) {
254
- return parent::decrypt($ciphertext);
255
- }
256
- return $this->_crypt($ciphertext, CRYPT_RC4_DECRYPT);
257
- }
258
-
259
-
260
- /**
261
- * Setup the key (expansion)
262
- *
263
- * @see Crypt_Base::_setupKey()
264
- * @access private
265
- */
266
- function _setupKey()
267
- {
268
- $key = $this->key;
269
- $keyLength = strlen($key);
270
- $keyStream = range(0, 255);
271
- $j = 0;
272
- for ($i = 0; $i < 256; $i++) {
273
- $j = ($j + $keyStream[$i] + ord($key[$i % $keyLength])) & 255;
274
- $temp = $keyStream[$i];
275
- $keyStream[$i] = $keyStream[$j];
276
- $keyStream[$j] = $temp;
277
- }
278
-
279
- $this->stream = array();
280
- $this->stream[CRYPT_RC4_DECRYPT] = $this->stream[CRYPT_RC4_ENCRYPT] = array(
281
- 0, // index $i
282
- 0, // index $j
283
- $keyStream
284
- );
285
- }
286
-
287
- /**
288
- * Encrypts or decrypts a message.
289
- *
290
- * @see Crypt_RC4::encrypt()
291
- * @see Crypt_RC4::decrypt()
292
- * @access private
293
- * @param String $text
294
- * @param Integer $mode
295
- * @return String $text
296
- */
297
- function _crypt($text, $mode)
298
- {
299
- if ($this->changed) {
300
- $this->_setup();
301
- $this->changed = false;
302
- }
303
-
304
- $stream = &$this->stream[$mode];
305
- if ($this->continuousBuffer) {
306
- $i = &$stream[0];
307
- $j = &$stream[1];
308
- $keyStream = &$stream[2];
309
- } else {
310
- $i = $stream[0];
311
- $j = $stream[1];
312
- $keyStream = $stream[2];
313
- }
314
-
315
- $len = strlen($text);
316
- for ($k = 0; $k < $len; ++$k) {
317
- $i = ($i + 1) & 255;
318
- $ksi = $keyStream[$i];
319
- $j = ($j + $ksi) & 255;
320
- $ksj = $keyStream[$j];
321
-
322
- $keyStream[$i] = $ksj;
323
- $keyStream[$j] = $ksi;
324
- $text[$k] = $text[$k] ^ chr($keyStream[($ksj + $ksi) & 255]);
325
- }
326
-
327
- return $text;
328
- }
329
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Pure-PHP implementation of RC4.
5
+ *
6
+ * Uses mcrypt, if available, and an internal implementation, otherwise.
7
+ *
8
+ * PHP versions 4 and 5
9
+ *
10
+ * Useful resources are as follows:
11
+ *
12
+ * - {@link http://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt ARCFOUR Algorithm}
13
+ * - {@link http://en.wikipedia.org/wiki/RC4 - Wikipedia: RC4}
14
+ *
15
+ * RC4 is also known as ARCFOUR or ARC4. The reason is elaborated upon at Wikipedia. This class is named RC4 and not
16
+ * ARCFOUR or ARC4 because RC4 is how it is referred to in the SSH1 specification.
17
+ *
18
+ * Here's a short example of how to use this library:
19
+ * <code>
20
+ * <?php
21
+ * include 'Crypt/RC4.php';
22
+ *
23
+ * $rc4 = new Crypt_RC4();
24
+ *
25
+ * $rc4->setKey('abcdefgh');
26
+ *
27
+ * $size = 10 * 1024;
28
+ * $plaintext = '';
29
+ * for ($i = 0; $i < $size; $i++) {
30
+ * $plaintext.= 'a';
31
+ * }
32
+ *
33
+ * echo $rc4->decrypt($rc4->encrypt($plaintext));
34
+ * ?>
35
+ * </code>
36
+ *
37
+ * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
38
+ * of this software and associated documentation files (the "Software"), to deal
39
+ * in the Software without restriction, including without limitation the rights
40
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
41
+ * copies of the Software, and to permit persons to whom the Software is
42
+ * furnished to do so, subject to the following conditions:
43
+ *
44
+ * The above copyright notice and this permission notice shall be included in
45
+ * all copies or substantial portions of the Software.
46
+ *
47
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
48
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
49
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
50
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
51
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
52
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
53
+ * THE SOFTWARE.
54
+ *
55
+ * @category Crypt
56
+ * @package Crypt_RC4
57
+ * @author Jim Wigginton <terrafrost@php.net>
58
+ * @copyright 2007 Jim Wigginton
59
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
60
+ * @link http://phpseclib.sourceforge.net
61
+ */
62
+
63
+ /**
64
+ * Include Crypt_Base
65
+ *
66
+ * Base cipher class
67
+ */
68
+ if (!class_exists('Crypt_Base')) {
69
+ include_once 'Base.php';
70
+ }
71
+
72
+ /**#@+
73
+ * @access private
74
+ * @see Crypt_RC4::_crypt()
75
+ */
76
+ define('CRYPT_RC4_ENCRYPT', 0);
77
+ define('CRYPT_RC4_DECRYPT', 1);
78
+ /**#@-*/
79
+
80
+ /**
81
+ * Pure-PHP implementation of RC4.
82
+ *
83
+ * @package Crypt_RC4
84
+ * @author Jim Wigginton <terrafrost@php.net>
85
+ * @access public
86
+ */
87
+ class Crypt_RC4 extends Crypt_Base
88
+ {
89
+ /**
90
+ * Block Length of the cipher
91
+ *
92
+ * RC4 is a stream cipher
93
+ * so we the block_size to 0
94
+ *
95
+ * @see Crypt_Base::block_size
96
+ * @var Integer
97
+ * @access private
98
+ */
99
+ var $block_size = 0;
100
+
101
+ /**
102
+ * The default password key_size used by setPassword()
103
+ *
104
+ * @see Crypt_Base::password_key_size
105
+ * @see Crypt_Base::setPassword()
106
+ * @var Integer
107
+ * @access private
108
+ */
109
+ var $password_key_size = 128; // = 1024 bits
110
+
111
+ /**
112
+ * The namespace used by the cipher for its constants.
113
+ *
114
+ * @see Crypt_Base::const_namespace
115
+ * @var String
116
+ * @access private
117
+ */
118
+ var $const_namespace = 'RC4';
119
+
120
+ /**
121
+ * The mcrypt specific name of the cipher
122
+ *
123
+ * @see Crypt_Base::cipher_name_mcrypt
124
+ * @var String
125
+ * @access private
126
+ */
127
+ var $cipher_name_mcrypt = 'arcfour';
128
+
129
+ /**
130
+ * Holds whether performance-optimized $inline_crypt() can/should be used.
131
+ *
132
+ * @see Crypt_Base::inline_crypt
133
+ * @var mixed
134
+ * @access private
135
+ */
136
+ var $use_inline_crypt = false; // currently not available
137
+
138
+ /**
139
+ * The Key
140
+ *
141
+ * @see Crypt_RC4::setKey()
142
+ * @var String
143
+ * @access private
144
+ */
145
+ var $key = "\0";
146
+
147
+ /**
148
+ * The Key Stream for decryption and encryption
149
+ *
150
+ * @see Crypt_RC4::setKey()
151
+ * @var Array
152
+ * @access private
153
+ */
154
+ var $stream;
155
+
156
+ /**
157
+ * Default Constructor.
158
+ *
159
+ * Determines whether or not the mcrypt extension should be used.
160
+ *
161
+ * @see Crypt_Base::Crypt_Base()
162
+ * @return Crypt_RC4
163
+ * @access public
164
+ */
165
+ function Crypt_RC4()
166
+ {
167
+ parent::Crypt_Base(CRYPT_MODE_STREAM);
168
+ }
169
+
170
+ /**
171
+ * Test for engine validity
172
+ *
173
+ * This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine()
174
+ *
175
+ * @see Crypt_Base::Crypt_Base()
176
+ * @param Integer $engine
177
+ * @access public
178
+ * @return Boolean
179
+ */
180
+ function isValidEngine($engine)
181
+ {
182
+ switch ($engine) {
183
+ case CRYPT_ENGINE_OPENSSL:
184
+ switch (strlen($this->key)) {
185
+ case 5:
186
+ $this->cipher_name_openssl = 'rc4-40';
187
+ break;
188
+ case 8:
189
+ $this->cipher_name_openssl = 'rc4-64';
190
+ break;
191
+ case 16:
192
+ $this->cipher_name_openssl = 'rc4';
193
+ break;
194
+ default:
195
+ return false;
196
+ }
197
+ }
198
+
199
+ return parent::isValidEngine($engine);
200
+ }
201
+
202
+ /**
203
+ * Dummy function.
204
+ *
205
+ * Some protocols, such as WEP, prepend an "initialization vector" to the key, effectively creating a new key [1].
206
+ * If you need to use an initialization vector in this manner, feel free to prepend it to the key, yourself, before
207
+ * calling setKey().
208
+ *
209
+ * [1] WEP's initialization vectors (IV's) are used in a somewhat insecure way. Since, in that protocol,
210
+ * the IV's are relatively easy to predict, an attack described by
211
+ * {@link http://www.drizzle.com/~aboba/IEEE/rc4_ksaproc.pdf Scott Fluhrer, Itsik Mantin, and Adi Shamir}
212
+ * can be used to quickly guess at the rest of the key. The following links elaborate:
213
+ *
214
+ * {@link http://www.rsa.com/rsalabs/node.asp?id=2009 http://www.rsa.com/rsalabs/node.asp?id=2009}
215
+ * {@link http://en.wikipedia.org/wiki/Related_key_attack http://en.wikipedia.org/wiki/Related_key_attack}
216
+ *
217
+ * @param String $iv
218
+ * @see Crypt_RC4::setKey()
219
+ * @access public
220
+ */
221
+ function setIV($iv)
222
+ {
223
+ }
224
+
225
+ /**
226
+ * Sets the key.
227
+ *
228
+ * Keys can be between 1 and 256 bytes long. If they are longer then 256 bytes, the first 256 bytes will
229
+ * be used. If no key is explicitly set, it'll be assumed to be a single null byte.
230
+ *
231
+ * @access public
232
+ * @see Crypt_Base::setKey()
233
+ * @param String $key
234
+ */
235
+ function setKey($key)
236
+ {
237
+ parent::setKey(substr($key, 0, 256));
238
+ }
239
+
240
+ /**
241
+ * Encrypts a message.
242
+ *
243
+ * @see Crypt_Base::decrypt()
244
+ * @see Crypt_RC4::_crypt()
245
+ * @access public
246
+ * @param String $plaintext
247
+ * @return String $ciphertext
248
+ */
249
+ function encrypt($plaintext)
250
+ {
251
+ if ($this->engine != CRYPT_ENGINE_INTERNAL) {
252
+ return parent::encrypt($plaintext);
253
+ }
254
+ return $this->_crypt($plaintext, CRYPT_RC4_ENCRYPT);
255
+ }
256
+
257
+ /**
258
+ * Decrypts a message.
259
+ *
260
+ * $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)).
261
+ * At least if the continuous buffer is disabled.
262
+ *
263
+ * @see Crypt_Base::encrypt()
264
+ * @see Crypt_RC4::_crypt()
265
+ * @access public
266
+ * @param String $ciphertext
267
+ * @return String $plaintext
268
+ */
269
+ function decrypt($ciphertext)
270
+ {
271
+ if ($this->engine != CRYPT_ENGINE_INTERNAL) {
272
+ return parent::decrypt($ciphertext);
273
+ }
274
+ return $this->_crypt($ciphertext, CRYPT_RC4_DECRYPT);
275
+ }
276
+
277
+
278
+ /**
279
+ * Setup the key (expansion)
280
+ *
281
+ * @see Crypt_Base::_setupKey()
282
+ * @access private
283
+ */
284
+ function _setupKey()
285
+ {
286
+ $key = $this->key;
287
+ $keyLength = strlen($key);
288
+ $keyStream = range(0, 255);
289
+ $j = 0;
290
+ for ($i = 0; $i < 256; $i++) {
291
+ $j = ($j + $keyStream[$i] + ord($key[$i % $keyLength])) & 255;
292
+ $temp = $keyStream[$i];
293
+ $keyStream[$i] = $keyStream[$j];
294
+ $keyStream[$j] = $temp;
295
+ }
296
+
297
+ $this->stream = array();
298
+ $this->stream[CRYPT_RC4_DECRYPT] = $this->stream[CRYPT_RC4_ENCRYPT] = array(
299
+ 0, // index $i
300
+ 0, // index $j
301
+ $keyStream
302
+ );
303
+ }
304
+
305
+ /**
306
+ * Encrypts or decrypts a message.
307
+ *
308
+ * @see Crypt_RC4::encrypt()
309
+ * @see Crypt_RC4::decrypt()
310
+ * @access private
311
+ * @param String $text
312
+ * @param Integer $mode
313
+ * @return String $text
314
+ */
315
+ function _crypt($text, $mode)
316
+ {
317
+ if ($this->changed) {
318
+ $this->_setup();
319
+ $this->changed = false;
320
+ }
321
+
322
+ $stream = &$this->stream[$mode];
323
+ if ($this->continuousBuffer) {
324
+ $i = &$stream[0];
325
+ $j = &$stream[1];
326
+ $keyStream = &$stream[2];
327
+ } else {
328
+ $i = $stream[0];
329
+ $j = $stream[1];
330
+ $keyStream = $stream[2];
331
+ }
332
+
333
+ $len = strlen($text);
334
+ for ($k = 0; $k < $len; ++$k) {
335
+ $i = ($i + 1) & 255;
336
+ $ksi = $keyStream[$i];
337
+ $j = ($j + $ksi) & 255;
338
+ $ksj = $keyStream[$j];
339
+
340
+ $keyStream[$i] = $ksj;
341
+ $keyStream[$j] = $ksi;
342
+ $text[$k] = $text[$k] ^ chr($keyStream[($ksj + $ksi) & 255]);
343
+ }
344
+
345
+ return $text;
346
+ }
347
+ }
phpseclib/Crypt/RSA.php CHANGED
@@ -1,2990 +1,3033 @@
1
- <?php
2
-
3
- /**
4
- * Pure-PHP PKCS#1 (v2.1) compliant implementation of RSA.
5
- *
6
- * PHP versions 4 and 5
7
- *
8
- * Here's an example of how to encrypt and decrypt text with this library:
9
- * <code>
10
- * <?php
11
- * include 'Crypt/RSA.php';
12
- *
13
- * $rsa = new Crypt_RSA();
14
- * extract($rsa->createKey());
15
- *
16
- * $plaintext = 'terrafrost';
17
- *
18
- * $rsa->loadKey($privatekey);
19
- * $ciphertext = $rsa->encrypt($plaintext);
20
- *
21
- * $rsa->loadKey($publickey);
22
- * echo $rsa->decrypt($ciphertext);
23
- * ?>
24
- * </code>
25
- *
26
- * Here's an example of how to create signatures and verify signatures with this library:
27
- * <code>
28
- * <?php
29
- * include 'Crypt/RSA.php';
30
- *
31
- * $rsa = new Crypt_RSA();
32
- * extract($rsa->createKey());
33
- *
34
- * $plaintext = 'terrafrost';
35
- *
36
- * $rsa->loadKey($privatekey);
37
- * $signature = $rsa->sign($plaintext);
38
- *
39
- * $rsa->loadKey($publickey);
40
- * echo $rsa->verify($plaintext, $signature) ? 'verified' : 'unverified';
41
- * ?>
42
- * </code>
43
- *
44
- * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
45
- * of this software and associated documentation files (the "Software"), to deal
46
- * in the Software without restriction, including without limitation the rights
47
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
48
- * copies of the Software, and to permit persons to whom the Software is
49
- * furnished to do so, subject to the following conditions:
50
- *
51
- * The above copyright notice and this permission notice shall be included in
52
- * all copies or substantial portions of the Software.
53
- *
54
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
55
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
56
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
57
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
58
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
59
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
60
- * THE SOFTWARE.
61
- *
62
- * @category Crypt
63
- * @package Crypt_RSA
64
- * @author Jim Wigginton <terrafrost@php.net>
65
- * @copyright MMIX Jim Wigginton
66
- * @license http://www.opensource.org/licenses/mit-license.html MIT License
67
- * @link http://phpseclib.sourceforge.net
68
- */
69
-
70
- /**
71
- * Include Crypt_Random
72
- */
73
- // the class_exists() will only be called if the crypt_random_string function hasn't been defined and
74
- // will trigger a call to __autoload() if you're wanting to auto-load classes
75
- // call function_exists() a second time to stop the include_once from being called outside
76
- // of the auto loader
77
- if (!function_exists('crypt_random_string')) {
78
- include_once 'Random.php';
79
- }
80
-
81
- /**
82
- * Include Crypt_Hash
83
- */
84
- if (!class_exists('Crypt_Hash')) {
85
- include_once 'Hash.php';
86
- }
87
-
88
- /**#@+
89
- * @access public
90
- * @see Crypt_RSA::encrypt()
91
- * @see Crypt_RSA::decrypt()
92
- */
93
- /**
94
- * Use {@link http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding Optimal Asymmetric Encryption Padding}
95
- * (OAEP) for encryption / decryption.
96
- *
97
- * Uses sha1 by default.
98
- *
99
- * @see Crypt_RSA::setHash()
100
- * @see Crypt_RSA::setMGFHash()
101
- */
102
- define('CRYPT_RSA_ENCRYPTION_OAEP', 1);
103
- /**
104
- * Use PKCS#1 padding.
105
- *
106
- * Although CRYPT_RSA_ENCRYPTION_OAEP offers more security, including PKCS#1 padding is necessary for purposes of backwards
107
- * compatibility with protocols (like SSH-1) written before OAEP's introduction.
108
- */
109
- define('CRYPT_RSA_ENCRYPTION_PKCS1', 2);
110
- /**#@-*/
111
-
112
- /**#@+
113
- * @access public
114
- * @see Crypt_RSA::sign()
115
- * @see Crypt_RSA::verify()
116
- * @see Crypt_RSA::setHash()
117
- */
118
- /**
119
- * Use the Probabilistic Signature Scheme for signing
120
- *
121
- * Uses sha1 by default.
122
- *
123
- * @see Crypt_RSA::setSaltLength()
124
- * @see Crypt_RSA::setMGFHash()
125
- */
126
- define('CRYPT_RSA_SIGNATURE_PSS', 1);
127
- /**
128
- * Use the PKCS#1 scheme by default.
129
- *
130
- * Although CRYPT_RSA_SIGNATURE_PSS offers more security, including PKCS#1 signing is necessary for purposes of backwards
131
- * compatibility with protocols (like SSH-2) written before PSS's introduction.
132
- */
133
- define('CRYPT_RSA_SIGNATURE_PKCS1', 2);
134
- /**#@-*/
135
-
136
- /**#@+
137
- * @access private
138
- * @see Crypt_RSA::createKey()
139
- */
140
- /**
141
- * ASN1 Integer
142
- */
143
- define('CRYPT_RSA_ASN1_INTEGER', 2);
144
- /**
145
- * ASN1 Bit String
146
- */
147
- define('CRYPT_RSA_ASN1_BITSTRING', 3);
148
- /**
149
- * ASN1 Octet String
150
- */
151
- define('CRYPT_RSA_ASN1_OCTETSTRING', 4);
152
- /**
153
- * ASN1 Object Identifier
154
- */
155
- define('CRYPT_RSA_ASN1_OBJECT', 6);
156
- /**
157
- * ASN1 Sequence (with the constucted bit set)
158
- */
159
- define('CRYPT_RSA_ASN1_SEQUENCE', 48);
160
- /**#@-*/
161
-
162
- /**#@+
163
- * @access private
164
- * @see Crypt_RSA::Crypt_RSA()
165
- */
166
- /**
167
- * To use the pure-PHP implementation
168
- */
169
- define('CRYPT_RSA_MODE_INTERNAL', 1);
170
- /**
171
- * To use the OpenSSL library
172
- *
173
- * (if enabled; otherwise, the internal implementation will be used)
174
- */
175
- define('CRYPT_RSA_MODE_OPENSSL', 2);
176
- /**#@-*/
177
-
178
- /**
179
- * Default openSSL configuration file.
180
- */
181
- define('CRYPT_RSA_OPENSSL_CONFIG', dirname(__FILE__) . '/../openssl.cnf');
182
-
183
- /**#@+
184
- * @access public
185
- * @see Crypt_RSA::createKey()
186
- * @see Crypt_RSA::setPrivateKeyFormat()
187
- */
188
- /**
189
- * PKCS#1 formatted private key
190
- *
191
- * Used by OpenSSH
192
- */
193
- define('CRYPT_RSA_PRIVATE_FORMAT_PKCS1', 0);
194
- /**
195
- * PuTTY formatted private key
196
- */
197
- define('CRYPT_RSA_PRIVATE_FORMAT_PUTTY', 1);
198
- /**
199
- * XML formatted private key
200
- */
201
- define('CRYPT_RSA_PRIVATE_FORMAT_XML', 2);
202
- /**
203
- * PKCS#8 formatted private key
204
- */
205
- define('CRYPT_RSA_PRIVATE_FORMAT_PKCS8', 3);
206
- /**#@-*/
207
-
208
- /**#@+
209
- * @access public
210
- * @see Crypt_RSA::createKey()
211
- * @see Crypt_RSA::setPublicKeyFormat()
212
- */
213
- /**
214
- * Raw public key
215
- *
216
- * An array containing two Math_BigInteger objects.
217
- *
218
- * The exponent can be indexed with any of the following:
219
- *
220
- * 0, e, exponent, publicExponent
221
- *
222
- * The modulus can be indexed with any of the following:
223
- *
224
- * 1, n, modulo, modulus
225
- */
226
- define('CRYPT_RSA_PUBLIC_FORMAT_RAW', 3);
227
- /**
228
- * PKCS#1 formatted public key (raw)
229
- *
230
- * Used by File/X509.php
231
- *
232
- * Has the following header:
233
- *
234
- * -----BEGIN RSA PUBLIC KEY-----
235
- *
236
- * Analogous to ssh-keygen's pem format (as specified by -m)
237
- */
238
- define('CRYPT_RSA_PUBLIC_FORMAT_PKCS1', 4);
239
- define('CRYPT_RSA_PUBLIC_FORMAT_PKCS1_RAW', 4);
240
- /**
241
- * XML formatted public key
242
- */
243
- define('CRYPT_RSA_PUBLIC_FORMAT_XML', 5);
244
- /**
245
- * OpenSSH formatted public key
246
- *
247
- * Place in $HOME/.ssh/authorized_keys
248
- */
249
- define('CRYPT_RSA_PUBLIC_FORMAT_OPENSSH', 6);
250
- /**
251
- * PKCS#1 formatted public key (encapsulated)
252
- *
253
- * Used by PHP's openssl_public_encrypt() and openssl's rsautl (when -pubin is set)
254
- *
255
- * Has the following header:
256
- *
257
- * -----BEGIN PUBLIC KEY-----
258
- *
259
- * Analogous to ssh-keygen's pkcs8 format (as specified by -m). Although PKCS8
260
- * is specific to private keys it's basically creating a DER-encoded wrapper
261
- * for keys. This just extends that same concept to public keys (much like ssh-keygen)
262
- */
263
- define('CRYPT_RSA_PUBLIC_FORMAT_PKCS8', 7);
264
- /**#@-*/
265
-
266
- /**
267
- * Pure-PHP PKCS#1 compliant implementation of RSA.
268
- *
269
- * @package Crypt_RSA
270
- * @author Jim Wigginton <terrafrost@php.net>
271
- * @access public
272
- */
273
- class Crypt_RSA
274
- {
275
- /**
276
- * Precomputed Zero
277
- *
278
- * @var Array
279
- * @access private
280
- */
281
- var $zero;
282
-
283
- /**
284
- * Precomputed One
285
- *
286
- * @var Array
287
- * @access private
288
- */
289
- var $one;
290
-
291
- /**
292
- * Private Key Format
293
- *
294
- * @var Integer
295
- * @access private
296
- */
297
- var $privateKeyFormat = CRYPT_RSA_PRIVATE_FORMAT_PKCS1;
298
-
299
- /**
300
- * Public Key Format
301
- *
302
- * @var Integer
303
- * @access public
304
- */
305
- var $publicKeyFormat = CRYPT_RSA_PUBLIC_FORMAT_PKCS8;
306
-
307
- /**
308
- * Modulus (ie. n)
309
- *
310
- * @var Math_BigInteger
311
- * @access private
312
- */
313
- var $modulus;
314
-
315
- /**
316
- * Modulus length
317
- *
318
- * @var Math_BigInteger
319
- * @access private
320
- */
321
- var $k;
322
-
323
- /**
324
- * Exponent (ie. e or d)
325
- *
326
- * @var Math_BigInteger
327
- * @access private
328
- */
329
- var $exponent;
330
-
331
- /**
332
- * Primes for Chinese Remainder Theorem (ie. p and q)
333
- *
334
- * @var Array
335
- * @access private
336
- */
337
- var $primes;
338
-
339
- /**
340
- * Exponents for Chinese Remainder Theorem (ie. dP and dQ)
341
- *
342
- * @var Array
343
- * @access private
344
- */
345
- var $exponents;
346
-
347
- /**
348
- * Coefficients for Chinese Remainder Theorem (ie. qInv)
349
- *
350
- * @var Array
351
- * @access private
352
- */
353
- var $coefficients;
354
-
355
- /**
356
- * Hash name
357
- *
358
- * @var String
359
- * @access private
360
- */
361
- var $hashName;
362
-
363
- /**
364
- * Hash function
365
- *
366
- * @var Crypt_Hash
367
- * @access private
368
- */
369
- var $hash;
370
-
371
- /**
372
- * Length of hash function output
373
- *
374
- * @var Integer
375
- * @access private
376
- */
377
- var $hLen;
378
-
379
- /**
380
- * Length of salt
381
- *
382
- * @var Integer
383
- * @access private
384
- */
385
- var $sLen;
386
-
387
- /**
388
- * Hash function for the Mask Generation Function
389
- *
390
- * @var Crypt_Hash
391
- * @access private
392
- */
393
- var $mgfHash;
394
-
395
- /**
396
- * Length of MGF hash function output
397
- *
398
- * @var Integer
399
- * @access private
400
- */
401
- var $mgfHLen;
402
-
403
- /**
404
- * Encryption mode
405
- *
406
- * @var Integer
407
- * @access private
408
- */
409
- var $encryptionMode = CRYPT_RSA_ENCRYPTION_OAEP;
410
-
411
- /**
412
- * Signature mode
413
- *
414
- * @var Integer
415
- * @access private
416
- */
417
- var $signatureMode = CRYPT_RSA_SIGNATURE_PSS;
418
-
419
- /**
420
- * Public Exponent
421
- *
422
- * @var Mixed
423
- * @access private
424
- */
425
- var $publicExponent = false;
426
-
427
- /**
428
- * Password
429
- *
430
- * @var String
431
- * @access private
432
- */
433
- var $password = false;
434
-
435
- /**
436
- * Components
437
- *
438
- * For use with parsing XML formatted keys. PHP's XML Parser functions use utilized - instead of PHP's DOM functions -
439
- * because PHP's XML Parser functions work on PHP4 whereas PHP's DOM functions - although surperior - don't.
440
- *
441
- * @see Crypt_RSA::_start_element_handler()
442
- * @var Array
443
- * @access private
444
- */
445
- var $components = array();
446
-
447
- /**
448
- * Current String
449
- *
450
- * For use with parsing XML formatted keys.
451
- *
452
- * @see Crypt_RSA::_character_handler()
453
- * @see Crypt_RSA::_stop_element_handler()
454
- * @var Mixed
455
- * @access private
456
- */
457
- var $current;
458
-
459
- /**
460
- * OpenSSL configuration file name.
461
- *
462
- * Set to null to use system configuration file.
463
- * @see Crypt_RSA::createKey()
464
- * @var Mixed
465
- * @Access public
466
- */
467
- var $configFile;
468
-
469
- /**
470
- * Public key comment field.
471
- *
472
- * @var String
473
- * @access private
474
- */
475
- var $comment = 'phpseclib-generated-key';
476
-
477
- /**
478
- * The constructor
479
- *
480
- * If you want to make use of the openssl extension, you'll need to set the mode manually, yourself. The reason
481
- * Crypt_RSA doesn't do it is because OpenSSL doesn't fail gracefully. openssl_pkey_new(), in particular, requires
482
- * openssl.cnf be present somewhere and, unfortunately, the only real way to find out is too late.
483
- *
484
- * @return Crypt_RSA
485
- * @access public
486
- */
487
- function Crypt_RSA()
488
- {
489
- if (!class_exists('Math_BigInteger')) {
490
- include_once 'Math/BigInteger.php';
491
- }
492
-
493
- $this->configFile = CRYPT_RSA_OPENSSL_CONFIG;
494
-
495
- if ( !defined('CRYPT_RSA_MODE') ) {
496
- switch (true) {
497
- // Math/BigInteger's openssl requirements are a little less stringent than Crypt/RSA's. in particular,
498
- // Math/BigInteger doesn't require an openssl.cfg file whereas Crypt/RSA does. so if Math/BigInteger
499
- // can't use OpenSSL it can be pretty trivially assumed, then, that Crypt/RSA can't either.
500
- case defined('MATH_BIGINTEGER_OPENSSL_DISABLE'):
501
- define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_INTERNAL);
502
- break;
503
- // openssl_pkey_get_details - which is used in the only place Crypt/RSA.php uses OpenSSL - was introduced in PHP 5.2.0
504
- case !function_exists('openssl_pkey_get_details'):
505
- define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_INTERNAL);
506
- break;
507
- case extension_loaded('openssl') && version_compare(PHP_VERSION, '4.2.0', '>=') && file_exists($this->configFile):
508
- // some versions of XAMPP have mismatched versions of OpenSSL which causes it not to work
509
- ob_start();
510
- @phpinfo();
511
- $content = ob_get_contents();
512
- ob_end_clean();
513
-
514
- preg_match_all('#OpenSSL (Header|Library) Version(.*)#im', $content, $matches);
515
-
516
- $versions = array();
517
- if (!empty($matches[1])) {
518
- for ($i = 0; $i < count($matches[1]); $i++) {
519
- $versions[$matches[1][$i]] = trim(str_replace('=>', '', strip_tags($matches[2][$i])));
520
- }
521
- }
522
-
523
- // it doesn't appear that OpenSSL versions were reported upon until PHP 5.3+
524
- switch (true) {
525
- case !isset($versions['Header']):
526
- case !isset($versions['Library']):
527
- case $versions['Header'] == $versions['Library']:
528
- define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_OPENSSL);
529
- break;
530
- default:
531
- define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_INTERNAL);
532
- define('MATH_BIGINTEGER_OPENSSL_DISABLE', true);
533
- }
534
- break;
535
- default:
536
- define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_INTERNAL);
537
- }
538
- }
539
-
540
- $this->zero = new Math_BigInteger();
541
- $this->one = new Math_BigInteger(1);
542
-
543
- $this->hash = new Crypt_Hash('sha1');
544
- $this->hLen = $this->hash->getLength();
545
- $this->hashName = 'sha1';
546
- $this->mgfHash = new Crypt_Hash('sha1');
547
- $this->mgfHLen = $this->mgfHash->getLength();
548
- }
549
-
550
- /**
551
- * Create public / private key pair
552
- *
553
- * Returns an array with the following three elements:
554
- * - 'privatekey': The private key.
555
- * - 'publickey': The public key.
556
- * - 'partialkey': A partially computed key (if the execution time exceeded $timeout).
557
- * Will need to be passed back to Crypt_RSA::createKey() as the third parameter for further processing.
558
- *
559
- * @access public
560
- * @param optional Integer $bits
561
- * @param optional Integer $timeout
562
- * @param optional Math_BigInteger $p
563
- */
564
- function createKey($bits = 1024, $timeout = false, $partial = array())
565
- {
566
- if (!defined('CRYPT_RSA_EXPONENT')) {
567
- // http://en.wikipedia.org/wiki/65537_%28number%29
568
- define('CRYPT_RSA_EXPONENT', '65537');
569
- }
570
- // per <http://cseweb.ucsd.edu/~hovav/dist/survey.pdf#page=5>, this number ought not result in primes smaller
571
- // than 256 bits. as a consequence if the key you're trying to create is 1024 bits and you've set CRYPT_RSA_SMALLEST_PRIME
572
- // to 384 bits then you're going to get a 384 bit prime and a 640 bit prime (384 + 1024 % 384). at least if
573
- // CRYPT_RSA_MODE is set to CRYPT_RSA_MODE_INTERNAL. if CRYPT_RSA_MODE is set to CRYPT_RSA_MODE_OPENSSL then
574
- // CRYPT_RSA_SMALLEST_PRIME is ignored (ie. multi-prime RSA support is more intended as a way to speed up RSA key
575
- // generation when there's a chance neither gmp nor OpenSSL are installed)
576
- if (!defined('CRYPT_RSA_SMALLEST_PRIME')) {
577
- define('CRYPT_RSA_SMALLEST_PRIME', 4096);
578
- }
579
-
580
- // OpenSSL uses 65537 as the exponent and requires RSA keys be 384 bits minimum
581
- if ( CRYPT_RSA_MODE == CRYPT_RSA_MODE_OPENSSL && $bits >= 384 && CRYPT_RSA_EXPONENT == 65537) {
582
- $config = array();
583
- if (isset($this->configFile)) {
584
- $config['config'] = $this->configFile;
585
- }
586
- $rsa = openssl_pkey_new(array('private_key_bits' => $bits) + $config);
587
- openssl_pkey_export($rsa, $privatekey, null, $config);
588
- $publickey = openssl_pkey_get_details($rsa);
589
- $publickey = $publickey['key'];
590
-
591
- $privatekey = call_user_func_array(array($this, '_convertPrivateKey'), array_values($this->_parseKey($privatekey, CRYPT_RSA_PRIVATE_FORMAT_PKCS1)));
592
- $publickey = call_user_func_array(array($this, '_convertPublicKey'), array_values($this->_parseKey($publickey, CRYPT_RSA_PUBLIC_FORMAT_PKCS1)));
593
-
594
- // clear the buffer of error strings stemming from a minimalistic openssl.cnf
595
- while (openssl_error_string() !== false);
596
-
597
- return array(
598
- 'privatekey' => $privatekey,
599
- 'publickey' => $publickey,
600
- 'partialkey' => false
601
- );
602
- }
603
-
604
- static $e;
605
- if (!isset($e)) {
606
- $e = new Math_BigInteger(CRYPT_RSA_EXPONENT);
607
- }
608
-
609
- extract($this->_generateMinMax($bits));
610
- $absoluteMin = $min;
611
- $temp = $bits >> 1; // divide by two to see how many bits P and Q would be
612
- if ($temp > CRYPT_RSA_SMALLEST_PRIME) {
613
- $num_primes = floor($bits / CRYPT_RSA_SMALLEST_PRIME);
614
- $temp = CRYPT_RSA_SMALLEST_PRIME;
615
- } else {
616
- $num_primes = 2;
617
- }
618
- extract($this->_generateMinMax($temp + $bits % $temp));
619
- $finalMax = $max;
620
- extract($this->_generateMinMax($temp));
621
-
622
- $generator = new Math_BigInteger();
623
-
624
- $n = $this->one->copy();
625
- if (!empty($partial)) {
626
- extract(unserialize($partial));
627
- } else {
628
- $exponents = $coefficients = $primes = array();
629
- $lcm = array(
630
- 'top' => $this->one->copy(),
631
- 'bottom' => false
632
- );
633
- }
634
-
635
- $start = time();
636
- $i0 = count($primes) + 1;
637
-
638
- do {
639
- for ($i = $i0; $i <= $num_primes; $i++) {
640
- if ($timeout !== false) {
641
- $timeout-= time() - $start;
642
- $start = time();
643
- if ($timeout <= 0) {
644
- return array(
645
- 'privatekey' => '',
646
- 'publickey' => '',
647
- 'partialkey' => serialize(array(
648
- 'primes' => $primes,
649
- 'coefficients' => $coefficients,
650
- 'lcm' => $lcm,
651
- 'exponents' => $exponents
652
- ))
653
- );
654
- }
655
- }
656
-
657
- if ($i == $num_primes) {
658
- list($min, $temp) = $absoluteMin->divide($n);
659
- if (!$temp->equals($this->zero)) {
660
- $min = $min->add($this->one); // ie. ceil()
661
- }
662
- $primes[$i] = $generator->randomPrime($min, $finalMax, $timeout);
663
- } else {
664
- $primes[$i] = $generator->randomPrime($min, $max, $timeout);
665
- }
666
-
667
- if ($primes[$i] === false) { // if we've reached the timeout
668
- if (count($primes) > 1) {
669
- $partialkey = '';
670
- } else {
671
- array_pop($primes);
672
- $partialkey = serialize(array(
673
- 'primes' => $primes,
674
- 'coefficients' => $coefficients,
675
- 'lcm' => $lcm,
676
- 'exponents' => $exponents
677
- ));
678
- }
679
-
680
- return array(
681
- 'privatekey' => '',
682
- 'publickey' => '',
683
- 'partialkey' => $partialkey
684
- );
685
- }
686
-
687
- // the first coefficient is calculated differently from the rest
688
- // ie. instead of being $primes[1]->modInverse($primes[2]), it's $primes[2]->modInverse($primes[1])
689
- if ($i > 2) {
690
- $coefficients[$i] = $n->modInverse($primes[$i]);
691
- }
692
-
693
- $n = $n->multiply($primes[$i]);
694
-
695
- $temp = $primes[$i]->subtract($this->one);
696
-
697
- // textbook RSA implementations use Euler's totient function instead of the least common multiple.
698
- // see http://en.wikipedia.org/wiki/Euler%27s_totient_function
699
- $lcm['top'] = $lcm['top']->multiply($temp);
700
- $lcm['bottom'] = $lcm['bottom'] === false ? $temp : $lcm['bottom']->gcd($temp);
701
-
702
- $exponents[$i] = $e->modInverse($temp);
703
- }
704
-
705
- list($temp) = $lcm['top']->divide($lcm['bottom']);
706
- $gcd = $temp->gcd($e);
707
- $i0 = 1;
708
- } while (!$gcd->equals($this->one));
709
-
710
- $d = $e->modInverse($temp);
711
-
712
- $coefficients[2] = $primes[2]->modInverse($primes[1]);
713
-
714
- // from <http://tools.ietf.org/html/rfc3447#appendix-A.1.2>:
715
- // RSAPrivateKey ::= SEQUENCE {
716
- // version Version,
717
- // modulus INTEGER, -- n
718
- // publicExponent INTEGER, -- e
719
- // privateExponent INTEGER, -- d
720
- // prime1 INTEGER, -- p
721
- // prime2 INTEGER, -- q
722
- // exponent1 INTEGER, -- d mod (p-1)
723
- // exponent2 INTEGER, -- d mod (q-1)
724
- // coefficient INTEGER, -- (inverse of q) mod p
725
- // otherPrimeInfos OtherPrimeInfos OPTIONAL
726
- // }
727
-
728
- return array(
729
- 'privatekey' => $this->_convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients),
730
- 'publickey' => $this->_convertPublicKey($n, $e),
731
- 'partialkey' => false
732
- );
733
- }
734
-
735
- /**
736
- * Convert a private key to the appropriate format.
737
- *
738
- * @access private
739
- * @see setPrivateKeyFormat()
740
- * @param String $RSAPrivateKey
741
- * @return String
742
- */
743
- function _convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients)
744
- {
745
- $signed = $this->privateKeyFormat != CRYPT_RSA_PRIVATE_FORMAT_XML;
746
- $num_primes = count($primes);
747
- $raw = array(
748
- 'version' => $num_primes == 2 ? chr(0) : chr(1), // two-prime vs. multi
749
- 'modulus' => $n->toBytes($signed),
750
- 'publicExponent' => $e->toBytes($signed),
751
- 'privateExponent' => $d->toBytes($signed),
752
- 'prime1' => $primes[1]->toBytes($signed),
753
- 'prime2' => $primes[2]->toBytes($signed),
754
- 'exponent1' => $exponents[1]->toBytes($signed),
755
- 'exponent2' => $exponents[2]->toBytes($signed),
756
- 'coefficient' => $coefficients[2]->toBytes($signed)
757
- );
758
-
759
- // if the format in question does not support multi-prime rsa and multi-prime rsa was used,
760
- // call _convertPublicKey() instead.
761
- switch ($this->privateKeyFormat) {
762
- case CRYPT_RSA_PRIVATE_FORMAT_XML:
763
- if ($num_primes != 2) {
764
- return false;
765
- }
766
- return "<RSAKeyValue>\r\n" .
767
- ' <Modulus>' . base64_encode($raw['modulus']) . "</Modulus>\r\n" .
768
- ' <Exponent>' . base64_encode($raw['publicExponent']) . "</Exponent>\r\n" .
769
- ' <P>' . base64_encode($raw['prime1']) . "</P>\r\n" .
770
- ' <Q>' . base64_encode($raw['prime2']) . "</Q>\r\n" .
771
- ' <DP>' . base64_encode($raw['exponent1']) . "</DP>\r\n" .
772
- ' <DQ>' . base64_encode($raw['exponent2']) . "</DQ>\r\n" .
773
- ' <InverseQ>' . base64_encode($raw['coefficient']) . "</InverseQ>\r\n" .
774
- ' <D>' . base64_encode($raw['privateExponent']) . "</D>\r\n" .
775
- '</RSAKeyValue>';
776
- break;
777
- case CRYPT_RSA_PRIVATE_FORMAT_PUTTY:
778
- if ($num_primes != 2) {
779
- return false;
780
- }
781
- $key = "PuTTY-User-Key-File-2: ssh-rsa\r\nEncryption: ";
782
- $encryption = (!empty($this->password) || is_string($this->password)) ? 'aes256-cbc' : 'none';
783
- $key.= $encryption;
784
- $key.= "\r\nComment: " . $this->comment . "\r\n";
785
- $public = pack('Na*Na*Na*',
786
- strlen('ssh-rsa'), 'ssh-rsa', strlen($raw['publicExponent']), $raw['publicExponent'], strlen($raw['modulus']), $raw['modulus']
787
- );
788
- $source = pack('Na*Na*Na*Na*',
789
- strlen('ssh-rsa'), 'ssh-rsa', strlen($encryption), $encryption,
790
- strlen($this->comment), $this->comment, strlen($public), $public
791
- );
792
- $public = base64_encode($public);
793
- $key.= "Public-Lines: " . ((strlen($public) + 63) >> 6) . "\r\n";
794
- $key.= chunk_split($public, 64);
795
- $private = pack('Na*Na*Na*Na*',
796
- strlen($raw['privateExponent']), $raw['privateExponent'], strlen($raw['prime1']), $raw['prime1'],
797
- strlen($raw['prime2']), $raw['prime2'], strlen($raw['coefficient']), $raw['coefficient']
798
- );
799
- if (empty($this->password) && !is_string($this->password)) {
800
- $source.= pack('Na*', strlen($private), $private);
801
- $hashkey = 'putty-private-key-file-mac-key';
802
- } else {
803
- $private.= crypt_random_string(16 - (strlen($private) & 15));
804
- $source.= pack('Na*', strlen($private), $private);
805
- if (!class_exists('Crypt_AES')) {
806
- include_once 'Crypt/AES.php';
807
- }
808
- $sequence = 0;
809
- $symkey = '';
810
- while (strlen($symkey) < 32) {
811
- $temp = pack('Na*', $sequence++, $this->password);
812
- $symkey.= pack('H*', sha1($temp));
813
- }
814
- $symkey = substr($symkey, 0, 32);
815
- $crypto = new Crypt_AES();
816
-
817
- $crypto->setKey($symkey);
818
- $crypto->disablePadding();
819
- $private = $crypto->encrypt($private);
820
- $hashkey = 'putty-private-key-file-mac-key' . $this->password;
821
- }
822
-
823
- $private = base64_encode($private);
824
- $key.= 'Private-Lines: ' . ((strlen($private) + 63) >> 6) . "\r\n";
825
- $key.= chunk_split($private, 64);
826
- if (!class_exists('Crypt_Hash')) {
827
- include_once 'Crypt/Hash.php';
828
- }
829
- $hash = new Crypt_Hash('sha1');
830
- $hash->setKey(pack('H*', sha1($hashkey)));
831
- $key.= 'Private-MAC: ' . bin2hex($hash->hash($source)) . "\r\n";
832
-
833
- return $key;
834
- default: // eg. CRYPT_RSA_PRIVATE_FORMAT_PKCS1
835
- $components = array();
836
- foreach ($raw as $name => $value) {
837
- $components[$name] = pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($value)), $value);
838
- }
839
-
840
- $RSAPrivateKey = implode('', $components);
841
-
842
- if ($num_primes > 2) {
843
- $OtherPrimeInfos = '';
844
- for ($i = 3; $i <= $num_primes; $i++) {
845
- // OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
846
- //
847
- // OtherPrimeInfo ::= SEQUENCE {
848
- // prime INTEGER, -- ri
849
- // exponent INTEGER, -- di
850
- // coefficient INTEGER -- ti
851
- // }
852
- $OtherPrimeInfo = pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($primes[$i]->toBytes(true))), $primes[$i]->toBytes(true));
853
- $OtherPrimeInfo.= pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($exponents[$i]->toBytes(true))), $exponents[$i]->toBytes(true));
854
- $OtherPrimeInfo.= pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($coefficients[$i]->toBytes(true))), $coefficients[$i]->toBytes(true));
855
- $OtherPrimeInfos.= pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($OtherPrimeInfo)), $OtherPrimeInfo);
856
- }
857
- $RSAPrivateKey.= pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($OtherPrimeInfos)), $OtherPrimeInfos);
858
- }
859
-
860
- $RSAPrivateKey = pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
861
-
862
- if ($this->privateKeyFormat == CRYPT_RSA_PRIVATE_FORMAT_PKCS8) {
863
- $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
864
- $RSAPrivateKey = pack('Ca*a*Ca*a*',
865
- CRYPT_RSA_ASN1_INTEGER, "\01\00", $rsaOID, 4, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey
866
- );
867
- $RSAPrivateKey = pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
868
- if (!empty($this->password) || is_string($this->password)) {
869
- $salt = crypt_random_string(8);
870
- $iterationCount = 2048;
871
-
872
- if (!class_exists('Crypt_DES')) {
873
- include_once 'Crypt/DES.php';
874
- }
875
- $crypto = new Crypt_DES();
876
- $crypto->setPassword($this->password, 'pbkdf1', 'md5', $salt, $iterationCount);
877
- $RSAPrivateKey = $crypto->encrypt($RSAPrivateKey);
878
-
879
- $parameters = pack('Ca*a*Ca*N',
880
- CRYPT_RSA_ASN1_OCTETSTRING, $this->_encodeLength(strlen($salt)), $salt,
881
- CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(4), $iterationCount
882
- );
883
- $pbeWithMD5AndDES_CBC = "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03";
884
-
885
- $encryptionAlgorithm = pack('Ca*a*Ca*a*',
886
- CRYPT_RSA_ASN1_OBJECT, $this->_encodeLength(strlen($pbeWithMD5AndDES_CBC)), $pbeWithMD5AndDES_CBC,
887
- CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($parameters)), $parameters
888
- );
889
-
890
- $RSAPrivateKey = pack('Ca*a*Ca*a*',
891
- CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($encryptionAlgorithm)), $encryptionAlgorithm,
892
- CRYPT_RSA_ASN1_OCTETSTRING, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey
893
- );
894
-
895
- $RSAPrivateKey = pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
896
-
897
- $RSAPrivateKey = "-----BEGIN ENCRYPTED PRIVATE KEY-----\r\n" .
898
- chunk_split(base64_encode($RSAPrivateKey), 64) .
899
- '-----END ENCRYPTED PRIVATE KEY-----';
900
- } else {
901
- $RSAPrivateKey = "-----BEGIN PRIVATE KEY-----\r\n" .
902
- chunk_split(base64_encode($RSAPrivateKey), 64) .
903
- '-----END PRIVATE KEY-----';
904
- }
905
- return $RSAPrivateKey;
906
- }
907
-
908
- if (!empty($this->password) || is_string($this->password)) {
909
- $iv = crypt_random_string(8);
910
- $symkey = pack('H*', md5($this->password . $iv)); // symkey is short for symmetric key
911
- $symkey.= substr(pack('H*', md5($symkey . $this->password . $iv)), 0, 8);
912
- if (!class_exists('Crypt_TripleDES')) {
913
- include_once 'Crypt/TripleDES.php';
914
- }
915
- $des = new Crypt_TripleDES();
916
- $des->setKey($symkey);
917
- $des->setIV($iv);
918
- $iv = strtoupper(bin2hex($iv));
919
- $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .
920
- "Proc-Type: 4,ENCRYPTED\r\n" .
921
- "DEK-Info: DES-EDE3-CBC,$iv\r\n" .
922
- "\r\n" .
923
- chunk_split(base64_encode($des->encrypt($RSAPrivateKey)), 64) .
924
- '-----END RSA PRIVATE KEY-----';
925
- } else {
926
- $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .
927
- chunk_split(base64_encode($RSAPrivateKey), 64) .
928
- '-----END RSA PRIVATE KEY-----';
929
- }
930
-
931
- return $RSAPrivateKey;
932
- }
933
- }
934
-
935
- /**
936
- * Convert a public key to the appropriate format
937
- *
938
- * @access private
939
- * @see setPublicKeyFormat()
940
- * @param String $RSAPrivateKey
941
- * @return String
942
- */
943
- function _convertPublicKey($n, $e)
944
- {
945
- $signed = $this->publicKeyFormat != CRYPT_RSA_PUBLIC_FORMAT_XML;
946
-
947
- $modulus = $n->toBytes($signed);
948
- $publicExponent = $e->toBytes($signed);
949
-
950
- switch ($this->publicKeyFormat) {
951
- case CRYPT_RSA_PUBLIC_FORMAT_RAW:
952
- return array('e' => $e->copy(), 'n' => $n->copy());
953
- case CRYPT_RSA_PUBLIC_FORMAT_XML:
954
- return "<RSAKeyValue>\r\n" .
955
- ' <Modulus>' . base64_encode($modulus) . "</Modulus>\r\n" .
956
- ' <Exponent>' . base64_encode($publicExponent) . "</Exponent>\r\n" .
957
- '</RSAKeyValue>';
958
- break;
959
- case CRYPT_RSA_PUBLIC_FORMAT_OPENSSH:
960
- // from <http://tools.ietf.org/html/rfc4253#page-15>:
961
- // string "ssh-rsa"
962
- // mpint e
963
- // mpint n
964
- $RSAPublicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publicExponent), $publicExponent, strlen($modulus), $modulus);
965
- $RSAPublicKey = 'ssh-rsa ' . base64_encode($RSAPublicKey) . ' ' . $this->comment;
966
-
967
- return $RSAPublicKey;
968
- default: // eg. CRYPT_RSA_PUBLIC_FORMAT_PKCS1_RAW or CRYPT_RSA_PUBLIC_FORMAT_PKCS1
969
- // from <http://tools.ietf.org/html/rfc3447#appendix-A.1.1>:
970
- // RSAPublicKey ::= SEQUENCE {
971
- // modulus INTEGER, -- n
972
- // publicExponent INTEGER -- e
973
- // }
974
- $components = array(
975
- 'modulus' => pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($modulus)), $modulus),
976
- 'publicExponent' => pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($publicExponent)), $publicExponent)
977
- );
978
-
979
- $RSAPublicKey = pack('Ca*a*a*',
980
- CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])),
981
- $components['modulus'], $components['publicExponent']
982
- );
983
-
984
- if ($this->publicKeyFormat == CRYPT_RSA_PUBLIC_FORMAT_PKCS1_RAW) {
985
- $RSAPublicKey = "-----BEGIN RSA PUBLIC KEY-----\r\n" .
986
- chunk_split(base64_encode($RSAPublicKey), 64) .
987
- '-----END RSA PUBLIC KEY-----';
988
- } else {
989
- // sequence(oid(1.2.840.113549.1.1.1), null)) = rsaEncryption.
990
- $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
991
- $RSAPublicKey = chr(0) . $RSAPublicKey;
992
- $RSAPublicKey = chr(3) . $this->_encodeLength(strlen($RSAPublicKey)) . $RSAPublicKey;
993
-
994
- $RSAPublicKey = pack('Ca*a*',
995
- CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($rsaOID . $RSAPublicKey)), $rsaOID . $RSAPublicKey
996
- );
997
-
998
- $RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" .
999
- chunk_split(base64_encode($RSAPublicKey), 64) .
1000
- '-----END PUBLIC KEY-----';
1001
- }
1002
-
1003
- return $RSAPublicKey;
1004
- }
1005
- }
1006
-
1007
- /**
1008
- * Break a public or private key down into its constituant components
1009
- *
1010
- * @access private
1011
- * @see _convertPublicKey()
1012
- * @see _convertPrivateKey()
1013
- * @param String $key
1014
- * @param Integer $type
1015
- * @return Array
1016
- */
1017
- function _parseKey($key, $type)
1018
- {
1019
- if ($type != CRYPT_RSA_PUBLIC_FORMAT_RAW && !is_string($key)) {
1020
- return false;
1021
- }
1022
-
1023
- switch ($type) {
1024
- case CRYPT_RSA_PUBLIC_FORMAT_RAW:
1025
- if (!is_array($key)) {
1026
- return false;
1027
- }
1028
- $components = array();
1029
- switch (true) {
1030
- case isset($key['e']):
1031
- $components['publicExponent'] = $key['e']->copy();
1032
- break;
1033
- case isset($key['exponent']):
1034
- $components['publicExponent'] = $key['exponent']->copy();
1035
- break;
1036
- case isset($key['publicExponent']):
1037
- $components['publicExponent'] = $key['publicExponent']->copy();
1038
- break;
1039
- case isset($key[0]):
1040
- $components['publicExponent'] = $key[0]->copy();
1041
- }
1042
- switch (true) {
1043
- case isset($key['n']):
1044
- $components['modulus'] = $key['n']->copy();
1045
- break;
1046
- case isset($key['modulo']):
1047
- $components['modulus'] = $key['modulo']->copy();
1048
- break;
1049
- case isset($key['modulus']):
1050
- $components['modulus'] = $key['modulus']->copy();
1051
- break;
1052
- case isset($key[1]):
1053
- $components['modulus'] = $key[1]->copy();
1054
- }
1055
- return isset($components['modulus']) && isset($components['publicExponent']) ? $components : false;
1056
- case CRYPT_RSA_PRIVATE_FORMAT_PKCS1:
1057
- case CRYPT_RSA_PRIVATE_FORMAT_PKCS8:
1058
- case CRYPT_RSA_PUBLIC_FORMAT_PKCS1:
1059
- /* Although PKCS#1 proposes a format that public and private keys can use, encrypting them is
1060
- "outside the scope" of PKCS#1. PKCS#1 then refers you to PKCS#12 and PKCS#15 if you're wanting to
1061
- protect private keys, however, that's not what OpenSSL* does. OpenSSL protects private keys by adding
1062
- two new "fields" to the key - DEK-Info and Proc-Type. These fields are discussed here:
1063
-
1064
- http://tools.ietf.org/html/rfc1421#section-4.6.1.1
1065
- http://tools.ietf.org/html/rfc1421#section-4.6.1.3
1066
-
1067
- DES-EDE3-CBC as an algorithm, however, is not discussed anywhere, near as I can tell.
1068
- DES-CBC and DES-EDE are discussed in RFC1423, however, DES-EDE3-CBC isn't, nor is its key derivation
1069
- function. As is, the definitive authority on this encoding scheme isn't the IETF but rather OpenSSL's
1070
- own implementation. ie. the implementation *is* the standard and any bugs that may exist in that
1071
- implementation are part of the standard, as well.
1072
-
1073
- * OpenSSL is the de facto standard. It's utilized by OpenSSH and other projects */
1074
- if (preg_match('#DEK-Info: (.+),(.+)#', $key, $matches)) {
1075
- $iv = pack('H*', trim($matches[2]));
1076
- $symkey = pack('H*', md5($this->password . substr($iv, 0, 8))); // symkey is short for symmetric key
1077
- $symkey.= pack('H*', md5($symkey . $this->password . substr($iv, 0, 8)));
1078
- // remove the Proc-Type / DEK-Info sections as they're no longer needed
1079
- $key = preg_replace('#^(?:Proc-Type|DEK-Info): .*#m', '', $key);
1080
- $ciphertext = $this->_extractBER($key);
1081
- if ($ciphertext === false) {
1082
- $ciphertext = $key;
1083
- }
1084
- switch ($matches[1]) {
1085
- case 'AES-256-CBC':
1086
- if (!class_exists('Crypt_AES')) {
1087
- include_once 'Crypt/AES.php';
1088
- }
1089
- $crypto = new Crypt_AES();
1090
- break;
1091
- case 'AES-128-CBC':
1092
- if (!class_exists('Crypt_AES')) {
1093
- include_once 'Crypt/AES.php';
1094
- }
1095
- $symkey = substr($symkey, 0, 16);
1096
- $crypto = new Crypt_AES();
1097
- break;
1098
- case 'DES-EDE3-CFB':
1099
- if (!class_exists('Crypt_TripleDES')) {
1100
- include_once 'Crypt/TripleDES.php';
1101
- }
1102
- $crypto = new Crypt_TripleDES(CRYPT_DES_MODE_CFB);
1103
- break;
1104
- case 'DES-EDE3-CBC':
1105
- if (!class_exists('Crypt_TripleDES')) {
1106
- include_once 'Crypt/TripleDES.php';
1107
- }
1108
- $symkey = substr($symkey, 0, 24);
1109
- $crypto = new Crypt_TripleDES();
1110
- break;
1111
- case 'DES-CBC':
1112
- if (!class_exists('Crypt_DES')) {
1113
- include_once 'Crypt/DES.php';
1114
- }
1115
- $crypto = new Crypt_DES();
1116
- break;
1117
- default:
1118
- return false;
1119
- }
1120
- $crypto->setKey($symkey);
1121
- $crypto->setIV($iv);
1122
- $decoded = $crypto->decrypt($ciphertext);
1123
- } else {
1124
- $decoded = $this->_extractBER($key);
1125
- }
1126
-
1127
- if ($decoded !== false) {
1128
- $key = $decoded;
1129
- }
1130
-
1131
- $components = array();
1132
-
1133
- if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_SEQUENCE) {
1134
- return false;
1135
- }
1136
- if ($this->_decodeLength($key) != strlen($key)) {
1137
- return false;
1138
- }
1139
-
1140
- $tag = ord($this->_string_shift($key));
1141
- /* intended for keys for which OpenSSL's asn1parse returns the following:
1142
-
1143
- 0:d=0 hl=4 l= 631 cons: SEQUENCE
1144
- 4:d=1 hl=2 l= 1 prim: INTEGER :00
1145
- 7:d=1 hl=2 l= 13 cons: SEQUENCE
1146
- 9:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
1147
- 20:d=2 hl=2 l= 0 prim: NULL
1148
- 22:d=1 hl=4 l= 609 prim: OCTET STRING
1149
-
1150
- ie. PKCS8 keys*/
1151
-
1152
- if ($tag == CRYPT_RSA_ASN1_INTEGER && substr($key, 0, 3) == "\x01\x00\x30") {
1153
- $this->_string_shift($key, 3);
1154
- $tag = CRYPT_RSA_ASN1_SEQUENCE;
1155
- }
1156
-
1157
- if ($tag == CRYPT_RSA_ASN1_SEQUENCE) {
1158
- $temp = $this->_string_shift($key, $this->_decodeLength($key));
1159
- if (ord($this->_string_shift($temp)) != CRYPT_RSA_ASN1_OBJECT) {
1160
- return false;
1161
- }
1162
- $length = $this->_decodeLength($temp);
1163
- switch ($this->_string_shift($temp, $length)) {
1164
- case "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01": // rsaEncryption
1165
- break;
1166
- case "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03": // pbeWithMD5AndDES-CBC
1167
- /*
1168
- PBEParameter ::= SEQUENCE {
1169
- salt OCTET STRING (SIZE(8)),
1170
- iterationCount INTEGER }
1171
- */
1172
- if (ord($this->_string_shift($temp)) != CRYPT_RSA_ASN1_SEQUENCE) {
1173
- return false;
1174
- }
1175
- if ($this->_decodeLength($temp) != strlen($temp)) {
1176
- return false;
1177
- }
1178
- $this->_string_shift($temp); // assume it's an octet string
1179
- $salt = $this->_string_shift($temp, $this->_decodeLength($temp));
1180
- if (ord($this->_string_shift($temp)) != CRYPT_RSA_ASN1_INTEGER) {
1181
- return false;
1182
- }
1183
- $this->_decodeLength($temp);
1184
- list(, $iterationCount) = unpack('N', str_pad($temp, 4, chr(0), STR_PAD_LEFT));
1185
- $this->_string_shift($key); // assume it's an octet string
1186
- $length = $this->_decodeLength($key);
1187
- if (strlen($key) != $length) {
1188
- return false;
1189
- }
1190
-
1191
- if (!class_exists('Crypt_DES')) {
1192
- include_once 'Crypt/DES.php';
1193
- }
1194
- $crypto = new Crypt_DES();
1195
- $crypto->setPassword($this->password, 'pbkdf1', 'md5', $salt, $iterationCount);
1196
- $key = $crypto->decrypt($key);
1197
- if ($key === false) {
1198
- return false;
1199
- }
1200
- return $this->_parseKey($key, CRYPT_RSA_PRIVATE_FORMAT_PKCS1);
1201
- default:
1202
- return false;
1203
- }
1204
- /* intended for keys for which OpenSSL's asn1parse returns the following:
1205
-
1206
- 0:d=0 hl=4 l= 290 cons: SEQUENCE
1207
- 4:d=1 hl=2 l= 13 cons: SEQUENCE
1208
- 6:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
1209
- 17:d=2 hl=2 l= 0 prim: NULL
1210
- 19:d=1 hl=4 l= 271 prim: BIT STRING */
1211
- $tag = ord($this->_string_shift($key)); // skip over the BIT STRING / OCTET STRING tag
1212
- $this->_decodeLength($key); // skip over the BIT STRING / OCTET STRING length
1213
- // "The initial octet shall encode, as an unsigned binary integer wtih bit 1 as the least significant bit, the number of
1214
- // unused bits in the final subsequent octet. The number shall be in the range zero to seven."
1215
- // -- http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf (section 8.6.2.2)
1216
- if ($tag == CRYPT_RSA_ASN1_BITSTRING) {
1217
- $this->_string_shift($key);
1218
- }
1219
- if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_SEQUENCE) {
1220
- return false;
1221
- }
1222
- if ($this->_decodeLength($key) != strlen($key)) {
1223
- return false;
1224
- }
1225
- $tag = ord($this->_string_shift($key));
1226
- }
1227
- if ($tag != CRYPT_RSA_ASN1_INTEGER) {
1228
- return false;
1229
- }
1230
-
1231
- $length = $this->_decodeLength($key);
1232
- $temp = $this->_string_shift($key, $length);
1233
- if (strlen($temp) != 1 || ord($temp) > 2) {
1234
- $components['modulus'] = new Math_BigInteger($temp, 256);
1235
- $this->_string_shift($key); // skip over CRYPT_RSA_ASN1_INTEGER
1236
- $length = $this->_decodeLength($key);
1237
- $components[$type == CRYPT_RSA_PUBLIC_FORMAT_PKCS1 ? 'publicExponent' : 'privateExponent'] = new Math_BigInteger($this->_string_shift($key, $length), 256);
1238
-
1239
- return $components;
1240
- }
1241
- if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_INTEGER) {
1242
- return false;
1243
- }
1244
- $length = $this->_decodeLength($key);
1245
- $components['modulus'] = new Math_BigInteger($this->_string_shift($key, $length), 256);
1246
- $this->_string_shift($key);
1247
- $length = $this->_decodeLength($key);
1248
- $components['publicExponent'] = new Math_BigInteger($this->_string_shift($key, $length), 256);
1249
- $this->_string_shift($key);
1250
- $length = $this->_decodeLength($key);
1251
- $components['privateExponent'] = new Math_BigInteger($this->_string_shift($key, $length), 256);
1252
- $this->_string_shift($key);
1253
- $length = $this->_decodeLength($key);
1254
- $components['primes'] = array(1 => new Math_BigInteger($this->_string_shift($key, $length), 256));
1255
- $this->_string_shift($key);
1256
- $length = $this->_decodeLength($key);
1257
- $components['primes'][] = new Math_BigInteger($this->_string_shift($key, $length), 256);
1258
- $this->_string_shift($key);
1259
- $length = $this->_decodeLength($key);
1260
- $components['exponents'] = array(1 => new Math_BigInteger($this->_string_shift($key, $length), 256));
1261
- $this->_string_shift($key);
1262
- $length = $this->_decodeLength($key);
1263
- $components['exponents'][] = new Math_BigInteger($this->_string_shift($key, $length), 256);
1264
- $this->_string_shift($key);
1265
- $length = $this->_decodeLength($key);
1266
- $components['coefficients'] = array(2 => new Math_BigInteger($this->_string_shift($key, $length), 256));
1267
-
1268
- if (!empty($key)) {
1269
- if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_SEQUENCE) {
1270
- return false;
1271
- }
1272
- $this->_decodeLength($key);
1273
- while (!empty($key)) {
1274
- if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_SEQUENCE) {
1275
- return false;
1276
- }
1277
- $this->_decodeLength($key);
1278
- $key = substr($key, 1);
1279
- $length = $this->_decodeLength($key);
1280
- $components['primes'][] = new Math_BigInteger($this->_string_shift($key, $length), 256);
1281
- $this->_string_shift($key);
1282
- $length = $this->_decodeLength($key);
1283
- $components['exponents'][] = new Math_BigInteger($this->_string_shift($key, $length), 256);
1284
- $this->_string_shift($key);
1285
- $length = $this->_decodeLength($key);
1286
- $components['coefficients'][] = new Math_BigInteger($this->_string_shift($key, $length), 256);
1287
- }
1288
- }
1289
-
1290
- return $components;
1291
- case CRYPT_RSA_PUBLIC_FORMAT_OPENSSH:
1292
- $parts = explode(' ', $key, 3);
1293
-
1294
- $key = isset($parts[1]) ? base64_decode($parts[1]) : false;
1295
- if ($key === false) {
1296
- return false;
1297
- }
1298
-
1299
- $comment = isset($parts[2]) ? $parts[2] : false;
1300
-
1301
- $cleanup = substr($key, 0, 11) == "\0\0\0\7ssh-rsa";
1302
-
1303
- if (strlen($key) <= 4) {
1304
- return false;
1305
- }
1306
- extract(unpack('Nlength', $this->_string_shift($key, 4)));
1307
- $publicExponent = new Math_BigInteger($this->_string_shift($key, $length), -256);
1308
- if (strlen($key) <= 4) {
1309
- return false;
1310
- }
1311
- extract(unpack('Nlength', $this->_string_shift($key, 4)));
1312
- $modulus = new Math_BigInteger($this->_string_shift($key, $length), -256);
1313
-
1314
- if ($cleanup && strlen($key)) {
1315
- if (strlen($key) <= 4) {
1316
- return false;
1317
- }
1318
- extract(unpack('Nlength', $this->_string_shift($key, 4)));
1319
- $realModulus = new Math_BigInteger($this->_string_shift($key, $length), -256);
1320
- return strlen($key) ? false : array(
1321
- 'modulus' => $realModulus,
1322
- 'publicExponent' => $modulus,
1323
- 'comment' => $comment
1324
- );
1325
- } else {
1326
- return strlen($key) ? false : array(
1327
- 'modulus' => $modulus,
1328
- 'publicExponent' => $publicExponent,
1329
- 'comment' => $comment
1330
- );
1331
- }
1332
- // http://www.w3.org/TR/xmldsig-core/#sec-RSAKeyValue
1333
- // http://en.wikipedia.org/wiki/XML_Signature
1334
- case CRYPT_RSA_PRIVATE_FORMAT_XML:
1335
- case CRYPT_RSA_PUBLIC_FORMAT_XML:
1336
- $this->components = array();
1337
-
1338
- $xml = xml_parser_create('UTF-8');
1339
- xml_set_object($xml, $this);
1340
- xml_set_element_handler($xml, '_start_element_handler', '_stop_element_handler');
1341
- xml_set_character_data_handler($xml, '_data_handler');
1342
- // add <xml></xml> to account for "dangling" tags like <BitStrength>...</BitStrength> that are sometimes added
1343
- if (!xml_parse($xml, '<xml>' . $key . '</xml>')) {
1344
- return false;
1345
- }
1346
-
1347
- return isset($this->components['modulus']) && isset($this->components['publicExponent']) ? $this->components : false;
1348
- // from PuTTY's SSHPUBK.C
1349
- case CRYPT_RSA_PRIVATE_FORMAT_PUTTY:
1350
- $components = array();
1351
- $key = preg_split('#\r\n|\r|\n#', $key);
1352
- $type = trim(preg_replace('#PuTTY-User-Key-File-2: (.+)#', '$1', $key[0]));
1353
- if ($type != 'ssh-rsa') {
1354
- return false;
1355
- }
1356
- $encryption = trim(preg_replace('#Encryption: (.+)#', '$1', $key[1]));
1357
- $comment = trim(preg_replace('#Comment: (.+)#', '$1', $key[2]));
1358
-
1359
- $publicLength = trim(preg_replace('#Public-Lines: (\d+)#', '$1', $key[3]));
1360
- $public = base64_decode(implode('', array_map('trim', array_slice($key, 4, $publicLength))));
1361
- $public = substr($public, 11);
1362
- extract(unpack('Nlength', $this->_string_shift($public, 4)));
1363
- $components['publicExponent'] = new Math_BigInteger($this->_string_shift($public, $length), -256);
1364
- extract(unpack('Nlength', $this->_string_shift($public, 4)));
1365
- $components['modulus'] = new Math_BigInteger($this->_string_shift($public, $length), -256);
1366
-
1367
- $privateLength = trim(preg_replace('#Private-Lines: (\d+)#', '$1', $key[$publicLength + 4]));
1368
- $private = base64_decode(implode('', array_map('trim', array_slice($key, $publicLength + 5, $privateLength))));
1369
-
1370
- switch ($encryption) {
1371
- case 'aes256-cbc':
1372
- if (!class_exists('Crypt_AES')) {
1373
- include_once 'Crypt/AES.php';
1374
- }
1375
- $symkey = '';
1376
- $sequence = 0;
1377
- while (strlen($symkey) < 32) {
1378
- $temp = pack('Na*', $sequence++, $this->password);
1379
- $symkey.= pack('H*', sha1($temp));
1380
- }
1381
- $symkey = substr($symkey, 0, 32);
1382
- $crypto = new Crypt_AES();
1383
- }
1384
-
1385
- if ($encryption != 'none') {
1386
- $crypto->setKey($symkey);
1387
- $crypto->disablePadding();
1388
- $private = $crypto->decrypt($private);
1389
- if ($private === false) {
1390
- return false;
1391
- }
1392
- }
1393
-
1394
- extract(unpack('Nlength', $this->_string_shift($private, 4)));
1395
- if (strlen($private) < $length) {
1396
- return false;
1397
- }
1398
- $components['privateExponent'] = new Math_BigInteger($this->_string_shift($private, $length), -256);
1399
- extract(unpack('Nlength', $this->_string_shift($private, 4)));
1400
- if (strlen($private) < $length) {
1401
- return false;
1402
- }
1403
- $components['primes'] = array(1 => new Math_BigInteger($this->_string_shift($private, $length), -256));
1404
- extract(unpack('Nlength', $this->_string_shift($private, 4)));
1405
- if (strlen($private) < $length) {
1406
- return false;
1407
- }
1408
- $components['primes'][] = new Math_BigInteger($this->_string_shift($private, $length), -256);
1409
-
1410
- $temp = $components['primes'][1]->subtract($this->one);
1411
- $components['exponents'] = array(1 => $components['publicExponent']->modInverse($temp));
1412
- $temp = $components['primes'][2]->subtract($this->one);
1413
- $components['exponents'][] = $components['publicExponent']->modInverse($temp);
1414
-
1415
- extract(unpack('Nlength', $this->_string_shift($private, 4)));
1416
- if (strlen($private) < $length) {
1417
- return false;
1418
- }
1419
- $components['coefficients'] = array(2 => new Math_BigInteger($this->_string_shift($private, $length), -256));
1420
-
1421
- return $components;
1422
- }
1423
- }
1424
-
1425
- /**
1426
- * Returns the key size
1427
- *
1428
- * More specifically, this returns the size of the modulo in bits.
1429
- *
1430
- * @access public
1431
- * @return Integer
1432
- */
1433
- function getSize()
1434
- {
1435
- return !isset($this->modulus) ? 0 : strlen($this->modulus->toBits());
1436
- }
1437
-
1438
- /**
1439
- * Start Element Handler
1440
- *
1441
- * Called by xml_set_element_handler()
1442
- *
1443
- * @access private
1444
- * @param Resource $parser
1445
- * @param String $name
1446
- * @param Array $attribs
1447
- */
1448
- function _start_element_handler($parser, $name, $attribs)
1449
- {
1450
- //$name = strtoupper($name);
1451
- switch ($name) {
1452
- case 'MODULUS':
1453
- $this->current = &$this->components['modulus'];
1454
- break;
1455
- case 'EXPONENT':
1456
- $this->current = &$this->components['publicExponent'];
1457
- break;
1458
- case 'P':
1459
- $this->current = &$this->components['primes'][1];
1460
- break;
1461
- case 'Q':
1462
- $this->current = &$this->components['primes'][2];
1463
- break;
1464
- case 'DP':
1465
- $this->current = &$this->components['exponents'][1];
1466
- break;
1467
- case 'DQ':
1468
- $this->current = &$this->components['exponents'][2];
1469
- break;
1470
- case 'INVERSEQ':
1471
- $this->current = &$this->components['coefficients'][2];
1472
- break;
1473
- case 'D':
1474
- $this->current = &$this->components['privateExponent'];
1475
- }
1476
- $this->current = '';
1477
- }
1478
-
1479
- /**
1480
- * Stop Element Handler
1481
- *
1482
- * Called by xml_set_element_handler()
1483
- *
1484
- * @access private
1485
- * @param Resource $parser
1486
- * @param String $name
1487
- */
1488
- function _stop_element_handler($parser, $name)
1489
- {
1490
- if (isset($this->current)) {
1491
- $this->current = new Math_BigInteger(base64_decode($this->current), 256);
1492
- unset($this->current);
1493
- }
1494
- }
1495
-
1496
- /**
1497
- * Data Handler
1498
- *
1499
- * Called by xml_set_character_data_handler()
1500
- *
1501
- * @access private
1502
- * @param Resource $parser
1503
- * @param String $data
1504
- */
1505
- function _data_handler($parser, $data)
1506
- {
1507
- if (!isset($this->current) || is_object($this->current)) {
1508
- return;
1509
- }
1510
- $this->current.= trim($data);
1511
- }
1512
-
1513
- /**
1514
- * Loads a public or private key
1515
- *
1516
- * Returns true on success and false on failure (ie. an incorrect password was provided or the key was malformed)
1517
- *
1518
- * @access public
1519
- * @param String $key
1520
- * @param Integer $type optional
1521
- */
1522
- function loadKey($key, $type = false)
1523
- {
1524
- if (is_object($key) && strtolower(get_class($key)) == 'crypt_rsa') {
1525
- $this->privateKeyFormat = $key->privateKeyFormat;
1526
- $this->publicKeyFormat = $key->publicKeyFormat;
1527
- $this->k = $key->k;
1528
- $this->hLen = $key->hLen;
1529
- $this->sLen = $key->sLen;
1530
- $this->mgfHLen = $key->mgfHLen;
1531
- $this->encryptionMode = $key->encryptionMode;
1532
- $this->signatureMode = $key->signatureMode;
1533
- $this->password = $key->password;
1534
- $this->configFile = $key->configFile;
1535
- $this->comment = $key->comment;
1536
-
1537
- if (is_object($key->hash)) {
1538
- $this->hash = new Crypt_Hash($key->hash->getHash());
1539
- }
1540
- if (is_object($key->mgfHash)) {
1541
- $this->mgfHash = new Crypt_Hash($key->mgfHash->getHash());
1542
- }
1543
-
1544
- if (is_object($key->modulus)) {
1545
- $this->modulus = $key->modulus->copy();
1546
- }
1547
- if (is_object($key->exponent)) {
1548
- $this->exponent = $key->exponent->copy();
1549
- }
1550
- if (is_object($key->publicExponent)) {
1551
- $this->publicExponent = $key->publicExponent->copy();
1552
- }
1553
-
1554
- $this->primes = array();
1555
- $this->exponents = array();
1556
- $this->coefficients = array();
1557
-
1558
- foreach ($this->primes as $prime) {
1559
- $this->primes[] = $prime->copy();
1560
- }
1561
- foreach ($this->exponents as $exponent) {
1562
- $this->exponents[] = $exponent->copy();
1563
- }
1564
- foreach ($this->coefficients as $coefficient) {
1565
- $this->coefficients[] = $coefficient->copy();
1566
- }
1567
-
1568
- return true;
1569
- }
1570
-
1571
- if ($type === false) {
1572
- $types = array(
1573
- CRYPT_RSA_PUBLIC_FORMAT_RAW,
1574
- CRYPT_RSA_PRIVATE_FORMAT_PKCS1,
1575
- CRYPT_RSA_PRIVATE_FORMAT_XML,
1576
- CRYPT_RSA_PRIVATE_FORMAT_PUTTY,
1577
- CRYPT_RSA_PUBLIC_FORMAT_OPENSSH
1578
- );
1579
- foreach ($types as $type) {
1580
- $components = $this->_parseKey($key, $type);
1581
- if ($components !== false) {
1582
- break;
1583
- }
1584
- }
1585
-
1586
- } else {
1587
- $components = $this->_parseKey($key, $type);
1588
- }
1589
-
1590
- if ($components === false) {
1591
- return false;
1592
- }
1593
-
1594
- if (isset($components['comment']) && $components['comment'] !== false) {
1595
- $this->comment = $components['comment'];
1596
- }
1597
- $this->modulus = $components['modulus'];
1598
- $this->k = strlen($this->modulus->toBytes());
1599
- $this->exponent = isset($components['privateExponent']) ? $components['privateExponent'] : $components['publicExponent'];
1600
- if (isset($components['primes'])) {
1601
- $this->primes = $components['primes'];
1602
- $this->exponents = $components['exponents'];
1603
- $this->coefficients = $components['coefficients'];
1604
- $this->publicExponent = $components['publicExponent'];
1605
- } else {
1606
- $this->primes = array();
1607
- $this->exponents = array();
1608
- $this->coefficients = array();
1609
- $this->publicExponent = false;
1610
- }
1611
-
1612
- switch ($type) {
1613
- case CRYPT_RSA_PUBLIC_FORMAT_OPENSSH:
1614
- case CRYPT_RSA_PUBLIC_FORMAT_RAW:
1615
- $this->setPublicKey();
1616
- break;
1617
- case CRYPT_RSA_PRIVATE_FORMAT_PKCS1:
1618
- switch (true) {
1619
- case strpos($key, '-BEGIN PUBLIC KEY-') !== false:
1620
- case strpos($key, '-BEGIN RSA PUBLIC KEY-') !== false:
1621
- $this->setPublicKey();
1622
- }
1623
- }
1624
-
1625
- return true;
1626
- }
1627
-
1628
- /**
1629
- * Sets the password
1630
- *
1631
- * Private keys can be encrypted with a password. To unset the password, pass in the empty string or false.
1632
- * Or rather, pass in $password such that empty($password) && !is_string($password) is true.
1633
- *
1634
- * @see createKey()
1635
- * @see loadKey()
1636
- * @access public
1637
- * @param String $password
1638
- */
1639
- function setPassword($password = false)
1640
- {
1641
- $this->password = $password;
1642
- }
1643
-
1644
- /**
1645
- * Defines the public key
1646
- *
1647
- * Some private key formats define the public exponent and some don't. Those that don't define it are problematic when
1648
- * used in certain contexts. For example, in SSH-2, RSA authentication works by sending the public key along with a
1649
- * message signed by the private key to the server. The SSH-2 server looks the public key up in an index of public keys
1650
- * and if it's present then proceeds to verify the signature. Problem is, if your private key doesn't include the public
1651
- * exponent this won't work unless you manually add the public exponent. phpseclib tries to guess if the key being used
1652
- * is the public key but in the event that it guesses incorrectly you might still want to explicitly set the key as being
1653
- * public.
1654
- *
1655
- * Do note that when a new key is loaded the index will be cleared.
1656
- *
1657
- * Returns true on success, false on failure
1658
- *
1659
- * @see getPublicKey()
1660
- * @access public
1661
- * @param String $key optional
1662
- * @param Integer $type optional
1663
- * @return Boolean
1664
- */
1665
- function setPublicKey($key = false, $type = false)
1666
- {
1667
- // if a public key has already been loaded return false
1668
- if (!empty($this->publicExponent)) {
1669
- return false;
1670
- }
1671
-
1672
- if ($key === false && !empty($this->modulus)) {
1673
- $this->publicExponent = $this->exponent;
1674
- return true;
1675
- }
1676
-
1677
- if ($type === false) {
1678
- $types = array(
1679
- CRYPT_RSA_PUBLIC_FORMAT_RAW,
1680
- CRYPT_RSA_PUBLIC_FORMAT_PKCS1,
1681
- CRYPT_RSA_PUBLIC_FORMAT_XML,
1682
- CRYPT_RSA_PUBLIC_FORMAT_OPENSSH
1683
- );
1684
- foreach ($types as $type) {
1685
- $components = $this->_parseKey($key, $type);
1686
- if ($components !== false) {
1687
- break;
1688
- }
1689
- }
1690
- } else {
1691
- $components = $this->_parseKey($key, $type);
1692
- }
1693
-
1694
- if ($components === false) {
1695
- return false;
1696
- }
1697
-
1698
- if (empty($this->modulus) || !$this->modulus->equals($components['modulus'])) {
1699
- $this->modulus = $components['modulus'];
1700
- $this->exponent = $this->publicExponent = $components['publicExponent'];
1701
- return true;
1702
- }
1703
-
1704
- $this->publicExponent = $components['publicExponent'];
1705
-
1706
- return true;
1707
- }
1708
-
1709
- /**
1710
- * Defines the private key
1711
- *
1712
- * If phpseclib guessed a private key was a public key and loaded it as such it might be desirable to force
1713
- * phpseclib to treat the key as a private key. This function will do that.
1714
- *
1715
- * Do note that when a new key is loaded the index will be cleared.
1716
- *
1717
- * Returns true on success, false on failure
1718
- *
1719
- * @see getPublicKey()
1720
- * @access public
1721
- * @param String $key optional
1722
- * @param Integer $type optional
1723
- * @return Boolean
1724
- */
1725
- function setPrivateKey($key = false, $type = false)
1726
- {
1727
- if ($key === false && !empty($this->publicExponent)) {
1728
- unset($this->publicExponent);
1729
- return true;
1730
- }
1731
-
1732
- $rsa = new Crypt_RSA();
1733
- if (!$rsa->loadKey($key, $type)) {
1734
- return false;
1735
- }
1736
- unset($rsa->publicExponent);
1737
-
1738
- // don't overwrite the old key if the new key is invalid
1739
- $this->loadKey($rsa);
1740
- return true;
1741
- }
1742
-
1743
- /**
1744
- * Returns the public key
1745
- *
1746
- * The public key is only returned under two circumstances - if the private key had the public key embedded within it
1747
- * or if the public key was set via setPublicKey(). If the currently loaded key is supposed to be the public key this
1748
- * function won't return it since this library, for the most part, doesn't distinguish between public and private keys.
1749
- *
1750
- * @see getPublicKey()
1751
- * @access public
1752
- * @param String $key
1753
- * @param Integer $type optional
1754
- */
1755
- function getPublicKey($type = CRYPT_RSA_PUBLIC_FORMAT_PKCS8)
1756
- {
1757
- if (empty($this->modulus) || empty($this->publicExponent)) {
1758
- return false;
1759
- }
1760
-
1761
- $oldFormat = $this->publicKeyFormat;
1762
- $this->publicKeyFormat = $type;
1763
- $temp = $this->_convertPublicKey($this->modulus, $this->publicExponent);
1764
- $this->publicKeyFormat = $oldFormat;
1765
- return $temp;
1766
- }
1767
-
1768
- /**
1769
- * Returns the private key
1770
- *
1771
- * The private key is only returned if the currently loaded key contains the constituent prime numbers.
1772
- *
1773
- * @see getPublicKey()
1774
- * @access public
1775
- * @param String $key
1776
- * @param Integer $type optional
1777
- */
1778
- function getPrivateKey($type = CRYPT_RSA_PUBLIC_FORMAT_PKCS1)
1779
- {
1780
- if (empty($this->primes)) {
1781
- return false;
1782
- }
1783
-
1784
- $oldFormat = $this->privateKeyFormat;
1785
- $this->privateKeyFormat = $type;
1786
- $temp = $this->_convertPrivateKey($this->modulus, $this->publicExponent, $this->exponent, $this->primes, $this->exponents, $this->coefficients);
1787
- $this->privateKeyFormat = $oldFormat;
1788
- return $temp;
1789
- }
1790
-
1791
- /**
1792
- * Returns a minimalistic private key
1793
- *
1794
- * Returns the private key without the prime number constituants. Structurally identical to a public key that
1795
- * hasn't been set as the public key
1796
- *
1797
- * @see getPrivateKey()
1798
- * @access private
1799
- * @param String $key
1800
- * @param Integer $type optional
1801
- */
1802
- function _getPrivatePublicKey($mode = CRYPT_RSA_PUBLIC_FORMAT_PKCS8)
1803
- {
1804
- if (empty($this->modulus) || empty($this->exponent)) {
1805
- return false;
1806
- }
1807
-
1808
- $oldFormat = $this->publicKeyFormat;
1809
- $this->publicKeyFormat = $mode;
1810
- $temp = $this->_convertPublicKey($this->modulus, $this->exponent);
1811
- $this->publicKeyFormat = $oldFormat;
1812
- return $temp;
1813
- }
1814
-
1815
- /**
1816
- * __toString() magic method
1817
- *
1818
- * @access public
1819
- */
1820
- function __toString()
1821
- {
1822
- $key = $this->getPrivateKey($this->privateKeyFormat);
1823
- if ($key !== false) {
1824
- return $key;
1825
- }
1826
- $key = $this->_getPrivatePublicKey($this->publicKeyFormat);
1827
- return $key !== false ? $key : '';
1828
- }
1829
-
1830
- /**
1831
- * __clone() magic method
1832
- *
1833
- * @access public
1834
- */
1835
- function __clone()
1836
- {
1837
- $key = new Crypt_RSA();
1838
- $key->loadKey($this);
1839
- return $key;
1840
- }
1841
-
1842
- /**
1843
- * Generates the smallest and largest numbers requiring $bits bits
1844
- *
1845
- * @access private
1846
- * @param Integer $bits
1847
- * @return Array
1848
- */
1849
- function _generateMinMax($bits)
1850
- {
1851
- $bytes = $bits >> 3;
1852
- $min = str_repeat(chr(0), $bytes);
1853
- $max = str_repeat(chr(0xFF), $bytes);
1854
- $msb = $bits & 7;
1855
- if ($msb) {
1856
- $min = chr(1 << ($msb - 1)) . $min;
1857
- $max = chr((1 << $msb) - 1) . $max;
1858
- } else {
1859
- $min[0] = chr(0x80);
1860
- }
1861
-
1862
- return array(
1863
- 'min' => new Math_BigInteger($min, 256),
1864
- 'max' => new Math_BigInteger($max, 256)
1865
- );
1866
- }
1867
-
1868
- /**
1869
- * DER-decode the length
1870
- *
1871
- * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
1872
- * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
1873
- *
1874
- * @access private
1875
- * @param String $string
1876
- * @return Integer
1877
- */
1878
- function _decodeLength(&$string)
1879
- {
1880
- $length = ord($this->_string_shift($string));
1881
- if ( $length & 0x80 ) { // definite length, long form
1882
- $length&= 0x7F;
1883
- $temp = $this->_string_shift($string, $length);
1884
- list(, $length) = unpack('N', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4));
1885
- }
1886
- return $length;
1887
- }
1888
-
1889
- /**
1890
- * DER-encode the length
1891
- *
1892
- * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
1893
- * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
1894
- *
1895
- * @access private
1896
- * @param Integer $length
1897
- * @return String
1898
- */
1899
- function _encodeLength($length)
1900
- {
1901
- if ($length <= 0x7F) {
1902
- return chr($length);
1903
- }
1904
-
1905
- $temp = ltrim(pack('N', $length), chr(0));
1906
- return pack('Ca*', 0x80 | strlen($temp), $temp);
1907
- }
1908
-
1909
- /**
1910
- * String Shift
1911
- *
1912
- * Inspired by array_shift
1913
- *
1914
- * @param String $string
1915
- * @param optional Integer $index
1916
- * @return String
1917
- * @access private
1918
- */
1919
- function _string_shift(&$string, $index = 1)
1920
- {
1921
- $substr = substr($string, 0, $index);
1922
- $string = substr($string, $index);
1923
- return $substr;
1924
- }
1925
-
1926
- /**
1927
- * Determines the private key format
1928
- *
1929
- * @see createKey()
1930
- * @access public
1931
- * @param Integer $format
1932
- */
1933
- function setPrivateKeyFormat($format)
1934
- {
1935
- $this->privateKeyFormat = $format;
1936
- }
1937
-
1938
- /**
1939
- * Determines the public key format
1940
- *
1941
- * @see createKey()
1942
- * @access public
1943
- * @param Integer $format
1944
- */
1945
- function setPublicKeyFormat($format)
1946
- {
1947
- $this->publicKeyFormat = $format;
1948
- }
1949
-
1950
- /**
1951
- * Determines which hashing function should be used
1952
- *
1953
- * Used with signature production / verification and (if the encryption mode is CRYPT_RSA_ENCRYPTION_OAEP) encryption and
1954
- * decryption. If $hash isn't supported, sha1 is used.
1955
- *
1956
- * @access public
1957
- * @param String $hash
1958
- */
1959
- function setHash($hash)
1960
- {
1961
- // Crypt_Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example.
1962
- switch ($hash) {
1963
- case 'md2':
1964
- case 'md5':
1965
- case 'sha1':
1966
- case 'sha256':
1967
- case 'sha384':
1968
- case 'sha512':
1969
- $this->hash = new Crypt_Hash($hash);
1970
- $this->hashName = $hash;
1971
- break;
1972
- default:
1973
- $this->hash = new Crypt_Hash('sha1');
1974
- $this->hashName = 'sha1';
1975
- }
1976
- $this->hLen = $this->hash->getLength();
1977
- }
1978
-
1979
- /**
1980
- * Determines which hashing function should be used for the mask generation function
1981
- *
1982
- * The mask generation function is used by CRYPT_RSA_ENCRYPTION_OAEP and CRYPT_RSA_SIGNATURE_PSS and although it's
1983
- * best if Hash and MGFHash are set to the same thing this is not a requirement.
1984
- *
1985
- * @access public
1986
- * @param String $hash
1987
- */
1988
- function setMGFHash($hash)
1989
- {
1990
- // Crypt_Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example.
1991
- switch ($hash) {
1992
- case 'md2':
1993
- case 'md5':
1994
- case 'sha1':
1995
- case 'sha256':
1996
- case 'sha384':
1997
- case 'sha512':
1998
- $this->mgfHash = new Crypt_Hash($hash);
1999
- break;
2000
- default:
2001
- $this->mgfHash = new Crypt_Hash('sha1');
2002
- }
2003
- $this->mgfHLen = $this->mgfHash->getLength();
2004
- }
2005
-
2006
- /**
2007
- * Determines the salt length
2008
- *
2009
- * To quote from {@link http://tools.ietf.org/html/rfc3447#page-38 RFC3447#page-38}:
2010
- *
2011
- * Typical salt lengths in octets are hLen (the length of the output
2012
- * of the hash function Hash) and 0.
2013
- *
2014
- * @access public
2015
- * @param Integer $format
2016
- */
2017
- function setSaltLength($sLen)
2018
- {
2019
- $this->sLen = $sLen;
2020
- }
2021
-
2022
- /**
2023
- * Integer-to-Octet-String primitive
2024
- *
2025
- * See {@link http://tools.ietf.org/html/rfc3447#section-4.1 RFC3447#section-4.1}.
2026
- *
2027
- * @access private
2028
- * @param Math_BigInteger $x
2029
- * @param Integer $xLen
2030
- * @return String
2031
- */
2032
- function _i2osp($x, $xLen)
2033
- {
2034
- $x = $x->toBytes();
2035
- if (strlen($x) > $xLen) {
2036
- user_error('Integer too large');
2037
- return false;
2038
- }
2039
- return str_pad($x, $xLen, chr(0), STR_PAD_LEFT);
2040
- }
2041
-
2042
- /**
2043
- * Octet-String-to-Integer primitive
2044
- *
2045
- * See {@link http://tools.ietf.org/html/rfc3447#section-4.2 RFC3447#section-4.2}.
2046
- *
2047
- * @access private
2048
- * @param String $x
2049
- * @return Math_BigInteger
2050
- */
2051
- function _os2ip($x)
2052
- {
2053
- return new Math_BigInteger($x, 256);
2054
- }
2055
-
2056
- /**
2057
- * Exponentiate with or without Chinese Remainder Theorem
2058
- *
2059
- * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.2}.
2060
- *
2061
- * @access private
2062
- * @param Math_BigInteger $x
2063
- * @return Math_BigInteger
2064
- */
2065
- function _exponentiate($x)
2066
- {
2067
- if (empty($this->primes) || empty($this->coefficients) || empty($this->exponents)) {
2068
- return $x->modPow($this->exponent, $this->modulus);
2069
- }
2070
-
2071
- $num_primes = count($this->primes);
2072
-
2073
- if (defined('CRYPT_RSA_DISABLE_BLINDING')) {
2074
- $m_i = array(
2075
- 1 => $x->modPow($this->exponents[1], $this->primes[1]),
2076
- 2 => $x->modPow($this->exponents[2], $this->primes[2])
2077
- );
2078
- $h = $m_i[1]->subtract($m_i[2]);
2079
- $h = $h->multiply($this->coefficients[2]);
2080
- list(, $h) = $h->divide($this->primes[1]);
2081
- $m = $m_i[2]->add($h->multiply($this->primes[2]));
2082
-
2083
- $r = $this->primes[1];
2084
- for ($i = 3; $i <= $num_primes; $i++) {
2085
- $m_i = $x->modPow($this->exponents[$i], $this->primes[$i]);
2086
-
2087
- $r = $r->multiply($this->primes[$i - 1]);
2088
-
2089
- $h = $m_i->subtract($m);
2090
- $h = $h->multiply($this->coefficients[$i]);
2091
- list(, $h) = $h->divide($this->primes[$i]);
2092
-
2093
- $m = $m->add($r->multiply($h));
2094
- }
2095
- } else {
2096
- $smallest = $this->primes[1];
2097
- for ($i = 2; $i <= $num_primes; $i++) {
2098
- if ($smallest->compare($this->primes[$i]) > 0) {
2099
- $smallest = $this->primes[$i];
2100
- }
2101
- }
2102
-
2103
- $one = new Math_BigInteger(1);
2104
-
2105
- $r = $one->random($one, $smallest->subtract($one));
2106
-
2107
- $m_i = array(
2108
- 1 => $this->_blind($x, $r, 1),
2109
- 2 => $this->_blind($x, $r, 2)
2110
- );
2111
- $h = $m_i[1]->subtract($m_i[2]);
2112
- $h = $h->multiply($this->coefficients[2]);
2113
- list(, $h) = $h->divide($this->primes[1]);
2114
- $m = $m_i[2]->add($h->multiply($this->primes[2]));
2115
-
2116
- $r = $this->primes[1];
2117
- for ($i = 3; $i <= $num_primes; $i++) {
2118
- $m_i = $this->_blind($x, $r, $i);
2119
-
2120
- $r = $r->multiply($this->primes[$i - 1]);
2121
-
2122
- $h = $m_i->subtract($m);
2123
- $h = $h->multiply($this->coefficients[$i]);
2124
- list(, $h) = $h->divide($this->primes[$i]);
2125
-
2126
- $m = $m->add($r->multiply($h));
2127
- }
2128
- }
2129
-
2130
- return $m;
2131
- }
2132
-
2133
- /**
2134
- * Performs RSA Blinding
2135
- *
2136
- * Protects against timing attacks by employing RSA Blinding.
2137
- * Returns $x->modPow($this->exponents[$i], $this->primes[$i])
2138
- *
2139
- * @access private
2140
- * @param Math_BigInteger $x
2141
- * @param Math_BigInteger $r
2142
- * @param Integer $i
2143
- * @return Math_BigInteger
2144
- */
2145
- function _blind($x, $r, $i)
2146
- {
2147
- $x = $x->multiply($r->modPow($this->publicExponent, $this->primes[$i]));
2148
- $x = $x->modPow($this->exponents[$i], $this->primes[$i]);
2149
-
2150
- $r = $r->modInverse($this->primes[$i]);
2151
- $x = $x->multiply($r);
2152
- list(, $x) = $x->divide($this->primes[$i]);
2153
-
2154
- return $x;
2155
- }
2156
-
2157
- /**
2158
- * Performs blinded RSA equality testing
2159
- *
2160
- * Protects against a particular type of timing attack described.
2161
- *
2162
- * See {@link http://codahale.com/a-lesson-in-timing-attacks/ A Lesson In Timing Attacks (or, Don't use MessageDigest.isEquals)}
2163
- *
2164
- * Thanks for the heads up singpolyma!
2165
- *
2166
- * @access private
2167
- * @param String $x
2168
- * @param String $y
2169
- * @return Boolean
2170
- */
2171
- function _equals($x, $y)
2172
- {
2173
- if (strlen($x) != strlen($y)) {
2174
- return false;
2175
- }
2176
-
2177
- $result = 0;
2178
- for ($i = 0; $i < strlen($x); $i++) {
2179
- $result |= ord($x[$i]) ^ ord($y[$i]);
2180
- }
2181
-
2182
- return $result == 0;
2183
- }
2184
-
2185
- /**
2186
- * RSAEP
2187
- *
2188
- * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.1}.
2189
- *
2190
- * @access private
2191
- * @param Math_BigInteger $m
2192
- * @return Math_BigInteger
2193
- */
2194
- function _rsaep($m)
2195
- {
2196
- if ($m->compare($this->zero) < 0 || $m->compare($this->modulus) > 0) {
2197
- user_error('Message representative out of range');
2198
- return false;
2199
- }
2200
- return $this->_exponentiate($m);
2201
- }
2202
-
2203
- /**
2204
- * RSADP
2205
- *
2206
- * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.2 RFC3447#section-5.1.2}.
2207
- *
2208
- * @access private
2209
- * @param Math_BigInteger $c
2210
- * @return Math_BigInteger
2211
- */
2212
- function _rsadp($c)
2213
- {
2214
- if ($c->compare($this->zero) < 0 || $c->compare($this->modulus) > 0) {
2215
- user_error('Ciphertext representative out of range');
2216
- return false;
2217
- }
2218
- return $this->_exponentiate($c);
2219
- }
2220
-
2221
- /**
2222
- * RSASP1
2223
- *
2224
- * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.1 RFC3447#section-5.2.1}.
2225
- *
2226
- * @access private
2227
- * @param Math_BigInteger $m
2228
- * @return Math_BigInteger
2229
- */
2230
- function _rsasp1($m)
2231
- {
2232
- if ($m->compare($this->zero) < 0 || $m->compare($this->modulus) > 0) {
2233
- user_error('Message representative out of range');
2234
- return false;
2235
- }
2236
- return $this->_exponentiate($m);
2237
- }
2238
-
2239
- /**
2240
- * RSAVP1
2241
- *
2242
- * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.2 RFC3447#section-5.2.2}.
2243
- *
2244
- * @access private
2245
- * @param Math_BigInteger $s
2246
- * @return Math_BigInteger
2247
- */
2248
- function _rsavp1($s)
2249
- {
2250
- if ($s->compare($this->zero) < 0 || $s->compare($this->modulus) > 0) {
2251
- user_error('Signature representative out of range');
2252
- return false;
2253
- }
2254
- return $this->_exponentiate($s);
2255
- }
2256
-
2257
- /**
2258
- * MGF1
2259
- *
2260
- * See {@link http://tools.ietf.org/html/rfc3447#appendix-B.2.1 RFC3447#appendix-B.2.1}.
2261
- *
2262
- * @access private
2263
- * @param String $mgfSeed
2264
- * @param Integer $mgfLen
2265
- * @return String
2266
- */
2267
- function _mgf1($mgfSeed, $maskLen)
2268
- {
2269
- // if $maskLen would yield strings larger than 4GB, PKCS#1 suggests a "Mask too long" error be output.
2270
-
2271
- $t = '';
2272
- $count = ceil($maskLen / $this->mgfHLen);
2273
- for ($i = 0; $i < $count; $i++) {
2274
- $c = pack('N', $i);
2275
- $t.= $this->mgfHash->hash($mgfSeed . $c);
2276
- }
2277
-
2278
- return substr($t, 0, $maskLen);
2279
- }
2280
-
2281
- /**
2282
- * RSAES-OAEP-ENCRYPT
2283
- *
2284
- * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.1 RFC3447#section-7.1.1} and
2285
- * {http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding OAES}.
2286
- *
2287
- * @access private
2288
- * @param String $m
2289
- * @param String $l
2290
- * @return String
2291
- */
2292
- function _rsaes_oaep_encrypt($m, $l = '')
2293
- {
2294
- $mLen = strlen($m);
2295
-
2296
- // Length checking
2297
-
2298
- // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error
2299
- // be output.
2300
-
2301
- if ($mLen > $this->k - 2 * $this->hLen - 2) {
2302
- user_error('Message too long');
2303
- return false;
2304
- }
2305
-
2306
- // EME-OAEP encoding
2307
-
2308
- $lHash = $this->hash->hash($l);
2309
- $ps = str_repeat(chr(0), $this->k - $mLen - 2 * $this->hLen - 2);
2310
- $db = $lHash . $ps . chr(1) . $m;
2311
- $seed = crypt_random_string($this->hLen);
2312
- $dbMask = $this->_mgf1($seed, $this->k - $this->hLen - 1);
2313
- $maskedDB = $db ^ $dbMask;
2314
- $seedMask = $this->_mgf1($maskedDB, $this->hLen);
2315
- $maskedSeed = $seed ^ $seedMask;
2316
- $em = chr(0) . $maskedSeed . $maskedDB;
2317
-
2318
- // RSA encryption
2319
-
2320
- $m = $this->_os2ip($em);
2321
- $c = $this->_rsaep($m);
2322
- $c = $this->_i2osp($c, $this->k);
2323
-
2324
- // Output the ciphertext C
2325
-
2326
- return $c;
2327
- }
2328
-
2329
- /**
2330
- * RSAES-OAEP-DECRYPT
2331
- *
2332
- * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.2 RFC3447#section-7.1.2}. The fact that the error
2333
- * messages aren't distinguishable from one another hinders debugging, but, to quote from RFC3447#section-7.1.2:
2334
- *
2335
- * Note. Care must be taken to ensure that an opponent cannot
2336
- * distinguish the different error conditions in Step 3.g, whether by
2337
- * error message or timing, or, more generally, learn partial
2338
- * information about the encoded message EM. Otherwise an opponent may
2339
- * be able to obtain useful information about the decryption of the
2340
- * ciphertext C, leading to a chosen-ciphertext attack such as the one
2341
- * observed by Manger [36].
2342
- *
2343
- * As for $l... to quote from {@link http://tools.ietf.org/html/rfc3447#page-17 RFC3447#page-17}:
2344
- *
2345
- * Both the encryption and the decryption operations of RSAES-OAEP take
2346
- * the value of a label L as input. In this version of PKCS #1, L is
2347
- * the empty string; other uses of the label are outside the scope of
2348
- * this document.
2349
- *
2350
- * @access private
2351
- * @param String $c
2352
- * @param String $l
2353
- * @return String
2354
- */
2355
- function _rsaes_oaep_decrypt($c, $l = '')
2356
- {
2357
- // Length checking
2358
-
2359
- // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error
2360
- // be output.
2361
-
2362
- if (strlen($c) != $this->k || $this->k < 2 * $this->hLen + 2) {
2363
- user_error('Decryption error');
2364
- return false;
2365
- }
2366
-
2367
- // RSA decryption
2368
-
2369
- $c = $this->_os2ip($c);
2370
- $m = $this->_rsadp($c);
2371
- if ($m === false) {
2372
- user_error('Decryption error');
2373
- return false;
2374
- }
2375
- $em = $this->_i2osp($m, $this->k);
2376
-
2377
- // EME-OAEP decoding
2378
-
2379
- $lHash = $this->hash->hash($l);
2380
- $y = ord($em[0]);
2381
- $maskedSeed = substr($em, 1, $this->hLen);
2382
- $maskedDB = substr($em, $this->hLen + 1);
2383
- $seedMask = $this->_mgf1($maskedDB, $this->hLen);
2384
- $seed = $maskedSeed ^ $seedMask;
2385
- $dbMask = $this->_mgf1($seed, $this->k - $this->hLen - 1);
2386
- $db = $maskedDB ^ $dbMask;
2387
- $lHash2 = substr($db, 0, $this->hLen);
2388
- $m = substr($db, $this->hLen);
2389
- if ($lHash != $lHash2) {
2390
- user_error('Decryption error');
2391
- return false;
2392
- }
2393
- $m = ltrim($m, chr(0));
2394
- if (ord($m[0]) != 1) {
2395
- user_error('Decryption error');
2396
- return false;
2397
- }
2398
-
2399
- // Output the message M
2400
-
2401
- return substr($m, 1);
2402
- }
2403
-
2404
- /**
2405
- * RSAES-PKCS1-V1_5-ENCRYPT
2406
- *
2407
- * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.1 RFC3447#section-7.2.1}.
2408
- *
2409
- * @access private
2410
- * @param String $m
2411
- * @return String
2412
- */
2413
- function _rsaes_pkcs1_v1_5_encrypt($m)
2414
- {
2415
- $mLen = strlen($m);
2416
-
2417
- // Length checking
2418
-
2419
- if ($mLen > $this->k - 11) {
2420
- user_error('Message too long');
2421
- return false;
2422
- }
2423
-
2424
- // EME-PKCS1-v1_5 encoding
2425
-
2426
- $psLen = $this->k - $mLen - 3;
2427
- $ps = '';
2428
- while (strlen($ps) != $psLen) {
2429
- $temp = crypt_random_string($psLen - strlen($ps));
2430
- $temp = str_replace("\x00", '', $temp);
2431
- $ps.= $temp;
2432
- }
2433
- $type = 2;
2434
- // see the comments of _rsaes_pkcs1_v1_5_decrypt() to understand why this is being done
2435
- if (defined('CRYPT_RSA_PKCS15_COMPAT') && (!isset($this->publicExponent) || $this->exponent !== $this->publicExponent)) {
2436
- $type = 1;
2437
- // "The padding string PS shall consist of k-3-||D|| octets. ... for block type 01, they shall have value FF"
2438
- $ps = str_repeat("\xFF", $psLen);
2439
- }
2440
- $em = chr(0) . chr($type) . $ps . chr(0) . $m;
2441
-
2442
- // RSA encryption
2443
- $m = $this->_os2ip($em);
2444
- $c = $this->_rsaep($m);
2445
- $c = $this->_i2osp($c, $this->k);
2446
-
2447
- // Output the ciphertext C
2448
-
2449
- return $c;
2450
- }
2451
-
2452
- /**
2453
- * RSAES-PKCS1-V1_5-DECRYPT
2454
- *
2455
- * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.2 RFC3447#section-7.2.2}.
2456
- *
2457
- * For compatibility purposes, this function departs slightly from the description given in RFC3447.
2458
- * The reason being that RFC2313#section-8.1 (PKCS#1 v1.5) states that ciphertext's encrypted by the
2459
- * private key should have the second byte set to either 0 or 1 and that ciphertext's encrypted by the
2460
- * public key should have the second byte set to 2. In RFC3447 (PKCS#1 v2.1), the second byte is supposed
2461
- * to be 2 regardless of which key is used. For compatibility purposes, we'll just check to make sure the
2462
- * second byte is 2 or less. If it is, we'll accept the decrypted string as valid.
2463
- *
2464
- * As a consequence of this, a private key encrypted ciphertext produced with Crypt_RSA may not decrypt
2465
- * with a strictly PKCS#1 v1.5 compliant RSA implementation. Public key encrypted ciphertext's should but
2466
- * not private key encrypted ciphertext's.
2467
- *
2468
- * @access private
2469
- * @param String $c
2470
- * @return String
2471
- */
2472
- function _rsaes_pkcs1_v1_5_decrypt($c)
2473
- {
2474
- // Length checking
2475
-
2476
- if (strlen($c) != $this->k) { // or if k < 11
2477
- user_error('Decryption error');
2478
- return false;
2479
- }
2480
-
2481
- // RSA decryption
2482
-
2483
- $c = $this->_os2ip($c);
2484
- $m = $this->_rsadp($c);
2485
-
2486
- if ($m === false) {
2487
- user_error('Decryption error');
2488
- return false;
2489
- }
2490
- $em = $this->_i2osp($m, $this->k);
2491
-
2492
- // EME-PKCS1-v1_5 decoding
2493
-
2494
- if (ord($em[0]) != 0 || ord($em[1]) > 2) {
2495
- user_error('Decryption error');
2496
- return false;
2497
- }
2498
-
2499
- $ps = substr($em, 2, strpos($em, chr(0), 2) - 2);
2500
- $m = substr($em, strlen($ps) + 3);
2501
-
2502
- if (strlen($ps) < 8) {
2503
- user_error('Decryption error');
2504
- return false;
2505
- }
2506
-
2507
- // Output M
2508
-
2509
- return $m;
2510
- }
2511
-
2512
- /**
2513
- * EMSA-PSS-ENCODE
2514
- *
2515
- * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.1 RFC3447#section-9.1.1}.
2516
- *
2517
- * @access private
2518
- * @param String $m
2519
- * @param Integer $emBits
2520
- */
2521
- function _emsa_pss_encode($m, $emBits)
2522
- {
2523
- // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error
2524
- // be output.
2525
-
2526
- $emLen = ($emBits + 1) >> 3; // ie. ceil($emBits / 8)
2527
- $sLen = $this->sLen == false ? $this->hLen : $this->sLen;
2528
-
2529
- $mHash = $this->hash->hash($m);
2530
- if ($emLen < $this->hLen + $sLen + 2) {
2531
- user_error('Encoding error');
2532
- return false;
2533
- }
2534
-
2535
- $salt = crypt_random_string($sLen);
2536
- $m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt;
2537
- $h = $this->hash->hash($m2);
2538
- $ps = str_repeat(chr(0), $emLen - $sLen - $this->hLen - 2);
2539
- $db = $ps . chr(1) . $salt;
2540
- $dbMask = $this->_mgf1($h, $emLen - $this->hLen - 1);
2541
- $maskedDB = $db ^ $dbMask;
2542
- $maskedDB[0] = ~chr(0xFF << ($emBits & 7)) & $maskedDB[0];
2543
- $em = $maskedDB . $h . chr(0xBC);
2544
-
2545
- return $em;
2546
- }
2547
-
2548
- /**
2549
- * EMSA-PSS-VERIFY
2550
- *
2551
- * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.2 RFC3447#section-9.1.2}.
2552
- *
2553
- * @access private
2554
- * @param String $m
2555
- * @param String $em
2556
- * @param Integer $emBits
2557
- * @return String
2558
- */
2559
- function _emsa_pss_verify($m, $em, $emBits)
2560
- {
2561
- // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error
2562
- // be output.
2563
-
2564
- $emLen = ($emBits + 1) >> 3; // ie. ceil($emBits / 8);
2565
- $sLen = $this->sLen == false ? $this->hLen : $this->sLen;
2566
-
2567
- $mHash = $this->hash->hash($m);
2568
- if ($emLen < $this->hLen + $sLen + 2) {
2569
- return false;
2570
- }
2571
-
2572
- if ($em[strlen($em) - 1] != chr(0xBC)) {
2573
- return false;
2574
- }
2575
-
2576
- $maskedDB = substr($em, 0, -$this->hLen - 1);
2577
- $h = substr($em, -$this->hLen - 1, $this->hLen);
2578
- $temp = chr(0xFF << ($emBits & 7));
2579
- if ((~$maskedDB[0] & $temp) != $temp) {
2580
- return false;
2581
- }
2582
- $dbMask = $this->_mgf1($h, $emLen - $this->hLen - 1);
2583
- $db = $maskedDB ^ $dbMask;
2584
- $db[0] = ~chr(0xFF << ($emBits & 7)) & $db[0];
2585
- $temp = $emLen - $this->hLen - $sLen - 2;
2586
- if (substr($db, 0, $temp) != str_repeat(chr(0), $temp) || ord($db[$temp]) != 1) {
2587
- return false;
2588
- }
2589
- $salt = substr($db, $temp + 1); // should be $sLen long
2590
- $m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt;
2591
- $h2 = $this->hash->hash($m2);
2592
- return $this->_equals($h, $h2);
2593
- }
2594
-
2595
- /**
2596
- * RSASSA-PSS-SIGN
2597
- *
2598
- * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.1 RFC3447#section-8.1.1}.
2599
- *
2600
- * @access private
2601
- * @param String $m
2602
- * @return String
2603
- */
2604
- function _rsassa_pss_sign($m)
2605
- {
2606
- // EMSA-PSS encoding
2607
-
2608
- $em = $this->_emsa_pss_encode($m, 8 * $this->k - 1);
2609
-
2610
- // RSA signature
2611
-
2612
- $m = $this->_os2ip($em);
2613
- $s = $this->_rsasp1($m);
2614
- $s = $this->_i2osp($s, $this->k);
2615
-
2616
- // Output the signature S
2617
-
2618
- return $s;
2619
- }
2620
-
2621
- /**
2622
- * RSASSA-PSS-VERIFY
2623
- *
2624
- * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.2 RFC3447#section-8.1.2}.
2625
- *
2626
- * @access private
2627
- * @param String $m
2628
- * @param String $s
2629
- * @return String
2630
- */
2631
- function _rsassa_pss_verify($m, $s)
2632
- {
2633
- // Length checking
2634
-
2635
- if (strlen($s) != $this->k) {
2636
- user_error('Invalid signature');
2637
- return false;
2638
- }
2639
-
2640
- // RSA verification
2641
-
2642
- $modBits = 8 * $this->k;
2643
-
2644
- $s2 = $this->_os2ip($s);
2645
- $m2 = $this->_rsavp1($s2);
2646
- if ($m2 === false) {
2647
- user_error('Invalid signature');
2648
- return false;
2649
- }
2650
- $em = $this->_i2osp($m2, $modBits >> 3);
2651
- if ($em === false) {
2652
- user_error('Invalid signature');
2653
- return false;
2654
- }
2655
-
2656
- // EMSA-PSS verification
2657
-
2658
- return $this->_emsa_pss_verify($m, $em, $modBits - 1);
2659
- }
2660
-
2661
- /**
2662
- * EMSA-PKCS1-V1_5-ENCODE
2663
- *
2664
- * See {@link http://tools.ietf.org/html/rfc3447#section-9.2 RFC3447#section-9.2}.
2665
- *
2666
- * @access private
2667
- * @param String $m
2668
- * @param Integer $emLen
2669
- * @return String
2670
- */
2671
- function _emsa_pkcs1_v1_5_encode($m, $emLen)
2672
- {
2673
- $h = $this->hash->hash($m);
2674
- if ($h === false) {
2675
- return false;
2676
- }
2677
-
2678
- // see http://tools.ietf.org/html/rfc3447#page-43
2679
- switch ($this->hashName) {
2680
- case 'md2':
2681
- $t = pack('H*', '3020300c06082a864886f70d020205000410');
2682
- break;
2683
- case 'md5':
2684
- $t = pack('H*', '3020300c06082a864886f70d020505000410');
2685
- break;
2686
- case 'sha1':
2687
- $t = pack('H*', '3021300906052b0e03021a05000414');
2688
- break;
2689
- case 'sha256':
2690
- $t = pack('H*', '3031300d060960864801650304020105000420');
2691
- break;
2692
- case 'sha384':
2693
- $t = pack('H*', '3041300d060960864801650304020205000430');
2694
- break;
2695
- case 'sha512':
2696
- $t = pack('H*', '3051300d060960864801650304020305000440');
2697
- }
2698
- $t.= $h;
2699
- $tLen = strlen($t);
2700
-
2701
- if ($emLen < $tLen + 11) {
2702
- user_error('Intended encoded message length too short');
2703
- return false;
2704
- }
2705
-
2706
- $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3);
2707
-
2708
- $em = "\0\1$ps\0$t";
2709
-
2710
- return $em;
2711
- }
2712
-
2713
- /**
2714
- * RSASSA-PKCS1-V1_5-SIGN
2715
- *
2716
- * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.1 RFC3447#section-8.2.1}.
2717
- *
2718
- * @access private
2719
- * @param String $m
2720
- * @return String
2721
- */
2722
- function _rsassa_pkcs1_v1_5_sign($m)
2723
- {
2724
- // EMSA-PKCS1-v1_5 encoding
2725
-
2726
- $em = $this->_emsa_pkcs1_v1_5_encode($m, $this->k);
2727
- if ($em === false) {
2728
- user_error('RSA modulus too short');
2729
- return false;
2730
- }
2731
-
2732
- // RSA signature
2733
-
2734
- $m = $this->_os2ip($em);
2735
- $s = $this->_rsasp1($m);
2736
- $s = $this->_i2osp($s, $this->k);
2737
-
2738
- // Output the signature S
2739
-
2740
- return $s;
2741
- }
2742
-
2743
- /**
2744
- * RSASSA-PKCS1-V1_5-VERIFY
2745
- *
2746
- * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.2 RFC3447#section-8.2.2}.
2747
- *
2748
- * @access private
2749
- * @param String $m
2750
- * @return String
2751
- */
2752
- function _rsassa_pkcs1_v1_5_verify($m, $s)
2753
- {
2754
- // Length checking
2755
-
2756
- if (strlen($s) != $this->k) {
2757
- user_error('Invalid signature');
2758
- return false;
2759
- }
2760
-
2761
- // RSA verification
2762
-
2763
- $s = $this->_os2ip($s);
2764
- $m2 = $this->_rsavp1($s);
2765
- if ($m2 === false) {
2766
- user_error('Invalid signature');
2767
- return false;
2768
- }
2769
- $em = $this->_i2osp($m2, $this->k);
2770
- if ($em === false) {
2771
- user_error('Invalid signature');
2772
- return false;
2773
- }
2774
-
2775
- // EMSA-PKCS1-v1_5 encoding
2776
-
2777
- $em2 = $this->_emsa_pkcs1_v1_5_encode($m, $this->k);
2778
- if ($em2 === false) {
2779
- user_error('RSA modulus too short');
2780
- return false;
2781
- }
2782
-
2783
- // Compare
2784
- return $this->_equals($em, $em2);
2785
- }
2786
-
2787
- /**
2788
- * Set Encryption Mode
2789
- *
2790
- * Valid values include CRYPT_RSA_ENCRYPTION_OAEP and CRYPT_RSA_ENCRYPTION_PKCS1.
2791
- *
2792
- * @access public
2793
- * @param Integer $mode
2794
- */
2795
- function setEncryptionMode($mode)
2796
- {
2797
- $this->encryptionMode = $mode;
2798
- }
2799
-
2800
- /**
2801
- * Set Signature Mode
2802
- *
2803
- * Valid values include CRYPT_RSA_SIGNATURE_PSS and CRYPT_RSA_SIGNATURE_PKCS1
2804
- *
2805
- * @access public
2806
- * @param Integer $mode
2807
- */
2808
- function setSignatureMode($mode)
2809
- {
2810
- $this->signatureMode = $mode;
2811
- }
2812
-
2813
- /**
2814
- * Set public key comment.
2815
- *
2816
- * @access public
2817
- * @param String $comment
2818
- */
2819
- function setComment($comment)
2820
- {
2821
- $this->comment = $comment;
2822
- }
2823
-
2824
- /**
2825
- * Get public key comment.
2826
- *
2827
- * @access public
2828
- * @return String
2829
- */
2830
- function getComment()
2831
- {
2832
- return $this->comment;
2833
- }
2834
-
2835
- /**
2836
- * Encryption
2837
- *
2838
- * Both CRYPT_RSA_ENCRYPTION_OAEP and CRYPT_RSA_ENCRYPTION_PKCS1 both place limits on how long $plaintext can be.
2839
- * If $plaintext exceeds those limits it will be broken up so that it does and the resultant ciphertext's will
2840
- * be concatenated together.
2841
- *
2842
- * @see decrypt()
2843
- * @access public
2844
- * @param String $plaintext
2845
- * @return String
2846
- */
2847
- function encrypt($plaintext)
2848
- {
2849
- switch ($this->encryptionMode) {
2850
- case CRYPT_RSA_ENCRYPTION_PKCS1:
2851
- $length = $this->k - 11;
2852
- if ($length <= 0) {
2853
- return false;
2854
- }
2855
-
2856
- $plaintext = str_split($plaintext, $length);
2857
- $ciphertext = '';
2858
- foreach ($plaintext as $m) {
2859
- $ciphertext.= $this->_rsaes_pkcs1_v1_5_encrypt($m);
2860
- }
2861
- return $ciphertext;
2862
- //case CRYPT_RSA_ENCRYPTION_OAEP:
2863
- default:
2864
- $length = $this->k - 2 * $this->hLen - 2;
2865
- if ($length <= 0) {
2866
- return false;
2867
- }
2868
-
2869
- $plaintext = str_split($plaintext, $length);
2870
- $ciphertext = '';
2871
- foreach ($plaintext as $m) {
2872
- $ciphertext.= $this->_rsaes_oaep_encrypt($m);
2873
- }
2874
- return $ciphertext;
2875
- }
2876
- }
2877
-
2878
- /**
2879
- * Decryption
2880
- *
2881
- * @see encrypt()
2882
- * @access public
2883
- * @param String $plaintext
2884
- * @return String
2885
- */
2886
- function decrypt($ciphertext)
2887
- {
2888
- if ($this->k <= 0) {
2889
- return false;
2890
- }
2891
-
2892
- $ciphertext = str_split($ciphertext, $this->k);
2893
- $ciphertext[count($ciphertext) - 1] = str_pad($ciphertext[count($ciphertext) - 1], $this->k, chr(0), STR_PAD_LEFT);
2894
-
2895
- $plaintext = '';
2896
-
2897
- switch ($this->encryptionMode) {
2898
- case CRYPT_RSA_ENCRYPTION_PKCS1:
2899
- $decrypt = '_rsaes_pkcs1_v1_5_decrypt';
2900
- break;
2901
- //case CRYPT_RSA_ENCRYPTION_OAEP:
2902
- default:
2903
- $decrypt = '_rsaes_oaep_decrypt';
2904
- }
2905
-
2906
- foreach ($ciphertext as $c) {
2907
- $temp = $this->$decrypt($c);
2908
- if ($temp === false) {
2909
- return false;
2910
- }
2911
- $plaintext.= $temp;
2912
- }
2913
-
2914
- return $plaintext;
2915
- }
2916
-
2917
- /**
2918
- * Create a signature
2919
- *
2920
- * @see verify()
2921
- * @access public
2922
- * @param String $message
2923
- * @return String
2924
- */
2925
- function sign($message)
2926
- {
2927
- if (empty($this->modulus) || empty($this->exponent)) {
2928
- return false;
2929
- }
2930
-
2931
- switch ($this->signatureMode) {
2932
- case CRYPT_RSA_SIGNATURE_PKCS1:
2933
- return $this->_rsassa_pkcs1_v1_5_sign($message);
2934
- //case CRYPT_RSA_SIGNATURE_PSS:
2935
- default:
2936
- return $this->_rsassa_pss_sign($message);
2937
- }
2938
- }
2939
-
2940
- /**
2941
- * Verifies a signature
2942
- *
2943
- * @see sign()
2944
- * @access public
2945
- * @param String $message
2946
- * @param String $signature
2947
- * @return Boolean
2948
- */
2949
- function verify($message, $signature)
2950
- {
2951
- if (empty($this->modulus) || empty($this->exponent)) {
2952
- return false;
2953
- }
2954
-
2955
- switch ($this->signatureMode) {
2956
- case CRYPT_RSA_SIGNATURE_PKCS1:
2957
- return $this->_rsassa_pkcs1_v1_5_verify($message, $signature);
2958
- //case CRYPT_RSA_SIGNATURE_PSS:
2959
- default:
2960
- return $this->_rsassa_pss_verify($message, $signature);
2961
- }
2962
- }
2963
-
2964
- /**
2965
- * Extract raw BER from Base64 encoding
2966
- *
2967
- * @access private
2968
- * @param String $str
2969
- * @return String
2970
- */
2971
- function _extractBER($str)
2972
- {
2973
- /* X.509 certs are assumed to be base64 encoded but sometimes they'll have additional things in them
2974
- * above and beyond the ceritificate.
2975
- * ie. some may have the following preceding the -----BEGIN CERTIFICATE----- line:
2976
- *
2977
- * Bag Attributes
2978
- * localKeyID: 01 00 00 00
2979
- * subject=/O=organization/OU=org unit/CN=common name
2980
- * issuer=/O=organization/CN=common name
2981
- */
2982
- $temp = preg_replace('#.*?^-+[^-]+-+#ms', '', $str, 1);
2983
- // remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff
2984
- $temp = preg_replace('#-+[^-]+-+#', '', $temp);
2985
- // remove new lines
2986
- $temp = str_replace(array("\r", "\n", ' '), '', $temp);
2987
- $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false;
2988
- return $temp != false ? $temp : $str;
2989
- }
2990
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Pure-PHP PKCS#1 (v2.1) compliant implementation of RSA.
5
+ *
6
+ * PHP versions 4 and 5
7
+ *
8
+ * Here's an example of how to encrypt and decrypt text with this library:
9
+ * <code>
10
+ * <?php
11
+ * include 'Crypt/RSA.php';
12
+ *
13
+ * $rsa = new Crypt_RSA();
14
+ * extract($rsa->createKey());
15
+ *
16
+ * $plaintext = 'terrafrost';
17
+ *
18
+ * $rsa->loadKey($privatekey);
19
+ * $ciphertext = $rsa->encrypt($plaintext);
20
+ *
21
+ * $rsa->loadKey($publickey);
22
+ * echo $rsa->decrypt($ciphertext);
23
+ * ?>
24
+ * </code>
25
+ *
26
+ * Here's an example of how to create signatures and verify signatures with this library:
27
+ * <code>
28
+ * <?php
29
+ * include 'Crypt/RSA.php';
30
+ *
31
+ * $rsa = new Crypt_RSA();
32
+ * extract($rsa->createKey());
33
+ *
34
+ * $plaintext = 'terrafrost';
35
+ *
36
+ * $rsa->loadKey($privatekey);
37
+ * $signature = $rsa->sign($plaintext);
38
+ *
39
+ * $rsa->loadKey($publickey);
40
+ * echo $rsa->verify($plaintext, $signature) ? 'verified' : 'unverified';
41
+ * ?>
42
+ * </code>
43
+ *
44
+ * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
45
+ * of this software and associated documentation files (the "Software"), to deal
46
+ * in the Software without restriction, including without limitation the rights
47
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
48
+ * copies of the Software, and to permit persons to whom the Software is
49
+ * furnished to do so, subject to the following conditions:
50
+ *
51
+ * The above copyright notice and this permission notice shall be included in
52
+ * all copies or substantial portions of the Software.
53
+ *
54
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
55
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
56
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
57
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
58
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
59
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
60
+ * THE SOFTWARE.
61
+ *
62
+ * @category Crypt
63
+ * @package Crypt_RSA
64
+ * @author Jim Wigginton <terrafrost@php.net>
65
+ * @copyright 2009 Jim Wigginton
66
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
67
+ * @link http://phpseclib.sourceforge.net
68
+ */
69
+
70
+ /**
71
+ * Include Crypt_Random
72
+ */
73
+ // the class_exists() will only be called if the crypt_random_string function hasn't been defined and
74
+ // will trigger a call to __autoload() if you're wanting to auto-load classes
75
+ // call function_exists() a second time to stop the include_once from being called outside
76
+ // of the auto loader
77
+ if (!function_exists('crypt_random_string')) {
78
+ include_once 'Random.php';
79
+ }
80
+
81
+ /**
82
+ * Include Crypt_Hash
83
+ */
84
+ if (!class_exists('Crypt_Hash')) {
85
+ include_once 'Hash.php';
86
+ }
87
+
88
+ /**#@+
89
+ * @access public
90
+ * @see Crypt_RSA::encrypt()
91
+ * @see Crypt_RSA::decrypt()
92
+ */
93
+ /**
94
+ * Use {@link http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding Optimal Asymmetric Encryption Padding}
95
+ * (OAEP) for encryption / decryption.
96
+ *
97
+ * Uses sha1 by default.
98
+ *
99
+ * @see Crypt_RSA::setHash()
100
+ * @see Crypt_RSA::setMGFHash()
101
+ */
102
+ define('CRYPT_RSA_ENCRYPTION_OAEP', 1);
103
+ /**
104
+ * Use PKCS#1 padding.
105
+ *
106
+ * Although CRYPT_RSA_ENCRYPTION_OAEP offers more security, including PKCS#1 padding is necessary for purposes of backwards
107
+ * compatibility with protocols (like SSH-1) written before OAEP's introduction.
108
+ */
109
+ define('CRYPT_RSA_ENCRYPTION_PKCS1', 2);
110
+ /**#@-*/
111
+
112
+ /**#@+
113
+ * @access public
114
+ * @see Crypt_RSA::sign()
115
+ * @see Crypt_RSA::verify()
116
+ * @see Crypt_RSA::setHash()
117
+ */
118
+ /**
119
+ * Use the Probabilistic Signature Scheme for signing
120
+ *
121
+ * Uses sha1 by default.
122
+ *
123
+ * @see Crypt_RSA::setSaltLength()
124
+ * @see Crypt_RSA::setMGFHash()
125
+ */
126
+ define('CRYPT_RSA_SIGNATURE_PSS', 1);
127
+ /**
128
+ * Use the PKCS#1 scheme by default.
129
+ *
130
+ * Although CRYPT_RSA_SIGNATURE_PSS offers more security, including PKCS#1 signing is necessary for purposes of backwards
131
+ * compatibility with protocols (like SSH-2) written before PSS's introduction.
132
+ */
133
+ define('CRYPT_RSA_SIGNATURE_PKCS1', 2);
134
+ /**#@-*/
135
+
136
+ /**#@+
137
+ * @access private
138
+ * @see Crypt_RSA::createKey()
139
+ */
140
+ /**
141
+ * ASN1 Integer
142
+ */
143
+ define('CRYPT_RSA_ASN1_INTEGER', 2);
144
+ /**
145
+ * ASN1 Bit String
146
+ */
147
+ define('CRYPT_RSA_ASN1_BITSTRING', 3);
148
+ /**
149
+ * ASN1 Octet String
150
+ */
151
+ define('CRYPT_RSA_ASN1_OCTETSTRING', 4);
152
+ /**
153
+ * ASN1 Object Identifier
154
+ */
155
+ define('CRYPT_RSA_ASN1_OBJECT', 6);
156
+ /**
157
+ * ASN1 Sequence (with the constucted bit set)
158
+ */
159
+ define('CRYPT_RSA_ASN1_SEQUENCE', 48);
160
+ /**#@-*/
161
+
162
+ /**#@+
163
+ * @access private
164
+ * @see Crypt_RSA::Crypt_RSA()
165
+ */
166
+ /**
167
+ * To use the pure-PHP implementation
168
+ */
169
+ define('CRYPT_RSA_MODE_INTERNAL', 1);
170
+ /**
171
+ * To use the OpenSSL library
172
+ *
173
+ * (if enabled; otherwise, the internal implementation will be used)
174
+ */
175
+ define('CRYPT_RSA_MODE_OPENSSL', 2);
176
+ /**#@-*/
177
+
178
+ /**
179
+ * Default openSSL configuration file.
180
+ */
181
+ define('CRYPT_RSA_OPENSSL_CONFIG', dirname(__FILE__) . '/../openssl.cnf');
182
+
183
+ /**#@+
184
+ * @access public
185
+ * @see Crypt_RSA::createKey()
186
+ * @see Crypt_RSA::setPrivateKeyFormat()
187
+ */
188
+ /**
189
+ * PKCS#1 formatted private key
190
+ *
191
+ * Used by OpenSSH
192
+ */
193
+ define('CRYPT_RSA_PRIVATE_FORMAT_PKCS1', 0);
194
+ /**
195
+ * PuTTY formatted private key
196
+ */
197
+ define('CRYPT_RSA_PRIVATE_FORMAT_PUTTY', 1);
198
+ /**
199
+ * XML formatted private key
200
+ */
201
+ define('CRYPT_RSA_PRIVATE_FORMAT_XML', 2);
202
+ /**
203
+ * PKCS#8 formatted private key
204
+ */
205
+ define('CRYPT_RSA_PRIVATE_FORMAT_PKCS8', 3);
206
+ /**#@-*/
207
+
208
+ /**#@+
209
+ * @access public
210
+ * @see Crypt_RSA::createKey()
211
+ * @see Crypt_RSA::setPublicKeyFormat()
212
+ */
213
+ /**
214
+ * Raw public key
215
+ *
216
+ * An array containing two Math_BigInteger objects.
217
+ *
218
+ * The exponent can be indexed with any of the following:
219
+ *
220
+ * 0, e, exponent, publicExponent
221
+ *
222
+ * The modulus can be indexed with any of the following:
223
+ *
224
+ * 1, n, modulo, modulus
225
+ */
226
+ define('CRYPT_RSA_PUBLIC_FORMAT_RAW', 3);
227
+ /**
228
+ * PKCS#1 formatted public key (raw)
229
+ *
230
+ * Used by File/X509.php
231
+ *
232
+ * Has the following header:
233
+ *
234
+ * -----BEGIN RSA PUBLIC KEY-----
235
+ *
236
+ * Analogous to ssh-keygen's pem format (as specified by -m)
237
+ */
238
+ define('CRYPT_RSA_PUBLIC_FORMAT_PKCS1', 4);
239
+ define('CRYPT_RSA_PUBLIC_FORMAT_PKCS1_RAW', 4);
240
+ /**
241
+ * XML formatted public key
242
+ */
243
+ define('CRYPT_RSA_PUBLIC_FORMAT_XML', 5);
244
+ /**
245
+ * OpenSSH formatted public key
246
+ *
247
+ * Place in $HOME/.ssh/authorized_keys
248
+ */
249
+ define('CRYPT_RSA_PUBLIC_FORMAT_OPENSSH', 6);
250
+ /**
251
+ * PKCS#1 formatted public key (encapsulated)
252
+ *
253
+ * Used by PHP's openssl_public_encrypt() and openssl's rsautl (when -pubin is set)
254
+ *
255
+ * Has the following header:
256
+ *
257
+ * -----BEGIN PUBLIC KEY-----
258
+ *
259
+ * Analogous to ssh-keygen's pkcs8 format (as specified by -m). Although PKCS8
260
+ * is specific to private keys it's basically creating a DER-encoded wrapper
261
+ * for keys. This just extends that same concept to public keys (much like ssh-keygen)
262
+ */
263
+ define('CRYPT_RSA_PUBLIC_FORMAT_PKCS8', 7);
264
+ /**#@-*/
265
+
266
+ /**
267
+ * Pure-PHP PKCS#1 compliant implementation of RSA.
268
+ *
269
+ * @package Crypt_RSA
270
+ * @author Jim Wigginton <terrafrost@php.net>
271
+ * @access public
272
+ */
273
+ class Crypt_RSA
274
+ {
275
+ /**
276
+ * Precomputed Zero
277
+ *
278
+ * @var Array
279
+ * @access private
280
+ */
281
+ var $zero;
282
+
283
+ /**
284
+ * Precomputed One
285
+ *
286
+ * @var Array
287
+ * @access private
288
+ */
289
+ var $one;
290
+
291
+ /**
292
+ * Private Key Format
293
+ *
294
+ * @var Integer
295
+ * @access private
296
+ */
297
+ var $privateKeyFormat = CRYPT_RSA_PRIVATE_FORMAT_PKCS1;
298
+
299
+ /**
300
+ * Public Key Format
301
+ *
302
+ * @var Integer
303
+ * @access public
304
+ */
305
+ var $publicKeyFormat = CRYPT_RSA_PUBLIC_FORMAT_PKCS8;
306
+
307
+ /**
308
+ * Modulus (ie. n)
309
+ *
310
+ * @var Math_BigInteger
311
+ * @access private
312
+ */
313
+ var $modulus;
314
+
315
+ /**
316
+ * Modulus length
317
+ *
318
+ * @var Math_BigInteger
319
+ * @access private
320
+ */
321
+ var $k;
322
+
323
+ /**
324
+ * Exponent (ie. e or d)
325
+ *
326
+ * @var Math_BigInteger
327
+ * @access private
328
+ */
329
+ var $exponent;
330
+
331
+ /**
332
+ * Primes for Chinese Remainder Theorem (ie. p and q)
333
+ *
334
+ * @var Array
335
+ * @access private
336
+ */
337
+ var $primes;
338
+
339
+ /**
340
+ * Exponents for Chinese Remainder Theorem (ie. dP and dQ)
341
+ *
342
+ * @var Array
343
+ * @access private
344
+ */
345
+ var $exponents;
346
+
347
+ /**
348
+ * Coefficients for Chinese Remainder Theorem (ie. qInv)
349
+ *
350
+ * @var Array
351
+ * @access private
352
+ */
353
+ var $coefficients;
354
+
355
+ /**
356
+ * Hash name
357
+ *
358
+ * @var String
359
+ * @access private
360
+ */
361
+ var $hashName;
362
+
363
+ /**
364
+ * Hash function
365
+ *
366
+ * @var Crypt_Hash
367
+ * @access private
368
+ */
369
+ var $hash;
370
+
371
+ /**
372
+ * Length of hash function output
373
+ *
374
+ * @var Integer
375
+ * @access private
376
+ */
377
+ var $hLen;
378
+
379
+ /**
380
+ * Length of salt
381
+ *
382
+ * @var Integer
383
+ * @access private
384
+ */
385
+ var $sLen;
386
+
387
+ /**
388
+ * Hash function for the Mask Generation Function
389
+ *
390
+ * @var Crypt_Hash
391
+ * @access private
392
+ */
393
+ var $mgfHash;
394
+
395
+ /**
396
+ * Length of MGF hash function output
397
+ *
398
+ * @var Integer
399
+ * @access private
400
+ */
401
+ var $mgfHLen;
402
+
403
+ /**
404
+ * Encryption mode
405
+ *
406
+ * @var Integer
407
+ * @access private
408
+ */
409
+ var $encryptionMode = CRYPT_RSA_ENCRYPTION_OAEP;
410
+
411
+ /**
412
+ * Signature mode
413
+ *
414
+ * @var Integer
415
+ * @access private
416
+ */
417
+ var $signatureMode = CRYPT_RSA_SIGNATURE_PSS;
418
+
419
+ /**
420
+ * Public Exponent
421
+ *
422
+ * @var Mixed
423
+ * @access private
424
+ */
425
+ var $publicExponent = false;
426
+
427
+ /**
428
+ * Password
429
+ *
430
+ * @var String
431
+ * @access private
432
+ */
433
+ var $password = false;
434
+
435
+ /**
436
+ * Components
437
+ *
438
+ * For use with parsing XML formatted keys. PHP's XML Parser functions use utilized - instead of PHP's DOM functions -
439
+ * because PHP's XML Parser functions work on PHP4 whereas PHP's DOM functions - although surperior - don't.
440
+ *
441
+ * @see Crypt_RSA::_start_element_handler()
442
+ * @var Array
443
+ * @access private
444
+ */
445
+ var $components = array();
446
+
447
+ /**
448
+ * Current String
449
+ *
450
+ * For use with parsing XML formatted keys.
451
+ *
452
+ * @see Crypt_RSA::_character_handler()
453
+ * @see Crypt_RSA::_stop_element_handler()
454
+ * @var Mixed
455
+ * @access private
456
+ */
457
+ var $current;
458
+
459
+ /**
460
+ * OpenSSL configuration file name.
461
+ *
462
+ * Set to null to use system configuration file.
463
+ * @see Crypt_RSA::createKey()
464
+ * @var Mixed
465
+ * @Access public
466
+ */
467
+ var $configFile;
468
+
469
+ /**
470
+ * Public key comment field.
471
+ *
472
+ * @var String
473
+ * @access private
474
+ */
475
+ var $comment = 'phpseclib-generated-key';
476
+
477
+ /**
478
+ * The constructor
479
+ *
480
+ * If you want to make use of the openssl extension, you'll need to set the mode manually, yourself. The reason
481
+ * Crypt_RSA doesn't do it is because OpenSSL doesn't fail gracefully. openssl_pkey_new(), in particular, requires
482
+ * openssl.cnf be present somewhere and, unfortunately, the only real way to find out is too late.
483
+ *
484
+ * @return Crypt_RSA
485
+ * @access public
486
+ */
487
+ function Crypt_RSA()
488
+ {
489
+ if (!class_exists('Math_BigInteger')) {
490
+ include_once 'Math/BigInteger.php';
491
+ }
492
+
493
+ $this->configFile = CRYPT_RSA_OPENSSL_CONFIG;
494
+
495
+ if ( !defined('CRYPT_RSA_MODE') ) {
496
+ switch (true) {
497
+ // Math/BigInteger's openssl requirements are a little less stringent than Crypt/RSA's. in particular,
498
+ // Math/BigInteger doesn't require an openssl.cfg file whereas Crypt/RSA does. so if Math/BigInteger
499
+ // can't use OpenSSL it can be pretty trivially assumed, then, that Crypt/RSA can't either.
500
+ case defined('MATH_BIGINTEGER_OPENSSL_DISABLE'):
501
+ define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_INTERNAL);
502
+ break;
503
+ // openssl_pkey_get_details - which is used in the only place Crypt/RSA.php uses OpenSSL - was introduced in PHP 5.2.0
504
+ case !function_exists('openssl_pkey_get_details'):
505
+ define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_INTERNAL);
506
+ break;
507
+ case extension_loaded('openssl') && version_compare(PHP_VERSION, '4.2.0', '>=') && file_exists($this->configFile):
508
+ // some versions of XAMPP have mismatched versions of OpenSSL which causes it not to work
509
+ ob_start();
510
+ @phpinfo();
511
+ $content = ob_get_contents();
512
+ ob_end_clean();
513
+
514
+ preg_match_all('#OpenSSL (Header|Library) Version(.*)#im', $content, $matches);
515
+
516
+ $versions = array();
517
+ if (!empty($matches[1])) {
518
+ for ($i = 0; $i < count($matches[1]); $i++) {
519
+ $fullVersion = trim(str_replace('=>', '', strip_tags($matches[2][$i])));
520
+
521
+ // Remove letter part in OpenSSL version
522
+ if (!preg_match('/(\d+\.\d+\.\d+)/i', $fullVersion, $m)) {
523
+ $versions[$matches[1][$i]] = $fullVersion;
524
+ } else {
525
+ $versions[$matches[1][$i]] = $m[0];
526
+ }
527
+ }
528
+ }
529
+
530
+ // it doesn't appear that OpenSSL versions were reported upon until PHP 5.3+
531
+ switch (true) {
532
+ case !isset($versions['Header']):
533
+ case !isset($versions['Library']):
534
+ case $versions['Header'] == $versions['Library']:
535
+ define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_OPENSSL);
536
+ break;
537
+ default:
538
+ define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_INTERNAL);
539
+ define('MATH_BIGINTEGER_OPENSSL_DISABLE', true);
540
+ }
541
+ break;
542
+ default:
543
+ define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_INTERNAL);
544
+ }
545
+ }
546
+
547
+ $this->zero = new Math_BigInteger();
548
+ $this->one = new Math_BigInteger(1);
549
+
550
+ $this->hash = new Crypt_Hash('sha1');
551
+ $this->hLen = $this->hash->getLength();
552
+ $this->hashName = 'sha1';
553
+ $this->mgfHash = new Crypt_Hash('sha1');
554
+ $this->mgfHLen = $this->mgfHash->getLength();
555
+ }
556
+
557
+ /**
558
+ * Create public / private key pair
559
+ *
560
+ * Returns an array with the following three elements:
561
+ * - 'privatekey': The private key.
562
+ * - 'publickey': The public key.
563
+ * - 'partialkey': A partially computed key (if the execution time exceeded $timeout).
564
+ * Will need to be passed back to Crypt_RSA::createKey() as the third parameter for further processing.
565
+ *
566
+ * @access public
567
+ * @param optional Integer $bits
568
+ * @param optional Integer $timeout
569
+ * @param optional Math_BigInteger $p
570
+ */
571
+ function createKey($bits = 1024, $timeout = false, $partial = array())
572
+ {
573
+ if (!defined('CRYPT_RSA_EXPONENT')) {
574
+ // http://en.wikipedia.org/wiki/65537_%28number%29
575
+ define('CRYPT_RSA_EXPONENT', '65537');
576
+ }
577
+ // per <http://cseweb.ucsd.edu/~hovav/dist/survey.pdf#page=5>, this number ought not result in primes smaller
578
+ // than 256 bits. as a consequence if the key you're trying to create is 1024 bits and you've set CRYPT_RSA_SMALLEST_PRIME
579
+ // to 384 bits then you're going to get a 384 bit prime and a 640 bit prime (384 + 1024 % 384). at least if
580
+ // CRYPT_RSA_MODE is set to CRYPT_RSA_MODE_INTERNAL. if CRYPT_RSA_MODE is set to CRYPT_RSA_MODE_OPENSSL then
581
+ // CRYPT_RSA_SMALLEST_PRIME is ignored (ie. multi-prime RSA support is more intended as a way to speed up RSA key
582
+ // generation when there's a chance neither gmp nor OpenSSL are installed)
583
+ if (!defined('CRYPT_RSA_SMALLEST_PRIME')) {
584
+ define('CRYPT_RSA_SMALLEST_PRIME', 4096);
585
+ }
586
+
587
+ // OpenSSL uses 65537 as the exponent and requires RSA keys be 384 bits minimum
588
+ if ( CRYPT_RSA_MODE == CRYPT_RSA_MODE_OPENSSL && $bits >= 384 && CRYPT_RSA_EXPONENT == 65537) {
589
+ $config = array();
590
+ if (isset($this->configFile)) {
591
+ $config['config'] = $this->configFile;
592
+ }
593
+ $rsa = openssl_pkey_new(array('private_key_bits' => $bits) + $config);
594
+ openssl_pkey_export($rsa, $privatekey, null, $config);
595
+ $publickey = openssl_pkey_get_details($rsa);
596
+ $publickey = $publickey['key'];
597
+
598
+ $privatekey = call_user_func_array(array($this, '_convertPrivateKey'), array_values($this->_parseKey($privatekey, CRYPT_RSA_PRIVATE_FORMAT_PKCS1)));
599
+ $publickey = call_user_func_array(array($this, '_convertPublicKey'), array_values($this->_parseKey($publickey, CRYPT_RSA_PUBLIC_FORMAT_PKCS1)));
600
+
601
+ // clear the buffer of error strings stemming from a minimalistic openssl.cnf
602
+ while (openssl_error_string() !== false);
603
+
604
+ return array(
605
+ 'privatekey' => $privatekey,
606
+ 'publickey' => $publickey,
607
+ 'partialkey' => false
608
+ );
609
+ }
610
+
611
+ static $e;
612
+ if (!isset($e)) {
613
+ $e = new Math_BigInteger(CRYPT_RSA_EXPONENT);
614
+ }
615
+
616
+ extract($this->_generateMinMax($bits));
617
+ $absoluteMin = $min;
618
+ $temp = $bits >> 1; // divide by two to see how many bits P and Q would be
619
+ if ($temp > CRYPT_RSA_SMALLEST_PRIME) {
620
+ $num_primes = floor($bits / CRYPT_RSA_SMALLEST_PRIME);
621
+ $temp = CRYPT_RSA_SMALLEST_PRIME;
622
+ } else {
623
+ $num_primes = 2;
624
+ }
625
+ extract($this->_generateMinMax($temp + $bits % $temp));
626
+ $finalMax = $max;
627
+ extract($this->_generateMinMax($temp));
628
+
629
+ $generator = new Math_BigInteger();
630
+
631
+ $n = $this->one->copy();
632
+ if (!empty($partial)) {
633
+ extract(unserialize($partial));
634
+ } else {
635
+ $exponents = $coefficients = $primes = array();
636
+ $lcm = array(
637
+ 'top' => $this->one->copy(),
638
+ 'bottom' => false
639
+ );
640
+ }
641
+
642
+ $start = time();
643
+ $i0 = count($primes) + 1;
644
+
645
+ do {
646
+ for ($i = $i0; $i <= $num_primes; $i++) {
647
+ if ($timeout !== false) {
648
+ $timeout-= time() - $start;
649
+ $start = time();
650
+ if ($timeout <= 0) {
651
+ return array(
652
+ 'privatekey' => '',
653
+ 'publickey' => '',
654
+ 'partialkey' => serialize(array(
655
+ 'primes' => $primes,
656
+ 'coefficients' => $coefficients,
657
+ 'lcm' => $lcm,
658
+ 'exponents' => $exponents
659
+ ))
660
+ );
661
+ }
662
+ }
663
+
664
+ if ($i == $num_primes) {
665
+ list($min, $temp) = $absoluteMin->divide($n);
666
+ if (!$temp->equals($this->zero)) {
667
+ $min = $min->add($this->one); // ie. ceil()
668
+ }
669
+ $primes[$i] = $generator->randomPrime($min, $finalMax, $timeout);
670
+ } else {
671
+ $primes[$i] = $generator->randomPrime($min, $max, $timeout);
672
+ }
673
+
674
+ if ($primes[$i] === false) { // if we've reached the timeout
675
+ if (count($primes) > 1) {
676
+ $partialkey = '';
677
+ } else {
678
+ array_pop($primes);
679
+ $partialkey = serialize(array(
680
+ 'primes' => $primes,
681
+ 'coefficients' => $coefficients,
682
+ 'lcm' => $lcm,
683
+ 'exponents' => $exponents
684
+ ));
685
+ }
686
+
687
+ return array(
688
+ 'privatekey' => '',
689
+ 'publickey' => '',
690
+ 'partialkey' => $partialkey
691
+ );
692
+ }
693
+
694
+ // the first coefficient is calculated differently from the rest
695
+ // ie. instead of being $primes[1]->modInverse($primes[2]), it's $primes[2]->modInverse($primes[1])
696
+ if ($i > 2) {
697
+ $coefficients[$i] = $n->modInverse($primes[$i]);
698
+ }
699
+
700
+ $n = $n->multiply($primes[$i]);
701
+
702
+ $temp = $primes[$i]->subtract($this->one);
703
+
704
+ // textbook RSA implementations use Euler's totient function instead of the least common multiple.
705
+ // see http://en.wikipedia.org/wiki/Euler%27s_totient_function
706
+ $lcm['top'] = $lcm['top']->multiply($temp);
707
+ $lcm['bottom'] = $lcm['bottom'] === false ? $temp : $lcm['bottom']->gcd($temp);
708
+
709
+ $exponents[$i] = $e->modInverse($temp);
710
+ }
711
+
712
+ list($temp) = $lcm['top']->divide($lcm['bottom']);
713
+ $gcd = $temp->gcd($e);
714
+ $i0 = 1;
715
+ } while (!$gcd->equals($this->one));
716
+
717
+ $d = $e->modInverse($temp);
718
+
719
+ $coefficients[2] = $primes[2]->modInverse($primes[1]);
720
+
721
+ // from <http://tools.ietf.org/html/rfc3447#appendix-A.1.2>:
722
+ // RSAPrivateKey ::= SEQUENCE {
723
+ // version Version,
724
+ // modulus INTEGER, -- n
725
+ // publicExponent INTEGER, -- e
726
+ // privateExponent INTEGER, -- d
727
+ // prime1 INTEGER, -- p
728
+ // prime2 INTEGER, -- q
729
+ // exponent1 INTEGER, -- d mod (p-1)
730
+ // exponent2 INTEGER, -- d mod (q-1)
731
+ // coefficient INTEGER, -- (inverse of q) mod p
732
+ // otherPrimeInfos OtherPrimeInfos OPTIONAL
733
+ // }
734
+
735
+ return array(
736
+ 'privatekey' => $this->_convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients),
737
+ 'publickey' => $this->_convertPublicKey($n, $e),
738
+ 'partialkey' => false
739
+ );
740
+ }
741
+
742
+ /**
743
+ * Convert a private key to the appropriate format.
744
+ *
745
+ * @access private
746
+ * @see setPrivateKeyFormat()
747
+ * @param String $RSAPrivateKey
748
+ * @return String
749
+ */
750
+ function _convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients)
751
+ {
752
+ $signed = $this->privateKeyFormat != CRYPT_RSA_PRIVATE_FORMAT_XML;
753
+ $num_primes = count($primes);
754
+ $raw = array(
755
+ 'version' => $num_primes == 2 ? chr(0) : chr(1), // two-prime vs. multi
756
+ 'modulus' => $n->toBytes($signed),
757
+ 'publicExponent' => $e->toBytes($signed),
758
+ 'privateExponent' => $d->toBytes($signed),
759
+ 'prime1' => $primes[1]->toBytes($signed),
760
+ 'prime2' => $primes[2]->toBytes($signed),
761
+ 'exponent1' => $exponents[1]->toBytes($signed),
762
+ 'exponent2' => $exponents[2]->toBytes($signed),
763
+ 'coefficient' => $coefficients[2]->toBytes($signed)
764
+ );
765
+
766
+ // if the format in question does not support multi-prime rsa and multi-prime rsa was used,
767
+ // call _convertPublicKey() instead.
768
+ switch ($this->privateKeyFormat) {
769
+ case CRYPT_RSA_PRIVATE_FORMAT_XML:
770
+ if ($num_primes != 2) {
771
+ return false;
772
+ }
773
+ return "<RSAKeyValue>\r\n" .
774
+ ' <Modulus>' . base64_encode($raw['modulus']) . "</Modulus>\r\n" .
775
+ ' <Exponent>' . base64_encode($raw['publicExponent']) . "</Exponent>\r\n" .
776
+ ' <P>' . base64_encode($raw['prime1']) . "</P>\r\n" .
777
+ ' <Q>' . base64_encode($raw['prime2']) . "</Q>\r\n" .
778
+ ' <DP>' . base64_encode($raw['exponent1']) . "</DP>\r\n" .
779
+ ' <DQ>' . base64_encode($raw['exponent2']) . "</DQ>\r\n" .
780
+ ' <InverseQ>' . base64_encode($raw['coefficient']) . "</InverseQ>\r\n" .
781
+ ' <D>' . base64_encode($raw['privateExponent']) . "</D>\r\n" .
782
+ '</RSAKeyValue>';
783
+ break;
784
+ case CRYPT_RSA_PRIVATE_FORMAT_PUTTY:
785
+ if ($num_primes != 2) {
786
+ return false;
787
+ }
788
+ $key = "PuTTY-User-Key-File-2: ssh-rsa\r\nEncryption: ";
789
+ $encryption = (!empty($this->password) || is_string($this->password)) ? 'aes256-cbc' : 'none';
790
+ $key.= $encryption;
791
+ $key.= "\r\nComment: " . $this->comment . "\r\n";
792
+ $public = pack('Na*Na*Na*',
793
+ strlen('ssh-rsa'), 'ssh-rsa', strlen($raw['publicExponent']), $raw['publicExponent'], strlen($raw['modulus']), $raw['modulus']
794
+ );
795
+ $source = pack('Na*Na*Na*Na*',
796
+ strlen('ssh-rsa'), 'ssh-rsa', strlen($encryption), $encryption,
797
+ strlen($this->comment), $this->comment, strlen($public), $public
798
+ );
799
+ $public = base64_encode($public);
800
+ $key.= "Public-Lines: " . ((strlen($public) + 63) >> 6) . "\r\n";
801
+ $key.= chunk_split($public, 64);
802
+ $private = pack('Na*Na*Na*Na*',
803
+ strlen($raw['privateExponent']), $raw['privateExponent'], strlen($raw['prime1']), $raw['prime1'],
804
+ strlen($raw['prime2']), $raw['prime2'], strlen($raw['coefficient']), $raw['coefficient']
805
+ );
806
+ if (empty($this->password) && !is_string($this->password)) {
807
+ $source.= pack('Na*', strlen($private), $private);
808
+ $hashkey = 'putty-private-key-file-mac-key';
809
+ } else {
810
+ $private.= crypt_random_string(16 - (strlen($private) & 15));
811
+ $source.= pack('Na*', strlen($private), $private);
812
+ if (!class_exists('Crypt_AES')) {
813
+ include_once 'Crypt/AES.php';
814
+ }
815
+ $sequence = 0;
816
+ $symkey = '';
817
+ while (strlen($symkey) < 32) {
818
+ $temp = pack('Na*', $sequence++, $this->password);
819
+ $symkey.= pack('H*', sha1($temp));
820
+ }
821
+ $symkey = substr($symkey, 0, 32);
822
+ $crypto = new Crypt_AES();
823
+
824
+ $crypto->setKey($symkey);
825
+ $crypto->disablePadding();
826
+ $private = $crypto->encrypt($private);
827
+ $hashkey = 'putty-private-key-file-mac-key' . $this->password;
828
+ }
829
+
830
+ $private = base64_encode($private);
831
+ $key.= 'Private-Lines: ' . ((strlen($private) + 63) >> 6) . "\r\n";
832
+ $key.= chunk_split($private, 64);
833
+ if (!class_exists('Crypt_Hash')) {
834
+ include_once 'Crypt/Hash.php';
835
+ }
836
+ $hash = new Crypt_Hash('sha1');
837
+ $hash->setKey(pack('H*', sha1($hashkey)));
838
+ $key.= 'Private-MAC: ' . bin2hex($hash->hash($source)) . "\r\n";
839
+
840
+ return $key;
841
+ default: // eg. CRYPT_RSA_PRIVATE_FORMAT_PKCS1
842
+ $components = array();
843
+ foreach ($raw as $name => $value) {
844
+ $components[$name] = pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($value)), $value);
845
+ }
846
+
847
+ $RSAPrivateKey = implode('', $components);
848
+
849
+ if ($num_primes > 2) {
850
+ $OtherPrimeInfos = '';
851
+ for ($i = 3; $i <= $num_primes; $i++) {
852
+ // OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
853
+ //
854
+ // OtherPrimeInfo ::= SEQUENCE {
855
+ // prime INTEGER, -- ri
856
+ // exponent INTEGER, -- di
857
+ // coefficient INTEGER -- ti
858
+ // }
859
+ $OtherPrimeInfo = pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($primes[$i]->toBytes(true))), $primes[$i]->toBytes(true));
860
+ $OtherPrimeInfo.= pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($exponents[$i]->toBytes(true))), $exponents[$i]->toBytes(true));
861
+ $OtherPrimeInfo.= pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($coefficients[$i]->toBytes(true))), $coefficients[$i]->toBytes(true));
862
+ $OtherPrimeInfos.= pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($OtherPrimeInfo)), $OtherPrimeInfo);
863
+ }
864
+ $RSAPrivateKey.= pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($OtherPrimeInfos)), $OtherPrimeInfos);
865
+ }
866
+
867
+ $RSAPrivateKey = pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
868
+
869
+ if ($this->privateKeyFormat == CRYPT_RSA_PRIVATE_FORMAT_PKCS8) {
870
+ $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
871
+ $RSAPrivateKey = pack('Ca*a*Ca*a*',
872
+ CRYPT_RSA_ASN1_INTEGER, "\01\00", $rsaOID, 4, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey
873
+ );
874
+ $RSAPrivateKey = pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
875
+ if (!empty($this->password) || is_string($this->password)) {
876
+ $salt = crypt_random_string(8);
877
+ $iterationCount = 2048;
878
+
879
+ if (!class_exists('Crypt_DES')) {
880
+ include_once 'Crypt/DES.php';
881
+ }
882
+ $crypto = new Crypt_DES();
883
+ $crypto->setPassword($this->password, 'pbkdf1', 'md5', $salt, $iterationCount);
884
+ $RSAPrivateKey = $crypto->encrypt($RSAPrivateKey);
885
+
886
+ $parameters = pack('Ca*a*Ca*N',
887
+ CRYPT_RSA_ASN1_OCTETSTRING, $this->_encodeLength(strlen($salt)), $salt,
888
+ CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(4), $iterationCount
889
+ );
890
+ $pbeWithMD5AndDES_CBC = "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03";
891
+
892
+ $encryptionAlgorithm = pack('Ca*a*Ca*a*',
893
+ CRYPT_RSA_ASN1_OBJECT, $this->_encodeLength(strlen($pbeWithMD5AndDES_CBC)), $pbeWithMD5AndDES_CBC,
894
+ CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($parameters)), $parameters
895
+ );
896
+
897
+ $RSAPrivateKey = pack('Ca*a*Ca*a*',
898
+ CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($encryptionAlgorithm)), $encryptionAlgorithm,
899
+ CRYPT_RSA_ASN1_OCTETSTRING, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey
900
+ );
901
+
902
+ $RSAPrivateKey = pack('Ca*a*', CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
903
+
904
+ $RSAPrivateKey = "-----BEGIN ENCRYPTED PRIVATE KEY-----\r\n" .
905
+ chunk_split(base64_encode($RSAPrivateKey), 64) .
906
+ '-----END ENCRYPTED PRIVATE KEY-----';
907
+ } else {
908
+ $RSAPrivateKey = "-----BEGIN PRIVATE KEY-----\r\n" .
909
+ chunk_split(base64_encode($RSAPrivateKey), 64) .
910
+ '-----END PRIVATE KEY-----';
911
+ }
912
+ return $RSAPrivateKey;
913
+ }
914
+
915
+ if (!empty($this->password) || is_string($this->password)) {
916
+ $iv = crypt_random_string(8);
917
+ $symkey = pack('H*', md5($this->password . $iv)); // symkey is short for symmetric key
918
+ $symkey.= substr(pack('H*', md5($symkey . $this->password . $iv)), 0, 8);
919
+ if (!class_exists('Crypt_TripleDES')) {
920
+ include_once 'Crypt/TripleDES.php';
921
+ }
922
+ $des = new Crypt_TripleDES();
923
+ $des->setKey($symkey);
924
+ $des->setIV($iv);
925
+ $iv = strtoupper(bin2hex($iv));
926
+ $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .
927
+ "Proc-Type: 4,ENCRYPTED\r\n" .
928
+ "DEK-Info: DES-EDE3-CBC,$iv\r\n" .
929
+ "\r\n" .
930
+ chunk_split(base64_encode($des->encrypt($RSAPrivateKey)), 64) .
931
+ '-----END RSA PRIVATE KEY-----';
932
+ } else {
933
+ $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .
934
+ chunk_split(base64_encode($RSAPrivateKey), 64) .
935
+ '-----END RSA PRIVATE KEY-----';
936
+ }
937
+
938
+ return $RSAPrivateKey;
939
+ }
940
+ }
941
+
942
+ /**
943
+ * Convert a public key to the appropriate format
944
+ *
945
+ * @access private
946
+ * @see setPublicKeyFormat()
947
+ * @param String $RSAPrivateKey
948
+ * @return String
949
+ */
950
+ function _convertPublicKey($n, $e)
951
+ {
952
+ $signed = $this->publicKeyFormat != CRYPT_RSA_PUBLIC_FORMAT_XML;
953
+
954
+ $modulus = $n->toBytes($signed);
955
+ $publicExponent = $e->toBytes($signed);
956
+
957
+ switch ($this->publicKeyFormat) {
958
+ case CRYPT_RSA_PUBLIC_FORMAT_RAW:
959
+ return array('e' => $e->copy(), 'n' => $n->copy());
960
+ case CRYPT_RSA_PUBLIC_FORMAT_XML:
961
+ return "<RSAKeyValue>\r\n" .
962
+ ' <Modulus>' . base64_encode($modulus) . "</Modulus>\r\n" .
963
+ ' <Exponent>' . base64_encode($publicExponent) . "</Exponent>\r\n" .
964
+ '</RSAKeyValue>';
965
+ break;
966
+ case CRYPT_RSA_PUBLIC_FORMAT_OPENSSH:
967
+ // from <http://tools.ietf.org/html/rfc4253#page-15>:
968
+ // string "ssh-rsa"
969
+ // mpint e
970
+ // mpint n
971
+ $RSAPublicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publicExponent), $publicExponent, strlen($modulus), $modulus);
972
+ $RSAPublicKey = 'ssh-rsa ' . base64_encode($RSAPublicKey) . ' ' . $this->comment;
973
+
974
+ return $RSAPublicKey;
975
+ default: // eg. CRYPT_RSA_PUBLIC_FORMAT_PKCS1_RAW or CRYPT_RSA_PUBLIC_FORMAT_PKCS1
976
+ // from <http://tools.ietf.org/html/rfc3447#appendix-A.1.1>:
977
+ // RSAPublicKey ::= SEQUENCE {
978
+ // modulus INTEGER, -- n
979
+ // publicExponent INTEGER -- e
980
+ // }
981
+ $components = array(
982
+ 'modulus' => pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($modulus)), $modulus),
983
+ 'publicExponent' => pack('Ca*a*', CRYPT_RSA_ASN1_INTEGER, $this->_encodeLength(strlen($publicExponent)), $publicExponent)
984
+ );
985
+
986
+ $RSAPublicKey = pack('Ca*a*a*',
987
+ CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])),
988
+ $components['modulus'], $components['publicExponent']
989
+ );
990
+
991
+ if ($this->publicKeyFormat == CRYPT_RSA_PUBLIC_FORMAT_PKCS1_RAW) {
992
+ $RSAPublicKey = "-----BEGIN RSA PUBLIC KEY-----\r\n" .
993
+ chunk_split(base64_encode($RSAPublicKey), 64) .
994
+ '-----END RSA PUBLIC KEY-----';
995
+ } else {
996
+ // sequence(oid(1.2.840.113549.1.1.1), null)) = rsaEncryption.
997
+ $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
998
+ $RSAPublicKey = chr(0) . $RSAPublicKey;
999
+ $RSAPublicKey = chr(3) . $this->_encodeLength(strlen($RSAPublicKey)) . $RSAPublicKey;
1000
+
1001
+ $RSAPublicKey = pack('Ca*a*',
1002
+ CRYPT_RSA_ASN1_SEQUENCE, $this->_encodeLength(strlen($rsaOID . $RSAPublicKey)), $rsaOID . $RSAPublicKey
1003
+ );
1004
+
1005
+ $RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" .
1006
+ chunk_split(base64_encode($RSAPublicKey), 64) .
1007
+ '-----END PUBLIC KEY-----';
1008
+ }
1009
+
1010
+ return $RSAPublicKey;
1011
+ }
1012
+ }
1013
+
1014
+ /**
1015
+ * Break a public or private key down into its constituant components
1016
+ *
1017
+ * @access private
1018
+ * @see _convertPublicKey()
1019
+ * @see _convertPrivateKey()
1020
+ * @param String $key
1021
+ * @param Integer $type
1022
+ * @return Array
1023
+ */
1024
+ function _parseKey($key, $type)
1025
+ {
1026
+ if ($type != CRYPT_RSA_PUBLIC_FORMAT_RAW && !is_string($key)) {
1027
+ return false;
1028
+ }
1029
+
1030
+ switch ($type) {
1031
+ case CRYPT_RSA_PUBLIC_FORMAT_RAW:
1032
+ if (!is_array($key)) {
1033
+ return false;
1034
+ }
1035
+ $components = array();
1036
+ switch (true) {
1037
+ case isset($key['e']):
1038
+ $components['publicExponent'] = $key['e']->copy();
1039
+ break;
1040
+ case isset($key['exponent']):
1041
+ $components['publicExponent'] = $key['exponent']->copy();
1042
+ break;
1043
+ case isset($key['publicExponent']):
1044
+ $components['publicExponent'] = $key['publicExponent']->copy();
1045
+ break;
1046
+ case isset($key[0]):
1047
+ $components['publicExponent'] = $key[0]->copy();
1048
+ }
1049
+ switch (true) {
1050
+ case isset($key['n']):
1051
+ $components['modulus'] = $key['n']->copy();
1052
+ break;
1053
+ case isset($key['modulo']):
1054
+ $components['modulus'] = $key['modulo']->copy();
1055
+ break;
1056
+ case isset($key['modulus']):
1057
+ $components['modulus'] = $key['modulus']->copy();
1058
+ break;
1059
+ case isset($key[1]):
1060
+ $components['modulus'] = $key[1]->copy();
1061
+ }
1062
+ return isset($components['modulus']) && isset($components['publicExponent']) ? $components : false;
1063
+ case CRYPT_RSA_PRIVATE_FORMAT_PKCS1:
1064
+ case CRYPT_RSA_PRIVATE_FORMAT_PKCS8:
1065
+ case CRYPT_RSA_PUBLIC_FORMAT_PKCS1:
1066
+ /* Although PKCS#1 proposes a format that public and private keys can use, encrypting them is
1067
+ "outside the scope" of PKCS#1. PKCS#1 then refers you to PKCS#12 and PKCS#15 if you're wanting to
1068
+ protect private keys, however, that's not what OpenSSL* does. OpenSSL protects private keys by adding
1069
+ two new "fields" to the key - DEK-Info and Proc-Type. These fields are discussed here:
1070
+
1071
+ http://tools.ietf.org/html/rfc1421#section-4.6.1.1
1072
+ http://tools.ietf.org/html/rfc1421#section-4.6.1.3
1073
+
1074
+ DES-EDE3-CBC as an algorithm, however, is not discussed anywhere, near as I can tell.
1075
+ DES-CBC and DES-EDE are discussed in RFC1423, however, DES-EDE3-CBC isn't, nor is its key derivation
1076
+ function. As is, the definitive authority on this encoding scheme isn't the IETF but rather OpenSSL's
1077
+ own implementation. ie. the implementation *is* the standard and any bugs that may exist in that
1078
+ implementation are part of the standard, as well.
1079
+
1080
+ * OpenSSL is the de facto standard. It's utilized by OpenSSH and other projects */
1081
+ if (preg_match('#DEK-Info: (.+),(.+)#', $key, $matches)) {
1082
+ $iv = pack('H*', trim($matches[2]));
1083
+ $symkey = pack('H*', md5($this->password . substr($iv, 0, 8))); // symkey is short for symmetric key
1084
+ $symkey.= pack('H*', md5($symkey . $this->password . substr($iv, 0, 8)));
1085
+ // remove the Proc-Type / DEK-Info sections as they're no longer needed
1086
+ $key = preg_replace('#^(?:Proc-Type|DEK-Info): .*#m', '', $key);
1087
+ $ciphertext = $this->_extractBER($key);
1088
+ if ($ciphertext === false) {
1089
+ $ciphertext = $key;
1090
+ }
1091
+ switch ($matches[1]) {
1092
+ case 'AES-256-CBC':
1093
+ if (!class_exists('Crypt_AES')) {
1094
+ include_once 'Crypt/AES.php';
1095
+ }
1096
+ $crypto = new Crypt_AES();
1097
+ break;
1098
+ case 'AES-128-CBC':
1099
+ if (!class_exists('Crypt_AES')) {
1100
+ include_once 'Crypt/AES.php';
1101
+ }
1102
+ $symkey = substr($symkey, 0, 16);
1103
+ $crypto = new Crypt_AES();
1104
+ break;
1105
+ case 'DES-EDE3-CFB':
1106
+ if (!class_exists('Crypt_TripleDES')) {
1107
+ include_once 'Crypt/TripleDES.php';
1108
+ }
1109
+ $crypto = new Crypt_TripleDES(CRYPT_DES_MODE_CFB);
1110
+ break;
1111
+ case 'DES-EDE3-CBC':
1112
+ if (!class_exists('Crypt_TripleDES')) {
1113
+ include_once 'Crypt/TripleDES.php';
1114
+ }
1115
+ $symkey = substr($symkey, 0, 24);
1116
+ $crypto = new Crypt_TripleDES();
1117
+ break;
1118
+ case 'DES-CBC':
1119
+ if (!class_exists('Crypt_DES')) {
1120
+ include_once 'Crypt/DES.php';
1121
+ }
1122
+ $crypto = new Crypt_DES();
1123
+ break;
1124
+ default:
1125
+ return false;
1126
+ }
1127
+ $crypto->setKey($symkey);
1128
+ $crypto->setIV($iv);
1129
+ $decoded = $crypto->decrypt($ciphertext);
1130
+ } else {
1131
+ $decoded = $this->_extractBER($key);
1132
+ }
1133
+
1134
+ if ($decoded !== false) {
1135
+ $key = $decoded;
1136
+ }
1137
+
1138
+ $components = array();
1139
+
1140
+ if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_SEQUENCE) {
1141
+ return false;
1142
+ }
1143
+ if ($this->_decodeLength($key) != strlen($key)) {
1144
+ return false;
1145
+ }
1146
+
1147
+ $tag = ord($this->_string_shift($key));
1148
+ /* intended for keys for which OpenSSL's asn1parse returns the following:
1149
+
1150
+ 0:d=0 hl=4 l= 631 cons: SEQUENCE
1151
+ 4:d=1 hl=2 l= 1 prim: INTEGER :00
1152
+ 7:d=1 hl=2 l= 13 cons: SEQUENCE
1153
+ 9:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
1154
+ 20:d=2 hl=2 l= 0 prim: NULL
1155
+ 22:d=1 hl=4 l= 609 prim: OCTET STRING
1156
+
1157
+ ie. PKCS8 keys*/
1158
+
1159
+ if ($tag == CRYPT_RSA_ASN1_INTEGER && substr($key, 0, 3) == "\x01\x00\x30") {
1160
+ $this->_string_shift($key, 3);
1161
+ $tag = CRYPT_RSA_ASN1_SEQUENCE;
1162
+ }
1163
+
1164
+ if ($tag == CRYPT_RSA_ASN1_SEQUENCE) {
1165
+ $temp = $this->_string_shift($key, $this->_decodeLength($key));
1166
+ if (ord($this->_string_shift($temp)) != CRYPT_RSA_ASN1_OBJECT) {
1167
+ return false;
1168
+ }
1169
+ $length = $this->_decodeLength($temp);
1170
+ switch ($this->_string_shift($temp, $length)) {
1171
+ case "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01": // rsaEncryption
1172
+ break;
1173
+ case "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03": // pbeWithMD5AndDES-CBC
1174
+ /*
1175
+ PBEParameter ::= SEQUENCE {
1176
+ salt OCTET STRING (SIZE(8)),
1177
+ iterationCount INTEGER }
1178
+ */
1179
+ if (ord($this->_string_shift($temp)) != CRYPT_RSA_ASN1_SEQUENCE) {
1180
+ return false;
1181
+ }
1182
+ if ($this->_decodeLength($temp) != strlen($temp)) {
1183
+ return false;
1184
+ }
1185
+ $this->_string_shift($temp); // assume it's an octet string
1186
+ $salt = $this->_string_shift($temp, $this->_decodeLength($temp));
1187
+ if (ord($this->_string_shift($temp)) != CRYPT_RSA_ASN1_INTEGER) {
1188
+ return false;
1189
+ }
1190
+ $this->_decodeLength($temp);
1191
+ list(, $iterationCount) = unpack('N', str_pad($temp, 4, chr(0), STR_PAD_LEFT));
1192
+ $this->_string_shift($key); // assume it's an octet string
1193
+ $length = $this->_decodeLength($key);
1194
+ if (strlen($key) != $length) {
1195
+ return false;
1196
+ }
1197
+
1198
+ if (!class_exists('Crypt_DES')) {
1199
+ include_once 'Crypt/DES.php';
1200
+ }
1201
+ $crypto = new Crypt_DES();
1202
+ $crypto->setPassword($this->password, 'pbkdf1', 'md5', $salt, $iterationCount);
1203
+ $key = $crypto->decrypt($key);
1204
+ if ($key === false) {
1205
+ return false;
1206
+ }
1207
+ return $this->_parseKey($key, CRYPT_RSA_PRIVATE_FORMAT_PKCS1);
1208
+ default:
1209
+ return false;
1210
+ }
1211
+ /* intended for keys for which OpenSSL's asn1parse returns the following:
1212
+
1213
+ 0:d=0 hl=4 l= 290 cons: SEQUENCE
1214
+ 4:d=1 hl=2 l= 13 cons: SEQUENCE
1215
+ 6:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
1216
+ 17:d=2 hl=2 l= 0 prim: NULL
1217
+ 19:d=1 hl=4 l= 271 prim: BIT STRING */
1218
+ $tag = ord($this->_string_shift($key)); // skip over the BIT STRING / OCTET STRING tag
1219
+ $this->_decodeLength($key); // skip over the BIT STRING / OCTET STRING length
1220
+ // "The initial octet shall encode, as an unsigned binary integer wtih bit 1 as the least significant bit, the number of
1221
+ // unused bits in the final subsequent octet. The number shall be in the range zero to seven."
1222
+ // -- http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf (section 8.6.2.2)
1223
+ if ($tag == CRYPT_RSA_ASN1_BITSTRING) {
1224
+ $this->_string_shift($key);
1225
+ }
1226
+ if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_SEQUENCE) {
1227
+ return false;
1228
+ }
1229
+ if ($this->_decodeLength($key) != strlen($key)) {
1230
+ return false;
1231
+ }
1232
+ $tag = ord($this->_string_shift($key));
1233
+ }
1234
+ if ($tag != CRYPT_RSA_ASN1_INTEGER) {
1235
+ return false;
1236
+ }
1237
+
1238
+ $length = $this->_decodeLength($key);
1239
+ $temp = $this->_string_shift($key, $length);
1240
+ if (strlen($temp) != 1 || ord($temp) > 2) {
1241
+ $components['modulus'] = new Math_BigInteger($temp, 256);
1242
+ $this->_string_shift($key); // skip over CRYPT_RSA_ASN1_INTEGER
1243
+ $length = $this->_decodeLength($key);
1244
+ $components[$type == CRYPT_RSA_PUBLIC_FORMAT_PKCS1 ? 'publicExponent' : 'privateExponent'] = new Math_BigInteger($this->_string_shift($key, $length), 256);
1245
+
1246
+ return $components;
1247
+ }
1248
+ if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_INTEGER) {
1249
+ return false;
1250
+ }
1251
+ $length = $this->_decodeLength($key);
1252
+ $components['modulus'] = new Math_BigInteger($this->_string_shift($key, $length), 256);
1253
+ $this->_string_shift($key);
1254
+ $length = $this->_decodeLength($key);
1255
+ $components['publicExponent'] = new Math_BigInteger($this->_string_shift($key, $length), 256);
1256
+ $this->_string_shift($key);
1257
+ $length = $this->_decodeLength($key);
1258
+ $components['privateExponent'] = new Math_BigInteger($this->_string_shift($key, $length), 256);
1259
+ $this->_string_shift($key);
1260
+ $length = $this->_decodeLength($key);
1261
+ $components['primes'] = array(1 => new Math_BigInteger($this->_string_shift($key, $length), 256));
1262
+ $this->_string_shift($key);
1263
+ $length = $this->_decodeLength($key);
1264
+ $components['primes'][] = new Math_BigInteger($this->_string_shift($key, $length), 256);
1265
+ $this->_string_shift($key);
1266
+ $length = $this->_decodeLength($key);
1267
+ $components['exponents'] = array(1 => new Math_BigInteger($this->_string_shift($key, $length), 256));
1268
+ $this->_string_shift($key);
1269
+ $length = $this->_decodeLength($key);
1270
+ $components['exponents'][] = new Math_BigInteger($this->_string_shift($key, $length), 256);
1271
+ $this->_string_shift($key);
1272
+ $length = $this->_decodeLength($key);
1273
+ $components['coefficients'] = array(2 => new Math_BigInteger($this->_string_shift($key, $length), 256));
1274
+
1275
+ if (!empty($key)) {
1276
+ if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_SEQUENCE) {
1277
+ return false;
1278
+ }
1279
+ $this->_decodeLength($key);
1280
+ while (!empty($key)) {
1281
+ if (ord($this->_string_shift($key)) != CRYPT_RSA_ASN1_SEQUENCE) {
1282
+ return false;
1283
+ }
1284
+ $this->_decodeLength($key);
1285
+ $key = substr($key, 1);
1286
+ $length = $this->_decodeLength($key);
1287
+ $components['primes'][] = new Math_BigInteger($this->_string_shift($key, $length), 256);
1288
+ $this->_string_shift($key);
1289
+ $length = $this->_decodeLength($key);
1290
+ $components['exponents'][] = new Math_BigInteger($this->_string_shift($key, $length), 256);
1291
+ $this->_string_shift($key);
1292
+ $length = $this->_decodeLength($key);
1293
+ $components['coefficients'][] = new Math_BigInteger($this->_string_shift($key, $length), 256);
1294
+ }
1295
+ }
1296
+
1297
+ return $components;
1298
+ case CRYPT_RSA_PUBLIC_FORMAT_OPENSSH:
1299
+ $parts = explode(' ', $key, 3);
1300
+
1301
+ $key = isset($parts[1]) ? base64_decode($parts[1]) : false;
1302
+ if ($key === false) {
1303
+ return false;
1304
+ }
1305
+
1306
+ $comment = isset($parts[2]) ? $parts[2] : false;
1307
+
1308
+ $cleanup = substr($key, 0, 11) == "\0\0\0\7ssh-rsa";
1309
+
1310
+ if (strlen($key) <= 4) {
1311
+ return false;
1312
+ }
1313
+ extract(unpack('Nlength', $this->_string_shift($key, 4)));
1314
+ $publicExponent = new Math_BigInteger($this->_string_shift($key, $length), -256);
1315
+ if (strlen($key) <= 4) {
1316
+ return false;
1317
+ }
1318
+ extract(unpack('Nlength', $this->_string_shift($key, 4)));
1319
+ $modulus = new Math_BigInteger($this->_string_shift($key, $length), -256);
1320
+
1321
+ if ($cleanup && strlen($key)) {
1322
+ if (strlen($key) <= 4) {
1323
+ return false;
1324
+ }
1325
+ extract(unpack('Nlength', $this->_string_shift($key, 4)));
1326
+ $realModulus = new Math_BigInteger($this->_string_shift($key, $length), -256);
1327
+ return strlen($key) ? false : array(
1328
+ 'modulus' => $realModulus,
1329
+ 'publicExponent' => $modulus,
1330
+ 'comment' => $comment
1331
+ );
1332
+ } else {
1333
+ return strlen($key) ? false : array(
1334
+ 'modulus' => $modulus,
1335
+ 'publicExponent' => $publicExponent,
1336
+ 'comment' => $comment
1337
+ );
1338
+ }
1339
+ // http://www.w3.org/TR/xmldsig-core/#sec-RSAKeyValue
1340
+ // http://en.wikipedia.org/wiki/XML_Signature
1341
+ case CRYPT_RSA_PRIVATE_FORMAT_XML:
1342
+ case CRYPT_RSA_PUBLIC_FORMAT_XML:
1343
+ $this->components = array();
1344
+
1345
+ $xml = xml_parser_create('UTF-8');
1346
+ xml_set_object($xml, $this);
1347
+ xml_set_element_handler($xml, '_start_element_handler', '_stop_element_handler');
1348
+ xml_set_character_data_handler($xml, '_data_handler');
1349
+ // add <xml></xml> to account for "dangling" tags like <BitStrength>...</BitStrength> that are sometimes added
1350
+ if (!xml_parse($xml, '<xml>' . $key . '</xml>')) {
1351
+ return false;
1352
+ }
1353
+
1354
+ return isset($this->components['modulus']) && isset($this->components['publicExponent']) ? $this->components : false;
1355
+ // from PuTTY's SSHPUBK.C
1356
+ case CRYPT_RSA_PRIVATE_FORMAT_PUTTY:
1357
+ $components = array();
1358
+ $key = preg_split('#\r\n|\r|\n#', $key);
1359
+ $type = trim(preg_replace('#PuTTY-User-Key-File-2: (.+)#', '$1', $key[0]));
1360
+ if ($type != 'ssh-rsa') {
1361
+ return false;
1362
+ }
1363
+ $encryption = trim(preg_replace('#Encryption: (.+)#', '$1', $key[1]));
1364
+ $comment = trim(preg_replace('#Comment: (.+)#', '$1', $key[2]));
1365
+
1366
+ $publicLength = trim(preg_replace('#Public-Lines: (\d+)#', '$1', $key[3]));
1367
+ $public = base64_decode(implode('', array_map('trim', array_slice($key, 4, $publicLength))));
1368
+ $public = substr($public, 11);
1369
+ extract(unpack('Nlength', $this->_string_shift($public, 4)));
1370
+ $components['publicExponent'] = new Math_BigInteger($this->_string_shift($public, $length), -256);
1371
+ extract(unpack('Nlength', $this->_string_shift($public, 4)));
1372
+ $components['modulus'] = new Math_BigInteger($this->_string_shift($public, $length), -256);
1373
+
1374
+ $privateLength = trim(preg_replace('#Private-Lines: (\d+)#', '$1', $key[$publicLength + 4]));
1375
+ $private = base64_decode(implode('', array_map('trim', array_slice($key, $publicLength + 5, $privateLength))));
1376
+
1377
+ switch ($encryption) {
1378
+ case 'aes256-cbc':
1379
+ if (!class_exists('Crypt_AES')) {
1380
+ include_once 'Crypt/AES.php';
1381
+ }
1382
+ $symkey = '';
1383
+ $sequence = 0;
1384
+ while (strlen($symkey) < 32) {
1385
+ $temp = pack('Na*', $sequence++, $this->password);
1386
+ $symkey.= pack('H*', sha1($temp));
1387
+ }
1388
+ $symkey = substr($symkey, 0, 32);
1389
+ $crypto = new Crypt_AES();
1390
+ }
1391
+
1392
+ if ($encryption != 'none') {
1393
+ $crypto->setKey($symkey);
1394
+ $crypto->disablePadding();
1395
+ $private = $crypto->decrypt($private);
1396
+ if ($private === false) {
1397
+ return false;
1398
+ }
1399
+ }
1400
+
1401
+ extract(unpack('Nlength', $this->_string_shift($private, 4)));
1402
+ if (strlen($private) < $length) {
1403
+ return false;
1404
+ }
1405
+ $components['privateExponent'] = new Math_BigInteger($this->_string_shift($private, $length), -256);
1406
+ extract(unpack('Nlength', $this->_string_shift($private, 4)));
1407
+ if (strlen($private) < $length) {
1408
+ return false;
1409
+ }
1410
+ $components['primes'] = array(1 => new Math_BigInteger($this->_string_shift($private, $length), -256));
1411
+ extract(unpack('Nlength', $this->_string_shift($private, 4)));
1412
+ if (strlen($private) < $length) {
1413
+ return false;
1414
+ }
1415
+ $components['primes'][] = new Math_BigInteger($this->_string_shift($private, $length), -256);
1416
+
1417
+ $temp = $components['primes'][1]->subtract($this->one);
1418
+ $components['exponents'] = array(1 => $components['publicExponent']->modInverse($temp));
1419
+ $temp = $components['primes'][2]->subtract($this->one);
1420
+ $components['exponents'][] = $components['publicExponent']->modInverse($temp);
1421
+
1422
+ extract(unpack('Nlength', $this->_string_shift($private, 4)));
1423
+ if (strlen($private) < $length) {
1424
+ return false;
1425
+ }
1426
+ $components['coefficients'] = array(2 => new Math_BigInteger($this->_string_shift($private, $length), -256));
1427
+
1428
+ return $components;
1429
+ }
1430
+ }
1431
+
1432
+ /**
1433
+ * Returns the key size
1434
+ *
1435
+ * More specifically, this returns the size of the modulo in bits.
1436
+ *
1437
+ * @access public
1438
+ * @return Integer
1439
+ */
1440
+ function getSize()
1441
+ {
1442
+ return !isset($this->modulus) ? 0 : strlen($this->modulus->toBits());
1443
+ }
1444
+
1445
+ /**
1446
+ * Start Element Handler
1447
+ *
1448
+ * Called by xml_set_element_handler()
1449
+ *
1450
+ * @access private
1451
+ * @param Resource $parser
1452
+ * @param String $name
1453
+ * @param Array $attribs
1454
+ */
1455
+ function _start_element_handler($parser, $name, $attribs)
1456
+ {
1457
+ //$name = strtoupper($name);
1458
+ switch ($name) {
1459
+ case 'MODULUS':
1460
+ $this->current = &$this->components['modulus'];
1461
+ break;
1462
+ case 'EXPONENT':
1463
+ $this->current = &$this->components['publicExponent'];
1464
+ break;
1465
+ case 'P':
1466
+ $this->current = &$this->components['primes'][1];
1467
+ break;
1468
+ case 'Q':
1469
+ $this->current = &$this->components['primes'][2];
1470
+ break;
1471
+ case 'DP':
1472
+ $this->current = &$this->components['exponents'][1];
1473
+ break;
1474
+ case 'DQ':
1475
+ $this->current = &$this->components['exponents'][2];
1476
+ break;
1477
+ case 'INVERSEQ':
1478
+ $this->current = &$this->components['coefficients'][2];
1479
+ break;
1480
+ case 'D':
1481
+ $this->current = &$this->components['privateExponent'];
1482
+ }
1483
+ $this->current = '';
1484
+ }
1485
+
1486
+ /**
1487
+ * Stop Element Handler
1488
+ *
1489
+ * Called by xml_set_element_handler()
1490
+ *
1491
+ * @access private
1492
+ * @param Resource $parser
1493
+ * @param String $name
1494
+ */
1495
+ function _stop_element_handler($parser, $name)
1496
+ {
1497
+ if (isset($this->current)) {
1498
+ $this->current = new Math_BigInteger(base64_decode($this->current), 256);
1499
+ unset($this->current);
1500
+ }
1501
+ }
1502
+
1503
+ /**
1504
+ * Data Handler
1505
+ *
1506
+ * Called by xml_set_character_data_handler()
1507
+ *
1508
+ * @access private
1509
+ * @param Resource $parser
1510
+ * @param String $data
1511
+ */
1512
+ function _data_handler($parser, $data)
1513
+ {
1514
+ if (!isset($this->current) || is_object($this->current)) {
1515
+ return;
1516
+ }
1517
+ $this->current.= trim($data);
1518
+ }
1519
+
1520
+ /**
1521
+ * Loads a public or private key
1522
+ *
1523
+ * Returns true on success and false on failure (ie. an incorrect password was provided or the key was malformed)
1524
+ *
1525
+ * @access public
1526
+ * @param String $key
1527
+ * @param Integer $type optional
1528
+ */
1529
+ function loadKey($key, $type = false)
1530
+ {
1531
+ if (is_object($key) && strtolower(get_class($key)) == 'crypt_rsa') {
1532
+ $this->privateKeyFormat = $key->privateKeyFormat;
1533
+ $this->publicKeyFormat = $key->publicKeyFormat;
1534
+ $this->k = $key->k;
1535
+ $this->hLen = $key->hLen;
1536
+ $this->sLen = $key->sLen;
1537
+ $this->mgfHLen = $key->mgfHLen;
1538
+ $this->encryptionMode = $key->encryptionMode;
1539
+ $this->signatureMode = $key->signatureMode;
1540
+ $this->password = $key->password;
1541
+ $this->configFile = $key->configFile;
1542
+ $this->comment = $key->comment;
1543
+
1544
+ if (is_object($key->hash)) {
1545
+ $this->hash = new Crypt_Hash($key->hash->getHash());
1546
+ }
1547
+ if (is_object($key->mgfHash)) {
1548
+ $this->mgfHash = new Crypt_Hash($key->mgfHash->getHash());
1549
+ }
1550
+
1551
+ if (is_object($key->modulus)) {
1552
+ $this->modulus = $key->modulus->copy();
1553
+ }
1554
+ if (is_object($key->exponent)) {
1555
+ $this->exponent = $key->exponent->copy();
1556
+ }
1557
+ if (is_object($key->publicExponent)) {
1558
+ $this->publicExponent = $key->publicExponent->copy();
1559
+ }
1560
+
1561
+ $this->primes = array();
1562
+ $this->exponents = array();
1563
+ $this->coefficients = array();
1564
+
1565
+ foreach ($this->primes as $prime) {
1566
+ $this->primes[] = $prime->copy();
1567
+ }
1568
+ foreach ($this->exponents as $exponent) {
1569
+ $this->exponents[] = $exponent->copy();
1570
+ }
1571
+ foreach ($this->coefficients as $coefficient) {
1572
+ $this->coefficients[] = $coefficient->copy();
1573
+ }
1574
+
1575
+ return true;
1576
+ }
1577
+
1578
+ if ($type === false) {
1579
+ $types = array(
1580
+ CRYPT_RSA_PUBLIC_FORMAT_RAW,
1581
+ CRYPT_RSA_PRIVATE_FORMAT_PKCS1,
1582
+ CRYPT_RSA_PRIVATE_FORMAT_XML,
1583
+ CRYPT_RSA_PRIVATE_FORMAT_PUTTY,
1584
+ CRYPT_RSA_PUBLIC_FORMAT_OPENSSH
1585
+ );
1586
+ foreach ($types as $type) {
1587
+ $components = $this->_parseKey($key, $type);
1588
+ if ($components !== false) {
1589
+ break;
1590
+ }
1591
+ }
1592
+
1593
+ } else {
1594
+ $components = $this->_parseKey($key, $type);
1595
+ }
1596
+
1597
+ if ($components === false) {
1598
+ return false;
1599
+ }
1600
+
1601
+ if (isset($components['comment']) && $components['comment'] !== false) {
1602
+ $this->comment = $components['comment'];
1603
+ }
1604
+ $this->modulus = $components['modulus'];
1605
+ $this->k = strlen($this->modulus->toBytes());
1606
+ $this->exponent = isset($components['privateExponent']) ? $components['privateExponent'] : $components['publicExponent'];
1607
+ if (isset($components['primes'])) {
1608
+ $this->primes = $components['primes'];
1609
+ $this->exponents = $components['exponents'];
1610
+ $this->coefficients = $components['coefficients'];
1611
+ $this->publicExponent = $components['publicExponent'];
1612
+ } else {
1613
+ $this->primes = array();
1614
+ $this->exponents = array();
1615
+ $this->coefficients = array();
1616
+ $this->publicExponent = false;
1617
+ }
1618
+
1619
+ switch ($type) {
1620
+ case CRYPT_RSA_PUBLIC_FORMAT_OPENSSH:
1621
+ case CRYPT_RSA_PUBLIC_FORMAT_RAW:
1622
+ $this->setPublicKey();
1623
+ break;
1624
+ case CRYPT_RSA_PRIVATE_FORMAT_PKCS1:
1625
+ switch (true) {
1626
+ case strpos($key, '-BEGIN PUBLIC KEY-') !== false:
1627
+ case strpos($key, '-BEGIN RSA PUBLIC KEY-') !== false:
1628
+ $this->setPublicKey();
1629
+ }
1630
+ }
1631
+
1632
+ return true;
1633
+ }
1634
+
1635
+ /**
1636
+ * Sets the password
1637
+ *
1638
+ * Private keys can be encrypted with a password. To unset the password, pass in the empty string or false.
1639
+ * Or rather, pass in $password such that empty($password) && !is_string($password) is true.
1640
+ *
1641
+ * @see createKey()
1642
+ * @see loadKey()
1643
+ * @access public
1644
+ * @param String $password
1645
+ */
1646
+ function setPassword($password = false)
1647
+ {
1648
+ $this->password = $password;
1649
+ }
1650
+
1651
+ /**
1652
+ * Defines the public key
1653
+ *
1654
+ * Some private key formats define the public exponent and some don't. Those that don't define it are problematic when
1655
+ * used in certain contexts. For example, in SSH-2, RSA authentication works by sending the public key along with a
1656
+ * message signed by the private key to the server. The SSH-2 server looks the public key up in an index of public keys
1657
+ * and if it's present then proceeds to verify the signature. Problem is, if your private key doesn't include the public
1658
+ * exponent this won't work unless you manually add the public exponent. phpseclib tries to guess if the key being used
1659
+ * is the public key but in the event that it guesses incorrectly you might still want to explicitly set the key as being
1660
+ * public.
1661
+ *
1662
+ * Do note that when a new key is loaded the index will be cleared.
1663
+ *
1664
+ * Returns true on success, false on failure
1665
+ *
1666
+ * @see getPublicKey()
1667
+ * @access public
1668
+ * @param String $key optional
1669
+ * @param Integer $type optional
1670
+ * @return Boolean
1671
+ */
1672
+ function setPublicKey($key = false, $type = false)
1673
+ {
1674
+ // if a public key has already been loaded return false
1675
+ if (!empty($this->publicExponent)) {
1676
+ return false;
1677
+ }
1678
+
1679
+ if ($key === false && !empty($this->modulus)) {
1680
+ $this->publicExponent = $this->exponent;
1681
+ return true;
1682
+ }
1683
+
1684
+ if ($type === false) {
1685
+ $types = array(
1686
+ CRYPT_RSA_PUBLIC_FORMAT_RAW,
1687
+ CRYPT_RSA_PUBLIC_FORMAT_PKCS1,
1688
+ CRYPT_RSA_PUBLIC_FORMAT_XML,
1689
+ CRYPT_RSA_PUBLIC_FORMAT_OPENSSH
1690
+ );
1691
+ foreach ($types as $type) {
1692
+ $components = $this->_parseKey($key, $type);
1693
+ if ($components !== false) {
1694
+ break;
1695
+ }
1696
+ }
1697
+ } else {
1698
+ $components = $this->_parseKey($key, $type);
1699
+ }
1700
+
1701
+ if ($components === false) {
1702
+ return false;
1703
+ }
1704
+
1705
+ if (empty($this->modulus) || !$this->modulus->equals($components['modulus'])) {
1706
+ $this->modulus = $components['modulus'];
1707
+ $this->exponent = $this->publicExponent = $components['publicExponent'];
1708
+ return true;
1709
+ }
1710
+
1711
+ $this->publicExponent = $components['publicExponent'];
1712
+
1713
+ return true;
1714
+ }
1715
+
1716
+ /**
1717
+ * Defines the private key
1718
+ *
1719
+ * If phpseclib guessed a private key was a public key and loaded it as such it might be desirable to force
1720
+ * phpseclib to treat the key as a private key. This function will do that.
1721
+ *
1722
+ * Do note that when a new key is loaded the index will be cleared.
1723
+ *
1724
+ * Returns true on success, false on failure
1725
+ *
1726
+ * @see getPublicKey()
1727
+ * @access public
1728
+ * @param String $key optional
1729
+ * @param Integer $type optional
1730
+ * @return Boolean
1731
+ */
1732
+ function setPrivateKey($key = false, $type = false)
1733
+ {
1734
+ if ($key === false && !empty($this->publicExponent)) {
1735
+ unset($this->publicExponent);
1736
+ return true;
1737
+ }
1738
+
1739
+ $rsa = new Crypt_RSA();
1740
+ if (!$rsa->loadKey($key, $type)) {
1741
+ return false;
1742
+ }
1743
+ unset($rsa->publicExponent);
1744
+
1745
+ // don't overwrite the old key if the new key is invalid
1746
+ $this->loadKey($rsa);
1747
+ return true;
1748
+ }
1749
+
1750
+ /**
1751
+ * Returns the public key
1752
+ *
1753
+ * The public key is only returned under two circumstances - if the private key had the public key embedded within it
1754
+ * or if the public key was set via setPublicKey(). If the currently loaded key is supposed to be the public key this
1755
+ * function won't return it since this library, for the most part, doesn't distinguish between public and private keys.
1756
+ *
1757
+ * @see getPublicKey()
1758
+ * @access public
1759
+ * @param String $key
1760
+ * @param Integer $type optional
1761
+ */
1762
+ function getPublicKey($type = CRYPT_RSA_PUBLIC_FORMAT_PKCS8)
1763
+ {
1764
+ if (empty($this->modulus) || empty($this->publicExponent)) {
1765
+ return false;
1766
+ }
1767
+
1768
+ $oldFormat = $this->publicKeyFormat;
1769
+ $this->publicKeyFormat = $type;
1770
+ $temp = $this->_convertPublicKey($this->modulus, $this->publicExponent);
1771
+ $this->publicKeyFormat = $oldFormat;
1772
+ return $temp;
1773
+ }
1774
+
1775
+ /**
1776
+ * Returns the public key's fingerprint
1777
+ *
1778
+ * The public key's fingerprint is returned, which is equivalent to running `ssh-keygen -lf rsa.pub`. If there is
1779
+ * no public key currently loaded, false is returned.
1780
+ * Example output (md5): "c1:b1:30:29:d7:b8:de:6c:97:77:10:d7:46:41:63:87" (as specified by RFC 4716)
1781
+ *
1782
+ * @access public
1783
+ * @param String $algorithm The hashing algorithm to be used. Valid options are 'md5' and 'sha256'. False is returned
1784
+ * for invalid values.
1785
+ */
1786
+ public function getPublicKeyFingerprint($algorithm = 'md5')
1787
+ {
1788
+ if (empty($this->modulus) || empty($this->publicExponent)) {
1789
+ return false;
1790
+ }
1791
+
1792
+ $modulus = $this->modulus->toBytes(true);
1793
+ $publicExponent = $this->publicExponent->toBytes(true);
1794
+
1795
+ $RSAPublicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publicExponent), $publicExponent, strlen($modulus), $modulus);
1796
+
1797
+ switch($algorithm)
1798
+ {
1799
+ case 'sha256':
1800
+ $hash = new Crypt_Hash('sha256');
1801
+ $base = base64_encode($hash->hash($RSAPublicKey));
1802
+ return substr($base, 0, strlen($base) - 1);
1803
+ case 'md5':
1804
+ return substr(chunk_split(md5($RSAPublicKey), 2, ':'), 0, -1);
1805
+ default:
1806
+ return false;
1807
+ }
1808
+
1809
+ }
1810
+
1811
+ /**
1812
+ * Returns the private key
1813
+ *
1814
+ * The private key is only returned if the currently loaded key contains the constituent prime numbers.
1815
+ *
1816
+ * @see getPublicKey()
1817
+ * @access public
1818
+ * @param String $key
1819
+ * @param Integer $type optional
1820
+ */
1821
+ function getPrivateKey($type = CRYPT_RSA_PUBLIC_FORMAT_PKCS1)
1822
+ {
1823
+ if (empty($this->primes)) {
1824
+ return false;
1825
+ }
1826
+
1827
+ $oldFormat = $this->privateKeyFormat;
1828
+ $this->privateKeyFormat = $type;
1829
+ $temp = $this->_convertPrivateKey($this->modulus, $this->publicExponent, $this->exponent, $this->primes, $this->exponents, $this->coefficients);
1830
+ $this->privateKeyFormat = $oldFormat;
1831
+ return $temp;
1832
+ }
1833
+
1834
+ /**
1835
+ * Returns a minimalistic private key
1836
+ *
1837
+ * Returns the private key without the prime number constituants. Structurally identical to a public key that
1838
+ * hasn't been set as the public key
1839
+ *
1840
+ * @see getPrivateKey()
1841
+ * @access private
1842
+ * @param String $key
1843
+ * @param Integer $type optional
1844
+ */
1845
+ function _getPrivatePublicKey($mode = CRYPT_RSA_PUBLIC_FORMAT_PKCS8)
1846
+ {
1847
+ if (empty($this->modulus) || empty($this->exponent)) {
1848
+ return false;
1849
+ }
1850
+
1851
+ $oldFormat = $this->publicKeyFormat;
1852
+ $this->publicKeyFormat = $mode;
1853
+ $temp = $this->_convertPublicKey($this->modulus, $this->exponent);
1854
+ $this->publicKeyFormat = $oldFormat;
1855
+ return $temp;
1856
+ }
1857
+
1858
+ /**
1859
+ * __toString() magic method
1860
+ *
1861
+ * @access public
1862
+ */
1863
+ function __toString()
1864
+ {
1865
+ $key = $this->getPrivateKey($this->privateKeyFormat);
1866
+ if ($key !== false) {
1867
+ return $key;
1868
+ }
1869
+ $key = $this->_getPrivatePublicKey($this->publicKeyFormat);
1870
+ return $key !== false ? $key : '';
1871
+ }
1872
+
1873
+ /**
1874
+ * __clone() magic method
1875
+ *
1876
+ * @access public
1877
+ */
1878
+ function __clone()
1879
+ {
1880
+ $key = new Crypt_RSA();
1881
+ $key->loadKey($this);
1882
+ return $key;
1883
+ }
1884
+
1885
+ /**
1886
+ * Generates the smallest and largest numbers requiring $bits bits
1887
+ *
1888
+ * @access private
1889
+ * @param Integer $bits
1890
+ * @return Array
1891
+ */
1892
+ function _generateMinMax($bits)
1893
+ {
1894
+ $bytes = $bits >> 3;
1895
+ $min = str_repeat(chr(0), $bytes);
1896
+ $max = str_repeat(chr(0xFF), $bytes);
1897
+ $msb = $bits & 7;
1898
+ if ($msb) {
1899
+ $min = chr(1 << ($msb - 1)) . $min;
1900
+ $max = chr((1 << $msb) - 1) . $max;
1901
+ } else {
1902
+ $min[0] = chr(0x80);
1903
+ }
1904
+
1905
+ return array(
1906
+ 'min' => new Math_BigInteger($min, 256),
1907
+ 'max' => new Math_BigInteger($max, 256)
1908
+ );
1909
+ }
1910
+
1911
+ /**
1912
+ * DER-decode the length
1913
+ *
1914
+ * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
1915
+ * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
1916
+ *
1917
+ * @access private
1918
+ * @param String $string
1919
+ * @return Integer
1920
+ */
1921
+ function _decodeLength(&$string)
1922
+ {
1923
+ $length = ord($this->_string_shift($string));
1924
+ if ( $length & 0x80 ) { // definite length, long form
1925
+ $length&= 0x7F;
1926
+ $temp = $this->_string_shift($string, $length);
1927
+ list(, $length) = unpack('N', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4));
1928
+ }
1929
+ return $length;
1930
+ }
1931
+
1932
+ /**
1933
+ * DER-encode the length
1934
+ *
1935
+ * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
1936
+ * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
1937
+ *
1938
+ * @access private
1939
+ * @param Integer $length
1940
+ * @return String
1941
+ */
1942
+ function _encodeLength($length)
1943
+ {
1944
+ if ($length <= 0x7F) {
1945
+ return chr($length);
1946
+ }
1947
+
1948
+ $temp = ltrim(pack('N', $length), chr(0));
1949
+ return pack('Ca*', 0x80 | strlen($temp), $temp);
1950
+ }
1951
+
1952
+ /**
1953
+ * String Shift
1954
+ *
1955
+ * Inspired by array_shift
1956
+ *
1957
+ * @param String $string
1958
+ * @param optional Integer $index
1959
+ * @return String
1960
+ * @access private
1961
+ */
1962
+ function _string_shift(&$string, $index = 1)
1963
+ {
1964
+ $substr = substr($string, 0, $index);
1965
+ $string = substr($string, $index);
1966
+ return $substr;
1967
+ }
1968
+
1969
+ /**
1970
+ * Determines the private key format
1971
+ *
1972
+ * @see createKey()
1973
+ * @access public
1974
+ * @param Integer $format
1975
+ */
1976
+ function setPrivateKeyFormat($format)
1977
+ {
1978
+ $this->privateKeyFormat = $format;
1979
+ }
1980
+
1981
+ /**
1982
+ * Determines the public key format
1983
+ *
1984
+ * @see createKey()
1985
+ * @access public
1986
+ * @param Integer $format
1987
+ */
1988
+ function setPublicKeyFormat($format)
1989
+ {
1990
+ $this->publicKeyFormat = $format;
1991
+ }
1992
+
1993
+ /**
1994
+ * Determines which hashing function should be used
1995
+ *
1996
+ * Used with signature production / verification and (if the encryption mode is CRYPT_RSA_ENCRYPTION_OAEP) encryption and
1997
+ * decryption. If $hash isn't supported, sha1 is used.
1998
+ *
1999
+ * @access public
2000
+ * @param String $hash
2001
+ */
2002
+ function setHash($hash)
2003
+ {
2004
+ // Crypt_Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example.
2005
+ switch ($hash) {
2006
+ case 'md2':
2007
+ case 'md5':
2008
+ case 'sha1':
2009
+ case 'sha256':
2010
+ case 'sha384':
2011
+ case 'sha512':
2012
+ $this->hash = new Crypt_Hash($hash);
2013
+ $this->hashName = $hash;
2014
+ break;
2015
+ default:
2016
+ $this->hash = new Crypt_Hash('sha1');
2017
+ $this->hashName = 'sha1';
2018
+ }
2019
+ $this->hLen = $this->hash->getLength();
2020
+ }
2021
+
2022
+ /**
2023
+ * Determines which hashing function should be used for the mask generation function
2024
+ *
2025
+ * The mask generation function is used by CRYPT_RSA_ENCRYPTION_OAEP and CRYPT_RSA_SIGNATURE_PSS and although it's
2026
+ * best if Hash and MGFHash are set to the same thing this is not a requirement.
2027
+ *
2028
+ * @access public
2029
+ * @param String $hash
2030
+ */
2031
+ function setMGFHash($hash)
2032
+ {
2033
+ // Crypt_Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example.
2034
+ switch ($hash) {
2035
+ case 'md2':
2036
+ case 'md5':
2037
+ case 'sha1':
2038
+ case 'sha256':
2039
+ case 'sha384':
2040
+ case 'sha512':
2041
+ $this->mgfHash = new Crypt_Hash($hash);
2042
+ break;
2043
+ default:
2044
+ $this->mgfHash = new Crypt_Hash('sha1');
2045
+ }
2046
+ $this->mgfHLen = $this->mgfHash->getLength();
2047
+ }
2048
+
2049
+ /**
2050
+ * Determines the salt length
2051
+ *
2052
+ * To quote from {@link http://tools.ietf.org/html/rfc3447#page-38 RFC3447#page-38}:
2053
+ *
2054
+ * Typical salt lengths in octets are hLen (the length of the output
2055
+ * of the hash function Hash) and 0.
2056
+ *
2057
+ * @access public
2058
+ * @param Integer $format
2059
+ */
2060
+ function setSaltLength($sLen)
2061
+ {
2062
+ $this->sLen = $sLen;
2063
+ }
2064
+
2065
+ /**
2066
+ * Integer-to-Octet-String primitive
2067
+ *
2068
+ * See {@link http://tools.ietf.org/html/rfc3447#section-4.1 RFC3447#section-4.1}.
2069
+ *
2070
+ * @access private
2071
+ * @param Math_BigInteger $x
2072
+ * @param Integer $xLen
2073
+ * @return String
2074
+ */
2075
+ function _i2osp($x, $xLen)
2076
+ {
2077
+ $x = $x->toBytes();
2078
+ if (strlen($x) > $xLen) {
2079
+ user_error('Integer too large');
2080
+ return false;
2081
+ }
2082
+ return str_pad($x, $xLen, chr(0), STR_PAD_LEFT);
2083
+ }
2084
+
2085
+ /**
2086
+ * Octet-String-to-Integer primitive
2087
+ *
2088
+ * See {@link http://tools.ietf.org/html/rfc3447#section-4.2 RFC3447#section-4.2}.
2089
+ *
2090
+ * @access private
2091
+ * @param String $x
2092
+ * @return Math_BigInteger
2093
+ */
2094
+ function _os2ip($x)
2095
+ {
2096
+ return new Math_BigInteger($x, 256);
2097
+ }
2098
+
2099
+ /**
2100
+ * Exponentiate with or without Chinese Remainder Theorem
2101
+ *
2102
+ * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.2}.
2103
+ *
2104
+ * @access private
2105
+ * @param Math_BigInteger $x
2106
+ * @return Math_BigInteger
2107
+ */
2108
+ function _exponentiate($x)
2109
+ {
2110
+ if (empty($this->primes) || empty($this->coefficients) || empty($this->exponents)) {
2111
+ return $x->modPow($this->exponent, $this->modulus);
2112
+ }
2113
+
2114
+ $num_primes = count($this->primes);
2115
+
2116
+ if (defined('CRYPT_RSA_DISABLE_BLINDING')) {
2117
+ $m_i = array(
2118
+ 1 => $x->modPow($this->exponents[1], $this->primes[1]),
2119
+ 2 => $x->modPow($this->exponents[2], $this->primes[2])
2120
+ );
2121
+ $h = $m_i[1]->subtract($m_i[2]);
2122
+ $h = $h->multiply($this->coefficients[2]);
2123
+ list(, $h) = $h->divide($this->primes[1]);
2124
+ $m = $m_i[2]->add($h->multiply($this->primes[2]));
2125
+
2126
+ $r = $this->primes[1];
2127
+ for ($i = 3; $i <= $num_primes; $i++) {
2128
+ $m_i = $x->modPow($this->exponents[$i], $this->primes[$i]);
2129
+
2130
+ $r = $r->multiply($this->primes[$i - 1]);
2131
+
2132
+ $h = $m_i->subtract($m);
2133
+ $h = $h->multiply($this->coefficients[$i]);
2134
+ list(, $h) = $h->divide($this->primes[$i]);
2135
+
2136
+ $m = $m->add($r->multiply($h));
2137
+ }
2138
+ } else {
2139
+ $smallest = $this->primes[1];
2140
+ for ($i = 2; $i <= $num_primes; $i++) {
2141
+ if ($smallest->compare($this->primes[$i]) > 0) {
2142
+ $smallest = $this->primes[$i];
2143
+ }
2144
+ }
2145
+
2146
+ $one = new Math_BigInteger(1);
2147
+
2148
+ $r = $one->random($one, $smallest->subtract($one));
2149
+
2150
+ $m_i = array(
2151
+ 1 => $this->_blind($x, $r, 1),
2152
+ 2 => $this->_blind($x, $r, 2)
2153
+ );
2154
+ $h = $m_i[1]->subtract($m_i[2]);
2155
+ $h = $h->multiply($this->coefficients[2]);
2156
+ list(, $h) = $h->divide($this->primes[1]);
2157
+ $m = $m_i[2]->add($h->multiply($this->primes[2]));
2158
+
2159
+ $r = $this->primes[1];
2160
+ for ($i = 3; $i <= $num_primes; $i++) {
2161
+ $m_i = $this->_blind($x, $r, $i);
2162
+
2163
+ $r = $r->multiply($this->primes[$i - 1]);
2164
+
2165
+ $h = $m_i->subtract($m);
2166
+ $h = $h->multiply($this->coefficients[$i]);
2167
+ list(, $h) = $h->divide($this->primes[$i]);
2168
+
2169
+ $m = $m->add($r->multiply($h));
2170
+ }
2171
+ }
2172
+
2173
+ return $m;
2174
+ }
2175
+
2176
+ /**
2177
+ * Performs RSA Blinding
2178
+ *
2179
+ * Protects against timing attacks by employing RSA Blinding.
2180
+ * Returns $x->modPow($this->exponents[$i], $this->primes[$i])
2181
+ *
2182
+ * @access private
2183
+ * @param Math_BigInteger $x
2184
+ * @param Math_BigInteger $r
2185
+ * @param Integer $i
2186
+ * @return Math_BigInteger
2187
+ */
2188
+ function _blind($x, $r, $i)
2189
+ {
2190
+ $x = $x->multiply($r->modPow($this->publicExponent, $this->primes[$i]));
2191
+ $x = $x->modPow($this->exponents[$i], $this->primes[$i]);
2192
+
2193
+ $r = $r->modInverse($this->primes[$i]);
2194
+ $x = $x->multiply($r);
2195
+ list(, $x) = $x->divide($this->primes[$i]);
2196
+
2197
+ return $x;
2198
+ }
2199
+
2200
+ /**
2201
+ * Performs blinded RSA equality testing
2202
+ *
2203
+ * Protects against a particular type of timing attack described.
2204
+ *
2205
+ * See {@link http://codahale.com/a-lesson-in-timing-attacks/ A Lesson In Timing Attacks (or, Don't use MessageDigest.isEquals)}
2206
+ *
2207
+ * Thanks for the heads up singpolyma!
2208
+ *
2209
+ * @access private
2210
+ * @param String $x
2211
+ * @param String $y
2212
+ * @return Boolean
2213
+ */
2214
+ function _equals($x, $y)
2215
+ {
2216
+ if (strlen($x) != strlen($y)) {
2217
+ return false;
2218
+ }
2219
+
2220
+ $result = 0;
2221
+ for ($i = 0; $i < strlen($x); $i++) {
2222
+ $result |= ord($x[$i]) ^ ord($y[$i]);
2223
+ }
2224
+
2225
+ return $result == 0;
2226
+ }
2227
+
2228
+ /**
2229
+ * RSAEP
2230
+ *
2231
+ * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.1}.
2232
+ *
2233
+ * @access private
2234
+ * @param Math_BigInteger $m
2235
+ * @return Math_BigInteger
2236
+ */
2237
+ function _rsaep($m)
2238
+ {
2239
+ if ($m->compare($this->zero) < 0 || $m->compare($this->modulus) > 0) {
2240
+ user_error('Message representative out of range');
2241
+ return false;
2242
+ }
2243
+ return $this->_exponentiate($m);
2244
+ }
2245
+
2246
+ /**
2247
+ * RSADP
2248
+ *
2249
+ * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.2 RFC3447#section-5.1.2}.
2250
+ *
2251
+ * @access private
2252
+ * @param Math_BigInteger $c
2253
+ * @return Math_BigInteger
2254
+ */
2255
+ function _rsadp($c)
2256
+ {
2257
+ if ($c->compare($this->zero) < 0 || $c->compare($this->modulus) > 0) {
2258
+ user_error('Ciphertext representative out of range');
2259
+ return false;
2260
+ }
2261
+ return $this->_exponentiate($c);
2262
+ }
2263
+
2264
+ /**
2265
+ * RSASP1
2266
+ *
2267
+ * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.1 RFC3447#section-5.2.1}.
2268
+ *
2269
+ * @access private
2270
+ * @param Math_BigInteger $m
2271
+ * @return Math_BigInteger
2272
+ */
2273
+ function _rsasp1($m)
2274
+ {
2275
+ if ($m->compare($this->zero) < 0 || $m->compare($this->modulus) > 0) {
2276
+ user_error('Message representative out of range');
2277
+ return false;
2278
+ }
2279
+ return $this->_exponentiate($m);
2280
+ }
2281
+
2282
+ /**
2283
+ * RSAVP1
2284
+ *
2285
+ * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.2 RFC3447#section-5.2.2}.
2286
+ *
2287
+ * @access private
2288
+ * @param Math_BigInteger $s
2289
+ * @return Math_BigInteger
2290
+ */
2291
+ function _rsavp1($s)
2292
+ {
2293
+ if ($s->compare($this->zero) < 0 || $s->compare($this->modulus) > 0) {
2294
+ user_error('Signature representative out of range');
2295
+ return false;
2296
+ }
2297
+ return $this->_exponentiate($s);
2298
+ }
2299
+
2300
+ /**
2301
+ * MGF1
2302
+ *
2303
+ * See {@link http://tools.ietf.org/html/rfc3447#appendix-B.2.1 RFC3447#appendix-B.2.1}.
2304
+ *
2305
+ * @access private
2306
+ * @param String $mgfSeed
2307
+ * @param Integer $mgfLen
2308
+ * @return String
2309
+ */
2310
+ function _mgf1($mgfSeed, $maskLen)
2311
+ {
2312
+ // if $maskLen would yield strings larger than 4GB, PKCS#1 suggests a "Mask too long" error be output.
2313
+
2314
+ $t = '';
2315
+ $count = ceil($maskLen / $this->mgfHLen);
2316
+ for ($i = 0; $i < $count; $i++) {
2317
+ $c = pack('N', $i);
2318
+ $t.= $this->mgfHash->hash($mgfSeed . $c);
2319
+ }
2320
+
2321
+ return substr($t, 0, $maskLen);
2322
+ }
2323
+
2324
+ /**
2325
+ * RSAES-OAEP-ENCRYPT
2326
+ *
2327
+ * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.1 RFC3447#section-7.1.1} and
2328
+ * {http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding OAES}.
2329
+ *
2330
+ * @access private
2331
+ * @param String $m
2332
+ * @param String $l
2333
+ * @return String
2334
+ */
2335
+ function _rsaes_oaep_encrypt($m, $l = '')
2336
+ {
2337
+ $mLen = strlen($m);
2338
+
2339
+ // Length checking
2340
+
2341
+ // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error
2342
+ // be output.
2343
+
2344
+ if ($mLen > $this->k - 2 * $this->hLen - 2) {
2345
+ user_error('Message too long');
2346
+ return false;
2347
+ }
2348
+
2349
+ // EME-OAEP encoding
2350
+
2351
+ $lHash = $this->hash->hash($l);
2352
+ $ps = str_repeat(chr(0), $this->k - $mLen - 2 * $this->hLen - 2);
2353
+ $db = $lHash . $ps . chr(1) . $m;
2354
+ $seed = crypt_random_string($this->hLen);
2355
+ $dbMask = $this->_mgf1($seed, $this->k - $this->hLen - 1);
2356
+ $maskedDB = $db ^ $dbMask;
2357
+ $seedMask = $this->_mgf1($maskedDB, $this->hLen);
2358
+ $maskedSeed = $seed ^ $seedMask;
2359
+ $em = chr(0) . $maskedSeed . $maskedDB;
2360
+
2361
+ // RSA encryption
2362
+
2363
+ $m = $this->_os2ip($em);
2364
+ $c = $this->_rsaep($m);
2365
+ $c = $this->_i2osp($c, $this->k);
2366
+
2367
+ // Output the ciphertext C
2368
+
2369
+ return $c;
2370
+ }
2371
+
2372
+ /**
2373
+ * RSAES-OAEP-DECRYPT
2374
+ *
2375
+ * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.2 RFC3447#section-7.1.2}. The fact that the error
2376
+ * messages aren't distinguishable from one another hinders debugging, but, to quote from RFC3447#section-7.1.2:
2377
+ *
2378
+ * Note. Care must be taken to ensure that an opponent cannot
2379
+ * distinguish the different error conditions in Step 3.g, whether by
2380
+ * error message or timing, or, more generally, learn partial
2381
+ * information about the encoded message EM. Otherwise an opponent may
2382
+ * be able to obtain useful information about the decryption of the
2383
+ * ciphertext C, leading to a chosen-ciphertext attack such as the one
2384
+ * observed by Manger [36].
2385
+ *
2386
+ * As for $l... to quote from {@link http://tools.ietf.org/html/rfc3447#page-17 RFC3447#page-17}:
2387
+ *
2388
+ * Both the encryption and the decryption operations of RSAES-OAEP take
2389
+ * the value of a label L as input. In this version of PKCS #1, L is
2390
+ * the empty string; other uses of the label are outside the scope of
2391
+ * this document.
2392
+ *
2393
+ * @access private
2394
+ * @param String $c
2395
+ * @param String $l
2396
+ * @return String
2397
+ */
2398
+ function _rsaes_oaep_decrypt($c, $l = '')
2399
+ {
2400
+ // Length checking
2401
+
2402
+ // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error
2403
+ // be output.
2404
+
2405
+ if (strlen($c) != $this->k || $this->k < 2 * $this->hLen + 2) {
2406
+ user_error('Decryption error');
2407
+ return false;
2408
+ }
2409
+
2410
+ // RSA decryption
2411
+
2412
+ $c = $this->_os2ip($c);
2413
+ $m = $this->_rsadp($c);
2414
+ if ($m === false) {
2415
+ user_error('Decryption error');
2416
+ return false;
2417
+ }
2418
+ $em = $this->_i2osp($m, $this->k);
2419
+
2420
+ // EME-OAEP decoding
2421
+
2422
+ $lHash = $this->hash->hash($l);
2423
+ $y = ord($em[0]);
2424
+ $maskedSeed = substr($em, 1, $this->hLen);
2425
+ $maskedDB = substr($em, $this->hLen + 1);
2426
+ $seedMask = $this->_mgf1($maskedDB, $this->hLen);
2427
+ $seed = $maskedSeed ^ $seedMask;
2428
+ $dbMask = $this->_mgf1($seed, $this->k - $this->hLen - 1);
2429
+ $db = $maskedDB ^ $dbMask;
2430
+ $lHash2 = substr($db, 0, $this->hLen);
2431
+ $m = substr($db, $this->hLen);
2432
+ if ($lHash != $lHash2) {
2433
+ user_error('Decryption error');
2434
+ return false;
2435
+ }
2436
+ $m = ltrim($m, chr(0));
2437
+ if (ord($m[0]) != 1) {
2438
+ user_error('Decryption error');
2439
+ return false;
2440
+ }
2441
+
2442
+ // Output the message M
2443
+
2444
+ return substr($m, 1);
2445
+ }
2446
+
2447
+ /**
2448
+ * RSAES-PKCS1-V1_5-ENCRYPT
2449
+ *
2450
+ * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.1 RFC3447#section-7.2.1}.
2451
+ *
2452
+ * @access private
2453
+ * @param String $m
2454
+ * @return String
2455
+ */
2456
+ function _rsaes_pkcs1_v1_5_encrypt($m)
2457
+ {
2458
+ $mLen = strlen($m);
2459
+
2460
+ // Length checking
2461
+
2462
+ if ($mLen > $this->k - 11) {
2463
+ user_error('Message too long');
2464
+ return false;
2465
+ }
2466
+
2467
+ // EME-PKCS1-v1_5 encoding
2468
+
2469
+ $psLen = $this->k - $mLen - 3;
2470
+ $ps = '';
2471
+ while (strlen($ps) != $psLen) {
2472
+ $temp = crypt_random_string($psLen - strlen($ps));
2473
+ $temp = str_replace("\x00", '', $temp);
2474
+ $ps.= $temp;
2475
+ }
2476
+ $type = 2;
2477
+ // see the comments of _rsaes_pkcs1_v1_5_decrypt() to understand why this is being done
2478
+ if (defined('CRYPT_RSA_PKCS15_COMPAT') && (!isset($this->publicExponent) || $this->exponent !== $this->publicExponent)) {
2479
+ $type = 1;
2480
+ // "The padding string PS shall consist of k-3-||D|| octets. ... for block type 01, they shall have value FF"
2481
+ $ps = str_repeat("\xFF", $psLen);
2482
+ }
2483
+ $em = chr(0) . chr($type) . $ps . chr(0) . $m;
2484
+
2485
+ // RSA encryption
2486
+ $m = $this->_os2ip($em);
2487
+ $c = $this->_rsaep($m);
2488
+ $c = $this->_i2osp($c, $this->k);
2489
+
2490
+ // Output the ciphertext C
2491
+
2492
+ return $c;
2493
+ }
2494
+
2495
+ /**
2496
+ * RSAES-PKCS1-V1_5-DECRYPT
2497
+ *
2498
+ * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.2 RFC3447#section-7.2.2}.
2499
+ *
2500
+ * For compatibility purposes, this function departs slightly from the description given in RFC3447.
2501
+ * The reason being that RFC2313#section-8.1 (PKCS#1 v1.5) states that ciphertext's encrypted by the
2502
+ * private key should have the second byte set to either 0 or 1 and that ciphertext's encrypted by the
2503
+ * public key should have the second byte set to 2. In RFC3447 (PKCS#1 v2.1), the second byte is supposed
2504
+ * to be 2 regardless of which key is used. For compatibility purposes, we'll just check to make sure the
2505
+ * second byte is 2 or less. If it is, we'll accept the decrypted string as valid.
2506
+ *
2507
+ * As a consequence of this, a private key encrypted ciphertext produced with Crypt_RSA may not decrypt
2508
+ * with a strictly PKCS#1 v1.5 compliant RSA implementation. Public key encrypted ciphertext's should but
2509
+ * not private key encrypted ciphertext's.
2510
+ *
2511
+ * @access private
2512
+ * @param String $c
2513
+ * @return String
2514
+ */
2515
+ function _rsaes_pkcs1_v1_5_decrypt($c)
2516
+ {
2517
+ // Length checking
2518
+
2519
+ if (strlen($c) != $this->k) { // or if k < 11
2520
+ user_error('Decryption error');
2521
+ return false;
2522
+ }
2523
+
2524
+ // RSA decryption
2525
+
2526
+ $c = $this->_os2ip($c);
2527
+ $m = $this->_rsadp($c);
2528
+
2529
+ if ($m === false) {
2530
+ user_error('Decryption error');
2531
+ return false;
2532
+ }
2533
+ $em = $this->_i2osp($m, $this->k);
2534
+
2535
+ // EME-PKCS1-v1_5 decoding
2536
+
2537
+ if (ord($em[0]) != 0 || ord($em[1]) > 2) {
2538
+ user_error('Decryption error');
2539
+ return false;
2540
+ }
2541
+
2542
+ $ps = substr($em, 2, strpos($em, chr(0), 2) - 2);
2543
+ $m = substr($em, strlen($ps) + 3);
2544
+
2545
+ if (strlen($ps) < 8) {
2546
+ user_error('Decryption error');
2547
+ return false;
2548
+ }
2549
+
2550
+ // Output M
2551
+
2552
+ return $m;
2553
+ }
2554
+
2555
+ /**
2556
+ * EMSA-PSS-ENCODE
2557
+ *
2558
+ * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.1 RFC3447#section-9.1.1}.
2559
+ *
2560
+ * @access private
2561
+ * @param String $m
2562
+ * @param Integer $emBits
2563
+ */
2564
+ function _emsa_pss_encode($m, $emBits)
2565
+ {
2566
+ // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error
2567
+ // be output.
2568
+
2569
+ $emLen = ($emBits + 1) >> 3; // ie. ceil($emBits / 8)
2570
+ $sLen = $this->sLen === false ? $this->hLen : $this->sLen;
2571
+
2572
+ $mHash = $this->hash->hash($m);
2573
+ if ($emLen < $this->hLen + $sLen + 2) {
2574
+ user_error('Encoding error');
2575
+ return false;
2576
+ }
2577
+
2578
+ $salt = crypt_random_string($sLen);
2579
+ $m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt;
2580
+ $h = $this->hash->hash($m2);
2581
+ $ps = str_repeat(chr(0), $emLen - $sLen - $this->hLen - 2);
2582
+ $db = $ps . chr(1) . $salt;
2583
+ $dbMask = $this->_mgf1($h, $emLen - $this->hLen - 1);
2584
+ $maskedDB = $db ^ $dbMask;
2585
+ $maskedDB[0] = ~chr(0xFF << ($emBits & 7)) & $maskedDB[0];
2586
+ $em = $maskedDB . $h . chr(0xBC);
2587
+
2588
+ return $em;
2589
+ }
2590
+
2591
+ /**
2592
+ * EMSA-PSS-VERIFY
2593
+ *
2594
+ * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.2 RFC3447#section-9.1.2}.
2595
+ *
2596
+ * @access private
2597
+ * @param String $m
2598
+ * @param String $em
2599
+ * @param Integer $emBits
2600
+ * @return String
2601
+ */
2602
+ function _emsa_pss_verify($m, $em, $emBits)
2603
+ {
2604
+ // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error
2605
+ // be output.
2606
+
2607
+ $emLen = ($emBits + 1) >> 3; // ie. ceil($emBits / 8);
2608
+ $sLen = $this->sLen === false ? $this->hLen : $this->sLen;
2609
+
2610
+ $mHash = $this->hash->hash($m);
2611
+ if ($emLen < $this->hLen + $sLen + 2) {
2612
+ return false;
2613
+ }
2614
+
2615
+ if ($em[strlen($em) - 1] != chr(0xBC)) {
2616
+ return false;
2617
+ }
2618
+
2619
+ $maskedDB = substr($em, 0, -$this->hLen - 1);
2620
+ $h = substr($em, -$this->hLen - 1, $this->hLen);
2621
+ $temp = chr(0xFF << ($emBits & 7));
2622
+ if ((~$maskedDB[0] & $temp) != $temp) {
2623
+ return false;
2624
+ }
2625
+ $dbMask = $this->_mgf1($h, $emLen - $this->hLen - 1);
2626
+ $db = $maskedDB ^ $dbMask;
2627
+ $db[0] = ~chr(0xFF << ($emBits & 7)) & $db[0];
2628
+ $temp = $emLen - $this->hLen - $sLen - 2;
2629
+ if (substr($db, 0, $temp) != str_repeat(chr(0), $temp) || ord($db[$temp]) != 1) {
2630
+ return false;
2631
+ }
2632
+ $salt = substr($db, $temp + 1); // should be $sLen long
2633
+ $m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt;
2634
+ $h2 = $this->hash->hash($m2);
2635
+ return $this->_equals($h, $h2);
2636
+ }
2637
+
2638
+ /**
2639
+ * RSASSA-PSS-SIGN
2640
+ *
2641
+ * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.1 RFC3447#section-8.1.1}.
2642
+ *
2643
+ * @access private
2644
+ * @param String $m
2645
+ * @return String
2646
+ */
2647
+ function _rsassa_pss_sign($m)
2648
+ {
2649
+ // EMSA-PSS encoding
2650
+
2651
+ $em = $this->_emsa_pss_encode($m, 8 * $this->k - 1);
2652
+
2653
+ // RSA signature
2654
+
2655
+ $m = $this->_os2ip($em);
2656
+ $s = $this->_rsasp1($m);
2657
+ $s = $this->_i2osp($s, $this->k);
2658
+
2659
+ // Output the signature S
2660
+
2661
+ return $s;
2662
+ }
2663
+
2664
+ /**
2665
+ * RSASSA-PSS-VERIFY
2666
+ *
2667
+ * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.2 RFC3447#section-8.1.2}.
2668
+ *
2669
+ * @access private
2670
+ * @param String $m
2671
+ * @param String $s
2672
+ * @return String
2673
+ */
2674
+ function _rsassa_pss_verify($m, $s)
2675
+ {
2676
+ // Length checking
2677
+
2678
+ if (strlen($s) != $this->k) {
2679
+ user_error('Invalid signature');
2680
+ return false;
2681
+ }
2682
+
2683
+ // RSA verification
2684
+
2685
+ $modBits = 8 * $this->k;
2686
+
2687
+ $s2 = $this->_os2ip($s);
2688
+ $m2 = $this->_rsavp1($s2);
2689
+ if ($m2 === false) {
2690
+ user_error('Invalid signature');
2691
+ return false;
2692
+ }
2693
+ $em = $this->_i2osp($m2, $modBits >> 3);
2694
+ if ($em === false) {
2695
+ user_error('Invalid signature');
2696
+ return false;
2697
+ }
2698
+
2699
+ // EMSA-PSS verification
2700
+
2701
+ return $this->_emsa_pss_verify($m, $em, $modBits - 1);
2702
+ }
2703
+
2704
+ /**
2705
+ * EMSA-PKCS1-V1_5-ENCODE
2706
+ *
2707
+ * See {@link http://tools.ietf.org/html/rfc3447#section-9.2 RFC3447#section-9.2}.
2708
+ *
2709
+ * @access private
2710
+ * @param String $m
2711
+ * @param Integer $emLen
2712
+ * @return String
2713
+ */
2714
+ function _emsa_pkcs1_v1_5_encode($m, $emLen)
2715
+ {
2716
+ $h = $this->hash->hash($m);
2717
+ if ($h === false) {
2718
+ return false;
2719
+ }
2720
+
2721
+ // see http://tools.ietf.org/html/rfc3447#page-43
2722
+ switch ($this->hashName) {
2723
+ case 'md2':
2724
+ $t = pack('H*', '3020300c06082a864886f70d020205000410');
2725
+ break;
2726
+ case 'md5':
2727
+ $t = pack('H*', '3020300c06082a864886f70d020505000410');
2728
+ break;
2729
+ case 'sha1':
2730
+ $t = pack('H*', '3021300906052b0e03021a05000414');
2731
+ break;
2732
+ case 'sha256':
2733
+ $t = pack('H*', '3031300d060960864801650304020105000420');
2734
+ break;
2735
+ case 'sha384':
2736
+ $t = pack('H*', '3041300d060960864801650304020205000430');
2737
+ break;
2738
+ case 'sha512':
2739
+ $t = pack('H*', '3051300d060960864801650304020305000440');
2740
+ }
2741
+ $t.= $h;
2742
+ $tLen = strlen($t);
2743
+
2744
+ if ($emLen < $tLen + 11) {
2745
+ user_error('Intended encoded message length too short');
2746
+ return false;
2747
+ }
2748
+
2749
+ $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3);
2750
+
2751
+ $em = "\0\1$ps\0$t";
2752
+
2753
+ return $em;
2754
+ }
2755
+
2756
+ /**
2757
+ * RSASSA-PKCS1-V1_5-SIGN
2758
+ *
2759
+ * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.1 RFC3447#section-8.2.1}.
2760
+ *
2761
+ * @access private
2762
+ * @param String $m
2763
+ * @return String
2764
+ */
2765
+ function _rsassa_pkcs1_v1_5_sign($m)
2766
+ {
2767
+ // EMSA-PKCS1-v1_5 encoding
2768
+
2769
+ $em = $this->_emsa_pkcs1_v1_5_encode($m, $this->k);
2770
+ if ($em === false) {
2771
+ user_error('RSA modulus too short');
2772
+ return false;
2773
+ }
2774
+
2775
+ // RSA signature
2776
+
2777
+ $m = $this->_os2ip($em);
2778
+ $s = $this->_rsasp1($m);
2779
+ $s = $this->_i2osp($s, $this->k);
2780
+
2781
+ // Output the signature S
2782
+
2783
+ return $s;
2784
+ }
2785
+
2786
+ /**
2787
+ * RSASSA-PKCS1-V1_5-VERIFY
2788
+ *
2789
+ * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.2 RFC3447#section-8.2.2}.
2790
+ *
2791
+ * @access private
2792
+ * @param String $m
2793
+ * @return String
2794
+ */
2795
+ function _rsassa_pkcs1_v1_5_verify($m, $s)
2796
+ {
2797
+ // Length checking
2798
+
2799
+ if (strlen($s) != $this->k) {
2800
+ user_error('Invalid signature');
2801
+ return false;
2802
+ }
2803
+
2804
+ // RSA verification
2805
+
2806
+ $s = $this->_os2ip($s);
2807
+ $m2 = $this->_rsavp1($s);
2808
+ if ($m2 === false) {
2809
+ user_error('Invalid signature');
2810
+ return false;
2811
+ }
2812
+ $em = $this->_i2osp($m2, $this->k);
2813
+ if ($em === false) {
2814
+ user_error('Invalid signature');
2815
+ return false;
2816
+ }
2817
+
2818
+ // EMSA-PKCS1-v1_5 encoding
2819
+
2820
+ $em2 = $this->_emsa_pkcs1_v1_5_encode($m, $this->k);
2821
+ if ($em2 === false) {
2822
+ user_error('RSA modulus too short');
2823
+ return false;
2824
+ }
2825
+
2826
+ // Compare
2827
+ return $this->_equals($em, $em2);
2828
+ }
2829
+
2830
+ /**
2831
+ * Set Encryption Mode
2832
+ *
2833
+ * Valid values include CRYPT_RSA_ENCRYPTION_OAEP and CRYPT_RSA_ENCRYPTION_PKCS1.
2834
+ *
2835
+ * @access public
2836
+ * @param Integer $mode
2837
+ */
2838
+ function setEncryptionMode($mode)
2839
+ {
2840
+ $this->encryptionMode = $mode;
2841
+ }
2842
+
2843
+ /**
2844
+ * Set Signature Mode
2845
+ *
2846
+ * Valid values include CRYPT_RSA_SIGNATURE_PSS and CRYPT_RSA_SIGNATURE_PKCS1
2847
+ *
2848
+ * @access public
2849
+ * @param Integer $mode
2850
+ */
2851
+ function setSignatureMode($mode)
2852
+ {
2853
+ $this->signatureMode = $mode;
2854
+ }
2855
+
2856
+ /**
2857
+ * Set public key comment.
2858
+ *
2859
+ * @access public
2860
+ * @param String $comment
2861
+ */
2862
+ function setComment($comment)
2863
+ {
2864
+ $this->comment = $comment;
2865
+ }
2866
+
2867
+ /**
2868
+ * Get public key comment.
2869
+ *
2870
+ * @access public
2871
+ * @return String
2872
+ */
2873
+ function getComment()
2874
+ {
2875
+ return $this->comment;
2876
+ }
2877
+
2878
+ /**
2879
+ * Encryption
2880
+ *
2881
+ * Both CRYPT_RSA_ENCRYPTION_OAEP and CRYPT_RSA_ENCRYPTION_PKCS1 both place limits on how long $plaintext can be.
2882
+ * If $plaintext exceeds those limits it will be broken up so that it does and the resultant ciphertext's will
2883
+ * be concatenated together.
2884
+ *
2885
+ * @see decrypt()
2886
+ * @access public
2887
+ * @param String $plaintext
2888
+ * @return String
2889
+ */
2890
+ function encrypt($plaintext)
2891
+ {
2892
+ switch ($this->encryptionMode) {
2893
+ case CRYPT_RSA_ENCRYPTION_PKCS1:
2894
+ $length = $this->k - 11;
2895
+ if ($length <= 0) {
2896
+ return false;
2897
+ }
2898
+
2899
+ $plaintext = str_split($plaintext, $length);
2900
+ $ciphertext = '';
2901
+ foreach ($plaintext as $m) {
2902
+ $ciphertext.= $this->_rsaes_pkcs1_v1_5_encrypt($m);
2903
+ }
2904
+ return $ciphertext;
2905
+ //case CRYPT_RSA_ENCRYPTION_OAEP:
2906
+ default:
2907
+ $length = $this->k - 2 * $this->hLen - 2;
2908
+ if ($length <= 0) {
2909
+ return false;
2910
+ }
2911
+
2912
+ $plaintext = str_split($plaintext, $length);
2913
+ $ciphertext = '';
2914
+ foreach ($plaintext as $m) {
2915
+ $ciphertext.= $this->_rsaes_oaep_encrypt($m);
2916
+ }
2917
+ return $ciphertext;
2918
+ }
2919
+ }
2920
+
2921
+ /**
2922
+ * Decryption
2923
+ *
2924
+ * @see encrypt()
2925
+ * @access public
2926
+ * @param String $plaintext
2927
+ * @return String
2928
+ */
2929
+ function decrypt($ciphertext)
2930
+ {
2931
+ if ($this->k <= 0) {
2932
+ return false;
2933
+ }
2934
+
2935
+ $ciphertext = str_split($ciphertext, $this->k);
2936
+ $ciphertext[count($ciphertext) - 1] = str_pad($ciphertext[count($ciphertext) - 1], $this->k, chr(0), STR_PAD_LEFT);
2937
+
2938
+ $plaintext = '';
2939
+
2940
+ switch ($this->encryptionMode) {
2941
+ case CRYPT_RSA_ENCRYPTION_PKCS1:
2942
+ $decrypt = '_rsaes_pkcs1_v1_5_decrypt';
2943
+ break;
2944
+ //case CRYPT_RSA_ENCRYPTION_OAEP:
2945
+ default:
2946
+ $decrypt = '_rsaes_oaep_decrypt';
2947
+ }
2948
+
2949
+ foreach ($ciphertext as $c) {
2950
+ $temp = $this->$decrypt($c);
2951
+ if ($temp === false) {
2952
+ return false;
2953
+ }
2954
+ $plaintext.= $temp;
2955
+ }
2956
+
2957
+ return $plaintext;
2958
+ }
2959
+
2960
+ /**
2961
+ * Create a signature
2962
+ *
2963
+ * @see verify()
2964
+ * @access public
2965
+ * @param String $message
2966
+ * @return String
2967
+ */
2968
+ function sign($message)
2969
+ {
2970
+ if (empty($this->modulus) || empty($this->exponent)) {
2971
+ return false;
2972
+ }
2973
+
2974
+ switch ($this->signatureMode) {
2975
+ case CRYPT_RSA_SIGNATURE_PKCS1:
2976
+ return $this->_rsassa_pkcs1_v1_5_sign($message);
2977
+ //case CRYPT_RSA_SIGNATURE_PSS:
2978
+ default:
2979
+ return $this->_rsassa_pss_sign($message);
2980
+ }
2981
+ }
2982
+
2983
+ /**
2984
+ * Verifies a signature
2985
+ *
2986
+ * @see sign()
2987
+ * @access public
2988
+ * @param String $message
2989
+ * @param String $signature
2990
+ * @return Boolean
2991
+ */
2992
+ function verify($message, $signature)
2993
+ {
2994
+ if (empty($this->modulus) || empty($this->exponent)) {
2995
+ return false;
2996
+ }
2997
+
2998
+ switch ($this->signatureMode) {
2999
+ case CRYPT_RSA_SIGNATURE_PKCS1:
3000
+ return $this->_rsassa_pkcs1_v1_5_verify($message, $signature);
3001
+ //case CRYPT_RSA_SIGNATURE_PSS:
3002
+ default:
3003
+ return $this->_rsassa_pss_verify($message, $signature);
3004
+ }
3005
+ }
3006
+
3007
+ /**
3008
+ * Extract raw BER from Base64 encoding
3009
+ *
3010
+ * @access private
3011
+ * @param String $str
3012
+ * @return String
3013
+ */
3014
+ function _extractBER($str)
3015
+ {
3016
+ /* X.509 certs are assumed to be base64 encoded but sometimes they'll have additional things in them
3017
+ * above and beyond the ceritificate.
3018
+ * ie. some may have the following preceding the -----BEGIN CERTIFICATE----- line:
3019
+ *
3020
+ * Bag Attributes
3021
+ * localKeyID: 01 00 00 00
3022
+ * subject=/O=organization/OU=org unit/CN=common name
3023
+ * issuer=/O=organization/CN=common name
3024
+ */
3025
+ $temp = preg_replace('#.*?^-+[^-]+-+#ms', '', $str, 1);
3026
+ // remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff
3027
+ $temp = preg_replace('#-+[^-]+-+#', '', $temp);
3028
+ // remove new lines
3029
+ $temp = str_replace(array("\r", "\n", ' '), '', $temp);
3030
+ $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false;
3031
+ return $temp != false ? $temp : $str;
3032
+ }
3033
+ }
phpseclib/Crypt/Random.php CHANGED
@@ -1,300 +1,300 @@
1
- <?php
2
-
3
- /**
4
- * Random Number Generator
5
- *
6
- * The idea behind this function is that it can be easily replaced with your own crypt_random_string()
7
- * function. eg. maybe you have a better source of entropy for creating the initial states or whatever.
8
- *
9
- * PHP versions 4 and 5
10
- *
11
- * Here's a short example of how to use this library:
12
- * <code>
13
- * <?php
14
- * include 'Crypt/Random.php';
15
- *
16
- * echo bin2hex(crypt_random_string(8));
17
- * ?>
18
- * </code>
19
- *
20
- * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
21
- * of this software and associated documentation files (the "Software"), to deal
22
- * in the Software without restriction, including without limitation the rights
23
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
24
- * copies of the Software, and to permit persons to whom the Software is
25
- * furnished to do so, subject to the following conditions:
26
- *
27
- * The above copyright notice and this permission notice shall be included in
28
- * all copies or substantial portions of the Software.
29
- *
30
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
33
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
34
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
35
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
36
- * THE SOFTWARE.
37
- *
38
- * @category Crypt
39
- * @package Crypt_Random
40
- * @author Jim Wigginton <terrafrost@php.net>
41
- * @copyright MMVII Jim Wigginton
42
- * @license http://www.opensource.org/licenses/mit-license.html MIT License
43
- * @link http://phpseclib.sourceforge.net
44
- */
45
-
46
- // laravel is a PHP framework that utilizes phpseclib. laravel workbenches may, independently,
47
- // have phpseclib as a requirement as well. if you're developing such a program you may encounter
48
- // a "Cannot redeclare crypt_random_string()" error.
49
- if (!function_exists('crypt_random_string')) {
50
- /**
51
- * "Is Windows" test
52
- *
53
- * @access private
54
- */
55
- define('CRYPT_RANDOM_IS_WINDOWS', strtoupper(substr(PHP_OS, 0, 3)) === 'WIN');
56
-
57
- /**
58
- * Generate a random string.
59
- *
60
- * Although microoptimizations are generally discouraged as they impair readability this function is ripe with
61
- * microoptimizations because this function has the potential of being called a huge number of times.
62
- * eg. for RSA key generation.
63
- *
64
- * @param Integer $length
65
- * @return String
66
- * @access public
67
- */
68
- function crypt_random_string($length)
69
- {
70
- if (CRYPT_RANDOM_IS_WINDOWS) {
71
- // method 1. prior to PHP 5.3 this would call rand() on windows hence the function_exists('class_alias') call.
72
- // ie. class_alias is a function that was introduced in PHP 5.3
73
- if (function_exists('mcrypt_create_iv') && function_exists('class_alias')) {
74
- return mcrypt_create_iv($length);
75
- }
76
- // method 2. openssl_random_pseudo_bytes was introduced in PHP 5.3.0 but prior to PHP 5.3.4 there was,
77
- // to quote <http://php.net/ChangeLog-5.php#5.3.4>, "possible blocking behavior". as of 5.3.4
78
- // openssl_random_pseudo_bytes and mcrypt_create_iv do the exact same thing on Windows. ie. they both
79
- // call php_win32_get_random_bytes():
80
- //
81
- // https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/openssl/openssl.c#L5008
82
- // https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/mcrypt/mcrypt.c#L1392
83
- //
84
- // php_win32_get_random_bytes() is defined thusly:
85
- //
86
- // https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/win32/winutil.c#L80
87
- //
88
- // we're calling it, all the same, in the off chance that the mcrypt extension is not available
89
- if (function_exists('openssl_random_pseudo_bytes') && version_compare(PHP_VERSION, '5.3.4', '>=')) {
90
- return openssl_random_pseudo_bytes($length);
91
- }
92
- } else {
93
- // method 1. the fastest
94
- if (function_exists('openssl_random_pseudo_bytes')) {
95
- return openssl_random_pseudo_bytes($length);
96
- }
97
- // method 2
98
- static $fp = true;
99
- if ($fp === true) {
100
- // warning's will be output unles the error suppression operator is used. errors such as
101
- // "open_basedir restriction in effect", "Permission denied", "No such file or directory", etc.
102
- $fp = @fopen('/dev/urandom', 'rb');
103
- }
104
- if ($fp !== true && $fp !== false) { // surprisingly faster than !is_bool() or is_resource()
105
- return fread($fp, $length);
106
- }
107
- // method 3. pretty much does the same thing as method 2 per the following url:
108
- // https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/mcrypt/mcrypt.c#L1391
109
- // surprisingly slower than method 2. maybe that's because mcrypt_create_iv does a bunch of error checking that we're
110
- // not doing. regardless, this'll only be called if this PHP script couldn't open /dev/urandom due to open_basedir
111
- // restrictions or some such
112
- if (function_exists('mcrypt_create_iv')) {
113
- return mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
114
- }
115
- }
116
- // at this point we have no choice but to use a pure-PHP CSPRNG
117
-
118
- // cascade entropy across multiple PHP instances by fixing the session and collecting all
119
- // environmental variables, including the previous session data and the current session
120
- // data.
121
- //
122
- // mt_rand seeds itself by looking at the PID and the time, both of which are (relatively)
123
- // easy to guess at. linux uses mouse clicks, keyboard timings, etc, as entropy sources, but
124
- // PHP isn't low level to be able to use those as sources and on a web server there's not likely
125
- // going to be a ton of keyboard or mouse action. web servers do have one thing that we can use
126
- // however, a ton of people visiting the website. obviously you don't want to base your seeding
127
- // soley on parameters a potential attacker sends but (1) not everything in $_SERVER is controlled
128
- // by the user and (2) this isn't just looking at the data sent by the current user - it's based
129
- // on the data sent by all users. one user requests the page and a hash of their info is saved.
130
- // another user visits the page and the serialization of their data is utilized along with the
131
- // server envirnment stuff and a hash of the previous http request data (which itself utilizes
132
- // a hash of the session data before that). certainly an attacker should be assumed to have
133
- // full control over his own http requests. he, however, is not going to have control over
134
- // everyone's http requests.
135
- static $crypto = false, $v;
136
- if ($crypto === false) {
137
- // save old session data
138
- $old_session_id = session_id();
139
- $old_use_cookies = ini_get('session.use_cookies');
140
- $old_session_cache_limiter = session_cache_limiter();
141
- $_OLD_SESSION = isset($_SESSION) ? $_SESSION : false;
142
- if ($old_session_id != '') {
143
- session_write_close();
144
- }
145
-
146
- session_id(1);
147
- ini_set('session.use_cookies', 0);
148
- session_cache_limiter('');
149
- session_start();
150
-
151
- $v = $seed = $_SESSION['seed'] = pack('H*', sha1(
152
- serialize($_SERVER) .
153
- serialize($_POST) .
154
- serialize($_GET) .
155
- serialize($_COOKIE) .
156
- serialize($GLOBALS) .
157
- serialize($_SESSION) .
158
- serialize($_OLD_SESSION)
159
- ));
160
- if (!isset($_SESSION['count'])) {
161
- $_SESSION['count'] = 0;
162
- }
163
- $_SESSION['count']++;
164
-
165
- session_write_close();
166
-
167
- // restore old session data
168
- if ($old_session_id != '') {
169
- session_id($old_session_id);
170
- session_start();
171
- ini_set('session.use_cookies', $old_use_cookies);
172
- session_cache_limiter($old_session_cache_limiter);
173
- } else {
174
- if ($_OLD_SESSION !== false) {
175
- $_SESSION = $_OLD_SESSION;
176
- unset($_OLD_SESSION);
177
- } else {
178
- unset($_SESSION);
179
- }
180
- }
181
-
182
- // in SSH2 a shared secret and an exchange hash are generated through the key exchange process.
183
- // the IV client to server is the hash of that "nonce" with the letter A and for the encryption key it's the letter C.
184
- // if the hash doesn't produce enough a key or an IV that's long enough concat successive hashes of the
185
- // original hash and the current hash. we'll be emulating that. for more info see the following URL:
186
- //
187
- // http://tools.ietf.org/html/rfc4253#section-7.2
188
- //
189
- // see the is_string($crypto) part for an example of how to expand the keys
190
- $key = pack('H*', sha1($seed . 'A'));
191
- $iv = pack('H*', sha1($seed . 'C'));
192
-
193
- // ciphers are used as per the nist.gov link below. also, see this link:
194
- //
195
- // http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator#Designs_based_on_cryptographic_primitives
196
- switch (true) {
197
- case phpseclib_resolve_include_path('Crypt/AES.php'):
198
- if (!class_exists('Crypt_AES')) {
199
- include_once 'AES.php';
200
- }
201
- $crypto = new Crypt_AES(CRYPT_AES_MODE_CTR);
202
- break;
203
- case phpseclib_resolve_include_path('Crypt/Twofish.php'):
204
- if (!class_exists('Crypt_Twofish')) {
205
- include_once 'Twofish.php';
206
- }
207
- $crypto = new Crypt_Twofish(CRYPT_TWOFISH_MODE_CTR);
208
- break;
209
- case phpseclib_resolve_include_path('Crypt/Blowfish.php'):
210
- if (!class_exists('Crypt_Blowfish')) {
211
- include_once 'Blowfish.php';
212
- }
213
- $crypto = new Crypt_Blowfish(CRYPT_BLOWFISH_MODE_CTR);
214
- break;
215
- case phpseclib_resolve_include_path('Crypt/TripleDES.php'):
216
- if (!class_exists('Crypt_TripleDES')) {
217
- include_once 'TripleDES.php';
218
- }
219
- $crypto = new Crypt_TripleDES(CRYPT_DES_MODE_CTR);
220
- break;
221
- case phpseclib_resolve_include_path('Crypt/DES.php'):
222
- if (!class_exists('Crypt_DES')) {
223
- include_once 'DES.php';
224
- }
225
- $crypto = new Crypt_DES(CRYPT_DES_MODE_CTR);
226
- break;
227
- case phpseclib_resolve_include_path('Crypt/RC4.php'):
228
- if (!class_exists('Crypt_RC4')) {
229
- include_once 'RC4.php';
230
- }
231
- $crypto = new Crypt_RC4();
232
- break;
233
- default:
234
- user_error('crypt_random_string requires at least one symmetric cipher be loaded');
235
- return false;
236
- }
237
-
238
- $crypto->setKey($key);
239
- $crypto->setIV($iv);
240
- $crypto->enableContinuousBuffer();
241
- }
242
-
243
- //return $crypto->encrypt(str_repeat("\0", $length));
244
-
245
- // the following is based off of ANSI X9.31:
246
- //
247
- // http://csrc.nist.gov/groups/STM/cavp/documents/rng/931rngext.pdf
248
- //
249
- // OpenSSL uses that same standard for it's random numbers:
250
- //
251
- // http://www.opensource.apple.com/source/OpenSSL/OpenSSL-38/openssl/fips-1.0/rand/fips_rand.c
252
- // (do a search for "ANS X9.31 A.2.4")
253
- $result = '';
254
- while (strlen($result) < $length) {
255
- $i = $crypto->encrypt(microtime()); // strlen(microtime()) == 21
256
- $r = $crypto->encrypt($i ^ $v); // strlen($v) == 20
257
- $v = $crypto->encrypt($r ^ $i); // strlen($r) == 20
258
- $result.= $r;
259
- }
260
- return substr($result, 0, $length);
261
- }
262
- }
263
-
264
- if (!function_exists('phpseclib_resolve_include_path')) {
265
- /**
266
- * Resolve filename against the include path.
267
- *
268
- * Wrapper around stream_resolve_include_path() (which was introduced in
269
- * PHP 5.3.2) with fallback implementation for earlier PHP versions.
270
- *
271
- * @param string $filename
272
- * @return mixed Filename (string) on success, false otherwise.
273
- * @access public
274
- */
275
- function phpseclib_resolve_include_path($filename)
276
- {
277
- if (function_exists('stream_resolve_include_path')) {
278
- return stream_resolve_include_path($filename);
279
- }
280
-
281
- // handle non-relative paths
282
- if (file_exists($filename)) {
283
- return realpath($filename);
284
- }
285
-
286
- $paths = PATH_SEPARATOR == ':' ?
287
- preg_split('#(?<!phar):#', get_include_path()) :
288
- explode(PATH_SEPARATOR, get_include_path());
289
- foreach ($paths as $prefix) {
290
- // path's specified in include_path don't always end in /
291
- $ds = substr($prefix, -1) == DIRECTORY_SEPARATOR ? '' : DIRECTORY_SEPARATOR;
292
- $file = $prefix . $ds . $filename;
293
- if (file_exists($file)) {
294
- return realpath($file);
295
- }
296
- }
297
-
298
- return false;
299
- }
300
- }
1
+ <?php
2
+
3
+ /**
4
+ * Random Number Generator
5
+ *
6
+ * The idea behind this function is that it can be easily replaced with your own crypt_random_string()
7
+ * function. eg. maybe you have a better source of entropy for creating the initial states or whatever.
8
+ *
9
+ * PHP versions 4 and 5
10
+ *
11
+ * Here's a short example of how to use this library:
12
+ * <code>
13
+ * <?php
14
+ * include 'Crypt/Random.php';
15
+ *
16
+ * echo bin2hex(crypt_random_string(8));
17
+ * ?>
18
+ * </code>
19
+ *
20
+ * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
21
+ * of this software and associated documentation files (the "Software"), to deal
22
+ * in the Software without restriction, including without limitation the rights
23
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
24
+ * copies of the Software, and to permit persons to whom the Software is
25
+ * furnished to do so, subject to the following conditions:
26
+ *
27
+ * The above copyright notice and this permission notice shall be included in
28
+ * all copies or substantial portions of the Software.
29
+ *
30
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
33
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
34
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
35
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
36
+ * THE SOFTWARE.
37
+ *
38
+ * @category Crypt
39
+ * @package Crypt_Random
40
+ * @author Jim Wigginton <terrafrost@php.net>
41
+ * @copyright 2007 Jim Wigginton
42
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
43
+ * @link http://phpseclib.sourceforge.net
44
+ */
45
+
46
+ // laravel is a PHP framework that utilizes phpseclib. laravel workbenches may, independently,
47
+ // have phpseclib as a requirement as well. if you're developing such a program you may encounter
48
+ // a "Cannot redeclare crypt_random_string()" error.
49
+ if (!function_exists('crypt_random_string')) {
50
+ /**
51
+ * "Is Windows" test
52
+ *
53
+ * @access private
54
+ */
55
+ define('CRYPT_RANDOM_IS_WINDOWS', strtoupper(substr(PHP_OS, 0, 3)) === 'WIN');
56
+
57
+ /**
58
+ * Generate a random string.
59
+ *
60
+ * Although microoptimizations are generally discouraged as they impair readability this function is ripe with
61
+ * microoptimizations because this function has the potential of being called a huge number of times.
62
+ * eg. for RSA key generation.
63
+ *
64
+ * @param Integer $length
65
+ * @return String
66
+ * @access public
67
+ */
68
+ function crypt_random_string($length)
69
+ {
70
+ if (CRYPT_RANDOM_IS_WINDOWS) {
71
+ // method 1. prior to PHP 5.3 this would call rand() on windows hence the function_exists('class_alias') call.
72
+ // ie. class_alias is a function that was introduced in PHP 5.3
73
+ if (function_exists('mcrypt_create_iv') && function_exists('class_alias')) {
74
+ return mcrypt_create_iv($length);
75
+ }
76
+ // method 2. openssl_random_pseudo_bytes was introduced in PHP 5.3.0 but prior to PHP 5.3.4 there was,
77
+ // to quote <http://php.net/ChangeLog-5.php#5.3.4>, "possible blocking behavior". as of 5.3.4
78
+ // openssl_random_pseudo_bytes and mcrypt_create_iv do the exact same thing on Windows. ie. they both
79
+ // call php_win32_get_random_bytes():
80
+ //
81
+ // https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/openssl/openssl.c#L5008
82
+ // https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/mcrypt/mcrypt.c#L1392
83
+ //
84
+ // php_win32_get_random_bytes() is defined thusly:
85
+ //
86
+ // https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/win32/winutil.c#L80
87
+ //
88
+ // we're calling it, all the same, in the off chance that the mcrypt extension is not available
89
+ if (function_exists('openssl_random_pseudo_bytes') && version_compare(PHP_VERSION, '5.3.4', '>=')) {
90
+ return openssl_random_pseudo_bytes($length);
91
+ }
92
+ } else {
93
+ // method 1. the fastest
94
+ if (function_exists('openssl_random_pseudo_bytes')) {
95
+ return openssl_random_pseudo_bytes($length);
96
+ }
97
+ // method 2
98
+ static $fp = true;
99
+ if ($fp === true) {
100
+ // warning's will be output unles the error suppression operator is used. errors such as
101
+ // "open_basedir restriction in effect", "Permission denied", "No such file or directory", etc.
102
+ $fp = @fopen('/dev/urandom', 'rb');
103
+ }
104
+ if ($fp !== true && $fp !== false) { // surprisingly faster than !is_bool() or is_resource()
105
+ return fread($fp, $length);
106
+ }
107
+ // method 3. pretty much does the same thing as method 2 per the following url:
108
+ // https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/mcrypt/mcrypt.c#L1391
109
+ // surprisingly slower than method 2. maybe that's because mcrypt_create_iv does a bunch of error checking that we're
110
+ // not doing. regardless, this'll only be called if this PHP script couldn't open /dev/urandom due to open_basedir
111
+ // restrictions or some such
112
+ if (function_exists('mcrypt_create_iv')) {
113
+ return mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
114
+ }
115
+ }
116
+ // at this point we have no choice but to use a pure-PHP CSPRNG
117
+
118
+ // cascade entropy across multiple PHP instances by fixing the session and collecting all
119
+ // environmental variables, including the previous session data and the current session
120
+ // data.
121
+ //
122
+ // mt_rand seeds itself by looking at the PID and the time, both of which are (relatively)
123
+ // easy to guess at. linux uses mouse clicks, keyboard timings, etc, as entropy sources, but
124
+ // PHP isn't low level to be able to use those as sources and on a web server there's not likely
125
+ // going to be a ton of keyboard or mouse action. web servers do have one thing that we can use
126
+ // however, a ton of people visiting the website. obviously you don't want to base your seeding
127
+ // soley on parameters a potential attacker sends but (1) not everything in $_SERVER is controlled
128
+ // by the user and (2) this isn't just looking at the data sent by the current user - it's based
129
+ // on the data sent by all users. one user requests the page and a hash of their info is saved.
130
+ // another user visits the page and the serialization of their data is utilized along with the
131
+ // server envirnment stuff and a hash of the previous http request data (which itself utilizes
132
+ // a hash of the session data before that). certainly an attacker should be assumed to have
133
+ // full control over his own http requests. he, however, is not going to have control over
134
+ // everyone's http requests.
135
+ static $crypto = false, $v;
136
+ if ($crypto === false) {
137
+ // save old session data
138
+ $old_session_id = session_id();
139
+ $old_use_cookies = ini_get('session.use_cookies');
140
+ $old_session_cache_limiter = session_cache_limiter();
141
+ $_OLD_SESSION = isset($_SESSION) ? $_SESSION : false;
142
+ if ($old_session_id != '') {
143
+ session_write_close();
144
+ }
145
+
146
+ session_id(1);
147
+ ini_set('session.use_cookies', 0);
148
+ session_cache_limiter('');
149
+ session_start();
150
+
151
+ $v = $seed = $_SESSION['seed'] = pack('H*', sha1(
152
+ serialize($_SERVER) .
153
+ serialize($_POST) .
154
+ serialize($_GET) .
155
+ serialize($_COOKIE) .
156
+ serialize($GLOBALS) .
157
+ serialize($_SESSION) .
158
+ serialize($_OLD_SESSION)
159
+ ));
160
+ if (!isset($_SESSION['count'])) {
161
+ $_SESSION['count'] = 0;
162
+ }
163
+ $_SESSION['count']++;
164
+
165
+ session_write_close();
166
+
167
+ // restore old session data
168
+ if ($old_session_id != '') {
169
+ session_id($old_session_id);
170
+ session_start();
171
+ ini_set('session.use_cookies', $old_use_cookies);
172
+ session_cache_limiter($old_session_cache_limiter);
173
+ } else {
174
+ if ($_OLD_SESSION !== false) {
175
+ $_SESSION = $_OLD_SESSION;
176
+ unset($_OLD_SESSION);
177
+ } else {
178
+ unset($_SESSION);
179
+ }
180
+ }
181
+
182
+ // in SSH2 a shared secret and an exchange hash are generated through the key exchange process.
183
+ // the IV client to server is the hash of that "nonce" with the letter A and for the encryption key it's the letter C.
184
+ // if the hash doesn't produce enough a key or an IV that's long enough concat successive hashes of the
185
+ // original hash and the current hash. we'll be emulating that. for more info see the following URL:
186
+ //
187
+ // http://tools.ietf.org/html/rfc4253#section-7.2
188
+ //
189
+ // see the is_string($crypto) part for an example of how to expand the keys
190
+ $key = pack('H*', sha1($seed . 'A'));
191
+ $iv = pack('H*', sha1($seed . 'C'));
192
+
193
+ // ciphers are used as per the nist.gov link below. also, see this link:
194
+ //
195
+ // http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator#Designs_based_on_cryptographic_primitives
196
+ switch (true) {
197
+ case phpseclib_resolve_include_path('Crypt/AES.php'):
198
+ if (!class_exists('Crypt_AES')) {
199
+ include_once 'AES.php';
200
+ }
201
+ $crypto = new Crypt_AES(CRYPT_AES_MODE_CTR);
202
+ break;
203
+ case phpseclib_resolve_include_path('Crypt/Twofish.php'):
204
+ if (!class_exists('Crypt_Twofish')) {
205
+ include_once 'Twofish.php';
206
+ }
207
+ $crypto = new Crypt_Twofish(CRYPT_TWOFISH_MODE_CTR);
208
+ break;
209
+ case phpseclib_resolve_include_path('Crypt/Blowfish.php'):
210
+ if (!class_exists('Crypt_Blowfish')) {
211
+ include_once 'Blowfish.php';
212
+ }
213
+ $crypto = new Crypt_Blowfish(CRYPT_BLOWFISH_MODE_CTR);
214
+ break;
215
+ case phpseclib_resolve_include_path('Crypt/TripleDES.php'):
216
+ if (!class_exists('Crypt_TripleDES')) {
217
+ include_once 'TripleDES.php';
218
+ }
219
+ $crypto = new Crypt_TripleDES(CRYPT_DES_MODE_CTR);
220
+ break;
221
+ case phpseclib_resolve_include_path('Crypt/DES.php'):
222
+ if (!class_exists('Crypt_DES')) {
223
+ include_once 'DES.php';
224
+ }
225
+ $crypto = new Crypt_DES(CRYPT_DES_MODE_CTR);
226
+ break;
227
+ case phpseclib_resolve_include_path('Crypt/RC4.php'):
228
+ if (!class_exists('Crypt_RC4')) {
229
+ include_once 'RC4.php';
230
+ }
231
+ $crypto = new Crypt_RC4();
232
+ break;
233
+ default:
234
+ user_error('crypt_random_string requires at least one symmetric cipher be loaded');
235
+ return false;
236
+ }
237
+
238
+ $crypto->setKey($key);
239
+ $crypto->setIV($iv);
240
+ $crypto->enableContinuousBuffer();
241
+ }
242
+
243
+ //return $crypto->encrypt(str_repeat("\0", $length));
244
+
245
+ // the following is based off of ANSI X9.31:
246
+ //
247
+ // http://csrc.nist.gov/groups/STM/cavp/documents/rng/931rngext.pdf
248
+ //
249
+ // OpenSSL uses that same standard for it's random numbers:
250
+ //
251
+ // http://www.opensource.apple.com/source/OpenSSL/OpenSSL-38/openssl/fips-1.0/rand/fips_rand.c
252
+ // (do a search for "ANS X9.31 A.2.4")
253
+ $result = '';
254
+ while (strlen($result) < $length) {
255
+ $i = $crypto->encrypt(microtime()); // strlen(microtime()) == 21
256
+ $r = $crypto->encrypt($i ^ $v); // strlen($v) == 20
257
+ $v = $crypto->encrypt($r ^ $i); // strlen($r) == 20
258
+ $result.= $r;
259
+ }
260
+ return substr($result, 0, $length);
261
+ }
262
+ }
263
+
264
+ if (!function_exists('phpseclib_resolve_include_path')) {
265
+ /**
266
+ * Resolve filename against the include path.
267
+ *
268
+ * Wrapper around stream_resolve_include_path() (which was introduced in
269
+ * PHP 5.3.2) with fallback implementation for earlier PHP versions.
270
+ *
271
+ * @param string $filename
272
+ * @return mixed Filename (string) on success, false otherwise.
273
+ * @access public
274
+ */
275
+ function phpseclib_resolve_include_path($filename)
276
+ {
277
+ if (function_exists('stream_resolve_include_path')) {
278
+ return stream_resolve_include_path($filename);
279
+ }
280
+
281
+ // handle non-relative paths
282
+ if (file_exists($filename)) {
283
+ return realpath($filename);
284
+ }
285
+
286
+ $paths = PATH_SEPARATOR == ':' ?
287
+ preg_split('#(?<!phar):#', get_include_path()) :
288
+ explode(PATH_SEPARATOR, get_include_path());
289
+ foreach ($paths as $prefix) {
290
+ // path's specified in include_path don't always end in /
291
+ $ds = substr($prefix, -1) == DIRECTORY_SEPARATOR ? '' : DIRECTORY_SEPARATOR;
292
+ $file = $prefix . $ds . $filename;
293
+ if (file_exists($file)) {
294
+ return realpath($file);
295
+ }
296
+ }
297
+
298
+ return false;
299
+ }
300
+ }
phpseclib/Crypt/Rijndael.php CHANGED
@@ -1,1348 +1,1113 @@
1
- <?php
2
-
3
- /**
4
- * Pure-PHP implementation of Rijndael.
5
- *
6
- * Uses mcrypt, if available/possible, and an internal implementation, otherwise.
7
- *
8
- * PHP versions 4 and 5
9
- *
10
- * If {@link Crypt_Rijndael::setBlockLength() setBlockLength()} isn't called, it'll be assumed to be 128 bits. If
11
- * {@link Crypt_Rijndael::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
12
- * {@link Crypt_Rijndael::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's
13
- * 136-bits it'll be null-padded to 192-bits and 192 bits will be the key length until
14
- * {@link Crypt_Rijndael::setKey() setKey()} is called, again, at which point, it'll be recalculated.
15
- *
16
- * Not all Rijndael implementations may support 160-bits or 224-bits as the block length / key length. mcrypt, for example,
17
- * does not. AES, itself, only supports block lengths of 128 and key lengths of 128, 192, and 256.
18
- * {@link http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=10 Rijndael-ammended.pdf#page=10} defines the
19
- * algorithm for block lengths of 192 and 256 but not for block lengths / key lengths of 160 and 224. Indeed, 160 and 224
20
- * are first defined as valid key / block lengths in
21
- * {@link http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=44 Rijndael-ammended.pdf#page=44}:
22
- * Extensions: Other block and Cipher Key lengths.
23
- * Note: Use of 160/224-bit Keys must be explicitly set by setKeyLength(160) respectively setKeyLength(224).
24
- *
25
- * {@internal The variable names are the same as those in
26
- * {@link http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf#page=10 fips-197.pdf#page=10}.}}
27
- *
28
- * Here's a short example of how to use this library:
29
- * <code>
30
- * <?php
31
- * include 'Crypt/Rijndael.php';
32
- *
33
- * $rijndael = new Crypt_Rijndael();
34
- *
35
- * $rijndael->setKey('abcdefghijklmnop');
36
- *
37
- * $size = 10 * 1024;
38
- * $plaintext = '';
39
- * for ($i = 0; $i < $size; $i++) {
40
- * $plaintext.= 'a';
41
- * }
42
- *
43
- * echo $rijndael->decrypt($rijndael->encrypt($plaintext));
44
- * ?>
45
- * </code>
46
- *
47
- * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
48
- * of this software and associated documentation files (the "Software"), to deal
49
- * in the Software without restriction, including without limitation the rights
50
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
51
- * copies of the Software, and to permit persons to whom the Software is
52
- * furnished to do so, subject to the following conditions:
53
- *
54
- * The above copyright notice and this permission notice shall be included in
55
- * all copies or substantial portions of the Software.
56
- *
57
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
58
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
59
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
60
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
61
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
62
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
63
- * THE SOFTWARE.
64
- *
65
- * @category Crypt
66
- * @package Crypt_Rijndael
67
- * @author Jim Wigginton <terrafrost@php.net>
68
- * @copyright MMVIII Jim Wigginton
69
- * @license http://www.opensource.org/licenses/mit-license.html MIT License
70
- * @link http://phpseclib.sourceforge.net
71
- */
72
-
73
- /**
74
- * Include Crypt_Base
75
- *
76
- * Base cipher class
77
- */
78
- if (!class_exists('Crypt_Base')) {
79
- include_once 'Base.php';
80
- }
81
-
82
- /**#@+
83
- * @access public
84
- * @see Crypt_Rijndael::encrypt()
85
- * @see Crypt_Rijndael::decrypt()
86
- */
87
- /**
88
- * Encrypt / decrypt using the Counter mode.
89
- *
90
- * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
91
- *
92
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
93
- */
94
- define('CRYPT_RIJNDAEL_MODE_CTR', CRYPT_MODE_CTR);
95
- /**
96
- * Encrypt / decrypt using the Electronic Code Book mode.
97
- *
98
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
99
- */
100
- define('CRYPT_RIJNDAEL_MODE_ECB', CRYPT_MODE_ECB);
101
- /**
102
- * Encrypt / decrypt using the Code Book Chaining mode.
103
- *
104
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
105
- */
106
- define('CRYPT_RIJNDAEL_MODE_CBC', CRYPT_MODE_CBC);
107
- /**
108
- * Encrypt / decrypt using the Cipher Feedback mode.
109
- *
110
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
111
- */
112
- define('CRYPT_RIJNDAEL_MODE_CFB', CRYPT_MODE_CFB);
113
- /**
114
- * Encrypt / decrypt using the Cipher Feedback mode.
115
- *
116
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
117
- */
118
- define('CRYPT_RIJNDAEL_MODE_OFB', CRYPT_MODE_OFB);
119
- /**#@-*/
120
-
121
- /**#@+
122
- * @access private
123
- * @see Crypt_Base::Crypt_Base()
124
- */
125
- /**
126
- * Toggles the internal implementation
127
- */
128
- define('CRYPT_RIJNDAEL_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
129
- /**
130
- * Toggles the mcrypt implementation
131
- */
132
- define('CRYPT_RIJNDAEL_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
133
- /**#@-*/
134
-
135
- /**
136
- * Pure-PHP implementation of Rijndael.
137
- *
138
- * @package Crypt_Rijndael
139
- * @author Jim Wigginton <terrafrost@php.net>
140
- * @access public
141
- */
142
- class Crypt_Rijndael extends Crypt_Base
143
- {
144
- /**
145
- * The default password key_size used by setPassword()
146
- *
147
- * @see Crypt_Base::password_key_size
148
- * @see Crypt_Base::setPassword()
149
- * @var Integer
150
- * @access private
151
- */
152
- var $password_key_size = 16;
153
-
154
- /**
155
- * The namespace used by the cipher for its constants.
156
- *
157
- * @see Crypt_Base::const_namespace
158
- * @var String
159
- * @access private
160
- */
161
- var $const_namespace = 'RIJNDAEL';
162
-
163
- /**
164
- * The mcrypt specific name of the cipher
165
- *
166
- * Mcrypt is useable for 128/192/256-bit $block_size/$key_size. For 160/224 not.
167
- * Crypt_Rijndael determines automatically whether mcrypt is useable
168
- * or not for the current $block_size/$key_size.
169
- * In case of, $cipher_name_mcrypt will be set dynamically at run time accordingly.
170
- *
171
- * @see Crypt_Base::cipher_name_mcrypt
172
- * @see Crypt_Base::engine
173
- * @see _setupEngine()
174
- * @var String
175
- * @access private
176
- */
177
- var $cipher_name_mcrypt = 'rijndael-128';
178
-
179
- /**
180
- * The default salt used by setPassword()
181
- *
182
- * @see Crypt_Base::password_default_salt
183
- * @see Crypt_Base::setPassword()
184
- * @var String
185
- * @access private
186
- */
187
- var $password_default_salt = 'phpseclib';
188
-
189
- /**
190
- * Has the key length explicitly been set or should it be derived from the key, itself?
191
- *
192
- * @see setKeyLength()
193
- * @var Boolean
194
- * @access private
195
- */
196
- var $explicit_key_length = false;
197
-
198
- /**
199
- * The Key Schedule
200
- *
201
- * @see _setup()
202
- * @var Array
203
- * @access private
204
- */
205
- var $w;
206
-
207
- /**
208
- * The Inverse Key Schedule
209
- *
210
- * @see _setup()
211
- * @var Array
212
- * @access private
213
- */
214
- var $dw;
215
-
216
- /**
217
- * The Block Length divided by 32
218
- *
219
- * @see setBlockLength()
220
- * @var Integer
221
- * @access private
222
- * @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4. Exists in conjunction with $block_size
223
- * because the encryption / decryption / key schedule creation requires this number and not $block_size. We could
224
- * derive this from $block_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
225
- * of that, we'll just precompute it once.
226
- *
227
- */
228
- var $Nb = 4;
229
-
230
- /**
231
- * The Key Length
232
- *
233
- * @see setKeyLength()
234
- * @var Integer
235
- * @access private
236
- * @internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk
237
- * because the encryption / decryption / key schedule creation requires this number and not $key_size. We could
238
- * derive this from $key_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
239
- * of that, we'll just precompute it once.
240
- */
241
- var $key_size = 16;
242
-
243
- /**
244
- * The Key Length divided by 32
245
- *
246
- * @see setKeyLength()
247
- * @var Integer
248
- * @access private
249
- * @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4
250
- */
251
- var $Nk = 4;
252
-
253
- /**
254
- * The Number of Rounds
255
- *
256
- * @var Integer
257
- * @access private
258
- * @internal The max value is 14, the min value is 10.
259
- */
260
- var $Nr;
261
-
262
- /**
263
- * Shift offsets
264
- *
265
- * @var Array
266
- * @access private
267
- */
268
- var $c;
269
-
270
- /**
271
- * Holds the last used key- and block_size information
272
- *
273
- * @var Array
274
- * @access private
275
- */
276
- var $kl;
277
-
278
- /**
279
- * Precomputed mixColumns table
280
- *
281
- * According to <http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=19> (section 5.2.1),
282
- * precomputed tables can be used in the mixColumns phase. in that example, they're assigned t0...t3, so
283
- * those are the names we'll use.
284
- *
285
- * @see Crypt_Rijndael:_encryptBlock()
286
- * @see Crypt_Rijndael:_decryptBlock()
287
- * @var Array
288
- * @access private
289
- */
290
- var $t0 = array(
291
- 0xC66363A5, 0xF87C7C84, 0xEE777799, 0xF67B7B8D, 0xFFF2F20D, 0xD66B6BBD, 0xDE6F6FB1, 0x91C5C554,
292
- 0x60303050, 0x02010103, 0xCE6767A9, 0x562B2B7D, 0xE7FEFE19, 0xB5D7D762, 0x4DABABE6, 0xEC76769A,
293
- 0x8FCACA45, 0x1F82829D, 0x89C9C940, 0xFA7D7D87, 0xEFFAFA15, 0xB25959EB, 0x8E4747C9, 0xFBF0F00B,
294
- 0x41ADADEC, 0xB3D4D467, 0x5FA2A2FD, 0x45AFAFEA, 0x239C9CBF, 0x53A4A4F7, 0xE4727296, 0x9BC0C05B,
295
- 0x75B7B7C2, 0xE1FDFD1C, 0x3D9393AE, 0x4C26266A, 0x6C36365A, 0x7E3F3F41, 0xF5F7F702, 0x83CCCC4F,
296
- 0x6834345C, 0x51A5A5F4, 0xD1E5E534, 0xF9F1F108, 0xE2717193, 0xABD8D873, 0x62313153, 0x2A15153F,
297
- 0x0804040C, 0x95C7C752, 0x46232365, 0x9DC3C35E, 0x30181828, 0x379696A1, 0x0A05050F, 0x2F9A9AB5,
298
- 0x0E070709, 0x24121236, 0x1B80809B, 0xDFE2E23D, 0xCDEBEB26, 0x4E272769, 0x7FB2B2CD, 0xEA75759F,
299
- 0x1209091B, 0x1D83839E, 0x582C2C74, 0x341A1A2E, 0x361B1B2D, 0xDC6E6EB2, 0xB45A5AEE, 0x5BA0A0FB,
300
- 0xA45252F6, 0x763B3B4D, 0xB7D6D661, 0x7DB3B3CE, 0x5229297B, 0xDDE3E33E, 0x5E2F2F71, 0x13848497,
301
- 0xA65353F5, 0xB9D1D168, 0x00000000, 0xC1EDED2C, 0x40202060, 0xE3FCFC1F, 0x79B1B1C8, 0xB65B5BED,
302
- 0xD46A6ABE, 0x8DCBCB46, 0x67BEBED9, 0x7239394B, 0x944A4ADE, 0x984C4CD4, 0xB05858E8, 0x85CFCF4A,
303
- 0xBBD0D06B, 0xC5EFEF2A, 0x4FAAAAE5, 0xEDFBFB16, 0x864343C5, 0x9A4D4DD7, 0x66333355, 0x11858594,
304
- 0x8A4545CF, 0xE9F9F910, 0x04020206, 0xFE7F7F81, 0xA05050F0, 0x783C3C44, 0x259F9FBA, 0x4BA8A8E3,
305
- 0xA25151F3, 0x5DA3A3FE, 0x804040C0, 0x058F8F8A, 0x3F9292AD, 0x219D9DBC, 0x70383848, 0xF1F5F504,
306
- 0x63BCBCDF, 0x77B6B6C1, 0xAFDADA75, 0x42212163, 0x20101030, 0xE5FFFF1A, 0xFDF3F30E, 0xBFD2D26D,
307
- 0x81CDCD4C, 0x180C0C14, 0x26131335, 0xC3ECEC2F, 0xBE5F5FE1, 0x359797A2, 0x884444CC, 0x2E171739,
308
- 0x93C4C457, 0x55A7A7F2, 0xFC7E7E82, 0x7A3D3D47, 0xC86464AC, 0xBA5D5DE7, 0x3219192B, 0xE6737395,
309
- 0xC06060A0, 0x19818198, 0x9E4F4FD1, 0xA3DCDC7F, 0x44222266, 0x542A2A7E, 0x3B9090AB, 0x0B888883,
310
- 0x8C4646CA, 0xC7EEEE29, 0x6BB8B8D3, 0x2814143C, 0xA7DEDE79, 0xBC5E5EE2, 0x160B0B1D, 0xADDBDB76,
311
- 0xDBE0E03B, 0x64323256, 0x743A3A4E, 0x140A0A1E, 0x924949DB, 0x0C06060A, 0x4824246C, 0xB85C5CE4,
312
- 0x9FC2C25D, 0xBDD3D36E, 0x43ACACEF, 0xC46262A6, 0x399191A8, 0x319595A4, 0xD3E4E437, 0xF279798B,
313
- 0xD5E7E732, 0x8BC8C843, 0x6E373759, 0xDA6D6DB7, 0x018D8D8C, 0xB1D5D564, 0x9C4E4ED2, 0x49A9A9E0,
314
- 0xD86C6CB4, 0xAC5656FA, 0xF3F4F407, 0xCFEAEA25, 0xCA6565AF, 0xF47A7A8E, 0x47AEAEE9, 0x10080818,
315
- 0x6FBABAD5, 0xF0787888, 0x4A25256F, 0x5C2E2E72, 0x381C1C24, 0x57A6A6F1, 0x73B4B4C7, 0x97C6C651,
316
- 0xCBE8E823, 0xA1DDDD7C, 0xE874749C, 0x3E1F1F21, 0x964B4BDD, 0x61BDBDDC, 0x0D8B8B86, 0x0F8A8A85,
317
- 0xE0707090, 0x7C3E3E42, 0x71B5B5C4, 0xCC6666AA, 0x904848D8, 0x06030305, 0xF7F6F601, 0x1C0E0E12,
318
- 0xC26161A3, 0x6A35355F, 0xAE5757F9, 0x69B9B9D0, 0x17868691, 0x99C1C158, 0x3A1D1D27, 0x279E9EB9,
319
- 0xD9E1E138, 0xEBF8F813, 0x2B9898B3, 0x22111133, 0xD26969BB, 0xA9D9D970, 0x078E8E89, 0x339494A7,
320
- 0x2D9B9BB6, 0x3C1E1E22, 0x15878792, 0xC9E9E920, 0x87CECE49, 0xAA5555FF, 0x50282878, 0xA5DFDF7A,
321
- 0x038C8C8F, 0x59A1A1F8, 0x09898980, 0x1A0D0D17, 0x65BFBFDA, 0xD7E6E631, 0x844242C6, 0xD06868B8,
322
- 0x824141C3, 0x299999B0, 0x5A2D2D77, 0x1E0F0F11, 0x7BB0B0CB, 0xA85454FC, 0x6DBBBBD6, 0x2C16163A
323
- );
324
-
325
- /**
326
- * Precomputed mixColumns table
327
- *
328
- * @see Crypt_Rijndael:_encryptBlock()
329
- * @see Crypt_Rijndael:_decryptBlock()
330
- * @var Array
331
- * @access private
332
- */
333
- var $t1 = array(
334
- 0xA5C66363, 0x84F87C7C, 0x99EE7777, 0x8DF67B7B, 0x0DFFF2F2, 0xBDD66B6B, 0xB1DE6F6F, 0x5491C5C5,
335
- 0x50603030, 0x03020101, 0xA9CE6767, 0x7D562B2B, 0x19E7FEFE, 0x62B5D7D7, 0xE64DABAB, 0x9AEC7676,
336
- 0x458FCACA, 0x9D1F8282, 0x4089C9C9, 0x87FA7D7D, 0x15EFFAFA, 0xEBB25959, 0xC98E4747, 0x0BFBF0F0,
337
- 0xEC41ADAD, 0x67B3D4D4, 0xFD5FA2A2, 0xEA45AFAF, 0xBF239C9C, 0xF753A4A4, 0x96E47272, 0x5B9BC0C0,
338
- 0xC275B7B7, 0x1CE1FDFD, 0xAE3D9393, 0x6A4C2626, 0x5A6C3636, 0x417E3F3F, 0x02F5F7F7, 0x4F83CCCC,
339
- 0x5C683434, 0xF451A5A5, 0x34D1E5E5, 0x08F9F1F1, 0x93E27171, 0x73ABD8D8, 0x53623131, 0x3F2A1515,
340
- 0x0C080404, 0x5295C7C7, 0x65462323, 0x5E9DC3C3, 0x28301818, 0xA1379696, 0x0F0A0505, 0xB52F9A9A,
341
- 0x090E0707, 0x36241212, 0x9B1B8080, 0x3DDFE2E2, 0x26CDEBEB, 0x694E2727, 0xCD7FB2B2, 0x9FEA7575,
342
- 0x1B120909, 0x9E1D8383, 0x74582C2C, 0x2E341A1A, 0x2D361B1B, 0xB2DC6E6E, 0xEEB45A5A, 0xFB5BA0A0,
343
- 0xF6A45252, 0x4D763B3B, 0x61B7D6D6, 0xCE7DB3B3, 0x7B522929, 0x3EDDE3E3, 0x715E2F2F, 0x97138484,
344
- 0xF5A65353, 0x68B9D1D1, 0x00000000, 0x2CC1EDED, 0x60402020, 0x1FE3FCFC, 0xC879B1B1, 0xEDB65B5B,
345
- 0xBED46A6A, 0x468DCBCB, 0xD967BEBE, 0x4B723939, 0xDE944A4A, 0xD4984C4C, 0xE8B05858, 0x4A85CFCF,
346
- 0x6BBBD0D0, 0x2AC5EFEF, 0xE54FAAAA, 0x16EDFBFB, 0xC5864343, 0xD79A4D4D, 0x55663333, 0x94118585,
347
- 0xCF8A4545, 0x10E9F9F9, 0x06040202, 0x81FE7F7F, 0xF0A05050, 0x44783C3C, 0xBA259F9F, 0xE34BA8A8,
348
- 0xF3A25151, 0xFE5DA3A3, 0xC0804040, 0x8A058F8F, 0xAD3F9292, 0xBC219D9D, 0x48703838, 0x04F1F5F5,
349
- 0xDF63BCBC, 0xC177B6B6, 0x75AFDADA, 0x63422121, 0x30201010, 0x1AE5FFFF, 0x0EFDF3F3, 0x6DBFD2D2,
350
- 0x4C81CDCD, 0x14180C0C, 0x35261313, 0x2FC3ECEC, 0xE1BE5F5F, 0xA2359797, 0xCC884444, 0x392E1717,
351
- 0x5793C4C4, 0xF255A7A7, 0x82FC7E7E, 0x477A3D3D, 0xACC86464, 0xE7BA5D5D, 0x2B321919, 0x95E67373,
352
- 0xA0C06060, 0x98198181, 0xD19E4F4F, 0x7FA3DCDC, 0x66442222, 0x7E542A2A, 0xAB3B9090, 0x830B8888,
353
- 0xCA8C4646, 0x29C7EEEE, 0xD36BB8B8, 0x3C281414, 0x79A7DEDE, 0xE2BC5E5E, 0x1D160B0B, 0x76ADDBDB,
354
- 0x3BDBE0E0, 0x56643232, 0x4E743A3A, 0x1E140A0A, 0xDB924949, 0x0A0C0606, 0x6C482424, 0xE4B85C5C,
355
- 0x5D9FC2C2, 0x6EBDD3D3, 0xEF43ACAC, 0xA6C46262, 0xA8399191, 0xA4319595, 0x37D3E4E4, 0x8BF27979,
356
- 0x32D5E7E7, 0x438BC8C8, 0x596E3737, 0xB7DA6D6D, 0x8C018D8D, 0x64B1D5D5, 0xD29C4E4E, 0xE049A9A9,
357
- 0xB4D86C6C, 0xFAAC5656, 0x07F3F4F4, 0x25CFEAEA, 0xAFCA6565, 0x8EF47A7A, 0xE947AEAE, 0x18100808,
358
- 0xD56FBABA, 0x88F07878, 0x6F4A2525, 0x725C2E2E, 0x24381C1C, 0xF157A6A6, 0xC773B4B4, 0x5197C6C6,
359
- 0x23CBE8E8, 0x7CA1DDDD, 0x9CE87474, 0x213E1F1F, 0xDD964B4B, 0xDC61BDBD, 0x860D8B8B, 0x850F8A8A,
360
- 0x90E07070, 0x427C3E3E, 0xC471B5B5, 0xAACC6666, 0xD8904848, 0x05060303, 0x01F7F6F6, 0x121C0E0E,
361
- 0xA3C26161, 0x5F6A3535, 0xF9AE5757, 0xD069B9B9, 0x91178686, 0x5899C1C1, 0x273A1D1D, 0xB9279E9E,
362
- 0x38D9E1E1, 0x13EBF8F8, 0xB32B9898, 0x33221111, 0xBBD26969, 0x70A9D9D9, 0x89078E8E, 0xA7339494,
363
- 0xB62D9B9B, 0x223C1E1E, 0x92158787, 0x20C9E9E9, 0x4987CECE, 0xFFAA5555, 0x78502828, 0x7AA5DFDF,
364
- 0x8F038C8C, 0xF859A1A1, 0x80098989, 0x171A0D0D, 0xDA65BFBF, 0x31D7E6E6, 0xC6844242, 0xB8D06868,
365
- 0xC3824141, 0xB0299999, 0x775A2D2D, 0x111E0F0F, 0xCB7BB0B0, 0xFCA85454, 0xD66DBBBB, 0x3A2C1616
366
- );
367
-
368
- /**
369
- * Precomputed mixColumns table
370
- *
371
- * @see Crypt_Rijndael:_encryptBlock()
372
- * @see Crypt_Rijndael:_decryptBlock()
373
- * @var Array
374
- * @access private
375
- */
376
- var $t2 = array(
377
- 0x63A5C663, 0x7C84F87C, 0x7799EE77, 0x7B8DF67B, 0xF20DFFF2, 0x6BBDD66B, 0x6FB1DE6F, 0xC55491C5,
378
- 0x30506030, 0x01030201, 0x67A9CE67, 0x2B7D562B, 0xFE19E7FE, 0xD762B5D7, 0xABE64DAB, 0x769AEC76,
379
- 0xCA458FCA, 0x829D1F82, 0xC94089C9, 0x7D87FA7D, 0xFA15EFFA, 0x59EBB259, 0x47C98E47, 0xF00BFBF0,
380
- 0xADEC41AD, 0xD467B3D4, 0xA2FD5FA2, 0xAFEA45AF, 0x9CBF239C, 0xA4F753A4, 0x7296E472, 0xC05B9BC0,
381
- 0xB7C275B7, 0xFD1CE1FD, 0x93AE3D93, 0x266A4C26, 0x365A6C36, 0x3F417E3F, 0xF702F5F7, 0xCC4F83CC,
382
- 0x345C6834, 0xA5F451A5, 0xE534D1E5, 0xF108F9F1, 0x7193E271, 0xD873ABD8, 0x31536231, 0x153F2A15,
383
- 0x040C0804, 0xC75295C7, 0x23654623, 0xC35E9DC3, 0x18283018, 0x96A13796, 0x050F0A05, 0x9AB52F9A,
384
- 0x07090E07, 0x12362412, 0x809B1B80, 0xE23DDFE2, 0xEB26CDEB, 0x27694E27, 0xB2CD7FB2, 0x759FEA75,
385
- 0x091B1209, 0x839E1D83, 0x2C74582C, 0x1A2E341A, 0x1B2D361B, 0x6EB2DC6E, 0x5AEEB45A, 0xA0FB5BA0,
386
- 0x52F6A452, 0x3B4D763B, 0xD661B7D6, 0xB3CE7DB3, 0x297B5229, 0xE33EDDE3, 0x2F715E2F, 0x84971384,
387
- 0x53F5A653, 0xD168B9D1, 0x00000000, 0xED2CC1ED, 0x20604020, 0xFC1FE3FC, 0xB1C879B1, 0x5BEDB65B,
388
- 0x6ABED46A, 0xCB468DCB, 0xBED967BE, 0x394B7239, 0x4ADE944A, 0x4CD4984C, 0x58E8B058, 0xCF4A85CF,
389
- 0xD06BBBD0, 0xEF2AC5EF, 0xAAE54FAA, 0xFB16EDFB, 0x43C58643, 0x4DD79A4D, 0x33556633, 0x85941185,
390
- 0x45CF8A45, 0xF910E9F9, 0x02060402, 0x7F81FE7F, 0x50F0A050, 0x3C44783C, 0x9FBA259F, 0xA8E34BA8,
391
- 0x51F3A251, 0xA3FE5DA3, 0x40C08040, 0x8F8A058F, 0x92AD3F92, 0x9DBC219D, 0x38487038, 0xF504F1F5,
392
- 0xBCDF63BC, 0xB6C177B6, 0xDA75AFDA, 0x21634221, 0x10302010, 0xFF1AE5FF, 0xF30EFDF3, 0xD26DBFD2,
393
- 0xCD4C81CD, 0x0C14180C, 0x13352613, 0xEC2FC3EC, 0x5FE1BE5F, 0x97A23597, 0x44CC8844, 0x17392E17,
394
- 0xC45793C4, 0xA7F255A7, 0x7E82FC7E, 0x3D477A3D, 0x64ACC864, 0x5DE7BA5D, 0x192B3219, 0x7395E673,
395
- 0x60A0C060, 0x81981981, 0x4FD19E4F, 0xDC7FA3DC, 0x22664422, 0x2A7E542A, 0x90AB3B90, 0x88830B88,
396
- 0x46CA8C46, 0xEE29C7EE, 0xB8D36BB8, 0x143C2814, 0xDE79A7DE, 0x5EE2BC5E, 0x0B1D160B, 0xDB76ADDB,
397
- 0xE03BDBE0, 0x32566432, 0x3A4E743A, 0x0A1E140A, 0x49DB9249, 0x060A0C06, 0x246C4824, 0x5CE4B85C,
398
- 0xC25D9FC2, 0xD36EBDD3, 0xACEF43AC, 0x62A6C462, 0x91A83991, 0x95A43195, 0xE437D3E4, 0x798BF279,
399
- 0xE732D5E7, 0xC8438BC8, 0x37596E37, 0x6DB7DA6D, 0x8D8C018D, 0xD564B1D5, 0x4ED29C4E, 0xA9E049A9,
400
- 0x6CB4D86C, 0x56FAAC56, 0xF407F3F4, 0xEA25CFEA, 0x65AFCA65, 0x7A8EF47A, 0xAEE947AE, 0x08181008,
401
- 0xBAD56FBA, 0x7888F078, 0x256F4A25, 0x2E725C2E, 0x1C24381C, 0xA6F157A6, 0xB4C773B4, 0xC65197C6,
402
- 0xE823CBE8, 0xDD7CA1DD, 0x749CE874, 0x1F213E1F, 0x4BDD964B, 0xBDDC61BD, 0x8B860D8B, 0x8A850F8A,
403
- 0x7090E070, 0x3E427C3E, 0xB5C471B5, 0x66AACC66, 0x48D89048, 0x03050603, 0xF601F7F6, 0x0E121C0E,
404
- 0x61A3C261, 0x355F6A35, 0x57F9AE57, 0xB9D069B9, 0x86911786, 0xC15899C1, 0x1D273A1D, 0x9EB9279E,
405
- 0xE138D9E1, 0xF813EBF8, 0x98B32B98, 0x11332211, 0x69BBD269, 0xD970A9D9, 0x8E89078E, 0x94A73394,
406
- 0x9BB62D9B, 0x1E223C1E, 0x87921587, 0xE920C9E9, 0xCE4987CE, 0x55FFAA55, 0x28785028, 0xDF7AA5DF,
407
- 0x8C8F038C, 0xA1F859A1, 0x89800989, 0x0D171A0D, 0xBFDA65BF, 0xE631D7E6, 0x42C68442, 0x68B8D068,
408
- 0x41C38241, 0x99B02999, 0x2D775A2D, 0x0F111E0F, 0xB0CB7BB0, 0x54FCA854, 0xBBD66DBB, 0x163A2C16
409
- );
410
-
411
- /**
412
- * Precomputed mixColumns table
413
- *
414
- * @see Crypt_Rijndael:_encryptBlock()
415
- * @see Crypt_Rijndael:_decryptBlock()
416
- * @var Array
417
- * @access private
418
- */
419
- var $t3 = array(
420
- 0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491,
421
- 0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC,
422
- 0xCACA458F, 0x82829D1F, 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB,
423
- 0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, 0x727296E4, 0xC0C05B9B,
424
- 0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83,
425
- 0x34345C68, 0xA5A5F451, 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A,
426
- 0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, 0x05050F0A, 0x9A9AB52F,
427
- 0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA,
428
- 0x09091B12, 0x83839E1D, 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B,
429
- 0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, 0x2F2F715E, 0x84849713,
430
- 0x5353F5A6, 0xD1D168B9, 0x00000000, 0xEDED2CC1, 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6,
431
- 0x6A6ABED4, 0xCBCB468D, 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85,
432
- 0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, 0x33335566, 0x85859411,
433
- 0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B,
434
- 0x5151F3A2, 0xA3A3FE5D, 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1,
435
- 0xBCBCDF63, 0xB6B6C177, 0xDADA75AF, 0x21216342, 0x10103020, 0xFFFF1AE5, 0xF3F30EFD, 0xD2D26DBF,
436
- 0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E,
437
- 0xC4C45793, 0xA7A7F255, 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6,
438
- 0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, 0x9090AB3B, 0x8888830B,
439
- 0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD,
440
- 0xE0E03BDB, 0x32325664, 0x3A3A4E74, 0x0A0A1E14, 0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8,
441
- 0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, 0xE4E437D3, 0x79798BF2,
442
- 0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049,
443
- 0x6C6CB4D8, 0x5656FAAC, 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810,
444
- 0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, 0xB4B4C773, 0xC6C65197,
445
- 0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, 0x4B4BDD96, 0xBDBDDC61, 0x8B8B860D, 0x8A8A850F,
446
- 0x707090E0, 0x3E3E427C, 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C,
447
- 0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, 0x1D1D273A, 0x9E9EB927,
448
- 0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733,
449
- 0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5,
450
- 0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0,
451
- 0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C
452
- );
453
-
454
- /**
455
- * Precomputed invMixColumns table
456
- *
457
- * @see Crypt_Rijndael:_encryptBlock()
458
- * @see Crypt_Rijndael:_decryptBlock()
459
- * @var Array
460
- * @access private
461
- */
462
- var $dt0 = array(
463
- 0x51F4A750, 0x7E416553, 0x1A17A4C3, 0x3A275E96, 0x3BAB6BCB, 0x1F9D45F1, 0xACFA58AB, 0x4BE30393,
464
- 0x2030FA55, 0xAD766DF6, 0x88CC7691, 0xF5024C25, 0x4FE5D7FC, 0xC52ACBD7, 0x26354480, 0xB562A38F,
465
- 0xDEB15A49, 0x25BA1B67, 0x45EA0E98, 0x5DFEC0E1, 0xC32F7502, 0x814CF012, 0x8D4697A3, 0x6BD3F9C6,
466
- 0x038F5FE7, 0x15929C95, 0xBF6D7AEB, 0x955259DA, 0xD4BE832D, 0x587421D3, 0x49E06929, 0x8EC9C844,
467
- 0x75C2896A, 0xF48E7978, 0x99583E6B, 0x27B971DD, 0xBEE14FB6, 0xF088AD17, 0xC920AC66, 0x7DCE3AB4,
468
- 0x63DF4A18, 0xE51A3182, 0x97513360, 0x62537F45, 0xB16477E0, 0xBB6BAE84, 0xFE81A01C, 0xF9082B94,
469
- 0x70486858, 0x8F45FD19, 0x94DE6C87, 0x527BF8B7, 0xAB73D323, 0x724B02E2, 0xE31F8F57, 0x6655AB2A,
470
- 0xB2EB2807, 0x2FB5C203, 0x86C57B9A, 0xD33708A5, 0x302887F2, 0x23BFA5B2, 0x02036ABA, 0xED16825C,
471
- 0x8ACF1C2B, 0xA779B492, 0xF307F2F0, 0x4E69E2A1, 0x65DAF4CD, 0x0605BED5, 0xD134621F, 0xC4A6FE8A,
472
- 0x342E539D, 0xA2F355A0, 0x058AE132, 0xA4F6EB75, 0x0B83EC39, 0x4060EFAA, 0x5E719F06, 0xBD6E1051,
473
- 0x3E218AF9, 0x96DD063D, 0xDD3E05AE, 0x4DE6BD46, 0x91548DB5, 0x71C45D05, 0x0406D46F, 0x605015FF,
474
- 0x1998FB24, 0xD6BDE997, 0x894043CC, 0x67D99E77, 0xB0E842BD, 0x07898B88, 0xE7195B38, 0x79C8EEDB,
475
- 0xA17C0A47, 0x7C420FE9, 0xF8841EC9, 0x00000000, 0x09808683, 0x322BED48, 0x1E1170AC, 0x6C5A724E,
476
- 0xFD0EFFFB, 0x0F853856, 0x3DAED51E, 0x362D3927, 0x0A0FD964, 0x685CA621, 0x9B5B54D1, 0x24362E3A,
477
- 0x0C0A67B1, 0x9357E70F, 0xB4EE96D2, 0x1B9B919E, 0x80C0C54F, 0x61DC20A2, 0x5A774B69, 0x1C121A16,
478
- 0xE293BA0A, 0xC0A02AE5, 0x3C22E043, 0x121B171D, 0x0E090D0B, 0xF28BC7AD, 0x2DB6A8B9, 0x141EA9C8,
479
- 0x57F11985, 0xAF75074C, 0xEE99DDBB, 0xA37F60FD, 0xF701269F, 0x5C72F5BC, 0x44663BC5, 0x5BFB7E34,
480
- 0x8B432976, 0xCB23C6DC, 0xB6EDFC68, 0xB8E4F163, 0xD731DCCA, 0x42638510, 0x13972240, 0x84C61120,
481
- 0x854A247D, 0xD2BB3DF8, 0xAEF93211, 0xC729A16D, 0x1D9E2F4B, 0xDCB230F3, 0x0D8652EC, 0x77C1E3D0,
482
- 0x2BB3166C, 0xA970B999, 0x119448FA, 0x47E96422, 0xA8FC8CC4, 0xA0F03F1A, 0x567D2CD8, 0x223390EF,
483
- 0x87494EC7, 0xD938D1C1, 0x8CCAA2FE, 0x98D40B36, 0xA6F581CF, 0xA57ADE28, 0xDAB78E26, 0x3FADBFA4,
484
- 0x2C3A9DE4, 0x5078920D, 0x6A5FCC9B, 0x547E4662, 0xF68D13C2, 0x90D8B8E8, 0x2E39F75E, 0x82C3AFF5,
485
- 0x9F5D80BE, 0x69D0937C, 0x6FD52DA9, 0xCF2512B3, 0xC8AC993B, 0x10187DA7, 0xE89C636E, 0xDB3BBB7B,
486
- 0xCD267809, 0x6E5918F4, 0xEC9AB701, 0x834F9AA8, 0xE6956E65, 0xAAFFE67E, 0x21BCCF08, 0xEF15E8E6,
487
- 0xBAE79BD9, 0x4A6F36CE, 0xEA9F09D4, 0x29B07CD6, 0x31A4B2AF, 0x2A3F2331, 0xC6A59430, 0x35A266C0,
488
- 0x744EBC37, 0xFC82CAA6, 0xE090D0B0, 0x33A7D815, 0xF104984A, 0x41ECDAF7, 0x7FCD500E, 0x1791F62F,
489
- 0x764DD68D, 0x43EFB04D, 0xCCAA4D54, 0xE49604DF, 0x9ED1B5E3, 0x4C6A881B, 0xC12C1FB8, 0x4665517F,
490
- 0x9D5EEA04, 0x018C355D, 0xFA877473, 0xFB0B412E, 0xB3671D5A, 0x92DBD252, 0xE9105633, 0x6DD64713,
491
- 0x9AD7618C, 0x37A10C7A, 0x59F8148E, 0xEB133C89, 0xCEA927EE, 0xB761C935, 0xE11CE5ED, 0x7A47B13C,
492
- 0x9CD2DF59, 0x55F2733F, 0x1814CE79, 0x73C737BF, 0x53F7CDEA, 0x5FFDAA5B, 0xDF3D6F14, 0x7844DB86,
493
- 0xCAAFF381, 0xB968C43E, 0x3824342C, 0xC2A3405F, 0x161DC372, 0xBCE2250C, 0x283C498B, 0xFF0D9541,
494
- 0x39A80171, 0x080CB3DE, 0xD8B4E49C, 0x6456C190, 0x7BCB8461, 0xD532B670, 0x486C5C74, 0xD0B85742
495
- );
496
-
497
- /**
498
- * Precomputed invMixColumns table
499
- *
500
- * @see Crypt_Rijndael:_encryptBlock()
501
- * @see Crypt_Rijndael:_decryptBlock()
502
- * @var Array
503
- * @access private
504
- */
505
- var $dt1 = array(
506
- 0x5051F4A7, 0x537E4165, 0xC31A17A4, 0x963A275E, 0xCB3BAB6B, 0xF11F9D45, 0xABACFA58, 0x934BE303,
507
- 0x552030FA, 0xF6AD766D, 0x9188CC76, 0x25F5024C, 0xFC4FE5D7, 0xD7C52ACB, 0x80263544, 0x8FB562A3,
508
- 0x49DEB15A, 0x6725BA1B, 0x9845EA0E, 0xE15DFEC0, 0x02C32F75, 0x12814CF0, 0xA38D4697, 0xC66BD3F9,
509
- 0xE7038F5F, 0x9515929C, 0xEBBF6D7A, 0xDA955259, 0x2DD4BE83, 0xD3587421, 0x2949E069, 0x448EC9C8,
510
- 0x6A75C289, 0x78F48E79, 0x6B99583E, 0xDD27B971, 0xB6BEE14F, 0x17F088AD, 0x66C920AC, 0xB47DCE3A,
511
- 0x1863DF4A, 0x82E51A31, 0x60975133, 0x4562537F, 0xE0B16477, 0x84BB6BAE, 0x1CFE81A0, 0x94F9082B,
512
- 0x58704868, 0x198F45FD, 0x8794DE6C, 0xB7527BF8, 0x23AB73D3, 0xE2724B02, 0x57E31F8F, 0x2A6655AB,
513
- 0x07B2EB28, 0x032FB5C2, 0x9A86C57B, 0xA5D33708, 0xF2302887, 0xB223BFA5, 0xBA02036A, 0x5CED1682,
514
- 0x2B8ACF1C, 0x92A779B4, 0xF0F307F2, 0xA14E69E2, 0xCD65DAF4, 0xD50605BE, 0x1FD13462, 0x8AC4A6FE,
515
- 0x9D342E53, 0xA0A2F355, 0x32058AE1, 0x75A4F6EB, 0x390B83EC, 0xAA4060EF, 0x065E719F, 0x51BD6E10,
516
- 0xF93E218A, 0x3D96DD06, 0xAEDD3E05, 0x464DE6BD, 0xB591548D, 0x0571C45D, 0x6F0406D4, 0xFF605015,
517
- 0x241998FB, 0x97D6BDE9, 0xCC894043, 0x7767D99E, 0xBDB0E842, 0x8807898B, 0x38E7195B, 0xDB79C8EE,
518
- 0x47A17C0A, 0xE97C420F, 0xC9F8841E, 0x00000000, 0x83098086, 0x48322BED, 0xAC1E1170, 0x4E6C5A72,
519
- 0xFBFD0EFF, 0x560F8538, 0x1E3DAED5, 0x27362D39, 0x640A0FD9, 0x21685CA6, 0xD19B5B54, 0x3A24362E,
520
- 0xB10C0A67, 0x0F9357E7, 0xD2B4EE96, 0x9E1B9B91, 0x4F80C0C5, 0xA261DC20, 0x695A774B, 0x161C121A,
521
- 0x0AE293BA, 0xE5C0A02A, 0x433C22E0, 0x1D121B17, 0x0B0E090D, 0xADF28BC7, 0xB92DB6A8, 0xC8141EA9,
522
- 0x8557F119, 0x4CAF7507, 0xBBEE99DD, 0xFDA37F60, 0x9FF70126, 0xBC5C72F5, 0xC544663B, 0x345BFB7E,
523
- 0x768B4329, 0xDCCB23C6, 0x68B6EDFC, 0x63B8E4F1, 0xCAD731DC, 0x10426385, 0x40139722, 0x2084C611,
524
- 0x7D854A24, 0xF8D2BB3D, 0x11AEF932, 0x6DC729A1, 0x4B1D9E2F, 0xF3DCB230, 0xEC0D8652, 0xD077C1E3,
525
- 0x6C2BB316, 0x99A970B9, 0xFA119448, 0x2247E964, 0xC4A8FC8C, 0x1AA0F03F, 0xD8567D2C, 0xEF223390,
526
- 0xC787494E, 0xC1D938D1, 0xFE8CCAA2, 0x3698D40B, 0xCFA6F581, 0x28A57ADE, 0x26DAB78E, 0xA43FADBF,
527
- 0xE42C3A9D, 0x0D507892, 0x9B6A5FCC, 0x62547E46, 0xC2F68D13, 0xE890D8B8, 0x5E2E39F7, 0xF582C3AF,
528
- 0xBE9F5D80, 0x7C69D093, 0xA96FD52D, 0xB3CF2512, 0x3BC8AC99, 0xA710187D, 0x6EE89C63, 0x7BDB3BBB,
529
- 0x09CD2678, 0xF46E5918, 0x01EC9AB7, 0xA8834F9A, 0x65E6956E, 0x7EAAFFE6, 0x0821BCCF, 0xE6EF15E8,
530
- 0xD9BAE79B, 0xCE4A6F36, 0xD4EA9F09, 0xD629B07C, 0xAF31A4B2, 0x312A3F23, 0x30C6A594, 0xC035A266,
531
- 0x37744EBC, 0xA6FC82CA, 0xB0E090D0, 0x1533A7D8, 0x4AF10498, 0xF741ECDA, 0x0E7FCD50, 0x2F1791F6,
532
- 0x8D764DD6, 0x4D43EFB0, 0x54CCAA4D, 0xDFE49604, 0xE39ED1B5, 0x1B4C6A88, 0xB8C12C1F, 0x7F466551,
533
- 0x049D5EEA, 0x5D018C35, 0x73FA8774, 0x2EFB0B41, 0x5AB3671D, 0x5292DBD2, 0x33E91056, 0x136DD647,
534
- 0x8C9AD761, 0x7A37A10C, 0x8E59F814, 0x89EB133C, 0xEECEA927, 0x35B761C9, 0xEDE11CE5, 0x3C7A47B1,
535
- 0x599CD2DF, 0x3F55F273, 0x791814CE, 0xBF73C737, 0xEA53F7CD, 0x5B5FFDAA, 0x14DF3D6F, 0x867844DB,
536
- 0x81CAAFF3, 0x3EB968C4, 0x2C382434, 0x5FC2A340, 0x72161DC3, 0x0CBCE225, 0x8B283C49, 0x41FF0D95,
537
- 0x7139A801, 0xDE080CB3, 0x9CD8B4E4, 0x906456C1, 0x617BCB84, 0x70D532B6, 0x74486C5C, 0x42D0B857
538
- );
539
-
540
- /**
541
- * Precomputed invMixColumns table
542
- *
543
- * @see Crypt_Rijndael:_encryptBlock()
544
- * @see Crypt_Rijndael:_decryptBlock()
545
- * @var Array
546
- * @access private
547
- */
548
- var $dt2 = array(
549
- 0xA75051F4, 0x65537E41, 0xA4C31A17, 0x5E963A27, 0x6BCB3BAB, 0x45F11F9D, 0x58ABACFA, 0x03934BE3,
550
- 0xFA552030, 0x6DF6AD76, 0x769188CC, 0x4C25F502, 0xD7FC4FE5, 0xCBD7C52A, 0x44802635, 0xA38FB562,
551
- 0x5A49DEB1, 0x1B6725BA, 0x0E9845EA, 0xC0E15DFE, 0x7502C32F, 0xF012814C, 0x97A38D46, 0xF9C66BD3,
552
- 0x5FE7038F, 0x9C951592, 0x7AEBBF6D, 0x59DA9552, 0x832DD4BE, 0x21D35874, 0x692949E0, 0xC8448EC9,
553
- 0x896A75C2, 0x7978F48E, 0x3E6B9958, 0x71DD27B9, 0x4FB6BEE1, 0xAD17F088, 0xAC66C920, 0x3AB47DCE,
554
- 0x4A1863DF, 0x3182E51A, 0x33609751, 0x7F456253, 0x77E0B164, 0xAE84BB6B, 0xA01CFE81, 0x2B94F908,
555
- 0x68587048, 0xFD198F45, 0x6C8794DE, 0xF8B7527B, 0xD323AB73, 0x02E2724B, 0x8F57E31F, 0xAB2A6655,
556
- 0x2807B2EB, 0xC2032FB5, 0x7B9A86C5, 0x08A5D337, 0x87F23028, 0xA5B223BF, 0x6ABA0203, 0x825CED16,
557
- 0x1C2B8ACF, 0xB492A779, 0xF2F0F307, 0xE2A14E69, 0xF4CD65DA, 0xBED50605, 0x621FD134, 0xFE8AC4A6,
558
- 0x539D342E, 0x55A0A2F3, 0xE132058A, 0xEB75A4F6, 0xEC390B83, 0xEFAA4060, 0x9F065E71, 0x1051BD6E,
559
- 0x8AF93E21, 0x063D96DD, 0x05AEDD3E, 0xBD464DE6, 0x8DB59154, 0x5D0571C4, 0xD46F0406, 0x15FF6050,
560
- 0xFB241998, 0xE997D6BD, 0x43CC8940, 0x9E7767D9, 0x42BDB0E8, 0x8B880789, 0x5B38E719, 0xEEDB79C8,
561
- 0x0A47A17C, 0x0FE97C42, 0x1EC9F884, 0x00000000, 0x86830980, 0xED48322B, 0x70AC1E11, 0x724E6C5A,
562
- 0xFFFBFD0E, 0x38560F85, 0xD51E3DAE, 0x3927362D, 0xD9640A0F, 0xA621685C, 0x54D19B5B, 0x2E3A2436,
563
- 0x67B10C0A, 0xE70F9357, 0x96D2B4EE, 0x919E1B9B, 0xC54F80C0, 0x20A261DC, 0x4B695A77, 0x1A161C12,
564
- 0xBA0AE293, 0x2AE5C0A0, 0xE0433C22, 0x171D121B, 0x0D0B0E09, 0xC7ADF28B, 0xA8B92DB6, 0xA9C8141E,
565
- 0x198557F1, 0x074CAF75, 0xDDBBEE99, 0x60FDA37F, 0x269FF701, 0xF5BC5C72, 0x3BC54466, 0x7E345BFB,
566
- 0x29768B43, 0xC6DCCB23, 0xFC68B6ED, 0xF163B8E4, 0xDCCAD731, 0x85104263, 0x22401397, 0x112084C6,
567
- 0x247D854A, 0x3DF8D2BB, 0x3211AEF9, 0xA16DC729, 0x2F4B1D9E, 0x30F3DCB2, 0x52EC0D86, 0xE3D077C1,
568
- 0x166C2BB3, 0xB999A970, 0x48FA1194, 0x642247E9, 0x8CC4A8FC, 0x3F1AA0F0, 0x2CD8567D, 0x90EF2233,
569
- 0x4EC78749, 0xD1C1D938, 0xA2FE8CCA, 0x0B3698D4, 0x81CFA6F5, 0xDE28A57A, 0x8E26DAB7, 0xBFA43FAD,
570
- 0x9DE42C3A, 0x920D5078, 0xCC9B6A5F, 0x4662547E, 0x13C2F68D, 0xB8E890D8, 0xF75E2E39, 0xAFF582C3,
571
- 0x80BE9F5D, 0x937C69D0, 0x2DA96FD5, 0x12B3CF25, 0x993BC8AC, 0x7DA71018, 0x636EE89C, 0xBB7BDB3B,
572
- 0x7809CD26, 0x18F46E59, 0xB701EC9A, 0x9AA8834F, 0x6E65E695, 0xE67EAAFF, 0xCF0821BC, 0xE8E6EF15,
573
- 0x9BD9BAE7, 0x36CE4A6F, 0x09D4EA9F, 0x7CD629B0, 0xB2AF31A4, 0x23312A3F, 0x9430C6A5, 0x66C035A2,
574
- 0xBC37744E, 0xCAA6FC82, 0xD0B0E090, 0xD81533A7, 0x984AF104, 0xDAF741EC, 0x500E7FCD, 0xF62F1791,
575
- 0xD68D764D, 0xB04D43EF, 0x4D54CCAA, 0x04DFE496, 0xB5E39ED1, 0x881B4C6A, 0x1FB8C12C, 0x517F4665,
576
- 0xEA049D5E, 0x355D018C, 0x7473FA87, 0x412EFB0B, 0x1D5AB367, 0xD25292DB, 0x5633E910, 0x47136DD6,
577
- 0x618C9AD7, 0x0C7A37A1, 0x148E59F8, 0x3C89EB13, 0x27EECEA9, 0xC935B761, 0xE5EDE11C, 0xB13C7A47,
578
- 0xDF599CD2, 0x733F55F2, 0xCE791814, 0x37BF73C7, 0xCDEA53F7, 0xAA5B5FFD, 0x6F14DF3D, 0xDB867844,
579
- 0xF381CAAF, 0xC43EB968, 0x342C3824, 0x405FC2A3, 0xC372161D, 0x250CBCE2, 0x498B283C, 0x9541FF0D,
580
- 0x017139A8, 0xB3DE080C, 0xE49CD8B4, 0xC1906456, 0x84617BCB, 0xB670D532, 0x5C74486C, 0x5742D0B8
581
- );
582
-
583
- /**
584
- * Precomputed invMixColumns table
585
- *
586
- * @see Crypt_Rijndael:_encryptBlock()
587
- * @see Crypt_Rijndael:_decryptBlock()
588
- * @var Array
589
- * @access private
590
- */
591
- var $dt3 = array(
592
- 0xF4A75051, 0x4165537E, 0x17A4C31A, 0x275E963A, 0xAB6BCB3B, 0x9D45F11F, 0xFA58ABAC, 0xE303934B,
593
- 0x30FA5520, 0x766DF6AD, 0xCC769188, 0x024C25F5, 0xE5D7FC4F, 0x2ACBD7C5, 0x35448026, 0x62A38FB5,
594
- 0xB15A49DE, 0xBA1B6725, 0xEA0E9845, 0xFEC0E15D, 0x2F7502C3, 0x4CF01281, 0x4697A38D, 0xD3F9C66B,
595
- 0x8F5FE703, 0x929C9515, 0x6D7AEBBF, 0x5259DA95, 0xBE832DD4, 0x7421D358, 0xE0692949, 0xC9C8448E,
596
- 0xC2896A75, 0x8E7978F4, 0x583E6B99, 0xB971DD27, 0xE14FB6BE, 0x88AD17F0, 0x20AC66C9, 0xCE3AB47D,
597
- 0xDF4A1863, 0x1A3182E5, 0x51336097, 0x537F4562, 0x6477E0B1, 0x6BAE84BB, 0x81A01CFE, 0x082B94F9,
598
- 0x48685870, 0x45FD198F, 0xDE6C8794, 0x7BF8B752, 0x73D323AB, 0x4B02E272, 0x1F8F57E3, 0x55AB2A66,
599
- 0xEB2807B2, 0xB5C2032F, 0xC57B9A86, 0x3708A5D3, 0x2887F230, 0xBFA5B223, 0x036ABA02, 0x16825CED,
600
- 0xCF1C2B8A, 0x79B492A7, 0x07F2F0F3, 0x69E2A14E, 0xDAF4CD65, 0x05BED506, 0x34621FD1, 0xA6FE8AC4,
601
- 0x2E539D34, 0xF355A0A2, 0x8AE13205, 0xF6EB75A4, 0x83EC390B, 0x60EFAA40, 0x719F065E, 0x6E1051BD,
602
- 0x218AF93E, 0xDD063D96, 0x3E05AEDD, 0xE6BD464D, 0x548DB591, 0xC45D0571, 0x06D46F04, 0x5015FF60,
603
- 0x98FB2419, 0xBDE997D6, 0x4043CC89, 0xD99E7767, 0xE842BDB0, 0x898B8807, 0x195B38E7, 0xC8EEDB79,
604
- 0x7C0A47A1, 0x420FE97C, 0x841EC9F8, 0x00000000, 0x80868309, 0x2BED4832, 0x1170AC1E, 0x5A724E6C,
605
- 0x0EFFFBFD, 0x8538560F, 0xAED51E3D, 0x2D392736, 0x0FD9640A, 0x5CA62168, 0x5B54D19B, 0x362E3A24,
606
- 0x0A67B10C, 0x57E70F93, 0xEE96D2B4, 0x9B919E1B, 0xC0C54F80, 0xDC20A261, 0x774B695A, 0x121A161C,
607
- 0x93BA0AE2, 0xA02AE5C0, 0x22E0433C, 0x1B171D12, 0x090D0B0E, 0x8BC7ADF2, 0xB6A8B92D, 0x1EA9C814,
608
- 0xF1198557, 0x75074CAF, 0x99DDBBEE, 0x7F60FDA3, 0x01269FF7, 0x72F5BC5C, 0x663BC544, 0xFB7E345B,
609
- 0x4329768B, 0x23C6DCCB, 0xEDFC68B6, 0xE4F163B8, 0x31DCCAD7, 0x63851042, 0x97224013, 0xC6112084,
610
- 0x4A247D85, 0xBB3DF8D2, 0xF93211AE, 0x29A16DC7, 0x9E2F4B1D, 0xB230F3DC, 0x8652EC0D, 0xC1E3D077,
611
- 0xB3166C2B, 0x70B999A9, 0x9448FA11, 0xE9642247, 0xFC8CC4A8, 0xF03F1AA0, 0x7D2CD856, 0x3390EF22,
612
- 0x494EC787, 0x38D1C1D9, 0xCAA2FE8C, 0xD40B3698, 0xF581CFA6, 0x7ADE28A5, 0xB78E26DA, 0xADBFA43F,
613
- 0x3A9DE42C, 0x78920D50, 0x5FCC9B6A, 0x7E466254, 0x8D13C2F6, 0xD8B8E890, 0x39F75E2E, 0xC3AFF582,
614
- 0x5D80BE9F, 0xD0937C69, 0xD52DA96F, 0x2512B3CF, 0xAC993BC8, 0x187DA710, 0x9C636EE8, 0x3BBB7BDB,
615
- 0x267809CD, 0x5918F46E, 0x9AB701EC, 0x4F9AA883, 0x956E65E6, 0xFFE67EAA, 0xBCCF0821, 0x15E8E6EF,
616
- 0xE79BD9BA, 0x6F36CE4A, 0x9F09D4EA, 0xB07CD629, 0xA4B2AF31, 0x3F23312A, 0xA59430C6, 0xA266C035,
617
- 0x4EBC3774, 0x82CAA6FC, 0x90D0B0E0, 0xA7D81533, 0x04984AF1, 0xECDAF741, 0xCD500E7F, 0x91F62F17,
618
- 0x4DD68D76, 0xEFB04D43, 0xAA4D54CC, 0x9604DFE4, 0xD1B5E39E, 0x6A881B4C, 0x2C1FB8C1, 0x65517F46,
619
- 0x5EEA049D, 0x8C355D01, 0x877473FA, 0x0B412EFB, 0x671D5AB3, 0xDBD25292, 0x105633E9, 0xD647136D,
620
- 0xD7618C9A, 0xA10C7A37, 0xF8148E59, 0x133C89EB, 0xA927EECE, 0x61C935B7, 0x1CE5EDE1, 0x47B13C7A,
621
- 0xD2DF599C, 0xF2733F55, 0x14CE7918, 0xC737BF73, 0xF7CDEA53, 0xFDAA5B5F, 0x3D6F14DF, 0x44DB8678,
622
- 0xAFF381CA, 0x68C43EB9, 0x24342C38, 0xA3405FC2, 0x1DC37216, 0xE2250CBC, 0x3C498B28, 0x0D9541FF,
623
- 0xA8017139, 0x0CB3DE08, 0xB4E49CD8, 0x56C19064, 0xCB84617B, 0x32B670D5, 0x6C5C7448, 0xB85742D0
624
- );
625
-
626
- /**
627
- * The SubByte S-Box
628
- *
629
- * @see Crypt_Rijndael::_encryptBlock()
630
- * @var Array
631
- * @access private
632
- */
633
- var $sbox = array(
634
- 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
635
- 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
636
- 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
637
- 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
638
- 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
639
- 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
640
- 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
641
- 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
642
- 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
643
- 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
644
- 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
645
- 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
646
- 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
647
- 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
648
- 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
649
- 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
650
- );
651
-
652
- /**
653
- * The inverse SubByte S-Box
654
- *
655
- * @see Crypt_Rijndael::_decryptBlock()
656
- * @var Array
657
- * @access private
658
- */
659
- var $isbox = array(
660
- 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
661
- 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
662
- 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
663
- 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
664
- 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
665
- 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
666
- 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
667
- 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
668
- 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
669
- 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
670
- 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
671
- 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
672
- 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
673
- 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
674
- 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
675
- 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
676
- );
677
-
678
- /**
679
- * Sets the key.
680
- *
681
- * Keys can be of any length. Rijndael, itself, requires the use of a key that's between 128-bits and 256-bits long and
682
- * whose length is a multiple of 32. If the key is less than 256-bits and the key length isn't set, we round the length
683
- * up to the closest valid key length, padding $key with null bytes. If the key is more than 256-bits, we trim the
684
- * excess bits.
685
- *
686
- * If the key is not explicitly set, it'll be assumed to be all null bytes.
687
- *
688
- * Note: 160/224-bit keys must explicitly set by setKeyLength(), otherwise they will be round/pad up to 192/256 bits.
689
- *
690
- * @see Crypt_Base:setKey()
691
- * @see setKeyLength()
692
- * @access public
693
- * @param String $key
694
- */
695
- function setKey($key)
696
- {
697
- parent::setKey($key);
698
-
699
- if (!$this->explicit_key_length) {
700
- $length = strlen($key);
701
- switch (true) {
702
- case $length <= 16:
703
- $this->key_size = 16;
704
- break;
705
- case $length <= 20:
706
- $this->key_size = 20;
707
- break;
708
- case $length <= 24:
709
- $this->key_size = 24;
710
- break;
711
- case $length <= 28:
712
- $this->key_size = 28;
713
- break;
714
- default:
715
- $this->key_size = 32;
716
- }
717
- $this->_setupEngine();
718
- }
719
- }
720
-
721
- /**
722
- * Sets the key length
723
- *
724
- * Valid key lengths are 128, 160, 192, 224, and 256. If the length is less than 128, it will be rounded up to
725
- * 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount.
726
- *
727
- * Note: phpseclib extends Rijndael (and AES) for using 160- and 224-bit keys but they are officially not defined
728
- * and the most (if not all) implementations are not able using 160/224-bit keys but round/pad them up to
729
- * 192/256 bits as, for example, mcrypt will do.
730
- *
731
- * That said, if you want be compatible with other Rijndael and AES implementations,
732
- * you should not setKeyLength(160) or setKeyLength(224).
733
- *
734
- * Additional: In case of 160- and 224-bit keys, phpseclib will/can, for that reason, not use
735
- * the mcrypt php extension, even if available.
736
- * This results then in slower encryption.
737
- *
738
- * @access public
739
- * @param Integer $length
740
- */
741
- function setKeyLength($length)
742
- {
743
- switch (true) {
744
- case $length == 160:
745
- $this->key_size = 20;
746
- break;
747
- case $length == 224:
748
- $this->key_size = 28;
749
- break;
750
- case $length <= 128:
751
- $this->key_size = 16;
752
- break;
753
- case $length <= 192:
754
- $this->key_size = 24;
755
- break;
756
- default:
757
- $this->key_size = 32;
758
- }
759
-
760
- $this->explicit_key_length = true;
761
- $this->changed = true;
762
- $this->_setupEngine();
763
- }
764
-
765
- /**
766
- * Sets the block length
767
- *
768
- * Valid block lengths are 128, 160, 192, 224, and 256. If the length is less than 128, it will be rounded up to
769
- * 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount.
770
- *
771
- * @access public
772
- * @param Integer $length
773
- */
774
- function setBlockLength($length)
775
- {
776
- $length >>= 5;
777
- if ($length > 8) {
778
- $length = 8;
779
- } else if ($length < 4) {
780
- $length = 4;
781
- }
782
- $this->Nb = $length;
783
- $this->block_size = $length << 2;
784
- $this->changed = true;
785
- $this->_setupEngine();
786
- }
787
-
788
- /**
789
- * Setup the fastest possible $engine
790
- *
791
- * Determines if the mcrypt (MODE_MCRYPT) $engine available
792
- * and usable for the current $block_size and $key_size.
793
- *
794
- * If not, the slower MODE_INTERNAL $engine will be set.
795
- *
796
- * @see setKey()
797
- * @see setKeyLength()
798
- * @see setBlockLength()
799
- * @access private
800
- */
801
- function _setupEngine()
802
- {
803
- if (constant('CRYPT_' . $this->const_namespace . '_MODE') == CRYPT_MODE_INTERNAL) {
804
- // No mcrypt support at all for rijndael
805
- return;
806
- }
807
-
808
- // The required mcrypt module name for the current $block_size of rijndael
809
- $cipher_name_mcrypt = 'rijndael-' . ($this->block_size << 3);
810
-
811
- // Determining the availibility/usability of $cipher_name_mcrypt
812
- switch (true) {
813
- case $this->key_size % 8: // mcrypt is not usable for 160/224-bit keys, only for 128/192/256-bit keys
814
- case !in_array($cipher_name_mcrypt, mcrypt_list_algorithms()): // $cipher_name_mcrypt is not available for the current $block_size
815
- $engine = CRYPT_MODE_INTERNAL;
816
- break;
817
- default:
818
- $engine = CRYPT_MODE_MCRYPT;
819
- }
820
-
821
- if ($this->engine == $engine && $this->cipher_name_mcrypt == $cipher_name_mcrypt) {
822
- // allready set, so we not unnecessary close $this->enmcrypt/demcrypt/ecb
823
- return;
824
- }
825
-
826
- // Set the $engine
827
- $this->engine = $engine;
828
- $this->cipher_name_mcrypt = $cipher_name_mcrypt;
829
-
830
- if ($this->enmcrypt) {
831
- // Closing the current mcrypt resource(s). _mcryptSetup() will, if needed,
832
- // (re)open them with the module named in $this->cipher_name_mcrypt
833
- mcrypt_module_close($this->enmcrypt);
834
- mcrypt_module_close($this->demcrypt);
835
- $this->enmcrypt = null;
836
- $this->demcrypt = null;
837
-
838
- if ($this->ecb) {
839
- mcrypt_module_close($this->ecb);
840
- $this->ecb = null;
841
- }
842
- }
843
- }
844
-
845
- /**
846
- * Setup the CRYPT_MODE_MCRYPT $engine
847
- *
848
- * @see Crypt_Base::_setupMcrypt()
849
- * @access private
850
- */
851
- function _setupMcrypt()
852
- {
853
- $this->key = str_pad(substr($this->key, 0, $this->key_size), $this->key_size, "\0");
854
- parent::_setupMcrypt();
855
- }
856
-
857
- /**
858
- * Encrypts a block
859
- *
860
- * @access private
861
- * @param String $in
862
- * @return String
863
- */
864
- function _encryptBlock($in)
865
- {
866
- static $t0, $t1, $t2, $t3, $sbox;
867
- if (!$t0) {
868
- for ($i = 0; $i < 256; ++$i) {
869
- $t0[] = (int)$this->t0[$i];
870
- $t1[] = (int)$this->t1[$i];
871
- $t2[] = (int)$this->t2[$i];
872
- $t3[] = (int)$this->t3[$i];
873
- $sbox[] = (int)$this->sbox[$i];
874
- }
875
- }
876
-
877
- $state = array();
878
- $words = unpack('N*', $in);
879
-
880
- $c = $this->c;
881
- $w = $this->w;
882
- $Nb = $this->Nb;
883
- $Nr = $this->Nr;
884
-
885
- // addRoundKey
886
- $i = -1;
887
- foreach ($words as $word) {
888
- $state[] = $word ^ $w[0][++$i];
889
- }
890
-
891
- // fips-197.pdf#page=19, "Figure 5. Pseudo Code for the Cipher", states that this loop has four components -
892
- // subBytes, shiftRows, mixColumns, and addRoundKey. fips-197.pdf#page=30, "Implementation Suggestions Regarding
893
- // Various Platforms" suggests that performs enhanced implementations are described in Rijndael-ammended.pdf.
894
- // Rijndael-ammended.pdf#page=20, "Implementation aspects / 32-bit processor", discusses such an optimization.
895
- // Unfortunately, the description given there is not quite correct. Per aes.spec.v316.pdf#page=19 [1],
896
- // equation (7.4.7) is supposed to use addition instead of subtraction, so we'll do that here, as well.
897
-
898
- // [1] http://fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.v316.pdf
899
- $temp = array();
900
- for ($round = 1; $round < $Nr; ++$round) {
901
- $i = 0; // $c[0] == 0
902
- $j = $c[1];
903
- $k = $c[2];
904
- $l = $c[3];
905
-
906
- while ($i < $Nb) {
907
- $temp[$i] = $t0[$state[$i] >> 24 & 0x000000FF] ^
908
- $t1[$state[$j] >> 16 & 0x000000FF] ^
909
- $t2[$state[$k] >> 8 & 0x000000FF] ^
910
- $t3[$state[$l] & 0x000000FF] ^
911
- $w[$round][$i];
912
- ++$i;
913
- $j = ($j + 1) % $Nb;
914
- $k = ($k + 1) % $Nb;
915
- $l = ($l + 1) % $Nb;
916
- }
917
- $state = $temp;
918
- }
919
-
920
- // subWord
921
- for ($i = 0; $i < $Nb; ++$i) {
922
- $state[$i] = $sbox[$state[$i] & 0x000000FF] |
923
- ($sbox[$state[$i] >> 8 & 0x000000FF] << 8) |
924
- ($sbox[$state[$i] >> 16 & 0x000000FF] << 16) |
925
- ($sbox[$state[$i] >> 24 & 0x000000FF] << 24);
926
- }
927
-
928
- // shiftRows + addRoundKey
929
- $i = 0; // $c[0] == 0
930
- $j = $c[1];
931
- $k = $c[2];
932
- $l = $c[3];
933
- while ($i < $Nb) {
934
- $temp[$i] = ($state[$i] & 0xFF000000) ^
935
- ($state[$j] & 0x00FF0000) ^
936
- ($state[$k] & 0x0000FF00) ^
937
- ($state[$l] & 0x000000FF) ^
938
- $w[$Nr][$i];
939
- ++$i;
940
- $j = ($j + 1) % $Nb;
941
- $k = ($k + 1) % $Nb;
942
- $l = ($l + 1) % $Nb;
943
- }
944
-
945
- switch ($Nb) {
946
- case 8:
947
- return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6], $temp[7]);
948
- case 7:
949
- return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6]);
950
- case 6:
951
- return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5]);
952
- case 5:
953
- return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4]);
954
- default:
955
- return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3]);
956
- }
957
- }
958
-
959
- /**
960
- * Decrypts a block
961
- *
962
- * @access private
963
- * @param String $in
964
- * @return String
965
- */
966
- function _decryptBlock($in)
967
- {
968
- static $dt0, $dt1, $dt2, $dt3, $isbox;
969
- if (!$dt0) {
970
- for ($i = 0; $i < 256; ++$i) {
971
- $dt0[] = (int)$this->dt0[$i];
972
- $dt1[] = (int)$this->dt1[$i];
973
- $dt2[] = (int)$this->dt2[$i];
974
- $dt3[] = (int)$this->dt3[$i];
975
- $isbox[] = (int)$this->isbox[$i];
976
- }
977
- }
978
-
979
- $state = array();
980
- $words = unpack('N*', $in);
981
-
982
- $c = $this->c;
983
- $dw = $this->dw;
984
- $Nb = $this->Nb;
985
- $Nr = $this->Nr;
986
-
987
- // addRoundKey
988
- $i = -1;
989
- foreach ($words as $word) {
990
- $state[] = $word ^ $dw[$Nr][++$i];
991
- }
992
-
993
- $temp = array();
994
- for ($round = $Nr - 1; $round > 0; --$round) {
995
- $i = 0; // $c[0] == 0
996
- $j = $Nb - $c[1];
997
- $k = $Nb - $c[2];
998
- $l = $Nb - $c[3];
999
-
1000
- while ($i < $Nb) {
1001
- $temp[$i] = $dt0[$state[$i] >> 24 & 0x000000FF] ^
1002
- $dt1[$state[$j] >> 16 & 0x000000FF] ^
1003
- $dt2[$state[$k] >> 8 & 0x000000FF] ^
1004
- $dt3[$state[$l] & 0x000000FF] ^
1005
- $dw[$round][$i];
1006
- ++$i;
1007
- $j = ($j + 1) % $Nb;
1008
- $k = ($k + 1) % $Nb;
1009
- $l = ($l + 1) % $Nb;
1010
- }
1011
- $state = $temp;
1012
- }
1013
-
1014
- // invShiftRows + invSubWord + addRoundKey
1015
- $i = 0; // $c[0] == 0
1016
- $j = $Nb - $c[1];
1017
- $k = $Nb - $c[2];
1018
- $l = $Nb - $c[3];
1019
-
1020
- while ($i < $Nb) {
1021
- $word = ($state[$i] & 0xFF000000) |
1022
- ($state[$j] & 0x00FF0000) |
1023
- ($state[$k] & 0x0000FF00) |
1024
- ($state[$l] & 0x000000FF);
1025
-
1026
- $temp[$i] = $dw[0][$i] ^ ($isbox[$word & 0x000000FF] |
1027
- ($isbox[$word >> 8 & 0x000000FF] << 8) |
1028
- ($isbox[$word >> 16 & 0x000000FF] << 16) |
1029
- ($isbox[$word >> 24 & 0x000000FF] << 24));
1030
- ++$i;
1031
- $j = ($j + 1) % $Nb;
1032
- $k = ($k + 1) % $Nb;
1033
- $l = ($l + 1) % $Nb;
1034
- }
1035
-
1036
- switch ($Nb) {
1037
- case 8:
1038
- return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6], $temp[7]);
1039
- case 7:
1040
- return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6]);
1041
- case 6:
1042
- return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5]);
1043
- case 5:
1044
- return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4]);
1045
- default:
1046
- return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3]);
1047
- }
1048
- }
1049
-
1050
- /**
1051
- * Setup the key (expansion)
1052
- *
1053
- * @see Crypt_Base::_setupKey()
1054
- * @access private
1055
- */
1056
- function _setupKey()
1057
- {
1058
- // Each number in $rcon is equal to the previous number multiplied by two in Rijndael's finite field.
1059
- // See http://en.wikipedia.org/wiki/Finite_field_arithmetic#Multiplicative_inverse
1060
- static $rcon = array(0,
1061
- 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
1062
- 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000,
1063
- 0x6C000000, 0xD8000000, 0xAB000000, 0x4D000000, 0x9A000000,
1064
- 0x2F000000, 0x5E000000, 0xBC000000, 0x63000000, 0xC6000000,
1065
- 0x97000000, 0x35000000, 0x6A000000, 0xD4000000, 0xB3000000,
1066
- 0x7D000000, 0xFA000000, 0xEF000000, 0xC5000000, 0x91000000
1067
- );
1068
-
1069
- $this->key = str_pad(substr($this->key, 0, $this->key_size), $this->key_size, "\0");
1070
-
1071
- if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->key_size === $this->kl['key_size'] && $this->block_size === $this->kl['block_size']) {
1072
- // already expanded
1073
- return;
1074
- }
1075
- $this->kl = array('key' => $this->key, 'key_size' => $this->key_size, 'block_size' => $this->block_size);
1076
-
1077
- $this->Nk = $this->key_size >> 2;
1078
- // see Rijndael-ammended.pdf#page=44
1079
- $this->Nr = max($this->Nk, $this->Nb) + 6;
1080
-
1081
- // shift offsets for Nb = 5, 7 are defined in Rijndael-ammended.pdf#page=44,
1082
- // "Table 8: Shift offsets in Shiftrow for the alternative block lengths"
1083
- // shift offsets for Nb = 4, 6, 8 are defined in Rijndael-ammended.pdf#page=14,
1084
- // "Table 2: Shift offsets for different block lengths"
1085
- switch ($this->Nb) {
1086
- case 4:
1087
- case 5:
1088
- case 6:
1089
- $this->c = array(0, 1, 2, 3);
1090
- break;
1091
- case 7:
1092
- $this->c = array(0, 1, 2, 4);
1093
- break;
1094
- case 8:
1095
- $this->c = array(0, 1, 3, 4);
1096
- }
1097
-
1098
- $w = array_values(unpack('N*words', $this->key));
1099
-
1100
- $length = $this->Nb * ($this->Nr + 1);
1101
- for ($i = $this->Nk; $i < $length; $i++) {
1102
- $temp = $w[$i - 1];
1103
- if ($i % $this->Nk == 0) {
1104
- // according to <http://php.net/language.types.integer>, "the size of an integer is platform-dependent".
1105
- // on a 32-bit machine, it's 32-bits, and on a 64-bit machine, it's 64-bits. on a 32-bit machine,
1106
- // 0xFFFFFFFF << 8 == 0xFFFFFF00, but on a 64-bit machine, it equals 0xFFFFFFFF00. as such, doing 'and'
1107
- // with 0xFFFFFFFF (or 0xFFFFFF00) on a 32-bit machine is unnecessary, but on a 64-bit machine, it is.
1108
- $temp = (($temp << 8) & 0xFFFFFF00) | (($temp >> 24) & 0x000000FF); // rotWord
1109
- $temp = $this->_subWord($temp) ^ $rcon[$i / $this->Nk];
1110
- } else if ($this->Nk > 6 && $i % $this->Nk == 4) {
1111
- $temp = $this->_subWord($temp);
1112
- }
1113
- $w[$i] = $w[$i - $this->Nk] ^ $temp;
1114
- }
1115
-
1116
- // convert the key schedule from a vector of $Nb * ($Nr + 1) length to a matrix with $Nr + 1 rows and $Nb columns
1117
- // and generate the inverse key schedule. more specifically,
1118
- // according to <http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=23> (section 5.3.3),
1119
- // "The key expansion for the Inverse Cipher is defined as follows:
1120
- // 1. Apply the Key Expansion.
1121
- // 2. Apply InvMixColumn to all Round Keys except the first and the last one."
1122
- // also, see fips-197.pdf#page=27, "5.3.5 Equivalent Inverse Cipher"
1123
- $temp = $this->w = $this->dw = array();
1124
- for ($i = $row = $col = 0; $i < $length; $i++, $col++) {
1125
- if ($col == $this->Nb) {
1126
- if ($row == 0) {
1127
- $this->dw[0] = $this->w[0];
1128
- } else {
1129
- // subWord + invMixColumn + invSubWord = invMixColumn
1130
- $j = 0;
1131
- while ($j < $this->Nb) {
1132
- $dw = $this->_subWord($this->w[$row][$j]);
1133
- $temp[$j] = $this->dt0[$dw >> 24 & 0x000000FF] ^
1134
- $this->dt1[$dw >> 16 & 0x000000FF] ^
1135
- $this->dt2[$dw >> 8 & 0x000000FF] ^
1136
- $this->dt3[$dw & 0x000000FF];
1137
- $j++;
1138
- }
1139
- $this->dw[$row] = $temp;
1140
- }
1141
-
1142
- $col = 0;
1143
- $row++;
1144
- }
1145
- $this->w[$row][$col] = $w[$i];
1146
- }
1147
-
1148
- $this->dw[$row] = $this->w[$row];
1149
-
1150
- // In case of $this->use_inline_crypt === true we have to use 1-dim key arrays (both ascending)
1151
- if ($this->use_inline_crypt) {
1152
- $this->dw = array_reverse($this->dw);
1153
- $w = array_pop($this->w);
1154
- $dw = array_pop($this->dw);
1155
- foreach ($this->w as $r => $wr) {
1156
- foreach ($wr as $c => $wc) {
1157
- $w[] = $wc;
1158
- $dw[] = $this->dw[$r][$c];
1159
- }
1160
- }
1161
- $this->w = $w;
1162
- $this->dw = $dw;
1163
- }
1164
- }
1165
-
1166
- /**
1167
- * Performs S-Box substitutions
1168
- *
1169
- * @access private
1170
- * @param Integer $word
1171
- */
1172
- function _subWord($word)
1173
- {
1174
- $sbox = $this->sbox;
1175
-
1176
- return $sbox[$word & 0x000000FF] |
1177
- ($sbox[$word >> 8 & 0x000000FF] << 8) |
1178
- ($sbox[$word >> 16 & 0x000000FF] << 16) |
1179
- ($sbox[$word >> 24 & 0x000000FF] << 24);
1180
- }
1181
-
1182
- /**
1183
- * Setup the performance-optimized function for de/encrypt()
1184
- *
1185
- * @see Crypt_Base::_setupInlineCrypt()
1186
- * @access private
1187
- */
1188
- function _setupInlineCrypt()
1189
- {
1190
- // Note: _setupInlineCrypt() will be called only if $this->changed === true
1191
- // So here we are'nt under the same heavy timing-stress as we are in _de/encryptBlock() or de/encrypt().
1192
- // However...the here generated function- $code, stored as php callback in $this->inline_crypt, must work as fast as even possible.
1193
-
1194
- $lambda_functions =& Crypt_Rijndael::_getLambdaFunctions();
1195
-
1196
- // The first 10 generated $lambda_functions will use the key-words hardcoded for better performance.
1197
- // For memory reason we limit those ultra-optimized functions.
1198
- // After that, we use pure (extracted) integer vars for the key-words which is faster than accessing them via array.
1199
- if (count($lambda_functions) < 10) {
1200
- $w = $this->w;
1201
- $dw = $this->dw;
1202
- $init_encrypt = '';
1203
- $init_decrypt = '';
1204
- } else {
1205
- for ($i = 0, $cw = count($this->w); $i < $cw; ++$i) {
1206
- $w[] = '$w[' . $i . ']';
1207
- $dw[] = '$dw[' . $i . ']';
1208
- }
1209
- $init_encrypt = '$w = $self->w;';
1210
- $init_decrypt = '$dw = $self->dw;';
1211
- }
1212
-
1213
- $code_hash = md5(str_pad("Crypt_Rijndael, {$this->mode}, {$this->block_size}, ", 32, "\0") . implode(',', $w));
1214
-
1215
- if (!isset($lambda_functions[$code_hash])) {
1216
- $Nr = $this->Nr;
1217
- $Nb = $this->Nb;
1218
- $c = $this->c;
1219
-
1220
- // Generating encrypt code:
1221
- $init_encrypt.= '
1222
- static $t0, $t1, $t2, $t3, $sbox;
1223
- if (!$t0) {
1224
- for ($i = 0; $i < 256; ++$i) {
1225
- $t0[$i] = (int)$self->t0[$i];
1226
- $t1[$i] = (int)$self->t1[$i];
1227
- $t2[$i] = (int)$self->t2[$i];
1228
- $t3[$i] = (int)$self->t3[$i];
1229
- $sbox[$i] = (int)$self->sbox[$i];
1230
- }
1231
- }
1232
- ';
1233
-
1234
- $s = 'e';
1235
- $e = 's';
1236
- $wc = $Nb - 1;
1237
-
1238
- // Preround: addRoundKey
1239
- $encrypt_block = '$in = unpack("N*", $in);'."\n";
1240
- for ($i = 0; $i < $Nb; ++$i) {
1241
- $encrypt_block .= '$s'.$i.' = $in['.($i + 1).'] ^ '.$w[++$wc].";\n";
1242
- }
1243
-
1244
- // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey
1245
- for ($round = 1; $round < $Nr; ++$round) {
1246
- list($s, $e) = array($e, $s);
1247
- for ($i = 0; $i < $Nb; ++$i) {
1248
- $encrypt_block.=
1249
- '$'.$e.$i.' =
1250
- $t0[($'.$s.$i .' >> 24) & 0xff] ^
1251
- $t1[($'.$s.(($i + $c[1]) % $Nb).' >> 16) & 0xff] ^
1252
- $t2[($'.$s.(($i + $c[2]) % $Nb).' >> 8) & 0xff] ^
1253
- $t3[ $'.$s.(($i + $c[3]) % $Nb).' & 0xff] ^
1254
- '.$w[++$wc].";\n";
1255
- }
1256
- }
1257
-
1258
- // Finalround: subWord + shiftRows + addRoundKey
1259
- for ($i = 0; $i < $Nb; ++$i) {
1260
- $encrypt_block.=
1261
- '$'.$e.$i.' =
1262
- $sbox[ $'.$e.$i.' & 0xff] |
1263
- ($sbox[($'.$e.$i.' >> 8) & 0xff] << 8) |
1264
- ($sbox[($'.$e.$i.' >> 16) & 0xff] << 16) |
1265
- ($sbox[($'.$e.$i.' >> 24) & 0xff] << 24);'."\n";
1266
- }
1267
- $encrypt_block .= '$in = pack("N*"'."\n";
1268
- for ($i = 0; $i < $Nb; ++$i) {
1269
- $encrypt_block.= ',
1270
- ($'.$e.$i .' & 0xFF000000) ^
1271
- ($'.$e.(($i + $c[1]) % $Nb).' & 0x00FF0000) ^
1272
- ($'.$e.(($i + $c[2]) % $Nb).' & 0x0000FF00) ^
1273
- ($'.$e.(($i + $c[3]) % $Nb).' & 0x000000FF) ^
1274
- '.$w[$i]."\n";
1275
- }
1276
- $encrypt_block .= ');';
1277
-
1278
- // Generating decrypt code:
1279
- $init_decrypt.= '
1280
- static $dt0, $dt1, $dt2, $dt3, $isbox;
1281
- if (!$dt0) {
1282
- for ($i = 0; $i < 256; ++$i) {
1283
- $dt0[$i] = (int)$self->dt0[$i];
1284
- $dt1[$i] = (int)$self->dt1[$i];
1285
- $dt2[$i] = (int)$self->dt2[$i];
1286
- $dt3[$i] = (int)$self->dt3[$i];
1287
- $isbox[$i] = (int)$self->isbox[$i];
1288
- }
1289
- }
1290
- ';
1291
-
1292
- $s = 'e';
1293
- $e = 's';
1294
- $wc = $Nb - 1;
1295
-
1296
- // Preround: addRoundKey
1297
- $decrypt_block = '$in = unpack("N*", $in);'."\n";
1298
- for ($i = 0; $i < $Nb; ++$i) {
1299
- $decrypt_block .= '$s'.$i.' = $in['.($i + 1).'] ^ '.$dw[++$wc].';'."\n";
1300
- }
1301
-
1302
- // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey
1303
- for ($round = 1; $round < $Nr; ++$round) {
1304
- list($s, $e) = array($e, $s);
1305
- for ($i = 0; $i < $Nb; ++$i) {
1306
- $decrypt_block.=
1307
- '$'.$e.$i.' =
1308
- $dt0[($'.$s.$i .' >> 24) & 0xff] ^
1309
- $dt1[($'.$s.(($Nb + $i - $c[1]) % $Nb).' >> 16) & 0xff] ^
1310
- $dt2[($'.$s.(($Nb + $i - $c[2]) % $Nb).' >> 8) & 0xff] ^
1311
- $dt3[ $'.$s.(($Nb + $i - $c[3]) % $Nb).' & 0xff] ^
1312
- '.$dw[++$wc].";\n";
1313
- }
1314
- }
1315
-
1316
- // Finalround: subWord + shiftRows + addRoundKey
1317
- for ($i = 0; $i < $Nb; ++$i) {
1318
- $decrypt_block.=
1319
- '$'.$e.$i.' =
1320
- $isbox[ $'.$e.$i.' & 0xff] |
1321
- ($isbox[($'.$e.$i.' >> 8) & 0xff] << 8) |
1322
- ($isbox[($'.$e.$i.' >> 16) & 0xff] << 16) |
1323
- ($isbox[($'.$e.$i.' >> 24) & 0xff] << 24);'."\n";
1324
- }
1325
- $decrypt_block .= '$in = pack("N*"'."\n";
1326
- for ($i = 0; $i < $Nb; ++$i) {
1327
- $decrypt_block.= ',
1328
- ($'.$e.$i. ' & 0xFF000000) ^
1329
- ($'.$e.(($Nb + $i - $c[1]) % $Nb).' & 0x00FF0000) ^
1330
- ($'.$e.(($Nb + $i - $c[2]) % $Nb).' & 0x0000FF00) ^
1331
- ($'.$e.(($Nb + $i - $c[3]) % $Nb).' & 0x000000FF) ^
1332
- '.$dw[$i]."\n";
1333
- }
1334
- $decrypt_block .= ');';
1335
-
1336
- $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
1337
- array(
1338
- 'init_crypt' => '',
1339
- 'init_encrypt' => $init_encrypt,
1340
- 'init_decrypt' => $init_decrypt,
1341
- 'encrypt_block' => $encrypt_block,
1342
- 'decrypt_block' => $decrypt_block
1343
- )
1344
- );
1345
- }
1346
- $this->inline_crypt = $lambda_functions[$code_hash];
1347
- }
1348
- }
1
+ <?php
2
+
3
+ /**
4
+ * Pure-PHP implementation of Rijndael.
5
+ *
6
+ * Uses mcrypt, if available/possible, and an internal implementation, otherwise.
7
+ *
8
+ * PHP versions 4 and 5
9
+ *
10
+ * If {@link Crypt_Rijndael::setBlockLength() setBlockLength()} isn't called, it'll be assumed to be 128 bits. If
11
+ * {@link Crypt_Rijndael::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
12
+ * {@link Crypt_Rijndael::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's
13
+ * 136-bits it'll be null-padded to 192-bits and 192 bits will be the key length until
14
+ * {@link Crypt_Rijndael::setKey() setKey()} is called, again, at which point, it'll be recalculated.
15
+ *
16
+ * Not all Rijndael implementations may support 160-bits or 224-bits as the block length / key length. mcrypt, for example,
17
+ * does not. AES, itself, only supports block lengths of 128 and key lengths of 128, 192, and 256.
18
+ * {@link http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=10 Rijndael-ammended.pdf#page=10} defines the
19
+ * algorithm for block lengths of 192 and 256 but not for block lengths / key lengths of 160 and 224. Indeed, 160 and 224
20
+ * are first defined as valid key / block lengths in
21
+ * {@link http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=44 Rijndael-ammended.pdf#page=44}:
22
+ * Extensions: Other block and Cipher Key lengths.
23
+ * Note: Use of 160/224-bit Keys must be explicitly set by setKeyLength(160) respectively setKeyLength(224).
24
+ *
25
+ * {@internal The variable names are the same as those in
26
+ * {@link http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf#page=10 fips-197.pdf#page=10}.}}
27
+ *
28
+ * Here's a short example of how to use this library:
29
+ * <code>
30
+ * <?php
31
+ * include 'Crypt/Rijndael.php';
32
+ *
33
+ * $rijndael = new Crypt_Rijndael();
34
+ *
35
+ * $rijndael->setKey('abcdefghijklmnop');
36
+ *
37
+ * $size = 10 * 1024;
38
+ * $plaintext = '';
39
+ * for ($i = 0; $i < $size; $i++) {
40
+ * $plaintext.= 'a';
41
+ * }
42
+ *
43
+ * echo $rijndael->decrypt($rijndael->encrypt($plaintext));
44
+ * ?>
45
+ * </code>
46
+ *
47
+ * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
48
+ * of this software and associated documentation files (the "Software"), to deal
49
+ * in the Software without restriction, including without limitation the rights
50
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
51
+ * copies of the Software, and to permit persons to whom the Software is
52
+ * furnished to do so, subject to the following conditions:
53
+ *
54
+ * The above copyright notice and this permission notice shall be included in
55
+ * all copies or substantial portions of the Software.
56
+ *
57
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
58
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
59
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
60
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
61
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
62
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
63
+ * THE SOFTWARE.
64
+ *
65
+ * @category Crypt
66
+ * @package Crypt_Rijndael
67
+ * @author Jim Wigginton <terrafrost@php.net>
68
+ * @copyright 2008 Jim Wigginton
69
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
70
+ * @link http://phpseclib.sourceforge.net
71
+ */
72
+
73
+ /**
74
+ * Include Crypt_Base
75
+ *
76
+ * Base cipher class
77
+ */
78
+ if (!class_exists('Crypt_Base')) {
79
+ include_once 'Base.php';
80
+ }
81
+
82
+ /**#@+
83
+ * @access public
84
+ * @see Crypt_Rijndael::encrypt()
85
+ * @see Crypt_Rijndael::decrypt()
86
+ */
87
+ /**
88
+ * Encrypt / decrypt using the Counter mode.
89
+ *
90
+ * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
91
+ *
92
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
93
+ */
94
+ define('CRYPT_RIJNDAEL_MODE_CTR', CRYPT_MODE_CTR);
95
+ /**
96
+ * Encrypt / decrypt using the Electronic Code Book mode.
97
+ *
98
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
99
+ */
100
+ define('CRYPT_RIJNDAEL_MODE_ECB', CRYPT_MODE_ECB);
101
+ /**
102
+ * Encrypt / decrypt using the Code Book Chaining mode.
103
+ *
104
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
105
+ */
106
+ define('CRYPT_RIJNDAEL_MODE_CBC', CRYPT_MODE_CBC);
107
+ /**
108
+ * Encrypt / decrypt using the Cipher Feedback mode.
109
+ *
110
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
111
+ */
112
+ define('CRYPT_RIJNDAEL_MODE_CFB', CRYPT_MODE_CFB);
113
+ /**
114
+ * Encrypt / decrypt using the Cipher Feedback mode.
115
+ *
116
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
117
+ */
118
+ define('CRYPT_RIJNDAEL_MODE_OFB', CRYPT_MODE_OFB);
119
+ /**#@-*/
120
+
121
+ /**
122
+ * Pure-PHP implementation of Rijndael.
123
+ *
124
+ * @package Crypt_Rijndael
125
+ * @author Jim Wigginton <terrafrost@php.net>
126
+ * @access public
127
+ */
128
+ class Crypt_Rijndael extends Crypt_Base
129
+ {
130
+ /**
131
+ * The default password key_size used by setPassword()
132
+ *
133
+ * @see Crypt_Base::password_key_size
134
+ * @see Crypt_Base::setPassword()
135
+ * @var Integer
136
+ * @access private
137
+ */
138
+ var $password_key_size = 16;
139
+
140
+ /**
141
+ * The namespace used by the cipher for its constants.
142
+ *
143
+ * @see Crypt_Base::const_namespace
144
+ * @var String
145
+ * @access private
146
+ */
147
+ var $const_namespace = 'RIJNDAEL';
148
+
149
+ /**
150
+ * The mcrypt specific name of the cipher
151
+ *
152
+ * Mcrypt is useable for 128/192/256-bit $block_size/$key_size. For 160/224 not.
153
+ * Crypt_Rijndael determines automatically whether mcrypt is useable
154
+ * or not for the current $block_size/$key_size.
155
+ * In case of, $cipher_name_mcrypt will be set dynamically at run time accordingly.
156
+ *
157
+ * @see Crypt_Base::cipher_name_mcrypt
158
+ * @see Crypt_Base::engine
159
+ * @see isValidEngine()
160
+ * @var String
161
+ * @access private
162
+ */
163
+ var $cipher_name_mcrypt = 'rijndael-128';
164
+
165
+ /**
166
+ * The default salt used by setPassword()
167
+ *
168
+ * @see Crypt_Base::password_default_salt
169
+ * @see Crypt_Base::setPassword()
170
+ * @var String
171
+ * @access private
172
+ */
173
+ var $password_default_salt = 'phpseclib';
174
+
175
+ /**
176
+ * Has the key length explicitly been set or should it be derived from the key, itself?
177
+ *
178
+ * @see setKeyLength()
179
+ * @var Boolean
180
+ * @access private
181
+ */
182
+ var $explicit_key_length = false;
183
+
184
+ /**
185
+ * The Key Schedule
186
+ *
187
+ * @see _setup()
188
+ * @var Array
189
+ * @access private
190
+ */
191
+ var $w;
192
+
193
+ /**
194
+ * The Inverse Key Schedule
195
+ *
196
+ * @see _setup()
197
+ * @var Array
198
+ * @access private
199
+ */
200
+ var $dw;
201
+
202
+ /**
203
+ * The Block Length divided by 32
204
+ *
205
+ * @see setBlockLength()
206
+ * @var Integer
207
+ * @access private
208
+ * @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4. Exists in conjunction with $block_size
209
+ * because the encryption / decryption / key schedule creation requires this number and not $block_size. We could
210
+ * derive this from $block_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
211
+ * of that, we'll just precompute it once.
212
+ */
213
+ var $Nb = 4;
214
+
215
+ /**
216
+ * The Key Length
217
+ *
218
+ * @see setKeyLength()
219
+ * @var Integer
220
+ * @access private
221
+ * @internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk
222
+ * because the encryption / decryption / key schedule creation requires this number and not $key_size. We could
223
+ * derive this from $key_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
224
+ * of that, we'll just precompute it once.
225
+ */
226
+ var $key_size = 16;
227
+
228
+ /**
229
+ * The Key Length divided by 32
230
+ *
231
+ * @see setKeyLength()
232
+ * @var Integer
233
+ * @access private
234
+ * @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4
235
+ */
236
+ var $Nk = 4;
237
+
238
+ /**
239
+ * The Number of Rounds
240
+ *
241
+ * @var Integer
242
+ * @access private
243
+ * @internal The max value is 14, the min value is 10.
244
+ */
245
+ var $Nr;
246
+
247
+ /**
248
+ * Shift offsets
249
+ *
250
+ * @var Array
251
+ * @access private
252
+ */
253
+ var $c;
254
+
255
+ /**
256
+ * Holds the last used key- and block_size information
257
+ *
258
+ * @var Array
259
+ * @access private
260
+ */
261
+ var $kl;
262
+
263
+ /**
264
+ * Default Constructor.
265
+ *
266
+ * Determines whether or not the mcrypt extension should be used.
267
+ *
268
+ * $mode could be:
269
+ *
270
+ * - CRYPT_RIJNDAEL_MODE_ECB
271
+ *
272
+ * - CRYPT_RIJNDAEL_MODE_CBC
273
+ *
274
+ * - CRYPT_RIJNDAEL_MODE_CTR
275
+ *
276
+ * - CRYPT_RIJNDAEL_MODE_CFB
277
+ *
278
+ * - CRYPT_RIJNDAEL_MODE_OFB
279
+ *
280
+ * If not explictly set, CRYPT_RIJNDAEL_MODE_CBC will be used.
281
+ *
282
+ * @see Crypt_Base::Crypt_Base()
283
+ * @param optional Integer $mode
284
+ * @access public
285
+ */
286
+ function Crypt_Rijndael($mode = CRYPT_RIJNDAEL_MODE_CBC)
287
+ {
288
+ parent::Crypt_Base($mode);
289
+ }
290
+
291
+ /**
292
+ * Sets the key.
293
+ *
294
+ * Keys can be of any length. Rijndael, itself, requires the use of a key that's between 128-bits and 256-bits long and
295
+ * whose length is a multiple of 32. If the key is less than 256-bits and the key length isn't set, we round the length
296
+ * up to the closest valid key length, padding $key with null bytes. If the key is more than 256-bits, we trim the
297
+ * excess bits.
298
+ *
299
+ * If the key is not explicitly set, it'll be assumed to be all null bytes.
300
+ *
301
+ * Note: 160/224-bit keys must explicitly set by setKeyLength(), otherwise they will be round/pad up to 192/256 bits.
302
+ *
303
+ * @see Crypt_Base:setKey()
304
+ * @see setKeyLength()
305
+ * @access public
306
+ * @param String $key
307
+ */
308
+ function setKey($key)
309
+ {
310
+ if (!$this->explicit_key_length) {
311
+ $length = strlen($key);
312
+ switch (true) {
313
+ case $length <= 16:
314
+ $this->key_size = 16;
315
+ break;
316
+ case $length <= 20:
317
+ $this->key_size = 20;
318
+ break;
319
+ case $length <= 24:
320
+ $this->key_size = 24;
321
+ break;
322
+ case $length <= 28:
323
+ $this->key_size = 28;
324
+ break;
325
+ default:
326
+ $this->key_size = 32;
327
+ }
328
+ }
329
+ parent::setKey($key);
330
+ }
331
+
332
+ /**
333
+ * Sets the key length
334
+ *
335
+ * Valid key lengths are 128, 160, 192, 224, and 256. If the length is less than 128, it will be rounded up to
336
+ * 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount.
337
+ *
338
+ * Note: phpseclib extends Rijndael (and AES) for using 160- and 224-bit keys but they are officially not defined
339
+ * and the most (if not all) implementations are not able using 160/224-bit keys but round/pad them up to
340
+ * 192/256 bits as, for example, mcrypt will do.
341
+ *
342
+ * That said, if you want be compatible with other Rijndael and AES implementations,
343
+ * you should not setKeyLength(160) or setKeyLength(224).
344
+ *
345
+ * Additional: In case of 160- and 224-bit keys, phpseclib will/can, for that reason, not use
346
+ * the mcrypt php extension, even if available.
347
+ * This results then in slower encryption.
348
+ *
349
+ * @access public
350
+ * @param Integer $length
351
+ */
352
+ function setKeyLength($length)
353
+ {
354
+ switch (true) {
355
+ case $length == 160:
356
+ $this->key_size = 20;
357
+ break;
358
+ case $length == 224:
359
+ $this->key_size = 28;
360
+ break;
361
+ case $length <= 128:
362
+ $this->key_size = 16;
363
+ break;
364
+ case $length <= 192:
365
+ $this->key_size = 24;
366
+ break;
367
+ default:
368
+ $this->key_size = 32;
369
+ }
370
+
371
+ $this->explicit_key_length = true;
372
+ $this->changed = true;
373
+ $this->_setEngine();
374
+ }
375
+
376
+ /**
377
+ * Sets the block length
378
+ *
379
+ * Valid block lengths are 128, 160, 192, 224, and 256. If the length is less than 128, it will be rounded up to
380
+ * 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount.
381
+ *
382
+ * @access public
383
+ * @param Integer $length
384
+ */
385
+ function setBlockLength($length)
386
+ {
387
+ $length >>= 5;
388
+ if ($length > 8) {
389
+ $length = 8;
390
+ } else if ($length < 4) {
391
+ $length = 4;
392
+ }
393
+ $this->Nb = $length;
394
+ $this->block_size = $length << 2;
395
+ $this->changed = true;
396
+ $this->_setEngine();
397
+ }
398
+
399
+ /**
400
+ * Test for engine validity
401
+ *
402
+ * This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine()
403
+ *
404
+ * @see Crypt_Base::Crypt_Base()
405
+ * @param Integer $engine
406
+ * @access public
407
+ * @return Boolean
408
+ */
409
+ function isValidEngine($engine)
410
+ {
411
+ switch ($engine) {
412
+ case CRYPT_ENGINE_OPENSSL:
413
+ if ($this->block_size != 16) {
414
+ return false;
415
+ }
416
+ $this->cipher_name_openssl_ecb = 'aes-' . ($this->key_size << 3) . '-ecb';
417
+ $this->cipher_name_openssl = 'aes-' . ($this->key_size << 3) . '-' . $this->_openssl_translate_mode();
418
+ break;
419
+ case CRYPT_ENGINE_MCRYPT:
420
+ $this->cipher_name_mcrypt = 'rijndael-' . ($this->block_size << 3);
421
+ if ($this->key_size % 8) { // is it a 160/224-bit key?
422
+ // mcrypt is not usable for them, only for 128/192/256-bit keys
423
+ return false;
424
+ }
425
+ }
426
+
427
+ return parent::isValidEngine($engine);
428
+ }
429
+
430
+ /**
431
+ * Setup the CRYPT_ENGINE_MCRYPT $engine
432
+ *
433
+ * @see Crypt_Base::_setupMcrypt()
434
+ * @access private
435
+ */
436
+ function _setupMcrypt()
437
+ {
438
+ $this->key = str_pad(substr($this->key, 0, $this->key_size), $this->key_size, "\0");
439
+ parent::_setupMcrypt();
440
+ }
441
+
442
+ /**
443
+ * Encrypts a block
444
+ *
445
+ * @access private
446
+ * @param String $in
447
+ * @return String
448
+ */
449
+ function _encryptBlock($in)
450
+ {
451
+ static $tables;
452
+ if (empty($tables)) {
453
+ $tables = &$this->_getTables();
454
+ }
455
+ $t0 = $tables[0];
456
+ $t1 = $tables[1];
457
+ $t2 = $tables[2];
458
+ $t3 = $tables[3];
459
+ $sbox = $tables[4];
460
+
461
+ $state = array();
462
+ $words = unpack('N*', $in);
463
+
464
+ $c = $this->c;
465
+ $w = $this->w;
466
+ $Nb = $this->Nb;
467
+ $Nr = $this->Nr;
468
+
469
+ // addRoundKey
470
+ $wc = $Nb - 1;
471
+ foreach ($words as $word) {
472
+ $state[] = $word ^ $w[++$wc];
473
+ }
474
+
475
+ // fips-197.pdf#page=19, "Figure 5. Pseudo Code for the Cipher", states that this loop has four components -
476
+ // subBytes, shiftRows, mixColumns, and addRoundKey. fips-197.pdf#page=30, "Implementation Suggestions Regarding
477
+ // Various Platforms" suggests that performs enhanced implementations are described in Rijndael-ammended.pdf.
478
+ // Rijndael-ammended.pdf#page=20, "Implementation aspects / 32-bit processor", discusses such an optimization.
479
+ // Unfortunately, the description given there is not quite correct. Per aes.spec.v316.pdf#page=19 [1],
480
+ // equation (7.4.7) is supposed to use addition instead of subtraction, so we'll do that here, as well.
481
+
482
+ // [1] http://fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.v316.pdf
483
+ $temp = array();
484
+ for ($round = 1; $round < $Nr; ++$round) {
485
+ $i = 0; // $c[0] == 0
486
+ $j = $c[1];
487
+ $k = $c[2];
488
+ $l = $c[3];
489
+
490
+ while ($i < $Nb) {
491
+ $temp[$i] = $t0[$state[$i] >> 24 & 0x000000FF] ^
492
+ $t1[$state[$j] >> 16 & 0x000000FF] ^
493
+ $t2[$state[$k] >> 8 & 0x000000FF] ^
494
+ $t3[$state[$l] & 0x000000FF] ^
495
+ $w[++$wc];
496
+ ++$i;
497
+ $j = ($j + 1) % $Nb;
498
+ $k = ($k + 1) % $Nb;
499
+ $l = ($l + 1) % $Nb;
500
+ }
501
+ $state = $temp;
502
+ }
503
+
504
+ // subWord
505
+ for ($i = 0; $i < $Nb; ++$i) {
506
+ $state[$i] = $sbox[$state[$i] & 0x000000FF] |
507
+ ($sbox[$state[$i] >> 8 & 0x000000FF] << 8) |
508
+ ($sbox[$state[$i] >> 16 & 0x000000FF] << 16) |
509
+ ($sbox[$state[$i] >> 24 & 0x000000FF] << 24);
510
+ }
511
+
512
+ // shiftRows + addRoundKey
513
+ $i = 0; // $c[0] == 0
514
+ $j = $c[1];
515
+ $k = $c[2];
516
+ $l = $c[3];
517
+ while ($i < $Nb) {
518
+ $temp[$i] = ($state[$i] & 0xFF000000) ^
519
+ ($state[$j] & 0x00FF0000) ^
520
+ ($state[$k] & 0x0000FF00) ^
521
+ ($state[$l] & 0x000000FF) ^
522
+ $w[$i];
523
+ ++$i;
524
+ $j = ($j + 1) % $Nb;
525
+ $k = ($k + 1) % $Nb;
526
+ $l = ($l + 1) % $Nb;
527
+ }
528
+
529
+ switch ($Nb) {
530
+ case 8:
531
+ return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6], $temp[7]);
532
+ case 7:
533
+ return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6]);
534
+ case 6:
535
+ return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5]);
536
+ case 5:
537
+ return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4]);
538
+ default:
539
+ return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3]);
540
+ }
541
+ }
542
+
543
+ /**
544
+ * Decrypts a block
545
+ *
546
+ * @access private
547
+ * @param String $in
548
+ * @return String
549
+ */
550
+ function _decryptBlock($in)
551
+ {
552
+ static $invtables;
553
+ if (empty($invtables)) {
554
+ $invtables = &$this->_getInvTables();
555
+ }
556
+ $dt0 = $invtables[0];
557
+ $dt1 = $invtables[1];
558
+ $dt2 = $invtables[2];
559
+ $dt3 = $invtables[3];
560
+ $isbox = $invtables[4];
561
+
562
+ $state = array();
563
+ $words = unpack('N*', $in);
564
+
565
+ $c = $this->c;
566
+ $dw = $this->dw;
567
+ $Nb = $this->Nb;
568
+ $Nr = $this->Nr;
569
+
570
+ // addRoundKey
571
+ $wc = $Nb - 1;
572
+ foreach ($words as $word) {
573
+ $state[] = $word ^ $dw[++$wc];
574
+ }
575
+
576
+ $temp = array();
577
+ for ($round = $Nr - 1; $round > 0; --$round) {
578
+ $i = 0; // $c[0] == 0
579
+ $j = $Nb - $c[1];
580
+ $k = $Nb - $c[2];
581
+ $l = $Nb - $c[3];
582
+
583
+ while ($i < $Nb) {
584
+ $temp[$i] = $dt0[$state[$i] >> 24 & 0x000000FF] ^
585
+ $dt1[$state[$j] >> 16 & 0x000000FF] ^
586
+ $dt2[$state[$k] >> 8 & 0x000000FF] ^
587
+ $dt3[$state[$l] & 0x000000FF] ^
588
+ $dw[++$wc];
589
+ ++$i;
590
+ $j = ($j + 1) % $Nb;
591
+ $k = ($k + 1) % $Nb;
592
+ $l = ($l + 1) % $Nb;
593
+ }
594
+ $state = $temp;
595
+ }
596
+
597
+ // invShiftRows + invSubWord + addRoundKey
598
+ $i = 0; // $c[0] == 0
599
+ $j = $Nb - $c[1];
600
+ $k = $Nb - $c[2];
601
+ $l = $Nb - $c[3];
602
+
603
+ while ($i < $Nb) {
604
+ $word = ($state[$i] & 0xFF000000) |
605
+ ($state[$j] & 0x00FF0000) |
606
+ ($state[$k] & 0x0000FF00) |
607
+ ($state[$l] & 0x000000FF);
608
+
609
+ $temp[$i] = $dw[$i] ^ ($isbox[$word & 0x000000FF] |
610
+ ($isbox[$word >> 8 & 0x000000FF] << 8) |
611
+ ($isbox[$word >> 16 & 0x000000FF] << 16) |
612
+ ($isbox[$word >> 24 & 0x000000FF] << 24));
613
+ ++$i;
614
+ $j = ($j + 1) % $Nb;
615
+ $k = ($k + 1) % $Nb;
616
+ $l = ($l + 1) % $Nb;
617
+ }
618
+
619
+ switch ($Nb) {
620
+ case 8:
621
+ return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6], $temp[7]);
622
+ case 7:
623
+ return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6]);
624
+ case 6:
625
+ return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5]);
626
+ case 5:
627
+ return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4]);
628
+ default:
629
+ return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3]);
630
+ }
631
+ }
632
+
633
+ /**
634
+ * Setup the key (expansion)
635
+ *
636
+ * @see Crypt_Base::_setupKey()
637
+ * @access private
638
+ */
639
+ function _setupKey()
640
+ {
641
+ // Each number in $rcon is equal to the previous number multiplied by two in Rijndael's finite field.
642
+ // See http://en.wikipedia.org/wiki/Finite_field_arithmetic#Multiplicative_inverse
643
+ static $rcon = array(0,
644
+ 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
645
+ 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000,
646
+ 0x6C000000, 0xD8000000, 0xAB000000, 0x4D000000, 0x9A000000,
647
+ 0x2F000000, 0x5E000000, 0xBC000000, 0x63000000, 0xC6000000,
648
+ 0x97000000, 0x35000000, 0x6A000000, 0xD4000000, 0xB3000000,
649
+ 0x7D000000, 0xFA000000, 0xEF000000, 0xC5000000, 0x91000000
650
+ );
651
+
652
+ $this->key = str_pad(substr($this->key, 0, $this->key_size), $this->key_size, "\0");
653
+
654
+ if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->key_size === $this->kl['key_size'] && $this->block_size === $this->kl['block_size']) {
655
+ // already expanded
656
+ return;
657
+ }
658
+ $this->kl = array('key' => $this->key, 'key_size' => $this->key_size, 'block_size' => $this->block_size);
659
+
660
+ $this->Nk = $this->key_size >> 2;
661
+ // see Rijndael-ammended.pdf#page=44
662
+ $this->Nr = max($this->Nk, $this->Nb) + 6;
663
+
664
+ // shift offsets for Nb = 5, 7 are defined in Rijndael-ammended.pdf#page=44,
665
+ // "Table 8: Shift offsets in Shiftrow for the alternative block lengths"
666
+ // shift offsets for Nb = 4, 6, 8 are defined in Rijndael-ammended.pdf#page=14,
667
+ // "Table 2: Shift offsets for different block lengths"
668
+ switch ($this->Nb) {
669
+ case 4:
670
+ case 5:
671
+ case 6:
672
+ $this->c = array(0, 1, 2, 3);
673
+ break;
674
+ case 7:
675
+ $this->c = array(0, 1, 2, 4);
676
+ break;
677
+ case 8:
678
+ $this->c = array(0, 1, 3, 4);
679
+ }
680
+
681
+ $w = array_values(unpack('N*words', $this->key));
682
+
683
+ $length = $this->Nb * ($this->Nr + 1);
684
+ for ($i = $this->Nk; $i < $length; $i++) {
685
+ $temp = $w[$i - 1];
686
+ if ($i % $this->Nk == 0) {
687
+ // according to <http://php.net/language.types.integer>, "the size of an integer is platform-dependent".
688
+ // on a 32-bit machine, it's 32-bits, and on a 64-bit machine, it's 64-bits. on a 32-bit machine,
689
+ // 0xFFFFFFFF << 8 == 0xFFFFFF00, but on a 64-bit machine, it equals 0xFFFFFFFF00. as such, doing 'and'
690
+ // with 0xFFFFFFFF (or 0xFFFFFF00) on a 32-bit machine is unnecessary, but on a 64-bit machine, it is.
691
+ $temp = (($temp << 8) & 0xFFFFFF00) | (($temp >> 24) & 0x000000FF); // rotWord
692
+ $temp = $this->_subWord($temp) ^ $rcon[$i / $this->Nk];
693
+ } else if ($this->Nk > 6 && $i % $this->Nk == 4) {
694
+ $temp = $this->_subWord($temp);
695
+ }
696
+ $w[$i] = $w[$i - $this->Nk] ^ $temp;
697
+ }
698
+
699
+ // convert the key schedule from a vector of $Nb * ($Nr + 1) length to a matrix with $Nr + 1 rows and $Nb columns
700
+ // and generate the inverse key schedule. more specifically,
701
+ // according to <http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=23> (section 5.3.3),
702
+ // "The key expansion for the Inverse Cipher is defined as follows:
703
+ // 1. Apply the Key Expansion.
704
+ // 2. Apply InvMixColumn to all Round Keys except the first and the last one."
705
+ // also, see fips-197.pdf#page=27, "5.3.5 Equivalent Inverse Cipher"
706
+ list($dt0, $dt1, $dt2, $dt3) = $this->_getInvTables();
707
+ $temp = $this->w = $this->dw = array();
708
+ for ($i = $row = $col = 0; $i < $length; $i++, $col++) {
709
+ if ($col == $this->Nb) {
710
+ if ($row == 0) {
711
+ $this->dw[0] = $this->w[0];
712
+ } else {
713
+ // subWord + invMixColumn + invSubWord = invMixColumn
714
+ $j = 0;
715
+ while ($j < $this->Nb) {
716
+ $dw = $this->_subWord($this->w[$row][$j]);
717
+ $temp[$j] = $dt0[$dw >> 24 & 0x000000FF] ^
718
+ $dt1[$dw >> 16 & 0x000000FF] ^
719
+ $dt2[$dw >> 8 & 0x000000FF] ^
720
+ $dt3[$dw & 0x000000FF];
721
+ $j++;
722
+ }
723
+ $this->dw[$row] = $temp;
724
+ }
725
+
726
+ $col = 0;
727
+ $row++;
728
+ }
729
+ $this->w[$row][$col] = $w[$i];
730
+ }
731
+
732
+ $this->dw[$row] = $this->w[$row];
733
+
734
+ // Converting to 1-dim key arrays (both ascending)
735
+ $this->dw = array_reverse($this->dw);
736
+ $w = array_pop($this->w);
737
+ $dw = array_pop($this->dw);
738
+ foreach ($this->w as $r => $wr) {
739
+ foreach ($wr as $c => $wc) {
740
+ $w[] = $wc;
741
+ $dw[] = $this->dw[$r][$c];
742
+ }
743
+ }
744
+ $this->w = $w;
745
+ $this->dw = $dw;
746
+ }
747
+
748
+ /**
749
+ * Performs S-Box substitutions
750
+ *
751
+ * @access private
752
+ * @param Integer $word
753
+ */
754
+ function _subWord($word)
755
+ {
756
+ static $sbox;
757
+ if (empty($sbox)) {
758
+ list(,,,, $sbox) = $this->_getTables();
759
+ }
760
+
761
+ return $sbox[$word & 0x000000FF] |
762
+ ($sbox[$word >> 8 & 0x000000FF] << 8) |
763
+ ($sbox[$word >> 16 & 0x000000FF] << 16) |
764
+ ($sbox[$word >> 24 & 0x000000FF] << 24);
765
+ }
766
+
767
+ /**
768
+ * Provides the mixColumns and sboxes tables
769
+ *
770
+ * @see Crypt_Rijndael:_encryptBlock()
771
+ * @see Crypt_Rijndael:_setupInlineCrypt()
772
+ * @see Crypt_Rijndael:_subWord()
773
+ * @access private
774
+ * @return Array &$tables
775
+ */
776
+ function &_getTables()
777
+ {
778
+ static $tables;
779
+ if (empty($tables)) {
780
+ // according to <http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=19> (section 5.2.1),
781
+ // precomputed tables can be used in the mixColumns phase. in that example, they're assigned t0...t3, so
782
+ // those are the names we'll use.
783
+ $t3 = array_map('intval', array(
784
+ // with array_map('intval', ...) we ensure we have only int's and not
785
+ // some slower floats converted by php automatically on high values
786
+ 0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491,
787
+ 0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC,
788
+ 0xCACA458F, 0x82829D1F, 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB,
789
+ 0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, 0x727296E4, 0xC0C05B9B,
790
+ 0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83,
791
+ 0x34345C68, 0xA5A5F451, 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A,
792
+ 0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, 0x05050F0A, 0x9A9AB52F,
793
+ 0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA,
794
+ 0x09091B12, 0x83839E1D, 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B,
795
+ 0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, 0x2F2F715E, 0x84849713,
796
+ 0x5353F5A6, 0xD1D168B9, 0x00000000, 0xEDED2CC1, 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6,
797
+ 0x6A6ABED4, 0xCBCB468D, 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85,
798
+ 0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, 0x33335566, 0x85859411,
799
+ 0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B,
800
+ 0x5151F3A2, 0xA3A3FE5D, 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1,
801
+ 0xBCBCDF63, 0xB6B6C177, 0xDADA75AF, 0x21216342, 0x10103020, 0xFFFF1AE5, 0xF3F30EFD, 0xD2D26DBF,
802
+ 0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E,
803
+ 0xC4C45793, 0xA7A7F255, 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6,
804
+ 0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, 0x9090AB3B, 0x8888830B,
805
+ 0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD,
806
+ 0xE0E03BDB, 0x32325664, 0x3A3A4E74, 0x0A0A1E14, 0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8,
807
+ 0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, 0xE4E437D3, 0x79798BF2,
808
+ 0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049,
809
+ 0x6C6CB4D8, 0x5656FAAC, 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810,
810
+ 0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, 0xB4B4C773, 0xC6C65197,
811
+ 0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, 0x4B4BDD96, 0xBDBDDC61, 0x8B8B860D, 0x8A8A850F,
812
+ 0x707090E0, 0x3E3E427C, 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C,
813
+ 0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, 0x1D1D273A, 0x9E9EB927,
814
+ 0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733,
815
+ 0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5,
816
+ 0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0,
817
+ 0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C
818
+ ));
819
+
820
+ foreach ($t3 as $t3i) {
821
+ $t0[] = (($t3i << 24) & 0xFF000000) | (($t3i >> 8) & 0x00FFFFFF);
822
+ $t1[] = (($t3i << 16) & 0xFFFF0000) | (($t3i >> 16) & 0x0000FFFF);
823
+ $t2[] = (($t3i << 8) & 0xFFFFFF00) | (($t3i >> 24) & 0x000000FF);
824
+ }
825
+
826
+ $tables = array(
827
+ // The Precomputed mixColumns tables t0 - t3
828
+ $t0,
829
+ $t1,
830
+ $t2,
831
+ $t3,
832
+ // The SubByte S-Box
833
+ array(
834
+ 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
835
+ 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
836
+ 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
837
+ 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
838
+ 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
839
+ 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
840
+ 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
841
+ 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
842
+ 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
843
+ 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
844
+ 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
845
+ 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
846
+ 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
847
+ 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
848
+ 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
849
+ 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
850
+ )
851
+ );
852
+ }
853
+ return $tables;
854
+ }
855
+
856
+ /**
857
+ * Provides the inverse mixColumns and inverse sboxes tables
858
+ *
859
+ * @see Crypt_Rijndael:_decryptBlock()
860
+ * @see Crypt_Rijndael:_setupInlineCrypt()
861
+ * @see Crypt_Rijndael:_setupKey()
862
+ * @access private
863
+ * @return Array &$tables
864
+ */
865
+ function &_getInvTables()
866
+ {
867
+ static $tables;
868
+ if (empty($tables)) {
869
+ $dt3 = array_map('intval', array(
870
+ 0xF4A75051, 0x4165537E, 0x17A4C31A, 0x275E963A, 0xAB6BCB3B, 0x9D45F11F, 0xFA58ABAC, 0xE303934B,
871
+ 0x30FA5520, 0x766DF6AD, 0xCC769188, 0x024C25F5, 0xE5D7FC4F, 0x2ACBD7C5, 0x35448026, 0x62A38FB5,
872
+ 0xB15A49DE, 0xBA1B6725, 0xEA0E9845, 0xFEC0E15D, 0x2F7502C3, 0x4CF01281, 0x4697A38D, 0xD3F9C66B,
873
+ 0x8F5FE703, 0x929C9515, 0x6D7AEBBF, 0x5259DA95, 0xBE832DD4, 0x7421D358, 0xE0692949, 0xC9C8448E,
874
+ 0xC2896A75, 0x8E7978F4, 0x583E6B99, 0xB971DD27, 0xE14FB6BE, 0x88AD17F0, 0x20AC66C9, 0xCE3AB47D,
875
+ 0xDF4A1863, 0x1A3182E5, 0x51336097, 0x537F4562, 0x6477E0B1, 0x6BAE84BB, 0x81A01CFE, 0x082B94F9,
876
+ 0x48685870, 0x45FD198F, 0xDE6C8794, 0x7BF8B752, 0x73D323AB, 0x4B02E272, 0x1F8F57E3, 0x55AB2A66,
877
+ 0xEB2807B2, 0xB5C2032F, 0xC57B9A86, 0x3708A5D3, 0x2887F230, 0xBFA5B223, 0x036ABA02, 0x16825CED,
878
+ 0xCF1C2B8A, 0x79B492A7, 0x07F2F0F3, 0x69E2A14E, 0xDAF4CD65, 0x05BED506, 0x34621FD1, 0xA6FE8AC4,
879
+ 0x2E539D34, 0xF355A0A2, 0x8AE13205, 0xF6EB75A4, 0x83EC390B, 0x60EFAA40, 0x719F065E, 0x6E1051BD,
880
+ 0x218AF93E, 0xDD063D96, 0x3E05AEDD, 0xE6BD464D, 0x548DB591, 0xC45D0571, 0x06D46F04, 0x5015FF60,
881
+ 0x98FB2419, 0xBDE997D6, 0x4043CC89, 0xD99E7767, 0xE842BDB0, 0x898B8807, 0x195B38E7, 0xC8EEDB79,
882
+ 0x7C0A47A1, 0x420FE97C, 0x841EC9F8, 0x00000000, 0x80868309, 0x2BED4832, 0x1170AC1E, 0x5A724E6C,
883
+ 0x0EFFFBFD, 0x8538560F, 0xAED51E3D, 0x2D392736, 0x0FD9640A, 0x5CA62168, 0x5B54D19B, 0x362E3A24,
884
+ 0x0A67B10C, 0x57E70F93, 0xEE96D2B4, 0x9B919E1B, 0xC0C54F80, 0xDC20A261, 0x774B695A, 0x121A161C,
885
+ 0x93BA0AE2, 0xA02AE5C0, 0x22E0433C, 0x1B171D12, 0x090D0B0E, 0x8BC7ADF2, 0xB6A8B92D, 0x1EA9C814,
886
+ 0xF1198557, 0x75074CAF, 0x99DDBBEE, 0x7F60FDA3, 0x01269FF7, 0x72F5BC5C, 0x663BC544, 0xFB7E345B,
887
+ 0x4329768B, 0x23C6DCCB, 0xEDFC68B6, 0xE4F163B8, 0x31DCCAD7, 0x63851042, 0x97224013, 0xC6112084,
888
+ 0x4A247D85, 0xBB3DF8D2, 0xF93211AE, 0x29A16DC7, 0x9E2F4B1D, 0xB230F3DC, 0x8652EC0D, 0xC1E3D077,
889
+ 0xB3166C2B, 0x70B999A9, 0x9448FA11, 0xE9642247, 0xFC8CC4A8, 0xF03F1AA0, 0x7D2CD856, 0x3390EF22,
890
+ 0x494EC787, 0x38D1C1D9, 0xCAA2FE8C, 0xD40B3698, 0xF581CFA6, 0x7ADE28A5, 0xB78E26DA, 0xADBFA43F,
891
+ 0x3A9DE42C, 0x78920D50, 0x5FCC9B6A, 0x7E466254, 0x8D13C2F6, 0xD8B8E890, 0x39F75E2E, 0xC3AFF582,
892
+ 0x5D80BE9F, 0xD0937C69, 0xD52DA96F, 0x2512B3CF, 0xAC993BC8, 0x187DA710, 0x9C636EE8, 0x3BBB7BDB,
893
+ 0x267809CD, 0x5918F46E, 0x9AB701EC, 0x4F9AA883, 0x956E65E6, 0xFFE67EAA, 0xBCCF0821, 0x15E8E6EF,
894
+ 0xE79BD9BA, 0x6F36CE4A, 0x9F09D4EA, 0xB07CD629, 0xA4B2AF31, 0x3F23312A, 0xA59430C6, 0xA266C035,
895
+ 0x4EBC3774, 0x82CAA6FC, 0x90D0B0E0, 0xA7D81533, 0x04984AF1, 0xECDAF741, 0xCD500E7F, 0x91F62F17,
896
+ 0x4DD68D76, 0xEFB04D43, 0xAA4D54CC, 0x9604DFE4, 0xD1B5E39E, 0x6A881B4C, 0x2C1FB8C1, 0x65517F46,
897
+ 0x5EEA049D, 0x8C355D01, 0x877473FA, 0x0B412EFB, 0x671D5AB3, 0xDBD25292, 0x105633E9, 0xD647136D,
898
+ 0xD7618C9A, 0xA10C7A37, 0xF8148E59, 0x133C89EB, 0xA927EECE, 0x61C935B7, 0x1CE5EDE1, 0x47B13C7A,
899
+ 0xD2DF599C, 0xF2733F55, 0x14CE7918, 0xC737BF73, 0xF7CDEA53, 0xFDAA5B5F, 0x3D6F14DF, 0x44DB8678,
900
+ 0xAFF381CA, 0x68C43EB9, 0x24342C38, 0xA3405FC2, 0x1DC37216, 0xE2250CBC, 0x3C498B28, 0x0D9541FF,
901
+ 0xA8017139, 0x0CB3DE08, 0xB4E49CD8, 0x56C19064, 0xCB84617B, 0x32B670D5, 0x6C5C7448, 0xB85742D0
902
+ ));
903
+
904
+ foreach ($dt3 as $dt3i) {
905
+ $dt0[] = (($dt3i << 24) & 0xFF000000) | (($dt3i >> 8) & 0x00FFFFFF);
906
+ $dt1[] = (($dt3i << 16) & 0xFFFF0000) | (($dt3i >> 16) & 0x0000FFFF);
907
+ $dt2[] = (($dt3i << 8) & 0xFFFFFF00) | (($dt3i >> 24) & 0x000000FF);
908
+ };
909
+
910
+ $tables = array(
911
+ // The Precomputed inverse mixColumns tables dt0 - dt3
912
+ $dt0,
913
+ $dt1,
914
+ $dt2,
915
+ $dt3,
916
+ // The inverse SubByte S-Box
917
+ array(
918
+ 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
919
+ 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
920
+ 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
921
+ 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
922
+ 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
923
+ 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
924
+ 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
925
+ 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
926
+ 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
927
+ 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
928
+ 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
929
+ 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
930
+ 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
931
+ 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
932
+ 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
933
+ 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
934
+ )
935
+ );
936
+ }
937
+ return $tables;
938
+ }
939
+
940
+ /**
941
+ * Setup the performance-optimized function for de/encrypt()
942
+ *
943
+ * @see Crypt_Base::_setupInlineCrypt()
944
+ * @access private
945
+ */
946
+ function _setupInlineCrypt()
947
+ {
948
+ // Note: _setupInlineCrypt() will be called only if $this->changed === true
949
+ // So here we are'nt under the same heavy timing-stress as we are in _de/encryptBlock() or de/encrypt().
950
+ // However...the here generated function- $code, stored as php callback in $this->inline_crypt, must work as fast as even possible.
951
+
952
+ $lambda_functions =& Crypt_Rijndael::_getLambdaFunctions();
953
+
954
+ // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
955
+ // (Currently, for Crypt_Rijndael/AES, one generated $lambda_function cost on php5.5@32bit ~80kb unfreeable mem and ~130kb on php5.5@64bit)
956
+ // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one.
957
+ $gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
958
+
959
+ // Generation of a uniqe hash for our generated code
960
+ $code_hash = "Crypt_Rijndael, {$this->mode}, {$this->Nr}, {$this->Nb}";
961
+ if ($gen_hi_opt_code) {
962
+ $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
963
+ }
964
+
965
+ if (!isset($lambda_functions[$code_hash])) {
966
+ switch (true) {
967
+ case $gen_hi_opt_code:
968
+ // The hi-optimized $lambda_functions will use the key-words hardcoded for better performance.
969
+ $w = $this->w;
970
+ $dw = $this->dw;
971
+ $init_encrypt = '';
972
+ $init_decrypt = '';
973
+ break;
974
+ default:
975
+ for ($i = 0, $cw = count($this->w); $i < $cw; ++$i) {
976
+ $w[] = '$w[' . $i . ']';
977
+ $dw[] = '$dw[' . $i . ']';
978
+ }
979
+ $init_encrypt = '$w = $self->w;';
980
+ $init_decrypt = '$dw = $self->dw;';
981
+ }
982
+
983
+ $Nr = $this->Nr;
984
+ $Nb = $this->Nb;
985
+ $c = $this->c;
986
+
987
+ // Generating encrypt code:
988
+ $init_encrypt.= '
989
+ static $tables;
990
+ if (empty($tables)) {
991
+ $tables = &$self->_getTables();
992
+ }
993
+ $t0 = $tables[0];
994
+ $t1 = $tables[1];
995
+ $t2 = $tables[2];
996
+ $t3 = $tables[3];
997
+ $sbox = $tables[4];
998
+ ';
999
+
1000
+ $s = 'e';
1001
+ $e = 's';
1002
+ $wc = $Nb - 1;
1003
+
1004
+ // Preround: addRoundKey
1005
+ $encrypt_block = '$in = unpack("N*", $in);'."\n";
1006
+ for ($i = 0; $i < $Nb; ++$i) {
1007
+ $encrypt_block .= '$s'.$i.' = $in['.($i + 1).'] ^ '.$w[++$wc].";\n";
1008
+ }
1009
+
1010
+ // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey
1011
+ for ($round = 1; $round < $Nr; ++$round) {
1012
+ list($s, $e) = array($e, $s);
1013
+ for ($i = 0; $i < $Nb; ++$i) {
1014
+ $encrypt_block.=
1015
+ '$'.$e.$i.' =
1016
+ $t0[($'.$s.$i .' >> 24) & 0xff] ^
1017
+ $t1[($'.$s.(($i + $c[1]) % $Nb).' >> 16) & 0xff] ^
1018
+ $t2[($'.$s.(($i + $c[2]) % $Nb).' >> 8) & 0xff] ^
1019
+ $t3[ $'.$s.(($i + $c[3]) % $Nb).' & 0xff] ^
1020
+ '.$w[++$wc].";\n";
1021
+ }
1022
+ }
1023
+
1024
+ // Finalround: subWord + shiftRows + addRoundKey
1025
+ for ($i = 0; $i < $Nb; ++$i) {
1026
+ $encrypt_block.=
1027
+ '$'.$e.$i.' =
1028
+ $sbox[ $'.$e.$i.' & 0xff] |
1029
+ ($sbox[($'.$e.$i.' >> 8) & 0xff] << 8) |
1030
+ ($sbox[($'.$e.$i.' >> 16) & 0xff] << 16) |
1031
+ ($sbox[($'.$e.$i.' >> 24) & 0xff] << 24);'."\n";
1032
+ }
1033
+ $encrypt_block .= '$in = pack("N*"'."\n";
1034
+ for ($i = 0; $i < $Nb; ++$i) {
1035
+ $encrypt_block.= ',
1036
+ ($'.$e.$i .' & '.((int)0xFF000000).') ^
1037
+ ($'.$e.(($i + $c[1]) % $Nb).' & 0x00FF0000 ) ^
1038
+ ($'.$e.(($i + $c[2]) % $Nb).' & 0x0000FF00 ) ^
1039
+ ($'.$e.(($i + $c[3]) % $Nb).' & 0x000000FF ) ^
1040
+ '.$w[$i]."\n";
1041
+ }
1042
+ $encrypt_block .= ');';
1043
+
1044
+ // Generating decrypt code:
1045
+ $init_decrypt.= '
1046
+ static $invtables;
1047
+ if (empty($invtables)) {
1048
+ $invtables = &$self->_getInvTables();
1049
+ }
1050
+ $dt0 = $invtables[0];
1051
+ $dt1 = $invtables[1];
1052
+ $dt2 = $invtables[2];
1053
+ $dt3 = $invtables[3];
1054
+ $isbox = $invtables[4];
1055
+ ';
1056
+
1057
+ $s = 'e';
1058
+ $e = 's';
1059
+ $wc = $Nb - 1;
1060
+
1061
+ // Preround: addRoundKey
1062
+ $decrypt_block = '$in = unpack("N*", $in);'."\n";
1063
+ for ($i = 0; $i < $Nb; ++$i) {
1064
+ $decrypt_block .= '$s'.$i.' = $in['.($i + 1).'] ^ '.$dw[++$wc].';'."\n";
1065
+ }
1066
+
1067
+ // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey
1068
+ for ($round = 1; $round < $Nr; ++$round) {
1069
+ list($s, $e) = array($e, $s);
1070
+ for ($i = 0; $i < $Nb; ++$i) {
1071
+ $decrypt_block.=
1072
+ '$'.$e.$i.' =
1073
+ $dt0[($'.$s.$i .' >> 24) & 0xff] ^
1074
+ $dt1[($'.$s.(($Nb + $i - $c[1]) % $Nb).' >> 16) & 0xff] ^
1075
+ $dt2[($'.$s.(($Nb + $i - $c[2]) % $Nb).' >> 8) & 0xff] ^
1076
+ $dt3[ $'.$s.(($Nb + $i - $c[3]) % $Nb).' & 0xff] ^
1077
+ '.$dw[++$wc].";\n";
1078
+ }
1079
+ }
1080
+
1081
+ // Finalround: subWord + shiftRows + addRoundKey
1082
+ for ($i = 0; $i < $Nb; ++$i) {
1083
+ $decrypt_block.=
1084
+ '$'.$e.$i.' =
1085
+ $isbox[ $'.$e.$i.' & 0xff] |
1086
+ ($isbox[($'.$e.$i.' >> 8) & 0xff] << 8) |
1087
+ ($isbox[($'.$e.$i.' >> 16) & 0xff] << 16) |
1088
+ ($isbox[($'.$e.$i.' >> 24) & 0xff] << 24);'."\n";
1089
+ }
1090
+ $decrypt_block .= '$in = pack("N*"'."\n";
1091
+ for ($i = 0; $i < $Nb; ++$i) {
1092
+ $decrypt_block.= ',
1093
+ ($'.$e.$i. ' & '.((int)0xFF000000).') ^
1094
+ ($'.$e.(($Nb + $i - $c[1]) % $Nb).' & 0x00FF0000 ) ^
1095
+ ($'.$e.(($Nb + $i - $c[2]) % $Nb).' & 0x0000FF00 ) ^
1096
+ ($'.$e.(($Nb + $i - $c[3]) % $Nb).' & 0x000000FF ) ^
1097
+ '.$dw[$i]."\n";
1098
+ }
1099
+ $decrypt_block .= ');';
1100
+
1101
+ $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
1102
+ array(
1103
+ 'init_crypt' => '',
1104
+ 'init_encrypt' => $init_encrypt,
1105
+ 'init_decrypt' => $init_decrypt,
1106
+ 'encrypt_block' => $encrypt_block,
1107
+ 'decrypt_block' => $decrypt_block
1108
+ )
1109
+ );
1110
+ }
1111
+ $this->inline_crypt = $lambda_functions[$code_hash];
1112
+ }
1113
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
phpseclib/Crypt/TripleDES.php CHANGED
@@ -1,428 +1,481 @@
1
- <?php
2
-
3
- /**
4
- * Pure-PHP implementation of Triple DES.
5
- *
6
- * Uses mcrypt, if available, and an internal implementation, otherwise. Operates in the EDE3 mode (encrypt-decrypt-encrypt).
7
- *
8
- * PHP versions 4 and 5
9
- *
10
- * Here's a short example of how to use this library:
11
- * <code>
12
- * <?php
13
- * include 'Crypt/TripleDES.php';
14
- *
15
- * $des = new Crypt_TripleDES();
16
- *
17
- * $des->setKey('abcdefghijklmnopqrstuvwx');
18
- *
19
- * $size = 10 * 1024;
20
- * $plaintext = '';
21
- * for ($i = 0; $i < $size; $i++) {
22
- * $plaintext.= 'a';
23
- * }
24
- *
25
- * echo $des->decrypt($des->encrypt($plaintext));
26
- * ?>
27
- * </code>
28
- *
29
- * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
30
- * of this software and associated documentation files (the "Software"), to deal
31
- * in the Software without restriction, including without limitation the rights
32
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
33
- * copies of the Software, and to permit persons to whom the Software is
34
- * furnished to do so, subject to the following conditions:
35
- *
36
- * The above copyright notice and this permission notice shall be included in
37
- * all copies or substantial portions of the Software.
38
- *
39
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
40
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
41
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
42
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
43
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
44
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
45
- * THE SOFTWARE.
46
- *
47
- * @category Crypt
48
- * @package Crypt_TripleDES
49
- * @author Jim Wigginton <terrafrost@php.net>
50
- * @copyright MMVII Jim Wigginton
51
- * @license http://www.opensource.org/licenses/mit-license.html MIT License
52
- * @link http://phpseclib.sourceforge.net
53
- */
54
-
55
- /**
56
- * Include Crypt_DES
57
- */
58
- if (!class_exists('Crypt_DES')) {
59
- include_once 'DES.php';
60
- }
61
-
62
- /**
63
- * Encrypt / decrypt using inner chaining
64
- *
65
- * Inner chaining is used by SSH-1 and is generally considered to be less secure then outer chaining (CRYPT_DES_MODE_CBC3).
66
- */
67
- define('CRYPT_DES_MODE_3CBC', -2);
68
-
69
- /**
70
- * Encrypt / decrypt using outer chaining
71
- *
72
- * Outer chaining is used by SSH-2 and when the mode is set to CRYPT_DES_MODE_CBC.
73
- */
74
- define('CRYPT_DES_MODE_CBC3', CRYPT_DES_MODE_CBC);
75
-
76
- /**
77
- * Pure-PHP implementation of Triple DES.
78
- *
79
- * @package Crypt_TripleDES
80
- * @author Jim Wigginton <terrafrost@php.net>
81
- * @access public
82
- */
83
- class Crypt_TripleDES extends Crypt_DES
84
- {
85
- /**
86
- * The default password key_size used by setPassword()
87
- *
88
- * @see Crypt_DES::password_key_size
89
- * @see Crypt_Base::password_key_size
90
- * @see Crypt_Base::setPassword()
91
- * @var Integer
92
- * @access private
93
- */
94
- var $password_key_size = 24;
95
-
96
- /**
97
- * The default salt used by setPassword()
98
- *
99
- * @see Crypt_Base::password_default_salt
100
- * @see Crypt_Base::setPassword()
101
- * @var String
102
- * @access private
103
- */
104
- var $password_default_salt = 'phpseclib';
105
-
106
- /**
107
- * The namespace used by the cipher for its constants.
108
- *
109
- * @see Crypt_DES::const_namespace
110
- * @see Crypt_Base::const_namespace
111
- * @var String
112
- * @access private
113
- */
114
- var $const_namespace = 'DES';
115
-
116
- /**
117
- * The mcrypt specific name of the cipher
118
- *
119
- * @see Crypt_DES::cipher_name_mcrypt
120
- * @see Crypt_Base::cipher_name_mcrypt
121
- * @var String
122
- * @access private
123
- */
124
- var $cipher_name_mcrypt = 'tripledes';
125
-
126
- /**
127
- * Optimizing value while CFB-encrypting
128
- *
129
- * @see Crypt_Base::cfb_init_len
130
- * @var Integer
131
- * @access private
132
- */
133
- var $cfb_init_len = 750;
134
-
135
- /**
136
- * max possible size of $key
137
- *
138
- * @see Crypt_TripleDES::setKey()
139
- * @see Crypt_DES::setKey()
140
- * @var String
141
- * @access private
142
- */
143
- var $key_size_max = 24;
144
-
145
- /**
146
- * Internal flag whether using CRYPT_DES_MODE_3CBC or not
147
- *
148
- * @var Boolean
149
- * @access private
150
- */
151
- var $mode_3cbc;
152
-
153
- /**
154
- * The Crypt_DES objects
155
- *
156
- * Used only if $mode_3cbc === true
157
- *
158
- * @var Array
159
- * @access private
160
- */
161
- var $des;
162
-
163
- /**
164
- * Default Constructor.
165
- *
166
- * Determines whether or not the mcrypt extension should be used.
167
- *
168
- * $mode could be:
169
- *
170
- * - CRYPT_DES_MODE_ECB
171
- *
172
- * - CRYPT_DES_MODE_CBC
173
- *
174
- * - CRYPT_DES_MODE_CTR
175
- *
176
- * - CRYPT_DES_MODE_CFB
177
- *
178
- * - CRYPT_DES_MODE_OFB
179
- *
180
- * - CRYPT_DES_MODE_3CBC
181
- *
182
- * If not explicitly set, CRYPT_DES_MODE_CBC will be used.
183
- *
184
- * @see Crypt_DES::Crypt_DES()
185
- * @see Crypt_Base::Crypt_Base()
186
- * @param optional Integer $mode
187
- * @access public
188
- */
189
- function Crypt_TripleDES($mode = CRYPT_DES_MODE_CBC)
190
- {
191
- switch ($mode) {
192
- // In case of CRYPT_DES_MODE_3CBC, we init as CRYPT_DES_MODE_CBC
193
- // and additional flag us internally as 3CBC
194
- case CRYPT_DES_MODE_3CBC:
195
- parent::Crypt_Base(CRYPT_DES_MODE_CBC);
196
- $this->mode_3cbc = true;
197
-
198
- // This three $des'es will do the 3CBC work (if $key > 64bits)
199
- $this->des = array(
200
- new Crypt_DES(CRYPT_DES_MODE_CBC),
201
- new Crypt_DES(CRYPT_DES_MODE_CBC),
202
- new Crypt_DES(CRYPT_DES_MODE_CBC),
203
- );
204
-
205
- // we're going to be doing the padding, ourselves, so disable it in the Crypt_DES objects
206
- $this->des[0]->disablePadding();
207
- $this->des[1]->disablePadding();
208
- $this->des[2]->disablePadding();
209
- break;
210
- // If not 3CBC, we init as usual
211
- default:
212
- parent::Crypt_Base($mode);
213
- }
214
- }
215
-
216
- /**
217
- * Sets the initialization vector. (optional)
218
- *
219
- * SetIV is not required when CRYPT_DES_MODE_ECB is being used. If not explicitly set, it'll be assumed
220
- * to be all zero's.
221
- *
222
- * @see Crypt_Base::setIV()
223
- * @access public
224
- * @param String $iv
225
- */
226
- function setIV($iv)
227
- {
228
- parent::setIV($iv);
229
- if ($this->mode_3cbc) {
230
- $this->des[0]->setIV($iv);
231
- $this->des[1]->setIV($iv);
232
- $this->des[2]->setIV($iv);
233
- }
234
- }
235
-
236
- /**
237
- * Sets the key.
238
- *
239
- * Keys can be of any length. Triple DES, itself, can use 128-bit (eg. strlen($key) == 16) or
240
- * 192-bit (eg. strlen($key) == 24) keys. This function pads and truncates $key as appropriate.
241
- *
242
- * DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
243
- *
244
- * If the key is not explicitly set, it'll be assumed to be all null bytes.
245
- *
246
- * @access public
247
- * @see Crypt_DES::setKey()
248
- * @see Crypt_Base::setKey()
249
- * @param String $key
250
- */
251
- function setKey($key)
252
- {
253
- $length = strlen($key);
254
- if ($length > 8) {
255
- $key = str_pad(substr($key, 0, 24), 24, chr(0));
256
- // if $key is between 64 and 128-bits, use the first 64-bits as the last, per this:
257
- // http://php.net/function.mcrypt-encrypt#47973
258
- //$key = $length <= 16 ? substr_replace($key, substr($key, 0, 8), 16) : substr($key, 0, 24);
259
- } else {
260
- $key = str_pad($key, 8, chr(0));
261
- }
262
- parent::setKey($key);
263
-
264
- // And in case of CRYPT_DES_MODE_3CBC:
265
- // if key <= 64bits we not need the 3 $des to work,
266
- // because we will then act as regular DES-CBC with just a <= 64bit key.
267
- // So only if the key > 64bits (> 8 bytes) we will call setKey() for the 3 $des.
268
- if ($this->mode_3cbc && $length > 8) {
269
- $this->des[0]->setKey(substr($key, 0, 8));
270
- $this->des[1]->setKey(substr($key, 8, 8));
271
- $this->des[2]->setKey(substr($key, 16, 8));
272
- }
273
- }
274
-
275
- /**
276
- * Encrypts a message.
277
- *
278
- * @see Crypt_Base::encrypt()
279
- * @access public
280
- * @param String $plaintext
281
- * @return String $cipertext
282
- */
283
- function encrypt($plaintext)
284
- {
285
- // parent::en/decrypt() is able to do all the work for all modes and keylengths,
286
- // except for: CRYPT_DES_MODE_3CBC (inner chaining CBC) with a key > 64bits
287
-
288
- // if the key is smaller then 8, do what we'd normally do
289
- if ($this->mode_3cbc && strlen($this->key) > 8) {
290
- return $this->des[2]->encrypt(
291
- $this->des[1]->decrypt(
292
- $this->des[0]->encrypt(
293
- $this->_pad($plaintext)
294
- )
295
- )
296
- );
297
- }
298
-
299
- return parent::encrypt($plaintext);
300
- }
301
-
302
- /**
303
- * Decrypts a message.
304
- *
305
- * @see Crypt_Base::decrypt()
306
- * @access public
307
- * @param String $ciphertext
308
- * @return String $plaintext
309
- */
310
- function decrypt($ciphertext)
311
- {
312
- if ($this->mode_3cbc && strlen($this->key) > 8) {
313
- return $this->_unpad(
314
- $this->des[0]->decrypt(
315
- $this->des[1]->encrypt(
316
- $this->des[2]->decrypt(
317
- str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, "\0")
318
- )
319
- )
320
- )
321
- );
322
- }
323
-
324
- return parent::decrypt($ciphertext);
325
- }
326
-
327
- /**
328
- * Treat consecutive "packets" as if they are a continuous buffer.
329
- *
330
- * Say you have a 16-byte plaintext $plaintext. Using the default behavior, the two following code snippets
331
- * will yield different outputs:
332
- *
333
- * <code>
334
- * echo $des->encrypt(substr($plaintext, 0, 8));
335
- * echo $des->encrypt(substr($plaintext, 8, 8));
336
- * </code>
337
- * <code>
338
- * echo $des->encrypt($plaintext);
339
- * </code>
340
- *
341
- * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates
342
- * another, as demonstrated with the following:
343
- *
344
- * <code>
345
- * $des->encrypt(substr($plaintext, 0, 8));
346
- * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
347
- * </code>
348
- * <code>
349
- * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
350
- * </code>
351
- *
352
- * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different
353
- * outputs. The reason is due to the fact that the initialization vector's change after every encryption /
354
- * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
355
- *
356
- * Put another way, when the continuous buffer is enabled, the state of the Crypt_DES() object changes after each
357
- * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
358
- * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
359
- * however, they are also less intuitive and more likely to cause you problems.
360
- *
361
- * @see Crypt_Base::enableContinuousBuffer()
362
- * @see Crypt_TripleDES::disableContinuousBuffer()
363
- * @access public
364
- */
365
- function enableContinuousBuffer()
366
- {
367
- parent::enableContinuousBuffer();
368
- if ($this->mode_3cbc) {
369
- $this->des[0]->enableContinuousBuffer();
370
- $this->des[1]->enableContinuousBuffer();
371
- $this->des[2]->enableContinuousBuffer();
372
- }
373
- }
374
-
375
- /**
376
- * Treat consecutive packets as if they are a discontinuous buffer.
377
- *
378
- * The default behavior.
379
- *
380
- * @see Crypt_Base::disableContinuousBuffer()
381
- * @see Crypt_TripleDES::enableContinuousBuffer()
382
- * @access public
383
- */
384
- function disableContinuousBuffer()
385
- {
386
- parent::disableContinuousBuffer();
387
- if ($this->mode_3cbc) {
388
- $this->des[0]->disableContinuousBuffer();
389
- $this->des[1]->disableContinuousBuffer();
390
- $this->des[2]->disableContinuousBuffer();
391
- }
392
- }
393
-
394
- /**
395
- * Creates the key schedule
396
- *
397
- * @see Crypt_DES::_setupKey()
398
- * @see Crypt_Base::_setupKey()
399
- * @access private
400
- */
401
- function _setupKey()
402
- {
403
- switch (true) {
404
- // if $key <= 64bits we configure our internal pure-php cipher engine
405
- // to act as regular [1]DES, not as 3DES. mcrypt.so::tripledes does the same.
406
- case strlen($this->key) <= 8:
407
- $this->des_rounds = 1;
408
- break;
409
-
410
- // otherwise, if $key > 64bits, we configure our engine to work as 3DES.
411
- default:
412
- $this->des_rounds = 3;
413
-
414
- // (only) if 3CBC is used we have, of course, to setup the $des[0-2] keys also separately.
415
- if ($this->mode_3cbc) {
416
- $this->des[0]->_setupKey();
417
- $this->des[1]->_setupKey();
418
- $this->des[2]->_setupKey();
419
-
420
- // because $des[0-2] will, now, do all the work we can return here
421
- // not need unnecessary stress parent::_setupKey() with our, now unused, $key.
422
- return;
423
- }
424
- }
425
- // setup our key
426
- parent::_setupKey();
427
- }
428
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Pure-PHP implementation of Triple DES.
5
+ *
6
+ * Uses mcrypt, if available, and an internal implementation, otherwise. Operates in the EDE3 mode (encrypt-decrypt-encrypt).
7
+ *
8
+ * PHP versions 4 and 5
9
+ *
10
+ * Here's a short example of how to use this library:
11
+ * <code>
12
+ * <?php
13
+ * include 'Crypt/TripleDES.php';
14
+ *
15
+ * $des = new Crypt_TripleDES();
16
+ *
17
+ * $des->setKey('abcdefghijklmnopqrstuvwx');
18
+ *
19
+ * $size = 10 * 1024;
20
+ * $plaintext = '';
21
+ * for ($i = 0; $i < $size; $i++) {
22
+ * $plaintext.= 'a';
23
+ * }
24
+ *
25
+ * echo $des->decrypt($des->encrypt($plaintext));
26
+ * ?>
27
+ * </code>
28
+ *
29
+ * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
30
+ * of this software and associated documentation files (the "Software"), to deal
31
+ * in the Software without restriction, including without limitation the rights
32
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
33
+ * copies of the Software, and to permit persons to whom the Software is
34
+ * furnished to do so, subject to the following conditions:
35
+ *
36
+ * The above copyright notice and this permission notice shall be included in
37
+ * all copies or substantial portions of the Software.
38
+ *
39
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
40
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
41
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
42
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
43
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
44
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
45
+ * THE SOFTWARE.
46
+ *
47
+ * @category Crypt
48
+ * @package Crypt_TripleDES
49
+ * @author Jim Wigginton <terrafrost@php.net>
50
+ * @copyright 2007 Jim Wigginton
51
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
52
+ * @link http://phpseclib.sourceforge.net
53
+ */
54
+
55
+ /**
56
+ * Include Crypt_DES
57
+ */
58
+ if (!class_exists('Crypt_DES')) {
59
+ include_once 'DES.php';
60
+ }
61
+
62
+ /**#@+
63
+ * @access public
64
+ * @see Crypt_TripleDES::Crypt_TripleDES()
65
+ */
66
+ /**
67
+ * Encrypt / decrypt using inner chaining
68
+ *
69
+ * Inner chaining is used by SSH-1 and is generally considered to be less secure then outer chaining (CRYPT_DES_MODE_CBC3).
70
+ */
71
+ define('CRYPT_MODE_3CBC', -2);
72
+ /**
73
+ * BC version of the above.
74
+ */
75
+ define('CRYPT_DES_MODE_3CBC', -2);
76
+ /**
77
+ * Encrypt / decrypt using outer chaining
78
+ *
79
+ * Outer chaining is used by SSH-2 and when the mode is set to CRYPT_DES_MODE_CBC.
80
+ */
81
+ define('CRYPT_MODE_CBC3', CRYPT_MODE_CBC);
82
+ /**
83
+ * BC version of the above.
84
+ */
85
+ define('CRYPT_DES_MODE_CBC3', CRYPT_MODE_CBC3);
86
+ /**#@-*/
87
+
88
+ /**
89
+ * Pure-PHP implementation of Triple DES.
90
+ *
91
+ * @package Crypt_TripleDES
92
+ * @author Jim Wigginton <terrafrost@php.net>
93
+ * @access public
94
+ */
95
+ class Crypt_TripleDES extends Crypt_DES
96
+ {
97
+ /**
98
+ * The default password key_size used by setPassword()
99
+ *
100
+ * @see Crypt_DES::password_key_size
101
+ * @see Crypt_Base::password_key_size
102
+ * @see Crypt_Base::setPassword()
103
+ * @var Integer
104
+ * @access private
105
+ */
106
+ var $password_key_size = 24;
107
+
108
+ /**
109
+ * The default salt used by setPassword()
110
+ *
111
+ * @see Crypt_Base::password_default_salt
112
+ * @see Crypt_Base::setPassword()
113
+ * @var String
114
+ * @access private
115
+ */
116
+ var $password_default_salt = 'phpseclib';
117
+
118
+ /**
119
+ * The namespace used by the cipher for its constants.
120
+ *
121
+ * @see Crypt_DES::const_namespace
122
+ * @see Crypt_Base::const_namespace
123
+ * @var String
124
+ * @access private
125
+ */
126
+ var $const_namespace = 'DES';
127
+
128
+ /**
129
+ * The mcrypt specific name of the cipher
130
+ *
131
+ * @see Crypt_DES::cipher_name_mcrypt
132
+ * @see Crypt_Base::cipher_name_mcrypt
133
+ * @var String
134
+ * @access private
135
+ */
136
+ var $cipher_name_mcrypt = 'tripledes';
137
+
138
+ /**
139
+ * Optimizing value while CFB-encrypting
140
+ *
141
+ * @see Crypt_Base::cfb_init_len
142
+ * @var Integer
143
+ * @access private
144
+ */
145
+ var $cfb_init_len = 750;
146
+
147
+ /**
148
+ * max possible size of $key
149
+ *
150
+ * @see Crypt_TripleDES::setKey()
151
+ * @see Crypt_DES::setKey()
152
+ * @var String
153
+ * @access private
154
+ */
155
+ var $key_size_max = 24;
156
+
157
+ /**
158
+ * Internal flag whether using CRYPT_DES_MODE_3CBC or not
159
+ *
160
+ * @var Boolean
161
+ * @access private
162
+ */
163
+ var $mode_3cbc;
164
+
165
+ /**
166
+ * The Crypt_DES objects
167
+ *
168
+ * Used only if $mode_3cbc === true
169
+ *
170
+ * @var Array
171
+ * @access private
172
+ */
173
+ var $des;
174
+
175
+ /**
176
+ * Default Constructor.
177
+ *
178
+ * Determines whether or not the mcrypt extension should be used.
179
+ *
180
+ * $mode could be:
181
+ *
182
+ * - CRYPT_DES_MODE_ECB
183
+ *
184
+ * - CRYPT_DES_MODE_CBC
185
+ *
186
+ * - CRYPT_DES_MODE_CTR
187
+ *
188
+ * - CRYPT_DES_MODE_CFB
189
+ *
190
+ * - CRYPT_DES_MODE_OFB
191
+ *
192
+ * - CRYPT_DES_MODE_3CBC
193
+ *
194
+ * If not explicitly set, CRYPT_DES_MODE_CBC will be used.
195
+ *
196
+ * @see Crypt_DES::Crypt_DES()
197
+ * @see Crypt_Base::Crypt_Base()
198
+ * @param optional Integer $mode
199
+ * @access public
200
+ */
201
+ function Crypt_TripleDES($mode = CRYPT_MODE_CBC)
202
+ {
203
+ switch ($mode) {
204
+ // In case of CRYPT_DES_MODE_3CBC, we init as CRYPT_DES_MODE_CBC
205
+ // and additional flag us internally as 3CBC
206
+ case CRYPT_DES_MODE_3CBC:
207
+ parent::Crypt_Base(CRYPT_MODE_CBC);
208
+ $this->mode_3cbc = true;
209
+
210
+ // This three $des'es will do the 3CBC work (if $key > 64bits)
211
+ $this->des = array(
212
+ new Crypt_DES(CRYPT_MODE_CBC),
213
+ new Crypt_DES(CRYPT_MODE_CBC),
214
+ new Crypt_DES(CRYPT_MODE_CBC),
215
+ );
216
+
217
+ // we're going to be doing the padding, ourselves, so disable it in the Crypt_DES objects
218
+ $this->des[0]->disablePadding();
219
+ $this->des[1]->disablePadding();
220
+ $this->des[2]->disablePadding();
221
+ break;
222
+ // If not 3CBC, we init as usual
223
+ default:
224
+ parent::Crypt_Base($mode);
225
+ }
226
+ }
227
+
228
+ /**
229
+ * Test for engine validity
230
+ *
231
+ * This is mainly just a wrapper to set things up for Crypt_Base::isValidEngine()
232
+ *
233
+ * @see Crypt_Base::Crypt_Base()
234
+ * @param Integer $engine
235
+ * @access public
236
+ * @return Boolean
237
+ */
238
+ function isValidEngine($engine)
239
+ {
240
+ if ($engine == CRYPT_ENGINE_OPENSSL) {
241
+ $this->cipher_name_openssl_ecb = 'des-ede3';
242
+ $mode = $this->_openssl_translate_mode();
243
+ $this->cipher_name_openssl = $mode == 'ecb' ? 'des-ede3' : 'des-ede3-' . $mode;
244
+ }
245
+
246
+ return parent::isValidEngine($engine);
247
+ }
248
+
249
+ /**
250
+ * Sets the initialization vector. (optional)
251
+ *
252
+ * SetIV is not required when CRYPT_DES_MODE_ECB is being used. If not explicitly set, it'll be assumed
253
+ * to be all zero's.
254
+ *
255
+ * @see Crypt_Base::setIV()
256
+ * @access public
257
+ * @param String $iv
258
+ */
259
+ function setIV($iv)
260
+ {
261
+ parent::setIV($iv);
262
+ if ($this->mode_3cbc) {
263
+ $this->des[0]->setIV($iv);
264
+ $this->des[1]->setIV($iv);
265
+ $this->des[2]->setIV($iv);
266
+ }
267
+ }
268
+
269
+ /**
270
+ * Sets the key.
271
+ *
272
+ * Keys can be of any length. Triple DES, itself, can use 128-bit (eg. strlen($key) == 16) or
273
+ * 192-bit (eg. strlen($key) == 24) keys. This function pads and truncates $key as appropriate.
274
+ *
275
+ * DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
276
+ *
277
+ * If the key is not explicitly set, it'll be assumed to be all null bytes.
278
+ *
279
+ * @access public
280
+ * @see Crypt_DES::setKey()
281
+ * @see Crypt_Base::setKey()
282
+ * @param String $key
283
+ */
284
+ function setKey($key)
285
+ {
286
+ $length = strlen($key);
287
+ if ($length > 8) {
288
+ $key = str_pad(substr($key, 0, 24), 24, chr(0));
289
+ // if $key is between 64 and 128-bits, use the first 64-bits as the last, per this:
290
+ // http://php.net/function.mcrypt-encrypt#47973
291
+ $key = $length <= 16 ? substr_replace($key, substr($key, 0, 8), 16) : substr($key, 0, 24);
292
+ } else {
293
+ $key = str_pad($key, 8, chr(0));
294
+ }
295
+ parent::setKey($key);
296
+
297
+ // And in case of CRYPT_DES_MODE_3CBC:
298
+ // if key <= 64bits we not need the 3 $des to work,
299
+ // because we will then act as regular DES-CBC with just a <= 64bit key.
300
+ // So only if the key > 64bits (> 8 bytes) we will call setKey() for the 3 $des.
301
+ if ($this->mode_3cbc && $length > 8) {
302
+ $this->des[0]->setKey(substr($key, 0, 8));
303
+ $this->des[1]->setKey(substr($key, 8, 8));
304
+ $this->des[2]->setKey(substr($key, 16, 8));
305
+ }
306
+ }
307
+
308
+ /**
309
+ * Encrypts a message.
310
+ *
311
+ * @see Crypt_Base::encrypt()
312
+ * @access public
313
+ * @param String $plaintext
314
+ * @return String $cipertext
315
+ */
316
+ function encrypt($plaintext)
317
+ {
318
+ // parent::en/decrypt() is able to do all the work for all modes and keylengths,
319
+ // except for: CRYPT_MODE_3CBC (inner chaining CBC) with a key > 64bits
320
+
321
+ // if the key is smaller then 8, do what we'd normally do
322
+ if ($this->mode_3cbc && strlen($this->key) > 8) {
323
+ return $this->des[2]->encrypt(
324
+ $this->des[1]->decrypt(
325
+ $this->des[0]->encrypt(
326
+ $this->_pad($plaintext)
327
+ )
328
+ )
329
+ );
330
+ }
331
+
332
+ return parent::encrypt($plaintext);
333
+ }
334
+
335
+ /**
336
+ * Decrypts a message.
337
+ *
338
+ * @see Crypt_Base::decrypt()
339
+ * @access public
340
+ * @param String $ciphertext
341
+ * @return String $plaintext
342
+ */
343
+ function decrypt($ciphertext)
344
+ {
345
+ if ($this->mode_3cbc && strlen($this->key) > 8) {
346
+ return $this->_unpad(
347
+ $this->des[0]->decrypt(
348
+ $this->des[1]->encrypt(
349
+ $this->des[2]->decrypt(
350
+ str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, "\0")
351
+ )
352
+ )
353
+ )
354
+ );
355
+ }
356
+
357
+ return parent::decrypt($ciphertext);
358
+ }
359
+
360
+ /**
361
+ * Treat consecutive "packets" as if they are a continuous buffer.
362
+ *
363
+ * Say you have a 16-byte plaintext $plaintext. Using the default behavior, the two following code snippets
364
+ * will yield different outputs:
365
+ *
366
+ * <code>
367
+ * echo $des->encrypt(substr($plaintext, 0, 8));
368
+ * echo $des->encrypt(substr($plaintext, 8, 8));
369
+ * </code>
370
+ * <code>
371
+ * echo $des->encrypt($plaintext);
372
+ * </code>
373
+ *
374
+ * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates
375
+ * another, as demonstrated with the following:
376
+ *
377
+ * <code>
378
+ * $des->encrypt(substr($plaintext, 0, 8));
379
+ * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
380
+ * </code>
381
+ * <code>
382
+ * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
383
+ * </code>
384
+ *
385
+ * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different
386
+ * outputs. The reason is due to the fact that the initialization vector's change after every encryption /
387
+ * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
388
+ *
389
+ * Put another way, when the continuous buffer is enabled, the state of the Crypt_DES() object changes after each
390
+ * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
391
+ * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
392
+ * however, they are also less intuitive and more likely to cause you problems.
393
+ *
394
+ * @see Crypt_Base::enableContinuousBuffer()
395
+ * @see Crypt_TripleDES::disableContinuousBuffer()
396
+ * @access public
397
+ */
398
+ function enableContinuousBuffer()
399
+ {
400
+ parent::enableContinuousBuffer();
401
+ if ($this->mode_3cbc) {
402
+ $this->des[0]->enableContinuousBuffer();
403
+ $this->des[1]->enableContinuousBuffer();
404
+ $this->des[2]->enableContinuousBuffer();
405
+ }
406
+ }
407
+
408
+ /**
409
+ * Treat consecutive packets as if they are a discontinuous buffer.
410
+ *
411
+ * The default behavior.
412
+ *
413
+ * @see Crypt_Base::disableContinuousBuffer()
414
+ * @see Crypt_TripleDES::enableContinuousBuffer()
415
+ * @access public
416
+ */
417
+ function disableContinuousBuffer()
418
+ {
419
+ parent::disableContinuousBuffer();
420
+ if ($this->mode_3cbc) {
421
+ $this->des[0]->disableContinuousBuffer();
422
+ $this->des[1]->disableContinuousBuffer();
423
+ $this->des[2]->disableContinuousBuffer();
424
+ }
425
+ }
426
+
427
+ /**
428
+ * Creates the key schedule
429
+ *
430
+ * @see Crypt_DES::_setupKey()
431
+ * @see Crypt_Base::_setupKey()
432
+ * @access private
433
+ */
434
+ function _setupKey()
435
+ {
436
+ switch (true) {
437
+ // if $key <= 64bits we configure our internal pure-php cipher engine
438
+ // to act as regular [1]DES, not as 3DES. mcrypt.so::tripledes does the same.
439
+ case strlen($this->key) <= 8:
440
+ $this->des_rounds = 1;
441
+ break;
442
+
443
+ // otherwise, if $key > 64bits, we configure our engine to work as 3DES.
444
+ default:
445
+ $this->des_rounds = 3;
446
+
447
+ // (only) if 3CBC is used we have, of course, to setup the $des[0-2] keys also separately.
448
+ if ($this->mode_3cbc) {
449
+ $this->des[0]->_setupKey();
450
+ $this->des[1]->_setupKey();
451
+ $this->des[2]->_setupKey();
452
+
453
+ // because $des[0-2] will, now, do all the work we can return here
454
+ // not need unnecessary stress parent::_setupKey() with our, now unused, $key.
455
+ return;
456
+ }
457
+ }
458
+ // setup our key
459
+ parent::_setupKey();
460
+ }
461
+
462
+ /**
463
+ * Sets the internal crypt engine
464
+ *
465
+ * @see Crypt_Base::Crypt_Base()
466
+ * @see Crypt_Base::setPreferredEngine()
467
+ * @param Integer $engine
468
+ * @access public
469
+ * @return Integer
470
+ */
471
+ function setPreferredEngine($engine)
472
+ {
473
+ if ($this->mode_3cbc) {
474
+ $this->des[0]->setPreferredEngine($engine);
475
+ $this->des[1]->setPreferredEngine($engine);
476
+ $this->des[2]->setPreferredEngine($engine);
477
+ }
478
+
479
+ return parent::setPreferredEngine($engine);
480
+ }
481
+ }
phpseclib/Crypt/Twofish.php CHANGED
@@ -1,895 +1,878 @@
1
- <?php
2
-
3
- /**
4
- * Pure-PHP implementation of Twofish.
5
- *
6
- * Uses mcrypt, if available, and an internal implementation, otherwise.
7
- *
8
- * PHP versions 4 and 5
9
- *
10
- * Useful resources are as follows:
11
- *
12
- * - {@link http://en.wikipedia.org/wiki/Twofish Wikipedia description of Twofish}
13
- *
14
- * Here's a short example of how to use this library:
15
- * <code>
16
- * <?php
17
- * include 'Crypt/Twofish.php';
18
- *
19
- * $twofish = new Crypt_Twofish();
20
- *
21
- * $twofish->setKey('12345678901234567890123456789012');
22
- *
23
- * $plaintext = str_repeat('a', 1024);
24
- *
25
- * echo $twofish->decrypt($twofish->encrypt($plaintext));
26
- * ?>
27
- * </code>
28
- *
29
- * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
30
- * of this software and associated documentation files (the "Software"), to deal
31
- * in the Software without restriction, including without limitation the rights
32
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
33
- * copies of the Software, and to permit persons to whom the Software is
34
- * furnished to do so, subject to the following conditions:
35
- *
36
- * The above copyright notice and this permission notice shall be included in
37
- * all copies or substantial portions of the Software.
38
- *
39
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
40
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
41
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
42
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
43
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
44
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
45
- * THE SOFTWARE.
46
- *
47
- * @category Crypt
48
- * @package Crypt_Twofish
49
- * @author Jim Wigginton <terrafrost@php.net>
50
- * @author Hans-Juergen Petrich <petrich@tronic-media.com>
51
- * @copyright MMVII Jim Wigginton
52
- * @license http://www.opensource.org/licenses/mit-license.html MIT License
53
- * @link http://phpseclib.sourceforge.net
54
- */
55
-
56
- /**
57
- * Include Crypt_Base
58
- *
59
- * Base cipher class
60
- */
61
- if (!class_exists('Crypt_Base')) {
62
- include_once 'Base.php';
63
- }
64
-
65
- /**#@+
66
- * @access public
67
- * @see Crypt_Twofish::encrypt()
68
- * @see Crypt_Twofish::decrypt()
69
- */
70
- /**
71
- * Encrypt / decrypt using the Counter mode.
72
- *
73
- * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
74
- *
75
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
76
- */
77
- define('CRYPT_TWOFISH_MODE_CTR', CRYPT_MODE_CTR);
78
- /**
79
- * Encrypt / decrypt using the Electronic Code Book mode.
80
- *
81
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
82
- */
83
- define('CRYPT_TWOFISH_MODE_ECB', CRYPT_MODE_ECB);
84
- /**
85
- * Encrypt / decrypt using the Code Book Chaining mode.
86
- *
87
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
88
- */
89
- define('CRYPT_TWOFISH_MODE_CBC', CRYPT_MODE_CBC);
90
- /**
91
- * Encrypt / decrypt using the Cipher Feedback mode.
92
- *
93
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
94
- */
95
- define('CRYPT_TWOFISH_MODE_CFB', CRYPT_MODE_CFB);
96
- /**
97
- * Encrypt / decrypt using the Cipher Feedback mode.
98
- *
99
- * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
100
- */
101
- define('CRYPT_TWOFISH_MODE_OFB', CRYPT_MODE_OFB);
102
- /**#@-*/
103
-
104
- /**#@+
105
- * @access private
106
- * @see Crypt_Base::Crypt_Base()
107
- */
108
- /**
109
- * Toggles the internal implementation
110
- */
111
- define('CRYPT_TWOFISH_MODE_INTERNAL', CRYPT_MODE_INTERNAL);
112
- /**
113
- * Toggles the mcrypt implementation
114
- */
115
- define('CRYPT_TWOFISH_MODE_MCRYPT', CRYPT_MODE_MCRYPT);
116
- /**#@-*/
117
-
118
- /**
119
- * Pure-PHP implementation of Twofish.
120
- *
121
- * @package Crypt_Twofish
122
- * @author Jim Wigginton <terrafrost@php.net>
123
- * @author Hans-Juergen Petrich <petrich@tronic-media.com>
124
- * @access public
125
- */
126
- class Crypt_Twofish extends Crypt_Base
127
- {
128
- /**
129
- * The namespace used by the cipher for its constants.
130
- *
131
- * @see Crypt_Base::const_namespace
132
- * @var String
133
- * @access private
134
- */
135
- var $const_namespace = 'TWOFISH';
136
-
137
- /**
138
- * The mcrypt specific name of the cipher
139
- *
140
- * @see Crypt_Base::cipher_name_mcrypt
141
- * @var String
142
- * @access private
143
- */
144
- var $cipher_name_mcrypt = 'twofish';
145
-
146
- /**
147
- * Optimizing value while CFB-encrypting
148
- *
149
- * @see Crypt_Base::cfb_init_len
150
- * @var Integer
151
- * @access private
152
- */
153
- var $cfb_init_len = 800;
154
-
155
- /**
156
- * Q-Table
157
- *
158
- * @var Array
159
- * @access private
160
- */
161
- var $q0 = array (
162
- 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76,
163
- 0x9A, 0x92, 0x80, 0x78, 0xE4, 0xDD, 0xD1, 0x38,
164
- 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
165
- 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48,
166
- 0xF2, 0xD0, 0x8B, 0x30, 0x84, 0x54, 0xDF, 0x23,
167
- 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
168
- 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C,
169
- 0xA6, 0xEB, 0xA5, 0xBE, 0x16, 0x0C, 0xE3, 0x61,
170
- 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B,
171
- 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1,
172
- 0xE1, 0xE6, 0xBD, 0x45, 0xE2, 0xF4, 0xB6, 0x66,
173
- 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
174
- 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA,
175
- 0xEA, 0x77, 0x39, 0xAF, 0x33, 0xC9, 0x62, 0x71,
176
- 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8,
177
- 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7,
178
- 0xA1, 0x1D, 0xAA, 0xED, 0x06, 0x70, 0xB2, 0xD2,
179
- 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
180
- 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB,
181
- 0x9E, 0x9C, 0x52, 0x1B, 0x5F, 0x93, 0x0A, 0xEF,
182
- 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B,
183
- 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64,
184
- 0x2A, 0xCE, 0xCB, 0x2F, 0xFC, 0x97, 0x05, 0x7A,
185
- 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
186
- 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02,
187
- 0xB8, 0xDA, 0xB0, 0x17, 0x55, 0x1F, 0x8A, 0x7D,
188
- 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72,
189
- 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34,
190
- 0x6E, 0x50, 0xDE, 0x68, 0x65, 0xBC, 0xDB, 0xF8,
191
- 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
192
- 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00,
193
- 0x6F, 0x9D, 0x36, 0x42, 0x4A, 0x5E, 0xC1, 0xE0
194
- );
195
-
196
- /**
197
- * Q-Table
198
- *
199
- * @var Array
200
- * @access private
201
- */
202
- var $q1 = array (
203
- 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8,
204
- 0x4A, 0xD3, 0xE6, 0x6B, 0x45, 0x7D, 0xE8, 0x4B,
205
- 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
206
- 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F,
207
- 0x5E, 0xBA, 0xAE, 0x5B, 0x8A, 0x00, 0xBC, 0x9D,
208
- 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
209
- 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3,
210
- 0xB2, 0x73, 0x4C, 0x54, 0x92, 0x74, 0x36, 0x51,
211
- 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96,
212
- 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C,
213
- 0x13, 0x95, 0x9C, 0xC7, 0x24, 0x46, 0x3B, 0x70,
214
- 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
215
- 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC,
216
- 0x03, 0x6F, 0x08, 0xBF, 0x40, 0xE7, 0x2B, 0xE2,
217
- 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9,
218
- 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17,
219
- 0x66, 0x94, 0xA1, 0x1D, 0x3D, 0xF0, 0xDE, 0xB3,
220
- 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
221
- 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49,
222
- 0x81, 0x88, 0xEE, 0x21, 0xC4, 0x1A, 0xEB, 0xD9,
223
- 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01,
224
- 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48,
225
- 0x4F, 0xF2, 0x65, 0x8E, 0x78, 0x5C, 0x58, 0x19,
226
- 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
227
- 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5,
228
- 0xCE, 0xE9, 0x68, 0x44, 0xE0, 0x4D, 0x43, 0x69,
229
- 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E,
230
- 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC,
231
- 0x22, 0xC9, 0xC0, 0x9B, 0x89, 0xD4, 0xED, 0xAB,
232
- 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
233
- 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2,
234
- 0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xBE, 0x91
235
- );
236
-
237
- /**
238
- * M-Table
239
- *
240
- * @var Array
241
- * @access private
242
- */
243
- var $m0 = array (
244
- 0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B, 0xE2E22BFB, 0x9E9EFAC8,
245
- 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B, 0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B,
246
- 0x3C3C57D6, 0x93938A32, 0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1,
247
- 0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA, 0xB0B0B306, 0x7575DE3F,
248
- 0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B, 0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D,
249
- 0xAEAE2C6D, 0x7F7FABC1, 0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5,
250
- 0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490, 0x3131272C, 0x808065A3,
251
- 0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154, 0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51,
252
- 0x2A2A3638, 0xC4C49CB0, 0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796,
253
- 0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228, 0x6767C027, 0xE9E9AF8C,
254
- 0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7, 0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70,
255
- 0x29294CCA, 0xF0F035E3, 0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8,
256
- 0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477, 0xC8C81DC3, 0x9999FFCC,
257
- 0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF, 0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2,
258
- 0xB5B53D79, 0x09090F0C, 0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9,
259
- 0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA, 0xEDEDD07A, 0x4343FC17,
260
- 0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D, 0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3,
261
- 0x5656E70B, 0xE3E3DA72, 0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E,
262
- 0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76, 0x8181942A, 0x91910149,
263
- 0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321, 0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9,
264
- 0x7878AEC5, 0xC5C56D39, 0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01,
265
- 0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D, 0x55559DF9, 0x7E7E5A48,
266
- 0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E, 0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519,
267
- 0x0606F48D, 0x404086E5, 0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64,
268
- 0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7, 0x2D2D333C, 0x3030D6A5,
269
- 0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544, 0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969,
270
- 0xD9D97929, 0x8686912E, 0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E,
271
- 0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A, 0xC1C112CF, 0x8585EBDC,
272
- 0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B, 0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB,
273
- 0xABABA212, 0x6F6F3EA2, 0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9,
274
- 0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504, 0x04047FF6, 0x272746C2,
275
- 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756, 0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91
276
- );
277
-
278
- /**
279
- * M-Table
280
- *
281
- * @var Array
282
- * @access private
283
- */
284
- var $m1 = array (
285
- 0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252, 0xA3658080, 0x76DFE4E4,
286
- 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A, 0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A,
287
- 0x0D54E6E6, 0xC6432020, 0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141,
288
- 0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444, 0x94B1FBFB, 0x485A7E7E,
289
- 0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424, 0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060,
290
- 0x1945FDFD, 0x5BA33A3A, 0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757,
291
- 0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383, 0x9B53AAAA, 0x7C635D5D,
292
- 0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A, 0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7,
293
- 0xC0F09090, 0x8CAFE9E9, 0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656,
294
- 0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1, 0xB499C3C3, 0xF1975B5B,
295
- 0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898, 0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8,
296
- 0xCCFF9999, 0x95EA1414, 0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3,
297
- 0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1, 0xBF7E9595, 0xBA207D7D,
298
- 0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989, 0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB,
299
- 0x81FB0F0F, 0x793DB5B5, 0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282,
300
- 0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E, 0x86135050, 0xE730F7F7,
301
- 0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E, 0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B,
302
- 0x410B9F9F, 0x7B8B0202, 0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC,
303
- 0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565, 0xB1C72B2B, 0xAB6F8E8E,
304
- 0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A, 0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9,
305
- 0x91EF1313, 0x85FE0808, 0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272,
306
- 0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A, 0x6929A9A9, 0x647D4F4F,
307
- 0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969, 0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED,
308
- 0xAC87D1D1, 0x7F8E0505, 0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5,
309
- 0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D, 0x4C5F7979, 0x02B6B7B7,
310
- 0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343, 0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2,
311
- 0x57AC3333, 0xC718CFCF, 0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3,
312
- 0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F, 0x99E51D1D, 0x34392323,
313
- 0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646, 0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA,
314
- 0xC8FA9E9E, 0xA882D6D6, 0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF,
315
- 0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A, 0x0FE25151, 0x00000000,
316
- 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7, 0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8
317
- );
318
-
319
- /**
320
- * M-Table
321
- *
322
- * @var Array
323
- * @access private
324
- */
325
- var $m2 = array (
326
- 0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B, 0xE2FBE22B, 0x9EC89EFA,
327
- 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F, 0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7,
328
- 0x3CD63C57, 0x9332938A, 0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783,
329
- 0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70, 0xB006B0B3, 0x753F75DE,
330
- 0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3, 0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0,
331
- 0xAE6DAE2C, 0x7FC17FAB, 0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA,
332
- 0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4, 0x312C3127, 0x80A38065,
333
- 0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41, 0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F,
334
- 0x2A382A36, 0xC4B0C49C, 0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07,
335
- 0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622, 0x672767C0, 0xE98CE9AF,
336
- 0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18, 0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C,
337
- 0x29CA294C, 0xF0E3F035, 0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96,
338
- 0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84, 0xC8C3C81D, 0x99CC99FF,
339
- 0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E, 0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E,
340
- 0xB579B53D, 0x090C090F, 0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD,
341
- 0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558, 0xED7AEDD0, 0x431743FC,
342
- 0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40, 0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71,
343
- 0x560B56E7, 0xE372E3DA, 0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85,
344
- 0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF, 0x812A8194, 0x91499101,
345
- 0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773, 0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5,
346
- 0x78C578AE, 0xC539C56D, 0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B,
347
- 0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C, 0x55F9559D, 0x7E487E5A,
348
- 0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19, 0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45,
349
- 0x068D06F4, 0x40E54086, 0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D,
350
- 0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74, 0x2D3C2D33, 0x30A530D6,
351
- 0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755, 0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929,
352
- 0xD929D979, 0x862E8691, 0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D,
353
- 0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4, 0xC1CFC112, 0x85DC85EB,
354
- 0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53, 0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F,
355
- 0xAB12ABA2, 0x6FA26F3E, 0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9,
356
- 0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705, 0x04F6047F, 0x27C22746,
357
- 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7, 0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF
358
- );
359
-
360
- /**
361
- * M-Table
362
- *
363
- * @var Array
364
- * @access private
365
- */
366
- var $m3 = array (
367
- 0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98, 0x6580A365, 0xDFE476DF,
368
- 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866, 0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836,
369
- 0x54E60D54, 0x4320C643, 0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77,
370
- 0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9, 0xB1FB94B1, 0x5A7E485A,
371
- 0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C, 0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5,
372
- 0x45FD1945, 0xA33A5BA3, 0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216,
373
- 0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F, 0x53AA9B53, 0x635D7C63,
374
- 0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25, 0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123,
375
- 0xF090C0F0, 0xAFE98CAF, 0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7,
376
- 0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4, 0x99C3B499, 0x975BF197,
377
- 0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E, 0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB,
378
- 0xFF99CCFF, 0xEA1495EA, 0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C,
379
- 0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12, 0x7E95BF7E, 0x207DBA20,
380
- 0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A, 0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137,
381
- 0xFB0F81FB, 0x3DB5793D, 0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE,
382
- 0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A, 0x13508613, 0x30F7E730,
383
- 0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C, 0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252,
384
- 0x0B9F410B, 0x8B027B8B, 0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4,
385
- 0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B, 0xC72BB1C7, 0x6F8EAB6F,
386
- 0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3, 0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A,
387
- 0xEF1391EF, 0xFE0885FE, 0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB,
388
- 0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85, 0x29A96929, 0x7D4F647D,
389
- 0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA, 0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0,
390
- 0x87D1AC87, 0x8E057F8E, 0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8,
391
- 0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33, 0x5F794C5F, 0xB6B702B6,
392
- 0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC, 0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38,
393
- 0xAC3357AC, 0x18CFC718, 0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA,
394
- 0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8, 0xE51D99E5, 0x39233439,
395
- 0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872, 0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6,
396
- 0xFA9EC8FA, 0x82D6A882, 0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D,
397
- 0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10, 0xE2510FE2, 0x00000000,
398
- 0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6, 0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8
399
- );
400
-
401
- /**
402
- * The Key Schedule Array
403
- *
404
- * @var Array
405
- * @access private
406
- */
407
- var $K = array();
408
-
409
- /**
410
- * The Key depended S-Table 0
411
- *
412
- * @var Array
413
- * @access private
414
- */
415
- var $S0 = array();
416
-
417
- /**
418
- * The Key depended S-Table 1
419
- *
420
- * @var Array
421
- * @access private
422
- */
423
- var $S1 = array();
424
-
425
- /**
426
- * The Key depended S-Table 2
427
- *
428
- * @var Array
429
- * @access private
430
- */
431
- var $S2 = array();
432
-
433
- /**
434
- * The Key depended S-Table 3
435
- *
436
- * @var Array
437
- * @access private
438
- */
439
- var $S3 = array();
440
-
441
- /**
442
- * Holds the last used key
443
- *
444
- * @var Array
445
- * @access private
446
- */
447
- var $kl;
448
-
449
- /**
450
- * Sets the key.
451
- *
452
- * Keys can be of any length. Twofish, itself, requires the use of a key that's 128, 192 or 256-bits long.
453
- * If the key is less than 256-bits we round the length up to the closest valid key length,
454
- * padding $key with null bytes. If the key is more than 256-bits, we trim the excess bits.
455
- *
456
- * If the key is not explicitly set, it'll be assumed a 128 bits key to be all null bytes.
457
- *
458
- * @access public
459
- * @see Crypt_Base::setKey()
460
- * @param String $key
461
- */
462
- function setKey($key)
463
- {
464
- $keylength = strlen($key);
465
- switch (true) {
466
- case $keylength <= 16:
467
- $key = str_pad($key, 16, "\0");
468
- break;
469
- case $keylength <= 24:
470
- $key = str_pad($key, 24, "\0");
471
- break;
472
- case $keylength < 32:
473
- $key = str_pad($key, 32, "\0");
474
- break;
475
- case $keylength > 32:
476
- $key = substr($key, 0, 32);
477
- }
478
- parent::setKey($key);
479
- }
480
-
481
- /**
482
- * Setup the key (expansion)
483
- *
484
- * @see Crypt_Base::_setupKey()
485
- * @access private
486
- */
487
- function _setupKey()
488
- {
489
- if (isset($this->kl['key']) && $this->key === $this->kl['key']) {
490
- // already expanded
491
- return;
492
- }
493
- $this->kl = array('key' => $this->key);
494
-
495
- /* Key expanding and generating the key-depended s-boxes */
496
- $le_longs = unpack('V*', $this->key);
497
- $key = unpack('C*', $this->key);
498
- $m0 = $this->m0;
499
- $m1 = $this->m1;
500
- $m2 = $this->m2;
501
- $m3 = $this->m3;
502
- $q0 = $this->q0;
503
- $q1 = $this->q1;
504
-
505
- $K = $S0 = $S1 = $S2 = $S3 = array();
506
-
507
- switch (strlen($this->key)) {
508
- case 16:
509
- list ($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[1], $le_longs[2]);
510
- list ($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[3], $le_longs[4]);
511
- for ($i = 0, $j = 1; $i < 40; $i+= 2,$j+= 2) {
512
- $A = $m0[$q0[$q0[$i] ^ $key[ 9]] ^ $key[1]] ^
513
- $m1[$q0[$q1[$i] ^ $key[10]] ^ $key[2]] ^
514
- $m2[$q1[$q0[$i] ^ $key[11]] ^ $key[3]] ^
515
- $m3[$q1[$q1[$i] ^ $key[12]] ^ $key[4]];
516
- $B = $m0[$q0[$q0[$j] ^ $key[13]] ^ $key[5]] ^
517
- $m1[$q0[$q1[$j] ^ $key[14]] ^ $key[6]] ^
518
- $m2[$q1[$q0[$j] ^ $key[15]] ^ $key[7]] ^
519
- $m3[$q1[$q1[$j] ^ $key[16]] ^ $key[8]];
520
- $B = ($B << 8) | ($B >> 24 & 0xff);
521
- $K[] = $A+= $B;
522
- $K[] = (($A+= $B) << 9 | $A >> 23 & 0x1ff);
523
- }
524
- for ($i = 0; $i < 256; ++$i) {
525
- $S0[$i] = $m0[$q0[$q0[$i] ^ $s4] ^ $s0];
526
- $S1[$i] = $m1[$q0[$q1[$i] ^ $s5] ^ $s1];
527
- $S2[$i] = $m2[$q1[$q0[$i] ^ $s6] ^ $s2];
528
- $S3[$i] = $m3[$q1[$q1[$i] ^ $s7] ^ $s3];
529
- }
530
- break;
531
- case 24:
532
- list ($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[1], $le_longs[2]);
533
- list ($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[3], $le_longs[4]);
534
- list ($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[5], $le_longs[6]);
535
- for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
536
- $A = $m0[$q0[$q0[$q1[$i] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^
537
- $m1[$q0[$q1[$q1[$i] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^
538
- $m2[$q1[$q0[$q0[$i] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^
539
- $m3[$q1[$q1[$q0[$i] ^ $key[20]] ^ $key[12]] ^ $key[4]];
540
- $B = $m0[$q0[$q0[$q1[$j] ^ $key[21]] ^ $key[13]] ^ $key[5]] ^
541
- $m1[$q0[$q1[$q1[$j] ^ $key[22]] ^ $key[14]] ^ $key[6]] ^
542
- $m2[$q1[$q0[$q0[$j] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^
543
- $m3[$q1[$q1[$q0[$j] ^ $key[24]] ^ $key[16]] ^ $key[8]];
544
- $B = ($B << 8) | ($B >> 24 & 0xff);
545
- $K[] = $A+= $B;
546
- $K[] = (($A+= $B) << 9 | $A >> 23 & 0x1ff);
547
- }
548
- for ($i = 0; $i < 256; ++$i) {
549
- $S0[$i] = $m0[$q0[$q0[$q1[$i] ^ $s8] ^ $s4] ^ $s0];
550
- $S1[$i] = $m1[$q0[$q1[$q1[$i] ^ $s9] ^ $s5] ^ $s1];
551
- $S2[$i] = $m2[$q1[$q0[$q0[$i] ^ $sa] ^ $s6] ^ $s2];
552
- $S3[$i] = $m3[$q1[$q1[$q0[$i] ^ $sb] ^ $s7] ^ $s3];
553
- }
554
- break;
555
- default: // 32
556
- list ($sf, $se, $sd, $sc) = $this->_mdsrem($le_longs[1], $le_longs[2]);
557
- list ($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[3], $le_longs[4]);
558
- list ($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[5], $le_longs[6]);
559
- list ($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[7], $le_longs[8]);
560
- for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
561
- $A = $m0[$q0[$q0[$q1[$q1[$i] ^ $key[25]] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^
562
- $m1[$q0[$q1[$q1[$q0[$i] ^ $key[26]] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^
563
- $m2[$q1[$q0[$q0[$q0[$i] ^ $key[27]] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^
564
- $m3[$q1[$q1[$q0[$q1[$i] ^ $key[28]] ^ $key[20]] ^ $key[12]] ^ $key[4]];
565
- $B = $m0[$q0[$q0[$q1[$q1[$j] ^ $key[29]] ^ $key[21]] ^ $key[13]] ^ $key[5]] ^
566
- $m1[$q0[$q1[$q1[$q0[$j] ^ $key[30]] ^ $key[22]] ^ $key[14]] ^ $key[6]] ^
567
- $m2[$q1[$q0[$q0[$q0[$j] ^ $key[31]] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^
568
- $m3[$q1[$q1[$q0[$q1[$j] ^ $key[32]] ^ $key[24]] ^ $key[16]] ^ $key[8]];
569
- $B = ($B << 8) | ($B >> 24 & 0xff);
570
- $K[] = $A+= $B;
571
- $K[] = (($A+= $B) << 9 | $A >> 23 & 0x1ff);
572
- }
573
- for ($i = 0; $i < 256; ++$i) {
574
- $S0[$i] = $m0[$q0[$q0[$q1[$q1[$i] ^ $sc] ^ $s8] ^ $s4] ^ $s0];
575
- $S1[$i] = $m1[$q0[$q1[$q1[$q0[$i] ^ $sd] ^ $s9] ^ $s5] ^ $s1];
576
- $S2[$i] = $m2[$q1[$q0[$q0[$q0[$i] ^ $se] ^ $sa] ^ $s6] ^ $s2];
577
- $S3[$i] = $m3[$q1[$q1[$q0[$q1[$i] ^ $sf] ^ $sb] ^ $s7] ^ $s3];
578
- }
579
- }
580
-
581
- $this->K = $K;
582
- $this->S0 = $S0;
583
- $this->S1 = $S1;
584
- $this->S2 = $S2;
585
- $this->S3 = $S3;
586
- }
587
-
588
- /**
589
- * _mdsrem function using by the twofish cipher algorithm
590
- *
591
- * @access private
592
- * @param String $A
593
- * @param String $B
594
- * @return Array
595
- */
596
- function _mdsrem($A, $B)
597
- {
598
- // No gain by unrolling this loop.
599
- for ($i = 0; $i < 8; ++$i) {
600
- // Get most significant coefficient.
601
- $t = 0xff & ($B >> 24);
602
-
603
- // Shift the others up.
604
- $B = ($B << 8) | (0xff & ($A >> 24));
605
- $A<<= 8;
606
-
607
- $u = $t << 1;
608
-
609
- // Subtract the modular polynomial on overflow.
610
- if ($t & 0x80) {
611
- $u^= 0x14d;
612
- }
613
-
614
- // Remove t * (a * x^2 + 1).
615
- $B ^= $t ^ ($u << 16);
616
-
617
- // Form u = a*t + t/a = t*(a + 1/a).
618
- $u^= 0x7fffffff & ($t >> 1);
619
-
620
- // Add the modular polynomial on underflow.
621
- if ($t & 0x01) $u^= 0xa6 ;
622
-
623
- // Remove t * (a + 1/a) * (x^3 + x).
624
- $B^= ($u << 24) | ($u << 8);
625
- }
626
-
627
- return array(
628
- 0xff & $B >> 24,
629
- 0xff & $B >> 16,
630
- 0xff & $B >> 8,
631
- 0xff & $B);
632
- }
633
-
634
- /**
635
- * Encrypts a block
636
- *
637
- * @access private
638
- * @param String $in
639
- * @return String
640
- */
641
- function _encryptBlock($in)
642
- {
643
- $S0 = $this->S0;
644
- $S1 = $this->S1;
645
- $S2 = $this->S2;
646
- $S3 = $this->S3;
647
- $K = $this->K;
648
-
649
- $in = unpack("V4", $in);
650
- $R0 = $K[0] ^ $in[1];
651
- $R1 = $K[1] ^ $in[2];
652
- $R2 = $K[2] ^ $in[3];
653
- $R3 = $K[3] ^ $in[4];
654
-
655
- $ki = 7;
656
- while ($ki < 39) {
657
- $t0 = $S0[ $R0 & 0xff] ^
658
- $S1[($R0 >> 8) & 0xff] ^
659
- $S2[($R0 >> 16) & 0xff] ^
660
- $S3[($R0 >> 24) & 0xff];
661
- $t1 = $S0[($R1 >> 24) & 0xff] ^
662
- $S1[ $R1 & 0xff] ^
663
- $S2[($R1 >> 8) & 0xff] ^
664
- $S3[($R1 >> 16) & 0xff];
665
- $R2^= $t0 + $t1 + $K[++$ki];
666
- $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
667
- $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ($t0 + ($t1 << 1) + $K[++$ki]);
668
-
669
- $t0 = $S0[ $R2 & 0xff] ^
670
- $S1[($R2 >> 8) & 0xff] ^
671
- $S2[($R2 >> 16) & 0xff] ^
672
- $S3[($R2 >> 24) & 0xff];
673
- $t1 = $S0[($R3 >> 24) & 0xff] ^
674
- $S1[ $R3 & 0xff] ^
675
- $S2[($R3 >> 8) & 0xff] ^
676
- $S3[($R3 >> 16) & 0xff];
677
- $R0^= ($t0 + $t1 + $K[++$ki]);
678
- $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
679
- $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ($t0 + ($t1 << 1) + $K[++$ki]);
680
- }
681
-
682
- // @codingStandardsIgnoreStart
683
- return pack("V4", $K[4] ^ $R2,
684
- $K[5] ^ $R3,
685
- $K[6] ^ $R0,
686
- $K[7] ^ $R1);
687
- // @codingStandardsIgnoreEnd
688
- }
689
-
690
- /**
691
- * Decrypts a block
692
- *
693
- * @access private
694
- * @param String $in
695
- * @return String
696
- */
697
- function _decryptBlock($in)
698
- {
699
- $S0 = $this->S0;
700
- $S1 = $this->S1;
701
- $S2 = $this->S2;
702
- $S3 = $this->S3;
703
- $K = $this->K;
704
-
705
- $in = unpack("V4", $in);
706
- $R0 = $K[4] ^ $in[1];
707
- $R1 = $K[5] ^ $in[2];
708
- $R2 = $K[6] ^ $in[3];
709
- $R3 = $K[7] ^ $in[4];
710
-
711
- $ki = 40;
712
- while ($ki > 8) {
713
- $t0 = $S0[$R0 & 0xff] ^
714
- $S1[$R0 >> 8 & 0xff] ^
715
- $S2[$R0 >> 16 & 0xff] ^
716
- $S3[$R0 >> 24 & 0xff];
717
- $t1 = $S0[$R1 >> 24 & 0xff] ^
718
- $S1[$R1 & 0xff] ^
719
- $S2[$R1 >> 8 & 0xff] ^
720
- $S3[$R1 >> 16 & 0xff];
721
- $R3^= $t0 + ($t1 << 1) + $K[--$ki];
722
- $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
723
- $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ($t0 + $t1 + $K[--$ki]);
724
-
725
- $t0 = $S0[$R2 & 0xff] ^
726
- $S1[$R2 >> 8 & 0xff] ^
727
- $S2[$R2 >> 16 & 0xff] ^
728
- $S3[$R2 >> 24 & 0xff];
729
- $t1 = $S0[$R3 >> 24 & 0xff] ^
730
- $S1[$R3 & 0xff] ^
731
- $S2[$R3 >> 8 & 0xff] ^
732
- $S3[$R3 >> 16 & 0xff];
733
- $R1^= $t0 + ($t1 << 1) + $K[--$ki];
734
- $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
735
- $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ($t0 + $t1 + $K[--$ki]);
736
- }
737
-
738
- // @codingStandardsIgnoreStart
739
- return pack("V4", $K[0] ^ $R2,
740
- $K[1] ^ $R3,
741
- $K[2] ^ $R0,
742
- $K[3] ^ $R1);
743
- // @codingStandardsIgnoreEnd
744
- }
745
-
746
- /**
747
- * Setup the performance-optimized function for de/encrypt()
748
- *
749
- * @see Crypt_Base::_setupInlineCrypt()
750
- * @access private
751
- */
752
- function _setupInlineCrypt()
753
- {
754
- $lambda_functions =& Crypt_Twofish::_getLambdaFunctions();
755
-
756
- // Max. 10 Ultra-Hi-optimized inline-crypt functions. After that, we'll (still) create very fast code, but not the ultimate fast one.
757
- $gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
758
-
759
- switch (true) {
760
- case $gen_hi_opt_code:
761
- $code_hash = md5(str_pad("Crypt_Twofish, {$this->mode}, ", 32, "\0") . $this->key);
762
- break;
763
- default:
764
- $code_hash = "Crypt_Twofish, {$this->mode}";
765
- }
766
-
767
- if (!isset($lambda_functions[$code_hash])) {
768
- switch (true) {
769
- case $gen_hi_opt_code:
770
- $K = $this->K;
771
-
772
- $init_crypt = '
773
- static $S0, $S1, $S2, $S3;
774
- if (!$S0) {
775
- for ($i = 0; $i < 256; ++$i) {
776
- $S0[] = (int)$self->S0[$i];
777
- $S1[] = (int)$self->S1[$i];
778
- $S2[] = (int)$self->S2[$i];
779
- $S3[] = (int)$self->S3[$i];
780
- }
781
- }
782
- ';
783
- break;
784
- default:
785
- $K = array();
786
- for ($i = 0; $i < 40; ++$i) {
787
- $K[] = '$K_' . $i;
788
- }
789
-
790
- $init_crypt = '
791
- $S0 = $self->S0;
792
- $S1 = $self->S1;
793
- $S2 = $self->S2;
794
- $S3 = $self->S3;
795
- list(' . implode(',', $K) . ') = $self->K;
796
- ';
797
- }
798
-
799
- // Generating encrypt code:
800
- $encrypt_block = '
801
- $in = unpack("V4", $in);
802
- $R0 = '.$K[0].' ^ $in[1];
803
- $R1 = '.$K[1].' ^ $in[2];
804
- $R2 = '.$K[2].' ^ $in[3];
805
- $R3 = '.$K[3].' ^ $in[4];
806
- ';
807
- for ($ki = 7, $i = 0; $i < 8; ++$i) {
808
- $encrypt_block.= '
809
- $t0 = $S0[ $R0 & 0xff] ^
810
- $S1[($R0 >> 8) & 0xff] ^
811
- $S2[($R0 >> 16) & 0xff] ^
812
- $S3[($R0 >> 24) & 0xff];
813
- $t1 = $S0[($R1 >> 24) & 0xff] ^
814
- $S1[ $R1 & 0xff] ^
815
- $S2[($R1 >> 8) & 0xff] ^
816
- $S3[($R1 >> 16) & 0xff];
817
- $R2^= ($t0 + $t1 + '.$K[++$ki].');
818
- $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
819
- $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ($t0 + ($t1 << 1) + '.$K[++$ki].');
820
-
821
- $t0 = $S0[ $R2 & 0xff] ^
822
- $S1[($R2 >> 8) & 0xff] ^
823
- $S2[($R2 >> 16) & 0xff] ^
824
- $S3[($R2 >> 24) & 0xff];
825
- $t1 = $S0[($R3 >> 24) & 0xff] ^
826
- $S1[ $R3 & 0xff] ^
827
- $S2[($R3 >> 8) & 0xff] ^
828
- $S3[($R3 >> 16) & 0xff];
829
- $R0^= ($t0 + $t1 + '.$K[++$ki].');
830
- $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
831
- $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ($t0 + ($t1 << 1) + '.$K[++$ki].');
832
- ';
833
- }
834
- $encrypt_block.= '
835
- $in = pack("V4", '.$K[4].' ^ $R2,
836
- '.$K[5].' ^ $R3,
837
- '.$K[6].' ^ $R0,
838
- '.$K[7].' ^ $R1);
839
- ';
840
-
841
- // Generating decrypt code:
842
- $decrypt_block = '
843
- $in = unpack("V4", $in);
844
- $R0 = '.$K[4].' ^ $in[1];
845
- $R1 = '.$K[5].' ^ $in[2];
846
- $R2 = '.$K[6].' ^ $in[3];
847
- $R3 = '.$K[7].' ^ $in[4];
848
- ';
849
- for ($ki = 40, $i = 0; $i < 8; ++$i) {
850
- $decrypt_block.= '
851
- $t0 = $S0[$R0 & 0xff] ^
852
- $S1[$R0 >> 8 & 0xff] ^
853
- $S2[$R0 >> 16 & 0xff] ^
854
- $S3[$R0 >> 24 & 0xff];
855
- $t1 = $S0[$R1 >> 24 & 0xff] ^
856
- $S1[$R1 & 0xff] ^
857
- $S2[$R1 >> 8 & 0xff] ^
858
- $S3[$R1 >> 16 & 0xff];
859
- $R3^= $t0 + ($t1 << 1) + '.$K[--$ki].';
860
- $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
861
- $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ($t0 + $t1 + '.$K[--$ki].');
862
-
863
- $t0 = $S0[$R2 & 0xff] ^
864
- $S1[$R2 >> 8 & 0xff] ^
865
- $S2[$R2 >> 16 & 0xff] ^
866
- $S3[$R2 >> 24 & 0xff];
867
- $t1 = $S0[$R3 >> 24 & 0xff] ^
868
- $S1[$R3 & 0xff] ^
869
- $S2[$R3 >> 8 & 0xff] ^
870
- $S3[$R3 >> 16 & 0xff];
871
- $R1^= $t0 + ($t1 << 1) + '.$K[--$ki].';
872
- $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
873
- $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ($t0 + $t1 + '.$K[--$ki].');
874
- ';
875
- }
876
- $decrypt_block.= '
877
- $in = pack("V4", '.$K[0].' ^ $R2,
878
- '.$K[1].' ^ $R3,
879
- '.$K[2].' ^ $R0,
880
- '.$K[3].' ^ $R1);
881
- ';
882
-
883
- $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
884
- array(
885
- 'init_crypt' => $init_crypt,
886
- 'init_encrypt' => '',
887
- 'init_decrypt' => '',
888
- 'encrypt_block' => $encrypt_block,
889
- 'decrypt_block' => $decrypt_block
890
- )
891
- );
892
- }
893
- $this->inline_crypt = $lambda_functions[$code_hash];
894
- }
895
- }
1
+ <?php
2
+
3
+ /**
4
+ * Pure-PHP implementation of Twofish.
5
+ *
6
+ * Uses mcrypt, if available, and an internal implementation, otherwise.
7
+ *
8
+ * PHP versions 4 and 5
9
+ *
10
+ * Useful resources are as follows:
11
+ *
12
+ * - {@link http://en.wikipedia.org/wiki/Twofish Wikipedia description of Twofish}
13
+ *
14
+ * Here's a short example of how to use this library:
15
+ * <code>
16
+ * <?php
17
+ * include 'Crypt/Twofish.php';
18
+ *
19
+ * $twofish = new Crypt_Twofish();
20
+ *
21
+ * $twofish->setKey('12345678901234567890123456789012');
22
+ *
23
+ * $plaintext = str_repeat('a', 1024);
24
+ *
25
+ * echo $twofish->decrypt($twofish->encrypt($plaintext));
26
+ * ?>
27
+ * </code>
28
+ *
29
+ * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
30
+ * of this software and associated documentation files (the "Software"), to deal
31
+ * in the Software without restriction, including without limitation the rights
32
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
33
+ * copies of the Software, and to permit persons to whom the Software is
34
+ * furnished to do so, subject to the following conditions:
35
+ *
36
+ * The above copyright notice and this permission notice shall be included in
37
+ * all copies or substantial portions of the Software.
38
+ *
39
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
40
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
41
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
42
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
43
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
44
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
45
+ * THE SOFTWARE.
46
+ *
47
+ * @category Crypt
48
+ * @package Crypt_Twofish
49
+ * @author Jim Wigginton <terrafrost@php.net>
50
+ * @author Hans-Juergen Petrich <petrich@tronic-media.com>
51
+ * @copyright 2007 Jim Wigginton
52
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
53
+ * @link http://phpseclib.sourceforge.net
54
+ */
55
+
56
+ /**
57
+ * Include Crypt_Base
58
+ *
59
+ * Base cipher class
60
+ */
61
+ if (!class_exists('Crypt_Base')) {
62
+ include_once 'Base.php';
63
+ }
64
+
65
+ /**#@+
66
+ * @access public
67
+ * @see Crypt_Twofish::encrypt()
68
+ * @see Crypt_Twofish::decrypt()
69
+ */
70
+ /**
71
+ * Encrypt / decrypt using the Counter mode.
72
+ *
73
+ * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
74
+ *
75
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
76
+ */
77
+ define('CRYPT_TWOFISH_MODE_CTR', CRYPT_MODE_CTR);
78
+ /**
79
+ * Encrypt / decrypt using the Electronic Code Book mode.
80
+ *
81
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
82
+ */
83
+ define('CRYPT_TWOFISH_MODE_ECB', CRYPT_MODE_ECB);
84
+ /**
85
+ * Encrypt / decrypt using the Code Book Chaining mode.
86
+ *
87
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
88
+ */
89
+ define('CRYPT_TWOFISH_MODE_CBC', CRYPT_MODE_CBC);
90
+ /**
91
+ * Encrypt / decrypt using the Cipher Feedback mode.
92
+ *
93
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
94
+ */
95
+ define('CRYPT_TWOFISH_MODE_CFB', CRYPT_MODE_CFB);
96
+ /**
97
+ * Encrypt / decrypt using the Cipher Feedback mode.
98
+ *
99
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
100
+ */
101
+ define('CRYPT_TWOFISH_MODE_OFB', CRYPT_MODE_OFB);
102
+ /**#@-*/
103
+
104
+ /**
105
+ * Pure-PHP implementation of Twofish.
106
+ *
107
+ * @package Crypt_Twofish
108
+ * @author Jim Wigginton <terrafrost@php.net>
109
+ * @author Hans-Juergen Petrich <petrich@tronic-media.com>
110
+ * @access public
111
+ */
112
+ class Crypt_Twofish extends Crypt_Base
113
+ {
114
+ /**
115
+ * The namespace used by the cipher for its constants.
116
+ *
117
+ * @see Crypt_Base::const_namespace
118
+ * @var String
119
+ * @access private
120
+ */
121
+ var $const_namespace = 'TWOFISH';
122
+
123
+ /**
124
+ * The mcrypt specific name of the cipher
125
+ *
126
+ * @see Crypt_Base::cipher_name_mcrypt
127
+ * @var String
128
+ * @access private
129
+ */
130
+ var $cipher_name_mcrypt = 'twofish';
131
+
132
+ /**
133
+ * Optimizing value while CFB-encrypting
134
+ *
135
+ * @see Crypt_Base::cfb_init_len
136
+ * @var Integer
137
+ * @access private
138
+ */
139
+ var $cfb_init_len = 800;
140
+
141
+ /**
142
+ * Q-Table
143
+ *
144
+ * @var Array
145
+ * @access private
146
+ */
147
+ var $q0 = array (
148
+ 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76,
149
+ 0x9A, 0x92, 0x80, 0x78, 0xE4, 0xDD, 0xD1, 0x38,
150
+ 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
151
+ 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48,
152
+ 0xF2, 0xD0, 0x8B, 0x30, 0x84, 0x54, 0xDF, 0x23,
153
+ 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
154
+ 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C,
155
+ 0xA6, 0xEB, 0xA5, 0xBE, 0x16, 0x0C, 0xE3, 0x61,
156
+ 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B,
157
+ 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1,
158
+ 0xE1, 0xE6, 0xBD, 0x45, 0xE2, 0xF4, 0xB6, 0x66,
159
+ 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
160
+ 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA,
161
+ 0xEA, 0x77, 0x39, 0xAF, 0x33, 0xC9, 0x62, 0x71,
162
+ 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8,
163
+ 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7,
164
+ 0xA1, 0x1D, 0xAA, 0xED, 0x06, 0x70, 0xB2, 0xD2,
165
+ 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
166
+ 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB,
167
+ 0x9E, 0x9C, 0x52, 0x1B, 0x5F, 0x93, 0x0A, 0xEF,
168
+ 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B,
169
+ 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64,
170
+ 0x2A, 0xCE, 0xCB, 0x2F, 0xFC, 0x97, 0x05, 0x7A,
171
+ 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
172
+ 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02,
173
+ 0xB8, 0xDA, 0xB0, 0x17, 0x55, 0x1F, 0x8A, 0x7D,
174
+ 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72,
175
+ 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34,
176
+ 0x6E, 0x50, 0xDE, 0x68, 0x65, 0xBC, 0xDB, 0xF8,
177
+ 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
178
+ 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00,
179
+ 0x6F, 0x9D, 0x36, 0x42, 0x4A, 0x5E, 0xC1, 0xE0
180
+ );
181
+
182
+ /**
183
+ * Q-Table
184
+ *
185
+ * @var Array
186
+ * @access private
187
+ */
188
+ var $q1 = array (
189
+ 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8,
190
+ 0x4A, 0xD3, 0xE6, 0x6B, 0x45, 0x7D, 0xE8, 0x4B,
191
+ 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
192
+ 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F,
193
+ 0x5E, 0xBA, 0xAE, 0x5B, 0x8A, 0x00, 0xBC, 0x9D,
194
+ 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
195
+ 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3,
196
+ 0xB2, 0x73, 0x4C, 0x54, 0x92, 0x74, 0x36, 0x51,
197
+ 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96,
198
+ 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C,
199
+ 0x13, 0x95, 0x9C, 0xC7, 0x24, 0x46, 0x3B, 0x70,
200
+ 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
201
+ 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC,
202
+ 0x03, 0x6F, 0x08, 0xBF, 0x40, 0xE7, 0x2B, 0xE2,
203
+ 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9,
204
+ 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17,
205
+ 0x66, 0x94, 0xA1, 0x1D, 0x3D, 0xF0, 0xDE, 0xB3,
206
+ 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
207
+ 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49,
208
+ 0x81, 0x88, 0xEE, 0x21, 0xC4, 0x1A, 0xEB, 0xD9,
209
+ 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01,
210
+ 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48,
211
+ 0x4F, 0xF2, 0x65, 0x8E, 0x78, 0x5C, 0x58, 0x19,
212
+ 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
213
+ 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5,
214
+ 0xCE, 0xE9, 0x68, 0x44, 0xE0, 0x4D, 0x43, 0x69,
215
+ 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E,
216
+ 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC,
217
+ 0x22, 0xC9, 0xC0, 0x9B, 0x89, 0xD4, 0xED, 0xAB,
218
+ 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
219
+ 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2,
220
+ 0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xBE, 0x91
221
+ );
222
+
223
+ /**
224
+ * M-Table
225
+ *
226
+ * @var Array
227
+ * @access private
228
+ */
229
+ var $m0 = array (
230
+ 0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B, 0xE2E22BFB, 0x9E9EFAC8,
231
+ 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B, 0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B,
232
+ 0x3C3C57D6, 0x93938A32, 0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1,
233
+ 0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA, 0xB0B0B306, 0x7575DE3F,
234
+ 0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B, 0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D,
235
+ 0xAEAE2C6D, 0x7F7FABC1, 0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5,
236
+ 0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490, 0x3131272C, 0x808065A3,
237
+ 0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154, 0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51,
238
+ 0x2A2A3638, 0xC4C49CB0, 0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796,
239
+ 0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228, 0x6767C027, 0xE9E9AF8C,
240
+ 0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7, 0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70,
241
+ 0x29294CCA, 0xF0F035E3, 0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8,
242
+ 0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477, 0xC8C81DC3, 0x9999FFCC,
243
+ 0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF, 0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2,
244
+ 0xB5B53D79, 0x09090F0C, 0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9,
245
+ 0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA, 0xEDEDD07A, 0x4343FC17,
246
+ 0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D, 0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3,
247
+ 0x5656E70B, 0xE3E3DA72, 0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E,
248
+ 0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76, 0x8181942A, 0x91910149,
249
+ 0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321, 0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9,
250
+ 0x7878AEC5, 0xC5C56D39, 0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01,
251
+ 0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D, 0x55559DF9, 0x7E7E5A48,
252
+ 0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E, 0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519,
253
+ 0x0606F48D, 0x404086E5, 0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64,
254
+ 0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7, 0x2D2D333C, 0x3030D6A5,
255
+ 0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544, 0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969,
256
+ 0xD9D97929, 0x8686912E, 0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E,
257
+ 0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A, 0xC1C112CF, 0x8585EBDC,
258
+ 0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B, 0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB,
259
+ 0xABABA212, 0x6F6F3EA2, 0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9,
260
+ 0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504, 0x04047FF6, 0x272746C2,
261
+ 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756, 0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91
262
+ );
263
+
264
+ /**
265
+ * M-Table
266
+ *
267
+ * @var Array
268
+ * @access private
269
+ */
270
+ var $m1 = array (
271
+ 0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252, 0xA3658080, 0x76DFE4E4,
272
+ 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A, 0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A,
273
+ 0x0D54E6E6, 0xC6432020, 0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141,
274
+ 0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444, 0x94B1FBFB, 0x485A7E7E,
275
+ 0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424, 0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060,
276
+ 0x1945FDFD, 0x5BA33A3A, 0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757,
277
+ 0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383, 0x9B53AAAA, 0x7C635D5D,
278
+ 0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A, 0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7,
279
+ 0xC0F09090, 0x8CAFE9E9, 0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656,
280
+ 0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1, 0xB499C3C3, 0xF1975B5B,
281
+ 0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898, 0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8,
282
+ 0xCCFF9999, 0x95EA1414, 0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3,
283
+ 0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1, 0xBF7E9595, 0xBA207D7D,
284
+ 0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989, 0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB,
285
+ 0x81FB0F0F, 0x793DB5B5, 0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282,
286
+ 0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E, 0x86135050, 0xE730F7F7,
287
+ 0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E, 0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B,
288
+ 0x410B9F9F, 0x7B8B0202, 0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC,
289
+ 0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565, 0xB1C72B2B, 0xAB6F8E8E,
290
+ 0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A, 0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9,
291
+ 0x91EF1313, 0x85FE0808, 0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272,
292
+ 0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A, 0x6929A9A9, 0x647D4F4F,
293
+ 0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969, 0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED,
294
+ 0xAC87D1D1, 0x7F8E0505, 0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5,
295
+ 0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D, 0x4C5F7979, 0x02B6B7B7,
296
+ 0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343, 0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2,
297
+ 0x57AC3333, 0xC718CFCF, 0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3,
298
+ 0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F, 0x99E51D1D, 0x34392323,
299
+ 0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646, 0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA,
300
+ 0xC8FA9E9E, 0xA882D6D6, 0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF,
301
+ 0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A, 0x0FE25151, 0x00000000,
302
+ 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7, 0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8
303
+ );
304
+
305
+ /**
306
+ * M-Table
307
+ *
308
+ * @var Array
309
+ * @access private
310
+ */
311
+ var $m2 = array (
312
+ 0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B, 0xE2FBE22B, 0x9EC89EFA,
313
+ 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F, 0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7,
314
+ 0x3CD63C57, 0x9332938A, 0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783,
315
+ 0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70, 0xB006B0B3, 0x753F75DE,
316
+ 0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3, 0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0,
317
+ 0xAE6DAE2C, 0x7FC17FAB, 0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA,
318
+ 0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4, 0x312C3127, 0x80A38065,
319
+ 0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41, 0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F,
320
+ 0x2A382A36, 0xC4B0C49C, 0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07,
321
+ 0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622, 0x672767C0, 0xE98CE9AF,
322
+ 0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18, 0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C,
323
+ 0x29CA294C, 0xF0E3F035, 0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96,
324
+ 0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84, 0xC8C3C81D, 0x99CC99FF,
325
+ 0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E, 0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E,
326
+ 0xB579B53D, 0x090C090F, 0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD,
327
+ 0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558, 0xED7AEDD0, 0x431743FC,
328
+ 0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40, 0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71,
329
+ 0x560B56E7, 0xE372E3DA, 0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85,
330
+ 0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF, 0x812A8194, 0x91499101,
331
+ 0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773, 0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5,
332
+ 0x78C578AE, 0xC539C56D, 0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B,
333
+ 0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C, 0x55F9559D, 0x7E487E5A,
334
+ 0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19, 0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45,
335
+ 0x068D06F4, 0x40E54086, 0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D,
336
+ 0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74, 0x2D3C2D33, 0x30A530D6,
337
+ 0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755, 0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929,
338
+ 0xD929D979, 0x862E8691, 0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D,
339
+ 0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4, 0xC1CFC112, 0x85DC85EB,
340
+ 0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53, 0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F,
341
+ 0xAB12ABA2, 0x6FA26F3E, 0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9,
342
+ 0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705, 0x04F6047F, 0x27C22746,
343
+ 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7, 0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF
344
+ );
345
+
346
+ /**
347
+ * M-Table
348
+ *
349
+ * @var Array
350
+ * @access private
351
+ */
352
+ var $m3 = array (
353
+ 0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98, 0x6580A365, 0xDFE476DF,
354
+ 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866, 0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836,
355
+ 0x54E60D54, 0x4320C643, 0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77,
356
+ 0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9, 0xB1FB94B1, 0x5A7E485A,
357
+ 0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C, 0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5,
358
+ 0x45FD1945, 0xA33A5BA3, 0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216,
359
+ 0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F, 0x53AA9B53, 0x635D7C63,
360
+ 0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25, 0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123,
361
+ 0xF090C0F0, 0xAFE98CAF, 0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7,
362
+ 0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4, 0x99C3B499, 0x975BF197,
363
+ 0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E, 0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB,
364
+ 0xFF99CCFF, 0xEA1495EA, 0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C,
365
+ 0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12, 0x7E95BF7E, 0x207DBA20,
366
+ 0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A, 0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137,
367
+ 0xFB0F81FB, 0x3DB5793D, 0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE,
368
+ 0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A, 0x13508613, 0x30F7E730,
369
+ 0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C, 0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252,
370
+ 0x0B9F410B, 0x8B027B8B, 0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4,
371
+ 0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B, 0xC72BB1C7, 0x6F8EAB6F,
372
+ 0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3, 0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A,
373
+ 0xEF1391EF, 0xFE0885FE, 0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB,
374
+ 0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85, 0x29A96929, 0x7D4F647D,
375
+ 0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA, 0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0,
376
+ 0x87D1AC87, 0x8E057F8E, 0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8,
377
+ 0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33, 0x5F794C5F, 0xB6B702B6,
378
+ 0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC, 0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38,
379
+ 0xAC3357AC, 0x18CFC718, 0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA,
380
+ 0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8, 0xE51D99E5, 0x39233439,
381
+ 0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872, 0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6,
382
+ 0xFA9EC8FA, 0x82D6A882, 0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D,
383
+ 0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10, 0xE2510FE2, 0x00000000,
384
+ 0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6, 0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8
385
+ );
386
+
387
+ /**
388
+ * The Key Schedule Array
389
+ *
390
+ * @var Array
391
+ * @access private
392
+ */
393
+ var $K = array();
394
+
395
+ /**
396
+ * The Key depended S-Table 0
397
+ *
398
+ * @var Array
399
+ * @access private
400
+ */
401
+ var $S0 = array();
402
+
403
+ /**
404
+ * The Key depended S-Table 1
405
+ *
406
+ * @var Array
407
+ * @access private
408
+ */
409
+ var $S1 = array();
410
+
411
+ /**
412
+ * The Key depended S-Table 2
413
+ *
414
+ * @var Array
415
+ * @access private
416
+ */
417
+ var $S2 = array();
418
+
419
+ /**
420
+ * The Key depended S-Table 3
421
+ *
422
+ * @var Array
423
+ * @access private
424
+ */
425
+ var $S3 = array();
426
+
427
+ /**
428
+ * Holds the last used key
429
+ *
430
+ * @var Array
431
+ * @access private
432
+ */
433
+ var $kl;
434
+
435
+ /**
436
+ * Sets the key.
437
+ *
438
+ * Keys can be of any length. Twofish, itself, requires the use of a key that's 128, 192 or 256-bits long.
439
+ * If the key is less than 256-bits we round the length up to the closest valid key length,
440
+ * padding $key with null bytes. If the key is more than 256-bits, we trim the excess bits.
441
+ *
442
+ * If the key is not explicitly set, it'll be assumed a 128 bits key to be all null bytes.
443
+ *
444
+ * @access public
445
+ * @see Crypt_Base::setKey()
446
+ * @param String $key
447
+ */
448
+ function setKey($key)
449
+ {
450
+ $keylength = strlen($key);
451
+ switch (true) {
452
+ case $keylength <= 16:
453
+ $key = str_pad($key, 16, "\0");
454
+ break;
455
+ case $keylength <= 24:
456
+ $key = str_pad($key, 24, "\0");
457
+ break;
458
+ case $keylength < 32:
459
+ $key = str_pad($key, 32, "\0");
460
+ break;
461
+ case $keylength > 32:
462
+ $key = substr($key, 0, 32);
463
+ }
464
+ parent::setKey($key);
465
+ }
466
+
467
+ /**
468
+ * Setup the key (expansion)
469
+ *
470
+ * @see Crypt_Base::_setupKey()
471
+ * @access private
472
+ */
473
+ function _setupKey()
474
+ {
475
+ if (isset($this->kl['key']) && $this->key === $this->kl['key']) {
476
+ // already expanded
477
+ return;
478
+ }
479
+ $this->kl = array('key' => $this->key);
480
+
481
+ /* Key expanding and generating the key-depended s-boxes */
482
+ $le_longs = unpack('V*', $this->key);
483
+ $key = unpack('C*', $this->key);
484
+ $m0 = $this->m0;
485
+ $m1 = $this->m1;
486
+ $m2 = $this->m2;
487
+ $m3 = $this->m3;
488
+ $q0 = $this->q0;
489
+ $q1 = $this->q1;
490
+
491
+ $K = $S0 = $S1 = $S2 = $S3 = array();
492
+
493
+ switch (strlen($this->key)) {
494
+ case 16:
495
+ list ($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[1], $le_longs[2]);
496
+ list ($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[3], $le_longs[4]);
497
+ for ($i = 0, $j = 1; $i < 40; $i+= 2,$j+= 2) {
498
+ $A = $m0[$q0[$q0[$i] ^ $key[ 9]] ^ $key[1]] ^
499
+ $m1[$q0[$q1[$i] ^ $key[10]] ^ $key[2]] ^
500
+ $m2[$q1[$q0[$i] ^ $key[11]] ^ $key[3]] ^
501
+ $m3[$q1[$q1[$i] ^ $key[12]] ^ $key[4]];
502
+ $B = $m0[$q0[$q0[$j] ^ $key[13]] ^ $key[5]] ^
503
+ $m1[$q0[$q1[$j] ^ $key[14]] ^ $key[6]] ^
504
+ $m2[$q1[$q0[$j] ^ $key[15]] ^ $key[7]] ^
505
+ $m3[$q1[$q1[$j] ^ $key[16]] ^ $key[8]];
506
+ $B = ($B << 8) | ($B >> 24 & 0xff);
507
+ $K[] = $A+= $B;
508
+ $K[] = (($A+= $B) << 9 | $A >> 23 & 0x1ff);
509
+ }
510
+ for ($i = 0; $i < 256; ++$i) {
511
+ $S0[$i] = $m0[$q0[$q0[$i] ^ $s4] ^ $s0];
512
+ $S1[$i] = $m1[$q0[$q1[$i] ^ $s5] ^ $s1];
513
+ $S2[$i] = $m2[$q1[$q0[$i] ^ $s6] ^ $s2];
514
+ $S3[$i] = $m3[$q1[$q1[$i] ^ $s7] ^ $s3];
515
+ }
516
+ break;
517
+ case 24:
518
+ list ($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[1], $le_longs[2]);
519
+ list ($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[3], $le_longs[4]);
520
+ list ($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[5], $le_longs[6]);
521
+ for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
522
+ $A = $m0[$q0[$q0[$q1[$i] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^
523
+ $m1[$q0[$q1[$q1[$i] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^
524
+ $m2[$q1[$q0[$q0[$i] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^
525
+ $m3[$q1[$q1[$q0[$i] ^ $key[20]] ^ $key[12]] ^ $key[4]];
526
+ $B = $m0[$q0[$q0[$q1[$j] ^ $key[21]] ^ $key[13]] ^ $key[5]] ^
527
+ $m1[$q0[$q1[$q1[$j] ^ $key[22]] ^ $key[14]] ^ $key[6]] ^
528
+ $m2[$q1[$q0[$q0[$j] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^
529
+ $m3[$q1[$q1[$q0[$j] ^ $key[24]] ^ $key[16]] ^ $key[8]];
530
+ $B = ($B << 8) | ($B >> 24 & 0xff);
531
+ $K[] = $A+= $B;
532
+ $K[] = (($A+= $B) << 9 | $A >> 23 & 0x1ff);
533
+ }
534
+ for ($i = 0; $i < 256; ++$i) {
535
+ $S0[$i] = $m0[$q0[$q0[$q1[$i] ^ $s8] ^ $s4] ^ $s0];
536
+ $S1[$i] = $m1[$q0[$q1[$q1[$i] ^ $s9] ^ $s5] ^ $s1];
537
+ $S2[$i] = $m2[$q1[$q0[$q0[$i] ^ $sa] ^ $s6] ^ $s2];
538
+ $S3[$i] = $m3[$q1[$q1[$q0[$i] ^ $sb] ^ $s7] ^ $s3];
539
+ }
540
+ break;
541
+ default: // 32
542
+ list ($sf, $se, $sd, $sc) = $this->_mdsrem($le_longs[1], $le_longs[2]);
543
+ list ($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[3], $le_longs[4]);
544
+ list ($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[5], $le_longs[6]);
545
+ list ($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[7], $le_longs[8]);
546
+ for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
547
+ $A = $m0[$q0[$q0[$q1[$q1[$i] ^ $key[25]] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^
548
+ $m1[$q0[$q1[$q1[$q0[$i] ^ $key[26]] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^
549
+ $m2[$q1[$q0[$q0[$q0[$i] ^ $key[27]] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^
550
+ $m3[$q1[$q1[$q0[$q1[$i] ^ $key[28]] ^ $key[20]] ^ $key[12]] ^ $key[4]];
551
+ $B = $m0[$q0[$q0[$q1[$q1[$j] ^ $key[29]] ^ $key[21]] ^ $key[13]] ^ $key[5]] ^
552
+ $m1[$q0[$q1[$q1[$q0[$j] ^ $key[30]] ^ $key[22]] ^ $key[14]] ^ $key[6]] ^
553
+ $m2[$q1[$q0[$q0[$q0[$j] ^ $key[31]] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^
554
+ $m3[$q1[$q1[$q0[$q1[$j] ^ $key[32]] ^ $key[24]] ^ $key[16]] ^ $key[8]];
555
+ $B = ($B << 8) | ($B >> 24 & 0xff);
556
+ $K[] = $A+= $B;
557
+ $K[] = (($A+= $B) << 9 | $A >> 23 & 0x1ff);
558
+ }
559
+ for ($i = 0; $i < 256; ++$i) {
560
+ $S0[$i] = $m0[$q0[$q0[$q1[$q1[$i] ^ $sc] ^ $s8] ^ $s4] ^ $s0];
561
+ $S1[$i] = $m1[$q0[$q1[$q1[$q0[$i] ^ $sd] ^ $s9] ^ $s5] ^ $s1];
562
+ $S2[$i] = $m2[$q1[$q0[$q0[$q0[$i] ^ $se] ^ $sa] ^ $s6] ^ $s2];
563
+ $S3[$i] = $m3[$q1[$q1[$q0[$q1[$i] ^ $sf] ^ $sb] ^ $s7] ^ $s3];
564
+ }
565
+ }
566
+
567
+ $this->K = $K;
568
+ $this->S0 = $S0;
569
+ $this->S1 = $S1;
570
+ $this->S2 = $S2;
571
+ $this->S3 = $S3;
572
+ }
573
+
574
+ /**
575
+ * _mdsrem function using by the twofish cipher algorithm
576
+ *
577
+ * @access private
578
+ * @param String $A
579
+ * @param String $B
580
+ * @return Array
581
+ */
582
+ function _mdsrem($A, $B)
583
+ {
584
+ // No gain by unrolling this loop.
585
+ for ($i = 0; $i < 8; ++$i) {
586
+ // Get most significant coefficient.
587
+ $t = 0xff & ($B >> 24);
588
+
589
+ // Shift the others up.
590
+ $B = ($B << 8) | (0xff & ($A >> 24));
591
+ $A<<= 8;
592
+
593
+ $u = $t << 1;
594
+
595
+ // Subtract the modular polynomial on overflow.
596
+ if ($t & 0x80) {
597
+ $u^= 0x14d;
598
+ }
599
+
600
+ // Remove t * (a * x^2 + 1).
601
+ $B ^= $t ^ ($u << 16);
602
+
603
+ // Form u = a*t + t/a = t*(a + 1/a).
604
+ $u^= 0x7fffffff & ($t >> 1);
605
+
606
+ // Add the modular polynomial on underflow.
607
+ if ($t & 0x01) $u^= 0xa6 ;
608
+
609
+ // Remove t * (a + 1/a) * (x^3 + x).
610
+ $B^= ($u << 24) | ($u << 8);
611
+ }
612
+
613
+ return array(
614
+ 0xff & $B >> 24,
615
+ 0xff & $B >> 16,
616
+ 0xff & $B >> 8,
617
+ 0xff & $B);
618
+ }
619
+
620
+ /**
621
+ * Encrypts a block
622
+ *
623
+ * @access private
624
+ * @param String $in
625
+ * @return String
626
+ */
627
+ function _encryptBlock($in)
628
+ {
629
+ $S0 = $this->S0;
630
+ $S1 = $this->S1;
631
+ $S2 = $this->S2;
632
+ $S3 = $this->S3;
633
+ $K = $this->K;
634
+
635
+ $in = unpack("V4", $in);
636
+ $R0 = $K[0] ^ $in[1];
637
+ $R1 = $K[1] ^ $in[2];
638
+ $R2 = $K[2] ^ $in[3];
639
+ $R3 = $K[3] ^ $in[4];
640
+
641
+ $ki = 7;
642
+ while ($ki < 39) {
643
+ $t0 = $S0[ $R0 & 0xff] ^
644
+ $S1[($R0 >> 8) & 0xff] ^
645
+ $S2[($R0 >> 16) & 0xff] ^
646
+ $S3[($R0 >> 24) & 0xff];
647
+ $t1 = $S0[($R1 >> 24) & 0xff] ^
648
+ $S1[ $R1 & 0xff] ^
649
+ $S2[($R1 >> 8) & 0xff] ^
650
+ $S3[($R1 >> 16) & 0xff];
651
+ $R2^= $t0 + $t1 + $K[++$ki];
652
+ $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
653
+ $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ($t0 + ($t1 << 1) + $K[++$ki]);
654
+
655
+ $t0 = $S0[ $R2 & 0xff] ^
656
+ $S1[($R2 >> 8) & 0xff] ^
657
+ $S2[($R2 >> 16) & 0xff] ^
658
+ $S3[($R2 >> 24) & 0xff];
659
+ $t1 = $S0[($R3 >> 24) & 0xff] ^
660
+ $S1[ $R3 & 0xff] ^
661
+ $S2[($R3 >> 8) & 0xff] ^
662
+ $S3[($R3 >> 16) & 0xff];
663
+ $R0^= ($t0 + $t1 + $K[++$ki]);
664
+ $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
665
+ $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ($t0 + ($t1 << 1) + $K[++$ki]);
666
+ }
667
+
668
+ // @codingStandardsIgnoreStart
669
+ return pack("V4", $K[4] ^ $R2,
670
+ $K[5] ^ $R3,
671
+ $K[6] ^ $R0,
672
+ $K[7] ^ $R1);
673
+ // @codingStandardsIgnoreEnd
674
+ }
675
+
676
+ /**
677
+ * Decrypts a block
678
+ *
679
+ * @access private
680
+ * @param String $in
681
+ * @return String
682
+ */
683
+ function _decryptBlock($in)
684
+ {
685
+ $S0 = $this->S0;
686
+ $S1 = $this->S1;
687
+ $S2 = $this->S2;
688
+ $S3 = $this->S3;
689
+ $K = $this->K;
690
+
691
+ $in = unpack("V4", $in);
692
+ $R0 = $K[4] ^ $in[1];
693
+ $R1 = $K[5] ^ $in[2];
694
+ $R2 = $K[6] ^ $in[3];
695
+ $R3 = $K[7] ^ $in[4];
696
+
697
+ $ki = 40;
698
+ while ($ki > 8) {
699
+ $t0 = $S0[$R0 & 0xff] ^
700
+ $S1[$R0 >> 8 & 0xff] ^
701
+ $S2[$R0 >> 16 & 0xff] ^
702
+ $S3[$R0 >> 24 & 0xff];
703
+ $t1 = $S0[$R1 >> 24 & 0xff] ^
704
+ $S1[$R1 & 0xff] ^
705
+ $S2[$R1 >> 8 & 0xff] ^
706
+ $S3[$R1 >> 16 & 0xff];
707
+ $R3^= $t0 + ($t1 << 1) + $K[--$ki];
708
+ $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
709
+ $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ($t0 + $t1 + $K[--$ki]);
710
+
711
+ $t0 = $S0[$R2 & 0xff] ^
712
+ $S1[$R2 >> 8 & 0xff] ^
713
+ $S2[$R2 >> 16 & 0xff] ^
714
+ $S3[$R2 >> 24 & 0xff];
715
+ $t1 = $S0[$R3 >> 24 & 0xff] ^
716
+ $S1[$R3 & 0xff] ^
717
+ $S2[$R3 >> 8 & 0xff] ^
718
+ $S3[$R3 >> 16 & 0xff];
719
+ $R1^= $t0 + ($t1 << 1) + $K[--$ki];
720
+ $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
721
+ $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ($t0 + $t1 + $K[--$ki]);
722
+ }
723
+
724
+ // @codingStandardsIgnoreStart
725
+ return pack("V4", $K[0] ^ $R2,
726
+ $K[1] ^ $R3,
727
+ $K[2] ^ $R0,
728
+ $K[3] ^ $R1);
729
+ // @codingStandardsIgnoreEnd
730
+ }
731
+
732
+ /**
733
+ * Setup the performance-optimized function for de/encrypt()
734
+ *
735
+ * @see Crypt_Base::_setupInlineCrypt()
736
+ * @access private
737
+ */
738
+ function _setupInlineCrypt()
739
+ {
740
+ $lambda_functions =& Crypt_Twofish::_getLambdaFunctions();
741
+
742
+ // Max. 10 Ultra-Hi-optimized inline-crypt functions. After that, we'll (still) create very fast code, but not the ultimate fast one.
743
+ // (Currently, for Crypt_Twofish, one generated $lambda_function cost on php5.5@32bit ~140kb unfreeable mem and ~240kb on php5.5@64bit)
744
+ $gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
745
+
746
+ // Generation of a uniqe hash for our generated code
747
+ $code_hash = "Crypt_Twofish, {$this->mode}";
748
+ if ($gen_hi_opt_code) {
749
+ $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
750
+ }
751
+
752
+ if (!isset($lambda_functions[$code_hash])) {
753
+ switch (true) {
754
+ case $gen_hi_opt_code:
755
+ $K = $this->K;
756
+ $init_crypt = '
757
+ static $S0, $S1, $S2, $S3;
758
+ if (!$S0) {
759
+ for ($i = 0; $i < 256; ++$i) {
760
+ $S0[] = (int)$self->S0[$i];
761
+ $S1[] = (int)$self->S1[$i];
762
+ $S2[] = (int)$self->S2[$i];
763
+ $S3[] = (int)$self->S3[$i];
764
+ }
765
+ }
766
+ ';
767
+ break;
768
+ default:
769
+ $K = array();
770
+ for ($i = 0; $i < 40; ++$i) {
771
+ $K[] = '$K_' . $i;
772
+ }
773
+ $init_crypt = '
774
+ $S0 = $self->S0;
775
+ $S1 = $self->S1;
776
+ $S2 = $self->S2;
777
+ $S3 = $self->S3;
778
+ list(' . implode(',', $K) . ') = $self->K;
779
+ ';
780
+ }
781
+
782
+ // Generating encrypt code:
783
+ $encrypt_block = '
784
+ $in = unpack("V4", $in);
785
+ $R0 = '.$K[0].' ^ $in[1];
786
+ $R1 = '.$K[1].' ^ $in[2];
787
+ $R2 = '.$K[2].' ^ $in[3];
788
+ $R3 = '.$K[3].' ^ $in[4];
789
+ ';
790
+ for ($ki = 7, $i = 0; $i < 8; ++$i) {
791
+ $encrypt_block.= '
792
+ $t0 = $S0[ $R0 & 0xff] ^
793
+ $S1[($R0 >> 8) & 0xff] ^
794
+ $S2[($R0 >> 16) & 0xff] ^
795
+ $S3[($R0 >> 24) & 0xff];
796
+ $t1 = $S0[($R1 >> 24) & 0xff] ^
797
+ $S1[ $R1 & 0xff] ^
798
+ $S2[($R1 >> 8) & 0xff] ^
799
+ $S3[($R1 >> 16) & 0xff];
800
+ $R2^= ($t0 + $t1 + '.$K[++$ki].');
801
+ $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
802
+ $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ($t0 + ($t1 << 1) + '.$K[++$ki].');
803
+
804
+ $t0 = $S0[ $R2 & 0xff] ^
805
+ $S1[($R2 >> 8) & 0xff] ^
806
+ $S2[($R2 >> 16) & 0xff] ^
807
+ $S3[($R2 >> 24) & 0xff];
808
+ $t1 = $S0[($R3 >> 24) & 0xff] ^
809
+ $S1[ $R3 & 0xff] ^
810
+ $S2[($R3 >> 8) & 0xff] ^
811
+ $S3[($R3 >> 16) & 0xff];
812
+ $R0^= ($t0 + $t1 + '.$K[++$ki].');
813
+ $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
814
+ $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ($t0 + ($t1 << 1) + '.$K[++$ki].');
815
+ ';
816
+ }
817
+ $encrypt_block.= '
818
+ $in = pack("V4", '.$K[4].' ^ $R2,
819
+ '.$K[5].' ^ $R3,
820
+ '.$K[6].' ^ $R0,
821
+ '.$K[7].' ^ $R1);
822
+ ';
823
+
824
+ // Generating decrypt code:
825
+ $decrypt_block = '
826
+ $in = unpack("V4", $in);
827
+ $R0 = '.$K[4].' ^ $in[1];
828
+ $R1 = '.$K[5].' ^ $in[2];
829
+ $R2 = '.$K[6].' ^ $in[3];
830
+ $R3 = '.$K[7].' ^ $in[4];
831
+ ';
832
+ for ($ki = 40, $i = 0; $i < 8; ++$i) {
833
+ $decrypt_block.= '
834
+ $t0 = $S0[$R0 & 0xff] ^
835
+ $S1[$R0 >> 8 & 0xff] ^
836
+ $S2[$R0 >> 16 & 0xff] ^
837
+ $S3[$R0 >> 24 & 0xff];
838
+ $t1 = $S0[$R1 >> 24 & 0xff] ^
839
+ $S1[$R1 & 0xff] ^
840
+ $S2[$R1 >> 8 & 0xff] ^
841
+ $S3[$R1 >> 16 & 0xff];
842
+ $R3^= $t0 + ($t1 << 1) + '.$K[--$ki].';
843
+ $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
844
+ $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ($t0 + $t1 + '.$K[--$ki].');
845
+
846
+ $t0 = $S0[$R2 & 0xff] ^
847
+ $S1[$R2 >> 8 & 0xff] ^
848
+ $S2[$R2 >> 16 & 0xff] ^
849
+ $S3[$R2 >> 24 & 0xff];
850
+ $t1 = $S0[$R3 >> 24 & 0xff] ^
851
+ $S1[$R3 & 0xff] ^
852
+ $S2[$R3 >> 8 & 0xff] ^
853
+ $S3[$R3 >> 16 & 0xff];
854
+ $R1^= $t0 + ($t1 << 1) + '.$K[--$ki].';
855
+ $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
856
+ $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ($t0 + $t1 + '.$K[--$ki].');
857
+ ';
858
+ }
859
+ $decrypt_block.= '
860
+ $in = pack("V4", '.$K[0].' ^ $R2,
861
+ '.$K[1].' ^ $R3,
862
+ '.$K[2].' ^ $R0,
863
+ '.$K[3].' ^ $R1);
864
+ ';
865
+
866
+ $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
867
+ array(
868
+ 'init_crypt' => $init_crypt,
869
+ 'init_encrypt' => '',
870
+ 'init_decrypt' => '',
871
+ 'encrypt_block' => $encrypt_block,
872
+ 'decrypt_block' => $decrypt_block
873
+ )
874
+ );
875
+ }
876
+ $this->inline_crypt = $lambda_functions[$code_hash];
877
+ }
878
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
phpseclib/Math/BigInteger.php CHANGED
@@ -1,3751 +1,3758 @@
1
- <?php
2
-
3
- /**
4
- * Pure-PHP arbitrary precision integer arithmetic library.
5
- *
6
- * Supports base-2, base-10, base-16, and base-256 numbers. Uses the GMP or BCMath extensions, if available,
7
- * and an internal implementation, otherwise.
8
- *
9
- * PHP versions 4 and 5
10
- *
11
- * {@internal (all DocBlock comments regarding implementation - such as the one that follows - refer to the
12
- * {@link MATH_BIGINTEGER_MODE_INTERNAL MATH_BIGINTEGER_MODE_INTERNAL} mode)
13
- *
14
- * Math_BigInteger uses base-2**26 to perform operations such as multiplication and division and
15
- * base-2**52 (ie. two base 2**26 digits) to perform addition and subtraction. Because the largest possible
16
- * value when multiplying two base-2**26 numbers together is a base-2**52 number, double precision floating
17
- * point numbers - numbers that should be supported on most hardware and whose significand is 53 bits - are
18
- * used. As a consequence, bitwise operators such as >> and << cannot be used, nor can the modulo operator %,
19
- * which only supports integers. Although this fact will slow this library down, the fact that such a high
20
- * base is being used should more than compensate.
21
- *
22
- * Numbers are stored in {@link http://en.wikipedia.org/wiki/Endianness little endian} format. ie.
23
- * (new Math_BigInteger(pow(2, 26)))->value = array(0, 1)
24
- *
25
- * Useful resources are as follows:
26
- *
27
- * - {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf Handbook of Applied Cryptography (HAC)}
28
- * - {@link http://math.libtomcrypt.com/files/tommath.pdf Multi-Precision Math (MPM)}
29
- * - Java's BigInteger classes. See /j2se/src/share/classes/java/math in jdk-1_5_0-src-jrl.zip
30
- *
31
- * Here's an example of how to use this library:
32
- * <code>
33
- * <?php
34
- * include 'Math/BigInteger.php';
35
- *
36
- * $a = new Math_BigInteger(2);
37
- * $b = new Math_BigInteger(3);
38
- *
39
- * $c = $a->add($b);
40
- *
41
- * echo $c->toString(); // outputs 5
42
- * ?>
43
- * </code>
44
- *
45
- * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
46
- * of this software and associated documentation files (the "Software"), to deal
47
- * in the Software without restriction, including without limitation the rights
48
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
49
- * copies of the Software, and to permit persons to whom the Software is
50
- * furnished to do so, subject to the following conditions:
51
- *
52
- * The above copyright notice and this permission notice shall be included in
53
- * all copies or substantial portions of the Software.
54
- *
55
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
56
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
57
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
58
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
59
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
60
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
61
- * THE SOFTWARE.
62
- *
63
- * @category Math
64
- * @package Math_BigInteger
65
- * @author Jim Wigginton <terrafrost@php.net>
66
- * @copyright MMVI Jim Wigginton
67
- * @license http://www.opensource.org/licenses/mit-license.html MIT License
68
- * @link http://pear.php.net/package/Math_BigInteger
69
- */
70
-
71
- /**#@+
72
- * Reduction constants
73
- *
74
- * @access private
75
- * @see Math_BigInteger::_reduce()
76
- */
77
- /**
78
- * @see Math_BigInteger::_montgomery()
79
- * @see Math_BigInteger::_prepMontgomery()
80
- */
81
- define('MATH_BIGINTEGER_MONTGOMERY', 0);
82
- /**
83
- * @see Math_BigInteger::_barrett()
84
- */
85
- define('MATH_BIGINTEGER_BARRETT', 1);
86
- /**
87
- * @see Math_BigInteger::_mod2()
88
- */
89
- define('MATH_BIGINTEGER_POWEROF2', 2);
90
- /**
91
- * @see Math_BigInteger::_remainder()
92
- */
93
- define('MATH_BIGINTEGER_CLASSIC', 3);
94
- /**
95
- * @see Math_BigInteger::__clone()
96
- */
97
- define('MATH_BIGINTEGER_NONE', 4);
98
- /**#@-*/
99
-
100
- /**#@+
101
- * Array constants
102
- *
103
- * Rather than create a thousands and thousands of new Math_BigInteger objects in repeated function calls to add() and
104
- * multiply() or whatever, we'll just work directly on arrays, taking them in as parameters and returning them.
105
- *
106
- * @access private
107
- */
108
- /**
109
- * $result[MATH_BIGINTEGER_VALUE] contains the value.
110
- */
111
- define('MATH_BIGINTEGER_VALUE', 0);
112
- /**
113
- * $result[MATH_BIGINTEGER_SIGN] contains the sign.
114
- */
115
- define('MATH_BIGINTEGER_SIGN', 1);
116
- /**#@-*/
117
-
118
- /**#@+
119
- * @access private
120
- * @see Math_BigInteger::_montgomery()
121
- * @see Math_BigInteger::_barrett()
122
- */
123
- /**
124
- * Cache constants
125
- *
126
- * $cache[MATH_BIGINTEGER_VARIABLE] tells us whether or not the cached data is still valid.
127
- */
128
- define('MATH_BIGINTEGER_VARIABLE', 0);
129
- /**
130
- * $cache[MATH_BIGINTEGER_DATA] contains the cached data.
131
- */
132
- define('MATH_BIGINTEGER_DATA', 1);
133
- /**#@-*/
134
-
135
- /**#@+
136
- * Mode constants.
137
- *
138
- * @access private
139
- * @see Math_BigInteger::Math_BigInteger()
140
- */
141
- /**
142
- * To use the pure-PHP implementation
143
- */
144
- define('MATH_BIGINTEGER_MODE_INTERNAL', 1);
145
- /**
146
- * To use the BCMath library
147
- *
148
- * (if enabled; otherwise, the internal implementation will be used)
149
- */
150
- define('MATH_BIGINTEGER_MODE_BCMATH', 2);
151
- /**
152
- * To use the GMP library
153
- *
154
- * (if present; otherwise, either the BCMath or the internal implementation will be used)
155
- */
156
- define('MATH_BIGINTEGER_MODE_GMP', 3);
157
- /**#@-*/
158
-
159
- /**
160
- * Karatsuba Cutoff
161
- *
162
- * At what point do we switch between Karatsuba multiplication and schoolbook long multiplication?
163
- *
164
- * @access private
165
- */
166
- define('MATH_BIGINTEGER_KARATSUBA_CUTOFF', 25);
167
-
168
- /**
169
- * Pure-PHP arbitrary precision integer arithmetic library. Supports base-2, base-10, base-16, and base-256
170
- * numbers.
171
- *
172
- * @package Math_BigInteger
173
- * @author Jim Wigginton <terrafrost@php.net>
174
- * @access public
175
- */
176
- class Math_BigInteger
177
- {
178
- /**
179
- * Holds the BigInteger's value.
180
- *
181
- * @var Array
182
- * @access private
183
- */
184
- var $value;
185
-
186
- /**
187
- * Holds the BigInteger's magnitude.
188
- *
189
- * @var Boolean
190
- * @access private
191
- */
192
- var $is_negative = false;
193
-
194
- /**
195
- * Random number generator function
196
- *
197
- * @see setRandomGenerator()
198
- * @access private
199
- */
200
- var $generator = 'mt_rand';
201
-
202
- /**
203
- * Precision
204
- *
205
- * @see setPrecision()
206
- * @access private
207
- */
208
- var $precision = -1;
209
-
210
- /**
211
- * Precision Bitmask
212
- *
213
- * @see setPrecision()
214
- * @access private
215
- */
216
- var $bitmask = false;
217
-
218
- /**
219
- * Mode independent value used for serialization.
220
- *
221
- * If the bcmath or gmp extensions are installed $this->value will be a non-serializable resource, hence the need for
222
- * a variable that'll be serializable regardless of whether or not extensions are being used. Unlike $this->value,
223
- * however, $this->hex is only calculated when $this->__sleep() is called.
224
- *
225
- * @see __sleep()
226
- * @see __wakeup()
227
- * @var String
228
- * @access private
229
- */
230
- var $hex;
231
-
232
- /**
233
- * Converts base-2, base-10, base-16, and binary strings (base-256) to BigIntegers.
234
- *
235
- * If the second parameter - $base - is negative, then it will be assumed that the number's are encoded using
236
- * two's compliment. The sole exception to this is -10, which is treated the same as 10 is.
237
- *
238
- * Here's an example:
239
- * <code>
240
- * <?php
241
- * include 'Math/BigInteger.php';
242
- *
243
- * $a = new Math_BigInteger('0x32', 16); // 50 in base-16
244
- *
245
- * echo $a->toString(); // outputs 50
246
- * ?>
247
- * </code>
248
- *
249
- * @param optional $x base-10 number or base-$base number if $base set.
250
- * @param optional integer $base
251
- * @return Math_BigInteger
252
- * @access public
253
- */
254
- function Math_BigInteger($x = 0, $base = 10)
255
- {
256
- if ( !defined('MATH_BIGINTEGER_MODE') ) {
257
- switch (true) {
258
- case extension_loaded('gmp'):
259
- define('MATH_BIGINTEGER_MODE', MATH_BIGINTEGER_MODE_GMP);
260
- break;
261
- case extension_loaded('bcmath'):
262
- define('MATH_BIGINTEGER_MODE', MATH_BIGINTEGER_MODE_BCMATH);
263
- break;
264
- default:
265
- define('MATH_BIGINTEGER_MODE', MATH_BIGINTEGER_MODE_INTERNAL);
266
- }
267
- }
268
-
269
- if (function_exists('openssl_public_encrypt') && !defined('MATH_BIGINTEGER_OPENSSL_DISABLE') && !defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) {
270
- // some versions of XAMPP have mismatched versions of OpenSSL which causes it not to work
271
- ob_start();
272
- @phpinfo();
273
- $content = ob_get_contents();
274
- ob_end_clean();
275
-
276
- preg_match_all('#OpenSSL (Header|Library) Version(.*)#im', $content, $matches);
277
-
278
- $versions = array();
279
- if (!empty($matches[1])) {
280
- for ($i = 0; $i < count($matches[1]); $i++) {
281
- $versions[$matches[1][$i]] = trim(str_replace('=>', '', strip_tags($matches[2][$i])));
282
- }
283
- }
284
-
285
- // it doesn't appear that OpenSSL versions were reported upon until PHP 5.3+
286
- switch (true) {
287
- case !isset($versions['Header']):
288
- case !isset($versions['Library']):
289
- case $versions['Header'] == $versions['Library']:
290
- define('MATH_BIGINTEGER_OPENSSL_ENABLED', true);
291
- break;
292
- default:
293
- define('MATH_BIGINTEGER_OPENSSL_DISABLE', true);
294
- }
295
- }
296
-
297
- if (!defined('PHP_INT_SIZE')) {
298
- define('PHP_INT_SIZE', 4);
299
- }
300
-
301
- if (!defined('MATH_BIGINTEGER_BASE') && MATH_BIGINTEGER_MODE == MATH_BIGINTEGER_MODE_INTERNAL) {
302
- switch (PHP_INT_SIZE) {
303
- case 8: // use 64-bit integers if int size is 8 bytes
304
- define('MATH_BIGINTEGER_BASE', 31);
305
- define('MATH_BIGINTEGER_BASE_FULL', 0x80000000);
306
- define('MATH_BIGINTEGER_MAX_DIGIT', 0x7FFFFFFF);
307
- define('MATH_BIGINTEGER_MSB', 0x40000000);
308
- // 10**9 is the closest we can get to 2**31 without passing it
309
- define('MATH_BIGINTEGER_MAX10', 1000000000);
310
- define('MATH_BIGINTEGER_MAX10_LEN', 9);
311
- // the largest digit that may be used in addition / subtraction
312
- define('MATH_BIGINTEGER_MAX_DIGIT2', pow(2, 62));
313
- break;
314
- //case 4: // use 64-bit floats if int size is 4 bytes
315
- default:
316
- define('MATH_BIGINTEGER_BASE', 26);
317
- define('MATH_BIGINTEGER_BASE_FULL', 0x4000000);
318
- define('MATH_BIGINTEGER_MAX_DIGIT', 0x3FFFFFF);
319
- define('MATH_BIGINTEGER_MSB', 0x2000000);
320
- // 10**7 is the closest to 2**26 without passing it
321
- define('MATH_BIGINTEGER_MAX10', 10000000);
322
- define('MATH_BIGINTEGER_MAX10_LEN', 7);
323
- // the largest digit that may be used in addition / subtraction
324
- // we do pow(2, 52) instead of using 4503599627370496 directly because some
325
- // PHP installations will truncate 4503599627370496.
326
- define('MATH_BIGINTEGER_MAX_DIGIT2', pow(2, 52));
327
- }
328
- }
329
-
330
- switch ( MATH_BIGINTEGER_MODE ) {
331
- case MATH_BIGINTEGER_MODE_GMP:
332
- switch (true) {
333
- case is_resource($x) && get_resource_type($x) == 'GMP integer':
334
- // PHP 5.6 switched GMP from using resources to objects
335
- case is_object($x) && get_class($x) == 'GMP':
336
- $this->value = $x;
337
- return;
338
- }
339
- $this->value = gmp_init(0);
340
- break;
341
- case MATH_BIGINTEGER_MODE_BCMATH:
342
- $this->value = '0';
343
- break;
344
- default:
345
- $this->value = array();
346
- }
347
-
348
- // '0' counts as empty() but when the base is 256 '0' is equal to ord('0') or 48
349
- // '0' is the only value like this per http://php.net/empty
350
- if (empty($x) && (abs($base) != 256 || $x !== '0')) {
351
- return;
352
- }
353
-
354
- switch ($base) {
355
- case -256:
356
- if (ord($x[0]) & 0x80) {
357
- $x = ~$x;
358
- $this->is_negative = true;
359
- }
360
- case 256:
361
- switch ( MATH_BIGINTEGER_MODE ) {
362
- case MATH_BIGINTEGER_MODE_GMP:
363
- $sign = $this->is_negative ? '-' : '';
364
- $this->value = gmp_init($sign . '0x' . bin2hex($x));
365
- break;
366
- case MATH_BIGINTEGER_MODE_BCMATH:
367
- // round $len to the nearest 4 (thanks, DavidMJ!)
368
- $len = (strlen($x) + 3) & 0xFFFFFFFC;
369
-
370
- $x = str_pad($x, $len, chr(0), STR_PAD_LEFT);
371
-
372
- for ($i = 0; $i < $len; $i+= 4) {
373
- $this->value = bcmul($this->value, '4294967296', 0); // 4294967296 == 2**32
374
- $this->value = bcadd($this->value, 0x1000000 * ord($x[$i]) + ((ord($x[$i + 1]) << 16) | (ord($x[$i + 2]) << 8) | ord($x[$i + 3])), 0);
375
- }
376
-
377
- if ($this->is_negative) {
378
- $this->value = '-' . $this->value;
379
- }
380
-
381
- break;
382
- // converts a base-2**8 (big endian / msb) number to base-2**26 (little endian / lsb)
383
- default:
384
- while (strlen($x)) {
385
- $this->value[] = $this->_bytes2int($this->_base256_rshift($x, MATH_BIGINTEGER_BASE));
386
- }
387
- }
388
-
389
- if ($this->is_negative) {
390
- if (MATH_BIGINTEGER_MODE != MATH_BIGINTEGER_MODE_INTERNAL) {
391
- $this->is_negative = false;
392
- }
393
- $temp = $this->add(new Math_BigInteger('-1'));
394
- $this->value = $temp->value;
395
- }
396
- break;
397
- case 16:
398
- case -16:
399
- if ($base > 0 && $x[0] == '-') {
400
- $this->is_negative = true;
401
- $x = substr($x, 1);
402
- }
403
-
404
- $x = preg_replace('#^(?:0x)?([A-Fa-f0-9]*).*#', '$1', $x);
405
-
406
- $is_negative = false;
407
- if ($base < 0 && hexdec($x[0]) >= 8) {
408
- $this->is_negative = $is_negative = true;
409
- $x = bin2hex(~pack('H*', $x));
410
- }
411
-
412
- switch ( MATH_BIGINTEGER_MODE ) {
413
- case MATH_BIGINTEGER_MODE_GMP:
414
- $temp = $this->is_negative ? '-0x' . $x : '0x' . $x;
415
- $this->value = gmp_init($temp);
416
- $this->is_negative = false;
417
- break;
418
- case MATH_BIGINTEGER_MODE_BCMATH:
419
- $x = ( strlen($x) & 1 ) ? '0' . $x : $x;
420
- $temp = new Math_BigInteger(pack('H*', $x), 256);
421
- $this->value = $this->is_negative ? '-' . $temp->value : $temp->value;
422
- $this->is_negative = false;
423
- break;
424
- default:
425
- $x = ( strlen($x) & 1 ) ? '0' . $x : $x;
426
- $temp = new Math_BigInteger(pack('H*', $x), 256);
427
- $this->value = $temp->value;
428
- }
429
-
430
- if ($is_negative) {
431
- $temp = $this->add(new Math_BigInteger('-1'));
432
- $this->value = $temp->value;
433
- }
434
- break;
435
- case 10:
436
- case -10:
437
- // (?<!^)(?:-).*: find any -'s that aren't at the beginning and then any characters that follow that
438
- // (?<=^|-)0*: find any 0's that are preceded by the start of the string or by a - (ie. octals)
439
- // [^-0-9].*: find any non-numeric characters and then any characters that follow that
440
- $x = preg_replace('#(?<!^)(?:-).*|(?<=^|-)0*|[^-0-9].*#', '', $x);
441
-
442
- switch ( MATH_BIGINTEGER_MODE ) {
443
- case MATH_BIGINTEGER_MODE_GMP:
444
- $this->value = gmp_init($x);
445
- break;
446
- case MATH_BIGINTEGER_MODE_BCMATH:
447
- // explicitly casting $x to a string is necessary, here, since doing $x[0] on -1 yields different
448
- // results then doing it on '-1' does (modInverse does $x[0])
449
- $this->value = $x === '-' ? '0' : (string) $x;
450
- break;
451
- default:
452
- $temp = new Math_BigInteger();
453
-
454
- $multiplier = new Math_BigInteger();
455
- $multiplier->value = array(MATH_BIGINTEGER_MAX10);
456
-
457
- if ($x[0] == '-') {
458
- $this->is_negative = true;
459
- $x = substr($x, 1);
460
- }
461
-
462
- $x = str_pad($x, strlen($x) + ((MATH_BIGINTEGER_MAX10_LEN - 1) * strlen($x)) % MATH_BIGINTEGER_MAX10_LEN, 0, STR_PAD_LEFT);
463
- while (strlen($x)) {
464
- $temp = $temp->multiply($multiplier);
465
- $temp = $temp->add(new Math_BigInteger($this->_int2bytes(substr($x, 0, MATH_BIGINTEGER_MAX10_LEN)), 256));
466
- $x = substr($x, MATH_BIGINTEGER_MAX10_LEN);
467
- }
468
-
469
- $this->value = $temp->value;
470
- }
471
- break;
472
- case 2: // base-2 support originally implemented by Lluis Pamies - thanks!
473
- case -2:
474
- if ($base > 0 && $x[0] == '-') {
475
- $this->is_negative = true;
476
- $x = substr($x, 1);
477
- }
478
-
479
- $x = preg_replace('#^([01]*).*#', '$1', $x);
480
- $x = str_pad($x, strlen($x) + (3 * strlen($x)) % 4, 0, STR_PAD_LEFT);
481
-
482
- $str = '0x';
483
- while (strlen($x)) {
484
- $part = substr($x, 0, 4);
485
- $str.= dechex(bindec($part));
486
- $x = substr($x, 4);
487
- }
488
-
489
- if ($this->is_negative) {
490
- $str = '-' . $str;
491
- }
492
-
493
- $temp = new Math_BigInteger($str, 8 * $base); // ie. either -16 or +16
494
- $this->value = $temp->value;
495
- $this->is_negative = $temp->is_negative;
496
-
497
- break;
498
- default:
499
- // base not supported, so we'll let $this == 0
500
- }
501
- }
502
-
503
- /**
504
- * Converts a BigInteger to a byte string (eg. base-256).
505
- *
506
- * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're
507
- * saved as two's compliment.
508
- *
509
- * Here's an example:
510
- * <code>
511
- * <?php
512
- * include 'Math/BigInteger.php';
513
- *
514
- * $a = new Math_BigInteger('65');
515
- *
516
- * echo $a->toBytes(); // outputs chr(65)
517
- * ?>
518
- * </code>
519
- *
520
- * @param Boolean $twos_compliment
521
- * @return String
522
- * @access public
523
- * @internal Converts a base-2**26 number to base-2**8
524
- */
525
- function toBytes($twos_compliment = false)
526
- {
527
- if ($twos_compliment) {
528
- $comparison = $this->compare(new Math_BigInteger());
529
- if ($comparison == 0) {
530
- return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
531
- }
532
-
533
- $temp = $comparison < 0 ? $this->add(new Math_BigInteger(1)) : $this->copy();
534
- $bytes = $temp->toBytes();
535
-
536
- if (empty($bytes)) { // eg. if the number we're trying to convert is -1
537
- $bytes = chr(0);
538
- }
539
-
540
- if (ord($bytes[0]) & 0x80) {
541
- $bytes = chr(0) . $bytes;
542
- }
543
-
544
- return $comparison < 0 ? ~$bytes : $bytes;
545
- }
546
-
547
- switch ( MATH_BIGINTEGER_MODE ) {
548
- case MATH_BIGINTEGER_MODE_GMP:
549
- if (gmp_cmp($this->value, gmp_init(0)) == 0) {
550
- return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
551
- }
552
-
553
- $temp = gmp_strval(gmp_abs($this->value), 16);
554
- $temp = ( strlen($temp) & 1 ) ? '0' . $temp : $temp;
555
- $temp = pack('H*', $temp);
556
-
557
- return $this->precision > 0 ?
558
- substr(str_pad($temp, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) :
559
- ltrim($temp, chr(0));
560
- case MATH_BIGINTEGER_MODE_BCMATH:
561
- if ($this->value === '0') {
562
- return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
563
- }
564
-
565
- $value = '';
566
- $current = $this->value;
567
-
568
- if ($current[0] == '-') {
569
- $current = substr($current, 1);
570
- }
571
-
572
- while (bccomp($current, '0', 0) > 0) {
573
- $temp = bcmod($current, '16777216');
574
- $value = chr($temp >> 16) . chr($temp >> 8) . chr($temp) . $value;
575
- $current = bcdiv($current, '16777216', 0);
576
- }
577
-
578
- return $this->precision > 0 ?
579
- substr(str_pad($value, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) :
580
- ltrim($value, chr(0));
581
- }
582
-
583
- if (!count($this->value)) {
584
- return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
585
- }
586
- $result = $this->_int2bytes($this->value[count($this->value) - 1]);
587
-
588
- $temp = $this->copy();
589
-
590
- for ($i = count($temp->value) - 2; $i >= 0; --$i) {
591
- $temp->_base256_lshift($result, MATH_BIGINTEGER_BASE);
592
- $result = $result | str_pad($temp->_int2bytes($temp->value[$i]), strlen($result), chr(0), STR_PAD_LEFT);
593
- }
594
-
595
- return $this->precision > 0 ?
596
- str_pad(substr($result, -(($this->precision + 7) >> 3)), ($this->precision + 7) >> 3, chr(0), STR_PAD_LEFT) :
597
- $result;
598
- }
599
-
600
- /**
601
- * Converts a BigInteger to a hex string (eg. base-16)).
602
- *
603
- * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're
604
- * saved as two's compliment.
605
- *
606
- * Here's an example:
607
- * <code>
608
- * <?php
609
- * include 'Math/BigInteger.php';
610
- *
611
- * $a = new Math_BigInteger('65');
612
- *
613
- * echo $a->toHex(); // outputs '41'
614
- * ?>
615
- * </code>
616
- *
617
- * @param Boolean $twos_compliment
618
- * @return String
619
- * @access public
620
- * @internal Converts a base-2**26 number to base-2**8
621
- */
622
- function toHex($twos_compliment = false)
623
- {
624
- return bin2hex($this->toBytes($twos_compliment));
625
- }
626
-
627
- /**
628
- * Converts a BigInteger to a bit string (eg. base-2).
629
- *
630
- * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're
631
- * saved as two's compliment.
632
- *
633
- * Here's an example:
634
- * <code>
635
- * <?php
636
- * include 'Math/BigInteger.php';
637
- *
638
- * $a = new Math_BigInteger('65');
639
- *
640
- * echo $a->toBits(); // outputs '1000001'
641
- * ?>
642
- * </code>
643
- *
644
- * @param Boolean $twos_compliment
645
- * @return String
646
- * @access public
647
- * @internal Converts a base-2**26 number to base-2**2
648
- */
649
- function toBits($twos_compliment = false)
650
- {
651
- $hex = $this->toHex($twos_compliment);
652
- $bits = '';
653
- for ($i = strlen($hex) - 8, $start = strlen($hex) & 7; $i >= $start; $i-=8) {
654
- $bits = str_pad(decbin(hexdec(substr($hex, $i, 8))), 32, '0', STR_PAD_LEFT) . $bits;
655
- }
656
- if ($start) { // hexdec('') == 0
657
- $bits = str_pad(decbin(hexdec(substr($hex, 0, $start))), 8, '0', STR_PAD_LEFT) . $bits;
658
- }
659
- $result = $this->precision > 0 ? substr($bits, -$this->precision) : ltrim($bits, '0');
660
-
661
- if ($twos_compliment && $this->compare(new Math_BigInteger()) > 0 && $this->precision <= 0) {
662
- return '0' . $result;
663
- }
664
-
665
- return $result;
666
- }
667
-
668
- /**
669
- * Converts a BigInteger to a base-10 number.
670
- *
671
- * Here's an example:
672
- * <code>
673
- * <?php
674
- * include 'Math/BigInteger.php';
675
- *
676
- * $a = new Math_BigInteger('50');
677
- *
678
- * echo $a->toString(); // outputs 50
679
- * ?>
680
- * </code>
681
- *
682
- * @return String
683
- * @access public
684
- * @internal Converts a base-2**26 number to base-10**7 (which is pretty much base-10)
685
- */
686
- function toString()
687
- {
688
- switch ( MATH_BIGINTEGER_MODE ) {
689
- case MATH_BIGINTEGER_MODE_GMP:
690
- return gmp_strval($this->value);
691
- case MATH_BIGINTEGER_MODE_BCMATH:
692
- if ($this->value === '0') {
693
- return '0';
694
- }
695
-
696
- return ltrim($this->value, '0');
697
- }
698
-
699
- if (!count($this->value)) {
700
- return '0';
701
- }
702
-
703
- $temp = $this->copy();
704
- $temp->is_negative = false;
705
-
706
- $divisor = new Math_BigInteger();
707
- $divisor->value = array(MATH_BIGINTEGER_MAX10);
708
- $result = '';
709
- while (count($temp->value)) {
710
- list($temp, $mod) = $temp->divide($divisor);
711
- $result = str_pad(isset($mod->value[0]) ? $mod->value[0] : '', MATH_BIGINTEGER_MAX10_LEN, '0', STR_PAD_LEFT) . $result;
712
- }
713
- $result = ltrim($result, '0');
714
- if (empty($result)) {
715
- $result = '0';
716
- }
717
-
718
- if ($this->is_negative) {
719
- $result = '-' . $result;
720
- }
721
-
722
- return $result;
723
- }
724
-
725
- /**
726
- * Copy an object
727
- *
728
- * PHP5 passes objects by reference while PHP4 passes by value. As such, we need a function to guarantee
729
- * that all objects are passed by value, when appropriate. More information can be found here:
730
- *
731
- * {@link http://php.net/language.oop5.basic#51624}
732
- *
733
- * @access public
734
- * @see __clone()
735
- * @return Math_BigInteger
736
- */
737
- function copy()
738
- {
739
- $temp = new Math_BigInteger();
740
- $temp->value = $this->value;
741
- $temp->is_negative = $this->is_negative;
742
- $temp->generator = $this->generator;
743
- $temp->precision = $this->precision;
744
- $temp->bitmask = $this->bitmask;
745
- return $temp;
746
- }
747
-
748
- /**
749
- * __toString() magic method
750
- *
751
- * Will be called, automatically, if you're supporting just PHP5. If you're supporting PHP4, you'll need to call
752
- * toString().
753
- *
754
- * @access public
755
- * @internal Implemented per a suggestion by Techie-Michael - thanks!
756
- */
757
- function __toString()
758
- {
759
- return $this->toString();
760
- }
761
-
762
- /**
763
- * __clone() magic method
764
- *
765
- * Although you can call Math_BigInteger::__toString() directly in PHP5, you cannot call Math_BigInteger::__clone()
766
- * directly in PHP5. You can in PHP4 since it's not a magic method, but in PHP5, you have to call it by using the PHP5
767
- * only syntax of $y = clone $x. As such, if you're trying to write an application that works on both PHP4 and PHP5,
768
- * call Math_BigInteger::copy(), instead.
769
- *
770
- * @access public
771
- * @see copy()
772
- * @return Math_BigInteger
773
- */
774
- function __clone()
775
- {
776
- return $this->copy();
777
- }
778
-
779
- /**
780
- * __sleep() magic method
781
- *
782
- * Will be called, automatically, when serialize() is called on a Math_BigInteger object.
783
- *
784
- * @see __wakeup()
785
- * @access public
786
- */
787
- function __sleep()
788
- {
789
- $this->hex = $this->toHex(true);
790
- $vars = array('hex');
791
- if ($this->generator != 'mt_rand') {
792
- $vars[] = 'generator';
793
- }
794
- if ($this->precision > 0) {
795
- $vars[] = 'precision';
796
- }
797
- return $vars;
798
-
799
- }
800
-
801
- /**
802
- * __wakeup() magic method
803
- *
804
- * Will be called, automatically, when unserialize() is called on a Math_BigInteger object.
805
- *
806
- * @see __sleep()
807
- * @access public
808
- */
809
- function __wakeup()
810
- {
811
- $temp = new Math_BigInteger($this->hex, -16);
812
- $this->value = $temp->value;
813
- $this->is_negative = $temp->is_negative;
814
- $this->setRandomGenerator($this->generator);
815
- if ($this->precision > 0) {
816
- // recalculate $this->bitmask
817
- $this->setPrecision($this->precision);
818
- }
819
- }
820
-
821
- /**
822
- * Adds two BigIntegers.
823
- *
824
- * Here's an example:
825
- * <code>
826
- * <?php
827
- * include 'Math/BigInteger.php';
828
- *
829
- * $a = new Math_BigInteger('10');
830
- * $b = new Math_BigInteger('20');
831
- *
832
- * $c = $a->add($b);
833
- *
834
- * echo $c->toString(); // outputs 30
835
- * ?>
836
- * </code>
837
- *
838
- * @param Math_BigInteger $y
839
- * @return Math_BigInteger
840
- * @access public
841
- * @internal Performs base-2**52 addition
842
- */
843
- function add($y)
844
- {
845
- switch ( MATH_BIGINTEGER_MODE ) {
846
- case MATH_BIGINTEGER_MODE_GMP:
847
- $temp = new Math_BigInteger();
848
- $temp->value = gmp_add($this->value, $y->value);
849
-
850
- return $this->_normalize($temp);
851
- case MATH_BIGINTEGER_MODE_BCMATH:
852
- $temp = new Math_BigInteger();
853
- $temp->value = bcadd($this->value, $y->value, 0);
854
-
855
- return $this->_normalize($temp);
856
- }
857
-
858
- $temp = $this->_add($this->value, $this->is_negative, $y->value, $y->is_negative);
859
-
860
- $result = new Math_BigInteger();
861
- $result->value = $temp[MATH_BIGINTEGER_VALUE];
862
- $result->is_negative = $temp[MATH_BIGINTEGER_SIGN];
863
-
864
- return $this->_normalize($result);
865
- }
866
-
867
- /**
868
- * Performs addition.
869
- *
870
- * @param Array $x_value
871
- * @param Boolean $x_negative
872
- * @param Array $y_value
873
- * @param Boolean $y_negative
874
- * @return Array
875
- * @access private
876
- */
877
- function _add($x_value, $x_negative, $y_value, $y_negative)
878
- {
879
- $x_size = count($x_value);
880
- $y_size = count($y_value);
881
-
882
- if ($x_size == 0) {
883
- return array(
884
- MATH_BIGINTEGER_VALUE => $y_value,
885
- MATH_BIGINTEGER_SIGN => $y_negative
886
- );
887
- } else if ($y_size == 0) {
888
- return array(
889
- MATH_BIGINTEGER_VALUE => $x_value,
890
- MATH_BIGINTEGER_SIGN => $x_negative
891
- );
892
- }
893
-
894
- // subtract, if appropriate
895
- if ( $x_negative != $y_negative ) {
896
- if ( $x_value == $y_value ) {
897
- return array(
898
- MATH_BIGINTEGER_VALUE => array(),
899
- MATH_BIGINTEGER_SIGN => false
900
- );
901
- }
902
-
903
- $temp = $this->_subtract($x_value, false, $y_value, false);
904
- $temp[MATH_BIGINTEGER_SIGN] = $this->_compare($x_value, false, $y_value, false) > 0 ?
905
- $x_negative : $y_negative;
906
-
907
- return $temp;
908
- }
909
-
910
- if ($x_size < $y_size) {
911
- $size = $x_size;
912
- $value = $y_value;
913
- } else {
914
- $size = $y_size;
915
- $value = $x_value;
916
- }
917
-
918
- $value[count($value)] = 0; // just in case the carry adds an extra digit
919
-
920
- $carry = 0;
921
- for ($i = 0, $j = 1; $j < $size; $i+=2, $j+=2) {
922
- $sum = $x_value[$j] * MATH_BIGINTEGER_BASE_FULL + $x_value[$i] + $y_value[$j] * MATH_BIGINTEGER_BASE_FULL + $y_value[$i] + $carry;
923
- $carry = $sum >= MATH_BIGINTEGER_MAX_DIGIT2; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1
924
- $sum = $carry ? $sum - MATH_BIGINTEGER_MAX_DIGIT2 : $sum;
925
-
926
- $temp = MATH_BIGINTEGER_BASE === 26 ? intval($sum / 0x4000000) : ($sum >> 31);
927
-
928
- $value[$i] = (int) ($sum - MATH_BIGINTEGER_BASE_FULL * $temp); // eg. a faster alternative to fmod($sum, 0x4000000)
929
- $value[$j] = $temp;
930
- }
931
-
932
- if ($j == $size) { // ie. if $y_size is odd
933
- $sum = $x_value[$i] + $y_value[$i] + $carry;
934
- $carry = $sum >= MATH_BIGINTEGER_BASE_FULL;
935
- $value[$i] = $carry ? $sum - MATH_BIGINTEGER_BASE_FULL : $sum;
936
- ++$i; // ie. let $i = $j since we've just done $value[$i]
937
- }
938
-
939
- if ($carry) {
940
- for (; $value[$i] == MATH_BIGINTEGER_MAX_DIGIT; ++$i) {
941
- $value[$i] = 0;
942
- }
943
- ++$value[$i];
944
- }
945
-
946
- return array(
947
- MATH_BIGINTEGER_VALUE => $this->_trim($value),
948
- MATH_BIGINTEGER_SIGN => $x_negative
949
- );
950
- }
951
-
952
- /**
953
- * Subtracts two BigIntegers.
954
- *
955
- * Here's an example:
956
- * <code>
957
- * <?php
958
- * include 'Math/BigInteger.php';
959
- *
960
- * $a = new Math_BigInteger('10');
961
- * $b = new Math_BigInteger('20');
962
- *
963
- * $c = $a->subtract($b);
964
- *
965
- * echo $c->toString(); // outputs -10
966
- * ?>
967
- * </code>
968
- *
969
- * @param Math_BigInteger $y
970
- * @return Math_BigInteger
971
- * @access public
972
- * @internal Performs base-2**52 subtraction
973
- */
974
- function subtract($y)
975
- {
976
- switch ( MATH_BIGINTEGER_MODE ) {
977
- case MATH_BIGINTEGER_MODE_GMP:
978
- $temp = new Math_BigInteger();
979
- $temp->value = gmp_sub($this->value, $y->value);
980
-
981
- return $this->_normalize($temp);
982
- case MATH_BIGINTEGER_MODE_BCMATH:
983
- $temp = new Math_BigInteger();
984
- $temp->value = bcsub($this->value, $y->value, 0);
985
-
986
- return $this->_normalize($temp);
987
- }
988
-
989
- $temp = $this->_subtract($this->value, $this->is_negative, $y->value, $y->is_negative);
990
-
991
- $result = new Math_BigInteger();
992
- $result->value = $temp[MATH_BIGINTEGER_VALUE];
993
- $result->is_negative = $temp[MATH_BIGINTEGER_SIGN];
994
-
995
- return $this->_normalize($result);
996
- }
997
-
998
- /**
999
- * Performs subtraction.
1000
- *
1001
- * @param Array $x_value
1002
- * @param Boolean $x_negative
1003
- * @param Array $y_value
1004
- * @param Boolean $y_negative
1005
- * @return Array
1006
- * @access private
1007
- */
1008
- function _subtract($x_value, $x_negative, $y_value, $y_negative)
1009
- {
1010
- $x_size = count($x_value);
1011
- $y_size = count($y_value);
1012
-
1013
- if ($x_size == 0) {
1014
- return array(
1015
- MATH_BIGINTEGER_VALUE => $y_value,
1016
- MATH_BIGINTEGER_SIGN => !$y_negative
1017
- );
1018
- } else if ($y_size == 0) {
1019
- return array(
1020
- MATH_BIGINTEGER_VALUE => $x_value,
1021
- MATH_BIGINTEGER_SIGN => $x_negative
1022
- );
1023
- }
1024
-
1025
- // add, if appropriate (ie. -$x - +$y or +$x - -$y)
1026
- if ( $x_negative != $y_negative ) {
1027
- $temp = $this->_add($x_value, false, $y_value, false);
1028
- $temp[MATH_BIGINTEGER_SIGN] = $x_negative;
1029
-
1030
- return $temp;
1031
- }
1032
-
1033
- $diff = $this->_compare($x_value, $x_negative, $y_value, $y_negative);
1034
-
1035
- if ( !$diff ) {
1036
- return array(
1037
- MATH_BIGINTEGER_VALUE => array(),
1038
- MATH_BIGINTEGER_SIGN => false
1039
- );
1040
- }
1041
-
1042
- // switch $x and $y around, if appropriate.
1043
- if ( (!$x_negative && $diff < 0) || ($x_negative && $diff > 0) ) {
1044
- $temp = $x_value;
1045
- $x_value = $y_value;
1046
- $y_value = $temp;
1047
-
1048
- $x_negative = !$x_negative;
1049
-
1050
- $x_size = count($x_value);
1051
- $y_size = count($y_value);
1052
- }
1053
-
1054
- // at this point, $x_value should be at least as big as - if not bigger than - $y_value
1055
-
1056
- $carry = 0;
1057
- for ($i = 0, $j = 1; $j < $y_size; $i+=2, $j+=2) {
1058
- $sum = $x_value[$j] * MATH_BIGINTEGER_BASE_FULL + $x_value[$i] - $y_value[$j] * MATH_BIGINTEGER_BASE_FULL - $y_value[$i] - $carry;
1059
- $carry = $sum < 0; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1
1060
- $sum = $carry ? $sum + MATH_BIGINTEGER_MAX_DIGIT2 : $sum;
1061
-
1062
- $temp = MATH_BIGINTEGER_BASE === 26 ? intval($sum / 0x4000000) : ($sum >> 31);
1063
-
1064
- $x_value[$i] = (int) ($sum - MATH_BIGINTEGER_BASE_FULL * $temp);
1065
- $x_value[$j] = $temp;
1066
- }
1067
-
1068
- if ($j == $y_size) { // ie. if $y_size is odd
1069
- $sum = $x_value[$i] - $y_value[$i] - $carry;
1070
- $carry = $sum < 0;
1071
- $x_value[$i] = $carry ? $sum + MATH_BIGINTEGER_BASE_FULL : $sum;
1072
- ++$i;
1073
- }
1074
-
1075
- if ($carry) {
1076
- for (; !$x_value[$i]; ++$i) {
1077
- $x_value[$i] = MATH_BIGINTEGER_MAX_DIGIT;
1078
- }
1079
- --$x_value[$i];
1080
- }
1081
-
1082
- return array(
1083
- MATH_BIGINTEGER_VALUE => $this->_trim($x_value),
1084
- MATH_BIGINTEGER_SIGN => $x_negative
1085
- );
1086
- }
1087
-
1088
- /**
1089
- * Multiplies two BigIntegers
1090
- *
1091
- * Here's an example:
1092
- * <code>
1093
- * <?php
1094
- * include 'Math/BigInteger.php';
1095
- *
1096
- * $a = new Math_BigInteger('10');
1097
- * $b = new Math_BigInteger('20');
1098
- *
1099
- * $c = $a->multiply($b);
1100
- *
1101
- * echo $c->toString(); // outputs 200
1102
- * ?>
1103
- * </code>
1104
- *
1105
- * @param Math_BigInteger $x
1106
- * @return Math_BigInteger
1107
- * @access public
1108
- */
1109
- function multiply($x)
1110
- {
1111
- switch ( MATH_BIGINTEGER_MODE ) {
1112
- case MATH_BIGINTEGER_MODE_GMP:
1113
- $temp = new Math_BigInteger();
1114
- $temp->value = gmp_mul($this->value, $x->value);
1115
-
1116
- return $this->_normalize($temp);
1117
- case MATH_BIGINTEGER_MODE_BCMATH:
1118
- $temp = new Math_BigInteger();
1119
- $temp->value = bcmul($this->value, $x->value, 0);
1120
-
1121
- return $this->_normalize($temp);
1122
- }
1123
-
1124
- $temp = $this->_multiply($this->value, $this->is_negative, $x->value, $x->is_negative);
1125
-
1126
- $product = new Math_BigInteger();
1127
- $product->value = $temp[MATH_BIGINTEGER_VALUE];
1128
- $product->is_negative = $temp[MATH_BIGINTEGER_SIGN];
1129
-
1130
- return $this->_normalize($product);
1131
- }
1132
-
1133
- /**
1134
- * Performs multiplication.
1135
- *
1136
- * @param Array $x_value
1137
- * @param Boolean $x_negative
1138
- * @param Array $y_value
1139
- * @param Boolean $y_negative
1140
- * @return Array
1141
- * @access private
1142
- */
1143
- function _multiply($x_value, $x_negative, $y_value, $y_negative)
1144
- {
1145
- //if ( $x_value == $y_value ) {
1146
- // return array(
1147
- // MATH_BIGINTEGER_VALUE => $this->_square($x_value),
1148
- // MATH_BIGINTEGER_SIGN => $x_sign != $y_value
1149
- // );
1150
- //}
1151
-
1152
- $x_length = count($x_value);
1153
- $y_length = count($y_value);
1154
-
1155
- if ( !$x_length || !$y_length ) { // a 0 is being multiplied
1156
- return array(
1157
- MATH_BIGINTEGER_VALUE => array(),
1158
- MATH_BIGINTEGER_SIGN => false
1159
- );
1160
- }
1161
-
1162
- return array(
1163
- MATH_BIGINTEGER_VALUE => min($x_length, $y_length) < 2 * MATH_BIGINTEGER_KARATSUBA_CUTOFF ?
1164
- $this->_trim($this->_regularMultiply($x_value, $y_value)) :
1165
- $this->_trim($this->_karatsuba($x_value, $y_value)),
1166
- MATH_BIGINTEGER_SIGN => $x_negative != $y_negative
1167
- );
1168
- }
1169
-
1170
- /**
1171
- * Performs long multiplication on two BigIntegers
1172
- *
1173
- * Modeled after 'multiply' in MutableBigInteger.java.
1174
- *
1175
- * @param Array $x_value
1176
- * @param Array $y_value
1177
- * @return Array
1178
- * @access private
1179
- */
1180
- function _regularMultiply($x_value, $y_value)
1181
- {
1182
- $x_length = count($x_value);
1183
- $y_length = count($y_value);
1184
-
1185
- if ( !$x_length || !$y_length ) { // a 0 is being multiplied
1186
- return array();
1187
- }
1188
-
1189
- if ( $x_length < $y_length ) {
1190
- $temp = $x_value;
1191
- $x_value = $y_value;
1192
- $y_value = $temp;
1193
-
1194
- $x_length = count($x_value);
1195
- $y_length = count($y_value);
1196
- }
1197
-
1198
- $product_value = $this->_array_repeat(0, $x_length + $y_length);
1199
-
1200
- // the following for loop could be removed if the for loop following it
1201
- // (the one with nested for loops) initially set $i to 0, but
1202
- // doing so would also make the result in one set of unnecessary adds,
1203
- // since on the outermost loops first pass, $product->value[$k] is going
1204
- // to always be 0
1205
-
1206
- $carry = 0;
1207
-
1208
- for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0
1209
- $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0
1210
- $carry = MATH_BIGINTEGER_BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
1211
- $product_value[$j] = (int) ($temp - MATH_BIGINTEGER_BASE_FULL * $carry);
1212
- }
1213
-
1214
- $product_value[$j] = $carry;
1215
-
1216
- // the above for loop is what the previous comment was talking about. the
1217
- // following for loop is the "one with nested for loops"
1218
- for ($i = 1; $i < $y_length; ++$i) {
1219
- $carry = 0;
1220
-
1221
- for ($j = 0, $k = $i; $j < $x_length; ++$j, ++$k) {
1222
- $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry;
1223
- $carry = MATH_BIGINTEGER_BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
1224
- $product_value[$k] = (int) ($temp - MATH_BIGINTEGER_BASE_FULL * $carry);
1225
- }
1226
-
1227
- $product_value[$k] = $carry;
1228
- }
1229
-
1230
- return $product_value;
1231
- }
1232
-
1233
- /**
1234
- * Performs Karatsuba multiplication on two BigIntegers
1235
- *
1236
- * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and
1237
- * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=120 MPM 5.2.3}.
1238
- *
1239
- * @param Array $x_value
1240
- * @param Array $y_value
1241
- * @return Array
1242
- * @access private
1243
- */
1244
- function _karatsuba($x_value, $y_value)
1245
- {
1246
- $m = min(count($x_value) >> 1, count($y_value) >> 1);
1247
-
1248
- if ($m < MATH_BIGINTEGER_KARATSUBA_CUTOFF) {
1249
- return $this->_regularMultiply($x_value, $y_value);
1250
- }
1251
-
1252
- $x1 = array_slice($x_value, $m);
1253
- $x0 = array_slice($x_value, 0, $m);
1254
- $y1 = array_slice($y_value, $m);
1255
- $y0 = array_slice($y_value, 0, $m);
1256
-
1257
- $z2 = $this->_karatsuba($x1, $y1);
1258
- $z0 = $this->_karatsuba($x0, $y0);
1259
-
1260
- $z1 = $this->_add($x1, false, $x0, false);
1261
- $temp = $this->_add($y1, false, $y0, false);
1262
- $z1 = $this->_karatsuba($z1[MATH_BIGINTEGER_VALUE], $temp[MATH_BIGINTEGER_VALUE]);
1263
- $temp = $this->_add($z2, false, $z0, false);
1264
- $z1 = $this->_subtract($z1, false, $temp[MATH_BIGINTEGER_VALUE], false);
1265
-
1266
- $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2);
1267
- $z1[MATH_BIGINTEGER_VALUE] = array_merge(array_fill(0, $m, 0), $z1[MATH_BIGINTEGER_VALUE]);
1268
-
1269
- $xy = $this->_add($z2, false, $z1[MATH_BIGINTEGER_VALUE], $z1[MATH_BIGINTEGER_SIGN]);
1270
- $xy = $this->_add($xy[MATH_BIGINTEGER_VALUE], $xy[MATH_BIGINTEGER_SIGN], $z0, false);
1271
-
1272
- return $xy[MATH_BIGINTEGER_VALUE];
1273
- }
1274
-
1275
- /**
1276
- * Performs squaring
1277
- *
1278
- * @param Array $x
1279
- * @return Array
1280
- * @access private
1281
- */
1282
- function _square($x = false)
1283
- {
1284
- return count($x) < 2 * MATH_BIGINTEGER_KARATSUBA_CUTOFF ?
1285
- $this->_trim($this->_baseSquare($x)) :
1286
- $this->_trim($this->_karatsubaSquare($x));
1287
- }
1288
-
1289
- /**
1290
- * Performs traditional squaring on two BigIntegers
1291
- *
1292
- * Squaring can be done faster than multiplying a number by itself can be. See
1293
- * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=7 HAC 14.2.4} /
1294
- * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=141 MPM 5.3} for more information.
1295
- *
1296
- * @param Array $value
1297
- * @return Array
1298
- * @access private
1299
- */
1300
- function _baseSquare($value)
1301
- {
1302
- if ( empty($value) ) {
1303
- return array();
1304
- }
1305
- $square_value = $this->_array_repeat(0, 2 * count($value));
1306
-
1307
- for ($i = 0, $max_index = count($value) - 1; $i <= $max_index; ++$i) {
1308
- $i2 = $i << 1;
1309
-
1310
- $temp = $square_value[$i2] + $value[$i] * $value[$i];
1311
- $carry = MATH_BIGINTEGER_BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
1312
- $square_value[$i2] = (int) ($temp - MATH_BIGINTEGER_BASE_FULL * $carry);
1313
-
1314
- // note how we start from $i+1 instead of 0 as we do in multiplication.
1315
- for ($j = $i + 1, $k = $i2 + 1; $j <= $max_index; ++$j, ++$k) {
1316
- $temp = $square_value[$k] + 2 * $value[$j] * $value[$i] + $carry;
1317
- $carry = MATH_BIGINTEGER_BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
1318
- $square_value[$k] = (int) ($temp - MATH_BIGINTEGER_BASE_FULL * $carry);
1319
- }
1320
-
1321
- // the following line can yield values larger 2**15. at this point, PHP should switch
1322
- // over to floats.
1323
- $square_value[$i + $max_index + 1] = $carry;
1324
- }
1325
-
1326
- return $square_value;
1327
- }
1328
-
1329
- /**
1330
- * Performs Karatsuba "squaring" on two BigIntegers
1331
- *
1332
- * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and
1333
- * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=151 MPM 5.3.4}.
1334
- *
1335
- * @param Array $value
1336
- * @return Array
1337
- * @access private
1338
- */
1339
- function _karatsubaSquare($value)
1340
- {
1341
- $m = count($value) >> 1;
1342
-
1343
- if ($m < MATH_BIGINTEGER_KARATSUBA_CUTOFF) {
1344
- return $this->_baseSquare($value);
1345
- }
1346
-
1347
- $x1 = array_slice($value, $m);
1348
- $x0 = array_slice($value, 0, $m);
1349
-
1350
- $z2 = $this->_karatsubaSquare($x1);
1351
- $z0 = $this->_karatsubaSquare($x0);
1352
-
1353
- $z1 = $this->_add($x1, false, $x0, false);
1354
- $z1 = $this->_karatsubaSquare($z1[MATH_BIGINTEGER_VALUE]);
1355
- $temp = $this->_add($z2, false, $z0, false);
1356
- $z1 = $this->_subtract($z1, false, $temp[MATH_BIGINTEGER_VALUE], false);
1357
-
1358
- $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2);
1359
- $z1[MATH_BIGINTEGER_VALUE] = array_merge(array_fill(0, $m, 0), $z1[MATH_BIGINTEGER_VALUE]);
1360
-
1361
- $xx = $this->_add($z2, false, $z1[MATH_BIGINTEGER_VALUE], $z1[MATH_BIGINTEGER_SIGN]);
1362
- $xx = $this->_add($xx[MATH_BIGINTEGER_VALUE], $xx[MATH_BIGINTEGER_SIGN], $z0, false);
1363
-
1364
- return $xx[MATH_BIGINTEGER_VALUE];
1365
- }
1366
-
1367
- /**
1368
- * Divides two BigIntegers.
1369
- *
1370
- * Returns an array whose first element contains the quotient and whose second element contains the
1371
- * "common residue". If the remainder would be positive, the "common residue" and the remainder are the
1372
- * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder
1373
- * and the divisor (basically, the "common residue" is the first positive modulo).
1374
- *
1375
- * Here's an example:
1376
- * <code>
1377
- * <?php
1378
- * include 'Math/BigInteger.php';
1379
- *
1380
- * $a = new Math_BigInteger('10');
1381
- * $b = new Math_BigInteger('20');
1382
- *
1383
- * list($quotient, $remainder) = $a->divide($b);
1384
- *
1385
- * echo $quotient->toString(); // outputs 0
1386
- * echo "\r\n";
1387
- * echo $remainder->toString(); // outputs 10
1388
- * ?>
1389
- * </code>
1390
- *
1391
- * @param Math_BigInteger $y
1392
- * @return Array
1393
- * @access public
1394
- * @internal This function is based off of {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=9 HAC 14.20}.
1395
- */
1396
- function divide($y)
1397
- {
1398
- switch ( MATH_BIGINTEGER_MODE ) {
1399
- case MATH_BIGINTEGER_MODE_GMP:
1400
- $quotient = new Math_BigInteger();
1401
- $remainder = new Math_BigInteger();
1402
-
1403
- list($quotient->value, $remainder->value) = gmp_div_qr($this->value, $y->value);
1404
-
1405
- if (gmp_sign($remainder->value) < 0) {
1406
- $remainder->value = gmp_add($remainder->value, gmp_abs($y->value));
1407
- }
1408
-
1409
- return array($this->_normalize($quotient), $this->_normalize($remainder));
1410
- case MATH_BIGINTEGER_MODE_BCMATH:
1411
- $quotient = new Math_BigInteger();
1412
- $remainder = new Math_BigInteger();
1413
-
1414
- $quotient->value = bcdiv($this->value, $y->value, 0);
1415
- $remainder->value = bcmod($this->value, $y->value);
1416
-
1417
- if ($remainder->value[0] == '-') {
1418
- $remainder->value = bcadd($remainder->value, $y->value[0] == '-' ? substr($y->value, 1) : $y->value, 0);
1419
- }
1420
-
1421
- return array($this->_normalize($quotient), $this->_normalize($remainder));
1422
- }
1423
-
1424
- if (count($y->value) == 1) {
1425
- list($q, $r) = $this->_divide_digit($this->value, $y->value[0]);
1426
- $quotient = new Math_BigInteger();
1427
- $remainder = new Math_BigInteger();
1428
- $quotient->value = $q;
1429
- $remainder->value = array($r);
1430
- $quotient->is_negative = $this->is_negative != $y->is_negative;
1431
- return array($this->_normalize($quotient), $this->_normalize($remainder));
1432
- }
1433
-
1434
- static $zero;
1435
- if ( !isset($zero) ) {
1436
- $zero = new Math_BigInteger();
1437
- }
1438
-
1439
- $x = $this->copy();
1440
- $y = $y->copy();
1441
-
1442
- $x_sign = $x->is_negative;
1443
- $y_sign = $y->is_negative;
1444
-
1445
- $x->is_negative = $y->is_negative = false;
1446
-
1447
- $diff = $x->compare($y);
1448
-
1449
- if ( !$diff ) {
1450
- $temp = new Math_BigInteger();
1451
- $temp->value = array(1);
1452
- $temp->is_negative = $x_sign != $y_sign;
1453
- return array($this->_normalize($temp), $this->_normalize(new Math_BigInteger()));
1454
- }
1455
-
1456
- if ( $diff < 0 ) {
1457
- // if $x is negative, "add" $y.
1458
- if ( $x_sign ) {
1459
- $x = $y->subtract($x);
1460
- }
1461
- return array($this->_normalize(new Math_BigInteger()), $this->_normalize($x));
1462
- }
1463
-
1464
- // normalize $x and $y as described in HAC 14.23 / 14.24
1465
- $msb = $y->value[count($y->value) - 1];
1466
- for ($shift = 0; !($msb & MATH_BIGINTEGER_MSB); ++$shift) {
1467
- $msb <<= 1;
1468
- }
1469
- $x->_lshift($shift);
1470
- $y->_lshift($shift);
1471
- $y_value = &$y->value;
1472
-
1473
- $x_max = count($x->value) - 1;
1474
- $y_max = count($y->value) - 1;
1475
-
1476
- $quotient = new Math_BigInteger();
1477
- $quotient_value = &$quotient->value;
1478
- $quotient_value = $this->_array_repeat(0, $x_max - $y_max + 1);
1479
-
1480
- static $temp, $lhs, $rhs;
1481
- if (!isset($temp)) {
1482
- $temp = new Math_BigInteger();
1483
- $lhs = new Math_BigInteger();
1484
- $rhs = new Math_BigInteger();
1485
- }
1486
- $temp_value = &$temp->value;
1487
- $rhs_value = &$rhs->value;
1488
-
1489
- // $temp = $y << ($x_max - $y_max-1) in base 2**26
1490
- $temp_value = array_merge($this->_array_repeat(0, $x_max - $y_max), $y_value);
1491
-
1492
- while ( $x->compare($temp) >= 0 ) {
1493
- // calculate the "common residue"
1494
- ++$quotient_value[$x_max - $y_max];
1495
- $x = $x->subtract($temp);
1496
- $x_max = count($x->value) - 1;
1497
- }
1498
-
1499
- for ($i = $x_max; $i >= $y_max + 1; --$i) {
1500
- $x_value = &$x->value;
1501
- $x_window = array(
1502
- isset($x_value[$i]) ? $x_value[$i] : 0,
1503
- isset($x_value[$i - 1]) ? $x_value[$i - 1] : 0,
1504
- isset($x_value[$i - 2]) ? $x_value[$i - 2] : 0
1505
- );
1506
- $y_window = array(
1507
- $y_value[$y_max],
1508
- ( $y_max > 0 ) ? $y_value[$y_max - 1] : 0
1509
- );
1510
-
1511
- $q_index = $i - $y_max - 1;
1512
- if ($x_window[0] == $y_window[0]) {
1513
- $quotient_value[$q_index] = MATH_BIGINTEGER_MAX_DIGIT;
1514
- } else {
1515
- $quotient_value[$q_index] = $this->_safe_divide(
1516
- $x_window[0] * MATH_BIGINTEGER_BASE_FULL + $x_window[1],
1517
- $y_window[0]
1518
- );
1519
- }
1520
-
1521
- $temp_value = array($y_window[1], $y_window[0]);
1522
-
1523
- $lhs->value = array($quotient_value[$q_index]);
1524
- $lhs = $lhs->multiply($temp);
1525
-
1526
- $rhs_value = array($x_window[2], $x_window[1], $x_window[0]);
1527
-
1528
- while ( $lhs->compare($rhs) > 0 ) {
1529
- --$quotient_value[$q_index];
1530
-
1531
- $lhs->value = array($quotient_value[$q_index]);
1532
- $lhs = $lhs->multiply($temp);
1533
- }
1534
-
1535
- $adjust = $this->_array_repeat(0, $q_index);
1536
- $temp_value = array($quotient_value[$q_index]);
1537
- $temp = $temp->multiply($y);
1538
- $temp_value = &$temp->value;
1539
- $temp_value = array_merge($adjust, $temp_value);
1540
-
1541
- $x = $x->subtract($temp);
1542
-
1543
- if ($x->compare($zero) < 0) {
1544
- $temp_value = array_merge($adjust, $y_value);
1545
- $x = $x->add($temp);
1546
-
1547
- --$quotient_value[$q_index];
1548
- }
1549
-
1550
- $x_max = count($x_value) - 1;
1551
- }
1552
-
1553
- // unnormalize the remainder
1554
- $x->_rshift($shift);
1555
-
1556
- $quotient->is_negative = $x_sign != $y_sign;
1557
-
1558
- // calculate the "common residue", if appropriate
1559
- if ( $x_sign ) {
1560
- $y->_rshift($shift);
1561
- $x = $y->subtract($x);
1562
- }
1563
-
1564
- return array($this->_normalize($quotient), $this->_normalize($x));
1565
- }
1566
-
1567
- /**
1568
- * Divides a BigInteger by a regular integer
1569
- *
1570
- * abc / x = a00 / x + b0 / x + c / x
1571
- *
1572
- * @param Array $dividend
1573
- * @param Array $divisor
1574
- * @return Array
1575
- * @access private
1576
- */
1577
- function _divide_digit($dividend, $divisor)
1578
- {
1579
- $carry = 0;
1580
- $result = array();
1581
-
1582
- for ($i = count($dividend) - 1; $i >= 0; --$i) {
1583
- $temp = MATH_BIGINTEGER_BASE_FULL * $carry + $dividend[$i];
1584
- $result[$i] = $this->_safe_divide($temp, $divisor);
1585
- $carry = (int) ($temp - $divisor * $result[$i]);
1586
- }
1587
-
1588
- return array($result, $carry);
1589
- }
1590
-
1591
- /**
1592
- * Performs modular exponentiation.
1593
- *
1594
- * Here's an example:
1595
- * <code>
1596
- * <?php
1597
- * include 'Math/BigInteger.php';
1598
- *
1599
- * $a = new Math_BigInteger('10');
1600
- * $b = new Math_BigInteger('20');
1601
- * $c = new Math_BigInteger('30');
1602
- *
1603
- * $c = $a->modPow($b, $c);
1604
- *
1605
- * echo $c->toString(); // outputs 10
1606
- * ?>
1607
- * </code>
1608
- *
1609
- * @param Math_BigInteger $e
1610
- * @param Math_BigInteger $n
1611
- * @return Math_BigInteger
1612
- * @access public
1613
- * @internal The most naive approach to modular exponentiation has very unreasonable requirements, and
1614
- * and although the approach involving repeated squaring does vastly better, it, too, is impractical
1615
- * for our purposes. The reason being that division - by far the most complicated and time-consuming
1616
- * of the basic operations (eg. +,-,*,/) - occurs multiple times within it.
1617
- *
1618
- * Modular reductions resolve this issue. Although an individual modular reduction takes more time
1619
- * then an individual division, when performed in succession (with the same modulo), they're a lot faster.
1620
- *
1621
- * The two most commonly used modular reductions are Barrett and Montgomery reduction. Montgomery reduction,
1622
- * although faster, only works when the gcd of the modulo and of the base being used is 1. In RSA, when the
1623
- * base is a power of two, the modulo - a product of two primes - is always going to have a gcd of 1 (because
1624
- * the product of two odd numbers is odd), but what about when RSA isn't used?
1625
- *
1626
- * In contrast, Barrett reduction has no such constraint. As such, some bigint implementations perform a
1627
- * Barrett reduction after every operation in the modpow function. Others perform Barrett reductions when the
1628
- * modulo is even and Montgomery reductions when the modulo is odd. BigInteger.java's modPow method, however,
1629
- * uses a trick involving the Chinese Remainder Theorem to factor the even modulo into two numbers - one odd and
1630
- * the other, a power of two - and recombine them, later. This is the method that this modPow function uses.
1631
- * {@link http://islab.oregonstate.edu/papers/j34monex.pdf Montgomery Reduction with Even Modulus} elaborates.
1632
- */
1633
- function modPow($e, $n)
1634
- {
1635
- $n = $this->bitmask !== false && $this->bitmask->compare($n) < 0 ? $this->bitmask : $n->abs();
1636
-
1637
- if ($e->compare(new Math_BigInteger()) < 0) {
1638
- $e = $e->abs();
1639
-
1640
- $temp = $this->modInverse($n);
1641
- if ($temp === false) {
1642
- return false;
1643
- }
1644
-
1645
- return $this->_normalize($temp->modPow($e, $n));
1646
- }
1647
-
1648
- if ( MATH_BIGINTEGER_MODE == MATH_BIGINTEGER_MODE_GMP ) {
1649
- $temp = new Math_BigInteger();
1650
- $temp->value = gmp_powm($this->value, $e->value, $n->value);
1651
-
1652
- return $this->_normalize($temp);
1653
- }
1654
-
1655
- if ($this->compare(new Math_BigInteger()) < 0 || $this->compare($n) > 0) {
1656
- list(, $temp) = $this->divide($n);
1657
- return $temp->modPow($e, $n);
1658
- }
1659
-
1660
- if (defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) {
1661
- $components = array(
1662
- 'modulus' => $n->toBytes(true),
1663
- 'publicExponent' => $e->toBytes(true)
1664
- );
1665
-
1666
- $components = array(
1667
- 'modulus' => pack('Ca*a*', 2, $this->_encodeASN1Length(strlen($components['modulus'])), $components['modulus']),
1668
- 'publicExponent' => pack('Ca*a*', 2, $this->_encodeASN1Length(strlen($components['publicExponent'])), $components['publicExponent'])
1669
- );
1670
-
1671
- $RSAPublicKey = pack('Ca*a*a*',
1672
- 48, $this->_encodeASN1Length(strlen($components['modulus']) + strlen($components['publicExponent'])),
1673
- $components['modulus'], $components['publicExponent']
1674
- );
1675
-
1676
- $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
1677
- $RSAPublicKey = chr(0) . $RSAPublicKey;
1678
- $RSAPublicKey = chr(3) . $this->_encodeASN1Length(strlen($RSAPublicKey)) . $RSAPublicKey;
1679
-
1680
- $encapsulated = pack('Ca*a*',
1681
- 48, $this->_encodeASN1Length(strlen($rsaOID . $RSAPublicKey)), $rsaOID . $RSAPublicKey
1682
- );
1683
-
1684
- $RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" .
1685
- chunk_split(base64_encode($encapsulated)) .
1686
- '-----END PUBLIC KEY-----';
1687
-
1688
- $plaintext = str_pad($this->toBytes(), strlen($n->toBytes(true)) - 1, "\0", STR_PAD_LEFT);
1689
-
1690
- if (openssl_public_encrypt($plaintext, $result, $RSAPublicKey, OPENSSL_NO_PADDING)) {
1691
- return new Math_BigInteger($result, 256);
1692
- }
1693
- }
1694
-
1695
- if ( MATH_BIGINTEGER_MODE == MATH_BIGINTEGER_MODE_BCMATH ) {
1696
- $temp = new Math_BigInteger();
1697
- $temp->value = bcpowmod($this->value, $e->value, $n->value, 0);
1698
-
1699
- return $this->_normalize($temp);
1700
- }
1701
-
1702
- if ( empty($e->value) ) {
1703
- $temp = new Math_BigInteger();
1704
- $temp->value = array(1);
1705
- return $this->_normalize($temp);
1706
- }
1707
-
1708
- if ( $e->value == array(1) ) {
1709
- list(, $temp) = $this->divide($n);
1710
- return $this->_normalize($temp);
1711
- }
1712
-
1713
- if ( $e->value == array(2) ) {
1714
- $temp = new Math_BigInteger();
1715
- $temp->value = $this->_square($this->value);
1716
- list(, $temp) = $temp->divide($n);
1717
- return $this->_normalize($temp);
1718
- }
1719
-
1720
- return $this->_normalize($this->_slidingWindow($e, $n, MATH_BIGINTEGER_BARRETT));
1721
-
1722
- // the following code, although not callable, can be run independently of the above code
1723
- // although the above code performed better in my benchmarks the following could might
1724
- // perform better under different circumstances. in lieu of deleting it it's just been
1725
- // made uncallable
1726
-
1727
- // is the modulo odd?
1728
- if ( $n->value[0] & 1 ) {
1729
- return $this->_normalize($this->_slidingWindow($e, $n, MATH_BIGINTEGER_MONTGOMERY));
1730
- }
1731
- // if it's not, it's even
1732
-
1733
- // find the lowest set bit (eg. the max pow of 2 that divides $n)
1734
- for ($i = 0; $i < count($n->value); ++$i) {
1735
- if ( $n->value[$i] ) {
1736
- $temp = decbin($n->value[$i]);
1737
- $j = strlen($temp) - strrpos($temp, '1') - 1;
1738
- $j+= 26 * $i;
1739
- break;
1740
- }
1741
- }
1742
- // at this point, 2^$j * $n/(2^$j) == $n
1743
-
1744
- $mod1 = $n->copy();
1745
- $mod1->_rshift($j);
1746
- $mod2 = new Math_BigInteger();
1747
- $mod2->value = array(1);
1748
- $mod2->_lshift($j);
1749
-
1750
- $part1 = ( $mod1->value != array(1) ) ? $this->_slidingWindow($e, $mod1, MATH_BIGINTEGER_MONTGOMERY) : new Math_BigInteger();
1751
- $part2 = $this->_slidingWindow($e, $mod2, MATH_BIGINTEGER_POWEROF2);
1752
-
1753
- $y1 = $mod2->modInverse($mod1);
1754
- $y2 = $mod1->modInverse($mod2);
1755
-
1756
- $result = $part1->multiply($mod2);
1757
- $result = $result->multiply($y1);
1758
-
1759
- $temp = $part2->multiply($mod1);
1760
- $temp = $temp->multiply($y2);
1761
-
1762
- $result = $result->add($temp);
1763
- list(, $result) = $result->divide($n);
1764
-
1765
- return $this->_normalize($result);
1766
- }
1767
-
1768
- /**
1769
- * Performs modular exponentiation.
1770
- *
1771
- * Alias for Math_BigInteger::modPow()
1772
- *
1773
- * @param Math_BigInteger $e
1774
- * @param Math_BigInteger $n
1775
- * @return Math_BigInteger
1776
- * @access public
1777
- */
1778
- function powMod($e, $n)
1779
- {
1780
- return $this->modPow($e, $n);
1781
- }
1782
-
1783
- /**
1784
- * Sliding Window k-ary Modular Exponentiation
1785
- *
1786
- * Based on {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=27 HAC 14.85} /
1787
- * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=210 MPM 7.7}. In a departure from those algorithims,
1788
- * however, this function performs a modular reduction after every multiplication and squaring operation.
1789
- * As such, this function has the same preconditions that the reductions being used do.
1790
- *
1791
- * @param Math_BigInteger $e
1792
- * @param Math_BigInteger $n
1793
- * @param Integer $mode
1794
- * @return Math_BigInteger
1795
- * @access private
1796
- */
1797
- function _slidingWindow($e, $n, $mode)
1798
- {
1799
- static $window_ranges = array(7, 25, 81, 241, 673, 1793); // from BigInteger.java's oddModPow function
1800
- //static $window_ranges = array(0, 7, 36, 140, 450, 1303, 3529); // from MPM 7.3.1
1801
-
1802
- $e_value = $e->value;
1803
- $e_length = count($e_value) - 1;
1804
- $e_bits = decbin($e_value[$e_length]);
1805
- for ($i = $e_length - 1; $i >= 0; --$i) {
1806
- $e_bits.= str_pad(decbin($e_value[$i]), MATH_BIGINTEGER_BASE, '0', STR_PAD_LEFT);
1807
- }
1808
-
1809
- $e_length = strlen($e_bits);
1810
-
1811
- // calculate the appropriate window size.
1812
- // $window_size == 3 if $window_ranges is between 25 and 81, for example.
1813
- for ($i = 0, $window_size = 1; $e_length > $window_ranges[$i] && $i < count($window_ranges); ++$window_size, ++$i);
1814
-
1815
- $n_value = $n->value;
1816
-
1817
- // precompute $this^0 through $this^$window_size
1818
- $powers = array();
1819
- $powers[1] = $this->_prepareReduce($this->value, $n_value, $mode);
1820
- $powers[2] = $this->_squareReduce($powers[1], $n_value, $mode);
1821
-
1822
- // we do every other number since substr($e_bits, $i, $j+1) (see below) is supposed to end
1823
- // in a 1. ie. it's supposed to be odd.
1824
- $temp = 1 << ($window_size - 1);
1825
- for ($i = 1; $i < $temp; ++$i) {
1826
- $i2 = $i << 1;
1827
- $powers[$i2 + 1] = $this->_multiplyReduce($powers[$i2 - 1], $powers[2], $n_value, $mode);
1828
- }
1829
-
1830
- $result = array(1);
1831
- $result = $this->_prepareReduce($result, $n_value, $mode);
1832
-
1833
- for ($i = 0; $i < $e_length; ) {
1834
- if ( !$e_bits[$i] ) {
1835
- $result = $this->_squareReduce($result, $n_value, $mode);
1836
- ++$i;
1837
- } else {
1838
- for ($j = $window_size - 1; $j > 0; --$j) {
1839
- if ( !empty($e_bits[$i + $j]) ) {
1840
- break;
1841
- }
1842
- }
1843
-
1844
- for ($k = 0; $k <= $j; ++$k) {// eg. the length of substr($e_bits, $i, $j+1)
1845
- $result = $this->_squareReduce($result, $n_value, $mode);
1846
- }
1847
-
1848
- $result = $this->_multiplyReduce($result, $powers[bindec(substr($e_bits, $i, $j + 1))], $n_value, $mode);
1849
-
1850
- $i+=$j + 1;
1851
- }
1852
- }
1853
-
1854
- $temp = new Math_BigInteger();
1855
- $temp->value = $this->_reduce($result, $n_value, $mode);
1856
-
1857
- return $temp;
1858
- }
1859
-
1860
- /**
1861
- * Modular reduction
1862
- *
1863
- * For most $modes this will return the remainder.
1864
- *
1865
- * @see _slidingWindow()
1866
- * @access private
1867
- * @param Array $x
1868
- * @param Array $n
1869
- * @param Integer $mode
1870
- * @return Array
1871
- */
1872
- function _reduce($x, $n, $mode)
1873
- {
1874
- switch ($mode) {
1875
- case MATH_BIGINTEGER_MONTGOMERY:
1876
- return $this->_montgomery($x, $n);
1877
- case MATH_BIGINTEGER_BARRETT:
1878
- return $this->_barrett($x, $n);
1879
- case MATH_BIGINTEGER_POWEROF2:
1880
- $lhs = new Math_BigInteger();
1881
- $lhs->value = $x;
1882
- $rhs = new Math_BigInteger();
1883
- $rhs->value = $n;
1884
- return $x->_mod2($n);
1885
- case MATH_BIGINTEGER_CLASSIC:
1886
- $lhs = new Math_BigInteger();
1887
- $lhs->value = $x;
1888
- $rhs = new Math_BigInteger();
1889
- $rhs->value = $n;
1890
- list(, $temp) = $lhs->divide($rhs);
1891
- return $temp->value;
1892
- case MATH_BIGINTEGER_NONE:
1893
- return $x;
1894
- default:
1895
- // an invalid $mode was provided
1896
- }
1897
- }
1898
-
1899
- /**
1900
- * Modular reduction preperation
1901
- *
1902
- * @see _slidingWindow()
1903
- * @access private
1904
- * @param Array $x
1905
- * @param Array $n
1906
- * @param Integer $mode
1907
- * @return Array
1908
- */
1909
- function _prepareReduce($x, $n, $mode)
1910
- {
1911
- if ($mode == MATH_BIGINTEGER_MONTGOMERY) {
1912
- return $this->_prepMontgomery($x, $n);
1913
- }
1914
- return $this->_reduce($x, $n, $mode);
1915
- }
1916
-
1917
- /**
1918
- * Modular multiply
1919
- *
1920
- * @see _slidingWindow()
1921
- * @access private
1922
- * @param Array $x
1923
- * @param Array $y
1924
- * @param Array $n
1925
- * @param Integer $mode
1926
- * @return Array
1927
- */
1928
- function _multiplyReduce($x, $y, $n, $mode)
1929
- {
1930
- if ($mode == MATH_BIGINTEGER_MONTGOMERY) {
1931
- return $this->_montgomeryMultiply($x, $y, $n);
1932
- }
1933
- $temp = $this->_multiply($x, false, $y, false);
1934
- return $this->_reduce($temp[MATH_BIGINTEGER_VALUE], $n, $mode);
1935
- }
1936
-
1937
- /**
1938
- * Modular square
1939
- *
1940
- * @see _slidingWindow()
1941
- * @access private
1942
- * @param Array $x
1943
- * @param Array $n
1944
- * @param Integer $mode
1945
- * @return Array
1946
- */
1947
- function _squareReduce($x, $n, $mode)
1948
- {
1949
- if ($mode == MATH_BIGINTEGER_MONTGOMERY) {
1950
- return $this->_montgomeryMultiply($x, $x, $n);
1951
- }
1952
- return $this->_reduce($this->_square($x), $n, $mode);
1953
- }
1954
-
1955
- /**
1956
- * Modulos for Powers of Two
1957
- *
1958
- * Calculates $x%$n, where $n = 2**$e, for some $e. Since this is basically the same as doing $x & ($n-1),
1959
- * we'll just use this function as a wrapper for doing that.
1960
- *
1961
- * @see _slidingWindow()
1962
- * @access private
1963
- * @param Math_BigInteger
1964
- * @return Math_BigInteger
1965
- */
1966
- function _mod2($n)
1967
- {
1968
- $temp = new Math_BigInteger();
1969
- $temp->value = array(1);
1970
- return $this->bitwise_and($n->subtract($temp));
1971
- }
1972
-
1973
- /**
1974
- * Barrett Modular Reduction
1975
- *
1976
- * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=14 HAC 14.3.3} /
1977
- * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=165 MPM 6.2.5} for more information. Modified slightly,
1978
- * so as not to require negative numbers (initially, this script didn't support negative numbers).
1979
- *
1980
- * Employs "folding", as described at
1981
- * {@link http://www.cosic.esat.kuleuven.be/publications/thesis-149.pdf#page=66 thesis-149.pdf#page=66}. To quote from
1982
- * it, "the idea [behind folding] is to find a value x' such that x (mod m) = x' (mod m), with x' being smaller than x."
1983
- *
1984
- * Unfortunately, the "Barrett Reduction with Folding" algorithm described in thesis-149.pdf is not, as written, all that
1985
- * usable on account of (1) its not using reasonable radix points as discussed in
1986
- * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=162 MPM 6.2.2} and (2) the fact that, even with reasonable
1987
- * radix points, it only works when there are an even number of digits in the denominator. The reason for (2) is that
1988
- * (x >> 1) + (x >> 1) != x / 2 + x / 2. If x is even, they're the same, but if x is odd, they're not. See the in-line
1989
- * comments for details.
1990
- *
1991
- * @see _slidingWindow()
1992
- * @access private
1993
- * @param Array $n
1994
- * @param Array $m
1995
- * @return Array
1996
- */
1997
- function _barrett($n, $m)
1998
- {
1999
- static $cache = array(
2000
- MATH_BIGINTEGER_VARIABLE => array(),
2001
- MATH_BIGINTEGER_DATA => array()
2002
- );
2003
-
2004
- $m_length = count($m);
2005
-
2006
- // if ($this->_compare($n, $this->_square($m)) >= 0) {
2007
- if (count($n) > 2 * $m_length) {
2008
- $lhs = new Math_BigInteger();
2009
- $rhs = new Math_BigInteger();
2010
- $lhs->value = $n;
2011
- $rhs->value = $m;
2012
- list(, $temp) = $lhs->divide($rhs);
2013
- return $temp->value;
2014
- }
2015
-
2016
- // if (m.length >> 1) + 2 <= m.length then m is too small and n can't be reduced
2017
- if ($m_length < 5) {
2018
- return $this->_regularBarrett($n, $m);
2019
- }
2020
-
2021
- // n = 2 * m.length
2022
-
2023
- if ( ($key = array_search($m, $cache[MATH_BIGINTEGER_VARIABLE])) === false ) {
2024
- $key = count($cache[MATH_BIGINTEGER_VARIABLE]);
2025
- $cache[MATH_BIGINTEGER_VARIABLE][] = $m;
2026
-
2027
- $lhs = new Math_BigInteger();
2028
- $lhs_value = &$lhs->value;
2029
- $lhs_value = $this->_array_repeat(0, $m_length + ($m_length >> 1));
2030
- $lhs_value[] = 1;
2031
- $rhs = new Math_BigInteger();
2032
- $rhs->value = $m;
2033
-
2034
- list($u, $m1) = $lhs->divide($rhs);
2035
- $u = $u->value;
2036
- $m1 = $m1->value;
2037
-
2038
- $cache[MATH_BIGINTEGER_DATA][] = array(
2039
- 'u' => $u, // m.length >> 1 (technically (m.length >> 1) + 1)
2040
- 'm1'=> $m1 // m.length
2041
- );
2042
- } else {
2043
- extract($cache[MATH_BIGINTEGER_DATA][$key]);
2044
- }
2045
-
2046
- $cutoff = $m_length + ($m_length >> 1);
2047
- $lsd = array_slice($n, 0, $cutoff); // m.length + (m.length >> 1)
2048
- $msd = array_slice($n, $cutoff); // m.length >> 1
2049
- $lsd = $this->_trim($lsd);
2050
- $temp = $this->_multiply($msd, false, $m1, false);
2051
- $n = $this->_add($lsd, false, $temp[MATH_BIGINTEGER_VALUE], false); // m.length + (m.length >> 1) + 1
2052
-
2053
- if ($m_length & 1) {
2054
- return $this->_regularBarrett($n[MATH_BIGINTEGER_VALUE], $m);
2055
- }
2056
-
2057
- // (m.length + (m.length >> 1) + 1) - (m.length - 1) == (m.length >> 1) + 2
2058
- $temp = array_slice($n[MATH_BIGINTEGER_VALUE], $m_length - 1);
2059
- // if even: ((m.length >> 1) + 2) + (m.length >> 1) == m.length + 2
2060
- // if odd: ((m.length >> 1) + 2) + (m.length >> 1) == (m.length - 1) + 2 == m.length + 1
2061
- $temp = $this->_multiply($temp, false, $u, false);
2062
- // if even: (m.length + 2) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + 1
2063
- // if odd: (m.length + 1) - ((m.length >> 1) + 1) = m.length - (m.length >> 1)
2064
- $temp = array_slice($temp[MATH_BIGINTEGER_VALUE], ($m_length >> 1) + 1);
2065
- // if even: (m.length - (m.length >> 1) + 1) + m.length = 2 * m.length - (m.length >> 1) + 1
2066
- // if odd: (m.length - (m.length >> 1)) + m.length = 2 * m.length - (m.length >> 1)
2067
- $temp = $this->_multiply($temp, false, $m, false);
2068
-
2069
- // at this point, if m had an odd number of digits, we'd be subtracting a 2 * m.length - (m.length >> 1) digit
2070
- // number from a m.length + (m.length >> 1) + 1 digit number. ie. there'd be an extra digit and the while loop
2071
- // following this comment would loop a lot (hence our calling _regularBarrett() in that situation).
2072
-
2073
- $result = $this->_subtract($n[MATH_BIGINTEGER_VALUE], false, $temp[MATH_BIGINTEGER_VALUE], false);
2074
-
2075
- while ($this->_compare($result[MATH_BIGINTEGER_VALUE], $result[MATH_BIGINTEGER_SIGN], $m, false) >= 0) {
2076
- $result = $this->_subtract($result[MATH_BIGINTEGER_VALUE], $result[MATH_BIGINTEGER_SIGN], $m, false);
2077
- }
2078
-
2079
- return $result[MATH_BIGINTEGER_VALUE];
2080
- }
2081
-
2082
- /**
2083
- * (Regular) Barrett Modular Reduction
2084
- *
2085
- * For numbers with more than four digits Math_BigInteger::_barrett() is faster. The difference between that and this
2086
- * is that this function does not fold the denominator into a smaller form.
2087
- *
2088
- * @see _slidingWindow()
2089
- * @access private
2090
- * @param Array $x
2091
- * @param Array $n
2092
- * @return Array
2093
- */
2094
- function _regularBarrett($x, $n)
2095
- {
2096
- static $cache = array(
2097
- MATH_BIGINTEGER_VARIABLE => array(),
2098
- MATH_BIGINTEGER_DATA => array()
2099
- );
2100
-
2101
- $n_length = count($n);
2102
-
2103
- if (count($x) > 2 * $n_length) {
2104
- $lhs = new Math_BigInteger();
2105
- $rhs = new Math_BigInteger();
2106
- $lhs->value = $x;
2107
- $rhs->value = $n;
2108
- list(, $temp) = $lhs->divide($rhs);
2109
- return $temp->value;
2110
- }
2111
-
2112
- if ( ($key = array_search($n, $cache[MATH_BIGINTEGER_VARIABLE])) === false ) {
2113
- $key = count($cache[MATH_BIGINTEGER_VARIABLE]);
2114
- $cache[MATH_BIGINTEGER_VARIABLE][] = $n;
2115
- $lhs = new Math_BigInteger();
2116
- $lhs_value = &$lhs->value;
2117
- $lhs_value = $this->_array_repeat(0, 2 * $n_length);
2118
- $lhs_value[] = 1;
2119
- $rhs = new Math_BigInteger();
2120
- $rhs->value = $n;
2121
- list($temp, ) = $lhs->divide($rhs); // m.length
2122
- $cache[MATH_BIGINTEGER_DATA][] = $temp->value;
2123
- }
2124
-
2125
- // 2 * m.length - (m.length - 1) = m.length + 1
2126
- $temp = array_slice($x, $n_length - 1);
2127
- // (m.length + 1) + m.length = 2 * m.length + 1
2128
- $temp = $this->_multiply($temp, false, $cache[MATH_BIGINTEGER_DATA][$key], false);
2129
- // (2 * m.length + 1) - (m.length - 1) = m.length + 2
2130
- $temp = array_slice($temp[MATH_BIGINTEGER_VALUE], $n_length + 1);
2131
-
2132
- // m.length + 1
2133
- $result = array_slice($x, 0, $n_length + 1);
2134
- // m.length + 1
2135
- $temp = $this->_multiplyLower($temp, false, $n, false, $n_length + 1);
2136
- // $temp == array_slice($temp->_multiply($temp, false, $n, false)->value, 0, $n_length + 1)
2137
-
2138
- if ($this->_compare($result, false, $temp[MATH_BIGINTEGER_VALUE], $temp[MATH_BIGINTEGER_SIGN]) < 0) {
2139
- $corrector_value = $this->_array_repeat(0, $n_length + 1);
2140
- $corrector_value[count($corrector_value)] = 1;
2141
- $result = $this->_add($result, false, $corrector_value, false);
2142
- $result = $result[MATH_BIGINTEGER_VALUE];
2143
- }
2144
-
2145
- // at this point, we're subtracting a number with m.length + 1 digits from another number with m.length + 1 digits
2146
- $result = $this->_subtract($result, false, $temp[MATH_BIGINTEGER_VALUE], $temp[MATH_BIGINTEGER_SIGN]);
2147
- while ($this->_compare($result[MATH_BIGINTEGER_VALUE], $result[MATH_BIGINTEGER_SIGN], $n, false) > 0) {
2148
- $result = $this->_subtract($result[MATH_BIGINTEGER_VALUE], $result[MATH_BIGINTEGER_SIGN], $n, false);
2149
- }
2150
-
2151
- return $result[MATH_BIGINTEGER_VALUE];
2152
- }
2153
-
2154
- /**
2155
- * Performs long multiplication up to $stop digits
2156
- *
2157
- * If you're going to be doing array_slice($product->value, 0, $stop), some cycles can be saved.
2158
- *
2159
- * @see _regularBarrett()
2160
- * @param Array $x_value
2161
- * @param Boolean $x_negative
2162
- * @param Array $y_value
2163
- * @param Boolean $y_negative
2164
- * @param Integer $stop
2165
- * @return Array
2166
- * @access private
2167
- */
2168
- function _multiplyLower($x_value, $x_negative, $y_value, $y_negative, $stop)
2169
- {
2170
- $x_length = count($x_value);
2171
- $y_length = count($y_value);
2172
-
2173
- if ( !$x_length || !$y_length ) { // a 0 is being multiplied
2174
- return array(
2175
- MATH_BIGINTEGER_VALUE => array(),
2176
- MATH_BIGINTEGER_SIGN => false
2177
- );
2178
- }
2179
-
2180
- if ( $x_length < $y_length ) {
2181
- $temp = $x_value;
2182
- $x_value = $y_value;
2183
- $y_value = $temp;
2184
-
2185
- $x_length = count($x_value);
2186
- $y_length = count($y_value);
2187
- }
2188
-
2189
- $product_value = $this->_array_repeat(0, $x_length + $y_length);
2190
-
2191
- // the following for loop could be removed if the for loop following it
2192
- // (the one with nested for loops) initially set $i to 0, but
2193
- // doing so would also make the result in one set of unnecessary adds,
2194
- // since on the outermost loops first pass, $product->value[$k] is going
2195
- // to always be 0
2196
-
2197
- $carry = 0;
2198
-
2199
- for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0, $k = $i
2200
- $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0
2201
- $carry = MATH_BIGINTEGER_BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
2202
- $product_value[$j] = (int) ($temp - MATH_BIGINTEGER_BASE_FULL * $carry);
2203
- }
2204
-
2205
- if ($j < $stop) {
2206
- $product_value[$j] = $carry;
2207
- }
2208
-
2209
- // the above for loop is what the previous comment was talking about. the
2210
- // following for loop is the "one with nested for loops"
2211
-
2212
- for ($i = 1; $i < $y_length; ++$i) {
2213
- $carry = 0;
2214
-
2215
- for ($j = 0, $k = $i; $j < $x_length && $k < $stop; ++$j, ++$k) {
2216
- $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry;
2217
- $carry = MATH_BIGINTEGER_BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
2218
- $product_value[$k] = (int) ($temp - MATH_BIGINTEGER_BASE_FULL * $carry);
2219
- }
2220
-
2221
- if ($k < $stop) {
2222
- $product_value[$k] = $carry;
2223
- }
2224
- }
2225
-
2226
- return array(
2227
- MATH_BIGINTEGER_VALUE => $this->_trim($product_value),
2228
- MATH_BIGINTEGER_SIGN => $x_negative != $y_negative
2229
- );
2230
- }
2231
-
2232
- /**
2233
- * Montgomery Modular Reduction
2234
- *
2235
- * ($x->_prepMontgomery($n))->_montgomery($n) yields $x % $n.
2236
- * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=170 MPM 6.3} provides insights on how this can be
2237
- * improved upon (basically, by using the comba method). gcd($n, 2) must be equal to one for this function
2238
- * to work correctly.
2239
- *
2240
- * @see _prepMontgomery()
2241
- * @see _slidingWindow()
2242
- * @access private
2243
- * @param Array $x
2244
- * @param Array $n
2245
- * @return Array
2246
- */
2247
- function _montgomery($x, $n)
2248
- {
2249
- static $cache = array(
2250
- MATH_BIGINTEGER_VARIABLE => array(),
2251
- MATH_BIGINTEGER_DATA => array()
2252
- );
2253
-
2254
- if ( ($key = array_search($n, $cache[MATH_BIGIN