Coverage Report

Created: 2026-02-26 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libssh/src/libcrypto.c
Line
Count
Source
1
/*
2
 * This file is part of the SSH Library
3
 *
4
 * Copyright (c) 2009 by Aris Adamantiadis
5
 *
6
 * The SSH Library is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU Lesser General Public License as published by
8
 * the Free Software Foundation; either version 2.1 of the License, or (at your
9
 * option) any later version.
10
 *
11
 * The SSH Library is distributed in the hope that it will be useful, but
12
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14
 * License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public License
17
 * along with the SSH Library; see the file COPYING.  If not, write to
18
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
19
 * MA 02111-1307, USA.
20
 */
21
22
#include "config.h"
23
24
#include <stdlib.h>
25
#include <stdio.h>
26
#include <string.h>
27
#ifdef HAVE_SYS_TIME_H
28
#include <sys/time.h>
29
#endif /* HAVE_SYS_TIME_H */
30
31
#include "libssh/priv.h"
32
#include "libssh/session.h"
33
#include "libssh/crypto.h"
34
#include "libssh/wrapper.h"
35
#include "libssh/libcrypto.h"
36
#include "libssh/pki.h"
37
#ifdef HAVE_OPENSSL_EVP_CHACHA20
38
#include "libssh/bytearray.h"
39
#include "libssh/chacha20-poly1305-common.h"
40
#endif
41
42
#ifdef HAVE_LIBCRYPTO
43
#ifdef LIBRESSL_VERSION_NUMBER
44
#include <openssl/poly1305.h>
45
#endif
46
#include <openssl/err.h>
47
#include <openssl/md5.h>
48
#include <openssl/opensslv.h>
49
#include <openssl/sha.h>
50
#if OPENSSL_VERSION_NUMBER < 0x30000000L
51
#include <openssl/rsa.h>
52
#include <openssl/hmac.h>
53
#else
54
#include <openssl/core_names.h>
55
#include <openssl/param_build.h>
56
#include <openssl/provider.h>
57
#endif /* OPENSSL_VERSION_NUMBER */
58
#include <openssl/rand.h>
59
#if defined(WITH_PKCS11_URI) && !defined(WITH_PKCS11_PROVIDER)
60
#include <openssl/engine.h>
61
#endif
62
63
#include "libcrypto-compat.h"
64
65
#ifdef HAVE_OPENSSL_AES_H
66
#define HAS_AES
67
#include <openssl/aes.h>
68
#endif /* HAVE_OPENSSL_AES_H */
69
#ifdef HAVE_OPENSSL_DES_H
70
#define HAS_DES
71
#include <openssl/des.h>
72
#endif /* HAVE_OPENSSL_DES_H */
73
74
#if (defined(HAVE_VALGRIND_VALGRIND_H) && defined(HAVE_OPENSSL_IA32CAP_LOC))
75
#include <valgrind/valgrind.h>
76
#define CAN_DISABLE_AESNI
77
#endif
78
79
#include "libssh/crypto.h"
80
81
#ifdef HAVE_OPENSSL_EVP_KDF_CTX
82
#include <openssl/kdf.h>
83
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
84
#include <openssl/param_build.h>
85
#include <openssl/core_names.h>
86
#endif /* OPENSSL_VERSION_NUMBER */
87
#endif /* HAVE_OPENSSL_EVP_KDF_CTX */
88
89
#include "libssh/crypto.h"
90
91
static int libcrypto_initialized = 0;
92
93
94
6.51k
void ssh_reseed(void){
95
6.51k
#ifndef _WIN32
96
6.51k
    struct timeval tv;
97
6.51k
    gettimeofday(&tv, NULL);
98
6.51k
    RAND_add(&tv, sizeof(tv), 0.0);
99
6.51k
#endif
100
6.51k
}
101
102
#if defined(WITH_PKCS11_URI)
103
#if defined(WITH_PKCS11_PROVIDER)
104
static OSSL_PROVIDER *provider = NULL;
105
static bool pkcs11_provider_failed = false;
106
107
int pki_load_pkcs11_provider(void)
108
{
109
    if (OSSL_PROVIDER_available(NULL, "pkcs11") == 1) {
110
        /* the provider is already available.
111
         * Loaded through a configuration file? */
112
        return SSH_OK;
113
    }
114
115
    if (pkcs11_provider_failed) {
116
        /* the loading failed previously -- do not retry */
117
        return SSH_ERROR;
118
    }
119
120
    provider = OSSL_PROVIDER_try_load(NULL, "pkcs11", 1);
121
    if (provider != NULL) {
122
        return SSH_OK;
123
    }
124
125
    SSH_LOG(SSH_LOG_TRACE,
126
            "Failed to load the pkcs11 provider: %s",
127
            ERR_error_string(ERR_get_error(), NULL));
128
    /* Do not attempt to load it again */
129
    pkcs11_provider_failed = true;
130
    return SSH_ERROR;
131
}
132
#else
133
static ENGINE *engine = NULL;
134
135
ENGINE *pki_get_engine(void)
136
{
137
    int ok;
138
139
    if (engine == NULL) {
140
        ENGINE_load_builtin_engines();
141
142
        engine = ENGINE_by_id("pkcs11");
143
        if (engine == NULL) {
144
            SSH_LOG(SSH_LOG_TRACE,
145
                    "Could not load the engine: %s",
146
                    ERR_error_string(ERR_get_error(), NULL));
147
            return NULL;
148
        }
149
        SSH_LOG(SSH_LOG_DEBUG, "Engine loaded successfully");
150
151
        ok = ENGINE_init(engine);
152
        if (!ok) {
153
            SSH_LOG(SSH_LOG_TRACE,
154
                    "Could not initialize the engine: %s",
155
                    ERR_error_string(ERR_get_error(), NULL));
156
            ENGINE_free(engine);
157
            return NULL;
158
        }
159
160
        SSH_LOG(SSH_LOG_DEBUG, "Engine init success");
161
    }
162
    return engine;
163
}
164
#endif /* defined(WITH_PKCS11_PROVIDER) */
165
#endif /* defined(WITH_PKCS11_URI) */
166
167
#ifdef HAVE_OPENSSL_EVP_KDF_CTX
168
#if OPENSSL_VERSION_NUMBER < 0x30000000L
169
static const EVP_MD *sshkdf_digest_to_md(enum ssh_kdf_digest digest_type)
170
{
171
    switch (digest_type) {
172
    case SSH_KDF_SHA1:
173
        return EVP_sha1();
174
    case SSH_KDF_SHA256:
175
        return EVP_sha256();
176
    case SSH_KDF_SHA384:
177
        return EVP_sha384();
178
    case SSH_KDF_SHA512:
179
        return EVP_sha512();
180
    }
181
    return NULL;
182
}
183
#else
184
static const char *sshkdf_digest_to_md(enum ssh_kdf_digest digest_type)
185
{
186
    switch (digest_type) {
187
    case SSH_KDF_SHA1:
188
        return SN_sha1;
189
    case SSH_KDF_SHA256:
190
        return SN_sha256;
191
    case SSH_KDF_SHA384:
192
        return SN_sha384;
193
    case SSH_KDF_SHA512:
194
        return SN_sha512;
195
    }
196
    return NULL;
197
}
198
#endif /* OPENSSL_VERSION_NUMBER */
199
200
int ssh_kdf(struct ssh_crypto_struct *crypto,
201
            unsigned char *key, size_t key_len,
202
            uint8_t key_type, unsigned char *output,
203
            size_t requested_len)
204
{
205
    int ret = SSH_ERROR, rv;
206
#if OPENSSL_VERSION_NUMBER < 0x30000000L
207
    EVP_KDF_CTX *ctx = EVP_KDF_CTX_new_id(EVP_KDF_SSHKDF);
208
#else
209
    EVP_KDF_CTX *ctx = NULL;
210
    OSSL_PARAM_BLD *param_bld = NULL;
211
    OSSL_PARAM *params = NULL;
212
    const char *md = NULL;
213
    EVP_KDF *kdf = NULL;
214
215
    md = sshkdf_digest_to_md(crypto->digest_type);
216
    if (md == NULL) {
217
        return -1;
218
    }
219
220
    kdf = EVP_KDF_fetch(NULL, "SSHKDF", NULL);
221
    if (kdf == NULL) {
222
        return -1;
223
    }
224
    ctx = EVP_KDF_CTX_new(kdf);
225
    EVP_KDF_free(kdf);
226
227
    param_bld = OSSL_PARAM_BLD_new();
228
    if (param_bld == NULL) {
229
        EVP_KDF_CTX_free(ctx);
230
        return -1;
231
    }
232
#endif /* OPENSSL_VERSION_NUMBER */
233
234
    if (ctx == NULL) {
235
        goto out;
236
    }
237
238
#if OPENSSL_VERSION_NUMBER < 0x30000000L
239
    rv = EVP_KDF_ctrl(ctx,
240
                      EVP_KDF_CTRL_SET_MD,
241
                      sshkdf_digest_to_md(crypto->digest_type));
242
    if (rv != 1) {
243
        goto out;
244
    }
245
    rv = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_KEY, key, key_len);
246
    if (rv != 1) {
247
        goto out;
248
    }
249
    rv = EVP_KDF_ctrl(ctx,
250
                      EVP_KDF_CTRL_SET_SSHKDF_XCGHASH,
251
                      crypto->secret_hash,
252
                      crypto->digest_len);
253
    if (rv != 1) {
254
        goto out;
255
    }
256
    rv = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_SSHKDF_TYPE, key_type);
257
    if (rv != 1) {
258
        goto out;
259
    }
260
    rv = EVP_KDF_ctrl(ctx,
261
                      EVP_KDF_CTRL_SET_SSHKDF_SESSION_ID,
262
                      crypto->session_id,
263
                      crypto->session_id_len);
264
    if (rv != 1) {
265
        goto out;
266
    }
267
    rv = EVP_KDF_derive(ctx, output, requested_len);
268
    if (rv != 1) {
269
        goto out;
270
    }
271
#else
272
    rv = OSSL_PARAM_BLD_push_utf8_string(param_bld,
273
                                         OSSL_KDF_PARAM_DIGEST,
274
                                         md,
275
                                         strlen(md));
276
    if (rv != 1) {
277
        goto out;
278
    }
279
    rv = OSSL_PARAM_BLD_push_octet_string(param_bld,
280
                                          OSSL_KDF_PARAM_KEY,
281
                                          key,
282
                                          key_len);
283
    if (rv != 1) {
284
        goto out;
285
    }
286
    rv = OSSL_PARAM_BLD_push_octet_string(param_bld,
287
                                          OSSL_KDF_PARAM_SSHKDF_XCGHASH,
288
                                          crypto->secret_hash,
289
                                          crypto->digest_len);
290
    if (rv != 1) {
291
        goto out;
292
    }
293
    rv = OSSL_PARAM_BLD_push_octet_string(param_bld,
294
                                          OSSL_KDF_PARAM_SSHKDF_SESSION_ID,
295
                                          crypto->session_id,
296
                                          crypto->session_id_len);
297
    if (rv != 1) {
298
        goto out;
299
    }
300
    rv = OSSL_PARAM_BLD_push_utf8_string(param_bld,
301
                                         OSSL_KDF_PARAM_SSHKDF_TYPE,
302
                                         (const char *)&key_type,
303
                                         1);
304
    if (rv != 1) {
305
        goto out;
306
    }
307
308
    params = OSSL_PARAM_BLD_to_param(param_bld);
309
    if (params == NULL) {
310
        goto out;
311
    }
312
313
    rv = EVP_KDF_derive(ctx, output, requested_len, params);
314
    if (rv != 1) {
315
        goto out;
316
    }
317
#endif /* OPENSSL_VERSION_NUMBER */
318
    ret = SSH_OK;
319
320
out:
321
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
322
    OSSL_PARAM_BLD_free(param_bld);
323
    OSSL_PARAM_free(params);
324
#endif
325
    EVP_KDF_CTX_free(ctx);
326
    if (ret < 0) {
327
        return ret;
328
    }
329
    return 0;
330
}
331
332
#else
333
int ssh_kdf(struct ssh_crypto_struct *crypto,
334
            unsigned char *key, size_t key_len,
335
            uint8_t key_type, unsigned char *output,
336
            size_t requested_len)
337
36.1k
{
338
36.1k
    return sshkdf_derive_key(crypto, key, key_len,
339
36.1k
                             key_type, output, requested_len);
340
36.1k
}
341
#endif /* HAVE_OPENSSL_EVP_KDF_CTX */
342
343
HMACCTX hmac_init(const void *key, size_t len, enum ssh_hmac_e type)
344
3.96k
{
345
3.96k
    HMACCTX ctx = NULL;
346
3.96k
    EVP_PKEY *pkey = NULL;
347
3.96k
    int rc = -1;
348
349
3.96k
    ctx = EVP_MD_CTX_new();
350
3.96k
    if (ctx == NULL) {
351
0
        return NULL;
352
0
    }
353
354
3.96k
    pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, key, (int)len);
355
3.96k
    if (pkey == NULL) {
356
0
        goto error;
357
0
    }
358
359
3.96k
    switch (type) {
360
3.96k
    case SSH_HMAC_SHA1:
361
3.96k
        rc = EVP_DigestSignInit(ctx, NULL, EVP_sha1(), NULL, pkey);
362
3.96k
        break;
363
0
    case SSH_HMAC_SHA256:
364
0
        rc = EVP_DigestSignInit(ctx, NULL, EVP_sha256(), NULL, pkey);
365
0
        break;
366
0
    case SSH_HMAC_SHA512:
367
0
        rc = EVP_DigestSignInit(ctx, NULL, EVP_sha512(), NULL, pkey);
368
0
        break;
369
0
    case SSH_HMAC_MD5:
370
0
        rc = EVP_DigestSignInit(ctx, NULL, EVP_md5(), NULL, pkey);
371
0
        break;
372
0
    default:
373
0
        rc = -1;
374
0
        break;
375
3.96k
    }
376
377
3.96k
    EVP_PKEY_free(pkey);
378
3.96k
    if (rc != 1) {
379
0
        goto error;
380
0
    }
381
3.96k
    return ctx;
382
383
0
error:
384
0
    EVP_MD_CTX_free(ctx);
385
0
    return NULL;
386
3.96k
}
387
388
int hmac_update(HMACCTX ctx, const void *data, size_t len)
389
3.96k
{
390
3.96k
    return EVP_DigestSignUpdate(ctx, data, len);
391
3.96k
}
392
393
int hmac_final(HMACCTX ctx, unsigned char *hashmacbuf, size_t *len)
394
3.96k
{
395
3.96k
    size_t res = *len;
396
3.96k
    int rc;
397
3.96k
    rc = EVP_DigestSignFinal(ctx, hashmacbuf, &res);
398
3.96k
    EVP_MD_CTX_free(ctx);
399
3.96k
    if (rc == 1) {
400
3.96k
        *len = res;
401
3.96k
    }
402
403
3.96k
    return rc;
404
3.96k
}
405
406
static void evp_cipher_init(struct ssh_cipher_struct *cipher)
407
0
{
408
0
    if (cipher->ctx == NULL) {
409
0
        cipher->ctx = EVP_CIPHER_CTX_new();
410
0
    } else {
411
0
        EVP_CIPHER_CTX_reset(cipher->ctx);
412
0
    }
413
414
0
    switch(cipher->ciphertype){
415
0
    case SSH_AES128_CBC:
416
0
        cipher->cipher = EVP_aes_128_cbc();
417
0
        break;
418
0
    case SSH_AES192_CBC:
419
0
        cipher->cipher = EVP_aes_192_cbc();
420
0
        break;
421
0
    case SSH_AES256_CBC:
422
0
        cipher->cipher = EVP_aes_256_cbc();
423
0
        break;
424
0
    case SSH_AES128_CTR:
425
0
        cipher->cipher = EVP_aes_128_ctr();
426
0
        break;
427
0
    case SSH_AES192_CTR:
428
0
        cipher->cipher = EVP_aes_192_ctr();
429
0
        break;
430
0
    case SSH_AES256_CTR:
431
0
        cipher->cipher = EVP_aes_256_ctr();
432
0
        break;
433
0
    case SSH_AEAD_AES128_GCM:
434
0
        cipher->cipher = EVP_aes_128_gcm();
435
0
        break;
436
0
    case SSH_AEAD_AES256_GCM:
437
0
        cipher->cipher = EVP_aes_256_gcm();
438
0
        break;
439
0
    case SSH_3DES_CBC:
440
0
        cipher->cipher = EVP_des_ede3_cbc();
441
0
        break;
442
#ifdef HAVE_BLOWFISH
443
    case SSH_BLOWFISH_CBC:
444
        cipher->cipher = EVP_bf_cbc();
445
        break;
446
        /* ciphers not using EVP */
447
#endif /* HAVE_BLOWFISH */
448
0
    case SSH_AEAD_CHACHA20_POLY1305:
449
0
        SSH_LOG(SSH_LOG_TRACE, "The ChaCha cipher cannot be handled here");
450
0
        break;
451
0
    case SSH_NO_CIPHER:
452
0
        SSH_LOG(SSH_LOG_TRACE, "No valid ciphertype found");
453
0
        break;
454
0
    }
455
0
}
456
457
static int evp_cipher_set_encrypt_key(struct ssh_cipher_struct *cipher,
458
            void *key, void *IV)
459
0
{
460
0
    int rc;
461
462
0
    evp_cipher_init(cipher);
463
464
0
    rc = EVP_EncryptInit_ex(cipher->ctx, cipher->cipher, NULL, key, IV);
465
0
    if (rc != 1){
466
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_EncryptInit_ex failed");
467
0
        return SSH_ERROR;
468
0
    }
469
470
    /* For AES-GCM we need to set IV in specific way */
471
0
    if (cipher->ciphertype == SSH_AEAD_AES128_GCM ||
472
0
        cipher->ciphertype == SSH_AEAD_AES256_GCM) {
473
0
        rc = EVP_CIPHER_CTX_ctrl(cipher->ctx,
474
0
                                 EVP_CTRL_GCM_SET_IV_FIXED,
475
0
                                 -1,
476
0
                                 (uint8_t *)IV);
477
0
        if (rc != 1) {
478
0
            SSH_LOG(SSH_LOG_TRACE, "EVP_CTRL_GCM_SET_IV_FIXED failed");
479
0
            return SSH_ERROR;
480
0
        }
481
0
    }
482
483
0
    EVP_CIPHER_CTX_set_padding(cipher->ctx, 0);
484
485
0
    return SSH_OK;
486
0
}
487
488
static int evp_cipher_set_decrypt_key(struct ssh_cipher_struct *cipher,
489
0
            void *key, void *IV) {
490
0
    int rc;
491
492
0
    evp_cipher_init(cipher);
493
494
0
    rc = EVP_DecryptInit_ex(cipher->ctx, cipher->cipher, NULL, key, IV);
495
0
    if (rc != 1){
496
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_DecryptInit_ex failed");
497
0
        return SSH_ERROR;
498
0
    }
499
500
    /* For AES-GCM we need to set IV in specific way */
501
0
    if (cipher->ciphertype == SSH_AEAD_AES128_GCM ||
502
0
        cipher->ciphertype == SSH_AEAD_AES256_GCM) {
503
0
        rc = EVP_CIPHER_CTX_ctrl(cipher->ctx,
504
0
                                 EVP_CTRL_GCM_SET_IV_FIXED,
505
0
                                 -1,
506
0
                                 (uint8_t *)IV);
507
0
        if (rc != 1) {
508
0
            SSH_LOG(SSH_LOG_TRACE, "EVP_CTRL_GCM_SET_IV_FIXED failed");
509
0
            return SSH_ERROR;
510
0
        }
511
0
    }
512
513
0
    EVP_CIPHER_CTX_set_padding(cipher->ctx, 0);
514
515
0
    return SSH_OK;
516
0
}
517
518
/* EVP wrapper function for encrypt/decrypt */
519
static void evp_cipher_encrypt(struct ssh_cipher_struct *cipher,
520
                               void *in,
521
                               void *out,
522
                               size_t len)
523
0
{
524
0
    int outlen = 0;
525
0
    int rc = 0;
526
527
0
    rc = EVP_EncryptUpdate(cipher->ctx,
528
0
                           (unsigned char *)out,
529
0
                           &outlen,
530
0
                           (unsigned char *)in,
531
0
                           (int)len);
532
0
    if (rc != 1){
533
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_EncryptUpdate failed");
534
0
        return;
535
0
    }
536
0
    if (outlen != (int)len){
537
0
        SSH_LOG(SSH_LOG_DEBUG,
538
0
                "EVP_EncryptUpdate: output size %d for %zu in",
539
0
                outlen,
540
0
                len);
541
0
        return;
542
0
    }
543
0
}
544
545
static void evp_cipher_decrypt(struct ssh_cipher_struct *cipher,
546
                               void *in,
547
                               void *out,
548
                               size_t len)
549
0
{
550
0
    int outlen = 0;
551
0
    int rc = 0;
552
553
0
    rc = EVP_DecryptUpdate(cipher->ctx,
554
0
                           (unsigned char *)out,
555
0
                           &outlen,
556
0
                           (unsigned char *)in,
557
0
                           (int)len);
558
0
    if (rc != 1){
559
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_DecryptUpdate failed");
560
0
        return;
561
0
    }
562
0
    if (outlen != (int)len){
563
0
        SSH_LOG(SSH_LOG_DEBUG,
564
0
                "EVP_DecryptUpdate: output size %d for %zu in",
565
0
                outlen,
566
0
                len);
567
0
        return;
568
0
    }
569
0
}
570
571
0
static void evp_cipher_cleanup(struct ssh_cipher_struct *cipher) {
572
0
    if (cipher->ctx != NULL) {
573
0
        EVP_CIPHER_CTX_free(cipher->ctx);
574
0
    }
575
0
}
576
577
static int evp_cipher_aead_get_length(struct ssh_cipher_struct *cipher,
578
                                      void *in,
579
                                      uint8_t *out,
580
                                      size_t len,
581
                                      uint64_t seq)
582
0
{
583
0
    (void)cipher;
584
0
    (void)seq;
585
586
    /* The length is not encrypted: Copy it to the result buffer */
587
0
    memcpy(out, in, len);
588
589
0
    return SSH_OK;
590
0
}
591
592
static void evp_cipher_aead_encrypt(struct ssh_cipher_struct *cipher,
593
                                    void *in,
594
                                    void *out,
595
                                    size_t len,
596
                                    uint8_t *tag,
597
                                    uint64_t seq)
598
0
{
599
0
    size_t authlen, aadlen;
600
0
    uint8_t lastiv[1];
601
0
    int tmplen = 0;
602
0
    size_t outlen;
603
0
    int rc;
604
605
0
    (void) seq;
606
607
0
    aadlen = cipher->lenfield_blocksize;
608
0
    authlen = cipher->tag_size;
609
610
    /* increment IV */
611
0
    rc = EVP_CIPHER_CTX_ctrl(cipher->ctx, EVP_CTRL_GCM_IV_GEN, 1, lastiv);
612
0
    if (rc == 0) {
613
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_CTRL_GCM_IV_GEN failed");
614
0
        return;
615
0
    }
616
617
    /* Pass over the authenticated data (not encrypted) */
618
0
    rc = EVP_EncryptUpdate(cipher->ctx,
619
0
                           NULL,
620
0
                           &tmplen,
621
0
                           (unsigned char *)in,
622
0
                           (int)aadlen);
623
0
    outlen = tmplen;
624
0
    if (rc == 0 || outlen != aadlen) {
625
0
        SSH_LOG(SSH_LOG_TRACE, "Failed to pass authenticated data");
626
0
        return;
627
0
    }
628
0
    memcpy(out, in, aadlen);
629
630
    /* Encrypt the rest of the data */
631
0
    rc = EVP_EncryptUpdate(cipher->ctx,
632
0
                           (unsigned char *)out + aadlen,
633
0
                           &tmplen,
634
0
                           (unsigned char *)in + aadlen,
635
0
                           (int)(len - aadlen));
636
0
    outlen = tmplen;
637
0
    if (rc != 1 || outlen != (int)len - aadlen) {
638
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_EncryptUpdate failed");
639
0
        return;
640
0
    }
641
642
    /* compute tag */
643
0
    rc = EVP_EncryptFinal(cipher->ctx, NULL, &tmplen);
644
0
    if (rc < 0) {
645
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_EncryptFinal failed: Failed to create a tag");
646
0
        return;
647
0
    }
648
649
0
    rc = EVP_CIPHER_CTX_ctrl(cipher->ctx,
650
0
                             EVP_CTRL_GCM_GET_TAG,
651
0
                             (int)authlen,
652
0
                             (unsigned char *)tag);
653
0
    if (rc != 1) {
654
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_CTRL_GCM_GET_TAG failed");
655
0
        return;
656
0
    }
657
0
}
658
659
static int evp_cipher_aead_decrypt(struct ssh_cipher_struct *cipher,
660
                                   void *complete_packet,
661
                                   uint8_t *out,
662
                                   size_t encrypted_size,
663
                                   uint64_t seq)
664
0
{
665
0
    size_t authlen, aadlen;
666
0
    uint8_t lastiv[1];
667
0
    int outlen = 0;
668
0
    int rc = 0;
669
670
0
    (void)seq;
671
672
0
    aadlen = cipher->lenfield_blocksize;
673
0
    authlen = cipher->tag_size;
674
675
    /* increment IV */
676
0
    rc = EVP_CIPHER_CTX_ctrl(cipher->ctx, EVP_CTRL_GCM_IV_GEN, 1, lastiv);
677
0
    if (rc == 0) {
678
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_CTRL_GCM_IV_GEN failed");
679
0
        return SSH_ERROR;
680
0
    }
681
682
    /* set tag for authentication */
683
0
    rc = EVP_CIPHER_CTX_ctrl(cipher->ctx,
684
0
                             EVP_CTRL_GCM_SET_TAG,
685
0
                             (int)authlen,
686
0
                             (unsigned char *)complete_packet + aadlen +
687
0
                                 encrypted_size);
688
0
    if (rc == 0) {
689
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_CTRL_GCM_SET_TAG failed");
690
0
        return SSH_ERROR;
691
0
    }
692
693
    /* Pass over the authenticated data (not encrypted) */
694
0
    rc = EVP_DecryptUpdate(cipher->ctx,
695
0
                           NULL,
696
0
                           &outlen,
697
0
                           (unsigned char *)complete_packet,
698
0
                           (int)aadlen);
699
0
    if (rc == 0) {
700
0
        SSH_LOG(SSH_LOG_TRACE, "Failed to pass authenticated data");
701
0
        return SSH_ERROR;
702
0
    }
703
    /* Do not copy the length to the target buffer, because it is already processed */
704
    //memcpy(out, complete_packet, aadlen);
705
706
    /* Decrypt the rest of the data */
707
0
    rc = EVP_DecryptUpdate(cipher->ctx,
708
0
                           (unsigned char *)out,
709
0
                           &outlen,
710
0
                           (unsigned char *)complete_packet + aadlen,
711
0
                           (int)encrypted_size /* already subtracted aadlen */);
712
0
    if (rc != 1) {
713
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_DecryptUpdate failed");
714
0
        return SSH_ERROR;
715
0
    }
716
717
0
    if (outlen != (int)encrypted_size) {
718
0
        SSH_LOG(SSH_LOG_TRACE,
719
0
                "EVP_DecryptUpdate: output size %d for %zd in",
720
0
                outlen,
721
0
                encrypted_size);
722
0
        return SSH_ERROR;
723
0
    }
724
725
    /* verify tag */
726
0
    rc = EVP_DecryptFinal(cipher->ctx, NULL, &outlen);
727
0
    if (rc < 0) {
728
0
        SSH_LOG(SSH_LOG_TRACE,
729
0
                "EVP_DecryptFinal failed: Failed authentication");
730
0
        return SSH_ERROR;
731
0
    }
732
733
0
    return SSH_OK;
734
0
}
735
736
#ifdef HAVE_OPENSSL_EVP_CHACHA20
737
738
struct chacha20_poly1305_keysched {
739
    /* cipher handle used for encrypting the packets */
740
    EVP_CIPHER_CTX *main_evp;
741
    /* cipher handle used for encrypting the length field */
742
    EVP_CIPHER_CTX *header_evp;
743
#if defined(LIBRESSL_VERSION_NUMBER)
744
    /* LibreSSL Poly1305 context */
745
    poly1305_context poly_ctx;
746
#elif OPENSSL_VERSION_NUMBER < 0x30000000L
747
    /* mac handle used for authenticating the packets */
748
    EVP_PKEY_CTX *pctx;
749
    /* Poly1305 key */
750
    EVP_PKEY *key;
751
    /* MD context for digesting data in poly1305 */
752
    EVP_MD_CTX *mctx;
753
#else
754
    /* MAC context used to do poly1305 */
755
    EVP_MAC_CTX *mctx;
756
#endif /* OPENSSL_VERSION_NUMBER */
757
};
758
759
static void chacha20_poly1305_cleanup(struct ssh_cipher_struct *cipher)
760
0
{
761
0
    struct chacha20_poly1305_keysched *ctx = NULL;
762
763
0
    if (cipher->chacha20_schedule == NULL) {
764
0
        return;
765
0
    }
766
767
0
    ctx = cipher->chacha20_schedule;
768
769
0
    EVP_CIPHER_CTX_free(ctx->main_evp);
770
0
    ctx->main_evp = NULL;
771
0
    EVP_CIPHER_CTX_free(ctx->header_evp);
772
0
    ctx->header_evp = NULL;
773
#if defined(LIBRESSL_VERSION_NUMBER)
774
    /* nothing to free */
775
#elif OPENSSL_VERSION_NUMBER < 0x30000000L
776
    /* ctx->pctx is freed as part of MD context */
777
0
    EVP_PKEY_free(ctx->key);
778
0
    ctx->key = NULL;
779
0
    EVP_MD_CTX_free(ctx->mctx);
780
0
    ctx->mctx = NULL;
781
#else
782
    EVP_MAC_CTX_free(ctx->mctx);
783
    ctx->mctx = NULL;
784
#endif /* OPENSSL_VERSION_NUMBER */
785
786
0
    SAFE_FREE(cipher->chacha20_schedule);
787
0
}
788
789
static int chacha20_poly1305_set_key(struct ssh_cipher_struct *cipher,
790
                                     void *key,
791
                                     UNUSED_PARAM(void *IV))
792
0
{
793
0
    struct chacha20_poly1305_keysched *ctx = NULL;
794
0
    uint8_t *u8key = key;
795
0
    int ret = SSH_ERROR, rv;
796
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
797
    EVP_MAC *mac = NULL;
798
#endif
799
800
0
    if (cipher->chacha20_schedule == NULL) {
801
0
        ctx = calloc(1, sizeof(*ctx));
802
0
        if (ctx == NULL) {
803
0
            return -1;
804
0
        }
805
0
        cipher->chacha20_schedule = ctx;
806
0
    } else {
807
0
        ctx = cipher->chacha20_schedule;
808
0
    }
809
810
    /* ChaCha20 initialization */
811
    /* K2 uses the first half of the key */
812
0
    ctx->main_evp = EVP_CIPHER_CTX_new();
813
0
    if (ctx->main_evp == NULL) {
814
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_CIPHER_CTX_new failed");
815
0
        goto out;
816
0
    }
817
0
    rv = EVP_EncryptInit_ex(ctx->main_evp, EVP_chacha20(), NULL, u8key, NULL);
818
0
    if (rv != 1) {
819
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_CipherInit failed");
820
0
        goto out;
821
0
    }
822
    /* K1 uses the second half of the key */
823
0
    ctx->header_evp = EVP_CIPHER_CTX_new();
824
0
    if (ctx->header_evp == NULL) {
825
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_CIPHER_CTX_new failed");
826
0
        goto out;
827
0
    }
828
0
    rv = EVP_EncryptInit_ex(ctx->header_evp, EVP_chacha20(), NULL,
829
0
                             u8key + CHACHA20_KEYLEN, NULL);
830
0
    if (rv != 1) {
831
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_CipherInit failed");
832
0
        goto out;
833
0
    }
834
835
    /* The Poly1305 key initialization is delayed to the time we know
836
     * the actual key for packet so we do not need to create a bogus keys
837
     */
838
#if defined(LIBRESSL_VERSION_NUMBER)
839
    /* nothing, poly1305_context is stack based */
840
#elif OPENSSL_VERSION_NUMBER < 0x30000000L
841
0
    ctx->mctx = EVP_MD_CTX_new();
842
0
    if (ctx->mctx == NULL) {
843
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_MD_CTX_new failed");
844
0
        return SSH_ERROR;
845
0
    }
846
#else
847
    mac = EVP_MAC_fetch(NULL, SN_poly1305, NULL);
848
    if (mac == NULL) {
849
        SSH_LOG(SSH_LOG_TRACE, "EVP_MAC_fetch failed");
850
        goto out;
851
    }
852
    ctx->mctx = EVP_MAC_CTX_new(mac);
853
    if (ctx->mctx == NULL) {
854
        SSH_LOG(SSH_LOG_TRACE, "EVP_MAC_CTX_new failed");
855
        goto out;
856
    }
857
#endif /* OPENSSL_VERSION_NUMBER */
858
859
0
    ret = SSH_OK;
860
0
out:
861
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
862
    EVP_MAC_free(mac);
863
#endif
864
0
    if (ret != SSH_OK) {
865
0
        chacha20_poly1305_cleanup(cipher);
866
0
    }
867
0
    return ret;
868
0
}
869
870
static const uint8_t zero_block[CHACHA20_BLOCKSIZE] = {0};
871
872
static int chacha20_poly1305_set_iv(struct ssh_cipher_struct *cipher,
873
                                    uint64_t seq,
874
                                    int do_encrypt)
875
0
{
876
0
    struct chacha20_poly1305_keysched *ctx = cipher->chacha20_schedule;
877
0
    uint8_t seqbuf[16] = {0};
878
0
    int ret;
879
880
    /* Prepare the IV for OpenSSL -- it needs to be 128 b long. First 32 b is
881
     * counter the rest is nonce. The memory is initialized to zeros
882
     * (counter starts from 0) and we set the sequence number in the second half
883
     */
884
0
    PUSH_BE_U64(seqbuf, 8, seq);
885
#ifdef DEBUG_CRYPTO
886
    ssh_log_hexdump("seqbuf (chacha20 IV)", seqbuf, sizeof(seqbuf));
887
#endif /* DEBUG_CRYPTO */
888
889
0
    ret = EVP_CipherInit_ex(ctx->header_evp, NULL, NULL, NULL, seqbuf, do_encrypt);
890
0
    if (ret != 1) {
891
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_CipherInit_ex(header_evp) failed");
892
0
        return SSH_ERROR;
893
0
    }
894
895
0
    ret = EVP_CipherInit_ex(ctx->main_evp, NULL, NULL, NULL, seqbuf, do_encrypt);
896
0
    if (ret != 1) {
897
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_CipherInit_ex(main_evp) failed");
898
0
        return SSH_ERROR;
899
0
    }
900
901
0
    return SSH_OK;
902
0
}
903
904
static int chacha20_poly1305_packet_setup(struct ssh_cipher_struct *cipher,
905
                                          uint64_t seq,
906
                                          int do_encrypt)
907
0
{
908
0
    struct chacha20_poly1305_keysched *ctx = cipher->chacha20_schedule;
909
0
    uint8_t poly_key[CHACHA20_BLOCKSIZE];
910
0
    int ret = SSH_ERROR, len, rv;
911
912
    /* The initialization for decrypt was already done with the length block */
913
0
    if (do_encrypt) {
914
0
        rv = chacha20_poly1305_set_iv(cipher, seq, do_encrypt);
915
0
        if (rv != SSH_OK) {
916
0
            return SSH_ERROR;
917
0
        }
918
0
    }
919
920
    /* Output full ChaCha block so that counter increases by one for
921
     * next step. */
922
0
    rv = EVP_CipherUpdate(ctx->main_evp, poly_key, &len,
923
0
                           (unsigned char *)zero_block, sizeof(zero_block));
924
0
    if (rv != 1 || len != CHACHA20_BLOCKSIZE) {
925
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_EncryptUpdate failed");
926
0
        goto out;
927
0
    }
928
#ifdef DEBUG_CRYPTO
929
    ssh_log_hexdump("poly_key", poly_key, POLY1305_KEYLEN);
930
#endif /* DEBUG_CRYPTO */
931
932
/* LibreSSL path: use direct Poly1305 implementation */
933
#if defined(LIBRESSL_VERSION_NUMBER)
934
    CRYPTO_poly1305_init(&ctx->poly_ctx, poly_key);
935
/* Set the Poly1305 key */
936
#elif OPENSSL_VERSION_NUMBER < 0x30000000L
937
0
    if (ctx->key == NULL) {
938
        /* Poly1305 Initialization needs to know the actual key */
939
0
        ctx->key = EVP_PKEY_new_mac_key(EVP_PKEY_POLY1305,
940
0
                                        NULL,
941
0
                                        poly_key,
942
0
                                        POLY1305_KEYLEN);
943
0
        if (ctx->key == NULL) {
944
0
            SSH_LOG(SSH_LOG_TRACE, "EVP_PKEY_new_mac_key failed");
945
0
            goto out;
946
0
        }
947
0
        rv = EVP_DigestSignInit(ctx->mctx, &ctx->pctx, NULL, NULL, ctx->key);
948
0
        if (rv != 1) {
949
0
            SSH_LOG(SSH_LOG_TRACE, "EVP_DigestSignInit failed");
950
0
            goto out;
951
0
        }
952
0
    } else {
953
        /* Updating the key is easier but less obvious */
954
0
        rv = EVP_PKEY_CTX_ctrl(ctx->pctx,
955
0
                               -1,
956
0
                               EVP_PKEY_OP_SIGNCTX,
957
0
                               EVP_PKEY_CTRL_SET_MAC_KEY,
958
0
                               POLY1305_KEYLEN,
959
0
                               (void *)poly_key);
960
0
        if (rv <= 0) {
961
0
            SSH_LOG(SSH_LOG_TRACE, "EVP_PKEY_CTX_ctrl failed");
962
0
            goto out;
963
0
        }
964
0
    }
965
#else
966
    rv = EVP_MAC_init(ctx->mctx, poly_key, POLY1305_KEYLEN, NULL);
967
    if (rv != 1) {
968
        SSH_LOG(SSH_LOG_TRACE, "EVP_MAC_init failed");
969
        goto out;
970
    }
971
#endif /* OPENSSL_VERSION_NUMBER */
972
973
0
    ret = SSH_OK;
974
0
out:
975
0
    ssh_burn(poly_key, sizeof(poly_key));
976
0
    return ret;
977
0
}
978
979
static int
980
chacha20_poly1305_aead_decrypt_length(struct ssh_cipher_struct *cipher,
981
                                      void *in,
982
                                      uint8_t *out,
983
                                      size_t len,
984
                                      uint64_t seq)
985
0
{
986
0
    struct chacha20_poly1305_keysched *ctx = cipher->chacha20_schedule;
987
0
    int rv, outlen;
988
989
0
    if (len < sizeof(uint32_t)) {
990
0
        return SSH_ERROR;
991
0
    }
992
993
#ifdef DEBUG_CRYPTO
994
    ssh_log_hexdump("encrypted length", (uint8_t *)in, sizeof(uint32_t));
995
#endif /* DEBUG_CRYPTO */
996
997
    /* Set IV for the header EVP */
998
0
    rv = chacha20_poly1305_set_iv(cipher, seq, 0);
999
0
    if (rv != SSH_OK) {
1000
0
        return SSH_ERROR;
1001
0
    }
1002
1003
0
    rv = EVP_CipherUpdate(ctx->header_evp, out, &outlen, in, (int)len);
1004
0
    if (rv != 1 || outlen != sizeof(uint32_t)) {
1005
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_CipherUpdate failed");
1006
0
        return SSH_ERROR;
1007
0
    }
1008
1009
#ifdef DEBUG_CRYPTO
1010
    ssh_log_hexdump("deciphered length", out, sizeof(uint32_t));
1011
#endif /* DEBUG_CRYPTO */
1012
1013
0
    rv = EVP_CipherFinal_ex(ctx->header_evp, out + outlen, &outlen);
1014
0
    if (rv != 1 || outlen != 0) {
1015
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_CipherFinal_ex failed");
1016
0
        return SSH_ERROR;
1017
0
    }
1018
1019
0
    return SSH_OK;
1020
0
}
1021
1022
static int chacha20_poly1305_aead_decrypt(struct ssh_cipher_struct *cipher,
1023
                                          void *complete_packet,
1024
                                          uint8_t *out,
1025
                                          size_t encrypted_size,
1026
                                          uint64_t seq)
1027
0
{
1028
0
    struct chacha20_poly1305_keysched *ctx = cipher->chacha20_schedule;
1029
0
    uint8_t *mac =
1030
0
        (uint8_t *)complete_packet + sizeof(uint32_t) + encrypted_size;
1031
0
    uint8_t tag[POLY1305_TAGLEN] = {0};
1032
0
    int ret = SSH_ERROR;
1033
0
    int rv, cmp, len = 0;
1034
0
#if !defined(LIBRESSL_VERSION_NUMBER)
1035
0
    size_t taglen = POLY1305_TAGLEN;
1036
0
#endif
1037
1038
    /* Prepare the Poly1305 key */
1039
0
    rv = chacha20_poly1305_packet_setup(cipher, seq, 0);
1040
0
    if (rv != SSH_OK) {
1041
0
        SSH_LOG(SSH_LOG_TRACE, "Failed to setup packet");
1042
0
        goto out;
1043
0
    }
1044
1045
#ifdef DEBUG_CRYPTO
1046
    ssh_log_hexdump("received mac", mac, POLY1305_TAGLEN);
1047
#endif /* DEBUG_CRYPTO */
1048
1049
    /* Calculate MAC of received data */
1050
#if defined(LIBRESSL_VERSION_NUMBER)
1051
    CRYPTO_poly1305_update(&ctx->poly_ctx,
1052
                           complete_packet,
1053
                           encrypted_size + sizeof(uint32_t));
1054
    CRYPTO_poly1305_finish(&ctx->poly_ctx, tag);
1055
1056
#elif OPENSSL_VERSION_NUMBER < 0x30000000L
1057
0
    rv = EVP_DigestSignUpdate(ctx->mctx, complete_packet,
1058
0
                              encrypted_size + sizeof(uint32_t));
1059
0
    if (rv != 1) {
1060
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_DigestSignUpdate failed");
1061
0
        goto out;
1062
0
    }
1063
1064
0
    rv = EVP_DigestSignFinal(ctx->mctx, tag, &taglen);
1065
0
    if (rv != 1) {
1066
0
        SSH_LOG(SSH_LOG_TRACE, "poly1305 verify error");
1067
0
        goto out;
1068
0
    }
1069
#else
1070
    rv = EVP_MAC_update(ctx->mctx,
1071
                        complete_packet,
1072
                        encrypted_size + sizeof(uint32_t));
1073
    if (rv != 1) {
1074
        SSH_LOG(SSH_LOG_TRACE, "EVP_MAC_update failed");
1075
        goto out;
1076
    }
1077
1078
    rv = EVP_MAC_final(ctx->mctx, tag, &taglen, POLY1305_TAGLEN);
1079
    if (rv != 1) {
1080
        SSH_LOG(SSH_LOG_TRACE, "EVP_MAC_final failed");
1081
        goto out;
1082
    }
1083
#endif /* OPENSSL_VERSION_NUMBER */
1084
1085
#ifdef DEBUG_CRYPTO
1086
    ssh_log_hexdump("calculated mac", tag, POLY1305_TAGLEN);
1087
#endif /* DEBUG_CRYPTO */
1088
1089
    /* Verify the calculated MAC matches the attached MAC */
1090
0
    cmp = CRYPTO_memcmp(tag, mac, POLY1305_TAGLEN);
1091
0
    if (cmp != 0) {
1092
        /* mac error */
1093
0
        SSH_LOG(SSH_LOG_PACKET, "poly1305 verify error");
1094
0
        return SSH_ERROR;
1095
0
    }
1096
1097
    /* Decrypt the message */
1098
0
    rv = EVP_CipherUpdate(ctx->main_evp,
1099
0
                          out,
1100
0
                          &len,
1101
0
                          (uint8_t *)complete_packet + sizeof(uint32_t),
1102
0
                          (int)encrypted_size);
1103
0
    if (rv != 1) {
1104
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_CipherUpdate failed");
1105
0
        goto out;
1106
0
    }
1107
1108
0
    rv = EVP_CipherFinal_ex(ctx->main_evp, out + len, &len);
1109
0
    if (rv != 1 || len != 0) {
1110
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_CipherFinal_ex failed");
1111
0
        goto out;
1112
0
    }
1113
1114
0
    ret = SSH_OK;
1115
0
out:
1116
0
    return ret;
1117
0
}
1118
1119
static void chacha20_poly1305_aead_encrypt(struct ssh_cipher_struct *cipher,
1120
                                           void *in,
1121
                                           void *out,
1122
                                           size_t len,
1123
                                           uint8_t *tag,
1124
                                           uint64_t seq)
1125
0
{
1126
0
    struct ssh_packet_header *in_packet = in, *out_packet = out;
1127
0
    struct chacha20_poly1305_keysched *ctx = cipher->chacha20_schedule;
1128
0
#if !defined(LIBRESSL_VERSION_NUMBER)
1129
0
    size_t taglen = POLY1305_TAGLEN;
1130
0
#endif
1131
0
    int ret, outlen = 0;
1132
1133
    /* Prepare the Poly1305 key */
1134
0
    ret = chacha20_poly1305_packet_setup(cipher, seq, 1);
1135
0
    if (ret != SSH_OK) {
1136
0
        SSH_LOG(SSH_LOG_TRACE, "Failed to setup packet");
1137
0
        return;
1138
0
    }
1139
1140
#ifdef DEBUG_CRYPTO
1141
    ssh_log_hexdump("plaintext length",
1142
                    (unsigned char *)&in_packet->length,
1143
                    sizeof(uint32_t));
1144
#endif /* DEBUG_CRYPTO */
1145
    /* step 2, encrypt length field */
1146
0
    ret = EVP_CipherUpdate(ctx->header_evp,
1147
0
                           (unsigned char *)&out_packet->length,
1148
0
                           &outlen,
1149
0
                           (unsigned char *)&in_packet->length,
1150
0
                           sizeof(uint32_t));
1151
0
    if (ret != 1 || outlen != sizeof(uint32_t)) {
1152
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_CipherUpdate failed");
1153
0
        return;
1154
0
    }
1155
#ifdef DEBUG_CRYPTO
1156
    ssh_log_hexdump("encrypted length",
1157
                    (unsigned char *)&out_packet->length,
1158
                    outlen);
1159
#endif /* DEBUG_CRYPTO */
1160
0
    ret = EVP_CipherFinal_ex(ctx->header_evp, (uint8_t *)out + outlen, &outlen);
1161
0
    if (ret != 1 || outlen != 0) {
1162
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_EncryptFinal_ex failed");
1163
0
        return;
1164
0
    }
1165
1166
    /* step 3, encrypt packet payload (main_evp counter == 1) */
1167
    /* We already did encrypt one block so the counter should be in the correct position */
1168
0
    ret = EVP_CipherUpdate(ctx->main_evp,
1169
0
                           out_packet->payload,
1170
0
                           &outlen,
1171
0
                           in_packet->payload,
1172
0
                           (int)(len - sizeof(uint32_t)));
1173
0
    if (ret != 1) {
1174
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_CipherUpdate failed");
1175
0
        return;
1176
0
    }
1177
1178
    /* step 4, compute the MAC */
1179
#if defined(LIBRESSL_VERSION_NUMBER)
1180
1181
    CRYPTO_poly1305_update(&ctx->poly_ctx,
1182
                           (const unsigned char *)out_packet,
1183
                           len);
1184
    CRYPTO_poly1305_finish(&ctx->poly_ctx, tag);
1185
#elif OPENSSL_VERSION_NUMBER < 0x30000000L
1186
0
    ret = EVP_DigestSignUpdate(ctx->mctx, out_packet, len);
1187
0
    if (ret <= 0) {
1188
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_DigestSignUpdate failed");
1189
0
        return;
1190
0
    }
1191
0
    ret = EVP_DigestSignFinal(ctx->mctx, tag, &taglen);
1192
0
    if (ret <= 0) {
1193
0
        SSH_LOG(SSH_LOG_TRACE, "EVP_DigestSignFinal failed");
1194
0
        return;
1195
0
    }
1196
#else
1197
    ret = EVP_MAC_update(ctx->mctx, (void *)out_packet, len);
1198
    if (ret != 1) {
1199
        SSH_LOG(SSH_LOG_TRACE, "EVP_MAC_update failed");
1200
        return;
1201
    }
1202
1203
    ret = EVP_MAC_final(ctx->mctx, tag, &taglen, POLY1305_TAGLEN);
1204
    if (ret != 1) {
1205
        SSH_LOG(SSH_LOG_TRACE, "EVP_MAC_final failed");
1206
        return;
1207
    }
1208
#endif /* OPENSSL_VERSION_NUMBER */
1209
0
}
1210
#endif /* HAVE_OPENSSL_EVP_CHACHA20 */
1211
1212
#ifdef WITH_INSECURE_NONE
1213
static void none_crypt(UNUSED_PARAM(struct ssh_cipher_struct *cipher),
1214
                       void *in,
1215
                       void *out,
1216
                       size_t len)
1217
194k
{
1218
194k
    memcpy(out, in, len);
1219
194k
}
1220
#endif /* WITH_INSECURE_NONE */
1221
1222
/*
1223
 * The table of supported ciphers
1224
 */
1225
static struct ssh_cipher_struct ssh_ciphertab[] = {
1226
#ifdef HAVE_BLOWFISH
1227
    {
1228
        .name = "blowfish-cbc",
1229
        .blocksize = 8,
1230
        .ciphertype = SSH_BLOWFISH_CBC,
1231
        .keysize = 128,
1232
        .set_encrypt_key = evp_cipher_set_encrypt_key,
1233
        .set_decrypt_key = evp_cipher_set_decrypt_key,
1234
        .encrypt = evp_cipher_encrypt,
1235
        .decrypt = evp_cipher_decrypt,
1236
        .cleanup = evp_cipher_cleanup,
1237
    },
1238
#endif /* HAVE_BLOWFISH */
1239
#ifdef HAS_AES
1240
    {
1241
        .name = "aes128-ctr",
1242
        .blocksize = AES_BLOCK_SIZE,
1243
        .ciphertype = SSH_AES128_CTR,
1244
        .keysize = 128,
1245
        .set_encrypt_key = evp_cipher_set_encrypt_key,
1246
        .set_decrypt_key = evp_cipher_set_decrypt_key,
1247
        .encrypt = evp_cipher_encrypt,
1248
        .decrypt = evp_cipher_decrypt,
1249
        .cleanup = evp_cipher_cleanup,
1250
    },
1251
    {
1252
        .name = "aes192-ctr",
1253
        .blocksize = AES_BLOCK_SIZE,
1254
        .ciphertype = SSH_AES192_CTR,
1255
        .keysize = 192,
1256
        .set_encrypt_key = evp_cipher_set_encrypt_key,
1257
        .set_decrypt_key = evp_cipher_set_decrypt_key,
1258
        .encrypt = evp_cipher_encrypt,
1259
        .decrypt = evp_cipher_decrypt,
1260
        .cleanup = evp_cipher_cleanup,
1261
    },
1262
    {
1263
        .name = "aes256-ctr",
1264
        .blocksize = AES_BLOCK_SIZE,
1265
        .ciphertype = SSH_AES256_CTR,
1266
        .keysize = 256,
1267
        .set_encrypt_key = evp_cipher_set_encrypt_key,
1268
        .set_decrypt_key = evp_cipher_set_decrypt_key,
1269
        .encrypt = evp_cipher_encrypt,
1270
        .decrypt = evp_cipher_decrypt,
1271
        .cleanup = evp_cipher_cleanup,
1272
    },
1273
    {
1274
        .name = "aes128-cbc",
1275
        .blocksize = AES_BLOCK_SIZE,
1276
        .ciphertype = SSH_AES128_CBC,
1277
        .keysize = 128,
1278
        .set_encrypt_key = evp_cipher_set_encrypt_key,
1279
        .set_decrypt_key = evp_cipher_set_decrypt_key,
1280
        .encrypt = evp_cipher_encrypt,
1281
        .decrypt = evp_cipher_decrypt,
1282
        .cleanup = evp_cipher_cleanup,
1283
    },
1284
    {
1285
        .name = "aes192-cbc",
1286
        .blocksize = AES_BLOCK_SIZE,
1287
        .ciphertype = SSH_AES192_CBC,
1288
        .keysize = 192,
1289
        .set_encrypt_key = evp_cipher_set_encrypt_key,
1290
        .set_decrypt_key = evp_cipher_set_decrypt_key,
1291
        .encrypt = evp_cipher_encrypt,
1292
        .decrypt = evp_cipher_decrypt,
1293
        .cleanup = evp_cipher_cleanup,
1294
    },
1295
    {
1296
        .name = "aes256-cbc",
1297
        .blocksize = AES_BLOCK_SIZE,
1298
        .ciphertype = SSH_AES256_CBC,
1299
        .keysize = 256,
1300
        .set_encrypt_key = evp_cipher_set_encrypt_key,
1301
        .set_decrypt_key = evp_cipher_set_decrypt_key,
1302
        .encrypt = evp_cipher_encrypt,
1303
        .decrypt = evp_cipher_decrypt,
1304
        .cleanup = evp_cipher_cleanup,
1305
    },
1306
    {
1307
        .name = "aes128-gcm@openssh.com",
1308
        .blocksize = AES_BLOCK_SIZE,
1309
        .lenfield_blocksize = 4, /* not encrypted, but authenticated */
1310
        .ciphertype = SSH_AEAD_AES128_GCM,
1311
        .keysize = 128,
1312
        .tag_size = AES_GCM_TAGLEN,
1313
        .set_encrypt_key = evp_cipher_set_encrypt_key,
1314
        .set_decrypt_key = evp_cipher_set_decrypt_key,
1315
        .aead_encrypt = evp_cipher_aead_encrypt,
1316
        .aead_decrypt_length = evp_cipher_aead_get_length,
1317
        .aead_decrypt = evp_cipher_aead_decrypt,
1318
        .cleanup = evp_cipher_cleanup,
1319
    },
1320
    {
1321
        .name = "aes256-gcm@openssh.com",
1322
        .blocksize = AES_BLOCK_SIZE,
1323
        .lenfield_blocksize = 4, /* not encrypted, but authenticated */
1324
        .ciphertype = SSH_AEAD_AES256_GCM,
1325
        .keysize = 256,
1326
        .tag_size = AES_GCM_TAGLEN,
1327
        .set_encrypt_key = evp_cipher_set_encrypt_key,
1328
        .set_decrypt_key = evp_cipher_set_decrypt_key,
1329
        .aead_encrypt = evp_cipher_aead_encrypt,
1330
        .aead_decrypt_length = evp_cipher_aead_get_length,
1331
        .aead_decrypt = evp_cipher_aead_decrypt,
1332
        .cleanup = evp_cipher_cleanup,
1333
    },
1334
#endif /* HAS_AES */
1335
#ifdef HAS_DES
1336
    {
1337
        .name = "3des-cbc",
1338
        .blocksize = 8,
1339
        .ciphertype = SSH_3DES_CBC,
1340
        .keysize = 192,
1341
        .set_encrypt_key = evp_cipher_set_encrypt_key,
1342
        .set_decrypt_key = evp_cipher_set_decrypt_key,
1343
        .encrypt = evp_cipher_encrypt,
1344
        .decrypt = evp_cipher_decrypt,
1345
        .cleanup = evp_cipher_cleanup,
1346
    },
1347
#endif /* HAS_DES */
1348
    {
1349
#ifdef HAVE_OPENSSL_EVP_CHACHA20
1350
        .ciphertype = SSH_AEAD_CHACHA20_POLY1305,
1351
        .name = "chacha20-poly1305@openssh.com",
1352
        .blocksize = CHACHA20_BLOCKSIZE / 8,
1353
        .lenfield_blocksize = 4,
1354
        .keylen = sizeof(struct chacha20_poly1305_keysched),
1355
        .keysize = 2 * CHACHA20_KEYLEN * 8,
1356
        .tag_size = POLY1305_TAGLEN,
1357
        .set_encrypt_key = chacha20_poly1305_set_key,
1358
        .set_decrypt_key = chacha20_poly1305_set_key,
1359
        .aead_encrypt = chacha20_poly1305_aead_encrypt,
1360
        .aead_decrypt_length = chacha20_poly1305_aead_decrypt_length,
1361
        .aead_decrypt = chacha20_poly1305_aead_decrypt,
1362
        .cleanup = chacha20_poly1305_cleanup
1363
#else
1364
        .name = "chacha20-poly1305@openssh.com"
1365
#endif /* HAVE_OPENSSL_EVP_CHACHA20 */
1366
    },
1367
#ifdef WITH_INSECURE_NONE
1368
    {
1369
        .name = "none",
1370
        .blocksize = 8,
1371
        .keysize = 0,
1372
        .encrypt = none_crypt,
1373
        .decrypt = none_crypt,
1374
    },
1375
#endif /* WITH_INSECURE_NONE */
1376
    {
1377
        .name = NULL,
1378
    },
1379
};
1380
1381
struct ssh_cipher_struct *ssh_get_ciphertab(void)
1382
19.0k
{
1383
19.0k
    return ssh_ciphertab;
1384
19.0k
}
1385
1386
/**
1387
 * @internal
1388
 * @brief Initialize libcrypto's subsystem
1389
 */
1390
int ssh_crypto_init(void)
1391
36
{
1392
#ifndef HAVE_OPENSSL_EVP_CHACHA20
1393
    size_t i;
1394
#endif
1395
1396
36
    if (libcrypto_initialized) {
1397
0
        return SSH_OK;
1398
0
    }
1399
36
    if (OpenSSL_version_num() != OPENSSL_VERSION_NUMBER) {
1400
0
        SSH_LOG(SSH_LOG_DEBUG,
1401
0
                "libssh compiled with %s "
1402
0
                "headers, currently running with %s.",
1403
0
                OPENSSL_VERSION_TEXT,
1404
0
                OpenSSL_version(OpenSSL_version_num()));
1405
0
    }
1406
#ifdef CAN_DISABLE_AESNI
1407
    /*
1408
     * disable AES-NI when running within Valgrind, because they generate
1409
     * too many "uninitialized memory access" false positives
1410
     */
1411
    if (RUNNING_ON_VALGRIND) {
1412
        SSH_LOG(SSH_LOG_INFO, "Running within Valgrind, disabling AES-NI");
1413
        /* Bit #57 denotes AES-NI instruction set extension */
1414
        OPENSSL_ia32cap &= ~(1LL << 57);
1415
    }
1416
#endif /* CAN_DISABLE_AESNI */
1417
1418
#ifndef HAVE_OPENSSL_EVP_CHACHA20
1419
    for (i = 0; ssh_ciphertab[i].name != NULL; i++) {
1420
        int cmp;
1421
1422
        cmp = strcmp(ssh_ciphertab[i].name, "chacha20-poly1305@openssh.com");
1423
        if (cmp == 0) {
1424
            memcpy(&ssh_ciphertab[i],
1425
                   ssh_get_chacha20poly1305_cipher(),
1426
                   sizeof(struct ssh_cipher_struct));
1427
            break;
1428
        }
1429
    }
1430
#endif /* HAVE_OPENSSL_EVP_CHACHA20 */
1431
1432
36
    libcrypto_initialized = 1;
1433
1434
36
    return SSH_OK;
1435
36
}
1436
1437
/**
1438
 * @internal
1439
 * @brief Finalize libcrypto's subsystem
1440
 */
1441
void ssh_crypto_finalize(void)
1442
3.26k
{
1443
3.26k
    if (!libcrypto_initialized) {
1444
3.26k
        return;
1445
3.26k
    }
1446
1447
/* TODO this should finalize engine if it was started, but during atexit calls,
1448
 * we are crashing. AFAIK this is related to the dlopened pkcs11 modules calling
1449
 * the crypto cleanups earlier. */
1450
#if 0
1451
    if (engine != NULL) {
1452
        ENGINE_finish(engine);
1453
        ENGINE_free(engine);
1454
        engine = NULL;
1455
    }
1456
#endif
1457
#if defined(WITH_PKCS11_URI)
1458
#if defined(WITH_PKCS11_PROVIDER)
1459
    if (provider != NULL) {
1460
        OSSL_PROVIDER_unload(provider);
1461
        provider = NULL;
1462
    }
1463
#endif /* WITH_PKCS11_PROVIDER */
1464
#endif /* WITH_PKCS11_URI */
1465
1466
2
    libcrypto_initialized = 0;
1467
2
}
1468
1469
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
1470
/**
1471
 * @internal
1472
 * @brief Create EVP_PKEY from parameters
1473
 *
1474
 * @param[in] name Algorithm to use. For more info see manpage of
1475
 * EVP_PKEY_CTX_new_from_name
1476
 *
1477
 * @param[in] param_bld Constructed param builder for the pkey
1478
 *
1479
 * @param[out] pkey Created EVP_PKEY variable
1480
 *
1481
 * @param[in] selection Reference selections at man EVP_PKEY_FROMDATA
1482
 *
1483
 * @return 0 on success, -1 on error
1484
 */
1485
int evp_build_pkey(const char *name,
1486
                   OSSL_PARAM_BLD *param_bld,
1487
                   EVP_PKEY **pkey,
1488
                   int selection)
1489
{
1490
    int rc;
1491
    EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(NULL, name, NULL);
1492
    OSSL_PARAM *params = NULL;
1493
1494
    if (ctx == NULL) {
1495
        return -1;
1496
    }
1497
1498
    params = OSSL_PARAM_BLD_to_param(param_bld);
1499
    if (params == NULL) {
1500
        EVP_PKEY_CTX_free(ctx);
1501
        return -1;
1502
    }
1503
1504
    rc = EVP_PKEY_fromdata_init(ctx);
1505
    if (rc != 1) {
1506
        OSSL_PARAM_free(params);
1507
        EVP_PKEY_CTX_free(ctx);
1508
        return -1;
1509
    }
1510
1511
    rc = EVP_PKEY_fromdata(ctx, pkey, selection, params);
1512
    if (rc != 1) {
1513
        SSH_LOG(SSH_LOG_WARNING,
1514
                "Failed to import private key: %s\n",
1515
                ERR_error_string(ERR_get_error(), NULL));
1516
        OSSL_PARAM_free(params);
1517
        EVP_PKEY_CTX_free(ctx);
1518
        return -1;
1519
    }
1520
1521
    OSSL_PARAM_free(params);
1522
    EVP_PKEY_CTX_free(ctx);
1523
1524
    return SSH_OK;
1525
}
1526
1527
/**
1528
 * @brief creates a copy of EVP_PKEY
1529
 *
1530
 * @param[in] name Algorithm to use. For more info see manpage of
1531
 *                 EVP_PKEY_CTX_new_from_name
1532
 *
1533
 * @param[in] key Key being duplicated from
1534
 *
1535
 * @param[in] demote Same as at pki_key_dup, only the public
1536
 *                   part of the key gets duplicated if true
1537
 *
1538
 * @param[out] new_key The key where the duplicate is saved
1539
 *
1540
 * @return 0 on success, -1 on error
1541
 */
1542
static int
1543
evp_dup_pkey(const char *name, const ssh_key key, int demote, ssh_key new_key)
1544
{
1545
    int rc;
1546
    EVP_PKEY_CTX *ctx = NULL;
1547
    OSSL_PARAM *params = NULL;
1548
1549
    /* The simple case -- just reference the existing key */
1550
    if (!demote || (key->flags & SSH_KEY_FLAG_PRIVATE) == 0) {
1551
        rc = EVP_PKEY_up_ref(key->key);
1552
        if (rc != 1) {
1553
            return -1;
1554
        }
1555
        new_key->key = key->key;
1556
        return SSH_OK;
1557
    }
1558
1559
    /* demote == 1 */
1560
    ctx = EVP_PKEY_CTX_new_from_name(NULL, name, NULL);
1561
    if (ctx == NULL) {
1562
        return -1;
1563
    }
1564
1565
    rc = EVP_PKEY_todata(key->key, EVP_PKEY_PUBLIC_KEY, &params);
1566
    if (rc != 1) {
1567
        EVP_PKEY_CTX_free(ctx);
1568
        return -1;
1569
    }
1570
1571
    if (strcmp(name, "EC") == 0) {
1572
        OSSL_PARAM *locate_param = NULL;
1573
        /* For ECC keys provided by engine or provider, we need to have the
1574
         * explicit public part available, otherwise the key will not be
1575
         * usable */
1576
        locate_param = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PUB_KEY);
1577
        if (locate_param == NULL) {
1578
            EVP_PKEY_CTX_free(ctx);
1579
            OSSL_PARAM_free(params);
1580
            return -1;
1581
        }
1582
    }
1583
    rc = EVP_PKEY_fromdata_init(ctx);
1584
    if (rc != 1) {
1585
        EVP_PKEY_CTX_free(ctx);
1586
        OSSL_PARAM_free(params);
1587
        return -1;
1588
    }
1589
1590
    rc = EVP_PKEY_fromdata(ctx, &(new_key->key), EVP_PKEY_PUBLIC_KEY, params);
1591
    if (rc != 1) {
1592
        EVP_PKEY_CTX_free(ctx);
1593
        OSSL_PARAM_free(params);
1594
        return -1;
1595
    }
1596
1597
    OSSL_PARAM_free(params);
1598
    EVP_PKEY_CTX_free(ctx);
1599
1600
    return SSH_OK;
1601
}
1602
1603
int evp_dup_rsa_pkey(const ssh_key key, ssh_key new_key, int demote)
1604
{
1605
    return evp_dup_pkey(SN_rsa, key, demote, new_key);
1606
}
1607
1608
int evp_dup_ecdsa_pkey(const ssh_key key, ssh_key new_key, int demote)
1609
{
1610
    return evp_dup_pkey("EC", key, demote, new_key);
1611
}
1612
1613
int evp_dup_ed25519_pkey(const ssh_key key, ssh_key new_key, int demote)
1614
{
1615
    return evp_dup_pkey(SN_ED25519, key, demote, new_key);
1616
}
1617
1618
#endif /* OPENSSL_VERSION_NUMBER */
1619
1620
ssh_string pki_key_make_ecpoint_string(const EC_GROUP *g, const EC_POINT *p)
1621
1.98k
{
1622
1.98k
    ssh_string s = NULL;
1623
1.98k
    size_t len;
1624
1625
1.98k
    len = EC_POINT_point2oct(g,
1626
1.98k
                             p,
1627
1.98k
                             POINT_CONVERSION_UNCOMPRESSED,
1628
1.98k
                             NULL,
1629
1.98k
                             0,
1630
1.98k
                             NULL);
1631
1.98k
    if (len == 0) {
1632
0
        return NULL;
1633
0
    }
1634
1635
1.98k
    s = ssh_string_new(len);
1636
1.98k
    if (s == NULL) {
1637
0
        return NULL;
1638
0
    }
1639
1640
1.98k
    len = EC_POINT_point2oct(g,
1641
1.98k
                             p,
1642
1.98k
                             POINT_CONVERSION_UNCOMPRESSED,
1643
1.98k
                             ssh_string_data(s),
1644
1.98k
                             ssh_string_len(s),
1645
1.98k
                             NULL);
1646
1.98k
    if (len != ssh_string_len(s)) {
1647
0
        SSH_STRING_FREE(s);
1648
0
        return NULL;
1649
0
    }
1650
1651
1.98k
    return s;
1652
1.98k
}
1653
1654
int pki_key_ecgroup_name_to_nid(const char *group)
1655
0
{
1656
0
    if (strcmp(group, NISTP256) == 0 || strcmp(group, "secp256r1") == 0 ||
1657
0
        strcmp(group, SN_X9_62_prime256v1) == 0) {
1658
0
        return NID_X9_62_prime256v1;
1659
0
    } else if (strcmp(group, NISTP384) == 0 ||
1660
0
               strcmp(group, SN_secp384r1) == 0) {
1661
0
        return NID_secp384r1;
1662
0
    } else if (strcmp(group, NISTP521) == 0 ||
1663
0
               strcmp(group, SN_secp521r1) == 0) {
1664
0
        return NID_secp521r1;
1665
0
    }
1666
0
    return -1;
1667
0
}
1668
#endif /* LIBCRYPTO */