blob: 31ef3eeabe7b9c5ef3f1c28b3c124afdd1812cf4 [file] [log] [blame]
Jens Wiklander817466c2018-05-22 13:49:31 +02001/*
2 * Multi-precision integer library
3 *
Jerome Forissier79013242021-07-28 10:24:04 +02004 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0
Jens Wiklander817466c2018-05-22 13:49:31 +02006 *
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.
Jens Wiklander817466c2018-05-22 13:49:31 +020018 */
19
20/*
21 * The following sources were referenced in the design of this Multi-precision
22 * Integer library:
23 *
24 * [1] Handbook of Applied Cryptography - 1997
25 * Menezes, van Oorschot and Vanstone
26 *
27 * [2] Multi-Precision Math
28 * Tom St Denis
29 * https://github.com/libtom/libtommath/blob/develop/tommath.pdf
30 *
31 * [3] GNU Multi-Precision Arithmetic Library
32 * https://gmplib.org/manual/index.html
33 *
34 */
35
Jerome Forissier79013242021-07-28 10:24:04 +020036#include "common.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020037
38#if defined(MBEDTLS_BIGNUM_C)
39
40#include "mbedtls/bignum.h"
41#include "mbedtls/bn_mul.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010042#include "mbedtls/platform_util.h"
Jerome Forissier11fa71b2020-04-20 17:17:56 +020043#include "mbedtls/error.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020044
45#include <string.h>
46
47#if defined(MBEDTLS_PLATFORM_C)
48#include "mbedtls/platform.h"
49#else
50#include <stdio.h>
51#include <stdlib.h>
52#define mbedtls_printf printf
53#define mbedtls_calloc calloc
54#define mbedtls_free free
55#endif
56
Jens Wiklander98bd5fe2018-11-08 11:18:22 +010057#include <mempool.h>
Jens Wiklanderb99a4a12019-04-17 12:25:20 +020058#include <util.h>
Jens Wiklander98bd5fe2018-11-08 11:18:22 +010059
Jens Wiklander3d3b0592019-03-20 15:30:29 +010060#define MPI_VALIDATE_RET( cond ) \
61 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_MPI_BAD_INPUT_DATA )
62#define MPI_VALIDATE( cond ) \
63 MBEDTLS_INTERNAL_VALIDATE( cond )
Jens Wiklander817466c2018-05-22 13:49:31 +020064
65#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */
66#define biL (ciL << 3) /* bits in limb */
67#define biH (ciL << 2) /* half limb size */
68
69#define MPI_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
70
71/*
72 * Convert between bits/chars and number of limbs
73 * Divide first in order to avoid potential overflows
74 */
75#define BITS_TO_LIMBS(i) ( (i) / biL + ( (i) % biL != 0 ) )
76#define CHARS_TO_LIMBS(i) ( (i) / ciL + ( (i) % ciL != 0 ) )
77
Jens Wiklander98bd5fe2018-11-08 11:18:22 +010078void *mbedtls_mpi_mempool;
79
Jens Wiklander3d3b0592019-03-20 15:30:29 +010080/* Implementation that should never be optimized out by the compiler */
81static void mbedtls_mpi_zeroize( mbedtls_mpi_uint *v, size_t n )
82{
83 mbedtls_platform_zeroize( v, ciL * n );
84}
85
Jens Wiklander817466c2018-05-22 13:49:31 +020086/*
87 * Initialize one MPI
88 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +010089static void mpi_init( mbedtls_mpi *X, short use_mempool )
Jens Wiklander817466c2018-05-22 13:49:31 +020090{
Jens Wiklander3d3b0592019-03-20 15:30:29 +010091 MPI_VALIDATE( X != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +020092
Jens Wiklander3d3b0592019-03-20 15:30:29 +010093 X->s = 1;
94 X->use_mempool = use_mempool;
95 X->n = 0;
96 X->p = NULL;
Jens Wiklander817466c2018-05-22 13:49:31 +020097}
98
Jens Wiklander98bd5fe2018-11-08 11:18:22 +010099void mbedtls_mpi_init( mbedtls_mpi *X )
100{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100101 mpi_init( X, 0 /*use_mempool*/ );
Jens Wiklander98bd5fe2018-11-08 11:18:22 +0100102}
103
104void mbedtls_mpi_init_mempool( mbedtls_mpi *X )
105{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100106 mpi_init( X, !!mbedtls_mpi_mempool /*use_mempool*/ );
Jens Wiklander98bd5fe2018-11-08 11:18:22 +0100107}
108
Jens Wiklander817466c2018-05-22 13:49:31 +0200109/*
110 * Unallocate one MPI
111 */
112void mbedtls_mpi_free( mbedtls_mpi *X )
113{
114 if( X == NULL )
115 return;
116
117 if( X->p != NULL )
118 {
119 mbedtls_mpi_zeroize( X->p, X->n );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100120 if( X->use_mempool )
Jens Wiklander18c51482018-11-12 13:53:08 +0100121 mempool_free( mbedtls_mpi_mempool, X->p );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100122 else
123 mbedtls_free( X->p );
Jens Wiklander817466c2018-05-22 13:49:31 +0200124 }
125
126 X->s = 1;
127 X->n = 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100128 X->p = NULL;
Jens Wiklander817466c2018-05-22 13:49:31 +0200129}
130
131/*
132 * Enlarge to the specified number of limbs
133 */
134int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs )
135{
136 mbedtls_mpi_uint *p;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100137 MPI_VALIDATE_RET( X != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200138
139 if( nblimbs > MBEDTLS_MPI_MAX_LIMBS )
140 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
141
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100142 if( X->n < nblimbs )
143 {
144 if( X->use_mempool )
145 {
146 p = mempool_alloc( mbedtls_mpi_mempool, nblimbs * ciL );
147 if( p == NULL )
148 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
149 memset( p, 0, nblimbs * ciL );
150 }
151 else
152 {
153 p = (mbedtls_mpi_uint*)mbedtls_calloc( nblimbs, ciL );
154 if( p == NULL )
155 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
156 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200157
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100158 if( X->p != NULL )
159 {
160 memcpy( p, X->p, X->n * ciL );
161 mbedtls_mpi_zeroize( X->p, X->n );
162 if( X->use_mempool )
163 mempool_free( mbedtls_mpi_mempool, X->p);
164 else
165 mbedtls_free( X->p );
166 }
167
168 X->n = nblimbs;
169 X->p = p;
Jens Wiklander817466c2018-05-22 13:49:31 +0200170 }
171
172 return( 0 );
173}
174
175/*
176 * Resize down as much as possible,
177 * while keeping at least the specified number of limbs
178 */
179int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs )
180{
181 mbedtls_mpi_uint *p;
182 size_t i;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100183 MPI_VALIDATE_RET( X != NULL );
184
185 if( nblimbs > MBEDTLS_MPI_MAX_LIMBS )
186 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
Jens Wiklander817466c2018-05-22 13:49:31 +0200187
Jerome Forissier5b25c762020-04-07 11:18:49 +0200188 /* Actually resize up if there are currently fewer than nblimbs limbs. */
Jens Wiklander817466c2018-05-22 13:49:31 +0200189 if( X->n <= nblimbs )
190 return( mbedtls_mpi_grow( X, nblimbs ) );
Jerome Forissier5b25c762020-04-07 11:18:49 +0200191 /* After this point, then X->n > nblimbs and in particular X->n > 0. */
Jens Wiklander817466c2018-05-22 13:49:31 +0200192
193 for( i = X->n - 1; i > 0; i-- )
194 if( X->p[i] != 0 )
195 break;
196 i++;
197
198 if( i < nblimbs )
199 i = nblimbs;
200
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100201 if( X->use_mempool )
202 {
Jerome Forissiered3fa832020-04-29 15:35:00 +0200203 p = mempool_alloc( mbedtls_mpi_mempool, i * ciL );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100204 if( p == NULL )
Jens Wiklander98bd5fe2018-11-08 11:18:22 +0100205 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
Jerome Forissiered3fa832020-04-29 15:35:00 +0200206 memset( p, 0, i * ciL );
Jens Wiklander98bd5fe2018-11-08 11:18:22 +0100207 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100208 else
209 {
Jerome Forissiered3fa832020-04-29 15:35:00 +0200210 p = (mbedtls_mpi_uint*)mbedtls_calloc( i, ciL );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100211 if( p == NULL )
212 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
213 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200214
215 if( X->p != NULL )
216 {
217 memcpy( p, X->p, i * ciL );
218 mbedtls_mpi_zeroize( X->p, X->n );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100219 if( X->use_mempool )
Jens Wiklander18c51482018-11-12 13:53:08 +0100220 mempool_free( mbedtls_mpi_mempool, X->p );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100221 else
222 mbedtls_free( X->p );
Jens Wiklander817466c2018-05-22 13:49:31 +0200223 }
224
Jens Wiklander18c51482018-11-12 13:53:08 +0100225 X->n = i;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100226 X->p = p;
Jens Wiklander817466c2018-05-22 13:49:31 +0200227
228 return( 0 );
229}
230
Jerome Forissier79013242021-07-28 10:24:04 +0200231/* Resize X to have exactly n limbs and set it to 0. */
232static int mbedtls_mpi_resize_clear( mbedtls_mpi *X, size_t limbs )
233{
234 if( limbs == 0 )
235 {
236 mbedtls_mpi_free( X );
237 return( 0 );
238 }
239 else if( X->n == limbs )
240 {
241 memset( X->p, 0, limbs * ciL );
242 X->s = 1;
243 return( 0 );
244 }
245 else
246 {
247 mbedtls_mpi_free( X );
248 return( mbedtls_mpi_grow( X, limbs ) );
249 }
250}
251
Jens Wiklander817466c2018-05-22 13:49:31 +0200252/*
Jerome Forissier79013242021-07-28 10:24:04 +0200253 * Copy the contents of Y into X.
254 *
255 * This function is not constant-time. Leading zeros in Y may be removed.
256 *
257 * Ensure that X does not shrink. This is not guaranteed by the public API,
258 * but some code in the bignum module relies on this property, for example
259 * in mbedtls_mpi_exp_mod().
Jens Wiklander817466c2018-05-22 13:49:31 +0200260 */
261int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y )
262{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100263 int ret = 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200264 size_t i;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100265 MPI_VALIDATE_RET( X != NULL );
266 MPI_VALIDATE_RET( Y != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200267
268 if( X == Y )
269 return( 0 );
270
Jerome Forissier5b25c762020-04-07 11:18:49 +0200271 if( Y->n == 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200272 {
Jerome Forissier79013242021-07-28 10:24:04 +0200273 if( X->n != 0 )
274 {
275 X->s = 1;
276 memset( X->p, 0, X->n * ciL );
277 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200278 return( 0 );
279 }
280
281 for( i = Y->n - 1; i > 0; i-- )
282 if( Y->p[i] != 0 )
283 break;
284 i++;
285
286 X->s = Y->s;
287
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100288 if( X->n < i )
289 {
290 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i ) );
291 }
292 else
293 {
294 memset( X->p + i, 0, ( X->n - i ) * ciL );
295 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200296
Jens Wiklander817466c2018-05-22 13:49:31 +0200297 memcpy( X->p, Y->p, i * ciL );
298
299cleanup:
300
301 return( ret );
302}
303
304/*
305 * Swap the contents of X and Y
306 */
307void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y )
308{
309 mbedtls_mpi T;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100310 MPI_VALIDATE( X != NULL );
311 MPI_VALIDATE( Y != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200312
313 memcpy( &T, X, sizeof( mbedtls_mpi ) );
314 memcpy( X, Y, sizeof( mbedtls_mpi ) );
315 memcpy( Y, &T, sizeof( mbedtls_mpi ) );
316}
317
Jerome Forissier79013242021-07-28 10:24:04 +0200318/**
319 * Select between two sign values in constant-time.
320 *
321 * This is functionally equivalent to second ? a : b but uses only bit
322 * operations in order to avoid branches.
323 *
324 * \param[in] a The first sign; must be either +1 or -1.
325 * \param[in] b The second sign; must be either +1 or -1.
326 * \param[in] second Must be either 1 (return b) or 0 (return a).
327 *
328 * \return The selected sign value.
329 */
330static int mpi_safe_cond_select_sign( int a, int b, unsigned char second )
331{
332 /* In order to avoid questions about what we can reasonnably assume about
333 * the representations of signed integers, move everything to unsigned
334 * by taking advantage of the fact that a and b are either +1 or -1. */
335 unsigned ua = a + 1;
336 unsigned ub = b + 1;
337
338 /* second was 0 or 1, mask is 0 or 2 as are ua and ub */
339 const unsigned mask = second << 1;
340
341 /* select ua or ub */
342 unsigned ur = ( ua & ~mask ) | ( ub & mask );
343
344 /* ur is now 0 or 2, convert back to -1 or +1 */
345 return( (int) ur - 1 );
346}
347
348/*
349 * Conditionally assign dest = src, without leaking information
350 * about whether the assignment was made or not.
351 * dest and src must be arrays of limbs of size n.
352 * assign must be 0 or 1.
353 */
354static void mpi_safe_cond_assign( size_t n,
355 mbedtls_mpi_uint *dest,
356 const mbedtls_mpi_uint *src,
357 unsigned char assign )
358{
359 size_t i;
360
361 /* MSVC has a warning about unary minus on unsigned integer types,
362 * but this is well-defined and precisely what we want to do here. */
363#if defined(_MSC_VER)
364#pragma warning( push )
365#pragma warning( disable : 4146 )
366#endif
367
368 /* all-bits 1 if assign is 1, all-bits 0 if assign is 0 */
369 const mbedtls_mpi_uint mask = -assign;
370
371#if defined(_MSC_VER)
372#pragma warning( pop )
373#endif
374
375 for( i = 0; i < n; i++ )
376 dest[i] = ( src[i] & mask ) | ( dest[i] & ~mask );
377}
378
Jens Wiklander817466c2018-05-22 13:49:31 +0200379/*
380 * Conditionally assign X = Y, without leaking information
381 * about whether the assignment was made or not.
382 * (Leaking information about the respective sizes of X and Y is ok however.)
383 */
384int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign )
385{
386 int ret = 0;
387 size_t i;
Jerome Forissier79013242021-07-28 10:24:04 +0200388 mbedtls_mpi_uint limb_mask;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100389 MPI_VALIDATE_RET( X != NULL );
390 MPI_VALIDATE_RET( Y != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200391
Jerome Forissier79013242021-07-28 10:24:04 +0200392 /* MSVC has a warning about unary minus on unsigned integer types,
393 * but this is well-defined and precisely what we want to do here. */
394#if defined(_MSC_VER)
395#pragma warning( push )
396#pragma warning( disable : 4146 )
397#endif
398
Jens Wiklander817466c2018-05-22 13:49:31 +0200399 /* make sure assign is 0 or 1 in a time-constant manner */
Jerome Forissier79013242021-07-28 10:24:04 +0200400 assign = (assign | (unsigned char)-assign) >> (sizeof( assign ) * 8 - 1);
401 /* all-bits 1 if assign is 1, all-bits 0 if assign is 0 */
402 limb_mask = -assign;
403
404#if defined(_MSC_VER)
405#pragma warning( pop )
406#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200407
408 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
409
Jerome Forissier79013242021-07-28 10:24:04 +0200410 X->s = mpi_safe_cond_select_sign( X->s, Y->s, assign );
Jens Wiklander817466c2018-05-22 13:49:31 +0200411
Jerome Forissier79013242021-07-28 10:24:04 +0200412 mpi_safe_cond_assign( Y->n, X->p, Y->p, assign );
Jens Wiklander817466c2018-05-22 13:49:31 +0200413
Jerome Forissier79013242021-07-28 10:24:04 +0200414 for( i = Y->n; i < X->n; i++ )
415 X->p[i] &= ~limb_mask;
Jens Wiklander817466c2018-05-22 13:49:31 +0200416
417cleanup:
418 return( ret );
419}
420
421/*
422 * Conditionally swap X and Y, without leaking information
423 * about whether the swap was made or not.
424 * Here it is not ok to simply swap the pointers, which whould lead to
425 * different memory access patterns when X and Y are used afterwards.
426 */
427int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char swap )
428{
429 int ret, s;
430 size_t i;
Jerome Forissier79013242021-07-28 10:24:04 +0200431 mbedtls_mpi_uint limb_mask;
Jens Wiklander817466c2018-05-22 13:49:31 +0200432 mbedtls_mpi_uint tmp;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100433 MPI_VALIDATE_RET( X != NULL );
434 MPI_VALIDATE_RET( Y != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200435
436 if( X == Y )
437 return( 0 );
438
Jerome Forissier79013242021-07-28 10:24:04 +0200439 /* MSVC has a warning about unary minus on unsigned integer types,
440 * but this is well-defined and precisely what we want to do here. */
441#if defined(_MSC_VER)
442#pragma warning( push )
443#pragma warning( disable : 4146 )
444#endif
445
Jens Wiklander817466c2018-05-22 13:49:31 +0200446 /* make sure swap is 0 or 1 in a time-constant manner */
Jerome Forissier79013242021-07-28 10:24:04 +0200447 swap = (swap | (unsigned char)-swap) >> (sizeof( swap ) * 8 - 1);
448 /* all-bits 1 if swap is 1, all-bits 0 if swap is 0 */
449 limb_mask = -swap;
450
451#if defined(_MSC_VER)
452#pragma warning( pop )
453#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200454
455 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
456 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( Y, X->n ) );
457
458 s = X->s;
Jerome Forissier79013242021-07-28 10:24:04 +0200459 X->s = mpi_safe_cond_select_sign( X->s, Y->s, swap );
460 Y->s = mpi_safe_cond_select_sign( Y->s, s, swap );
Jens Wiklander817466c2018-05-22 13:49:31 +0200461
462
463 for( i = 0; i < X->n; i++ )
464 {
465 tmp = X->p[i];
Jerome Forissier79013242021-07-28 10:24:04 +0200466 X->p[i] = ( X->p[i] & ~limb_mask ) | ( Y->p[i] & limb_mask );
467 Y->p[i] = ( Y->p[i] & ~limb_mask ) | ( tmp & limb_mask );
Jens Wiklander817466c2018-05-22 13:49:31 +0200468 }
469
470cleanup:
471 return( ret );
472}
473
474/*
475 * Set value from integer
476 */
477int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z )
478{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200479 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100480 MPI_VALIDATE_RET( X != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200481
482 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, 1 ) );
483 memset( X->p, 0, X->n * ciL );
484
485 X->p[0] = ( z < 0 ) ? -z : z;
486 X->s = ( z < 0 ) ? -1 : 1;
487
488cleanup:
489
490 return( ret );
491}
492
493/*
494 * Get a specific bit
495 */
496int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos )
497{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100498 MPI_VALIDATE_RET( X != NULL );
499
Jens Wiklander817466c2018-05-22 13:49:31 +0200500 if( X->n * biL <= pos )
501 return( 0 );
502
503 return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 );
504}
505
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100506/* Get a specific byte, without range checks. */
507#define GET_BYTE( X, i ) \
508 ( ( ( X )->p[( i ) / ciL] >> ( ( ( i ) % ciL ) * 8 ) ) & 0xff )
509
Jens Wiklander817466c2018-05-22 13:49:31 +0200510/*
511 * Set a bit to a specific value of 0 or 1
512 */
513int mbedtls_mpi_set_bit( mbedtls_mpi *X, size_t pos, unsigned char val )
514{
515 int ret = 0;
516 size_t off = pos / biL;
517 size_t idx = pos % biL;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100518 MPI_VALIDATE_RET( X != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200519
520 if( val != 0 && val != 1 )
521 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
522
523 if( X->n * biL <= pos )
524 {
525 if( val == 0 )
526 return( 0 );
527
528 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, off + 1 ) );
529 }
530
531 X->p[off] &= ~( (mbedtls_mpi_uint) 0x01 << idx );
532 X->p[off] |= (mbedtls_mpi_uint) val << idx;
533
534cleanup:
535
536 return( ret );
537}
538
539/*
540 * Return the number of less significant zero-bits
541 */
542size_t mbedtls_mpi_lsb( const mbedtls_mpi *X )
543{
544 size_t i, j, count = 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100545 MBEDTLS_INTERNAL_VALIDATE_RET( X != NULL, 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200546
547 for( i = 0; i < X->n; i++ )
548 for( j = 0; j < biL; j++, count++ )
549 if( ( ( X->p[i] >> j ) & 1 ) != 0 )
550 return( count );
551
552 return( 0 );
553}
554
555/*
556 * Count leading zero bits in a given integer
557 */
558static size_t mbedtls_clz( const mbedtls_mpi_uint x )
559{
560 size_t j;
561 mbedtls_mpi_uint mask = (mbedtls_mpi_uint) 1 << (biL - 1);
562
563 for( j = 0; j < biL; j++ )
564 {
565 if( x & mask ) break;
566
567 mask >>= 1;
568 }
569
570 return j;
571}
572
573/*
574 * Return the number of bits
575 */
576size_t mbedtls_mpi_bitlen( const mbedtls_mpi *X )
577{
578 size_t i, j;
579
580 if( X->n == 0 )
581 return( 0 );
582
583 for( i = X->n - 1; i > 0; i-- )
584 if( X->p[i] != 0 )
585 break;
586
587 j = biL - mbedtls_clz( X->p[i] );
588
589 return( ( i * biL ) + j );
590}
591
592/*
593 * Return the total size in bytes
594 */
595size_t mbedtls_mpi_size( const mbedtls_mpi *X )
596{
597 return( ( mbedtls_mpi_bitlen( X ) + 7 ) >> 3 );
598}
599
600/*
601 * Convert an ASCII character to digit value
602 */
603static int mpi_get_digit( mbedtls_mpi_uint *d, int radix, char c )
604{
605 *d = 255;
606
607 if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30;
608 if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37;
609 if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57;
610
611 if( *d >= (mbedtls_mpi_uint) radix )
612 return( MBEDTLS_ERR_MPI_INVALID_CHARACTER );
613
614 return( 0 );
615}
616
617/*
618 * Import from an ASCII string
619 */
620int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s )
621{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200622 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200623 size_t i, j, slen, n;
Jerome Forissier79013242021-07-28 10:24:04 +0200624 int sign = 1;
Jens Wiklander817466c2018-05-22 13:49:31 +0200625 mbedtls_mpi_uint d;
626 mbedtls_mpi T;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100627 MPI_VALIDATE_RET( X != NULL );
628 MPI_VALIDATE_RET( s != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200629
630 if( radix < 2 || radix > 16 )
631 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
632
Jens Wiklander98bd5fe2018-11-08 11:18:22 +0100633 mbedtls_mpi_init_mempool( &T );
Jens Wiklander817466c2018-05-22 13:49:31 +0200634
Jerome Forissier79013242021-07-28 10:24:04 +0200635 if( s[0] == 0 )
636 {
637 mbedtls_mpi_free( X );
638 return( 0 );
639 }
640
641 if( s[0] == '-' )
642 {
643 ++s;
644 sign = -1;
645 }
646
Jens Wiklander817466c2018-05-22 13:49:31 +0200647 slen = strlen( s );
648
649 if( radix == 16 )
650 {
651 if( slen > MPI_SIZE_T_MAX >> 2 )
652 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
653
654 n = BITS_TO_LIMBS( slen << 2 );
655
656 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, n ) );
657 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
658
659 for( i = slen, j = 0; i > 0; i--, j++ )
660 {
Jens Wiklander817466c2018-05-22 13:49:31 +0200661 MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) );
662 X->p[j / ( 2 * ciL )] |= d << ( ( j % ( 2 * ciL ) ) << 2 );
663 }
664 }
665 else
666 {
667 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
668
669 for( i = 0; i < slen; i++ )
670 {
Jens Wiklander817466c2018-05-22 13:49:31 +0200671 MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
672 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T, X, radix ) );
Jerome Forissier79013242021-07-28 10:24:04 +0200673 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, &T, d ) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200674 }
675 }
676
Jerome Forissier79013242021-07-28 10:24:04 +0200677 if( sign < 0 && mbedtls_mpi_bitlen( X ) != 0 )
678 X->s = -1;
679
Jens Wiklander817466c2018-05-22 13:49:31 +0200680cleanup:
681
682 mbedtls_mpi_free( &T );
683
684 return( ret );
685}
686
687/*
Jerome Forissier5b25c762020-04-07 11:18:49 +0200688 * Helper to write the digits high-order first.
Jens Wiklander817466c2018-05-22 13:49:31 +0200689 */
Jerome Forissier5b25c762020-04-07 11:18:49 +0200690static int mpi_write_hlp( mbedtls_mpi *X, int radix,
691 char **p, const size_t buflen )
Jens Wiklander817466c2018-05-22 13:49:31 +0200692{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200693 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200694 mbedtls_mpi_uint r;
Jerome Forissier5b25c762020-04-07 11:18:49 +0200695 size_t length = 0;
696 char *p_end = *p + buflen;
Jens Wiklander817466c2018-05-22 13:49:31 +0200697
Jerome Forissier5b25c762020-04-07 11:18:49 +0200698 do
699 {
700 if( length >= buflen )
701 {
702 return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
703 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200704
Jerome Forissier5b25c762020-04-07 11:18:49 +0200705 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, radix ) );
706 MBEDTLS_MPI_CHK( mbedtls_mpi_div_int( X, NULL, X, radix ) );
707 /*
708 * Write the residue in the current position, as an ASCII character.
709 */
710 if( r < 0xA )
711 *(--p_end) = (char)( '0' + r );
712 else
713 *(--p_end) = (char)( 'A' + ( r - 0xA ) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200714
Jerome Forissier5b25c762020-04-07 11:18:49 +0200715 length++;
716 } while( mbedtls_mpi_cmp_int( X, 0 ) != 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200717
Jerome Forissier5b25c762020-04-07 11:18:49 +0200718 memmove( *p, p_end, length );
719 *p += length;
Jens Wiklander817466c2018-05-22 13:49:31 +0200720
721cleanup:
722
723 return( ret );
724}
725
726/*
727 * Export into an ASCII string
728 */
729int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix,
730 char *buf, size_t buflen, size_t *olen )
731{
732 int ret = 0;
733 size_t n;
734 char *p;
735 mbedtls_mpi T;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100736 MPI_VALIDATE_RET( X != NULL );
737 MPI_VALIDATE_RET( olen != NULL );
738 MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200739
740 if( radix < 2 || radix > 16 )
741 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
742
Jerome Forissier5b25c762020-04-07 11:18:49 +0200743 n = mbedtls_mpi_bitlen( X ); /* Number of bits necessary to present `n`. */
744 if( radix >= 4 ) n >>= 1; /* Number of 4-adic digits necessary to present
745 * `n`. If radix > 4, this might be a strict
746 * overapproximation of the number of
747 * radix-adic digits needed to present `n`. */
748 if( radix >= 16 ) n >>= 1; /* Number of hexadecimal digits necessary to
749 * present `n`. */
750
751 n += 1; /* Terminating null byte */
752 n += 1; /* Compensate for the divisions above, which round down `n`
753 * in case it's not even. */
754 n += 1; /* Potential '-'-sign. */
755 n += ( n & 1 ); /* Make n even to have enough space for hexadecimal writing,
756 * which always uses an even number of hex-digits. */
Jens Wiklander817466c2018-05-22 13:49:31 +0200757
758 if( buflen < n )
759 {
760 *olen = n;
761 return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
762 }
763
764 p = buf;
Jens Wiklander98bd5fe2018-11-08 11:18:22 +0100765 mbedtls_mpi_init_mempool( &T );
Jens Wiklander817466c2018-05-22 13:49:31 +0200766
767 if( X->s == -1 )
Jerome Forissier5b25c762020-04-07 11:18:49 +0200768 {
Jens Wiklander817466c2018-05-22 13:49:31 +0200769 *p++ = '-';
Jerome Forissier5b25c762020-04-07 11:18:49 +0200770 buflen--;
771 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200772
773 if( radix == 16 )
774 {
775 int c;
776 size_t i, j, k;
777
778 for( i = X->n, k = 0; i > 0; i-- )
779 {
780 for( j = ciL; j > 0; j-- )
781 {
782 c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF;
783
784 if( c == 0 && k == 0 && ( i + j ) != 2 )
785 continue;
786
787 *(p++) = "0123456789ABCDEF" [c / 16];
788 *(p++) = "0123456789ABCDEF" [c % 16];
789 k = 1;
790 }
791 }
792 }
793 else
794 {
795 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T, X ) );
796
797 if( T.s == -1 )
798 T.s = 1;
799
Jerome Forissier5b25c762020-04-07 11:18:49 +0200800 MBEDTLS_MPI_CHK( mpi_write_hlp( &T, radix, &p, buflen ) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200801 }
802
803 *p++ = '\0';
804 *olen = p - buf;
805
806cleanup:
807
808 mbedtls_mpi_free( &T );
809
810 return( ret );
811}
812
813#if defined(MBEDTLS_FS_IO)
814/*
815 * Read X from an opened file
816 */
817int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin )
818{
819 mbedtls_mpi_uint d;
820 size_t slen;
821 char *p;
822 /*
823 * Buffer should have space for (short) label and decimal formatted MPI,
824 * newline characters and '\0'
825 */
826 char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ];
827
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100828 MPI_VALIDATE_RET( X != NULL );
829 MPI_VALIDATE_RET( fin != NULL );
830
831 if( radix < 2 || radix > 16 )
832 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
833
Jens Wiklander817466c2018-05-22 13:49:31 +0200834 memset( s, 0, sizeof( s ) );
835 if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
836 return( MBEDTLS_ERR_MPI_FILE_IO_ERROR );
837
838 slen = strlen( s );
839 if( slen == sizeof( s ) - 2 )
840 return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
841
842 if( slen > 0 && s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
843 if( slen > 0 && s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
844
845 p = s + slen;
846 while( p-- > s )
847 if( mpi_get_digit( &d, radix, *p ) != 0 )
848 break;
849
850 return( mbedtls_mpi_read_string( X, radix, p + 1 ) );
851}
852
853/*
854 * Write X into an opened file (or stdout if fout == NULL)
855 */
856int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X, int radix, FILE *fout )
857{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200858 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200859 size_t n, slen, plen;
860 /*
861 * Buffer should have space for (short) label and decimal formatted MPI,
862 * newline characters and '\0'
863 */
864 char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ];
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100865 MPI_VALIDATE_RET( X != NULL );
866
867 if( radix < 2 || radix > 16 )
868 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
Jens Wiklander817466c2018-05-22 13:49:31 +0200869
870 memset( s, 0, sizeof( s ) );
871
872 MBEDTLS_MPI_CHK( mbedtls_mpi_write_string( X, radix, s, sizeof( s ) - 2, &n ) );
873
874 if( p == NULL ) p = "";
875
876 plen = strlen( p );
877 slen = strlen( s );
878 s[slen++] = '\r';
879 s[slen++] = '\n';
880
881 if( fout != NULL )
882 {
883 if( fwrite( p, 1, plen, fout ) != plen ||
884 fwrite( s, 1, slen, fout ) != slen )
885 return( MBEDTLS_ERR_MPI_FILE_IO_ERROR );
886 }
887 else
888 mbedtls_printf( "%s%s", p, s );
889
890cleanup:
891
892 return( ret );
893}
894#endif /* MBEDTLS_FS_IO */
895
Jerome Forissier5b25c762020-04-07 11:18:49 +0200896
897/* Convert a big-endian byte array aligned to the size of mbedtls_mpi_uint
898 * into the storage form used by mbedtls_mpi. */
899
900static mbedtls_mpi_uint mpi_uint_bigendian_to_host_c( mbedtls_mpi_uint x )
901{
902 uint8_t i;
903 unsigned char *x_ptr;
904 mbedtls_mpi_uint tmp = 0;
905
906 for( i = 0, x_ptr = (unsigned char*) &x; i < ciL; i++, x_ptr++ )
907 {
908 tmp <<= CHAR_BIT;
909 tmp |= (mbedtls_mpi_uint) *x_ptr;
910 }
911
912 return( tmp );
913}
914
915static mbedtls_mpi_uint mpi_uint_bigendian_to_host( mbedtls_mpi_uint x )
916{
917#if defined(__BYTE_ORDER__)
918
919/* Nothing to do on bigendian systems. */
920#if ( __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ )
921 return( x );
922#endif /* __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ */
923
924#if ( __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ )
925
926/* For GCC and Clang, have builtins for byte swapping. */
927#if defined(__GNUC__) && defined(__GNUC_PREREQ)
928#if __GNUC_PREREQ(4,3)
929#define have_bswap
930#endif
931#endif
932
933#if defined(__clang__) && defined(__has_builtin)
934#if __has_builtin(__builtin_bswap32) && \
935 __has_builtin(__builtin_bswap64)
936#define have_bswap
937#endif
938#endif
939
940#if defined(have_bswap)
941 /* The compiler is hopefully able to statically evaluate this! */
942 switch( sizeof(mbedtls_mpi_uint) )
943 {
944 case 4:
945 return( __builtin_bswap32(x) );
946 case 8:
947 return( __builtin_bswap64(x) );
948 }
949#endif
950#endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */
951#endif /* __BYTE_ORDER__ */
952
953 /* Fall back to C-based reordering if we don't know the byte order
954 * or we couldn't use a compiler-specific builtin. */
955 return( mpi_uint_bigendian_to_host_c( x ) );
956}
957
958static void mpi_bigendian_to_host( mbedtls_mpi_uint * const p, size_t limbs )
959{
960 mbedtls_mpi_uint *cur_limb_left;
961 mbedtls_mpi_uint *cur_limb_right;
962 if( limbs == 0 )
963 return;
964
965 /*
966 * Traverse limbs and
967 * - adapt byte-order in each limb
968 * - swap the limbs themselves.
969 * For that, simultaneously traverse the limbs from left to right
970 * and from right to left, as long as the left index is not bigger
971 * than the right index (it's not a problem if limbs is odd and the
972 * indices coincide in the last iteration).
973 */
974 for( cur_limb_left = p, cur_limb_right = p + ( limbs - 1 );
975 cur_limb_left <= cur_limb_right;
976 cur_limb_left++, cur_limb_right-- )
977 {
978 mbedtls_mpi_uint tmp;
979 /* Note that if cur_limb_left == cur_limb_right,
980 * this code effectively swaps the bytes only once. */
981 tmp = mpi_uint_bigendian_to_host( *cur_limb_left );
982 *cur_limb_left = mpi_uint_bigendian_to_host( *cur_limb_right );
983 *cur_limb_right = tmp;
984 }
985}
986
Jens Wiklander817466c2018-05-22 13:49:31 +0200987/*
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200988 * Import X from unsigned binary data, little endian
989 */
990int mbedtls_mpi_read_binary_le( mbedtls_mpi *X,
991 const unsigned char *buf, size_t buflen )
992{
993 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
994 size_t i;
995 size_t const limbs = CHARS_TO_LIMBS( buflen );
996
997 /* Ensure that target MPI has exactly the necessary number of limbs */
Jerome Forissier79013242021-07-28 10:24:04 +0200998 MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, limbs ) );
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200999
1000 for( i = 0; i < buflen; i++ )
1001 X->p[i / ciL] |= ((mbedtls_mpi_uint) buf[i]) << ((i % ciL) << 3);
1002
1003cleanup:
1004
1005 /*
1006 * This function is also used to import keys. However, wiping the buffers
1007 * upon failure is not necessary because failure only can happen before any
1008 * input is copied.
1009 */
1010 return( ret );
1011}
1012
1013/*
Jens Wiklander817466c2018-05-22 13:49:31 +02001014 * Import X from unsigned binary data, big endian
1015 */
1016int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen )
1017{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001018 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jerome Forissier5b25c762020-04-07 11:18:49 +02001019 size_t const limbs = CHARS_TO_LIMBS( buflen );
1020 size_t const overhead = ( limbs * ciL ) - buflen;
1021 unsigned char *Xp;
Jens Wiklander817466c2018-05-22 13:49:31 +02001022
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001023 MPI_VALIDATE_RET( X != NULL );
1024 MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001025
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001026 /* Ensure that target MPI has exactly the necessary number of limbs */
Jerome Forissier79013242021-07-28 10:24:04 +02001027 MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, limbs ) );
Jens Wiklander29762732019-04-17 12:28:43 +02001028
Jerome Forissier79013242021-07-28 10:24:04 +02001029 /* Avoid calling `memcpy` with NULL source or destination argument,
Jerome Forissier5b25c762020-04-07 11:18:49 +02001030 * even if buflen is 0. */
Jerome Forissier79013242021-07-28 10:24:04 +02001031 if( buflen != 0 )
Jerome Forissier5b25c762020-04-07 11:18:49 +02001032 {
1033 Xp = (unsigned char*) X->p;
1034 memcpy( Xp + overhead, buf, buflen );
1035
1036 mpi_bigendian_to_host( X->p, limbs );
1037 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001038
1039cleanup:
1040
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001041 /*
1042 * This function is also used to import keys. However, wiping the buffers
1043 * upon failure is not necessary because failure only can happen before any
1044 * input is copied.
1045 */
Jens Wiklander817466c2018-05-22 13:49:31 +02001046 return( ret );
1047}
1048
1049/*
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001050 * Export X into unsigned binary data, little endian
1051 */
1052int mbedtls_mpi_write_binary_le( const mbedtls_mpi *X,
1053 unsigned char *buf, size_t buflen )
1054{
1055 size_t stored_bytes = X->n * ciL;
1056 size_t bytes_to_copy;
1057 size_t i;
1058
1059 if( stored_bytes < buflen )
1060 {
1061 bytes_to_copy = stored_bytes;
1062 }
1063 else
1064 {
1065 bytes_to_copy = buflen;
1066
1067 /* The output buffer is smaller than the allocated size of X.
1068 * However X may fit if its leading bytes are zero. */
1069 for( i = bytes_to_copy; i < stored_bytes; i++ )
1070 {
1071 if( GET_BYTE( X, i ) != 0 )
1072 return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
1073 }
1074 }
1075
1076 for( i = 0; i < bytes_to_copy; i++ )
1077 buf[i] = GET_BYTE( X, i );
1078
1079 if( stored_bytes < buflen )
1080 {
1081 /* Write trailing 0 bytes */
1082 memset( buf + stored_bytes, 0, buflen - stored_bytes );
1083 }
1084
1085 return( 0 );
1086}
1087
1088/*
Jens Wiklander817466c2018-05-22 13:49:31 +02001089 * Export X into unsigned binary data, big endian
1090 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001091int mbedtls_mpi_write_binary( const mbedtls_mpi *X,
1092 unsigned char *buf, size_t buflen )
Jens Wiklander817466c2018-05-22 13:49:31 +02001093{
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001094 size_t stored_bytes;
1095 size_t bytes_to_copy;
1096 unsigned char *p;
1097 size_t i;
Jens Wiklander817466c2018-05-22 13:49:31 +02001098
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001099 MPI_VALIDATE_RET( X != NULL );
1100 MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001101
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001102 stored_bytes = X->n * ciL;
Jens Wiklander817466c2018-05-22 13:49:31 +02001103
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001104 if( stored_bytes < buflen )
1105 {
1106 /* There is enough space in the output buffer. Write initial
1107 * null bytes and record the position at which to start
1108 * writing the significant bytes. In this case, the execution
1109 * trace of this function does not depend on the value of the
1110 * number. */
1111 bytes_to_copy = stored_bytes;
1112 p = buf + buflen - stored_bytes;
1113 memset( buf, 0, buflen - stored_bytes );
1114 }
1115 else
1116 {
1117 /* The output buffer is smaller than the allocated size of X.
1118 * However X may fit if its leading bytes are zero. */
1119 bytes_to_copy = buflen;
1120 p = buf;
1121 for( i = bytes_to_copy; i < stored_bytes; i++ )
1122 {
1123 if( GET_BYTE( X, i ) != 0 )
1124 return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
1125 }
1126 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001127
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001128 for( i = 0; i < bytes_to_copy; i++ )
1129 p[bytes_to_copy - i - 1] = GET_BYTE( X, i );
Jens Wiklander817466c2018-05-22 13:49:31 +02001130
1131 return( 0 );
1132}
1133
1134/*
1135 * Left-shift: X <<= count
1136 */
1137int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count )
1138{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001139 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02001140 size_t i, v0, t1;
1141 mbedtls_mpi_uint r0 = 0, r1;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001142 MPI_VALIDATE_RET( X != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001143
1144 v0 = count / (biL );
1145 t1 = count & (biL - 1);
1146
1147 i = mbedtls_mpi_bitlen( X ) + count;
1148
1149 if( X->n * biL < i )
1150 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, BITS_TO_LIMBS( i ) ) );
1151
1152 ret = 0;
1153
1154 /*
1155 * shift by count / limb_size
1156 */
1157 if( v0 > 0 )
1158 {
1159 for( i = X->n; i > v0; i-- )
1160 X->p[i - 1] = X->p[i - v0 - 1];
1161
1162 for( ; i > 0; i-- )
1163 X->p[i - 1] = 0;
1164 }
1165
1166 /*
1167 * shift by count % limb_size
1168 */
1169 if( t1 > 0 )
1170 {
1171 for( i = v0; i < X->n; i++ )
1172 {
1173 r1 = X->p[i] >> (biL - t1);
1174 X->p[i] <<= t1;
1175 X->p[i] |= r0;
1176 r0 = r1;
1177 }
1178 }
1179
1180cleanup:
1181
1182 return( ret );
1183}
1184
1185/*
1186 * Right-shift: X >>= count
1187 */
1188int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count )
1189{
1190 size_t i, v0, v1;
1191 mbedtls_mpi_uint r0 = 0, r1;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001192 MPI_VALIDATE_RET( X != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001193
1194 v0 = count / biL;
1195 v1 = count & (biL - 1);
1196
1197 if( v0 > X->n || ( v0 == X->n && v1 > 0 ) )
1198 return mbedtls_mpi_lset( X, 0 );
1199
1200 /*
1201 * shift by count / limb_size
1202 */
1203 if( v0 > 0 )
1204 {
1205 for( i = 0; i < X->n - v0; i++ )
1206 X->p[i] = X->p[i + v0];
1207
1208 for( ; i < X->n; i++ )
1209 X->p[i] = 0;
1210 }
1211
1212 /*
1213 * shift by count % limb_size
1214 */
1215 if( v1 > 0 )
1216 {
1217 for( i = X->n; i > 0; i-- )
1218 {
1219 r1 = X->p[i - 1] << (biL - v1);
1220 X->p[i - 1] >>= v1;
1221 X->p[i - 1] |= r0;
1222 r0 = r1;
1223 }
1224 }
1225
1226 return( 0 );
1227}
1228
1229/*
1230 * Compare unsigned values
1231 */
1232int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y )
1233{
1234 size_t i, j;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001235 MPI_VALIDATE_RET( X != NULL );
1236 MPI_VALIDATE_RET( Y != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001237
1238 for( i = X->n; i > 0; i-- )
1239 if( X->p[i - 1] != 0 )
1240 break;
1241
1242 for( j = Y->n; j > 0; j-- )
1243 if( Y->p[j - 1] != 0 )
1244 break;
1245
1246 if( i == 0 && j == 0 )
1247 return( 0 );
1248
1249 if( i > j ) return( 1 );
1250 if( j > i ) return( -1 );
1251
1252 for( ; i > 0; i-- )
1253 {
1254 if( X->p[i - 1] > Y->p[i - 1] ) return( 1 );
1255 if( X->p[i - 1] < Y->p[i - 1] ) return( -1 );
1256 }
1257
1258 return( 0 );
1259}
1260
1261/*
1262 * Compare signed values
1263 */
1264int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y )
1265{
1266 size_t i, j;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001267 MPI_VALIDATE_RET( X != NULL );
1268 MPI_VALIDATE_RET( Y != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001269
1270 for( i = X->n; i > 0; i-- )
1271 if( X->p[i - 1] != 0 )
1272 break;
1273
1274 for( j = Y->n; j > 0; j-- )
1275 if( Y->p[j - 1] != 0 )
1276 break;
1277
1278 if( i == 0 && j == 0 )
1279 return( 0 );
1280
1281 if( i > j ) return( X->s );
1282 if( j > i ) return( -Y->s );
1283
1284 if( X->s > 0 && Y->s < 0 ) return( 1 );
1285 if( Y->s > 0 && X->s < 0 ) return( -1 );
1286
1287 for( ; i > 0; i-- )
1288 {
1289 if( X->p[i - 1] > Y->p[i - 1] ) return( X->s );
1290 if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s );
1291 }
1292
1293 return( 0 );
1294}
1295
Jerome Forissier5b25c762020-04-07 11:18:49 +02001296/** Decide if an integer is less than the other, without branches.
1297 *
1298 * \param x First integer.
1299 * \param y Second integer.
1300 *
1301 * \return 1 if \p x is less than \p y, 0 otherwise
1302 */
1303static unsigned ct_lt_mpi_uint( const mbedtls_mpi_uint x,
1304 const mbedtls_mpi_uint y )
1305{
1306 mbedtls_mpi_uint ret;
1307 mbedtls_mpi_uint cond;
1308
1309 /*
1310 * Check if the most significant bits (MSB) of the operands are different.
1311 */
1312 cond = ( x ^ y );
1313 /*
1314 * If the MSB are the same then the difference x-y will be negative (and
1315 * have its MSB set to 1 during conversion to unsigned) if and only if x<y.
1316 */
1317 ret = ( x - y ) & ~cond;
1318 /*
1319 * If the MSB are different, then the operand with the MSB of 1 is the
1320 * bigger. (That is if y has MSB of 1, then x<y is true and it is false if
1321 * the MSB of y is 0.)
1322 */
1323 ret |= y & cond;
1324
1325
1326 ret = ret >> ( biL - 1 );
1327
1328 return (unsigned) ret;
1329}
1330
1331/*
1332 * Compare signed values in constant time
1333 */
1334int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X, const mbedtls_mpi *Y,
1335 unsigned *ret )
1336{
1337 size_t i;
1338 /* The value of any of these variables is either 0 or 1 at all times. */
1339 unsigned cond, done, X_is_negative, Y_is_negative;
1340
1341 MPI_VALIDATE_RET( X != NULL );
1342 MPI_VALIDATE_RET( Y != NULL );
1343 MPI_VALIDATE_RET( ret != NULL );
1344
1345 if( X->n != Y->n )
1346 return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
1347
1348 /*
1349 * Set sign_N to 1 if N >= 0, 0 if N < 0.
1350 * We know that N->s == 1 if N >= 0 and N->s == -1 if N < 0.
1351 */
1352 X_is_negative = ( X->s & 2 ) >> 1;
1353 Y_is_negative = ( Y->s & 2 ) >> 1;
1354
1355 /*
1356 * If the signs are different, then the positive operand is the bigger.
1357 * That is if X is negative (X_is_negative == 1), then X < Y is true and it
1358 * is false if X is positive (X_is_negative == 0).
1359 */
1360 cond = ( X_is_negative ^ Y_is_negative );
1361 *ret = cond & X_is_negative;
1362
1363 /*
1364 * This is a constant-time function. We might have the result, but we still
1365 * need to go through the loop. Record if we have the result already.
1366 */
1367 done = cond;
1368
1369 for( i = X->n; i > 0; i-- )
1370 {
1371 /*
1372 * If Y->p[i - 1] < X->p[i - 1] then X < Y is true if and only if both
1373 * X and Y are negative.
1374 *
1375 * Again even if we can make a decision, we just mark the result and
1376 * the fact that we are done and continue looping.
1377 */
1378 cond = ct_lt_mpi_uint( Y->p[i - 1], X->p[i - 1] );
1379 *ret |= cond & ( 1 - done ) & X_is_negative;
1380 done |= cond;
1381
1382 /*
1383 * If X->p[i - 1] < Y->p[i - 1] then X < Y is true if and only if both
1384 * X and Y are positive.
1385 *
1386 * Again even if we can make a decision, we just mark the result and
1387 * the fact that we are done and continue looping.
1388 */
1389 cond = ct_lt_mpi_uint( X->p[i - 1], Y->p[i - 1] );
1390 *ret |= cond & ( 1 - done ) & ( 1 - X_is_negative );
1391 done |= cond;
1392 }
1393
1394 return( 0 );
1395}
1396
Jens Wiklander817466c2018-05-22 13:49:31 +02001397/*
1398 * Compare signed values
1399 */
1400int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z )
1401{
1402 mbedtls_mpi Y;
1403 mbedtls_mpi_uint p[1];
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001404 MPI_VALIDATE_RET( X != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001405
1406 *p = ( z < 0 ) ? -z : z;
1407 Y.s = ( z < 0 ) ? -1 : 1;
1408 Y.n = 1;
1409 Y.p = p;
1410
1411 return( mbedtls_mpi_cmp_mpi( X, &Y ) );
1412}
1413
1414/*
1415 * Unsigned addition: X = |A| + |B| (HAC 14.7)
1416 */
1417int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
1418{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001419 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02001420 size_t i, j;
1421 mbedtls_mpi_uint *o, *p, c, tmp;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001422 MPI_VALIDATE_RET( X != NULL );
1423 MPI_VALIDATE_RET( A != NULL );
1424 MPI_VALIDATE_RET( B != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001425
1426 if( X == B )
1427 {
1428 const mbedtls_mpi *T = A; A = X; B = T;
1429 }
1430
1431 if( X != A )
1432 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) );
1433
1434 /*
1435 * X should always be positive as a result of unsigned additions.
1436 */
1437 X->s = 1;
1438
1439 for( j = B->n; j > 0; j-- )
1440 if( B->p[j - 1] != 0 )
1441 break;
1442
1443 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) );
1444
1445 o = B->p; p = X->p; c = 0;
1446
1447 /*
1448 * tmp is used because it might happen that p == o
1449 */
1450 for( i = 0; i < j; i++, o++, p++ )
1451 {
1452 tmp= *o;
1453 *p += c; c = ( *p < c );
1454 *p += tmp; c += ( *p < tmp );
1455 }
1456
1457 while( c != 0 )
1458 {
1459 if( i >= X->n )
1460 {
1461 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + 1 ) );
1462 p = X->p + i;
1463 }
1464
1465 *p += c; c = ( *p < c ); i++; p++;
1466 }
1467
1468cleanup:
1469
1470 return( ret );
1471}
1472
Jerome Forissier79013242021-07-28 10:24:04 +02001473/**
1474 * Helper for mbedtls_mpi subtraction.
1475 *
1476 * Calculate l - r where l and r have the same size.
1477 * This function operates modulo (2^ciL)^n and returns the carry
1478 * (1 if there was a wraparound, i.e. if `l < r`, and 0 otherwise).
1479 *
1480 * d may be aliased to l or r.
1481 *
1482 * \param n Number of limbs of \p d, \p l and \p r.
1483 * \param[out] d The result of the subtraction.
1484 * \param[in] l The left operand.
1485 * \param[in] r The right operand.
1486 *
1487 * \return 1 if `l < r`.
1488 * 0 if `l >= r`.
Jens Wiklander817466c2018-05-22 13:49:31 +02001489 */
Jerome Forissier79013242021-07-28 10:24:04 +02001490static mbedtls_mpi_uint mpi_sub_hlp( size_t n,
1491 mbedtls_mpi_uint *d,
1492 const mbedtls_mpi_uint *l,
1493 const mbedtls_mpi_uint *r )
Jens Wiklander817466c2018-05-22 13:49:31 +02001494{
1495 size_t i;
Jerome Forissier79013242021-07-28 10:24:04 +02001496 mbedtls_mpi_uint c = 0, t, z;
Jens Wiklander817466c2018-05-22 13:49:31 +02001497
Jerome Forissier79013242021-07-28 10:24:04 +02001498 for( i = 0; i < n; i++ )
Jens Wiklander817466c2018-05-22 13:49:31 +02001499 {
Jerome Forissier79013242021-07-28 10:24:04 +02001500 z = ( l[i] < c ); t = l[i] - c;
1501 c = ( t < r[i] ) + z; d[i] = t - r[i];
Jens Wiklander817466c2018-05-22 13:49:31 +02001502 }
1503
Jerome Forissier79013242021-07-28 10:24:04 +02001504 return( c );
Jens Wiklander817466c2018-05-22 13:49:31 +02001505}
1506
1507/*
Jerome Forissier79013242021-07-28 10:24:04 +02001508 * Unsigned subtraction: X = |A| - |B| (HAC 14.9, 14.10)
Jens Wiklander817466c2018-05-22 13:49:31 +02001509 */
1510int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
1511{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001512 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02001513 size_t n;
Jerome Forissier79013242021-07-28 10:24:04 +02001514 mbedtls_mpi_uint carry;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001515 MPI_VALIDATE_RET( X != NULL );
1516 MPI_VALIDATE_RET( A != NULL );
1517 MPI_VALIDATE_RET( B != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001518
Jens Wiklander817466c2018-05-22 13:49:31 +02001519 for( n = B->n; n > 0; n-- )
1520 if( B->p[n - 1] != 0 )
1521 break;
Jerome Forissier79013242021-07-28 10:24:04 +02001522 if( n > A->n )
1523 {
1524 /* B >= (2^ciL)^n > A */
1525 ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
1526 goto cleanup;
1527 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001528
Jerome Forissier79013242021-07-28 10:24:04 +02001529 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, A->n ) );
1530
1531 /* Set the high limbs of X to match A. Don't touch the lower limbs
1532 * because X might be aliased to B, and we must not overwrite the
1533 * significant digits of B. */
1534 if( A->n > n )
1535 memcpy( X->p + n, A->p + n, ( A->n - n ) * ciL );
1536 if( X->n > A->n )
1537 memset( X->p + A->n, 0, ( X->n - A->n ) * ciL );
1538
1539 carry = mpi_sub_hlp( n, X->p, A->p, B->p );
1540 if( carry != 0 )
1541 {
1542 /* Propagate the carry to the first nonzero limb of X. */
1543 for( ; n < X->n && X->p[n] == 0; n++ )
1544 --X->p[n];
1545 /* If we ran out of space for the carry, it means that the result
1546 * is negative. */
1547 if( n == X->n )
1548 {
1549 ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
1550 goto cleanup;
1551 }
1552 --X->p[n];
1553 }
1554
1555 /* X should always be positive as a result of unsigned subtractions. */
1556 X->s = 1;
Jens Wiklander817466c2018-05-22 13:49:31 +02001557
1558cleanup:
Jens Wiklander817466c2018-05-22 13:49:31 +02001559 return( ret );
1560}
1561
1562/*
1563 * Signed addition: X = A + B
1564 */
1565int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
1566{
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001567 int ret, s;
1568 MPI_VALIDATE_RET( X != NULL );
1569 MPI_VALIDATE_RET( A != NULL );
1570 MPI_VALIDATE_RET( B != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001571
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001572 s = A->s;
Jens Wiklander817466c2018-05-22 13:49:31 +02001573 if( A->s * B->s < 0 )
1574 {
1575 if( mbedtls_mpi_cmp_abs( A, B ) >= 0 )
1576 {
1577 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) );
1578 X->s = s;
1579 }
1580 else
1581 {
1582 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) );
1583 X->s = -s;
1584 }
1585 }
1586 else
1587 {
1588 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( X, A, B ) );
1589 X->s = s;
1590 }
1591
1592cleanup:
1593
1594 return( ret );
1595}
1596
1597/*
1598 * Signed subtraction: X = A - B
1599 */
1600int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
1601{
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001602 int ret, s;
1603 MPI_VALIDATE_RET( X != NULL );
1604 MPI_VALIDATE_RET( A != NULL );
1605 MPI_VALIDATE_RET( B != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001606
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001607 s = A->s;
Jens Wiklander817466c2018-05-22 13:49:31 +02001608 if( A->s * B->s > 0 )
1609 {
1610 if( mbedtls_mpi_cmp_abs( A, B ) >= 0 )
1611 {
1612 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) );
1613 X->s = s;
1614 }
1615 else
1616 {
1617 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) );
1618 X->s = -s;
1619 }
1620 }
1621 else
1622 {
1623 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( X, A, B ) );
1624 X->s = s;
1625 }
1626
1627cleanup:
1628
1629 return( ret );
1630}
1631
1632/*
1633 * Signed addition: X = A + b
1634 */
1635int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b )
1636{
1637 mbedtls_mpi _B;
1638 mbedtls_mpi_uint p[1];
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001639 MPI_VALIDATE_RET( X != NULL );
1640 MPI_VALIDATE_RET( A != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001641
1642 p[0] = ( b < 0 ) ? -b : b;
1643 _B.s = ( b < 0 ) ? -1 : 1;
1644 _B.n = 1;
1645 _B.p = p;
1646
1647 return( mbedtls_mpi_add_mpi( X, A, &_B ) );
1648}
1649
1650/*
1651 * Signed subtraction: X = A - b
1652 */
1653int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b )
1654{
1655 mbedtls_mpi _B;
1656 mbedtls_mpi_uint p[1];
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001657 MPI_VALIDATE_RET( X != NULL );
1658 MPI_VALIDATE_RET( A != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001659
1660 p[0] = ( b < 0 ) ? -b : b;
1661 _B.s = ( b < 0 ) ? -1 : 1;
1662 _B.n = 1;
1663 _B.p = p;
1664
1665 return( mbedtls_mpi_sub_mpi( X, A, &_B ) );
1666}
1667
Jerome Forissier79013242021-07-28 10:24:04 +02001668/** Helper for mbedtls_mpi multiplication.
1669 *
1670 * Add \p b * \p s to \p d.
1671 *
1672 * \param i The number of limbs of \p s.
1673 * \param[in] s A bignum to multiply, of size \p i.
1674 * It may overlap with \p d, but only if
1675 * \p d <= \p s.
1676 * Its leading limb must not be \c 0.
1677 * \param[in,out] d The bignum to add to.
1678 * It must be sufficiently large to store the
1679 * result of the multiplication. This means
1680 * \p i + 1 limbs if \p d[\p i - 1] started as 0 and \p b
1681 * is not known a priori.
1682 * \param b A scalar to multiply.
Jens Wiklander817466c2018-05-22 13:49:31 +02001683 */
1684static
1685#if defined(__APPLE__) && defined(__arm__)
1686/*
1687 * Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
1688 * appears to need this to prevent bad ARM code generation at -O3.
1689 */
1690__attribute__ ((noinline))
1691#endif
Jerome Forissier79013242021-07-28 10:24:04 +02001692void mpi_mul_hlp( size_t i,
1693 const mbedtls_mpi_uint *s,
1694 mbedtls_mpi_uint *d,
1695 mbedtls_mpi_uint b )
Jens Wiklander817466c2018-05-22 13:49:31 +02001696{
1697 mbedtls_mpi_uint c = 0, t = 0;
1698
1699#if defined(MULADDC_HUIT)
1700 for( ; i >= 8; i -= 8 )
1701 {
1702 MULADDC_INIT
1703 MULADDC_HUIT
1704 MULADDC_STOP
1705 }
1706
1707 for( ; i > 0; i-- )
1708 {
1709 MULADDC_INIT
1710 MULADDC_CORE
1711 MULADDC_STOP
1712 }
1713#else /* MULADDC_HUIT */
1714 for( ; i >= 16; i -= 16 )
1715 {
1716 MULADDC_INIT
1717 MULADDC_CORE MULADDC_CORE
1718 MULADDC_CORE MULADDC_CORE
1719 MULADDC_CORE MULADDC_CORE
1720 MULADDC_CORE MULADDC_CORE
1721
1722 MULADDC_CORE MULADDC_CORE
1723 MULADDC_CORE MULADDC_CORE
1724 MULADDC_CORE MULADDC_CORE
1725 MULADDC_CORE MULADDC_CORE
1726 MULADDC_STOP
1727 }
1728
1729 for( ; i >= 8; i -= 8 )
1730 {
1731 MULADDC_INIT
1732 MULADDC_CORE MULADDC_CORE
1733 MULADDC_CORE MULADDC_CORE
1734
1735 MULADDC_CORE MULADDC_CORE
1736 MULADDC_CORE MULADDC_CORE
1737 MULADDC_STOP
1738 }
1739
1740 for( ; i > 0; i-- )
1741 {
1742 MULADDC_INIT
1743 MULADDC_CORE
1744 MULADDC_STOP
1745 }
1746#endif /* MULADDC_HUIT */
1747
1748 t++;
1749
Jerome Forissier79013242021-07-28 10:24:04 +02001750 while( c != 0 )
1751 {
Jens Wiklander817466c2018-05-22 13:49:31 +02001752 *d += c; c = ( *d < c ); d++;
1753 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001754}
1755
1756/*
1757 * Baseline multiplication: X = A * B (HAC 14.12)
1758 */
1759int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
1760{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001761 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02001762 size_t i, j;
1763 mbedtls_mpi TA, TB;
Jerome Forissier79013242021-07-28 10:24:04 +02001764 int result_is_zero = 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001765 MPI_VALIDATE_RET( X != NULL );
1766 MPI_VALIDATE_RET( A != NULL );
1767 MPI_VALIDATE_RET( B != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001768
Jens Wiklander98bd5fe2018-11-08 11:18:22 +01001769 mbedtls_mpi_init_mempool( &TA ); mbedtls_mpi_init_mempool( &TB );
Jens Wiklander817466c2018-05-22 13:49:31 +02001770
1771 if( X == A ) { MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) ); A = &TA; }
1772 if( X == B ) { MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) ); B = &TB; }
1773
1774 for( i = A->n; i > 0; i-- )
1775 if( A->p[i - 1] != 0 )
1776 break;
Jerome Forissier79013242021-07-28 10:24:04 +02001777 if( i == 0 )
1778 result_is_zero = 1;
Jens Wiklander817466c2018-05-22 13:49:31 +02001779
1780 for( j = B->n; j > 0; j-- )
1781 if( B->p[j - 1] != 0 )
1782 break;
Jerome Forissier79013242021-07-28 10:24:04 +02001783 if( j == 0 )
1784 result_is_zero = 1;
Jens Wiklander817466c2018-05-22 13:49:31 +02001785
1786 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + j ) );
1787 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
1788
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001789 for( ; j > 0; j-- )
1790 mpi_mul_hlp( i, A->p, X->p + j - 1, B->p[j - 1] );
Jens Wiklander817466c2018-05-22 13:49:31 +02001791
Jerome Forissier79013242021-07-28 10:24:04 +02001792 /* If the result is 0, we don't shortcut the operation, which reduces
1793 * but does not eliminate side channels leaking the zero-ness. We do
1794 * need to take care to set the sign bit properly since the library does
1795 * not fully support an MPI object with a value of 0 and s == -1. */
1796 if( result_is_zero )
1797 X->s = 1;
1798 else
1799 X->s = A->s * B->s;
Jens Wiklander817466c2018-05-22 13:49:31 +02001800
1801cleanup:
1802
1803 mbedtls_mpi_free( &TB ); mbedtls_mpi_free( &TA );
1804
1805 return( ret );
1806}
1807
1808/*
1809 * Baseline multiplication: X = A * b
1810 */
1811int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b )
1812{
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001813 MPI_VALIDATE_RET( X != NULL );
1814 MPI_VALIDATE_RET( A != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001815
Jerome Forissier79013242021-07-28 10:24:04 +02001816 /* mpi_mul_hlp can't deal with a leading 0. */
1817 size_t n = A->n;
1818 while( n > 0 && A->p[n - 1] == 0 )
1819 --n;
Jens Wiklander817466c2018-05-22 13:49:31 +02001820
Jerome Forissier79013242021-07-28 10:24:04 +02001821 /* The general method below doesn't work if n==0 or b==0. By chance
1822 * calculating the result is trivial in those cases. */
1823 if( b == 0 || n == 0 )
1824 {
1825 return( mbedtls_mpi_lset( X, 0 ) );
1826 }
1827
1828 /* Calculate A*b as A + A*(b-1) to take advantage of mpi_mul_hlp */
1829 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1830 /* In general, A * b requires 1 limb more than b. If
1831 * A->p[n - 1] * b / b == A->p[n - 1], then A * b fits in the same
1832 * number of limbs as A and the call to grow() is not required since
1833 * copy() will take care of the growth if needed. However, experimentally,
1834 * making the call to grow() unconditional causes slightly fewer
1835 * calls to calloc() in ECP code, presumably because it reuses the
1836 * same mpi for a while and this way the mpi is more likely to directly
1837 * grow to its final size. */
1838 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, n + 1 ) );
1839 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) );
1840 mpi_mul_hlp( n, A->p, X->p, b - 1 );
1841
1842cleanup:
1843 return( ret );
Jens Wiklander817466c2018-05-22 13:49:31 +02001844}
1845
1846/*
1847 * Unsigned integer divide - double mbedtls_mpi_uint dividend, u1/u0, and
1848 * mbedtls_mpi_uint divisor, d
1849 */
1850static mbedtls_mpi_uint mbedtls_int_div_int( mbedtls_mpi_uint u1,
1851 mbedtls_mpi_uint u0, mbedtls_mpi_uint d, mbedtls_mpi_uint *r )
1852{
1853#if defined(MBEDTLS_HAVE_UDBL)
1854 mbedtls_t_udbl dividend, quotient;
1855#else
1856 const mbedtls_mpi_uint radix = (mbedtls_mpi_uint) 1 << biH;
1857 const mbedtls_mpi_uint uint_halfword_mask = ( (mbedtls_mpi_uint) 1 << biH ) - 1;
1858 mbedtls_mpi_uint d0, d1, q0, q1, rAX, r0, quotient;
1859 mbedtls_mpi_uint u0_msw, u0_lsw;
1860 size_t s;
1861#endif
1862
1863 /*
1864 * Check for overflow
1865 */
1866 if( 0 == d || u1 >= d )
1867 {
1868 if (r != NULL) *r = ~0;
1869
1870 return ( ~0 );
1871 }
1872
1873#if defined(MBEDTLS_HAVE_UDBL)
1874 dividend = (mbedtls_t_udbl) u1 << biL;
1875 dividend |= (mbedtls_t_udbl) u0;
1876 quotient = dividend / d;
1877 if( quotient > ( (mbedtls_t_udbl) 1 << biL ) - 1 )
1878 quotient = ( (mbedtls_t_udbl) 1 << biL ) - 1;
1879
1880 if( r != NULL )
1881 *r = (mbedtls_mpi_uint)( dividend - (quotient * d ) );
1882
1883 return (mbedtls_mpi_uint) quotient;
1884#else
1885
1886 /*
1887 * Algorithm D, Section 4.3.1 - The Art of Computer Programming
1888 * Vol. 2 - Seminumerical Algorithms, Knuth
1889 */
1890
1891 /*
1892 * Normalize the divisor, d, and dividend, u0, u1
1893 */
1894 s = mbedtls_clz( d );
1895 d = d << s;
1896
1897 u1 = u1 << s;
1898 u1 |= ( u0 >> ( biL - s ) ) & ( -(mbedtls_mpi_sint)s >> ( biL - 1 ) );
1899 u0 = u0 << s;
1900
1901 d1 = d >> biH;
1902 d0 = d & uint_halfword_mask;
1903
1904 u0_msw = u0 >> biH;
1905 u0_lsw = u0 & uint_halfword_mask;
1906
1907 /*
1908 * Find the first quotient and remainder
1909 */
1910 q1 = u1 / d1;
1911 r0 = u1 - d1 * q1;
1912
1913 while( q1 >= radix || ( q1 * d0 > radix * r0 + u0_msw ) )
1914 {
1915 q1 -= 1;
1916 r0 += d1;
1917
1918 if ( r0 >= radix ) break;
1919 }
1920
1921 rAX = ( u1 * radix ) + ( u0_msw - q1 * d );
1922 q0 = rAX / d1;
1923 r0 = rAX - q0 * d1;
1924
1925 while( q0 >= radix || ( q0 * d0 > radix * r0 + u0_lsw ) )
1926 {
1927 q0 -= 1;
1928 r0 += d1;
1929
1930 if ( r0 >= radix ) break;
1931 }
1932
1933 if (r != NULL)
1934 *r = ( rAX * radix + u0_lsw - q0 * d ) >> s;
1935
1936 quotient = q1 * radix + q0;
1937
1938 return quotient;
1939#endif
1940}
1941
1942/*
1943 * Division by mbedtls_mpi: A = Q * B + R (HAC 14.20)
1944 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001945int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
1946 const mbedtls_mpi *B )
Jens Wiklander817466c2018-05-22 13:49:31 +02001947{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001948 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02001949 size_t i, n, t, k;
1950 mbedtls_mpi X, Y, Z, T1, T2;
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001951 mbedtls_mpi_uint TP2[3];
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001952 MPI_VALIDATE_RET( A != NULL );
1953 MPI_VALIDATE_RET( B != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001954
1955 if( mbedtls_mpi_cmp_int( B, 0 ) == 0 )
1956 return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO );
1957
Jens Wiklander98bd5fe2018-11-08 11:18:22 +01001958 mbedtls_mpi_init_mempool( &X ); mbedtls_mpi_init_mempool( &Y );
1959 mbedtls_mpi_init_mempool( &Z ); mbedtls_mpi_init_mempool( &T1 );
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001960 /*
1961 * Avoid dynamic memory allocations for constant-size T2.
1962 *
1963 * T2 is used for comparison only and the 3 limbs are assigned explicitly,
1964 * so nobody increase the size of the MPI and we're safe to use an on-stack
1965 * buffer.
1966 */
1967 T2.s = 1;
1968 T2.n = sizeof( TP2 ) / sizeof( *TP2 );
1969 T2.p = TP2;
Jens Wiklander817466c2018-05-22 13:49:31 +02001970
1971 if( mbedtls_mpi_cmp_abs( A, B ) < 0 )
1972 {
1973 if( Q != NULL ) MBEDTLS_MPI_CHK( mbedtls_mpi_lset( Q, 0 ) );
1974 if( R != NULL ) MBEDTLS_MPI_CHK( mbedtls_mpi_copy( R, A ) );
1975 return( 0 );
1976 }
1977
1978 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &X, A ) );
1979 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, B ) );
1980 X.s = Y.s = 1;
1981
1982 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &Z, A->n + 2 ) );
1983 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Z, 0 ) );
Jerome Forissier79013242021-07-28 10:24:04 +02001984 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T1, A->n + 2 ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02001985
1986 k = mbedtls_mpi_bitlen( &Y ) % biL;
1987 if( k < biL - 1 )
1988 {
1989 k = biL - 1 - k;
1990 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &X, k ) );
1991 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &Y, k ) );
1992 }
1993 else k = 0;
1994
1995 n = X.n - 1;
1996 t = Y.n - 1;
1997 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &Y, biL * ( n - t ) ) );
1998
1999 while( mbedtls_mpi_cmp_mpi( &X, &Y ) >= 0 )
2000 {
2001 Z.p[n - t]++;
2002 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &Y ) );
2003 }
2004 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, biL * ( n - t ) ) );
2005
2006 for( i = n; i > t ; i-- )
2007 {
2008 if( X.p[i] >= Y.p[t] )
2009 Z.p[i - t - 1] = ~0;
2010 else
2011 {
2012 Z.p[i - t - 1] = mbedtls_int_div_int( X.p[i], X.p[i - 1],
2013 Y.p[t], NULL);
2014 }
2015
Jerome Forissier11fa71b2020-04-20 17:17:56 +02002016 T2.p[0] = ( i < 2 ) ? 0 : X.p[i - 2];
2017 T2.p[1] = ( i < 1 ) ? 0 : X.p[i - 1];
2018 T2.p[2] = X.p[i];
2019
Jens Wiklander817466c2018-05-22 13:49:31 +02002020 Z.p[i - t - 1]++;
2021 do
2022 {
2023 Z.p[i - t - 1]--;
2024
2025 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &T1, 0 ) );
2026 T1.p[0] = ( t < 1 ) ? 0 : Y.p[t - 1];
2027 T1.p[1] = Y.p[t];
2028 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02002029 }
2030 while( mbedtls_mpi_cmp_mpi( &T1, &T2 ) > 0 );
2031
2032 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
2033 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T1, biL * ( i - t - 1 ) ) );
2034 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T1 ) );
2035
2036 if( mbedtls_mpi_cmp_int( &X, 0 ) < 0 )
2037 {
2038 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T1, &Y ) );
2039 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T1, biL * ( i - t - 1 ) ) );
2040 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &X, &X, &T1 ) );
2041 Z.p[i - t - 1]--;
2042 }
2043 }
2044
2045 if( Q != NULL )
2046 {
2047 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( Q, &Z ) );
2048 Q->s = A->s * B->s;
2049 }
2050
2051 if( R != NULL )
2052 {
2053 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &X, k ) );
2054 X.s = A->s;
2055 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( R, &X ) );
2056
2057 if( mbedtls_mpi_cmp_int( R, 0 ) == 0 )
2058 R->s = 1;
2059 }
2060
2061cleanup:
2062
2063 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
Jerome Forissier11fa71b2020-04-20 17:17:56 +02002064 mbedtls_mpi_free( &T1 );
2065 mbedtls_platform_zeroize( TP2, sizeof( TP2 ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02002066
2067 return( ret );
2068}
2069
2070/*
2071 * Division by int: A = Q * b + R
2072 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002073int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R,
2074 const mbedtls_mpi *A,
2075 mbedtls_mpi_sint b )
Jens Wiklander817466c2018-05-22 13:49:31 +02002076{
2077 mbedtls_mpi _B;
2078 mbedtls_mpi_uint p[1];
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002079 MPI_VALIDATE_RET( A != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02002080
2081 p[0] = ( b < 0 ) ? -b : b;
2082 _B.s = ( b < 0 ) ? -1 : 1;
2083 _B.n = 1;
2084 _B.p = p;
2085
2086 return( mbedtls_mpi_div_mpi( Q, R, A, &_B ) );
2087}
2088
2089/*
2090 * Modulo: R = A mod B
2091 */
2092int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B )
2093{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02002094 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002095 MPI_VALIDATE_RET( R != NULL );
2096 MPI_VALIDATE_RET( A != NULL );
2097 MPI_VALIDATE_RET( B != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02002098
2099 if( mbedtls_mpi_cmp_int( B, 0 ) < 0 )
2100 return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
2101
2102 MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( NULL, R, A, B ) );
2103
2104 while( mbedtls_mpi_cmp_int( R, 0 ) < 0 )
2105 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( R, R, B ) );
2106
2107 while( mbedtls_mpi_cmp_mpi( R, B ) >= 0 )
2108 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( R, R, B ) );
2109
2110cleanup:
2111
2112 return( ret );
2113}
2114
2115/*
2116 * Modulo: r = A mod b
2117 */
2118int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b )
2119{
2120 size_t i;
2121 mbedtls_mpi_uint x, y, z;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002122 MPI_VALIDATE_RET( r != NULL );
2123 MPI_VALIDATE_RET( A != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02002124
2125 if( b == 0 )
2126 return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO );
2127
2128 if( b < 0 )
2129 return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
2130
2131 /*
2132 * handle trivial cases
2133 */
2134 if( b == 1 )
2135 {
2136 *r = 0;
2137 return( 0 );
2138 }
2139
2140 if( b == 2 )
2141 {
2142 *r = A->p[0] & 1;
2143 return( 0 );
2144 }
2145
2146 /*
2147 * general case
2148 */
2149 for( i = A->n, y = 0; i > 0; i-- )
2150 {
2151 x = A->p[i - 1];
2152 y = ( y << biH ) | ( x >> biH );
2153 z = y / b;
2154 y -= z * b;
2155
2156 x <<= biH;
2157 y = ( y << biH ) | ( x >> biH );
2158 z = y / b;
2159 y -= z * b;
2160 }
2161
2162 /*
2163 * If A is negative, then the current y represents a negative value.
2164 * Flipping it to the positive side.
2165 */
2166 if( A->s < 0 && y != 0 )
2167 y = b - y;
2168
2169 *r = y;
2170
2171 return( 0 );
2172}
2173
2174/*
2175 * Fast Montgomery initialization (thanks to Tom St Denis)
2176 */
Jerome Forissier79013242021-07-28 10:24:04 +02002177static void mpi_montg_init( mbedtls_mpi_uint *mm, const mbedtls_mpi *N )
Jens Wiklander817466c2018-05-22 13:49:31 +02002178{
2179 mbedtls_mpi_uint x, m0 = N->p[0];
2180 unsigned int i;
2181
2182 x = m0;
2183 x += ( ( m0 + 2 ) & 4 ) << 1;
2184
2185 for( i = biL; i >= 8; i /= 2 )
2186 x *= ( 2 - ( m0 * x ) );
2187
2188 *mm = ~x + 1;
2189}
2190
Jerome Forissier79013242021-07-28 10:24:04 +02002191void mbedtls_mpi_montg_init( mbedtls_mpi_uint *mm, const mbedtls_mpi *N )
2192{
2193 mpi_montg_init( mm, N );
2194}
2195
2196/** Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
2197 *
2198 * \param[in,out] A One of the numbers to multiply.
2199 * It must have at least as many limbs as N
2200 * (A->n >= N->n), and any limbs beyond n are ignored.
2201 * On successful completion, A contains the result of
2202 * the multiplication A * B * R^-1 mod N where
2203 * R = (2^ciL)^n.
2204 * \param[in] B One of the numbers to multiply.
2205 * It must be nonzero and must not have more limbs than N
2206 * (B->n <= N->n).
2207 * \param[in] N The modulo. N must be odd.
2208 * \param mm The value calculated by `mpi_montg_init(&mm, N)`.
2209 * This is -N^-1 mod 2^ciL.
2210 * \param[in,out] T A bignum for temporary storage.
2211 * It must be at least twice the limb size of N plus 2
2212 * (T->n >= 2 * (N->n + 1)).
2213 * Its initial content is unused and
2214 * its final content is indeterminate.
2215 * Note that unlike the usual convention in the library
2216 * for `const mbedtls_mpi*`, the content of T can change.
Jens Wiklander817466c2018-05-22 13:49:31 +02002217 */
Jerome Forissier79013242021-07-28 10:24:04 +02002218static void mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi *N, mbedtls_mpi_uint mm,
Jens Wiklander817466c2018-05-22 13:49:31 +02002219 const mbedtls_mpi *T )
2220{
2221 size_t i, n, m;
2222 mbedtls_mpi_uint u0, u1, *d;
2223
Jens Wiklander817466c2018-05-22 13:49:31 +02002224 memset( T->p, 0, T->n * ciL );
2225
2226 d = T->p;
2227 n = N->n;
2228 m = ( B->n < n ) ? B->n : n;
2229
2230 for( i = 0; i < n; i++ )
2231 {
2232 /*
2233 * T = (T + u0*B + u1*N) / 2^biL
2234 */
2235 u0 = A->p[i];
2236 u1 = ( d[0] + u0 * B->p[0] ) * mm;
2237
2238 mpi_mul_hlp( m, B->p, d, u0 );
2239 mpi_mul_hlp( n, N->p, d, u1 );
2240
2241 *d++ = u0; d[n + 1] = 0;
2242 }
2243
Jerome Forissier79013242021-07-28 10:24:04 +02002244 /* At this point, d is either the desired result or the desired result
2245 * plus N. We now potentially subtract N, avoiding leaking whether the
2246 * subtraction is performed through side channels. */
Jens Wiklander817466c2018-05-22 13:49:31 +02002247
Jerome Forissier79013242021-07-28 10:24:04 +02002248 /* Copy the n least significant limbs of d to A, so that
2249 * A = d if d < N (recall that N has n limbs). */
2250 memcpy( A->p, d, n * ciL );
2251 /* If d >= N then we want to set A to d - N. To prevent timing attacks,
2252 * do the calculation without using conditional tests. */
2253 /* Set d to d0 + (2^biL)^n - N where d0 is the current value of d. */
2254 d[n] += 1;
2255 d[n] -= mpi_sub_hlp( n, d, d, N->p );
2256 /* If d0 < N then d < (2^biL)^n
2257 * so d[n] == 0 and we want to keep A as it is.
2258 * If d0 >= N then d >= (2^biL)^n, and d <= (2^biL)^n + N < 2 * (2^biL)^n
2259 * so d[n] == 1 and we want to set A to the result of the subtraction
2260 * which is d - (2^biL)^n, i.e. the n least significant limbs of d.
2261 * This exactly corresponds to a conditional assignment. */
2262 mpi_safe_cond_assign( n, A->p, d, (unsigned char) d[n] );
2263}
Jens Wiklander817466c2018-05-22 13:49:31 +02002264
Jerome Forissier79013242021-07-28 10:24:04 +02002265void mbedtls_mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi *N, mbedtls_mpi_uint mm,
2266 const mbedtls_mpi *T )
2267{
2268 mpi_montmul( A, B, N, mm, T);
Jens Wiklander817466c2018-05-22 13:49:31 +02002269}
2270
2271/*
2272 * Montgomery reduction: A = A * R^-1 mod N
Jerome Forissier79013242021-07-28 10:24:04 +02002273 *
2274 * See mpi_montmul() regarding constraints and guarantees on the parameters.
Jens Wiklander817466c2018-05-22 13:49:31 +02002275 */
Jerome Forissier79013242021-07-28 10:24:04 +02002276static void mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N,
2277 mbedtls_mpi_uint mm, const mbedtls_mpi *T )
Jens Wiklander817466c2018-05-22 13:49:31 +02002278{
2279 mbedtls_mpi_uint z = 1;
2280 mbedtls_mpi U;
2281
2282 U.n = U.s = (int) z;
2283 U.p = &z;
2284
Jerome Forissier79013242021-07-28 10:24:04 +02002285 mpi_montmul( A, &U, N, mm, T );
2286}
2287
2288void mbedtls_mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N,
2289 mbedtls_mpi_uint mm, const mbedtls_mpi *T )
2290{
2291 mpi_montred( A, N, mm, T );
2292}
2293
2294/*
2295 * Constant-flow boolean "equal" comparison:
2296 * return x == y
2297 *
2298 * This function can be used to write constant-time code by replacing branches
2299 * with bit operations - it can be used in conjunction with
2300 * mbedtls_ssl_cf_mask_from_bit().
2301 *
2302 * This function is implemented without using comparison operators, as those
2303 * might be translated to branches by some compilers on some platforms.
2304 */
2305static size_t mbedtls_mpi_cf_bool_eq( size_t x, size_t y )
2306{
2307 /* diff = 0 if x == y, non-zero otherwise */
2308 const size_t diff = x ^ y;
2309
2310 /* MSVC has a warning about unary minus on unsigned integer types,
2311 * but this is well-defined and precisely what we want to do here. */
2312#if defined(_MSC_VER)
2313#pragma warning( push )
2314#pragma warning( disable : 4146 )
2315#endif
2316
2317 /* diff_msb's most significant bit is equal to x != y */
2318 const size_t diff_msb = ( diff | (size_t) -diff );
2319
2320#if defined(_MSC_VER)
2321#pragma warning( pop )
2322#endif
2323
2324 /* diff1 = (x != y) ? 1 : 0 */
2325 const size_t diff1 = diff_msb >> ( sizeof( diff_msb ) * 8 - 1 );
2326
2327 return( 1 ^ diff1 );
2328}
2329
2330/**
2331 * Select an MPI from a table without leaking the index.
2332 *
2333 * This is functionally equivalent to mbedtls_mpi_copy(R, T[idx]) except it
2334 * reads the entire table in order to avoid leaking the value of idx to an
2335 * attacker able to observe memory access patterns.
2336 *
2337 * \param[out] R Where to write the selected MPI.
2338 * \param[in] T The table to read from.
2339 * \param[in] T_size The number of elements in the table.
2340 * \param[in] idx The index of the element to select;
2341 * this must satisfy 0 <= idx < T_size.
2342 *
2343 * \return \c 0 on success, or a negative error code.
2344 */
2345static int mpi_select( mbedtls_mpi *R, const mbedtls_mpi *T, size_t T_size, size_t idx )
2346{
2347 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2348
2349 for( size_t i = 0; i < T_size; i++ )
2350 {
2351 MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( R, &T[i],
2352 (unsigned char) mbedtls_mpi_cf_bool_eq( i, idx ) ) );
2353 }
2354
2355cleanup:
2356 return( ret );
Jens Wiklander817466c2018-05-22 13:49:31 +02002357}
2358
2359/*
2360 * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
2361 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002362int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
2363 const mbedtls_mpi *E, const mbedtls_mpi *N,
2364 mbedtls_mpi *_RR )
Jens Wiklander817466c2018-05-22 13:49:31 +02002365{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02002366 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02002367 size_t wbits, wsize, one = 1;
2368 size_t i, j, nblimbs;
2369 size_t bufsize, nbits;
2370 mbedtls_mpi_uint ei, mm, state;
Jerome Forissier79013242021-07-28 10:24:04 +02002371 mbedtls_mpi RR, T, WW, Apos;
Jens Wiklanderad443202019-05-27 16:42:58 +02002372 mbedtls_mpi *W = NULL;
Jens Wiklander41e5aa82019-05-21 22:52:10 +02002373 const size_t array_size_W = 2 << MBEDTLS_MPI_WINDOW_SIZE;
Jens Wiklander817466c2018-05-22 13:49:31 +02002374 int neg;
2375
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002376 MPI_VALIDATE_RET( X != NULL );
2377 MPI_VALIDATE_RET( A != NULL );
2378 MPI_VALIDATE_RET( E != NULL );
2379 MPI_VALIDATE_RET( N != NULL );
2380
2381 if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 || ( N->p[0] & 1 ) == 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +02002382 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
2383
2384 if( mbedtls_mpi_cmp_int( E, 0 ) < 0 )
2385 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
2386
Jerome Forissier79013242021-07-28 10:24:04 +02002387 if( mbedtls_mpi_bitlen( E ) > MBEDTLS_MPI_MAX_BITS ||
2388 mbedtls_mpi_bitlen( N ) > MBEDTLS_MPI_MAX_BITS )
2389 return ( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
2390
Jens Wiklander817466c2018-05-22 13:49:31 +02002391 /*
2392 * Init temps and window size
2393 */
Jerome Forissier79013242021-07-28 10:24:04 +02002394 mpi_montg_init( &mm, N );
2395 mbedtls_mpi_init_mempool( &RR ); mbedtls_mpi_init( &T );
Jens Wiklander98bd5fe2018-11-08 11:18:22 +01002396 mbedtls_mpi_init_mempool( &Apos );
Jerome Forissier79013242021-07-28 10:24:04 +02002397 mbedtls_mpi_init_mempool( &WW );
Jens Wiklander817466c2018-05-22 13:49:31 +02002398
2399 i = mbedtls_mpi_bitlen( E );
2400
2401 wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
2402 ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
2403
Jerome Forissier5b25c762020-04-07 11:18:49 +02002404#if( MBEDTLS_MPI_WINDOW_SIZE < 6 )
Jens Wiklander817466c2018-05-22 13:49:31 +02002405 if( wsize > MBEDTLS_MPI_WINDOW_SIZE )
2406 wsize = MBEDTLS_MPI_WINDOW_SIZE;
Jerome Forissier5b25c762020-04-07 11:18:49 +02002407#endif
Jens Wiklander817466c2018-05-22 13:49:31 +02002408
2409 j = N->n + 1;
Jerome Forissier79013242021-07-28 10:24:04 +02002410 /* All W[i] and X must have at least N->n limbs for the mpi_montmul()
2411 * and mpi_montred() calls later. Here we ensure that W[1] and X are
2412 * large enough, and later we'll grow other W[i] to the same length.
2413 * They must not be shrunk midway through this function!
2414 */
Jens Wiklander817466c2018-05-22 13:49:31 +02002415 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) );
Jens Wiklanderad443202019-05-27 16:42:58 +02002416
Jens Wiklander817466c2018-05-22 13:49:31 +02002417 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T, j * 2 ) );
2418
2419 /*
2420 * Compensate for negative A (and correct at the end)
2421 */
2422 neg = ( A->s == -1 );
2423 if( neg )
2424 {
2425 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Apos, A ) );
2426 Apos.s = 1;
2427 A = &Apos;
2428 }
2429
2430 /*
2431 * If 1st call, pre-compute R^2 mod N
2432 */
2433 if( _RR == NULL || _RR->p == NULL )
2434 {
2435 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &RR, 1 ) );
2436 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &RR, N->n * 2 * biL ) );
2437 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &RR, &RR, N ) );
2438
2439 if( _RR != NULL )
2440 memcpy( _RR, &RR, sizeof( mbedtls_mpi ) );
2441 }
2442 else
2443 memcpy( &RR, _RR, sizeof( mbedtls_mpi ) );
2444
Jens Wiklanderad443202019-05-27 16:42:58 +02002445 W = mempool_alloc( mbedtls_mpi_mempool,
2446 sizeof( mbedtls_mpi ) * array_size_W );
2447 if( W == NULL ) {
2448 ret = MBEDTLS_ERR_MPI_ALLOC_FAILED;
2449 goto cleanup;
2450 }
2451 for( i = 0; i < array_size_W; i++ )
2452 mbedtls_mpi_init_mempool( W + i );
2453 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1], j ) );
2454
Jens Wiklander817466c2018-05-22 13:49:31 +02002455 /*
2456 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
2457 */
2458 if( mbedtls_mpi_cmp_mpi( A, N ) >= 0 )
Jerome Forissier79013242021-07-28 10:24:04 +02002459 {
Jens Wiklander817466c2018-05-22 13:49:31 +02002460 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &W[1], A, N ) );
Jerome Forissier79013242021-07-28 10:24:04 +02002461 /* This should be a no-op because W[1] is already that large before
2462 * mbedtls_mpi_mod_mpi(), but it's necessary to avoid an overflow
2463 * in mpi_montmul() below, so let's make sure. */
2464 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1], N->n + 1 ) );
2465 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002466 else
2467 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[1], A ) );
2468
Jerome Forissier79013242021-07-28 10:24:04 +02002469 /* Note that this is safe because W[1] always has at least N->n limbs
2470 * (it grew above and was preserved by mbedtls_mpi_copy()). */
2471 mpi_montmul( &W[1], &RR, N, mm, &T );
Jens Wiklander817466c2018-05-22 13:49:31 +02002472
2473 /*
2474 * X = R^2 * R^-1 mod N = R mod N
2475 */
2476 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &RR ) );
Jerome Forissier79013242021-07-28 10:24:04 +02002477 mpi_montred( X, N, mm, &T );
Jens Wiklander817466c2018-05-22 13:49:31 +02002478
2479 if( wsize > 1 )
2480 {
2481 /*
2482 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
2483 */
2484 j = one << ( wsize - 1 );
2485
2486 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[j], N->n + 1 ) );
2487 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[j], &W[1] ) );
2488
2489 for( i = 0; i < wsize - 1; i++ )
Jerome Forissier79013242021-07-28 10:24:04 +02002490 mpi_montmul( &W[j], &W[j], N, mm, &T );
Jens Wiklander817466c2018-05-22 13:49:31 +02002491
2492 /*
2493 * W[i] = W[i - 1] * W[1]
2494 */
2495 for( i = j + 1; i < ( one << wsize ); i++ )
2496 {
2497 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[i], N->n + 1 ) );
2498 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[i], &W[i - 1] ) );
2499
Jerome Forissier79013242021-07-28 10:24:04 +02002500 mpi_montmul( &W[i], &W[1], N, mm, &T );
Jens Wiklander817466c2018-05-22 13:49:31 +02002501 }
2502 }
2503
2504 nblimbs = E->n;
2505 bufsize = 0;
2506 nbits = 0;
2507 wbits = 0;
2508 state = 0;
2509
2510 while( 1 )
2511 {
2512 if( bufsize == 0 )
2513 {
2514 if( nblimbs == 0 )
2515 break;
2516
2517 nblimbs--;
2518
2519 bufsize = sizeof( mbedtls_mpi_uint ) << 3;
2520 }
2521
2522 bufsize--;
2523
2524 ei = (E->p[nblimbs] >> bufsize) & 1;
2525
2526 /*
2527 * skip leading 0s
2528 */
2529 if( ei == 0 && state == 0 )
2530 continue;
2531
2532 if( ei == 0 && state == 1 )
2533 {
2534 /*
2535 * out of window, square X
2536 */
Jerome Forissier79013242021-07-28 10:24:04 +02002537 mpi_montmul( X, X, N, mm, &T );
Jens Wiklander817466c2018-05-22 13:49:31 +02002538 continue;
2539 }
2540
2541 /*
2542 * add ei to current window
2543 */
2544 state = 2;
2545
2546 nbits++;
2547 wbits |= ( ei << ( wsize - nbits ) );
2548
2549 if( nbits == wsize )
2550 {
2551 /*
2552 * X = X^wsize R^-1 mod N
2553 */
2554 for( i = 0; i < wsize; i++ )
Jerome Forissier79013242021-07-28 10:24:04 +02002555 mpi_montmul( X, X, N, mm, &T );
Jens Wiklander817466c2018-05-22 13:49:31 +02002556
2557 /*
2558 * X = X * W[wbits] R^-1 mod N
2559 */
Jerome Forissier79013242021-07-28 10:24:04 +02002560 MBEDTLS_MPI_CHK( mpi_select( &WW, W, (size_t) 1 << wsize, wbits ) );
2561 mpi_montmul( X, &WW, N, mm, &T );
Jens Wiklander817466c2018-05-22 13:49:31 +02002562
2563 state--;
2564 nbits = 0;
2565 wbits = 0;
2566 }
2567 }
2568
2569 /*
2570 * process the remaining bits
2571 */
2572 for( i = 0; i < nbits; i++ )
2573 {
Jerome Forissier79013242021-07-28 10:24:04 +02002574 mpi_montmul( X, X, N, mm, &T );
Jens Wiklander817466c2018-05-22 13:49:31 +02002575
2576 wbits <<= 1;
2577
2578 if( ( wbits & ( one << wsize ) ) != 0 )
Jerome Forissier79013242021-07-28 10:24:04 +02002579 mpi_montmul( X, &W[1], N, mm, &T );
Jens Wiklander817466c2018-05-22 13:49:31 +02002580 }
2581
2582 /*
2583 * X = A^E * R * R^-1 mod N = A^E mod N
2584 */
Jerome Forissier79013242021-07-28 10:24:04 +02002585 mpi_montred( X, N, mm, &T );
Jens Wiklander817466c2018-05-22 13:49:31 +02002586
2587 if( neg && E->n != 0 && ( E->p[0] & 1 ) != 0 )
2588 {
2589 X->s = -1;
2590 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( X, N, X ) );
2591 }
2592
2593cleanup:
2594
Jens Wiklanderad443202019-05-27 16:42:58 +02002595 if( W )
2596 for( i = 0; i < array_size_W; i++ )
2597 mbedtls_mpi_free( W + i );
Jens Wiklander41e5aa82019-05-21 22:52:10 +02002598 mempool_free( mbedtls_mpi_mempool , W );
Jens Wiklander817466c2018-05-22 13:49:31 +02002599
Jens Wiklanderb99a4a12019-04-17 12:25:20 +02002600 mbedtls_mpi_free( &T ); mbedtls_mpi_free( &Apos );
Jerome Forissier79013242021-07-28 10:24:04 +02002601 mbedtls_mpi_free( &WW );
Jens Wiklander817466c2018-05-22 13:49:31 +02002602
2603 if( _RR == NULL || _RR->p == NULL )
2604 mbedtls_mpi_free( &RR );
2605
2606 return( ret );
2607}
2608
2609/*
2610 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
2611 */
2612int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B )
2613{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02002614 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02002615 size_t lz, lzt;
Jerome Forissier11fa71b2020-04-20 17:17:56 +02002616 mbedtls_mpi TA, TB;
Jens Wiklander817466c2018-05-22 13:49:31 +02002617
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002618 MPI_VALIDATE_RET( G != NULL );
2619 MPI_VALIDATE_RET( A != NULL );
2620 MPI_VALIDATE_RET( B != NULL );
2621
Jerome Forissier11fa71b2020-04-20 17:17:56 +02002622 mbedtls_mpi_init_mempool( &TA ); mbedtls_mpi_init_mempool( &TB );
Jens Wiklander817466c2018-05-22 13:49:31 +02002623
2624 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) );
2625 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) );
2626
2627 lz = mbedtls_mpi_lsb( &TA );
2628 lzt = mbedtls_mpi_lsb( &TB );
2629
Jerome Forissier79013242021-07-28 10:24:04 +02002630 /* The loop below gives the correct result when A==0 but not when B==0.
2631 * So have a special case for B==0. Leverage the fact that we just
2632 * calculated the lsb and lsb(B)==0 iff B is odd or 0 to make the test
2633 * slightly more efficient than cmp_int(). */
2634 if( lzt == 0 && mbedtls_mpi_get_bit( &TB, 0 ) == 0 )
2635 {
2636 ret = mbedtls_mpi_copy( G, A );
2637 goto cleanup;
2638 }
2639
Jens Wiklander817466c2018-05-22 13:49:31 +02002640 if( lzt < lz )
2641 lz = lzt;
2642
Jens Wiklander817466c2018-05-22 13:49:31 +02002643 TA.s = TB.s = 1;
2644
Jerome Forissier79013242021-07-28 10:24:04 +02002645 /* We mostly follow the procedure described in HAC 14.54, but with some
2646 * minor differences:
2647 * - Sequences of multiplications or divisions by 2 are grouped into a
2648 * single shift operation.
2649 * - The procedure in HAC assumes that 0 < TB <= TA.
2650 * - The condition TB <= TA is not actually necessary for correctness.
2651 * TA and TB have symmetric roles except for the loop termination
2652 * condition, and the shifts at the beginning of the loop body
2653 * remove any significance from the ordering of TA vs TB before
2654 * the shifts.
2655 * - If TA = 0, the loop goes through 0 iterations and the result is
2656 * correctly TB.
2657 * - The case TB = 0 was short-circuited above.
2658 *
2659 * For the correctness proof below, decompose the original values of
2660 * A and B as
2661 * A = sa * 2^a * A' with A'=0 or A' odd, and sa = +-1
2662 * B = sb * 2^b * B' with B'=0 or B' odd, and sb = +-1
2663 * Then gcd(A, B) = 2^{min(a,b)} * gcd(A',B'),
2664 * and gcd(A',B') is odd or 0.
2665 *
2666 * At the beginning, we have TA = |A| and TB = |B| so gcd(A,B) = gcd(TA,TB).
2667 * The code maintains the following invariant:
2668 * gcd(A,B) = 2^k * gcd(TA,TB) for some k (I)
2669 */
2670
2671 /* Proof that the loop terminates:
2672 * At each iteration, either the right-shift by 1 is made on a nonzero
2673 * value and the nonnegative integer bitlen(TA) + bitlen(TB) decreases
2674 * by at least 1, or the right-shift by 1 is made on zero and then
2675 * TA becomes 0 which ends the loop (TB cannot be 0 if it is right-shifted
2676 * since in that case TB is calculated from TB-TA with the condition TB>TA).
2677 */
Jens Wiklander817466c2018-05-22 13:49:31 +02002678 while( mbedtls_mpi_cmp_int( &TA, 0 ) != 0 )
2679 {
Jerome Forissier79013242021-07-28 10:24:04 +02002680 /* Divisions by 2 preserve the invariant (I). */
Jens Wiklander817466c2018-05-22 13:49:31 +02002681 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, mbedtls_mpi_lsb( &TA ) ) );
2682 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, mbedtls_mpi_lsb( &TB ) ) );
2683
Jerome Forissier79013242021-07-28 10:24:04 +02002684 /* Set either TA or TB to |TA-TB|/2. Since TA and TB are both odd,
2685 * TA-TB is even so the division by 2 has an integer result.
2686 * Invariant (I) is preserved since any odd divisor of both TA and TB
2687 * also divides |TA-TB|/2, and any odd divisor of both TA and |TA-TB|/2
2688 * also divides TB, and any odd divisior of both TB and |TA-TB|/2 also
2689 * divides TA.
2690 */
Jens Wiklander817466c2018-05-22 13:49:31 +02002691 if( mbedtls_mpi_cmp_mpi( &TA, &TB ) >= 0 )
2692 {
2693 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TA, &TA, &TB ) );
2694 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, 1 ) );
2695 }
2696 else
2697 {
2698 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TB, &TB, &TA ) );
2699 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, 1 ) );
2700 }
Jerome Forissier79013242021-07-28 10:24:04 +02002701 /* Note that one of TA or TB is still odd. */
Jens Wiklander817466c2018-05-22 13:49:31 +02002702 }
2703
Jerome Forissier79013242021-07-28 10:24:04 +02002704 /* By invariant (I), gcd(A,B) = 2^k * gcd(TA,TB) for some k.
2705 * At the loop exit, TA = 0, so gcd(TA,TB) = TB.
2706 * - If there was at least one loop iteration, then one of TA or TB is odd,
2707 * and TA = 0, so TB is odd and gcd(TA,TB) = gcd(A',B'). In this case,
2708 * lz = min(a,b) so gcd(A,B) = 2^lz * TB.
2709 * - If there was no loop iteration, then A was 0, and gcd(A,B) = B.
2710 * In this case, lz = 0 and B = TB so gcd(A,B) = B = 2^lz * TB as well.
2711 */
2712
Jens Wiklander817466c2018-05-22 13:49:31 +02002713 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &TB, lz ) );
2714 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( G, &TB ) );
2715
2716cleanup:
2717
Jerome Forissier11fa71b2020-04-20 17:17:56 +02002718 mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TB );
Jens Wiklander817466c2018-05-22 13:49:31 +02002719
2720 return( ret );
2721}
2722
Jerome Forissier79013242021-07-28 10:24:04 +02002723/* Fill X with n_bytes random bytes.
2724 * X must already have room for those bytes.
2725 * The ordering of the bytes returned from the RNG is suitable for
2726 * deterministic ECDSA (see RFC 6979 §3.3 and mbedtls_mpi_random()).
2727 * The size and sign of X are unchanged.
2728 * n_bytes must not be 0.
2729 */
2730static int mpi_fill_random_internal(
2731 mbedtls_mpi *X, size_t n_bytes,
2732 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
2733{
2734 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2735 const size_t limbs = CHARS_TO_LIMBS( n_bytes );
2736 const size_t overhead = ( limbs * ciL ) - n_bytes;
2737
2738 if( X->n < limbs )
2739 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
2740
2741 memset( X->p, 0, overhead );
2742 memset( (unsigned char *) X->p + limbs * ciL, 0, ( X->n - limbs ) * ciL );
2743 MBEDTLS_MPI_CHK( f_rng( p_rng, (unsigned char *) X->p + overhead, n_bytes ) );
2744 mpi_bigendian_to_host( X->p, limbs );
2745
2746cleanup:
2747 return( ret );
2748}
2749
Jens Wiklander817466c2018-05-22 13:49:31 +02002750/*
2751 * Fill X with size bytes of random.
2752 *
2753 * Use a temporary bytes representation to make sure the result is the same
2754 * regardless of the platform endianness (useful when f_rng is actually
2755 * deterministic, eg for tests).
2756 */
2757int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size,
2758 int (*f_rng)(void *, unsigned char *, size_t),
2759 void *p_rng )
2760{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02002761 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jerome Forissier5b25c762020-04-07 11:18:49 +02002762 size_t const limbs = CHARS_TO_LIMBS( size );
Jerome Forissier5b25c762020-04-07 11:18:49 +02002763
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002764 MPI_VALIDATE_RET( X != NULL );
2765 MPI_VALIDATE_RET( f_rng != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02002766
Jerome Forissier5b25c762020-04-07 11:18:49 +02002767 /* Ensure that target MPI has exactly the necessary number of limbs */
Jerome Forissier79013242021-07-28 10:24:04 +02002768 MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, limbs ) );
2769 if( size == 0 )
2770 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +02002771
Jerome Forissier79013242021-07-28 10:24:04 +02002772 ret = mpi_fill_random_internal( X, size, f_rng, p_rng );
Jens Wiklander817466c2018-05-22 13:49:31 +02002773
2774cleanup:
2775 return( ret );
2776}
2777
Jerome Forissier79013242021-07-28 10:24:04 +02002778int mbedtls_mpi_random( mbedtls_mpi *X,
2779 mbedtls_mpi_sint min,
2780 const mbedtls_mpi *N,
2781 int (*f_rng)(void *, unsigned char *, size_t),
2782 void *p_rng )
2783{
2784 int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
2785 int count;
2786 unsigned lt_lower = 1, lt_upper = 0;
2787 size_t n_bits = mbedtls_mpi_bitlen( N );
2788 size_t n_bytes = ( n_bits + 7 ) / 8;
2789 mbedtls_mpi lower_bound;
2790
2791 if( min < 0 )
2792 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
2793 if( mbedtls_mpi_cmp_int( N, min ) <= 0 )
2794 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
2795
2796 /*
2797 * When min == 0, each try has at worst a probability 1/2 of failing
2798 * (the msb has a probability 1/2 of being 0, and then the result will
2799 * be < N), so after 30 tries failure probability is a most 2**(-30).
2800 *
2801 * When N is just below a power of 2, as is the case when generating
2802 * a random scalar on most elliptic curves, 1 try is enough with
2803 * overwhelming probability. When N is just above a power of 2,
2804 * as when generating a random scalar on secp224k1, each try has
2805 * a probability of failing that is almost 1/2.
2806 *
2807 * The probabilities are almost the same if min is nonzero but negligible
2808 * compared to N. This is always the case when N is crypto-sized, but
2809 * it's convenient to support small N for testing purposes. When N
2810 * is small, use a higher repeat count, otherwise the probability of
2811 * failure is macroscopic.
2812 */
2813 count = ( n_bytes > 4 ? 30 : 250 );
2814
2815 mbedtls_mpi_init( &lower_bound );
2816
2817 /* Ensure that target MPI has exactly the same number of limbs
2818 * as the upper bound, even if the upper bound has leading zeros.
2819 * This is necessary for the mbedtls_mpi_lt_mpi_ct() check. */
2820 MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, N->n ) );
2821 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &lower_bound, N->n ) );
2822 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &lower_bound, min ) );
2823
2824 /*
2825 * Match the procedure given in RFC 6979 §3.3 (deterministic ECDSA)
2826 * when f_rng is a suitably parametrized instance of HMAC_DRBG:
2827 * - use the same byte ordering;
2828 * - keep the leftmost n_bits bits of the generated octet string;
2829 * - try until result is in the desired range.
2830 * This also avoids any bias, which is especially important for ECDSA.
2831 */
2832 do
2833 {
2834 MBEDTLS_MPI_CHK( mpi_fill_random_internal( X, n_bytes, f_rng, p_rng ) );
2835 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, 8 * n_bytes - n_bits ) );
2836
2837 if( --count == 0 )
2838 {
2839 ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
2840 goto cleanup;
2841 }
2842
2843 MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( X, &lower_bound, &lt_lower ) );
2844 MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( X, N, &lt_upper ) );
2845 }
2846 while( lt_lower != 0 || lt_upper == 0 );
2847
2848cleanup:
2849 mbedtls_mpi_free( &lower_bound );
2850 return( ret );
2851}
2852
Jens Wiklander817466c2018-05-22 13:49:31 +02002853/*
2854 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
2855 */
2856int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N )
2857{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02002858 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02002859 mbedtls_mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002860 MPI_VALIDATE_RET( X != NULL );
2861 MPI_VALIDATE_RET( A != NULL );
2862 MPI_VALIDATE_RET( N != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02002863
2864 if( mbedtls_mpi_cmp_int( N, 1 ) <= 0 )
2865 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
2866
Jens Wiklander98bd5fe2018-11-08 11:18:22 +01002867 mbedtls_mpi_init_mempool( &TA ); mbedtls_mpi_init_mempool( &TU );
2868 mbedtls_mpi_init_mempool( &U1 ); mbedtls_mpi_init_mempool( &U2 );
2869 mbedtls_mpi_init_mempool( &G ); mbedtls_mpi_init_mempool( &TB );
2870 mbedtls_mpi_init_mempool( &TV ); mbedtls_mpi_init_mempool( &V1 );
2871 mbedtls_mpi_init_mempool( &V2 );
Jens Wiklander817466c2018-05-22 13:49:31 +02002872
2873 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, A, N ) );
2874
2875 if( mbedtls_mpi_cmp_int( &G, 1 ) != 0 )
2876 {
2877 ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
2878 goto cleanup;
2879 }
2880
2881 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &TA, A, N ) );
2882 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TU, &TA ) );
2883 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, N ) );
2884 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TV, N ) );
2885
2886 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &U1, 1 ) );
2887 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &U2, 0 ) );
2888 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &V1, 0 ) );
2889 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &V2, 1 ) );
2890
2891 do
2892 {
2893 while( ( TU.p[0] & 1 ) == 0 )
2894 {
2895 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TU, 1 ) );
2896
2897 if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
2898 {
2899 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &U1, &U1, &TB ) );
2900 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U2, &U2, &TA ) );
2901 }
2902
2903 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &U1, 1 ) );
2904 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &U2, 1 ) );
2905 }
2906
2907 while( ( TV.p[0] & 1 ) == 0 )
2908 {
2909 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TV, 1 ) );
2910
2911 if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
2912 {
2913 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &V1, &V1, &TB ) );
2914 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V2, &V2, &TA ) );
2915 }
2916
2917 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &V1, 1 ) );
2918 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &V2, 1 ) );
2919 }
2920
2921 if( mbedtls_mpi_cmp_mpi( &TU, &TV ) >= 0 )
2922 {
2923 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &TU, &TU, &TV ) );
2924 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U1, &U1, &V1 ) );
2925 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U2, &U2, &V2 ) );
2926 }
2927 else
2928 {
2929 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &TV, &TV, &TU ) );
2930 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V1, &V1, &U1 ) );
2931 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V2, &V2, &U2 ) );
2932 }
2933 }
2934 while( mbedtls_mpi_cmp_int( &TU, 0 ) != 0 );
2935
2936 while( mbedtls_mpi_cmp_int( &V1, 0 ) < 0 )
2937 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &V1, &V1, N ) );
2938
2939 while( mbedtls_mpi_cmp_mpi( &V1, N ) >= 0 )
2940 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V1, &V1, N ) );
2941
2942 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &V1 ) );
2943
2944cleanup:
2945
2946 mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TU ); mbedtls_mpi_free( &U1 ); mbedtls_mpi_free( &U2 );
2947 mbedtls_mpi_free( &G ); mbedtls_mpi_free( &TB ); mbedtls_mpi_free( &TV );
2948 mbedtls_mpi_free( &V1 ); mbedtls_mpi_free( &V2 );
2949
2950 return( ret );
2951}
2952
2953#if defined(MBEDTLS_GENPRIME)
2954
2955static const int small_prime[] =
2956{
2957 3, 5, 7, 11, 13, 17, 19, 23,
2958 29, 31, 37, 41, 43, 47, 53, 59,
2959 61, 67, 71, 73, 79, 83, 89, 97,
2960 101, 103, 107, 109, 113, 127, 131, 137,
2961 139, 149, 151, 157, 163, 167, 173, 179,
2962 181, 191, 193, 197, 199, 211, 223, 227,
2963 229, 233, 239, 241, 251, 257, 263, 269,
2964 271, 277, 281, 283, 293, 307, 311, 313,
2965 317, 331, 337, 347, 349, 353, 359, 367,
2966 373, 379, 383, 389, 397, 401, 409, 419,
2967 421, 431, 433, 439, 443, 449, 457, 461,
2968 463, 467, 479, 487, 491, 499, 503, 509,
2969 521, 523, 541, 547, 557, 563, 569, 571,
2970 577, 587, 593, 599, 601, 607, 613, 617,
2971 619, 631, 641, 643, 647, 653, 659, 661,
2972 673, 677, 683, 691, 701, 709, 719, 727,
2973 733, 739, 743, 751, 757, 761, 769, 773,
2974 787, 797, 809, 811, 821, 823, 827, 829,
2975 839, 853, 857, 859, 863, 877, 881, 883,
2976 887, 907, 911, 919, 929, 937, 941, 947,
2977 953, 967, 971, 977, 983, 991, 997, -103
2978};
2979
2980/*
2981 * Small divisors test (X must be positive)
2982 *
2983 * Return values:
2984 * 0: no small factor (possible prime, more tests needed)
2985 * 1: certain prime
2986 * MBEDTLS_ERR_MPI_NOT_ACCEPTABLE: certain non-prime
2987 * other negative: error
2988 */
2989static int mpi_check_small_factors( const mbedtls_mpi *X )
2990{
2991 int ret = 0;
2992 size_t i;
2993 mbedtls_mpi_uint r;
2994
2995 if( ( X->p[0] & 1 ) == 0 )
2996 return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
2997
2998 for( i = 0; small_prime[i] > 0; i++ )
2999 {
3000 if( mbedtls_mpi_cmp_int( X, small_prime[i] ) <= 0 )
3001 return( 1 );
3002
3003 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, small_prime[i] ) );
3004
3005 if( r == 0 )
3006 return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
3007 }
3008
3009cleanup:
3010 return( ret );
3011}
3012
3013/*
3014 * Miller-Rabin pseudo-primality test (HAC 4.24)
3015 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003016static int mpi_miller_rabin( const mbedtls_mpi *X, size_t rounds,
Jens Wiklander817466c2018-05-22 13:49:31 +02003017 int (*f_rng)(void *, unsigned char *, size_t),
3018 void *p_rng )
3019{
3020 int ret, count;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003021 size_t i, j, k, s;
Jens Wiklander817466c2018-05-22 13:49:31 +02003022 mbedtls_mpi W, R, T, A, RR;
3023
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003024 MPI_VALIDATE_RET( X != NULL );
3025 MPI_VALIDATE_RET( f_rng != NULL );
3026
Jens Wiklander98bd5fe2018-11-08 11:18:22 +01003027 mbedtls_mpi_init_mempool( &W ); mbedtls_mpi_init_mempool( &R );
3028 mbedtls_mpi_init_mempool( &T ); mbedtls_mpi_init_mempool( &A );
3029 mbedtls_mpi_init_mempool( &RR );
Jens Wiklander817466c2018-05-22 13:49:31 +02003030
3031 /*
3032 * W = |X| - 1
3033 * R = W >> lsb( W )
3034 */
3035 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &W, X, 1 ) );
3036 s = mbedtls_mpi_lsb( &W );
3037 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R, &W ) );
3038 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &R, s ) );
3039
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003040 for( i = 0; i < rounds; i++ )
Jens Wiklander817466c2018-05-22 13:49:31 +02003041 {
3042 /*
3043 * pick a random A, 1 < A < |X| - 1
3044 */
Jens Wiklander817466c2018-05-22 13:49:31 +02003045 count = 0;
3046 do {
3047 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
3048
3049 j = mbedtls_mpi_bitlen( &A );
3050 k = mbedtls_mpi_bitlen( &W );
3051 if (j > k) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003052 A.p[A.n - 1] &= ( (mbedtls_mpi_uint) 1 << ( k - ( A.n - 1 ) * biL - 1 ) ) - 1;
Jens Wiklander817466c2018-05-22 13:49:31 +02003053 }
3054
Jens Wiklander117cce92018-11-27 12:21:24 +01003055 if (count++ > 300) {
Jens Wiklander336e3292019-01-17 11:14:38 +01003056 ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
3057 goto cleanup;
Jens Wiklander817466c2018-05-22 13:49:31 +02003058 }
3059
3060 } while ( mbedtls_mpi_cmp_mpi( &A, &W ) >= 0 ||
3061 mbedtls_mpi_cmp_int( &A, 1 ) <= 0 );
3062
3063 /*
3064 * A = A^R mod |X|
3065 */
3066 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &A, &A, &R, X, &RR ) );
3067
3068 if( mbedtls_mpi_cmp_mpi( &A, &W ) == 0 ||
3069 mbedtls_mpi_cmp_int( &A, 1 ) == 0 )
3070 continue;
3071
3072 j = 1;
3073 while( j < s && mbedtls_mpi_cmp_mpi( &A, &W ) != 0 )
3074 {
3075 /*
3076 * A = A * A mod |X|
3077 */
3078 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &A, &A ) );
3079 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &A, &T, X ) );
3080
3081 if( mbedtls_mpi_cmp_int( &A, 1 ) == 0 )
3082 break;
3083
3084 j++;
3085 }
3086
3087 /*
3088 * not prime if A != |X| - 1 or A == 1
3089 */
3090 if( mbedtls_mpi_cmp_mpi( &A, &W ) != 0 ||
3091 mbedtls_mpi_cmp_int( &A, 1 ) == 0 )
3092 {
3093 ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
3094 break;
3095 }
3096 }
3097
3098cleanup:
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003099 mbedtls_mpi_free( &W ); mbedtls_mpi_free( &R );
3100 mbedtls_mpi_free( &T ); mbedtls_mpi_free( &A );
Jens Wiklander817466c2018-05-22 13:49:31 +02003101 mbedtls_mpi_free( &RR );
3102
3103 return( ret );
3104}
3105
3106/*
3107 * Pseudo-primality test: small factors, then Miller-Rabin
3108 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003109int mbedtls_mpi_is_prime_ext( const mbedtls_mpi *X, int rounds,
3110 int (*f_rng)(void *, unsigned char *, size_t),
3111 void *p_rng )
Jens Wiklander817466c2018-05-22 13:49:31 +02003112{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02003113 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02003114 mbedtls_mpi XX;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003115 MPI_VALIDATE_RET( X != NULL );
3116 MPI_VALIDATE_RET( f_rng != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02003117
3118 XX.s = 1;
3119 XX.n = X->n;
3120 XX.p = X->p;
3121
3122 if( mbedtls_mpi_cmp_int( &XX, 0 ) == 0 ||
3123 mbedtls_mpi_cmp_int( &XX, 1 ) == 0 )
3124 return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
3125
3126 if( mbedtls_mpi_cmp_int( &XX, 2 ) == 0 )
3127 return( 0 );
3128
3129 if( ( ret = mpi_check_small_factors( &XX ) ) != 0 )
3130 {
3131 if( ret == 1 )
3132 return( 0 );
3133
3134 return( ret );
3135 }
3136
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003137 return( mpi_miller_rabin( &XX, rounds, f_rng, p_rng ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02003138}
3139
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003140#if !defined(MBEDTLS_DEPRECATED_REMOVED)
3141/*
3142 * Pseudo-primality test, error probability 2^-80
3143 */
3144int mbedtls_mpi_is_prime( const mbedtls_mpi *X,
3145 int (*f_rng)(void *, unsigned char *, size_t),
3146 void *p_rng )
3147{
3148 MPI_VALIDATE_RET( X != NULL );
3149 MPI_VALIDATE_RET( f_rng != NULL );
3150
3151 /*
3152 * In the past our key generation aimed for an error rate of at most
3153 * 2^-80. Since this function is deprecated, aim for the same certainty
3154 * here as well.
3155 */
3156 return( mbedtls_mpi_is_prime_ext( X, 40, f_rng, p_rng ) );
3157}
3158#endif
3159
Jens Wiklander817466c2018-05-22 13:49:31 +02003160/*
3161 * Prime number generation
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003162 *
3163 * To generate an RSA key in a way recommended by FIPS 186-4, both primes must
3164 * be either 1024 bits or 1536 bits long, and flags must contain
3165 * MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR.
Jens Wiklander817466c2018-05-22 13:49:31 +02003166 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003167int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int flags,
Jens Wiklander817466c2018-05-22 13:49:31 +02003168 int (*f_rng)(void *, unsigned char *, size_t),
3169 void *p_rng )
3170{
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003171#ifdef MBEDTLS_HAVE_INT64
3172// ceil(2^63.5)
3173#define CEIL_MAXUINT_DIV_SQRT2 0xb504f333f9de6485ULL
3174#else
3175// ceil(2^31.5)
3176#define CEIL_MAXUINT_DIV_SQRT2 0xb504f334U
3177#endif
3178 int ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
Jens Wiklander817466c2018-05-22 13:49:31 +02003179 size_t k, n;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003180 int rounds;
Jens Wiklander817466c2018-05-22 13:49:31 +02003181 mbedtls_mpi_uint r;
3182 mbedtls_mpi Y;
3183
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003184 MPI_VALIDATE_RET( X != NULL );
3185 MPI_VALIDATE_RET( f_rng != NULL );
3186
Jens Wiklander817466c2018-05-22 13:49:31 +02003187 if( nbits < 3 || nbits > MBEDTLS_MPI_MAX_BITS )
3188 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
3189
Jens Wiklander98bd5fe2018-11-08 11:18:22 +01003190 mbedtls_mpi_init_mempool( &Y );
Jens Wiklander817466c2018-05-22 13:49:31 +02003191
3192 n = BITS_TO_LIMBS( nbits );
3193
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003194 if( ( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR ) == 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +02003195 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003196 /*
3197 * 2^-80 error probability, number of rounds chosen per HAC, table 4.4
3198 */
3199 rounds = ( ( nbits >= 1300 ) ? 2 : ( nbits >= 850 ) ? 3 :
3200 ( nbits >= 650 ) ? 4 : ( nbits >= 350 ) ? 8 :
3201 ( nbits >= 250 ) ? 12 : ( nbits >= 150 ) ? 18 : 27 );
Jens Wiklander817466c2018-05-22 13:49:31 +02003202 }
3203 else
3204 {
3205 /*
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003206 * 2^-100 error probability, number of rounds computed based on HAC,
3207 * fact 4.48
Jens Wiklander817466c2018-05-22 13:49:31 +02003208 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003209 rounds = ( ( nbits >= 1450 ) ? 4 : ( nbits >= 1150 ) ? 5 :
3210 ( nbits >= 1000 ) ? 6 : ( nbits >= 850 ) ? 7 :
3211 ( nbits >= 750 ) ? 8 : ( nbits >= 500 ) ? 13 :
3212 ( nbits >= 250 ) ? 28 : ( nbits >= 150 ) ? 40 : 51 );
3213 }
Jens Wiklander817466c2018-05-22 13:49:31 +02003214
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003215 while( 1 )
3216 {
3217 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
3218 /* make sure generated number is at least (nbits-1)+0.5 bits (FIPS 186-4 §B.3.3 steps 4.4, 5.5) */
3219 if( X->p[n-1] < CEIL_MAXUINT_DIV_SQRT2 ) continue;
Jens Wiklander817466c2018-05-22 13:49:31 +02003220
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003221 k = n * biL;
3222 if( k > nbits ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, k - nbits ) );
3223 X->p[0] |= 1;
Jens Wiklander817466c2018-05-22 13:49:31 +02003224
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003225 if( ( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH ) == 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +02003226 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003227 ret = mbedtls_mpi_is_prime_ext( X, rounds, f_rng, p_rng );
Jens Wiklander817466c2018-05-22 13:49:31 +02003228
3229 if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
3230 goto cleanup;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003231 }
3232 else
3233 {
Jens Wiklander817466c2018-05-22 13:49:31 +02003234 /*
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003235 * An necessary condition for Y and X = 2Y + 1 to be prime
3236 * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
3237 * Make sure it is satisfied, while keeping X = 3 mod 4
Jens Wiklander817466c2018-05-22 13:49:31 +02003238 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003239
3240 X->p[0] |= 2;
3241
3242 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, 3 ) );
3243 if( r == 0 )
3244 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 8 ) );
3245 else if( r == 1 )
3246 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 4 ) );
3247
3248 /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
3249 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, X ) );
3250 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, 1 ) );
3251
3252 while( 1 )
3253 {
3254 /*
3255 * First, check small factors for X and Y
3256 * before doing Miller-Rabin on any of them
3257 */
3258 if( ( ret = mpi_check_small_factors( X ) ) == 0 &&
3259 ( ret = mpi_check_small_factors( &Y ) ) == 0 &&
3260 ( ret = mpi_miller_rabin( X, rounds, f_rng, p_rng ) )
3261 == 0 &&
3262 ( ret = mpi_miller_rabin( &Y, rounds, f_rng, p_rng ) )
3263 == 0 )
3264 goto cleanup;
3265
3266 if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
3267 goto cleanup;
3268
3269 /*
3270 * Next candidates. We want to preserve Y = (X-1) / 2 and
3271 * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
3272 * so up Y by 6 and X by 12.
3273 */
3274 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 12 ) );
3275 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &Y, &Y, 6 ) );
3276 }
Jens Wiklander817466c2018-05-22 13:49:31 +02003277 }
3278 }
3279
3280cleanup:
3281
3282 mbedtls_mpi_free( &Y );
3283
3284 return( ret );
3285}
3286
3287#endif /* MBEDTLS_GENPRIME */
3288
3289#if defined(MBEDTLS_SELF_TEST)
3290
3291#define GCD_PAIR_COUNT 3
3292
3293static const int gcd_pairs[GCD_PAIR_COUNT][3] =
3294{
3295 { 693, 609, 21 },
3296 { 1764, 868, 28 },
3297 { 768454923, 542167814, 1 }
3298};
3299
3300/*
3301 * Checkup routine
3302 */
3303int mbedtls_mpi_self_test( int verbose )
3304{
3305 int ret, i;
3306 mbedtls_mpi A, E, N, X, Y, U, V;
3307
Jens Wiklander98bd5fe2018-11-08 11:18:22 +01003308 mbedtls_mpi_init_mempool( &A ); mbedtls_mpi_init_mempool( &E );
3309 mbedtls_mpi_init_mempool( &N ); mbedtls_mpi_init_mempool( &X );
3310 mbedtls_mpi_init_mempool( &Y ); mbedtls_mpi_init_mempool( &U );
3311 mbedtls_mpi_init_mempool( &V );
Jens Wiklander817466c2018-05-22 13:49:31 +02003312
3313 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &A, 16,
3314 "EFE021C2645FD1DC586E69184AF4A31E" \
3315 "D5F53E93B5F123FA41680867BA110131" \
3316 "944FE7952E2517337780CB0DB80E61AA" \
3317 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
3318
3319 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &E, 16,
3320 "B2E7EFD37075B9F03FF989C7C5051C20" \
3321 "34D2A323810251127E7BF8625A4F49A5" \
3322 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
3323 "5B5C25763222FEFCCFC38B832366C29E" ) );
3324
3325 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &N, 16,
3326 "0066A198186C18C10B2F5ED9B522752A" \
3327 "9830B69916E535C8F047518A889A43A5" \
3328 "94B6BED27A168D31D4A52F88925AA8F5" ) );
3329
3330 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &X, &A, &N ) );
3331
3332 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
3333 "602AB7ECA597A3D6B56FF9829A5E8B85" \
3334 "9E857EA95A03512E2BAE7391688D264A" \
3335 "A5663B0341DB9CCFD2C4C5F421FEC814" \
3336 "8001B72E848A38CAE1C65F78E56ABDEF" \
3337 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
3338 "ECF677152EF804370C1A305CAF3B5BF1" \
3339 "30879B56C61DE584A0F53A2447A51E" ) );
3340
3341 if( verbose != 0 )
3342 mbedtls_printf( " MPI test #1 (mul_mpi): " );
3343
3344 if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 )
3345 {
3346 if( verbose != 0 )
3347 mbedtls_printf( "failed\n" );
3348
3349 ret = 1;
3350 goto cleanup;
3351 }
3352
3353 if( verbose != 0 )
3354 mbedtls_printf( "passed\n" );
3355
3356 MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &X, &Y, &A, &N ) );
3357
3358 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
3359 "256567336059E52CAE22925474705F39A94" ) );
3360
3361 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &V, 16,
3362 "6613F26162223DF488E9CD48CC132C7A" \
3363 "0AC93C701B001B092E4E5B9F73BCD27B" \
3364 "9EE50D0657C77F374E903CDFA4C642" ) );
3365
3366 if( verbose != 0 )
3367 mbedtls_printf( " MPI test #2 (div_mpi): " );
3368
3369 if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 ||
3370 mbedtls_mpi_cmp_mpi( &Y, &V ) != 0 )
3371 {
3372 if( verbose != 0 )
3373 mbedtls_printf( "failed\n" );
3374
3375 ret = 1;
3376 goto cleanup;
3377 }
3378
3379 if( verbose != 0 )
3380 mbedtls_printf( "passed\n" );
3381
3382 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &X, &A, &E, &N, NULL ) );
3383
3384 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
3385 "36E139AEA55215609D2816998ED020BB" \
3386 "BD96C37890F65171D948E9BC7CBAA4D9" \
3387 "325D24D6A3C12710F10A09FA08AB87" ) );
3388
3389 if( verbose != 0 )
3390 mbedtls_printf( " MPI test #3 (exp_mod): " );
3391
3392 if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 )
3393 {
3394 if( verbose != 0 )
3395 mbedtls_printf( "failed\n" );
3396
3397 ret = 1;
3398 goto cleanup;
3399 }
3400
3401 if( verbose != 0 )
3402 mbedtls_printf( "passed\n" );
3403
3404 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &X, &A, &N ) );
3405
3406 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
3407 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
3408 "C3DBA76456363A10869622EAC2DD84EC" \
3409 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
3410
3411 if( verbose != 0 )
3412 mbedtls_printf( " MPI test #4 (inv_mod): " );
3413
3414 if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 )
3415 {
3416 if( verbose != 0 )
3417 mbedtls_printf( "failed\n" );
3418
3419 ret = 1;
3420 goto cleanup;
3421 }
3422
3423 if( verbose != 0 )
3424 mbedtls_printf( "passed\n" );
3425
3426 if( verbose != 0 )
3427 mbedtls_printf( " MPI test #5 (simple gcd): " );
3428
3429 for( i = 0; i < GCD_PAIR_COUNT; i++ )
3430 {
3431 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &X, gcd_pairs[i][0] ) );
3432 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Y, gcd_pairs[i][1] ) );
3433
3434 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &A, &X, &Y ) );
3435
3436 if( mbedtls_mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
3437 {
3438 if( verbose != 0 )
3439 mbedtls_printf( "failed at %d\n", i );
3440
3441 ret = 1;
3442 goto cleanup;
3443 }
3444 }
3445
3446 if( verbose != 0 )
3447 mbedtls_printf( "passed\n" );
3448
3449cleanup:
3450
3451 if( ret != 0 && verbose != 0 )
Jerome Forissier79013242021-07-28 10:24:04 +02003452 mbedtls_printf( "Unexpected error, return code = %08X\n", (unsigned int) ret );
Jens Wiklander817466c2018-05-22 13:49:31 +02003453
3454 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N ); mbedtls_mpi_free( &X );
3455 mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &U ); mbedtls_mpi_free( &V );
3456
3457 if( verbose != 0 )
3458 mbedtls_printf( "\n" );
3459
3460 return( ret );
3461}
3462
3463#endif /* MBEDTLS_SELF_TEST */
3464
3465#endif /* MBEDTLS_BIGNUM_C */