Coverage Report

Created: 2025-07-23 06:59

/src/wolfssl-fastmath/wolfcrypt/src/tfm.c
Line
Count
Source (jump to first uncovered line)
1
/* tfm.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
/*
25
 * Based on public domain TomsFastMath 0.10 by Tom St Denis, tomstdenis@iahu.ca,
26
 * http://math.libtomcrypt.com
27
 */
28
29
/**
30
 *  Edited by Moises Guimaraes (moises@wolfssl.com)
31
 *  to fit wolfSSL's needs.
32
 */
33
34
#ifdef USE_FAST_MATH
35
36
#ifdef NO_INLINE
37
    #include <wolfssl/wolfcrypt/misc.h>
38
#else
39
    #define WOLFSSL_MISC_INCLUDED
40
    #include <wolfcrypt/src/misc.c>
41
#endif
42
43
#include <wolfssl/wolfcrypt/random.h>
44
#include <wolfssl/wolfcrypt/tfm.h>
45
#include <wolfcrypt/src/asm.c>  /* will define asm MACROS or C ones */
46
#include <wolfssl/wolfcrypt/wolfmath.h> /* common functions */
47
48
#ifdef WOLFSSL_ESPIDF
49
    #include <esp_log.h>
50
    #include <wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h>
51
#endif
52
53
#if defined(WOLFSSL_ESP32_CRYPT_RSA_PRI)
54
    static const char* TAG = "TFM"; /* esp log breadcrumb */
55
    #if !defined(NO_WOLFSSL_ESP32_CRYPT_RSA_PRI)
56
        /* Each individual math HW can be turned on or off.
57
         * Listed in order of complexity and historical difficulty. */
58
        #define WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL
59
        #define WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD
60
        #define WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD
61
    #endif
62
63
    #if defined(NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL)
64
        #undef WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL
65
    #endif
66
67
    #if defined(NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD)
68
        #undef WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD
69
    #endif
70
71
    #if defined(NO_WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD)
72
        #undef WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD
73
    #endif
74
75
    /* Note with HW there's a ESP_RSA_EXPT_XBITS setting
76
     * as for some small numbers, SW may be faster.
77
     * See ESP_LOGV messages for ESP_RSA_EXPT_XBITS values. */
78
79
#endif /* WOLFSSL_ESP32_CRYPT_RSA_PRI */
80
81
#if defined(FREESCALE_LTC_TFM)
82
    #include <wolfssl/wolfcrypt/port/nxp/ksdk_port.h>
83
#endif
84
#ifdef WOLFSSL_DEBUG_MATH
85
    #include <stdio.h>
86
#endif
87
88
#if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)
89
#ifdef __cplusplus
90
    extern "C" {
91
#endif
92
WOLFSSL_LOCAL int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod,
93
    mp_int* res);
94
WOLFSSL_LOCAL int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod,
95
    mp_int* res);
96
WOLFSSL_LOCAL int sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod,
97
    mp_int* res);
98
WOLFSSL_LOCAL int sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod,
99
    mp_int* res);
100
WOLFSSL_LOCAL int sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod,
101
    mp_int* res);
102
#ifdef __cplusplus
103
    } /* extern "C" */
104
#endif
105
#endif
106
107
108
#if !defined(WOLFSSL_SP_MATH) && !defined(WOLFSSL_SP_MATH_ALL)
109
/* math settings check */
110
word32 CheckRunTimeSettings(void)
111
0
{
112
0
    return CTC_SETTINGS;
113
0
}
114
115
/* math settings size check */
116
word32 CheckRunTimeFastMath(void)
117
0
{
118
0
    return FP_SIZE;
119
0
}
120
#endif
121
122
123
/* Functions */
124
125
int fp_add(fp_int *a, fp_int *b, fp_int *c)
126
0
{
127
0
  int sa, sb;
128
0
  int ret = FP_OKAY;
129
130
  /* get sign of both inputs */
131
0
  sa = a->sign;
132
0
  sb = b->sign;
133
134
  /* handle two cases, not four */
135
0
  if (sa == sb) {
136
    /* both positive or both negative */
137
    /* add their magnitudes, copy the sign */
138
0
    c->sign = sa;
139
0
    ret = s_fp_add (a, b, c);
140
0
  } else {
141
    /* one positive, the other negative */
142
    /* subtract the one with the greater magnitude from */
143
    /* the one of the lesser magnitude.  The result gets */
144
    /* the sign of the one with the greater magnitude. */
145
0
    if (fp_cmp_mag (a, b) == FP_LT) {
146
0
      c->sign = sb;
147
0
      s_fp_sub (b, a, c);
148
0
    } else {
149
0
      c->sign = sa;
150
0
      s_fp_sub (a, b, c);
151
0
    }
152
0
  }
153
154
0
  return ret;
155
0
}
156
157
/* unsigned addition */
158
int s_fp_add(fp_int *a, fp_int *b, fp_int *c)
159
0
{
160
0
  int      x, y, oldused;
161
0
  fp_word  t;
162
163
0
  y       = MAX(a->used, b->used);
164
0
  oldused = MIN(c->used, FP_SIZE);   /* help static analysis w/ largest size */
165
0
  c->used = y;
166
167
0
  t = 0;
168
#ifdef HONOR_MATH_USED_LENGTH
169
  for (x = 0; x < y; x++) {
170
      if ( (x < a->used) && (x < b->used) ) {
171
          /* x is less than both [a].used and [b].used, so we add both */
172
                  t += ((fp_word)a->dp[x])    +    ((fp_word)b->dp[x]);
173
      }
174
      else {
175
          /* Here we honor the actual [a].used and [b].used values
176
           * and NOT assume that values beyond [used] are zero. */
177
          if ((x >= a->used) && (x < b->used)) {
178
                  /* x more than [a].used, [b] ok, so just add [b] */
179
                  t += /* ((fp_word)(0))      + */ ((fp_word)b->dp[x]);
180
          }
181
          else {
182
              if ((x < a->used) && (x >= b->used)) {
183
                  /* x more than [b].used, [a] ok, so just add [a] */
184
                  t += ((fp_word)a->dp[x]) /* +     (fp_word)(0) */;
185
              }
186
              else {
187
                  /* we should never get here, as a.used cannot be greater
188
                   * than b.used, while b.used is greater than a.used! */
189
               /* t += 0 + 0 */
190
              }
191
          }
192
      }
193
      c->dp[x]   = (fp_digit)t;
194
      t        >>= DIGIT_BIT;
195
  }
196
197
#else
198
  /* the original code */
199
0
  for (x = 0; x < y; x++) {
200
0
      t         += ((fp_word)a->dp[x]) + ((fp_word)b->dp[x]);
201
0
      c->dp[x]   = (fp_digit)t;
202
0
      t        >>= DIGIT_BIT;
203
0
  }
204
0
#endif /* HONOR_MATH_USED_LENGTH */
205
206
0
  if (t != 0) {
207
0
     if (x == FP_SIZE)
208
0
         return FP_VAL;
209
0
     c->dp[c->used++] = (fp_digit)t;
210
0
     ++x;
211
0
  }
212
213
0
  c->used = x;
214
215
  /* zero any excess digits on the destination that we didn't write to */
216
0
  for (; x < oldused; x++) {
217
0
     c->dp[x] = 0;
218
0
  }
219
0
  fp_clamp(c);
220
0
  return FP_OKAY;
221
0
}
222
223
/* c = a - b */
224
int fp_sub(fp_int *a, fp_int *b, fp_int *c)
225
0
{
226
0
  int sa, sb;
227
0
  int ret = FP_OKAY;
228
229
0
  sa = a->sign;
230
0
  sb = b->sign;
231
232
0
  if (sa != sb) {
233
    /* subtract a negative from a positive, OR */
234
    /* subtract a positive from a negative. */
235
    /* In either case, ADD their magnitudes, */
236
    /* and use the sign of the first number. */
237
0
    c->sign = sa;
238
0
    ret = s_fp_add (a, b, c);
239
0
  } else {
240
    /* subtract a positive from a positive, OR */
241
    /* subtract a negative from a negative. */
242
    /* First, take the difference between their */
243
    /* magnitudes, then... */
244
0
    if (fp_cmp_mag (a, b) != FP_LT) {
245
      /* Copy the sign from the first */
246
0
      c->sign = sa;
247
      /* The first has a larger or equal magnitude */
248
0
      s_fp_sub (a, b, c);
249
0
    } else {
250
      /* The result has the *opposite* sign from */
251
      /* the first number. */
252
0
      c->sign = (sa == FP_ZPOS) ? FP_NEG : FP_ZPOS;
253
      /* The second has a larger magnitude */
254
0
      s_fp_sub (b, a, c);
255
0
    }
256
0
  }
257
0
  return ret;
258
0
}
259
260
/* unsigned subtraction ||a|| >= ||b|| ALWAYS! */
261
void s_fp_sub(fp_int *a, fp_int *b, fp_int *c)
262
0
{
263
0
  int      x, oldbused, oldused;
264
0
  fp_word  t;
265
266
0
  oldused  = c->used;
267
0
  oldbused = b->used;
268
0
  c->used  = a->used;
269
0
  t       = 0;
270
0
  for (x = 0; x < oldbused; x++) {
271
0
     t         = ((fp_word)a->dp[x]) - (((fp_word)b->dp[x]) + t);
272
0
     c->dp[x]  = (fp_digit)t;
273
0
     t         = (t >> DIGIT_BIT)&1;
274
0
  }
275
0
  for (; x < a->used; x++) {
276
0
     t         = ((fp_word)a->dp[x]) - t;
277
0
     c->dp[x]  = (fp_digit)t;
278
0
     t         = (t >> DIGIT_BIT)&1;
279
0
   }
280
281
  /* zero any excess digits on the destination that we didn't write to */
282
0
  for (; x < oldused; x++) {
283
0
     c->dp[x] = 0;
284
0
  }
285
0
  fp_clamp(c);
286
0
}
287
288
/* c = a * b */
289
int fp_mul(fp_int *A, fp_int *B, fp_int *C)
290
0
{
291
0
    int   ret = FP_OKAY;
292
0
    int   y, yy, oldused;
293
294
0
    oldused = C->used;
295
296
0
    y  = MAX(A->used, B->used);
297
0
    yy = MIN(A->used, B->used);
298
299
    /* fail if we are out of range */
300
0
    if (y + yy >= FP_SIZE) {
301
0
       ret = FP_VAL;
302
0
       goto clean;
303
0
    }
304
305
#if defined(WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL)
306
    if (esp_hw_validation_active()) {
307
        ESP_LOGV(TAG, "Skipping call to esp_mp_mul "
308
                      "during active validation.");
309
    }
310
    else {
311
        ret = esp_mp_mul(A, B, C); /* HW accelerated multiply  */
312
        switch (ret) {
313
            case MP_OKAY:
314
                goto clean; /* success */
315
                break;
316
317
            case WC_NO_ERR_TRACE(WC_HW_WAIT_E): /* MP_HW_BUSY math HW busy, fall back */
318
            case MP_HW_FALLBACK:    /* forced fallback from HW to SW */
319
            case MP_HW_VALIDATION_ACTIVE: /* use SW to compare to HW */
320
                /* fall back to software, below */
321
                break;
322
323
            default:
324
                /* Once we've failed, exit without trying to continue.
325
                 * We may have mangled operands: (e.g. Z = X * Z)
326
                 * Future implementation may consider saving operands,
327
                 * but errors should never occur. */
328
                goto clean;  /* error */
329
                break;
330
        }
331
    }
332
    /* fall through to software calcs */
333
#endif /* WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL */
334
335
    /* pick a comba (unrolled 4/8/16/32 x or rolled) based on the size
336
       of the largest input.  We also want to avoid doing excess mults if the
337
       inputs are not close to the next power of two.  That is, for example,
338
       if say y=17 then we would do (32-17)^2 = 225 unneeded multiplications
339
    */
340
341
#if defined(TFM_MUL3) && FP_SIZE >= 6
342
        if (y <= 3) {
343
           ret = fp_mul_comba3(A,B,C);
344
           goto clean;
345
        }
346
#endif
347
0
#if defined(TFM_MUL4) && FP_SIZE >= 8
348
0
        if (y == 4) {
349
0
           ret = fp_mul_comba4(A,B,C);
350
0
           goto clean;
351
0
        }
352
0
#endif
353
#if defined(TFM_MUL6) && FP_SIZE >= 12
354
        if (y <= 6) {
355
           ret = fp_mul_comba6(A,B,C);
356
           goto clean;
357
        }
358
#endif
359
#if defined(TFM_MUL7) && FP_SIZE >= 14
360
        if (y == 7) {
361
           ret = fp_mul_comba7(A,B,C);
362
           goto clean;
363
        }
364
#endif
365
#if defined(TFM_MUL8) && FP_SIZE >= 16
366
        if (y == 8) {
367
           ret = fp_mul_comba8(A,B,C);
368
           goto clean;
369
        }
370
#endif
371
#if defined(TFM_MUL9) && FP_SIZE >= 18
372
        if (y == 9) {
373
           ret = fp_mul_comba9(A,B,C);
374
           goto clean;
375
        }
376
#endif
377
#if defined(TFM_MUL12) && FP_SIZE >= 24
378
        if (y <= 12) {
379
           ret = fp_mul_comba12(A,B,C);
380
           goto clean;
381
        }
382
#endif
383
#if defined(TFM_MUL17) && FP_SIZE >= 34
384
        if (y <= 17) {
385
           ret = fp_mul_comba17(A,B,C);
386
           goto clean;
387
        }
388
#endif
389
390
#if defined(TFM_SMALL_SET) && FP_SIZE >= 32
391
        if (y <= 16) {
392
           ret = fp_mul_comba_small(A,B,C);
393
           goto clean;
394
        }
395
#endif
396
#if defined(TFM_MUL20) && FP_SIZE >= 40
397
        if (y <= 20) {
398
           ret = fp_mul_comba20(A,B,C);
399
           goto clean;
400
        }
401
#endif
402
#if defined(TFM_MUL24) && FP_SIZE >= 48
403
        if (yy >= 16 && y <= 24) {
404
           ret = fp_mul_comba24(A,B,C);
405
           goto clean;
406
        }
407
#endif
408
#if defined(TFM_MUL28) && FP_SIZE >= 56
409
        if (yy >= 20 && y <= 28) {
410
           ret = fp_mul_comba28(A,B,C);
411
           goto clean;
412
        }
413
#endif
414
#if defined(TFM_MUL32) && FP_SIZE >= 64
415
        if (yy >= 24 && y <= 32) {
416
           ret = fp_mul_comba32(A,B,C);
417
           goto clean;
418
        }
419
#endif
420
#if defined(TFM_MUL48) && FP_SIZE >= 96
421
        if (yy >= 40 && y <= 48) {
422
          ret = fp_mul_comba48(A,B,C);
423
          goto clean;
424
        }
425
#endif
426
#if defined(TFM_MUL64) && FP_SIZE >= 128
427
        if (yy >= 56 && y <= 64) {
428
           ret = fp_mul_comba64(A,B,C);
429
           goto clean;
430
        }
431
#endif
432
0
        ret = fp_mul_comba(A,B,C);
433
434
0
clean:
435
    /* zero any excess digits on the destination that we didn't write to */
436
0
    for (y = C->used; y >= 0 && y < oldused; y++) {
437
0
        C->dp[y] = 0;
438
0
    }
439
440
0
    return ret;
441
0
}
442
443
int fp_mul_2(fp_int * a, fp_int * b)
444
0
{
445
0
  int     x, oldused;
446
447
  /* Make sure value to double and result are in range. */
448
0
  if ((a->used > (FP_SIZE-1)) || ((a->used == (FP_SIZE - 1)) &&
449
0
              ((a->dp[FP_SIZE - 1] & ((fp_digit)1 << (DIGIT_BIT - 1))) != 0))) {
450
0
    return FP_VAL;
451
0
  }
452
453
0
  oldused = b->used;
454
0
  b->used = a->used;
455
456
0
  {
457
0
    fp_digit r, rr, *tmpa, *tmpb;
458
459
    /* alias for source */
460
0
    tmpa = a->dp;
461
462
    /* alias for dest */
463
0
    tmpb = b->dp;
464
465
    /* carry */
466
0
    r = 0;
467
0
    for (x = 0; x < a->used; x++) {
468
469
      /* get what will be the *next* carry bit from the
470
       * MSB of the current digit
471
       */
472
0
      rr = *tmpa >> ((fp_digit)(DIGIT_BIT - 1));
473
474
      /* now shift up this digit, add in the carry [from the previous] */
475
0
      *tmpb++ = ((*tmpa++ << ((fp_digit)1)) | r);
476
477
      /* copy the carry that would be from the source
478
       * digit into the next iteration
479
       */
480
0
      r = rr;
481
0
    }
482
483
    /* new leading digit? */
484
0
    if (r != 0) {
485
      /* add a MSB which is always 1 at this point */
486
0
      *tmpb = 1;
487
0
      ++(b->used);
488
0
    }
489
490
    /* zero any excess digits on the destination that we didn't write to */
491
0
    tmpb = b->dp + b->used;
492
0
    for (x = b->used; x < oldused; x++) {
493
0
      *tmpb++ = 0;
494
0
    }
495
0
  }
496
0
  b->sign = a->sign;
497
498
0
  return FP_OKAY;
499
0
}
500
501
/* c = a * b */
502
int fp_mul_d(fp_int *a, fp_digit b, fp_int *c)
503
0
{
504
0
   fp_word  w;
505
0
   int      x, oldused;
506
507
0
   oldused = c->used;
508
0
   c->used = a->used;
509
0
   c->sign = a->sign;
510
0
   w       = 0;
511
0
   for (x = 0; x < a->used; x++) {
512
0
       w         = ((fp_word)a->dp[x]) * ((fp_word)b) + w;
513
0
       c->dp[x]  = (fp_digit)w;
514
0
       w         = w >> DIGIT_BIT;
515
0
   }
516
0
   if (w != 0) {
517
0
      if (a->used == FP_SIZE)
518
0
          return FP_VAL;
519
0
      c->dp[c->used++] = (fp_digit) w;
520
0
      ++x;
521
0
   }
522
523
   /* zero any excess digits on the destination that we didn't write to */
524
   /* also checking FP_SIZE here for static analysis */
525
0
   for (; x < oldused && x < FP_SIZE; x++) {
526
0
      c->dp[x] = 0;
527
0
   }
528
529
0
   fp_clamp(c);
530
0
   return FP_OKAY;
531
0
}
532
533
/* c = a * 2**d */
534
int fp_mul_2d(fp_int *a, int b, fp_int *c)
535
0
{
536
0
   fp_digit carry, carrytmp, shift;
537
0
   int x;
538
539
   /* copy it */
540
0
   fp_copy(a, c);
541
542
   /* handle whole digits */
543
0
   if (b >= DIGIT_BIT) {
544
0
      int ret = fp_lshd(c, b/DIGIT_BIT);
545
0
      if (ret != FP_OKAY)
546
0
         return ret;
547
0
   }
548
0
   b %= DIGIT_BIT;
549
550
   /* shift the digits */
551
0
   if (b != 0) {
552
0
      carry = 0;
553
0
      shift = DIGIT_BIT - b;
554
0
      for (x = 0; x < c->used; x++) {
555
0
          carrytmp = c->dp[x] >> shift;
556
0
          c->dp[x] = (c->dp[x] << b) + carry;
557
0
          carry = carrytmp;
558
0
      }
559
      /* store last carry if room */
560
0
      if (carry && x < FP_SIZE) {
561
0
         c->dp[c->used++] = carry;
562
0
      }
563
0
      if (x == FP_SIZE)
564
0
         return FP_VAL;
565
0
   }
566
0
   fp_clamp(c);
567
0
   return FP_OKAY;
568
0
}
569
570
/* generic PxQ multiplier */
571
#if defined(HAVE_INTEL_MULX)
572
573
WC_INLINE static int fp_mul_comba_mulx(fp_int *A, fp_int *B, fp_int *C)
574
575
{
576
   int       ix, iy, iz, pa;
577
   fp_int    *dst;
578
#ifndef WOLFSSL_SMALL_STACK
579
   fp_int    tmp[1];
580
#else
581
   fp_int    *tmp;
582
#endif
583
   fp_digit  carry;
584
585
   /* Variables used but not seen by cppcheck. */
586
   (void)ix; (void)iy; (void)iz;
587
588
#ifdef WOLFSSL_SMALL_STACK
589
   tmp = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);
590
   if (tmp == NULL)
591
       return FP_MEM;
592
#endif
593
594
   /* get size of output and trim */
595
   pa = A->used + B->used;
596
   if (pa >= FP_SIZE) {
597
      pa = FP_SIZE-1;
598
   }
599
600
   /* Always take branch to use tmp variable. This avoids a cache attack for
601
    * determining if C equals A */
602
   if (1) {
603
      fp_init(tmp);
604
      dst = tmp;
605
   }
606
607
   TFM_INTEL_MUL_COMBA(A, B, carry, dst) ;
608
609
  dst->used = pa;
610
  dst->sign = A->sign ^ B->sign;
611
  fp_clamp(dst);
612
  fp_copy(dst, C);
613
614
#ifdef WOLFSSL_SMALL_STACK
615
  XFREE(tmp, NULL, DYNAMIC_TYPE_BIGINT);
616
#endif
617
618
  return FP_OKAY;
619
}
620
#endif
621
622
/*  C = (A * B)   */
623
int fp_mul_comba(fp_int *A, fp_int *B, fp_int *C)
624
0
{
625
0
   int       ret = 0;
626
0
   int       ix, iy, iz, tx, ty, pa;
627
0
   fp_digit  c0, c1, c2, *tmpx, *tmpy;
628
0
   fp_int    *dst;
629
#ifndef WOLFSSL_SMALL_STACK
630
   fp_int    tmp[1];
631
#else
632
0
   fp_int    *tmp;
633
0
#endif
634
635
0
   if (A->used + B->used >= FP_SIZE) return FP_VAL;
636
637
0
   IF_HAVE_INTEL_MULX(ret = fp_mul_comba_mulx(A, B, C), return ret) ;
638
639
0
#ifdef WOLFSSL_SMALL_STACK
640
0
   tmp = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);
641
0
   if (tmp == NULL)
642
0
       return FP_MEM;
643
0
#endif
644
645
0
   COMBA_START;
646
0
   COMBA_CLEAR;
647
648
   /* get size of output and trim */
649
0
   pa = A->used + B->used;
650
0
   if (pa >= FP_SIZE) {
651
0
      pa = FP_SIZE-1;
652
0
   }
653
654
   /* Always take branch to use tmp variable. This avoids a cache attack for
655
    * determining if C equals A */
656
0
   if (1) {
657
0
      fp_init(tmp);
658
0
      dst = tmp;
659
0
   }
660
661
0
   for (ix = 0; ix < pa; ix++) {
662
      /* get offsets into the two bignums */
663
0
      ty = MIN(ix, (B->used > 0 ? B->used - 1 : 0));
664
0
      tx = ix - ty;
665
666
      /* setup temp aliases */
667
0
      tmpx = A->dp + tx;
668
0
      tmpy = B->dp + ty;
669
670
      /* this is the number of times the loop will iterate, essentially its
671
         while (tx++ < a->used && ty-- >= 0) { ... }
672
       */
673
0
      iy = MIN(A->used-tx, ty+1);
674
675
      /* execute loop */
676
0
      COMBA_FORWARD;
677
0
      for (iz = 0; iz < iy; ++iz) {
678
0
          fp_digit _tmpx = *tmpx++;
679
0
          fp_digit _tmpy = *tmpy--;
680
0
          MULADD(_tmpx, _tmpy);
681
0
      }
682
683
      /* store term */
684
0
      COMBA_STORE(dst->dp[ix]);
685
0
  }
686
0
  COMBA_FINI;
687
688
0
  dst->used = pa;
689
690
  /* warning: WOLFSSL_SP_INT_NEGATIVE may disable negative numbers */
691
0
  dst->sign = A->sign ^ B->sign;
692
0
  fp_clamp(dst);
693
0
  fp_copy(dst, C);
694
695
  /* Variables used but not seen by cppcheck. */
696
0
  (void)c0; (void)c1; (void)c2;
697
698
0
#ifdef WOLFSSL_SMALL_STACK
699
0
  XFREE(tmp, NULL, DYNAMIC_TYPE_BIGINT);
700
0
#endif
701
0
  return ret;
702
0
}
703
704
/* a/b => cb + d == a */
705
int fp_div(fp_int *a, fp_int *b, fp_int *c, fp_int *d)
706
0
{
707
0
  int     n, t, i, norm, neg;
708
0
  int     ret;
709
#ifndef WOLFSSL_SMALL_STACK
710
  fp_int  q[1], x[1], y[1], t1[1], t2[1];
711
#else
712
0
  fp_int  *q, *x, *y, *t1, *t2;
713
0
#endif
714
715
  /* is divisor zero ? */
716
0
  if (fp_iszero (b) == FP_YES) {
717
0
    return FP_VAL;
718
0
  }
719
720
  /* if a < b then q=0, r = a */
721
0
  if (fp_cmp_mag (a, b) == FP_LT)
722
0
  {
723
0
    if (d != NULL) {
724
0
      fp_copy (a, d);
725
0
    }
726
0
    if (c != NULL) {
727
0
      fp_zero (c);
728
0
    }
729
0
    return FP_OKAY;
730
0
  }
731
732
0
#ifdef WOLFSSL_SMALL_STACK          /* 0  1  2  3   4  */
733
  /* allocate 5 elements of fp_int for q, x, y, t1, t2 */
734
0
  q = (fp_int*)XMALLOC(sizeof(fp_int) * 5, NULL, DYNAMIC_TYPE_BIGINT);
735
0
  if (q == NULL) {
736
0
      return FP_MEM;
737
0
  }
738
0
  x = &q[1]; y = &q[2]; t1 = &q[3]; t2 = &q[4];
739
0
#endif
740
741
0
  fp_init(q);
742
  /* qb + d = a, and b is an integer > 0, therefore q <= a */
743
0
  q->used = a->used;
744
745
0
  fp_init(t1);
746
0
  fp_init(t2);
747
748
  /* Init a copy (y) of the input (b) and
749
  ** Init a copy (x) of the input (a)
750
  **
751
  ** ALERT: Not calling fp_init_copy() as some compiler optimization settings
752
  ** such as -O2 will complain that (x) or (y) "may be used uninitialized".
753
  ** The fp_init() is here only to appease the compiler.  */
754
0
  fp_init(x);
755
0
  fp_copy(a, x); /* copy (src = a) to (dst = x) */
756
757
0
  fp_init(y);
758
0
  fp_copy(b, y); /* copy (src = b) to (dst = y) */
759
760
  /* fix the sign */
761
0
  neg = (a->sign == b->sign) ? FP_ZPOS : FP_NEG;
762
0
  x->sign = y->sign = FP_ZPOS;
763
764
  /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */
765
0
  norm = fp_count_bits(y) % DIGIT_BIT;
766
0
  if (norm < (int)(DIGIT_BIT-1)) {
767
0
    norm = (DIGIT_BIT-1) - norm;
768
0
    ret = fp_mul_2d (x, norm, x);
769
0
    if (ret != FP_OKAY) {
770
0
    #ifdef WOLFSSL_SMALL_STACK
771
0
      XFREE(q, NULL, DYNAMIC_TYPE_BIGINT);
772
0
    #endif
773
0
      return ret;
774
0
    }
775
0
    ret = fp_mul_2d (y, norm, y);
776
0
    if (ret != FP_OKAY) {
777
0
    #ifdef WOLFSSL_SMALL_STACK
778
0
      XFREE(q, NULL, DYNAMIC_TYPE_BIGINT);
779
0
    #endif
780
0
      return ret;
781
0
    }
782
0
  } else {
783
0
    norm = 0;
784
0
  }
785
786
  /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */
787
0
  n = x->used - 1;
788
0
  t = y->used - 1;
789
790
  /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */
791
0
  ret = fp_lshd (y, n - t); /* y = y*b**{n-t} */
792
0
  if (ret != FP_OKAY) {
793
0
  #ifdef WOLFSSL_SMALL_STACK
794
0
    XFREE(q, NULL, DYNAMIC_TYPE_BIGINT);
795
0
  #endif
796
0
    return ret;
797
0
  }
798
799
0
  while (fp_cmp (x, y) != FP_LT) {
800
0
    ++(q->dp[n - t]);
801
0
    ret = fp_sub (x, y, x);
802
0
    if (ret != FP_OKAY) {
803
0
    #ifdef WOLFSSL_SMALL_STACK
804
0
      XFREE(q, NULL, DYNAMIC_TYPE_BIGINT);
805
0
    #endif
806
0
      return ret;
807
0
    }
808
0
  }
809
810
  /* reset y by shifting it back down */
811
0
  fp_rshd (y, n - t);
812
813
  /* step 3. for i from n down to (t + 1) */
814
0
  for (i = n; i >= (t + 1); i--) {
815
0
    if (i > x->used) {
816
0
      continue;
817
0
    }
818
819
    /* step 3.1 if xi == yt then set q{i-t-1} to b-1,
820
     * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
821
0
    if (x->dp[i] == y->dp[t]) {
822
0
      q->dp[i - t - 1] = (fp_digit) ((((fp_word)1) << DIGIT_BIT) - 1);
823
0
    } else {
824
0
      fp_word tmp;
825
0
      tmp = ((fp_word) x->dp[i]) << ((fp_word) DIGIT_BIT);
826
0
      tmp |= ((fp_word) x->dp[i - 1]);
827
#ifdef WOLFSSL_LINUXKM
828
      /* Linux kernel macro for in-place 64 bit integer division. */
829
      do_div(tmp, (fp_word)y->dp[t]);
830
#else
831
0
      tmp /= ((fp_word)y->dp[t]);
832
0
#endif
833
0
      q->dp[i - t - 1] = (fp_digit) (tmp);
834
0
    }
835
836
    /* while (q{i-t-1} * (yt * b + y{t-1})) >
837
             xi * b**2 + xi-1 * b + xi-2
838
839
       do q{i-t-1} -= 1;
840
    */
841
0
    q->dp[i - t - 1] = (q->dp[i - t - 1] + 1);
842
0
    do {
843
0
      q->dp[i - t - 1] = (q->dp[i - t - 1] - 1);
844
845
      /* find left hand */
846
0
      fp_zero (t1);
847
0
      t1->dp[0] = (t - 1 < 0) ? 0 : y->dp[t - 1];
848
0
      t1->dp[1] = y->dp[t];
849
0
      t1->used = 2;
850
0
      ret = fp_mul_d (t1, q->dp[i - t - 1], t1);
851
0
      if (ret != FP_OKAY) {
852
0
      #ifdef WOLFSSL_SMALL_STACK
853
0
        XFREE(q, NULL, DYNAMIC_TYPE_BIGINT);
854
0
      #endif
855
0
        return ret;
856
0
      }
857
858
      /* find right hand */
859
0
      t2->dp[0] = (i - 2 < 0) ? 0 : x->dp[i - 2];
860
0
      t2->dp[1] = (i - 1 < 0) ? 0 : x->dp[i - 1];
861
0
      t2->dp[2] = x->dp[i];
862
0
      t2->used = 3;
863
0
    } while (fp_cmp_mag(t1, t2) == FP_GT);
864
865
    /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */
866
0
    ret = fp_mul_d (y, q->dp[i - t - 1], t1);
867
0
    if (ret != FP_OKAY) {
868
0
    #ifdef WOLFSSL_SMALL_STACK
869
0
      XFREE(q, NULL, DYNAMIC_TYPE_BIGINT);
870
0
    #endif
871
0
      return ret;
872
0
    }
873
0
    ret = fp_lshd  (t1, i - t - 1);
874
0
    if (ret != FP_OKAY) {
875
0
    #ifdef WOLFSSL_SMALL_STACK
876
0
      XFREE(q, NULL, DYNAMIC_TYPE_BIGINT);
877
0
    #endif
878
0
      return ret;
879
0
    }
880
0
    ret = fp_sub   (x, t1, x);
881
0
    if (ret != FP_OKAY) {
882
0
    #ifdef WOLFSSL_SMALL_STACK
883
0
      XFREE(q, NULL, DYNAMIC_TYPE_BIGINT);
884
0
    #endif
885
0
      return ret;
886
0
    }
887
888
    /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */
889
0
    if (x->sign == FP_NEG) {
890
0
      fp_copy (y, t1);
891
0
      ret = fp_lshd (t1, i - t - 1);
892
0
      if (ret != FP_OKAY) {
893
0
      #ifdef WOLFSSL_SMALL_STACK
894
0
        XFREE(q, NULL, DYNAMIC_TYPE_BIGINT);
895
0
      #endif
896
0
        return ret;
897
0
      }
898
0
      ret = fp_add (x, t1, x);
899
0
      if (ret != FP_OKAY) {
900
0
      #ifdef WOLFSSL_SMALL_STACK
901
0
        XFREE(q, NULL, DYNAMIC_TYPE_BIGINT);
902
0
      #endif
903
0
        return ret;
904
0
      }
905
0
      q->dp[i - t - 1] = q->dp[i - t - 1] - 1;
906
0
    }
907
0
  }
908
909
  /* now q is the quotient and x is the remainder
910
   * [which we have to normalize]
911
   */
912
913
  /* get sign before writing to c */
914
0
  x->sign = x->used == 0 ? FP_ZPOS : a->sign;
915
916
0
  if (c != NULL) {
917
0
    fp_clamp (q);
918
0
    fp_copy (q, c);
919
0
    c->sign = neg;
920
0
  }
921
922
0
  if (d != NULL) {
923
0
    fp_div_2d (x, norm, x, NULL);
924
925
    /* zero any excess digits on the destination that we didn't write to */
926
0
    for (i = b->used; i < x->used; i++) {
927
0
        x->dp[i] = 0;
928
0
    }
929
0
    fp_clamp(x);
930
0
    fp_copy (x, d);
931
0
  }
932
933
0
#ifdef WOLFSSL_SMALL_STACK
934
0
  XFREE(q, NULL, DYNAMIC_TYPE_BIGINT);
935
0
#endif
936
0
  return FP_OKAY;
937
0
}
938
939
/* b = a/2 */
940
void fp_div_2(fp_int * a, fp_int * b)
941
0
{
942
0
  int     x, oldused;
943
944
0
  oldused = b->used;
945
0
  b->used = a->used;
946
0
  {
947
0
    fp_digit r, rr, *tmpa, *tmpb;
948
949
    /* source alias */
950
0
    tmpa = a->dp + b->used - 1;
951
952
    /* dest alias */
953
0
    tmpb = b->dp + b->used - 1;
954
955
    /* carry */
956
0
    r = 0;
957
0
    for (x = b->used - 1; x >= 0; x--) {
958
      /* get the carry for the next iteration */
959
0
      rr = *tmpa & 1;
960
961
      /* shift the current digit, add in carry and store */
962
0
      *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));
963
964
      /* forward carry to next iteration */
965
0
      r = rr;
966
0
    }
967
968
    /* zero any excess digits on the destination that we didn't write to */
969
0
    tmpb = b->dp + b->used;
970
0
    for (x = b->used; x < oldused; x++) {
971
0
      *tmpb++ = 0;
972
0
    }
973
0
  }
974
0
  b->sign = a->sign;
975
0
  fp_clamp (b);
976
0
}
977
978
/* c = a / 2 (mod b) - constant time (a < b and positive) */
979
int fp_div_2_mod_ct(fp_int *a, fp_int *b, fp_int *c)
980
0
{
981
0
  fp_word  w = 0;
982
0
  fp_digit mask;
983
0
  int i;
984
985
0
  mask = (fp_digit)0 - (a->dp[0] & 1);
986
0
  for (i = 0; i < b->used; i++) {
987
0
      fp_digit mask_a = (fp_digit)0 - (i < a->used);
988
989
0
      w         += b->dp[i] & mask;
990
0
      w         += a->dp[i] & mask_a;
991
0
      c->dp[i]   = (fp_digit)w;
992
0
      w        >>= DIGIT_BIT;
993
0
  }
994
0
  for (i = 0; i < b->used-1; i++) {
995
0
      c->dp[i] = (c->dp[i] >> 1) | (c->dp[i+1] << (DIGIT_BIT - 1));
996
0
  }
997
0
  c->dp[i] = (c->dp[i] >> 1) | ((fp_digit)w << (DIGIT_BIT - 1));
998
0
  c->used = i + 1;
999
0
  c->sign = FP_ZPOS;
1000
0
  fp_clamp(c);
1001
1002
0
  return FP_OKAY;
1003
0
}
1004
1005
/* c = a / 2**b */
1006
void fp_div_2d(fp_int *a, int b, fp_int *c, fp_int *d)
1007
0
{
1008
0
  int      D;
1009
1010
  /* if the shift count is <= 0 then we do no work */
1011
0
  if (b <= 0) {
1012
0
    fp_copy (a, c);
1013
0
    if (d != NULL) {
1014
0
      fp_zero (d);
1015
0
    }
1016
0
    return;
1017
0
  }
1018
1019
  /* get the remainder before a is changed in calculating c */
1020
0
  if (a == c && d != NULL) {
1021
0
    fp_mod_2d (a, b, d);
1022
0
  }
1023
1024
  /* copy */
1025
0
  fp_copy(a, c);
1026
1027
  /* shift by as many digits in the bit count */
1028
0
  if (b >= (int)DIGIT_BIT) {
1029
0
    fp_rshd (c, b / DIGIT_BIT);
1030
0
  }
1031
1032
  /* shift any bit count < DIGIT_BIT */
1033
0
  D = (b % DIGIT_BIT);
1034
0
  if (D != 0) {
1035
0
    fp_rshb(c, D);
1036
0
  }
1037
1038
  /* get the remainder if a is not changed in calculating c */
1039
0
  if (a != c && d != NULL) {
1040
0
    fp_mod_2d (a, b, d);
1041
0
  }
1042
1043
0
  fp_clamp (c);
1044
0
}
1045
1046
/* c = a mod b, 0 <= c < b  */
1047
int fp_mod(fp_int *a, fp_int *b, fp_int *c)
1048
0
{
1049
#ifndef WOLFSSL_SMALL_STACK
1050
   fp_int t[1];
1051
#else
1052
0
   fp_int *t;
1053
0
#endif
1054
0
   int    err;
1055
1056
0
#ifdef WOLFSSL_SMALL_STACK
1057
0
   t = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);
1058
0
   if (t == NULL)
1059
0
       return FP_MEM;
1060
0
#endif
1061
1062
0
   fp_init(t);
1063
0
   err = fp_div(a, b, NULL, t);
1064
0
   if (err == FP_OKAY) {
1065
0
      if (!fp_iszero(t) && (t->sign != b->sign)) {
1066
0
         err = fp_add(t, b, c);
1067
0
      } else {
1068
0
         fp_copy(t, c);
1069
0
     }
1070
0
  }
1071
1072
0
#ifdef WOLFSSL_SMALL_STACK
1073
0
  XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);
1074
0
#endif
1075
0
  return err;
1076
0
}
1077
1078
/* c = a mod 2**d */
1079
void fp_mod_2d(fp_int *a, int b, fp_int *c)
1080
0
{
1081
0
   unsigned int x;
1082
0
   unsigned int bmax;
1083
1084
   /* zero if count less than or equal to zero */
1085
0
   if (b <= 0) {
1086
0
      fp_zero(c);
1087
0
      return;
1088
0
   }
1089
1090
   /* get copy of input */
1091
0
   fp_copy(a, c);
1092
1093
   /* if 2**d is larger than we just return */
1094
0
   if (c->sign == FP_ZPOS && b >= (DIGIT_BIT * a->used)) {
1095
0
      return;
1096
0
   }
1097
1098
0
   bmax = ((unsigned int)b + DIGIT_BIT - 1) / DIGIT_BIT;
1099
1100
   /* If a is negative and bmax is greater than or equal to FP_SIZE, then the
1101
    * result can't fit within c. Just return. */
1102
0
   if (c->sign == FP_NEG && bmax >= FP_SIZE) {
1103
0
      return;
1104
0
   }
1105
1106
  /* zero digits above the last digit of the modulus */
1107
0
   for (x = bmax; x < (unsigned int)c->used; x++) {
1108
0
    c->dp[x] = 0;
1109
0
  }
1110
1111
0
  if (c->sign == FP_NEG) {
1112
0
     fp_digit carry = 0;
1113
     /* negate value */
1114
0
     for (x = 0; x < (unsigned int)c->used; x++) {
1115
0
         fp_digit next = c->dp[x] > 0;
1116
0
         c->dp[x] = (fp_digit)0 - c->dp[x] - carry;
1117
0
         carry |= next;
1118
0
     }
1119
0
     for (; x < bmax; x++) {
1120
0
         c->dp[x] = (fp_digit)0 - carry;
1121
0
     }
1122
0
     c->used = (int)bmax;
1123
0
     c->sign = FP_ZPOS;
1124
0
  }
1125
1126
  /* clear the digit that is not completely outside/inside the modulus */
1127
0
  x = DIGIT_BIT - (b % DIGIT_BIT);
1128
0
  if (x != DIGIT_BIT) {
1129
0
     c->dp[bmax - 1] &= ~((fp_digit)0) >> x;
1130
0
  }
1131
1132
0
  fp_clamp (c);
1133
0
}
1134
1135
static int fp_invmod_slow (fp_int * a, fp_int * b, fp_int * c)
1136
0
{
1137
#ifndef WOLFSSL_SMALL_STACK
1138
  fp_int  x[1], y[1], u[1], v[1], A[1], B[1], C[1], D[1];
1139
#else
1140
0
  fp_int  *x, *y, *u, *v, *A, *B, *C, *D;
1141
0
#endif
1142
0
  int     err;
1143
1144
  /* b cannot be negative */
1145
0
  if (b->sign == FP_NEG || fp_iszero(b) == FP_YES) {
1146
0
    return FP_VAL;
1147
0
  }
1148
0
  if (fp_iszero(a) == FP_YES) {
1149
0
    return FP_VAL;
1150
0
  }
1151
1152
0
#ifdef WOLFSSL_SMALL_STACK
1153
0
  x = (fp_int*)XMALLOC(sizeof(fp_int) * 8, NULL, DYNAMIC_TYPE_BIGINT);
1154
0
  if (x == NULL) {
1155
0
      return FP_MEM;
1156
0
  }
1157
0
  y = &x[1]; u = &x[2]; v = &x[3]; A = &x[4]; B = &x[5]; C = &x[6]; D = &x[7];
1158
0
#endif
1159
1160
  /* init temps */
1161
0
  fp_init(x);    fp_init(y);
1162
0
  fp_init(u);    fp_init(v);
1163
0
  fp_init(A);    fp_init(B);
1164
0
  fp_init(C);    fp_init(D);
1165
1166
  /* x = a, y = b */
1167
0
  if ((err = fp_mod(a, b, x)) != FP_OKAY) {
1168
0
  #ifdef WOLFSSL_SMALL_STACK
1169
0
    XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1170
0
  #endif
1171
0
    return err;
1172
0
  }
1173
0
  fp_copy(b, y);
1174
1175
0
  if (fp_iszero(x) == FP_YES) {
1176
    /* invmod doesn't exist for this a and b */
1177
0
  #ifdef WOLFSSL_SMALL_STACK
1178
0
    XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1179
0
  #endif
1180
0
    return FP_VAL;
1181
0
  }
1182
1183
  /* 2. [modified] if x,y are both even then return an error! */
1184
0
  if (fp_iseven(x) == FP_YES && fp_iseven(y) == FP_YES) {
1185
0
  #ifdef WOLFSSL_SMALL_STACK
1186
0
    XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1187
0
  #endif
1188
0
    return FP_VAL;
1189
0
  }
1190
1191
  /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
1192
0
  fp_copy (x, u);
1193
0
  fp_copy (y, v);
1194
0
  fp_set (A, 1);
1195
0
  fp_set (D, 1);
1196
1197
0
top:
1198
  /* 4.  while u is even do */
1199
0
  while (fp_iseven (u) == FP_YES) {
1200
    /* 4.1 u = u/2 */
1201
0
    fp_div_2 (u, u);
1202
1203
    /* 4.2 if A or B is odd then */
1204
0
    if (fp_isodd (A) == FP_YES || fp_isodd (B) == FP_YES) {
1205
      /* A = (A+y)/2, B = (B-x)/2 */
1206
0
      err = fp_add (A, y, A);
1207
0
      if (err != FP_OKAY) {
1208
0
      #ifdef WOLFSSL_SMALL_STACK
1209
0
        XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1210
0
      #endif
1211
0
        return err;
1212
0
      }
1213
0
      err = fp_sub (B, x, B);
1214
0
      if (err != FP_OKAY) {
1215
0
      #ifdef WOLFSSL_SMALL_STACK
1216
0
        XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1217
0
      #endif
1218
0
        return err;
1219
0
      }
1220
0
    }
1221
    /* A = A/2, B = B/2 */
1222
0
    fp_div_2 (A, A);
1223
0
    fp_div_2 (B, B);
1224
0
  }
1225
1226
  /* 5.  while v is even do */
1227
0
  while (fp_iseven (v) == FP_YES) {
1228
    /* 5.1 v = v/2 */
1229
0
    fp_div_2 (v, v);
1230
1231
    /* 5.2 if C or D is odd then */
1232
0
    if (fp_isodd (C) == FP_YES || fp_isodd (D) == FP_YES) {
1233
      /* C = (C+y)/2, D = (D-x)/2 */
1234
0
      err = fp_add (C, y, C);
1235
0
      if (err != FP_OKAY) {
1236
0
      #ifdef WOLFSSL_SMALL_STACK
1237
0
        XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1238
0
      #endif
1239
0
        return err;
1240
0
      }
1241
0
      err = fp_sub (D, x, D);
1242
0
      if (err != FP_OKAY) {
1243
0
      #ifdef WOLFSSL_SMALL_STACK
1244
0
        XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1245
0
      #endif
1246
0
        return err;
1247
0
      }
1248
0
    }
1249
    /* C = C/2, D = D/2 */
1250
0
    fp_div_2 (C, C);
1251
0
    fp_div_2 (D, D);
1252
0
  }
1253
1254
  /* 6.  if u >= v then */
1255
0
  if (fp_cmp (u, v) != FP_LT) {
1256
    /* u = u - v, A = A - C, B = B - D */
1257
0
    err = fp_sub (u, v, u);
1258
0
    if (err != FP_OKAY) {
1259
0
    #ifdef WOLFSSL_SMALL_STACK
1260
0
      XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1261
0
    #endif
1262
0
      return err;
1263
0
    }
1264
0
    err = fp_sub (A, C, A);
1265
0
    if (err != FP_OKAY) {
1266
0
    #ifdef WOLFSSL_SMALL_STACK
1267
0
      XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1268
0
    #endif
1269
0
      return err;
1270
0
    }
1271
0
    err = fp_sub (B, D, B);
1272
0
    if (err != FP_OKAY) {
1273
0
    #ifdef WOLFSSL_SMALL_STACK
1274
0
      XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1275
0
    #endif
1276
0
      return err;
1277
0
    }
1278
0
  } else {
1279
    /* v - v - u, C = C - A, D = D - B */
1280
0
    err = fp_sub (v, u, v);
1281
0
    if (err != FP_OKAY) {
1282
0
    #ifdef WOLFSSL_SMALL_STACK
1283
0
      XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1284
0
    #endif
1285
0
      return err;
1286
0
    }
1287
0
    err = fp_sub (C, A, C);
1288
0
    if (err != FP_OKAY) {
1289
0
    #ifdef WOLFSSL_SMALL_STACK
1290
0
      XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1291
0
    #endif
1292
0
      return err;
1293
0
    }
1294
0
    err = fp_sub (D, B, D);
1295
0
    if (err != FP_OKAY) {
1296
0
    #ifdef WOLFSSL_SMALL_STACK
1297
0
      XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1298
0
    #endif
1299
0
      return err;
1300
0
    }
1301
0
  }
1302
1303
  /* if not zero goto step 4 */
1304
0
  if (fp_iszero (u) == FP_NO)
1305
0
    goto top;
1306
1307
  /* now a = C, b = D, gcd == g*v */
1308
1309
  /* if v != 1 then there is no inverse */
1310
0
  if (fp_cmp_d (v, 1) != FP_EQ) {
1311
0
  #ifdef WOLFSSL_SMALL_STACK
1312
0
    XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1313
0
  #endif
1314
0
    return FP_VAL;
1315
0
  }
1316
1317
  /* if its too low */
1318
0
  while (fp_cmp_d(C, 0) == FP_LT) {
1319
0
    err = fp_add(C, b, C);
1320
0
    if (err != FP_OKAY) {
1321
0
    #ifdef WOLFSSL_SMALL_STACK
1322
0
      XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1323
0
    #endif
1324
0
      return err;
1325
0
    }
1326
0
  }
1327
1328
  /* too big */
1329
0
  while (fp_cmp_mag(C, b) != FP_LT) {
1330
0
    err = fp_sub(C, b, C);
1331
0
    if (err != FP_OKAY) {
1332
0
    #ifdef WOLFSSL_SMALL_STACK
1333
0
      XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1334
0
    #endif
1335
0
      return err;
1336
0
    }
1337
0
  }
1338
1339
  /* C is now the inverse */
1340
0
  fp_copy(C, c);
1341
0
#ifdef WOLFSSL_SMALL_STACK
1342
0
  XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1343
0
#endif
1344
0
  return FP_OKAY;
1345
0
}
1346
1347
/* c = 1/a (mod b) for odd b only */
1348
int fp_invmod(fp_int *a, fp_int *b, fp_int *c)
1349
0
{
1350
#ifndef WOLFSSL_SMALL_STACK
1351
  fp_int  x[1], y[1], u[1], v[1], B[1], D[1];
1352
#else
1353
0
  fp_int  *x, *y, *u, *v, *B, *D;
1354
0
#endif
1355
0
  int     err;
1356
1357
0
  if (b->sign == FP_NEG || fp_iszero(b) == FP_YES) {
1358
0
    return FP_VAL;
1359
0
  }
1360
1361
  /* [modified] sanity check on "a" */
1362
0
  if (fp_iszero(a) == FP_YES) {
1363
0
    return FP_VAL; /* can not divide by 0 here */
1364
0
  }
1365
1366
  /* 2. [modified] b must be odd   */
1367
0
  if (fp_iseven(b) == FP_YES) {
1368
0
    return fp_invmod_slow(a,b,c);
1369
0
  }
1370
1371
0
#ifdef WOLFSSL_SMALL_STACK
1372
0
  x = (fp_int*)XMALLOC(sizeof(fp_int) * 6, NULL, DYNAMIC_TYPE_BIGINT);
1373
0
  if (x == NULL) {
1374
0
      return FP_MEM;
1375
0
  }
1376
0
  y = &x[1]; u = &x[2]; v = &x[3]; B = &x[4]; D = &x[5];
1377
0
#endif
1378
1379
  /* init all our temps */
1380
0
  fp_init(x);  fp_init(y);
1381
0
  fp_init(u);  fp_init(v);
1382
0
  fp_init(B);  fp_init(D);
1383
1384
0
  if (fp_iszero(a) == FP_YES) {
1385
0
  #ifdef WOLFSSL_SMALL_STACK
1386
0
    XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1387
0
  #endif
1388
0
    return FP_VAL;
1389
0
  }
1390
1391
  /* x == modulus, y == value to invert */
1392
0
  fp_copy(b, x);
1393
1394
  /* we need y = |a| */
1395
0
  if ((err = mp_mod(a, b, y)) != FP_OKAY) {
1396
0
  #ifdef WOLFSSL_SMALL_STACK
1397
0
    XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1398
0
  #endif
1399
0
    return err;
1400
0
  }
1401
1402
0
  if (fp_iszero(y) == FP_YES) {
1403
    /* invmod doesn't exist for this a and b */
1404
0
  #ifdef WOLFSSL_SMALL_STACK
1405
0
    XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1406
0
  #endif
1407
0
    return FP_VAL;
1408
0
  }
1409
1410
  /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
1411
0
  fp_copy(x, u);
1412
0
  fp_copy(y, v);
1413
0
  fp_set (D, 1);
1414
1415
0
top:
1416
  /* 4.  while u is even do */
1417
0
  while (fp_iseven (u) == FP_YES) {
1418
    /* 4.1 u = u/2 */
1419
0
    fp_div_2 (u, u);
1420
1421
    /* 4.2 if B is odd then */
1422
0
    if (fp_isodd (B) == FP_YES) {
1423
0
      err = fp_sub (B, x, B);
1424
0
      if (err != FP_OKAY) {
1425
0
      #ifdef WOLFSSL_SMALL_STACK
1426
0
        XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1427
0
      #endif
1428
0
        return err;
1429
0
      }
1430
0
    }
1431
    /* B = B/2 */
1432
0
    fp_div_2 (B, B);
1433
0
  }
1434
1435
  /* 5.  while v is even do */
1436
0
  while (fp_iseven (v) == FP_YES) {
1437
    /* 5.1 v = v/2 */
1438
0
    fp_div_2 (v, v);
1439
1440
    /* 5.2 if D is odd then */
1441
0
    if (fp_isodd (D) == FP_YES) {
1442
      /* D = (D-x)/2 */
1443
0
      err = fp_sub (D, x, D);
1444
0
      if (err != FP_OKAY) {
1445
0
      #ifdef WOLFSSL_SMALL_STACK
1446
0
        XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1447
0
      #endif
1448
0
        return err;
1449
0
      }
1450
0
    }
1451
    /* D = D/2 */
1452
0
    fp_div_2 (D, D);
1453
0
  }
1454
1455
  /* 6.  if u >= v then */
1456
0
  if (fp_cmp (u, v) != FP_LT) {
1457
    /* u = u - v, B = B - D */
1458
0
    err = fp_sub (u, v, u);
1459
0
    if (err != FP_OKAY) {
1460
0
    #ifdef WOLFSSL_SMALL_STACK
1461
0
      XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1462
0
    #endif
1463
0
      return err;
1464
0
    }
1465
0
    err = fp_sub (B, D, B);
1466
0
    if (err != FP_OKAY) {
1467
0
    #ifdef WOLFSSL_SMALL_STACK
1468
0
      XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1469
0
    #endif
1470
0
      return err;
1471
0
    }
1472
0
  } else {
1473
    /* v - v - u, D = D - B */
1474
0
    err = fp_sub (v, u, v);
1475
0
    if (err != FP_OKAY) {
1476
0
    #ifdef WOLFSSL_SMALL_STACK
1477
0
      XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1478
0
    #endif
1479
0
      return err;
1480
0
    }
1481
0
    err = fp_sub (D, B, D);
1482
0
    if (err != FP_OKAY) {
1483
0
    #ifdef WOLFSSL_SMALL_STACK
1484
0
      XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1485
0
    #endif
1486
0
      return err;
1487
0
    }
1488
0
  }
1489
1490
  /* if not zero goto step 4 */
1491
0
  if (fp_iszero (u) == FP_NO) {
1492
0
    goto top;
1493
0
  }
1494
1495
  /* now a = C, b = D, gcd == g*v */
1496
1497
  /* if v != 1 then there is no inverse */
1498
0
  if (fp_cmp_d (v, 1) != FP_EQ) {
1499
0
  #ifdef WOLFSSL_SMALL_STACK
1500
0
    XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1501
0
  #endif
1502
0
    return FP_VAL;
1503
0
  }
1504
1505
  /* b is now the inverse */
1506
0
  while (D->sign == FP_NEG) {
1507
0
    err = fp_add (D, b, D);
1508
0
    if (err != FP_OKAY) {
1509
0
    #ifdef WOLFSSL_SMALL_STACK
1510
0
      XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1511
0
    #endif
1512
0
      return FP_OKAY;
1513
0
    }
1514
0
  }
1515
  /* too big */
1516
0
  while (fp_cmp_mag(D, b) != FP_LT) {
1517
0
    err = fp_sub(D, b, D);
1518
0
    if (err != FP_OKAY) {
1519
0
    #ifdef WOLFSSL_SMALL_STACK
1520
0
      XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1521
0
    #endif
1522
0
      return err;
1523
0
    }
1524
0
  }
1525
0
  fp_copy (D, c);
1526
0
#ifdef WOLFSSL_SMALL_STACK
1527
0
  XFREE(x, NULL, DYNAMIC_TYPE_BIGINT);
1528
0
#endif
1529
0
  return FP_OKAY;
1530
0
}
1531
1532
0
#define CT_INV_MOD_PRE_CNT      8
1533
1534
/* modulus (b) must be greater than 2 and a prime */
1535
int fp_invmod_mont_ct(fp_int *a, fp_int *b, fp_int *c, fp_digit mp)
1536
0
{
1537
0
  int i, j, err = FP_OKAY;
1538
#ifndef WOLFSSL_SMALL_STACK
1539
  fp_int t[1], e[1];
1540
  fp_int pre[CT_INV_MOD_PRE_CNT];
1541
#else
1542
0
  fp_int* t;
1543
0
  fp_int* e;
1544
0
  fp_int* pre;
1545
0
#endif
1546
1547
0
  if ((a->used * 2 > FP_SIZE) || (b->used * 2 > FP_SIZE)) {
1548
0
    return FP_VAL;
1549
0
  }
1550
1551
0
#ifdef WOLFSSL_SMALL_STACK
1552
0
  t = (fp_int*)XMALLOC(sizeof(fp_int) * (2 + CT_INV_MOD_PRE_CNT), NULL,
1553
0
                                                           DYNAMIC_TYPE_BIGINT);
1554
0
  if (t == NULL)
1555
0
    return FP_MEM;
1556
0
  e = t + 1;
1557
0
  pre = t + 2;
1558
0
#endif
1559
1560
0
  fp_init(t);
1561
0
  fp_init(e);
1562
1563
0
  fp_init(&pre[0]);
1564
0
  fp_copy(a, &pre[0]);
1565
0
  for (i = 1; i < CT_INV_MOD_PRE_CNT; i++) {
1566
0
    fp_init(&pre[i]);
1567
0
    err |= fp_sqr(&pre[i-1], &pre[i]);
1568
0
    err |= fp_montgomery_reduce(&pre[i], b, mp);
1569
0
    err |= fp_mul(&pre[i], a, &pre[i]);
1570
0
    err |= fp_montgomery_reduce(&pre[i], b, mp);
1571
0
  }
1572
1573
0
  err |= fp_sub_d(b, 2, e);
1574
  /* Highest bit is always set. */
1575
0
  j = 1;
1576
0
  for (i = fp_count_bits(e)-2; i >= 0; i--) {
1577
0
      if (!fp_is_bit_set(e, i) || j == CT_INV_MOD_PRE_CNT)
1578
0
          break;
1579
0
      j++;
1580
0
  }
1581
0
  fp_copy(&pre[j-1], t);
1582
0
  j = 0;
1583
0
  for (; i >= 0; i--) {
1584
0
    int set = fp_is_bit_set(e, i);
1585
1586
0
    if ((j == CT_INV_MOD_PRE_CNT) || (!set && j > 0)) {
1587
0
      err |= fp_mul(t, &pre[j-1], t);
1588
0
      err |= fp_montgomery_reduce(t, b, mp);
1589
0
      j = 0;
1590
0
    }
1591
0
    err |= fp_sqr(t, t);
1592
0
    err |= fp_montgomery_reduce(t, b, mp);
1593
0
    j += set;
1594
0
  }
1595
0
  if (j > 0) {
1596
0
    err |= fp_mul(t, &pre[j-1], c);
1597
0
    err |= fp_montgomery_reduce(c, b, mp);
1598
0
  }
1599
0
  else
1600
0
    fp_copy(t, c);
1601
1602
0
#ifdef WOLFSSL_SMALL_STACK
1603
0
  XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);
1604
0
#endif
1605
1606
0
  return err;
1607
0
}
1608
1609
/* d = a * b (mod c) */
1610
int fp_mulmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d)
1611
0
{
1612
0
  int err;
1613
#ifndef WOLFSSL_SMALL_STACK
1614
   fp_int t[1];
1615
#else
1616
0
   fp_int *t;
1617
0
#endif
1618
1619
0
#ifdef WOLFSSL_SMALL_STACK
1620
0
   t = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);
1621
0
   if (t == NULL)
1622
0
       return FP_MEM;
1623
0
#endif
1624
1625
0
  fp_init(t);
1626
0
  err = fp_mul(a, b, t);
1627
0
  if (err == FP_OKAY) {
1628
  #if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT)
1629
    if (d->size < FP_SIZE) {
1630
      err = fp_mod(t, c, t);
1631
      fp_copy(t, d);
1632
    } else
1633
  #endif
1634
0
    {
1635
0
      err = fp_mod(t, c, d);
1636
0
    }
1637
0
  }
1638
1639
0
#ifdef WOLFSSL_SMALL_STACK
1640
0
  XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);
1641
0
#endif
1642
0
  return err;
1643
0
}
1644
1645
/* d = a - b (mod c) */
1646
int fp_submod(fp_int *a, fp_int *b, fp_int *c, fp_int *d)
1647
0
{
1648
0
  int err;
1649
#ifndef WOLFSSL_SMALL_STACK
1650
   fp_int t[1];
1651
#else
1652
0
   fp_int *t;
1653
0
#endif
1654
1655
0
#ifdef WOLFSSL_SMALL_STACK
1656
0
   t = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);
1657
0
   if (t == NULL)
1658
0
       return FP_MEM;
1659
0
#endif
1660
1661
0
  fp_init(t);
1662
0
  err = fp_sub(a, b, t);
1663
0
  if (err == FP_OKAY) {
1664
  #if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT)
1665
    if (d->size < FP_SIZE) {
1666
      err = fp_mod(t, c, t);
1667
      fp_copy(t, d);
1668
    } else
1669
  #endif
1670
0
    {
1671
0
      err = fp_mod(t, c, d);
1672
0
    }
1673
0
  }
1674
1675
0
#ifdef WOLFSSL_SMALL_STACK
1676
0
  XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);
1677
0
#endif
1678
0
  return err;
1679
0
}
1680
1681
/* d = a + b (mod c) */
1682
int fp_addmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d)
1683
0
{
1684
0
  int err;
1685
#ifndef WOLFSSL_SMALL_STACK
1686
   fp_int t[1];
1687
#else
1688
0
   fp_int *t;
1689
0
#endif
1690
1691
0
#ifdef WOLFSSL_SMALL_STACK
1692
0
   t = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);
1693
0
   if (t == NULL)
1694
0
       return FP_MEM;
1695
0
#endif
1696
1697
0
  fp_init(t);
1698
0
  err = fp_add(a, b, t);
1699
0
  if (err == FP_OKAY) {
1700
  #if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT)
1701
    if (d->size < FP_SIZE) {
1702
      err = fp_mod(t, c, t);
1703
      fp_copy(t, d);
1704
    } else
1705
  #endif
1706
0
    {
1707
0
      err = fp_mod(t, c, d);
1708
0
    }
1709
0
  }
1710
1711
0
#ifdef WOLFSSL_SMALL_STACK
1712
0
  XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);
1713
0
#endif
1714
0
  return err;
1715
0
}
1716
1717
/* d = a - b (mod c) - constant time (a < c and b < c and all positive)
1718
 * c and d must not be the same pointers.
1719
 */
1720
int fp_submod_ct(fp_int *a, fp_int *b, fp_int *c, fp_int *d)
1721
0
{
1722
0
  fp_sword w;
1723
0
  fp_digit mask;
1724
0
  int i;
1725
1726
0
  if (c->used + 1 > FP_SIZE) {
1727
0
    return FP_VAL;
1728
0
  }
1729
0
  if (c == d) {
1730
0
    return FP_VAL;
1731
0
  }
1732
1733
  /* In constant time, subtract b from a putting result in d. */
1734
0
  w = 0;
1735
0
  for (i = 0; i < c->used; i++) {
1736
0
    w         += a->dp[i];
1737
0
    w         -= b->dp[i];
1738
0
    d->dp[i]   = (fp_digit)w;
1739
0
    w        >>= DIGIT_BIT;
1740
0
  }
1741
0
  w  += a->dp[i];
1742
0
  w  -= b->dp[i];
1743
0
  w >>= DIGIT_BIT;
1744
  /* When w is negative then we need to add modulus to make result positive. */
1745
0
  mask = (fp_digit)0 - (w < 0);
1746
  /* Constant time, conditionally, add modulus to difference. */
1747
0
  w = 0;
1748
0
  for (i = 0; i < c->used; i++) {
1749
0
    w         += d->dp[i];
1750
0
    w         += c->dp[i] & mask;
1751
0
    d->dp[i]   = (fp_digit)w;
1752
0
    w        >>= DIGIT_BIT;
1753
0
  }
1754
  /* Result will always have digits equal to or less than those in modulus. */
1755
0
  d->used = i;
1756
0
  d->sign = FP_ZPOS;
1757
0
  fp_clamp(d);
1758
1759
0
  return FP_OKAY;
1760
0
}
1761
1762
/* d = a + b (mod c) - constant time (a < c and b < c and all positive)
1763
 * c and d must not be the same pointers.
1764
 */
1765
int fp_addmod_ct(fp_int *a, fp_int *b, fp_int *c, fp_int *d)
1766
0
{
1767
0
  fp_word  w;
1768
0
  fp_sword s;
1769
0
  fp_digit mask;
1770
0
  int i;
1771
1772
0
  if (c == d) {
1773
0
    return FP_VAL;
1774
0
  }
1775
1776
  /* Add a to b into d. Do the subtract of modulus but don't store result.
1777
   * When subtract result is negative, the overflow will be negative.
1778
   * Only need to subtract mod when result is positive - overflow is positive.
1779
   */
1780
0
  w = 0;
1781
0
  s = 0;
1782
0
  for (i = 0; i < c->used; i++) {
1783
0
    w         += a->dp[i];
1784
0
    w         += b->dp[i];
1785
0
    d->dp[i]   = (fp_digit)w;
1786
0
    s         += (fp_digit)w;
1787
0
    s         -= c->dp[i];
1788
0
    w        >>= DIGIT_BIT;
1789
0
    s        >>= DIGIT_BIT;
1790
0
  }
1791
0
  s += (fp_digit)w;
1792
  /* s will be positive when subtracting modulus is needed. */
1793
0
  mask = (fp_digit)0 - (s >= 0);
1794
1795
  /* Constant time, conditionally, subtract modulus from sum. */
1796
0
  w = 0;
1797
0
  for (i = 0; i < c->used; i++) {
1798
0
    w        += c->dp[i] & mask;
1799
0
    w         = d->dp[i] - w;
1800
0
    d->dp[i]  = (fp_digit)w;
1801
0
    w         = (w >> DIGIT_BIT)&1;
1802
0
  }
1803
  /* Result will always have digits equal to or less than those in modulus. */
1804
0
  d->used = i;
1805
0
  d->sign = FP_ZPOS;
1806
0
  fp_clamp(d);
1807
1808
0
  return FP_OKAY;
1809
0
}
1810
1811
#ifdef TFM_TIMING_RESISTANT
1812
1813
#ifdef WC_RSA_NONBLOCK
1814
1815
#ifdef WC_RSA_NONBLOCK_TIME
1816
  /* User can override the check-time at build-time using the
1817
   * FP_EXPTMOD_NB_CHECKTIME macro to define your own function */
1818
  #ifndef FP_EXPTMOD_NB_CHECKTIME
1819
    /* instruction count for each type of operation */
1820
    /* array lookup is using TFM_EXPTMOD_NB_* states */
1821
    static const word32 exptModNbInst[TFM_EXPTMOD_NB_COUNT] = {
1822
    #ifdef TFM_PPC32
1823
      #ifdef _DEBUG
1824
        11098, 8701, 3971, 178394, 858093, 1040, 822, 178056, 181574, 90883, 184339, 236813
1825
      #else
1826
        7050,  2554, 3187, 43178,  200422, 384,  275, 43024,  43550,  30450, 46270,  61376
1827
      #endif
1828
    #elif defined(TFM_X86_64)
1829
      #ifdef _DEBUG
1830
        954, 2377, 858, 19027, 90840, 287, 407, 20140, 7874,  11385, 8005,  6151
1831
      #else
1832
        765, 1007, 771, 5216,  34993, 248, 193, 4975,  4201,  3947,  4275,  3811
1833
      #endif
1834
    #else /* software only fast math */
1835
      #ifdef _DEBUG
1836
        798, 2245, 802, 16657, 66920, 352, 186, 16997, 16145, 12789, 16742, 15006
1837
      #else
1838
        775, 1084, 783, 4692,  37510, 207, 183, 4374,  4392,  3097,  4442,  4079
1839
      #endif
1840
    #endif
1841
    };
1842
1843
    static int fp_exptmod_nb_checktime(exptModNb_t* nb)
1844
    {
1845
      word32 totalInst;
1846
1847
      /* if no max time has been set then stop (do not block) */
1848
      if (nb->maxBlockInst == 0 || nb->state >= TFM_EXPTMOD_NB_COUNT) {
1849
        return TFM_EXPTMOD_NB_STOP;
1850
      }
1851
1852
      /* if instruction table not set then use maxBlockInst as simple counter */
1853
      if (exptModNbInst[nb->state] == 0) {
1854
        if (++nb->totalInst < nb->maxBlockInst)
1855
          return TFM_EXPTMOD_NB_CONTINUE;
1856
1857
        nb->totalInst = 0; /* reset counter */
1858
        return TFM_EXPTMOD_NB_STOP;
1859
      }
1860
1861
      /* get total instruction count including next operation */
1862
      totalInst = nb->totalInst + exptModNbInst[nb->state];
1863
      /* if the next operation can completed within the maximum then continue */
1864
      if (totalInst <= nb->maxBlockInst) {
1865
        return TFM_EXPTMOD_NB_CONTINUE;
1866
      }
1867
1868
      return TFM_EXPTMOD_NB_STOP;
1869
    }
1870
    #define FP_EXPTMOD_NB_CHECKTIME(nb) fp_exptmod_nb_checktime((nb))
1871
  #endif /* !FP_EXPTMOD_NB_CHECKTIME */
1872
#endif /* WC_RSA_NONBLOCK_TIME */
1873
1874
/* non-blocking version of timing resistant fp_exptmod function */
1875
/* supports cache resistance */
1876
int fp_exptmod_nb(exptModNb_t* nb, fp_int* G, fp_int* X, fp_int* P, fp_int* Y)
1877
{
1878
  int err, ret = FP_WOULDBLOCK;
1879
1880
  if (nb == NULL)
1881
    return FP_VAL;
1882
1883
#ifdef WC_RSA_NONBLOCK_TIME
1884
  nb->totalInst = 0;
1885
  do {
1886
    nb->totalInst += exptModNbInst[nb->state];
1887
#endif
1888
1889
  switch (nb->state) {
1890
  case TFM_EXPTMOD_NB_INIT:
1891
    /* now setup montgomery  */
1892
    if ((err = fp_montgomery_setup(P, &nb->mp)) != FP_OKAY) {
1893
      nb->state = TFM_EXPTMOD_NB_INIT;
1894
      return err;
1895
    }
1896
1897
    /* init ints */
1898
    fp_init(&nb->R[0]);
1899
    fp_init(&nb->R[1]);
1900
  #ifndef WC_NO_CACHE_RESISTANT
1901
    fp_init(&nb->R[2]);
1902
  #endif
1903
    nb->state = TFM_EXPTMOD_NB_MONT;
1904
    break;
1905
1906
  case TFM_EXPTMOD_NB_MONT:
1907
    /* mod m -> R[0] */
1908
    err = fp_montgomery_calc_normalization(&nb->R[0], P);
1909
    if (err != FP_OKAY) {
1910
      nb->state = TFM_EXPTMOD_NB_INIT;
1911
      return err;
1912
    }
1913
1914
    nb->state = TFM_EXPTMOD_NB_MONT_RED;
1915
    break;
1916
1917
  case TFM_EXPTMOD_NB_MONT_RED:
1918
    /* reduce G -> R[1] */
1919
    if (fp_cmp_mag(P, G) != FP_GT) {
1920
       /* G > P so we reduce it first */
1921
       err = fp_mod(G, P, &nb->R[1]);
1922
       if (err != FP_OKAY) {
1923
         nb->state = TFM_EXPTMOD_NB_INIT;
1924
         return err;
1925
       }
1926
    } else {
1927
       fp_copy(G, &nb->R[1]);
1928
    }
1929
1930
    nb->state = TFM_EXPTMOD_NB_MONT_MUL;
1931
    break;
1932
1933
  case TFM_EXPTMOD_NB_MONT_MUL:
1934
    /* G (R[1]) * m (R[0]) */
1935
    err = fp_mul(&nb->R[1], &nb->R[0], &nb->R[1]);
1936
    if (err != FP_OKAY) {
1937
      nb->state = TFM_EXPTMOD_NB_INIT;
1938
      return err;
1939
    }
1940
1941
    nb->state = TFM_EXPTMOD_NB_MONT_MOD;
1942
    break;
1943
1944
  case TFM_EXPTMOD_NB_MONT_MOD:
1945
    /* mod m */
1946
    err = fp_div(&nb->R[1], P, NULL, &nb->R[1]);
1947
    if (err != FP_OKAY) {
1948
      nb->state = TFM_EXPTMOD_NB_INIT;
1949
      return err;
1950
    }
1951
1952
    nb->state = TFM_EXPTMOD_NB_MONT_MODCHK;
1953
    break;
1954
1955
  case TFM_EXPTMOD_NB_MONT_MODCHK:
1956
    /* m matches sign of (G * R mod m) */
1957
    if (nb->R[1].sign != P->sign) {
1958
       err = fp_add(&nb->R[1], P, &nb->R[1]);
1959
       if (err != FP_OKAY) {
1960
         nb->state = TFM_EXPTMOD_NB_INIT;
1961
         return err;
1962
       }
1963
    }
1964
1965
    /* set initial mode and bit cnt */
1966
    nb->bitcnt = 1;
1967
    nb->buf    = 0;
1968
    nb->digidx = X->used - 1;
1969
1970
    nb->state = TFM_EXPTMOD_NB_NEXT;
1971
    break;
1972
1973
  case TFM_EXPTMOD_NB_NEXT:
1974
    /* grab next digit as required */
1975
    if (--nb->bitcnt == 0) {
1976
      /* if nb->digidx == -1 we are out of digits so break */
1977
      if (nb->digidx == -1) {
1978
        nb->state = TFM_EXPTMOD_NB_RED;
1979
        break;
1980
      }
1981
      /* read next digit and reset nb->bitcnt */
1982
      nb->buf    = X->dp[nb->digidx--];
1983
      nb->bitcnt = (int)DIGIT_BIT;
1984
    }
1985
1986
    /* grab the next msb from the exponent */
1987
    nb->y     = (int)(nb->buf >> (DIGIT_BIT - 1)) & 1;
1988
    nb->buf <<= (fp_digit)1;
1989
    nb->state = TFM_EXPTMOD_NB_MUL;
1990
    FALL_THROUGH;
1991
1992
  case TFM_EXPTMOD_NB_MUL:
1993
    fp_mul(&nb->R[0], &nb->R[1], &nb->R[nb->y^1]);
1994
    nb->state = TFM_EXPTMOD_NB_MUL_RED;
1995
    break;
1996
1997
  case TFM_EXPTMOD_NB_MUL_RED:
1998
    err = fp_montgomery_reduce(&nb->R[nb->y^1], P, nb->mp);
1999
    if (err != FP_OKAY) {
2000
      nb->state = TFM_EXPTMOD_NB_INIT;
2001
      return err;
2002
    }
2003
    nb->state = TFM_EXPTMOD_NB_SQR;
2004
    break;
2005
2006
  case TFM_EXPTMOD_NB_SQR:
2007
  #ifdef WC_NO_CACHE_RESISTANT
2008
    err = fp_sqr(&nb->R[nb->y], &nb->R[nb->y]);
2009
  #else
2010
    fp_copy((fp_int*) ( ((wc_ptr_t)&nb->R[0] & wc_off_on_addr[nb->y^1]) +
2011
                        ((wc_ptr_t)&nb->R[1] & wc_off_on_addr[nb->y]) ),
2012
            &nb->R[2]);
2013
    err = fp_sqr(&nb->R[2], &nb->R[2]);
2014
  #endif /* WC_NO_CACHE_RESISTANT */
2015
    if (err != FP_OKAY) {
2016
      nb->state = TFM_EXPTMOD_NB_INIT;
2017
      return err;
2018
    }
2019
2020
    nb->state = TFM_EXPTMOD_NB_SQR_RED;
2021
    break;
2022
2023
  case TFM_EXPTMOD_NB_SQR_RED:
2024
  #ifdef WC_NO_CACHE_RESISTANT
2025
    err = fp_montgomery_reduce(&nb->R[nb->y], P, nb->mp);
2026
  #else
2027
    err = fp_montgomery_reduce(&nb->R[2], P, nb->mp);
2028
    fp_copy(&nb->R[2],
2029
            (fp_int*) ( ((wc_ptr_t)&nb->R[0] & wc_off_on_addr[nb->y^1]) +
2030
                        ((wc_ptr_t)&nb->R[1] & wc_off_on_addr[nb->y]) ) );
2031
  #endif /* WC_NO_CACHE_RESISTANT */
2032
    if (err != FP_OKAY) {
2033
      nb->state = TFM_EXPTMOD_NB_INIT;
2034
      return err;
2035
    }
2036
2037
    nb->state = TFM_EXPTMOD_NB_NEXT;
2038
    break;
2039
2040
  case TFM_EXPTMOD_NB_RED:
2041
    /* final reduce */
2042
    err = fp_montgomery_reduce(&nb->R[0], P, nb->mp);
2043
    if (err != FP_OKAY) {
2044
      nb->state = TFM_EXPTMOD_NB_INIT;
2045
      return err;
2046
    }
2047
    fp_copy(&nb->R[0], Y);
2048
2049
    nb->state = TFM_EXPTMOD_NB_INIT;
2050
    ret = FP_OKAY;
2051
    break;
2052
  } /* switch */
2053
2054
#ifdef WC_RSA_NONBLOCK_TIME
2055
  /* determine if maximum blocking time has been reached */
2056
  } while (ret == FP_WOULDBLOCK &&
2057
    FP_EXPTMOD_NB_CHECKTIME(nb) == TFM_EXPTMOD_NB_CONTINUE);
2058
#endif
2059
2060
  return ret;
2061
}
2062
2063
#endif /* WC_RSA_NONBLOCK */
2064
2065
2066
#ifndef WC_PROTECT_ENCRYPTED_MEM
2067
2068
/* timing resistant montgomery ladder based exptmod
2069
   Based on work by Marc Joye, Sung-Ming Yen, "The Montgomery Powering Ladder",
2070
   Cryptographic Hardware and Embedded Systems, CHES 2002
2071
*/
2072
static int _fp_exptmod_ct(fp_int * G, fp_int * X, int digits, fp_int * P,
2073
                          fp_int * Y)
2074
0
{
2075
#ifndef WOLFSSL_SMALL_STACK
2076
#ifdef WC_NO_CACHE_RESISTANT
2077
  fp_int   R[2];
2078
#else
2079
  fp_int   R[3];   /* need a temp for cache resistance */
2080
#endif
2081
#else
2082
0
   fp_int  *R;
2083
0
#endif
2084
0
  fp_digit buf, mp;
2085
0
  int      err, bitcnt, digidx, y;
2086
2087
  /* now setup montgomery  */
2088
0
  if ((err = fp_montgomery_setup (P, &mp)) != FP_OKAY) {
2089
0
     return err;
2090
0
  }
2091
2092
0
#ifdef WOLFSSL_SMALL_STACK
2093
0
#ifndef WC_NO_CACHE_RESISTANT
2094
0
   R = (fp_int*)XMALLOC(sizeof(fp_int) * 3, NULL, DYNAMIC_TYPE_BIGINT);
2095
#else
2096
   R = (fp_int*)XMALLOC(sizeof(fp_int) * 2, NULL, DYNAMIC_TYPE_BIGINT);
2097
#endif
2098
0
   if (R == NULL)
2099
0
       return FP_MEM;
2100
0
#endif
2101
0
  fp_init(&R[0]);
2102
0
  fp_init(&R[1]);
2103
0
#ifndef WC_NO_CACHE_RESISTANT
2104
0
  fp_init(&R[2]);
2105
0
#endif
2106
2107
  /* now we need R mod m */
2108
0
  err = fp_montgomery_calc_normalization (&R[0], P);
2109
0
  if (err != FP_OKAY) {
2110
0
  #ifdef WOLFSSL_SMALL_STACK
2111
0
    XFREE(R, NULL, DYNAMIC_TYPE_BIGINT);
2112
0
  #endif
2113
0
    return err;
2114
0
  }
2115
2116
  /* now set R[0][1] to G * R mod m */
2117
0
  if (fp_cmp_mag(P, G) != FP_GT) {
2118
     /* G > P so we reduce it first */
2119
0
     err = fp_mod(G, P, &R[1]);
2120
0
     if (err != FP_OKAY) {
2121
0
#ifdef WOLFSSL_SMALL_STACK
2122
0
         XFREE(R, NULL, DYNAMIC_TYPE_BIGINT);
2123
0
#endif
2124
0
         return err;
2125
0
     }
2126
0
  } else {
2127
0
     fp_copy(G, &R[1]);
2128
0
  }
2129
0
  err = fp_mulmod (&R[1], &R[0], P, &R[1]);
2130
0
  if (err != FP_OKAY) {
2131
0
#ifdef WOLFSSL_SMALL_STACK
2132
0
      XFREE(R, NULL, DYNAMIC_TYPE_BIGINT);
2133
0
#endif
2134
0
      return err;
2135
0
  }
2136
2137
  /* for j = t-1 downto 0 do
2138
        r_!k = R0*R1; r_k = r_k^2
2139
  */
2140
2141
  /* set initial mode and bit cnt */
2142
0
  bitcnt = 1;
2143
0
  buf    = 0;
2144
0
  digidx = digits - 1;
2145
2146
0
  for (;;) {
2147
    /* grab next digit as required */
2148
0
    if (--bitcnt == 0) {
2149
      /* if digidx == -1 we are out of digits so break */
2150
0
      if (digidx == -1) {
2151
0
        break;
2152
0
      }
2153
      /* read next digit and reset bitcnt */
2154
0
      buf    = X->dp[digidx--];
2155
0
      bitcnt = (int)DIGIT_BIT;
2156
0
    }
2157
2158
    /* grab the next msb from the exponent */
2159
0
    y     = (int)(buf >> (DIGIT_BIT - 1)) & 1;
2160
0
    buf <<= (fp_digit)1;
2161
2162
#ifdef WC_NO_CACHE_RESISTANT
2163
    /* do ops */
2164
    err = fp_mul(&R[0], &R[1], &R[y^1]);
2165
    if (err != FP_OKAY) {
2166
    #ifdef WOLFSSL_SMALL_STACK
2167
      XFREE(R, NULL, DYNAMIC_TYPE_BIGINT);
2168
    #endif
2169
      return err;
2170
    }
2171
    err = fp_montgomery_reduce(&R[y^1], P, mp);
2172
    if (err != FP_OKAY) {
2173
    #ifdef WOLFSSL_SMALL_STACK
2174
      XFREE(R, NULL, DYNAMIC_TYPE_BIGINT);
2175
    #endif
2176
      return err;
2177
    }
2178
2179
    err = fp_sqr(&R[y], &R[y]);
2180
    if (err != FP_OKAY) {
2181
    #ifdef WOLFSSL_SMALL_STACK
2182
      XFREE(R, NULL, DYNAMIC_TYPE_BIGINT);
2183
    #endif
2184
      return err;
2185
    }
2186
    err = fp_montgomery_reduce(&R[y], P, mp);
2187
    if (err != FP_OKAY) {
2188
    #ifdef WOLFSSL_SMALL_STACK
2189
      XFREE(R, NULL, DYNAMIC_TYPE_BIGINT);
2190
    #endif
2191
      return err;
2192
    }
2193
#else
2194
    /* do ops */
2195
0
    err = fp_mul(&R[0], &R[1], &R[2]);
2196
0
    if (err != FP_OKAY) {
2197
0
    #ifdef WOLFSSL_SMALL_STACK
2198
0
      XFREE(R, NULL, DYNAMIC_TYPE_BIGINT);
2199
0
    #endif
2200
0
      return err;
2201
0
    }
2202
0
    err = fp_montgomery_reduce(&R[2], P, mp);
2203
0
    if (err != FP_OKAY) {
2204
0
    #ifdef WOLFSSL_SMALL_STACK
2205
0
      XFREE(R, NULL, DYNAMIC_TYPE_BIGINT);
2206
0
    #endif
2207
0
      return err;
2208
0
    }
2209
    /* instead of using R[y^1] for mul, which leaks key bit to cache monitor,
2210
     * use R[2] as temp, make sure address calc is constant, keep
2211
     * &R[0] and &R[1] in cache */
2212
0
    fp_copy(&R[2],
2213
0
            (fp_int*) ( ((wc_ptr_t)&R[0] & wc_off_on_addr[y]) +
2214
0
                        ((wc_ptr_t)&R[1] & wc_off_on_addr[y^1]) ) );
2215
2216
    /* instead of using R[y] for sqr, which leaks key bit to cache monitor,
2217
     * use R[2] as temp, make sure address calc is constant, keep
2218
     * &R[0] and &R[1] in cache */
2219
0
    fp_copy((fp_int*) ( ((wc_ptr_t)&R[0] & wc_off_on_addr[y^1]) +
2220
0
                        ((wc_ptr_t)&R[1] & wc_off_on_addr[y]) ),
2221
0
            &R[2]);
2222
0
    err = fp_sqr(&R[2], &R[2]);
2223
0
    if (err != FP_OKAY) {
2224
0
    #ifdef WOLFSSL_SMALL_STACK
2225
0
      XFREE(R, NULL, DYNAMIC_TYPE_BIGINT);
2226
0
    #endif
2227
0
      return err;
2228
0
    }
2229
0
    err = fp_montgomery_reduce(&R[2], P, mp);
2230
0
    if (err != FP_OKAY) {
2231
0
    #ifdef WOLFSSL_SMALL_STACK
2232
0
      XFREE(R, NULL, DYNAMIC_TYPE_BIGINT);
2233
0
    #endif
2234
0
      return err;
2235
0
    }
2236
0
    fp_copy(&R[2],
2237
0
            (fp_int*) ( ((wc_ptr_t)&R[0] & wc_off_on_addr[y^1]) +
2238
0
                        ((wc_ptr_t)&R[1] & wc_off_on_addr[y]) ) );
2239
0
#endif /* WC_NO_CACHE_RESISTANT */
2240
0
  }
2241
2242
0
   err = fp_montgomery_reduce(&R[0], P, mp);
2243
0
   fp_copy(&R[0], Y);
2244
0
#ifdef WOLFSSL_SMALL_STACK
2245
0
   XFREE(R, NULL, DYNAMIC_TYPE_BIGINT);
2246
0
#endif
2247
2248
0
   return err;
2249
0
}
2250
2251
#else
2252
2253
/* Copy from a1 and a2 into r1 and r2 based on y in constant time.
2254
 * When y is 1, r1 = a1 and r2 = a2.
2255
 * When y is 0, r1 = a2 and r2 = a1.
2256
 * Always copy size digits as that is the maximum size for a1 and a2.
2257
 */
2258
static void fp_copy_2_ct(fp_int* a1, fp_int* a2, fp_int* r1, fp_int* r2, int y,
2259
    int size)
2260
{
2261
    int i;
2262
2263
    /* Copy data - constant time. */
2264
    for (i = 0; i < size; i++) {
2265
        r1->dp[i] = (a1->dp[i] & ((fp_digit)wc_off_on_addr[y  ])) +
2266
                    (a2->dp[i] & ((fp_digit)wc_off_on_addr[y^1]));
2267
        r2->dp[i] = (a1->dp[i] & ((fp_digit)wc_off_on_addr[y^1])) +
2268
                    (a2->dp[i] & ((fp_digit)wc_off_on_addr[y  ]));
2269
    }
2270
    /* Copy used. */
2271
    r1->used = (a1->used & ((int)wc_off_on_addr[y  ])) +
2272
               (a2->used & ((int)wc_off_on_addr[y^1]));
2273
    r2->used = (a1->used & ((int)wc_off_on_addr[y^1])) +
2274
               (a2->used & ((int)wc_off_on_addr[y  ]));
2275
    /* Copy sign. */
2276
    r1->sign = (a1->sign & ((int)wc_off_on_addr[y  ])) +
2277
               (a2->sign & ((int)wc_off_on_addr[y^1]));
2278
    r2->sign = (a1->sign & ((int)wc_off_on_addr[y^1])) +
2279
               (a2->sign & ((int)wc_off_on_addr[y  ]));
2280
}
2281
2282
/* timing resistant montgomery ladder based exptmod
2283
   Based on work by Marc Joye, Sung-Ming Yen, "The Montgomery Powering Ladder",
2284
   Cryptographic Hardware and Embedded Systems, CHES 2002
2285
*/
2286
static int _fp_exptmod_ct(fp_int * G, fp_int * X, int digits, fp_int * P,
2287
                          fp_int * Y)
2288
{
2289
#ifndef WOLFSSL_SMALL_STACK
2290
  fp_int   R[4];   /* need a temp for cache resistance */
2291
#else
2292
  fp_int  *R;
2293
#endif
2294
  fp_digit buf, mp;
2295
  int      err, bitcnt, digidx, y;
2296
2297
  /* now setup montgomery  */
2298
  if ((err = fp_montgomery_setup (P, &mp)) != FP_OKAY) {
2299
     return err;
2300
  }
2301
2302
#ifdef WOLFSSL_SMALL_STACK
2303
   R = (fp_int*)XMALLOC(sizeof(fp_int) * 4, NULL, DYNAMIC_TYPE_BIGINT);
2304
   if (R == NULL)
2305
       return FP_MEM;
2306
#endif
2307
  fp_init(&R[0]);
2308
  fp_init(&R[1]);
2309
  fp_init(&R[2]);
2310
  fp_init(&R[3]);
2311
2312
  /* now we need R mod m */
2313
  err = fp_montgomery_calc_normalization (&R[0], P);
2314
  if (err != FP_OKAY) {
2315
  #ifdef WOLFSSL_SMALL_STACK
2316
    XFREE(R, NULL, DYNAMIC_TYPE_BIGINT);
2317
  #endif
2318
    return err;
2319
  }
2320
2321
  /* now set R[0][1] to G * R mod m */
2322
  if (fp_cmp_mag(P, G) != FP_GT) {
2323
     /* G > P so we reduce it first */
2324
     err = fp_mod(G, P, &R[1]);
2325
     if (err != FP_OKAY) {
2326
#ifdef WOLFSSL_SMALL_STACK
2327
         XFREE(R, NULL, DYNAMIC_TYPE_BIGINT);
2328
#endif
2329
         return err;
2330
     }
2331
  } else {
2332
     fp_copy(G, &R[1]);
2333
  }
2334
  err = fp_mulmod (&R[1], &R[0], P, &R[1]);
2335
  if (err != FP_OKAY) {
2336
#ifdef WOLFSSL_SMALL_STACK
2337
      XFREE(R, NULL, DYNAMIC_TYPE_BIGINT);
2338
#endif
2339
      return err;
2340
  }
2341
2342
  /* for j = t-1 downto 0 do
2343
        r_!k = R0*R1; r_k = r_k^2
2344
  */
2345
2346
  /* set initial mode and bit cnt */
2347
  bitcnt = 1;
2348
  buf    = 0;
2349
  digidx = digits - 1;
2350
2351
  for (;;) {
2352
    /* grab next digit as required */
2353
    if (--bitcnt == 0) {
2354
      /* if digidx == -1 we are out of digits so break */
2355
      if (digidx == -1) {
2356
        break;
2357
      }
2358
      /* read next digit and reset bitcnt */
2359
      buf    = X->dp[digidx--];
2360
      bitcnt = (int)DIGIT_BIT;
2361
    }
2362
2363
    /* grab the next msb from the exponent */
2364
    y     = (int)(buf >> (DIGIT_BIT - 1)) & 1;
2365
    buf <<= (fp_digit)1;
2366
2367
    /* do ops */
2368
    err = fp_mul(&R[0], &R[1], &R[2]);
2369
    if (err != FP_OKAY) {
2370
    #ifdef WOLFSSL_SMALL_STACK
2371
      XFREE(R, NULL, DYNAMIC_TYPE_BIGINT);
2372
    #endif
2373
      return err;
2374
    }
2375
    err = fp_montgomery_reduce(&R[2], P, mp);
2376
    if (err != FP_OKAY) {
2377
    #ifdef WOLFSSL_SMALL_STACK
2378
      XFREE(R, NULL, DYNAMIC_TYPE_BIGINT);
2379
    #endif
2380
      return err;
2381
    }
2382
2383
    /* instead of using R[y] for sqr, which leaks key bit to cache monitor,
2384
     * use R[3] as temp, make sure address calc is constant, keep
2385
     * &R[0] and &R[1] in cache */
2386
    fp_copy((fp_int*) ( ((wc_ptr_t)&R[0] & wc_off_on_addr[y^1]) +
2387
                        ((wc_ptr_t)&R[1] & wc_off_on_addr[y]) ),
2388
            &R[3]);
2389
    err = fp_sqr(&R[3], &R[3]);
2390
    if (err != FP_OKAY) {
2391
    #ifdef WOLFSSL_SMALL_STACK
2392
      XFREE(R, NULL, DYNAMIC_TYPE_BIGINT);
2393
    #endif
2394
      return err;
2395
    }
2396
    err = fp_montgomery_reduce(&R[3], P, mp);
2397
    if (err != FP_OKAY) {
2398
    #ifdef WOLFSSL_SMALL_STACK
2399
      XFREE(R, NULL, DYNAMIC_TYPE_BIGINT);
2400
    #endif
2401
      return err;
2402
    }
2403
    fp_copy_2_ct(&R[2], &R[3], &R[0], &R[1], y, P->used);
2404
  }
2405
2406
  err = fp_montgomery_reduce(&R[0], P, mp);
2407
  fp_copy(&R[0], Y);
2408
#ifdef WOLFSSL_SMALL_STACK
2409
  XFREE(R, NULL, DYNAMIC_TYPE_BIGINT);
2410
#endif
2411
  return err;
2412
}
2413
2414
#endif /* WC_PROTECT_ENCRYPTED_MEM */
2415
2416
#endif /* TFM_TIMING_RESISTANT */
2417
2418
/* y = g**x (mod b)
2419
 * Some restrictions... x must be positive and < b
2420
 */
2421
static int _fp_exptmod_nct(fp_int * G, fp_int * X, fp_int * P, fp_int * Y)
2422
0
{
2423
0
  fp_int  *res;
2424
0
  fp_digit buf, mp;
2425
0
  int      err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
2426
0
#ifndef WOLFSSL_NO_MALLOC
2427
0
  fp_int  *M;
2428
#else
2429
  fp_int   M[(1 << 6) + 1];
2430
#endif
2431
2432
  /* find window size */
2433
0
  x = fp_count_bits (X);
2434
0
  if (x <= 21) {
2435
0
    winsize = 1;
2436
0
  } else if (x <= 36) {
2437
0
    winsize = 3;
2438
0
  } else if (x <= 140) {
2439
0
    winsize = 4;
2440
0
  } else if (x <= 450) {
2441
0
    winsize = 5;
2442
0
  } else {
2443
0
    winsize = 6;
2444
0
  }
2445
2446
  /* now setup montgomery  */
2447
0
  if ((err = fp_montgomery_setup (P, &mp)) != FP_OKAY) {
2448
0
     return err;
2449
0
  }
2450
2451
0
#ifndef WOLFSSL_NO_MALLOC
2452
  /* only allocate space for what's needed for window plus res */
2453
0
  M = (fp_int*)XMALLOC(sizeof(fp_int)*((1 << winsize) + 1), NULL,
2454
0
                                                           DYNAMIC_TYPE_BIGINT);
2455
0
  if (M == NULL) {
2456
0
     return FP_MEM;
2457
0
  }
2458
0
#endif
2459
0
  res = &M[(word32)(1 << winsize)];
2460
2461
  /* init M array */
2462
0
  for(x = 0; x < (1 << winsize); x++)
2463
0
    fp_init(&M[x]);
2464
2465
  /* setup result */
2466
0
  fp_init(res);
2467
2468
  /* create M table
2469
   *
2470
   * The M table contains powers of the input base, e.g. M[x] = G^x mod P
2471
   *
2472
   * The first half of the table is not computed though except for M[0] and M[1]
2473
   */
2474
2475
  /* now we need R mod m */
2476
0
  err = fp_montgomery_calc_normalization (res, P);
2477
0
  if (err != FP_OKAY) {
2478
0
#ifndef WOLFSSL_NO_MALLOC
2479
0
    XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);
2480
0
#endif
2481
0
    return err;
2482
0
  }
2483
2484
  /* now set M[1] to G * R mod m */
2485
0
  if (fp_cmp_mag(P, G) != FP_GT) {
2486
     /* G > P so we reduce it first */
2487
0
     err = fp_mod(G, P, &M[1]);
2488
0
     if (err != FP_OKAY) {
2489
0
     #ifndef WOLFSSL_NO_MALLOC
2490
0
        XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);
2491
0
     #endif
2492
0
        return err;
2493
0
     }
2494
0
  } else {
2495
0
     fp_copy(G, &M[1]);
2496
0
  }
2497
0
  err = fp_mulmod (&M[1], res, P, &M[1]);
2498
0
  if (err != FP_OKAY) {
2499
0
  #ifndef WOLFSSL_NO_MALLOC
2500
0
     XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);
2501
0
  #endif
2502
0
     return err;
2503
0
  }
2504
2505
  /* compute the value at M[1<<(winsize-1)] by
2506
   * squaring M[1] (winsize-1) times */
2507
0
  fp_copy (&M[1], &M[(word32)(1 << (winsize - 1))]);
2508
0
  for (x = 0; x < (winsize - 1); x++) {
2509
0
    err = fp_sqr (&M[(word32)(1 << (winsize - 1))],
2510
0
                  &M[(word32)(1 << (winsize - 1))]);
2511
0
    if (err != FP_OKAY) {
2512
0
#ifndef WOLFSSL_NO_MALLOC
2513
0
      XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);
2514
0
#endif
2515
0
      return err;
2516
0
    }
2517
0
    err = fp_montgomery_reduce_ex(&M[(word32)(1 << (winsize - 1))], P, mp, 0);
2518
0
    if (err != FP_OKAY) {
2519
0
#ifndef WOLFSSL_NO_MALLOC
2520
0
      XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);
2521
0
#endif
2522
0
      return err;
2523
0
    }
2524
0
  }
2525
2526
  /* create upper table */
2527
0
  for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
2528
0
    err = fp_mul(&M[x - 1], &M[1], &M[x]);
2529
0
    if (err != FP_OKAY) {
2530
0
#ifndef WOLFSSL_NO_MALLOC
2531
0
      XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);
2532
0
#endif
2533
0
      return err;
2534
0
    }
2535
0
    err = fp_montgomery_reduce_ex(&M[x], P, mp, 0);
2536
0
    if (err != FP_OKAY) {
2537
0
#ifndef WOLFSSL_NO_MALLOC
2538
0
      XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);
2539
0
#endif
2540
0
      return err;
2541
0
    }
2542
0
  }
2543
2544
  /* set initial mode and bit cnt */
2545
0
  mode   = 0;
2546
0
  bitcnt = (x % DIGIT_BIT) + 1;
2547
0
  buf    = 0;
2548
0
  digidx = X->used - 1;
2549
0
  bitcpy = 0;
2550
0
  bitbuf = 0;
2551
2552
0
  for (;;) {
2553
    /* grab next digit as required */
2554
0
    if (--bitcnt == 0) {
2555
      /* if digidx == -1 we are out of digits so break */
2556
0
      if (digidx == -1) {
2557
0
        break;
2558
0
      }
2559
      /* read next digit and reset bitcnt */
2560
0
      buf    = X->dp[digidx--];
2561
0
      bitcnt = (int)DIGIT_BIT;
2562
0
    }
2563
2564
    /* grab the next msb from the exponent */
2565
0
    y     = (int)(buf >> (DIGIT_BIT - 1)) & 1;
2566
0
    buf <<= (fp_digit)1;
2567
2568
    /* if the bit is zero and mode == 0 then we ignore it
2569
     * These represent the leading zero bits before the first 1 bit
2570
     * in the exponent.  Technically this opt is not required but it
2571
     * does lower the # of trivial squaring/reductions used
2572
     */
2573
0
    if (mode == 0 && y == 0) {
2574
0
      continue;
2575
0
    }
2576
2577
    /* if the bit is zero and mode == 1 then we square */
2578
0
    if (mode == 1 && y == 0) {
2579
0
      err = fp_sqr(res, res);
2580
0
      if (err != FP_OKAY) {
2581
0
#ifndef WOLFSSL_NO_MALLOC
2582
0
        XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);
2583
0
#endif
2584
0
        return err;
2585
0
      }
2586
0
      err = fp_montgomery_reduce_ex(res, P, mp, 0);
2587
0
      if (err != FP_OKAY) {
2588
0
#ifndef WOLFSSL_NO_MALLOC
2589
0
        XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);
2590
0
#endif
2591
0
        return err;
2592
0
      }
2593
0
      continue;
2594
0
    }
2595
2596
    /* else we add it to the window */
2597
0
    bitbuf |= (y << (winsize - ++bitcpy));
2598
0
    mode    = 2;
2599
2600
0
    if (bitcpy == winsize) {
2601
      /* ok window is filled so square as required and multiply  */
2602
      /* square first */
2603
0
      for (x = 0; x < winsize; x++) {
2604
0
        err = fp_sqr(res, res);
2605
0
        if (err != FP_OKAY) {
2606
0
#ifndef WOLFSSL_NO_MALLOC
2607
0
          XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);
2608
0
#endif
2609
0
          return err;
2610
0
        }
2611
0
        err = fp_montgomery_reduce_ex(res, P, mp, 0);
2612
0
        if (err != FP_OKAY) {
2613
0
#ifndef WOLFSSL_NO_MALLOC
2614
0
          XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);
2615
0
#endif
2616
0
          return err;
2617
0
        }
2618
0
      }
2619
2620
      /* then multiply */
2621
0
      err = fp_mul(res, &M[bitbuf], res);
2622
0
      if (err != FP_OKAY) {
2623
0
#ifndef WOLFSSL_NO_MALLOC
2624
0
        XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);
2625
0
#endif
2626
0
        return err;
2627
0
      }
2628
0
      err = fp_montgomery_reduce_ex(res, P, mp, 0);
2629
0
      if (err != FP_OKAY) {
2630
0
#ifndef WOLFSSL_NO_MALLOC
2631
0
        XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);
2632
0
#endif
2633
0
        return err;
2634
0
      }
2635
2636
      /* empty window and reset */
2637
0
      bitcpy = 0;
2638
0
      bitbuf = 0;
2639
0
      mode   = 1;
2640
0
    }
2641
0
  }
2642
2643
  /* if bits remain then square/multiply */
2644
0
  if (mode == 2 && bitcpy > 0) {
2645
    /* square then multiply if the bit is set */
2646
0
    for (x = 0; x < bitcpy; x++) {
2647
0
      err = fp_sqr(res, res);
2648
0
      if (err != FP_OKAY) {
2649
0
#ifndef WOLFSSL_NO_MALLOC
2650
0
        XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);
2651
0
#endif
2652
0
        return err;
2653
0
      }
2654
0
      err = fp_montgomery_reduce_ex(res, P, mp, 0);
2655
0
      if (err != FP_OKAY) {
2656
0
#ifndef WOLFSSL_NO_MALLOC
2657
0
        XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);
2658
0
#endif
2659
0
        return err;
2660
0
      }
2661
2662
      /* get next bit of the window */
2663
0
      bitbuf <<= 1;
2664
0
      if ((bitbuf & (1 << winsize)) != 0) {
2665
        /* then multiply */
2666
0
        err = fp_mul(res, &M[1], res);
2667
0
        if (err != FP_OKAY) {
2668
0
#ifndef WOLFSSL_NO_MALLOC
2669
0
          XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);
2670
0
#endif
2671
0
          return err;
2672
0
        }
2673
0
        err = fp_montgomery_reduce_ex(res, P, mp, 0);
2674
0
        if (err != FP_OKAY) {
2675
0
#ifndef WOLFSSL_NO_MALLOC
2676
0
          XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);
2677
0
#endif
2678
0
          return err;
2679
0
        }
2680
0
      }
2681
0
    }
2682
0
  }
2683
2684
  /* fixup result if Montgomery reduction is used
2685
   * recall that any value in a Montgomery system is
2686
   * actually multiplied by R mod n.  So we have
2687
   * to reduce one more time to cancel out the factor
2688
   * of R.
2689
   */
2690
0
  err = fp_montgomery_reduce_ex(res, P, mp, 0);
2691
2692
  /* swap res with Y */
2693
0
  fp_copy (res, Y);
2694
2695
0
#ifndef WOLFSSL_NO_MALLOC
2696
0
  XFREE(M, NULL, DYNAMIC_TYPE_BIGINT);
2697
0
#endif
2698
0
  return err;
2699
0
}
2700
2701
2702
#ifdef TFM_TIMING_RESISTANT
2703
#if DIGIT_BIT <= 16
2704
    #define WINSIZE    2
2705
    #define WINMASK    0x3
2706
#elif DIGIT_BIT <= 32
2707
    #define WINSIZE    3
2708
    #define WINMASK    0x7
2709
#elif DIGIT_BIT <= 64
2710
0
    #define WINSIZE    4
2711
    #define WINMASK    0xf
2712
#elif DIGIT_BIT <= 128
2713
    #define WINSIZE    5
2714
    #define WINMASK    0x1f
2715
#endif
2716
2717
/* y = 2**x (mod b)
2718
 * Some restrictions... x must be positive and < b
2719
 */
2720
static int _fp_exptmod_base_2(fp_int * X, int digits, fp_int * P,
2721
                              fp_int * Y)
2722
0
{
2723
0
  fp_digit buf, mp;
2724
0
  int      err, bitbuf, bitcpy, bitcnt, digidx, x, y;
2725
0
#ifdef WOLFSSL_SMALL_STACK
2726
0
  fp_int  *res;
2727
0
  fp_int  *tmp;
2728
#else
2729
  fp_int   res[1];
2730
  fp_int   tmp[1];
2731
#endif
2732
2733
0
#ifdef WOLFSSL_SMALL_STACK
2734
0
  res = (fp_int*)XMALLOC(2*sizeof(fp_int), NULL, DYNAMIC_TYPE_TMP_BUFFER);
2735
0
  if (res == NULL) {
2736
0
     return FP_MEM;
2737
0
  }
2738
0
  tmp = &res[1];
2739
0
#endif
2740
2741
  /* now setup montgomery  */
2742
0
  if ((err = fp_montgomery_setup(P, &mp)) != FP_OKAY) {
2743
0
#ifdef WOLFSSL_SMALL_STACK
2744
0
     XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2745
0
#endif
2746
0
     return err;
2747
0
  }
2748
2749
  /* setup result */
2750
0
  fp_init(res);
2751
0
  fp_init(tmp);
2752
2753
0
  err = fp_mul_2d(P, 1 << WINSIZE, tmp);
2754
0
  if (err != FP_OKAY) {
2755
0
  #ifdef WOLFSSL_SMALL_STACK
2756
0
    XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2757
0
  #endif
2758
0
    return err;
2759
0
  }
2760
2761
  /* now we need R mod m */
2762
0
  err = fp_montgomery_calc_normalization(res, P);
2763
0
  if (err != FP_OKAY) {
2764
0
  #ifdef WOLFSSL_SMALL_STACK
2765
0
    XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2766
0
  #endif
2767
0
    return err;
2768
0
  }
2769
2770
  /* Get the top bits left over after taking WINSIZE bits starting at the
2771
   * least-significant.
2772
   */
2773
0
  digidx = digits - 1;
2774
0
  bitcpy = (digits * DIGIT_BIT) % WINSIZE;
2775
0
  if (bitcpy > 0) {
2776
0
      bitcnt = (int)DIGIT_BIT - bitcpy;
2777
0
      buf    = X->dp[digidx--];
2778
0
      bitbuf = (int)(buf >> bitcnt);
2779
      /* Multiply montgomery representation of 1 by 2 ^ top */
2780
0
      err = fp_mul_2d(res, bitbuf, res);
2781
0
      if (err != FP_OKAY) {
2782
0
      #ifdef WOLFSSL_SMALL_STACK
2783
0
        XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2784
0
      #endif
2785
0
        return err;
2786
0
      }
2787
0
      err = fp_add(res, tmp, res);
2788
0
      if (err != FP_OKAY) {
2789
0
      #ifdef WOLFSSL_SMALL_STACK
2790
0
        XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2791
0
      #endif
2792
0
        return err;
2793
0
      }
2794
0
      err = fp_mod(res, P, res);
2795
0
      if (err != FP_OKAY) {
2796
0
      #ifdef WOLFSSL_SMALL_STACK
2797
0
        XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2798
0
      #endif
2799
0
        return err;
2800
0
      }
2801
      /* Move out bits used */
2802
0
      buf  <<= bitcpy;
2803
0
      bitcnt++;
2804
0
  }
2805
0
  else {
2806
0
      bitcnt = 1;
2807
0
      buf    = 0;
2808
0
  }
2809
2810
  /* empty window and reset  */
2811
0
  bitbuf = 0;
2812
0
  bitcpy = 0;
2813
2814
0
  for (;;) {
2815
    /* grab next digit as required */
2816
0
    if (--bitcnt == 0) {
2817
      /* if digidx == -1 we are out of digits so break */
2818
0
      if (digidx == -1) {
2819
0
        break;
2820
0
      }
2821
      /* read next digit and reset bitcnt */
2822
0
      buf    = X->dp[digidx--];
2823
0
      bitcnt = (int)DIGIT_BIT;
2824
0
    }
2825
2826
    /* grab the next msb from the exponent */
2827
0
    y       = (int)(buf >> (DIGIT_BIT - 1)) & 1;
2828
0
    buf   <<= (fp_digit)1;
2829
    /* add bit to the window */
2830
0
  #ifndef WC_PROTECT_ENCRYPTED_MEM
2831
0
    bitbuf |= (y << (WINSIZE - ++bitcpy));
2832
  #else
2833
    /* Ensure value changes even when y is zero. */
2834
    bitbuf += (WINMASK + 1) + (y << (WINSIZE - ++bitcpy));
2835
  #endif
2836
2837
0
    if (bitcpy == WINSIZE) {
2838
      /* ok window is filled so square as required and multiply  */
2839
      /* square first */
2840
0
      for (x = 0; x < WINSIZE; x++) {
2841
0
        err = fp_sqr(res, res);
2842
0
        if (err != FP_OKAY) {
2843
0
        #ifdef WOLFSSL_SMALL_STACK
2844
0
          XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2845
0
        #endif
2846
0
          return err;
2847
0
        }
2848
0
        err = fp_montgomery_reduce(res, P, mp);
2849
0
        if (err != FP_OKAY) {
2850
0
        #ifdef WOLFSSL_SMALL_STACK
2851
0
          XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2852
0
        #endif
2853
0
          return err;
2854
0
        }
2855
0
      }
2856
2857
      /* then multiply by 2^bitbuf */
2858
0
    #ifndef WC_PROTECT_ENCRYPTED_MEM
2859
0
      err = fp_mul_2d(res, bitbuf, res);
2860
    #else
2861
      /* Get the window bits. */
2862
      err = fp_mul_2d(res, bitbuf & WINMASK, res);
2863
    #endif
2864
0
      if (err != FP_OKAY) {
2865
0
      #ifdef WOLFSSL_SMALL_STACK
2866
0
        XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2867
0
      #endif
2868
0
        return err;
2869
0
      }
2870
      /* Add in value to make mod operation take same time */
2871
0
      err = fp_add(res, tmp, res);
2872
0
      if (err != FP_OKAY) {
2873
0
      #ifdef WOLFSSL_SMALL_STACK
2874
0
        XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2875
0
      #endif
2876
0
        return err;
2877
0
      }
2878
0
      err = fp_mod(res, P, res);
2879
0
      if (err != FP_OKAY) {
2880
0
      #ifdef WOLFSSL_SMALL_STACK
2881
0
        XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2882
0
      #endif
2883
0
        return err;
2884
0
      }
2885
2886
      /* empty window and reset */
2887
0
      bitcpy = 0;
2888
0
    #ifndef WC_PROTECT_ENCRYPTED_MEM
2889
0
      bitbuf = 0;
2890
    #else
2891
      /* Ensure value is new even when bottom bits are 0. */
2892
      bitbuf = (WINMASK + 1) + (bitbuf & ~WINMASK);
2893
    #endif
2894
0
    }
2895
0
  }
2896
2897
  /* fixup result if Montgomery reduction is used
2898
   * recall that any value in a Montgomery system is
2899
   * actually multiplied by R mod n.  So we have
2900
   * to reduce one more time to cancel out the factor
2901
   * of R.
2902
   */
2903
0
  err = fp_montgomery_reduce(res, P, mp);
2904
2905
  /* swap res with Y */
2906
0
  fp_copy(res, Y);
2907
2908
0
#ifdef WOLFSSL_SMALL_STACK
2909
0
  XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2910
0
#endif
2911
0
  return err;
2912
0
}
2913
2914
#undef WINSIZE
2915
#else
2916
#if DIGIT_BIT < 16
2917
    #define WINSIZE    3
2918
#elif DIGIT_BIT < 32
2919
    #define WINSIZE    4
2920
#elif DIGIT_BIT < 64
2921
    #define WINSIZE    5
2922
#elif DIGIT_BIT < 128
2923
    #define WINSIZE    6
2924
#elif DIGIT_BIT == 128
2925
    #define WINSIZE    7
2926
#endif
2927
2928
/* y = 2**x (mod b)
2929
 * Some restrictions... x must be positive and < b
2930
 */
2931
static int _fp_exptmod_base_2(fp_int * X, int digits, fp_int * P,
2932
                              fp_int * Y)
2933
{
2934
  fp_digit buf, mp;
2935
  int      err, bitbuf, bitcpy, bitcnt, digidx, x, y;
2936
#ifdef WOLFSSL_SMALL_STACK
2937
  fp_int  *res;
2938
#else
2939
  fp_int   res[1];
2940
#endif
2941
2942
  /* now setup montgomery  */
2943
  if ((err = fp_montgomery_setup(P, &mp)) != FP_OKAY) {
2944
    return err;
2945
  }
2946
2947
#ifdef WOLFSSL_SMALL_STACK
2948
  res = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_TMP_BUFFER);
2949
  if (res == NULL) {
2950
     return FP_MEM;
2951
  }
2952
#endif
2953
2954
  /* setup result */
2955
  fp_init(res);
2956
2957
  /* now we need R mod m */
2958
  err = fp_montgomery_calc_normalization(res, P);
2959
  if (err != FP_OKAY) {
2960
  #ifdef WOLFSSL_SMALL_STACK
2961
    XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2962
  #endif
2963
    return err;
2964
  }
2965
2966
  /* Get the top bits left over after taking WINSIZE bits starting at the
2967
   * least-significant.
2968
   */
2969
  digidx = digits - 1;
2970
  bitcpy = (digits * DIGIT_BIT) % WINSIZE;
2971
  if (bitcpy > 0) {
2972
      bitcnt = (int)DIGIT_BIT - bitcpy;
2973
      buf    = X->dp[digidx--];
2974
      bitbuf = (int)(buf >> bitcnt);
2975
      /* Multiply montgomery representation of 1 by 2 ^ top */
2976
      err = fp_mul_2d(res, bitbuf, res);
2977
      if (err != FP_OKAY) {
2978
      #ifdef WOLFSSL_SMALL_STACK
2979
        XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2980
      #endif
2981
        return err;
2982
      }
2983
      err = fp_mod(res, P, res);
2984
      if (err != FP_OKAY) {
2985
      #ifdef WOLFSSL_SMALL_STACK
2986
        XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2987
      #endif
2988
        return err;
2989
      }
2990
      /* Move out bits used */
2991
      buf  <<= bitcpy;
2992
      bitcnt++;
2993
  }
2994
  else {
2995
      bitcnt = 1;
2996
      buf    = 0;
2997
  }
2998
2999
  /* empty window and reset  */
3000
  bitbuf = 0;
3001
  bitcpy = 0;
3002
3003
  for (;;) {
3004
    /* grab next digit as required */
3005
    if (--bitcnt == 0) {
3006
      /* if digidx == -1 we are out of digits so break */
3007
      if (digidx == -1) {
3008
        break;
3009
      }
3010
      /* read next digit and reset bitcnt */
3011
      buf    = X->dp[digidx--];
3012
      bitcnt = (int)DIGIT_BIT;
3013
    }
3014
3015
    /* grab the next msb from the exponent */
3016
    y       = (int)(buf >> (DIGIT_BIT - 1)) & 1;
3017
    buf   <<= (fp_digit)1;
3018
    /* add bit to the window */
3019
    bitbuf |= (y << (WINSIZE - ++bitcpy));
3020
3021
    if (bitcpy == WINSIZE) {
3022
      /* ok window is filled so square as required and multiply  */
3023
      /* square first */
3024
      for (x = 0; x < WINSIZE; x++) {
3025
        err = fp_sqr(res, res);
3026
        if (err != FP_OKAY) {
3027
        #ifdef WOLFSSL_SMALL_STACK
3028
          XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3029
        #endif
3030
          return err;
3031
        }
3032
        err = fp_montgomery_reduce(res, P, mp);
3033
        if (err != FP_OKAY) {
3034
        #ifdef WOLFSSL_SMALL_STACK
3035
          XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3036
        #endif
3037
          return err;
3038
        }
3039
      }
3040
3041
      /* then multiply by 2^bitbuf */
3042
      err = fp_mul_2d(res, bitbuf, res);
3043
      if (err != FP_OKAY) {
3044
      #ifdef WOLFSSL_SMALL_STACK
3045
        XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3046
      #endif
3047
        return err;
3048
      }
3049
      err = fp_mod(res, P, res);
3050
      if (err != FP_OKAY) {
3051
      #ifdef WOLFSSL_SMALL_STACK
3052
        XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3053
      #endif
3054
        return err;
3055
      }
3056
3057
      /* empty window and reset */
3058
      bitcpy = 0;
3059
      bitbuf = 0;
3060
    }
3061
  }
3062
3063
  /* fixup result if Montgomery reduction is used
3064
   * recall that any value in a Montgomery system is
3065
   * actually multiplied by R mod n.  So we have
3066
   * to reduce one more time to cancel out the factor
3067
   * of R.
3068
   */
3069
  err = fp_montgomery_reduce(res, P, mp);
3070
3071
  /* swap res with Y */
3072
  fp_copy(res, Y);
3073
3074
#ifdef WOLFSSL_SMALL_STACK
3075
  XFREE(res, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3076
#endif
3077
  return err;
3078
}
3079
3080
#undef WINSIZE
3081
#endif
3082
3083
/* Y = (G * X) mod P */
3084
int fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y)
3085
0
{
3086
#if defined(WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD)
3087
    int retHW = FP_OKAY;
3088
#endif
3089
3090
   /* handle modulus of zero and prevent overflows */
3091
0
   if (fp_iszero(P) || (P->used > (FP_SIZE/2))) {
3092
0
      return FP_VAL;
3093
0
   }
3094
0
   if (fp_isone(P)) {
3095
0
      fp_set(Y, 0);
3096
0
      return FP_OKAY;
3097
0
   }
3098
0
   if (fp_iszero(X)) {
3099
0
      fp_set(Y, 1);
3100
0
      return FP_OKAY;
3101
0
   }
3102
0
   if (fp_iszero(G)) {
3103
0
      fp_set(Y, 0);
3104
0
      return FP_OKAY;
3105
0
   }
3106
3107
#if defined(WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD)
3108
   if (esp_hw_validation_active()) {
3109
      ESP_LOGV(TAG, "Skipping call to esp_mp_exptmod "
3110
                    "during active validation.");
3111
   }
3112
   else {
3113
      /* HW accelerated exptmod  */
3114
      retHW = esp_mp_exptmod(G, X, P, Y);
3115
      switch (retHW) {
3116
         case MP_OKAY:
3117
            /* successfully computed in HW */
3118
            return retHW;
3119
            break;
3120
3121
         case WC_NO_ERR_TRACE(WC_HW_WAIT_E): /* MP_HW_BUSY math HW busy, fall back */
3122
         case MP_HW_FALLBACK:    /* forced fallback from HW to SW */
3123
         case WC_NO_ERR_TRACE(MP_HW_VALIDATION_ACTIVE): /* use SW to compare to HW */
3124
            /* use software calc */
3125
            break;
3126
3127
         default:
3128
            /* Once we've failed, exit without trying to continue.
3129
             * We may have mangled operands: (e.g. Z = X * Z)
3130
             * Future implementation may consider saving operands,
3131
             * but hard errors should never actually occur. */
3132
            return retHW; /* error */
3133
            break;
3134
      } /* switch */
3135
   } /* if validation check */
3136
   /* fall through to software calcs */
3137
#endif /* WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD */
3138
3139
0
   if (X->sign == FP_NEG) {
3140
0
#ifndef POSITIVE_EXP_ONLY  /* reduce stack if assume no negatives */
3141
0
      int    err;
3142
   #ifndef WOLFSSL_SMALL_STACK
3143
      fp_int tmp[2];
3144
   #else
3145
0
      fp_int *tmp;
3146
0
   #endif
3147
3148
0
   #ifdef WOLFSSL_SMALL_STACK
3149
0
      tmp = (fp_int*)XMALLOC(sizeof(fp_int) * 2, NULL, DYNAMIC_TYPE_BIGINT);
3150
0
      if (tmp == NULL)
3151
0
          return FP_MEM;
3152
0
   #endif
3153
3154
      /* yes, copy G and invmod it */
3155
0
      fp_init_copy(&tmp[0], G);
3156
0
      fp_init_copy(&tmp[1], P);
3157
0
      tmp[1].sign = FP_ZPOS;
3158
0
      err = fp_invmod(&tmp[0], &tmp[1], &tmp[0]);
3159
0
      if (err == FP_OKAY) {
3160
0
         fp_copy(X, &tmp[1]);
3161
0
         tmp[1].sign = FP_ZPOS;
3162
0
   #ifdef TFM_TIMING_RESISTANT
3163
0
         err =  _fp_exptmod_ct(&tmp[0], &tmp[1], tmp[1].used, P, Y);
3164
   #else
3165
         err =  _fp_exptmod_nct(&tmp[0], &tmp[1], P, Y);
3166
   #endif
3167
0
         if ((err == 0) && (P->sign == FP_NEG)) {
3168
0
            err = fp_add(Y, P, Y);
3169
0
         }
3170
0
      }
3171
0
   #ifdef WOLFSSL_SMALL_STACK
3172
0
      XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3173
0
   #endif
3174
0
      return err;
3175
#else
3176
      return FP_VAL;
3177
#endif /* POSITIVE_EXP_ONLY check */
3178
0
   }
3179
0
   else if (G->used == 1 && G->dp[0] == 2) {
3180
0
      return _fp_exptmod_base_2(X, X->used, P, Y);
3181
0
   }
3182
0
   else {
3183
      /* Positive exponent so just exptmod */
3184
0
#ifdef TFM_TIMING_RESISTANT
3185
0
      return _fp_exptmod_ct(G, X, X->used, P, Y);
3186
#else
3187
      return _fp_exptmod_nct(G, X, P, Y);
3188
#endif
3189
0
   }
3190
0
}
3191
3192
int fp_exptmod_ex(fp_int * G, fp_int * X, int digits, fp_int * P, fp_int * Y)
3193
0
{
3194
#if defined(WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD)
3195
   int retHW = FP_OKAY;
3196
#endif
3197
3198
   /* handle modulus of zero and prevent overflows */
3199
0
   if (fp_iszero(P) || (P->used > (FP_SIZE/2))) {
3200
0
      return FP_VAL;
3201
0
   }
3202
0
   if (fp_isone(P)) {
3203
0
      fp_set(Y, 0);
3204
0
      return FP_OKAY;
3205
0
   }
3206
0
   if (fp_iszero(X)) {
3207
0
      fp_set(Y, 1);
3208
0
      return FP_OKAY;
3209
0
   }
3210
0
   if (fp_iszero(G)) {
3211
0
      fp_set(Y, 0);
3212
0
      return FP_OKAY;
3213
0
   }
3214
3215
#if defined(WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD)
3216
   retHW = esp_mp_exptmod(G, X, P, Y);
3217
   switch (retHW) {
3218
      case MP_OKAY:
3219
         /* successfully computed in HW */
3220
         return retHW;
3221
         break;
3222
3223
      case WC_NO_ERR_TRACE(WC_HW_WAIT_E): /* MP_HW_BUSY math HW busy, fall back */
3224
      case MP_HW_FALLBACK:    /* forced fallback from HW to SW */
3225
      case MP_HW_VALIDATION_ACTIVE: /* use SW to compare to HW */
3226
         /* use software calc */
3227
         break;
3228
3229
      default:
3230
         /* Once we've failed, exit without trying to continue.
3231
          * We may have mangled operands: (e.g. Z = X * Z)
3232
          * Future implementation may consider saving operands,
3233
          * but hard errors should never actually occur. */
3234
         return retHW;
3235
         break;
3236
   } /* HW result switch */
3237
   /* falling through to SW: */
3238
#endif /* WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD */
3239
3240
0
   if (X->sign == FP_NEG) {
3241
0
#ifndef POSITIVE_EXP_ONLY  /* reduce stack if assume no negatives */
3242
0
      int    err;
3243
   #ifndef WOLFSSL_SMALL_STACK
3244
      fp_int tmp[2];
3245
   #else
3246
0
      fp_int *tmp;
3247
0
   #endif
3248
3249
0
   #ifdef WOLFSSL_SMALL_STACK
3250
0
      tmp = (fp_int*)XMALLOC(sizeof(fp_int) * 2, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3251
0
      if (tmp == NULL)
3252
0
          return FP_MEM;
3253
0
   #endif
3254
3255
      /* yes, copy G and invmod it */
3256
0
      fp_init_copy(&tmp[0], G);
3257
0
      fp_init_copy(&tmp[1], P);
3258
0
      tmp[1].sign = FP_ZPOS;
3259
0
      err = fp_invmod(&tmp[0], &tmp[1], &tmp[0]);
3260
0
      if (err == FP_OKAY) {
3261
0
         X->sign = FP_ZPOS;
3262
0
#ifdef TFM_TIMING_RESISTANT
3263
0
         err =  _fp_exptmod_ct(&tmp[0], X, digits, P, Y);
3264
#else
3265
         err =  _fp_exptmod_nct(&tmp[0], X, P, Y);
3266
         (void)digits;
3267
#endif
3268
0
         if (X != Y) {
3269
0
            X->sign = FP_NEG;
3270
0
         }
3271
0
         if ((err == 0) && (P->sign == FP_NEG)) {
3272
0
            err = fp_add(Y, P, Y);
3273
0
         }
3274
0
      }
3275
0
   #ifdef WOLFSSL_SMALL_STACK
3276
0
      XFREE(tmp, NULL, DYNAMIC_TYPE_BIGINT);
3277
0
   #endif
3278
0
      return err;
3279
#else
3280
      return FP_VAL;
3281
#endif
3282
0
   }
3283
0
   else {
3284
      /* Positive exponent so just exptmod */
3285
0
#ifdef TFM_TIMING_RESISTANT
3286
0
      return _fp_exptmod_ct(G, X, digits, P, Y);
3287
#else
3288
      return  _fp_exptmod_nct(G, X, P, Y);
3289
#endif
3290
0
   }
3291
0
}
3292
3293
int fp_exptmod_nct(fp_int * G, fp_int * X, fp_int * P, fp_int * Y)
3294
0
{
3295
#if defined(WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD)
3296
   int retHW = FP_OKAY;
3297
#endif
3298
3299
   /* handle modulus of zero and prevent overflows */
3300
0
   if (fp_iszero(P) || (P->used > (FP_SIZE/2))) {
3301
0
      return FP_VAL;
3302
0
   }
3303
0
   if (fp_isone(P)) {
3304
0
      fp_set(Y, 0);
3305
0
      return FP_OKAY;
3306
0
   }
3307
0
   if (fp_iszero(X)) {
3308
0
      fp_set(Y, 1);
3309
0
      return FP_OKAY;
3310
0
   }
3311
0
   if (fp_iszero(G)) {
3312
0
      fp_set(Y, 0);
3313
0
      return FP_OKAY;
3314
0
   }
3315
3316
#if defined(WOLFSSL_ESP32_CRYPT_RSA_PRI_EXPTMOD)
3317
   retHW = esp_mp_exptmod(G, X, P, Y);
3318
   switch (retHW) {
3319
      case MP_OKAY:
3320
         /* successfully computed in HW */
3321
         return retHW;
3322
         break;
3323
3324
      case WC_NO_ERR_TRACE(WC_HW_WAIT_E): /* MP_HW_BUSY math HW busy, fall back */
3325
      case MP_HW_FALLBACK:    /* forced fallback from HW to SW */
3326
      case MP_HW_VALIDATION_ACTIVE: /* use SW to compare to HW */
3327
         /* use software calc */
3328
         break;
3329
3330
      default:
3331
         /* Once we've failed, exit without trying to continue.
3332
          * We may have mangled operands: (e.g. Z = X * Z)
3333
          * Future implementation may consider saving operands,
3334
          * but hard errors should never actually occur. */
3335
         return retHW;
3336
         break;
3337
   }
3338
   /* falling through to SW: */
3339
#endif
3340
3341
0
   if (X->sign == FP_NEG) {
3342
0
#ifndef POSITIVE_EXP_ONLY  /* reduce stack if assume no negatives */
3343
0
      int    err;
3344
   #ifndef WOLFSSL_SMALL_STACK
3345
      fp_int tmp[2];
3346
   #else
3347
0
      fp_int *tmp;
3348
0
   #endif
3349
3350
0
   #ifdef WOLFSSL_SMALL_STACK
3351
0
      tmp = (fp_int*)XMALLOC(sizeof(fp_int) * 2, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3352
0
      if (tmp == NULL)
3353
0
          return FP_MEM;
3354
0
   #endif
3355
3356
      /* yes, copy G and invmod it */
3357
0
      fp_init_copy(&tmp[0], G);
3358
0
      fp_init_copy(&tmp[1], P);
3359
0
      tmp[1].sign = FP_ZPOS;
3360
0
      err = fp_invmod(&tmp[0], &tmp[1], &tmp[0]);
3361
0
      if (err == FP_OKAY) {
3362
0
         X->sign = FP_ZPOS;
3363
0
         err =  _fp_exptmod_nct(&tmp[0], X, P, Y);
3364
0
         if (X != Y) {
3365
0
            X->sign = FP_NEG;
3366
0
         }
3367
0
         if ((err == 0) && (P->sign == FP_NEG)) {
3368
0
            err = fp_add(Y, P, Y);
3369
0
         }
3370
0
      }
3371
0
   #ifdef WOLFSSL_SMALL_STACK
3372
0
      XFREE(tmp, NULL, DYNAMIC_TYPE_BIGINT);
3373
0
   #endif
3374
0
      return err;
3375
#else
3376
      return FP_VAL;
3377
#endif
3378
0
   }
3379
0
   else {
3380
      /* Positive exponent so just exptmod */
3381
0
      return  _fp_exptmod_nct(G, X, P, Y);
3382
0
   }
3383
0
}
3384
3385
/* computes a = 2**b */
3386
void fp_2expt(fp_int *a, int b)
3387
0
{
3388
0
   int     z;
3389
3390
   /* zero a as per default */
3391
0
   fp_zero (a);
3392
3393
0
   if (b < 0) {
3394
0
      return;
3395
0
   }
3396
3397
0
   z = b / DIGIT_BIT;
3398
0
   if (z >= FP_SIZE) {
3399
0
      return;
3400
0
   }
3401
3402
  /* set the used count of where the bit will go */
3403
0
  a->used = z + 1;
3404
3405
  /* put the single bit in its place */
3406
0
  a->dp[z] = ((fp_digit)1) << (b % DIGIT_BIT);
3407
0
}
3408
3409
/* b = a*a  */
3410
int fp_sqr(fp_int *A, fp_int *B)
3411
0
{
3412
0
    int err;
3413
0
    int y, oldused;
3414
3415
0
    oldused = B->used;
3416
0
    y = A->used;
3417
3418
    /* error if we're out of range */
3419
0
    if (y + y >= FP_SIZE) {
3420
0
       err = FP_VAL;
3421
0
       goto clean;
3422
0
    }
3423
3424
#if defined(WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL)
3425
    if (esp_hw_validation_active()) {
3426
        ESP_LOGV(TAG, "Skipping call to esp_mp_mul "
3427
                      "during active validation.");
3428
    }
3429
    else {
3430
        err = esp_mp_mul(A, A, B); /* HW accelerated multiply  */
3431
        switch (err) {
3432
            case MP_OKAY:
3433
                goto clean; /* success */
3434
                break;
3435
3436
            case WC_NO_ERR_TRACE(WC_HW_WAIT_E): /* MP_HW_BUSY math HW busy, fall back */
3437
            case MP_HW_FALLBACK:    /* forced fallback from HW to SW */
3438
            case MP_HW_VALIDATION_ACTIVE: /* use SW to compare to HW */
3439
                /* fall back to software, below */
3440
                break;
3441
3442
            default:
3443
                /* Once we've failed, exit without trying to continue.
3444
                 * We may have mangled operands: (e.g. Z = X * Z)
3445
                 * Future implementation may consider saving operands,
3446
                 * but errors should never occur. */
3447
                goto clean;  /* error */
3448
                break;
3449
        }
3450
    }
3451
    /* fall through to software calcs */
3452
#endif /* WOLFSSL_ESP32_CRYPT_RSA_PRI_MP_MUL */
3453
3454
#if defined(TFM_SQR3) && FP_SIZE >= 6
3455
        if (y <= 3) {
3456
           err = fp_sqr_comba3(A,B);
3457
           goto clean;
3458
        }
3459
#endif
3460
0
#if defined(TFM_SQR4) && FP_SIZE >= 8
3461
0
        if (y == 4) {
3462
0
           err = fp_sqr_comba4(A,B);
3463
0
           goto clean;
3464
0
        }
3465
0
#endif
3466
#if defined(TFM_SQR6) && FP_SIZE >= 12
3467
        if (y <= 6) {
3468
           err = fp_sqr_comba6(A,B);
3469
           goto clean;
3470
        }
3471
#endif
3472
#if defined(TFM_SQR7) && FP_SIZE >= 14
3473
        if (y == 7) {
3474
           err = fp_sqr_comba7(A,B);
3475
           goto clean;
3476
        }
3477
#endif
3478
#if defined(TFM_SQR8) && FP_SIZE >= 16
3479
        if (y == 8) {
3480
           err = fp_sqr_comba8(A,B);
3481
           goto clean;
3482
        }
3483
#endif
3484
#if defined(TFM_SQR9) && FP_SIZE >= 18
3485
        if (y == 9) {
3486
           err = fp_sqr_comba9(A,B);
3487
           goto clean;
3488
        }
3489
#endif
3490
#if defined(TFM_SQR12) && FP_SIZE >= 24
3491
        if (y <= 12) {
3492
           err = fp_sqr_comba12(A,B);
3493
           goto clean;
3494
        }
3495
#endif
3496
#if defined(TFM_SQR17) && FP_SIZE >= 34
3497
        if (y <= 17) {
3498
           err = fp_sqr_comba17(A,B);
3499
           goto clean;
3500
        }
3501
#endif
3502
#if defined(TFM_SMALL_SET)
3503
        if (y <= 16) {
3504
           err = fp_sqr_comba_small(A,B);
3505
           goto clean;
3506
        }
3507
#endif
3508
#if defined(TFM_SQR20) && FP_SIZE >= 40
3509
        if (y <= 20) {
3510
           err = fp_sqr_comba20(A,B);
3511
           goto clean;
3512
        }
3513
#endif
3514
#if defined(TFM_SQR24) && FP_SIZE >= 48
3515
        if (y <= 24) {
3516
           err = fp_sqr_comba24(A,B);
3517
           goto clean;
3518
        }
3519
#endif
3520
#if defined(TFM_SQR28) && FP_SIZE >= 56
3521
        if (y <= 28) {
3522
           err = fp_sqr_comba28(A,B);
3523
           goto clean;
3524
        }
3525
#endif
3526
#if defined(TFM_SQR32) && FP_SIZE >= 64
3527
        if (y <= 32) {
3528
           err = fp_sqr_comba32(A,B);
3529
           goto clean;
3530
        }
3531
#endif
3532
#if defined(TFM_SQR48) && FP_SIZE >= 96
3533
        if (y <= 48) {
3534
           err = fp_sqr_comba48(A,B);
3535
           goto clean;
3536
        }
3537
#endif
3538
#if defined(TFM_SQR64) && FP_SIZE >= 128
3539
        if (y <= 64) {
3540
           err = fp_sqr_comba64(A,B);
3541
           goto clean;
3542
        }
3543
#endif
3544
0
       err = fp_sqr_comba(A, B);
3545
3546
0
clean:
3547
  /* zero any excess digits on the destination that we didn't write to */
3548
0
  for (y = B->used; y >= 0 && y < oldused; y++) {
3549
0
    B->dp[y] = 0;
3550
0
  }
3551
3552
0
  return err;
3553
0
}
3554
3555
/* generic comba squarer */
3556
int fp_sqr_comba(fp_int *A, fp_int *B)
3557
0
{
3558
0
  int       pa, ix, iz;
3559
0
  fp_digit  c0, c1, c2;
3560
#ifdef TFM_ISO
3561
  fp_word   tt = 0;
3562
#endif
3563
0
   fp_int    *dst;
3564
#ifndef WOLFSSL_SMALL_STACK
3565
   fp_int    tmp[1];
3566
#else
3567
0
   fp_int    *tmp;
3568
0
#endif
3569
3570
0
#ifdef WOLFSSL_SMALL_STACK
3571
0
   tmp = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);
3572
0
   if (tmp == NULL)
3573
0
       return FP_MEM;
3574
0
#endif
3575
3576
  /* get size of output and trim */
3577
0
  pa = A->used + A->used;
3578
0
  if (pa >= FP_SIZE) {
3579
0
     pa = FP_SIZE-1;
3580
0
  }
3581
3582
  /* number of output digits to produce */
3583
0
  COMBA_START;
3584
0
  COMBA_CLEAR;
3585
3586
0
  if (A == B) {
3587
0
     fp_init(tmp);
3588
0
     dst = tmp;
3589
0
  } else {
3590
0
     fp_zero(B);
3591
0
     dst = B;
3592
0
  }
3593
3594
0
  for (ix = 0; ix < pa; ix++) {
3595
0
      int      tx, ty, iy;
3596
0
      fp_digit *tmpy, *tmpx;
3597
3598
      /* get offsets into the two bignums */
3599
0
      ty = MIN(A->used-1, ix);
3600
0
      tx = ix - ty;
3601
3602
      /* setup temp aliases */
3603
0
      tmpx = A->dp + tx;
3604
0
      tmpy = A->dp + ty;
3605
3606
      /* this is the number of times the loop will iterate,
3607
         while (tx++ < a->used && ty-- >= 0) { ... }
3608
       */
3609
0
      iy = MIN(A->used-tx, ty+1);
3610
3611
      /* now for squaring tx can never equal ty
3612
       * we halve the distance since they approach
3613
       * at a rate of 2x and we have to round because
3614
       * odd cases need to be executed
3615
       */
3616
0
      iy = MIN(iy, (ty-tx+1)>>1);
3617
3618
      /* forward carries */
3619
0
      COMBA_FORWARD;
3620
3621
      /* execute loop */
3622
0
      for (iz = 0; iz < iy; iz++) {
3623
0
          SQRADD2(*tmpx++, *tmpy--);
3624
0
      }
3625
3626
      /* even columns have the square term in them */
3627
0
      if ((ix&1) == 0) {
3628
          /* TAO change COMBA_ADD back to SQRADD */
3629
0
          SQRADD(A->dp[ix>>1], A->dp[ix>>1]);
3630
0
      }
3631
3632
      /* store it */
3633
0
      COMBA_STORE(dst->dp[ix]);
3634
0
  }
3635
3636
0
  COMBA_FINI;
3637
3638
  /* setup dest */
3639
0
  dst->used = pa;
3640
0
  fp_clamp (dst);
3641
0
  if (dst != B) {
3642
0
     fp_copy(dst, B);
3643
0
  }
3644
3645
  /* Variables used but not seen by cppcheck. */
3646
0
  (void)c0; (void)c1; (void)c2;
3647
#ifdef TFM_ISO
3648
  (void)tt;
3649
#endif
3650
3651
0
#ifdef WOLFSSL_SMALL_STACK
3652
0
  XFREE(tmp, NULL, DYNAMIC_TYPE_BIGINT);
3653
0
#endif
3654
0
  return FP_OKAY;
3655
0
}
3656
3657
int fp_cmp(fp_int *a, fp_int *b)
3658
0
{
3659
0
   if (a->sign == FP_NEG && b->sign == FP_ZPOS) {
3660
0
      return FP_LT;
3661
0
   } else if (a->sign == FP_ZPOS && b->sign == FP_NEG) {
3662
0
      return FP_GT;
3663
0
   } else {
3664
      /* compare digits */
3665
0
      if (a->sign == FP_NEG) {
3666
         /* if negative compare opposite direction */
3667
0
         return fp_cmp_mag(b, a);
3668
0
      } else {
3669
0
         return fp_cmp_mag(a, b);
3670
0
      }
3671
0
   }
3672
0
}
3673
3674
/* compare against a single digit */
3675
int fp_cmp_d(fp_int *a, fp_digit b)
3676
0
{
3677
  /* special case for zero*/
3678
0
  if (a->used == 0 && b == 0)
3679
0
    return FP_EQ;
3680
3681
  /* compare based on sign */
3682
0
  if ((b && a->used == 0) || a->sign == FP_NEG) {
3683
0
    return FP_LT;
3684
0
  }
3685
3686
  /* compare based on magnitude */
3687
0
  if (a->used > 1) {
3688
0
    return FP_GT;
3689
0
  }
3690
3691
  /* compare the only digit of a to b */
3692
0
  if (a->dp[0] > b) {
3693
0
    return FP_GT;
3694
0
  } else if (a->dp[0] < b) {
3695
0
    return FP_LT;
3696
0
  } else {
3697
0
    return FP_EQ;
3698
0
  }
3699
3700
0
}
3701
3702
int fp_cmp_mag(fp_int *a, fp_int *b)
3703
0
{
3704
0
   int x;
3705
3706
0
   if (a->used > b->used) {
3707
0
      return FP_GT;
3708
0
   } else if (a->used < b->used) {
3709
0
      return FP_LT;
3710
0
   } else {
3711
0
      for (x = a->used - 1; x >= 0; x--) {
3712
0
          if (a->dp[x] > b->dp[x]) {
3713
0
             return FP_GT;
3714
0
          } else if (a->dp[x] < b->dp[x]) {
3715
0
             return FP_LT;
3716
0
          }
3717
0
      }
3718
0
   }
3719
0
   return FP_EQ;
3720
0
}
3721
3722
3723
/* sets up the montgomery reduction */
3724
int fp_montgomery_setup(fp_int *a, fp_digit *rho)
3725
0
{
3726
0
  fp_digit x, b;
3727
3728
/* fast inversion mod 2**k
3729
 *
3730
 * Based on the fact that
3731
 *
3732
 * XA = 1 (mod 2**n)  =>  (X(2-XA)) A = 1 (mod 2**2n)
3733
 *                    =>  2*X*A - X*X*A*A = 1
3734
 *                    =>  2*(1) - (1)     = 1
3735
 */
3736
0
  b = a->dp[0];
3737
3738
0
  if ((b & 1) == 0) {
3739
0
    return FP_VAL;
3740
0
  }
3741
3742
0
  x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
3743
0
  x *= 2 - b * x;               /* here x*a==1 mod 2**8 */
3744
0
  x *= 2 - b * x;               /* here x*a==1 mod 2**16 */
3745
0
  x *= 2 - b * x;               /* here x*a==1 mod 2**32 */
3746
0
#ifdef FP_64BIT
3747
0
  x *= 2 - b * x;               /* here x*a==1 mod 2**64 */
3748
0
#endif
3749
3750
  /* rho = -1/m mod b */
3751
0
  *rho = (fp_digit) (((fp_word) 1 << ((fp_word) DIGIT_BIT)) - ((fp_word)x));
3752
3753
0
  return FP_OKAY;
3754
0
}
3755
3756
/* computes a = B**n mod b without division or multiplication useful for
3757
 * normalizing numbers in a Montgomery system.
3758
 */
3759
int fp_montgomery_calc_normalization(fp_int *a, fp_int *b)
3760
0
{
3761
0
  int     x, bits;
3762
3763
  /* how many bits of last digit does b use */
3764
0
  bits = fp_count_bits (b) % DIGIT_BIT;
3765
0
  if (!bits) bits = DIGIT_BIT;
3766
3767
  /* compute A = B^(n-1) * 2^(bits-1) */
3768
0
  if (b->used > 1) {
3769
0
     fp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1);
3770
0
  } else {
3771
0
     fp_set(a, 1);
3772
0
     bits = 1;
3773
0
  }
3774
3775
  /* now compute C = A * B mod b */
3776
0
  for (x = bits - 1; x < (int)DIGIT_BIT; x++) {
3777
0
    int err = fp_mul_2 (a, a);
3778
0
    if (err != FP_OKAY) {
3779
0
      return err;
3780
0
    }
3781
0
    if (fp_cmp_mag (a, b) != FP_LT) {
3782
0
      s_fp_sub (a, b, a);
3783
0
    }
3784
0
  }
3785
0
  return FP_OKAY;
3786
0
}
3787
3788
3789
#ifdef TFM_SMALL_MONT_SET
3790
    #include "fp_mont_small.i"
3791
#endif
3792
3793
#ifdef HAVE_INTEL_MULX
3794
static WC_INLINE void innermul8_mulx(fp_digit *c_mulx, fp_digit *cy_mulx, fp_digit *tmpm, fp_digit mu)
3795
{
3796
    fp_digit cy = *cy_mulx ;
3797
    INNERMUL8_MULX ;
3798
    *cy_mulx = cy ;
3799
}
3800
3801
/* computes x/R == x (mod N) via Montgomery Reduction */
3802
static int fp_montgomery_reduce_mulx(fp_int *a, fp_int *m, fp_digit mp, int ct)
3803
{
3804
#ifndef WOLFSSL_SMALL_STACK
3805
   fp_digit c[FP_SIZE+1];
3806
#else
3807
   fp_digit *c;
3808
#endif
3809
   fp_digit *_c, *tmpm, mu = 0;
3810
   int      oldused, x, y, pa;
3811
3812
   /* bail if too large */
3813
   if (m->used > (FP_SIZE/2)) {
3814
      (void)mu;                     /* shut up compiler */
3815
      return FP_VAL;
3816
   }
3817
3818
#ifdef TFM_SMALL_MONT_SET
3819
   if (m->used <= 16) {
3820
      return fp_montgomery_reduce_small(a, m, mp);
3821
   }
3822
#endif
3823
3824
#ifdef WOLFSSL_SMALL_STACK
3825
   /* only allocate space for what's needed for window plus res */
3826
   c = (fp_digit*)XMALLOC(sizeof(fp_digit)*(FP_SIZE + 1), NULL, DYNAMIC_TYPE_BIGINT);
3827
   if (c == NULL) {
3828
      return FP_MEM;
3829
   }
3830
#endif
3831
3832
   /* now zero the buff */
3833
   XMEMSET(c, 0, sizeof(fp_digit)*(FP_SIZE + 1));
3834
   pa = m->used;
3835
3836
   /* copy the input */
3837
#ifdef TFM_TIMING_RESISTANT
3838
   if (a->used <= m->used) {
3839
      oldused = m->used;
3840
   }
3841
   else {
3842
      oldused = m->used * 2;
3843
   }
3844
#else
3845
   oldused = a->used;
3846
#endif
3847
   for (x = 0; x < oldused; x++) {
3848
       c[x] = a->dp[x];
3849
   }
3850
   MONT_START;
3851
3852
   for (x = 0; x < pa; x++) {
3853
       fp_digit cy = 0;
3854
       /* get Mu for this round */
3855
       LOOP_START;
3856
       _c   = c + x;
3857
       tmpm = m->dp;
3858
       y = 0;
3859
        for (; y < (pa & ~7); y += 8) {
3860
              innermul8_mulx(_c, &cy, tmpm, mu) ;
3861
              _c   += 8;
3862
              tmpm += 8;
3863
           }
3864
       for (; y < pa; y++) {
3865
          INNERMUL;
3866
          ++_c;
3867
       }
3868
       LOOP_END;
3869
       while (cy) {
3870
           PROPCARRY;
3871
           ++_c;
3872
       }
3873
  }
3874
3875
  /* now copy out */
3876
  _c   = c + pa;
3877
  tmpm = a->dp;
3878
  for (x = 0; x < pa+1; x++) {
3879
     *tmpm++ = *_c++;
3880
  }
3881
3882
  /* zero any excess digits on the destination that we didn't write to */
3883
  for (; x < oldused; x++) {
3884
     *tmpm++ = 0;
3885
  }
3886
3887
  MONT_FINI;
3888
3889
  a->used = pa+1;
3890
  fp_clamp(a);
3891
3892
#ifndef WOLFSSL_MONT_RED_CT
3893
  /* if A >= m then A = A - m */
3894
  if (fp_cmp_mag (a, m) != FP_LT) {
3895
    s_fp_sub (a, m, a);
3896
  }
3897
  (void)ct;
3898
#else
3899
  if (ct) {
3900
    fp_submod_ct(a, m, m, a);
3901
  }
3902
  else if (fp_cmp_mag (a, m) != FP_LT) {
3903
    s_fp_sub (a, m, a);
3904
  }
3905
#endif
3906
3907
#ifdef WOLFSSL_SMALL_STACK
3908
  XFREE(c, NULL, DYNAMIC_TYPE_BIGINT);
3909
#endif
3910
  return FP_OKAY;
3911
}
3912
#endif
3913
3914
/* computes x/R == x (mod N) via Montgomery Reduction */
3915
int fp_montgomery_reduce_ex(fp_int *a, fp_int *m, fp_digit mp, int ct)
3916
0
{
3917
#ifndef WOLFSSL_SMALL_STACK
3918
   fp_digit c[FP_SIZE+1];
3919
#else
3920
0
   fp_digit *c;
3921
0
#endif
3922
0
   fp_digit *_c, *tmpm, mu = 0;
3923
0
   int      oldused, x, y, pa, err = 0;
3924
3925
0
   IF_HAVE_INTEL_MULX(err=fp_montgomery_reduce_mulx(a, m, mp, ct), return err) ;
3926
0
   (void)err;
3927
3928
   /* bail if too large */
3929
0
   if (m->used > (FP_SIZE/2)) {
3930
0
      (void)mu;                     /* shut up compiler */
3931
0
      return FP_VAL;
3932
0
   }
3933
3934
#ifdef TFM_SMALL_MONT_SET
3935
   if (m->used <= 16) {
3936
      return fp_montgomery_reduce_small(a, m, mp);
3937
   }
3938
#endif
3939
3940
0
#ifdef WOLFSSL_SMALL_STACK
3941
   /* only allocate space for what's needed for window plus res */
3942
0
   c = (fp_digit*)XMALLOC(sizeof(fp_digit)*(FP_SIZE + 1), NULL, DYNAMIC_TYPE_BIGINT);
3943
0
   if (c == NULL) {
3944
0
      return FP_MEM;
3945
0
   }
3946
0
#endif
3947
3948
   /* now zero the buff */
3949
0
   XMEMSET(c, 0, sizeof(fp_digit)*(FP_SIZE + 1));
3950
0
   pa = m->used;
3951
3952
   /* copy the input */
3953
0
#ifdef TFM_TIMING_RESISTANT
3954
0
   if (a->used <= m->used) {
3955
0
      oldused = m->used;
3956
0
   }
3957
0
   else {
3958
0
      oldused = m->used * 2;
3959
0
   }
3960
#else
3961
   oldused = a->used;
3962
#endif
3963
0
   for (x = 0; x < oldused; x++) {
3964
0
       c[x] = a->dp[x];
3965
0
   }
3966
0
   MONT_START;
3967
3968
0
   for (x = 0; x < pa; x++) {
3969
0
       fp_digit cy = 0;
3970
       /* get Mu for this round */
3971
0
       LOOP_START;
3972
0
       _c   = c + x;
3973
0
       tmpm = m->dp;
3974
0
       y = 0;
3975
0
#if defined(INNERMUL8)
3976
0
        for (; y < (pa & ~7); y += 8) {
3977
0
              INNERMUL8 ;
3978
0
              _c   += 8;
3979
0
              tmpm += 8;
3980
0
           }
3981
0
#endif
3982
0
       for (; y < pa; y++) {
3983
0
          INNERMUL;
3984
0
          ++_c;
3985
0
       }
3986
0
       LOOP_END;
3987
0
       while (cy) { /* //NOLINT(bugprone-infinite-loop) */ /* PROPCARRY is an asm macro */
3988
0
           PROPCARRY;
3989
0
           ++_c;
3990
0
       }
3991
0
  }
3992
3993
  /* now copy out */
3994
0
  _c   = c + pa;
3995
0
  tmpm = a->dp;
3996
0
  for (x = 0; x < pa+1; x++) {
3997
0
     *tmpm++ = *_c++;
3998
0
  }
3999
4000
  /* zero any excess digits on the destination that we didn't write to */
4001
0
  for (; x < oldused; x++) {
4002
0
     *tmpm++ = 0;
4003
0
  }
4004
4005
0
  MONT_FINI;
4006
4007
0
  a->used = pa+1;
4008
0
  fp_clamp(a);
4009
4010
0
#ifndef WOLFSSL_MONT_RED_CT
4011
  /* if A >= m then A = A - m */
4012
0
  if (fp_cmp_mag (a, m) != FP_LT) {
4013
0
    s_fp_sub (a, m, a);
4014
0
  }
4015
0
  (void)ct;
4016
#else
4017
  if (ct) {
4018
    fp_submod_ct(a, m, m, a);
4019
  }
4020
  else if (fp_cmp_mag (a, m) != FP_LT) {
4021
    s_fp_sub (a, m, a);
4022
  }
4023
#endif
4024
4025
0
#ifdef WOLFSSL_SMALL_STACK
4026
0
  XFREE(c, NULL, DYNAMIC_TYPE_BIGINT);
4027
0
#endif
4028
0
  return FP_OKAY;
4029
0
}
4030
4031
int fp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp)
4032
0
{
4033
0
  return fp_montgomery_reduce_ex(a, m, mp, 1);
4034
0
}
4035
4036
int fp_read_unsigned_bin(fp_int *a, const unsigned char *b, int c)
4037
0
{
4038
#if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT)
4039
  const word32 maxC = (a->size * sizeof(fp_digit));
4040
#else
4041
0
  const word32 maxC = (FP_SIZE * sizeof(fp_digit));
4042
0
#endif
4043
4044
  /* zero the int */
4045
0
  fp_zero (a);
4046
4047
0
  if (c < 0) {
4048
0
      return FP_VAL;
4049
0
  }
4050
4051
0
  if (c == 0) {
4052
0
      return FP_OKAY;
4053
0
  }
4054
4055
  /* if input b excess max, then truncate */
4056
0
  if ((word32)c > maxC) {
4057
0
     int excess = (c - maxC);
4058
0
     c -= excess;
4059
0
     b += excess;
4060
0
  }
4061
4062
/* Not both endian simultaneously */
4063
#if defined(LITTLE_ENDIAN_ORDER) && defined(BIG_ENDIAN_ORDER)
4064
#error Both LITTLE_ENDIAN_ORDER and BIG_ENDIAN_ORDER defined.
4065
#endif
4066
4067
0
#if (defined(LITTLE_ENDIAN_ORDER) || defined(BIG_ENDIAN_ORDER)) && \
4068
0
    (defined(FP_32BIT) || defined(FP_64BIT))
4069
#ifdef FP_32BIT
4070
  /* If we know the endianness of this architecture, and we're using
4071
     32-bit fp_digits, we can optimize this */
4072
  {
4073
     unsigned char *pd = (unsigned char *)a->dp;
4074
4075
     a->used = (c + sizeof(fp_digit) - 1)/sizeof(fp_digit);
4076
#ifdef BIG_ENDIAN_ORDER
4077
     {
4078
       /* Use Duff's device to unroll the loop. */
4079
       int idx = (c - 1) & ~3;
4080
       switch (c % 4) {
4081
       case 0:    do { pd[idx+0] = *b++; FALL_THROUGH;
4082
       case 3:         pd[idx+1] = *b++; FALL_THROUGH;
4083
       case 2:         pd[idx+2] = *b++; FALL_THROUGH;
4084
       case 1:         pd[idx+3] = *b++;
4085
                     idx -= 4;
4086
                 } while ((c -= 4) > 0);
4087
       }
4088
     }
4089
#else
4090
     /* read the bytes in one at a time. */
4091
     for (c -= 1; c >= 0; c -= 1) {
4092
       pd[c] = *b++;
4093
     }
4094
#endif
4095
  }
4096
#elif defined(FP_64BIT)
4097
  /* If we know the endianness of this architecture, and we're using
4098
     64-bit fp_digits, we can optimize this */
4099
0
  {
4100
0
     unsigned char *pd = (unsigned char *)a->dp;
4101
4102
0
     a->used = (c + sizeof(fp_digit) - 1)/sizeof(fp_digit);
4103
#ifdef BIG_ENDIAN_ORDER
4104
     {
4105
       /* Use Duff's device to unroll the loop. */
4106
       int idx = (c - 1) & ~7;
4107
       switch (c % 8) {
4108
       case 0:    do { pd[idx+0] = *b++; FALL_THROUGH;
4109
       case 7:         pd[idx+1] = *b++; FALL_THROUGH;
4110
       case 6:         pd[idx+2] = *b++; FALL_THROUGH;
4111
       case 5:         pd[idx+3] = *b++; FALL_THROUGH;
4112
       case 4:         pd[idx+4] = *b++; FALL_THROUGH;
4113
       case 3:         pd[idx+5] = *b++; FALL_THROUGH;
4114
       case 2:         pd[idx+6] = *b++; FALL_THROUGH;
4115
       case 1:         pd[idx+7] = *b++;
4116
                     idx -= 8;
4117
                 } while ((c -= 8) > 0);
4118
       }
4119
     }
4120
#else
4121
     /* read the bytes in one at a time. */
4122
0
     for (c -= 1; c >= 0; c -= 1) {
4123
0
       pd[c] = *b++;
4124
0
     }
4125
0
#endif
4126
0
  }
4127
0
#endif
4128
#else
4129
  /* read the bytes in one at a time - unknown number of bits in digit */
4130
  for (; c > 0; c--) {
4131
     int err = fp_mul_2d (a, 8, a);
4132
     if (err != FP_OKAY) {
4133
         return err;
4134
     }
4135
     a->dp[0] |= *b++;
4136
4137
     if (a->used == 0) {
4138
         a->used = 1;
4139
     }
4140
  }
4141
#endif
4142
0
  fp_clamp (a);
4143
4144
0
  return FP_OKAY;
4145
0
}
4146
4147
int fp_to_unsigned_bin_at_pos(int x, fp_int *t, unsigned char *b)
4148
0
{
4149
0
#if DIGIT_BIT == 64 || DIGIT_BIT == 32
4150
0
   int i;
4151
0
   int j = 0;
4152
0
   fp_digit n;
4153
4154
0
   for (i = 0; i < t->used-1; ) {
4155
0
       b[x++] = (unsigned char)(t->dp[i] >> j);
4156
0
       j += 8;
4157
0
       i += j == DIGIT_BIT;
4158
0
       j &= DIGIT_BIT - 1;
4159
0
   }
4160
0
   n = t->dp[i];
4161
0
   while (n != 0) {
4162
0
       b[x++] = (unsigned char)n;
4163
0
       n >>= 8;
4164
0
   }
4165
0
   return x;
4166
#else
4167
   while (fp_iszero (t) == FP_NO) {
4168
      b[x++] = (unsigned char) (t->dp[0] & 255);
4169
      fp_div_2d (t, 8, t, NULL);
4170
  }
4171
  return x;
4172
#endif
4173
0
}
4174
4175
int fp_to_unsigned_bin(fp_int *a, unsigned char *b)
4176
0
{
4177
0
  int     x;
4178
#ifndef WOLFSSL_SMALL_STACK
4179
   fp_int t[1];
4180
#else
4181
0
   fp_int *t;
4182
0
#endif
4183
4184
0
#ifdef WOLFSSL_SMALL_STACK
4185
0
   t = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);
4186
0
   if (t == NULL)
4187
0
       return FP_MEM;
4188
0
#endif
4189
4190
0
  fp_init_copy(t, a);
4191
4192
0
  x = fp_to_unsigned_bin_at_pos(0, t, b);
4193
0
  mp_reverse (b, x);
4194
4195
0
#ifdef WOLFSSL_SMALL_STACK
4196
0
  XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);
4197
0
#endif
4198
0
  return FP_OKAY;
4199
0
}
4200
4201
int fp_to_unsigned_bin_len_ct(fp_int *a, unsigned char *out, int outSz)
4202
0
{
4203
0
  int err = MP_OKAY;
4204
4205
  /* Validate parameters. */
4206
0
  if ((a == NULL) || (out == NULL) || (outSz < 0)) {
4207
0
    err = MP_VAL;
4208
0
  }
4209
4210
0
#if DIGIT_BIT > 8
4211
0
  if (err == MP_OKAY) {
4212
    /* Start at the end of the buffer - least significant byte. */
4213
0
    int j;
4214
0
    unsigned int i;
4215
0
    fp_digit mask = (fp_digit)-1;
4216
0
    fp_digit d;
4217
4218
    /* Put each digit in. */
4219
0
    i = 0;
4220
0
    for (j = outSz - 1; j >= 0; ) {
4221
0
      unsigned int b;
4222
0
      d = a->dp[i];
4223
      /* Place each byte of a digit into the buffer. */
4224
0
      for (b = 0; (j >= 0) && (b < (DIGIT_BIT / 8)); b++) {
4225
0
        out[j--] = (byte)(d & mask);
4226
0
        d >>= 8;
4227
0
      }
4228
0
      mask &= (fp_digit)0 - (i < (unsigned int)a->used - 1);
4229
0
      i += (unsigned int)(1 & mask);
4230
0
    }
4231
0
  }
4232
#else
4233
  if ((err == MP_OKAY) && ((unsigned int)outSz < a->used)) {
4234
    err = MP_VAL;
4235
  }
4236
  if (err == MP_OKAY) {
4237
    unsigned int i;
4238
    int j;
4239
    fp_digit mask = (fp_digit)-1;
4240
4241
    i = 0;
4242
    for (j = outSz - 1; j >= 0; j--) {
4243
      out[j] = a->dp[i] & mask;
4244
      mask &= (fp_digit)0 - (i < (unsigned int)a->used - 1);
4245
      i += (unsigned int)(1 & mask);
4246
    }
4247
  }
4248
#endif
4249
4250
0
  return err;
4251
0
}
4252
4253
int fp_to_unsigned_bin_len(fp_int *a, unsigned char *b, int c)
4254
0
{
4255
0
#if DIGIT_BIT == 64 || DIGIT_BIT == 32 || DIGIT_BIT == 16
4256
0
  int i = 0;
4257
0
  int j = 0;
4258
0
  int x;
4259
4260
0
  for (x=c-1; x >= 0 && i < a->used; x--) {
4261
0
     b[x] = (unsigned char)(a->dp[i] >> j);
4262
0
     j += 8;
4263
0
     i += j == DIGIT_BIT;
4264
0
     j &= DIGIT_BIT - 1;
4265
0
  }
4266
0
  for (; x >= 0; x--) {
4267
0
     b[x] = 0;
4268
0
  }
4269
0
  if (i < a->used - 1) {
4270
0
      return FP_VAL;
4271
0
  }
4272
0
  if ((i == a->used - 1) && ((a->dp[i] >> j) != 0)) {
4273
0
      return FP_VAL;
4274
0
  }
4275
4276
0
  return FP_OKAY;
4277
#else
4278
  int     x;
4279
#ifndef WOLFSSL_SMALL_STACK
4280
   fp_int t[1];
4281
#else
4282
   fp_int *t;
4283
#endif
4284
4285
#ifdef WOLFSSL_SMALL_STACK
4286
   t = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);
4287
   if (t == NULL)
4288
       return FP_MEM;
4289
#endif
4290
4291
  fp_init_copy(t, a);
4292
4293
  for (x = 0; x < c; x++) {
4294
      b[x] = (unsigned char) (t->dp[0] & 255);
4295
      fp_div_2d (t, 8, t, NULL);
4296
  }
4297
  mp_reverse (b, x);
4298
4299
#ifdef WOLFSSL_SMALL_STACK
4300
  XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);
4301
#endif
4302
  if (!fp_iszero(t)) {
4303
      return FP_VAL;
4304
  }
4305
  return FP_OKAY;
4306
#endif
4307
0
}
4308
4309
int fp_unsigned_bin_size(const fp_int *a)
4310
0
{
4311
0
  int     size = fp_count_bits (a);
4312
0
  return (size / 8 + ((size & 7) != 0 ? 1 : 0));
4313
0
}
4314
4315
void fp_set(fp_int *a, fp_digit b)
4316
0
{
4317
0
   fp_zero(a);
4318
0
   a->dp[0] = b;
4319
0
   a->used  = a->dp[0] ? 1 : 0;
4320
0
}
4321
4322
4323
#ifndef MP_SET_CHUNK_BITS
4324
0
    #define MP_SET_CHUNK_BITS 4
4325
#endif
4326
int fp_set_int(fp_int *a, unsigned long b)
4327
0
{
4328
  /* use direct fp_set if b is less than fp_digit max
4329
   * If input max value of b down shift by 1 less than full range
4330
   * fp_digit, then condition is always true. */
4331
0
#if ((ULONG_MAX >> (DIGIT_BIT-1)) > 0)
4332
0
  int x;
4333
0
  if (b < FP_DIGIT_MAX)
4334
0
  {
4335
0
    fp_set (a, (fp_digit)b);
4336
0
    return FP_OKAY;
4337
0
  }
4338
4339
0
  fp_zero (a);
4340
4341
  /* set chunk bits at a time */
4342
0
  for (x = 0; x < (int)(sizeof(b) * 8) / MP_SET_CHUNK_BITS; x++) {
4343
0
    int err = fp_mul_2d (a, MP_SET_CHUNK_BITS, a);
4344
0
    if (err != FP_OKAY)
4345
0
        return err;
4346
4347
    /* OR in the top bits of the source */
4348
0
    a->dp[0] |= (b >> ((sizeof(b) * 8) - MP_SET_CHUNK_BITS)) &
4349
0
                                  ((1 << MP_SET_CHUNK_BITS) - 1);
4350
4351
    /* shift the source up to the next chunk bits */
4352
0
    b <<= MP_SET_CHUNK_BITS;
4353
4354
    /* ensure that digits are not clamped off */
4355
0
    a->used += 1;
4356
0
  }
4357
4358
  /* clamp digits */
4359
0
  fp_clamp(a);
4360
#else
4361
  fp_set (a, (fp_digit)b);
4362
#endif
4363
4364
0
  return FP_OKAY;
4365
0
}
4366
4367
/* check if a bit is set */
4368
int fp_is_bit_set (fp_int *a, fp_digit b)
4369
0
{
4370
0
    fp_digit i;
4371
4372
0
    if (b > FP_MAX_BITS)
4373
0
        return FP_VAL;
4374
4375
0
    i = b/DIGIT_BIT;
4376
4377
0
    if ((fp_digit)a->used < i)
4378
0
        return 0;
4379
4380
0
    return (int)((a->dp[i] >> b%DIGIT_BIT) & (fp_digit)1);
4381
0
}
4382
4383
/* set the b bit of a */
4384
int fp_set_bit (fp_int * a, fp_digit b)
4385
0
{
4386
0
    fp_digit i;
4387
4388
0
    if (b > FP_MAX_BITS)
4389
0
        return FP_VAL;
4390
4391
0
    i = b/DIGIT_BIT;
4392
4393
    /* set the used count of where the bit will go if required */
4394
0
    if (a->used < (int)(i+1))
4395
0
        a->used = (int)(i+1);
4396
4397
    /* put the single bit in its place */
4398
0
    a->dp[i] |= ((fp_digit)1) << (b % DIGIT_BIT);
4399
4400
0
    return MP_OKAY;
4401
0
}
4402
4403
int fp_count_bits (const fp_int * a)
4404
0
{
4405
0
  int     r;
4406
0
  fp_digit q;
4407
4408
  /* shortcut */
4409
0
  if (a->used == 0) {
4410
0
    return 0;
4411
0
  }
4412
4413
  /* get number of digits and add that */
4414
0
  r = (a->used - 1) * DIGIT_BIT;
4415
4416
  /* take the last digit and count the bits in it */
4417
0
  q = a->dp[a->used - 1];
4418
0
  while (q > ((fp_digit) 0)) {
4419
0
    ++r;
4420
0
    q >>= ((fp_digit) 1);
4421
0
  }
4422
4423
0
  return r;
4424
0
}
4425
4426
int fp_leading_bit(fp_int *a)
4427
0
{
4428
0
    int bit = 0;
4429
4430
0
    if (a->used != 0) {
4431
0
        fp_digit q = a->dp[a->used - 1];
4432
0
        int qSz = sizeof(fp_digit);
4433
4434
0
        while (qSz > 0) {
4435
0
            if ((unsigned char)q != 0)
4436
0
                bit = (q & 0x80) != 0;
4437
0
            q >>= 8;
4438
0
            qSz--;
4439
0
        }
4440
0
    }
4441
4442
0
    return bit;
4443
0
}
4444
4445
int fp_lshd(fp_int *a, int x)
4446
0
{
4447
0
    int y;
4448
4449
0
    if (a->used + x > FP_SIZE) return FP_VAL;
4450
4451
0
    y = a->used + x - 1;
4452
4453
    /* store new size */
4454
0
    a->used = y + 1;
4455
4456
    /* move digits */
4457
0
    for (; y >= x; y--) {
4458
0
        a->dp[y] = a->dp[y-x];
4459
0
    }
4460
4461
    /* zero lower digits */
4462
0
    for (; y >= 0; y--) {
4463
0
        a->dp[y] = 0;
4464
0
    }
4465
4466
    /* clamp digits */
4467
0
    fp_clamp(a);
4468
0
    return FP_OKAY;
4469
0
}
4470
4471
4472
/* right shift by bit count */
4473
void fp_rshb(fp_int *c, int x)
4474
0
{
4475
0
    fp_digit *tmpc, mask, shift;
4476
0
    fp_digit r, rr;
4477
0
    fp_digit D = x;
4478
4479
    /* shifting by a negative number not supported, and shifting by
4480
     * zero changes nothing.
4481
     */
4482
0
    if (x <= 0) return;
4483
4484
    /* shift digits first if needed */
4485
0
    if (x >= DIGIT_BIT) {
4486
0
        fp_rshd(c, x / DIGIT_BIT);
4487
        /* recalculate number of bits to shift */
4488
0
        D = x % DIGIT_BIT;
4489
        /* check if any more shifting needed */
4490
0
        if (D == 0) return;
4491
4492
0
    }
4493
4494
    /* zero shifted is always zero */
4495
0
    if (fp_iszero(c)) return;
4496
4497
    /* mask */
4498
0
    mask = (((fp_digit)1) << D) - 1;
4499
4500
    /* shift for lsb */
4501
0
    shift = DIGIT_BIT - D;
4502
4503
    /* alias */
4504
0
    tmpc = c->dp + (c->used - 1);
4505
4506
    /* carry */
4507
0
    r = 0;
4508
0
    for (x = c->used - 1; x >= 0; x--) {
4509
      /* get the lower  bits of this word in a temp */
4510
0
      rr = *tmpc & mask;
4511
4512
      /* shift the current word and mix in the carry bits from previous word */
4513
0
      *tmpc = (*tmpc >> D) | (r << shift);
4514
0
      --tmpc;
4515
4516
      /* set the carry to the carry bits of the current word found above */
4517
0
      r = rr;
4518
0
    }
4519
4520
    /* clamp digits */
4521
0
    fp_clamp(c);
4522
0
}
4523
4524
4525
void fp_rshd(fp_int *a, int x)
4526
0
{
4527
0
  int y;
4528
4529
  /* too many digits just zero and return */
4530
0
  if (x >= a->used) {
4531
0
     fp_zero(a);
4532
0
     return;
4533
0
  }
4534
4535
   /* shift */
4536
0
   for (y = 0; y < a->used - x; y++) {
4537
0
      a->dp[y] = a->dp[y+x];
4538
0
   }
4539
4540
   /* zero rest */
4541
0
   for (; y < a->used; y++) {
4542
0
      a->dp[y] = 0;
4543
0
   }
4544
4545
   /* decrement count */
4546
0
   a->used -= x;
4547
0
   fp_clamp(a);
4548
0
}
4549
4550
4551
/* c = a - b */
4552
int fp_sub_d(fp_int *a, fp_digit b, fp_int *c)
4553
0
{
4554
#ifndef WOLFSSL_SMALL_STACK
4555
   fp_int    tmp[1];
4556
#else
4557
0
   fp_int    *tmp;
4558
0
#endif
4559
0
   int       err = FP_OKAY;
4560
4561
0
#ifdef WOLFSSL_SMALL_STACK
4562
0
   tmp = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);
4563
0
   if (tmp == NULL)
4564
0
       return FP_MEM;
4565
0
#endif
4566
4567
0
   fp_init(tmp);
4568
0
   fp_set(tmp, b);
4569
#if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT)
4570
   if (c->size < FP_SIZE) {
4571
     err = fp_sub(a, tmp, tmp);
4572
     fp_copy(tmp, c);
4573
   }
4574
   else
4575
#endif
4576
0
   {
4577
0
     err = fp_sub(a, tmp, c);
4578
0
   }
4579
4580
0
#ifdef WOLFSSL_SMALL_STACK
4581
0
   XFREE(tmp, NULL, DYNAMIC_TYPE_BIGINT);
4582
0
#endif
4583
0
   return err;
4584
0
}
4585
4586
4587
/* wolfSSL callers from normal lib */
4588
4589
/* init a new mp_int */
4590
int mp_init (mp_int * a)
4591
{
4592
  if (a)
4593
    fp_init(a);
4594
  return MP_OKAY;
4595
}
4596
4597
void fp_init(fp_int *a)
4598
0
{
4599
#if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT)
4600
    a->size = FP_SIZE;
4601
#endif
4602
#ifdef HAVE_WOLF_BIGINT
4603
    wc_bigint_init(&a->raw);
4604
#endif
4605
0
    fp_zero(a);
4606
0
}
4607
4608
void fp_zero(fp_int *a)
4609
0
{
4610
0
    int size;
4611
0
    a->used = 0;
4612
0
    a->sign = FP_ZPOS;
4613
#if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT)
4614
    size = a->size;
4615
#else
4616
0
    size = FP_SIZE;
4617
0
#endif
4618
0
    XMEMSET(a->dp, 0, size * sizeof(fp_digit));
4619
0
}
4620
4621
void fp_clear(fp_int *a)
4622
0
{
4623
#ifdef HAVE_FIPS
4624
    fp_forcezero(a);
4625
#else
4626
0
    int size;
4627
0
    a->used = 0;
4628
0
    a->sign = FP_ZPOS;
4629
#if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT)
4630
    size = a->size;
4631
#else
4632
0
    size = FP_SIZE;
4633
0
#endif
4634
0
    XMEMSET(a->dp, 0, size * sizeof(fp_digit));
4635
0
    fp_free(a);
4636
0
#endif
4637
0
}
4638
4639
void fp_forcezero (mp_int * a)
4640
0
{
4641
0
    int size;
4642
4643
0
    if (a == NULL)
4644
0
      return;
4645
4646
0
    a->used = 0;
4647
0
    a->sign = FP_ZPOS;
4648
#if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT)
4649
    size = a->size;
4650
#else
4651
0
    size = FP_SIZE;
4652
0
#endif
4653
0
    ForceZero(a->dp, size * sizeof(fp_digit));
4654
#ifdef HAVE_WOLF_BIGINT
4655
    wc_bigint_zero(&a->raw);
4656
#endif
4657
0
    fp_free(a);
4658
0
}
4659
4660
void mp_forcezero (mp_int * a)
4661
{
4662
    fp_forcezero(a);
4663
}
4664
4665
void fp_free(fp_int* a)
4666
0
{
4667
#ifdef HAVE_WOLF_BIGINT
4668
    wc_bigint_free(&a->raw);
4669
#else
4670
0
    (void)a;
4671
0
#endif
4672
0
}
4673
4674
4675
/* clear one (frees)  */
4676
void mp_clear (mp_int * a)
4677
0
{
4678
0
    if (a == NULL)
4679
0
        return;
4680
0
    fp_clear(a);
4681
0
}
4682
4683
void mp_free(mp_int* a)
4684
{
4685
    fp_free(a);
4686
}
4687
4688
/* handle up to 6 inits */
4689
int mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d,
4690
                  mp_int* e, mp_int* f)
4691
0
{
4692
0
    if (a)
4693
0
        fp_init(a);
4694
0
    if (b)
4695
0
        fp_init(b);
4696
0
    if (c)
4697
0
        fp_init(c);
4698
0
    if (d)
4699
0
        fp_init(d);
4700
0
    if (e)
4701
0
        fp_init(e);
4702
0
    if (f)
4703
0
        fp_init(f);
4704
4705
0
    return MP_OKAY;
4706
0
}
4707
4708
/* high level addition (handles signs) */
4709
int mp_add (mp_int * a, mp_int * b, mp_int * c)
4710
0
{
4711
0
  return fp_add(a, b, c);
4712
0
}
4713
4714
/* high level subtraction (handles signs) */
4715
int mp_sub (mp_int * a, mp_int * b, mp_int * c)
4716
{
4717
  return fp_sub(a, b, c);
4718
}
4719
4720
/* high level multiplication (handles sign) */
4721
#if defined(FREESCALE_LTC_TFM)
4722
int wolfcrypt_mp_mul(mp_int * a, mp_int * b, mp_int * c)
4723
#else
4724
int mp_mul (mp_int * a, mp_int * b, mp_int * c)
4725
#endif
4726
{
4727
  return fp_mul(a, b, c);
4728
}
4729
4730
int mp_mul_d (mp_int * a, mp_digit b, mp_int * c)
4731
{
4732
  return fp_mul_d(a, b, c);
4733
}
4734
4735
/* d = a * b (mod c) */
4736
#if defined(FREESCALE_LTC_TFM)
4737
int wolfcrypt_mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
4738
#else
4739
int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
4740
#endif
4741
{
4742
   int ret = MP_OKAY;
4743
#ifdef WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD
4744
   ret = esp_mp_mulmod(a, b, c, d);
4745
   switch (ret) {
4746
      case MP_OKAY:
4747
         /* successfully computed in HW */
4748
         break;
4749
4750
      case WC_NO_ERR_TRACE(WC_HW_WAIT_E): /* MP_HW_BUSY math HW busy, fall back */
4751
      case MP_HW_FALLBACK:    /* forced fallback from HW to SW */
4752
      case MP_HW_VALIDATION_ACTIVE: /* use SW to compare to HW */
4753
         /* use software calc */
4754
         ret = fp_mulmod(a, b, c, d);
4755
         break;
4756
4757
      default:
4758
         /* Once we've failed, exit without trying to continue.
4759
          * We may have mangled operands: (e.g. Z = X * Z)
4760
          * Future implementation may consider saving operands,
4761
          * but hard errors should never actually occur. */
4762
         break;
4763
   }
4764
#else /* no HW */
4765
   ret = fp_mulmod(a, b, c, d);
4766
#endif /* WOLFSSL_ESP32_CRYPT_RSA_PRI_MULMOD */
4767
   return ret;
4768
}
4769
4770
/* d = a - b (mod c) */
4771
int mp_submod(mp_int *a, mp_int *b, mp_int *c, mp_int *d)
4772
{
4773
  return fp_submod(a, b, c, d);
4774
}
4775
4776
/* d = a + b (mod c) */
4777
int mp_addmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d)
4778
{
4779
  return fp_addmod(a, b, c, d);
4780
}
4781
4782
/* d = a - b (mod c) - constant time (a < c and b < c) */
4783
int mp_submod_ct(mp_int *a, mp_int *b, mp_int *c, mp_int *d)
4784
0
{
4785
0
  return fp_submod_ct(a, b, c, d);
4786
0
}
4787
4788
/* d = a + b (mod c) - constant time (a < c and b < c) */
4789
int mp_addmod_ct(mp_int *a, mp_int *b, mp_int *c, mp_int *d)
4790
{
4791
  return fp_addmod_ct(a, b, c, d);
4792
}
4793
4794
/* c = a mod b, 0 <= c < b */
4795
#if defined(FREESCALE_LTC_TFM)
4796
int wolfcrypt_mp_mod (mp_int * a, mp_int * b, mp_int * c)
4797
#else
4798
int mp_mod (mp_int * a, mp_int * b, mp_int * c)
4799
#endif
4800
0
{
4801
0
  return fp_mod (a, b, c);
4802
0
}
4803
4804
/* hac 14.61, pp608 */
4805
#if defined(FREESCALE_LTC_TFM)
4806
int wolfcrypt_mp_invmod (mp_int * a, mp_int * b, mp_int * c)
4807
#else
4808
int mp_invmod (mp_int * a, mp_int * b, mp_int * c)
4809
#endif
4810
0
{
4811
0
  return fp_invmod(a, b, c);
4812
0
}
4813
4814
/* hac 14.61, pp608 */
4815
int mp_invmod_mont_ct (mp_int * a, mp_int * b, mp_int * c, mp_digit mp)
4816
0
{
4817
0
  return fp_invmod_mont_ct(a, b, c, mp);
4818
0
}
4819
4820
/* this is a shell function that calls either the normal or Montgomery
4821
 * exptmod functions.  Originally the call to the montgomery code was
4822
 * embedded in the normal function but that wasted a lot of stack space
4823
 * for nothing (since 99% of the time the Montgomery code would be called)
4824
 */
4825
#if defined(FREESCALE_LTC_TFM)
4826
int wolfcrypt_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
4827
#else
4828
int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
4829
#endif
4830
{
4831
  return fp_exptmod(G, X, P, Y);
4832
}
4833
4834
int mp_exptmod_ex (mp_int * G, mp_int * X, int digits, mp_int * P, mp_int * Y)
4835
10
{
4836
10
  return fp_exptmod_ex(G, X, digits, P, Y);
4837
10
}
4838
4839
#if defined(FREESCALE_LTC_TFM)
4840
int wolfcrypt_mp_exptmod_nct (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
4841
#else
4842
int mp_exptmod_nct (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
4843
#endif
4844
0
{
4845
0
  return fp_exptmod_nct(G, X, P, Y);
4846
0
}
4847
4848
4849
/* compare two ints (signed)*/
4850
int mp_cmp (mp_int * a, mp_int * b)
4851
{
4852
  return fp_cmp(a, b);
4853
}
4854
4855
/* compare a digit */
4856
int mp_cmp_d(mp_int * a, mp_digit b)
4857
0
{
4858
0
  return fp_cmp_d(a, b);
4859
0
}
4860
4861
/* get the size for an unsigned equivalent */
4862
int mp_unsigned_bin_size (const mp_int * a)
4863
{
4864
  return fp_unsigned_bin_size(a);
4865
}
4866
4867
int mp_to_unsigned_bin_at_pos(int x, fp_int *t, unsigned char *b)
4868
{
4869
  return fp_to_unsigned_bin_at_pos(x, t, b);
4870
}
4871
4872
/* store in unsigned [big endian] format */
4873
int mp_to_unsigned_bin (mp_int * a, unsigned char *b)
4874
{
4875
  return fp_to_unsigned_bin(a,b);
4876
}
4877
4878
int mp_to_unsigned_bin_len_ct(mp_int * a, unsigned char *b, int c)
4879
0
{
4880
0
  return fp_to_unsigned_bin_len_ct(a, b, c);
4881
0
}
4882
4883
int mp_to_unsigned_bin_len(mp_int * a, unsigned char *b, int c)
4884
{
4885
  return fp_to_unsigned_bin_len(a, b, c);
4886
}
4887
/* reads a unsigned char array, assumes the msb is stored first [big endian] */
4888
int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c)
4889
0
{
4890
0
  return fp_read_unsigned_bin(a, b, c);
4891
0
}
4892
4893
4894
int mp_sub_d(fp_int *a, fp_digit b, fp_int *c)
4895
{
4896
  return fp_sub_d(a, b, c);
4897
}
4898
4899
int mp_mul_2d(fp_int *a, int b, fp_int *c)
4900
0
{
4901
0
  return fp_mul_2d(a, b, c);
4902
0
}
4903
4904
int mp_2expt(fp_int* a, int b)
4905
64.6k
{
4906
64.6k
  fp_2expt(a, b);
4907
64.6k
  return MP_OKAY;
4908
64.6k
}
4909
4910
int mp_div(fp_int * a, fp_int * b, fp_int * c, fp_int * d)
4911
0
{
4912
0
  return fp_div(a, b, c, d);
4913
0
}
4914
4915
int mp_div_2d(fp_int* a, int b, fp_int* c, fp_int* d)
4916
{
4917
  fp_div_2d(a, b, c, d);
4918
  return MP_OKAY;
4919
}
4920
4921
int mp_mod_2d(fp_int* a, int b, fp_int* c)
4922
0
{
4923
0
  fp_mod_2d(a, b, c);
4924
0
  return MP_OKAY;
4925
0
}
4926
4927
/* copy (src = a) to (dst = b) */
4928
void fp_copy(const fp_int *a, fp_int *b)
4929
0
{
4930
    /* if source and destination are different */
4931
0
    if (a != b) {
4932
#if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT)
4933
        /* verify a will fit in b */
4934
        if (b->size >= a->used) {
4935
            int x, oldused;
4936
            oldused = b->used;
4937
            b->used = a->used;
4938
            b->sign = a->sign;
4939
4940
            XMEMCPY(b->dp, a->dp, a->used * sizeof(fp_digit));
4941
4942
            /* zero any excess digits on the destination that we didn't write to */
4943
            for (x = b->used; x >= 0 && x < oldused; x++) {
4944
                b->dp[x] = 0;
4945
            }
4946
        }
4947
        else {
4948
            /* TODO: Handle error case */
4949
        }
4950
#else
4951
        /* all dp's are same size, so do straight copy */
4952
0
        b->used = a->used;
4953
0
        b->sign = a->sign;
4954
0
        XMEMCPY(b->dp, a->dp, FP_SIZE * sizeof(fp_digit));
4955
0
#endif
4956
0
    }
4957
0
}
4958
4959
int mp_init_copy(fp_int * a, fp_int * b)
4960
{
4961
    fp_init_copy(a, b);
4962
    return MP_OKAY;
4963
}
4964
4965
/* Copy (dst = a) from (src = b) */
4966
void fp_init_copy(fp_int *a, fp_int* b)
4967
0
{
4968
0
    if (a != b) {
4969
0
        fp_init(a);
4970
        /* Note reversed parameter order! */
4971
0
        fp_copy(b, a); /* copy (src = b) to (dst = a) */
4972
0
    }
4973
0
}
4974
4975
/* fast math wrappers */
4976
int mp_copy(const fp_int* a, fp_int* b)
4977
{
4978
    fp_copy(a, b);
4979
    return MP_OKAY;
4980
}
4981
4982
int mp_isodd(const mp_int* a)
4983
0
{
4984
0
    return fp_isodd(a);
4985
0
}
4986
4987
int mp_iszero(const mp_int* a)
4988
0
{
4989
0
    return fp_iszero(a);
4990
0
}
4991
4992
int mp_count_bits (const mp_int* a)
4993
{
4994
    return fp_count_bits(a);
4995
}
4996
4997
int mp_leading_bit (mp_int* a)
4998
{
4999
    return fp_leading_bit(a);
5000
}
5001
5002
void mp_rshb (mp_int* a, int x)
5003
{
5004
    fp_rshb(a, x);
5005
}
5006
5007
void mp_rshd (mp_int* a, int x)
5008
0
{
5009
0
    fp_rshd(a, x);
5010
0
}
5011
5012
int mp_set_int(mp_int *a, unsigned long b)
5013
0
{
5014
0
    return fp_set_int(a, b);
5015
0
}
5016
5017
int mp_is_bit_set (mp_int *a, mp_digit b)
5018
{
5019
    return fp_is_bit_set(a, b);
5020
}
5021
5022
int mp_set_bit(mp_int *a, mp_digit b)
5023
0
{
5024
0
    return fp_set_bit(a, b);
5025
0
}
5026
5027
#if defined(WOLFSSL_KEY_GEN) || defined (HAVE_ECC) || !defined(NO_DH) || \
5028
    !defined(NO_DSA) || !defined(NO_RSA)
5029
5030
/* c = a * a (mod b) */
5031
int fp_sqrmod(fp_int *a, fp_int *b, fp_int *c)
5032
0
{
5033
0
  int err;
5034
#ifndef WOLFSSL_SMALL_STACK
5035
   fp_int t[1];
5036
#else
5037
0
   fp_int *t;
5038
0
#endif
5039
5040
0
#ifdef WOLFSSL_SMALL_STACK
5041
0
   t = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);
5042
0
   if (t == NULL)
5043
0
       return FP_MEM;
5044
0
#endif
5045
5046
0
  fp_init(t);
5047
0
  err = fp_sqr(a, t);
5048
0
  if (err == FP_OKAY) {
5049
  #if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT)
5050
    if (c->size < FP_SIZE) {
5051
      err = fp_mod(t, b, t);
5052
      fp_copy(t, c);
5053
    }
5054
    else
5055
  #endif
5056
0
    {
5057
0
      err = fp_mod(t, b, c);
5058
0
    }
5059
0
  }
5060
5061
0
#ifdef WOLFSSL_SMALL_STACK
5062
0
  XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);
5063
0
#endif
5064
0
  return err;
5065
0
}
5066
5067
/* fast math conversion */
5068
int mp_sqrmod(mp_int *a, mp_int *b, mp_int *c)
5069
{
5070
    return fp_sqrmod(a, b, c);
5071
}
5072
5073
/* fast math conversion */
5074
int mp_montgomery_calc_normalization(mp_int *a, mp_int *b)
5075
0
{
5076
0
    return fp_montgomery_calc_normalization(a, b);
5077
0
}
5078
5079
#endif /* WOLFSSL_KEY_GEN || HAVE_ECC */
5080
5081
static int fp_cond_swap_ct_ex(mp_int* a, mp_int* b, int c, int m, mp_int* t)
5082
0
{
5083
0
    int i;
5084
0
    mp_digit mask = (mp_digit)0 - m;
5085
5086
0
    t->used = (a->used ^ b->used) & mask;
5087
0
    for (i = 0; i < c; i++) {
5088
0
        t->dp[i] = (a->dp[i] ^ b->dp[i]) & mask;
5089
0
    }
5090
0
    a->used ^= t->used;
5091
0
    for (i = 0; i < c; i++) {
5092
0
        a->dp[i] ^= t->dp[i];
5093
0
    }
5094
0
    b->used ^= t->used;
5095
0
    for (i = 0; i < c; i++) {
5096
0
        b->dp[i] ^= t->dp[i];
5097
0
    }
5098
5099
0
    return FP_OKAY;
5100
0
}
5101
5102
5103
static int fp_cond_swap_ct(mp_int* a, mp_int* b, int c, int m)
5104
0
{
5105
#ifndef WOLFSSL_SMALL_STACK
5106
    fp_int  t[1];
5107
#else
5108
0
    fp_int* t;
5109
0
#endif
5110
5111
0
#ifdef WOLFSSL_SMALL_STACK
5112
0
   t = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);
5113
0
   if (t == NULL)
5114
0
       return FP_MEM;
5115
0
#endif
5116
5117
0
   fp_cond_swap_ct_ex(a, b, c, m, t);
5118
5119
0
#ifdef WOLFSSL_SMALL_STACK
5120
0
    XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);
5121
0
#endif
5122
0
    return FP_OKAY;
5123
0
}
5124
5125
5126
#if defined(WC_MP_TO_RADIX) || !defined(NO_DH) || !defined(NO_DSA) || \
5127
    !defined(NO_RSA)
5128
5129
#ifdef WOLFSSL_KEY_GEN
5130
/* swap the elements of two integers, for cases where you can't simply swap the
5131
 * mp_int pointers around
5132
 */
5133
static int fp_exch (fp_int * a, fp_int * b)
5134
0
{
5135
#ifndef WOLFSSL_SMALL_STACK
5136
    fp_int  t[1];
5137
#else
5138
0
    fp_int *t;
5139
0
#endif
5140
5141
0
#ifdef WOLFSSL_SMALL_STACK
5142
0
   t = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);
5143
0
   if (t == NULL)
5144
0
       return FP_MEM;
5145
0
#endif
5146
5147
0
    *t = *a;
5148
0
    *a = *b;
5149
0
    *b = *t;
5150
5151
0
#ifdef WOLFSSL_SMALL_STACK
5152
0
    XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);
5153
0
#endif
5154
0
    return FP_OKAY;
5155
0
}
5156
#endif
5157
5158
static const int lnz[16] = {
5159
   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
5160
};
5161
5162
/* Counts the number of lsbs which are zero before the first zero bit */
5163
int fp_cnt_lsb(fp_int *a)
5164
0
{
5165
0
   int x;
5166
0
   fp_digit q, qq;
5167
5168
   /* easy out */
5169
0
   if (fp_iszero(a) == FP_YES) {
5170
0
      return 0;
5171
0
   }
5172
5173
   /* scan lower digits until non-zero */
5174
0
   for (x = 0; x < a->used && a->dp[x] == 0; x++) {}
5175
0
   q = a->dp[x];
5176
0
   x *= DIGIT_BIT;
5177
5178
   /* now scan this digit until a 1 is found */
5179
0
   if ((q & 1) == 0) {
5180
0
      do {
5181
0
         qq  = q & 15;
5182
0
         x  += lnz[qq];
5183
0
         q >>= 4;
5184
0
      } while (qq == 0);
5185
0
   }
5186
0
   return x;
5187
0
}
5188
5189
5190
static int s_is_power_of_two(fp_digit b, int *p)
5191
0
{
5192
0
   int x;
5193
5194
   /* fast return if no power of two */
5195
0
   if ((b==0) || (b & (b-1))) {
5196
0
      return FP_NO;
5197
0
   }
5198
5199
0
   for (x = 0; x < DIGIT_BIT; x++) {
5200
0
      if (b == (((fp_digit)1)<<x)) {
5201
0
         *p = x;
5202
0
         return FP_YES;
5203
0
      }
5204
0
   }
5205
0
   return FP_NO;
5206
0
}
5207
5208
/* a/b => cb + d == a */
5209
static int fp_div_d(fp_int *a, fp_digit b, fp_int *c, fp_digit *d)
5210
0
{
5211
#ifndef WOLFSSL_SMALL_STACK
5212
  fp_int   q[1];
5213
#else
5214
0
  fp_int   *q;
5215
0
#endif
5216
0
  fp_word  w;
5217
0
  fp_digit t;
5218
0
  int      ix;
5219
5220
  /* cannot divide by zero */
5221
0
  if (b == 0) {
5222
0
     return FP_VAL;
5223
0
  }
5224
5225
  /* quick outs */
5226
0
  if (b == 1 || fp_iszero(a) == FP_YES) {
5227
0
     if (d != NULL) {
5228
0
        *d = 0;
5229
0
     }
5230
0
     if (c != NULL) {
5231
0
        fp_copy(a, c);
5232
0
     }
5233
0
     return FP_OKAY;
5234
0
  }
5235
5236
  /* power of two ? */
5237
0
  if (s_is_power_of_two(b, &ix) == FP_YES) {
5238
0
     if (d != NULL) {
5239
0
        *d = a->dp[0] & ((((fp_digit)1)<<ix) - 1);
5240
0
     }
5241
0
     if (c != NULL) {
5242
0
        fp_div_2d(a, ix, c, NULL);
5243
0
     }
5244
0
     return FP_OKAY;
5245
0
  }
5246
5247
0
#ifdef WOLFSSL_SMALL_STACK
5248
0
  q = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);
5249
0
  if (q == NULL)
5250
0
      return FP_MEM;
5251
0
#endif
5252
5253
0
  fp_init(q);
5254
5255
0
  if (c != NULL) {
5256
0
    q->used = a->used;
5257
0
    q->sign = a->sign;
5258
0
  }
5259
5260
0
  w = 0;
5261
0
  for (ix = a->used - 1; ix >= 0; ix--) {
5262
0
     w = (w << ((fp_word)DIGIT_BIT)) | ((fp_word)a->dp[ix]);
5263
5264
0
     if (w >= b) {
5265
#ifdef WOLFSSL_LINUXKM
5266
        t = (fp_digit)w;
5267
        /* Linux kernel macro for in-place 64 bit integer division. */
5268
        do_div(t, b);
5269
#else
5270
0
        t = (fp_digit)(w / b);
5271
0
#endif
5272
0
        w -= ((fp_word)t) * ((fp_word)b);
5273
0
      } else {
5274
0
        t = 0;
5275
0
      }
5276
0
      if (c != NULL)
5277
0
        q->dp[ix] = (fp_digit)t;
5278
0
  }
5279
5280
0
  if (d != NULL) {
5281
0
     *d = (fp_digit)w;
5282
0
  }
5283
5284
0
  if (c != NULL) {
5285
0
     fp_clamp(q);
5286
0
     fp_copy(q, c);
5287
0
  }
5288
5289
0
#ifdef WOLFSSL_SMALL_STACK
5290
0
  XFREE(q, NULL, DYNAMIC_TYPE_BIGINT);
5291
0
#endif
5292
0
  return FP_OKAY;
5293
0
}
5294
5295
5296
/* c = a mod b, 0 <= c < b  */
5297
static int fp_mod_d(fp_int *a, fp_digit b, fp_digit *c)
5298
0
{
5299
0
   return fp_div_d(a, b, NULL, c);
5300
0
}
5301
5302
int mp_mod_d(fp_int *a, fp_digit b, fp_digit *c)
5303
409k
{
5304
409k
   return fp_mod_d(a, b, c);
5305
409k
}
5306
5307
#endif /* WC_MP_TO_RADIX || !NO_DH || !NO_DSA || !NO_RSA */
5308
5309
5310
#if !defined(NO_DH) || !defined(NO_DSA) || !defined(NO_RSA) || \
5311
    defined(WOLFSSL_KEY_GEN)
5312
5313
static int  fp_isprime_ex(fp_int *a, int t, int* result);
5314
5315
#if defined(FREESCALE_LTC_TFM)
5316
int wolfcrypt_mp_prime_is_prime(mp_int* a, int t, int* result)
5317
#else
5318
int mp_prime_is_prime(mp_int* a, int t, int* result)
5319
#endif
5320
0
{
5321
0
    return fp_isprime_ex(a, t, result);
5322
0
}
5323
5324
/* Miller-Rabin test of "a" to the base of "b" as described in
5325
 * HAC pp. 139 Algorithm 4.24
5326
 *
5327
 * Sets result to 0 if definitely composite or 1 if probably prime.
5328
 * Randomly the chance of error is no more than 1/4 and often
5329
 * very much lower.
5330
 */
5331
static int fp_prime_miller_rabin_ex(fp_int * a, fp_int * b, int *result,
5332
  fp_int *n1, fp_int *y, fp_int *r)
5333
0
{
5334
0
  int s, j;
5335
0
  int err;
5336
5337
  /* default */
5338
0
  *result = FP_NO;
5339
5340
  /* ensure b > 1 */
5341
0
  if (fp_cmp_d(b, 1) != FP_GT) {
5342
0
     return FP_OKAY;
5343
0
  }
5344
5345
  /* get n1 = a - 1 */
5346
0
  fp_copy(a, n1);
5347
0
  err = fp_sub_d(n1, 1, n1);
5348
0
  if (err != FP_OKAY) {
5349
0
     return err;
5350
0
  }
5351
5352
  /* set 2**s * r = n1 */
5353
0
  fp_copy(n1, r);
5354
5355
  /* count the number of least significant bits
5356
   * which are zero
5357
   */
5358
0
  s = fp_cnt_lsb(r);
5359
5360
  /* now divide n - 1 by 2**s */
5361
0
  fp_div_2d (r, s, r, NULL);
5362
5363
  /* compute y = b**r mod a */
5364
0
  fp_zero(y);
5365
#if (defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || \
5366
                                                     defined(WOLFSSL_HAVE_SP_DH)
5367
#ifndef WOLFSSL_SP_NO_2048
5368
  if (fp_count_bits(a) == 1024 && fp_isodd(a))
5369
      err = sp_ModExp_1024(b, r, a, y);
5370
  else if (fp_count_bits(a) == 2048 && fp_isodd(a))
5371
      err = sp_ModExp_2048(b, r, a, y);
5372
  else
5373
#endif
5374
#ifndef WOLFSSL_SP_NO_3072
5375
  if (fp_count_bits(a) == 1536 && fp_isodd(a))
5376
      err = sp_ModExp_1536(b, r, a, y);
5377
  else if (fp_count_bits(a) == 3072 && fp_isodd(a))
5378
      err = sp_ModExp_3072(b, r, a, y);
5379
  else
5380
#endif
5381
#ifdef WOLFSSL_SP_4096
5382
  if (fp_count_bits(a) == 4096 && fp_isodd(a))
5383
      err = sp_ModExp_4096(b, r, a, y);
5384
  else
5385
#endif
5386
#endif
5387
0
      err = fp_exptmod(b, r, a, y);
5388
0
   if (err != FP_OKAY) {
5389
0
       return err;
5390
0
   }
5391
5392
  /* if y != 1 and y != n1 do */
5393
0
  if (fp_cmp_d (y, 1) != FP_EQ && fp_cmp (y, n1) != FP_EQ) {
5394
0
    j = 1;
5395
    /* while j <= s-1 and y != n1 */
5396
0
    while ((j <= (s - 1)) && fp_cmp (y, n1) != FP_EQ) {
5397
0
      err = fp_sqrmod (y, a, y);
5398
0
      if (err != FP_OKAY)
5399
0
         return err;
5400
5401
      /* if y == 1 then composite */
5402
0
      if (fp_cmp_d (y, 1) == FP_EQ) {
5403
0
         return FP_OKAY;
5404
0
      }
5405
0
      ++j;
5406
0
    }
5407
5408
    /* if y != n1 then composite */
5409
0
    if (fp_cmp (y, n1) != FP_EQ) {
5410
0
       return FP_OKAY;
5411
0
    }
5412
0
  }
5413
5414
  /* probably prime now */
5415
0
  *result = FP_YES;
5416
5417
0
  return FP_OKAY;
5418
0
}
5419
5420
static int fp_prime_miller_rabin(fp_int * a, fp_int * b, int *result)
5421
0
{
5422
0
  int err;
5423
#ifndef WOLFSSL_SMALL_STACK
5424
  fp_int  n1[1], y[1], r[1];
5425
#else
5426
0
  fp_int *n1, *y, *r;
5427
0
#endif
5428
5429
0
#ifdef WOLFSSL_SMALL_STACK
5430
0
  n1 = (fp_int*)XMALLOC(sizeof(fp_int) * 3, NULL, DYNAMIC_TYPE_BIGINT);
5431
0
  if (n1 == NULL) {
5432
0
      return FP_MEM;
5433
0
  }
5434
0
  y = &n1[1]; r = &n1[2];
5435
0
#endif
5436
5437
0
  fp_init(n1);
5438
0
  fp_init(y);
5439
0
  fp_init(r);
5440
5441
0
  err = fp_prime_miller_rabin_ex(a, b, result, n1, y, r);
5442
5443
0
  fp_clear(n1);
5444
0
  fp_clear(y);
5445
0
  fp_clear(r);
5446
5447
0
#ifdef WOLFSSL_SMALL_STACK
5448
0
  XFREE(n1, NULL, DYNAMIC_TYPE_BIGINT);
5449
0
#endif
5450
5451
0
  return err;
5452
0
}
5453
5454
5455
/* a few primes */
5456
static const fp_digit primes[FP_PRIME_SIZE] = {
5457
  0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
5458
  0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
5459
  0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,
5460
  0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, 0x0083,
5461
  0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,
5462
  0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,
5463
  0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,
5464
  0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137,
5465
5466
  0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167,
5467
  0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199,
5468
  0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9,
5469
  0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7,
5470
  0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239,
5471
  0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265,
5472
  0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293,
5473
  0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF,
5474
5475
  0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301,
5476
  0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B,
5477
  0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371,
5478
  0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD,
5479
  0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,
5480
  0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419,
5481
  0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449,
5482
  0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B,
5483
5484
  0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7,
5485
  0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503,
5486
  0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529,
5487
  0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F,
5488
  0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3,
5489
  0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7,
5490
  0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623,
5491
  0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653
5492
};
5493
5494
int fp_isprime_ex(fp_int *a, int t, int* result)
5495
0
{
5496
#ifndef WOLFSSL_SMALL_STACK
5497
   fp_int   b[1];
5498
#else
5499
0
   fp_int   *b;
5500
0
#endif
5501
0
   fp_digit d;
5502
0
   int      r, res;
5503
0
   int      err;
5504
5505
0
   if (t <= 0 || t > FP_PRIME_SIZE) {
5506
0
     *result = FP_NO;
5507
0
     return FP_VAL;
5508
0
   }
5509
5510
0
   if (fp_isone(a)) {
5511
0
       *result = FP_NO;
5512
0
       return FP_OKAY;
5513
0
   }
5514
5515
   /* check against primes table */
5516
0
   for (r = 0; r < FP_PRIME_SIZE; r++) {
5517
0
       if (fp_cmp_d(a, primes[r]) == FP_EQ) {
5518
0
           *result = FP_YES;
5519
0
           return FP_OKAY;
5520
0
       }
5521
0
   }
5522
5523
   /* do trial division */
5524
0
   for (r = 0; r < FP_PRIME_SIZE; r++) {
5525
0
       res = fp_mod_d(a, primes[r], &d);
5526
0
       if (res != MP_OKAY || d == 0) {
5527
0
           *result = FP_NO;
5528
0
           return res;
5529
0
       }
5530
0
   }
5531
5532
0
#ifdef WOLFSSL_SMALL_STACK
5533
0
  b = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);
5534
0
  if (b == NULL)
5535
0
      return FP_MEM;
5536
0
#endif
5537
   /* now do 't' miller rabins */
5538
0
   fp_init(b);
5539
0
   for (r = 0; r < t; r++) {
5540
0
       fp_set(b, primes[r]);
5541
0
       err = fp_prime_miller_rabin(a, b, &res);
5542
0
       if ((err != FP_OKAY) || (res == FP_NO)) {
5543
0
          *result = res;
5544
0
       #ifdef WOLFSSL_SMALL_STACK
5545
0
          XFREE(b, NULL, DYNAMIC_TYPE_BIGINT);
5546
0
       #endif
5547
0
          return err;
5548
0
       }
5549
0
   }
5550
0
   *result = FP_YES;
5551
0
#ifdef WOLFSSL_SMALL_STACK
5552
0
   XFREE(b, NULL, DYNAMIC_TYPE_BIGINT);
5553
0
#endif
5554
0
   return FP_OKAY;
5555
0
}
5556
5557
5558
#if defined(FREESCALE_LTC_TFM)
5559
int wolfcrypt_mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng)
5560
#else
5561
int mp_prime_is_prime_ex(mp_int* a, int t, int* result, WC_RNG* rng)
5562
#endif
5563
0
{
5564
0
    int ret = FP_YES;
5565
0
    fp_digit d;
5566
0
    int i;
5567
5568
0
    if (a == NULL || result == NULL || rng == NULL)
5569
0
        return FP_VAL;
5570
0
    if (a->sign == FP_NEG)
5571
0
        return FP_VAL;
5572
0
    if (t <= 0 || t > FP_PRIME_SIZE)
5573
0
        return FP_VAL;
5574
5575
0
    if (fp_isone(a)) {
5576
0
        *result = FP_NO;
5577
0
        return FP_OKAY;
5578
0
    }
5579
5580
    /* check against primes table */
5581
0
    for (i = 0; i < FP_PRIME_SIZE; i++) {
5582
0
        if (fp_cmp_d(a, primes[i]) == FP_EQ) {
5583
0
            *result = FP_YES;
5584
0
            return FP_OKAY;
5585
0
        }
5586
0
    }
5587
5588
    /* do trial division */
5589
0
    for (i = 0; i < FP_PRIME_SIZE; i++) {
5590
0
        if (fp_mod_d(a, primes[i], &d) == MP_OKAY) {
5591
0
            if (d == 0) {
5592
0
                *result = FP_NO;
5593
0
                return FP_OKAY;
5594
0
            }
5595
0
        }
5596
0
        else
5597
0
            return FP_VAL;
5598
0
    }
5599
5600
0
#ifndef WC_NO_RNG
5601
    /* now do a miller rabin with up to t random numbers, this should
5602
     * give a (1/4)^t chance of a false prime. */
5603
0
    {
5604
    #ifndef WOLFSSL_SMALL_STACK
5605
        fp_int b[1], c[1], n1[1], y[1], r[1];
5606
        byte   base[FP_MAX_PRIME_SIZE];
5607
    #else
5608
0
        fp_int *b, *c, *n1, *y, *r;
5609
0
        byte*  base;
5610
0
    #endif
5611
0
        word32 baseSz;
5612
0
        word32 bitSz;
5613
0
        int    err;
5614
5615
0
        bitSz = fp_count_bits(a);
5616
        /* The base size is the number of bits / 8. One is added if the number
5617
         * of bits isn't an even 8. */
5618
0
        baseSz = (bitSz / 8) + ((bitSz % 8) ? 1 : 0);
5619
0
        bitSz %= 8;
5620
5621
    #ifndef WOLFSSL_SMALL_STACK
5622
        if (baseSz > sizeof(base))
5623
            return FP_MEM;
5624
    #else
5625
0
        base = (byte*)XMALLOC(baseSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5626
0
        if (base == NULL)
5627
0
            return FP_MEM;
5628
5629
0
        b = (fp_int*)XMALLOC(sizeof(fp_int) * 5, NULL, DYNAMIC_TYPE_BIGINT);
5630
0
        if (b == NULL) {
5631
0
            XFREE(base, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5632
0
            return FP_MEM;
5633
0
        }
5634
0
        c = &b[1]; n1 = &b[2]; y= &b[3]; r = &b[4];
5635
0
    #endif
5636
5637
0
        fp_init(b);
5638
0
        fp_init(c);
5639
0
        fp_init(n1);
5640
0
        fp_init(y);
5641
0
        fp_init(r);
5642
5643
0
        err = fp_sub_d(a, 2, c);
5644
0
        if (err != FP_OKAY) {
5645
0
        #ifdef WOLFSSL_SMALL_STACK
5646
0
           XFREE(b, NULL, DYNAMIC_TYPE_BIGINT);
5647
0
           XFREE(base, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5648
0
        #endif
5649
0
           return err;
5650
0
        }
5651
0
        while (t > 0) {
5652
0
            if ((err = wc_RNG_GenerateBlock(rng, base, baseSz)) != 0) {
5653
0
            #ifdef WOLFSSL_SMALL_STACK
5654
0
               XFREE(b, NULL, DYNAMIC_TYPE_BIGINT);
5655
0
               XFREE(base, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5656
0
            #endif
5657
0
               return err;
5658
0
            }
5659
5660
0
            if (bitSz != 0)
5661
0
                base[0] &= (1 << bitSz) - 1;
5662
5663
0
            err = fp_read_unsigned_bin(b, base, baseSz);
5664
0
            if (err != FP_OKAY) {
5665
0
            #ifdef WOLFSSL_SMALL_STACK
5666
0
               XFREE(b, NULL, DYNAMIC_TYPE_BIGINT);
5667
0
               XFREE(base, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5668
0
            #endif
5669
0
               return err;
5670
0
            }
5671
0
            if (fp_cmp_d(b, 2) != FP_GT || fp_cmp(b, c) != FP_LT) {
5672
0
                continue;
5673
0
            }
5674
5675
0
            err = fp_prime_miller_rabin_ex(a, b, &ret, n1, y, r);
5676
0
            if (err != FP_OKAY) {
5677
0
            #ifdef WOLFSSL_SMALL_STACK
5678
0
               XFREE(b, NULL, DYNAMIC_TYPE_BIGINT);
5679
0
               XFREE(base, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5680
0
            #endif
5681
0
               return err;
5682
0
            }
5683
0
            if (ret == FP_NO)
5684
0
                break;
5685
0
            fp_zero(b);
5686
0
            t--;
5687
0
        }
5688
5689
0
        fp_clear(n1);
5690
0
        fp_clear(y);
5691
0
        fp_clear(r);
5692
0
        fp_clear(b);
5693
0
        fp_clear(c);
5694
0
     #ifdef WOLFSSL_SMALL_STACK
5695
0
        XFREE(b, NULL, DYNAMIC_TYPE_BIGINT);
5696
0
        XFREE(base, NULL, DYNAMIC_TYPE_TMP_BUFFER);
5697
0
     #endif
5698
0
    }
5699
#else
5700
    (void)t;
5701
#endif /* !WC_NO_RNG */
5702
5703
0
    *result = ret;
5704
0
    return FP_OKAY;
5705
0
}
5706
#endif /* !NO_RSA || !NO_DSA || !NO_DH || WOLFSSL_KEY_GEN */
5707
5708
5709
int mp_cond_swap_ct_ex(mp_int* a, mp_int* b, int c, int m, mp_int* t)
5710
{
5711
    return fp_cond_swap_ct_ex(a, b, c, m, t);
5712
}
5713
5714
int mp_cond_swap_ct(mp_int* a, mp_int* b, int c, int m)
5715
0
{
5716
0
    return fp_cond_swap_ct(a, b, c, m);
5717
0
}
5718
5719
#ifdef WOLFSSL_KEY_GEN
5720
5721
static int  fp_gcd(fp_int *a, fp_int *b, fp_int *c);
5722
static int  fp_lcm(fp_int *a, fp_int *b, fp_int *c);
5723
static int  fp_randprime(fp_int* a, int len, WC_RNG* rng, void* heap);
5724
5725
int mp_gcd(fp_int *a, fp_int *b, fp_int *c)
5726
0
{
5727
0
    return fp_gcd(a, b, c);
5728
0
}
5729
5730
5731
int mp_lcm(fp_int *a, fp_int *b, fp_int *c)
5732
{
5733
    return fp_lcm(a, b, c);
5734
}
5735
5736
int mp_rand_prime(mp_int* a, int len, WC_RNG* rng, void* heap)
5737
{
5738
    int err;
5739
5740
    err = fp_randprime(a, len, rng, heap);
5741
    switch(err) {
5742
        case WC_NO_ERR_TRACE(MP_VAL):
5743
            return MP_VAL;
5744
        case WC_NO_ERR_TRACE(MP_MEM):
5745
            return MP_MEM;
5746
        default:
5747
            break;
5748
    }
5749
5750
    return MP_OKAY;
5751
}
5752
5753
int mp_exch (mp_int * a, mp_int * b)
5754
7.21M
{
5755
7.21M
    return fp_exch(a, b);
5756
7.21M
}
5757
5758
5759
5760
int fp_randprime(fp_int* a, int len, WC_RNG* rng, void* heap)
5761
0
{
5762
0
    static const int USE_BBS = 1;
5763
0
    int   err, type;
5764
0
    int   isPrime = FP_YES;
5765
        /* Assume the candidate is probably prime and then test until
5766
         * it is proven composite. */
5767
0
    byte* buf;
5768
5769
0
    (void)heap;
5770
5771
    /* get type */
5772
0
    if (len < 0) {
5773
0
        type = USE_BBS;
5774
0
        len = -len;
5775
0
    } else {
5776
0
        type = 0;
5777
0
    }
5778
5779
    /* allow sizes between 2 and 512 bytes for a prime size */
5780
0
    if (len < 2 || len > 512) {
5781
0
        return FP_VAL;
5782
0
    }
5783
5784
    /* allocate buffer to work with */
5785
0
    buf = (byte*)XMALLOC(len, heap, DYNAMIC_TYPE_TMP_BUFFER);
5786
0
    if (buf == NULL) {
5787
0
        return FP_MEM;
5788
0
    }
5789
0
    XMEMSET(buf, 0, len);
5790
5791
0
    do {
5792
#ifdef SHOW_GEN
5793
        printf(".");
5794
        fflush(stdout);
5795
#endif
5796
        /* generate value */
5797
0
        err = wc_RNG_GenerateBlock(rng, buf, len);
5798
0
        if (err != 0) {
5799
0
            XFREE(buf, heap, DYNAMIC_TYPE_TMP_BUFFER);
5800
0
            return FP_VAL;
5801
0
        }
5802
5803
        /* munge bits */
5804
0
        buf[0]     |= 0x80 | 0x40;
5805
0
        buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00);
5806
5807
        /* load value */
5808
0
        err = fp_read_unsigned_bin(a, buf, len);
5809
0
        if (err != 0) {
5810
0
            XFREE(buf, heap, DYNAMIC_TYPE_TMP_BUFFER);
5811
0
            return err;
5812
0
        }
5813
5814
        /* test */
5815
        /* Running Miller-Rabin up to 3 times gives us a 2^{-80} chance
5816
         * of a 1024-bit candidate being a false positive, when it is our
5817
         * prime candidate. (Note 4.49 of Handbook of Applied Cryptography.)
5818
         * Using 8 because we've always used 8 */
5819
0
        mp_prime_is_prime_ex(a, 8, &isPrime, rng);
5820
0
    } while (isPrime == FP_NO);
5821
5822
0
    XMEMSET(buf, 0, len);
5823
0
    XFREE(buf, heap, DYNAMIC_TYPE_TMP_BUFFER);
5824
5825
0
    return FP_OKAY;
5826
0
}
5827
5828
/* c = [a, b] */
5829
int fp_lcm(fp_int *a, fp_int *b, fp_int *c)
5830
0
{
5831
0
   int     err;
5832
#ifndef WOLFSSL_SMALL_STACK
5833
   fp_int  t[2];
5834
#else
5835
0
   fp_int  *t;
5836
0
#endif
5837
5838
   /* LCM of 0 and any number is undefined as 0 is not in the set of values
5839
    * being used. */
5840
0
   if (fp_iszero(a) == FP_YES || fp_iszero(b) == FP_YES) {
5841
0
       return FP_VAL;
5842
0
   }
5843
5844
0
#ifdef WOLFSSL_SMALL_STACK
5845
0
   t = (fp_int*)XMALLOC(sizeof(fp_int) * 2, NULL, DYNAMIC_TYPE_BIGINT);
5846
0
   if (t == NULL) {
5847
0
       return FP_MEM;
5848
0
   }
5849
0
#endif
5850
5851
0
   fp_init(&t[0]);
5852
0
   fp_init(&t[1]);
5853
0
   err = fp_gcd(a, b, &t[0]);
5854
0
   if (err == FP_OKAY) {
5855
0
      if (fp_cmp_mag(a, b) == FP_GT) {
5856
0
        err = fp_div(a, &t[0], &t[1], NULL);
5857
0
        if (err == FP_OKAY)
5858
0
          err = fp_mul(b, &t[1], c);
5859
0
     } else {
5860
0
        err = fp_div(b, &t[0], &t[1], NULL);
5861
0
        if (err == FP_OKAY)
5862
0
          err = fp_mul(a, &t[1], c);
5863
0
     }
5864
0
   }
5865
5866
0
#ifdef WOLFSSL_SMALL_STACK
5867
0
   XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);
5868
0
#endif
5869
0
   return err;
5870
0
}
5871
5872
5873
5874
/* c = (a, b) */
5875
int fp_gcd(fp_int *a, fp_int *b, fp_int *c)
5876
0
{
5877
#ifndef WOLFSSL_SMALL_STACK
5878
   fp_int u[1], v[1], r[1];
5879
#else
5880
0
   fp_int *u, *v, *r;
5881
0
#endif
5882
5883
   /* GCD of 0 and 0 is undefined as all integers divide 0. */
5884
0
   if (fp_iszero(a) == FP_YES && fp_iszero(b) == FP_YES) {
5885
0
       return FP_VAL;
5886
0
   }
5887
5888
   /* either zero than gcd is the largest */
5889
0
   if (fp_iszero (a) == FP_YES && fp_iszero (b) == FP_NO) {
5890
0
     fp_abs (b, c);
5891
0
     return FP_OKAY;
5892
0
   }
5893
0
   if (fp_iszero (a) == FP_NO && fp_iszero (b) == FP_YES) {
5894
0
     fp_abs (a, c);
5895
0
     return FP_OKAY;
5896
0
   }
5897
5898
   /* optimized.  At this point if a == 0 then
5899
    * b must equal zero too
5900
    */
5901
0
   if (fp_iszero (a) == FP_YES) {
5902
0
     fp_zero(c);
5903
0
     return FP_OKAY;
5904
0
   }
5905
5906
0
#ifdef WOLFSSL_SMALL_STACK
5907
0
   u = (fp_int*)XMALLOC(sizeof(fp_int) * 3, NULL, DYNAMIC_TYPE_BIGINT);
5908
0
   if (u == NULL) {
5909
0
       return FP_MEM;
5910
0
   }
5911
0
   v = &u[1]; r = &u[2];
5912
0
#endif
5913
5914
   /* sort inputs */
5915
0
   if (fp_cmp_mag(a, b) != FP_LT) {
5916
0
      fp_init_copy(u, a);
5917
0
      fp_init_copy(v, b);
5918
0
   } else {
5919
0
      fp_init_copy(u, b);
5920
0
      fp_init_copy(v, a);
5921
0
   }
5922
5923
0
   u->sign = FP_ZPOS;
5924
0
   v->sign = FP_ZPOS;
5925
5926
0
   fp_init(r);
5927
0
   while (fp_iszero(v) == FP_NO) {
5928
0
      int err = fp_mod(u, v, r);
5929
0
      if (err != MP_OKAY) {
5930
0
#ifdef WOLFSSL_SMALL_STACK
5931
0
          XFREE(u, NULL, DYNAMIC_TYPE_BIGINT);
5932
0
#endif
5933
0
        return err;
5934
0
      }
5935
0
      fp_copy(v, u);
5936
0
      fp_copy(r, v);
5937
0
   }
5938
0
   fp_copy(u, c);
5939
5940
0
#ifdef WOLFSSL_SMALL_STACK
5941
0
   XFREE(u, NULL, DYNAMIC_TYPE_BIGINT);
5942
0
#endif
5943
0
   return FP_OKAY;
5944
0
}
5945
5946
#endif /* WOLFSSL_KEY_GEN */
5947
5948
5949
#if defined(HAVE_ECC) || !defined(NO_PWDBASED) || defined(OPENSSL_EXTRA) || \
5950
    defined(WC_RSA_BLINDING) || !defined(NO_DSA) || \
5951
    (!defined(NO_RSA) && !defined(NO_RSA_BOUNDS_CHECK))
5952
/* c = a + b */
5953
int fp_add_d(fp_int *a, fp_digit b, fp_int *c)
5954
0
{
5955
#ifndef WOLFSSL_SMALL_STACK
5956
   fp_int  tmp[1];
5957
#else
5958
0
   fp_int* tmp;
5959
0
#endif
5960
0
   int     err;
5961
5962
0
#ifdef WOLFSSL_SMALL_STACK
5963
0
   tmp = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);
5964
0
   if (tmp == NULL)
5965
0
       return FP_MEM;
5966
0
#endif
5967
5968
0
   fp_init(tmp);
5969
0
   fp_set(tmp, b);
5970
0
   err = fp_add(a, tmp, c);
5971
5972
0
#ifdef WOLFSSL_SMALL_STACK
5973
0
   XFREE(tmp, NULL, DYNAMIC_TYPE_BIGINT);
5974
0
#endif
5975
0
   return err;
5976
0
}
5977
5978
/* external compatibility */
5979
int mp_add_d(fp_int *a, fp_digit b, fp_int *c)
5980
{
5981
    return fp_add_d(a, b, c);
5982
}
5983
5984
#endif  /* HAVE_ECC || !NO_PWDBASED || OPENSSL_EXTRA || WC_RSA_BLINDING ||
5985
  !NO_DSA || (!NO_RSA && !NO_RSA_BOUNDS_CHECK) */
5986
5987
5988
#if !defined(NO_DSA) || defined(HAVE_ECC) || defined(WOLFSSL_KEY_GEN) || \
5989
    defined(HAVE_COMP_KEY) || defined(WOLFSSL_DEBUG_MATH) || \
5990
    defined(DEBUG_WOLFSSL) || defined(OPENSSL_EXTRA) || defined(WC_MP_TO_RADIX)
5991
5992
/* chars used in radix conversions */
5993
static wcchar fp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
5994
                                    "abcdefghijklmnopqrstuvwxyz+/";
5995
#endif
5996
5997
#if defined(OPENSSL_EXTRA) || !defined(NO_DSA) || defined(HAVE_ECC)
5998
#if DIGIT_BIT == 64 || DIGIT_BIT == 32
5999
static int fp_read_radix_16(fp_int *a, const char *str)
6000
0
{
6001
0
  int     i, j, k, neg;
6002
0
  int     ch;
6003
  /* Skip whitespace at end of line */
6004
0
  int     eol_done = 0;
6005
6006
  /* if the leading digit is a
6007
   * minus set the sign to negative.
6008
   */
6009
0
  if (*str == '-') {
6010
0
    ++str;
6011
0
    neg = FP_NEG;
6012
0
  } else {
6013
0
    neg = FP_ZPOS;
6014
0
  }
6015
6016
0
  j = 0;
6017
0
  k = 0;
6018
0
  for (i = (int)(XSTRLEN(str) - 1); i >= 0; i--) {
6019
0
      ch = (int)HexCharToByte(str[i]);
6020
0
      if (ch < 0) {
6021
0
        if (!eol_done && CharIsWhiteSpace(str[i]))
6022
0
          continue;
6023
0
        return FP_VAL;
6024
0
      }
6025
0
      eol_done = 1;
6026
6027
0
      k += j == DIGIT_BIT;
6028
0
      j &= DIGIT_BIT - 1;
6029
0
      if (k >= FP_SIZE)
6030
0
          return FP_VAL;
6031
6032
0
      a->dp[k] |= ((fp_digit)ch) << j;
6033
0
      j += 4;
6034
0
  }
6035
6036
0
  a->used = k + 1;
6037
0
  fp_clamp(a);
6038
  /* set the sign only if a != 0 */
6039
0
  if (fp_iszero(a) != FP_YES) {
6040
0
     a->sign = neg;
6041
0
  }
6042
0
  return FP_OKAY;
6043
0
}
6044
#endif
6045
6046
static int fp_read_radix(fp_int *a, const char *str, int radix)
6047
0
{
6048
0
  int     y, neg;
6049
0
  char    ch;
6050
6051
  /* set the integer to the default of zero */
6052
0
  fp_zero (a);
6053
6054
0
#if DIGIT_BIT == 64 || DIGIT_BIT == 32
6055
0
  if (radix == 16)
6056
0
      return fp_read_radix_16(a, str);
6057
0
#endif
6058
6059
  /* make sure the radix is ok */
6060
0
  if (radix < 2 || radix > 64) {
6061
0
    return FP_VAL;
6062
0
  }
6063
6064
  /* if the leading digit is a
6065
   * minus set the sign to negative.
6066
   */
6067
0
  if (*str == '-') {
6068
0
    ++str;
6069
0
    neg = FP_NEG;
6070
0
  } else {
6071
0
    neg = FP_ZPOS;
6072
0
  }
6073
6074
  /* process each digit of the string */
6075
0
  while (*str) {
6076
    /* if the radix <= 36 the conversion is case insensitive
6077
     * this allows numbers like 1AB and 1ab to represent the same  value
6078
     * [e.g. in hex]
6079
     */
6080
0
    ch = (char)((radix <= 36) ? XTOUPPER((unsigned char)*str) : *str);
6081
0
    for (y = 0; y < 64; y++) {
6082
0
      if (ch == fp_s_rmap[y]) {
6083
0
         break;
6084
0
      }
6085
0
    }
6086
0
    if (y >= radix) {
6087
      /* Check if whitespace at end of line */
6088
0
      while (CharIsWhiteSpace(*str))
6089
0
        ++str;
6090
0
      if (*str)
6091
0
        return FP_VAL;
6092
0
      else
6093
0
        break;
6094
0
    }
6095
6096
    /* if the char was found in the map
6097
     * and is less than the given radix add it
6098
     * to the number, otherwise exit the loop.
6099
     */
6100
0
    if (y < radix) {
6101
0
      int ret = fp_mul_d (a, (fp_digit) radix, a);
6102
0
      if (ret != FP_OKAY)
6103
0
        return ret;
6104
0
      ret = fp_add_d (a, (fp_digit) y, a);
6105
0
      if (ret != FP_OKAY)
6106
0
        return ret;
6107
0
    } else {
6108
0
      break;
6109
0
    }
6110
0
    ++str;
6111
0
  }
6112
6113
  /* set the sign only if a != 0 */
6114
0
  if (fp_iszero(a) != FP_YES) {
6115
0
     a->sign = neg;
6116
0
  }
6117
0
  return FP_OKAY;
6118
0
}
6119
6120
/* fast math conversion */
6121
int mp_read_radix(mp_int *a, const char *str, int radix)
6122
{
6123
    return fp_read_radix(a, str, radix);
6124
}
6125
6126
#endif /* !defined(NO_DSA) || defined(HAVE_ECC) */
6127
6128
#if defined(HAVE_ECC) || (!defined(NO_RSA) && defined(WC_RSA_BLINDING))
6129
6130
int mp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp)
6131
0
{
6132
0
    return fp_montgomery_reduce(a, m, mp);
6133
0
}
6134
6135
int mp_montgomery_reduce_ex(fp_int *a, fp_int *m, fp_digit mp, int ct)
6136
0
{
6137
0
    return fp_montgomery_reduce_ex(a, m, mp, ct);
6138
0
}
6139
6140
6141
/* fast math conversion */
6142
int mp_montgomery_setup(fp_int *a, fp_digit *rho)
6143
{
6144
    return fp_montgomery_setup(a, rho);
6145
}
6146
6147
#endif /* HAVE_ECC || (!NO_RSA && WC_RSA_BLINDING) */
6148
6149
/* fast math conversion */
6150
int mp_sqr(fp_int *A, fp_int *B)
6151
{
6152
    return fp_sqr(A, B);
6153
}
6154
6155
#ifdef HAVE_ECC
6156
6157
/* fast math conversion */
6158
int mp_div_2(fp_int * a, fp_int * b)
6159
0
{
6160
0
    fp_div_2(a, b);
6161
0
    return MP_OKAY;
6162
0
}
6163
6164
/* c = a / 2 (mod b) - constant time (a < b and positive) */
6165
int mp_div_2_mod_ct(mp_int *a, mp_int *b, mp_int *c)
6166
{
6167
  return fp_div_2_mod_ct(a, b, c);
6168
}
6169
6170
#ifdef HAVE_COMP_KEY
6171
6172
int mp_cnt_lsb(fp_int* a)
6173
0
{
6174
0
    return fp_cnt_lsb(a);
6175
0
}
6176
6177
#endif /* HAVE_COMP_KEY */
6178
6179
#endif /* HAVE_ECC */
6180
6181
#if defined(HAVE_ECC) || !defined(NO_RSA) || !defined(NO_DSA) || \
6182
    defined(WOLFSSL_KEY_GEN)
6183
/* fast math conversion */
6184
int mp_set(fp_int *a, fp_digit b)
6185
{
6186
    fp_set(a,b);
6187
    return MP_OKAY;
6188
}
6189
#endif
6190
6191
#ifdef WC_MP_TO_RADIX
6192
6193
/* returns size of ASCII representation */
6194
int mp_radix_size (mp_int *a, int radix, int *size)
6195
{
6196
    int      res, digs;
6197
    fp_digit d;
6198
#ifndef WOLFSSL_SMALL_STACK
6199
    fp_int   t[1];
6200
#else
6201
    fp_int   *t;
6202
#endif
6203
6204
    *size = 0;
6205
6206
    /* special case for binary */
6207
    if (radix == 2) {
6208
        *size = fp_count_bits(a);
6209
        if (*size == 0)
6210
          *size = 1;
6211
        *size += (a->sign == FP_NEG ? 1 : 0) + 1; /* "-" sign + null term */
6212
        return FP_OKAY;
6213
    }
6214
6215
    /* make sure the radix is in range */
6216
    if (radix < 2 || radix > 64) {
6217
        return FP_VAL;
6218
    }
6219
6220
    if (fp_iszero(a) == MP_YES) {
6221
#ifndef WC_DISABLE_RADIX_ZERO_PAD
6222
        if (radix == 16)
6223
            *size = 3;
6224
        else
6225
#endif
6226
            *size = 2;
6227
        return FP_OKAY;
6228
    }
6229
6230
    /* digs is the digit count */
6231
    digs = 0;
6232
6233
#ifdef WOLFSSL_SMALL_STACK
6234
    t = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);
6235
    if (t == NULL)
6236
        return FP_MEM;
6237
#endif
6238
6239
    /* Init a copy (t) of the input (a)
6240
    **
6241
    ** ALERT: Not calling fp_init_copy() as some compiler optimization settings
6242
    ** such as -O2 will complain that (t) "may be used uninitialized"
6243
    ** The fp_init() is here only to appease the compiler.  */
6244
    fp_init(t);
6245
    fp_copy(a, t); /* copy (src = a) to (dst = t)*/
6246
6247
    /* force temp to positive */
6248
    t->sign = FP_ZPOS;
6249
6250
    /* fetch out all of the digits */
6251
    while (fp_iszero (t) == FP_NO) {
6252
        if ((res = fp_div_d (t, (mp_digit) radix, t, &d)) != FP_OKAY) {
6253
            fp_zero (t);
6254
        #ifdef WOLFSSL_SMALL_STACK
6255
            XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);
6256
        #endif
6257
            return res;
6258
        }
6259
        ++digs;
6260
    }
6261
    fp_zero (t);
6262
6263
#ifndef WC_DISABLE_RADIX_ZERO_PAD
6264
    /* For hexadecimal output, add zero padding when number of digits is odd */
6265
    if ((digs & 1) && (radix == 16)) {
6266
        ++digs;
6267
    }
6268
#endif
6269
6270
    /* if it's negative add one for the sign */
6271
    if (a->sign == FP_NEG) {
6272
        ++digs;
6273
    }
6274
6275
    /* return digs + 1, the 1 is for the NULL byte that would be required. */
6276
    *size = digs + 1;
6277
#ifdef WOLFSSL_SMALL_STACK
6278
    XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);
6279
#endif
6280
    return FP_OKAY;
6281
}
6282
6283
/* stores a bignum as a ASCII string in a given radix (2..64) */
6284
int mp_toradix (mp_int *a, char *str, int radix)
6285
0
{
6286
0
    int      res, digs;
6287
0
    fp_digit d;
6288
0
    char     *_s = str;
6289
#ifndef WOLFSSL_SMALL_STACK
6290
    fp_int   t[1];
6291
#else
6292
0
    fp_int   *t;
6293
0
#endif
6294
6295
    /* check range of the radix */
6296
0
    if (radix < 2 || radix > 64) {
6297
0
        return FP_VAL;
6298
0
    }
6299
6300
    /* quick out if its zero */
6301
0
    if (fp_iszero(a) == FP_YES) {
6302
0
#ifndef WC_DISABLE_RADIX_ZERO_PAD
6303
0
        if (radix == 16)
6304
0
            *str++ = '0';
6305
0
#endif
6306
0
        *str++ = '0';
6307
0
        *str = '\0';
6308
0
        return FP_OKAY;
6309
0
    }
6310
6311
0
#ifdef WOLFSSL_SMALL_STACK
6312
0
    t = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT);
6313
0
    if (t == NULL)
6314
0
        return FP_MEM;
6315
0
#endif
6316
6317
    /* Init a copy (t) of the input (a)
6318
    **
6319
    ** ALERT: Not calling fp_init_copy() as some compiler optimization settings
6320
    ** such as -O2 will complain that (t) "may be used uninitialized"
6321
    ** The fp_init() is here only to appease the compiler.  */
6322
0
    fp_init(t);
6323
0
    fp_copy(a, t); /* copy (src = a) to (dst = t) */
6324
6325
    /* if it is negative output a - */
6326
0
    if (t->sign == FP_NEG) {
6327
0
        ++_s;
6328
0
        *str++ = '-';
6329
0
        t->sign = FP_ZPOS;
6330
0
    }
6331
6332
0
    digs = 0;
6333
0
    while (fp_iszero (t) == FP_NO) {
6334
0
        if ((res = fp_div_d (t, (fp_digit) radix, t, &d)) != FP_OKAY) {
6335
0
            fp_zero (t);
6336
0
        #ifdef WOLFSSL_SMALL_STACK
6337
0
            XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);
6338
0
        #endif
6339
0
            return res;
6340
0
        }
6341
0
        *str++ = fp_s_rmap[d];
6342
0
        ++digs;
6343
0
    }
6344
0
#ifndef WC_DISABLE_RADIX_ZERO_PAD
6345
    /* For hexadecimal output, add zero padding when number of digits is odd */
6346
0
    if ((digs & 1) && (radix == 16)) {
6347
0
        *str++ = fp_s_rmap[0];
6348
0
        ++digs;
6349
0
    }
6350
0
#endif
6351
    /* reverse the digits of the string.  In this case _s points
6352
     * to the first digit [excluding the sign] of the number]
6353
     */
6354
0
    mp_reverse ((unsigned char *)_s, digs);
6355
6356
    /* append a NULL so the string is properly terminated */
6357
0
    *str = '\0';
6358
6359
0
    fp_zero (t);
6360
0
#ifdef WOLFSSL_SMALL_STACK
6361
0
    XFREE(t, NULL, DYNAMIC_TYPE_BIGINT);
6362
0
#endif
6363
0
    return FP_OKAY;
6364
0
}
6365
6366
#ifdef WOLFSSL_DEBUG_MATH
6367
void mp_dump(const char* desc, mp_int* a, byte verbose)
6368
{
6369
  char buffer[FP_SIZE * sizeof(fp_digit) * 2];
6370
  int size;
6371
6372
#if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT)
6373
  size = a->size;
6374
#else
6375
  size = FP_SIZE;
6376
#endif
6377
6378
  printf("%s: ptr=%p, used=%d, sign=%d, size=%d, fpd=%d\n",
6379
    desc, a, a->used, a->sign, size, (int)sizeof(fp_digit));
6380
6381
  mp_tohex(a, buffer);
6382
  printf("  %s\n  ", buffer);
6383
6384
  if (verbose) {
6385
    int i;
6386
    for(i=0; i<size * (int)sizeof(fp_digit); i++) {
6387
      printf("%x ", *(((byte*)a->dp) + i));
6388
    }
6389
    printf("\n");
6390
  }
6391
}
6392
#endif /* WOLFSSL_DEBUG_MATH */
6393
6394
#endif /* WC_MP_TO_RADIX */
6395
6396
6397
int mp_abs(mp_int* a, mp_int* b)
6398
{
6399
  fp_abs(a, b);
6400
  return FP_OKAY;
6401
}
6402
6403
6404
int mp_lshd (mp_int * a, int b)
6405
0
{
6406
0
  return fp_lshd(a, b);
6407
0
}
6408
6409
#ifdef WOLFSSL_CHECK_MEM_ZERO
6410
void mp_memzero_add(const char* name, mp_int* a)
6411
{
6412
    wc_MemZero_Add(name, a->dp, sizeof(a->dp));
6413
}
6414
6415
void mp_memzero_check(mp_int* a)
6416
{
6417
    wc_MemZero_Check(a->dp, sizeof(a->dp));
6418
}
6419
#endif /* WOLFSSL_CHECK_MEM_ZERO */
6420
6421
#endif /* USE_FAST_MATH */