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