diff options
32 files changed, 174 insertions, 120 deletions
diff --git a/Makefile.in b/Makefile.in index eef6fbe..f456a72 100644 --- a/Makefile.in +++ b/Makefile.in @@ -17,9 +17,9 @@ LTC=libtomcrypt/libtomcrypt.a 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 @@ link%: -ln -s dropbearmulti$(EXEEXT) $*$(EXEEXT) $(LTC): options.h - cd libtomcrypt && $(MAKE) clean && $(MAKE) + cd libtomcrypt && $(MAKE) $(LTM): options.h cd libtommath && $(MAKE) @@ -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 @@ enum { DROPBEAR_COMP_ZLIB_DELAY, }; +extern int dropbear_ltc_prng; #endif /* _ALGO_H_ */ @@ -59,7 +59,7 @@ buffer * buf_getstringbuf(buffer *buf); 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); diff --git a/cli-agentfwd.c b/cli-agentfwd.c index b7b8da3..ba07f54 100644 --- a/cli-agentfwd.c +++ b/cli-agentfwd.c @@ -266,7 +266,7 @@ void agent_buf_sign(buffer *sigblob, sign_key *key, 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); diff --git a/cli-authpubkey.c b/cli-authpubkey.c index adcf2a8..96eee05 100644 --- a/cli-authpubkey.c +++ b/cli-authpubkey.c @@ -172,7 +172,7 @@ static void send_msg_userauth_pubkey(sign_key *key, int type, int realsign) { 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 */ } diff --git a/cli-chansession.c b/cli-chansession.c index 65d1f4f..d3b14bb 100644 --- a/cli-chansession.c +++ b/cli-chansession.c @@ -455,7 +455,7 @@ do_escape(unsigned char c) { } 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; @@ -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 @@ void send_msg_kexdh_init() { } 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 @@ void recv_msg_kexdh_reply() { } 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"); } diff --git a/common-algo.c b/common-algo.c index 7fb1503..04bbd51 100644 --- a/common-algo.c +++ b/common-algo.c @@ -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 @@ algo_type sshhostkey[] = { 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 @@ static struct dropbear_kex kex_ecdh_secp384r1 = {NULL, 0, &ecc_curve_secp384r1, #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 @@ void crypto_init() { 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 diff --git a/common-kex.c b/common-kex.c index e241101..48569fe 100644 --- a/common-kex.c +++ b/common-kex.c @@ -87,6 +87,7 @@ 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 finish_kexhashbuf(void); /* Send our list of algorithms we can use */ @@ -258,7 +259,7 @@ static void hashkeys(unsigned char *out, int outlen, 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 @@ void gen_new_keys() { 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 @@ void kexdh_comb_key(struct kex_dh_param *param, mp_int *dh_pub_them, 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 @@ void kexdh_comb_key(struct kex_dh_param *param, mp_int *dh_pub_them, 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 @@ void kexecdh_comb_key(struct kex_ecdh_param *param, buffer *pub_them, // 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, ¶m->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 = ¶m->key; Q_S = Q_them; } else { Q_C = Q_them; - Q_S = param->key; + Q_S = ¶m->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 @@ void kexecdh_comb_key(struct kex_ecdh_param *param, buffer *pub_them, 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 @@ void kexecdh_comb_key(struct kex_ecdh_param *param, buffer *pub_them, /* 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. */ diff --git a/common-session.c b/common-session.c index f4fa579..ef8e6fa 100644 --- a/common-session.c +++ b/common-session.c @@ -103,7 +103,7 @@ void common_session_init(int sock_in, int sock_out) { 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 @@ void common_session_cleanup() { 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); @@ -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 @@ -110,7 +110,7 @@ error: 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 @@ ecc_key * buf_get_ecc_pubkey(buffer *buf, const struct dropbear_ecc_curve *curve } 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; diff --git a/libtomcrypt/Makefile.in b/libtomcrypt/Makefile.in index 14bce99..3056ef0 100644 --- a/libtomcrypt/Makefile.in +++ b/libtomcrypt/Makefile.in @@ -19,7 +19,7 @@ srcdir=@srcdir@ # 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_decrypt.o src/modes/lrw/lrw_done.o src/modes/lrw/lrw_encrypt.o 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 \ diff --git a/libtomcrypt/src/headers/tomcrypt.h b/libtomcrypt/src/headers/tomcrypt.h index 15ccd04..ba9f181 100644 --- a/libtomcrypt/src/headers/tomcrypt.h +++ b/libtomcrypt/src/headers/tomcrypt.h @@ -24,7 +24,7 @@ extern "C" { /* 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 { diff --git a/libtomcrypt/src/headers/tomcrypt_custom.h b/libtomcrypt/src/headers/tomcrypt_custom.h index d1d86c6..91a2ccb 100644 --- a/libtomcrypt/src/headers/tomcrypt_custom.h +++ b/libtomcrypt/src/headers/tomcrypt_custom.h @@ -138,6 +138,8 @@ #ifdef DROPBEAR_ECC #define MECC +#define MPI +#define LTM_DESC #ifdef DROPBEAR_ECC_256 #define ECC256 #endif diff --git a/libtomcrypt/src/headers/tomcrypt_math.h b/libtomcrypt/src/headers/tomcrypt_math.h index 8bf544f..c996e41 100644 --- a/libtomcrypt/src/headers/tomcrypt_math.h +++ b/libtomcrypt/src/headers/tomcrypt_math.h @@ -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 @@ typedef struct { 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 @@ typedef struct { 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; diff --git a/libtomcrypt/src/misc/crypt/crypt_ltc_mp_descriptor.c b/libtomcrypt/src/misc/crypt/crypt_ltc_mp_descriptor.c index 907862f..e042910 100644 --- a/libtomcrypt/src/misc/crypt/crypt_ltc_mp_descriptor.c +++ b/libtomcrypt/src/misc/crypt/crypt_ltc_mp_descriptor.c @@ -10,4 +10,4 @@ */ #include "tomcrypt.h" -ltc_math_descriptor ltc_mp; +ltc_math_descriptor ltc_mp = {0}; diff --git a/libtomcrypt/src/pk/ecc/ecc_decrypt_key.c b/libtomcrypt/src/pk/ecc/ecc_decrypt_key.c index bb56208..97039d0 100644 --- a/libtomcrypt/src/pk/ecc/ecc_decrypt_key.c +++ b/libtomcrypt/src/pk/ecc/ecc_decrypt_key.c @@ -21,7 +21,7 @@ ECC Crypto, Tom St Denis */ -#ifdef MECC +#if defined(MECC) && defined(LTC_DER) /** Decrypt an ECC encrypted key diff --git a/libtomcrypt/src/pk/ecc/ecc_encrypt_key.c b/libtomcrypt/src/pk/ecc/ecc_encrypt_key.c index dd9bab0..d11ffe4 100644 --- a/libtomcrypt/src/pk/ecc/ecc_encrypt_key.c +++ b/libtomcrypt/src/pk/ecc/ecc_encrypt_key.c @@ -21,7 +21,7 @@ ECC Crypto, Tom St Denis */ -#ifdef MECC +#if defined(MECC) && defined(LTC_DER) /** Encrypt a symmetric key with ECC diff --git a/libtomcrypt/src/pk/ecc/ecc_export.c b/libtomcrypt/src/pk/ecc/ecc_export.c index 1919849..08c8d31 100644 --- a/libtomcrypt/src/pk/ecc/ecc_export.c +++ b/libtomcrypt/src/pk/ecc/ecc_export.c @@ -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 diff --git a/libtomcrypt/src/pk/ecc/ecc_import.c b/libtomcrypt/src/pk/ecc/ecc_import.c index 4adb28e..97eaa7d 100644 --- a/libtomcrypt/src/pk/ecc/ecc_import.c +++ b/libtomcrypt/src/pk/ecc/ecc_import.c @@ -21,7 +21,7 @@ ECC Crypto, Tom St Denis */ -#ifdef MECC +#if defined(MECC) && defined(LTC_DER) static int is_point(ecc_key *key) { diff --git a/libtomcrypt/src/pk/ecc/ecc_sign_hash.c b/libtomcrypt/src/pk/ecc/ecc_sign_hash.c index 44f949e..34c5893 100644 --- a/libtomcrypt/src/pk/ecc/ecc_sign_hash.c +++ b/libtomcrypt/src/pk/ecc/ecc_sign_hash.c @@ -21,7 +21,7 @@ ECC Crypto, Tom St Denis */ -#ifdef MECC +#if defined(MECC) && defined(LTC_DER) /** Sign a message digest diff --git a/libtomcrypt/src/pk/ecc/ecc_verify_hash.c b/libtomcrypt/src/pk/ecc/ecc_verify_hash.c index bd8a840..65a96e6 100644 --- a/libtomcrypt/src/pk/ecc/ecc_verify_hash.c +++ b/libtomcrypt/src/pk/ecc/ecc_verify_hash.c @@ -21,7 +21,7 @@ ECC Crypto, Tom St Denis */ -#ifdef MECC +#if defined(MECC) && defined(LTC_DER) /* verify * @@ -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 @@ int dropbear_prng_start(prng_state *prng) @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 @@ int dropbear_prng_add_entropy(const unsigned char *in, unsigned long inlen, prng @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 @@ int dropbear_prng_ready(prng_state *prng) @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 @@ unsigned long dropbear_prng_read(unsigned char *out, unsigned long outlen, prng_ @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 @@ int dropbear_prng_done(prng_state *prng) @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 @@ int dropbear_prng_export(unsigned char *out, unsigned long *outlen, prng_state * @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; } @@ -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" @@ -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 uint32_t counter = 0; 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 @@ void seedrandom() { 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; @@ -32,6 +32,4 @@ void genrandom(unsigned char* buf, unsigned int len); 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_ */ @@ -157,7 +157,7 @@ struct sshsession { 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 */ @@ -93,8 +93,7 @@ static void send_msg_userauth_banner() { 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 @@ void send_msg_userauth_failure(int partial, int incrfail) { 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); diff --git a/svr-authpubkey.c b/svr-authpubkey.c index d483e9d..1c5f9d6 100644 --- a/svr-authpubkey.c +++ b/svr-authpubkey.c @@ -126,14 +126,13 @@ 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); - 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); @@ -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 @@ void recv_msg_kexdh_init() { } } else { #ifdef DROPBEAR_ECDH - buffer *ecdh_qs = buf_getstringbuf(ses.payload); + ecdh_qs = buf_getstringbuf(ses.payload); #endif } @@ -104,14 +104,14 @@ static void send_msg_kexdh_reply(mp_int *dh_e, buffer *ecdh_qs) { 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(); diff --git a/sysoptions.h b/sysoptions.h index 9b7c15a..d31b56f 100644 --- a/sysoptions.h +++ b/sysoptions.h @@ -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 |