Coverage Report

Created: 2026-07-15 06:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libssh/src/kex.c
Line
Count
Source
1
/*
2
 * kex.c - key exchange
3
 *
4
 * This file is part of the SSH Library
5
 *
6
 * Copyright (c) 2003-2008 by Aris Adamantiadis
7
 *
8
 * The SSH Library is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation; either version 2.1 of the License, or (at your
11
 * option) any later version.
12
 *
13
 * The SSH Library is distributed in the hope that it will be useful, but
14
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16
 * License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with the SSH Library; see the file COPYING.  If not, write to
20
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21
 * MA 02111-1307, USA.
22
 */
23
24
#include "config.h"
25
26
#include <string.h>
27
#include <stdlib.h>
28
#include <stdio.h>
29
#include <stdbool.h>
30
31
#include "libssh/libssh.h"
32
#include "libssh/priv.h"
33
#include "libssh/buffer.h"
34
#include "libssh/dh.h"
35
#ifdef WITH_GEX
36
#include "libssh/dh-gex.h"
37
#endif /* WITH_GEX */
38
#include "libssh/kex.h"
39
#include "libssh/session.h"
40
#include "libssh/ssh2.h"
41
#include "libssh/string.h"
42
#include "libssh/curve25519.h"
43
#include "libssh/sntrup761.h"
44
#include "libssh/hybrid_mlkem.h"
45
#include "libssh/kex-gss.h"
46
#include "libssh/knownhosts.h"
47
#include "libssh/misc.h"
48
#include "libssh/pki.h"
49
#include "libssh/bignum.h"
50
#include "libssh/token.h"
51
#include "libssh/gssapi.h"
52
53
#ifdef HAVE_BLOWFISH
54
# define BLOWFISH ",blowfish-cbc"
55
#else
56
# define BLOWFISH ""
57
#endif
58
59
#ifdef HAVE_LIBGCRYPT
60
# define AES "aes256-gcm@openssh.com,aes128-gcm@openssh.com," \
61
             "aes256-ctr,aes192-ctr,aes128-ctr"
62
# define AES_CBC ",aes256-cbc,aes192-cbc,aes128-cbc"
63
# define DES_SUPPORTED ",3des-cbc"
64
65
#elif defined(HAVE_LIBMBEDCRYPTO)
66
# ifdef MBEDTLS_GCM_C
67
#  define GCM "aes256-gcm@openssh.com,aes128-gcm@openssh.com,"
68
# else
69
#  define GCM ""
70
# endif /* MBEDTLS_GCM_C */
71
# define AES GCM "aes256-ctr,aes192-ctr,aes128-ctr"
72
# define AES_CBC ",aes256-cbc,aes192-cbc,aes128-cbc"
73
# define DES_SUPPORTED ",3des-cbc"
74
75
#elif defined(HAVE_LIBCRYPTO)
76
# ifdef HAVE_OPENSSL_AES_H
77
#  define GCM "aes256-gcm@openssh.com,aes128-gcm@openssh.com,"
78
#  define AES GCM "aes256-ctr,aes192-ctr,aes128-ctr"
79
#  define AES_CBC ",aes256-cbc,aes192-cbc,aes128-cbc"
80
# else /* HAVE_OPENSSL_AES_H */
81
#  define AES ""
82
#  define AES_CBC ""
83
# endif /* HAVE_OPENSSL_AES_H */
84
85
# define DES_SUPPORTED ",3des-cbc"
86
#endif /* HAVE_LIBCRYPTO */
87
88
#ifdef WITH_ZLIB
89
#define ZLIB "none,zlib@openssh.com,zlib"
90
#define ZLIB_DEFAULT "none,zlib@openssh.com"
91
#else
92
#define ZLIB "none"
93
#define ZLIB_DEFAULT "none"
94
#endif /* WITH_ZLIB */
95
96
#ifdef HAVE_CURVE25519
97
#define CURVE25519 "curve25519-sha256,curve25519-sha256@libssh.org,"
98
#else
99
#define CURVE25519 ""
100
#endif /* HAVE_CURVE25519 */
101
102
#ifdef HAVE_SNTRUP761
103
#define SNTRUP761X25519 "sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com,"
104
#else
105
#define SNTRUP761X25519 ""
106
#endif /* HAVE_SNTRUP761 */
107
108
#ifdef HAVE_MLKEM1024
109
#define HYBRID_MLKEM "mlkem768x25519-sha256," \
110
                     "mlkem768nistp256-sha256," \
111
                     "mlkem1024nistp384-sha384,"
112
#else
113
#define HYBRID_MLKEM "mlkem768x25519-sha256," \
114
                     "mlkem768nistp256-sha256,"
115
#endif /* HAVE_MLKEM1024 */
116
117
#ifdef HAVE_ECC
118
#define ECDH "ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,"
119
#define EC_HOSTKEYS "ecdsa-sha2-nistp521," \
120
                    "ecdsa-sha2-nistp384," \
121
                    "ecdsa-sha2-nistp256,"
122
#define EC_SK_HOSTKEYS "sk-ecdsa-sha2-nistp256@openssh.com,"
123
#define EC_FIPS_PUBLIC_KEY_ALGOS "ecdsa-sha2-nistp521-cert-v01@openssh.com," \
124
                                 "ecdsa-sha2-nistp384-cert-v01@openssh.com," \
125
                                 "ecdsa-sha2-nistp256-cert-v01@openssh.com,"
126
#define EC_PUBLIC_KEY_ALGORITHMS EC_FIPS_PUBLIC_KEY_ALGOS \
127
                                 "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,"
128
#else
129
#define ECDH ""
130
#define EC_HOSTKEYS ""
131
#define EC_SK_HOSTKEYS ""
132
#define EC_FIPS_PUBLIC_KEY_ALGOS ""
133
#define EC_PUBLIC_KEY_ALGORITHMS ""
134
#endif /* HAVE_ECC */
135
136
#ifdef WITH_INSECURE_NONE
137
#define NONE ",none"
138
#else
139
#define NONE
140
#endif /* WITH_INSECURE_NONE */
141
142
4.74k
#define HOSTKEYS "ssh-ed25519," \
143
4.74k
                 EC_HOSTKEYS \
144
4.74k
                 "sk-ssh-ed25519@openssh.com," \
145
4.74k
                 EC_SK_HOSTKEYS \
146
4.74k
                 "rsa-sha2-512," \
147
4.74k
                 "rsa-sha2-256," \
148
4.74k
                 "ssh-rsa"
149
#define DEFAULT_HOSTKEYS "ssh-ed25519," \
150
                         EC_HOSTKEYS \
151
                         "sk-ssh-ed25519@openssh.com," \
152
                         EC_SK_HOSTKEYS \
153
                         "rsa-sha2-512," \
154
                         "rsa-sha2-256"
155
156
#define PUBLIC_KEY_ALGORITHMS "ssh-ed25519-cert-v01@openssh.com," \
157
                              "sk-ssh-ed25519-cert-v01@openssh.com," \
158
                              EC_PUBLIC_KEY_ALGORITHMS \
159
                              "rsa-sha2-512-cert-v01@openssh.com," \
160
                              "rsa-sha2-256-cert-v01@openssh.com," \
161
                              "ssh-rsa-cert-v01@openssh.com," \
162
                              HOSTKEYS
163
#define DEFAULT_PUBLIC_KEY_ALGORITHMS "ssh-ed25519-cert-v01@openssh.com," \
164
                                      EC_PUBLIC_KEY_ALGORITHMS \
165
                                      "rsa-sha2-512-cert-v01@openssh.com," \
166
                                      "rsa-sha2-256-cert-v01@openssh.com," \
167
                                      DEFAULT_HOSTKEYS
168
169
#ifdef WITH_GEX
170
#define GEX_SHA256 "diffie-hellman-group-exchange-sha256,"
171
#define GEX_SHA1 "diffie-hellman-group-exchange-sha1,"
172
#else
173
#define GEX_SHA256
174
#define GEX_SHA1
175
#endif /* WITH_GEX */
176
177
#define CHACHA20 "chacha20-poly1305@openssh.com,"
178
179
#define DEFAULT_KEY_EXCHANGE \
180
    HYBRID_MLKEM \
181
    SNTRUP761X25519 \
182
    CURVE25519 \
183
    ECDH \
184
    "diffie-hellman-group18-sha512,diffie-hellman-group16-sha512," \
185
    GEX_SHA256 \
186
    "diffie-hellman-group14-sha256" \
187
188
#define KEY_EXCHANGE_SUPPORTED \
189
    GEX_SHA1 \
190
    DEFAULT_KEY_EXCHANGE \
191
    ",diffie-hellman-group14-sha1,diffie-hellman-group1-sha1"
192
193
/* RFC 8308 */
194
22.7k
#define KEX_EXTENSION_CLIENT "ext-info-c"
195
/* Strict kex mitigation against CVE-2023-48795 */
196
19.0k
#define KEX_STRICT_CLIENT "kex-strict-c-v00@openssh.com"
197
33.4k
#define KEX_STRICT_SERVER "kex-strict-s-v00@openssh.com"
198
199
/* Allowed algorithms in FIPS mode */
200
#define FIPS_ALLOWED_CIPHERS "aes256-gcm@openssh.com,"\
201
                             "aes256-ctr,"\
202
                             "aes256-cbc,"\
203
                             "aes128-gcm@openssh.com,"\
204
                             "aes128-ctr,"\
205
                             "aes128-cbc"
206
207
#define FIPS_ALLOWED_HOSTKEYS EC_HOSTKEYS \
208
                              "rsa-sha2-512," \
209
                              "rsa-sha2-256"
210
211
#define FIPS_ALLOWED_PUBLIC_KEY_ALGORITHMS EC_FIPS_PUBLIC_KEY_ALGOS \
212
                                           "rsa-sha2-512-cert-v01@openssh.com," \
213
                                           "rsa-sha2-256-cert-v01@openssh.com," \
214
                                           FIPS_ALLOWED_HOSTKEYS
215
216
#ifdef HAVE_MLKEM1024
217
#define FIPS_MLKEM_KEX "mlkem768nistp256-sha256," \
218
                       "mlkem1024nistp384-sha384,"
219
#else
220
#define FIPS_MLKEM_KEX "mlkem768nistp256-sha256,"
221
#endif
222
223
#define FIPS_ALLOWED_KEX FIPS_MLKEM_KEX \
224
                         "ecdh-sha2-nistp256,"\
225
                         "ecdh-sha2-nistp384,"\
226
                         "ecdh-sha2-nistp521,"\
227
                         "diffie-hellman-group-exchange-sha256,"\
228
                         "diffie-hellman-group14-sha256,"\
229
                         "diffie-hellman-group16-sha512,"\
230
                         "diffie-hellman-group18-sha512"
231
232
#define FIPS_ALLOWED_MACS "hmac-sha2-256-etm@openssh.com,"\
233
                          "hmac-sha1-etm@openssh.com,"\
234
                          "hmac-sha2-512-etm@openssh.com,"\
235
                          "hmac-sha2-256,"\
236
                          "hmac-sha1,"\
237
                          "hmac-sha2-512"
238
239
/* NOTE: This is a fixed API and the index is defined by ssh_kex_types_e */
240
static const char *fips_methods[] = {
241
    FIPS_ALLOWED_KEX,
242
    FIPS_ALLOWED_PUBLIC_KEY_ALGORITHMS,
243
    FIPS_ALLOWED_CIPHERS,
244
    FIPS_ALLOWED_CIPHERS,
245
    FIPS_ALLOWED_MACS,
246
    FIPS_ALLOWED_MACS,
247
    ZLIB_DEFAULT,
248
    ZLIB_DEFAULT,
249
    "",
250
    "",
251
    NULL
252
};
253
254
/* NOTE: This is a fixed API and the index is defined by ssh_kex_types_e */
255
static const char *default_methods[] = {
256
    DEFAULT_KEY_EXCHANGE,
257
    DEFAULT_PUBLIC_KEY_ALGORITHMS,
258
    CHACHA20 AES,
259
    CHACHA20 AES,
260
    "hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha2-512",
261
    "hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha2-256,hmac-sha2-512",
262
    ZLIB_DEFAULT,
263
    ZLIB_DEFAULT,
264
    "",
265
    "",
266
    NULL
267
};
268
269
/* NOTE: This is a fixed API and the index is defined by ssh_kex_types_e */
270
static const char *supported_methods[] = {
271
  KEY_EXCHANGE_SUPPORTED,
272
  PUBLIC_KEY_ALGORITHMS,
273
  CHACHA20 AES AES_CBC BLOWFISH DES_SUPPORTED NONE,
274
  CHACHA20 AES AES_CBC BLOWFISH DES_SUPPORTED NONE,
275
  "hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1" NONE,
276
  "hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1" NONE,
277
  ZLIB,
278
  ZLIB,
279
  "",
280
  "",
281
  NULL
282
};
283
284
/* descriptions of the key exchange packet */
285
static const char *ssh_kex_descriptions[] = {
286
  "kex algos",
287
  "server host key algo",
288
  "encryption client->server",
289
  "encryption server->client",
290
  "mac algo client->server",
291
  "mac algo server->client",
292
  "compression algo client->server",
293
  "compression algo server->client",
294
  "languages client->server",
295
  "languages server->client",
296
  NULL
297
};
298
299
const char *ssh_kex_get_default_methods(enum ssh_kex_types_e type)
300
67.0k
{
301
67.0k
    if (type >= SSH_KEX_METHODS) {
302
0
        return NULL;
303
0
    }
304
305
67.0k
    return default_methods[type];
306
67.0k
}
307
const char *ssh_kex_get_supported_method(enum ssh_kex_types_e type)
308
0
{
309
0
    if (type >= SSH_KEX_METHODS) {
310
0
        return NULL;
311
0
    }
312
313
0
    return supported_methods[type];
314
0
}
315
316
const char *ssh_kex_get_description(enum ssh_kex_types_e type)
317
603
{
318
603
    if (type >= SSH_KEX_METHODS) {
319
0
        return NULL;
320
0
    }
321
322
603
    return ssh_kex_descriptions[type];
323
603
}
324
325
const char *ssh_kex_get_fips_methods(enum ssh_kex_types_e type)
326
0
{
327
0
    if (type >= SSH_KEX_METHODS) {
328
0
        return NULL;
329
0
    }
330
331
0
    return fips_methods[type];
332
0
}
333
334
/**
335
 * @brief Get a list of supported algorithms of a given type. This respects the
336
 * FIPS mode status.
337
 *
338
 * @param[in] type The type of the algorithm to query (SSH_KEX, SSH_MAC_C_S,
339
 * ...).
340
 *
341
 * @return The list of supported methods as comma-separated string, or NULL for
342
 * unknown type.
343
 */
344
const char *ssh_get_supported_methods(enum ssh_kex_types_e type)
345
0
{
346
0
    if (ssh_fips_mode()) {
347
0
        return ssh_kex_get_fips_methods(type);
348
0
    } else {
349
0
        return ssh_kex_get_supported_method(type);
350
0
    }
351
0
}
352
353
/**
354
 * @internal
355
 * @brief returns whether the first client key exchange algorithm or
356
 *        hostkey type matches its server counterpart
357
 * @returns whether the first client key exchange algorithm or hostkey type
358
 *          matches its server counterpart
359
 */
360
static int cmp_first_kex_algo(const char *client_str,
361
2.12k
                              const char *server_str) {
362
2.12k
    size_t client_kex_len;
363
2.12k
    size_t server_kex_len;
364
365
2.12k
    const char *colon = NULL;
366
367
2.12k
    int is_wrong = 1;
368
369
2.12k
    if (client_str == NULL || server_str == NULL) {
370
0
        return is_wrong;
371
0
    }
372
373
2.12k
    colon = strchr(client_str, ',');
374
2.12k
    if (colon == NULL) {
375
189
        client_kex_len = strlen(client_str);
376
1.94k
    } else {
377
1.94k
        client_kex_len = colon - client_str;
378
1.94k
    }
379
380
2.12k
    colon = strchr(server_str, ',');
381
2.12k
    if (colon == NULL) {
382
282
        server_kex_len = strlen(server_str);
383
1.84k
    } else {
384
1.84k
        server_kex_len = colon - server_str;
385
1.84k
    }
386
387
2.12k
    if (client_kex_len != server_kex_len) {
388
1.88k
        return is_wrong;
389
1.88k
    }
390
391
245
    is_wrong = (strncmp(client_str, server_str, client_kex_len) != 0);
392
393
245
    return is_wrong;
394
2.12k
}
395
396
SSH_PACKET_CALLBACK(ssh_packet_kexinit)
397
13.4k
{
398
13.4k
    int i, ok;
399
13.4k
    struct ssh_crypto_struct *crypto = session->next_crypto;
400
13.4k
    int server_kex = session->server;
401
13.4k
    ssh_string str = NULL;
402
13.4k
    char *strings[SSH_KEX_METHODS] = {0};
403
13.4k
    int rc = SSH_ERROR;
404
13.4k
    size_t len;
405
406
13.4k
    uint8_t first_kex_packet_follows = 0;
407
13.4k
    uint32_t kexinit_reserved = 0;
408
409
13.4k
    (void)type;
410
13.4k
    (void)user;
411
412
13.4k
    SSH_LOG(SSH_LOG_TRACE, "KEXINIT received");
413
414
13.4k
    if (session->session_state == SSH_SESSION_STATE_AUTHENTICATED) {
415
238
        if (session->dh_handshake_state == DH_STATE_FINISHED) {
416
238
            SSH_LOG(SSH_LOG_DEBUG, "Peer initiated key re-exchange");
417
            /* Reset the sent flag if the re-kex was initiated by the peer */
418
238
            session->flags &= ~SSH_SESSION_FLAG_KEXINIT_SENT;
419
238
        } else if (session->flags & SSH_SESSION_FLAG_KEXINIT_SENT &&
420
0
                   session->dh_handshake_state == DH_STATE_INIT_SENT) {
421
            /* This happens only when we are sending our-guessed first kex
422
             * packet right after our KEXINIT packet. */
423
0
            SSH_LOG(SSH_LOG_DEBUG, "Received peer kexinit answer.");
424
0
        } else if (session->session_state != SSH_SESSION_STATE_INITIAL_KEX) {
425
0
            ssh_set_error(session, SSH_FATAL,
426
0
                          "SSH_KEXINIT received in wrong state");
427
0
            goto error;
428
0
        }
429
13.2k
    } else if (session->session_state != SSH_SESSION_STATE_INITIAL_KEX) {
430
0
        ssh_set_error(session, SSH_FATAL,
431
0
                      "SSH_KEXINIT received in wrong state");
432
0
        goto error;
433
0
    }
434
435
13.4k
    if (server_kex) {
436
9.67k
#ifdef WITH_SERVER
437
9.67k
        len = ssh_buffer_get_data(packet, crypto->client_kex.cookie, 16);
438
9.67k
        if (len != 16) {
439
6
            ssh_set_error(session, SSH_FATAL,
440
6
                          "ssh_packet_kexinit: no cookie in packet");
441
6
            goto error;
442
6
        }
443
444
9.67k
        ok = ssh_hashbufin_add_cookie(session, crypto->client_kex.cookie);
445
9.67k
        if (ok < 0) {
446
0
            ssh_set_error(session, SSH_FATAL,
447
0
                          "ssh_packet_kexinit: adding cookie failed");
448
0
            goto error;
449
0
        }
450
451
9.67k
        ok = server_set_kex(session);
452
9.67k
        if (ok == SSH_ERROR) {
453
0
            goto error;
454
0
        }
455
9.67k
#endif /* WITH_SERVER */
456
9.67k
    } else {
457
3.82k
        len = ssh_buffer_get_data(packet, crypto->server_kex.cookie, 16);
458
3.82k
        if (len != 16) {
459
6
            ssh_set_error(session, SSH_FATAL,
460
6
                          "ssh_packet_kexinit: no cookie in packet");
461
6
            goto error;
462
6
        }
463
464
3.81k
        ok = ssh_hashbufin_add_cookie(session, crypto->server_kex.cookie);
465
3.81k
        if (ok < 0) {
466
0
            ssh_set_error(session, SSH_FATAL,
467
0
                          "ssh_packet_kexinit: adding cookie failed");
468
0
            goto error;
469
0
        }
470
471
3.81k
        ok = ssh_set_client_kex(session);
472
3.81k
        if (ok == SSH_ERROR) {
473
0
            goto error;
474
0
        }
475
3.81k
    }
476
477
147k
    for (i = 0; i < SSH_KEX_METHODS; i++) {
478
133k
        str = ssh_buffer_get_ssh_string(packet);
479
133k
        if (str == NULL) {
480
169
          goto error;
481
169
        }
482
483
133k
        rc = ssh_buffer_add_ssh_string(session->in_hashbuf, str);
484
133k
        if (rc < 0) {
485
0
            ssh_set_error(session, SSH_FATAL,
486
0
                          "Error adding string in hash buffer");
487
0
            goto error;
488
0
        }
489
490
133k
        strings[i] = ssh_string_to_char(str);
491
133k
        if (strings[i] == NULL) {
492
0
            ssh_set_error_oom(session);
493
0
            goto error;
494
0
        }
495
133k
        SSH_STRING_FREE(str);
496
133k
        str = NULL;
497
133k
    }
498
499
    /* copy the peer kex info into an array of strings */
500
13.3k
    if (server_kex) {
501
9.58k
#ifdef WITH_SERVER
502
105k
        for (i = 0; i < SSH_KEX_METHODS; i++) {
503
95.8k
            crypto->client_kex.methods[i] = strings[i];
504
95.8k
        }
505
9.58k
#endif /* WITH_SERVER */
506
9.58k
    } else { /* client */
507
40.9k
        for (i = 0; i < SSH_KEX_METHODS; i++) {
508
37.2k
            crypto->server_kex.methods[i] = strings[i];
509
37.2k
        }
510
3.72k
    }
511
512
    /*
513
     * Handle the two final fields for the KEXINIT message (RFC 4253 7.1):
514
     *
515
     *      boolean      first_kex_packet_follows
516
     *      uint32       0 (reserved for future extension)
517
     *
518
     * Notably if clients set 'first_kex_packet_follows', it is expected
519
     * that its value is included when computing the session ID (see
520
     * 'make_sessionid').
521
     */
522
523
13.3k
    rc = ssh_buffer_get_u8(packet, &first_kex_packet_follows);
524
13.3k
    if (rc != 1) {
525
7
        goto error;
526
7
    }
527
528
13.3k
    rc = ssh_buffer_add_u8(session->in_hashbuf, first_kex_packet_follows);
529
13.3k
    if (rc < 0) {
530
0
        goto error;
531
0
    }
532
533
13.3k
    rc = ssh_buffer_add_u32(session->in_hashbuf, kexinit_reserved);
534
13.3k
    if (rc < 0) {
535
0
        goto error;
536
0
    }
537
538
    /*
539
     * Remember whether 'first_kex_packet_follows' was set and the client
540
     * guess was wrong: in this case the next SSH_MSG_KEXDH_INIT message
541
     * must be ignored on the server side.
542
     * Client needs to start the Key exchange over with the correct method
543
     */
544
13.3k
    if (first_kex_packet_follows || session->send_first_kex_follows) {
545
2.11k
        char **client_methods = crypto->client_kex.methods;
546
2.11k
        char **server_methods = crypto->server_kex.methods;
547
2.11k
        session->first_kex_follows_guess_wrong =
548
2.11k
            cmp_first_kex_algo(client_methods[SSH_KEX],
549
2.11k
                               server_methods[SSH_KEX]) ||
550
14
            cmp_first_kex_algo(client_methods[SSH_HOSTKEYS],
551
14
                               server_methods[SSH_HOSTKEYS]);
552
2.11k
            SSH_LOG(SSH_LOG_DEBUG, "The initial guess was %s.",
553
2.11k
                    session->first_kex_follows_guess_wrong ? "wrong" : "right");
554
2.11k
    }
555
556
    /*
557
     * handle the "strict KEX" feature. If supported by peer, then set up the
558
     * flag and verify packet sequence numbers.
559
     */
560
13.3k
    if (server_kex) {
561
9.58k
        ok = match_group(crypto->client_kex.methods[SSH_KEX],
562
9.58k
                         KEX_STRICT_CLIENT);
563
9.58k
        if (ok) {
564
677
            SSH_LOG(SSH_LOG_DEBUG, "Client supports strict kex, enabling.");
565
677
            session->flags |= SSH_SESSION_FLAG_KEX_STRICT;
566
677
        }
567
9.58k
    } else {
568
        /* client kex */
569
3.72k
        ok = match_group(crypto->server_kex.methods[SSH_KEX],
570
3.72k
                         KEX_STRICT_SERVER);
571
3.72k
        if (ok) {
572
381
            SSH_LOG(SSH_LOG_DEBUG, "Server supports strict kex, enabling.");
573
381
            session->flags |= SSH_SESSION_FLAG_KEX_STRICT;
574
381
        }
575
3.72k
    }
576
13.3k
#ifdef WITH_SERVER
577
13.3k
    if (server_kex) {
578
        /*
579
         * If client sent a ext-info-c message in the kex list, it supports
580
         * RFC 8308 extension negotiation.
581
         */
582
9.58k
        ok = match_group(crypto->client_kex.methods[SSH_KEX],
583
9.58k
                         KEX_EXTENSION_CLIENT);
584
9.58k
        if (ok) {
585
740
            const char *hostkeys = NULL, *wanted_hostkeys = NULL;
586
587
            /* The client supports extension negotiation */
588
740
            session->extensions |= SSH_EXT_NEGOTIATION;
589
            /*
590
             * RFC 8332 Section 3.1: Use for Server Authentication
591
             * Check what algorithms were provided in the SSH_HOSTKEYS list
592
             * by the client and enable the respective extensions to provide
593
             * correct signature in the next packet if RSA is negotiated
594
             */
595
740
            hostkeys = crypto->client_kex.methods[SSH_HOSTKEYS];
596
740
            wanted_hostkeys = session->opts.wanted_methods[SSH_HOSTKEYS];
597
740
            ok = match_group(hostkeys, "rsa-sha2-512");
598
740
            if (ok) {
599
                /* Check if rsa-sha2-512 is allowed by config */
600
608
                if (wanted_hostkeys != NULL) {
601
608
                    char *is_allowed = ssh_find_matching(wanted_hostkeys,
602
608
                                                         "rsa-sha2-512");
603
608
                    if (is_allowed != NULL) {
604
339
                        session->extensions |= SSH_EXT_SIG_RSA_SHA512;
605
339
                    }
606
608
                    SAFE_FREE(is_allowed);
607
608
                }
608
608
            }
609
740
            ok = match_group(hostkeys, "rsa-sha2-256");
610
740
            if (ok) {
611
                /* Check if rsa-sha2-256 is allowed by config */
612
463
                if (wanted_hostkeys != NULL) {
613
463
                    char *is_allowed = ssh_find_matching(wanted_hostkeys,
614
463
                                                         "rsa-sha2-256");
615
463
                    if (is_allowed != NULL) {
616
194
                        session->extensions |= SSH_EXT_SIG_RSA_SHA256;
617
194
                    }
618
463
                    SAFE_FREE(is_allowed);
619
463
                }
620
463
            }
621
622
            /*
623
             * Ensure that the client preference is honored for the case
624
             * both signature types are enabled.
625
             */
626
740
            if ((session->extensions & SSH_EXT_SIG_RSA_SHA256) &&
627
196
                (session->extensions & SSH_EXT_SIG_RSA_SHA512)) {
628
106
                char *rsa_sig_ext = NULL;
629
106
                session->extensions &= ~(SSH_EXT_SIG_RSA_SHA256 | SSH_EXT_SIG_RSA_SHA512);
630
106
                rsa_sig_ext = ssh_find_matching("rsa-sha2-512,rsa-sha2-256",
631
106
                                                hostkeys);
632
106
                if (rsa_sig_ext == NULL) {
633
4
                    goto error; /* should never happen */
634
102
                } else if (strcmp(rsa_sig_ext, "rsa-sha2-512") == 0) {
635
8
                    session->extensions |= SSH_EXT_SIG_RSA_SHA512;
636
94
                } else if (strcmp(rsa_sig_ext, "rsa-sha2-256") == 0) {
637
94
                    session->extensions |= SSH_EXT_SIG_RSA_SHA256;
638
94
                } else {
639
0
                    SAFE_FREE(rsa_sig_ext);
640
0
                    goto error; /* should never happen */
641
0
                }
642
102
                SAFE_FREE(rsa_sig_ext);
643
102
            }
644
645
736
            SSH_LOG(SSH_LOG_DEBUG, "The client supports extension "
646
736
                    "negotiation. Enabled signature algorithms: %s%s",
647
736
                    session->extensions & SSH_EXT_SIG_RSA_SHA256 ? "SHA256" : "",
648
736
                    session->extensions & SSH_EXT_SIG_RSA_SHA512 ? " SHA512" : "");
649
736
        }
650
9.58k
    }
651
13.3k
#endif /* WITH_SERVER */
652
653
    /* Note, that his overwrites authenticated state in case of rekeying */
654
13.3k
    session->session_state = SSH_SESSION_STATE_KEXINIT_RECEIVED;
655
    /* if we already sent our initial key exchange packet, do not reset the
656
     * DH state. We will know if we were right with our guess only in
657
     * dh_handshake_state() */
658
13.3k
    if (session->send_first_kex_follows == false) {
659
13.3k
        session->dh_handshake_state = DH_STATE_INIT;
660
13.3k
    }
661
13.3k
    session->ssh_connection_callback(session);
662
13.3k
    return SSH_PACKET_USED;
663
664
192
error:
665
192
    SSH_STRING_FREE(str);
666
2.11k
    for (i = 0; i < SSH_KEX_METHODS; i++) {
667
1.92k
        if (server_kex) {
668
930
#ifdef WITH_SERVER
669
930
            session->next_crypto->client_kex.methods[i] = NULL;
670
930
#endif /* WITH_SERVER */
671
990
        } else { /* client */
672
990
            session->next_crypto->server_kex.methods[i] = NULL;
673
990
        }
674
1.92k
        SAFE_FREE(strings[i]);
675
1.92k
    }
676
677
192
    session->session_state = SSH_SESSION_STATE_ERROR;
678
679
192
    return SSH_PACKET_USED;
680
13.3k
}
681
682
28.2k
void ssh_list_kex(struct ssh_kex_struct *kex) {
683
28.2k
  int i = 0;
684
685
#ifdef DEBUG_CRYPTO
686
  ssh_log_hexdump("session cookie", kex->cookie, 16);
687
#endif
688
689
310k
  for(i = 0; i < SSH_KEX_METHODS; i++) {
690
282k
    if (kex->methods[i] == NULL) {
691
0
      continue;
692
0
    }
693
282k
    SSH_LOG(SSH_LOG_FUNCTIONS, "%s: %s",
694
282k
        ssh_kex_descriptions[i], kex->methods[i]);
695
282k
  }
696
28.2k
}
697
698
/**
699
 * @internal
700
 *
701
 * @brief selects the hostkey mechanisms to be chosen for the key exchange,
702
 * as some hostkey mechanisms may be present in known_hosts files.
703
 *
704
 * @returns a cstring containing a comma-separated list of hostkey methods.
705
 *          NULL if no method matches
706
 */
707
char *ssh_client_select_hostkeys(ssh_session session)
708
4.74k
{
709
4.74k
    const char *wanted = NULL;
710
4.74k
    char *wanted_without_certs = NULL;
711
4.74k
    char *known_hosts_algorithms = NULL;
712
4.74k
    char *known_hosts_ordered = NULL;
713
4.74k
    char *new_hostkeys = NULL;
714
4.74k
    char *fips_hostkeys = NULL;
715
716
4.74k
    wanted = session->opts.wanted_methods[SSH_HOSTKEYS];
717
4.74k
    if (wanted == NULL) {
718
4.74k
        if (ssh_fips_mode()) {
719
0
            wanted = ssh_kex_get_fips_methods(SSH_HOSTKEYS);
720
4.74k
        } else {
721
4.74k
            wanted = ssh_kex_get_default_methods(SSH_HOSTKEYS);
722
4.74k
        }
723
4.74k
    }
724
725
    /* This removes the certificate types, unsupported for now */
726
4.74k
    wanted_without_certs = ssh_find_all_matching(HOSTKEYS, wanted);
727
4.74k
    if (wanted_without_certs == NULL) {
728
0
        SSH_LOG(SSH_LOG_TRACE,
729
0
                "List of allowed host key algorithms is empty or contains only "
730
0
                "unsupported algorithms");
731
0
        return NULL;
732
0
    }
733
734
4.74k
    SSH_LOG(SSH_LOG_DEBUG,
735
4.74k
            "Order of wanted host keys: \"%s\"",
736
4.74k
            wanted_without_certs);
737
738
4.74k
    known_hosts_algorithms = ssh_known_hosts_get_algorithms_names(session);
739
4.74k
    if (known_hosts_algorithms == NULL) {
740
4.74k
        SSH_LOG(SSH_LOG_DEBUG,
741
4.74k
                "No key found in known_hosts; "
742
4.74k
                "changing host key method to \"%s\"",
743
4.74k
                wanted_without_certs);
744
745
4.74k
        return wanted_without_certs;
746
4.74k
    }
747
748
0
    SSH_LOG(SSH_LOG_DEBUG,
749
0
            "Algorithms found in known_hosts files: \"%s\"",
750
0
            known_hosts_algorithms);
751
752
    /* Filter and order the keys from known_hosts according to wanted list */
753
0
    known_hosts_ordered = ssh_find_all_matching(known_hosts_algorithms,
754
0
                                                wanted_without_certs);
755
0
    SAFE_FREE(known_hosts_algorithms);
756
0
    if (known_hosts_ordered == NULL) {
757
0
        SSH_LOG(SSH_LOG_DEBUG,
758
0
                "No key found in known_hosts is allowed; "
759
0
                "changing host key method to \"%s\"",
760
0
                wanted_without_certs);
761
762
0
        return wanted_without_certs;
763
0
    }
764
765
    /* Append the other supported keys after the preferred ones
766
     * This function tolerates NULL pointers in parameters */
767
0
    new_hostkeys = ssh_append_without_duplicates(known_hosts_ordered,
768
0
                                                 wanted_without_certs);
769
0
    SAFE_FREE(known_hosts_ordered);
770
0
    SAFE_FREE(wanted_without_certs);
771
0
    if (new_hostkeys == NULL) {
772
0
        ssh_set_error_oom(session);
773
0
        return NULL;
774
0
    }
775
776
0
    if (ssh_fips_mode()) {
777
        /* Filter out algorithms not allowed in FIPS mode */
778
0
        fips_hostkeys = ssh_keep_fips_algos(SSH_HOSTKEYS, new_hostkeys);
779
0
        SAFE_FREE(new_hostkeys);
780
0
        if (fips_hostkeys == NULL) {
781
0
            SSH_LOG(SSH_LOG_TRACE,
782
0
                    "None of the wanted host keys or keys in known_hosts files "
783
0
                    "is allowed in FIPS mode.");
784
0
            return NULL;
785
0
        }
786
0
        new_hostkeys = fips_hostkeys;
787
0
    }
788
789
0
    SSH_LOG(SSH_LOG_DEBUG,
790
0
            "Changing host key method to \"%s\"",
791
0
            new_hostkeys);
792
793
0
    return new_hostkeys;
794
0
}
795
796
/**
797
 * @brief sets the key exchange parameters to be sent to the server,
798
 *        in function of the options and available methods.
799
 */
800
int ssh_set_client_kex(ssh_session session)
801
8.55k
{
802
8.55k
    struct ssh_kex_struct *client = &session->next_crypto->client_kex;
803
8.55k
    const char *wanted = NULL;
804
8.55k
    int ok;
805
8.55k
    int i;
806
8.55k
    bool gssapi_null_alg = false;
807
8.55k
    char *hostkeys = NULL;
808
809
    /* Skip if already set, for example for the rekey or when we do the guessing
810
     * it could have been already used to make some protocol decisions. */
811
8.55k
    if (client->methods[0] != NULL) {
812
3.81k
        return SSH_OK;
813
3.81k
    }
814
815
4.74k
    ok = ssh_get_random(client->cookie, 16, 0);
816
4.74k
    if (!ok) {
817
0
        ssh_set_error(session, SSH_FATAL, "PRNG error");
818
0
        return SSH_ERROR;
819
0
    }
820
#ifdef WITH_GSSAPI
821
    if (session->opts.gssapi_key_exchange) {
822
        char *gssapi_algs = NULL;
823
824
        ok = ssh_gssapi_init(session);
825
        if (ok != SSH_OK) {
826
            ssh_set_error_oom(session);
827
            return SSH_ERROR;
828
        }
829
830
        ok = ssh_gssapi_import_name(session->gssapi, session->opts.host);
831
        if (ok != SSH_OK) {
832
            return SSH_ERROR;
833
        }
834
835
        gssapi_algs = ssh_gssapi_kex_mechs(session);
836
        if (gssapi_algs == NULL) {
837
            return SSH_ERROR;
838
        }
839
840
        /* Prefix the default algorithms with gsskex algs */
841
        if (ssh_fips_mode()) {
842
            session->opts.wanted_methods[SSH_KEX] =
843
                ssh_prefix_without_duplicates(fips_methods[SSH_KEX],
844
                                              gssapi_algs);
845
        } else {
846
            session->opts.wanted_methods[SSH_KEX] =
847
                ssh_prefix_without_duplicates(default_methods[SSH_KEX],
848
                                              gssapi_algs);
849
        }
850
851
        gssapi_null_alg = true;
852
853
        SAFE_FREE(gssapi_algs);
854
    }
855
#endif
856
857
    /* Set the list of allowed algorithms in order of preference, if it hadn't
858
     * been set yet. */
859
52.1k
    for (i = 0; i < SSH_KEX_METHODS; i++) {
860
47.4k
        if (i == SSH_HOSTKEYS) {
861
            /* Set the hostkeys in the following order:
862
             * - First: keys present in known_hosts files ordered by preference
863
             * - Next: other wanted algorithms ordered by preference */
864
4.74k
            client->methods[i] = ssh_client_select_hostkeys(session);
865
4.74k
            if (client->methods[i] == NULL) {
866
0
                ssh_set_error_oom(session);
867
0
                return SSH_ERROR;
868
0
            }
869
4.74k
            if (gssapi_null_alg) {
870
0
                hostkeys =
871
0
                    ssh_append_without_duplicates(client->methods[i], "null");
872
0
                if (hostkeys == NULL) {
873
0
                    ssh_set_error_oom(session);
874
0
                    return SSH_ERROR;
875
0
                }
876
0
                SAFE_FREE(client->methods[i]);
877
0
                client->methods[i] = hostkeys;
878
0
            }
879
4.74k
            continue;
880
4.74k
        }
881
882
42.6k
        wanted = session->opts.wanted_methods[i];
883
42.6k
        if (wanted == NULL) {
884
23.7k
            if (ssh_fips_mode()) {
885
0
                wanted = fips_methods[i];
886
23.7k
            } else {
887
23.7k
                wanted = default_methods[i];
888
23.7k
            }
889
23.7k
        }
890
42.6k
        client->methods[i] = strdup(wanted);
891
42.6k
        if (client->methods[i] == NULL) {
892
0
            ssh_set_error_oom(session);
893
0
            return SSH_ERROR;
894
0
        }
895
42.6k
    }
896
897
    /* For rekeying, skip the extension negotiation */
898
4.74k
    if (session->flags & SSH_SESSION_FLAG_AUTHENTICATED) {
899
0
        return SSH_OK;
900
0
    }
901
902
4.74k
    ok = ssh_kex_append_extensions(session, client);
903
4.74k
    if (ok != SSH_OK){
904
0
        return ok;
905
0
    }
906
907
4.74k
    return SSH_OK;
908
4.74k
}
909
910
int ssh_kex_append_extensions(ssh_session session, struct ssh_kex_struct *pkex)
911
14.8k
{
912
14.8k
    char *kex = NULL;
913
14.8k
    char *kex_tmp = NULL;
914
14.8k
    size_t kex_len, len;
915
916
    /* Here we append ext-info-c and kex-strict-c-v00@openssh.com for client
917
     * and kex-strict-s-v00@openssh.com for server to the list of kex algorithms
918
     */
919
14.8k
    kex = pkex->methods[SSH_KEX];
920
14.8k
    len = strlen(kex);
921
14.8k
    if (session->server) {
922
        /* Comma, nul byte */
923
10.0k
        kex_len = len + 1 + strlen(KEX_STRICT_SERVER) + 1;
924
10.0k
    } else {
925
        /* Comma, comma, nul byte */
926
4.74k
        kex_len = len + 1 + strlen(KEX_EXTENSION_CLIENT) + 1 +
927
4.74k
                  strlen(KEX_STRICT_CLIENT) + 1;
928
4.74k
    }
929
14.8k
    if (kex_len >= MAX_PACKET_LEN) {
930
        /* Overflow */
931
0
        return SSH_ERROR;
932
0
    }
933
14.8k
    kex_tmp = realloc(kex, kex_len);
934
14.8k
    if (kex_tmp == NULL) {
935
0
        ssh_set_error_oom(session);
936
0
        return SSH_ERROR;
937
0
    }
938
14.8k
    if (session->server){
939
10.0k
        snprintf(kex_tmp + len, kex_len - len, ",%s", KEX_STRICT_SERVER);
940
10.0k
    } else {
941
4.74k
        snprintf(kex_tmp + len,
942
4.74k
                 kex_len - len,
943
4.74k
                 ",%s,%s",
944
4.74k
                 KEX_EXTENSION_CLIENT,
945
4.74k
                 KEX_STRICT_CLIENT);
946
4.74k
    }
947
14.8k
    pkex->methods[SSH_KEX] = kex_tmp;
948
14.8k
    return SSH_OK;
949
14.8k
}
950
951
static const char *ssh_find_aead_hmac(const char *cipher)
952
24.5k
{
953
24.5k
    if (cipher == NULL) {
954
0
        return NULL;
955
24.5k
    } else if (strcmp(cipher, "chacha20-poly1305@openssh.com") == 0) {
956
0
        return "aead-poly1305";
957
24.5k
    } else if (strcmp(cipher, "aes256-gcm@openssh.com") == 0) {
958
0
        return "aead-gcm";
959
24.5k
    } else if (strcmp(cipher, "aes128-gcm@openssh.com") == 0) {
960
0
        return "aead-gcm";
961
0
    }
962
24.5k
    return NULL;
963
24.5k
}
964
965
static enum ssh_key_exchange_e
966
kex_select_kex_type(const char *kex)
967
12.2k
{
968
12.2k
    if (strcmp(kex, "diffie-hellman-group1-sha1") == 0) {
969
0
        return SSH_KEX_DH_GROUP1_SHA1;
970
12.2k
    } else if (strncmp(kex, "gss-group14-sha256-", 19) == 0) {
971
0
        return SSH_GSS_KEX_DH_GROUP14_SHA256;
972
12.2k
    } else if (strncmp(kex, "gss-group16-sha512-", 19) == 0) {
973
0
        return SSH_GSS_KEX_DH_GROUP16_SHA512;
974
12.2k
    } else if (strncmp(kex, "gss-nistp256-sha256-", 20) == 0) {
975
0
        return SSH_GSS_KEX_ECDH_NISTP256_SHA256;
976
12.2k
    } else if (strncmp(kex, "gss-curve25519-sha256-", 22) == 0) {
977
0
        return SSH_GSS_KEX_CURVE25519_SHA256;
978
12.2k
    } else if (strcmp(kex, "diffie-hellman-group14-sha1") == 0) {
979
0
        return SSH_KEX_DH_GROUP14_SHA1;
980
12.2k
    } else if (strcmp(kex, "diffie-hellman-group14-sha256") == 0) {
981
770
        return SSH_KEX_DH_GROUP14_SHA256;
982
11.4k
    } else if (strcmp(kex, "diffie-hellman-group16-sha512") == 0) {
983
104
        return SSH_KEX_DH_GROUP16_SHA512;
984
11.3k
    } else if (strcmp(kex, "diffie-hellman-group18-sha512") == 0) {
985
268
        return SSH_KEX_DH_GROUP18_SHA512;
986
268
#ifdef WITH_GEX
987
11.1k
    } else if (strcmp(kex, "diffie-hellman-group-exchange-sha1") == 0) {
988
0
        return SSH_KEX_DH_GEX_SHA1;
989
11.1k
    } else if (strcmp(kex, "diffie-hellman-group-exchange-sha256") == 0) {
990
377
        return SSH_KEX_DH_GEX_SHA256;
991
377
#endif /* WITH_GEX */
992
10.7k
    } else if (strcmp(kex, "ecdh-sha2-nistp256") == 0) {
993
119
        return SSH_KEX_ECDH_SHA2_NISTP256;
994
10.6k
    } else if (strcmp(kex, "ecdh-sha2-nistp384") == 0) {
995
14
        return SSH_KEX_ECDH_SHA2_NISTP384;
996
10.6k
    } else if (strcmp(kex, "ecdh-sha2-nistp521") == 0) {
997
15
        return SSH_KEX_ECDH_SHA2_NISTP521;
998
10.6k
    } else if (strcmp(kex, "curve25519-sha256@libssh.org") == 0) {
999
439
        return SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG;
1000
10.1k
    } else if (strcmp(kex, "curve25519-sha256") == 0) {
1001
8.87k
        return SSH_KEX_CURVE25519_SHA256;
1002
8.87k
    } else if (strcmp(kex, "sntrup761x25519-sha512@openssh.com") == 0) {
1003
106
        return SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM;
1004
1.17k
    } else if (strcmp(kex, "sntrup761x25519-sha512") == 0) {
1005
256
        return SSH_KEX_SNTRUP761X25519_SHA512;
1006
923
    } else if (strcmp(kex, "mlkem768x25519-sha256") == 0) {
1007
616
        return SSH_KEX_MLKEM768X25519_SHA256;
1008
616
    } else if (strcmp(kex, "mlkem768nistp256-sha256") == 0) {
1009
307
        return SSH_KEX_MLKEM768NISTP256_SHA256;
1010
#ifdef HAVE_MLKEM1024
1011
    } else if (strcmp(kex, "mlkem1024nistp384-sha384") == 0) {
1012
        return SSH_KEX_MLKEM1024NISTP384_SHA384;
1013
#endif
1014
307
    }
1015
    /* should not happen. We should be getting only valid names at this stage */
1016
0
    return 0;
1017
12.2k
}
1018
1019
1020
/** @internal
1021
 * @brief Reverts guessed callbacks set during the dh_handshake()
1022
 * @param session session handle
1023
 * @returns void
1024
 */
1025
static void revert_kex_callbacks(ssh_session session)
1026
1.20k
{
1027
1.20k
    switch (session->next_crypto->kex_type) {
1028
0
    case SSH_KEX_DH_GROUP1_SHA1:
1029
0
    case SSH_KEX_DH_GROUP14_SHA1:
1030
0
    case SSH_KEX_DH_GROUP14_SHA256:
1031
0
    case SSH_KEX_DH_GROUP16_SHA512:
1032
0
    case SSH_KEX_DH_GROUP18_SHA512:
1033
0
        ssh_client_dh_remove_callbacks(session);
1034
0
        break;
1035
0
    case SSH_GSS_KEX_DH_GROUP14_SHA256:
1036
0
    case SSH_GSS_KEX_DH_GROUP16_SHA512:
1037
0
    case SSH_GSS_KEX_ECDH_NISTP256_SHA256:
1038
0
    case SSH_GSS_KEX_CURVE25519_SHA256:
1039
#ifdef WITH_GSSAPI
1040
        ssh_client_gss_kex_remove_callbacks(session);
1041
#endif /* WITH_GSSAPI */
1042
0
        break;
1043
0
#ifdef WITH_GEX
1044
0
    case SSH_KEX_DH_GEX_SHA1:
1045
0
    case SSH_KEX_DH_GEX_SHA256:
1046
0
        ssh_client_dhgex_remove_callbacks(session);
1047
0
        break;
1048
0
#endif /* WITH_GEX */
1049
0
#ifdef HAVE_ECDH
1050
0
    case SSH_KEX_ECDH_SHA2_NISTP256:
1051
0
    case SSH_KEX_ECDH_SHA2_NISTP384:
1052
0
    case SSH_KEX_ECDH_SHA2_NISTP521:
1053
0
        ssh_client_ecdh_remove_callbacks(session);
1054
0
        break;
1055
0
#endif
1056
0
#ifdef HAVE_CURVE25519
1057
0
    case SSH_KEX_CURVE25519_SHA256:
1058
0
    case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG:
1059
0
        ssh_client_curve25519_remove_callbacks(session);
1060
0
        break;
1061
0
#endif
1062
0
#ifdef HAVE_SNTRUP761
1063
0
    case SSH_KEX_SNTRUP761X25519_SHA512:
1064
0
    case SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM:
1065
0
        ssh_client_sntrup761x25519_remove_callbacks(session);
1066
0
        break;
1067
0
#endif
1068
0
    case SSH_KEX_MLKEM768X25519_SHA256:
1069
0
    case SSH_KEX_MLKEM768NISTP256_SHA256:
1070
#ifdef HAVE_MLKEM1024
1071
    case SSH_KEX_MLKEM1024NISTP384_SHA384:
1072
#endif
1073
0
        ssh_client_hybrid_mlkem_remove_callbacks(session);
1074
0
        break;
1075
1.20k
    }
1076
1.20k
}
1077
1078
/** @brief Select the different methods on basis of client's and
1079
 * server's kex messages, and watches out if a match is possible.
1080
 */
1081
int ssh_kex_select_methods (ssh_session session)
1082
13.3k
{
1083
13.3k
    struct ssh_crypto_struct *crypto = session->next_crypto;
1084
13.3k
    struct ssh_kex_struct *server = &crypto->server_kex;
1085
13.3k
    struct ssh_kex_struct *client = &crypto->client_kex;
1086
13.3k
    char *ext_start = NULL;
1087
13.3k
    const char *aead_hmac = NULL;
1088
13.3k
    enum ssh_key_exchange_e kex_type;
1089
13.3k
    int i;
1090
1091
    /* Here we should drop the extensions from the list so we avoid matching.
1092
     * it. We added it to the end, so we can just truncate the string here */
1093
13.3k
    if (session->client) {
1094
3.72k
        ext_start = strstr(client->methods[SSH_KEX], "," KEX_EXTENSION_CLIENT);
1095
3.72k
        if (ext_start != NULL) {
1096
3.72k
            ext_start[0] = '\0';
1097
3.72k
        }
1098
3.72k
    }
1099
13.3k
    if (session->server) {
1100
9.58k
        ext_start = strstr(server->methods[SSH_KEX], "," KEX_STRICT_SERVER);
1101
9.58k
        if (ext_start != NULL) {
1102
9.35k
            ext_start[0] = '\0';
1103
9.35k
        }
1104
9.58k
    }
1105
1106
136k
    for (i = 0; i < SSH_KEX_METHODS; i++) {
1107
123k
        crypto->kex_methods[i] = ssh_find_matching(server->methods[i],
1108
123k
                                                   client->methods[i]);
1109
1110
123k
        if (i == SSH_MAC_C_S || i == SSH_MAC_S_C) {
1111
24.5k
            aead_hmac = ssh_find_aead_hmac(crypto->kex_methods[i - 2]);
1112
24.5k
            if (aead_hmac) {
1113
0
                free(crypto->kex_methods[i]);
1114
0
                crypto->kex_methods[i] = strdup(aead_hmac);
1115
0
            }
1116
24.5k
        }
1117
123k
        if (crypto->kex_methods[i] == NULL && i < SSH_LANG_C_S) {
1118
1.03k
            ssh_set_error(session, SSH_FATAL,
1119
1.03k
                          "kex error : no match for method %s: server [%s], "
1120
1.03k
                          "client [%s]", ssh_kex_descriptions[i],
1121
1.03k
                          server->methods[i], client->methods[i]);
1122
1.03k
            return SSH_ERROR;
1123
122k
        } else if ((i >= SSH_LANG_C_S) && (crypto->kex_methods[i] == NULL)) {
1124
            /* we can safely do that for languages */
1125
4.30k
            crypto->kex_methods[i] = strdup("");
1126
4.30k
        }
1127
123k
    }
1128
1129
    /* We can not set this value directly as the old value is needed to revert
1130
     * callbacks if we are client */
1131
12.2k
    kex_type = kex_select_kex_type(crypto->kex_methods[SSH_KEX]);
1132
12.2k
    if (session->client && session->first_kex_follows_guess_wrong) {
1133
1.20k
        SSH_LOG(SSH_LOG_DEBUG, "Our guess was wrong. Restarting the KEX");
1134
        /* We need to remove the wrong callbacks and start kex again */
1135
1.20k
        revert_kex_callbacks(session);
1136
1.20k
        session->dh_handshake_state = DH_STATE_INIT;
1137
1.20k
        session->first_kex_follows_guess_wrong = false;
1138
1.20k
    }
1139
12.2k
    crypto->kex_type = kex_type;
1140
1141
12.2k
    SSH_LOG(SSH_LOG_DEBUG, "Negotiated %s,%s,%s,%s,%s,%s,%s,%s,%s,%s",
1142
12.2k
            session->next_crypto->kex_methods[SSH_KEX],
1143
12.2k
            session->next_crypto->kex_methods[SSH_HOSTKEYS],
1144
12.2k
            session->next_crypto->kex_methods[SSH_CRYPT_C_S],
1145
12.2k
            session->next_crypto->kex_methods[SSH_CRYPT_S_C],
1146
12.2k
            session->next_crypto->kex_methods[SSH_MAC_C_S],
1147
12.2k
            session->next_crypto->kex_methods[SSH_MAC_S_C],
1148
12.2k
            session->next_crypto->kex_methods[SSH_COMP_C_S],
1149
12.2k
            session->next_crypto->kex_methods[SSH_COMP_S_C],
1150
12.2k
            session->next_crypto->kex_methods[SSH_LANG_C_S],
1151
12.2k
            session->next_crypto->kex_methods[SSH_LANG_S_C]
1152
12.2k
    );
1153
12.2k
    return SSH_OK;
1154
13.3k
}
1155
1156
1157
/* this function only sends the predefined set of kex methods */
1158
int ssh_send_kex(ssh_session session)
1159
14.9k
{
1160
14.9k
    struct ssh_kex_struct *kex = (session->server ?
1161
10.2k
        &session->next_crypto->server_kex :
1162
14.9k
        &session->next_crypto->client_kex);
1163
14.9k
    ssh_string str = NULL;
1164
14.9k
    int i;
1165
14.9k
    int rc;
1166
14.9k
    int first_kex_packet_follows = 0;
1167
1168
    /* Only client can initiate the handshake methods we implement. If we
1169
     * already received the peer mechanisms, there is no point in guessing */
1170
14.9k
    if (session->client &&
1171
4.74k
        session->session_state != SSH_SESSION_STATE_KEXINIT_RECEIVED &&
1172
4.74k
        session->send_first_kex_follows) {
1173
0
        first_kex_packet_follows = 1;
1174
0
    }
1175
1176
14.9k
    SSH_LOG(SSH_LOG_TRACE,
1177
14.9k
            "Sending KEXINIT packet, first_kex_packet_follows = %d",
1178
14.9k
            first_kex_packet_follows);
1179
1180
14.9k
    rc = ssh_buffer_pack(session->out_buffer,
1181
14.9k
                         "bP",
1182
14.9k
                         SSH2_MSG_KEXINIT,
1183
14.9k
                         (size_t)16,
1184
14.9k
                         kex->cookie); /* cookie */
1185
14.9k
    if (rc != SSH_OK)
1186
0
        goto error;
1187
14.9k
    if (ssh_hashbufout_add_cookie(session) < 0) {
1188
0
        goto error;
1189
0
    }
1190
1191
14.9k
    ssh_list_kex(kex);
1192
1193
164k
    for (i = 0; i < SSH_KEX_METHODS; i++) {
1194
149k
        str = ssh_string_from_char(kex->methods[i]);
1195
149k
        if (str == NULL) {
1196
0
            goto error;
1197
0
        }
1198
1199
149k
        rc = ssh_buffer_add_ssh_string(session->out_hashbuf, str);
1200
149k
        if (rc < 0) {
1201
0
            goto error;
1202
0
        }
1203
149k
        rc = ssh_buffer_add_ssh_string(session->out_buffer, str);
1204
149k
        if (rc < 0) {
1205
0
            goto error;
1206
0
        }
1207
149k
        SSH_STRING_FREE(str);
1208
149k
        str = NULL;
1209
149k
    }
1210
1211
14.9k
    rc = ssh_buffer_pack(session->out_buffer,
1212
14.9k
                         "bd",
1213
14.9k
                         first_kex_packet_follows,
1214
14.9k
                         0);
1215
14.9k
    if (rc != SSH_OK) {
1216
0
        goto error;
1217
0
    }
1218
1219
    /* Prepare also the first_kex_packet_follows and reserved to 0 */
1220
14.9k
    rc = ssh_buffer_add_u8(session->out_hashbuf, first_kex_packet_follows);
1221
14.9k
    if (rc < 0) {
1222
0
        goto error;
1223
0
    }
1224
14.9k
    rc = ssh_buffer_add_u32(session->out_hashbuf, 0);
1225
14.9k
    if (rc < 0) {
1226
0
        goto error;
1227
0
    }
1228
1229
14.9k
    rc = ssh_packet_send(session);
1230
14.9k
    if (rc == SSH_ERROR) {
1231
0
        return -1;
1232
0
    }
1233
1234
14.9k
    session->flags |= SSH_SESSION_FLAG_KEXINIT_SENT;
1235
14.9k
    SSH_LOG(SSH_LOG_PACKET, "SSH_MSG_KEXINIT sent");
1236
1237
    /* If we indicated that we are sending the guessed key exchange packet,
1238
     * do it now. The packet is simple, but we need to do some preparations */
1239
14.9k
    if (first_kex_packet_follows == 1) {
1240
0
        char *list = kex->methods[SSH_KEX];
1241
0
        const char *colon = strchr(list, ',');
1242
0
        size_t kex_name_len = colon ? (size_t)(colon - list) : strlen(list);
1243
0
        char *kex_name = calloc(kex_name_len + 1, 1);
1244
0
        if (kex_name == NULL) {
1245
0
            ssh_set_error_oom(session);
1246
0
            goto error;
1247
0
        }
1248
0
        snprintf(kex_name, kex_name_len + 1, "%.*s", (int)kex_name_len, list);
1249
0
        SSH_LOG(SSH_LOG_TRACE, "Sending the first kex packet for %s", kex_name);
1250
1251
0
        session->next_crypto->kex_type = kex_select_kex_type(kex_name);
1252
0
        free(kex_name);
1253
1254
        /* run the first step of the DH handshake */
1255
0
        session->dh_handshake_state = DH_STATE_INIT;
1256
0
        if (dh_handshake(session) == SSH_ERROR) {
1257
0
            goto error;
1258
0
        }
1259
0
    }
1260
14.9k
    return 0;
1261
1262
0
error:
1263
0
    ssh_buffer_reinit(session->out_buffer);
1264
0
    ssh_buffer_reinit(session->out_hashbuf);
1265
0
    SSH_STRING_FREE(str);
1266
1267
0
    return -1;
1268
14.9k
}
1269
1270
/*
1271
 * Key re-exchange (rekey) is triggered by this function.
1272
 * It can not be called again after the rekey is initialized!
1273
 */
1274
int ssh_send_rekex(ssh_session session)
1275
0
{
1276
0
    int rc;
1277
1278
0
    if (session->dh_handshake_state != DH_STATE_FINISHED) {
1279
        /* Rekey/Key exchange is already in progress */
1280
0
        SSH_LOG(SSH_LOG_PACKET, "Attempting rekey in bad state");
1281
0
        return SSH_ERROR;
1282
0
    }
1283
1284
0
    if (session->current_crypto == NULL) {
1285
        /* No current crypto used -- can not exchange it */
1286
0
        SSH_LOG(SSH_LOG_PACKET, "No crypto to rekey");
1287
0
        return SSH_ERROR;
1288
0
    }
1289
1290
0
    if (session->client) {
1291
0
        rc = ssh_set_client_kex(session);
1292
0
        if (rc != SSH_OK) {
1293
0
            SSH_LOG(SSH_LOG_PACKET, "Failed to set client kex");
1294
0
            return rc;
1295
0
        }
1296
0
    } else {
1297
0
#ifdef WITH_SERVER
1298
0
        rc = server_set_kex(session);
1299
0
        if (rc == SSH_ERROR) {
1300
0
            SSH_LOG(SSH_LOG_PACKET, "Failed to set server kex");
1301
0
            return rc;
1302
0
        }
1303
#else
1304
        SSH_LOG(SSH_LOG_PACKET, "Invalid session state.");
1305
        return SSH_ERROR;
1306
#endif /* WITH_SERVER */
1307
0
    }
1308
1309
0
    session->dh_handshake_state = DH_STATE_INIT;
1310
0
    rc = ssh_send_kex(session);
1311
0
    if (rc < 0) {
1312
0
        SSH_LOG(SSH_LOG_PACKET, "Failed to send kex");
1313
0
        return rc;
1314
0
    }
1315
1316
    /* Reset the handshake state */
1317
0
    session->dh_handshake_state = DH_STATE_INIT_SENT;
1318
0
    return SSH_OK;
1319
0
}
1320
1321
/* returns a copy of the provided list if everything is supported,
1322
 * otherwise a new list of the supported algorithms */
1323
char *ssh_keep_known_algos(enum ssh_kex_types_e algo, const char *list)
1324
71.1k
{
1325
71.1k
    if (algo > SSH_LANG_S_C) {
1326
0
        return NULL;
1327
0
    }
1328
1329
71.1k
    return ssh_find_all_matching(supported_methods[algo], list);
1330
71.1k
}
1331
1332
/**
1333
 * @internal
1334
 *
1335
 * @brief Return a newly allocated string containing only the FIPS allowed
1336
 * algorithms from the list.
1337
 *
1338
 * @param[in] algo  The type of the methods to filter
1339
 * @param[in] list  The list to be filtered
1340
 *
1341
 * @return A newly allocated list containing only the FIPS allowed algorithms from
1342
 * the list; NULL in case of error.
1343
 */
1344
char *ssh_keep_fips_algos(enum ssh_kex_types_e algo, const char *list)
1345
0
{
1346
0
    if (algo > SSH_LANG_S_C) {
1347
0
        return NULL;
1348
0
    }
1349
1350
0
    return ssh_find_all_matching(fips_methods[algo], list);
1351
0
}
1352
1353
/**
1354
 * @internal
1355
 *
1356
 * @brief Return a newly allocated string containing the default
1357
 * algorithms plus the algorithms specified in list. If the system
1358
 * runs in fips mode, this will add only fips approved algorithms.
1359
 * Empty list will cause error.
1360
 *
1361
 * @param[in] algo  The type of the methods to filter
1362
 * @param[in] list  The list to be appended
1363
 *
1364
 * @return A newly allocated list containing the default algorithms and the
1365
 * algorithms in list at the end; NULL in case of error.
1366
 */
1367
char *ssh_add_to_default_algos(enum ssh_kex_types_e algo, const char *list)
1368
912
{
1369
912
    char *tmp = NULL, *ret = NULL;
1370
1371
912
    if (algo > SSH_LANG_S_C || list == NULL || list[0] == '\0') {
1372
15
        return NULL;
1373
15
    }
1374
1375
897
    if (ssh_fips_mode()) {
1376
0
        tmp = ssh_append_without_duplicates(fips_methods[algo], list);
1377
0
        ret = ssh_find_all_matching(fips_methods[algo], tmp);
1378
897
    } else {
1379
897
        tmp = ssh_append_without_duplicates(default_methods[algo], list);
1380
897
        ret = ssh_find_all_matching(supported_methods[algo], tmp);
1381
897
    }
1382
1383
897
    free(tmp);
1384
897
    return ret;
1385
912
}
1386
1387
/**
1388
 * @internal
1389
 *
1390
 * @brief Return a newly allocated string containing the default
1391
 * algorithms excluding the algorithms specified in list. If the system
1392
 * runs in fips mode, this will remove from the fips_methods list.
1393
 *
1394
 * @param[in] algo  The type of the methods to filter
1395
 * @param[in] list  The list to be exclude
1396
 *
1397
 * @return A newly allocated list containing the default algorithms without the
1398
 * algorithms in list; NULL in case of error.
1399
 */
1400
char *ssh_remove_from_default_algos(enum ssh_kex_types_e algo, const char *list)
1401
597
{
1402
597
    if (algo > SSH_LANG_S_C) {
1403
0
        return NULL;
1404
0
    }
1405
1406
597
    if (list == NULL || list[0] == '\0') {
1407
27
        if (ssh_fips_mode()) {
1408
0
            return strdup(fips_methods[algo]);
1409
27
        } else {
1410
27
            return strdup(default_methods[algo]);
1411
27
        }
1412
27
    }
1413
1414
570
    if (ssh_fips_mode()) {
1415
0
        return ssh_remove_all_matching(fips_methods[algo], list);
1416
570
    } else {
1417
570
        return ssh_remove_all_matching(default_methods[algo], list);
1418
570
    }
1419
570
}
1420
1421
/**
1422
 * @internal
1423
 *
1424
 * @brief Return a newly allocated string containing the default
1425
 * algorithms with prioritized algorithms specified in list. If the
1426
 * algorithms are present in the default list they get prioritized, if not
1427
 * they are added to the front of the default list. If the system
1428
 * runs in fips mode, this will work with the fips_methods list.
1429
 * Empty list will cause error.
1430
 *
1431
 * @param[in] algo  The type of the methods to filter
1432
 * @param[in] list  The list to be pushed to priority
1433
 *
1434
 * @return A newly allocated list containing the default algorithms prioritized
1435
 * with the algorithms in list at the beginning of the list; NULL in case
1436
 * of error.
1437
 */
1438
char *ssh_prefix_default_algos(enum ssh_kex_types_e algo, const char *list)
1439
376
{
1440
376
    char *ret = NULL, *tmp = NULL;
1441
1442
376
    if (algo > SSH_LANG_S_C || list == NULL || list[0] == '\0') {
1443
15
        return NULL;
1444
15
    }
1445
1446
361
    if (ssh_fips_mode()) {
1447
0
        tmp = ssh_prefix_without_duplicates(fips_methods[algo], list);
1448
0
        ret = ssh_find_all_matching(fips_methods[algo], tmp);
1449
361
    } else {
1450
361
        tmp = ssh_prefix_without_duplicates(default_methods[algo], list);
1451
361
        ret = ssh_find_all_matching(supported_methods[algo], tmp);
1452
361
    }
1453
1454
361
    free(tmp);
1455
361
    return ret;
1456
376
}
1457
1458
int ssh_make_sessionid(ssh_session session)
1459
10.3k
{
1460
10.3k
    ssh_string num = NULL;
1461
10.3k
    ssh_buffer server_hash = NULL;
1462
10.3k
    ssh_buffer client_hash = NULL;
1463
10.3k
    ssh_buffer buf = NULL;
1464
10.3k
    ssh_string server_pubkey_blob = NULL;
1465
10.3k
#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L
1466
10.3k
    const_bignum client_pubkey, server_pubkey;
1467
#else
1468
    bignum client_pubkey = NULL, server_pubkey = NULL;
1469
#endif /* OPENSSL_VERSION_NUMBER */
1470
10.3k
#ifdef WITH_GEX
1471
10.3k
#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L
1472
10.3k
    const_bignum modulus, generator;
1473
#else
1474
    bignum modulus = NULL, generator = NULL;
1475
#endif /* OPENSSL_VERSION_NUMBER */
1476
10.3k
#endif /* WITH_GEX */
1477
10.3k
    int rc = SSH_ERROR;
1478
1479
10.3k
    buf = ssh_buffer_new();
1480
10.3k
    if (buf == NULL) {
1481
0
        ssh_set_error_oom(session);
1482
0
        return rc;
1483
0
    }
1484
1485
10.3k
    rc = ssh_buffer_pack(buf,
1486
10.3k
                         "ss",
1487
10.3k
                         session->clientbanner,
1488
10.3k
                         session->serverbanner);
1489
10.3k
    if (rc == SSH_ERROR) {
1490
0
        ssh_set_error(session,
1491
0
                      SSH_FATAL,
1492
0
                      "Failed to pack client and server banner");
1493
0
        goto error;
1494
0
    }
1495
1496
10.3k
    if (session->client) {
1497
1.78k
        server_hash = session->in_hashbuf;
1498
1.78k
        client_hash = session->out_hashbuf;
1499
8.52k
    } else {
1500
8.52k
        server_hash = session->out_hashbuf;
1501
8.52k
        client_hash = session->in_hashbuf;
1502
8.52k
    }
1503
1504
10.3k
    rc = ssh_dh_get_next_server_publickey_blob(session, &server_pubkey_blob);
1505
10.3k
    if (rc != SSH_OK) {
1506
0
        ssh_set_error(session,
1507
0
                      SSH_FATAL,
1508
0
                      "Failed to get next server pubkey blob");
1509
0
        goto error;
1510
0
    }
1511
1512
10.3k
    if (server_pubkey_blob == NULL) {
1513
0
        if ((session->server && ssh_kex_is_gss(session->next_crypto)) ||
1514
0
            session->opts.gssapi_key_exchange) {
1515
0
            server_pubkey_blob = ssh_string_new(0);
1516
0
            if (server_pubkey_blob == NULL) {
1517
0
                ssh_set_error_oom(session);
1518
0
                rc = SSH_ERROR;
1519
0
                goto error;
1520
0
            }
1521
0
        }
1522
0
    }
1523
1524
10.3k
    rc = ssh_buffer_pack(buf,
1525
10.3k
                         "dPdPS",
1526
10.3k
                         ssh_buffer_get_len(client_hash),
1527
10.3k
                         (size_t)ssh_buffer_get_len(client_hash),
1528
10.3k
                         ssh_buffer_get(client_hash),
1529
10.3k
                         ssh_buffer_get_len(server_hash),
1530
10.3k
                         (size_t)ssh_buffer_get_len(server_hash),
1531
10.3k
                         ssh_buffer_get(server_hash),
1532
10.3k
                         server_pubkey_blob);
1533
10.3k
    SSH_STRING_FREE(server_pubkey_blob);
1534
10.3k
    if (rc != SSH_OK){
1535
0
        ssh_set_error(session,
1536
0
                      SSH_FATAL,
1537
0
                      "Failed to pack hashes and pubkey blob");
1538
0
        goto error;
1539
0
    }
1540
1541
10.3k
    switch(session->next_crypto->kex_type) {
1542
0
    case SSH_KEX_DH_GROUP1_SHA1:
1543
0
    case SSH_KEX_DH_GROUP14_SHA1:
1544
733
    case SSH_KEX_DH_GROUP14_SHA256:
1545
733
    case SSH_GSS_KEX_DH_GROUP14_SHA256:
1546
805
    case SSH_KEX_DH_GROUP16_SHA512:
1547
805
    case SSH_GSS_KEX_DH_GROUP16_SHA512:
1548
1.04k
    case SSH_KEX_DH_GROUP18_SHA512:
1549
1.04k
        rc = ssh_dh_keypair_get_keys(session->next_crypto->dh_ctx,
1550
1.04k
                                     DH_CLIENT_KEYPAIR, NULL, &client_pubkey);
1551
1.04k
        if (rc != SSH_OK) {
1552
0
            goto error;
1553
0
        }
1554
1.04k
        rc = ssh_dh_keypair_get_keys(session->next_crypto->dh_ctx,
1555
1.04k
                                     DH_SERVER_KEYPAIR, NULL, &server_pubkey);
1556
1.04k
        if (rc != SSH_OK) {
1557
0
            goto error;
1558
0
        }
1559
1.04k
        rc = ssh_buffer_pack(buf,
1560
1.04k
                             "BB",
1561
1.04k
                             client_pubkey,
1562
1.04k
                             server_pubkey);
1563
1.04k
        if (rc != SSH_OK) {
1564
0
            ssh_set_error(session, SSH_FATAL, "Failed to pack DH pubkeys");
1565
0
            goto error;
1566
0
        }
1567
#if defined(HAVE_LIBCRYPTO) && OPENSSL_VERSION_NUMBER >= 0x30000000L
1568
        bignum_safe_free(client_pubkey);
1569
        bignum_safe_free(server_pubkey);
1570
#endif /* OPENSSL_VERSION_NUMBER */
1571
1.04k
        break;
1572
1.04k
#ifdef WITH_GEX
1573
1.04k
    case SSH_KEX_DH_GEX_SHA1:
1574
18
    case SSH_KEX_DH_GEX_SHA256:
1575
18
        rc = ssh_dh_keypair_get_keys(session->next_crypto->dh_ctx,
1576
18
                                     DH_CLIENT_KEYPAIR, NULL, &client_pubkey);
1577
18
        if (rc != SSH_OK) {
1578
0
            goto error;
1579
0
        }
1580
18
        rc = ssh_dh_keypair_get_keys(session->next_crypto->dh_ctx,
1581
18
                                     DH_SERVER_KEYPAIR, NULL, &server_pubkey);
1582
18
        if (rc != SSH_OK) {
1583
0
            goto error;
1584
0
        }
1585
18
        rc = ssh_dh_get_parameters(session->next_crypto->dh_ctx,
1586
18
                                   &modulus, &generator);
1587
18
        if (rc != SSH_OK) {
1588
0
            goto error;
1589
0
        }
1590
18
        rc = ssh_buffer_pack(buf,
1591
18
                    "dddBBBB",
1592
18
                    session->next_crypto->dh_pmin,
1593
18
                    session->next_crypto->dh_pn,
1594
18
                    session->next_crypto->dh_pmax,
1595
18
                    modulus,
1596
18
                    generator,
1597
18
                    client_pubkey,
1598
18
                    server_pubkey);
1599
18
        if (rc != SSH_OK) {
1600
0
            ssh_set_error(session, SSH_FATAL, "Failed to pack DH GEX params");
1601
0
            goto error;
1602
0
        }
1603
#if defined(HAVE_LIBCRYPTO) && OPENSSL_VERSION_NUMBER >= 0x30000000L
1604
        bignum_safe_free(modulus);
1605
        bignum_safe_free(generator);
1606
#endif /* OPENSSL_VERSION_NUMBER */
1607
18
        break;
1608
18
#endif /* WITH_GEX */
1609
18
#ifdef HAVE_ECDH
1610
66
    case SSH_KEX_ECDH_SHA2_NISTP256:
1611
67
    case SSH_KEX_ECDH_SHA2_NISTP384:
1612
67
    case SSH_KEX_ECDH_SHA2_NISTP521:
1613
67
    case SSH_GSS_KEX_ECDH_NISTP256_SHA256:
1614
67
        if (session->next_crypto->ecdh_client_pubkey == NULL ||
1615
67
            session->next_crypto->ecdh_server_pubkey == NULL) {
1616
0
            SSH_LOG(SSH_LOG_TRACE, "ECDH parameter missing");
1617
0
            goto error;
1618
0
        }
1619
67
        rc = ssh_buffer_pack(buf,
1620
67
                             "SS",
1621
67
                             session->next_crypto->ecdh_client_pubkey,
1622
67
                             session->next_crypto->ecdh_server_pubkey);
1623
67
        if (rc != SSH_OK) {
1624
0
            ssh_set_error(session, SSH_FATAL, "Failed to pack ECDH pubkeys");
1625
0
            goto error;
1626
0
        }
1627
67
        break;
1628
67
#endif /* HAVE_ECDH */
1629
67
#ifdef HAVE_CURVE25519
1630
8.18k
    case SSH_KEX_CURVE25519_SHA256:
1631
8.56k
    case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG:
1632
8.56k
    case SSH_GSS_KEX_CURVE25519_SHA256:
1633
8.56k
        rc = ssh_buffer_pack(buf,
1634
8.56k
                             "dPdP",
1635
8.56k
                             CURVE25519_PUBKEY_SIZE,
1636
8.56k
                             (size_t)CURVE25519_PUBKEY_SIZE,
1637
8.56k
                             session->next_crypto->curve25519_client_pubkey,
1638
8.56k
                             CURVE25519_PUBKEY_SIZE,
1639
8.56k
                             (size_t)CURVE25519_PUBKEY_SIZE,
1640
8.56k
                             session->next_crypto->curve25519_server_pubkey);
1641
1642
8.56k
        if (rc != SSH_OK) {
1643
0
            ssh_set_error(session,
1644
0
                          SSH_FATAL,
1645
0
                          "Failed to pack Curve25519 pubkeys");
1646
0
            goto error;
1647
0
        }
1648
8.56k
        break;
1649
8.56k
#endif /* HAVE_CURVE25519 */
1650
8.56k
#ifdef HAVE_SNTRUP761
1651
8.56k
    case SSH_KEX_SNTRUP761X25519_SHA512:
1652
51
    case SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM:
1653
51
        rc = ssh_buffer_pack(buf,
1654
51
                             "dPPdPP",
1655
51
                             SNTRUP761_PUBLICKEY_SIZE + CURVE25519_PUBKEY_SIZE,
1656
51
                             (size_t)SNTRUP761_PUBLICKEY_SIZE,
1657
51
                             session->next_crypto->sntrup761_client_pubkey,
1658
51
                             (size_t)CURVE25519_PUBKEY_SIZE,
1659
51
                             session->next_crypto->curve25519_client_pubkey,
1660
51
                             SNTRUP761_CIPHERTEXT_SIZE + CURVE25519_PUBKEY_SIZE,
1661
51
                             (size_t)SNTRUP761_CIPHERTEXT_SIZE,
1662
51
                             session->next_crypto->sntrup761_ciphertext,
1663
51
                             (size_t)CURVE25519_PUBKEY_SIZE,
1664
51
                             session->next_crypto->curve25519_server_pubkey);
1665
1666
51
        if (rc != SSH_OK) {
1667
0
            ssh_set_error(session,
1668
0
                          SSH_FATAL,
1669
0
                          "Failed to pack SNTRU Prime params");
1670
0
            goto error;
1671
0
        }
1672
51
        break;
1673
51
#endif /* HAVE_SNTRUP761 */
1674
561
    case SSH_KEX_MLKEM768X25519_SHA256:
1675
569
    case SSH_KEX_MLKEM768NISTP256_SHA256:
1676
#ifdef HAVE_MLKEM1024
1677
    case SSH_KEX_MLKEM1024NISTP384_SHA384:
1678
#endif
1679
569
        rc = ssh_buffer_pack(buf,
1680
569
                             "SS",
1681
569
                             session->next_crypto->hybrid_client_init,
1682
569
                             session->next_crypto->hybrid_server_reply);
1683
569
        if (rc != SSH_OK) {
1684
0
            ssh_set_error(session,
1685
0
                          SSH_FATAL,
1686
0
                          "Failed to pack ML-KEM individual components");
1687
0
            goto error;
1688
0
        }
1689
569
        break;
1690
569
    default:
1691
        /* Handle unsupported kex types - this should not happen in normal operation */
1692
0
        rc = SSH_ERROR;
1693
0
        ssh_set_error(session, SSH_FATAL, "Unsupported KEX algorithm");
1694
0
        goto error;
1695
10.3k
    }
1696
10.3k
    switch (session->next_crypto->kex_type) {
1697
30
    case SSH_KEX_SNTRUP761X25519_SHA512:
1698
51
    case SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM:
1699
612
    case SSH_KEX_MLKEM768X25519_SHA256:
1700
620
    case SSH_KEX_MLKEM768NISTP256_SHA256:
1701
#ifdef HAVE_MLKEM1024
1702
    case SSH_KEX_MLKEM1024NISTP384_SHA384:
1703
#endif
1704
620
        rc = ssh_buffer_pack(buf, "S", session->next_crypto->hybrid_shared_secret);
1705
620
        break;
1706
9.69k
    default:
1707
9.69k
        rc = ssh_buffer_pack(buf, "B", session->next_crypto->shared_secret);
1708
9.69k
        break;
1709
10.3k
    }
1710
10.3k
    if (rc != SSH_OK) {
1711
0
        ssh_set_error(session, SSH_FATAL, "Failed to pack shared secret");
1712
0
        goto error;
1713
0
    }
1714
1715
#ifdef DEBUG_CRYPTO
1716
    ssh_log_hexdump("hash buffer", ssh_buffer_get(buf), ssh_buffer_get_len(buf));
1717
#endif
1718
1719
    /* Set rc for the following switch statement in case we goto error. */
1720
10.3k
    rc = SSH_ERROR;
1721
10.3k
    switch (session->next_crypto->kex_type) {
1722
0
    case SSH_KEX_DH_GROUP1_SHA1:
1723
0
    case SSH_KEX_DH_GROUP14_SHA1:
1724
0
#ifdef WITH_GEX
1725
0
    case SSH_KEX_DH_GEX_SHA1:
1726
0
#endif /* WITH_GEX */
1727
0
        session->next_crypto->digest_len = SHA_DIGEST_LENGTH;
1728
0
        session->next_crypto->digest_type = SSH_KDF_SHA1;
1729
0
        session->next_crypto->secret_hash = malloc(session->next_crypto->digest_len);
1730
0
        if (session->next_crypto->secret_hash == NULL) {
1731
0
            ssh_set_error_oom(session);
1732
0
            goto error;
1733
0
        }
1734
0
        sha1(ssh_buffer_get(buf), ssh_buffer_get_len(buf),
1735
0
                                   session->next_crypto->secret_hash);
1736
0
        break;
1737
733
    case SSH_KEX_DH_GROUP14_SHA256:
1738
733
    case SSH_GSS_KEX_DH_GROUP14_SHA256:
1739
799
    case SSH_KEX_ECDH_SHA2_NISTP256:
1740
8.98k
    case SSH_KEX_CURVE25519_SHA256:
1741
9.36k
    case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG:
1742
9.92k
    case SSH_KEX_MLKEM768X25519_SHA256:
1743
9.93k
    case SSH_KEX_MLKEM768NISTP256_SHA256:
1744
9.93k
    case SSH_GSS_KEX_ECDH_NISTP256_SHA256:
1745
9.93k
    case SSH_GSS_KEX_CURVE25519_SHA256:
1746
9.93k
#ifdef WITH_GEX
1747
9.95k
    case SSH_KEX_DH_GEX_SHA256:
1748
9.95k
#endif /* WITH_GEX */
1749
9.95k
        session->next_crypto->digest_len = SHA256_DIGEST_LENGTH;
1750
9.95k
        session->next_crypto->digest_type = SSH_KDF_SHA256;
1751
9.95k
        session->next_crypto->secret_hash = malloc(session->next_crypto->digest_len);
1752
9.95k
        if (session->next_crypto->secret_hash == NULL) {
1753
0
            ssh_set_error_oom(session);
1754
0
            goto error;
1755
0
        }
1756
9.95k
        sha256(ssh_buffer_get(buf), ssh_buffer_get_len(buf),
1757
9.95k
                                     session->next_crypto->secret_hash);
1758
9.95k
        break;
1759
1
    case SSH_KEX_ECDH_SHA2_NISTP384:
1760
#ifdef HAVE_MLKEM1024
1761
    case SSH_KEX_MLKEM1024NISTP384_SHA384:
1762
#endif
1763
1
        session->next_crypto->digest_len = SHA384_DIGEST_LENGTH;
1764
1
        session->next_crypto->digest_type = SSH_KDF_SHA384;
1765
1
        session->next_crypto->secret_hash = malloc(session->next_crypto->digest_len);
1766
1
        if (session->next_crypto->secret_hash == NULL) {
1767
0
            ssh_set_error_oom(session);
1768
0
            goto error;
1769
0
        }
1770
1
        sha384(ssh_buffer_get(buf), ssh_buffer_get_len(buf),
1771
1
                                     session->next_crypto->secret_hash);
1772
1
        break;
1773
72
    case SSH_KEX_DH_GROUP16_SHA512:
1774
72
    case SSH_GSS_KEX_DH_GROUP16_SHA512:
1775
309
    case SSH_KEX_DH_GROUP18_SHA512:
1776
309
    case SSH_KEX_ECDH_SHA2_NISTP521:
1777
339
    case SSH_KEX_SNTRUP761X25519_SHA512:
1778
360
    case SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM:
1779
360
        session->next_crypto->digest_len = SHA512_DIGEST_LENGTH;
1780
360
        session->next_crypto->digest_type = SSH_KDF_SHA512;
1781
360
        session->next_crypto->secret_hash = malloc(session->next_crypto->digest_len);
1782
360
        if (session->next_crypto->secret_hash == NULL) {
1783
0
            ssh_set_error_oom(session);
1784
0
            goto error;
1785
0
        }
1786
360
        sha512(ssh_buffer_get(buf),
1787
360
               ssh_buffer_get_len(buf),
1788
360
               session->next_crypto->secret_hash);
1789
360
        break;
1790
0
    default:
1791
        /* Handle unsupported kex types - this should not happen in normal operation */
1792
0
        ssh_set_error(session, SSH_FATAL, "Unsupported KEX algorithm for hash computation");
1793
0
        rc = SSH_ERROR;
1794
0
        goto error;
1795
10.3k
    }
1796
1797
    /* During the first kex, secret hash and session ID are equal. However, after
1798
     * a key re-exchange, a new secret hash is calculated. This hash will not replace
1799
     * but complement existing session id.
1800
     */
1801
10.3k
    if (!session->next_crypto->session_id) {
1802
10.1k
        session->next_crypto->session_id = malloc(session->next_crypto->digest_len);
1803
10.1k
        if (session->next_crypto->session_id == NULL) {
1804
0
            ssh_set_error_oom(session);
1805
0
            rc = SSH_ERROR;
1806
0
            goto error;
1807
0
        }
1808
10.1k
        memcpy(session->next_crypto->session_id, session->next_crypto->secret_hash,
1809
10.1k
                session->next_crypto->digest_len);
1810
  /* Initial length is the same as secret hash */
1811
10.1k
  session->next_crypto->session_id_len = session->next_crypto->digest_len;
1812
10.1k
    }
1813
#ifdef DEBUG_CRYPTO
1814
    SSH_LOG(SSH_LOG_DEBUG, "Session hash: \n");
1815
    ssh_log_hexdump("secret hash", session->next_crypto->secret_hash, session->next_crypto->digest_len);
1816
    ssh_log_hexdump("session id", session->next_crypto->session_id, session->next_crypto->session_id_len);
1817
#endif /* DEBUG_CRYPTO */
1818
1819
10.3k
    rc = SSH_OK;
1820
10.3k
error:
1821
10.3k
    SSH_BUFFER_FREE(buf);
1822
10.3k
    SSH_BUFFER_FREE(client_hash);
1823
10.3k
    SSH_BUFFER_FREE(server_hash);
1824
1825
10.3k
    session->in_hashbuf = NULL;
1826
10.3k
    session->out_hashbuf = NULL;
1827
1828
10.3k
    SSH_STRING_FREE(num);
1829
#if defined(HAVE_LIBCRYPTO) && OPENSSL_VERSION_NUMBER >= 0x30000000L
1830
    bignum_safe_free(client_pubkey);
1831
    bignum_safe_free(server_pubkey);
1832
#endif /* OPENSSL_VERSION_NUMBER */
1833
1834
10.3k
    return rc;
1835
10.3k
}
1836
1837
int ssh_hashbufout_add_cookie(ssh_session session)
1838
14.9k
{
1839
14.9k
    int rc;
1840
1841
14.9k
    session->out_hashbuf = ssh_buffer_new();
1842
14.9k
    if (session->out_hashbuf == NULL) {
1843
0
        return -1;
1844
0
    }
1845
1846
14.9k
    rc = ssh_buffer_allocate_size(session->out_hashbuf,
1847
14.9k
            sizeof(uint8_t) + 16);
1848
14.9k
    if (rc < 0) {
1849
0
        ssh_buffer_reinit(session->out_hashbuf);
1850
0
        return -1;
1851
0
    }
1852
1853
14.9k
    if (ssh_buffer_add_u8(session->out_hashbuf, 20) < 0) {
1854
0
        ssh_buffer_reinit(session->out_hashbuf);
1855
0
        return -1;
1856
0
    }
1857
1858
14.9k
    if (session->server) {
1859
10.2k
        if (ssh_buffer_add_data(session->out_hashbuf,
1860
10.2k
                    session->next_crypto->server_kex.cookie, 16) < 0) {
1861
0
            ssh_buffer_reinit(session->out_hashbuf);
1862
0
            return -1;
1863
0
        }
1864
10.2k
    } else {
1865
4.74k
        if (ssh_buffer_add_data(session->out_hashbuf,
1866
4.74k
                    session->next_crypto->client_kex.cookie, 16) < 0) {
1867
0
            ssh_buffer_reinit(session->out_hashbuf);
1868
0
            return -1;
1869
0
        }
1870
4.74k
    }
1871
1872
14.9k
    return 0;
1873
14.9k
}
1874
1875
int ssh_hashbufin_add_cookie(ssh_session session, unsigned char *cookie)
1876
13.4k
{
1877
13.4k
    int rc;
1878
1879
13.4k
    session->in_hashbuf = ssh_buffer_new();
1880
13.4k
    if (session->in_hashbuf == NULL) {
1881
0
        return -1;
1882
0
    }
1883
1884
13.4k
    rc = ssh_buffer_allocate_size(session->in_hashbuf,
1885
13.4k
            sizeof(uint8_t) + 20 + 16);
1886
13.4k
    if (rc < 0) {
1887
0
        ssh_buffer_reinit(session->in_hashbuf);
1888
0
        return -1;
1889
0
    }
1890
1891
13.4k
    if (ssh_buffer_add_u8(session->in_hashbuf, 20) < 0) {
1892
0
        ssh_buffer_reinit(session->in_hashbuf);
1893
0
        return -1;
1894
0
    }
1895
13.4k
    if (ssh_buffer_add_data(session->in_hashbuf,cookie, 16) < 0) {
1896
0
        ssh_buffer_reinit(session->in_hashbuf);
1897
0
        return -1;
1898
0
    }
1899
1900
13.4k
    return 0;
1901
13.4k
}
1902
1903
int ssh_generate_session_keys(ssh_session session)
1904
10.3k
{
1905
10.3k
    ssh_string k_string = NULL;
1906
10.3k
    struct ssh_crypto_struct *crypto = session->next_crypto;
1907
10.3k
    unsigned char *key = NULL;
1908
10.3k
    unsigned char *IV_cli_to_srv = NULL;
1909
10.3k
    unsigned char *IV_srv_to_cli = NULL;
1910
10.3k
    unsigned char *enckey_cli_to_srv = NULL;
1911
10.3k
    unsigned char *enckey_srv_to_cli = NULL;
1912
10.3k
    unsigned char *intkey_cli_to_srv = NULL;
1913
10.3k
    unsigned char *intkey_srv_to_cli = NULL;
1914
10.3k
    size_t key_len = 0;
1915
10.3k
    size_t IV_len = 0;
1916
10.3k
    size_t enckey_cli_to_srv_len = 0;
1917
10.3k
    size_t enckey_srv_to_cli_len = 0;
1918
10.3k
    size_t intkey_cli_to_srv_len = 0;
1919
10.3k
    size_t intkey_srv_to_cli_len = 0;
1920
10.3k
    int rc = -1;
1921
1922
10.3k
    switch (session->next_crypto->kex_type) {
1923
30
    case SSH_KEX_SNTRUP761X25519_SHA512:
1924
51
    case SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM:
1925
612
    case SSH_KEX_MLKEM768X25519_SHA256:
1926
620
    case SSH_KEX_MLKEM768NISTP256_SHA256:
1927
#ifdef HAVE_MLKEM1024
1928
    case SSH_KEX_MLKEM1024NISTP384_SHA384:
1929
#endif
1930
620
        k_string = ssh_string_copy(crypto->hybrid_shared_secret);
1931
620
        break;
1932
9.69k
    default:
1933
9.69k
        k_string = ssh_make_bignum_string(crypto->shared_secret);
1934
9.69k
        break;
1935
10.3k
    }
1936
10.3k
    if (k_string == NULL) {
1937
0
        ssh_set_error_oom(session);
1938
0
        goto error;
1939
0
    }
1940
    /* See RFC4251 Section 5 for the definition of mpint which is the
1941
     * encoding we need to use for key in the SSH KDF */
1942
10.3k
    key = (unsigned char *)k_string;
1943
10.3k
    key_len = ssh_string_len(k_string) + 4;
1944
1945
10.3k
    IV_len = crypto->digest_len;
1946
10.3k
    if (session->client) {
1947
1.78k
        enckey_cli_to_srv_len = crypto->out_cipher->keysize / 8;
1948
1.78k
        enckey_srv_to_cli_len = crypto->in_cipher->keysize / 8;
1949
1.78k
        intkey_cli_to_srv_len = hmac_digest_len(crypto->out_hmac);
1950
1.78k
        intkey_srv_to_cli_len = hmac_digest_len(crypto->in_hmac);
1951
8.52k
    } else {
1952
8.52k
        enckey_cli_to_srv_len = crypto->in_cipher->keysize / 8;
1953
8.52k
        enckey_srv_to_cli_len = crypto->out_cipher->keysize / 8;
1954
8.52k
        intkey_cli_to_srv_len = hmac_digest_len(crypto->in_hmac);
1955
8.52k
        intkey_srv_to_cli_len = hmac_digest_len(crypto->out_hmac);
1956
8.52k
    }
1957
1958
10.3k
    IV_cli_to_srv = malloc(IV_len);
1959
10.3k
    IV_srv_to_cli = malloc(IV_len);
1960
10.3k
    enckey_cli_to_srv = malloc(enckey_cli_to_srv_len);
1961
10.3k
    enckey_srv_to_cli = malloc(enckey_srv_to_cli_len);
1962
10.3k
    intkey_cli_to_srv = malloc(intkey_cli_to_srv_len);
1963
10.3k
    intkey_srv_to_cli = malloc(intkey_srv_to_cli_len);
1964
10.3k
    if (IV_cli_to_srv == NULL || IV_srv_to_cli == NULL ||
1965
10.3k
        enckey_cli_to_srv == NULL || enckey_srv_to_cli == NULL ||
1966
10.3k
        intkey_cli_to_srv == NULL || intkey_srv_to_cli == NULL) {
1967
0
        ssh_set_error_oom(session);
1968
0
        goto error;
1969
0
    }
1970
1971
    /* IV */
1972
10.3k
    rc = ssh_kdf(crypto, key, key_len, 'A', IV_cli_to_srv, IV_len);
1973
10.3k
    if (rc < 0) {
1974
0
        goto error;
1975
0
    }
1976
10.3k
    rc = ssh_kdf(crypto, key, key_len, 'B', IV_srv_to_cli, IV_len);
1977
10.3k
    if (rc < 0) {
1978
0
        goto error;
1979
0
    }
1980
    /* Encryption Key */
1981
10.3k
    rc = ssh_kdf(crypto, key, key_len, 'C', enckey_cli_to_srv,
1982
10.3k
                 enckey_cli_to_srv_len);
1983
10.3k
    if (rc < 0) {
1984
0
        goto error;
1985
0
    }
1986
10.3k
    rc = ssh_kdf(crypto, key, key_len, 'D', enckey_srv_to_cli,
1987
10.3k
                 enckey_srv_to_cli_len);
1988
10.3k
    if (rc < 0) {
1989
0
        goto error;
1990
0
    }
1991
    /* Integrity Key */
1992
10.3k
    rc = ssh_kdf(crypto, key, key_len, 'E', intkey_cli_to_srv,
1993
10.3k
                 intkey_cli_to_srv_len);
1994
10.3k
    if (rc < 0) {
1995
0
        goto error;
1996
0
    }
1997
10.3k
    rc = ssh_kdf(crypto, key, key_len, 'F', intkey_srv_to_cli,
1998
10.3k
                 intkey_srv_to_cli_len);
1999
10.3k
    if (rc < 0) {
2000
0
        goto error;
2001
0
    }
2002
2003
10.3k
    if (session->client) {
2004
1.78k
        crypto->encryptIV = IV_cli_to_srv;
2005
1.78k
        crypto->decryptIV = IV_srv_to_cli;
2006
1.78k
        crypto->encryptkey = enckey_cli_to_srv;
2007
1.78k
        crypto->decryptkey = enckey_srv_to_cli;
2008
1.78k
        crypto->encryptMAC = intkey_cli_to_srv;
2009
1.78k
        crypto->decryptMAC = intkey_srv_to_cli;
2010
8.52k
    } else {
2011
8.52k
        crypto->encryptIV = IV_srv_to_cli;
2012
8.52k
        crypto->decryptIV = IV_cli_to_srv;
2013
8.52k
        crypto->encryptkey = enckey_srv_to_cli;
2014
8.52k
        crypto->decryptkey = enckey_cli_to_srv;
2015
8.52k
        crypto->encryptMAC = intkey_srv_to_cli;
2016
8.52k
        crypto->decryptMAC = intkey_cli_to_srv;
2017
8.52k
    }
2018
2019
#ifdef DEBUG_CRYPTO
2020
    ssh_log_hexdump("Client to Server IV", IV_cli_to_srv, IV_len);
2021
    ssh_log_hexdump("Server to Client IV", IV_srv_to_cli, IV_len);
2022
    ssh_log_hexdump("Client to Server Encryption Key", enckey_cli_to_srv,
2023
                   enckey_cli_to_srv_len);
2024
    ssh_log_hexdump("Server to Client Encryption Key", enckey_srv_to_cli,
2025
                   enckey_srv_to_cli_len);
2026
    ssh_log_hexdump("Client to Server Integrity Key", intkey_cli_to_srv,
2027
                   intkey_cli_to_srv_len);
2028
    ssh_log_hexdump("Server to Client Integrity Key", intkey_srv_to_cli,
2029
                   intkey_srv_to_cli_len);
2030
#endif /* DEBUG_CRYPTO */
2031
2032
10.3k
    rc = 0;
2033
10.3k
error:
2034
10.3k
    ssh_string_burn(k_string);
2035
10.3k
    SSH_STRING_FREE(k_string);
2036
10.3k
    if (rc != 0) {
2037
0
        free(IV_cli_to_srv);
2038
0
        free(IV_srv_to_cli);
2039
0
        free(enckey_cli_to_srv);
2040
0
        free(enckey_srv_to_cli);
2041
0
        free(intkey_cli_to_srv);
2042
0
        free(intkey_srv_to_cli);
2043
0
    }
2044
2045
10.3k
    return rc;
2046
10.3k
}
2047
2048
/** @internal
2049
 * @brief Check if a given crypto context has a GSSAPI KEX set
2050
 *
2051
 * @param[in] crypto The SSH crypto context
2052
 * @return true if the KEX of the context is a GSSAPI KEX, false otherwise
2053
 */
2054
bool ssh_kex_is_gss(struct ssh_crypto_struct *crypto)
2055
37
{
2056
37
    switch (crypto->kex_type) {
2057
0
    case SSH_GSS_KEX_DH_GROUP14_SHA256:
2058
0
    case SSH_GSS_KEX_DH_GROUP16_SHA512:
2059
0
    case SSH_GSS_KEX_ECDH_NISTP256_SHA256:
2060
0
    case SSH_GSS_KEX_CURVE25519_SHA256:
2061
0
        return true;
2062
37
    default:
2063
        return false;
2064
37
    }
2065
37
}