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]; }
/** * 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]; }
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]; }