Coverage Report

Created: 2023-03-06 09:27

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