]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - plugins/OStatus/extlib/Crypt/TripleDES.php
Merge branch '0.9.x' of git@gitorious.org:statusnet/mainline into 1.0.x
[quix0rs-gnu-social.git] / plugins / OStatus / extlib / Crypt / TripleDES.php
1 <?php
2 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
4 /**
5  * Pure-PHP implementation of Triple DES.
6  *
7  * Uses mcrypt, if available, and an internal implementation, otherwise.  Operates in the EDE3 mode (encrypt-decrypt-encrypt).
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/TripleDES.php');
15  *
16  *    $des = new Crypt_TripleDES();
17  *
18  *    $des->setKey('abcdefghijklmnopqrstuvwx');
19  *
20  *    $size = 10 * 1024;
21  *    $plaintext = '';
22  *    for ($i = 0; $i < $size; $i++) {
23  *        $plaintext.= 'a';
24  *    }
25  *
26  *    echo $des->decrypt($des->encrypt($plaintext));
27  * ?>
28  * </code>
29  *
30  * LICENSE: This library is free software; you can redistribute it and/or
31  * modify it under the terms of the GNU Lesser General Public
32  * License as published by the Free Software Foundation; either
33  * version 2.1 of the License, or (at your option) any later version.
34  *
35  * This library is distributed in the hope that it will be useful,
36  * but WITHOUT ANY WARRANTY; without even the implied warranty of
37  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
38  * Lesser General Public License for more details.
39  *
40  * You should have received a copy of the GNU Lesser General Public
41  * License along with this library; if not, write to the Free Software
42  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
43  * MA  02111-1307  USA
44  *
45  * @category   Crypt
46  * @package    Crypt_TripleDES
47  * @author     Jim Wigginton <terrafrost@php.net>
48  * @copyright  MMVII Jim Wigginton
49  * @license    http://www.gnu.org/licenses/lgpl.txt
50  * @version    $Id: TripleDES.php,v 1.13 2010/02/26 03:40:25 terrafrost Exp $
51  * @link       http://phpseclib.sourceforge.net
52  */
53
54 /**
55  * Include Crypt_DES
56  */
57 require_once 'DES.php';
58
59 /**
60  * Encrypt / decrypt using inner chaining
61  *
62  * Inner chaining is used by SSH-1 and is generally considered to be less secure then outer chaining (CRYPT_DES_MODE_CBC3).
63  */
64 define('CRYPT_DES_MODE_3CBC', 3);
65
66 /**
67  * Encrypt / decrypt using outer chaining
68  *
69  * Outer chaining is used by SSH-2 and when the mode is set to CRYPT_DES_MODE_CBC.
70  */
71 define('CRYPT_DES_MODE_CBC3', CRYPT_DES_MODE_CBC);
72
73 /**
74  * Pure-PHP implementation of Triple DES.
75  *
76  * @author  Jim Wigginton <terrafrost@php.net>
77  * @version 0.1.0
78  * @access  public
79  * @package Crypt_TerraDES
80  */
81 class Crypt_TripleDES {
82     /**
83      * The Three Keys
84      *
85      * @see Crypt_TripleDES::setKey()
86      * @var String
87      * @access private
88      */
89     var $key = "\0\0\0\0\0\0\0\0";
90
91     /**
92      * The Encryption Mode
93      *
94      * @see Crypt_TripleDES::Crypt_TripleDES()
95      * @var Integer
96      * @access private
97      */
98     var $mode = CRYPT_DES_MODE_CBC;
99
100     /**
101      * Continuous Buffer status
102      *
103      * @see Crypt_TripleDES::enableContinuousBuffer()
104      * @var Boolean
105      * @access private
106      */
107     var $continuousBuffer = false;
108
109     /**
110      * Padding status
111      *
112      * @see Crypt_TripleDES::enablePadding()
113      * @var Boolean
114      * @access private
115      */
116     var $padding = true;
117
118     /**
119      * The Initialization Vector
120      *
121      * @see Crypt_TripleDES::setIV()
122      * @var String
123      * @access private
124      */
125     var $iv = "\0\0\0\0\0\0\0\0";
126
127     /**
128      * A "sliding" Initialization Vector
129      *
130      * @see Crypt_TripleDES::enableContinuousBuffer()
131      * @var String
132      * @access private
133      */
134     var $encryptIV = "\0\0\0\0\0\0\0\0";
135
136     /**
137      * A "sliding" Initialization Vector
138      *
139      * @see Crypt_TripleDES::enableContinuousBuffer()
140      * @var String
141      * @access private
142      */
143     var $decryptIV = "\0\0\0\0\0\0\0\0";
144
145     /**
146      * The Crypt_DES objects
147      *
148      * @var Array
149      * @access private
150      */
151     var $des;
152
153     /**
154      * mcrypt resource for encryption
155      *
156      * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
157      * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
158      *
159      * @see Crypt_AES::encrypt()
160      * @var String
161      * @access private
162      */
163     var $enmcrypt;
164
165     /**
166      * mcrypt resource for decryption
167      *
168      * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
169      * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
170      *
171      * @see Crypt_AES::decrypt()
172      * @var String
173      * @access private
174      */
175     var $demcrypt;
176
177     /**
178      * Does the (en|de)mcrypt resource need to be (re)initialized?
179      *
180      * @see setKey()
181      * @see setIV()
182      * @var Boolean
183      * @access private
184      */
185     var $changed = true;
186
187     /**
188      * Default Constructor.
189      *
190      * Determines whether or not the mcrypt extension should be used.  $mode should only, at present, be
191      * CRYPT_DES_MODE_ECB or CRYPT_DES_MODE_CBC.  If not explictly set, CRYPT_DES_MODE_CBC will be used.
192      *
193      * @param optional Integer $mode
194      * @return Crypt_TripleDES
195      * @access public
196      */
197     function Crypt_TripleDES($mode = CRYPT_DES_MODE_CBC)
198     {
199         if ( !defined('CRYPT_DES_MODE') ) {
200             switch (true) {
201                 case extension_loaded('mcrypt'):
202                     // i'd check to see if des was supported, by doing in_array('des', mcrypt_list_algorithms('')),
203                     // but since that can be changed after the object has been created, there doesn't seem to be
204                     // a lot of point...
205                     define('CRYPT_DES_MODE', CRYPT_DES_MODE_MCRYPT);
206                     break;
207                 default:
208                     define('CRYPT_DES_MODE', CRYPT_DES_MODE_INTERNAL);
209             }
210         }
211
212         if ( $mode == CRYPT_DES_MODE_3CBC ) {
213             $this->mode = CRYPT_DES_MODE_3CBC;
214             $this->des = array(
215                 new Crypt_DES(CRYPT_DES_MODE_CBC),
216                 new Crypt_DES(CRYPT_DES_MODE_CBC),
217                 new Crypt_DES(CRYPT_DES_MODE_CBC)
218             );
219
220             // we're going to be doing the padding, ourselves, so disable it in the Crypt_DES objects
221             $this->des[0]->disablePadding();
222             $this->des[1]->disablePadding();
223             $this->des[2]->disablePadding();
224
225             return;
226         }
227
228         switch ( CRYPT_DES_MODE ) {
229             case CRYPT_DES_MODE_MCRYPT:
230                 switch ($mode) {
231                     case CRYPT_DES_MODE_ECB:
232                         $this->mode = MCRYPT_MODE_ECB;
233                         break;
234                     case CRYPT_DES_MODE_CTR:
235                         $this->mode = 'ctr';
236                         break;
237                     case CRYPT_DES_MODE_CBC:
238                     default:
239                         $this->mode = MCRYPT_MODE_CBC;
240                 }
241
242                 break;
243             default:
244                 $this->des = array(
245                     new Crypt_DES(CRYPT_DES_MODE_ECB),
246                     new Crypt_DES(CRYPT_DES_MODE_ECB),
247                     new Crypt_DES(CRYPT_DES_MODE_ECB)
248                 );
249  
250                 // we're going to be doing the padding, ourselves, so disable it in the Crypt_DES objects
251                 $this->des[0]->disablePadding();
252                 $this->des[1]->disablePadding();
253                 $this->des[2]->disablePadding();
254
255                 switch ($mode) {
256                     case CRYPT_DES_MODE_ECB:
257                     case CRYPT_DES_MODE_CTR:
258                     case CRYPT_DES_MODE_CBC:
259                         $this->mode = $mode;
260                         break;
261                     default:
262                         $this->mode = CRYPT_DES_MODE_CBC;
263                 }
264         }
265     }
266
267     /**
268      * Sets the key.
269      *
270      * Keys can be of any length.  Triple DES, itself, can use 128-bit (eg. strlen($key) == 16) or
271      * 192-bit (eg. strlen($key) == 24) keys.  This function pads and truncates $key as appropriate.
272      *
273      * DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
274      *
275      * If the key is not explicitly set, it'll be assumed to be all zero's.
276      *
277      * @access public
278      * @param String $key
279      */
280     function setKey($key)
281     {
282         $length = strlen($key);
283         if ($length > 8) {
284             $key = str_pad($key, 24, chr(0));
285             // if $key is between 64 and 128-bits, use the first 64-bits as the last, per this:
286             // http://php.net/function.mcrypt-encrypt#47973
287             //$key = $length <= 16 ? substr_replace($key, substr($key, 0, 8), 16) : substr($key, 0, 24);
288         }
289         $this->key = $key;
290         switch (true) {
291             case CRYPT_DES_MODE == CRYPT_DES_MODE_INTERNAL:
292             case $this->mode == CRYPT_DES_MODE_3CBC:
293                 $this->des[0]->setKey(substr($key,  0, 8));
294                 $this->des[1]->setKey(substr($key,  8, 8));
295                 $this->des[2]->setKey(substr($key, 16, 8));
296         }
297         $this->changed = true;
298     }
299
300     /**
301      * Sets the initialization vector. (optional)
302      *
303      * SetIV is not required when CRYPT_DES_MODE_ECB is being used.  If not explictly set, it'll be assumed
304      * to be all zero's.
305      *
306      * @access public
307      * @param String $iv
308      */
309     function setIV($iv)
310     {
311         $this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($iv, 0, 8), 8, chr(0));
312         if ($this->mode == CRYPT_DES_MODE_3CBC) {
313             $this->des[0]->setIV($iv);
314             $this->des[1]->setIV($iv);
315             $this->des[2]->setIV($iv);
316         }
317         $this->changed = true;
318     }
319
320     /**
321      * Generate CTR XOR encryption key
322      *
323      * Encrypt the output of this and XOR it against the ciphertext / plaintext to get the
324      * plaintext / ciphertext in CTR mode.
325      *
326      * @see Crypt_DES::decrypt()
327      * @see Crypt_DES::encrypt()
328      * @access public
329      * @param Integer $length
330      * @param String $iv
331      */
332     function _generate_xor($length, &$iv)
333     {
334         $xor = '';
335         $num_blocks = ($length + 7) >> 3;
336         for ($i = 0; $i < $num_blocks; $i++) {
337             $xor.= $iv;
338             for ($j = 4; $j <= 8; $j+=4) {
339                 $temp = substr($iv, -$j, 4);
340                 switch ($temp) {
341                     case "\xFF\xFF\xFF\xFF":
342                         $iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4);
343                         break;
344                     case "\x7F\xFF\xFF\xFF":
345                         $iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4);
346                         break 2;
347                     default:
348                         extract(unpack('Ncount', $temp));
349                         $iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);
350                         break 2;
351                 }
352             }
353         }
354
355         return $xor;
356     }
357
358     /**
359      * Encrypts a message.
360      *
361      * @access public
362      * @param String $plaintext
363      */
364     function encrypt($plaintext)
365     {
366         if ($this->mode != CRYPT_DES_MODE_CTR && $this->mode != 'ctr') {
367             $plaintext = $this->_pad($plaintext);
368         }
369
370         // if the key is smaller then 8, do what we'd normally do
371         if ($this->mode == CRYPT_DES_MODE_3CBC && strlen($this->key) > 8) {
372             $ciphertext = $this->des[2]->encrypt($this->des[1]->decrypt($this->des[0]->encrypt($plaintext)));
373
374             return $ciphertext;
375         }
376
377         if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
378             if ($this->changed) {
379                 if (!isset($this->enmcrypt)) {
380                     $this->enmcrypt = mcrypt_module_open(MCRYPT_3DES, '', $this->mode, '');
381                 }
382                 mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
383                 $this->changed = false;
384             }
385
386             $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
387
388             if (!$this->continuousBuffer) {
389                 mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
390             }
391
392             return $ciphertext;
393         }
394
395         if (strlen($this->key) <= 8) {
396             $this->des[0]->mode = $this->mode;
397
398             return $this->des[0]->encrypt($plaintext);
399         }
400
401         // we pad with chr(0) since that's what mcrypt_generic does.  to quote from http://php.net/function.mcrypt-generic :
402         // "The data is padded with "\0" to make sure the length of the data is n * blocksize."
403         $plaintext = str_pad($plaintext, ceil(strlen($plaintext) / 8) * 8, chr(0));
404
405         $des = $this->des;
406
407         $ciphertext = '';
408         switch ($this->mode) {
409             case CRYPT_DES_MODE_ECB:
410                 for ($i = 0; $i < strlen($plaintext); $i+=8) {
411                     $block = substr($plaintext, $i, 8);
412                     $block = $des[0]->_processBlock($block, CRYPT_DES_ENCRYPT);
413                     $block = $des[1]->_processBlock($block, CRYPT_DES_DECRYPT);
414                     $block = $des[2]->_processBlock($block, CRYPT_DES_ENCRYPT);
415                     $ciphertext.= $block;
416                 }
417                 break;
418             case CRYPT_DES_MODE_CBC:
419                 $xor = $this->encryptIV;
420                 for ($i = 0; $i < strlen($plaintext); $i+=8) {
421                     $block = substr($plaintext, $i, 8) ^ $xor;
422                     $block = $des[0]->_processBlock($block, CRYPT_DES_ENCRYPT);
423                     $block = $des[1]->_processBlock($block, CRYPT_DES_DECRYPT);
424                     $block = $des[2]->_processBlock($block, CRYPT_DES_ENCRYPT);
425                     $xor = $block;
426                     $ciphertext.= $block;
427                 }
428                 if ($this->continuousBuffer) {
429                     $this->encryptIV = $xor;
430                 }
431                 break;
432             case CRYPT_DES_MODE_CTR:
433                 $xor = $this->encryptIV;
434                 for ($i = 0; $i < strlen($plaintext); $i+=8) {
435                     $key = $this->_generate_xor(8, $xor);
436                     $key = $des[0]->_processBlock($key, CRYPT_DES_ENCRYPT);
437                     $key = $des[1]->_processBlock($key, CRYPT_DES_DECRYPT);
438                     $key = $des[2]->_processBlock($key, CRYPT_DES_ENCRYPT);
439                     $block = substr($plaintext, $i, 8);
440                     $ciphertext.= $block ^ $key;
441                 }
442                 if ($this->continuousBuffer) {
443                     $this->encryptIV = $xor;
444                 }
445         }
446
447         return $ciphertext;
448     }
449
450     /**
451      * Decrypts a message.
452      *
453      * @access public
454      * @param String $ciphertext
455      */
456     function decrypt($ciphertext)
457     {
458         if ($this->mode == CRYPT_DES_MODE_3CBC && strlen($this->key) > 8) {
459             $plaintext = $this->des[0]->decrypt($this->des[1]->encrypt($this->des[2]->decrypt($ciphertext)));
460
461             return $this->_unpad($plaintext);
462         }
463
464         // we pad with chr(0) since that's what mcrypt_generic does.  to quote from http://php.net/function.mcrypt-generic :
465         // "The data is padded with "\0" to make sure the length of the data is n * blocksize."
466         $ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, chr(0));
467
468         if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
469             if ($this->changed) {
470                 if (!isset($this->demcrypt)) {
471                     $this->demcrypt = mcrypt_module_open(MCRYPT_3DES, '', $this->mode, '');
472                 }
473                 mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
474                 $this->changed = false;
475             }
476
477             $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
478
479             if (!$this->continuousBuffer) {
480                 mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
481             }
482
483             return $this->mode != 'ctr' ? $this->_unpad($plaintext) : $plaintext;
484         }
485
486         if (strlen($this->key) <= 8) {
487             $this->des[0]->mode = $this->mode;
488
489             return $this->_unpad($this->des[0]->decrypt($plaintext));
490         }
491
492         $des = $this->des;
493
494         $plaintext = '';
495         switch ($this->mode) {
496             case CRYPT_DES_MODE_ECB:
497                 for ($i = 0; $i < strlen($ciphertext); $i+=8) {
498                     $block = substr($ciphertext, $i, 8);
499                     $block = $des[2]->_processBlock($block, CRYPT_DES_DECRYPT);
500                     $block = $des[1]->_processBlock($block, CRYPT_DES_ENCRYPT);
501                     $block = $des[0]->_processBlock($block, CRYPT_DES_DECRYPT);
502                     $plaintext.= $block;
503                 }
504                 break;
505             case CRYPT_DES_MODE_CBC:
506                 $xor = $this->decryptIV;
507                 for ($i = 0; $i < strlen($ciphertext); $i+=8) {
508                     $orig = $block = substr($ciphertext, $i, 8);
509                     $block = $des[2]->_processBlock($block, CRYPT_DES_DECRYPT);
510                     $block = $des[1]->_processBlock($block, CRYPT_DES_ENCRYPT);
511                     $block = $des[0]->_processBlock($block, CRYPT_DES_DECRYPT);
512                     $plaintext.= $block ^ $xor;
513                     $xor = $orig;
514                 }
515                 if ($this->continuousBuffer) {
516                     $this->decryptIV = $xor;
517                 }
518                 break;
519             case CRYPT_DES_MODE_CTR:
520                 $xor = $this->decryptIV;
521                 for ($i = 0; $i < strlen($ciphertext); $i+=8) {
522                     $key = $this->_generate_xor(8, $xor);
523                     $key = $des[0]->_processBlock($key, CRYPT_DES_ENCRYPT);
524                     $key = $des[1]->_processBlock($key, CRYPT_DES_DECRYPT);
525                     $key = $des[2]->_processBlock($key, CRYPT_DES_ENCRYPT);
526                     $block = substr($ciphertext, $i, 8);
527                     $plaintext.= $block ^ $key;
528                 }
529                 if ($this->continuousBuffer) {
530                     $this->decryptIV = $xor;
531                 }
532         }
533
534         return $this->mode != CRYPT_DES_MODE_CTR ? $this->_unpad($plaintext) : $plaintext;
535     }
536
537     /**
538      * Treat consecutive "packets" as if they are a continuous buffer.
539      *
540      * Say you have a 16-byte plaintext $plaintext.  Using the default behavior, the two following code snippets
541      * will yield different outputs:
542      *
543      * <code>
544      *    echo $des->encrypt(substr($plaintext, 0, 8));
545      *    echo $des->encrypt(substr($plaintext, 8, 8));
546      * </code>
547      * <code>
548      *    echo $des->encrypt($plaintext);
549      * </code>
550      *
551      * The solution is to enable the continuous buffer.  Although this will resolve the above discrepancy, it creates
552      * another, as demonstrated with the following:
553      *
554      * <code>
555      *    $des->encrypt(substr($plaintext, 0, 8));
556      *    echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
557      * </code>
558      * <code>
559      *    echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
560      * </code>
561      *
562      * With the continuous buffer disabled, these would yield the same output.  With it enabled, they yield different
563      * outputs.  The reason is due to the fact that the initialization vector's change after every encryption /
564      * decryption round when the continuous buffer is enabled.  When it's disabled, they remain constant.
565      *
566      * Put another way, when the continuous buffer is enabled, the state of the Crypt_DES() object changes after each
567      * encryption / decryption round, whereas otherwise, it'd remain constant.  For this reason, it's recommended that
568      * continuous buffers not be used.  They do offer better security and are, in fact, sometimes required (SSH uses them),
569      * however, they are also less intuitive and more likely to cause you problems.
570      *
571      * @see Crypt_TripleDES::disableContinuousBuffer()
572      * @access public
573      */
574     function enableContinuousBuffer()
575     {
576         $this->continuousBuffer = true;
577         if ($this->mode == CRYPT_DES_MODE_3CBC) {
578             $this->des[0]->enableContinuousBuffer();
579             $this->des[1]->enableContinuousBuffer();
580             $this->des[2]->enableContinuousBuffer();
581         }
582     }
583
584     /**
585      * Treat consecutive packets as if they are a discontinuous buffer.
586      *
587      * The default behavior.
588      *
589      * @see Crypt_TripleDES::enableContinuousBuffer()
590      * @access public
591      */
592     function disableContinuousBuffer()
593     {
594         $this->continuousBuffer = false;
595         $this->encryptIV = $this->iv;
596         $this->decryptIV = $this->iv;
597
598         if ($this->mode == CRYPT_DES_MODE_3CBC) {
599             $this->des[0]->disableContinuousBuffer();
600             $this->des[1]->disableContinuousBuffer();
601             $this->des[2]->disableContinuousBuffer();
602         }
603     }
604
605     /**
606      * Pad "packets".
607      *
608      * DES works by encrypting eight bytes at a time.  If you ever need to encrypt or decrypt something that's not
609      * a multiple of eight, it becomes necessary to pad the input so that it's length is a multiple of eight.
610      *
611      * Padding is enabled by default.  Sometimes, however, it is undesirable to pad strings.  Such is the case in SSH1,
612      * where "packets" are padded with random bytes before being encrypted.  Unpad these packets and you risk stripping
613      * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is
614      * transmitted separately)
615      *
616      * @see Crypt_TripleDES::disablePadding()
617      * @access public
618      */
619     function enablePadding()
620     {
621         $this->padding = true;
622     }
623
624     /**
625      * Do not pad packets.
626      *
627      * @see Crypt_TripleDES::enablePadding()
628      * @access public
629      */
630     function disablePadding()
631     {
632         $this->padding = false;
633     }
634
635     /**
636      * Pads a string
637      *
638      * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize (8).
639      * 8 - (strlen($text) & 7) bytes are added, each of which is equal to chr(8 - (strlen($text) & 7)
640      *
641      * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless
642      * and padding will, hence forth, be enabled.
643      *
644      * @see Crypt_TripleDES::_unpad()
645      * @access private
646      */
647     function _pad($text)
648     {
649         $length = strlen($text);
650
651         if (!$this->padding) {
652             if (($length & 7) == 0) {
653                 return $text;
654             } else {
655                 user_error("The plaintext's length ($length) is not a multiple of the block size (8)", E_USER_NOTICE);
656                 $this->padding = true;
657             }
658         }
659
660         $pad = 8 - ($length & 7);
661         return str_pad($text, $length + $pad, chr($pad));
662     }
663
664     /**
665      * Unpads a string
666      *
667      * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong
668      * and false will be returned.
669      *
670      * @see Crypt_TripleDES::_pad()
671      * @access private
672      */
673     function _unpad($text)
674     {
675         if (!$this->padding) {
676             return $text;
677         }
678
679         $length = ord($text[strlen($text) - 1]);
680
681         if (!$length || $length > 8) {
682             return false;
683         }
684
685         return substr($text, 0, -$length);
686     }
687 }
688
689 // vim: ts=4:sw=4:et:
690 // vim6: fdl=1: