Coverage Report

Created: 2025-03-09 06:52

/src/cryptofuzz/modules/openssl/module.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "module.h"
2
#undef SHA1
3
#include <cryptofuzz/util.h>
4
#include <cryptofuzz/repository.h>
5
#include <fuzzing/datasource/id.hpp>
6
#include <openssl/aes.h>
7
#if defined(CRYPTOFUZZ_BORINGSSL)
8
#include <openssl/siphash.h>
9
#endif
10
#if !defined(CRYPTOFUZZ_BORINGSSL) && !defined(CRYPTOFUZZ_LIBRESSL) && !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_111) && !defined(CRYPTOFUZZ_OPENSSL_110) && !defined(CRYPTOFUZZ_OPENSSL_098)
11
#include <openssl/kdf.h>
12
#include <openssl/core_names.h>
13
#endif
14
#include <openssl/rand.h>
15
16
#if defined(CRYPTOFUZZ_BORINGSSL)
17
#include <openssl/curve25519.h>
18
#elif defined(CRYPTOFUZZ_LIBRESSL)
19
extern "C" {
20
    void X25519_public_from_private(uint8_t out_public_value[32], const uint8_t private_key[32]);
21
    int BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p,
22
            const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
23
    int BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1, const BIGNUM *p1,
24
            const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m,
25
            BN_CTX *ctx, BN_MONT_CTX *m_ctx);
26
}
27
#else
28
/* OpenSSL */
29
extern "C" { void ossl_x25519_public_from_private(uint8_t out_public_value[32], const uint8_t private_key[32]); }
30
extern "C" { void ossl_x448_public_from_private(uint8_t out_public_value[56], const uint8_t private_key[56]); }
31
#define X25519_public_from_private ossl_x25519_public_from_private
32
#define X448_public_from_private ossl_x448_public_from_private
33
#endif
34
35
#include "module_internal.h"
36
#include "bn_ops.h"
37
38
namespace cryptofuzz {
39
namespace module {
40
41
fuzzing::datasource::Datasource* global_ds = nullptr;
42
43
#if !defined(CRYPTOFUZZ_BORINGSSL) && !defined(CRYPTOFUZZ_LIBRESSL) && !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_098)
44
const RAND_METHOD* cryptofuzz_openssl_rand_default_method;
45
46
static int cryptofuzz_openssl_default_rand_bytes(unsigned char *buf, int num) {
47
    CF_ASSERT(cryptofuzz_openssl_rand_default_method != nullptr, "default rand method is NULL");
48
49
    return cryptofuzz_openssl_rand_default_method->bytes(buf, num);
50
}
51
52
static int cryptofuzz_openssl_rand_bytes(unsigned char *buf, int num)
53
{
54
    CF_ASSERT(num >= 0, "called rand_bytes with num < 0");
55
56
    if ( num == 0 ) {
57
        return 1;
58
    }
59
60
    if ( global_ds == nullptr ) {
61
        return cryptofuzz_openssl_default_rand_bytes(buf, num);
62
    }
63
64
    try {
65
        if ( global_ds->Get<bool>() == false ) {
66
            return cryptofuzz_openssl_default_rand_bytes(buf, num);
67
        }
68
    } catch ( fuzzing::datasource::Datasource::OutOfData& ) {
69
        return cryptofuzz_openssl_default_rand_bytes(buf, num);
70
    }
71
72
    try {
73
        const auto data = global_ds->GetData(0, num, num);
74
        memcpy(buf, data.data(), num);
75
        return 1;
76
    } catch ( fuzzing::datasource::Datasource::OutOfData& ) {
77
        return 0;
78
    }
79
}
80
81
static int cryptofuzz_openssl_rand_status(void)
82
{
83
    return 1;
84
}
85
86
static RAND_METHOD cryptofuzz_openssl_rand_method = {
87
    nullptr,
88
    cryptofuzz_openssl_rand_bytes,
89
    nullptr,
90
    nullptr,
91
    cryptofuzz_openssl_rand_bytes,
92
    cryptofuzz_openssl_rand_status
93
};
94
#endif
95
96
#if !defined(CRYPTOFUZZ_BORINGSSL) && !defined(CRYPTOFUZZ_LIBRESSL) && !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_098)
97
static void* OPENSSL_custom_malloc(size_t n, const char* file, int line) {
98
    (void)file;
99
    (void)line;
100
101
    return util::malloc(n);
102
}
103
104
static void* OPENSSL_custom_realloc(void* ptr, size_t n, const char* file, int line) {
105
    (void)file;
106
    (void)line;
107
108
    return util::realloc(ptr, n);
109
}
110
111
static void OPENSSL_custom_free(void* ptr, const char* file, int line) {
112
    (void)file;
113
    (void)line;
114
115
    util::free(ptr);
116
}
117
#endif
118
119
OpenSSL::OpenSSL(void) :
120
2
    Module("OpenSSL") {
121
#if !defined(CRYPTOFUZZ_BORINGSSL) && !defined(CRYPTOFUZZ_LIBRESSL) && !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_098)
122
    CF_ASSERT(
123
            CRYPTO_set_mem_functions(
124
                OPENSSL_custom_malloc,
125
                OPENSSL_custom_realloc,
126
                OPENSSL_custom_free) == 1,
127
    "Cannot set memory functions");
128
#endif
129
130
2
#if !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_098)
131
2
     OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, nullptr);
132
#else
133
     OpenSSL_add_all_algorithms();
134
#endif
135
136
#if !defined(CRYPTOFUZZ_BORINGSSL) && !defined(CRYPTOFUZZ_LIBRESSL) && !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_098)
137
     CF_ASSERT((cryptofuzz_openssl_rand_default_method = RAND_get_rand_method()) != nullptr,
138
         "Cannot retrieve default rand method");
139
     CF_ASSERT(RAND_set_rand_method(&cryptofuzz_openssl_rand_method) == 1,
140
         "Cannot set default rand method");
141
#endif
142
2
}
143
144
145
2.56k
bool OpenSSL::isAEAD(const EVP_CIPHER* ctx, const uint64_t cipherType) const {
146
#if defined(CRYPTOFUZZ_OPENSSL_098)
147
    (void)ctx;
148
    (void)cipherType;
149
    return false;
150
#else
151
2.56k
    bool ret = false;
152
153
    /* Special TLS AEAD ciphers that should not be attempted to use with aad/tag or
154
     * non-default iv/key sizes */
155
2.56k
    CF_CHECK_NE(cipherType, CF_CIPHER("RC4_HMAC_MD5"));
156
2.56k
    CF_CHECK_NE(cipherType, CF_CIPHER("AES_128_CBC_HMAC_SHA1"));
157
2.56k
    CF_CHECK_NE(cipherType, CF_CIPHER("AES_256_CBC_HMAC_SHA1"));
158
2.56k
    CF_CHECK_NE(cipherType, CF_CIPHER("AES_128_CBC_HMAC_SHA256"));
159
2.56k
    CF_CHECK_NE(cipherType, CF_CIPHER("AES_256_CBC_HMAC_SHA256"));
160
161
2.56k
    ret = EVP_CIPHER_flags(ctx) & EVP_CIPH_FLAG_AEAD_CIPHER;
162
163
2.56k
end:
164
2.56k
    return ret;
165
2.56k
#endif
166
2.56k
}
167
168
2.05k
const EVP_MD* OpenSSL::toEVPMD(const component::DigestType& digestType) const {
169
2.05k
    using fuzzing::datasource::ID;
170
171
2.05k
    static const std::map<uint64_t, const EVP_MD*> LUT = {
172
#if defined(CRYPTOFUZZ_BORINGSSL)
173
        { CF_DIGEST("SHA1"), EVP_sha1() },
174
        { CF_DIGEST("SHA224"), EVP_sha224() },
175
        { CF_DIGEST("SHA256"), EVP_sha256() },
176
        { CF_DIGEST("SHA384"), EVP_sha384() },
177
        { CF_DIGEST("SHA512"), EVP_sha512() },
178
        { CF_DIGEST("MD4"), EVP_md4() },
179
        { CF_DIGEST("MD5"), EVP_md5() },
180
        { CF_DIGEST("MD5_SHA1"), EVP_md5_sha1() },
181
        { CF_DIGEST("SHA512-256"), EVP_sha512_256() },
182
        { CF_DIGEST("BLAKE2B256"), EVP_blake2b256() },
183
#elif defined(CRYPTOFUZZ_LIBRESSL)
184
2.05k
        { CF_DIGEST("SHA1"), EVP_sha1() },
185
2.05k
        { CF_DIGEST("SHA224"), EVP_sha224() },
186
2.05k
        { CF_DIGEST("SHA256"), EVP_sha256() },
187
2.05k
        { CF_DIGEST("SHA384"), EVP_sha384() },
188
2.05k
        { CF_DIGEST("SHA512"), EVP_sha512() },
189
2.05k
        { CF_DIGEST("MD4"), EVP_md4() },
190
2.05k
        { CF_DIGEST("MD5"), EVP_md5() },
191
2.05k
        { CF_DIGEST("MD5_SHA1"), EVP_md5_sha1() },
192
2.05k
        { CF_DIGEST("RIPEMD160"), EVP_ripemd160() },
193
2.05k
        { CF_DIGEST("SM3"), EVP_sm3() },
194
2.05k
        { CF_DIGEST("SHA3-224"), EVP_sha3_224() },
195
2.05k
        { CF_DIGEST("SHA3-256"), EVP_sha3_256() },
196
2.05k
        { CF_DIGEST("SHA3-384"), EVP_sha3_384() },
197
2.05k
        { CF_DIGEST("SHA3-512"), EVP_sha3_512() },
198
2.05k
        { CF_DIGEST("SHA512-224"), EVP_sha512_224() },
199
2.05k
        { CF_DIGEST("SHA512-256"), EVP_sha512_256() },
200
#elif defined(CRYPTOFUZZ_OPENSSL_102)
201
        { CF_DIGEST("SHA1"), EVP_sha1() },
202
        { CF_DIGEST("SHA224"), EVP_sha224() },
203
        { CF_DIGEST("SHA256"), EVP_sha256() },
204
        { CF_DIGEST("SHA384"), EVP_sha384() },
205
        { CF_DIGEST("SHA512"), EVP_sha512() },
206
        { CF_DIGEST("MD2"), EVP_md2() },
207
        { CF_DIGEST("MD4"), EVP_md4() },
208
        { CF_DIGEST("MD5"), EVP_md5() },
209
        { CF_DIGEST("MDC2"), EVP_mdc2() },
210
        { CF_DIGEST("RIPEMD160"), EVP_ripemd160() },
211
        { CF_DIGEST("WHIRLPOOL"), EVP_whirlpool() },
212
#elif defined(CRYPTOFUZZ_OPENSSL_110)
213
        { CF_DIGEST("SHA1"), EVP_sha1() },
214
        { CF_DIGEST("SHA224"), EVP_sha224() },
215
        { CF_DIGEST("SHA256"), EVP_sha256() },
216
        { CF_DIGEST("SHA384"), EVP_sha384() },
217
        { CF_DIGEST("SHA512"), EVP_sha512() },
218
        { CF_DIGEST("MD2"), EVP_md2() },
219
        { CF_DIGEST("MD4"), EVP_md4() },
220
        { CF_DIGEST("MD5"), EVP_md5() },
221
        { CF_DIGEST("MD5_SHA1"), EVP_md5_sha1() },
222
        { CF_DIGEST("MDC2"), EVP_mdc2() },
223
        { CF_DIGEST("RIPEMD160"), EVP_ripemd160() },
224
        { CF_DIGEST("WHIRLPOOL"), EVP_whirlpool() },
225
        { CF_DIGEST("BLAKE2B512"), EVP_blake2b512() },
226
        { CF_DIGEST("BLAKE2S256"), EVP_blake2s256() },
227
#elif defined(CRYPTOFUZZ_OPENSSL_098)
228
        { CF_DIGEST("SHA1"), EVP_sha1() },
229
        { CF_DIGEST("SHA224"), EVP_sha224() },
230
        { CF_DIGEST("SHA256"), EVP_sha256() },
231
        { CF_DIGEST("SHA384"), EVP_sha384() },
232
        { CF_DIGEST("SHA512"), EVP_sha512() },
233
        { CF_DIGEST("MD2"), EVP_md2() },
234
        { CF_DIGEST("MD4"), EVP_md4() },
235
        { CF_DIGEST("MD5"), EVP_md5() },
236
        { CF_DIGEST("RIPEMD160"), EVP_ripemd160() },
237
#else
238
        { CF_DIGEST("SHA1"), EVP_sha1() },
239
        { CF_DIGEST("SHA224"), EVP_sha224() },
240
        { CF_DIGEST("SHA256"), EVP_sha256() },
241
        { CF_DIGEST("SHA384"), EVP_sha384() },
242
        { CF_DIGEST("SHA512"), EVP_sha512() },
243
        { CF_DIGEST("MD2"), EVP_md2() },
244
        { CF_DIGEST("MD4"), EVP_md4() },
245
        { CF_DIGEST("MD5"), EVP_md5() },
246
        { CF_DIGEST("MD5_SHA1"), EVP_md5_sha1() },
247
        { CF_DIGEST("MDC2"), EVP_mdc2() },
248
        { CF_DIGEST("RIPEMD160"), EVP_ripemd160() },
249
        { CF_DIGEST("WHIRLPOOL"), EVP_whirlpool() },
250
        { CF_DIGEST("SM3"), EVP_sm3() },
251
        { CF_DIGEST("BLAKE2B512"), EVP_blake2b512() },
252
        { CF_DIGEST("BLAKE2S256"), EVP_blake2s256() },
253
        { CF_DIGEST("SHAKE128"), EVP_shake128() },
254
        { CF_DIGEST("SHAKE256"), EVP_shake256() },
255
        { CF_DIGEST("SHA3-224"), EVP_sha3_224() },
256
        { CF_DIGEST("SHA3-256"), EVP_sha3_256() },
257
        { CF_DIGEST("SHA3-384"), EVP_sha3_384() },
258
        { CF_DIGEST("SHA3-512"), EVP_sha3_512() },
259
        { CF_DIGEST("SHA512-224"), EVP_sha512_224() },
260
        { CF_DIGEST("SHA512-256"), EVP_sha512_256() },
261
#endif
262
2.05k
    };
263
264
2.05k
    if ( LUT.find(digestType.Get()) == LUT.end() ) {
265
582
        return nullptr;
266
582
    }
267
268
1.46k
    return LUT.at(digestType.Get());
269
2.05k
}
270
271
6.24k
const EVP_CIPHER* OpenSSL::toEVPCIPHER(const component::SymmetricCipherType cipherType) const {
272
6.24k
    using fuzzing::datasource::ID;
273
274
6.24k
    switch ( cipherType.Get() ) {
275
#if defined(CRYPTOFUZZ_BORINGSSL)
276
        case CF_CIPHER("DES_CBC"):
277
            return EVP_des_cbc();
278
        case CF_CIPHER("DES_EDE_CBC"):
279
            return EVP_des_ede_cbc();
280
        case CF_CIPHER("DES_EDE3_CBC"):
281
            return EVP_des_ede3_cbc();
282
        case CF_CIPHER("DES_ECB"):
283
            return EVP_des_ecb();
284
        case CF_CIPHER("DES_EDE"):
285
            return EVP_des_ede();
286
        case CF_CIPHER("DES_EDE3"):
287
            return EVP_des_ede3();
288
        case CF_CIPHER("RC2_CBC"):
289
            return EVP_rc2_cbc();
290
        case CF_CIPHER("RC2_40_CBC"):
291
            return EVP_rc2_40_cbc();
292
        case CF_CIPHER("AES_128_ECB"):
293
            return EVP_aes_128_ecb();
294
        case CF_CIPHER("AES_128_CBC"):
295
            return EVP_aes_128_cbc();
296
        case CF_CIPHER("AES_128_OFB"):
297
            return EVP_aes_128_ofb();
298
        case CF_CIPHER("AES_128_CTR"):
299
            return EVP_aes_128_ctr();
300
        case CF_CIPHER("AES_128_GCM"):
301
            return EVP_aes_128_gcm();
302
        case CF_CIPHER("AES_192_ECB"):
303
            return EVP_aes_192_ecb();
304
        case CF_CIPHER("AES_192_CBC"):
305
            return EVP_aes_192_cbc();
306
        case CF_CIPHER("AES_192_OFB"):
307
            return EVP_aes_192_ofb();
308
        case CF_CIPHER("AES_192_CTR"):
309
            return EVP_aes_192_ctr();
310
        case CF_CIPHER("AES_192_GCM"):
311
            return EVP_aes_192_gcm();
312
        case CF_CIPHER("AES_256_ECB"):
313
            return EVP_aes_256_ecb();
314
        case CF_CIPHER("AES_256_CBC"):
315
            return EVP_aes_256_cbc();
316
        case CF_CIPHER("AES_256_OFB"):
317
            return EVP_aes_256_ofb();
318
        case CF_CIPHER("AES_256_CTR"):
319
            return EVP_aes_256_ctr();
320
        case CF_CIPHER("AES_256_GCM"):
321
            return EVP_aes_256_gcm();
322
        case CF_CIPHER("RC4"):
323
            return EVP_rc4();
324
#if defined(CRYPTOFUZZ_AWSLC)
325
        case CF_CIPHER("AES_256_XTS"):
326
            return EVP_aes_256_xts();
327
#endif
328
#elif defined(CRYPTOFUZZ_LIBRESSL)
329
19
        case CF_CIPHER("DES_CFB"):
330
19
            return EVP_des_cfb();
331
34
        case CF_CIPHER("DES_CFB1"):
332
34
            return EVP_des_cfb1();
333
35
        case CF_CIPHER("DES_CFB8"):
334
35
            return EVP_des_cfb8();
335
14
        case CF_CIPHER("DES_EDE_CFB"):
336
14
            return EVP_des_ede_cfb();
337
46
        case CF_CIPHER("DES_EDE3_CFB"):
338
46
            return EVP_des_ede3_cfb();
339
19
        case CF_CIPHER("DES_EDE3_CFB1"):
340
19
            return EVP_des_ede3_cfb1();
341
36
        case CF_CIPHER("DES_EDE3_CFB8"):
342
36
            return EVP_des_ede3_cfb8();
343
35
        case CF_CIPHER("DES_OFB"):
344
35
            return EVP_des_ofb();
345
29
        case CF_CIPHER("DES_EDE_OFB"):
346
29
            return EVP_des_ede_ofb();
347
36
        case CF_CIPHER("DES_EDE3_OFB"):
348
36
            return EVP_des_ede3_ofb();
349
3
        case CF_CIPHER("DESX_A_CBC"):
350
3
            return EVP_desx_cbc();
351
105
        case CF_CIPHER("DES_CBC"):
352
105
            return EVP_des_cbc();
353
56
        case CF_CIPHER("DES_EDE_CBC"):
354
56
            return EVP_des_ede_cbc();
355
52
        case CF_CIPHER("DES_EDE3_CBC"):
356
52
            return EVP_des_ede3_cbc();
357
14
        case CF_CIPHER("DES_ECB"):
358
14
            return EVP_des_ecb();
359
101
        case CF_CIPHER("DES_EDE"):
360
101
            return EVP_des_ede();
361
100
        case CF_CIPHER("DES_EDE3"):
362
100
            return EVP_des_ede3();
363
72
        case CF_CIPHER("RC4"):
364
72
            return EVP_rc4();
365
6
        case CF_CIPHER("RC4_40"):
366
6
            return EVP_rc4_40();
367
#if 0
368
        case CF_CIPHER("IDEA_ECB"):
369
            return EVP_idea_ecb();
370
        case CF_CIPHER("IDEA_CFB"):
371
            return EVP_idea_cfb();
372
        case CF_CIPHER("IDEA_OFB"):
373
            return EVP_idea_ofb();
374
        case CF_CIPHER("IDEA_CBC"):
375
            return EVP_idea_cbc();
376
#endif
377
27
        case CF_CIPHER("SM4_ECB"):
378
27
            return EVP_sm4_ecb();
379
152
        case CF_CIPHER("SM4_CBC"):
380
152
            return EVP_sm4_cbc();
381
76
        case CF_CIPHER("SM4_CFB"):
382
76
            return EVP_sm4_cfb();
383
47
        case CF_CIPHER("SM4_OFB"):
384
47
            return EVP_sm4_ofb();
385
107
        case CF_CIPHER("SM4_CTR"):
386
107
            return EVP_sm4_ctr();
387
23
        case CF_CIPHER("RC2_ECB"):
388
23
            return EVP_rc2_ecb();
389
52
        case CF_CIPHER("RC2_CFB"):
390
52
            return EVP_rc2_cfb();
391
20
        case CF_CIPHER("RC2_OFB"):
392
20
            return EVP_rc2_ofb();
393
71
        case CF_CIPHER("RC2_CBC"):
394
71
            return EVP_rc2_cbc();
395
69
        case CF_CIPHER("RC2_40_CBC"):
396
69
            return EVP_rc2_40_cbc();
397
57
        case CF_CIPHER("RC2_64_CBC"):
398
57
            return EVP_rc2_64_cbc();
399
115
        case CF_CIPHER("BF_ECB"):
400
115
            return EVP_bf_ecb();
401
91
        case CF_CIPHER("BF_CFB"):
402
91
            return EVP_bf_cfb();
403
43
        case CF_CIPHER("BF_OFB"):
404
43
            return EVP_bf_ofb();
405
114
        case CF_CIPHER("BF_CBC"):
406
114
            return EVP_bf_cbc();
407
257
        case CF_CIPHER("CAST5_ECB"):
408
257
            return EVP_cast5_ecb();
409
76
        case CF_CIPHER("CAST5_CFB"):
410
76
            return EVP_cast5_cfb();
411
54
        case CF_CIPHER("CAST5_OFB"):
412
54
            return EVP_cast5_ofb();
413
40
        case CF_CIPHER("CAST5_CBC"):
414
40
            return EVP_cast5_cbc();
415
42
        case CF_CIPHER("AES_128_ECB"):
416
42
            return EVP_aes_128_ecb();
417
96
        case CF_CIPHER("AES_128_CBC"):
418
96
            return EVP_aes_128_cbc();
419
110
        case CF_CIPHER("AES_128_CFB"):
420
110
            return EVP_aes_128_cfb();
421
26
        case CF_CIPHER("AES_128_CFB1"):
422
26
            return EVP_aes_128_cfb1();
423
29
        case CF_CIPHER("AES_128_CFB8"):
424
29
            return EVP_aes_128_cfb8();
425
24
        case CF_CIPHER("AES_128_OFB"):
426
24
            return EVP_aes_128_ofb();
427
25
        case CF_CIPHER("AES_128_CTR"):
428
25
            return EVP_aes_128_ctr();
429
200
        case CF_CIPHER("AES_128_GCM"):
430
200
            return EVP_aes_128_gcm();
431
48
        case CF_CIPHER("AES_128_XTS"):
432
48
            return EVP_aes_128_xts();
433
35
        case CF_CIPHER("AES_128_CCM"):
434
35
            return EVP_aes_128_ccm();
435
46
        case CF_CIPHER("AES_128_WRAP"):
436
46
            return EVP_aes_128_wrap();
437
36
        case CF_CIPHER("AES_192_ECB"):
438
36
            return EVP_aes_192_ecb();
439
68
        case CF_CIPHER("AES_192_CBC"):
440
68
            return EVP_aes_192_cbc();
441
18
        case CF_CIPHER("AES_192_CFB"):
442
18
            return EVP_aes_192_cfb();
443
7
        case CF_CIPHER("AES_192_CFB1"):
444
7
            return EVP_aes_192_cfb1();
445
35
        case CF_CIPHER("AES_192_CFB8"):
446
35
            return EVP_aes_192_cfb8();
447
36
        case CF_CIPHER("AES_192_OFB"):
448
36
            return EVP_aes_192_ofb();
449
17
        case CF_CIPHER("AES_192_CTR"):
450
17
            return EVP_aes_192_ctr();
451
87
        case CF_CIPHER("AES_192_GCM"):
452
87
            return EVP_aes_192_gcm();
453
24
        case CF_CIPHER("AES_192_CCM"):
454
24
            return EVP_aes_192_ccm();
455
26
        case CF_CIPHER("AES_192_WRAP"):
456
26
            return EVP_aes_192_wrap();
457
10
        case CF_CIPHER("AES_256_ECB"):
458
10
            return EVP_aes_256_ecb();
459
8
        case CF_CIPHER("AES_256_CBC"):
460
8
            return EVP_aes_256_cbc();
461
28
        case CF_CIPHER("AES_256_CFB"):
462
28
            return EVP_aes_256_cfb();
463
57
        case CF_CIPHER("AES_256_CFB1"):
464
57
            return EVP_aes_256_cfb1();
465
35
        case CF_CIPHER("AES_256_CFB8"):
466
35
            return EVP_aes_256_cfb8();
467
34
        case CF_CIPHER("AES_256_OFB"):
468
34
            return EVP_aes_256_ofb();
469
140
        case CF_CIPHER("AES_256_CTR"):
470
140
            return EVP_aes_256_ctr();
471
37
        case CF_CIPHER("AES_256_GCM"):
472
37
            return EVP_aes_256_gcm();
473
57
        case CF_CIPHER("AES_256_XTS"):
474
57
            return EVP_aes_256_xts();
475
48
        case CF_CIPHER("AES_256_CCM"):
476
48
            return EVP_aes_256_ccm();
477
43
        case CF_CIPHER("AES_256_WRAP"):
478
43
            return EVP_aes_256_wrap();
479
39
        case CF_CIPHER("CAMELLIA_128_ECB"):
480
39
            return EVP_camellia_128_ecb();
481
24
        case CF_CIPHER("CAMELLIA_128_CBC"):
482
24
            return EVP_camellia_128_cbc();
483
29
        case CF_CIPHER("CAMELLIA_128_CFB"):
484
29
            return EVP_camellia_128_cfb();
485
34
        case CF_CIPHER("CAMELLIA_128_CFB1"):
486
34
            return EVP_camellia_128_cfb1();
487
26
        case CF_CIPHER("CAMELLIA_128_CFB8"):
488
26
            return EVP_camellia_128_cfb8();
489
70
        case CF_CIPHER("CAMELLIA_128_OFB"):
490
70
            return EVP_camellia_128_ofb();
491
35
        case CF_CIPHER("CAMELLIA_192_ECB"):
492
35
            return EVP_camellia_192_ecb();
493
40
        case CF_CIPHER("CAMELLIA_192_CBC"):
494
40
            return EVP_camellia_192_cbc();
495
125
        case CF_CIPHER("CAMELLIA_192_CFB"):
496
125
            return EVP_camellia_192_cfb();
497
3
        case CF_CIPHER("CAMELLIA_192_CFB1"):
498
3
            return EVP_camellia_192_cfb1();
499
34
        case CF_CIPHER("CAMELLIA_192_CFB8"):
500
34
            return EVP_camellia_192_cfb8();
501
6
        case CF_CIPHER("CAMELLIA_192_OFB"):
502
6
            return EVP_camellia_192_ofb();
503
52
        case CF_CIPHER("CAMELLIA_256_ECB"):
504
52
            return EVP_camellia_256_ecb();
505
46
        case CF_CIPHER("CAMELLIA_256_CBC"):
506
46
            return EVP_camellia_256_cbc();
507
50
        case CF_CIPHER("CAMELLIA_256_CFB"):
508
50
            return EVP_camellia_256_cfb();
509
34
        case CF_CIPHER("CAMELLIA_256_CFB1"):
510
34
            return EVP_camellia_256_cfb1();
511
34
        case CF_CIPHER("CAMELLIA_256_CFB8"):
512
34
            return EVP_camellia_256_cfb8();
513
11
        case CF_CIPHER("CAMELLIA_256_OFB"):
514
11
            return EVP_camellia_256_ofb();
515
88
        case CF_CIPHER("CHACHA20"):
516
88
            return EVP_chacha20();
517
76
        case CF_CIPHER("CHACHA20_POLY1305"):
518
76
            return EVP_chacha20_poly1305();
519
#elif defined(CRYPTOFUZZ_OPENSSL_098)
520
        case CF_CIPHER("DES_CFB"):
521
            return EVP_des_cfb();
522
        case CF_CIPHER("DES_CFB1"):
523
            return EVP_des_cfb1();
524
        case CF_CIPHER("DES_CFB8"):
525
            return EVP_des_cfb8();
526
        case CF_CIPHER("DES_EDE_CFB"):
527
            return EVP_des_ede_cfb();
528
        case CF_CIPHER("DES_EDE3_CFB"):
529
            return EVP_des_ede3_cfb();
530
        case CF_CIPHER("DES_EDE3_CFB1"):
531
            return EVP_des_ede3_cfb1();
532
        case CF_CIPHER("DES_EDE3_CFB8"):
533
            return EVP_des_ede3_cfb8();
534
        case CF_CIPHER("DES_OFB"):
535
            return EVP_des_ofb();
536
        case CF_CIPHER("DES_EDE_OFB"):
537
            return EVP_des_ede_ofb();
538
        case CF_CIPHER("DES_EDE3_OFB"):
539
            return EVP_des_ede3_ofb();
540
        case CF_CIPHER("DESX_A_CBC"):
541
            return EVP_desx_cbc();
542
        case CF_CIPHER("DES_CBC"):
543
            return EVP_des_cbc();
544
        case CF_CIPHER("DES_EDE_CBC"):
545
            return EVP_des_ede_cbc();
546
        case CF_CIPHER("DES_EDE3_CBC"):
547
            return EVP_des_ede3_cbc();
548
        case CF_CIPHER("DES_ECB"):
549
            return EVP_des_ecb();
550
        case CF_CIPHER("DES_EDE"):
551
            return EVP_des_ede();
552
        case CF_CIPHER("DES_EDE3"):
553
            return EVP_des_ede3();
554
        case CF_CIPHER("RC4"):
555
            return EVP_rc4();
556
        case CF_CIPHER("RC4_40"):
557
            return EVP_rc4_40();
558
        case CF_CIPHER("IDEA_ECB"):
559
            return EVP_idea_ecb();
560
        case CF_CIPHER("IDEA_CFB"):
561
            return EVP_idea_cfb();
562
        case CF_CIPHER("IDEA_OFB"):
563
            return EVP_idea_ofb();
564
        case CF_CIPHER("IDEA_CBC"):
565
            return EVP_idea_cbc();
566
        case CF_CIPHER("RC2_ECB"):
567
            return EVP_rc2_ecb();
568
        case CF_CIPHER("RC2_CFB"):
569
            return EVP_rc2_cfb();
570
        case CF_CIPHER("RC2_OFB"):
571
            return EVP_rc2_ofb();
572
        case CF_CIPHER("RC2_CBC"):
573
            return EVP_rc2_cbc();
574
        case CF_CIPHER("RC2_40_CBC"):
575
            return EVP_rc2_40_cbc();
576
        case CF_CIPHER("RC2_64_CBC"):
577
            return EVP_rc2_64_cbc();
578
        case CF_CIPHER("BF_ECB"):
579
            return EVP_bf_ecb();
580
        case CF_CIPHER("BF_CFB"):
581
            return EVP_bf_cfb();
582
        case CF_CIPHER("BF_OFB"):
583
            return EVP_bf_ofb();
584
        case CF_CIPHER("BF_CBC"):
585
            return EVP_bf_cbc();
586
        case CF_CIPHER("CAST5_ECB"):
587
            return EVP_cast5_ecb();
588
        case CF_CIPHER("CAST5_CFB"):
589
            return EVP_cast5_cfb();
590
        case CF_CIPHER("CAST5_OFB"):
591
            return EVP_cast5_ofb();
592
        case CF_CIPHER("CAST5_CBC"):
593
            return EVP_cast5_cbc();
594
        case CF_CIPHER("AES_128_ECB"):
595
            return EVP_aes_128_ecb();
596
        case CF_CIPHER("AES_128_CBC"):
597
            return EVP_aes_128_cbc();
598
        case CF_CIPHER("AES_128_CFB"):
599
            return EVP_aes_128_cfb();
600
        case CF_CIPHER("AES_128_CFB1"):
601
            return EVP_aes_128_cfb1();
602
        case CF_CIPHER("AES_128_CFB8"):
603
            return EVP_aes_128_cfb8();
604
        case CF_CIPHER("AES_128_OFB"):
605
            return EVP_aes_128_ofb();
606
        case CF_CIPHER("AES_192_ECB"):
607
            return EVP_aes_192_ecb();
608
        case CF_CIPHER("AES_192_CBC"):
609
            return EVP_aes_192_cbc();
610
        case CF_CIPHER("AES_192_CFB"):
611
            return EVP_aes_192_cfb();
612
        case CF_CIPHER("AES_192_CFB1"):
613
            return EVP_aes_192_cfb1();
614
        case CF_CIPHER("AES_192_CFB8"):
615
            return EVP_aes_192_cfb8();
616
        case CF_CIPHER("AES_192_OFB"):
617
            return EVP_aes_192_ofb();
618
        case CF_CIPHER("AES_256_ECB"):
619
            return EVP_aes_256_ecb();
620
        case CF_CIPHER("AES_256_CBC"):
621
            return EVP_aes_256_cbc();
622
        case CF_CIPHER("AES_256_CFB"):
623
            return EVP_aes_256_cfb();
624
        case CF_CIPHER("AES_256_CFB1"):
625
            return EVP_aes_256_cfb1();
626
        case CF_CIPHER("AES_256_CFB8"):
627
            return EVP_aes_256_cfb8();
628
        case CF_CIPHER("AES_256_OFB"):
629
            return EVP_aes_256_ofb();
630
#elif defined(CRYPTOFUZZ_OPENSSL_102)
631
        case CF_CIPHER("DES_CFB"):
632
            return EVP_des_cfb();
633
        case CF_CIPHER("DES_CFB1"):
634
            return EVP_des_cfb1();
635
        case CF_CIPHER("DES_CFB8"):
636
            return EVP_des_cfb8();
637
        case CF_CIPHER("DES_EDE_CFB"):
638
            return EVP_des_ede_cfb();
639
        case CF_CIPHER("DES_EDE3_CFB"):
640
            return EVP_des_ede3_cfb();
641
        case CF_CIPHER("DES_EDE3_CFB1"):
642
            return EVP_des_ede3_cfb1();
643
        case CF_CIPHER("DES_EDE3_CFB8"):
644
            return EVP_des_ede3_cfb8();
645
        case CF_CIPHER("DES_OFB"):
646
            return EVP_des_ofb();
647
        case CF_CIPHER("DES_EDE_OFB"):
648
            return EVP_des_ede_ofb();
649
        case CF_CIPHER("DES_EDE3_OFB"):
650
            return EVP_des_ede3_ofb();
651
        case CF_CIPHER("DESX_A_CBC"):
652
            return EVP_desx_cbc();
653
        case CF_CIPHER("DES_CBC"):
654
            return EVP_des_cbc();
655
        case CF_CIPHER("DES_EDE_CBC"):
656
            return EVP_des_ede_cbc();
657
        case CF_CIPHER("DES_EDE3_CBC"):
658
            return EVP_des_ede3_cbc();
659
        case CF_CIPHER("DES_ECB"):
660
            return EVP_des_ecb();
661
        case CF_CIPHER("DES_EDE"):
662
            return EVP_des_ede();
663
        case CF_CIPHER("DES_EDE3"):
664
            return EVP_des_ede3();
665
        case CF_CIPHER("DES_EDE3_WRAP"):
666
            return EVP_des_ede3_wrap();
667
        case CF_CIPHER("RC4"):
668
            return EVP_rc4();
669
        case CF_CIPHER("RC4_40"):
670
            return EVP_rc4_40();
671
        case CF_CIPHER("RC4_HMAC_MD5"):
672
            return EVP_rc4_hmac_md5();
673
        case CF_CIPHER("IDEA_ECB"):
674
            return EVP_idea_ecb();
675
        case CF_CIPHER("IDEA_CFB"):
676
            return EVP_idea_cfb();
677
        case CF_CIPHER("IDEA_OFB"):
678
            return EVP_idea_ofb();
679
        case CF_CIPHER("IDEA_CBC"):
680
            return EVP_idea_cbc();
681
        case CF_CIPHER("SEED_ECB"):
682
            return EVP_seed_ecb();
683
        case CF_CIPHER("SEED_CFB"):
684
            return EVP_seed_cfb();
685
        case CF_CIPHER("SEED_OFB"):
686
            return EVP_seed_ofb();
687
        case CF_CIPHER("SEED_CBC"):
688
            return EVP_seed_cbc();
689
        case CF_CIPHER("RC2_ECB"):
690
            return EVP_rc2_ecb();
691
        case CF_CIPHER("RC2_CFB"):
692
            return EVP_rc2_cfb();
693
        case CF_CIPHER("RC2_OFB"):
694
            return EVP_rc2_ofb();
695
        case CF_CIPHER("RC2_CBC"):
696
            return EVP_rc2_cbc();
697
        case CF_CIPHER("RC2_40_CBC"):
698
            return EVP_rc2_40_cbc();
699
        case CF_CIPHER("RC2_64_CBC"):
700
            return EVP_rc2_64_cbc();
701
        case CF_CIPHER("BF_ECB"):
702
            return EVP_bf_ecb();
703
        case CF_CIPHER("BF_CFB"):
704
            return EVP_bf_cfb();
705
        case CF_CIPHER("BF_OFB"):
706
            return EVP_bf_ofb();
707
        case CF_CIPHER("BF_CBC"):
708
            return EVP_bf_cbc();
709
        case CF_CIPHER("CAST5_ECB"):
710
            return EVP_cast5_ecb();
711
        case CF_CIPHER("CAST5_CFB"):
712
            return EVP_cast5_cfb();
713
        case CF_CIPHER("CAST5_OFB"):
714
            return EVP_cast5_ofb();
715
        case CF_CIPHER("CAST5_CBC"):
716
            return EVP_cast5_cbc();
717
        case CF_CIPHER("RC5_32_12_16_ECB"):
718
            return EVP_rc5_32_12_16_ecb();
719
        case CF_CIPHER("RC5_32_12_16_CFB"):
720
            return EVP_rc5_32_12_16_cfb();
721
        case CF_CIPHER("RC5_32_12_16_OFB"):
722
            return EVP_rc5_32_12_16_ofb();
723
        case CF_CIPHER("RC5_32_12_16_CBC"):
724
            return EVP_rc5_32_12_16_cbc();
725
        case CF_CIPHER("AES_128_ECB"):
726
            return EVP_aes_128_ecb();
727
        case CF_CIPHER("AES_128_CBC"):
728
            return EVP_aes_128_cbc();
729
        case CF_CIPHER("AES_128_CFB"):
730
            return EVP_aes_128_cfb();
731
        case CF_CIPHER("AES_128_CFB1"):
732
            return EVP_aes_128_cfb1();
733
        case CF_CIPHER("AES_128_CFB8"):
734
            return EVP_aes_128_cfb8();
735
        case CF_CIPHER("AES_128_OFB"):
736
            return EVP_aes_128_ofb();
737
        case CF_CIPHER("AES_128_CTR"):
738
            return EVP_aes_128_ctr();
739
        case CF_CIPHER("AES_128_GCM"):
740
            return EVP_aes_128_gcm();
741
        case CF_CIPHER("AES_128_XTS"):
742
            return EVP_aes_128_xts();
743
        case CF_CIPHER("AES_128_CCM"):
744
            return EVP_aes_128_ccm();
745
        case CF_CIPHER("AES_128_WRAP"):
746
            return EVP_aes_128_wrap();
747
        case CF_CIPHER("AES_192_ECB"):
748
            return EVP_aes_192_ecb();
749
        case CF_CIPHER("AES_192_CBC"):
750
            return EVP_aes_192_cbc();
751
        case CF_CIPHER("AES_192_CFB"):
752
            return EVP_aes_192_cfb();
753
        case CF_CIPHER("AES_192_CFB1"):
754
            return EVP_aes_192_cfb1();
755
        case CF_CIPHER("AES_192_CFB8"):
756
            return EVP_aes_192_cfb8();
757
        case CF_CIPHER("AES_192_OFB"):
758
            return EVP_aes_192_ofb();
759
        case CF_CIPHER("AES_192_CTR"):
760
            return EVP_aes_192_ctr();
761
        case CF_CIPHER("AES_192_GCM"):
762
            return EVP_aes_192_gcm();
763
        case CF_CIPHER("AES_192_CCM"):
764
            return EVP_aes_192_ccm();
765
        case CF_CIPHER("AES_192_WRAP"):
766
            return EVP_aes_192_wrap();
767
        case CF_CIPHER("AES_256_ECB"):
768
            return EVP_aes_256_ecb();
769
        case CF_CIPHER("AES_256_CBC"):
770
            return EVP_aes_256_cbc();
771
        case CF_CIPHER("AES_256_CFB"):
772
            return EVP_aes_256_cfb();
773
        case CF_CIPHER("AES_256_CFB1"):
774
            return EVP_aes_256_cfb1();
775
        case CF_CIPHER("AES_256_CFB8"):
776
            return EVP_aes_256_cfb8();
777
        case CF_CIPHER("AES_256_OFB"):
778
            return EVP_aes_256_ofb();
779
        case CF_CIPHER("AES_256_CTR"):
780
            return EVP_aes_256_ctr();
781
        case CF_CIPHER("AES_256_GCM"):
782
            return EVP_aes_256_gcm();
783
        case CF_CIPHER("AES_256_XTS"):
784
            return EVP_aes_256_xts();
785
        case CF_CIPHER("AES_256_CCM"):
786
            return EVP_aes_256_ccm();
787
        case CF_CIPHER("AES_256_WRAP"):
788
            return EVP_aes_256_wrap();
789
        case CF_CIPHER("AES_128_CBC_HMAC_SHA1"):
790
            return EVP_aes_128_cbc_hmac_sha1();
791
        case CF_CIPHER("AES_256_CBC_HMAC_SHA1"):
792
            return EVP_aes_256_cbc_hmac_sha1();
793
        case CF_CIPHER("AES_128_CBC_HMAC_SHA256"):
794
            return EVP_aes_128_cbc_hmac_sha256();
795
        case CF_CIPHER("AES_256_CBC_HMAC_SHA256"):
796
            return EVP_aes_256_cbc_hmac_sha256();
797
        case CF_CIPHER("CAMELLIA_128_ECB"):
798
            return EVP_camellia_128_ecb();
799
        case CF_CIPHER("CAMELLIA_128_CBC"):
800
            return EVP_camellia_128_cbc();
801
        case CF_CIPHER("CAMELLIA_128_CFB"):
802
            return EVP_camellia_128_cfb();
803
        case CF_CIPHER("CAMELLIA_128_CFB1"):
804
            return EVP_camellia_128_cfb1();
805
        case CF_CIPHER("CAMELLIA_128_CFB8"):
806
            return EVP_camellia_128_cfb8();
807
        case CF_CIPHER("CAMELLIA_128_OFB"):
808
            return EVP_camellia_128_ofb();
809
        case CF_CIPHER("CAMELLIA_192_ECB"):
810
            return EVP_camellia_192_ecb();
811
        case CF_CIPHER("CAMELLIA_192_CBC"):
812
            return EVP_camellia_192_cbc();
813
        case CF_CIPHER("CAMELLIA_192_CFB"):
814
            return EVP_camellia_192_cfb();
815
        case CF_CIPHER("CAMELLIA_192_CFB1"):
816
            return EVP_camellia_192_cfb1();
817
        case CF_CIPHER("CAMELLIA_192_CFB8"):
818
            return EVP_camellia_192_cfb8();
819
        case CF_CIPHER("CAMELLIA_192_OFB"):
820
            return EVP_camellia_192_ofb();
821
        case CF_CIPHER("CAMELLIA_256_ECB"):
822
            return EVP_camellia_256_ecb();
823
        case CF_CIPHER("CAMELLIA_256_CBC"):
824
            return EVP_camellia_256_cbc();
825
        case CF_CIPHER("CAMELLIA_256_CFB"):
826
            return EVP_camellia_256_cfb();
827
        case CF_CIPHER("CAMELLIA_256_CFB1"):
828
            return EVP_camellia_256_cfb1();
829
        case CF_CIPHER("CAMELLIA_256_CFB8"):
830
            return EVP_camellia_256_cfb8();
831
        case CF_CIPHER("CAMELLIA_256_OFB"):
832
            return EVP_camellia_256_ofb();
833
#elif defined(CRYPTOFUZZ_OPENSSL_110)
834
        case CF_CIPHER("DES_CFB"):
835
            return EVP_des_cfb();
836
        case CF_CIPHER("DES_CFB1"):
837
            return EVP_des_cfb1();
838
        case CF_CIPHER("DES_CFB8"):
839
            return EVP_des_cfb8();
840
        case CF_CIPHER("DES_EDE_CFB"):
841
            return EVP_des_ede_cfb();
842
        case CF_CIPHER("DES_EDE3_CFB"):
843
            return EVP_des_ede3_cfb();
844
        case CF_CIPHER("DES_EDE3_CFB1"):
845
            return EVP_des_ede3_cfb1();
846
        case CF_CIPHER("DES_EDE3_CFB8"):
847
            return EVP_des_ede3_cfb8();
848
        case CF_CIPHER("DES_OFB"):
849
            return EVP_des_ofb();
850
        case CF_CIPHER("DES_EDE_OFB"):
851
            return EVP_des_ede_ofb();
852
        case CF_CIPHER("DES_EDE3_OFB"):
853
            return EVP_des_ede3_ofb();
854
        case CF_CIPHER("DESX_A_CBC"):
855
            return EVP_desx_cbc();
856
        case CF_CIPHER("DES_CBC"):
857
            return EVP_des_cbc();
858
        case CF_CIPHER("DES_EDE_CBC"):
859
            return EVP_des_ede_cbc();
860
        case CF_CIPHER("DES_EDE3_CBC"):
861
            return EVP_des_ede3_cbc();
862
        case CF_CIPHER("DES_ECB"):
863
            return EVP_des_ecb();
864
        case CF_CIPHER("DES_EDE"):
865
            return EVP_des_ede();
866
        case CF_CIPHER("DES_EDE3"):
867
            return EVP_des_ede3();
868
        case CF_CIPHER("DES_EDE3_WRAP"):
869
            return EVP_des_ede3_wrap();
870
        case CF_CIPHER("RC4"):
871
            return EVP_rc4();
872
        case CF_CIPHER("RC4_40"):
873
            return EVP_rc4_40();
874
        case CF_CIPHER("RC4_HMAC_MD5"):
875
            return EVP_rc4_hmac_md5();
876
        case CF_CIPHER("IDEA_ECB"):
877
            return EVP_idea_ecb();
878
        case CF_CIPHER("IDEA_CFB"):
879
            return EVP_idea_cfb();
880
        case CF_CIPHER("IDEA_OFB"):
881
            return EVP_idea_ofb();
882
        case CF_CIPHER("IDEA_CBC"):
883
            return EVP_idea_cbc();
884
        case CF_CIPHER("SEED_ECB"):
885
            return EVP_seed_ecb();
886
        case CF_CIPHER("SEED_CFB"):
887
            return EVP_seed_cfb();
888
        case CF_CIPHER("SEED_OFB"):
889
            return EVP_seed_ofb();
890
        case CF_CIPHER("SEED_CBC"):
891
            return EVP_seed_cbc();
892
        case CF_CIPHER("RC2_ECB"):
893
            return EVP_rc2_ecb();
894
        case CF_CIPHER("RC2_CFB"):
895
            return EVP_rc2_cfb();
896
        case CF_CIPHER("RC2_OFB"):
897
            return EVP_rc2_ofb();
898
        case CF_CIPHER("RC2_CBC"):
899
            return EVP_rc2_cbc();
900
        case CF_CIPHER("RC2_40_CBC"):
901
            return EVP_rc2_40_cbc();
902
        case CF_CIPHER("RC2_64_CBC"):
903
            return EVP_rc2_64_cbc();
904
        case CF_CIPHER("BF_ECB"):
905
            return EVP_bf_ecb();
906
        case CF_CIPHER("BF_CFB"):
907
            return EVP_bf_cfb();
908
        case CF_CIPHER("BF_OFB"):
909
            return EVP_bf_ofb();
910
        case CF_CIPHER("BF_CBC"):
911
            return EVP_bf_cbc();
912
        case CF_CIPHER("CAST5_ECB"):
913
            return EVP_cast5_ecb();
914
        case CF_CIPHER("CAST5_CFB"):
915
            return EVP_cast5_cfb();
916
        case CF_CIPHER("CAST5_OFB"):
917
            return EVP_cast5_ofb();
918
        case CF_CIPHER("CAST5_CBC"):
919
            return EVP_cast5_cbc();
920
        case CF_CIPHER("RC5_32_12_16_ECB"):
921
            return EVP_rc5_32_12_16_ecb();
922
        case CF_CIPHER("RC5_32_12_16_CFB"):
923
            return EVP_rc5_32_12_16_cfb();
924
        case CF_CIPHER("RC5_32_12_16_OFB"):
925
            return EVP_rc5_32_12_16_ofb();
926
        case CF_CIPHER("RC5_32_12_16_CBC"):
927
            return EVP_rc5_32_12_16_cbc();
928
        case CF_CIPHER("AES_128_ECB"):
929
            return EVP_aes_128_ecb();
930
        case CF_CIPHER("AES_128_CBC"):
931
            return EVP_aes_128_cbc();
932
        case CF_CIPHER("AES_128_CFB"):
933
            return EVP_aes_128_cfb();
934
        case CF_CIPHER("AES_128_CFB1"):
935
            return EVP_aes_128_cfb1();
936
        case CF_CIPHER("AES_128_CFB8"):
937
            return EVP_aes_128_cfb8();
938
        case CF_CIPHER("AES_128_OFB"):
939
            return EVP_aes_128_ofb();
940
        case CF_CIPHER("AES_128_CTR"):
941
            return EVP_aes_128_ctr();
942
        case CF_CIPHER("AES_128_GCM"):
943
            return EVP_aes_128_gcm();
944
        case CF_CIPHER("AES_128_OCB"):
945
            return EVP_aes_128_ocb();
946
        case CF_CIPHER("AES_128_XTS"):
947
            return EVP_aes_128_xts();
948
        case CF_CIPHER("AES_128_CCM"):
949
            return EVP_aes_128_ccm();
950
        case CF_CIPHER("AES_128_WRAP"):
951
            return EVP_aes_128_wrap();
952
        case CF_CIPHER("AES_128_WRAP_PAD"):
953
            return EVP_aes_128_wrap_pad();
954
        case CF_CIPHER("AES_192_ECB"):
955
            return EVP_aes_192_ecb();
956
        case CF_CIPHER("AES_192_CBC"):
957
            return EVP_aes_192_cbc();
958
        case CF_CIPHER("AES_192_CFB"):
959
            return EVP_aes_192_cfb();
960
        case CF_CIPHER("AES_192_CFB1"):
961
            return EVP_aes_192_cfb1();
962
        case CF_CIPHER("AES_192_CFB8"):
963
            return EVP_aes_192_cfb8();
964
        case CF_CIPHER("AES_192_OFB"):
965
            return EVP_aes_192_ofb();
966
        case CF_CIPHER("AES_192_CTR"):
967
            return EVP_aes_192_ctr();
968
        case CF_CIPHER("AES_192_GCM"):
969
            return EVP_aes_192_gcm();
970
        case CF_CIPHER("AES_192_CCM"):
971
            return EVP_aes_192_ccm();
972
        case CF_CIPHER("AES_192_WRAP"):
973
            return EVP_aes_192_wrap();
974
        case CF_CIPHER("AES_192_WRAP_PAD"):
975
            return EVP_aes_192_wrap_pad();
976
        case CF_CIPHER("AES_256_ECB"):
977
            return EVP_aes_256_ecb();
978
        case CF_CIPHER("AES_256_CBC"):
979
            return EVP_aes_256_cbc();
980
        case CF_CIPHER("AES_256_CFB"):
981
            return EVP_aes_256_cfb();
982
        case CF_CIPHER("AES_256_CFB1"):
983
            return EVP_aes_256_cfb1();
984
        case CF_CIPHER("AES_256_CFB8"):
985
            return EVP_aes_256_cfb8();
986
        case CF_CIPHER("AES_256_OFB"):
987
            return EVP_aes_256_ofb();
988
        case CF_CIPHER("AES_256_CTR"):
989
            return EVP_aes_256_ctr();
990
        case CF_CIPHER("AES_256_GCM"):
991
            return EVP_aes_256_gcm();
992
        case CF_CIPHER("AES_256_OCB"):
993
            return EVP_aes_256_ocb();
994
        case CF_CIPHER("AES_256_XTS"):
995
            return EVP_aes_256_xts();
996
        case CF_CIPHER("AES_256_CCM"):
997
            return EVP_aes_256_ccm();
998
        case CF_CIPHER("AES_256_WRAP"):
999
            return EVP_aes_256_wrap();
1000
        case CF_CIPHER("AES_256_WRAP_PAD"):
1001
            return EVP_aes_256_wrap_pad();
1002
        case CF_CIPHER("AES_128_CBC_HMAC_SHA1"):
1003
            return EVP_aes_128_cbc_hmac_sha1();
1004
        case CF_CIPHER("AES_256_CBC_HMAC_SHA1"):
1005
            return EVP_aes_256_cbc_hmac_sha1();
1006
        case CF_CIPHER("AES_128_CBC_HMAC_SHA256"):
1007
            return EVP_aes_128_cbc_hmac_sha256();
1008
        case CF_CIPHER("AES_256_CBC_HMAC_SHA256"):
1009
            return EVP_aes_256_cbc_hmac_sha256();
1010
        case CF_CIPHER("CAMELLIA_128_ECB"):
1011
            return EVP_camellia_128_ecb();
1012
        case CF_CIPHER("CAMELLIA_128_CBC"):
1013
            return EVP_camellia_128_cbc();
1014
        case CF_CIPHER("CAMELLIA_128_CFB"):
1015
            return EVP_camellia_128_cfb();
1016
        case CF_CIPHER("CAMELLIA_128_CFB1"):
1017
            return EVP_camellia_128_cfb1();
1018
        case CF_CIPHER("CAMELLIA_128_CFB8"):
1019
            return EVP_camellia_128_cfb8();
1020
        case CF_CIPHER("CAMELLIA_128_OFB"):
1021
            return EVP_camellia_128_ofb();
1022
        case CF_CIPHER("CAMELLIA_192_ECB"):
1023
            return EVP_camellia_192_ecb();
1024
        case CF_CIPHER("CAMELLIA_192_CBC"):
1025
            return EVP_camellia_192_cbc();
1026
        case CF_CIPHER("CAMELLIA_192_CFB"):
1027
            return EVP_camellia_192_cfb();
1028
        case CF_CIPHER("CAMELLIA_192_CFB1"):
1029
            return EVP_camellia_192_cfb1();
1030
        case CF_CIPHER("CAMELLIA_192_CFB8"):
1031
            return EVP_camellia_192_cfb8();
1032
        case CF_CIPHER("CAMELLIA_192_OFB"):
1033
            return EVP_camellia_192_ofb();
1034
        case CF_CIPHER("CAMELLIA_256_ECB"):
1035
            return EVP_camellia_256_ecb();
1036
        case CF_CIPHER("CAMELLIA_256_CBC"):
1037
            return EVP_camellia_256_cbc();
1038
        case CF_CIPHER("CAMELLIA_256_CFB"):
1039
            return EVP_camellia_256_cfb();
1040
        case CF_CIPHER("CAMELLIA_256_CFB1"):
1041
            return EVP_camellia_256_cfb1();
1042
        case CF_CIPHER("CAMELLIA_256_CFB8"):
1043
            return EVP_camellia_256_cfb8();
1044
        case CF_CIPHER("CAMELLIA_256_OFB"):
1045
            return EVP_camellia_256_ofb();
1046
        case CF_CIPHER("CAMELLIA_128_CTR"):
1047
            return EVP_camellia_128_ctr();
1048
        case CF_CIPHER("CAMELLIA_192_CTR"):
1049
            return EVP_camellia_192_ctr();
1050
        case CF_CIPHER("CAMELLIA_256_CTR"):
1051
            return EVP_camellia_256_ctr();
1052
        case CF_CIPHER("CHACHA20"):
1053
            return EVP_chacha20();
1054
        case CF_CIPHER("CHACHA20_POLY1305"):
1055
            return EVP_chacha20_poly1305();
1056
#else
1057
        case CF_CIPHER("DES_CFB"):
1058
            return EVP_des_cfb();
1059
        case CF_CIPHER("DES_CFB1"):
1060
            return EVP_des_cfb1();
1061
        case CF_CIPHER("DES_CFB8"):
1062
            return EVP_des_cfb8();
1063
        case CF_CIPHER("DES_EDE_CFB"):
1064
            return EVP_des_ede_cfb();
1065
        case CF_CIPHER("DES_EDE3_CFB"):
1066
            return EVP_des_ede3_cfb();
1067
        case CF_CIPHER("DES_EDE3_CFB1"):
1068
            return EVP_des_ede3_cfb1();
1069
        case CF_CIPHER("DES_EDE3_CFB8"):
1070
            return EVP_des_ede3_cfb8();
1071
        case CF_CIPHER("DES_OFB"):
1072
            return EVP_des_ofb();
1073
        case CF_CIPHER("DES_EDE_OFB"):
1074
            return EVP_des_ede_ofb();
1075
        case CF_CIPHER("DES_EDE3_OFB"):
1076
            return EVP_des_ede3_ofb();
1077
        case CF_CIPHER("DESX_A_CBC"):
1078
            return EVP_desx_cbc();
1079
        case CF_CIPHER("DES_CBC"):
1080
            return EVP_des_cbc();
1081
        case CF_CIPHER("DES_EDE_CBC"):
1082
            return EVP_des_ede_cbc();
1083
        case CF_CIPHER("DES_EDE3_CBC"):
1084
            return EVP_des_ede3_cbc();
1085
        case CF_CIPHER("DES_ECB"):
1086
            return EVP_des_ecb();
1087
        case CF_CIPHER("DES_EDE"):
1088
            return EVP_des_ede();
1089
        case CF_CIPHER("DES_EDE3"):
1090
            return EVP_des_ede3();
1091
        case CF_CIPHER("RC4"):
1092
            return EVP_rc4();
1093
        case CF_CIPHER("RC4_40"):
1094
            return EVP_rc4_40();
1095
        case CF_CIPHER("RC4_HMAC_MD5"):
1096
            return EVP_rc4_hmac_md5();
1097
        case CF_CIPHER("IDEA_ECB"):
1098
            return EVP_idea_ecb();
1099
        case CF_CIPHER("IDEA_CFB"):
1100
            return EVP_idea_cfb();
1101
        case CF_CIPHER("IDEA_OFB"):
1102
            return EVP_idea_ofb();
1103
        case CF_CIPHER("IDEA_CBC"):
1104
            return EVP_idea_cbc();
1105
        case CF_CIPHER("SEED_ECB"):
1106
            return EVP_seed_ecb();
1107
        case CF_CIPHER("SEED_CFB"):
1108
            return EVP_seed_cfb();
1109
        case CF_CIPHER("SEED_OFB"):
1110
            return EVP_seed_ofb();
1111
        case CF_CIPHER("SEED_CBC"):
1112
            return EVP_seed_cbc();
1113
        case CF_CIPHER("SM4_ECB"):
1114
            return EVP_sm4_ecb();
1115
        case CF_CIPHER("SM4_CBC"):
1116
            return EVP_sm4_cbc();
1117
        case CF_CIPHER("SM4_CFB"):
1118
            return EVP_sm4_cfb();
1119
        case CF_CIPHER("SM4_OFB"):
1120
            return EVP_sm4_ofb();
1121
        case CF_CIPHER("SM4_CTR"):
1122
            return EVP_sm4_ctr();
1123
        case CF_CIPHER("RC2_ECB"):
1124
            return EVP_rc2_ecb();
1125
        case CF_CIPHER("RC2_CFB"):
1126
            return EVP_rc2_cfb();
1127
        case CF_CIPHER("RC2_OFB"):
1128
            return EVP_rc2_ofb();
1129
        case CF_CIPHER("RC2_CBC"):
1130
            return EVP_rc2_cbc();
1131
        case CF_CIPHER("RC2_40_CBC"):
1132
            return EVP_rc2_40_cbc();
1133
        case CF_CIPHER("RC2_64_CBC"):
1134
            return EVP_rc2_64_cbc();
1135
        case CF_CIPHER("BF_ECB"):
1136
            return EVP_bf_ecb();
1137
        case CF_CIPHER("BF_CFB"):
1138
            return EVP_bf_cfb();
1139
        case CF_CIPHER("BF_OFB"):
1140
            return EVP_bf_ofb();
1141
        case CF_CIPHER("BF_CBC"):
1142
            return EVP_bf_cbc();
1143
        case CF_CIPHER("CAST5_ECB"):
1144
            return EVP_cast5_ecb();
1145
        case CF_CIPHER("CAST5_CFB"):
1146
            return EVP_cast5_cfb();
1147
        case CF_CIPHER("CAST5_OFB"):
1148
            return EVP_cast5_ofb();
1149
        case CF_CIPHER("CAST5_CBC"):
1150
            return EVP_cast5_cbc();
1151
        case CF_CIPHER("RC5_32_12_16_ECB"):
1152
            return EVP_rc5_32_12_16_ecb();
1153
        case CF_CIPHER("RC5_32_12_16_CFB"):
1154
            return EVP_rc5_32_12_16_cfb();
1155
        case CF_CIPHER("RC5_32_12_16_OFB"):
1156
            return EVP_rc5_32_12_16_ofb();
1157
        case CF_CIPHER("RC5_32_12_16_CBC"):
1158
            return EVP_rc5_32_12_16_cbc();
1159
        case CF_CIPHER("AES_128_ECB"):
1160
            return EVP_aes_128_ecb();
1161
        case CF_CIPHER("AES_128_CBC"):
1162
            return EVP_aes_128_cbc();
1163
        case CF_CIPHER("AES_128_CFB"):
1164
            return EVP_aes_128_cfb();
1165
        case CF_CIPHER("AES_128_CFB1"):
1166
            return EVP_aes_128_cfb1();
1167
        case CF_CIPHER("AES_128_CFB8"):
1168
            return EVP_aes_128_cfb8();
1169
        case CF_CIPHER("AES_128_OFB"):
1170
            return EVP_aes_128_ofb();
1171
        case CF_CIPHER("AES_128_CTR"):
1172
            return EVP_aes_128_ctr();
1173
        case CF_CIPHER("AES_128_GCM"):
1174
            return EVP_aes_128_gcm();
1175
        case CF_CIPHER("AES_128_OCB"):
1176
            return EVP_aes_128_ocb();
1177
        case CF_CIPHER("AES_128_XTS"):
1178
            return EVP_aes_128_xts();
1179
        case CF_CIPHER("AES_128_CCM"):
1180
            return EVP_aes_128_ccm();
1181
        case CF_CIPHER("AES_192_ECB"):
1182
            return EVP_aes_192_ecb();
1183
        case CF_CIPHER("AES_192_CBC"):
1184
            return EVP_aes_192_cbc();
1185
        case CF_CIPHER("AES_192_CFB"):
1186
            return EVP_aes_192_cfb();
1187
        case CF_CIPHER("AES_192_CFB1"):
1188
            return EVP_aes_192_cfb1();
1189
        case CF_CIPHER("AES_192_CFB8"):
1190
            return EVP_aes_192_cfb8();
1191
        case CF_CIPHER("AES_192_OFB"):
1192
            return EVP_aes_192_ofb();
1193
        case CF_CIPHER("AES_192_CTR"):
1194
            return EVP_aes_192_ctr();
1195
        case CF_CIPHER("AES_192_GCM"):
1196
            return EVP_aes_192_gcm();
1197
        case CF_CIPHER("AES_192_CCM"):
1198
            return EVP_aes_192_ccm();
1199
        case CF_CIPHER("AES_256_ECB"):
1200
            return EVP_aes_256_ecb();
1201
        case CF_CIPHER("AES_256_CBC"):
1202
            return EVP_aes_256_cbc();
1203
        case CF_CIPHER("AES_256_CFB"):
1204
            return EVP_aes_256_cfb();
1205
        case CF_CIPHER("AES_256_CFB1"):
1206
            return EVP_aes_256_cfb1();
1207
        case CF_CIPHER("AES_256_CFB8"):
1208
            return EVP_aes_256_cfb8();
1209
        case CF_CIPHER("AES_256_OFB"):
1210
            return EVP_aes_256_ofb();
1211
        case CF_CIPHER("AES_256_CTR"):
1212
            return EVP_aes_256_ctr();
1213
        case CF_CIPHER("AES_256_GCM"):
1214
            return EVP_aes_256_gcm();
1215
        case CF_CIPHER("AES_256_OCB"):
1216
            return EVP_aes_256_ocb();
1217
        case CF_CIPHER("AES_256_XTS"):
1218
            return EVP_aes_256_xts();
1219
        case CF_CIPHER("AES_256_CCM"):
1220
            return EVP_aes_256_ccm();
1221
        case CF_CIPHER("AES_128_CBC_HMAC_SHA1"):
1222
            return EVP_aes_128_cbc_hmac_sha1();
1223
        case CF_CIPHER("AES_256_CBC_HMAC_SHA1"):
1224
            return EVP_aes_256_cbc_hmac_sha1();
1225
        case CF_CIPHER("AES_128_CBC_HMAC_SHA256"):
1226
            return EVP_aes_128_cbc_hmac_sha256();
1227
        case CF_CIPHER("AES_256_CBC_HMAC_SHA256"):
1228
            return EVP_aes_256_cbc_hmac_sha256();
1229
        case CF_CIPHER("ARIA_128_ECB"):
1230
            return EVP_aria_128_ecb();
1231
        case CF_CIPHER("ARIA_128_CBC"):
1232
            return EVP_aria_128_cbc();
1233
        case CF_CIPHER("ARIA_128_CFB"):
1234
            return EVP_aria_128_cfb();
1235
        case CF_CIPHER("ARIA_128_CFB1"):
1236
            return EVP_aria_128_cfb1();
1237
        case CF_CIPHER("ARIA_128_CFB8"):
1238
            return EVP_aria_128_cfb8();
1239
        case CF_CIPHER("ARIA_128_CTR"):
1240
            return EVP_aria_128_ctr();
1241
        case CF_CIPHER("ARIA_128_OFB"):
1242
            return EVP_aria_128_ofb();
1243
        case CF_CIPHER("ARIA_128_GCM"):
1244
            return EVP_aria_128_gcm();
1245
        case CF_CIPHER("ARIA_128_CCM"):
1246
            return EVP_aria_128_ccm();
1247
        case CF_CIPHER("ARIA_192_ECB"):
1248
            return EVP_aria_192_ecb();
1249
        case CF_CIPHER("ARIA_192_CBC"):
1250
            return EVP_aria_192_cbc();
1251
        case CF_CIPHER("ARIA_192_CFB"):
1252
            return EVP_aria_192_cfb();
1253
        case CF_CIPHER("ARIA_192_CFB1"):
1254
            return EVP_aria_192_cfb1();
1255
        case CF_CIPHER("ARIA_192_CFB8"):
1256
            return EVP_aria_192_cfb8();
1257
        case CF_CIPHER("ARIA_192_CTR"):
1258
            return EVP_aria_192_ctr();
1259
        case CF_CIPHER("ARIA_192_OFB"):
1260
            return EVP_aria_192_ofb();
1261
        case CF_CIPHER("ARIA_192_GCM"):
1262
            return EVP_aria_192_gcm();
1263
        case CF_CIPHER("ARIA_192_CCM"):
1264
            return EVP_aria_192_ccm();
1265
        case CF_CIPHER("ARIA_256_ECB"):
1266
            return EVP_aria_256_ecb();
1267
        case CF_CIPHER("ARIA_256_CBC"):
1268
            return EVP_aria_256_cbc();
1269
        case CF_CIPHER("ARIA_256_CFB"):
1270
            return EVP_aria_256_cfb();
1271
        case CF_CIPHER("ARIA_256_CFB1"):
1272
            return EVP_aria_256_cfb1();
1273
        case CF_CIPHER("ARIA_256_CFB8"):
1274
            return EVP_aria_256_cfb8();
1275
        case CF_CIPHER("ARIA_256_CTR"):
1276
            return EVP_aria_256_ctr();
1277
        case CF_CIPHER("ARIA_256_OFB"):
1278
            return EVP_aria_256_ofb();
1279
        case CF_CIPHER("ARIA_256_GCM"):
1280
            return EVP_aria_256_gcm();
1281
        case CF_CIPHER("ARIA_256_CCM"):
1282
            return EVP_aria_256_ccm();
1283
        case CF_CIPHER("CAMELLIA_128_ECB"):
1284
            return EVP_camellia_128_ecb();
1285
        case CF_CIPHER("CAMELLIA_128_CBC"):
1286
            return EVP_camellia_128_cbc();
1287
        case CF_CIPHER("CAMELLIA_128_CFB"):
1288
            return EVP_camellia_128_cfb();
1289
        case CF_CIPHER("CAMELLIA_128_CFB1"):
1290
            return EVP_camellia_128_cfb1();
1291
        case CF_CIPHER("CAMELLIA_128_CFB8"):
1292
            return EVP_camellia_128_cfb8();
1293
        case CF_CIPHER("CAMELLIA_128_OFB"):
1294
            return EVP_camellia_128_ofb();
1295
        case CF_CIPHER("CAMELLIA_192_ECB"):
1296
            return EVP_camellia_192_ecb();
1297
        case CF_CIPHER("CAMELLIA_192_CBC"):
1298
            return EVP_camellia_192_cbc();
1299
        case CF_CIPHER("CAMELLIA_192_CFB"):
1300
            return EVP_camellia_192_cfb();
1301
        case CF_CIPHER("CAMELLIA_192_CFB1"):
1302
            return EVP_camellia_192_cfb1();
1303
        case CF_CIPHER("CAMELLIA_192_CFB8"):
1304
            return EVP_camellia_192_cfb8();
1305
        case CF_CIPHER("CAMELLIA_192_OFB"):
1306
            return EVP_camellia_192_ofb();
1307
        case CF_CIPHER("CAMELLIA_256_ECB"):
1308
            return EVP_camellia_256_ecb();
1309
        case CF_CIPHER("CAMELLIA_256_CBC"):
1310
            return EVP_camellia_256_cbc();
1311
        case CF_CIPHER("CAMELLIA_256_CFB"):
1312
            return EVP_camellia_256_cfb();
1313
        case CF_CIPHER("CAMELLIA_256_CFB1"):
1314
            return EVP_camellia_256_cfb1();
1315
        case CF_CIPHER("CAMELLIA_256_CFB8"):
1316
            return EVP_camellia_256_cfb8();
1317
        case CF_CIPHER("CAMELLIA_256_OFB"):
1318
            return EVP_camellia_256_ofb();
1319
        case CF_CIPHER("CAMELLIA_128_CTR"):
1320
            return EVP_camellia_128_ctr();
1321
        case CF_CIPHER("CAMELLIA_192_CTR"):
1322
            return EVP_camellia_192_ctr();
1323
        case CF_CIPHER("CAMELLIA_256_CTR"):
1324
            return EVP_camellia_256_ctr();
1325
        case CF_CIPHER("CHACHA20"):
1326
            return EVP_chacha20();
1327
        case CF_CIPHER("CHACHA20_POLY1305"):
1328
            return EVP_chacha20_poly1305();
1329
1330
        /*  Disabled due to unfixed memory issues with wrap ciphers:
1331
            https://github.com/openssl/openssl/issues/15728
1332
            https://github.com/openssl/openssl/issues/12073
1333
            https://github.com/openssl/openssl/issues/12014
1334
        */
1335
        //case CF_CIPHER("DES_EDE3_WRAP"):
1336
        //    return EVP_des_ede3_wrap();
1337
        //case CF_CIPHER("AES_128_WRAP"):
1338
        //    return EVP_aes_128_wrap();
1339
        //case CF_CIPHER("AES_128_WRAP_PAD"):
1340
        //    return EVP_aes_128_wrap_pad();
1341
        //case CF_CIPHER("AES_192_WRAP"):
1342
        //    return EVP_aes_192_wrap();
1343
        //case CF_CIPHER("AES_192_WRAP_PAD"):
1344
        //    return EVP_aes_192_wrap_pad();
1345
        //case CF_CIPHER("AES_256_WRAP"):
1346
        //    return EVP_aes_256_wrap();
1347
        //case CF_CIPHER("AES_256_WRAP_PAD"):
1348
        //    return EVP_aes_256_wrap_pad();
1349
#endif
1350
1.55k
        default:
1351
1.55k
            return nullptr;
1352
6.24k
    }
1353
6.24k
}
1354
1355
#if defined(CRYPTOFUZZ_BORINGSSL) || defined(CRYPTOFUZZ_LIBRESSL)
1356
4.43k
const EVP_AEAD* OpenSSL::toEVPAEAD(const component::SymmetricCipherType cipherType) const {
1357
4.43k
    static const std::map<uint64_t, const EVP_AEAD*> LUT = {
1358
4.43k
        { CF_CIPHER("CHACHA20_POLY1305"), EVP_aead_chacha20_poly1305() },
1359
4.43k
        { CF_CIPHER("XCHACHA20_POLY1305"), EVP_aead_xchacha20_poly1305() },
1360
4.43k
        { CF_CIPHER("AES_128_GCM"), EVP_aead_aes_128_gcm() },
1361
4.43k
        { CF_CIPHER("AES_256_GCM"), EVP_aead_aes_256_gcm() },
1362
#if defined(CRYPTOFUZZ_BORINGSSL)
1363
        { CF_CIPHER("AES_256_CBC_HMAC_SHA256"), EVP_aead_aes_128_ctr_hmac_sha256() },
1364
        { CF_CIPHER("AES_128_CTR_HMAC_SHA256"), EVP_aead_aes_128_ctr_hmac_sha256() },
1365
        { CF_CIPHER("AES_256_CTR_HMAC_SHA256"), EVP_aead_aes_256_ctr_hmac_sha256() },
1366
        { CF_CIPHER("AES_128_GCM_SIV"), EVP_aead_aes_128_gcm_siv() },
1367
        { CF_CIPHER("AES_256_GCM_SIV"), EVP_aead_aes_256_gcm_siv() },
1368
        { CF_CIPHER("AES_128_CCM_BLUETOOTH"), EVP_aead_aes_128_ccm_bluetooth() },
1369
        { CF_CIPHER("AES_128_CCM_BLUETOOTH_8"), EVP_aead_aes_128_ccm_bluetooth_8() },
1370
        { CF_CIPHER("AES_128_CBC_SHA1_TLS"), EVP_aead_aes_128_cbc_sha1_tls() },
1371
        { CF_CIPHER("AES_128_CBC_SHA1_TLS_IMPLICIT_IV"), EVP_aead_aes_128_cbc_sha1_tls_implicit_iv() },
1372
        { CF_CIPHER("AES_256_CBC_SHA1_TLS"), EVP_aead_aes_256_cbc_sha1_tls() },
1373
        { CF_CIPHER("AES_256_CBC_SHA1_TLS_IMPLICIT_IV"), EVP_aead_aes_256_cbc_sha1_tls_implicit_iv() },
1374
        { CF_CIPHER("DES_EDE3_CBC_SHA1_TLS"), EVP_aead_des_ede3_cbc_sha1_tls() },
1375
        { CF_CIPHER("DES_EDE3_CBC_SHA1_TLS_IMPLICIT_IV"), EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv() },
1376
        { CF_CIPHER("AES_128_GCM_TLS12"), EVP_aead_aes_128_gcm_tls12() },
1377
        { CF_CIPHER("AES_256_GCM_TLS12"), EVP_aead_aes_256_gcm_tls12() },
1378
        { CF_CIPHER("AES_128_GCM_TLS13"), EVP_aead_aes_128_gcm_tls13() },
1379
        { CF_CIPHER("AES_256_GCM_TLS13"), EVP_aead_aes_256_gcm_tls13() },
1380
#endif
1381
4.43k
    };
1382
1383
4.43k
    if ( LUT.find(cipherType.Get()) == LUT.end() ) {
1384
3.38k
        return nullptr;
1385
3.38k
    }
1386
1387
1.04k
    return LUT.at(cipherType.Get());
1388
4.43k
}
1389
#endif
1390
1391
978
std::optional<component::Digest> OpenSSL::OpDigest(operation::Digest& op) {
1392
978
    std::optional<component::Digest> ret = std::nullopt;
1393
978
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
1394
1395
978
    util::Multipart parts;
1396
1397
978
    CF_EVP_MD_CTX ctx(ds);
1398
978
    const EVP_MD* md = nullptr;
1399
1400
    /* Initialize */
1401
978
    {
1402
978
        parts = util::ToParts(ds, op.cleartext);
1403
978
        CF_CHECK_NE(md = toEVPMD(op.digestType), nullptr);
1404
644
        CF_CHECK_EQ(EVP_DigestInit_ex(ctx.GetPtr(), md, nullptr), 1);
1405
644
    }
1406
1407
    /* Process */
1408
41.1k
    for (const auto& part : parts) {
1409
41.1k
        CF_CHECK_EQ(EVP_DigestUpdate(ctx.GetPtr(), part.first, part.second), 1);
1410
41.1k
    }
1411
1412
    /* Finalize */
1413
644
    {
1414
644
        unsigned int len = -1;
1415
644
        unsigned char md[EVP_MAX_MD_SIZE];
1416
644
        CF_CHECK_EQ(EVP_DigestFinal_ex(ctx.GetPtr(), md, &len), 1);
1417
1418
644
        ret = component::Digest(md, len);
1419
644
    }
1420
1421
978
end:
1422
978
    return ret;
1423
644
}
1424
1425
#if !defined(CRYPTOFUZZ_BORINGSSL) && !defined(CRYPTOFUZZ_OPENSSL_098)
1426
871
std::optional<component::MAC> OpenSSL::OpHMAC_EVP(operation::HMAC& op, Datasource& ds) {
1427
871
    std::optional<component::MAC> ret = std::nullopt;
1428
1429
871
    util::Multipart parts;
1430
1431
871
    CF_EVP_MD_CTX ctx(ds);
1432
871
    const EVP_MD* md = nullptr;
1433
871
    EVP_PKEY *pkey = nullptr;
1434
1435
    /* Initialize */
1436
871
    {
1437
871
        parts = util::ToParts(ds, op.cleartext);
1438
1439
871
        CF_CHECK_NE(md = toEVPMD(op.digestType), nullptr);
1440
696
        CF_CHECK_NE(pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, nullptr, op.cipher.key.GetPtr(), op.cipher.key.GetSize()), nullptr);
1441
696
        CF_CHECK_EQ(EVP_DigestSignInit(ctx.GetPtr(), nullptr, md, nullptr, pkey), 1);
1442
696
    }
1443
1444
    /* Process */
1445
11.5k
    for (const auto& part : parts) {
1446
11.5k
        CF_CHECK_EQ(EVP_DigestSignUpdate(ctx.GetPtr(), part.first, part.second), 1);
1447
11.5k
    }
1448
1449
    /* Finalize */
1450
696
    {
1451
696
        size_t len = -1;
1452
696
        uint8_t out[EVP_MAX_MD_SIZE];
1453
696
        CF_CHECK_EQ(EVP_DigestSignFinal(ctx.GetPtr(), out, &len), 1);
1454
1455
696
        ret = component::MAC(out, len);
1456
696
    }
1457
1458
871
end:
1459
871
    EVP_PKEY_free(pkey);
1460
1461
871
    return ret;
1462
696
}
1463
#endif
1464
1465
#if !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_098)
1466
202
std::optional<component::MAC> OpenSSL::OpHMAC_HMAC(operation::HMAC& op, Datasource& ds) {
1467
202
    std::optional<component::MAC> ret = std::nullopt;
1468
1469
202
    util::Multipart parts;
1470
1471
202
    CF_HMAC_CTX ctx(ds);
1472
202
    const EVP_MD* md = nullptr;
1473
1474
    /* Initialize */
1475
202
    {
1476
202
        parts = util::ToParts(ds, op.cleartext);
1477
        /* TODO remove ? */
1478
202
        HMAC_CTX_reset(ctx.GetPtr());
1479
202
        CF_CHECK_NE(md = toEVPMD(op.digestType), nullptr);
1480
129
        CF_CHECK_EQ(HMAC_Init_ex(ctx.GetPtr(), op.cipher.key.GetPtr(), op.cipher.key.GetSize(), md, nullptr), 1);
1481
120
    }
1482
1483
    /* Process */
1484
5.03k
    for (const auto& part : parts) {
1485
5.03k
        CF_CHECK_EQ(HMAC_Update(ctx.GetPtr(), part.first, part.second), 1);
1486
5.03k
    }
1487
1488
    /* Finalize */
1489
120
    {
1490
120
        unsigned int len = -1;
1491
120
        uint8_t out[EVP_MAX_MD_SIZE];
1492
120
        CF_CHECK_EQ(HMAC_Final(ctx.GetPtr(), out, &len), 1);
1493
1494
120
        ret = component::MAC(out, len);
1495
120
    }
1496
1497
202
end:
1498
202
    return ret;
1499
120
}
1500
#endif
1501
1502
namespace OpenSSL_detail {
1503
30
    std::optional<component::MAC> SipHash(operation::HMAC& op) {
1504
30
        std::optional<component::MAC> ret = std::nullopt;
1505
#if defined(CRYPTOFUZZ_BORINGSSL)
1506
        if ( op.digestType.Get() != CF_DIGEST("SIPHASH64") ) {
1507
            return ret;
1508
        }
1509
        if ( op.cipher.key.GetSize() != 16 ) {
1510
            return ret;
1511
        }
1512
1513
        uint64_t key[2];
1514
        memcpy(&key[0], op.cipher.key.GetPtr(), 8);
1515
        memcpy(&key[1], op.cipher.key.GetPtr() + 8, 8);
1516
1517
        const auto ret_uint64_t = SIPHASH_24(key, op.cleartext.GetPtr(), op.cleartext.GetSize());
1518
1519
        uint8_t ret_uint8_t[8];
1520
        static_assert(sizeof(ret_uint8_t) == sizeof(ret_uint64_t));
1521
1522
        memcpy(ret_uint8_t, &ret_uint64_t, sizeof(ret_uint8_t));
1523
1524
        ret = component::MAC(ret_uint8_t, sizeof(ret_uint8_t));
1525
1526
        return ret;
1527
#elif defined(CRYPTOFUZZ_LIBRESSL) || defined(CRYPTOFUZZ_OPENSSL_102) || defined(CRYPTOFUZZ_OPENSSL_098)
1528
30
        (void)op;
1529
#else
1530
        Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
1531
1532
        size_t macSize;
1533
        util::Multipart parts;
1534
        uint8_t* out = nullptr;
1535
1536
        EVP_MAC* siphash = nullptr;
1537
        EVP_MAC_CTX *ctx = nullptr;
1538
        OSSL_PARAM params[3], *p = params;
1539
1540
        /* Initialize */
1541
        {
1542
            macSize = op.digestType.Get() == CF_DIGEST("SIPHASH64") ? 8 : 16;
1543
            parts = util::ToParts(ds, op.cleartext);
1544
            siphash = EVP_MAC_fetch(nullptr, "SIPHASH", nullptr);
1545
            ctx = EVP_MAC_CTX_new(siphash);
1546
1547
            unsigned int macSize_ui = macSize;
1548
            *p++ = OSSL_PARAM_construct_uint(OSSL_MAC_PARAM_SIZE, &macSize_ui);
1549
1550
            *p = OSSL_PARAM_construct_end();
1551
1552
            CF_CHECK_EQ(EVP_MAC_init(ctx, op.cipher.key.GetPtr(), op.cipher.key.GetSize(), params), 1);
1553
1554
            out = util::malloc(macSize);
1555
        }
1556
1557
        /* Process */
1558
        for (const auto& part : parts) {
1559
            CF_CHECK_EQ(EVP_MAC_update(ctx, part.first, part.second), 1);
1560
        }
1561
1562
        /* Finalize */
1563
        CF_CHECK_EQ(EVP_MAC_final(ctx, out, &macSize, macSize), 1);
1564
        ret = component::MAC(out, macSize);
1565
end:
1566
        util::free(out);
1567
1568
        EVP_MAC_CTX_free(ctx);
1569
        EVP_MAC_free(siphash);
1570
1571
#endif
1572
30
        return ret;
1573
30
    }
1574
}
1575
1576
#if !defined(CRYPTOFUZZ_OPENSSL_098)
1577
1.10k
std::optional<component::MAC> OpenSSL::OpHMAC(operation::HMAC& op) {
1578
1.10k
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
1579
1580
1.10k
    if (    op.digestType.Get() == CF_DIGEST("SIPHASH64") ||
1581
1.10k
            op.digestType.Get() == CF_DIGEST("SIPHASH128") ) {
1582
        /* Not HMAC but invoking SipHash here anyway due to convenience. */
1583
30
        return OpenSSL_detail::SipHash(op);
1584
30
    }
1585
1586
1.07k
    bool useEVP = true;
1587
1.07k
    try {
1588
1.07k
        useEVP = ds.Get<bool>();
1589
1.07k
    } catch ( fuzzing::datasource::Datasource::OutOfData& ) {
1590
204
    }
1591
1592
1.07k
    if ( useEVP == true ) {
1593
871
#if !defined(CRYPTOFUZZ_BORINGSSL)
1594
871
        return OpHMAC_EVP(op, ds);
1595
#else
1596
        return OpHMAC_HMAC(op, ds);
1597
#endif
1598
871
    } else {
1599
202
#if !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_098)
1600
202
        return OpHMAC_HMAC(op, ds);
1601
#else
1602
        return OpHMAC_EVP(op, ds);
1603
#endif
1604
202
    }
1605
1.07k
}
1606
#endif
1607
1608
2.25k
bool OpenSSL::checkSetIVLength(const uint64_t cipherType, const EVP_CIPHER* cipher, EVP_CIPHER_CTX* ctx, const size_t inputIvLength) const {
1609
2.25k
    bool ret = false;
1610
1611
2.25k
    const size_t ivLength = EVP_CIPHER_iv_length(cipher);
1612
2.25k
    const bool ivLengthMismatch = ivLength != inputIvLength;
1613
1614
2.25k
    if ( isAEAD(cipher, cipherType) == false ) {
1615
        /* Return true (success) if input IV length is expected IV length */
1616
1.90k
        return !ivLengthMismatch;
1617
1.90k
    }
1618
1619
353
    const bool isCCM = repository::IsCCM( cipherType );
1620
353
#if defined(CRYPTOFUZZ_LIBRESSL) || defined(CRYPTOFUZZ_OPENSSL_102)
1621
353
    const bool isGCM = repository::IsGCM( cipherType );
1622
353
#endif
1623
1624
    /* Only AEAD ciphers past this point */
1625
1626
    /* EVP_CIPHER_iv_length may return the wrong default IV length for CCM ciphers.
1627
     * Eg. EVP_CIPHER_iv_length returns 12 for EVP_aes_128_ccm() even though the
1628
     * IV length is actually.
1629
     *
1630
     * Hence, with CCM ciphers set the desired IV length always.
1631
     */
1632
1633
353
    if ( isCCM || ivLengthMismatch ) {
1634
#if defined(CRYPTOFUZZ_OPENSSL_098)
1635
        (void)ctx;
1636
        goto end;
1637
#elif defined(CRYPTOFUZZ_LIBRESSL) || defined(CRYPTOFUZZ_OPENSSL_102)
1638
303
        if ( isCCM == true ) {
1639
0
            CF_CHECK_EQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_IVLEN, inputIvLength, nullptr), 1);
1640
303
        } else if ( isGCM == true ) {
1641
277
            CF_CHECK_EQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, inputIvLength, nullptr), 1);
1642
211
        } else {
1643
26
            return false;
1644
26
        }
1645
#else
1646
        CF_CHECK_EQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, inputIvLength, nullptr), 1);
1647
#endif
1648
303
    }
1649
1650
261
    ret = true;
1651
327
end:
1652
1653
327
    return ret;
1654
261
}
1655
1656
2.12k
bool OpenSSL::checkSetKeyLength(const EVP_CIPHER* cipher, EVP_CIPHER_CTX* ctx, const size_t inputKeyLength) const {
1657
2.12k
    (void)ctx;
1658
1659
2.12k
    bool ret = false;
1660
1661
2.12k
    const size_t keyLength = EVP_CIPHER_key_length(cipher);
1662
2.12k
    if ( keyLength != inputKeyLength ) {
1663
489
        CF_CHECK_EQ(EVP_CIPHER_CTX_set_key_length(ctx, inputKeyLength), 1);
1664
424
    }
1665
1666
2.06k
    ret = true;
1667
1668
2.12k
end:
1669
2.12k
    return ret;
1670
2.06k
}
1671
1672
#if !defined(CRYPTOFUZZ_BORINGSSL)
1673
225
std::optional<component::Ciphertext> OpenSSL::OpSymmetricEncrypt_BIO(operation::SymmetricEncrypt& op, Datasource& ds) {
1674
225
    (void)ds;
1675
1676
225
    std::optional<component::Ciphertext> ret = std::nullopt;
1677
1678
    /* No support for AEAD tags and AAD with BIO */
1679
225
    if ( op.tagSize != std::nullopt || op.aad != std::nullopt ) {
1680
112
        return ret;
1681
112
    }
1682
1683
#if defined(CRYPTOFUZZ_OPENSSL_102)
1684
    /* WRAP ciphers crash in OpenSSL 1.0.2 */
1685
    if ( repository::IsWRAP(op.cipher.cipherType.Get()) ) {
1686
        return ret;
1687
    }
1688
#endif
1689
1690
113
    util::Multipart parts;
1691
1692
113
    const EVP_CIPHER* cipher = nullptr;
1693
113
    BIO* bio_cipher = nullptr;
1694
1695
113
    uint8_t* out = util::malloc(op.ciphertextSize);
1696
1697
    /* Initialization */
1698
113
    {
1699
113
        CF_CHECK_NE(cipher = toEVPCIPHER(op.cipher.cipherType), nullptr);
1700
1701
        /* TODO set key/iv size? */
1702
59
        CF_CHECK_EQ(static_cast<int>(op.cipher.key.GetSize()), EVP_CIPHER_key_length(cipher));
1703
38
        CF_CHECK_EQ(static_cast<int>(op.cipher.iv.GetSize()), EVP_CIPHER_iv_length(cipher));
1704
1705
12
        CF_CHECK_NE(bio_cipher = BIO_new(BIO_f_cipher()), nullptr);
1706
12
#if !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_098)
1707
        /* In OpenSSL 1.0.2 and 0.9.8, BIO_set_cipher does not return a value */
1708
12
        CF_CHECK_EQ(
1709
12
#endif
1710
12
                BIO_set_cipher(bio_cipher, cipher, op.cipher.key.GetPtr(), op.cipher.iv.GetPtr(), 1 /* encrypt */)
1711
12
#if !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_098)
1712
12
        , 1)
1713
11
#endif
1714
11
           ;
1715
11
    }
1716
1717
    /* Process */
1718
0
    {
1719
#if defined(CRYPTOFUZZ_OPENSSL_098)
1720
        BIO_push(bio_cipher, BIO_new_mem_buf((void*)op.cleartext.GetPtr(), op.cleartext.GetSize()));
1721
#else
1722
11
        BIO_push(bio_cipher, BIO_new_mem_buf(op.cleartext.GetPtr(), op.cleartext.GetSize()));
1723
11
#endif
1724
        //CF_CHECK_EQ(BIO_write(bio_out, op.cleartext.GetPtr(), op.cleartext.GetSize()), static_cast<int>(op.cleartext.GetSize()));
1725
11
    }
1726
1727
    /* Finalize */
1728
11
    {
1729
11
        int num;
1730
11
        CF_CHECK_GTE(num = BIO_read(bio_cipher, out, op.ciphertextSize), 0);
1731
1732
11
        CF_ASSERT(
1733
11
                num <= (int)op.ciphertextSize,
1734
11
                "BIO_read reports more written bytes than the buffer can hold");
1735
1736
11
        {
1737
            /* Check if more data can be read. If yes, then the buffer is too small.
1738
             * BIO_eof doesn't seem to work as expected here. */
1739
11
            int num2;
1740
11
            uint8_t out2[1];
1741
11
            CF_CHECK_EQ(num2 = BIO_read(bio_cipher, out2, sizeof(out2)), 0);
1742
10
        }
1743
1744
        /* Currently disabled to due length/padding mismatches with EVP, which are not necessarily OpenSSL's fault.
1745
         * (needs researching)
1746
         */
1747
        //ret = component::Ciphertext(Buffer(out, num));
1748
10
    }
1749
1750
113
end:
1751
113
    BIO_free_all(bio_cipher);
1752
113
    util::free(out);
1753
1754
113
    return ret;
1755
10
}
1756
#endif
1757
1758
1.42k
std::optional<component::Ciphertext> OpenSSL::OpSymmetricEncrypt_EVP(operation::SymmetricEncrypt& op, Datasource& ds) {
1759
1.42k
    std::optional<component::Ciphertext> ret = std::nullopt;
1760
1761
1.42k
    util::Multipart partsCleartext, partsAAD;
1762
1763
1.42k
    const EVP_CIPHER* cipher = nullptr;
1764
1.42k
    CF_EVP_CIPHER_CTX ctx(ds);
1765
1766
1.42k
    size_t out_size = op.ciphertextSize;
1767
1.42k
    size_t outIdx = 0;
1768
1.42k
    uint8_t* out = util::malloc(out_size);
1769
1.42k
    uint8_t* outTag = op.tagSize != std::nullopt ? util::malloc(*op.tagSize) : nullptr;
1770
1771
    /* Initialize */
1772
1.42k
    {
1773
1.42k
        CF_CHECK_NE(cipher = toEVPCIPHER(op.cipher.cipherType), nullptr);
1774
1.01k
        if ( op.tagSize != std::nullopt || op.aad != std::nullopt ) {
1775
            /* Trying to treat non-AEAD with AEAD-specific features (tag, aad)
1776
             * leads to all kinds of gnarly memory bugs in OpenSSL.
1777
             * It is quite arguably misuse of the OpenSSL API, so don't do this.
1778
             */
1779
173
            CF_CHECK_EQ(isAEAD(cipher, op.cipher.cipherType.Get()), true);
1780
95
        }
1781
1782
940
        if ( repository::IsWRAP(op.cipher.cipherType.Get()) ) {
1783
#if defined(CRYPTOFUZZ_OPENSSL_098)
1784
            goto end;
1785
#else
1786
25
            /* noret */ EVP_CIPHER_CTX_set_flags(ctx.GetPtr(), EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
1787
25
#endif
1788
25
        }
1789
940
        CF_CHECK_EQ(EVP_EncryptInit_ex(ctx.GetPtr(), cipher, nullptr, nullptr, nullptr), 1);
1790
1791
940
        if ( repository::IsWRAP(op.cipher.cipherType.Get()) ) {
1792
25
            partsCleartext = util::Multipart{ {op.cleartext.GetPtr(), op.cleartext.GetSize()} };
1793
915
        } else {
1794
            /* Convert cleartext to parts */
1795
915
            partsCleartext = util::CipherInputTransform(ds, op.cipher.cipherType, out, out_size, op.cleartext.GetPtr(), op.cleartext.GetSize());
1796
915
        }
1797
1798
940
        if ( op.aad != std::nullopt ) {
1799
74
            if ( repository::IsCCM( op.cipher.cipherType.Get() ) ) {
1800
                /* CCM does not support chunked AAD updating.
1801
                 * See: https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption#Authenticated_Encryption_using_CCM_mode
1802
                 */
1803
0
                partsAAD = { {op.aad->GetPtr(), op.aad->GetSize()} };
1804
74
            } else {
1805
74
                partsAAD = util::ToParts(ds, *(op.aad));
1806
74
            }
1807
74
        }
1808
1809
940
        if ( op.cipher.cipherType.Get() != CF_CIPHER("CHACHA20") ) {
1810
903
            CF_CHECK_EQ(checkSetIVLength(op.cipher.cipherType.Get(), cipher, ctx.GetPtr(), op.cipher.iv.GetSize()), true);
1811
817
        } else {
1812
37
            CF_CHECK_EQ(op.cipher.iv.GetSize(), 12);
1813
28
        }
1814
845
        CF_CHECK_EQ(checkSetKeyLength(cipher, ctx.GetPtr(), op.cipher.key.GetSize()), true);
1815
1816
821
        if ( op.cipher.cipherType.Get() != CF_CIPHER("CHACHA20") ) {
1817
793
            CF_CHECK_EQ(EVP_EncryptInit_ex(ctx.GetPtr(), nullptr, nullptr, op.cipher.key.GetPtr(), op.cipher.iv.GetPtr()), 1);
1818
793
        } else {
1819
            /* Prepend the 32 bit counter (which is 0) to the iv */
1820
28
            uint8_t cc20IV[16];
1821
28
            memset(cc20IV, 0, 4);
1822
28
            memcpy(cc20IV + 4, op.cipher.iv.GetPtr(), op.cipher.iv.GetSize());
1823
28
            CF_CHECK_EQ(EVP_EncryptInit_ex(ctx.GetPtr(), nullptr, nullptr, op.cipher.key.GetPtr(), cc20IV), 1);
1824
28
        }
1825
1826
        /* Disable ECB padding for consistency with mbed TLS */
1827
821
        if ( repository::IsECB(op.cipher.cipherType.Get()) ) {
1828
169
            CF_CHECK_EQ(EVP_CIPHER_CTX_set_padding(ctx.GetPtr(), 0), 1);
1829
169
        }
1830
821
    }
1831
1832
    /* Process */
1833
821
    {
1834
        /* If the cipher is CCM, the total cleartext size needs to be indicated explicitly
1835
         * https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption
1836
         */
1837
821
        if ( repository::IsCCM(op.cipher.cipherType.Get()) == true ) {
1838
0
            int len;
1839
0
            CF_CHECK_EQ(EVP_EncryptUpdate(ctx.GetPtr(), nullptr, &len, nullptr, op.cleartext.GetSize()), 1);
1840
0
        }
1841
1842
        /* Set AAD */
1843
821
        if ( op.aad != std::nullopt ) {
1844
1845
180
            for (const auto& part : partsAAD) {
1846
180
                int len;
1847
180
                CF_CHECK_EQ(EVP_EncryptUpdate(ctx.GetPtr(), nullptr, &len, part.first, part.second), 1);
1848
180
            }
1849
67
        }
1850
1851
21.3k
        for (const auto& part : partsCleartext) {
1852
21.3k
            if ( repository::IsWRAP(op.cipher.cipherType.Get()) ) {
1853
                /* WRAP ciphers don't honor the default rule */
1854
6
                CF_CHECK_GTE(out_size, part.second + EVP_CIPHER_block_size(cipher));
1855
21.3k
            } else {
1856
                /* "the amount of data written may be anything from zero bytes to (inl + cipher_block_size - 1)" */
1857
21.3k
                CF_CHECK_GTE(out_size, part.second + EVP_CIPHER_block_size(cipher) - 1);
1858
21.2k
            }
1859
1860
21.2k
            int len = -1;
1861
21.2k
            CF_CHECK_EQ(EVP_EncryptUpdate(ctx.GetPtr(), out + outIdx, &len, part.first, part.second), 1);
1862
21.2k
            outIdx += len;
1863
21.2k
            out_size -= len;
1864
21.2k
        }
1865
821
    }
1866
1867
    /* Finalize */
1868
753
    {
1869
753
        CF_CHECK_GTE(out_size, static_cast<size_t>(EVP_CIPHER_block_size(cipher)));
1870
1871
745
        int len = -1;
1872
745
        CF_CHECK_EQ(EVP_EncryptFinal_ex(ctx.GetPtr(), out + outIdx, &len), 1);
1873
745
        outIdx += len;
1874
1875
745
        if ( op.tagSize != std::nullopt ) {
1876
#if !defined(CRYPTOFUZZ_LIBRESSL) && !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_098)
1877
            /* Get tag.
1878
             *
1879
             * See comments around EVP_CTRL_AEAD_SET_TAG in OpSymmetricDecrypt_EVP for reasons
1880
             * as to why this is disabled for LibreSSL.
1881
             */
1882
            CF_CHECK_EQ(EVP_CIPHER_CTX_ctrl(ctx.GetPtr(), EVP_CTRL_AEAD_GET_TAG, *op.tagSize, outTag), 1);
1883
            ret = component::Ciphertext(Buffer(out, outIdx), Buffer(outTag, *op.tagSize));
1884
#endif
1885
723
        } else {
1886
723
            ret = component::Ciphertext(Buffer(out, outIdx));
1887
723
        }
1888
745
    }
1889
1890
1.42k
end:
1891
1892
1.42k
    util::free(out);
1893
1.42k
    util::free(outTag);
1894
1895
1.42k
    return ret;
1896
745
}
1897
1898
#if defined(CRYPTOFUZZ_BORINGSSL) || defined(CRYPTOFUZZ_LIBRESSL)
1899
198
std::optional<component::Ciphertext> OpenSSL::AEAD_Encrypt(operation::SymmetricEncrypt& op, Datasource& ds) {
1900
198
    (void)ds;
1901
1902
198
    std::optional<component::Ciphertext> ret = std::nullopt;
1903
1904
198
    const EVP_AEAD* aead = nullptr;
1905
198
    EVP_AEAD_CTX* ctx = nullptr;
1906
198
    size_t len;
1907
1908
198
    size_t out_size = op.ciphertextSize;
1909
198
    uint8_t* out = util::malloc(out_size);
1910
1911
198
    const size_t tagSize = op.tagSize != std::nullopt ? *op.tagSize : 0;
1912
1913
    /* Initialize */
1914
198
    {
1915
198
        CF_CHECK_NE(aead = toEVPAEAD(op.cipher.cipherType), nullptr);
1916
198
#if defined(CRYPTOFUZZ_LIBRESSL)
1917
198
    CF_CHECK_NE(ctx = EVP_AEAD_CTX_new(), nullptr);
1918
198
        CF_CHECK_NE(EVP_AEAD_CTX_init(
1919
198
                    ctx,
1920
198
                    aead,
1921
198
                    op.cipher.key.GetPtr(),
1922
198
                    op.cipher.key.GetSize(),
1923
198
                    tagSize,
1924
198
                    nullptr), 0);
1925
#else /* CRYPTOFUZZ_BORINGSSL */
1926
        CF_CHECK_NE(ctx = EVP_AEAD_CTX_new(
1927
                    aead,
1928
                    op.cipher.key.GetPtr(),
1929
                    op.cipher.key.GetSize(),
1930
                    tagSize), nullptr);
1931
#endif
1932
136
    }
1933
1934
    /* Process */
1935
0
    {
1936
136
        CF_CHECK_NE(EVP_AEAD_CTX_seal(ctx,
1937
136
                    out,
1938
136
                    &len,
1939
136
                    out_size,
1940
136
                    op.cipher.iv.GetPtr(),
1941
136
                    op.cipher.iv.GetSize(),
1942
136
                    op.cleartext.GetPtr(),
1943
136
                    op.cleartext.GetSize(),
1944
136
                    op.aad != std::nullopt ? op.aad->GetPtr() : nullptr,
1945
136
                    op.aad != std::nullopt ? op.aad->GetSize() : 0),
1946
136
                0);
1947
98
    }
1948
1949
    /* Finalize */
1950
0
    {
1951
98
        size_t tagSize2 = tagSize;
1952
#if defined(CRYPTOFUZZ_BORINGSSL)
1953
        if ( tagSize == 0 ) {
1954
            CF_CHECK_EQ(EVP_AEAD_CTX_tag_len(ctx, &tagSize2, op.cleartext.GetSize(), 0), 1);
1955
        }
1956
#elif defined(CRYPTOFUZZ_LIBRESSL)
1957
        /* LibreSSL does not have EVP_AEAD_CTX_tag_len */
1958
98
        CF_CHECK_NE(tagSize, 0);
1959
13
#endif
1960
1961
        /* The tag should be part of the output.
1962
         * Hence, the total output size should be equal or greater than the tag size.
1963
         * Note that removing this check will lead to an overflow below. */
1964
13
        CF_ASSERT(op.cleartext.GetSize() + tagSize2 == len, "input + tag size != output length");
1965
1966
13
        if ( tagSize != 0 ) {
1967
13
            const size_t ciphertextSize = len - tagSize2;
1968
13
            ret = component::Ciphertext(Buffer(out, ciphertextSize), Buffer(out + ciphertextSize, tagSize));
1969
13
        } else {
1970
            /* Do not set ret if tag size is 0; the AEAD API cannot decrypt inputs whose tag size is 0,
1971
             * because it interprets a tag size of 0 as the default tag size
1972
             */
1973
0
        }
1974
13
    }
1975
1976
198
end:
1977
198
    CF_NORET(EVP_AEAD_CTX_free(ctx));
1978
1979
198
    util::free(out);
1980
1981
198
    return ret;
1982
13
}
1983
#endif
1984
1985
114
std::optional<component::Ciphertext> OpenSSL::AES_Encrypt(operation::SymmetricEncrypt& op, Datasource& ds) {
1986
114
    (void)ds;
1987
1988
114
    std::optional<component::Ciphertext> ret = std::nullopt;
1989
1990
114
    AES_KEY key;
1991
114
    uint8_t* out = nullptr;
1992
1993
    /* Initialize */
1994
114
    {
1995
114
        CF_CHECK_EQ(op.aad, std::nullopt);
1996
92
        CF_CHECK_EQ(op.tagSize, std::nullopt);
1997
73
        CF_CHECK_EQ(op.cipher.iv.GetSize(), 0);
1998
39
        CF_CHECK_GT(op.cleartext.GetSize(), 0);
1999
21
        CF_CHECK_GTE(op.ciphertextSize, op.cleartext.GetSize());
2000
17
        CF_CHECK_EQ(op.cleartext.GetSize() % 16, 0);
2001
17
        CF_CHECK_EQ(AES_set_encrypt_key(op.cipher.key.GetPtr(), op.cipher.key.GetSize() * 8, &key), 0);
2002
0
    }
2003
2004
    /* Process */
2005
0
    {
2006
#if 0
2007
        bool useOverlap = false;
2008
        uint64_t cleartextIndex;
2009
        try {
2010
            bool _useOverlap = ds.Get<bool>();
2011
            if ( _useOverlap == true ) {
2012
                cleartextIndex = ds.Get<uint64_t>() % op.cleartext.GetSize();
2013
                useOverlap = true;
2014
            }
2015
        } catch ( fuzzing::datasource::Datasource::OutOfData& ) {
2016
        }
2017
2018
        if ( useOverlap == true ) {
2019
            /* in and out are allowed to overlap */
2020
            out = (uint8_t*)malloc(op.cleartext.GetSize() + cleartextIndex);
2021
            memcpy(out + cleartextIndex, op.cleartext.GetPtr(), op.cleartext.GetSize());
2022
2023
            for (size_t i = 0; i < op.cleartext.GetSize(); i += 16) {
2024
                AES_encrypt(out + cleartextIndex + i, out + i, &key);
2025
            }
2026
        } else
2027
#endif
2028
0
        {
2029
0
            out = (uint8_t*)malloc(op.ciphertextSize);
2030
2031
0
            for (size_t i = 0; i < op.cleartext.GetSize(); i += 16) {
2032
0
                AES_encrypt(op.cleartext.GetPtr() + i, out + i, &key);
2033
0
            }
2034
0
        }
2035
0
    }
2036
2037
    /* Finalize */
2038
0
    {
2039
0
        ret = component::Ciphertext(Buffer(out, op.cleartext.GetSize()));
2040
0
    }
2041
2042
114
end:
2043
2044
114
    free(out);
2045
2046
114
    return ret;
2047
0
}
2048
2049
2.00k
std::optional<component::Ciphertext> OpenSSL::OpSymmetricEncrypt(operation::SymmetricEncrypt& op) {
2050
2.00k
#if defined(CRYPTOFUZZ_LIBRESSL)
2051
    /* LibreSSL will encrypt, but not decrypt, CHACHA20_POLY1305 with empty tag.
2052
     * See also https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=52890
2053
     */
2054
2.00k
    if ( op.cipher.cipherType.Is(CF_CIPHER("CHACHA20_POLY1305")) ) {
2055
71
        if ( op.tagSize == std::nullopt ) {
2056
20
            return std::nullopt;
2057
20
        }
2058
51
        if ( *op.tagSize == 0 ) {
2059
23
            return std::nullopt;
2060
23
        }
2061
51
    }
2062
1.96k
#endif
2063
2064
1.96k
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
2065
2066
1.96k
    if ( op.cipher.cipherType.Get() == CF_CIPHER("AES") ) {
2067
114
        return AES_Encrypt(op, ds);
2068
114
    }
2069
2070
#if defined(CRYPTOFUZZ_OPENSSL_110)
2071
    if ( repository::IsCCM( op.cipher.cipherType.Get() ) ) {
2072
        return std::nullopt;
2073
    }
2074
#endif
2075
2076
#if defined(CRYPTOFUZZ_OPENSSL_102) || defined(CRYPTOFUZZ_OPENSSL_110)
2077
    /* Prevent OOB write for large keys in RC5.
2078
     * Fixed in OpenSSL master, but will not be fixed for OpenSSL 1.0.2 and 1.1.0
2079
     */
2080
    if ( op.cipher.key.GetSize() > 255 ) {
2081
        switch ( op.cipher.cipherType.Get() ) {
2082
            case CF_CIPHER("RC5_32_12_16_ECB"):
2083
            case CF_CIPHER("RC5_32_12_16_CFB"):
2084
            case CF_CIPHER("RC5_32_12_16_OFB"):
2085
            case CF_CIPHER("RC5_32_12_16_CBC"):
2086
                return std::nullopt;
2087
        }
2088
    }
2089
#endif
2090
2091
1.84k
    bool useEVP = true;
2092
1.84k
    try {
2093
1.84k
        useEVP = ds.Get<bool>();
2094
1.84k
    } catch ( fuzzing::datasource::Datasource::OutOfData& ) {
2095
475
    }
2096
2097
1.84k
#if defined(CRYPTOFUZZ_BORINGSSL) || defined(CRYPTOFUZZ_LIBRESSL)
2098
1.84k
    if ( toEVPAEAD(op.cipher.cipherType) != nullptr ) {
2099
301
        try {
2100
301
            if ( ds.Get<bool>() == true ) {
2101
198
                return AEAD_Encrypt(op, ds);
2102
198
            }
2103
2104
            /* Fall through to OpSymmetricEncrypt_EVP/OpSymmetricEncrypt_BIO */
2105
2106
301
        } catch ( fuzzing::datasource::Datasource::OutOfData& ) { }
2107
301
    }
2108
1.64k
#endif
2109
2110
1.64k
    if ( useEVP == true ) {
2111
1.42k
        return OpSymmetricEncrypt_EVP(op, ds);
2112
1.42k
    } else {
2113
225
#if !defined(CRYPTOFUZZ_BORINGSSL)
2114
225
        return OpSymmetricEncrypt_BIO(op, ds);
2115
#else
2116
        return OpSymmetricEncrypt_EVP(op, ds);
2117
#endif
2118
225
    }
2119
1.64k
}
2120
2121
#if !defined(CRYPTOFUZZ_BORINGSSL)
2122
270
std::optional<component::Cleartext> OpenSSL::OpSymmetricDecrypt_BIO(operation::SymmetricDecrypt& op, Datasource& ds) {
2123
270
    (void)ds;
2124
2125
270
    std::optional<component::Cleartext> ret = std::nullopt;
2126
2127
    /* No support for AEAD tags and AAD with BIO */
2128
270
    if ( op.aad != std::nullopt || op.tag != std::nullopt ) {
2129
39
        return ret;
2130
39
    }
2131
2132
#if defined(CRYPTOFUZZ_OPENSSL_102)
2133
    /* WRAP ciphers crash in OpenSSL 1.0.2 */
2134
    if ( repository::IsWRAP(op.cipher.cipherType.Get()) ) {
2135
        return ret;
2136
    }
2137
#endif
2138
2139
231
    util::Multipart parts;
2140
2141
231
    const EVP_CIPHER* cipher = nullptr;
2142
231
    BIO* bio_cipher = nullptr;
2143
2144
231
    uint8_t* out = util::malloc(op.cleartextSize);
2145
2146
    /* Initialization */
2147
231
    {
2148
231
        CF_CHECK_NE(cipher = toEVPCIPHER(op.cipher.cipherType), nullptr);
2149
2150
        /* TODO set key/iv size? */
2151
159
        CF_CHECK_EQ(static_cast<int>(op.cipher.key.GetSize()), EVP_CIPHER_key_length(cipher));
2152
143
        CF_CHECK_EQ(static_cast<int>(op.cipher.iv.GetSize()), EVP_CIPHER_iv_length(cipher));
2153
2154
108
        CF_CHECK_NE(bio_cipher = BIO_new(BIO_f_cipher()), nullptr);
2155
108
#if !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_098)
2156
        /* In OpenSSL 1.0.2, BIO_set_cipher does not return a value */
2157
108
        CF_CHECK_EQ(
2158
108
#endif
2159
108
                BIO_set_cipher(bio_cipher, cipher, op.cipher.key.GetPtr(), op.cipher.iv.GetPtr(), 0 /* decrypt */)
2160
108
#if !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_098)
2161
108
        , 1)
2162
101
#endif
2163
101
           ;
2164
101
    }
2165
2166
    /* Process */
2167
0
    {
2168
#if defined(CRYPTOFUZZ_OPENSSL_098)
2169
        BIO_push(bio_cipher, BIO_new_mem_buf((void*)op.ciphertext.GetPtr(), op.ciphertext.GetSize()));
2170
#else
2171
101
        BIO_push(bio_cipher, BIO_new_mem_buf(op.ciphertext.GetPtr(), op.ciphertext.GetSize()));
2172
101
#endif
2173
        //CF_CHECK_EQ(BIO_write(bio_out, op.cleartext.GetPtr(), op.cleartext.GetSize()), static_cast<int>(op.cleartext.GetSize()));
2174
101
    }
2175
2176
    /* Finalize */
2177
101
    {
2178
101
        int num;
2179
101
        CF_CHECK_GTE(num = BIO_read(bio_cipher, out, op.cleartextSize), 0);
2180
2181
101
        CF_ASSERT(
2182
101
                num <= (int)op.cleartextSize,
2183
101
                "BIO_read reports more written bytes than the buffer can hold");
2184
2185
101
        {
2186
            /* Check if more data can be read. If yes, then the buffer is too small.
2187
             * BIO_eof doesn't seem to work as expected here. */
2188
101
            int num2;
2189
101
            uint8_t out2[1];
2190
101
            CF_CHECK_EQ(num2 = BIO_read(bio_cipher, out2, sizeof(out2)), 0);
2191
55
        }
2192
2193
        /* Currently disabled to due length/padding mismatches with EVP, which are not necessarily OpenSSL's fault.
2194
         * (needs researching)
2195
         */
2196
        //ret = component::Cleartext(out, num);
2197
55
    }
2198
2199
231
end:
2200
231
    BIO_free_all(bio_cipher);
2201
231
    util::free(out);
2202
2203
231
    return ret;
2204
55
}
2205
#endif
2206
2207
1.75k
std::optional<component::Cleartext> OpenSSL::OpSymmetricDecrypt_EVP(operation::SymmetricDecrypt& op, Datasource& ds) {
2208
1.75k
    std::optional<component::Cleartext> ret = std::nullopt;
2209
2210
1.75k
    util::Multipart partsCiphertext, partsAAD;
2211
2212
1.75k
    const EVP_CIPHER* cipher = nullptr;
2213
1.75k
    CF_EVP_CIPHER_CTX ctx(ds);
2214
2215
1.75k
    size_t out_size = op.cleartextSize;
2216
1.75k
    size_t outIdx = 0;
2217
1.75k
    uint8_t* out = util::malloc(out_size);
2218
2219
    /* Initialize */
2220
1.75k
    {
2221
1.75k
        CF_CHECK_NE(cipher = toEVPCIPHER(op.cipher.cipherType), nullptr);
2222
1.44k
        if ( op.tag != std::nullopt || op.aad != std::nullopt ) {
2223
            /* Trying to treat non-AEAD with AEAD-specific features (tag, aad)
2224
             * leads to all kinds of gnarly memory bugs in OpenSSL.
2225
             * It is quite arguably misuse of the OpenSSL API, so don't do this.
2226
             */
2227
133
            CF_CHECK_EQ(isAEAD(cipher, op.cipher.cipherType.Get()), true);
2228
69
        }
2229
2230
1.38k
        if ( repository::IsWRAP(op.cipher.cipherType.Get()) ) {
2231
#if defined(CRYPTOFUZZ_OPENSSL_098)
2232
            goto end;
2233
#else
2234
13
            /* noret */ EVP_CIPHER_CTX_set_flags(ctx.GetPtr(), EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
2235
13
#endif
2236
13
        }
2237
2238
1.38k
        CF_CHECK_EQ(EVP_DecryptInit_ex(ctx.GetPtr(), cipher, nullptr, nullptr, nullptr), 1);
2239
2240
1.38k
        if ( repository::IsWRAP(op.cipher.cipherType.Get()) ) {
2241
13
            partsCiphertext = util::Multipart{ {op.ciphertext.GetPtr(), op.ciphertext.GetSize()} };
2242
1.36k
        } else {
2243
            /* Convert ciphertext to parts */
2244
1.36k
            partsCiphertext = util::CipherInputTransform(ds, op.cipher.cipherType, out, out_size, op.ciphertext.GetPtr(), op.ciphertext.GetSize());
2245
1.36k
        }
2246
2247
1.38k
        if ( op.aad != std::nullopt ) {
2248
67
            if ( repository::IsCCM( op.cipher.cipherType.Get() ) ) {
2249
                /* CCM does not support chunked AAD updating.
2250
                 * See: https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption#Authenticated_Encryption_using_CCM_mode
2251
                 */
2252
0
                partsAAD = { {op.aad->GetPtr(), op.aad->GetSize()} };
2253
67
            } else {
2254
67
                partsAAD = util::ToParts(ds, *(op.aad));
2255
67
            }
2256
67
        }
2257
2258
1.38k
        if ( op.cipher.cipherType.Get() != CF_CIPHER("CHACHA20") ) {
2259
1.35k
            CF_CHECK_EQ(checkSetIVLength(op.cipher.cipherType.Get(), cipher, ctx.GetPtr(), op.cipher.iv.GetSize()), true);
2260
1.25k
        } else {
2261
29
            CF_CHECK_EQ(op.cipher.iv.GetSize(), 12);
2262
27
        }
2263
1.28k
        CF_CHECK_EQ(checkSetKeyLength(cipher, ctx.GetPtr(), op.cipher.key.GetSize()), true);
2264
2265
#if !defined(CRYPTOFUZZ_LIBRESSL) && !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_098)
2266
        /* Set tag.
2267
         *
2268
         * LibreSSL supports setting the tag via the EVP interface with EVP_CTRL_GCM_SET_TAG for GCM,
2269
         * and EVP_CTRL_CCM_SET_TAG for CCM, but does not provide a generic setter like EVP_CTRL_AEAD_SET_TAG
2270
         * that also sets the tag for chacha20-poly1305.
2271
         * At the moment, LibreSSL should never arrive here if tag is not nullopt; it is direct to AEAD_Decrypt
2272
         * in that case.
2273
         * Later, this can be changed to use the EVP interface for GCM and CCM ciphers.
2274
         */
2275
        if ( op.tag != std::nullopt ) {
2276
            CF_CHECK_EQ(EVP_CIPHER_CTX_ctrl(ctx.GetPtr(), EVP_CTRL_AEAD_SET_TAG, op.tag->GetSize(), (void*)op.tag->GetPtr()), 1);
2277
        }
2278
#endif
2279
1.24k
        if ( op.cipher.cipherType.Get() != CF_CIPHER("CHACHA20") ) {
2280
1.21k
            CF_CHECK_EQ(EVP_DecryptInit_ex(ctx.GetPtr(), nullptr, nullptr, op.cipher.key.GetPtr(), op.cipher.iv.GetPtr()), 1);
2281
1.21k
        } else {
2282
            /* Prepend the 32 bit counter (which is 0) to the iv */
2283
27
            uint8_t cc20IV[16];
2284
27
            memset(cc20IV, 0, 4);
2285
27
            memcpy(cc20IV + 4, op.cipher.iv.GetPtr(), op.cipher.iv.GetSize());
2286
27
            CF_CHECK_EQ(EVP_DecryptInit_ex(ctx.GetPtr(), nullptr, nullptr, op.cipher.key.GetPtr(), cc20IV), 1);
2287
27
        }
2288
2289
        /* Disable ECB padding for consistency with mbed TLS */
2290
1.24k
        if ( repository::IsECB(op.cipher.cipherType.Get()) ) {
2291
148
            CF_CHECK_EQ(EVP_CIPHER_CTX_set_padding(ctx.GetPtr(), 0), 1);
2292
148
        }
2293
1.24k
    }
2294
2295
    /* Process */
2296
1.24k
    {
2297
        /* If the cipher is CCM, the total cleartext size needs to be indicated explicitly
2298
         * https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption
2299
         */
2300
1.24k
        if ( repository::IsCCM(op.cipher.cipherType.Get()) == true ) {
2301
0
            int len;
2302
0
            CF_CHECK_EQ(EVP_DecryptUpdate(ctx.GetPtr(), nullptr, &len, nullptr, op.ciphertext.GetSize()), 1);
2303
0
        }
2304
2305
        /* Set AAD */
2306
1.24k
        if ( op.aad != std::nullopt ) {
2307
16
            for (const auto& part : partsAAD) {
2308
16
                int len;
2309
16
                CF_CHECK_EQ(EVP_DecryptUpdate(ctx.GetPtr(), nullptr, &len, part.first, part.second), 1);
2310
16
            }
2311
16
        }
2312
2313
        /* Set ciphertext */
2314
14.2k
        for (const auto& part : partsCiphertext) {
2315
14.2k
            CF_CHECK_GTE(out_size, part.second + EVP_CIPHER_block_size(cipher));
2316
2317
14.1k
            int len = -1;
2318
14.1k
            CF_CHECK_EQ(EVP_DecryptUpdate(ctx.GetPtr(), out + outIdx, &len, part.first, part.second), 1);
2319
2320
14.1k
            outIdx += len;
2321
14.1k
            out_size -= len;
2322
14.1k
        }
2323
1.24k
    }
2324
2325
    /* Finalize */
2326
1.17k
    {
2327
1.17k
        CF_CHECK_GTE(out_size, static_cast<size_t>(EVP_CIPHER_block_size(cipher)));
2328
2329
1.17k
        int len = -1;
2330
1.17k
        CF_CHECK_EQ(EVP_DecryptFinal_ex(ctx.GetPtr(), out + outIdx, &len), 1);
2331
953
        outIdx += len;
2332
2333
953
        ret = component::Cleartext(out, outIdx);
2334
953
    }
2335
2336
1.75k
end:
2337
2338
1.75k
    util::free(out);
2339
2340
1.75k
    return ret;
2341
953
}
2342
2343
#if defined(CRYPTOFUZZ_BORINGSSL) || defined(CRYPTOFUZZ_LIBRESSL)
2344
180
std::optional<component::Cleartext> OpenSSL::AEAD_Decrypt(operation::SymmetricDecrypt& op, Datasource& ds) {
2345
180
    (void)ds;
2346
2347
180
    std::optional<component::Cleartext> ret = std::nullopt;
2348
2349
180
    const EVP_AEAD* aead = nullptr;
2350
180
    EVP_AEAD_CTX* ctx = nullptr;
2351
180
    size_t len;
2352
2353
180
    size_t out_size = op.cleartextSize;
2354
180
    uint8_t* out = util::malloc(out_size);
2355
2356
180
    const size_t tagSize = op.tag != std::nullopt ? op.tag->GetSize() : 0;
2357
2358
    /* Initialize */
2359
180
    {
2360
180
        CF_CHECK_NE(aead = toEVPAEAD(op.cipher.cipherType), nullptr);
2361
180
#if defined(CRYPTOFUZZ_LIBRESSL)
2362
180
    CF_CHECK_NE(ctx = EVP_AEAD_CTX_new(), nullptr);
2363
180
        CF_CHECK_NE(EVP_AEAD_CTX_init(
2364
180
                    ctx,
2365
180
                    aead,
2366
180
                    op.cipher.key.GetPtr(),
2367
180
                    op.cipher.key.GetSize(),
2368
180
                    tagSize,
2369
180
                    nullptr), 0);
2370
#else /* CRYPTOFUZZ_BORINGSSL */
2371
        CF_CHECK_NE(ctx = EVP_AEAD_CTX_new(
2372
                    aead,
2373
                    op.cipher.key.GetPtr(),
2374
                    op.cipher.key.GetSize(),
2375
                    tagSize), nullptr);
2376
#endif
2377
153
    }
2378
2379
    /* Process */
2380
0
    {
2381
        /* OpenSSL and derivates consume the ciphertext + tag in concatenated form */
2382
153
        std::vector<uint8_t> ciphertextAndTag(op.ciphertext.GetSize() + tagSize);
2383
153
        memcpy(ciphertextAndTag.data(), op.ciphertext.GetPtr(), op.ciphertext.GetSize());
2384
153
        if ( tagSize > 0 ) {
2385
68
            memcpy(ciphertextAndTag.data() + op.ciphertext.GetSize(), op.tag->GetPtr(), tagSize);
2386
68
        }
2387
2388
153
        CF_CHECK_NE(EVP_AEAD_CTX_open(ctx,
2389
153
                    out,
2390
153
                    &len,
2391
153
                    out_size,
2392
153
                    op.cipher.iv.GetPtr(),
2393
153
                    op.cipher.iv.GetSize(),
2394
153
                    ciphertextAndTag.data(),
2395
153
                    ciphertextAndTag.size(),
2396
153
                    op.aad != std::nullopt ? op.aad->GetPtr() : nullptr,
2397
153
                    op.aad != std::nullopt ? op.aad->GetSize() : 0),
2398
153
                0);
2399
3
    }
2400
2401
    /* Finalize */
2402
0
    {
2403
3
        ret = component::Cleartext(out, len);
2404
3
    }
2405
2406
180
end:
2407
180
    CF_NORET(EVP_AEAD_CTX_free(ctx));
2408
2409
180
    util::free(out);
2410
2411
180
    return ret;
2412
3
}
2413
#endif
2414
2415
57
std::optional<component::Cleartext> OpenSSL::AES_Decrypt(operation::SymmetricDecrypt& op, Datasource& ds) {
2416
57
    (void)ds;
2417
2418
57
    std::optional<component::Cleartext> ret = std::nullopt;
2419
2420
57
    AES_KEY key;
2421
57
    uint8_t* out = nullptr;
2422
2423
    /* Initialize */
2424
57
    {
2425
57
        CF_CHECK_EQ(op.aad, std::nullopt);
2426
45
        CF_CHECK_EQ(op.tag, std::nullopt);
2427
35
        CF_CHECK_EQ(op.cipher.iv.GetSize(), 0);
2428
32
        CF_CHECK_GT(op.ciphertext.GetSize(), 0);
2429
22
        CF_CHECK_GTE(op.cleartextSize, op.ciphertext.GetSize());
2430
19
        CF_CHECK_EQ(op.ciphertext.GetSize() % 16, 0);
2431
0
        CF_CHECK_EQ(AES_set_decrypt_key(op.cipher.key.GetPtr(), op.cipher.key.GetSize() * 8, &key), 0);
2432
0
    }
2433
2434
    /* Process */
2435
0
    {
2436
#if 0
2437
        bool useOverlap = false;
2438
        uint64_t ciphertextIndex;
2439
        try {
2440
            bool _useOverlap = ds.Get<bool>();
2441
            if ( _useOverlap == true ) {
2442
                ciphertextIndex = ds.Get<uint64_t>() % op.ciphertext.GetSize();
2443
                useOverlap = true;
2444
            }
2445
        } catch ( fuzzing::datasource::Datasource::OutOfData& ) {
2446
        }
2447
2448
        if ( useOverlap == true ) {
2449
            /* in and out are allowed to overlap */
2450
            out = (uint8_t*)malloc(op.ciphertext.GetSize() + ciphertextIndex);
2451
            memcpy(out + ciphertextIndex, op.ciphertext.GetPtr(), op.ciphertext.GetSize());
2452
2453
            for (size_t i = 0; i < op.ciphertext.GetSize(); i += 16) {
2454
                AES_decrypt(out + ciphertextIndex + i, out + i, &key);
2455
            }
2456
        } else
2457
#endif
2458
0
        {
2459
0
            out = (uint8_t*)malloc(op.cleartextSize);
2460
2461
0
            for (size_t i = 0; i < op.ciphertext.GetSize(); i += 16) {
2462
0
                AES_decrypt(op.ciphertext.GetPtr() + i, out + i, &key);
2463
0
            }
2464
0
        }
2465
0
    }
2466
2467
    /* Finalize */
2468
0
    {
2469
0
        ret = component::Cleartext(out, op.ciphertext.GetSize());
2470
0
    }
2471
2472
57
end:
2473
2474
57
    free(out);
2475
2476
57
    return ret;
2477
0
}
2478
2479
2.26k
std::optional<component::Cleartext> OpenSSL::OpSymmetricDecrypt(operation::SymmetricDecrypt& op) {
2480
2.26k
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
2481
2482
2.26k
    if ( op.cipher.cipherType.Get() == CF_CIPHER("AES") ) {
2483
57
        return AES_Decrypt(op, ds);
2484
57
    }
2485
2486
#if defined(CRYPTOFUZZ_OPENSSL_102) || defined(CRYPTOFUZZ_OPENSSL_110)
2487
    /* Prevent OOB write for large keys in RC5.
2488
     * Fixed in OpenSSL master, but will not be fixed for OpenSSL 1.0.2 and 1.1.0
2489
     */
2490
    if ( op.cipher.key.GetSize() > 255 ) {
2491
        switch ( op.cipher.cipherType.Get() ) {
2492
            case CF_CIPHER("RC5_32_12_16_ECB"):
2493
            case CF_CIPHER("RC5_32_12_16_CFB"):
2494
            case CF_CIPHER("RC5_32_12_16_OFB"):
2495
            case CF_CIPHER("RC5_32_12_16_CBC"):
2496
                return std::nullopt;
2497
        }
2498
    }
2499
#endif
2500
2501
2.20k
    bool useEVP = true;
2502
2.20k
    try {
2503
2.20k
        useEVP = ds.Get<bool>();
2504
2.20k
    } catch ( fuzzing::datasource::Datasource::OutOfData& ) {
2505
1.02k
    }
2506
2507
2.20k
#if defined(CRYPTOFUZZ_BORINGSSL) || defined(CRYPTOFUZZ_LIBRESSL)
2508
2.20k
    if ( toEVPAEAD(op.cipher.cipherType) != nullptr ) {
2509
369
        if ( op.tag != std::nullopt || op.aad != std::nullopt ) {
2510
            /* See comment at OpSymmetricEncrypt */
2511
180
            return AEAD_Decrypt(op, ds);
2512
180
        }
2513
369
    }
2514
2.02k
#endif
2515
2516
2.02k
    if ( useEVP == true ) {
2517
1.75k
        return OpSymmetricDecrypt_EVP(op, ds);
2518
1.75k
    } else {
2519
270
#if !defined(CRYPTOFUZZ_BORINGSSL)
2520
270
        return OpSymmetricDecrypt_BIO(op, ds);
2521
#else
2522
        return OpSymmetricDecrypt_EVP(op, ds);
2523
#endif
2524
270
    }
2525
2.02k
}
2526
2527
#if !defined(CRYPTOFUZZ_BORINGSSL) && !defined(CRYPTOFUZZ_LIBRESSL) && !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_110) && !defined(CRYPTOFUZZ_OPENSSL_098)
2528
std::optional<component::Key> OpenSSL::OpKDF_SCRYPT_EVP_PKEY(operation::KDF_SCRYPT& op) const {
2529
    std::optional<component::Key> ret = std::nullopt;
2530
    EVP_PKEY_CTX* pctx = nullptr;
2531
2532
    size_t out_size = op.keySize;
2533
    uint8_t* out = util::malloc(out_size);
2534
2535
    /* Initialize */
2536
    {
2537
        CF_CHECK_NE(pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SCRYPT, nullptr), nullptr);
2538
        CF_CHECK_EQ(EVP_PKEY_derive_init(pctx), 1);
2539
        CF_CHECK_EQ(EVP_PKEY_CTX_set1_pbe_pass(pctx, (const char*)op.password.GetPtr(), op.password.GetSize()), 1);
2540
        CF_CHECK_EQ(EVP_PKEY_CTX_set1_scrypt_salt(pctx, op.salt.GetPtr(), op.salt.GetSize()), 1);
2541
        CF_CHECK_EQ(EVP_PKEY_CTX_set_scrypt_N(pctx, op.N) , 1);
2542
        CF_CHECK_EQ(EVP_PKEY_CTX_set_scrypt_r(pctx, op.r) , 1);
2543
        CF_CHECK_EQ(EVP_PKEY_CTX_set_scrypt_p(pctx, op.p) , 1);
2544
    }
2545
2546
    /* Process/finalize */
2547
    {
2548
        CF_CHECK_EQ(EVP_PKEY_derive(pctx, out, &out_size) , 1);
2549
2550
        CF_CHECK_NE(out, nullptr);
2551
2552
        ret = component::Key(out, out_size);
2553
    }
2554
2555
end:
2556
    EVP_PKEY_CTX_free(pctx);
2557
    util::free(out);
2558
2559
    return ret;
2560
}
2561
#endif
2562
2563
#if !defined(CRYPTOFUZZ_BORINGSSL) && !defined(CRYPTOFUZZ_LIBRESSL) && !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_110) && !defined(CRYPTOFUZZ_OPENSSL_098)
2564
std::optional<component::Key> OpenSSL::OpKDF_SCRYPT_EVP_KDF(operation::KDF_SCRYPT& op) const {
2565
    std::optional<component::Key> ret = std::nullopt;
2566
    EVP_KDF_CTX* kctx = nullptr;
2567
    OSSL_PARAM params[7], *p = params;
2568
    uint8_t* out = util::malloc(op.keySize);
2569
2570
    {
2571
2572
        auto passwordCopy = op.password.Get();
2573
        *p++ = OSSL_PARAM_construct_octet_string(
2574
                OSSL_KDF_PARAM_PASSWORD,
2575
                passwordCopy.data(),
2576
                passwordCopy.size());
2577
2578
        auto saltCopy = op.salt.Get();
2579
        *p++ = OSSL_PARAM_construct_octet_string(
2580
                OSSL_KDF_PARAM_SALT,
2581
                saltCopy.data(),
2582
                saltCopy.size());
2583
2584
        unsigned int N = op.N;
2585
        *p++ = OSSL_PARAM_construct_uint(OSSL_KDF_PARAM_SCRYPT_N, &N);
2586
2587
        unsigned int r = op.r;
2588
        *p++ = OSSL_PARAM_construct_uint(OSSL_KDF_PARAM_SCRYPT_R, &r);
2589
2590
        unsigned int p_ = op.p;
2591
        *p++ = OSSL_PARAM_construct_uint(OSSL_KDF_PARAM_SCRYPT_P, &p_);
2592
2593
        unsigned int maxmem = 1024;
2594
        *p++ = OSSL_PARAM_construct_uint(OSSL_KDF_PARAM_SCRYPT_MAXMEM, &maxmem);
2595
2596
        *p = OSSL_PARAM_construct_end();
2597
2598
        {
2599
            EVP_KDF* kdf = EVP_KDF_fetch(nullptr, OSSL_KDF_NAME_SCRYPT, nullptr);
2600
            CF_CHECK_NE(kdf, nullptr);
2601
            kctx = EVP_KDF_CTX_new(kdf);
2602
            EVP_KDF_free(kdf);
2603
            CF_CHECK_NE(kctx, nullptr);
2604
        }
2605
2606
        CF_CHECK_GT(EVP_KDF_derive(kctx, out, op.keySize, params), 0);
2607
    }
2608
2609
    /* Finalize */
2610
    {
2611
        ret = component::Key(out, op.keySize);
2612
    }
2613
2614
end:
2615
    EVP_KDF_CTX_free(kctx);
2616
2617
    util::free(out);
2618
    return ret;
2619
}
2620
#endif
2621
2622
#if !defined(CRYPTOFUZZ_LIBRESSL) && !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_110) && !defined(CRYPTOFUZZ_OPENSSL_098)
2623
std::optional<component::Key> OpenSSL::OpKDF_SCRYPT(operation::KDF_SCRYPT& op) {
2624
 #if defined(CRYPTOFUZZ_BORINGSSL)
2625
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
2626
    std::optional<component::Key> ret = std::nullopt;
2627
2628
    size_t outSize = op.keySize;
2629
    uint8_t* out = util::malloc(outSize);
2630
2631
    size_t maxMem = 0;
2632
    try {
2633
        maxMem = ds.Get<uint64_t>() % (64*1024*1024);
2634
    } catch ( fuzzing::datasource::Datasource::OutOfData& ) {
2635
    }
2636
2637
    CF_CHECK_EQ(EVP_PBE_scrypt(
2638
                (const char*)(op.password.GetPtr()),
2639
                op.password.GetSize(),
2640
                op.salt.GetPtr(),
2641
                op.salt.GetSize(),
2642
                op.N,
2643
                op.r,
2644
                op.p,
2645
                maxMem,
2646
                out,
2647
                outSize), 1);
2648
2649
    ret = component::Key(out, outSize);
2650
2651
end:
2652
    util::free(out);
2653
2654
    return ret;
2655
 #else
2656
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
2657
2658
    bool useEVP_PKEY = true;
2659
    try {
2660
        useEVP_PKEY = ds.Get<bool>();
2661
    } catch ( fuzzing::datasource::Datasource::OutOfData& ) {
2662
    }
2663
2664
    if ( useEVP_PKEY == true ) {
2665
        return OpKDF_SCRYPT_EVP_PKEY(op);
2666
    } else {
2667
        return OpKDF_SCRYPT_EVP_KDF(op);
2668
    }
2669
 #endif
2670
}
2671
#endif
2672
2673
#if !defined(CRYPTOFUZZ_LIBRESSL) && !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_098)
2674
std::optional<component::Key> OpenSSL::OpKDF_HKDF(operation::KDF_HKDF& op) {
2675
 #if defined(CRYPTOFUZZ_BORINGSSL)
2676
    std::optional<component::Key> ret = std::nullopt;
2677
    const EVP_MD* md = nullptr;
2678
2679
    const size_t outSize = op.keySize;
2680
    uint8_t* out = util::malloc(outSize);
2681
2682
    CF_CHECK_NE(md = toEVPMD(op.digestType), nullptr);
2683
    CF_CHECK_EQ(
2684
            HKDF(out,
2685
                outSize,
2686
                md,
2687
                op.password.GetPtr(),
2688
                op.password.GetSize(),
2689
                op.salt.GetPtr(),
2690
                op.salt.GetSize(),
2691
                op.info.GetPtr(),
2692
                op.info.GetSize()), 1);
2693
2694
    ret = component::Key(out, outSize);
2695
2696
end:
2697
    util::free(out);
2698
2699
    return ret;
2700
 #else
2701
    std::optional<component::Key> ret = std::nullopt;
2702
    EVP_PKEY_CTX* pctx = nullptr;
2703
    const EVP_MD* md = nullptr;
2704
2705
    size_t out_size = op.keySize;
2706
    uint8_t* out = util::malloc(out_size);
2707
2708
    /* Initialize */
2709
    {
2710
        CF_CHECK_NE(md = toEVPMD(op.digestType), nullptr);
2711
        CF_CHECK_NE(pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, nullptr), nullptr);
2712
        CF_CHECK_EQ(EVP_PKEY_derive_init(pctx), 1);
2713
        CF_CHECK_EQ(EVP_PKEY_CTX_set_hkdf_md(pctx, md), 1);
2714
        CF_CHECK_EQ(EVP_PKEY_CTX_set1_hkdf_key(pctx, op.password.GetPtr(), op.password.GetSize()), 1);
2715
        CF_CHECK_EQ(EVP_PKEY_CTX_set1_hkdf_salt(pctx, op.salt.GetPtr(), op.salt.GetSize()), 1);
2716
        CF_CHECK_EQ(EVP_PKEY_CTX_add1_hkdf_info(pctx, op.info.GetPtr(), op.info.GetSize()), 1);
2717
    }
2718
2719
    /* Process/finalize */
2720
    {
2721
        CF_CHECK_EQ(EVP_PKEY_derive(pctx, out, &out_size) , 1);
2722
2723
        CF_CHECK_NE(out, nullptr);
2724
2725
        ret = component::Key(out, out_size);
2726
    }
2727
2728
end:
2729
    EVP_PKEY_CTX_free(pctx);
2730
2731
    util::free(out);
2732
2733
    return ret;
2734
 #endif
2735
}
2736
#endif
2737
2738
#if !defined(CRYPTOFUZZ_BORINGSSL) && !defined(CRYPTOFUZZ_LIBRESSL) && !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_098)
2739
std::optional<component::Key> OpenSSL::OpKDF_TLS1_PRF(operation::KDF_TLS1_PRF& op) {
2740
    std::optional<component::Key> ret = std::nullopt;
2741
    EVP_PKEY_CTX* pctx = nullptr;
2742
    const EVP_MD* md = nullptr;
2743
2744
    size_t out_size = op.keySize;
2745
    uint8_t* out = util::malloc(out_size);
2746
2747
    /* Initialize */
2748
    {
2749
        CF_CHECK_NE(md = toEVPMD(op.digestType), nullptr);
2750
        CF_CHECK_NE(pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_TLS1_PRF, nullptr), nullptr);
2751
        CF_CHECK_EQ(EVP_PKEY_derive_init(pctx), 1);
2752
        CF_CHECK_EQ(EVP_PKEY_CTX_set_tls1_prf_md(pctx, md), 1);
2753
        CF_CHECK_EQ(EVP_PKEY_CTX_set1_tls1_prf_secret(pctx, op.secret.GetPtr(), op.secret.GetSize()), 1);
2754
        CF_CHECK_EQ(EVP_PKEY_CTX_add1_tls1_prf_seed(pctx, op.seed.GetPtr(), op.seed.GetSize()), 1);
2755
    }
2756
2757
    /* Process/finalize */
2758
    {
2759
        CF_CHECK_EQ(EVP_PKEY_derive(pctx, out, &out_size) , 1);
2760
2761
        /* Documentation:
2762
         *
2763
         * "If key is NULL then the maximum size of the output buffer is written to the keylen parameter."
2764
         *
2765
         * So in this case 'out_size' should not be interpreted as containing the output size,
2766
         * and we shouldn't attempt to construct a result from it.
2767
         */
2768
        CF_CHECK_NE(out, nullptr);
2769
2770
        ret = component::Key(out, out_size);
2771
    }
2772
2773
end:
2774
    EVP_PKEY_CTX_free(pctx);
2775
2776
    util::free(out);
2777
2778
    return ret;
2779
}
2780
#endif
2781
2782
#if !defined(CRYPTOFUZZ_LIBRESSL) && !defined(CRYPTOFUZZ_BORINGSSL) && !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_111) && !defined(CRYPTOFUZZ_OPENSSL_110) && !defined(CRYPTOFUZZ_OPENSSL_098)
2783
std::optional<component::Key> OpenSSL::OpKDF_PBKDF(operation::KDF_PBKDF& op) {
2784
    std::optional<component::Key> ret = std::nullopt;
2785
    EVP_KDF_CTX* kctx = nullptr;
2786
    const EVP_MD* md = nullptr;
2787
    OSSL_PARAM params[7], *p = params;
2788
    uint8_t* out = util::malloc(op.keySize);
2789
2790
    {
2791
        CF_CHECK_NE(md = toEVPMD(op.digestType), nullptr);
2792
2793
        auto passwordCopy = op.password.Get();
2794
        *p++ = OSSL_PARAM_construct_octet_string(
2795
                OSSL_KDF_PARAM_PASSWORD,
2796
                passwordCopy.data(),
2797
                passwordCopy.size());
2798
2799
        auto saltCopy = op.salt.Get();
2800
        *p++ = OSSL_PARAM_construct_octet_string(
2801
                OSSL_KDF_PARAM_SALT,
2802
                saltCopy.data(),
2803
                saltCopy.size());
2804
2805
        unsigned int iterations = op.iterations;
2806
        *p++ = OSSL_PARAM_construct_uint(OSSL_KDF_PARAM_ITER, &iterations);
2807
2808
        unsigned int id = 1;
2809
        *p++ = OSSL_PARAM_construct_uint(OSSL_KDF_PARAM_PKCS12_ID, &id);
2810
2811
        std::string mdName(EVP_MD_name(md));
2812
        *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, mdName.data(), mdName.size() + 1);
2813
2814
        int pkcs5 = 0;
2815
        *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_PKCS5, &pkcs5);
2816
2817
        *p = OSSL_PARAM_construct_end();
2818
2819
        {
2820
            EVP_KDF* kdf = EVP_KDF_fetch(nullptr, "PKCS12KDF", nullptr);
2821
            CF_CHECK_NE(kdf, nullptr);
2822
            kctx = EVP_KDF_CTX_new(kdf);
2823
            EVP_KDF_free(kdf);
2824
            CF_CHECK_NE(kctx, nullptr);
2825
        }
2826
2827
        CF_CHECK_GT(EVP_KDF_derive(kctx, out, op.keySize, params), 0);
2828
    }
2829
2830
    /* Finalize */
2831
    {
2832
        ret = component::Key(out, op.keySize);
2833
    }
2834
end:
2835
    EVP_KDF_CTX_free(kctx);
2836
2837
    util::free(out);
2838
2839
    return ret;
2840
}
2841
#endif
2842
2843
#if !defined(CRYPTOFUZZ_LIBRESSL) && !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_111) && !defined(CRYPTOFUZZ_OPENSSL_110) && !defined(CRYPTOFUZZ_OPENSSL_098)
2844
std::optional<component::Key> OpenSSL::OpKDF_PBKDF2(operation::KDF_PBKDF2& op) {
2845
 #if defined(CRYPTOFUZZ_BORINGSSL)
2846
    std::optional<component::Key> ret = std::nullopt;
2847
    const EVP_MD* md = nullptr;
2848
2849
    const size_t outSize = op.keySize;
2850
    uint8_t* out = util::malloc(outSize);
2851
2852
    CF_CHECK_NE(md = toEVPMD(op.digestType), nullptr);
2853
    CF_CHECK_EQ(PKCS5_PBKDF2_HMAC(
2854
                (const char*)(op.password.GetPtr()),
2855
                op.password.GetSize(),
2856
                op.salt.GetPtr(),
2857
                op.salt.GetSize(),
2858
                op.iterations,
2859
                md,
2860
                outSize,
2861
                out), 1);
2862
2863
    ret = component::Key(out, outSize);
2864
end:
2865
    util::free(out);
2866
2867
    return ret;
2868
 #else
2869
    std::optional<component::Key> ret = std::nullopt;
2870
    EVP_KDF_CTX* kctx = nullptr;
2871
    const EVP_MD* md = nullptr;
2872
    OSSL_PARAM params[6], *p = params;
2873
    uint8_t* out = util::malloc(op.keySize);
2874
2875
    {
2876
        CF_CHECK_NE(md = toEVPMD(op.digestType), nullptr);
2877
2878
        auto passwordCopy = op.password.Get();
2879
        *p++ = OSSL_PARAM_construct_octet_string(
2880
                OSSL_KDF_PARAM_PASSWORD,
2881
                passwordCopy.data(),
2882
                passwordCopy.size());
2883
2884
        auto saltCopy = op.salt.Get();
2885
        *p++ = OSSL_PARAM_construct_octet_string(
2886
                OSSL_KDF_PARAM_SALT,
2887
                saltCopy.data(),
2888
                saltCopy.size());
2889
2890
        unsigned int iterations = op.iterations;
2891
        *p++ = OSSL_PARAM_construct_uint(OSSL_KDF_PARAM_ITER, &iterations);
2892
2893
        std::string mdName(EVP_MD_name(md));
2894
        *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, mdName.data(), mdName.size() + 1);
2895
2896
        int pkcs5 = 0;
2897
        *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_PKCS5, &pkcs5);
2898
2899
        *p = OSSL_PARAM_construct_end();
2900
2901
        {
2902
            EVP_KDF* kdf = EVP_KDF_fetch(nullptr, OSSL_KDF_NAME_PBKDF2, nullptr);
2903
            CF_CHECK_NE(kdf, nullptr);
2904
            kctx = EVP_KDF_CTX_new(kdf);
2905
            EVP_KDF_free(kdf);
2906
            CF_CHECK_NE(kctx, nullptr);
2907
        }
2908
2909
        CF_CHECK_GT(EVP_KDF_derive(kctx, out, op.keySize, params), 0);
2910
    }
2911
2912
    /* Finalize */
2913
    {
2914
        ret = component::Key(out, op.keySize);
2915
    }
2916
2917
end:
2918
    EVP_KDF_CTX_free(kctx);
2919
2920
    util::free(out);
2921
2922
    return ret;
2923
 #endif
2924
}
2925
#endif
2926
2927
#if !defined(CRYPTOFUZZ_BORINGSSL) && !defined(CRYPTOFUZZ_LIBRESSL) && !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_111) && !defined(CRYPTOFUZZ_OPENSSL_110)
2928
std::optional<component::Key> OpenSSL::OpKDF_ARGON2(operation::KDF_ARGON2& op) {
2929
    (void)op;
2930
    std::optional<component::Key> ret = std::nullopt;
2931
2932
    /* Pending https://github.com/openssl/openssl/pull/12256 */
2933
#if 0
2934
    uint8_t* out = util::malloc(op.keySize);
2935
    EVP_KDF_CTX *kctx = nullptr;
2936
    OSSL_PARAM params[7], *p = params;
2937
2938
    /* Initialize */
2939
    {
2940
        const char* type = nullptr;
2941
        switch ( op.type ) {
2942
            case    0:
2943
                type = SN_argon2d;
2944
                break;
2945
            case    1:
2946
                type = SN_argon2i;
2947
                break;
2948
            case    2:
2949
                type = SN_argon2id;
2950
                break;
2951
            default:
2952
                goto end;
2953
        }
2954
2955
        CF_CHECK_GTE(op.keySize, 64);
2956
        CF_CHECK_EQ(op.threads, 1);
2957
2958
        {
2959
            EVP_KDF* kdf = EVP_KDF_fetch(nullptr, type, nullptr);
2960
            CF_CHECK_NE(kdf, nullptr);
2961
            kctx = EVP_KDF_CTX_new(kdf);
2962
            EVP_KDF_free(kdf);
2963
            CF_CHECK_NE(kctx, nullptr);
2964
        }
2965
2966
        {
2967
            int threads = 1;
2968
            int m_cost = op.memory;
2969
            unsigned int iterations = op.iterations;
2970
2971
            auto passwordCopy = op.password.Get();
2972
            p[0] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PASSWORD, passwordCopy.data(), passwordCopy.size());
2973
2974
            auto saltCopy = op.salt.Get();
2975
            p[1] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, saltCopy.data(), saltCopy.size());
2976
2977
            p[2] = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_ARGON2_LANES, &threads);
2978
            p[3] = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_THREADS, &threads);
2979
            p[4] = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_ARGON2_MEMCOST, &m_cost);
2980
            p[5] = OSSL_PARAM_construct_uint(OSSL_KDF_PARAM_ITER, &iterations);
2981
            p[6] = OSSL_PARAM_construct_end();
2982
            CF_CHECK_EQ(EVP_KDF_CTX_set_params(kctx, params), 1);
2983
        }
2984
    }
2985
    /* Process/finalize */
2986
    {
2987
        CF_CHECK_EQ(EVP_KDF_derive(kctx, out, op.keySize), 1);
2988
2989
        ret = component::Key(out, op.keySize);
2990
    }
2991
2992
end:
2993
    EVP_KDF_CTX_free(kctx);
2994
2995
    util::free(out);
2996
#endif
2997
2998
    return ret;
2999
}
3000
#endif
3001
3002
#if !defined(CRYPTOFUZZ_BORINGSSL) && !defined(CRYPTOFUZZ_LIBRESSL) && !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_111) && !defined(CRYPTOFUZZ_OPENSSL_110) && !defined(CRYPTOFUZZ_OPENSSL_098)
3003
std::optional<component::Key> OpenSSL::OpKDF_SSH(operation::KDF_SSH& op) {
3004
    std::optional<component::Key> ret = std::nullopt;
3005
    EVP_KDF_CTX* kctx = nullptr;
3006
    const EVP_MD* md = nullptr;
3007
    OSSL_PARAM params[6], *p = params;
3008
    uint8_t* out = util::malloc(op.keySize);
3009
3010
    {
3011
        CF_CHECK_NE(md = toEVPMD(op.digestType), nullptr);
3012
        CF_CHECK_EQ(op.type.GetSize(), 1);
3013
3014
        std::string mdName(EVP_MD_name(md));
3015
        *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, mdName.data(), mdName.size() + 1);
3016
3017
        auto keyCopy = op.key.Get();
3018
        *p++ = OSSL_PARAM_construct_octet_string(
3019
                OSSL_KDF_PARAM_PASSWORD,
3020
                keyCopy.data(),
3021
                keyCopy.size());
3022
3023
        auto xcghashCopy = op.xcghash.Get();
3024
        *p++ = OSSL_PARAM_construct_octet_string(
3025
                OSSL_KDF_PARAM_SSHKDF_XCGHASH,
3026
                xcghashCopy.data(),
3027
                xcghashCopy.size());
3028
3029
        auto session_idCopy = op.session_id.Get();
3030
        *p++ = OSSL_PARAM_construct_octet_string(
3031
                OSSL_KDF_PARAM_SSHKDF_SESSION_ID,
3032
                session_idCopy.data(),
3033
                session_idCopy.size());
3034
3035
3036
        /* Must be null-terminated even if size is specified.
3037
         *
3038
         * See also https://github.com/openssl/openssl/issues/14027
3039
         */
3040
        char type[2];
3041
        type[0] = *(op.type.GetPtr());
3042
        type[1] = 0;
3043
3044
        *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_SSHKDF_TYPE,
3045
                type, sizeof(type));
3046
3047
        *p = OSSL_PARAM_construct_end();
3048
3049
        {
3050
            EVP_KDF* kdf = EVP_KDF_fetch(nullptr, OSSL_KDF_NAME_SSHKDF, nullptr);
3051
            CF_CHECK_NE(kdf, nullptr);
3052
            kctx = EVP_KDF_CTX_new(kdf);
3053
            EVP_KDF_free(kdf);
3054
            CF_CHECK_NE(kctx, nullptr);
3055
        }
3056
3057
        CF_CHECK_GT(EVP_KDF_derive(kctx, out, op.keySize, params), 0);
3058
    }
3059
3060
    /* Finalize */
3061
    {
3062
        ret = component::Key(out, op.keySize);
3063
    }
3064
3065
end:
3066
    EVP_KDF_CTX_free(kctx);
3067
3068
    util::free(out);
3069
3070
    return ret;
3071
}
3072
3073
std::optional<component::Key> OpenSSL::OpKDF_X963(operation::KDF_X963& op) {
3074
    std::optional<component::Key> ret = std::nullopt;
3075
    EVP_KDF_CTX* kctx = nullptr;
3076
    const EVP_MD* md = nullptr;
3077
    OSSL_PARAM params[4], *p = params;
3078
    uint8_t* out = util::malloc(op.keySize);
3079
3080
    {
3081
        CF_CHECK_NE(md = toEVPMD(op.digestType), nullptr);
3082
3083
        std::string mdName(EVP_MD_name(md));
3084
        *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, mdName.data(), mdName.size() + 1);
3085
3086
        auto secretCopy = op.secret.Get();
3087
        *p++ = OSSL_PARAM_construct_octet_string(
3088
                OSSL_KDF_PARAM_SECRET,
3089
                secretCopy.data(),
3090
                secretCopy.size());
3091
3092
        auto infoCopy = op.info.Get();
3093
        *p++ = OSSL_PARAM_construct_octet_string(
3094
                OSSL_KDF_PARAM_INFO,
3095
                infoCopy.data(),
3096
                infoCopy.size());
3097
3098
        *p = OSSL_PARAM_construct_end();
3099
3100
        {
3101
            EVP_KDF* kdf = EVP_KDF_fetch(nullptr, "X963KDF", nullptr);
3102
            CF_CHECK_NE(kdf, nullptr);
3103
            kctx = EVP_KDF_CTX_new(kdf);
3104
            EVP_KDF_free(kdf);
3105
            CF_CHECK_NE(kctx, nullptr);
3106
        }
3107
3108
        CF_CHECK_GT(EVP_KDF_derive(kctx, out, op.keySize, params), 0);
3109
    }
3110
3111
    /* Finalize */
3112
    {
3113
        ret = component::Key(out, op.keySize);
3114
    }
3115
3116
end:
3117
    EVP_KDF_CTX_free(kctx);
3118
3119
    util::free(out);
3120
3121
    return ret;
3122
}
3123
3124
std::optional<component::Key> OpenSSL::OpKDF_SP_800_108(operation::KDF_SP_800_108& op) {
3125
    std::optional<component::Key> ret = std::nullopt;
3126
    EVP_KDF_CTX* kctx = nullptr;
3127
    const EVP_MD* md = nullptr;
3128
    OSSL_PARAM params[7], *p = params;
3129
    uint8_t* out = util::malloc(op.keySize);
3130
3131
    std::string hmacStr = "HMAC";
3132
    std::string counterStr = "COUNTER";
3133
    std::string feedbackStr = "FEEDBACK";
3134
3135
    {
3136
        if ( op.mode != 0 && op.mode != 1 ) {
3137
            goto end;
3138
        }
3139
3140
        if ( op.mode == 1 ) {
3141
            /* XXX Salt is ignored in feedback mode
3142
             * https://github.com/openssl/openssl/issues/12409#issuecomment-701645838
3143
             */
3144
            CF_CHECK_EQ(op.salt.GetSize(), 0);
3145
        }
3146
3147
        CF_CHECK_EQ(op.mech.mode, true); /* Currently only HMAC supported, not CMAC */
3148
3149
        CF_CHECK_NE(md = toEVPMD(op.mech.type), nullptr);
3150
3151
        std::string mdName(EVP_MD_name(md));
3152
        *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, mdName.data(), 0);
3153
        *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MAC, hmacStr.data(), 0);
3154
3155
        if ( op.mode == 0 ) {
3156
            *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MODE, counterStr.data(), 0);
3157
        } else if ( op.mode == 1 ) {
3158
            *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MODE, feedbackStr.data(), 0);
3159
        } else {
3160
            CF_UNREACHABLE();
3161
        }
3162
3163
        auto secretCopy = op.secret.Get();
3164
        *p++ = OSSL_PARAM_construct_octet_string(
3165
                OSSL_KDF_PARAM_KEY,
3166
                secretCopy.data(),
3167
                secretCopy.size());
3168
3169
        auto labelCopy = op.label.Get();
3170
        *p++ = OSSL_PARAM_construct_octet_string(
3171
                OSSL_KDF_PARAM_SALT,
3172
                labelCopy.data(),
3173
                labelCopy.size());
3174
3175
        auto saltCopy = op.salt.Get();
3176
        *p++ = OSSL_PARAM_construct_octet_string(
3177
                OSSL_KDF_PARAM_INFO,
3178
                saltCopy.data(),
3179
                saltCopy.size());
3180
3181
        *p = OSSL_PARAM_construct_end();
3182
3183
        {
3184
            EVP_KDF* kdf = EVP_KDF_fetch(nullptr, "KBKDF", nullptr);
3185
            CF_CHECK_NE(kdf, nullptr);
3186
            kctx = EVP_KDF_CTX_new(kdf);
3187
            EVP_KDF_free(kdf);
3188
            CF_CHECK_NE(kctx, nullptr);
3189
        }
3190
3191
        CF_CHECK_GT(EVP_KDF_derive(kctx, out, op.keySize, params), 0);
3192
    }
3193
3194
    /* Finalize */
3195
    {
3196
        ret = component::Key(out, op.keySize);
3197
    }
3198
3199
end:
3200
    EVP_KDF_CTX_free(kctx);
3201
3202
    util::free(out);
3203
3204
    return ret;
3205
}
3206
#endif
3207
3208
#if !defined(CRYPTOFUZZ_OPENSSL_098)
3209
2.72k
std::optional<component::MAC> OpenSSL::OpCMAC(operation::CMAC& op) {
3210
2.72k
    std::optional<component::MAC> ret = std::nullopt;
3211
2.72k
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
3212
3213
2.72k
    util::Multipart parts;
3214
3215
2.72k
    CF_CMAC_CTX ctx(ds);
3216
2.72k
    const EVP_CIPHER* cipher = nullptr;
3217
3218
    /* Initialize */
3219
2.72k
    {
3220
2.72k
        parts = util::ToParts(ds, op.cleartext);
3221
3222
2.72k
        CF_CHECK_NE(cipher = toEVPCIPHER(op.cipher.cipherType), nullptr);
3223
2.00k
        CF_CHECK_EQ(CMAC_Init(ctx.GetPtr(), op.cipher.key.GetPtr(), op.cipher.key.GetSize(), cipher, nullptr), 1);
3224
1.19k
    }
3225
3226
    /* Process */
3227
15.2k
    for (const auto& part : parts) {
3228
15.2k
        CF_CHECK_EQ(CMAC_Update(ctx.GetPtr(), part.first, part.second), 1);
3229
14.7k
    }
3230
3231
    /* Finalize */
3232
734
    {
3233
734
        size_t len = 0;
3234
734
        uint8_t out[EVP_MAX_MD_SIZE];
3235
734
        CF_CHECK_EQ(CMAC_Final(ctx.GetPtr(), out, &len), 1);
3236
734
        ret = component::MAC(out, len);
3237
734
    }
3238
3239
2.72k
end:
3240
2.72k
    return ret;
3241
734
}
3242
#endif
3243
3244
/* LibreSSL uses getentropy() in ECC operations.
3245
 * MemorySanitizer erroneously does not unpoison the destination buffer.
3246
 * https://github.com/google/sanitizers/issues/1173
3247
 */
3248
#if !(defined(CRYPTOFUZZ_LIBRESSL) && defined(SANITIZER_MSAN))
3249
2.70k
static std::optional<int> toCurveNID(const component::CurveType& curveType) {
3250
2.70k
    static const std::map<uint64_t, int> LUT = {
3251
2.70k
#if !defined(CRYPTOFUZZ_OPENSSL_098)
3252
2.70k
        { CF_ECC_CURVE("brainpool160r1"), NID_brainpoolP160r1 },
3253
2.70k
        { CF_ECC_CURVE("brainpool160t1"), NID_brainpoolP160t1 },
3254
2.70k
        { CF_ECC_CURVE("brainpool192r1"), NID_brainpoolP192r1 },
3255
2.70k
        { CF_ECC_CURVE("brainpool192t1"), NID_brainpoolP192t1 },
3256
2.70k
        { CF_ECC_CURVE("brainpool224r1"), NID_brainpoolP224r1 },
3257
2.70k
        { CF_ECC_CURVE("brainpool224t1"), NID_brainpoolP224t1 },
3258
2.70k
        { CF_ECC_CURVE("brainpool256r1"), NID_brainpoolP256r1 },
3259
2.70k
        { CF_ECC_CURVE("brainpool256t1"), NID_brainpoolP256t1 },
3260
2.70k
        { CF_ECC_CURVE("brainpool320r1"), NID_brainpoolP320r1 },
3261
2.70k
        { CF_ECC_CURVE("brainpool320t1"), NID_brainpoolP320t1 },
3262
2.70k
        { CF_ECC_CURVE("brainpool384r1"), NID_brainpoolP384r1 },
3263
2.70k
        { CF_ECC_CURVE("brainpool384t1"), NID_brainpoolP384t1 },
3264
2.70k
        { CF_ECC_CURVE("brainpool512r1"), NID_brainpoolP512r1 },
3265
2.70k
        { CF_ECC_CURVE("brainpool512t1"), NID_brainpoolP512t1 },
3266
2.70k
#endif
3267
2.70k
        { CF_ECC_CURVE("secp112r1"), NID_secp112r1 },
3268
2.70k
        { CF_ECC_CURVE("secp112r2"), NID_secp112r2 },
3269
2.70k
        { CF_ECC_CURVE("secp128r1"), NID_secp128r1 },
3270
2.70k
        { CF_ECC_CURVE("secp128r2"), NID_secp128r2 },
3271
2.70k
        { CF_ECC_CURVE("secp160k1"), NID_secp160k1 },
3272
2.70k
        { CF_ECC_CURVE("secp160r1"), NID_secp160r1 },
3273
2.70k
        { CF_ECC_CURVE("secp160r2"), NID_secp160r2 },
3274
2.70k
        { CF_ECC_CURVE("secp192k1"), NID_secp192k1 },
3275
2.70k
        { CF_ECC_CURVE("secp224k1"), NID_secp224k1 },
3276
2.70k
        { CF_ECC_CURVE("secp224r1"), NID_secp224r1 },
3277
2.70k
        { CF_ECC_CURVE("secp256k1"), NID_secp256k1 },
3278
2.70k
        { CF_ECC_CURVE("secp384r1"), NID_secp384r1 },
3279
2.70k
        { CF_ECC_CURVE("secp521r1"), NID_secp521r1 },
3280
2.70k
        { CF_ECC_CURVE("sect113r1"), NID_sect113r1 },
3281
2.70k
        { CF_ECC_CURVE("sect113r2"), NID_sect113r2 },
3282
2.70k
        { CF_ECC_CURVE("sect131r1"), NID_sect131r1 },
3283
2.70k
        { CF_ECC_CURVE("sect131r2"), NID_sect131r2 },
3284
2.70k
        { CF_ECC_CURVE("sect163k1"), NID_sect163k1 },
3285
2.70k
        { CF_ECC_CURVE("sect163r1"), NID_sect163r1 },
3286
2.70k
        { CF_ECC_CURVE("sect163r2"), NID_sect163r2 },
3287
2.70k
        { CF_ECC_CURVE("sect193r1"), NID_sect193r1 },
3288
2.70k
        { CF_ECC_CURVE("sect193r2"), NID_sect193r2 },
3289
2.70k
        { CF_ECC_CURVE("sect233k1"), NID_sect233k1 },
3290
2.70k
        { CF_ECC_CURVE("sect233r1"), NID_sect233r1 },
3291
2.70k
        { CF_ECC_CURVE("sect239k1"), NID_sect239k1 },
3292
2.70k
        { CF_ECC_CURVE("sect283k1"), NID_sect283k1 },
3293
2.70k
        { CF_ECC_CURVE("sect283r1"), NID_sect283r1 },
3294
2.70k
        { CF_ECC_CURVE("sect409k1"), NID_sect409k1 },
3295
2.70k
        { CF_ECC_CURVE("sect409r1"), NID_sect409r1 },
3296
2.70k
        { CF_ECC_CURVE("sect571k1"), NID_sect571k1 },
3297
2.70k
        { CF_ECC_CURVE("sect571r1"), NID_sect571r1 },
3298
#if !defined(CRYPTOFUZZ_BORINGSSL) && !defined(CRYPTOFUZZ_LIBRESSL) && !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_110) && !defined(CRYPTOFUZZ_OPENSSL_098)
3299
        { CF_ECC_CURVE("sm2p256v1"), NID_sm2 },
3300
#endif
3301
2.70k
        { CF_ECC_CURVE("wap_wsg_idm_ecid_wtls1"), NID_wap_wsg_idm_ecid_wtls1 },
3302
2.70k
        { CF_ECC_CURVE("wap_wsg_idm_ecid_wtls10"), NID_wap_wsg_idm_ecid_wtls10 },
3303
2.70k
        { CF_ECC_CURVE("wap_wsg_idm_ecid_wtls11"), NID_wap_wsg_idm_ecid_wtls11 },
3304
2.70k
        { CF_ECC_CURVE("wap_wsg_idm_ecid_wtls12"), NID_wap_wsg_idm_ecid_wtls12 },
3305
2.70k
        { CF_ECC_CURVE("wap_wsg_idm_ecid_wtls3"), NID_wap_wsg_idm_ecid_wtls3 },
3306
2.70k
        { CF_ECC_CURVE("wap_wsg_idm_ecid_wtls4"), NID_wap_wsg_idm_ecid_wtls4 },
3307
2.70k
        { CF_ECC_CURVE("wap_wsg_idm_ecid_wtls5"), NID_wap_wsg_idm_ecid_wtls5 },
3308
2.70k
        { CF_ECC_CURVE("wap_wsg_idm_ecid_wtls6"), NID_wap_wsg_idm_ecid_wtls6 },
3309
#if 0
3310
        /* Incorrectly implemented by OpenSSL:
3311
         * https://github.com/openssl/openssl/issues/6317
3312
         */
3313
        { CF_ECC_CURVE("wap_wsg_idm_ecid_wtls7"), NID_wap_wsg_idm_ecid_wtls7 },
3314
#endif
3315
2.70k
        { CF_ECC_CURVE("wap_wsg_idm_ecid_wtls8"), NID_wap_wsg_idm_ecid_wtls8 },
3316
2.70k
        { CF_ECC_CURVE("wap_wsg_idm_ecid_wtls9"), NID_wap_wsg_idm_ecid_wtls9 },
3317
2.70k
        { CF_ECC_CURVE("x962_c2pnb163v1"), NID_X9_62_c2pnb163v1 },
3318
2.70k
        { CF_ECC_CURVE("x962_c2pnb163v2"), NID_X9_62_c2pnb163v2 },
3319
2.70k
        { CF_ECC_CURVE("x962_c2pnb163v3"), NID_X9_62_c2pnb163v3 },
3320
2.70k
        { CF_ECC_CURVE("x962_c2pnb176v1"), NID_X9_62_c2pnb176v1 },
3321
2.70k
        { CF_ECC_CURVE("x962_c2pnb208w1"), NID_X9_62_c2pnb208w1 },
3322
2.70k
        { CF_ECC_CURVE("x962_c2pnb272w1"), NID_X9_62_c2pnb272w1 },
3323
2.70k
        { CF_ECC_CURVE("x962_c2pnb304w1"), NID_X9_62_c2pnb304w1 },
3324
2.70k
        { CF_ECC_CURVE("x962_c2pnb368w1"), NID_X9_62_c2pnb368w1 },
3325
2.70k
        { CF_ECC_CURVE("x962_c2tnb191v1"), NID_X9_62_c2tnb191v1 },
3326
2.70k
        { CF_ECC_CURVE("x962_c2tnb191v2"), NID_X9_62_c2tnb191v2 },
3327
2.70k
        { CF_ECC_CURVE("x962_c2tnb191v3"), NID_X9_62_c2tnb191v3 },
3328
2.70k
        { CF_ECC_CURVE("x962_c2tnb239v1"), NID_X9_62_c2tnb239v1 },
3329
2.70k
        { CF_ECC_CURVE("x962_c2tnb239v2"), NID_X9_62_c2tnb239v2 },
3330
2.70k
        { CF_ECC_CURVE("x962_c2tnb239v3"), NID_X9_62_c2tnb239v3 },
3331
2.70k
        { CF_ECC_CURVE("x962_c2tnb359v1"), NID_X9_62_c2tnb359v1 },
3332
2.70k
        { CF_ECC_CURVE("x962_c2tnb431r1"), NID_X9_62_c2tnb431r1 },
3333
2.70k
        { CF_ECC_CURVE("secp192r1"), NID_X9_62_prime192v1 },
3334
2.70k
        { CF_ECC_CURVE("x962_p192v1"), NID_X9_62_prime192v1 },
3335
2.70k
        { CF_ECC_CURVE("x962_p192v2"), NID_X9_62_prime192v2 },
3336
2.70k
        { CF_ECC_CURVE("x962_p192v3"), NID_X9_62_prime192v3 },
3337
2.70k
        { CF_ECC_CURVE("x962_p239v1"), NID_X9_62_prime239v1 },
3338
2.70k
        { CF_ECC_CURVE("x962_p239v2"), NID_X9_62_prime239v2 },
3339
2.70k
        { CF_ECC_CURVE("x962_p239v3"), NID_X9_62_prime239v3 },
3340
2.70k
        { CF_ECC_CURVE("secp256r1"), NID_X9_62_prime256v1 },
3341
2.70k
        { CF_ECC_CURVE("x962_p256v1"), NID_X9_62_prime256v1 },
3342
2.70k
#if defined(CRYPTOFUZZ_LIBRESSL)
3343
2.70k
        { CF_ECC_CURVE("ipsec3"), NID_ipsec3 },
3344
2.70k
        { CF_ECC_CURVE("ipsec4"), NID_ipsec4 },
3345
2.70k
        { CF_ECC_CURVE("gostr3410_2001_test"), NID_id_GostR3410_2001_TestParamSet },
3346
2.70k
        { CF_ECC_CURVE("gostr3410_2001_cryptopro_a"), NID_id_GostR3410_2001_CryptoPro_A_ParamSet },
3347
2.70k
        { CF_ECC_CURVE("gostr3410_2001_cryptopro_b"), NID_id_GostR3410_2001_CryptoPro_B_ParamSet },
3348
2.70k
        { CF_ECC_CURVE("gostr3410_2001_cryptopro_c"), NID_id_GostR3410_2001_CryptoPro_C_ParamSet },
3349
2.70k
        { CF_ECC_CURVE("gostr3410_2001_cryptopro_xcha"), NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet },
3350
2.70k
        { CF_ECC_CURVE("gostr3410_2001_cryptopro_xchb"), NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet },
3351
2.70k
        { CF_ECC_CURVE("tc26_gost_3410_12_256_a"), NID_id_tc26_gost_3410_12_256_paramSetA },
3352
2.70k
        { CF_ECC_CURVE("tc26_gost_3410_12_256_b"), NID_id_tc26_gost_3410_12_256_paramSetB },
3353
2.70k
        { CF_ECC_CURVE("tc26_gost_3410_12_256_c"), NID_id_tc26_gost_3410_12_256_paramSetC },
3354
2.70k
        { CF_ECC_CURVE("tc26_gost_3410_12_256_d"), NID_id_tc26_gost_3410_12_256_paramSetD },
3355
2.70k
        { CF_ECC_CURVE("tc26_gost_3410_12_512_test"), NID_id_tc26_gost_3410_12_512_paramSetTest },
3356
2.70k
        { CF_ECC_CURVE("tc26_gost_3410_12_512_a"), NID_id_tc26_gost_3410_12_512_paramSetA },
3357
2.70k
        { CF_ECC_CURVE("tc26_gost_3410_12_512_b"), NID_id_tc26_gost_3410_12_512_paramSetB },
3358
2.70k
        { CF_ECC_CURVE("tc26_gost_3410_12_512_c"), NID_id_tc26_gost_3410_12_512_paramSetC },
3359
2.70k
#endif
3360
2.70k
    };
3361
3362
2.70k
    if ( LUT.find(curveType.Get()) == LUT.end() ) {
3363
445
        return std::nullopt;
3364
445
    }
3365
3366
2.25k
    return LUT.at(curveType.Get());
3367
2.70k
}
3368
3369
/* TODO OpenSSL 1.0.2, 0.9.8 */
3370
#if !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_098)
3371
192
std::optional<component::ECC_PublicKey> OpenSSL::OpECC_PrivateToPublic(operation::ECC_PrivateToPublic& op) {
3372
192
    std::optional<component::ECC_PublicKey> ret = std::nullopt;
3373
192
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
3374
3375
192
    global_ds = &ds;
3376
3377
192
    char* pub_x_str = nullptr;
3378
192
    char* pub_y_str = nullptr;
3379
3380
192
    try {
3381
192
        if ( op.curveType.Get() == CF_ECC_CURVE("x25519") ) {
3382
21
            uint8_t priv_bytes[32];
3383
21
            uint8_t pub_bytes[32];
3384
21
            OpenSSL_bignum::Bignum priv(ds), pub(ds);
3385
21
            CF_CHECK_EQ(pub.New(), true);
3386
3387
21
            CF_CHECK_EQ(priv.Set(op.priv.ToString(ds)), true);
3388
3389
            /* Load private key */
3390
21
            CF_CHECK_NE(BN_bn2binpad(priv.GetPtr(), priv_bytes, sizeof(priv_bytes)), -1);
3391
3392
            /* Private -> public */
3393
16
            /* noret */ X25519_public_from_private(pub_bytes, priv_bytes);
3394
3395
            /* Convert public key */
3396
16
            CF_CHECK_NE(BN_bin2bn(pub_bytes, sizeof(pub_bytes), pub.GetDestPtr()), nullptr);
3397
3398
16
            CF_CHECK_NE(pub_x_str = BN_bn2dec(pub.GetPtr()), nullptr);
3399
3400
            /* Save bignum x/y */
3401
16
            ret = { std::string(pub_x_str), "0" };
3402
#if !defined(CRYPTOFUZZ_BORINGSSL) && !defined(CRYPTOFUZZ_LIBRESSL)
3403
        } else if ( op.curveType.Get() == CF_ECC_CURVE("x448") ) {
3404
            uint8_t priv_bytes[56];
3405
            uint8_t pub_bytes[56];
3406
            OpenSSL_bignum::Bignum priv(ds), pub(ds);
3407
            CF_CHECK_EQ(pub.New(), true);
3408
3409
            CF_CHECK_EQ(priv.Set(op.priv.ToString(ds)), true);
3410
3411
            /* Load private key */
3412
            CF_CHECK_NE(BN_bn2binpad(priv.GetPtr(), priv_bytes, sizeof(priv_bytes)), -1);
3413
3414
            /* Private -> public */
3415
            /* noret */ X448_public_from_private(pub_bytes, priv_bytes);
3416
3417
            /* Convert public key */
3418
            CF_CHECK_NE(BN_bin2bn(pub_bytes, sizeof(pub_bytes), pub.GetDestPtr()), nullptr);
3419
3420
            CF_CHECK_NE(pub_x_str = BN_bn2dec(pub.GetPtr()), nullptr);
3421
3422
            /* Save bignum x/y */
3423
            ret = { std::string(pub_x_str), "0" };
3424
#endif
3425
171
        } else {
3426
171
            CF_EC_KEY key(ds);
3427
171
            std::shared_ptr<CF_EC_GROUP> group = nullptr;
3428
171
            OpenSSL_bignum::Bignum prv(ds);
3429
171
            std::unique_ptr<CF_EC_POINT> pub = nullptr;
3430
171
            OpenSSL_bignum::Bignum pub_x(ds);
3431
171
            OpenSSL_bignum::Bignum pub_y(ds);
3432
3433
171
            {
3434
171
                std::optional<int> curveNID;
3435
171
                CF_CHECK_NE(curveNID = toCurveNID(op.curveType), std::nullopt);
3436
113
                CF_CHECK_NE(group = std::make_shared<CF_EC_GROUP>(ds, *curveNID), nullptr);
3437
113
                group->Lock();
3438
113
                CF_CHECK_NE(group->GetPtr(), nullptr);
3439
87
            }
3440
3441
87
            CF_CHECK_EQ(EC_KEY_set_group(key.GetPtr(), group->GetPtr()), 1);
3442
3443
            /* Load private key */
3444
87
            CF_CHECK_EQ(prv.Set(op.priv.ToString(ds)), true);
3445
3446
            /* Set private key */
3447
87
            CF_CHECK_EQ(EC_KEY_set_private_key(key.GetPtr(), prv.GetPtr()), 1);
3448
3449
            /* Compute public key */
3450
87
            CF_CHECK_NE(pub = std::make_unique<CF_EC_POINT>(ds, group, op.curveType.Get()), nullptr);
3451
87
            CF_CHECK_EQ(EC_POINT_mul(group->GetPtr(), pub->GetPtr(), prv.GetPtr(), nullptr, nullptr, nullptr), 1);
3452
3453
87
            CF_CHECK_EQ(pub_x.New(), true);
3454
87
            CF_CHECK_EQ(pub_y.New(), true);
3455
3456
#if !defined(CRYPTOFUZZ_BORINGSSL) && !defined(CRYPTOFUZZ_LIBRESSL) && !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_110)
3457
            CF_CHECK_NE(EC_POINT_get_affine_coordinates(group->GetPtr(), pub->GetPtr(), pub_x.GetDestPtr(), pub_y.GetDestPtr(), nullptr), 0);
3458
#else
3459
87
            CF_CHECK_NE(EC_POINT_get_affine_coordinates_GFp(group->GetPtr(), pub->GetPtr(), pub_x.GetDestPtr(), pub_y.GetDestPtr(), nullptr), 0);
3460
72
#endif
3461
3462
            /* Convert bignum x/y to strings */
3463
72
            CF_CHECK_NE(pub_x_str = BN_bn2dec(pub_x.GetPtr()), nullptr);
3464
72
            CF_CHECK_NE(pub_y_str = BN_bn2dec(pub_y.GetPtr()), nullptr);
3465
3466
            /* Save bignum x/y */
3467
72
            ret = { std::string(pub_x_str), std::string(pub_y_str) };
3468
72
        }
3469
192
    } catch ( ... ) { }
3470
3471
192
end:
3472
192
    OPENSSL_free(pub_x_str);
3473
192
    OPENSSL_free(pub_y_str);
3474
3475
192
    global_ds = nullptr;
3476
3477
192
    return ret;
3478
192
}
3479
#endif /* CRYPTOFUZZ_OPENSSL_102, CRYPTOFUZZ_OPENSSL_098 */
3480
3481
294
std::optional<component::ECC_KeyPair> OpenSSL::OpECC_GenerateKeyPair(operation::ECC_GenerateKeyPair& op) {
3482
294
    std::optional<component::ECC_KeyPair> ret = std::nullopt;
3483
294
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
3484
3485
294
    global_ds = &ds;
3486
3487
294
    EC_KEY* key = nullptr;
3488
294
    char* priv_str = nullptr;
3489
294
    BIGNUM* pub_x = nullptr;
3490
294
    BIGNUM* pub_y = nullptr;
3491
294
    char* pub_x_str = nullptr;
3492
294
    char* pub_y_str = nullptr;
3493
3494
294
    try {
3495
294
        const BIGNUM* priv = nullptr;
3496
294
        std::shared_ptr<CF_EC_GROUP> group = nullptr;
3497
294
        std::unique_ptr<CF_EC_POINT> pub = nullptr;
3498
3499
294
        std::optional<int> curveNID;
3500
294
        CF_CHECK_NE(curveNID = toCurveNID(op.curveType), std::nullopt);
3501
220
        CF_CHECK_NE(key = EC_KEY_new_by_curve_name(*curveNID), nullptr);
3502
172
        CF_CHECK_EQ(EC_KEY_generate_key(key), 1);
3503
3504
        /* Private key */
3505
172
        {
3506
172
            CF_CHECK_NE(priv = EC_KEY_get0_private_key(key), nullptr);
3507
172
            CF_CHECK_NE(priv_str = BN_bn2dec(priv), nullptr);
3508
172
        }
3509
3510
        /* Public key */
3511
0
        {
3512
172
            CF_CHECK_NE(pub_x = BN_new(), nullptr);
3513
172
            CF_CHECK_NE(pub_y = BN_new(), nullptr);
3514
172
            CF_CHECK_NE(group = std::make_shared<CF_EC_GROUP>(ds, *curveNID), nullptr);
3515
172
            group->Lock();
3516
172
            CF_CHECK_NE(group->GetPtr(), nullptr);
3517
172
            CF_CHECK_NE(pub = std::make_unique<CF_EC_POINT>(ds, group, op.curveType.Get()), nullptr);
3518
172
            CF_CHECK_EQ(EC_POINT_mul(group->GetPtr(), pub->GetPtr(), priv, nullptr, nullptr, nullptr), 1);
3519
3520
#if !defined(CRYPTOFUZZ_BORINGSSL) && !defined(CRYPTOFUZZ_LIBRESSL) && !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_110) && !defined(CRYPTOFUZZ_OPENSSL_098)
3521
            CF_CHECK_NE(EC_POINT_get_affine_coordinates(group->GetPtr(), pub->GetPtr(), pub_x, pub_y, nullptr), 0);
3522
#else
3523
172
            CF_CHECK_NE(EC_POINT_get_affine_coordinates_GFp(group->GetPtr(), pub->GetPtr(), pub_x, pub_y, nullptr), 0);
3524
172
#endif
3525
3526
172
            CF_CHECK_NE(pub_x_str = BN_bn2dec(pub_x), nullptr);
3527
172
            CF_CHECK_NE(pub_y_str = BN_bn2dec(pub_y), nullptr);
3528
172
        }
3529
3530
0
        {
3531
172
            ret = {
3532
172
                std::string(priv_str),
3533
172
                { std::string(pub_x_str), std::string(pub_y_str) }
3534
172
            };
3535
172
        }
3536
172
    } catch ( ... ) { }
3537
3538
294
end:
3539
294
    EC_KEY_free(key);
3540
294
    OPENSSL_free(priv_str);
3541
294
    BN_free(pub_x);
3542
294
    BN_free(pub_y);
3543
294
    OPENSSL_free(pub_x_str);
3544
294
    OPENSSL_free(pub_y_str);
3545
3546
294
    global_ds = nullptr;
3547
3548
294
    return ret;
3549
294
}
3550
3551
288
std::optional<bool> OpenSSL::OpECC_ValidatePubkey(operation::ECC_ValidatePubkey& op) {
3552
288
    std::optional<bool> ret = std::nullopt;
3553
288
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
3554
3555
288
    CF_EC_KEY key(ds);
3556
288
    std::shared_ptr<CF_EC_GROUP> group = nullptr;
3557
3558
288
    std::unique_ptr<CF_EC_POINT> pub = nullptr;
3559
3560
288
    {
3561
288
        std::optional<int> curveNID;
3562
288
        CF_CHECK_NE(curveNID = toCurveNID(op.curveType), std::nullopt);
3563
252
        CF_CHECK_NE(group = std::make_shared<CF_EC_GROUP>(ds, *curveNID), nullptr);
3564
252
        group->Lock();
3565
252
        CF_CHECK_NE(group->GetPtr(), nullptr);
3566
238
    }
3567
3568
238
    CF_CHECK_EQ(EC_KEY_set_group(key.GetPtr(), group->GetPtr()), 1);
3569
3570
    /* Construct key */
3571
238
    CF_CHECK_NE(pub = std::make_unique<CF_EC_POINT>(ds, group, op.curveType.Get()), nullptr);
3572
238
    CF_CHECK_TRUE(pub->Set(op.pub.first, op.pub.second, false,
3573
                /* allowProjective */
3574
238
#if defined(CRYPTOFUZZ_LIBRESSL)
3575
                /* https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=55750 */
3576
238
                true
3577
#else
3578
                false
3579
#endif
3580
238
    ));
3581
3582
    /* Reject oversized pubkeys until it is fixed in OpenSSL
3583
     * https://github.com/openssl/openssl/issues/17590
3584
     */
3585
123
    {
3586
123
        const auto order = cryptofuzz::repository::ECC_CurveToOrder(op.curveType.Get());
3587
123
        CF_CHECK_NE(order, std::nullopt);
3588
123
        CF_CHECK_TRUE(op.pub.first.IsLessThan(*order));
3589
122
        CF_CHECK_TRUE(op.pub.second.IsLessThan(*order));
3590
122
    }
3591
3592
0
    ret = EC_KEY_set_public_key(key.GetPtr(), pub->GetPtr()) == 1;
3593
3594
    /* https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=66667 */
3595
    /* Curves with cofactor > 1 need additional validation */
3596
122
    if (    op.curveType.Is(CF_ECC_CURVE("secp112r2")) ||
3597
122
            op.curveType.Is(CF_ECC_CURVE("secp128r2")) ) {
3598
0
        if ( *ret ) {
3599
0
            ret = EC_KEY_check_key(key.GetPtr()) == 1;
3600
0
        }
3601
0
    }
3602
3603
288
end:
3604
288
    return ret;
3605
122
}
3606
3607
/* TODO OpenSSL 1.0.2, 0.9.8 */
3608
#if !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_098)
3609
930
std::optional<component::ECDSA_Signature> OpenSSL::OpECDSA_Sign(operation::ECDSA_Sign& op) {
3610
930
    std::optional<component::ECDSA_Signature> ret = std::nullopt;
3611
930
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
3612
3613
930
    global_ds = &ds;
3614
3615
930
    ECDSA_SIG* signature = nullptr;
3616
930
    char* pub_x_str = nullptr;
3617
930
    char* pub_y_str = nullptr;
3618
930
    char* sig_r_str = nullptr;
3619
930
    char* sig_s_str = nullptr;
3620
3621
930
    try {
3622
930
        CF_EC_KEY key(ds);
3623
930
        std::shared_ptr<CF_EC_GROUP> group = nullptr;
3624
930
        OpenSSL_bignum::Bignum prv(ds);
3625
930
        std::unique_ptr<CF_EC_POINT> pub = nullptr;
3626
930
        OpenSSL_bignum::Bignum pub_x(ds);
3627
930
        OpenSSL_bignum::Bignum pub_y(ds);
3628
930
        const BIGNUM *R = nullptr, *S = nullptr;
3629
3630
#if defined(CRYPTOFUZZ_BORINGSSL)
3631
        CF_CHECK_TRUE(op.UseRandomNonce() || op.UseSpecifiedNonce());
3632
#else
3633
930
        CF_CHECK_TRUE(op.UseRandomNonce());
3634
528
#endif
3635
528
        CF_CHECK_TRUE(op.digestType.Is(CF_DIGEST("NULL")));
3636
3637
485
        {
3638
485
            std::optional<int> curveNID;
3639
485
            CF_CHECK_NE(curveNID = toCurveNID(op.curveType), std::nullopt);
3640
470
            CF_CHECK_NE(group = std::make_shared<CF_EC_GROUP>(ds, *curveNID), nullptr);
3641
470
            group->Lock();
3642
470
            CF_CHECK_NE(group->GetPtr(), nullptr);
3643
464
        }
3644
3645
464
        CF_CHECK_EQ(EC_KEY_set_group(key.GetPtr(), group->GetPtr()), 1);
3646
3647
        /* Load private key */
3648
464
        CF_CHECK_EQ(prv.Set(op.priv.ToString(ds)), true);
3649
3650
        /* Set private key */
3651
464
        CF_CHECK_EQ(EC_KEY_set_private_key(key.GetPtr(), prv.GetPtr()), 1);
3652
3653
        /* Compute public key */
3654
464
        CF_CHECK_NE(pub = std::make_unique<CF_EC_POINT>(ds, group, op.curveType.Get()), nullptr);
3655
464
        CF_CHECK_EQ(EC_POINT_mul(group->GetPtr(), pub->GetPtr(), prv.GetPtr(), nullptr, nullptr, nullptr), 1);
3656
3657
464
        CF_CHECK_EQ(pub_x.New(), true);
3658
464
        CF_CHECK_EQ(pub_y.New(), true);
3659
3660
#if !defined(CRYPTOFUZZ_BORINGSSL) && !defined(CRYPTOFUZZ_LIBRESSL) && !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_110)
3661
        CF_CHECK_NE(EC_POINT_get_affine_coordinates(group->GetPtr(), pub->GetPtr(), pub_x.GetDestPtr(), pub_y.GetDestPtr(), nullptr), 0);
3662
#else
3663
464
        CF_CHECK_NE(EC_POINT_get_affine_coordinates_GFp(group->GetPtr(), pub->GetPtr(), pub_x.GetDestPtr(), pub_y.GetDestPtr(), nullptr), 0);
3664
453
#endif
3665
3666
453
        CF_CHECK_NE(pub_x_str = BN_bn2dec(pub_x.GetPtr()), nullptr);
3667
453
        CF_CHECK_NE(pub_y_str = BN_bn2dec(pub_y.GetPtr()), nullptr);
3668
3669
453
        const auto CT = op.cleartext.ECDSA_RandomPad(ds, op.curveType);
3670
3671
#if defined(CRYPTOFUZZ_BORINGSSL)
3672
        if ( op.UseSpecifiedNonce() ) {
3673
            std::optional<std::vector<uint8_t>> nonce_bytes;
3674
            CF_CHECK_NE(nonce_bytes = util::DecToBin(op.nonce.ToTrimmedString()), std::nullopt);
3675
3676
            CF_CHECK_NE(signature = ECDSA_sign_with_nonce_and_leak_private_key_for_testing(CT.GetPtr(), CT.GetSize(), key.GetPtr(), nonce_bytes->data(), nonce_bytes->size()), nullptr);
3677
        }
3678
        else
3679
#endif
3680
453
        CF_CHECK_NE(signature = ECDSA_do_sign(CT.GetPtr(), CT.GetSize(), key.GetPtr()), nullptr);
3681
3682
453
#if defined(CRYPTOFUZZ_LIBRESSL)
3683
453
        /* noret */ ECDSA_SIG_get0(signature, &R, &S);
3684
453
        CF_CHECK_NE(R, nullptr);
3685
453
        CF_CHECK_NE(S, nullptr);
3686
#else
3687
        CF_CHECK_NE(R = ECDSA_SIG_get0_r(signature), nullptr);
3688
        CF_CHECK_NE(S = ECDSA_SIG_get0_s(signature), nullptr);
3689
#endif
3690
3691
        /* Convert bignum x/y to strings */
3692
453
        CF_CHECK_NE(sig_r_str = BN_bn2dec(R), nullptr);
3693
453
        CF_CHECK_NE(sig_s_str = BN_bn2dec(S), nullptr);
3694
3695
3696
453
        component::Bignum S_corrected{std::string(sig_s_str)};
3697
453
        CF_NORET(util::AdjustECDSASignature(op.curveType.Get(), S_corrected));
3698
3699
453
        ret = { {sig_r_str, S_corrected.ToTrimmedString()}, {pub_x_str, pub_y_str} };
3700
453
    } catch ( ... ) { }
3701
3702
930
end:
3703
930
    if ( signature != nullptr ) {
3704
453
        ECDSA_SIG_free(signature);
3705
453
    }
3706
930
    OPENSSL_free(pub_x_str);
3707
930
    OPENSSL_free(pub_y_str);
3708
930
    OPENSSL_free(sig_r_str);
3709
930
    OPENSSL_free(sig_s_str);
3710
3711
930
    global_ds = nullptr;
3712
3713
930
    return ret;
3714
930
}
3715
#endif /* CRYPTOFUZZ_OPENSSL_102, CRYPTOFUZZ_OPENSSL_098 */
3716
3717
656
std::optional<bool> OpenSSL::OpECDSA_Verify(operation::ECDSA_Verify& op) {
3718
656
    std::optional<bool> ret = std::nullopt;
3719
656
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
3720
3721
656
    global_ds = &ds;
3722
3723
656
    ECDSA_SIG* signature = nullptr;
3724
3725
656
    try {
3726
656
        CF_EC_KEY key(ds);
3727
656
        std::shared_ptr<CF_EC_GROUP> group = nullptr;
3728
3729
656
        std::unique_ptr<CF_EC_POINT> pub = nullptr;
3730
3731
656
        OpenSSL_bignum::Bignum sig_s(ds);
3732
656
        OpenSSL_bignum::Bignum sig_r(ds);
3733
3734
        /* Initialize */
3735
656
        {
3736
656
            {
3737
656
                std::optional<int> curveNID;
3738
656
                CF_CHECK_NE(curveNID = toCurveNID(op.curveType), std::nullopt);
3739
583
                CF_CHECK_NE(group = std::make_shared<CF_EC_GROUP>(ds, *curveNID), nullptr);
3740
583
                group->Lock();
3741
583
                CF_CHECK_NE(group->GetPtr(), nullptr);
3742
540
            }
3743
540
            CF_CHECK_EQ(EC_KEY_set_group(key.GetPtr(), group->GetPtr()), 1);
3744
3745
            /* Construct signature */
3746
540
            CF_CHECK_EQ(sig_r.Set(op.signature.signature.first.ToString(ds)), true);
3747
540
            CF_CHECK_EQ(sig_s.Set(op.signature.signature.second.ToString(ds)), true);
3748
540
            CF_CHECK_NE(signature = ECDSA_SIG_new(), nullptr);
3749
#if defined(CRYPTOFUZZ_OPENSSL_102) || defined(CRYPTOFUZZ_OPENSSL_098)
3750
            BN_free(signature->r);
3751
            BN_free(signature->s);
3752
            signature->r = sig_r.GetPtrConst();
3753
            signature->s = sig_s.GetPtrConst();
3754
#else
3755
540
            CF_CHECK_EQ(ECDSA_SIG_set0(signature, sig_r.GetDestPtr(false), sig_s.GetDestPtr(false)), 1);
3756
540
#endif
3757
            /* 'signature' now has ownership, and the BIGNUMs will be freed by ECDSA_SIG_free */
3758
540
            sig_r.ReleaseOwnership();
3759
540
            sig_s.ReleaseOwnership();
3760
3761
            /* Construct key */
3762
540
            CF_CHECK_NE(pub = std::make_unique<CF_EC_POINT>(ds, group, op.curveType.Get()), nullptr);
3763
540
            CF_CHECK_TRUE(pub->Set(op.signature.pub.first, op.signature.pub.second, false));
3764
459
            CF_CHECK_EQ(EC_KEY_set_public_key(key.GetPtr(), pub->GetPtr()), 1);
3765
459
        }
3766
3767
        /* Process */
3768
0
        {
3769
459
            int res;
3770
459
            if ( op.digestType.Get() == CF_DIGEST("NULL") ) {
3771
434
                const auto CT = op.cleartext.ECDSA_RandomPad(ds, op.curveType);
3772
434
                res = ECDSA_do_verify(CT.GetPtr(), CT.GetSize(), signature, key.GetPtr());
3773
434
            } else if ( op.digestType.Get() == CF_DIGEST("SHA256") ) {
3774
4
                uint8_t CT[32];
3775
4
                SHA256(op.cleartext.GetPtr(), op.cleartext.GetSize(), CT);
3776
4
                res = ECDSA_do_verify(CT, sizeof(CT), signature, key.GetPtr());
3777
21
            } else {
3778
                /* TODO other digests */
3779
21
                goto end;
3780
21
            }
3781
3782
438
            if ( res == 0 ) {
3783
20
                ret = false;
3784
418
            } else if ( res == 1 ) {
3785
418
                ret = true;
3786
418
            } else {
3787
                /* ECDSA_do_verify failed -- don't set ret */
3788
0
            }
3789
3790
438
        }
3791
438
    } catch ( ... ) { }
3792
3793
656
end:
3794
656
    if ( signature != nullptr ) {
3795
540
        ECDSA_SIG_free(signature);
3796
540
    }
3797
3798
656
    global_ds = nullptr;
3799
3800
656
    return ret;
3801
656
}
3802
3803
51
std::optional<component::Secret> OpenSSL::OpECDH_Derive(operation::ECDH_Derive& op) {
3804
51
    std::optional<component::Secret> ret = std::nullopt;
3805
51
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
3806
3807
3808
51
    CF_EC_KEY key(ds);
3809
51
    OpenSSL_bignum::Bignum prv(ds);
3810
51
    std::shared_ptr<CF_EC_GROUP> group = nullptr;
3811
51
    std::unique_ptr<CF_EC_POINT> pub = nullptr;
3812
51
    uint8_t* secret = nullptr;
3813
51
    int secret_len;
3814
3815
51
    {
3816
51
        std::optional<int> curveNID;
3817
51
        CF_CHECK_NE(curveNID = toCurveNID(op.curveType), std::nullopt);
3818
21
        CF_CHECK_NE(group = std::make_shared<CF_EC_GROUP>(ds, *curveNID), nullptr);
3819
21
        group->Lock();
3820
21
        CF_CHECK_NE(group->GetPtr(), nullptr);
3821
17
    }
3822
3823
    /* Load private key */
3824
0
    {
3825
17
        CF_CHECK_EQ(EC_KEY_set_group(key.GetPtr(), group->GetPtr()), 1);
3826
3827
        /* Load private key */
3828
17
        CF_CHECK_EQ(prv.Set(op.priv.ToString(ds)), true);
3829
3830
        /* Set private key */
3831
17
        CF_CHECK_EQ(EC_KEY_set_private_key(key.GetPtr(), prv.GetPtr()), 1);
3832
17
    }
3833
3834
    /* Load public key */
3835
0
    {
3836
17
        CF_CHECK_NE(pub = std::make_unique<CF_EC_POINT>(ds, group, op.curveType.Get()), nullptr);
3837
17
        CF_CHECK_TRUE(pub->Set(op.pub.first, op.pub.second, false, false));
3838
5
    }
3839
3840
#if 0
3841
    secret_len = ECDH_compute_key(
3842
            nullptr, 0, pub->GetPtr(), key.GetPtr(), nullptr);
3843
    CF_CHECK_GT(secret_len, 0);
3844
    abort();
3845
#endif
3846
3847
0
    secret_len = 1024;
3848
5
    secret = util::malloc(secret_len);
3849
3850
5
    secret_len = ECDH_compute_key(
3851
5
             secret,
3852
5
             1024,
3853
5
             pub->GetPtr(),
3854
5
             key.GetPtr(), nullptr);
3855
5
    CF_CHECK_GT(secret_len, 0);
3856
3857
4
    ret = component::Secret(Buffer(secret, secret_len));
3858
3859
51
end:
3860
51
    util::free(secret);
3861
3862
51
    return ret;
3863
4
}
3864
3865
/* TODO OpenSSL 1.0.2, 0.9.8 */
3866
#if !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_098)
3867
167
std::optional<component::DH_KeyPair> OpenSSL::OpDH_GenerateKeyPair(operation::DH_GenerateKeyPair& op) {
3868
167
    std::optional<component::DH_KeyPair> ret = std::nullopt;
3869
167
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
3870
3871
167
    global_ds = &ds;
3872
3873
167
    DH* dh = nullptr;
3874
167
    char* priv_str = nullptr;
3875
167
    char* pub_str = nullptr;
3876
3877
167
    CF_CHECK_NE(dh = DH_new(), nullptr);
3878
3879
167
    try {
3880
167
        OpenSSL_bignum::Bignum prime(ds), base(ds);
3881
        /* Set prime and base */
3882
167
        {
3883
167
            CF_CHECK_EQ(prime.Set(op.prime.ToString(ds)), true);
3884
167
            CF_CHECK_EQ(base.Set(op.base.ToString(ds)), true);
3885
3886
167
            CF_CHECK_EQ(DH_set0_pqg(dh, prime.GetPtrConst(), nullptr, base.GetPtrConst()), 1);
3887
167
            prime.ReleaseOwnership();
3888
167
            base.ReleaseOwnership();
3889
167
        }
3890
3891
167
        CF_CHECK_EQ(DH_generate_key(dh), 1);
3892
3893
118
        {
3894
118
            const BIGNUM* priv = nullptr, *pub = nullptr;
3895
118
            /* noret */ DH_get0_key(dh, &priv, &pub);
3896
118
            CF_CHECK_NE(priv, nullptr);
3897
118
            CF_CHECK_NE(pub, nullptr);
3898
3899
118
            CF_CHECK_NE(priv_str = BN_bn2dec(priv), nullptr);
3900
118
            CF_CHECK_NE(pub_str = BN_bn2dec(pub), nullptr);
3901
118
        }
3902
3903
0
        ret = { std::string(priv_str), std::string(pub_str) };
3904
118
    } catch ( ... ) { }
3905
3906
167
end:
3907
167
    DH_free(dh);
3908
167
    OPENSSL_free(priv_str);
3909
167
    OPENSSL_free(pub_str);
3910
3911
167
    global_ds = nullptr;
3912
3913
167
    return ret;
3914
167
}
3915
#endif /* CRYPTOFUZZ_OPENSSL_102, CRYPTOFUZZ_OPENSSL_098 */
3916
3917
/* TODO OpenSSL 1.0.2, 0.9.8 */
3918
#if !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_098)
3919
171
std::optional<component::Bignum> OpenSSL::OpDH_Derive(operation::DH_Derive& op) {
3920
171
    std::optional<component::Bignum> ret = std::nullopt;
3921
171
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
3922
3923
171
    DH* dh = nullptr;
3924
171
    OpenSSL_bignum::Bignum prime(ds), base(ds), priv(ds), pub(ds), derived(ds);
3925
171
    uint8_t* derived_bytes = nullptr;
3926
171
    int derived_size;
3927
3928
171
    CF_CHECK_NE(op.priv.ToTrimmedString(), "0");
3929
159
    CF_CHECK_NE(dh = DH_new(), nullptr);
3930
3931
    /* Set prime, base and private key */
3932
159
    {
3933
159
        CF_CHECK_EQ(prime.Set(op.prime.ToString(ds)), true);
3934
159
        CF_CHECK_EQ(base.Set(op.base.ToString(ds)), true);
3935
3936
159
        CF_CHECK_EQ(DH_set0_pqg(dh, prime.GetPtrConst(), nullptr, base.GetPtrConst()), 1);
3937
159
        prime.ReleaseOwnership();
3938
159
        base.ReleaseOwnership();
3939
3940
159
        CF_CHECK_EQ(priv.Set(op.priv.ToString(ds)), true);
3941
159
        CF_CHECK_EQ(DH_set0_key(dh, nullptr, priv.GetPtrConst()), 1);
3942
159
        priv.ReleaseOwnership();
3943
159
    }
3944
3945
0
    derived_size = DH_size(dh);
3946
159
    derived_bytes = util::malloc(derived_size);
3947
3948
159
    CF_CHECK_EQ(pub.Set(op.pub.ToString(ds)), true);
3949
3950
159
    CF_CHECK_NE(derived_size = DH_compute_key(derived_bytes, pub.GetPtr(), dh), -1);
3951
3952
27
    CF_CHECK_EQ(derived.New(), true);
3953
27
    CF_CHECK_NE(BN_bin2bn(derived_bytes, derived_size, derived.GetDestPtr()), nullptr);
3954
3955
27
    CF_CHECK_EQ(BN_is_zero(derived.GetPtr()), 0);
3956
3957
27
    ret = derived.ToComponentBignum();
3958
3959
171
end:
3960
171
    DH_free(dh);
3961
171
    util::free(derived_bytes);
3962
171
    return ret;
3963
27
}
3964
#endif /* CRYPTOFUZZ_OPENSSL_102, CRYPTOFUZZ_OPENSSL_098 */
3965
3966
26
std::optional<component::Bignum> OpenSSL::OpDSA_PrivateToPublic(operation::DSA_PrivateToPublic& op) {
3967
26
    std::optional<component::Bignum> ret = std::nullopt;
3968
26
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
3969
3970
26
    global_ds = &ds;
3971
26
    OpenSSL_bignum::Bignum priv(ds);
3972
26
    DSA* dsa = nullptr;
3973
26
    char* str;
3974
26
    const BIGNUM* pub = nullptr;
3975
26
    std::string pub_str;
3976
3977
26
    CF_CHECK_EQ(priv.Set(op.priv.ToString(ds)), true);
3978
3979
26
    CF_CHECK_NE(dsa = DSA_new(), nullptr);
3980
26
    CF_CHECK_NE(DSA_set0_key(dsa, nullptr, priv.GetDestPtr()), 0);
3981
0
    priv.ReleaseOwnership();
3982
3983
0
    CF_CHECK_NE(DSA_generate_key(dsa), 0);
3984
0
    CF_NORET(DSA_get0_key(dsa, &pub, nullptr));
3985
0
    CF_CHECK_NE(str = BN_bn2dec(pub), nullptr);
3986
0
    pub_str = str;
3987
0
    OPENSSL_free(str);
3988
3989
0
    ret = pub_str;
3990
3991
26
end:
3992
3993
26
    CF_NORET(DSA_free(dsa));
3994
3995
26
    global_ds = nullptr;
3996
3997
26
    return ret;
3998
0
}
3999
4000
623
std::optional<component::DSA_Parameters> OpenSSL::OpDSA_GenerateParameters(operation::DSA_GenerateParameters& op) {
4001
623
    (void)op;
4002
623
    std::optional<component::DSA_Parameters> ret = std::nullopt;
4003
623
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
4004
4005
623
    global_ds = &ds;
4006
4007
623
    DSA* dsa = nullptr;
4008
4009
623
    CF_CHECK_NE(dsa = DSA_new(), nullptr);
4010
623
    CF_CHECK_NE(DSA_generate_parameters_ex(dsa, 1024, NULL, 0, NULL, NULL, NULL), 0);
4011
4012
623
    {
4013
623
        std::string p_str, q_str, g_str;
4014
4015
623
        char* str;
4016
4017
623
        CF_CHECK_NE(str = BN_bn2dec(DSA_get0_p(dsa)), nullptr);
4018
623
        p_str = str;
4019
623
        OPENSSL_free(str);
4020
4021
623
        CF_CHECK_NE(str = BN_bn2dec(DSA_get0_q(dsa)), nullptr);
4022
623
        q_str = str;
4023
623
        OPENSSL_free(str);
4024
4025
623
        CF_CHECK_NE(str = BN_bn2dec(DSA_get0_g(dsa)), nullptr);
4026
623
        g_str = str;
4027
623
        OPENSSL_free(str);
4028
4029
623
        ret = { p_str, q_str, g_str };
4030
623
    }
4031
4032
623
end:
4033
623
    CF_NORET(DSA_free(dsa));
4034
4035
623
    global_ds = nullptr;
4036
4037
623
    return ret;
4038
623
}
4039
4040
100
std::optional<component::DSA_Signature> OpenSSL::OpDSA_Sign(operation::DSA_Sign& op) {
4041
100
    std::optional<component::DSA_Signature> ret = std::nullopt;
4042
100
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
4043
4044
100
    global_ds = &ds;
4045
4046
100
    DSA* dsa = nullptr;
4047
100
    DSA_SIG* dsa_sig = nullptr;
4048
100
    uint8_t* signature = nullptr;
4049
100
    unsigned int signature_len;
4050
100
    OpenSSL_bignum::Bignum p(ds), q(ds), g(ds), pub(ds), priv(ds);
4051
100
    std::string r_str, s_str, pub_str;
4052
4053
100
    CF_CHECK_EQ(p.Set(op.parameters.p.ToString(ds)), true);
4054
100
    CF_CHECK_EQ(q.Set(op.parameters.q.ToString(ds)), true);
4055
100
    CF_CHECK_EQ(g.Set(op.parameters.g.ToString(ds)), true);
4056
4057
    /* Prevent time-outs */
4058
100
    CF_CHECK_LTE(BN_num_bits(p.GetPtr()), 7000);
4059
97
    CF_CHECK_LTE(BN_num_bits(q.GetPtr()), 7000);
4060
96
    CF_CHECK_LTE(BN_num_bits(g.GetPtr()), 7000);
4061
4062
95
    CF_CHECK_TRUE(pub.New());
4063
95
    CF_CHECK_EQ(priv.Set(op.priv.ToString(ds)), true);
4064
4065
95
    CF_CHECK_NE(dsa = DSA_new(), nullptr);
4066
4067
95
    CF_CHECK_NE(DSA_set0_pqg(dsa, p.GetDestPtr(), q.GetDestPtr(), g.GetDestPtr()), 0);
4068
4069
95
    p.ReleaseOwnership();
4070
95
    q.ReleaseOwnership();
4071
95
    g.ReleaseOwnership();
4072
4073
95
    CF_CHECK_NE(DSA_set0_key(dsa, pub.GetDestPtr(), priv.GetDestPtr()), 0);
4074
95
    pub.ReleaseOwnership();
4075
95
    priv.ReleaseOwnership();
4076
4077
95
    signature = util::malloc(DSA_size(dsa));
4078
95
    CF_CHECK_NE(DSA_sign(
4079
95
                0,
4080
95
                op.cleartext.GetPtr(), op.cleartext.GetSize(),
4081
95
                signature, &signature_len,
4082
95
                dsa), 0);
4083
4084
0
    {
4085
0
        const uint8_t* p = signature;
4086
0
        CF_CHECK_NE(dsa_sig = d2i_DSA_SIG(nullptr, &p, signature_len), nullptr);
4087
0
        const BIGNUM *r, *s;
4088
0
        CF_NORET(DSA_SIG_get0(dsa_sig, &r, &s));
4089
4090
0
        char* str;
4091
0
        CF_CHECK_NE(str = BN_bn2dec(r), nullptr);
4092
0
        r_str = str;
4093
0
        OPENSSL_free(str);
4094
4095
0
        CF_CHECK_NE(str = BN_bn2dec(s), nullptr);
4096
0
        s_str = str;
4097
0
        OPENSSL_free(str);
4098
4099
0
        CF_CHECK_NE(DSA_generate_key(dsa), 0);
4100
0
        const BIGNUM* pub = nullptr;
4101
0
        CF_NORET(DSA_get0_key(dsa, &pub, nullptr));
4102
0
        CF_CHECK_NE(str = BN_bn2dec(pub), nullptr);
4103
0
        pub_str = str;
4104
0
        OPENSSL_free(str);
4105
4106
0
        ret = component::DSA_Signature({r_str, s_str}, pub_str);
4107
0
    }
4108
4109
100
end:
4110
100
    CF_NORET(DSA_free(dsa));
4111
100
    CF_NORET(DSA_SIG_free(dsa_sig));
4112
100
    util::free(signature);
4113
4114
100
    global_ds = nullptr;
4115
4116
100
    return ret;
4117
0
}
4118
4119
216
std::optional<bool> OpenSSL::OpDSA_Verify(operation::DSA_Verify& op) {
4120
216
    std::optional<bool> ret = std::nullopt;
4121
216
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
4122
4123
216
    global_ds = &ds;
4124
4125
216
    DSA* dsa = nullptr;
4126
216
    DSA_SIG* dsa_sig = nullptr;
4127
216
    uint8_t* signature = nullptr;
4128
216
    OpenSSL_bignum::Bignum p(ds), q(ds), g(ds), r(ds), s(ds), pub(ds);
4129
216
    std::string r_str, s_str, pub_str;
4130
4131
216
    CF_CHECK_EQ(p.Set(op.parameters.p.ToString(ds)), true);
4132
216
    CF_CHECK_EQ(q.Set(op.parameters.q.ToString(ds)), true);
4133
216
    CF_CHECK_EQ(g.Set(op.parameters.g.ToString(ds)), true);
4134
216
    CF_CHECK_EQ(r.Set(op.signature.first.ToString(ds)), true);
4135
216
    CF_CHECK_EQ(s.Set(op.signature.second.ToString(ds)), true);
4136
216
    CF_CHECK_EQ(pub.Set(op.pub.ToString(ds)), true);
4137
4138
216
    CF_CHECK_NE(dsa = DSA_new(), nullptr);
4139
4140
216
    CF_CHECK_NE(DSA_set0_pqg(dsa, p.GetDestPtr(), q.GetDestPtr(), g.GetDestPtr()), 0);
4141
4142
216
    p.ReleaseOwnership();
4143
216
    q.ReleaseOwnership();
4144
216
    g.ReleaseOwnership();
4145
4146
216
    CF_CHECK_NE(DSA_set0_key(dsa, pub.GetDestPtr(), nullptr), 0);
4147
216
    pub.ReleaseOwnership();
4148
4149
216
    {
4150
216
        CF_CHECK_NE(dsa_sig = DSA_SIG_new(), nullptr);
4151
4152
216
        CF_CHECK_NE(DSA_SIG_set0(dsa_sig, r.GetDestPtr(), s.GetDestPtr()), 0);
4153
216
        r.ReleaseOwnership();
4154
216
        s.ReleaseOwnership();
4155
4156
216
        const auto siglen = i2d_DSA_SIG(dsa_sig, &signature);
4157
216
        CF_CHECK_GT(siglen, 0);
4158
4159
216
        const auto r = DSA_verify(
4160
216
                0,
4161
216
                op.cleartext.GetPtr(), op.cleartext.GetSize(),
4162
216
                signature, siglen,
4163
216
                dsa);
4164
4165
216
        CF_CHECK_NE(r, -1);
4166
4167
2
        ret = r;
4168
2
    }
4169
4170
216
end:
4171
216
    CF_NORET(DSA_free(dsa));
4172
216
    CF_NORET(DSA_SIG_free(dsa_sig));
4173
216
    OPENSSL_free(signature);
4174
4175
216
    global_ds = nullptr;
4176
4177
216
    return ret;
4178
2
}
4179
4180
117
std::optional<component::ECC_Point> OpenSSL::OpECC_Point_Add(operation::ECC_Point_Add& op) {
4181
117
    std::optional<component::ECC_Point> ret = std::nullopt;
4182
117
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
4183
4184
117
    global_ds = &ds;
4185
4186
117
    std::shared_ptr<CF_EC_GROUP> group = nullptr;
4187
117
    std::unique_ptr<CF_EC_POINT> a = nullptr, b = nullptr, res = nullptr;
4188
117
    char* x_str = nullptr;
4189
117
    char* y_str = nullptr;
4190
4191
117
    {
4192
117
        std::optional<int> curveNID;
4193
117
        CF_CHECK_NE(curveNID = toCurveNID(op.curveType), std::nullopt);
4194
90
        CF_CHECK_NE(group = std::make_shared<CF_EC_GROUP>(ds, *curveNID), nullptr);
4195
90
        group->Lock();
4196
90
        CF_CHECK_NE(group->GetPtr(), nullptr);
4197
68
    }
4198
4199
68
    CF_CHECK_NE(a = std::make_unique<CF_EC_POINT>(ds, group, op.curveType.Get()), nullptr);
4200
68
    CF_CHECK_TRUE(a->Set(op.a.first, op.a.second));
4201
4202
27
    CF_CHECK_NE(b = std::make_unique<CF_EC_POINT>(ds, group, op.curveType.Get()), nullptr);
4203
27
    CF_CHECK_TRUE(b->Set(op.b.first, op.b.second));
4204
4205
12
    CF_CHECK_NE(res = std::make_unique<CF_EC_POINT>(ds, group, op.curveType.Get()), nullptr);
4206
4207
12
    CF_CHECK_NE(EC_POINT_add(group->GetPtr(), res->GetPtr(), a->GetPtr(), b->GetPtr(), nullptr), 0);
4208
4209
12
    if ( a->IsProjective() ) {
4210
0
        OpenSSL_bignum::BN_CTX ctx(ds);
4211
0
        if ( !EC_POINT_is_on_curve(group->GetPtr(), a->GetPtr(), ctx.GetPtr()) ) {
4212
0
            goto end;
4213
0
        }
4214
0
    }
4215
4216
12
    if ( b->IsProjective() ) {
4217
0
        OpenSSL_bignum::BN_CTX ctx(ds);
4218
0
        if ( !EC_POINT_is_on_curve(group->GetPtr(), b->GetPtr(), ctx.GetPtr()) ) {
4219
0
            goto end;
4220
0
        }
4221
0
    }
4222
4223
12
    {
4224
12
        OpenSSL_bignum::Bignum x(ds);
4225
12
        OpenSSL_bignum::Bignum y(ds);
4226
4227
12
        CF_CHECK_EQ(x.New(), true);
4228
12
        CF_CHECK_EQ(y.New(), true);
4229
4230
#if !defined(CRYPTOFUZZ_BORINGSSL) && !defined(CRYPTOFUZZ_LIBRESSL) && !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_110) && !defined(CRYPTOFUZZ_OPENSSL_098)
4231
        CF_CHECK_NE(EC_POINT_get_affine_coordinates(group->GetPtr(), res->GetPtr(), x.GetDestPtr(), y.GetDestPtr(), nullptr), 0);
4232
#else
4233
12
        CF_CHECK_NE(EC_POINT_get_affine_coordinates_GFp(group->GetPtr(), res->GetPtr(), x.GetDestPtr(), y.GetDestPtr(), nullptr), 0);
4234
12
#endif
4235
4236
        /* Convert bignum x/y to strings */
4237
12
        CF_CHECK_NE(x_str = BN_bn2dec(x.GetPtr()), nullptr);
4238
12
        CF_CHECK_NE(y_str = BN_bn2dec(y.GetPtr()), nullptr);
4239
4240
12
        ret = { std::string(x_str), std::string(y_str) };
4241
12
    }
4242
4243
117
end:
4244
117
    OPENSSL_free(x_str);
4245
117
    OPENSSL_free(y_str);
4246
4247
117
    global_ds = nullptr;
4248
4249
117
    return ret;
4250
12
}
4251
4252
164
std::optional<component::ECC_Point> OpenSSL::OpECC_Point_Mul(operation::ECC_Point_Mul& op) {
4253
164
    std::optional<component::ECC_Point> ret = std::nullopt;
4254
164
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
4255
4256
164
    global_ds = &ds;
4257
4258
164
    std::shared_ptr<CF_EC_GROUP> group = nullptr;
4259
164
    std::unique_ptr<CF_EC_POINT> a = nullptr, res = nullptr;
4260
164
    OpenSSL_bignum::Bignum b(ds);
4261
164
    char* x_str = nullptr;
4262
164
    char* y_str = nullptr;
4263
4264
164
    {
4265
164
        std::optional<int> curveNID;
4266
164
        CF_CHECK_NE(curveNID = toCurveNID(op.curveType), std::nullopt);
4267
126
        CF_CHECK_NE(group = std::make_shared<CF_EC_GROUP>(ds, *curveNID), nullptr);
4268
126
        group->Lock();
4269
126
        CF_CHECK_NE(group->GetPtr(), nullptr);
4270
99
    }
4271
4272
99
    CF_CHECK_NE(a = std::make_unique<CF_EC_POINT>(ds, group, op.curveType.Get()), nullptr);
4273
99
    CF_CHECK_TRUE(a->Set(op.a.first, op.a.second));
4274
4275
46
    CF_CHECK_NE(res = std::make_unique<CF_EC_POINT>(ds, group, op.curveType.Get()), nullptr);
4276
4277
46
    CF_CHECK_EQ(b.Set(op.b.ToString(ds)), true);
4278
4279
46
#if !defined(CRYPTOFUZZ_BORINGSSL)
4280
46
    {
4281
46
        bool precompute = false;
4282
46
        try {
4283
46
            precompute = ds.Get<bool>();
4284
46
        } catch ( fuzzing::datasource::Datasource::OutOfData& ) {
4285
31
        }
4286
4287
46
        if ( precompute == true ) {
4288
9
            CF_CHECK_NE(EC_GROUP_precompute_mult(group->GetPtr(), nullptr), 0);
4289
0
        }
4290
46
    }
4291
37
#endif
4292
4293
37
    CF_CHECK_NE(EC_POINT_mul(group->GetPtr(), res->GetPtr(), nullptr, a->GetPtr(), b.GetPtr(), nullptr), 0);
4294
4295
37
    if ( op.b.ToTrimmedString() == "0" ) {
4296
1
        if ( !a->IsProjective() ) {
4297
1
            CF_ASSERT(
4298
1
                    EC_POINT_is_at_infinity(group->GetPtr(), res->GetPtr()) == 1,
4299
1
                    "Point multiplication by 0 does not yield point at infinity");
4300
1
        }
4301
1
    }
4302
4303
    /* Bug */
4304
37
#if !defined(CRYPTOFUZZ_OPENSSL_098)
4305
37
    {
4306
37
        if ( !a->IsProjective() ) {
4307
37
            OpenSSL_bignum::BN_CTX ctx(ds);
4308
4309
37
            if ( !EC_POINT_is_on_curve(group->GetPtr(), a->GetPtr(), ctx.GetPtr()) ) {
4310
0
                CF_ASSERT(
4311
0
                        EC_POINT_is_on_curve(group->GetPtr(), res->GetPtr(), ctx.GetPtr()) == 0,
4312
0
                        "Point multiplication of invalid point yields valid point");
4313
0
            }
4314
37
        }
4315
37
    }
4316
37
#endif
4317
4318
37
    if ( a->IsProjective() ) {
4319
0
        OpenSSL_bignum::BN_CTX ctx(ds);
4320
0
        if ( !EC_POINT_is_on_curve(group->GetPtr(), a->GetPtr(), ctx.GetPtr()) ) {
4321
0
            goto end;
4322
0
        }
4323
0
    }
4324
4325
37
    ret = res->Get();
4326
4327
164
end:
4328
164
    OPENSSL_free(x_str);
4329
164
    OPENSSL_free(y_str);
4330
4331
164
    global_ds = nullptr;
4332
4333
164
    return ret;
4334
37
}
4335
4336
139
std::optional<component::ECC_Point> OpenSSL::OpECC_Point_Neg(operation::ECC_Point_Neg& op) {
4337
139
    std::optional<component::ECC_Point> ret = std::nullopt;
4338
139
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
4339
4340
139
    std::shared_ptr<CF_EC_GROUP> group = nullptr;
4341
139
    std::unique_ptr<CF_EC_POINT> a = nullptr, res = nullptr;
4342
139
    char* x_str = nullptr;
4343
139
    char* y_str = nullptr;
4344
4345
139
    {
4346
139
        std::optional<int> curveNID;
4347
139
        CF_CHECK_NE(curveNID = toCurveNID(op.curveType), std::nullopt);
4348
103
        CF_CHECK_NE(group = std::make_shared<CF_EC_GROUP>(ds, *curveNID), nullptr);
4349
103
        group->Lock();
4350
103
        CF_CHECK_NE(group->GetPtr(), nullptr);
4351
77
    }
4352
4353
77
    CF_CHECK_NE(a = std::make_unique<CF_EC_POINT>(ds, group, op.curveType.Get()), nullptr);
4354
77
    CF_CHECK_TRUE(a->Set(op.a.first, op.a.second));
4355
4356
7
    CF_CHECK_NE(EC_POINT_invert(group->GetPtr(), a->GetPtr(), nullptr), 0);
4357
4358
7
    {
4359
7
        OpenSSL_bignum::Bignum x(ds);
4360
7
        OpenSSL_bignum::Bignum y(ds);
4361
4362
7
        CF_CHECK_EQ(x.New(), true);
4363
7
        CF_CHECK_EQ(y.New(), true);
4364
4365
#if !defined(CRYPTOFUZZ_BORINGSSL) && !defined(CRYPTOFUZZ_LIBRESSL) && !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_110) && !defined(CRYPTOFUZZ_OPENSSL_098)
4366
        CF_CHECK_NE(EC_POINT_get_affine_coordinates(group->GetPtr(), a->GetPtr(), x.GetDestPtr(), y.GetDestPtr(), nullptr), 0);
4367
#else
4368
7
        CF_CHECK_NE(EC_POINT_get_affine_coordinates_GFp(group->GetPtr(), a->GetPtr(), x.GetDestPtr(), y.GetDestPtr(), nullptr), 0);
4369
7
#endif
4370
4371
        /* Convert bignum x/y to strings */
4372
7
        CF_CHECK_NE(x_str = BN_bn2dec(x.GetPtr()), nullptr);
4373
7
        CF_CHECK_NE(y_str = BN_bn2dec(y.GetPtr()), nullptr);
4374
4375
7
        ret = { std::string(x_str), std::string(y_str) };
4376
7
    }
4377
4378
139
end:
4379
139
    OPENSSL_free(x_str);
4380
139
    OPENSSL_free(y_str);
4381
4382
139
    return ret;
4383
7
}
4384
4385
225
std::optional<component::ECC_Point> OpenSSL::OpECC_Point_Dbl(operation::ECC_Point_Dbl& op) {
4386
225
    std::optional<component::ECC_Point> ret = std::nullopt;
4387
225
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
4388
4389
225
    global_ds = &ds;
4390
4391
225
    std::shared_ptr<CF_EC_GROUP> group = nullptr;
4392
225
    std::unique_ptr<CF_EC_POINT> a = nullptr, res = nullptr;
4393
225
    char* x_str = nullptr;
4394
225
    char* y_str = nullptr;
4395
4396
225
    {
4397
225
        std::optional<int> curveNID;
4398
225
        CF_CHECK_NE(curveNID = toCurveNID(op.curveType), std::nullopt);
4399
198
        CF_CHECK_NE(group = std::make_shared<CF_EC_GROUP>(ds, *curveNID), nullptr);
4400
198
        group->Lock();
4401
198
        CF_CHECK_NE(group->GetPtr(), nullptr);
4402
185
    }
4403
4404
185
    CF_CHECK_NE(a = std::make_unique<CF_EC_POINT>(ds, group, op.curveType.Get()), nullptr);
4405
185
    CF_CHECK_TRUE(a->Set(op.a.first, op.a.second));
4406
4407
26
    CF_CHECK_NE(res = std::make_unique<CF_EC_POINT>(ds, group, op.curveType.Get()), nullptr);
4408
4409
26
    CF_CHECK_NE(EC_POINT_dbl(group->GetPtr(), res->GetPtr(), a->GetPtr(), nullptr), 0);
4410
4411
26
    {
4412
26
        OpenSSL_bignum::Bignum x(ds);
4413
26
        OpenSSL_bignum::Bignum y(ds);
4414
4415
26
        CF_CHECK_EQ(x.New(), true);
4416
26
        CF_CHECK_EQ(y.New(), true);
4417
4418
#if !defined(CRYPTOFUZZ_BORINGSSL) && !defined(CRYPTOFUZZ_LIBRESSL) && !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_110) && !defined(CRYPTOFUZZ_OPENSSL_098)
4419
        CF_CHECK_NE(EC_POINT_get_affine_coordinates(group->GetPtr(), res->GetPtr(), x.GetDestPtr(), y.GetDestPtr(), nullptr), 0);
4420
#else
4421
26
        CF_CHECK_NE(EC_POINT_get_affine_coordinates_GFp(group->GetPtr(), res->GetPtr(), x.GetDestPtr(), y.GetDestPtr(), nullptr), 0);
4422
26
#endif
4423
4424
        /* Convert bignum x/y to strings */
4425
26
        CF_CHECK_NE(x_str = BN_bn2dec(x.GetPtr()), nullptr);
4426
26
        CF_CHECK_NE(y_str = BN_bn2dec(y.GetPtr()), nullptr);
4427
4428
26
        ret = { std::string(x_str), std::string(y_str) };
4429
26
    }
4430
4431
225
end:
4432
225
    OPENSSL_free(x_str);
4433
225
    OPENSSL_free(y_str);
4434
4435
225
    global_ds = nullptr;
4436
4437
225
    return ret;
4438
26
}
4439
4440
113
std::optional<bool> OpenSSL::OpECC_Point_Cmp(operation::ECC_Point_Cmp& op) {
4441
113
    std::optional<bool> ret = std::nullopt;
4442
113
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
4443
4444
113
    global_ds = &ds;
4445
4446
113
    std::shared_ptr<CF_EC_GROUP> group = nullptr;
4447
113
    std::unique_ptr<CF_EC_POINT> a = nullptr, b = nullptr;
4448
4449
113
    {
4450
113
        std::optional<int> curveNID;
4451
113
        CF_CHECK_NE(curveNID = toCurveNID(op.curveType), std::nullopt);
4452
82
        CF_CHECK_NE(group = std::make_shared<CF_EC_GROUP>(ds, *curveNID), nullptr);
4453
82
        group->Lock();
4454
82
        CF_CHECK_NE(group->GetPtr(), nullptr);
4455
45
    }
4456
4457
45
    CF_CHECK_NE(a = std::make_unique<CF_EC_POINT>(ds, group, op.curveType.Get()), nullptr);
4458
45
    CF_CHECK_TRUE(a->Set(op.a.first, op.a.second));
4459
4460
5
    CF_CHECK_NE(b = std::make_unique<CF_EC_POINT>(ds, group, op.curveType.Get()), nullptr);
4461
5
    CF_CHECK_TRUE(b->Set(op.b.first, op.b.second));
4462
4463
2
    ret = EC_POINT_cmp(group->GetPtr(), a->GetPtr(), b->GetPtr(), nullptr) == 0;
4464
4465
113
end:
4466
113
    global_ds = nullptr;
4467
4468
113
    return ret;
4469
2
}
4470
4471
10.1k
std::optional<component::Bignum> OpenSSL::OpBignumCalc(operation::BignumCalc& op) {
4472
10.1k
    bool prime_modulus = false;
4473
4474
10.1k
    if ( op.modulo != std::nullopt ) {
4475
362
        if ( op.calcOp.Get() != CF_CALCOP("Sqrt(A)") ) {
4476
269
            return std::nullopt;
4477
269
        }
4478
4479
93
        if ( op.modulo->ToTrimmedString() == "52435875175126190479447740508185965837690552500527637822603658699938581184513" ) {
4480
18
            prime_modulus = true;
4481
75
        } else if ( op.modulo->ToTrimmedString() == "4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787" ) {
4482
33
            prime_modulus = true;
4483
42
        } else {
4484
42
            return std::nullopt;
4485
42
        }
4486
93
    }
4487
4488
9.81k
    std::optional<component::Bignum> ret = std::nullopt;
4489
9.81k
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
4490
4491
9.81k
    global_ds = &ds;
4492
4493
9.81k
    try {
4494
9.81k
        OpenSSL_bignum::BN_CTX ctx(ds);
4495
9.81k
        OpenSSL_bignum::BignumCluster bn(ds,
4496
9.81k
                OpenSSL_bignum::Bignum(ds),
4497
9.81k
                OpenSSL_bignum::Bignum(ds),
4498
9.81k
                OpenSSL_bignum::Bignum(ds),
4499
9.81k
                OpenSSL_bignum::Bignum(ds));
4500
4501
9.81k
        OpenSSL_bignum::Bignum res(ds);
4502
4503
9.81k
        std::unique_ptr<OpenSSL_bignum::Operation> opRunner = nullptr;
4504
4505
9.81k
        CF_CHECK_EQ(res.New(), true);
4506
9.81k
        CF_CHECK_EQ(bn.New(0), true);
4507
9.81k
        CF_CHECK_EQ(bn.New(1), true);
4508
9.81k
        CF_CHECK_EQ(bn.New(2), true);
4509
9.81k
        CF_CHECK_EQ(bn.New(3), true);
4510
4511
9.81k
        CF_NORET(res.Randomize());
4512
9.81k
        CF_CHECK_EQ(bn.Set(0, op.bn0.ToString(ds)), true);
4513
9.81k
        if ( prime_modulus == false ) {
4514
9.76k
            CF_CHECK_EQ(bn.Set(1, op.bn1.ToString(ds)), true);
4515
9.76k
        } else {
4516
51
            CF_CHECK_EQ(bn.Set(1, op.modulo->ToString(ds)), true);
4517
51
        }
4518
9.81k
        CF_CHECK_EQ(bn.Set(2, op.bn2.ToString(ds)), true);
4519
9.81k
        CF_CHECK_EQ(bn.Set(3, op.bn3.ToString(ds)), true);
4520
4521
9.81k
        switch ( op.calcOp.Get() ) {
4522
104
            case    CF_CALCOP("Add(A,B)"):
4523
104
                opRunner = std::make_unique<OpenSSL_bignum::Add>();
4524
104
                break;
4525
119
            case    CF_CALCOP("Sub(A,B)"):
4526
119
                opRunner = std::make_unique<OpenSSL_bignum::Sub>();
4527
119
                break;
4528
62
            case    CF_CALCOP("Mul(A,B)"):
4529
62
                opRunner = std::make_unique<OpenSSL_bignum::Mul>();
4530
62
                break;
4531
88
            case    CF_CALCOP("Mod(A,B)"):
4532
88
                opRunner = std::make_unique<OpenSSL_bignum::Mod>();
4533
88
                break;
4534
1.52k
            case    CF_CALCOP("ExpMod(A,B,C)"):
4535
1.52k
                opRunner = std::make_unique<OpenSSL_bignum::ExpMod>();
4536
1.52k
                break;
4537
19
            case    CF_CALCOP("Sqr(A)"):
4538
19
                opRunner = std::make_unique<OpenSSL_bignum::Sqr>();
4539
19
                break;
4540
362
            case    CF_CALCOP("GCD(A,B)"):
4541
362
                opRunner = std::make_unique<OpenSSL_bignum::GCD>();
4542
362
                break;
4543
51
            case    CF_CALCOP("AddMod(A,B,C)"):
4544
51
                opRunner = std::make_unique<OpenSSL_bignum::AddMod>();
4545
51
                break;
4546
83
            case    CF_CALCOP("SubMod(A,B,C)"):
4547
83
                opRunner = std::make_unique<OpenSSL_bignum::SubMod>();
4548
83
                break;
4549
59
            case    CF_CALCOP("MulMod(A,B,C)"):
4550
59
                opRunner = std::make_unique<OpenSSL_bignum::MulMod>();
4551
59
                break;
4552
26
            case    CF_CALCOP("SqrMod(A,B)"):
4553
26
                opRunner = std::make_unique<OpenSSL_bignum::SqrMod>();
4554
26
                break;
4555
956
            case    CF_CALCOP("InvMod(A,B)"):
4556
956
                opRunner = std::make_unique<OpenSSL_bignum::InvMod>();
4557
956
                break;
4558
84
            case    CF_CALCOP("Cmp(A,B)"):
4559
84
                opRunner = std::make_unique<OpenSSL_bignum::Cmp>();
4560
84
                break;
4561
175
            case    CF_CALCOP("Div(A,B)"):
4562
175
                opRunner = std::make_unique<OpenSSL_bignum::Div>();
4563
175
                break;
4564
553
            case    CF_CALCOP("IsPrime(A)"):
4565
553
                opRunner = std::make_unique<OpenSSL_bignum::IsPrime>();
4566
553
                break;
4567
194
            case    CF_CALCOP("Sqrt(A)"):
4568
194
                if ( prime_modulus == false ) {
4569
143
                    opRunner = std::make_unique<OpenSSL_bignum::Sqrt>();
4570
143
                } else {
4571
51
                    opRunner = std::make_unique<OpenSSL_bignum::SqrtMod>();
4572
51
                }
4573
194
                break;
4574
18
            case    CF_CALCOP("IsNeg(A)"):
4575
18
                opRunner = std::make_unique<OpenSSL_bignum::IsNeg>();
4576
18
                break;
4577
11
            case    CF_CALCOP("IsEq(A,B)"):
4578
11
                opRunner = std::make_unique<OpenSSL_bignum::IsEq>();
4579
11
                break;
4580
13
            case    CF_CALCOP("IsEven(A)"):
4581
13
                opRunner = std::make_unique<OpenSSL_bignum::IsEven>();
4582
13
                break;
4583
3
            case    CF_CALCOP("IsOdd(A)"):
4584
3
                opRunner = std::make_unique<OpenSSL_bignum::IsOdd>();
4585
3
                break;
4586
11
            case    CF_CALCOP("IsZero(A)"):
4587
11
                opRunner = std::make_unique<OpenSSL_bignum::IsZero>();
4588
11
                break;
4589
11
            case    CF_CALCOP("IsOne(A)"):
4590
11
                opRunner = std::make_unique<OpenSSL_bignum::IsOne>();
4591
11
                break;
4592
861
            case    CF_CALCOP("Jacobi(A,B)"):
4593
861
                opRunner = std::make_unique<OpenSSL_bignum::Jacobi>();
4594
861
                break;
4595
#if !defined(CRYPTOFUZZ_BORINGSSL) && !defined(CRYPTOFUZZ_OPENSSL_098) && !defined(CRYPTOFUZZ_LIBRESSL)
4596
            case    CF_CALCOP("Mod_NIST_192(A)"):
4597
                opRunner = std::make_unique<OpenSSL_bignum::Mod_NIST_192>();
4598
                break;
4599
            case    CF_CALCOP("Mod_NIST_224(A)"):
4600
                opRunner = std::make_unique<OpenSSL_bignum::Mod_NIST_224>();
4601
                break;
4602
            case    CF_CALCOP("Mod_NIST_256(A)"):
4603
                opRunner = std::make_unique<OpenSSL_bignum::Mod_NIST_256>();
4604
                break;
4605
            case    CF_CALCOP("Mod_NIST_384(A)"):
4606
                opRunner = std::make_unique<OpenSSL_bignum::Mod_NIST_384>();
4607
                break;
4608
            case    CF_CALCOP("Mod_NIST_521(A)"):
4609
                opRunner = std::make_unique<OpenSSL_bignum::Mod_NIST_521>();
4610
                break;
4611
#endif
4612
#if defined(CRYPTOFUZZ_BORINGSSL)
4613
            case    CF_CALCOP("LCM(A,B)"):
4614
                opRunner = std::make_unique<OpenSSL_bignum::LCM>();
4615
                break;
4616
#endif
4617
95
            case    CF_CALCOP("Exp(A,B)"):
4618
95
                opRunner = std::make_unique<OpenSSL_bignum::Exp>();
4619
95
                break;
4620
47
            case    CF_CALCOP("Abs(A)"):
4621
47
                opRunner = std::make_unique<OpenSSL_bignum::Abs>();
4622
47
                break;
4623
28
            case    CF_CALCOP("RShift(A,B)"):
4624
28
                opRunner = std::make_unique<OpenSSL_bignum::RShift>();
4625
28
                break;
4626
25
            case    CF_CALCOP("LShift1(A)"):
4627
25
                opRunner = std::make_unique<OpenSSL_bignum::LShift1>();
4628
25
                break;
4629
22
            case    CF_CALCOP("SetBit(A,B)"):
4630
22
                opRunner = std::make_unique<OpenSSL_bignum::SetBit>();
4631
22
                break;
4632
23
            case    CF_CALCOP("ClearBit(A,B)"):
4633
23
                opRunner = std::make_unique<OpenSSL_bignum::ClearBit>();
4634
23
                break;
4635
18
            case    CF_CALCOP("Bit(A,B)"):
4636
18
                opRunner = std::make_unique<OpenSSL_bignum::Bit>();
4637
18
                break;
4638
27
            case    CF_CALCOP("CmpAbs(A,B)"):
4639
27
                opRunner = std::make_unique<OpenSSL_bignum::CmpAbs>();
4640
27
                break;
4641
97
            case    CF_CALCOP("ModLShift(A,B,C)"):
4642
97
                opRunner = std::make_unique<OpenSSL_bignum::ModLShift>();
4643
97
                break;
4644
12
            case    CF_CALCOP("IsPow2(A)"):
4645
12
                opRunner = std::make_unique<OpenSSL_bignum::IsPow2>();
4646
12
                break;
4647
12
            case    CF_CALCOP("Mask(A,B)"):
4648
12
                opRunner = std::make_unique<OpenSSL_bignum::Mask>();
4649
12
                break;
4650
1
            case    CF_CALCOP("IsCoprime(A,B)"):
4651
1
                opRunner = std::make_unique<OpenSSL_bignum::IsCoprime>();
4652
1
                break;
4653
122
            case    CF_CALCOP("Rand()"):
4654
122
                opRunner = std::make_unique<OpenSSL_bignum::Rand>();
4655
122
                break;
4656
52
            case    CF_CALCOP("IsSquare(A)"):
4657
52
                opRunner = std::make_unique<OpenSSL_bignum::IsSquare>();
4658
52
                break;
4659
14
            case    CF_CALCOP("Neg(A)"):
4660
14
                opRunner = std::make_unique<OpenSSL_bignum::Neg>();
4661
14
                break;
4662
29
            case    CF_CALCOP("RandRange(A,B)"):
4663
29
                opRunner = std::make_unique<OpenSSL_bignum::RandRange>();
4664
29
                break;
4665
9.81k
        }
4666
4667
9.81k
        CF_CHECK_NE(opRunner, nullptr);
4668
6.01k
        CF_CHECK_EQ(opRunner->Run(ds, res, bn, ctx), true);
4669
4670
4.46k
        ret = res.ToComponentBignum();
4671
4.46k
    } catch ( ... ) { }
4672
4673
9.81k
end:
4674
9.81k
    global_ds = nullptr;
4675
4676
9.81k
    return ret;
4677
9.81k
}
4678
4679
371
bool OpenSSL::SupportsModularBignumCalc(void) const {
4680
371
    return true;
4681
371
}
4682
4683
#endif
4684
4685
} /* namespace module */
4686
} /* namespace cryptofuzz */