/** * Creates performance-optimized function for de/encrypt(), storing it in $this->inline_crypt * * @param optional Integer $des_rounds (1 = DES[default], 3 = TribleDES) * @access private */ function inline_crypt_setup($des_rounds = 1) { $lambda_functions =& Crypt_DES::get_lambda_functions(); $block_size = 8; $mode = $this->mode; $code_hash = "{$mode},{$des_rounds}"; if (!isset($lambda_functions[$code_hash])) { // Generating encrypt code: $ki = -1; $init_cryptBlock = ' $shuffle = $self->shuffle; $invipmap = $self->invipmap; $ipmap = $self->ipmap; $sbox1 = $self->sbox1; $sbox2 = $self->sbox2; $sbox3 = $self->sbox3; $sbox4 = $self->sbox4; $sbox5 = $self->sbox5; $sbox6 = $self->sbox6; $sbox7 = $self->sbox7; $sbox8 = $self->sbox8; '; $_cryptBlock = '$in = unpack("N*", $in);' . "\n"; // Do the initial IP permutation. $_cryptBlock .= ' $l = $in[1]; $r = $in[2]; $in = unpack("N*", ($shuffle[$ipmap[ $r & 0xFF]] & "\\x80\\x80\\x80\\x80\\x80\\x80\\x80\\x80") | ($shuffle[$ipmap[($r >> 8) & 0xFF]] & "\\x40\\x40\\x40\\x40\\x40\\x40\\x40\\x40") | ($shuffle[$ipmap[($r >> 16) & 0xFF]] & "\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20") | ($shuffle[$ipmap[($r >> 24) & 0xFF]] & "\\x10\\x10\\x10\\x10\\x10\\x10\\x10\\x10") | ($shuffle[$ipmap[ $l & 0xFF]] & "\\x08\\x08\\x08\\x08\\x08\\x08\\x08\\x08") | ($shuffle[$ipmap[($l >> 8) & 0xFF]] & "\\x04\\x04\\x04\\x04\\x04\\x04\\x04\\x04") | ($shuffle[$ipmap[($l >> 16) & 0xFF]] & "\\x02\\x02\\x02\\x02\\x02\\x02\\x02\\x02") | ($shuffle[$ipmap[($l >> 24) & 0xFF]] & "\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01") ); ' . '' . ' $l = $in[1]; $r = $in[2]; '; $l = 'l'; $r = 'r'; for ($des_round = 0; $des_round < $des_rounds; ++$des_round) { // Perform the 16 steps. // start of "the Feistel (F) function" - see the following URL: // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png // Merge key schedule. for ($i = 0; $i < 8; ++$i) { $_cryptBlock .= ' $b1 = (($' . $r . ' >> 3) & 0x1FFFFFFF) ^ ($' . $r . ' << 29) ^ $k_' . ++$ki . '; $b2 = (($' . $r . ' >> 31) & 0x00000001) ^ ($' . $r . ' << 1) ^ $k_' . ++$ki . '; $' . $l . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^ $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^ $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^ $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ $' . $l . '; $b1 = (($' . $l . ' >> 3) & 0x1FFFFFFF) ^ ($' . $l . ' << 29) ^ $k_' . ++$ki . '; $b2 = (($' . $l . ' >> 31) & 0x00000001) ^ ($' . $l . ' << 1) ^ $k_' . ++$ki . '; $' . $r . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^ $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^ $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^ $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ $' . $r . '; '; } // Last step should not permute L & R. $t = $l; $l = $r; $r = $t; } // Perform the inverse IP permutation. $_cryptBlock .= '$in = ( ($shuffle[$invipmap[($' . $r . ' >> 24) & 0xFF]] & "\\x80\\x80\\x80\\x80\\x80\\x80\\x80\\x80") | ($shuffle[$invipmap[($' . $l . ' >> 24) & 0xFF]] & "\\x40\\x40\\x40\\x40\\x40\\x40\\x40\\x40") | ($shuffle[$invipmap[($' . $r . ' >> 16) & 0xFF]] & "\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20") | ($shuffle[$invipmap[($' . $l . ' >> 16) & 0xFF]] & "\\x10\\x10\\x10\\x10\\x10\\x10\\x10\\x10") | ($shuffle[$invipmap[($' . $r . ' >> 8) & 0xFF]] & "\\x08\\x08\\x08\\x08\\x08\\x08\\x08\\x08") | ($shuffle[$invipmap[($' . $l . ' >> 8) & 0xFF]] & "\\x04\\x04\\x04\\x04\\x04\\x04\\x04\\x04") | ($shuffle[$invipmap[ $' . $r . ' & 0xFF]] & "\\x02\\x02\\x02\\x02\\x02\\x02\\x02\\x02") | ($shuffle[$invipmap[ $' . $l . ' & 0xFF]] & "\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01") ); '; // Generating mode of operation code: switch ($mode) { case CRYPT_DES_MODE_ECB: $encrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $ciphertext = ""; $plaintext_len = strlen($text); for ($i = 0; $i < $plaintext_len; $i+= ' . $block_size . ') { $in = substr($text, $i, ' . $block_size . '); ' . $_cryptBlock . ' $ciphertext.= $in; } return $ciphertext; '; $decrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_DECRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $plaintext = ""; $ciphertext_len = strlen($text); for ($i = 0; $i < $ciphertext_len; $i+= ' . $block_size . ') { $in = substr($text, $i, ' . $block_size . '); ' . $_cryptBlock . ' $plaintext.= $in; } return $self->_unpad($plaintext); '; break; case CRYPT_DES_MODE_CBC: $encrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $ciphertext = ""; $plaintext_len = strlen($text); $in = $self->encryptIV; for ($i = 0; $i < $plaintext_len; $i+= ' . $block_size . ') { $in = substr($text, $i, ' . $block_size . ') ^ $in; ' . $_cryptBlock . ' $ciphertext.= $in; } if ($self->continuousBuffer) { $self->encryptIV = $in; } return $ciphertext; '; $decrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_DECRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $plaintext = ""; $ciphertext_len = strlen($text); $iv = $self->decryptIV; for ($i = 0; $i < $ciphertext_len; $i+= ' . $block_size . ') { $in = $block = substr($text, $i, ' . $block_size . '); ' . $_cryptBlock . ' $plaintext.= $in ^ $iv; $iv = $block; } if ($self->continuousBuffer) { $self->decryptIV = $iv; } return $self->_unpad($plaintext); '; break; case CRYPT_DES_MODE_CTR: $encrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $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($xor); ' . $_cryptBlock . ' $buffer["encrypted"].= $in; } $key = $self->_string_shift($buffer["encrypted"]); $ciphertext.= $block ^ $key; } } else { for ($i = 0; $i < $plaintext_len; $i+= ' . $block_size . ') { $block = substr($text, $i, ' . $block_size . '); $in = $self->_generate_xor($xor); ' . $_cryptBlock . ' $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_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $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($xor); ' . $_cryptBlock . ' $buffer["ciphertext"].= $in; } $key = $self->_string_shift($buffer["ciphertext"]); $plaintext.= $block ^ $key; } } else { for ($i = 0; $i < $ciphertext_len; $i+= ' . $block_size . ') { $block = substr($text, $i, ' . $block_size . '); $in = $self->_generate_xor($xor); ' . $_cryptBlock . ' $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_DES_MODE_CFB: $encrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $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; ' . $_cryptBlock . '; $iv = $in ^ substr($text, $i, ' . $block_size . '); $ciphertext.= $iv; $len-= ' . $block_size . '; $i+= ' . $block_size . '; } if ($len) { $in = $iv; ' . $_cryptBlock . ' $iv = $in; $block = $iv ^ substr($text, $i); $iv = substr_replace($iv, $block, 0, $len); $ciphertext.= $block; $pos = $len; } return $ciphertext; '; $decrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $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; ' . $_cryptBlock . ' $iv = $in; $cb = substr($text, $i, ' . $block_size . '); $plaintext.= $iv ^ $cb; $iv = $cb; $len-= ' . $block_size . '; $i+= ' . $block_size . '; } if ($len) { $in = $iv; ' . $_cryptBlock . ' $iv = $in; $plaintext.= $iv ^ substr($text, $i); $iv = substr_replace($iv, substr($text, $i), 0, $len); $pos = $len; } return $plaintext; '; break; case CRYPT_DES_MODE_OFB: $encrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $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; ' . $_cryptBlock . ' $xor = $in; $buffer["xor"].= $xor; } $key = $self->_string_shift($buffer["xor"]); $ciphertext.= $block ^ $key; } } else { for ($i = 0; $i < $plaintext_len; $i+= ' . $block_size . ') { $in = $xor; ' . $_cryptBlock . ' $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_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $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; ' . $_cryptBlock . ' $xor = $in; $buffer["xor"].= $xor; } $key = $self->_string_shift($buffer["xor"]); $plaintext.= $block ^ $key; } } else { for ($i = 0; $i < $ciphertext_len; $i+= ' . $block_size . ') { $in = $xor; ' . $_cryptBlock . ' $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]; }
function inline_crypt_setup($des_rounds = 1) { $lambda_functions =& Crypt_DES::get_lambda_functions(); $block_size = 8; $mode = $this->mode; $code_hash = "$mode,$des_rounds"; if (!isset($lambda_functions[$code_hash])) { $ki = -1; $init_cryptBlock = ' $shuffle = $self->shuffle; $invipmap = $self->invipmap; $ipmap = $self->ipmap; $sbox1 = $self->sbox1; $sbox2 = $self->sbox2; $sbox3 = $self->sbox3; $sbox4 = $self->sbox4; $sbox5 = $self->sbox5; $sbox6 = $self->sbox6; $sbox7 = $self->sbox7; $sbox8 = $self->sbox8; '; $_cryptBlock = '$in = unpack("N*", $in);'."\n"; $_cryptBlock .= ' $l = $in[1]; $r = $in[2]; $in = unpack("N*", ($shuffle[$ipmap[ $r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") | ($shuffle[$ipmap[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") | ($shuffle[$ipmap[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") | ($shuffle[$ipmap[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") | ($shuffle[$ipmap[ $l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") | ($shuffle[$ipmap[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") | ($shuffle[$ipmap[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") | ($shuffle[$ipmap[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01") ); '.'' .' $l = $in[1]; $r = $in[2]; '; $l = 'l'; $r = 'r'; for ($des_round = 0; $des_round < $des_rounds; ++$des_round) { for ($i = 0; $i < 8; ++$i) { $_cryptBlock .= ' $b1 = (($' . $r . ' >> 3) & 0x1FFFFFFF) ^ ($' . $r . ' << 29) ^ $k_'.(++$ki).'; $b2 = (($' . $r . ' >> 31) & 0x00000001) ^ ($' . $r . ' << 1) ^ $k_'.(++$ki).'; $' . $l . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^ $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^ $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^ $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ $' . $l . '; $b1 = (($' . $l . ' >> 3) & 0x1FFFFFFF) ^ ($' . $l . ' << 29) ^ $k_'.(++$ki).'; $b2 = (($' . $l . ' >> 31) & 0x00000001) ^ ($' . $l . ' << 1) ^ $k_'.(++$ki).'; $' . $r . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^ $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^ $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^ $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ $' . $r . '; '; } $t = $l; $l = $r; $r = $t; } $_cryptBlock .= '$in = ( ($shuffle[$invipmap[($' . $r . ' >> 24) & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") | ($shuffle[$invipmap[($' . $l . ' >> 24) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") | ($shuffle[$invipmap[($' . $r . ' >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") | ($shuffle[$invipmap[($' . $l . ' >> 16) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") | ($shuffle[$invipmap[($' . $r . ' >> 8) & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") | ($shuffle[$invipmap[($' . $l . ' >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") | ($shuffle[$invipmap[ $' . $r . ' & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") | ($shuffle[$invipmap[ $' . $l . ' & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01") ); '; switch ($mode) { case CRYPT_DES_MODE_ECB: $encrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $ciphertext = ""; $plaintext_len = strlen($text); for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') { $in = substr($text, $i, '.$block_size.'); '.$_cryptBlock.' $ciphertext.= $in; } return $ciphertext; '; $decrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_DECRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $plaintext = ""; $ciphertext_len = strlen($text); for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') { $in = substr($text, $i, '.$block_size.'); '.$_cryptBlock.' $plaintext.= $in; } return $self->_unpad($plaintext); '; break; case CRYPT_DES_MODE_CBC: $encrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $ciphertext = ""; $plaintext_len = strlen($text); $in = $self->encryptIV; for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') { $in = substr($text, $i, '.$block_size.') ^ $in; '.$_cryptBlock.' $ciphertext.= $in; } if ($self->continuousBuffer) { $self->encryptIV = $in; } return $ciphertext; '; $decrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_DECRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $plaintext = ""; $ciphertext_len = strlen($text); $iv = $self->decryptIV; for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') { $in = $block = substr($text, $i, '.$block_size.'); '.$_cryptBlock.' $plaintext.= $in ^ $iv; $iv = $block; } if ($self->continuousBuffer) { $self->decryptIV = $iv; } return $self->_unpad($plaintext); '; break; case CRYPT_DES_MODE_CTR: $encrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $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($xor); '.$_cryptBlock.' $buffer["encrypted"].= $in; } $key = $self->_string_shift($buffer["encrypted"]); $ciphertext.= $block ^ $key; } } else { for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') { $block = substr($text, $i, '.$block_size.'); $in = $self->_generate_xor($xor); '.$_cryptBlock.' $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_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $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($xor); '.$_cryptBlock.' $buffer["ciphertext"].= $in; } $key = $self->_string_shift($buffer["ciphertext"]); $plaintext.= $block ^ $key; } } else { for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') { $block = substr($text, $i, '.$block_size.'); $in = $self->_generate_xor($xor); '.$_cryptBlock.' $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_DES_MODE_CFB: $encrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $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; '.$_cryptBlock.'; $iv = $in ^ substr($text, $i, '.$block_size.'); $ciphertext.= $iv; $len-= '.$block_size.'; $i+= '.$block_size.'; } if ($len) { $in = $iv; '.$_cryptBlock.' $iv = $in; $block = $iv ^ substr($text, $i); $iv = substr_replace($iv, $block, 0, $len); $ciphertext.= $block; $pos = $len; } return $ciphertext; '; $decrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $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; '.$_cryptBlock.' $iv = $in; $cb = substr($text, $i, '.$block_size.'); $plaintext.= $iv ^ $cb; $iv = $cb; $len-= '.$block_size.'; $i+= '.$block_size.'; } if ($len) { $in = $iv; '.$_cryptBlock.' $iv = $in; $plaintext.= $iv ^ substr($text, $i); $iv = substr_replace($iv, substr($text, $i), 0, $len); $pos = $len; } return $plaintext; '; break; case CRYPT_DES_MODE_OFB: $encrypt = $init_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $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; '.$_cryptBlock.' $xor = $in; $buffer["xor"].= $xor; } $key = $self->_string_shift($buffer["xor"]); $ciphertext.= $block ^ $key; } } else { for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') { $in = $xor; '.$_cryptBlock.' $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_cryptBlock . ' extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k"); $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; '.$_cryptBlock.' $xor = $in; $buffer["xor"].= $xor; } $key = $self->_string_shift($buffer["xor"]); $plaintext.= $block ^ $key; } } else { for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') { $in = $xor; '.$_cryptBlock.' $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($des_rounds) { $lambda_functions =& Crypt_DES::get_lambda_functions(); $block_size = 8; $mode = $this->mode; $code_hash = "{$mode},{$des_rounds}"; if (!$lambda_functions[$code_hash]) { $ki = -1; $init_cryptBlock = "\n \$shuffle = \$self->shuffle;\n \$invipmap = \$self->invipmap;\n \$ipmap = \$self->ipmap;\n \$sbox1 = \$self->sbox1;\n \$sbox2 = \$self->sbox2;\n \$sbox3 = \$self->sbox3;\n \$sbox4 = \$self->sbox4;\n \$sbox5 = \$self->sbox5;\n \$sbox6 = \$self->sbox6;\n \$sbox7 = \$self->sbox7;\n \$sbox8 = \$self->sbox8;\n "; $_cryptBlock = "\$in = unpack(\"N*\", \$in);\n"; $_cryptBlock .= "\n \$l = \$in[1];\n \$r = \$in[2];\n \$in = unpack(\"N*\",\n (\$shuffle[\$ipmap[ \$r & 0xFF]] & \"\\x80\\x80\\x80\\x80\\x80\\x80\\x80\\x80\") |\n (\$shuffle[\$ipmap[(\$r >> 8) & 0xFF]] & \"\\x40\\x40\\x40\\x40\\x40\\x40\\x40\\x40\") |\n (\$shuffle[\$ipmap[(\$r >> 16) & 0xFF]] & \"\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\") |\n (\$shuffle[\$ipmap[(\$r >> 24) & 0xFF]] & \"\\x10\\x10\\x10\\x10\\x10\\x10\\x10\\x10\") |\n (\$shuffle[\$ipmap[ \$l & 0xFF]] & \"\\x08\\x08\\x08\\x08\\x08\\x08\\x08\\x08\") |\n (\$shuffle[\$ipmap[(\$l >> 8) & 0xFF]] & \"\\x04\\x04\\x04\\x04\\x04\\x04\\x04\\x04\") |\n (\$shuffle[\$ipmap[(\$l >> 16) & 0xFF]] & \"\\x02\\x02\\x02\\x02\\x02\\x02\\x02\\x02\") |\n (\$shuffle[\$ipmap[(\$l >> 24) & 0xFF]] & \"\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\")\n );\n\n \n \$l = \$in[1];\n \$r = \$in[2];\n "; $l = "l"; $r = "r"; for ($des_round = 0; $des_round < $des_rounds; ++$des_round) { for ($i = 0; $i < 8; ++$i) { $_cryptBlock .= "\n \$b1 = ((\$" . $r . " >> 3) & 0x1FFFFFFF) ^ (\$" . $r . " << 29) ^ \$k_" . ++$ki . ";\n \$b2 = ((\$" . $r . " >> 31) & 0x00000001) ^ (\$" . $r . " << 1) ^ \$k_" . ++$ki . ";\n \$" . $l . " = \$sbox1[(\$b1 >> 24) & 0x3F] ^ \$sbox2[(\$b2 >> 24) & 0x3F] ^\n \$sbox3[(\$b1 >> 16) & 0x3F] ^ \$sbox4[(\$b2 >> 16) & 0x3F] ^\n \$sbox5[(\$b1 >> 8) & 0x3F] ^ \$sbox6[(\$b2 >> 8) & 0x3F] ^\n \$sbox7[ \$b1 & 0x3F] ^ \$sbox8[ \$b2 & 0x3F] ^ \$" . $l . ";\n\n \$b1 = ((\$" . $l . " >> 3) & 0x1FFFFFFF) ^ (\$" . $l . " << 29) ^ \$k_" . ++$ki . ";\n \$b2 = ((\$" . $l . " >> 31) & 0x00000001) ^ (\$" . $l . " << 1) ^ \$k_" . ++$ki . ";\n \$" . $r . " = \$sbox1[(\$b1 >> 24) & 0x3F] ^ \$sbox2[(\$b2 >> 24) & 0x3F] ^\n \$sbox3[(\$b1 >> 16) & 0x3F] ^ \$sbox4[(\$b2 >> 16) & 0x3F] ^\n \$sbox5[(\$b1 >> 8) & 0x3F] ^ \$sbox6[(\$b2 >> 8) & 0x3F] ^\n \$sbox7[ \$b1 & 0x3F] ^ \$sbox8[ \$b2 & 0x3F] ^ \$" . $r . ";\n "; } $t = $l; $l = $r; $r = $t; } $_cryptBlock .= "\$in = (\n (\$shuffle[\$invipmap[(\$" . $r . " >> 24) & 0xFF]] & \"\\x80\\x80\\x80\\x80\\x80\\x80\\x80\\x80\") |\n (\$shuffle[\$invipmap[(\$" . $l . " >> 24) & 0xFF]] & \"\\x40\\x40\\x40\\x40\\x40\\x40\\x40\\x40\") |\n (\$shuffle[\$invipmap[(\$" . $r . " >> 16) & 0xFF]] & \"\\x20\\x20\\x20\\x20\\x20\\x20\\x20\\x20\") |\n (\$shuffle[\$invipmap[(\$" . $l . " >> 16) & 0xFF]] & \"\\x10\\x10\\x10\\x10\\x10\\x10\\x10\\x10\") |\n (\$shuffle[\$invipmap[(\$" . $r . " >> 8) & 0xFF]] & \"\\x08\\x08\\x08\\x08\\x08\\x08\\x08\\x08\") |\n (\$shuffle[\$invipmap[(\$" . $l . " >> 8) & 0xFF]] & \"\\x04\\x04\\x04\\x04\\x04\\x04\\x04\\x04\") |\n (\$shuffle[\$invipmap[ \$" . $r . " & 0xFF]] & \"\\x02\\x02\\x02\\x02\\x02\\x02\\x02\\x02\") |\n (\$shuffle[\$invipmap[ \$" . $l . " & 0xFF]] & \"\\x01\\x01\\x01\\x01\\x01\\x01\\x01\\x01\")\n );\n "; switch ($mode) { case CRYPT_DES_MODE_ECB: $encrypt = $init_cryptBlock . "\n extract(\$self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, \"k\");\n \$ciphertext = \"\";\n \$plaintext_len = strlen(\$text);\n\n for (\$i = 0; \$i < \$plaintext_len; \$i+= " . $block_size . ") {\n \$in = substr(\$text, \$i, " . $block_size . ");\n " . $_cryptBlock . "\n \$ciphertext.= \$in;\n }\n \n return \$ciphertext;\n "; $decrypt = $init_cryptBlock . "\n extract(\$self->keys[CRYPT_DES_DECRYPT_1DIM], EXTR_PREFIX_ALL, \"k\");\n \$plaintext = \"\";\n \$ciphertext_len = strlen(\$text);\n\n for (\$i = 0; \$i < \$ciphertext_len; \$i+= " . $block_size . ") {\n \$in = substr(\$text, \$i, " . $block_size . ");\n " . $_cryptBlock . "\n \$plaintext.= \$in;\n }\n\n return \$self->_unpad(\$plaintext);\n "; break; case CRYPT_DES_MODE_CBC: $encrypt = $init_cryptBlock . "\n extract(\$self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, \"k\");\n \$ciphertext = \"\";\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 " . $_cryptBlock . "\n \$ciphertext.= \$in;\n }\n\n if (\$self->continuousBuffer) {\n \$self->encryptIV = \$in;\n }\n\n return \$ciphertext;\n "; $decrypt = $init_cryptBlock . "\n extract(\$self->keys[CRYPT_DES_DECRYPT_1DIM], EXTR_PREFIX_ALL, \"k\");\n \$plaintext = \"\";\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 " . $_cryptBlock . "\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_DES_MODE_CTR: $encrypt = $init_cryptBlock . "\n extract(\$self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, \"k\");\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(\$xor);\n " . $_cryptBlock . "\n \$buffer[\"encrypted\"].= \$in;\n }\n \$key = \$self->_string_shift(\$buffer[\"encrypted\"]);\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(\$xor);\n " . $_cryptBlock . "\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_cryptBlock . "\n extract(\$self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, \"k\");\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(\$xor);\n " . $_cryptBlock . "\n \$buffer[\"ciphertext\"].= \$in;\n }\n \$key = \$self->_string_shift(\$buffer[\"ciphertext\"]);\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(\$xor);\n " . $_cryptBlock . "\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_DES_MODE_CFB: $encrypt = $init_cryptBlock . "\n extract(\$self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, \"k\");\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 " . $_cryptBlock . ";\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 " . $_cryptBlock . "\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_cryptBlock . "\n extract(\$self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, \"k\");\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 " . $_cryptBlock . "\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 " . $_cryptBlock . "\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_DES_MODE_OFB: $encrypt = $init_cryptBlock . "\n extract(\$self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, \"k\");\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 " . $_cryptBlock . "\n \$xor = \$in;\n \$buffer[\"xor\"].= \$xor;\n }\n \$key = \$self->_string_shift(\$buffer[\"xor\"]);\n \$ciphertext.= \$block ^ \$key;\n }\n } else {\n for (\$i = 0; \$i < \$plaintext_len; \$i+= " . $block_size . ") {\n \$in = \$xor;\n " . $_cryptBlock . "\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_cryptBlock . "\n extract(\$self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, \"k\");\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 " . $_cryptBlock . "\n \$xor = \$in;\n \$buffer[\"xor\"].= \$xor;\n }\n \$key = \$self->_string_shift(\$buffer[\"xor\"]);\n \$plaintext.= \$block ^ \$key;\n }\n } else {\n for (\$i = 0; \$i < \$ciphertext_len; \$i+= " . $block_size . ") {\n \$in = \$xor;\n " . $_cryptBlock . "\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]; }