Path: blob/master/thirdparty/mbedtls/library/bignum.c
21794 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#if defined(__has_builtin)433#if (MBEDTLS_MPI_UINT_MAX == UINT_MAX) && __has_builtin(__builtin_ctz)434#define mbedtls_mpi_uint_ctz __builtin_ctz435#elif (MBEDTLS_MPI_UINT_MAX == ULONG_MAX) && __has_builtin(__builtin_ctzl)436#define mbedtls_mpi_uint_ctz __builtin_ctzl437#elif (MBEDTLS_MPI_UINT_MAX == ULLONG_MAX) && __has_builtin(__builtin_ctzll)438#define mbedtls_mpi_uint_ctz __builtin_ctzll439#endif440#endif441442#if !defined(mbedtls_mpi_uint_ctz)443static size_t mbedtls_mpi_uint_ctz(mbedtls_mpi_uint x)444{445size_t count = 0;446mbedtls_ct_condition_t done = MBEDTLS_CT_FALSE;447448for (size_t i = 0; i < biL; i++) {449mbedtls_ct_condition_t non_zero = mbedtls_ct_bool((x >> i) & 1);450done = mbedtls_ct_bool_or(done, non_zero);451count = mbedtls_ct_size_if(done, count, i + 1);452}453454return count;455}456#endif457458/*459* Return the number of less significant zero-bits460*/461size_t mbedtls_mpi_lsb(const mbedtls_mpi *X)462{463size_t i;464465for (i = 0; i < X->n; i++) {466if (X->p[i] != 0) {467return i * biL + mbedtls_mpi_uint_ctz(X->p[i]);468}469}470471return 0;472}473474/*475* Return the number of bits476*/477size_t mbedtls_mpi_bitlen(const mbedtls_mpi *X)478{479return mbedtls_mpi_core_bitlen(X->p, X->n);480}481482/*483* Return the total size in bytes484*/485size_t mbedtls_mpi_size(const mbedtls_mpi *X)486{487return (mbedtls_mpi_bitlen(X) + 7) >> 3;488}489490/*491* Convert an ASCII character to digit value492*/493static int mpi_get_digit(mbedtls_mpi_uint *d, int radix, char c)494{495*d = 255;496497if (c >= 0x30 && c <= 0x39) {498*d = c - 0x30;499}500if (c >= 0x41 && c <= 0x46) {501*d = c - 0x37;502}503if (c >= 0x61 && c <= 0x66) {504*d = c - 0x57;505}506507if (*d >= (mbedtls_mpi_uint) radix) {508return MBEDTLS_ERR_MPI_INVALID_CHARACTER;509}510511return 0;512}513514/*515* Import from an ASCII string516*/517int mbedtls_mpi_read_string(mbedtls_mpi *X, int radix, const char *s)518{519int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;520size_t i, j, slen, n;521int sign = 1;522mbedtls_mpi_uint d;523mbedtls_mpi T;524525if (radix < 2 || radix > 16) {526return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;527}528529mbedtls_mpi_init(&T);530531if (s[0] == 0) {532mbedtls_mpi_free(X);533return 0;534}535536if (s[0] == '-') {537++s;538sign = -1;539}540541slen = strlen(s);542543if (radix == 16) {544if (slen > SIZE_MAX >> 2) {545return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;546}547548n = BITS_TO_LIMBS(slen << 2);549550MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, n));551MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 0));552553for (i = slen, j = 0; i > 0; i--, j++) {554MBEDTLS_MPI_CHK(mpi_get_digit(&d, radix, s[i - 1]));555X->p[j / (2 * ciL)] |= d << ((j % (2 * ciL)) << 2);556}557} else {558MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 0));559560for (i = 0; i < slen; i++) {561MBEDTLS_MPI_CHK(mpi_get_digit(&d, radix, s[i]));562MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(&T, X, radix));563MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, &T, d));564}565}566567if (sign < 0 && mbedtls_mpi_bitlen(X) != 0) {568X->s = -1;569}570571cleanup:572573mbedtls_mpi_free(&T);574575return ret;576}577578/*579* Helper to write the digits high-order first.580*/581static int mpi_write_hlp(mbedtls_mpi *X, int radix,582char **p, const size_t buflen)583{584int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;585mbedtls_mpi_uint r;586size_t length = 0;587char *p_end = *p + buflen;588589do {590if (length >= buflen) {591return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL;592}593594MBEDTLS_MPI_CHK(mbedtls_mpi_mod_int(&r, X, radix));595MBEDTLS_MPI_CHK(mbedtls_mpi_div_int(X, NULL, X, radix));596/*597* Write the residue in the current position, as an ASCII character.598*/599if (r < 0xA) {600*(--p_end) = (char) ('0' + r);601} else {602*(--p_end) = (char) ('A' + (r - 0xA));603}604605length++;606} while (mbedtls_mpi_cmp_int(X, 0) != 0);607608memmove(*p, p_end, length);609*p += length;610611cleanup:612613return ret;614}615616/*617* Export into an ASCII string618*/619int mbedtls_mpi_write_string(const mbedtls_mpi *X, int radix,620char *buf, size_t buflen, size_t *olen)621{622int ret = 0;623size_t n;624char *p;625mbedtls_mpi T;626627if (radix < 2 || radix > 16) {628return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;629}630631n = mbedtls_mpi_bitlen(X); /* Number of bits necessary to present `n`. */632if (radix >= 4) {633n >>= 1; /* Number of 4-adic digits necessary to present634* `n`. If radix > 4, this might be a strict635* overapproximation of the number of636* radix-adic digits needed to present `n`. */637}638if (radix >= 16) {639n >>= 1; /* Number of hexadecimal digits necessary to640* present `n`. */641642}643n += 1; /* Terminating null byte */644n += 1; /* Compensate for the divisions above, which round down `n`645* in case it's not even. */646n += 1; /* Potential '-'-sign. */647n += (n & 1); /* Make n even to have enough space for hexadecimal writing,648* which always uses an even number of hex-digits. */649650if (buflen < n) {651*olen = n;652return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL;653}654655p = buf;656mbedtls_mpi_init(&T);657658if (X->s == -1) {659*p++ = '-';660buflen--;661}662663if (radix == 16) {664int c;665size_t i, j, k;666667for (i = X->n, k = 0; i > 0; i--) {668for (j = ciL; j > 0; j--) {669c = (X->p[i - 1] >> ((j - 1) << 3)) & 0xFF;670671if (c == 0 && k == 0 && (i + j) != 2) {672continue;673}674675*(p++) = "0123456789ABCDEF" [c / 16];676*(p++) = "0123456789ABCDEF" [c % 16];677k = 1;678}679}680} else {681MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&T, X));682683if (T.s == -1) {684T.s = 1;685}686687MBEDTLS_MPI_CHK(mpi_write_hlp(&T, radix, &p, buflen));688}689690*p++ = '\0';691*olen = (size_t) (p - buf);692693cleanup:694695mbedtls_mpi_free(&T);696697return ret;698}699700#if defined(MBEDTLS_FS_IO)701/*702* Read X from an opened file703*/704int mbedtls_mpi_read_file(mbedtls_mpi *X, int radix, FILE *fin)705{706mbedtls_mpi_uint d;707size_t slen;708char *p;709/*710* Buffer should have space for (short) label and decimal formatted MPI,711* newline characters and '\0'712*/713char s[MBEDTLS_MPI_RW_BUFFER_SIZE];714715if (radix < 2 || radix > 16) {716return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;717}718719memset(s, 0, sizeof(s));720if (fgets(s, sizeof(s) - 1, fin) == NULL) {721return MBEDTLS_ERR_MPI_FILE_IO_ERROR;722}723724slen = strlen(s);725if (slen == sizeof(s) - 2) {726return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL;727}728729if (slen > 0 && s[slen - 1] == '\n') {730slen--; s[slen] = '\0';731}732if (slen > 0 && s[slen - 1] == '\r') {733slen--; s[slen] = '\0';734}735736p = s + slen;737while (p-- > s) {738if (mpi_get_digit(&d, radix, *p) != 0) {739break;740}741}742743return mbedtls_mpi_read_string(X, radix, p + 1);744}745746/*747* Write X into an opened file (or stdout if fout == NULL)748*/749int mbedtls_mpi_write_file(const char *p, const mbedtls_mpi *X, int radix, FILE *fout)750{751int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;752size_t n, slen, plen;753/*754* Buffer should have space for (short) label and decimal formatted MPI,755* newline characters and '\0'756*/757char s[MBEDTLS_MPI_RW_BUFFER_SIZE];758759if (radix < 2 || radix > 16) {760return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;761}762763memset(s, 0, sizeof(s));764765MBEDTLS_MPI_CHK(mbedtls_mpi_write_string(X, radix, s, sizeof(s) - 2, &n));766767if (p == NULL) {768p = "";769}770771plen = strlen(p);772slen = strlen(s);773s[slen++] = '\r';774s[slen++] = '\n';775776if (fout != NULL) {777if (fwrite(p, 1, plen, fout) != plen ||778fwrite(s, 1, slen, fout) != slen) {779return MBEDTLS_ERR_MPI_FILE_IO_ERROR;780}781} else {782mbedtls_printf("%s%s", p, s);783}784785cleanup:786787return ret;788}789#endif /* MBEDTLS_FS_IO */790791/*792* Import X from unsigned binary data, little endian793*794* This function is guaranteed to return an MPI with exactly the necessary795* number of limbs (in particular, it does not skip 0s in the input).796*/797int mbedtls_mpi_read_binary_le(mbedtls_mpi *X,798const unsigned char *buf, size_t buflen)799{800int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;801const size_t limbs = CHARS_TO_LIMBS(buflen);802803/* Ensure that target MPI has exactly the necessary number of limbs */804MBEDTLS_MPI_CHK(mbedtls_mpi_resize_clear(X, limbs));805806MBEDTLS_MPI_CHK(mbedtls_mpi_core_read_le(X->p, X->n, buf, buflen));807808cleanup:809810/*811* This function is also used to import keys. However, wiping the buffers812* upon failure is not necessary because failure only can happen before any813* input is copied.814*/815return ret;816}817818/*819* Import X from unsigned binary data, big endian820*821* This function is guaranteed to return an MPI with exactly the necessary822* number of limbs (in particular, it does not skip 0s in the input).823*/824int mbedtls_mpi_read_binary(mbedtls_mpi *X, const unsigned char *buf, size_t buflen)825{826int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;827const size_t limbs = CHARS_TO_LIMBS(buflen);828829/* Ensure that target MPI has exactly the necessary number of limbs */830MBEDTLS_MPI_CHK(mbedtls_mpi_resize_clear(X, limbs));831832MBEDTLS_MPI_CHK(mbedtls_mpi_core_read_be(X->p, X->n, buf, buflen));833834cleanup:835836/*837* This function is also used to import keys. However, wiping the buffers838* upon failure is not necessary because failure only can happen before any839* input is copied.840*/841return ret;842}843844/*845* Export X into unsigned binary data, little endian846*/847int mbedtls_mpi_write_binary_le(const mbedtls_mpi *X,848unsigned char *buf, size_t buflen)849{850return mbedtls_mpi_core_write_le(X->p, X->n, buf, buflen);851}852853/*854* Export X into unsigned binary data, big endian855*/856int mbedtls_mpi_write_binary(const mbedtls_mpi *X,857unsigned char *buf, size_t buflen)858{859return mbedtls_mpi_core_write_be(X->p, X->n, buf, buflen);860}861862/*863* Left-shift: X <<= count864*/865int mbedtls_mpi_shift_l(mbedtls_mpi *X, size_t count)866{867int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;868size_t i;869870i = mbedtls_mpi_bitlen(X) + count;871872if (X->n * biL < i) {873MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, BITS_TO_LIMBS(i)));874}875876ret = 0;877878mbedtls_mpi_core_shift_l(X->p, X->n, count);879cleanup:880881return ret;882}883884/*885* Right-shift: X >>= count886*/887int mbedtls_mpi_shift_r(mbedtls_mpi *X, size_t count)888{889if (X->n != 0) {890mbedtls_mpi_core_shift_r(X->p, X->n, count);891}892return 0;893}894895/*896* Compare unsigned values897*/898int mbedtls_mpi_cmp_abs(const mbedtls_mpi *X, const mbedtls_mpi *Y)899{900size_t i, j;901902for (i = X->n; i > 0; i--) {903if (X->p[i - 1] != 0) {904break;905}906}907908for (j = Y->n; j > 0; j--) {909if (Y->p[j - 1] != 0) {910break;911}912}913914/* If i == j == 0, i.e. abs(X) == abs(Y),915* we end up returning 0 at the end of the function. */916917if (i > j) {918return 1;919}920if (j > i) {921return -1;922}923924for (; i > 0; i--) {925if (X->p[i - 1] > Y->p[i - 1]) {926return 1;927}928if (X->p[i - 1] < Y->p[i - 1]) {929return -1;930}931}932933return 0;934}935936/*937* Compare signed values938*/939int mbedtls_mpi_cmp_mpi(const mbedtls_mpi *X, const mbedtls_mpi *Y)940{941size_t i, j;942943for (i = X->n; i > 0; i--) {944if (X->p[i - 1] != 0) {945break;946}947}948949for (j = Y->n; j > 0; j--) {950if (Y->p[j - 1] != 0) {951break;952}953}954955if (i == 0 && j == 0) {956return 0;957}958959if (i > j) {960return X->s;961}962if (j > i) {963return -Y->s;964}965966if (X->s > 0 && Y->s < 0) {967return 1;968}969if (Y->s > 0 && X->s < 0) {970return -1;971}972973for (; i > 0; i--) {974if (X->p[i - 1] > Y->p[i - 1]) {975return X->s;976}977if (X->p[i - 1] < Y->p[i - 1]) {978return -X->s;979}980}981982return 0;983}984985/*986* Compare signed values987*/988int mbedtls_mpi_cmp_int(const mbedtls_mpi *X, mbedtls_mpi_sint z)989{990mbedtls_mpi Y;991mbedtls_mpi_uint p[1];992993*p = mpi_sint_abs(z);994Y.s = TO_SIGN(z);995Y.n = 1;996Y.p = p;997998return mbedtls_mpi_cmp_mpi(X, &Y);999}10001001/*1002* Unsigned addition: X = |A| + |B| (HAC 14.7)1003*/1004int mbedtls_mpi_add_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)1005{1006int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;1007size_t j;1008mbedtls_mpi_uint *p;1009mbedtls_mpi_uint c;10101011if (X == B) {1012const mbedtls_mpi *T = A; A = X; B = T;1013}10141015if (X != A) {1016MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A));1017}10181019/*1020* X must always be positive as a result of unsigned additions.1021*/1022X->s = 1;10231024for (j = B->n; j > 0; j--) {1025if (B->p[j - 1] != 0) {1026break;1027}1028}10291030/* Exit early to avoid undefined behavior on NULL+0 when X->n == 01031* and B is 0 (of any size). */1032if (j == 0) {1033return 0;1034}10351036MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, j));10371038/* j is the number of non-zero limbs of B. Add those to X. */10391040p = X->p;10411042c = mbedtls_mpi_core_add(p, p, B->p, j);10431044p += j;10451046/* Now propagate any carry */10471048while (c != 0) {1049if (j >= X->n) {1050MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, j + 1));1051p = X->p + j;1052}10531054*p += c; c = (*p < c); j++; p++;1055}10561057cleanup:10581059return ret;1060}10611062/*1063* Unsigned subtraction: X = |A| - |B| (HAC 14.9, 14.10)1064*/1065int mbedtls_mpi_sub_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)1066{1067int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;1068size_t n;1069mbedtls_mpi_uint carry;10701071for (n = B->n; n > 0; n--) {1072if (B->p[n - 1] != 0) {1073break;1074}1075}1076if (n > A->n) {1077/* B >= (2^ciL)^n > A */1078ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE;1079goto cleanup;1080}10811082MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, A->n));10831084/* Set the high limbs of X to match A. Don't touch the lower limbs1085* because X might be aliased to B, and we must not overwrite the1086* significant digits of B. */1087if (A->n > n && A != X) {1088memcpy(X->p + n, A->p + n, (A->n - n) * ciL);1089}1090if (X->n > A->n) {1091memset(X->p + A->n, 0, (X->n - A->n) * ciL);1092}10931094carry = mbedtls_mpi_core_sub(X->p, A->p, B->p, n);1095if (carry != 0) {1096/* Propagate the carry through the rest of X. */1097carry = mbedtls_mpi_core_sub_int(X->p + n, X->p + n, carry, X->n - n);10981099/* If we have further carry/borrow, the result is negative. */1100if (carry != 0) {1101ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE;1102goto cleanup;1103}1104}11051106/* X should always be positive as a result of unsigned subtractions. */1107X->s = 1;11081109cleanup:1110return ret;1111}11121113/* Common function for signed addition and subtraction.1114* Calculate A + B * flip_B where flip_B is 1 or -1.1115*/1116static int add_sub_mpi(mbedtls_mpi *X,1117const mbedtls_mpi *A, const mbedtls_mpi *B,1118int flip_B)1119{1120int ret, s;11211122s = A->s;1123if (A->s * B->s * flip_B < 0) {1124int cmp = mbedtls_mpi_cmp_abs(A, B);1125if (cmp >= 0) {1126MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(X, A, B));1127/* If |A| = |B|, the result is 0 and we must set the sign bit1128* to +1 regardless of which of A or B was negative. Otherwise,1129* since |A| > |B|, the sign is the sign of A. */1130X->s = cmp == 0 ? 1 : s;1131} else {1132MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(X, B, A));1133/* Since |A| < |B|, the sign is the opposite of A. */1134X->s = -s;1135}1136} else {1137MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(X, A, B));1138X->s = s;1139}11401141cleanup:11421143return ret;1144}11451146/*1147* Signed addition: X = A + B1148*/1149int mbedtls_mpi_add_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)1150{1151return add_sub_mpi(X, A, B, 1);1152}11531154/*1155* Signed subtraction: X = A - B1156*/1157int mbedtls_mpi_sub_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)1158{1159return add_sub_mpi(X, A, B, -1);1160}11611162/*1163* Signed addition: X = A + b1164*/1165int mbedtls_mpi_add_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b)1166{1167mbedtls_mpi B;1168mbedtls_mpi_uint p[1];11691170p[0] = mpi_sint_abs(b);1171B.s = TO_SIGN(b);1172B.n = 1;1173B.p = p;11741175return mbedtls_mpi_add_mpi(X, A, &B);1176}11771178/*1179* Signed subtraction: X = A - b1180*/1181int mbedtls_mpi_sub_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b)1182{1183mbedtls_mpi B;1184mbedtls_mpi_uint p[1];11851186p[0] = mpi_sint_abs(b);1187B.s = TO_SIGN(b);1188B.n = 1;1189B.p = p;11901191return mbedtls_mpi_sub_mpi(X, A, &B);1192}11931194/*1195* Baseline multiplication: X = A * B (HAC 14.12)1196*/1197int mbedtls_mpi_mul_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)1198{1199int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;1200size_t i, j;1201mbedtls_mpi TA, TB;1202int result_is_zero = 0;12031204mbedtls_mpi_init(&TA);1205mbedtls_mpi_init(&TB);12061207if (X == A) {1208MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TA, A)); A = &TA;1209}1210if (X == B) {1211MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TB, B)); B = &TB;1212}12131214for (i = A->n; i > 0; i--) {1215if (A->p[i - 1] != 0) {1216break;1217}1218}1219if (i == 0) {1220result_is_zero = 1;1221}12221223for (j = B->n; j > 0; j--) {1224if (B->p[j - 1] != 0) {1225break;1226}1227}1228if (j == 0) {1229result_is_zero = 1;1230}12311232MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, i + j));1233MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 0));12341235mbedtls_mpi_core_mul(X->p, A->p, i, B->p, j);12361237/* If the result is 0, we don't shortcut the operation, which reduces1238* but does not eliminate side channels leaking the zero-ness. We do1239* need to take care to set the sign bit properly since the library does1240* not fully support an MPI object with a value of 0 and s == -1. */1241if (result_is_zero) {1242X->s = 1;1243} else {1244X->s = A->s * B->s;1245}12461247cleanup:12481249mbedtls_mpi_free(&TB); mbedtls_mpi_free(&TA);12501251return ret;1252}12531254/*1255* Baseline multiplication: X = A * b1256*/1257int mbedtls_mpi_mul_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b)1258{1259size_t n = A->n;1260while (n > 0 && A->p[n - 1] == 0) {1261--n;1262}12631264/* The general method below doesn't work if b==0. */1265if (b == 0 || n == 0) {1266return mbedtls_mpi_lset(X, 0);1267}12681269/* Calculate A*b as A + A*(b-1) to take advantage of mbedtls_mpi_core_mla */1270int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;1271/* In general, A * b requires 1 limb more than b. If1272* A->p[n - 1] * b / b == A->p[n - 1], then A * b fits in the same1273* number of limbs as A and the call to grow() is not required since1274* copy() will take care of the growth if needed. However, experimentally,1275* making the call to grow() unconditional causes slightly fewer1276* calls to calloc() in ECP code, presumably because it reuses the1277* same mpi for a while and this way the mpi is more likely to directly1278* grow to its final size.1279*1280* Note that calculating A*b as 0 + A*b doesn't work as-is because1281* A,X can be the same. */1282MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, n + 1));1283MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A));1284mbedtls_mpi_core_mla(X->p, X->n, A->p, n, b - 1);12851286cleanup:1287return ret;1288}12891290/*1291* Unsigned integer divide - double mbedtls_mpi_uint dividend, u1/u0, and1292* mbedtls_mpi_uint divisor, d1293*/1294static mbedtls_mpi_uint mbedtls_int_div_int(mbedtls_mpi_uint u1,1295mbedtls_mpi_uint u0,1296mbedtls_mpi_uint d,1297mbedtls_mpi_uint *r)1298{1299#if defined(MBEDTLS_HAVE_UDBL)1300mbedtls_t_udbl dividend, quotient;1301#else1302const mbedtls_mpi_uint radix = (mbedtls_mpi_uint) 1 << biH;1303const mbedtls_mpi_uint uint_halfword_mask = ((mbedtls_mpi_uint) 1 << biH) - 1;1304mbedtls_mpi_uint d0, d1, q0, q1, rAX, r0, quotient;1305mbedtls_mpi_uint u0_msw, u0_lsw;1306size_t s;1307#endif13081309/*1310* Check for overflow1311*/1312if (0 == d || u1 >= d) {1313if (r != NULL) {1314*r = ~(mbedtls_mpi_uint) 0u;1315}13161317return ~(mbedtls_mpi_uint) 0u;1318}13191320#if defined(MBEDTLS_HAVE_UDBL)1321dividend = (mbedtls_t_udbl) u1 << biL;1322dividend |= (mbedtls_t_udbl) u0;1323quotient = dividend / d;1324if (quotient > ((mbedtls_t_udbl) 1 << biL) - 1) {1325quotient = ((mbedtls_t_udbl) 1 << biL) - 1;1326}13271328if (r != NULL) {1329*r = (mbedtls_mpi_uint) (dividend - (quotient * d));1330}13311332return (mbedtls_mpi_uint) quotient;1333#else13341335/*1336* Algorithm D, Section 4.3.1 - The Art of Computer Programming1337* Vol. 2 - Seminumerical Algorithms, Knuth1338*/13391340/*1341* Normalize the divisor, d, and dividend, u0, u11342*/1343s = mbedtls_mpi_core_clz(d);1344d = d << s;13451346u1 = u1 << s;1347u1 |= (u0 >> (biL - s)) & (-(mbedtls_mpi_sint) s >> (biL - 1));1348u0 = u0 << s;13491350d1 = d >> biH;1351d0 = d & uint_halfword_mask;13521353u0_msw = u0 >> biH;1354u0_lsw = u0 & uint_halfword_mask;13551356/*1357* Find the first quotient and remainder1358*/1359q1 = u1 / d1;1360r0 = u1 - d1 * q1;13611362while (q1 >= radix || (q1 * d0 > radix * r0 + u0_msw)) {1363q1 -= 1;1364r0 += d1;13651366if (r0 >= radix) {1367break;1368}1369}13701371rAX = (u1 * radix) + (u0_msw - q1 * d);1372q0 = rAX / d1;1373r0 = rAX - q0 * d1;13741375while (q0 >= radix || (q0 * d0 > radix * r0 + u0_lsw)) {1376q0 -= 1;1377r0 += d1;13781379if (r0 >= radix) {1380break;1381}1382}13831384if (r != NULL) {1385*r = (rAX * radix + u0_lsw - q0 * d) >> s;1386}13871388quotient = q1 * radix + q0;13891390return quotient;1391#endif1392}13931394/*1395* Division by mbedtls_mpi: A = Q * B + R (HAC 14.20)1396*/1397int mbedtls_mpi_div_mpi(mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,1398const mbedtls_mpi *B)1399{1400int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;1401size_t i, n, t, k;1402mbedtls_mpi X, Y, Z, T1, T2;1403mbedtls_mpi_uint TP2[3];14041405if (mbedtls_mpi_cmp_int(B, 0) == 0) {1406return MBEDTLS_ERR_MPI_DIVISION_BY_ZERO;1407}14081409mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);1410mbedtls_mpi_init(&T1);1411/*1412* Avoid dynamic memory allocations for constant-size T2.1413*1414* T2 is used for comparison only and the 3 limbs are assigned explicitly,1415* so nobody increase the size of the MPI and we're safe to use an on-stack1416* buffer.1417*/1418T2.s = 1;1419T2.n = sizeof(TP2) / sizeof(*TP2);1420T2.p = TP2;14211422if (mbedtls_mpi_cmp_abs(A, B) < 0) {1423if (Q != NULL) {1424MBEDTLS_MPI_CHK(mbedtls_mpi_lset(Q, 0));1425}1426if (R != NULL) {1427MBEDTLS_MPI_CHK(mbedtls_mpi_copy(R, A));1428}1429return 0;1430}14311432MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&X, A));1433MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&Y, B));1434X.s = Y.s = 1;14351436MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&Z, A->n + 2));1437MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&Z, 0));1438MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&T1, A->n + 2));14391440k = mbedtls_mpi_bitlen(&Y) % biL;1441if (k < biL - 1) {1442k = biL - 1 - k;1443MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&X, k));1444MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&Y, k));1445} else {1446k = 0;1447}14481449n = X.n - 1;1450t = Y.n - 1;1451MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&Y, biL * (n - t)));14521453while (mbedtls_mpi_cmp_mpi(&X, &Y) >= 0) {1454Z.p[n - t]++;1455MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&X, &X, &Y));1456}1457MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&Y, biL * (n - t)));14581459for (i = n; i > t; i--) {1460if (X.p[i] >= Y.p[t]) {1461Z.p[i - t - 1] = ~(mbedtls_mpi_uint) 0u;1462} else {1463Z.p[i - t - 1] = mbedtls_int_div_int(X.p[i], X.p[i - 1],1464Y.p[t], NULL);1465}14661467T2.p[0] = (i < 2) ? 0 : X.p[i - 2];1468T2.p[1] = (i < 1) ? 0 : X.p[i - 1];1469T2.p[2] = X.p[i];14701471Z.p[i - t - 1]++;1472do {1473Z.p[i - t - 1]--;14741475MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&T1, 0));1476T1.p[0] = (t < 1) ? 0 : Y.p[t - 1];1477T1.p[1] = Y.p[t];1478MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(&T1, &T1, Z.p[i - t - 1]));1479} while (mbedtls_mpi_cmp_mpi(&T1, &T2) > 0);14801481MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(&T1, &Y, Z.p[i - t - 1]));1482MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&T1, biL * (i - t - 1)));1483MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&X, &X, &T1));14841485if (mbedtls_mpi_cmp_int(&X, 0) < 0) {1486MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&T1, &Y));1487MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&T1, biL * (i - t - 1)));1488MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&X, &X, &T1));1489Z.p[i - t - 1]--;1490}1491}14921493if (Q != NULL) {1494MBEDTLS_MPI_CHK(mbedtls_mpi_copy(Q, &Z));1495Q->s = A->s * B->s;1496}14971498if (R != NULL) {1499MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&X, k));1500X.s = A->s;1501MBEDTLS_MPI_CHK(mbedtls_mpi_copy(R, &X));15021503if (mbedtls_mpi_cmp_int(R, 0) == 0) {1504R->s = 1;1505}1506}15071508cleanup:15091510mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);1511mbedtls_mpi_free(&T1);1512mbedtls_platform_zeroize(TP2, sizeof(TP2));15131514return ret;1515}15161517/*1518* Division by int: A = Q * b + R1519*/1520int mbedtls_mpi_div_int(mbedtls_mpi *Q, mbedtls_mpi *R,1521const mbedtls_mpi *A,1522mbedtls_mpi_sint b)1523{1524mbedtls_mpi B;1525mbedtls_mpi_uint p[1];15261527p[0] = mpi_sint_abs(b);1528B.s = TO_SIGN(b);1529B.n = 1;1530B.p = p;15311532return mbedtls_mpi_div_mpi(Q, R, A, &B);1533}15341535/*1536* Modulo: R = A mod B1537*/1538int mbedtls_mpi_mod_mpi(mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B)1539{1540int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;15411542if (mbedtls_mpi_cmp_int(B, 0) < 0) {1543return MBEDTLS_ERR_MPI_NEGATIVE_VALUE;1544}15451546MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(NULL, R, A, B));15471548while (mbedtls_mpi_cmp_int(R, 0) < 0) {1549MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(R, R, B));1550}15511552while (mbedtls_mpi_cmp_mpi(R, B) >= 0) {1553MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(R, R, B));1554}15551556cleanup:15571558return ret;1559}15601561/*1562* Modulo: r = A mod b1563*/1564int mbedtls_mpi_mod_int(mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b)1565{1566size_t i;1567mbedtls_mpi_uint x, y, z;15681569if (b == 0) {1570return MBEDTLS_ERR_MPI_DIVISION_BY_ZERO;1571}15721573if (b < 0) {1574return MBEDTLS_ERR_MPI_NEGATIVE_VALUE;1575}15761577/*1578* handle trivial cases1579*/1580if (b == 1 || A->n == 0) {1581*r = 0;1582return 0;1583}15841585if (b == 2) {1586*r = A->p[0] & 1;1587return 0;1588}15891590/*1591* general case1592*/1593for (i = A->n, y = 0; i > 0; i--) {1594x = A->p[i - 1];1595y = (y << biH) | (x >> biH);1596z = y / b;1597y -= z * b;15981599x <<= biH;1600y = (y << biH) | (x >> biH);1601z = y / b;1602y -= z * b;1603}16041605/*1606* If A is negative, then the current y represents a negative value.1607* Flipping it to the positive side.1608*/1609if (A->s < 0 && y != 0) {1610y = b - y;1611}16121613*r = y;16141615return 0;1616}16171618/*1619* Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value,1620* this function is not constant time with respect to the exponent (parameter E).1621*/1622static int mbedtls_mpi_exp_mod_optionally_safe(mbedtls_mpi *X, const mbedtls_mpi *A,1623const mbedtls_mpi *E, int E_public,1624const mbedtls_mpi *N, mbedtls_mpi *prec_RR)1625{1626int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;16271628if (mbedtls_mpi_cmp_int(N, 0) <= 0 || (N->p[0] & 1) == 0) {1629return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;1630}16311632if (mbedtls_mpi_cmp_int(E, 0) < 0) {1633return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;1634}16351636if (mbedtls_mpi_bitlen(E) > MBEDTLS_MPI_MAX_BITS ||1637mbedtls_mpi_bitlen(N) > MBEDTLS_MPI_MAX_BITS) {1638return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;1639}16401641/*1642* Ensure that the exponent that we are passing to the core is not NULL.1643*/1644if (E->n == 0) {1645ret = mbedtls_mpi_lset(X, 1);1646return ret;1647}16481649/*1650* Allocate working memory for mbedtls_mpi_core_exp_mod()1651*/1652size_t T_limbs = mbedtls_mpi_core_exp_mod_working_limbs(N->n, E->n);1653mbedtls_mpi_uint *T = (mbedtls_mpi_uint *) mbedtls_calloc(T_limbs, sizeof(mbedtls_mpi_uint));1654if (T == NULL) {1655return MBEDTLS_ERR_MPI_ALLOC_FAILED;1656}16571658mbedtls_mpi RR;1659mbedtls_mpi_init(&RR);16601661/*1662* If 1st call, pre-compute R^2 mod N1663*/1664if (prec_RR == NULL || prec_RR->p == NULL) {1665MBEDTLS_MPI_CHK(mbedtls_mpi_core_get_mont_r2_unsafe(&RR, N));16661667if (prec_RR != NULL) {1668*prec_RR = RR;1669}1670} else {1671MBEDTLS_MPI_CHK(mbedtls_mpi_grow(prec_RR, N->n));1672RR = *prec_RR;1673}16741675/*1676* To preserve constness we need to make a copy of A. Using X for this to1677* save memory.1678*/1679MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A));16801681/*1682* Compensate for negative A (and correct at the end).1683*/1684X->s = 1;16851686/*1687* Make sure that X is in a form that is safe for consumption by1688* the core functions.1689*1690* - The core functions will not touch the limbs of X above N->n. The1691* result will be correct if those limbs are 0, which the mod call1692* ensures.1693* - Also, X must have at least as many limbs as N for the calls to the1694* core functions.1695*/1696if (mbedtls_mpi_cmp_mpi(X, N) >= 0) {1697MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(X, X, N));1698}1699MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, N->n));17001701/*1702* Convert to and from Montgomery around mbedtls_mpi_core_exp_mod().1703*/1704{1705mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N->p);1706mbedtls_mpi_core_to_mont_rep(X->p, X->p, N->p, N->n, mm, RR.p, T);1707if (E_public == MBEDTLS_MPI_IS_PUBLIC) {1708mbedtls_mpi_core_exp_mod_unsafe(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T);1709} else {1710mbedtls_mpi_core_exp_mod(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T);1711}1712mbedtls_mpi_core_from_mont_rep(X->p, X->p, N->p, N->n, mm, T);1713}17141715/*1716* Correct for negative A.1717*/1718if (A->s == -1 && (E->p[0] & 1) != 0) {1719mbedtls_ct_condition_t is_x_non_zero = mbedtls_mpi_core_check_zero_ct(X->p, X->n);1720X->s = mbedtls_ct_mpi_sign_if(is_x_non_zero, -1, 1);17211722MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(X, N, X));1723}17241725cleanup:17261727mbedtls_mpi_zeroize_and_free(T, T_limbs);17281729if (prec_RR == NULL || prec_RR->p == NULL) {1730mbedtls_mpi_free(&RR);1731}17321733return ret;1734}17351736int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,1737const mbedtls_mpi *E, const mbedtls_mpi *N,1738mbedtls_mpi *prec_RR)1739{1740return mbedtls_mpi_exp_mod_optionally_safe(X, A, E, MBEDTLS_MPI_IS_SECRET, N, prec_RR);1741}17421743int mbedtls_mpi_exp_mod_unsafe(mbedtls_mpi *X, const mbedtls_mpi *A,1744const mbedtls_mpi *E, const mbedtls_mpi *N,1745mbedtls_mpi *prec_RR)1746{1747return mbedtls_mpi_exp_mod_optionally_safe(X, A, E, MBEDTLS_MPI_IS_PUBLIC, N, prec_RR);1748}17491750/* Constant-time GCD and/or modinv with odd modulus and A <= N */1751int mbedtls_mpi_gcd_modinv_odd(mbedtls_mpi *G,1752mbedtls_mpi *I,1753const mbedtls_mpi *A,1754const mbedtls_mpi *N)1755{1756int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;1757mbedtls_mpi local_g;1758mbedtls_mpi_uint *T = NULL;1759const size_t T_factor = I != NULL ? 5 : 4;1760const mbedtls_mpi_uint zero = 0;17611762/* Check requirements on A and N */1763if (mbedtls_mpi_cmp_int(A, 0) < 0 ||1764mbedtls_mpi_cmp_mpi(A, N) > 0 ||1765mbedtls_mpi_get_bit(N, 0) != 1 ||1766(I != NULL && mbedtls_mpi_cmp_int(N, 1) == 0)) {1767return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;1768}17691770/* Check aliasing requirements */1771if (A == N || (I != NULL && (I == N || G == N))) {1772return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;1773}17741775mbedtls_mpi_init(&local_g);17761777if (G == NULL) {1778G = &local_g;1779}17801781/* We can't modify the values of G or I before use in the main function,1782* as they could be aliased to A or N. */1783MBEDTLS_MPI_CHK(mbedtls_mpi_grow(G, N->n));1784if (I != NULL) {1785MBEDTLS_MPI_CHK(mbedtls_mpi_grow(I, N->n));1786}17871788T = mbedtls_calloc(sizeof(mbedtls_mpi_uint) * N->n, T_factor);1789if (T == NULL) {1790ret = MBEDTLS_ERR_MPI_ALLOC_FAILED;1791goto cleanup;1792}17931794mbedtls_mpi_uint *Ip = I != NULL ? I->p : NULL;1795/* If A is 0 (null), then A->p would be null, and A->n would be 0,1796* which would be an issue if A->p and A->n were passed to1797* mbedtls_mpi_core_gcd_modinv_odd below. */1798const mbedtls_mpi_uint *Ap = A->p != NULL ? A->p : &zero;1799size_t An = A->n >= N->n ? N->n : A->p != NULL ? A->n : 1;1800mbedtls_mpi_core_gcd_modinv_odd(G->p, Ip, Ap, An, N->p, N->n, T);18011802G->s = 1;1803if (I != NULL) {1804I->s = 1;1805}18061807if (G->n > N->n) {1808memset(G->p + N->n, 0, ciL * (G->n - N->n));1809}1810if (I != NULL && I->n > N->n) {1811memset(I->p + N->n, 0, ciL * (I->n - N->n));1812}18131814cleanup:1815mbedtls_mpi_free(&local_g);1816mbedtls_free(T);1817return ret;1818}18191820/*1821* Greatest common divisor: G = gcd(A, B)1822* Wrapper around mbedtls_mpi_gcd_modinv() that removes its restrictions.1823*/1824int mbedtls_mpi_gcd(mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B)1825{1826int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;1827mbedtls_mpi TA, TB;18281829mbedtls_mpi_init(&TA); mbedtls_mpi_init(&TB);18301831/* Make copies and take absolute values */1832MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TA, A));1833MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TB, B));1834TA.s = TB.s = 1;18351836/* Make the two values the same (non-zero) number of limbs.1837* This is needed to use mbedtls_mpi_core functions below. */1838MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&TA, TB.n != 0 ? TB.n : 1));1839MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&TB, TA.n)); // non-zero from above18401841/* Handle special cases (that don't happen in crypto usage) */1842if (mbedtls_mpi_core_check_zero_ct(TA.p, TA.n) == MBEDTLS_CT_FALSE) {1843MBEDTLS_MPI_CHK(mbedtls_mpi_copy(G, &TB)); // GCD(0, B) = abs(B)1844goto cleanup;1845}1846if (mbedtls_mpi_core_check_zero_ct(TB.p, TB.n) == MBEDTLS_CT_FALSE) {1847MBEDTLS_MPI_CHK(mbedtls_mpi_copy(G, &TA)); // GCD(A, 0) = abs(A)1848goto cleanup;1849}18501851/* Make boths inputs odd by putting powers of 2 on the side */1852const size_t za = mbedtls_mpi_lsb(&TA);1853const size_t zb = mbedtls_mpi_lsb(&TB);1854MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TA, za));1855MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TB, zb));18561857/* Ensure A <= B: if B < A, swap them */1858mbedtls_ct_condition_t swap = mbedtls_mpi_core_lt_ct(TB.p, TA.p, TA.n);1859mbedtls_mpi_core_cond_swap(TA.p, TB.p, TA.n, swap);18601861MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(G, NULL, &TA, &TB));18621863/* Re-inject the power of 2 we had previously put aside */1864size_t zg = za > zb ? zb : za; // zg = min(za, zb)1865MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(G, zg));18661867cleanup:18681869mbedtls_mpi_free(&TA); mbedtls_mpi_free(&TB);18701871return ret;1872}18731874/*1875* Fill X with size bytes of random.1876* The bytes returned from the RNG are used in a specific order which1877* is suitable for deterministic ECDSA (see the specification of1878* mbedtls_mpi_random() and the implementation in mbedtls_mpi_fill_random()).1879*/1880int mbedtls_mpi_fill_random(mbedtls_mpi *X, size_t size,1881int (*f_rng)(void *, unsigned char *, size_t),1882void *p_rng)1883{1884int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;1885const size_t limbs = CHARS_TO_LIMBS(size);18861887/* Ensure that target MPI has exactly the necessary number of limbs */1888MBEDTLS_MPI_CHK(mbedtls_mpi_resize_clear(X, limbs));1889if (size == 0) {1890return 0;1891}18921893ret = mbedtls_mpi_core_fill_random(X->p, X->n, size, f_rng, p_rng);18941895cleanup:1896return ret;1897}18981899int mbedtls_mpi_random(mbedtls_mpi *X,1900mbedtls_mpi_sint min,1901const mbedtls_mpi *N,1902int (*f_rng)(void *, unsigned char *, size_t),1903void *p_rng)1904{1905if (min < 0) {1906return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;1907}1908if (mbedtls_mpi_cmp_int(N, min) <= 0) {1909return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;1910}19111912/* Ensure that target MPI has exactly the same number of limbs1913* as the upper bound, even if the upper bound has leading zeros.1914* This is necessary for mbedtls_mpi_core_random. */1915int ret = mbedtls_mpi_resize_clear(X, N->n);1916if (ret != 0) {1917return ret;1918}19191920return mbedtls_mpi_core_random(X->p, min, N->p, X->n, f_rng, p_rng);1921}19221923/*1924* Modular inverse: X = A^-1 mod N with N odd (and A any range)1925*/1926int mbedtls_mpi_inv_mod_odd(mbedtls_mpi *X,1927const mbedtls_mpi *A,1928const mbedtls_mpi *N)1929{1930int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;1931mbedtls_mpi T, G;19321933mbedtls_mpi_init(&T);1934mbedtls_mpi_init(&G);19351936MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&T, A, N));1937MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(&G, &T, &T, N));1938if (mbedtls_mpi_cmp_int(&G, 1) != 0) {1939ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;1940goto cleanup;1941}19421943MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, &T));19441945cleanup:1946mbedtls_mpi_free(&T);1947mbedtls_mpi_free(&G);19481949return ret;1950}19511952/*1953* Compute X = A^-1 mod N with N even, A odd and 1 < A < N.1954*1955* This is not obvious because our constant-time modinv function only works with1956* an odd modulus, and here the modulus is even. The idea is that computing a1957* a^-1 mod b is really just computing the u coefficient in the Bézout relation1958* a*u + b*v = 1 (assuming gcd(a,b) = 1, i.e. the inverse exists). But if we know1959* one of u, v in this relation then the other is easy to find. So we can1960* actually start by computing N^-1 mod A with gives us "the wrong half" of the1961* Bézout relation, from which we'll deduce the interesting half A^-1 mod N.1962*1963* Return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if the inverse doesn't exist.1964*/1965int mbedtls_mpi_inv_mod_even_in_range(mbedtls_mpi *X,1966mbedtls_mpi const *A,1967mbedtls_mpi const *N)1968{1969int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;1970mbedtls_mpi I, G;19711972mbedtls_mpi_init(&I);1973mbedtls_mpi_init(&G);19741975/* Set I = N^-1 mod A */1976MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&I, N, A));1977MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(&G, &I, &I, A));1978if (mbedtls_mpi_cmp_int(&G, 1) != 0) {1979ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;1980goto cleanup;1981}19821983/* We know N * I = 1 + k * A for some k, which we can easily compute1984* as k = (N*I - 1) / A (we know there will be no remainder). */1985MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&I, &I, N));1986MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&I, &I, 1));1987MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(&G, NULL, &I, A));19881989/* Now we have a Bézout relation N * (previous value of I) - G * A = 1,1990* so A^-1 mod N is -G mod N, which is N - G.1991* Note that 0 < k < N since 0 < I < A, so G (k) is already in range. */1992MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(X, N, &G));19931994cleanup:1995mbedtls_mpi_free(&I);1996mbedtls_mpi_free(&G);1997return ret;1998}19992000/*2001* Compute X = A^-1 mod N with N even and A odd (but in any range).2002*2003* Return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if the inverse doesn't exist.2004*/2005static int mbedtls_mpi_inv_mod_even(mbedtls_mpi *X,2006mbedtls_mpi const *A,2007mbedtls_mpi const *N)2008{2009int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;2010mbedtls_mpi AA;20112012mbedtls_mpi_init(&AA);20132014/* Bring A in the range [0, N). */2015MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&AA, A, N));20162017/* We know A >= 0 but the next function wants A > 1 */2018int cmp = mbedtls_mpi_cmp_int(&AA, 1);2019if (cmp < 0) { // AA == 02020ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;2021goto cleanup;2022}2023if (cmp == 0) { // AA = 12024MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 1));2025goto cleanup;2026}20272028/* Now we know 1 < A < N, N is even and AA is still odd */2029MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod_even_in_range(X, &AA, N));20302031cleanup:2032mbedtls_mpi_free(&AA);2033return ret;2034}20352036/*2037* Modular inverse: X = A^-1 mod N2038*2039* Wrapper around mbedtls_mpi_gcd_modinv_odd() that lifts its limitations.2040*/2041int mbedtls_mpi_inv_mod(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N)2042{2043if (mbedtls_mpi_cmp_int(N, 1) <= 0) {2044return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;2045}20462047if (mbedtls_mpi_get_bit(N, 0) == 1) {2048return mbedtls_mpi_inv_mod_odd(X, A, N);2049}20502051if (mbedtls_mpi_get_bit(A, 0) == 1) {2052return mbedtls_mpi_inv_mod_even(X, A, N);2053}20542055/* If A and N are both even, 2 divides their GCD, so no inverse. */2056return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;2057}20582059#if defined(MBEDTLS_GENPRIME)20602061/* Gaps between primes, starting at 3. https://oeis.org/A001223 */2062static const unsigned char small_prime_gaps[] = {20632, 2, 4, 2, 4, 2, 4, 6,20642, 6, 4, 2, 4, 6, 6, 2,20656, 4, 2, 6, 4, 6, 8, 4,20662, 4, 2, 4, 14, 4, 6, 2,206710, 2, 6, 6, 4, 6, 6, 2,206810, 2, 4, 2, 12, 12, 4, 2,20694, 6, 2, 10, 6, 6, 6, 2,20706, 4, 2, 10, 14, 4, 2, 4,207114, 6, 10, 2, 4, 6, 8, 6,20726, 4, 6, 8, 4, 8, 10, 2,207310, 2, 6, 4, 6, 8, 4, 2,20744, 12, 8, 4, 8, 4, 6, 12,20752, 18, 6, 10, 6, 6, 2, 6,207610, 6, 6, 2, 6, 6, 4, 2,207712, 10, 2, 4, 6, 6, 2, 12,20784, 6, 8, 10, 8, 10, 8, 6,20796, 4, 8, 6, 4, 8, 4, 14,208010, 12, 2, 10, 2, 4, 2, 10,208114, 4, 2, 4, 14, 4, 2, 4,208220, 4, 8, 10, 8, 4, 6, 6,208314, 4, 6, 6, 8, 6, /*reaches 997*/20840 /* the last entry is effectively unused */2085};20862087/*2088* Small divisors test (X must be positive)2089*2090* Return values:2091* 0: no small factor (possible prime, more tests needed)2092* 1: certain prime2093* MBEDTLS_ERR_MPI_NOT_ACCEPTABLE: certain non-prime2094* other negative: error2095*/2096static int mpi_check_small_factors(const mbedtls_mpi *X)2097{2098int ret = 0;2099size_t i;2100mbedtls_mpi_uint r;2101unsigned p = 3; /* The first odd prime */21022103if ((X->p[0] & 1) == 0) {2104return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;2105}21062107for (i = 0; i < sizeof(small_prime_gaps); p += small_prime_gaps[i], i++) {2108MBEDTLS_MPI_CHK(mbedtls_mpi_mod_int(&r, X, p));2109if (r == 0) {2110if (mbedtls_mpi_cmp_int(X, p) == 0) {2111return 1;2112} else {2113return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;2114}2115}2116}21172118cleanup:2119return ret;2120}21212122/*2123* Miller-Rabin pseudo-primality test (HAC 4.24)2124*/2125static int mpi_miller_rabin(const mbedtls_mpi *X, size_t rounds,2126int (*f_rng)(void *, unsigned char *, size_t),2127void *p_rng)2128{2129int ret, count;2130size_t i, j, k, s;2131mbedtls_mpi W, R, T, A, RR;21322133mbedtls_mpi_init(&W); mbedtls_mpi_init(&R);2134mbedtls_mpi_init(&T); mbedtls_mpi_init(&A);2135mbedtls_mpi_init(&RR);21362137/*2138* W = |X| - 12139* R = W >> lsb( W )2140*/2141MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&W, X, 1));2142s = mbedtls_mpi_lsb(&W);2143MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&R, &W));2144MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&R, s));21452146for (i = 0; i < rounds; i++) {2147/*2148* pick a random A, 1 < A < |X| - 12149*/2150count = 0;2151do {2152MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&A, X->n * ciL, f_rng, p_rng));21532154j = mbedtls_mpi_bitlen(&A);2155k = mbedtls_mpi_bitlen(&W);2156if (j > k) {2157A.p[A.n - 1] &= ((mbedtls_mpi_uint) 1 << (k - (A.n - 1) * biL - 1)) - 1;2158}21592160if (count++ > 30) {2161ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;2162goto cleanup;2163}21642165} while (mbedtls_mpi_cmp_mpi(&A, &W) >= 0 ||2166mbedtls_mpi_cmp_int(&A, 1) <= 0);21672168/*2169* A = A^R mod |X|2170*/2171MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&A, &A, &R, X, &RR));21722173if (mbedtls_mpi_cmp_mpi(&A, &W) == 0 ||2174mbedtls_mpi_cmp_int(&A, 1) == 0) {2175continue;2176}21772178j = 1;2179while (j < s && mbedtls_mpi_cmp_mpi(&A, &W) != 0) {2180/*2181* A = A * A mod |X|2182*/2183MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&T, &A, &A));2184MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&A, &T, X));21852186if (mbedtls_mpi_cmp_int(&A, 1) == 0) {2187break;2188}21892190j++;2191}21922193/*2194* not prime if A != |X| - 1 or A == 12195*/2196if (mbedtls_mpi_cmp_mpi(&A, &W) != 0 ||2197mbedtls_mpi_cmp_int(&A, 1) == 0) {2198ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;2199break;2200}2201}22022203cleanup:2204mbedtls_mpi_free(&W); mbedtls_mpi_free(&R);2205mbedtls_mpi_free(&T); mbedtls_mpi_free(&A);2206mbedtls_mpi_free(&RR);22072208return ret;2209}22102211/*2212* Pseudo-primality test: small factors, then Miller-Rabin2213*/2214int mbedtls_mpi_is_prime_ext(const mbedtls_mpi *X, int rounds,2215int (*f_rng)(void *, unsigned char *, size_t),2216void *p_rng)2217{2218int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;2219mbedtls_mpi XX;22202221XX.s = 1;2222XX.n = X->n;2223XX.p = X->p;22242225if (mbedtls_mpi_cmp_int(&XX, 0) == 0 ||2226mbedtls_mpi_cmp_int(&XX, 1) == 0) {2227return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;2228}22292230if (mbedtls_mpi_cmp_int(&XX, 2) == 0) {2231return 0;2232}22332234if ((ret = mpi_check_small_factors(&XX)) != 0) {2235if (ret == 1) {2236return 0;2237}22382239return ret;2240}22412242return mpi_miller_rabin(&XX, rounds, f_rng, p_rng);2243}22442245/*2246* Prime number generation2247*2248* To generate an RSA key in a way recommended by FIPS 186-4, both primes must2249* be either 1024 bits or 1536 bits long, and flags must contain2250* MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR.2251*/2252int mbedtls_mpi_gen_prime(mbedtls_mpi *X, size_t nbits, int flags,2253int (*f_rng)(void *, unsigned char *, size_t),2254void *p_rng)2255{2256#ifdef MBEDTLS_HAVE_INT642257// ceil(2^63.5)2258#define CEIL_MAXUINT_DIV_SQRT2 0xb504f333f9de6485ULL2259#else2260// ceil(2^31.5)2261#define CEIL_MAXUINT_DIV_SQRT2 0xb504f334U2262#endif2263int ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;2264size_t k, n;2265int rounds;2266mbedtls_mpi_uint r;2267mbedtls_mpi Y;22682269if (nbits < 3 || nbits > MBEDTLS_MPI_MAX_BITS) {2270return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;2271}22722273mbedtls_mpi_init(&Y);22742275n = BITS_TO_LIMBS(nbits);22762277if ((flags & MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR) == 0) {2278/*2279* 2^-80 error probability, number of rounds chosen per HAC, table 4.42280*/2281rounds = ((nbits >= 1300) ? 2 : (nbits >= 850) ? 3 :2282(nbits >= 650) ? 4 : (nbits >= 350) ? 8 :2283(nbits >= 250) ? 12 : (nbits >= 150) ? 18 : 27);2284} else {2285/*2286* 2^-100 error probability, number of rounds computed based on HAC,2287* fact 4.482288*/2289rounds = ((nbits >= 1450) ? 4 : (nbits >= 1150) ? 5 :2290(nbits >= 1000) ? 6 : (nbits >= 850) ? 7 :2291(nbits >= 750) ? 8 : (nbits >= 500) ? 13 :2292(nbits >= 250) ? 28 : (nbits >= 150) ? 40 : 51);2293}22942295while (1) {2296MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(X, n * ciL, f_rng, p_rng));2297/* make sure generated number is at least (nbits-1)+0.5 bits (FIPS 186-4 §B.3.3 steps 4.4, 5.5) */2298if (X->p[n-1] < CEIL_MAXUINT_DIV_SQRT2) {2299continue;2300}23012302k = n * biL;2303if (k > nbits) {2304MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(X, k - nbits));2305}2306X->p[0] |= 1;23072308if ((flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH) == 0) {2309ret = mbedtls_mpi_is_prime_ext(X, rounds, f_rng, p_rng);23102311if (ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) {2312goto cleanup;2313}2314} else {2315/*2316* A necessary condition for Y and X = 2Y + 1 to be prime2317* is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).2318* Make sure it is satisfied, while keeping X = 3 mod 42319*/23202321X->p[0] |= 2;23222323MBEDTLS_MPI_CHK(mbedtls_mpi_mod_int(&r, X, 3));2324if (r == 0) {2325MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, X, 8));2326} else if (r == 1) {2327MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, X, 4));2328}23292330/* Set Y = (X-1) / 2, which is X / 2 because X is odd */2331MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&Y, X));2332MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&Y, 1));23332334while (1) {2335/*2336* First, check small factors for X and Y2337* before doing Miller-Rabin on any of them2338*/2339if ((ret = mpi_check_small_factors(X)) == 0 &&2340(ret = mpi_check_small_factors(&Y)) == 0 &&2341(ret = mpi_miller_rabin(X, rounds, f_rng, p_rng))2342== 0 &&2343(ret = mpi_miller_rabin(&Y, rounds, f_rng, p_rng))2344== 0) {2345goto cleanup;2346}23472348if (ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) {2349goto cleanup;2350}23512352/*2353* Next candidates. We want to preserve Y = (X-1) / 2 and2354* Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)2355* so up Y by 6 and X by 12.2356*/2357MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, X, 12));2358MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&Y, &Y, 6));2359}2360}2361}23622363cleanup:23642365mbedtls_mpi_free(&Y);23662367return ret;2368}23692370#endif /* MBEDTLS_GENPRIME */23712372#if defined(MBEDTLS_SELF_TEST)23732374#define GCD_PAIR_COUNT 323752376static const int gcd_pairs[GCD_PAIR_COUNT][3] =2377{2378{ 693, 609, 21 },2379{ 1764, 868, 28 },2380{ 768454923, 542167814, 1 }2381};23822383/*2384* Checkup routine2385*/2386int mbedtls_mpi_self_test(int verbose)2387{2388int ret, i;2389mbedtls_mpi A, E, N, X, Y, U, V;23902391mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N); mbedtls_mpi_init(&X);2392mbedtls_mpi_init(&Y); mbedtls_mpi_init(&U); mbedtls_mpi_init(&V);23932394MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&A, 16,2395"EFE021C2645FD1DC586E69184AF4A31E" \2396"D5F53E93B5F123FA41680867BA110131" \2397"944FE7952E2517337780CB0DB80E61AA" \2398"E7C8DDC6C5C6AADEB34EB38A2F40D5E6"));23992400MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&E, 16,2401"B2E7EFD37075B9F03FF989C7C5051C20" \2402"34D2A323810251127E7BF8625A4F49A5" \2403"F3E27F4DA8BD59C47D6DAABA4C8127BD" \2404"5B5C25763222FEFCCFC38B832366C29E"));24052406MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&N, 16,2407"0066A198186C18C10B2F5ED9B522752A" \2408"9830B69916E535C8F047518A889A43A5" \2409"94B6BED27A168D31D4A52F88925AA8F5"));24102411MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&X, &A, &N));24122413MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16,2414"602AB7ECA597A3D6B56FF9829A5E8B85" \2415"9E857EA95A03512E2BAE7391688D264A" \2416"A5663B0341DB9CCFD2C4C5F421FEC814" \2417"8001B72E848A38CAE1C65F78E56ABDEF" \2418"E12D3C039B8A02D6BE593F0BBBDA56F1" \2419"ECF677152EF804370C1A305CAF3B5BF1" \2420"30879B56C61DE584A0F53A2447A51E"));24212422if (verbose != 0) {2423mbedtls_printf(" MPI test #1 (mul_mpi): ");2424}24252426if (mbedtls_mpi_cmp_mpi(&X, &U) != 0) {2427if (verbose != 0) {2428mbedtls_printf("failed\n");2429}24302431ret = 1;2432goto cleanup;2433}24342435if (verbose != 0) {2436mbedtls_printf("passed\n");2437}24382439MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(&X, &Y, &A, &N));24402441MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16,2442"256567336059E52CAE22925474705F39A94"));24432444MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&V, 16,2445"6613F26162223DF488E9CD48CC132C7A" \2446"0AC93C701B001B092E4E5B9F73BCD27B" \2447"9EE50D0657C77F374E903CDFA4C642"));24482449if (verbose != 0) {2450mbedtls_printf(" MPI test #2 (div_mpi): ");2451}24522453if (mbedtls_mpi_cmp_mpi(&X, &U) != 0 ||2454mbedtls_mpi_cmp_mpi(&Y, &V) != 0) {2455if (verbose != 0) {2456mbedtls_printf("failed\n");2457}24582459ret = 1;2460goto cleanup;2461}24622463if (verbose != 0) {2464mbedtls_printf("passed\n");2465}24662467MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&X, &A, &E, &N, NULL));24682469MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16,2470"36E139AEA55215609D2816998ED020BB" \2471"BD96C37890F65171D948E9BC7CBAA4D9" \2472"325D24D6A3C12710F10A09FA08AB87"));24732474if (verbose != 0) {2475mbedtls_printf(" MPI test #3 (exp_mod): ");2476}24772478if (mbedtls_mpi_cmp_mpi(&X, &U) != 0) {2479if (verbose != 0) {2480mbedtls_printf("failed\n");2481}24822483ret = 1;2484goto cleanup;2485}24862487if (verbose != 0) {2488mbedtls_printf("passed\n");2489}24902491MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&X, &A, &N));24922493MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16,2494"003A0AAEDD7E784FC07D8F9EC6E3BFD5" \2495"C3DBA76456363A10869622EAC2DD84EC" \2496"C5B8A74DAC4D09E03B5E0BE779F2DF61"));24972498if (verbose != 0) {2499mbedtls_printf(" MPI test #4 (inv_mod): ");2500}25012502if (mbedtls_mpi_cmp_mpi(&X, &U) != 0) {2503if (verbose != 0) {2504mbedtls_printf("failed\n");2505}25062507ret = 1;2508goto cleanup;2509}25102511if (verbose != 0) {2512mbedtls_printf("passed\n");2513}25142515if (verbose != 0) {2516mbedtls_printf(" MPI test #5 (simple gcd): ");2517}25182519for (i = 0; i < GCD_PAIR_COUNT; i++) {2520MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&X, gcd_pairs[i][0]));2521MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&Y, gcd_pairs[i][1]));25222523MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(&A, &X, &Y));25242525if (mbedtls_mpi_cmp_int(&A, gcd_pairs[i][2]) != 0) {2526if (verbose != 0) {2527mbedtls_printf("failed at %d\n", i);2528}25292530ret = 1;2531goto cleanup;2532}2533}25342535if (verbose != 0) {2536mbedtls_printf("passed\n");2537}25382539cleanup:25402541if (ret != 0 && verbose != 0) {2542mbedtls_printf("Unexpected error, return code = %08X\n", (unsigned int) ret);2543}25442545mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N); mbedtls_mpi_free(&X);2546mbedtls_mpi_free(&Y); mbedtls_mpi_free(&U); mbedtls_mpi_free(&V);25472548if (verbose != 0) {2549mbedtls_printf("\n");2550}25512552return ret;2553}25542555#endif /* MBEDTLS_SELF_TEST */25562557#endif /* MBEDTLS_BIGNUM_C */255825592560