Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/mbedtls/library/constant_time_internal.h
9903 views
1
/**
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 */
67
typedef size_t mbedtls_ct_condition_t;
68
typedef size_t mbedtls_ct_uint_t;
69
typedef 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 */
73
typedef uint64_t mbedtls_ct_condition_t;
74
typedef uint64_t mbedtls_ct_uint_t;
75
typedef 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 */
80
typedef uint32_t mbedtls_ct_condition_t;
81
typedef uint32_t mbedtls_ct_uint_t;
82
typedef 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
*/
99
static 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
*/
112
static 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
*/
125
static 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
*/
139
static 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
*/
152
static 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
*/
167
static 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
*/
182
static 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
*/
200
static 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
*/
215
static 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
*/
230
static 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
*/
243
static 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
*/
262
static 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
*/
278
static 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
*/
294
static 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
*/
312
static 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
*/
332
static 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
*/
348
static 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
*/
365
static 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
*/
383
static 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
*/
397
static 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
*/
414
static 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
*/
430
static 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
*/
450
void 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
*/
465
void 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
*/
495
void 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
*/
531
void 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
*/
568
int 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 */
580
581