1 /*
2 * Dropbear SSH
3 *
4 * Copyright (c) 2002-2004 Matt Johnston
5 * Portions Copyright (c) 2004 by Mihnea Stoenescu
6 * All rights reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * SOFTWARE. */
25
26 #include "includes.h"
27 #include "dbutil.h"
28 #include "algo.h"
29 #include "buffer.h"
30 #include "session.h"
31 #include "kex.h"
32 #include "dh_groups.h"
33 #include "ssh.h"
34 #include "packet.h"
35 #include "bignum.h"
36 #include "dbrandom.h"
37 #include "runopts.h"
38 #include "ecc.h"
39 #include "curve25519.h"
40 #include "crypto_desc.h"
41
42 static void kexinitialise(void);
43 static void gen_new_keys(void);
44 #ifndef DISABLE_ZLIB
45 static void gen_new_zstream_recv(void);
46 static void gen_new_zstream_trans(void);
47 #endif
48 static void read_kex_algos(void);
49 /* helper function for gen_new_keys */
50 static void hashkeys(unsigned char *out, unsigned int outlen,
51 const hash_state * hs, const unsigned char X);
52
53
54 /* Send our list of algorithms we can use */
send_msg_kexinit()55 void send_msg_kexinit() {
56
57 CHECKCLEARTOWRITE();
58 buf_putbyte(ses.writepayload, SSH_MSG_KEXINIT);
59
60 /* cookie */
61 genrandom(buf_getwriteptr(ses.writepayload, 16), 16);
62 buf_incrwritepos(ses.writepayload, 16);
63
64 /* kex algos */
65 buf_put_algolist(ses.writepayload, sshkex);
66
67 /* server_host_key_algorithms */
68 buf_put_algolist(ses.writepayload, sigalgs);
69
70 /* encryption_algorithms_client_to_server */
71 buf_put_algolist(ses.writepayload, sshciphers);
72
73 /* encryption_algorithms_server_to_client */
74 buf_put_algolist(ses.writepayload, sshciphers);
75
76 /* mac_algorithms_client_to_server */
77 buf_put_algolist(ses.writepayload, sshhashes);
78
79 /* mac_algorithms_server_to_client */
80 buf_put_algolist(ses.writepayload, sshhashes);
81
82
83 /* compression_algorithms_client_to_server */
84 buf_put_algolist(ses.writepayload, ses.compress_algos);
85
86 /* compression_algorithms_server_to_client */
87 buf_put_algolist(ses.writepayload, ses.compress_algos);
88
89 /* languages_client_to_server */
90 buf_putstring(ses.writepayload, "", 0);
91
92 /* languages_server_to_client */
93 buf_putstring(ses.writepayload, "", 0);
94
95 /* first_kex_packet_follows */
96 buf_putbyte(ses.writepayload, (ses.send_kex_first_guess != NULL));
97
98 /* reserved unit32 */
99 buf_putint(ses.writepayload, 0);
100
101 /* set up transmitted kex packet buffer for hashing.
102 * This is freed after the end of the kex */
103 ses.transkexinit = buf_newcopy(ses.writepayload);
104
105 encrypt_packet();
106 ses.dataallowed = 0; /* don't send other packets during kex */
107
108 ses.kexstate.sentkexinit = 1;
109
110 ses.newkeys = (struct key_context*)m_malloc(sizeof(struct key_context));
111
112 if (ses.send_kex_first_guess) {
113 ses.newkeys->algo_kex = first_usable_algo(sshkex)->data;
114 ses.newkeys->algo_signature = first_usable_algo(sigalgs)->val;
115 ses.newkeys->algo_hostkey = signkey_type_from_signature(ses.newkeys->algo_signature);
116 ses.send_kex_first_guess();
117 }
118
119 TRACE(("DATAALLOWED=0"))
120 TRACE(("-> KEXINIT"))
121
122 }
123
switch_keys()124 static void switch_keys() {
125 TRACE2(("enter switch_keys"))
126 if (!(ses.kexstate.sentkexinit && ses.kexstate.recvkexinit)) {
127 dropbear_exit("Unexpected newkeys message");
128 }
129
130 if (!ses.keys) {
131 ses.keys = m_malloc(sizeof(*ses.newkeys));
132 }
133 if (ses.kexstate.recvnewkeys && ses.newkeys->recv.valid) {
134 TRACE(("switch_keys recv"))
135 #ifndef DISABLE_ZLIB
136 gen_new_zstream_recv();
137 #endif
138 ses.keys->recv = ses.newkeys->recv;
139 m_burn(&ses.newkeys->recv, sizeof(ses.newkeys->recv));
140 ses.newkeys->recv.valid = 0;
141 }
142 if (ses.kexstate.sentnewkeys && ses.newkeys->trans.valid) {
143 TRACE(("switch_keys trans"))
144 #ifndef DISABLE_ZLIB
145 gen_new_zstream_trans();
146 #endif
147 ses.keys->trans = ses.newkeys->trans;
148 m_burn(&ses.newkeys->trans, sizeof(ses.newkeys->trans));
149 ses.newkeys->trans.valid = 0;
150 }
151 if (ses.kexstate.sentnewkeys && ses.kexstate.recvnewkeys)
152 {
153 TRACE(("switch_keys done"))
154 ses.keys->algo_kex = ses.newkeys->algo_kex;
155 ses.keys->algo_hostkey = ses.newkeys->algo_hostkey;
156 ses.keys->algo_signature = ses.newkeys->algo_signature;
157 ses.keys->allow_compress = 0;
158 m_free(ses.newkeys);
159 ses.newkeys = NULL;
160 kexinitialise();
161 }
162 TRACE2(("leave switch_keys"))
163 }
164
165 /* Bring new keys into use after a key exchange, and let the client know*/
send_msg_newkeys()166 void send_msg_newkeys() {
167
168 TRACE(("enter send_msg_newkeys"))
169
170 /* generate the kexinit request */
171 CHECKCLEARTOWRITE();
172 buf_putbyte(ses.writepayload, SSH_MSG_NEWKEYS);
173 encrypt_packet();
174
175
176 /* set up our state */
177 ses.kexstate.sentnewkeys = 1;
178 if (ses.kexstate.donefirstkex) {
179 ses.kexstate.donesecondkex = 1;
180 }
181 ses.kexstate.donefirstkex = 1;
182 ses.dataallowed = 1; /* we can send other packets again now */
183 gen_new_keys();
184 switch_keys();
185
186 TRACE(("leave send_msg_newkeys"))
187 }
188
189 /* Bring the new keys into use after a key exchange */
recv_msg_newkeys()190 void recv_msg_newkeys() {
191
192 TRACE(("enter recv_msg_newkeys"))
193
194 ses.kexstate.recvnewkeys = 1;
195 switch_keys();
196
197 TRACE(("leave recv_msg_newkeys"))
198 }
199
200
201 /* Set up the kex for the first time */
kexfirstinitialise()202 void kexfirstinitialise() {
203 #ifdef DISABLE_ZLIB
204 ses.compress_algos = ssh_nocompress;
205 #else
206 switch (opts.compress_mode)
207 {
208 case DROPBEAR_COMPRESS_DELAYED:
209 ses.compress_algos = ssh_delaycompress;
210 break;
211
212 case DROPBEAR_COMPRESS_ON:
213 ses.compress_algos = ssh_compress;
214 break;
215
216 case DROPBEAR_COMPRESS_OFF:
217 ses.compress_algos = ssh_nocompress;
218 break;
219 }
220 #endif
221 kexinitialise();
222 }
223
224 /* Reset the kex state, ready for a new negotiation */
kexinitialise()225 static void kexinitialise() {
226
227 TRACE(("kexinitialise()"))
228
229 /* sent/recv'd MSG_KEXINIT */
230 ses.kexstate.sentkexinit = 0;
231 ses.kexstate.recvkexinit = 0;
232
233 /* sent/recv'd MSG_NEWKEYS */
234 ses.kexstate.recvnewkeys = 0;
235 ses.kexstate.sentnewkeys = 0;
236
237 /* first_packet_follows */
238 ses.kexstate.them_firstfollows = 0;
239
240 ses.kexstate.datatrans = 0;
241 ses.kexstate.datarecv = 0;
242
243 ses.kexstate.our_first_follows_matches = 0;
244
245 ses.kexstate.lastkextime = monotonic_now();
246
247 }
248
249 /* Helper function for gen_new_keys, creates a hash. It makes a copy of the
250 * already initialised hash_state hs, which should already have processed
251 * the dh_K and hash, since these are common. X is the letter 'A', 'B' etc.
252 * out must have at least min(SHA1_HASH_SIZE, outlen) bytes allocated.
253 *
254 * See Section 7.2 of rfc4253 (ssh transport) for details */
hashkeys(unsigned char * out,unsigned int outlen,const hash_state * hs,const unsigned char X)255 static void hashkeys(unsigned char *out, unsigned int outlen,
256 const hash_state * hs, const unsigned char X) {
257
258 const struct ltc_hash_descriptor *hash_desc = ses.newkeys->algo_kex->hash_desc;
259 hash_state hs2;
260 unsigned int offset;
261 unsigned char tmpout[MAX_HASH_SIZE];
262
263 memcpy(&hs2, hs, sizeof(hash_state));
264 hash_desc->process(&hs2, &X, 1);
265 hash_desc->process(&hs2, ses.session_id->data, ses.session_id->len);
266 hash_desc->done(&hs2, tmpout);
267 memcpy(out, tmpout, MIN(hash_desc->hashsize, outlen));
268 for (offset = hash_desc->hashsize;
269 offset < outlen;
270 offset += hash_desc->hashsize)
271 {
272 /* need to extend */
273 memcpy(&hs2, hs, sizeof(hash_state));
274 hash_desc->process(&hs2, out, offset);
275 hash_desc->done(&hs2, tmpout);
276 memcpy(&out[offset], tmpout, MIN(outlen - offset, hash_desc->hashsize));
277 }
278 m_burn(&hs2, sizeof(hash_state));
279 }
280
281 /* Generate the actual encryption/integrity keys, using the results of the
282 * key exchange, as specified in section 7.2 of the transport rfc 4253.
283 * This occurs after the DH key-exchange.
284 *
285 * ses.newkeys is the new set of keys which are generated, these are only
286 * taken into use after both sides have sent a newkeys message */
287
gen_new_keys()288 static void gen_new_keys() {
289
290 unsigned char C2S_IV[MAX_IV_LEN];
291 unsigned char C2S_key[MAX_KEY_LEN];
292 unsigned char S2C_IV[MAX_IV_LEN];
293 unsigned char S2C_key[MAX_KEY_LEN];
294 /* unsigned char key[MAX_KEY_LEN]; */
295 unsigned char *trans_IV, *trans_key, *recv_IV, *recv_key;
296
297 hash_state hs;
298 const struct ltc_hash_descriptor *hash_desc = ses.newkeys->algo_kex->hash_desc;
299 char mactransletter, macrecvletter; /* Client or server specific */
300
301 TRACE(("enter gen_new_keys"))
302 /* the dh_K and hash are the start of all hashes, we make use of that */
303
304 hash_desc->init(&hs);
305 hash_process_mp(hash_desc, &hs, ses.dh_K);
306 mp_clear(ses.dh_K);
307 m_free(ses.dh_K);
308 hash_desc->process(&hs, ses.hash->data, ses.hash->len);
309 buf_burn(ses.hash);
310 buf_free(ses.hash);
311 ses.hash = NULL;
312
313 if (IS_DROPBEAR_CLIENT) {
314 trans_IV = C2S_IV;
315 recv_IV = S2C_IV;
316 trans_key = C2S_key;
317 recv_key = S2C_key;
318 mactransletter = 'E';
319 macrecvletter = 'F';
320 } else {
321 trans_IV = S2C_IV;
322 recv_IV = C2S_IV;
323 trans_key = S2C_key;
324 recv_key = C2S_key;
325 mactransletter = 'F';
326 macrecvletter = 'E';
327 }
328
329 hashkeys(C2S_IV, sizeof(C2S_IV), &hs, 'A');
330 hashkeys(S2C_IV, sizeof(S2C_IV), &hs, 'B');
331 hashkeys(C2S_key, sizeof(C2S_key), &hs, 'C');
332 hashkeys(S2C_key, sizeof(S2C_key), &hs, 'D');
333
334 if (ses.newkeys->recv.algo_crypt->cipherdesc != NULL) {
335 int recv_cipher = -1;
336 if (ses.newkeys->recv.algo_crypt->cipherdesc->name != NULL) {
337 recv_cipher = find_cipher(ses.newkeys->recv.algo_crypt->cipherdesc->name);
338 if (recv_cipher < 0) {
339 dropbear_exit("Crypto error");
340 }
341 }
342 if (ses.newkeys->recv.crypt_mode->start(recv_cipher,
343 recv_IV, recv_key,
344 ses.newkeys->recv.algo_crypt->keysize, 0,
345 &ses.newkeys->recv.cipher_state) != CRYPT_OK) {
346 dropbear_exit("Crypto error");
347 }
348 }
349
350 if (ses.newkeys->trans.algo_crypt->cipherdesc != NULL) {
351 int trans_cipher = -1;
352 if (ses.newkeys->trans.algo_crypt->cipherdesc->name != NULL) {
353 trans_cipher = find_cipher(ses.newkeys->trans.algo_crypt->cipherdesc->name);
354 if (trans_cipher < 0) {
355 dropbear_exit("Crypto error");
356 }
357 }
358 if (ses.newkeys->trans.crypt_mode->start(trans_cipher,
359 trans_IV, trans_key,
360 ses.newkeys->trans.algo_crypt->keysize, 0,
361 &ses.newkeys->trans.cipher_state) != CRYPT_OK) {
362 dropbear_exit("Crypto error");
363 }
364 }
365
366 if (ses.newkeys->trans.algo_mac->hash_desc != NULL) {
367 hashkeys(ses.newkeys->trans.mackey,
368 ses.newkeys->trans.algo_mac->keysize, &hs, mactransletter);
369 ses.newkeys->trans.hash_index = find_hash(ses.newkeys->trans.algo_mac->hash_desc->name);
370 }
371
372 if (ses.newkeys->recv.algo_mac->hash_desc != NULL) {
373 hashkeys(ses.newkeys->recv.mackey,
374 ses.newkeys->recv.algo_mac->keysize, &hs, macrecvletter);
375 ses.newkeys->recv.hash_index = find_hash(ses.newkeys->recv.algo_mac->hash_desc->name);
376 }
377
378 /* Ready to switch over */
379 ses.newkeys->trans.valid = 1;
380 ses.newkeys->recv.valid = 1;
381
382 m_burn(C2S_IV, sizeof(C2S_IV));
383 m_burn(C2S_key, sizeof(C2S_key));
384 m_burn(S2C_IV, sizeof(S2C_IV));
385 m_burn(S2C_key, sizeof(S2C_key));
386 m_burn(&hs, sizeof(hash_state));
387
388 TRACE(("leave gen_new_keys"))
389 }
390
391 #ifndef DISABLE_ZLIB
392
is_compress_trans()393 int is_compress_trans() {
394 return ses.keys->trans.algo_comp == DROPBEAR_COMP_ZLIB
395 || (ses.authstate.authdone
396 && ses.keys->trans.algo_comp == DROPBEAR_COMP_ZLIB_DELAY);
397 }
398
is_compress_recv()399 int is_compress_recv() {
400 return ses.keys->recv.algo_comp == DROPBEAR_COMP_ZLIB
401 || (ses.authstate.authdone
402 && ses.keys->recv.algo_comp == DROPBEAR_COMP_ZLIB_DELAY);
403 }
404
dropbear_zalloc(void * UNUSED (opaque),uInt items,uInt size)405 static void* dropbear_zalloc(void* UNUSED(opaque), uInt items, uInt size) {
406 return m_calloc(items, size);
407 }
408
dropbear_zfree(void * UNUSED (opaque),void * ptr)409 static void dropbear_zfree(void* UNUSED(opaque), void* ptr) {
410 m_free(ptr);
411 }
412
413 /* Set up new zlib compression streams, close the old ones. Only
414 * called from gen_new_keys() */
gen_new_zstream_recv()415 static void gen_new_zstream_recv() {
416
417 /* create new zstreams */
418 if (ses.newkeys->recv.algo_comp == DROPBEAR_COMP_ZLIB
419 || ses.newkeys->recv.algo_comp == DROPBEAR_COMP_ZLIB_DELAY) {
420 ses.newkeys->recv.zstream = (z_streamp)m_malloc(sizeof(z_stream));
421 ses.newkeys->recv.zstream->zalloc = dropbear_zalloc;
422 ses.newkeys->recv.zstream->zfree = dropbear_zfree;
423
424 if (inflateInit(ses.newkeys->recv.zstream) != Z_OK) {
425 dropbear_exit("zlib error");
426 }
427 } else {
428 ses.newkeys->recv.zstream = NULL;
429 }
430 /* clean up old keys */
431 if (ses.keys->recv.zstream != NULL) {
432 if (inflateEnd(ses.keys->recv.zstream) == Z_STREAM_ERROR) {
433 /* Z_DATA_ERROR is ok, just means that stream isn't ended */
434 dropbear_exit("Crypto error");
435 }
436 m_free(ses.keys->recv.zstream);
437 }
438 }
439
gen_new_zstream_trans()440 static void gen_new_zstream_trans() {
441
442 if (ses.newkeys->trans.algo_comp == DROPBEAR_COMP_ZLIB
443 || ses.newkeys->trans.algo_comp == DROPBEAR_COMP_ZLIB_DELAY) {
444 ses.newkeys->trans.zstream = (z_streamp)m_malloc(sizeof(z_stream));
445 ses.newkeys->trans.zstream->zalloc = dropbear_zalloc;
446 ses.newkeys->trans.zstream->zfree = dropbear_zfree;
447
448 if (deflateInit2(ses.newkeys->trans.zstream, Z_DEFAULT_COMPRESSION,
449 Z_DEFLATED, DROPBEAR_ZLIB_WINDOW_BITS,
450 DROPBEAR_ZLIB_MEM_LEVEL, Z_DEFAULT_STRATEGY)
451 != Z_OK) {
452 dropbear_exit("zlib error");
453 }
454 } else {
455 ses.newkeys->trans.zstream = NULL;
456 }
457
458 if (ses.keys->trans.zstream != NULL) {
459 if (deflateEnd(ses.keys->trans.zstream) == Z_STREAM_ERROR) {
460 /* Z_DATA_ERROR is ok, just means that stream isn't ended */
461 dropbear_exit("Crypto error");
462 }
463 m_free(ses.keys->trans.zstream);
464 }
465 }
466 #endif /* DISABLE_ZLIB */
467
468
469 /* Executed upon receiving a kexinit message from the client to initiate
470 * key exchange. If we haven't already done so, we send the list of our
471 * preferred algorithms. The client's requested algorithms are processed,
472 * and we calculate the first portion of the key-exchange-hash for used
473 * later in the key exchange. No response is sent, as the client should
474 * initiate the diffie-hellman key exchange */
recv_msg_kexinit()475 void recv_msg_kexinit() {
476
477 unsigned int kexhashbuf_len = 0;
478 unsigned int remote_ident_len = 0;
479 unsigned int local_ident_len = 0;
480
481 TRACE(("<- KEXINIT"))
482 TRACE(("enter recv_msg_kexinit"))
483
484 if (!ses.kexstate.sentkexinit) {
485 /* we need to send a kex packet */
486 send_msg_kexinit();
487 TRACE(("continue recv_msg_kexinit: sent kexinit"))
488 }
489
490 /* "Once a party has sent a SSH_MSG_KEXINIT message ...
491 further SSH_MSG_KEXINIT messages MUST NOT be sent" */
492 if (ses.kexstate.recvkexinit) {
493 dropbear_exit("Unexpected KEXINIT");
494 }
495
496 /* start the kex hash */
497 local_ident_len = strlen(LOCAL_IDENT);
498 remote_ident_len = strlen(ses.remoteident);
499
500 kexhashbuf_len = local_ident_len + remote_ident_len
501 + ses.transkexinit->len + ses.payload->len
502 + KEXHASHBUF_MAX_INTS;
503
504 ses.kexhashbuf = buf_new(kexhashbuf_len);
505
506 if (IS_DROPBEAR_CLIENT) {
507
508 /* read the peer's choice of algos */
509 read_kex_algos();
510
511 /* V_C, the client's version string (CR and NL excluded) */
512 buf_putstring(ses.kexhashbuf, LOCAL_IDENT, local_ident_len);
513 /* V_S, the server's version string (CR and NL excluded) */
514 buf_putstring(ses.kexhashbuf, ses.remoteident, remote_ident_len);
515
516 /* I_C, the payload of the client's SSH_MSG_KEXINIT */
517 buf_putstring(ses.kexhashbuf,
518 (const char*)ses.transkexinit->data, ses.transkexinit->len);
519 /* I_S, the payload of the server's SSH_MSG_KEXINIT */
520 buf_setpos(ses.payload, ses.payload_beginning);
521 buf_putstring(ses.kexhashbuf,
522 (const char*)buf_getptr(ses.payload, ses.payload->len-ses.payload->pos),
523 ses.payload->len-ses.payload->pos);
524 ses.requirenext = SSH_MSG_KEXDH_REPLY;
525 } else {
526 /* SERVER */
527
528 /* read the peer's choice of algos */
529 read_kex_algos();
530 /* V_C, the client's version string (CR and NL excluded) */
531 buf_putstring(ses.kexhashbuf, ses.remoteident, remote_ident_len);
532 /* V_S, the server's version string (CR and NL excluded) */
533 buf_putstring(ses.kexhashbuf, LOCAL_IDENT, local_ident_len);
534
535 /* I_C, the payload of the client's SSH_MSG_KEXINIT */
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);
540
541 /* I_S, the payload of the server's SSH_MSG_KEXINIT */
542 buf_putstring(ses.kexhashbuf,
543 (const char*)ses.transkexinit->data, ses.transkexinit->len);
544
545 ses.requirenext = SSH_MSG_KEXDH_INIT;
546 }
547
548 buf_free(ses.transkexinit);
549 ses.transkexinit = NULL;
550 /* the rest of ses.kexhashbuf will be done after DH exchange */
551
552 ses.kexstate.recvkexinit = 1;
553
554 TRACE(("leave recv_msg_kexinit"))
555 }
556
557 #if DROPBEAR_NORMAL_DH
load_dh_p(mp_int * dh_p)558 static void load_dh_p(mp_int * dh_p)
559 {
560 bytes_to_mp(dh_p, ses.newkeys->algo_kex->dh_p_bytes,
561 ses.newkeys->algo_kex->dh_p_len);
562 }
563
564 /* Initialises and generate one side of the diffie-hellman key exchange values.
565 * See the transport rfc 4253 section 8 for details */
566 /* dh_pub and dh_priv MUST be already initialised */
gen_kexdh_param()567 struct kex_dh_param *gen_kexdh_param() {
568 struct kex_dh_param *param = NULL;
569
570 DEF_MP_INT(dh_p);
571 DEF_MP_INT(dh_q);
572 DEF_MP_INT(dh_g);
573
574 TRACE(("enter gen_kexdh_vals"))
575
576 param = m_malloc(sizeof(*param));
577 m_mp_init_multi(¶m->pub, ¶m->priv, &dh_g, &dh_p, &dh_q, NULL);
578
579 /* read the prime and generator*/
580 load_dh_p(&dh_p);
581
582 mp_set_ul(&dh_g, DH_G_VAL);
583
584 /* calculate q = (p-1)/2 */
585 /* dh_priv is just a temp var here */
586 if (mp_sub_d(&dh_p, 1, ¶m->priv) != MP_OKAY) {
587 dropbear_exit("Diffie-Hellman error");
588 }
589 if (mp_div_2(¶m->priv, &dh_q) != MP_OKAY) {
590 dropbear_exit("Diffie-Hellman error");
591 }
592
593 /* Generate a private portion 0 < dh_priv < dh_q */
594 gen_random_mpint(&dh_q, ¶m->priv);
595
596 /* f = g^y mod p */
597 if (mp_exptmod(&dh_g, ¶m->priv, &dh_p, ¶m->pub) != MP_OKAY) {
598 dropbear_exit("Diffie-Hellman error");
599 }
600 mp_clear_multi(&dh_g, &dh_p, &dh_q, NULL);
601 return param;
602 }
603
free_kexdh_param(struct kex_dh_param * param)604 void free_kexdh_param(struct kex_dh_param *param)
605 {
606 mp_clear_multi(¶m->pub, ¶m->priv, NULL);
607 m_free(param);
608 }
609
610 /* This function is fairly common between client/server, with some substitution
611 * of dh_e/dh_f etc. Hence these arguments:
612 * dh_pub_us is 'e' for the client, 'f' for the server. dh_pub_them is
613 * vice-versa. dh_priv is the x/y value corresponding to dh_pub_us */
kexdh_comb_key(struct kex_dh_param * param,mp_int * dh_pub_them,sign_key * hostkey)614 void kexdh_comb_key(struct kex_dh_param *param, mp_int *dh_pub_them,
615 sign_key *hostkey) {
616
617 DEF_MP_INT(dh_p);
618 DEF_MP_INT(dh_p_min1);
619 mp_int *dh_e = NULL, *dh_f = NULL;
620
621 m_mp_init_multi(&dh_p, &dh_p_min1, NULL);
622 load_dh_p(&dh_p);
623
624 if (mp_sub_d(&dh_p, 1, &dh_p_min1) != MP_OKAY) {
625 dropbear_exit("Diffie-Hellman error");
626 }
627
628 /* Check that dh_pub_them (dh_e or dh_f) is in the range [2, p-2] */
629 if (mp_cmp(dh_pub_them, &dh_p_min1) != MP_LT
630 || mp_cmp_d(dh_pub_them, 1) != MP_GT) {
631 dropbear_exit("Diffie-Hellman error");
632 }
633
634 /* K = e^y mod p = f^x mod p */
635 m_mp_alloc_init_multi(&ses.dh_K, NULL);
636 if (mp_exptmod(dh_pub_them, ¶m->priv, &dh_p, ses.dh_K) != MP_OKAY) {
637 dropbear_exit("Diffie-Hellman error");
638 }
639
640 /* clear no longer needed vars */
641 mp_clear_multi(&dh_p, &dh_p_min1, NULL);
642
643 /* From here on, the code needs to work with the _same_ vars on each side,
644 * not vice-versaing for client/server */
645 if (IS_DROPBEAR_CLIENT) {
646 dh_e = ¶m->pub;
647 dh_f = dh_pub_them;
648 } else {
649 dh_e = dh_pub_them;
650 dh_f = ¶m->pub;
651 }
652
653 /* Create the remainder of the hash buffer, to generate the exchange hash */
654 /* K_S, the host key */
655 buf_put_pub_key(ses.kexhashbuf, hostkey, ses.newkeys->algo_hostkey);
656 /* e, exchange value sent by the client */
657 buf_putmpint(ses.kexhashbuf, dh_e);
658 /* f, exchange value sent by the server */
659 buf_putmpint(ses.kexhashbuf, dh_f);
660 /* K, the shared secret */
661 buf_putmpint(ses.kexhashbuf, ses.dh_K);
662
663 /* calculate the hash H to sign */
664 finish_kexhashbuf();
665 }
666 #endif
667
668 #if DROPBEAR_ECDH
gen_kexecdh_param()669 struct kex_ecdh_param *gen_kexecdh_param() {
670 struct kex_ecdh_param *param = m_malloc(sizeof(*param));
671 if (ecc_make_key_ex(NULL, dropbear_ltc_prng,
672 ¶m->key, ses.newkeys->algo_kex->ecc_curve->dp) != CRYPT_OK) {
673 dropbear_exit("ECC error");
674 }
675 return param;
676 }
677
free_kexecdh_param(struct kex_ecdh_param * param)678 void free_kexecdh_param(struct kex_ecdh_param *param) {
679 ecc_free(¶m->key);
680 m_free(param);
681
682 }
kexecdh_comb_key(struct kex_ecdh_param * param,buffer * pub_them,sign_key * hostkey)683 void kexecdh_comb_key(struct kex_ecdh_param *param, buffer *pub_them,
684 sign_key *hostkey) {
685 const struct dropbear_kex *algo_kex = ses.newkeys->algo_kex;
686 /* public keys from client and server */
687 ecc_key *Q_C, *Q_S, *Q_them;
688
689 Q_them = buf_get_ecc_raw_pubkey(pub_them, algo_kex->ecc_curve);
690 if (Q_them == NULL) {
691 dropbear_exit("ECC error");
692 }
693
694 ses.dh_K = dropbear_ecc_shared_secret(Q_them, ¶m->key);
695
696 /* Create the remainder of the hash buffer, to generate the exchange hash
697 See RFC5656 section 4 page 7 */
698 if (IS_DROPBEAR_CLIENT) {
699 Q_C = ¶m->key;
700 Q_S = Q_them;
701 } else {
702 Q_C = Q_them;
703 Q_S = ¶m->key;
704 }
705
706 /* K_S, the host key */
707 buf_put_pub_key(ses.kexhashbuf, hostkey, ses.newkeys->algo_hostkey);
708 /* Q_C, client's ephemeral public key octet string */
709 buf_put_ecc_raw_pubkey_string(ses.kexhashbuf, Q_C);
710 /* Q_S, server's ephemeral public key octet string */
711 buf_put_ecc_raw_pubkey_string(ses.kexhashbuf, Q_S);
712 /* K, the shared secret */
713 buf_putmpint(ses.kexhashbuf, ses.dh_K);
714
715 ecc_free(Q_them);
716 m_free(Q_them);
717
718 /* calculate the hash H to sign */
719 finish_kexhashbuf();
720 }
721 #endif /* DROPBEAR_ECDH */
722
723 #if DROPBEAR_CURVE25519
gen_kexcurve25519_param()724 struct kex_curve25519_param *gen_kexcurve25519_param() {
725 /* Per http://cr.yp.to/ecdh.html */
726 struct kex_curve25519_param *param = m_malloc(sizeof(*param));
727 const unsigned char basepoint[32] = {9};
728
729 genrandom(param->priv, CURVE25519_LEN);
730 dropbear_curve25519_scalarmult(param->pub, param->priv, basepoint);
731
732 return param;
733 }
734
free_kexcurve25519_param(struct kex_curve25519_param * param)735 void free_kexcurve25519_param(struct kex_curve25519_param *param) {
736 m_burn(param->priv, CURVE25519_LEN);
737 m_free(param);
738 }
739
kexcurve25519_comb_key(const struct kex_curve25519_param * param,const buffer * buf_pub_them,sign_key * hostkey)740 void kexcurve25519_comb_key(const struct kex_curve25519_param *param, const buffer *buf_pub_them,
741 sign_key *hostkey) {
742 unsigned char out[CURVE25519_LEN];
743 const unsigned char* Q_C = NULL;
744 const unsigned char* Q_S = NULL;
745 char zeroes[CURVE25519_LEN] = {0};
746
747 if (buf_pub_them->len != CURVE25519_LEN)
748 {
749 dropbear_exit("Bad curve25519");
750 }
751
752 dropbear_curve25519_scalarmult(out, param->priv, buf_pub_them->data);
753
754 if (constant_time_memcmp(zeroes, out, CURVE25519_LEN) == 0) {
755 dropbear_exit("Bad curve25519");
756 }
757
758 m_mp_alloc_init_multi(&ses.dh_K, NULL);
759 bytes_to_mp(ses.dh_K, out, CURVE25519_LEN);
760 m_burn(out, sizeof(out));
761
762 /* Create the remainder of the hash buffer, to generate the exchange hash.
763 See RFC5656 section 4 page 7 */
764 if (IS_DROPBEAR_CLIENT) {
765 Q_C = param->pub;
766 Q_S = buf_pub_them->data;
767 } else {
768 Q_S = param->pub;
769 Q_C = buf_pub_them->data;
770 }
771
772 /* K_S, the host key */
773 buf_put_pub_key(ses.kexhashbuf, hostkey, ses.newkeys->algo_hostkey);
774 /* Q_C, client's ephemeral public key octet string */
775 buf_putstring(ses.kexhashbuf, (const char*)Q_C, CURVE25519_LEN);
776 /* Q_S, server's ephemeral public key octet string */
777 buf_putstring(ses.kexhashbuf, (const char*)Q_S, CURVE25519_LEN);
778 /* K, the shared secret */
779 buf_putmpint(ses.kexhashbuf, ses.dh_K);
780
781 /* calculate the hash H to sign */
782 finish_kexhashbuf();
783 }
784 #endif /* DROPBEAR_CURVE25519 */
785
786
finish_kexhashbuf(void)787 void finish_kexhashbuf(void) {
788 hash_state hs;
789 const struct ltc_hash_descriptor *hash_desc = ses.newkeys->algo_kex->hash_desc;
790
791 hash_desc->init(&hs);
792 buf_setpos(ses.kexhashbuf, 0);
793 hash_desc->process(&hs, buf_getptr(ses.kexhashbuf, ses.kexhashbuf->len),
794 ses.kexhashbuf->len);
795 ses.hash = buf_new(hash_desc->hashsize);
796 hash_desc->done(&hs, buf_getwriteptr(ses.hash, hash_desc->hashsize));
797 buf_setlen(ses.hash, hash_desc->hashsize);
798
799 #if defined(DEBUG_KEXHASH) && DEBUG_TRACE
800 if (!debug_trace) {
801 printhex("kexhashbuf", ses.kexhashbuf->data, ses.kexhashbuf->len);
802 printhex("kexhash", ses.hash->data, ses.hash->len);
803 }
804 #endif
805
806 buf_burn(ses.kexhashbuf);
807 buf_free(ses.kexhashbuf);
808 m_burn(&hs, sizeof(hash_state));
809 ses.kexhashbuf = NULL;
810
811 /* first time around, we set the session_id to H */
812 if (ses.session_id == NULL) {
813 /* create the session_id, this never needs freeing */
814 ses.session_id = buf_newcopy(ses.hash);
815 }
816 }
817
818 /* read the other side's algo list. buf_match_algo is a callback to match
819 * algos for the client or server. */
read_kex_algos()820 static void read_kex_algos() {
821
822 /* for asymmetry */
823 algo_type * c2s_hash_algo = NULL;
824 algo_type * s2c_hash_algo = NULL;
825 algo_type * c2s_cipher_algo = NULL;
826 algo_type * s2c_cipher_algo = NULL;
827 algo_type * c2s_comp_algo = NULL;
828 algo_type * s2c_comp_algo = NULL;
829 /* the generic one */
830 algo_type * algo = NULL;
831
832 /* which algo couldn't match */
833 char * erralgo = NULL;
834
835 int goodguess = 0;
836 int allgood = 1; /* we AND this with each goodguess and see if its still
837 true after */
838 int kexguess2 = 0;
839
840 buf_incrpos(ses.payload, 16); /* start after the cookie */
841
842 memset(ses.newkeys, 0x0, sizeof(*ses.newkeys));
843
844 /* kex_algorithms */
845 #if DROPBEAR_KEXGUESS2
846 if (buf_has_algo(ses.payload, KEXGUESS2_ALGO_NAME) == DROPBEAR_SUCCESS) {
847 kexguess2 = 1;
848 }
849 #endif
850
851 #if DROPBEAR_EXT_INFO
852 /* Determine if SSH_MSG_EXT_INFO messages should be sent.
853 Should be done for the first key exchange. Only required on server side
854 for server-sig-algs */
855 if (IS_DROPBEAR_SERVER) {
856 if (!ses.kexstate.donefirstkex) {
857 if (buf_has_algo(ses.payload, SSH_EXT_INFO_C) == DROPBEAR_SUCCESS) {
858 ses.allow_ext_info = 1;
859 }
860 }
861 }
862 #endif
863
864 algo = buf_match_algo(ses.payload, sshkex, kexguess2, &goodguess);
865 allgood &= goodguess;
866 if (algo == NULL || algo->data == NULL) {
867 /* kexguess2, ext-info-c, ext-info-s should not match negotiation */
868 erralgo = "kex";
869 goto error;
870 }
871 TRACE(("kexguess2 %d", kexguess2))
872 TRACE(("kex algo %s", algo->name))
873 ses.newkeys->algo_kex = algo->data;
874
875 /* server_host_key_algorithms */
876 algo = buf_match_algo(ses.payload, sigalgs, kexguess2, &goodguess);
877 allgood &= goodguess;
878 if (algo == NULL) {
879 erralgo = "hostkey";
880 goto error;
881 }
882 TRACE(("signature algo %s", algo->name))
883 ses.newkeys->algo_signature = algo->val;
884 ses.newkeys->algo_hostkey = signkey_type_from_signature(ses.newkeys->algo_signature);
885
886 /* encryption_algorithms_client_to_server */
887 c2s_cipher_algo = buf_match_algo(ses.payload, sshciphers, 0, NULL);
888 if (c2s_cipher_algo == NULL) {
889 erralgo = "enc c->s";
890 goto error;
891 }
892 TRACE(("enc c2s is %s", c2s_cipher_algo->name))
893
894 /* encryption_algorithms_server_to_client */
895 s2c_cipher_algo = buf_match_algo(ses.payload, sshciphers, 0, NULL);
896 if (s2c_cipher_algo == NULL) {
897 erralgo = "enc s->c";
898 goto error;
899 }
900 TRACE(("enc s2c is %s", s2c_cipher_algo->name))
901
902 /* mac_algorithms_client_to_server */
903 c2s_hash_algo = buf_match_algo(ses.payload, sshhashes, 0, NULL);
904 #if DROPBEAR_AEAD_MODE
905 if (((struct dropbear_cipher_mode*)c2s_cipher_algo->mode)->aead_crypt != NULL) {
906 c2s_hash_algo = NULL;
907 } else
908 #endif
909 if (c2s_hash_algo == NULL) {
910 erralgo = "mac c->s";
911 goto error;
912 }
913 TRACE(("hash c2s is %s", c2s_hash_algo ? c2s_hash_algo->name : "<implicit>"))
914
915 /* mac_algorithms_server_to_client */
916 s2c_hash_algo = buf_match_algo(ses.payload, sshhashes, 0, NULL);
917 #if DROPBEAR_AEAD_MODE
918 if (((struct dropbear_cipher_mode*)s2c_cipher_algo->mode)->aead_crypt != NULL) {
919 s2c_hash_algo = NULL;
920 } else
921 #endif
922 if (s2c_hash_algo == NULL) {
923 erralgo = "mac s->c";
924 goto error;
925 }
926 TRACE(("hash s2c is %s", s2c_hash_algo ? s2c_hash_algo->name : "<implicit>"))
927
928 /* compression_algorithms_client_to_server */
929 c2s_comp_algo = buf_match_algo(ses.payload, ses.compress_algos, 0, NULL);
930 if (c2s_comp_algo == NULL) {
931 erralgo = "comp c->s";
932 goto error;
933 }
934 TRACE(("hash c2s is %s", c2s_comp_algo->name))
935
936 /* compression_algorithms_server_to_client */
937 s2c_comp_algo = buf_match_algo(ses.payload, ses.compress_algos, 0, NULL);
938 if (s2c_comp_algo == NULL) {
939 erralgo = "comp s->c";
940 goto error;
941 }
942 TRACE(("hash s2c is %s", s2c_comp_algo->name))
943
944 /* languages_client_to_server */
945 buf_eatstring(ses.payload);
946
947 /* languages_server_to_client */
948 buf_eatstring(ses.payload);
949
950 /* their first_kex_packet_follows */
951 if (buf_getbool(ses.payload)) {
952 TRACE(("them kex firstfollows. allgood %d", allgood))
953 ses.kexstate.them_firstfollows = 1;
954 /* if the guess wasn't good, we ignore the packet sent */
955 if (!allgood) {
956 ses.ignorenext = 1;
957 }
958 }
959
960 /* Handle the asymmetry */
961 if (IS_DROPBEAR_CLIENT) {
962 ses.newkeys->recv.algo_crypt =
963 (struct dropbear_cipher*)s2c_cipher_algo->data;
964 ses.newkeys->trans.algo_crypt =
965 (struct dropbear_cipher*)c2s_cipher_algo->data;
966 ses.newkeys->recv.crypt_mode =
967 (struct dropbear_cipher_mode*)s2c_cipher_algo->mode;
968 ses.newkeys->trans.crypt_mode =
969 (struct dropbear_cipher_mode*)c2s_cipher_algo->mode;
970 ses.newkeys->recv.algo_mac =
971 #if DROPBEAR_AEAD_MODE
972 s2c_hash_algo == NULL ? ses.newkeys->recv.crypt_mode->aead_mac :
973 #endif
974 (struct dropbear_hash*)s2c_hash_algo->data;
975 ses.newkeys->trans.algo_mac =
976 #if DROPBEAR_AEAD_MODE
977 c2s_hash_algo == NULL ? ses.newkeys->trans.crypt_mode->aead_mac :
978 #endif
979 (struct dropbear_hash*)c2s_hash_algo->data;
980 ses.newkeys->recv.algo_comp = s2c_comp_algo->val;
981 ses.newkeys->trans.algo_comp = c2s_comp_algo->val;
982 } else {
983 /* SERVER */
984 ses.newkeys->recv.algo_crypt =
985 (struct dropbear_cipher*)c2s_cipher_algo->data;
986 ses.newkeys->trans.algo_crypt =
987 (struct dropbear_cipher*)s2c_cipher_algo->data;
988 ses.newkeys->recv.crypt_mode =
989 (struct dropbear_cipher_mode*)c2s_cipher_algo->mode;
990 ses.newkeys->trans.crypt_mode =
991 (struct dropbear_cipher_mode*)s2c_cipher_algo->mode;
992 ses.newkeys->recv.algo_mac =
993 #if DROPBEAR_AEAD_MODE
994 c2s_hash_algo == NULL ? ses.newkeys->recv.crypt_mode->aead_mac :
995 #endif
996 (struct dropbear_hash*)c2s_hash_algo->data;
997 ses.newkeys->trans.algo_mac =
998 #if DROPBEAR_AEAD_MODE
999 s2c_hash_algo == NULL ? ses.newkeys->trans.crypt_mode->aead_mac :
1000 #endif
1001 (struct dropbear_hash*)s2c_hash_algo->data;
1002 ses.newkeys->recv.algo_comp = c2s_comp_algo->val;
1003 ses.newkeys->trans.algo_comp = s2c_comp_algo->val;
1004 }
1005
1006 #if DROPBEAR_FUZZ
1007 if (fuzz.fuzzing) {
1008 fuzz_kex_fakealgos();
1009 }
1010 #endif
1011
1012 /* reserved for future extensions */
1013 buf_getint(ses.payload);
1014
1015 if (ses.send_kex_first_guess && allgood) {
1016 TRACE(("our_first_follows_matches 1"))
1017 ses.kexstate.our_first_follows_matches = 1;
1018 }
1019 return;
1020
1021 error:
1022 dropbear_exit("No matching algo %s", erralgo);
1023 }
1024