Coverage Report

Created: 2025-08-09 07:10

/src/dropbear/src/common-kex.c
Line
Count
Source (jump to first uncovered line)
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 "ssh.h"
33
#include "packet.h"
34
#include "bignum.h"
35
#include "dbrandom.h"
36
#include "runopts.h"
37
38
static void kexinitialise(void);
39
static void gen_new_keys(void);
40
#ifndef DISABLE_ZLIB
41
static void gen_new_zstream_recv(void);
42
static void gen_new_zstream_trans(void);
43
#endif
44
static void read_kex_algos(void);
45
/* helper function for gen_new_keys */
46
static void hashkeys(unsigned char *out, unsigned int outlen, 
47
    const hash_state * hs, const unsigned char X);
48
49
50
/* Send our list of algorithms we can use */
51
0
void send_msg_kexinit() {
52
53
0
  CHECKCLEARTOWRITE();
54
0
  buf_putbyte(ses.writepayload, SSH_MSG_KEXINIT);
55
56
  /* cookie */
57
0
  genrandom(buf_getwriteptr(ses.writepayload, 16), 16);
58
0
  buf_incrwritepos(ses.writepayload, 16);
59
60
  /* kex algos */
61
0
  buf_put_algolist(ses.writepayload, sshkex);
62
63
  /* server_host_key_algorithms */
64
0
  buf_put_algolist(ses.writepayload, sigalgs);
65
66
  /* encryption_algorithms_client_to_server */
67
0
  buf_put_algolist(ses.writepayload, sshciphers);
68
69
  /* encryption_algorithms_server_to_client */
70
0
  buf_put_algolist(ses.writepayload, sshciphers);
71
72
  /* mac_algorithms_client_to_server */
73
0
  buf_put_algolist(ses.writepayload, sshhashes);
74
75
  /* mac_algorithms_server_to_client */
76
0
  buf_put_algolist(ses.writepayload, sshhashes);
77
78
79
  /* compression_algorithms_client_to_server */
80
0
  buf_put_algolist(ses.writepayload, ses.compress_algos_c2s);
81
82
  /* compression_algorithms_server_to_client */
83
0
  buf_put_algolist(ses.writepayload, ses.compress_algos_s2c);
84
85
  /* languages_client_to_server */
86
0
  buf_putstring(ses.writepayload, "", 0);
87
88
  /* languages_server_to_client */
89
0
  buf_putstring(ses.writepayload, "", 0);
90
91
  /* first_kex_packet_follows */
92
0
  buf_putbyte(ses.writepayload, (ses.send_kex_first_guess != NULL));
93
94
  /* reserved unit32 */
95
0
  buf_putint(ses.writepayload, 0);
96
97
  /* set up transmitted kex packet buffer for hashing. 
98
   * This is freed after the end of the kex */
99
0
  ses.transkexinit = buf_newcopy(ses.writepayload);
100
101
0
  encrypt_packet();
102
0
  ses.dataallowed = 0; /* don't send other packets during kex */
103
104
0
  ses.kexstate.sentkexinit = 1;
105
106
0
  ses.newkeys = (struct key_context*)m_malloc(sizeof(struct key_context));
107
108
0
  if (ses.send_kex_first_guess) {
109
0
    ses.newkeys->algo_kex = first_usable_algo(sshkex)->data;
110
0
    ses.newkeys->algo_signature = first_usable_algo(sigalgs)->val;
111
0
    ses.newkeys->algo_hostkey = signkey_type_from_signature(ses.newkeys->algo_signature);
112
0
    ses.send_kex_first_guess();
113
0
  }
114
115
0
  TRACE(("DATAALLOWED=0"))
116
0
  TRACE(("-> KEXINIT"))
117
118
0
}
119
120
0
static void switch_keys() {
121
0
  TRACE2(("enter switch_keys"))
122
0
  if (!(ses.kexstate.sentkexinit && ses.kexstate.recvkexinit)) {
123
0
    dropbear_exit("Unexpected newkeys message");
124
0
  }
125
126
0
  if (!ses.keys) {
127
0
    ses.keys = m_malloc(sizeof(*ses.newkeys));
128
0
  }
129
0
  if (ses.kexstate.recvnewkeys && ses.newkeys->recv.valid) {
130
0
    TRACE(("switch_keys recv"))
131
#ifndef DISABLE_ZLIB
132
    gen_new_zstream_recv();
133
#endif
134
0
    ses.keys->recv = ses.newkeys->recv;
135
0
    m_burn(&ses.newkeys->recv, sizeof(ses.newkeys->recv));
136
0
    ses.newkeys->recv.valid = 0;
137
0
  }
138
0
  if (ses.kexstate.sentnewkeys && ses.newkeys->trans.valid) {
139
0
    TRACE(("switch_keys trans"))
140
#ifndef DISABLE_ZLIB
141
    gen_new_zstream_trans();
142
#endif
143
0
    ses.keys->trans = ses.newkeys->trans;
144
0
    m_burn(&ses.newkeys->trans, sizeof(ses.newkeys->trans));
145
0
    ses.newkeys->trans.valid = 0;
146
0
  }
147
0
  if (ses.kexstate.sentnewkeys && ses.kexstate.recvnewkeys)
148
0
  {
149
0
    TRACE(("switch_keys done"))
150
0
    ses.keys->algo_kex = ses.newkeys->algo_kex;
151
0
    ses.keys->algo_hostkey = ses.newkeys->algo_hostkey;
152
0
    ses.keys->algo_signature = ses.newkeys->algo_signature;
153
0
    ses.keys->allow_compress = 0;
154
0
    m_free(ses.newkeys);
155
0
    ses.newkeys = NULL;
156
0
    kexinitialise();
157
0
  }
158
0
  TRACE2(("leave switch_keys"))
159
0
}
160
161
/* Bring new keys into use after a key exchange, and let the client know*/
162
0
void send_msg_newkeys() {
163
164
0
  TRACE(("enter send_msg_newkeys"))
165
166
  /* generate the kexinit request */
167
0
  CHECKCLEARTOWRITE();
168
0
  buf_putbyte(ses.writepayload, SSH_MSG_NEWKEYS);
169
0
  encrypt_packet();
170
171
  
172
  /* set up our state */
173
0
  ses.kexstate.sentnewkeys = 1;
174
0
  if (ses.kexstate.donefirstkex) {
175
0
    ses.kexstate.donesecondkex = 1;
176
0
  }
177
0
  ses.kexstate.donefirstkex = 1;
178
0
  ses.dataallowed = 1; /* we can send other packets again now */
179
0
  gen_new_keys();
180
0
  switch_keys();
181
182
0
  if (ses.kexstate.strict_kex) {
183
0
    ses.transseq = 0;
184
0
  }
185
186
0
  TRACE(("leave send_msg_newkeys"))
187
0
}
188
189
/* Bring the new keys into use after a key exchange */
190
0
void recv_msg_newkeys() {
191
192
0
  TRACE(("enter recv_msg_newkeys"))
193
194
0
  ses.kexstate.recvnewkeys = 1;
195
0
  switch_keys();
196
197
0
  if (ses.kexstate.strict_kex) {
198
0
    ses.recvseq = 0;
199
0
  }
200
0
  ses.kexstate.recvfirstnewkeys = 1;
201
202
0
  TRACE(("leave recv_msg_newkeys"))
203
0
}
204
205
0
static void kex_setup_compress(void) {
206
0
#ifdef DISABLE_ZLIB
207
0
  ses.compress_algos_c2s = ssh_nocompress;
208
0
  ses.compress_algos_s2c = ssh_nocompress;
209
#else
210
211
  if (!opts.allow_compress) {
212
    ses.compress_algos_c2s = ssh_nocompress;
213
    ses.compress_algos_s2c = ssh_nocompress;
214
    return;
215
  }
216
217
  if (IS_DROPBEAR_CLIENT) {
218
    /* TODO: should c2s in dbclient be disabled?
219
     * Current Dropbear server disables it. Disabling it also
220
     * lets DROPBEAR_CLI_IMMEDIATE_AUTH work (see comment there) */
221
    ses.compress_algos_c2s = ssh_compress;
222
    ses.compress_algos_s2c = ssh_compress;
223
  } else {
224
    ses.compress_algos_c2s = ssh_nocompress;
225
    ses.compress_algos_s2c = ssh_compress;
226
  }
227
#endif
228
0
}
229
230
/* Set up the kex for the first time */
231
0
void kexfirstinitialise() {
232
0
  kex_setup_compress();
233
0
  kexinitialise();
234
0
}
235
236
/* Reset the kex state, ready for a new negotiation */
237
0
static void kexinitialise() {
238
239
0
  TRACE(("kexinitialise()"))
240
241
  /* sent/recv'd MSG_KEXINIT */
242
0
  ses.kexstate.sentkexinit = 0;
243
0
  ses.kexstate.recvkexinit = 0;
244
245
  /* sent/recv'd MSG_NEWKEYS */
246
0
  ses.kexstate.recvnewkeys = 0;
247
0
  ses.kexstate.sentnewkeys = 0;
248
249
  /* first_packet_follows */
250
0
  ses.kexstate.them_firstfollows = 0;
251
252
0
  ses.kexstate.datatrans = 0;
253
0
  ses.kexstate.datarecv = 0;
254
255
0
  ses.kexstate.our_first_follows_matches = 0;
256
257
0
  ses.kexstate.lastkextime = monotonic_now();
258
259
0
}
260
261
/* Helper function for gen_new_keys, creates a hash. It makes a copy of the
262
 * already initialised hash_state hs, which should already have processed
263
 * the dh_K and hash, since these are common. X is the letter 'A', 'B' etc.
264
 * out must have at least min(hash_size, outlen) bytes allocated.
265
 *
266
 * See Section 7.2 of rfc4253 (ssh transport) for details */
267
static void hashkeys(unsigned char *out, unsigned int outlen, 
268
0
    const hash_state * hs, const unsigned char X) {
269
270
0
  const struct ltc_hash_descriptor *hash_desc = ses.newkeys->algo_kex->hash_desc;
271
0
  hash_state hs2;
272
0
  unsigned int offset;
273
0
  unsigned char tmpout[MAX_HASH_SIZE];
274
275
0
  memcpy(&hs2, hs, sizeof(hash_state));
276
0
  hash_desc->process(&hs2, &X, 1);
277
0
  hash_desc->process(&hs2, ses.session_id->data, ses.session_id->len);
278
0
  hash_desc->done(&hs2, tmpout);
279
0
  memcpy(out, tmpout, MIN(hash_desc->hashsize, outlen));
280
0
  for (offset = hash_desc->hashsize; 
281
0
      offset < outlen; 
282
0
      offset += hash_desc->hashsize)
283
0
  {
284
    /* need to extend */
285
0
    memcpy(&hs2, hs, sizeof(hash_state));
286
0
    hash_desc->process(&hs2, out, offset);
287
0
    hash_desc->done(&hs2, tmpout);
288
0
    memcpy(&out[offset], tmpout, MIN(outlen - offset, hash_desc->hashsize));
289
0
  }
290
0
  m_burn(&hs2, sizeof(hash_state));
291
0
}
292
293
/* Generate the actual encryption/integrity keys, using the results of the
294
 * key exchange, as specified in section 7.2 of the transport rfc 4253.
295
 * This occurs after the DH key-exchange.
296
 *
297
 * ses.newkeys is the new set of keys which are generated, these are only
298
 * taken into use after both sides have sent a newkeys message */
299
300
0
static void gen_new_keys() {
301
302
0
  unsigned char C2S_IV[MAX_IV_LEN];
303
0
  unsigned char C2S_key[MAX_KEY_LEN];
304
0
  unsigned char S2C_IV[MAX_IV_LEN];
305
0
  unsigned char S2C_key[MAX_KEY_LEN];
306
  /* unsigned char key[MAX_KEY_LEN]; */
307
0
  unsigned char *trans_IV, *trans_key, *recv_IV, *recv_key;
308
309
0
  hash_state hs;
310
0
  const struct ltc_hash_descriptor *hash_desc = ses.newkeys->algo_kex->hash_desc;
311
0
  char mactransletter, macrecvletter; /* Client or server specific */
312
313
0
  TRACE(("enter gen_new_keys"))
314
  /* the dh_K and hash are the start of all hashes, we make use of that */
315
316
0
  hash_desc->init(&hs);
317
0
  if (ses.dh_K) {
318
0
    hash_process_mp(hash_desc, &hs, ses.dh_K);
319
0
    mp_clear(ses.dh_K);
320
0
    m_free(ses.dh_K);
321
0
  }
322
0
  if (ses.dh_K_bytes) {
323
0
      hash_desc->process(&hs, ses.dh_K_bytes->data, ses.dh_K_bytes->len);
324
0
    buf_burn_free(ses.dh_K_bytes);
325
0
    ses.dh_K_bytes = NULL;
326
0
  }
327
0
  hash_desc->process(&hs, ses.hash->data, ses.hash->len);
328
0
  buf_burn_free(ses.hash);
329
0
  ses.hash = NULL;
330
331
0
  if (IS_DROPBEAR_CLIENT) {
332
0
    trans_IV  = C2S_IV;
333
0
    recv_IV   = S2C_IV;
334
0
    trans_key = C2S_key;
335
0
    recv_key  = S2C_key;
336
0
    mactransletter = 'E';
337
0
    macrecvletter = 'F';
338
0
  } else {
339
0
    trans_IV  = S2C_IV;
340
0
    recv_IV   = C2S_IV;
341
0
    trans_key = S2C_key;
342
0
    recv_key  = C2S_key;
343
0
    mactransletter = 'F';
344
0
    macrecvletter = 'E';
345
0
  }
346
347
0
  hashkeys(C2S_IV, sizeof(C2S_IV), &hs, 'A');
348
0
  hashkeys(S2C_IV, sizeof(S2C_IV), &hs, 'B');
349
0
  hashkeys(C2S_key, sizeof(C2S_key), &hs, 'C');
350
0
  hashkeys(S2C_key, sizeof(S2C_key), &hs, 'D');
351
352
0
  if (ses.newkeys->recv.algo_crypt->cipherdesc != NULL) {
353
0
    int recv_cipher = -1;
354
0
    if (ses.newkeys->recv.algo_crypt->cipherdesc->name != NULL) {
355
0
      recv_cipher = find_cipher(ses.newkeys->recv.algo_crypt->cipherdesc->name);
356
0
      if (recv_cipher < 0) {
357
0
        dropbear_exit("Crypto error");
358
0
      }
359
0
    }
360
0
    if (ses.newkeys->recv.crypt_mode->start(recv_cipher, 
361
0
        recv_IV, recv_key, 
362
0
        ses.newkeys->recv.algo_crypt->keysize, 0, 
363
0
        &ses.newkeys->recv.cipher_state) != CRYPT_OK) {
364
0
      dropbear_exit("Crypto error");
365
0
    }
366
0
  }
367
368
0
  if (ses.newkeys->trans.algo_crypt->cipherdesc != NULL) {
369
0
    int trans_cipher = -1;
370
0
    if (ses.newkeys->trans.algo_crypt->cipherdesc->name != NULL) {
371
0
      trans_cipher = find_cipher(ses.newkeys->trans.algo_crypt->cipherdesc->name);
372
0
      if (trans_cipher < 0) {
373
0
        dropbear_exit("Crypto error");
374
0
      }
375
0
    }
376
0
    if (ses.newkeys->trans.crypt_mode->start(trans_cipher, 
377
0
        trans_IV, trans_key, 
378
0
        ses.newkeys->trans.algo_crypt->keysize, 0, 
379
0
        &ses.newkeys->trans.cipher_state) != CRYPT_OK) {
380
0
      dropbear_exit("Crypto error");
381
0
    }
382
0
  }
383
384
0
  if (ses.newkeys->trans.algo_mac->hash_desc != NULL) {
385
0
    hashkeys(ses.newkeys->trans.mackey, 
386
0
        ses.newkeys->trans.algo_mac->keysize, &hs, mactransletter);
387
0
    ses.newkeys->trans.hash_index = find_hash(ses.newkeys->trans.algo_mac->hash_desc->name);
388
0
  }
389
390
0
  if (ses.newkeys->recv.algo_mac->hash_desc != NULL) {
391
0
    hashkeys(ses.newkeys->recv.mackey, 
392
0
        ses.newkeys->recv.algo_mac->keysize, &hs, macrecvletter);
393
0
    ses.newkeys->recv.hash_index = find_hash(ses.newkeys->recv.algo_mac->hash_desc->name);
394
0
  }
395
396
  /* Ready to switch over */
397
0
  ses.newkeys->trans.valid = 1;
398
0
  ses.newkeys->recv.valid = 1;
399
400
0
  m_burn(C2S_IV, sizeof(C2S_IV));
401
0
  m_burn(C2S_key, sizeof(C2S_key));
402
0
  m_burn(S2C_IV, sizeof(S2C_IV));
403
0
  m_burn(S2C_key, sizeof(S2C_key));
404
0
  m_burn(&hs, sizeof(hash_state));
405
406
0
  TRACE(("leave gen_new_keys"))
407
0
}
408
409
#ifndef DISABLE_ZLIB
410
411
int is_compress_trans() {
412
  return ses.keys->trans.algo_comp == DROPBEAR_COMP_ZLIB
413
    || (ses.authstate.authdone
414
      && ses.keys->trans.algo_comp == DROPBEAR_COMP_ZLIB_DELAY);
415
}
416
417
int is_compress_recv() {
418
  return ses.keys->recv.algo_comp == DROPBEAR_COMP_ZLIB
419
    || (ses.authstate.authdone
420
      && ses.keys->recv.algo_comp == DROPBEAR_COMP_ZLIB_DELAY);
421
}
422
423
static void* dropbear_zalloc(void* UNUSED(opaque), uInt items, uInt size) {
424
  return m_calloc(items, size);
425
}
426
427
static void dropbear_zfree(void* UNUSED(opaque), void* ptr) {
428
  m_free(ptr);
429
}
430
431
/* Set up new zlib compression streams, close the old ones. Only
432
 * called from gen_new_keys() */
433
static void gen_new_zstream_recv() {
434
435
  /* create new zstreams */
436
  if (ses.newkeys->recv.algo_comp == DROPBEAR_COMP_ZLIB
437
      || ses.newkeys->recv.algo_comp == DROPBEAR_COMP_ZLIB_DELAY) {
438
    ses.newkeys->recv.zstream = (z_streamp)m_malloc(sizeof(z_stream));
439
    ses.newkeys->recv.zstream->zalloc = dropbear_zalloc;
440
    ses.newkeys->recv.zstream->zfree = dropbear_zfree;
441
    
442
    if (inflateInit(ses.newkeys->recv.zstream) != Z_OK) {
443
      dropbear_exit("zlib error");
444
    }
445
  } else {
446
    ses.newkeys->recv.zstream = NULL;
447
  }
448
  /* clean up old keys */
449
  if (ses.keys->recv.zstream != NULL) {
450
    if (inflateEnd(ses.keys->recv.zstream) == Z_STREAM_ERROR) {
451
      /* Z_DATA_ERROR is ok, just means that stream isn't ended */
452
      dropbear_exit("Crypto error");
453
    }
454
    m_free(ses.keys->recv.zstream);
455
  }
456
}
457
458
static void gen_new_zstream_trans() {
459
460
  if (ses.newkeys->trans.algo_comp == DROPBEAR_COMP_ZLIB
461
      || ses.newkeys->trans.algo_comp == DROPBEAR_COMP_ZLIB_DELAY) {
462
    ses.newkeys->trans.zstream = (z_streamp)m_malloc(sizeof(z_stream));
463
    ses.newkeys->trans.zstream->zalloc = dropbear_zalloc;
464
    ses.newkeys->trans.zstream->zfree = dropbear_zfree;
465
  
466
    if (deflateInit2(ses.newkeys->trans.zstream, Z_DEFAULT_COMPRESSION,
467
          Z_DEFLATED, DROPBEAR_ZLIB_WINDOW_BITS, 
468
          DROPBEAR_ZLIB_MEM_LEVEL, Z_DEFAULT_STRATEGY)
469
        != Z_OK) {
470
      dropbear_exit("zlib error");
471
    }
472
  } else {
473
    ses.newkeys->trans.zstream = NULL;
474
  }
475
476
  if (ses.keys->trans.zstream != NULL) {
477
    if (deflateEnd(ses.keys->trans.zstream) == Z_STREAM_ERROR) {
478
      /* Z_DATA_ERROR is ok, just means that stream isn't ended */
479
      dropbear_exit("Crypto error");
480
    }
481
    m_free(ses.keys->trans.zstream);
482
  }
483
}
484
#endif /* DISABLE_ZLIB */
485
486
487
/* Executed upon receiving a kexinit message from the client to initiate
488
 * key exchange. If we haven't already done so, we send the list of our
489
 * preferred algorithms. The client's requested algorithms are processed,
490
 * and we calculate the first portion of the key-exchange-hash for used
491
 * later in the key exchange. No response is sent, as the client should
492
 * initiate the diffie-hellman key exchange */
493
0
void recv_msg_kexinit() {
494
  
495
0
  unsigned int kexhashbuf_len = 0;
496
0
  unsigned int remote_ident_len = 0;
497
0
  unsigned int local_ident_len = 0;
498
499
0
  TRACE(("<- KEXINIT"))
500
0
  TRACE(("enter recv_msg_kexinit"))
501
  
502
0
  if (!ses.kexstate.sentkexinit) {
503
    /* we need to send a kex packet */
504
0
    send_msg_kexinit();
505
0
    TRACE(("continue recv_msg_kexinit: sent kexinit"))
506
0
  }
507
508
  /* "Once a party has sent a SSH_MSG_KEXINIT message ...
509
  further SSH_MSG_KEXINIT messages MUST NOT be sent" */
510
0
  if (ses.kexstate.recvkexinit) {
511
0
    dropbear_exit("Unexpected KEXINIT");
512
0
  }
513
514
  /* start the kex hash */
515
0
  local_ident_len = strlen(LOCAL_IDENT);
516
0
  remote_ident_len = strlen(ses.remoteident);
517
518
0
  kexhashbuf_len = local_ident_len + remote_ident_len
519
0
    + ses.transkexinit->len + ses.payload->len
520
0
    + KEXHASHBUF_MAX_INTS;
521
522
0
  ses.kexhashbuf = buf_new(kexhashbuf_len);
523
524
0
  if (IS_DROPBEAR_CLIENT) {
525
526
    /* read the peer's choice of algos */
527
0
    read_kex_algos();
528
529
    /* V_C, the client's version string (CR and NL excluded) */
530
0
    buf_putstring(ses.kexhashbuf, LOCAL_IDENT, local_ident_len);
531
    /* V_S, the server's version string (CR and NL excluded) */
532
0
    buf_putstring(ses.kexhashbuf, ses.remoteident, remote_ident_len);
533
534
    /* I_C, the payload of the client's SSH_MSG_KEXINIT */
535
0
    buf_putstring(ses.kexhashbuf,
536
0
      (const char*)ses.transkexinit->data, ses.transkexinit->len);
537
    /* I_S, the payload of the server's SSH_MSG_KEXINIT */
538
0
    buf_setpos(ses.payload, ses.payload_beginning);
539
0
    buf_putstring(ses.kexhashbuf,
540
0
      (const char*)buf_getptr(ses.payload, ses.payload->len-ses.payload->pos),
541
0
      ses.payload->len-ses.payload->pos);
542
0
    ses.requirenext = SSH_MSG_KEXDH_REPLY;
543
0
  } else {
544
    /* SERVER */
545
546
    /* read the peer's choice of algos */
547
0
    read_kex_algos();
548
    /* V_C, the client's version string (CR and NL excluded) */
549
0
    buf_putstring(ses.kexhashbuf, ses.remoteident, remote_ident_len);
550
    /* V_S, the server's version string (CR and NL excluded) */
551
0
    buf_putstring(ses.kexhashbuf, LOCAL_IDENT, local_ident_len);
552
553
    /* I_C, the payload of the client's SSH_MSG_KEXINIT */
554
0
    buf_setpos(ses.payload, ses.payload_beginning);
555
0
    buf_putstring(ses.kexhashbuf, 
556
0
      (const char*)buf_getptr(ses.payload, ses.payload->len-ses.payload->pos),
557
0
      ses.payload->len-ses.payload->pos);
558
559
    /* I_S, the payload of the server's SSH_MSG_KEXINIT */
560
0
    buf_putstring(ses.kexhashbuf,
561
0
      (const char*)ses.transkexinit->data, ses.transkexinit->len);
562
563
0
    ses.requirenext = SSH_MSG_KEXDH_INIT;
564
0
  }
565
566
0
  buf_free(ses.transkexinit);
567
0
  ses.transkexinit = NULL;
568
  /* the rest of ses.kexhashbuf will be done after DH exchange */
569
570
0
  ses.kexstate.recvkexinit = 1;
571
572
0
  if (ses.kexstate.strict_kex && !ses.kexstate.donefirstkex && ses.recvseq != 1) {
573
0
    dropbear_exit("First packet wasn't kexinit");
574
0
  }
575
576
0
  TRACE(("leave recv_msg_kexinit"))
577
0
}
578
579
580
183
void finish_kexhashbuf(void) {
581
183
  hash_state hs;
582
183
  const struct ltc_hash_descriptor *hash_desc = ses.newkeys->algo_kex->hash_desc;
583
584
183
  hash_desc->init(&hs);
585
183
  buf_setpos(ses.kexhashbuf, 0);
586
183
  hash_desc->process(&hs, buf_getptr(ses.kexhashbuf, ses.kexhashbuf->len),
587
183
      ses.kexhashbuf->len);
588
183
  ses.hash = buf_new(hash_desc->hashsize);
589
183
  hash_desc->done(&hs, buf_getwriteptr(ses.hash, hash_desc->hashsize));
590
183
  buf_setlen(ses.hash, hash_desc->hashsize);
591
592
#if defined(DEBUG_KEXHASH) && DEBUG_TRACE
593
  if (!debug_trace) {
594
    printhex("kexhashbuf", ses.kexhashbuf->data, ses.kexhashbuf->len);
595
    printhex("kexhash", ses.hash->data, ses.hash->len);
596
  }
597
#endif
598
599
183
  buf_burn_free(ses.kexhashbuf);
600
183
  m_burn(&hs, sizeof(hash_state));
601
183
  ses.kexhashbuf = NULL;
602
  
603
  /* first time around, we set the session_id to H */
604
183
  if (ses.session_id == NULL) {
605
    /* create the session_id, this never needs freeing */
606
183
    ses.session_id = buf_newcopy(ses.hash);
607
183
  }
608
183
}
609
610
/* read the other side's algo list. buf_match_algo is a callback to match
611
 * algos for the client or server. */
612
0
static void read_kex_algos() {
613
614
  /* for asymmetry */
615
0
  algo_type * c2s_hash_algo = NULL;
616
0
  algo_type * s2c_hash_algo = NULL;
617
0
  algo_type * c2s_cipher_algo = NULL;
618
0
  algo_type * s2c_cipher_algo = NULL;
619
0
  algo_type * c2s_comp_algo = NULL;
620
0
  algo_type * s2c_comp_algo = NULL;
621
  /* the generic one */
622
0
  algo_type * algo = NULL;
623
624
  /* which algo couldn't match */
625
0
  char * erralgo = NULL;
626
627
0
  int goodguess = 0;
628
0
  int allgood = 1; /* we AND this with each goodguess and see if its still
629
            true after */
630
0
  int kexguess2 = 0;
631
632
0
  buf_incrpos(ses.payload, 16); /* start after the cookie */
633
634
0
  memset(ses.newkeys, 0x0, sizeof(*ses.newkeys));
635
636
  /* kex_algorithms */
637
0
#if DROPBEAR_KEXGUESS2
638
0
  if (buf_has_algo(ses.payload, KEXGUESS2_ALGO_NAME) == DROPBEAR_SUCCESS) {
639
0
    kexguess2 = 1;
640
0
  }
641
0
#endif
642
643
0
#if DROPBEAR_EXT_INFO
644
  /* Determine if SSH_MSG_EXT_INFO messages should be sent.
645
  Should be done for the first key exchange. Only required on server side
646
    for server-sig-algs */
647
0
  if (IS_DROPBEAR_SERVER) {
648
0
    if (!ses.kexstate.donefirstkex) {
649
0
      if (buf_has_algo(ses.payload, SSH_EXT_INFO_C) == DROPBEAR_SUCCESS) {
650
0
        ses.allow_ext_info = 1;
651
0
      }
652
0
    }
653
0
  }
654
0
#endif
655
656
0
  if (!ses.kexstate.donefirstkex) {
657
0
    const char* strict_name;
658
0
    if (IS_DROPBEAR_CLIENT) {
659
0
      strict_name = SSH_STRICT_KEX_S;
660
0
    } else {
661
0
      strict_name = SSH_STRICT_KEX_C;
662
0
    }
663
0
    if (buf_has_algo(ses.payload, strict_name) == DROPBEAR_SUCCESS) {
664
0
      ses.kexstate.strict_kex = 1;
665
0
    }
666
0
  }
667
668
0
  algo = buf_match_algo(ses.payload, sshkex, kexguess2, &goodguess);
669
0
  allgood &= goodguess;
670
0
  if (algo == NULL || algo->data == NULL) {
671
    /* kexguess2, ext-info-c, ext-info-s should not match negotiation */
672
0
    erralgo = "kex";
673
0
    goto error;
674
0
  }
675
0
  TRACE(("kexguess2 %d", kexguess2))
676
0
  DEBUG3(("kex algo %s", algo->name))
677
0
  ses.newkeys->algo_kex = algo->data;
678
679
  /* server_host_key_algorithms */
680
0
  algo = buf_match_algo(ses.payload, sigalgs, kexguess2, &goodguess);
681
0
  allgood &= goodguess;
682
0
  if (algo == NULL) {
683
0
    erralgo = "hostkey";
684
0
    goto error;
685
0
  }
686
0
  DEBUG2(("hostkey algo %s", algo->name))
687
0
  ses.newkeys->algo_signature = algo->val;
688
0
  ses.newkeys->algo_hostkey = signkey_type_from_signature(ses.newkeys->algo_signature);
689
690
  /* encryption_algorithms_client_to_server */
691
0
  c2s_cipher_algo = buf_match_algo(ses.payload, sshciphers, 0, NULL);
692
0
  if (c2s_cipher_algo == NULL) {
693
0
    erralgo = "enc c->s";
694
0
    goto error;
695
0
  }
696
0
  DEBUG2(("enc  c2s is %s", c2s_cipher_algo->name))
697
698
  /* encryption_algorithms_server_to_client */
699
0
  s2c_cipher_algo = buf_match_algo(ses.payload, sshciphers, 0, NULL);
700
0
  if (s2c_cipher_algo == NULL) {
701
0
    erralgo = "enc s->c";
702
0
    goto error;
703
0
  }
704
0
  DEBUG2(("enc  s2c is %s", s2c_cipher_algo->name))
705
706
  /* mac_algorithms_client_to_server */
707
0
  c2s_hash_algo = buf_match_algo(ses.payload, sshhashes, 0, NULL);
708
0
#if DROPBEAR_AEAD_MODE
709
0
  if (((struct dropbear_cipher_mode*)c2s_cipher_algo->mode)->aead_crypt != NULL) {
710
0
    c2s_hash_algo = NULL;
711
0
  } else
712
0
#endif
713
0
  if (c2s_hash_algo == NULL) {
714
0
    erralgo = "mac c->s";
715
0
    goto error;
716
0
  }
717
0
  DEBUG2(("hmac c2s is %s", c2s_hash_algo ? c2s_hash_algo->name : "<implicit>"))
718
719
  /* mac_algorithms_server_to_client */
720
0
  s2c_hash_algo = buf_match_algo(ses.payload, sshhashes, 0, NULL);
721
0
#if DROPBEAR_AEAD_MODE
722
0
  if (((struct dropbear_cipher_mode*)s2c_cipher_algo->mode)->aead_crypt != NULL) {
723
0
    s2c_hash_algo = NULL;
724
0
  } else
725
0
#endif
726
0
  if (s2c_hash_algo == NULL) {
727
0
    erralgo = "mac s->c";
728
0
    goto error;
729
0
  }
730
0
  DEBUG2(("hmac s2c is %s", s2c_hash_algo ? s2c_hash_algo->name : "<implicit>"))
731
732
  /* compression_algorithms_client_to_server */
733
0
  c2s_comp_algo = buf_match_algo(ses.payload, ses.compress_algos_c2s, 0, NULL);
734
0
  if (c2s_comp_algo == NULL) {
735
0
    erralgo = "comp c->s";
736
0
    goto error;
737
0
  }
738
0
  DEBUG2(("comp c2s is %s", c2s_comp_algo->name))
739
740
  /* compression_algorithms_server_to_client */
741
0
  s2c_comp_algo = buf_match_algo(ses.payload, ses.compress_algos_s2c, 0, NULL);
742
0
  if (s2c_comp_algo == NULL) {
743
0
    erralgo = "comp s->c";
744
0
    goto error;
745
0
  }
746
0
  DEBUG2(("comp s2c is %s", s2c_comp_algo->name))
747
748
  /* languages_client_to_server */
749
0
  buf_eatstring(ses.payload);
750
751
  /* languages_server_to_client */
752
0
  buf_eatstring(ses.payload);
753
754
  /* their first_kex_packet_follows */
755
0
  if (buf_getbool(ses.payload)) {
756
0
    TRACE(("them kex firstfollows. allgood %d", allgood))
757
0
    ses.kexstate.them_firstfollows = 1;
758
    /* if the guess wasn't good, we ignore the packet sent */
759
0
    if (!allgood) {
760
0
      ses.ignorenext = 1;
761
0
    }
762
0
  }
763
764
  /* Handle the asymmetry */
765
0
  if (IS_DROPBEAR_CLIENT) {
766
0
    ses.newkeys->recv.algo_crypt = 
767
0
      (struct dropbear_cipher*)s2c_cipher_algo->data;
768
0
    ses.newkeys->trans.algo_crypt = 
769
0
      (struct dropbear_cipher*)c2s_cipher_algo->data;
770
0
    ses.newkeys->recv.crypt_mode = 
771
0
      (struct dropbear_cipher_mode*)s2c_cipher_algo->mode;
772
0
    ses.newkeys->trans.crypt_mode =
773
0
      (struct dropbear_cipher_mode*)c2s_cipher_algo->mode;
774
0
    ses.newkeys->recv.algo_mac = 
775
0
#if DROPBEAR_AEAD_MODE
776
0
      s2c_hash_algo == NULL ? ses.newkeys->recv.crypt_mode->aead_mac :
777
0
#endif
778
0
      (struct dropbear_hash*)s2c_hash_algo->data;
779
0
    ses.newkeys->trans.algo_mac = 
780
0
#if DROPBEAR_AEAD_MODE
781
0
      c2s_hash_algo == NULL ? ses.newkeys->trans.crypt_mode->aead_mac :
782
0
#endif
783
0
      (struct dropbear_hash*)c2s_hash_algo->data;
784
0
    ses.newkeys->recv.algo_comp = s2c_comp_algo->val;
785
0
    ses.newkeys->trans.algo_comp = c2s_comp_algo->val;
786
0
  } else {
787
    /* SERVER */
788
0
    ses.newkeys->recv.algo_crypt = 
789
0
      (struct dropbear_cipher*)c2s_cipher_algo->data;
790
0
    ses.newkeys->trans.algo_crypt = 
791
0
      (struct dropbear_cipher*)s2c_cipher_algo->data;
792
0
    ses.newkeys->recv.crypt_mode =
793
0
      (struct dropbear_cipher_mode*)c2s_cipher_algo->mode;
794
0
    ses.newkeys->trans.crypt_mode =
795
0
      (struct dropbear_cipher_mode*)s2c_cipher_algo->mode;
796
0
    ses.newkeys->recv.algo_mac = 
797
0
#if DROPBEAR_AEAD_MODE
798
0
      c2s_hash_algo == NULL ? ses.newkeys->recv.crypt_mode->aead_mac :
799
0
#endif
800
0
      (struct dropbear_hash*)c2s_hash_algo->data;
801
0
    ses.newkeys->trans.algo_mac = 
802
0
#if DROPBEAR_AEAD_MODE
803
0
      s2c_hash_algo == NULL ? ses.newkeys->trans.crypt_mode->aead_mac :
804
0
#endif
805
0
      (struct dropbear_hash*)s2c_hash_algo->data;
806
0
    ses.newkeys->recv.algo_comp = c2s_comp_algo->val;
807
0
    ses.newkeys->trans.algo_comp = s2c_comp_algo->val;
808
0
  }
809
810
0
#if DROPBEAR_FUZZ
811
0
  if (fuzz.fuzzing) {
812
0
    fuzz_kex_fakealgos();
813
0
  }
814
0
#endif
815
816
  /* reserved for future extensions */
817
0
  buf_getint(ses.payload);
818
819
0
  if (ses.send_kex_first_guess && allgood) {
820
0
    TRACE(("our_first_follows_matches 1"))
821
0
    ses.kexstate.our_first_follows_matches = 1;
822
0
  }
823
0
  return;
824
825
0
error:
826
0
  dropbear_exit("No matching algo %s", erralgo);
827
0
}