From a730ed6e4c14a009daf79b4ce5924d09b4d24192 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Fri, 7 Jun 2013 00:38:38 +0200 Subject: [PATCH 1/8] [feature/elliptic-curve] Use an instance of Crypt_Hash instead of sha1(). --- phpseclib/Net/SSH2.php | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index eecd3660..88852233 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -1166,8 +1166,6 @@ class Net_SSH2 { '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF'); - $keyLength = $keyLength < 20 ? $keyLength : 20; - $hash = 'sha1'; break; // see http://tools.ietf.org/html/rfc3526#section-3 case 'diffie-hellman-group14-sha1': @@ -1179,10 +1177,12 @@ class Net_SSH2 { '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . '3995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF'); - $keyLength = $keyLength < 20 ? $keyLength : 20; - $hash = 'sha1'; + break; } + $kexHash = new Crypt_Hash('sha1'); + $keyLength = min($keyLength, $kexHash->getLength()); + $p = new Math_BigInteger($p, 256); //$q = $p->bitwise_rightShift(1); @@ -1248,7 +1248,7 @@ class Net_SSH2 { $eBytes, strlen($fBytes), $fBytes, strlen($keyBytes), $keyBytes ); - $this->exchange_hash = pack('H*', $hash($this->exchange_hash)); + $this->exchange_hash = $kexHash->hash($this->exchange_hash); if ($this->session_id === false) { $this->session_id = $this->exchange_hash; @@ -1447,15 +1447,15 @@ class Net_SSH2 { $this->encrypt->enableContinuousBuffer(); $this->encrypt->disablePadding(); - $iv = pack('H*', $hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id)); + $iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id); while ($this->encrypt_block_size > strlen($iv)) { - $iv.= pack('H*', $hash($keyBytes . $this->exchange_hash . $iv)); + $iv.= $kexHash->hash($keyBytes . $this->exchange_hash . $iv); } $this->encrypt->setIV(substr($iv, 0, $this->encrypt_block_size)); - $key = pack('H*', $hash($keyBytes . $this->exchange_hash . 'C' . $this->session_id)); + $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'C' . $this->session_id); while ($encryptKeyLength > strlen($key)) { - $key.= pack('H*', $hash($keyBytes . $this->exchange_hash . $key)); + $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key); } $this->encrypt->setKey(substr($key, 0, $encryptKeyLength)); } @@ -1464,15 +1464,15 @@ class Net_SSH2 { $this->decrypt->enableContinuousBuffer(); $this->decrypt->disablePadding(); - $iv = pack('H*', $hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id)); + $iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id); while ($this->decrypt_block_size > strlen($iv)) { - $iv.= pack('H*', $hash($keyBytes . $this->exchange_hash . $iv)); + $iv.= $kexHash->hash($keyBytes . $this->exchange_hash . $iv); } $this->decrypt->setIV(substr($iv, 0, $this->decrypt_block_size)); - $key = pack('H*', $hash($keyBytes . $this->exchange_hash . 'D' . $this->session_id)); + $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'D' . $this->session_id); while ($decryptKeyLength > strlen($key)) { - $key.= pack('H*', $hash($keyBytes . $this->exchange_hash . $key)); + $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key); } $this->decrypt->setKey(substr($key, 0, $decryptKeyLength)); } @@ -1546,15 +1546,15 @@ class Net_SSH2 { $this->hmac_size = 12; } - $key = pack('H*', $hash($keyBytes . $this->exchange_hash . 'E' . $this->session_id)); + $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'E' . $this->session_id); while ($createKeyLength > strlen($key)) { - $key.= pack('H*', $hash($keyBytes . $this->exchange_hash . $key)); + $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key); } $this->hmac_create->setKey(substr($key, 0, $createKeyLength)); - $key = pack('H*', $hash($keyBytes . $this->exchange_hash . 'F' . $this->session_id)); + $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'F' . $this->session_id); while ($checkKeyLength > strlen($key)) { - $key.= pack('H*', $hash($keyBytes . $this->exchange_hash . $key)); + $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key); } $this->hmac_check->setKey(substr($key, 0, $checkKeyLength)); From 50f5f3f97ed755d1a5215e0071e2b55ed194d1c9 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Fri, 7 Jun 2013 00:43:40 +0200 Subject: [PATCH 2/8] [feature/elliptic-curve] Assign a variable to Math_BigInteger(1). --- phpseclib/Net/SSH2.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index 88852233..3e4a391c 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -1193,13 +1193,13 @@ class Net_SSH2 { [VAN-OORSCHOT]. -- http://tools.ietf.org/html/rfc4419#section-6.2 */ - $q = new Math_BigInteger(1); - $q = $q->bitwise_leftShift(16 * $keyLength); // 2 * 8 * $keyLength - $q = $q->subtract(new Math_BigInteger(1)); + $one = new Math_BigInteger(1); + $q = $one->bitwise_leftShift(16 * $keyLength); // 2 * 8 * $keyLength + $q = $q->subtract($one); $g = new Math_BigInteger(2); $x = new Math_BigInteger(); - $x = $x->random(new Math_BigInteger(1), $q); + $x = $x->random($one, $q); $e = $g->modPow($x, $p); $eBytes = $e->toBytes(true); From 97cf60900d7457416170008c7f78c7ca27b96a5a Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Fri, 7 Jun 2013 00:47:37 +0200 Subject: [PATCH 3/8] [feature/elliptic-curve] Rename $q to $max because that's what it is. --- phpseclib/Net/SSH2.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index 3e4a391c..e01b4519 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -1194,12 +1194,11 @@ class Net_SSH2 { -- http://tools.ietf.org/html/rfc4419#section-6.2 */ $one = new Math_BigInteger(1); - $q = $one->bitwise_leftShift(16 * $keyLength); // 2 * 8 * $keyLength - $q = $q->subtract($one); + $max = $one->bitwise_leftShift(16 * $keyLength)->subtract($one); // 2 * 8 * $keyLength $g = new Math_BigInteger(2); $x = new Math_BigInteger(); - $x = $x->random($one, $q); + $x = $x->random($one, $max); $e = $g->modPow($x, $p); $eBytes = $e->toBytes(true); From 7253e77386a3d4bb548f7fe190571830b443f706 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Fri, 7 Jun 2013 00:47:59 +0200 Subject: [PATCH 4/8] [feature/elliptic-curve] Do not instantiate unnecessary $x instance. --- phpseclib/Net/SSH2.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index e01b4519..f6207509 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -1197,8 +1197,7 @@ class Net_SSH2 { $max = $one->bitwise_leftShift(16 * $keyLength)->subtract($one); // 2 * 8 * $keyLength $g = new Math_BigInteger(2); - $x = new Math_BigInteger(); - $x = $x->random($one, $max); + $x = $one->random($one, $max); $e = $g->modPow($x, $p); $eBytes = $e->toBytes(true); From 1a200f8c7bb9e0f0de798988b9cf224934975898 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Fri, 7 Jun 2013 00:53:21 +0200 Subject: [PATCH 5/8] [feature/elliptic-curve] Rename $p -> $prime --- phpseclib/Net/SSH2.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index f6207509..2d030002 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -1162,14 +1162,14 @@ class Net_SSH2 { // see http://tools.ietf.org/html/rfc2409#section-6.2 and // http://tools.ietf.org/html/rfc2412, appendex E case 'diffie-hellman-group1-sha1': - $p = pack('H256', 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . + $prime = pack('H256', 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF'); break; // see http://tools.ietf.org/html/rfc3526#section-3 case 'diffie-hellman-group14-sha1': - $p = pack('H512', 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . + $prime = pack('H512', 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . @@ -1183,7 +1183,7 @@ class Net_SSH2 { $kexHash = new Crypt_Hash('sha1'); $keyLength = min($keyLength, $kexHash->getLength()); - $p = new Math_BigInteger($p, 256); + $prime = new Math_BigInteger($prime, 256); //$q = $p->bitwise_rightShift(1); /* To increase the speed of the key exchange, both client and server may @@ -1198,7 +1198,7 @@ class Net_SSH2 { $g = new Math_BigInteger(2); $x = $one->random($one, $max); - $e = $g->modPow($x, $p); + $e = $g->modPow($x, $prime); $eBytes = $e->toBytes(true); $data = pack('CNa*', NET_SSH2_MSG_KEXDH_INIT, strlen($eBytes), $eBytes); @@ -1236,7 +1236,7 @@ class Net_SSH2 { $temp = unpack('Nlength', $this->_string_shift($this->signature, 4)); $this->signature_format = $this->_string_shift($this->signature, $temp['length']); - $key = $f->modPow($x, $p); + $key = $f->modPow($x, $prime); $keyBytes = $key->toBytes(true); $this->exchange_hash = pack('Na*Na*Na*Na*Na*Na*Na*Na*', From 1c63d4b74664a9c06621c6cbcdce860044350eaa Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Fri, 7 Jun 2013 00:55:23 +0200 Subject: [PATCH 6/8] [feature/elliptic-curve] Specify prime data to BigInteger directly in base 16. --- phpseclib/Net/SSH2.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index 2d030002..869b455b 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -1162,28 +1162,28 @@ class Net_SSH2 { // see http://tools.ietf.org/html/rfc2409#section-6.2 and // http://tools.ietf.org/html/rfc2412, appendex E case 'diffie-hellman-group1-sha1': - $prime = pack('H256', 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . - '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . - '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . - 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF'); + $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . + '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . + '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF'; break; // see http://tools.ietf.org/html/rfc3526#section-3 case 'diffie-hellman-group14-sha1': - $prime = pack('H512', 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . - '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . - '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . - 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . - '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . - '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . - 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . - '3995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF'); + $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . + '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . + '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . + '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . + '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . + '3995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF'; break; } $kexHash = new Crypt_Hash('sha1'); $keyLength = min($keyLength, $kexHash->getLength()); - $prime = new Math_BigInteger($prime, 256); + $prime = new Math_BigInteger($prime, 16); //$q = $p->bitwise_rightShift(1); /* To increase the speed of the key exchange, both client and server may From 2fcbd776058daa93b4d87f09fe8e4be2c6efe995 Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Fri, 7 Jun 2013 00:58:09 +0200 Subject: [PATCH 7/8] [feature/elliptic-curve] Associate the generator (decimal 2) with the prime. --- phpseclib/Net/SSH2.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index 869b455b..2807f839 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -1183,6 +1183,7 @@ class Net_SSH2 { $kexHash = new Crypt_Hash('sha1'); $keyLength = min($keyLength, $kexHash->getLength()); + $g = new Math_BigInteger(2); $prime = new Math_BigInteger($prime, 16); //$q = $p->bitwise_rightShift(1); @@ -1196,7 +1197,6 @@ class Net_SSH2 { $one = new Math_BigInteger(1); $max = $one->bitwise_leftShift(16 * $keyLength)->subtract($one); // 2 * 8 * $keyLength - $g = new Math_BigInteger(2); $x = $one->random($one, $max); $e = $g->modPow($x, $prime); From 61279f1fb6c38649f5bfc2f4c0cf8c68ebb1e74a Mon Sep 17 00:00:00 2001 From: Andreas Fischer Date: Fri, 7 Jun 2013 01:03:03 +0200 Subject: [PATCH 8/8] [feature/elliptic-curve] Add comment for generator 2 and sha1 hash function. --- phpseclib/Net/SSH2.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/phpseclib/Net/SSH2.php b/phpseclib/Net/SSH2.php index 2807f839..9fb29c7c 100644 --- a/phpseclib/Net/SSH2.php +++ b/phpseclib/Net/SSH2.php @@ -1180,11 +1180,11 @@ class Net_SSH2 { break; } - $kexHash = new Crypt_Hash('sha1'); - $keyLength = min($keyLength, $kexHash->getLength()); - + // For both diffie-hellman-group1-sha1 and diffie-hellman-group14-sha1 + // the generator field element is 2 (decimal) and the hash function is sha1. $g = new Math_BigInteger(2); $prime = new Math_BigInteger($prime, 16); + $kexHash = new Crypt_Hash('sha1'); //$q = $p->bitwise_rightShift(1); /* To increase the speed of the key exchange, both client and server may @@ -1195,6 +1195,7 @@ class Net_SSH2 { -- http://tools.ietf.org/html/rfc4419#section-6.2 */ $one = new Math_BigInteger(1); + $keyLength = min($keyLength, $kexHash->getLength()); $max = $one->bitwise_leftShift(16 * $keyLength)->subtract($one); // 2 * 8 * $keyLength $x = $one->random($one, $max);