From c797c1750c46d2e111874e31adf5627b24e97462 Mon Sep 17 00:00:00 2001
From: Matt Johnston <matt@ucc.asn.au>
Date: Mon, 8 Apr 2013 00:10:57 +0800
Subject: [PATCH] - Fix various hardcoded uses of SHA1 - rename curves to
 nistp256 etc - fix svr-auth.c TRACE problem

--HG--
branch : ecc
---
 bignum.c         |  7 +++----
 bignum.h         |  3 ++-
 cli-authpubkey.c |  2 +-
 common-algo.c    | 12 ++++++------
 common-kex.c     | 46 ++++++++++++++++++++++------------------------
 ecc.c            | 14 +++++++-------
 ecc.h            |  6 +++---
 svr-auth.c       |  3 +--
 svr-authpubkey.c |  2 +-
 sysoptions.h     |  3 +--
 10 files changed, 47 insertions(+), 51 deletions(-)

diff --git a/bignum.c b/bignum.c
index cf50ddc9..886568d5 100644
--- a/bignum.c
+++ b/bignum.c
@@ -60,7 +60,8 @@ void bytes_to_mp(mp_int *mp, const unsigned char* bytes, unsigned int len) {
 }
 
 /* hash the ssh representation of the mp_int mp */
-void sha1_process_mp(hash_state *hs, mp_int *mp) {
+void hash_process_mp(const struct ltc_hash_descriptor *hash_desc, 
+				hash_state *hs, mp_int *mp) {
 
 	int i;
 	buffer * buf;
@@ -68,8 +69,6 @@ void sha1_process_mp(hash_state *hs, mp_int *mp) {
 	buf = buf_new(512 + 20); /* max buffer is a 4096 bit key, 
 								plus header + some leeway*/
 	buf_putmpint(buf, mp);
-	i = buf->pos;
-	buf_setpos(buf, 0);
-	sha1_process(hs, buf_getptr(buf, i), i);
+	hash_desc->process(hs, buf->data, buf->len);
 	buf_free(buf);
 }
diff --git a/bignum.h b/bignum.h
index 042f8115..f7abc7d3 100644
--- a/bignum.h
+++ b/bignum.h
@@ -30,6 +30,7 @@
 void m_mp_init(mp_int *mp);
 void m_mp_init_multi(mp_int *mp, ...);
 void bytes_to_mp(mp_int *mp, const unsigned char* bytes, unsigned int len);
-void sha1_process_mp(hash_state *hs, mp_int *mp);
+void hash_process_mp(const struct ltc_hash_descriptor *hash_desc, 
+				hash_state *hs, mp_int *mp);
 
 #endif /* _BIGNUM_H_ */
diff --git a/cli-authpubkey.c b/cli-authpubkey.c
index 96eee05c..9fcc2565 100644
--- a/cli-authpubkey.c
+++ b/cli-authpubkey.c
@@ -169,7 +169,7 @@ static void send_msg_userauth_pubkey(sign_key *key, int type, int realsign) {
 		TRACE(("realsign"))
 		/* We put the signature as well - this contains string(session id), then
 		 * the contents of the write payload to this point */
-		sigbuf = buf_new(4 + SHA1_HASH_SIZE + ses.writepayload->len);
+		sigbuf = buf_new(4 + ses.session_id->len + ses.writepayload->len);
 		buf_putbufstring(sigbuf, ses.session_id);
 		buf_putbytes(sigbuf, ses.writepayload->data, ses.writepayload->len);
 		cli_buf_put_sign(ses.writepayload, key, type, sigbuf);
diff --git a/common-algo.c b/common-algo.c
index 04bbd51b..025faaeb 100644
--- a/common-algo.c
+++ b/common-algo.c
@@ -227,13 +227,13 @@ static struct dropbear_kex kex_dh_group14 = {dh_p_14, DH_P_14_LEN, NULL, &sha1_d
 
 #ifdef DROPBEAR_ECDH
 #ifdef DROPBEAR_ECC_256
-static struct dropbear_kex kex_ecdh_secp256r1 = {NULL, 0, &ecc_curve_secp256r1, &sha256_desc };
+static struct dropbear_kex kex_ecdh_nistp256 = {NULL, 0, &ecc_curve_nistp256, &sha256_desc };
 #endif
 #ifdef DROPBEAR_ECC_384
-static struct dropbear_kex kex_ecdh_secp384r1 = {NULL, 0, &ecc_curve_secp384r1, &sha384_desc };
+static struct dropbear_kex kex_ecdh_nistp384 = {NULL, 0, &ecc_curve_nistp384, &sha384_desc };
 #endif
 #ifdef DROPBEAR_ECC_521
-static struct dropbear_kex kex_ecdh_secp521r1 = {NULL, 0, &ecc_curve_secp521r1, &sha512_desc };
+static struct dropbear_kex kex_ecdh_nistp521 = {NULL, 0, &ecc_curve_nistp521, &sha512_desc };
 #endif
 #endif // DROPBEAR_ECDH
 
@@ -241,13 +241,13 @@ static struct dropbear_kex kex_ecdh_secp521r1 = {NULL, 0, &ecc_curve_secp521r1,
 algo_type sshkex[] = {
 #ifdef DROPBEAR_ECDH
 #ifdef DROPBEAR_ECC_256
-	{"ecdh-sha2-secp256r1", 0, &kex_ecdh_secp256r1, 1, NULL},
+	{"ecdh-sha2-nistp256", 0, &kex_ecdh_nistp256, 1, NULL},
 #endif
 #ifdef DROPBEAR_ECC_384
-	{"ecdh-sha2-secp384r1", 0, &kex_ecdh_secp384r1, 1, NULL},
+	{"ecdh-sha2-nistp384", 0, &kex_ecdh_nistp384, 1, NULL},
 #endif
 #ifdef DROPBEAR_ECC_521
-	{"ecdh-sha2-secp521r1", 0, &kex_ecdh_secp521r1, 1, NULL},
+	{"ecdh-sha2-nistp521", 0, &kex_ecdh_nistp521, 1, NULL},
 #endif
 #endif
 	{"diffie-hellman-group1-sha1", 0, &kex_dh_group1, 1, NULL},
diff --git a/common-kex.c b/common-kex.c
index 48569fe2..1543fb8f 100644
--- a/common-kex.c
+++ b/common-kex.c
@@ -85,8 +85,8 @@ static void gen_new_zstreams();
 #endif
 static void read_kex_algos();
 /* helper function for gen_new_keys */
-static void hashkeys(unsigned char *out, int outlen, 
-		const hash_state * hs, unsigned const char X);
+static void hashkeys(unsigned char *out, unsigned int outlen, 
+		const hash_state * hs, const unsigned char X);
 static void finish_kexhashbuf(void);
 
 
@@ -251,26 +251,28 @@ static void kexinitialise() {
  * out must have at least min(SHA1_HASH_SIZE, outlen) bytes allocated.
  *
  * See Section 7.2 of rfc4253 (ssh transport) for details */
-static void hashkeys(unsigned char *out, int outlen, 
+static void hashkeys(unsigned char *out, unsigned int outlen, 
 		const hash_state * hs, const unsigned char X) {
 
+	const struct ltc_hash_descriptor *hashdesc = ses.newkeys->algo_kex->hashdesc;
 	hash_state hs2;
-	int offset;
+	unsigned int offset;
+	unsigned char tmpout[hashdesc->hashsize];
 
 	memcpy(&hs2, hs, sizeof(hash_state));
-	sha1_process(&hs2, &X, 1);
-	sha1_process(&hs2, ses.session_id->data, ses.session_id->len);
-	sha1_done(&hs2, out);
-	for (offset = SHA1_HASH_SIZE; 
+	hashdesc->process(&hs2, &X, 1);
+	hashdesc->process(&hs2, ses.session_id->data, ses.session_id->len);
+	hashdesc->done(&hs2, tmpout);
+	memcpy(out, tmpout, MIN(hashdesc->hashsize, outlen));
+	for (offset = hashdesc->hashsize; 
 			offset < outlen; 
-			offset += SHA1_HASH_SIZE)
+			offset += hashdesc->hashsize)
 	{
 		/* need to extend */
-		unsigned char k2[SHA1_HASH_SIZE];
 		memcpy(&hs2, hs, sizeof(hash_state));
-		sha1_process(&hs2, out, offset);
-		sha1_done(&hs2, k2);
-		memcpy(&out[offset], k2, MIN(outlen - offset, SHA1_HASH_SIZE));
+		hashdesc->process(&hs2, out, offset);
+		hashdesc->done(&hs2, tmpout);
+		memcpy(&out[offset], tmpout, MIN(outlen - offset, hashdesc->hashsize));
 	}
 }
 
@@ -292,14 +294,14 @@ void gen_new_keys() {
 	unsigned char *trans_IV, *trans_key, *recv_IV, *recv_key;
 
 	hash_state hs;
-	unsigned int C2S_keysize, S2C_keysize;
+	const struct ltc_hash_descriptor *hashdesc = ses.newkeys->algo_kex->hashdesc;
 	char mactransletter, macrecvletter; /* Client or server specific */
 
 	TRACE(("enter gen_new_keys"))
 	/* the dh_K and hash are the start of all hashes, we make use of that */
 
-	sha1_init(&hs);
-	sha1_process_mp(&hs, ses.dh_K);
+	hashdesc->init(&hs);
+	hash_process_mp(hashdesc, &hs, ses.dh_K);
 	mp_clear(ses.dh_K);
 	m_free(ses.dh_K);
 	sha1_process(&hs, ses.hash->data, ses.hash->len);
@@ -312,8 +314,6 @@ void gen_new_keys() {
 	    recv_IV		= S2C_IV;
 	    trans_key	= C2S_key;
 	    recv_key	= S2C_key;
-	    C2S_keysize = ses.newkeys->trans.algo_crypt->keysize;
-	    S2C_keysize = ses.newkeys->recv.algo_crypt->keysize;
 		mactransletter = 'E';
 		macrecvletter = 'F';
 	} else {
@@ -321,16 +321,14 @@ void gen_new_keys() {
 	    recv_IV		= C2S_IV;
 	    trans_key	= S2C_key;
 	    recv_key	= C2S_key;
-	    C2S_keysize = ses.newkeys->recv.algo_crypt->keysize;
-	    S2C_keysize = ses.newkeys->trans.algo_crypt->keysize;
 		mactransletter = 'F';
 		macrecvletter = 'E';
 	}
 
-	hashkeys(C2S_IV, SHA1_HASH_SIZE, &hs, 'A');
-	hashkeys(S2C_IV, SHA1_HASH_SIZE, &hs, 'B');
-	hashkeys(C2S_key, C2S_keysize, &hs, 'C');
-	hashkeys(S2C_key, S2C_keysize, &hs, 'D');
+	hashkeys(C2S_IV, sizeof(C2S_IV), &hs, 'A');
+	hashkeys(S2C_IV, sizeof(S2C_IV), &hs, 'B');
+	hashkeys(C2S_key, sizeof(C2S_key), &hs, 'C');
+	hashkeys(S2C_key, sizeof(S2C_key), &hs, 'D');
 
 	if (ses.newkeys->recv.algo_crypt->cipherdesc != NULL) {
 		int recv_cipher = find_cipher(ses.newkeys->recv.algo_crypt->cipherdesc->name);
diff --git a/ecc.c b/ecc.c
index 0f988acd..fc5ea9d0 100644
--- a/ecc.c
+++ b/ecc.c
@@ -9,24 +9,24 @@
 // TODO: use raw bytes for the dp rather than the hex strings in libtomcrypt's ecc.c
 
 #ifdef DROPBEAR_ECC_256
-const struct dropbear_ecc_curve ecc_curve_secp256r1 = {
+const struct dropbear_ecc_curve ecc_curve_nistp256 = {
 	.dp = &ltc_ecc_sets[0],
 	.hash_desc = &sha256_desc,
-	.name = "secp256r1"
+	.name = "nistp256"
 };
 #endif
 #ifdef DROPBEAR_ECC_384
-const struct dropbear_ecc_curve ecc_curve_secp384r1 = {
+const struct dropbear_ecc_curve ecc_curve_nistp384 = {
 	.dp = &ltc_ecc_sets[1],
 	.hash_desc = &sha384_desc,
-	.name = "secp384r1"
+	.name = "nistp384"
 };
 #endif
 #ifdef DROPBEAR_ECC_521
-const struct dropbear_ecc_curve ecc_curve_secp521r1 = {
+const struct dropbear_ecc_curve ecc_curve_nistp521 = {
 	.dp = &ltc_ecc_sets[2],
 	.hash_desc = &sha512_desc,
-	.name = "secp521r1"
+	.name = "nistp521"
 };
 #endif
 
@@ -35,7 +35,7 @@ static ecc_key * new_ecc_key(void) {
    key->pubkey.x = m_malloc(sizeof(mp_int));
    key->pubkey.y = m_malloc(sizeof(mp_int));
    key->pubkey.z = m_malloc(sizeof(mp_int));
-   key->k = m_malloc(sizeof(mp_init));
+   key->k = m_malloc(sizeof(mp_int));
    m_mp_init_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL);
    return key;
 }
diff --git a/ecc.h b/ecc.h
index d72fbb1d..dcf190e1 100644
--- a/ecc.h
+++ b/ecc.h
@@ -14,9 +14,9 @@ struct dropbear_ecc_curve {
 	const char *name;
 };
 
-extern const struct dropbear_ecc_curve ecc_curve_secp256r1;
-extern const struct dropbear_ecc_curve ecc_curve_secp384r1;
-extern const struct dropbear_ecc_curve ecc_curve_secp521r1;
+extern const struct dropbear_ecc_curve ecc_curve_nistp256;
+extern const struct dropbear_ecc_curve ecc_curve_nistp384;
+extern const struct dropbear_ecc_curve ecc_curve_nistp521;
 
 // "pubkey" refers to a point, but LTC uses ecc_key structure for both public
 // and private keys
diff --git a/svr-auth.c b/svr-auth.c
index dca95f55..eb518fc4 100644
--- a/svr-auth.c
+++ b/svr-auth.c
@@ -332,8 +332,7 @@ void send_msg_userauth_failure(int partial, int incrfail) {
 	buf_putbufstring(ses.writepayload, typebuf);
 
 	TRACE(("auth fail: methods %d, '%.*s'", ses.authstate.authtypes,
-				typebuf->len,
-				buf_getptr(typebuf, typebuf->len)));
+				typebuf->len, typebuf->data))
 
 	buf_free(typebuf);
 
diff --git a/svr-authpubkey.c b/svr-authpubkey.c
index 1c5f9d6b..e0727de7 100644
--- a/svr-authpubkey.c
+++ b/svr-authpubkey.c
@@ -125,7 +125,7 @@ void svr_auth_pubkey() {
 
 	/* create the data which has been signed - this a string containing
 	 * session_id, concatenated with the payload packet up to the signature */
-	signbuf = buf_new(ses.payload->pos + 4 + SHA1_HASH_SIZE);
+	signbuf = buf_new(ses.payload->pos + 4 + ses.session_id->len);
 	buf_putbufstring(signbuf, ses.session_id);
 	buf_putbytes(signbuf, ses.payload->data, ses.payload->pos);
 	buf_setpos(signbuf, 0);
diff --git a/sysoptions.h b/sysoptions.h
index d31b56f6..a6b1364e 100644
--- a/sysoptions.h
+++ b/sysoptions.h
@@ -74,8 +74,7 @@
 #define MD5_HASH_SIZE 16
 
 #define MAX_KEY_LEN 32 /* 256 bits for aes256 etc */
-#define MAX_IV_LEN 20 /* must be same as max blocksize, 
-						 and >= SHA1_HASH_SIZE */
+#define MAX_IV_LEN 20 /* must be same as max blocksize,  */
 
 #if defined(DROPBEAR_SHA2_512_HMAC)
 #define MAX_MAC_LEN 64
-- 
GitLab