1a8e1175bSopenharmony_ci/**
2a8e1175bSopenharmony_ci *  Constant-time functions
3a8e1175bSopenharmony_ci *
4a8e1175bSopenharmony_ci *  Copyright The Mbed TLS Contributors
5a8e1175bSopenharmony_ci *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6a8e1175bSopenharmony_ci */
7a8e1175bSopenharmony_ci
8a8e1175bSopenharmony_ci#ifndef MBEDTLS_CONSTANT_TIME_INTERNAL_H
9a8e1175bSopenharmony_ci#define MBEDTLS_CONSTANT_TIME_INTERNAL_H
10a8e1175bSopenharmony_ci
11a8e1175bSopenharmony_ci#include <stdint.h>
12a8e1175bSopenharmony_ci#include <stddef.h>
13a8e1175bSopenharmony_ci
14a8e1175bSopenharmony_ci#include "common.h"
15a8e1175bSopenharmony_ci
16a8e1175bSopenharmony_ci#if defined(MBEDTLS_BIGNUM_C)
17a8e1175bSopenharmony_ci#include "mbedtls/bignum.h"
18a8e1175bSopenharmony_ci#endif
19a8e1175bSopenharmony_ci
20a8e1175bSopenharmony_ci/* The constant-time interface provides various operations that are likely
21a8e1175bSopenharmony_ci * to result in constant-time code that does not branch or use conditional
22a8e1175bSopenharmony_ci * instructions for secret data (for secret pointers, this also applies to
23a8e1175bSopenharmony_ci * the data pointed to).
24a8e1175bSopenharmony_ci *
25a8e1175bSopenharmony_ci * It has three main parts:
26a8e1175bSopenharmony_ci *
27a8e1175bSopenharmony_ci * - boolean operations
28a8e1175bSopenharmony_ci *   These are all named mbedtls_ct_<type>_<operation>.
29a8e1175bSopenharmony_ci *   They operate over <type> and return mbedtls_ct_condition_t.
30a8e1175bSopenharmony_ci *   All arguments are considered secret.
31a8e1175bSopenharmony_ci *   example: bool x = y | z          =>    x = mbedtls_ct_bool_or(y, z)
32a8e1175bSopenharmony_ci *   example: bool x = y == z         =>    x = mbedtls_ct_uint_eq(y, z)
33a8e1175bSopenharmony_ci *
34a8e1175bSopenharmony_ci * - conditional data selection
35a8e1175bSopenharmony_ci *   These are all named mbedtls_ct_<type>_if and mbedtls_ct_<type>_if_else_0
36a8e1175bSopenharmony_ci *   All arguments are considered secret.
37a8e1175bSopenharmony_ci *   example: size_t a = x ? b : c    =>    a = mbedtls_ct_size_if(x, b, c)
38a8e1175bSopenharmony_ci *   example: unsigned a = x ? b : 0  =>    a = mbedtls_ct_uint_if_else_0(x, b)
39a8e1175bSopenharmony_ci *
40a8e1175bSopenharmony_ci * - block memory operations
41a8e1175bSopenharmony_ci *   Only some arguments are considered secret, as documented for each
42a8e1175bSopenharmony_ci *   function.
43a8e1175bSopenharmony_ci *   example: if (x) memcpy(...)      =>    mbedtls_ct_memcpy_if(x, ...)
44a8e1175bSopenharmony_ci *
45a8e1175bSopenharmony_ci * mbedtls_ct_condition_t must be treated as opaque and only created and
46a8e1175bSopenharmony_ci * manipulated via the functions in this header. The compiler should never
47a8e1175bSopenharmony_ci * be able to prove anything about its value at compile-time.
48a8e1175bSopenharmony_ci *
49a8e1175bSopenharmony_ci * mbedtls_ct_uint_t is an unsigned integer type over which constant time
50a8e1175bSopenharmony_ci * operations may be performed via the functions in this header. It is as big
51a8e1175bSopenharmony_ci * as the larger of size_t and mbedtls_mpi_uint, i.e. it is safe to cast
52a8e1175bSopenharmony_ci * to/from "unsigned int", "size_t", and "mbedtls_mpi_uint" (and any other
53a8e1175bSopenharmony_ci * not-larger integer types).
54a8e1175bSopenharmony_ci *
55a8e1175bSopenharmony_ci * For Arm (32-bit, 64-bit and Thumb), x86 and x86-64, assembly implementations
56a8e1175bSopenharmony_ci * are used to ensure that the generated code is constant time. For other
57a8e1175bSopenharmony_ci * architectures, it uses a plain C fallback designed to yield constant-time code
58a8e1175bSopenharmony_ci * (this has been observed to be constant-time on latest gcc, clang and MSVC
59a8e1175bSopenharmony_ci * as of May 2023).
60a8e1175bSopenharmony_ci *
61a8e1175bSopenharmony_ci * For readability, the static inline definitions are separated out into
62a8e1175bSopenharmony_ci * constant_time_impl.h.
63a8e1175bSopenharmony_ci */
64a8e1175bSopenharmony_ci
65a8e1175bSopenharmony_ci#if (SIZE_MAX > 0xffffffffffffffffULL)
66a8e1175bSopenharmony_ci/* Pointer size > 64-bit */
67a8e1175bSopenharmony_citypedef size_t    mbedtls_ct_condition_t;
68a8e1175bSopenharmony_citypedef size_t    mbedtls_ct_uint_t;
69a8e1175bSopenharmony_citypedef ptrdiff_t mbedtls_ct_int_t;
70a8e1175bSopenharmony_ci#define MBEDTLS_CT_TRUE  ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(SIZE_MAX))
71a8e1175bSopenharmony_ci#elif (SIZE_MAX > 0xffffffff) || defined(MBEDTLS_HAVE_INT64)
72a8e1175bSopenharmony_ci/* 32-bit < pointer size <= 64-bit, or 64-bit MPI */
73a8e1175bSopenharmony_citypedef uint64_t  mbedtls_ct_condition_t;
74a8e1175bSopenharmony_citypedef uint64_t  mbedtls_ct_uint_t;
75a8e1175bSopenharmony_citypedef int64_t   mbedtls_ct_int_t;
76a8e1175bSopenharmony_ci#define MBEDTLS_CT_SIZE_64
77a8e1175bSopenharmony_ci#define MBEDTLS_CT_TRUE  ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(UINT64_MAX))
78a8e1175bSopenharmony_ci#else
79a8e1175bSopenharmony_ci/* Pointer size <= 32-bit, and no 64-bit MPIs */
80a8e1175bSopenharmony_citypedef uint32_t  mbedtls_ct_condition_t;
81a8e1175bSopenharmony_citypedef uint32_t  mbedtls_ct_uint_t;
82a8e1175bSopenharmony_citypedef int32_t   mbedtls_ct_int_t;
83a8e1175bSopenharmony_ci#define MBEDTLS_CT_SIZE_32
84a8e1175bSopenharmony_ci#define MBEDTLS_CT_TRUE  ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(UINT32_MAX))
85a8e1175bSopenharmony_ci#endif
86a8e1175bSopenharmony_ci#define MBEDTLS_CT_FALSE ((mbedtls_ct_condition_t) mbedtls_ct_compiler_opaque(0))
87a8e1175bSopenharmony_ci
88a8e1175bSopenharmony_ci/* ============================================================================
89a8e1175bSopenharmony_ci * Boolean operations
90a8e1175bSopenharmony_ci */
91a8e1175bSopenharmony_ci
92a8e1175bSopenharmony_ci/** Convert a number into a mbedtls_ct_condition_t.
93a8e1175bSopenharmony_ci *
94a8e1175bSopenharmony_ci * \param x Number to convert.
95a8e1175bSopenharmony_ci *
96a8e1175bSopenharmony_ci * \return MBEDTLS_CT_TRUE if \p x != 0, or MBEDTLS_CT_FALSE if \p x == 0
97a8e1175bSopenharmony_ci *
98a8e1175bSopenharmony_ci */
99a8e1175bSopenharmony_cistatic inline mbedtls_ct_condition_t mbedtls_ct_bool(mbedtls_ct_uint_t x);
100a8e1175bSopenharmony_ci
101a8e1175bSopenharmony_ci/** Boolean "not equal" operation.
102a8e1175bSopenharmony_ci *
103a8e1175bSopenharmony_ci * Functionally equivalent to:
104a8e1175bSopenharmony_ci *
105a8e1175bSopenharmony_ci * \p x != \p y
106a8e1175bSopenharmony_ci *
107a8e1175bSopenharmony_ci * \param x     The first value to analyze.
108a8e1175bSopenharmony_ci * \param y     The second value to analyze.
109a8e1175bSopenharmony_ci *
110a8e1175bSopenharmony_ci * \return      MBEDTLS_CT_TRUE if \p x != \p y, otherwise MBEDTLS_CT_FALSE.
111a8e1175bSopenharmony_ci */
112a8e1175bSopenharmony_cistatic inline mbedtls_ct_condition_t mbedtls_ct_uint_ne(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y);
113a8e1175bSopenharmony_ci
114a8e1175bSopenharmony_ci/** Boolean "equals" operation.
115a8e1175bSopenharmony_ci *
116a8e1175bSopenharmony_ci * Functionally equivalent to:
117a8e1175bSopenharmony_ci *
118a8e1175bSopenharmony_ci * \p x == \p y
119a8e1175bSopenharmony_ci *
120a8e1175bSopenharmony_ci * \param x     The first value to analyze.
121a8e1175bSopenharmony_ci * \param y     The second value to analyze.
122a8e1175bSopenharmony_ci *
123a8e1175bSopenharmony_ci * \return      MBEDTLS_CT_TRUE if \p x == \p y, otherwise MBEDTLS_CT_FALSE.
124a8e1175bSopenharmony_ci */
125a8e1175bSopenharmony_cistatic inline mbedtls_ct_condition_t mbedtls_ct_uint_eq(mbedtls_ct_uint_t x,
126a8e1175bSopenharmony_ci                                                        mbedtls_ct_uint_t y);
127a8e1175bSopenharmony_ci
128a8e1175bSopenharmony_ci/** Boolean "less than" operation.
129a8e1175bSopenharmony_ci *
130a8e1175bSopenharmony_ci * Functionally equivalent to:
131a8e1175bSopenharmony_ci *
132a8e1175bSopenharmony_ci * \p x < \p y
133a8e1175bSopenharmony_ci *
134a8e1175bSopenharmony_ci * \param x     The first value to analyze.
135a8e1175bSopenharmony_ci * \param y     The second value to analyze.
136a8e1175bSopenharmony_ci *
137a8e1175bSopenharmony_ci * \return      MBEDTLS_CT_TRUE if \p x < \p y, otherwise MBEDTLS_CT_FALSE.
138a8e1175bSopenharmony_ci */
139a8e1175bSopenharmony_cistatic inline mbedtls_ct_condition_t mbedtls_ct_uint_lt(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y);
140a8e1175bSopenharmony_ci
141a8e1175bSopenharmony_ci/** Boolean "greater than" operation.
142a8e1175bSopenharmony_ci *
143a8e1175bSopenharmony_ci * Functionally equivalent to:
144a8e1175bSopenharmony_ci *
145a8e1175bSopenharmony_ci * \p x > \p y
146a8e1175bSopenharmony_ci *
147a8e1175bSopenharmony_ci * \param x     The first value to analyze.
148a8e1175bSopenharmony_ci * \param y     The second value to analyze.
149a8e1175bSopenharmony_ci *
150a8e1175bSopenharmony_ci * \return      MBEDTLS_CT_TRUE if \p x > \p y, otherwise MBEDTLS_CT_FALSE.
151a8e1175bSopenharmony_ci */
152a8e1175bSopenharmony_cistatic inline mbedtls_ct_condition_t mbedtls_ct_uint_gt(mbedtls_ct_uint_t x,
153a8e1175bSopenharmony_ci                                                        mbedtls_ct_uint_t y);
154a8e1175bSopenharmony_ci
155a8e1175bSopenharmony_ci/** Boolean "greater or equal" operation.
156a8e1175bSopenharmony_ci *
157a8e1175bSopenharmony_ci * Functionally equivalent to:
158a8e1175bSopenharmony_ci *
159a8e1175bSopenharmony_ci * \p x >= \p y
160a8e1175bSopenharmony_ci *
161a8e1175bSopenharmony_ci * \param x     The first value to analyze.
162a8e1175bSopenharmony_ci * \param y     The second value to analyze.
163a8e1175bSopenharmony_ci *
164a8e1175bSopenharmony_ci * \return      MBEDTLS_CT_TRUE if \p x >= \p y,
165a8e1175bSopenharmony_ci *              otherwise MBEDTLS_CT_FALSE.
166a8e1175bSopenharmony_ci */
167a8e1175bSopenharmony_cistatic inline mbedtls_ct_condition_t mbedtls_ct_uint_ge(mbedtls_ct_uint_t x,
168a8e1175bSopenharmony_ci                                                        mbedtls_ct_uint_t y);
169a8e1175bSopenharmony_ci
170a8e1175bSopenharmony_ci/** Boolean "less than or equal" operation.
171a8e1175bSopenharmony_ci *
172a8e1175bSopenharmony_ci * Functionally equivalent to:
173a8e1175bSopenharmony_ci *
174a8e1175bSopenharmony_ci * \p x <= \p y
175a8e1175bSopenharmony_ci *
176a8e1175bSopenharmony_ci * \param x     The first value to analyze.
177a8e1175bSopenharmony_ci * \param y     The second value to analyze.
178a8e1175bSopenharmony_ci *
179a8e1175bSopenharmony_ci * \return      MBEDTLS_CT_TRUE if \p x <= \p y,
180a8e1175bSopenharmony_ci *              otherwise MBEDTLS_CT_FALSE.
181a8e1175bSopenharmony_ci */
182a8e1175bSopenharmony_cistatic inline mbedtls_ct_condition_t mbedtls_ct_uint_le(mbedtls_ct_uint_t x,
183a8e1175bSopenharmony_ci                                                        mbedtls_ct_uint_t y);
184a8e1175bSopenharmony_ci
185a8e1175bSopenharmony_ci/** Boolean not-equals operation.
186a8e1175bSopenharmony_ci *
187a8e1175bSopenharmony_ci * Functionally equivalent to:
188a8e1175bSopenharmony_ci *
189a8e1175bSopenharmony_ci * \p x != \p y
190a8e1175bSopenharmony_ci *
191a8e1175bSopenharmony_ci * \param x     The first value to analyze.
192a8e1175bSopenharmony_ci * \param y     The second value to analyze.
193a8e1175bSopenharmony_ci *
194a8e1175bSopenharmony_ci * \note        This is more efficient than mbedtls_ct_uint_ne if both arguments are
195a8e1175bSopenharmony_ci *              mbedtls_ct_condition_t.
196a8e1175bSopenharmony_ci *
197a8e1175bSopenharmony_ci * \return      MBEDTLS_CT_TRUE if \p x != \p y,
198a8e1175bSopenharmony_ci *              otherwise MBEDTLS_CT_FALSE.
199a8e1175bSopenharmony_ci */
200a8e1175bSopenharmony_cistatic inline mbedtls_ct_condition_t mbedtls_ct_bool_ne(mbedtls_ct_condition_t x,
201a8e1175bSopenharmony_ci                                                        mbedtls_ct_condition_t y);
202a8e1175bSopenharmony_ci
203a8e1175bSopenharmony_ci/** Boolean "and" operation.
204a8e1175bSopenharmony_ci *
205a8e1175bSopenharmony_ci * Functionally equivalent to:
206a8e1175bSopenharmony_ci *
207a8e1175bSopenharmony_ci * \p x && \p y
208a8e1175bSopenharmony_ci *
209a8e1175bSopenharmony_ci * \param x     The first value to analyze.
210a8e1175bSopenharmony_ci * \param y     The second value to analyze.
211a8e1175bSopenharmony_ci *
212a8e1175bSopenharmony_ci * \return      MBEDTLS_CT_TRUE if \p x && \p y,
213a8e1175bSopenharmony_ci *              otherwise MBEDTLS_CT_FALSE.
214a8e1175bSopenharmony_ci */
215a8e1175bSopenharmony_cistatic inline mbedtls_ct_condition_t mbedtls_ct_bool_and(mbedtls_ct_condition_t x,
216a8e1175bSopenharmony_ci                                                         mbedtls_ct_condition_t y);
217a8e1175bSopenharmony_ci
218a8e1175bSopenharmony_ci/** Boolean "or" operation.
219a8e1175bSopenharmony_ci *
220a8e1175bSopenharmony_ci * Functionally equivalent to:
221a8e1175bSopenharmony_ci *
222a8e1175bSopenharmony_ci * \p x || \p y
223a8e1175bSopenharmony_ci *
224a8e1175bSopenharmony_ci * \param x     The first value to analyze.
225a8e1175bSopenharmony_ci * \param y     The second value to analyze.
226a8e1175bSopenharmony_ci *
227a8e1175bSopenharmony_ci * \return      MBEDTLS_CT_TRUE if \p x || \p y,
228a8e1175bSopenharmony_ci *              otherwise MBEDTLS_CT_FALSE.
229a8e1175bSopenharmony_ci */
230a8e1175bSopenharmony_cistatic inline mbedtls_ct_condition_t mbedtls_ct_bool_or(mbedtls_ct_condition_t x,
231a8e1175bSopenharmony_ci                                                        mbedtls_ct_condition_t y);
232a8e1175bSopenharmony_ci
233a8e1175bSopenharmony_ci/** Boolean "not" operation.
234a8e1175bSopenharmony_ci *
235a8e1175bSopenharmony_ci * Functionally equivalent to:
236a8e1175bSopenharmony_ci *
237a8e1175bSopenharmony_ci * ! \p x
238a8e1175bSopenharmony_ci *
239a8e1175bSopenharmony_ci * \param x     The value to invert
240a8e1175bSopenharmony_ci *
241a8e1175bSopenharmony_ci * \return      MBEDTLS_CT_FALSE if \p x, otherwise MBEDTLS_CT_TRUE.
242a8e1175bSopenharmony_ci */
243a8e1175bSopenharmony_cistatic inline mbedtls_ct_condition_t mbedtls_ct_bool_not(mbedtls_ct_condition_t x);
244a8e1175bSopenharmony_ci
245a8e1175bSopenharmony_ci
246a8e1175bSopenharmony_ci/* ============================================================================
247a8e1175bSopenharmony_ci * Data selection operations
248a8e1175bSopenharmony_ci */
249a8e1175bSopenharmony_ci
250a8e1175bSopenharmony_ci/** Choose between two size_t values.
251a8e1175bSopenharmony_ci *
252a8e1175bSopenharmony_ci * Functionally equivalent to:
253a8e1175bSopenharmony_ci *
254a8e1175bSopenharmony_ci * condition ? if1 : if0.
255a8e1175bSopenharmony_ci *
256a8e1175bSopenharmony_ci * \param condition     Condition to test.
257a8e1175bSopenharmony_ci * \param if1           Value to use if \p condition == MBEDTLS_CT_TRUE.
258a8e1175bSopenharmony_ci * \param if0           Value to use if \p condition == MBEDTLS_CT_FALSE.
259a8e1175bSopenharmony_ci *
260a8e1175bSopenharmony_ci * \return  \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
261a8e1175bSopenharmony_ci */
262a8e1175bSopenharmony_cistatic inline size_t mbedtls_ct_size_if(mbedtls_ct_condition_t condition,
263a8e1175bSopenharmony_ci                                        size_t if1,
264a8e1175bSopenharmony_ci                                        size_t if0);
265a8e1175bSopenharmony_ci
266a8e1175bSopenharmony_ci/** Choose between two unsigned values.
267a8e1175bSopenharmony_ci *
268a8e1175bSopenharmony_ci * Functionally equivalent to:
269a8e1175bSopenharmony_ci *
270a8e1175bSopenharmony_ci * condition ? if1 : if0.
271a8e1175bSopenharmony_ci *
272a8e1175bSopenharmony_ci * \param condition     Condition to test.
273a8e1175bSopenharmony_ci * \param if1           Value to use if \p condition == MBEDTLS_CT_TRUE.
274a8e1175bSopenharmony_ci * \param if0           Value to use if \p condition == MBEDTLS_CT_FALSE.
275a8e1175bSopenharmony_ci *
276a8e1175bSopenharmony_ci * \return  \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
277a8e1175bSopenharmony_ci */
278a8e1175bSopenharmony_cistatic inline unsigned mbedtls_ct_uint_if(mbedtls_ct_condition_t condition,
279a8e1175bSopenharmony_ci                                          unsigned if1,
280a8e1175bSopenharmony_ci                                          unsigned if0);
281a8e1175bSopenharmony_ci
282a8e1175bSopenharmony_ci/** Choose between two mbedtls_ct_condition_t values.
283a8e1175bSopenharmony_ci *
284a8e1175bSopenharmony_ci * Functionally equivalent to:
285a8e1175bSopenharmony_ci *
286a8e1175bSopenharmony_ci * condition ? if1 : if0.
287a8e1175bSopenharmony_ci *
288a8e1175bSopenharmony_ci * \param condition     Condition to test.
289a8e1175bSopenharmony_ci * \param if1           Value to use if \p condition == MBEDTLS_CT_TRUE.
290a8e1175bSopenharmony_ci * \param if0           Value to use if \p condition == MBEDTLS_CT_FALSE.
291a8e1175bSopenharmony_ci *
292a8e1175bSopenharmony_ci * \return  \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
293a8e1175bSopenharmony_ci */
294a8e1175bSopenharmony_cistatic inline mbedtls_ct_condition_t mbedtls_ct_bool_if(mbedtls_ct_condition_t condition,
295a8e1175bSopenharmony_ci                                                        mbedtls_ct_condition_t if1,
296a8e1175bSopenharmony_ci                                                        mbedtls_ct_condition_t if0);
297a8e1175bSopenharmony_ci
298a8e1175bSopenharmony_ci#if defined(MBEDTLS_BIGNUM_C)
299a8e1175bSopenharmony_ci
300a8e1175bSopenharmony_ci/** Choose between two mbedtls_mpi_uint values.
301a8e1175bSopenharmony_ci *
302a8e1175bSopenharmony_ci * Functionally equivalent to:
303a8e1175bSopenharmony_ci *
304a8e1175bSopenharmony_ci * condition ? if1 : if0.
305a8e1175bSopenharmony_ci *
306a8e1175bSopenharmony_ci * \param condition     Condition to test.
307a8e1175bSopenharmony_ci * \param if1           Value to use if \p condition == MBEDTLS_CT_TRUE.
308a8e1175bSopenharmony_ci * \param if0           Value to use if \p condition == MBEDTLS_CT_FALSE.
309a8e1175bSopenharmony_ci *
310a8e1175bSopenharmony_ci * \return  \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
311a8e1175bSopenharmony_ci */
312a8e1175bSopenharmony_cistatic inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if(mbedtls_ct_condition_t condition, \
313a8e1175bSopenharmony_ci                                                      mbedtls_mpi_uint if1, \
314a8e1175bSopenharmony_ci                                                      mbedtls_mpi_uint if0);
315a8e1175bSopenharmony_ci
316a8e1175bSopenharmony_ci#endif
317a8e1175bSopenharmony_ci
318a8e1175bSopenharmony_ci/** Choose between an unsigned value and 0.
319a8e1175bSopenharmony_ci *
320a8e1175bSopenharmony_ci * Functionally equivalent to:
321a8e1175bSopenharmony_ci *
322a8e1175bSopenharmony_ci * condition ? if1 : 0.
323a8e1175bSopenharmony_ci *
324a8e1175bSopenharmony_ci * Functionally equivalent to mbedtls_ct_uint_if(condition, if1, 0) but
325a8e1175bSopenharmony_ci * results in smaller code size.
326a8e1175bSopenharmony_ci *
327a8e1175bSopenharmony_ci * \param condition     Condition to test.
328a8e1175bSopenharmony_ci * \param if1           Value to use if \p condition == MBEDTLS_CT_TRUE.
329a8e1175bSopenharmony_ci *
330a8e1175bSopenharmony_ci * \return  \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
331a8e1175bSopenharmony_ci */
332a8e1175bSopenharmony_cistatic inline unsigned mbedtls_ct_uint_if_else_0(mbedtls_ct_condition_t condition, unsigned if1);
333a8e1175bSopenharmony_ci
334a8e1175bSopenharmony_ci/** Choose between an mbedtls_ct_condition_t and 0.
335a8e1175bSopenharmony_ci *
336a8e1175bSopenharmony_ci * Functionally equivalent to:
337a8e1175bSopenharmony_ci *
338a8e1175bSopenharmony_ci * condition ? if1 : 0.
339a8e1175bSopenharmony_ci *
340a8e1175bSopenharmony_ci * Functionally equivalent to mbedtls_ct_bool_if(condition, if1, 0) but
341a8e1175bSopenharmony_ci * results in smaller code size.
342a8e1175bSopenharmony_ci *
343a8e1175bSopenharmony_ci * \param condition     Condition to test.
344a8e1175bSopenharmony_ci * \param if1           Value to use if \p condition == MBEDTLS_CT_TRUE.
345a8e1175bSopenharmony_ci *
346a8e1175bSopenharmony_ci * \return  \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
347a8e1175bSopenharmony_ci */
348a8e1175bSopenharmony_cistatic inline mbedtls_ct_condition_t mbedtls_ct_bool_if_else_0(mbedtls_ct_condition_t condition,
349a8e1175bSopenharmony_ci                                                               mbedtls_ct_condition_t if1);
350a8e1175bSopenharmony_ci
351a8e1175bSopenharmony_ci/** Choose between a size_t value and 0.
352a8e1175bSopenharmony_ci *
353a8e1175bSopenharmony_ci * Functionally equivalent to:
354a8e1175bSopenharmony_ci *
355a8e1175bSopenharmony_ci * condition ? if1 : 0.
356a8e1175bSopenharmony_ci *
357a8e1175bSopenharmony_ci * Functionally equivalent to mbedtls_ct_size_if(condition, if1, 0) but
358a8e1175bSopenharmony_ci * results in smaller code size.
359a8e1175bSopenharmony_ci *
360a8e1175bSopenharmony_ci * \param condition     Condition to test.
361a8e1175bSopenharmony_ci * \param if1           Value to use if \p condition == MBEDTLS_CT_TRUE.
362a8e1175bSopenharmony_ci *
363a8e1175bSopenharmony_ci * \return  \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
364a8e1175bSopenharmony_ci */
365a8e1175bSopenharmony_cistatic inline size_t mbedtls_ct_size_if_else_0(mbedtls_ct_condition_t condition, size_t if1);
366a8e1175bSopenharmony_ci
367a8e1175bSopenharmony_ci#if defined(MBEDTLS_BIGNUM_C)
368a8e1175bSopenharmony_ci
369a8e1175bSopenharmony_ci/** Choose between an mbedtls_mpi_uint value and 0.
370a8e1175bSopenharmony_ci *
371a8e1175bSopenharmony_ci * Functionally equivalent to:
372a8e1175bSopenharmony_ci *
373a8e1175bSopenharmony_ci * condition ? if1 : 0.
374a8e1175bSopenharmony_ci *
375a8e1175bSopenharmony_ci * Functionally equivalent to mbedtls_ct_mpi_uint_if(condition, if1, 0) but
376a8e1175bSopenharmony_ci * results in smaller code size.
377a8e1175bSopenharmony_ci *
378a8e1175bSopenharmony_ci * \param condition     Condition to test.
379a8e1175bSopenharmony_ci * \param if1           Value to use if \p condition == MBEDTLS_CT_TRUE.
380a8e1175bSopenharmony_ci *
381a8e1175bSopenharmony_ci * \return  \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
382a8e1175bSopenharmony_ci */
383a8e1175bSopenharmony_cistatic inline mbedtls_mpi_uint mbedtls_ct_mpi_uint_if_else_0(mbedtls_ct_condition_t condition,
384a8e1175bSopenharmony_ci                                                             mbedtls_mpi_uint if1);
385a8e1175bSopenharmony_ci
386a8e1175bSopenharmony_ci#endif
387a8e1175bSopenharmony_ci
388a8e1175bSopenharmony_ci/** Constant-flow char selection
389a8e1175bSopenharmony_ci *
390a8e1175bSopenharmony_ci * \param low   Secret. Bottom of range
391a8e1175bSopenharmony_ci * \param high  Secret. Top of range
392a8e1175bSopenharmony_ci * \param c     Secret. Value to compare to range
393a8e1175bSopenharmony_ci * \param t     Secret. Value to return, if in range
394a8e1175bSopenharmony_ci *
395a8e1175bSopenharmony_ci * \return      \p t if \p low <= \p c <= \p high, 0 otherwise.
396a8e1175bSopenharmony_ci */
397a8e1175bSopenharmony_cistatic inline unsigned char mbedtls_ct_uchar_in_range_if(unsigned char low,
398a8e1175bSopenharmony_ci                                                         unsigned char high,
399a8e1175bSopenharmony_ci                                                         unsigned char c,
400a8e1175bSopenharmony_ci                                                         unsigned char t);
401a8e1175bSopenharmony_ci
402a8e1175bSopenharmony_ci/** Choose between two error values. The values must be in the range [-32767..0].
403a8e1175bSopenharmony_ci *
404a8e1175bSopenharmony_ci * Functionally equivalent to:
405a8e1175bSopenharmony_ci *
406a8e1175bSopenharmony_ci * condition ? if1 : if0.
407a8e1175bSopenharmony_ci *
408a8e1175bSopenharmony_ci * \param condition     Condition to test.
409a8e1175bSopenharmony_ci * \param if1           Value to use if \p condition == MBEDTLS_CT_TRUE.
410a8e1175bSopenharmony_ci * \param if0           Value to use if \p condition == MBEDTLS_CT_FALSE.
411a8e1175bSopenharmony_ci *
412a8e1175bSopenharmony_ci * \return  \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise \c if0.
413a8e1175bSopenharmony_ci */
414a8e1175bSopenharmony_cistatic inline int mbedtls_ct_error_if(mbedtls_ct_condition_t condition, int if1, int if0);
415a8e1175bSopenharmony_ci
416a8e1175bSopenharmony_ci/** Choose between an error value and 0. The error value must be in the range [-32767..0].
417a8e1175bSopenharmony_ci *
418a8e1175bSopenharmony_ci * Functionally equivalent to:
419a8e1175bSopenharmony_ci *
420a8e1175bSopenharmony_ci * condition ? if1 : 0.
421a8e1175bSopenharmony_ci *
422a8e1175bSopenharmony_ci * Functionally equivalent to mbedtls_ct_error_if(condition, if1, 0) but
423a8e1175bSopenharmony_ci * results in smaller code size.
424a8e1175bSopenharmony_ci *
425a8e1175bSopenharmony_ci * \param condition     Condition to test.
426a8e1175bSopenharmony_ci * \param if1           Value to use if \p condition == MBEDTLS_CT_TRUE.
427a8e1175bSopenharmony_ci *
428a8e1175bSopenharmony_ci * \return  \c if1 if \p condition == MBEDTLS_CT_TRUE, otherwise 0.
429a8e1175bSopenharmony_ci */
430a8e1175bSopenharmony_cistatic inline int mbedtls_ct_error_if_else_0(mbedtls_ct_condition_t condition, int if1);
431a8e1175bSopenharmony_ci
432a8e1175bSopenharmony_ci/* ============================================================================
433a8e1175bSopenharmony_ci * Block memory operations
434a8e1175bSopenharmony_ci */
435a8e1175bSopenharmony_ci
436a8e1175bSopenharmony_ci#if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
437a8e1175bSopenharmony_ci
438a8e1175bSopenharmony_ci/** Conditionally set a block of memory to zero.
439a8e1175bSopenharmony_ci *
440a8e1175bSopenharmony_ci * Regardless of the condition, every byte will be read once and written to
441a8e1175bSopenharmony_ci * once.
442a8e1175bSopenharmony_ci *
443a8e1175bSopenharmony_ci * \param condition     Secret. Condition to test.
444a8e1175bSopenharmony_ci * \param buf           Secret. Pointer to the start of the buffer.
445a8e1175bSopenharmony_ci * \param len           Number of bytes to set to zero.
446a8e1175bSopenharmony_ci *
447a8e1175bSopenharmony_ci * \warning Unlike mbedtls_platform_zeroize, this does not have the same guarantees
448a8e1175bSopenharmony_ci * about not being optimised away if the memory is never read again.
449a8e1175bSopenharmony_ci */
450a8e1175bSopenharmony_civoid mbedtls_ct_zeroize_if(mbedtls_ct_condition_t condition, void *buf, size_t len);
451a8e1175bSopenharmony_ci
452a8e1175bSopenharmony_ci/** Shift some data towards the left inside a buffer.
453a8e1175bSopenharmony_ci *
454a8e1175bSopenharmony_ci * Functionally equivalent to:
455a8e1175bSopenharmony_ci *
456a8e1175bSopenharmony_ci * memmove(start, start + offset, total - offset);
457a8e1175bSopenharmony_ci * memset(start + (total - offset), 0, offset);
458a8e1175bSopenharmony_ci *
459a8e1175bSopenharmony_ci * Timing independence comes at the expense of performance.
460a8e1175bSopenharmony_ci *
461a8e1175bSopenharmony_ci * \param start     Secret. Pointer to the start of the buffer.
462a8e1175bSopenharmony_ci * \param total     Total size of the buffer.
463a8e1175bSopenharmony_ci * \param offset    Secret. Offset from which to copy \p total - \p offset bytes.
464a8e1175bSopenharmony_ci */
465a8e1175bSopenharmony_civoid mbedtls_ct_memmove_left(void *start,
466a8e1175bSopenharmony_ci                             size_t total,
467a8e1175bSopenharmony_ci                             size_t offset);
468a8e1175bSopenharmony_ci
469a8e1175bSopenharmony_ci#endif /* defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT) */
470a8e1175bSopenharmony_ci
471a8e1175bSopenharmony_ci/** Conditional memcpy.
472a8e1175bSopenharmony_ci *
473a8e1175bSopenharmony_ci * Functionally equivalent to:
474a8e1175bSopenharmony_ci *
475a8e1175bSopenharmony_ci * if (condition) {
476a8e1175bSopenharmony_ci *      memcpy(dest, src1, len);
477a8e1175bSopenharmony_ci * } else {
478a8e1175bSopenharmony_ci *      if (src2 != NULL)
479a8e1175bSopenharmony_ci *          memcpy(dest, src2, len);
480a8e1175bSopenharmony_ci * }
481a8e1175bSopenharmony_ci *
482a8e1175bSopenharmony_ci * It will always read len bytes from src1.
483a8e1175bSopenharmony_ci * If src2 != NULL, it will always read len bytes from src2.
484a8e1175bSopenharmony_ci * If src2 == NULL, it will instead read len bytes from dest (as if src2 == dest).
485a8e1175bSopenharmony_ci *
486a8e1175bSopenharmony_ci * \param condition The condition
487a8e1175bSopenharmony_ci * \param dest      Secret. Destination pointer.
488a8e1175bSopenharmony_ci * \param src1      Secret. Pointer to copy from (if \p condition == MBEDTLS_CT_TRUE).
489a8e1175bSopenharmony_ci *                  This may be equal to \p dest, but may not overlap in other ways.
490a8e1175bSopenharmony_ci * \param src2      Secret (contents only - may branch to determine if this parameter is NULL).
491a8e1175bSopenharmony_ci *                  Pointer to copy from (if \p condition == MBEDTLS_CT_FALSE and \p src2 is not NULL). May be NULL.
492a8e1175bSopenharmony_ci *                  This may be equal to \p dest, but may not overlap it in other ways. It may overlap with \p src1.
493a8e1175bSopenharmony_ci * \param len       Number of bytes to copy.
494a8e1175bSopenharmony_ci */
495a8e1175bSopenharmony_civoid mbedtls_ct_memcpy_if(mbedtls_ct_condition_t condition,
496a8e1175bSopenharmony_ci                          unsigned char *dest,
497a8e1175bSopenharmony_ci                          const unsigned char *src1,
498a8e1175bSopenharmony_ci                          const unsigned char *src2,
499a8e1175bSopenharmony_ci                          size_t len
500a8e1175bSopenharmony_ci                          );
501a8e1175bSopenharmony_ci
502a8e1175bSopenharmony_ci/** Copy data from a secret position.
503a8e1175bSopenharmony_ci *
504a8e1175bSopenharmony_ci * Functionally equivalent to:
505a8e1175bSopenharmony_ci *
506a8e1175bSopenharmony_ci * memcpy(dst, src + offset, len)
507a8e1175bSopenharmony_ci *
508a8e1175bSopenharmony_ci * This function copies \p len bytes from \p src + \p offset to
509a8e1175bSopenharmony_ci * \p dst, with a code flow and memory access pattern that does not depend on
510a8e1175bSopenharmony_ci * \p offset, but only on \p offset_min, \p offset_max and \p len.
511a8e1175bSopenharmony_ci *
512a8e1175bSopenharmony_ci * \note                This function reads from \p dest, but the value that
513a8e1175bSopenharmony_ci *                      is read does not influence the result and this
514a8e1175bSopenharmony_ci *                      function's behavior is well-defined regardless of the
515a8e1175bSopenharmony_ci *                      contents of the buffers. This may result in false
516a8e1175bSopenharmony_ci *                      positives from static or dynamic analyzers, especially
517a8e1175bSopenharmony_ci *                      if \p dest is not initialized.
518a8e1175bSopenharmony_ci *
519a8e1175bSopenharmony_ci * \param dest          Secret. The destination buffer. This must point to a writable
520a8e1175bSopenharmony_ci *                      buffer of at least \p len bytes.
521a8e1175bSopenharmony_ci * \param src           Secret. The base of the source buffer. This must point to a
522a8e1175bSopenharmony_ci *                      readable buffer of at least \p offset_max + \p len
523a8e1175bSopenharmony_ci *                      bytes. Shouldn't overlap with \p dest
524a8e1175bSopenharmony_ci * \param offset        Secret. The offset in the source buffer from which to copy.
525a8e1175bSopenharmony_ci *                      This must be no less than \p offset_min and no greater
526a8e1175bSopenharmony_ci *                      than \p offset_max.
527a8e1175bSopenharmony_ci * \param offset_min    The minimal value of \p offset.
528a8e1175bSopenharmony_ci * \param offset_max    The maximal value of \p offset.
529a8e1175bSopenharmony_ci * \param len           The number of bytes to copy.
530a8e1175bSopenharmony_ci */
531a8e1175bSopenharmony_civoid mbedtls_ct_memcpy_offset(unsigned char *dest,
532a8e1175bSopenharmony_ci                              const unsigned char *src,
533a8e1175bSopenharmony_ci                              size_t offset,
534a8e1175bSopenharmony_ci                              size_t offset_min,
535a8e1175bSopenharmony_ci                              size_t offset_max,
536a8e1175bSopenharmony_ci                              size_t len);
537a8e1175bSopenharmony_ci
538a8e1175bSopenharmony_ci/* Documented in include/mbedtls/constant_time.h. a and b are secret.
539a8e1175bSopenharmony_ci
540a8e1175bSopenharmony_ci   int mbedtls_ct_memcmp(const void *a,
541a8e1175bSopenharmony_ci                         const void *b,
542a8e1175bSopenharmony_ci                         size_t n);
543a8e1175bSopenharmony_ci */
544a8e1175bSopenharmony_ci
545a8e1175bSopenharmony_ci#if defined(MBEDTLS_NIST_KW_C)
546a8e1175bSopenharmony_ci
547a8e1175bSopenharmony_ci/** Constant-time buffer comparison without branches.
548a8e1175bSopenharmony_ci *
549a8e1175bSopenharmony_ci * Similar to mbedtls_ct_memcmp, except that the result only depends on part of
550a8e1175bSopenharmony_ci * the input data - differences in the head or tail are ignored. Functionally equivalent to:
551a8e1175bSopenharmony_ci *
552a8e1175bSopenharmony_ci * memcmp(a + skip_head, b + skip_head, size - skip_head - skip_tail)
553a8e1175bSopenharmony_ci *
554a8e1175bSopenharmony_ci * Time taken depends on \p n, but not on \p skip_head or \p skip_tail .
555a8e1175bSopenharmony_ci *
556a8e1175bSopenharmony_ci * Behaviour is undefined if ( \p skip_head + \p skip_tail) > \p n.
557a8e1175bSopenharmony_ci *
558a8e1175bSopenharmony_ci * \param a         Secret. Pointer to the first buffer, containing at least \p n bytes. May not be NULL.
559a8e1175bSopenharmony_ci * \param b         Secret. Pointer to the second buffer, containing at least \p n bytes. May not be NULL.
560a8e1175bSopenharmony_ci * \param n         The number of bytes to examine (total size of the buffers).
561a8e1175bSopenharmony_ci * \param skip_head Secret. The number of bytes to treat as non-significant at the start of the buffer.
562a8e1175bSopenharmony_ci *                  These bytes will still be read.
563a8e1175bSopenharmony_ci * \param skip_tail Secret. The number of bytes to treat as non-significant at the end of the buffer.
564a8e1175bSopenharmony_ci *                  These bytes will still be read.
565a8e1175bSopenharmony_ci *
566a8e1175bSopenharmony_ci * \return          Zero if the contents of the two buffers are the same, otherwise non-zero.
567a8e1175bSopenharmony_ci */
568a8e1175bSopenharmony_ciint mbedtls_ct_memcmp_partial(const void *a,
569a8e1175bSopenharmony_ci                              const void *b,
570a8e1175bSopenharmony_ci                              size_t n,
571a8e1175bSopenharmony_ci                              size_t skip_head,
572a8e1175bSopenharmony_ci                              size_t skip_tail);
573a8e1175bSopenharmony_ci
574a8e1175bSopenharmony_ci#endif
575a8e1175bSopenharmony_ci
576a8e1175bSopenharmony_ci/* Include the implementation of static inline functions above. */
577a8e1175bSopenharmony_ci#include "constant_time_impl.h"
578a8e1175bSopenharmony_ci
579a8e1175bSopenharmony_ci#endif /* MBEDTLS_CONSTANT_TIME_INTERNAL_H */
580