Esempio n. 1
0
 /**
  * Decrypt a RC2 encrypted string
  *
  * @param string $text A RC2 encrypted string
  * @return boolean Returns true
  */
 public function decrypt(&$text)
 {
     $this->operation(parent::DECRYPT);
     // first split up the message into four 16 bit parts (2 bytes),
     // then convert each array element to an integer
     $w = self::splitBytes($text);
     $k = self::splitBytes($this->xkey);
     $j = 0;
     // the key index
     for ($i = 15; $i >= 0; --$i) {
         $j = $i * 4;
         /* This is where it gets ugly, RC2 relies on unsigned ints. PHP does
          * not have a nice way to handle unsigned ints, so we have to rely on sprintf.
          * To make RC2 compatible with mCrypt, I also forced everything to 32 bit
          * When I test against mcrypt and the original rc2 C source, I get 32 bit
          * results, even on a 64 bit platform
          */
         $w[3] &= 65535;
         $w[3] = parent::uInt($w[3] << 11) + parent::uInt($w[3] >> 5);
         $w[3] -= parent::uInt($w[0] & ~$w[2]) + parent::uInt($w[1] & $w[2]) + $k[$j + 3];
         $w[3] = parent::uInt32($w[3]);
         $w[2] &= 65535;
         $w[2] = parent::uInt($w[2] << 13) + parent::uInt($w[2] >> 3);
         $w[2] -= parent::uInt($w[3] & ~$w[1]) + parent::uInt($w[0] & $w[1]) + $k[$j + 2];
         $w[2] = parent::uInt32($w[2]);
         $w[1] &= 65535;
         $w[1] = parent::uInt($w[1] << 14) + parent::uInt($w[1] >> 2);
         $w[1] -= parent::uInt($w[2] & ~$w[0]) + parent::uInt($w[3] & $w[0]) + $k[$j + 1];
         $w[1] = parent::uInt32($w[1]);
         $w[0] &= 65535;
         $w[0] = parent::uInt($w[0] << 15) + parent::uInt($w[0] >> 1);
         $w[0] -= parent::uInt($w[1] & ~$w[3]) + parent::uInt($w[2] & $w[3]) + $k[$j + 0];
         $w[0] = parent::uInt32($w[0]);
         if ($i == 5 || $i == 11) {
             $w[3] -= $k[$w[2] & 63];
             $w[2] -= $k[$w[1] & 63];
             $w[1] -= $k[$w[0] & 63];
             $w[0] -= $k[$w[3] & 63];
         }
     }
     /* I am not clear why this is required. It was not mentioned
      * in any of the documentation I read, however reading the original RC2 C
      * source code, this was done and in order for me to get the
      * correct results in PHP I needed to do this as well
      */
     $max = count($w);
     for ($i = 0; $i < $max; ++$i) {
         $pos = $i * 2;
         $text[$pos] = chr($w[$i]);
         $text[$pos + 1] = chr($w[$i] >> 8);
     }
     return true;
 }
Esempio n. 2
0
 /**
  * The code for this function was translated to PHP from mcrypt's enigma.c,
  * I was not able to find sufficient documentation to create my own
  * version of this function.
  * Enigma requires a 13 byte key, this function will
  * lengthen the key to get it to 13 bytes long if it's short. It also
  * Sets $deck, and $t1, $t2, $t3 which I think are the Enigma rotors.
  *
  * @return void
  */
 private function createKey()
 {
     $this->deck = array();
     $this->t1 = array();
     $this->t2 = array_fill(0, self::ROTORSZ, 0);
     $this->t3 = $this->t2;
     $this->xkey = $this->key();
     $klen = $this->keySize();
     // get the key to exactly 13 bytes if it's less than 13
     if ($klen < 13) {
         $this->xkey = str_pad($this->xkey, 13, chr(0), STR_PAD_RIGHT);
     }
     $seed = 123;
     for ($i = 0; $i < 13; ++$i) {
         $seed = parent::sInt32($seed) * ord($this->xkey[$i]) + $i;
     }
     // sets $t1 and $deck
     for ($i = 0; $i < self::ROTORSZ; ++$i) {
         $this->t1[] = $i;
         $this->deck[] = $i;
     }
     // sets $t3
     for ($i = 0; $i < self::ROTORSZ; ++$i) {
         // make sure the return values are 32 bit
         $seed = 5 * parent::sInt32($seed) + ord($this->xkey[$i % 13]);
         $seed = parent::sInt32($seed);
         // force the returned value to be an unsigned int
         //$random = parent::uint32($seed % 65521);
         $random = parent::uInt($seed % 65521);
         $k = self::ROTORSZ - 1 - $i;
         $ic = ($random & self::MASK) % ($k + 1);
         // make sure the returned value is an unsigned int
         $random = parent::uInt($random >> 8);
         $temp = $this->t1[$k];
         $this->t1[$k] = $this->t1[$ic];
         $this->t1[$ic] = $temp;
         if ($this->t3[$k] != 0) {
             continue;
         }
         $ic = ($random & self::MASK) % $k;
         while ($this->t3[$ic] != 0) {
             $ic = ($ic + 1) % $k;
         }
         $this->t3[$k] = $ic;
         $this->t3[$ic] = $k;
     }
     // sets $t2
     for ($i = 0; $i < self::ROTORSZ; ++$i) {
         $pos = $this->t1[$i] & self::MASK;
         $this->t2[$pos] = $i;
     }
     // now convert $t1, $t2, $t3, $deck values to signed chars,
     // PHP's chr() function returns an unsigned char, so we have
     // to use use our own
     $this->t1 = array_map("parent::sChar", $this->t1);
     $this->t2 = array_map("parent::sChar", $this->t2);
     $this->t3 = array_map("parent::sChar", $this->t3);
     $this->deck = array_map("parent::sChar", $this->deck);
 }