Coverage Report

Created: 2022-08-24 06:31

/src/cryptofuzz/modules/openssl/bn_ops.h
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
3
#include <cryptofuzz/components.h>
4
#include <cryptofuzz/operations.h>
5
#include <openssl/bn.h>
6
#include <openssl/asn1.h>
7
#if defined(CRYPTOFUZZ_BORINGSSL)
8
#include <openssl/mem.h>
9
#endif
10
#include <array>
11
12
namespace cryptofuzz {
13
namespace module {
14
namespace OpenSSL_bignum {
15
16
class Bignum {
17
    private:
18
        BIGNUM* bn = nullptr;
19
        Datasource& ds;
20
        bool locked = false;
21
        bool noFree = false;
22
    public:
23
        Bignum(Datasource& ds) :
24
            ds(ds)
25
19.5k
    { }
26
27
29.3k
        ~Bignum() {
28
29.3k
            if ( noFree == false ) {
29
26.8k
                BN_free(bn);
30
26.8k
            }
31
29.3k
        }
32
33
2.57k
        void Lock(void) {
34
2.57k
            locked = true;
35
2.57k
        }
36
37
2.52k
        void DisableFree(void) {
38
2.52k
            noFree = true;
39
2.52k
        }
40
41
2.52k
        void ReleaseOwnership(void) {
42
2.52k
            Lock();
43
2.52k
            DisableFree();
44
2.52k
        }
45
46
13.9k
        bool New(void) {
47
13.9k
            CF_ASSERT(locked == false, "Cannot renew locked Bignum");
48
49
13.9k
            BN_free(bn);
50
13.9k
            bn = BN_new();
51
52
13.9k
            return bn != nullptr;
53
13.9k
        }
54
55
30
        bool Set(Bignum& other) {
56
30
            bool ret = false;
57
58
30
            CF_CHECK_NE(BN_copy(bn, other.GetPtr()), NULL);
59
60
30
            ret = true;
61
30
end:
62
30
            return ret;
63
30
        }
64
65
15.5k
        bool Set(const std::string s) {
66
15.5k
            CF_ASSERT(locked == false, "Cannot set locked Bignum");
67
68
15.5k
            bool ret = false;
69
70
15.5k
            CF_CHECK_NE(BN_dec2bn(&bn, s.c_str()), 0);
71
72
15.5k
            ret = true;
73
15.5k
end:
74
15.5k
            return ret;
75
15.5k
        }
76
77
175
        std::optional<uint64_t> AsUint64(void) const {
78
175
            std::optional<uint64_t> ret = std::nullopt;
79
80
175
            uint8_t which = 0; try { which = ds.Get<uint8_t>(); } catch ( ... ) { }
81
82
175
            switch ( which ) {
83
137
                case    0:
84
137
#if !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_098)
85
137
                    {
86
                        /* BN_bn2binpad is not supported by OpenSSL 1.0.2 and 0.9.8 */
87
88
137
                        uint64_t v;
89
90
137
                        CF_CHECK_NE(BN_is_negative(bn), 1);
91
92
137
                        CF_CHECK_LTE(BN_num_bytes(bn), (int)sizeof(uint64_t));
93
123
                        CF_CHECK_NE(BN_bn2binpad(bn, (unsigned char*)&v, sizeof(v)), -1);
94
95
                        /* Manual reversing is required because
96
                         * BN_bn2lebinpad is not supported by BoringSSL.
97
                         *
98
                         * TODO This must be omitted on big-endian platforms.
99
                         */
100
123
                        v =
101
123
                            ((v & 0xFF00000000000000) >> 56) |
102
123
                            ((v & 0x00FF000000000000) >> 40) |
103
123
                            ((v & 0x0000FF0000000000) >> 24) |
104
123
                            ((v & 0x000000FF00000000) >>  8) |
105
123
                            ((v & 0x00000000FF000000) <<  8) |
106
123
                            ((v & 0x0000000000FF0000) << 24) |
107
123
                            ((v & 0x000000000000FF00) << 40) |
108
123
                            ((v & 0x00000000000000FF) << 56);
109
110
123
                        ret = v;
111
123
                    }
112
0
#endif
113
0
                    break;
114
12
                case    1:
115
#if !defined(CRYPTOFUZZ_LIBRESSL) && !defined(CRYPTOFUZZ_BORINGSSL) && !defined(CRYPTOFUZZ_OPENSSL_102) && !defined(CRYPTOFUZZ_OPENSSL_098)
116
                    {
117
                        ASN1_INTEGER* asn1 = nullptr;
118
                        uint64_t v;
119
120
                        CF_CHECK_NE( (asn1 = BN_to_ASN1_INTEGER(bn, nullptr)), nullptr);
121
                        const auto r = ASN1_INTEGER_get_uint64(&v, asn1);
122
                        ASN1_INTEGER_free(asn1);
123
                        CF_CHECK_EQ(r, 1);
124
125
                        ret = v;
126
                    }
127
#endif
128
12
                    break;
129
26
                default:
130
26
                    break;
131
132
175
            }
133
134
            /* Silence compiler */
135
161
            goto end;
136
175
end:
137
175
            return ret;
138
175
        }
139
140
99
        std::optional<int> AsInt(void) const {
141
99
            CF_NORET(util::HintBignumInt());
142
143
99
            std::optional<int> ret = std::nullopt;
144
99
            const auto u64 = AsUint64();
145
146
99
            CF_CHECK_NE(u64, std::nullopt);
147
79
            CF_CHECK_LTE(*u64, 2147483647);
148
149
69
            ret = *u64;
150
99
end:
151
99
            return ret;
152
69
        }
153
154
76
        std::optional<BN_ULONG> AsBN_ULONG(void) const {
155
76
            std::optional<BN_ULONG> ret;
156
76
            std::optional<uint64_t> v64;
157
158
            /* Convert bn[1] to uint64_t if possible */
159
76
            CF_CHECK_NE(v64 = AsUint64(), std::nullopt);
160
161
            /* Try to convert the uint64_t to BN_ULONG */
162
44
            BN_ULONG vul;
163
44
            CF_CHECK_EQ(vul = *v64, *v64);
164
165
44
            ret = vul;
166
76
end:
167
76
            return ret;
168
44
        }
169
170
9
        void SetUint32(const uint32_t v) {
171
            /* Gnarly but it works for now */
172
173
9
            char s[1024];
174
9
            if ( sprintf(s, "%u", v) < 0 ) {
175
0
                abort();
176
0
            }
177
178
9
            if ( Set(s) == false ) {
179
0
                abort();
180
0
            }
181
9
        }
182
183
15.5k
        BIGNUM* GetDestPtr(const bool allowDup = true) {
184
15.5k
            if ( locked == false ) {
185
15.5k
                try {
186
15.5k
                    {
187
15.5k
                        const bool changeConstness = ds.Get<bool>();
188
15.5k
                        if ( changeConstness == true ) {
189
1.02k
#if !defined(CRYPTOFUZZ_BORINGSSL)
190
1.02k
                            const bool constness = ds.Get<bool>();
191
192
1.02k
                            if ( constness == true ) {
193
530
                                /* noret */ BN_set_flags(bn, BN_FLG_CONSTTIME);
194
530
                            } else {
195
492
                                /* noret */ BN_set_flags(bn, 0);
196
492
                            }
197
1.02k
#endif
198
1.02k
                        }
199
15.5k
                    }
200
201
15.5k
                    {
202
15.5k
                        if ( allowDup == true ) {
203
1.98k
                            const bool dup = ds.Get<bool>();
204
205
1.98k
                            if ( dup == true ) {
206
883
                                BIGNUM* tmp = BN_dup(bn);
207
883
                                if ( tmp != nullptr ) {
208
883
                                    BN_free(bn);
209
883
                                    bn = tmp;
210
883
                                }
211
883
                            }
212
1.98k
                        }
213
15.5k
                    }
214
215
15.5k
                    {
216
15.5k
                        if ( allowDup == true ) {
217
1.75k
                            const bool asn1Convert = ds.Get<bool>();
218
219
1.75k
                            if ( asn1Convert == true ) {
220
802
                                ASN1_INTEGER* asn1 = BN_to_ASN1_INTEGER(bn, nullptr);
221
222
802
                                if ( asn1 != nullptr ) {
223
802
                                    BIGNUM* tmp = ASN1_INTEGER_to_BN(asn1, nullptr);
224
225
802
                                    if ( tmp != nullptr ) {
226
802
                                        BN_free(bn);
227
802
                                        bn = tmp;
228
802
                                    }
229
230
802
                                    ASN1_INTEGER_free(asn1);
231
802
                                }
232
802
                            }
233
1.75k
                        }
234
15.5k
                    }
235
236
15.5k
                    {
237
15.5k
                        if ( allowDup == true ) {
238
1.64k
                            const bool asn1Convert = ds.Get<bool>();
239
240
1.64k
                            if ( asn1Convert == true ) {
241
734
                                ASN1_ENUMERATED* asn1 = BN_to_ASN1_ENUMERATED(bn, nullptr);
242
243
734
                                if ( asn1 != nullptr ) {
244
734
                                    BIGNUM* tmp = ASN1_ENUMERATED_to_BN(asn1, nullptr);
245
246
734
                                    if ( tmp != nullptr ) {
247
734
                                        BN_free(bn);
248
734
                                        bn = tmp;
249
734
                                    }
250
251
734
                                    ASN1_ENUMERATED_free(asn1);
252
734
                                }
253
734
                            }
254
1.64k
                        }
255
15.5k
                    }
256
257
15.5k
                    {
258
15.5k
                        if ( allowDup == true ) {
259
1.56k
                            const bool mpiConvert = ds.Get<bool>();
260
261
1.56k
                            if ( mpiConvert == true ) {
262
692
                                const auto size = BN_bn2mpi(bn, nullptr);
263
692
                                uint8_t* p = util::malloc(size);
264
692
                                const auto size2 = BN_bn2mpi(bn, p);
265
692
                                CF_ASSERT(size == size2, "BN_bn2mpi size discrepancy");
266
692
                                BIGNUM* newbn = BN_new();
267
692
                                CF_ASSERT(BN_mpi2bn(p, size, newbn) != nullptr, "BN_mpi2bn failed");
268
692
                                CF_ASSERT(BN_copy(bn, newbn) != nullptr, "BN_copy failed");
269
692
                                BN_free(newbn);
270
692
                                util::free(p);
271
692
                            }
272
1.56k
                        }
273
274
15.5k
                        if ( allowDup == true ) {
275
1.50k
                            const bool binConvert = ds.Get<bool>();
276
277
1.50k
                            if ( binConvert == true && BN_is_negative(bn) == 0 ) {
278
693
                                const auto size = BN_num_bytes(bn);
279
693
                                uint8_t* p = util::malloc(size);
280
693
                                const auto size2 = BN_bn2bin(bn, p);
281
693
                                CF_ASSERT(size == size2, "BN_bn2bin size discrepancy");
282
693
                                BIGNUM* newbn = BN_new();
283
693
                                CF_ASSERT(BN_bin2bn(p, size, newbn) != nullptr, "BN_bin2bn failed");
284
693
                                CF_ASSERT(BN_copy(bn, newbn) != nullptr, "BN_copy failed");
285
693
                                BN_free(newbn);
286
693
                                util::free(p);
287
693
                            }
288
1.50k
                        }
289
15.5k
                    }
290
15.5k
                } catch ( ... ) { }
291
15.5k
            }
292
293
15.5k
            return bn;
294
15.5k
        }
295
296
2.11k
        BIGNUM* GetPtrConst(void) const {
297
2.11k
            return bn;
298
2.11k
        }
299
300
11.2k
        const BIGNUM* GetPtr(const bool allowDup = true) {
301
11.2k
            return GetDestPtr(allowDup);
302
11.2k
        }
303
304
1.77k
        std::optional<component::Bignum> ToComponentBignum(void) {
305
1.77k
            std::optional<component::Bignum> ret = std::nullopt;
306
307
1.77k
            char* str = nullptr;
308
309
1.77k
            bool hex = true;
310
1.77k
            try { hex = ds.Get<bool>(); } catch ( fuzzing::datasource::Datasource::OutOfData ) { }
311
312
1.77k
            if ( hex == true ) {
313
1.67k
                CF_CHECK_NE(str = BN_bn2hex(GetPtr()), nullptr);
314
1.67k
                ret = { util::HexToDec(str) };
315
1.67k
            } else {
316
104
                CF_CHECK_NE(str = BN_bn2dec(GetPtr()), nullptr);
317
104
                ret = { std::string(str) };
318
104
            }
319
1.77k
end:
320
1.77k
            OPENSSL_free(str);
321
322
1.77k
            return ret;
323
1.77k
        }
324
325
0
        std::optional<std::string> ToString(void) {
326
0
            std::optional<std::string> ret = std::nullopt;
327
0
328
0
            char* str = nullptr;
329
0
330
0
            CF_CHECK_NE(str = BN_bn2dec(GetPtr()), nullptr);
331
0
            ret = { std::string(str) };
332
0
end:
333
0
            OPENSSL_free(str);
334
0
335
0
            return ret;
336
0
        }
337
338
2.45k
        void Randomize(void) {
339
2.45k
            std::vector<uint8_t> data;
340
2.45k
            try {
341
2.45k
                data = ds.GetData(0, 1, 1024);
342
2.45k
            } catch ( fuzzing::datasource::Datasource::OutOfData ) { }
343
344
2.45k
            if ( !data.empty() ) {
345
250
                /* ignore return value */ BN_bin2bn(data.data(), data.size(), bn);
346
250
            }
347
2.45k
        }
348
349
408
        inline bool operator==(const Bignum& rhs) const {
350
408
            return BN_cmp(GetPtrConst(), rhs.GetPtrConst()) == 0;
351
408
        }
352
};
353
354
class BignumCluster {
355
    private:
356
        Datasource& ds;
357
        std::array<Bignum, 4> bn;
358
    public:
359
        BignumCluster(Datasource& ds, Bignum bn0, Bignum bn1, Bignum bn2, Bignum bn3) :
360
            ds(ds),
361
            bn({bn0, bn1, bn2, bn3})
362
2.45k
        { }
363
364
4.65k
        Bignum& operator[](const size_t index) {
365
4.65k
            CF_ASSERT(index < bn.size(), "Accessing bignum with illegal index");
366
367
4.65k
            try {
368
                /* Rewire? */
369
4.65k
                if ( ds.Get<bool>() == true ) {
370
                    /* Pick a random bignum */
371
426
                    const size_t newIndex = ds.Get<uint8_t>() % 4;
372
373
                    /* Same value? */
374
426
                    if ( bn[newIndex] == bn[index] ) {
375
                        /* Then return reference to other bignum */
376
377
176
                        if ( newIndex != index ) {
378
47
                            bn[newIndex].Lock();
379
47
                        }
380
381
176
                        return bn[newIndex];
382
176
                    }
383
384
                    /* Fall through */
385
426
                }
386
4.65k
            } catch ( fuzzing::datasource::Datasource::OutOfData ) { }
387
388
4.48k
            return bn[index];
389
4.65k
        }
390
391
49
        Bignum& Get(const size_t index) {
392
49
            CF_ASSERT(index < bn.size(), "Accessing bignum with illegal index");
393
394
49
            return bn[index];
395
49
        }
396
397
49
        BIGNUM* GetDestPtr(const size_t index) {
398
49
            return Get(index).GetDestPtr();
399
49
        }
400
401
9.82k
        bool New(const size_t index) {
402
9.82k
            CF_ASSERT(index < bn.size(), "Accessing bignum with illegal index");
403
404
9.82k
            return bn[index].New();
405
9.82k
        }
406
407
9.82k
        bool Set(const size_t index, const std::string s) {
408
9.82k
            CF_ASSERT(index < bn.size(), "Accessing bignum with illegal index");
409
410
9.82k
            return bn[index].Set(s);
411
9.82k
        }
412
};
413
414
class BN_CTX {
415
    private:
416
        ::BN_CTX* ctx = nullptr;
417
    public:
418
        BN_CTX(Datasource& ds) :
419
            ctx(BN_CTX_new())
420
2.48k
        {
421
2.48k
            (void)ds;
422
423
2.48k
            CF_ASSERT(ctx != nullptr, "BN_CTX_new() returned NULL");
424
2.48k
        }
425
426
1.45k
        ::BN_CTX* GetPtr() {
427
1.45k
            return ctx;
428
1.45k
        }
429
430
2.48k
        ~BN_CTX() {
431
2.48k
            BN_CTX_free(ctx);
432
2.48k
        }
433
};
434
class BN_MONT_CTX {
435
    private:
436
        ::BN_MONT_CTX* ctx = nullptr;
437
    public:
438
        BN_MONT_CTX(Datasource& ds) :
439
            ctx(BN_MONT_CTX_new())
440
18
        {
441
18
            (void)ds;
442
443
18
            CF_ASSERT(ctx != nullptr, "BN_MONT_CTX_new() returned NULL");
444
18
        }
445
446
38
        ::BN_MONT_CTX* GetPtr() {
447
38
            return ctx;
448
38
        }
449
450
18
        ~BN_MONT_CTX() {
451
18
            BN_MONT_CTX_free(ctx);
452
18
        }
453
};
454
455
class Operation {
456
    public:
457
        virtual bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const = 0;
458
2.07k
        virtual ~Operation() { }
459
};
460
461
class Add : public Operation {
462
    public:
463
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
464
};
465
466
class Sub : public Operation {
467
    public:
468
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
469
};
470
471
class Mul : public Operation {
472
    public:
473
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
474
};
475
476
class Mod : public Operation {
477
    public:
478
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
479
};
480
481
class ExpMod : public Operation {
482
    public:
483
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
484
};
485
486
class Sqr : public Operation {
487
    public:
488
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
489
};
490
491
class GCD : public Operation {
492
    public:
493
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
494
};
495
496
class AddMod : public Operation {
497
    public:
498
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
499
};
500
501
class SubMod : public Operation {
502
    public:
503
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
504
};
505
506
class MulMod : public Operation {
507
    public:
508
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
509
};
510
511
class SqrMod : public Operation {
512
    public:
513
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
514
};
515
516
class InvMod : public Operation {
517
    public:
518
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
519
};
520
521
class Cmp : public Operation {
522
    public:
523
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
524
};
525
526
class Div : public Operation {
527
    public:
528
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
529
};
530
531
class IsPrime : public Operation {
532
    public:
533
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
534
};
535
536
class Sqrt : public Operation {
537
    public:
538
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
539
};
540
541
class IsNeg : public Operation {
542
    public:
543
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
544
};
545
546
class IsEq : public Operation {
547
    public:
548
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
549
};
550
551
class IsEven : public Operation {
552
    public:
553
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
554
};
555
556
class IsOdd : public Operation {
557
    public:
558
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
559
};
560
561
class IsZero : public Operation {
562
    public:
563
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
564
};
565
566
class IsOne : public Operation {
567
    public:
568
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
569
};
570
571
class Jacobi : public Operation {
572
    public:
573
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
574
};
575
576
#if !defined(CRYPTOFUZZ_BORINGSSL) && !defined(CRYPTOFUZZ_OPENSSL_098)
577
class Mod_NIST_192 : public Operation {
578
    public:
579
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
580
};
581
582
class Mod_NIST_224 : public Operation {
583
    public:
584
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
585
};
586
587
class Mod_NIST_256 : public Operation {
588
    public:
589
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
590
};
591
592
class Mod_NIST_384 : public Operation {
593
    public:
594
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
595
};
596
597
class Mod_NIST_521 : public Operation {
598
    public:
599
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
600
};
601
#endif
602
603
class SqrtMod : public Operation {
604
    public:
605
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
606
};
607
608
#if defined(CRYPTOFUZZ_BORINGSSL)
609
class LCM : public Operation {
610
    public:
611
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
612
};
613
#endif
614
615
class Exp : public Operation {
616
    public:
617
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
618
};
619
620
class Abs : public Operation {
621
    public:
622
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
623
};
624
625
class RShift : public Operation {
626
    public:
627
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
628
};
629
630
class LShift1 : public Operation {
631
    public:
632
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
633
};
634
635
class SetBit : public Operation {
636
    public:
637
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
638
};
639
640
class ClearBit : public Operation {
641
    public:
642
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
643
};
644
645
class Bit : public Operation {
646
    public:
647
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
648
};
649
650
class CmpAbs : public Operation {
651
    public:
652
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
653
};
654
655
class ModLShift : public Operation {
656
    public:
657
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
658
};
659
660
class IsPow2 : public Operation {
661
    public:
662
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
663
};
664
665
class Mask : public Operation {
666
    public:
667
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
668
};
669
670
class IsCoprime : public Operation {
671
    public:
672
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
673
};
674
675
class Rand : public Operation {
676
    public:
677
        bool Run(Datasource& ds, Bignum& res, BignumCluster& bn, BN_CTX& ctx) const override;
678
};
679
680
} /* namespace OpenSSL_bignum */
681
} /* namespace module */
682
} /* namespace cryptofuzz */