1*32b31808SJens Wiklander /** 2*32b31808SJens Wiklander * Modular bignum functions 3*32b31808SJens Wiklander * 4*32b31808SJens Wiklander * Copyright The Mbed TLS Contributors 5*32b31808SJens Wiklander * SPDX-License-Identifier: Apache-2.0 6*32b31808SJens Wiklander * 7*32b31808SJens Wiklander * Licensed under the Apache License, Version 2.0 (the "License"); you may 8*32b31808SJens Wiklander * not use this file except in compliance with the License. 9*32b31808SJens Wiklander * You may obtain a copy of the License at 10*32b31808SJens Wiklander * 11*32b31808SJens Wiklander * http://www.apache.org/licenses/LICENSE-2.0 12*32b31808SJens Wiklander * 13*32b31808SJens Wiklander * Unless required by applicable law or agreed to in writing, software 14*32b31808SJens Wiklander * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15*32b31808SJens Wiklander * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16*32b31808SJens Wiklander * See the License for the specific language governing permissions and 17*32b31808SJens Wiklander * limitations under the License. 18*32b31808SJens Wiklander */ 19*32b31808SJens Wiklander 20*32b31808SJens Wiklander #include "common.h" 21*32b31808SJens Wiklander 22*32b31808SJens Wiklander #if defined(MBEDTLS_BIGNUM_C) 23*32b31808SJens Wiklander 24*32b31808SJens Wiklander #include <string.h> 25*32b31808SJens Wiklander 26*32b31808SJens Wiklander #include "mbedtls/platform_util.h" 27*32b31808SJens Wiklander #include "mbedtls/error.h" 28*32b31808SJens Wiklander #include "mbedtls/bignum.h" 29*32b31808SJens Wiklander 30*32b31808SJens Wiklander #include "mbedtls/platform.h" 31*32b31808SJens Wiklander 32*32b31808SJens Wiklander #include "bignum_core.h" 33*32b31808SJens Wiklander #include "bignum_mod.h" 34*32b31808SJens Wiklander #include "bignum_mod_raw.h" 35*32b31808SJens Wiklander #include "constant_time_internal.h" 36*32b31808SJens Wiklander 37*32b31808SJens Wiklander int mbedtls_mpi_mod_residue_setup(mbedtls_mpi_mod_residue *r, 38*32b31808SJens Wiklander const mbedtls_mpi_mod_modulus *N, 39*32b31808SJens Wiklander mbedtls_mpi_uint *p, 40*32b31808SJens Wiklander size_t p_limbs) 41*32b31808SJens Wiklander { 42*32b31808SJens Wiklander if (p_limbs != N->limbs || !mbedtls_mpi_core_lt_ct(p, N->p, N->limbs)) { 43*32b31808SJens Wiklander return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; 44*32b31808SJens Wiklander } 45*32b31808SJens Wiklander 46*32b31808SJens Wiklander r->limbs = N->limbs; 47*32b31808SJens Wiklander r->p = p; 48*32b31808SJens Wiklander 49*32b31808SJens Wiklander return 0; 50*32b31808SJens Wiklander } 51*32b31808SJens Wiklander 52*32b31808SJens Wiklander void mbedtls_mpi_mod_residue_release(mbedtls_mpi_mod_residue *r) 53*32b31808SJens Wiklander { 54*32b31808SJens Wiklander if (r == NULL) { 55*32b31808SJens Wiklander return; 56*32b31808SJens Wiklander } 57*32b31808SJens Wiklander 58*32b31808SJens Wiklander r->limbs = 0; 59*32b31808SJens Wiklander r->p = NULL; 60*32b31808SJens Wiklander } 61*32b31808SJens Wiklander 62*32b31808SJens Wiklander void mbedtls_mpi_mod_modulus_init(mbedtls_mpi_mod_modulus *N) 63*32b31808SJens Wiklander { 64*32b31808SJens Wiklander if (N == NULL) { 65*32b31808SJens Wiklander return; 66*32b31808SJens Wiklander } 67*32b31808SJens Wiklander 68*32b31808SJens Wiklander N->p = NULL; 69*32b31808SJens Wiklander N->limbs = 0; 70*32b31808SJens Wiklander N->bits = 0; 71*32b31808SJens Wiklander N->int_rep = MBEDTLS_MPI_MOD_REP_INVALID; 72*32b31808SJens Wiklander } 73*32b31808SJens Wiklander 74*32b31808SJens Wiklander void mbedtls_mpi_mod_modulus_free(mbedtls_mpi_mod_modulus *N) 75*32b31808SJens Wiklander { 76*32b31808SJens Wiklander if (N == NULL) { 77*32b31808SJens Wiklander return; 78*32b31808SJens Wiklander } 79*32b31808SJens Wiklander 80*32b31808SJens Wiklander switch (N->int_rep) { 81*32b31808SJens Wiklander case MBEDTLS_MPI_MOD_REP_MONTGOMERY: 82*32b31808SJens Wiklander if (N->rep.mont.rr != NULL) { 83*32b31808SJens Wiklander mbedtls_platform_zeroize((mbedtls_mpi_uint *) N->rep.mont.rr, 84*32b31808SJens Wiklander N->limbs * sizeof(mbedtls_mpi_uint)); 85*32b31808SJens Wiklander mbedtls_free((mbedtls_mpi_uint *) N->rep.mont.rr); 86*32b31808SJens Wiklander N->rep.mont.rr = NULL; 87*32b31808SJens Wiklander } 88*32b31808SJens Wiklander N->rep.mont.mm = 0; 89*32b31808SJens Wiklander break; 90*32b31808SJens Wiklander case MBEDTLS_MPI_MOD_REP_OPT_RED: 91*32b31808SJens Wiklander mbedtls_free(N->rep.ored); 92*32b31808SJens Wiklander break; 93*32b31808SJens Wiklander case MBEDTLS_MPI_MOD_REP_INVALID: 94*32b31808SJens Wiklander break; 95*32b31808SJens Wiklander } 96*32b31808SJens Wiklander 97*32b31808SJens Wiklander N->p = NULL; 98*32b31808SJens Wiklander N->limbs = 0; 99*32b31808SJens Wiklander N->bits = 0; 100*32b31808SJens Wiklander N->int_rep = MBEDTLS_MPI_MOD_REP_INVALID; 101*32b31808SJens Wiklander } 102*32b31808SJens Wiklander 103*32b31808SJens Wiklander static int set_mont_const_square(const mbedtls_mpi_uint **X, 104*32b31808SJens Wiklander const mbedtls_mpi_uint *A, 105*32b31808SJens Wiklander size_t limbs) 106*32b31808SJens Wiklander { 107*32b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 108*32b31808SJens Wiklander mbedtls_mpi N; 109*32b31808SJens Wiklander mbedtls_mpi RR; 110*32b31808SJens Wiklander *X = NULL; 111*32b31808SJens Wiklander 112*32b31808SJens Wiklander mbedtls_mpi_init(&N); 113*32b31808SJens Wiklander mbedtls_mpi_init(&RR); 114*32b31808SJens Wiklander 115*32b31808SJens Wiklander if (A == NULL || limbs == 0 || limbs >= (MBEDTLS_MPI_MAX_LIMBS / 2) - 2) { 116*32b31808SJens Wiklander goto cleanup; 117*32b31808SJens Wiklander } 118*32b31808SJens Wiklander 119*32b31808SJens Wiklander if (mbedtls_mpi_grow(&N, limbs)) { 120*32b31808SJens Wiklander goto cleanup; 121*32b31808SJens Wiklander } 122*32b31808SJens Wiklander 123*32b31808SJens Wiklander memcpy(N.p, A, sizeof(mbedtls_mpi_uint) * limbs); 124*32b31808SJens Wiklander 125*32b31808SJens Wiklander ret = mbedtls_mpi_core_get_mont_r2_unsafe(&RR, &N); 126*32b31808SJens Wiklander 127*32b31808SJens Wiklander if (ret == 0) { 128*32b31808SJens Wiklander *X = RR.p; 129*32b31808SJens Wiklander RR.p = NULL; 130*32b31808SJens Wiklander } 131*32b31808SJens Wiklander 132*32b31808SJens Wiklander cleanup: 133*32b31808SJens Wiklander mbedtls_mpi_free(&N); 134*32b31808SJens Wiklander mbedtls_mpi_free(&RR); 135*32b31808SJens Wiklander ret = (ret != 0) ? MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED : 0; 136*32b31808SJens Wiklander return ret; 137*32b31808SJens Wiklander } 138*32b31808SJens Wiklander 139*32b31808SJens Wiklander int mbedtls_mpi_mod_modulus_setup(mbedtls_mpi_mod_modulus *N, 140*32b31808SJens Wiklander const mbedtls_mpi_uint *p, 141*32b31808SJens Wiklander size_t p_limbs, 142*32b31808SJens Wiklander mbedtls_mpi_mod_rep_selector int_rep) 143*32b31808SJens Wiklander { 144*32b31808SJens Wiklander int ret = 0; 145*32b31808SJens Wiklander 146*32b31808SJens Wiklander N->p = p; 147*32b31808SJens Wiklander N->limbs = p_limbs; 148*32b31808SJens Wiklander N->bits = mbedtls_mpi_core_bitlen(p, p_limbs); 149*32b31808SJens Wiklander 150*32b31808SJens Wiklander switch (int_rep) { 151*32b31808SJens Wiklander case MBEDTLS_MPI_MOD_REP_MONTGOMERY: 152*32b31808SJens Wiklander N->int_rep = int_rep; 153*32b31808SJens Wiklander N->rep.mont.mm = mbedtls_mpi_core_montmul_init(N->p); 154*32b31808SJens Wiklander ret = set_mont_const_square(&N->rep.mont.rr, N->p, N->limbs); 155*32b31808SJens Wiklander break; 156*32b31808SJens Wiklander case MBEDTLS_MPI_MOD_REP_OPT_RED: 157*32b31808SJens Wiklander N->int_rep = int_rep; 158*32b31808SJens Wiklander N->rep.ored = NULL; 159*32b31808SJens Wiklander break; 160*32b31808SJens Wiklander default: 161*32b31808SJens Wiklander ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; 162*32b31808SJens Wiklander goto exit; 163*32b31808SJens Wiklander } 164*32b31808SJens Wiklander 165*32b31808SJens Wiklander exit: 166*32b31808SJens Wiklander 167*32b31808SJens Wiklander if (ret != 0) { 168*32b31808SJens Wiklander mbedtls_mpi_mod_modulus_free(N); 169*32b31808SJens Wiklander } 170*32b31808SJens Wiklander 171*32b31808SJens Wiklander return ret; 172*32b31808SJens Wiklander } 173*32b31808SJens Wiklander 174*32b31808SJens Wiklander /* BEGIN MERGE SLOT 1 */ 175*32b31808SJens Wiklander 176*32b31808SJens Wiklander /* END MERGE SLOT 1 */ 177*32b31808SJens Wiklander 178*32b31808SJens Wiklander /* BEGIN MERGE SLOT 2 */ 179*32b31808SJens Wiklander 180*32b31808SJens Wiklander int mbedtls_mpi_mod_mul(mbedtls_mpi_mod_residue *X, 181*32b31808SJens Wiklander const mbedtls_mpi_mod_residue *A, 182*32b31808SJens Wiklander const mbedtls_mpi_mod_residue *B, 183*32b31808SJens Wiklander const mbedtls_mpi_mod_modulus *N) 184*32b31808SJens Wiklander { 185*32b31808SJens Wiklander if (N->limbs == 0) { 186*32b31808SJens Wiklander return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; 187*32b31808SJens Wiklander } 188*32b31808SJens Wiklander 189*32b31808SJens Wiklander if (X->limbs != N->limbs || A->limbs != N->limbs || B->limbs != N->limbs) { 190*32b31808SJens Wiklander return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; 191*32b31808SJens Wiklander } 192*32b31808SJens Wiklander 193*32b31808SJens Wiklander mbedtls_mpi_uint *T = mbedtls_calloc(N->limbs * 2 + 1, ciL); 194*32b31808SJens Wiklander if (T == NULL) { 195*32b31808SJens Wiklander return MBEDTLS_ERR_MPI_ALLOC_FAILED; 196*32b31808SJens Wiklander } 197*32b31808SJens Wiklander 198*32b31808SJens Wiklander mbedtls_mpi_mod_raw_mul(X->p, A->p, B->p, N, T); 199*32b31808SJens Wiklander 200*32b31808SJens Wiklander mbedtls_free(T); 201*32b31808SJens Wiklander 202*32b31808SJens Wiklander return 0; 203*32b31808SJens Wiklander } 204*32b31808SJens Wiklander 205*32b31808SJens Wiklander /* END MERGE SLOT 2 */ 206*32b31808SJens Wiklander 207*32b31808SJens Wiklander /* BEGIN MERGE SLOT 3 */ 208*32b31808SJens Wiklander int mbedtls_mpi_mod_sub(mbedtls_mpi_mod_residue *X, 209*32b31808SJens Wiklander const mbedtls_mpi_mod_residue *A, 210*32b31808SJens Wiklander const mbedtls_mpi_mod_residue *B, 211*32b31808SJens Wiklander const mbedtls_mpi_mod_modulus *N) 212*32b31808SJens Wiklander { 213*32b31808SJens Wiklander if (X->limbs != N->limbs || A->limbs != N->limbs || B->limbs != N->limbs) { 214*32b31808SJens Wiklander return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; 215*32b31808SJens Wiklander } 216*32b31808SJens Wiklander 217*32b31808SJens Wiklander mbedtls_mpi_mod_raw_sub(X->p, A->p, B->p, N); 218*32b31808SJens Wiklander 219*32b31808SJens Wiklander return 0; 220*32b31808SJens Wiklander } 221*32b31808SJens Wiklander 222*32b31808SJens Wiklander static int mbedtls_mpi_mod_inv_mont(mbedtls_mpi_mod_residue *X, 223*32b31808SJens Wiklander const mbedtls_mpi_mod_residue *A, 224*32b31808SJens Wiklander const mbedtls_mpi_mod_modulus *N, 225*32b31808SJens Wiklander mbedtls_mpi_uint *working_memory) 226*32b31808SJens Wiklander { 227*32b31808SJens Wiklander /* Input already in Montgomery form, so there's little to do */ 228*32b31808SJens Wiklander mbedtls_mpi_mod_raw_inv_prime(X->p, A->p, 229*32b31808SJens Wiklander N->p, N->limbs, 230*32b31808SJens Wiklander N->rep.mont.rr, 231*32b31808SJens Wiklander working_memory); 232*32b31808SJens Wiklander return 0; 233*32b31808SJens Wiklander } 234*32b31808SJens Wiklander 235*32b31808SJens Wiklander static int mbedtls_mpi_mod_inv_non_mont(mbedtls_mpi_mod_residue *X, 236*32b31808SJens Wiklander const mbedtls_mpi_mod_residue *A, 237*32b31808SJens Wiklander const mbedtls_mpi_mod_modulus *N, 238*32b31808SJens Wiklander mbedtls_mpi_uint *working_memory) 239*32b31808SJens Wiklander { 240*32b31808SJens Wiklander /* Need to convert input into Montgomery form */ 241*32b31808SJens Wiklander 242*32b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 243*32b31808SJens Wiklander 244*32b31808SJens Wiklander mbedtls_mpi_mod_modulus Nmont; 245*32b31808SJens Wiklander mbedtls_mpi_mod_modulus_init(&Nmont); 246*32b31808SJens Wiklander 247*32b31808SJens Wiklander MBEDTLS_MPI_CHK(mbedtls_mpi_mod_modulus_setup(&Nmont, N->p, N->limbs, 248*32b31808SJens Wiklander MBEDTLS_MPI_MOD_REP_MONTGOMERY)); 249*32b31808SJens Wiklander 250*32b31808SJens Wiklander /* We'll use X->p to hold the Montgomery form of the input A->p */ 251*32b31808SJens Wiklander mbedtls_mpi_core_to_mont_rep(X->p, A->p, Nmont.p, Nmont.limbs, 252*32b31808SJens Wiklander Nmont.rep.mont.mm, Nmont.rep.mont.rr, 253*32b31808SJens Wiklander working_memory); 254*32b31808SJens Wiklander 255*32b31808SJens Wiklander mbedtls_mpi_mod_raw_inv_prime(X->p, X->p, 256*32b31808SJens Wiklander Nmont.p, Nmont.limbs, 257*32b31808SJens Wiklander Nmont.rep.mont.rr, 258*32b31808SJens Wiklander working_memory); 259*32b31808SJens Wiklander 260*32b31808SJens Wiklander /* And convert back from Montgomery form */ 261*32b31808SJens Wiklander 262*32b31808SJens Wiklander mbedtls_mpi_core_from_mont_rep(X->p, X->p, Nmont.p, Nmont.limbs, 263*32b31808SJens Wiklander Nmont.rep.mont.mm, working_memory); 264*32b31808SJens Wiklander 265*32b31808SJens Wiklander cleanup: 266*32b31808SJens Wiklander mbedtls_mpi_mod_modulus_free(&Nmont); 267*32b31808SJens Wiklander return ret; 268*32b31808SJens Wiklander } 269*32b31808SJens Wiklander 270*32b31808SJens Wiklander int mbedtls_mpi_mod_inv(mbedtls_mpi_mod_residue *X, 271*32b31808SJens Wiklander const mbedtls_mpi_mod_residue *A, 272*32b31808SJens Wiklander const mbedtls_mpi_mod_modulus *N) 273*32b31808SJens Wiklander { 274*32b31808SJens Wiklander if (X->limbs != N->limbs || A->limbs != N->limbs) { 275*32b31808SJens Wiklander return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; 276*32b31808SJens Wiklander } 277*32b31808SJens Wiklander 278*32b31808SJens Wiklander /* Zero has the same value regardless of Montgomery form or not */ 279*32b31808SJens Wiklander if (mbedtls_mpi_core_check_zero_ct(A->p, A->limbs) == 0) { 280*32b31808SJens Wiklander return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; 281*32b31808SJens Wiklander } 282*32b31808SJens Wiklander 283*32b31808SJens Wiklander size_t working_limbs = 284*32b31808SJens Wiklander mbedtls_mpi_mod_raw_inv_prime_working_limbs(N->limbs); 285*32b31808SJens Wiklander 286*32b31808SJens Wiklander mbedtls_mpi_uint *working_memory = mbedtls_calloc(working_limbs, 287*32b31808SJens Wiklander sizeof(mbedtls_mpi_uint)); 288*32b31808SJens Wiklander if (working_memory == NULL) { 289*32b31808SJens Wiklander return MBEDTLS_ERR_MPI_ALLOC_FAILED; 290*32b31808SJens Wiklander } 291*32b31808SJens Wiklander 292*32b31808SJens Wiklander int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 293*32b31808SJens Wiklander 294*32b31808SJens Wiklander switch (N->int_rep) { 295*32b31808SJens Wiklander case MBEDTLS_MPI_MOD_REP_MONTGOMERY: 296*32b31808SJens Wiklander ret = mbedtls_mpi_mod_inv_mont(X, A, N, working_memory); 297*32b31808SJens Wiklander break; 298*32b31808SJens Wiklander case MBEDTLS_MPI_MOD_REP_OPT_RED: 299*32b31808SJens Wiklander ret = mbedtls_mpi_mod_inv_non_mont(X, A, N, working_memory); 300*32b31808SJens Wiklander break; 301*32b31808SJens Wiklander default: 302*32b31808SJens Wiklander ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; 303*32b31808SJens Wiklander break; 304*32b31808SJens Wiklander } 305*32b31808SJens Wiklander 306*32b31808SJens Wiklander mbedtls_platform_zeroize(working_memory, 307*32b31808SJens Wiklander working_limbs * sizeof(mbedtls_mpi_uint)); 308*32b31808SJens Wiklander mbedtls_free(working_memory); 309*32b31808SJens Wiklander 310*32b31808SJens Wiklander return ret; 311*32b31808SJens Wiklander } 312*32b31808SJens Wiklander /* END MERGE SLOT 3 */ 313*32b31808SJens Wiklander 314*32b31808SJens Wiklander /* BEGIN MERGE SLOT 4 */ 315*32b31808SJens Wiklander 316*32b31808SJens Wiklander /* END MERGE SLOT 4 */ 317*32b31808SJens Wiklander 318*32b31808SJens Wiklander /* BEGIN MERGE SLOT 5 */ 319*32b31808SJens Wiklander int mbedtls_mpi_mod_add(mbedtls_mpi_mod_residue *X, 320*32b31808SJens Wiklander const mbedtls_mpi_mod_residue *A, 321*32b31808SJens Wiklander const mbedtls_mpi_mod_residue *B, 322*32b31808SJens Wiklander const mbedtls_mpi_mod_modulus *N) 323*32b31808SJens Wiklander { 324*32b31808SJens Wiklander if (X->limbs != N->limbs || A->limbs != N->limbs || B->limbs != N->limbs) { 325*32b31808SJens Wiklander return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; 326*32b31808SJens Wiklander } 327*32b31808SJens Wiklander 328*32b31808SJens Wiklander mbedtls_mpi_mod_raw_add(X->p, A->p, B->p, N); 329*32b31808SJens Wiklander 330*32b31808SJens Wiklander return 0; 331*32b31808SJens Wiklander } 332*32b31808SJens Wiklander /* END MERGE SLOT 5 */ 333*32b31808SJens Wiklander 334*32b31808SJens Wiklander /* BEGIN MERGE SLOT 6 */ 335*32b31808SJens Wiklander 336*32b31808SJens Wiklander int mbedtls_mpi_mod_random(mbedtls_mpi_mod_residue *X, 337*32b31808SJens Wiklander mbedtls_mpi_uint min, 338*32b31808SJens Wiklander const mbedtls_mpi_mod_modulus *N, 339*32b31808SJens Wiklander int (*f_rng)(void *, unsigned char *, size_t), 340*32b31808SJens Wiklander void *p_rng) 341*32b31808SJens Wiklander { 342*32b31808SJens Wiklander if (X->limbs != N->limbs) { 343*32b31808SJens Wiklander return MBEDTLS_ERR_MPI_BAD_INPUT_DATA; 344*32b31808SJens Wiklander } 345*32b31808SJens Wiklander return mbedtls_mpi_mod_raw_random(X->p, min, N, f_rng, p_rng); 346*32b31808SJens Wiklander } 347*32b31808SJens Wiklander 348*32b31808SJens Wiklander /* END MERGE SLOT 6 */ 349*32b31808SJens Wiklander 350*32b31808SJens Wiklander /* BEGIN MERGE SLOT 7 */ 351*32b31808SJens Wiklander int mbedtls_mpi_mod_read(mbedtls_mpi_mod_residue *r, 352*32b31808SJens Wiklander const mbedtls_mpi_mod_modulus *N, 353*32b31808SJens Wiklander const unsigned char *buf, 354*32b31808SJens Wiklander size_t buflen, 355*32b31808SJens Wiklander mbedtls_mpi_mod_ext_rep ext_rep) 356*32b31808SJens Wiklander { 357*32b31808SJens Wiklander int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; 358*32b31808SJens Wiklander 359*32b31808SJens Wiklander /* Do our best to check if r and m have been set up */ 360*32b31808SJens Wiklander if (r->limbs == 0 || N->limbs == 0) { 361*32b31808SJens Wiklander goto cleanup; 362*32b31808SJens Wiklander } 363*32b31808SJens Wiklander if (r->limbs != N->limbs) { 364*32b31808SJens Wiklander goto cleanup; 365*32b31808SJens Wiklander } 366*32b31808SJens Wiklander 367*32b31808SJens Wiklander ret = mbedtls_mpi_mod_raw_read(r->p, N, buf, buflen, ext_rep); 368*32b31808SJens Wiklander if (ret != 0) { 369*32b31808SJens Wiklander goto cleanup; 370*32b31808SJens Wiklander } 371*32b31808SJens Wiklander 372*32b31808SJens Wiklander r->limbs = N->limbs; 373*32b31808SJens Wiklander 374*32b31808SJens Wiklander ret = mbedtls_mpi_mod_raw_canonical_to_modulus_rep(r->p, N); 375*32b31808SJens Wiklander 376*32b31808SJens Wiklander cleanup: 377*32b31808SJens Wiklander return ret; 378*32b31808SJens Wiklander } 379*32b31808SJens Wiklander 380*32b31808SJens Wiklander int mbedtls_mpi_mod_write(const mbedtls_mpi_mod_residue *r, 381*32b31808SJens Wiklander const mbedtls_mpi_mod_modulus *N, 382*32b31808SJens Wiklander unsigned char *buf, 383*32b31808SJens Wiklander size_t buflen, 384*32b31808SJens Wiklander mbedtls_mpi_mod_ext_rep ext_rep) 385*32b31808SJens Wiklander { 386*32b31808SJens Wiklander int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; 387*32b31808SJens Wiklander 388*32b31808SJens Wiklander /* Do our best to check if r and m have been set up */ 389*32b31808SJens Wiklander if (r->limbs == 0 || N->limbs == 0) { 390*32b31808SJens Wiklander goto cleanup; 391*32b31808SJens Wiklander } 392*32b31808SJens Wiklander if (r->limbs != N->limbs) { 393*32b31808SJens Wiklander goto cleanup; 394*32b31808SJens Wiklander } 395*32b31808SJens Wiklander 396*32b31808SJens Wiklander if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) { 397*32b31808SJens Wiklander ret = mbedtls_mpi_mod_raw_from_mont_rep(r->p, N); 398*32b31808SJens Wiklander if (ret != 0) { 399*32b31808SJens Wiklander goto cleanup; 400*32b31808SJens Wiklander } 401*32b31808SJens Wiklander } 402*32b31808SJens Wiklander 403*32b31808SJens Wiklander ret = mbedtls_mpi_mod_raw_write(r->p, N, buf, buflen, ext_rep); 404*32b31808SJens Wiklander 405*32b31808SJens Wiklander if (N->int_rep == MBEDTLS_MPI_MOD_REP_MONTGOMERY) { 406*32b31808SJens Wiklander /* If this fails, the value of r is corrupted and we want to return 407*32b31808SJens Wiklander * this error (as opposed to the error code from the write above) to 408*32b31808SJens Wiklander * let the caller know. If it succeeds, we want to return the error 409*32b31808SJens Wiklander * code from write above. */ 410*32b31808SJens Wiklander int conv_ret = mbedtls_mpi_mod_raw_to_mont_rep(r->p, N); 411*32b31808SJens Wiklander if (ret == 0) { 412*32b31808SJens Wiklander ret = conv_ret; 413*32b31808SJens Wiklander } 414*32b31808SJens Wiklander } 415*32b31808SJens Wiklander 416*32b31808SJens Wiklander cleanup: 417*32b31808SJens Wiklander 418*32b31808SJens Wiklander return ret; 419*32b31808SJens Wiklander } 420*32b31808SJens Wiklander /* END MERGE SLOT 7 */ 421*32b31808SJens Wiklander 422*32b31808SJens Wiklander /* BEGIN MERGE SLOT 8 */ 423*32b31808SJens Wiklander 424*32b31808SJens Wiklander /* END MERGE SLOT 8 */ 425*32b31808SJens Wiklander 426*32b31808SJens Wiklander /* BEGIN MERGE SLOT 9 */ 427*32b31808SJens Wiklander 428*32b31808SJens Wiklander /* END MERGE SLOT 9 */ 429*32b31808SJens Wiklander 430*32b31808SJens Wiklander /* BEGIN MERGE SLOT 10 */ 431*32b31808SJens Wiklander 432*32b31808SJens Wiklander /* END MERGE SLOT 10 */ 433*32b31808SJens Wiklander 434*32b31808SJens Wiklander #endif /* MBEDTLS_BIGNUM_C */ 435