• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  *  Constant-time functions
3  *
4  *  Copyright The Mbed TLS Contributors
5  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6  */
7 
8 #ifndef MBEDTLS_CONSTANT_TIME_INTERNAL_H
9 #define MBEDTLS_CONSTANT_TIME_INTERNAL_H
10 
11 #include "common.h"
12 
13 #if defined(MBEDTLS_BIGNUM_C)
14 #include "mbedtls/bignum.h"
15 #endif
16 
17 #if defined(MBEDTLS_SSL_TLS_C)
18 #include "mbedtls/ssl_internal.h"
19 #endif
20 
21 #include <stddef.h>
22 
23 /** Turn a value into a mask:
24  * - if \p value == 0, return the all-bits 0 mask, aka 0
25  * - otherwise, return the all-bits 1 mask, aka (unsigned) -1
26  *
27  * This function can be used to write constant-time code by replacing branches
28  * with bit operations using masks.
29  *
30  * \param value     The value to analyze.
31  *
32  * \return          Zero if \p value is zero, otherwise all-bits-one.
33  */
34 unsigned mbedtls_ct_uint_mask(unsigned value);
35 
36 #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) || defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC) || \
37     defined(MBEDTLS_NIST_KW_C) || defined(MBEDTLS_CIPHER_MODE_CBC)
38 
39 /** Turn a value into a mask:
40  * - if \p value == 0, return the all-bits 0 mask, aka 0
41  * - otherwise, return the all-bits 1 mask, aka (size_t) -1
42  *
43  * This function can be used to write constant-time code by replacing branches
44  * with bit operations using masks.
45  *
46  * \param value     The value to analyze.
47  *
48  * \return          Zero if \p value is zero, otherwise all-bits-one.
49  */
50 size_t mbedtls_ct_size_mask(size_t value);
51 
52 #endif /* defined(MBEDTLS_SSL_SOME_MODES_USE_MAC) || defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC) ||
53           defined(MBEDTLS_NIST_KW_C) || defined(MBEDTLS_CIPHER_MODE_CBC) */
54 
55 #if defined(MBEDTLS_BIGNUM_C)
56 
57 /** Turn a value into a mask:
58  * - if \p value == 0, return the all-bits 0 mask, aka 0
59  * - otherwise, return the all-bits 1 mask, aka (mbedtls_mpi_uint) -1
60  *
61  * This function can be used to write constant-time code by replacing branches
62  * with bit operations using masks.
63  *
64  * \param value     The value to analyze.
65  *
66  * \return          Zero if \p value is zero, otherwise all-bits-one.
67  */
68 mbedtls_mpi_uint mbedtls_ct_mpi_uint_mask(mbedtls_mpi_uint value);
69 
70 #endif /* MBEDTLS_BIGNUM_C */
71 
72 #if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC) || defined(MBEDTLS_NIST_KW_C) || \
73     defined(MBEDTLS_CIPHER_MODE_CBC)
74 
75 /** Constant-flow mask generation for "greater or equal" comparison:
76  * - if \p x >= \p y, return all-bits 1, that is (size_t) -1
77  * - otherwise, return all bits 0, that is 0
78  *
79  * This function can be used to write constant-time code by replacing branches
80  * with bit operations using masks.
81  *
82  * \param x     The first value to analyze.
83  * \param y     The second value to analyze.
84  *
85  * \return      All-bits-one if \p x is greater or equal than \p y,
86  *              otherwise zero.
87  */
88 size_t mbedtls_ct_size_mask_ge(size_t x,
89                                size_t y);
90 
91 #endif /* defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC) || defined(MBEDTLS_NIST_KW_C) ||
92           defined(MBEDTLS_CIPHER_MODE_CBC) */
93 
94 /** Constant-flow boolean "equal" comparison:
95  * return x == y
96  *
97  * This is equivalent to \p x == \p y, but is likely to be compiled
98  * to code using bitwise operation rather than a branch.
99  *
100  * \param x     The first value to analyze.
101  * \param y     The second value to analyze.
102  *
103  * \return      1 if \p x equals to \p y, otherwise 0.
104  */
105 unsigned mbedtls_ct_size_bool_eq(size_t x,
106                                  size_t y);
107 
108 #if defined(MBEDTLS_BIGNUM_C)
109 
110 /** Decide if an integer is less than the other, without branches.
111  *
112  * This is equivalent to \p x < \p y, but is likely to be compiled
113  * to code using bitwise operation rather than a branch.
114  *
115  * \param x     The first value to analyze.
116  * \param y     The second value to analyze.
117  *
118  * \return      1 if \p x is less than \p y, otherwise 0.
119  */
120 unsigned mbedtls_ct_mpi_uint_lt(const mbedtls_mpi_uint x,
121                                 const mbedtls_mpi_uint y);
122 
123 #endif /* MBEDTLS_BIGNUM_C */
124 
125 /** Choose between two integer values without branches.
126  *
127  * This is equivalent to `condition ? if1 : if0`, but is likely to be compiled
128  * to code using bitwise operation rather than a branch.
129  *
130  * \param condition     Condition to test.
131  * \param if1           Value to use if \p condition is nonzero.
132  * \param if0           Value to use if \p condition is zero.
133  *
134  * \return  \c if1 if \p condition is nonzero, otherwise \c if0.
135  */
136 unsigned mbedtls_ct_uint_if(unsigned condition,
137                             unsigned if1,
138                             unsigned if0);
139 
140 #if defined(MBEDTLS_BIGNUM_C)
141 
142 /** Conditionally assign a value without branches.
143  *
144  * This is equivalent to `if ( condition ) dest = src`, but is likely
145  * to be compiled to code using bitwise operation rather than a branch.
146  *
147  * \param n             \p dest and \p src must be arrays of limbs of size n.
148  * \param dest          The MPI to conditionally assign to. This must point
149  *                      to an initialized MPI.
150  * \param src           The MPI to be assigned from. This must point to an
151  *                      initialized MPI.
152  * \param condition     Condition to test, must be 0 or 1.
153  */
154 void mbedtls_ct_mpi_uint_cond_assign(size_t n,
155                                      mbedtls_mpi_uint *dest,
156                                      const mbedtls_mpi_uint *src,
157                                      unsigned char condition);
158 
159 #endif /* MBEDTLS_BIGNUM_C */
160 
161 #if defined(MBEDTLS_BASE64_C)
162 
163 /** Given a value in the range 0..63, return the corresponding Base64 digit.
164  *
165  * The implementation assumes that letters are consecutive (e.g. ASCII
166  * but not EBCDIC).
167  *
168  * \param value     A value in the range 0..63.
169  *
170  * \return          A base64 digit converted from \p value.
171  */
172 unsigned char mbedtls_ct_base64_enc_char(unsigned char value);
173 
174 /** Given a Base64 digit, return its value.
175  *
176  * If c is not a Base64 digit ('A'..'Z', 'a'..'z', '0'..'9', '+' or '/'),
177  * return -1.
178  *
179  * The implementation assumes that letters are consecutive (e.g. ASCII
180  * but not EBCDIC).
181  *
182  * \param c     A base64 digit.
183  *
184  * \return      The value of the base64 digit \p c.
185  */
186 signed char mbedtls_ct_base64_dec_value(unsigned char c);
187 
188 #endif /* MBEDTLS_BASE64_C */
189 
190 #if defined(MBEDTLS_SSL_SOME_MODES_USE_MAC)
191 
192 /** Conditional memcpy without branches.
193  *
194  * This is equivalent to `if ( c1 == c2 ) memcpy(dest, src, len)`, but is likely
195  * to be compiled to code using bitwise operation rather than a branch.
196  *
197  * \param dest      The pointer to conditionally copy to.
198  * \param src       The pointer to copy from. Shouldn't overlap with \p dest.
199  * \param len       The number of bytes to copy.
200  * \param c1        The first value to analyze in the condition.
201  * \param c2        The second value to analyze in the condition.
202  */
203 void mbedtls_ct_memcpy_if_eq(unsigned char *dest,
204                              const unsigned char *src,
205                              size_t len,
206                              size_t c1, size_t c2);
207 
208 /** Copy data from a secret position with constant flow.
209  *
210  * This function copies \p len bytes from \p src_base + \p offset_secret to \p
211  * dst, with a code flow and memory access pattern that does not depend on \p
212  * offset_secret, but only on \p offset_min, \p offset_max and \p len.
213  * Functionally equivalent to `memcpy(dst, src + offset_secret, len)`.
214  *
215  * \note                This function reads from \p dest, but the value that
216  *                      is read does not influence the result and this
217  *                      function's behavior is well-defined regardless of the
218  *                      contents of the buffers. This may result in false
219  *                      positives from static or dynamic analyzers, especially
220  *                      if \p dest is not initialized.
221  *
222  * \param dest          The destination buffer. This must point to a writable
223  *                      buffer of at least \p len bytes.
224  * \param src           The base of the source buffer. This must point to a
225  *                      readable buffer of at least \p offset_max + \p len
226  *                      bytes. Shouldn't overlap with \p dest.
227  * \param offset        The offset in the source buffer from which to copy.
228  *                      This must be no less than \p offset_min and no greater
229  *                      than \p offset_max.
230  * \param offset_min    The minimal value of \p offset.
231  * \param offset_max    The maximal value of \p offset.
232  * \param len           The number of bytes to copy.
233  */
234 void mbedtls_ct_memcpy_offset(unsigned char *dest,
235                               const unsigned char *src,
236                               size_t offset,
237                               size_t offset_min,
238                               size_t offset_max,
239                               size_t len);
240 
241 /** Compute the HMAC of variable-length data with constant flow.
242  *
243  * This function computes the HMAC of the concatenation of \p add_data and \p
244  * data, and does with a code flow and memory access pattern that does not
245  * depend on \p data_len_secret, but only on \p min_data_len and \p
246  * max_data_len. In particular, this function always reads exactly \p
247  * max_data_len bytes from \p data.
248  *
249  * \param ctx               The HMAC context. It must have keys configured
250  *                          with mbedtls_md_hmac_starts() and use one of the
251  *                          following hashes: SHA-384, SHA-256, SHA-1 or MD-5.
252  *                          It is reset using mbedtls_md_hmac_reset() after
253  *                          the computation is complete to prepare for the
254  *                          next computation.
255  * \param add_data          The first part of the message whose HMAC is being
256  *                          calculated. This must point to a readable buffer
257  *                          of \p add_data_len bytes.
258  * \param add_data_len      The length of \p add_data in bytes.
259  * \param data              The buffer containing the second part of the
260  *                          message. This must point to a readable buffer
261  *                          of \p max_data_len bytes.
262  * \param data_len_secret   The length of the data to process in \p data.
263  *                          This must be no less than \p min_data_len and no
264  *                          greater than \p max_data_len.
265  * \param min_data_len      The minimal length of the second part of the
266  *                          message, read from \p data.
267  * \param max_data_len      The maximal length of the second part of the
268  *                          message, read from \p data.
269  * \param output            The HMAC will be written here. This must point to
270  *                          a writable buffer of sufficient size to hold the
271  *                          HMAC value.
272  *
273  * \retval 0 on success.
274  * \retval #MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED
275  *         The hardware accelerator failed.
276  */
277 int mbedtls_ct_hmac(mbedtls_md_context_t *ctx,
278                     const unsigned char *add_data,
279                     size_t add_data_len,
280                     const unsigned char *data,
281                     size_t data_len_secret,
282                     size_t min_data_len,
283                     size_t max_data_len,
284                     unsigned char *output);
285 
286 #endif /* MBEDTLS_SSL_SOME_MODES_USE_MAC */
287 
288 #if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
289 
290 /** This function performs the unpadding part of a PKCS#1 v1.5 decryption
291  *  operation (EME-PKCS1-v1_5 decoding).
292  *
293  * \note The return value from this function is a sensitive value
294  *       (this is unusual). #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE shouldn't happen
295  *       in a well-written application, but 0 vs #MBEDTLS_ERR_RSA_INVALID_PADDING
296  *       is often a situation that an attacker can provoke and leaking which
297  *       one is the result is precisely the information the attacker wants.
298  *
299  * \param mode           The mode of operation. This must be either
300  *                       #MBEDTLS_RSA_PRIVATE or #MBEDTLS_RSA_PUBLIC (deprecated).
301  * \param input          The input buffer which is the payload inside PKCS#1v1.5
302  *                       encryption padding, called the "encoded message EM"
303  *                       by the terminology.
304  * \param ilen           The length of the payload in the \p input buffer.
305  * \param output         The buffer for the payload, called "message M" by the
306  *                       PKCS#1 terminology. This must be a writable buffer of
307  *                       length \p output_max_len bytes.
308  * \param olen           The address at which to store the length of
309  *                       the payload. This must not be \c NULL.
310  * \param output_max_len The length in bytes of the output buffer \p output.
311  *
312  * \return      \c 0 on success.
313  * \return      #MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE
314  *              The output buffer is too small for the unpadded payload.
315  * \return      #MBEDTLS_ERR_RSA_INVALID_PADDING
316  *              The input doesn't contain properly formatted padding.
317  */
318 int mbedtls_ct_rsaes_pkcs1_v15_unpadding(int mode,
319                                          unsigned char *input,
320                                          size_t ilen,
321                                          unsigned char *output,
322                                          size_t output_max_len,
323                                          size_t *olen);
324 
325 #endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
326 
327 #endif /* MBEDTLS_CONSTANT_TIME_INTERNAL_H */
328