diff --git a/composer.json b/composer.json
index 843fd311..79c92b52 100644
--- a/composer.json
+++ b/composer.json
@@ -47,5 +47,10 @@
"files": [
"phpseclib/Crypt/Random.php"
]
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "0.3-dev"
+ }
}
}
diff --git a/phpseclib/Crypt/DES.php b/phpseclib/Crypt/DES.php
index be99d6a5..ff42d627 100644
--- a/phpseclib/Crypt/DES.php
+++ b/phpseclib/Crypt/DES.php
@@ -73,6 +73,14 @@ define('CRYPT_DES_ENCRYPT', 0);
* Contains array_reverse($keys[CRYPT_DES_ENCRYPT])
*/
define('CRYPT_DES_DECRYPT', 1);
+/**
+ * Contains $keys[CRYPT_DES_ENCRYPT] as 1-dim array
+ */
+define('CRYPT_DES_ENCRYPT_1DIM', 2);
+/**
+ * Contains $keys[CRYPT_DES_DECRYPT] as 1-dim array
+ */
+define('CRYPT_DES_DECRYPT_1DIM', 3);
/**#@-*/
/**#@+
@@ -281,17 +289,452 @@ class Crypt_DES {
*/
var $ecb;
+ /**
+ * Performance-optimized callback function for en/decrypt()
+ *
+ * @var Callback
+ * @access private
+ */
+ var $inline_crypt;
+
+ /**
+ * Holds whether performance-optimized $inline_crypt should be used or not.
+ *
+ * @var Boolean
+ * @access private
+ */
+ var $use_inline_crypt = false;
+
/**
* Shuffle table.
+ *
* For each byte value index, the entry holds an 8-byte string
* with each byte containing all bits in the same state as the
* corresponding bit in the index value.
+ *
* @see Crypt_DES::_processBlock()
* @see Crypt_DES::_prepareKey()
* @var Array
* @access private
*/
- var $shuffle;
+ var $shuffle = array(
+ "\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\xFF",
+ "\x00\x00\x00\x00\x00\x00\xFF\x00", "\x00\x00\x00\x00\x00\x00\xFF\xFF",
+ "\x00\x00\x00\x00\x00\xFF\x00\x00", "\x00\x00\x00\x00\x00\xFF\x00\xFF",
+ "\x00\x00\x00\x00\x00\xFF\xFF\x00", "\x00\x00\x00\x00\x00\xFF\xFF\xFF",
+ "\x00\x00\x00\x00\xFF\x00\x00\x00", "\x00\x00\x00\x00\xFF\x00\x00\xFF",
+ "\x00\x00\x00\x00\xFF\x00\xFF\x00", "\x00\x00\x00\x00\xFF\x00\xFF\xFF",
+ "\x00\x00\x00\x00\xFF\xFF\x00\x00", "\x00\x00\x00\x00\xFF\xFF\x00\xFF",
+ "\x00\x00\x00\x00\xFF\xFF\xFF\x00", "\x00\x00\x00\x00\xFF\xFF\xFF\xFF",
+ "\x00\x00\x00\xFF\x00\x00\x00\x00", "\x00\x00\x00\xFF\x00\x00\x00\xFF",
+ "\x00\x00\x00\xFF\x00\x00\xFF\x00", "\x00\x00\x00\xFF\x00\x00\xFF\xFF",
+ "\x00\x00\x00\xFF\x00\xFF\x00\x00", "\x00\x00\x00\xFF\x00\xFF\x00\xFF",
+ "\x00\x00\x00\xFF\x00\xFF\xFF\x00", "\x00\x00\x00\xFF\x00\xFF\xFF\xFF",
+ "\x00\x00\x00\xFF\xFF\x00\x00\x00", "\x00\x00\x00\xFF\xFF\x00\x00\xFF",
+ "\x00\x00\x00\xFF\xFF\x00\xFF\x00", "\x00\x00\x00\xFF\xFF\x00\xFF\xFF",
+ "\x00\x00\x00\xFF\xFF\xFF\x00\x00", "\x00\x00\x00\xFF\xFF\xFF\x00\xFF",
+ "\x00\x00\x00\xFF\xFF\xFF\xFF\x00", "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF",
+ "\x00\x00\xFF\x00\x00\x00\x00\x00", "\x00\x00\xFF\x00\x00\x00\x00\xFF",
+ "\x00\x00\xFF\x00\x00\x00\xFF\x00", "\x00\x00\xFF\x00\x00\x00\xFF\xFF",
+ "\x00\x00\xFF\x00\x00\xFF\x00\x00", "\x00\x00\xFF\x00\x00\xFF\x00\xFF",
+ "\x00\x00\xFF\x00\x00\xFF\xFF\x00", "\x00\x00\xFF\x00\x00\xFF\xFF\xFF",
+ "\x00\x00\xFF\x00\xFF\x00\x00\x00", "\x00\x00\xFF\x00\xFF\x00\x00\xFF",
+ "\x00\x00\xFF\x00\xFF\x00\xFF\x00", "\x00\x00\xFF\x00\xFF\x00\xFF\xFF",
+ "\x00\x00\xFF\x00\xFF\xFF\x00\x00", "\x00\x00\xFF\x00\xFF\xFF\x00\xFF",
+ "\x00\x00\xFF\x00\xFF\xFF\xFF\x00", "\x00\x00\xFF\x00\xFF\xFF\xFF\xFF",
+ "\x00\x00\xFF\xFF\x00\x00\x00\x00", "\x00\x00\xFF\xFF\x00\x00\x00\xFF",
+ "\x00\x00\xFF\xFF\x00\x00\xFF\x00", "\x00\x00\xFF\xFF\x00\x00\xFF\xFF",
+ "\x00\x00\xFF\xFF\x00\xFF\x00\x00", "\x00\x00\xFF\xFF\x00\xFF\x00\xFF",
+ "\x00\x00\xFF\xFF\x00\xFF\xFF\x00", "\x00\x00\xFF\xFF\x00\xFF\xFF\xFF",
+ "\x00\x00\xFF\xFF\xFF\x00\x00\x00", "\x00\x00\xFF\xFF\xFF\x00\x00\xFF",
+ "\x00\x00\xFF\xFF\xFF\x00\xFF\x00", "\x00\x00\xFF\xFF\xFF\x00\xFF\xFF",
+ "\x00\x00\xFF\xFF\xFF\xFF\x00\x00", "\x00\x00\xFF\xFF\xFF\xFF\x00\xFF",
+ "\x00\x00\xFF\xFF\xFF\xFF\xFF\x00", "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF",
+ "\x00\xFF\x00\x00\x00\x00\x00\x00", "\x00\xFF\x00\x00\x00\x00\x00\xFF",
+ "\x00\xFF\x00\x00\x00\x00\xFF\x00", "\x00\xFF\x00\x00\x00\x00\xFF\xFF",
+ "\x00\xFF\x00\x00\x00\xFF\x00\x00", "\x00\xFF\x00\x00\x00\xFF\x00\xFF",
+ "\x00\xFF\x00\x00\x00\xFF\xFF\x00", "\x00\xFF\x00\x00\x00\xFF\xFF\xFF",
+ "\x00\xFF\x00\x00\xFF\x00\x00\x00", "\x00\xFF\x00\x00\xFF\x00\x00\xFF",
+ "\x00\xFF\x00\x00\xFF\x00\xFF\x00", "\x00\xFF\x00\x00\xFF\x00\xFF\xFF",
+ "\x00\xFF\x00\x00\xFF\xFF\x00\x00", "\x00\xFF\x00\x00\xFF\xFF\x00\xFF",
+ "\x00\xFF\x00\x00\xFF\xFF\xFF\x00", "\x00\xFF\x00\x00\xFF\xFF\xFF\xFF",
+ "\x00\xFF\x00\xFF\x00\x00\x00\x00", "\x00\xFF\x00\xFF\x00\x00\x00\xFF",
+ "\x00\xFF\x00\xFF\x00\x00\xFF\x00", "\x00\xFF\x00\xFF\x00\x00\xFF\xFF",
+ "\x00\xFF\x00\xFF\x00\xFF\x00\x00", "\x00\xFF\x00\xFF\x00\xFF\x00\xFF",
+ "\x00\xFF\x00\xFF\x00\xFF\xFF\x00", "\x00\xFF\x00\xFF\x00\xFF\xFF\xFF",
+ "\x00\xFF\x00\xFF\xFF\x00\x00\x00", "\x00\xFF\x00\xFF\xFF\x00\x00\xFF",
+ "\x00\xFF\x00\xFF\xFF\x00\xFF\x00", "\x00\xFF\x00\xFF\xFF\x00\xFF\xFF",
+ "\x00\xFF\x00\xFF\xFF\xFF\x00\x00", "\x00\xFF\x00\xFF\xFF\xFF\x00\xFF",
+ "\x00\xFF\x00\xFF\xFF\xFF\xFF\x00", "\x00\xFF\x00\xFF\xFF\xFF\xFF\xFF",
+ "\x00\xFF\xFF\x00\x00\x00\x00\x00", "\x00\xFF\xFF\x00\x00\x00\x00\xFF",
+ "\x00\xFF\xFF\x00\x00\x00\xFF\x00", "\x00\xFF\xFF\x00\x00\x00\xFF\xFF",
+ "\x00\xFF\xFF\x00\x00\xFF\x00\x00", "\x00\xFF\xFF\x00\x00\xFF\x00\xFF",
+ "\x00\xFF\xFF\x00\x00\xFF\xFF\x00", "\x00\xFF\xFF\x00\x00\xFF\xFF\xFF",
+ "\x00\xFF\xFF\x00\xFF\x00\x00\x00", "\x00\xFF\xFF\x00\xFF\x00\x00\xFF",
+ "\x00\xFF\xFF\x00\xFF\x00\xFF\x00", "\x00\xFF\xFF\x00\xFF\x00\xFF\xFF",
+ "\x00\xFF\xFF\x00\xFF\xFF\x00\x00", "\x00\xFF\xFF\x00\xFF\xFF\x00\xFF",
+ "\x00\xFF\xFF\x00\xFF\xFF\xFF\x00", "\x00\xFF\xFF\x00\xFF\xFF\xFF\xFF",
+ "\x00\xFF\xFF\xFF\x00\x00\x00\x00", "\x00\xFF\xFF\xFF\x00\x00\x00\xFF",
+ "\x00\xFF\xFF\xFF\x00\x00\xFF\x00", "\x00\xFF\xFF\xFF\x00\x00\xFF\xFF",
+ "\x00\xFF\xFF\xFF\x00\xFF\x00\x00", "\x00\xFF\xFF\xFF\x00\xFF\x00\xFF",
+ "\x00\xFF\xFF\xFF\x00\xFF\xFF\x00", "\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF",
+ "\x00\xFF\xFF\xFF\xFF\x00\x00\x00", "\x00\xFF\xFF\xFF\xFF\x00\x00\xFF",
+ "\x00\xFF\xFF\xFF\xFF\x00\xFF\x00", "\x00\xFF\xFF\xFF\xFF\x00\xFF\xFF",
+ "\x00\xFF\xFF\xFF\xFF\xFF\x00\x00", "\x00\xFF\xFF\xFF\xFF\xFF\x00\xFF",
+ "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
+ "\xFF\x00\x00\x00\x00\x00\x00\x00", "\xFF\x00\x00\x00\x00\x00\x00\xFF",
+ "\xFF\x00\x00\x00\x00\x00\xFF\x00", "\xFF\x00\x00\x00\x00\x00\xFF\xFF",
+ "\xFF\x00\x00\x00\x00\xFF\x00\x00", "\xFF\x00\x00\x00\x00\xFF\x00\xFF",
+ "\xFF\x00\x00\x00\x00\xFF\xFF\x00", "\xFF\x00\x00\x00\x00\xFF\xFF\xFF",
+ "\xFF\x00\x00\x00\xFF\x00\x00\x00", "\xFF\x00\x00\x00\xFF\x00\x00\xFF",
+ "\xFF\x00\x00\x00\xFF\x00\xFF\x00", "\xFF\x00\x00\x00\xFF\x00\xFF\xFF",
+ "\xFF\x00\x00\x00\xFF\xFF\x00\x00", "\xFF\x00\x00\x00\xFF\xFF\x00\xFF",
+ "\xFF\x00\x00\x00\xFF\xFF\xFF\x00", "\xFF\x00\x00\x00\xFF\xFF\xFF\xFF",
+ "\xFF\x00\x00\xFF\x00\x00\x00\x00", "\xFF\x00\x00\xFF\x00\x00\x00\xFF",
+ "\xFF\x00\x00\xFF\x00\x00\xFF\x00", "\xFF\x00\x00\xFF\x00\x00\xFF\xFF",
+ "\xFF\x00\x00\xFF\x00\xFF\x00\x00", "\xFF\x00\x00\xFF\x00\xFF\x00\xFF",
+ "\xFF\x00\x00\xFF\x00\xFF\xFF\x00", "\xFF\x00\x00\xFF\x00\xFF\xFF\xFF",
+ "\xFF\x00\x00\xFF\xFF\x00\x00\x00", "\xFF\x00\x00\xFF\xFF\x00\x00\xFF",
+ "\xFF\x00\x00\xFF\xFF\x00\xFF\x00", "\xFF\x00\x00\xFF\xFF\x00\xFF\xFF",
+ "\xFF\x00\x00\xFF\xFF\xFF\x00\x00", "\xFF\x00\x00\xFF\xFF\xFF\x00\xFF",
+ "\xFF\x00\x00\xFF\xFF\xFF\xFF\x00", "\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF",
+ "\xFF\x00\xFF\x00\x00\x00\x00\x00", "\xFF\x00\xFF\x00\x00\x00\x00\xFF",
+ "\xFF\x00\xFF\x00\x00\x00\xFF\x00", "\xFF\x00\xFF\x00\x00\x00\xFF\xFF",
+ "\xFF\x00\xFF\x00\x00\xFF\x00\x00", "\xFF\x00\xFF\x00\x00\xFF\x00\xFF",
+ "\xFF\x00\xFF\x00\x00\xFF\xFF\x00", "\xFF\x00\xFF\x00\x00\xFF\xFF\xFF",
+ "\xFF\x00\xFF\x00\xFF\x00\x00\x00", "\xFF\x00\xFF\x00\xFF\x00\x00\xFF",
+ "\xFF\x00\xFF\x00\xFF\x00\xFF\x00", "\xFF\x00\xFF\x00\xFF\x00\xFF\xFF",
+ "\xFF\x00\xFF\x00\xFF\xFF\x00\x00", "\xFF\x00\xFF\x00\xFF\xFF\x00\xFF",
+ "\xFF\x00\xFF\x00\xFF\xFF\xFF\x00", "\xFF\x00\xFF\x00\xFF\xFF\xFF\xFF",
+ "\xFF\x00\xFF\xFF\x00\x00\x00\x00", "\xFF\x00\xFF\xFF\x00\x00\x00\xFF",
+ "\xFF\x00\xFF\xFF\x00\x00\xFF\x00", "\xFF\x00\xFF\xFF\x00\x00\xFF\xFF",
+ "\xFF\x00\xFF\xFF\x00\xFF\x00\x00", "\xFF\x00\xFF\xFF\x00\xFF\x00\xFF",
+ "\xFF\x00\xFF\xFF\x00\xFF\xFF\x00", "\xFF\x00\xFF\xFF\x00\xFF\xFF\xFF",
+ "\xFF\x00\xFF\xFF\xFF\x00\x00\x00", "\xFF\x00\xFF\xFF\xFF\x00\x00\xFF",
+ "\xFF\x00\xFF\xFF\xFF\x00\xFF\x00", "\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF",
+ "\xFF\x00\xFF\xFF\xFF\xFF\x00\x00", "\xFF\x00\xFF\xFF\xFF\xFF\x00\xFF",
+ "\xFF\x00\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF",
+ "\xFF\xFF\x00\x00\x00\x00\x00\x00", "\xFF\xFF\x00\x00\x00\x00\x00\xFF",
+ "\xFF\xFF\x00\x00\x00\x00\xFF\x00", "\xFF\xFF\x00\x00\x00\x00\xFF\xFF",
+ "\xFF\xFF\x00\x00\x00\xFF\x00\x00", "\xFF\xFF\x00\x00\x00\xFF\x00\xFF",
+ "\xFF\xFF\x00\x00\x00\xFF\xFF\x00", "\xFF\xFF\x00\x00\x00\xFF\xFF\xFF",
+ "\xFF\xFF\x00\x00\xFF\x00\x00\x00", "\xFF\xFF\x00\x00\xFF\x00\x00\xFF",
+ "\xFF\xFF\x00\x00\xFF\x00\xFF\x00", "\xFF\xFF\x00\x00\xFF\x00\xFF\xFF",
+ "\xFF\xFF\x00\x00\xFF\xFF\x00\x00", "\xFF\xFF\x00\x00\xFF\xFF\x00\xFF",
+ "\xFF\xFF\x00\x00\xFF\xFF\xFF\x00", "\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF",
+ "\xFF\xFF\x00\xFF\x00\x00\x00\x00", "\xFF\xFF\x00\xFF\x00\x00\x00\xFF",
+ "\xFF\xFF\x00\xFF\x00\x00\xFF\x00", "\xFF\xFF\x00\xFF\x00\x00\xFF\xFF",
+ "\xFF\xFF\x00\xFF\x00\xFF\x00\x00", "\xFF\xFF\x00\xFF\x00\xFF\x00\xFF",
+ "\xFF\xFF\x00\xFF\x00\xFF\xFF\x00", "\xFF\xFF\x00\xFF\x00\xFF\xFF\xFF",
+ "\xFF\xFF\x00\xFF\xFF\x00\x00\x00", "\xFF\xFF\x00\xFF\xFF\x00\x00\xFF",
+ "\xFF\xFF\x00\xFF\xFF\x00\xFF\x00", "\xFF\xFF\x00\xFF\xFF\x00\xFF\xFF",
+ "\xFF\xFF\x00\xFF\xFF\xFF\x00\x00", "\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF",
+ "\xFF\xFF\x00\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF",
+ "\xFF\xFF\xFF\x00\x00\x00\x00\x00", "\xFF\xFF\xFF\x00\x00\x00\x00\xFF",
+ "\xFF\xFF\xFF\x00\x00\x00\xFF\x00", "\xFF\xFF\xFF\x00\x00\x00\xFF\xFF",
+ "\xFF\xFF\xFF\x00\x00\xFF\x00\x00", "\xFF\xFF\xFF\x00\x00\xFF\x00\xFF",
+ "\xFF\xFF\xFF\x00\x00\xFF\xFF\x00", "\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF",
+ "\xFF\xFF\xFF\x00\xFF\x00\x00\x00", "\xFF\xFF\xFF\x00\xFF\x00\x00\xFF",
+ "\xFF\xFF\xFF\x00\xFF\x00\xFF\x00", "\xFF\xFF\xFF\x00\xFF\x00\xFF\xFF",
+ "\xFF\xFF\xFF\x00\xFF\xFF\x00\x00", "\xFF\xFF\xFF\x00\xFF\xFF\x00\xFF",
+ "\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF",
+ "\xFF\xFF\xFF\xFF\x00\x00\x00\x00", "\xFF\xFF\xFF\xFF\x00\x00\x00\xFF",
+ "\xFF\xFF\xFF\xFF\x00\x00\xFF\x00", "\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF",
+ "\xFF\xFF\xFF\xFF\x00\xFF\x00\x00", "\xFF\xFF\xFF\xFF\x00\xFF\x00\xFF",
+ "\xFF\xFF\xFF\xFF\x00\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF",
+ "\xFF\xFF\xFF\xFF\xFF\x00\x00\x00", "\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF",
+ "\xFF\xFF\xFF\xFF\xFF\x00\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF",
+ "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF",
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ );
+
+ /**
+ * IP mapping helper table.
+ *
+ * Indexing this table with each source byte performs the initial bit permutation.
+ *
+ * @var Array
+ * @access private
+ */
+ var $ipmap = array(
+ 0x00, 0x10, 0x01, 0x11, 0x20, 0x30, 0x21, 0x31,
+ 0x02, 0x12, 0x03, 0x13, 0x22, 0x32, 0x23, 0x33,
+ 0x40, 0x50, 0x41, 0x51, 0x60, 0x70, 0x61, 0x71,
+ 0x42, 0x52, 0x43, 0x53, 0x62, 0x72, 0x63, 0x73,
+ 0x04, 0x14, 0x05, 0x15, 0x24, 0x34, 0x25, 0x35,
+ 0x06, 0x16, 0x07, 0x17, 0x26, 0x36, 0x27, 0x37,
+ 0x44, 0x54, 0x45, 0x55, 0x64, 0x74, 0x65, 0x75,
+ 0x46, 0x56, 0x47, 0x57, 0x66, 0x76, 0x67, 0x77,
+ 0x80, 0x90, 0x81, 0x91, 0xA0, 0xB0, 0xA1, 0xB1,
+ 0x82, 0x92, 0x83, 0x93, 0xA2, 0xB2, 0xA3, 0xB3,
+ 0xC0, 0xD0, 0xC1, 0xD1, 0xE0, 0xF0, 0xE1, 0xF1,
+ 0xC2, 0xD2, 0xC3, 0xD3, 0xE2, 0xF2, 0xE3, 0xF3,
+ 0x84, 0x94, 0x85, 0x95, 0xA4, 0xB4, 0xA5, 0xB5,
+ 0x86, 0x96, 0x87, 0x97, 0xA6, 0xB6, 0xA7, 0xB7,
+ 0xC4, 0xD4, 0xC5, 0xD5, 0xE4, 0xF4, 0xE5, 0xF5,
+ 0xC6, 0xD6, 0xC7, 0xD7, 0xE6, 0xF6, 0xE7, 0xF7,
+ 0x08, 0x18, 0x09, 0x19, 0x28, 0x38, 0x29, 0x39,
+ 0x0A, 0x1A, 0x0B, 0x1B, 0x2A, 0x3A, 0x2B, 0x3B,
+ 0x48, 0x58, 0x49, 0x59, 0x68, 0x78, 0x69, 0x79,
+ 0x4A, 0x5A, 0x4B, 0x5B, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0x0C, 0x1C, 0x0D, 0x1D, 0x2C, 0x3C, 0x2D, 0x3D,
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4C, 0x5C, 0x4D, 0x5D, 0x6C, 0x7C, 0x6D, 0x7D,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x88, 0x98, 0x89, 0x99, 0xA8, 0xB8, 0xA9, 0xB9,
+ 0x8A, 0x9A, 0x8B, 0x9B, 0xAA, 0xBA, 0xAB, 0xBB,
+ 0xC8, 0xD8, 0xC9, 0xD9, 0xE8, 0xF8, 0xE9, 0xF9,
+ 0xCA, 0xDA, 0xCB, 0xDB, 0xEA, 0xFA, 0xEB, 0xFB,
+ 0x8C, 0x9C, 0x8D, 0x9D, 0xAC, 0xBC, 0xAD, 0xBD,
+ 0x8E, 0x9E, 0x8F, 0x9F, 0xAE, 0xBE, 0xAF, 0xBF,
+ 0xCC, 0xDC, 0xCD, 0xDD, 0xEC, 0xFC, 0xED, 0xFD,
+ 0xCE, 0xDE, 0xCF, 0xDF, 0xEE, 0xFE, 0xEF, 0xFF
+ );
+
+ /**
+ * Inverse IP mapping helper table.
+ * Indexing this table with a byte value reverses the bit order.
+ *
+ * @var Array
+ * @access private
+ */
+ var $invipmap = array(
+ 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
+ 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
+ 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
+ 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
+ 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
+ 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
+ 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
+ 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
+ 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
+ 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
+ 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
+ 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
+ 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
+ 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
+ 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
+ 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
+ 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
+ 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
+ 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
+ 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
+ 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
+ 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
+ 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
+ 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
+ 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
+ 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
+ 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
+ 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
+ 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
+ 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
+ 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
+ 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
+ );
+
+ /**
+ * Pre-permuted S-box1
+ *
+ * Each box ($sbox1-$sbox8) has been vectorized, then each value pre-permuted using the
+ * P table: concatenation can then be replaced by exclusive ORs.
+ *
+ * @var Array
+ * @access private
+ */
+ var $sbox1 = array(
+ 0x00808200, 0x00000000, 0x00008000, 0x00808202,
+ 0x00808002, 0x00008202, 0x00000002, 0x00008000,
+ 0x00000200, 0x00808200, 0x00808202, 0x00000200,
+ 0x00800202, 0x00808002, 0x00800000, 0x00000002,
+ 0x00000202, 0x00800200, 0x00800200, 0x00008200,
+ 0x00008200, 0x00808000, 0x00808000, 0x00800202,
+ 0x00008002, 0x00800002, 0x00800002, 0x00008002,
+ 0x00000000, 0x00000202, 0x00008202, 0x00800000,
+ 0x00008000, 0x00808202, 0x00000002, 0x00808000,
+ 0x00808200, 0x00800000, 0x00800000, 0x00000200,
+ 0x00808002, 0x00008000, 0x00008200, 0x00800002,
+ 0x00000200, 0x00000002, 0x00800202, 0x00008202,
+ 0x00808202, 0x00008002, 0x00808000, 0x00800202,
+ 0x00800002, 0x00000202, 0x00008202, 0x00808200,
+ 0x00000202, 0x00800200, 0x00800200, 0x00000000,
+ 0x00008002, 0x00008200, 0x00000000, 0x00808002
+ );
+
+ /**
+ * Pre-permuted S-box2
+ *
+ * @var Array
+ * @access private
+ */
+ var $sbox2 = array(
+ 0x40084010, 0x40004000, 0x00004000, 0x00084010,
+ 0x00080000, 0x00000010, 0x40080010, 0x40004010,
+ 0x40000010, 0x40084010, 0x40084000, 0x40000000,
+ 0x40004000, 0x00080000, 0x00000010, 0x40080010,
+ 0x00084000, 0x00080010, 0x40004010, 0x00000000,
+ 0x40000000, 0x00004000, 0x00084010, 0x40080000,
+ 0x00080010, 0x40000010, 0x00000000, 0x00084000,
+ 0x00004010, 0x40084000, 0x40080000, 0x00004010,
+ 0x00000000, 0x00084010, 0x40080010, 0x00080000,
+ 0x40004010, 0x40080000, 0x40084000, 0x00004000,
+ 0x40080000, 0x40004000, 0x00000010, 0x40084010,
+ 0x00084010, 0x00000010, 0x00004000, 0x40000000,
+ 0x00004010, 0x40084000, 0x00080000, 0x40000010,
+ 0x00080010, 0x40004010, 0x40000010, 0x00080010,
+ 0x00084000, 0x00000000, 0x40004000, 0x00004010,
+ 0x40000000, 0x40080010, 0x40084010, 0x00084000
+ );
+
+ /**
+ * Pre-permuted S-box3
+ *
+ * @var Array
+ * @access private
+ */
+ var $sbox3 = array(
+ 0x00000104, 0x04010100, 0x00000000, 0x04010004,
+ 0x04000100, 0x00000000, 0x00010104, 0x04000100,
+ 0x00010004, 0x04000004, 0x04000004, 0x00010000,
+ 0x04010104, 0x00010004, 0x04010000, 0x00000104,
+ 0x04000000, 0x00000004, 0x04010100, 0x00000100,
+ 0x00010100, 0x04010000, 0x04010004, 0x00010104,
+ 0x04000104, 0x00010100, 0x00010000, 0x04000104,
+ 0x00000004, 0x04010104, 0x00000100, 0x04000000,
+ 0x04010100, 0x04000000, 0x00010004, 0x00000104,
+ 0x00010000, 0x04010100, 0x04000100, 0x00000000,
+ 0x00000100, 0x00010004, 0x04010104, 0x04000100,
+ 0x04000004, 0x00000100, 0x00000000, 0x04010004,
+ 0x04000104, 0x00010000, 0x04000000, 0x04010104,
+ 0x00000004, 0x00010104, 0x00010100, 0x04000004,
+ 0x04010000, 0x04000104, 0x00000104, 0x04010000,
+ 0x00010104, 0x00000004, 0x04010004, 0x00010100
+ );
+
+ /**
+ * Pre-permuted S-box4
+ *
+ * @var Array
+ * @access private
+ */
+ var $sbox4 = array(
+ 0x80401000, 0x80001040, 0x80001040, 0x00000040,
+ 0x00401040, 0x80400040, 0x80400000, 0x80001000,
+ 0x00000000, 0x00401000, 0x00401000, 0x80401040,
+ 0x80000040, 0x00000000, 0x00400040, 0x80400000,
+ 0x80000000, 0x00001000, 0x00400000, 0x80401000,
+ 0x00000040, 0x00400000, 0x80001000, 0x00001040,
+ 0x80400040, 0x80000000, 0x00001040, 0x00400040,
+ 0x00001000, 0x00401040, 0x80401040, 0x80000040,
+ 0x00400040, 0x80400000, 0x00401000, 0x80401040,
+ 0x80000040, 0x00000000, 0x00000000, 0x00401000,
+ 0x00001040, 0x00400040, 0x80400040, 0x80000000,
+ 0x80401000, 0x80001040, 0x80001040, 0x00000040,
+ 0x80401040, 0x80000040, 0x80000000, 0x00001000,
+ 0x80400000, 0x80001000, 0x00401040, 0x80400040,
+ 0x80001000, 0x00001040, 0x00400000, 0x80401000,
+ 0x00000040, 0x00400000, 0x00001000, 0x00401040
+ );
+
+ /**
+ * Pre-permuted S-box5
+ *
+ * @var Array
+ * @access private
+ */
+ var $sbox5 = array(
+ 0x00000080, 0x01040080, 0x01040000, 0x21000080,
+ 0x00040000, 0x00000080, 0x20000000, 0x01040000,
+ 0x20040080, 0x00040000, 0x01000080, 0x20040080,
+ 0x21000080, 0x21040000, 0x00040080, 0x20000000,
+ 0x01000000, 0x20040000, 0x20040000, 0x00000000,
+ 0x20000080, 0x21040080, 0x21040080, 0x01000080,
+ 0x21040000, 0x20000080, 0x00000000, 0x21000000,
+ 0x01040080, 0x01000000, 0x21000000, 0x00040080,
+ 0x00040000, 0x21000080, 0x00000080, 0x01000000,
+ 0x20000000, 0x01040000, 0x21000080, 0x20040080,
+ 0x01000080, 0x20000000, 0x21040000, 0x01040080,
+ 0x20040080, 0x00000080, 0x01000000, 0x21040000,
+ 0x21040080, 0x00040080, 0x21000000, 0x21040080,
+ 0x01040000, 0x00000000, 0x20040000, 0x21000000,
+ 0x00040080, 0x01000080, 0x20000080, 0x00040000,
+ 0x00000000, 0x20040000, 0x01040080, 0x20000080
+ );
+
+ /**
+ * Pre-permuted S-box6
+ *
+ * @var Array
+ * @access private
+ */
+ var $sbox6 = array(
+ 0x10000008, 0x10200000, 0x00002000, 0x10202008,
+ 0x10200000, 0x00000008, 0x10202008, 0x00200000,
+ 0x10002000, 0x00202008, 0x00200000, 0x10000008,
+ 0x00200008, 0x10002000, 0x10000000, 0x00002008,
+ 0x00000000, 0x00200008, 0x10002008, 0x00002000,
+ 0x00202000, 0x10002008, 0x00000008, 0x10200008,
+ 0x10200008, 0x00000000, 0x00202008, 0x10202000,
+ 0x00002008, 0x00202000, 0x10202000, 0x10000000,
+ 0x10002000, 0x00000008, 0x10200008, 0x00202000,
+ 0x10202008, 0x00200000, 0x00002008, 0x10000008,
+ 0x00200000, 0x10002000, 0x10000000, 0x00002008,
+ 0x10000008, 0x10202008, 0x00202000, 0x10200000,
+ 0x00202008, 0x10202000, 0x00000000, 0x10200008,
+ 0x00000008, 0x00002000, 0x10200000, 0x00202008,
+ 0x00002000, 0x00200008, 0x10002008, 0x00000000,
+ 0x10202000, 0x10000000, 0x00200008, 0x10002008
+ );
+
+ /**
+ * Pre-permuted S-box7
+ *
+ * @var Array
+ * @access private
+ */
+ var $sbox7 = array(
+ 0x00100000, 0x02100001, 0x02000401, 0x00000000,
+ 0x00000400, 0x02000401, 0x00100401, 0x02100400,
+ 0x02100401, 0x00100000, 0x00000000, 0x02000001,
+ 0x00000001, 0x02000000, 0x02100001, 0x00000401,
+ 0x02000400, 0x00100401, 0x00100001, 0x02000400,
+ 0x02000001, 0x02100000, 0x02100400, 0x00100001,
+ 0x02100000, 0x00000400, 0x00000401, 0x02100401,
+ 0x00100400, 0x00000001, 0x02000000, 0x00100400,
+ 0x02000000, 0x00100400, 0x00100000, 0x02000401,
+ 0x02000401, 0x02100001, 0x02100001, 0x00000001,
+ 0x00100001, 0x02000000, 0x02000400, 0x00100000,
+ 0x02100400, 0x00000401, 0x00100401, 0x02100400,
+ 0x00000401, 0x02000001, 0x02100401, 0x02100000,
+ 0x00100400, 0x00000000, 0x00000001, 0x02100401,
+ 0x00000000, 0x00100401, 0x02100000, 0x00000400,
+ 0x02000001, 0x02000400, 0x00000400, 0x00100001
+ );
+
+ /**
+ * Pre-permuted S-box8
+ *
+ * @var Array
+ * @access private
+ */
+ var $sbox8 = array(
+ 0x08000820, 0x00000800, 0x00020000, 0x08020820,
+ 0x08000000, 0x08000820, 0x00000020, 0x08000000,
+ 0x00020020, 0x08020000, 0x08020820, 0x00020800,
+ 0x08020800, 0x00020820, 0x00000800, 0x00000020,
+ 0x08020000, 0x08000020, 0x08000800, 0x00000820,
+ 0x00020800, 0x00020020, 0x08020020, 0x08020800,
+ 0x00000820, 0x00000000, 0x00000000, 0x08020020,
+ 0x08000020, 0x08000800, 0x00020820, 0x00020000,
+ 0x00020820, 0x00020000, 0x08020800, 0x00000800,
+ 0x00000020, 0x08020020, 0x00000800, 0x00020820,
+ 0x08000800, 0x00000020, 0x08000020, 0x08020000,
+ 0x08020020, 0x08000000, 0x00020000, 0x08000820,
+ 0x00000000, 0x08020820, 0x00020020, 0x08000020,
+ 0x08020000, 0x08000800, 0x08000820, 0x00000000,
+ 0x08020820, 0x00020800, 0x00020800, 0x00000820,
+ 0x00000820, 0x00020020, 0x08000000, 0x08020800
+ );
/**
* Default Constructor.
@@ -305,143 +748,6 @@ class Crypt_DES {
*/
function Crypt_DES($mode = CRYPT_DES_MODE_CBC)
{
-
- /**
- * Shuffle table.
- * For each byte value index, the entry holds an 8-byte string
- * with each byte containing all bits in the same state as the
- * corresponding bit in the index value.
- */
- static $shuffle = array(
- "\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\xFF",
- "\x00\x00\x00\x00\x00\x00\xFF\x00", "\x00\x00\x00\x00\x00\x00\xFF\xFF",
- "\x00\x00\x00\x00\x00\xFF\x00\x00", "\x00\x00\x00\x00\x00\xFF\x00\xFF",
- "\x00\x00\x00\x00\x00\xFF\xFF\x00", "\x00\x00\x00\x00\x00\xFF\xFF\xFF",
- "\x00\x00\x00\x00\xFF\x00\x00\x00", "\x00\x00\x00\x00\xFF\x00\x00\xFF",
- "\x00\x00\x00\x00\xFF\x00\xFF\x00", "\x00\x00\x00\x00\xFF\x00\xFF\xFF",
- "\x00\x00\x00\x00\xFF\xFF\x00\x00", "\x00\x00\x00\x00\xFF\xFF\x00\xFF",
- "\x00\x00\x00\x00\xFF\xFF\xFF\x00", "\x00\x00\x00\x00\xFF\xFF\xFF\xFF",
- "\x00\x00\x00\xFF\x00\x00\x00\x00", "\x00\x00\x00\xFF\x00\x00\x00\xFF",
- "\x00\x00\x00\xFF\x00\x00\xFF\x00", "\x00\x00\x00\xFF\x00\x00\xFF\xFF",
- "\x00\x00\x00\xFF\x00\xFF\x00\x00", "\x00\x00\x00\xFF\x00\xFF\x00\xFF",
- "\x00\x00\x00\xFF\x00\xFF\xFF\x00", "\x00\x00\x00\xFF\x00\xFF\xFF\xFF",
- "\x00\x00\x00\xFF\xFF\x00\x00\x00", "\x00\x00\x00\xFF\xFF\x00\x00\xFF",
- "\x00\x00\x00\xFF\xFF\x00\xFF\x00", "\x00\x00\x00\xFF\xFF\x00\xFF\xFF",
- "\x00\x00\x00\xFF\xFF\xFF\x00\x00", "\x00\x00\x00\xFF\xFF\xFF\x00\xFF",
- "\x00\x00\x00\xFF\xFF\xFF\xFF\x00", "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF",
- "\x00\x00\xFF\x00\x00\x00\x00\x00", "\x00\x00\xFF\x00\x00\x00\x00\xFF",
- "\x00\x00\xFF\x00\x00\x00\xFF\x00", "\x00\x00\xFF\x00\x00\x00\xFF\xFF",
- "\x00\x00\xFF\x00\x00\xFF\x00\x00", "\x00\x00\xFF\x00\x00\xFF\x00\xFF",
- "\x00\x00\xFF\x00\x00\xFF\xFF\x00", "\x00\x00\xFF\x00\x00\xFF\xFF\xFF",
- "\x00\x00\xFF\x00\xFF\x00\x00\x00", "\x00\x00\xFF\x00\xFF\x00\x00\xFF",
- "\x00\x00\xFF\x00\xFF\x00\xFF\x00", "\x00\x00\xFF\x00\xFF\x00\xFF\xFF",
- "\x00\x00\xFF\x00\xFF\xFF\x00\x00", "\x00\x00\xFF\x00\xFF\xFF\x00\xFF",
- "\x00\x00\xFF\x00\xFF\xFF\xFF\x00", "\x00\x00\xFF\x00\xFF\xFF\xFF\xFF",
- "\x00\x00\xFF\xFF\x00\x00\x00\x00", "\x00\x00\xFF\xFF\x00\x00\x00\xFF",
- "\x00\x00\xFF\xFF\x00\x00\xFF\x00", "\x00\x00\xFF\xFF\x00\x00\xFF\xFF",
- "\x00\x00\xFF\xFF\x00\xFF\x00\x00", "\x00\x00\xFF\xFF\x00\xFF\x00\xFF",
- "\x00\x00\xFF\xFF\x00\xFF\xFF\x00", "\x00\x00\xFF\xFF\x00\xFF\xFF\xFF",
- "\x00\x00\xFF\xFF\xFF\x00\x00\x00", "\x00\x00\xFF\xFF\xFF\x00\x00\xFF",
- "\x00\x00\xFF\xFF\xFF\x00\xFF\x00", "\x00\x00\xFF\xFF\xFF\x00\xFF\xFF",
- "\x00\x00\xFF\xFF\xFF\xFF\x00\x00", "\x00\x00\xFF\xFF\xFF\xFF\x00\xFF",
- "\x00\x00\xFF\xFF\xFF\xFF\xFF\x00", "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF",
- "\x00\xFF\x00\x00\x00\x00\x00\x00", "\x00\xFF\x00\x00\x00\x00\x00\xFF",
- "\x00\xFF\x00\x00\x00\x00\xFF\x00", "\x00\xFF\x00\x00\x00\x00\xFF\xFF",
- "\x00\xFF\x00\x00\x00\xFF\x00\x00", "\x00\xFF\x00\x00\x00\xFF\x00\xFF",
- "\x00\xFF\x00\x00\x00\xFF\xFF\x00", "\x00\xFF\x00\x00\x00\xFF\xFF\xFF",
- "\x00\xFF\x00\x00\xFF\x00\x00\x00", "\x00\xFF\x00\x00\xFF\x00\x00\xFF",
- "\x00\xFF\x00\x00\xFF\x00\xFF\x00", "\x00\xFF\x00\x00\xFF\x00\xFF\xFF",
- "\x00\xFF\x00\x00\xFF\xFF\x00\x00", "\x00\xFF\x00\x00\xFF\xFF\x00\xFF",
- "\x00\xFF\x00\x00\xFF\xFF\xFF\x00", "\x00\xFF\x00\x00\xFF\xFF\xFF\xFF",
- "\x00\xFF\x00\xFF\x00\x00\x00\x00", "\x00\xFF\x00\xFF\x00\x00\x00\xFF",
- "\x00\xFF\x00\xFF\x00\x00\xFF\x00", "\x00\xFF\x00\xFF\x00\x00\xFF\xFF",
- "\x00\xFF\x00\xFF\x00\xFF\x00\x00", "\x00\xFF\x00\xFF\x00\xFF\x00\xFF",
- "\x00\xFF\x00\xFF\x00\xFF\xFF\x00", "\x00\xFF\x00\xFF\x00\xFF\xFF\xFF",
- "\x00\xFF\x00\xFF\xFF\x00\x00\x00", "\x00\xFF\x00\xFF\xFF\x00\x00\xFF",
- "\x00\xFF\x00\xFF\xFF\x00\xFF\x00", "\x00\xFF\x00\xFF\xFF\x00\xFF\xFF",
- "\x00\xFF\x00\xFF\xFF\xFF\x00\x00", "\x00\xFF\x00\xFF\xFF\xFF\x00\xFF",
- "\x00\xFF\x00\xFF\xFF\xFF\xFF\x00", "\x00\xFF\x00\xFF\xFF\xFF\xFF\xFF",
- "\x00\xFF\xFF\x00\x00\x00\x00\x00", "\x00\xFF\xFF\x00\x00\x00\x00\xFF",
- "\x00\xFF\xFF\x00\x00\x00\xFF\x00", "\x00\xFF\xFF\x00\x00\x00\xFF\xFF",
- "\x00\xFF\xFF\x00\x00\xFF\x00\x00", "\x00\xFF\xFF\x00\x00\xFF\x00\xFF",
- "\x00\xFF\xFF\x00\x00\xFF\xFF\x00", "\x00\xFF\xFF\x00\x00\xFF\xFF\xFF",
- "\x00\xFF\xFF\x00\xFF\x00\x00\x00", "\x00\xFF\xFF\x00\xFF\x00\x00\xFF",
- "\x00\xFF\xFF\x00\xFF\x00\xFF\x00", "\x00\xFF\xFF\x00\xFF\x00\xFF\xFF",
- "\x00\xFF\xFF\x00\xFF\xFF\x00\x00", "\x00\xFF\xFF\x00\xFF\xFF\x00\xFF",
- "\x00\xFF\xFF\x00\xFF\xFF\xFF\x00", "\x00\xFF\xFF\x00\xFF\xFF\xFF\xFF",
- "\x00\xFF\xFF\xFF\x00\x00\x00\x00", "\x00\xFF\xFF\xFF\x00\x00\x00\xFF",
- "\x00\xFF\xFF\xFF\x00\x00\xFF\x00", "\x00\xFF\xFF\xFF\x00\x00\xFF\xFF",
- "\x00\xFF\xFF\xFF\x00\xFF\x00\x00", "\x00\xFF\xFF\xFF\x00\xFF\x00\xFF",
- "\x00\xFF\xFF\xFF\x00\xFF\xFF\x00", "\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF",
- "\x00\xFF\xFF\xFF\xFF\x00\x00\x00", "\x00\xFF\xFF\xFF\xFF\x00\x00\xFF",
- "\x00\xFF\xFF\xFF\xFF\x00\xFF\x00", "\x00\xFF\xFF\xFF\xFF\x00\xFF\xFF",
- "\x00\xFF\xFF\xFF\xFF\xFF\x00\x00", "\x00\xFF\xFF\xFF\xFF\xFF\x00\xFF",
- "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
- "\xFF\x00\x00\x00\x00\x00\x00\x00", "\xFF\x00\x00\x00\x00\x00\x00\xFF",
- "\xFF\x00\x00\x00\x00\x00\xFF\x00", "\xFF\x00\x00\x00\x00\x00\xFF\xFF",
- "\xFF\x00\x00\x00\x00\xFF\x00\x00", "\xFF\x00\x00\x00\x00\xFF\x00\xFF",
- "\xFF\x00\x00\x00\x00\xFF\xFF\x00", "\xFF\x00\x00\x00\x00\xFF\xFF\xFF",
- "\xFF\x00\x00\x00\xFF\x00\x00\x00", "\xFF\x00\x00\x00\xFF\x00\x00\xFF",
- "\xFF\x00\x00\x00\xFF\x00\xFF\x00", "\xFF\x00\x00\x00\xFF\x00\xFF\xFF",
- "\xFF\x00\x00\x00\xFF\xFF\x00\x00", "\xFF\x00\x00\x00\xFF\xFF\x00\xFF",
- "\xFF\x00\x00\x00\xFF\xFF\xFF\x00", "\xFF\x00\x00\x00\xFF\xFF\xFF\xFF",
- "\xFF\x00\x00\xFF\x00\x00\x00\x00", "\xFF\x00\x00\xFF\x00\x00\x00\xFF",
- "\xFF\x00\x00\xFF\x00\x00\xFF\x00", "\xFF\x00\x00\xFF\x00\x00\xFF\xFF",
- "\xFF\x00\x00\xFF\x00\xFF\x00\x00", "\xFF\x00\x00\xFF\x00\xFF\x00\xFF",
- "\xFF\x00\x00\xFF\x00\xFF\xFF\x00", "\xFF\x00\x00\xFF\x00\xFF\xFF\xFF",
- "\xFF\x00\x00\xFF\xFF\x00\x00\x00", "\xFF\x00\x00\xFF\xFF\x00\x00\xFF",
- "\xFF\x00\x00\xFF\xFF\x00\xFF\x00", "\xFF\x00\x00\xFF\xFF\x00\xFF\xFF",
- "\xFF\x00\x00\xFF\xFF\xFF\x00\x00", "\xFF\x00\x00\xFF\xFF\xFF\x00\xFF",
- "\xFF\x00\x00\xFF\xFF\xFF\xFF\x00", "\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF",
- "\xFF\x00\xFF\x00\x00\x00\x00\x00", "\xFF\x00\xFF\x00\x00\x00\x00\xFF",
- "\xFF\x00\xFF\x00\x00\x00\xFF\x00", "\xFF\x00\xFF\x00\x00\x00\xFF\xFF",
- "\xFF\x00\xFF\x00\x00\xFF\x00\x00", "\xFF\x00\xFF\x00\x00\xFF\x00\xFF",
- "\xFF\x00\xFF\x00\x00\xFF\xFF\x00", "\xFF\x00\xFF\x00\x00\xFF\xFF\xFF",
- "\xFF\x00\xFF\x00\xFF\x00\x00\x00", "\xFF\x00\xFF\x00\xFF\x00\x00\xFF",
- "\xFF\x00\xFF\x00\xFF\x00\xFF\x00", "\xFF\x00\xFF\x00\xFF\x00\xFF\xFF",
- "\xFF\x00\xFF\x00\xFF\xFF\x00\x00", "\xFF\x00\xFF\x00\xFF\xFF\x00\xFF",
- "\xFF\x00\xFF\x00\xFF\xFF\xFF\x00", "\xFF\x00\xFF\x00\xFF\xFF\xFF\xFF",
- "\xFF\x00\xFF\xFF\x00\x00\x00\x00", "\xFF\x00\xFF\xFF\x00\x00\x00\xFF",
- "\xFF\x00\xFF\xFF\x00\x00\xFF\x00", "\xFF\x00\xFF\xFF\x00\x00\xFF\xFF",
- "\xFF\x00\xFF\xFF\x00\xFF\x00\x00", "\xFF\x00\xFF\xFF\x00\xFF\x00\xFF",
- "\xFF\x00\xFF\xFF\x00\xFF\xFF\x00", "\xFF\x00\xFF\xFF\x00\xFF\xFF\xFF",
- "\xFF\x00\xFF\xFF\xFF\x00\x00\x00", "\xFF\x00\xFF\xFF\xFF\x00\x00\xFF",
- "\xFF\x00\xFF\xFF\xFF\x00\xFF\x00", "\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF",
- "\xFF\x00\xFF\xFF\xFF\xFF\x00\x00", "\xFF\x00\xFF\xFF\xFF\xFF\x00\xFF",
- "\xFF\x00\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF",
- "\xFF\xFF\x00\x00\x00\x00\x00\x00", "\xFF\xFF\x00\x00\x00\x00\x00\xFF",
- "\xFF\xFF\x00\x00\x00\x00\xFF\x00", "\xFF\xFF\x00\x00\x00\x00\xFF\xFF",
- "\xFF\xFF\x00\x00\x00\xFF\x00\x00", "\xFF\xFF\x00\x00\x00\xFF\x00\xFF",
- "\xFF\xFF\x00\x00\x00\xFF\xFF\x00", "\xFF\xFF\x00\x00\x00\xFF\xFF\xFF",
- "\xFF\xFF\x00\x00\xFF\x00\x00\x00", "\xFF\xFF\x00\x00\xFF\x00\x00\xFF",
- "\xFF\xFF\x00\x00\xFF\x00\xFF\x00", "\xFF\xFF\x00\x00\xFF\x00\xFF\xFF",
- "\xFF\xFF\x00\x00\xFF\xFF\x00\x00", "\xFF\xFF\x00\x00\xFF\xFF\x00\xFF",
- "\xFF\xFF\x00\x00\xFF\xFF\xFF\x00", "\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF",
- "\xFF\xFF\x00\xFF\x00\x00\x00\x00", "\xFF\xFF\x00\xFF\x00\x00\x00\xFF",
- "\xFF\xFF\x00\xFF\x00\x00\xFF\x00", "\xFF\xFF\x00\xFF\x00\x00\xFF\xFF",
- "\xFF\xFF\x00\xFF\x00\xFF\x00\x00", "\xFF\xFF\x00\xFF\x00\xFF\x00\xFF",
- "\xFF\xFF\x00\xFF\x00\xFF\xFF\x00", "\xFF\xFF\x00\xFF\x00\xFF\xFF\xFF",
- "\xFF\xFF\x00\xFF\xFF\x00\x00\x00", "\xFF\xFF\x00\xFF\xFF\x00\x00\xFF",
- "\xFF\xFF\x00\xFF\xFF\x00\xFF\x00", "\xFF\xFF\x00\xFF\xFF\x00\xFF\xFF",
- "\xFF\xFF\x00\xFF\xFF\xFF\x00\x00", "\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF",
- "\xFF\xFF\x00\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF",
- "\xFF\xFF\xFF\x00\x00\x00\x00\x00", "\xFF\xFF\xFF\x00\x00\x00\x00\xFF",
- "\xFF\xFF\xFF\x00\x00\x00\xFF\x00", "\xFF\xFF\xFF\x00\x00\x00\xFF\xFF",
- "\xFF\xFF\xFF\x00\x00\xFF\x00\x00", "\xFF\xFF\xFF\x00\x00\xFF\x00\xFF",
- "\xFF\xFF\xFF\x00\x00\xFF\xFF\x00", "\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF",
- "\xFF\xFF\xFF\x00\xFF\x00\x00\x00", "\xFF\xFF\xFF\x00\xFF\x00\x00\xFF",
- "\xFF\xFF\xFF\x00\xFF\x00\xFF\x00", "\xFF\xFF\xFF\x00\xFF\x00\xFF\xFF",
- "\xFF\xFF\xFF\x00\xFF\xFF\x00\x00", "\xFF\xFF\xFF\x00\xFF\xFF\x00\xFF",
- "\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF",
- "\xFF\xFF\xFF\xFF\x00\x00\x00\x00", "\xFF\xFF\xFF\xFF\x00\x00\x00\xFF",
- "\xFF\xFF\xFF\xFF\x00\x00\xFF\x00", "\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF",
- "\xFF\xFF\xFF\xFF\x00\xFF\x00\x00", "\xFF\xFF\xFF\xFF\x00\xFF\x00\xFF",
- "\xFF\xFF\xFF\xFF\x00\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF",
- "\xFF\xFF\xFF\xFF\xFF\x00\x00\x00", "\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF",
- "\xFF\xFF\xFF\xFF\xFF\x00\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF",
- "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF",
- "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
- );
if ( !defined('CRYPT_DES_MODE') ) {
switch (true) {
case extension_loaded('mcrypt') && in_array('des', mcrypt_list_algorithms()):
@@ -480,7 +786,6 @@ class Crypt_DES {
break;
default:
- $this->shuffle = $shuffle;
switch ($mode) {
case CRYPT_DES_MODE_ECB:
case CRYPT_DES_MODE_CBC:
@@ -496,6 +801,10 @@ class Crypt_DES {
$this->paddable = true;
$this->mode = CRYPT_DES_MODE_CBC;
}
+ if (function_exists('create_function') && is_callable('create_function')) {
+ $this->inline_crypt_setup();
+ $this->use_inline_crypt = true;
+ }
}
}
@@ -717,6 +1026,11 @@ class Crypt_DES {
$this->keys = $this->_prepareKey("\0\0\0\0\0\0\0\0");
}
+ if ($this->use_inline_crypt) {
+ $inline = $this->inline_crypt;
+ return $inline('encrypt', $this, $plaintext);
+ }
+
$buffer = &$this->enbuffer;
$continuousBuffer = $this->continuousBuffer;
$ciphertext = '';
@@ -746,7 +1060,7 @@ class Crypt_DES {
if (strlen($block) > strlen($buffer['encrypted'])) {
$buffer['encrypted'].= $this->_processBlock($this->_generate_xor($xor), CRYPT_DES_ENCRYPT);
}
- $key = $this->_string_shift($buffer['encrypted'], 8);
+ $key = $this->_string_shift($buffer['encrypted']);
$ciphertext.= $block ^ $key;
}
} else {
@@ -811,7 +1125,7 @@ class Crypt_DES {
$xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
$buffer['xor'].= $xor;
}
- $key = $this->_string_shift($buffer['xor'], 8);
+ $key = $this->_string_shift($buffer['xor']);
$ciphertext.= $block ^ $key;
}
} else {
@@ -907,6 +1221,11 @@ class Crypt_DES {
$this->keys = $this->_prepareKey("\0\0\0\0\0\0\0\0");
}
+ if ($this->use_inline_crypt) {
+ $inline = $this->inline_crypt;
+ return $inline('decrypt', $this, $ciphertext);
+ }
+
$buffer = &$this->debuffer;
$continuousBuffer = $this->continuousBuffer;
$plaintext = '';
@@ -935,7 +1254,7 @@ class Crypt_DES {
if (strlen($block) > strlen($buffer['ciphertext'])) {
$buffer['ciphertext'].= $this->_processBlock($this->_generate_xor($xor), CRYPT_DES_ENCRYPT);
}
- $key = $this->_string_shift($buffer['ciphertext'], 8);
+ $key = $this->_string_shift($buffer['ciphertext']);
$plaintext.= $block ^ $key;
}
} else {
@@ -1001,7 +1320,7 @@ class Crypt_DES {
$xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
$buffer['xor'].= $xor;
}
- $key = $this->_string_shift($buffer['xor'], 8);
+ $key = $this->_string_shift($buffer['xor']);
$plaintext.= $block ^ $key;
}
} else {
@@ -1183,242 +1502,30 @@ class Crypt_DES {
*/
function _processBlock($block, $mode)
{
- // IP mapping helper table.
- // Indexing this table with each source byte performs the initial bit
- // permutation.
- static $ipmap = array(
- 0x00, 0x10, 0x01, 0x11, 0x20, 0x30, 0x21, 0x31,
- 0x02, 0x12, 0x03, 0x13, 0x22, 0x32, 0x23, 0x33,
- 0x40, 0x50, 0x41, 0x51, 0x60, 0x70, 0x61, 0x71,
- 0x42, 0x52, 0x43, 0x53, 0x62, 0x72, 0x63, 0x73,
- 0x04, 0x14, 0x05, 0x15, 0x24, 0x34, 0x25, 0x35,
- 0x06, 0x16, 0x07, 0x17, 0x26, 0x36, 0x27, 0x37,
- 0x44, 0x54, 0x45, 0x55, 0x64, 0x74, 0x65, 0x75,
- 0x46, 0x56, 0x47, 0x57, 0x66, 0x76, 0x67, 0x77,
- 0x80, 0x90, 0x81, 0x91, 0xA0, 0xB0, 0xA1, 0xB1,
- 0x82, 0x92, 0x83, 0x93, 0xA2, 0xB2, 0xA3, 0xB3,
- 0xC0, 0xD0, 0xC1, 0xD1, 0xE0, 0xF0, 0xE1, 0xF1,
- 0xC2, 0xD2, 0xC3, 0xD3, 0xE2, 0xF2, 0xE3, 0xF3,
- 0x84, 0x94, 0x85, 0x95, 0xA4, 0xB4, 0xA5, 0xB5,
- 0x86, 0x96, 0x87, 0x97, 0xA6, 0xB6, 0xA7, 0xB7,
- 0xC4, 0xD4, 0xC5, 0xD5, 0xE4, 0xF4, 0xE5, 0xF5,
- 0xC6, 0xD6, 0xC7, 0xD7, 0xE6, 0xF6, 0xE7, 0xF7,
- 0x08, 0x18, 0x09, 0x19, 0x28, 0x38, 0x29, 0x39,
- 0x0A, 0x1A, 0x0B, 0x1B, 0x2A, 0x3A, 0x2B, 0x3B,
- 0x48, 0x58, 0x49, 0x59, 0x68, 0x78, 0x69, 0x79,
- 0x4A, 0x5A, 0x4B, 0x5B, 0x6A, 0x7A, 0x6B, 0x7B,
- 0x0C, 0x1C, 0x0D, 0x1D, 0x2C, 0x3C, 0x2D, 0x3D,
- 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
- 0x4C, 0x5C, 0x4D, 0x5D, 0x6C, 0x7C, 0x6D, 0x7D,
- 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
- 0x88, 0x98, 0x89, 0x99, 0xA8, 0xB8, 0xA9, 0xB9,
- 0x8A, 0x9A, 0x8B, 0x9B, 0xAA, 0xBA, 0xAB, 0xBB,
- 0xC8, 0xD8, 0xC9, 0xD9, 0xE8, 0xF8, 0xE9, 0xF9,
- 0xCA, 0xDA, 0xCB, 0xDB, 0xEA, 0xFA, 0xEB, 0xFB,
- 0x8C, 0x9C, 0x8D, 0x9D, 0xAC, 0xBC, 0xAD, 0xBD,
- 0x8E, 0x9E, 0x8F, 0x9F, 0xAE, 0xBE, 0xAF, 0xBF,
- 0xCC, 0xDC, 0xCD, 0xDD, 0xEC, 0xFC, 0xED, 0xFD,
- 0xCE, 0xDE, 0xCF, 0xDF, 0xEE, 0xFE, 0xEF, 0xFF
- );
-
- // Inverse IP mapping helper table.
- // Indexing this table with a byte value reverses the bit order.
- static $invipmap = array(
- 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
- 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
- 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
- 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
- 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
- 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
- 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
- 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
- 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
- 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
- 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
- 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
- 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
- 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
- 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
- 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
- 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
- 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
- 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
- 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
- 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
- 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
- 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
- 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
- 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
- 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
- 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
- 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
- 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
- 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
- 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
- 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
- );
-
- // Pre-permuted S-boxes.
- // Each box has been vectorized, then each value pre-permuted using the
- // P table: concatenation can then be replaced by exclusive ORs.
- static $sbox1 = array(
- 0x00808200, 0x00000000, 0x00008000, 0x00808202,
- 0x00808002, 0x00008202, 0x00000002, 0x00008000,
- 0x00000200, 0x00808200, 0x00808202, 0x00000200,
- 0x00800202, 0x00808002, 0x00800000, 0x00000002,
- 0x00000202, 0x00800200, 0x00800200, 0x00008200,
- 0x00008200, 0x00808000, 0x00808000, 0x00800202,
- 0x00008002, 0x00800002, 0x00800002, 0x00008002,
- 0x00000000, 0x00000202, 0x00008202, 0x00800000,
- 0x00008000, 0x00808202, 0x00000002, 0x00808000,
- 0x00808200, 0x00800000, 0x00800000, 0x00000200,
- 0x00808002, 0x00008000, 0x00008200, 0x00800002,
- 0x00000200, 0x00000002, 0x00800202, 0x00008202,
- 0x00808202, 0x00008002, 0x00808000, 0x00800202,
- 0x00800002, 0x00000202, 0x00008202, 0x00808200,
- 0x00000202, 0x00800200, 0x00800200, 0x00000000,
- 0x00008002, 0x00008200, 0x00000000, 0x00808002
- );
- static $sbox2 = array(
- 0x40084010, 0x40004000, 0x00004000, 0x00084010,
- 0x00080000, 0x00000010, 0x40080010, 0x40004010,
- 0x40000010, 0x40084010, 0x40084000, 0x40000000,
- 0x40004000, 0x00080000, 0x00000010, 0x40080010,
- 0x00084000, 0x00080010, 0x40004010, 0x00000000,
- 0x40000000, 0x00004000, 0x00084010, 0x40080000,
- 0x00080010, 0x40000010, 0x00000000, 0x00084000,
- 0x00004010, 0x40084000, 0x40080000, 0x00004010,
- 0x00000000, 0x00084010, 0x40080010, 0x00080000,
- 0x40004010, 0x40080000, 0x40084000, 0x00004000,
- 0x40080000, 0x40004000, 0x00000010, 0x40084010,
- 0x00084010, 0x00000010, 0x00004000, 0x40000000,
- 0x00004010, 0x40084000, 0x00080000, 0x40000010,
- 0x00080010, 0x40004010, 0x40000010, 0x00080010,
- 0x00084000, 0x00000000, 0x40004000, 0x00004010,
- 0x40000000, 0x40080010, 0x40084010, 0x00084000
- );
- static $sbox3 = array(
- 0x00000104, 0x04010100, 0x00000000, 0x04010004,
- 0x04000100, 0x00000000, 0x00010104, 0x04000100,
- 0x00010004, 0x04000004, 0x04000004, 0x00010000,
- 0x04010104, 0x00010004, 0x04010000, 0x00000104,
- 0x04000000, 0x00000004, 0x04010100, 0x00000100,
- 0x00010100, 0x04010000, 0x04010004, 0x00010104,
- 0x04000104, 0x00010100, 0x00010000, 0x04000104,
- 0x00000004, 0x04010104, 0x00000100, 0x04000000,
- 0x04010100, 0x04000000, 0x00010004, 0x00000104,
- 0x00010000, 0x04010100, 0x04000100, 0x00000000,
- 0x00000100, 0x00010004, 0x04010104, 0x04000100,
- 0x04000004, 0x00000100, 0x00000000, 0x04010004,
- 0x04000104, 0x00010000, 0x04000000, 0x04010104,
- 0x00000004, 0x00010104, 0x00010100, 0x04000004,
- 0x04010000, 0x04000104, 0x00000104, 0x04010000,
- 0x00010104, 0x00000004, 0x04010004, 0x00010100
- );
- static $sbox4 = array(
- 0x80401000, 0x80001040, 0x80001040, 0x00000040,
- 0x00401040, 0x80400040, 0x80400000, 0x80001000,
- 0x00000000, 0x00401000, 0x00401000, 0x80401040,
- 0x80000040, 0x00000000, 0x00400040, 0x80400000,
- 0x80000000, 0x00001000, 0x00400000, 0x80401000,
- 0x00000040, 0x00400000, 0x80001000, 0x00001040,
- 0x80400040, 0x80000000, 0x00001040, 0x00400040,
- 0x00001000, 0x00401040, 0x80401040, 0x80000040,
- 0x00400040, 0x80400000, 0x00401000, 0x80401040,
- 0x80000040, 0x00000000, 0x00000000, 0x00401000,
- 0x00001040, 0x00400040, 0x80400040, 0x80000000,
- 0x80401000, 0x80001040, 0x80001040, 0x00000040,
- 0x80401040, 0x80000040, 0x80000000, 0x00001000,
- 0x80400000, 0x80001000, 0x00401040, 0x80400040,
- 0x80001000, 0x00001040, 0x00400000, 0x80401000,
- 0x00000040, 0x00400000, 0x00001000, 0x00401040
- );
- static $sbox5 = array(
- 0x00000080, 0x01040080, 0x01040000, 0x21000080,
- 0x00040000, 0x00000080, 0x20000000, 0x01040000,
- 0x20040080, 0x00040000, 0x01000080, 0x20040080,
- 0x21000080, 0x21040000, 0x00040080, 0x20000000,
- 0x01000000, 0x20040000, 0x20040000, 0x00000000,
- 0x20000080, 0x21040080, 0x21040080, 0x01000080,
- 0x21040000, 0x20000080, 0x00000000, 0x21000000,
- 0x01040080, 0x01000000, 0x21000000, 0x00040080,
- 0x00040000, 0x21000080, 0x00000080, 0x01000000,
- 0x20000000, 0x01040000, 0x21000080, 0x20040080,
- 0x01000080, 0x20000000, 0x21040000, 0x01040080,
- 0x20040080, 0x00000080, 0x01000000, 0x21040000,
- 0x21040080, 0x00040080, 0x21000000, 0x21040080,
- 0x01040000, 0x00000000, 0x20040000, 0x21000000,
- 0x00040080, 0x01000080, 0x20000080, 0x00040000,
- 0x00000000, 0x20040000, 0x01040080, 0x20000080
- );
- static $sbox6 = array(
- 0x10000008, 0x10200000, 0x00002000, 0x10202008,
- 0x10200000, 0x00000008, 0x10202008, 0x00200000,
- 0x10002000, 0x00202008, 0x00200000, 0x10000008,
- 0x00200008, 0x10002000, 0x10000000, 0x00002008,
- 0x00000000, 0x00200008, 0x10002008, 0x00002000,
- 0x00202000, 0x10002008, 0x00000008, 0x10200008,
- 0x10200008, 0x00000000, 0x00202008, 0x10202000,
- 0x00002008, 0x00202000, 0x10202000, 0x10000000,
- 0x10002000, 0x00000008, 0x10200008, 0x00202000,
- 0x10202008, 0x00200000, 0x00002008, 0x10000008,
- 0x00200000, 0x10002000, 0x10000000, 0x00002008,
- 0x10000008, 0x10202008, 0x00202000, 0x10200000,
- 0x00202008, 0x10202000, 0x00000000, 0x10200008,
- 0x00000008, 0x00002000, 0x10200000, 0x00202008,
- 0x00002000, 0x00200008, 0x10002008, 0x00000000,
- 0x10202000, 0x10000000, 0x00200008, 0x10002008
- );
- static $sbox7 = array(
- 0x00100000, 0x02100001, 0x02000401, 0x00000000,
- 0x00000400, 0x02000401, 0x00100401, 0x02100400,
- 0x02100401, 0x00100000, 0x00000000, 0x02000001,
- 0x00000001, 0x02000000, 0x02100001, 0x00000401,
- 0x02000400, 0x00100401, 0x00100001, 0x02000400,
- 0x02000001, 0x02100000, 0x02100400, 0x00100001,
- 0x02100000, 0x00000400, 0x00000401, 0x02100401,
- 0x00100400, 0x00000001, 0x02000000, 0x00100400,
- 0x02000000, 0x00100400, 0x00100000, 0x02000401,
- 0x02000401, 0x02100001, 0x02100001, 0x00000001,
- 0x00100001, 0x02000000, 0x02000400, 0x00100000,
- 0x02100400, 0x00000401, 0x00100401, 0x02100400,
- 0x00000401, 0x02000001, 0x02100401, 0x02100000,
- 0x00100400, 0x00000000, 0x00000001, 0x02100401,
- 0x00000000, 0x00100401, 0x02100000, 0x00000400,
- 0x02000001, 0x02000400, 0x00000400, 0x00100001
- );
- static $sbox8 = array(
- 0x08000820, 0x00000800, 0x00020000, 0x08020820,
- 0x08000000, 0x08000820, 0x00000020, 0x08000000,
- 0x00020020, 0x08020000, 0x08020820, 0x00020800,
- 0x08020800, 0x00020820, 0x00000800, 0x00000020,
- 0x08020000, 0x08000020, 0x08000800, 0x00000820,
- 0x00020800, 0x00020020, 0x08020020, 0x08020800,
- 0x00000820, 0x00000000, 0x00000000, 0x08020020,
- 0x08000020, 0x08000800, 0x00020820, 0x00020000,
- 0x00020820, 0x00020000, 0x08020800, 0x00000800,
- 0x00000020, 0x08020020, 0x00000800, 0x00020820,
- 0x08000800, 0x00000020, 0x08000020, 0x08020000,
- 0x08020020, 0x08000000, 0x00020000, 0x08000820,
- 0x00000000, 0x08020820, 0x00020020, 0x08000020,
- 0x08020000, 0x08000800, 0x08000820, 0x00000000,
- 0x08020820, 0x00020800, 0x00020800, 0x00000820,
- 0x00000820, 0x00020020, 0x08000000, 0x08020800
- );
-
- $keys = $this->keys[$mode];
+ $shuffle = $this->shuffle;
+ $invipmap = $this->invipmap;
+ $ipmap = $this->ipmap;
+ $sbox1 = $this->sbox1;
+ $sbox2 = $this->sbox2;
+ $sbox3 = $this->sbox3;
+ $sbox4 = $this->sbox4;
+ $sbox5 = $this->sbox5;
+ $sbox6 = $this->sbox6;
+ $sbox7 = $this->sbox7;
+ $sbox8 = $this->sbox8;
+ $keys = $this->keys[$mode];
// Do the initial IP permutation.
$t = unpack('Nl/Nr', $block);
list($l, $r) = array($t['l'], $t['r']);
- $block = ($this->shuffle[$ipmap[$r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
- ($this->shuffle[$ipmap[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
- ($this->shuffle[$ipmap[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
- ($this->shuffle[$ipmap[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
- ($this->shuffle[$ipmap[$l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
- ($this->shuffle[$ipmap[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
- ($this->shuffle[$ipmap[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
- ($this->shuffle[$ipmap[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01");
+ $block = ($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");
// Extract L0 and R0.
$t = unpack('Nl/Nr', $block);
@@ -1444,14 +1551,14 @@ class Crypt_DES {
}
// Perform the inverse IP permutation.
- return ($this->shuffle[$invipmap[($l >> 24) & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
- ($this->shuffle[$invipmap[($r >> 24) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
- ($this->shuffle[$invipmap[($l >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
- ($this->shuffle[$invipmap[($r >> 16) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
- ($this->shuffle[$invipmap[($l >> 8) & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
- ($this->shuffle[$invipmap[($r >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
- ($this->shuffle[$invipmap[$l & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
- ($this->shuffle[$invipmap[$r & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01");
+ return ($shuffle[$invipmap[($l >> 24) & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
+ ($shuffle[$invipmap[($r >> 24) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
+ ($shuffle[$invipmap[($l >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
+ ($shuffle[$invipmap[($r >> 16) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
+ ($shuffle[$invipmap[($l >> 8) & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
+ ($shuffle[$invipmap[($r >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
+ ($shuffle[$invipmap[$l & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
+ ($shuffle[$invipmap[$r & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01");
}
/**
@@ -1952,10 +2059,22 @@ class Crypt_DES {
);
}
- return array(
+ $keys = array(
CRYPT_DES_ENCRYPT => $keys,
- CRYPT_DES_DECRYPT => array_reverse($keys)
+ CRYPT_DES_DECRYPT => array_reverse($keys),
+ CRYPT_DES_ENCRYPT_1DIM => array(),
+ CRYPT_DES_DECRYPT_1DIM => array()
);
+
+ // Generate 1-dim arrays for inline en/decrypting
+ for ($i = 0; $i < 16; ++$i) {
+ $keys[CRYPT_DES_ENCRYPT_1DIM][] = $keys[CRYPT_DES_ENCRYPT][$i][0];
+ $keys[CRYPT_DES_ENCRYPT_1DIM][] = $keys[CRYPT_DES_ENCRYPT][$i][1];
+ $keys[CRYPT_DES_DECRYPT_1DIM][] = $keys[CRYPT_DES_DECRYPT][$i][0];
+ $keys[CRYPT_DES_DECRYPT_1DIM][] = $keys[CRYPT_DES_DECRYPT][$i][1];
+ }
+
+ return $keys;
}
/**
@@ -1964,16 +2083,447 @@ class Crypt_DES {
* Inspired by array_shift
*
* @param String $string
- * @param optional Integer $index
* @return String
* @access private
*/
- function _string_shift(&$string, $index = 1)
+ function _string_shift(&$string)
{
- $substr = substr($string, 0, $index);
- $string = substr($string, $index);
+ $substr = substr($string, 0, 8);
+ $string = substr($string, 8);
return $substr;
}
+
+ /**
+ * 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";
+ for ($des_round = 0; $des_round < $des_rounds; ++$des_round) {
+ // 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")
+ );
+
+ '.'' /* Extract L0 and R0 */ .'
+ $l = $in[1];
+ $r = $in[2];
+ ';
+
+ // 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;
+ ';
+ }
+
+ // Perform the inverse IP permutation.
+ $_cryptBlock .= '$in = ' . ($des_round == $des_rounds-1 ? '(' : 'unpack("N*",') . '
+ ($shuffle[$invipmap[($l >> 24) & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
+ ($shuffle[$invipmap[($r >> 24) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
+ ($shuffle[$invipmap[($l >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
+ ($shuffle[$invipmap[($r >> 16) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
+ ($shuffle[$invipmap[($l >> 8) & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
+ ($shuffle[$invipmap[($r >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
+ ($shuffle[$invipmap[ $l & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
+ ($shuffle[$invipmap[ $r & 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];
+ }
+
+ /**
+ * Holds the lambda_functions table (classwide)
+ *
+ * @see inline_crypt_setup()
+ * @return Array
+ * @access private
+ */
+ function &get_lambda_functions()
+ {
+ static $functions = array();
+ return $functions;
+ }
}
// vim: ts=4:sw=4:et:
diff --git a/phpseclib/Crypt/Random.php b/phpseclib/Crypt/Random.php
index 1796b2e9..475ec4f2 100644
--- a/phpseclib/Crypt/Random.php
+++ b/phpseclib/Crypt/Random.php
@@ -42,6 +42,13 @@
* @link http://phpseclib.sourceforge.net
*/
+/**
+ * "Is Windows" test
+ *
+ * @access private
+ */
+define('CRYPT_RANDOM_IS_WINDOWS', strtoupper(substr(PHP_OS, 0, 3)) === 'WIN');
+
/**
* Generate a random string.
*
@@ -55,8 +62,7 @@
*/
function crypt_random_string($length)
{
- // PHP_OS & "\xDF\xDF\xDF" == strtoupper(substr(PHP_OS, 0, 3)), but a lot faster
- if ((PHP_OS & "\xDF\xDF\xDF") === 'WIN') {
+ if (CRYPT_RANDOM_IS_WINDOWS) {
// method 1. prior to PHP 5.3 this would call rand() on windows hence the function_exists('class_alias') call.
// ie. class_alias is a function that was introduced in PHP 5.3
if (function_exists('mcrypt_create_iv') && function_exists('class_alias')) {
diff --git a/phpseclib/Crypt/TripleDES.php b/phpseclib/Crypt/TripleDES.php
index 28cdc588..8d463554 100644
--- a/phpseclib/Crypt/TripleDES.php
+++ b/phpseclib/Crypt/TripleDES.php
@@ -83,70 +83,7 @@ define('CRYPT_DES_MODE_CBC3', CRYPT_DES_MODE_CBC);
* @access public
* @package Crypt_TerraDES
*/
-class Crypt_TripleDES {
- /**
- * The Three Keys
- *
- * @see Crypt_TripleDES::setKey()
- * @var String
- * @access private
- */
- var $key = "\0\0\0\0\0\0\0\0";
-
- /**
- * The Encryption Mode
- *
- * @see Crypt_TripleDES::Crypt_TripleDES()
- * @var Integer
- * @access private
- */
- var $mode = CRYPT_DES_MODE_CBC;
-
- /**
- * Continuous Buffer status
- *
- * @see Crypt_TripleDES::enableContinuousBuffer()
- * @var Boolean
- * @access private
- */
- var $continuousBuffer = false;
-
- /**
- * Padding status
- *
- * @see Crypt_TripleDES::enablePadding()
- * @var Boolean
- * @access private
- */
- var $padding = true;
-
- /**
- * The Initialization Vector
- *
- * @see Crypt_TripleDES::setIV()
- * @var String
- * @access private
- */
- var $iv = "\0\0\0\0\0\0\0\0";
-
- /**
- * A "sliding" Initialization Vector
- *
- * @see Crypt_TripleDES::enableContinuousBuffer()
- * @var String
- * @access private
- */
- var $encryptIV = "\0\0\0\0\0\0\0\0";
-
- /**
- * A "sliding" Initialization Vector
- *
- * @see Crypt_TripleDES::enableContinuousBuffer()
- * @var String
- * @access private
- */
- var $decryptIV = "\0\0\0\0\0\0\0\0";
-
+class Crypt_TripleDES extends Crypt_DES {
/**
* The Crypt_DES objects
*
@@ -155,87 +92,6 @@ class Crypt_TripleDES {
*/
var $des;
- /**
- * mcrypt resource for encryption
- *
- * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
- * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
- *
- * @see Crypt_TripleDES::encrypt()
- * @var String
- * @access private
- */
- var $enmcrypt;
-
- /**
- * mcrypt resource for decryption
- *
- * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
- * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
- *
- * @see Crypt_TripleDES::decrypt()
- * @var String
- * @access private
- */
- var $demcrypt;
-
- /**
- * Does the enmcrypt resource need to be (re)initialized?
- *
- * @see Crypt_TripleDES::setKey()
- * @see Crypt_TripleDES::setIV()
- * @var Boolean
- * @access private
- */
- var $enchanged = true;
-
- /**
- * Does the demcrypt resource need to be (re)initialized?
- *
- * @see Crypt_TripleDES::setKey()
- * @see Crypt_TripleDES::setIV()
- * @var Boolean
- * @access private
- */
- var $dechanged = true;
-
- /**
- * Is the mode one that is paddable?
- *
- * @see Crypt_TripleDES::Crypt_TripleDES()
- * @var Boolean
- * @access private
- */
- var $paddable = false;
-
- /**
- * Encryption buffer for CTR, OFB and CFB modes
- *
- * @see Crypt_TripleDES::encrypt()
- * @var Array
- * @access private
- */
- var $enbuffer = array('encrypted' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);
-
- /**
- * Decryption buffer for CTR, OFB and CFB modes
- *
- * @see Crypt_TripleDES::decrypt()
- * @var Array
- * @access private
- */
- var $debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'demcrypt_init' => true);
-
- /**
- * mcrypt resource for CFB mode
- *
- * @see Crypt_TripleDES::encrypt()
- * @see Crypt_TripleDES::decrypt()
- * @var String
- * @access private
- */
- var $ecb;
-
/**
* Default Constructor.
*
@@ -328,6 +184,10 @@ class Crypt_TripleDES {
$this->paddable = true;
$this->mode = CRYPT_DES_MODE_CBC;
}
+ if (function_exists('create_function') && is_callable('create_function')) {
+ $this->inline_crypt_setup(3);
+ $this->use_inline_crypt = true;
+ }
}
}
@@ -362,6 +222,22 @@ class Crypt_TripleDES {
$this->des[0]->setKey(substr($key, 0, 8));
$this->des[1]->setKey(substr($key, 8, 8));
$this->des[2]->setKey(substr($key, 16, 8));
+
+ // Merge the three DES-1-dim-key-arrays for 3DES-inline-en/decrypting
+ if ($this->use_inline_crypt && $this->mode != CRYPT_DES_MODE_3CBC) {
+ $this->keys = array(
+ CRYPT_DES_ENCRYPT_1DIM => array_merge(
+ $this->des[0]->keys[CRYPT_DES_ENCRYPT_1DIM],
+ $this->des[1]->keys[CRYPT_DES_DECRYPT_1DIM],
+ $this->des[2]->keys[CRYPT_DES_ENCRYPT_1DIM]
+ ),
+ CRYPT_DES_DECRYPT_1DIM => array_merge(
+ $this->des[2]->keys[CRYPT_DES_DECRYPT_1DIM],
+ $this->des[1]->keys[CRYPT_DES_ENCRYPT_1DIM],
+ $this->des[0]->keys[CRYPT_DES_DECRYPT_1DIM]
+ ),
+ );
+ }
}
$this->enchanged = $this->dechanged = true;
}
@@ -438,39 +314,6 @@ class Crypt_TripleDES {
$this->enchanged = $this->dechanged = true;
}
- /**
- * Generate CTR XOR encryption key
- *
- * Encrypt the output of this and XOR it against the ciphertext / plaintext to get the
- * plaintext / ciphertext in CTR mode.
- *
- * @see Crypt_TripleDES::decrypt()
- * @see Crypt_TripleDES::encrypt()
- * @access private
- * @param String $iv
- */
- function _generate_xor(&$iv)
- {
- $xor = $iv;
- for ($j = 4; $j <= 8; $j+=4) {
- $temp = substr($iv, -$j, 4);
- switch ($temp) {
- case "\xFF\xFF\xFF\xFF":
- $iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4);
- break;
- case "\x7F\xFF\xFF\xFF":
- $iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4);
- break 2;
- default:
- extract(unpack('Ncount', $temp));
- $iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);
- break 2;
- }
- }
-
- return $xor;
- }
-
/**
* Encrypts a message.
*
@@ -565,6 +408,11 @@ class Crypt_TripleDES {
return $this->des[0]->encrypt($plaintext);
}
+ if ($this->use_inline_crypt) {
+ $inline = $this->inline_crypt;
+ return $inline('encrypt', $this, $plaintext);
+ }
+
$des = $this->des;
$buffer = &$this->enbuffer;
@@ -612,7 +460,7 @@ class Crypt_TripleDES {
$key = $des[2]->_processBlock($key, CRYPT_DES_ENCRYPT);
$buffer['encrypted'].= $key;
}
- $key = $this->_string_shift($buffer['encrypted'], 8);
+ $key = $this->_string_shift($buffer['encrypted']);
$ciphertext.= $block ^ $key;
}
} else {
@@ -676,7 +524,7 @@ class Crypt_TripleDES {
$xor = $des[2]->_processBlock($xor, CRYPT_DES_ENCRYPT);
$buffer['xor'].= $xor;
}
- $key = $this->_string_shift($buffer['xor'], 8);
+ $key = $this->_string_shift($buffer['xor']);
$ciphertext.= $block ^ $key;
}
} else {
@@ -780,6 +628,11 @@ class Crypt_TripleDES {
return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
}
+ if ($this->use_inline_crypt) {
+ $inline = $this->inline_crypt;
+ return $inline('decrypt', $this, $ciphertext);
+ }
+
$des = $this->des;
$buffer = &$this->debuffer;
@@ -821,7 +674,7 @@ class Crypt_TripleDES {
$key = $des[2]->_processBlock($key, CRYPT_DES_ENCRYPT);
$buffer['ciphertext'].= $key;
}
- $key = $this->_string_shift($buffer['ciphertext'], 8);
+ $key = $this->_string_shift($buffer['ciphertext']);
$plaintext.= $block ^ $key;
}
} else {
@@ -890,7 +743,7 @@ class Crypt_TripleDES {
$xor = $des[2]->_processBlock($xor, CRYPT_DES_ENCRYPT);
$buffer['xor'].= $xor;
}
- $key = $this->_string_shift($buffer['xor'], 8);
+ $key = $this->_string_shift($buffer['xor']);
$plaintext.= $block ^ $key;
}
} else {
@@ -984,106 +837,6 @@ class Crypt_TripleDES {
$this->des[2]->disableContinuousBuffer();
}
}
-
- /**
- * Pad "packets".
- *
- * DES works by encrypting eight bytes at a time. If you ever need to encrypt or decrypt something that's not
- * a multiple of eight, it becomes necessary to pad the input so that it's length is a multiple of eight.
- *
- * Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH1,
- * where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping
- * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is
- * transmitted separately)
- *
- * @see Crypt_TripleDES::disablePadding()
- * @access public
- */
- function enablePadding()
- {
- $this->padding = true;
- }
-
- /**
- * Do not pad packets.
- *
- * @see Crypt_TripleDES::enablePadding()
- * @access public
- */
- function disablePadding()
- {
- $this->padding = false;
- }
-
- /**
- * Pads a string
- *
- * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize (8).
- * 8 - (strlen($text) & 7) bytes are added, each of which is equal to chr(8 - (strlen($text) & 7)
- *
- * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless
- * and padding will, hence forth, be enabled.
- *
- * @see Crypt_TripleDES::_unpad()
- * @access private
- */
- function _pad($text)
- {
- $length = strlen($text);
-
- if (!$this->padding) {
- if (($length & 7) == 0) {
- return $text;
- } else {
- user_error("The plaintext's length ($length) is not a multiple of the block size (8)", E_USER_NOTICE);
- $this->padding = true;
- }
- }
-
- $pad = 8 - ($length & 7);
- return str_pad($text, $length + $pad, chr($pad));
- }
-
- /**
- * Unpads a string
- *
- * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong
- * and false will be returned.
- *
- * @see Crypt_TripleDES::_pad()
- * @access private
- */
- function _unpad($text)
- {
- if (!$this->padding) {
- return $text;
- }
-
- $length = ord($text[strlen($text) - 1]);
-
- if (!$length || $length > 8) {
- return false;
- }
-
- return substr($text, 0, -$length);
- }
-
- /**
- * String Shift
- *
- * Inspired by array_shift
- *
- * @param String $string
- * @param optional Integer $index
- * @return String
- * @access private
- */
- function _string_shift(&$string, $index = 1)
- {
- $substr = substr($string, 0, $index);
- $string = substr($string, $index);
- return $substr;
- }
}
// vim: ts=4:sw=4:et:
diff --git a/phpseclib/Math/BigInteger.php b/phpseclib/Math/BigInteger.php
index 8ff41470..9c295b5d 100644
--- a/phpseclib/Math/BigInteger.php
+++ b/phpseclib/Math/BigInteger.php
@@ -236,20 +236,20 @@ class Math_BigInteger {
var $hex;
/**
- * Converts base-2, base-10, base-16, and binary strings (eg. base-256) to BigIntegers.
+ * Converts base-2, base-10, base-16, and binary strings (base-256) to BigIntegers.
*
* If the second parameter - $base - is negative, then it will be assumed that the number's are encoded using
* two's compliment. The sole exception to this is -10, which is treated the same as 10 is.
*
* Here's an example:
*
- * toString(); // outputs 50
- * ?>
+ * ?>
*
*
* @param optional $x base-10 number or base-$base number if $base set.
@@ -2137,6 +2137,7 @@ class Math_BigInteger {
* @param Boolean $x_negative
* @param Array $y_value
* @param Boolean $y_negative
+ * @param Integer $stop
* @return Array
* @access private
*/
@@ -2629,8 +2630,8 @@ class Math_BigInteger {
*
* Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y).
*
- * @param Math_BigInteger $x
- * @return Integer < 0 if $this is less than $x; > 0 if $this is greater than $x, and 0 if they are equal.
+ * @param Math_BigInteger $y
+ * @return Integer < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal.
* @access public
* @see equals()
* @internal Could return $this->subtract($x), but that's not as fast as what we do do.
@@ -2709,7 +2710,7 @@ class Math_BigInteger {
* Some bitwise operations give different results depending on the precision being used. Examples include left
* shift, not, and rotates.
*
- * @param Math_BigInteger $x
+ * @param Integer $bits
* @access public
* @return Math_BigInteger
*/
@@ -3510,6 +3511,7 @@ class Math_BigInteger {
*
* Removes leading zeros
*
+ * @param Array $value
* @return Math_BigInteger
* @access private
*/
diff --git a/phpseclib/Net/SCP.php b/phpseclib/Net/SCP.php
new file mode 100644
index 00000000..64756c49
--- /dev/null
+++ b/phpseclib/Net/SCP.php
@@ -0,0 +1,341 @@
+
+ * login('username', 'password')) {
+ * exit('bad login');
+ * }
+
+ * $scp = new Net_SCP($ssh);
+ * $scp->put('abcd', str_repeat('x', 1024*1024));
+ * ?>
+ *
+ *
+ * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * @category Net
+ * @package Net_SCP
+ * @author Jim Wigginton
+ * @copyright MMX Jim Wigginton
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ * @link http://phpseclib.sourceforge.net
+ */
+
+/**#@+
+ * @access public
+ * @see Net_SCP::put()
+ */
+/**
+ * Reads data from a local file.
+ */
+define('NET_SCP_LOCAL_FILE', 1);
+/**
+ * Reads data from a string.
+ */
+define('NET_SCP_STRING', 2);
+/**#@-*/
+
+/**#@+
+ * @access private
+ * @see Net_SCP::_send()
+ * @see Net_SCP::_receive()
+ */
+/**
+ * SSH1 is being used.
+ */
+define('NET_SCP_SSH1', 1);
+/**
+ * SSH2 is being used.
+ */
+define('NET_SCP_SSH2', 2);
+/**#@-*/
+
+/**
+ * Pure-PHP implementations of SCP.
+ *
+ * @author Jim Wigginton
+ * @version 0.1.0
+ * @access public
+ * @package Net_SCP
+ */
+class Net_SCP {
+ /**
+ * SSH Object
+ *
+ * @var Object
+ * @access private
+ */
+ var $ssh;
+
+ /**
+ * Packet Size
+ *
+ * @var Integer
+ * @access private
+ */
+ var $packet_size;
+
+ /**
+ * Mode
+ *
+ * @var Integer
+ * @access private
+ */
+ var $mode;
+
+ /**
+ * Default Constructor.
+ *
+ * Connects to an SSH server
+ *
+ * @param String $host
+ * @param optional Integer $port
+ * @param optional Integer $timeout
+ * @return Net_SCP
+ * @access public
+ */
+ function Net_SCP($ssh)
+ {
+ if (!is_object($ssh)) {
+ return;
+ }
+
+ switch (strtolower(get_class($ssh))) {
+ case'net_ssh2':
+ $this->mode = NET_SCP_SSH2;
+ break;
+ case 'net_ssh1':
+ $this->packet_size = 50000;
+ $this->mode = NET_SCP_SSH1;
+ break;
+ default:
+ return;
+ }
+
+ $this->ssh = $ssh;
+ }
+
+ /**
+ * Uploads a file to the SCP server.
+ *
+ * By default, Net_SCP::put() does not read from the local filesystem. $data is dumped directly into $remote_file.
+ * So, for example, if you set $data to 'filename.ext' and then do Net_SCP::get(), you will get a file, twelve bytes
+ * long, containing 'filename.ext' as its contents.
+ *
+ * Setting $mode to NET_SFTP_LOCAL_FILE will change the above behavior. With NET_SFTP_LOCAL_FILE, $remote_file will
+ * contain as many bytes as filename.ext does on your local filesystem. If your filename.ext is 1MB then that is how
+ * large $remote_file will be, as well.
+ *
+ * Currently, only binary mode is supported. As such, if the line endings need to be adjusted, you will need to take
+ * care of that, yourself.
+ *
+ * @param String $remote_file
+ * @param String $data
+ * @param optional Integer $mode
+ * @return Boolean
+ * @access public
+ */
+ function put($remote_file, $data, $mode = NET_SCP_STRING)
+ {
+ if (!isset($this->ssh)) {
+ return false;
+ }
+
+ $this->ssh->exec('scp -t ' . $remote_file, false); // -t = to
+
+ $temp = $this->_receive();
+ if ($temp !== chr(0)) {
+ return false;
+ }
+
+ if ($this->mode == NET_SCP_SSH2) {
+ $this->packet_size = $this->ssh->packet_size_client_to_server[NET_SSH2_CHANNEL_EXEC];
+ }
+
+ $remote_file = basename($remote_file);
+ $this->_send('C0644 ' . strlen($data) . ' ' . $remote_file . "\n");
+
+ $temp = $this->_receive();
+ if ($temp !== chr(0)) {
+ return false;
+ }
+
+ if ($mode == NET_SCP_STRING) {
+ $this->_send($data);
+ } else {
+ if (!is_file($data)) {
+ user_error("$data is not a valid file", E_USER_NOTICE);
+ return false;
+ }
+ $fp = @fopen($data, 'rb');
+ if (!$fp) {
+ return false;
+ }
+ $size = filesize($data);
+ for ($i = 0; $i < $length; $i++) {
+ $this->_send(fgets($fp, $this->packet_size));
+ }
+ fclose($fp);
+ }
+ $this->_close();
+ }
+
+ /**
+ * Downloads a file from the SCP server.
+ *
+ * Returns a string containing the contents of $remote_file if $local_file is left undefined or a boolean false if
+ * the operation was unsuccessful. If $local_file is defined, returns true or false depending on the success of the
+ * operation
+ *
+ * @param String $remote_file
+ * @param optional String $local_file
+ * @return Mixed
+ * @access public
+ */
+ function get($remote_file, $local_file = false)
+ {
+ if (!isset($this->ssh)) {
+ return false;
+ }
+
+ $this->ssh->exec('scp -f ' . $remote_file, false); // -f = from
+
+ $this->_send("\0");
+
+ if (!preg_match('#(?[^ ]+) (?\d+) (?.+)#', rtrim($this->_receive()), $info)) {
+ return false;
+ }
+
+ $this->_send("\0");
+
+ $size = 0;
+
+ if ($local_file !== false) {
+ $fp = @fopen($local_file, 'wb');
+ if (!$fp) {
+ return false;
+ }
+ }
+
+ $content = '';
+ while ($size < $info['size']) {
+ $data = $this->_receive();
+ // SCP usually seems to split stuff out into 16k chunks
+ $size+= strlen($data);
+
+ if ($local_file === false) {
+ $content.= $data;
+ } else {
+ fputs($fp, $data);
+ }
+ }
+
+ $this->_close();
+
+ if ($local_file !== false) {
+ fclose($fp);
+ return true;
+ }
+
+ return $content;
+ }
+
+ /**
+ * Sends a packet to an SSH server
+ *
+ * @param String $data
+ * @access private
+ */
+ function _send($data)
+ {
+ switch ($this->mode) {
+ case NET_SCP_SSH2:
+ $this->ssh->_send_channel_packet(NET_SSH2_CHANNEL_EXEC, $data);
+ break;
+ case NET_SCP_SSH1:
+ $data = pack('CNa*', NET_SSH1_CMSG_STDIN_DATA, strlen($data), $data);
+ $this->ssh->_send_binary_packet($data);
+ }
+ }
+
+ /**
+ * Receives a packet from an SSH server
+ *
+ * @return String
+ * @access private
+ */
+ function _receive()
+ {
+ switch ($this->mode) {
+ case NET_SCP_SSH2:
+ return $this->ssh->_get_channel_packet(NET_SSH2_CHANNEL_EXEC, true);
+ case NET_SCP_SSH1:
+ if (!$this->ssh->bitmap) {
+ return false;
+ }
+ while (true) {
+ $response = $this->ssh->_get_binary_packet();
+ switch ($response[NET_SSH1_RESPONSE_TYPE]) {
+ case NET_SSH1_SMSG_STDOUT_DATA:
+ extract(unpack('Nlength', $response[NET_SSH1_RESPONSE_DATA]));
+ return $this->ssh->_string_shift($response[NET_SSH1_RESPONSE_DATA], $length);
+ case NET_SSH1_SMSG_STDERR_DATA:
+ break;
+ case NET_SSH1_SMSG_EXITSTATUS:
+ $this->ssh->_send_binary_packet(chr(NET_SSH1_CMSG_EXIT_CONFIRMATION));
+ fclose($this->ssh->fsock);
+ $this->ssh->bitmap = 0;
+ return false;
+ default:
+ user_error('Unknown packet received', E_USER_NOTICE);
+ return false;
+ }
+ }
+ }
+ }
+
+ /**
+ * Closes the connection to an SSH server
+ *
+ * @access private
+ */
+ function _close()
+ {
+ switch ($this->mode) {
+ case NET_SCP_SSH2:
+ $this->ssh->_close_channel(NET_SSH2_CHANNEL_EXEC);
+ break;
+ case NET_SCP_SSH1:
+ $this->ssh->disconnect();
+ }
+ }
+}
\ No newline at end of file
diff --git a/phpseclib/Net/SFTP.php b/phpseclib/Net/SFTP.php
index 46245a42..4a0eb11f 100644
--- a/phpseclib/Net/SFTP.php
+++ b/phpseclib/Net/SFTP.php
@@ -1331,7 +1331,9 @@ class Net_SFTP extends Net_SSH2 {
}
$dir = $this->_realpath($dir);
- $attr = $mode == -1 ? chr(0) : pack('N2', NET_SFTP_ATTR_PERMISSIONS, $mode & 07777);
+ // by not providing any permissions, hopefully the server will use the logged in users umask - their
+ // default permissions.
+ $attr = $mode == -1 ? "\0\0\0\0" : pack('N2', NET_SFTP_ATTR_PERMISSIONS, $mode & 07777);
if ($recursive) {
$dirs = explode('/', preg_replace('#/(?=/)|/$#', '', $dir));
@@ -1359,8 +1361,6 @@ class Net_SFTP extends Net_SSH2 {
*/
function _mkdir_helper($dir, $attr)
{
- // by not providing any permissions, hopefully the server will use the logged in users umask - their
- // default permissions.
if (!$this->_send_sftp_packet(NET_SFTP_MKDIR, pack('Na*a*', strlen($dir), $dir, $attr))) {
return false;
}
@@ -2205,4 +2205,4 @@ class Net_SFTP extends Net_SSH2 {
$this->pwd = false;
parent::_disconnect($reason);
}
-}
+}
\ No newline at end of file
diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php
index d2da09e0..6e679e22 100644
--- a/phpseclib/Net/SSH2.php
+++ b/phpseclib/Net/SSH2.php
@@ -112,6 +112,13 @@ if (!class_exists('Crypt_AES')) {
require_once('Crypt/AES.php');
}
+/**
+ * Include Crypt_Twofish
+ */
+if (!class_exists('Crypt_Twofish')) {
+ require_once('Crypt/Twofish.php');
+}
+
/**#@+
* Execution Bitmap Masks
*
@@ -752,6 +759,18 @@ class Net_SSH2 {
*/
var $keyboard_requests_responses = array();
+ /**
+ * Banner Message
+ *
+ * Quoting from the RFC, "in some jurisdictions, sending a warning message before
+ * authentication may be relevant for getting legal protection."
+ *
+ * @see Net_SSH2::_filter()
+ * @see Net_SSH2::getBannerMessage()
+ * @access private
+ */
+ var $banner_message = '';
+
/**
* Default Constructor.
*
@@ -958,20 +977,30 @@ class Net_SSH2 {
'arcfour256',
'arcfour128',
- 'arcfour', // OPTIONAL the ARCFOUR stream cipher with a 128-bit key
+ 'arcfour', // OPTIONAL the ARCFOUR stream cipher with a 128-bit key
- 'aes128-cbc', // RECOMMENDED AES with a 128-bit key
- 'aes192-cbc', // OPTIONAL AES with a 192-bit key
- 'aes256-cbc', // OPTIONAL AES in CBC mode, with a 256-bit key
+ // CTR modes from :
+ 'aes128-ctr', // RECOMMENDED AES (Rijndael) in SDCTR mode, with 128-bit key
+ 'aes192-ctr', // RECOMMENDED AES with 192-bit key
+ 'aes256-ctr', // RECOMMENDED AES with 256-bit key
- // from :
- 'aes128-ctr', // RECOMMENDED AES (Rijndael) in SDCTR mode, with 128-bit key
- 'aes192-ctr', // RECOMMENDED AES with 192-bit key
- 'aes256-ctr', // RECOMMENDED AES with 256-bit key
- '3des-ctr', // RECOMMENDED Three-key 3DES in SDCTR mode
+ 'twofish128-ctr', // OPTIONAL Twofish in SDCTR mode, with 128-bit key
+ 'twofish192-ctr', // OPTIONAL Twofish with 192-bit key
+ 'twofish256-ctr', // OPTIONAL Twofish with 256-bit key
- '3des-cbc', // REQUIRED three-key 3DES in CBC mode
- 'none' // OPTIONAL no encryption; NOT RECOMMENDED
+ 'aes128-cbc', // RECOMMENDED AES with a 128-bit key
+ 'aes192-cbc', // OPTIONAL AES with a 192-bit key
+ 'aes256-cbc', // OPTIONAL AES in CBC mode, with a 256-bit key
+
+ 'twofish128-cbc', // OPTIONAL Twofish with a 128-bit key
+ 'twofish192-cbc', // OPTIONAL Twofish with a 192-bit key
+ 'twofish256-cbc',
+ 'twofish-cbc', // OPTIONAL alias for "twofish256-cbc"
+ // (this is being retained for historical reasons)
+ '3des-ctr', // RECOMMENDED Three-key 3DES in SDCTR mode
+
+ '3des-cbc', // REQUIRED three-key 3DES in CBC mode
+ 'none' // OPTIONAL no encryption; NOT RECOMMENDED
);
static $mac_algorithms = array(
@@ -1080,14 +1109,21 @@ class Net_SSH2 {
break;
case 'aes256-cbc':
case 'aes256-ctr':
+ case 'twofish-cbc':
+ case 'twofish256-cbc':
+ case 'twofish256-ctr':
$decryptKeyLength = 32; // eg. 256 / 8
break;
case 'aes192-cbc':
case 'aes192-ctr':
+ case 'twofish192-cbc':
+ case 'twofish192-ctr':
$decryptKeyLength = 24; // eg. 192 / 8
break;
case 'aes128-cbc':
case 'aes128-ctr':
+ case 'twofish128-cbc':
+ case 'twofish128-ctr':
$decryptKeyLength = 16; // eg. 128 / 8
break;
case 'arcfour':
@@ -1115,14 +1151,21 @@ class Net_SSH2 {
break;
case 'aes256-cbc':
case 'aes256-ctr':
+ case 'twofish-cbc':
+ case 'twofish256-cbc':
+ case 'twofish256-ctr':
$encryptKeyLength = 32;
break;
case 'aes192-cbc':
case 'aes192-ctr':
+ case 'twofish192-cbc':
+ case 'twofish192-ctr':
$encryptKeyLength = 24;
break;
case 'aes128-cbc':
case 'aes128-ctr':
+ case 'twofish128-cbc':
+ case 'twofish128-ctr':
$encryptKeyLength = 16;
break;
case 'arcfour':
@@ -1248,7 +1291,7 @@ class Net_SSH2 {
}
if ($public_key_format != $server_host_key_algorithms[$i] || $this->signature_format != $server_host_key_algorithms[$i]) {
- user_error('Sever Host Key Algorithm Mismatch');
+ user_error('Server Host Key Algorithm Mismatch');
return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
}
@@ -1295,6 +1338,19 @@ class Net_SSH2 {
$this->encrypt = new Crypt_AES(CRYPT_AES_MODE_CTR);
$this->encrypt_block_size = 16; // eg. 128 / 8
break;
+ case 'twofish128-cbc':
+ case 'twofish192-cbc':
+ case 'twofish256-cbc':
+ case 'twofish-cbc':
+ $this->encrypt = new Crypt_Twofish();
+ $this->encrypt_block_size = 16;
+ break;
+ case 'twofish128-ctr':
+ case 'twofish192-ctr':
+ case 'twofish256-ctr':
+ $this->encrypt = new Crypt_Twofish(CRYPT_TWOFISH_MODE_CTR);
+ $this->encrypt_block_size = 16;
+ break;
case 'arcfour':
case 'arcfour128':
case 'arcfour256':
@@ -1323,6 +1379,19 @@ class Net_SSH2 {
$this->decrypt = new Crypt_AES(CRYPT_AES_MODE_CTR);
$this->decrypt_block_size = 16;
break;
+ case 'twofish128-cbc':
+ case 'twofish192-cbc':
+ case 'twofish256-cbc':
+ case 'twofish-cbc':
+ $this->decrypt = new Crypt_Twofish();
+ $this->decrypt_block_size = 16;
+ break;
+ case 'twofish128-ctr':
+ case 'twofish192-ctr':
+ case 'twofish256-ctr':
+ $this->decrypt = new Crypt_Twofish(CRYPT_TWOFISH_MODE_CTR);
+ $this->decrypt_block_size = 16;
+ break;
case 'arcfour':
case 'arcfour128':
case 'arcfour256':
@@ -1875,6 +1944,7 @@ class Net_SSH2 {
* Setting $timeout to false or 0 will mean there is no timeout.
*
* @param Mixed $timeout
+ * @access public
*/
function setTimeout($timeout)
{
@@ -1883,8 +1953,11 @@ class Net_SSH2 {
/**
* Get the output from stdError
+ *
+ * @access public
*/
- function getStdError(){
+ function getStdError()
+ {
return $this->stdErrorLog;
}
@@ -2313,7 +2386,7 @@ class Net_SSH2 {
if (($this->bitmap & NET_SSH2_MASK_CONSTRUCTOR) && !($this->bitmap & NET_SSH2_MASK_LOGIN) && ord($payload[0]) == NET_SSH2_MSG_USERAUTH_BANNER) {
$this->_string_shift($payload, 1);
extract(unpack('Nlength', $this->_string_shift($payload, 4)));
- $this->errors[] = 'SSH_MSG_USERAUTH_BANNER: ' . utf8_decode($this->_string_shift($payload, $length));
+ $this->banner_message = utf8_decode($this->_string_shift($payload, $length));
$payload = $this->_get_binary_packet();
}
@@ -3045,6 +3118,20 @@ class Net_SSH2 {
return $this->languages_client_to_server;
}
+ /**
+ * Returns the banner message.
+ *
+ * Quoting from the RFC, "in some jurisdictions, sending a warning message before
+ * authentication may be relevant for getting legal protection."
+ *
+ * @return String
+ * @access public
+ */
+ function getBannerMessage()
+ {
+ return $this->banner_message;
+ }
+
/**
* Returns the server public host key.
*