NCBI C++ ToolKit
constant_time.c
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /**
2  * Constant-time functions
3  *
4  * Copyright The Mbed TLS Contributors
5  * SPDX-License-Identifier: Apache-2.0
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may
8  * not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 /*
21  * The following functions are implemented without using comparison operators, as those
22  * might be translated to branches by some compilers on some platforms.
23  */
24 
25 #include "common.h"
26 #include "constant_time_internal.h"
27 #include "mbedtls/constant_time.h"
28 #include "mbedtls/error.h"
29 #include "mbedtls/platform_util.h"
30 
31 #if defined(MBEDTLS_BIGNUM_C)
32 #include "mbedtls/bignum.h"
33 #endif
34 
35 #if defined(MBEDTLS_SSL_TLS_C)
36 #include "mbedtls/ssl_internal.h"
37 #endif
38 
39 #if defined(MBEDTLS_RSA_C)
40 #include "mbedtls/rsa.h"
41 #endif
42 
43 #if defined(MBEDTLS_BASE64_C)
44 #include "constant_time_invasive.h"
45 #endif
46 
47 #include <string.h>
48 
49 int mbedtls_ct_memcmp(const void *a,
50  const void *b,
51  size_t n)
52 {
53  size_t i;
54  volatile const unsigned char *A = (volatile const unsigned char *) a;
55  volatile const unsigned char *B = (volatile const unsigned char *) b;
56  volatile unsigned char diff = 0;
57 
58  for (i = 0; i < n; i++) {
59  /* Read volatile data in order before computing diff.
60  * This avoids IAR compiler warning:
61  * 'the order of volatile accesses is undefined ..' */
62  unsigned char x = A[i], y = B[i];
63  diff |= x ^ y;
64  }
65 
66  return (int) diff;
67 }
68 
69 unsigned mbedtls_ct_uint_mask(unsigned value)
70 {
71  /* MSVC has a warning about unary minus on unsigned, but this is
72  * well-defined and precisely what we want to do here */
73 #if defined(_MSC_VER)
74 #pragma warning( push )
75 #pragma warning( disable : 4146 )
76 #endif
77  return -((value | -value) >> (sizeof(value) * 8 - 1));
78 #if defined(_MSC_VER)
79 #pragma warning( pop )
80 #endif
81 }
82 
83 #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
84 
86 {
87  /* MSVC has a warning about unary minus on unsigned integer types,
88  * but this is well-defined and precisely what we want to do here. */
89 #if defined(_MSC_VER)
90 #pragma warning( push )
91 #pragma warning( disable : 4146 )
92 #endif
93  return -((value | -value) >> (sizeof(value) * 8 - 1));
94 #if defined(_MSC_VER)
95 #pragma warning( pop )
96 #endif
97 }
98 
99 #endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
100 
101 #if defined(MBEDTLS_BIGNUM_C)
102 
104 {
105  /* MSVC has a warning about unary minus on unsigned, but this is
106  * well-defined and precisely what we want to do here */
107 #if defined(_MSC_VER)
108 #pragma warning( push )
109 #pragma warning( disable : 4146 )
110 #endif
111  return -((value | -value) >> (sizeof(value) * 8 - 1));
112 #if defined(_MSC_VER)
113 #pragma warning( pop )
114 #endif
115 }
116 
117 #endif /* MBEDTLS_BIGNUM_C */
118 
119 #if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
120 
121 /** Constant-flow mask generation for "less than" comparison:
122  * - if \p x < \p y, return all-bits 1, that is (size_t) -1
123  * - otherwise, return all bits 0, that is 0
124  *
125  * This function can be used to write constant-time code by replacing branches
126  * with bit operations using masks.
127  *
128  * \param x The first value to analyze.
129  * \param y The second value to analyze.
130  *
131  * \return All-bits-one if \p x is less than \p y, otherwise zero.
132  */
133 static size_t mbedtls_ct_size_mask_lt(size_t x,
134  size_t y)
135 {
136  /* This has the most significant bit set if and only if x < y */
137  const size_t sub = x - y;
138 
139  /* sub1 = (x < y) ? 1 : 0 */
140  const size_t sub1 = sub >> (sizeof(sub) * 8 - 1);
141 
142  /* mask = (x < y) ? 0xff... : 0x00... */
143  const size_t mask = mbedtls_ct_size_mask(sub1);
144 
145  return mask;
146 }
147 
148 size_t mbedtls_ct_size_mask_ge(size_t x,
149  size_t y)
150 {
151  return ~mbedtls_ct_size_mask_lt(x, y);
152 }
153 
154 #endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
155 
156 #if defined(MBEDTLS_BASE64_C)
157 
158 /* Return 0xff if low <= c <= high, 0 otherwise.
159  *
160  * Constant flow with respect to c.
161  */
163 unsigned char mbedtls_ct_uchar_mask_of_range(unsigned char low,
164  unsigned char high,
165  unsigned char c)
166 {
167  /* low_mask is: 0 if low <= c, 0x...ff if low > c */
168  unsigned low_mask = ((unsigned) c - low) >> 8;
169  /* high_mask is: 0 if c <= high, 0x...ff if c > high */
170  unsigned high_mask = ((unsigned) high - c) >> 8;
171  return ~(low_mask | high_mask) & 0xff;
172 }
173 
174 #endif /* MBEDTLS_BASE64_C */
175 
176 unsigned mbedtls_ct_size_bool_eq(size_t x,
177  size_t y)
178 {
179  /* diff = 0 if x == y, non-zero otherwise */
180  const size_t diff = x ^ y;
181 
182  /* MSVC has a warning about unary minus on unsigned integer types,
183  * but this is well-defined and precisely what we want to do here. */
184 #if defined(_MSC_VER)
185 #pragma warning( push )
186 #pragma warning( disable : 4146 )
187 #endif
188 
189  /* diff_msb's most significant bit is equal to x != y */
190  const size_t diff_msb = (diff | (size_t) -diff);
191 
192 #if defined(_MSC_VER)
193 #pragma warning( pop )
194 #endif
195 
196  /* diff1 = (x != y) ? 1 : 0 */
197  const unsigned diff1 = diff_msb >> (sizeof(diff_msb) * 8 - 1);
198 
199  return 1 ^ diff1;
200 }
201 
202 #if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
203 
204 /** Constant-flow "greater than" comparison:
205  * return x > y
206  *
207  * This is equivalent to \p x > \p y, but is likely to be compiled
208  * to code using bitwise operation rather than a branch.
209  *
210  * \param x The first value to analyze.
211  * \param y The second value to analyze.
212  *
213  * \return 1 if \p x greater than \p y, otherwise 0.
214  */
215 static unsigned mbedtls_ct_size_gt(size_t x,
216  size_t y)
217 {
218  /* Return the sign bit (1 for negative) of (y - x). */
219  return (y - x) >> (sizeof(size_t) * 8 - 1);
220 }
221 
222 #endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
223 
224 #if defined(MBEDTLS_BIGNUM_C)
225 
227  const mbedtls_mpi_uint y)
228 {
229  mbedtls_mpi_uint ret;
230  mbedtls_mpi_uint cond;
231 
232  /*
233  * Check if the most significant bits (MSB) of the operands are different.
234  */
235  cond = (x ^ y);
236  /*
237  * If the MSB are the same then the difference x-y will be negative (and
238  * have its MSB set to 1 during conversion to unsigned) if and only if x<y.
239  */
240  ret = (x - y) & ~cond;
241  /*
242  * If the MSB are different, then the operand with the MSB of 1 is the
243  * bigger. (That is if y has MSB of 1, then x<y is true and it is false if
244  * the MSB of y is 0.)
245  */
246  ret |= y & cond;
247 
248 
249  ret = ret >> (sizeof(mbedtls_mpi_uint) * 8 - 1);
250 
251  return (unsigned) ret;
252 }
253 
254 #endif /* MBEDTLS_BIGNUM_C */
255 
256 unsigned mbedtls_ct_uint_if(unsigned condition,
257  unsigned if1,
258  unsigned if0)
259 {
260  unsigned mask = mbedtls_ct_uint_mask(condition);
261  return (mask & if1) | (~mask & if0);
262 }
263 
264 #if defined(MBEDTLS_BIGNUM_C)
265 
266 /** Select between two sign values without branches.
267  *
268  * This is functionally equivalent to `condition ? if1 : if0` but uses only bit
269  * operations in order to avoid branches.
270  *
271  * \note if1 and if0 must be either 1 or -1, otherwise the result
272  * is undefined.
273  *
274  * \param condition Condition to test; must be either 0 or 1.
275  * \param if1 The first sign; must be either +1 or -1.
276  * \param if0 The second sign; must be either +1 or -1.
277  *
278  * \return \c if1 if \p condition is nonzero, otherwise \c if0.
279  * */
280 static int mbedtls_ct_cond_select_sign(unsigned char condition,
281  int if1,
282  int if0)
283 {
284  /* In order to avoid questions about what we can reasonably assume about
285  * the representations of signed integers, move everything to unsigned
286  * by taking advantage of the fact that if1 and if0 are either +1 or -1. */
287  unsigned uif1 = if1 + 1;
288  unsigned uif0 = if0 + 1;
289 
290  /* condition was 0 or 1, mask is 0 or 2 as are uif1 and uif0 */
291  const unsigned mask = condition << 1;
292 
293  /* select uif1 or uif0 */
294  unsigned ur = (uif0 & ~mask) | (uif1 & mask);
295 
296  /* ur is now 0 or 2, convert back to -1 or +1 */
297  return (int) ur - 1;
298 }
299 
301  mbedtls_mpi_uint *dest,
302  const mbedtls_mpi_uint *src,
303  unsigned char condition)
304 {
305  size_t i;
306 
307  /* MSVC has a warning about unary minus on unsigned integer types,
308  * but this is well-defined and precisely what we want to do here. */
309 #if defined(_MSC_VER)
310 #pragma warning( push )
311 #pragma warning( disable : 4146 )
312 #endif
313 
314  /* all-bits 1 if condition is 1, all-bits 0 if condition is 0 */
315  const mbedtls_mpi_uint mask = -condition;
316 
317 #if defined(_MSC_VER)
318 #pragma warning( pop )
319 #endif
320 
321  for (i = 0; i < n; i++) {
322  dest[i] = (src[i] & mask) | (dest[i] & ~mask);
323  }
324 }
325 
326 #endif /* MBEDTLS_BIGNUM_C */
327 
328 #if defined(MBEDTLS_BASE64_C)
329 
330 unsigned char mbedtls_ct_base64_enc_char(unsigned char value)
331 {
332  unsigned char digit = 0;
333  /* For each range of values, if value is in that range, mask digit with
334  * the corresponding value. Since value can only be in a single range,
335  * only at most one masking will change digit. */
336  digit |= mbedtls_ct_uchar_mask_of_range(0, 25, value) & ('A' + value);
337  digit |= mbedtls_ct_uchar_mask_of_range(26, 51, value) & ('a' + value - 26);
338  digit |= mbedtls_ct_uchar_mask_of_range(52, 61, value) & ('0' + value - 52);
339  digit |= mbedtls_ct_uchar_mask_of_range(62, 62, value) & '+';
340  digit |= mbedtls_ct_uchar_mask_of_range(63, 63, value) & '/';
341  return digit;
342 }
343 
344 signed char mbedtls_ct_base64_dec_value(unsigned char c)
345 {
346  unsigned char val = 0;
347  /* For each range of digits, if c is in that range, mask val with
348  * the corresponding value. Since c can only be in a single range,
349  * only at most one masking will change val. Set val to one plus
350  * the desired value so that it stays 0 if c is in none of the ranges. */
351  val |= mbedtls_ct_uchar_mask_of_range('A', 'Z', c) & (c - 'A' + 0 + 1);
352  val |= mbedtls_ct_uchar_mask_of_range('a', 'z', c) & (c - 'a' + 26 + 1);
353  val |= mbedtls_ct_uchar_mask_of_range('0', '9', c) & (c - '0' + 52 + 1);
354  val |= mbedtls_ct_uchar_mask_of_range('+', '+', c) & (c - '+' + 62 + 1);
355  val |= mbedtls_ct_uchar_mask_of_range('/', '/', c) & (c - '/' + 63 + 1);
356  /* At this point, val is 0 if c is an invalid digit and v+1 if c is
357  * a digit with the value v. */
358  return val - 1;
359 }
360 
361 #endif /* MBEDTLS_BASE64_C */
362 
363 #if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
364 
365 /** Shift some data towards the left inside a buffer.
366  *
367  * `mbedtls_ct_mem_move_to_left(start, total, offset)` is functionally
368  * equivalent to
369  * ```
370  * memmove(start, start + offset, total - offset);
371  * memset(start + offset, 0, total - offset);
372  * ```
373  * but it strives to use a memory access pattern (and thus total timing)
374  * that does not depend on \p offset. This timing independence comes at
375  * the expense of performance.
376  *
377  * \param start Pointer to the start of the buffer.
378  * \param total Total size of the buffer.
379  * \param offset Offset from which to copy \p total - \p offset bytes.
380  */
381 static void mbedtls_ct_mem_move_to_left(void *start,
382  size_t total,
383  size_t offset)
384 {
385  volatile unsigned char *buf = start;
386  size_t i, n;
387  if (total == 0) {
388  return;
389  }
390  for (i = 0; i < total; i++) {
391  unsigned no_op = mbedtls_ct_size_gt(total - offset, i);
392  /* The first `total - offset` passes are a no-op. The last
393  * `offset` passes shift the data one byte to the left and
394  * zero out the last byte. */
395  for (n = 0; n < total - 1; n++) {
396  unsigned char current = buf[n];
397  unsigned char next = buf[n+1];
398  buf[n] = mbedtls_ct_uint_if(no_op, current, next);
399  }
400  buf[total-1] = mbedtls_ct_uint_if(no_op, buf[total-1], 0);
401  }
402 }
403 
404 #endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
405 
406 #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
407 void mbedtls_ct_memcpy_if_eq(unsigned char *dest,
408  const unsigned char *src,
409  size_t len,
410  size_t c1,
411  size_t c2)
412 {
413  /* mask = c1 == c2 ? 0xff : 0x00 */
414  const size_t equal = mbedtls_ct_size_bool_eq(c1, c2);
415  const unsigned char mask = (unsigned char) mbedtls_ct_size_mask(equal);
416 
417  /* dest[i] = c1 == c2 ? src[i] : dest[i] */
418  for (size_t i = 0; i < len; i++) {
419  dest[i] = (src[i] & mask) | (dest[i] & ~mask);
420  }
421 }
422 
423 void mbedtls_ct_memcpy_offset(unsigned char *dest,
424  const unsigned char *src,
425  size_t offset,
426  size_t offset_min,
427  size_t offset_max,
428  size_t len)
429 {
430  size_t offsetval;
431 
432  for (offsetval = offset_min; offsetval <= offset_max; offsetval++) {
433  mbedtls_ct_memcpy_if_eq(dest, src + offsetval, len,
434  offsetval, offset);
435  }
436 }
437 
439  const unsigned char *add_data,
440  size_t add_data_len,
441  const unsigned char *data,
442  size_t data_len_secret,
443  size_t min_data_len,
444  size_t max_data_len,
445  unsigned char *output)
446 {
447  /*
448  * This function breaks the HMAC abstraction and uses the md_clone()
449  * extension to the MD API in order to get constant-flow behaviour.
450  *
451  * HMAC(msg) is defined as HASH(okey + HASH(ikey + msg)) where + means
452  * concatenation, and okey/ikey are the XOR of the key with some fixed bit
453  * patterns (see RFC 2104, sec. 2), which are stored in ctx->hmac_ctx.
454  *
455  * We'll first compute inner_hash = HASH(ikey + msg) by hashing up to
456  * minlen, then cloning the context, and for each byte up to maxlen
457  * finishing up the hash computation, keeping only the correct result.
458  *
459  * Then we only need to compute HASH(okey + inner_hash) and we're done.
460  */
461  const mbedtls_md_type_t md_alg = mbedtls_md_get_type(ctx->md_info);
462  /* TLS 1.0-1.2 only support SHA-384, SHA-256, SHA-1, MD-5,
463  * all of which have the same block size except SHA-384. */
464  const size_t block_size = md_alg == MBEDTLS_MD_SHA384 ? 128 : 64;
465  const unsigned char * const ikey = ctx->hmac_ctx;
466  const unsigned char * const okey = ikey + block_size;
467  const size_t hash_size = mbedtls_md_get_size(ctx->md_info);
468 
469  unsigned char aux_out[MBEDTLS_MD_MAX_SIZE];
471  size_t offset;
473 
474  mbedtls_md_init(&aux);
475 
476 #define MD_CHK(func_call) \
477  do { \
478  ret = (func_call); \
479  if (ret != 0) \
480  goto cleanup; \
481  } while (0)
482 
483  MD_CHK(mbedtls_md_setup(&aux, ctx->md_info, 0));
484 
485  /* After hmac_start() of hmac_reset(), ikey has already been hashed,
486  * so we can start directly with the message */
487  MD_CHK(mbedtls_md_update(ctx, add_data, add_data_len));
488  MD_CHK(mbedtls_md_update(ctx, data, min_data_len));
489 
490  /* Fill the hash buffer in advance with something that is
491  * not a valid hash (barring an attack on the hash and
492  * deliberately-crafted input), in case the caller doesn't
493  * check the return status properly. */
494  memset(output, '!', hash_size);
495 
496  /* For each possible length, compute the hash up to that point */
497  for (offset = min_data_len; offset <= max_data_len; offset++) {
498  MD_CHK(mbedtls_md_clone(&aux, ctx));
499  MD_CHK(mbedtls_md_finish(&aux, aux_out));
500  /* Keep only the correct inner_hash in the output buffer */
501  mbedtls_ct_memcpy_if_eq(output, aux_out, hash_size,
502  offset, data_len_secret);
503 
504  if (offset < max_data_len) {
506  }
507  }
508 
509  /* The context needs to finish() before it starts() again */
510  MD_CHK(mbedtls_md_finish(ctx, aux_out));
511 
512  /* Now compute HASH(okey + inner_hash) */
514  MD_CHK(mbedtls_md_update(ctx, okey, block_size));
515  MD_CHK(mbedtls_md_update(ctx, output, hash_size));
517 
518  /* Done, get ready for next time */
520 
521 #undef MD_CHK
522 
523 cleanup:
524  mbedtls_md_free(&aux);
525  return ret;
526 }
527 
528 #endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
529 
530 #if defined(MBEDTLS_BIGNUM_C)
531 
532 #define MPI_VALIDATE_RET(cond) \
533  MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_MPI_BAD_INPUT_DATA)
534 
535 /*
536  * Conditionally assign X = Y, without leaking information
537  * about whether the assignment was made or not.
538  * (Leaking information about the respective sizes of X and Y is ok however.)
539  */
540 #if defined(_MSC_VER) && defined(_M_ARM64) && (_MSC_FULL_VER < 193131103)
541 /*
542  * MSVC miscompiles this function if it's inlined prior to Visual Studio 2022 version 17.1. See:
543  * https://developercommunity.visualstudio.com/t/c-compiler-miscompiles-part-of-mbedtls-library-on/1646989
544  */
545 __declspec(noinline)
546 #endif
548  const mbedtls_mpi *Y,
549  unsigned char assign)
550 {
551  int ret = 0;
552  size_t i;
553  mbedtls_mpi_uint limb_mask;
554  MPI_VALIDATE_RET(X != NULL);
555  MPI_VALIDATE_RET(Y != NULL);
556 
557  /* all-bits 1 if assign is 1, all-bits 0 if assign is 0 */
558  limb_mask = mbedtls_ct_mpi_uint_mask(assign);;
559 
561 
562  X->s = mbedtls_ct_cond_select_sign(assign, Y->s, X->s);
563 
564  mbedtls_ct_mpi_uint_cond_assign(Y->n, X->p, Y->p, assign);
565 
566  for (i = Y->n; i < X->n; i++) {
567  X->p[i] &= ~limb_mask;
568  }
569 
570 cleanup:
571  return ret;
572 }
573 
574 /*
575  * Conditionally swap X and Y, without leaking information
576  * about whether the swap was made or not.
577  * Here it is not ok to simply swap the pointers, which would lead to
578  * different memory access patterns when X and Y are used afterwards.
579  */
581  mbedtls_mpi *Y,
582  unsigned char swap)
583 {
584  int ret, s;
585  size_t i;
586  mbedtls_mpi_uint limb_mask;
588  MPI_VALIDATE_RET(X != NULL);
589  MPI_VALIDATE_RET(Y != NULL);
590 
591  if (X == Y) {
592  return 0;
593  }
594 
595  /* all-bits 1 if swap is 1, all-bits 0 if swap is 0 */
596  limb_mask = mbedtls_ct_mpi_uint_mask(swap);
597 
600 
601  s = X->s;
602  X->s = mbedtls_ct_cond_select_sign(swap, Y->s, X->s);
603  Y->s = mbedtls_ct_cond_select_sign(swap, s, Y->s);
604 
605 
606  for (i = 0; i < X->n; i++) {
607  tmp = X->p[i];
608  X->p[i] = (X->p[i] & ~limb_mask) | (Y->p[i] & limb_mask);
609  Y->p[i] = (Y->p[i] & ~limb_mask) | (tmp & limb_mask);
610  }
611 
612 cleanup:
613  return ret;
614 }
615 
616 /*
617  * Compare signed values in constant time
618  */
620  const mbedtls_mpi *Y,
621  unsigned *ret)
622 {
623  size_t i;
624  /* The value of any of these variables is either 0 or 1 at all times. */
625  unsigned cond, done, X_is_negative, Y_is_negative;
626 
627  MPI_VALIDATE_RET(X != NULL);
628  MPI_VALIDATE_RET(Y != NULL);
629  MPI_VALIDATE_RET(ret != NULL);
630 
631  if (X->n != Y->n) {
633  }
634 
635  /*
636  * Set sign_N to 1 if N >= 0, 0 if N < 0.
637  * We know that N->s == 1 if N >= 0 and N->s == -1 if N < 0.
638  */
639  X_is_negative = (X->s & 2) >> 1;
640  Y_is_negative = (Y->s & 2) >> 1;
641 
642  /*
643  * If the signs are different, then the positive operand is the bigger.
644  * That is if X is negative (X_is_negative == 1), then X < Y is true and it
645  * is false if X is positive (X_is_negative == 0).
646  */
647  cond = (X_is_negative ^ Y_is_negative);
648  *ret = cond & X_is_negative;
649 
650  /*
651  * This is a constant-time function. We might have the result, but we still
652  * need to go through the loop. Record if we have the result already.
653  */
654  done = cond;
655 
656  for (i = X->n; i > 0; i--) {
657  /*
658  * If Y->p[i - 1] < X->p[i - 1] then X < Y is true if and only if both
659  * X and Y are negative.
660  *
661  * Again even if we can make a decision, we just mark the result and
662  * the fact that we are done and continue looping.
663  */
664  cond = mbedtls_ct_mpi_uint_lt(Y->p[i - 1], X->p[i - 1]);
665  *ret |= cond & (1 - done) & X_is_negative;
666  done |= cond;
667 
668  /*
669  * If X->p[i - 1] < Y->p[i - 1] then X < Y is true if and only if both
670  * X and Y are positive.
671  *
672  * Again even if we can make a decision, we just mark the result and
673  * the fact that we are done and continue looping.
674  */
675  cond = mbedtls_ct_mpi_uint_lt(X->p[i - 1], Y->p[i - 1]);
676  *ret |= cond & (1 - done) & (1 - X_is_negative);
677  done |= cond;
678  }
679 
680  return 0;
681 }
682 
683 #endif /* MBEDTLS_BIGNUM_C */
684 
685 #if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
686 
688  unsigned char *input,
689  size_t ilen,
690  unsigned char *output,
691  size_t output_max_len,
692  size_t *olen)
693 {
695  size_t i, plaintext_max_size;
696 
697  /* The following variables take sensitive values: their value must
698  * not leak into the observable behavior of the function other than
699  * the designated outputs (output, olen, return value). Otherwise
700  * this would open the execution of the function to
701  * side-channel-based variants of the Bleichenbacher padding oracle
702  * attack. Potential side channels include overall timing, memory
703  * access patterns (especially visible to an adversary who has access
704  * to a shared memory cache), and branches (especially visible to
705  * an adversary who has access to a shared code cache or to a shared
706  * branch predictor). */
707  size_t pad_count = 0;
708  unsigned bad = 0;
709  unsigned char pad_done = 0;
710  size_t plaintext_size = 0;
711  unsigned output_too_large;
712 
713  plaintext_max_size = (output_max_len > ilen - 11) ? ilen - 11
714  : output_max_len;
715 
716  /* Check and get padding length in constant time and constant
717  * memory trace. The first byte must be 0. */
718  bad |= input[0];
719 
720  if (mode == MBEDTLS_RSA_PRIVATE) {
721  /* Decode EME-PKCS1-v1_5 padding: 0x00 || 0x02 || PS || 0x00
722  * where PS must be at least 8 nonzero bytes. */
723  bad |= input[1] ^ MBEDTLS_RSA_CRYPT;
724 
725  /* Read the whole buffer. Set pad_done to nonzero if we find
726  * the 0x00 byte and remember the padding length in pad_count. */
727  for (i = 2; i < ilen; i++) {
728  pad_done |= ((input[i] | (unsigned char) -input[i]) >> 7) ^ 1;
729  pad_count += ((pad_done | (unsigned char) -pad_done) >> 7) ^ 1;
730  }
731  } else {
732  /* Decode EMSA-PKCS1-v1_5 padding: 0x00 || 0x01 || PS || 0x00
733  * where PS must be at least 8 bytes with the value 0xFF. */
734  bad |= input[1] ^ MBEDTLS_RSA_SIGN;
735 
736  /* Read the whole buffer. Set pad_done to nonzero if we find
737  * the 0x00 byte and remember the padding length in pad_count.
738  * If there's a non-0xff byte in the padding, the padding is bad. */
739  for (i = 2; i < ilen; i++) {
740  pad_done |= mbedtls_ct_uint_if(input[i], 0, 1);
741  pad_count += mbedtls_ct_uint_if(pad_done, 0, 1);
742  bad |= mbedtls_ct_uint_if(pad_done, 0, input[i] ^ 0xFF);
743  }
744  }
745 
746  /* If pad_done is still zero, there's no data, only unfinished padding. */
747  bad |= mbedtls_ct_uint_if(pad_done, 0, 1);
748 
749  /* There must be at least 8 bytes of padding. */
750  bad |= mbedtls_ct_size_gt(8, pad_count);
751 
752  /* If the padding is valid, set plaintext_size to the number of
753  * remaining bytes after stripping the padding. If the padding
754  * is invalid, avoid leaking this fact through the size of the
755  * output: use the maximum message size that fits in the output
756  * buffer. Do it without branches to avoid leaking the padding
757  * validity through timing. RSA keys are small enough that all the
758  * size_t values involved fit in unsigned int. */
759  plaintext_size = mbedtls_ct_uint_if(
760  bad, (unsigned) plaintext_max_size,
761  (unsigned) (ilen - pad_count - 3));
762 
763  /* Set output_too_large to 0 if the plaintext fits in the output
764  * buffer and to 1 otherwise. */
765  output_too_large = mbedtls_ct_size_gt(plaintext_size,
766  plaintext_max_size);
767 
768  /* Set ret without branches to avoid timing attacks. Return:
769  * - INVALID_PADDING if the padding is bad (bad != 0).
770  * - OUTPUT_TOO_LARGE if the padding is good but the decrypted
771  * plaintext does not fit in the output buffer.
772  * - 0 if the padding is correct. */
773  ret = -(int) mbedtls_ct_uint_if(
775  mbedtls_ct_uint_if(output_too_large,
777  0));
778 
779  /* If the padding is bad or the plaintext is too large, zero the
780  * data that we're about to copy to the output buffer.
781  * We need to copy the same amount of data
782  * from the same buffer whether the padding is good or not to
783  * avoid leaking the padding validity through overall timing or
784  * through memory or cache access patterns. */
785  bad = mbedtls_ct_uint_mask(bad | output_too_large);
786  for (i = 11; i < ilen; i++) {
787  input[i] &= ~bad;
788  }
789 
790  /* If the plaintext is too large, truncate it to the buffer size.
791  * Copy anyway to avoid revealing the length through timing, because
792  * revealing the length is as bad as revealing the padding validity
793  * for a Bleichenbacher attack. */
794  plaintext_size = mbedtls_ct_uint_if(output_too_large,
795  (unsigned) plaintext_max_size,
796  (unsigned) plaintext_size);
797 
798  /* Move the plaintext to the leftmost position where it can start in
799  * the working buffer, i.e. make it start plaintext_max_size from
800  * the end of the buffer. Do this with a memory access trace that
801  * does not depend on the plaintext size. After this move, the
802  * starting location of the plaintext is no longer sensitive
803  * information. */
804  mbedtls_ct_mem_move_to_left(input + ilen - plaintext_max_size,
805  plaintext_max_size,
806  plaintext_max_size - plaintext_size);
807 
808  /* Finally copy the decrypted plaintext plus trailing zeros into the output
809  * buffer. If output_max_len is 0, then output may be an invalid pointer
810  * and the result of memcpy() would be undefined; prevent undefined
811  * behavior making sure to depend only on output_max_len (the size of the
812  * user-provided output buffer), which is independent from plaintext
813  * length, validity of padding, success of the decryption, and other
814  * secrets. */
815  if (output_max_len != 0) {
816  memcpy(output, input + ilen - plaintext_max_size, plaintext_max_size);
817  }
818 
819  /* Report the amount of data we copied to the output buffer. In case
820  * of errors (bad padding or output too large), the value of *olen
821  * when this function returns is not specified. Making it equivalent
822  * to the good case limits the risks of leaking the padding validity. */
823  *olen = plaintext_size;
824 
825  return ret;
826 }
827 
828 #endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
Multi-precision integer library.
int mbedtls_mpi_safe_cond_swap(mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char swap)
Perform a safe conditional swap which doesn't reveal whether the condition was true or not.
int mbedtls_mpi_grow(mbedtls_mpi *X, size_t nblimbs)
Enlarge an MPI to the specified number of limbs.
#define MBEDTLS_ERR_MPI_BAD_INPUT_DATA
Bad input parameters to function.
Definition: bignum.h:41
int mbedtls_mpi_safe_cond_assign(mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign)
Perform a safe conditional copy of MPI which doesn't reveal whether the condition was true or not.
uint32_t mbedtls_mpi_uint
The type of machine digits in a bignum, called _limbs_.
Definition: bignum.h:180
#define MBEDTLS_MPI_CHK(f)
Definition: bignum.h:55
int mbedtls_mpi_lt_mpi_ct(const mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned *ret)
Check if an MPI is less than the other in constant time.
ncbi::TMaskedQueryRegions mask
#define MBEDTLS_STATIC_TESTABLE
Helper to define a function as static except when building invasive tests.
Definition: common.h:60
static unsigned mbedtls_ct_size_gt(size_t x, size_t y)
Constant-flow "greater than" comparison: return x > y.
#define MD_CHK(func_call)
static void mbedtls_ct_mem_move_to_left(void *start, size_t total, size_t offset)
Shift some data towards the left inside a buffer.
static int mbedtls_ct_cond_select_sign(unsigned char condition, int if1, int if0)
Select between two sign values without branches.
static size_t mbedtls_ct_size_mask_lt(size_t x, size_t y)
Constant-flow mask generation for "less than" comparison:
#define MPI_VALIDATE_RET(cond)
static unsigned char mbedtls_ct_uchar_mask_of_range(unsigned char low, unsigned char high, unsigned char c)
int mbedtls_ct_memcmp(const void *a, const void *b, size_t n)
Constant-time functions.
Constant-time module: interfaces for invasive testing only.
#define A(i)
Definition: ecp_curves.c:948
static void cleanup(void)
Definition: ct_dynamic.c:30
CS_CONTEXT * ctx
Definition: t0006.c:12
static DLIST_TYPE *DLIST_NAME() next(DLIST_LIST_TYPE *list, DLIST_TYPE *item)
Definition: dlist.tmpl.h:56
static SQLCHAR output[256]
Definition: print.c:5
static char tmp[3200]
Definition: utf8.c:42
int offset
Definition: replacements.h:160
char data[12]
Definition: iconv.c:80
void swap(NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair1, NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair2)
Definition: ncbimisc.hpp:1508
#define NULL
Definition: ncbistd.hpp:225
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
char * buf
static int input()
int i
yy_size_t n
int len
MBEDTLS_CHECK_RETURN_TYPICAL int mbedtls_md_finish(mbedtls_md_context_t *ctx, unsigned char *output)
This function finishes the digest operation, and writes the result to the output buffer.
mbedtls_md_type_t
Supported message digests.
Definition: md.h:62
@ MBEDTLS_MD_SHA384
The SHA-384 message digest.
Definition: md.h:70
MBEDTLS_CHECK_RETURN_TYPICAL int mbedtls_md_hmac_reset(mbedtls_md_context_t *ctx)
This function prepares to authenticate a new message with the same key as the previous HMAC operation...
MBEDTLS_CHECK_RETURN_TYPICAL int mbedtls_md_starts(mbedtls_md_context_t *ctx)
This function starts a message-digest computation.
mbedtls_md_type_t mbedtls_md_get_type(const mbedtls_md_info_t *md_info)
This function extracts the message-digest type from the message-digest information structure.
MBEDTLS_CHECK_RETURN_TYPICAL int mbedtls_md_clone(mbedtls_md_context_t *dst, const mbedtls_md_context_t *src)
This function clones the state of a message-digest context.
MBEDTLS_CHECK_RETURN_TYPICAL int mbedtls_md_setup(mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac)
This function selects the message digest algorithm to use, and allocates internal structures.
MBEDTLS_CHECK_RETURN_TYPICAL int mbedtls_md_update(mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen)
This function feeds an input buffer into an ongoing message-digest computation.
#define MBEDTLS_MD_MAX_SIZE
Definition: md.h:78
void mbedtls_md_init(mbedtls_md_context_t *ctx)
This function initializes a message-digest context without binding it to a particular message-digest ...
unsigned char mbedtls_md_get_size(const mbedtls_md_info_t *md_info)
This function extracts the message-digest size from the message-digest information structure.
void mbedtls_md_free(mbedtls_md_context_t *ctx)
This function clears the internal structure of ctx and frees any embedded internal structure,...
mdb_mode_t mode
Definition: lmdb++.h:38
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1227
unsigned int a
Definition: ncbi_localip.c:102
#define mbedtls_ct_hmac
#define mbedtls_ct_size_mask_ge
#define mbedtls_ct_rsaes_pkcs1_v15_unpadding
#define mbedtls_ct_base64_dec_value
#define mbedtls_ct_base64_enc_char
#define mbedtls_ct_size_bool_eq
#define mbedtls_ct_mpi_uint_lt
#define mbedtls_ct_mpi_uint_cond_assign
#define mbedtls_ct_uint_mask
#define mbedtls_ct_uint_if
#define mbedtls_ct_mpi_uint_mask
#define mbedtls_ct_memcpy_if_eq
#define mbedtls_ct_memcpy_offset
#define mbedtls_ct_size_mask
Common and shared functions used by multiple modules in the Mbed TLS library.
This file provides an API for the RSA public-key cryptosystem.
#define MBEDTLS_RSA_PRIVATE
Request public key operation.
Definition: rsa.h:79
#define MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE
The output buffer for decryption is not large enough.
Definition: rsa.h:62
#define MBEDTLS_RSA_SIGN
Identifier for RSA signature operations.
Definition: rsa.h:84
#define MBEDTLS_RSA_CRYPT
Identifier for RSA encryption and decryption operations.
Definition: rsa.h:85
#define MBEDTLS_ERR_RSA_INVALID_PADDING
Input data contains invalid padding and is rejected.
Definition: rsa.h:50
Error to string translation.
#define MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED
This is a bug in the library.
Definition: error.h:122
union __declspec(align(16)) SIMDVec
Definition: sse2neon.h:347
Internal functions shared by the SSL modules.
The generic message-digest context.
Definition: md.h:95
MPI structure.
Definition: bignum.h:208
size_t n
Total number of limbs in p.
Definition: bignum.h:223
int s
Sign: -1 if the mpi is negative, 1 otherwise.
Definition: bignum.h:220
mbedtls_mpi_uint * p
Pointer to limbs.
Definition: bignum.h:229
done
Definition: token1.c:1
Modified on Sun Apr 14 05:29:05 2024 by modify_doxy.py rev. 669887