Subversion Repositories oidplus

Rev

Rev 846 | Rev 1042 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. <?php
  2.  
  3. /**
  4.  * Pure-PHP implementation of RC2.
  5.  *
  6.  * Uses mcrypt, if available, and an internal implementation, otherwise.
  7.  *
  8.  * PHP version 5
  9.  *
  10.  * Useful resources are as follows:
  11.  *
  12.  *  - {@link http://tools.ietf.org/html/rfc2268}
  13.  *
  14.  * Here's a short example of how to use this library:
  15.  * <code>
  16.  * <?php
  17.  *    include 'vendor/autoload.php';
  18.  *
  19.  *    $rc2 = new \phpseclib3\Crypt\RC2('ctr');
  20.  *
  21.  *    $rc2->setKey('abcdefgh');
  22.  *
  23.  *    $plaintext = str_repeat('a', 1024);
  24.  *
  25.  *    echo $rc2->decrypt($rc2->encrypt($plaintext));
  26.  * ?>
  27.  * </code>
  28.  *
  29.  * @category Crypt
  30.  * @package  RC2
  31.  * @author   Patrick Monnerat <pm@datasphere.ch>
  32.  * @license  http://www.opensource.org/licenses/mit-license.html  MIT License
  33.  * @link     http://phpseclib.sourceforge.net
  34.  */
  35.  
  36. namespace phpseclib3\Crypt;
  37.  
  38. use phpseclib3\Crypt\Common\BlockCipher;
  39. use phpseclib3\Exception\BadModeException;
  40.  
  41. /**
  42.  * Pure-PHP implementation of RC2.
  43.  *
  44.  * @package RC2
  45.  * @access  public
  46.  */
  47. class RC2 extends BlockCipher
  48. {
  49.     /**
  50.      * Block Length of the cipher
  51.      *
  52.      * @see \phpseclib3\Crypt\Common\SymmetricKey::block_size
  53.      * @var int
  54.      * @access private
  55.      */
  56.     protected $block_size = 8;
  57.  
  58.     /**
  59.      * The Key
  60.      *
  61.      * @see \phpseclib3\Crypt\Common\SymmetricKey::key
  62.      * @see self::setKey()
  63.      * @var string
  64.      * @access private
  65.      */
  66.     protected $key;
  67.  
  68.     /**
  69.      * The Original (unpadded) Key
  70.      *
  71.      * @see \phpseclib3\Crypt\Common\SymmetricKey::key
  72.      * @see self::setKey()
  73.      * @see self::encrypt()
  74.      * @see self::decrypt()
  75.      * @var string
  76.      * @access private
  77.      */
  78.     private $orig_key;
  79.  
  80.     /**
  81.      * Don't truncate / null pad key
  82.      *
  83.      * @see \phpseclib3\Crypt\Common\SymmetricKey::clearBuffers()
  84.      * @var bool
  85.      * @access private
  86.      */
  87.     private $skip_key_adjustment = true;
  88.  
  89.     /**
  90.      * Key Length (in bytes)
  91.      *
  92.      * @see \phpseclib3\Crypt\RC2::setKeyLength()
  93.      * @var int
  94.      * @access private
  95.      */
  96.     protected $key_length = 16; // = 128 bits
  97.  
  98.     /**
  99.      * The mcrypt specific name of the cipher
  100.      *
  101.      * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt
  102.      * @var string
  103.      * @access private
  104.      */
  105.     protected $cipher_name_mcrypt = 'rc2';
  106.  
  107.     /**
  108.      * Optimizing value while CFB-encrypting
  109.      *
  110.      * @see \phpseclib3\Crypt\Common\SymmetricKey::cfb_init_len
  111.      * @var int
  112.      * @access private
  113.      */
  114.     protected $cfb_init_len = 500;
  115.  
  116.     /**
  117.      * The key length in bits.
  118.      *
  119.      * {@internal Should be in range [1..1024].}
  120.      *
  121.      * {@internal Changing this value after setting the key has no effect.}
  122.      *
  123.      * @see self::setKeyLength()
  124.      * @see self::setKey()
  125.      * @var int
  126.      * @access private
  127.      */
  128.     private $default_key_length = 1024;
  129.  
  130.     /**
  131.      * The key length in bits.
  132.      *
  133.      * {@internal Should be in range [1..1024].}
  134.      *
  135.      * @see self::isValidEnine()
  136.      * @see self::setKey()
  137.      * @var int
  138.      * @access private
  139.      */
  140.     private $current_key_length;
  141.  
  142.     /**
  143.      * The Key Schedule
  144.      *
  145.      * @see self::setupKey()
  146.      * @var array
  147.      * @access private
  148.      */
  149.     private $keys;
  150.  
  151.     /**
  152.      * Key expansion randomization table.
  153.      * Twice the same 256-value sequence to save a modulus in key expansion.
  154.      *
  155.      * @see self::setKey()
  156.      * @var array
  157.      * @access private
  158.      */
  159.     private static $pitable = [
  160.         0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED,
  161.         0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D,
  162.         0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E,
  163.         0x62, 0x4C, 0x64, 0x88, 0x44, 0x8B, 0xFB, 0xA2,
  164.         0x17, 0x9A, 0x59, 0xF5, 0x87, 0xB3, 0x4F, 0x13,
  165.         0x61, 0x45, 0x6D, 0x8D, 0x09, 0x81, 0x7D, 0x32,
  166.         0xBD, 0x8F, 0x40, 0xEB, 0x86, 0xB7, 0x7B, 0x0B,
  167.         0xF0, 0x95, 0x21, 0x22, 0x5C, 0x6B, 0x4E, 0x82,
  168.         0x54, 0xD6, 0x65, 0x93, 0xCE, 0x60, 0xB2, 0x1C,
  169.         0x73, 0x56, 0xC0, 0x14, 0xA7, 0x8C, 0xF1, 0xDC,
  170.         0x12, 0x75, 0xCA, 0x1F, 0x3B, 0xBE, 0xE4, 0xD1,
  171.         0x42, 0x3D, 0xD4, 0x30, 0xA3, 0x3C, 0xB6, 0x26,
  172.         0x6F, 0xBF, 0x0E, 0xDA, 0x46, 0x69, 0x07, 0x57,
  173.         0x27, 0xF2, 0x1D, 0x9B, 0xBC, 0x94, 0x43, 0x03,
  174.         0xF8, 0x11, 0xC7, 0xF6, 0x90, 0xEF, 0x3E, 0xE7,
  175.         0x06, 0xC3, 0xD5, 0x2F, 0xC8, 0x66, 0x1E, 0xD7,
  176.         0x08, 0xE8, 0xEA, 0xDE, 0x80, 0x52, 0xEE, 0xF7,
  177.         0x84, 0xAA, 0x72, 0xAC, 0x35, 0x4D, 0x6A, 0x2A,
  178.         0x96, 0x1A, 0xD2, 0x71, 0x5A, 0x15, 0x49, 0x74,
  179.         0x4B, 0x9F, 0xD0, 0x5E, 0x04, 0x18, 0xA4, 0xEC,
  180.         0xC2, 0xE0, 0x41, 0x6E, 0x0F, 0x51, 0xCB, 0xCC,
  181.         0x24, 0x91, 0xAF, 0x50, 0xA1, 0xF4, 0x70, 0x39,
  182.         0x99, 0x7C, 0x3A, 0x85, 0x23, 0xB8, 0xB4, 0x7A,
  183.         0xFC, 0x02, 0x36, 0x5B, 0x25, 0x55, 0x97, 0x31,
  184.         0x2D, 0x5D, 0xFA, 0x98, 0xE3, 0x8A, 0x92, 0xAE,
  185.         0x05, 0xDF, 0x29, 0x10, 0x67, 0x6C, 0xBA, 0xC9,
  186.         0xD3, 0x00, 0xE6, 0xCF, 0xE1, 0x9E, 0xA8, 0x2C,
  187.         0x63, 0x16, 0x01, 0x3F, 0x58, 0xE2, 0x89, 0xA9,
  188.         0x0D, 0x38, 0x34, 0x1B, 0xAB, 0x33, 0xFF, 0xB0,
  189.         0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E,
  190.         0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77,
  191.         0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD,
  192.         0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED,
  193.         0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D,
  194.         0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E,
  195.         0x62, 0x4C, 0x64, 0x88, 0x44, 0x8B, 0xFB, 0xA2,
  196.         0x17, 0x9A, 0x59, 0xF5, 0x87, 0xB3, 0x4F, 0x13,
  197.         0x61, 0x45, 0x6D, 0x8D, 0x09, 0x81, 0x7D, 0x32,
  198.         0xBD, 0x8F, 0x40, 0xEB, 0x86, 0xB7, 0x7B, 0x0B,
  199.         0xF0, 0x95, 0x21, 0x22, 0x5C, 0x6B, 0x4E, 0x82,
  200.         0x54, 0xD6, 0x65, 0x93, 0xCE, 0x60, 0xB2, 0x1C,
  201.         0x73, 0x56, 0xC0, 0x14, 0xA7, 0x8C, 0xF1, 0xDC,
  202.         0x12, 0x75, 0xCA, 0x1F, 0x3B, 0xBE, 0xE4, 0xD1,
  203.         0x42, 0x3D, 0xD4, 0x30, 0xA3, 0x3C, 0xB6, 0x26,
  204.         0x6F, 0xBF, 0x0E, 0xDA, 0x46, 0x69, 0x07, 0x57,
  205.         0x27, 0xF2, 0x1D, 0x9B, 0xBC, 0x94, 0x43, 0x03,
  206.         0xF8, 0x11, 0xC7, 0xF6, 0x90, 0xEF, 0x3E, 0xE7,
  207.         0x06, 0xC3, 0xD5, 0x2F, 0xC8, 0x66, 0x1E, 0xD7,
  208.         0x08, 0xE8, 0xEA, 0xDE, 0x80, 0x52, 0xEE, 0xF7,
  209.         0x84, 0xAA, 0x72, 0xAC, 0x35, 0x4D, 0x6A, 0x2A,
  210.         0x96, 0x1A, 0xD2, 0x71, 0x5A, 0x15, 0x49, 0x74,
  211.         0x4B, 0x9F, 0xD0, 0x5E, 0x04, 0x18, 0xA4, 0xEC,
  212.         0xC2, 0xE0, 0x41, 0x6E, 0x0F, 0x51, 0xCB, 0xCC,
  213.         0x24, 0x91, 0xAF, 0x50, 0xA1, 0xF4, 0x70, 0x39,
  214.         0x99, 0x7C, 0x3A, 0x85, 0x23, 0xB8, 0xB4, 0x7A,
  215.         0xFC, 0x02, 0x36, 0x5B, 0x25, 0x55, 0x97, 0x31,
  216.         0x2D, 0x5D, 0xFA, 0x98, 0xE3, 0x8A, 0x92, 0xAE,
  217.         0x05, 0xDF, 0x29, 0x10, 0x67, 0x6C, 0xBA, 0xC9,
  218.         0xD3, 0x00, 0xE6, 0xCF, 0xE1, 0x9E, 0xA8, 0x2C,
  219.         0x63, 0x16, 0x01, 0x3F, 0x58, 0xE2, 0x89, 0xA9,
  220.         0x0D, 0x38, 0x34, 0x1B, 0xAB, 0x33, 0xFF, 0xB0,
  221.         0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E,
  222.         0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77,
  223.         0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD
  224.     ];
  225.  
  226.     /**
  227.      * Inverse key expansion randomization table.
  228.      *
  229.      * @see self::setKey()
  230.      * @var array
  231.      * @access private
  232.      */
  233.     private static $invpitable = [
  234.         0xD1, 0xDA, 0xB9, 0x6F, 0x9C, 0xC8, 0x78, 0x66,
  235.         0x80, 0x2C, 0xF8, 0x37, 0xEA, 0xE0, 0x62, 0xA4,
  236.         0xCB, 0x71, 0x50, 0x27, 0x4B, 0x95, 0xD9, 0x20,
  237.         0x9D, 0x04, 0x91, 0xE3, 0x47, 0x6A, 0x7E, 0x53,
  238.         0xFA, 0x3A, 0x3B, 0xB4, 0xA8, 0xBC, 0x5F, 0x68,
  239.         0x08, 0xCA, 0x8F, 0x14, 0xD7, 0xC0, 0xEF, 0x7B,
  240.         0x5B, 0xBF, 0x2F, 0xE5, 0xE2, 0x8C, 0xBA, 0x12,
  241.         0xE1, 0xAF, 0xB2, 0x54, 0x5D, 0x59, 0x76, 0xDB,
  242.         0x32, 0xA2, 0x58, 0x6E, 0x1C, 0x29, 0x64, 0xF3,
  243.         0xE9, 0x96, 0x0C, 0x98, 0x19, 0x8D, 0x3E, 0x26,
  244.         0xAB, 0xA5, 0x85, 0x16, 0x40, 0xBD, 0x49, 0x67,
  245.         0xDC, 0x22, 0x94, 0xBB, 0x3C, 0xC1, 0x9B, 0xEB,
  246.         0x45, 0x28, 0x18, 0xD8, 0x1A, 0x42, 0x7D, 0xCC,
  247.         0xFB, 0x65, 0x8E, 0x3D, 0xCD, 0x2A, 0xA3, 0x60,
  248.         0xAE, 0x93, 0x8A, 0x48, 0x97, 0x51, 0x15, 0xF7,
  249.         0x01, 0x0B, 0xB7, 0x36, 0xB1, 0x2E, 0x11, 0xFD,
  250.         0x84, 0x2D, 0x3F, 0x13, 0x88, 0xB3, 0x34, 0x24,
  251.         0x1B, 0xDE, 0xC5, 0x1D, 0x4D, 0x2B, 0x17, 0x31,
  252.         0x74, 0xA9, 0xC6, 0x43, 0x6D, 0x39, 0x90, 0xBE,
  253.         0xC3, 0xB0, 0x21, 0x6B, 0xF6, 0x0F, 0xD5, 0x99,
  254.         0x0D, 0xAC, 0x1F, 0x5C, 0x9E, 0xF5, 0xF9, 0x4C,
  255.         0xD6, 0xDF, 0x89, 0xE4, 0x8B, 0xFF, 0xC7, 0xAA,
  256.         0xE7, 0xED, 0x46, 0x25, 0xB6, 0x06, 0x5E, 0x35,
  257.         0xB5, 0xEC, 0xCE, 0xE8, 0x6C, 0x30, 0x55, 0x61,
  258.         0x4A, 0xFE, 0xA0, 0x79, 0x03, 0xF0, 0x10, 0x72,
  259.         0x7C, 0xCF, 0x52, 0xA6, 0xA7, 0xEE, 0x44, 0xD3,
  260.         0x9A, 0x57, 0x92, 0xD0, 0x5A, 0x7A, 0x41, 0x7F,
  261.         0x0E, 0x00, 0x63, 0xF2, 0x4F, 0x05, 0x83, 0xC9,
  262.         0xA1, 0xD4, 0xDD, 0xC4, 0x56, 0xF4, 0xD2, 0x77,
  263.         0x81, 0x09, 0x82, 0x33, 0x9F, 0x07, 0x86, 0x75,
  264.         0x38, 0x4E, 0x69, 0xF1, 0xAD, 0x23, 0x73, 0x87,
  265.         0x70, 0x02, 0xC2, 0x1E, 0xB8, 0x0A, 0xFC, 0xE6
  266.     ];
  267.  
  268.     /**
  269.      * Default Constructor.
  270.      *
  271.      * @param string $mode
  272.      * @access public
  273.      * @throws \InvalidArgumentException if an invalid / unsupported mode is provided
  274.      */
  275.     public function __construct($mode)
  276.     {
  277.         parent::__construct($mode);
  278.  
  279.         if ($this->mode == self::MODE_STREAM) {
  280.             throw new BadModeException('Block ciphers cannot be ran in stream mode');
  281.         }
  282.     }
  283.  
  284.     /**
  285.      * Test for engine validity
  286.      *
  287.      * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine()
  288.      *
  289.      * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct()
  290.      * @param int $engine
  291.      * @access protected
  292.      * @return bool
  293.      */
  294.     protected function isValidEngineHelper($engine)
  295.     {
  296.         switch ($engine) {
  297.             case self::ENGINE_OPENSSL:
  298.                 if ($this->current_key_length != 128 || strlen($this->orig_key) < 16) {
  299.                     return false;
  300.                 }
  301.                 $this->cipher_name_openssl_ecb = 'rc2-ecb';
  302.                 $this->cipher_name_openssl = 'rc2-' . $this->openssl_translate_mode();
  303.         }
  304.  
  305.         return parent::isValidEngineHelper($engine);
  306.     }
  307.  
  308.     /**
  309.      * Sets the key length.
  310.      *
  311.      * Valid key lengths are 8 to 1024.
  312.      * Calling this function after setting the key has no effect until the next
  313.      *  \phpseclib3\Crypt\RC2::setKey() call.
  314.      *
  315.      * @access public
  316.      * @param int $length in bits
  317.      * @throws \LengthException if the key length isn't supported
  318.      */
  319.     public function setKeyLength($length)
  320.     {
  321.         if ($length < 8 || $length > 1024) {
  322.             throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 1024 bits, inclusive, are supported');
  323.         }
  324.  
  325.         $this->default_key_length = $this->current_key_length = $length;
  326.         $this->explicit_key_length = $length >> 3;
  327.     }
  328.  
  329.     /**
  330.      * Returns the current key length
  331.      *
  332.      * @access public
  333.      * @return int
  334.      */
  335.     public function getKeyLength()
  336.     {
  337.         return $this->current_key_length;
  338.     }
  339.  
  340.     /**
  341.      * Sets the key.
  342.      *
  343.      * Keys can be of any length. RC2, itself, uses 8 to 1024 bit keys (eg.
  344.      * strlen($key) <= 128), however, we only use the first 128 bytes if $key
  345.      * has more then 128 bytes in it, and set $key to a single null byte if
  346.      * it is empty.
  347.      *
  348.      * @see \phpseclib3\Crypt\Common\SymmetricKey::setKey()
  349.      * @access public
  350.      * @param string $key
  351.      * @param int|boolean $t1 optional Effective key length in bits.
  352.      * @throws \LengthException if the key length isn't supported
  353.      */
  354.     public function setKey($key, $t1 = false)
  355.     {
  356.         $this->orig_key = $key;
  357.  
  358.         if ($t1 === false) {
  359.             $t1 = $this->default_key_length;
  360.         }
  361.  
  362.         if ($t1 < 1 || $t1 > 1024) {
  363.             throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 1024 bits, inclusive, are supported');
  364.         }
  365.  
  366.         $this->current_key_length = $t1;
  367.         if (strlen($key) < 1 || strlen($key) > 128) {
  368.             throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes between 8 and 1024 bits, inclusive, are supported');
  369.         }
  370.  
  371.         $t = strlen($key);
  372.  
  373.         // The mcrypt RC2 implementation only supports effective key length
  374.         // of 1024 bits. It is however possible to handle effective key
  375.         // lengths in range 1..1024 by expanding the key and applying
  376.         // inverse pitable mapping to the first byte before submitting it
  377.         // to mcrypt.
  378.  
  379.         // Key expansion.
  380.         $l = array_values(unpack('C*', $key));
  381.         $t8 = ($t1 + 7) >> 3;
  382.         $tm = 0xFF >> (8 * $t8 - $t1);
  383.  
  384.         // Expand key.
  385.         $pitable = self::$pitable;
  386.         for ($i = $t; $i < 128; $i++) {
  387.             $l[$i] = $pitable[$l[$i - 1] + $l[$i - $t]];
  388.         }
  389.         $i = 128 - $t8;
  390.         $l[$i] = $pitable[$l[$i] & $tm];
  391.         while ($i--) {
  392.             $l[$i] = $pitable[$l[$i + 1] ^ $l[$i + $t8]];
  393.         }
  394.  
  395.         // Prepare the key for mcrypt.
  396.         $l[0] = self::$invpitable[$l[0]];
  397.         array_unshift($l, 'C*');
  398.  
  399.         $this->key = pack(...$l);
  400.         $this->key_length = strlen($this->key);
  401.         $this->changed = $this->nonIVChanged = true;
  402.         $this->setEngine();
  403.     }
  404.  
  405.     /**
  406.      * Encrypts a message.
  407.      *
  408.      * Mostly a wrapper for \phpseclib3\Crypt\Common\SymmetricKey::encrypt, with some additional OpenSSL handling code
  409.      *
  410.      * @see self::decrypt()
  411.      * @access public
  412.      * @param string $plaintext
  413.      * @return string $ciphertext
  414.      */
  415.     public function encrypt($plaintext)
  416.     {
  417.         if ($this->engine == self::ENGINE_OPENSSL) {
  418.             $temp = $this->key;
  419.             $this->key = $this->orig_key;
  420.             $result = parent::encrypt($plaintext);
  421.             $this->key = $temp;
  422.             return $result;
  423.         }
  424.  
  425.         return parent::encrypt($plaintext);
  426.     }
  427.  
  428.     /**
  429.      * Decrypts a message.
  430.      *
  431.      * Mostly a wrapper for \phpseclib3\Crypt\Common\SymmetricKey::decrypt, with some additional OpenSSL handling code
  432.      *
  433.      * @see self::encrypt()
  434.      * @access public
  435.      * @param string $ciphertext
  436.      * @return string $plaintext
  437.      */
  438.     public function decrypt($ciphertext)
  439.     {
  440.         if ($this->engine == self::ENGINE_OPENSSL) {
  441.             $temp = $this->key;
  442.             $this->key = $this->orig_key;
  443.             $result = parent::decrypt($ciphertext);
  444.             $this->key = $temp;
  445.             return $result;
  446.         }
  447.  
  448.         return parent::decrypt($ciphertext);
  449.     }
  450.  
  451.     /**
  452.      * Encrypts a block
  453.      *
  454.      * @see \phpseclib3\Crypt\Common\SymmetricKey::encryptBlock()
  455.      * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt()
  456.      * @access private
  457.      * @param string $in
  458.      * @return string
  459.      */
  460.     protected function encryptBlock($in)
  461.     {
  462.         list($r0, $r1, $r2, $r3) = array_values(unpack('v*', $in));
  463.         $keys = $this->keys;
  464.         $limit = 20;
  465.         $actions = [$limit => 44, 44 => 64];
  466.         $j = 0;
  467.  
  468.         for (;;) {
  469.             // Mixing round.
  470.             $r0 = (($r0 + $keys[$j++] + ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1;
  471.             $r0 |= $r0 >> 16;
  472.             $r1 = (($r1 + $keys[$j++] + ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2;
  473.             $r1 |= $r1 >> 16;
  474.             $r2 = (($r2 + $keys[$j++] + ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3;
  475.             $r2 |= $r2 >> 16;
  476.             $r3 = (($r3 + $keys[$j++] + ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5;
  477.             $r3 |= $r3 >> 16;
  478.  
  479.             if ($j === $limit) {
  480.                 if ($limit === 64) {
  481.                     break;
  482.                 }
  483.  
  484.                 // Mashing round.
  485.                 $r0 += $keys[$r3 & 0x3F];
  486.                 $r1 += $keys[$r0 & 0x3F];
  487.                 $r2 += $keys[$r1 & 0x3F];
  488.                 $r3 += $keys[$r2 & 0x3F];
  489.                 $limit = $actions[$limit];
  490.             }
  491.         }
  492.  
  493.         return pack('vvvv', $r0, $r1, $r2, $r3);
  494.     }
  495.  
  496.     /**
  497.      * Decrypts a block
  498.      *
  499.      * @see \phpseclib3\Crypt\Common\SymmetricKey::decryptBlock()
  500.      * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt()
  501.      * @access private
  502.      * @param string $in
  503.      * @return string
  504.      */
  505.     protected function decryptBlock($in)
  506.     {
  507.         list($r0, $r1, $r2, $r3) = array_values(unpack('v*', $in));
  508.         $keys = $this->keys;
  509.         $limit = 44;
  510.         $actions = [$limit => 20, 20 => 0];
  511.         $j = 64;
  512.  
  513.         for (;;) {
  514.             // R-mixing round.
  515.             $r3 = ($r3 | ($r3 << 16)) >> 5;
  516.             $r3 = ($r3 - $keys[--$j] - ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF;
  517.             $r2 = ($r2 | ($r2 << 16)) >> 3;
  518.             $r2 = ($r2 - $keys[--$j] - ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF;
  519.             $r1 = ($r1 | ($r1 << 16)) >> 2;
  520.             $r1 = ($r1 - $keys[--$j] - ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF;
  521.             $r0 = ($r0 | ($r0 << 16)) >> 1;
  522.             $r0 = ($r0 - $keys[--$j] - ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF;
  523.  
  524.             if ($j === $limit) {
  525.                 if ($limit === 0) {
  526.                     break;
  527.                 }
  528.  
  529.                 // R-mashing round.
  530.                 $r3 = ($r3 - $keys[$r2 & 0x3F]) & 0xFFFF;
  531.                 $r2 = ($r2 - $keys[$r1 & 0x3F]) & 0xFFFF;
  532.                 $r1 = ($r1 - $keys[$r0 & 0x3F]) & 0xFFFF;
  533.                 $r0 = ($r0 - $keys[$r3 & 0x3F]) & 0xFFFF;
  534.                 $limit = $actions[$limit];
  535.             }
  536.         }
  537.  
  538.         return pack('vvvv', $r0, $r1, $r2, $r3);
  539.     }
  540.  
  541.     /**
  542.      * Creates the key schedule
  543.      *
  544.      * @see \phpseclib3\Crypt\Common\SymmetricKey::setupKey()
  545.      * @access private
  546.      */
  547.     protected function setupKey()
  548.     {
  549.         if (!isset($this->key)) {
  550.             $this->setKey('');
  551.         }
  552.  
  553.         // Key has already been expanded in \phpseclib3\Crypt\RC2::setKey():
  554.         // Only the first value must be altered.
  555.         $l = unpack('Ca/Cb/v*', $this->key);
  556.         array_unshift($l, self::$pitable[$l['a']] | ($l['b'] << 8));
  557.         unset($l['a']);
  558.         unset($l['b']);
  559.         $this->keys = $l;
  560.     }
  561.  
  562.     /**
  563.      * Setup the performance-optimized function for de/encrypt()
  564.      *
  565.      * @see \phpseclib3\Crypt\Common\SymmetricKey::setupInlineCrypt()
  566.      * @access private
  567.      */
  568.     protected function setupInlineCrypt()
  569.     {
  570.         // Init code for both, encrypt and decrypt.
  571.         $init_crypt = '$keys = $this->keys;';
  572.  
  573.         $keys = $this->keys;
  574.  
  575.         // $in is the current 8 bytes block which has to be en/decrypt
  576.         $encrypt_block = $decrypt_block = '
  577.            $in = unpack("v4", $in);
  578.            $r0 = $in[1];
  579.            $r1 = $in[2];
  580.            $r2 = $in[3];
  581.            $r3 = $in[4];
  582.        ';
  583.  
  584.         // Create code for encryption.
  585.         $limit = 20;
  586.         $actions = [$limit => 44, 44 => 64];
  587.         $j = 0;
  588.  
  589.         for (;;) {
  590.             // Mixing round.
  591.             $encrypt_block .= '
  592.                $r0 = (($r0 + ' . $keys[$j++] . ' +
  593.                       ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1;
  594.                $r0 |= $r0 >> 16;
  595.                $r1 = (($r1 + ' . $keys[$j++] . ' +
  596.                       ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2;
  597.                $r1 |= $r1 >> 16;
  598.                $r2 = (($r2 + ' . $keys[$j++] . ' +
  599.                       ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3;
  600.                $r2 |= $r2 >> 16;
  601.                $r3 = (($r3 + ' . $keys[$j++] . ' +
  602.                       ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5;
  603.                $r3 |= $r3 >> 16;';
  604.  
  605.             if ($j === $limit) {
  606.                 if ($limit === 64) {
  607.                     break;
  608.                 }
  609.  
  610.                 // Mashing round.
  611.                 $encrypt_block .= '
  612.                    $r0 += $keys[$r3 & 0x3F];
  613.                    $r1 += $keys[$r0 & 0x3F];
  614.                    $r2 += $keys[$r1 & 0x3F];
  615.                    $r3 += $keys[$r2 & 0x3F];';
  616.                 $limit = $actions[$limit];
  617.             }
  618.         }
  619.  
  620.         $encrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);';
  621.  
  622.         // Create code for decryption.
  623.         $limit = 44;
  624.         $actions = [$limit => 20, 20 => 0];
  625.         $j = 64;
  626.  
  627.         for (;;) {
  628.             // R-mixing round.
  629.             $decrypt_block .= '
  630.                $r3 = ($r3 | ($r3 << 16)) >> 5;
  631.                $r3 = ($r3 - ' . $keys[--$j] . ' -
  632.                       ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF;
  633.                $r2 = ($r2 | ($r2 << 16)) >> 3;
  634.                $r2 = ($r2 - ' . $keys[--$j] . ' -
  635.                       ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF;
  636.                $r1 = ($r1 | ($r1 << 16)) >> 2;
  637.                $r1 = ($r1 - ' . $keys[--$j] . ' -
  638.                       ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF;
  639.                $r0 = ($r0 | ($r0 << 16)) >> 1;
  640.                $r0 = ($r0 - ' . $keys[--$j] . ' -
  641.                       ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF;';
  642.  
  643.             if ($j === $limit) {
  644.                 if ($limit === 0) {
  645.                     break;
  646.                 }
  647.  
  648.                 // R-mashing round.
  649.                 $decrypt_block .= '
  650.                    $r3 = ($r3 - $keys[$r2 & 0x3F]) & 0xFFFF;
  651.                    $r2 = ($r2 - $keys[$r1 & 0x3F]) & 0xFFFF;
  652.                    $r1 = ($r1 - $keys[$r0 & 0x3F]) & 0xFFFF;
  653.                    $r0 = ($r0 - $keys[$r3 & 0x3F]) & 0xFFFF;';
  654.                 $limit = $actions[$limit];
  655.             }
  656.         }
  657.  
  658.         $decrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);';
  659.  
  660.         // Creates the inline-crypt function
  661.         $this->inline_crypt = $this->createInlineCryptFunction(
  662.             [
  663.                'init_crypt'    => $init_crypt,
  664.                'encrypt_block' => $encrypt_block,
  665.                'decrypt_block' => $decrypt_block
  666.             ]
  667.         );
  668.     }
  669. }
  670.