Coverage Report

Created: 2022-08-24 06:31

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