LCOV - code coverage report
Current view: top level - os_stub/mbedtlslib/mbedtls/library - bignum.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 52.7 % 901 475
Test Date: 2025-06-29 08:09:00 Functions: 70.2 % 57 40

            Line data    Source code
       1              : /*
       2              :  *  Multi-precision integer library
       3              :  *
       4              :  *  Copyright The Mbed TLS Contributors
       5              :  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
       6              :  */
       7              : 
       8              : /*
       9              :  *  The following sources were referenced in the design of this Multi-precision
      10              :  *  Integer library:
      11              :  *
      12              :  *  [1] Handbook of Applied Cryptography - 1997
      13              :  *      Menezes, van Oorschot and Vanstone
      14              :  *
      15              :  *  [2] Multi-Precision Math
      16              :  *      Tom St Denis
      17              :  *      https://github.com/libtom/libtommath/blob/develop/tommath.pdf
      18              :  *
      19              :  *  [3] GNU Multi-Precision Arithmetic Library
      20              :  *      https://gmplib.org/manual/index.html
      21              :  *
      22              :  */
      23              : 
      24              : #include "common.h"
      25              : 
      26              : #if defined(MBEDTLS_BIGNUM_C)
      27              : 
      28              : #include "mbedtls/bignum.h"
      29              : #include "bignum_core.h"
      30              : #include "bignum_internal.h"
      31              : #include "bn_mul.h"
      32              : #include "mbedtls/platform_util.h"
      33              : #include "mbedtls/error.h"
      34              : #include "constant_time_internal.h"
      35              : 
      36              : #include <limits.h>
      37              : #include <string.h>
      38              : 
      39              : #include "mbedtls/platform.h"
      40              : 
      41              : 
      42              : 
      43              : /*
      44              :  * Conditionally select an MPI sign in constant time.
      45              :  * (MPI sign is the field s in mbedtls_mpi. It is unsigned short and only 1 and -1 are valid
      46              :  * values.)
      47              :  */
      48      4838708 : static inline signed short mbedtls_ct_mpi_sign_if(mbedtls_ct_condition_t cond,
      49              :                                                   signed short sign1, signed short sign2)
      50              : {
      51      4838708 :     return (signed short) mbedtls_ct_uint_if(cond, sign1 + 1, sign2 + 1) - 1;
      52              : }
      53              : 
      54              : /*
      55              :  * Compare signed values in constant time
      56              :  */
      57            0 : int mbedtls_mpi_lt_mpi_ct(const mbedtls_mpi *X,
      58              :                           const mbedtls_mpi *Y,
      59              :                           unsigned *ret)
      60              : {
      61              :     mbedtls_ct_condition_t different_sign, X_is_negative, Y_is_negative, result;
      62              : 
      63            0 :     if (X->n != Y->n) {
      64            0 :         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
      65              :     }
      66              : 
      67              :     /*
      68              :      * Set N_is_negative to MBEDTLS_CT_FALSE if N >= 0, MBEDTLS_CT_TRUE if N < 0.
      69              :      * We know that N->s == 1 if N >= 0 and N->s == -1 if N < 0.
      70              :      */
      71            0 :     X_is_negative = mbedtls_ct_bool((X->s & 2) >> 1);
      72            0 :     Y_is_negative = mbedtls_ct_bool((Y->s & 2) >> 1);
      73              : 
      74              :     /*
      75              :      * If the signs are different, then the positive operand is the bigger.
      76              :      * That is if X is negative (X_is_negative == 1), then X < Y is true and it
      77              :      * is false if X is positive (X_is_negative == 0).
      78              :      */
      79            0 :     different_sign = mbedtls_ct_bool_ne(X_is_negative, Y_is_negative); // true if different sign
      80            0 :     result = mbedtls_ct_bool_and(different_sign, X_is_negative);
      81              : 
      82              :     /*
      83              :      * Assuming signs are the same, compare X and Y. We switch the comparison
      84              :      * order if they are negative so that we get the right result, regardles of
      85              :      * sign.
      86              :      */
      87              : 
      88              :     /* This array is used to conditionally swap the pointers in const time */
      89            0 :     void * const p[2] = { X->p, Y->p };
      90            0 :     size_t i = mbedtls_ct_size_if_else_0(X_is_negative, 1);
      91            0 :     mbedtls_ct_condition_t lt = mbedtls_mpi_core_lt_ct(p[i], p[i ^ 1], X->n);
      92              : 
      93              :     /*
      94              :      * Store in result iff the signs are the same (i.e., iff different_sign == false). If
      95              :      * the signs differ, result has already been set, so we don't change it.
      96              :      */
      97            0 :     result = mbedtls_ct_bool_or(result,
      98              :                                 mbedtls_ct_bool_and(mbedtls_ct_bool_not(different_sign), lt));
      99              : 
     100            0 :     *ret = mbedtls_ct_uint_if_else_0(result, 1);
     101              : 
     102            0 :     return 0;
     103              : }
     104              : 
     105              : /*
     106              :  * Conditionally assign X = Y, without leaking information
     107              :  * about whether the assignment was made or not.
     108              :  * (Leaking information about the respective sizes of X and Y is ok however.)
     109              :  */
     110              : #if defined(_MSC_VER) && defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64) && \
     111              :     (_MSC_FULL_VER < 193131103)
     112              : /*
     113              :  * MSVC miscompiles this function if it's inlined prior to Visual Studio 2022 version 17.1. See:
     114              :  * https://developercommunity.visualstudio.com/t/c-compiler-miscompiles-part-of-mbedtls-library-on/1646989
     115              :  */
     116              : __declspec(noinline)
     117              : #endif
     118      4838708 : int mbedtls_mpi_safe_cond_assign(mbedtls_mpi *X,
     119              :                                  const mbedtls_mpi *Y,
     120              :                                  unsigned char assign)
     121              : {
     122      4838708 :     int ret = 0;
     123              : 
     124      4838708 :     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, Y->n));
     125              : 
     126              :     {
     127      4838708 :         mbedtls_ct_condition_t do_assign = mbedtls_ct_bool(assign);
     128              : 
     129      4838708 :         X->s = mbedtls_ct_mpi_sign_if(do_assign, Y->s, X->s);
     130              : 
     131      4838708 :         mbedtls_mpi_core_cond_assign(X->p, Y->p, Y->n, do_assign);
     132              : 
     133      4838708 :         mbedtls_ct_condition_t do_not_assign = mbedtls_ct_bool_not(do_assign);
     134      4855368 :         for (size_t i = Y->n; i < X->n; i++) {
     135        16660 :             X->p[i] = mbedtls_ct_mpi_uint_if_else_0(do_not_assign, X->p[i]);
     136              :         }
     137              :     }
     138              : 
     139      4838708 : cleanup:
     140      4838708 :     return ret;
     141              : }
     142              : 
     143              : /*
     144              :  * Conditionally swap X and Y, without leaking information
     145              :  * about whether the swap was made or not.
     146              :  * Here it is not ok to simply swap the pointers, which would lead to
     147              :  * different memory access patterns when X and Y are used afterwards.
     148              :  */
     149            0 : int mbedtls_mpi_safe_cond_swap(mbedtls_mpi *X,
     150              :                                mbedtls_mpi *Y,
     151              :                                unsigned char swap)
     152              : {
     153            0 :     int ret = 0;
     154              :     int s;
     155              : 
     156            0 :     if (X == Y) {
     157            0 :         return 0;
     158              :     }
     159              : 
     160            0 :     mbedtls_ct_condition_t do_swap = mbedtls_ct_bool(swap);
     161              : 
     162            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, Y->n));
     163            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(Y, X->n));
     164              : 
     165            0 :     s = X->s;
     166            0 :     X->s = mbedtls_ct_mpi_sign_if(do_swap, Y->s, X->s);
     167            0 :     Y->s = mbedtls_ct_mpi_sign_if(do_swap, s, Y->s);
     168              : 
     169            0 :     mbedtls_mpi_core_cond_swap(X->p, Y->p, X->n, do_swap);
     170              : 
     171            0 : cleanup:
     172            0 :     return ret;
     173              : }
     174              : 
     175              : /* Implementation that should never be optimized out by the compiler */
     176              : #define mbedtls_mpi_zeroize_and_free(v, n) mbedtls_zeroize_and_free(v, ciL * (n))
     177              : 
     178              : /*
     179              :  * Initialize one MPI
     180              :  */
     181     13417917 : void mbedtls_mpi_init(mbedtls_mpi *X)
     182              : {
     183     13417917 :     X->s = 1;
     184     13417917 :     X->n = 0;
     185     13417917 :     X->p = NULL;
     186     13417917 : }
     187              : 
     188              : /*
     189              :  * Unallocate one MPI
     190              :  */
     191     13342304 : void mbedtls_mpi_free(mbedtls_mpi *X)
     192              : {
     193     13342304 :     if (X == NULL) {
     194            0 :         return;
     195              :     }
     196              : 
     197     13342304 :     if (X->p != NULL) {
     198      2337787 :         mbedtls_mpi_zeroize_and_free(X->p, X->n);
     199              :     }
     200              : 
     201     13342304 :     X->s = 1;
     202     13342304 :     X->n = 0;
     203     13342304 :     X->p = NULL;
     204              : }
     205              : 
     206              : /*
     207              :  * Enlarge to the specified number of limbs
     208              :  */
     209     51292373 : int mbedtls_mpi_grow(mbedtls_mpi *X, size_t nblimbs)
     210              : {
     211              :     mbedtls_mpi_uint *p;
     212              : 
     213     51292373 :     if (nblimbs > MBEDTLS_MPI_MAX_LIMBS) {
     214            0 :         return MBEDTLS_ERR_MPI_ALLOC_FAILED;
     215              :     }
     216              : 
     217     51292373 :     if (X->n < nblimbs) {
     218      2595379 :         if ((p = (mbedtls_mpi_uint *) mbedtls_calloc(nblimbs, ciL)) == NULL) {
     219            0 :             return MBEDTLS_ERR_MPI_ALLOC_FAILED;
     220              :         }
     221              : 
     222      2595379 :         if (X->p != NULL) {
     223       256819 :             memcpy(p, X->p, X->n * ciL);
     224       256819 :             mbedtls_mpi_zeroize_and_free(X->p, X->n);
     225              :         }
     226              : 
     227              :         /* nblimbs fits in n because we ensure that MBEDTLS_MPI_MAX_LIMBS
     228              :          * fits, and we've checked that nblimbs <= MBEDTLS_MPI_MAX_LIMBS. */
     229      2595379 :         X->n = (unsigned short) nblimbs;
     230      2595379 :         X->p = p;
     231              :     }
     232              : 
     233     51292373 :     return 0;
     234              : }
     235              : 
     236              : /*
     237              :  * Resize down as much as possible,
     238              :  * while keeping at least the specified number of limbs
     239              :  */
     240        31373 : int mbedtls_mpi_shrink(mbedtls_mpi *X, size_t nblimbs)
     241              : {
     242              :     mbedtls_mpi_uint *p;
     243              :     size_t i;
     244              : 
     245        31373 :     if (nblimbs > MBEDTLS_MPI_MAX_LIMBS) {
     246            0 :         return MBEDTLS_ERR_MPI_ALLOC_FAILED;
     247              :     }
     248              : 
     249              :     /* Actually resize up if there are currently fewer than nblimbs limbs. */
     250        31373 :     if (X->n <= nblimbs) {
     251            0 :         return mbedtls_mpi_grow(X, nblimbs);
     252              :     }
     253              :     /* After this point, then X->n > nblimbs and in particular X->n > 0. */
     254              : 
     255       208500 :     for (i = X->n - 1; i > 0; i--) {
     256       208500 :         if (X->p[i] != 0) {
     257        31373 :             break;
     258              :         }
     259              :     }
     260        31373 :     i++;
     261              : 
     262        31373 :     if (i < nblimbs) {
     263          279 :         i = nblimbs;
     264              :     }
     265              : 
     266        31373 :     if ((p = (mbedtls_mpi_uint *) mbedtls_calloc(i, ciL)) == NULL) {
     267            0 :         return MBEDTLS_ERR_MPI_ALLOC_FAILED;
     268              :     }
     269              : 
     270        31373 :     if (X->p != NULL) {
     271        31373 :         memcpy(p, X->p, i * ciL);
     272        31373 :         mbedtls_mpi_zeroize_and_free(X->p, X->n);
     273              :     }
     274              : 
     275              :     /* i fits in n because we ensure that MBEDTLS_MPI_MAX_LIMBS
     276              :      * fits, and we've checked that i <= nblimbs <= MBEDTLS_MPI_MAX_LIMBS. */
     277        31373 :     X->n = (unsigned short) i;
     278        31373 :     X->p = p;
     279              : 
     280        31373 :     return 0;
     281              : }
     282              : 
     283              : /* Resize X to have exactly n limbs and set it to 0. */
     284        32875 : static int mbedtls_mpi_resize_clear(mbedtls_mpi *X, size_t limbs)
     285              : {
     286        32875 :     if (limbs == 0) {
     287            0 :         mbedtls_mpi_free(X);
     288            0 :         return 0;
     289        32875 :     } else if (X->n == limbs) {
     290          110 :         memset(X->p, 0, limbs * ciL);
     291          110 :         X->s = 1;
     292          110 :         return 0;
     293              :     } else {
     294        32765 :         mbedtls_mpi_free(X);
     295        32765 :         return mbedtls_mpi_grow(X, limbs);
     296              :     }
     297              : }
     298              : 
     299              : /*
     300              :  * Copy the contents of Y into X.
     301              :  *
     302              :  * This function is not constant-time. Leading zeros in Y may be removed.
     303              :  *
     304              :  * Ensure that X does not shrink. This is not guaranteed by the public API,
     305              :  * but some code in the bignum module might still rely on this property.
     306              :  */
     307      4708727 : int mbedtls_mpi_copy(mbedtls_mpi *X, const mbedtls_mpi *Y)
     308              : {
     309      4708727 :     int ret = 0;
     310              :     size_t i;
     311              : 
     312      4708727 :     if (X == Y) {
     313        74012 :         return 0;
     314              :     }
     315              : 
     316      4634715 :     if (Y->n == 0) {
     317         2231 :         if (X->n != 0) {
     318            0 :             X->s = 1;
     319            0 :             memset(X->p, 0, X->n * ciL);
     320              :         }
     321         2231 :         return 0;
     322              :     }
     323              : 
     324     27078096 :     for (i = Y->n - 1; i > 0; i--) {
     325     27051581 :         if (Y->p[i] != 0) {
     326      4605969 :             break;
     327              :         }
     328              :     }
     329      4632484 :     i++;
     330              : 
     331      4632484 :     X->s = Y->s;
     332              : 
     333      4632484 :     if (X->n < i) {
     334      1942415 :         MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, i));
     335              :     } else {
     336      2690069 :         memset(X->p + i, 0, (X->n - i) * ciL);
     337              :     }
     338              : 
     339      4632484 :     memcpy(X->p, Y->p, i * ciL);
     340              : 
     341      4632484 : cleanup:
     342              : 
     343      4632484 :     return ret;
     344              : }
     345              : 
     346              : /*
     347              :  * Swap the contents of X and Y
     348              :  */
     349            0 : void mbedtls_mpi_swap(mbedtls_mpi *X, mbedtls_mpi *Y)
     350              : {
     351              :     mbedtls_mpi T;
     352              : 
     353            0 :     memcpy(&T,  X, sizeof(mbedtls_mpi));
     354            0 :     memcpy(X,  Y, sizeof(mbedtls_mpi));
     355            0 :     memcpy(Y, &T, sizeof(mbedtls_mpi));
     356            0 : }
     357              : 
     358     18428175 : static inline mbedtls_mpi_uint mpi_sint_abs(mbedtls_mpi_sint z)
     359              : {
     360     18428175 :     if (z >= 0) {
     361     18425233 :         return z;
     362              :     }
     363              :     /* Take care to handle the most negative value (-2^(biL-1)) correctly.
     364              :      * A naive -z would have undefined behavior.
     365              :      * Write this in a way that makes popular compilers happy (GCC, Clang,
     366              :      * MSVC). */
     367         2942 :     return (mbedtls_mpi_uint) 0 - (mbedtls_mpi_uint) z;
     368              : }
     369              : 
     370              : /* Convert x to a sign, i.e. to 1, if x is positive, or -1, if x is negative.
     371              :  * This looks awkward but generates smaller code than (x < 0 ? -1 : 1) */
     372              : #define TO_SIGN(x) ((mbedtls_mpi_sint) (((mbedtls_mpi_uint) x) >> (biL - 1)) * -2 + 1)
     373              : 
     374              : /*
     375              :  * Set value from integer
     376              :  */
     377      6667076 : int mbedtls_mpi_lset(mbedtls_mpi *X, mbedtls_mpi_sint z)
     378              : {
     379      6667076 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     380              : 
     381      6667076 :     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, 1));
     382      6667076 :     memset(X->p, 0, X->n * ciL);
     383              : 
     384      6667076 :     X->p[0] = mpi_sint_abs(z);
     385      6667076 :     X->s    = TO_SIGN(z);
     386              : 
     387      6667076 : cleanup:
     388              : 
     389      6667076 :     return ret;
     390              : }
     391              : 
     392              : /*
     393              :  * Get a specific bit
     394              :  */
     395       881106 : int mbedtls_mpi_get_bit(const mbedtls_mpi *X, size_t pos)
     396              : {
     397       881106 :     if (X->n * biL <= pos) {
     398         7144 :         return 0;
     399              :     }
     400              : 
     401       873962 :     return (X->p[pos / biL] >> (pos % biL)) & 0x01;
     402              : }
     403              : 
     404              : /*
     405              :  * Set a bit to a specific value of 0 or 1
     406              :  */
     407            0 : int mbedtls_mpi_set_bit(mbedtls_mpi *X, size_t pos, unsigned char val)
     408              : {
     409            0 :     int ret = 0;
     410            0 :     size_t off = pos / biL;
     411            0 :     size_t idx = pos % biL;
     412              : 
     413            0 :     if (val != 0 && val != 1) {
     414            0 :         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
     415              :     }
     416              : 
     417            0 :     if (X->n * biL <= pos) {
     418            0 :         if (val == 0) {
     419            0 :             return 0;
     420              :         }
     421              : 
     422            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, off + 1));
     423              :     }
     424              : 
     425            0 :     X->p[off] &= ~((mbedtls_mpi_uint) 0x01 << idx);
     426            0 :     X->p[off] |= (mbedtls_mpi_uint) val << idx;
     427              : 
     428            0 : cleanup:
     429              : 
     430            0 :     return ret;
     431              : }
     432              : 
     433              : /*
     434              :  * Return the number of less significant zero-bits
     435              :  */
     436      3578754 : size_t mbedtls_mpi_lsb(const mbedtls_mpi *X)
     437              : {
     438              :     size_t i;
     439              : 
     440              : #if defined(__has_builtin)
     441              : #if (MBEDTLS_MPI_UINT_MAX == UINT_MAX) && __has_builtin(__builtin_ctz)
     442              :     #define mbedtls_mpi_uint_ctz __builtin_ctz
     443              : #elif (MBEDTLS_MPI_UINT_MAX == ULONG_MAX) && __has_builtin(__builtin_ctzl)
     444              :     #define mbedtls_mpi_uint_ctz __builtin_ctzl
     445              : #elif (MBEDTLS_MPI_UINT_MAX == ULLONG_MAX) && __has_builtin(__builtin_ctzll)
     446              :     #define mbedtls_mpi_uint_ctz __builtin_ctzll
     447              : #endif
     448              : #endif
     449              : 
     450              : #if defined(mbedtls_mpi_uint_ctz)
     451      3578754 :     for (i = 0; i < X->n; i++) {
     452      3578754 :         if (X->p[i] != 0) {
     453      3578754 :             return i * biL + mbedtls_mpi_uint_ctz(X->p[i]);
     454              :         }
     455              :     }
     456              : #else
     457              :     size_t count = 0;
     458              :     for (i = 0; i < X->n; i++) {
     459              :         for (size_t j = 0; j < biL; j++, count++) {
     460              :             if (((X->p[i] >> j) & 1) != 0) {
     461              :                 return count;
     462              :             }
     463              :         }
     464              :     }
     465              : #endif
     466              : 
     467            0 :     return 0;
     468              : }
     469              : 
     470              : /*
     471              :  * Return the number of bits
     472              :  */
     473      8594847 : size_t mbedtls_mpi_bitlen(const mbedtls_mpi *X)
     474              : {
     475      8594847 :     return mbedtls_mpi_core_bitlen(X->p, X->n);
     476              : }
     477              : 
     478              : /*
     479              :  * Return the total size in bytes
     480              :  */
     481        16890 : size_t mbedtls_mpi_size(const mbedtls_mpi *X)
     482              : {
     483        16890 :     return (mbedtls_mpi_bitlen(X) + 7) >> 3;
     484              : }
     485              : 
     486              : /*
     487              :  * Convert an ASCII character to digit value
     488              :  */
     489            0 : static int mpi_get_digit(mbedtls_mpi_uint *d, int radix, char c)
     490              : {
     491            0 :     *d = 255;
     492              : 
     493            0 :     if (c >= 0x30 && c <= 0x39) {
     494            0 :         *d = c - 0x30;
     495              :     }
     496            0 :     if (c >= 0x41 && c <= 0x46) {
     497            0 :         *d = c - 0x37;
     498              :     }
     499            0 :     if (c >= 0x61 && c <= 0x66) {
     500            0 :         *d = c - 0x57;
     501              :     }
     502              : 
     503            0 :     if (*d >= (mbedtls_mpi_uint) radix) {
     504            0 :         return MBEDTLS_ERR_MPI_INVALID_CHARACTER;
     505              :     }
     506              : 
     507            0 :     return 0;
     508              : }
     509              : 
     510              : /*
     511              :  * Import from an ASCII string
     512              :  */
     513            0 : int mbedtls_mpi_read_string(mbedtls_mpi *X, int radix, const char *s)
     514              : {
     515            0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     516              :     size_t i, j, slen, n;
     517            0 :     int sign = 1;
     518              :     mbedtls_mpi_uint d;
     519              :     mbedtls_mpi T;
     520              : 
     521            0 :     if (radix < 2 || radix > 16) {
     522            0 :         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
     523              :     }
     524              : 
     525            0 :     mbedtls_mpi_init(&T);
     526              : 
     527            0 :     if (s[0] == 0) {
     528            0 :         mbedtls_mpi_free(X);
     529            0 :         return 0;
     530              :     }
     531              : 
     532            0 :     if (s[0] == '-') {
     533            0 :         ++s;
     534            0 :         sign = -1;
     535              :     }
     536              : 
     537            0 :     slen = strlen(s);
     538              : 
     539            0 :     if (radix == 16) {
     540            0 :         if (slen > SIZE_MAX >> 2) {
     541            0 :             return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
     542              :         }
     543              : 
     544            0 :         n = BITS_TO_LIMBS(slen << 2);
     545              : 
     546            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, n));
     547            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 0));
     548              : 
     549            0 :         for (i = slen, j = 0; i > 0; i--, j++) {
     550            0 :             MBEDTLS_MPI_CHK(mpi_get_digit(&d, radix, s[i - 1]));
     551            0 :             X->p[j / (2 * ciL)] |= d << ((j % (2 * ciL)) << 2);
     552              :         }
     553              :     } else {
     554            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 0));
     555              : 
     556            0 :         for (i = 0; i < slen; i++) {
     557            0 :             MBEDTLS_MPI_CHK(mpi_get_digit(&d, radix, s[i]));
     558            0 :             MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(&T, X, radix));
     559            0 :             MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, &T, d));
     560              :         }
     561              :     }
     562              : 
     563            0 :     if (sign < 0 && mbedtls_mpi_bitlen(X) != 0) {
     564            0 :         X->s = -1;
     565              :     }
     566              : 
     567            0 : cleanup:
     568              : 
     569            0 :     mbedtls_mpi_free(&T);
     570              : 
     571            0 :     return ret;
     572              : }
     573              : 
     574              : /*
     575              :  * Helper to write the digits high-order first.
     576              :  */
     577            0 : static int mpi_write_hlp(mbedtls_mpi *X, int radix,
     578              :                          char **p, const size_t buflen)
     579              : {
     580            0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     581              :     mbedtls_mpi_uint r;
     582            0 :     size_t length = 0;
     583            0 :     char *p_end = *p + buflen;
     584              : 
     585              :     do {
     586            0 :         if (length >= buflen) {
     587            0 :             return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL;
     588              :         }
     589              : 
     590            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_mod_int(&r, X, radix));
     591            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_div_int(X, NULL, X, radix));
     592              :         /*
     593              :          * Write the residue in the current position, as an ASCII character.
     594              :          */
     595            0 :         if (r < 0xA) {
     596            0 :             *(--p_end) = (char) ('0' + r);
     597              :         } else {
     598            0 :             *(--p_end) = (char) ('A' + (r - 0xA));
     599              :         }
     600              : 
     601            0 :         length++;
     602            0 :     } while (mbedtls_mpi_cmp_int(X, 0) != 0);
     603              : 
     604            0 :     memmove(*p, p_end, length);
     605            0 :     *p += length;
     606              : 
     607            0 : cleanup:
     608              : 
     609            0 :     return ret;
     610              : }
     611              : 
     612              : /*
     613              :  * Export into an ASCII string
     614              :  */
     615            0 : int mbedtls_mpi_write_string(const mbedtls_mpi *X, int radix,
     616              :                              char *buf, size_t buflen, size_t *olen)
     617              : {
     618            0 :     int ret = 0;
     619              :     size_t n;
     620              :     char *p;
     621              :     mbedtls_mpi T;
     622              : 
     623            0 :     if (radix < 2 || radix > 16) {
     624            0 :         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
     625              :     }
     626              : 
     627            0 :     n = mbedtls_mpi_bitlen(X);   /* Number of bits necessary to present `n`. */
     628            0 :     if (radix >=  4) {
     629            0 :         n >>= 1;                 /* Number of 4-adic digits necessary to present
     630              :                                   * `n`. If radix > 4, this might be a strict
     631              :                                   * overapproximation of the number of
     632              :                                   * radix-adic digits needed to present `n`. */
     633              :     }
     634            0 :     if (radix >= 16) {
     635            0 :         n >>= 1;                 /* Number of hexadecimal digits necessary to
     636              :                                   * present `n`. */
     637              : 
     638              :     }
     639            0 :     n += 1; /* Terminating null byte */
     640            0 :     n += 1; /* Compensate for the divisions above, which round down `n`
     641              :              * in case it's not even. */
     642            0 :     n += 1; /* Potential '-'-sign. */
     643            0 :     n += (n & 1);   /* Make n even to have enough space for hexadecimal writing,
     644              :                      * which always uses an even number of hex-digits. */
     645              : 
     646            0 :     if (buflen < n) {
     647            0 :         *olen = n;
     648            0 :         return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL;
     649              :     }
     650              : 
     651            0 :     p = buf;
     652            0 :     mbedtls_mpi_init(&T);
     653              : 
     654            0 :     if (X->s == -1) {
     655            0 :         *p++ = '-';
     656            0 :         buflen--;
     657              :     }
     658              : 
     659            0 :     if (radix == 16) {
     660              :         int c;
     661              :         size_t i, j, k;
     662              : 
     663            0 :         for (i = X->n, k = 0; i > 0; i--) {
     664            0 :             for (j = ciL; j > 0; j--) {
     665            0 :                 c = (X->p[i - 1] >> ((j - 1) << 3)) & 0xFF;
     666              : 
     667            0 :                 if (c == 0 && k == 0 && (i + j) != 2) {
     668            0 :                     continue;
     669              :                 }
     670              : 
     671            0 :                 *(p++) = "0123456789ABCDEF" [c / 16];
     672            0 :                 *(p++) = "0123456789ABCDEF" [c % 16];
     673            0 :                 k = 1;
     674              :             }
     675              :         }
     676              :     } else {
     677            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&T, X));
     678              : 
     679            0 :         if (T.s == -1) {
     680            0 :             T.s = 1;
     681              :         }
     682              : 
     683            0 :         MBEDTLS_MPI_CHK(mpi_write_hlp(&T, radix, &p, buflen));
     684              :     }
     685              : 
     686            0 :     *p++ = '\0';
     687            0 :     *olen = (size_t) (p - buf);
     688              : 
     689            0 : cleanup:
     690              : 
     691            0 :     mbedtls_mpi_free(&T);
     692              : 
     693            0 :     return ret;
     694              : }
     695              : 
     696              : #if defined(MBEDTLS_FS_IO)
     697              : /*
     698              :  * Read X from an opened file
     699              :  */
     700              : int mbedtls_mpi_read_file(mbedtls_mpi *X, int radix, FILE *fin)
     701              : {
     702              :     mbedtls_mpi_uint d;
     703              :     size_t slen;
     704              :     char *p;
     705              :     /*
     706              :      * Buffer should have space for (short) label and decimal formatted MPI,
     707              :      * newline characters and '\0'
     708              :      */
     709              :     char s[MBEDTLS_MPI_RW_BUFFER_SIZE];
     710              : 
     711              :     if (radix < 2 || radix > 16) {
     712              :         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
     713              :     }
     714              : 
     715              :     memset(s, 0, sizeof(s));
     716              :     if (fgets(s, sizeof(s) - 1, fin) == NULL) {
     717              :         return MBEDTLS_ERR_MPI_FILE_IO_ERROR;
     718              :     }
     719              : 
     720              :     slen = strlen(s);
     721              :     if (slen == sizeof(s) - 2) {
     722              :         return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL;
     723              :     }
     724              : 
     725              :     if (slen > 0 && s[slen - 1] == '\n') {
     726              :         slen--; s[slen] = '\0';
     727              :     }
     728              :     if (slen > 0 && s[slen - 1] == '\r') {
     729              :         slen--; s[slen] = '\0';
     730              :     }
     731              : 
     732              :     p = s + slen;
     733              :     while (p-- > s) {
     734              :         if (mpi_get_digit(&d, radix, *p) != 0) {
     735              :             break;
     736              :         }
     737              :     }
     738              : 
     739              :     return mbedtls_mpi_read_string(X, radix, p + 1);
     740              : }
     741              : 
     742              : /*
     743              :  * Write X into an opened file (or stdout if fout == NULL)
     744              :  */
     745              : int mbedtls_mpi_write_file(const char *p, const mbedtls_mpi *X, int radix, FILE *fout)
     746              : {
     747              :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     748              :     size_t n, slen, plen;
     749              :     /*
     750              :      * Buffer should have space for (short) label and decimal formatted MPI,
     751              :      * newline characters and '\0'
     752              :      */
     753              :     char s[MBEDTLS_MPI_RW_BUFFER_SIZE];
     754              : 
     755              :     if (radix < 2 || radix > 16) {
     756              :         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
     757              :     }
     758              : 
     759              :     memset(s, 0, sizeof(s));
     760              : 
     761              :     MBEDTLS_MPI_CHK(mbedtls_mpi_write_string(X, radix, s, sizeof(s) - 2, &n));
     762              : 
     763              :     if (p == NULL) {
     764              :         p = "";
     765              :     }
     766              : 
     767              :     plen = strlen(p);
     768              :     slen = strlen(s);
     769              :     s[slen++] = '\r';
     770              :     s[slen++] = '\n';
     771              : 
     772              :     if (fout != NULL) {
     773              :         if (fwrite(p, 1, plen, fout) != plen ||
     774              :             fwrite(s, 1, slen, fout) != slen) {
     775              :             return MBEDTLS_ERR_MPI_FILE_IO_ERROR;
     776              :         }
     777              :     } else {
     778              :         mbedtls_printf("%s%s", p, s);
     779              :     }
     780              : 
     781              : cleanup:
     782              : 
     783              :     return ret;
     784              : }
     785              : #endif /* MBEDTLS_FS_IO */
     786              : 
     787              : /*
     788              :  * Import X from unsigned binary data, little endian
     789              :  *
     790              :  * This function is guaranteed to return an MPI with exactly the necessary
     791              :  * number of limbs (in particular, it does not skip 0s in the input).
     792              :  */
     793            0 : int mbedtls_mpi_read_binary_le(mbedtls_mpi *X,
     794              :                                const unsigned char *buf, size_t buflen)
     795              : {
     796            0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     797            0 :     const size_t limbs = CHARS_TO_LIMBS(buflen);
     798              : 
     799              :     /* Ensure that target MPI has exactly the necessary number of limbs */
     800            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_resize_clear(X, limbs));
     801              : 
     802            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_core_read_le(X->p, X->n, buf, buflen));
     803              : 
     804            0 : cleanup:
     805              : 
     806              :     /*
     807              :      * This function is also used to import keys. However, wiping the buffers
     808              :      * upon failure is not necessary because failure only can happen before any
     809              :      * input is copied.
     810              :      */
     811            0 :     return ret;
     812              : }
     813              : 
     814              : /*
     815              :  * Import X from unsigned binary data, big endian
     816              :  *
     817              :  * This function is guaranteed to return an MPI with exactly the necessary
     818              :  * number of limbs (in particular, it does not skip 0s in the input).
     819              :  */
     820        31479 : int mbedtls_mpi_read_binary(mbedtls_mpi *X, const unsigned char *buf, size_t buflen)
     821              : {
     822        31479 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     823        31479 :     const size_t limbs = CHARS_TO_LIMBS(buflen);
     824              : 
     825              :     /* Ensure that target MPI has exactly the necessary number of limbs */
     826        31479 :     MBEDTLS_MPI_CHK(mbedtls_mpi_resize_clear(X, limbs));
     827              : 
     828        31479 :     MBEDTLS_MPI_CHK(mbedtls_mpi_core_read_be(X->p, X->n, buf, buflen));
     829              : 
     830        31479 : cleanup:
     831              : 
     832              :     /*
     833              :      * This function is also used to import keys. However, wiping the buffers
     834              :      * upon failure is not necessary because failure only can happen before any
     835              :      * input is copied.
     836              :      */
     837        31479 :     return ret;
     838              : }
     839              : 
     840              : /*
     841              :  * Export X into unsigned binary data, little endian
     842              :  */
     843            0 : int mbedtls_mpi_write_binary_le(const mbedtls_mpi *X,
     844              :                                 unsigned char *buf, size_t buflen)
     845              : {
     846            0 :     return mbedtls_mpi_core_write_le(X->p, X->n, buf, buflen);
     847              : }
     848              : 
     849              : /*
     850              :  * Export X into unsigned binary data, big endian
     851              :  */
     852         1117 : int mbedtls_mpi_write_binary(const mbedtls_mpi *X,
     853              :                              unsigned char *buf, size_t buflen)
     854              : {
     855         1117 :     return mbedtls_mpi_core_write_be(X->p, X->n, buf, buflen);
     856              : }
     857              : 
     858              : /*
     859              :  * Left-shift: X <<= count
     860              :  */
     861      2222245 : int mbedtls_mpi_shift_l(mbedtls_mpi *X, size_t count)
     862              : {
     863      2222245 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     864              :     size_t i;
     865              : 
     866      2222245 :     i = mbedtls_mpi_bitlen(X) + count;
     867              : 
     868      2222245 :     if (X->n * biL < i) {
     869        11771 :         MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, BITS_TO_LIMBS(i)));
     870              :     }
     871              : 
     872      2222245 :     ret = 0;
     873              : 
     874      2222245 :     mbedtls_mpi_core_shift_l(X->p, X->n, count);
     875      2222245 : cleanup:
     876              : 
     877      2222245 :     return ret;
     878              : }
     879              : 
     880              : /*
     881              :  * Right-shift: X >>= count
     882              :  */
     883     15953901 : int mbedtls_mpi_shift_r(mbedtls_mpi *X, size_t count)
     884              : {
     885     15953901 :     if (X->n != 0) {
     886     15953901 :         mbedtls_mpi_core_shift_r(X->p, X->n, count);
     887              :     }
     888     15953901 :     return 0;
     889              : }
     890              : 
     891              : /*
     892              :  * Compare unsigned values
     893              :  */
     894     15863705 : int mbedtls_mpi_cmp_abs(const mbedtls_mpi *X, const mbedtls_mpi *Y)
     895              : {
     896              :     size_t i, j;
     897              : 
     898     72836288 :     for (i = X->n; i > 0; i--) {
     899     72821314 :         if (X->p[i - 1] != 0) {
     900     15848731 :             break;
     901              :         }
     902              :     }
     903              : 
     904     40122830 :     for (j = Y->n; j > 0; j--) {
     905     40118696 :         if (Y->p[j - 1] != 0) {
     906     15859571 :             break;
     907              :         }
     908              :     }
     909              : 
     910              :     /* If i == j == 0, i.e. abs(X) == abs(Y),
     911              :      * we end up returning 0 at the end of the function. */
     912              : 
     913     15863705 :     if (i > j) {
     914      1611511 :         return 1;
     915              :     }
     916     14252194 :     if (j > i) {
     917        28287 :         return -1;
     918              :     }
     919              : 
     920     14323555 :     for (; i > 0; i--) {
     921     14301430 :         if (X->p[i - 1] > Y->p[i - 1]) {
     922      4794319 :             return 1;
     923              :         }
     924      9507111 :         if (X->p[i - 1] < Y->p[i - 1]) {
     925      9407463 :             return -1;
     926              :         }
     927              :     }
     928              : 
     929        22125 :     return 0;
     930              : }
     931              : 
     932              : /*
     933              :  * Compare signed values
     934              :  */
     935     27864749 : int mbedtls_mpi_cmp_mpi(const mbedtls_mpi *X, const mbedtls_mpi *Y)
     936              : {
     937              :     size_t i, j;
     938              : 
     939    140090547 :     for (i = X->n; i > 0; i--) {
     940    140063390 :         if (X->p[i - 1] != 0) {
     941     27837592 :             break;
     942              :         }
     943              :     }
     944              : 
     945     46434057 :     for (j = Y->n; j > 0; j--) {
     946     34939936 :         if (Y->p[j - 1] != 0) {
     947     16370628 :             break;
     948              :         }
     949              :     }
     950              : 
     951     27864749 :     if (i == 0 && j == 0) {
     952        27150 :         return 0;
     953              :     }
     954              : 
     955     27837599 :     if (i > j) {
     956     14467934 :         return X->s;
     957              :     }
     958     13369665 :     if (j > i) {
     959        72611 :         return -Y->s;
     960              :     }
     961              : 
     962     13297054 :     if (X->s > 0 && Y->s < 0) {
     963            0 :         return 1;
     964              :     }
     965     13297054 :     if (Y->s > 0 && X->s < 0) {
     966            0 :         return -1;
     967              :     }
     968              : 
     969     13692739 :     for (; i > 0; i--) {
     970     13424936 :         if (X->p[i - 1] > Y->p[i - 1]) {
     971      1775968 :             return X->s;
     972              :         }
     973     11648968 :         if (X->p[i - 1] < Y->p[i - 1]) {
     974     11253283 :             return -X->s;
     975              :         }
     976              :     }
     977              : 
     978       267803 :     return 0;
     979              : }
     980              : 
     981              : /*
     982              :  * Compare signed values
     983              :  */
     984     11746027 : int mbedtls_mpi_cmp_int(const mbedtls_mpi *X, mbedtls_mpi_sint z)
     985              : {
     986              :     mbedtls_mpi Y;
     987              :     mbedtls_mpi_uint p[1];
     988              : 
     989     11746027 :     *p  = mpi_sint_abs(z);
     990     11746027 :     Y.s = TO_SIGN(z);
     991     11746027 :     Y.n = 1;
     992     11746027 :     Y.p = p;
     993              : 
     994     11746027 :     return mbedtls_mpi_cmp_mpi(X, &Y);
     995              : }
     996              : 
     997              : /*
     998              :  * Unsigned addition: X = |A| + |B|  (HAC 14.7)
     999              :  */
    1000      3969205 : int mbedtls_mpi_add_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
    1001              : {
    1002      3969205 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1003              :     size_t j;
    1004              :     mbedtls_mpi_uint *p;
    1005              :     mbedtls_mpi_uint c;
    1006              : 
    1007      3969205 :     if (X == B) {
    1008            0 :         const mbedtls_mpi *T = A; A = X; B = T;
    1009              :     }
    1010              : 
    1011      3969205 :     if (X != A) {
    1012       488686 :         MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A));
    1013              :     }
    1014              : 
    1015              :     /*
    1016              :      * X must always be positive as a result of unsigned additions.
    1017              :      */
    1018      3969205 :     X->s = 1;
    1019              : 
    1020      7246767 :     for (j = B->n; j > 0; j--) {
    1021      7245855 :         if (B->p[j - 1] != 0) {
    1022      3968293 :             break;
    1023              :         }
    1024              :     }
    1025              : 
    1026              :     /* Exit early to avoid undefined behavior on NULL+0 when X->n == 0
    1027              :      * and B is 0 (of any size). */
    1028      3969205 :     if (j == 0) {
    1029          912 :         return 0;
    1030              :     }
    1031              : 
    1032      3968293 :     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, j));
    1033              : 
    1034              :     /* j is the number of non-zero limbs of B. Add those to X. */
    1035              : 
    1036      3968293 :     p = X->p;
    1037              : 
    1038      3968293 :     c = mbedtls_mpi_core_add(p, p, B->p, j);
    1039              : 
    1040      3968293 :     p += j;
    1041              : 
    1042              :     /* Now propagate any carry */
    1043              : 
    1044      5691531 :     while (c != 0) {
    1045      1723238 :         if (j >= X->n) {
    1046        18260 :             MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, j + 1));
    1047        18260 :             p = X->p + j;
    1048              :         }
    1049              : 
    1050      1723238 :         *p += c; c = (*p < c); j++; p++;
    1051              :     }
    1052              : 
    1053      3968293 : cleanup:
    1054              : 
    1055      3968293 :     return ret;
    1056              : }
    1057              : 
    1058              : /*
    1059              :  * Unsigned subtraction: X = |A| - |B|  (HAC 14.9, 14.10)
    1060              :  */
    1061     20555435 : int mbedtls_mpi_sub_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
    1062              : {
    1063     20555435 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1064              :     size_t n;
    1065              :     mbedtls_mpi_uint carry;
    1066              : 
    1067     75820318 :     for (n = B->n; n > 0; n--) {
    1068     75801210 :         if (B->p[n - 1] != 0) {
    1069     20536327 :             break;
    1070              :         }
    1071              :     }
    1072     20555435 :     if (n > A->n) {
    1073              :         /* B >= (2^ciL)^n > A */
    1074            0 :         ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
    1075            0 :         goto cleanup;
    1076              :     }
    1077              : 
    1078     20555435 :     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, A->n));
    1079              : 
    1080              :     /* Set the high limbs of X to match A. Don't touch the lower limbs
    1081              :      * because X might be aliased to B, and we must not overwrite the
    1082              :      * significant digits of B. */
    1083     20555435 :     if (A->n > n && A != X) {
    1084      2915188 :         memcpy(X->p + n, A->p + n, (A->n - n) * ciL);
    1085              :     }
    1086     20555435 :     if (X->n > A->n) {
    1087      6468765 :         memset(X->p + A->n, 0, (X->n - A->n) * ciL);
    1088              :     }
    1089              : 
    1090     20555435 :     carry = mbedtls_mpi_core_sub(X->p, A->p, B->p, n);
    1091     20555435 :     if (carry != 0) {
    1092              :         /* Propagate the carry through the rest of X. */
    1093      4508045 :         carry = mbedtls_mpi_core_sub_int(X->p + n, X->p + n, carry, X->n - n);
    1094              : 
    1095              :         /* If we have further carry/borrow, the result is negative. */
    1096      4508045 :         if (carry != 0) {
    1097            0 :             ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
    1098            0 :             goto cleanup;
    1099              :         }
    1100              :     }
    1101              : 
    1102              :     /* X should always be positive as a result of unsigned subtractions. */
    1103     20555435 :     X->s = 1;
    1104              : 
    1105     20555435 : cleanup:
    1106     20555435 :     return ret;
    1107              : }
    1108              : 
    1109              : /* Common function for signed addition and subtraction.
    1110              :  * Calculate A + B * flip_B where flip_B is 1 or -1.
    1111              :  */
    1112     19817776 : static int add_sub_mpi(mbedtls_mpi *X,
    1113              :                        const mbedtls_mpi *A, const mbedtls_mpi *B,
    1114              :                        int flip_B)
    1115              : {
    1116              :     int ret, s;
    1117              : 
    1118     19817776 :     s = A->s;
    1119     19817776 :     if (A->s * B->s * flip_B < 0) {
    1120     15848607 :         int cmp = mbedtls_mpi_cmp_abs(A, B);
    1121     15848607 :         if (cmp >= 0) {
    1122      6424031 :             MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(X, A, B));
    1123              :             /* If |A| = |B|, the result is 0 and we must set the sign bit
    1124              :              * to +1 regardless of which of A or B was negative. Otherwise,
    1125              :              * since |A| > |B|, the sign is the sign of A. */
    1126      6424031 :             X->s = cmp == 0 ? 1 : s;
    1127              :         } else {
    1128      9424576 :             MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(X, B, A));
    1129              :             /* Since |A| < |B|, the sign is the opposite of A. */
    1130      9424576 :             X->s = -s;
    1131              :         }
    1132              :     } else {
    1133      3969169 :         MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(X, A, B));
    1134      3969169 :         X->s = s;
    1135              :     }
    1136              : 
    1137     19817776 : cleanup:
    1138              : 
    1139     19817776 :     return ret;
    1140              : }
    1141              : 
    1142              : /*
    1143              :  * Signed addition: X = A + B
    1144              :  */
    1145      9011773 : int mbedtls_mpi_add_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
    1146              : {
    1147      9011773 :     return add_sub_mpi(X, A, B, 1);
    1148              : }
    1149              : 
    1150              : /*
    1151              :  * Signed subtraction: X = A - B
    1152              :  */
    1153     10806003 : int mbedtls_mpi_sub_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
    1154              : {
    1155     10806003 :     return add_sub_mpi(X, A, B, -1);
    1156              : }
    1157              : 
    1158              : /*
    1159              :  * Signed addition: X = A + b
    1160              :  */
    1161            2 : int mbedtls_mpi_add_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b)
    1162              : {
    1163              :     mbedtls_mpi B;
    1164              :     mbedtls_mpi_uint p[1];
    1165              : 
    1166            2 :     p[0] = mpi_sint_abs(b);
    1167            2 :     B.s = TO_SIGN(b);
    1168            2 :     B.n = 1;
    1169            2 :     B.p = p;
    1170              : 
    1171            2 :     return mbedtls_mpi_add_mpi(X, A, &B);
    1172              : }
    1173              : 
    1174              : /*
    1175              :  * Signed subtraction: X = A - b
    1176              :  */
    1177        15070 : int mbedtls_mpi_sub_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b)
    1178              : {
    1179              :     mbedtls_mpi B;
    1180              :     mbedtls_mpi_uint p[1];
    1181              : 
    1182        15070 :     p[0] = mpi_sint_abs(b);
    1183        15070 :     B.s = TO_SIGN(b);
    1184        15070 :     B.n = 1;
    1185        15070 :     B.p = p;
    1186              : 
    1187        15070 :     return mbedtls_mpi_sub_mpi(X, A, &B);
    1188              : }
    1189              : 
    1190              : /*
    1191              :  * Baseline multiplication: X = A * B  (HAC 14.12)
    1192              :  */
    1193      6325187 : int mbedtls_mpi_mul_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
    1194              : {
    1195      6325187 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1196              :     size_t i, j;
    1197              :     mbedtls_mpi TA, TB;
    1198      6325187 :     int result_is_zero = 0;
    1199              : 
    1200      6325187 :     mbedtls_mpi_init(&TA);
    1201      6325187 :     mbedtls_mpi_init(&TB);
    1202              : 
    1203      6325187 :     if (X == A) {
    1204      1801462 :         MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TA, A)); A = &TA;
    1205              :     }
    1206      6325187 :     if (X == B) {
    1207        21043 :         MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TB, B)); B = &TB;
    1208              :     }
    1209              : 
    1210     21512238 :     for (i = A->n; i > 0; i--) {
    1211     21512238 :         if (A->p[i - 1] != 0) {
    1212      6325187 :             break;
    1213              :         }
    1214              :     }
    1215      6325187 :     if (i == 0) {
    1216            0 :         result_is_zero = 1;
    1217              :     }
    1218              : 
    1219     28435704 :     for (j = B->n; j > 0; j--) {
    1220     28435704 :         if (B->p[j - 1] != 0) {
    1221      6325187 :             break;
    1222              :         }
    1223              :     }
    1224      6325187 :     if (j == 0) {
    1225            0 :         result_is_zero = 1;
    1226              :     }
    1227              : 
    1228      6325187 :     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, i + j));
    1229      6325187 :     MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 0));
    1230              : 
    1231      6325187 :     mbedtls_mpi_core_mul(X->p, A->p, i, B->p, j);
    1232              : 
    1233              :     /* If the result is 0, we don't shortcut the operation, which reduces
    1234              :      * but does not eliminate side channels leaking the zero-ness. We do
    1235              :      * need to take care to set the sign bit properly since the library does
    1236              :      * not fully support an MPI object with a value of 0 and s == -1. */
    1237      6325187 :     if (result_is_zero) {
    1238            0 :         X->s = 1;
    1239              :     } else {
    1240      6325187 :         X->s = A->s * B->s;
    1241              :     }
    1242              : 
    1243      6325187 : cleanup:
    1244              : 
    1245      6325187 :     mbedtls_mpi_free(&TB); mbedtls_mpi_free(&TA);
    1246              : 
    1247      6325187 :     return ret;
    1248              : }
    1249              : 
    1250              : /*
    1251              :  * Baseline multiplication: X = A * b
    1252              :  */
    1253       602563 : int mbedtls_mpi_mul_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b)
    1254              : {
    1255       602563 :     size_t n = A->n;
    1256      9624847 :     while (n > 0 && A->p[n - 1] == 0) {
    1257      9022284 :         --n;
    1258              :     }
    1259              : 
    1260              :     /* The general method below doesn't work if b==0. */
    1261       602563 :     if (b == 0 || n == 0) {
    1262            4 :         return mbedtls_mpi_lset(X, 0);
    1263              :     }
    1264              : 
    1265              :     /* Calculate A*b as A + A*(b-1) to take advantage of mbedtls_mpi_core_mla */
    1266       602559 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1267              :     /* In general, A * b requires 1 limb more than b. If
    1268              :      * A->p[n - 1] * b / b == A->p[n - 1], then A * b fits in the same
    1269              :      * number of limbs as A and the call to grow() is not required since
    1270              :      * copy() will take care of the growth if needed. However, experimentally,
    1271              :      * making the call to grow() unconditional causes slightly fewer
    1272              :      * calls to calloc() in ECP code, presumably because it reuses the
    1273              :      * same mpi for a while and this way the mpi is more likely to directly
    1274              :      * grow to its final size.
    1275              :      *
    1276              :      * Note that calculating A*b as 0 + A*b doesn't work as-is because
    1277              :      * A,X can be the same. */
    1278       602559 :     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, n + 1));
    1279       602559 :     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A));
    1280       602559 :     mbedtls_mpi_core_mla(X->p, X->n, A->p, n, b - 1);
    1281              : 
    1282       602559 : cleanup:
    1283       602559 :     return ret;
    1284              : }
    1285              : 
    1286              : /*
    1287              :  * Unsigned integer divide - double mbedtls_mpi_uint dividend, u1/u0, and
    1288              :  * mbedtls_mpi_uint divisor, d
    1289              :  */
    1290        41762 : static mbedtls_mpi_uint mbedtls_int_div_int(mbedtls_mpi_uint u1,
    1291              :                                             mbedtls_mpi_uint u0,
    1292              :                                             mbedtls_mpi_uint d,
    1293              :                                             mbedtls_mpi_uint *r)
    1294              : {
    1295              : #if defined(MBEDTLS_HAVE_UDBL)
    1296              :     mbedtls_t_udbl dividend, quotient;
    1297              : #else
    1298              :     const mbedtls_mpi_uint radix = (mbedtls_mpi_uint) 1 << biH;
    1299              :     const mbedtls_mpi_uint uint_halfword_mask = ((mbedtls_mpi_uint) 1 << biH) - 1;
    1300              :     mbedtls_mpi_uint d0, d1, q0, q1, rAX, r0, quotient;
    1301              :     mbedtls_mpi_uint u0_msw, u0_lsw;
    1302              :     size_t s;
    1303              : #endif
    1304              : 
    1305              :     /*
    1306              :      * Check for overflow
    1307              :      */
    1308        41762 :     if (0 == d || u1 >= d) {
    1309            0 :         if (r != NULL) {
    1310            0 :             *r = ~(mbedtls_mpi_uint) 0u;
    1311              :         }
    1312              : 
    1313            0 :         return ~(mbedtls_mpi_uint) 0u;
    1314              :     }
    1315              : 
    1316              : #if defined(MBEDTLS_HAVE_UDBL)
    1317        41762 :     dividend  = (mbedtls_t_udbl) u1 << biL;
    1318        41762 :     dividend |= (mbedtls_t_udbl) u0;
    1319        41762 :     quotient = dividend / d;
    1320        41762 :     if (quotient > ((mbedtls_t_udbl) 1 << biL) - 1) {
    1321            0 :         quotient = ((mbedtls_t_udbl) 1 << biL) - 1;
    1322              :     }
    1323              : 
    1324        41762 :     if (r != NULL) {
    1325            0 :         *r = (mbedtls_mpi_uint) (dividend - (quotient * d));
    1326              :     }
    1327              : 
    1328        41762 :     return (mbedtls_mpi_uint) quotient;
    1329              : #else
    1330              : 
    1331              :     /*
    1332              :      * Algorithm D, Section 4.3.1 - The Art of Computer Programming
    1333              :      *   Vol. 2 - Seminumerical Algorithms, Knuth
    1334              :      */
    1335              : 
    1336              :     /*
    1337              :      * Normalize the divisor, d, and dividend, u0, u1
    1338              :      */
    1339              :     s = mbedtls_mpi_core_clz(d);
    1340              :     d = d << s;
    1341              : 
    1342              :     u1 = u1 << s;
    1343              :     u1 |= (u0 >> (biL - s)) & (-(mbedtls_mpi_sint) s >> (biL - 1));
    1344              :     u0 =  u0 << s;
    1345              : 
    1346              :     d1 = d >> biH;
    1347              :     d0 = d & uint_halfword_mask;
    1348              : 
    1349              :     u0_msw = u0 >> biH;
    1350              :     u0_lsw = u0 & uint_halfword_mask;
    1351              : 
    1352              :     /*
    1353              :      * Find the first quotient and remainder
    1354              :      */
    1355              :     q1 = u1 / d1;
    1356              :     r0 = u1 - d1 * q1;
    1357              : 
    1358              :     while (q1 >= radix || (q1 * d0 > radix * r0 + u0_msw)) {
    1359              :         q1 -= 1;
    1360              :         r0 += d1;
    1361              : 
    1362              :         if (r0 >= radix) {
    1363              :             break;
    1364              :         }
    1365              :     }
    1366              : 
    1367              :     rAX = (u1 * radix) + (u0_msw - q1 * d);
    1368              :     q0 = rAX / d1;
    1369              :     r0 = rAX - q0 * d1;
    1370              : 
    1371              :     while (q0 >= radix || (q0 * d0 > radix * r0 + u0_lsw)) {
    1372              :         q0 -= 1;
    1373              :         r0 += d1;
    1374              : 
    1375              :         if (r0 >= radix) {
    1376              :             break;
    1377              :         }
    1378              :     }
    1379              : 
    1380              :     if (r != NULL) {
    1381              :         *r = (rAX * radix + u0_lsw - q0 * d) >> s;
    1382              :     }
    1383              : 
    1384              :     quotient = q1 * radix + q0;
    1385              : 
    1386              :     return quotient;
    1387              : #endif
    1388              : }
    1389              : 
    1390              : /*
    1391              :  * Division by mbedtls_mpi: A = Q * B + R  (HAC 14.20)
    1392              :  */
    1393        15098 : int mbedtls_mpi_div_mpi(mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
    1394              :                         const mbedtls_mpi *B)
    1395              : {
    1396        15098 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1397              :     size_t i, n, t, k;
    1398              :     mbedtls_mpi X, Y, Z, T1, T2;
    1399              :     mbedtls_mpi_uint TP2[3];
    1400              : 
    1401        15098 :     if (mbedtls_mpi_cmp_int(B, 0) == 0) {
    1402            0 :         return MBEDTLS_ERR_MPI_DIVISION_BY_ZERO;
    1403              :     }
    1404              : 
    1405        15098 :     mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
    1406        15098 :     mbedtls_mpi_init(&T1);
    1407              :     /*
    1408              :      * Avoid dynamic memory allocations for constant-size T2.
    1409              :      *
    1410              :      * T2 is used for comparison only and the 3 limbs are assigned explicitly,
    1411              :      * so nobody increase the size of the MPI and we're safe to use an on-stack
    1412              :      * buffer.
    1413              :      */
    1414        15098 :     T2.s = 1;
    1415        15098 :     T2.n = sizeof(TP2) / sizeof(*TP2);
    1416        15098 :     T2.p = TP2;
    1417              : 
    1418        15098 :     if (mbedtls_mpi_cmp_abs(A, B) < 0) {
    1419        11174 :         if (Q != NULL) {
    1420            0 :             MBEDTLS_MPI_CHK(mbedtls_mpi_lset(Q, 0));
    1421              :         }
    1422        11174 :         if (R != NULL) {
    1423        11174 :             MBEDTLS_MPI_CHK(mbedtls_mpi_copy(R, A));
    1424              :         }
    1425        11174 :         return 0;
    1426              :     }
    1427              : 
    1428         3924 :     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&X, A));
    1429         3924 :     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&Y, B));
    1430         3924 :     X.s = Y.s = 1;
    1431              : 
    1432         3924 :     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&Z, A->n + 2));
    1433         3924 :     MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&Z,  0));
    1434         3924 :     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&T1, A->n + 2));
    1435              : 
    1436         3924 :     k = mbedtls_mpi_bitlen(&Y) % biL;
    1437         3924 :     if (k < biL - 1) {
    1438         3924 :         k = biL - 1 - k;
    1439         3924 :         MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&X, k));
    1440         3924 :         MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&Y, k));
    1441              :     } else {
    1442            0 :         k = 0;
    1443              :     }
    1444              : 
    1445         3924 :     n = X.n - 1;
    1446         3924 :     t = Y.n - 1;
    1447         3924 :     MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&Y, biL * (n - t)));
    1448              : 
    1449         4378 :     while (mbedtls_mpi_cmp_mpi(&X, &Y) >= 0) {
    1450          454 :         Z.p[n - t]++;
    1451          454 :         MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&X, &X, &Y));
    1452              :     }
    1453         3924 :     MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&Y, biL * (n - t)));
    1454              : 
    1455        45686 :     for (i = n; i > t; i--) {
    1456        41762 :         if (X.p[i] >= Y.p[t]) {
    1457            0 :             Z.p[i - t - 1] = ~(mbedtls_mpi_uint) 0u;
    1458              :         } else {
    1459        41762 :             Z.p[i - t - 1] = mbedtls_int_div_int(X.p[i], X.p[i - 1],
    1460        41762 :                                                  Y.p[t], NULL);
    1461              :         }
    1462              : 
    1463        41762 :         T2.p[0] = (i < 2) ? 0 : X.p[i - 2];
    1464        41762 :         T2.p[1] = (i < 1) ? 0 : X.p[i - 1];
    1465        41762 :         T2.p[2] = X.p[i];
    1466              : 
    1467        41762 :         Z.p[i - t - 1]++;
    1468              :         do {
    1469        72153 :             Z.p[i - t - 1]--;
    1470              : 
    1471        72153 :             MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&T1, 0));
    1472        72153 :             T1.p[0] = (t < 1) ? 0 : Y.p[t - 1];
    1473        72153 :             T1.p[1] = Y.p[t];
    1474        72153 :             MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(&T1, &T1, Z.p[i - t - 1]));
    1475        72153 :         } while (mbedtls_mpi_cmp_mpi(&T1, &T2) > 0);
    1476              : 
    1477        41762 :         MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(&T1, &Y, Z.p[i - t - 1]));
    1478        41762 :         MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&T1,  biL * (i - t - 1)));
    1479        41762 :         MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&X, &X, &T1));
    1480              : 
    1481        41762 :         if (mbedtls_mpi_cmp_int(&X, 0) < 0) {
    1482            0 :             MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&T1, &Y));
    1483            0 :             MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&T1, biL * (i - t - 1)));
    1484            0 :             MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&X, &X, &T1));
    1485            0 :             Z.p[i - t - 1]--;
    1486              :         }
    1487              :     }
    1488              : 
    1489         3924 :     if (Q != NULL) {
    1490            2 :         MBEDTLS_MPI_CHK(mbedtls_mpi_copy(Q, &Z));
    1491            2 :         Q->s = A->s * B->s;
    1492              :     }
    1493              : 
    1494         3924 :     if (R != NULL) {
    1495         3922 :         MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&X, k));
    1496         3922 :         X.s = A->s;
    1497         3922 :         MBEDTLS_MPI_CHK(mbedtls_mpi_copy(R, &X));
    1498              : 
    1499         3922 :         if (mbedtls_mpi_cmp_int(R, 0) == 0) {
    1500            0 :             R->s = 1;
    1501              :         }
    1502              :     }
    1503              : 
    1504         3924 : cleanup:
    1505              : 
    1506         3924 :     mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
    1507         3924 :     mbedtls_mpi_free(&T1);
    1508         3924 :     mbedtls_platform_zeroize(TP2, sizeof(TP2));
    1509              : 
    1510         3924 :     return ret;
    1511              : }
    1512              : 
    1513              : /*
    1514              :  * Division by int: A = Q * b + R
    1515              :  */
    1516            0 : int mbedtls_mpi_div_int(mbedtls_mpi *Q, mbedtls_mpi *R,
    1517              :                         const mbedtls_mpi *A,
    1518              :                         mbedtls_mpi_sint b)
    1519              : {
    1520              :     mbedtls_mpi B;
    1521              :     mbedtls_mpi_uint p[1];
    1522              : 
    1523            0 :     p[0] = mpi_sint_abs(b);
    1524            0 :     B.s = TO_SIGN(b);
    1525            0 :     B.n = 1;
    1526            0 :     B.p = p;
    1527              : 
    1528            0 :     return mbedtls_mpi_div_mpi(Q, R, A, &B);
    1529              : }
    1530              : 
    1531              : /*
    1532              :  * Modulo: R = A mod B
    1533              :  */
    1534        15096 : int mbedtls_mpi_mod_mpi(mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B)
    1535              : {
    1536        15096 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1537              : 
    1538        15096 :     if (mbedtls_mpi_cmp_int(B, 0) < 0) {
    1539            0 :         return MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
    1540              :     }
    1541              : 
    1542        15096 :     MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(NULL, R, A, B));
    1543              : 
    1544        15118 :     while (mbedtls_mpi_cmp_int(R, 0) < 0) {
    1545           22 :         MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(R, R, B));
    1546              :     }
    1547              : 
    1548        15096 :     while (mbedtls_mpi_cmp_mpi(R, B) >= 0) {
    1549            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(R, R, B));
    1550              :     }
    1551              : 
    1552        15096 : cleanup:
    1553              : 
    1554        15096 :     return ret;
    1555              : }
    1556              : 
    1557              : /*
    1558              :  * Modulo: r = A mod b
    1559              :  */
    1560            0 : int mbedtls_mpi_mod_int(mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b)
    1561              : {
    1562              :     size_t i;
    1563              :     mbedtls_mpi_uint x, y, z;
    1564              : 
    1565            0 :     if (b == 0) {
    1566            0 :         return MBEDTLS_ERR_MPI_DIVISION_BY_ZERO;
    1567              :     }
    1568              : 
    1569            0 :     if (b < 0) {
    1570            0 :         return MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
    1571              :     }
    1572              : 
    1573              :     /*
    1574              :      * handle trivial cases
    1575              :      */
    1576            0 :     if (b == 1 || A->n == 0) {
    1577            0 :         *r = 0;
    1578            0 :         return 0;
    1579              :     }
    1580              : 
    1581            0 :     if (b == 2) {
    1582            0 :         *r = A->p[0] & 1;
    1583            0 :         return 0;
    1584              :     }
    1585              : 
    1586              :     /*
    1587              :      * general case
    1588              :      */
    1589            0 :     for (i = A->n, y = 0; i > 0; i--) {
    1590            0 :         x  = A->p[i - 1];
    1591            0 :         y  = (y << biH) | (x >> biH);
    1592            0 :         z  = y / b;
    1593            0 :         y -= z * b;
    1594              : 
    1595            0 :         x <<= biH;
    1596            0 :         y  = (y << biH) | (x >> biH);
    1597            0 :         z  = y / b;
    1598            0 :         y -= z * b;
    1599              :     }
    1600              : 
    1601              :     /*
    1602              :      * If A is negative, then the current y represents a negative value.
    1603              :      * Flipping it to the positive side.
    1604              :      */
    1605            0 :     if (A->s < 0 && y != 0) {
    1606            0 :         y = b - y;
    1607              :     }
    1608              : 
    1609            0 :     *r = y;
    1610              : 
    1611            0 :     return 0;
    1612              : }
    1613              : 
    1614              : /*
    1615              :  * Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value,
    1616              :  * this function is not constant time with respect to the exponent (parameter E).
    1617              :  */
    1618          504 : static int mbedtls_mpi_exp_mod_optionally_safe(mbedtls_mpi *X, const mbedtls_mpi *A,
    1619              :                                                const mbedtls_mpi *E, int E_public,
    1620              :                                                const mbedtls_mpi *N, mbedtls_mpi *prec_RR)
    1621              : {
    1622          504 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1623              : 
    1624          504 :     if (mbedtls_mpi_cmp_int(N, 0) <= 0 || (N->p[0] & 1) == 0) {
    1625            0 :         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
    1626              :     }
    1627              : 
    1628          504 :     if (mbedtls_mpi_cmp_int(E, 0) < 0) {
    1629            0 :         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
    1630              :     }
    1631              : 
    1632         1008 :     if (mbedtls_mpi_bitlen(E) > MBEDTLS_MPI_MAX_BITS ||
    1633          504 :         mbedtls_mpi_bitlen(N) > MBEDTLS_MPI_MAX_BITS) {
    1634            0 :         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
    1635              :     }
    1636              : 
    1637              :     /*
    1638              :      * Ensure that the exponent that we are passing to the core is not NULL.
    1639              :      */
    1640          504 :     if (E->n == 0) {
    1641            0 :         ret = mbedtls_mpi_lset(X, 1);
    1642            0 :         return ret;
    1643              :     }
    1644              : 
    1645              :     /*
    1646              :      * Allocate working memory for mbedtls_mpi_core_exp_mod()
    1647              :      */
    1648          504 :     size_t T_limbs = mbedtls_mpi_core_exp_mod_working_limbs(N->n, E->n);
    1649          504 :     mbedtls_mpi_uint *T = (mbedtls_mpi_uint *) mbedtls_calloc(T_limbs, sizeof(mbedtls_mpi_uint));
    1650          504 :     if (T == NULL) {
    1651            0 :         return MBEDTLS_ERR_MPI_ALLOC_FAILED;
    1652              :     }
    1653              : 
    1654              :     mbedtls_mpi RR;
    1655          504 :     mbedtls_mpi_init(&RR);
    1656              : 
    1657              :     /*
    1658              :      * If 1st call, pre-compute R^2 mod N
    1659              :      */
    1660          504 :     if (prec_RR == NULL || prec_RR->p == NULL) {
    1661          415 :         MBEDTLS_MPI_CHK(mbedtls_mpi_core_get_mont_r2_unsafe(&RR, N));
    1662              : 
    1663          415 :         if (prec_RR != NULL) {
    1664          415 :             *prec_RR = RR;
    1665              :         }
    1666              :     } else {
    1667           89 :         MBEDTLS_MPI_CHK(mbedtls_mpi_grow(prec_RR, N->n));
    1668           89 :         RR = *prec_RR;
    1669              :     }
    1670              : 
    1671              :     /*
    1672              :      * To preserve constness we need to make a copy of A. Using X for this to
    1673              :      * save memory.
    1674              :      */
    1675          504 :     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A));
    1676              : 
    1677              :     /*
    1678              :      * Compensate for negative A (and correct at the end).
    1679              :      */
    1680          504 :     X->s = 1;
    1681              : 
    1682              :     /*
    1683              :      * Make sure that X is in a form that is safe for consumption by
    1684              :      * the core functions.
    1685              :      *
    1686              :      * - The core functions will not touch the limbs of X above N->n. The
    1687              :      *   result will be correct if those limbs are 0, which the mod call
    1688              :      *   ensures.
    1689              :      * - Also, X must have at least as many limbs as N for the calls to the
    1690              :      *   core functions.
    1691              :      */
    1692          504 :     if (mbedtls_mpi_cmp_mpi(X, N) >= 0) {
    1693           76 :         MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(X, X, N));
    1694              :     }
    1695          504 :     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, N->n));
    1696              : 
    1697              :     /*
    1698              :      * Convert to and from Montgomery around mbedtls_mpi_core_exp_mod().
    1699              :      */
    1700              :     {
    1701          504 :         mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N->p);
    1702          504 :         mbedtls_mpi_core_to_mont_rep(X->p, X->p, N->p, N->n, mm, RR.p, T);
    1703          504 :         if (E_public == MBEDTLS_MPI_IS_PUBLIC) {
    1704          346 :             mbedtls_mpi_core_exp_mod_unsafe(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T);
    1705              :         } else {
    1706          158 :             mbedtls_mpi_core_exp_mod(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T);
    1707              :         }
    1708          504 :         mbedtls_mpi_core_from_mont_rep(X->p, X->p, N->p, N->n, mm, T);
    1709              :     }
    1710              : 
    1711              :     /*
    1712              :      * Correct for negative A.
    1713              :      */
    1714          504 :     if (A->s == -1 && (E->p[0] & 1) != 0) {
    1715            0 :         mbedtls_ct_condition_t is_x_non_zero = mbedtls_mpi_core_check_zero_ct(X->p, X->n);
    1716            0 :         X->s = mbedtls_ct_mpi_sign_if(is_x_non_zero, -1, 1);
    1717              : 
    1718            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(X, N, X));
    1719              :     }
    1720              : 
    1721          504 : cleanup:
    1722              : 
    1723          504 :     mbedtls_mpi_zeroize_and_free(T, T_limbs);
    1724              : 
    1725          504 :     if (prec_RR == NULL || prec_RR->p == NULL) {
    1726            0 :         mbedtls_mpi_free(&RR);
    1727              :     }
    1728              : 
    1729          504 :     return ret;
    1730              : }
    1731              : 
    1732          158 : int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
    1733              :                         const mbedtls_mpi *E, const mbedtls_mpi *N,
    1734              :                         mbedtls_mpi *prec_RR)
    1735              : {
    1736          158 :     return mbedtls_mpi_exp_mod_optionally_safe(X, A, E, MBEDTLS_MPI_IS_SECRET, N, prec_RR);
    1737              : }
    1738              : 
    1739          346 : int mbedtls_mpi_exp_mod_unsafe(mbedtls_mpi *X, const mbedtls_mpi *A,
    1740              :                                const mbedtls_mpi *E, const mbedtls_mpi *N,
    1741              :                                mbedtls_mpi *prec_RR)
    1742              : {
    1743          346 :     return mbedtls_mpi_exp_mod_optionally_safe(X, A, E, MBEDTLS_MPI_IS_PUBLIC, N, prec_RR);
    1744              : }
    1745              : 
    1746              : /*
    1747              :  * Greatest common divisor: G = gcd(A, B)  (HAC 14.54)
    1748              :  */
    1749         9557 : int mbedtls_mpi_gcd(mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B)
    1750              : {
    1751         9557 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1752              :     size_t lz, lzt;
    1753              :     mbedtls_mpi TA, TB;
    1754              : 
    1755         9557 :     mbedtls_mpi_init(&TA); mbedtls_mpi_init(&TB);
    1756              : 
    1757         9557 :     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TA, A));
    1758         9557 :     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TB, B));
    1759              : 
    1760         9557 :     lz = mbedtls_mpi_lsb(&TA);
    1761         9557 :     lzt = mbedtls_mpi_lsb(&TB);
    1762              : 
    1763              :     /* The loop below gives the correct result when A==0 but not when B==0.
    1764              :      * So have a special case for B==0. Leverage the fact that we just
    1765              :      * calculated the lsb and lsb(B)==0 iff B is odd or 0 to make the test
    1766              :      * slightly more efficient than cmp_int(). */
    1767         9557 :     if (lzt == 0 && mbedtls_mpi_get_bit(&TB, 0) == 0) {
    1768            0 :         ret = mbedtls_mpi_copy(G, A);
    1769            0 :         goto cleanup;
    1770              :     }
    1771              : 
    1772         9557 :     if (lzt < lz) {
    1773         5423 :         lz = lzt;
    1774              :     }
    1775              : 
    1776         9557 :     TA.s = TB.s = 1;
    1777              : 
    1778              :     /* We mostly follow the procedure described in HAC 14.54, but with some
    1779              :      * minor differences:
    1780              :      * - Sequences of multiplications or divisions by 2 are grouped into a
    1781              :      *   single shift operation.
    1782              :      * - The procedure in HAC assumes that 0 < TB <= TA.
    1783              :      *     - The condition TB <= TA is not actually necessary for correctness.
    1784              :      *       TA and TB have symmetric roles except for the loop termination
    1785              :      *       condition, and the shifts at the beginning of the loop body
    1786              :      *       remove any significance from the ordering of TA vs TB before
    1787              :      *       the shifts.
    1788              :      *     - If TA = 0, the loop goes through 0 iterations and the result is
    1789              :      *       correctly TB.
    1790              :      *     - The case TB = 0 was short-circuited above.
    1791              :      *
    1792              :      * For the correctness proof below, decompose the original values of
    1793              :      * A and B as
    1794              :      *   A = sa * 2^a * A' with A'=0 or A' odd, and sa = +-1
    1795              :      *   B = sb * 2^b * B' with B'=0 or B' odd, and sb = +-1
    1796              :      * Then gcd(A, B) = 2^{min(a,b)} * gcd(A',B'),
    1797              :      * and gcd(A',B') is odd or 0.
    1798              :      *
    1799              :      * At the beginning, we have TA = |A| and TB = |B| so gcd(A,B) = gcd(TA,TB).
    1800              :      * The code maintains the following invariant:
    1801              :      *     gcd(A,B) = 2^k * gcd(TA,TB) for some k   (I)
    1802              :      */
    1803              : 
    1804              :     /* Proof that the loop terminates:
    1805              :      * At each iteration, either the right-shift by 1 is made on a nonzero
    1806              :      * value and the nonnegative integer bitlen(TA) + bitlen(TB) decreases
    1807              :      * by at least 1, or the right-shift by 1 is made on zero and then
    1808              :      * TA becomes 0 which ends the loop (TB cannot be 0 if it is right-shifted
    1809              :      * since in that case TB is calculated from TB-TA with the condition TB>TA).
    1810              :      */
    1811      1789376 :     while (mbedtls_mpi_cmp_int(&TA, 0) != 0) {
    1812              :         /* Divisions by 2 preserve the invariant (I). */
    1813      1779819 :         MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TA, mbedtls_mpi_lsb(&TA)));
    1814      1779819 :         MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TB, mbedtls_mpi_lsb(&TB)));
    1815              : 
    1816              :         /* Set either TA or TB to |TA-TB|/2. Since TA and TB are both odd,
    1817              :          * TA-TB is even so the division by 2 has an integer result.
    1818              :          * Invariant (I) is preserved since any odd divisor of both TA and TB
    1819              :          * also divides |TA-TB|/2, and any odd divisor of both TA and |TA-TB|/2
    1820              :          * also divides TB, and any odd divisor of both TB and |TA-TB|/2 also
    1821              :          * divides TA.
    1822              :          */
    1823      1779819 :         if (mbedtls_mpi_cmp_mpi(&TA, &TB) >= 0) {
    1824       907049 :             MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(&TA, &TA, &TB));
    1825       907049 :             MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TA, 1));
    1826              :         } else {
    1827       872770 :             MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(&TB, &TB, &TA));
    1828       872770 :             MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TB, 1));
    1829              :         }
    1830              :         /* Note that one of TA or TB is still odd. */
    1831              :     }
    1832              : 
    1833              :     /* By invariant (I), gcd(A,B) = 2^k * gcd(TA,TB) for some k.
    1834              :      * At the loop exit, TA = 0, so gcd(TA,TB) = TB.
    1835              :      * - If there was at least one loop iteration, then one of TA or TB is odd,
    1836              :      *   and TA = 0, so TB is odd and gcd(TA,TB) = gcd(A',B'). In this case,
    1837              :      *   lz = min(a,b) so gcd(A,B) = 2^lz * TB.
    1838              :      * - If there was no loop iteration, then A was 0, and gcd(A,B) = B.
    1839              :      *   In this case, lz = 0 and B = TB so gcd(A,B) = B = 2^lz * TB as well.
    1840              :      */
    1841              : 
    1842         9557 :     MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&TB, lz));
    1843         9557 :     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(G, &TB));
    1844              : 
    1845         9557 : cleanup:
    1846              : 
    1847         9557 :     mbedtls_mpi_free(&TA); mbedtls_mpi_free(&TB);
    1848              : 
    1849         9557 :     return ret;
    1850              : }
    1851              : 
    1852              : /*
    1853              :  * Fill X with size bytes of random.
    1854              :  * The bytes returned from the RNG are used in a specific order which
    1855              :  * is suitable for deterministic ECDSA (see the specification of
    1856              :  * mbedtls_mpi_random() and the implementation in mbedtls_mpi_fill_random()).
    1857              :  */
    1858          152 : int mbedtls_mpi_fill_random(mbedtls_mpi *X, size_t size,
    1859              :                             int (*f_rng)(void *, unsigned char *, size_t),
    1860              :                             void *p_rng)
    1861              : {
    1862          152 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1863          152 :     const size_t limbs = CHARS_TO_LIMBS(size);
    1864              : 
    1865              :     /* Ensure that target MPI has exactly the necessary number of limbs */
    1866          152 :     MBEDTLS_MPI_CHK(mbedtls_mpi_resize_clear(X, limbs));
    1867          152 :     if (size == 0) {
    1868            0 :         return 0;
    1869              :     }
    1870              : 
    1871          152 :     ret = mbedtls_mpi_core_fill_random(X->p, X->n, size, f_rng, p_rng);
    1872              : 
    1873          152 : cleanup:
    1874          152 :     return ret;
    1875              : }
    1876              : 
    1877         1244 : int mbedtls_mpi_random(mbedtls_mpi *X,
    1878              :                        mbedtls_mpi_sint min,
    1879              :                        const mbedtls_mpi *N,
    1880              :                        int (*f_rng)(void *, unsigned char *, size_t),
    1881              :                        void *p_rng)
    1882              : {
    1883         1244 :     if (min < 0) {
    1884            0 :         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
    1885              :     }
    1886         1244 :     if (mbedtls_mpi_cmp_int(N, min) <= 0) {
    1887            0 :         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
    1888              :     }
    1889              : 
    1890              :     /* Ensure that target MPI has exactly the same number of limbs
    1891              :      * as the upper bound, even if the upper bound has leading zeros.
    1892              :      * This is necessary for mbedtls_mpi_core_random. */
    1893         1244 :     int ret = mbedtls_mpi_resize_clear(X, N->n);
    1894         1244 :     if (ret != 0) {
    1895            0 :         return ret;
    1896              :     }
    1897              : 
    1898         1244 :     return mbedtls_mpi_core_random(X->p, min, N->p, X->n, f_rng, p_rng);
    1899              : }
    1900              : 
    1901              : /*
    1902              :  * Modular inverse: X = A^-1 mod N  (HAC 14.61 / 14.64)
    1903              :  */
    1904         9553 : int mbedtls_mpi_inv_mod(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N)
    1905              : {
    1906         9553 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1907              :     mbedtls_mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
    1908              : 
    1909         9553 :     if (mbedtls_mpi_cmp_int(N, 1) <= 0) {
    1910            0 :         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
    1911              :     }
    1912              : 
    1913         9553 :     mbedtls_mpi_init(&TA); mbedtls_mpi_init(&TU); mbedtls_mpi_init(&U1); mbedtls_mpi_init(&U2);
    1914         9553 :     mbedtls_mpi_init(&G); mbedtls_mpi_init(&TB); mbedtls_mpi_init(&TV);
    1915         9553 :     mbedtls_mpi_init(&V1); mbedtls_mpi_init(&V2);
    1916              : 
    1917         9553 :     MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(&G, A, N));
    1918              : 
    1919         9553 :     if (mbedtls_mpi_cmp_int(&G, 1) != 0) {
    1920            0 :         ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
    1921            0 :         goto cleanup;
    1922              :     }
    1923              : 
    1924         9553 :     MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&TA, A, N));
    1925         9553 :     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TU, &TA));
    1926         9553 :     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TB, N));
    1927         9553 :     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TV, N));
    1928              : 
    1929         9553 :     MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&U1, 1));
    1930         9553 :     MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&U2, 0));
    1931         9553 :     MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&V1, 0));
    1932         9553 :     MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&V2, 1));
    1933              : 
    1934              :     do {
    1935      3558880 :         while ((TU.p[0] & 1) == 0) {
    1936      1782542 :             MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TU, 1));
    1937              : 
    1938      1782542 :             if ((U1.p[0] & 1) != 0 || (U2.p[0] & 1) != 0) {
    1939       750779 :                 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&U1, &U1, &TB));
    1940       750779 :                 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&U2, &U2, &TA));
    1941              :             }
    1942              : 
    1943      1782542 :             MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&U1, 1));
    1944      1782542 :             MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&U2, 1));
    1945              :         }
    1946              : 
    1947      3529316 :         while ((TV.p[0] & 1) == 0) {
    1948      1752978 :             MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TV, 1));
    1949              : 
    1950      1752978 :             if ((V1.p[0] & 1) != 0 || (V2.p[0] & 1) != 0) {
    1951       799176 :                 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&V1, &V1, &TB));
    1952       799176 :                 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&V2, &V2, &TA));
    1953              :             }
    1954              : 
    1955      1752978 :             MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&V1, 1));
    1956      1752978 :             MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&V2, 1));
    1957              :         }
    1958              : 
    1959      1776338 :         if (mbedtls_mpi_cmp_mpi(&TU, &TV) >= 0) {
    1960       906347 :             MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&TU, &TU, &TV));
    1961       906347 :             MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&U1, &U1, &V1));
    1962       906347 :             MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&U2, &U2, &V2));
    1963              :         } else {
    1964       869991 :             MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&TV, &TV, &TU));
    1965       869991 :             MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&V1, &V1, &U1));
    1966       869991 :             MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&V2, &V2, &U2));
    1967              :         }
    1968      1776338 :     } while (mbedtls_mpi_cmp_int(&TU, 0) != 0);
    1969              : 
    1970        10537 :     while (mbedtls_mpi_cmp_int(&V1, 0) < 0) {
    1971          984 :         MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&V1, &V1, N));
    1972              :     }
    1973              : 
    1974         9557 :     while (mbedtls_mpi_cmp_mpi(&V1, N) >= 0) {
    1975            4 :         MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&V1, &V1, N));
    1976              :     }
    1977              : 
    1978         9553 :     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, &V1));
    1979              : 
    1980         9553 : cleanup:
    1981              : 
    1982         9553 :     mbedtls_mpi_free(&TA); mbedtls_mpi_free(&TU); mbedtls_mpi_free(&U1); mbedtls_mpi_free(&U2);
    1983         9553 :     mbedtls_mpi_free(&G); mbedtls_mpi_free(&TB); mbedtls_mpi_free(&TV);
    1984         9553 :     mbedtls_mpi_free(&V1); mbedtls_mpi_free(&V2);
    1985              : 
    1986         9553 :     return ret;
    1987              : }
    1988              : 
    1989              : #if defined(MBEDTLS_GENPRIME)
    1990              : 
    1991              : /* Gaps between primes, starting at 3. https://oeis.org/A001223 */
    1992              : static const unsigned char small_prime_gaps[] = {
    1993              :     2, 2, 4, 2, 4, 2, 4, 6,
    1994              :     2, 6, 4, 2, 4, 6, 6, 2,
    1995              :     6, 4, 2, 6, 4, 6, 8, 4,
    1996              :     2, 4, 2, 4, 14, 4, 6, 2,
    1997              :     10, 2, 6, 6, 4, 6, 6, 2,
    1998              :     10, 2, 4, 2, 12, 12, 4, 2,
    1999              :     4, 6, 2, 10, 6, 6, 6, 2,
    2000              :     6, 4, 2, 10, 14, 4, 2, 4,
    2001              :     14, 6, 10, 2, 4, 6, 8, 6,
    2002              :     6, 4, 6, 8, 4, 8, 10, 2,
    2003              :     10, 2, 6, 4, 6, 8, 4, 2,
    2004              :     4, 12, 8, 4, 8, 4, 6, 12,
    2005              :     2, 18, 6, 10, 6, 6, 2, 6,
    2006              :     10, 6, 6, 2, 6, 6, 4, 2,
    2007              :     12, 10, 2, 4, 6, 6, 2, 12,
    2008              :     4, 6, 8, 10, 8, 10, 8, 6,
    2009              :     6, 4, 8, 6, 4, 8, 4, 14,
    2010              :     10, 12, 2, 10, 2, 4, 2, 10,
    2011              :     14, 4, 2, 4, 14, 4, 2, 4,
    2012              :     20, 4, 8, 10, 8, 4, 6, 6,
    2013              :     14, 4, 6, 6, 8, 6, /*reaches 997*/
    2014              :     0 /* the last entry is effectively unused */
    2015              : };
    2016              : 
    2017              : /*
    2018              :  * Small divisors test (X must be positive)
    2019              :  *
    2020              :  * Return values:
    2021              :  * 0: no small factor (possible prime, more tests needed)
    2022              :  * 1: certain prime
    2023              :  * MBEDTLS_ERR_MPI_NOT_ACCEPTABLE: certain non-prime
    2024              :  * other negative: error
    2025              :  */
    2026            0 : static int mpi_check_small_factors(const mbedtls_mpi *X)
    2027              : {
    2028            0 :     int ret = 0;
    2029              :     size_t i;
    2030              :     mbedtls_mpi_uint r;
    2031            0 :     unsigned p = 3; /* The first odd prime */
    2032              : 
    2033            0 :     if ((X->p[0] & 1) == 0) {
    2034            0 :         return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
    2035              :     }
    2036              : 
    2037            0 :     for (i = 0; i < sizeof(small_prime_gaps); p += small_prime_gaps[i], i++) {
    2038            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_mod_int(&r, X, p));
    2039            0 :         if (r == 0) {
    2040            0 :             if (mbedtls_mpi_cmp_int(X, p) == 0) {
    2041            0 :                 return 1;
    2042              :             } else {
    2043            0 :                 return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
    2044              :             }
    2045              :         }
    2046              :     }
    2047              : 
    2048            0 : cleanup:
    2049            0 :     return ret;
    2050              : }
    2051              : 
    2052              : /*
    2053              :  * Miller-Rabin pseudo-primality test  (HAC 4.24)
    2054              :  */
    2055            0 : static int mpi_miller_rabin(const mbedtls_mpi *X, size_t rounds,
    2056              :                             int (*f_rng)(void *, unsigned char *, size_t),
    2057              :                             void *p_rng)
    2058              : {
    2059              :     int ret, count;
    2060              :     size_t i, j, k, s;
    2061              :     mbedtls_mpi W, R, T, A, RR;
    2062              : 
    2063            0 :     mbedtls_mpi_init(&W); mbedtls_mpi_init(&R);
    2064            0 :     mbedtls_mpi_init(&T); mbedtls_mpi_init(&A);
    2065            0 :     mbedtls_mpi_init(&RR);
    2066              : 
    2067              :     /*
    2068              :      * W = |X| - 1
    2069              :      * R = W >> lsb( W )
    2070              :      */
    2071            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&W, X, 1));
    2072            0 :     s = mbedtls_mpi_lsb(&W);
    2073            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&R, &W));
    2074            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&R, s));
    2075              : 
    2076            0 :     for (i = 0; i < rounds; i++) {
    2077              :         /*
    2078              :          * pick a random A, 1 < A < |X| - 1
    2079              :          */
    2080            0 :         count = 0;
    2081              :         do {
    2082            0 :             MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&A, X->n * ciL, f_rng, p_rng));
    2083              : 
    2084            0 :             j = mbedtls_mpi_bitlen(&A);
    2085            0 :             k = mbedtls_mpi_bitlen(&W);
    2086            0 :             if (j > k) {
    2087            0 :                 A.p[A.n - 1] &= ((mbedtls_mpi_uint) 1 << (k - (A.n - 1) * biL - 1)) - 1;
    2088              :             }
    2089              : 
    2090            0 :             if (count++ > 30) {
    2091            0 :                 ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
    2092            0 :                 goto cleanup;
    2093              :             }
    2094              : 
    2095            0 :         } while (mbedtls_mpi_cmp_mpi(&A, &W) >= 0 ||
    2096            0 :                  mbedtls_mpi_cmp_int(&A, 1)  <= 0);
    2097              : 
    2098              :         /*
    2099              :          * A = A^R mod |X|
    2100              :          */
    2101            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&A, &A, &R, X, &RR));
    2102              : 
    2103            0 :         if (mbedtls_mpi_cmp_mpi(&A, &W) == 0 ||
    2104            0 :             mbedtls_mpi_cmp_int(&A,  1) == 0) {
    2105            0 :             continue;
    2106              :         }
    2107              : 
    2108            0 :         j = 1;
    2109            0 :         while (j < s && mbedtls_mpi_cmp_mpi(&A, &W) != 0) {
    2110              :             /*
    2111              :              * A = A * A mod |X|
    2112              :              */
    2113            0 :             MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&T, &A, &A));
    2114            0 :             MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&A, &T, X));
    2115              : 
    2116            0 :             if (mbedtls_mpi_cmp_int(&A, 1) == 0) {
    2117            0 :                 break;
    2118              :             }
    2119              : 
    2120            0 :             j++;
    2121              :         }
    2122              : 
    2123              :         /*
    2124              :          * not prime if A != |X| - 1 or A == 1
    2125              :          */
    2126            0 :         if (mbedtls_mpi_cmp_mpi(&A, &W) != 0 ||
    2127            0 :             mbedtls_mpi_cmp_int(&A,  1) == 0) {
    2128            0 :             ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
    2129            0 :             break;
    2130              :         }
    2131              :     }
    2132              : 
    2133            0 : cleanup:
    2134            0 :     mbedtls_mpi_free(&W); mbedtls_mpi_free(&R);
    2135            0 :     mbedtls_mpi_free(&T); mbedtls_mpi_free(&A);
    2136            0 :     mbedtls_mpi_free(&RR);
    2137              : 
    2138            0 :     return ret;
    2139              : }
    2140              : 
    2141              : /*
    2142              :  * Pseudo-primality test: small factors, then Miller-Rabin
    2143              :  */
    2144            0 : int mbedtls_mpi_is_prime_ext(const mbedtls_mpi *X, int rounds,
    2145              :                              int (*f_rng)(void *, unsigned char *, size_t),
    2146              :                              void *p_rng)
    2147              : {
    2148            0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    2149              :     mbedtls_mpi XX;
    2150              : 
    2151            0 :     XX.s = 1;
    2152            0 :     XX.n = X->n;
    2153            0 :     XX.p = X->p;
    2154              : 
    2155            0 :     if (mbedtls_mpi_cmp_int(&XX, 0) == 0 ||
    2156            0 :         mbedtls_mpi_cmp_int(&XX, 1) == 0) {
    2157            0 :         return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
    2158              :     }
    2159              : 
    2160            0 :     if (mbedtls_mpi_cmp_int(&XX, 2) == 0) {
    2161            0 :         return 0;
    2162              :     }
    2163              : 
    2164            0 :     if ((ret = mpi_check_small_factors(&XX)) != 0) {
    2165            0 :         if (ret == 1) {
    2166            0 :             return 0;
    2167              :         }
    2168              : 
    2169            0 :         return ret;
    2170              :     }
    2171              : 
    2172            0 :     return mpi_miller_rabin(&XX, rounds, f_rng, p_rng);
    2173              : }
    2174              : 
    2175              : /*
    2176              :  * Prime number generation
    2177              :  *
    2178              :  * To generate an RSA key in a way recommended by FIPS 186-4, both primes must
    2179              :  * be either 1024 bits or 1536 bits long, and flags must contain
    2180              :  * MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR.
    2181              :  */
    2182            0 : int mbedtls_mpi_gen_prime(mbedtls_mpi *X, size_t nbits, int flags,
    2183              :                           int (*f_rng)(void *, unsigned char *, size_t),
    2184              :                           void *p_rng)
    2185              : {
    2186              : #ifdef MBEDTLS_HAVE_INT64
    2187              : // ceil(2^63.5)
    2188              : #define CEIL_MAXUINT_DIV_SQRT2 0xb504f333f9de6485ULL
    2189              : #else
    2190              : // ceil(2^31.5)
    2191              : #define CEIL_MAXUINT_DIV_SQRT2 0xb504f334U
    2192              : #endif
    2193            0 :     int ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
    2194              :     size_t k, n;
    2195              :     int rounds;
    2196              :     mbedtls_mpi_uint r;
    2197              :     mbedtls_mpi Y;
    2198              : 
    2199            0 :     if (nbits < 3 || nbits > MBEDTLS_MPI_MAX_BITS) {
    2200            0 :         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
    2201              :     }
    2202              : 
    2203            0 :     mbedtls_mpi_init(&Y);
    2204              : 
    2205            0 :     n = BITS_TO_LIMBS(nbits);
    2206              : 
    2207            0 :     if ((flags & MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR) == 0) {
    2208              :         /*
    2209              :          * 2^-80 error probability, number of rounds chosen per HAC, table 4.4
    2210              :          */
    2211            0 :         rounds = ((nbits >= 1300) ?  2 : (nbits >=  850) ?  3 :
    2212            0 :                   (nbits >=  650) ?  4 : (nbits >=  350) ?  8 :
    2213            0 :                   (nbits >=  250) ? 12 : (nbits >=  150) ? 18 : 27);
    2214              :     } else {
    2215              :         /*
    2216              :          * 2^-100 error probability, number of rounds computed based on HAC,
    2217              :          * fact 4.48
    2218              :          */
    2219            0 :         rounds = ((nbits >= 1450) ?  4 : (nbits >=  1150) ?  5 :
    2220            0 :                   (nbits >= 1000) ?  6 : (nbits >=   850) ?  7 :
    2221            0 :                   (nbits >=  750) ?  8 : (nbits >=   500) ? 13 :
    2222            0 :                   (nbits >=  250) ? 28 : (nbits >=   150) ? 40 : 51);
    2223              :     }
    2224              : 
    2225              :     while (1) {
    2226            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(X, n * ciL, f_rng, p_rng));
    2227              :         /* make sure generated number is at least (nbits-1)+0.5 bits (FIPS 186-4 §B.3.3 steps 4.4, 5.5) */
    2228            0 :         if (X->p[n-1] < CEIL_MAXUINT_DIV_SQRT2) {
    2229            0 :             continue;
    2230              :         }
    2231              : 
    2232            0 :         k = n * biL;
    2233            0 :         if (k > nbits) {
    2234            0 :             MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(X, k - nbits));
    2235              :         }
    2236            0 :         X->p[0] |= 1;
    2237              : 
    2238            0 :         if ((flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH) == 0) {
    2239            0 :             ret = mbedtls_mpi_is_prime_ext(X, rounds, f_rng, p_rng);
    2240              : 
    2241            0 :             if (ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) {
    2242            0 :                 goto cleanup;
    2243              :             }
    2244              :         } else {
    2245              :             /*
    2246              :              * A necessary condition for Y and X = 2Y + 1 to be prime
    2247              :              * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
    2248              :              * Make sure it is satisfied, while keeping X = 3 mod 4
    2249              :              */
    2250              : 
    2251            0 :             X->p[0] |= 2;
    2252              : 
    2253            0 :             MBEDTLS_MPI_CHK(mbedtls_mpi_mod_int(&r, X, 3));
    2254            0 :             if (r == 0) {
    2255            0 :                 MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, X, 8));
    2256            0 :             } else if (r == 1) {
    2257            0 :                 MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, X, 4));
    2258              :             }
    2259              : 
    2260              :             /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
    2261            0 :             MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&Y, X));
    2262            0 :             MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&Y, 1));
    2263              : 
    2264              :             while (1) {
    2265              :                 /*
    2266              :                  * First, check small factors for X and Y
    2267              :                  * before doing Miller-Rabin on any of them
    2268              :                  */
    2269            0 :                 if ((ret = mpi_check_small_factors(X)) == 0 &&
    2270            0 :                     (ret = mpi_check_small_factors(&Y)) == 0 &&
    2271            0 :                     (ret = mpi_miller_rabin(X, rounds, f_rng, p_rng))
    2272            0 :                     == 0 &&
    2273            0 :                     (ret = mpi_miller_rabin(&Y, rounds, f_rng, p_rng))
    2274              :                     == 0) {
    2275            0 :                     goto cleanup;
    2276              :                 }
    2277              : 
    2278            0 :                 if (ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) {
    2279            0 :                     goto cleanup;
    2280              :                 }
    2281              : 
    2282              :                 /*
    2283              :                  * Next candidates. We want to preserve Y = (X-1) / 2 and
    2284              :                  * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
    2285              :                  * so up Y by 6 and X by 12.
    2286              :                  */
    2287            0 :                 MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X,  X, 12));
    2288            0 :                 MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&Y, &Y, 6));
    2289              :             }
    2290              :         }
    2291              :     }
    2292              : 
    2293            0 : cleanup:
    2294              : 
    2295            0 :     mbedtls_mpi_free(&Y);
    2296              : 
    2297            0 :     return ret;
    2298              : }
    2299              : 
    2300              : #endif /* MBEDTLS_GENPRIME */
    2301              : 
    2302              : #if defined(MBEDTLS_SELF_TEST)
    2303              : 
    2304              : #define GCD_PAIR_COUNT  3
    2305              : 
    2306              : static const int gcd_pairs[GCD_PAIR_COUNT][3] =
    2307              : {
    2308              :     { 693, 609, 21 },
    2309              :     { 1764, 868, 28 },
    2310              :     { 768454923, 542167814, 1 }
    2311              : };
    2312              : 
    2313              : /*
    2314              :  * Checkup routine
    2315              :  */
    2316            0 : int mbedtls_mpi_self_test(int verbose)
    2317              : {
    2318              :     int ret, i;
    2319              :     mbedtls_mpi A, E, N, X, Y, U, V;
    2320              : 
    2321            0 :     mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N); mbedtls_mpi_init(&X);
    2322            0 :     mbedtls_mpi_init(&Y); mbedtls_mpi_init(&U); mbedtls_mpi_init(&V);
    2323              : 
    2324            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&A, 16,
    2325              :                                             "EFE021C2645FD1DC586E69184AF4A31E" \
    2326              :                                             "D5F53E93B5F123FA41680867BA110131" \
    2327              :                                             "944FE7952E2517337780CB0DB80E61AA" \
    2328              :                                             "E7C8DDC6C5C6AADEB34EB38A2F40D5E6"));
    2329              : 
    2330            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&E, 16,
    2331              :                                             "B2E7EFD37075B9F03FF989C7C5051C20" \
    2332              :                                             "34D2A323810251127E7BF8625A4F49A5" \
    2333              :                                             "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
    2334              :                                             "5B5C25763222FEFCCFC38B832366C29E"));
    2335              : 
    2336            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&N, 16,
    2337              :                                             "0066A198186C18C10B2F5ED9B522752A" \
    2338              :                                             "9830B69916E535C8F047518A889A43A5" \
    2339              :                                             "94B6BED27A168D31D4A52F88925AA8F5"));
    2340              : 
    2341            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&X, &A, &N));
    2342              : 
    2343            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16,
    2344              :                                             "602AB7ECA597A3D6B56FF9829A5E8B85" \
    2345              :                                             "9E857EA95A03512E2BAE7391688D264A" \
    2346              :                                             "A5663B0341DB9CCFD2C4C5F421FEC814" \
    2347              :                                             "8001B72E848A38CAE1C65F78E56ABDEF" \
    2348              :                                             "E12D3C039B8A02D6BE593F0BBBDA56F1" \
    2349              :                                             "ECF677152EF804370C1A305CAF3B5BF1" \
    2350              :                                             "30879B56C61DE584A0F53A2447A51E"));
    2351              : 
    2352            0 :     if (verbose != 0) {
    2353            0 :         mbedtls_printf("  MPI test #1 (mul_mpi): ");
    2354              :     }
    2355              : 
    2356            0 :     if (mbedtls_mpi_cmp_mpi(&X, &U) != 0) {
    2357            0 :         if (verbose != 0) {
    2358            0 :             mbedtls_printf("failed\n");
    2359              :         }
    2360              : 
    2361            0 :         ret = 1;
    2362            0 :         goto cleanup;
    2363              :     }
    2364              : 
    2365            0 :     if (verbose != 0) {
    2366            0 :         mbedtls_printf("passed\n");
    2367              :     }
    2368              : 
    2369            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(&X, &Y, &A, &N));
    2370              : 
    2371            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16,
    2372              :                                             "256567336059E52CAE22925474705F39A94"));
    2373              : 
    2374            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&V, 16,
    2375              :                                             "6613F26162223DF488E9CD48CC132C7A" \
    2376              :                                             "0AC93C701B001B092E4E5B9F73BCD27B" \
    2377              :                                             "9EE50D0657C77F374E903CDFA4C642"));
    2378              : 
    2379            0 :     if (verbose != 0) {
    2380            0 :         mbedtls_printf("  MPI test #2 (div_mpi): ");
    2381              :     }
    2382              : 
    2383            0 :     if (mbedtls_mpi_cmp_mpi(&X, &U) != 0 ||
    2384            0 :         mbedtls_mpi_cmp_mpi(&Y, &V) != 0) {
    2385            0 :         if (verbose != 0) {
    2386            0 :             mbedtls_printf("failed\n");
    2387              :         }
    2388              : 
    2389            0 :         ret = 1;
    2390            0 :         goto cleanup;
    2391              :     }
    2392              : 
    2393            0 :     if (verbose != 0) {
    2394            0 :         mbedtls_printf("passed\n");
    2395              :     }
    2396              : 
    2397            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&X, &A, &E, &N, NULL));
    2398              : 
    2399            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16,
    2400              :                                             "36E139AEA55215609D2816998ED020BB" \
    2401              :                                             "BD96C37890F65171D948E9BC7CBAA4D9" \
    2402              :                                             "325D24D6A3C12710F10A09FA08AB87"));
    2403              : 
    2404            0 :     if (verbose != 0) {
    2405            0 :         mbedtls_printf("  MPI test #3 (exp_mod): ");
    2406              :     }
    2407              : 
    2408            0 :     if (mbedtls_mpi_cmp_mpi(&X, &U) != 0) {
    2409            0 :         if (verbose != 0) {
    2410            0 :             mbedtls_printf("failed\n");
    2411              :         }
    2412              : 
    2413            0 :         ret = 1;
    2414            0 :         goto cleanup;
    2415              :     }
    2416              : 
    2417            0 :     if (verbose != 0) {
    2418            0 :         mbedtls_printf("passed\n");
    2419              :     }
    2420              : 
    2421            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&X, &A, &N));
    2422              : 
    2423            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16,
    2424              :                                             "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
    2425              :                                             "C3DBA76456363A10869622EAC2DD84EC" \
    2426              :                                             "C5B8A74DAC4D09E03B5E0BE779F2DF61"));
    2427              : 
    2428            0 :     if (verbose != 0) {
    2429            0 :         mbedtls_printf("  MPI test #4 (inv_mod): ");
    2430              :     }
    2431              : 
    2432            0 :     if (mbedtls_mpi_cmp_mpi(&X, &U) != 0) {
    2433            0 :         if (verbose != 0) {
    2434            0 :             mbedtls_printf("failed\n");
    2435              :         }
    2436              : 
    2437            0 :         ret = 1;
    2438            0 :         goto cleanup;
    2439              :     }
    2440              : 
    2441            0 :     if (verbose != 0) {
    2442            0 :         mbedtls_printf("passed\n");
    2443              :     }
    2444              : 
    2445            0 :     if (verbose != 0) {
    2446            0 :         mbedtls_printf("  MPI test #5 (simple gcd): ");
    2447              :     }
    2448              : 
    2449            0 :     for (i = 0; i < GCD_PAIR_COUNT; i++) {
    2450            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&X, gcd_pairs[i][0]));
    2451            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&Y, gcd_pairs[i][1]));
    2452              : 
    2453            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(&A, &X, &Y));
    2454              : 
    2455            0 :         if (mbedtls_mpi_cmp_int(&A, gcd_pairs[i][2]) != 0) {
    2456            0 :             if (verbose != 0) {
    2457            0 :                 mbedtls_printf("failed at %d\n", i);
    2458              :             }
    2459              : 
    2460            0 :             ret = 1;
    2461            0 :             goto cleanup;
    2462              :         }
    2463              :     }
    2464              : 
    2465            0 :     if (verbose != 0) {
    2466            0 :         mbedtls_printf("passed\n");
    2467              :     }
    2468              : 
    2469            0 : cleanup:
    2470              : 
    2471            0 :     if (ret != 0 && verbose != 0) {
    2472            0 :         mbedtls_printf("Unexpected error, return code = %08X\n", (unsigned int) ret);
    2473              :     }
    2474              : 
    2475            0 :     mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N); mbedtls_mpi_free(&X);
    2476            0 :     mbedtls_mpi_free(&Y); mbedtls_mpi_free(&U); mbedtls_mpi_free(&V);
    2477              : 
    2478            0 :     if (verbose != 0) {
    2479            0 :         mbedtls_printf("\n");
    2480              :     }
    2481              : 
    2482            0 :     return ret;
    2483              : }
    2484              : 
    2485              : #endif /* MBEDTLS_SELF_TEST */
    2486              : 
    2487              : #endif /* MBEDTLS_BIGNUM_C */
        

Generated by: LCOV version 2.0-1