238
238
void kexfirstinitialise() {
239
239
ses.kexstate.donefirstkex = 0;
242
if (opts.enable_compress) {
243
ses.compress_algos = ssh_compress;
242
ses.compress_algos = ssh_nocompress;
244
switch (opts.compress_mode)
247
ses.compress_algos = ssh_nocompress;
246
case DROPBEAR_COMPRESS_DELAYED:
247
ses.compress_algos = ssh_delaycompress;
250
case DROPBEAR_COMPRESS_ON:
251
ses.compress_algos = ssh_compress;
254
case DROPBEAR_COMPRESS_OFF:
255
ses.compress_algos = ssh_nocompress;
303
313
hash_desc->done(&hs2, tmpout);
304
314
memcpy(&out[offset], tmpout, MIN(outlen - offset, hash_desc->hashsize));
316
m_burn(&hs2, sizeof(hash_state));
309
319
/* Generate the actual encryption/integrity keys, using the results of the
403
413
m_burn(C2S_key, sizeof(C2S_key));
404
414
m_burn(S2C_IV, sizeof(S2C_IV));
405
415
m_burn(S2C_key, sizeof(S2C_key));
416
m_burn(&hs, sizeof(hash_state));
407
418
TRACE(("leave gen_new_keys"))
501
512
/* start the kex hash */
502
513
local_ident_len = strlen(LOCAL_IDENT);
503
remote_ident_len = strlen((char*)ses.remoteident);
514
remote_ident_len = strlen(ses.remoteident);
505
516
kexhashbuf_len = local_ident_len + remote_ident_len
506
517
+ ses.transkexinit->len + ses.payload->len
514
525
read_kex_algos();
516
527
/* V_C, the client's version string (CR and NL excluded) */
517
buf_putstring(ses.kexhashbuf,
518
(unsigned char*)LOCAL_IDENT, local_ident_len);
528
buf_putstring(ses.kexhashbuf, LOCAL_IDENT, local_ident_len);
519
529
/* V_S, the server's version string (CR and NL excluded) */
520
530
buf_putstring(ses.kexhashbuf, ses.remoteident, remote_ident_len);
522
532
/* I_C, the payload of the client's SSH_MSG_KEXINIT */
523
533
buf_putstring(ses.kexhashbuf,
524
ses.transkexinit->data, ses.transkexinit->len);
534
(const char*)ses.transkexinit->data, ses.transkexinit->len);
525
535
/* I_S, the payload of the server's SSH_MSG_KEXINIT */
526
buf_setpos(ses.payload, 0);
527
buf_putstring(ses.kexhashbuf, ses.payload->data, ses.payload->len);
536
buf_setpos(ses.payload, ses.payload_beginning);
537
buf_putstring(ses.kexhashbuf,
538
(const char*)buf_getptr(ses.payload, ses.payload->len-ses.payload->pos),
539
ses.payload->len-ses.payload->pos);
528
540
ses.requirenext = SSH_MSG_KEXDH_REPLY;
534
546
/* V_C, the client's version string (CR and NL excluded) */
535
547
buf_putstring(ses.kexhashbuf, ses.remoteident, remote_ident_len);
536
548
/* V_S, the server's version string (CR and NL excluded) */
549
buf_putstring(ses.kexhashbuf, LOCAL_IDENT, local_ident_len);
551
/* I_C, the payload of the client's SSH_MSG_KEXINIT */
552
buf_setpos(ses.payload, ses.payload_beginning);
537
553
buf_putstring(ses.kexhashbuf,
538
(unsigned char*)LOCAL_IDENT, local_ident_len);
540
/* I_C, the payload of the client's SSH_MSG_KEXINIT */
541
buf_setpos(ses.payload, 0);
542
buf_putstring(ses.kexhashbuf, ses.payload->data, ses.payload->len);
554
(const char*)buf_getptr(ses.payload, ses.payload->len-ses.payload->pos),
555
ses.payload->len-ses.payload->pos);
544
557
/* I_S, the payload of the server's SSH_MSG_KEXINIT */
545
558
buf_putstring(ses.kexhashbuf,
546
ses.transkexinit->data, ses.transkexinit->len);
559
(const char*)ses.transkexinit->data, ses.transkexinit->len);
548
561
ses.requirenext = SSH_MSG_KEXDH_INIT;
618
631
void kexdh_comb_key(struct kex_dh_param *param, mp_int *dh_pub_them,
619
632
sign_key *hostkey) {
635
DEF_MP_INT(dh_p_min1);
622
636
mp_int *dh_e = NULL, *dh_f = NULL;
624
/* read the prime and generator*/
638
m_mp_init_multi(&dh_p, &dh_p_min1, NULL);
626
639
load_dh_p(&dh_p);
628
/* Check that dh_pub_them (dh_e or dh_f) is in the range [1, p-1] */
629
if (mp_cmp(dh_pub_them, &dh_p) != MP_LT
630
|| mp_cmp_d(dh_pub_them, 0) != MP_GT) {
641
if (mp_sub_d(&dh_p, 1, &dh_p_min1) != MP_OKAY) {
642
dropbear_exit("Diffie-Hellman error");
645
/* Check that dh_pub_them (dh_e or dh_f) is in the range [2, p-2] */
646
if (mp_cmp(dh_pub_them, &dh_p_min1) != MP_LT
647
|| mp_cmp_d(dh_pub_them, 1) != MP_GT) {
631
648
dropbear_exit("Diffie-Hellman error");
640
657
/* clear no longer needed vars */
641
mp_clear_multi(&dh_p, NULL);
658
mp_clear_multi(&dh_p, &dh_p_min1, NULL);
643
660
/* From here on, the code needs to work with the _same_ vars on each side,
644
661
* not vice-versaing for client/server */
686
703
ecc_key *Q_C, *Q_S, *Q_them;
688
705
Q_them = buf_get_ecc_raw_pubkey(pub_them, algo_kex->ecc_curve);
706
if (Q_them == NULL) {
707
dropbear_exit("ECC error");
690
710
ses.dh_K = dropbear_ecc_shared_secret(Q_them, ¶m->key);
764
784
/* K_S, the host key */
765
785
buf_put_pub_key(ses.kexhashbuf, hostkey, ses.newkeys->algo_hostkey);
766
786
/* Q_C, client's ephemeral public key octet string */
767
buf_putstring(ses.kexhashbuf, Q_C, CURVE25519_LEN);
787
buf_putstring(ses.kexhashbuf, (const char*)Q_C, CURVE25519_LEN);
768
788
/* Q_S, server's ephemeral public key octet string */
769
buf_putstring(ses.kexhashbuf, Q_S, CURVE25519_LEN);
789
buf_putstring(ses.kexhashbuf, (const char*)Q_S, CURVE25519_LEN);
770
790
/* K, the shared secret */
771
791
buf_putmpint(ses.kexhashbuf, ses.dh_K);
799
819
buf_burn(ses.kexhashbuf);
800
820
buf_free(ses.kexhashbuf);
821
m_burn(&hs, sizeof(hash_state));
801
822
ses.kexhashbuf = NULL;
803
824
/* first time around, we set the session_id to H */