Coverage Report

Created: 2025-11-16 07:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-openssl-api/src/ssl_bn.c
Line
Count
Source
1
/* ssl_bn.c
2
 *
3
 * Copyright (C) 2006-2025 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
23
24
#include <wolfssl/internal.h>
25
#ifndef WC_NO_RNG
26
    #include <wolfssl/wolfcrypt/random.h>
27
#endif
28
29
#if !defined(WOLFSSL_SSL_BN_INCLUDED)
30
    #ifndef WOLFSSL_IGNORE_FILE_WARN
31
        #warning ssl_bn.c does not need to be compiled separately from ssl.c
32
    #endif
33
#else
34
35
/* Check on validity of big number.
36
 *
37
 * Used for parameter validation.
38
 *
39
 * @param [in] bn  Big number.
40
 * @return 1 when bn is not NULL and internal representation is not NULL.
41
 * @return 0 otherwise.
42
 */
43
61.1k
#define BN_IS_NULL(bn) (((bn) == NULL) || ((bn)->internal == NULL))
44
45
/*******************************************************************************
46
 * Constructor/Destructor/Initializer APIs
47
 ******************************************************************************/
48
49
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN)
50
/* Set big number to be negative.
51
 *
52
 * @param [in, out] bn   Big number to make negative.
53
 * @param [in]      neg  Whether number is negative.
54
 * @return  1 on success.
55
 * @return  -1 when bn or internal representation of bn is NULL.
56
 */
57
static int wolfssl_bn_set_neg(WOLFSSL_BIGNUM* bn, int neg)
58
1.33k
{
59
1.33k
    int ret = 1;
60
61
1.33k
    if (BN_IS_NULL(bn)) {
62
0
        WOLFSSL_MSG("bn NULL error");
63
0
        ret = WOLFSSL_FATAL_ERROR;
64
0
    }
65
1.33k
#if !defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_SP_INT_NEGATIVE)
66
1.33k
    else if (neg) {
67
44
        mp_setneg((mp_int*)bn->internal);
68
44
    }
69
1.28k
    else {
70
1.28k
        ((mp_int*)bn->internal)->sign = MP_ZPOS;
71
1.28k
    }
72
1.33k
#endif
73
74
1.33k
    return ret;
75
1.33k
}
76
#endif /* OPENSSL_EXTRA && !NO_ASN */
77
78
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
79
/* Get the internal representation value into an MP integer.
80
 *
81
 * When calling wolfssl_bn_get_value, mpi should be cleared by caller if no
82
 * longer used. ie mp_free(mpi). This is to free data when fastmath is
83
 * disabled since a copy of mpi is made by this function and placed into bn.
84
 *
85
 * @param [in]      bn   Big number to copy value from.
86
 * @param [in, out] mpi  MP integer to copy into.
87
 * @return  1 on success.
88
 * @return  -1 when bn or internal representation of bn is NULL.
89
 * @return  -1 when mpi is NULL.
90
 * @return  -1 when copy fails.
91
 */
92
int wolfssl_bn_get_value(WOLFSSL_BIGNUM* bn, mp_int* mpi)
93
9.33k
{
94
9.33k
    int ret = 1;
95
96
9.33k
    WOLFSSL_MSG("Entering wolfssl_bn_get_value_mp");
97
98
    /* Validate parameters. */
99
9.33k
    if (BN_IS_NULL(bn)) {
100
0
        WOLFSSL_MSG("bn NULL error");
101
0
        ret = WOLFSSL_FATAL_ERROR;
102
0
    }
103
9.33k
    else if (mpi == NULL) {
104
0
        WOLFSSL_MSG("mpi NULL error");
105
0
        ret = WOLFSSL_FATAL_ERROR;
106
0
    }
107
108
    /* Copy the internal representation into MP integer. */
109
9.33k
    if ((ret == 1) && mp_copy((mp_int*)bn->internal, mpi) != MP_OKAY) {
110
0
        WOLFSSL_MSG("mp_copy error");
111
0
        ret = WOLFSSL_FATAL_ERROR;
112
0
    }
113
114
9.33k
    return ret;
115
9.33k
}
116
117
/* Set big number internal representation to value in mpi.
118
 *
119
 * Will create a new big number if bn points to NULL.
120
 *
121
 * When calling wolfssl_bn_set_value, mpi should be cleared by caller if no
122
 * longer used. ie mp_free(mpi). This is to free data when fastmath is
123
 * disabled since a copy of mpi is made by this function and placed into bn.
124
 *
125
 * @param [in, out] bn   Pointer to big number to have value.
126
 * @param [in]      mpi  MP integer with value to set.
127
 * @return  1 on success.
128
 * @return  -1 when mpi or bn is NULL.
129
 * @return  -1 when creating a new big number fails.
130
 * @return  -1 when copying MP integer fails.
131
 */
132
int wolfssl_bn_set_value(WOLFSSL_BIGNUM** bn, mp_int* mpi)
133
25.7k
{
134
25.7k
    int ret = 1;
135
25.7k
    WOLFSSL_BIGNUM* a = NULL;
136
137
#ifdef WOLFSSL_DEBUG_OPENSSL
138
    WOLFSSL_ENTER("wolfssl_bn_set_value");
139
#endif
140
141
    /* Validate parameters. */
142
25.7k
    if ((bn == NULL) || (mpi == NULL)) {
143
0
        WOLFSSL_MSG("mpi or bn NULL error");
144
0
        ret = WOLFSSL_FATAL_ERROR;
145
0
    }
146
147
    /* Allocate a new big number if one not passed in. */
148
25.7k
    if ((ret == 1) && (*bn == NULL)) {
149
21.9k
        a = wolfSSL_BN_new();
150
21.9k
        if (a == NULL) {
151
0
            WOLFSSL_MSG("wolfssl_bn_set_value alloc failed");
152
0
            ret = WOLFSSL_FATAL_ERROR;
153
0
        }
154
21.9k
        *bn = a;
155
21.9k
    }
156
157
    /* Copy MP integer value into internal representation of big number. */
158
25.7k
    if ((ret == 1) && (mp_copy(mpi, (mp_int*)((*bn)->internal)) != MP_OKAY)) {
159
0
        WOLFSSL_MSG("mp_copy error");
160
0
        ret = WOLFSSL_FATAL_ERROR;
161
0
    }
162
163
    /* Dispose of any allocated big number on error. */
164
25.7k
    if ((ret == -1) && (a != NULL)) {
165
0
        wolfSSL_BN_free(a);
166
0
        *bn = NULL;
167
0
    }
168
25.7k
    return ret;
169
25.7k
}
170
171
/* Initialize a big number.
172
 *
173
 * Assumes bn is not NULL.
174
 *
175
 * @param [in, out] bn  Big number to initialize.
176
 */
177
static void wolfssl_bn_init(WOLFSSL_BIGNUM* bn)
178
58.3k
{
179
    /* Clear fields of big number. */
180
58.3k
    XMEMSET(bn, 0, sizeof(WOLFSSL_BIGNUM));
181
    /* Initialization only fails when passed NULL. */
182
58.3k
    (void)mp_init(&bn->mpi);
183
    /* Set an internal representation. */
184
58.3k
    bn->internal = &bn->mpi;
185
58.3k
}
186
187
/* Create a new big number.
188
 *
189
 * @return  An allocated and initialized big number on success.
190
 * @return  NULL on failure.
191
 */
192
WOLFSSL_BIGNUM* wolfSSL_BN_new(void)
193
58.3k
{
194
58.3k
    WOLFSSL_BIGNUM* bn = NULL;
195
196
#ifdef WOLFSSL_DEBUG_OPENSSL
197
    WOLFSSL_ENTER("wolfSSL_BN_new");
198
#endif
199
200
    /* Allocate memory for big number. */
201
58.3k
    bn = (WOLFSSL_BIGNUM*)XMALLOC(sizeof(WOLFSSL_BIGNUM), NULL,
202
58.3k
        DYNAMIC_TYPE_BIGINT);
203
58.3k
    if (bn == NULL) {
204
0
        WOLFSSL_MSG("wolfSSL_BN_new malloc WOLFSSL_BIGNUM failure");
205
0
    }
206
58.3k
    else {
207
        /* Initialize newly allocated object. */
208
58.3k
        wolfssl_bn_init(bn);
209
58.3k
    }
210
211
58.3k
    return bn;
212
58.3k
}
213
214
#if !defined(USE_INTEGER_HEAP_MATH) && !defined(HAVE_WOLF_BIGINT)
215
/* Initialize a big number.
216
 *
217
 * Call this instead of wolfSSL_BN_new() and wolfSSL_BN_free().
218
 *
219
 * Do not call this API after wolfSSL_BN_new() or wolfSSL_BN_init().
220
 *
221
 * @param [in, out] bn  Big number to initialize.
222
 */
223
void wolfSSL_BN_init(WOLFSSL_BIGNUM* bn)
224
0
{
225
#ifdef WOLFSSL_DEBUG_OPENSSL
226
    WOLFSSL_ENTER("wolfSSL_BN_init");
227
#endif
228
229
    /* Validate parameter. */
230
0
    if (bn != NULL) {
231
        /* Initialize big number object. */
232
0
        wolfssl_bn_init(bn);
233
0
    }
234
0
}
235
#endif
236
237
/* Dispose of big number.
238
 *
239
 * bn is unusable after this call.
240
 *
241
 * @param [in, out] bn  Big number to free.
242
 */
243
void wolfSSL_BN_free(WOLFSSL_BIGNUM* bn)
244
110k
{
245
#ifdef WOLFSSL_DEBUG_OPENSSL
246
    WOLFSSL_ENTER("wolfSSL_BN_free");
247
#endif
248
249
    /* Validate parameter. */
250
110k
    if (bn != NULL) {
251
        /* Cleanup any internal representation. */
252
58.3k
        if (bn->internal != NULL) {
253
            /* Free MP integer. */
254
58.3k
            mp_free(&bn->mpi);
255
58.3k
        }
256
        /* Dispose of big number object. */
257
58.3k
        XFREE(bn, NULL, DYNAMIC_TYPE_BIGINT);
258
        /* bn = NULL, don't try to access or double free it */
259
58.3k
    }
260
110k
}
261
262
/* Zeroize and dispose of big number.
263
 *
264
 * bn is unusable after this call.
265
 *
266
 * @param [in, out] bn  Big number to clear and free.
267
 */
268
void wolfSSL_BN_clear_free(WOLFSSL_BIGNUM* bn)
269
2.59k
{
270
#ifdef WOLFSSL_DEBUG_OPENSSL
271
    WOLFSSL_ENTER("wolfSSL_BN_clear_free");
272
#endif
273
274
    /* Validate parameter. */
275
2.59k
    if (bn != NULL) {
276
        /* Check for internal representation. */
277
0
        if (bn->internal != NULL) {
278
            /* Zeroize MP integer. */
279
0
            mp_forcezero((mp_int*)bn->internal);
280
0
        }
281
        /* Dispose of big number. */
282
0
        wolfSSL_BN_free(bn);
283
0
    }
284
2.59k
}
285
286
/* Zeroize big number.
287
 *
288
 * @param [in, out] bn  Big number to clear.
289
 */
290
void wolfSSL_BN_clear(WOLFSSL_BIGNUM* bn)
291
0
{
292
#ifdef WOLFSSL_DEBUG_OPENSSL
293
    WOLFSSL_ENTER("wolfSSL_BN_clear");
294
#endif
295
296
    /* Validate parameter. */
297
0
    if (!BN_IS_NULL(bn)) {
298
        /* Zeroize MP integer. */
299
0
        mp_forcezero((mp_int*)bn->internal);
300
0
    }
301
0
}
302
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
303
304
#ifdef OPENSSL_EXTRA
305
306
static WOLFSSL_BIGNUM* bn_one = NULL;
307
308
/* Return a big number with the value of one.
309
 *
310
 * @return  A big number with the value one on success.
311
 * @return  NULL on failure.
312
 */
313
const WOLFSSL_BIGNUM* wolfSSL_BN_value_one(void)
314
0
{
315
0
    WOLFSSL_BIGNUM* one;
316
317
0
    WOLFSSL_ENTER("wolfSSL_BN_value_one");
318
319
    /* Get the global object. */
320
0
    one = bn_one;
321
    /* Create a new big number if global not set. */
322
0
    if ((one == NULL) && ((one = wolfSSL_BN_new()) != NULL)) {
323
        /* Set internal representation to have a value of 1. */
324
0
        if (mp_set_int((mp_int*)one->internal, 1) != MP_OKAY) {
325
            /* Dispose of big number on error. */
326
0
            wolfSSL_BN_free(one);
327
0
            one = NULL;
328
0
        }
329
0
        else
330
0
    #ifndef SINGLE_THREADED
331
        /* Ensure global has not been set by another thread. */
332
0
        if (bn_one == NULL)
333
0
    #endif
334
0
        {
335
            /* Set this big number as the global. */
336
0
            bn_one = one;
337
0
        }
338
0
    #ifndef SINGLE_THREADED
339
        /* Check if another thread has set the global. */
340
0
        if (bn_one != one) {
341
            /* Dispose of this big number and return the global.  */
342
0
            wolfSSL_BN_free(one);
343
0
            one = bn_one;
344
0
        }
345
0
    #endif
346
0
    }
347
348
0
    return one;
349
0
}
350
351
16
static void wolfSSL_BN_free_one(void) {
352
16
    wolfSSL_BN_free(bn_one);
353
16
    bn_one = NULL;
354
16
}
355
356
/* Create a new big number with the same value as the one passed in.
357
 *
358
 * @param [in] bn  Big number to duplicate.
359
 * @return  Big number on success.
360
 * @return  NULL when bn or internal representation of bn is NULL.
361
 * @return  NULL when creating a new big number fails.
362
 * @return  NULL when copying the internal representation fails.
363
 */
364
WOLFSSL_BIGNUM* wolfSSL_BN_dup(const WOLFSSL_BIGNUM* bn)
365
2.68k
{
366
2.68k
    int err = 0;
367
2.68k
    WOLFSSL_BIGNUM* ret = NULL;
368
369
2.68k
    WOLFSSL_ENTER("wolfSSL_BN_dup");
370
371
    /* Validate parameter. */
372
2.68k
    if (BN_IS_NULL(bn)) {
373
0
        WOLFSSL_MSG("bn NULL error");
374
0
        err = 1;
375
0
    }
376
377
    /* Create a new big number to return. */
378
2.68k
    if ((!err) && ((ret = wolfSSL_BN_new()) == NULL)) {
379
0
        WOLFSSL_MSG("bn new error");
380
0
        err = 1;
381
0
    }
382
383
2.68k
    if (!err) {
384
2.68k
        err = (wolfSSL_BN_copy(ret, bn) == NULL);
385
2.68k
    }
386
387
2.68k
    if (err) {
388
         /* Dispose of dynamically allocated data. */
389
0
         wolfSSL_BN_free(ret);
390
0
         ret = NULL;
391
0
    }
392
2.68k
    return ret;
393
2.68k
}
394
395
/* Copy value from bn into another r.
396
 *
397
 * @param [in, out] r   Big number to copy into.
398
 * @param [in]      bn  Big number to copy from.
399
 * @return  Big number copied into on success.
400
 * @return  NULL when r or bn is NULL.
401
 * @return  NULL when copying fails.
402
 */
403
WOLFSSL_BIGNUM* wolfSSL_BN_copy(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* bn)
404
8.56k
{
405
8.56k
    WOLFSSL_ENTER("wolfSSL_BN_copy");
406
407
    /* Validate parameters. */
408
8.56k
    if (BN_IS_NULL(r) || BN_IS_NULL(bn)) {
409
0
        WOLFSSL_MSG("r or bn NULL error");
410
0
        r = NULL;
411
0
    }
412
413
    /* Copy the value in. */
414
8.56k
    if ((r != NULL) && mp_copy((mp_int*)bn->internal, (mp_int*)r->internal) !=
415
8.56k
            MP_OKAY) {
416
0
        WOLFSSL_MSG("mp_copy error");
417
0
        r = NULL;
418
0
    }
419
420
8.56k
    if (r != NULL) {
421
        /* Copy other fields in a big number. */
422
8.56k
        r->neg = bn->neg;
423
8.56k
    }
424
425
8.56k
    return r;
426
8.56k
}
427
428
429
/*******************************************************************************
430
 * Encode/Decode APIs.
431
 ******************************************************************************/
432
433
/* Encode the number is a big-endian byte array.
434
 *
435
 * Assumes byte array is large enough to hold encoding when not NULL.
436
 * Use NULL for byte array to get length.
437
 *
438
 * Return compliant with OpenSSL.
439
 *
440
 * @param [in]  bn  Big number to reduced
441
 * @param [out] r   Byte array to encode into. May be NULL.
442
 * @return  Length of big number in bytes on success.
443
 * @return  -1 when bn is NULL or encoding fails.
444
 */
445
int wolfSSL_BN_bn2bin(const WOLFSSL_BIGNUM* bn, unsigned char* r)
446
936
{
447
936
    int ret;
448
449
936
    WOLFSSL_ENTER("wolfSSL_BN_bn2bin");
450
451
    /* Validate parameters. */
452
936
    if (BN_IS_NULL(bn)) {
453
0
        WOLFSSL_MSG("NULL bn error");
454
0
        ret = WOLFSSL_FATAL_ERROR;
455
0
    }
456
936
    else {
457
        /* Get the length of the encoding. */
458
936
        ret = mp_unsigned_bin_size((mp_int*)bn->internal);
459
        /* Encode if byte array supplied. */
460
936
        if ((r != NULL) && (mp_to_unsigned_bin((mp_int*)bn->internal, r) !=
461
936
                MP_OKAY)) {
462
0
            WOLFSSL_MSG("mp_to_unsigned_bin error");
463
0
            ret = WOLFSSL_FATAL_ERROR;
464
0
        }
465
936
    }
466
467
936
    return ret;
468
936
}
469
470
471
/* Return a big number with value of the decoding of the big-endian byte array.
472
 *
473
 * Returns ret when not NULL.
474
 * Allocates a big number when ret is NULL.
475
 * Assumes str is not NULL.
476
 *
477
 * @param [in]      data  Byte array to decode.
478
 * @param [in]      len   Number of bytes in byte array.
479
 * @param [in, out] ret   Big number to reduced. May be NULL.
480
 * @return  A big number on success.
481
 * @return  NULL on failure.
482
 */
483
WOLFSSL_BIGNUM* wolfSSL_BN_bin2bn(const unsigned char* data, int len,
484
    WOLFSSL_BIGNUM* ret)
485
1.33k
{
486
1.33k
    WOLFSSL_BIGNUM* bn = NULL;
487
488
1.33k
    WOLFSSL_ENTER("wolfSSL_BN_bin2bn");
489
490
    /* Validate parameters. */
491
1.33k
    if (len < 0) {
492
0
        ret = NULL;
493
0
    }
494
    /* Allocate a new big number when ret is NULL. */
495
1.33k
    else if (ret == NULL) {
496
1.33k
        ret = wolfSSL_BN_new();
497
1.33k
        bn = ret;
498
1.33k
    }
499
500
    /* Check ret is usable. */
501
1.33k
    if (ret != NULL) {
502
        /* Check internal representation is usable. */
503
1.33k
        if (ret->internal == NULL) {
504
0
            ret = NULL;
505
0
        }
506
1.33k
        else if (data != NULL) {
507
            /* Decode into big number. */
508
1.33k
            if (mp_read_unsigned_bin((mp_int*)ret->internal, data, (word32)len)
509
1.33k
                    != 0) {
510
3
                WOLFSSL_MSG("mp_read_unsigned_bin failure");
511
                /* Don't return anything on failure. bn will be freed if set. */
512
3
                ret = NULL;
513
3
            }
514
1.33k
            else {
515
                /* Don't free bn as we are returning it. */
516
1.33k
                bn = NULL;
517
1.33k
            }
518
1.33k
        }
519
0
        else if (data == NULL) {
520
0
            wolfSSL_BN_zero(ret);
521
            /* Don't free bn as we are returning it. */
522
0
            bn = NULL;
523
0
        }
524
1.33k
    }
525
526
    /* Dispose of allocated BN not being returned. */
527
1.33k
    wolfSSL_BN_free(bn);
528
529
1.33k
    return ret;
530
1.33k
}
531
532
/* Encode the big number value into a string, of the radix, that is allocated.
533
 *
534
 * @param [in] bn     Big number to encode.
535
 * @param [in] radix  Radix to encode to.
536
 * @return  String with encoding on success.
537
 * @return  NULL when bn or internal representation of bn is NULL.
538
 * @return  NULL on failure.
539
 */
540
static char* wolfssl_bn_bn2radix(const WOLFSSL_BIGNUM* bn, int radix)
541
4.34k
{
542
4.34k
    int err = 0;
543
4.34k
    int len = 0;
544
4.34k
    char* str = NULL;
545
546
547
    /* Validate parameter. */
548
4.34k
    if (BN_IS_NULL(bn)) {
549
0
        WOLFSSL_MSG("bn NULL error");
550
0
        err = 1;
551
0
    }
552
553
    /* Determine length of encoding. */
554
4.34k
    if ((!err) && (mp_radix_size((mp_int*)bn->internal, radix, &len) !=
555
4.34k
            MP_OKAY)) {
556
0
        WOLFSSL_MSG("mp_radix_size failure");
557
0
        err = 1;
558
0
    }
559
560
4.34k
    if (!err) {
561
        /* Allocate string. */
562
4.34k
        str = (char*)XMALLOC((size_t)len, NULL, DYNAMIC_TYPE_OPENSSL);
563
4.34k
        if (str == NULL) {
564
0
            WOLFSSL_MSG("BN_bn2hex malloc string failure");
565
0
            err = 1;
566
0
        }
567
4.34k
    }
568
569
    /* Encode into string using wolfCrypt. */
570
4.34k
    if ((!err) && (mp_toradix((mp_int*)bn->internal, str, radix) != MP_OKAY)) {
571
0
        err = 1;
572
0
    }
573
574
4.34k
    if (err) {
575
        /* Dispose of dynamically allocated data. */
576
0
        XFREE(str, NULL, DYNAMIC_TYPE_OPENSSL);
577
        /* Don't return freed string. */
578
0
        str = NULL;
579
0
    }
580
4.34k
    return str;
581
4.34k
}
582
583
/* Encode the big number value into hex string that is allocated.
584
 *
585
 * @param [in] bn  Big number to encode.
586
 * @return  String with encoding on success.
587
 * @return  NULL when bn or internal representation of bn is NULL.
588
 * @return  NULL on failure.
589
 */
590
char* wolfSSL_BN_bn2hex(const WOLFSSL_BIGNUM *bn)
591
0
{
592
0
    WOLFSSL_ENTER("wolfSSL_BN_bn2hex");
593
0
    return wolfssl_bn_bn2radix(bn, MP_RADIX_HEX);
594
0
}
595
596
/* Decode string of a radix into a big number.
597
 *
598
 * If bn is a pointer to NULL, then a new big number is allocated and assigned.
599
 *
600
 * Note on use: this function expects str to be an even length. It is
601
 * converting pairs of bytes into 8-bit values. As an example, the RSA
602
 * public exponent is commonly 0x010001. To get it to convert, you need
603
 * to pass in the string "010001", it will fail if you use "10001". This
604
 * is an affect of how Base16_Decode() works.
605
 *
606
 * @param [in, out] bn     Pointer to a big number. May point to NULL.
607
 * @param [in]      str    Hex string to decode.
608
 * @param [in]      radix  Radix to decode from.
609
 * @return  1 on success.
610
 * @return  0 when bn or str is NULL or str is zero length.
611
 * @return  0 when creating a new big number fails.
612
 * @return  0 when decoding fails.
613
 */
614
static int wolfssl_bn_radix2bn(WOLFSSL_BIGNUM** bn, const char* str, int radix)
615
23.5k
{
616
23.5k
    int ret = 1;
617
23.5k
    WOLFSSL_BIGNUM* a = NULL;
618
619
    /* Validate parameters. */
620
23.5k
    if ((bn == NULL) || (str == NULL) || (str[0] == '\0')) {
621
0
        WOLFSSL_MSG("Bad function argument");
622
0
        ret = 0;
623
0
    }
624
    /* Check if we have a big number to decode into. */
625
23.5k
    if ((ret == 1) && (*bn == NULL)) {
626
        /* Allocate a new big number. */
627
6.08k
        a = wolfSSL_BN_new();
628
6.08k
        if (a == NULL) {
629
0
            WOLFSSL_MSG("BN new failed");
630
0
            ret = 0;
631
0
        }
632
        /* Return allocated big number. */
633
6.08k
        *bn = a;
634
6.08k
    }
635
    /* Decode hex string into internal representation. */
636
23.5k
    if ((ret == 1) && (mp_read_radix((mp_int*)(*bn)->internal, str, radix) !=
637
23.5k
            MP_OKAY)) {
638
153
        WOLFSSL_MSG("Bad read_radix error");
639
153
        ret = 0;
640
153
    }
641
642
23.5k
    if ((ret == 0) && (a != NULL)) {
643
        /* Dispose of big number. */
644
112
        wolfSSL_BN_free(a);
645
        /* Don't return freed big number. */
646
112
        *bn = NULL;
647
112
    }
648
23.5k
    return ret;
649
23.5k
}
650
651
/* Decode hex string into a big number.
652
 *
653
 * If bn is a pointer to NULL, then a new big number is allocated and assigned.
654
 *
655
 * Note on use: this function expects str to be an even length. It is
656
 * converting pairs of bytes into 8-bit values. As an example, the RSA
657
 * public exponent is commonly 0x010001. To get it to convert, you need
658
 * to pass in the string "010001", it will fail if you use "10001". This
659
 * is an affect of how Base16_Decode() works.
660
 *
661
 * @param [in, out] bn   Pointer to a big number. May point to NULL.
662
 * @param [in]      str  Hex string to decode.
663
 * @return  1 on success.
664
 * @return  0 when bn or str is NULL or str is zero length.
665
 * @return  0 when creating a new big number fails.
666
 * @return  0 when decoding fails.
667
 */
668
int wolfSSL_BN_hex2bn(WOLFSSL_BIGNUM** bn, const char* str)
669
23.5k
{
670
23.5k
    WOLFSSL_ENTER("wolfSSL_BN_hex2bn");
671
23.5k
    return wolfssl_bn_radix2bn(bn, str, MP_RADIX_HEX);
672
23.5k
}
673
674
#if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY)
675
/* Encode big number into decimal string.
676
 *
677
 * @param [in] bn  Big number to encode.
678
 * @return  String with encoding on success.
679
 * @return  NULL when bn or internal representation of bn is NULL.
680
 * @return  NULL on failure.
681
 */
682
char* wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM *bn)
683
4.34k
{
684
4.34k
    WOLFSSL_ENTER("wolfSSL_BN_bn2hex");
685
4.34k
    return wolfssl_bn_bn2radix(bn, MP_RADIX_DEC);
686
4.34k
}
687
#else
688
/* Encode big number into decimal string.
689
 *
690
 * @param [in] bn  Big number to encode.
691
 * @return  NULL as implementation not available.
692
 */
693
char* wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM* bn)
694
{
695
    (void)bn;
696
    WOLFSSL_ENTER("wolfSSL_BN_bn2dec");
697
    return NULL;
698
}
699
#endif /* defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) */
700
701
702
#ifndef NO_RSA
703
/* Decode hex string into a big number.
704
 *
705
 * If bn is a pointer to NULL, then a new big number is allocated and assigned.
706
 *
707
 * Note on use: this function expects str to be an even length. It is
708
 * converting pairs of bytes into 8-bit values. As an example, the RSA
709
 * public exponent is commonly 0x010001. To get it to convert, you need
710
 * to pass in the string "010001", it will fail if you use "10001". This
711
 * is an affect of how Base16_Decode() works.
712
 *
713
 * @param [in, out] bn   Pointer to a big number. May point to NULL.
714
 * @param [in]      str  Hex string to decode.
715
 * @return  1 on success.
716
 * @return  0 when bn or str is NULL or str is zero length.
717
 * @return  0 when creating a new big number fails.
718
 * @return  0 when decoding fails.
719
 */
720
int wolfSSL_BN_dec2bn(WOLFSSL_BIGNUM** bn, const char* str)
721
0
{
722
0
    WOLFSSL_ENTER("wolfSSL_BN_bn2dec");
723
0
    return wolfssl_bn_radix2bn(bn, str, MP_RADIX_DEC);
724
0
}
725
#else
726
/* Decode hex string into a big number.
727
 *
728
 * @param [in, out] bn   Pointer to a big number. May point to NULL.
729
 * @param [in]      str  Hex string to decode.
730
 * @return  0 as implementation not available..
731
 */
732
int wolfSSL_BN_dec2bn(WOLFSSL_BIGNUM** bn, const char* str)
733
{
734
    (void)bn;
735
    (void)str;
736
    WOLFSSL_ENTER("wolfSSL_BN_bn2dec");
737
    return 0;
738
}
739
#endif
740
741
/*******************************************************************************
742
 * Get/Set APIs
743
 ******************************************************************************/
744
745
/* Calculate the number of bytes need to represent big number.
746
 *
747
 * Return compliant with OpenSSL.
748
 *
749
 * @param [in] bn  Big number to use.
750
 * @return  Size of BIGNUM in bytes on success.
751
 * @return  0 when bn or internal representation of bn is NULL.
752
 */
753
int wolfSSL_BN_num_bytes(const WOLFSSL_BIGNUM* bn)
754
1.33k
{
755
1.33k
    int ret;
756
757
1.33k
    WOLFSSL_ENTER("wolfSSL_BN_num_bytes");
758
759
    /* Validate parameter. */
760
1.33k
    if (BN_IS_NULL(bn)) {
761
0
        ret = 0;
762
0
    }
763
1.33k
    else {
764
        /* Get size from wolfCrypt. */
765
1.33k
        ret = mp_unsigned_bin_size((mp_int*)bn->internal);
766
1.33k
    }
767
768
1.33k
    return ret;
769
1.33k
}
770
771
/* Calculate the number of bits need to represent big number.
772
 *
773
 * Return compliant with OpenSSL.
774
 *
775
 * @param [in] bn  Big number to use.
776
 * @return  Size of BIGNUM in bits on success.
777
 * @return  0 when bn or internal representation of bn is NULL.
778
 */
779
int wolfSSL_BN_num_bits(const WOLFSSL_BIGNUM* bn)
780
1.33k
{
781
1.33k
    int ret;
782
783
1.33k
    WOLFSSL_ENTER("wolfSSL_BN_num_bits");
784
785
    /* Validate parameter. */
786
1.33k
    if (BN_IS_NULL(bn)) {
787
0
        ret = 0;
788
0
    }
789
1.33k
    else {
790
        /* Get size from wolfCrypt. */
791
1.33k
        ret = mp_count_bits((mp_int*)bn->internal);
792
1.33k
    }
793
794
1.33k
    return ret;
795
1.33k
}
796
797
/* Indicates whether a big number is negative.
798
 *
799
 * @param [in] bn  Big number to use.
800
 * @return  1 when number is negative.
801
 * @return  0 when number is positive.
802
 * @return  0 when bn is NULL.
803
 */
804
int wolfSSL_BN_is_negative(const WOLFSSL_BIGNUM* bn)
805
2.67k
{
806
2.67k
    int ret;
807
808
    /* Validate parameter. */
809
2.67k
    if (BN_IS_NULL(bn)) {
810
0
        ret = 0;
811
0
    }
812
2.67k
    else {
813
        /* Check sign with wolfCrypt. */
814
2.67k
        ret = mp_isneg((mp_int*)bn->internal);
815
2.67k
    }
816
817
2.67k
    return ret;
818
2.67k
}
819
820
/* Indicates whether a big number is odd.
821
 *
822
 * Return compliant with OpenSSL.
823
 *
824
 * @param [in] bn  Big number to use.
825
 * @return  1 when number is odd.
826
 * @return  0 when number is even.
827
 * @return  0 when bn or internal representation of bn is NULL.
828
 */
829
int wolfSSL_BN_is_odd(const WOLFSSL_BIGNUM* bn)
830
40
{
831
40
    int ret;
832
833
40
    WOLFSSL_ENTER("wolfSSL_BN_is_odd");
834
835
    /* Validate parameter. */
836
40
    if (BN_IS_NULL(bn)) {
837
0
        ret = 0;
838
0
    }
839
40
    else {
840
        /* wolfCrypt checks whether value is odd. */
841
40
        ret = (mp_isodd((mp_int*)bn->internal) == MP_YES);
842
40
    }
843
844
40
    return ret;
845
40
}
846
847
#ifndef NO_WOLFSSL_STUB
848
/* Mask the lowest n bits.
849
 *
850
 * TODO: mp_mod_2d()
851
 *
852
 * Return compliant with OpenSSL.
853
 *
854
 * @param [in, out] bn  Big number to operation on.
855
 * @param [in]      n   Number of bits.
856
 * @return  0 on failure.
857
 */
858
int wolfSSL_mask_bits(WOLFSSL_BIGNUM* bn, int n)
859
0
{
860
0
    (void)bn;
861
0
    (void)n;
862
0
    WOLFSSL_ENTER("wolfSSL_BN_mask_bits");
863
0
    WOLFSSL_STUB("BN_mask_bits");
864
0
    return 0;
865
0
}
866
#endif
867
868
/* Set a bit of the value in a big number.
869
 *
870
 * Return code compliant with OpenSSL.
871
 *
872
 * @param [in, out] bn  Big number to modify.
873
 * @return  1 on success.
874
 * @return  0 when bn or internal representation of bn is NULL.
875
 * @return  0 when failed to set bit.
876
 */
877
int wolfSSL_BN_set_bit(WOLFSSL_BIGNUM* bn, int n)
878
0
{
879
0
    int ret = 1;
880
881
0
    if (BN_IS_NULL(bn)) {
882
0
        WOLFSSL_MSG("bn NULL error");
883
0
        ret = 0;
884
0
    }
885
0
    else if (mp_set_bit((mp_int*)bn->internal, n) != MP_OKAY) {
886
0
        WOLFSSL_MSG("mp_set_bit error");
887
0
        ret = 0;
888
0
    }
889
890
0
    return ret;
891
0
}
892
893
/* Clear a bit of the value in a big number.
894
 *
895
 * Return code compliant with OpenSSL.
896
 *
897
 * @param [in] bn  Big number to check.
898
 * @param [in] n   Inidex of bit to check.
899
 * @return  1 on success.
900
 * @return  0 when bn or internal representation of bn is NULL.
901
 * @return  0 when failed to clear bit.
902
 */
903
int wolfSSL_BN_clear_bit(WOLFSSL_BIGNUM* bn, int n)
904
0
{
905
0
    int ret = 1;
906
0
    WC_DECLARE_VAR(tmp, mp_int, 1, 0);
907
908
    /* Validate parameters. */
909
0
    if (BN_IS_NULL(bn) || (n < 0)) {
910
0
        WOLFSSL_MSG("bn NULL error");
911
0
        ret = 0;
912
0
    }
913
    /* Check if bit is set to clear. */
914
0
    if ((ret == 1) && (mp_is_bit_set((mp_int*)bn->internal, n))) {
915
        /* Allocate a new MP integer to hold bit to clear. */
916
0
        WC_ALLOC_VAR_EX(tmp, mp_int, 1, NULL, DYNAMIC_TYPE_BIGINT, ret=0);
917
0
        if (ret == 1) {
918
            /* Reset new MP integer. */
919
0
            XMEMSET(tmp, 0, sizeof(mp_int));
920
0
            if (mp_init(tmp) != MP_OKAY) {
921
0
                ret = 0;
922
0
            }
923
0
        }
924
        /* Set the bit to clear into temporary MP integer. */
925
0
        if ((ret == 1) && (mp_set_bit(tmp, n) != MP_OKAY)) {
926
0
            ret = 0;
927
0
        }
928
        /* Clear bit by sutraction. */
929
0
        if ((ret == 1) && (mp_sub((mp_int*)bn->internal, tmp,
930
0
                (mp_int*)bn->internal) != MP_OKAY)) {
931
0
            ret = 0;
932
0
        }
933
934
        /* Free any dynamic memory in MP integer. */
935
0
        mp_clear(tmp);
936
0
        WC_FREE_VAR_EX(tmp, NULL, DYNAMIC_TYPE_BIGINT);
937
0
    }
938
939
0
    return ret;
940
0
}
941
942
/* Returns whether the bit is set in the value of the big number.
943
 *
944
 * When bn is NULL, returns 0.
945
 *
946
 * Return code compliant with OpenSSL.
947
 *
948
 * @param [in] bn  Big number to check.
949
 * @param [in] n   Inidex of bit to check.
950
 * @return  1 if bit set.
951
 * @return  0 otherwise.
952
 */
953
int wolfSSL_BN_is_bit_set(const WOLFSSL_BIGNUM* bn, int n)
954
0
{
955
0
    int ret;
956
957
    /* Check for big number value. */
958
0
    if (BN_IS_NULL(bn) || (n < 0)) {
959
0
        WOLFSSL_MSG("bn NULL error");
960
0
        ret = 0;
961
0
    }
962
0
    else {
963
        /* Set bit with wolfCrypt. */
964
0
        ret = mp_is_bit_set((mp_int*)bn->internal, (mp_digit)n);
965
0
    }
966
967
0
    return ret;
968
0
}
969
970
/* Set the big number to the value 0.
971
 *
972
 * @param [in, out] bn  Big number to use.
973
 */
974
void wolfSSL_BN_zero(WOLFSSL_BIGNUM* bn)
975
0
{
976
    /* Validate parameter. */
977
0
    if (!BN_IS_NULL(bn)) {
978
        /* Set wolfCrypt representation to 0. */
979
0
        mp_zero((mp_int*)bn->internal);
980
0
    }
981
0
}
982
983
/* Set the big number to the value 0.
984
 *
985
 * @param [in, out] bn  Big number to use.
986
 * @return  1 on success.
987
 * @return  0 when bn or internal representation of bn is NULL.
988
 */
989
int wolfSSL_BN_one(WOLFSSL_BIGNUM* bn)
990
1.56k
{
991
1.56k
    int ret;
992
993
    /* Validate parameter. */
994
1.56k
    if (BN_IS_NULL(bn)) {
995
0
        ret = 0;
996
0
    }
997
1.56k
    else {
998
        /* Set to value one. */
999
1.56k
        ret = wolfSSL_BN_set_word(bn, 1);
1000
1.56k
    }
1001
1002
1.56k
    return ret;
1003
1.56k
}
1004
1005
/* Get the value of the MP integer as a word.
1006
 *
1007
 * Assumes the MP integer value will fit in a word.
1008
 *
1009
 * @param [in] mp  MP integer.
1010
 * @return  Value of MP integer as an unsigned long.
1011
 */
1012
0
static WOLFSSL_BN_ULONG wolfssl_bn_get_word_1(mp_int *mp) {
1013
0
#if DIGIT_BIT >= (SIZEOF_LONG * CHAR_BIT)
1014
0
    return (WOLFSSL_BN_ULONG)mp->dp[0];
1015
#else
1016
    WOLFSSL_BN_ULONG ret = 0UL;
1017
    unsigned int i;
1018
1019
    for (i = 0; i < (unsigned int)mp->used; ++i) {
1020
        ret |= ((WOLFSSL_BN_ULONG)mp->dp[i]) << (DIGIT_BIT * i);
1021
    }
1022
1023
    return ret;
1024
#endif
1025
0
}
1026
1027
/* Return the value of big number as an unsigned long if possible.
1028
 *
1029
 * @param [in] bn  Big number to get value from.
1030
 * @return  Value or 0xFFFFFFFFL if bigger than unsigned long.
1031
 */
1032
WOLFSSL_BN_ULONG wolfSSL_BN_get_word(const WOLFSSL_BIGNUM* bn)
1033
0
{
1034
0
    WOLFSSL_BN_ULONG ret;
1035
1036
0
    WOLFSSL_ENTER("wolfSSL_BN_get_word");
1037
1038
    /* Validate parameter. */
1039
0
    if (BN_IS_NULL(bn)) {
1040
0
        WOLFSSL_MSG("Invalid argument");
1041
0
        ret = 0;
1042
0
    }
1043
    /* Check whether big number is to fit in an unsigned long. */
1044
0
    else if (wolfSSL_BN_num_bytes(bn) > (int)sizeof(unsigned long)) {
1045
0
        WOLFSSL_MSG("bignum is larger than unsigned long");
1046
0
        ret = WOLFSSL_BN_MAX_VAL;
1047
0
    }
1048
0
    else {
1049
        /* Get the word from the internal representation. */
1050
0
        ret = wolfssl_bn_get_word_1((mp_int*)bn->internal);
1051
0
    }
1052
1053
0
    return ret;
1054
0
}
1055
1056
/* Set the big number to the value in the word.
1057
 *
1058
 * Return code compliant with OpenSSL.
1059
 *
1060
 * @param [in, out] bn  Big number to set.
1061
 * @param [in       w   Word to set.
1062
 * @return  1 on success.
1063
 * @return  0 when bn is NULL or setting value failed.
1064
 */
1065
int wolfSSL_BN_set_word(WOLFSSL_BIGNUM* bn, unsigned long w)
1066
1.56k
{
1067
1.56k
    int ret = 1;
1068
1069
1.56k
    WOLFSSL_ENTER("wolfSSL_BN_set_word");
1070
1071
    /* Validate parameters. */
1072
1.56k
    if (BN_IS_NULL(bn)) {
1073
0
        WOLFSSL_MSG("bn NULL error");
1074
0
        ret = 0;
1075
0
    }
1076
1077
    /* Set the word into the internal representation. */
1078
1.56k
    if ((ret == 1) && (mp_set_int((mp_int*)bn->internal, w) != MP_OKAY)) {
1079
0
        WOLFSSL_MSG("mp_init_set_int error");
1080
0
        ret = 0;
1081
0
    }
1082
1083
1.56k
    return ret;
1084
1.56k
}
1085
1086
/*******************************************************************************
1087
 * Comparison APIs
1088
 ******************************************************************************/
1089
1090
/* Compares two big numbers. a <=> b
1091
 *
1092
 * NULL equals NULL
1093
 * NULL less than not NULL
1094
 * not NULL greater than NULL.
1095
 *
1096
 * Return compliant with OpenSSL.
1097
 *
1098
 * @param [in] bn  First big number to compare.
1099
 * @param [in] bn  Second big number to compare.
1100
 * @return  -1 when a is less than b (a < b).
1101
 * @return  0 when a is equal to b (a == b).
1102
 * @return  1 when a is greater than b (a > b).
1103
 * @return  0 when bn or internal representation of bn is NULL.
1104
 */
1105
int wolfSSL_BN_cmp(const WOLFSSL_BIGNUM* a, const WOLFSSL_BIGNUM* b)
1106
280
{
1107
280
    int ret;
1108
280
    int bIsNull;
1109
1110
280
    WOLFSSL_ENTER("wolfSSL_BN_cmp");
1111
1112
    /* Must know whether b is NULL. */
1113
280
    bIsNull = BN_IS_NULL(b);
1114
    /* Check whether a is NULL. */
1115
280
    if (BN_IS_NULL(a)) {
1116
0
        if (bIsNull) {
1117
            /* NULL equals NULL. */
1118
0
            ret = 0;
1119
0
        }
1120
0
        else {
1121
0
            ret = -1; /* NULL less than not NULL. */
1122
0
        }
1123
0
    }
1124
280
    else if (bIsNull) {
1125
        /* not NULL greater than NULL. */
1126
0
        ret = 1;
1127
0
    }
1128
280
    else {
1129
280
        PRAGMA_GCC_DIAG_PUSH
1130
280
        PRAGMA_GCC("GCC diagnostic ignored \"-Wduplicated-branches\"")
1131
        /* Compare big numbers with wolfCrypt. */
1132
280
        ret = mp_cmp((mp_int*)a->internal, (mp_int*)b->internal);
1133
        /* Convert wolfCrypt return value. */
1134
280
        if (ret == MP_EQ) {
1135
97
            ret = 0;
1136
97
        }
1137
183
        else if (ret == MP_GT) {
1138
63
            ret = 1;
1139
63
        }
1140
120
        else if (ret == MP_LT) {
1141
120
            ret = -1;
1142
120
        }
1143
0
        else {
1144
            /* ignored warning here because the same return value
1145
               was intentional */
1146
0
            ret = WOLFSSL_FATAL_ERROR; /* also -1 */
1147
0
        }
1148
280
        PRAGMA_GCC_DIAG_POP
1149
280
    }
1150
1151
280
    return ret;
1152
280
}
1153
1154
/* Same as above, but compare absolute value. */
1155
int wolfSSL_BN_ucmp(const WOLFSSL_BIGNUM* a, const WOLFSSL_BIGNUM* b)
1156
0
{
1157
0
    int ret = 0;
1158
0
    int bIsNull;
1159
1160
0
    WOLFSSL_ENTER("wolfSSL_BN_ucmp");
1161
1162
    /* Must know whether b is NULL. */
1163
0
    bIsNull = BN_IS_NULL(b);
1164
    /* Check whether a is NULL. */
1165
0
    if (BN_IS_NULL(a)) {
1166
0
        if (bIsNull) {
1167
            /* NULL equals NULL. */
1168
0
            ret = 0;
1169
0
        }
1170
0
        else {
1171
0
            ret = -1; /* NULL less than not NULL. */
1172
0
        }
1173
0
    }
1174
0
    else if (bIsNull) {
1175
        /* not NULL greater than NULL. */
1176
0
        ret = 1;
1177
0
    }
1178
0
    else {
1179
        /* Neither are NULL; copy to new instances and switch to positive if
1180
         * required, compare, and then free.  Must copy because there is
1181
         * possibility of switch to positive but they are declared const.
1182
         * wolfssl_bn_set_neg() only returns -1 if the bn is NULL, but we
1183
         * already check that so we can ignore the return code. Note for
1184
         * wolfSSL_BN_is_negative if n=1 then set to positive. */
1185
0
        WOLFSSL_BIGNUM* abs_a = wolfSSL_BN_dup(a);
1186
0
        WOLFSSL_BIGNUM* abs_b = wolfSSL_BN_dup(b);
1187
1188
0
        if (abs_a == NULL || abs_b == NULL) {
1189
0
            WOLFSSL_MSG("wolfSSL_BN_dup failed");
1190
0
            wolfSSL_BN_free(abs_a);
1191
0
            wolfSSL_BN_free(abs_b);
1192
0
            return WOLFSSL_FATAL_ERROR;
1193
0
        }
1194
1195
0
        if (wolfSSL_BN_is_negative(abs_a)) {
1196
0
            wolfssl_bn_set_neg(abs_a, 1);
1197
0
        }
1198
1199
0
        if (wolfSSL_BN_is_negative(abs_b)) {
1200
0
            wolfssl_bn_set_neg(abs_b, 1);
1201
0
        }
1202
1203
0
        ret = wolfSSL_BN_cmp(abs_a, abs_b);
1204
0
        wolfSSL_BN_free(abs_a);
1205
0
        wolfSSL_BN_free(abs_b);
1206
0
    }
1207
0
    return ret;
1208
0
}
1209
1210
/* Indicates whether a big number is the value 0.
1211
 *
1212
 * Return compliant with OpenSSL.
1213
 *
1214
 * @param [in] bn  Big number to use.
1215
 * @return  1 when number is zero.
1216
 * @return  0 when number is not zero.
1217
 * @return  0 when bn or internal representation of bn is NULL.
1218
 */
1219
int wolfSSL_BN_is_zero(const WOLFSSL_BIGNUM* bn)
1220
1.38k
{
1221
1.38k
    int ret;
1222
1223
1.38k
    WOLFSSL_ENTER("wolfSSL_BN_is_zero");
1224
1225
    /* Validate parameter. */
1226
1.38k
    if (BN_IS_NULL(bn)) {
1227
0
        ret = 0;
1228
0
    }
1229
1.38k
    else {
1230
        /* wolfCrypt checks whether value is 0. */
1231
1.38k
        ret = (mp_iszero((mp_int*)bn->internal) == MP_YES);
1232
1.38k
    }
1233
1234
1.38k
    return ret;
1235
1.38k
}
1236
1237
/* Indicates whether a big number is the value 1.
1238
 *
1239
 * Return compliant with OpenSSL.
1240
 *
1241
 * @param [in] bn  Big number to use.
1242
 * @return  1 when number is one.
1243
 * @return  0 when number is not one.
1244
 * @return  0 when bn or internal representation of bn is NULL.
1245
 */
1246
int wolfSSL_BN_is_one(const WOLFSSL_BIGNUM* bn)
1247
2.72k
{
1248
2.72k
    int ret;
1249
1250
2.72k
    WOLFSSL_ENTER("wolfSSL_BN_is_one");
1251
1252
    /* Validate parameter. */
1253
2.72k
    if (BN_IS_NULL(bn)) {
1254
0
        ret = 0;
1255
0
    }
1256
2.72k
    else {
1257
        /* wolfCrypt checks whether value is 1. */
1258
2.72k
        ret = (mp_cmp_d((mp_int*)bn->internal, 1) == MP_EQ);
1259
2.72k
    }
1260
1261
2.72k
    return ret;
1262
2.72k
}
1263
1264
/* Indicates whether a big number is the value passed in.
1265
 *
1266
 * Return compliant with OpenSSL.
1267
 *
1268
 * @param [in] bn  Big number to use.
1269
 * @return  1 when big number is the value.
1270
 * @return  0 when big number is not the value.
1271
 * @return  0 when bn or internal representation of bn is NULL.
1272
 */
1273
int wolfSSL_BN_is_word(const WOLFSSL_BIGNUM* bn, WOLFSSL_BN_ULONG w)
1274
0
{
1275
0
    int ret;
1276
1277
0
    WOLFSSL_ENTER("wolfSSL_BN_is_word");
1278
1279
    /* Validate parameter. */
1280
0
    if (BN_IS_NULL(bn)) {
1281
0
        WOLFSSL_MSG("bn NULL error");
1282
0
        ret = 0;
1283
0
    }
1284
0
    else
1285
#if DIGIT_BIT < (SIZEOF_LONG * CHAR_BIT)
1286
    /* When value is greater than what can be stored in one digit - special
1287
     * case. */
1288
    if (w > (WOLFSSL_BN_ULONG)MP_MASK) {
1289
        /* TODO: small stack */
1290
        mp_int w_mp;
1291
1292
        /* Create a MP to hold the number. */
1293
        if (mp_init(&w_mp) != MP_OKAY) {
1294
            ret = 0;
1295
        }
1296
        /* Set the value - held in more than one digit. */
1297
        else if (mp_set_int(&w_mp, w) != MP_OKAY) {
1298
            ret = 0;
1299
        }
1300
        else {
1301
            /* Compare MP representations. */
1302
            ret = (mp_cmp((mp_int *)bn->internal, &w_mp) == MP_EQ);
1303
            mp_free(&w_mp);
1304
        }
1305
    }
1306
    else
1307
#endif
1308
0
    {
1309
        /* wolfCrypt checks whether it is the value. */
1310
0
        ret = (mp_isword((mp_int*)bn->internal, (mp_digit)w) == MP_YES);
1311
0
    }
1312
1313
0
    return ret;
1314
0
}
1315
1316
1317
/*******************************************************************************
1318
 * Word operation APIs.
1319
 ******************************************************************************/
1320
1321
enum BN_WORD_OP {
1322
    BN_WORD_ADD = 0,
1323
    BN_WORD_SUB = 1,
1324
    BN_WORD_MUL = 2,
1325
    BN_WORD_DIV = 3,
1326
    BN_WORD_MOD = 4
1327
};
1328
1329
/* Helper function for word operations.
1330
 *
1331
 * @param [in, out] bn  Big number to operate on.
1332
 * @param [in]      w   Word to operate with.
1333
 * @param [in]      op  Operation to perform. See BN_WORD_OP for valid values.
1334
 * @param [out]     mod_res Result of the modulo operation.
1335
 * @return  1 on success.
1336
 * @return  0 on failure.
1337
 */
1338
static int bn_word_helper(const WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w,
1339
        enum BN_WORD_OP op, WOLFSSL_BN_ULONG* mod_res)
1340
0
{
1341
0
    int ret = 1;
1342
1343
0
    WOLFSSL_ENTER("bn_word_helper");
1344
1345
    /* Validate parameters. */
1346
0
    if (ret == 1 && BN_IS_NULL(bn)) {
1347
0
        WOLFSSL_MSG("bn NULL error");
1348
0
        ret = 0;
1349
0
    }
1350
1351
0
    if (ret == 1) {
1352
0
        int rc = MP_OKAY;
1353
#if DIGIT_BIT < (SIZEOF_LONG * CHAR_BIT)
1354
        /* When input 'w' is greater than what can be stored in one digit */
1355
        if (w > (WOLFSSL_BN_ULONG)MP_MASK) {
1356
            DECL_MP_INT_SIZE_DYN(w_mp, sizeof(WOLFSSL_BN_ULONG) * CHAR_BIT,
1357
                                       sizeof(WOLFSSL_BN_ULONG) * CHAR_BIT);
1358
            NEW_MP_INT_SIZE(w_mp, sizeof(WOLFSSL_BN_ULONG) * CHAR_BIT, NULL,
1359
                    DYNAMIC_TYPE_TMP_BUFFER);
1360
#ifdef MP_INT_SIZE_CHECK_NULL
1361
            if (w_mp == NULL) {
1362
                WOLFSSL_MSG("NEW_MP_INT_SIZE error");
1363
                ret = 0;
1364
            }
1365
#endif
1366
            if (ret == 1 && mp_set_int(w_mp, w) != MP_OKAY) {
1367
                WOLFSSL_MSG("mp_set_int error");
1368
                ret = 0;
1369
            }
1370
            if (ret == 1) {
1371
                switch (op) {
1372
                    case BN_WORD_ADD:
1373
                        rc = mp_add((mp_int*)bn->internal, w_mp,
1374
                                (mp_int*)bn->internal);
1375
                        break;
1376
                    case BN_WORD_SUB:
1377
                        rc = mp_sub((mp_int*)bn->internal, w_mp,
1378
                                (mp_int*)bn->internal);
1379
                        break;
1380
                    case BN_WORD_MUL:
1381
                        rc = mp_mul((mp_int*)bn->internal, w_mp,
1382
                                (mp_int*)bn->internal);
1383
                        break;
1384
                    case BN_WORD_DIV:
1385
                        rc = mp_div((mp_int*)bn->internal, w_mp,
1386
                                (mp_int*)bn->internal, NULL);
1387
                        break;
1388
                    case BN_WORD_MOD:
1389
                        rc = mp_mod((mp_int*) bn->internal, w_mp,
1390
                                w_mp);
1391
                        if (rc == MP_OKAY && mod_res != NULL)
1392
                            *mod_res = wolfssl_bn_get_word_1(w_mp);
1393
                        break;
1394
                    default:
1395
                        rc = WOLFSSL_NOT_IMPLEMENTED;
1396
                        break;
1397
                }
1398
            }
1399
            FREE_MP_INT_SIZE(w_mp, NULL, DYNAMIC_TYPE_RSA);
1400
        }
1401
        else
1402
#endif
1403
0
        {
1404
0
            switch (op) {
1405
0
                case BN_WORD_ADD:
1406
0
                    rc = mp_add_d((mp_int*)bn->internal, (mp_digit)w,
1407
0
                            (mp_int*)bn->internal);
1408
0
                    break;
1409
0
                case BN_WORD_SUB:
1410
0
                    rc = mp_sub_d((mp_int*)bn->internal, (mp_digit)w,
1411
0
                            (mp_int*)bn->internal);
1412
0
                    break;
1413
0
                case BN_WORD_MUL:
1414
0
                    rc = mp_mul_d((mp_int*)bn->internal, (mp_digit)w,
1415
0
                            (mp_int*)bn->internal);
1416
0
                    break;
1417
0
                case BN_WORD_DIV:
1418
0
#if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)
1419
/* copied from sp_int.h */
1420
0
#if (defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) || \
1421
0
    defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || \
1422
0
    defined(WC_MP_TO_RADIX)
1423
0
                    rc = mp_div_d((mp_int*)bn->internal, (mp_digit)w,
1424
0
                            (mp_int*)bn->internal, NULL);
1425
#else
1426
                    rc = WOLFSSL_NOT_IMPLEMENTED;
1427
#endif
1428
#else
1429
                    rc = WOLFSSL_NOT_IMPLEMENTED;
1430
#endif
1431
0
                    break;
1432
0
                case BN_WORD_MOD:
1433
0
                    {
1434
0
                        mp_digit _mod_res;
1435
0
                        rc = mp_mod_d((mp_int*) bn->internal, (mp_digit) w,
1436
0
                                &_mod_res);
1437
0
                        if (rc == MP_OKAY && mod_res != NULL)
1438
0
                            *mod_res = (WOLFSSL_BN_ULONG)_mod_res;
1439
0
                    }
1440
0
                    break;
1441
0
                default:
1442
0
                    rc = WOLFSSL_NOT_IMPLEMENTED;
1443
0
                    break;
1444
0
            }
1445
0
        }
1446
0
        if (ret == 1 && rc != MP_OKAY) {
1447
0
            WOLFSSL_MSG("mp word operation error or not implemented");
1448
0
            ret = 0;
1449
0
        }
1450
0
    }
1451
1452
0
    WOLFSSL_LEAVE("bn_word_helper", ret);
1453
1454
0
    return ret;
1455
0
}
1456
1457
/* Add a word to a big number.
1458
 *
1459
 * Return code compliant with OpenSSL.
1460
 *
1461
 * @param [in, out] bn   Big number to operate on.
1462
 * @param [in]      w    Word to operate with.
1463
 * @return  1 on success.
1464
 * @return  0 in failure.
1465
 */
1466
int wolfSSL_BN_add_word(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w)
1467
0
{
1468
0
    int ret;
1469
1470
0
    WOLFSSL_ENTER("wolfSSL_BN_add_word");
1471
1472
0
    ret = bn_word_helper(bn, w, BN_WORD_ADD, NULL);
1473
1474
0
    WOLFSSL_LEAVE("wolfSSL_BN_add_word", ret);
1475
1476
0
    return ret;
1477
0
}
1478
1479
/* Subtract a word from a big number.
1480
 *
1481
 * Return code compliant with OpenSSL.
1482
 *
1483
 * @param [in, out] bn   Big number to operate on.
1484
 * @param [in]      w    Word to operate with.
1485
 * @return  1 on success.
1486
 * @return  0 in failure.
1487
 */
1488
int wolfSSL_BN_sub_word(WOLFSSL_BIGNUM* bn, WOLFSSL_BN_ULONG w)
1489
0
{
1490
0
    int ret;
1491
1492
0
    WOLFSSL_ENTER("wolfSSL_BN_sub_word");
1493
1494
0
    ret = bn_word_helper(bn, w, BN_WORD_SUB, NULL);
1495
1496
0
    WOLFSSL_LEAVE("wolfSSL_BN_sub_word", ret);
1497
1498
0
    return ret;
1499
0
}
1500
1501
int wolfSSL_BN_mul_word(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w)
1502
0
{
1503
0
    int ret;
1504
1505
0
    WOLFSSL_ENTER("wolfSSL_BN_mul_word");
1506
1507
0
    ret = bn_word_helper(bn, w, BN_WORD_MUL, NULL);
1508
1509
0
    WOLFSSL_LEAVE("wolfSSL_BN_mul_word", ret);
1510
1511
0
    return ret;
1512
0
}
1513
1514
1515
int wolfSSL_BN_div_word(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w)
1516
0
{
1517
0
    int ret;
1518
1519
0
    WOLFSSL_ENTER("wolfSSL_BN_div_word");
1520
1521
0
    ret = bn_word_helper(bn, w, BN_WORD_DIV, NULL);
1522
1523
0
    WOLFSSL_LEAVE("wolfSSL_BN_div_word", ret);
1524
1525
0
    return ret;
1526
0
}
1527
1528
#if defined(WOLFSSL_KEY_GEN) && (!defined(NO_RSA) || !defined(NO_DH) || \
1529
    !defined(NO_DSA))
1530
/* Calculate bn modulo word w. bn % w
1531
 *
1532
 * Return code compliant with OpenSSL.
1533
 *
1534
 * @return  Word result on success
1535
 * @return  -1 on error
1536
 */
1537
WOLFSSL_BN_ULONG wolfSSL_BN_mod_word(const WOLFSSL_BIGNUM *bn,
1538
    WOLFSSL_BN_ULONG w)
1539
0
{
1540
0
    int ret;
1541
0
    WOLFSSL_BN_ULONG res = 0;
1542
1543
0
    WOLFSSL_ENTER("wolfSSL_BN_mod_word");
1544
1545
0
    ret = bn_word_helper(bn, w, BN_WORD_MOD, &res);
1546
1547
0
    WOLFSSL_LEAVE("wolfSSL_BN_mod_word", ret);
1548
1549
0
    return ret == 1 ? res : (WOLFSSL_BN_ULONG)-1;
1550
0
}
1551
#endif /* WOLFSSL_KEY_GEN && (!NO_RSA || !NO_DH || !NO_DSA) */
1552
1553
/*******************************************************************************
1554
 * Shift APIs
1555
 ******************************************************************************/
1556
1557
#ifndef WOLFSSL_SP_MATH
1558
/* Shift the value in bn left by n bits into r. r = bn << n
1559
 *
1560
 * Return code compliant with OpenSSL.
1561
 *
1562
 * @return  1 on success.
1563
 * @return  0 when r or bn or internal representation is NULL.
1564
 * @return  0 on failure.
1565
 */
1566
int wolfSSL_BN_lshift(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *bn, int n)
1567
0
{
1568
0
    int ret = 1;
1569
1570
0
    WOLFSSL_ENTER("wolfSSL_BN_lshift");
1571
1572
    /* Validate parameters. */
1573
0
    if (BN_IS_NULL(r) || BN_IS_NULL(bn)) {
1574
0
        WOLFSSL_MSG("bn NULL error");
1575
0
        ret = 0;
1576
0
    }
1577
0
    else if (n < 0) {
1578
0
        WOLFSSL_MSG("n value error");
1579
0
        ret = 0;
1580
0
    }
1581
1582
    /* Use wolfCrypt perform operation. */
1583
0
    if ((ret == 1) && (mp_mul_2d((mp_int*)bn->internal, n,
1584
0
            (mp_int*)r->internal) != MP_OKAY)) {
1585
0
        WOLFSSL_MSG("mp_mul_2d error");
1586
0
        ret = 0;
1587
0
    }
1588
1589
0
    return ret;
1590
0
}
1591
1592
/* Shift the value in bn right by n bits into r. r = bn >> n
1593
 *
1594
 * Return code compliant with OpenSSL.
1595
 *
1596
 * @return  1 on success.
1597
 * @return  0 when r or bn or internal representation is NULL.
1598
 * @return  0 on failure.
1599
 */
1600
int wolfSSL_BN_rshift(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *bn, int n)
1601
0
{
1602
0
    int ret = 1;
1603
1604
0
    WOLFSSL_ENTER("wolfSSL_BN_rshift");
1605
1606
    /* Validate parameters. */
1607
0
    if (BN_IS_NULL(r) || BN_IS_NULL(bn)) {
1608
0
        WOLFSSL_MSG("bn NULL error");
1609
0
        ret = 0;
1610
0
    }
1611
0
    else if (n < 0) {
1612
0
        WOLFSSL_MSG("n value error");
1613
0
        ret = 0;
1614
0
    }
1615
1616
    /* Use wolfCrypt perform operation. */
1617
0
    if ((ret == 1) && (mp_div_2d((mp_int*)bn->internal, n, (mp_int*)r->internal,
1618
0
            NULL) != MP_OKAY)) {
1619
0
        WOLFSSL_MSG("mp_mul_2d error");
1620
0
        ret = 0;
1621
0
    }
1622
1623
0
    return ret;
1624
0
}
1625
#endif
1626
1627
/*******************************************************************************
1628
 * Simple Math APIs
1629
 ******************************************************************************/
1630
1631
/* Add a to b into r. r = a + b
1632
 *
1633
 * Return code compliant with OpenSSL.
1634
 *
1635
 * @param [out] r  Big number to put result into.
1636
 * @param [in]  a  Big number to be added to.
1637
 * @param [in]  b  Big number to add with.
1638
 *
1639
 * @return  1 on success.
1640
 * @return  0 when r, a or b or internal representation is NULL.
1641
 * @return  0 on failure.
1642
 */
1643
int wolfSSL_BN_add(WOLFSSL_BIGNUM *r, WOLFSSL_BIGNUM *a, WOLFSSL_BIGNUM *b)
1644
7
{
1645
7
    int ret = 1;
1646
1647
7
    WOLFSSL_ENTER("wolfSSL_BN_add");
1648
1649
    /* Validate parameters. */
1650
7
    if (BN_IS_NULL(r) || BN_IS_NULL(a) || BN_IS_NULL(b)) {
1651
0
        WOLFSSL_MSG("bn NULL error");
1652
0
        ret = 0;
1653
0
    }
1654
1655
    /* Add the internal representations into internal representation. */
1656
7
    if ((ret == 1) && (mp_add((mp_int*)a->internal, (mp_int*)b->internal,
1657
7
            (mp_int*)r->internal) != MP_OKAY)) {
1658
0
        WOLFSSL_MSG("mp_add_d error");
1659
0
        ret = 0;
1660
0
    }
1661
1662
7
    return ret;
1663
7
}
1664
1665
/* Subtract a from b into r. r = a - b
1666
 *
1667
 * @param [out] r  Big number to put result into.
1668
 * @param [in]  a  Big number to be subtracted from.
1669
 * @param [in]  b  Big number to subtract with.
1670
 *
1671
 * @return  1 on success.
1672
 * @return  0 when r, a or b is NULL.
1673
 * @return  0 on failure.
1674
 */
1675
int wolfSSL_BN_sub(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* a,
1676
    const WOLFSSL_BIGNUM* b)
1677
11
{
1678
11
    int ret = 1;
1679
1680
11
    WOLFSSL_ENTER("wolfSSL_BN_sub");
1681
1682
    /* Validate parameters. */
1683
11
    if (BN_IS_NULL(r) || BN_IS_NULL(a) || BN_IS_NULL(b)) {
1684
0
        ret = 0;
1685
0
    }
1686
1687
    /* Have wolfCrypt perform operation with internal representations. */
1688
11
    if ((ret == 1) && (mp_sub((mp_int*)a->internal,(mp_int*)b->internal,
1689
11
            (mp_int*)r->internal) != MP_OKAY)) {
1690
0
        ret = 0;
1691
0
    }
1692
1693
11
    WOLFSSL_LEAVE("wolfSSL_BN_sub mp_sub", ret);
1694
11
    return ret;
1695
11
}
1696
1697
/* Multiply a with b into r. r = a * b
1698
 *
1699
 * @param [out] r    Big number to put result into.
1700
 * @param [in]  a    Big number to be multiplied.
1701
 * @param [in]  b    Big number to multiply with.
1702
 * @param [in]  ctx  BN context object. Unused.
1703
 *
1704
 * @return  1 on success.
1705
 * @return  0 when r, a or b is NULL.
1706
 * @return  0 when internal representation of r, a or b is NULL.
1707
 * @return  0 on failure.
1708
 */
1709
int wolfSSL_BN_mul(WOLFSSL_BIGNUM *r, WOLFSSL_BIGNUM *a, WOLFSSL_BIGNUM *b,
1710
    WOLFSSL_BN_CTX *ctx)
1711
0
{
1712
0
    int ret = 1;
1713
1714
0
    (void)ctx;
1715
1716
0
    WOLFSSL_ENTER("wolfSSL_BN_mul");
1717
1718
    /* Validate parameters. */
1719
0
    if (BN_IS_NULL(r) || BN_IS_NULL(a) || BN_IS_NULL(b)) {
1720
0
        ret = 0;
1721
0
    }
1722
1723
    /* Have wolfCrypt perform operation with internal representations. */
1724
0
    if ((ret == 1) && (mp_mul((mp_int*)a->internal, (mp_int*)b->internal,
1725
0
            (mp_int*)r->internal) != MP_OKAY)) {
1726
0
        ret = 0;
1727
0
    }
1728
1729
0
    WOLFSSL_LEAVE("wolfSSL_BN_mul", ret);
1730
0
    return ret;
1731
0
}
1732
1733
#ifndef WOLFSSL_SP_MATH
1734
/* Divide a by b into dv and put remainder into rem. dv = a / b, rem = a % b
1735
 *
1736
 * @param [out] dv   Big number to put division result into.
1737
 * @param [out] rem  Big number to put remainder into.
1738
 * @param [in]  a    Big number to be divided.
1739
 * @param [in]  b    Big number to divide with.
1740
 * @param [in]  ctx  BN context object. Unused.
1741
 *
1742
 * @return  1 on success.
1743
 * @return  0 when dv, rem, a or b is NULL.
1744
 * @return  0 when internal representation of dv, rem, a or b is NULL.
1745
 * @return  0 on failure.
1746
 */
1747
int wolfSSL_BN_div(WOLFSSL_BIGNUM* dv, WOLFSSL_BIGNUM* rem,
1748
    const WOLFSSL_BIGNUM* a, const WOLFSSL_BIGNUM* d, WOLFSSL_BN_CTX* ctx)
1749
0
{
1750
0
    int ret = 1;
1751
0
    WOLFSSL_BIGNUM* res = dv;
1752
1753
    /* BN context not needed. */
1754
0
    (void)ctx;
1755
1756
0
    WOLFSSL_ENTER("wolfSSL_BN_div");
1757
1758
0
    if (BN_IS_NULL(res)) {
1759
0
        res = wolfSSL_BN_new();
1760
0
    }
1761
1762
    /* Validate parameters. */
1763
0
    if (BN_IS_NULL(res) || BN_IS_NULL(rem) || BN_IS_NULL(a) || BN_IS_NULL(d)) {
1764
0
        ret = 0;
1765
0
    }
1766
1767
    /* Have wolfCrypt perform operation with internal representations. */
1768
0
    if ((ret == 1) && (mp_div((mp_int*)a->internal, (mp_int*)d->internal,
1769
0
            (mp_int*)res->internal, (mp_int*)rem->internal) != MP_OKAY)) {
1770
0
        ret = 0;
1771
0
    }
1772
1773
0
    if (res != dv)
1774
0
        wolfSSL_BN_free(res);
1775
1776
0
    WOLFSSL_LEAVE("wolfSSL_BN_div", ret);
1777
0
    return ret;
1778
0
}
1779
#endif
1780
1781
/* Calculate a mod b into r. r = a % b
1782
 *
1783
 * @param [out] r    Big number to put result into.
1784
 * @param [in]  a    Big number to reduced
1785
 * @param [in]  b    Big number to reduce with.
1786
 * @param [in]  ctx  BN context object. Unused.
1787
 *
1788
 * @return  1 on success.
1789
 * @return  0 when r, a or b is NULL.
1790
 * @return  0 on failure.
1791
 */
1792
int wolfSSL_BN_mod(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* a,
1793
                  const WOLFSSL_BIGNUM* b, const WOLFSSL_BN_CTX* c)
1794
32
{
1795
32
    int ret = 1;
1796
1797
32
    (void)c;
1798
1799
32
    WOLFSSL_ENTER("wolfSSL_BN_mod");
1800
1801
    /* Validate parameters. */
1802
32
    if (BN_IS_NULL(r) || BN_IS_NULL(a) || BN_IS_NULL(b)) {
1803
0
        ret = 0;
1804
0
    }
1805
1806
    /* Have wolfCrypt perform operation with internal representations. */
1807
32
    if ((ret == 1) && (mp_mod((mp_int*)a->internal,(mp_int*)b->internal,
1808
32
            (mp_int*)r->internal) != MP_OKAY)) {
1809
10
        ret = 0;
1810
10
    }
1811
1812
32
    WOLFSSL_LEAVE("wolfSSL_BN_mod mp_mod", ret);
1813
32
    return ret;
1814
32
}
1815
1816
/*******************************************************************************
1817
 * Math and Mod APIs
1818
 ******************************************************************************/
1819
1820
#ifndef WOLFSSL_SP_MATH
1821
/* Add a to b modulo m into r. r = a + b (mod m)
1822
 *
1823
 * @param [in, out] r    Big number to hold result.
1824
 * @param [in]      a    Big number to add to.
1825
 * @param [in]      b    Big number to add with.
1826
 * @param [in]      m    Big number that is the modulus.
1827
 * @param [in]      ctx  BN context. Not used.
1828
 * @return  1 on success.
1829
 * @return  0 when r, a or b or internal representation is NULL.
1830
 * @return  0 on calculation failure.
1831
 */
1832
int wolfSSL_BN_mod_add(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *a,
1833
    const WOLFSSL_BIGNUM *b, const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx)
1834
35
{
1835
35
    int ret = 1;
1836
1837
    /* BN context not needed. */
1838
35
    (void)ctx;
1839
1840
35
    WOLFSSL_ENTER("wolfSSL_BN_add");
1841
1842
    /* Validate parameters. */
1843
35
    if (BN_IS_NULL(r) || BN_IS_NULL(a) || BN_IS_NULL(b) || BN_IS_NULL(m)) {
1844
0
        WOLFSSL_MSG("bn NULL error");
1845
0
        ret = 0;
1846
0
    }
1847
1848
    /* Perform operation with wolfCrypt. */
1849
35
    if ((ret == 1) && (mp_addmod((mp_int*)a->internal, (mp_int*)b->internal,
1850
35
            (mp_int*)m->internal, (mp_int*)r->internal) != MP_OKAY)) {
1851
20
        WOLFSSL_MSG("mp_add_d error");
1852
20
        ret = 0;
1853
20
    }
1854
1855
35
    return ret;
1856
35
}
1857
#endif
1858
1859
/* Calculate a multiplied by b, mod m into r. r = (a * b) % m
1860
 *
1861
 * @param [out] r    Big number to put result into.
1862
 * @param [in]  a    Base as a big number.
1863
 * @param [in]  b    Multiplier as a big number.
1864
 * @param [in]  m    Modulus as a big number.
1865
 * @param [in]  ctx  BN context object. Unused.
1866
 *
1867
 * @return  1 on success.
1868
 * @return  0 when r, a, b or m is NULL.
1869
 * @return  0 on failure.
1870
 */
1871
int wolfSSL_BN_mod_mul(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *a,
1872
    const WOLFSSL_BIGNUM *b, const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx)
1873
27
{
1874
27
    int ret = 1;
1875
1876
    /* BN context not needed. */
1877
27
    (void)ctx;
1878
1879
27
    WOLFSSL_ENTER("wolfSSL_BN_mod_mul");
1880
1881
    /* Validate parameters. */
1882
27
    if (BN_IS_NULL(r) || BN_IS_NULL(a) || BN_IS_NULL(b) || BN_IS_NULL(m)) {
1883
0
        WOLFSSL_MSG("Bad Argument");
1884
0
        ret = 0;
1885
0
    }
1886
1887
    /* Have wolfCrypt perform operation with internal representations. */
1888
27
    if ((ret == 1) && (mp_mulmod((mp_int*)a->internal, (mp_int*)b->internal,
1889
27
            (mp_int*)m->internal, (mp_int*)r->internal)) != MP_OKAY) {
1890
10
        ret = 0;
1891
10
    }
1892
1893
27
    WOLFSSL_LEAVE("wolfSSL_BN_mod_mul", ret);
1894
27
    return ret;
1895
27
}
1896
1897
1898
/* Calculate a to the power of e, mod m into r. r = (a ^ e) % m
1899
 *
1900
 * @param [out] r    Big number to put result into.
1901
 * @param [in]  a    Base as a big number.
1902
 * @param [in]  e    Exponent as a big number.
1903
 * @param [in]  m    Modulus as a big number.
1904
 * @param [in]  ctx  BN context object. Unused.
1905
 *
1906
 * @return  1 on success.
1907
 * @return  0 when r, a, p or m is NULL.
1908
 * @return  0 on failure.
1909
 */
1910
int wolfSSL_BN_mod_exp(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *a,
1911
    const WOLFSSL_BIGNUM *e, const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx)
1912
289
{
1913
289
    int ret = 1;
1914
1915
    /* BN context not needed. */
1916
289
    (void)ctx;
1917
1918
289
    WOLFSSL_ENTER("wolfSSL_BN_mod_exp");
1919
1920
    /* Validate parameters. */
1921
289
    if (BN_IS_NULL(r) || BN_IS_NULL(a) || BN_IS_NULL(e) || BN_IS_NULL(m)) {
1922
0
        WOLFSSL_MSG("Bad Argument");
1923
0
        ret = 0;
1924
0
    }
1925
1926
    /* Have wolfCrypt perform operation with internal representations. */
1927
289
    if ((ret == 1) && (mp_exptmod((mp_int*)a->internal, (mp_int*)e->internal,
1928
289
            (mp_int*)m->internal, (mp_int*)r->internal)) != MP_OKAY) {
1929
19
        ret = 0;
1930
19
    }
1931
1932
289
    WOLFSSL_LEAVE("wolfSSL_BN_mod_exp", ret);
1933
289
    return ret;
1934
289
}
1935
1936
/* Calculate the modular inverse of a mod m into r. r = a^-1 mod m
1937
 *
1938
 * A new big number is allocated when r is NULL.
1939
 *
1940
 * @param [in, out] r    Big number to hold result. May be NULL.
1941
 * @param [in]      a    Big number to invert.
1942
 * @param [in]      m    Big number that is the modulus.
1943
 * @param [in]      ctx  BN context. Not used.
1944
 * @return  Big number holding result on success.
1945
 * @return  NULL on failure.
1946
 */
1947
WOLFSSL_BIGNUM *wolfSSL_BN_mod_inverse(WOLFSSL_BIGNUM *r, WOLFSSL_BIGNUM *a,
1948
    const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx)
1949
230
{
1950
230
    int err = 0;
1951
230
    WOLFSSL_BIGNUM* t = NULL;
1952
1953
    /* BN context not needed. */
1954
230
    (void)ctx;
1955
1956
230
    WOLFSSL_ENTER("wolfSSL_BN_mod_inverse");
1957
1958
    /* Validate parameters. */
1959
230
    if (BN_IS_NULL(a) || BN_IS_NULL(m) || ((r != NULL) &&
1960
230
            (r->internal == NULL))) {
1961
0
        WOLFSSL_MSG("a or n NULL error");
1962
0
        err = 1;
1963
0
    }
1964
    /* Check whether we have a result big number. */
1965
230
    if ((!err) && (r == NULL)) {
1966
        /* Allocate a new big number to hold result and be returned. */
1967
0
        t = wolfSSL_BN_new();
1968
0
        if (t == NULL){
1969
0
            WOLFSSL_MSG("WolfSSL_BN_new() failed");
1970
0
            err = 1;
1971
0
        }
1972
0
        r = t;
1973
0
    }
1974
1975
    /* Compute inverse of a modulo n and return in r */
1976
230
    if ((!err) && (mp_invmod((mp_int *)a->internal, (mp_int *)m->internal,
1977
230
            (mp_int*)r->internal) != MP_OKAY)) {
1978
87
        WOLFSSL_MSG("mp_invmod() error");
1979
87
        err = 1;
1980
87
    }
1981
1982
230
    if (err) {
1983
87
        wolfSSL_BN_free(t);
1984
87
        r = NULL;
1985
87
    }
1986
230
    return r;
1987
230
}
1988
1989
/*******************************************************************************
1990
 * Other Math APIs
1991
 ******************************************************************************/
1992
1993
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)
1994
/* Needed to get mp_gcd. */
1995
/* Greatest Common Divisor (GCM) of a and b into r. r = GCD(a, b)
1996
 *
1997
 * @param [out] r    Big number to put result into.
1998
 * @param [in]  a    First big number.
1999
 * @param [in]  b    Second big number.
2000
 * @param [in]  ctx  BN context object. Unused.
2001
 *
2002
 * @return  1 on success.
2003
 * @return  0 when r, a or b is NULL.
2004
 * @return  0 when internal representation of r, a or b is NULL.
2005
 * @return  0 on failure.
2006
 */
2007
int wolfSSL_BN_gcd(WOLFSSL_BIGNUM* r, WOLFSSL_BIGNUM* a, WOLFSSL_BIGNUM* b,
2008
    WOLFSSL_BN_CTX* ctx)
2009
0
{
2010
0
    int ret = 1;
2011
2012
    /* BN context not needed. */
2013
0
    (void)ctx;
2014
2015
0
    WOLFSSL_ENTER("wolfSSL_BN_gcd");
2016
2017
    /* Validate parameters. */
2018
0
    if (BN_IS_NULL(r) || BN_IS_NULL(a) || BN_IS_NULL(b)) {
2019
0
        ret = 0;
2020
0
    }
2021
2022
    /* Have wolfCrypt perform operation with internal representations. */
2023
0
    if ((ret == 1) && (mp_gcd((mp_int*)a->internal, (mp_int*)b->internal,
2024
0
            (mp_int*)r->internal) != MP_OKAY)) {
2025
0
        ret = 0;
2026
0
    }
2027
2028
0
    WOLFSSL_LEAVE("wolfSSL_BN_gcd", ret);
2029
0
    return ret;
2030
0
}
2031
#endif /* !NO_RSA && WOLFSSL_KEY_GEN */
2032
2033
/*******************************************************************************
2034
 * Random APIs
2035
 ******************************************************************************/
2036
2037
/* Generates a random number up to bits long.
2038
 *
2039
 * @param [in, out] bn       Big number to generate into.
2040
 * @param [in]      bits     Number of bits in word.
2041
 * @param [in]      top      Whether top bits must be set.
2042
 *                           Valid values: WOLFSSL_BN_RAND_TOP_ANY,
2043
 *                           WOLFSSL_BN_RAND_TOP_ONE, WOLFSSL_BN_RAND_TOP_TWO.
2044
 * @param [in]      bottom   Whether bottom bit must be set.
2045
 *                           Valid values: WOLFSSL_BN_RAND_BOTTOM_ANY,
2046
                             WOLFSSL_BN_RAND_BOTTOM_ODD.
2047
 * @return  1 on success.
2048
 * @return  0 when bn is NULL.
2049
 * @return  0 when bits is invalid.
2050
 * @return  0 when bits and top/bottom are invalid.
2051
 * @return  0 when generation fails.
2052
 */
2053
int wolfSSL_BN_rand(WOLFSSL_BIGNUM* bn, int bits, int top, int bottom)
2054
0
{
2055
0
    int ret = 1;
2056
0
    word32 len = (word32)((bits + 7) / 8);
2057
0
    WC_RNG* rng;
2058
2059
0
    WOLFSSL_ENTER("wolfSSL_BN_rand");
2060
2061
    /* Validate parameters. */
2062
0
    if (BN_IS_NULL(bn)) {
2063
0
        WOLFSSL_MSG("Bad argument - bn");
2064
0
        ret = 0;
2065
0
    }
2066
0
    else if (bits < 0) {
2067
0
        WOLFSSL_MSG("Bad argument - bits < 0");
2068
0
        ret = 0;
2069
0
    }
2070
0
    else if ((bits == 0) && ((bottom != WOLFSSL_BN_RAND_BOTTOM_ANY) ||
2071
0
            (top != WOLFSSL_BN_RAND_TOP_ANY))) {
2072
0
        WOLFSSL_MSG("Bad top/bottom - bits == 0");
2073
0
        ret = 0;
2074
0
    }
2075
0
    else if ((bits == 1) && (top > WOLFSSL_BN_RAND_TOP_ONE)) {
2076
0
        WOLFSSL_MSG("Bad top - bits == 1");
2077
0
        ret = 0;
2078
0
    }
2079
2080
    /* Handle simple case of zero bits. */
2081
0
    if ((ret == 1) && (bits == 0)) {
2082
0
        mp_zero((mp_int*)bn->internal);
2083
0
    }
2084
0
    else if (ret == 1) {
2085
0
        byte* buff = NULL;
2086
2087
        /* Get random to global random to generate bits. */
2088
0
        if ((rng = wolfssl_make_global_rng()) == NULL) {
2089
0
            WOLFSSL_MSG("Failed to use global RNG.");
2090
0
            ret = 0;
2091
0
        }
2092
2093
        /* Allocate buffer to hold generated bits. */
2094
0
        if ((ret == 1) && ((buff = (byte*)XMALLOC(len, NULL,
2095
0
                DYNAMIC_TYPE_TMP_BUFFER)) == NULL)) {
2096
0
            WOLFSSL_MSG("Failed to allocate buffer.");
2097
0
            ret = 0;
2098
0
        }
2099
        /* Generate bytes to cover bits. */
2100
0
        if ((ret == 1) && wc_RNG_GenerateBlock(rng, buff, len) != 0) {
2101
0
            WOLFSSL_MSG("wc_RNG_GenerateBlock failed");
2102
0
            ret = 0;
2103
0
        }
2104
        /* Read bytes in to big number. */
2105
0
        if ((ret == 1) && mp_read_unsigned_bin((mp_int*)bn->internal, buff, len)
2106
0
                != MP_OKAY) {
2107
0
            WOLFSSL_MSG("mp_read_unsigned_bin failed");
2108
0
            ret = 0;
2109
0
        }
2110
        /* Dispose of buffer - no longer needed. */
2111
0
        XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2112
2113
0
        if (ret == 1) {
2114
            /* Truncate to requested bit length. */
2115
0
            mp_rshb((mp_int*)bn->internal, 8 - (bits % 8));
2116
0
        }
2117
2118
        /* Set top bit when required. */
2119
0
        if ((ret == 1) && (top >= WOLFSSL_BN_RAND_TOP_ONE) &&
2120
0
                (mp_set_bit((mp_int*)bn->internal, bits - 1) != MP_OKAY)) {
2121
0
            WOLFSSL_MSG("Failed to set top bit");
2122
0
            ret = 0;
2123
0
        }
2124
        /* Set second top bit when required. */
2125
0
        if ((ret == 1) && (top > WOLFSSL_BN_RAND_TOP_ONE) &&
2126
0
                (mp_set_bit((mp_int*)bn->internal, bits - 2) != MP_OKAY)) {
2127
0
            WOLFSSL_MSG("Failed to set second top bit");
2128
0
            ret = 0;
2129
0
        }
2130
        /* Set bottom bit when required. */
2131
0
        if ((ret == 1) && (bottom == WOLFSSL_BN_RAND_BOTTOM_ODD) &&
2132
0
                (mp_set_bit((mp_int*)bn->internal, 0) != MP_OKAY)) {
2133
0
            WOLFSSL_MSG("Failed to set 0th bit");
2134
0
            ret = 0;
2135
0
        }
2136
0
    }
2137
2138
0
    WOLFSSL_LEAVE("wolfSSL_BN_rand", ret);
2139
2140
0
    return ret;
2141
0
}
2142
2143
/* Generates a pseudo-random number up to bits long.
2144
 *
2145
 * Implemented using wolfSSL_BN_rand().
2146
 *
2147
 * @param [in, out] bn       Big number to generate into.
2148
 * @param [in]      bits     Number of bits in word.
2149
 * @param [in]      top      Whether top bits must be set.
2150
 *                           Valid values: WOLFSSL_BN_RAND_TOP_ANY,
2151
 *                           WOLFSSL_BN_RAND_TOP_ONE, WOLFSSL_BN_RAND_TOP_TWO.
2152
 * @param [in]      bottom   Whether bottom bit must be set.
2153
 *                           Valid values: WOLFSSL_BN_RAND_BOTTOM_ANY,
2154
                             WOLFSSL_BN_RAND_BOTTOM_ODD.
2155
 * @return  1 on success.
2156
 * @return  0 when bn is NULL.
2157
 * @return  0 when bits is invalid.
2158
 * @return  0 when bits and top/bottom are invalid.
2159
 * @return  0 when generation fails.
2160
 */
2161
int wolfSSL_BN_pseudo_rand(WOLFSSL_BIGNUM* bn, int bits, int top, int bottom)
2162
0
{
2163
0
    return wolfSSL_BN_rand(bn, bits, top, bottom);
2164
0
}
2165
2166
/* Maximum number of trials to attempt at generating a number in range. */
2167
0
#define RANGE_MAX_TRIALS    100
2168
2169
/* Generate big number to be a value between 0 and range-1.
2170
 *
2171
 * N = length of range input var
2172
 *
2173
 * Generate N-bit length numbers until generated number is less than range
2174
 * @param [in] r      Big number to generate into.
2175
 * @param [in] range  The upper limit of generated number.
2176
 * @return  1 on success.
2177
 * @return  0 on failure.
2178
 */
2179
int wolfSSL_BN_rand_range(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *range)
2180
0
{
2181
0
    int ret = 1;
2182
2183
0
    WOLFSSL_ENTER("wolfSSL_BN_rand_range");
2184
2185
    /* Validate parameters. */
2186
0
    if (BN_IS_NULL(r) || BN_IS_NULL(range)) {
2187
0
        WOLFSSL_MSG("Bad parameter");
2188
0
        ret = 0;
2189
0
    }
2190
2191
0
    if (ret == 1) {
2192
        /* Calculate number of bits in modulus. */
2193
0
        int n = wolfSSL_BN_num_bits(range);
2194
2195
0
        if (n <= 1) {
2196
            /* Modulus is 0 or 1. */
2197
0
            wolfSSL_BN_zero(r);
2198
0
        }
2199
0
        else {
2200
0
            int i;
2201
            /* Try generating a number in range for a limited number of trials.
2202
             */
2203
0
            for (i = 0; (ret == 1) && (i < RANGE_MAX_TRIALS); i++) {
2204
                /* Generate a random number in range. */
2205
0
                if (wolfSSL_BN_pseudo_rand(r, n, WOLFSSL_BN_RAND_TOP_ANY,
2206
0
                        WOLFSSL_BN_RAND_BOTTOM_ANY) == 0) {
2207
0
                    WOLFSSL_MSG("wolfSSL_BN_rand error");
2208
0
                    ret = 0;
2209
0
                }
2210
                /* Check if in range. */
2211
0
                else if (wolfSSL_BN_cmp(r, range) < 0) {
2212
0
                    break;
2213
0
                }
2214
0
            }
2215
            /* Fail if max trial attempts made. */
2216
0
            if (i >= RANGE_MAX_TRIALS) {
2217
0
                WOLFSSL_MSG("wolfSSL_BN_rand_range too many iterations");
2218
0
                ret = 0;
2219
0
            }
2220
0
        }
2221
0
    }
2222
2223
0
    return ret;
2224
0
}
2225
2226
/*******************************************************************************
2227
 * Prime APIs
2228
 ******************************************************************************/
2229
2230
#if defined(WOLFSSL_KEY_GEN) && (!defined(NO_RSA) || !defined(NO_DH) || \
2231
    !defined(NO_DSA))
2232
2233
/* Generate a prime number.
2234
 *
2235
 * @param [in, out] prime  Big number to generate into.
2236
 * @param [in]      bits   Number of bits in generated number.
2237
 * @param [in]      safe   Whether number must be a safe prime.
2238
 * @param [in]      add    Value to add when generating. Not used.
2239
 * @param [in]      rem    Remainder of number modulo add. Not used.
2240
 * @param [in]      cb     Generation callback. Not used.
2241
 * @return  1 on success.
2242
 * @return  0 when prime is NULL.
2243
 * @return  0 when safe required or add or rem is not NULL.
2244
 * @return  0 on generation failure.
2245
 */
2246
int wolfSSL_BN_generate_prime_ex(WOLFSSL_BIGNUM* prime, int bits,
2247
    int safe, const WOLFSSL_BIGNUM* add, const WOLFSSL_BIGNUM* rem,
2248
    WOLFSSL_BN_GENCB* cb)
2249
0
{
2250
0
    int ret = 1;
2251
0
    WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
2252
0
    WC_RNG* rng = NULL;
2253
0
    int localRng = 0;
2254
2255
    /* Callback not used. */
2256
0
    (void)cb;
2257
2258
0
    WOLFSSL_ENTER("wolfSSL_BN_generate_prime_ex");
2259
2260
    /* Check unsupported parameters. */
2261
0
    if ((safe == 1) || (add != NULL) || (rem != NULL)) {
2262
0
        ret = 0;
2263
0
    }
2264
    /* Validate parameters. */
2265
0
    else if (BN_IS_NULL(prime)) {
2266
0
        ret = 0;
2267
0
    }
2268
2269
    /* Create a new RNG or use global. */
2270
0
    if ((ret == 1) && ((rng = wolfssl_make_rng(tmpRng, &localRng)) == NULL)) {
2271
0
        ret = 0;
2272
0
    }
2273
2274
    /* Use wolfCrypt to generate a prime. */
2275
0
    if ((ret == 1) && (mp_rand_prime((mp_int*)prime->internal, (bits + 7) / 8,
2276
0
            rng, NULL) != MP_OKAY)) {
2277
0
        ret = 0;
2278
0
    }
2279
2280
0
    if (localRng) {
2281
        /* Dispose of local RNG that was created. */
2282
0
        wc_FreeRng(rng);
2283
0
        WC_FREE_VAR_EX(rng, NULL, DYNAMIC_TYPE_RNG);
2284
0
    }
2285
2286
0
    WOLFSSL_LEAVE("wolfSSL_BN_generate_prime_ex", ret);
2287
2288
0
    return ret;
2289
0
}
2290
2291
/* Check whether a big number is prime.
2292
 *
2293
 * Return code compliant with OpenSSL.
2294
 *
2295
 * @param [in] bn      Big number to check.
2296
 * @param [in] checks  Number of Miller-Rabin tests to perform.
2297
 * @param [in] ctx     BN context. Not used.
2298
 * @param [in] cb      Generation callback. Not used.
2299
 * @return  1 when number is prime.
2300
 * @return  0 when number is not prime.
2301
 * @return  -1 when bn is NULL or failure when checking.
2302
 */
2303
int wolfSSL_BN_is_prime_ex(const WOLFSSL_BIGNUM *bn, int checks,
2304
    WOLFSSL_BN_CTX *ctx, WOLFSSL_BN_GENCB *cb)
2305
0
{
2306
0
    int ret = 1;
2307
0
    WC_RNG* rng    = NULL;
2308
0
    WC_DECLARE_VAR(tmpRng, WC_RNG, 1, 0);
2309
0
    int localRng = 0;
2310
0
    int res = MP_NO;
2311
2312
    /* BN context not needed. */
2313
0
    (void)ctx;
2314
0
    (void)cb;
2315
2316
0
    WOLFSSL_ENTER("wolfSSL_BN_is_prime_ex");
2317
2318
0
    if (BN_IS_NULL(bn)) {
2319
0
        WOLFSSL_MSG("bn NULL error");
2320
0
        ret = WOLFSSL_FATAL_ERROR;
2321
0
    }
2322
2323
    /* Create a new RNG or use global. */
2324
0
    if ((ret == 1) && ((rng = wolfssl_make_rng(tmpRng, &localRng)) == NULL)) {
2325
0
        ret = WOLFSSL_FATAL_ERROR;
2326
0
    }
2327
2328
0
    if ((ret == 1) && (mp_prime_is_prime_ex((mp_int*)bn->internal, checks, &res,
2329
0
            rng) != MP_OKAY)) {
2330
0
        WOLFSSL_MSG("mp_prime_is_prime_ex error");
2331
0
        ret = WOLFSSL_FATAL_ERROR;
2332
0
    }
2333
2334
0
    if (localRng) {
2335
0
        wc_FreeRng(rng);
2336
0
        WC_FREE_VAR_EX(rng, NULL, DYNAMIC_TYPE_RNG);
2337
0
    }
2338
2339
0
    if ((ret != -1) && (res != MP_YES)) {
2340
0
        WOLFSSL_MSG("mp_prime_is_prime_ex not prime");
2341
0
        ret = 0;
2342
0
    }
2343
2344
0
    return ret;
2345
0
}
2346
2347
#endif /* WOLFSSL_KEY_GEN && (!NO_RSA || !NO_DH || !NO_DSA) */
2348
2349
/*******************************************************************************
2350
 * Print APIs
2351
 ******************************************************************************/
2352
2353
#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) && \
2354
    defined(XFPRINTF)
2355
/* Print big number to file pointer.
2356
 *
2357
 * Return code compliant with OpenSSL.
2358
 *
2359
 * @param [in] fp  File pointer.
2360
 * @param [in] bn  Big number to print.
2361
 * @return  1 on success.
2362
 * @return  0 when fp is a bad file pointer.
2363
 * @return  0 when bn is NULL.
2364
 * @return  0 when creating hex string fails.
2365
 * @return  0 when printing fails.
2366
 */
2367
int wolfSSL_BN_print_fp(XFILE fp, const WOLFSSL_BIGNUM *bn)
2368
0
{
2369
0
    int ret = 1;
2370
0
    char* buf = NULL;
2371
2372
0
    WOLFSSL_ENTER("wolfSSL_BN_print_fp");
2373
2374
    /* Validate parameters. */
2375
0
    if ((fp == XBADFILE) || BN_IS_NULL(bn)) {
2376
0
        WOLFSSL_MSG("bn NULL error");
2377
0
        ret = 0;
2378
0
    }
2379
2380
    /* Create a hex string of big number. */
2381
0
    if ((ret == 1) && ((buf = wolfSSL_BN_bn2hex(bn)) == NULL)) {
2382
0
        WOLFSSL_MSG("wolfSSL_BN_bn2hex failure");
2383
0
        ret = 0;
2384
0
    }
2385
2386
    /* Print hex string to file pointer. */
2387
0
    if ((ret == 1) && (XFPRINTF(fp, "%s", buf) < 0)) {
2388
0
        ret = 0;
2389
0
    }
2390
2391
    /* Dispose of any allocated data. */
2392
0
    XFREE(buf, NULL, DYNAMIC_TYPE_OPENSSL);
2393
2394
0
    return ret;
2395
0
}
2396
#endif /* !NO_FILESYSTEM && XFPRINTF */
2397
2398
#ifndef NO_WOLFSSL_BN_CTX
2399
/*******************************************************************************
2400
 * BN_CTX APIs
2401
 ******************************************************************************/
2402
2403
/* Create a new BN context object.
2404
 *
2405
 * @return  BN context object on success.
2406
 * @return  NULL on failure.
2407
 */
2408
WOLFSSL_BN_CTX* wolfSSL_BN_CTX_new(void)
2409
3.60k
{
2410
3.60k
    WOLFSSL_BN_CTX* ctx = NULL;
2411
2412
3.60k
    WOLFSSL_ENTER("wolfSSL_BN_CTX_new");
2413
3.60k
    ctx = (WOLFSSL_BN_CTX*)XMALLOC(sizeof(WOLFSSL_BN_CTX), NULL,
2414
3.60k
            DYNAMIC_TYPE_OPENSSL);
2415
3.60k
    if (ctx != NULL) {
2416
3.60k
        XMEMSET(ctx, 0, sizeof(WOLFSSL_BN_CTX));
2417
3.60k
    }
2418
2419
3.60k
    return ctx;
2420
3.60k
}
2421
2422
2423
#ifndef NO_WOLFSSL_STUB
2424
/* deprecated
2425
 *
2426
 * Initialize a BN context object.
2427
 * This function was removed in OpenSSL 1.1.0 and later.
2428
 * Keeping a stub function here for older applications that have BN_CTX_init()
2429
 * calls.
2430
 *
2431
 * @param [in] ctx  Dummy BN context.
2432
 */
2433
void wolfSSL_BN_CTX_init(WOLFSSL_BN_CTX* ctx)
2434
0
{
2435
0
    (void)ctx;
2436
0
    WOLFSSL_ENTER("wolfSSL_BN_CTX_init");
2437
0
    WOLFSSL_STUB("wolfSSL_BN_CTX_init");
2438
0
    WOLFSSL_MSG("wolfSSL_BN_CTX_init is deprecated");
2439
0
}
2440
#endif
2441
2442
2443
/* Free a BN context object.
2444
 *
2445
 * @param [in] ctx  BN context object.
2446
 */
2447
void wolfSSL_BN_CTX_free(WOLFSSL_BN_CTX* ctx)
2448
3.60k
{
2449
3.60k
    WOLFSSL_ENTER("wolfSSL_BN_CTX_free");
2450
3.60k
    if (ctx != NULL) {
2451
3.60k
        while (ctx->list != NULL) {
2452
0
            struct WOLFSSL_BN_CTX_LIST* tmp = ctx->list;
2453
0
            ctx->list = ctx->list->next;
2454
0
            wolfSSL_BN_free(tmp->bn);
2455
0
            XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL);
2456
0
        }
2457
3.60k
        XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL);
2458
3.60k
    }
2459
3.60k
}
2460
2461
/* Get a big number from the BN context.
2462
 *
2463
 * @param [in] ctx  BN context object.
2464
 * @return  Big number on success.
2465
 * @return  NULL on failure.
2466
 */
2467
WOLFSSL_BIGNUM *wolfSSL_BN_CTX_get(WOLFSSL_BN_CTX *ctx)
2468
0
{
2469
0
    WOLFSSL_BIGNUM* bn = NULL;
2470
2471
0
    WOLFSSL_ENTER("wolfSSL_BN_CTX_get");
2472
0
    if (ctx != NULL) {
2473
0
        struct WOLFSSL_BN_CTX_LIST* node = (struct WOLFSSL_BN_CTX_LIST*)XMALLOC(
2474
0
                sizeof(struct WOLFSSL_BN_CTX_LIST), NULL, DYNAMIC_TYPE_OPENSSL);
2475
0
        if (node != NULL) {
2476
0
            XMEMSET(node, 0, sizeof(struct WOLFSSL_BN_CTX_LIST));
2477
0
            bn = node->bn = wolfSSL_BN_new();
2478
0
            if (node->bn != NULL) {
2479
0
                node->next = ctx->list;
2480
0
                ctx->list = node;
2481
0
            }
2482
0
            else {
2483
0
                XFREE(node, NULL, DYNAMIC_TYPE_OPENSSL);
2484
0
                node = NULL;
2485
0
            }
2486
0
        }
2487
0
    }
2488
2489
0
    return bn;
2490
0
}
2491
2492
#ifndef NO_WOLFSSL_STUB
2493
/* Start stack of temporary big numbers.
2494
 *
2495
 * Newly allocated big numbers are returned instead of having a stack.
2496
 *
2497
 * @param [in] ctx  BN context. Not used.
2498
 */
2499
void wolfSSL_BN_CTX_start(WOLFSSL_BN_CTX *ctx)
2500
0
{
2501
0
    (void)ctx;
2502
2503
0
    WOLFSSL_ENTER("wolfSSL_BN_CTX_start");
2504
0
    WOLFSSL_STUB("BN_CTX_start");
2505
0
    WOLFSSL_MSG("wolfSSL_BN_CTX_start TBD");
2506
0
}
2507
#endif
2508
2509
#endif /* NO_WOLFSSL_BN_CTX */
2510
2511
/*******************************************************************************
2512
 * BN_MONT_CTX APIs
2513
 ******************************************************************************/
2514
2515
WOLFSSL_BN_MONT_CTX* wolfSSL_BN_MONT_CTX_new(void)
2516
0
{
2517
    /* wolfcrypt doesn't need BN MONT context. */
2518
0
    static int mont;
2519
0
    WOLFSSL_ENTER("wolfSSL_BN_MONT_CTX_new");
2520
0
    return (WOLFSSL_BN_MONT_CTX*)&mont;
2521
0
}
2522
2523
void wolfSSL_BN_MONT_CTX_free(WOLFSSL_BN_MONT_CTX *mont)
2524
0
{
2525
0
    (void)mont;
2526
0
    WOLFSSL_ENTER("wolfSSL_BN_MONT_CTX_free");
2527
    /* Don't do anything since using dummy, static BN context. */
2528
0
}
2529
2530
int wolfSSL_BN_MONT_CTX_set(WOLFSSL_BN_MONT_CTX *mont,
2531
        const WOLFSSL_BIGNUM *mod, WOLFSSL_BN_CTX *ctx)
2532
0
{
2533
0
    (void) mont;
2534
0
    (void) mod;
2535
0
    (void) ctx;
2536
0
    WOLFSSL_ENTER("wolfSSL_BN_MONT_CTX_set");
2537
0
    return WOLFSSL_SUCCESS;
2538
0
}
2539
2540
/* Calculate r = a ^ p % m.
2541
 *
2542
 * @param [out] r    Big number to store the result.
2543
 * @param [in]  a    Base as an unsigned long.
2544
 * @param [in]  p    Exponent as a big number.
2545
 * @param [in]  m    Modulus as a big number.
2546
 * @param [in]  ctx  BN context object. Unused.
2547
 * @param [in]  mont Montgomery context object. Unused.
2548
 *
2549
 * @return  1 on success.
2550
 * @return  0 on failure.
2551
 */
2552
int wolfSSL_BN_mod_exp_mont_word(WOLFSSL_BIGNUM *r, WOLFSSL_BN_ULONG a,
2553
        const WOLFSSL_BIGNUM *p, const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx,
2554
        WOLFSSL_BN_MONT_CTX *mont)
2555
0
{
2556
0
    WOLFSSL_BIGNUM* tmp = NULL;
2557
0
    int ret = WOLFSSL_SUCCESS;
2558
2559
0
    (void)mont;
2560
0
    WOLFSSL_ENTER("wolfSSL_BN_mod_exp_mont_word");
2561
2562
0
    if (ret == WOLFSSL_SUCCESS && (tmp = wolfSSL_BN_new()) == NULL) {
2563
0
        WOLFSSL_MSG("wolfSSL_BN_new failed");
2564
0
        ret = WOLFSSL_FAILURE;
2565
0
    }
2566
0
    if (ret == WOLFSSL_SUCCESS && (wolfSSL_BN_set_word(tmp, (unsigned long)a))
2567
0
                                   == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) {
2568
0
        WOLFSSL_MSG("wolfSSL_BN_set_word failed");
2569
0
        ret = WOLFSSL_FAILURE;
2570
0
    }
2571
0
    if (ret == WOLFSSL_SUCCESS)
2572
0
        ret = wolfSSL_BN_mod_exp(r, tmp, p, m, ctx);
2573
2574
0
    wolfSSL_BN_free(tmp);
2575
0
    return ret;
2576
0
}
2577
2578
#endif /* OPENSSL_EXTRA */
2579
2580
#endif /* !WOLFSSL_SSL_BN_INCLUDED */
2581