1 /*
2  *  Low-level modular bignum functions
3  *
4  *  Copyright The Mbed TLS Contributors
5  *  SPDX-License-Identifier: Apache-2.0
6  *
7  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
8  *  not use this file except in compliance with the License.
9  *  You may obtain a copy of the License at
10  *
11  *  http://www.apache.org/licenses/LICENSE-2.0
12  *
13  *  Unless required by applicable law or agreed to in writing, software
14  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  *  See the License for the specific language governing permissions and
17  *  limitations under the License.
18  */
19 
20 #include "common.h"
21 
22 #if defined(MBEDTLS_BIGNUM_C)
23 
24 #include <string.h>
25 
26 #include "mbedtls/error.h"
27 #include "mbedtls/platform_util.h"
28 
29 #include "mbedtls/platform.h"
30 
31 #include "bignum_core.h"
32 #include "bignum_mod_raw.h"
33 #include "bignum_mod.h"
34 #include "constant_time_internal.h"
35 
mbedtls_mpi_mod_raw_cond_assign(mbedtls_mpi_uint * X,const mbedtls_mpi_uint * A,const mbedtls_mpi_mod_modulus * N,unsigned char assign)36 void mbedtls_mpi_mod_raw_cond_assign( mbedtls_mpi_uint *X,
37                                       const mbedtls_mpi_uint *A,
38                                       const mbedtls_mpi_mod_modulus *N,
39                                       unsigned char assign )
40 {
41     mbedtls_mpi_core_cond_assign( X, A, N->limbs, assign );
42 }
43 
mbedtls_mpi_mod_raw_cond_swap(mbedtls_mpi_uint * X,mbedtls_mpi_uint * Y,const mbedtls_mpi_mod_modulus * N,unsigned char swap)44 void mbedtls_mpi_mod_raw_cond_swap( mbedtls_mpi_uint *X,
45                                     mbedtls_mpi_uint *Y,
46                                     const mbedtls_mpi_mod_modulus *N,
47                                     unsigned char swap )
48 {
49     mbedtls_mpi_core_cond_swap( X, Y, N->limbs, swap );
50 }
51 
mbedtls_mpi_mod_raw_read(mbedtls_mpi_uint * X,const mbedtls_mpi_mod_modulus * m,const unsigned char * input,size_t input_length,mbedtls_mpi_mod_ext_rep ext_rep)52 int mbedtls_mpi_mod_raw_read( mbedtls_mpi_uint *X,
53                               const mbedtls_mpi_mod_modulus *m,
54                               const unsigned char *input,
55                               size_t input_length,
56                               mbedtls_mpi_mod_ext_rep ext_rep )
57 {
58     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
59 
60     switch( ext_rep )
61     {
62         case MBEDTLS_MPI_MOD_EXT_REP_LE:
63             ret = mbedtls_mpi_core_read_le( X, m->limbs,
64                                             input, input_length );
65             break;
66         case MBEDTLS_MPI_MOD_EXT_REP_BE:
67             ret = mbedtls_mpi_core_read_be( X, m->limbs,
68                                             input, input_length );
69             break;
70         default:
71             return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
72     }
73 
74     if( ret != 0 )
75         goto cleanup;
76 
77     if( !mbedtls_mpi_core_lt_ct( X, m->p, m->limbs ) )
78     {
79         ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
80         goto cleanup;
81     }
82 
83 cleanup:
84 
85     return( ret );
86 }
87 
mbedtls_mpi_mod_raw_write(const mbedtls_mpi_uint * A,const mbedtls_mpi_mod_modulus * m,unsigned char * output,size_t output_length,mbedtls_mpi_mod_ext_rep ext_rep)88 int mbedtls_mpi_mod_raw_write( const mbedtls_mpi_uint *A,
89                                const mbedtls_mpi_mod_modulus *m,
90                                unsigned char *output,
91                                size_t output_length,
92                                mbedtls_mpi_mod_ext_rep ext_rep )
93 {
94     switch( ext_rep )
95     {
96         case MBEDTLS_MPI_MOD_EXT_REP_LE:
97             return( mbedtls_mpi_core_write_le( A, m->limbs,
98                                                output, output_length ) );
99         case MBEDTLS_MPI_MOD_EXT_REP_BE:
100             return( mbedtls_mpi_core_write_be( A, m->limbs,
101                                                output, output_length ) );
102         default:
103             return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
104     }
105 }
106 
107 /* BEGIN MERGE SLOT 1 */
108 
109 /* END MERGE SLOT 1 */
110 
111 /* BEGIN MERGE SLOT 2 */
112 
mbedtls_mpi_mod_raw_sub(mbedtls_mpi_uint * X,const mbedtls_mpi_uint * A,const mbedtls_mpi_uint * B,const mbedtls_mpi_mod_modulus * N)113 void mbedtls_mpi_mod_raw_sub( mbedtls_mpi_uint *X,
114                               const mbedtls_mpi_uint *A,
115                               const mbedtls_mpi_uint *B,
116                               const mbedtls_mpi_mod_modulus *N )
117 {
118     mbedtls_mpi_uint c = mbedtls_mpi_core_sub( X, A, B, N->limbs );
119 
120     (void) mbedtls_mpi_core_add_if( X, N->p, N->limbs, (unsigned) c );
121 }
122 
123 /* END MERGE SLOT 2 */
124 
125 /* BEGIN MERGE SLOT 3 */
126 
127 /* END MERGE SLOT 3 */
128 
129 /* BEGIN MERGE SLOT 4 */
130 
131 /* END MERGE SLOT 4 */
132 
133 /* BEGIN MERGE SLOT 5 */
mbedtls_mpi_mod_raw_add(mbedtls_mpi_uint * X,const mbedtls_mpi_uint * A,const mbedtls_mpi_uint * B,const mbedtls_mpi_mod_modulus * N)134 void mbedtls_mpi_mod_raw_add( mbedtls_mpi_uint *X,
135                               const mbedtls_mpi_uint *A,
136                               const mbedtls_mpi_uint *B,
137                               const mbedtls_mpi_mod_modulus *N )
138 {
139     mbedtls_mpi_uint carry, borrow;
140     carry  = mbedtls_mpi_core_add( X, A, B, N->limbs );
141     borrow = mbedtls_mpi_core_sub( X, X, N->p, N->limbs );
142     (void) mbedtls_mpi_core_add_if( X, N->p, N->limbs, (unsigned) ( carry ^ borrow ) );
143 }
144 /* END MERGE SLOT 5 */
145 
146 /* BEGIN MERGE SLOT 6 */
147 
148 /* END MERGE SLOT 6 */
149 
150 /* BEGIN MERGE SLOT 7 */
mbedtls_mpi_mod_raw_to_mont_rep(mbedtls_mpi_uint * X,const mbedtls_mpi_mod_modulus * m)151 int mbedtls_mpi_mod_raw_to_mont_rep( mbedtls_mpi_uint *X,
152                                      const mbedtls_mpi_mod_modulus *m )
153 {
154     mbedtls_mpi_uint *T;
155     const size_t t_limbs = m->limbs * 2 + 1;
156 
157     if( ( T = (mbedtls_mpi_uint *) mbedtls_calloc( t_limbs, ciL ) ) == NULL )
158         return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
159 
160     mbedtls_mpi_core_montmul( X, X, m->rep.mont.rr, m->limbs, m->p, m->limbs,
161                               m->rep.mont.mm, T );
162 
163     mbedtls_platform_zeroize( T, t_limbs * ciL );
164     mbedtls_free( T );
165     return( 0 );
166 }
167 
mbedtls_mpi_mod_raw_from_mont_rep(mbedtls_mpi_uint * X,const mbedtls_mpi_mod_modulus * m)168 int mbedtls_mpi_mod_raw_from_mont_rep( mbedtls_mpi_uint *X,
169                                        const mbedtls_mpi_mod_modulus *m )
170 {
171     const mbedtls_mpi_uint one = 1;
172     const size_t t_limbs = m->limbs * 2 + 1;
173     mbedtls_mpi_uint *T;
174 
175     if( ( T = (mbedtls_mpi_uint *) mbedtls_calloc( t_limbs, ciL ) ) == NULL )
176         return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
177 
178     mbedtls_mpi_core_montmul( X, X, &one, 1, m->p, m->limbs,
179                               m->rep.mont.mm, T );
180 
181     mbedtls_platform_zeroize( T, t_limbs * ciL );
182     mbedtls_free( T );
183     return( 0 );
184 }
185 /* END MERGE SLOT 7 */
186 
187 /* BEGIN MERGE SLOT 8 */
188 
189 /* END MERGE SLOT 8 */
190 
191 /* BEGIN MERGE SLOT 9 */
192 
193 /* END MERGE SLOT 9 */
194 
195 /* BEGIN MERGE SLOT 10 */
196 
197 /* END MERGE SLOT 10 */
198 
199 #endif /* MBEDTLS_BIGNUM_C */
200