# HG changeset patch # User Matt Johnston # Date 1364920375 -28800 # Node ID 15999b098cc9e6e701a7d1c1e94e62bb28e97fa7 # Parent 504f33c684b54f2a230263ba7b64a80be3d92a98 Don't usually need to recalculate dh_e for the repeated kexdh_init packet diff -r 504f33c684b5 -r 15999b098cc9 cli-kex.c --- a/cli-kex.c Wed Apr 03 00:32:05 2013 +0800 +++ b/cli-kex.c Wed Apr 03 00:32:55 2013 +0800 @@ -43,11 +43,19 @@ void send_msg_kexdh_init() { TRACE(("send_msg_kexdh_init()")) - cli_ses.dh_e = (mp_int*)m_malloc(sizeof(mp_int)); - cli_ses.dh_x = (mp_int*)m_malloc(sizeof(mp_int)); - m_mp_init_multi(cli_ses.dh_e, cli_ses.dh_x, NULL); + if ((cli_ses.dh_e && cli_ses.dh_x + && cli_ses.dh_val_algo == ses.newkeys->algo_kex)) { + TRACE(("reusing existing dh_e from first_kex_packet_follows")) + } else { + if (!cli_ses.dh_e || !cli_ses.dh_e) { + cli_ses.dh_e = (mp_int*)m_malloc(sizeof(mp_int)); + cli_ses.dh_x = (mp_int*)m_malloc(sizeof(mp_int)); + m_mp_init_multi(cli_ses.dh_e, cli_ses.dh_x, NULL); + } - gen_kexdh_vals(cli_ses.dh_e, cli_ses.dh_x); + gen_kexdh_vals(cli_ses.dh_e, cli_ses.dh_x); + cli_ses.dh_val_algo = ses.newkeys->algo_kex; + } CHECKCLEARTOWRITE(); buf_putbyte(ses.writepayload, SSH_MSG_KEXDH_INIT); @@ -99,6 +107,7 @@ mp_clear_multi(cli_ses.dh_e, cli_ses.dh_x, NULL); m_free(cli_ses.dh_e); m_free(cli_ses.dh_x); + cli_ses.dh_val_algo = DROPBEAR_KEX_NONE; if (buf_verify(ses.payload, hostkey, ses.hash, SHA1_HASH_SIZE) != DROPBEAR_SUCCESS) { diff -r 504f33c684b5 -r 15999b098cc9 cli-session.c --- a/cli-session.c Wed Apr 03 00:32:05 2013 +0800 +++ b/cli-session.c Wed Apr 03 00:32:55 2013 +0800 @@ -182,6 +182,11 @@ TRACE2(("enter cli_sessionloop")) + if (ses.lastpacket == 0) { + TRACE2(("exit cli_sessionloop: no real packets yet")) + return; + } + if (ses.lastpacket == SSH_MSG_KEXINIT && cli_ses.kex_state == KEX_NOTHING) { /* We initiate the KEXDH. If DH wasn't the correct type, the KEXINIT * negotiation would have failed. */ @@ -206,10 +211,9 @@ return; } - /* We should exit if we haven't donefirstkex: we shouldn't reach here - * in normal operation */ if (ses.kexstate.donefirstkex == 0) { - TRACE(("XXX XXX might be bad! leave cli_sessionloop: haven't donefirstkex")) + /* We might reach here if we have partial packet reads or have + * received SSG_MSG_IGNORE etc. Just skip it */ return; } diff -r 504f33c684b5 -r 15999b098cc9 common-algo.c --- a/common-algo.c Wed Apr 03 00:32:05 2013 +0800 +++ b/common-algo.c Wed Apr 03 00:32:55 2013 +0800 @@ -214,8 +214,8 @@ }; algo_type sshkex[] = { + {"diffie-hellman-group14-sha1", DROPBEAR_KEX_DH_GROUP14, NULL, 1, NULL}, {"diffie-hellman-group1-sha1", DROPBEAR_KEX_DH_GROUP1, NULL, 1, NULL}, - {"diffie-hellman-group14-sha1", DROPBEAR_KEX_DH_GROUP14, NULL, 1, NULL}, {KEXGUESS2_ALGO_NAME, KEXGUESS2_ALGO_ID, NULL, 1, NULL}, {NULL, 0, NULL, 0, NULL} }; diff -r 504f33c684b5 -r 15999b098cc9 session.h --- a/session.h Wed Apr 03 00:32:05 2013 +0800 +++ b/session.h Wed Apr 03 00:32:55 2013 +0800 @@ -241,6 +241,7 @@ struct clientsession { mp_int *dh_e, *dh_x; /* Used during KEX */ + int dh_val_algo; /* KEX algorithm corresponding to current dh_e and dh_x */ cli_kex_state kex_state; /* Used for progressing KEX */ cli_state state; /* Used to progress auth/channelsession etc */ unsigned donefirstkex : 1; /* Set when we set sentnewkeys, never reset */ diff -r 504f33c684b5 -r 15999b098cc9 sysoptions.h --- a/sysoptions.h Wed Apr 03 00:32:05 2013 +0800 +++ b/sysoptions.h Wed Apr 03 00:32:55 2013 +0800 @@ -61,8 +61,9 @@ #define DROPBEAR_FAILURE -1 /* various algorithm identifiers */ -#define DROPBEAR_KEX_DH_GROUP1 0 -#define DROPBEAR_KEX_DH_GROUP14 1 +#define DROPBEAR_KEX_NONE 0 +#define DROPBEAR_KEX_DH_GROUP1 1 +#define DROPBEAR_KEX_DH_GROUP14 2 #define DROPBEAR_SIGNKEY_ANY 0 #define DROPBEAR_SIGNKEY_RSA 1