Path: blob/master/thirdparty/mbedtls/library/bignum_core.c
9898 views
/*1* Core bignum functions2*3* Copyright The Mbed TLS Contributors4* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later5*/67#include "common.h"89#if defined(MBEDTLS_BIGNUM_C)1011#include <string.h>1213#include "mbedtls/error.h"14#include "mbedtls/platform_util.h"15#include "constant_time_internal.h"1617#include "mbedtls/platform.h"1819#include "bignum_core.h"20#include "bn_mul.h"21#include "constant_time_internal.h"2223size_t mbedtls_mpi_core_clz(mbedtls_mpi_uint a)24{25#if defined(__has_builtin)26#if (MBEDTLS_MPI_UINT_MAX == UINT_MAX) && __has_builtin(__builtin_clz)27#define core_clz __builtin_clz28#elif (MBEDTLS_MPI_UINT_MAX == ULONG_MAX) && __has_builtin(__builtin_clzl)29#define core_clz __builtin_clzl30#elif (MBEDTLS_MPI_UINT_MAX == ULLONG_MAX) && __has_builtin(__builtin_clzll)31#define core_clz __builtin_clzll32#endif33#endif34#if defined(core_clz)35return (size_t) core_clz(a);36#else37size_t j;38mbedtls_mpi_uint mask = (mbedtls_mpi_uint) 1 << (biL - 1);3940for (j = 0; j < biL; j++) {41if (a & mask) {42break;43}4445mask >>= 1;46}4748return j;49#endif50}5152size_t mbedtls_mpi_core_bitlen(const mbedtls_mpi_uint *A, size_t A_limbs)53{54int i;55size_t j;5657for (i = ((int) A_limbs) - 1; i >= 0; i--) {58if (A[i] != 0) {59j = biL - mbedtls_mpi_core_clz(A[i]);60return (i * biL) + j;61}62}6364return 0;65}6667static mbedtls_mpi_uint mpi_bigendian_to_host(mbedtls_mpi_uint a)68{69if (MBEDTLS_IS_BIG_ENDIAN) {70/* Nothing to do on bigendian systems. */71return a;72} else {73#if defined(MBEDTLS_HAVE_INT32)74return (mbedtls_mpi_uint) MBEDTLS_BSWAP32(a);75#elif defined(MBEDTLS_HAVE_INT64)76return (mbedtls_mpi_uint) MBEDTLS_BSWAP64(a);77#endif78}79}8081void mbedtls_mpi_core_bigendian_to_host(mbedtls_mpi_uint *A,82size_t A_limbs)83{84mbedtls_mpi_uint *cur_limb_left;85mbedtls_mpi_uint *cur_limb_right;86if (A_limbs == 0) {87return;88}8990/*91* Traverse limbs and92* - adapt byte-order in each limb93* - swap the limbs themselves.94* For that, simultaneously traverse the limbs from left to right95* and from right to left, as long as the left index is not bigger96* than the right index (it's not a problem if limbs is odd and the97* indices coincide in the last iteration).98*/99for (cur_limb_left = A, cur_limb_right = A + (A_limbs - 1);100cur_limb_left <= cur_limb_right;101cur_limb_left++, cur_limb_right--) {102mbedtls_mpi_uint tmp;103/* Note that if cur_limb_left == cur_limb_right,104* this code effectively swaps the bytes only once. */105tmp = mpi_bigendian_to_host(*cur_limb_left);106*cur_limb_left = mpi_bigendian_to_host(*cur_limb_right);107*cur_limb_right = tmp;108}109}110111/* Whether min <= A, in constant time.112* A_limbs must be at least 1. */113mbedtls_ct_condition_t mbedtls_mpi_core_uint_le_mpi(mbedtls_mpi_uint min,114const mbedtls_mpi_uint *A,115size_t A_limbs)116{117/* min <= least significant limb? */118mbedtls_ct_condition_t min_le_lsl = mbedtls_ct_uint_ge(A[0], min);119120/* limbs other than the least significant one are all zero? */121mbedtls_ct_condition_t msll_mask = MBEDTLS_CT_FALSE;122for (size_t i = 1; i < A_limbs; i++) {123msll_mask = mbedtls_ct_bool_or(msll_mask, mbedtls_ct_bool(A[i]));124}125126/* min <= A iff the lowest limb of A is >= min or the other limbs127* are not all zero. */128return mbedtls_ct_bool_or(msll_mask, min_le_lsl);129}130131mbedtls_ct_condition_t mbedtls_mpi_core_lt_ct(const mbedtls_mpi_uint *A,132const mbedtls_mpi_uint *B,133size_t limbs)134{135mbedtls_ct_condition_t ret = MBEDTLS_CT_FALSE, cond = MBEDTLS_CT_FALSE, done = MBEDTLS_CT_FALSE;136137for (size_t i = limbs; i > 0; i--) {138/*139* If B[i - 1] < A[i - 1] then A < B is false and the result must140* remain 0.141*142* Again even if we can make a decision, we just mark the result and143* the fact that we are done and continue looping.144*/145cond = mbedtls_ct_uint_lt(B[i - 1], A[i - 1]);146done = mbedtls_ct_bool_or(done, cond);147148/*149* If A[i - 1] < B[i - 1] then A < B is true.150*151* Again even if we can make a decision, we just mark the result and152* the fact that we are done and continue looping.153*/154cond = mbedtls_ct_uint_lt(A[i - 1], B[i - 1]);155ret = mbedtls_ct_bool_or(ret, mbedtls_ct_bool_and(cond, mbedtls_ct_bool_not(done)));156done = mbedtls_ct_bool_or(done, cond);157}158159/*160* If all the limbs were equal, then the numbers are equal, A < B is false161* and leaving the result 0 is correct.162*/163164return ret;165}166167void mbedtls_mpi_core_cond_assign(mbedtls_mpi_uint *X,168const mbedtls_mpi_uint *A,169size_t limbs,170mbedtls_ct_condition_t assign)171{172if (X == A) {173return;174}175176/* This function is very performance-sensitive for RSA. For this reason177* we have the loop below, instead of calling mbedtls_ct_memcpy_if178* (this is more optimal since here we don't have to handle the case where179* we copy awkwardly sized data).180*/181for (size_t i = 0; i < limbs; i++) {182X[i] = mbedtls_ct_mpi_uint_if(assign, A[i], X[i]);183}184}185186void mbedtls_mpi_core_cond_swap(mbedtls_mpi_uint *X,187mbedtls_mpi_uint *Y,188size_t limbs,189mbedtls_ct_condition_t swap)190{191if (X == Y) {192return;193}194195for (size_t i = 0; i < limbs; i++) {196mbedtls_mpi_uint tmp = X[i];197X[i] = mbedtls_ct_mpi_uint_if(swap, Y[i], X[i]);198Y[i] = mbedtls_ct_mpi_uint_if(swap, tmp, Y[i]);199}200}201202int mbedtls_mpi_core_read_le(mbedtls_mpi_uint *X,203size_t X_limbs,204const unsigned char *input,205size_t input_length)206{207const size_t limbs = CHARS_TO_LIMBS(input_length);208209if (X_limbs < limbs) {210return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL;211}212213if (X != NULL) {214memset(X, 0, X_limbs * ciL);215216for (size_t i = 0; i < input_length; i++) {217size_t offset = ((i % ciL) << 3);218X[i / ciL] |= ((mbedtls_mpi_uint) input[i]) << offset;219}220}221222return 0;223}224225int mbedtls_mpi_core_read_be(mbedtls_mpi_uint *X,226size_t X_limbs,227const unsigned char *input,228size_t input_length)229{230const size_t limbs = CHARS_TO_LIMBS(input_length);231232if (X_limbs < limbs) {233return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL;234}235236/* If X_limbs is 0, input_length must also be 0 (from previous test).237* Nothing to do. */238if (X_limbs == 0) {239return 0;240}241242memset(X, 0, X_limbs * ciL);243244/* memcpy() with (NULL, 0) is undefined behaviour */245if (input_length != 0) {246size_t overhead = (X_limbs * ciL) - input_length;247unsigned char *Xp = (unsigned char *) X;248memcpy(Xp + overhead, input, input_length);249}250251mbedtls_mpi_core_bigendian_to_host(X, X_limbs);252253return 0;254}255256int mbedtls_mpi_core_write_le(const mbedtls_mpi_uint *A,257size_t A_limbs,258unsigned char *output,259size_t output_length)260{261size_t stored_bytes = A_limbs * ciL;262size_t bytes_to_copy;263264if (stored_bytes < output_length) {265bytes_to_copy = stored_bytes;266} else {267bytes_to_copy = output_length;268269/* The output buffer is smaller than the allocated size of A.270* However A may fit if its leading bytes are zero. */271for (size_t i = bytes_to_copy; i < stored_bytes; i++) {272if (GET_BYTE(A, i) != 0) {273return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL;274}275}276}277278for (size_t i = 0; i < bytes_to_copy; i++) {279output[i] = GET_BYTE(A, i);280}281282if (stored_bytes < output_length) {283/* Write trailing 0 bytes */284memset(output + stored_bytes, 0, output_length - stored_bytes);285}286287return 0;288}289290int mbedtls_mpi_core_write_be(const mbedtls_mpi_uint *X,291size_t X_limbs,292unsigned char *output,293size_t output_length)294{295size_t stored_bytes;296size_t bytes_to_copy;297unsigned char *p;298299stored_bytes = X_limbs * ciL;300301if (stored_bytes < output_length) {302/* There is enough space in the output buffer. Write initial303* null bytes and record the position at which to start304* writing the significant bytes. In this case, the execution305* trace of this function does not depend on the value of the306* number. */307bytes_to_copy = stored_bytes;308p = output + output_length - stored_bytes;309memset(output, 0, output_length - stored_bytes);310} else {311/* The output buffer is smaller than the allocated size of X.312* However X may fit if its leading bytes are zero. */313bytes_to_copy = output_length;314p = output;315for (size_t i = bytes_to_copy; i < stored_bytes; i++) {316if (GET_BYTE(X, i) != 0) {317return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL;318}319}320}321322for (size_t i = 0; i < bytes_to_copy; i++) {323p[bytes_to_copy - i - 1] = GET_BYTE(X, i);324}325326return 0;327}328329void mbedtls_mpi_core_shift_r(mbedtls_mpi_uint *X, size_t limbs,330size_t count)331{332size_t i, v0, v1;333mbedtls_mpi_uint r0 = 0, r1;334335v0 = count / biL;336v1 = count & (biL - 1);337338if (v0 > limbs || (v0 == limbs && v1 > 0)) {339memset(X, 0, limbs * ciL);340return;341}342343/*344* shift by count / limb_size345*/346if (v0 > 0) {347for (i = 0; i < limbs - v0; i++) {348X[i] = X[i + v0];349}350351for (; i < limbs; i++) {352X[i] = 0;353}354}355356/*357* shift by count % limb_size358*/359if (v1 > 0) {360for (i = limbs; i > 0; i--) {361r1 = X[i - 1] << (biL - v1);362X[i - 1] >>= v1;363X[i - 1] |= r0;364r0 = r1;365}366}367}368369void mbedtls_mpi_core_shift_l(mbedtls_mpi_uint *X, size_t limbs,370size_t count)371{372size_t i, v0, v1;373mbedtls_mpi_uint r0 = 0, r1;374375v0 = count / (biL);376v1 = count & (biL - 1);377378/*379* shift by count / limb_size380*/381if (v0 > 0) {382for (i = limbs; i > v0; i--) {383X[i - 1] = X[i - v0 - 1];384}385386for (; i > 0; i--) {387X[i - 1] = 0;388}389}390391/*392* shift by count % limb_size393*/394if (v1 > 0) {395for (i = v0; i < limbs; i++) {396r1 = X[i] >> (biL - v1);397X[i] <<= v1;398X[i] |= r0;399r0 = r1;400}401}402}403404mbedtls_mpi_uint mbedtls_mpi_core_add(mbedtls_mpi_uint *X,405const mbedtls_mpi_uint *A,406const mbedtls_mpi_uint *B,407size_t limbs)408{409mbedtls_mpi_uint c = 0;410411for (size_t i = 0; i < limbs; i++) {412mbedtls_mpi_uint t = c + A[i];413c = (t < A[i]);414t += B[i];415c += (t < B[i]);416X[i] = t;417}418419return c;420}421422mbedtls_mpi_uint mbedtls_mpi_core_add_if(mbedtls_mpi_uint *X,423const mbedtls_mpi_uint *A,424size_t limbs,425unsigned cond)426{427mbedtls_mpi_uint c = 0;428429mbedtls_ct_condition_t do_add = mbedtls_ct_bool(cond);430431for (size_t i = 0; i < limbs; i++) {432mbedtls_mpi_uint add = mbedtls_ct_mpi_uint_if_else_0(do_add, A[i]);433mbedtls_mpi_uint t = c + X[i];434c = (t < X[i]);435t += add;436c += (t < add);437X[i] = t;438}439440return c;441}442443mbedtls_mpi_uint mbedtls_mpi_core_sub(mbedtls_mpi_uint *X,444const mbedtls_mpi_uint *A,445const mbedtls_mpi_uint *B,446size_t limbs)447{448mbedtls_mpi_uint c = 0;449450for (size_t i = 0; i < limbs; i++) {451mbedtls_mpi_uint z = (A[i] < c);452mbedtls_mpi_uint t = A[i] - c;453c = (t < B[i]) + z;454X[i] = t - B[i];455}456457return c;458}459460mbedtls_mpi_uint mbedtls_mpi_core_mla(mbedtls_mpi_uint *d, size_t d_len,461const mbedtls_mpi_uint *s, size_t s_len,462mbedtls_mpi_uint b)463{464mbedtls_mpi_uint c = 0; /* carry */465/*466* It is a documented precondition of this function that d_len >= s_len.467* If that's not the case, we swap these round: this turns what would be468* a buffer overflow into an incorrect result.469*/470if (d_len < s_len) {471s_len = d_len;472}473size_t excess_len = d_len - s_len;474size_t steps_x8 = s_len / 8;475size_t steps_x1 = s_len & 7;476477while (steps_x8--) {478MULADDC_X8_INIT479MULADDC_X8_CORE480MULADDC_X8_STOP481}482483while (steps_x1--) {484MULADDC_X1_INIT485MULADDC_X1_CORE486MULADDC_X1_STOP487}488489while (excess_len--) {490*d += c;491c = (*d < c);492d++;493}494495return c;496}497498void mbedtls_mpi_core_mul(mbedtls_mpi_uint *X,499const mbedtls_mpi_uint *A, size_t A_limbs,500const mbedtls_mpi_uint *B, size_t B_limbs)501{502memset(X, 0, (A_limbs + B_limbs) * ciL);503504for (size_t i = 0; i < B_limbs; i++) {505(void) mbedtls_mpi_core_mla(X + i, A_limbs + 1, A, A_limbs, B[i]);506}507}508509/*510* Fast Montgomery initialization (thanks to Tom St Denis).511*/512mbedtls_mpi_uint mbedtls_mpi_core_montmul_init(const mbedtls_mpi_uint *N)513{514mbedtls_mpi_uint x = N[0];515516x += ((N[0] + 2) & 4) << 1;517518for (unsigned int i = biL; i >= 8; i /= 2) {519x *= (2 - (N[0] * x));520}521522return ~x + 1;523}524525void mbedtls_mpi_core_montmul(mbedtls_mpi_uint *X,526const mbedtls_mpi_uint *A,527const mbedtls_mpi_uint *B,528size_t B_limbs,529const mbedtls_mpi_uint *N,530size_t AN_limbs,531mbedtls_mpi_uint mm,532mbedtls_mpi_uint *T)533{534memset(T, 0, (2 * AN_limbs + 1) * ciL);535536for (size_t i = 0; i < AN_limbs; i++) {537/* T = (T + u0*B + u1*N) / 2^biL */538mbedtls_mpi_uint u0 = A[i];539mbedtls_mpi_uint u1 = (T[0] + u0 * B[0]) * mm;540541(void) mbedtls_mpi_core_mla(T, AN_limbs + 2, B, B_limbs, u0);542(void) mbedtls_mpi_core_mla(T, AN_limbs + 2, N, AN_limbs, u1);543544T++;545}546547/*548* The result we want is (T >= N) ? T - N : T.549*550* For better constant-time properties in this function, we always do the551* subtraction, with the result in X.552*553* We also look to see if there was any carry in the final additions in the554* loop above.555*/556557mbedtls_mpi_uint carry = T[AN_limbs];558mbedtls_mpi_uint borrow = mbedtls_mpi_core_sub(X, T, N, AN_limbs);559560/*561* Using R as the Montgomery radix (auxiliary modulus) i.e. 2^(biL*AN_limbs):562*563* T can be in one of 3 ranges:564*565* 1) T < N : (carry, borrow) = (0, 1): we want T566* 2) N <= T < R : (carry, borrow) = (0, 0): we want X567* 3) T >= R : (carry, borrow) = (1, 1): we want X568*569* and (carry, borrow) = (1, 0) can't happen.570*571* So the correct return value is already in X if (carry ^ borrow) = 0,572* but is in (the lower AN_limbs limbs of) T if (carry ^ borrow) = 1.573*/574mbedtls_ct_memcpy_if(mbedtls_ct_bool(carry ^ borrow),575(unsigned char *) X,576(unsigned char *) T,577NULL,578AN_limbs * sizeof(mbedtls_mpi_uint));579}580581int mbedtls_mpi_core_get_mont_r2_unsafe(mbedtls_mpi *X,582const mbedtls_mpi *N)583{584int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;585586MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 1));587MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(X, N->n * 2 * biL));588MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(X, X, N));589MBEDTLS_MPI_CHK(mbedtls_mpi_shrink(X, N->n));590591cleanup:592return ret;593}594595MBEDTLS_STATIC_TESTABLE596void mbedtls_mpi_core_ct_uint_table_lookup(mbedtls_mpi_uint *dest,597const mbedtls_mpi_uint *table,598size_t limbs,599size_t count,600size_t index)601{602for (size_t i = 0; i < count; i++, table += limbs) {603mbedtls_ct_condition_t assign = mbedtls_ct_uint_eq(i, index);604mbedtls_mpi_core_cond_assign(dest, table, limbs, assign);605}606}607608/* Fill X with n_bytes random bytes.609* X must already have room for those bytes.610* The ordering of the bytes returned from the RNG is suitable for611* deterministic ECDSA (see RFC 6979 §3.3 and the specification of612* mbedtls_mpi_core_random()).613*/614int mbedtls_mpi_core_fill_random(615mbedtls_mpi_uint *X, size_t X_limbs,616size_t n_bytes,617int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)618{619int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;620const size_t limbs = CHARS_TO_LIMBS(n_bytes);621const size_t overhead = (limbs * ciL) - n_bytes;622623if (X_limbs < limbs) {624return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;625}626627memset(X, 0, overhead);628memset((unsigned char *) X + limbs * ciL, 0, (X_limbs - limbs) * ciL);629MBEDTLS_MPI_CHK(f_rng(p_rng, (unsigned char *) X + overhead, n_bytes));630mbedtls_mpi_core_bigendian_to_host(X, limbs);631632cleanup:633return ret;634}635636int mbedtls_mpi_core_random(mbedtls_mpi_uint *X,637mbedtls_mpi_uint min,638const mbedtls_mpi_uint *N,639size_t limbs,640int (*f_rng)(void *, unsigned char *, size_t),641void *p_rng)642{643mbedtls_ct_condition_t ge_lower = MBEDTLS_CT_TRUE, lt_upper = MBEDTLS_CT_FALSE;644size_t n_bits = mbedtls_mpi_core_bitlen(N, limbs);645size_t n_bytes = (n_bits + 7) / 8;646int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;647648/*649* When min == 0, each try has at worst a probability 1/2 of failing650* (the msb has a probability 1/2 of being 0, and then the result will651* be < N), so after 30 tries failure probability is a most 2**(-30).652*653* When N is just below a power of 2, as is the case when generating654* a random scalar on most elliptic curves, 1 try is enough with655* overwhelming probability. When N is just above a power of 2,656* as when generating a random scalar on secp224k1, each try has657* a probability of failing that is almost 1/2.658*659* The probabilities are almost the same if min is nonzero but negligible660* compared to N. This is always the case when N is crypto-sized, but661* it's convenient to support small N for testing purposes. When N662* is small, use a higher repeat count, otherwise the probability of663* failure is macroscopic.664*/665int count = (n_bytes > 4 ? 30 : 250);666667/*668* Match the procedure given in RFC 6979 §3.3 (deterministic ECDSA)669* when f_rng is a suitably parametrized instance of HMAC_DRBG:670* - use the same byte ordering;671* - keep the leftmost n_bits bits of the generated octet string;672* - try until result is in the desired range.673* This also avoids any bias, which is especially important for ECDSA.674*/675do {676MBEDTLS_MPI_CHK(mbedtls_mpi_core_fill_random(X, limbs,677n_bytes,678f_rng, p_rng));679mbedtls_mpi_core_shift_r(X, limbs, 8 * n_bytes - n_bits);680681if (--count == 0) {682ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;683goto cleanup;684}685686ge_lower = mbedtls_mpi_core_uint_le_mpi(min, X, limbs);687lt_upper = mbedtls_mpi_core_lt_ct(X, N, limbs);688} while (mbedtls_ct_bool_and(ge_lower, lt_upper) == MBEDTLS_CT_FALSE);689690cleanup:691return ret;692}693694static size_t exp_mod_get_window_size(size_t Ebits)695{696#if MBEDTLS_MPI_WINDOW_SIZE >= 6697return (Ebits > 671) ? 6 : (Ebits > 239) ? 5 : (Ebits > 79) ? 4 : 1;698#elif MBEDTLS_MPI_WINDOW_SIZE == 5699return (Ebits > 239) ? 5 : (Ebits > 79) ? 4 : 1;700#elif MBEDTLS_MPI_WINDOW_SIZE > 1701return (Ebits > 79) ? MBEDTLS_MPI_WINDOW_SIZE : 1;702#else703(void) Ebits;704return 1;705#endif706}707708size_t mbedtls_mpi_core_exp_mod_working_limbs(size_t AN_limbs, size_t E_limbs)709{710const size_t wsize = exp_mod_get_window_size(E_limbs * biL);711const size_t welem = ((size_t) 1) << wsize;712713/* How big does each part of the working memory pool need to be? */714const size_t table_limbs = welem * AN_limbs;715const size_t select_limbs = AN_limbs;716const size_t temp_limbs = 2 * AN_limbs + 1;717718return table_limbs + select_limbs + temp_limbs;719}720721static void exp_mod_precompute_window(const mbedtls_mpi_uint *A,722const mbedtls_mpi_uint *N,723size_t AN_limbs,724mbedtls_mpi_uint mm,725const mbedtls_mpi_uint *RR,726size_t welem,727mbedtls_mpi_uint *Wtable,728mbedtls_mpi_uint *temp)729{730/* W[0] = 1 (in Montgomery presentation) */731memset(Wtable, 0, AN_limbs * ciL);732Wtable[0] = 1;733mbedtls_mpi_core_montmul(Wtable, Wtable, RR, AN_limbs, N, AN_limbs, mm, temp);734735/* W[1] = A (already in Montgomery presentation) */736mbedtls_mpi_uint *W1 = Wtable + AN_limbs;737memcpy(W1, A, AN_limbs * ciL);738739/* W[i+1] = W[i] * W[1], i >= 2 */740mbedtls_mpi_uint *Wprev = W1;741for (size_t i = 2; i < welem; i++) {742mbedtls_mpi_uint *Wcur = Wprev + AN_limbs;743mbedtls_mpi_core_montmul(Wcur, Wprev, W1, AN_limbs, N, AN_limbs, mm, temp);744Wprev = Wcur;745}746}747748#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)749void (*mbedtls_safe_codepath_hook)(void) = NULL;750void (*mbedtls_unsafe_codepath_hook)(void) = NULL;751#endif752753/*754* This function calculates the indices of the exponent where the exponentiation algorithm should755* start processing.756*757* Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value,758* this function is not constant time with respect to the exponent (parameter E).759*/760static inline void exp_mod_calc_first_bit_optionally_safe(const mbedtls_mpi_uint *E,761size_t E_limbs,762int E_public,763size_t *E_limb_index,764size_t *E_bit_index)765{766if (E_public == MBEDTLS_MPI_IS_PUBLIC) {767/*768* Skip leading zero bits.769*/770size_t E_bits = mbedtls_mpi_core_bitlen(E, E_limbs);771if (E_bits == 0) {772/*773* If E is 0 mbedtls_mpi_core_bitlen() returns 0. Even if that is the case, we will want774* to represent it as a single 0 bit and as such the bitlength will be 1.775*/776E_bits = 1;777}778779*E_limb_index = E_bits / biL;780*E_bit_index = E_bits % biL;781782#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)783if (mbedtls_unsafe_codepath_hook != NULL) {784mbedtls_unsafe_codepath_hook();785}786#endif787} else {788/*789* Here we need to be constant time with respect to E and can't do anything better than790* start at the first allocated bit.791*/792*E_limb_index = E_limbs;793*E_bit_index = 0;794#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)795if (mbedtls_safe_codepath_hook != NULL) {796mbedtls_safe_codepath_hook();797}798#endif799}800}801802/*803* Warning! If the parameter window_public has MBEDTLS_MPI_IS_PUBLIC as its value, this function is804* not constant time with respect to the window parameter and consequently the exponent of the805* exponentiation (parameter E of mbedtls_mpi_core_exp_mod_optionally_safe).806*/807static inline void exp_mod_table_lookup_optionally_safe(mbedtls_mpi_uint *Wselect,808mbedtls_mpi_uint *Wtable,809size_t AN_limbs, size_t welem,810mbedtls_mpi_uint window,811int window_public)812{813if (window_public == MBEDTLS_MPI_IS_PUBLIC) {814memcpy(Wselect, Wtable + window * AN_limbs, AN_limbs * ciL);815#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)816if (mbedtls_unsafe_codepath_hook != NULL) {817mbedtls_unsafe_codepath_hook();818}819#endif820} else {821/* Select Wtable[window] without leaking window through822* memory access patterns. */823mbedtls_mpi_core_ct_uint_table_lookup(Wselect, Wtable,824AN_limbs, welem, window);825#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)826if (mbedtls_safe_codepath_hook != NULL) {827mbedtls_safe_codepath_hook();828}829#endif830}831}832833/* Exponentiation: X := A^E mod N.834*835* Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value,836* this function is not constant time with respect to the exponent (parameter E).837*838* A must already be in Montgomery form.839*840* As in other bignum functions, assume that AN_limbs and E_limbs are nonzero.841*842* RR must contain 2^{2*biL} mod N.843*844* The algorithm is a variant of Left-to-right k-ary exponentiation: HAC 14.82845* (The difference is that the body in our loop processes a single bit instead846* of a full window.)847*/848static void mbedtls_mpi_core_exp_mod_optionally_safe(mbedtls_mpi_uint *X,849const mbedtls_mpi_uint *A,850const mbedtls_mpi_uint *N,851size_t AN_limbs,852const mbedtls_mpi_uint *E,853size_t E_limbs,854int E_public,855const mbedtls_mpi_uint *RR,856mbedtls_mpi_uint *T)857{858/* We'll process the bits of E from most significant859* (limb_index=E_limbs-1, E_bit_index=biL-1) to least significant860* (limb_index=0, E_bit_index=0). */861size_t E_limb_index = E_limbs;862size_t E_bit_index = 0;863exp_mod_calc_first_bit_optionally_safe(E, E_limbs, E_public,864&E_limb_index, &E_bit_index);865866const size_t wsize = exp_mod_get_window_size(E_limb_index * biL);867const size_t welem = ((size_t) 1) << wsize;868869/* This is how we will use the temporary storage T, which must have space870* for table_limbs, select_limbs and (2 * AN_limbs + 1) for montmul. */871const size_t table_limbs = welem * AN_limbs;872const size_t select_limbs = AN_limbs;873874/* Pointers to specific parts of the temporary working memory pool */875mbedtls_mpi_uint *const Wtable = T;876mbedtls_mpi_uint *const Wselect = Wtable + table_limbs;877mbedtls_mpi_uint *const temp = Wselect + select_limbs;878879/*880* Window precomputation881*/882883const mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N);884885/* Set Wtable[i] = A^i (in Montgomery representation) */886exp_mod_precompute_window(A, N, AN_limbs,887mm, RR,888welem, Wtable, temp);889890/*891* Fixed window exponentiation892*/893894/* X = 1 (in Montgomery presentation) initially */895memcpy(X, Wtable, AN_limbs * ciL);896897/* At any given time, window contains window_bits bits from E.898* window_bits can go up to wsize. */899size_t window_bits = 0;900mbedtls_mpi_uint window = 0;901902do {903/* Square */904mbedtls_mpi_core_montmul(X, X, X, AN_limbs, N, AN_limbs, mm, temp);905906/* Move to the next bit of the exponent */907if (E_bit_index == 0) {908--E_limb_index;909E_bit_index = biL - 1;910} else {911--E_bit_index;912}913/* Insert next exponent bit into window */914++window_bits;915window <<= 1;916window |= (E[E_limb_index] >> E_bit_index) & 1;917918/* Clear window if it's full. Also clear the window at the end,919* when we've finished processing the exponent. */920if (window_bits == wsize ||921(E_bit_index == 0 && E_limb_index == 0)) {922923exp_mod_table_lookup_optionally_safe(Wselect, Wtable, AN_limbs, welem,924window, E_public);925/* Multiply X by the selected element. */926mbedtls_mpi_core_montmul(X, X, Wselect, AN_limbs, N, AN_limbs, mm,927temp);928window = 0;929window_bits = 0;930}931} while (!(E_bit_index == 0 && E_limb_index == 0));932}933934void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X,935const mbedtls_mpi_uint *A,936const mbedtls_mpi_uint *N, size_t AN_limbs,937const mbedtls_mpi_uint *E, size_t E_limbs,938const mbedtls_mpi_uint *RR,939mbedtls_mpi_uint *T)940{941mbedtls_mpi_core_exp_mod_optionally_safe(X,942A,943N,944AN_limbs,945E,946E_limbs,947MBEDTLS_MPI_IS_SECRET,948RR,949T);950}951952void mbedtls_mpi_core_exp_mod_unsafe(mbedtls_mpi_uint *X,953const mbedtls_mpi_uint *A,954const mbedtls_mpi_uint *N, size_t AN_limbs,955const mbedtls_mpi_uint *E, size_t E_limbs,956const mbedtls_mpi_uint *RR,957mbedtls_mpi_uint *T)958{959mbedtls_mpi_core_exp_mod_optionally_safe(X,960A,961N,962AN_limbs,963E,964E_limbs,965MBEDTLS_MPI_IS_PUBLIC,966RR,967T);968}969970mbedtls_mpi_uint mbedtls_mpi_core_sub_int(mbedtls_mpi_uint *X,971const mbedtls_mpi_uint *A,972mbedtls_mpi_uint c, /* doubles as carry */973size_t limbs)974{975for (size_t i = 0; i < limbs; i++) {976mbedtls_mpi_uint s = A[i];977mbedtls_mpi_uint t = s - c;978c = (t > s);979X[i] = t;980}981982return c;983}984985mbedtls_ct_condition_t mbedtls_mpi_core_check_zero_ct(const mbedtls_mpi_uint *A,986size_t limbs)987{988volatile const mbedtls_mpi_uint *force_read_A = A;989mbedtls_mpi_uint bits = 0;990991for (size_t i = 0; i < limbs; i++) {992bits |= force_read_A[i];993}994995return mbedtls_ct_bool(bits);996}997998void mbedtls_mpi_core_to_mont_rep(mbedtls_mpi_uint *X,999const mbedtls_mpi_uint *A,1000const mbedtls_mpi_uint *N,1001size_t AN_limbs,1002mbedtls_mpi_uint mm,1003const mbedtls_mpi_uint *rr,1004mbedtls_mpi_uint *T)1005{1006mbedtls_mpi_core_montmul(X, A, rr, AN_limbs, N, AN_limbs, mm, T);1007}10081009void mbedtls_mpi_core_from_mont_rep(mbedtls_mpi_uint *X,1010const mbedtls_mpi_uint *A,1011const mbedtls_mpi_uint *N,1012size_t AN_limbs,1013mbedtls_mpi_uint mm,1014mbedtls_mpi_uint *T)1015{1016const mbedtls_mpi_uint Rinv = 1; /* 1/R in Mont. rep => 1 */10171018mbedtls_mpi_core_montmul(X, A, &Rinv, 1, N, AN_limbs, mm, T);1019}10201021#endif /* MBEDTLS_BIGNUM_C */102210231024