blob: b188eb6299dd03b9f53977d37976bf0c8788b85b [file] [log] [blame]
Jens Wiklander817466c2018-05-22 13:49:31 +02001/*
2 * Multi-precision integer library
3 *
Jerome Forissier3602df82021-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 Forissier3602df82021-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 Wiklanderb81d8962018-11-08 11:18:22 +010057#include <mempool.h>
58
Jens Wiklander3d3b0592019-03-20 15:30:29 +010059#define MPI_VALIDATE_RET( cond ) \
60 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_MPI_BAD_INPUT_DATA )
61#define MPI_VALIDATE( cond ) \
62 MBEDTLS_INTERNAL_VALIDATE( cond )
Jens Wiklander817466c2018-05-22 13:49:31 +020063
64#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */
65#define biL (ciL << 3) /* bits in limb */
66#define biH (ciL << 2) /* half limb size */
67
68#define MPI_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
69
70/*
71 * Convert between bits/chars and number of limbs
72 * Divide first in order to avoid potential overflows
73 */
74#define BITS_TO_LIMBS(i) ( (i) / biL + ( (i) % biL != 0 ) )
75#define CHARS_TO_LIMBS(i) ( (i) / ciL + ( (i) % ciL != 0 ) )
76
Jens Wiklanderb81d8962018-11-08 11:18:22 +010077void *mbedtls_mpi_mempool;
78
Jens Wiklander3d3b0592019-03-20 15:30:29 +010079/* Implementation that should never be optimized out by the compiler */
80static void mbedtls_mpi_zeroize( mbedtls_mpi_uint *v, size_t n )
81{
82 mbedtls_platform_zeroize( v, ciL * n );
83}
84
Jens Wiklander817466c2018-05-22 13:49:31 +020085/*
86 * Initialize one MPI
87 */
Jens Wiklanderb81d8962018-11-08 11:18:22 +010088static void mpi_init( mbedtls_mpi *X, short use_mempool )
Jens Wiklander817466c2018-05-22 13:49:31 +020089{
Jens Wiklander3d3b0592019-03-20 15:30:29 +010090 MPI_VALIDATE( X != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +020091
Jens Wiklander3d3b0592019-03-20 15:30:29 +010092 X->s = 1;
Jens Wiklanderb81d8962018-11-08 11:18:22 +010093 X->use_mempool = use_mempool;
Jens Wiklander3d3b0592019-03-20 15:30:29 +010094 X->n = 0;
95 X->p = NULL;
Jens Wiklander817466c2018-05-22 13:49:31 +020096}
97
Jens Wiklanderb81d8962018-11-08 11:18:22 +010098void mbedtls_mpi_init( mbedtls_mpi *X )
99{
100 mpi_init( X, 0 /*use_mempool*/ );
101}
102
103void mbedtls_mpi_init_mempool( mbedtls_mpi *X )
104{
105 mpi_init( X, !!mbedtls_mpi_mempool /*use_mempool*/ );
106}
107
Jens Wiklander817466c2018-05-22 13:49:31 +0200108/*
109 * Unallocate one MPI
110 */
111void mbedtls_mpi_free( mbedtls_mpi *X )
112{
113 if( X == NULL )
114 return;
115
116 if( X->p != NULL )
117 {
118 mbedtls_mpi_zeroize( X->p, X->n );
Jens Wiklanderb81d8962018-11-08 11:18:22 +0100119 if( X->use_mempool )
120 mempool_free( mbedtls_mpi_mempool, X->p );
121 else
122 mbedtls_free( X->p );
Jens Wiklander817466c2018-05-22 13:49:31 +0200123 }
124
125 X->s = 1;
126 X->n = 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100127 X->p = NULL;
Jens Wiklander817466c2018-05-22 13:49:31 +0200128}
129
130/*
131 * Enlarge to the specified number of limbs
132 */
133int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs )
134{
135 mbedtls_mpi_uint *p;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100136 MPI_VALIDATE_RET( X != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200137
138 if( nblimbs > MBEDTLS_MPI_MAX_LIMBS )
139 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
140
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100141 if( X->n < nblimbs )
142 {
Jens Wiklanderb81d8962018-11-08 11:18:22 +0100143 if( X->use_mempool )
144 {
145 p = mempool_alloc( mbedtls_mpi_mempool, nblimbs * ciL );
146 if( p == NULL )
147 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
148 memset( p, 0, nblimbs * ciL );
149 }
150 else
151 {
152 p = (mbedtls_mpi_uint*)mbedtls_calloc( nblimbs, ciL );
153 if( p == NULL )
154 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
155 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200156
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100157 if( X->p != NULL )
158 {
159 memcpy( p, X->p, X->n * ciL );
160 mbedtls_mpi_zeroize( X->p, X->n );
Jens Wiklanderb81d8962018-11-08 11:18:22 +0100161 if( X->use_mempool )
162 mempool_free( mbedtls_mpi_mempool, X->p);
163 else
164 mbedtls_free( X->p );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100165 }
166
167 X->n = nblimbs;
168 X->p = p;
Jens Wiklander817466c2018-05-22 13:49:31 +0200169 }
170
171 return( 0 );
172}
173
174/*
175 * Resize down as much as possible,
176 * while keeping at least the specified number of limbs
177 */
178int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs )
179{
180 mbedtls_mpi_uint *p;
181 size_t i;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100182 MPI_VALIDATE_RET( X != NULL );
183
184 if( nblimbs > MBEDTLS_MPI_MAX_LIMBS )
185 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
Jens Wiklander817466c2018-05-22 13:49:31 +0200186
Jerome Forissier5b25c762020-04-07 11:18:49 +0200187 /* Actually resize up if there are currently fewer than nblimbs limbs. */
Jens Wiklander817466c2018-05-22 13:49:31 +0200188 if( X->n <= nblimbs )
189 return( mbedtls_mpi_grow( X, nblimbs ) );
Jerome Forissier5b25c762020-04-07 11:18:49 +0200190 /* After this point, then X->n > nblimbs and in particular X->n > 0. */
Jens Wiklander817466c2018-05-22 13:49:31 +0200191
192 for( i = X->n - 1; i > 0; i-- )
193 if( X->p[i] != 0 )
194 break;
195 i++;
196
197 if( i < nblimbs )
198 i = nblimbs;
199
Jens Wiklanderb81d8962018-11-08 11:18:22 +0100200 if( X->use_mempool )
201 {
202 p = mempool_alloc( mbedtls_mpi_mempool, i * ciL );
203 if( p == NULL )
204 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
205 memset( p, 0, i * ciL );
206 }
207 else
208 {
209 p = (mbedtls_mpi_uint*)mbedtls_calloc( i, ciL );
210 if( p == NULL )
211 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
212 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200213
214 if( X->p != NULL )
215 {
216 memcpy( p, X->p, i * ciL );
217 mbedtls_mpi_zeroize( X->p, X->n );
Jens Wiklanderb81d8962018-11-08 11:18:22 +0100218 if( X->use_mempool )
219 mempool_free( mbedtls_mpi_mempool, X->p );
220 else
221 mbedtls_free( X->p );
Jens Wiklander817466c2018-05-22 13:49:31 +0200222 }
223
Jens Wiklander18c51482018-11-12 13:53:08 +0100224 X->n = i;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100225 X->p = p;
Jens Wiklander817466c2018-05-22 13:49:31 +0200226
227 return( 0 );
228}
229
Jerome Forissier3602df82021-07-28 10:24:04 +0200230/* Resize X to have exactly n limbs and set it to 0. */
231static int mbedtls_mpi_resize_clear( mbedtls_mpi *X, size_t limbs )
232{
233 if( limbs == 0 )
234 {
235 mbedtls_mpi_free( X );
236 return( 0 );
237 }
238 else if( X->n == limbs )
239 {
240 memset( X->p, 0, limbs * ciL );
241 X->s = 1;
242 return( 0 );
243 }
244 else
245 {
246 mbedtls_mpi_free( X );
247 return( mbedtls_mpi_grow( X, limbs ) );
248 }
249}
250
Jens Wiklander817466c2018-05-22 13:49:31 +0200251/*
Jerome Forissier3602df82021-07-28 10:24:04 +0200252 * Copy the contents of Y into X.
253 *
254 * This function is not constant-time. Leading zeros in Y may be removed.
255 *
256 * Ensure that X does not shrink. This is not guaranteed by the public API,
257 * but some code in the bignum module relies on this property, for example
258 * in mbedtls_mpi_exp_mod().
Jens Wiklander817466c2018-05-22 13:49:31 +0200259 */
260int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y )
261{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100262 int ret = 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200263 size_t i;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100264 MPI_VALIDATE_RET( X != NULL );
265 MPI_VALIDATE_RET( Y != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200266
267 if( X == Y )
268 return( 0 );
269
Jerome Forissier5b25c762020-04-07 11:18:49 +0200270 if( Y->n == 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200271 {
Jerome Forissier3602df82021-07-28 10:24:04 +0200272 if( X->n != 0 )
273 {
274 X->s = 1;
275 memset( X->p, 0, X->n * ciL );
276 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200277 return( 0 );
278 }
279
280 for( i = Y->n - 1; i > 0; i-- )
281 if( Y->p[i] != 0 )
282 break;
283 i++;
284
285 X->s = Y->s;
286
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100287 if( X->n < i )
288 {
289 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i ) );
290 }
291 else
292 {
293 memset( X->p + i, 0, ( X->n - i ) * ciL );
294 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200295
Jens Wiklander817466c2018-05-22 13:49:31 +0200296 memcpy( X->p, Y->p, i * ciL );
297
298cleanup:
299
300 return( ret );
301}
302
303/*
304 * Swap the contents of X and Y
305 */
306void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y )
307{
308 mbedtls_mpi T;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100309 MPI_VALIDATE( X != NULL );
310 MPI_VALIDATE( Y != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200311
312 memcpy( &T, X, sizeof( mbedtls_mpi ) );
313 memcpy( X, Y, sizeof( mbedtls_mpi ) );
314 memcpy( Y, &T, sizeof( mbedtls_mpi ) );
315}
316
Jerome Forissier3602df82021-07-28 10:24:04 +0200317/**
318 * Select between two sign values in constant-time.
319 *
320 * This is functionally equivalent to second ? a : b but uses only bit
321 * operations in order to avoid branches.
322 *
323 * \param[in] a The first sign; must be either +1 or -1.
324 * \param[in] b The second sign; must be either +1 or -1.
325 * \param[in] second Must be either 1 (return b) or 0 (return a).
326 *
327 * \return The selected sign value.
328 */
329static int mpi_safe_cond_select_sign( int a, int b, unsigned char second )
330{
331 /* In order to avoid questions about what we can reasonnably assume about
332 * the representations of signed integers, move everything to unsigned
333 * by taking advantage of the fact that a and b are either +1 or -1. */
334 unsigned ua = a + 1;
335 unsigned ub = b + 1;
336
337 /* second was 0 or 1, mask is 0 or 2 as are ua and ub */
338 const unsigned mask = second << 1;
339
340 /* select ua or ub */
341 unsigned ur = ( ua & ~mask ) | ( ub & mask );
342
343 /* ur is now 0 or 2, convert back to -1 or +1 */
344 return( (int) ur - 1 );
345}
346
347/*
348 * Conditionally assign dest = src, without leaking information
349 * about whether the assignment was made or not.
350 * dest and src must be arrays of limbs of size n.
351 * assign must be 0 or 1.
352 */
353static void mpi_safe_cond_assign( size_t n,
354 mbedtls_mpi_uint *dest,
355 const mbedtls_mpi_uint *src,
356 unsigned char assign )
357{
358 size_t i;
359
360 /* MSVC has a warning about unary minus on unsigned integer types,
361 * but this is well-defined and precisely what we want to do here. */
362#if defined(_MSC_VER)
363#pragma warning( push )
364#pragma warning( disable : 4146 )
365#endif
366
367 /* all-bits 1 if assign is 1, all-bits 0 if assign is 0 */
368 const mbedtls_mpi_uint mask = -assign;
369
370#if defined(_MSC_VER)
371#pragma warning( pop )
372#endif
373
374 for( i = 0; i < n; i++ )
375 dest[i] = ( src[i] & mask ) | ( dest[i] & ~mask );
376}
377
Jens Wiklander817466c2018-05-22 13:49:31 +0200378/*
379 * Conditionally assign X = Y, without leaking information
380 * about whether the assignment was made or not.
381 * (Leaking information about the respective sizes of X and Y is ok however.)
382 */
383int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign )
384{
385 int ret = 0;
386 size_t i;
Jerome Forissier3602df82021-07-28 10:24:04 +0200387 mbedtls_mpi_uint limb_mask;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100388 MPI_VALIDATE_RET( X != NULL );
389 MPI_VALIDATE_RET( Y != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200390
Jerome Forissier3602df82021-07-28 10:24:04 +0200391 /* MSVC has a warning about unary minus on unsigned integer types,
392 * but this is well-defined and precisely what we want to do here. */
393#if defined(_MSC_VER)
394#pragma warning( push )
395#pragma warning( disable : 4146 )
396#endif
397
Jens Wiklander817466c2018-05-22 13:49:31 +0200398 /* make sure assign is 0 or 1 in a time-constant manner */
Jerome Forissier3602df82021-07-28 10:24:04 +0200399 assign = (assign | (unsigned char)-assign) >> (sizeof( assign ) * 8 - 1);
400 /* all-bits 1 if assign is 1, all-bits 0 if assign is 0 */
401 limb_mask = -assign;
402
403#if defined(_MSC_VER)
404#pragma warning( pop )
405#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200406
407 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
408
Jerome Forissier3602df82021-07-28 10:24:04 +0200409 X->s = mpi_safe_cond_select_sign( X->s, Y->s, assign );
Jens Wiklander817466c2018-05-22 13:49:31 +0200410
Jerome Forissier3602df82021-07-28 10:24:04 +0200411 mpi_safe_cond_assign( Y->n, X->p, Y->p, assign );
Jens Wiklander817466c2018-05-22 13:49:31 +0200412
Jerome Forissier3602df82021-07-28 10:24:04 +0200413 for( i = Y->n; i < X->n; i++ )
414 X->p[i] &= ~limb_mask;
Jens Wiklander817466c2018-05-22 13:49:31 +0200415
416cleanup:
417 return( ret );
418}
419
420/*
421 * Conditionally swap X and Y, without leaking information
422 * about whether the swap was made or not.
423 * Here it is not ok to simply swap the pointers, which whould lead to
424 * different memory access patterns when X and Y are used afterwards.
425 */
426int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char swap )
427{
428 int ret, s;
429 size_t i;
Jerome Forissier3602df82021-07-28 10:24:04 +0200430 mbedtls_mpi_uint limb_mask;
Jens Wiklander817466c2018-05-22 13:49:31 +0200431 mbedtls_mpi_uint tmp;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100432 MPI_VALIDATE_RET( X != NULL );
433 MPI_VALIDATE_RET( Y != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200434
435 if( X == Y )
436 return( 0 );
437
Jerome Forissier3602df82021-07-28 10:24:04 +0200438 /* MSVC has a warning about unary minus on unsigned integer types,
439 * but this is well-defined and precisely what we want to do here. */
440#if defined(_MSC_VER)
441#pragma warning( push )
442#pragma warning( disable : 4146 )
443#endif
444
Jens Wiklander817466c2018-05-22 13:49:31 +0200445 /* make sure swap is 0 or 1 in a time-constant manner */
Jerome Forissier3602df82021-07-28 10:24:04 +0200446 swap = (swap | (unsigned char)-swap) >> (sizeof( swap ) * 8 - 1);
447 /* all-bits 1 if swap is 1, all-bits 0 if swap is 0 */
448 limb_mask = -swap;
449
450#if defined(_MSC_VER)
451#pragma warning( pop )
452#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200453
454 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
455 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( Y, X->n ) );
456
457 s = X->s;
Jerome Forissier3602df82021-07-28 10:24:04 +0200458 X->s = mpi_safe_cond_select_sign( X->s, Y->s, swap );
459 Y->s = mpi_safe_cond_select_sign( Y->s, s, swap );
Jens Wiklander817466c2018-05-22 13:49:31 +0200460
461
462 for( i = 0; i < X->n; i++ )
463 {
464 tmp = X->p[i];
Jerome Forissier3602df82021-07-28 10:24:04 +0200465 X->p[i] = ( X->p[i] & ~limb_mask ) | ( Y->p[i] & limb_mask );
466 Y->p[i] = ( Y->p[i] & ~limb_mask ) | ( tmp & limb_mask );
Jens Wiklander817466c2018-05-22 13:49:31 +0200467 }
468
469cleanup:
470 return( ret );
471}
472
473/*
474 * Set value from integer
475 */
476int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z )
477{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200478 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100479 MPI_VALIDATE_RET( X != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200480
481 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, 1 ) );
482 memset( X->p, 0, X->n * ciL );
483
484 X->p[0] = ( z < 0 ) ? -z : z;
485 X->s = ( z < 0 ) ? -1 : 1;
486
487cleanup:
488
489 return( ret );
490}
491
492/*
493 * Get a specific bit
494 */
495int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos )
496{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100497 MPI_VALIDATE_RET( X != NULL );
498
Jens Wiklander817466c2018-05-22 13:49:31 +0200499 if( X->n * biL <= pos )
500 return( 0 );
501
502 return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 );
503}
504
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100505/* Get a specific byte, without range checks. */
506#define GET_BYTE( X, i ) \
507 ( ( ( X )->p[( i ) / ciL] >> ( ( ( i ) % ciL ) * 8 ) ) & 0xff )
508
Jens Wiklander817466c2018-05-22 13:49:31 +0200509/*
510 * Set a bit to a specific value of 0 or 1
511 */
512int mbedtls_mpi_set_bit( mbedtls_mpi *X, size_t pos, unsigned char val )
513{
514 int ret = 0;
515 size_t off = pos / biL;
516 size_t idx = pos % biL;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100517 MPI_VALIDATE_RET( X != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200518
519 if( val != 0 && val != 1 )
520 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
521
522 if( X->n * biL <= pos )
523 {
524 if( val == 0 )
525 return( 0 );
526
527 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, off + 1 ) );
528 }
529
530 X->p[off] &= ~( (mbedtls_mpi_uint) 0x01 << idx );
531 X->p[off] |= (mbedtls_mpi_uint) val << idx;
532
533cleanup:
534
535 return( ret );
536}
537
538/*
539 * Return the number of less significant zero-bits
540 */
541size_t mbedtls_mpi_lsb( const mbedtls_mpi *X )
542{
543 size_t i, j, count = 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100544 MBEDTLS_INTERNAL_VALIDATE_RET( X != NULL, 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200545
546 for( i = 0; i < X->n; i++ )
547 for( j = 0; j < biL; j++, count++ )
548 if( ( ( X->p[i] >> j ) & 1 ) != 0 )
549 return( count );
550
551 return( 0 );
552}
553
554/*
555 * Count leading zero bits in a given integer
556 */
557static size_t mbedtls_clz( const mbedtls_mpi_uint x )
558{
559 size_t j;
560 mbedtls_mpi_uint mask = (mbedtls_mpi_uint) 1 << (biL - 1);
561
562 for( j = 0; j < biL; j++ )
563 {
564 if( x & mask ) break;
565
566 mask >>= 1;
567 }
568
569 return j;
570}
571
572/*
573 * Return the number of bits
574 */
575size_t mbedtls_mpi_bitlen( const mbedtls_mpi *X )
576{
577 size_t i, j;
578
579 if( X->n == 0 )
580 return( 0 );
581
582 for( i = X->n - 1; i > 0; i-- )
583 if( X->p[i] != 0 )
584 break;
585
586 j = biL - mbedtls_clz( X->p[i] );
587
588 return( ( i * biL ) + j );
589}
590
591/*
592 * Return the total size in bytes
593 */
594size_t mbedtls_mpi_size( const mbedtls_mpi *X )
595{
596 return( ( mbedtls_mpi_bitlen( X ) + 7 ) >> 3 );
597}
598
599/*
600 * Convert an ASCII character to digit value
601 */
602static int mpi_get_digit( mbedtls_mpi_uint *d, int radix, char c )
603{
604 *d = 255;
605
606 if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30;
607 if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37;
608 if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57;
609
610 if( *d >= (mbedtls_mpi_uint) radix )
611 return( MBEDTLS_ERR_MPI_INVALID_CHARACTER );
612
613 return( 0 );
614}
615
616/*
617 * Import from an ASCII string
618 */
619int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s )
620{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200621 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200622 size_t i, j, slen, n;
Jerome Forissier3602df82021-07-28 10:24:04 +0200623 int sign = 1;
Jens Wiklander817466c2018-05-22 13:49:31 +0200624 mbedtls_mpi_uint d;
625 mbedtls_mpi T;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100626 MPI_VALIDATE_RET( X != NULL );
627 MPI_VALIDATE_RET( s != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200628
629 if( radix < 2 || radix > 16 )
630 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
631
Jens Wiklanderb81d8962018-11-08 11:18:22 +0100632 mbedtls_mpi_init_mempool( &T );
Jerome Forissier3602df82021-07-28 10:24:04 +0200633
634 if( s[0] == 0 )
635 {
636 mbedtls_mpi_free( X );
637 return( 0 );
638 }
639
640 if( s[0] == '-' )
641 {
642 ++s;
643 sign = -1;
644 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200645
646 slen = strlen( s );
647
648 if( radix == 16 )
649 {
650 if( slen > MPI_SIZE_T_MAX >> 2 )
651 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
652
653 n = BITS_TO_LIMBS( slen << 2 );
654
655 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, n ) );
656 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
657
658 for( i = slen, j = 0; i > 0; i--, j++ )
659 {
Jens Wiklander817466c2018-05-22 13:49:31 +0200660 MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) );
661 X->p[j / ( 2 * ciL )] |= d << ( ( j % ( 2 * ciL ) ) << 2 );
662 }
663 }
664 else
665 {
666 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
667
668 for( i = 0; i < slen; i++ )
669 {
Jens Wiklander817466c2018-05-22 13:49:31 +0200670 MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
671 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T, X, radix ) );
Jerome Forissier3602df82021-07-28 10:24:04 +0200672 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, &T, d ) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200673 }
674 }
675
Jerome Forissier3602df82021-07-28 10:24:04 +0200676 if( sign < 0 && mbedtls_mpi_bitlen( X ) != 0 )
677 X->s = -1;
678
Jens Wiklander817466c2018-05-22 13:49:31 +0200679cleanup:
680
681 mbedtls_mpi_free( &T );
682
683 return( ret );
684}
685
686/*
Jerome Forissier5b25c762020-04-07 11:18:49 +0200687 * Helper to write the digits high-order first.
Jens Wiklander817466c2018-05-22 13:49:31 +0200688 */
Jerome Forissier5b25c762020-04-07 11:18:49 +0200689static int mpi_write_hlp( mbedtls_mpi *X, int radix,
690 char **p, const size_t buflen )
Jens Wiklander817466c2018-05-22 13:49:31 +0200691{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200692 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200693 mbedtls_mpi_uint r;
Jerome Forissier5b25c762020-04-07 11:18:49 +0200694 size_t length = 0;
695 char *p_end = *p + buflen;
Jens Wiklander817466c2018-05-22 13:49:31 +0200696
Jerome Forissier5b25c762020-04-07 11:18:49 +0200697 do
698 {
699 if( length >= buflen )
700 {
701 return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
702 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200703
Jerome Forissier5b25c762020-04-07 11:18:49 +0200704 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, radix ) );
705 MBEDTLS_MPI_CHK( mbedtls_mpi_div_int( X, NULL, X, radix ) );
706 /*
707 * Write the residue in the current position, as an ASCII character.
708 */
709 if( r < 0xA )
710 *(--p_end) = (char)( '0' + r );
711 else
712 *(--p_end) = (char)( 'A' + ( r - 0xA ) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200713
Jerome Forissier5b25c762020-04-07 11:18:49 +0200714 length++;
715 } while( mbedtls_mpi_cmp_int( X, 0 ) != 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200716
Jerome Forissier5b25c762020-04-07 11:18:49 +0200717 memmove( *p, p_end, length );
718 *p += length;
Jens Wiklander817466c2018-05-22 13:49:31 +0200719
720cleanup:
721
722 return( ret );
723}
724
725/*
726 * Export into an ASCII string
727 */
728int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix,
729 char *buf, size_t buflen, size_t *olen )
730{
731 int ret = 0;
732 size_t n;
733 char *p;
734 mbedtls_mpi T;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100735 MPI_VALIDATE_RET( X != NULL );
736 MPI_VALIDATE_RET( olen != NULL );
737 MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200738
739 if( radix < 2 || radix > 16 )
740 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
741
Jerome Forissier5b25c762020-04-07 11:18:49 +0200742 n = mbedtls_mpi_bitlen( X ); /* Number of bits necessary to present `n`. */
743 if( radix >= 4 ) n >>= 1; /* Number of 4-adic digits necessary to present
744 * `n`. If radix > 4, this might be a strict
745 * overapproximation of the number of
746 * radix-adic digits needed to present `n`. */
747 if( radix >= 16 ) n >>= 1; /* Number of hexadecimal digits necessary to
748 * present `n`. */
749
750 n += 1; /* Terminating null byte */
751 n += 1; /* Compensate for the divisions above, which round down `n`
752 * in case it's not even. */
753 n += 1; /* Potential '-'-sign. */
754 n += ( n & 1 ); /* Make n even to have enough space for hexadecimal writing,
755 * which always uses an even number of hex-digits. */
Jens Wiklander817466c2018-05-22 13:49:31 +0200756
757 if( buflen < n )
758 {
759 *olen = n;
760 return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
761 }
762
763 p = buf;
Jens Wiklanderb81d8962018-11-08 11:18:22 +0100764 mbedtls_mpi_init_mempool( &T );
Jens Wiklander817466c2018-05-22 13:49:31 +0200765
766 if( X->s == -1 )
Jerome Forissier5b25c762020-04-07 11:18:49 +0200767 {
Jens Wiklander817466c2018-05-22 13:49:31 +0200768 *p++ = '-';
Jerome Forissier5b25c762020-04-07 11:18:49 +0200769 buflen--;
770 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200771
772 if( radix == 16 )
773 {
774 int c;
775 size_t i, j, k;
776
777 for( i = X->n, k = 0; i > 0; i-- )
778 {
779 for( j = ciL; j > 0; j-- )
780 {
781 c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF;
782
783 if( c == 0 && k == 0 && ( i + j ) != 2 )
784 continue;
785
786 *(p++) = "0123456789ABCDEF" [c / 16];
787 *(p++) = "0123456789ABCDEF" [c % 16];
788 k = 1;
789 }
790 }
791 }
792 else
793 {
794 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T, X ) );
795
796 if( T.s == -1 )
797 T.s = 1;
798
Jerome Forissier5b25c762020-04-07 11:18:49 +0200799 MBEDTLS_MPI_CHK( mpi_write_hlp( &T, radix, &p, buflen ) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200800 }
801
802 *p++ = '\0';
803 *olen = p - buf;
804
805cleanup:
806
807 mbedtls_mpi_free( &T );
808
809 return( ret );
810}
811
812#if defined(MBEDTLS_FS_IO)
813/*
814 * Read X from an opened file
815 */
816int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin )
817{
818 mbedtls_mpi_uint d;
819 size_t slen;
820 char *p;
821 /*
822 * Buffer should have space for (short) label and decimal formatted MPI,
823 * newline characters and '\0'
824 */
825 char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ];
826
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100827 MPI_VALIDATE_RET( X != NULL );
828 MPI_VALIDATE_RET( fin != NULL );
829
830 if( radix < 2 || radix > 16 )
831 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
832
Jens Wiklander817466c2018-05-22 13:49:31 +0200833 memset( s, 0, sizeof( s ) );
834 if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
835 return( MBEDTLS_ERR_MPI_FILE_IO_ERROR );
836
837 slen = strlen( s );
838 if( slen == sizeof( s ) - 2 )
839 return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
840
841 if( slen > 0 && s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
842 if( slen > 0 && s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
843
844 p = s + slen;
845 while( p-- > s )
846 if( mpi_get_digit( &d, radix, *p ) != 0 )
847 break;
848
849 return( mbedtls_mpi_read_string( X, radix, p + 1 ) );
850}
851
852/*
853 * Write X into an opened file (or stdout if fout == NULL)
854 */
855int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X, int radix, FILE *fout )
856{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200857 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200858 size_t n, slen, plen;
859 /*
860 * Buffer should have space for (short) label and decimal formatted MPI,
861 * newline characters and '\0'
862 */
863 char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ];
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100864 MPI_VALIDATE_RET( X != NULL );
865
866 if( radix < 2 || radix > 16 )
867 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
Jens Wiklander817466c2018-05-22 13:49:31 +0200868
869 memset( s, 0, sizeof( s ) );
870
871 MBEDTLS_MPI_CHK( mbedtls_mpi_write_string( X, radix, s, sizeof( s ) - 2, &n ) );
872
873 if( p == NULL ) p = "";
874
875 plen = strlen( p );
876 slen = strlen( s );
877 s[slen++] = '\r';
878 s[slen++] = '\n';
879
880 if( fout != NULL )
881 {
882 if( fwrite( p, 1, plen, fout ) != plen ||
883 fwrite( s, 1, slen, fout ) != slen )
884 return( MBEDTLS_ERR_MPI_FILE_IO_ERROR );
885 }
886 else
887 mbedtls_printf( "%s%s", p, s );
888
889cleanup:
890
891 return( ret );
892}
893#endif /* MBEDTLS_FS_IO */
894
Jerome Forissier5b25c762020-04-07 11:18:49 +0200895
896/* Convert a big-endian byte array aligned to the size of mbedtls_mpi_uint
897 * into the storage form used by mbedtls_mpi. */
898
899static mbedtls_mpi_uint mpi_uint_bigendian_to_host_c( mbedtls_mpi_uint x )
900{
901 uint8_t i;
902 unsigned char *x_ptr;
903 mbedtls_mpi_uint tmp = 0;
904
905 for( i = 0, x_ptr = (unsigned char*) &x; i < ciL; i++, x_ptr++ )
906 {
907 tmp <<= CHAR_BIT;
908 tmp |= (mbedtls_mpi_uint) *x_ptr;
909 }
910
911 return( tmp );
912}
913
914static mbedtls_mpi_uint mpi_uint_bigendian_to_host( mbedtls_mpi_uint x )
915{
916#if defined(__BYTE_ORDER__)
917
918/* Nothing to do on bigendian systems. */
919#if ( __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ )
920 return( x );
921#endif /* __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ */
922
923#if ( __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ )
924
925/* For GCC and Clang, have builtins for byte swapping. */
926#if defined(__GNUC__) && defined(__GNUC_PREREQ)
927#if __GNUC_PREREQ(4,3)
928#define have_bswap
929#endif
930#endif
931
932#if defined(__clang__) && defined(__has_builtin)
933#if __has_builtin(__builtin_bswap32) && \
934 __has_builtin(__builtin_bswap64)
935#define have_bswap
936#endif
937#endif
938
939#if defined(have_bswap)
940 /* The compiler is hopefully able to statically evaluate this! */
941 switch( sizeof(mbedtls_mpi_uint) )
942 {
943 case 4:
944 return( __builtin_bswap32(x) );
945 case 8:
946 return( __builtin_bswap64(x) );
947 }
948#endif
949#endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */
950#endif /* __BYTE_ORDER__ */
951
952 /* Fall back to C-based reordering if we don't know the byte order
953 * or we couldn't use a compiler-specific builtin. */
954 return( mpi_uint_bigendian_to_host_c( x ) );
955}
956
957static void mpi_bigendian_to_host( mbedtls_mpi_uint * const p, size_t limbs )
958{
959 mbedtls_mpi_uint *cur_limb_left;
960 mbedtls_mpi_uint *cur_limb_right;
961 if( limbs == 0 )
962 return;
963
964 /*
965 * Traverse limbs and
966 * - adapt byte-order in each limb
967 * - swap the limbs themselves.
968 * For that, simultaneously traverse the limbs from left to right
969 * and from right to left, as long as the left index is not bigger
970 * than the right index (it's not a problem if limbs is odd and the
971 * indices coincide in the last iteration).
972 */
973 for( cur_limb_left = p, cur_limb_right = p + ( limbs - 1 );
974 cur_limb_left <= cur_limb_right;
975 cur_limb_left++, cur_limb_right-- )
976 {
977 mbedtls_mpi_uint tmp;
978 /* Note that if cur_limb_left == cur_limb_right,
979 * this code effectively swaps the bytes only once. */
980 tmp = mpi_uint_bigendian_to_host( *cur_limb_left );
981 *cur_limb_left = mpi_uint_bigendian_to_host( *cur_limb_right );
982 *cur_limb_right = tmp;
983 }
984}
985
Jens Wiklander817466c2018-05-22 13:49:31 +0200986/*
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200987 * Import X from unsigned binary data, little endian
988 */
989int mbedtls_mpi_read_binary_le( mbedtls_mpi *X,
990 const unsigned char *buf, size_t buflen )
991{
992 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
993 size_t i;
994 size_t const limbs = CHARS_TO_LIMBS( buflen );
995
996 /* Ensure that target MPI has exactly the necessary number of limbs */
Jerome Forissier3602df82021-07-28 10:24:04 +0200997 MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, limbs ) );
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200998
999 for( i = 0; i < buflen; i++ )
1000 X->p[i / ciL] |= ((mbedtls_mpi_uint) buf[i]) << ((i % ciL) << 3);
1001
1002cleanup:
1003
1004 /*
1005 * This function is also used to import keys. However, wiping the buffers
1006 * upon failure is not necessary because failure only can happen before any
1007 * input is copied.
1008 */
1009 return( ret );
1010}
1011
1012/*
Jens Wiklander817466c2018-05-22 13:49:31 +02001013 * Import X from unsigned binary data, big endian
1014 */
1015int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen )
1016{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001017 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jerome Forissier5b25c762020-04-07 11:18:49 +02001018 size_t const limbs = CHARS_TO_LIMBS( buflen );
1019 size_t const overhead = ( limbs * ciL ) - buflen;
1020 unsigned char *Xp;
Jens Wiklander817466c2018-05-22 13:49:31 +02001021
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001022 MPI_VALIDATE_RET( X != NULL );
1023 MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001024
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001025 /* Ensure that target MPI has exactly the necessary number of limbs */
Jerome Forissier3602df82021-07-28 10:24:04 +02001026 MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, limbs ) );
Jens Wiklander29762732019-04-17 12:28:43 +02001027
Jerome Forissier3602df82021-07-28 10:24:04 +02001028 /* Avoid calling `memcpy` with NULL source or destination argument,
Jerome Forissier5b25c762020-04-07 11:18:49 +02001029 * even if buflen is 0. */
Jerome Forissier3602df82021-07-28 10:24:04 +02001030 if( buflen != 0 )
Jerome Forissier5b25c762020-04-07 11:18:49 +02001031 {
1032 Xp = (unsigned char*) X->p;
1033 memcpy( Xp + overhead, buf, buflen );
1034
1035 mpi_bigendian_to_host( X->p, limbs );
1036 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001037
1038cleanup:
1039
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001040 /*
1041 * This function is also used to import keys. However, wiping the buffers
1042 * upon failure is not necessary because failure only can happen before any
1043 * input is copied.
1044 */
Jens Wiklander817466c2018-05-22 13:49:31 +02001045 return( ret );
1046}
1047
1048/*
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001049 * Export X into unsigned binary data, little endian
1050 */
1051int mbedtls_mpi_write_binary_le( const mbedtls_mpi *X,
1052 unsigned char *buf, size_t buflen )
1053{
1054 size_t stored_bytes = X->n * ciL;
1055 size_t bytes_to_copy;
1056 size_t i;
1057
1058 if( stored_bytes < buflen )
1059 {
1060 bytes_to_copy = stored_bytes;
1061 }
1062 else
1063 {
1064 bytes_to_copy = buflen;
1065
1066 /* The output buffer is smaller than the allocated size of X.
1067 * However X may fit if its leading bytes are zero. */
1068 for( i = bytes_to_copy; i < stored_bytes; i++ )
1069 {
1070 if( GET_BYTE( X, i ) != 0 )
1071 return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
1072 }
1073 }
1074
1075 for( i = 0; i < bytes_to_copy; i++ )
1076 buf[i] = GET_BYTE( X, i );
1077
1078 if( stored_bytes < buflen )
1079 {
1080 /* Write trailing 0 bytes */
1081 memset( buf + stored_bytes, 0, buflen - stored_bytes );
1082 }
1083
1084 return( 0 );
1085}
1086
1087/*
Jens Wiklander817466c2018-05-22 13:49:31 +02001088 * Export X into unsigned binary data, big endian
1089 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001090int mbedtls_mpi_write_binary( const mbedtls_mpi *X,
1091 unsigned char *buf, size_t buflen )
Jens Wiklander817466c2018-05-22 13:49:31 +02001092{
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001093 size_t stored_bytes;
1094 size_t bytes_to_copy;
1095 unsigned char *p;
1096 size_t i;
Jens Wiklander817466c2018-05-22 13:49:31 +02001097
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001098 MPI_VALIDATE_RET( X != NULL );
1099 MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001100
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001101 stored_bytes = X->n * ciL;
Jens Wiklander817466c2018-05-22 13:49:31 +02001102
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001103 if( stored_bytes < buflen )
1104 {
1105 /* There is enough space in the output buffer. Write initial
1106 * null bytes and record the position at which to start
1107 * writing the significant bytes. In this case, the execution
1108 * trace of this function does not depend on the value of the
1109 * number. */
1110 bytes_to_copy = stored_bytes;
1111 p = buf + buflen - stored_bytes;
1112 memset( buf, 0, buflen - stored_bytes );
1113 }
1114 else
1115 {
1116 /* The output buffer is smaller than the allocated size of X.
1117 * However X may fit if its leading bytes are zero. */
1118 bytes_to_copy = buflen;
1119 p = buf;
1120 for( i = bytes_to_copy; i < stored_bytes; i++ )
1121 {
1122 if( GET_BYTE( X, i ) != 0 )
1123 return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
1124 }
1125 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001126
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001127 for( i = 0; i < bytes_to_copy; i++ )
1128 p[bytes_to_copy - i - 1] = GET_BYTE( X, i );
Jens Wiklander817466c2018-05-22 13:49:31 +02001129
1130 return( 0 );
1131}
1132
1133/*
1134 * Left-shift: X <<= count
1135 */
1136int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count )
1137{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001138 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02001139 size_t i, v0, t1;
1140 mbedtls_mpi_uint r0 = 0, r1;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001141 MPI_VALIDATE_RET( X != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001142
1143 v0 = count / (biL );
1144 t1 = count & (biL - 1);
1145
1146 i = mbedtls_mpi_bitlen( X ) + count;
1147
1148 if( X->n * biL < i )
1149 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, BITS_TO_LIMBS( i ) ) );
1150
1151 ret = 0;
1152
1153 /*
1154 * shift by count / limb_size
1155 */
1156 if( v0 > 0 )
1157 {
1158 for( i = X->n; i > v0; i-- )
1159 X->p[i - 1] = X->p[i - v0 - 1];
1160
1161 for( ; i > 0; i-- )
1162 X->p[i - 1] = 0;
1163 }
1164
1165 /*
1166 * shift by count % limb_size
1167 */
1168 if( t1 > 0 )
1169 {
1170 for( i = v0; i < X->n; i++ )
1171 {
1172 r1 = X->p[i] >> (biL - t1);
1173 X->p[i] <<= t1;
1174 X->p[i] |= r0;
1175 r0 = r1;
1176 }
1177 }
1178
1179cleanup:
1180
1181 return( ret );
1182}
1183
1184/*
1185 * Right-shift: X >>= count
1186 */
1187int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count )
1188{
1189 size_t i, v0, v1;
1190 mbedtls_mpi_uint r0 = 0, r1;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001191 MPI_VALIDATE_RET( X != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001192
1193 v0 = count / biL;
1194 v1 = count & (biL - 1);
1195
1196 if( v0 > X->n || ( v0 == X->n && v1 > 0 ) )
1197 return mbedtls_mpi_lset( X, 0 );
1198
1199 /*
1200 * shift by count / limb_size
1201 */
1202 if( v0 > 0 )
1203 {
1204 for( i = 0; i < X->n - v0; i++ )
1205 X->p[i] = X->p[i + v0];
1206
1207 for( ; i < X->n; i++ )
1208 X->p[i] = 0;
1209 }
1210
1211 /*
1212 * shift by count % limb_size
1213 */
1214 if( v1 > 0 )
1215 {
1216 for( i = X->n; i > 0; i-- )
1217 {
1218 r1 = X->p[i - 1] << (biL - v1);
1219 X->p[i - 1] >>= v1;
1220 X->p[i - 1] |= r0;
1221 r0 = r1;
1222 }
1223 }
1224
1225 return( 0 );
1226}
1227
1228/*
1229 * Compare unsigned values
1230 */
1231int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y )
1232{
1233 size_t i, j;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001234 MPI_VALIDATE_RET( X != NULL );
1235 MPI_VALIDATE_RET( Y != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001236
1237 for( i = X->n; i > 0; i-- )
1238 if( X->p[i - 1] != 0 )
1239 break;
1240
1241 for( j = Y->n; j > 0; j-- )
1242 if( Y->p[j - 1] != 0 )
1243 break;
1244
1245 if( i == 0 && j == 0 )
1246 return( 0 );
1247
1248 if( i > j ) return( 1 );
1249 if( j > i ) return( -1 );
1250
1251 for( ; i > 0; i-- )
1252 {
1253 if( X->p[i - 1] > Y->p[i - 1] ) return( 1 );
1254 if( X->p[i - 1] < Y->p[i - 1] ) return( -1 );
1255 }
1256
1257 return( 0 );
1258}
1259
1260/*
1261 * Compare signed values
1262 */
1263int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y )
1264{
1265 size_t i, j;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001266 MPI_VALIDATE_RET( X != NULL );
1267 MPI_VALIDATE_RET( Y != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001268
1269 for( i = X->n; i > 0; i-- )
1270 if( X->p[i - 1] != 0 )
1271 break;
1272
1273 for( j = Y->n; j > 0; j-- )
1274 if( Y->p[j - 1] != 0 )
1275 break;
1276
1277 if( i == 0 && j == 0 )
1278 return( 0 );
1279
1280 if( i > j ) return( X->s );
1281 if( j > i ) return( -Y->s );
1282
1283 if( X->s > 0 && Y->s < 0 ) return( 1 );
1284 if( Y->s > 0 && X->s < 0 ) return( -1 );
1285
1286 for( ; i > 0; i-- )
1287 {
1288 if( X->p[i - 1] > Y->p[i - 1] ) return( X->s );
1289 if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s );
1290 }
1291
1292 return( 0 );
1293}
1294
Jerome Forissier5b25c762020-04-07 11:18:49 +02001295/** Decide if an integer is less than the other, without branches.
1296 *
1297 * \param x First integer.
1298 * \param y Second integer.
1299 *
1300 * \return 1 if \p x is less than \p y, 0 otherwise
1301 */
1302static unsigned ct_lt_mpi_uint( const mbedtls_mpi_uint x,
1303 const mbedtls_mpi_uint y )
1304{
1305 mbedtls_mpi_uint ret;
1306 mbedtls_mpi_uint cond;
1307
1308 /*
1309 * Check if the most significant bits (MSB) of the operands are different.
1310 */
1311 cond = ( x ^ y );
1312 /*
1313 * If the MSB are the same then the difference x-y will be negative (and
1314 * have its MSB set to 1 during conversion to unsigned) if and only if x<y.
1315 */
1316 ret = ( x - y ) & ~cond;
1317 /*
1318 * If the MSB are different, then the operand with the MSB of 1 is the
1319 * bigger. (That is if y has MSB of 1, then x<y is true and it is false if
1320 * the MSB of y is 0.)
1321 */
1322 ret |= y & cond;
1323
1324
1325 ret = ret >> ( biL - 1 );
1326
1327 return (unsigned) ret;
1328}
1329
1330/*
1331 * Compare signed values in constant time
1332 */
1333int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X, const mbedtls_mpi *Y,
1334 unsigned *ret )
1335{
1336 size_t i;
1337 /* The value of any of these variables is either 0 or 1 at all times. */
1338 unsigned cond, done, X_is_negative, Y_is_negative;
1339
1340 MPI_VALIDATE_RET( X != NULL );
1341 MPI_VALIDATE_RET( Y != NULL );
1342 MPI_VALIDATE_RET( ret != NULL );
1343
1344 if( X->n != Y->n )
1345 return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
1346
1347 /*
1348 * Set sign_N to 1 if N >= 0, 0 if N < 0.
1349 * We know that N->s == 1 if N >= 0 and N->s == -1 if N < 0.
1350 */
1351 X_is_negative = ( X->s & 2 ) >> 1;
1352 Y_is_negative = ( Y->s & 2 ) >> 1;
1353
1354 /*
1355 * If the signs are different, then the positive operand is the bigger.
1356 * That is if X is negative (X_is_negative == 1), then X < Y is true and it
1357 * is false if X is positive (X_is_negative == 0).
1358 */
1359 cond = ( X_is_negative ^ Y_is_negative );
1360 *ret = cond & X_is_negative;
1361
1362 /*
1363 * This is a constant-time function. We might have the result, but we still
1364 * need to go through the loop. Record if we have the result already.
1365 */
1366 done = cond;
1367
1368 for( i = X->n; i > 0; i-- )
1369 {
1370 /*
1371 * If Y->p[i - 1] < X->p[i - 1] then X < Y is true if and only if both
1372 * X and Y are negative.
1373 *
1374 * Again even if we can make a decision, we just mark the result and
1375 * the fact that we are done and continue looping.
1376 */
1377 cond = ct_lt_mpi_uint( Y->p[i - 1], X->p[i - 1] );
1378 *ret |= cond & ( 1 - done ) & X_is_negative;
1379 done |= cond;
1380
1381 /*
1382 * If X->p[i - 1] < Y->p[i - 1] then X < Y is true if and only if both
1383 * X and Y are positive.
1384 *
1385 * Again even if we can make a decision, we just mark the result and
1386 * the fact that we are done and continue looping.
1387 */
1388 cond = ct_lt_mpi_uint( X->p[i - 1], Y->p[i - 1] );
1389 *ret |= cond & ( 1 - done ) & ( 1 - X_is_negative );
1390 done |= cond;
1391 }
1392
1393 return( 0 );
1394}
1395
Jens Wiklander817466c2018-05-22 13:49:31 +02001396/*
1397 * Compare signed values
1398 */
1399int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z )
1400{
1401 mbedtls_mpi Y;
1402 mbedtls_mpi_uint p[1];
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001403 MPI_VALIDATE_RET( X != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001404
1405 *p = ( z < 0 ) ? -z : z;
1406 Y.s = ( z < 0 ) ? -1 : 1;
1407 Y.n = 1;
1408 Y.p = p;
1409
1410 return( mbedtls_mpi_cmp_mpi( X, &Y ) );
1411}
1412
1413/*
1414 * Unsigned addition: X = |A| + |B| (HAC 14.7)
1415 */
1416int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
1417{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001418 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02001419 size_t i, j;
1420 mbedtls_mpi_uint *o, *p, c, tmp;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001421 MPI_VALIDATE_RET( X != NULL );
1422 MPI_VALIDATE_RET( A != NULL );
1423 MPI_VALIDATE_RET( B != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001424
1425 if( X == B )
1426 {
1427 const mbedtls_mpi *T = A; A = X; B = T;
1428 }
1429
1430 if( X != A )
1431 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) );
1432
1433 /*
1434 * X should always be positive as a result of unsigned additions.
1435 */
1436 X->s = 1;
1437
1438 for( j = B->n; j > 0; j-- )
1439 if( B->p[j - 1] != 0 )
1440 break;
1441
1442 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) );
1443
1444 o = B->p; p = X->p; c = 0;
1445
1446 /*
1447 * tmp is used because it might happen that p == o
1448 */
1449 for( i = 0; i < j; i++, o++, p++ )
1450 {
1451 tmp= *o;
1452 *p += c; c = ( *p < c );
1453 *p += tmp; c += ( *p < tmp );
1454 }
1455
1456 while( c != 0 )
1457 {
1458 if( i >= X->n )
1459 {
1460 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + 1 ) );
1461 p = X->p + i;
1462 }
1463
1464 *p += c; c = ( *p < c ); i++; p++;
1465 }
1466
1467cleanup:
1468
1469 return( ret );
1470}
1471
Jerome Forissier3602df82021-07-28 10:24:04 +02001472/**
1473 * Helper for mbedtls_mpi subtraction.
1474 *
1475 * Calculate l - r where l and r have the same size.
1476 * This function operates modulo (2^ciL)^n and returns the carry
1477 * (1 if there was a wraparound, i.e. if `l < r`, and 0 otherwise).
1478 *
1479 * d may be aliased to l or r.
1480 *
1481 * \param n Number of limbs of \p d, \p l and \p r.
1482 * \param[out] d The result of the subtraction.
1483 * \param[in] l The left operand.
1484 * \param[in] r The right operand.
1485 *
1486 * \return 1 if `l < r`.
1487 * 0 if `l >= r`.
Jens Wiklander817466c2018-05-22 13:49:31 +02001488 */
Jerome Forissier3602df82021-07-28 10:24:04 +02001489static mbedtls_mpi_uint mpi_sub_hlp( size_t n,
1490 mbedtls_mpi_uint *d,
1491 const mbedtls_mpi_uint *l,
1492 const mbedtls_mpi_uint *r )
Jens Wiklander817466c2018-05-22 13:49:31 +02001493{
1494 size_t i;
Jerome Forissier3602df82021-07-28 10:24:04 +02001495 mbedtls_mpi_uint c = 0, t, z;
Jens Wiklander817466c2018-05-22 13:49:31 +02001496
Jerome Forissier3602df82021-07-28 10:24:04 +02001497 for( i = 0; i < n; i++ )
Jens Wiklander817466c2018-05-22 13:49:31 +02001498 {
Jerome Forissier3602df82021-07-28 10:24:04 +02001499 z = ( l[i] < c ); t = l[i] - c;
1500 c = ( t < r[i] ) + z; d[i] = t - r[i];
Jens Wiklander817466c2018-05-22 13:49:31 +02001501 }
1502
Jerome Forissier3602df82021-07-28 10:24:04 +02001503 return( c );
Jens Wiklander817466c2018-05-22 13:49:31 +02001504}
1505
1506/*
Jerome Forissier3602df82021-07-28 10:24:04 +02001507 * Unsigned subtraction: X = |A| - |B| (HAC 14.9, 14.10)
Jens Wiklander817466c2018-05-22 13:49:31 +02001508 */
1509int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
1510{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001511 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02001512 size_t n;
Jerome Forissier3602df82021-07-28 10:24:04 +02001513 mbedtls_mpi_uint carry;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001514 MPI_VALIDATE_RET( X != NULL );
1515 MPI_VALIDATE_RET( A != NULL );
1516 MPI_VALIDATE_RET( B != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001517
Jens Wiklander817466c2018-05-22 13:49:31 +02001518 for( n = B->n; n > 0; n-- )
1519 if( B->p[n - 1] != 0 )
1520 break;
Jerome Forissier3602df82021-07-28 10:24:04 +02001521 if( n > A->n )
1522 {
1523 /* B >= (2^ciL)^n > A */
1524 ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
1525 goto cleanup;
1526 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001527
Jerome Forissier3602df82021-07-28 10:24:04 +02001528 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, A->n ) );
1529
1530 /* Set the high limbs of X to match A. Don't touch the lower limbs
1531 * because X might be aliased to B, and we must not overwrite the
1532 * significant digits of B. */
1533 if( A->n > n )
1534 memcpy( X->p + n, A->p + n, ( A->n - n ) * ciL );
1535 if( X->n > A->n )
1536 memset( X->p + A->n, 0, ( X->n - A->n ) * ciL );
1537
1538 carry = mpi_sub_hlp( n, X->p, A->p, B->p );
1539 if( carry != 0 )
1540 {
1541 /* Propagate the carry to the first nonzero limb of X. */
1542 for( ; n < X->n && X->p[n] == 0; n++ )
1543 --X->p[n];
1544 /* If we ran out of space for the carry, it means that the result
1545 * is negative. */
1546 if( n == X->n )
1547 {
1548 ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
1549 goto cleanup;
1550 }
1551 --X->p[n];
1552 }
1553
1554 /* X should always be positive as a result of unsigned subtractions. */
1555 X->s = 1;
Jens Wiklander817466c2018-05-22 13:49:31 +02001556
1557cleanup:
Jens Wiklander817466c2018-05-22 13:49:31 +02001558 return( ret );
1559}
1560
1561/*
1562 * Signed addition: X = A + B
1563 */
1564int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
1565{
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001566 int ret, s;
1567 MPI_VALIDATE_RET( X != NULL );
1568 MPI_VALIDATE_RET( A != NULL );
1569 MPI_VALIDATE_RET( B != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001570
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001571 s = A->s;
Jens Wiklander817466c2018-05-22 13:49:31 +02001572 if( A->s * B->s < 0 )
1573 {
1574 if( mbedtls_mpi_cmp_abs( A, B ) >= 0 )
1575 {
1576 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) );
1577 X->s = s;
1578 }
1579 else
1580 {
1581 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) );
1582 X->s = -s;
1583 }
1584 }
1585 else
1586 {
1587 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( X, A, B ) );
1588 X->s = s;
1589 }
1590
1591cleanup:
1592
1593 return( ret );
1594}
1595
1596/*
1597 * Signed subtraction: X = A - B
1598 */
1599int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
1600{
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001601 int ret, s;
1602 MPI_VALIDATE_RET( X != NULL );
1603 MPI_VALIDATE_RET( A != NULL );
1604 MPI_VALIDATE_RET( B != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001605
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001606 s = A->s;
Jens Wiklander817466c2018-05-22 13:49:31 +02001607 if( A->s * B->s > 0 )
1608 {
1609 if( mbedtls_mpi_cmp_abs( A, B ) >= 0 )
1610 {
1611 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) );
1612 X->s = s;
1613 }
1614 else
1615 {
1616 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) );
1617 X->s = -s;
1618 }
1619 }
1620 else
1621 {
1622 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( X, A, B ) );
1623 X->s = s;
1624 }
1625
1626cleanup:
1627
1628 return( ret );
1629}
1630
1631/*
1632 * Signed addition: X = A + b
1633 */
1634int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b )
1635{
1636 mbedtls_mpi _B;
1637 mbedtls_mpi_uint p[1];
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001638 MPI_VALIDATE_RET( X != NULL );
1639 MPI_VALIDATE_RET( A != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001640
1641 p[0] = ( b < 0 ) ? -b : b;
1642 _B.s = ( b < 0 ) ? -1 : 1;
1643 _B.n = 1;
1644 _B.p = p;
1645
1646 return( mbedtls_mpi_add_mpi( X, A, &_B ) );
1647}
1648
1649/*
1650 * Signed subtraction: X = A - b
1651 */
1652int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b )
1653{
1654 mbedtls_mpi _B;
1655 mbedtls_mpi_uint p[1];
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001656 MPI_VALIDATE_RET( X != NULL );
1657 MPI_VALIDATE_RET( A != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001658
1659 p[0] = ( b < 0 ) ? -b : b;
1660 _B.s = ( b < 0 ) ? -1 : 1;
1661 _B.n = 1;
1662 _B.p = p;
1663
1664 return( mbedtls_mpi_sub_mpi( X, A, &_B ) );
1665}
1666
Jerome Forissier3602df82021-07-28 10:24:04 +02001667/** Helper for mbedtls_mpi multiplication.
1668 *
1669 * Add \p b * \p s to \p d.
1670 *
1671 * \param i The number of limbs of \p s.
1672 * \param[in] s A bignum to multiply, of size \p i.
1673 * It may overlap with \p d, but only if
1674 * \p d <= \p s.
1675 * Its leading limb must not be \c 0.
1676 * \param[in,out] d The bignum to add to.
1677 * It must be sufficiently large to store the
1678 * result of the multiplication. This means
1679 * \p i + 1 limbs if \p d[\p i - 1] started as 0 and \p b
1680 * is not known a priori.
1681 * \param b A scalar to multiply.
Jens Wiklander817466c2018-05-22 13:49:31 +02001682 */
1683static
1684#if defined(__APPLE__) && defined(__arm__)
1685/*
1686 * Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
1687 * appears to need this to prevent bad ARM code generation at -O3.
1688 */
1689__attribute__ ((noinline))
1690#endif
Jerome Forissier3602df82021-07-28 10:24:04 +02001691void mpi_mul_hlp( size_t i,
1692 const mbedtls_mpi_uint *s,
1693 mbedtls_mpi_uint *d,
1694 mbedtls_mpi_uint b )
Jens Wiklander817466c2018-05-22 13:49:31 +02001695{
1696 mbedtls_mpi_uint c = 0, t = 0;
1697
1698#if defined(MULADDC_HUIT)
1699 for( ; i >= 8; i -= 8 )
1700 {
1701 MULADDC_INIT
1702 MULADDC_HUIT
1703 MULADDC_STOP
1704 }
1705
1706 for( ; i > 0; i-- )
1707 {
1708 MULADDC_INIT
1709 MULADDC_CORE
1710 MULADDC_STOP
1711 }
1712#else /* MULADDC_HUIT */
1713 for( ; i >= 16; i -= 16 )
1714 {
1715 MULADDC_INIT
1716 MULADDC_CORE MULADDC_CORE
1717 MULADDC_CORE MULADDC_CORE
1718 MULADDC_CORE MULADDC_CORE
1719 MULADDC_CORE MULADDC_CORE
1720
1721 MULADDC_CORE MULADDC_CORE
1722 MULADDC_CORE MULADDC_CORE
1723 MULADDC_CORE MULADDC_CORE
1724 MULADDC_CORE MULADDC_CORE
1725 MULADDC_STOP
1726 }
1727
1728 for( ; i >= 8; i -= 8 )
1729 {
1730 MULADDC_INIT
1731 MULADDC_CORE MULADDC_CORE
1732 MULADDC_CORE MULADDC_CORE
1733
1734 MULADDC_CORE MULADDC_CORE
1735 MULADDC_CORE MULADDC_CORE
1736 MULADDC_STOP
1737 }
1738
1739 for( ; i > 0; i-- )
1740 {
1741 MULADDC_INIT
1742 MULADDC_CORE
1743 MULADDC_STOP
1744 }
1745#endif /* MULADDC_HUIT */
1746
1747 t++;
1748
Jerome Forissier3602df82021-07-28 10:24:04 +02001749 while( c != 0 )
1750 {
Jens Wiklander817466c2018-05-22 13:49:31 +02001751 *d += c; c = ( *d < c ); d++;
1752 }
Jens Wiklander817466c2018-05-22 13:49:31 +02001753}
1754
1755/*
1756 * Baseline multiplication: X = A * B (HAC 14.12)
1757 */
1758int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
1759{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001760 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02001761 size_t i, j;
1762 mbedtls_mpi TA, TB;
Jerome Forissier3602df82021-07-28 10:24:04 +02001763 int result_is_zero = 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001764 MPI_VALIDATE_RET( X != NULL );
1765 MPI_VALIDATE_RET( A != NULL );
1766 MPI_VALIDATE_RET( B != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001767
Jens Wiklanderb81d8962018-11-08 11:18:22 +01001768 mbedtls_mpi_init_mempool( &TA ); mbedtls_mpi_init_mempool( &TB );
Jens Wiklander817466c2018-05-22 13:49:31 +02001769
1770 if( X == A ) { MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) ); A = &TA; }
1771 if( X == B ) { MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) ); B = &TB; }
1772
1773 for( i = A->n; i > 0; i-- )
1774 if( A->p[i - 1] != 0 )
1775 break;
Jerome Forissier3602df82021-07-28 10:24:04 +02001776 if( i == 0 )
1777 result_is_zero = 1;
Jens Wiklander817466c2018-05-22 13:49:31 +02001778
1779 for( j = B->n; j > 0; j-- )
1780 if( B->p[j - 1] != 0 )
1781 break;
Jerome Forissier3602df82021-07-28 10:24:04 +02001782 if( j == 0 )
1783 result_is_zero = 1;
Jens Wiklander817466c2018-05-22 13:49:31 +02001784
1785 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + j ) );
1786 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
1787
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001788 for( ; j > 0; j-- )
1789 mpi_mul_hlp( i, A->p, X->p + j - 1, B->p[j - 1] );
Jens Wiklander817466c2018-05-22 13:49:31 +02001790
Jerome Forissier3602df82021-07-28 10:24:04 +02001791 /* If the result is 0, we don't shortcut the operation, which reduces
1792 * but does not eliminate side channels leaking the zero-ness. We do
1793 * need to take care to set the sign bit properly since the library does
1794 * not fully support an MPI object with a value of 0 and s == -1. */
1795 if( result_is_zero )
1796 X->s = 1;
1797 else
1798 X->s = A->s * B->s;
Jens Wiklander817466c2018-05-22 13:49:31 +02001799
1800cleanup:
1801
1802 mbedtls_mpi_free( &TB ); mbedtls_mpi_free( &TA );
1803
1804 return( ret );
1805}
1806
1807/*
1808 * Baseline multiplication: X = A * b
1809 */
1810int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b )
1811{
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001812 MPI_VALIDATE_RET( X != NULL );
1813 MPI_VALIDATE_RET( A != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001814
Jerome Forissier3602df82021-07-28 10:24:04 +02001815 /* mpi_mul_hlp can't deal with a leading 0. */
1816 size_t n = A->n;
1817 while( n > 0 && A->p[n - 1] == 0 )
1818 --n;
Jens Wiklander817466c2018-05-22 13:49:31 +02001819
Jerome Forissier3602df82021-07-28 10:24:04 +02001820 /* The general method below doesn't work if n==0 or b==0. By chance
1821 * calculating the result is trivial in those cases. */
1822 if( b == 0 || n == 0 )
1823 {
1824 return( mbedtls_mpi_lset( X, 0 ) );
1825 }
1826
1827 /* Calculate A*b as A + A*(b-1) to take advantage of mpi_mul_hlp */
1828 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1829 /* In general, A * b requires 1 limb more than b. If
1830 * A->p[n - 1] * b / b == A->p[n - 1], then A * b fits in the same
1831 * number of limbs as A and the call to grow() is not required since
1832 * copy() will take care of the growth if needed. However, experimentally,
1833 * making the call to grow() unconditional causes slightly fewer
1834 * calls to calloc() in ECP code, presumably because it reuses the
1835 * same mpi for a while and this way the mpi is more likely to directly
1836 * grow to its final size. */
1837 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, n + 1 ) );
1838 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) );
1839 mpi_mul_hlp( n, A->p, X->p, b - 1 );
1840
1841cleanup:
1842 return( ret );
Jens Wiklander817466c2018-05-22 13:49:31 +02001843}
1844
1845/*
1846 * Unsigned integer divide - double mbedtls_mpi_uint dividend, u1/u0, and
1847 * mbedtls_mpi_uint divisor, d
1848 */
1849static mbedtls_mpi_uint mbedtls_int_div_int( mbedtls_mpi_uint u1,
1850 mbedtls_mpi_uint u0, mbedtls_mpi_uint d, mbedtls_mpi_uint *r )
1851{
1852#if defined(MBEDTLS_HAVE_UDBL)
1853 mbedtls_t_udbl dividend, quotient;
1854#else
1855 const mbedtls_mpi_uint radix = (mbedtls_mpi_uint) 1 << biH;
1856 const mbedtls_mpi_uint uint_halfword_mask = ( (mbedtls_mpi_uint) 1 << biH ) - 1;
1857 mbedtls_mpi_uint d0, d1, q0, q1, rAX, r0, quotient;
1858 mbedtls_mpi_uint u0_msw, u0_lsw;
1859 size_t s;
1860#endif
1861
1862 /*
1863 * Check for overflow
1864 */
1865 if( 0 == d || u1 >= d )
1866 {
1867 if (r != NULL) *r = ~0;
1868
1869 return ( ~0 );
1870 }
1871
1872#if defined(MBEDTLS_HAVE_UDBL)
1873 dividend = (mbedtls_t_udbl) u1 << biL;
1874 dividend |= (mbedtls_t_udbl) u0;
1875 quotient = dividend / d;
1876 if( quotient > ( (mbedtls_t_udbl) 1 << biL ) - 1 )
1877 quotient = ( (mbedtls_t_udbl) 1 << biL ) - 1;
1878
1879 if( r != NULL )
1880 *r = (mbedtls_mpi_uint)( dividend - (quotient * d ) );
1881
1882 return (mbedtls_mpi_uint) quotient;
1883#else
1884
1885 /*
1886 * Algorithm D, Section 4.3.1 - The Art of Computer Programming
1887 * Vol. 2 - Seminumerical Algorithms, Knuth
1888 */
1889
1890 /*
1891 * Normalize the divisor, d, and dividend, u0, u1
1892 */
1893 s = mbedtls_clz( d );
1894 d = d << s;
1895
1896 u1 = u1 << s;
1897 u1 |= ( u0 >> ( biL - s ) ) & ( -(mbedtls_mpi_sint)s >> ( biL - 1 ) );
1898 u0 = u0 << s;
1899
1900 d1 = d >> biH;
1901 d0 = d & uint_halfword_mask;
1902
1903 u0_msw = u0 >> biH;
1904 u0_lsw = u0 & uint_halfword_mask;
1905
1906 /*
1907 * Find the first quotient and remainder
1908 */
1909 q1 = u1 / d1;
1910 r0 = u1 - d1 * q1;
1911
1912 while( q1 >= radix || ( q1 * d0 > radix * r0 + u0_msw ) )
1913 {
1914 q1 -= 1;
1915 r0 += d1;
1916
1917 if ( r0 >= radix ) break;
1918 }
1919
1920 rAX = ( u1 * radix ) + ( u0_msw - q1 * d );
1921 q0 = rAX / d1;
1922 r0 = rAX - q0 * d1;
1923
1924 while( q0 >= radix || ( q0 * d0 > radix * r0 + u0_lsw ) )
1925 {
1926 q0 -= 1;
1927 r0 += d1;
1928
1929 if ( r0 >= radix ) break;
1930 }
1931
1932 if (r != NULL)
1933 *r = ( rAX * radix + u0_lsw - q0 * d ) >> s;
1934
1935 quotient = q1 * radix + q0;
1936
1937 return quotient;
1938#endif
1939}
1940
1941/*
1942 * Division by mbedtls_mpi: A = Q * B + R (HAC 14.20)
1943 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001944int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
1945 const mbedtls_mpi *B )
Jens Wiklander817466c2018-05-22 13:49:31 +02001946{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001947 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02001948 size_t i, n, t, k;
1949 mbedtls_mpi X, Y, Z, T1, T2;
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001950 mbedtls_mpi_uint TP2[3];
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001951 MPI_VALIDATE_RET( A != NULL );
1952 MPI_VALIDATE_RET( B != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001953
1954 if( mbedtls_mpi_cmp_int( B, 0 ) == 0 )
1955 return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO );
1956
Jens Wiklanderb81d8962018-11-08 11:18:22 +01001957 mbedtls_mpi_init_mempool( &X ); mbedtls_mpi_init_mempool( &Y );
1958 mbedtls_mpi_init_mempool( &Z ); mbedtls_mpi_init_mempool( &T1 );
Jerome Forissier11fa71b2020-04-20 17:17:56 +02001959 /*
1960 * Avoid dynamic memory allocations for constant-size T2.
1961 *
1962 * T2 is used for comparison only and the 3 limbs are assigned explicitly,
1963 * so nobody increase the size of the MPI and we're safe to use an on-stack
1964 * buffer.
1965 */
1966 T2.s = 1;
1967 T2.n = sizeof( TP2 ) / sizeof( *TP2 );
1968 T2.p = TP2;
Jens Wiklander817466c2018-05-22 13:49:31 +02001969
1970 if( mbedtls_mpi_cmp_abs( A, B ) < 0 )
1971 {
1972 if( Q != NULL ) MBEDTLS_MPI_CHK( mbedtls_mpi_lset( Q, 0 ) );
1973 if( R != NULL ) MBEDTLS_MPI_CHK( mbedtls_mpi_copy( R, A ) );
1974 return( 0 );
1975 }
1976
1977 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &X, A ) );
1978 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, B ) );
1979 X.s = Y.s = 1;
1980
1981 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &Z, A->n + 2 ) );
1982 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Z, 0 ) );
Jerome Forissier3602df82021-07-28 10:24:04 +02001983 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T1, A->n + 2 ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02001984
1985 k = mbedtls_mpi_bitlen( &Y ) % biL;
1986 if( k < biL - 1 )
1987 {
1988 k = biL - 1 - k;
1989 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &X, k ) );
1990 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &Y, k ) );
1991 }
1992 else k = 0;
1993
1994 n = X.n - 1;
1995 t = Y.n - 1;
1996 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &Y, biL * ( n - t ) ) );
1997
1998 while( mbedtls_mpi_cmp_mpi( &X, &Y ) >= 0 )
1999 {
2000 Z.p[n - t]++;
2001 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &Y ) );
2002 }
2003 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, biL * ( n - t ) ) );
2004
2005 for( i = n; i > t ; i-- )
2006 {
2007 if( X.p[i] >= Y.p[t] )
2008 Z.p[i - t - 1] = ~0;
2009 else
2010 {
2011 Z.p[i - t - 1] = mbedtls_int_div_int( X.p[i], X.p[i - 1],
2012 Y.p[t], NULL);
2013 }
2014
Jerome Forissier11fa71b2020-04-20 17:17:56 +02002015 T2.p[0] = ( i < 2 ) ? 0 : X.p[i - 2];
2016 T2.p[1] = ( i < 1 ) ? 0 : X.p[i - 1];
2017 T2.p[2] = X.p[i];
2018
Jens Wiklander817466c2018-05-22 13:49:31 +02002019 Z.p[i - t - 1]++;
2020 do
2021 {
2022 Z.p[i - t - 1]--;
2023
2024 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &T1, 0 ) );
2025 T1.p[0] = ( t < 1 ) ? 0 : Y.p[t - 1];
2026 T1.p[1] = Y.p[t];
2027 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02002028 }
2029 while( mbedtls_mpi_cmp_mpi( &T1, &T2 ) > 0 );
2030
2031 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
2032 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T1, biL * ( i - t - 1 ) ) );
2033 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T1 ) );
2034
2035 if( mbedtls_mpi_cmp_int( &X, 0 ) < 0 )
2036 {
2037 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T1, &Y ) );
2038 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T1, biL * ( i - t - 1 ) ) );
2039 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &X, &X, &T1 ) );
2040 Z.p[i - t - 1]--;
2041 }
2042 }
2043
2044 if( Q != NULL )
2045 {
2046 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( Q, &Z ) );
2047 Q->s = A->s * B->s;
2048 }
2049
2050 if( R != NULL )
2051 {
2052 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &X, k ) );
2053 X.s = A->s;
2054 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( R, &X ) );
2055
2056 if( mbedtls_mpi_cmp_int( R, 0 ) == 0 )
2057 R->s = 1;
2058 }
2059
2060cleanup:
2061
2062 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
Jerome Forissier11fa71b2020-04-20 17:17:56 +02002063 mbedtls_mpi_free( &T1 );
2064 mbedtls_platform_zeroize( TP2, sizeof( TP2 ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02002065
2066 return( ret );
2067}
2068
2069/*
2070 * Division by int: A = Q * b + R
2071 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002072int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R,
2073 const mbedtls_mpi *A,
2074 mbedtls_mpi_sint b )
Jens Wiklander817466c2018-05-22 13:49:31 +02002075{
2076 mbedtls_mpi _B;
2077 mbedtls_mpi_uint p[1];
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002078 MPI_VALIDATE_RET( A != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02002079
2080 p[0] = ( b < 0 ) ? -b : b;
2081 _B.s = ( b < 0 ) ? -1 : 1;
2082 _B.n = 1;
2083 _B.p = p;
2084
2085 return( mbedtls_mpi_div_mpi( Q, R, A, &_B ) );
2086}
2087
2088/*
2089 * Modulo: R = A mod B
2090 */
2091int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B )
2092{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02002093 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002094 MPI_VALIDATE_RET( R != NULL );
2095 MPI_VALIDATE_RET( A != NULL );
2096 MPI_VALIDATE_RET( B != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02002097
2098 if( mbedtls_mpi_cmp_int( B, 0 ) < 0 )
2099 return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
2100
2101 MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( NULL, R, A, B ) );
2102
2103 while( mbedtls_mpi_cmp_int( R, 0 ) < 0 )
2104 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( R, R, B ) );
2105
2106 while( mbedtls_mpi_cmp_mpi( R, B ) >= 0 )
2107 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( R, R, B ) );
2108
2109cleanup:
2110
2111 return( ret );
2112}
2113
2114/*
2115 * Modulo: r = A mod b
2116 */
2117int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b )
2118{
2119 size_t i;
2120 mbedtls_mpi_uint x, y, z;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002121 MPI_VALIDATE_RET( r != NULL );
2122 MPI_VALIDATE_RET( A != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02002123
2124 if( b == 0 )
2125 return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO );
2126
2127 if( b < 0 )
2128 return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
2129
2130 /*
2131 * handle trivial cases
2132 */
2133 if( b == 1 )
2134 {
2135 *r = 0;
2136 return( 0 );
2137 }
2138
2139 if( b == 2 )
2140 {
2141 *r = A->p[0] & 1;
2142 return( 0 );
2143 }
2144
2145 /*
2146 * general case
2147 */
2148 for( i = A->n, y = 0; i > 0; i-- )
2149 {
2150 x = A->p[i - 1];
2151 y = ( y << biH ) | ( x >> biH );
2152 z = y / b;
2153 y -= z * b;
2154
2155 x <<= biH;
2156 y = ( y << biH ) | ( x >> biH );
2157 z = y / b;
2158 y -= z * b;
2159 }
2160
2161 /*
2162 * If A is negative, then the current y represents a negative value.
2163 * Flipping it to the positive side.
2164 */
2165 if( A->s < 0 && y != 0 )
2166 y = b - y;
2167
2168 *r = y;
2169
2170 return( 0 );
2171}
2172
2173/*
2174 * Fast Montgomery initialization (thanks to Tom St Denis)
2175 */
Jerome Forissier3602df82021-07-28 10:24:04 +02002176static void mpi_montg_init( mbedtls_mpi_uint *mm, const mbedtls_mpi *N )
Jens Wiklander817466c2018-05-22 13:49:31 +02002177{
2178 mbedtls_mpi_uint x, m0 = N->p[0];
2179 unsigned int i;
2180
2181 x = m0;
2182 x += ( ( m0 + 2 ) & 4 ) << 1;
2183
2184 for( i = biL; i >= 8; i /= 2 )
2185 x *= ( 2 - ( m0 * x ) );
2186
2187 *mm = ~x + 1;
2188}
2189
Jens Wiklander3fbd8662018-11-07 08:11:29 +01002190void mbedtls_mpi_montg_init( mbedtls_mpi_uint *mm, const mbedtls_mpi *N )
2191{
2192 mpi_montg_init( mm, N );
2193}
2194
Jerome Forissier3602df82021-07-28 10:24:04 +02002195/** Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
2196 *
2197 * \param[in,out] A One of the numbers to multiply.
2198 * It must have at least as many limbs as N
2199 * (A->n >= N->n), and any limbs beyond n are ignored.
2200 * On successful completion, A contains the result of
2201 * the multiplication A * B * R^-1 mod N where
2202 * R = (2^ciL)^n.
2203 * \param[in] B One of the numbers to multiply.
2204 * It must be nonzero and must not have more limbs than N
2205 * (B->n <= N->n).
2206 * \param[in] N The modulo. N must be odd.
2207 * \param mm The value calculated by `mpi_montg_init(&mm, N)`.
2208 * This is -N^-1 mod 2^ciL.
2209 * \param[in,out] T A bignum for temporary storage.
2210 * It must be at least twice the limb size of N plus 2
2211 * (T->n >= 2 * (N->n + 1)).
2212 * Its initial content is unused and
2213 * its final content is indeterminate.
2214 * Note that unlike the usual convention in the library
2215 * for `const mbedtls_mpi*`, the content of T can change.
Jens Wiklander817466c2018-05-22 13:49:31 +02002216 */
Jerome Forissier3602df82021-07-28 10:24:04 +02002217static 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 +02002218 const mbedtls_mpi *T )
2219{
2220 size_t i, n, m;
2221 mbedtls_mpi_uint u0, u1, *d;
2222
Jens Wiklander817466c2018-05-22 13:49:31 +02002223 memset( T->p, 0, T->n * ciL );
2224
2225 d = T->p;
2226 n = N->n;
2227 m = ( B->n < n ) ? B->n : n;
2228
2229 for( i = 0; i < n; i++ )
2230 {
2231 /*
2232 * T = (T + u0*B + u1*N) / 2^biL
2233 */
2234 u0 = A->p[i];
2235 u1 = ( d[0] + u0 * B->p[0] ) * mm;
2236
2237 mpi_mul_hlp( m, B->p, d, u0 );
2238 mpi_mul_hlp( n, N->p, d, u1 );
2239
2240 *d++ = u0; d[n + 1] = 0;
2241 }
2242
Jerome Forissier3602df82021-07-28 10:24:04 +02002243 /* At this point, d is either the desired result or the desired result
2244 * plus N. We now potentially subtract N, avoiding leaking whether the
2245 * subtraction is performed through side channels. */
Jens Wiklander817466c2018-05-22 13:49:31 +02002246
Jerome Forissier3602df82021-07-28 10:24:04 +02002247 /* Copy the n least significant limbs of d to A, so that
2248 * A = d if d < N (recall that N has n limbs). */
2249 memcpy( A->p, d, n * ciL );
2250 /* If d >= N then we want to set A to d - N. To prevent timing attacks,
2251 * do the calculation without using conditional tests. */
2252 /* Set d to d0 + (2^biL)^n - N where d0 is the current value of d. */
2253 d[n] += 1;
2254 d[n] -= mpi_sub_hlp( n, d, d, N->p );
2255 /* If d0 < N then d < (2^biL)^n
2256 * so d[n] == 0 and we want to keep A as it is.
2257 * If d0 >= N then d >= (2^biL)^n, and d <= (2^biL)^n + N < 2 * (2^biL)^n
2258 * so d[n] == 1 and we want to set A to the result of the subtraction
2259 * which is d - (2^biL)^n, i.e. the n least significant limbs of d.
2260 * This exactly corresponds to a conditional assignment. */
2261 mpi_safe_cond_assign( n, A->p, d, (unsigned char) d[n] );
Jens Wiklander817466c2018-05-22 13:49:31 +02002262}
2263
Jens Wiklander3fbd8662018-11-07 08:11:29 +01002264void mbedtls_mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi *N, mbedtls_mpi_uint mm,
2265 const mbedtls_mpi *T )
2266{
2267 mpi_montmul( A, B, N, mm, T);
2268}
2269
Jens Wiklander817466c2018-05-22 13:49:31 +02002270/*
2271 * Montgomery reduction: A = A * R^-1 mod N
Jerome Forissier3602df82021-07-28 10:24:04 +02002272 *
2273 * See mpi_montmul() regarding constraints and guarantees on the parameters.
Jens Wiklander817466c2018-05-22 13:49:31 +02002274 */
Jerome Forissier3602df82021-07-28 10:24:04 +02002275static void mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N,
2276 mbedtls_mpi_uint mm, const mbedtls_mpi *T )
Jens Wiklander817466c2018-05-22 13:49:31 +02002277{
2278 mbedtls_mpi_uint z = 1;
2279 mbedtls_mpi U;
2280
2281 U.n = U.s = (int) z;
2282 U.p = &z;
2283
Jerome Forissier3602df82021-07-28 10:24:04 +02002284 mpi_montmul( A, &U, N, mm, T );
2285}
2286
Jens Wiklander3fbd8662018-11-07 08:11:29 +01002287void mbedtls_mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N,
2288 mbedtls_mpi_uint mm, const mbedtls_mpi *T )
2289{
2290 mpi_montred( A, N, mm, T );
2291}
2292
Jerome Forissier3602df82021-07-28 10:24:04 +02002293/*
2294 * Constant-flow boolean "equal" comparison:
2295 * return x == y
2296 *
2297 * This function can be used to write constant-time code by replacing branches
2298 * with bit operations - it can be used in conjunction with
2299 * mbedtls_ssl_cf_mask_from_bit().
2300 *
2301 * This function is implemented without using comparison operators, as those
2302 * might be translated to branches by some compilers on some platforms.
2303 */
2304static size_t mbedtls_mpi_cf_bool_eq( size_t x, size_t y )
2305{
2306 /* diff = 0 if x == y, non-zero otherwise */
2307 const size_t diff = x ^ y;
2308
2309 /* MSVC has a warning about unary minus on unsigned integer types,
2310 * but this is well-defined and precisely what we want to do here. */
2311#if defined(_MSC_VER)
2312#pragma warning( push )
2313#pragma warning( disable : 4146 )
2314#endif
2315
2316 /* diff_msb's most significant bit is equal to x != y */
2317 const size_t diff_msb = ( diff | (size_t) -diff );
2318
2319#if defined(_MSC_VER)
2320#pragma warning( pop )
2321#endif
2322
2323 /* diff1 = (x != y) ? 1 : 0 */
2324 const size_t diff1 = diff_msb >> ( sizeof( diff_msb ) * 8 - 1 );
2325
2326 return( 1 ^ diff1 );
2327}
2328
2329/**
2330 * Select an MPI from a table without leaking the index.
2331 *
2332 * This is functionally equivalent to mbedtls_mpi_copy(R, T[idx]) except it
2333 * reads the entire table in order to avoid leaking the value of idx to an
2334 * attacker able to observe memory access patterns.
2335 *
2336 * \param[out] R Where to write the selected MPI.
2337 * \param[in] T The table to read from.
2338 * \param[in] T_size The number of elements in the table.
2339 * \param[in] idx The index of the element to select;
2340 * this must satisfy 0 <= idx < T_size.
2341 *
2342 * \return \c 0 on success, or a negative error code.
2343 */
2344static int mpi_select( mbedtls_mpi *R, const mbedtls_mpi *T, size_t T_size, size_t idx )
2345{
2346 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2347
2348 for( size_t i = 0; i < T_size; i++ )
2349 {
2350 MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( R, &T[i],
2351 (unsigned char) mbedtls_mpi_cf_bool_eq( i, idx ) ) );
2352 }
2353
2354cleanup:
2355 return( ret );
Jens Wiklander817466c2018-05-22 13:49:31 +02002356}
2357
2358/*
2359 * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
2360 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002361int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
2362 const mbedtls_mpi *E, const mbedtls_mpi *N,
2363 mbedtls_mpi *_RR )
Jens Wiklander817466c2018-05-22 13:49:31 +02002364{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02002365 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02002366 size_t wbits, wsize, one = 1;
2367 size_t i, j, nblimbs;
2368 size_t bufsize, nbits;
2369 mbedtls_mpi_uint ei, mm, state;
Jerome Forissier3602df82021-07-28 10:24:04 +02002370 mbedtls_mpi RR, T, W[ 1 << MBEDTLS_MPI_WINDOW_SIZE ], WW, Apos;
Jens Wiklander817466c2018-05-22 13:49:31 +02002371 int neg;
2372
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002373 MPI_VALIDATE_RET( X != NULL );
2374 MPI_VALIDATE_RET( A != NULL );
2375 MPI_VALIDATE_RET( E != NULL );
2376 MPI_VALIDATE_RET( N != NULL );
2377
2378 if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 || ( N->p[0] & 1 ) == 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +02002379 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
2380
2381 if( mbedtls_mpi_cmp_int( E, 0 ) < 0 )
2382 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
2383
Jerome Forissier3602df82021-07-28 10:24:04 +02002384 if( mbedtls_mpi_bitlen( E ) > MBEDTLS_MPI_MAX_BITS ||
2385 mbedtls_mpi_bitlen( N ) > MBEDTLS_MPI_MAX_BITS )
2386 return ( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
2387
Jens Wiklander817466c2018-05-22 13:49:31 +02002388 /*
2389 * Init temps and window size
2390 */
Jerome Forissier3602df82021-07-28 10:24:04 +02002391 mpi_montg_init( &mm, N );
Jens Wiklanderb81d8962018-11-08 11:18:22 +01002392 mbedtls_mpi_init_mempool( &RR ); mbedtls_mpi_init( &T );
2393 mbedtls_mpi_init_mempool( &Apos );
2394 mbedtls_mpi_init_mempool( &WW );
Jerome Forissier3602df82021-07-28 10:24:04 +02002395 memset( W, 0, sizeof( W ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02002396
2397 i = mbedtls_mpi_bitlen( E );
2398
2399 wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
2400 ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
2401
Jerome Forissier5b25c762020-04-07 11:18:49 +02002402#if( MBEDTLS_MPI_WINDOW_SIZE < 6 )
Jens Wiklander817466c2018-05-22 13:49:31 +02002403 if( wsize > MBEDTLS_MPI_WINDOW_SIZE )
2404 wsize = MBEDTLS_MPI_WINDOW_SIZE;
Jerome Forissier5b25c762020-04-07 11:18:49 +02002405#endif
Jens Wiklander817466c2018-05-22 13:49:31 +02002406
2407 j = N->n + 1;
Jerome Forissier3602df82021-07-28 10:24:04 +02002408 /* All W[i] and X must have at least N->n limbs for the mpi_montmul()
2409 * and mpi_montred() calls later. Here we ensure that W[1] and X are
2410 * large enough, and later we'll grow other W[i] to the same length.
2411 * They must not be shrunk midway through this function!
2412 */
Jens Wiklander817466c2018-05-22 13:49:31 +02002413 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) );
Jerome Forissier3602df82021-07-28 10:24:04 +02002414 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1], j ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02002415 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T, j * 2 ) );
2416
2417 /*
2418 * Compensate for negative A (and correct at the end)
2419 */
2420 neg = ( A->s == -1 );
2421 if( neg )
2422 {
2423 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Apos, A ) );
2424 Apos.s = 1;
2425 A = &Apos;
2426 }
2427
2428 /*
2429 * If 1st call, pre-compute R^2 mod N
2430 */
2431 if( _RR == NULL || _RR->p == NULL )
2432 {
2433 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &RR, 1 ) );
2434 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &RR, N->n * 2 * biL ) );
2435 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &RR, &RR, N ) );
2436
2437 if( _RR != NULL )
2438 memcpy( _RR, &RR, sizeof( mbedtls_mpi ) );
2439 }
2440 else
2441 memcpy( &RR, _RR, sizeof( mbedtls_mpi ) );
2442
2443 /*
2444 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
2445 */
2446 if( mbedtls_mpi_cmp_mpi( A, N ) >= 0 )
Jerome Forissier3602df82021-07-28 10:24:04 +02002447 {
Jens Wiklander817466c2018-05-22 13:49:31 +02002448 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &W[1], A, N ) );
Jerome Forissier3602df82021-07-28 10:24:04 +02002449 /* This should be a no-op because W[1] is already that large before
2450 * mbedtls_mpi_mod_mpi(), but it's necessary to avoid an overflow
2451 * in mpi_montmul() below, so let's make sure. */
2452 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1], N->n + 1 ) );
2453 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002454 else
2455 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[1], A ) );
2456
Jerome Forissier3602df82021-07-28 10:24:04 +02002457 /* Note that this is safe because W[1] always has at least N->n limbs
2458 * (it grew above and was preserved by mbedtls_mpi_copy()). */
2459 mpi_montmul( &W[1], &RR, N, mm, &T );
Jens Wiklander817466c2018-05-22 13:49:31 +02002460
2461 /*
2462 * X = R^2 * R^-1 mod N = R mod N
2463 */
2464 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &RR ) );
Jerome Forissier3602df82021-07-28 10:24:04 +02002465 mpi_montred( X, N, mm, &T );
Jens Wiklander817466c2018-05-22 13:49:31 +02002466
2467 if( wsize > 1 )
2468 {
2469 /*
2470 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
2471 */
2472 j = one << ( wsize - 1 );
2473
2474 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[j], N->n + 1 ) );
2475 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[j], &W[1] ) );
2476
2477 for( i = 0; i < wsize - 1; i++ )
Jerome Forissier3602df82021-07-28 10:24:04 +02002478 mpi_montmul( &W[j], &W[j], N, mm, &T );
Jens Wiklander817466c2018-05-22 13:49:31 +02002479
2480 /*
2481 * W[i] = W[i - 1] * W[1]
2482 */
2483 for( i = j + 1; i < ( one << wsize ); i++ )
2484 {
2485 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[i], N->n + 1 ) );
2486 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[i], &W[i - 1] ) );
2487
Jerome Forissier3602df82021-07-28 10:24:04 +02002488 mpi_montmul( &W[i], &W[1], N, mm, &T );
Jens Wiklander817466c2018-05-22 13:49:31 +02002489 }
2490 }
2491
2492 nblimbs = E->n;
2493 bufsize = 0;
2494 nbits = 0;
2495 wbits = 0;
2496 state = 0;
2497
2498 while( 1 )
2499 {
2500 if( bufsize == 0 )
2501 {
2502 if( nblimbs == 0 )
2503 break;
2504
2505 nblimbs--;
2506
2507 bufsize = sizeof( mbedtls_mpi_uint ) << 3;
2508 }
2509
2510 bufsize--;
2511
2512 ei = (E->p[nblimbs] >> bufsize) & 1;
2513
2514 /*
2515 * skip leading 0s
2516 */
2517 if( ei == 0 && state == 0 )
2518 continue;
2519
2520 if( ei == 0 && state == 1 )
2521 {
2522 /*
2523 * out of window, square X
2524 */
Jerome Forissier3602df82021-07-28 10:24:04 +02002525 mpi_montmul( X, X, N, mm, &T );
Jens Wiklander817466c2018-05-22 13:49:31 +02002526 continue;
2527 }
2528
2529 /*
2530 * add ei to current window
2531 */
2532 state = 2;
2533
2534 nbits++;
2535 wbits |= ( ei << ( wsize - nbits ) );
2536
2537 if( nbits == wsize )
2538 {
2539 /*
2540 * X = X^wsize R^-1 mod N
2541 */
2542 for( i = 0; i < wsize; i++ )
Jerome Forissier3602df82021-07-28 10:24:04 +02002543 mpi_montmul( X, X, N, mm, &T );
Jens Wiklander817466c2018-05-22 13:49:31 +02002544
2545 /*
2546 * X = X * W[wbits] R^-1 mod N
2547 */
Jerome Forissier3602df82021-07-28 10:24:04 +02002548 MBEDTLS_MPI_CHK( mpi_select( &WW, W, (size_t) 1 << wsize, wbits ) );
2549 mpi_montmul( X, &WW, N, mm, &T );
Jens Wiklander817466c2018-05-22 13:49:31 +02002550
2551 state--;
2552 nbits = 0;
2553 wbits = 0;
2554 }
2555 }
2556
2557 /*
2558 * process the remaining bits
2559 */
2560 for( i = 0; i < nbits; i++ )
2561 {
Jerome Forissier3602df82021-07-28 10:24:04 +02002562 mpi_montmul( X, X, N, mm, &T );
Jens Wiklander817466c2018-05-22 13:49:31 +02002563
2564 wbits <<= 1;
2565
2566 if( ( wbits & ( one << wsize ) ) != 0 )
Jerome Forissier3602df82021-07-28 10:24:04 +02002567 mpi_montmul( X, &W[1], N, mm, &T );
Jens Wiklander817466c2018-05-22 13:49:31 +02002568 }
2569
2570 /*
2571 * X = A^E * R * R^-1 mod N = A^E mod N
2572 */
Jerome Forissier3602df82021-07-28 10:24:04 +02002573 mpi_montred( X, N, mm, &T );
Jens Wiklander817466c2018-05-22 13:49:31 +02002574
2575 if( neg && E->n != 0 && ( E->p[0] & 1 ) != 0 )
2576 {
2577 X->s = -1;
2578 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( X, N, X ) );
2579 }
2580
2581cleanup:
2582
Jerome Forissier3602df82021-07-28 10:24:04 +02002583 for( i = ( one << ( wsize - 1 ) ); i < ( one << wsize ); i++ )
2584 mbedtls_mpi_free( &W[i] );
Jens Wiklander817466c2018-05-22 13:49:31 +02002585
Jerome Forissier3602df82021-07-28 10:24:04 +02002586 mbedtls_mpi_free( &W[1] ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &Apos );
2587 mbedtls_mpi_free( &WW );
Jens Wiklander817466c2018-05-22 13:49:31 +02002588
2589 if( _RR == NULL || _RR->p == NULL )
2590 mbedtls_mpi_free( &RR );
2591
2592 return( ret );
2593}
2594
2595/*
2596 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
2597 */
2598int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B )
2599{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02002600 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02002601 size_t lz, lzt;
Jerome Forissier11fa71b2020-04-20 17:17:56 +02002602 mbedtls_mpi TA, TB;
Jens Wiklander817466c2018-05-22 13:49:31 +02002603
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002604 MPI_VALIDATE_RET( G != NULL );
2605 MPI_VALIDATE_RET( A != NULL );
2606 MPI_VALIDATE_RET( B != NULL );
2607
Jens Wiklanderb81d8962018-11-08 11:18:22 +01002608 mbedtls_mpi_init_mempool( &TA ); mbedtls_mpi_init_mempool( &TB );
Jens Wiklander817466c2018-05-22 13:49:31 +02002609
2610 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) );
2611 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) );
2612
2613 lz = mbedtls_mpi_lsb( &TA );
2614 lzt = mbedtls_mpi_lsb( &TB );
2615
Jerome Forissier3602df82021-07-28 10:24:04 +02002616 /* The loop below gives the correct result when A==0 but not when B==0.
2617 * So have a special case for B==0. Leverage the fact that we just
2618 * calculated the lsb and lsb(B)==0 iff B is odd or 0 to make the test
2619 * slightly more efficient than cmp_int(). */
2620 if( lzt == 0 && mbedtls_mpi_get_bit( &TB, 0 ) == 0 )
2621 {
2622 ret = mbedtls_mpi_copy( G, A );
2623 goto cleanup;
2624 }
2625
Jens Wiklander817466c2018-05-22 13:49:31 +02002626 if( lzt < lz )
2627 lz = lzt;
2628
Jens Wiklander817466c2018-05-22 13:49:31 +02002629 TA.s = TB.s = 1;
2630
Jerome Forissier3602df82021-07-28 10:24:04 +02002631 /* We mostly follow the procedure described in HAC 14.54, but with some
2632 * minor differences:
2633 * - Sequences of multiplications or divisions by 2 are grouped into a
2634 * single shift operation.
2635 * - The procedure in HAC assumes that 0 < TB <= TA.
2636 * - The condition TB <= TA is not actually necessary for correctness.
2637 * TA and TB have symmetric roles except for the loop termination
2638 * condition, and the shifts at the beginning of the loop body
2639 * remove any significance from the ordering of TA vs TB before
2640 * the shifts.
2641 * - If TA = 0, the loop goes through 0 iterations and the result is
2642 * correctly TB.
2643 * - The case TB = 0 was short-circuited above.
2644 *
2645 * For the correctness proof below, decompose the original values of
2646 * A and B as
2647 * A = sa * 2^a * A' with A'=0 or A' odd, and sa = +-1
2648 * B = sb * 2^b * B' with B'=0 or B' odd, and sb = +-1
2649 * Then gcd(A, B) = 2^{min(a,b)} * gcd(A',B'),
2650 * and gcd(A',B') is odd or 0.
2651 *
2652 * At the beginning, we have TA = |A| and TB = |B| so gcd(A,B) = gcd(TA,TB).
2653 * The code maintains the following invariant:
2654 * gcd(A,B) = 2^k * gcd(TA,TB) for some k (I)
2655 */
2656
2657 /* Proof that the loop terminates:
2658 * At each iteration, either the right-shift by 1 is made on a nonzero
2659 * value and the nonnegative integer bitlen(TA) + bitlen(TB) decreases
2660 * by at least 1, or the right-shift by 1 is made on zero and then
2661 * TA becomes 0 which ends the loop (TB cannot be 0 if it is right-shifted
2662 * since in that case TB is calculated from TB-TA with the condition TB>TA).
2663 */
Jens Wiklander817466c2018-05-22 13:49:31 +02002664 while( mbedtls_mpi_cmp_int( &TA, 0 ) != 0 )
2665 {
Jerome Forissier3602df82021-07-28 10:24:04 +02002666 /* Divisions by 2 preserve the invariant (I). */
Jens Wiklander817466c2018-05-22 13:49:31 +02002667 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, mbedtls_mpi_lsb( &TA ) ) );
2668 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, mbedtls_mpi_lsb( &TB ) ) );
2669
Jerome Forissier3602df82021-07-28 10:24:04 +02002670 /* Set either TA or TB to |TA-TB|/2. Since TA and TB are both odd,
2671 * TA-TB is even so the division by 2 has an integer result.
2672 * Invariant (I) is preserved since any odd divisor of both TA and TB
2673 * also divides |TA-TB|/2, and any odd divisor of both TA and |TA-TB|/2
2674 * also divides TB, and any odd divisior of both TB and |TA-TB|/2 also
2675 * divides TA.
2676 */
Jens Wiklander817466c2018-05-22 13:49:31 +02002677 if( mbedtls_mpi_cmp_mpi( &TA, &TB ) >= 0 )
2678 {
2679 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TA, &TA, &TB ) );
2680 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, 1 ) );
2681 }
2682 else
2683 {
2684 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TB, &TB, &TA ) );
2685 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, 1 ) );
2686 }
Jerome Forissier3602df82021-07-28 10:24:04 +02002687 /* Note that one of TA or TB is still odd. */
Jens Wiklander817466c2018-05-22 13:49:31 +02002688 }
2689
Jerome Forissier3602df82021-07-28 10:24:04 +02002690 /* By invariant (I), gcd(A,B) = 2^k * gcd(TA,TB) for some k.
2691 * At the loop exit, TA = 0, so gcd(TA,TB) = TB.
2692 * - If there was at least one loop iteration, then one of TA or TB is odd,
2693 * and TA = 0, so TB is odd and gcd(TA,TB) = gcd(A',B'). In this case,
2694 * lz = min(a,b) so gcd(A,B) = 2^lz * TB.
2695 * - If there was no loop iteration, then A was 0, and gcd(A,B) = B.
2696 * In this case, lz = 0 and B = TB so gcd(A,B) = B = 2^lz * TB as well.
2697 */
2698
Jens Wiklander817466c2018-05-22 13:49:31 +02002699 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &TB, lz ) );
2700 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( G, &TB ) );
2701
2702cleanup:
2703
Jerome Forissier11fa71b2020-04-20 17:17:56 +02002704 mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TB );
Jens Wiklander817466c2018-05-22 13:49:31 +02002705
2706 return( ret );
2707}
2708
Jerome Forissier3602df82021-07-28 10:24:04 +02002709/* Fill X with n_bytes random bytes.
2710 * X must already have room for those bytes.
2711 * The ordering of the bytes returned from the RNG is suitable for
2712 * deterministic ECDSA (see RFC 6979 §3.3 and mbedtls_mpi_random()).
2713 * The size and sign of X are unchanged.
2714 * n_bytes must not be 0.
2715 */
2716static int mpi_fill_random_internal(
2717 mbedtls_mpi *X, size_t n_bytes,
2718 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
2719{
2720 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2721 const size_t limbs = CHARS_TO_LIMBS( n_bytes );
2722 const size_t overhead = ( limbs * ciL ) - n_bytes;
2723
2724 if( X->n < limbs )
2725 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
2726
2727 memset( X->p, 0, overhead );
2728 memset( (unsigned char *) X->p + limbs * ciL, 0, ( X->n - limbs ) * ciL );
2729 MBEDTLS_MPI_CHK( f_rng( p_rng, (unsigned char *) X->p + overhead, n_bytes ) );
2730 mpi_bigendian_to_host( X->p, limbs );
2731
2732cleanup:
2733 return( ret );
2734}
2735
Jens Wiklander817466c2018-05-22 13:49:31 +02002736/*
2737 * Fill X with size bytes of random.
2738 *
2739 * Use a temporary bytes representation to make sure the result is the same
2740 * regardless of the platform endianness (useful when f_rng is actually
2741 * deterministic, eg for tests).
2742 */
2743int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size,
2744 int (*f_rng)(void *, unsigned char *, size_t),
2745 void *p_rng )
2746{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02002747 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jerome Forissier5b25c762020-04-07 11:18:49 +02002748 size_t const limbs = CHARS_TO_LIMBS( size );
Jerome Forissier5b25c762020-04-07 11:18:49 +02002749
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002750 MPI_VALIDATE_RET( X != NULL );
2751 MPI_VALIDATE_RET( f_rng != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02002752
Jerome Forissier5b25c762020-04-07 11:18:49 +02002753 /* Ensure that target MPI has exactly the necessary number of limbs */
Jerome Forissier3602df82021-07-28 10:24:04 +02002754 MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, limbs ) );
2755 if( size == 0 )
2756 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +02002757
Jerome Forissier3602df82021-07-28 10:24:04 +02002758 ret = mpi_fill_random_internal( X, size, f_rng, p_rng );
Jens Wiklander817466c2018-05-22 13:49:31 +02002759
2760cleanup:
2761 return( ret );
2762}
2763
Jerome Forissier3602df82021-07-28 10:24:04 +02002764int mbedtls_mpi_random( mbedtls_mpi *X,
2765 mbedtls_mpi_sint min,
2766 const mbedtls_mpi *N,
2767 int (*f_rng)(void *, unsigned char *, size_t),
2768 void *p_rng )
2769{
2770 int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
2771 int count;
2772 unsigned lt_lower = 1, lt_upper = 0;
2773 size_t n_bits = mbedtls_mpi_bitlen( N );
2774 size_t n_bytes = ( n_bits + 7 ) / 8;
2775 mbedtls_mpi lower_bound;
2776
2777 if( min < 0 )
2778 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
2779 if( mbedtls_mpi_cmp_int( N, min ) <= 0 )
2780 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
2781
2782 /*
2783 * When min == 0, each try has at worst a probability 1/2 of failing
2784 * (the msb has a probability 1/2 of being 0, and then the result will
2785 * be < N), so after 30 tries failure probability is a most 2**(-30).
2786 *
2787 * When N is just below a power of 2, as is the case when generating
2788 * a random scalar on most elliptic curves, 1 try is enough with
2789 * overwhelming probability. When N is just above a power of 2,
2790 * as when generating a random scalar on secp224k1, each try has
2791 * a probability of failing that is almost 1/2.
2792 *
2793 * The probabilities are almost the same if min is nonzero but negligible
2794 * compared to N. This is always the case when N is crypto-sized, but
2795 * it's convenient to support small N for testing purposes. When N
2796 * is small, use a higher repeat count, otherwise the probability of
2797 * failure is macroscopic.
2798 */
2799 count = ( n_bytes > 4 ? 30 : 250 );
2800
2801 mbedtls_mpi_init( &lower_bound );
2802
2803 /* Ensure that target MPI has exactly the same number of limbs
2804 * as the upper bound, even if the upper bound has leading zeros.
2805 * This is necessary for the mbedtls_mpi_lt_mpi_ct() check. */
2806 MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, N->n ) );
2807 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &lower_bound, N->n ) );
2808 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &lower_bound, min ) );
2809
2810 /*
2811 * Match the procedure given in RFC 6979 §3.3 (deterministic ECDSA)
2812 * when f_rng is a suitably parametrized instance of HMAC_DRBG:
2813 * - use the same byte ordering;
2814 * - keep the leftmost n_bits bits of the generated octet string;
2815 * - try until result is in the desired range.
2816 * This also avoids any bias, which is especially important for ECDSA.
2817 */
2818 do
2819 {
2820 MBEDTLS_MPI_CHK( mpi_fill_random_internal( X, n_bytes, f_rng, p_rng ) );
2821 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, 8 * n_bytes - n_bits ) );
2822
2823 if( --count == 0 )
2824 {
2825 ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
2826 goto cleanup;
2827 }
2828
2829 MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( X, &lower_bound, &lt_lower ) );
2830 MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( X, N, &lt_upper ) );
2831 }
2832 while( lt_lower != 0 || lt_upper == 0 );
2833
2834cleanup:
2835 mbedtls_mpi_free( &lower_bound );
2836 return( ret );
2837}
2838
Jens Wiklander817466c2018-05-22 13:49:31 +02002839/*
2840 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
2841 */
2842int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N )
2843{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02002844 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02002845 mbedtls_mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002846 MPI_VALIDATE_RET( X != NULL );
2847 MPI_VALIDATE_RET( A != NULL );
2848 MPI_VALIDATE_RET( N != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02002849
2850 if( mbedtls_mpi_cmp_int( N, 1 ) <= 0 )
2851 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
2852
Jens Wiklanderb81d8962018-11-08 11:18:22 +01002853 mbedtls_mpi_init_mempool( &TA ); mbedtls_mpi_init_mempool( &TU );
2854 mbedtls_mpi_init_mempool( &U1 ); mbedtls_mpi_init_mempool( &U2 );
2855 mbedtls_mpi_init_mempool( &G ); mbedtls_mpi_init_mempool( &TB );
2856 mbedtls_mpi_init_mempool( &TV ); mbedtls_mpi_init_mempool( &V1 );
2857 mbedtls_mpi_init_mempool( &V2 );
Jens Wiklander817466c2018-05-22 13:49:31 +02002858
2859 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, A, N ) );
2860
2861 if( mbedtls_mpi_cmp_int( &G, 1 ) != 0 )
2862 {
2863 ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
2864 goto cleanup;
2865 }
2866
2867 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &TA, A, N ) );
2868 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TU, &TA ) );
2869 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, N ) );
2870 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TV, N ) );
2871
2872 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &U1, 1 ) );
2873 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &U2, 0 ) );
2874 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &V1, 0 ) );
2875 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &V2, 1 ) );
2876
2877 do
2878 {
2879 while( ( TU.p[0] & 1 ) == 0 )
2880 {
2881 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TU, 1 ) );
2882
2883 if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
2884 {
2885 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &U1, &U1, &TB ) );
2886 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U2, &U2, &TA ) );
2887 }
2888
2889 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &U1, 1 ) );
2890 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &U2, 1 ) );
2891 }
2892
2893 while( ( TV.p[0] & 1 ) == 0 )
2894 {
2895 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TV, 1 ) );
2896
2897 if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
2898 {
2899 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &V1, &V1, &TB ) );
2900 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V2, &V2, &TA ) );
2901 }
2902
2903 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &V1, 1 ) );
2904 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &V2, 1 ) );
2905 }
2906
2907 if( mbedtls_mpi_cmp_mpi( &TU, &TV ) >= 0 )
2908 {
2909 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &TU, &TU, &TV ) );
2910 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U1, &U1, &V1 ) );
2911 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U2, &U2, &V2 ) );
2912 }
2913 else
2914 {
2915 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &TV, &TV, &TU ) );
2916 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V1, &V1, &U1 ) );
2917 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V2, &V2, &U2 ) );
2918 }
2919 }
2920 while( mbedtls_mpi_cmp_int( &TU, 0 ) != 0 );
2921
2922 while( mbedtls_mpi_cmp_int( &V1, 0 ) < 0 )
2923 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &V1, &V1, N ) );
2924
2925 while( mbedtls_mpi_cmp_mpi( &V1, N ) >= 0 )
2926 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V1, &V1, N ) );
2927
2928 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &V1 ) );
2929
2930cleanup:
2931
2932 mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TU ); mbedtls_mpi_free( &U1 ); mbedtls_mpi_free( &U2 );
2933 mbedtls_mpi_free( &G ); mbedtls_mpi_free( &TB ); mbedtls_mpi_free( &TV );
2934 mbedtls_mpi_free( &V1 ); mbedtls_mpi_free( &V2 );
2935
2936 return( ret );
2937}
2938
2939#if defined(MBEDTLS_GENPRIME)
2940
2941static const int small_prime[] =
2942{
2943 3, 5, 7, 11, 13, 17, 19, 23,
2944 29, 31, 37, 41, 43, 47, 53, 59,
2945 61, 67, 71, 73, 79, 83, 89, 97,
2946 101, 103, 107, 109, 113, 127, 131, 137,
2947 139, 149, 151, 157, 163, 167, 173, 179,
2948 181, 191, 193, 197, 199, 211, 223, 227,
2949 229, 233, 239, 241, 251, 257, 263, 269,
2950 271, 277, 281, 283, 293, 307, 311, 313,
2951 317, 331, 337, 347, 349, 353, 359, 367,
2952 373, 379, 383, 389, 397, 401, 409, 419,
2953 421, 431, 433, 439, 443, 449, 457, 461,
2954 463, 467, 479, 487, 491, 499, 503, 509,
2955 521, 523, 541, 547, 557, 563, 569, 571,
2956 577, 587, 593, 599, 601, 607, 613, 617,
2957 619, 631, 641, 643, 647, 653, 659, 661,
2958 673, 677, 683, 691, 701, 709, 719, 727,
2959 733, 739, 743, 751, 757, 761, 769, 773,
2960 787, 797, 809, 811, 821, 823, 827, 829,
2961 839, 853, 857, 859, 863, 877, 881, 883,
2962 887, 907, 911, 919, 929, 937, 941, 947,
2963 953, 967, 971, 977, 983, 991, 997, -103
2964};
2965
2966/*
2967 * Small divisors test (X must be positive)
2968 *
2969 * Return values:
2970 * 0: no small factor (possible prime, more tests needed)
2971 * 1: certain prime
2972 * MBEDTLS_ERR_MPI_NOT_ACCEPTABLE: certain non-prime
2973 * other negative: error
2974 */
2975static int mpi_check_small_factors( const mbedtls_mpi *X )
2976{
2977 int ret = 0;
2978 size_t i;
2979 mbedtls_mpi_uint r;
2980
2981 if( ( X->p[0] & 1 ) == 0 )
2982 return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
2983
2984 for( i = 0; small_prime[i] > 0; i++ )
2985 {
2986 if( mbedtls_mpi_cmp_int( X, small_prime[i] ) <= 0 )
2987 return( 1 );
2988
2989 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, small_prime[i] ) );
2990
2991 if( r == 0 )
2992 return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
2993 }
2994
2995cleanup:
2996 return( ret );
2997}
2998
2999/*
3000 * Miller-Rabin pseudo-primality test (HAC 4.24)
3001 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003002static int mpi_miller_rabin( const mbedtls_mpi *X, size_t rounds,
Jens Wiklander817466c2018-05-22 13:49:31 +02003003 int (*f_rng)(void *, unsigned char *, size_t),
3004 void *p_rng )
3005{
3006 int ret, count;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003007 size_t i, j, k, s;
Jens Wiklander817466c2018-05-22 13:49:31 +02003008 mbedtls_mpi W, R, T, A, RR;
3009
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003010 MPI_VALIDATE_RET( X != NULL );
3011 MPI_VALIDATE_RET( f_rng != NULL );
3012
Jens Wiklanderb81d8962018-11-08 11:18:22 +01003013 mbedtls_mpi_init_mempool( &W ); mbedtls_mpi_init_mempool( &R );
3014 mbedtls_mpi_init_mempool( &T ); mbedtls_mpi_init_mempool( &A );
3015 mbedtls_mpi_init_mempool( &RR );
Jens Wiklander817466c2018-05-22 13:49:31 +02003016
3017 /*
3018 * W = |X| - 1
3019 * R = W >> lsb( W )
3020 */
3021 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &W, X, 1 ) );
3022 s = mbedtls_mpi_lsb( &W );
3023 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R, &W ) );
3024 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &R, s ) );
3025
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003026 for( i = 0; i < rounds; i++ )
Jens Wiklander817466c2018-05-22 13:49:31 +02003027 {
3028 /*
3029 * pick a random A, 1 < A < |X| - 1
3030 */
Jens Wiklander817466c2018-05-22 13:49:31 +02003031 count = 0;
3032 do {
3033 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
3034
3035 j = mbedtls_mpi_bitlen( &A );
3036 k = mbedtls_mpi_bitlen( &W );
3037 if (j > k) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003038 A.p[A.n - 1] &= ( (mbedtls_mpi_uint) 1 << ( k - ( A.n - 1 ) * biL - 1 ) ) - 1;
Jens Wiklander817466c2018-05-22 13:49:31 +02003039 }
3040
Jens Wiklandere5b6c162018-11-27 12:21:24 +01003041 if (count++ > 300) {
Jens Wiklander336e3292019-01-17 11:14:38 +01003042 ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
3043 goto cleanup;
Jens Wiklander817466c2018-05-22 13:49:31 +02003044 }
3045
3046 } while ( mbedtls_mpi_cmp_mpi( &A, &W ) >= 0 ||
3047 mbedtls_mpi_cmp_int( &A, 1 ) <= 0 );
3048
3049 /*
3050 * A = A^R mod |X|
3051 */
3052 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &A, &A, &R, X, &RR ) );
3053
3054 if( mbedtls_mpi_cmp_mpi( &A, &W ) == 0 ||
3055 mbedtls_mpi_cmp_int( &A, 1 ) == 0 )
3056 continue;
3057
3058 j = 1;
3059 while( j < s && mbedtls_mpi_cmp_mpi( &A, &W ) != 0 )
3060 {
3061 /*
3062 * A = A * A mod |X|
3063 */
3064 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &A, &A ) );
3065 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &A, &T, X ) );
3066
3067 if( mbedtls_mpi_cmp_int( &A, 1 ) == 0 )
3068 break;
3069
3070 j++;
3071 }
3072
3073 /*
3074 * not prime if A != |X| - 1 or A == 1
3075 */
3076 if( mbedtls_mpi_cmp_mpi( &A, &W ) != 0 ||
3077 mbedtls_mpi_cmp_int( &A, 1 ) == 0 )
3078 {
3079 ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
3080 break;
3081 }
3082 }
3083
3084cleanup:
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003085 mbedtls_mpi_free( &W ); mbedtls_mpi_free( &R );
3086 mbedtls_mpi_free( &T ); mbedtls_mpi_free( &A );
Jens Wiklander817466c2018-05-22 13:49:31 +02003087 mbedtls_mpi_free( &RR );
3088
3089 return( ret );
3090}
3091
3092/*
3093 * Pseudo-primality test: small factors, then Miller-Rabin
3094 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003095int mbedtls_mpi_is_prime_ext( const mbedtls_mpi *X, int rounds,
3096 int (*f_rng)(void *, unsigned char *, size_t),
3097 void *p_rng )
Jens Wiklander817466c2018-05-22 13:49:31 +02003098{
Jerome Forissier11fa71b2020-04-20 17:17:56 +02003099 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +02003100 mbedtls_mpi XX;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003101 MPI_VALIDATE_RET( X != NULL );
3102 MPI_VALIDATE_RET( f_rng != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02003103
3104 XX.s = 1;
3105 XX.n = X->n;
3106 XX.p = X->p;
3107
3108 if( mbedtls_mpi_cmp_int( &XX, 0 ) == 0 ||
3109 mbedtls_mpi_cmp_int( &XX, 1 ) == 0 )
3110 return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
3111
3112 if( mbedtls_mpi_cmp_int( &XX, 2 ) == 0 )
3113 return( 0 );
3114
3115 if( ( ret = mpi_check_small_factors( &XX ) ) != 0 )
3116 {
3117 if( ret == 1 )
3118 return( 0 );
3119
3120 return( ret );
3121 }
3122
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003123 return( mpi_miller_rabin( &XX, rounds, f_rng, p_rng ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02003124}
3125
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003126#if !defined(MBEDTLS_DEPRECATED_REMOVED)
3127/*
3128 * Pseudo-primality test, error probability 2^-80
3129 */
3130int mbedtls_mpi_is_prime( const mbedtls_mpi *X,
3131 int (*f_rng)(void *, unsigned char *, size_t),
3132 void *p_rng )
3133{
3134 MPI_VALIDATE_RET( X != NULL );
3135 MPI_VALIDATE_RET( f_rng != NULL );
3136
3137 /*
3138 * In the past our key generation aimed for an error rate of at most
3139 * 2^-80. Since this function is deprecated, aim for the same certainty
3140 * here as well.
3141 */
3142 return( mbedtls_mpi_is_prime_ext( X, 40, f_rng, p_rng ) );
3143}
3144#endif
3145
Jens Wiklander817466c2018-05-22 13:49:31 +02003146/*
3147 * Prime number generation
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003148 *
3149 * To generate an RSA key in a way recommended by FIPS 186-4, both primes must
3150 * be either 1024 bits or 1536 bits long, and flags must contain
3151 * MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR.
Jens Wiklander817466c2018-05-22 13:49:31 +02003152 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003153int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int flags,
Jens Wiklander817466c2018-05-22 13:49:31 +02003154 int (*f_rng)(void *, unsigned char *, size_t),
3155 void *p_rng )
3156{
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003157#ifdef MBEDTLS_HAVE_INT64
3158// ceil(2^63.5)
3159#define CEIL_MAXUINT_DIV_SQRT2 0xb504f333f9de6485ULL
3160#else
3161// ceil(2^31.5)
3162#define CEIL_MAXUINT_DIV_SQRT2 0xb504f334U
3163#endif
3164 int ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
Jens Wiklander817466c2018-05-22 13:49:31 +02003165 size_t k, n;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003166 int rounds;
Jens Wiklander817466c2018-05-22 13:49:31 +02003167 mbedtls_mpi_uint r;
3168 mbedtls_mpi Y;
3169
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003170 MPI_VALIDATE_RET( X != NULL );
3171 MPI_VALIDATE_RET( f_rng != NULL );
3172
Jens Wiklander817466c2018-05-22 13:49:31 +02003173 if( nbits < 3 || nbits > MBEDTLS_MPI_MAX_BITS )
3174 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
3175
Jens Wiklanderb81d8962018-11-08 11:18:22 +01003176 mbedtls_mpi_init_mempool( &Y );
Jens Wiklander817466c2018-05-22 13:49:31 +02003177
3178 n = BITS_TO_LIMBS( nbits );
3179
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003180 if( ( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR ) == 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +02003181 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003182 /*
3183 * 2^-80 error probability, number of rounds chosen per HAC, table 4.4
3184 */
3185 rounds = ( ( nbits >= 1300 ) ? 2 : ( nbits >= 850 ) ? 3 :
3186 ( nbits >= 650 ) ? 4 : ( nbits >= 350 ) ? 8 :
3187 ( nbits >= 250 ) ? 12 : ( nbits >= 150 ) ? 18 : 27 );
Jens Wiklander817466c2018-05-22 13:49:31 +02003188 }
3189 else
3190 {
3191 /*
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003192 * 2^-100 error probability, number of rounds computed based on HAC,
3193 * fact 4.48
Jens Wiklander817466c2018-05-22 13:49:31 +02003194 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003195 rounds = ( ( nbits >= 1450 ) ? 4 : ( nbits >= 1150 ) ? 5 :
3196 ( nbits >= 1000 ) ? 6 : ( nbits >= 850 ) ? 7 :
3197 ( nbits >= 750 ) ? 8 : ( nbits >= 500 ) ? 13 :
3198 ( nbits >= 250 ) ? 28 : ( nbits >= 150 ) ? 40 : 51 );
3199 }
Jens Wiklander817466c2018-05-22 13:49:31 +02003200
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003201 while( 1 )
3202 {
3203 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
3204 /* make sure generated number is at least (nbits-1)+0.5 bits (FIPS 186-4 §B.3.3 steps 4.4, 5.5) */
3205 if( X->p[n-1] < CEIL_MAXUINT_DIV_SQRT2 ) continue;
Jens Wiklander817466c2018-05-22 13:49:31 +02003206
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003207 k = n * biL;
3208 if( k > nbits ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, k - nbits ) );
3209 X->p[0] |= 1;
Jens Wiklander817466c2018-05-22 13:49:31 +02003210
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003211 if( ( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH ) == 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +02003212 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003213 ret = mbedtls_mpi_is_prime_ext( X, rounds, f_rng, p_rng );
Jens Wiklander817466c2018-05-22 13:49:31 +02003214
3215 if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
3216 goto cleanup;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003217 }
3218 else
3219 {
Jens Wiklander817466c2018-05-22 13:49:31 +02003220 /*
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003221 * An necessary condition for Y and X = 2Y + 1 to be prime
3222 * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
3223 * Make sure it is satisfied, while keeping X = 3 mod 4
Jens Wiklander817466c2018-05-22 13:49:31 +02003224 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01003225
3226 X->p[0] |= 2;
3227
3228 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, 3 ) );
3229 if( r == 0 )
3230 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 8 ) );
3231 else if( r == 1 )
3232 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 4 ) );
3233
3234 /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
3235 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, X ) );
3236 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, 1 ) );
3237
3238 while( 1 )
3239 {
3240 /*
3241 * First, check small factors for X and Y
3242 * before doing Miller-Rabin on any of them
3243 */
3244 if( ( ret = mpi_check_small_factors( X ) ) == 0 &&
3245 ( ret = mpi_check_small_factors( &Y ) ) == 0 &&
3246 ( ret = mpi_miller_rabin( X, rounds, f_rng, p_rng ) )
3247 == 0 &&
3248 ( ret = mpi_miller_rabin( &Y, rounds, f_rng, p_rng ) )
3249 == 0 )
3250 goto cleanup;
3251
3252 if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
3253 goto cleanup;
3254
3255 /*
3256 * Next candidates. We want to preserve Y = (X-1) / 2 and
3257 * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
3258 * so up Y by 6 and X by 12.
3259 */
3260 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 12 ) );
3261 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &Y, &Y, 6 ) );
3262 }
Jens Wiklander817466c2018-05-22 13:49:31 +02003263 }
3264 }
3265
3266cleanup:
3267
3268 mbedtls_mpi_free( &Y );
3269
3270 return( ret );
3271}
3272
3273#endif /* MBEDTLS_GENPRIME */
3274
3275#if defined(MBEDTLS_SELF_TEST)
3276
3277#define GCD_PAIR_COUNT 3
3278
3279static const int gcd_pairs[GCD_PAIR_COUNT][3] =
3280{
3281 { 693, 609, 21 },
3282 { 1764, 868, 28 },
3283 { 768454923, 542167814, 1 }
3284};
3285
3286/*
3287 * Checkup routine
3288 */
3289int mbedtls_mpi_self_test( int verbose )
3290{
3291 int ret, i;
3292 mbedtls_mpi A, E, N, X, Y, U, V;
3293
Jens Wiklanderb81d8962018-11-08 11:18:22 +01003294 mbedtls_mpi_init_mempool( &A ); mbedtls_mpi_init_mempool( &E );
3295 mbedtls_mpi_init_mempool( &N ); mbedtls_mpi_init_mempool( &X );
3296 mbedtls_mpi_init_mempool( &Y ); mbedtls_mpi_init_mempool( &U );
3297 mbedtls_mpi_init_mempool( &V );
Jens Wiklander817466c2018-05-22 13:49:31 +02003298
3299 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &A, 16,
3300 "EFE021C2645FD1DC586E69184AF4A31E" \
3301 "D5F53E93B5F123FA41680867BA110131" \
3302 "944FE7952E2517337780CB0DB80E61AA" \
3303 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
3304
3305 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &E, 16,
3306 "B2E7EFD37075B9F03FF989C7C5051C20" \
3307 "34D2A323810251127E7BF8625A4F49A5" \
3308 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
3309 "5B5C25763222FEFCCFC38B832366C29E" ) );
3310
3311 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &N, 16,
3312 "0066A198186C18C10B2F5ED9B522752A" \
3313 "9830B69916E535C8F047518A889A43A5" \
3314 "94B6BED27A168D31D4A52F88925AA8F5" ) );
3315
3316 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &X, &A, &N ) );
3317
3318 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
3319 "602AB7ECA597A3D6B56FF9829A5E8B85" \
3320 "9E857EA95A03512E2BAE7391688D264A" \
3321 "A5663B0341DB9CCFD2C4C5F421FEC814" \
3322 "8001B72E848A38CAE1C65F78E56ABDEF" \
3323 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
3324 "ECF677152EF804370C1A305CAF3B5BF1" \
3325 "30879B56C61DE584A0F53A2447A51E" ) );
3326
3327 if( verbose != 0 )
3328 mbedtls_printf( " MPI test #1 (mul_mpi): " );
3329
3330 if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 )
3331 {
3332 if( verbose != 0 )
3333 mbedtls_printf( "failed\n" );
3334
3335 ret = 1;
3336 goto cleanup;
3337 }
3338
3339 if( verbose != 0 )
3340 mbedtls_printf( "passed\n" );
3341
3342 MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &X, &Y, &A, &N ) );
3343
3344 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
3345 "256567336059E52CAE22925474705F39A94" ) );
3346
3347 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &V, 16,
3348 "6613F26162223DF488E9CD48CC132C7A" \
3349 "0AC93C701B001B092E4E5B9F73BCD27B" \
3350 "9EE50D0657C77F374E903CDFA4C642" ) );
3351
3352 if( verbose != 0 )
3353 mbedtls_printf( " MPI test #2 (div_mpi): " );
3354
3355 if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 ||
3356 mbedtls_mpi_cmp_mpi( &Y, &V ) != 0 )
3357 {
3358 if( verbose != 0 )
3359 mbedtls_printf( "failed\n" );
3360
3361 ret = 1;
3362 goto cleanup;
3363 }
3364
3365 if( verbose != 0 )
3366 mbedtls_printf( "passed\n" );
3367
3368 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &X, &A, &E, &N, NULL ) );
3369
3370 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
3371 "36E139AEA55215609D2816998ED020BB" \
3372 "BD96C37890F65171D948E9BC7CBAA4D9" \
3373 "325D24D6A3C12710F10A09FA08AB87" ) );
3374
3375 if( verbose != 0 )
3376 mbedtls_printf( " MPI test #3 (exp_mod): " );
3377
3378 if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 )
3379 {
3380 if( verbose != 0 )
3381 mbedtls_printf( "failed\n" );
3382
3383 ret = 1;
3384 goto cleanup;
3385 }
3386
3387 if( verbose != 0 )
3388 mbedtls_printf( "passed\n" );
3389
3390 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &X, &A, &N ) );
3391
3392 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
3393 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
3394 "C3DBA76456363A10869622EAC2DD84EC" \
3395 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
3396
3397 if( verbose != 0 )
3398 mbedtls_printf( " MPI test #4 (inv_mod): " );
3399
3400 if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 )
3401 {
3402 if( verbose != 0 )
3403 mbedtls_printf( "failed\n" );
3404
3405 ret = 1;
3406 goto cleanup;
3407 }
3408
3409 if( verbose != 0 )
3410 mbedtls_printf( "passed\n" );
3411
3412 if( verbose != 0 )
3413 mbedtls_printf( " MPI test #5 (simple gcd): " );
3414
3415 for( i = 0; i < GCD_PAIR_COUNT; i++ )
3416 {
3417 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &X, gcd_pairs[i][0] ) );
3418 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Y, gcd_pairs[i][1] ) );
3419
3420 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &A, &X, &Y ) );
3421
3422 if( mbedtls_mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
3423 {
3424 if( verbose != 0 )
3425 mbedtls_printf( "failed at %d\n", i );
3426
3427 ret = 1;
3428 goto cleanup;
3429 }
3430 }
3431
3432 if( verbose != 0 )
3433 mbedtls_printf( "passed\n" );
3434
3435cleanup:
3436
3437 if( ret != 0 && verbose != 0 )
Jerome Forissier3602df82021-07-28 10:24:04 +02003438 mbedtls_printf( "Unexpected error, return code = %08X\n", (unsigned int) ret );
Jens Wiklander817466c2018-05-22 13:49:31 +02003439
3440 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N ); mbedtls_mpi_free( &X );
3441 mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &U ); mbedtls_mpi_free( &V );
3442
3443 if( verbose != 0 )
3444 mbedtls_printf( "\n" );
3445
3446 return( ret );
3447}
3448
3449#endif /* MBEDTLS_SELF_TEST */
3450
3451#endif /* MBEDTLS_BIGNUM_C */