Beispiel #1
0
 public function inline_crypt_setup()
 {
     $lambda_functions =& Crypt_Rijndael::get_lambda_functions();
     $block_size = $this->block_size;
     $mode = $this->mode;
     if (count($lambda_functions) < 5) {
         $w = $this->w;
         $dw = $this->dw;
         $init_encryptBlock = '';
         $init_decryptBlock = '';
     } else {
         $i = 0;
         for ($cw = count($this->w); $i < $cw; ++$i) {
             $w[] = '$w_' . $i;
             $dw[] = '$dw_' . $i;
         }
         $init_encryptBlock = 'extract($self->w,  EXTR_PREFIX_ALL, "w");';
         $init_decryptBlock = 'extract($self->dw, EXTR_PREFIX_ALL, "dw");';
     }
     $code_hash = md5($mode . ', ' . $block_size . ', ' . implode(',', $w));
     if (!isset($lambda_functions[$code_hash])) {
         $Nr = $this->Nr;
         $Nb = $this->Nb;
         $c = $this->c;
         $init_encryptBlock .= '' . "\n" . '                $t0 = $self->t0;' . "\n" . '                $t1 = $self->t1;' . "\n" . '                $t2 = $self->t2;' . "\n" . '                $t3 = $self->t3;' . "\n" . '                $sbox = $self->sbox;';
         $s = 'e';
         $e = 's';
         $wc = $Nb - 1;
         $_encryptBlock = '$in = unpack("N*", $in);' . "\n";
         for ($i = 0; $i < $Nb; ++$i) {
             $_encryptBlock .= '$s' . $i . ' = $in[' . ($i + 1) . '] ^ ' . $w[++$wc] . ';' . "\n" . '';
         }
         for ($round = 1; $round < $Nr; ++$round) {
             list($s, $e) = array($e, $s);
             for ($i = 0; $i < $Nb; ++$i) {
                 $_encryptBlock .= '$' . $e . $i . ' =' . "\n" . '                        $t0[($' . $s . $i . ' >> 24) & 0xff] ^' . "\n" . '                        $t1[($' . $s . ($i + $c[1]) % $Nb . ' >> 16) & 0xff] ^' . "\n" . '                        $t2[($' . $s . ($i + $c[2]) % $Nb . ' >>  8) & 0xff] ^' . "\n" . '                        $t3[ $' . $s . ($i + $c[3]) % $Nb . '        & 0xff] ^' . "\n" . '                        ' . $w[++$wc] . ';' . "\n" . '';
             }
         }
         for ($i = 0; $i < $Nb; ++$i) {
             $_encryptBlock .= '$' . $e . $i . ' =' . "\n" . '                     $sbox[ $' . $e . $i . '        & 0xff]        |' . "\n" . '                    ($sbox[($' . $e . $i . ' >>  8) & 0xff] <<  8) |' . "\n" . '                    ($sbox[($' . $e . $i . ' >> 16) & 0xff] << 16) |' . "\n" . '                    ($sbox[($' . $e . $i . ' >> 24) & 0xff] << 24);' . "\n";
         }
         $_encryptBlock .= '$in = pack("N*"' . "\n";
         for ($i = 0; $i < $Nb; ++$i) {
             $_encryptBlock .= ',' . "\n" . '                    ($' . $e . $i . ' & 0xFF000000) ^' . "\n" . '                    ($' . $e . ($i + $c[1]) % $Nb . ' & 0x00FF0000) ^' . "\n" . '                    ($' . $e . ($i + $c[2]) % $Nb . ' & 0x0000FF00) ^' . "\n" . '                    ($' . $e . ($i + $c[3]) % $Nb . ' & 0x000000FF) ^' . "\n" . '                    ' . $w[$i] . "\n";
         }
         $_encryptBlock .= ');';
         $init_decryptBlock .= '' . "\n" . '                $dt0 = $self->dt0;' . "\n" . '                $dt1 = $self->dt1;' . "\n" . '                $dt2 = $self->dt2;' . "\n" . '                $dt3 = $self->dt3;' . "\n" . '                $isbox = $self->isbox;';
         $s = 'e';
         $e = 's';
         $wc = $Nb - 1;
         $_decryptBlock = '$in = unpack("N*", $in);' . "\n";
         for ($i = 0; $i < $Nb; ++$i) {
             $_decryptBlock .= '$s' . $i . ' = $in[' . ($i + 1) . '] ^ ' . $dw[++$wc] . ';' . "\n";
         }
         for ($round = 1; $round < $Nr; ++$round) {
             list($s, $e) = array($e, $s);
             for ($i = 0; $i < $Nb; ++$i) {
                 $_decryptBlock .= '$' . $e . $i . ' =' . "\n" . '                        $dt0[($' . $s . $i . ' >> 24) & 0xff] ^' . "\n" . '                        $dt1[($' . $s . ($Nb + $i - $c[1]) % $Nb . ' >> 16) & 0xff] ^' . "\n" . '                        $dt2[($' . $s . ($Nb + $i - $c[2]) % $Nb . ' >>  8) & 0xff] ^' . "\n" . '                        $dt3[ $' . $s . ($Nb + $i - $c[3]) % $Nb . '        & 0xff] ^' . "\n" . '                        ' . $dw[++$wc] . ';' . "\n" . '';
             }
         }
         for ($i = 0; $i < $Nb; ++$i) {
             $_decryptBlock .= '$' . $e . $i . ' =' . "\n" . '                     $isbox[ $' . $e . $i . '        & 0xff]        |' . "\n" . '                    ($isbox[($' . $e . $i . ' >>  8) & 0xff] <<  8) |' . "\n" . '                    ($isbox[($' . $e . $i . ' >> 16) & 0xff] << 16) |' . "\n" . '                    ($isbox[($' . $e . $i . ' >> 24) & 0xff] << 24);' . "\n";
         }
         $_decryptBlock .= '$in = pack("N*"' . "\n";
         for ($i = 0; $i < $Nb; ++$i) {
             $_decryptBlock .= ',' . "\n" . '                    ($' . $e . $i . ' & 0xFF000000) ^' . "\n" . '                    ($' . $e . ($Nb + $i - $c[1]) % $Nb . ' & 0x00FF0000) ^' . "\n" . '                    ($' . $e . ($Nb + $i - $c[2]) % $Nb . ' & 0x0000FF00) ^' . "\n" . '                    ($' . $e . ($Nb + $i - $c[3]) % $Nb . ' & 0x000000FF) ^' . "\n" . '                    ' . $dw[$i] . "\n";
         }
         $_decryptBlock .= ');';
         switch ($mode) {
             case CRYPT_RIJNDAEL_MODE_ECB:
                 $encrypt = $init_encryptBlock . '' . "\n" . '                        $ciphertext = "";' . "\n" . '                        $text = $self->_pad($text);' . "\n" . '                        $plaintext_len = strlen($text);' . "\n" . '' . "\n" . '                        for ($i = 0; $i < $plaintext_len; $i+= ' . $block_size . ') {' . "\n" . '                            $in = substr($text, $i, ' . $block_size . ');' . "\n" . '                            ' . $_encryptBlock . '' . "\n" . '                            $ciphertext.= $in;' . "\n" . '                        }' . "\n" . '                       ' . "\n" . '                        return $ciphertext;' . "\n" . '                        ';
                 $decrypt = $init_decryptBlock . '' . "\n" . '                        $plaintext = "";' . "\n" . '                        $text = str_pad($text, strlen($text) + (' . $block_size . ' - strlen($text) % ' . $block_size . ') % ' . $block_size . ', chr(0));' . "\n" . '                        $ciphertext_len = strlen($text);' . "\n" . '' . "\n" . '                        for ($i = 0; $i < $ciphertext_len; $i+= ' . $block_size . ') {' . "\n" . '                            $in = substr($text, $i, ' . $block_size . ');' . "\n" . '                            ' . $_decryptBlock . '' . "\n" . '                            $plaintext.= $in;' . "\n" . '                        }' . "\n" . '' . "\n" . '                        return $self->_unpad($plaintext);' . "\n" . '                        ';
                 break;
             case CRYPT_RIJNDAEL_MODE_CBC:
                 $encrypt = $init_encryptBlock . '' . "\n" . '                        $ciphertext = "";' . "\n" . '                        $text = $self->_pad($text);' . "\n" . '                        $plaintext_len = strlen($text);' . "\n" . '' . "\n" . '                        $in = $self->encryptIV;' . "\n" . '' . "\n" . '                        for ($i = 0; $i < $plaintext_len; $i+= ' . $block_size . ') {' . "\n" . '                            $in = substr($text, $i, ' . $block_size . ') ^ $in;' . "\n" . '                            ' . $_encryptBlock . '' . "\n" . '                            $ciphertext.= $in;' . "\n" . '                        }' . "\n" . '' . "\n" . '                        if ($self->continuousBuffer) {' . "\n" . '                            $self->encryptIV = $in;' . "\n" . '                        }' . "\n" . '' . "\n" . '                        return $ciphertext;' . "\n" . '                        ';
                 $decrypt = $init_decryptBlock . '' . "\n" . '                        $plaintext = "";' . "\n" . '                        $text = str_pad($text, strlen($text) + (' . $block_size . ' - strlen($text) % ' . $block_size . ') % ' . $block_size . ', chr(0));' . "\n" . '                        $ciphertext_len = strlen($text);' . "\n" . '' . "\n" . '                        $iv = $self->decryptIV;' . "\n" . '' . "\n" . '                        for ($i = 0; $i < $ciphertext_len; $i+= ' . $block_size . ') {' . "\n" . '                            $in = $block = substr($text, $i, ' . $block_size . ');' . "\n" . '                            ' . $_decryptBlock . '' . "\n" . '                            $plaintext.= $in ^ $iv;' . "\n" . '                            $iv = $block;' . "\n" . '                        }' . "\n" . '' . "\n" . '                        if ($self->continuousBuffer) {' . "\n" . '                            $self->decryptIV = $iv;' . "\n" . '                        }' . "\n" . '' . "\n" . '                        return $self->_unpad($plaintext);' . "\n" . '                        ';
                 break;
             case CRYPT_RIJNDAEL_MODE_CTR:
                 $encrypt = $init_encryptBlock . '' . "\n" . '                        $ciphertext = "";' . "\n" . '                        $plaintext_len = strlen($text);' . "\n" . '                        $xor = $self->encryptIV;' . "\n" . '                        $buffer = &$self->enbuffer;' . "\n" . '' . "\n" . '                        if (strlen($buffer["encrypted"])) {' . "\n" . '                            for ($i = 0; $i < $plaintext_len; $i+= ' . $block_size . ') {' . "\n" . '                                $block = substr($text, $i, ' . $block_size . ');' . "\n" . '                                if (strlen($block) > strlen($buffer["encrypted"])) {' . "\n" . '                                    $in = $self->_generate_xor(' . $block_size . ', $xor);' . "\n" . '                                    ' . $_encryptBlock . '' . "\n" . '                                    $buffer["encrypted"].= $in;' . "\n" . '                                }' . "\n" . '                                $key = $self->_string_shift($buffer["encrypted"], ' . $block_size . ');' . "\n" . '                                $ciphertext.= $block ^ $key;' . "\n" . '                            }' . "\n" . '                        } else {' . "\n" . '                            for ($i = 0; $i < $plaintext_len; $i+= ' . $block_size . ') {' . "\n" . '                                $block = substr($text, $i, ' . $block_size . ');' . "\n" . '                                $in = $self->_generate_xor(' . $block_size . ', $xor);' . "\n" . '                                ' . $_encryptBlock . '' . "\n" . '                                $key = $in;' . "\n" . '                                $ciphertext.= $block ^ $key;' . "\n" . '                            }' . "\n" . '                        }' . "\n" . '                        if ($self->continuousBuffer) {' . "\n" . '                            $self->encryptIV = $xor;' . "\n" . '                            if ($start = $plaintext_len % ' . $block_size . ') {' . "\n" . '                                $buffer["encrypted"] = substr($key, $start) . $buffer["encrypted"];' . "\n" . '                            }' . "\n" . '                        }' . "\n" . '' . "\n" . '                        return $ciphertext;' . "\n" . '                    ';
                 $decrypt = $init_encryptBlock . '' . "\n" . '                        $plaintext = "";' . "\n" . '                        $ciphertext_len = strlen($text);' . "\n" . '                        $xor = $self->decryptIV;' . "\n" . '                        $buffer = &$self->debuffer;' . "\n" . '' . "\n" . '                        if (strlen($buffer["ciphertext"])) {' . "\n" . '                            for ($i = 0; $i < $ciphertext_len; $i+= ' . $block_size . ') {' . "\n" . '                                $block = substr($text, $i, ' . $block_size . ');' . "\n" . '                                if (strlen($block) > strlen($buffer["ciphertext"])) {' . "\n" . '                                    $in = $self->_generate_xor(' . $block_size . ', $xor);' . "\n" . '                                    ' . $_encryptBlock . '' . "\n" . '                                    $buffer["ciphertext"].= $in;' . "\n" . '                                }' . "\n" . '                                $key = $self->_string_shift($buffer["ciphertext"], ' . $block_size . ');' . "\n" . '                                $plaintext.= $block ^ $key;' . "\n" . '                            }' . "\n" . '                        } else {' . "\n" . '                            for ($i = 0; $i < $ciphertext_len; $i+= ' . $block_size . ') {' . "\n" . '                                $block = substr($text, $i, ' . $block_size . ');' . "\n" . '                                $in = $self->_generate_xor(' . $block_size . ', $xor);' . "\n" . '                                ' . $_encryptBlock . '' . "\n" . '                                $key = $in;' . "\n" . '                                $plaintext.= $block ^ $key;' . "\n" . '                            }' . "\n" . '                        }' . "\n" . '                        if ($self->continuousBuffer) {' . "\n" . '                            $self->decryptIV = $xor;' . "\n" . '                            if ($start = $ciphertext_len % ' . $block_size . ') {' . "\n" . '                                $buffer["ciphertext"] = substr($key, $start) . $buffer["ciphertext"];' . "\n" . '                            }' . "\n" . '                        }' . "\n" . '                       ' . "\n" . '                        return $plaintext;' . "\n" . '                        ';
                 break;
             case CRYPT_RIJNDAEL_MODE_CFB:
                 $encrypt = $init_encryptBlock . '' . "\n" . '                        $ciphertext = "";' . "\n" . '                        $buffer = &$self->enbuffer;' . "\n" . '' . "\n" . '                        if ($self->continuousBuffer) {' . "\n" . '                            $iv = &$self->encryptIV;' . "\n" . '                            $pos = &$buffer["pos"];' . "\n" . '                        } else {' . "\n" . '                            $iv = $self->encryptIV;' . "\n" . '                            $pos = 0;' . "\n" . '                        }' . "\n" . '                        $len = strlen($text);' . "\n" . '                        $i = 0;' . "\n" . '                        if ($pos) {' . "\n" . '                            $orig_pos = $pos;' . "\n" . '                            $max = ' . $block_size . ' - $pos;' . "\n" . '                            if ($len >= $max) {' . "\n" . '                                $i = $max;' . "\n" . '                                $len-= $max;' . "\n" . '                                $pos = 0;' . "\n" . '                            } else {' . "\n" . '                                $i = $len;' . "\n" . '                                $pos+= $len;' . "\n" . '                                $len = 0;' . "\n" . '                            }' . "\n" . '                            $ciphertext = substr($iv, $orig_pos) ^ $text;' . "\n" . '                            $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);' . "\n" . '                        }' . "\n" . '                        while ($len >= ' . $block_size . ') {' . "\n" . '                            $in = $iv;' . "\n" . '                            ' . $_encryptBlock . ';' . "\n" . '                            $iv = $in ^ substr($text, $i, ' . $block_size . ');' . "\n" . '                            $ciphertext.= $iv;' . "\n" . '                            $len-= ' . $block_size . ';' . "\n" . '                            $i+= ' . $block_size . ';' . "\n" . '                        }' . "\n" . '                        if ($len) {' . "\n" . '                            $in = $iv;' . "\n" . '                            ' . $_encryptBlock . '' . "\n" . '                            $iv = $in;' . "\n" . '                            $block = $iv ^ substr($text, $i);' . "\n" . '                            $iv = substr_replace($iv, $block, 0, $len);' . "\n" . '                            $ciphertext.= $block;' . "\n" . '                            $pos = $len;' . "\n" . '                        }' . "\n" . '                        return $ciphertext;' . "\n" . '                    ';
                 $decrypt = $init_encryptBlock . '' . "\n" . '                        $plaintext = "";' . "\n" . '                        $buffer = &$self->debuffer;' . "\n" . '' . "\n" . '                        if ($self->continuousBuffer) {' . "\n" . '                            $iv = &$self->decryptIV;' . "\n" . '                            $pos = &$buffer["pos"];' . "\n" . '                        } else {' . "\n" . '                            $iv = $self->decryptIV;' . "\n" . '                            $pos = 0;' . "\n" . '                        }' . "\n" . '                        $len = strlen($text);' . "\n" . '                        $i = 0;' . "\n" . '                        if ($pos) {' . "\n" . '                            $orig_pos = $pos;' . "\n" . '                            $max = ' . $block_size . ' - $pos;' . "\n" . '                            if ($len >= $max) {' . "\n" . '                                $i = $max;' . "\n" . '                                $len-= $max;' . "\n" . '                                $pos = 0;' . "\n" . '                            } else {' . "\n" . '                                $i = $len;' . "\n" . '                                $pos+= $len;' . "\n" . '                                $len = 0;' . "\n" . '                            }' . "\n" . '                            $plaintext = substr($iv, $orig_pos) ^ $text;' . "\n" . '                            $iv = substr_replace($iv, substr($text, 0, $i), $orig_pos, $i);' . "\n" . '                        }' . "\n" . '                        while ($len >= ' . $block_size . ') {' . "\n" . '                            $in = $iv;' . "\n" . '                            ' . $_encryptBlock . '' . "\n" . '                            $iv = $in;' . "\n" . '                            $cb = substr($text, $i, ' . $block_size . ');' . "\n" . '                            $plaintext.= $iv ^ $cb;' . "\n" . '                            $iv = $cb;' . "\n" . '                            $len-= ' . $block_size . ';' . "\n" . '                            $i+= ' . $block_size . ';' . "\n" . '                        }' . "\n" . '                        if ($len) {' . "\n" . '                            $in = $iv;' . "\n" . '                            ' . $_encryptBlock . '' . "\n" . '                            $iv = $in;' . "\n" . '                            $plaintext.= $iv ^ substr($text, $i);' . "\n" . '                            $iv = substr_replace($iv, substr($text, $i), 0, $len);' . "\n" . '                            $pos = $len;' . "\n" . '                        }' . "\n" . '' . "\n" . '                        return $plaintext;' . "\n" . '                        ';
                 break;
             case CRYPT_RIJNDAEL_MODE_OFB:
                 $encrypt = $init_encryptBlock . '' . "\n" . '                        $ciphertext = "";' . "\n" . '                        $plaintext_len = strlen($text);' . "\n" . '                        $xor = $self->encryptIV;' . "\n" . '                        $buffer = &$self->enbuffer;' . "\n" . '' . "\n" . '                        if (strlen($buffer["xor"])) {' . "\n" . '                            for ($i = 0; $i < $plaintext_len; $i+= ' . $block_size . ') {' . "\n" . '                                $block = substr($text, $i, ' . $block_size . ');' . "\n" . '                                if (strlen($block) > strlen($buffer["xor"])) {' . "\n" . '                                    $in = $xor;' . "\n" . '                                    ' . $_encryptBlock . '' . "\n" . '                                    $xor = $in;' . "\n" . '                                    $buffer["xor"].= $xor;' . "\n" . '                                }' . "\n" . '                                $key = $self->_string_shift($buffer["xor"], ' . $block_size . ');' . "\n" . '                                $ciphertext.= $block ^ $key;' . "\n" . '                            }' . "\n" . '                        } else {' . "\n" . '                            for ($i = 0; $i < $plaintext_len; $i+= ' . $block_size . ') {' . "\n" . '                                $in = $xor;' . "\n" . '                                ' . $_encryptBlock . '' . "\n" . '                                $xor = $in;' . "\n" . '                                $ciphertext.= substr($text, $i, ' . $block_size . ') ^ $xor;' . "\n" . '                            }' . "\n" . '                            $key = $xor;' . "\n" . '                        }' . "\n" . '                        if ($self->continuousBuffer) {' . "\n" . '                            $self->encryptIV = $xor;' . "\n" . '                            if ($start = $plaintext_len % ' . $block_size . ') {' . "\n" . '                                 $buffer["xor"] = substr($key, $start) . $buffer["xor"];' . "\n" . '                            }' . "\n" . '                        }' . "\n" . '                        return $ciphertext;' . "\n" . '                        ';
                 $decrypt = $init_encryptBlock . '' . "\n" . '                        $plaintext = "";' . "\n" . '                        $ciphertext_len = strlen($text);' . "\n" . '                        $xor = $self->decryptIV;' . "\n" . '                        $buffer = &$self->debuffer;' . "\n" . '' . "\n" . '                        if (strlen($buffer["xor"])) {' . "\n" . '                            for ($i = 0; $i < $ciphertext_len; $i+= ' . $block_size . ') {' . "\n" . '                                $block = substr($text, $i, ' . $block_size . ');' . "\n" . '                                if (strlen($block) > strlen($buffer["xor"])) {' . "\n" . '                                    $in = $xor;' . "\n" . '                                    ' . $_encryptBlock . '' . "\n" . '                                    $xor = $in;' . "\n" . '                                    $buffer["xor"].= $xor;' . "\n" . '                                }' . "\n" . '                                $key = $self->_string_shift($buffer["xor"], ' . $block_size . ');' . "\n" . '                                $plaintext.= $block ^ $key;' . "\n" . '                            }' . "\n" . '                        } else {' . "\n" . '                            for ($i = 0; $i < $ciphertext_len; $i+= ' . $block_size . ') {' . "\n" . '                                $in = $xor;' . "\n" . '                                ' . $_encryptBlock . '' . "\n" . '                                $xor = $in;' . "\n" . '                                $plaintext.= substr($text, $i, ' . $block_size . ') ^ $xor;' . "\n" . '                            }' . "\n" . '                            $key = $xor;' . "\n" . '                        }' . "\n" . '                        if ($self->continuousBuffer) {' . "\n" . '                            $self->decryptIV = $xor;' . "\n" . '                            if ($start = $ciphertext_len % ' . $block_size . ') {' . "\n" . '                                 $buffer["xor"] = substr($key, $start) . $buffer["xor"];' . "\n" . '                            }' . "\n" . '                        }' . "\n" . '                        return $plaintext;' . "\n" . '                        ';
                 break;
         }
         $lambda_functions[$code_hash] = create_function('$action, &$self, $text', 'if ($action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' }');
     }
     $this->inline_crypt = $lambda_functions[$code_hash];
 }
Beispiel #2
0
    /**
     * Creates performance-optimized function for de/encrypt(), storing it in $this->inline_crypt
     *
     * @see Crypt_Rijndael::encrypt()
     * @see Crypt_Rijndael::decrypt()
     * @access private
     */
    function inline_crypt_setup()
    {
        // Note: inline_crypt_setup() will be called only if $this->changed === true
        // So here we are'nt under the same heavy timing-stress as we are in _de/encryptBlock() or de/encrypt().
        // However...the here generated function- $code, stored as php callback in $this->inline_crypt, must work as fast as even possible.
        $lambda_functions =& Crypt_Rijndael::get_lambda_functions();
        $block_size = $this->block_size;
        $mode = $this->mode;
        // The first 5 generated $lambda_functions will use the key-words hardcoded for better performance.
        // For memory reason we limit those ultra-optimized function code to 5.
        // After that, we use pure (extracted) integer vars for the key-words which is faster than accessing them via array.
        if (count($lambda_functions) < 5) {
            $w = $this->w;
            $dw = $this->dw;
            $init_encryptBlock = '';
            $init_decryptBlock = '';
        } else {
            for ($i = 0, $cw = count($this->w); $i < $cw; ++$i) {
                $w[] = '$w_' . $i;
                $dw[] = '$dw_' . $i;
            }
            $init_encryptBlock = 'extract($self->w,  EXTR_PREFIX_ALL, "w");';
            $init_decryptBlock = 'extract($self->dw, EXTR_PREFIX_ALL, "dw");';
        }
        $code_hash = md5("{$mode}, {$block_size}, " . implode(',', $w));
        if (!isset($lambda_functions[$code_hash])) {
            $Nr = $this->Nr;
            $Nb = $this->Nb;
            $c = $this->c;
            // Generating encrypt code:
            $init_encryptBlock .= '

                $t0 = $self->t0;

                $t1 = $self->t1;

                $t2 = $self->t2;

                $t3 = $self->t3;

                $sbox = $self->sbox;';
            $s = 'e';
            $e = 's';
            $wc = $Nb - 1;
            // Preround: addRoundKey
            $_encryptBlock = '$in = unpack("N*", $in);' . "\n";
            for ($i = 0; $i < $Nb; ++$i) {
                $_encryptBlock .= '$s' . $i . ' = $in[' . ($i + 1) . '] ^ ' . $w[++$wc] . ";\n";
            }
            // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey
            for ($round = 1; $round < $Nr; ++$round) {
                list($s, $e) = array($e, $s);
                for ($i = 0; $i < $Nb; ++$i) {
                    $_encryptBlock .= '$' . $e . $i . ' =

                        $t0[($' . $s . $i . ' >> 24) & 0xff] ^

                        $t1[($' . $s . ($i + $c[1]) % $Nb . ' >> 16) & 0xff] ^

                        $t2[($' . $s . ($i + $c[2]) % $Nb . ' >>  8) & 0xff] ^

                        $t3[ $' . $s . ($i + $c[3]) % $Nb . '        & 0xff] ^

                        ' . $w[++$wc] . ";\n";
                }
            }
            // Finalround: subWord + shiftRows + addRoundKey
            for ($i = 0; $i < $Nb; ++$i) {
                $_encryptBlock .= '$' . $e . $i . ' =

                     $sbox[ $' . $e . $i . '        & 0xff]        |

                    ($sbox[($' . $e . $i . ' >>  8) & 0xff] <<  8) |

                    ($sbox[($' . $e . $i . ' >> 16) & 0xff] << 16) |

                    ($sbox[($' . $e . $i . ' >> 24) & 0xff] << 24);' . "\n";
            }
            $_encryptBlock .= '$in = pack("N*"' . "\n";
            for ($i = 0; $i < $Nb; ++$i) {
                $_encryptBlock .= ',

                    ($' . $e . $i . ' & 0xFF000000) ^

                    ($' . $e . ($i + $c[1]) % $Nb . ' & 0x00FF0000) ^

                    ($' . $e . ($i + $c[2]) % $Nb . ' & 0x0000FF00) ^

                    ($' . $e . ($i + $c[3]) % $Nb . ' & 0x000000FF) ^

                    ' . $w[$i] . "\n";
            }
            $_encryptBlock .= ');';
            // Generating decrypt code:
            $init_decryptBlock .= '

                $dt0 = $self->dt0;

                $dt1 = $self->dt1;

                $dt2 = $self->dt2;

                $dt3 = $self->dt3;

                $isbox = $self->isbox;';
            $s = 'e';
            $e = 's';
            $wc = $Nb - 1;
            // Preround: addRoundKey
            $_decryptBlock = '$in = unpack("N*", $in);' . "\n";
            for ($i = 0; $i < $Nb; ++$i) {
                $_decryptBlock .= '$s' . $i . ' = $in[' . ($i + 1) . '] ^ ' . $dw[++$wc] . ';' . "\n";
            }
            // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey
            for ($round = 1; $round < $Nr; ++$round) {
                list($s, $e) = array($e, $s);
                for ($i = 0; $i < $Nb; ++$i) {
                    $_decryptBlock .= '$' . $e . $i . ' =

                        $dt0[($' . $s . $i . ' >> 24) & 0xff] ^

                        $dt1[($' . $s . ($Nb + $i - $c[1]) % $Nb . ' >> 16) & 0xff] ^

                        $dt2[($' . $s . ($Nb + $i - $c[2]) % $Nb . ' >>  8) & 0xff] ^

                        $dt3[ $' . $s . ($Nb + $i - $c[3]) % $Nb . '        & 0xff] ^

                        ' . $dw[++$wc] . ";\n";
                }
            }
            // Finalround: subWord + shiftRows + addRoundKey
            for ($i = 0; $i < $Nb; ++$i) {
                $_decryptBlock .= '$' . $e . $i . ' =

                     $isbox[ $' . $e . $i . '        & 0xff]        |

                    ($isbox[($' . $e . $i . ' >>  8) & 0xff] <<  8) |

                    ($isbox[($' . $e . $i . ' >> 16) & 0xff] << 16) |

                    ($isbox[($' . $e . $i . ' >> 24) & 0xff] << 24);' . "\n";
            }
            $_decryptBlock .= '$in = pack("N*"' . "\n";
            for ($i = 0; $i < $Nb; ++$i) {
                $_decryptBlock .= ',

                    ($' . $e . $i . ' & 0xFF000000) ^

                    ($' . $e . ($Nb + $i - $c[1]) % $Nb . ' & 0x00FF0000) ^

                    ($' . $e . ($Nb + $i - $c[2]) % $Nb . ' & 0x0000FF00) ^

                    ($' . $e . ($Nb + $i - $c[3]) % $Nb . ' & 0x000000FF) ^

                    ' . $dw[$i] . "\n";
            }
            $_decryptBlock .= ');';
            // Generating mode of operation code:
            switch ($mode) {
                case CRYPT_RIJNDAEL_MODE_ECB:
                    $encrypt = $init_encryptBlock . '

                        $ciphertext = "";

                        $text = $self->_pad($text);

                        $plaintext_len = strlen($text);



                        for ($i = 0; $i < $plaintext_len; $i+= ' . $block_size . ') {

                            $in = substr($text, $i, ' . $block_size . ');

                            ' . $_encryptBlock . '

                            $ciphertext.= $in;

                        }

                       

                        return $ciphertext;

                        ';
                    $decrypt = $init_decryptBlock . '

                        $plaintext = "";

                        $text = str_pad($text, strlen($text) + (' . $block_size . ' - strlen($text) % ' . $block_size . ') % ' . $block_size . ', chr(0));

                        $ciphertext_len = strlen($text);



                        for ($i = 0; $i < $ciphertext_len; $i+= ' . $block_size . ') {

                            $in = substr($text, $i, ' . $block_size . ');

                            ' . $_decryptBlock . '

                            $plaintext.= $in;

                        }



                        return $self->_unpad($plaintext);

                        ';
                    break;
                case CRYPT_RIJNDAEL_MODE_CBC:
                    $encrypt = $init_encryptBlock . '

                        $ciphertext = "";

                        $text = $self->_pad($text);

                        $plaintext_len = strlen($text);



                        $in = $self->encryptIV;



                        for ($i = 0; $i < $plaintext_len; $i+= ' . $block_size . ') {

                            $in = substr($text, $i, ' . $block_size . ') ^ $in;

                            ' . $_encryptBlock . '

                            $ciphertext.= $in;

                        }



                        if ($self->continuousBuffer) {

                            $self->encryptIV = $in;

                        }



                        return $ciphertext;

                        ';
                    $decrypt = $init_decryptBlock . '

                        $plaintext = "";

                        $text = str_pad($text, strlen($text) + (' . $block_size . ' - strlen($text) % ' . $block_size . ') % ' . $block_size . ', chr(0));

                        $ciphertext_len = strlen($text);



                        $iv = $self->decryptIV;



                        for ($i = 0; $i < $ciphertext_len; $i+= ' . $block_size . ') {

                            $in = $block = substr($text, $i, ' . $block_size . ');

                            ' . $_decryptBlock . '

                            $plaintext.= $in ^ $iv;

                            $iv = $block;

                        }



                        if ($self->continuousBuffer) {

                            $self->decryptIV = $iv;

                        }



                        return $self->_unpad($plaintext);

                        ';
                    break;
                case CRYPT_RIJNDAEL_MODE_CTR:
                    $encrypt = $init_encryptBlock . '

                        $ciphertext = "";

                        $plaintext_len = strlen($text);

                        $xor = $self->encryptIV;

                        $buffer = &$self->enbuffer;



                        if (strlen($buffer["encrypted"])) {

                            for ($i = 0; $i < $plaintext_len; $i+= ' . $block_size . ') {

                                $block = substr($text, $i, ' . $block_size . ');

                                if (strlen($block) > strlen($buffer["encrypted"])) {

                                    $in = $self->_generate_xor(' . $block_size . ', $xor);

                                    ' . $_encryptBlock . '

                                    $buffer["encrypted"].= $in;

                                }

                                $key = $self->_string_shift($buffer["encrypted"], ' . $block_size . ');

                                $ciphertext.= $block ^ $key;

                            }

                        } else {

                            for ($i = 0; $i < $plaintext_len; $i+= ' . $block_size . ') {

                                $block = substr($text, $i, ' . $block_size . ');

                                $in = $self->_generate_xor(' . $block_size . ', $xor);

                                ' . $_encryptBlock . '

                                $key = $in;

                                $ciphertext.= $block ^ $key;

                            }

                        }

                        if ($self->continuousBuffer) {

                            $self->encryptIV = $xor;

                            if ($start = $plaintext_len % ' . $block_size . ') {

                                $buffer["encrypted"] = substr($key, $start) . $buffer["encrypted"];

                            }

                        }



                        return $ciphertext;

                    ';
                    $decrypt = $init_encryptBlock . '

                        $plaintext = "";

                        $ciphertext_len = strlen($text);

                        $xor = $self->decryptIV;

                        $buffer = &$self->debuffer;



                        if (strlen($buffer["ciphertext"])) {

                            for ($i = 0; $i < $ciphertext_len; $i+= ' . $block_size . ') {

                                $block = substr($text, $i, ' . $block_size . ');

                                if (strlen($block) > strlen($buffer["ciphertext"])) {

                                    $in = $self->_generate_xor(' . $block_size . ', $xor);

                                    ' . $_encryptBlock . '

                                    $buffer["ciphertext"].= $in;

                                }

                                $key = $self->_string_shift($buffer["ciphertext"], ' . $block_size . ');

                                $plaintext.= $block ^ $key;

                            }

                        } else {

                            for ($i = 0; $i < $ciphertext_len; $i+= ' . $block_size . ') {

                                $block = substr($text, $i, ' . $block_size . ');

                                $in = $self->_generate_xor(' . $block_size . ', $xor);

                                ' . $_encryptBlock . '

                                $key = $in;

                                $plaintext.= $block ^ $key;

                            }

                        }

                        if ($self->continuousBuffer) {

                            $self->decryptIV = $xor;

                            if ($start = $ciphertext_len % ' . $block_size . ') {

                                $buffer["ciphertext"] = substr($key, $start) . $buffer["ciphertext"];

                            }

                        }

                       

                        return $plaintext;

                        ';
                    break;
                case CRYPT_RIJNDAEL_MODE_CFB:
                    $encrypt = $init_encryptBlock . '

                        $ciphertext = "";

                        $buffer = &$self->enbuffer;



                        if ($self->continuousBuffer) {

                            $iv = &$self->encryptIV;

                            $pos = &$buffer["pos"];

                        } else {

                            $iv = $self->encryptIV;

                            $pos = 0;

                        }

                        $len = strlen($text);

                        $i = 0;

                        if ($pos) {

                            $orig_pos = $pos;

                            $max = ' . $block_size . ' - $pos;

                            if ($len >= $max) {

                                $i = $max;

                                $len-= $max;

                                $pos = 0;

                            } else {

                                $i = $len;

                                $pos+= $len;

                                $len = 0;

                            }

                            $ciphertext = substr($iv, $orig_pos) ^ $text;

                            $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);

                        }

                        while ($len >= ' . $block_size . ') {

                            $in = $iv;

                            ' . $_encryptBlock . ';

                            $iv = $in ^ substr($text, $i, ' . $block_size . ');

                            $ciphertext.= $iv;

                            $len-= ' . $block_size . ';

                            $i+= ' . $block_size . ';

                        }

                        if ($len) {

                            $in = $iv;

                            ' . $_encryptBlock . '

                            $iv = $in;

                            $block = $iv ^ substr($text, $i);

                            $iv = substr_replace($iv, $block, 0, $len);

                            $ciphertext.= $block;

                            $pos = $len;

                        }

                        return $ciphertext;

                    ';
                    $decrypt = $init_encryptBlock . '

                        $plaintext = "";

                        $buffer = &$self->debuffer;



                        if ($self->continuousBuffer) {

                            $iv = &$self->decryptIV;

                            $pos = &$buffer["pos"];

                        } else {

                            $iv = $self->decryptIV;

                            $pos = 0;

                        }

                        $len = strlen($text);

                        $i = 0;

                        if ($pos) {

                            $orig_pos = $pos;

                            $max = ' . $block_size . ' - $pos;

                            if ($len >= $max) {

                                $i = $max;

                                $len-= $max;

                                $pos = 0;

                            } else {

                                $i = $len;

                                $pos+= $len;

                                $len = 0;

                            }

                            $plaintext = substr($iv, $orig_pos) ^ $text;

                            $iv = substr_replace($iv, substr($text, 0, $i), $orig_pos, $i);

                        }

                        while ($len >= ' . $block_size . ') {

                            $in = $iv;

                            ' . $_encryptBlock . '

                            $iv = $in;

                            $cb = substr($text, $i, ' . $block_size . ');

                            $plaintext.= $iv ^ $cb;

                            $iv = $cb;

                            $len-= ' . $block_size . ';

                            $i+= ' . $block_size . ';

                        }

                        if ($len) {

                            $in = $iv;

                            ' . $_encryptBlock . '

                            $iv = $in;

                            $plaintext.= $iv ^ substr($text, $i);

                            $iv = substr_replace($iv, substr($text, $i), 0, $len);

                            $pos = $len;

                        }



                        return $plaintext;

                        ';
                    break;
                case CRYPT_RIJNDAEL_MODE_OFB:
                    $encrypt = $init_encryptBlock . '

                        $ciphertext = "";

                        $plaintext_len = strlen($text);

                        $xor = $self->encryptIV;

                        $buffer = &$self->enbuffer;



                        if (strlen($buffer["xor"])) {

                            for ($i = 0; $i < $plaintext_len; $i+= ' . $block_size . ') {

                                $block = substr($text, $i, ' . $block_size . ');

                                if (strlen($block) > strlen($buffer["xor"])) {

                                    $in = $xor;

                                    ' . $_encryptBlock . '

                                    $xor = $in;

                                    $buffer["xor"].= $xor;

                                }

                                $key = $self->_string_shift($buffer["xor"], ' . $block_size . ');

                                $ciphertext.= $block ^ $key;

                            }

                        } else {

                            for ($i = 0; $i < $plaintext_len; $i+= ' . $block_size . ') {

                                $in = $xor;

                                ' . $_encryptBlock . '

                                $xor = $in;

                                $ciphertext.= substr($text, $i, ' . $block_size . ') ^ $xor;

                            }

                            $key = $xor;

                        }

                        if ($self->continuousBuffer) {

                            $self->encryptIV = $xor;

                            if ($start = $plaintext_len % ' . $block_size . ') {

                                 $buffer["xor"] = substr($key, $start) . $buffer["xor"];

                            }

                        }

                        return $ciphertext;

                        ';
                    $decrypt = $init_encryptBlock . '

                        $plaintext = "";

                        $ciphertext_len = strlen($text);

                        $xor = $self->decryptIV;

                        $buffer = &$self->debuffer;



                        if (strlen($buffer["xor"])) {

                            for ($i = 0; $i < $ciphertext_len; $i+= ' . $block_size . ') {

                                $block = substr($text, $i, ' . $block_size . ');

                                if (strlen($block) > strlen($buffer["xor"])) {

                                    $in = $xor;

                                    ' . $_encryptBlock . '

                                    $xor = $in;

                                    $buffer["xor"].= $xor;

                                }

                                $key = $self->_string_shift($buffer["xor"], ' . $block_size . ');

                                $plaintext.= $block ^ $key;

                            }

                        } else {

                            for ($i = 0; $i < $ciphertext_len; $i+= ' . $block_size . ') {

                                $in = $xor;

                                ' . $_encryptBlock . '

                                $xor = $in;

                                $plaintext.= substr($text, $i, ' . $block_size . ') ^ $xor;

                            }

                            $key = $xor;

                        }

                        if ($self->continuousBuffer) {

                            $self->decryptIV = $xor;

                            if ($start = $ciphertext_len % ' . $block_size . ') {

                                 $buffer["xor"] = substr($key, $start) . $buffer["xor"];

                            }

                        }

                        return $plaintext;

                        ';
                    break;
            }
            $lambda_functions[$code_hash] = create_function('$action, &$self, $text', 'if ($action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' }');
        }
        $this->inline_crypt = $lambda_functions[$code_hash];
    }
Beispiel #3
0
 public function inline_crypt_setup()
 {
     $lambda_functions =& Crypt_Rijndael::get_lambda_functions();
     $block_size = $this->block_size;
     $mode = $this->mode;
     if (count($lambda_functions) < 5) {
         $w = $this->w;
         $dw = $this->dw;
         $init_encryptBlock = "";
         $init_decryptBlock = "";
     } else {
         $i = 0;
         for ($cw = count($this->w); $i < $cw; ++$i) {
             $w[] = "\$w_" . $i;
             $dw[] = "\$dw_" . $i;
         }
         $init_encryptBlock = "extract(\$self->w,  EXTR_PREFIX_ALL, \"w\");";
         $init_decryptBlock = "extract(\$self->dw, EXTR_PREFIX_ALL, \"dw\");";
     }
     $code_hash = md5("{$mode}, {$block_size}, " . implode(",", $w));
     if (!$lambda_functions[$code_hash]) {
         $Nr = $this->Nr;
         $Nb = $this->Nb;
         $c = $this->c;
         $init_encryptBlock .= "\n                \$t0 = \$self->t0;\n                \$t1 = \$self->t1;\n                \$t2 = \$self->t2;\n                \$t3 = \$self->t3;\n                \$sbox = \$self->sbox;";
         $s = "e";
         $e = "s";
         $wc = $Nb - 1;
         $_encryptBlock = "\$in = unpack(\"N*\", \$in);\n";
         for ($i = 0; $i < $Nb; ++$i) {
             $_encryptBlock .= "\$s" . $i . " = \$in[" . ($i + 1) . "] ^ " . $w[++$wc] . ";\n";
         }
         for ($round = 1; $round < $Nr; ++$round) {
             list($s, $e) = array($e, $s);
             for ($i = 0; $i < $Nb; ++$i) {
                 $_encryptBlock .= "\$" . $e . $i . " =\n                        \$t0[(\$" . $s . $i . " >> 24) & 0xff] ^\n                        \$t1[(\$" . $s . ($i + $c[1]) % $Nb . " >> 16) & 0xff] ^\n                        \$t2[(\$" . $s . ($i + $c[2]) % $Nb . " >>  8) & 0xff] ^\n                        \$t3[ \$" . $s . ($i + $c[3]) % $Nb . "        & 0xff] ^\n                        " . $w[++$wc] . ";\n";
             }
         }
         for ($i = 0; $i < $Nb; ++$i) {
             $_encryptBlock .= "\$" . $e . $i . " =\n                     \$sbox[ \$" . $e . $i . "        & 0xff]        |\n                    (\$sbox[(\$" . $e . $i . " >>  8) & 0xff] <<  8) |\n                    (\$sbox[(\$" . $e . $i . " >> 16) & 0xff] << 16) |\n                    (\$sbox[(\$" . $e . $i . " >> 24) & 0xff] << 24);\n";
         }
         $_encryptBlock .= "\$in = pack(\"N*\"\n";
         for ($i = 0; $i < $Nb; ++$i) {
             $_encryptBlock .= ",\n                    (\$" . $e . $i . " & 0xFF000000) ^\n                    (\$" . $e . ($i + $c[1]) % $Nb . " & 0x00FF0000) ^\n                    (\$" . $e . ($i + $c[2]) % $Nb . " & 0x0000FF00) ^\n                    (\$" . $e . ($i + $c[3]) % $Nb . " & 0x000000FF) ^\n                    " . $w[$i] . "\n";
         }
         $_encryptBlock .= ");";
         $init_decryptBlock .= "\n                \$dt0 = \$self->dt0;\n                \$dt1 = \$self->dt1;\n                \$dt2 = \$self->dt2;\n                \$dt3 = \$self->dt3;\n                \$isbox = \$self->isbox;";
         $s = "e";
         $e = "s";
         $wc = $Nb - 1;
         $_decryptBlock = "\$in = unpack(\"N*\", \$in);\n";
         for ($i = 0; $i < $Nb; ++$i) {
             $_decryptBlock .= "\$s" . $i . " = \$in[" . ($i + 1) . "] ^ " . $dw[++$wc] . ";\n";
         }
         for ($round = 1; $round < $Nr; ++$round) {
             list($s, $e) = array($e, $s);
             for ($i = 0; $i < $Nb; ++$i) {
                 $_decryptBlock .= "\$" . $e . $i . " =\n                        \$dt0[(\$" . $s . $i . " >> 24) & 0xff] ^\n                        \$dt1[(\$" . $s . ($Nb + $i - $c[1]) % $Nb . " >> 16) & 0xff] ^\n                        \$dt2[(\$" . $s . ($Nb + $i - $c[2]) % $Nb . " >>  8) & 0xff] ^\n                        \$dt3[ \$" . $s . ($Nb + $i - $c[3]) % $Nb . "        & 0xff] ^\n                        " . $dw[++$wc] . ";\n";
             }
         }
         for ($i = 0; $i < $Nb; ++$i) {
             $_decryptBlock .= "\$" . $e . $i . " =\n                     \$isbox[ \$" . $e . $i . "        & 0xff]        |\n                    (\$isbox[(\$" . $e . $i . " >>  8) & 0xff] <<  8) |\n                    (\$isbox[(\$" . $e . $i . " >> 16) & 0xff] << 16) |\n                    (\$isbox[(\$" . $e . $i . " >> 24) & 0xff] << 24);\n";
         }
         $_decryptBlock .= "\$in = pack(\"N*\"\n";
         for ($i = 0; $i < $Nb; ++$i) {
             $_decryptBlock .= ",\n                    (\$" . $e . $i . " & 0xFF000000) ^\n                    (\$" . $e . ($Nb + $i - $c[1]) % $Nb . " & 0x00FF0000) ^\n                    (\$" . $e . ($Nb + $i - $c[2]) % $Nb . " & 0x0000FF00) ^\n                    (\$" . $e . ($Nb + $i - $c[3]) % $Nb . " & 0x000000FF) ^\n                    " . $dw[$i] . "\n";
         }
         $_decryptBlock .= ");";
         switch ($mode) {
             case CRYPT_RIJNDAEL_MODE_ECB:
                 $encrypt = $init_encryptBlock . "\n                        \$ciphertext = \"\";\n                        \$text = \$self->_pad(\$text);\n                        \$plaintext_len = strlen(\$text);\n\n                        for (\$i = 0; \$i < \$plaintext_len; \$i+= " . $block_size . ") {\n                            \$in = substr(\$text, \$i, " . $block_size . ");\n                            " . $_encryptBlock . "\n                            \$ciphertext.= \$in;\n                        }\n                       \n                        return \$ciphertext;\n                        ";
                 $decrypt = $init_decryptBlock . "\n                        \$plaintext = \"\";\n                        \$text = str_pad(\$text, strlen(\$text) + (" . $block_size . " - strlen(\$text) % " . $block_size . ") % " . $block_size . ", chr(0));\n                        \$ciphertext_len = strlen(\$text);\n\n                        for (\$i = 0; \$i < \$ciphertext_len; \$i+= " . $block_size . ") {\n                            \$in = substr(\$text, \$i, " . $block_size . ");\n                            " . $_decryptBlock . "\n                            \$plaintext.= \$in;\n                        }\n\n                        return \$self->_unpad(\$plaintext);\n                        ";
                 break;
             case CRYPT_RIJNDAEL_MODE_CBC:
                 $encrypt = $init_encryptBlock . "\n                        \$ciphertext = \"\";\n                        \$text = \$self->_pad(\$text);\n                        \$plaintext_len = strlen(\$text);\n\n                        \$in = \$self->encryptIV;\n\n                        for (\$i = 0; \$i < \$plaintext_len; \$i+= " . $block_size . ") {\n                            \$in = substr(\$text, \$i, " . $block_size . ") ^ \$in;\n                            " . $_encryptBlock . "\n                            \$ciphertext.= \$in;\n                        }\n\n                        if (\$self->continuousBuffer) {\n                            \$self->encryptIV = \$in;\n                        }\n\n                        return \$ciphertext;\n                        ";
                 $decrypt = $init_decryptBlock . "\n                        \$plaintext = \"\";\n                        \$text = str_pad(\$text, strlen(\$text) + (" . $block_size . " - strlen(\$text) % " . $block_size . ") % " . $block_size . ", chr(0));\n                        \$ciphertext_len = strlen(\$text);\n\n                        \$iv = \$self->decryptIV;\n\n                        for (\$i = 0; \$i < \$ciphertext_len; \$i+= " . $block_size . ") {\n                            \$in = \$block = substr(\$text, \$i, " . $block_size . ");\n                            " . $_decryptBlock . "\n                            \$plaintext.= \$in ^ \$iv;\n                            \$iv = \$block;\n                        }\n\n                        if (\$self->continuousBuffer) {\n                            \$self->decryptIV = \$iv;\n                        }\n\n                        return \$self->_unpad(\$plaintext);\n                        ";
                 break;
             case CRYPT_RIJNDAEL_MODE_CTR:
                 $encrypt = $init_encryptBlock . "\n                        \$ciphertext = \"\";\n                        \$plaintext_len = strlen(\$text);\n                        \$xor = \$self->encryptIV;\n                        \$buffer = &\$self->enbuffer;\n\n                        if (strlen(\$buffer[\"encrypted\"])) {\n                            for (\$i = 0; \$i < \$plaintext_len; \$i+= " . $block_size . ") {\n                                \$block = substr(\$text, \$i, " . $block_size . ");\n                                if (strlen(\$block) > strlen(\$buffer[\"encrypted\"])) {\n                                    \$in = \$self->_generate_xor(" . $block_size . ", \$xor);\n                                    " . $_encryptBlock . "\n                                    \$buffer[\"encrypted\"].= \$in;\n                                }\n                                \$key = \$self->_string_shift(\$buffer[\"encrypted\"], " . $block_size . ");\n                                \$ciphertext.= \$block ^ \$key;\n                            }\n                        } else {\n                            for (\$i = 0; \$i < \$plaintext_len; \$i+= " . $block_size . ") {\n                                \$block = substr(\$text, \$i, " . $block_size . ");\n                                \$in = \$self->_generate_xor(" . $block_size . ", \$xor);\n                                " . $_encryptBlock . "\n                                \$key = \$in;\n                                \$ciphertext.= \$block ^ \$key;\n                            }\n                        }\n                        if (\$self->continuousBuffer) {\n                            \$self->encryptIV = \$xor;\n                            if (\$start = \$plaintext_len % " . $block_size . ") {\n                                \$buffer[\"encrypted\"] = substr(\$key, \$start) . \$buffer[\"encrypted\"];\n                            }\n                        }\n\n                        return \$ciphertext;\n                    ";
                 $decrypt = $init_encryptBlock . "\n                        \$plaintext = \"\";\n                        \$ciphertext_len = strlen(\$text);\n                        \$xor = \$self->decryptIV;\n                        \$buffer = &\$self->debuffer;\n\n                        if (strlen(\$buffer[\"ciphertext\"])) {\n                            for (\$i = 0; \$i < \$ciphertext_len; \$i+= " . $block_size . ") {\n                                \$block = substr(\$text, \$i, " . $block_size . ");\n                                if (strlen(\$block) > strlen(\$buffer[\"ciphertext\"])) {\n                                    \$in = \$self->_generate_xor(" . $block_size . ", \$xor);\n                                    " . $_encryptBlock . "\n                                    \$buffer[\"ciphertext\"].= \$in;\n                                }\n                                \$key = \$self->_string_shift(\$buffer[\"ciphertext\"], " . $block_size . ");\n                                \$plaintext.= \$block ^ \$key;\n                            }\n                        } else {\n                            for (\$i = 0; \$i < \$ciphertext_len; \$i+= " . $block_size . ") {\n                                \$block = substr(\$text, \$i, " . $block_size . ");\n                                \$in = \$self->_generate_xor(" . $block_size . ", \$xor);\n                                " . $_encryptBlock . "\n                                \$key = \$in;\n                                \$plaintext.= \$block ^ \$key;\n                            }\n                        }\n                        if (\$self->continuousBuffer) {\n                            \$self->decryptIV = \$xor;\n                            if (\$start = \$ciphertext_len % " . $block_size . ") {\n                                \$buffer[\"ciphertext\"] = substr(\$key, \$start) . \$buffer[\"ciphertext\"];\n                            }\n                        }\n                       \n                        return \$plaintext;\n                        ";
                 break;
             case CRYPT_RIJNDAEL_MODE_CFB:
                 $encrypt = $init_encryptBlock . "\n                        \$ciphertext = \"\";\n                        \$buffer = &\$self->enbuffer;\n\n                        if (\$self->continuousBuffer) {\n                            \$iv = &\$self->encryptIV;\n                            \$pos = &\$buffer[\"pos\"];\n                        } else {\n                            \$iv = \$self->encryptIV;\n                            \$pos = 0;\n                        }\n                        \$len = strlen(\$text);\n                        \$i = 0;\n                        if (\$pos) {\n                            \$orig_pos = \$pos;\n                            \$max = " . $block_size . " - \$pos;\n                            if (\$len >= \$max) {\n                                \$i = \$max;\n                                \$len-= \$max;\n                                \$pos = 0;\n                            } else {\n                                \$i = \$len;\n                                \$pos+= \$len;\n                                \$len = 0;\n                            }\n                            \$ciphertext = substr(\$iv, \$orig_pos) ^ \$text;\n                            \$iv = substr_replace(\$iv, \$ciphertext, \$orig_pos, \$i);\n                        }\n                        while (\$len >= " . $block_size . ") {\n                            \$in = \$iv;\n                            " . $_encryptBlock . ";\n                            \$iv = \$in ^ substr(\$text, \$i, " . $block_size . ");\n                            \$ciphertext.= \$iv;\n                            \$len-= " . $block_size . ";\n                            \$i+= " . $block_size . ";\n                        }\n                        if (\$len) {\n                            \$in = \$iv;\n                            " . $_encryptBlock . "\n                            \$iv = \$in;\n                            \$block = \$iv ^ substr(\$text, \$i);\n                            \$iv = substr_replace(\$iv, \$block, 0, \$len);\n                            \$ciphertext.= \$block;\n                            \$pos = \$len;\n                        }\n                        return \$ciphertext;\n                    ";
                 $decrypt = $init_encryptBlock . "\n                        \$plaintext = \"\";\n                        \$buffer = &\$self->debuffer;\n\n                        if (\$self->continuousBuffer) {\n                            \$iv = &\$self->decryptIV;\n                            \$pos = &\$buffer[\"pos\"];\n                        } else {\n                            \$iv = \$self->decryptIV;\n                            \$pos = 0;\n                        }\n                        \$len = strlen(\$text);\n                        \$i = 0;\n                        if (\$pos) {\n                            \$orig_pos = \$pos;\n                            \$max = " . $block_size . " - \$pos;\n                            if (\$len >= \$max) {\n                                \$i = \$max;\n                                \$len-= \$max;\n                                \$pos = 0;\n                            } else {\n                                \$i = \$len;\n                                \$pos+= \$len;\n                                \$len = 0;\n                            }\n                            \$plaintext = substr(\$iv, \$orig_pos) ^ \$text;\n                            \$iv = substr_replace(\$iv, substr(\$text, 0, \$i), \$orig_pos, \$i);\n                        }\n                        while (\$len >= " . $block_size . ") {\n                            \$in = \$iv;\n                            " . $_encryptBlock . "\n                            \$iv = \$in;\n                            \$cb = substr(\$text, \$i, " . $block_size . ");\n                            \$plaintext.= \$iv ^ \$cb;\n                            \$iv = \$cb;\n                            \$len-= " . $block_size . ";\n                            \$i+= " . $block_size . ";\n                        }\n                        if (\$len) {\n                            \$in = \$iv;\n                            " . $_encryptBlock . "\n                            \$iv = \$in;\n                            \$plaintext.= \$iv ^ substr(\$text, \$i);\n                            \$iv = substr_replace(\$iv, substr(\$text, \$i), 0, \$len);\n                            \$pos = \$len;\n                        }\n\n                        return \$plaintext;\n                        ";
                 break;
             case CRYPT_RIJNDAEL_MODE_OFB:
                 $encrypt = $init_encryptBlock . "\n                        \$ciphertext = \"\";\n                        \$plaintext_len = strlen(\$text);\n                        \$xor = \$self->encryptIV;\n                        \$buffer = &\$self->enbuffer;\n\n                        if (strlen(\$buffer[\"xor\"])) {\n                            for (\$i = 0; \$i < \$plaintext_len; \$i+= " . $block_size . ") {\n                                \$block = substr(\$text, \$i, " . $block_size . ");\n                                if (strlen(\$block) > strlen(\$buffer[\"xor\"])) {\n                                    \$in = \$xor;\n                                    " . $_encryptBlock . "\n                                    \$xor = \$in;\n                                    \$buffer[\"xor\"].= \$xor;\n                                }\n                                \$key = \$self->_string_shift(\$buffer[\"xor\"], " . $block_size . ");\n                                \$ciphertext.= \$block ^ \$key;\n                            }\n                        } else {\n                            for (\$i = 0; \$i < \$plaintext_len; \$i+= " . $block_size . ") {\n                                \$in = \$xor;\n                                " . $_encryptBlock . "\n                                \$xor = \$in;\n                                \$ciphertext.= substr(\$text, \$i, " . $block_size . ") ^ \$xor;\n                            }\n                            \$key = \$xor;\n                        }\n                        if (\$self->continuousBuffer) {\n                            \$self->encryptIV = \$xor;\n                            if (\$start = \$plaintext_len % " . $block_size . ") {\n                                 \$buffer[\"xor\"] = substr(\$key, \$start) . \$buffer[\"xor\"];\n                            }\n                        }\n                        return \$ciphertext;\n                        ";
                 $decrypt = $init_encryptBlock . "\n                        \$plaintext = \"\";\n                        \$ciphertext_len = strlen(\$text);\n                        \$xor = \$self->decryptIV;\n                        \$buffer = &\$self->debuffer;\n\n                        if (strlen(\$buffer[\"xor\"])) {\n                            for (\$i = 0; \$i < \$ciphertext_len; \$i+= " . $block_size . ") {\n                                \$block = substr(\$text, \$i, " . $block_size . ");\n                                if (strlen(\$block) > strlen(\$buffer[\"xor\"])) {\n                                    \$in = \$xor;\n                                    " . $_encryptBlock . "\n                                    \$xor = \$in;\n                                    \$buffer[\"xor\"].= \$xor;\n                                }\n                                \$key = \$self->_string_shift(\$buffer[\"xor\"], " . $block_size . ");\n                                \$plaintext.= \$block ^ \$key;\n                            }\n                        } else {\n                            for (\$i = 0; \$i < \$ciphertext_len; \$i+= " . $block_size . ") {\n                                \$in = \$xor;\n                                " . $_encryptBlock . "\n                                \$xor = \$in;\n                                \$plaintext.= substr(\$text, \$i, " . $block_size . ") ^ \$xor;\n                            }\n                            \$key = \$xor;\n                        }\n                        if (\$self->continuousBuffer) {\n                            \$self->decryptIV = \$xor;\n                            if (\$start = \$ciphertext_len % " . $block_size . ") {\n                                 \$buffer[\"xor\"] = substr(\$key, \$start) . \$buffer[\"xor\"];\n                            }\n                        }\n                        return \$plaintext;\n                        ";
                 break;
         }
         $lambda_functions[$code_hash] = create_function("\$action, &\$self, \$text", "if (\$action == \"encrypt\") { " . $encrypt . " } else { " . $decrypt . " }");
     }
     $this->inline_crypt = $lambda_functions[$code_hash];
 }