blob: 61a5c6d4e9525b6e7d7954caf78dfa6759f476d7 [file] [log] [blame]
Tom Rini0344c602024-10-08 13:56:50 -06001/**
2 * Constant-time functions
3 *
4 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 */
7
8#ifndef MBEDTLS_CONSTANT_TIME_INTERNAL_H
9#define MBEDTLS_CONSTANT_TIME_INTERNAL_H
10
11#include <stdint.h>
12#include <stddef.h>
13
14#include "common.h"
15
16#if defined(MBEDTLS_BIGNUM_C)
17#include "mbedtls/bignum.h"
18#endif
19
20/* The constant-time interface provides various operations that are likely
21 * to result in constant-time code that does not branch or use conditional
22 * instructions for secret data (for secret pointers, this also applies to
23 * the data pointed to).
24 *
25 * It has three main parts:
26 *
27 * - boolean operations
28 * These are all named mbedtls_ct_<type>_<operation>.
29 * They operate over <type> and return mbedtls_ct_condition_t.
30 * All arguments are considered secret.
31 * example: bool x = y | z => x = mbedtls_ct_bool_or(y, z)
32 * example: bool x = y == z => x = mbedtls_ct_uint_eq(y, z)
33 *
34 * - conditional data selection
35 * These are all named mbedtls_ct_<type>_if and mbedtls_ct_<type>_if_else_0
36 * All arguments are considered secret.
37 * example: size_t a = x ? b : c => a = mbedtls_ct_size_if(x, b, c)
38 * example: unsigned a = x ? b : 0 => a = mbedtls_ct_uint_if_else_0(x, b)
39 *
40 * - block memory operations
41 * Only some arguments are considered secret, as documented for each
42 * function.
43 * example: if (x) memcpy(...) => mbedtls_ct_memcpy_if(x, ...)
44 *
45 * mbedtls_ct_condition_t must be treated as opaque and only created and
46 * manipulated via the functions in this header. The compiler should never
47 * be able to prove anything about its value at compile-time.
48 *
49 * mbedtls_ct_uint_t is an unsigned integer type over which constant time
50 * operations may be performed via the functions in this header. It is as big
51 * as the larger of size_t and mbedtls_mpi_uint, i.e. it is safe to cast
52 * to/from "unsigned int", "size_t", and "mbedtls_mpi_uint" (and any other
53 * not-larger integer types).
54 *
55 * For Arm (32-bit, 64-bit and Thumb), x86 and x86-64, assembly implementations
56 * are used to ensure that the generated code is constant time. For other
57 * architectures, it uses a plain C fallback designed to yield constant-time code
58 * (this has been observed to be constant-time on latest gcc, clang and MSVC
59 * as of May 2023).
60 *
61 * For readability, the static inline definitions are separated out into
62 * constant_time_impl.h.
63 */
64
65#if (SIZE_MAX > 0xffffffffffffffffULL)
66/* Pointer size > 64-bit */
67typedef size_t mbedtls_ct_condition_t;
68typedef size_t mbedtls_ct_uint_t;
69typedef ptrdiff_t mbedtls_ct_int_t;
70#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(SIZE_MAX))
71#elif (SIZE_MAX > 0xffffffff) || defined(MBEDTLS_HAVE_INT64)
72/* 32-bit < pointer size <= 64-bit, or 64-bit MPI */
73typedef uint64_t mbedtls_ct_condition_t;
74typedef uint64_t mbedtls_ct_uint_t;
75typedef int64_t mbedtls_ct_int_t;
76#define MBEDTLS_CT_SIZE_64
77#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(UINT64_MAX))
78#else
79/* Pointer size <= 32-bit, and no 64-bit MPIs */
80typedef uint32_t mbedtls_ct_condition_t;
81typedef uint32_t mbedtls_ct_uint_t;
82typedef int32_t mbedtls_ct_int_t;
83#define MBEDTLS_CT_SIZE_32
84#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(UINT32_MAX))
85#endif
86#define MBEDTLS_CT_FALSE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(0))
87
88/* ============================================================================
89 * Boolean operations
90 */
91
92/** Convert a number into a mbedtls_ct_condition_t.
93 *
94 * \param x Number to convert.
95 *
96 * \return MBEDTLS_CT_TRUE if \p x != 0, or MBEDTLS_CT_FALSE if \p x == 0
97 *
98 */
99static inline mbedtls_ct_condition_t mbedtls_ct_bool(mbedtls_ct_uint_t x);
100
101/** Boolean "not equal" operation.
102 *
103 * Functionally equivalent to:
104 *
105 * \p x != \p y
106 *
107 * \param x The first value to analyze.
108 * \param y The second value to analyze.
109 *
110 * \return MBEDTLS_CT_TRUE if \p x != \p y, otherwise MBEDTLS_CT_FALSE.
111 */
112static inline mbedtls_ct_condition_t mbedtls_ct_uint_ne(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y);
113
114/** Boolean "equals" operation.
115 *
116 * Functionally equivalent to:
117 *
118 * \p x == \p y
119 *
120 * \param x The first value to analyze.
121 * \param y The second value to analyze.
122 *
123 * \return MBEDTLS_CT_TRUE if \p x == \p y, otherwise MBEDTLS_CT_FALSE.
124 */
125static inline mbedtls_ct_condition_t mbedtls_ct_uint_eq(mbedtls_ct_uint_t x,
126 mbedtls_ct_uint_t y);
127
128/** Boolean "less than" operation.
129 *
130 * Functionally equivalent to:
131 *
132 * \p x < \p y
133 *
134 * \param x The first value to analyze.
135 * \param y The second value to analyze.
136 *
137 * \return MBEDTLS_CT_TRUE if \p x < \p y, otherwise MBEDTLS_CT_FALSE.
138 */
139static inline mbedtls_ct_condition_t mbedtls_ct_uint_lt(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y);
140
141/** Boolean "greater than" operation.
142 *
143 * Functionally equivalent to:
144 *
145 * \p x > \p y
146 *
147 * \param x The first value to analyze.
148 * \param y The second value to analyze.
149 *
150 * \return MBEDTLS_CT_TRUE if \p x > \p y, otherwise MBEDTLS_CT_FALSE.
151 */
152static inline mbedtls_ct_condition_t mbedtls_ct_uint_gt(mbedtls_ct_uint_t x,
153 mbedtls_ct_uint_t y);
154
155/** Boolean "greater or equal" operation.
156 *
157 * Functionally equivalent to:
158 *
159 * \p x >= \p y
160 *
161 * \param x The first value to analyze.
162 * \param y The second value to analyze.
163 *
164 * \return MBEDTLS_CT_TRUE if \p x >= \p y,
165 * otherwise MBEDTLS_CT_FALSE.
166 */
167static inline mbedtls_ct_condition_t mbedtls_ct_uint_ge(mbedtls_ct_uint_t x,
168 mbedtls_ct_uint_t y);
169
170/** Boolean "less than or equal" operation.
171 *
172 * Functionally equivalent to:
173 *
174 * \p x <= \p y
175 *
176 * \param x The first value to analyze.
177 * \param y The second value to analyze.
178 *
179 * \return MBEDTLS_CT_TRUE if \p x <= \p y,
180 * otherwise MBEDTLS_CT_FALSE.
181 */
182static inline mbedtls_ct_condition_t mbedtls_ct_uint_le(mbedtls_ct_uint_t x,
183 mbedtls_ct_uint_t y);
184
185/** Boolean not-equals operation.
186 *
187 * Functionally equivalent to:
188 *
189 * \p x != \p y
190 *
191 * \param x The first value to analyze.
192 * \param y The second value to analyze.
193 *
194 * \note This is more efficient than mbedtls_ct_uint_ne if both arguments are
195 * mbedtls_ct_condition_t.
196 *
197 * \return MBEDTLS_CT_TRUE if \p x != \p y,
198 * otherwise MBEDTLS_CT_FALSE.
199 */
200static inline mbedtls_ct_condition_t mbedtls_ct_bool_ne(mbedtls_ct_condition_t x,
201 mbedtls_ct_condition_t y);
202
203/** Boolean "and" operation.
204 *
205 * Functionally equivalent to:
206 *
207 * \p x && \p y
208 *
209 * \param x The first value to analyze.
210 * \param y The second value to analyze.
211 *
212 * \return MBEDTLS_CT_TRUE if \p x && \p y,
213 * otherwise MBEDTLS_CT_FALSE.
214 */
215static inline mbedtls_ct_condition_t mbedtls_ct_bool_and(mbedtls_ct_condition_t x,
216 mbedtls_ct_condition_t y);
217
218/** Boolean "or" operation.
219 *
220 * Functionally equivalent to:
221 *
222 * \p x || \p y
223 *
224 * \param x The first value to analyze.
225 * \param y The second value to analyze.
226 *
227 * \return MBEDTLS_CT_TRUE if \p x || \p y,
228 * otherwise MBEDTLS_CT_FALSE.
229 */
230static inline mbedtls_ct_condition_t mbedtls_ct_bool_or(mbedtls_ct_condition_t x,
231 mbedtls_ct_condition_t y);
232
233/** Boolean "not" operation.
234 *
235 * Functionally equivalent to:
236 *
237 * ! \p x
238 *
239 * \param x The value to invert
240 *
241 * \return MBEDTLS_CT_FALSE if \p x, otherwise MBEDTLS_CT_TRUE.
242 */
243static inline mbedtls_ct_condition_t mbedtls_ct_bool_not(mbedtls_ct_condition_t x);
244
245
246/* ============================================================================
247 * Data selection operations
248 */
249
250/** Choose between two size_t values.
251 *
252 * Functionally equivalent to:
253 *
254 * condition ? if1 : if0.
255 *
256 * \param condition Condition to test.
257 * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
258 * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE.
259 *
260 * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
261 */
262static inline size_t mbedtls_ct_size_if(mbedtls_ct_condition_t condition,
263 size_t if1,
264 size_t if0);
265
266/** Choose between two unsigned values.
267 *
268 * Functionally equivalent to:
269 *
270 * condition ? if1 : if0.
271 *
272 * \param condition Condition to test.
273 * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
274 * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE.
275 *
276 * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
277 */
278static inline unsigned mbedtls_ct_uint_if(mbedtls_ct_condition_t condition,
279 unsigned if1,
280 unsigned if0);
281
282/** Choose between two mbedtls_ct_condition_t values.
283 *
284 * Functionally equivalent to:
285 *
286 * condition ? if1 : if0.
287 *
288 * \param condition Condition to test.
289 * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
290 * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE.
291 *
292 * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
293 */
294static inline mbedtls_ct_condition_t mbedtls_ct_bool_if(mbedtls_ct_condition_t condition,
295 mbedtls_ct_condition_t if1,
296 mbedtls_ct_condition_t if0);
297
298#if defined(MBEDTLS_BIGNUM_C)
299
300/** Choose between two mbedtls_mpi_uint values.
301 *
302 * Functionally equivalent to:
303 *
304 * condition ? if1 : if0.
305 *
306 * \param condition Condition to test.
307 * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
308 * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE.
309 *
310 * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
311 */
312static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if(mbedtls_ct_condition_t condition, \
313 mbedtls_mpi_uint if1, \
314 mbedtls_mpi_uint if0);
315
316#endif
317
318/** Choose between an unsigned value and 0.
319 *
320 * Functionally equivalent to:
321 *
322 * condition ? if1 : 0.
323 *
324 * Functionally equivalent to mbedtls_ct_uint_if(condition, if1, 0) but
325 * results in smaller code size.
326 *
327 * \param condition Condition to test.
328 * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
329 *
330 * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
331 */
332static inline unsigned mbedtls_ct_uint_if_else_0(mbedtls_ct_condition_t condition, unsigned if1);
333
334/** Choose between an mbedtls_ct_condition_t and 0.
335 *
336 * Functionally equivalent to:
337 *
338 * condition ? if1 : 0.
339 *
340 * Functionally equivalent to mbedtls_ct_bool_if(condition, if1, 0) but
341 * results in smaller code size.
342 *
343 * \param condition Condition to test.
344 * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
345 *
346 * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
347 */
348static inline mbedtls_ct_condition_t mbedtls_ct_bool_if_else_0(mbedtls_ct_condition_t condition,
349 mbedtls_ct_condition_t if1);
350
351/** Choose between a size_t value and 0.
352 *
353 * Functionally equivalent to:
354 *
355 * condition ? if1 : 0.
356 *
357 * Functionally equivalent to mbedtls_ct_size_if(condition, if1, 0) but
358 * results in smaller code size.
359 *
360 * \param condition Condition to test.
361 * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
362 *
363 * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
364 */
365static inline size_t mbedtls_ct_size_if_else_0(mbedtls_ct_condition_t condition, size_t if1);
366
367#if defined(MBEDTLS_BIGNUM_C)
368
369/** Choose between an mbedtls_mpi_uint value and 0.
370 *
371 * Functionally equivalent to:
372 *
373 * condition ? if1 : 0.
374 *
375 * Functionally equivalent to mbedtls_ct_mpi_uint_if(condition, if1, 0) but
376 * results in smaller code size.
377 *
378 * \param condition Condition to test.
379 * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
380 *
381 * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
382 */
383static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if_else_0(mbedtls_ct_condition_t condition,
384 mbedtls_mpi_uint if1);
385
386#endif
387
388/** Constant-flow char selection
389 *
390 * \param low Secret. Bottom of range
391 * \param high Secret. Top of range
392 * \param c Secret. Value to compare to range
393 * \param t Secret. Value to return, if in range
394 *
395 * \return \p t if \p low <= \p c <= \p high, 0 otherwise.
396 */
397static inline unsigned char mbedtls_ct_uchar_in_range_if(unsigned char low,
398 unsigned char high,
399 unsigned char c,
400 unsigned char t);
401
402/** Choose between two error values. The values must be in the range [-32767..0].
403 *
404 * Functionally equivalent to:
405 *
406 * condition ? if1 : if0.
407 *
408 * \param condition Condition to test.
409 * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
410 * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE.
411 *
412 * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
413 */
414static inline int mbedtls_ct_error_if(mbedtls_ct_condition_t condition, int if1, int if0);
415
416/** Choose between an error value and 0. The error value must be in the range [-32767..0].
417 *
418 * Functionally equivalent to:
419 *
420 * condition ? if1 : 0.
421 *
422 * Functionally equivalent to mbedtls_ct_error_if(condition, if1, 0) but
423 * results in smaller code size.
424 *
425 * \param condition Condition to test.
426 * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
427 *
428 * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
429 */
430static inline int mbedtls_ct_error_if_else_0(mbedtls_ct_condition_t condition, int if1);
431
432/* ============================================================================
433 * Block memory operations
434 */
435
436#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
437
438/** Conditionally set a block of memory to zero.
439 *
440 * Regardless of the condition, every byte will be read once and written to
441 * once.
442 *
443 * \param condition Secret. Condition to test.
444 * \param buf Secret. Pointer to the start of the buffer.
445 * \param len Number of bytes to set to zero.
446 *
447 * \warning Unlike mbedtls_platform_zeroize, this does not have the same guarantees
448 * about not being optimised away if the memory is never read again.
449 */
450void mbedtls_ct_zeroize_if(mbedtls_ct_condition_t condition, void *buf, size_t len);
451
452/** Shift some data towards the left inside a buffer.
453 *
454 * Functionally equivalent to:
455 *
456 * memmove(start, start + offset, total - offset);
457 * memset(start + (total - offset), 0, offset);
458 *
459 * Timing independence comes at the expense of performance.
460 *
461 * \param start Secret. Pointer to the start of the buffer.
462 * \param total Total size of the buffer.
463 * \param offset Secret. Offset from which to copy \p total - \p offset bytes.
464 */
465void mbedtls_ct_memmove_left(void *start,
466 size_t total,
467 size_t offset);
468
469#endif /* defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT) */
470
471/** Conditional memcpy.
472 *
473 * Functionally equivalent to:
474 *
475 * if (condition) {
476 * memcpy(dest, src1, len);
477 * } else {
478 * if (src2 != NULL)
479 * memcpy(dest, src2, len);
480 * }
481 *
482 * It will always read len bytes from src1.
483 * If src2 != NULL, it will always read len bytes from src2.
484 * If src2 == NULL, it will instead read len bytes from dest (as if src2 == dest).
485 *
486 * \param condition The condition
487 * \param dest Secret. Destination pointer.
488 * \param src1 Secret. Pointer to copy from (if \p condition == MBEDTLS_CT_TRUE).
489 * This may be equal to \p dest, but may not overlap in other ways.
490 * \param src2 Secret (contents only - may branch to determine if this parameter is NULL).
491 * Pointer to copy from (if \p condition == MBEDTLS_CT_FALSE and \p src2 is not NULL). May be NULL.
492 * This may be equal to \p dest, but may not overlap it in other ways. It may overlap with \p src1.
493 * \param len Number of bytes to copy.
494 */
495void mbedtls_ct_memcpy_if(mbedtls_ct_condition_t condition,
496 unsigned char *dest,
497 const unsigned char *src1,
498 const unsigned char *src2,
499 size_t len
500 );
501
502/** Copy data from a secret position.
503 *
504 * Functionally equivalent to:
505 *
506 * memcpy(dst, src + offset, len)
507 *
508 * This function copies \p len bytes from \p src + \p offset to
509 * \p dst, with a code flow and memory access pattern that does not depend on
510 * \p offset, but only on \p offset_min, \p offset_max and \p len.
511 *
512 * \note This function reads from \p dest, but the value that
513 * is read does not influence the result and this
514 * function's behavior is well-defined regardless of the
515 * contents of the buffers. This may result in false
516 * positives from static or dynamic analyzers, especially
517 * if \p dest is not initialized.
518 *
519 * \param dest Secret. The destination buffer. This must point to a writable
520 * buffer of at least \p len bytes.
521 * \param src Secret. The base of the source buffer. This must point to a
522 * readable buffer of at least \p offset_max + \p len
523 * bytes. Shouldn't overlap with \p dest
524 * \param offset Secret. The offset in the source buffer from which to copy.
525 * This must be no less than \p offset_min and no greater
526 * than \p offset_max.
527 * \param offset_min The minimal value of \p offset.
528 * \param offset_max The maximal value of \p offset.
529 * \param len The number of bytes to copy.
530 */
531void mbedtls_ct_memcpy_offset(unsigned char *dest,
532 const unsigned char *src,
533 size_t offset,
534 size_t offset_min,
535 size_t offset_max,
536 size_t len);
537
538/* Documented in include/mbedtls/constant_time.h. a and b are secret.
539
540 int mbedtls_ct_memcmp(const void *a,
541 const void *b,
542 size_t n);
543 */
544
545#if defined(MBEDTLS_NIST_KW_C)
546
547/** Constant-time buffer comparison without branches.
548 *
549 * Similar to mbedtls_ct_memcmp, except that the result only depends on part of
550 * the input data - differences in the head or tail are ignored. Functionally equivalent to:
551 *
552 * memcmp(a + skip_head, b + skip_head, size - skip_head - skip_tail)
553 *
554 * Time taken depends on \p n, but not on \p skip_head or \p skip_tail .
555 *
556 * Behaviour is undefined if ( \p skip_head + \p skip_tail) > \p n.
557 *
558 * \param a Secret. Pointer to the first buffer, containing at least \p n bytes. May not be NULL.
559 * \param b Secret. Pointer to the second buffer, containing at least \p n bytes. May not be NULL.
560 * \param n The number of bytes to examine (total size of the buffers).
561 * \param skip_head Secret. The number of bytes to treat as non-significant at the start of the buffer.
562 * These bytes will still be read.
563 * \param skip_tail Secret. The number of bytes to treat as non-significant at the end of the buffer.
564 * These bytes will still be read.
565 *
566 * \return Zero if the contents of the two buffers are the same, otherwise non-zero.
567 */
568int mbedtls_ct_memcmp_partial(const void *a,
569 const void *b,
570 size_t n,
571 size_t skip_head,
572 size_t skip_tail);
573
574#endif
575
576/* Include the implementation of static inline functions above. */
577#include "constant_time_impl.h"
578
579#endif /* MBEDTLS_CONSTANT_TIME_INTERNAL_H */