xref: /optee_os/lib/libmbedtls/mbedtls/library/bignum_mod.c (revision 32b3180828fa15a49ccc86ecb4be9d274c140c89)
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