changeset 761:ac2158e3e403 ecc

ecc kind of works, needs fixing/testing
author Matt Johnston <matt@ucc.asn.au>
date Sun, 07 Apr 2013 01:36:42 +0800
parents f336d232fc63
children a78a38e402d1
files Makefile.in algo.h buffer.h cli-agentfwd.c cli-authpubkey.c cli-chansession.c cli-kex.c common-algo.c common-kex.c common-session.c debug.h ecc.c libtomcrypt/Makefile.in libtomcrypt/src/headers/tomcrypt.h libtomcrypt/src/headers/tomcrypt_custom.h libtomcrypt/src/headers/tomcrypt_math.h libtomcrypt/src/misc/crypt/crypt_ltc_mp_descriptor.c libtomcrypt/src/pk/ecc/ecc_decrypt_key.c libtomcrypt/src/pk/ecc/ecc_encrypt_key.c libtomcrypt/src/pk/ecc/ecc_export.c libtomcrypt/src/pk/ecc/ecc_import.c libtomcrypt/src/pk/ecc/ecc_sign_hash.c libtomcrypt/src/pk/ecc/ecc_verify_hash.c ltc_prng.c options.h random.c random.h session.h svr-auth.c svr-authpubkey.c svr-kex.c sysoptions.h
diffstat 32 files changed, 174 insertions(+), 120 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile.in	Sat Apr 06 16:00:37 2013 +0800
+++ b/Makefile.in	Sun Apr 07 01:36:42 2013 +0800
@@ -17,9 +17,9 @@
 LTM=libtommath/libtommath.a
 
 ifeq (@BUNDLED_LIBTOM@, 1)
-LIBTOM_DEPS=$(LTC) $(LTM)
-CFLAGS+=-I$(srcdir)/libtomcrypt/src/headers/ 
-LIBS+=$(LTC) $(LTM)
+LIBTOM_DEPS=$(LTM) $(LTC)
+CFLAGS+=-I$(srcdir)/libtomcrypt/src/headers/
+LIBS+=$(LTM) $(LTC)
 endif
 
 COMMONOBJS=dbutil.o buffer.o \
@@ -185,7 +185,7 @@
 	-ln -s dropbearmulti$(EXEEXT) $*$(EXEEXT)
 
 $(LTC): options.h
-	cd libtomcrypt && $(MAKE) clean && $(MAKE)
+	cd libtomcrypt && $(MAKE)
 
 $(LTM): options.h
 	cd libtommath && $(MAKE)
--- a/algo.h	Sat Apr 06 16:00:37 2013 +0800
+++ b/algo.h	Sun Apr 07 01:36:42 2013 +0800
@@ -36,7 +36,7 @@
 struct Algo_Type {
 
 	const unsigned char *name; /* identifying name */
-	const char val; /* a value for this cipher, or -1 for invalid */
+	char val; /* a value for this cipher, or -1 for invalid */
 	const void *data; /* algorithm specific data */
 	char usable; /* whether we can use this algorithm */
 	const void *mode; /* the mode, currently only used for ciphers,
@@ -120,5 +120,6 @@
 	DROPBEAR_COMP_ZLIB_DELAY,
 };
 
+extern int dropbear_ltc_prng;
 
 #endif /* _ALGO_H_ */
--- a/buffer.h	Sat Apr 06 16:00:37 2013 +0800
+++ b/buffer.h	Sun Apr 07 01:36:42 2013 +0800
@@ -59,7 +59,7 @@
 void buf_eatstring(buffer *buf);
 void buf_putint(buffer* buf, unsigned int val);
 void buf_putstring(buffer* buf, const unsigned char* str, unsigned int len);
-void buf_putstringbuf(buffer *buf, const buffer* buf_str);
+void buf_putbufstring(buffer *buf, const buffer* buf_str);
 void buf_putbytes(buffer *buf, const unsigned char *bytes, unsigned int len);
 void buf_putmpint(buffer* buf, mp_int * mp);
 int buf_getmpint(buffer* buf, mp_int* mp);
--- a/cli-agentfwd.c	Sat Apr 06 16:00:37 2013 +0800
+++ b/cli-agentfwd.c	Sun Apr 07 01:36:42 2013 +0800
@@ -266,7 +266,7 @@
 	string			data
 	uint32			flags
 	*/
-	request_data = buf_new(MAX_PUBKEY_SIZE + data_buf>-len + 12);
+	request_data = buf_new(MAX_PUBKEY_SIZE + data_buf->len + 12);
 	buf_put_pub_key(request_data, key, key->type);
 	
 	buf_putbufstring(request_data, data_buf);
--- a/cli-authpubkey.c	Sat Apr 06 16:00:37 2013 +0800
+++ b/cli-authpubkey.c	Sun Apr 07 01:36:42 2013 +0800
@@ -172,7 +172,7 @@
 		sigbuf = buf_new(4 + SHA1_HASH_SIZE + 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->data, sigbuf->len);
+		cli_buf_put_sign(ses.writepayload, key, type, sigbuf);
 		buf_free(sigbuf); /* Nothing confidential in the buffer */
 	}
 
--- a/cli-chansession.c	Sat Apr 06 16:00:37 2013 +0800
+++ b/cli-chansession.c	Sun Apr 07 01:36:42 2013 +0800
@@ -455,7 +455,7 @@
 }
 
 static
-void cli_escape_handler(struct Channel *channel, unsigned char* buf, int *len) {
+void cli_escape_handler(struct Channel* UNUSED(channel), unsigned char* buf, int *len) {
 	char c;
 	int skip_char = 0;
 
--- a/cli-kex.c	Sat Apr 06 16:00:37 2013 +0800
+++ b/cli-kex.c	Sun Apr 07 01:36:42 2013 +0800
@@ -36,6 +36,7 @@
 #include "random.h"
 #include "runopts.h"
 #include "signkey.h"
+#include "ecc.h"
 
 
 static void checkhostkey(unsigned char* keyblob, unsigned int keybloblen);
@@ -50,6 +51,7 @@
 	} else {
 #ifdef DROPBEAR_ECDH
 		cli_ses.ecdh_param = gen_kexecdh_param();
+		buf_put_ecc_pubkey_string(ses.writepayload, &cli_ses.ecdh_param->key);
 #endif
 	}
 	encrypt_packet();
@@ -99,14 +101,14 @@
 	} else {
 #ifdef DROPBEAR_ECDH
 		buffer *ecdh_qs = buf_getstringbuf(ses.payload);
-		kexecdh_comb_key(cli_ses.dh_param, ecdh_qs, hostkey);
+		kexecdh_comb_key(cli_ses.ecdh_param, ecdh_qs, hostkey);
 		buf_free(ecdh_qs);
 #endif
 	}
 	free_kexdh_param(cli_ses.dh_param);
 	cli_ses.dh_param = NULL;
 
-	if (buf_verify(ses.payload, hostkey, ses.hash, SHA1_HASH_SIZE) 
+	if (buf_verify(ses.payload, hostkey, ses.hash) 
 			!= DROPBEAR_SUCCESS) {
 		dropbear_exit("Bad hostkey signature");
 	}
--- a/common-algo.c	Sat Apr 06 16:00:37 2013 +0800
+++ b/common-algo.c	Sun Apr 07 01:36:42 2013 +0800
@@ -23,24 +23,33 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE. */
 
+#include "includes.h"
 #include "algo.h"
 #include "dbutil.h"
 #include "kex.h"
+#include "ltc_prng.h"
+#include "ecc.h"
 
 /* This file (algo.c) organises the ciphers which can be used, and is used to
  * decide which ciphers/hashes/compression/signing to use during key exchange*/
 
+#ifdef DROPBEAR_LTC_PRNG
+	int dropbear_ltc_prng = -1;
+#endif
+
+
+
 static int void_cipher(const unsigned char* in, unsigned char* out,
-		unsigned long len, void *cipher_state) {
+		unsigned long len, void* UNUSED(cipher_state)) {
 	if (in != out) {
 		memmove(out, in, len);
 	}
 	return CRYPT_OK;
 }
 
-static int void_start(int cipher, const unsigned char *IV, 
-			const unsigned char *key, 
-			int keylen, int num_rounds, void *cipher_state) {
+static int void_start(int UNUSED(cipher), const unsigned char* UNUSED(IV), 
+			const unsigned char* UNUSED(key), 
+			int UNUSED(keylen), int UNUSED(num_rounds), void* UNUSED(cipher_state)) {
 	return CRYPT_OK;
 }
 
@@ -216,7 +225,7 @@
 static struct dropbear_kex kex_dh_group1 = {dh_p_1, DH_P_1_LEN, NULL, &sha1_desc };
 static struct dropbear_kex kex_dh_group14 = {dh_p_14, DH_P_14_LEN, NULL, &sha1_desc };
 
-#ifdef DROPBEAR_ECC_DH
+#ifdef DROPBEAR_ECDH
 #ifdef DROPBEAR_ECC_256
 static struct dropbear_kex kex_ecdh_secp256r1 = {NULL, 0, &ecc_curve_secp256r1, &sha256_desc };
 #endif
@@ -226,19 +235,19 @@
 #ifdef DROPBEAR_ECC_521
 static struct dropbear_kex kex_ecdh_secp521r1 = {NULL, 0, &ecc_curve_secp521r1, &sha512_desc };
 #endif
-#endif // DROPBEAR_ECC_DH
+#endif // DROPBEAR_ECDH
 
 
 algo_type sshkex[] = {
-#ifdef DROPBEAR_ECC_DH
+#ifdef DROPBEAR_ECDH
 #ifdef DROPBEAR_ECC_256
-	{"ecdh-sha2-secp256r1", 0, &kex_ecdh_descp256r1, 1, NULL},
+	{"ecdh-sha2-secp256r1", 0, &kex_ecdh_secp256r1, 1, NULL},
 #endif
 #ifdef DROPBEAR_ECC_384
-	{"ecdh-sha2-secp384r1", 0, &kex_ecdh_descp384r1, 1, NULL},
+	{"ecdh-sha2-secp384r1", 0, &kex_ecdh_secp384r1, 1, NULL},
 #endif
 #ifdef DROPBEAR_ECC_521
-	{"ecdh-sha2-secp521r1", 0, &kex_ecdh_descp521r1, 1, NULL},
+	{"ecdh-sha2-secp521r1", 0, &kex_ecdh_secp521r1, 1, NULL},
 #endif
 #endif
 	{"diffie-hellman-group1-sha1", 0, &kex_dh_group1, 1, NULL},
@@ -297,6 +306,17 @@
 			dropbear_exit("Error registering crypto");
 		}
 	}
+
+#ifdef DROPBEAR_LTC_PRNG
+	dropbear_ltc_prng = register_prng(&dropbear_prng_desc);
+	if (dropbear_ltc_prng == -1) {
+		dropbear_exit("Error registering crypto");
+	}
+#endif
+
+#ifdef DROPBEAR_ECC
+	ltc_mp = ltm_desc;
+#endif
 }
 
 /* algolen specifies the length of algo, algos is our local list to match
--- a/common-kex.c	Sat Apr 06 16:00:37 2013 +0800
+++ b/common-kex.c	Sun Apr 07 01:36:42 2013 +0800
@@ -87,6 +87,7 @@
 /* helper function for gen_new_keys */
 static void hashkeys(unsigned char *out, int outlen, 
 		const hash_state * hs, unsigned const char X);
+static void finish_kexhashbuf(void);
 
 
 /* Send our list of algorithms we can use */
@@ -258,7 +259,7 @@
 
 	memcpy(&hs2, hs, sizeof(hash_state));
 	sha1_process(&hs2, &X, 1);
-	sha1_process(&hs2, ses.session_id, SHA1_HASH_SIZE);
+	sha1_process(&hs2, ses.session_id->data, ses.session_id->len);
 	sha1_done(&hs2, out);
 	for (offset = SHA1_HASH_SIZE; 
 			offset < outlen; 
@@ -301,8 +302,10 @@
 	sha1_process_mp(&hs, ses.dh_K);
 	mp_clear(ses.dh_K);
 	m_free(ses.dh_K);
-	sha1_process(&hs, ses.hash, SHA1_HASH_SIZE);
-	m_burn(ses.hash, SHA1_HASH_SIZE);
+	sha1_process(&hs, ses.hash->data, ses.hash->len);
+	buf_burn(ses.hash);
+	buf_free(ses.hash);
+	ses.hash = NULL;
 
 	if (IS_DROPBEAR_CLIENT) {
 	    trans_IV	= C2S_IV;
@@ -596,8 +599,6 @@
 	mp_int dh_p;
 	mp_int *dh_e = NULL, *dh_f = NULL;
 
-	hash_state hs;
-
 	/* read the prime and generator*/
 	m_mp_init(&dh_p);
 	load_dh_p(&dh_p);
@@ -639,25 +640,7 @@
 	buf_putmpint(ses.kexhashbuf, ses.dh_K);
 
 	/* calculate the hash H to sign */
-	sha1_init(&hs);
-	buf_setpos(ses.kexhashbuf, 0);
-	sha1_process(&hs, buf_getptr(ses.kexhashbuf, ses.kexhashbuf->len),
-			ses.kexhashbuf->len);
-	
-		ses.hash = m_malloc(SHA1_HASH_SIZE);
-	}
-	sha1_done(&hs, ses.hash);
-
-	buf_burn(ses.kexhashbuf);
-	buf_free(ses.kexhashbuf);
-	ses.kexhashbuf = NULL;
-	
-	/* first time around, we set the session_id to H */
-	if (ses.session_id == NULL) {
-		/* create the session_id, this never needs freeing */
-		ses.session_id = (unsigned char*)m_malloc(SHA1_HASH_SIZE);
-		memcpy(ses.session_id, ses.hash, SHA1_HASH_SIZE);
-	}
+	finish_kexhashbuf();
 }
 
 #ifdef DROPBEAR_ECDH
@@ -685,25 +668,25 @@
 	// XXX load Q_them
 	Q_them = buf_get_ecc_pubkey(pub_them, algo_kex->ecc_curve);
 
-	ses.dh_K = dropbear_ecc_shared_secret(Q_them, param->key);
+	ses.dh_K = dropbear_ecc_shared_secret(Q_them, &param->key);
 
 	/* From here on, the code needs to work with the _same_ vars on each side,
 	 * not vice-versaing for client/server */
 	if (IS_DROPBEAR_CLIENT) {
-		Q_C = param->key;
+		Q_C = &param->key;
 		Q_S = Q_them;
 	} else {
 		Q_C = Q_them;
-		Q_S = param->key;
+		Q_S = &param->key;
 	} 
 
 	/* Create the remainder of the hash buffer, to generate the exchange hash */
 	/* K_S, the host key */
 	buf_put_pub_key(ses.kexhashbuf, hostkey, ses.newkeys->algo_hostkey);
 	/* Q_C, client's ephemeral public key octet string */
-	buf_put_ecc_pubkey_string(Q_C);
+	buf_put_ecc_pubkey_string(ses.kexhashbuf, Q_C);
 	/* Q_S, server's ephemeral public key octet string */
-	buf_put_ecc_pubkey_string(Q_S);
+	buf_put_ecc_pubkey_string(ses.kexhashbuf, Q_S);
 	/* K, the shared secret */
 	buf_putmpint(ses.kexhashbuf, ses.dh_K);
 
@@ -712,10 +695,23 @@
 	buf_setpos(ses.kexhashbuf, 0);
 	algo_kex->hashdesc->process(&hs, buf_getptr(ses.kexhashbuf, ses.kexhashbuf->len),
 			ses.kexhashbuf->len);
-	if (!ses.hash) {
-		ses.hash = m_malloc(algo_kex->hashdesc->hashsize);
-	}
-	algo_kex->hashdesc->done(&hs, ses.hash);
+
+	/* calculate the hash H to sign */
+	finish_kexhashbuf();
+}
+#endif
+
+static void finish_kexhashbuf(void) {
+	hash_state hs;
+	const struct ltc_hash_descriptor *hashdesc = ses.newkeys->algo_kex->hashdesc;
+
+	hashdesc->init(&hs);
+	buf_setpos(ses.kexhashbuf, 0);
+	hashdesc->process(&hs, buf_getptr(ses.kexhashbuf, ses.kexhashbuf->len),
+			ses.kexhashbuf->len);
+	ses.hash = buf_new(hashdesc->hashsize);
+	hashdesc->done(&hs, buf_getwriteptr(ses.hash, hashdesc->hashsize));
+	buf_setlen(ses.hash, hashdesc->hashsize);
 
 	buf_burn(ses.kexhashbuf);
 	buf_free(ses.kexhashbuf);
@@ -724,12 +720,10 @@
 	/* first time around, we set the session_id to H */
 	if (ses.session_id == NULL) {
 		/* create the session_id, this never needs freeing */
-		ses.session_id = m_malloc(algo_kex->hashdesc->hashsize);
-		memcpy(ses.session_id, ses.hash, algo_kex->hashdesc->hashsize);
+		ses.session_id = buf_newcopy(ses.hash);
 	}
 
 }
-#endif
 
 /* read the other side's algo list. buf_match_algo is a callback to match
  * algos for the client or server. */
--- a/common-session.c	Sat Apr 06 16:00:37 2013 +0800
+++ b/common-session.c	Sun Apr 07 01:36:42 2013 +0800
@@ -103,7 +103,7 @@
 	ses.keys->recv.algo_mac = &dropbear_nohash;
 	ses.keys->trans.algo_mac = &dropbear_nohash;
 
-	ses.keys->algo_kex = -1;
+	ses.keys->algo_kex = NULL;
 	ses.keys->algo_hostkey = -1;
 	ses.keys->recv.algo_comp = DROPBEAR_COMP_NONE;
 	ses.keys->trans.algo_comp = DROPBEAR_COMP_NONE;
@@ -235,7 +235,16 @@
 		return;
 	}
 	
-	m_free(ses.session_id);
+	if (ses.session_id) {
+		buf_burn(ses.session_id);
+		buf_free(ses.session_id);
+		ses.session_id = NULL;
+	}
+	if (ses.hash) {
+		buf_burn(ses.hash);
+		buf_free(ses.hash);
+		ses.hash = NULL;
+	}
 	m_burn(ses.keys, sizeof(struct key_context));
 	m_free(ses.keys);
 
--- a/debug.h	Sat Apr 06 16:00:37 2013 +0800
+++ b/debug.h	Sun Apr 07 01:36:42 2013 +0800
@@ -39,7 +39,7 @@
  * Caution: Don't use this in an unfriendly environment (ie unfirewalled),
  * since the printing may not sanitise strings etc. This will add a reasonable
  * amount to your executable size. */
-/*#define DEBUG_TRACE */
+#define DEBUG_TRACE
 
 /* All functions writing to the cleartext payload buffer call
  * CHECKCLEARTOWRITE() before writing. This is only really useful if you're
@@ -69,7 +69,7 @@
 
 /* To debug with GDB it is easier to run with no forking of child processes.
    You will need to pass "-F" as well. */
-/* #define DEBUG_NOFORK */
+#define DEBUG_NOFORK
 
 
 /* For testing as non-root on shadowed systems, include the crypt of a password
--- a/ecc.c	Sat Apr 06 16:00:37 2013 +0800
+++ b/ecc.c	Sun Apr 07 01:36:42 2013 +0800
@@ -110,7 +110,7 @@
 ecc_key * buf_get_ecc_pubkey(buffer *buf, const struct dropbear_ecc_curve *curve) {
    ecc_key *key = NULL;
    int ret = DROPBEAR_FAILURE;
-   const int size = curve->dp->size;
+   const unsigned int size = curve->dp->size;
    buf_setpos(buf, 0);
    unsigned int len = buf->len;
    unsigned char first = buf_getbyte(buf);
@@ -123,6 +123,7 @@
    }
 
    key = new_ecc_key();
+   key->dp = curve->dp;
 
    if (mp_read_unsigned_bin(key->pubkey.x, buf_getptr(buf, size), size) != MP_OKAY) {
       goto out;
--- a/libtomcrypt/Makefile.in	Sat Apr 06 16:00:37 2013 +0800
+++ b/libtomcrypt/Makefile.in	Sun Apr 07 01:36:42 2013 +0800
@@ -19,7 +19,7 @@
 
 # Compilation flags. Note the += does not write over the user's CFLAGS!
 # The rest of the flags come from the parent Dropbear makefile
-CFLAGS += -c -I$(srcdir)/src/headers/ -I$(srcdir)/../ -DLTC_SOURCE
+CFLAGS += -c -I$(srcdir)/src/headers/ -I$(srcdir)/../ -DLTC_SOURCE -I$(srcdir)/../libtommath/
 
 # additional warnings (newer GCC 3.4 and higher)
 ifdef GCC_34
@@ -157,7 +157,53 @@
 src/modes/lrw/lrw_getiv.o src/modes/lrw/lrw_process.o src/modes/lrw/lrw_setiv.o \
 src/modes/lrw/lrw_start.o src/modes/lrw/lrw_test.o src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o \
 src/modes/ofb/ofb_encrypt.o src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o \
-src/modes/ofb/ofb_start.o 
+src/modes/ofb/ofb_start.o src/pk/asn1/der/bit/der_decode_bit_string.o \
+src/pk/asn1/der/bit/der_encode_bit_string.o src/pk/asn1/der/bit/der_length_bit_string.o \
+src/pk/asn1/der/boolean/der_decode_boolean.o src/pk/asn1/der/boolean/der_encode_boolean.o \
+src/pk/asn1/der/boolean/der_length_boolean.o src/pk/asn1/der/choice/der_decode_choice.o \
+src/pk/asn1/der/ia5/der_decode_ia5_string.o src/pk/asn1/der/ia5/der_encode_ia5_string.o \
+src/pk/asn1/der/ia5/der_length_ia5_string.o src/pk/asn1/der/integer/der_decode_integer.o \
+src/pk/asn1/der/integer/der_encode_integer.o src/pk/asn1/der/integer/der_length_integer.o \
+src/pk/asn1/der/object_identifier/der_decode_object_identifier.o \
+src/pk/asn1/der/object_identifier/der_encode_object_identifier.o \
+src/pk/asn1/der/object_identifier/der_length_object_identifier.o \
+src/pk/asn1/der/octet/der_decode_octet_string.o src/pk/asn1/der/octet/der_encode_octet_string.o \
+src/pk/asn1/der/octet/der_length_octet_string.o \
+src/pk/asn1/der/printable_string/der_decode_printable_string.o \
+src/pk/asn1/der/printable_string/der_encode_printable_string.o \
+src/pk/asn1/der/printable_string/der_length_printable_string.o \
+src/pk/asn1/der/sequence/der_decode_sequence_ex.o \
+src/pk/asn1/der/sequence/der_decode_sequence_flexi.o \
+src/pk/asn1/der/sequence/der_decode_sequence_multi.o \
+src/pk/asn1/der/sequence/der_encode_sequence_ex.o \
+src/pk/asn1/der/sequence/der_encode_sequence_multi.o src/pk/asn1/der/sequence/der_length_sequence.o \
+src/pk/asn1/der/sequence/der_sequence_free.o src/pk/asn1/der/set/der_encode_set.o \
+src/pk/asn1/der/set/der_encode_setof.o src/pk/asn1/der/short_integer/der_decode_short_integer.o \
+src/pk/asn1/der/short_integer/der_encode_short_integer.o \
+src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \
+src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \
+src/pk/asn1/der/utf8/der_decode_utf8_string.o src/pk/asn1/der/utf8/der_encode_utf8_string.o \
+src/pk/asn1/der/utf8/der_length_utf8_string.o src/pk/dsa/dsa_decrypt_key.o \
+src/pk/dsa/dsa_encrypt_key.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o \
+src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_shared_secret.o src/pk/dsa/dsa_sign_hash.o \
+src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc.o \
+src/pk/ecc/ecc_ansi_x963_export.o src/pk/ecc/ecc_ansi_x963_import.o src/pk/ecc/ecc_decrypt_key.o \
+src/pk/ecc/ecc_encrypt_key.o src/pk/ecc/ecc_export.o src/pk/ecc/ecc_free.o src/pk/ecc/ecc_get_size.o \
+src/pk/ecc/ecc_import.o src/pk/ecc/ecc_make_key.o src/pk/ecc/ecc_shared_secret.o \
+src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_test.o src/pk/ecc/ecc_verify_hash.o \
+src/pk/ecc/ltc_ecc_is_valid_idx.o src/pk/ecc/ltc_ecc_map.o src/pk/ecc/ltc_ecc_mul2add.o \
+src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \
+src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \
+src/pk/katja/katja_decrypt_key.o src/pk/katja/katja_encrypt_key.o src/pk/katja/katja_export.o \
+src/pk/katja/katja_exptmod.o src/pk/katja/katja_free.o src/pk/katja/katja_import.o \
+src/pk/katja/katja_make_key.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \
+src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \
+src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v1_5_decode.o \
+src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \
+src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \
+src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o \
+src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \
+src/prngs/sprng.o src/prngs/yarrow.o 
 
 HEADERS=src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \
 src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \
--- a/libtomcrypt/src/headers/tomcrypt.h	Sat Apr 06 16:00:37 2013 +0800
+++ b/libtomcrypt/src/headers/tomcrypt.h	Sun Apr 07 01:36:42 2013 +0800
@@ -24,7 +24,7 @@
 
 /* descriptor table size */
 /* Dropbear change - this should be smaller, saves some size */
-#define TAB_SIZE    4
+#define TAB_SIZE    5
 
 /* error codes [will be expanded in future releases] */
 enum {
--- a/libtomcrypt/src/headers/tomcrypt_custom.h	Sat Apr 06 16:00:37 2013 +0800
+++ b/libtomcrypt/src/headers/tomcrypt_custom.h	Sun Apr 07 01:36:42 2013 +0800
@@ -138,6 +138,8 @@
 
 #ifdef DROPBEAR_ECC
 #define MECC
+#define MPI
+#define LTM_DESC
 #ifdef DROPBEAR_ECC_256
 #define ECC256
 #endif
--- a/libtomcrypt/src/headers/tomcrypt_math.h	Sat Apr 06 16:00:37 2013 +0800
+++ b/libtomcrypt/src/headers/tomcrypt_math.h	Sun Apr 07 01:36:42 2013 +0800
@@ -11,12 +11,9 @@
    typedef void ecc_point;
 #endif
 
-/* Dropbear has its own rsa_key. We just comment this out. */
-#if 0
 #ifndef MRSA
    typedef void rsa_key;
 #endif
-#endif
 
 /** math descriptor */
 typedef struct {
@@ -389,8 +386,6 @@
                       ecc_point *C,
                            void *modulus);
 
-/* Dropbear has its own rsa code */
-#if 0
 /* ---- (optional) rsa optimized math (for internal CRT) ---- */
 
    /** RSA Key Generation 
@@ -416,7 +411,6 @@
    int (*rsa_me)(const unsigned char *in,   unsigned long inlen,
                        unsigned char *out,  unsigned long *outlen, int which,
                        rsa_key *key);
-#endif
 } ltc_math_descriptor;
 
 extern ltc_math_descriptor ltc_mp;
--- a/libtomcrypt/src/misc/crypt/crypt_ltc_mp_descriptor.c	Sat Apr 06 16:00:37 2013 +0800
+++ b/libtomcrypt/src/misc/crypt/crypt_ltc_mp_descriptor.c	Sun Apr 07 01:36:42 2013 +0800
@@ -10,4 +10,4 @@
  */
 #include "tomcrypt.h"
 
-ltc_math_descriptor ltc_mp;
+ltc_math_descriptor ltc_mp = {0};
--- a/libtomcrypt/src/pk/ecc/ecc_decrypt_key.c	Sat Apr 06 16:00:37 2013 +0800
+++ b/libtomcrypt/src/pk/ecc/ecc_decrypt_key.c	Sun Apr 07 01:36:42 2013 +0800
@@ -21,7 +21,7 @@
   ECC Crypto, Tom St Denis
 */  
 
-#ifdef MECC
+#if defined(MECC) && defined(LTC_DER)
 
 /**
   Decrypt an ECC encrypted key
--- a/libtomcrypt/src/pk/ecc/ecc_encrypt_key.c	Sat Apr 06 16:00:37 2013 +0800
+++ b/libtomcrypt/src/pk/ecc/ecc_encrypt_key.c	Sun Apr 07 01:36:42 2013 +0800
@@ -21,7 +21,7 @@
   ECC Crypto, Tom St Denis
 */  
 
-#ifdef MECC
+#if defined(MECC) && defined(LTC_DER)
 
 /**
   Encrypt a symmetric key with ECC 
--- a/libtomcrypt/src/pk/ecc/ecc_export.c	Sat Apr 06 16:00:37 2013 +0800
+++ b/libtomcrypt/src/pk/ecc/ecc_export.c	Sun Apr 07 01:36:42 2013 +0800
@@ -21,7 +21,7 @@
   ECC Crypto, Tom St Denis
 */  
 
-#ifdef MECC
+#if defined(MECC) && defined(LTC_DER)
 
 /**
   Export an ECC key as a binary packet
--- a/libtomcrypt/src/pk/ecc/ecc_import.c	Sat Apr 06 16:00:37 2013 +0800
+++ b/libtomcrypt/src/pk/ecc/ecc_import.c	Sun Apr 07 01:36:42 2013 +0800
@@ -21,7 +21,7 @@
   ECC Crypto, Tom St Denis
 */  
 
-#ifdef MECC
+#if defined(MECC) && defined(LTC_DER)
 
 static int is_point(ecc_key *key)
 {
--- a/libtomcrypt/src/pk/ecc/ecc_sign_hash.c	Sat Apr 06 16:00:37 2013 +0800
+++ b/libtomcrypt/src/pk/ecc/ecc_sign_hash.c	Sun Apr 07 01:36:42 2013 +0800
@@ -21,7 +21,7 @@
   ECC Crypto, Tom St Denis
 */  
 
-#ifdef MECC
+#if defined(MECC) && defined(LTC_DER)
 
 /**
   Sign a message digest
--- a/libtomcrypt/src/pk/ecc/ecc_verify_hash.c	Sat Apr 06 16:00:37 2013 +0800
+++ b/libtomcrypt/src/pk/ecc/ecc_verify_hash.c	Sun Apr 07 01:36:42 2013 +0800
@@ -21,7 +21,7 @@
   ECC Crypto, Tom St Denis
 */  
 
-#ifdef MECC
+#if defined(MECC) && defined(LTC_DER)
 
 /* verify 
  *
--- a/ltc_prng.c	Sat Apr 06 16:00:37 2013 +0800
+++ b/ltc_prng.c	Sun Apr 07 01:36:42 2013 +0800
@@ -33,7 +33,7 @@
   @param prng     [out] The PRNG state to initialize
   @return CRYPT_OK if successful
 */  
-int dropbear_prng_start(prng_state *prng)
+int dropbear_prng_start(prng_state* UNUSED(prng))
 {
    return CRYPT_OK;  
 }
@@ -45,7 +45,7 @@
   @param prng     PRNG state to update
   @return CRYPT_OK if successful
 */  
-int dropbear_prng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng)
+int dropbear_prng_add_entropy(const unsigned char* UNUSED(in), unsigned long UNUSED(inlen), prng_state* UNUSED(prng))
 {
    return CRYPT_OK;
 }
@@ -55,7 +55,7 @@
   @param prng   The PRNG to make active
   @return CRYPT_OK if successful
 */  
-int dropbear_prng_ready(prng_state *prng)
+int dropbear_prng_ready(prng_state* UNUSED(prng))
 {
    return CRYPT_OK;
 }
@@ -67,11 +67,11 @@
   @param prng     The active PRNG to read from
   @return Number of octets read
 */  
-unsigned long dropbear_prng_read(unsigned char *out, unsigned long outlen, prng_state *prng)
+unsigned long dropbear_prng_read(unsigned char* out, unsigned long outlen, prng_state* UNUSED(prng))
 {
    LTC_ARGCHK(out != NULL);
    genrandom(out, outlen);
-   return CRYPT_OK;
+   return outlen;
 }
 
 /**
@@ -79,7 +79,7 @@
   @param prng   The PRNG to terminate
   @return CRYPT_OK if successful
 */  
-int dropbear_prng_done(prng_state *prng)
+int dropbear_prng_done(prng_state* UNUSED(prng))
 {
    return CRYPT_OK;
 }
@@ -91,7 +91,7 @@
   @param prng      The PRNG to export
   @return CRYPT_OK if successful
 */  
-int dropbear_prng_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
+int dropbear_prng_export(unsigned char* UNUSED(out), unsigned long* outlen, prng_state* UNUSED(prng))
 {
    LTC_ARGCHK(outlen != NULL);
 
@@ -106,7 +106,7 @@
   @param prng     The PRNG to import
   @return CRYPT_OK if successful
 */  
-int dropbear_prng_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
+int dropbear_prng_import(const unsigned char* UNUSED(in), unsigned long UNUSED(inlen), prng_state* UNUSED(prng))
 {
    return CRYPT_OK;
 }
--- a/options.h	Sat Apr 06 16:00:37 2013 +0800
+++ b/options.h	Sun Apr 07 01:36:42 2013 +0800
@@ -5,10 +5,10 @@
 #ifndef _OPTIONS_H_
 #define _OPTIONS_H_
 
-/******************************************************************
- * Define compile-time options below - the "#ifndef DROPBEAR_XXX .... #endif"
- * parts are to allow for commandline -DDROPBEAR_XXX options etc.
- ******************************************************************/
+/* Define compile-time options below - the "#ifndef DROPBEAR_XXX .... #endif"
+ * parts are to allow for commandline -DDROPBEAR_XXX options etc. */
+
+// XXX XXX You should probably run "make clean" after changing most options */
 
 #ifndef DROPBEAR_DEFPORT
 #define DROPBEAR_DEFPORT "22"
--- a/random.c	Sat Apr 06 16:00:37 2013 +0800
+++ b/random.c	Sun Apr 07 01:36:42 2013 +0800
@@ -27,7 +27,6 @@
 #include "dbutil.h"
 #include "bignum.h"
 #include "random.h"
-#include "ltc_prng.h"
 
 
 /* this is used to generate unique output from the same hashpool */
@@ -38,8 +37,6 @@
 static unsigned char hashpool[SHA1_HASH_SIZE] = {0};
 static int donerandinit = 0;
 
-int dropbear_ltc_prng = -1;
-
 #define INIT_SEED_SIZE 32 /* 256 bits */
 
 /* The basic setup is we read some data from /dev/(u)random or prngd and hash it
@@ -235,13 +232,6 @@
 
 	sha1_done(&hs, hashpool);
 
-#ifdef DROPBEAR_LTC_PRNG
-	if (dropbear_ltc_prng == -1) {
-		dropbear_ltc_prng = register_prng(&dropbear_prng_desc);
-		dropbear_assert(dropbear_ltc_prng != -1);
-	}
-#endif
-
 	counter = 0;
 	donerandinit = 1;
 
--- a/random.h	Sat Apr 06 16:00:37 2013 +0800
+++ b/random.h	Sun Apr 07 01:36:42 2013 +0800
@@ -32,6 +32,4 @@
 void addrandom(char * buf, unsigned int len);
 void gen_random_mpint(mp_int *max, mp_int *rand);
 
-extern int dropbear_ltc_prng;
-
 #endif /* _RANDOM_H_ */
--- a/session.h	Sat Apr 06 16:00:37 2013 +0800
+++ b/session.h	Sun Apr 07 01:36:42 2013 +0800
@@ -157,7 +157,7 @@
 	buffer *session_id; /* this is the hash from the first kex */
 	/* The below are used temporarily during kex, are freed after use */
 	mp_int * dh_K; /* SSH_MSG_KEXDH_REPLY and sending SSH_MSH_NEWKEYS */
-	buffer *hash/* the session hash */
+	buffer *hash; /* the session hash */
 	buffer* kexhashbuf; /* session hash buffer calculated from various packets*/
 	buffer* transkexinit; /* the kexinit packet we send should be kept so we
 							 can add it to the hash when generating keys */
--- a/svr-auth.c	Sat Apr 06 16:00:37 2013 +0800
+++ b/svr-auth.c	Sun Apr 07 01:36:42 2013 +0800
@@ -93,8 +93,7 @@
 	CHECKCLEARTOWRITE();
 
 	buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_BANNER);
-	buf_putstring(ses.writepayload, buf_getptr(svr_opts.banner,
-				svr_opts.banner->len), svr_opts.banner->len);
+	buf_putbufstring(ses.writepayload, svr_opts.banner);
 	buf_putstring(ses.writepayload, "en", 2);
 
 	encrypt_packet();
@@ -330,11 +329,10 @@
 		buf_putbytes(typebuf, AUTH_METHOD_PASSWORD, AUTH_METHOD_PASSWORD_LEN);
 	}
 
-	buf_setpos(typebuf, 0);
-	buf_putstring(ses.writepayload, buf_getptr(typebuf, typebuf->len),
-			typebuf->len);
+	buf_putbufstring(ses.writepayload, typebuf);
 
-	TRACE(("auth fail: methods %d, '%s'", ses.authstate.authtypes,
+	TRACE(("auth fail: methods %d, '%.*s'", ses.authstate.authtypes,
+				typebuf->len,
 				buf_getptr(typebuf, typebuf->len)));
 
 	buf_free(typebuf);
--- a/svr-authpubkey.c	Sat Apr 06 16:00:37 2013 +0800
+++ b/svr-authpubkey.c	Sun Apr 07 01:36:42 2013 +0800
@@ -126,14 +126,13 @@
 	/* 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);
-	buf_putstring(signbuf, ses.session_id, SHA1_HASH_SIZE);
+	buf_putbufstring(signbuf, ses.session_id);
 	buf_putbytes(signbuf, ses.payload->data, ses.payload->pos);
 	buf_setpos(signbuf, 0);
 
 	/* ... and finally verify the signature */
 	fp = sign_key_fingerprint(keyblob, keybloblen);
-	if (buf_verify(ses.payload, key, buf_getptr(signbuf, signbuf->len),
-				signbuf->len) == DROPBEAR_SUCCESS) {
+	if (buf_verify(ses.payload, key, signbuf) == DROPBEAR_SUCCESS) {
 		dropbear_log(LOG_NOTICE,
 				"Pubkey auth succeeded for '%s' with key %s from %s",
 				ses.authstate.pw_name, fp, svr_ses.addrstring);
--- a/svr-kex.c	Sat Apr 06 16:00:37 2013 +0800
+++ b/svr-kex.c	Sun Apr 07 01:36:42 2013 +0800
@@ -34,7 +34,7 @@
 #include "bignum.h"
 #include "random.h"
 #include "runopts.h"
-
+#include "ecc.h"
 
 static void send_msg_kexdh_reply(mp_int *dh_e, buffer *ecdh_qs);
 
@@ -59,7 +59,7 @@
 		}
 	} else {
 #ifdef DROPBEAR_ECDH
-		buffer *ecdh_qs = buf_getstringbuf(ses.payload);
+		ecdh_qs = buf_getstringbuf(ses.payload);
 #endif
 	}
 
@@ -104,14 +104,14 @@
 		struct kex_ecdh_param *ecdh_param = gen_kexecdh_param();
 		kexecdh_comb_key(ecdh_param, ecdh_qs, svr_opts.hostkey);
 
-		buf_put_ecc_pub(ses.writepayload, &ecdh_param->key);
+		buf_put_ecc_pubkey_string(ses.writepayload, &ecdh_param->key);
 		free_kexecdh_param(ecdh_param);
 #endif
 	}
 
 	/* calc the signature */
 	buf_put_sign(ses.writepayload, svr_opts.hostkey, 
-			ses.newkeys->algo_hostkey, ses.hash, SHA1_HASH_SIZE);
+			ses.newkeys->algo_hostkey, ses.hash);
 
 	/* the SSH_MSG_KEXDH_REPLY is done */
 	encrypt_packet();
--- a/sysoptions.h	Sat Apr 06 16:00:37 2013 +0800
+++ b/sysoptions.h	Sun Apr 07 01:36:42 2013 +0800
@@ -70,10 +70,6 @@
 #define DROPBEAR_SIGNKEY_VERIFY
 #endif
 
-#ifdef DROPBEAR_ECDH
-#define DROPBEAR_LTC_PRNG
-#endif
-
 #define SHA1_HASH_SIZE 20
 #define MD5_HASH_SIZE 16
 
@@ -99,6 +95,10 @@
 #define DROPBEAR_ECC_521
 #endif
 
+#ifdef DROPBEAR_ECC
+#define DROPBEAR_LTC_PRNG
+#endif
+
 // hashes which will be linked and registered
 #if defined(DROPBEAR_SHA2_256_HMAC) || defined(DROPBEAR_ECC_256)
 #define DROPBEAR_SHA256