blob: cc26edcd1e4b84d5956e08a98a91aa139db467e1 [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 Rodgman38b227c2023-08-10 12:18:27 +010040 * These are all named mbedtls_ct_<type>_<operation>.
41 * They operate over <type> and return 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)
Dave Rodgmanb7825ce2023-08-10 11:58:18 +010044 * example: bool x = y == z => x = mbedtls_ct_uint_eq(y, z)
Dave Rodgman40a41d02023-05-17 11:59:56 +010045 *
46 * - conditional data selection
Dave Rodgman48fb8a32023-08-10 14:01:51 +010047 * These are all named mbedtls_ct_<type>_if and mbedtls_ct_<type>_if_else_0
Dave Rodgman40a41d02023-05-17 11:59:56 +010048 * All arguments are considered secret.
49 * example: size_t a = x ? b : c => a = mbedtls_ct_size_if(x, b, c)
Dave Rodgmane97de402023-08-29 09:47:35 +010050 * example: unsigned a = x ? b : 0 => a = mbedtls_ct_uint_if_else_0(x, b)
Dave Rodgman40a41d02023-05-17 11:59:56 +010051 *
52 * - block memory operations
53 * Only some arguments are considered secret, as documented for each
54 * function.
55 * example: if (x) memcpy(...) => mbedtls_ct_memcpy_if(x, ...)
56 *
Dave Rodgman93cec452023-07-31 12:30:26 +010057 * mbedtls_ct_condition_t must be treated as opaque and only created and
58 * manipulated via the functions in this header. The compiler should never
59 * be able to prove anything about its value at compile-time.
Dave Rodgman40a41d02023-05-17 11:59:56 +010060 *
61 * mbedtls_ct_uint_t is an unsigned integer type over which constant time
62 * operations may be performed via the functions in this header. It is as big
63 * as the larger of size_t and mbedtls_mpi_uint, i.e. it is safe to cast
64 * to/from "unsigned int", "size_t", and "mbedtls_mpi_uint" (and any other
65 * not-larger integer types).
66 *
Dave Rodgmanf27727b2023-05-13 12:12:02 +010067 * For Arm (32-bit, 64-bit and Thumb), x86 and x86-64, assembly implementations
68 * are used to ensure that the generated code is constant time. For other
Dave Rodgman0172de82023-07-31 12:32:23 +010069 * architectures, it uses a plain C fallback designed to yield constant-time code
70 * (this has been observed to be constant-time on latest gcc, clang and MSVC
71 * as of May 2023).
Dave Rodgman205295c2023-08-01 14:10:56 +010072 *
73 * For readability, the static inline definitions are separated out into
74 * constant_time_impl.h.
Dave Rodgman40a41d02023-05-17 11:59:56 +010075 */
76
77#if (SIZE_MAX > 0xffffffffffffffffULL)
78/* Pointer size > 64-bit */
79typedef size_t mbedtls_ct_condition_t;
80typedef size_t mbedtls_ct_uint_t;
81typedef ptrdiff_t mbedtls_ct_int_t;
Dave Rodgmanfba55982023-07-14 13:44:22 +010082#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(SIZE_MAX))
Dave Rodgman40a41d02023-05-17 11:59:56 +010083#elif (SIZE_MAX > 0xffffffff) || defined(MBEDTLS_HAVE_INT64)
Dave Rodgmanc882adf2023-06-21 07:37:56 +010084/* 32-bit < pointer size <= 64-bit, or 64-bit MPI */
Dave Rodgman40a41d02023-05-17 11:59:56 +010085typedef uint64_t mbedtls_ct_condition_t;
86typedef uint64_t mbedtls_ct_uint_t;
87typedef int64_t mbedtls_ct_int_t;
Dave Rodgmanc9ed5de2023-05-13 12:47:02 +010088#define MBEDTLS_CT_SIZE_64
Dave Rodgmanfba55982023-07-14 13:44:22 +010089#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(UINT64_MAX))
Dave Rodgman40a41d02023-05-17 11:59:56 +010090#else
Dave Rodgmanc882adf2023-06-21 07:37:56 +010091/* Pointer size <= 32-bit, and no 64-bit MPIs */
Dave Rodgman40a41d02023-05-17 11:59:56 +010092typedef uint32_t mbedtls_ct_condition_t;
93typedef uint32_t mbedtls_ct_uint_t;
94typedef int32_t mbedtls_ct_int_t;
Dave Rodgmanc9ed5de2023-05-13 12:47:02 +010095#define MBEDTLS_CT_SIZE_32
Dave Rodgmanfba55982023-07-14 13:44:22 +010096#define MBEDTLS_CT_TRUE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(UINT32_MAX))
Dave Rodgman40a41d02023-05-17 11:59:56 +010097#endif
Dave Rodgmanfba55982023-07-14 13:44:22 +010098#define MBEDTLS_CT_FALSE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(0))
Dave Rodgman40a41d02023-05-17 11:59:56 +010099
Dave Rodgman40a41d02023-05-17 11:59:56 +0100100/* ============================================================================
101 * Boolean operations
102 */
103
104/** Convert a number into a mbedtls_ct_condition_t.
105 *
106 * \param x Number to convert.
107 *
108 * \return MBEDTLS_CT_TRUE if \p x != 0, or MBEDTLS_CT_FALSE if \p x == 0
109 *
110 */
111static inline mbedtls_ct_condition_t mbedtls_ct_bool(mbedtls_ct_uint_t x);
112
113/** Boolean "not equal" operation.
114 *
115 * Functionally equivalent to:
116 *
117 * \p x != \p y
118 *
119 * \param x The first value to analyze.
120 * \param y The second value to analyze.
121 *
122 * \return MBEDTLS_CT_TRUE if \p x != \p y, otherwise MBEDTLS_CT_FALSE.
123 */
Dave Rodgmanb7825ce2023-08-10 11:58:18 +0100124static inline mbedtls_ct_condition_t mbedtls_ct_uint_ne(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y);
Dave Rodgman40a41d02023-05-17 11:59:56 +0100125
126/** Boolean "equals" operation.
127 *
128 * Functionally equivalent to:
129 *
130 * \p x == \p y
131 *
132 * \param x The first value to analyze.
133 * \param y The second value to analyze.
134 *
135 * \return MBEDTLS_CT_TRUE if \p x == \p y, otherwise MBEDTLS_CT_FALSE.
136 */
Dave Rodgmanb7825ce2023-08-10 11:58:18 +0100137static inline mbedtls_ct_condition_t mbedtls_ct_uint_eq(mbedtls_ct_uint_t x,
Dave Rodgman40a41d02023-05-17 11:59:56 +0100138 mbedtls_ct_uint_t y);
139
140/** Boolean "less than" operation.
141 *
142 * Functionally equivalent to:
143 *
144 * \p x < \p y
145 *
146 * \param x The first value to analyze.
147 * \param y The second value to analyze.
148 *
149 * \return MBEDTLS_CT_TRUE if \p x < \p y, otherwise MBEDTLS_CT_FALSE.
150 */
Dave Rodgmanb7825ce2023-08-10 11:58:18 +0100151static inline mbedtls_ct_condition_t mbedtls_ct_uint_lt(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y);
Dave Rodgman40a41d02023-05-17 11:59:56 +0100152
153/** Boolean "greater than" operation.
154 *
155 * Functionally equivalent to:
156 *
157 * \p x > \p y
158 *
159 * \param x The first value to analyze.
160 * \param y The second value to analyze.
161 *
162 * \return MBEDTLS_CT_TRUE if \p x > \p y, otherwise MBEDTLS_CT_FALSE.
163 */
Dave Rodgmanb7825ce2023-08-10 11:58:18 +0100164static inline mbedtls_ct_condition_t mbedtls_ct_uint_gt(mbedtls_ct_uint_t x,
Dave Rodgman40a41d02023-05-17 11:59:56 +0100165 mbedtls_ct_uint_t y);
166
167/** Boolean "greater or equal" operation.
168 *
169 * Functionally equivalent to:
170 *
171 * \p x >= \p y
172 *
173 * \param x The first value to analyze.
174 * \param y The second value to analyze.
175 *
176 * \return MBEDTLS_CT_TRUE if \p x >= \p y,
177 * otherwise MBEDTLS_CT_FALSE.
178 */
Dave Rodgmanb7825ce2023-08-10 11:58:18 +0100179static inline mbedtls_ct_condition_t mbedtls_ct_uint_ge(mbedtls_ct_uint_t x,
Dave Rodgman40a41d02023-05-17 11:59:56 +0100180 mbedtls_ct_uint_t y);
181
182/** Boolean "less than or equal" operation.
183 *
184 * Functionally equivalent to:
185 *
186 * \p x <= \p y
187 *
188 * \param x The first value to analyze.
189 * \param y The second value to analyze.
190 *
191 * \return MBEDTLS_CT_TRUE if \p x <= \p y,
192 * otherwise MBEDTLS_CT_FALSE.
193 */
Dave Rodgmanb7825ce2023-08-10 11:58:18 +0100194static inline mbedtls_ct_condition_t mbedtls_ct_uint_le(mbedtls_ct_uint_t x,
Dave Rodgman40a41d02023-05-17 11:59:56 +0100195 mbedtls_ct_uint_t y);
196
Dave Rodgman1cfc43c2023-09-19 16:18:59 +0100197/** Boolean not-equals operation.
Dave Rodgman40a41d02023-05-17 11:59:56 +0100198 *
199 * Functionally equivalent to:
200 *
Dave Rodgman1cfc43c2023-09-19 16:18:59 +0100201 * \p x != \p y
Dave Rodgman40a41d02023-05-17 11:59:56 +0100202 *
203 * \param x The first value to analyze.
204 * \param y The second value to analyze.
205 *
Dave Rodgman48fb8a32023-08-10 14:01:51 +0100206 * \note This is more efficient than mbedtls_ct_uint_ne if both arguments are
Dave Rodgman40a41d02023-05-17 11:59:56 +0100207 * mbedtls_ct_condition_t.
208 *
Dave Rodgman1cfc43c2023-09-19 16:18:59 +0100209 * \return MBEDTLS_CT_TRUE if \p x != \p y,
Dave Rodgman40a41d02023-05-17 11:59:56 +0100210 * otherwise MBEDTLS_CT_FALSE.
211 */
Dave Rodgman1cfc43c2023-09-19 16:18:59 +0100212static inline mbedtls_ct_condition_t mbedtls_ct_bool_ne(mbedtls_ct_condition_t x,
213 mbedtls_ct_condition_t y);
Dave Rodgman40a41d02023-05-17 11:59:56 +0100214
215/** Boolean "and" operation.
216 *
217 * Functionally equivalent to:
218 *
219 * \p x && \p y
220 *
221 * \param x The first value to analyze.
222 * \param y The second value to analyze.
223 *
224 * \return MBEDTLS_CT_TRUE if \p x && \p y,
225 * otherwise MBEDTLS_CT_FALSE.
226 */
227static inline mbedtls_ct_condition_t mbedtls_ct_bool_and(mbedtls_ct_condition_t x,
228 mbedtls_ct_condition_t y);
229
230/** Boolean "or" operation.
231 *
232 * Functionally equivalent to:
233 *
234 * \p x || \p y
235 *
236 * \param x The first value to analyze.
237 * \param y The second value to analyze.
238 *
239 * \return MBEDTLS_CT_TRUE if \p x || \p y,
240 * otherwise MBEDTLS_CT_FALSE.
241 */
242static inline mbedtls_ct_condition_t mbedtls_ct_bool_or(mbedtls_ct_condition_t x,
243 mbedtls_ct_condition_t y);
244
245/** Boolean "not" operation.
246 *
247 * Functionally equivalent to:
248 *
249 * ! \p x
250 *
251 * \param x The value to invert
252 *
253 * \return MBEDTLS_CT_FALSE if \p x, otherwise MBEDTLS_CT_TRUE.
254 */
255static inline mbedtls_ct_condition_t mbedtls_ct_bool_not(mbedtls_ct_condition_t x);
256
257
258/* ============================================================================
259 * Data selection operations
260 */
261
262/** Choose between two size_t values.
263 *
264 * Functionally equivalent to:
265 *
266 * condition ? if1 : if0.
267 *
268 * \param condition Condition to test.
269 * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
270 * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE.
271 *
272 * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
273 */
274static inline size_t mbedtls_ct_size_if(mbedtls_ct_condition_t condition,
275 size_t if1,
276 size_t if0);
277
278/** Choose between two unsigned values.
279 *
280 * Functionally equivalent to:
281 *
282 * condition ? if1 : if0.
283 *
284 * \param condition Condition to test.
285 * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
286 * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE.
287 *
288 * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
289 */
Dave Rodgman2b4486a2023-05-17 15:51:59 +0100290static inline unsigned mbedtls_ct_uint_if(mbedtls_ct_condition_t condition,
Dave Rodgman40a41d02023-05-17 11:59:56 +0100291 unsigned if1,
292 unsigned if0);
293
Dave Rodgman143f5f72023-09-19 21:51:13 +0100294/** Choose between two mbedtls_ct_condition_t 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_ct_condition_t mbedtls_ct_bool_if(mbedtls_ct_condition_t condition,
307 mbedtls_ct_condition_t if1,
308 mbedtls_ct_condition_t if0);
309
Dave Rodgman40a41d02023-05-17 11:59:56 +0100310#if defined(MBEDTLS_BIGNUM_C)
311
312/** Choose between two mbedtls_mpi_uint values.
313 *
314 * Functionally equivalent to:
315 *
316 * condition ? if1 : if0.
317 *
318 * \param condition Condition to test.
319 * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
320 * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE.
321 *
322 * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
323 */
324static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if(mbedtls_ct_condition_t condition, \
325 mbedtls_mpi_uint if1, \
326 mbedtls_mpi_uint if0);
327
328#endif
329
330/** Choose between an unsigned value and 0.
331 *
332 * Functionally equivalent to:
333 *
334 * condition ? if1 : 0.
335 *
Dave Rodgman065f9122023-08-10 12:11:58 +0100336 * Functionally equivalent to mbedtls_ct_uint_if(condition, if1, 0) but
Dave Rodgman40a41d02023-05-17 11:59:56 +0100337 * 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 */
Dave Rodgman98ddc012023-08-10 12:11:31 +0100344static inline unsigned mbedtls_ct_uint_if_else_0(mbedtls_ct_condition_t condition, unsigned if1);
Dave Rodgman40a41d02023-05-17 11:59:56 +0100345
Dave Rodgman143f5f72023-09-19 21:51:13 +0100346/** Choose between an mbedtls_ct_condition_t and 0.
347 *
348 * Functionally equivalent to:
349 *
350 * condition ? if1 : 0.
351 *
352 * Functionally equivalent to mbedtls_ct_bool_if(condition, if1, 0) but
353 * results in smaller code size.
354 *
355 * \param condition Condition to test.
356 * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
357 *
358 * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
359 */
360static inline mbedtls_ct_condition_t mbedtls_ct_bool_if_else_0(mbedtls_ct_condition_t condition,
361 mbedtls_ct_condition_t if1);
362
Dave Rodgmanb364a222023-08-10 12:25:25 +0100363/** Choose between a size_t value and 0.
Dave Rodgmanac69b452023-08-10 12:13:27 +0100364 *
365 * Functionally equivalent to:
366 *
367 * condition ? if1 : 0.
368 *
369 * Functionally equivalent to mbedtls_ct_size_if(condition, if1, 0) but
370 * results in smaller code size.
371 *
372 * \param condition Condition to test.
373 * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
374 *
375 * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
376 */
377static inline size_t mbedtls_ct_size_if_else_0(mbedtls_ct_condition_t condition, size_t if1);
378
Dave Rodgman40a41d02023-05-17 11:59:56 +0100379#if defined(MBEDTLS_BIGNUM_C)
380
381/** Choose between an mbedtls_mpi_uint value and 0.
382 *
383 * Functionally equivalent to:
384 *
385 * condition ? if1 : 0.
386 *
Dave Rodgman065f9122023-08-10 12:11:58 +0100387 * Functionally equivalent to mbedtls_ct_mpi_uint_if(condition, if1, 0) but
Dave Rodgman40a41d02023-05-17 11:59:56 +0100388 * results in smaller code size.
389 *
390 * \param condition Condition to test.
391 * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
392 *
393 * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
394 */
Dave Rodgman98ddc012023-08-10 12:11:31 +0100395static inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if_else_0(mbedtls_ct_condition_t condition,
396 mbedtls_mpi_uint if1);
Dave Rodgman40a41d02023-05-17 11:59:56 +0100397
398#endif
399
400/** Constant-flow char selection
401 *
402 * \param low Secret. Bottom of range
403 * \param high Secret. Top of range
404 * \param c Secret. Value to compare to range
405 * \param t Secret. Value to return, if in range
406 *
407 * \return \p t if \p low <= \p c <= \p high, 0 otherwise.
408 */
409static inline unsigned char mbedtls_ct_uchar_in_range_if(unsigned char low,
410 unsigned char high,
411 unsigned char c,
412 unsigned char t);
413
Dave Rodgmanfbe74a92023-09-22 09:43:49 +0100414/** Choose between two error values. The values must be in the range [-32767..0].
415 *
416 * Functionally equivalent to:
417 *
418 * condition ? if1 : if0.
419 *
420 * \param condition Condition to test.
421 * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
422 * \param if0 Value to use if \p condition == MBEDTLS_CT_FALSE.
423 *
424 * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
425 */
426static inline int mbedtls_ct_error_if(mbedtls_ct_condition_t condition, int if1, int if0);
427
428/** Choose between an error value and 0. The error value must be in the range [-32767..0].
429 *
430 * Functionally equivalent to:
431 *
432 * condition ? if1 : 0.
433 *
434 * Functionally equivalent to mbedtls_ct_error_if(condition, if1, 0) but
435 * results in smaller code size.
436 *
437 * \param condition Condition to test.
438 * \param if1 Value to use if \p condition == MBEDTLS_CT_TRUE.
439 *
440 * \return \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
441 */
442static inline int mbedtls_ct_error_if_else_0(mbedtls_ct_condition_t condition, int if1);
Dave Rodgman40a41d02023-05-17 11:59:56 +0100443
444/* ============================================================================
445 * Block memory operations
446 */
447
448#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
449
450/** Conditionally set a block of memory to zero.
451 *
452 * Regardless of the condition, every byte will be read once and written to
453 * once.
454 *
455 * \param condition Secret. Condition to test.
456 * \param buf Secret. Pointer to the start of the buffer.
457 * \param len Number of bytes to set to zero.
458 *
459 * \warning Unlike mbedtls_platform_zeroize, this does not have the same guarantees
460 * about not being optimised away if the memory is never read again.
461 */
462void mbedtls_ct_zeroize_if(mbedtls_ct_condition_t condition, void *buf, size_t len);
463
464/** Shift some data towards the left inside a buffer.
465 *
466 * Functionally equivalent to:
467 *
468 * memmove(start, start + offset, total - offset);
469 * memset(start + (total - offset), 0, offset);
470 *
471 * Timing independence comes at the expense of performance.
472 *
473 * \param start Secret. Pointer to the start of the buffer.
474 * \param total Total size of the buffer.
475 * \param offset Secret. Offset from which to copy \p total - \p offset bytes.
476 */
477void mbedtls_ct_memmove_left(void *start,
478 size_t total,
479 size_t offset);
480
481#endif /* defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT) */
482
483/** Conditional memcpy.
484 *
485 * Functionally equivalent to:
486 *
487 * if (condition) {
488 * memcpy(dest, src1, len);
489 * } else {
490 * if (src2 != NULL)
491 * memcpy(dest, src2, len);
492 * }
493 *
494 * It will always read len bytes from src1.
495 * If src2 != NULL, it will always read len bytes from src2.
496 * If src2 == NULL, it will instead read len bytes from dest (as if src2 == dest).
497 *
498 * \param condition The condition
499 * \param dest Secret. Destination pointer.
Dave Rodgman31086452023-05-18 13:47:13 +0100500 * \param src1 Secret. Pointer to copy from (if \p condition == MBEDTLS_CT_TRUE).
501 * This may be equal to \p dest, but may not overlap in other ways.
Dave Rodgman741d4232023-07-31 12:31:01 +0100502 * \param src2 Secret (contents only - may branch to determine if this parameter is NULL).
Dave Rodgman31086452023-05-18 13:47:13 +0100503 * Pointer to copy from (if \p condition == MBEDTLS_CT_FALSE and \p src2 is not NULL). May be NULL.
504 * 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 +0100505 * \param len Number of bytes to copy.
506 */
507void mbedtls_ct_memcpy_if(mbedtls_ct_condition_t condition,
508 unsigned char *dest,
509 const unsigned char *src1,
510 const unsigned char *src2,
511 size_t len
512 );
513
514/** Copy data from a secret position.
515 *
516 * Functionally equivalent to:
517 *
518 * memcpy(dst, src + offset, len)
519 *
Dave Rodgman6d5261e2023-08-09 14:57:25 +0100520 * This function copies \p len bytes from \p src + \p offset to
521 * \p dst, with a code flow and memory access pattern that does not depend on
Dave Rodgman40a41d02023-05-17 11:59:56 +0100522 * \p offset, but only on \p offset_min, \p offset_max and \p len.
523 *
524 * \note This function reads from \p dest, but the value that
525 * is read does not influence the result and this
526 * function's behavior is well-defined regardless of the
527 * contents of the buffers. This may result in false
528 * positives from static or dynamic analyzers, especially
529 * if \p dest is not initialized.
530 *
531 * \param dest Secret. The destination buffer. This must point to a writable
532 * buffer of at least \p len bytes.
533 * \param src Secret. The base of the source buffer. This must point to a
534 * readable buffer of at least \p offset_max + \p len
Dave Rodgman31086452023-05-18 13:47:13 +0100535 * bytes. Shouldn't overlap with \p dest
Dave Rodgman40a41d02023-05-17 11:59:56 +0100536 * \param offset Secret. The offset in the source buffer from which to copy.
537 * This must be no less than \p offset_min and no greater
538 * than \p offset_max.
539 * \param offset_min The minimal value of \p offset.
540 * \param offset_max The maximal value of \p offset.
541 * \param len The number of bytes to copy.
542 */
543void mbedtls_ct_memcpy_offset(unsigned char *dest,
544 const unsigned char *src,
545 size_t offset,
546 size_t offset_min,
547 size_t offset_max,
548 size_t len);
549
Dave Rodgman9ee0e1f2023-07-31 12:33:36 +0100550/* Documented in include/mbedtls/constant_time.h. a and b are secret.
551
552 int mbedtls_ct_memcmp(const void *a,
553 const void *b,
554 size_t n);
555 */
Dave Rodgman40a41d02023-05-17 11:59:56 +0100556
Dave Rodgman9c140072023-09-18 18:20:27 +0100557#if defined(MBEDTLS_NIST_KW_C)
558
559/** Constant-time buffer comparison without branches.
560 *
561 * Similar to mbedtls_ct_memcmp, except that the result only depends on part of
562 * the input data - differences in the head or tail are ignored. Functionally equivalent to:
563 *
564 * memcmp(a + skip_head, b + skip_head, size - skip_head - skip_tail)
565 *
566 * Time taken depends on \p n, but not on \p skip_head or \p skip_tail .
567 *
568 * Behaviour is undefined if ( \p skip_head + \p skip_tail) > \p n.
569 *
570 * \param a Secret. Pointer to the first buffer, containing at least \p n bytes. May not be NULL.
571 * \param b Secret. Pointer to the second buffer, containing at least \p n bytes. May not be NULL.
572 * \param n The number of bytes to examine (total size of the buffers).
573 * \param skip_head Secret. The number of bytes to treat as non-significant at the start of the buffer.
574 * These bytes will still be read.
575 * \param skip_tail Secret. The number of bytes to treat as non-significant at the end of the buffer.
576 * These bytes will still be read.
577 *
578 * \return Zero if the contents of the two buffers are the same, otherwise non-zero.
579 */
580int mbedtls_ct_memcmp_partial(const void *a,
581 const void *b,
582 size_t n,
583 size_t skip_head,
584 size_t skip_tail);
585
586#endif
587
Dave Rodgman205295c2023-08-01 14:10:56 +0100588/* Include the implementation of static inline functions above. */
589#include "constant_time_impl.h"
Dave Rodgmana02b3682023-07-14 13:43:39 +0100590
Gabor Mezei291df7b2021-10-19 11:27:17 +0200591#endif /* MBEDTLS_CONSTANT_TIME_INTERNAL_H */