blob: 79927c1f15de3e8ca39db38594481b7bd4778b67 [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 *
Dave Rodgmanf27727b2023-05-13 12:12:02 +010039 * - boolean operations
Dave Rodgman40a41d02023-05-17 11:59:56 +010040 * These are all named mbedtls_ct_bool_<operation>, and operate over
41 * mbedtls_ct_condition_t.
Dave Rodgmanf27727b2023-05-13 12:12:02 +010042 * All arguments are considered secret.
Dave Rodgman40a41d02023-05-17 11:59:56 +010043 * 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 *
Dave Rodgmanf27727b2023-05-13 12:12:02 +010065 * For Arm (32-bit, 64-bit and Thumb), x86 and x86-64, assembly implementations
66 * are used to ensure that the generated code is constant time. For other
67 * architectures, a plain C fallback designed to yield constant-time code (this
68 * has been observed to be constant-time on latest gcc, clang and MSVC as of
69 * May 2023).
Dave Rodgman40a41d02023-05-17 11:59:56 +010070 */
71
72#if (SIZE_MAX > 0xffffffffffffffffULL)
73/* Pointer size > 64-bit */
74typedef size_t mbedtls_ct_condition_t;
75typedef size_t mbedtls_ct_uint_t;
76typedef ptrdiff_t mbedtls_ct_int_t;
Dave Rodgmanfba55982023-07-14 13:44:22 +010077#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(SIZE_MAX))
Dave Rodgman40a41d02023-05-17 11:59:56 +010078#elif (SIZE_MAX > 0xffffffff) || defined(MBEDTLS_HAVE_INT64)
Dave Rodgmanc882adf2023-06-21 07:37:56 +010079/* 32-bit < pointer size <= 64-bit, or 64-bit MPI */
Dave Rodgman40a41d02023-05-17 11:59:56 +010080typedef uint64_t mbedtls_ct_condition_t;
81typedef uint64_t mbedtls_ct_uint_t;
82typedef int64_t mbedtls_ct_int_t;
Dave Rodgmanfba55982023-07-14 13:44:22 +010083#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(UINT64_MAX))
Dave Rodgman40a41d02023-05-17 11:59:56 +010084#else
Dave Rodgmanc882adf2023-06-21 07:37:56 +010085/* Pointer size <= 32-bit, and no 64-bit MPIs */
Dave Rodgman40a41d02023-05-17 11:59:56 +010086typedef uint32_t mbedtls_ct_condition_t;
87typedef uint32_t mbedtls_ct_uint_t;
88typedef int32_t mbedtls_ct_int_t;
Dave Rodgmanfba55982023-07-14 13:44:22 +010089#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(UINT32_MAX))
Dave Rodgman40a41d02023-05-17 11:59:56 +010090#endif
Dave Rodgmanfba55982023-07-14 13:44:22 +010091#define MBEDTLS_CT_FALSE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(0))
Dave Rodgman40a41d02023-05-17 11:59:56 +010092
93/* constant_time_impl.h contains all the static inline implementations,
94 * so that constant_time_internal.h is more readable.
Dave Rodgmana02b3682023-07-14 13:43:39 +010095 *
96 * gcc generates warnings about duplicate declarations, so disable this
97 * warning.
Dave Rodgman40a41d02023-05-17 11:59:56 +010098 */
Dave Rodgmana02b3682023-07-14 13:43:39 +010099#ifdef __GNUC__
100 #pragma GCC diagnostic push
101 #pragma GCC diagnostic ignored "-Wredundant-decls"
102#endif
Dave Rodgman40a41d02023-05-17 11:59:56 +0100103
Dave Rodgmana02b3682023-07-14 13:43:39 +0100104#include "constant_time_impl.h"
Dave Rodgman40a41d02023-05-17 11:59:56 +0100105
106/* ============================================================================
107 * Boolean operations
108 */
109
110/** Convert a number into a mbedtls_ct_condition_t.
111 *
112 * \param x Number to convert.
113 *
114 * \return MBEDTLS_CT_TRUE if \p x != 0, or MBEDTLS_CT_FALSE if \p x == 0
115 *
116 */
117static inline mbedtls_ct_condition_t mbedtls_ct_bool(mbedtls_ct_uint_t x);
118
119/** Boolean "not equal" operation.
120 *
121 * Functionally equivalent to:
122 *
123 * \p x != \p y
124 *
125 * \param x The first value to analyze.
126 * \param y The second value to analyze.
127 *
128 * \return MBEDTLS_CT_TRUE if \p x != \p y, otherwise MBEDTLS_CT_FALSE.
129 */
130static inline mbedtls_ct_condition_t mbedtls_ct_bool_ne(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y);
131
132/** Boolean "equals" operation.
133 *
134 * Functionally equivalent to:
135 *
136 * \p x == \p y
137 *
138 * \param x The first value to analyze.
139 * \param y The second value to analyze.
140 *
141 * \return MBEDTLS_CT_TRUE if \p x == \p y, otherwise MBEDTLS_CT_FALSE.
142 */
143static inline mbedtls_ct_condition_t mbedtls_ct_bool_eq(mbedtls_ct_uint_t x,
144 mbedtls_ct_uint_t y);
145
146/** Boolean "less than" operation.
147 *
148 * Functionally equivalent to:
149 *
150 * \p x < \p y
151 *
152 * \param x The first value to analyze.
153 * \param y The second value to analyze.
154 *
155 * \return MBEDTLS_CT_TRUE if \p x < \p y, otherwise MBEDTLS_CT_FALSE.
156 */
157static inline mbedtls_ct_condition_t mbedtls_ct_bool_lt(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y);
158
159/** Boolean "greater than" operation.
160 *
161 * Functionally equivalent to:
162 *
163 * \p x > \p y
164 *
165 * \param x The first value to analyze.
166 * \param y The second value to analyze.
167 *
168 * \return MBEDTLS_CT_TRUE if \p x > \p y, otherwise MBEDTLS_CT_FALSE.
169 */
170static inline mbedtls_ct_condition_t mbedtls_ct_bool_gt(mbedtls_ct_uint_t x,
171 mbedtls_ct_uint_t y);
172
173/** Boolean "greater or equal" operation.
174 *
175 * Functionally equivalent to:
176 *
177 * \p x >= \p y
178 *
179 * \param x The first value to analyze.
180 * \param y The second value to analyze.
181 *
182 * \return MBEDTLS_CT_TRUE if \p x >= \p y,
183 * otherwise MBEDTLS_CT_FALSE.
184 */
185static inline mbedtls_ct_condition_t mbedtls_ct_bool_ge(mbedtls_ct_uint_t x,
186 mbedtls_ct_uint_t y);
187
188/** Boolean "less than or equal" operation.
189 *
190 * Functionally equivalent to:
191 *
192 * \p x <= \p y
193 *
194 * \param x The first value to analyze.
195 * \param y The second value to analyze.
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_le(mbedtls_ct_uint_t x,
201 mbedtls_ct_uint_t y);
202
203/** Boolean "xor" 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 * \note This is more efficient than mbedtls_ct_bool_ne if both arguments are
213 * mbedtls_ct_condition_t.
214 *
215 * \return MBEDTLS_CT_TRUE if \p x ^ \p y,
216 * otherwise MBEDTLS_CT_FALSE.
217 */
218static inline mbedtls_ct_condition_t mbedtls_ct_bool_xor(mbedtls_ct_condition_t x,
219 mbedtls_ct_condition_t y);
220
221/** Boolean "and" operation.
222 *
223 * Functionally equivalent to:
224 *
225 * \p x && \p y
226 *
227 * \param x The first value to analyze.
228 * \param y The second value to analyze.
229 *
230 * \return MBEDTLS_CT_TRUE if \p x && \p y,
231 * otherwise MBEDTLS_CT_FALSE.
232 */
233static inline mbedtls_ct_condition_t mbedtls_ct_bool_and(mbedtls_ct_condition_t x,
234 mbedtls_ct_condition_t y);
235
236/** Boolean "or" operation.
237 *
238 * Functionally equivalent to:
239 *
240 * \p x || \p y
241 *
242 * \param x The first value to analyze.
243 * \param y The second value to analyze.
244 *
245 * \return MBEDTLS_CT_TRUE if \p x || \p y,
246 * otherwise MBEDTLS_CT_FALSE.
247 */
248static inline mbedtls_ct_condition_t mbedtls_ct_bool_or(mbedtls_ct_condition_t x,
249 mbedtls_ct_condition_t y);
250
251/** Boolean "not" operation.
252 *
253 * Functionally equivalent to:
254 *
255 * ! \p x
256 *
257 * \param x The value to invert
258 *
259 * \return MBEDTLS_CT_FALSE if \p x, otherwise MBEDTLS_CT_TRUE.
260 */
261static inline mbedtls_ct_condition_t mbedtls_ct_bool_not(mbedtls_ct_condition_t x);
262
263
264/* ============================================================================
265 * Data selection operations
266 */
267
268/** Choose between two size_t values.
269 *
270 * Functionally equivalent to:
271 *
272 * condition ? if1 : if0.
273 *
274 * \param condition Condition to test.
275 * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
276 * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE.
277 *
278 * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
279 */
280static inline size_t mbedtls_ct_size_if(mbedtls_ct_condition_t condition,
281 size_t if1,
282 size_t if0);
283
284/** Choose between two unsigned values.
285 *
286 * Functionally equivalent to:
287 *
288 * condition ? if1 : if0.
289 *
290 * \param condition Condition to test.
291 * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
292 * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE.
293 *
294 * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
295 */
Dave Rodgman2b4486a2023-05-17 15:51:59 +0100296static inline unsigned mbedtls_ct_uint_if(mbedtls_ct_condition_t condition,
Dave Rodgman40a41d02023-05-17 11:59:56 +0100297 unsigned if1,
298 unsigned if0);
299
300#if defined(MBEDTLS_BIGNUM_C)
301
302/** Choose between two mbedtls_mpi_uint values.
303 *
304 * Functionally equivalent to:
305 *
306 * condition ? if1 : if0.
307 *
308 * \param condition Condition to test.
309 * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
310 * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE.
311 *
312 * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
313 */
314static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if(mbedtls_ct_condition_t condition, \
315 mbedtls_mpi_uint if1, \
316 mbedtls_mpi_uint if0);
317
318#endif
319
320/** Choose between an unsigned value and 0.
321 *
322 * Functionally equivalent to:
323 *
324 * condition ? if1 : 0.
325 *
326 * Functionally equivalent tombedtls_ct_uint_if(condition, if1, 0) but
327 * results in smaller code size.
328 *
329 * \param condition Condition to test.
330 * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
331 *
332 * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
333 */
334static inline unsigned mbedtls_ct_uint_if0(mbedtls_ct_condition_t condition, unsigned if1);
335
336#if defined(MBEDTLS_BIGNUM_C)
337
338/** Choose between an mbedtls_mpi_uint value and 0.
339 *
340 * Functionally equivalent to:
341 *
342 * condition ? if1 : 0.
343 *
344 * Functionally equivalent tombedtls_ct_mpi_uint_if(condition, if1, 0) but
345 * results in smaller code size.
346 *
347 * \param condition Condition to test.
348 * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
349 *
350 * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
351 */
352static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if0(mbedtls_ct_condition_t condition,
353 mbedtls_mpi_uint if1);
354
355#endif
356
357/** Constant-flow char selection
358 *
359 * \param low Secret. Bottom of range
360 * \param high Secret. Top of range
361 * \param c Secret. Value to compare to range
362 * \param t Secret. Value to return, if in range
363 *
364 * \return \p t if \p low <= \p c <= \p high, 0 otherwise.
365 */
366static inline unsigned char mbedtls_ct_uchar_in_range_if(unsigned char low,
367 unsigned char high,
368 unsigned char c,
369 unsigned char t);
370
371
372/* ============================================================================
373 * Block memory operations
374 */
375
376#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
377
378/** Conditionally set a block of memory to zero.
379 *
380 * Regardless of the condition, every byte will be read once and written to
381 * once.
382 *
383 * \param condition Secret. Condition to test.
384 * \param buf Secret. Pointer to the start of the buffer.
385 * \param len Number of bytes to set to zero.
386 *
387 * \warning Unlike mbedtls_platform_zeroize, this does not have the same guarantees
388 * about not being optimised away if the memory is never read again.
389 */
390void mbedtls_ct_zeroize_if(mbedtls_ct_condition_t condition, void *buf, size_t len);
391
392/** Shift some data towards the left inside a buffer.
393 *
394 * Functionally equivalent to:
395 *
396 * memmove(start, start + offset, total - offset);
397 * memset(start + (total - offset), 0, offset);
398 *
399 * Timing independence comes at the expense of performance.
400 *
401 * \param start Secret. Pointer to the start of the buffer.
402 * \param total Total size of the buffer.
403 * \param offset Secret. Offset from which to copy \p total - \p offset bytes.
404 */
405void mbedtls_ct_memmove_left(void *start,
406 size_t total,
407 size_t offset);
408
409#endif /* defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT) */
410
411/** Conditional memcpy.
412 *
413 * Functionally equivalent to:
414 *
415 * if (condition) {
416 * memcpy(dest, src1, len);
417 * } else {
418 * if (src2 != NULL)
419 * memcpy(dest, src2, len);
420 * }
421 *
422 * It will always read len bytes from src1.
423 * If src2 != NULL, it will always read len bytes from src2.
424 * If src2 == NULL, it will instead read len bytes from dest (as if src2 == dest).
425 *
426 * \param condition The condition
427 * \param dest Secret. Destination pointer.
Dave Rodgman31086452023-05-18 13:47:13 +0100428 * \param src1 Secret. Pointer to copy from (if \p condition == MBEDTLS_CT_TRUE).
429 * This may be equal to \p dest, but may not overlap in other ways.
Dave Rodgman40a41d02023-05-17 11:59:56 +0100430 * \param src2 Secret (contents only - may branch to test if src2 == NULL).
Dave Rodgman31086452023-05-18 13:47:13 +0100431 * Pointer to copy from (if \p condition == MBEDTLS_CT_FALSE and \p src2 is not NULL). May be NULL.
432 * This may be equal to \p dest, but may not overlap it in other ways. It may overlap with \p src1.
Dave Rodgman40a41d02023-05-17 11:59:56 +0100433 * \param len Number of bytes to copy.
434 */
435void mbedtls_ct_memcpy_if(mbedtls_ct_condition_t condition,
436 unsigned char *dest,
437 const unsigned char *src1,
438 const unsigned char *src2,
439 size_t len
440 );
441
442/** Copy data from a secret position.
443 *
444 * Functionally equivalent to:
445 *
446 * memcpy(dst, src + offset, len)
447 *
448 * This function copies \p len bytes from \p src_base + \p offset to \p
449 * dst, with a code flow and memory access pattern that does not depend on
450 * \p offset, but only on \p offset_min, \p offset_max and \p len.
451 *
452 * \note This function reads from \p dest, but the value that
453 * is read does not influence the result and this
454 * function's behavior is well-defined regardless of the
455 * contents of the buffers. This may result in false
456 * positives from static or dynamic analyzers, especially
457 * if \p dest is not initialized.
458 *
459 * \param dest Secret. The destination buffer. This must point to a writable
460 * buffer of at least \p len bytes.
461 * \param src Secret. The base of the source buffer. This must point to a
462 * readable buffer of at least \p offset_max + \p len
Dave Rodgman31086452023-05-18 13:47:13 +0100463 * bytes. Shouldn't overlap with \p dest
Dave Rodgman40a41d02023-05-17 11:59:56 +0100464 * \param offset Secret. The offset in the source buffer from which to copy.
465 * This must be no less than \p offset_min and no greater
466 * than \p offset_max.
467 * \param offset_min The minimal value of \p offset.
468 * \param offset_max The maximal value of \p offset.
469 * \param len The number of bytes to copy.
470 */
471void mbedtls_ct_memcpy_offset(unsigned char *dest,
472 const unsigned char *src,
473 size_t offset,
474 size_t offset_min,
475 size_t offset_max,
476 size_t len);
477
478/* Documented in include/mbedtls/constant_time.h. a and b are secret. */
479int mbedtls_ct_memcmp(const void *a,
480 const void *b,
481 size_t n);
482
Dave Rodgmana02b3682023-07-14 13:43:39 +0100483#ifdef __GNUC__
484 #pragma GCC diagnostic pop
485#endif
486
Gabor Mezei291df7b2021-10-19 11:27:17 +0200487#endif /* MBEDTLS_CONSTANT_TIME_INTERNAL_H */