Path: blob/master/thirdparty/mbedtls/library/bignum.c
9898 views
/*1* Multi-precision integer library2*3* Copyright The Mbed TLS Contributors4* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later5*/67/*8* The following sources were referenced in the design of this Multi-precision9* Integer library:10*11* [1] Handbook of Applied Cryptography - 199712* Menezes, van Oorschot and Vanstone13*14* [2] Multi-Precision Math15* Tom St Denis16* https://github.com/libtom/libtommath/blob/develop/tommath.pdf17*18* [3] GNU Multi-Precision Arithmetic Library19* https://gmplib.org/manual/index.html20*21*/2223#include "common.h"2425#if defined(MBEDTLS_BIGNUM_C)2627#include "mbedtls/bignum.h"28#include "bignum_core.h"29#include "bignum_internal.h"30#include "bn_mul.h"31#include "mbedtls/platform_util.h"32#include "mbedtls/error.h"33#include "constant_time_internal.h"3435#include <limits.h>36#include <string.h>3738#include "mbedtls/platform.h"39404142/*43* Conditionally select an MPI sign in constant time.44* (MPI sign is the field s in mbedtls_mpi. It is unsigned short and only 1 and -1 are valid45* values.)46*/47static inline signed short mbedtls_ct_mpi_sign_if(mbedtls_ct_condition_t cond,48signed short sign1, signed short sign2)49{50return (signed short) mbedtls_ct_uint_if(cond, sign1 + 1, sign2 + 1) - 1;51}5253/*54* Compare signed values in constant time55*/56int mbedtls_mpi_lt_mpi_ct(const mbedtls_mpi *X,57const mbedtls_mpi *Y,58unsigned *ret)59{60mbedtls_ct_condition_t different_sign, X_is_negative, Y_is_negative, result;6162if (X->n != Y->n) {63return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;64}6566/*67* Set N_is_negative to MBEDTLS_CT_FALSE if N >= 0, MBEDTLS_CT_TRUE if N < 0.68* We know that N->s == 1 if N >= 0 and N->s == -1 if N < 0.69*/70X_is_negative = mbedtls_ct_bool((X->s & 2) >> 1);71Y_is_negative = mbedtls_ct_bool((Y->s & 2) >> 1);7273/*74* If the signs are different, then the positive operand is the bigger.75* That is if X is negative (X_is_negative == 1), then X < Y is true and it76* is false if X is positive (X_is_negative == 0).77*/78different_sign = mbedtls_ct_bool_ne(X_is_negative, Y_is_negative); // true if different sign79result = mbedtls_ct_bool_and(different_sign, X_is_negative);8081/*82* Assuming signs are the same, compare X and Y. We switch the comparison83* order if they are negative so that we get the right result, regardles of84* sign.85*/8687/* This array is used to conditionally swap the pointers in const time */88void * const p[2] = { X->p, Y->p };89size_t i = mbedtls_ct_size_if_else_0(X_is_negative, 1);90mbedtls_ct_condition_t lt = mbedtls_mpi_core_lt_ct(p[i], p[i ^ 1], X->n);9192/*93* Store in result iff the signs are the same (i.e., iff different_sign == false). If94* the signs differ, result has already been set, so we don't change it.95*/96result = mbedtls_ct_bool_or(result,97mbedtls_ct_bool_and(mbedtls_ct_bool_not(different_sign), lt));9899*ret = mbedtls_ct_uint_if_else_0(result, 1);100101return 0;102}103104/*105* Conditionally assign X = Y, without leaking information106* about whether the assignment was made or not.107* (Leaking information about the respective sizes of X and Y is ok however.)108*/109#if defined(_MSC_VER) && defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64) && \110(_MSC_FULL_VER < 193131103)111/*112* MSVC miscompiles this function if it's inlined prior to Visual Studio 2022 version 17.1. See:113* https://developercommunity.visualstudio.com/t/c-compiler-miscompiles-part-of-mbedtls-library-on/1646989114*/115__declspec(noinline)116#endif117int mbedtls_mpi_safe_cond_assign(mbedtls_mpi *X,118const mbedtls_mpi *Y,119unsigned char assign)120{121int ret = 0;122123MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, Y->n));124125{126mbedtls_ct_condition_t do_assign = mbedtls_ct_bool(assign);127128X->s = mbedtls_ct_mpi_sign_if(do_assign, Y->s, X->s);129130mbedtls_mpi_core_cond_assign(X->p, Y->p, Y->n, do_assign);131132mbedtls_ct_condition_t do_not_assign = mbedtls_ct_bool_not(do_assign);133for (size_t i = Y->n; i < X->n; i++) {134X->p[i] = mbedtls_ct_mpi_uint_if_else_0(do_not_assign, X->p[i]);135}136}137138cleanup:139return ret;140}141142/*143* Conditionally swap X and Y, without leaking information144* about whether the swap was made or not.145* Here it is not ok to simply swap the pointers, which would lead to146* different memory access patterns when X and Y are used afterwards.147*/148int mbedtls_mpi_safe_cond_swap(mbedtls_mpi *X,149mbedtls_mpi *Y,150unsigned char swap)151{152int ret = 0;153int s;154155if (X == Y) {156return 0;157}158159mbedtls_ct_condition_t do_swap = mbedtls_ct_bool(swap);160161MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, Y->n));162MBEDTLS_MPI_CHK(mbedtls_mpi_grow(Y, X->n));163164s = X->s;165X->s = mbedtls_ct_mpi_sign_if(do_swap, Y->s, X->s);166Y->s = mbedtls_ct_mpi_sign_if(do_swap, s, Y->s);167168mbedtls_mpi_core_cond_swap(X->p, Y->p, X->n, do_swap);169170cleanup:171return ret;172}173174/* Implementation that should never be optimized out by the compiler */175#define mbedtls_mpi_zeroize_and_free(v, n) mbedtls_zeroize_and_free(v, ciL * (n))176177/*178* Initialize one MPI179*/180void mbedtls_mpi_init(mbedtls_mpi *X)181{182X->s = 1;183X->n = 0;184X->p = NULL;185}186187/*188* Unallocate one MPI189*/190void mbedtls_mpi_free(mbedtls_mpi *X)191{192if (X == NULL) {193return;194}195196if (X->p != NULL) {197mbedtls_mpi_zeroize_and_free(X->p, X->n);198}199200X->s = 1;201X->n = 0;202X->p = NULL;203}204205/*206* Enlarge to the specified number of limbs207*/208int mbedtls_mpi_grow(mbedtls_mpi *X, size_t nblimbs)209{210mbedtls_mpi_uint *p;211212if (nblimbs > MBEDTLS_MPI_MAX_LIMBS) {213return MBEDTLS_ERR_MPI_ALLOC_FAILED;214}215216if (X->n < nblimbs) {217if ((p = (mbedtls_mpi_uint *) mbedtls_calloc(nblimbs, ciL)) == NULL) {218return MBEDTLS_ERR_MPI_ALLOC_FAILED;219}220221if (X->p != NULL) {222memcpy(p, X->p, X->n * ciL);223mbedtls_mpi_zeroize_and_free(X->p, X->n);224}225226/* nblimbs fits in n because we ensure that MBEDTLS_MPI_MAX_LIMBS227* fits, and we've checked that nblimbs <= MBEDTLS_MPI_MAX_LIMBS. */228X->n = (unsigned short) nblimbs;229X->p = p;230}231232return 0;233}234235/*236* Resize down as much as possible,237* while keeping at least the specified number of limbs238*/239int mbedtls_mpi_shrink(mbedtls_mpi *X, size_t nblimbs)240{241mbedtls_mpi_uint *p;242size_t i;243244if (nblimbs > MBEDTLS_MPI_MAX_LIMBS) {245return MBEDTLS_ERR_MPI_ALLOC_FAILED;246}247248/* Actually resize up if there are currently fewer than nblimbs limbs. */249if (X->n <= nblimbs) {250return mbedtls_mpi_grow(X, nblimbs);251}252/* After this point, then X->n > nblimbs and in particular X->n > 0. */253254for (i = X->n - 1; i > 0; i--) {255if (X->p[i] != 0) {256break;257}258}259i++;260261if (i < nblimbs) {262i = nblimbs;263}264265if ((p = (mbedtls_mpi_uint *) mbedtls_calloc(i, ciL)) == NULL) {266return MBEDTLS_ERR_MPI_ALLOC_FAILED;267}268269if (X->p != NULL) {270memcpy(p, X->p, i * ciL);271mbedtls_mpi_zeroize_and_free(X->p, X->n);272}273274/* i fits in n because we ensure that MBEDTLS_MPI_MAX_LIMBS275* fits, and we've checked that i <= nblimbs <= MBEDTLS_MPI_MAX_LIMBS. */276X->n = (unsigned short) i;277X->p = p;278279return 0;280}281282/* Resize X to have exactly n limbs and set it to 0. */283static int mbedtls_mpi_resize_clear(mbedtls_mpi *X, size_t limbs)284{285if (limbs == 0) {286mbedtls_mpi_free(X);287return 0;288} else if (X->n == limbs) {289memset(X->p, 0, limbs * ciL);290X->s = 1;291return 0;292} else {293mbedtls_mpi_free(X);294return mbedtls_mpi_grow(X, limbs);295}296}297298/*299* Copy the contents of Y into X.300*301* This function is not constant-time. Leading zeros in Y may be removed.302*303* Ensure that X does not shrink. This is not guaranteed by the public API,304* but some code in the bignum module might still rely on this property.305*/306int mbedtls_mpi_copy(mbedtls_mpi *X, const mbedtls_mpi *Y)307{308int ret = 0;309size_t i;310311if (X == Y) {312return 0;313}314315if (Y->n == 0) {316if (X->n != 0) {317X->s = 1;318memset(X->p, 0, X->n * ciL);319}320return 0;321}322323for (i = Y->n - 1; i > 0; i--) {324if (Y->p[i] != 0) {325break;326}327}328i++;329330X->s = Y->s;331332if (X->n < i) {333MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, i));334} else {335memset(X->p + i, 0, (X->n - i) * ciL);336}337338memcpy(X->p, Y->p, i * ciL);339340cleanup:341342return ret;343}344345/*346* Swap the contents of X and Y347*/348void mbedtls_mpi_swap(mbedtls_mpi *X, mbedtls_mpi *Y)349{350mbedtls_mpi T;351352memcpy(&T, X, sizeof(mbedtls_mpi));353memcpy(X, Y, sizeof(mbedtls_mpi));354memcpy(Y, &T, sizeof(mbedtls_mpi));355}356357static inline mbedtls_mpi_uint mpi_sint_abs(mbedtls_mpi_sint z)358{359if (z >= 0) {360return z;361}362/* Take care to handle the most negative value (-2^(biL-1)) correctly.363* A naive -z would have undefined behavior.364* Write this in a way that makes popular compilers happy (GCC, Clang,365* MSVC). */366return (mbedtls_mpi_uint) 0 - (mbedtls_mpi_uint) z;367}368369/* Convert x to a sign, i.e. to 1, if x is positive, or -1, if x is negative.370* This looks awkward but generates smaller code than (x < 0 ? -1 : 1) */371#define TO_SIGN(x) ((mbedtls_mpi_sint) (((mbedtls_mpi_uint) x) >> (biL - 1)) * -2 + 1)372373/*374* Set value from integer375*/376int mbedtls_mpi_lset(mbedtls_mpi *X, mbedtls_mpi_sint z)377{378int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;379380MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, 1));381memset(X->p, 0, X->n * ciL);382383X->p[0] = mpi_sint_abs(z);384X->s = TO_SIGN(z);385386cleanup:387388return ret;389}390391/*392* Get a specific bit393*/394int mbedtls_mpi_get_bit(const mbedtls_mpi *X, size_t pos)395{396if (X->n * biL <= pos) {397return 0;398}399400return (X->p[pos / biL] >> (pos % biL)) & 0x01;401}402403/*404* Set a bit to a specific value of 0 or 1405*/406int mbedtls_mpi_set_bit(mbedtls_mpi *X, size_t pos, unsigned char val)407{408int ret = 0;409size_t off = pos / biL;410size_t idx = pos % biL;411412if (val != 0 && val != 1) {413return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;414}415416if (X->n * biL <= pos) {417if (val == 0) {418return 0;419}420421MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, off + 1));422}423424X->p[off] &= ~((mbedtls_mpi_uint) 0x01 << idx);425X->p[off] |= (mbedtls_mpi_uint) val << idx;426427cleanup:428429return ret;430}431432/*433* Return the number of less significant zero-bits434*/435size_t mbedtls_mpi_lsb(const mbedtls_mpi *X)436{437size_t i;438439#if defined(__has_builtin)440#if (MBEDTLS_MPI_UINT_MAX == UINT_MAX) && __has_builtin(__builtin_ctz)441#define mbedtls_mpi_uint_ctz __builtin_ctz442#elif (MBEDTLS_MPI_UINT_MAX == ULONG_MAX) && __has_builtin(__builtin_ctzl)443#define mbedtls_mpi_uint_ctz __builtin_ctzl444#elif (MBEDTLS_MPI_UINT_MAX == ULLONG_MAX) && __has_builtin(__builtin_ctzll)445#define mbedtls_mpi_uint_ctz __builtin_ctzll446#endif447#endif448449#if defined(mbedtls_mpi_uint_ctz)450for (i = 0; i < X->n; i++) {451if (X->p[i] != 0) {452return i * biL + mbedtls_mpi_uint_ctz(X->p[i]);453}454}455#else456size_t count = 0;457for (i = 0; i < X->n; i++) {458for (size_t j = 0; j < biL; j++, count++) {459if (((X->p[i] >> j) & 1) != 0) {460return count;461}462}463}464#endif465466return 0;467}468469/*470* Return the number of bits471*/472size_t mbedtls_mpi_bitlen(const mbedtls_mpi *X)473{474return mbedtls_mpi_core_bitlen(X->p, X->n);475}476477/*478* Return the total size in bytes479*/480size_t mbedtls_mpi_size(const mbedtls_mpi *X)481{482return (mbedtls_mpi_bitlen(X) + 7) >> 3;483}484485/*486* Convert an ASCII character to digit value487*/488static int mpi_get_digit(mbedtls_mpi_uint *d, int radix, char c)489{490*d = 255;491492if (c >= 0x30 && c <= 0x39) {493*d = c - 0x30;494}495if (c >= 0x41 && c <= 0x46) {496*d = c - 0x37;497}498if (c >= 0x61 && c <= 0x66) {499*d = c - 0x57;500}501502if (*d >= (mbedtls_mpi_uint) radix) {503return MBEDTLS_ERR_MPI_INVALID_CHARACTER;504}505506return 0;507}508509/*510* Import from an ASCII string511*/512int mbedtls_mpi_read_string(mbedtls_mpi *X, int radix, const char *s)513{514int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;515size_t i, j, slen, n;516int sign = 1;517mbedtls_mpi_uint d;518mbedtls_mpi T;519520if (radix < 2 || radix > 16) {521return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;522}523524mbedtls_mpi_init(&T);525526if (s[0] == 0) {527mbedtls_mpi_free(X);528return 0;529}530531if (s[0] == '-') {532++s;533sign = -1;534}535536slen = strlen(s);537538if (radix == 16) {539if (slen > SIZE_MAX >> 2) {540return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;541}542543n = BITS_TO_LIMBS(slen << 2);544545MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, n));546MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 0));547548for (i = slen, j = 0; i > 0; i--, j++) {549MBEDTLS_MPI_CHK(mpi_get_digit(&d, radix, s[i - 1]));550X->p[j / (2 * ciL)] |= d << ((j % (2 * ciL)) << 2);551}552} else {553MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 0));554555for (i = 0; i < slen; i++) {556MBEDTLS_MPI_CHK(mpi_get_digit(&d, radix, s[i]));557MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(&T, X, radix));558MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, &T, d));559}560}561562if (sign < 0 && mbedtls_mpi_bitlen(X) != 0) {563X->s = -1;564}565566cleanup:567568mbedtls_mpi_free(&T);569570return ret;571}572573/*574* Helper to write the digits high-order first.575*/576static int mpi_write_hlp(mbedtls_mpi *X, int radix,577char **p, const size_t buflen)578{579int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;580mbedtls_mpi_uint r;581size_t length = 0;582char *p_end = *p + buflen;583584do {585if (length >= buflen) {586return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL;587}588589MBEDTLS_MPI_CHK(mbedtls_mpi_mod_int(&r, X, radix));590MBEDTLS_MPI_CHK(mbedtls_mpi_div_int(X, NULL, X, radix));591/*592* Write the residue in the current position, as an ASCII character.593*/594if (r < 0xA) {595*(--p_end) = (char) ('0' + r);596} else {597*(--p_end) = (char) ('A' + (r - 0xA));598}599600length++;601} while (mbedtls_mpi_cmp_int(X, 0) != 0);602603memmove(*p, p_end, length);604*p += length;605606cleanup:607608return ret;609}610611/*612* Export into an ASCII string613*/614int mbedtls_mpi_write_string(const mbedtls_mpi *X, int radix,615char *buf, size_t buflen, size_t *olen)616{617int ret = 0;618size_t n;619char *p;620mbedtls_mpi T;621622if (radix < 2 || radix > 16) {623return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;624}625626n = mbedtls_mpi_bitlen(X); /* Number of bits necessary to present `n`. */627if (radix >= 4) {628n >>= 1; /* Number of 4-adic digits necessary to present629* `n`. If radix > 4, this might be a strict630* overapproximation of the number of631* radix-adic digits needed to present `n`. */632}633if (radix >= 16) {634n >>= 1; /* Number of hexadecimal digits necessary to635* present `n`. */636637}638n += 1; /* Terminating null byte */639n += 1; /* Compensate for the divisions above, which round down `n`640* in case it's not even. */641n += 1; /* Potential '-'-sign. */642n += (n & 1); /* Make n even to have enough space for hexadecimal writing,643* which always uses an even number of hex-digits. */644645if (buflen < n) {646*olen = n;647return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL;648}649650p = buf;651mbedtls_mpi_init(&T);652653if (X->s == -1) {654*p++ = '-';655buflen--;656}657658if (radix == 16) {659int c;660size_t i, j, k;661662for (i = X->n, k = 0; i > 0; i--) {663for (j = ciL; j > 0; j--) {664c = (X->p[i - 1] >> ((j - 1) << 3)) & 0xFF;665666if (c == 0 && k == 0 && (i + j) != 2) {667continue;668}669670*(p++) = "0123456789ABCDEF" [c / 16];671*(p++) = "0123456789ABCDEF" [c % 16];672k = 1;673}674}675} else {676MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&T, X));677678if (T.s == -1) {679T.s = 1;680}681682MBEDTLS_MPI_CHK(mpi_write_hlp(&T, radix, &p, buflen));683}684685*p++ = '\0';686*olen = (size_t) (p - buf);687688cleanup:689690mbedtls_mpi_free(&T);691692return ret;693}694695#if defined(MBEDTLS_FS_IO)696/*697* Read X from an opened file698*/699int mbedtls_mpi_read_file(mbedtls_mpi *X, int radix, FILE *fin)700{701mbedtls_mpi_uint d;702size_t slen;703char *p;704/*705* Buffer should have space for (short) label and decimal formatted MPI,706* newline characters and '\0'707*/708char s[MBEDTLS_MPI_RW_BUFFER_SIZE];709710if (radix < 2 || radix > 16) {711return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;712}713714memset(s, 0, sizeof(s));715if (fgets(s, sizeof(s) - 1, fin) == NULL) {716return MBEDTLS_ERR_MPI_FILE_IO_ERROR;717}718719slen = strlen(s);720if (slen == sizeof(s) - 2) {721return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL;722}723724if (slen > 0 && s[slen - 1] == '\n') {725slen--; s[slen] = '\0';726}727if (slen > 0 && s[slen - 1] == '\r') {728slen--; s[slen] = '\0';729}730731p = s + slen;732while (p-- > s) {733if (mpi_get_digit(&d, radix, *p) != 0) {734break;735}736}737738return mbedtls_mpi_read_string(X, radix, p + 1);739}740741/*742* Write X into an opened file (or stdout if fout == NULL)743*/744int mbedtls_mpi_write_file(const char *p, const mbedtls_mpi *X, int radix, FILE *fout)745{746int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;747size_t n, slen, plen;748/*749* Buffer should have space for (short) label and decimal formatted MPI,750* newline characters and '\0'751*/752char s[MBEDTLS_MPI_RW_BUFFER_SIZE];753754if (radix < 2 || radix > 16) {755return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;756}757758memset(s, 0, sizeof(s));759760MBEDTLS_MPI_CHK(mbedtls_mpi_write_string(X, radix, s, sizeof(s) - 2, &n));761762if (p == NULL) {763p = "";764}765766plen = strlen(p);767slen = strlen(s);768s[slen++] = '\r';769s[slen++] = '\n';770771if (fout != NULL) {772if (fwrite(p, 1, plen, fout) != plen ||773fwrite(s, 1, slen, fout) != slen) {774return MBEDTLS_ERR_MPI_FILE_IO_ERROR;775}776} else {777mbedtls_printf("%s%s", p, s);778}779780cleanup:781782return ret;783}784#endif /* MBEDTLS_FS_IO */785786/*787* Import X from unsigned binary data, little endian788*789* This function is guaranteed to return an MPI with exactly the necessary790* number of limbs (in particular, it does not skip 0s in the input).791*/792int mbedtls_mpi_read_binary_le(mbedtls_mpi *X,793const unsigned char *buf, size_t buflen)794{795int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;796const size_t limbs = CHARS_TO_LIMBS(buflen);797798/* Ensure that target MPI has exactly the necessary number of limbs */799MBEDTLS_MPI_CHK(mbedtls_mpi_resize_clear(X, limbs));800801MBEDTLS_MPI_CHK(mbedtls_mpi_core_read_le(X->p, X->n, buf, buflen));802803cleanup:804805/*806* This function is also used to import keys. However, wiping the buffers807* upon failure is not necessary because failure only can happen before any808* input is copied.809*/810return ret;811}812813/*814* Import X from unsigned binary data, big endian815*816* This function is guaranteed to return an MPI with exactly the necessary817* number of limbs (in particular, it does not skip 0s in the input).818*/819int mbedtls_mpi_read_binary(mbedtls_mpi *X, const unsigned char *buf, size_t buflen)820{821int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;822const size_t limbs = CHARS_TO_LIMBS(buflen);823824/* Ensure that target MPI has exactly the necessary number of limbs */825MBEDTLS_MPI_CHK(mbedtls_mpi_resize_clear(X, limbs));826827MBEDTLS_MPI_CHK(mbedtls_mpi_core_read_be(X->p, X->n, buf, buflen));828829cleanup:830831/*832* This function is also used to import keys. However, wiping the buffers833* upon failure is not necessary because failure only can happen before any834* input is copied.835*/836return ret;837}838839/*840* Export X into unsigned binary data, little endian841*/842int mbedtls_mpi_write_binary_le(const mbedtls_mpi *X,843unsigned char *buf, size_t buflen)844{845return mbedtls_mpi_core_write_le(X->p, X->n, buf, buflen);846}847848/*849* Export X into unsigned binary data, big endian850*/851int mbedtls_mpi_write_binary(const mbedtls_mpi *X,852unsigned char *buf, size_t buflen)853{854return mbedtls_mpi_core_write_be(X->p, X->n, buf, buflen);855}856857/*858* Left-shift: X <<= count859*/860int mbedtls_mpi_shift_l(mbedtls_mpi *X, size_t count)861{862int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;863size_t i;864865i = mbedtls_mpi_bitlen(X) + count;866867if (X->n * biL < i) {868MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, BITS_TO_LIMBS(i)));869}870871ret = 0;872873mbedtls_mpi_core_shift_l(X->p, X->n, count);874cleanup:875876return ret;877}878879/*880* Right-shift: X >>= count881*/882int mbedtls_mpi_shift_r(mbedtls_mpi *X, size_t count)883{884if (X->n != 0) {885mbedtls_mpi_core_shift_r(X->p, X->n, count);886}887return 0;888}889890/*891* Compare unsigned values892*/893int mbedtls_mpi_cmp_abs(const mbedtls_mpi *X, const mbedtls_mpi *Y)894{895size_t i, j;896897for (i = X->n; i > 0; i--) {898if (X->p[i - 1] != 0) {899break;900}901}902903for (j = Y->n; j > 0; j--) {904if (Y->p[j - 1] != 0) {905break;906}907}908909/* If i == j == 0, i.e. abs(X) == abs(Y),910* we end up returning 0 at the end of the function. */911912if (i > j) {913return 1;914}915if (j > i) {916return -1;917}918919for (; i > 0; i--) {920if (X->p[i - 1] > Y->p[i - 1]) {921return 1;922}923if (X->p[i - 1] < Y->p[i - 1]) {924return -1;925}926}927928return 0;929}930931/*932* Compare signed values933*/934int mbedtls_mpi_cmp_mpi(const mbedtls_mpi *X, const mbedtls_mpi *Y)935{936size_t i, j;937938for (i = X->n; i > 0; i--) {939if (X->p[i - 1] != 0) {940break;941}942}943944for (j = Y->n; j > 0; j--) {945if (Y->p[j - 1] != 0) {946break;947}948}949950if (i == 0 && j == 0) {951return 0;952}953954if (i > j) {955return X->s;956}957if (j > i) {958return -Y->s;959}960961if (X->s > 0 && Y->s < 0) {962return 1;963}964if (Y->s > 0 && X->s < 0) {965return -1;966}967968for (; i > 0; i--) {969if (X->p[i - 1] > Y->p[i - 1]) {970return X->s;971}972if (X->p[i - 1] < Y->p[i - 1]) {973return -X->s;974}975}976977return 0;978}979980/*981* Compare signed values982*/983int mbedtls_mpi_cmp_int(const mbedtls_mpi *X, mbedtls_mpi_sint z)984{985mbedtls_mpi Y;986mbedtls_mpi_uint p[1];987988*p = mpi_sint_abs(z);989Y.s = TO_SIGN(z);990Y.n = 1;991Y.p = p;992993return mbedtls_mpi_cmp_mpi(X, &Y);994}995996/*997* Unsigned addition: X = |A| + |B| (HAC 14.7)998*/999int mbedtls_mpi_add_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)1000{1001int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;1002size_t j;1003mbedtls_mpi_uint *p;1004mbedtls_mpi_uint c;10051006if (X == B) {1007const mbedtls_mpi *T = A; A = X; B = T;1008}10091010if (X != A) {1011MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A));1012}10131014/*1015* X must always be positive as a result of unsigned additions.1016*/1017X->s = 1;10181019for (j = B->n; j > 0; j--) {1020if (B->p[j - 1] != 0) {1021break;1022}1023}10241025/* Exit early to avoid undefined behavior on NULL+0 when X->n == 01026* and B is 0 (of any size). */1027if (j == 0) {1028return 0;1029}10301031MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, j));10321033/* j is the number of non-zero limbs of B. Add those to X. */10341035p = X->p;10361037c = mbedtls_mpi_core_add(p, p, B->p, j);10381039p += j;10401041/* Now propagate any carry */10421043while (c != 0) {1044if (j >= X->n) {1045MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, j + 1));1046p = X->p + j;1047}10481049*p += c; c = (*p < c); j++; p++;1050}10511052cleanup:10531054return ret;1055}10561057/*1058* Unsigned subtraction: X = |A| - |B| (HAC 14.9, 14.10)1059*/1060int mbedtls_mpi_sub_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)1061{1062int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;1063size_t n;1064mbedtls_mpi_uint carry;10651066for (n = B->n; n > 0; n--) {1067if (B->p[n - 1] != 0) {1068break;1069}1070}1071if (n > A->n) {1072/* B >= (2^ciL)^n > A */1073ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE;1074goto cleanup;1075}10761077MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, A->n));10781079/* Set the high limbs of X to match A. Don't touch the lower limbs1080* because X might be aliased to B, and we must not overwrite the1081* significant digits of B. */1082if (A->n > n && A != X) {1083memcpy(X->p + n, A->p + n, (A->n - n) * ciL);1084}1085if (X->n > A->n) {1086memset(X->p + A->n, 0, (X->n - A->n) * ciL);1087}10881089carry = mbedtls_mpi_core_sub(X->p, A->p, B->p, n);1090if (carry != 0) {1091/* Propagate the carry through the rest of X. */1092carry = mbedtls_mpi_core_sub_int(X->p + n, X->p + n, carry, X->n - n);10931094/* If we have further carry/borrow, the result is negative. */1095if (carry != 0) {1096ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE;1097goto cleanup;1098}1099}11001101/* X should always be positive as a result of unsigned subtractions. */1102X->s = 1;11031104cleanup:1105return ret;1106}11071108/* Common function for signed addition and subtraction.1109* Calculate A + B * flip_B where flip_B is 1 or -1.1110*/1111static int add_sub_mpi(mbedtls_mpi *X,1112const mbedtls_mpi *A, const mbedtls_mpi *B,1113int flip_B)1114{1115int ret, s;11161117s = A->s;1118if (A->s * B->s * flip_B < 0) {1119int cmp = mbedtls_mpi_cmp_abs(A, B);1120if (cmp >= 0) {1121MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(X, A, B));1122/* If |A| = |B|, the result is 0 and we must set the sign bit1123* to +1 regardless of which of A or B was negative. Otherwise,1124* since |A| > |B|, the sign is the sign of A. */1125X->s = cmp == 0 ? 1 : s;1126} else {1127MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(X, B, A));1128/* Since |A| < |B|, the sign is the opposite of A. */1129X->s = -s;1130}1131} else {1132MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(X, A, B));1133X->s = s;1134}11351136cleanup:11371138return ret;1139}11401141/*1142* Signed addition: X = A + B1143*/1144int mbedtls_mpi_add_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)1145{1146return add_sub_mpi(X, A, B, 1);1147}11481149/*1150* Signed subtraction: X = A - B1151*/1152int mbedtls_mpi_sub_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)1153{1154return add_sub_mpi(X, A, B, -1);1155}11561157/*1158* Signed addition: X = A + b1159*/1160int mbedtls_mpi_add_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b)1161{1162mbedtls_mpi B;1163mbedtls_mpi_uint p[1];11641165p[0] = mpi_sint_abs(b);1166B.s = TO_SIGN(b);1167B.n = 1;1168B.p = p;11691170return mbedtls_mpi_add_mpi(X, A, &B);1171}11721173/*1174* Signed subtraction: X = A - b1175*/1176int mbedtls_mpi_sub_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b)1177{1178mbedtls_mpi B;1179mbedtls_mpi_uint p[1];11801181p[0] = mpi_sint_abs(b);1182B.s = TO_SIGN(b);1183B.n = 1;1184B.p = p;11851186return mbedtls_mpi_sub_mpi(X, A, &B);1187}11881189/*1190* Baseline multiplication: X = A * B (HAC 14.12)1191*/1192int mbedtls_mpi_mul_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)1193{1194int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;1195size_t i, j;1196mbedtls_mpi TA, TB;1197int result_is_zero = 0;11981199mbedtls_mpi_init(&TA);1200mbedtls_mpi_init(&TB);12011202if (X == A) {1203MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TA, A)); A = &TA;1204}1205if (X == B) {1206MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TB, B)); B = &TB;1207}12081209for (i = A->n; i > 0; i--) {1210if (A->p[i - 1] != 0) {1211break;1212}1213}1214if (i == 0) {1215result_is_zero = 1;1216}12171218for (j = B->n; j > 0; j--) {1219if (B->p[j - 1] != 0) {1220break;1221}1222}1223if (j == 0) {1224result_is_zero = 1;1225}12261227MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, i + j));1228MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 0));12291230mbedtls_mpi_core_mul(X->p, A->p, i, B->p, j);12311232/* If the result is 0, we don't shortcut the operation, which reduces1233* but does not eliminate side channels leaking the zero-ness. We do1234* need to take care to set the sign bit properly since the library does1235* not fully support an MPI object with a value of 0 and s == -1. */1236if (result_is_zero) {1237X->s = 1;1238} else {1239X->s = A->s * B->s;1240}12411242cleanup:12431244mbedtls_mpi_free(&TB); mbedtls_mpi_free(&TA);12451246return ret;1247}12481249/*1250* Baseline multiplication: X = A * b1251*/1252int mbedtls_mpi_mul_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b)1253{1254size_t n = A->n;1255while (n > 0 && A->p[n - 1] == 0) {1256--n;1257}12581259/* The general method below doesn't work if b==0. */1260if (b == 0 || n == 0) {1261return mbedtls_mpi_lset(X, 0);1262}12631264/* Calculate A*b as A + A*(b-1) to take advantage of mbedtls_mpi_core_mla */1265int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;1266/* In general, A * b requires 1 limb more than b. If1267* A->p[n - 1] * b / b == A->p[n - 1], then A * b fits in the same1268* number of limbs as A and the call to grow() is not required since1269* copy() will take care of the growth if needed. However, experimentally,1270* making the call to grow() unconditional causes slightly fewer1271* calls to calloc() in ECP code, presumably because it reuses the1272* same mpi for a while and this way the mpi is more likely to directly1273* grow to its final size.1274*1275* Note that calculating A*b as 0 + A*b doesn't work as-is because1276* A,X can be the same. */1277MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, n + 1));1278MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A));1279mbedtls_mpi_core_mla(X->p, X->n, A->p, n, b - 1);12801281cleanup:1282return ret;1283}12841285/*1286* Unsigned integer divide - double mbedtls_mpi_uint dividend, u1/u0, and1287* mbedtls_mpi_uint divisor, d1288*/1289static mbedtls_mpi_uint mbedtls_int_div_int(mbedtls_mpi_uint u1,1290mbedtls_mpi_uint u0,1291mbedtls_mpi_uint d,1292mbedtls_mpi_uint *r)1293{1294#if defined(MBEDTLS_HAVE_UDBL)1295mbedtls_t_udbl dividend, quotient;1296#else1297const mbedtls_mpi_uint radix = (mbedtls_mpi_uint) 1 << biH;1298const mbedtls_mpi_uint uint_halfword_mask = ((mbedtls_mpi_uint) 1 << biH) - 1;1299mbedtls_mpi_uint d0, d1, q0, q1, rAX, r0, quotient;1300mbedtls_mpi_uint u0_msw, u0_lsw;1301size_t s;1302#endif13031304/*1305* Check for overflow1306*/1307if (0 == d || u1 >= d) {1308if (r != NULL) {1309*r = ~(mbedtls_mpi_uint) 0u;1310}13111312return ~(mbedtls_mpi_uint) 0u;1313}13141315#if defined(MBEDTLS_HAVE_UDBL)1316dividend = (mbedtls_t_udbl) u1 << biL;1317dividend |= (mbedtls_t_udbl) u0;1318quotient = dividend / d;1319if (quotient > ((mbedtls_t_udbl) 1 << biL) - 1) {1320quotient = ((mbedtls_t_udbl) 1 << biL) - 1;1321}13221323if (r != NULL) {1324*r = (mbedtls_mpi_uint) (dividend - (quotient * d));1325}13261327return (mbedtls_mpi_uint) quotient;1328#else13291330/*1331* Algorithm D, Section 4.3.1 - The Art of Computer Programming1332* Vol. 2 - Seminumerical Algorithms, Knuth1333*/13341335/*1336* Normalize the divisor, d, and dividend, u0, u11337*/1338s = mbedtls_mpi_core_clz(d);1339d = d << s;13401341u1 = u1 << s;1342u1 |= (u0 >> (biL - s)) & (-(mbedtls_mpi_sint) s >> (biL - 1));1343u0 = u0 << s;13441345d1 = d >> biH;1346d0 = d & uint_halfword_mask;13471348u0_msw = u0 >> biH;1349u0_lsw = u0 & uint_halfword_mask;13501351/*1352* Find the first quotient and remainder1353*/1354q1 = u1 / d1;1355r0 = u1 - d1 * q1;13561357while (q1 >= radix || (q1 * d0 > radix * r0 + u0_msw)) {1358q1 -= 1;1359r0 += d1;13601361if (r0 >= radix) {1362break;1363}1364}13651366rAX = (u1 * radix) + (u0_msw - q1 * d);1367q0 = rAX / d1;1368r0 = rAX - q0 * d1;13691370while (q0 >= radix || (q0 * d0 > radix * r0 + u0_lsw)) {1371q0 -= 1;1372r0 += d1;13731374if (r0 >= radix) {1375break;1376}1377}13781379if (r != NULL) {1380*r = (rAX * radix + u0_lsw - q0 * d) >> s;1381}13821383quotient = q1 * radix + q0;13841385return quotient;1386#endif1387}13881389/*1390* Division by mbedtls_mpi: A = Q * B + R (HAC 14.20)1391*/1392int mbedtls_mpi_div_mpi(mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,1393const mbedtls_mpi *B)1394{1395int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;1396size_t i, n, t, k;1397mbedtls_mpi X, Y, Z, T1, T2;1398mbedtls_mpi_uint TP2[3];13991400if (mbedtls_mpi_cmp_int(B, 0) == 0) {1401return MBEDTLS_ERR_MPI_DIVISION_BY_ZERO;1402}14031404mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);1405mbedtls_mpi_init(&T1);1406/*1407* Avoid dynamic memory allocations for constant-size T2.1408*1409* T2 is used for comparison only and the 3 limbs are assigned explicitly,1410* so nobody increase the size of the MPI and we're safe to use an on-stack1411* buffer.1412*/1413T2.s = 1;1414T2.n = sizeof(TP2) / sizeof(*TP2);1415T2.p = TP2;14161417if (mbedtls_mpi_cmp_abs(A, B) < 0) {1418if (Q != NULL) {1419MBEDTLS_MPI_CHK(mbedtls_mpi_lset(Q, 0));1420}1421if (R != NULL) {1422MBEDTLS_MPI_CHK(mbedtls_mpi_copy(R, A));1423}1424return 0;1425}14261427MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&X, A));1428MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&Y, B));1429X.s = Y.s = 1;14301431MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&Z, A->n + 2));1432MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&Z, 0));1433MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&T1, A->n + 2));14341435k = mbedtls_mpi_bitlen(&Y) % biL;1436if (k < biL - 1) {1437k = biL - 1 - k;1438MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&X, k));1439MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&Y, k));1440} else {1441k = 0;1442}14431444n = X.n - 1;1445t = Y.n - 1;1446MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&Y, biL * (n - t)));14471448while (mbedtls_mpi_cmp_mpi(&X, &Y) >= 0) {1449Z.p[n - t]++;1450MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&X, &X, &Y));1451}1452MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&Y, biL * (n - t)));14531454for (i = n; i > t; i--) {1455if (X.p[i] >= Y.p[t]) {1456Z.p[i - t - 1] = ~(mbedtls_mpi_uint) 0u;1457} else {1458Z.p[i - t - 1] = mbedtls_int_div_int(X.p[i], X.p[i - 1],1459Y.p[t], NULL);1460}14611462T2.p[0] = (i < 2) ? 0 : X.p[i - 2];1463T2.p[1] = (i < 1) ? 0 : X.p[i - 1];1464T2.p[2] = X.p[i];14651466Z.p[i - t - 1]++;1467do {1468Z.p[i - t - 1]--;14691470MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&T1, 0));1471T1.p[0] = (t < 1) ? 0 : Y.p[t - 1];1472T1.p[1] = Y.p[t];1473MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(&T1, &T1, Z.p[i - t - 1]));1474} while (mbedtls_mpi_cmp_mpi(&T1, &T2) > 0);14751476MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(&T1, &Y, Z.p[i - t - 1]));1477MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&T1, biL * (i - t - 1)));1478MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&X, &X, &T1));14791480if (mbedtls_mpi_cmp_int(&X, 0) < 0) {1481MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&T1, &Y));1482MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&T1, biL * (i - t - 1)));1483MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&X, &X, &T1));1484Z.p[i - t - 1]--;1485}1486}14871488if (Q != NULL) {1489MBEDTLS_MPI_CHK(mbedtls_mpi_copy(Q, &Z));1490Q->s = A->s * B->s;1491}14921493if (R != NULL) {1494MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&X, k));1495X.s = A->s;1496MBEDTLS_MPI_CHK(mbedtls_mpi_copy(R, &X));14971498if (mbedtls_mpi_cmp_int(R, 0) == 0) {1499R->s = 1;1500}1501}15021503cleanup:15041505mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);1506mbedtls_mpi_free(&T1);1507mbedtls_platform_zeroize(TP2, sizeof(TP2));15081509return ret;1510}15111512/*1513* Division by int: A = Q * b + R1514*/1515int mbedtls_mpi_div_int(mbedtls_mpi *Q, mbedtls_mpi *R,1516const mbedtls_mpi *A,1517mbedtls_mpi_sint b)1518{1519mbedtls_mpi B;1520mbedtls_mpi_uint p[1];15211522p[0] = mpi_sint_abs(b);1523B.s = TO_SIGN(b);1524B.n = 1;1525B.p = p;15261527return mbedtls_mpi_div_mpi(Q, R, A, &B);1528}15291530/*1531* Modulo: R = A mod B1532*/1533int mbedtls_mpi_mod_mpi(mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B)1534{1535int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;15361537if (mbedtls_mpi_cmp_int(B, 0) < 0) {1538return MBEDTLS_ERR_MPI_NEGATIVE_VALUE;1539}15401541MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(NULL, R, A, B));15421543while (mbedtls_mpi_cmp_int(R, 0) < 0) {1544MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(R, R, B));1545}15461547while (mbedtls_mpi_cmp_mpi(R, B) >= 0) {1548MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(R, R, B));1549}15501551cleanup:15521553return ret;1554}15551556/*1557* Modulo: r = A mod b1558*/1559int mbedtls_mpi_mod_int(mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b)1560{1561size_t i;1562mbedtls_mpi_uint x, y, z;15631564if (b == 0) {1565return MBEDTLS_ERR_MPI_DIVISION_BY_ZERO;1566}15671568if (b < 0) {1569return MBEDTLS_ERR_MPI_NEGATIVE_VALUE;1570}15711572/*1573* handle trivial cases1574*/1575if (b == 1 || A->n == 0) {1576*r = 0;1577return 0;1578}15791580if (b == 2) {1581*r = A->p[0] & 1;1582return 0;1583}15841585/*1586* general case1587*/1588for (i = A->n, y = 0; i > 0; i--) {1589x = A->p[i - 1];1590y = (y << biH) | (x >> biH);1591z = y / b;1592y -= z * b;15931594x <<= biH;1595y = (y << biH) | (x >> biH);1596z = y / b;1597y -= z * b;1598}15991600/*1601* If A is negative, then the current y represents a negative value.1602* Flipping it to the positive side.1603*/1604if (A->s < 0 && y != 0) {1605y = b - y;1606}16071608*r = y;16091610return 0;1611}16121613/*1614* Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value,1615* this function is not constant time with respect to the exponent (parameter E).1616*/1617static int mbedtls_mpi_exp_mod_optionally_safe(mbedtls_mpi *X, const mbedtls_mpi *A,1618const mbedtls_mpi *E, int E_public,1619const mbedtls_mpi *N, mbedtls_mpi *prec_RR)1620{1621int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;16221623if (mbedtls_mpi_cmp_int(N, 0) <= 0 || (N->p[0] & 1) == 0) {1624return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;1625}16261627if (mbedtls_mpi_cmp_int(E, 0) < 0) {1628return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;1629}16301631if (mbedtls_mpi_bitlen(E) > MBEDTLS_MPI_MAX_BITS ||1632mbedtls_mpi_bitlen(N) > MBEDTLS_MPI_MAX_BITS) {1633return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;1634}16351636/*1637* Ensure that the exponent that we are passing to the core is not NULL.1638*/1639if (E->n == 0) {1640ret = mbedtls_mpi_lset(X, 1);1641return ret;1642}16431644/*1645* Allocate working memory for mbedtls_mpi_core_exp_mod()1646*/1647size_t T_limbs = mbedtls_mpi_core_exp_mod_working_limbs(N->n, E->n);1648mbedtls_mpi_uint *T = (mbedtls_mpi_uint *) mbedtls_calloc(T_limbs, sizeof(mbedtls_mpi_uint));1649if (T == NULL) {1650return MBEDTLS_ERR_MPI_ALLOC_FAILED;1651}16521653mbedtls_mpi RR;1654mbedtls_mpi_init(&RR);16551656/*1657* If 1st call, pre-compute R^2 mod N1658*/1659if (prec_RR == NULL || prec_RR->p == NULL) {1660MBEDTLS_MPI_CHK(mbedtls_mpi_core_get_mont_r2_unsafe(&RR, N));16611662if (prec_RR != NULL) {1663*prec_RR = RR;1664}1665} else {1666MBEDTLS_MPI_CHK(mbedtls_mpi_grow(prec_RR, N->n));1667RR = *prec_RR;1668}16691670/*1671* To preserve constness we need to make a copy of A. Using X for this to1672* save memory.1673*/1674MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A));16751676/*1677* Compensate for negative A (and correct at the end).1678*/1679X->s = 1;16801681/*1682* Make sure that X is in a form that is safe for consumption by1683* the core functions.1684*1685* - The core functions will not touch the limbs of X above N->n. The1686* result will be correct if those limbs are 0, which the mod call1687* ensures.1688* - Also, X must have at least as many limbs as N for the calls to the1689* core functions.1690*/1691if (mbedtls_mpi_cmp_mpi(X, N) >= 0) {1692MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(X, X, N));1693}1694MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, N->n));16951696/*1697* Convert to and from Montgomery around mbedtls_mpi_core_exp_mod().1698*/1699{1700mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N->p);1701mbedtls_mpi_core_to_mont_rep(X->p, X->p, N->p, N->n, mm, RR.p, T);1702if (E_public == MBEDTLS_MPI_IS_PUBLIC) {1703mbedtls_mpi_core_exp_mod_unsafe(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T);1704} else {1705mbedtls_mpi_core_exp_mod(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T);1706}1707mbedtls_mpi_core_from_mont_rep(X->p, X->p, N->p, N->n, mm, T);1708}17091710/*1711* Correct for negative A.1712*/1713if (A->s == -1 && (E->p[0] & 1) != 0) {1714mbedtls_ct_condition_t is_x_non_zero = mbedtls_mpi_core_check_zero_ct(X->p, X->n);1715X->s = mbedtls_ct_mpi_sign_if(is_x_non_zero, -1, 1);17161717MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(X, N, X));1718}17191720cleanup:17211722mbedtls_mpi_zeroize_and_free(T, T_limbs);17231724if (prec_RR == NULL || prec_RR->p == NULL) {1725mbedtls_mpi_free(&RR);1726}17271728return ret;1729}17301731int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,1732const mbedtls_mpi *E, const mbedtls_mpi *N,1733mbedtls_mpi *prec_RR)1734{1735return mbedtls_mpi_exp_mod_optionally_safe(X, A, E, MBEDTLS_MPI_IS_SECRET, N, prec_RR);1736}17371738int mbedtls_mpi_exp_mod_unsafe(mbedtls_mpi *X, const mbedtls_mpi *A,1739const mbedtls_mpi *E, const mbedtls_mpi *N,1740mbedtls_mpi *prec_RR)1741{1742return mbedtls_mpi_exp_mod_optionally_safe(X, A, E, MBEDTLS_MPI_IS_PUBLIC, N, prec_RR);1743}17441745/*1746* Greatest common divisor: G = gcd(A, B) (HAC 14.54)1747*/1748int mbedtls_mpi_gcd(mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B)1749{1750int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;1751size_t lz, lzt;1752mbedtls_mpi TA, TB;17531754mbedtls_mpi_init(&TA); mbedtls_mpi_init(&TB);17551756MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TA, A));1757MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TB, B));17581759lz = mbedtls_mpi_lsb(&TA);1760lzt = mbedtls_mpi_lsb(&TB);17611762/* The loop below gives the correct result when A==0 but not when B==0.1763* So have a special case for B==0. Leverage the fact that we just1764* calculated the lsb and lsb(B)==0 iff B is odd or 0 to make the test1765* slightly more efficient than cmp_int(). */1766if (lzt == 0 && mbedtls_mpi_get_bit(&TB, 0) == 0) {1767ret = mbedtls_mpi_copy(G, A);1768goto cleanup;1769}17701771if (lzt < lz) {1772lz = lzt;1773}17741775TA.s = TB.s = 1;17761777/* We mostly follow the procedure described in HAC 14.54, but with some1778* minor differences:1779* - Sequences of multiplications or divisions by 2 are grouped into a1780* single shift operation.1781* - The procedure in HAC assumes that 0 < TB <= TA.1782* - The condition TB <= TA is not actually necessary for correctness.1783* TA and TB have symmetric roles except for the loop termination1784* condition, and the shifts at the beginning of the loop body1785* remove any significance from the ordering of TA vs TB before1786* the shifts.1787* - If TA = 0, the loop goes through 0 iterations and the result is1788* correctly TB.1789* - The case TB = 0 was short-circuited above.1790*1791* For the correctness proof below, decompose the original values of1792* A and B as1793* A = sa * 2^a * A' with A'=0 or A' odd, and sa = +-11794* B = sb * 2^b * B' with B'=0 or B' odd, and sb = +-11795* Then gcd(A, B) = 2^{min(a,b)} * gcd(A',B'),1796* and gcd(A',B') is odd or 0.1797*1798* At the beginning, we have TA = |A| and TB = |B| so gcd(A,B) = gcd(TA,TB).1799* The code maintains the following invariant:1800* gcd(A,B) = 2^k * gcd(TA,TB) for some k (I)1801*/18021803/* Proof that the loop terminates:1804* At each iteration, either the right-shift by 1 is made on a nonzero1805* value and the nonnegative integer bitlen(TA) + bitlen(TB) decreases1806* by at least 1, or the right-shift by 1 is made on zero and then1807* TA becomes 0 which ends the loop (TB cannot be 0 if it is right-shifted1808* since in that case TB is calculated from TB-TA with the condition TB>TA).1809*/1810while (mbedtls_mpi_cmp_int(&TA, 0) != 0) {1811/* Divisions by 2 preserve the invariant (I). */1812MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TA, mbedtls_mpi_lsb(&TA)));1813MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TB, mbedtls_mpi_lsb(&TB)));18141815/* Set either TA or TB to |TA-TB|/2. Since TA and TB are both odd,1816* TA-TB is even so the division by 2 has an integer result.1817* Invariant (I) is preserved since any odd divisor of both TA and TB1818* also divides |TA-TB|/2, and any odd divisor of both TA and |TA-TB|/21819* also divides TB, and any odd divisor of both TB and |TA-TB|/2 also1820* divides TA.1821*/1822if (mbedtls_mpi_cmp_mpi(&TA, &TB) >= 0) {1823MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(&TA, &TA, &TB));1824MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TA, 1));1825} else {1826MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(&TB, &TB, &TA));1827MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TB, 1));1828}1829/* Note that one of TA or TB is still odd. */1830}18311832/* By invariant (I), gcd(A,B) = 2^k * gcd(TA,TB) for some k.1833* At the loop exit, TA = 0, so gcd(TA,TB) = TB.1834* - If there was at least one loop iteration, then one of TA or TB is odd,1835* and TA = 0, so TB is odd and gcd(TA,TB) = gcd(A',B'). In this case,1836* lz = min(a,b) so gcd(A,B) = 2^lz * TB.1837* - If there was no loop iteration, then A was 0, and gcd(A,B) = B.1838* In this case, lz = 0 and B = TB so gcd(A,B) = B = 2^lz * TB as well.1839*/18401841MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&TB, lz));1842MBEDTLS_MPI_CHK(mbedtls_mpi_copy(G, &TB));18431844cleanup:18451846mbedtls_mpi_free(&TA); mbedtls_mpi_free(&TB);18471848return ret;1849}18501851/*1852* Fill X with size bytes of random.1853* The bytes returned from the RNG are used in a specific order which1854* is suitable for deterministic ECDSA (see the specification of1855* mbedtls_mpi_random() and the implementation in mbedtls_mpi_fill_random()).1856*/1857int mbedtls_mpi_fill_random(mbedtls_mpi *X, size_t size,1858int (*f_rng)(void *, unsigned char *, size_t),1859void *p_rng)1860{1861int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;1862const size_t limbs = CHARS_TO_LIMBS(size);18631864/* Ensure that target MPI has exactly the necessary number of limbs */1865MBEDTLS_MPI_CHK(mbedtls_mpi_resize_clear(X, limbs));1866if (size == 0) {1867return 0;1868}18691870ret = mbedtls_mpi_core_fill_random(X->p, X->n, size, f_rng, p_rng);18711872cleanup:1873return ret;1874}18751876int mbedtls_mpi_random(mbedtls_mpi *X,1877mbedtls_mpi_sint min,1878const mbedtls_mpi *N,1879int (*f_rng)(void *, unsigned char *, size_t),1880void *p_rng)1881{1882if (min < 0) {1883return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;1884}1885if (mbedtls_mpi_cmp_int(N, min) <= 0) {1886return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;1887}18881889/* Ensure that target MPI has exactly the same number of limbs1890* as the upper bound, even if the upper bound has leading zeros.1891* This is necessary for mbedtls_mpi_core_random. */1892int ret = mbedtls_mpi_resize_clear(X, N->n);1893if (ret != 0) {1894return ret;1895}18961897return mbedtls_mpi_core_random(X->p, min, N->p, X->n, f_rng, p_rng);1898}18991900/*1901* Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)1902*/1903int mbedtls_mpi_inv_mod(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N)1904{1905int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;1906mbedtls_mpi G, TA, TU, U1, U2, TB, TV, V1, V2;19071908if (mbedtls_mpi_cmp_int(N, 1) <= 0) {1909return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;1910}19111912mbedtls_mpi_init(&TA); mbedtls_mpi_init(&TU); mbedtls_mpi_init(&U1); mbedtls_mpi_init(&U2);1913mbedtls_mpi_init(&G); mbedtls_mpi_init(&TB); mbedtls_mpi_init(&TV);1914mbedtls_mpi_init(&V1); mbedtls_mpi_init(&V2);19151916MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(&G, A, N));19171918if (mbedtls_mpi_cmp_int(&G, 1) != 0) {1919ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;1920goto cleanup;1921}19221923MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&TA, A, N));1924MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TU, &TA));1925MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TB, N));1926MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TV, N));19271928MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&U1, 1));1929MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&U2, 0));1930MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&V1, 0));1931MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&V2, 1));19321933do {1934while ((TU.p[0] & 1) == 0) {1935MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TU, 1));19361937if ((U1.p[0] & 1) != 0 || (U2.p[0] & 1) != 0) {1938MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&U1, &U1, &TB));1939MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&U2, &U2, &TA));1940}19411942MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&U1, 1));1943MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&U2, 1));1944}19451946while ((TV.p[0] & 1) == 0) {1947MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TV, 1));19481949if ((V1.p[0] & 1) != 0 || (V2.p[0] & 1) != 0) {1950MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&V1, &V1, &TB));1951MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&V2, &V2, &TA));1952}19531954MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&V1, 1));1955MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&V2, 1));1956}19571958if (mbedtls_mpi_cmp_mpi(&TU, &TV) >= 0) {1959MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&TU, &TU, &TV));1960MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&U1, &U1, &V1));1961MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&U2, &U2, &V2));1962} else {1963MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&TV, &TV, &TU));1964MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&V1, &V1, &U1));1965MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&V2, &V2, &U2));1966}1967} while (mbedtls_mpi_cmp_int(&TU, 0) != 0);19681969while (mbedtls_mpi_cmp_int(&V1, 0) < 0) {1970MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&V1, &V1, N));1971}19721973while (mbedtls_mpi_cmp_mpi(&V1, N) >= 0) {1974MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&V1, &V1, N));1975}19761977MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, &V1));19781979cleanup:19801981mbedtls_mpi_free(&TA); mbedtls_mpi_free(&TU); mbedtls_mpi_free(&U1); mbedtls_mpi_free(&U2);1982mbedtls_mpi_free(&G); mbedtls_mpi_free(&TB); mbedtls_mpi_free(&TV);1983mbedtls_mpi_free(&V1); mbedtls_mpi_free(&V2);19841985return ret;1986}19871988#if defined(MBEDTLS_GENPRIME)19891990/* Gaps between primes, starting at 3. https://oeis.org/A001223 */1991static const unsigned char small_prime_gaps[] = {19922, 2, 4, 2, 4, 2, 4, 6,19932, 6, 4, 2, 4, 6, 6, 2,19946, 4, 2, 6, 4, 6, 8, 4,19952, 4, 2, 4, 14, 4, 6, 2,199610, 2, 6, 6, 4, 6, 6, 2,199710, 2, 4, 2, 12, 12, 4, 2,19984, 6, 2, 10, 6, 6, 6, 2,19996, 4, 2, 10, 14, 4, 2, 4,200014, 6, 10, 2, 4, 6, 8, 6,20016, 4, 6, 8, 4, 8, 10, 2,200210, 2, 6, 4, 6, 8, 4, 2,20034, 12, 8, 4, 8, 4, 6, 12,20042, 18, 6, 10, 6, 6, 2, 6,200510, 6, 6, 2, 6, 6, 4, 2,200612, 10, 2, 4, 6, 6, 2, 12,20074, 6, 8, 10, 8, 10, 8, 6,20086, 4, 8, 6, 4, 8, 4, 14,200910, 12, 2, 10, 2, 4, 2, 10,201014, 4, 2, 4, 14, 4, 2, 4,201120, 4, 8, 10, 8, 4, 6, 6,201214, 4, 6, 6, 8, 6, /*reaches 997*/20130 /* the last entry is effectively unused */2014};20152016/*2017* Small divisors test (X must be positive)2018*2019* Return values:2020* 0: no small factor (possible prime, more tests needed)2021* 1: certain prime2022* MBEDTLS_ERR_MPI_NOT_ACCEPTABLE: certain non-prime2023* other negative: error2024*/2025static int mpi_check_small_factors(const mbedtls_mpi *X)2026{2027int ret = 0;2028size_t i;2029mbedtls_mpi_uint r;2030unsigned p = 3; /* The first odd prime */20312032if ((X->p[0] & 1) == 0) {2033return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;2034}20352036for (i = 0; i < sizeof(small_prime_gaps); p += small_prime_gaps[i], i++) {2037MBEDTLS_MPI_CHK(mbedtls_mpi_mod_int(&r, X, p));2038if (r == 0) {2039if (mbedtls_mpi_cmp_int(X, p) == 0) {2040return 1;2041} else {2042return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;2043}2044}2045}20462047cleanup:2048return ret;2049}20502051/*2052* Miller-Rabin pseudo-primality test (HAC 4.24)2053*/2054static int mpi_miller_rabin(const mbedtls_mpi *X, size_t rounds,2055int (*f_rng)(void *, unsigned char *, size_t),2056void *p_rng)2057{2058int ret, count;2059size_t i, j, k, s;2060mbedtls_mpi W, R, T, A, RR;20612062mbedtls_mpi_init(&W); mbedtls_mpi_init(&R);2063mbedtls_mpi_init(&T); mbedtls_mpi_init(&A);2064mbedtls_mpi_init(&RR);20652066/*2067* W = |X| - 12068* R = W >> lsb( W )2069*/2070MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&W, X, 1));2071s = mbedtls_mpi_lsb(&W);2072MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&R, &W));2073MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&R, s));20742075for (i = 0; i < rounds; i++) {2076/*2077* pick a random A, 1 < A < |X| - 12078*/2079count = 0;2080do {2081MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&A, X->n * ciL, f_rng, p_rng));20822083j = mbedtls_mpi_bitlen(&A);2084k = mbedtls_mpi_bitlen(&W);2085if (j > k) {2086A.p[A.n - 1] &= ((mbedtls_mpi_uint) 1 << (k - (A.n - 1) * biL - 1)) - 1;2087}20882089if (count++ > 30) {2090ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;2091goto cleanup;2092}20932094} while (mbedtls_mpi_cmp_mpi(&A, &W) >= 0 ||2095mbedtls_mpi_cmp_int(&A, 1) <= 0);20962097/*2098* A = A^R mod |X|2099*/2100MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&A, &A, &R, X, &RR));21012102if (mbedtls_mpi_cmp_mpi(&A, &W) == 0 ||2103mbedtls_mpi_cmp_int(&A, 1) == 0) {2104continue;2105}21062107j = 1;2108while (j < s && mbedtls_mpi_cmp_mpi(&A, &W) != 0) {2109/*2110* A = A * A mod |X|2111*/2112MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&T, &A, &A));2113MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&A, &T, X));21142115if (mbedtls_mpi_cmp_int(&A, 1) == 0) {2116break;2117}21182119j++;2120}21212122/*2123* not prime if A != |X| - 1 or A == 12124*/2125if (mbedtls_mpi_cmp_mpi(&A, &W) != 0 ||2126mbedtls_mpi_cmp_int(&A, 1) == 0) {2127ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;2128break;2129}2130}21312132cleanup:2133mbedtls_mpi_free(&W); mbedtls_mpi_free(&R);2134mbedtls_mpi_free(&T); mbedtls_mpi_free(&A);2135mbedtls_mpi_free(&RR);21362137return ret;2138}21392140/*2141* Pseudo-primality test: small factors, then Miller-Rabin2142*/2143int mbedtls_mpi_is_prime_ext(const mbedtls_mpi *X, int rounds,2144int (*f_rng)(void *, unsigned char *, size_t),2145void *p_rng)2146{2147int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;2148mbedtls_mpi XX;21492150XX.s = 1;2151XX.n = X->n;2152XX.p = X->p;21532154if (mbedtls_mpi_cmp_int(&XX, 0) == 0 ||2155mbedtls_mpi_cmp_int(&XX, 1) == 0) {2156return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;2157}21582159if (mbedtls_mpi_cmp_int(&XX, 2) == 0) {2160return 0;2161}21622163if ((ret = mpi_check_small_factors(&XX)) != 0) {2164if (ret == 1) {2165return 0;2166}21672168return ret;2169}21702171return mpi_miller_rabin(&XX, rounds, f_rng, p_rng);2172}21732174/*2175* Prime number generation2176*2177* To generate an RSA key in a way recommended by FIPS 186-4, both primes must2178* be either 1024 bits or 1536 bits long, and flags must contain2179* MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR.2180*/2181int mbedtls_mpi_gen_prime(mbedtls_mpi *X, size_t nbits, int flags,2182int (*f_rng)(void *, unsigned char *, size_t),2183void *p_rng)2184{2185#ifdef MBEDTLS_HAVE_INT642186// ceil(2^63.5)2187#define CEIL_MAXUINT_DIV_SQRT2 0xb504f333f9de6485ULL2188#else2189// ceil(2^31.5)2190#define CEIL_MAXUINT_DIV_SQRT2 0xb504f334U2191#endif2192int ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;2193size_t k, n;2194int rounds;2195mbedtls_mpi_uint r;2196mbedtls_mpi Y;21972198if (nbits < 3 || nbits > MBEDTLS_MPI_MAX_BITS) {2199return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;2200}22012202mbedtls_mpi_init(&Y);22032204n = BITS_TO_LIMBS(nbits);22052206if ((flags & MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR) == 0) {2207/*2208* 2^-80 error probability, number of rounds chosen per HAC, table 4.42209*/2210rounds = ((nbits >= 1300) ? 2 : (nbits >= 850) ? 3 :2211(nbits >= 650) ? 4 : (nbits >= 350) ? 8 :2212(nbits >= 250) ? 12 : (nbits >= 150) ? 18 : 27);2213} else {2214/*2215* 2^-100 error probability, number of rounds computed based on HAC,2216* fact 4.482217*/2218rounds = ((nbits >= 1450) ? 4 : (nbits >= 1150) ? 5 :2219(nbits >= 1000) ? 6 : (nbits >= 850) ? 7 :2220(nbits >= 750) ? 8 : (nbits >= 500) ? 13 :2221(nbits >= 250) ? 28 : (nbits >= 150) ? 40 : 51);2222}22232224while (1) {2225MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(X, n * ciL, f_rng, p_rng));2226/* make sure generated number is at least (nbits-1)+0.5 bits (FIPS 186-4 §B.3.3 steps 4.4, 5.5) */2227if (X->p[n-1] < CEIL_MAXUINT_DIV_SQRT2) {2228continue;2229}22302231k = n * biL;2232if (k > nbits) {2233MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(X, k - nbits));2234}2235X->p[0] |= 1;22362237if ((flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH) == 0) {2238ret = mbedtls_mpi_is_prime_ext(X, rounds, f_rng, p_rng);22392240if (ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) {2241goto cleanup;2242}2243} else {2244/*2245* A necessary condition for Y and X = 2Y + 1 to be prime2246* is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).2247* Make sure it is satisfied, while keeping X = 3 mod 42248*/22492250X->p[0] |= 2;22512252MBEDTLS_MPI_CHK(mbedtls_mpi_mod_int(&r, X, 3));2253if (r == 0) {2254MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, X, 8));2255} else if (r == 1) {2256MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, X, 4));2257}22582259/* Set Y = (X-1) / 2, which is X / 2 because X is odd */2260MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&Y, X));2261MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&Y, 1));22622263while (1) {2264/*2265* First, check small factors for X and Y2266* before doing Miller-Rabin on any of them2267*/2268if ((ret = mpi_check_small_factors(X)) == 0 &&2269(ret = mpi_check_small_factors(&Y)) == 0 &&2270(ret = mpi_miller_rabin(X, rounds, f_rng, p_rng))2271== 0 &&2272(ret = mpi_miller_rabin(&Y, rounds, f_rng, p_rng))2273== 0) {2274goto cleanup;2275}22762277if (ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) {2278goto cleanup;2279}22802281/*2282* Next candidates. We want to preserve Y = (X-1) / 2 and2283* Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)2284* so up Y by 6 and X by 12.2285*/2286MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, X, 12));2287MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&Y, &Y, 6));2288}2289}2290}22912292cleanup:22932294mbedtls_mpi_free(&Y);22952296return ret;2297}22982299#endif /* MBEDTLS_GENPRIME */23002301#if defined(MBEDTLS_SELF_TEST)23022303#define GCD_PAIR_COUNT 323042305static const int gcd_pairs[GCD_PAIR_COUNT][3] =2306{2307{ 693, 609, 21 },2308{ 1764, 868, 28 },2309{ 768454923, 542167814, 1 }2310};23112312/*2313* Checkup routine2314*/2315int mbedtls_mpi_self_test(int verbose)2316{2317int ret, i;2318mbedtls_mpi A, E, N, X, Y, U, V;23192320mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N); mbedtls_mpi_init(&X);2321mbedtls_mpi_init(&Y); mbedtls_mpi_init(&U); mbedtls_mpi_init(&V);23222323MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&A, 16,2324"EFE021C2645FD1DC586E69184AF4A31E" \2325"D5F53E93B5F123FA41680867BA110131" \2326"944FE7952E2517337780CB0DB80E61AA" \2327"E7C8DDC6C5C6AADEB34EB38A2F40D5E6"));23282329MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&E, 16,2330"B2E7EFD37075B9F03FF989C7C5051C20" \2331"34D2A323810251127E7BF8625A4F49A5" \2332"F3E27F4DA8BD59C47D6DAABA4C8127BD" \2333"5B5C25763222FEFCCFC38B832366C29E"));23342335MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&N, 16,2336"0066A198186C18C10B2F5ED9B522752A" \2337"9830B69916E535C8F047518A889A43A5" \2338"94B6BED27A168D31D4A52F88925AA8F5"));23392340MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&X, &A, &N));23412342MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16,2343"602AB7ECA597A3D6B56FF9829A5E8B85" \2344"9E857EA95A03512E2BAE7391688D264A" \2345"A5663B0341DB9CCFD2C4C5F421FEC814" \2346"8001B72E848A38CAE1C65F78E56ABDEF" \2347"E12D3C039B8A02D6BE593F0BBBDA56F1" \2348"ECF677152EF804370C1A305CAF3B5BF1" \2349"30879B56C61DE584A0F53A2447A51E"));23502351if (verbose != 0) {2352mbedtls_printf(" MPI test #1 (mul_mpi): ");2353}23542355if (mbedtls_mpi_cmp_mpi(&X, &U) != 0) {2356if (verbose != 0) {2357mbedtls_printf("failed\n");2358}23592360ret = 1;2361goto cleanup;2362}23632364if (verbose != 0) {2365mbedtls_printf("passed\n");2366}23672368MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(&X, &Y, &A, &N));23692370MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16,2371"256567336059E52CAE22925474705F39A94"));23722373MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&V, 16,2374"6613F26162223DF488E9CD48CC132C7A" \2375"0AC93C701B001B092E4E5B9F73BCD27B" \2376"9EE50D0657C77F374E903CDFA4C642"));23772378if (verbose != 0) {2379mbedtls_printf(" MPI test #2 (div_mpi): ");2380}23812382if (mbedtls_mpi_cmp_mpi(&X, &U) != 0 ||2383mbedtls_mpi_cmp_mpi(&Y, &V) != 0) {2384if (verbose != 0) {2385mbedtls_printf("failed\n");2386}23872388ret = 1;2389goto cleanup;2390}23912392if (verbose != 0) {2393mbedtls_printf("passed\n");2394}23952396MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&X, &A, &E, &N, NULL));23972398MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16,2399"36E139AEA55215609D2816998ED020BB" \2400"BD96C37890F65171D948E9BC7CBAA4D9" \2401"325D24D6A3C12710F10A09FA08AB87"));24022403if (verbose != 0) {2404mbedtls_printf(" MPI test #3 (exp_mod): ");2405}24062407if (mbedtls_mpi_cmp_mpi(&X, &U) != 0) {2408if (verbose != 0) {2409mbedtls_printf("failed\n");2410}24112412ret = 1;2413goto cleanup;2414}24152416if (verbose != 0) {2417mbedtls_printf("passed\n");2418}24192420MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&X, &A, &N));24212422MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16,2423"003A0AAEDD7E784FC07D8F9EC6E3BFD5" \2424"C3DBA76456363A10869622EAC2DD84EC" \2425"C5B8A74DAC4D09E03B5E0BE779F2DF61"));24262427if (verbose != 0) {2428mbedtls_printf(" MPI test #4 (inv_mod): ");2429}24302431if (mbedtls_mpi_cmp_mpi(&X, &U) != 0) {2432if (verbose != 0) {2433mbedtls_printf("failed\n");2434}24352436ret = 1;2437goto cleanup;2438}24392440if (verbose != 0) {2441mbedtls_printf("passed\n");2442}24432444if (verbose != 0) {2445mbedtls_printf(" MPI test #5 (simple gcd): ");2446}24472448for (i = 0; i < GCD_PAIR_COUNT; i++) {2449MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&X, gcd_pairs[i][0]));2450MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&Y, gcd_pairs[i][1]));24512452MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(&A, &X, &Y));24532454if (mbedtls_mpi_cmp_int(&A, gcd_pairs[i][2]) != 0) {2455if (verbose != 0) {2456mbedtls_printf("failed at %d\n", i);2457}24582459ret = 1;2460goto cleanup;2461}2462}24632464if (verbose != 0) {2465mbedtls_printf("passed\n");2466}24672468cleanup:24692470if (ret != 0 && verbose != 0) {2471mbedtls_printf("Unexpected error, return code = %08X\n", (unsigned int) ret);2472}24732474mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N); mbedtls_mpi_free(&X);2475mbedtls_mpi_free(&Y); mbedtls_mpi_free(&U); mbedtls_mpi_free(&V);24762477if (verbose != 0) {2478mbedtls_printf("\n");2479}24802481return ret;2482}24832484#endif /* MBEDTLS_SELF_TEST */24852486#endif /* MBEDTLS_BIGNUM_C */248724882489