blob: 09de92f173df052e91136bcc6451080ea371f55d [file] [log] [blame]
gabor-mezei-armdb9a38c2021-09-27 11:28:54 +02001/**
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
Gabor Mezei291df7b2021-10-19 11:27:17 +020020#ifndef MBEDTLS_CONSTANT_TIME_INTERNAL_H
21#define MBEDTLS_CONSTANT_TIME_INTERNAL_H
22
Dave Rodgman40a41d02023-05-17 11:59:56 +010023#include <stdint.h>
24#include <stddef.h>
25
gabor-mezei-armdb9a38c2021-09-27 11:28:54 +020026#include "common.h"
27
gabor-mezei-arm3f90fd52021-09-27 12:55:33 +020028#if defined(MBEDTLS_BIGNUM_C)
29#include "mbedtls/bignum.h"
30#endif
31
Dave Rodgman40a41d02023-05-17 11:59:56 +010032/* The constant-time interface provides various operations that are likely
33 * to result in constant-time code that does not branch or use conditional
34 * instructions for secret data (for secret pointers, this also applies to
35 * the data pointed to).
36 *
37 * It has three main parts:
38 *
39 * - boolean operations (and a few non-boolean operations)
40 * These are all named mbedtls_ct_bool_<operation>, and operate over
41 * mbedtls_ct_condition_t.
42 * All arguments to these operations are considered secret.
43 * example: bool x = y | z => x = mbedtls_ct_bool_or(y, z)
44 *
45 * - conditional data selection
46 * These are all named mbedtls_ct_<type>_if and mbedtls_ct_<type>_if0
47 * All arguments are considered secret.
48 * example: size_t a = x ? b : c => a = mbedtls_ct_size_if(x, b, c)
49 * example: unsigned a = x ? b : 0 => a = mbedtls_ct_uint_if0(x, b)
50 *
51 * - block memory operations
52 * Only some arguments are considered secret, as documented for each
53 * function.
54 * example: if (x) memcpy(...) => mbedtls_ct_memcpy_if(x, ...)
55 *
56 * mbedtls_ct_condition_t should be treated as opaque and only manipulated
57 * via the functions in this header.
58 *
59 * mbedtls_ct_uint_t is an unsigned integer type over which constant time
60 * operations may be performed via the functions in this header. It is as big
61 * as the larger of size_t and mbedtls_mpi_uint, i.e. it is safe to cast
62 * to/from "unsigned int", "size_t", and "mbedtls_mpi_uint" (and any other
63 * not-larger integer types).
64 *
65 * For Arm (32-bit, 64-bit and Thumb), assembly implementations are used
66 * to ensure that the generated code is constant time. For other architectures,
67 * a plain C fallback designed to yield constant-time code (this has been
68 * observed to be constant-time on latest gcc, clang and MSVC as of May 2023).
69 */
70
71#if (SIZE_MAX > 0xffffffffffffffffULL)
72/* Pointer size > 64-bit */
73typedef size_t mbedtls_ct_condition_t;
74typedef size_t mbedtls_ct_uint_t;
75typedef ptrdiff_t mbedtls_ct_int_t;
76#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) SIZE_MAX)
77#elif (SIZE_MAX > 0xffffffff) || defined(MBEDTLS_HAVE_INT64)
78/* 32-bit < pointer size < 64-bit, or 64-bit MPI */
79typedef uint64_t mbedtls_ct_condition_t;
80typedef uint64_t mbedtls_ct_uint_t;
81typedef int64_t mbedtls_ct_int_t;
82#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) UINT64_MAX)
83#else
84/* Pointer size < 32-bit, and no 64-bit MPIs */
85typedef uint32_t mbedtls_ct_condition_t;
86typedef uint32_t mbedtls_ct_uint_t;
87typedef int32_t mbedtls_ct_int_t;
88#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) UINT32_MAX)
89#endif
90#define MBEDTLS_CT_FALSE ((mbedtls_ct_condition_t) 0)
91
92/* constant_time_impl.h contains all the static inline implementations,
93 * so that constant_time_internal.h is more readable.
94 */
95#include "constant_time_impl.h"
96
97
98/* ============================================================================
99 * Boolean operations
100 */
101
102/** Convert a number into a mbedtls_ct_condition_t.
103 *
104 * \param x Number to convert.
105 *
106 * \return MBEDTLS_CT_TRUE if \p x != 0, or MBEDTLS_CT_FALSE if \p x == 0
107 *
108 */
109static inline mbedtls_ct_condition_t mbedtls_ct_bool(mbedtls_ct_uint_t x);
110
111/** Boolean "not equal" operation.
112 *
113 * Functionally equivalent to:
114 *
115 * \p x != \p y
116 *
117 * \param x The first value to analyze.
118 * \param y The second value to analyze.
119 *
120 * \return MBEDTLS_CT_TRUE if \p x != \p y, otherwise MBEDTLS_CT_FALSE.
121 */
122static inline mbedtls_ct_condition_t mbedtls_ct_bool_ne(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y);
123
124/** Boolean "equals" operation.
125 *
126 * Functionally equivalent to:
127 *
128 * \p x == \p y
129 *
130 * \param x The first value to analyze.
131 * \param y The second value to analyze.
132 *
133 * \return MBEDTLS_CT_TRUE if \p x == \p y, otherwise MBEDTLS_CT_FALSE.
134 */
135static inline mbedtls_ct_condition_t mbedtls_ct_bool_eq(mbedtls_ct_uint_t x,
136 mbedtls_ct_uint_t y);
137
138/** Boolean "less than" operation.
139 *
140 * Functionally equivalent to:
141 *
142 * \p x < \p y
143 *
144 * \param x The first value to analyze.
145 * \param y The second value to analyze.
146 *
147 * \return MBEDTLS_CT_TRUE if \p x < \p y, otherwise MBEDTLS_CT_FALSE.
148 */
149static inline mbedtls_ct_condition_t mbedtls_ct_bool_lt(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y);
150
151/** Boolean "greater than" operation.
152 *
153 * Functionally equivalent to:
154 *
155 * \p x > \p y
156 *
157 * \param x The first value to analyze.
158 * \param y The second value to analyze.
159 *
160 * \return MBEDTLS_CT_TRUE if \p x > \p y, otherwise MBEDTLS_CT_FALSE.
161 */
162static inline mbedtls_ct_condition_t mbedtls_ct_bool_gt(mbedtls_ct_uint_t x,
163 mbedtls_ct_uint_t y);
164
165/** Boolean "greater or equal" operation.
166 *
167 * Functionally equivalent to:
168 *
169 * \p x >= \p y
170 *
171 * \param x The first value to analyze.
172 * \param y The second value to analyze.
173 *
174 * \return MBEDTLS_CT_TRUE if \p x >= \p y,
175 * otherwise MBEDTLS_CT_FALSE.
176 */
177static inline mbedtls_ct_condition_t mbedtls_ct_bool_ge(mbedtls_ct_uint_t x,
178 mbedtls_ct_uint_t y);
179
180/** Boolean "less than or equal" operation.
181 *
182 * Functionally equivalent to:
183 *
184 * \p x <= \p y
185 *
186 * \param x The first value to analyze.
187 * \param y The second value to analyze.
188 *
189 * \return MBEDTLS_CT_TRUE if \p x <= \p y,
190 * otherwise MBEDTLS_CT_FALSE.
191 */
192static inline mbedtls_ct_condition_t mbedtls_ct_bool_le(mbedtls_ct_uint_t x,
193 mbedtls_ct_uint_t y);
194
195/** Boolean "xor" operation.
196 *
197 * Functionally equivalent to:
198 *
199 * \p x ^ \p y
200 *
201 * \param x The first value to analyze.
202 * \param y The second value to analyze.
203 *
204 * \note This is more efficient than mbedtls_ct_bool_ne if both arguments are
205 * mbedtls_ct_condition_t.
206 *
207 * \return MBEDTLS_CT_TRUE if \p x ^ \p y,
208 * otherwise MBEDTLS_CT_FALSE.
209 */
210static inline mbedtls_ct_condition_t mbedtls_ct_bool_xor(mbedtls_ct_condition_t x,
211 mbedtls_ct_condition_t y);
212
213/** Boolean "and" operation.
214 *
215 * Functionally equivalent to:
216 *
217 * \p x && \p y
218 *
219 * \param x The first value to analyze.
220 * \param y The second value to analyze.
221 *
222 * \return MBEDTLS_CT_TRUE if \p x && \p y,
223 * otherwise MBEDTLS_CT_FALSE.
224 */
225static inline mbedtls_ct_condition_t mbedtls_ct_bool_and(mbedtls_ct_condition_t x,
226 mbedtls_ct_condition_t y);
227
228/** Boolean "or" operation.
229 *
230 * Functionally equivalent to:
231 *
232 * \p x || \p y
233 *
234 * \param x The first value to analyze.
235 * \param y The second value to analyze.
236 *
237 * \return MBEDTLS_CT_TRUE if \p x || \p y,
238 * otherwise MBEDTLS_CT_FALSE.
239 */
240static inline mbedtls_ct_condition_t mbedtls_ct_bool_or(mbedtls_ct_condition_t x,
241 mbedtls_ct_condition_t y);
242
243/** Boolean "not" operation.
244 *
245 * Functionally equivalent to:
246 *
247 * ! \p x
248 *
249 * \param x The value to invert
250 *
251 * \return MBEDTLS_CT_FALSE if \p x, otherwise MBEDTLS_CT_TRUE.
252 */
253static inline mbedtls_ct_condition_t mbedtls_ct_bool_not(mbedtls_ct_condition_t x);
254
255
256/* ============================================================================
257 * Data selection operations
258 */
259
260/** Choose between two size_t values.
261 *
262 * Functionally equivalent to:
263 *
264 * condition ? if1 : if0.
265 *
266 * \param condition Condition to test.
267 * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
268 * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE.
269 *
270 * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
271 */
272static inline size_t mbedtls_ct_size_if(mbedtls_ct_condition_t condition,
273 size_t if1,
274 size_t if0);
275
276/** Choose between two unsigned values.
277 *
278 * Functionally equivalent to:
279 *
280 * condition ? if1 : if0.
281 *
282 * \param condition Condition to test.
283 * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
284 * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE.
285 *
286 * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
287 */
Dave Rodgman2b4486a2023-05-17 15:51:59 +0100288static inline unsigned mbedtls_ct_uint_if(mbedtls_ct_condition_t condition,
Dave Rodgman40a41d02023-05-17 11:59:56 +0100289 unsigned if1,
290 unsigned if0);
291
292#if defined(MBEDTLS_BIGNUM_C)
293
294/** Choose between two mbedtls_mpi_uint values.
295 *
296 * Functionally equivalent to:
297 *
298 * condition ? if1 : if0.
299 *
300 * \param condition Condition to test.
301 * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
302 * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE.
303 *
304 * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
305 */
306static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if(mbedtls_ct_condition_t condition, \
307 mbedtls_mpi_uint if1, \
308 mbedtls_mpi_uint if0);
309
310#endif
311
312/** Choose between an unsigned value and 0.
313 *
314 * Functionally equivalent to:
315 *
316 * condition ? if1 : 0.
317 *
318 * Functionally equivalent tombedtls_ct_uint_if(condition, if1, 0) but
319 * results in smaller code size.
320 *
321 * \param condition Condition to test.
322 * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
323 *
324 * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
325 */
326static inline unsigned mbedtls_ct_uint_if0(mbedtls_ct_condition_t condition, unsigned if1);
327
328#if defined(MBEDTLS_BIGNUM_C)
329
330/** Choose between an mbedtls_mpi_uint value and 0.
331 *
332 * Functionally equivalent to:
333 *
334 * condition ? if1 : 0.
335 *
336 * Functionally equivalent tombedtls_ct_mpi_uint_if(condition, if1, 0) but
337 * results in smaller code size.
338 *
339 * \param condition Condition to test.
340 * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
341 *
342 * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
343 */
344static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if0(mbedtls_ct_condition_t condition,
345 mbedtls_mpi_uint if1);
346
347#endif
348
349/** Constant-flow char selection
350 *
351 * \param low Secret. Bottom of range
352 * \param high Secret. Top of range
353 * \param c Secret. Value to compare to range
354 * \param t Secret. Value to return, if in range
355 *
356 * \return \p t if \p low <= \p c <= \p high, 0 otherwise.
357 */
358static inline unsigned char mbedtls_ct_uchar_in_range_if(unsigned char low,
359 unsigned char high,
360 unsigned char c,
361 unsigned char t);
362
363
364/* ============================================================================
365 * Block memory operations
366 */
367
368#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
369
370/** Conditionally set a block of memory to zero.
371 *
372 * Regardless of the condition, every byte will be read once and written to
373 * once.
374 *
375 * \param condition Secret. Condition to test.
376 * \param buf Secret. Pointer to the start of the buffer.
377 * \param len Number of bytes to set to zero.
378 *
379 * \warning Unlike mbedtls_platform_zeroize, this does not have the same guarantees
380 * about not being optimised away if the memory is never read again.
381 */
382void mbedtls_ct_zeroize_if(mbedtls_ct_condition_t condition, void *buf, size_t len);
383
384/** Shift some data towards the left inside a buffer.
385 *
386 * Functionally equivalent to:
387 *
388 * memmove(start, start + offset, total - offset);
389 * memset(start + (total - offset), 0, offset);
390 *
391 * Timing independence comes at the expense of performance.
392 *
393 * \param start Secret. Pointer to the start of the buffer.
394 * \param total Total size of the buffer.
395 * \param offset Secret. Offset from which to copy \p total - \p offset bytes.
396 */
397void mbedtls_ct_memmove_left(void *start,
398 size_t total,
399 size_t offset);
400
401#endif /* defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT) */
402
403/** Conditional memcpy.
404 *
405 * Functionally equivalent to:
406 *
407 * if (condition) {
408 * memcpy(dest, src1, len);
409 * } else {
410 * if (src2 != NULL)
411 * memcpy(dest, src2, len);
412 * }
413 *
414 * It will always read len bytes from src1.
415 * If src2 != NULL, it will always read len bytes from src2.
416 * If src2 == NULL, it will instead read len bytes from dest (as if src2 == dest).
417 *
418 * \param condition The condition
419 * \param dest Secret. Destination pointer.
420 * \param src1 Secret. Pointer to copy from (if \p condition == MBEDTLS_CT_TRUE). Shouldn't overlap with \p dest.
421 * \param src2 Secret (contents only - may branch to test if src2 == NULL).
422 * Pointer to copy from (if \p condition == MBEDTLS_CT_FALSE and \p src2 is not NULL). Shouldn't overlap with \p dest. May be NULL.
423 * \param len Number of bytes to copy.
424 */
425void mbedtls_ct_memcpy_if(mbedtls_ct_condition_t condition,
426 unsigned char *dest,
427 const unsigned char *src1,
428 const unsigned char *src2,
429 size_t len
430 );
431
432/** Copy data from a secret position.
433 *
434 * Functionally equivalent to:
435 *
436 * memcpy(dst, src + offset, len)
437 *
438 * This function copies \p len bytes from \p src_base + \p offset to \p
439 * dst, with a code flow and memory access pattern that does not depend on
440 * \p offset, but only on \p offset_min, \p offset_max and \p len.
441 *
442 * \note This function reads from \p dest, but the value that
443 * is read does not influence the result and this
444 * function's behavior is well-defined regardless of the
445 * contents of the buffers. This may result in false
446 * positives from static or dynamic analyzers, especially
447 * if \p dest is not initialized.
448 *
449 * \param dest Secret. The destination buffer. This must point to a writable
450 * buffer of at least \p len bytes.
451 * \param src Secret. The base of the source buffer. This must point to a
452 * readable buffer of at least \p offset_max + \p len
453 * bytes. Shouldn't overlap with \p dest.
454 * \param offset Secret. The offset in the source buffer from which to copy.
455 * This must be no less than \p offset_min and no greater
456 * than \p offset_max.
457 * \param offset_min The minimal value of \p offset.
458 * \param offset_max The maximal value of \p offset.
459 * \param len The number of bytes to copy.
460 */
461void mbedtls_ct_memcpy_offset(unsigned char *dest,
462 const unsigned char *src,
463 size_t offset,
464 size_t offset_min,
465 size_t offset_max,
466 size_t len);
467
468/* Documented in include/mbedtls/constant_time.h. a and b are secret. */
469int mbedtls_ct_memcmp(const void *a,
470 const void *b,
471 size_t n);
472
Gabor Mezei291df7b2021-10-19 11:27:17 +0200473#endif /* MBEDTLS_CONSTANT_TIME_INTERNAL_H */