Coverage Report

Created: 2026-10-28 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl/fuzz/slh-dsa.c
Line
Count
Source
1
/*
2
 * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved.
3
 *
4
 * Licensed under the Apache License 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 * https://www.openssl.org/source/license.html
8
 * or in the file LICENSE in the source distribution.
9
 */
10
11
/*
12
 * Test slh-dsa operation.
13
 */
14
#include <string.h>
15
#include <stdio.h>
16
#include <openssl/evp.h>
17
#include <openssl/err.h>
18
#include <openssl/rand.h>
19
#include <openssl/byteorder.h>
20
#include <openssl/core_names.h>
21
#include "crypto/slh_dsa.h"
22
#include "internal/nelem.h"
23
#include "fuzzer.h"
24
25
/**
26
 * @brief Consumes an 8-bit unsigned integer from a buffer.
27
 *
28
 * This function extracts an 8-bit unsigned integer from the provided buffer,
29
 * updates the buffer pointer, and adjusts the remaining length.
30
 *
31
 * @param buf  Pointer to the input buffer.
32
 * @param len  Pointer to the size of the remaining buffer; updated after consumption.
33
 * @param val  Pointer to store the extracted 8-bit value.
34
 *
35
 * @return Pointer to the updated buffer position after reading the value,
36
 *         or NULL if the buffer does not contain enough data.
37
 */
38
static uint8_t *consume_uint8t(const uint8_t *buf, size_t *len, uint8_t *val)
39
4.98k
{
40
4.98k
    if (*len < sizeof(uint8_t))
41
0
        return NULL;
42
4.98k
    *val = *buf;
43
4.98k
    *len -= sizeof(uint8_t);
44
4.98k
    return (uint8_t *)buf + 1;
45
4.98k
}
46
47
/**
48
 * @brief Generates a DSA key pair using OpenSSL EVP API.
49
 *
50
 * This function creates a DSA key pair based on the specified key size and
51
 * parameters. It supports generating keys using explicit parameters if provided.
52
 *
53
 * @param name The name of the key type (e.g., "DSA").
54
 * @param keysize The desired key size in bits.
55
 * @param params Optional OpenSSL parameters for key generation.
56
 * @param param_broken A flag indicating if the parameters are broken.
57
 *                     If true, key generation will fail.
58
 *
59
 * @return A pointer to the generated EVP_PKEY structure on success,
60
 *         or NULL on failure.
61
 */
62
static EVP_PKEY *slh_dsa_gen_key(const char *name, uint32_t keysize,
63
    OSSL_PARAM params[], uint8_t *param_broken)
64
475
{
65
475
    EVP_PKEY_CTX *ctx;
66
475
    EVP_PKEY *new = NULL;
67
68
475
    ctx = EVP_PKEY_CTX_new_from_name(NULL, name, NULL);
69
475
    if (ctx == NULL)
70
0
        return NULL;
71
475
    if (params != NULL) {
72
81
        new = EVP_PKEY_new();
73
81
        if (new == NULL)
74
0
            goto out;
75
81
        if (!EVP_PKEY_fromdata_init(ctx)) {
76
0
            EVP_PKEY_free(new);
77
0
            new = NULL;
78
0
            goto out;
79
0
        }
80
81
        if (EVP_PKEY_fromdata(ctx, &new, EVP_PKEY_KEYPAIR, params) != 1) {
81
67
            EVP_PKEY_free(new);
82
67
            new = NULL;
83
67
        }
84
81
        goto out;
85
81
    }
86
87
394
    if (!EVP_PKEY_keygen_init(ctx))
88
0
        goto out;
89
394
    if (!EVP_PKEY_generate(ctx, &new)) {
90
0
        EVP_PKEY_free(new);
91
0
        new = NULL;
92
0
    }
93
94
475
out:
95
475
    EVP_PKEY_CTX_free(ctx);
96
475
    return new;
97
394
}
98
99
/**
100
 * @brief Selects a key type and determines the key size.
101
 *
102
 * This function maps a selector value to a specific SLH-DSA algorithm
103
 * using a modulo operation. It then retrieves the corresponding
104
 * algorithm name and assigns an appropriate key size based on the
105
 * selected algorithm.
106
 *
107
 * @param selector A random selector value used to determine the key type.
108
 * @param keysize Pointer to a variable where the determined key size
109
 *                (in bytes) will be stored.
110
 *
111
 * @return A pointer to a string containing the long name of the
112
 *         selected key type, or NULL if invalid.
113
 */
114
static const char *select_keytype(uint8_t selector, uint32_t *keysize)
115
2.13k
{
116
2.13k
    unsigned int choice;
117
2.13k
    const char *name = NULL;
118
119
2.13k
    *keysize = 0;
120
    /*
121
     * There are 12 SLH-DSA algs with registered NIDS at the moment
122
     * So use our random selector value to get one of them by computing
123
     * its modulo 12 value and adding the offset of the first NID, 1460
124
     * Then convert that to a long name
125
     */
126
2.13k
    choice = (selector % 12) + 1460;
127
128
2.13k
    name = OBJ_nid2ln(choice);
129
130
    /*
131
     * Select a keysize, values taken from
132
     * man7/EVP_PKEY-SLH-DSA.pod
133
     */
134
2.13k
    switch (choice) {
135
321
    case NID_SLH_DSA_SHA2_128s:
136
598
    case NID_SLH_DSA_SHA2_128f:
137
699
    case NID_SLH_DSA_SHAKE_128s:
138
761
    case NID_SLH_DSA_SHAKE_128f:
139
761
        *keysize = 16;
140
761
        break;
141
109
    case NID_SLH_DSA_SHA2_192s:
142
494
    case NID_SLH_DSA_SHA2_192f:
143
640
    case NID_SLH_DSA_SHAKE_192s:
144
826
    case NID_SLH_DSA_SHAKE_192f:
145
826
        *keysize = 24;
146
826
        break;
147
133
    case NID_SLH_DSA_SHA2_256s:
148
292
    case NID_SLH_DSA_SHA2_256f:
149
443
    case NID_SLH_DSA_SHAKE_256s:
150
552
    case NID_SLH_DSA_SHAKE_256f:
151
552
        *keysize = 32;
152
552
        break;
153
0
    default:
154
0
        fprintf(stderr, "Selecting invalid key size\n");
155
0
        *keysize = 0;
156
0
        break;
157
2.13k
    }
158
2.13k
    return name;
159
2.13k
}
160
161
/**
162
 * @brief Generates two SLH-DSA key pairs based on consumed selector values.
163
 *
164
 * This function extracts two selector values from the provided buffer,
165
 * determines the corresponding key types and sizes, and generates two
166
 * SLH-DSA key pairs.
167
 *
168
 * @param buf Pointer to a buffer containing selector values. The buffer
169
 *            pointer is updated as values are consumed.
170
 * @param len Pointer to the remaining buffer length, updated as values
171
 *            are consumed.
172
 * @param out1 Pointer to store the first generated key.
173
 * @param out2 Pointer to store the second generated key.
174
 */
175
static void slh_dsa_gen_keys(uint8_t **buf, size_t *len,
176
    void **out1, void **out2)
177
418
{
178
418
    uint8_t selector = 0;
179
418
    const char *keytype = NULL;
180
418
    uint32_t keysize;
181
182
418
    *buf = consume_uint8t(*buf, len, &selector);
183
418
    keytype = select_keytype(selector, &keysize);
184
418
    *out1 = (void *)slh_dsa_gen_key(keytype, keysize, NULL, 0);
185
186
418
    *buf = consume_uint8t(*buf, len, &selector);
187
418
    keytype = select_keytype(selector, &keysize);
188
418
    *out2 = (void *)slh_dsa_gen_key(keytype, keysize, NULL, 0);
189
418
    return;
190
418
}
191
192
243
#define PARAM_BUF_SZ 256
193
194
/**
195
 * @brief Generates an SLH-DSA key pair with custom parameters.
196
 *
197
 * This function extracts a selector value from the provided buffer,
198
 * determines the corresponding key type and size, and generates an
199
 * SLH-DSA key pair using randomly generated public and private key
200
 * buffers. It also introduces intentional modifications to test
201
 * invalid parameter handling.
202
 *
203
 * @param buf Pointer to a buffer containing the selector value. The
204
 *            buffer pointer is updated as values are consumed.
205
 * @param len Pointer to the remaining buffer length, updated as values
206
 *            are consumed.
207
 * @param out1 Pointer to store the generated key. Will be NULL if key
208
 *             generation fails due to invalid parameters.
209
 * @param out2 Unused output parameter (placeholder for symmetry with
210
 *             other key generation functions).
211
 */
212
static void slh_dsa_gen_key_with_params(uint8_t **buf, size_t *len,
213
    void **out1, void **out2)
214
81
{
215
81
    uint8_t selector = 0;
216
81
    const char *keytype = NULL;
217
81
    uint32_t keysize;
218
81
    uint8_t pubbuf[PARAM_BUF_SZ]; /* expressly bigger than max key size * 3 */
219
81
    uint8_t prvbuf[PARAM_BUF_SZ]; /* expressly bigger than max key size * 3 */
220
81
    uint8_t sdbuf[PARAM_BUF_SZ]; /* expressly bigger than max key size * 3 */
221
81
    uint8_t *bufptr;
222
81
    OSSL_PARAM params[3];
223
81
    size_t buflen;
224
81
    uint8_t broken = 0;
225
226
81
    *out1 = NULL;
227
228
81
    *buf = consume_uint8t(*buf, len, &selector);
229
81
    keytype = select_keytype(selector, &keysize);
230
231
81
    if (!RAND_bytes(pubbuf, PARAM_BUF_SZ)
232
81
        || !RAND_bytes(prvbuf, PARAM_BUF_SZ)
233
81
        || !RAND_bytes(sdbuf, PARAM_BUF_SZ))
234
0
        return;
235
236
    /*
237
     * select an invalid length if the buffer 0th bit is one
238
     * make it too big if the 2nd bit is 0, smaller otherwise
239
     */
240
81
    buflen = keysize * 2; /* these params are 2 * the keysize */
241
81
    if ((*buf)[0] & 0x1) {
242
44
        buflen = ((*buf)[0] & 0x2) ? buflen - 1 : buflen + 1;
243
44
        broken = 1;
244
44
    }
245
246
    /* pass a null buffer if the third bit of the buffer is 1 */
247
81
    bufptr = ((*buf)[0] & 0x4) ? NULL : pubbuf;
248
81
    if (!broken)
249
37
        broken = (bufptr == NULL) ? 1 : 0;
250
251
81
    params[0] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PUB_KEY,
252
81
        (char *)bufptr, buflen);
253
254
81
    buflen = keysize * 2;
255
    /* select an invalid length if the 4th bit is true  */
256
81
    if ((*buf)[0] & 0x8) {
257
24
        buflen = (*buf[0] & 0x1) ? buflen - 1 : buflen + 1;
258
24
        broken = 1;
259
24
    }
260
261
    /* pass a null buffer if the 5th bit is true */
262
81
    bufptr = ((*buf)[0] & 0x10) ? NULL : prvbuf;
263
81
    if (!broken)
264
21
        broken = (bufptr == NULL) ? 1 : 0;
265
81
    params[1] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PRIV_KEY,
266
81
        (char *)bufptr, buflen);
267
268
81
    params[2] = OSSL_PARAM_construct_end();
269
270
81
    *out1 = (void *)slh_dsa_gen_key(keytype, keysize, params, &broken);
271
81
    return;
272
81
}
273
274
/**
275
 * @brief Frees allocated SLH-DSA key structures.
276
 *
277
 * This function releases memory allocated for SLH-DSA key pairs
278
 * by freeing the provided EVP_PKEY structures.
279
 *
280
 * @param in1 Pointer to the first input key to be freed.
281
 * @param in2 Pointer to the second input key to be freed.
282
 * @param out1 Pointer to the first output key to be freed.
283
 * @param out2 Pointer to the second output key to be freed.
284
 */
285
static void slh_dsa_clean_keys(void *in1, void *in2, void *out1, void *out2)
286
1.72k
{
287
1.72k
    EVP_PKEY_free((EVP_PKEY *)in1);
288
1.72k
    EVP_PKEY_free((EVP_PKEY *)in2);
289
1.72k
    EVP_PKEY_free((EVP_PKEY *)out1);
290
1.72k
    EVP_PKEY_free((EVP_PKEY *)out2);
291
1.72k
}
292
293
/**
294
 * @brief Performs SLH-DSA signing and verification on a given message.
295
 *
296
 * This function generates an SLH-DSA key, signs a message, and verifies
297
 * the generated signature. It extracts necessary parameters from the buffer
298
 * to determine signing options.
299
 *
300
 * @param buf Pointer to a buffer containing the selector and message data.
301
 *            The buffer pointer is updated as values are consumed.
302
 * @param len Pointer to the remaining buffer length, updated as values
303
 *            are consumed.
304
 * @param key1 Unused key parameter (placeholder for function signature consistency).
305
 * @param key2 Unused key parameter (placeholder for function signature consistency).
306
 * @param out1 Pointer to store the generated key (for cleanup purposes).
307
 * @param out2 Unused output parameter (placeholder for consistency).
308
 */
309
static void slh_dsa_sign_verify(uint8_t **buf, size_t *len, void *key1,
310
    void *key2, void **out1, void **out2)
311
{
312
    EVP_PKEY_CTX *ctx = NULL;
313
    EVP_PKEY *key = NULL;
314
    EVP_SIGNATURE *sig_alg = NULL;
315
    const char *keytype;
316
    uint32_t keylen;
317
    uint8_t selector = 0;
318
    unsigned char *msg = NULL;
319
    size_t msg_len;
320
    size_t sig_len;
321
    unsigned char *sig = NULL;
322
    OSSL_PARAM params[4];
323
    int paramidx = 0;
324
    int intval1, intval2;
325
326
    *buf = consume_uint8t(*buf, len, &selector);
327
    if (*buf == NULL)
328
        return;
329
330
    keytype = select_keytype(selector, &keylen);
331
332
    /*
333
     * Consume another byte to figure out our params
334
     */
335
    *buf = consume_uint8t(*buf, len, &selector);
336
    if (*buf == NULL)
337
        return;
338
339
    /*
340
     * Remainder of the buffer is the msg to sign
341
     */
342
    msg = (unsigned char *)*buf;
343
    msg_len = *len;
344
345
    *len = 0;
346
347
    if (selector & 0x1)
348
        params[paramidx++] = OSSL_PARAM_construct_octet_string(OSSL_SIGNATURE_PARAM_CONTEXT_STRING,
349
            msg, msg_len);
350
351
    if (selector & 0x2) {
352
        intval1 = selector & 0x4;
353
        params[paramidx++] = OSSL_PARAM_construct_int(OSSL_SIGNATURE_PARAM_MESSAGE_ENCODING,
354
            &intval1);
355
    }
356
357
    if (selector & 0x8) {
358
        intval2 = selector & 0x10;
359
        params[paramidx++] = OSSL_PARAM_construct_int(OSSL_SIGNATURE_PARAM_DETERMINISTIC,
360
            &intval2);
361
    }
362
363
    params[paramidx] = OSSL_PARAM_construct_end();
364
365
    key = (void *)slh_dsa_gen_key(keytype, keylen, NULL, 0);
366
    if (key == NULL)
367
        return;
368
    *out1 = key; /* for cleanup */
369
370
    ctx = EVP_PKEY_CTX_new_from_pkey(NULL, key, NULL);
371
    if (ctx == NULL)
372
        goto out;
373
374
    sig_alg = EVP_SIGNATURE_fetch(NULL, keytype, NULL);
375
    if (sig_alg == NULL)
376
        goto out;
377
378
    /*
379
     * the context_string parameter can be no more than 255 bytes, so if
380
     * our random input buffer is greater than that, sign_message_init will
381
     * fail, in which case there's nothing more we can do here so bail out
382
     */
383
    if (EVP_PKEY_sign_message_init(ctx, sig_alg, params) != 1)
384
        goto out;
385
386
    if (EVP_PKEY_sign(ctx, NULL, &sig_len, msg, msg_len) != 1)
387
        goto out;
388
    sig = OPENSSL_zalloc(sig_len);
389
    if (sig == NULL)
390
        goto out;
391
392
    if (EVP_PKEY_sign(ctx, sig, &sig_len, msg, msg_len) != 1)
393
        goto out;
394
395
    if (EVP_PKEY_verify_message_init(ctx, sig_alg, params) != 1)
396
        goto out;
397
    if (EVP_PKEY_verify(ctx, sig, sig_len, msg, msg_len) != 1)
398
        fprintf(stderr, "Failed to verify message\n");
399
400
out:
401
    OPENSSL_free(sig);
402
    EVP_SIGNATURE_free(sig_alg);
403
    EVP_PKEY_CTX_free(ctx);
404
}
405
406
/**
407
 * @brief Exports and imports SLH-DSA key pairs, verifying equivalence.
408
 *
409
 * This function extracts key data from two given SLH-DSA keys (`alice` and `bob`),
410
 * reconstructs new keys from the extracted data, and verifies that the imported
411
 * keys are equivalent to the originals. It ensures that key export/import
412
 * functionality is working correctly.
413
 *
414
 * @param buf Unused buffer parameter (placeholder for function signature consistency).
415
 * @param len Unused length parameter (placeholder for function signature consistency).
416
 * @param key1 Pointer to the first key (`alice`) to be exported and imported.
417
 * @param key2 Pointer to the second key (`bob`) to be exported and imported.
418
 * @param out1 Unused output parameter (placeholder for consistency).
419
 * @param out2 Unused output parameter (placeholder for consistency).
420
 */
421
static void slh_dsa_export_import(uint8_t **buf, size_t *len, void *key1,
422
    void *key2, void **out1, void **out2)
423
119
{
424
119
    EVP_PKEY *alice = (EVP_PKEY *)key1;
425
119
    EVP_PKEY *bob = (EVP_PKEY *)key2;
426
119
    EVP_PKEY *new = NULL;
427
119
    EVP_PKEY_CTX *ctx = NULL;
428
119
    OSSL_PARAM *params = NULL;
429
430
119
    if (alice == NULL || bob == NULL)
431
0
        return;
432
433
119
    if (!EVP_PKEY_todata(alice, EVP_PKEY_KEYPAIR, &params))
434
0
        goto alice_done;
435
436
119
    ctx = EVP_PKEY_CTX_new_from_pkey(NULL, alice, NULL);
437
119
    if (ctx == NULL)
438
0
        goto alice_done;
439
440
119
    if (!EVP_PKEY_fromdata_init(ctx))
441
0
        goto alice_done;
442
443
119
    new = EVP_PKEY_new();
444
119
    if (new == NULL)
445
0
        goto alice_done;
446
119
    if (EVP_PKEY_fromdata(ctx, &new, EVP_PKEY_KEYPAIR, params) != 1)
447
0
        goto alice_done;
448
449
119
    (void)EVP_PKEY_eq(alice, new);
450
451
119
alice_done:
452
119
    EVP_PKEY_free(new);
453
119
    EVP_PKEY_CTX_free(ctx);
454
119
    OSSL_PARAM_free(params);
455
119
    params = NULL;
456
119
    ctx = NULL;
457
119
    new = NULL;
458
459
119
    if (!EVP_PKEY_todata(bob, EVP_PKEY_KEYPAIR, &params))
460
0
        goto bob_done;
461
462
119
    ctx = EVP_PKEY_CTX_new_from_pkey(NULL, bob, NULL);
463
119
    if (ctx == NULL)
464
0
        goto bob_done;
465
466
119
    if (!EVP_PKEY_fromdata_init(ctx))
467
0
        goto bob_done;
468
469
119
    new = EVP_PKEY_new();
470
119
    if (new == NULL)
471
0
        goto bob_done;
472
119
    if (EVP_PKEY_fromdata(ctx, &new, EVP_PKEY_KEYPAIR, params) != 1)
473
0
        goto bob_done;
474
475
119
    (void)EVP_PKEY_eq(bob, new);
476
119
    (void)EVP_PKEY_eq(alice, new);
477
478
119
bob_done:
479
119
    EVP_PKEY_CTX_free(ctx);
480
119
    EVP_PKEY_free(new);
481
119
    OSSL_PARAM_free(params);
482
119
}
483
484
/**
485
 * @brief Represents an operation table entry for cryptographic operations.
486
 *
487
 * This structure defines a table entry containing function pointers for
488
 * setting up, executing, and cleaning up cryptographic operations, along
489
 * with associated metadata such as a name and description.
490
 *
491
 * @struct op_table_entry
492
 */
493
struct op_table_entry {
494
    /** Name of the operation. */
495
    char *name;
496
497
    /**
498
     * @brief Function pointer for setting up the operation.
499
     *
500
     * @param buf   Pointer to the buffer pointer; may be updated.
501
     * @param len   Pointer to the remaining buffer size; may be updated.
502
     * @param out1  Pointer to store the first output of the setup function.
503
     * @param out2  Pointer to store the second output of the setup function.
504
     */
505
    void (*setup)(uint8_t **buf, size_t *len, void **out1, void **out2);
506
507
    /**
508
     * @brief Function pointer for executing the operation.
509
     *
510
     * @param buf   Pointer to the buffer pointer; may be updated.
511
     * @param len   Pointer to the remaining buffer size; may be updated.
512
     * @param in1   First input parameter for the operation.
513
     * @param in2   Second input parameter for the operation.
514
     * @param out1  Pointer to store the first output of the operation.
515
     * @param out2  Pointer to store the second output of the operation.
516
     */
517
    void (*doit)(uint8_t **buf, size_t *len, void *in1, void *in2,
518
        void **out1, void **out2);
519
520
    /**
521
     * @brief Function pointer for cleaning up after the operation.
522
     *
523
     * @param in1   First input parameter to be cleaned up.
524
     * @param in2   Second input parameter to be cleaned up.
525
     * @param out1  First output parameter to be cleaned up.
526
     * @param out2  Second output parameter to be cleaned up.
527
     */
528
    void (*cleanup)(void *in1, void *in2, void *out1, void *out2);
529
};
530
531
static struct op_table_entry ops[] = {
532
    { "Generate SLH-DSA keys",
533
        slh_dsa_gen_keys,
534
        NULL,
535
        slh_dsa_clean_keys },
536
    { "Generate SLH-DSA keys with params",
537
        slh_dsa_gen_key_with_params,
538
        NULL,
539
        slh_dsa_clean_keys },
540
    { "SLH-DSA Export/Import",
541
        slh_dsa_gen_keys,
542
        slh_dsa_export_import,
543
        slh_dsa_clean_keys },
544
    { "SLH-DSA sign and verify",
545
        NULL,
546
        slh_dsa_sign_verify,
547
        slh_dsa_clean_keys }
548
};
549
550
int FuzzerInitialize(int *argc, char ***argv)
551
254
{
552
254
    return 0;
553
254
}
554
555
/**
556
 * @brief Processes a fuzzing input by selecting and executing an operation.
557
 *
558
 * This function interprets the first byte of the input buffer to determine
559
 * an operation to execute. It then follows a setup, execution, and cleanup
560
 * sequence based on the selected operation.
561
 *
562
 * @param buf Pointer to the input buffer.
563
 * @param len Length of the input buffer.
564
 *
565
 * @return 0 on successful execution, -1 if the input is too short.
566
 *
567
 * @note The function requires at least 32 bytes in the buffer to proceed.
568
 *       It utilizes the `ops` operation table to dynamically determine and
569
 *       execute the selected operation.
570
 */
571
int FuzzerTestOneInput(const uint8_t *buf, size_t len)
572
1.29k
{
573
1.29k
    uint8_t operation;
574
1.29k
    uint8_t *buffer_cursor;
575
1.29k
    void *in1 = NULL, *in2 = NULL;
576
1.29k
    void *out1 = NULL, *out2 = NULL;
577
578
1.29k
    if (len < 32)
579
48
        return -1;
580
    /*
581
     * Get the first byte of the buffer to tell us what operation
582
     * to perform
583
     */
584
1.25k
    buffer_cursor = consume_uint8t(buf, &len, &operation);
585
1.25k
    if (buffer_cursor == NULL)
586
0
        return -1;
587
588
    /*
589
     * Adjust for operational array size
590
     */
591
1.25k
    operation %= OSSL_NELEM(ops);
592
593
    /*
594
     * And run our setup/doit/cleanup sequence
595
     */
596
1.25k
    if (ops[operation].setup != NULL)
597
1.24k
        ops[operation].setup(&buffer_cursor, &len, &in1, &in2);
598
1.25k
    if (ops[operation].doit != NULL && in1 != NULL)
599
815
        ops[operation].doit(&buffer_cursor, &len, in1, in2, &out1, &out2);
600
1.25k
    if (ops[operation].cleanup != NULL)
601
1.25k
        ops[operation].cleanup(in1, in2, out1, out2);
602
603
1.25k
    return 0;
604
1.25k
}
605
606
void FuzzerCleanup(void)
607
0
{
608
0
    OPENSSL_cleanup();
609
0
}