1 /*
2 * Multi-precision integer library
3 *
4 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 */
7
8 /*
9 * The following sources were referenced in the design of this Multi-precision
10 * Integer library:
11 *
12 * [1] Handbook of Applied Cryptography - 1997
13 * Menezes, van Oorschot and Vanstone
14 *
15 * [2] Multi-Precision Math
16 * Tom St Denis
17 * https://github.com/libtom/libtommath/blob/develop/tommath.pdf
18 *
19 * [3] GNU Multi-Precision Arithmetic Library
20 * https://gmplib.org/manual/index.html
21 *
22 */
23
24 #include "common.h"
25
26 #if defined(MBEDTLS_BIGNUM_C)
27
28 #include "mbedtls/bignum.h"
29 #include "bignum_core.h"
30 #include "bignum_internal.h"
31 #include "bn_mul.h"
32 #include "mbedtls/platform_util.h"
33 #include "mbedtls/error.h"
34 #include "constant_time_internal.h"
35
36 #include <limits.h>
37 #include <string.h>
38
39 #include "mbedtls/platform.h"
40
41
42
43 /*
44 * Conditionally select an MPI sign in constant time.
45 * (MPI sign is the field s in mbedtls_mpi. It is unsigned short and only 1 and -1 are valid
46 * values.)
47 */
mbedtls_ct_mpi_sign_if(mbedtls_ct_condition_t cond,signed short sign1,signed short sign2)48 static inline signed short mbedtls_ct_mpi_sign_if(mbedtls_ct_condition_t cond,
49 signed short sign1, signed short sign2)
50 {
51 return (signed short) mbedtls_ct_uint_if(cond, sign1 + 1, sign2 + 1) - 1;
52 }
53
54 /*
55 * Compare signed values in constant time
56 */
mbedtls_mpi_lt_mpi_ct(const mbedtls_mpi * X,const mbedtls_mpi * Y,unsigned * ret)57 int mbedtls_mpi_lt_mpi_ct(const mbedtls_mpi *X,
58 const mbedtls_mpi *Y,
59 unsigned *ret)
60 {
61 mbedtls_ct_condition_t different_sign, X_is_negative, Y_is_negative, result;
62
63 if (X->n != Y->n) {
64 return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
65 }
66
67 /*
68 * Set N_is_negative to MBEDTLS_CT_FALSE if N >= 0, MBEDTLS_CT_TRUE if N < 0.
69 * We know that N->s == 1 if N >= 0 and N->s == -1 if N < 0.
70 */
71 X_is_negative = mbedtls_ct_bool((X->s & 2) >> 1);
72 Y_is_negative = mbedtls_ct_bool((Y->s & 2) >> 1);
73
74 /*
75 * If the signs are different, then the positive operand is the bigger.
76 * That is if X is negative (X_is_negative == 1), then X < Y is true and it
77 * is false if X is positive (X_is_negative == 0).
78 */
79 different_sign = mbedtls_ct_bool_ne(X_is_negative, Y_is_negative); // true if different sign
80 result = mbedtls_ct_bool_and(different_sign, X_is_negative);
81
82 /*
83 * Assuming signs are the same, compare X and Y. We switch the comparison
84 * order if they are negative so that we get the right result, regardles of
85 * sign.
86 */
87
88 /* This array is used to conditionally swap the pointers in const time */
89 void * const p[2] = { X->p, Y->p };
90 size_t i = mbedtls_ct_size_if_else_0(X_is_negative, 1);
91 mbedtls_ct_condition_t lt = mbedtls_mpi_core_lt_ct(p[i], p[i ^ 1], X->n);
92
93 /*
94 * Store in result iff the signs are the same (i.e., iff different_sign == false). If
95 * the signs differ, result has already been set, so we don't change it.
96 */
97 result = mbedtls_ct_bool_or(result,
98 mbedtls_ct_bool_and(mbedtls_ct_bool_not(different_sign), lt));
99
100 *ret = mbedtls_ct_uint_if_else_0(result, 1);
101
102 return 0;
103 }
104
105 /*
106 * Conditionally assign X = Y, without leaking information
107 * about whether the assignment was made or not.
108 * (Leaking information about the respective sizes of X and Y is ok however.)
109 */
110 #if defined(_MSC_VER) && defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64) && \
111 (_MSC_FULL_VER < 193131103)
112 /*
113 * MSVC miscompiles this function if it's inlined prior to Visual Studio 2022 version 17.1. See:
114 * https://developercommunity.visualstudio.com/t/c-compiler-miscompiles-part-of-mbedtls-library-on/1646989
115 */
116 __declspec(noinline)
117 #endif
mbedtls_mpi_safe_cond_assign(mbedtls_mpi * X,const mbedtls_mpi * Y,unsigned char assign)118 int mbedtls_mpi_safe_cond_assign(mbedtls_mpi *X,
119 const mbedtls_mpi *Y,
120 unsigned char assign)
121 {
122 int ret = 0;
123
124 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, Y->n));
125
126 {
127 mbedtls_ct_condition_t do_assign = mbedtls_ct_bool(assign);
128
129 X->s = mbedtls_ct_mpi_sign_if(do_assign, Y->s, X->s);
130
131 mbedtls_mpi_core_cond_assign(X->p, Y->p, Y->n, do_assign);
132
133 mbedtls_ct_condition_t do_not_assign = mbedtls_ct_bool_not(do_assign);
134 for (size_t i = Y->n; i < X->n; i++) {
135 X->p[i] = mbedtls_ct_mpi_uint_if_else_0(do_not_assign, X->p[i]);
136 }
137 }
138
139 cleanup:
140 return ret;
141 }
142
143 /*
144 * Conditionally swap X and Y, without leaking information
145 * about whether the swap was made or not.
146 * Here it is not ok to simply swap the pointers, which would lead to
147 * different memory access patterns when X and Y are used afterwards.
148 */
mbedtls_mpi_safe_cond_swap(mbedtls_mpi * X,mbedtls_mpi * Y,unsigned char swap)149 int mbedtls_mpi_safe_cond_swap(mbedtls_mpi *X,
150 mbedtls_mpi *Y,
151 unsigned char swap)
152 {
153 int ret = 0;
154 int s;
155
156 if (X == Y) {
157 return 0;
158 }
159
160 mbedtls_ct_condition_t do_swap = mbedtls_ct_bool(swap);
161
162 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, Y->n));
163 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(Y, X->n));
164
165 s = X->s;
166 X->s = mbedtls_ct_mpi_sign_if(do_swap, Y->s, X->s);
167 Y->s = mbedtls_ct_mpi_sign_if(do_swap, s, Y->s);
168
169 mbedtls_mpi_core_cond_swap(X->p, Y->p, X->n, do_swap);
170
171 cleanup:
172 return ret;
173 }
174
175 /* Implementation that should never be optimized out by the compiler */
176 #define mbedtls_mpi_zeroize_and_free(v, n) mbedtls_zeroize_and_free(v, ciL * (n))
177
178 /*
179 * Initialize one MPI
180 */
mbedtls_mpi_init(mbedtls_mpi * X)181 void mbedtls_mpi_init(mbedtls_mpi *X)
182 {
183 X->s = 1;
184 X->n = 0;
185 X->p = NULL;
186 }
187
188 /*
189 * Unallocate one MPI
190 */
mbedtls_mpi_free(mbedtls_mpi * X)191 void mbedtls_mpi_free(mbedtls_mpi *X)
192 {
193 if (X == NULL) {
194 return;
195 }
196
197 if (X->p != NULL) {
198 mbedtls_mpi_zeroize_and_free(X->p, X->n);
199 }
200
201 X->s = 1;
202 X->n = 0;
203 X->p = NULL;
204 }
205
206 /*
207 * Enlarge to the specified number of limbs
208 */
mbedtls_mpi_grow(mbedtls_mpi * X,size_t nblimbs)209 int mbedtls_mpi_grow(mbedtls_mpi *X, size_t nblimbs)
210 {
211 mbedtls_mpi_uint *p;
212
213 if (nblimbs > MBEDTLS_MPI_MAX_LIMBS) {
214 return MBEDTLS_ERR_MPI_ALLOC_FAILED;
215 }
216
217 if (X->n < nblimbs) {
218 if ((p = (mbedtls_mpi_uint *) mbedtls_calloc(nblimbs, ciL)) == NULL) {
219 return MBEDTLS_ERR_MPI_ALLOC_FAILED;
220 }
221
222 if (X->p != NULL) {
223 memcpy(p, X->p, X->n * ciL);
224 mbedtls_mpi_zeroize_and_free(X->p, X->n);
225 }
226
227 /* nblimbs fits in n because we ensure that MBEDTLS_MPI_MAX_LIMBS
228 * fits, and we've checked that nblimbs <= MBEDTLS_MPI_MAX_LIMBS. */
229 X->n = (unsigned short) nblimbs;
230 X->p = p;
231 }
232
233 return 0;
234 }
235
236 /*
237 * Resize down as much as possible,
238 * while keeping at least the specified number of limbs
239 */
mbedtls_mpi_shrink(mbedtls_mpi * X,size_t nblimbs)240 int mbedtls_mpi_shrink(mbedtls_mpi *X, size_t nblimbs)
241 {
242 mbedtls_mpi_uint *p;
243 size_t i;
244
245 if (nblimbs > MBEDTLS_MPI_MAX_LIMBS) {
246 return MBEDTLS_ERR_MPI_ALLOC_FAILED;
247 }
248
249 /* Actually resize up if there are currently fewer than nblimbs limbs. */
250 if (X->n <= nblimbs) {
251 return mbedtls_mpi_grow(X, nblimbs);
252 }
253 /* After this point, then X->n > nblimbs and in particular X->n > 0. */
254
255 for (i = X->n - 1; i > 0; i--) {
256 if (X->p[i] != 0) {
257 break;
258 }
259 }
260 i++;
261
262 if (i < nblimbs) {
263 i = nblimbs;
264 }
265
266 if ((p = (mbedtls_mpi_uint *) mbedtls_calloc(i, ciL)) == NULL) {
267 return MBEDTLS_ERR_MPI_ALLOC_FAILED;
268 }
269
270 if (X->p != NULL) {
271 memcpy(p, X->p, i * ciL);
272 mbedtls_mpi_zeroize_and_free(X->p, X->n);
273 }
274
275 /* i fits in n because we ensure that MBEDTLS_MPI_MAX_LIMBS
276 * fits, and we've checked that i <= nblimbs <= MBEDTLS_MPI_MAX_LIMBS. */
277 X->n = (unsigned short) i;
278 X->p = p;
279
280 return 0;
281 }
282
283 /* Resize X to have exactly n limbs and set it to 0. */
mbedtls_mpi_resize_clear(mbedtls_mpi * X,size_t limbs)284 static int mbedtls_mpi_resize_clear(mbedtls_mpi *X, size_t limbs)
285 {
286 if (limbs == 0) {
287 mbedtls_mpi_free(X);
288 return 0;
289 } else if (X->n == limbs) {
290 memset(X->p, 0, limbs * ciL);
291 X->s = 1;
292 return 0;
293 } else {
294 mbedtls_mpi_free(X);
295 return mbedtls_mpi_grow(X, limbs);
296 }
297 }
298
299 /*
300 * Copy the contents of Y into X.
301 *
302 * This function is not constant-time. Leading zeros in Y may be removed.
303 *
304 * Ensure that X does not shrink. This is not guaranteed by the public API,
305 * but some code in the bignum module might still rely on this property.
306 */
mbedtls_mpi_copy(mbedtls_mpi * X,const mbedtls_mpi * Y)307 int mbedtls_mpi_copy(mbedtls_mpi *X, const mbedtls_mpi *Y)
308 {
309 int ret = 0;
310 size_t i;
311
312 if (X == Y) {
313 return 0;
314 }
315
316 if (Y->n == 0) {
317 if (X->n != 0) {
318 X->s = 1;
319 memset(X->p, 0, X->n * ciL);
320 }
321 return 0;
322 }
323
324 for (i = Y->n - 1; i > 0; i--) {
325 if (Y->p[i] != 0) {
326 break;
327 }
328 }
329 i++;
330
331 X->s = Y->s;
332
333 if (X->n < i) {
334 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, i));
335 } else {
336 memset(X->p + i, 0, (X->n - i) * ciL);
337 }
338
339 memcpy(X->p, Y->p, i * ciL);
340
341 cleanup:
342
343 return ret;
344 }
345
346 /*
347 * Swap the contents of X and Y
348 */
mbedtls_mpi_swap(mbedtls_mpi * X,mbedtls_mpi * Y)349 void mbedtls_mpi_swap(mbedtls_mpi *X, mbedtls_mpi *Y)
350 {
351 mbedtls_mpi T;
352
353 memcpy(&T, X, sizeof(mbedtls_mpi));
354 memcpy(X, Y, sizeof(mbedtls_mpi));
355 memcpy(Y, &T, sizeof(mbedtls_mpi));
356 }
357
mpi_sint_abs(mbedtls_mpi_sint z)358 static inline mbedtls_mpi_uint mpi_sint_abs(mbedtls_mpi_sint z)
359 {
360 if (z >= 0) {
361 return z;
362 }
363 /* Take care to handle the most negative value (-2^(biL-1)) correctly.
364 * A naive -z would have undefined behavior.
365 * Write this in a way that makes popular compilers happy (GCC, Clang,
366 * MSVC). */
367 return (mbedtls_mpi_uint) 0 - (mbedtls_mpi_uint) z;
368 }
369
370 /* Convert x to a sign, i.e. to 1, if x is positive, or -1, if x is negative.
371 * This looks awkward but generates smaller code than (x < 0 ? -1 : 1) */
372 #define TO_SIGN(x) ((mbedtls_mpi_sint) (((mbedtls_mpi_uint) x) >> (biL - 1)) * -2 + 1)
373
374 /*
375 * Set value from integer
376 */
mbedtls_mpi_lset(mbedtls_mpi * X,mbedtls_mpi_sint z)377 int mbedtls_mpi_lset(mbedtls_mpi *X, mbedtls_mpi_sint z)
378 {
379 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
380
381 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, 1));
382 memset(X->p, 0, X->n * ciL);
383
384 X->p[0] = mpi_sint_abs(z);
385 X->s = TO_SIGN(z);
386
387 cleanup:
388
389 return ret;
390 }
391
392 /*
393 * Get a specific bit
394 */
mbedtls_mpi_get_bit(const mbedtls_mpi * X,size_t pos)395 int mbedtls_mpi_get_bit(const mbedtls_mpi *X, size_t pos)
396 {
397 if (X->n * biL <= pos) {
398 return 0;
399 }
400
401 return (X->p[pos / biL] >> (pos % biL)) & 0x01;
402 }
403
404 /*
405 * Set a bit to a specific value of 0 or 1
406 */
mbedtls_mpi_set_bit(mbedtls_mpi * X,size_t pos,unsigned char val)407 int mbedtls_mpi_set_bit(mbedtls_mpi *X, size_t pos, unsigned char val)
408 {
409 int ret = 0;
410 size_t off = pos / biL;
411 size_t idx = pos % biL;
412
413 if (val != 0 && val != 1) {
414 return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
415 }
416
417 if (X->n * biL <= pos) {
418 if (val == 0) {
419 return 0;
420 }
421
422 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, off + 1));
423 }
424
425 X->p[off] &= ~((mbedtls_mpi_uint) 0x01 << idx);
426 X->p[off] |= (mbedtls_mpi_uint) val << idx;
427
428 cleanup:
429
430 return ret;
431 }
432
433 /*
434 * Return the number of less significant zero-bits
435 */
mbedtls_mpi_lsb(const mbedtls_mpi * X)436 size_t mbedtls_mpi_lsb(const mbedtls_mpi *X)
437 {
438 size_t i;
439
440 #if defined(__has_builtin)
441 #if (MBEDTLS_MPI_UINT_MAX == UINT_MAX) && __has_builtin(__builtin_ctz)
442 #define mbedtls_mpi_uint_ctz __builtin_ctz
443 #elif (MBEDTLS_MPI_UINT_MAX == ULONG_MAX) && __has_builtin(__builtin_ctzl)
444 #define mbedtls_mpi_uint_ctz __builtin_ctzl
445 #elif (MBEDTLS_MPI_UINT_MAX == ULLONG_MAX) && __has_builtin(__builtin_ctzll)
446 #define mbedtls_mpi_uint_ctz __builtin_ctzll
447 #endif
448 #endif
449
450 #if defined(mbedtls_mpi_uint_ctz)
451 for (i = 0; i < X->n; i++) {
452 if (X->p[i] != 0) {
453 return i * biL + mbedtls_mpi_uint_ctz(X->p[i]);
454 }
455 }
456 #else
457 size_t count = 0;
458 for (i = 0; i < X->n; i++) {
459 for (size_t j = 0; j < biL; j++, count++) {
460 if (((X->p[i] >> j) & 1) != 0) {
461 return count;
462 }
463 }
464 }
465 #endif
466
467 return 0;
468 }
469
470 /*
471 * Return the number of bits
472 */
mbedtls_mpi_bitlen(const mbedtls_mpi * X)473 size_t mbedtls_mpi_bitlen(const mbedtls_mpi *X)
474 {
475 return mbedtls_mpi_core_bitlen(X->p, X->n);
476 }
477
478 /*
479 * Return the total size in bytes
480 */
mbedtls_mpi_size(const mbedtls_mpi * X)481 size_t mbedtls_mpi_size(const mbedtls_mpi *X)
482 {
483 return (mbedtls_mpi_bitlen(X) + 7) >> 3;
484 }
485
486 /*
487 * Convert an ASCII character to digit value
488 */
mpi_get_digit(mbedtls_mpi_uint * d,int radix,char c)489 static int mpi_get_digit(mbedtls_mpi_uint *d, int radix, char c)
490 {
491 *d = 255;
492
493 if (c >= 0x30 && c <= 0x39) {
494 *d = c - 0x30;
495 }
496 if (c >= 0x41 && c <= 0x46) {
497 *d = c - 0x37;
498 }
499 if (c >= 0x61 && c <= 0x66) {
500 *d = c - 0x57;
501 }
502
503 if (*d >= (mbedtls_mpi_uint) radix) {
504 return MBEDTLS_ERR_MPI_INVALID_CHARACTER;
505 }
506
507 return 0;
508 }
509
510 /*
511 * Import from an ASCII string
512 */
mbedtls_mpi_read_string(mbedtls_mpi * X,int radix,const char * s)513 int mbedtls_mpi_read_string(mbedtls_mpi *X, int radix, const char *s)
514 {
515 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
516 size_t i, j, slen, n;
517 int sign = 1;
518 mbedtls_mpi_uint d;
519 mbedtls_mpi T;
520
521 if (radix < 2 || radix > 16) {
522 return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
523 }
524
525 mbedtls_mpi_init(&T);
526
527 if (s[0] == 0) {
528 mbedtls_mpi_free(X);
529 return 0;
530 }
531
532 if (s[0] == '-') {
533 ++s;
534 sign = -1;
535 }
536
537 slen = strlen(s);
538
539 if (radix == 16) {
540 if (slen > SIZE_MAX >> 2) {
541 return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
542 }
543
544 n = BITS_TO_LIMBS(slen << 2);
545
546 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, n));
547 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 0));
548
549 for (i = slen, j = 0; i > 0; i--, j++) {
550 MBEDTLS_MPI_CHK(mpi_get_digit(&d, radix, s[i - 1]));
551 X->p[j / (2 * ciL)] |= d << ((j % (2 * ciL)) << 2);
552 }
553 } else {
554 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 0));
555
556 for (i = 0; i < slen; i++) {
557 MBEDTLS_MPI_CHK(mpi_get_digit(&d, radix, s[i]));
558 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(&T, X, radix));
559 MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, &T, d));
560 }
561 }
562
563 if (sign < 0 && mbedtls_mpi_bitlen(X) != 0) {
564 X->s = -1;
565 }
566
567 cleanup:
568
569 mbedtls_mpi_free(&T);
570
571 return ret;
572 }
573
574 /*
575 * Helper to write the digits high-order first.
576 */
mpi_write_hlp(mbedtls_mpi * X,int radix,char ** p,const size_t buflen)577 static int mpi_write_hlp(mbedtls_mpi *X, int radix,
578 char **p, const size_t buflen)
579 {
580 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
581 mbedtls_mpi_uint r;
582 size_t length = 0;
583 char *p_end = *p + buflen;
584
585 do {
586 if (length >= buflen) {
587 return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL;
588 }
589
590 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_int(&r, X, radix));
591 MBEDTLS_MPI_CHK(mbedtls_mpi_div_int(X, NULL, X, radix));
592 /*
593 * Write the residue in the current position, as an ASCII character.
594 */
595 if (r < 0xA) {
596 *(--p_end) = (char) ('0' + r);
597 } else {
598 *(--p_end) = (char) ('A' + (r - 0xA));
599 }
600
601 length++;
602 } while (mbedtls_mpi_cmp_int(X, 0) != 0);
603
604 memmove(*p, p_end, length);
605 *p += length;
606
607 cleanup:
608
609 return ret;
610 }
611
612 /*
613 * Export into an ASCII string
614 */
mbedtls_mpi_write_string(const mbedtls_mpi * X,int radix,char * buf,size_t buflen,size_t * olen)615 int mbedtls_mpi_write_string(const mbedtls_mpi *X, int radix,
616 char *buf, size_t buflen, size_t *olen)
617 {
618 int ret = 0;
619 size_t n;
620 char *p;
621 mbedtls_mpi T;
622
623 if (radix < 2 || radix > 16) {
624 return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
625 }
626
627 n = mbedtls_mpi_bitlen(X); /* Number of bits necessary to present `n`. */
628 if (radix >= 4) {
629 n >>= 1; /* Number of 4-adic digits necessary to present
630 * `n`. If radix > 4, this might be a strict
631 * overapproximation of the number of
632 * radix-adic digits needed to present `n`. */
633 }
634 if (radix >= 16) {
635 n >>= 1; /* Number of hexadecimal digits necessary to
636 * present `n`. */
637
638 }
639 n += 1; /* Terminating null byte */
640 n += 1; /* Compensate for the divisions above, which round down `n`
641 * in case it's not even. */
642 n += 1; /* Potential '-'-sign. */
643 n += (n & 1); /* Make n even to have enough space for hexadecimal writing,
644 * which always uses an even number of hex-digits. */
645
646 if (buflen < n) {
647 *olen = n;
648 return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL;
649 }
650
651 p = buf;
652 mbedtls_mpi_init(&T);
653
654 if (X->s == -1) {
655 *p++ = '-';
656 buflen--;
657 }
658
659 if (radix == 16) {
660 int c;
661 size_t i, j, k;
662
663 for (i = X->n, k = 0; i > 0; i--) {
664 for (j = ciL; j > 0; j--) {
665 c = (X->p[i - 1] >> ((j - 1) << 3)) & 0xFF;
666
667 if (c == 0 && k == 0 && (i + j) != 2) {
668 continue;
669 }
670
671 *(p++) = "0123456789ABCDEF" [c / 16];
672 *(p++) = "0123456789ABCDEF" [c % 16];
673 k = 1;
674 }
675 }
676 } else {
677 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&T, X));
678
679 if (T.s == -1) {
680 T.s = 1;
681 }
682
683 MBEDTLS_MPI_CHK(mpi_write_hlp(&T, radix, &p, buflen));
684 }
685
686 *p++ = '\0';
687 *olen = (size_t) (p - buf);
688
689 cleanup:
690
691 mbedtls_mpi_free(&T);
692
693 return ret;
694 }
695
696 #if defined(MBEDTLS_FS_IO)
697 /*
698 * Read X from an opened file
699 */
mbedtls_mpi_read_file(mbedtls_mpi * X,int radix,FILE * fin)700 int mbedtls_mpi_read_file(mbedtls_mpi *X, int radix, FILE *fin)
701 {
702 mbedtls_mpi_uint d;
703 size_t slen;
704 char *p;
705 /*
706 * Buffer should have space for (short) label and decimal formatted MPI,
707 * newline characters and '\0'
708 */
709 char s[MBEDTLS_MPI_RW_BUFFER_SIZE];
710
711 if (radix < 2 || radix > 16) {
712 return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
713 }
714
715 memset(s, 0, sizeof(s));
716 if (fgets(s, sizeof(s) - 1, fin) == NULL) {
717 return MBEDTLS_ERR_MPI_FILE_IO_ERROR;
718 }
719
720 slen = strlen(s);
721 if (slen == sizeof(s) - 2) {
722 return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL;
723 }
724
725 if (slen > 0 && s[slen - 1] == '\n') {
726 slen--; s[slen] = '\0';
727 }
728 if (slen > 0 && s[slen - 1] == '\r') {
729 slen--; s[slen] = '\0';
730 }
731
732 p = s + slen;
733 while (p-- > s) {
734 if (mpi_get_digit(&d, radix, *p) != 0) {
735 break;
736 }
737 }
738
739 return mbedtls_mpi_read_string(X, radix, p + 1);
740 }
741
742 /*
743 * Write X into an opened file (or stdout if fout == NULL)
744 */
mbedtls_mpi_write_file(const char * p,const mbedtls_mpi * X,int radix,FILE * fout)745 int mbedtls_mpi_write_file(const char *p, const mbedtls_mpi *X, int radix, FILE *fout)
746 {
747 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
748 size_t n, slen, plen;
749 /*
750 * Buffer should have space for (short) label and decimal formatted MPI,
751 * newline characters and '\0'
752 */
753 char s[MBEDTLS_MPI_RW_BUFFER_SIZE];
754
755 if (radix < 2 || radix > 16) {
756 return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
757 }
758
759 memset(s, 0, sizeof(s));
760
761 MBEDTLS_MPI_CHK(mbedtls_mpi_write_string(X, radix, s, sizeof(s) - 2, &n));
762
763 if (p == NULL) {
764 p = "";
765 }
766
767 plen = strlen(p);
768 slen = strlen(s);
769 s[slen++] = '\r';
770 s[slen++] = '\n';
771
772 if (fout != NULL) {
773 if (fwrite(p, 1, plen, fout) != plen ||
774 fwrite(s, 1, slen, fout) != slen) {
775 return MBEDTLS_ERR_MPI_FILE_IO_ERROR;
776 }
777 } else {
778 mbedtls_printf("%s%s", p, s);
779 }
780
781 cleanup:
782
783 return ret;
784 }
785 #endif /* MBEDTLS_FS_IO */
786
787 /*
788 * Import X from unsigned binary data, little endian
789 *
790 * This function is guaranteed to return an MPI with exactly the necessary
791 * number of limbs (in particular, it does not skip 0s in the input).
792 */
mbedtls_mpi_read_binary_le(mbedtls_mpi * X,const unsigned char * buf,size_t buflen)793 int mbedtls_mpi_read_binary_le(mbedtls_mpi *X,
794 const unsigned char *buf, size_t buflen)
795 {
796 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
797 const size_t limbs = CHARS_TO_LIMBS(buflen);
798
799 /* Ensure that target MPI has exactly the necessary number of limbs */
800 MBEDTLS_MPI_CHK(mbedtls_mpi_resize_clear(X, limbs));
801
802 MBEDTLS_MPI_CHK(mbedtls_mpi_core_read_le(X->p, X->n, buf, buflen));
803
804 cleanup:
805
806 /*
807 * This function is also used to import keys. However, wiping the buffers
808 * upon failure is not necessary because failure only can happen before any
809 * input is copied.
810 */
811 return ret;
812 }
813
814 /*
815 * Import X from unsigned binary data, big endian
816 *
817 * This function is guaranteed to return an MPI with exactly the necessary
818 * number of limbs (in particular, it does not skip 0s in the input).
819 */
mbedtls_mpi_read_binary(mbedtls_mpi * X,const unsigned char * buf,size_t buflen)820 int mbedtls_mpi_read_binary(mbedtls_mpi *X, const unsigned char *buf, size_t buflen)
821 {
822 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
823 const size_t limbs = CHARS_TO_LIMBS(buflen);
824
825 /* Ensure that target MPI has exactly the necessary number of limbs */
826 MBEDTLS_MPI_CHK(mbedtls_mpi_resize_clear(X, limbs));
827
828 MBEDTLS_MPI_CHK(mbedtls_mpi_core_read_be(X->p, X->n, buf, buflen));
829
830 cleanup:
831
832 /*
833 * This function is also used to import keys. However, wiping the buffers
834 * upon failure is not necessary because failure only can happen before any
835 * input is copied.
836 */
837 return ret;
838 }
839
840 /*
841 * Export X into unsigned binary data, little endian
842 */
mbedtls_mpi_write_binary_le(const mbedtls_mpi * X,unsigned char * buf,size_t buflen)843 int mbedtls_mpi_write_binary_le(const mbedtls_mpi *X,
844 unsigned char *buf, size_t buflen)
845 {
846 return mbedtls_mpi_core_write_le(X->p, X->n, buf, buflen);
847 }
848
849 /*
850 * Export X into unsigned binary data, big endian
851 */
mbedtls_mpi_write_binary(const mbedtls_mpi * X,unsigned char * buf,size_t buflen)852 int mbedtls_mpi_write_binary(const mbedtls_mpi *X,
853 unsigned char *buf, size_t buflen)
854 {
855 return mbedtls_mpi_core_write_be(X->p, X->n, buf, buflen);
856 }
857
858 /*
859 * Left-shift: X <<= count
860 */
mbedtls_mpi_shift_l(mbedtls_mpi * X,size_t count)861 int mbedtls_mpi_shift_l(mbedtls_mpi *X, size_t count)
862 {
863 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
864 size_t i;
865
866 i = mbedtls_mpi_bitlen(X) + count;
867
868 if (X->n * biL < i) {
869 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, BITS_TO_LIMBS(i)));
870 }
871
872 ret = 0;
873
874 mbedtls_mpi_core_shift_l(X->p, X->n, count);
875 cleanup:
876
877 return ret;
878 }
879
880 /*
881 * Right-shift: X >>= count
882 */
mbedtls_mpi_shift_r(mbedtls_mpi * X,size_t count)883 int mbedtls_mpi_shift_r(mbedtls_mpi *X, size_t count)
884 {
885 if (X->n != 0) {
886 mbedtls_mpi_core_shift_r(X->p, X->n, count);
887 }
888 return 0;
889 }
890
891 /*
892 * Compare unsigned values
893 */
mbedtls_mpi_cmp_abs(const mbedtls_mpi * X,const mbedtls_mpi * Y)894 int mbedtls_mpi_cmp_abs(const mbedtls_mpi *X, const mbedtls_mpi *Y)
895 {
896 size_t i, j;
897
898 for (i = X->n; i > 0; i--) {
899 if (X->p[i - 1] != 0) {
900 break;
901 }
902 }
903
904 for (j = Y->n; j > 0; j--) {
905 if (Y->p[j - 1] != 0) {
906 break;
907 }
908 }
909
910 /* If i == j == 0, i.e. abs(X) == abs(Y),
911 * we end up returning 0 at the end of the function. */
912
913 if (i > j) {
914 return 1;
915 }
916 if (j > i) {
917 return -1;
918 }
919
920 for (; i > 0; i--) {
921 if (X->p[i - 1] > Y->p[i - 1]) {
922 return 1;
923 }
924 if (X->p[i - 1] < Y->p[i - 1]) {
925 return -1;
926 }
927 }
928
929 return 0;
930 }
931
932 /*
933 * Compare signed values
934 */
mbedtls_mpi_cmp_mpi(const mbedtls_mpi * X,const mbedtls_mpi * Y)935 int mbedtls_mpi_cmp_mpi(const mbedtls_mpi *X, const mbedtls_mpi *Y)
936 {
937 size_t i, j;
938
939 for (i = X->n; i > 0; i--) {
940 if (X->p[i - 1] != 0) {
941 break;
942 }
943 }
944
945 for (j = Y->n; j > 0; j--) {
946 if (Y->p[j - 1] != 0) {
947 break;
948 }
949 }
950
951 if (i == 0 && j == 0) {
952 return 0;
953 }
954
955 if (i > j) {
956 return X->s;
957 }
958 if (j > i) {
959 return -Y->s;
960 }
961
962 if (X->s > 0 && Y->s < 0) {
963 return 1;
964 }
965 if (Y->s > 0 && X->s < 0) {
966 return -1;
967 }
968
969 for (; i > 0; i--) {
970 if (X->p[i - 1] > Y->p[i - 1]) {
971 return X->s;
972 }
973 if (X->p[i - 1] < Y->p[i - 1]) {
974 return -X->s;
975 }
976 }
977
978 return 0;
979 }
980
981 /*
982 * Compare signed values
983 */
mbedtls_mpi_cmp_int(const mbedtls_mpi * X,mbedtls_mpi_sint z)984 int mbedtls_mpi_cmp_int(const mbedtls_mpi *X, mbedtls_mpi_sint z)
985 {
986 mbedtls_mpi Y;
987 mbedtls_mpi_uint p[1];
988
989 *p = mpi_sint_abs(z);
990 Y.s = TO_SIGN(z);
991 Y.n = 1;
992 Y.p = p;
993
994 return mbedtls_mpi_cmp_mpi(X, &Y);
995 }
996
997 /*
998 * Unsigned addition: X = |A| + |B| (HAC 14.7)
999 */
mbedtls_mpi_add_abs(mbedtls_mpi * X,const mbedtls_mpi * A,const mbedtls_mpi * B)1000 int mbedtls_mpi_add_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
1001 {
1002 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1003 size_t j;
1004 mbedtls_mpi_uint *p;
1005 mbedtls_mpi_uint c;
1006
1007 if (X == B) {
1008 const mbedtls_mpi *T = A; A = X; B = T;
1009 }
1010
1011 if (X != A) {
1012 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A));
1013 }
1014
1015 /*
1016 * X must always be positive as a result of unsigned additions.
1017 */
1018 X->s = 1;
1019
1020 for (j = B->n; j > 0; j--) {
1021 if (B->p[j - 1] != 0) {
1022 break;
1023 }
1024 }
1025
1026 /* Exit early to avoid undefined behavior on NULL+0 when X->n == 0
1027 * and B is 0 (of any size). */
1028 if (j == 0) {
1029 return 0;
1030 }
1031
1032 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, j));
1033
1034 /* j is the number of non-zero limbs of B. Add those to X. */
1035
1036 p = X->p;
1037
1038 c = mbedtls_mpi_core_add(p, p, B->p, j);
1039
1040 p += j;
1041
1042 /* Now propagate any carry */
1043
1044 while (c != 0) {
1045 if (j >= X->n) {
1046 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, j + 1));
1047 p = X->p + j;
1048 }
1049
1050 *p += c; c = (*p < c); j++; p++;
1051 }
1052
1053 cleanup:
1054
1055 return ret;
1056 }
1057
1058 /*
1059 * Unsigned subtraction: X = |A| - |B| (HAC 14.9, 14.10)
1060 */
mbedtls_mpi_sub_abs(mbedtls_mpi * X,const mbedtls_mpi * A,const mbedtls_mpi * B)1061 int mbedtls_mpi_sub_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
1062 {
1063 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1064 size_t n;
1065 mbedtls_mpi_uint carry;
1066
1067 for (n = B->n; n > 0; n--) {
1068 if (B->p[n - 1] != 0) {
1069 break;
1070 }
1071 }
1072 if (n > A->n) {
1073 /* B >= (2^ciL)^n > A */
1074 ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
1075 goto cleanup;
1076 }
1077
1078 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, A->n));
1079
1080 /* Set the high limbs of X to match A. Don't touch the lower limbs
1081 * because X might be aliased to B, and we must not overwrite the
1082 * significant digits of B. */
1083 if (A->n > n && A != X) {
1084 memcpy(X->p + n, A->p + n, (A->n - n) * ciL);
1085 }
1086 if (X->n > A->n) {
1087 memset(X->p + A->n, 0, (X->n - A->n) * ciL);
1088 }
1089
1090 carry = mbedtls_mpi_core_sub(X->p, A->p, B->p, n);
1091 if (carry != 0) {
1092 /* Propagate the carry through the rest of X. */
1093 carry = mbedtls_mpi_core_sub_int(X->p + n, X->p + n, carry, X->n - n);
1094
1095 /* If we have further carry/borrow, the result is negative. */
1096 if (carry != 0) {
1097 ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
1098 goto cleanup;
1099 }
1100 }
1101
1102 /* X should always be positive as a result of unsigned subtractions. */
1103 X->s = 1;
1104
1105 cleanup:
1106 return ret;
1107 }
1108
1109 /* Common function for signed addition and subtraction.
1110 * Calculate A + B * flip_B where flip_B is 1 or -1.
1111 */
add_sub_mpi(mbedtls_mpi * X,const mbedtls_mpi * A,const mbedtls_mpi * B,int flip_B)1112 static int add_sub_mpi(mbedtls_mpi *X,
1113 const mbedtls_mpi *A, const mbedtls_mpi *B,
1114 int flip_B)
1115 {
1116 int ret, s;
1117
1118 s = A->s;
1119 if (A->s * B->s * flip_B < 0) {
1120 int cmp = mbedtls_mpi_cmp_abs(A, B);
1121 if (cmp >= 0) {
1122 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(X, A, B));
1123 /* If |A| = |B|, the result is 0 and we must set the sign bit
1124 * to +1 regardless of which of A or B was negative. Otherwise,
1125 * since |A| > |B|, the sign is the sign of A. */
1126 X->s = cmp == 0 ? 1 : s;
1127 } else {
1128 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(X, B, A));
1129 /* Since |A| < |B|, the sign is the opposite of A. */
1130 X->s = -s;
1131 }
1132 } else {
1133 MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(X, A, B));
1134 X->s = s;
1135 }
1136
1137 cleanup:
1138
1139 return ret;
1140 }
1141
1142 /*
1143 * Signed addition: X = A + B
1144 */
mbedtls_mpi_add_mpi(mbedtls_mpi * X,const mbedtls_mpi * A,const mbedtls_mpi * B)1145 int mbedtls_mpi_add_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
1146 {
1147 return add_sub_mpi(X, A, B, 1);
1148 }
1149
1150 /*
1151 * Signed subtraction: X = A - B
1152 */
mbedtls_mpi_sub_mpi(mbedtls_mpi * X,const mbedtls_mpi * A,const mbedtls_mpi * B)1153 int mbedtls_mpi_sub_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
1154 {
1155 return add_sub_mpi(X, A, B, -1);
1156 }
1157
1158 /*
1159 * Signed addition: X = A + b
1160 */
mbedtls_mpi_add_int(mbedtls_mpi * X,const mbedtls_mpi * A,mbedtls_mpi_sint b)1161 int mbedtls_mpi_add_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b)
1162 {
1163 mbedtls_mpi B;
1164 mbedtls_mpi_uint p[1];
1165
1166 p[0] = mpi_sint_abs(b);
1167 B.s = TO_SIGN(b);
1168 B.n = 1;
1169 B.p = p;
1170
1171 return mbedtls_mpi_add_mpi(X, A, &B);
1172 }
1173
1174 /*
1175 * Signed subtraction: X = A - b
1176 */
mbedtls_mpi_sub_int(mbedtls_mpi * X,const mbedtls_mpi * A,mbedtls_mpi_sint b)1177 int mbedtls_mpi_sub_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b)
1178 {
1179 mbedtls_mpi B;
1180 mbedtls_mpi_uint p[1];
1181
1182 p[0] = mpi_sint_abs(b);
1183 B.s = TO_SIGN(b);
1184 B.n = 1;
1185 B.p = p;
1186
1187 return mbedtls_mpi_sub_mpi(X, A, &B);
1188 }
1189
1190 /*
1191 * Baseline multiplication: X = A * B (HAC 14.12)
1192 */
mbedtls_mpi_mul_mpi(mbedtls_mpi * X,const mbedtls_mpi * A,const mbedtls_mpi * B)1193 int mbedtls_mpi_mul_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
1194 {
1195 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1196 size_t i, j;
1197 mbedtls_mpi TA, TB;
1198 int result_is_zero = 0;
1199
1200 mbedtls_mpi_init(&TA);
1201 mbedtls_mpi_init(&TB);
1202
1203 if (X == A) {
1204 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TA, A)); A = &TA;
1205 }
1206 if (X == B) {
1207 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TB, B)); B = &TB;
1208 }
1209
1210 for (i = A->n; i > 0; i--) {
1211 if (A->p[i - 1] != 0) {
1212 break;
1213 }
1214 }
1215 if (i == 0) {
1216 result_is_zero = 1;
1217 }
1218
1219 for (j = B->n; j > 0; j--) {
1220 if (B->p[j - 1] != 0) {
1221 break;
1222 }
1223 }
1224 if (j == 0) {
1225 result_is_zero = 1;
1226 }
1227
1228 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, i + j));
1229 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 0));
1230
1231 mbedtls_mpi_core_mul(X->p, A->p, i, B->p, j);
1232
1233 /* If the result is 0, we don't shortcut the operation, which reduces
1234 * but does not eliminate side channels leaking the zero-ness. We do
1235 * need to take care to set the sign bit properly since the library does
1236 * not fully support an MPI object with a value of 0 and s == -1. */
1237 if (result_is_zero) {
1238 X->s = 1;
1239 } else {
1240 X->s = A->s * B->s;
1241 }
1242
1243 cleanup:
1244
1245 mbedtls_mpi_free(&TB); mbedtls_mpi_free(&TA);
1246
1247 return ret;
1248 }
1249
1250 /*
1251 * Baseline multiplication: X = A * b
1252 */
mbedtls_mpi_mul_int(mbedtls_mpi * X,const mbedtls_mpi * A,mbedtls_mpi_uint b)1253 int mbedtls_mpi_mul_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b)
1254 {
1255 size_t n = A->n;
1256 while (n > 0 && A->p[n - 1] == 0) {
1257 --n;
1258 }
1259
1260 /* The general method below doesn't work if b==0. */
1261 if (b == 0 || n == 0) {
1262 return mbedtls_mpi_lset(X, 0);
1263 }
1264
1265 /* Calculate A*b as A + A*(b-1) to take advantage of mbedtls_mpi_core_mla */
1266 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1267 /* In general, A * b requires 1 limb more than b. If
1268 * A->p[n - 1] * b / b == A->p[n - 1], then A * b fits in the same
1269 * number of limbs as A and the call to grow() is not required since
1270 * copy() will take care of the growth if needed. However, experimentally,
1271 * making the call to grow() unconditional causes slightly fewer
1272 * calls to calloc() in ECP code, presumably because it reuses the
1273 * same mpi for a while and this way the mpi is more likely to directly
1274 * grow to its final size.
1275 *
1276 * Note that calculating A*b as 0 + A*b doesn't work as-is because
1277 * A,X can be the same. */
1278 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, n + 1));
1279 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A));
1280 mbedtls_mpi_core_mla(X->p, X->n, A->p, n, b - 1);
1281
1282 cleanup:
1283 return ret;
1284 }
1285
1286 /*
1287 * Unsigned integer divide - double mbedtls_mpi_uint dividend, u1/u0, and
1288 * mbedtls_mpi_uint divisor, d
1289 */
mbedtls_int_div_int(mbedtls_mpi_uint u1,mbedtls_mpi_uint u0,mbedtls_mpi_uint d,mbedtls_mpi_uint * r)1290 static mbedtls_mpi_uint mbedtls_int_div_int(mbedtls_mpi_uint u1,
1291 mbedtls_mpi_uint u0,
1292 mbedtls_mpi_uint d,
1293 mbedtls_mpi_uint *r)
1294 {
1295 #if defined(MBEDTLS_HAVE_UDBL)
1296 mbedtls_t_udbl dividend, quotient;
1297 #else
1298 const mbedtls_mpi_uint radix = (mbedtls_mpi_uint) 1 << biH;
1299 const mbedtls_mpi_uint uint_halfword_mask = ((mbedtls_mpi_uint) 1 << biH) - 1;
1300 mbedtls_mpi_uint d0, d1, q0, q1, rAX, r0, quotient;
1301 mbedtls_mpi_uint u0_msw, u0_lsw;
1302 size_t s;
1303 #endif
1304
1305 /*
1306 * Check for overflow
1307 */
1308 if (0 == d || u1 >= d) {
1309 if (r != NULL) {
1310 *r = ~(mbedtls_mpi_uint) 0u;
1311 }
1312
1313 return ~(mbedtls_mpi_uint) 0u;
1314 }
1315
1316 #if defined(MBEDTLS_HAVE_UDBL)
1317 dividend = (mbedtls_t_udbl) u1 << biL;
1318 dividend |= (mbedtls_t_udbl) u0;
1319 quotient = dividend / d;
1320 if (quotient > ((mbedtls_t_udbl) 1 << biL) - 1) {
1321 quotient = ((mbedtls_t_udbl) 1 << biL) - 1;
1322 }
1323
1324 if (r != NULL) {
1325 *r = (mbedtls_mpi_uint) (dividend - (quotient * d));
1326 }
1327
1328 return (mbedtls_mpi_uint) quotient;
1329 #else
1330
1331 /*
1332 * Algorithm D, Section 4.3.1 - The Art of Computer Programming
1333 * Vol. 2 - Seminumerical Algorithms, Knuth
1334 */
1335
1336 /*
1337 * Normalize the divisor, d, and dividend, u0, u1
1338 */
1339 s = mbedtls_mpi_core_clz(d);
1340 d = d << s;
1341
1342 u1 = u1 << s;
1343 u1 |= (u0 >> (biL - s)) & (-(mbedtls_mpi_sint) s >> (biL - 1));
1344 u0 = u0 << s;
1345
1346 d1 = d >> biH;
1347 d0 = d & uint_halfword_mask;
1348
1349 u0_msw = u0 >> biH;
1350 u0_lsw = u0 & uint_halfword_mask;
1351
1352 /*
1353 * Find the first quotient and remainder
1354 */
1355 q1 = u1 / d1;
1356 r0 = u1 - d1 * q1;
1357
1358 while (q1 >= radix || (q1 * d0 > radix * r0 + u0_msw)) {
1359 q1 -= 1;
1360 r0 += d1;
1361
1362 if (r0 >= radix) {
1363 break;
1364 }
1365 }
1366
1367 rAX = (u1 * radix) + (u0_msw - q1 * d);
1368 q0 = rAX / d1;
1369 r0 = rAX - q0 * d1;
1370
1371 while (q0 >= radix || (q0 * d0 > radix * r0 + u0_lsw)) {
1372 q0 -= 1;
1373 r0 += d1;
1374
1375 if (r0 >= radix) {
1376 break;
1377 }
1378 }
1379
1380 if (r != NULL) {
1381 *r = (rAX * radix + u0_lsw - q0 * d) >> s;
1382 }
1383
1384 quotient = q1 * radix + q0;
1385
1386 return quotient;
1387 #endif
1388 }
1389
1390 /*
1391 * Division by mbedtls_mpi: A = Q * B + R (HAC 14.20)
1392 */
mbedtls_mpi_div_mpi(mbedtls_mpi * Q,mbedtls_mpi * R,const mbedtls_mpi * A,const mbedtls_mpi * B)1393 int mbedtls_mpi_div_mpi(mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
1394 const mbedtls_mpi *B)
1395 {
1396 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1397 size_t i, n, t, k;
1398 mbedtls_mpi X, Y, Z, T1, T2;
1399 mbedtls_mpi_uint TP2[3];
1400
1401 if (mbedtls_mpi_cmp_int(B, 0) == 0) {
1402 return MBEDTLS_ERR_MPI_DIVISION_BY_ZERO;
1403 }
1404
1405 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
1406 mbedtls_mpi_init(&T1);
1407 /*
1408 * Avoid dynamic memory allocations for constant-size T2.
1409 *
1410 * T2 is used for comparison only and the 3 limbs are assigned explicitly,
1411 * so nobody increase the size of the MPI and we're safe to use an on-stack
1412 * buffer.
1413 */
1414 T2.s = 1;
1415 T2.n = sizeof(TP2) / sizeof(*TP2);
1416 T2.p = TP2;
1417
1418 if (mbedtls_mpi_cmp_abs(A, B) < 0) {
1419 if (Q != NULL) {
1420 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(Q, 0));
1421 }
1422 if (R != NULL) {
1423 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(R, A));
1424 }
1425 return 0;
1426 }
1427
1428 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&X, A));
1429 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&Y, B));
1430 X.s = Y.s = 1;
1431
1432 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&Z, A->n + 2));
1433 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&Z, 0));
1434 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&T1, A->n + 2));
1435
1436 k = mbedtls_mpi_bitlen(&Y) % biL;
1437 if (k < biL - 1) {
1438 k = biL - 1 - k;
1439 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&X, k));
1440 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&Y, k));
1441 } else {
1442 k = 0;
1443 }
1444
1445 n = X.n - 1;
1446 t = Y.n - 1;
1447 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&Y, biL * (n - t)));
1448
1449 while (mbedtls_mpi_cmp_mpi(&X, &Y) >= 0) {
1450 Z.p[n - t]++;
1451 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&X, &X, &Y));
1452 }
1453 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&Y, biL * (n - t)));
1454
1455 for (i = n; i > t; i--) {
1456 if (X.p[i] >= Y.p[t]) {
1457 Z.p[i - t - 1] = ~(mbedtls_mpi_uint) 0u;
1458 } else {
1459 Z.p[i - t - 1] = mbedtls_int_div_int(X.p[i], X.p[i - 1],
1460 Y.p[t], NULL);
1461 }
1462
1463 T2.p[0] = (i < 2) ? 0 : X.p[i - 2];
1464 T2.p[1] = (i < 1) ? 0 : X.p[i - 1];
1465 T2.p[2] = X.p[i];
1466
1467 Z.p[i - t - 1]++;
1468 do {
1469 Z.p[i - t - 1]--;
1470
1471 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&T1, 0));
1472 T1.p[0] = (t < 1) ? 0 : Y.p[t - 1];
1473 T1.p[1] = Y.p[t];
1474 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(&T1, &T1, Z.p[i - t - 1]));
1475 } while (mbedtls_mpi_cmp_mpi(&T1, &T2) > 0);
1476
1477 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(&T1, &Y, Z.p[i - t - 1]));
1478 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&T1, biL * (i - t - 1)));
1479 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&X, &X, &T1));
1480
1481 if (mbedtls_mpi_cmp_int(&X, 0) < 0) {
1482 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&T1, &Y));
1483 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&T1, biL * (i - t - 1)));
1484 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&X, &X, &T1));
1485 Z.p[i - t - 1]--;
1486 }
1487 }
1488
1489 if (Q != NULL) {
1490 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(Q, &Z));
1491 Q->s = A->s * B->s;
1492 }
1493
1494 if (R != NULL) {
1495 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&X, k));
1496 X.s = A->s;
1497 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(R, &X));
1498
1499 if (mbedtls_mpi_cmp_int(R, 0) == 0) {
1500 R->s = 1;
1501 }
1502 }
1503
1504 cleanup:
1505
1506 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
1507 mbedtls_mpi_free(&T1);
1508 mbedtls_platform_zeroize(TP2, sizeof(TP2));
1509
1510 return ret;
1511 }
1512
1513 /*
1514 * Division by int: A = Q * b + R
1515 */
mbedtls_mpi_div_int(mbedtls_mpi * Q,mbedtls_mpi * R,const mbedtls_mpi * A,mbedtls_mpi_sint b)1516 int mbedtls_mpi_div_int(mbedtls_mpi *Q, mbedtls_mpi *R,
1517 const mbedtls_mpi *A,
1518 mbedtls_mpi_sint b)
1519 {
1520 mbedtls_mpi B;
1521 mbedtls_mpi_uint p[1];
1522
1523 p[0] = mpi_sint_abs(b);
1524 B.s = TO_SIGN(b);
1525 B.n = 1;
1526 B.p = p;
1527
1528 return mbedtls_mpi_div_mpi(Q, R, A, &B);
1529 }
1530
1531 /*
1532 * Modulo: R = A mod B
1533 */
mbedtls_mpi_mod_mpi(mbedtls_mpi * R,const mbedtls_mpi * A,const mbedtls_mpi * B)1534 int mbedtls_mpi_mod_mpi(mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B)
1535 {
1536 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1537
1538 if (mbedtls_mpi_cmp_int(B, 0) < 0) {
1539 return MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
1540 }
1541
1542 MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(NULL, R, A, B));
1543
1544 while (mbedtls_mpi_cmp_int(R, 0) < 0) {
1545 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(R, R, B));
1546 }
1547
1548 while (mbedtls_mpi_cmp_mpi(R, B) >= 0) {
1549 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(R, R, B));
1550 }
1551
1552 cleanup:
1553
1554 return ret;
1555 }
1556
1557 /*
1558 * Modulo: r = A mod b
1559 */
mbedtls_mpi_mod_int(mbedtls_mpi_uint * r,const mbedtls_mpi * A,mbedtls_mpi_sint b)1560 int mbedtls_mpi_mod_int(mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b)
1561 {
1562 size_t i;
1563 mbedtls_mpi_uint x, y, z;
1564
1565 if (b == 0) {
1566 return MBEDTLS_ERR_MPI_DIVISION_BY_ZERO;
1567 }
1568
1569 if (b < 0) {
1570 return MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
1571 }
1572
1573 /*
1574 * handle trivial cases
1575 */
1576 if (b == 1 || A->n == 0) {
1577 *r = 0;
1578 return 0;
1579 }
1580
1581 if (b == 2) {
1582 *r = A->p[0] & 1;
1583 return 0;
1584 }
1585
1586 /*
1587 * general case
1588 */
1589 for (i = A->n, y = 0; i > 0; i--) {
1590 x = A->p[i - 1];
1591 y = (y << biH) | (x >> biH);
1592 z = y / b;
1593 y -= z * b;
1594
1595 x <<= biH;
1596 y = (y << biH) | (x >> biH);
1597 z = y / b;
1598 y -= z * b;
1599 }
1600
1601 /*
1602 * If A is negative, then the current y represents a negative value.
1603 * Flipping it to the positive side.
1604 */
1605 if (A->s < 0 && y != 0) {
1606 y = b - y;
1607 }
1608
1609 *r = y;
1610
1611 return 0;
1612 }
1613
1614 /*
1615 * Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value,
1616 * this function is not constant time with respect to the exponent (parameter E).
1617 */
mbedtls_mpi_exp_mod_optionally_safe(mbedtls_mpi * X,const mbedtls_mpi * A,const mbedtls_mpi * E,int E_public,const mbedtls_mpi * N,mbedtls_mpi * prec_RR)1618 static int mbedtls_mpi_exp_mod_optionally_safe(mbedtls_mpi *X, const mbedtls_mpi *A,
1619 const mbedtls_mpi *E, int E_public,
1620 const mbedtls_mpi *N, mbedtls_mpi *prec_RR)
1621 {
1622 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1623
1624 if (mbedtls_mpi_cmp_int(N, 0) <= 0 || (N->p[0] & 1) == 0) {
1625 return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
1626 }
1627
1628 if (mbedtls_mpi_cmp_int(E, 0) < 0) {
1629 return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
1630 }
1631
1632 if (mbedtls_mpi_bitlen(E) > MBEDTLS_MPI_MAX_BITS ||
1633 mbedtls_mpi_bitlen(N) > MBEDTLS_MPI_MAX_BITS) {
1634 return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
1635 }
1636
1637 /*
1638 * Ensure that the exponent that we are passing to the core is not NULL.
1639 */
1640 if (E->n == 0) {
1641 ret = mbedtls_mpi_lset(X, 1);
1642 return ret;
1643 }
1644
1645 /*
1646 * Allocate working memory for mbedtls_mpi_core_exp_mod()
1647 */
1648 size_t T_limbs = mbedtls_mpi_core_exp_mod_working_limbs(N->n, E->n);
1649 mbedtls_mpi_uint *T = (mbedtls_mpi_uint *) mbedtls_calloc(T_limbs, sizeof(mbedtls_mpi_uint));
1650 if (T == NULL) {
1651 return MBEDTLS_ERR_MPI_ALLOC_FAILED;
1652 }
1653
1654 mbedtls_mpi RR;
1655 mbedtls_mpi_init(&RR);
1656
1657 /*
1658 * If 1st call, pre-compute R^2 mod N
1659 */
1660 if (prec_RR == NULL || prec_RR->p == NULL) {
1661 MBEDTLS_MPI_CHK(mbedtls_mpi_core_get_mont_r2_unsafe(&RR, N));
1662
1663 if (prec_RR != NULL) {
1664 *prec_RR = RR;
1665 }
1666 } else {
1667 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(prec_RR, N->n));
1668 RR = *prec_RR;
1669 }
1670
1671 /*
1672 * To preserve constness we need to make a copy of A. Using X for this to
1673 * save memory.
1674 */
1675 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A));
1676
1677 /*
1678 * Compensate for negative A (and correct at the end).
1679 */
1680 X->s = 1;
1681
1682 /*
1683 * Make sure that X is in a form that is safe for consumption by
1684 * the core functions.
1685 *
1686 * - The core functions will not touch the limbs of X above N->n. The
1687 * result will be correct if those limbs are 0, which the mod call
1688 * ensures.
1689 * - Also, X must have at least as many limbs as N for the calls to the
1690 * core functions.
1691 */
1692 if (mbedtls_mpi_cmp_mpi(X, N) >= 0) {
1693 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(X, X, N));
1694 }
1695 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, N->n));
1696
1697 /*
1698 * Convert to and from Montgomery around mbedtls_mpi_core_exp_mod().
1699 */
1700 {
1701 mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N->p);
1702 mbedtls_mpi_core_to_mont_rep(X->p, X->p, N->p, N->n, mm, RR.p, T);
1703 if (E_public == MBEDTLS_MPI_IS_PUBLIC) {
1704 mbedtls_mpi_core_exp_mod_unsafe(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T);
1705 } else {
1706 mbedtls_mpi_core_exp_mod(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T);
1707 }
1708 mbedtls_mpi_core_from_mont_rep(X->p, X->p, N->p, N->n, mm, T);
1709 }
1710
1711 /*
1712 * Correct for negative A.
1713 */
1714 if (A->s == -1 && (E->p[0] & 1) != 0) {
1715 mbedtls_ct_condition_t is_x_non_zero = mbedtls_mpi_core_check_zero_ct(X->p, X->n);
1716 X->s = mbedtls_ct_mpi_sign_if(is_x_non_zero, -1, 1);
1717
1718 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(X, N, X));
1719 }
1720
1721 cleanup:
1722
1723 mbedtls_mpi_zeroize_and_free(T, T_limbs);
1724
1725 if (prec_RR == NULL || prec_RR->p == NULL) {
1726 mbedtls_mpi_free(&RR);
1727 }
1728
1729 return ret;
1730 }
1731
mbedtls_mpi_exp_mod(mbedtls_mpi * X,const mbedtls_mpi * A,const mbedtls_mpi * E,const mbedtls_mpi * N,mbedtls_mpi * prec_RR)1732 int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
1733 const mbedtls_mpi *E, const mbedtls_mpi *N,
1734 mbedtls_mpi *prec_RR)
1735 {
1736 return mbedtls_mpi_exp_mod_optionally_safe(X, A, E, MBEDTLS_MPI_IS_SECRET, N, prec_RR);
1737 }
1738
mbedtls_mpi_exp_mod_unsafe(mbedtls_mpi * X,const mbedtls_mpi * A,const mbedtls_mpi * E,const mbedtls_mpi * N,mbedtls_mpi * prec_RR)1739 int mbedtls_mpi_exp_mod_unsafe(mbedtls_mpi *X, const mbedtls_mpi *A,
1740 const mbedtls_mpi *E, const mbedtls_mpi *N,
1741 mbedtls_mpi *prec_RR)
1742 {
1743 return mbedtls_mpi_exp_mod_optionally_safe(X, A, E, MBEDTLS_MPI_IS_PUBLIC, N, prec_RR);
1744 }
1745
1746 /*
1747 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
1748 */
mbedtls_mpi_gcd(mbedtls_mpi * G,const mbedtls_mpi * A,const mbedtls_mpi * B)1749 int mbedtls_mpi_gcd(mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B)
1750 {
1751 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1752 size_t lz, lzt;
1753 mbedtls_mpi TA, TB;
1754
1755 mbedtls_mpi_init(&TA); mbedtls_mpi_init(&TB);
1756
1757 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TA, A));
1758 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TB, B));
1759
1760 lz = mbedtls_mpi_lsb(&TA);
1761 lzt = mbedtls_mpi_lsb(&TB);
1762
1763 /* The loop below gives the correct result when A==0 but not when B==0.
1764 * So have a special case for B==0. Leverage the fact that we just
1765 * calculated the lsb and lsb(B)==0 iff B is odd or 0 to make the test
1766 * slightly more efficient than cmp_int(). */
1767 if (lzt == 0 && mbedtls_mpi_get_bit(&TB, 0) == 0) {
1768 ret = mbedtls_mpi_copy(G, A);
1769 goto cleanup;
1770 }
1771
1772 if (lzt < lz) {
1773 lz = lzt;
1774 }
1775
1776 TA.s = TB.s = 1;
1777
1778 /* We mostly follow the procedure described in HAC 14.54, but with some
1779 * minor differences:
1780 * - Sequences of multiplications or divisions by 2 are grouped into a
1781 * single shift operation.
1782 * - The procedure in HAC assumes that 0 < TB <= TA.
1783 * - The condition TB <= TA is not actually necessary for correctness.
1784 * TA and TB have symmetric roles except for the loop termination
1785 * condition, and the shifts at the beginning of the loop body
1786 * remove any significance from the ordering of TA vs TB before
1787 * the shifts.
1788 * - If TA = 0, the loop goes through 0 iterations and the result is
1789 * correctly TB.
1790 * - The case TB = 0 was short-circuited above.
1791 *
1792 * For the correctness proof below, decompose the original values of
1793 * A and B as
1794 * A = sa * 2^a * A' with A'=0 or A' odd, and sa = +-1
1795 * B = sb * 2^b * B' with B'=0 or B' odd, and sb = +-1
1796 * Then gcd(A, B) = 2^{min(a,b)} * gcd(A',B'),
1797 * and gcd(A',B') is odd or 0.
1798 *
1799 * At the beginning, we have TA = |A| and TB = |B| so gcd(A,B) = gcd(TA,TB).
1800 * The code maintains the following invariant:
1801 * gcd(A,B) = 2^k * gcd(TA,TB) for some k (I)
1802 */
1803
1804 /* Proof that the loop terminates:
1805 * At each iteration, either the right-shift by 1 is made on a nonzero
1806 * value and the nonnegative integer bitlen(TA) + bitlen(TB) decreases
1807 * by at least 1, or the right-shift by 1 is made on zero and then
1808 * TA becomes 0 which ends the loop (TB cannot be 0 if it is right-shifted
1809 * since in that case TB is calculated from TB-TA with the condition TB>TA).
1810 */
1811 while (mbedtls_mpi_cmp_int(&TA, 0) != 0) {
1812 /* Divisions by 2 preserve the invariant (I). */
1813 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TA, mbedtls_mpi_lsb(&TA)));
1814 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TB, mbedtls_mpi_lsb(&TB)));
1815
1816 /* Set either TA or TB to |TA-TB|/2. Since TA and TB are both odd,
1817 * TA-TB is even so the division by 2 has an integer result.
1818 * Invariant (I) is preserved since any odd divisor of both TA and TB
1819 * also divides |TA-TB|/2, and any odd divisor of both TA and |TA-TB|/2
1820 * also divides TB, and any odd divisor of both TB and |TA-TB|/2 also
1821 * divides TA.
1822 */
1823 if (mbedtls_mpi_cmp_mpi(&TA, &TB) >= 0) {
1824 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(&TA, &TA, &TB));
1825 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TA, 1));
1826 } else {
1827 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(&TB, &TB, &TA));
1828 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TB, 1));
1829 }
1830 /* Note that one of TA or TB is still odd. */
1831 }
1832
1833 /* By invariant (I), gcd(A,B) = 2^k * gcd(TA,TB) for some k.
1834 * At the loop exit, TA = 0, so gcd(TA,TB) = TB.
1835 * - If there was at least one loop iteration, then one of TA or TB is odd,
1836 * and TA = 0, so TB is odd and gcd(TA,TB) = gcd(A',B'). In this case,
1837 * lz = min(a,b) so gcd(A,B) = 2^lz * TB.
1838 * - If there was no loop iteration, then A was 0, and gcd(A,B) = B.
1839 * In this case, lz = 0 and B = TB so gcd(A,B) = B = 2^lz * TB as well.
1840 */
1841
1842 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&TB, lz));
1843 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(G, &TB));
1844
1845 cleanup:
1846
1847 mbedtls_mpi_free(&TA); mbedtls_mpi_free(&TB);
1848
1849 return ret;
1850 }
1851
1852 /*
1853 * Fill X with size bytes of random.
1854 * The bytes returned from the RNG are used in a specific order which
1855 * is suitable for deterministic ECDSA (see the specification of
1856 * mbedtls_mpi_random() and the implementation in mbedtls_mpi_fill_random()).
1857 */
mbedtls_mpi_fill_random(mbedtls_mpi * X,size_t size,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)1858 int mbedtls_mpi_fill_random(mbedtls_mpi *X, size_t size,
1859 int (*f_rng)(void *, unsigned char *, size_t),
1860 void *p_rng)
1861 {
1862 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1863 const size_t limbs = CHARS_TO_LIMBS(size);
1864
1865 /* Ensure that target MPI has exactly the necessary number of limbs */
1866 MBEDTLS_MPI_CHK(mbedtls_mpi_resize_clear(X, limbs));
1867 if (size == 0) {
1868 return 0;
1869 }
1870
1871 ret = mbedtls_mpi_core_fill_random(X->p, X->n, size, f_rng, p_rng);
1872
1873 cleanup:
1874 return ret;
1875 }
1876
mbedtls_mpi_random(mbedtls_mpi * X,mbedtls_mpi_sint min,const mbedtls_mpi * N,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)1877 int mbedtls_mpi_random(mbedtls_mpi *X,
1878 mbedtls_mpi_sint min,
1879 const mbedtls_mpi *N,
1880 int (*f_rng)(void *, unsigned char *, size_t),
1881 void *p_rng)
1882 {
1883 if (min < 0) {
1884 return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
1885 }
1886 if (mbedtls_mpi_cmp_int(N, min) <= 0) {
1887 return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
1888 }
1889
1890 /* Ensure that target MPI has exactly the same number of limbs
1891 * as the upper bound, even if the upper bound has leading zeros.
1892 * This is necessary for mbedtls_mpi_core_random. */
1893 int ret = mbedtls_mpi_resize_clear(X, N->n);
1894 if (ret != 0) {
1895 return ret;
1896 }
1897
1898 return mbedtls_mpi_core_random(X->p, min, N->p, X->n, f_rng, p_rng);
1899 }
1900
1901 /*
1902 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
1903 */
mbedtls_mpi_inv_mod(mbedtls_mpi * X,const mbedtls_mpi * A,const mbedtls_mpi * N)1904 int mbedtls_mpi_inv_mod(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N)
1905 {
1906 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1907 mbedtls_mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
1908
1909 if (mbedtls_mpi_cmp_int(N, 1) <= 0) {
1910 return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
1911 }
1912
1913 mbedtls_mpi_init(&TA); mbedtls_mpi_init(&TU); mbedtls_mpi_init(&U1); mbedtls_mpi_init(&U2);
1914 mbedtls_mpi_init(&G); mbedtls_mpi_init(&TB); mbedtls_mpi_init(&TV);
1915 mbedtls_mpi_init(&V1); mbedtls_mpi_init(&V2);
1916
1917 MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(&G, A, N));
1918
1919 if (mbedtls_mpi_cmp_int(&G, 1) != 0) {
1920 ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
1921 goto cleanup;
1922 }
1923
1924 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&TA, A, N));
1925 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TU, &TA));
1926 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TB, N));
1927 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TV, N));
1928
1929 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&U1, 1));
1930 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&U2, 0));
1931 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&V1, 0));
1932 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&V2, 1));
1933
1934 do {
1935 while ((TU.p[0] & 1) == 0) {
1936 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TU, 1));
1937
1938 if ((U1.p[0] & 1) != 0 || (U2.p[0] & 1) != 0) {
1939 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&U1, &U1, &TB));
1940 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&U2, &U2, &TA));
1941 }
1942
1943 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&U1, 1));
1944 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&U2, 1));
1945 }
1946
1947 while ((TV.p[0] & 1) == 0) {
1948 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TV, 1));
1949
1950 if ((V1.p[0] & 1) != 0 || (V2.p[0] & 1) != 0) {
1951 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&V1, &V1, &TB));
1952 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&V2, &V2, &TA));
1953 }
1954
1955 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&V1, 1));
1956 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&V2, 1));
1957 }
1958
1959 if (mbedtls_mpi_cmp_mpi(&TU, &TV) >= 0) {
1960 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&TU, &TU, &TV));
1961 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&U1, &U1, &V1));
1962 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&U2, &U2, &V2));
1963 } else {
1964 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&TV, &TV, &TU));
1965 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&V1, &V1, &U1));
1966 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&V2, &V2, &U2));
1967 }
1968 } while (mbedtls_mpi_cmp_int(&TU, 0) != 0);
1969
1970 while (mbedtls_mpi_cmp_int(&V1, 0) < 0) {
1971 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&V1, &V1, N));
1972 }
1973
1974 while (mbedtls_mpi_cmp_mpi(&V1, N) >= 0) {
1975 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&V1, &V1, N));
1976 }
1977
1978 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, &V1));
1979
1980 cleanup:
1981
1982 mbedtls_mpi_free(&TA); mbedtls_mpi_free(&TU); mbedtls_mpi_free(&U1); mbedtls_mpi_free(&U2);
1983 mbedtls_mpi_free(&G); mbedtls_mpi_free(&TB); mbedtls_mpi_free(&TV);
1984 mbedtls_mpi_free(&V1); mbedtls_mpi_free(&V2);
1985
1986 return ret;
1987 }
1988
1989 #if defined(MBEDTLS_GENPRIME)
1990
1991 /* Gaps between primes, starting at 3. https://oeis.org/A001223 */
1992 static const unsigned char small_prime_gaps[] = {
1993 2, 2, 4, 2, 4, 2, 4, 6,
1994 2, 6, 4, 2, 4, 6, 6, 2,
1995 6, 4, 2, 6, 4, 6, 8, 4,
1996 2, 4, 2, 4, 14, 4, 6, 2,
1997 10, 2, 6, 6, 4, 6, 6, 2,
1998 10, 2, 4, 2, 12, 12, 4, 2,
1999 4, 6, 2, 10, 6, 6, 6, 2,
2000 6, 4, 2, 10, 14, 4, 2, 4,
2001 14, 6, 10, 2, 4, 6, 8, 6,
2002 6, 4, 6, 8, 4, 8, 10, 2,
2003 10, 2, 6, 4, 6, 8, 4, 2,
2004 4, 12, 8, 4, 8, 4, 6, 12,
2005 2, 18, 6, 10, 6, 6, 2, 6,
2006 10, 6, 6, 2, 6, 6, 4, 2,
2007 12, 10, 2, 4, 6, 6, 2, 12,
2008 4, 6, 8, 10, 8, 10, 8, 6,
2009 6, 4, 8, 6, 4, 8, 4, 14,
2010 10, 12, 2, 10, 2, 4, 2, 10,
2011 14, 4, 2, 4, 14, 4, 2, 4,
2012 20, 4, 8, 10, 8, 4, 6, 6,
2013 14, 4, 6, 6, 8, 6, /*reaches 997*/
2014 0 /* the last entry is effectively unused */
2015 };
2016
2017 /*
2018 * Small divisors test (X must be positive)
2019 *
2020 * Return values:
2021 * 0: no small factor (possible prime, more tests needed)
2022 * 1: certain prime
2023 * MBEDTLS_ERR_MPI_NOT_ACCEPTABLE: certain non-prime
2024 * other negative: error
2025 */
mpi_check_small_factors(const mbedtls_mpi * X)2026 static int mpi_check_small_factors(const mbedtls_mpi *X)
2027 {
2028 int ret = 0;
2029 size_t i;
2030 mbedtls_mpi_uint r;
2031 unsigned p = 3; /* The first odd prime */
2032
2033 if ((X->p[0] & 1) == 0) {
2034 return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
2035 }
2036
2037 for (i = 0; i < sizeof(small_prime_gaps); p += small_prime_gaps[i], i++) {
2038 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_int(&r, X, p));
2039 if (r == 0) {
2040 if (mbedtls_mpi_cmp_int(X, p) == 0) {
2041 return 1;
2042 } else {
2043 return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
2044 }
2045 }
2046 }
2047
2048 cleanup:
2049 return ret;
2050 }
2051
2052 /*
2053 * Miller-Rabin pseudo-primality test (HAC 4.24)
2054 */
mpi_miller_rabin(const mbedtls_mpi * X,size_t rounds,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)2055 static int mpi_miller_rabin(const mbedtls_mpi *X, size_t rounds,
2056 int (*f_rng)(void *, unsigned char *, size_t),
2057 void *p_rng)
2058 {
2059 int ret, count;
2060 size_t i, j, k, s;
2061 mbedtls_mpi W, R, T, A, RR;
2062
2063 mbedtls_mpi_init(&W); mbedtls_mpi_init(&R);
2064 mbedtls_mpi_init(&T); mbedtls_mpi_init(&A);
2065 mbedtls_mpi_init(&RR);
2066
2067 /*
2068 * W = |X| - 1
2069 * R = W >> lsb( W )
2070 */
2071 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&W, X, 1));
2072 s = mbedtls_mpi_lsb(&W);
2073 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&R, &W));
2074 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&R, s));
2075
2076 for (i = 0; i < rounds; i++) {
2077 /*
2078 * pick a random A, 1 < A < |X| - 1
2079 */
2080 count = 0;
2081 do {
2082 MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&A, X->n * ciL, f_rng, p_rng));
2083
2084 j = mbedtls_mpi_bitlen(&A);
2085 k = mbedtls_mpi_bitlen(&W);
2086 if (j > k) {
2087 A.p[A.n - 1] &= ((mbedtls_mpi_uint) 1 << (k - (A.n - 1) * biL - 1)) - 1;
2088 }
2089
2090 if (count++ > 30) {
2091 ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
2092 goto cleanup;
2093 }
2094
2095 } while (mbedtls_mpi_cmp_mpi(&A, &W) >= 0 ||
2096 mbedtls_mpi_cmp_int(&A, 1) <= 0);
2097
2098 /*
2099 * A = A^R mod |X|
2100 */
2101 MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&A, &A, &R, X, &RR));
2102
2103 if (mbedtls_mpi_cmp_mpi(&A, &W) == 0 ||
2104 mbedtls_mpi_cmp_int(&A, 1) == 0) {
2105 continue;
2106 }
2107
2108 j = 1;
2109 while (j < s && mbedtls_mpi_cmp_mpi(&A, &W) != 0) {
2110 /*
2111 * A = A * A mod |X|
2112 */
2113 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&T, &A, &A));
2114 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&A, &T, X));
2115
2116 if (mbedtls_mpi_cmp_int(&A, 1) == 0) {
2117 break;
2118 }
2119
2120 j++;
2121 }
2122
2123 /*
2124 * not prime if A != |X| - 1 or A == 1
2125 */
2126 if (mbedtls_mpi_cmp_mpi(&A, &W) != 0 ||
2127 mbedtls_mpi_cmp_int(&A, 1) == 0) {
2128 ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
2129 break;
2130 }
2131 }
2132
2133 cleanup:
2134 mbedtls_mpi_free(&W); mbedtls_mpi_free(&R);
2135 mbedtls_mpi_free(&T); mbedtls_mpi_free(&A);
2136 mbedtls_mpi_free(&RR);
2137
2138 return ret;
2139 }
2140
2141 /*
2142 * Pseudo-primality test: small factors, then Miller-Rabin
2143 */
mbedtls_mpi_is_prime_ext(const mbedtls_mpi * X,int rounds,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)2144 int mbedtls_mpi_is_prime_ext(const mbedtls_mpi *X, int rounds,
2145 int (*f_rng)(void *, unsigned char *, size_t),
2146 void *p_rng)
2147 {
2148 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2149 mbedtls_mpi XX;
2150
2151 XX.s = 1;
2152 XX.n = X->n;
2153 XX.p = X->p;
2154
2155 if (mbedtls_mpi_cmp_int(&XX, 0) == 0 ||
2156 mbedtls_mpi_cmp_int(&XX, 1) == 0) {
2157 return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
2158 }
2159
2160 if (mbedtls_mpi_cmp_int(&XX, 2) == 0) {
2161 return 0;
2162 }
2163
2164 if ((ret = mpi_check_small_factors(&XX)) != 0) {
2165 if (ret == 1) {
2166 return 0;
2167 }
2168
2169 return ret;
2170 }
2171
2172 return mpi_miller_rabin(&XX, rounds, f_rng, p_rng);
2173 }
2174
2175 /*
2176 * Prime number generation
2177 *
2178 * To generate an RSA key in a way recommended by FIPS 186-4, both primes must
2179 * be either 1024 bits or 1536 bits long, and flags must contain
2180 * MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR.
2181 */
mbedtls_mpi_gen_prime(mbedtls_mpi * X,size_t nbits,int flags,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)2182 int mbedtls_mpi_gen_prime(mbedtls_mpi *X, size_t nbits, int flags,
2183 int (*f_rng)(void *, unsigned char *, size_t),
2184 void *p_rng)
2185 {
2186 #ifdef MBEDTLS_HAVE_INT64
2187 // ceil(2^63.5)
2188 #define CEIL_MAXUINT_DIV_SQRT2 0xb504f333f9de6485ULL
2189 #else
2190 // ceil(2^31.5)
2191 #define CEIL_MAXUINT_DIV_SQRT2 0xb504f334U
2192 #endif
2193 int ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
2194 size_t k, n;
2195 int rounds;
2196 mbedtls_mpi_uint r;
2197 mbedtls_mpi Y;
2198
2199 if (nbits < 3 || nbits > MBEDTLS_MPI_MAX_BITS) {
2200 return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
2201 }
2202
2203 mbedtls_mpi_init(&Y);
2204
2205 n = BITS_TO_LIMBS(nbits);
2206
2207 if ((flags & MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR) == 0) {
2208 /*
2209 * 2^-80 error probability, number of rounds chosen per HAC, table 4.4
2210 */
2211 rounds = ((nbits >= 1300) ? 2 : (nbits >= 850) ? 3 :
2212 (nbits >= 650) ? 4 : (nbits >= 350) ? 8 :
2213 (nbits >= 250) ? 12 : (nbits >= 150) ? 18 : 27);
2214 } else {
2215 /*
2216 * 2^-100 error probability, number of rounds computed based on HAC,
2217 * fact 4.48
2218 */
2219 rounds = ((nbits >= 1450) ? 4 : (nbits >= 1150) ? 5 :
2220 (nbits >= 1000) ? 6 : (nbits >= 850) ? 7 :
2221 (nbits >= 750) ? 8 : (nbits >= 500) ? 13 :
2222 (nbits >= 250) ? 28 : (nbits >= 150) ? 40 : 51);
2223 }
2224
2225 while (1) {
2226 MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(X, n * ciL, f_rng, p_rng));
2227 /* make sure generated number is at least (nbits-1)+0.5 bits (FIPS 186-4 §B.3.3 steps 4.4, 5.5) */
2228 if (X->p[n-1] < CEIL_MAXUINT_DIV_SQRT2) {
2229 continue;
2230 }
2231
2232 k = n * biL;
2233 if (k > nbits) {
2234 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(X, k - nbits));
2235 }
2236 X->p[0] |= 1;
2237
2238 if ((flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH) == 0) {
2239 ret = mbedtls_mpi_is_prime_ext(X, rounds, f_rng, p_rng);
2240
2241 if (ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) {
2242 goto cleanup;
2243 }
2244 } else {
2245 /*
2246 * A necessary condition for Y and X = 2Y + 1 to be prime
2247 * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
2248 * Make sure it is satisfied, while keeping X = 3 mod 4
2249 */
2250
2251 X->p[0] |= 2;
2252
2253 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_int(&r, X, 3));
2254 if (r == 0) {
2255 MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, X, 8));
2256 } else if (r == 1) {
2257 MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, X, 4));
2258 }
2259
2260 /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
2261 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&Y, X));
2262 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&Y, 1));
2263
2264 while (1) {
2265 /*
2266 * First, check small factors for X and Y
2267 * before doing Miller-Rabin on any of them
2268 */
2269 if ((ret = mpi_check_small_factors(X)) == 0 &&
2270 (ret = mpi_check_small_factors(&Y)) == 0 &&
2271 (ret = mpi_miller_rabin(X, rounds, f_rng, p_rng))
2272 == 0 &&
2273 (ret = mpi_miller_rabin(&Y, rounds, f_rng, p_rng))
2274 == 0) {
2275 goto cleanup;
2276 }
2277
2278 if (ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) {
2279 goto cleanup;
2280 }
2281
2282 /*
2283 * Next candidates. We want to preserve Y = (X-1) / 2 and
2284 * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
2285 * so up Y by 6 and X by 12.
2286 */
2287 MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, X, 12));
2288 MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&Y, &Y, 6));
2289 }
2290 }
2291 }
2292
2293 cleanup:
2294
2295 mbedtls_mpi_free(&Y);
2296
2297 return ret;
2298 }
2299
2300 #endif /* MBEDTLS_GENPRIME */
2301
2302 #if defined(MBEDTLS_SELF_TEST)
2303
2304 #define GCD_PAIR_COUNT 3
2305
2306 static const int gcd_pairs[GCD_PAIR_COUNT][3] =
2307 {
2308 { 693, 609, 21 },
2309 { 1764, 868, 28 },
2310 { 768454923, 542167814, 1 }
2311 };
2312
2313 /*
2314 * Checkup routine
2315 */
mbedtls_mpi_self_test(int verbose)2316 int mbedtls_mpi_self_test(int verbose)
2317 {
2318 int ret, i;
2319 mbedtls_mpi A, E, N, X, Y, U, V;
2320
2321 mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N); mbedtls_mpi_init(&X);
2322 mbedtls_mpi_init(&Y); mbedtls_mpi_init(&U); mbedtls_mpi_init(&V);
2323
2324 MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&A, 16,
2325 "EFE021C2645FD1DC586E69184AF4A31E" \
2326 "D5F53E93B5F123FA41680867BA110131" \
2327 "944FE7952E2517337780CB0DB80E61AA" \
2328 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6"));
2329
2330 MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&E, 16,
2331 "B2E7EFD37075B9F03FF989C7C5051C20" \
2332 "34D2A323810251127E7BF8625A4F49A5" \
2333 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
2334 "5B5C25763222FEFCCFC38B832366C29E"));
2335
2336 MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&N, 16,
2337 "0066A198186C18C10B2F5ED9B522752A" \
2338 "9830B69916E535C8F047518A889A43A5" \
2339 "94B6BED27A168D31D4A52F88925AA8F5"));
2340
2341 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&X, &A, &N));
2342
2343 MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16,
2344 "602AB7ECA597A3D6B56FF9829A5E8B85" \
2345 "9E857EA95A03512E2BAE7391688D264A" \
2346 "A5663B0341DB9CCFD2C4C5F421FEC814" \
2347 "8001B72E848A38CAE1C65F78E56ABDEF" \
2348 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
2349 "ECF677152EF804370C1A305CAF3B5BF1" \
2350 "30879B56C61DE584A0F53A2447A51E"));
2351
2352 if (verbose != 0) {
2353 mbedtls_printf(" MPI test #1 (mul_mpi): ");
2354 }
2355
2356 if (mbedtls_mpi_cmp_mpi(&X, &U) != 0) {
2357 if (verbose != 0) {
2358 mbedtls_printf("failed\n");
2359 }
2360
2361 ret = 1;
2362 goto cleanup;
2363 }
2364
2365 if (verbose != 0) {
2366 mbedtls_printf("passed\n");
2367 }
2368
2369 MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(&X, &Y, &A, &N));
2370
2371 MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16,
2372 "256567336059E52CAE22925474705F39A94"));
2373
2374 MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&V, 16,
2375 "6613F26162223DF488E9CD48CC132C7A" \
2376 "0AC93C701B001B092E4E5B9F73BCD27B" \
2377 "9EE50D0657C77F374E903CDFA4C642"));
2378
2379 if (verbose != 0) {
2380 mbedtls_printf(" MPI test #2 (div_mpi): ");
2381 }
2382
2383 if (mbedtls_mpi_cmp_mpi(&X, &U) != 0 ||
2384 mbedtls_mpi_cmp_mpi(&Y, &V) != 0) {
2385 if (verbose != 0) {
2386 mbedtls_printf("failed\n");
2387 }
2388
2389 ret = 1;
2390 goto cleanup;
2391 }
2392
2393 if (verbose != 0) {
2394 mbedtls_printf("passed\n");
2395 }
2396
2397 MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&X, &A, &E, &N, NULL));
2398
2399 MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16,
2400 "36E139AEA55215609D2816998ED020BB" \
2401 "BD96C37890F65171D948E9BC7CBAA4D9" \
2402 "325D24D6A3C12710F10A09FA08AB87"));
2403
2404 if (verbose != 0) {
2405 mbedtls_printf(" MPI test #3 (exp_mod): ");
2406 }
2407
2408 if (mbedtls_mpi_cmp_mpi(&X, &U) != 0) {
2409 if (verbose != 0) {
2410 mbedtls_printf("failed\n");
2411 }
2412
2413 ret = 1;
2414 goto cleanup;
2415 }
2416
2417 if (verbose != 0) {
2418 mbedtls_printf("passed\n");
2419 }
2420
2421 MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&X, &A, &N));
2422
2423 MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16,
2424 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
2425 "C3DBA76456363A10869622EAC2DD84EC" \
2426 "C5B8A74DAC4D09E03B5E0BE779F2DF61"));
2427
2428 if (verbose != 0) {
2429 mbedtls_printf(" MPI test #4 (inv_mod): ");
2430 }
2431
2432 if (mbedtls_mpi_cmp_mpi(&X, &U) != 0) {
2433 if (verbose != 0) {
2434 mbedtls_printf("failed\n");
2435 }
2436
2437 ret = 1;
2438 goto cleanup;
2439 }
2440
2441 if (verbose != 0) {
2442 mbedtls_printf("passed\n");
2443 }
2444
2445 if (verbose != 0) {
2446 mbedtls_printf(" MPI test #5 (simple gcd): ");
2447 }
2448
2449 for (i = 0; i < GCD_PAIR_COUNT; i++) {
2450 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&X, gcd_pairs[i][0]));
2451 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&Y, gcd_pairs[i][1]));
2452
2453 MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(&A, &X, &Y));
2454
2455 if (mbedtls_mpi_cmp_int(&A, gcd_pairs[i][2]) != 0) {
2456 if (verbose != 0) {
2457 mbedtls_printf("failed at %d\n", i);
2458 }
2459
2460 ret = 1;
2461 goto cleanup;
2462 }
2463 }
2464
2465 if (verbose != 0) {
2466 mbedtls_printf("passed\n");
2467 }
2468
2469 cleanup:
2470
2471 if (ret != 0 && verbose != 0) {
2472 mbedtls_printf("Unexpected error, return code = %08X\n", (unsigned int) ret);
2473 }
2474
2475 mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N); mbedtls_mpi_free(&X);
2476 mbedtls_mpi_free(&Y); mbedtls_mpi_free(&U); mbedtls_mpi_free(&V);
2477
2478 if (verbose != 0) {
2479 mbedtls_printf("\n");
2480 }
2481
2482 return ret;
2483 }
2484
2485 #endif /* MBEDTLS_SELF_TEST */
2486
2487 #endif /* MBEDTLS_BIGNUM_C */
2488