Coverage Report

Created: 2026-03-20 06:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libssh/src/wrapper.c
Line
Count
Source
1
/*
2
 * wrapper.c - wrapper for crypto functions
3
 *
4
 * This file is part of the SSH Library
5
 *
6
 * Copyright (c) 2003-2013   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
/*
25
 * Why a wrapper?
26
 *
27
 * Let's say you want to port libssh from libcrypto of openssl to libfoo
28
 * you are going to spend hours removing every reference to SHA1_Update()
29
 * to libfoo_sha1_update after the work is finished, you're going to have
30
 * only this file to modify it's not needed to say that your modifications
31
 * are welcome.
32
 */
33
34
#include "config.h"
35
36
37
#include <stdlib.h>
38
#include <stdio.h>
39
#include <string.h>
40
41
#include "libssh/priv.h"
42
#include "libssh/session.h"
43
#include "libssh/crypto.h"
44
#include "libssh/wrapper.h"
45
#include "libssh/pki.h"
46
#include "libssh/poly1305.h"
47
#include "libssh/dh.h"
48
#ifdef WITH_GEX
49
#include "libssh/dh-gex.h"
50
#endif /* WITH_GEX */
51
#include "libssh/curve25519.h"
52
#include "libssh/kex-gss.h"
53
#include "libssh/ecdh.h"
54
#include "libssh/hybrid_mlkem.h"
55
#include "libssh/sntrup761.h"
56
57
static struct ssh_hmac_struct ssh_hmac_tab[] = {
58
  { "hmac-sha1",                     SSH_HMAC_SHA1,          false },
59
  { "hmac-sha2-256",                 SSH_HMAC_SHA256,        false },
60
  { "hmac-sha2-512",                 SSH_HMAC_SHA512,        false },
61
  { "hmac-md5",                      SSH_HMAC_MD5,           false },
62
  { "aead-poly1305",                 SSH_HMAC_AEAD_POLY1305, false },
63
  { "aead-gcm",                      SSH_HMAC_AEAD_GCM,      false },
64
  { "hmac-sha1-etm@openssh.com",     SSH_HMAC_SHA1,          true  },
65
  { "hmac-sha2-256-etm@openssh.com", SSH_HMAC_SHA256,        true  },
66
  { "hmac-sha2-512-etm@openssh.com", SSH_HMAC_SHA512,        true  },
67
  { "hmac-md5-etm@openssh.com",      SSH_HMAC_MD5,           true  },
68
#ifdef WITH_INSECURE_NONE
69
  { "none",                          SSH_HMAC_NONE,          false },
70
#endif /* WITH_INSECURE_NONE */
71
  { NULL,                            0,                      false }
72
};
73
74
12.1k
struct ssh_hmac_struct *ssh_get_hmactab(void) {
75
12.1k
  return ssh_hmac_tab;
76
12.1k
}
77
78
688k
size_t hmac_digest_len(enum ssh_hmac_e type) {
79
688k
  switch(type) {
80
252k
    case SSH_HMAC_SHA1:
81
252k
      return SHA_DIGEST_LEN;
82
252k
    case SSH_HMAC_SHA256:
83
252k
      return SHA256_DIGEST_LEN;
84
0
    case SSH_HMAC_SHA512:
85
0
      return SHA512_DIGEST_LEN;
86
0
    case SSH_HMAC_MD5:
87
0
      return MD5_DIGEST_LEN;
88
0
    case SSH_HMAC_AEAD_POLY1305:
89
0
      return POLY1305_TAGLEN;
90
0
    case SSH_HMAC_AEAD_GCM:
91
0
      return AES_GCM_TAGLEN;
92
182k
    default:
93
182k
      return 0;
94
688k
  }
95
688k
}
96
97
const char *ssh_hmac_type_to_string(enum ssh_hmac_e hmac_type, bool etm)
98
0
{
99
0
  int i = 0;
100
0
  struct ssh_hmac_struct *ssh_hmactab = ssh_get_hmactab();
101
0
  while (ssh_hmactab[i].name &&
102
0
         ((ssh_hmactab[i].hmac_type != hmac_type) ||
103
0
          (ssh_hmactab[i].etm != etm))) {
104
0
    i++;
105
0
  }
106
0
  return ssh_hmactab[i].name;
107
0
}
108
109
/* it allocates a new cipher structure based on its offset into the global table */
110
24.3k
static struct ssh_cipher_struct *cipher_new(uint8_t offset) {
111
24.3k
  struct ssh_cipher_struct *cipher = NULL;
112
113
24.3k
  cipher = malloc(sizeof(struct ssh_cipher_struct));
114
24.3k
  if (cipher == NULL) {
115
0
    return NULL;
116
0
  }
117
118
  /* note the memcpy will copy the pointers : so, you shouldn't free them */
119
24.3k
  memcpy(cipher, &ssh_get_ciphertab()[offset], sizeof(*cipher));
120
121
24.3k
  return cipher;
122
24.3k
}
123
124
73.1k
void ssh_cipher_clear(struct ssh_cipher_struct *cipher){
125
#ifdef HAVE_LIBGCRYPT
126
    unsigned int i;
127
#endif
128
129
73.1k
    if (cipher == NULL) {
130
48.7k
        return;
131
48.7k
    }
132
133
#ifdef HAVE_LIBGCRYPT
134
    if (cipher->key) {
135
        for (i = 0; i < (cipher->keylen / sizeof(gcry_cipher_hd_t)); i++) {
136
            gcry_cipher_close(cipher->key[i]);
137
        }
138
        SAFE_FREE(cipher->key);
139
    }
140
#endif
141
142
24.3k
    if (cipher->cleanup != NULL) {
143
18.2k
        cipher->cleanup(cipher);
144
18.2k
    }
145
24.3k
}
146
147
73.1k
static void cipher_free(struct ssh_cipher_struct *cipher) {
148
73.1k
  ssh_cipher_clear(cipher);
149
73.1k
  SAFE_FREE(cipher);
150
73.1k
}
151
152
struct ssh_crypto_struct *crypto_new(void)
153
36.5k
{
154
36.5k
    struct ssh_crypto_struct *crypto = NULL;
155
156
36.5k
    crypto = calloc(1, sizeof(struct ssh_crypto_struct));
157
36.5k
    if (crypto == NULL) {
158
0
        return NULL;
159
0
    }
160
36.5k
    return crypto;
161
36.5k
}
162
163
void crypto_free(struct ssh_crypto_struct *crypto)
164
48.7k
{
165
48.7k
    size_t i;
166
167
48.7k
    if (crypto == NULL) {
168
12.1k
        return;
169
12.1k
    }
170
171
36.5k
    ssh_key_free(crypto->server_pubkey);
172
173
36.5k
    ssh_dh_cleanup(crypto);
174
36.5k
    bignum_safe_free(crypto->shared_secret);
175
36.5k
#ifdef HAVE_ECDH
176
36.5k
    SAFE_FREE(crypto->ecdh_client_pubkey);
177
36.5k
    SAFE_FREE(crypto->ecdh_server_pubkey);
178
36.5k
    if (crypto->ecdh_privkey != NULL) {
179
0
#ifdef HAVE_OPENSSL_ECC
180
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
181
0
        EC_KEY_free(crypto->ecdh_privkey);
182
#else
183
        EVP_PKEY_free(crypto->ecdh_privkey);
184
#endif /* OPENSSL_VERSION_NUMBER */
185
#elif defined HAVE_GCRYPT_ECC
186
        gcry_sexp_release(crypto->ecdh_privkey);
187
#elif defined HAVE_LIBMBEDCRYPTO
188
        mbedtls_ecp_keypair_free(crypto->ecdh_privkey);
189
        SAFE_FREE(crypto->ecdh_privkey);
190
#endif /* HAVE_LIBGCRYPT */
191
0
        crypto->ecdh_privkey = NULL;
192
0
    }
193
36.5k
#endif
194
36.5k
#ifdef HAVE_LIBCRYPTO
195
36.5k
    EVP_PKEY_free(crypto->curve25519_privkey);
196
#elif defined(HAVE_GCRYPT_CURVE25519)
197
    gcry_sexp_release(crypto->curve25519_privkey);
198
#endif
199
36.5k
    SAFE_FREE(crypto->dh_server_signature);
200
36.5k
    if (crypto->session_id != NULL) {
201
24.3k
        ssh_burn(crypto->session_id, crypto->session_id_len);
202
24.3k
        SAFE_FREE(crypto->session_id);
203
24.3k
    }
204
36.5k
    if (crypto->secret_hash != NULL) {
205
12.1k
        ssh_burn(crypto->secret_hash, crypto->digest_len);
206
12.1k
        SAFE_FREE(crypto->secret_hash);
207
12.1k
    }
208
36.5k
    compress_cleanup(crypto);
209
36.5k
    SAFE_FREE(crypto->encryptIV);
210
36.5k
    SAFE_FREE(crypto->decryptIV);
211
36.5k
    SAFE_FREE(crypto->encryptMAC);
212
36.5k
    SAFE_FREE(crypto->decryptMAC);
213
36.5k
    if (crypto->encryptkey != NULL) {
214
12.1k
        ssh_burn(crypto->encryptkey, crypto->out_cipher->keysize / 8);
215
12.1k
        SAFE_FREE(crypto->encryptkey);
216
12.1k
    }
217
36.5k
    if (crypto->decryptkey != NULL) {
218
12.1k
        ssh_burn(crypto->decryptkey, crypto->in_cipher->keysize / 8);
219
12.1k
        SAFE_FREE(crypto->decryptkey);
220
12.1k
    }
221
222
36.5k
    cipher_free(crypto->in_cipher);
223
36.5k
    cipher_free(crypto->out_cipher);
224
225
402k
    for (i = 0; i < SSH_KEX_METHODS; i++) {
226
365k
        SAFE_FREE(crypto->client_kex.methods[i]);
227
365k
        SAFE_FREE(crypto->server_kex.methods[i]);
228
365k
        SAFE_FREE(crypto->kex_methods[i]);
229
365k
    }
230
231
#ifdef HAVE_OPENSSL_MLKEM
232
    EVP_PKEY_free(crypto->mlkem_privkey);
233
#else
234
36.5k
    if (crypto->mlkem_privkey != NULL) {
235
6.09k
        ssh_burn(crypto->mlkem_privkey, crypto->mlkem_privkey_len);
236
6.09k
        SAFE_FREE(crypto->mlkem_privkey);
237
6.09k
        crypto->mlkem_privkey_len = 0;
238
6.09k
    }
239
36.5k
#endif
240
36.5k
    ssh_string_burn(crypto->hybrid_shared_secret);
241
36.5k
    ssh_string_free(crypto->mlkem_client_pubkey);
242
36.5k
    ssh_string_free(crypto->mlkem_ciphertext);
243
36.5k
    ssh_string_free(crypto->hybrid_client_init);
244
36.5k
    ssh_string_free(crypto->hybrid_server_reply);
245
36.5k
    ssh_string_free(crypto->hybrid_shared_secret);
246
247
36.5k
    ssh_burn(crypto, sizeof(struct ssh_crypto_struct));
248
249
36.5k
    SAFE_FREE(crypto);
250
36.5k
}
251
252
static void
253
compression_enable(ssh_session session,
254
                   enum ssh_crypto_direction_e direction,
255
                   bool delayed)
256
0
{
257
    /* The delayed compression is turned on AFTER authentication. This means
258
     * that we need to turn it on immediately in case of rekeying */
259
0
    if (delayed && !(session->flags & SSH_SESSION_FLAG_AUTHENTICATED)) {
260
0
        if (direction == SSH_DIRECTION_IN) {
261
0
            session->next_crypto->delayed_compress_in = 1;
262
0
        } else { /* SSH_DIRECTION_OUT */
263
0
            session->next_crypto->delayed_compress_out = 1;
264
0
        }
265
0
    } else {
266
0
        if (direction == SSH_DIRECTION_IN) {
267
0
            session->next_crypto->do_compress_in = 1;
268
0
        } else { /* SSH_DIRECTION_OUT */
269
0
            session->next_crypto->do_compress_out = 1;
270
0
        }
271
0
    }
272
0
}
273
274
static int crypt_set_algorithms2(ssh_session session)
275
6.09k
{
276
6.09k
    const char *wanted = NULL;
277
6.09k
    const char *method = NULL;
278
6.09k
    struct ssh_cipher_struct *ssh_ciphertab=ssh_get_ciphertab();
279
6.09k
    struct ssh_hmac_struct *ssh_hmactab=ssh_get_hmactab();
280
6.09k
    uint8_t i = 0;
281
6.09k
    int cmp;
282
283
    /*
284
     * We must scan the kex entries to find crypto algorithms and set their
285
     * appropriate structure.
286
     */
287
288
    /* out */
289
6.09k
    wanted = session->next_crypto->kex_methods[SSH_CRYPT_C_S];
290
28.9k
    for (i = 0; i < 64 && ssh_ciphertab[i].name != NULL; ++i) {
291
28.9k
        cmp = strcmp(wanted, ssh_ciphertab[i].name);
292
28.9k
        if (cmp == 0) {
293
6.09k
            break;
294
6.09k
        }
295
28.9k
    }
296
297
6.09k
    if (ssh_ciphertab[i].name == NULL) {
298
0
        ssh_set_error(session, SSH_FATAL,
299
0
                "crypt_set_algorithms2: no crypto algorithm function found for %s",
300
0
                wanted);
301
0
        return SSH_ERROR;
302
0
    }
303
6.09k
    SSH_LOG(SSH_LOG_PACKET, "Set output algorithm to %s", wanted);
304
305
6.09k
    session->next_crypto->out_cipher = cipher_new(i);
306
6.09k
    if (session->next_crypto->out_cipher == NULL) {
307
0
        ssh_set_error_oom(session);
308
0
        return SSH_ERROR;
309
0
    }
310
311
6.09k
    if (session->next_crypto->out_cipher->aead_encrypt != NULL) {
312
        /* this cipher has integrated MAC */
313
0
        if (session->next_crypto->out_cipher->ciphertype == SSH_AEAD_CHACHA20_POLY1305) {
314
0
            wanted = "aead-poly1305";
315
0
        } else {
316
0
            wanted = "aead-gcm";
317
0
        }
318
6.09k
    } else {
319
        /*
320
         * We must scan the kex entries to find hmac algorithms and set their
321
         * appropriate structure.
322
         */
323
324
        /* out */
325
6.09k
        wanted = session->next_crypto->kex_methods[SSH_MAC_C_S];
326
6.09k
    }
327
328
28.4k
    for (i = 0; ssh_hmactab[i].name != NULL; i++) {
329
28.4k
        cmp = strcmp(wanted, ssh_hmactab[i].name);
330
28.4k
        if (cmp == 0) {
331
6.09k
            break;
332
6.09k
        }
333
28.4k
    }
334
335
6.09k
    if (ssh_hmactab[i].name == NULL) {
336
0
        ssh_set_error(session, SSH_FATAL,
337
0
                "crypt_set_algorithms2: no hmac algorithm function found for %s",
338
0
                wanted);
339
0
        return SSH_ERROR;
340
0
    }
341
6.09k
    SSH_LOG(SSH_LOG_PACKET, "Set HMAC output algorithm to %s", wanted);
342
343
6.09k
    session->next_crypto->out_hmac = ssh_hmactab[i].hmac_type;
344
6.09k
    session->next_crypto->out_hmac_etm = ssh_hmactab[i].etm;
345
346
    /* in */
347
6.09k
    wanted = session->next_crypto->kex_methods[SSH_CRYPT_S_C];
348
349
28.9k
    for (i = 0; ssh_ciphertab[i].name != NULL; i++) {
350
28.9k
        cmp = strcmp(wanted, ssh_ciphertab[i].name);
351
28.9k
        if (cmp == 0) {
352
6.09k
            break;
353
6.09k
        }
354
28.9k
    }
355
356
6.09k
    if (ssh_ciphertab[i].name == NULL) {
357
0
        ssh_set_error(session, SSH_FATAL,
358
0
                "Crypt_set_algorithms: no crypto algorithm function found for %s",
359
0
                wanted);
360
0
        return SSH_ERROR;
361
0
    }
362
6.09k
    SSH_LOG(SSH_LOG_PACKET, "Set input algorithm to %s", wanted);
363
364
6.09k
    session->next_crypto->in_cipher = cipher_new(i);
365
6.09k
    if (session->next_crypto->in_cipher == NULL) {
366
0
        ssh_set_error_oom(session);
367
0
        return SSH_ERROR;
368
0
    }
369
370
6.09k
    if (session->next_crypto->in_cipher->aead_encrypt != NULL){
371
        /* this cipher has integrated MAC */
372
0
        if (session->next_crypto->in_cipher->ciphertype == SSH_AEAD_CHACHA20_POLY1305) {
373
0
            wanted = "aead-poly1305";
374
0
        } else {
375
0
            wanted = "aead-gcm";
376
0
        }
377
6.09k
    } else {
378
        /* we must scan the kex entries to find hmac algorithms and set their appropriate structure */
379
6.09k
        wanted = session->next_crypto->kex_methods[SSH_MAC_S_C];
380
6.09k
    }
381
382
28.4k
    for (i = 0; ssh_hmactab[i].name != NULL; i++) {
383
28.4k
        cmp = strcmp(wanted, ssh_hmactab[i].name);
384
28.4k
        if (cmp == 0) {
385
6.09k
            break;
386
6.09k
        }
387
28.4k
    }
388
389
6.09k
    if (ssh_hmactab[i].name == NULL) {
390
0
        ssh_set_error(session, SSH_FATAL,
391
0
                "crypt_set_algorithms2: no hmac algorithm function found for %s",
392
0
                wanted);
393
0
        return SSH_ERROR;
394
0
    }
395
6.09k
    SSH_LOG(SSH_LOG_PACKET, "Set HMAC input algorithm to %s", wanted);
396
397
6.09k
    session->next_crypto->in_hmac = ssh_hmactab[i].hmac_type;
398
6.09k
    session->next_crypto->in_hmac_etm = ssh_hmactab[i].etm;
399
400
    /* compression: client */
401
6.09k
    method = session->next_crypto->kex_methods[SSH_COMP_C_S];
402
6.09k
    cmp = strcmp(method, "zlib");
403
6.09k
    if (cmp == 0) {
404
0
        SSH_LOG(SSH_LOG_PACKET, "enabling C->S compression");
405
0
        compression_enable(session, SSH_DIRECTION_OUT, false);
406
0
    }
407
6.09k
    cmp = strcmp(method, "zlib@openssh.com");
408
6.09k
    if (cmp == 0) {
409
0
        SSH_LOG(SSH_LOG_PACKET, "enabling C->S delayed compression");
410
0
        compression_enable(session, SSH_DIRECTION_OUT, true);
411
0
    }
412
413
6.09k
    method = session->next_crypto->kex_methods[SSH_COMP_S_C];
414
6.09k
    cmp = strcmp(method, "zlib");
415
6.09k
    if (cmp == 0) {
416
0
        SSH_LOG(SSH_LOG_PACKET, "enabling S->C compression");
417
0
        compression_enable(session, SSH_DIRECTION_IN, false);
418
0
    }
419
6.09k
    cmp = strcmp(method, "zlib@openssh.com");
420
6.09k
    if (cmp == 0) {
421
0
        SSH_LOG(SSH_LOG_PACKET, "enabling S->C delayed compression");
422
0
        compression_enable(session, SSH_DIRECTION_IN, true);
423
0
    }
424
425
6.09k
    return SSH_OK;
426
6.09k
}
427
428
int crypt_set_algorithms_client(ssh_session session)
429
6.09k
{
430
6.09k
    return crypt_set_algorithms2(session);
431
6.09k
}
432
433
#ifdef WITH_SERVER
434
6.09k
int crypt_set_algorithms_server(ssh_session session){
435
6.09k
    const char *method = NULL;
436
6.09k
    uint8_t i = 0;
437
6.09k
    struct ssh_cipher_struct *ssh_ciphertab=ssh_get_ciphertab();
438
6.09k
    struct ssh_hmac_struct   *ssh_hmactab=ssh_get_hmactab();
439
6.09k
    int cmp;
440
441
6.09k
    if (session == NULL) {
442
0
        return SSH_ERROR;
443
0
    }
444
445
    /*
446
     * We must scan the kex entries to find crypto algorithms and set their
447
     * appropriate structure
448
     */
449
    /* out */
450
6.09k
    method = session->next_crypto->kex_methods[SSH_CRYPT_S_C];
451
452
28.9k
    for (i = 0; ssh_ciphertab[i].name != NULL; i++) {
453
28.9k
        cmp = strcmp(method, ssh_ciphertab[i].name);
454
28.9k
        if (cmp == 0) {
455
6.09k
          break;
456
6.09k
        }
457
28.9k
    }
458
459
6.09k
    if (ssh_ciphertab[i].name == NULL) {
460
0
        ssh_set_error(session,SSH_FATAL,"crypt_set_algorithms_server : "
461
0
                "no crypto algorithm function found for %s",method);
462
0
        return SSH_ERROR;
463
0
    }
464
6.09k
    SSH_LOG(SSH_LOG_PACKET,"Set output algorithm %s",method);
465
466
6.09k
    session->next_crypto->out_cipher = cipher_new(i);
467
6.09k
    if (session->next_crypto->out_cipher == NULL) {
468
0
        ssh_set_error_oom(session);
469
0
        return SSH_ERROR;
470
0
    }
471
472
6.09k
    if (session->next_crypto->out_cipher->aead_encrypt != NULL){
473
        /* this cipher has integrated MAC */
474
0
        if (session->next_crypto->out_cipher->ciphertype == SSH_AEAD_CHACHA20_POLY1305) {
475
0
            method = "aead-poly1305";
476
0
        } else {
477
0
            method = "aead-gcm";
478
0
        }
479
6.09k
    } else {
480
        /* we must scan the kex entries to find hmac algorithms and set their appropriate structure */
481
        /* out */
482
6.09k
        method = session->next_crypto->kex_methods[SSH_MAC_S_C];
483
6.09k
    }
484
    /* HMAC algorithm selection */
485
486
28.4k
    for (i = 0; ssh_hmactab[i].name != NULL; i++) {
487
28.4k
        cmp = strcmp(method, ssh_hmactab[i].name);
488
28.4k
        if (cmp == 0) {
489
6.09k
            break;
490
6.09k
        }
491
28.4k
    }
492
493
6.09k
    if (ssh_hmactab[i].name == NULL) {
494
0
      ssh_set_error(session, SSH_FATAL,
495
0
          "crypt_set_algorithms_server: no hmac algorithm function found for %s",
496
0
          method);
497
0
        return SSH_ERROR;
498
0
    }
499
6.09k
    SSH_LOG(SSH_LOG_PACKET, "Set HMAC output algorithm to %s", method);
500
501
6.09k
    session->next_crypto->out_hmac = ssh_hmactab[i].hmac_type;
502
6.09k
    session->next_crypto->out_hmac_etm = ssh_hmactab[i].etm;
503
504
    /* in */
505
6.09k
    method = session->next_crypto->kex_methods[SSH_CRYPT_C_S];
506
507
28.9k
    for (i = 0; ssh_ciphertab[i].name; i++) {
508
28.9k
        cmp = strcmp(method, ssh_ciphertab[i].name);
509
28.9k
        if (cmp == 0) {
510
6.09k
            break;
511
6.09k
        }
512
28.9k
    }
513
514
6.09k
    if (ssh_ciphertab[i].name == NULL) {
515
0
        ssh_set_error(session,SSH_FATAL,"Crypt_set_algorithms_server :"
516
0
                "no crypto algorithm function found for %s",method);
517
0
        return SSH_ERROR;
518
0
    }
519
6.09k
    SSH_LOG(SSH_LOG_PACKET,"Set input algorithm %s",method);
520
521
6.09k
    session->next_crypto->in_cipher = cipher_new(i);
522
6.09k
    if (session->next_crypto->in_cipher == NULL) {
523
0
        ssh_set_error_oom(session);
524
0
        return SSH_ERROR;
525
0
    }
526
527
6.09k
    if (session->next_crypto->in_cipher->aead_encrypt != NULL){
528
        /* this cipher has integrated MAC */
529
0
        if (session->next_crypto->in_cipher->ciphertype == SSH_AEAD_CHACHA20_POLY1305) {
530
0
            method = "aead-poly1305";
531
0
        } else {
532
0
            method = "aead-gcm";
533
0
        }
534
6.09k
    } else {
535
        /* we must scan the kex entries to find hmac algorithms and set their appropriate structure */
536
6.09k
        method = session->next_crypto->kex_methods[SSH_MAC_C_S];
537
6.09k
    }
538
539
28.4k
    for (i = 0; ssh_hmactab[i].name != NULL; i++) {
540
28.4k
        cmp = strcmp(method, ssh_hmactab[i].name);
541
28.4k
        if (cmp == 0) {
542
6.09k
            break;
543
6.09k
        }
544
28.4k
    }
545
546
6.09k
    if (ssh_hmactab[i].name == NULL) {
547
0
      ssh_set_error(session, SSH_FATAL,
548
0
          "crypt_set_algorithms_server: no hmac algorithm function found for %s",
549
0
          method);
550
0
        return SSH_ERROR;
551
0
    }
552
6.09k
    SSH_LOG(SSH_LOG_PACKET, "Set HMAC input algorithm to %s", method);
553
554
6.09k
    session->next_crypto->in_hmac = ssh_hmactab[i].hmac_type;
555
6.09k
    session->next_crypto->in_hmac_etm = ssh_hmactab[i].etm;
556
557
    /* compression */
558
6.09k
    method = session->next_crypto->kex_methods[SSH_COMP_C_S];
559
6.09k
    cmp = strcmp(method, "zlib");
560
6.09k
    if (cmp == 0) {
561
0
        SSH_LOG(SSH_LOG_PACKET, "enabling C->S compression");
562
0
        compression_enable(session, SSH_DIRECTION_IN, false);
563
0
    }
564
6.09k
    cmp = strcmp(method, "zlib@openssh.com");
565
6.09k
    if (cmp == 0) {
566
0
        SSH_LOG(SSH_LOG_PACKET, "enabling C->S delayed compression");
567
0
        compression_enable(session, SSH_DIRECTION_IN, true);
568
0
    }
569
570
6.09k
    method = session->next_crypto->kex_methods[SSH_COMP_S_C];
571
6.09k
    cmp = strcmp(method, "zlib");
572
6.09k
    if (cmp == 0) {
573
0
        SSH_LOG(SSH_LOG_PACKET, "enabling S->C compression");
574
0
        compression_enable(session, SSH_DIRECTION_OUT, false);
575
0
    }
576
6.09k
    cmp = strcmp(method, "zlib@openssh.com");
577
6.09k
    if (cmp == 0) {
578
0
        SSH_LOG(SSH_LOG_PACKET, "enabling S->C delayed compression");
579
0
        compression_enable(session, SSH_DIRECTION_OUT, true);
580
0
    }
581
582
6.09k
    method = session->next_crypto->kex_methods[SSH_HOSTKEYS];
583
6.09k
    session->srv.hostkey = ssh_key_type_from_signature_name(method);
584
6.09k
    session->srv.hostkey_digest = ssh_key_hash_from_name(method);
585
586
    /* setup DH key exchange type */
587
6.09k
    switch (session->next_crypto->kex_type) {
588
0
    case SSH_KEX_DH_GROUP1_SHA1:
589
0
    case SSH_KEX_DH_GROUP14_SHA1:
590
0
    case SSH_KEX_DH_GROUP14_SHA256:
591
0
    case SSH_KEX_DH_GROUP16_SHA512:
592
0
    case SSH_KEX_DH_GROUP18_SHA512:
593
0
      ssh_server_dh_init(session);
594
0
      break;
595
#ifdef WITH_GSSAPI
596
    case SSH_GSS_KEX_DH_GROUP14_SHA256:
597
    case SSH_GSS_KEX_DH_GROUP16_SHA512:
598
    case SSH_GSS_KEX_ECDH_NISTP256_SHA256:
599
    case SSH_GSS_KEX_CURVE25519_SHA256:
600
        ssh_server_gss_kex_init(session);
601
        break;
602
#endif /* WITH_GSSAPI */
603
0
#ifdef WITH_GEX
604
0
    case SSH_KEX_DH_GEX_SHA1:
605
0
    case SSH_KEX_DH_GEX_SHA256:
606
0
      ssh_server_dhgex_init(session);
607
0
      break;
608
0
#endif /* WITH_GEX */
609
0
#ifdef HAVE_ECDH
610
0
    case SSH_KEX_ECDH_SHA2_NISTP256:
611
0
    case SSH_KEX_ECDH_SHA2_NISTP384:
612
0
    case SSH_KEX_ECDH_SHA2_NISTP521:
613
0
      ssh_server_ecdh_init(session);
614
0
      break;
615
0
#endif
616
0
#ifdef HAVE_CURVE25519
617
0
    case SSH_KEX_CURVE25519_SHA256:
618
0
    case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG:
619
0
        ssh_server_curve25519_init(session);
620
0
        break;
621
0
#endif
622
0
#ifdef HAVE_SNTRUP761
623
0
    case SSH_KEX_SNTRUP761X25519_SHA512:
624
0
    case SSH_KEX_SNTRUP761X25519_SHA512_OPENSSH_COM:
625
0
        ssh_server_sntrup761x25519_init(session);
626
0
        break;
627
0
#endif
628
6.09k
    case SSH_KEX_MLKEM768X25519_SHA256:
629
6.09k
    case SSH_KEX_MLKEM768NISTP256_SHA256:
630
#ifdef HAVE_MLKEM1024
631
    case SSH_KEX_MLKEM1024NISTP384_SHA384:
632
#endif
633
6.09k
        ssh_server_hybrid_mlkem_init(session);
634
6.09k
        break;
635
0
    default:
636
0
        ssh_set_error(session,
637
0
                      SSH_FATAL,
638
0
                      "crypt_set_algorithms_server: could not find init "
639
0
                      "handler for kex type %d",
640
0
                      session->next_crypto->kex_type);
641
0
        return SSH_ERROR;
642
6.09k
    }
643
6.09k
    return SSH_OK;
644
6.09k
}
645
646
#endif /* WITH_SERVER */