Coverage Report

Created: 2024-11-21 07:03

/src/cryptofuzz/modules/libsodium/module.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "module.h"
2
#include <cryptofuzz/util.h>
3
#include <cryptofuzz/repository.h>
4
#include <sodium.h>
5
6
namespace cryptofuzz {
7
namespace module {
8
9
libsodium::libsodium(void) :
10
10
    Module("libsodium") {
11
10
    if ( sodium_init() == -1 ) {
12
0
        abort();
13
0
    }
14
10
}
15
16
103
std::optional<component::Digest> libsodium::SHA256(operation::Digest& op) const {
17
103
    std::optional<component::Digest> ret = std::nullopt;
18
19
103
    uint8_t out[crypto_hash_sha256_BYTES];
20
21
103
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
22
23
103
    bool doMulti = false;
24
103
    try {
25
103
        doMulti = ds.Get<bool>();
26
103
    } catch ( fuzzing::datasource::Datasource::OutOfData ) {
27
18
    }
28
29
103
    if ( doMulti == false ) {
30
60
        crypto_hash_sha256(out, op.cleartext.GetPtr(), op.cleartext.GetSize());
31
32
60
        ret = component::Digest(out, crypto_hash_sha256_BYTES);
33
60
    } else {
34
43
        crypto_hash_sha256_state state;
35
36
43
        util::Multipart parts;
37
38
        /* Initialize */
39
43
        {
40
43
            CF_CHECK_EQ(crypto_hash_sha256_init(&state), 0);
41
43
            parts = util::ToParts(ds, op.cleartext);
42
43
        }
43
44
        /* Process */
45
8.49k
        for (const auto& part : parts) {
46
8.49k
            CF_CHECK_EQ(crypto_hash_sha256_update(&state, part.first, part.second), 0);
47
8.49k
        }
48
49
        /* Finalize */
50
43
        {
51
43
            CF_CHECK_EQ(crypto_hash_sha256_final(&state, out), 0);
52
43
        }
53
54
43
        ret = component::Digest(out, crypto_hash_sha256_BYTES);
55
43
    }
56
57
103
end:
58
59
103
    return ret;
60
103
}
61
62
103
std::optional<component::Digest> libsodium::SHA512(operation::Digest& op) const {
63
103
    std::optional<component::Digest> ret = std::nullopt;
64
65
103
    uint8_t out[crypto_hash_sha512_BYTES];
66
67
103
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
68
69
103
    bool doMulti = false;
70
103
    try {
71
103
        doMulti = ds.Get<bool>();
72
103
    } catch ( fuzzing::datasource::Datasource::OutOfData ) {
73
26
    }
74
75
103
    if ( doMulti == false ) {
76
62
        crypto_hash_sha512(out, op.cleartext.GetPtr(), op.cleartext.GetSize());
77
78
62
        ret = component::Digest(out, crypto_hash_sha512_BYTES);
79
62
    } else {
80
41
        crypto_hash_sha512_state state;
81
82
41
        util::Multipart parts;
83
84
        /* Initialize */
85
41
        {
86
41
            CF_CHECK_EQ(crypto_hash_sha512_init(&state), 0);
87
41
            parts = util::ToParts(ds, op.cleartext);
88
41
        }
89
90
        /* Process */
91
11.0k
        for (const auto& part : parts) {
92
11.0k
            CF_CHECK_EQ(crypto_hash_sha512_update(&state, part.first, part.second), 0);
93
11.0k
        }
94
95
        /* Finalize */
96
41
        {
97
41
            CF_CHECK_EQ(crypto_hash_sha512_final(&state, out), 0);
98
41
        }
99
100
41
        ret = component::Digest(out, crypto_hash_sha512_BYTES);
101
41
    }
102
103
103
end:
104
105
103
    return ret;
106
103
}
107
108
3.42k
std::optional<component::Digest> libsodium::OpDigest(operation::Digest& op) {
109
3.42k
    switch ( op.digestType.Get() ) {
110
103
        case CF_DIGEST("SHA256"):
111
103
            return SHA256(op);
112
103
        case CF_DIGEST("SHA512"):
113
103
            return SHA512(op);
114
3.21k
        default:
115
3.21k
            return std::nullopt;
116
3.42k
    }
117
3.42k
}
118
119
87
std::optional<component::MAC> libsodium::HMAC_SHA256(operation::HMAC& op) const {
120
87
    std::optional<component::MAC> ret = std::nullopt;
121
122
87
    uint8_t out[crypto_auth_hmacsha256_BYTES];
123
124
87
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
125
126
87
    bool doMulti = false;
127
87
    try {
128
87
        doMulti = ds.Get<bool>();
129
87
    } catch ( fuzzing::datasource::Datasource::OutOfData ) {
130
28
    }
131
132
87
    if ( doMulti == false ) {
133
53
        CF_CHECK_EQ(op.cipher.key.GetSize(), crypto_auth_hmacsha256_KEYBYTES);
134
3
        CF_CHECK_EQ(crypto_auth_hmacsha256(out, op.cleartext.GetPtr(), op.cleartext.GetSize(), op.cipher.key.GetPtr()), 0);
135
136
3
        ret = component::MAC(out, crypto_auth_hmacsha256_BYTES);
137
34
    } else {
138
34
        crypto_auth_hmacsha256_state state;
139
140
34
        util::Multipart parts;
141
142
        /* Initialize */
143
34
        {
144
34
            CF_CHECK_EQ(crypto_auth_hmacsha256_init(&state, op.cipher.key.GetPtr(), op.cipher.key.GetSize()), 0);
145
34
            parts = util::ToParts(ds, op.cleartext);
146
34
        }
147
148
        /* Process */
149
7.82k
        for (const auto& part : parts) {
150
7.82k
            CF_CHECK_EQ(crypto_auth_hmacsha256_update(&state, part.first, part.second), 0);
151
7.82k
        }
152
153
        /* Finalize */
154
34
        {
155
34
            CF_CHECK_EQ(crypto_auth_hmacsha256_final(&state, out), 0);
156
34
        }
157
158
34
        ret = component::MAC(out, crypto_auth_hmacsha256_BYTES);
159
34
    }
160
161
87
end:
162
163
87
    return ret;
164
87
}
165
166
105
std::optional<component::MAC> libsodium::HMAC_SHA512(operation::HMAC& op) const {
167
105
    std::optional<component::MAC> ret = std::nullopt;
168
169
105
    uint8_t out[crypto_auth_hmacsha512_BYTES];
170
171
105
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
172
173
105
    bool doMulti = false;
174
105
    try {
175
105
        doMulti = ds.Get<bool>();
176
105
    } catch ( fuzzing::datasource::Datasource::OutOfData ) {
177
23
    }
178
179
105
    if ( doMulti == false ) {
180
60
        CF_CHECK_EQ(op.cipher.key.GetSize(), crypto_auth_hmacsha512_KEYBYTES);
181
1
        CF_CHECK_EQ(crypto_auth_hmacsha512(out, op.cleartext.GetPtr(), op.cleartext.GetSize(), op.cipher.key.GetPtr()), 0);
182
183
1
        ret = component::MAC(out, crypto_auth_hmacsha512_BYTES);
184
45
    } else {
185
45
        crypto_auth_hmacsha512_state state;
186
187
45
        util::Multipart parts;
188
189
        /* Initialize */
190
45
        {
191
45
            CF_CHECK_EQ(crypto_auth_hmacsha512_init(&state, op.cipher.key.GetPtr(), op.cipher.key.GetSize()), 0);
192
45
            parts = util::ToParts(ds, op.cleartext);
193
45
        }
194
195
        /* Process */
196
9.16k
        for (const auto& part : parts) {
197
9.16k
            CF_CHECK_EQ(crypto_auth_hmacsha512_update(&state, part.first, part.second), 0);
198
9.16k
        }
199
200
        /* Finalize */
201
45
        {
202
45
            CF_CHECK_EQ(crypto_auth_hmacsha512_final(&state, out), 0);
203
45
        }
204
205
45
        ret = component::MAC(out, crypto_auth_hmacsha512_BYTES);
206
45
    }
207
208
105
end:
209
210
105
    return ret;
211
105
}
212
213
63
std::optional<component::MAC> libsodium::HMAC_SHA512256(operation::HMAC& op) const {
214
63
    std::optional<component::MAC> ret = std::nullopt;
215
216
63
    uint8_t out[crypto_auth_hmacsha512256_BYTES];
217
218
63
    Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
219
220
63
    bool doMulti = false;
221
63
    try {
222
63
        doMulti = ds.Get<bool>();
223
63
    } catch ( fuzzing::datasource::Datasource::OutOfData ) {
224
19
    }
225
226
63
    if ( doMulti == false ) {
227
38
        CF_CHECK_EQ(op.cipher.key.GetSize(), crypto_auth_hmacsha512256_KEYBYTES);
228
2
        CF_CHECK_EQ(crypto_auth_hmacsha512256(out, op.cleartext.GetPtr(), op.cleartext.GetSize(), op.cipher.key.GetPtr()), 0);
229
230
        //ret = component::MAC(out, crypto_auth_hmacsha512256_BYTES);
231
25
    } else {
232
25
        crypto_auth_hmacsha512256_state state;
233
234
25
        util::Multipart parts;
235
236
        /* Initialize */
237
25
        {
238
25
            CF_CHECK_EQ(crypto_auth_hmacsha512256_init(&state, op.cipher.key.GetPtr(), op.cipher.key.GetSize()), 0);
239
25
            parts = util::ToParts(ds, op.cleartext);
240
25
        }
241
242
        /* Process */
243
7.96k
        for (const auto& part : parts) {
244
7.96k
            CF_CHECK_EQ(crypto_auth_hmacsha512256_update(&state, part.first, part.second), 0);
245
7.96k
        }
246
247
        /* Finalize */
248
25
        {
249
25
            CF_CHECK_EQ(crypto_auth_hmacsha512256_final(&state, out), 0);
250
25
        }
251
252
        //ret = component::MAC(out, crypto_auth_hmacsha512256_BYTES);
253
25
    }
254
255
63
end:
256
257
63
    return ret;
258
63
}
259
260
19
std::optional<component::MAC> libsodium::SIPHASH64(operation::HMAC& op) const {
261
19
    std::optional<component::MAC> ret = std::nullopt;
262
19
    uint8_t out[crypto_shorthash_BYTES];
263
264
    /* Initialize */
265
19
    {
266
19
        CF_CHECK_EQ(op.cipher.key.GetSize(), crypto_shorthash_KEYBYTES);
267
5
    }
268
269
    /* Process */
270
0
    {
271
5
        CF_CHECK_EQ(crypto_shorthash(out, op.cleartext.GetPtr(), op.cleartext.GetSize(), op.cipher.key.GetPtr()), 0);
272
5
    }
273
274
    /* Finalize */
275
0
    {
276
5
        ret = component::MAC(out, crypto_shorthash_BYTES);
277
5
    }
278
279
19
end:
280
281
19
    return ret;
282
5
}
283
284
16
std::optional<component::MAC> libsodium::SIPHASH128(operation::HMAC& op) const {
285
16
    std::optional<component::MAC> ret = std::nullopt;
286
16
    uint8_t out[crypto_shorthash_siphashx24_BYTES];
287
288
    /* Initialize */
289
16
    {
290
16
        CF_CHECK_EQ(op.cipher.key.GetSize(), crypto_shorthash_siphashx24_KEYBYTES);
291
7
    }
292
293
    /* Process */
294
0
    {
295
7
        CF_CHECK_EQ(crypto_shorthash_siphashx24(out, op.cleartext.GetPtr(), op.cleartext.GetSize(), op.cipher.key.GetPtr()), 0);
296
7
    }
297
298
    /* Finalize */
299
0
    {
300
7
        ret = component::MAC(out, crypto_shorthash_siphashx24_BYTES);
301
7
    }
302
303
16
end:
304
305
16
    return ret;
306
7
}
307
308
2.22k
std::optional<component::MAC> libsodium::OpHMAC(operation::HMAC& op) {
309
2.22k
    switch ( op.digestType.Get() ) {
310
87
        case CF_DIGEST("SHA256"):
311
87
            return HMAC_SHA256(op);
312
105
        case CF_DIGEST("SHA512"):
313
105
            return HMAC_SHA512(op);
314
63
        case CF_DIGEST("SHA512-256"):
315
63
            return HMAC_SHA512256(op);
316
19
        case CF_DIGEST("SIPHASH64"):
317
19
            return SIPHASH64(op);
318
16
        case CF_DIGEST("SIPHASH128"):
319
16
            return SIPHASH128(op);
320
1.93k
        default:
321
1.93k
            return std::nullopt;
322
2.22k
    }
323
2.22k
}
324
325
1.10k
std::optional<component::Key> libsodium::OpKDF_HKDF(operation::KDF_HKDF& op) {
326
1.10k
    std::optional<component::Key> ret = std::nullopt;
327
328
1.10k
    uint8_t* prk = nullptr;
329
1.10k
    uint8_t* out = nullptr;
330
331
1.10k
    switch ( op.digestType.Get() ) {
332
28
        case CF_DIGEST("SHA256"):
333
28
            {
334
28
                prk = util::malloc(crypto_kdf_hkdf_sha256_KEYBYTES);
335
336
28
                CF_CHECK_EQ(crypto_kdf_hkdf_sha256_extract(
337
28
                            prk,
338
28
                            op.salt.GetPtr(),
339
28
                            op.salt.GetSize(),
340
28
                            op.password.GetPtr(),
341
28
                            op.password.GetSize()), 0);
342
343
28
                out = util::malloc(op.keySize);
344
345
28
                CF_CHECK_EQ(crypto_kdf_hkdf_sha256_expand(
346
28
                            out,
347
28
                            op.keySize,
348
28
                            (const char*)(op.info.GetPtr()),
349
28
                            op.info.GetSize(),
350
28
                            prk), 0);
351
24
                ret = component::Key(out, op.keySize);
352
24
            }
353
0
            break;
354
53
        case CF_DIGEST("SHA512"):
355
53
            {
356
53
                prk = util::malloc(crypto_kdf_hkdf_sha512_KEYBYTES);
357
358
53
                CF_CHECK_EQ(crypto_kdf_hkdf_sha512_extract(
359
53
                            prk,
360
53
                            op.salt.GetPtr(),
361
53
                            op.salt.GetSize(),
362
53
                            op.password.GetPtr(),
363
53
                            op.password.GetSize()), 0);
364
365
53
                out = util::malloc(op.keySize);
366
367
53
                CF_CHECK_EQ(crypto_kdf_hkdf_sha512_expand(
368
53
                            out,
369
53
                            op.keySize,
370
53
                            (const char*)(op.info.GetPtr()),
371
53
                            op.info.GetSize(),
372
53
                            prk), 0);
373
52
                ret = component::Key(out, op.keySize);
374
52
            }
375
0
            break;
376
1.02k
        default:
377
1.02k
            return std::nullopt;
378
1.10k
    }
379
380
81
end:
381
81
    util::free(prk);
382
81
    util::free(out);
383
384
81
    return ret;
385
1.10k
}
386
387
namespace libsodium_detail {
388
389
template <size_t TAGLEN, size_t IVLEN, size_t KEYLEN>
390
class AEAD {
391
    private:
392
        virtual int encrypt(unsigned char *c,
393
                unsigned long long *clen,
394
                const unsigned char *m,
395
                unsigned long long mlen,
396
                const unsigned char *ad,
397
                unsigned long long adlen,
398
                const unsigned char *nsec,
399
                const unsigned char *npub,
400
                const unsigned char *k) const = 0;
401
        virtual int decrypt(unsigned char *m,
402
                unsigned long long *mlen,
403
                unsigned char *nsec,
404
                const unsigned char *c,
405
                unsigned long long clen,
406
                const unsigned char *ad,
407
                unsigned long long adlen,
408
                const unsigned char *npub,
409
                const unsigned char *k) const = 0;
410
    public:
411
85
        std::optional<component::Ciphertext> Encrypt(const operation::SymmetricEncrypt& op) const {
412
85
            std::optional<component::Ciphertext> ret = std::nullopt;
413
414
85
            uint8_t* out = util::malloc(op.ciphertextSize);
415
416
            /* Operation must support tag output */
417
85
            CF_CHECK_NE(op.tagSize, std::nullopt);
418
52
            CF_CHECK_GTE(op.tagSize, TAGLEN);
419
420
            /* Output must be able to hold message + tag */
421
38
            CF_CHECK_GTE(op.ciphertextSize, op.cleartext.GetSize() + TAGLEN);
422
423
19
            CF_CHECK_EQ(op.cipher.iv.GetSize(), IVLEN);
424
7
            CF_CHECK_EQ(op.cipher.key.GetSize(), KEYLEN);
425
426
6
            unsigned long long ciphertext_len;
427
428
6
            CF_CHECK_EQ(encrypt(
429
6
                        out,
430
6
                        &ciphertext_len,
431
6
                        op.cleartext.GetPtr(),
432
6
                        op.cleartext.GetSize(),
433
6
                        op.aad == std::nullopt ? (const uint8_t*)0x12 : op.aad->GetPtr(),
434
6
                        op.aad == std::nullopt ? 0: op.aad->GetSize(),
435
6
                        nullptr,
436
6
                        op.cipher.iv.GetPtr(),
437
6
                        op.cipher.key.GetPtr()), 0);
438
439
6
            if ( ciphertext_len > op.cleartext.GetSize() + TAGLEN ) {
440
0
                abort();
441
0
            }
442
6
            if ( ciphertext_len < TAGLEN ) {
443
0
                abort();
444
0
            }
445
446
6
            ret = component::Ciphertext(
447
6
                    Buffer(out, ciphertext_len - TAGLEN),
448
6
                    Buffer(out + ciphertext_len - TAGLEN, TAGLEN));
449
85
end:
450
85
            util::free(out);
451
85
            return ret;
452
6
        }
cryptofuzz::module::libsodium_detail::AEAD<16ul, 12ul, 32ul>::Encrypt(cryptofuzz::operation::SymmetricEncrypt const&) const
Line
Count
Source
411
54
        std::optional<component::Ciphertext> Encrypt(const operation::SymmetricEncrypt& op) const {
412
54
            std::optional<component::Ciphertext> ret = std::nullopt;
413
414
54
            uint8_t* out = util::malloc(op.ciphertextSize);
415
416
            /* Operation must support tag output */
417
54
            CF_CHECK_NE(op.tagSize, std::nullopt);
418
36
            CF_CHECK_GTE(op.tagSize, TAGLEN);
419
420
            /* Output must be able to hold message + tag */
421
25
            CF_CHECK_GTE(op.ciphertextSize, op.cleartext.GetSize() + TAGLEN);
422
423
18
            CF_CHECK_EQ(op.cipher.iv.GetSize(), IVLEN);
424
7
            CF_CHECK_EQ(op.cipher.key.GetSize(), KEYLEN);
425
426
6
            unsigned long long ciphertext_len;
427
428
6
            CF_CHECK_EQ(encrypt(
429
6
                        out,
430
6
                        &ciphertext_len,
431
6
                        op.cleartext.GetPtr(),
432
6
                        op.cleartext.GetSize(),
433
6
                        op.aad == std::nullopt ? (const uint8_t*)0x12 : op.aad->GetPtr(),
434
6
                        op.aad == std::nullopt ? 0: op.aad->GetSize(),
435
6
                        nullptr,
436
6
                        op.cipher.iv.GetPtr(),
437
6
                        op.cipher.key.GetPtr()), 0);
438
439
6
            if ( ciphertext_len > op.cleartext.GetSize() + TAGLEN ) {
440
0
                abort();
441
0
            }
442
6
            if ( ciphertext_len < TAGLEN ) {
443
0
                abort();
444
0
            }
445
446
6
            ret = component::Ciphertext(
447
6
                    Buffer(out, ciphertext_len - TAGLEN),
448
6
                    Buffer(out + ciphertext_len - TAGLEN, TAGLEN));
449
54
end:
450
54
            util::free(out);
451
54
            return ret;
452
6
        }
cryptofuzz::module::libsodium_detail::AEAD<16ul, 8ul, 32ul>::Encrypt(cryptofuzz::operation::SymmetricEncrypt const&) const
Line
Count
Source
411
10
        std::optional<component::Ciphertext> Encrypt(const operation::SymmetricEncrypt& op) const {
412
10
            std::optional<component::Ciphertext> ret = std::nullopt;
413
414
10
            uint8_t* out = util::malloc(op.ciphertextSize);
415
416
            /* Operation must support tag output */
417
10
            CF_CHECK_NE(op.tagSize, std::nullopt);
418
5
            CF_CHECK_GTE(op.tagSize, TAGLEN);
419
420
            /* Output must be able to hold message + tag */
421
4
            CF_CHECK_GTE(op.ciphertextSize, op.cleartext.GetSize() + TAGLEN);
422
423
0
            CF_CHECK_EQ(op.cipher.iv.GetSize(), IVLEN);
424
0
            CF_CHECK_EQ(op.cipher.key.GetSize(), KEYLEN);
425
426
0
            unsigned long long ciphertext_len;
427
428
0
            CF_CHECK_EQ(encrypt(
429
0
                        out,
430
0
                        &ciphertext_len,
431
0
                        op.cleartext.GetPtr(),
432
0
                        op.cleartext.GetSize(),
433
0
                        op.aad == std::nullopt ? (const uint8_t*)0x12 : op.aad->GetPtr(),
434
0
                        op.aad == std::nullopt ? 0: op.aad->GetSize(),
435
0
                        nullptr,
436
0
                        op.cipher.iv.GetPtr(),
437
0
                        op.cipher.key.GetPtr()), 0);
438
439
0
            if ( ciphertext_len > op.cleartext.GetSize() + TAGLEN ) {
440
0
                abort();
441
0
            }
442
0
            if ( ciphertext_len < TAGLEN ) {
443
0
                abort();
444
0
            }
445
446
0
            ret = component::Ciphertext(
447
0
                    Buffer(out, ciphertext_len - TAGLEN),
448
0
                    Buffer(out + ciphertext_len - TAGLEN, TAGLEN));
449
10
end:
450
10
            util::free(out);
451
10
            return ret;
452
0
        }
cryptofuzz::module::libsodium_detail::AEAD<16ul, 24ul, 32ul>::Encrypt(cryptofuzz::operation::SymmetricEncrypt const&) const
Line
Count
Source
411
21
        std::optional<component::Ciphertext> Encrypt(const operation::SymmetricEncrypt& op) const {
412
21
            std::optional<component::Ciphertext> ret = std::nullopt;
413
414
21
            uint8_t* out = util::malloc(op.ciphertextSize);
415
416
            /* Operation must support tag output */
417
21
            CF_CHECK_NE(op.tagSize, std::nullopt);
418
11
            CF_CHECK_GTE(op.tagSize, TAGLEN);
419
420
            /* Output must be able to hold message + tag */
421
9
            CF_CHECK_GTE(op.ciphertextSize, op.cleartext.GetSize() + TAGLEN);
422
423
1
            CF_CHECK_EQ(op.cipher.iv.GetSize(), IVLEN);
424
0
            CF_CHECK_EQ(op.cipher.key.GetSize(), KEYLEN);
425
426
0
            unsigned long long ciphertext_len;
427
428
0
            CF_CHECK_EQ(encrypt(
429
0
                        out,
430
0
                        &ciphertext_len,
431
0
                        op.cleartext.GetPtr(),
432
0
                        op.cleartext.GetSize(),
433
0
                        op.aad == std::nullopt ? (const uint8_t*)0x12 : op.aad->GetPtr(),
434
0
                        op.aad == std::nullopt ? 0: op.aad->GetSize(),
435
0
                        nullptr,
436
0
                        op.cipher.iv.GetPtr(),
437
0
                        op.cipher.key.GetPtr()), 0);
438
439
0
            if ( ciphertext_len > op.cleartext.GetSize() + TAGLEN ) {
440
0
                abort();
441
0
            }
442
0
            if ( ciphertext_len < TAGLEN ) {
443
0
                abort();
444
0
            }
445
446
0
            ret = component::Ciphertext(
447
0
                    Buffer(out, ciphertext_len - TAGLEN),
448
0
                    Buffer(out + ciphertext_len - TAGLEN, TAGLEN));
449
21
end:
450
21
            util::free(out);
451
21
            return ret;
452
0
        }
453
454
71
        std::optional<component::Cleartext> Decrypt(const operation::SymmetricDecrypt& op) const {
455
71
            std::optional<component::Cleartext> ret = std::nullopt;
456
457
71
            size_t ciphertextAndTagSize;
458
71
            uint8_t* ciphertextAndTag = nullptr;
459
71
            uint8_t* out = nullptr;
460
461
71
            CF_CHECK_GTE(op.cleartextSize, op.ciphertext.GetSize());
462
463
45
            CF_CHECK_NE(op.tag, std::nullopt);
464
465
            /* Concatenate ciphertext + tag */
466
31
            {
467
31
                ciphertextAndTagSize = op.ciphertext.GetSize() + op.tag->GetSize();
468
31
                ciphertextAndTag = util::malloc(ciphertextAndTagSize);
469
470
31
                if ( op.ciphertext.GetSize() ) {
471
27
                    memcpy(ciphertextAndTag, op.ciphertext.GetPtr(), op.ciphertext.GetSize());
472
27
                }
473
31
                if ( op.tag->GetSize() ) {
474
30
                    memcpy(ciphertextAndTag + op.ciphertext.GetSize(), op.tag->GetPtr(), op.tag->GetSize());
475
30
                }
476
31
            }
477
478
31
            CF_CHECK_EQ(op.tag->GetSize(), TAGLEN);
479
11
            CF_CHECK_EQ(op.cipher.iv.GetSize(), IVLEN);
480
10
            CF_CHECK_EQ(op.cipher.key.GetSize(), KEYLEN);
481
482
10
            out = util::malloc(op.cleartextSize);
483
484
10
            unsigned long long cleartext_len;
485
486
10
            CF_CHECK_EQ(decrypt(
487
10
                        out,
488
10
                        &cleartext_len,
489
10
                        nullptr,
490
10
                        ciphertextAndTag,
491
10
                        ciphertextAndTagSize,
492
10
                        op.aad == std::nullopt ? (const uint8_t*)0x12 : op.aad->GetPtr(),
493
10
                        op.aad == std::nullopt ? 0: op.aad->GetSize(),
494
10
                        op.cipher.iv.GetPtr(),
495
10
                        op.cipher.key.GetPtr()), 0);
496
497
1
            ret = component::Cleartext(out, cleartext_len);
498
499
71
end:
500
71
            util::free(ciphertextAndTag);
501
71
            util::free(out);
502
503
71
            return ret;
504
1
        }
cryptofuzz::module::libsodium_detail::AEAD<16ul, 12ul, 32ul>::Decrypt(cryptofuzz::operation::SymmetricDecrypt const&) const
Line
Count
Source
454
48
        std::optional<component::Cleartext> Decrypt(const operation::SymmetricDecrypt& op) const {
455
48
            std::optional<component::Cleartext> ret = std::nullopt;
456
457
48
            size_t ciphertextAndTagSize;
458
48
            uint8_t* ciphertextAndTag = nullptr;
459
48
            uint8_t* out = nullptr;
460
461
48
            CF_CHECK_GTE(op.cleartextSize, op.ciphertext.GetSize());
462
463
33
            CF_CHECK_NE(op.tag, std::nullopt);
464
465
            /* Concatenate ciphertext + tag */
466
25
            {
467
25
                ciphertextAndTagSize = op.ciphertext.GetSize() + op.tag->GetSize();
468
25
                ciphertextAndTag = util::malloc(ciphertextAndTagSize);
469
470
25
                if ( op.ciphertext.GetSize() ) {
471
21
                    memcpy(ciphertextAndTag, op.ciphertext.GetPtr(), op.ciphertext.GetSize());
472
21
                }
473
25
                if ( op.tag->GetSize() ) {
474
25
                    memcpy(ciphertextAndTag + op.ciphertext.GetSize(), op.tag->GetPtr(), op.tag->GetSize());
475
25
                }
476
25
            }
477
478
25
            CF_CHECK_EQ(op.tag->GetSize(), TAGLEN);
479
11
            CF_CHECK_EQ(op.cipher.iv.GetSize(), IVLEN);
480
10
            CF_CHECK_EQ(op.cipher.key.GetSize(), KEYLEN);
481
482
10
            out = util::malloc(op.cleartextSize);
483
484
10
            unsigned long long cleartext_len;
485
486
10
            CF_CHECK_EQ(decrypt(
487
10
                        out,
488
10
                        &cleartext_len,
489
10
                        nullptr,
490
10
                        ciphertextAndTag,
491
10
                        ciphertextAndTagSize,
492
10
                        op.aad == std::nullopt ? (const uint8_t*)0x12 : op.aad->GetPtr(),
493
10
                        op.aad == std::nullopt ? 0: op.aad->GetSize(),
494
10
                        op.cipher.iv.GetPtr(),
495
10
                        op.cipher.key.GetPtr()), 0);
496
497
1
            ret = component::Cleartext(out, cleartext_len);
498
499
48
end:
500
48
            util::free(ciphertextAndTag);
501
48
            util::free(out);
502
503
48
            return ret;
504
1
        }
cryptofuzz::module::libsodium_detail::AEAD<16ul, 8ul, 32ul>::Decrypt(cryptofuzz::operation::SymmetricDecrypt const&) const
Line
Count
Source
454
13
        std::optional<component::Cleartext> Decrypt(const operation::SymmetricDecrypt& op) const {
455
13
            std::optional<component::Cleartext> ret = std::nullopt;
456
457
13
            size_t ciphertextAndTagSize;
458
13
            uint8_t* ciphertextAndTag = nullptr;
459
13
            uint8_t* out = nullptr;
460
461
13
            CF_CHECK_GTE(op.cleartextSize, op.ciphertext.GetSize());
462
463
6
            CF_CHECK_NE(op.tag, std::nullopt);
464
465
            /* Concatenate ciphertext + tag */
466
2
            {
467
2
                ciphertextAndTagSize = op.ciphertext.GetSize() + op.tag->GetSize();
468
2
                ciphertextAndTag = util::malloc(ciphertextAndTagSize);
469
470
2
                if ( op.ciphertext.GetSize() ) {
471
2
                    memcpy(ciphertextAndTag, op.ciphertext.GetPtr(), op.ciphertext.GetSize());
472
2
                }
473
2
                if ( op.tag->GetSize() ) {
474
2
                    memcpy(ciphertextAndTag + op.ciphertext.GetSize(), op.tag->GetPtr(), op.tag->GetSize());
475
2
                }
476
2
            }
477
478
2
            CF_CHECK_EQ(op.tag->GetSize(), TAGLEN);
479
0
            CF_CHECK_EQ(op.cipher.iv.GetSize(), IVLEN);
480
0
            CF_CHECK_EQ(op.cipher.key.GetSize(), KEYLEN);
481
482
0
            out = util::malloc(op.cleartextSize);
483
484
0
            unsigned long long cleartext_len;
485
486
0
            CF_CHECK_EQ(decrypt(
487
0
                        out,
488
0
                        &cleartext_len,
489
0
                        nullptr,
490
0
                        ciphertextAndTag,
491
0
                        ciphertextAndTagSize,
492
0
                        op.aad == std::nullopt ? (const uint8_t*)0x12 : op.aad->GetPtr(),
493
0
                        op.aad == std::nullopt ? 0: op.aad->GetSize(),
494
0
                        op.cipher.iv.GetPtr(),
495
0
                        op.cipher.key.GetPtr()), 0);
496
497
0
            ret = component::Cleartext(out, cleartext_len);
498
499
13
end:
500
13
            util::free(ciphertextAndTag);
501
13
            util::free(out);
502
503
13
            return ret;
504
0
        }
cryptofuzz::module::libsodium_detail::AEAD<16ul, 24ul, 32ul>::Decrypt(cryptofuzz::operation::SymmetricDecrypt const&) const
Line
Count
Source
454
10
        std::optional<component::Cleartext> Decrypt(const operation::SymmetricDecrypt& op) const {
455
10
            std::optional<component::Cleartext> ret = std::nullopt;
456
457
10
            size_t ciphertextAndTagSize;
458
10
            uint8_t* ciphertextAndTag = nullptr;
459
10
            uint8_t* out = nullptr;
460
461
10
            CF_CHECK_GTE(op.cleartextSize, op.ciphertext.GetSize());
462
463
6
            CF_CHECK_NE(op.tag, std::nullopt);
464
465
            /* Concatenate ciphertext + tag */
466
4
            {
467
4
                ciphertextAndTagSize = op.ciphertext.GetSize() + op.tag->GetSize();
468
4
                ciphertextAndTag = util::malloc(ciphertextAndTagSize);
469
470
4
                if ( op.ciphertext.GetSize() ) {
471
4
                    memcpy(ciphertextAndTag, op.ciphertext.GetPtr(), op.ciphertext.GetSize());
472
4
                }
473
4
                if ( op.tag->GetSize() ) {
474
3
                    memcpy(ciphertextAndTag + op.ciphertext.GetSize(), op.tag->GetPtr(), op.tag->GetSize());
475
3
                }
476
4
            }
477
478
4
            CF_CHECK_EQ(op.tag->GetSize(), TAGLEN);
479
0
            CF_CHECK_EQ(op.cipher.iv.GetSize(), IVLEN);
480
0
            CF_CHECK_EQ(op.cipher.key.GetSize(), KEYLEN);
481
482
0
            out = util::malloc(op.cleartextSize);
483
484
0
            unsigned long long cleartext_len;
485
486
0
            CF_CHECK_EQ(decrypt(
487
0
                        out,
488
0
                        &cleartext_len,
489
0
                        nullptr,
490
0
                        ciphertextAndTag,
491
0
                        ciphertextAndTagSize,
492
0
                        op.aad == std::nullopt ? (const uint8_t*)0x12 : op.aad->GetPtr(),
493
0
                        op.aad == std::nullopt ? 0: op.aad->GetSize(),
494
0
                        op.cipher.iv.GetPtr(),
495
0
                        op.cipher.key.GetPtr()), 0);
496
497
0
            ret = component::Cleartext(out, cleartext_len);
498
499
10
end:
500
10
            util::free(ciphertextAndTag);
501
10
            util::free(out);
502
503
10
            return ret;
504
0
        }
505
};
506
507
static class : public AEAD<
508
                                crypto_aead_aes256gcm_ABYTES,
509
                                crypto_aead_aes256gcm_NPUBBYTES,
510
                                crypto_aead_aes256gcm_KEYBYTES> {
511
    private:
512
        int encrypt(unsigned char *c,
513
                unsigned long long *clen,
514
                const unsigned char *m,
515
                unsigned long long mlen,
516
                const unsigned char *ad,
517
                unsigned long long adlen,
518
                const unsigned char *nsec,
519
                const unsigned char *npub,
520
0
                const unsigned char *k) const override {
521
0
            return crypto_aead_aes256gcm_encrypt(c, clen, m, mlen, ad, adlen, nsec, npub, k);
522
0
        }
523
524
        int decrypt(unsigned char *m,
525
                unsigned long long *mlen,
526
                unsigned char *nsec,
527
                const unsigned char *c,
528
                unsigned long long clen,
529
                const unsigned char *ad,
530
                unsigned long long adlen,
531
                const unsigned char *npub,
532
0
                const unsigned char *k) const override {
533
0
            return crypto_aead_aes256gcm_decrypt(m, mlen, nsec, c, clen, ad, adlen, npub, k);
534
0
        }
535
} aes_256_gcm;
536
537
static class : public AEAD<
538
                                crypto_aead_aes256gcm_ABYTES,
539
                                crypto_aead_aes256gcm_NPUBBYTES,
540
                                crypto_aead_aes256gcm_KEYBYTES> {
541
    private:
542
        int encrypt(unsigned char *c,
543
                unsigned long long *clen,
544
                const unsigned char *m,
545
                unsigned long long mlen,
546
                const unsigned char *ad,
547
                unsigned long long adlen,
548
                const unsigned char *nsec,
549
                const unsigned char *npub,
550
0
                const unsigned char *k) const override {
551
0
            int ret = -1;
552
553
0
            crypto_aead_aes256gcm_state ctx;
554
0
            CF_CHECK_EQ(crypto_aead_aes256gcm_beforenm(&ctx, k), 0);
555
556
0
            CF_CHECK_EQ(crypto_aead_aes256gcm_encrypt_afternm(c, clen, m, mlen, ad, adlen, nsec, npub, &ctx), 0);
557
558
0
            ret = 0;
559
560
0
end:
561
0
            return ret;
562
0
        }
563
564
        int decrypt(unsigned char *m,
565
                unsigned long long *mlen,
566
                unsigned char *nsec,
567
                const unsigned char *c,
568
                unsigned long long clen,
569
                const unsigned char *ad,
570
                unsigned long long adlen,
571
                const unsigned char *npub,
572
0
                const unsigned char *k) const override {
573
0
            int ret = -1;
574
0
            crypto_aead_aes256gcm_state ctx;
575
0
            CF_CHECK_EQ(crypto_aead_aes256gcm_beforenm(&ctx, k), 0);
576
577
0
            CF_CHECK_EQ(crypto_aead_aes256gcm_decrypt_afternm(m, mlen, nsec, c, clen, ad, adlen, npub, &ctx), 0);
578
579
0
            ret = 0;
580
0
end:
581
0
            return ret;
582
0
        }
583
} aes_256_gcm_precompute;
584
585
static class : public AEAD<
586
                                crypto_aead_chacha20poly1305_ABYTES,
587
                                crypto_aead_chacha20poly1305_NPUBBYTES,
588
                                crypto_aead_chacha20poly1305_KEYBYTES> {
589
    private:
590
        int encrypt(unsigned char *c,
591
                unsigned long long *clen,
592
                const unsigned char *m,
593
                unsigned long long mlen,
594
                const unsigned char *ad,
595
                unsigned long long adlen,
596
                const unsigned char *nsec,
597
                const unsigned char *npub,
598
0
                const unsigned char *k) const override {
599
0
            return crypto_aead_chacha20poly1305_encrypt(c, clen, m, mlen, ad, adlen, nsec, npub, k);
600
0
        }
601
602
        int decrypt(unsigned char *m,
603
                unsigned long long *mlen,
604
                unsigned char *nsec,
605
                const unsigned char *c,
606
                unsigned long long clen,
607
                const unsigned char *ad,
608
                unsigned long long adlen,
609
                const unsigned char *npub,
610
0
                const unsigned char *k) const override {
611
0
            return crypto_aead_chacha20poly1305_decrypt(m, mlen, nsec, c, clen, ad, adlen, npub, k);
612
0
        }
613
} chacha20_poly1305_libsodium;
614
615
static class : public AEAD<
616
                                crypto_aead_chacha20poly1305_IETF_ABYTES,
617
                                crypto_aead_chacha20poly1305_IETF_NPUBBYTES,
618
                                crypto_aead_chacha20poly1305_IETF_KEYBYTES> {
619
    private:
620
        int encrypt(unsigned char *c,
621
                unsigned long long *clen,
622
                const unsigned char *m,
623
                unsigned long long mlen,
624
                const unsigned char *ad,
625
                unsigned long long adlen,
626
                const unsigned char *nsec,
627
                const unsigned char *npub,
628
6
                const unsigned char *k) const override {
629
6
            return crypto_aead_chacha20poly1305_ietf_encrypt(c, clen, m, mlen, ad, adlen, nsec, npub, k);
630
6
        }
631
632
        int decrypt(unsigned char *m,
633
                unsigned long long *mlen,
634
                unsigned char *nsec,
635
                const unsigned char *c,
636
                unsigned long long clen,
637
                const unsigned char *ad,
638
                unsigned long long adlen,
639
                const unsigned char *npub,
640
10
                const unsigned char *k) const override {
641
10
            return crypto_aead_chacha20poly1305_ietf_decrypt(m, mlen, nsec, c, clen, ad, adlen, npub, k);
642
10
        }
643
} chacha20_poly1305;
644
645
static class : public AEAD<
646
                                crypto_aead_xchacha20poly1305_IETF_ABYTES,
647
                                crypto_aead_xchacha20poly1305_IETF_NPUBBYTES,
648
                                crypto_aead_xchacha20poly1305_IETF_KEYBYTES> {
649
    private:
650
        int encrypt(unsigned char *c,
651
                unsigned long long *clen,
652
                const unsigned char *m,
653
                unsigned long long mlen,
654
                const unsigned char *ad,
655
                unsigned long long adlen,
656
                const unsigned char *nsec,
657
                const unsigned char *npub,
658
0
                const unsigned char *k) const override {
659
0
            return crypto_aead_xchacha20poly1305_ietf_encrypt(c, clen, m, mlen, ad, adlen, nsec, npub, k);
660
0
        }
661
662
        int decrypt(unsigned char *m,
663
                unsigned long long *mlen,
664
                unsigned char *nsec,
665
                const unsigned char *c,
666
                unsigned long long clen,
667
                const unsigned char *ad,
668
                unsigned long long adlen,
669
                const unsigned char *npub,
670
0
                const unsigned char *k) const override {
671
0
            return crypto_aead_xchacha20poly1305_ietf_decrypt(m, mlen, nsec, c, clen, ad, adlen, npub, k);
672
0
        }
673
} xchacha20_poly1305;
674
675
} /* namespace libsodium_detail */
676
677
1.47k
std::optional<component::Ciphertext> libsodium::OpSymmetricEncrypt(operation::SymmetricEncrypt& op) {
678
1.47k
    uint8_t* out = nullptr;
679
680
1.47k
    switch ( op.cipher.cipherType.Get() ) {
681
27
        case    CF_CIPHER("AES_256_GCM"):
682
27
            {
683
27
                Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
684
27
                bool usePrecomputation = false;
685
27
                try {
686
27
                    usePrecomputation = ds.Get<bool>();
687
27
                } catch ( fuzzing::datasource::Datasource::OutOfData ) {
688
17
                }
689
690
27
                if ( usePrecomputation == false ) {
691
22
                    return libsodium_detail::aes_256_gcm.Encrypt(op);
692
22
                } else {
693
5
                    return libsodium_detail::aes_256_gcm_precompute.Encrypt(op);
694
5
                }
695
27
            }
696
0
            break;
697
10
        case    CF_CIPHER("CHACHA20_POLY1305_LIBSODIUM"):
698
10
            {
699
10
                return libsodium_detail::chacha20_poly1305_libsodium.Encrypt(op);
700
27
            }
701
0
            break;
702
27
        case    CF_CIPHER("CHACHA20_POLY1305"):
703
27
            {
704
27
                return libsodium_detail::chacha20_poly1305.Encrypt(op);
705
27
            }
706
0
            break;
707
21
        case    CF_CIPHER("XCHACHA20_POLY1305"):
708
21
            {
709
21
                return libsodium_detail::xchacha20_poly1305.Encrypt(op);
710
27
            }
711
0
            break;
712
26
        case    CF_CIPHER("CHACHA20"):
713
26
            {
714
26
                CF_CHECK_GTE(op.ciphertextSize, op.cleartext.GetSize());
715
14
                CF_CHECK_EQ(op.cipher.key.GetSize(), crypto_stream_chacha20_ietf_KEYBYTES);
716
9
                CF_CHECK_EQ(op.cipher.iv.GetSize(), crypto_stream_chacha20_ietf_NONCEBYTES);
717
2
                out = util::malloc(op.ciphertextSize);
718
2
                CF_CHECK_EQ(crypto_stream_chacha20_ietf_xor_ic(out, op.cleartext.GetPtr(), op.cleartext.GetSize(), op.cipher.iv.GetPtr(), 0, op.cipher.key.GetPtr()), 0);
719
2
                auto ret = component::Ciphertext(Buffer(out, op.cleartext.GetSize()));
720
2
                util::free(out);
721
2
                return ret;
722
2
            }
723
0
            break;
724
6
        case    CF_CIPHER("SALSA20_256"):
725
12
        case    CF_CIPHER("SALSA20_12_256"):
726
12
            {
727
12
                CF_CHECK_GTE(op.ciphertextSize, op.cleartext.GetSize());
728
5
                CF_CHECK_EQ(op.cipher.key.GetSize(), crypto_stream_salsa20_KEYBYTES);
729
1
                CF_CHECK_EQ(op.cipher.iv.GetSize(), crypto_stream_salsa20_NONCEBYTES);
730
1
                out = util::malloc(op.ciphertextSize);
731
1
                if ( op.cipher.cipherType.Get() == CF_CIPHER("SALSA20_256") ) {
732
0
                    CF_CHECK_EQ(crypto_stream_salsa20_xor(out, op.cleartext.GetPtr(), op.cleartext.GetSize(), op.cipher.iv.GetPtr(), op.cipher.key.GetPtr()), 0);
733
1
                } else {
734
1
                    CF_CHECK_EQ(crypto_stream_salsa2012_xor(out, op.cleartext.GetPtr(), op.cleartext.GetSize(), op.cipher.iv.GetPtr(), op.cipher.key.GetPtr()), 0);
735
1
                }
736
1
                auto ret = component::Ciphertext(Buffer(out, op.cleartext.GetSize()));
737
1
                util::free(out);
738
1
                return ret;
739
1
            }
740
0
            break;
741
1.35k
        default:
742
1.35k
            return std::nullopt;
743
1.47k
    }
744
745
35
end:
746
35
    util::free(out);
747
35
    return std::nullopt;
748
1.47k
}
749
750
1.42k
std::optional<component::Cleartext> libsodium::OpSymmetricDecrypt(operation::SymmetricDecrypt& op) {
751
1.42k
    uint8_t* out = nullptr;
752
753
1.42k
    switch ( op.cipher.cipherType.Get() ) {
754
15
        case    CF_CIPHER("AES_256_GCM"):
755
15
            {
756
15
                Datasource ds(op.modifier.GetPtr(), op.modifier.GetSize());
757
15
                bool usePrecomputation = false;
758
15
                try {
759
15
                    usePrecomputation = ds.Get<bool>();
760
15
                } catch ( fuzzing::datasource::Datasource::OutOfData ) {
761
6
                }
762
763
15
                if ( usePrecomputation == false ) {
764
9
                    return libsodium_detail::aes_256_gcm.Decrypt(op);
765
9
                } else {
766
6
                    return libsodium_detail::aes_256_gcm_precompute.Decrypt(op);
767
6
                }
768
15
            }
769
0
            break;
770
13
        case    CF_CIPHER("CHACHA20_POLY1305_LIBSODIUM"):
771
13
            {
772
13
                return libsodium_detail::chacha20_poly1305_libsodium.Decrypt(op);
773
15
            }
774
0
            break;
775
33
        case    CF_CIPHER("CHACHA20_POLY1305"):
776
33
            {
777
33
                return libsodium_detail::chacha20_poly1305.Decrypt(op);
778
15
            }
779
0
            break;
780
10
        case    CF_CIPHER("XCHACHA20_POLY1305"):
781
10
            {
782
10
                return libsodium_detail::xchacha20_poly1305.Decrypt(op);
783
15
            }
784
0
            break;
785
15
        case    CF_CIPHER("CHACHA20"):
786
15
            {
787
15
                CF_CHECK_GTE(op.cleartextSize, op.ciphertext.GetSize());
788
6
                CF_CHECK_EQ(op.cipher.key.GetSize(), crypto_stream_chacha20_ietf_KEYBYTES);
789
2
                CF_CHECK_EQ(op.cipher.iv.GetSize(), crypto_stream_chacha20_ietf_NONCEBYTES);
790
2
                out = util::malloc(op.cleartextSize);
791
2
                CF_CHECK_EQ(crypto_stream_chacha20_ietf_xor_ic(out, op.ciphertext.GetPtr(), op.ciphertext.GetSize(), op.cipher.iv.GetPtr(), 0, op.cipher.key.GetPtr()), 0);
792
2
                auto ret = component::Cleartext(Buffer(out, op.ciphertext.GetSize()));
793
2
                util::free(out);
794
2
                return ret;
795
2
            }
796
0
            break;
797
5
        case    CF_CIPHER("SALSA20_256"):
798
12
        case    CF_CIPHER("SALSA20_12_256"):
799
12
            {
800
12
                CF_CHECK_GTE(op.cleartextSize, op.ciphertext.GetSize());
801
8
                CF_CHECK_EQ(op.cipher.key.GetSize(), crypto_stream_salsa20_KEYBYTES);
802
2
                CF_CHECK_EQ(op.cipher.iv.GetSize(), crypto_stream_salsa20_NONCEBYTES);
803
1
                out = util::malloc(op.cleartextSize);
804
1
                if ( op.cipher.cipherType.Get() == CF_CIPHER("SALSA20_256") ) {
805
0
                    CF_CHECK_EQ(crypto_stream_salsa20_xor(out, op.ciphertext.GetPtr(), op.ciphertext.GetSize(), op.cipher.iv.GetPtr(), op.cipher.key.GetPtr()), 0);
806
1
                } else {
807
1
                    CF_CHECK_EQ(crypto_stream_salsa2012_xor(out, op.ciphertext.GetPtr(), op.ciphertext.GetSize(), op.cipher.iv.GetPtr(), op.cipher.key.GetPtr()), 0);
808
1
                }
809
1
                auto ret = component::Cleartext(Buffer(out, op.ciphertext.GetSize()));
810
1
                util::free(out);
811
1
                return ret;
812
1
            }
813
0
            break;
814
1.32k
        default:
815
1.32k
            return std::nullopt;
816
1.42k
    }
817
818
24
end:
819
24
    util::free(out);
820
24
    return std::nullopt;
821
1.42k
}
822
823
526
std::optional<component::Key> libsodium::OpKDF_ARGON2(operation::KDF_ARGON2& op) {
824
526
    std::optional<component::Key> ret = std::nullopt;
825
526
    uint8_t* out = util::malloc(op.keySize);
826
827
526
    CF_CHECK_EQ(op.salt.GetSize(), crypto_pwhash_SALTBYTES);
828
11
    CF_CHECK_EQ(op.threads, 1);
829
6
    CF_CHECK_GTE(op.keySize, crypto_pwhash_BYTES_MIN);
830
6
    CF_CHECK_GTE(op.password.GetSize(), crypto_pwhash_PASSWD_MIN);
831
6
    CF_CHECK_LTE(op.password.GetSize(), crypto_pwhash_PASSWD_MAX);
832
6
    CF_CHECK_GTE(op.iterations, crypto_pwhash_OPSLIMIT_MIN);
833
5
    CF_CHECK_LTE(op.iterations, crypto_pwhash_OPSLIMIT_MAX);
834
5
    CF_CHECK_GTE(op.memory * 1024, crypto_pwhash_MEMLIMIT_MIN);
835
    //CF_CHECK_LTE(op.memory, crypto_pwhash_MEMLIMIT_MAX);
836
837
5
    CF_CHECK_EQ(op.type == 1 || op.type == 2, true);
838
4
    CF_CHECK_EQ(crypto_pwhash(
839
4
                out,
840
4
                op.keySize,
841
4
                (const char*)op.password.GetPtr(),
842
4
                op.password.GetSize(),
843
4
                op.salt.GetPtr(),
844
4
                op.iterations,
845
4
                op.memory * 1024,
846
4
                op.type == 1 ? crypto_pwhash_ALG_ARGON2I13 : crypto_pwhash_ALG_ARGON2ID13
847
4
            ), 0);
848
849
2
    ret = component::Key(out, op.keySize);
850
851
526
end:
852
526
    util::free(out);
853
854
526
    return ret;
855
2
}
856
857
508
std::optional<component::Key> libsodium::OpKDF_SCRYPT(operation::KDF_SCRYPT& op) {
858
508
    std::optional<component::Key> ret = std::nullopt;
859
860
508
    const size_t outSize = op.keySize;
861
508
    uint8_t* out = util::malloc(outSize);
862
863
508
    CF_CHECK_EQ(crypto_pwhash_scryptsalsa208sha256_ll(
864
508
        op.password.GetPtr(),
865
508
        op.password.GetSize(),
866
508
        op.salt.GetPtr(),
867
508
        op.salt.GetSize(),
868
508
        op.N,
869
508
        op.r,
870
508
        op.p,
871
508
        out,
872
508
        outSize), 0);
873
874
332
    ret = component::Key(out, outSize);
875
876
508
end:
877
508
    util::free(out);
878
879
508
    return ret;
880
332
}
881
882
} /* namespace module */
883
} /* namespace cryptofuzz */