Line data Source code
1 : /*
2 : * Core bignum functions
3 : *
4 : * Copyright The Mbed TLS Contributors
5 : * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 : */
7 :
8 : #include "common.h"
9 :
10 : #if defined(MBEDTLS_BIGNUM_C)
11 :
12 : #include <string.h>
13 :
14 : #include "mbedtls/error.h"
15 : #include "mbedtls/platform_util.h"
16 : #include "constant_time_internal.h"
17 :
18 : #include "mbedtls/platform.h"
19 :
20 : #include "bignum_core.h"
21 : #include "bn_mul.h"
22 : #include "constant_time_internal.h"
23 :
24 8596435 : size_t mbedtls_mpi_core_clz(mbedtls_mpi_uint a)
25 : {
26 : #if defined(__has_builtin)
27 : #if (MBEDTLS_MPI_UINT_MAX == UINT_MAX) && __has_builtin(__builtin_clz)
28 : #define core_clz __builtin_clz
29 : #elif (MBEDTLS_MPI_UINT_MAX == ULONG_MAX) && __has_builtin(__builtin_clzl)
30 : #define core_clz __builtin_clzl
31 : #elif (MBEDTLS_MPI_UINT_MAX == ULLONG_MAX) && __has_builtin(__builtin_clzll)
32 : #define core_clz __builtin_clzll
33 : #endif
34 : #endif
35 : #if defined(core_clz)
36 8596435 : return (size_t) core_clz(a);
37 : #else
38 : size_t j;
39 : mbedtls_mpi_uint mask = (mbedtls_mpi_uint) 1 << (biL - 1);
40 :
41 : for (j = 0; j < biL; j++) {
42 : if (a & mask) {
43 : break;
44 : }
45 :
46 : mask >>= 1;
47 : }
48 :
49 : return j;
50 : #endif
51 : }
52 :
53 8596437 : size_t mbedtls_mpi_core_bitlen(const mbedtls_mpi_uint *A, size_t A_limbs)
54 : {
55 : int i;
56 : size_t j;
57 :
58 27272411 : for (i = ((int) A_limbs) - 1; i >= 0; i--) {
59 27272409 : if (A[i] != 0) {
60 8596435 : j = biL - mbedtls_mpi_core_clz(A[i]);
61 8596435 : return (i * biL) + j;
62 : }
63 : }
64 :
65 2 : return 0;
66 : }
67 :
68 215950 : static mbedtls_mpi_uint mpi_bigendian_to_host(mbedtls_mpi_uint a)
69 : {
70 : if (MBEDTLS_IS_BIG_ENDIAN) {
71 : /* Nothing to do on bigendian systems. */
72 : return a;
73 : } else {
74 : #if defined(MBEDTLS_HAVE_INT32)
75 : return (mbedtls_mpi_uint) MBEDTLS_BSWAP32(a);
76 : #elif defined(MBEDTLS_HAVE_INT64)
77 215950 : return (mbedtls_mpi_uint) MBEDTLS_BSWAP64(a);
78 : #endif
79 : }
80 : }
81 :
82 32875 : void mbedtls_mpi_core_bigendian_to_host(mbedtls_mpi_uint *A,
83 : size_t A_limbs)
84 : {
85 : mbedtls_mpi_uint *cur_limb_left;
86 : mbedtls_mpi_uint *cur_limb_right;
87 32875 : if (A_limbs == 0) {
88 0 : return;
89 : }
90 :
91 : /*
92 : * Traverse limbs and
93 : * - adapt byte-order in each limb
94 : * - swap the limbs themselves.
95 : * For that, simultaneously traverse the limbs from left to right
96 : * and from right to left, as long as the left index is not bigger
97 : * than the right index (it's not a problem if limbs is odd and the
98 : * indices coincide in the last iteration).
99 : */
100 32875 : for (cur_limb_left = A, cur_limb_right = A + (A_limbs - 1);
101 140850 : cur_limb_left <= cur_limb_right;
102 107975 : cur_limb_left++, cur_limb_right--) {
103 : mbedtls_mpi_uint tmp;
104 : /* Note that if cur_limb_left == cur_limb_right,
105 : * this code effectively swaps the bytes only once. */
106 107975 : tmp = mpi_bigendian_to_host(*cur_limb_left);
107 107975 : *cur_limb_left = mpi_bigendian_to_host(*cur_limb_right);
108 107975 : *cur_limb_right = tmp;
109 : }
110 : }
111 :
112 : /* Whether min <= A, in constant time.
113 : * A_limbs must be at least 1. */
114 1244 : mbedtls_ct_condition_t mbedtls_mpi_core_uint_le_mpi(mbedtls_mpi_uint min,
115 : const mbedtls_mpi_uint *A,
116 : size_t A_limbs)
117 : {
118 : /* min <= least significant limb? */
119 1244 : mbedtls_ct_condition_t min_le_lsl = mbedtls_ct_uint_ge(A[0], min);
120 :
121 : /* limbs other than the least significant one are all zero? */
122 1244 : mbedtls_ct_condition_t msll_mask = MBEDTLS_CT_FALSE;
123 5032 : for (size_t i = 1; i < A_limbs; i++) {
124 3788 : msll_mask = mbedtls_ct_bool_or(msll_mask, mbedtls_ct_bool(A[i]));
125 : }
126 :
127 : /* min <= A iff the lowest limb of A is >= min or the other limbs
128 : * are not all zero. */
129 1244 : return mbedtls_ct_bool_or(msll_mask, min_le_lsl);
130 : }
131 :
132 1244 : mbedtls_ct_condition_t mbedtls_mpi_core_lt_ct(const mbedtls_mpi_uint *A,
133 : const mbedtls_mpi_uint *B,
134 : size_t limbs)
135 : {
136 1244 : mbedtls_ct_condition_t ret = MBEDTLS_CT_FALSE, cond = MBEDTLS_CT_FALSE, done = MBEDTLS_CT_FALSE;
137 :
138 6276 : for (size_t i = limbs; i > 0; i--) {
139 : /*
140 : * If B[i - 1] < A[i - 1] then A < B is false and the result must
141 : * remain 0.
142 : *
143 : * Again even if we can make a decision, we just mark the result and
144 : * the fact that we are done and continue looping.
145 : */
146 5032 : cond = mbedtls_ct_uint_lt(B[i - 1], A[i - 1]);
147 5032 : done = mbedtls_ct_bool_or(done, cond);
148 :
149 : /*
150 : * If A[i - 1] < B[i - 1] then A < B is true.
151 : *
152 : * Again even if we can make a decision, we just mark the result and
153 : * the fact that we are done and continue looping.
154 : */
155 5032 : cond = mbedtls_ct_uint_lt(A[i - 1], B[i - 1]);
156 5032 : ret = mbedtls_ct_bool_or(ret, mbedtls_ct_bool_and(cond, mbedtls_ct_bool_not(done)));
157 5032 : done = mbedtls_ct_bool_or(done, cond);
158 : }
159 :
160 : /*
161 : * If all the limbs were equal, then the numbers are equal, A < B is false
162 : * and leaving the result 0 is correct.
163 : */
164 :
165 1244 : return ret;
166 : }
167 :
168 5141172 : void mbedtls_mpi_core_cond_assign(mbedtls_mpi_uint *X,
169 : const mbedtls_mpi_uint *A,
170 : size_t limbs,
171 : mbedtls_ct_condition_t assign)
172 : {
173 5141172 : if (X == A) {
174 0 : return;
175 : }
176 :
177 : /* This function is very performance-sensitive for RSA. For this reason
178 : * we have the loop below, instead of calling mbedtls_ct_memcpy_if
179 : * (this is more optimal since here we don't have to handle the case where
180 : * we copy awkwardly sized data).
181 : */
182 30130308 : for (size_t i = 0; i < limbs; i++) {
183 24989136 : X[i] = mbedtls_ct_mpi_uint_if(assign, A[i], X[i]);
184 : }
185 : }
186 :
187 0 : void mbedtls_mpi_core_cond_swap(mbedtls_mpi_uint *X,
188 : mbedtls_mpi_uint *Y,
189 : size_t limbs,
190 : mbedtls_ct_condition_t swap)
191 : {
192 0 : if (X == Y) {
193 0 : return;
194 : }
195 :
196 0 : for (size_t i = 0; i < limbs; i++) {
197 0 : mbedtls_mpi_uint tmp = X[i];
198 0 : X[i] = mbedtls_ct_mpi_uint_if(swap, Y[i], X[i]);
199 0 : Y[i] = mbedtls_ct_mpi_uint_if(swap, tmp, Y[i]);
200 : }
201 : }
202 :
203 0 : int mbedtls_mpi_core_read_le(mbedtls_mpi_uint *X,
204 : size_t X_limbs,
205 : const unsigned char *input,
206 : size_t input_length)
207 : {
208 0 : const size_t limbs = CHARS_TO_LIMBS(input_length);
209 :
210 0 : if (X_limbs < limbs) {
211 0 : return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL;
212 : }
213 :
214 0 : if (X != NULL) {
215 0 : memset(X, 0, X_limbs * ciL);
216 :
217 0 : for (size_t i = 0; i < input_length; i++) {
218 0 : size_t offset = ((i % ciL) << 3);
219 0 : X[i / ciL] |= ((mbedtls_mpi_uint) input[i]) << offset;
220 : }
221 : }
222 :
223 0 : return 0;
224 : }
225 :
226 31479 : int mbedtls_mpi_core_read_be(mbedtls_mpi_uint *X,
227 : size_t X_limbs,
228 : const unsigned char *input,
229 : size_t input_length)
230 : {
231 31479 : const size_t limbs = CHARS_TO_LIMBS(input_length);
232 :
233 31479 : if (X_limbs < limbs) {
234 0 : return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL;
235 : }
236 :
237 : /* If X_limbs is 0, input_length must also be 0 (from previous test).
238 : * Nothing to do. */
239 31479 : if (X_limbs == 0) {
240 0 : return 0;
241 : }
242 :
243 31479 : memset(X, 0, X_limbs * ciL);
244 :
245 : /* memcpy() with (NULL, 0) is undefined behaviour */
246 31479 : if (input_length != 0) {
247 31479 : size_t overhead = (X_limbs * ciL) - input_length;
248 31479 : unsigned char *Xp = (unsigned char *) X;
249 31479 : memcpy(Xp + overhead, input, input_length);
250 : }
251 :
252 31479 : mbedtls_mpi_core_bigendian_to_host(X, X_limbs);
253 :
254 31479 : return 0;
255 : }
256 :
257 0 : int mbedtls_mpi_core_write_le(const mbedtls_mpi_uint *A,
258 : size_t A_limbs,
259 : unsigned char *output,
260 : size_t output_length)
261 : {
262 0 : size_t stored_bytes = A_limbs * ciL;
263 : size_t bytes_to_copy;
264 :
265 0 : if (stored_bytes < output_length) {
266 0 : bytes_to_copy = stored_bytes;
267 : } else {
268 0 : bytes_to_copy = output_length;
269 :
270 : /* The output buffer is smaller than the allocated size of A.
271 : * However A may fit if its leading bytes are zero. */
272 0 : for (size_t i = bytes_to_copy; i < stored_bytes; i++) {
273 0 : if (GET_BYTE(A, i) != 0) {
274 0 : return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL;
275 : }
276 : }
277 : }
278 :
279 0 : for (size_t i = 0; i < bytes_to_copy; i++) {
280 0 : output[i] = GET_BYTE(A, i);
281 : }
282 :
283 0 : if (stored_bytes < output_length) {
284 : /* Write trailing 0 bytes */
285 0 : memset(output + stored_bytes, 0, output_length - stored_bytes);
286 : }
287 :
288 0 : return 0;
289 : }
290 :
291 1117 : int mbedtls_mpi_core_write_be(const mbedtls_mpi_uint *X,
292 : size_t X_limbs,
293 : unsigned char *output,
294 : size_t output_length)
295 : {
296 : size_t stored_bytes;
297 : size_t bytes_to_copy;
298 : unsigned char *p;
299 :
300 1117 : stored_bytes = X_limbs * ciL;
301 :
302 1117 : if (stored_bytes < output_length) {
303 : /* There is enough space in the output buffer. Write initial
304 : * null bytes and record the position at which to start
305 : * writing the significant bytes. In this case, the execution
306 : * trace of this function does not depend on the value of the
307 : * number. */
308 0 : bytes_to_copy = stored_bytes;
309 0 : p = output + output_length - stored_bytes;
310 0 : memset(output, 0, output_length - stored_bytes);
311 : } else {
312 : /* The output buffer is smaller than the allocated size of X.
313 : * However X may fit if its leading bytes are zero. */
314 1117 : bytes_to_copy = output_length;
315 1117 : p = output;
316 40630 : for (size_t i = bytes_to_copy; i < stored_bytes; i++) {
317 39513 : if (GET_BYTE(X, i) != 0) {
318 0 : return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL;
319 : }
320 : }
321 : }
322 :
323 189180 : for (size_t i = 0; i < bytes_to_copy; i++) {
324 188063 : p[bytes_to_copy - i - 1] = GET_BYTE(X, i);
325 : }
326 :
327 1117 : return 0;
328 : }
329 :
330 15955145 : void mbedtls_mpi_core_shift_r(mbedtls_mpi_uint *X, size_t limbs,
331 : size_t count)
332 : {
333 : size_t i, v0, v1;
334 15955145 : mbedtls_mpi_uint r0 = 0, r1;
335 :
336 15955145 : v0 = count / biL;
337 15955145 : v1 = count & (biL - 1);
338 :
339 15955145 : if (v0 > limbs || (v0 == limbs && v1 > 0)) {
340 0 : memset(X, 0, limbs * ciL);
341 0 : return;
342 : }
343 :
344 : /*
345 : * shift by count / limb_size
346 : */
347 15955145 : if (v0 > 0) {
348 47814 : for (i = 0; i < limbs - v0; i++) {
349 43891 : X[i] = X[i + v0];
350 : }
351 :
352 45685 : for (; i < limbs; i++) {
353 41762 : X[i] = 0;
354 : }
355 : }
356 :
357 : /*
358 : * shift by count % limb_size
359 : */
360 15955145 : if (v1 > 0) {
361 83275315 : for (i = limbs; i > 0; i--) {
362 69994748 : r1 = X[i - 1] << (biL - v1);
363 69994748 : X[i - 1] >>= v1;
364 69994748 : X[i - 1] |= r0;
365 69994748 : r0 = r1;
366 : }
367 : }
368 : }
369 :
370 2222245 : void mbedtls_mpi_core_shift_l(mbedtls_mpi_uint *X, size_t limbs,
371 : size_t count)
372 : {
373 : size_t i, v0, v1;
374 2222245 : mbedtls_mpi_uint r0 = 0, r1;
375 :
376 2222245 : v0 = count / (biL);
377 2222245 : v1 = count & (biL - 1);
378 :
379 : /*
380 : * shift by count / limb_size
381 : */
382 2222245 : if (v0 > 0) {
383 2276843 : for (i = limbs; i > v0; i--) {
384 2234628 : X[i - 1] = X[i - v0 - 1];
385 : }
386 :
387 842028 : for (; i > 0; i--) {
388 799813 : X[i - 1] = 0;
389 : }
390 : }
391 :
392 : /*
393 : * shift by count % limb_size
394 : */
395 2222245 : if (v1 > 0) {
396 21724436 : for (i = v0; i < limbs; i++) {
397 19557887 : r1 = X[i] >> (biL - v1);
398 19557887 : X[i] <<= v1;
399 19557887 : X[i] |= r0;
400 19557887 : r0 = r1;
401 : }
402 : }
403 2222245 : }
404 :
405 3968293 : mbedtls_mpi_uint mbedtls_mpi_core_add(mbedtls_mpi_uint *X,
406 : const mbedtls_mpi_uint *A,
407 : const mbedtls_mpi_uint *B,
408 : size_t limbs)
409 : {
410 3968293 : mbedtls_mpi_uint c = 0;
411 :
412 22865010 : for (size_t i = 0; i < limbs; i++) {
413 18896717 : mbedtls_mpi_uint t = c + A[i];
414 18896717 : c = (t < A[i]);
415 18896717 : t += B[i];
416 18896717 : c += (t < B[i]);
417 18896717 : X[i] = t;
418 : }
419 :
420 3968293 : return c;
421 : }
422 :
423 0 : mbedtls_mpi_uint mbedtls_mpi_core_add_if(mbedtls_mpi_uint *X,
424 : const mbedtls_mpi_uint *A,
425 : size_t limbs,
426 : unsigned cond)
427 : {
428 0 : mbedtls_mpi_uint c = 0;
429 :
430 0 : mbedtls_ct_condition_t do_add = mbedtls_ct_bool(cond);
431 :
432 0 : for (size_t i = 0; i < limbs; i++) {
433 0 : mbedtls_mpi_uint add = mbedtls_ct_mpi_uint_if_else_0(do_add, A[i]);
434 0 : mbedtls_mpi_uint t = c + X[i];
435 0 : c = (t < X[i]);
436 0 : t += add;
437 0 : c += (t < add);
438 0 : X[i] = t;
439 : }
440 :
441 0 : return c;
442 : }
443 :
444 20725295 : mbedtls_mpi_uint mbedtls_mpi_core_sub(mbedtls_mpi_uint *X,
445 : const mbedtls_mpi_uint *A,
446 : const mbedtls_mpi_uint *B,
447 : size_t limbs)
448 : {
449 20725295 : mbedtls_mpi_uint c = 0;
450 :
451 107903385 : for (size_t i = 0; i < limbs; i++) {
452 87178090 : mbedtls_mpi_uint z = (A[i] < c);
453 87178090 : mbedtls_mpi_uint t = A[i] - c;
454 87178090 : c = (t < B[i]) + z;
455 87178090 : X[i] = t - B[i];
456 : }
457 :
458 20725295 : return c;
459 : }
460 :
461 33278313 : mbedtls_mpi_uint mbedtls_mpi_core_mla(mbedtls_mpi_uint *d, size_t d_len,
462 : const mbedtls_mpi_uint *s, size_t s_len,
463 : mbedtls_mpi_uint b)
464 : {
465 33278313 : mbedtls_mpi_uint c = 0; /* carry */
466 : /*
467 : * It is a documented precondition of this function that d_len >= s_len.
468 : * If that's not the case, we swap these round: this turns what would be
469 : * a buffer overflow into an incorrect result.
470 : */
471 33278313 : if (d_len < s_len) {
472 0 : s_len = d_len;
473 : }
474 33278313 : size_t excess_len = d_len - s_len;
475 33278313 : size_t steps_x8 = s_len / 8;
476 33278313 : size_t steps_x1 = s_len & 7;
477 :
478 59730159 : while (steps_x8--) {
479 26451846 : MULADDC_X8_INIT
480 : MULADDC_X8_CORE
481 : MULADDC_X8_STOP
482 : }
483 :
484 137435395 : while (steps_x1--) {
485 104157082 : MULADDC_X1_INIT
486 : MULADDC_X1_CORE
487 : MULADDC_X1_STOP
488 : }
489 :
490 82516519 : while (excess_len--) {
491 49238206 : *d += c;
492 49238206 : c = (*d < c);
493 49238206 : d++;
494 : }
495 :
496 33278313 : return c;
497 : }
498 :
499 6325187 : void mbedtls_mpi_core_mul(mbedtls_mpi_uint *X,
500 : const mbedtls_mpi_uint *A, size_t A_limbs,
501 : const mbedtls_mpi_uint *B, size_t B_limbs)
502 : {
503 6325187 : memset(X, 0, (A_limbs + B_limbs) * ciL);
504 :
505 31567867 : for (size_t i = 0; i < B_limbs; i++) {
506 25242680 : (void) mbedtls_mpi_core_mla(X + i, A_limbs + 1, A, A_limbs, B[i]);
507 : }
508 6325187 : }
509 :
510 : /*
511 : * Fast Montgomery initialization (thanks to Tom St Denis).
512 : */
513 1046 : mbedtls_mpi_uint mbedtls_mpi_core_montmul_init(const mbedtls_mpi_uint *N)
514 : {
515 1046 : mbedtls_mpi_uint x = N[0];
516 :
517 1046 : x += ((N[0] + 2) & 4) << 1;
518 :
519 5230 : for (unsigned int i = biL; i >= 8; i /= 2) {
520 4184 : x *= (2 - (N[0] * x));
521 : }
522 :
523 1046 : return ~x + 1;
524 : }
525 :
526 169860 : void mbedtls_mpi_core_montmul(mbedtls_mpi_uint *X,
527 : const mbedtls_mpi_uint *A,
528 : const mbedtls_mpi_uint *B,
529 : size_t B_limbs,
530 : const mbedtls_mpi_uint *N,
531 : size_t AN_limbs,
532 : mbedtls_mpi_uint mm,
533 : mbedtls_mpi_uint *T)
534 : {
535 169860 : memset(T, 0, (2 * AN_limbs + 1) * ciL);
536 :
537 3886397 : for (size_t i = 0; i < AN_limbs; i++) {
538 : /* T = (T + u0*B + u1*N) / 2^biL */
539 3716537 : mbedtls_mpi_uint u0 = A[i];
540 3716537 : mbedtls_mpi_uint u1 = (T[0] + u0 * B[0]) * mm;
541 :
542 3716537 : (void) mbedtls_mpi_core_mla(T, AN_limbs + 2, B, B_limbs, u0);
543 3716537 : (void) mbedtls_mpi_core_mla(T, AN_limbs + 2, N, AN_limbs, u1);
544 :
545 3716537 : T++;
546 : }
547 :
548 : /*
549 : * The result we want is (T >= N) ? T - N : T.
550 : *
551 : * For better constant-time properties in this function, we always do the
552 : * subtraction, with the result in X.
553 : *
554 : * We also look to see if there was any carry in the final additions in the
555 : * loop above.
556 : */
557 :
558 169860 : mbedtls_mpi_uint carry = T[AN_limbs];
559 169860 : mbedtls_mpi_uint borrow = mbedtls_mpi_core_sub(X, T, N, AN_limbs);
560 :
561 : /*
562 : * Using R as the Montgomery radix (auxiliary modulus) i.e. 2^(biL*AN_limbs):
563 : *
564 : * T can be in one of 3 ranges:
565 : *
566 : * 1) T < N : (carry, borrow) = (0, 1): we want T
567 : * 2) N <= T < R : (carry, borrow) = (0, 0): we want X
568 : * 3) T >= R : (carry, borrow) = (1, 1): we want X
569 : *
570 : * and (carry, borrow) = (1, 0) can't happen.
571 : *
572 : * So the correct return value is already in X if (carry ^ borrow) = 0,
573 : * but is in (the lower AN_limbs limbs of) T if (carry ^ borrow) = 1.
574 : */
575 169860 : mbedtls_ct_memcpy_if(mbedtls_ct_bool(carry ^ borrow),
576 : (unsigned char *) X,
577 : (unsigned char *) T,
578 : NULL,
579 : AN_limbs * sizeof(mbedtls_mpi_uint));
580 169860 : }
581 :
582 453 : int mbedtls_mpi_core_get_mont_r2_unsafe(mbedtls_mpi *X,
583 : const mbedtls_mpi *N)
584 : {
585 453 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
586 :
587 453 : MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 1));
588 453 : MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(X, N->n * 2 * biL));
589 453 : MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(X, X, N));
590 453 : MBEDTLS_MPI_CHK(mbedtls_mpi_shrink(X, N->n));
591 :
592 453 : cleanup:
593 453 : return ret;
594 : }
595 :
596 : MBEDTLS_STATIC_TESTABLE
597 41456 : void mbedtls_mpi_core_ct_uint_table_lookup(mbedtls_mpi_uint *dest,
598 : const mbedtls_mpi_uint *table,
599 : size_t limbs,
600 : size_t count,
601 : size_t index)
602 : {
603 343920 : for (size_t i = 0; i < count; i++, table += limbs) {
604 302464 : mbedtls_ct_condition_t assign = mbedtls_ct_uint_eq(i, index);
605 302464 : mbedtls_mpi_core_cond_assign(dest, table, limbs, assign);
606 : }
607 41456 : }
608 :
609 : /* Fill X with n_bytes random bytes.
610 : * X must already have room for those bytes.
611 : * The ordering of the bytes returned from the RNG is suitable for
612 : * deterministic ECDSA (see RFC 6979 §3.3 and the specification of
613 : * mbedtls_mpi_core_random()).
614 : */
615 1396 : int mbedtls_mpi_core_fill_random(
616 : mbedtls_mpi_uint *X, size_t X_limbs,
617 : size_t n_bytes,
618 : int (*f_rng)(void *, unsigned char *, size_t), void *p_rng)
619 : {
620 1396 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
621 1396 : const size_t limbs = CHARS_TO_LIMBS(n_bytes);
622 1396 : const size_t overhead = (limbs * ciL) - n_bytes;
623 :
624 1396 : if (X_limbs < limbs) {
625 0 : return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
626 : }
627 :
628 1396 : memset(X, 0, overhead);
629 1396 : memset((unsigned char *) X + limbs * ciL, 0, (X_limbs - limbs) * ciL);
630 1396 : MBEDTLS_MPI_CHK(f_rng(p_rng, (unsigned char *) X + overhead, n_bytes));
631 1396 : mbedtls_mpi_core_bigendian_to_host(X, limbs);
632 :
633 1396 : cleanup:
634 1396 : return ret;
635 : }
636 :
637 1244 : int mbedtls_mpi_core_random(mbedtls_mpi_uint *X,
638 : mbedtls_mpi_uint min,
639 : const mbedtls_mpi_uint *N,
640 : size_t limbs,
641 : int (*f_rng)(void *, unsigned char *, size_t),
642 : void *p_rng)
643 : {
644 1244 : mbedtls_ct_condition_t ge_lower = MBEDTLS_CT_TRUE, lt_upper = MBEDTLS_CT_FALSE;
645 1244 : size_t n_bits = mbedtls_mpi_core_bitlen(N, limbs);
646 1244 : size_t n_bytes = (n_bits + 7) / 8;
647 1244 : int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
648 :
649 : /*
650 : * When min == 0, each try has at worst a probability 1/2 of failing
651 : * (the msb has a probability 1/2 of being 0, and then the result will
652 : * be < N), so after 30 tries failure probability is a most 2**(-30).
653 : *
654 : * When N is just below a power of 2, as is the case when generating
655 : * a random scalar on most elliptic curves, 1 try is enough with
656 : * overwhelming probability. When N is just above a power of 2,
657 : * as when generating a random scalar on secp224k1, each try has
658 : * a probability of failing that is almost 1/2.
659 : *
660 : * The probabilities are almost the same if min is nonzero but negligible
661 : * compared to N. This is always the case when N is crypto-sized, but
662 : * it's convenient to support small N for testing purposes. When N
663 : * is small, use a higher repeat count, otherwise the probability of
664 : * failure is macroscopic.
665 : */
666 1244 : int count = (n_bytes > 4 ? 30 : 250);
667 :
668 : /*
669 : * Match the procedure given in RFC 6979 §3.3 (deterministic ECDSA)
670 : * when f_rng is a suitably parametrized instance of HMAC_DRBG:
671 : * - use the same byte ordering;
672 : * - keep the leftmost n_bits bits of the generated octet string;
673 : * - try until result is in the desired range.
674 : * This also avoids any bias, which is especially important for ECDSA.
675 : */
676 : do {
677 1244 : MBEDTLS_MPI_CHK(mbedtls_mpi_core_fill_random(X, limbs,
678 : n_bytes,
679 : f_rng, p_rng));
680 1244 : mbedtls_mpi_core_shift_r(X, limbs, 8 * n_bytes - n_bits);
681 :
682 1244 : if (--count == 0) {
683 0 : ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
684 0 : goto cleanup;
685 : }
686 :
687 1244 : ge_lower = mbedtls_mpi_core_uint_le_mpi(min, X, limbs);
688 1244 : lt_upper = mbedtls_mpi_core_lt_ct(X, N, limbs);
689 1244 : } while (mbedtls_ct_bool_and(ge_lower, lt_upper) == MBEDTLS_CT_FALSE);
690 :
691 1244 : cleanup:
692 1244 : return ret;
693 : }
694 :
695 1008 : static size_t exp_mod_get_window_size(size_t Ebits)
696 : {
697 : #if MBEDTLS_MPI_WINDOW_SIZE >= 6
698 : return (Ebits > 671) ? 6 : (Ebits > 239) ? 5 : (Ebits > 79) ? 4 : 1;
699 : #elif MBEDTLS_MPI_WINDOW_SIZE == 5
700 : return (Ebits > 239) ? 5 : (Ebits > 79) ? 4 : 1;
701 : #elif MBEDTLS_MPI_WINDOW_SIZE > 1
702 1008 : return (Ebits > 79) ? MBEDTLS_MPI_WINDOW_SIZE : 1;
703 : #else
704 : (void) Ebits;
705 : return 1;
706 : #endif
707 : }
708 :
709 504 : size_t mbedtls_mpi_core_exp_mod_working_limbs(size_t AN_limbs, size_t E_limbs)
710 : {
711 504 : const size_t wsize = exp_mod_get_window_size(E_limbs * biL);
712 504 : const size_t welem = ((size_t) 1) << wsize;
713 :
714 : /* How big does each part of the working memory pool need to be? */
715 504 : const size_t table_limbs = welem * AN_limbs;
716 504 : const size_t select_limbs = AN_limbs;
717 504 : const size_t temp_limbs = 2 * AN_limbs + 1;
718 :
719 504 : return table_limbs + select_limbs + temp_limbs;
720 : }
721 :
722 504 : static void exp_mod_precompute_window(const mbedtls_mpi_uint *A,
723 : const mbedtls_mpi_uint *N,
724 : size_t AN_limbs,
725 : mbedtls_mpi_uint mm,
726 : const mbedtls_mpi_uint *RR,
727 : size_t welem,
728 : mbedtls_mpi_uint *Wtable,
729 : mbedtls_mpi_uint *temp)
730 : {
731 : /* W[0] = 1 (in Montgomery presentation) */
732 504 : memset(Wtable, 0, AN_limbs * ciL);
733 504 : Wtable[0] = 1;
734 504 : mbedtls_mpi_core_montmul(Wtable, Wtable, RR, AN_limbs, N, AN_limbs, mm, temp);
735 :
736 : /* W[1] = A (already in Montgomery presentation) */
737 504 : mbedtls_mpi_uint *W1 = Wtable + AN_limbs;
738 504 : memcpy(W1, A, AN_limbs * ciL);
739 :
740 : /* W[i+1] = W[i] * W[1], i >= 2 */
741 504 : mbedtls_mpi_uint *Wprev = W1;
742 996 : for (size_t i = 2; i < welem; i++) {
743 492 : mbedtls_mpi_uint *Wcur = Wprev + AN_limbs;
744 492 : mbedtls_mpi_core_montmul(Wcur, Wprev, W1, AN_limbs, N, AN_limbs, mm, temp);
745 492 : Wprev = Wcur;
746 : }
747 504 : }
748 :
749 : #if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
750 : // Set to a default that is neither MBEDTLS_MPI_IS_PUBLIC nor MBEDTLS_MPI_IS_SECRET
751 : int mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC + MBEDTLS_MPI_IS_SECRET + 1;
752 : #endif
753 :
754 : /*
755 : * This function calculates the indices of the exponent where the exponentiation algorithm should
756 : * start processing.
757 : *
758 : * Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value,
759 : * this function is not constant time with respect to the exponent (parameter E).
760 : */
761 504 : static inline void exp_mod_calc_first_bit_optionally_safe(const mbedtls_mpi_uint *E,
762 : size_t E_limbs,
763 : int E_public,
764 : size_t *E_limb_index,
765 : size_t *E_bit_index)
766 : {
767 504 : if (E_public == MBEDTLS_MPI_IS_PUBLIC) {
768 : /*
769 : * Skip leading zero bits.
770 : */
771 346 : size_t E_bits = mbedtls_mpi_core_bitlen(E, E_limbs);
772 346 : if (E_bits == 0) {
773 : /*
774 : * If E is 0 mbedtls_mpi_core_bitlen() returns 0. Even if that is the case, we will want
775 : * to represent it as a single 0 bit and as such the bitlength will be 1.
776 : */
777 0 : E_bits = 1;
778 : }
779 :
780 346 : *E_limb_index = E_bits / biL;
781 346 : *E_bit_index = E_bits % biL;
782 :
783 : #if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
784 : mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC;
785 : #endif
786 : } else {
787 : /*
788 : * Here we need to be constant time with respect to E and can't do anything better than
789 : * start at the first allocated bit.
790 : */
791 158 : *E_limb_index = E_limbs;
792 158 : *E_bit_index = 0;
793 : #if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
794 : // Only mark the codepath safe if there wasn't an unsafe codepath before
795 : if (mbedtls_mpi_optionally_safe_codepath != MBEDTLS_MPI_IS_PUBLIC) {
796 : mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_SECRET;
797 : }
798 : #endif
799 : }
800 504 : }
801 :
802 : /*
803 : * Warning! If the parameter window_public has MBEDTLS_MPI_IS_PUBLIC as its value, this function is
804 : * not constant time with respect to the window parameter and consequently the exponent of the
805 : * exponentiation (parameter E of mbedtls_mpi_core_exp_mod_optionally_safe).
806 : */
807 47338 : static inline void exp_mod_table_lookup_optionally_safe(mbedtls_mpi_uint *Wselect,
808 : mbedtls_mpi_uint *Wtable,
809 : size_t AN_limbs, size_t welem,
810 : mbedtls_mpi_uint window,
811 : int window_public)
812 : {
813 47338 : if (window_public == MBEDTLS_MPI_IS_PUBLIC) {
814 5882 : memcpy(Wselect, Wtable + window * AN_limbs, AN_limbs * ciL);
815 : #if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
816 : mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_PUBLIC;
817 : #endif
818 : } else {
819 : /* Select Wtable[window] without leaking window through
820 : * memory access patterns. */
821 41456 : mbedtls_mpi_core_ct_uint_table_lookup(Wselect, Wtable,
822 : AN_limbs, welem, window);
823 : #if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
824 : // Only mark the codepath safe if there wasn't an unsafe codepath before
825 : if (mbedtls_mpi_optionally_safe_codepath != MBEDTLS_MPI_IS_PUBLIC) {
826 : mbedtls_mpi_optionally_safe_codepath = MBEDTLS_MPI_IS_SECRET;
827 : }
828 : #endif
829 : }
830 47338 : }
831 :
832 : /* Exponentiation: X := A^E mod N.
833 : *
834 : * Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value,
835 : * this function is not constant time with respect to the exponent (parameter E).
836 : *
837 : * A must already be in Montgomery form.
838 : *
839 : * As in other bignum functions, assume that AN_limbs and E_limbs are nonzero.
840 : *
841 : * RR must contain 2^{2*biL} mod N.
842 : *
843 : * The algorithm is a variant of Left-to-right k-ary exponentiation: HAC 14.82
844 : * (The difference is that the body in our loop processes a single bit instead
845 : * of a full window.)
846 : */
847 504 : static void mbedtls_mpi_core_exp_mod_optionally_safe(mbedtls_mpi_uint *X,
848 : const mbedtls_mpi_uint *A,
849 : const mbedtls_mpi_uint *N,
850 : size_t AN_limbs,
851 : const mbedtls_mpi_uint *E,
852 : size_t E_limbs,
853 : int E_public,
854 : const mbedtls_mpi_uint *RR,
855 : mbedtls_mpi_uint *T)
856 : {
857 : /* We'll process the bits of E from most significant
858 : * (limb_index=E_limbs-1, E_bit_index=biL-1) to least significant
859 : * (limb_index=0, E_bit_index=0). */
860 : size_t E_limb_index;
861 : size_t E_bit_index;
862 504 : exp_mod_calc_first_bit_optionally_safe(E, E_limbs, E_public,
863 : &E_limb_index, &E_bit_index);
864 :
865 504 : const size_t wsize = exp_mod_get_window_size(E_limb_index * biL);
866 504 : const size_t welem = ((size_t) 1) << wsize;
867 :
868 : /* This is how we will use the temporary storage T, which must have space
869 : * for table_limbs, select_limbs and (2 * AN_limbs + 1) for montmul. */
870 504 : const size_t table_limbs = welem * AN_limbs;
871 504 : const size_t select_limbs = AN_limbs;
872 :
873 : /* Pointers to specific parts of the temporary working memory pool */
874 504 : mbedtls_mpi_uint *const Wtable = T;
875 504 : mbedtls_mpi_uint *const Wselect = Wtable + table_limbs;
876 504 : mbedtls_mpi_uint *const temp = Wselect + select_limbs;
877 :
878 : /*
879 : * Window precomputation
880 : */
881 :
882 504 : const mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N);
883 :
884 : /* Set Wtable[i] = A^i (in Montgomery representation) */
885 504 : exp_mod_precompute_window(A, N, AN_limbs,
886 : mm, RR,
887 : welem, Wtable, temp);
888 :
889 : /*
890 : * Fixed window exponentiation
891 : */
892 :
893 : /* X = 1 (in Montgomery presentation) initially */
894 504 : memcpy(X, Wtable, AN_limbs * ciL);
895 :
896 : /* At any given time, window contains window_bits bits from E.
897 : * window_bits can go up to wsize. */
898 504 : size_t window_bits = 0;
899 504 : mbedtls_mpi_uint window = 0;
900 :
901 : do {
902 : /* Square */
903 120442 : mbedtls_mpi_core_montmul(X, X, X, AN_limbs, N, AN_limbs, mm, temp);
904 :
905 : /* Move to the next bit of the exponent */
906 120442 : if (E_bit_index == 0) {
907 1790 : --E_limb_index;
908 1790 : E_bit_index = biL - 1;
909 : } else {
910 118652 : --E_bit_index;
911 : }
912 : /* Insert next exponent bit into window */
913 120442 : ++window_bits;
914 120442 : window <<= 1;
915 120442 : window |= (E[E_limb_index] >> E_bit_index) & 1;
916 :
917 : /* Clear window if it's full. Also clear the window at the end,
918 : * when we've finished processing the exponent. */
919 120442 : if (window_bits == wsize ||
920 73184 : (E_bit_index == 0 && E_limb_index == 0)) {
921 :
922 47338 : exp_mod_table_lookup_optionally_safe(Wselect, Wtable, AN_limbs, welem,
923 : window, E_public);
924 : /* Multiply X by the selected element. */
925 47338 : mbedtls_mpi_core_montmul(X, X, Wselect, AN_limbs, N, AN_limbs, mm,
926 : temp);
927 47338 : window = 0;
928 47338 : window_bits = 0;
929 : }
930 120442 : } while (!(E_bit_index == 0 && E_limb_index == 0));
931 504 : }
932 :
933 158 : void mbedtls_mpi_core_exp_mod(mbedtls_mpi_uint *X,
934 : const mbedtls_mpi_uint *A,
935 : const mbedtls_mpi_uint *N, size_t AN_limbs,
936 : const mbedtls_mpi_uint *E, size_t E_limbs,
937 : const mbedtls_mpi_uint *RR,
938 : mbedtls_mpi_uint *T)
939 : {
940 158 : mbedtls_mpi_core_exp_mod_optionally_safe(X,
941 : A,
942 : N,
943 : AN_limbs,
944 : E,
945 : E_limbs,
946 : MBEDTLS_MPI_IS_SECRET,
947 : RR,
948 : T);
949 158 : }
950 :
951 346 : void mbedtls_mpi_core_exp_mod_unsafe(mbedtls_mpi_uint *X,
952 : const mbedtls_mpi_uint *A,
953 : const mbedtls_mpi_uint *N, size_t AN_limbs,
954 : const mbedtls_mpi_uint *E, size_t E_limbs,
955 : const mbedtls_mpi_uint *RR,
956 : mbedtls_mpi_uint *T)
957 : {
958 346 : mbedtls_mpi_core_exp_mod_optionally_safe(X,
959 : A,
960 : N,
961 : AN_limbs,
962 : E,
963 : E_limbs,
964 : MBEDTLS_MPI_IS_PUBLIC,
965 : RR,
966 : T);
967 346 : }
968 :
969 4508045 : mbedtls_mpi_uint mbedtls_mpi_core_sub_int(mbedtls_mpi_uint *X,
970 : const mbedtls_mpi_uint *A,
971 : mbedtls_mpi_uint c, /* doubles as carry */
972 : size_t limbs)
973 : {
974 25496584 : for (size_t i = 0; i < limbs; i++) {
975 20988539 : mbedtls_mpi_uint s = A[i];
976 20988539 : mbedtls_mpi_uint t = s - c;
977 20988539 : c = (t > s);
978 20988539 : X[i] = t;
979 : }
980 :
981 4508045 : return c;
982 : }
983 :
984 0 : mbedtls_ct_condition_t mbedtls_mpi_core_check_zero_ct(const mbedtls_mpi_uint *A,
985 : size_t limbs)
986 : {
987 0 : volatile const mbedtls_mpi_uint *force_read_A = A;
988 0 : mbedtls_mpi_uint bits = 0;
989 :
990 0 : for (size_t i = 0; i < limbs; i++) {
991 0 : bits |= force_read_A[i];
992 : }
993 :
994 0 : return mbedtls_ct_bool(bits);
995 : }
996 :
997 542 : void mbedtls_mpi_core_to_mont_rep(mbedtls_mpi_uint *X,
998 : const mbedtls_mpi_uint *A,
999 : const mbedtls_mpi_uint *N,
1000 : size_t AN_limbs,
1001 : mbedtls_mpi_uint mm,
1002 : const mbedtls_mpi_uint *rr,
1003 : mbedtls_mpi_uint *T)
1004 : {
1005 542 : mbedtls_mpi_core_montmul(X, A, rr, AN_limbs, N, AN_limbs, mm, T);
1006 542 : }
1007 :
1008 504 : void mbedtls_mpi_core_from_mont_rep(mbedtls_mpi_uint *X,
1009 : const mbedtls_mpi_uint *A,
1010 : const mbedtls_mpi_uint *N,
1011 : size_t AN_limbs,
1012 : mbedtls_mpi_uint mm,
1013 : mbedtls_mpi_uint *T)
1014 : {
1015 504 : const mbedtls_mpi_uint Rinv = 1; /* 1/R in Mont. rep => 1 */
1016 :
1017 504 : mbedtls_mpi_core_montmul(X, A, &Rinv, 1, N, AN_limbs, mm, T);
1018 504 : }
1019 :
1020 : #endif /* MBEDTLS_BIGNUM_C */
|