diff --git a/Makefile.in b/Makefile.in index f456a722b00d6c6c9cd0e52b39993029ef8ecbe4..13d8e833cd75d323d373fd534063921ac5e921a8 100644 --- a/Makefile.in +++ b/Makefile.in @@ -26,7 +26,8 @@ COMMONOBJS=dbutil.o buffer.o \ dss.o bignum.o \ signkey.o rsa.o random.o \ queue.o \ - atomicio.o compat.o fake-rfc2553.o ltc_prng.o ecc.o + atomicio.o compat.o fake-rfc2553.o \ + ltc_prng.o ecc.o ecdsa.o crypto_desc.o SVROBJS=svr-kex.o svr-algo.o svr-auth.o sshpty.o \ svr-authpasswd.o svr-authpubkey.o svr-authpubkeyoptions.o svr-session.o svr-service.o \ @@ -54,7 +55,7 @@ HEADERS=options.h dbutil.h session.h packet.h algo.h ssh.h buffer.h kex.h \ debug.h channel.h chansession.h config.h queue.h sshpty.h \ termcodes.h gendss.h genrsa.h runopts.h includes.h \ loginrec.h atomicio.h x11fwd.h agentfwd.h tcpfwd.h compat.h \ - listener.h fake-rfc2553.h + listener.h fake-rfc2553.h ecc.h ecdsa.h dropbearobjs=$(COMMONOBJS) $(CLISVROBJS) $(SVROBJS) @CRYPTLIB@ dbclientobjs=$(COMMONOBJS) $(CLISVROBJS) $(CLIOBJS) diff --git a/algo.h b/algo.h index 500c449fb5912162afbef474c0c489ffd5075e80..4be7cf30034f980b67c695372b16dafef480000b 100644 --- a/algo.h +++ b/algo.h @@ -93,7 +93,6 @@ struct dropbear_kex { const struct ltc_hash_descriptor *hashdesc; }; -void crypto_init(); int have_algo(char* algo, size_t algolen, algo_type algos[]); void buf_put_algolist(buffer * buf, algo_type localalgos[]); @@ -120,6 +119,4 @@ enum { DROPBEAR_COMP_ZLIB_DELAY, }; -extern int dropbear_ltc_prng; - #endif /* _ALGO_H_ */ diff --git a/cli-session.c b/cli-session.c index e58fdbde5711d09d1ff727eb5a71d8c7471dd7a3..2905389e9d61a643521e9fdbe42e89be4fa8966f 100644 --- a/cli-session.c +++ b/cli-session.c @@ -36,6 +36,7 @@ #include "runopts.h" #include "chansession.h" #include "agentfwd.h" +#include "crypto_desc.h" static void cli_remoteclosed(); static void cli_sessionloop(); diff --git a/common-algo.c b/common-algo.c index 025faaeb8c006d4d5bf5c1b012d812563e588ac5..9915ce651e5d296f8b167d2a65931fe391c11e1b 100644 --- a/common-algo.c +++ b/common-algo.c @@ -33,12 +33,6 @@ /* 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* UNUSED(cipher_state)) { if (in != out) { @@ -255,70 +249,6 @@ algo_type sshkex[] = { {NULL, 0, NULL, 0, NULL} }; - -/* Register the compiled in ciphers. - * This should be run before using any of the ciphers/hashes */ -void crypto_init() { - - const struct ltc_cipher_descriptor *regciphers[] = { -#ifdef DROPBEAR_AES - &aes_desc, -#endif -#ifdef DROPBEAR_BLOWFISH - &blowfish_desc, -#endif -#ifdef DROPBEAR_TWOFISH - &twofish_desc, -#endif -#ifdef DROPBEAR_3DES - &des3_desc, -#endif - NULL - }; - - const struct ltc_hash_descriptor *reghashes[] = { - /* we need sha1 for hostkey stuff regardless */ - &sha1_desc, -#ifdef DROPBEAR_MD5_HMAC - &md5_desc, -#endif -#ifdef DROPBEAR_SHA256 - &sha256_desc, -#endif -#ifdef DROPBEAR_SHA384 - &sha384_desc, -#endif -#ifdef DROPBEAR_SHA512 - &sha512_desc, -#endif - NULL - }; - int i; - - for (i = 0; regciphers[i] != NULL; i++) { - if (register_cipher(regciphers[i]) == -1) { - dropbear_exit("Error registering crypto"); - } - } - - for (i = 0; reghashes[i] != NULL; i++) { - if (register_hash(reghashes[i]) == -1) { - 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 * against. * Returns DROPBEAR_SUCCESS if we have a match for algo, DROPBEAR_FAILURE diff --git a/common-kex.c b/common-kex.c index 99d0859df583187167286a62285cb88aada26d8f..c68b2279a954aab9c2b4a598f5f9fffefc788715 100644 --- a/common-kex.c +++ b/common-kex.c @@ -35,6 +35,7 @@ #include "random.h" #include "runopts.h" #include "ecc.h" +#include "crypto_desc.h" /* diffie-hellman-group1-sha1 value for p */ const unsigned char dh_p_1[DH_P_1_LEN] = { diff --git a/crypto_desc.c b/crypto_desc.c new file mode 100644 index 0000000000000000000000000000000000000000..403e0852754ee9c0695d90499b401d8f2c519a2f --- /dev/null +++ b/crypto_desc.c @@ -0,0 +1,73 @@ +#include "includes.h" +#include "dbutil.h" +#include "crypto_desc.h" +#include "ltc_prng.h" + +#ifdef DROPBEAR_LTC_PRNG + int dropbear_ltc_prng = -1; +#endif + + +/* Register the compiled in ciphers. + * This should be run before using any of the ciphers/hashes */ +void crypto_init() { + + const struct ltc_cipher_descriptor *regciphers[] = { +#ifdef DROPBEAR_AES + &aes_desc, +#endif +#ifdef DROPBEAR_BLOWFISH + &blowfish_desc, +#endif +#ifdef DROPBEAR_TWOFISH + &twofish_desc, +#endif +#ifdef DROPBEAR_3DES + &des3_desc, +#endif + NULL + }; + + const struct ltc_hash_descriptor *reghashes[] = { + /* we need sha1 for hostkey stuff regardless */ + &sha1_desc, +#ifdef DROPBEAR_MD5_HMAC + &md5_desc, +#endif +#ifdef DROPBEAR_SHA256 + &sha256_desc, +#endif +#ifdef DROPBEAR_SHA384 + &sha384_desc, +#endif +#ifdef DROPBEAR_SHA512 + &sha512_desc, +#endif + NULL + }; + int i; + + for (i = 0; regciphers[i] != NULL; i++) { + if (register_cipher(regciphers[i]) == -1) { + dropbear_exit("Error registering crypto"); + } + } + + for (i = 0; reghashes[i] != NULL; i++) { + if (register_hash(reghashes[i]) == -1) { + 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 +} + diff --git a/crypto_desc.h b/crypto_desc.h new file mode 100644 index 0000000000000000000000000000000000000000..ff04066bd2dc804174a700eac8b5fca05b18aaaf --- /dev/null +++ b/crypto_desc.h @@ -0,0 +1,9 @@ +#ifndef _CRYPTO_DESC_H +#define _CRYPTO_DESC_H + +void crypto_init(); + +extern int dropbear_ltc_prng; + +#endif // _CRYPTO_DESC_H + diff --git a/dropbearkey.c b/dropbearkey.c index 9b82a777b5e36caa832fd60aaddf004988497702..a9d80fde935bba3fae5f692e0e3b7bc345de6fcb 100644 --- a/dropbearkey.c +++ b/dropbearkey.c @@ -188,6 +188,7 @@ int main(int argc, char ** argv) { exit(EXIT_FAILURE); } + // TODO: put RSA and DSS size checks into genrsa.c etc if (keytype == DROPBEAR_SIGNKEY_DSS && bits != 1024) { fprintf(stderr, "DSS keys have a fixed size of 1024 bits\n"); exit(EXIT_FAILURE); diff --git a/ecc.c b/ecc.c index 56ab47aaa0f20a08618e97ae22816667beae7c8c..10ae3227dd6dcd73d2d5b95223ab8b0d3ffe3e09 100644 --- a/ecc.c +++ b/ecc.c @@ -7,25 +7,24 @@ #ifdef DROPBEAR_ECC // 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_nistp256 = { .dp = <c_ecc_sets[0], - .hash_desc = &sha256_desc, + .hashdesc = &sha256_desc, .name = "nistp256" }; #endif #ifdef DROPBEAR_ECC_384 const struct dropbear_ecc_curve ecc_curve_nistp384 = { .dp = <c_ecc_sets[1], - .hash_desc = &sha384_desc, + .hashdesc = &sha384_desc, .name = "nistp384" }; #endif #ifdef DROPBEAR_ECC_521 const struct dropbear_ecc_curve ecc_curve_nistp521 = { .dp = <c_ecc_sets[2], - .hash_desc = &sha512_desc, + .hashdesc = &sha512_desc, .name = "nistp521" }; #endif diff --git a/ecc.h b/ecc.h index 9457ebe96bcc82ecfc78eafbb56da4813d757aa4..35775d8e1b7d807232de861753ebca711f7b3f52 100644 --- a/ecc.h +++ b/ecc.h @@ -10,7 +10,7 @@ struct dropbear_ecc_curve { const ltc_ecc_set_type *dp; // curve domain parameters - const struct ltc_hash_descriptor *hash_desc; + const struct ltc_hash_descriptor *hashdesc; const char *name; }; diff --git a/ecdsa.c b/ecdsa.c new file mode 100644 index 0000000000000000000000000000000000000000..b29ef1f618a8dcfd7dd72dece75827905f86fee1 --- /dev/null +++ b/ecdsa.c @@ -0,0 +1,53 @@ +#include "includes.h" +#include "dbutil.h" +#include "crypto_desc.h" + +#ifdef DROPBEAR_ECDSA + +ecc_key *gen_ecdsa_priv_key(unsigned int bit_size) { + const ltc_ecc_set_type *dp = NULL; // curve domain parameters + // TODO: use raw bytes for the dp rather than the hex strings in libtomcrypt's ecc.c + switch (bit_size) { +#ifdef DROPBEAR_ECC_256 + case 256: + dp = <c_ecc_sets[0]; + break; +#endif +#ifdef DROPBEAR_ECC_384 + case 384: + dp = <c_ecc_sets[0]; + break; +#endif +#ifdef DROPBEAR_ECC_521 + case 521: + dp = <c_ecc_sets[0]; + break; +#endif + } + if (!dp) { + dropbear_exit("Key size %d isn't valid. Try " +#ifdef DROPBEAR_ECC_256 + "256 " +#endif +#ifdef DROPBEAR_ECC_384 + "384 " +#endif +#ifdef DROPBEAR_ECC_521 + "521 " +#endif + , bit_size); + } + + ecc_key *new_key = m_malloc(sizeof(*new_key)); + if (ecc_make_key_ex(NULL, dropbear_ltc_prng, new_key, dp) != CRYPT_OK) { + dropbear_exit("ECC error"); + } + return new_key; +} + +int buf_get_ecdsa_pub_key(buffer* buf, ecc_key *key) { + +} + + +#endif // DROPBEAR_ECDSA diff --git a/ecdsa.h b/ecdsa.h new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/options.h b/options.h index 4f0dc120595099588113546d3ff6f2d5c452f374..2547c991614ddfb4cbcd3e7f82fba8565e97eda7 100644 --- a/options.h +++ b/options.h @@ -137,6 +137,7 @@ much traffic. */ #define DROPBEAR_DSS #define DROPBEAR_ECDH +#define DROPBEAR_ECDSA /* RSA can be vulnerable to timing attacks which use the time required for * signing to guess the private key. Blinding avoids this attack, though makes diff --git a/signkey.h b/signkey.h index e4dd7cee3b61a6e55a71a7cccde69c355109bd1f..316ca49f0c79afae26220818c75761ab6892fe33 100644 --- a/signkey.h +++ b/signkey.h @@ -51,6 +51,9 @@ struct SIGN_key { #ifdef DROPBEAR_RSA dropbear_rsa_key * rsakey; #endif +#ifdef DROPBEAR_ECDSA + ecc_key *ecckey; +#endif }; typedef struct SIGN_key sign_key; diff --git a/svr-session.c b/svr-session.c index cf822897c0e19f4a3794ced408dc256a3b96bca9..b3b8d5e18f417c7cf75a00a027d55f9b6020e2c5 100644 --- a/svr-session.c +++ b/svr-session.c @@ -39,6 +39,7 @@ #include "service.h" #include "auth.h" #include "runopts.h" +#include "crypto_desc.h" static void svr_remoteclosed(); diff --git a/sysoptions.h b/sysoptions.h index a6b1364ea73c872d00fda5581ca54e3425ef1159..af3efe4747c4bd7ccf4c822c467b611b39923b6f 100644 --- a/sysoptions.h +++ b/sysoptions.h @@ -60,10 +60,13 @@ #define DROPBEAR_SUCCESS 0 #define DROPBEAR_FAILURE -1 -#define DROPBEAR_SIGNKEY_ANY 0 -#define DROPBEAR_SIGNKEY_RSA 1 -#define DROPBEAR_SIGNKEY_DSS 2 -#define DROPBEAR_SIGNKEY_NONE 3 +enum { + DROPBEAR_SIGNKEY_ANY, + DROPBEAR_SIGNKEY_RSA, + DROPBEAR_SIGNKEY_DSS, + DROPBEAR_SIGNKEY_ECDSA, + DROPBEAR_SIGNKEY_NONE, +}; /* Required for pubkey auth */ #if defined(ENABLE_SVR_PUBKEY_AUTH) || defined(DROPBEAR_CLIENT)