PageRenderTime 29ms CodeModel.GetById 2ms app.highlight 21ms RepoModel.GetById 1ms app.codeStats 1ms

/protdocs/includes/statusnet/statusnet-0.9.6/plugins/OStatus/extlib/Crypt/TripleDES.php

https://gitlab.com/intersango/witcoin
PHP | 690 lines | 331 code | 59 blank | 300 comment | 60 complexity | 131661743e97ec23a75624821ea628a4 MD5 | raw file
  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 */
 57require_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 */
 64define('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 */
 71define('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 */
 81class 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: