Commit 8eefb092 authored by Matt Johnston's avatar Matt Johnston
Browse files

Merge in ECC

parents 3d733a16 45bd0eda
......@@ -17,16 +17,17 @@ LTC=libtomcrypt/libtomcrypt.a
LTM=libtommath/libtommath.a
ifeq (@[email protected], 1)
LIBTOM_DEPS=$(LTC) $(LTM)
CFLAGS+=-I$(srcdir)/libtomcrypt/src/headers/
LIBS+=$(LTC) $(LTM)
LIBTOM_DEPS=$(LTC) $(LTM)
CFLAGS+=-I$(srcdir)/libtomcrypt/src/headers/
LIBS+=$(LTC) $(LTM)
endif
COMMONOBJS=dbutil.o buffer.o \
dss.o bignum.o \
signkey.o rsa.o random.o \
queue.o \
atomicio.o compat.o fake-rfc2553.o
atomicio.o compat.o fake-rfc2553.o \
ltc_prng.o ecc.o ecdsa.o crypto_desc.o
SVROBJS=svr-kex.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) @[email protected]
dbclientobjs=$(COMMONOBJS) $(CLISVROBJS) $(CLIOBJS)
......@@ -185,7 +186,7 @@ link%:
-ln -s dropbearmulti$(EXEEXT) $*$(EXEEXT)
$(LTC): options.h
cd libtomcrypt && $(MAKE) clean && $(MAKE)
cd libtomcrypt && $(MAKE)
$(LTM): options.h
cd libtommath && $(MAKE)
......
......@@ -40,7 +40,7 @@
/* client functions */
void cli_load_agent_keys(m_list * ret_list);
void agent_buf_sign(buffer *sigblob, sign_key *key,
const unsigned char *data, unsigned int len);
buffer *data_buf);
void cli_setup_agent(struct Channel *channel);
#ifdef __hpux
......
......@@ -35,7 +35,7 @@
struct Algo_Type {
unsigned char *name; /* identifying name */
const unsigned char *name; /* identifying name */
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 */
......@@ -59,8 +59,8 @@ extern const struct dropbear_hash dropbear_nohash;
struct dropbear_cipher {
const struct ltc_cipher_descriptor *cipherdesc;
unsigned long keysize;
unsigned char blocksize;
const unsigned long keysize;
const unsigned char blocksize;
};
struct dropbear_cipher_mode {
......@@ -74,12 +74,27 @@ struct dropbear_cipher_mode {
};
struct dropbear_hash {
const struct ltc_hash_descriptor *hashdesc;
unsigned long keysize;
unsigned char hashsize;
const struct ltc_hash_descriptor *hash_desc;
const unsigned long keysize;
// hashsize may be truncated from the size returned by hash_desc,
// eg sha1-96
const unsigned char hashsize;
};
struct dropbear_kex {
// "normal" DH KEX
const unsigned char *dh_p_bytes;
const int dh_p_len;
// elliptic curve DH KEX
#ifdef DROPBEAR_ECDH
const struct dropbear_ecc_curve *ecc_curve;
#endif
// both
const struct ltc_hash_descriptor *hash_desc;
};
void crypto_init();
int have_algo(char* algo, size_t algolen, algo_type algos[]);
void buf_put_algolist(buffer * buf, algo_type localalgos[]);
......@@ -102,5 +117,16 @@ int check_user_algos(const char* user_algo_list, algo_type * algos,
char * algolist_string(algo_type algos[]);
#endif
#ifdef DROPBEAR_ECDH
#define IS_NORMAL_DH(algo) ((algo)->dh_p_bytes != NULL)
#else
#define IS_NORMAL_DH(algo) 1
#endif
enum {
DROPBEAR_COMP_NONE,
DROPBEAR_COMP_ZLIB,
DROPBEAR_COMP_ZLIB_DELAY,
};
#endif /* _ALGO_H_ */
......@@ -52,6 +52,22 @@ void m_mp_init_multi(mp_int *mp, ...)
va_end(args);
}
void m_mp_alloc_init_multi(mp_int **mp, ...)
{
mp_int** cur_arg = mp;
va_list args;
va_start(args, mp); /* init args to next argument from caller */
while (cur_arg != NULL) {
*cur_arg = m_malloc(sizeof(mp_int));
if (mp_init(*cur_arg) != MP_OKAY) {
dropbear_exit("Mem alloc error");
}
cur_arg = va_arg(args, mp_int**);
}
va_end(args);
}
void bytes_to_mp(mp_int *mp, const unsigned char* bytes, unsigned int len) {
if (mp_read_unsigned_bin(mp, (unsigned char*)bytes, len) != MP_OKAY) {
......@@ -60,7 +76,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 +85,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);
}
......@@ -30,7 +30,9 @@
void m_mp_init(mp_int *mp);
void m_mp_init_multi(mp_int *mp, ...) ATTRIB_SENTINEL;
void m_mp_alloc_init_multi(mp_int **mp, ...) ATTRIB_SENTINEL;
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_ */
......@@ -269,6 +269,11 @@ void buf_putstring(buffer* buf, const unsigned char* str, unsigned int len) {
}
/* puts an entire buffer as a SSH string. ignore pos of buf_str. */
void buf_putbufstring(buffer *buf, const buffer* buf_str) {
buf_putstring(buf, buf_str->data, buf_str->len);
}
/* put the set of len bytes into the buffer, incrementing the pos, increasing
* len if required */
void buf_putbytes(buffer *buf, const unsigned char *bytes, unsigned int len) {
......
......@@ -59,6 +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_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);
......
......@@ -254,7 +254,7 @@ void cli_load_agent_keys(m_list *ret_list) {
}
void agent_buf_sign(buffer *sigblob, sign_key *key,
const unsigned char *data, unsigned int len) {
buffer *data_buf) {
buffer *request_data = NULL;
buffer *response = NULL;
unsigned int siglen;
......@@ -266,10 +266,10 @@ void agent_buf_sign(buffer *sigblob, sign_key *key,
string data
uint32 flags
*/
request_data = buf_new(MAX_PUBKEY_SIZE + len + 12);
request_data = buf_new(MAX_PUBKEY_SIZE + data_buf->len + 12);
buf_put_pub_key(request_data, key, key->type);
buf_putstring(request_data, data, len);
buf_putbufstring(request_data, data_buf);
buf_putint(request_data, 0);
response = agent_request(SSH2_AGENTC_SIGN_REQUEST, request_data);
......
......@@ -121,23 +121,19 @@ void recv_msg_userauth_pk_ok() {
}
void cli_buf_put_sign(buffer* buf, sign_key *key, int type,
const unsigned char *data, unsigned int len)
{
buffer *data_buf) {
#ifdef ENABLE_CLI_AGENTFWD
if (key->source == SIGNKEY_SOURCE_AGENT) {
/* Format the agent signature ourselves, as buf_put_sign would. */
buffer *sigblob;
sigblob = buf_new(MAX_PUBKEY_SIZE);
agent_buf_sign(sigblob, key, data, len);
buf_setpos(sigblob, 0);
buf_putstring(buf, buf_getptr(sigblob, sigblob->len),
sigblob->len);
agent_buf_sign(sigblob, key, data_buf);
buf_putbufstring(buf, sigblob);
buf_free(sigblob);
} else
#endif /* ENABLE_CLI_AGENTFWD */
{
buf_put_sign(buf, key, type, data, len);
buf_put_sign(buf, key, type, data_buf);
}
}
......@@ -173,10 +169,10 @@ 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);
buf_putstring(sigbuf, ses.session_id, SHA1_HASH_SIZE);
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->data, sigbuf->len);
cli_buf_put_sign(ses.writepayload, key, type, sigbuf);
buf_free(sigbuf); /* Nothing confidential in the buffer */
}
......
......@@ -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);
......@@ -43,23 +44,31 @@ static void checkhostkey(unsigned char* keyblob, unsigned int keybloblen);
void send_msg_kexdh_init() {
TRACE(("send_msg_kexdh_init()"))
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);
cli_ses.dh_val_algo = ses.newkeys->algo_kex;
}
CHECKCLEARTOWRITE();
buf_putbyte(ses.writepayload, SSH_MSG_KEXDH_INIT);
buf_putmpint(ses.writepayload, cli_ses.dh_e);
if (IS_NORMAL_DH(ses.newkeys->algo_kex)) {
if (ses.newkeys->algo_kex != cli_ses.param_kex_algo
|| !cli_ses.dh_param) {
if (cli_ses.dh_param) {
free_kexdh_param(cli_ses.dh_param);
}
cli_ses.dh_param = gen_kexdh_param();
}
buf_putmpint(ses.writepayload, &cli_ses.dh_param->pub);
} else {
#ifdef DROPBEAR_ECDH
if (ses.newkeys->algo_kex != cli_ses.param_kex_algo
|| !cli_ses.ecdh_param) {
if (cli_ses.ecdh_param) {
free_kexecdh_param(cli_ses.ecdh_param);
}
cli_ses.ecdh_param = gen_kexecdh_param();
}
buf_put_ecc_raw_pubkey_string(ses.writepayload, &cli_ses.ecdh_param->key);
#endif
}
cli_ses.param_kex_algo = ses.newkeys->algo_kex;
encrypt_packet();
ses.requirenext[0] = SSH_MSG_KEXDH_REPLY;
ses.requirenext[1] = SSH_MSG_KEXINIT;
......@@ -68,18 +77,15 @@ void send_msg_kexdh_init() {
/* Handle a diffie-hellman key exchange reply. */
void recv_msg_kexdh_reply() {
DEF_MP_INT(dh_f);
sign_key *hostkey = NULL;
unsigned int type, keybloblen;
unsigned char* keyblob = NULL;
TRACE(("enter recv_msg_kexdh_reply"))
if (cli_ses.kex_state != KEXDH_INIT_SENT) {
dropbear_exit("Received out-of-order kexdhreply");
}
m_mp_init(&dh_f);
type = ses.newkeys->algo_hostkey;
TRACE(("type is %d", type))
......@@ -97,20 +103,38 @@ void recv_msg_kexdh_reply() {
dropbear_exit("Bad KEX packet");
}
if (buf_getmpint(ses.payload, &dh_f) != DROPBEAR_SUCCESS) {
TRACE(("failed getting mpint"))
dropbear_exit("Bad KEX packet");
if (IS_NORMAL_DH(ses.newkeys->algo_kex)) {
// Normal diffie-hellman
DEF_MP_INT(dh_f);
m_mp_init(&dh_f);
if (buf_getmpint(ses.payload, &dh_f) != DROPBEAR_SUCCESS) {
TRACE(("failed getting mpint"))
dropbear_exit("Bad KEX packet");
}
kexdh_comb_key(cli_ses.dh_param, &dh_f, hostkey);
mp_clear(&dh_f);
} else {
#ifdef DROPBEAR_ECDH
buffer *ecdh_qs = buf_getstringbuf(ses.payload);
kexecdh_comb_key(cli_ses.ecdh_param, ecdh_qs, hostkey);
buf_free(ecdh_qs);
#endif
}
kexdh_comb_key(cli_ses.dh_e, cli_ses.dh_x, &dh_f, hostkey);
mp_clear(&dh_f);
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 (cli_ses.dh_param) {
free_kexdh_param(cli_ses.dh_param);
cli_ses.dh_param = NULL;
}
#ifdef DROPBEAR_ECDH
if (cli_ses.ecdh_param) {
free_kexecdh_param(cli_ses.ecdh_param);
cli_ses.ecdh_param = NULL;
}
#endif
if (buf_verify(ses.payload, hostkey, ses.hash, SHA1_HASH_SIZE)
!= DROPBEAR_SUCCESS) {
cli_ses.param_kex_algo = NULL;
if (buf_verify(ses.payload, hostkey, ses.hash) != DROPBEAR_SUCCESS) {
dropbear_exit("Bad hostkey signature");
}
......
......@@ -28,6 +28,8 @@
#include "dbutil.h"
#include "runopts.h"
#include "session.h"
#include "random.h"
#include "crypto_desc.h"
static void cli_dropbear_exit(int exitcode, const char* format, va_list param) ATTRIB_NORETURN;
static void cli_dropbear_log(int priority, const char* format, va_list param);
......@@ -51,6 +53,9 @@ int main(int argc, char ** argv) {
disallow_core();
seedrandom();
crypto_init();
cli_getopts(argc, argv);
TRACE(("user='%s' host='%s' port='%s'", cli_opts.username,
......
......@@ -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();
......@@ -86,10 +87,6 @@ static const struct ChanType *cli_chantypes[] = {
void cli_session(int sock_in, int sock_out) {
seedrandom();
crypto_init();
common_session_init(sock_in, sock_out);
chaninitialise(cli_chantypes);
......
......@@ -23,24 +23,28 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. */
#include "includes.h"
#include "algo.h"
#include "session.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*/
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;
}
......@@ -204,6 +208,17 @@ algo_type ssh_nocompress[] = {
};
algo_type sshhostkey[] = {
#ifdef DROPBEAR_ECDSA
#ifdef DROPBEAR_ECC_256
{"ecdsa-sha2-nistp256", DROPBEAR_SIGNKEY_ECDSA_NISTP256, NULL, 1, NULL},
#endif
#ifdef DROPBEAR_ECC_384
{"ecdsa-sha2-nistp384", DROPBEAR_SIGNKEY_ECDSA_NISTP384, NULL, 1, NULL},
#endif
#ifdef DROPBEAR_ECC_521
{"ecdsa-sha2-nistp521", DROPBEAR_SIGNKEY_ECDSA_NISTP521, NULL, 1, NULL},
#endif
#endif
#ifdef DROPBEAR_RSA
{"ssh-rsa", DROPBEAR_SIGNKEY_RSA, NULL, 1, NULL},
#endif
......@@ -213,64 +228,41 @@ algo_type sshhostkey[] = {
{NULL, 0, NULL, 0, NULL}
};
algo_type sshkex[] = {
{"diffie-hellman-group1-sha1", DROPBEAR_KEX_DH_GROUP1, NULL, 1, NULL},
{"diffie-hellman-group14-sha1", DROPBEAR_KEX_DH_GROUP14, NULL, 1, NULL},
#ifdef USE_KEXGUESS2
{KEXGUESS2_ALGO_NAME, KEXGUESS2_ALGO_ID, NULL, 1, NULL},
#endif
{NULL, 0, NULL, 0, NULL}
};
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 };
/* 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,
#ifdef DROPBEAR_ECDH
#ifdef DROPBEAR_ECC_256
static struct dropbear_kex kex_ecdh_nistp256 = {NULL, 0, &ecc_curve_nistp256, &sha256_desc };
#endif
#ifdef DROPBEAR_TWOFISH
&twofish_desc,
#ifdef DROPBEAR_ECC_384
static struct dropbear_kex kex_ecdh_nistp384 = {NULL, 0, &ecc_curve_nistp384, &sha384_desc };
#endif
#ifdef DROPBEAR_3DES
&des3_desc,
#ifdef DROPBEAR_ECC_521
static struct dropbear_kex kex_ecdh_nistp521 = {NULL, 0, &ecc_curve_nistp521, &sha512_desc };
#endif
NULL
};
#endif // DROPBEAR_ECDH
const struct ltc_hash_descriptor *reghashes[] = {
/* we need sha1 for hostkey stuff regardless */
&sha1_desc,
#ifdef DROPBEAR_MD5_HMAC
&md5_desc,
algo_type sshkex[] = {
#ifdef DROPBEAR_ECDH
#ifdef DROPBEAR_ECC_256
{"ecdh-sha2-nistp256", 0, &kex_ecdh_nistp256, 1, NULL},
#endif
#ifdef DROPBEAR_SHA2_256_HMAC
&sha256_desc,
#ifdef DROPBEAR_ECC_384
{"ecdh-sha2-nistp384", 0, &kex_ecdh_nistp384, 1, NULL},
#endif
#ifdef DROPBEAR_SHA2_512_HMAC
&sha512_desc,
#ifdef DROPBEAR_ECC_521
{"ecdh-sha2-nistp521", 0, &kex_ecdh_nistp521, 1, NULL},
#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");
}
}
}
#endif
{"diffie-hellman-group1-sha1", 0, &kex_dh_group1, 1, NULL},
{"diffie-hellman-group14-sha1", 0, &kex_dh_group14, 1, NULL},
#ifdef USE_KEXGUESS2
{KEXGUESS2_ALGO_NAME, KEXGUESS2_ALGO_ID, NULL, 1, NULL},
#endif
{NULL, 0, NULL, 0, NULL}
};
/* algolen specifies the length of algo, algos is our local list to match
* against.
......
......@@ -34,10 +34,11 @@
#include "bignum.h"
#include "random.h"
#include "runopts.h"
#include "ecc.h"
#include "crypto_desc.h"
/* diffie-hellman-group1-sha1 value for p */
#define DH_P_1_LEN 128
static const unsigned char dh_p_1[DH_P_1_LEN] = {
const unsigned char dh_p_1[DH_P_1_LEN] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
......@@ -51,8 +52,7 @@ static const unsigned char dh_p_1[DH_P_1_LEN] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
/* diffie-hellman-group14-sha1 value for p */
#define DH_P_14_LEN 256
static const unsigned char dh_p_14[DH_P_14_LEN] = {
const unsigned char dh_p_14[DH_P_14_LEN] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
......@@ -87,8 +87,9 @@ static void gen_new_zstream_trans();
#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);
/* Send our list of algorithms we can use */
......@@ -150,7 +151,7 @@ void send_msg_kexinit() {
ses.newkeys = (struct key_context*)m_malloc(sizeof(struct key_context));
if (ses.send_kex_first_guess) {
ses.newkeys->algo_kex = sshkex[0].val;
ses.newkeys->algo_kex = sshkex[0].data;
ses.newkeys->algo_hostkey = sshhostkey[0].val;
ses.send_kex_first_guess();
}
......@@ -279,26 +280,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) {