xref: /optee_os/lib/libmbedtls/mbedtls/library/constant_time.c (revision 32b3180828fa15a49ccc86ecb4be9d274c140c89)
1039e02dfSJerome Forissier /**
2039e02dfSJerome Forissier  *  Constant-time functions
3039e02dfSJerome Forissier  *
4039e02dfSJerome Forissier  *  Copyright The Mbed TLS Contributors
5039e02dfSJerome Forissier  *  SPDX-License-Identifier: Apache-2.0
6039e02dfSJerome Forissier  *
7039e02dfSJerome Forissier  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
8039e02dfSJerome Forissier  *  not use this file except in compliance with the License.
9039e02dfSJerome Forissier  *  You may obtain a copy of the License at
10039e02dfSJerome Forissier  *
11039e02dfSJerome Forissier  *  http://www.apache.org/licenses/LICENSE-2.0
12039e02dfSJerome Forissier  *
13039e02dfSJerome Forissier  *  Unless required by applicable law or agreed to in writing, software
14039e02dfSJerome Forissier  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15039e02dfSJerome Forissier  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16039e02dfSJerome Forissier  *  See the License for the specific language governing permissions and
17039e02dfSJerome Forissier  *  limitations under the License.
18039e02dfSJerome Forissier  */
19039e02dfSJerome Forissier 
20039e02dfSJerome Forissier /*
21039e02dfSJerome Forissier  * The following functions are implemented without using comparison operators, as those
22039e02dfSJerome Forissier  * might be translated to branches by some compilers on some platforms.
23039e02dfSJerome Forissier  */
24039e02dfSJerome Forissier 
25039e02dfSJerome Forissier #include "common.h"
26039e02dfSJerome Forissier #include "constant_time_internal.h"
27039e02dfSJerome Forissier #include "mbedtls/constant_time.h"
28039e02dfSJerome Forissier #include "mbedtls/error.h"
29039e02dfSJerome Forissier #include "mbedtls/platform_util.h"
30039e02dfSJerome Forissier 
31039e02dfSJerome Forissier #if defined(MBEDTLS_BIGNUM_C)
32039e02dfSJerome Forissier #include "mbedtls/bignum.h"
33*32b31808SJens Wiklander #include "bignum_core.h"
34039e02dfSJerome Forissier #endif
35039e02dfSJerome Forissier 
36039e02dfSJerome Forissier #if defined(MBEDTLS_SSL_TLS_C)
37*32b31808SJens Wiklander #include "ssl_misc.h"
38039e02dfSJerome Forissier #endif
39039e02dfSJerome Forissier 
40039e02dfSJerome Forissier #if defined(MBEDTLS_RSA_C)
41039e02dfSJerome Forissier #include "mbedtls/rsa.h"
42039e02dfSJerome Forissier #endif
43039e02dfSJerome Forissier 
44039e02dfSJerome Forissier #if defined(MBEDTLS_BASE64_C)
45039e02dfSJerome Forissier #include "constant_time_invasive.h"
46039e02dfSJerome Forissier #endif
47039e02dfSJerome Forissier 
48039e02dfSJerome Forissier #include <string.h>
49*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
50*32b31808SJens Wiklander #define PSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status,    \
51*32b31808SJens Wiklander                                                            psa_to_ssl_errors,              \
52*32b31808SJens Wiklander                                                            psa_generic_status_to_mbedtls)
53*32b31808SJens Wiklander #endif
54*32b31808SJens Wiklander 
55*32b31808SJens Wiklander /*
56*32b31808SJens Wiklander  * Define MBEDTLS_EFFICIENT_UNALIGNED_VOLATILE_ACCESS where assembly is present to
57*32b31808SJens Wiklander  * perform fast unaligned access to volatile data.
58*32b31808SJens Wiklander  *
59*32b31808SJens Wiklander  * This is needed because mbedtls_get_unaligned_uintXX etc don't support volatile
60*32b31808SJens Wiklander  * memory accesses.
61*32b31808SJens Wiklander  *
62*32b31808SJens Wiklander  * Some of these definitions could be moved into alignment.h but for now they are
63*32b31808SJens Wiklander  * only used here.
64*32b31808SJens Wiklander  */
65*32b31808SJens Wiklander #if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS) && defined(MBEDTLS_HAVE_ASM)
66*32b31808SJens Wiklander #if defined(__arm__) || defined(__thumb__) || defined(__thumb2__) || defined(__aarch64__)
67*32b31808SJens Wiklander #define MBEDTLS_EFFICIENT_UNALIGNED_VOLATILE_ACCESS
68*32b31808SJens Wiklander #endif
69*32b31808SJens Wiklander #endif
70*32b31808SJens Wiklander 
71*32b31808SJens Wiklander #if defined(MBEDTLS_EFFICIENT_UNALIGNED_VOLATILE_ACCESS)
72*32b31808SJens Wiklander static inline uint32_t mbedtls_get_unaligned_volatile_uint32(volatile const unsigned char *p)
73*32b31808SJens Wiklander {
74*32b31808SJens Wiklander     /* This is UB, even where it's safe:
75*32b31808SJens Wiklander      *    return *((volatile uint32_t*)p);
76*32b31808SJens Wiklander      * so instead the same thing is expressed in assembly below.
77*32b31808SJens Wiklander      */
78*32b31808SJens Wiklander     uint32_t r;
79*32b31808SJens Wiklander #if defined(__arm__) || defined(__thumb__) || defined(__thumb2__)
80*32b31808SJens Wiklander     asm volatile ("ldr %0, [%1]" : "=r" (r) : "r" (p) :);
81*32b31808SJens Wiklander #elif defined(__aarch64__)
82*32b31808SJens Wiklander     asm volatile ("ldr %w0, [%1]" : "=r" (r) : "r" (p) :);
83*32b31808SJens Wiklander #endif
84*32b31808SJens Wiklander     return r;
85*32b31808SJens Wiklander }
86*32b31808SJens Wiklander #endif /* MBEDTLS_EFFICIENT_UNALIGNED_VOLATILE_ACCESS */
87039e02dfSJerome Forissier 
88039e02dfSJerome Forissier int mbedtls_ct_memcmp(const void *a,
89039e02dfSJerome Forissier                       const void *b,
90039e02dfSJerome Forissier                       size_t n)
91039e02dfSJerome Forissier {
92*32b31808SJens Wiklander     size_t i = 0;
93*32b31808SJens Wiklander     /*
94*32b31808SJens Wiklander      * `A` and `B` are cast to volatile to ensure that the compiler
95*32b31808SJens Wiklander      * generates code that always fully reads both buffers.
96*32b31808SJens Wiklander      * Otherwise it could generate a test to exit early if `diff` has all
97*32b31808SJens Wiklander      * bits set early in the loop.
98*32b31808SJens Wiklander      */
99039e02dfSJerome Forissier     volatile const unsigned char *A = (volatile const unsigned char *) a;
100039e02dfSJerome Forissier     volatile const unsigned char *B = (volatile const unsigned char *) b;
101*32b31808SJens Wiklander     uint32_t diff = 0;
102039e02dfSJerome Forissier 
103*32b31808SJens Wiklander #if defined(MBEDTLS_EFFICIENT_UNALIGNED_VOLATILE_ACCESS)
104*32b31808SJens Wiklander     for (; (i + 4) <= n; i += 4) {
105*32b31808SJens Wiklander         uint32_t x = mbedtls_get_unaligned_volatile_uint32(A + i);
106*32b31808SJens Wiklander         uint32_t y = mbedtls_get_unaligned_volatile_uint32(B + i);
107*32b31808SJens Wiklander         diff |= x ^ y;
108*32b31808SJens Wiklander     }
109*32b31808SJens Wiklander #endif
110*32b31808SJens Wiklander 
111*32b31808SJens Wiklander     for (; i < n; i++) {
112039e02dfSJerome Forissier         /* Read volatile data in order before computing diff.
113039e02dfSJerome Forissier          * This avoids IAR compiler warning:
114039e02dfSJerome Forissier          * 'the order of volatile accesses is undefined ..' */
115039e02dfSJerome Forissier         unsigned char x = A[i], y = B[i];
116039e02dfSJerome Forissier         diff |= x ^ y;
117039e02dfSJerome Forissier     }
118039e02dfSJerome Forissier 
119*32b31808SJens Wiklander     return (int) diff;
120039e02dfSJerome Forissier }
121039e02dfSJerome Forissier 
122039e02dfSJerome Forissier unsigned mbedtls_ct_uint_mask(unsigned value)
123039e02dfSJerome Forissier {
124039e02dfSJerome Forissier     /* MSVC has a warning about unary minus on unsigned, but this is
125039e02dfSJerome Forissier      * well-defined and precisely what we want to do here */
126039e02dfSJerome Forissier #if defined(_MSC_VER)
127039e02dfSJerome Forissier #pragma warning( push )
128039e02dfSJerome Forissier #pragma warning( disable : 4146 )
129039e02dfSJerome Forissier #endif
130*32b31808SJens Wiklander     return -((value | -value) >> (sizeof(value) * 8 - 1));
131039e02dfSJerome Forissier #if defined(_MSC_VER)
132039e02dfSJerome Forissier #pragma warning( pop )
133039e02dfSJerome Forissier #endif
134039e02dfSJerome Forissier }
135039e02dfSJerome Forissier 
136*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
137039e02dfSJerome Forissier 
138039e02dfSJerome Forissier size_t mbedtls_ct_size_mask(size_t value)
139039e02dfSJerome Forissier {
140039e02dfSJerome Forissier     /* MSVC has a warning about unary minus on unsigned integer types,
141039e02dfSJerome Forissier      * but this is well-defined and precisely what we want to do here. */
142039e02dfSJerome Forissier #if defined(_MSC_VER)
143039e02dfSJerome Forissier #pragma warning( push )
144039e02dfSJerome Forissier #pragma warning( disable : 4146 )
145039e02dfSJerome Forissier #endif
146*32b31808SJens Wiklander     return -((value | -value) >> (sizeof(value) * 8 - 1));
147039e02dfSJerome Forissier #if defined(_MSC_VER)
148039e02dfSJerome Forissier #pragma warning( pop )
149039e02dfSJerome Forissier #endif
150039e02dfSJerome Forissier }
151039e02dfSJerome Forissier 
152*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
153039e02dfSJerome Forissier 
154039e02dfSJerome Forissier #if defined(MBEDTLS_BIGNUM_C)
155039e02dfSJerome Forissier 
156039e02dfSJerome Forissier mbedtls_mpi_uint mbedtls_ct_mpi_uint_mask(mbedtls_mpi_uint value)
157039e02dfSJerome Forissier {
158039e02dfSJerome Forissier     /* MSVC has a warning about unary minus on unsigned, but this is
159039e02dfSJerome Forissier      * well-defined and precisely what we want to do here */
160039e02dfSJerome Forissier #if defined(_MSC_VER)
161039e02dfSJerome Forissier #pragma warning( push )
162039e02dfSJerome Forissier #pragma warning( disable : 4146 )
163039e02dfSJerome Forissier #endif
164*32b31808SJens Wiklander     return -((value | -value) >> (sizeof(value) * 8 - 1));
165039e02dfSJerome Forissier #if defined(_MSC_VER)
166039e02dfSJerome Forissier #pragma warning( pop )
167039e02dfSJerome Forissier #endif
168039e02dfSJerome Forissier }
169039e02dfSJerome Forissier 
170039e02dfSJerome Forissier #endif /* MBEDTLS_BIGNUM_C */
171039e02dfSJerome Forissier 
172039e02dfSJerome Forissier #if defined(MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC)
173039e02dfSJerome Forissier 
174039e02dfSJerome Forissier /** Constant-flow mask generation for "less than" comparison:
175039e02dfSJerome Forissier  * - if \p x < \p y, return all-bits 1, that is (size_t) -1
176039e02dfSJerome Forissier  * - otherwise, return all bits 0, that is 0
177039e02dfSJerome Forissier  *
178039e02dfSJerome Forissier  * This function can be used to write constant-time code by replacing branches
179039e02dfSJerome Forissier  * with bit operations using masks.
180039e02dfSJerome Forissier  *
181039e02dfSJerome Forissier  * \param x     The first value to analyze.
182039e02dfSJerome Forissier  * \param y     The second value to analyze.
183039e02dfSJerome Forissier  *
184039e02dfSJerome Forissier  * \return      All-bits-one if \p x is less than \p y, otherwise zero.
185039e02dfSJerome Forissier  */
186039e02dfSJerome Forissier static size_t mbedtls_ct_size_mask_lt(size_t x,
187039e02dfSJerome Forissier                                       size_t y)
188039e02dfSJerome Forissier {
189039e02dfSJerome Forissier     /* This has the most significant bit set if and only if x < y */
190039e02dfSJerome Forissier     const size_t sub = x - y;
191039e02dfSJerome Forissier 
192039e02dfSJerome Forissier     /* sub1 = (x < y) ? 1 : 0 */
193039e02dfSJerome Forissier     const size_t sub1 = sub >> (sizeof(sub) * 8 - 1);
194039e02dfSJerome Forissier 
195039e02dfSJerome Forissier     /* mask = (x < y) ? 0xff... : 0x00... */
196039e02dfSJerome Forissier     const size_t mask = mbedtls_ct_size_mask(sub1);
197039e02dfSJerome Forissier 
198*32b31808SJens Wiklander     return mask;
199039e02dfSJerome Forissier }
200039e02dfSJerome Forissier 
201039e02dfSJerome Forissier size_t mbedtls_ct_size_mask_ge(size_t x,
202039e02dfSJerome Forissier                                size_t y)
203039e02dfSJerome Forissier {
204*32b31808SJens Wiklander     return ~mbedtls_ct_size_mask_lt(x, y);
205039e02dfSJerome Forissier }
206039e02dfSJerome Forissier 
207039e02dfSJerome Forissier #endif /* MBEDTLS_SSL_SOME_SUITES_USE_TLS_CBC */
208039e02dfSJerome Forissier 
209039e02dfSJerome Forissier #if defined(MBEDTLS_BASE64_C)
210039e02dfSJerome Forissier 
211039e02dfSJerome Forissier /* Return 0xff if low <= c <= high, 0 otherwise.
212039e02dfSJerome Forissier  *
213039e02dfSJerome Forissier  * Constant flow with respect to c.
214039e02dfSJerome Forissier  */
215039e02dfSJerome Forissier MBEDTLS_STATIC_TESTABLE
216039e02dfSJerome Forissier unsigned char mbedtls_ct_uchar_mask_of_range(unsigned char low,
217039e02dfSJerome Forissier                                              unsigned char high,
218039e02dfSJerome Forissier                                              unsigned char c)
219039e02dfSJerome Forissier {
220039e02dfSJerome Forissier     /* low_mask is: 0 if low <= c, 0x...ff if low > c */
221039e02dfSJerome Forissier     unsigned low_mask = ((unsigned) c - low) >> 8;
222039e02dfSJerome Forissier     /* high_mask is: 0 if c <= high, 0x...ff if c > high */
223039e02dfSJerome Forissier     unsigned high_mask = ((unsigned) high - c) >> 8;
224*32b31808SJens Wiklander     return ~(low_mask | high_mask) & 0xff;
225039e02dfSJerome Forissier }
226039e02dfSJerome Forissier 
227039e02dfSJerome Forissier #endif /* MBEDTLS_BASE64_C */
228039e02dfSJerome Forissier 
229039e02dfSJerome Forissier unsigned mbedtls_ct_size_bool_eq(size_t x,
230039e02dfSJerome Forissier                                  size_t y)
231039e02dfSJerome Forissier {
232039e02dfSJerome Forissier     /* diff = 0 if x == y, non-zero otherwise */
233039e02dfSJerome Forissier     const size_t diff = x ^ y;
234039e02dfSJerome Forissier 
235039e02dfSJerome Forissier     /* MSVC has a warning about unary minus on unsigned integer types,
236039e02dfSJerome Forissier      * but this is well-defined and precisely what we want to do here. */
237039e02dfSJerome Forissier #if defined(_MSC_VER)
238039e02dfSJerome Forissier #pragma warning( push )
239039e02dfSJerome Forissier #pragma warning( disable : 4146 )
240039e02dfSJerome Forissier #endif
241039e02dfSJerome Forissier 
242039e02dfSJerome Forissier     /* diff_msb's most significant bit is equal to x != y */
243039e02dfSJerome Forissier     const size_t diff_msb = (diff | (size_t) -diff);
244039e02dfSJerome Forissier 
245039e02dfSJerome Forissier #if defined(_MSC_VER)
246039e02dfSJerome Forissier #pragma warning( pop )
247039e02dfSJerome Forissier #endif
248039e02dfSJerome Forissier 
249039e02dfSJerome Forissier     /* diff1 = (x != y) ? 1 : 0 */
250039e02dfSJerome Forissier     const unsigned diff1 = diff_msb >> (sizeof(diff_msb) * 8 - 1);
251039e02dfSJerome Forissier 
252*32b31808SJens Wiklander     return 1 ^ diff1;
253039e02dfSJerome Forissier }
254039e02dfSJerome Forissier 
255039e02dfSJerome Forissier #if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
256039e02dfSJerome Forissier 
257039e02dfSJerome Forissier /** Constant-flow "greater than" comparison:
258039e02dfSJerome Forissier  * return x > y
259039e02dfSJerome Forissier  *
260039e02dfSJerome Forissier  * This is equivalent to \p x > \p y, but is likely to be compiled
261039e02dfSJerome Forissier  * to code using bitwise operation rather than a branch.
262039e02dfSJerome Forissier  *
263039e02dfSJerome Forissier  * \param x     The first value to analyze.
264039e02dfSJerome Forissier  * \param y     The second value to analyze.
265039e02dfSJerome Forissier  *
266039e02dfSJerome Forissier  * \return      1 if \p x greater than \p y, otherwise 0.
267039e02dfSJerome Forissier  */
268039e02dfSJerome Forissier static unsigned mbedtls_ct_size_gt(size_t x,
269039e02dfSJerome Forissier                                    size_t y)
270039e02dfSJerome Forissier {
271039e02dfSJerome Forissier     /* Return the sign bit (1 for negative) of (y - x). */
272*32b31808SJens Wiklander     return (y - x) >> (sizeof(size_t) * 8 - 1);
273039e02dfSJerome Forissier }
274039e02dfSJerome Forissier 
275039e02dfSJerome Forissier #endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
276039e02dfSJerome Forissier 
277039e02dfSJerome Forissier #if defined(MBEDTLS_BIGNUM_C)
278039e02dfSJerome Forissier 
279039e02dfSJerome Forissier unsigned mbedtls_ct_mpi_uint_lt(const mbedtls_mpi_uint x,
280039e02dfSJerome Forissier                                 const mbedtls_mpi_uint y)
281039e02dfSJerome Forissier {
282039e02dfSJerome Forissier     mbedtls_mpi_uint ret;
283039e02dfSJerome Forissier     mbedtls_mpi_uint cond;
284039e02dfSJerome Forissier 
285039e02dfSJerome Forissier     /*
286039e02dfSJerome Forissier      * Check if the most significant bits (MSB) of the operands are different.
287039e02dfSJerome Forissier      */
288039e02dfSJerome Forissier     cond = (x ^ y);
289039e02dfSJerome Forissier     /*
290039e02dfSJerome Forissier      * If the MSB are the same then the difference x-y will be negative (and
291039e02dfSJerome Forissier      * have its MSB set to 1 during conversion to unsigned) if and only if x<y.
292039e02dfSJerome Forissier      */
293039e02dfSJerome Forissier     ret = (x - y) & ~cond;
294039e02dfSJerome Forissier     /*
295039e02dfSJerome Forissier      * If the MSB are different, then the operand with the MSB of 1 is the
296039e02dfSJerome Forissier      * bigger. (That is if y has MSB of 1, then x<y is true and it is false if
297039e02dfSJerome Forissier      * the MSB of y is 0.)
298039e02dfSJerome Forissier      */
299039e02dfSJerome Forissier     ret |= y & cond;
300039e02dfSJerome Forissier 
301039e02dfSJerome Forissier 
302039e02dfSJerome Forissier     ret = ret >> (sizeof(mbedtls_mpi_uint) * 8 - 1);
303039e02dfSJerome Forissier 
304039e02dfSJerome Forissier     return (unsigned) ret;
305039e02dfSJerome Forissier }
306039e02dfSJerome Forissier 
307039e02dfSJerome Forissier #endif /* MBEDTLS_BIGNUM_C */
308039e02dfSJerome Forissier 
309039e02dfSJerome Forissier unsigned mbedtls_ct_uint_if(unsigned condition,
310039e02dfSJerome Forissier                             unsigned if1,
311039e02dfSJerome Forissier                             unsigned if0)
312039e02dfSJerome Forissier {
313039e02dfSJerome Forissier     unsigned mask = mbedtls_ct_uint_mask(condition);
314*32b31808SJens Wiklander     return (mask & if1) | (~mask & if0);
315039e02dfSJerome Forissier }
316039e02dfSJerome Forissier 
317039e02dfSJerome Forissier #if defined(MBEDTLS_BIGNUM_C)
318039e02dfSJerome Forissier 
319039e02dfSJerome Forissier /** Select between two sign values without branches.
320039e02dfSJerome Forissier  *
321039e02dfSJerome Forissier  * This is functionally equivalent to `condition ? if1 : if0` but uses only bit
322039e02dfSJerome Forissier  * operations in order to avoid branches.
323039e02dfSJerome Forissier  *
324039e02dfSJerome Forissier  * \note if1 and if0 must be either 1 or -1, otherwise the result
325039e02dfSJerome Forissier  *       is undefined.
326039e02dfSJerome Forissier  *
327*32b31808SJens Wiklander  * \param condition     Condition to test; must be either 0 or 1.
328039e02dfSJerome Forissier  * \param if1           The first sign; must be either +1 or -1.
329039e02dfSJerome Forissier  * \param if0           The second sign; must be either +1 or -1.
330039e02dfSJerome Forissier  *
331039e02dfSJerome Forissier  * \return  \c if1 if \p condition is nonzero, otherwise \c if0.
332039e02dfSJerome Forissier  * */
333039e02dfSJerome Forissier static int mbedtls_ct_cond_select_sign(unsigned char condition,
334039e02dfSJerome Forissier                                        int if1,
335039e02dfSJerome Forissier                                        int if0)
336039e02dfSJerome Forissier {
337039e02dfSJerome Forissier     /* In order to avoid questions about what we can reasonably assume about
338039e02dfSJerome Forissier      * the representations of signed integers, move everything to unsigned
339039e02dfSJerome Forissier      * by taking advantage of the fact that if1 and if0 are either +1 or -1. */
340039e02dfSJerome Forissier     unsigned uif1 = if1 + 1;
341039e02dfSJerome Forissier     unsigned uif0 = if0 + 1;
342039e02dfSJerome Forissier 
343039e02dfSJerome Forissier     /* condition was 0 or 1, mask is 0 or 2 as are uif1 and uif0 */
344039e02dfSJerome Forissier     const unsigned mask = condition << 1;
345039e02dfSJerome Forissier 
346039e02dfSJerome Forissier     /* select uif1 or uif0 */
347039e02dfSJerome Forissier     unsigned ur = (uif0 & ~mask) | (uif1 & mask);
348039e02dfSJerome Forissier 
349039e02dfSJerome Forissier     /* ur is now 0 or 2, convert back to -1 or +1 */
350*32b31808SJens Wiklander     return (int) ur - 1;
351039e02dfSJerome Forissier }
352039e02dfSJerome Forissier 
353039e02dfSJerome Forissier void mbedtls_ct_mpi_uint_cond_assign(size_t n,
354039e02dfSJerome Forissier                                      mbedtls_mpi_uint *dest,
355039e02dfSJerome Forissier                                      const mbedtls_mpi_uint *src,
356039e02dfSJerome Forissier                                      unsigned char condition)
357039e02dfSJerome Forissier {
358039e02dfSJerome Forissier     size_t i;
359039e02dfSJerome Forissier 
360039e02dfSJerome Forissier     /* MSVC has a warning about unary minus on unsigned integer types,
361039e02dfSJerome Forissier      * but this is well-defined and precisely what we want to do here. */
362039e02dfSJerome Forissier #if defined(_MSC_VER)
363039e02dfSJerome Forissier #pragma warning( push )
364039e02dfSJerome Forissier #pragma warning( disable : 4146 )
365039e02dfSJerome Forissier #endif
366039e02dfSJerome Forissier 
367039e02dfSJerome Forissier     /* all-bits 1 if condition is 1, all-bits 0 if condition is 0 */
368039e02dfSJerome Forissier     const mbedtls_mpi_uint mask = -condition;
369039e02dfSJerome Forissier 
370039e02dfSJerome Forissier #if defined(_MSC_VER)
371039e02dfSJerome Forissier #pragma warning( pop )
372039e02dfSJerome Forissier #endif
373039e02dfSJerome Forissier 
374*32b31808SJens Wiklander     for (i = 0; i < n; i++) {
375039e02dfSJerome Forissier         dest[i] = (src[i] & mask) | (dest[i] & ~mask);
376039e02dfSJerome Forissier     }
377*32b31808SJens Wiklander }
378039e02dfSJerome Forissier 
379039e02dfSJerome Forissier #endif /* MBEDTLS_BIGNUM_C */
380039e02dfSJerome Forissier 
381039e02dfSJerome Forissier #if defined(MBEDTLS_BASE64_C)
382039e02dfSJerome Forissier 
383039e02dfSJerome Forissier unsigned char mbedtls_ct_base64_enc_char(unsigned char value)
384039e02dfSJerome Forissier {
385039e02dfSJerome Forissier     unsigned char digit = 0;
386039e02dfSJerome Forissier     /* For each range of values, if value is in that range, mask digit with
387039e02dfSJerome Forissier      * the corresponding value. Since value can only be in a single range,
388039e02dfSJerome Forissier      * only at most one masking will change digit. */
389039e02dfSJerome Forissier     digit |= mbedtls_ct_uchar_mask_of_range(0, 25, value) & ('A' + value);
390039e02dfSJerome Forissier     digit |= mbedtls_ct_uchar_mask_of_range(26, 51, value) & ('a' + value - 26);
391039e02dfSJerome Forissier     digit |= mbedtls_ct_uchar_mask_of_range(52, 61, value) & ('0' + value - 52);
392039e02dfSJerome Forissier     digit |= mbedtls_ct_uchar_mask_of_range(62, 62, value) & '+';
393039e02dfSJerome Forissier     digit |= mbedtls_ct_uchar_mask_of_range(63, 63, value) & '/';
394*32b31808SJens Wiklander     return digit;
395039e02dfSJerome Forissier }
396039e02dfSJerome Forissier 
397039e02dfSJerome Forissier signed char mbedtls_ct_base64_dec_value(unsigned char c)
398039e02dfSJerome Forissier {
399039e02dfSJerome Forissier     unsigned char val = 0;
400039e02dfSJerome Forissier     /* For each range of digits, if c is in that range, mask val with
401039e02dfSJerome Forissier      * the corresponding value. Since c can only be in a single range,
402039e02dfSJerome Forissier      * only at most one masking will change val. Set val to one plus
403039e02dfSJerome Forissier      * the desired value so that it stays 0 if c is in none of the ranges. */
404039e02dfSJerome Forissier     val |= mbedtls_ct_uchar_mask_of_range('A', 'Z', c) & (c - 'A' +  0 + 1);
405039e02dfSJerome Forissier     val |= mbedtls_ct_uchar_mask_of_range('a', 'z', c) & (c - 'a' + 26 + 1);
406039e02dfSJerome Forissier     val |= mbedtls_ct_uchar_mask_of_range('0', '9', c) & (c - '0' + 52 + 1);
407039e02dfSJerome Forissier     val |= mbedtls_ct_uchar_mask_of_range('+', '+', c) & (c - '+' + 62 + 1);
408039e02dfSJerome Forissier     val |= mbedtls_ct_uchar_mask_of_range('/', '/', c) & (c - '/' + 63 + 1);
409039e02dfSJerome Forissier     /* At this point, val is 0 if c is an invalid digit and v+1 if c is
410039e02dfSJerome Forissier      * a digit with the value v. */
411*32b31808SJens Wiklander     return val - 1;
412039e02dfSJerome Forissier }
413039e02dfSJerome Forissier 
414039e02dfSJerome Forissier #endif /* MBEDTLS_BASE64_C */
415039e02dfSJerome Forissier 
416039e02dfSJerome Forissier #if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
417039e02dfSJerome Forissier 
418039e02dfSJerome Forissier /** Shift some data towards the left inside a buffer.
419039e02dfSJerome Forissier  *
420039e02dfSJerome Forissier  * `mbedtls_ct_mem_move_to_left(start, total, offset)` is functionally
421039e02dfSJerome Forissier  * equivalent to
422039e02dfSJerome Forissier  * ```
423039e02dfSJerome Forissier  * memmove(start, start + offset, total - offset);
424039e02dfSJerome Forissier  * memset(start + offset, 0, total - offset);
425039e02dfSJerome Forissier  * ```
426039e02dfSJerome Forissier  * but it strives to use a memory access pattern (and thus total timing)
427039e02dfSJerome Forissier  * that does not depend on \p offset. This timing independence comes at
428039e02dfSJerome Forissier  * the expense of performance.
429039e02dfSJerome Forissier  *
430039e02dfSJerome Forissier  * \param start     Pointer to the start of the buffer.
431039e02dfSJerome Forissier  * \param total     Total size of the buffer.
432039e02dfSJerome Forissier  * \param offset    Offset from which to copy \p total - \p offset bytes.
433039e02dfSJerome Forissier  */
434039e02dfSJerome Forissier static void mbedtls_ct_mem_move_to_left(void *start,
435039e02dfSJerome Forissier                                         size_t total,
436039e02dfSJerome Forissier                                         size_t offset)
437039e02dfSJerome Forissier {
438039e02dfSJerome Forissier     volatile unsigned char *buf = start;
439039e02dfSJerome Forissier     size_t i, n;
440*32b31808SJens Wiklander     if (total == 0) {
441039e02dfSJerome Forissier         return;
442*32b31808SJens Wiklander     }
443*32b31808SJens Wiklander     for (i = 0; i < total; i++) {
444039e02dfSJerome Forissier         unsigned no_op = mbedtls_ct_size_gt(total - offset, i);
445039e02dfSJerome Forissier         /* The first `total - offset` passes are a no-op. The last
446039e02dfSJerome Forissier          * `offset` passes shift the data one byte to the left and
447039e02dfSJerome Forissier          * zero out the last byte. */
448*32b31808SJens Wiklander         for (n = 0; n < total - 1; n++) {
449039e02dfSJerome Forissier             unsigned char current = buf[n];
450039e02dfSJerome Forissier             unsigned char next = buf[n+1];
451039e02dfSJerome Forissier             buf[n] = mbedtls_ct_uint_if(no_op, current, next);
452039e02dfSJerome Forissier         }
453039e02dfSJerome Forissier         buf[total-1] = mbedtls_ct_uint_if(no_op, buf[total-1], 0);
454039e02dfSJerome Forissier     }
455039e02dfSJerome Forissier }
456039e02dfSJerome Forissier 
457039e02dfSJerome Forissier #endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
458039e02dfSJerome Forissier 
459*32b31808SJens Wiklander #if defined(MBEDTLS_SSL_SOME_SUITES_USE_MAC)
460039e02dfSJerome Forissier 
461039e02dfSJerome Forissier void mbedtls_ct_memcpy_if_eq(unsigned char *dest,
462039e02dfSJerome Forissier                              const unsigned char *src,
463039e02dfSJerome Forissier                              size_t len,
464039e02dfSJerome Forissier                              size_t c1,
465039e02dfSJerome Forissier                              size_t c2)
466039e02dfSJerome Forissier {
467039e02dfSJerome Forissier     /* mask = c1 == c2 ? 0xff : 0x00 */
468039e02dfSJerome Forissier     const size_t equal = mbedtls_ct_size_bool_eq(c1, c2);
469039e02dfSJerome Forissier 
470039e02dfSJerome Forissier     /* dest[i] = c1 == c2 ? src[i] : dest[i] */
471*32b31808SJens Wiklander     size_t i = 0;
472*32b31808SJens Wiklander #if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)
473*32b31808SJens Wiklander     const uint32_t mask32 = (uint32_t) mbedtls_ct_size_mask(equal);
474*32b31808SJens Wiklander     const unsigned char mask = (unsigned char) mask32 & 0xff;
475*32b31808SJens Wiklander 
476*32b31808SJens Wiklander     for (; (i + 4) <= len; i += 4) {
477*32b31808SJens Wiklander         uint32_t a = mbedtls_get_unaligned_uint32(src  + i) &  mask32;
478*32b31808SJens Wiklander         uint32_t b = mbedtls_get_unaligned_uint32(dest + i) & ~mask32;
479*32b31808SJens Wiklander         mbedtls_put_unaligned_uint32(dest + i, a | b);
480*32b31808SJens Wiklander     }
481*32b31808SJens Wiklander #else
482*32b31808SJens Wiklander     const unsigned char mask = (unsigned char) mbedtls_ct_size_mask(equal);
483*32b31808SJens Wiklander #endif /* MBEDTLS_EFFICIENT_UNALIGNED_ACCESS */
484*32b31808SJens Wiklander     for (; i < len; i++) {
485039e02dfSJerome Forissier         dest[i] = (src[i] & mask) | (dest[i] & ~mask);
486039e02dfSJerome Forissier     }
487*32b31808SJens Wiklander }
488039e02dfSJerome Forissier 
489039e02dfSJerome Forissier void mbedtls_ct_memcpy_offset(unsigned char *dest,
490039e02dfSJerome Forissier                               const unsigned char *src,
491039e02dfSJerome Forissier                               size_t offset,
492039e02dfSJerome Forissier                               size_t offset_min,
493039e02dfSJerome Forissier                               size_t offset_max,
494039e02dfSJerome Forissier                               size_t len)
495039e02dfSJerome Forissier {
496039e02dfSJerome Forissier     size_t offsetval;
497039e02dfSJerome Forissier 
498*32b31808SJens Wiklander     for (offsetval = offset_min; offsetval <= offset_max; offsetval++) {
499039e02dfSJerome Forissier         mbedtls_ct_memcpy_if_eq(dest, src + offsetval, len,
500039e02dfSJerome Forissier                                 offsetval, offset);
501039e02dfSJerome Forissier     }
502039e02dfSJerome Forissier }
503039e02dfSJerome Forissier 
504*32b31808SJens Wiklander #if defined(MBEDTLS_USE_PSA_CRYPTO)
505*32b31808SJens Wiklander 
506*32b31808SJens Wiklander #if defined(PSA_WANT_ALG_SHA_384)
507*32b31808SJens Wiklander #define MAX_HASH_BLOCK_LENGTH PSA_HASH_BLOCK_LENGTH(PSA_ALG_SHA_384)
508*32b31808SJens Wiklander #elif defined(PSA_WANT_ALG_SHA_256)
509*32b31808SJens Wiklander #define MAX_HASH_BLOCK_LENGTH PSA_HASH_BLOCK_LENGTH(PSA_ALG_SHA_256)
510*32b31808SJens Wiklander #else /* See check_config.h */
511*32b31808SJens Wiklander #define MAX_HASH_BLOCK_LENGTH PSA_HASH_BLOCK_LENGTH(PSA_ALG_SHA_1)
512*32b31808SJens Wiklander #endif
513*32b31808SJens Wiklander 
514*32b31808SJens Wiklander int mbedtls_ct_hmac(mbedtls_svc_key_id_t key,
515*32b31808SJens Wiklander                     psa_algorithm_t mac_alg,
516*32b31808SJens Wiklander                     const unsigned char *add_data,
517*32b31808SJens Wiklander                     size_t add_data_len,
518*32b31808SJens Wiklander                     const unsigned char *data,
519*32b31808SJens Wiklander                     size_t data_len_secret,
520*32b31808SJens Wiklander                     size_t min_data_len,
521*32b31808SJens Wiklander                     size_t max_data_len,
522*32b31808SJens Wiklander                     unsigned char *output)
523*32b31808SJens Wiklander {
524*32b31808SJens Wiklander     /*
525*32b31808SJens Wiklander      * This function breaks the HMAC abstraction and uses psa_hash_clone()
526*32b31808SJens Wiklander      * extension in order to get constant-flow behaviour.
527*32b31808SJens Wiklander      *
528*32b31808SJens Wiklander      * HMAC(msg) is defined as HASH(okey + HASH(ikey + msg)) where + means
529*32b31808SJens Wiklander      * concatenation, and okey/ikey are the XOR of the key with some fixed bit
530*32b31808SJens Wiklander      * patterns (see RFC 2104, sec. 2).
531*32b31808SJens Wiklander      *
532*32b31808SJens Wiklander      * We'll first compute ikey/okey, then inner_hash = HASH(ikey + msg) by
533*32b31808SJens Wiklander      * hashing up to minlen, then cloning the context, and for each byte up
534*32b31808SJens Wiklander      * to maxlen finishing up the hash computation, keeping only the
535*32b31808SJens Wiklander      * correct result.
536*32b31808SJens Wiklander      *
537*32b31808SJens Wiklander      * Then we only need to compute HASH(okey + inner_hash) and we're done.
538*32b31808SJens Wiklander      */
539*32b31808SJens Wiklander     psa_algorithm_t hash_alg = PSA_ALG_HMAC_GET_HASH(mac_alg);
540*32b31808SJens Wiklander     const size_t block_size = PSA_HASH_BLOCK_LENGTH(hash_alg);
541*32b31808SJens Wiklander     unsigned char key_buf[MAX_HASH_BLOCK_LENGTH];
542*32b31808SJens Wiklander     const size_t hash_size = PSA_HASH_LENGTH(hash_alg);
543*32b31808SJens Wiklander     psa_hash_operation_t operation = PSA_HASH_OPERATION_INIT;
544*32b31808SJens Wiklander     size_t hash_length;
545*32b31808SJens Wiklander 
546*32b31808SJens Wiklander     unsigned char aux_out[PSA_HASH_MAX_SIZE];
547*32b31808SJens Wiklander     psa_hash_operation_t aux_operation = PSA_HASH_OPERATION_INIT;
548*32b31808SJens Wiklander     size_t offset;
549*32b31808SJens Wiklander     psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
550*32b31808SJens Wiklander 
551*32b31808SJens Wiklander     size_t mac_key_length;
552*32b31808SJens Wiklander     size_t i;
553*32b31808SJens Wiklander 
554*32b31808SJens Wiklander #define PSA_CHK(func_call)        \
555*32b31808SJens Wiklander     do {                            \
556*32b31808SJens Wiklander         status = (func_call);       \
557*32b31808SJens Wiklander         if (status != PSA_SUCCESS) \
558*32b31808SJens Wiklander         goto cleanup;           \
559*32b31808SJens Wiklander     } while (0)
560*32b31808SJens Wiklander 
561*32b31808SJens Wiklander     /* Export MAC key
562*32b31808SJens Wiklander      * We assume key length is always exactly the output size
563*32b31808SJens Wiklander      * which is never more than the block size, thus we use block_size
564*32b31808SJens Wiklander      * as the key buffer size.
565*32b31808SJens Wiklander      */
566*32b31808SJens Wiklander     PSA_CHK(psa_export_key(key, key_buf, block_size, &mac_key_length));
567*32b31808SJens Wiklander 
568*32b31808SJens Wiklander     /* Calculate ikey */
569*32b31808SJens Wiklander     for (i = 0; i < mac_key_length; i++) {
570*32b31808SJens Wiklander         key_buf[i] = (unsigned char) (key_buf[i] ^ 0x36);
571*32b31808SJens Wiklander     }
572*32b31808SJens Wiklander     for (; i < block_size; ++i) {
573*32b31808SJens Wiklander         key_buf[i] = 0x36;
574*32b31808SJens Wiklander     }
575*32b31808SJens Wiklander 
576*32b31808SJens Wiklander     PSA_CHK(psa_hash_setup(&operation, hash_alg));
577*32b31808SJens Wiklander 
578*32b31808SJens Wiklander     /* Now compute inner_hash = HASH(ikey + msg) */
579*32b31808SJens Wiklander     PSA_CHK(psa_hash_update(&operation, key_buf, block_size));
580*32b31808SJens Wiklander     PSA_CHK(psa_hash_update(&operation, add_data, add_data_len));
581*32b31808SJens Wiklander     PSA_CHK(psa_hash_update(&operation, data, min_data_len));
582*32b31808SJens Wiklander 
583*32b31808SJens Wiklander     /* Fill the hash buffer in advance with something that is
584*32b31808SJens Wiklander      * not a valid hash (barring an attack on the hash and
585*32b31808SJens Wiklander      * deliberately-crafted input), in case the caller doesn't
586*32b31808SJens Wiklander      * check the return status properly. */
587*32b31808SJens Wiklander     memset(output, '!', hash_size);
588*32b31808SJens Wiklander 
589*32b31808SJens Wiklander     /* For each possible length, compute the hash up to that point */
590*32b31808SJens Wiklander     for (offset = min_data_len; offset <= max_data_len; offset++) {
591*32b31808SJens Wiklander         PSA_CHK(psa_hash_clone(&operation, &aux_operation));
592*32b31808SJens Wiklander         PSA_CHK(psa_hash_finish(&aux_operation, aux_out,
593*32b31808SJens Wiklander                                 PSA_HASH_MAX_SIZE, &hash_length));
594*32b31808SJens Wiklander         /* Keep only the correct inner_hash in the output buffer */
595*32b31808SJens Wiklander         mbedtls_ct_memcpy_if_eq(output, aux_out, hash_size,
596*32b31808SJens Wiklander                                 offset, data_len_secret);
597*32b31808SJens Wiklander 
598*32b31808SJens Wiklander         if (offset < max_data_len) {
599*32b31808SJens Wiklander             PSA_CHK(psa_hash_update(&operation, data + offset, 1));
600*32b31808SJens Wiklander         }
601*32b31808SJens Wiklander     }
602*32b31808SJens Wiklander 
603*32b31808SJens Wiklander     /* Abort current operation to prepare for final operation */
604*32b31808SJens Wiklander     PSA_CHK(psa_hash_abort(&operation));
605*32b31808SJens Wiklander 
606*32b31808SJens Wiklander     /* Calculate okey */
607*32b31808SJens Wiklander     for (i = 0; i < mac_key_length; i++) {
608*32b31808SJens Wiklander         key_buf[i] = (unsigned char) ((key_buf[i] ^ 0x36) ^ 0x5C);
609*32b31808SJens Wiklander     }
610*32b31808SJens Wiklander     for (; i < block_size; ++i) {
611*32b31808SJens Wiklander         key_buf[i] = 0x5C;
612*32b31808SJens Wiklander     }
613*32b31808SJens Wiklander 
614*32b31808SJens Wiklander     /* Now compute HASH(okey + inner_hash) */
615*32b31808SJens Wiklander     PSA_CHK(psa_hash_setup(&operation, hash_alg));
616*32b31808SJens Wiklander     PSA_CHK(psa_hash_update(&operation, key_buf, block_size));
617*32b31808SJens Wiklander     PSA_CHK(psa_hash_update(&operation, output, hash_size));
618*32b31808SJens Wiklander     PSA_CHK(psa_hash_finish(&operation, output, hash_size, &hash_length));
619*32b31808SJens Wiklander 
620*32b31808SJens Wiklander #undef PSA_CHK
621*32b31808SJens Wiklander 
622*32b31808SJens Wiklander cleanup:
623*32b31808SJens Wiklander     mbedtls_platform_zeroize(key_buf, MAX_HASH_BLOCK_LENGTH);
624*32b31808SJens Wiklander     mbedtls_platform_zeroize(aux_out, PSA_HASH_MAX_SIZE);
625*32b31808SJens Wiklander 
626*32b31808SJens Wiklander     psa_hash_abort(&operation);
627*32b31808SJens Wiklander     psa_hash_abort(&aux_operation);
628*32b31808SJens Wiklander     return PSA_TO_MBEDTLS_ERR(status);
629*32b31808SJens Wiklander }
630*32b31808SJens Wiklander 
631*32b31808SJens Wiklander #undef MAX_HASH_BLOCK_LENGTH
632*32b31808SJens Wiklander 
633*32b31808SJens Wiklander #else
634039e02dfSJerome Forissier int mbedtls_ct_hmac(mbedtls_md_context_t *ctx,
635039e02dfSJerome Forissier                     const unsigned char *add_data,
636039e02dfSJerome Forissier                     size_t add_data_len,
637039e02dfSJerome Forissier                     const unsigned char *data,
638039e02dfSJerome Forissier                     size_t data_len_secret,
639039e02dfSJerome Forissier                     size_t min_data_len,
640039e02dfSJerome Forissier                     size_t max_data_len,
641039e02dfSJerome Forissier                     unsigned char *output)
642039e02dfSJerome Forissier {
643039e02dfSJerome Forissier     /*
644039e02dfSJerome Forissier      * This function breaks the HMAC abstraction and uses the md_clone()
645039e02dfSJerome Forissier      * extension to the MD API in order to get constant-flow behaviour.
646039e02dfSJerome Forissier      *
647039e02dfSJerome Forissier      * HMAC(msg) is defined as HASH(okey + HASH(ikey + msg)) where + means
648039e02dfSJerome Forissier      * concatenation, and okey/ikey are the XOR of the key with some fixed bit
649039e02dfSJerome Forissier      * patterns (see RFC 2104, sec. 2), which are stored in ctx->hmac_ctx.
650039e02dfSJerome Forissier      *
651039e02dfSJerome Forissier      * We'll first compute inner_hash = HASH(ikey + msg) by hashing up to
652039e02dfSJerome Forissier      * minlen, then cloning the context, and for each byte up to maxlen
653039e02dfSJerome Forissier      * finishing up the hash computation, keeping only the correct result.
654039e02dfSJerome Forissier      *
655039e02dfSJerome Forissier      * Then we only need to compute HASH(okey + inner_hash) and we're done.
656039e02dfSJerome Forissier      */
657039e02dfSJerome Forissier     const mbedtls_md_type_t md_alg = mbedtls_md_get_type(ctx->md_info);
658*32b31808SJens Wiklander     /* TLS 1.2 only supports SHA-384, SHA-256, SHA-1, MD-5,
659039e02dfSJerome Forissier      * all of which have the same block size except SHA-384. */
660039e02dfSJerome Forissier     const size_t block_size = md_alg == MBEDTLS_MD_SHA384 ? 128 : 64;
661039e02dfSJerome Forissier     const unsigned char * const ikey = ctx->hmac_ctx;
662039e02dfSJerome Forissier     const unsigned char * const okey = ikey + block_size;
663039e02dfSJerome Forissier     const size_t hash_size = mbedtls_md_get_size(ctx->md_info);
664039e02dfSJerome Forissier 
665039e02dfSJerome Forissier     unsigned char aux_out[MBEDTLS_MD_MAX_SIZE];
666039e02dfSJerome Forissier     mbedtls_md_context_t aux;
667039e02dfSJerome Forissier     size_t offset;
668039e02dfSJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
669039e02dfSJerome Forissier 
670039e02dfSJerome Forissier     mbedtls_md_init(&aux);
671039e02dfSJerome Forissier 
672039e02dfSJerome Forissier #define MD_CHK(func_call) \
673039e02dfSJerome Forissier     do {                    \
674039e02dfSJerome Forissier         ret = (func_call);  \
675039e02dfSJerome Forissier         if (ret != 0)      \
676039e02dfSJerome Forissier         goto cleanup;   \
677039e02dfSJerome Forissier     } while (0)
678039e02dfSJerome Forissier 
679039e02dfSJerome Forissier     MD_CHK(mbedtls_md_setup(&aux, ctx->md_info, 0));
680039e02dfSJerome Forissier 
681039e02dfSJerome Forissier     /* After hmac_start() of hmac_reset(), ikey has already been hashed,
682039e02dfSJerome Forissier      * so we can start directly with the message */
683039e02dfSJerome Forissier     MD_CHK(mbedtls_md_update(ctx, add_data, add_data_len));
684039e02dfSJerome Forissier     MD_CHK(mbedtls_md_update(ctx, data, min_data_len));
685039e02dfSJerome Forissier 
686039e02dfSJerome Forissier     /* Fill the hash buffer in advance with something that is
687039e02dfSJerome Forissier      * not a valid hash (barring an attack on the hash and
688039e02dfSJerome Forissier      * deliberately-crafted input), in case the caller doesn't
689039e02dfSJerome Forissier      * check the return status properly. */
690039e02dfSJerome Forissier     memset(output, '!', hash_size);
691039e02dfSJerome Forissier 
692039e02dfSJerome Forissier     /* For each possible length, compute the hash up to that point */
693*32b31808SJens Wiklander     for (offset = min_data_len; offset <= max_data_len; offset++) {
694039e02dfSJerome Forissier         MD_CHK(mbedtls_md_clone(&aux, ctx));
695039e02dfSJerome Forissier         MD_CHK(mbedtls_md_finish(&aux, aux_out));
696039e02dfSJerome Forissier         /* Keep only the correct inner_hash in the output buffer */
697039e02dfSJerome Forissier         mbedtls_ct_memcpy_if_eq(output, aux_out, hash_size,
698039e02dfSJerome Forissier                                 offset, data_len_secret);
699039e02dfSJerome Forissier 
700*32b31808SJens Wiklander         if (offset < max_data_len) {
701039e02dfSJerome Forissier             MD_CHK(mbedtls_md_update(ctx, data + offset, 1));
702039e02dfSJerome Forissier         }
703*32b31808SJens Wiklander     }
704039e02dfSJerome Forissier 
705039e02dfSJerome Forissier     /* The context needs to finish() before it starts() again */
706039e02dfSJerome Forissier     MD_CHK(mbedtls_md_finish(ctx, aux_out));
707039e02dfSJerome Forissier 
708039e02dfSJerome Forissier     /* Now compute HASH(okey + inner_hash) */
709039e02dfSJerome Forissier     MD_CHK(mbedtls_md_starts(ctx));
710039e02dfSJerome Forissier     MD_CHK(mbedtls_md_update(ctx, okey, block_size));
711039e02dfSJerome Forissier     MD_CHK(mbedtls_md_update(ctx, output, hash_size));
712039e02dfSJerome Forissier     MD_CHK(mbedtls_md_finish(ctx, output));
713039e02dfSJerome Forissier 
714039e02dfSJerome Forissier     /* Done, get ready for next time */
715039e02dfSJerome Forissier     MD_CHK(mbedtls_md_hmac_reset(ctx));
716039e02dfSJerome Forissier 
717039e02dfSJerome Forissier #undef MD_CHK
718039e02dfSJerome Forissier 
719039e02dfSJerome Forissier cleanup:
720039e02dfSJerome Forissier     mbedtls_md_free(&aux);
721*32b31808SJens Wiklander     return ret;
722039e02dfSJerome Forissier }
723*32b31808SJens Wiklander #endif /* MBEDTLS_USE_PSA_CRYPTO */
724039e02dfSJerome Forissier 
725*32b31808SJens Wiklander #endif /* MBEDTLS_SSL_SOME_SUITES_USE_MAC */
726039e02dfSJerome Forissier 
727039e02dfSJerome Forissier #if defined(MBEDTLS_BIGNUM_C)
728039e02dfSJerome Forissier 
729039e02dfSJerome Forissier #define MPI_VALIDATE_RET(cond)                                       \
730039e02dfSJerome Forissier     MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_MPI_BAD_INPUT_DATA)
731039e02dfSJerome Forissier 
732039e02dfSJerome Forissier /*
733039e02dfSJerome Forissier  * Conditionally assign X = Y, without leaking information
734039e02dfSJerome Forissier  * about whether the assignment was made or not.
735039e02dfSJerome Forissier  * (Leaking information about the respective sizes of X and Y is ok however.)
736039e02dfSJerome Forissier  */
737039e02dfSJerome Forissier #if defined(_MSC_VER) && defined(_M_ARM64) && (_MSC_FULL_VER < 193131103)
738039e02dfSJerome Forissier /*
739039e02dfSJerome Forissier  * MSVC miscompiles this function if it's inlined prior to Visual Studio 2022 version 17.1. See:
740039e02dfSJerome Forissier  * https://developercommunity.visualstudio.com/t/c-compiler-miscompiles-part-of-mbedtls-library-on/1646989
741039e02dfSJerome Forissier  */
742039e02dfSJerome Forissier __declspec(noinline)
743039e02dfSJerome Forissier #endif
744039e02dfSJerome Forissier int mbedtls_mpi_safe_cond_assign(mbedtls_mpi *X,
745039e02dfSJerome Forissier                                  const mbedtls_mpi *Y,
746039e02dfSJerome Forissier                                  unsigned char assign)
747039e02dfSJerome Forissier {
748039e02dfSJerome Forissier     int ret = 0;
749039e02dfSJerome Forissier     MPI_VALIDATE_RET(X != NULL);
750039e02dfSJerome Forissier     MPI_VALIDATE_RET(Y != NULL);
751039e02dfSJerome Forissier 
752039e02dfSJerome Forissier     /* all-bits 1 if assign is 1, all-bits 0 if assign is 0 */
753*32b31808SJens Wiklander     mbedtls_mpi_uint limb_mask = mbedtls_ct_mpi_uint_mask(assign);
754039e02dfSJerome Forissier 
755039e02dfSJerome Forissier     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, Y->n));
756039e02dfSJerome Forissier 
757039e02dfSJerome Forissier     X->s = mbedtls_ct_cond_select_sign(assign, Y->s, X->s);
758039e02dfSJerome Forissier 
759*32b31808SJens Wiklander     mbedtls_mpi_core_cond_assign(X->p, Y->p, Y->n, assign);
760039e02dfSJerome Forissier 
761*32b31808SJens Wiklander     for (size_t i = Y->n; i < X->n; i++) {
762039e02dfSJerome Forissier         X->p[i] &= ~limb_mask;
763*32b31808SJens Wiklander     }
764039e02dfSJerome Forissier 
765039e02dfSJerome Forissier cleanup:
766*32b31808SJens Wiklander     return ret;
767039e02dfSJerome Forissier }
768039e02dfSJerome Forissier 
769039e02dfSJerome Forissier /*
770039e02dfSJerome Forissier  * Conditionally swap X and Y, without leaking information
771039e02dfSJerome Forissier  * about whether the swap was made or not.
772039e02dfSJerome Forissier  * Here it is not ok to simply swap the pointers, which would lead to
773039e02dfSJerome Forissier  * different memory access patterns when X and Y are used afterwards.
774039e02dfSJerome Forissier  */
775039e02dfSJerome Forissier int mbedtls_mpi_safe_cond_swap(mbedtls_mpi *X,
776039e02dfSJerome Forissier                                mbedtls_mpi *Y,
777039e02dfSJerome Forissier                                unsigned char swap)
778039e02dfSJerome Forissier {
779*32b31808SJens Wiklander     int ret = 0;
780*32b31808SJens Wiklander     int s;
781039e02dfSJerome Forissier     MPI_VALIDATE_RET(X != NULL);
782039e02dfSJerome Forissier     MPI_VALIDATE_RET(Y != NULL);
783039e02dfSJerome Forissier 
784*32b31808SJens Wiklander     if (X == Y) {
785*32b31808SJens Wiklander         return 0;
786*32b31808SJens Wiklander     }
787039e02dfSJerome Forissier 
788039e02dfSJerome Forissier     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, Y->n));
789039e02dfSJerome Forissier     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(Y, X->n));
790039e02dfSJerome Forissier 
791039e02dfSJerome Forissier     s = X->s;
792039e02dfSJerome Forissier     X->s = mbedtls_ct_cond_select_sign(swap, Y->s, X->s);
793039e02dfSJerome Forissier     Y->s = mbedtls_ct_cond_select_sign(swap, s, Y->s);
794039e02dfSJerome Forissier 
795*32b31808SJens Wiklander     mbedtls_mpi_core_cond_swap(X->p, Y->p, X->n, swap);
796039e02dfSJerome Forissier 
797039e02dfSJerome Forissier cleanup:
798*32b31808SJens Wiklander     return ret;
799*32b31808SJens Wiklander }
800*32b31808SJens Wiklander 
801*32b31808SJens Wiklander /*
802*32b31808SJens Wiklander  * Compare unsigned values in constant time
803*32b31808SJens Wiklander  */
804*32b31808SJens Wiklander unsigned mbedtls_mpi_core_lt_ct(const mbedtls_mpi_uint *A,
805*32b31808SJens Wiklander                                 const mbedtls_mpi_uint *B,
806*32b31808SJens Wiklander                                 size_t limbs)
807*32b31808SJens Wiklander {
808*32b31808SJens Wiklander     unsigned ret, cond, done;
809*32b31808SJens Wiklander 
810*32b31808SJens Wiklander     /* The value of any of these variables is either 0 or 1 for the rest of
811*32b31808SJens Wiklander      * their scope. */
812*32b31808SJens Wiklander     ret = cond = done = 0;
813*32b31808SJens Wiklander 
814*32b31808SJens Wiklander     for (size_t i = limbs; i > 0; i--) {
815*32b31808SJens Wiklander         /*
816*32b31808SJens Wiklander          * If B[i - 1] < A[i - 1] then A < B is false and the result must
817*32b31808SJens Wiklander          * remain 0.
818*32b31808SJens Wiklander          *
819*32b31808SJens Wiklander          * Again even if we can make a decision, we just mark the result and
820*32b31808SJens Wiklander          * the fact that we are done and continue looping.
821*32b31808SJens Wiklander          */
822*32b31808SJens Wiklander         cond = mbedtls_ct_mpi_uint_lt(B[i - 1], A[i - 1]);
823*32b31808SJens Wiklander         done |= cond;
824*32b31808SJens Wiklander 
825*32b31808SJens Wiklander         /*
826*32b31808SJens Wiklander          * If A[i - 1] < B[i - 1] then A < B is true.
827*32b31808SJens Wiklander          *
828*32b31808SJens Wiklander          * Again even if we can make a decision, we just mark the result and
829*32b31808SJens Wiklander          * the fact that we are done and continue looping.
830*32b31808SJens Wiklander          */
831*32b31808SJens Wiklander         cond = mbedtls_ct_mpi_uint_lt(A[i - 1], B[i - 1]);
832*32b31808SJens Wiklander         ret |= cond & (1 - done);
833*32b31808SJens Wiklander         done |= cond;
834*32b31808SJens Wiklander     }
835*32b31808SJens Wiklander 
836*32b31808SJens Wiklander     /*
837*32b31808SJens Wiklander      * If all the limbs were equal, then the numbers are equal, A < B is false
838*32b31808SJens Wiklander      * and leaving the result 0 is correct.
839*32b31808SJens Wiklander      */
840*32b31808SJens Wiklander 
841*32b31808SJens Wiklander     return ret;
842039e02dfSJerome Forissier }
843039e02dfSJerome Forissier 
844039e02dfSJerome Forissier /*
845039e02dfSJerome Forissier  * Compare signed values in constant time
846039e02dfSJerome Forissier  */
847039e02dfSJerome Forissier int mbedtls_mpi_lt_mpi_ct(const mbedtls_mpi *X,
848039e02dfSJerome Forissier                           const mbedtls_mpi *Y,
849039e02dfSJerome Forissier                           unsigned *ret)
850039e02dfSJerome Forissier {
851039e02dfSJerome Forissier     size_t i;
852039e02dfSJerome Forissier     /* The value of any of these variables is either 0 or 1 at all times. */
853039e02dfSJerome Forissier     unsigned cond, done, X_is_negative, Y_is_negative;
854039e02dfSJerome Forissier 
855039e02dfSJerome Forissier     MPI_VALIDATE_RET(X != NULL);
856039e02dfSJerome Forissier     MPI_VALIDATE_RET(Y != NULL);
857039e02dfSJerome Forissier     MPI_VALIDATE_RET(ret != NULL);
858039e02dfSJerome Forissier 
859*32b31808SJens Wiklander     if (X->n != Y->n) {
860039e02dfSJerome Forissier         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
861*32b31808SJens Wiklander     }
862039e02dfSJerome Forissier 
863039e02dfSJerome Forissier     /*
864039e02dfSJerome Forissier      * Set sign_N to 1 if N >= 0, 0 if N < 0.
865039e02dfSJerome Forissier      * We know that N->s == 1 if N >= 0 and N->s == -1 if N < 0.
866039e02dfSJerome Forissier      */
867039e02dfSJerome Forissier     X_is_negative = (X->s & 2) >> 1;
868039e02dfSJerome Forissier     Y_is_negative = (Y->s & 2) >> 1;
869039e02dfSJerome Forissier 
870039e02dfSJerome Forissier     /*
871039e02dfSJerome Forissier      * If the signs are different, then the positive operand is the bigger.
872039e02dfSJerome Forissier      * That is if X is negative (X_is_negative == 1), then X < Y is true and it
873039e02dfSJerome Forissier      * is false if X is positive (X_is_negative == 0).
874039e02dfSJerome Forissier      */
875039e02dfSJerome Forissier     cond = (X_is_negative ^ Y_is_negative);
876039e02dfSJerome Forissier     *ret = cond & X_is_negative;
877039e02dfSJerome Forissier 
878039e02dfSJerome Forissier     /*
879039e02dfSJerome Forissier      * This is a constant-time function. We might have the result, but we still
880039e02dfSJerome Forissier      * need to go through the loop. Record if we have the result already.
881039e02dfSJerome Forissier      */
882039e02dfSJerome Forissier     done = cond;
883039e02dfSJerome Forissier 
884*32b31808SJens Wiklander     for (i = X->n; i > 0; i--) {
885039e02dfSJerome Forissier         /*
886039e02dfSJerome Forissier          * If Y->p[i - 1] < X->p[i - 1] then X < Y is true if and only if both
887039e02dfSJerome Forissier          * X and Y are negative.
888039e02dfSJerome Forissier          *
889039e02dfSJerome Forissier          * Again even if we can make a decision, we just mark the result and
890039e02dfSJerome Forissier          * the fact that we are done and continue looping.
891039e02dfSJerome Forissier          */
892039e02dfSJerome Forissier         cond = mbedtls_ct_mpi_uint_lt(Y->p[i - 1], X->p[i - 1]);
893039e02dfSJerome Forissier         *ret |= cond & (1 - done) & X_is_negative;
894039e02dfSJerome Forissier         done |= cond;
895039e02dfSJerome Forissier 
896039e02dfSJerome Forissier         /*
897039e02dfSJerome Forissier          * If X->p[i - 1] < Y->p[i - 1] then X < Y is true if and only if both
898039e02dfSJerome Forissier          * X and Y are positive.
899039e02dfSJerome Forissier          *
900039e02dfSJerome Forissier          * Again even if we can make a decision, we just mark the result and
901039e02dfSJerome Forissier          * the fact that we are done and continue looping.
902039e02dfSJerome Forissier          */
903039e02dfSJerome Forissier         cond = mbedtls_ct_mpi_uint_lt(X->p[i - 1], Y->p[i - 1]);
904039e02dfSJerome Forissier         *ret |= cond & (1 - done) & (1 - X_is_negative);
905039e02dfSJerome Forissier         done |= cond;
906039e02dfSJerome Forissier     }
907039e02dfSJerome Forissier 
908*32b31808SJens Wiklander     return 0;
909039e02dfSJerome Forissier }
910039e02dfSJerome Forissier 
911039e02dfSJerome Forissier #endif /* MBEDTLS_BIGNUM_C */
912039e02dfSJerome Forissier 
913039e02dfSJerome Forissier #if defined(MBEDTLS_PKCS1_V15) && defined(MBEDTLS_RSA_C) && !defined(MBEDTLS_RSA_ALT)
914039e02dfSJerome Forissier 
915*32b31808SJens Wiklander int mbedtls_ct_rsaes_pkcs1_v15_unpadding(unsigned char *input,
916039e02dfSJerome Forissier                                          size_t ilen,
917039e02dfSJerome Forissier                                          unsigned char *output,
918039e02dfSJerome Forissier                                          size_t output_max_len,
919039e02dfSJerome Forissier                                          size_t *olen)
920039e02dfSJerome Forissier {
921039e02dfSJerome Forissier     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
922039e02dfSJerome Forissier     size_t i, plaintext_max_size;
923039e02dfSJerome Forissier 
924039e02dfSJerome Forissier     /* The following variables take sensitive values: their value must
925039e02dfSJerome Forissier      * not leak into the observable behavior of the function other than
926039e02dfSJerome Forissier      * the designated outputs (output, olen, return value). Otherwise
927039e02dfSJerome Forissier      * this would open the execution of the function to
928039e02dfSJerome Forissier      * side-channel-based variants of the Bleichenbacher padding oracle
929039e02dfSJerome Forissier      * attack. Potential side channels include overall timing, memory
930039e02dfSJerome Forissier      * access patterns (especially visible to an adversary who has access
931039e02dfSJerome Forissier      * to a shared memory cache), and branches (especially visible to
932039e02dfSJerome Forissier      * an adversary who has access to a shared code cache or to a shared
933039e02dfSJerome Forissier      * branch predictor). */
934039e02dfSJerome Forissier     size_t pad_count = 0;
935039e02dfSJerome Forissier     unsigned bad = 0;
936039e02dfSJerome Forissier     unsigned char pad_done = 0;
937039e02dfSJerome Forissier     size_t plaintext_size = 0;
938039e02dfSJerome Forissier     unsigned output_too_large;
939039e02dfSJerome Forissier 
940039e02dfSJerome Forissier     plaintext_max_size = (output_max_len > ilen - 11) ? ilen - 11
941039e02dfSJerome Forissier                                                         : output_max_len;
942039e02dfSJerome Forissier 
943039e02dfSJerome Forissier     /* Check and get padding length in constant time and constant
944039e02dfSJerome Forissier      * memory trace. The first byte must be 0. */
945039e02dfSJerome Forissier     bad |= input[0];
946039e02dfSJerome Forissier 
947*32b31808SJens Wiklander 
948039e02dfSJerome Forissier     /* Decode EME-PKCS1-v1_5 padding: 0x00 || 0x02 || PS || 0x00
949039e02dfSJerome Forissier      * where PS must be at least 8 nonzero bytes. */
950039e02dfSJerome Forissier     bad |= input[1] ^ MBEDTLS_RSA_CRYPT;
951039e02dfSJerome Forissier 
952039e02dfSJerome Forissier     /* Read the whole buffer. Set pad_done to nonzero if we find
953039e02dfSJerome Forissier      * the 0x00 byte and remember the padding length in pad_count. */
954*32b31808SJens Wiklander     for (i = 2; i < ilen; i++) {
955039e02dfSJerome Forissier         pad_done  |= ((input[i] | (unsigned char) -input[i]) >> 7) ^ 1;
956039e02dfSJerome Forissier         pad_count += ((pad_done | (unsigned char) -pad_done) >> 7) ^ 1;
957039e02dfSJerome Forissier     }
958039e02dfSJerome Forissier 
959039e02dfSJerome Forissier 
960039e02dfSJerome Forissier     /* If pad_done is still zero, there's no data, only unfinished padding. */
961039e02dfSJerome Forissier     bad |= mbedtls_ct_uint_if(pad_done, 0, 1);
962039e02dfSJerome Forissier 
963039e02dfSJerome Forissier     /* There must be at least 8 bytes of padding. */
964039e02dfSJerome Forissier     bad |= mbedtls_ct_size_gt(8, pad_count);
965039e02dfSJerome Forissier 
966039e02dfSJerome Forissier     /* If the padding is valid, set plaintext_size to the number of
967039e02dfSJerome Forissier      * remaining bytes after stripping the padding. If the padding
968039e02dfSJerome Forissier      * is invalid, avoid leaking this fact through the size of the
969039e02dfSJerome Forissier      * output: use the maximum message size that fits in the output
970039e02dfSJerome Forissier      * buffer. Do it without branches to avoid leaking the padding
971039e02dfSJerome Forissier      * validity through timing. RSA keys are small enough that all the
972039e02dfSJerome Forissier      * size_t values involved fit in unsigned int. */
973039e02dfSJerome Forissier     plaintext_size = mbedtls_ct_uint_if(
974039e02dfSJerome Forissier         bad, (unsigned) plaintext_max_size,
975039e02dfSJerome Forissier         (unsigned) (ilen - pad_count - 3));
976039e02dfSJerome Forissier 
977039e02dfSJerome Forissier     /* Set output_too_large to 0 if the plaintext fits in the output
978039e02dfSJerome Forissier      * buffer and to 1 otherwise. */
979039e02dfSJerome Forissier     output_too_large = mbedtls_ct_size_gt(plaintext_size,
980039e02dfSJerome Forissier                                           plaintext_max_size);
981039e02dfSJerome Forissier 
982039e02dfSJerome Forissier     /* Set ret without branches to avoid timing attacks. Return:
983039e02dfSJerome Forissier      * - INVALID_PADDING if the padding is bad (bad != 0).
984039e02dfSJerome Forissier      * - OUTPUT_TOO_LARGE if the padding is good but the decrypted
985039e02dfSJerome Forissier      *   plaintext does not fit in the output buffer.
986039e02dfSJerome Forissier      * - 0 if the padding is correct. */
987039e02dfSJerome Forissier     ret = -(int) mbedtls_ct_uint_if(
988039e02dfSJerome Forissier         bad, -MBEDTLS_ERR_RSA_INVALID_PADDING,
989039e02dfSJerome Forissier         mbedtls_ct_uint_if(output_too_large,
990039e02dfSJerome Forissier                            -MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE,
991039e02dfSJerome Forissier                            0));
992039e02dfSJerome Forissier 
993039e02dfSJerome Forissier     /* If the padding is bad or the plaintext is too large, zero the
994039e02dfSJerome Forissier      * data that we're about to copy to the output buffer.
995039e02dfSJerome Forissier      * We need to copy the same amount of data
996039e02dfSJerome Forissier      * from the same buffer whether the padding is good or not to
997039e02dfSJerome Forissier      * avoid leaking the padding validity through overall timing or
998039e02dfSJerome Forissier      * through memory or cache access patterns. */
999039e02dfSJerome Forissier     bad = mbedtls_ct_uint_mask(bad | output_too_large);
1000*32b31808SJens Wiklander     for (i = 11; i < ilen; i++) {
1001039e02dfSJerome Forissier         input[i] &= ~bad;
1002*32b31808SJens Wiklander     }
1003039e02dfSJerome Forissier 
1004039e02dfSJerome Forissier     /* If the plaintext is too large, truncate it to the buffer size.
1005039e02dfSJerome Forissier      * Copy anyway to avoid revealing the length through timing, because
1006039e02dfSJerome Forissier      * revealing the length is as bad as revealing the padding validity
1007039e02dfSJerome Forissier      * for a Bleichenbacher attack. */
1008039e02dfSJerome Forissier     plaintext_size = mbedtls_ct_uint_if(output_too_large,
1009039e02dfSJerome Forissier                                         (unsigned) plaintext_max_size,
1010039e02dfSJerome Forissier                                         (unsigned) plaintext_size);
1011039e02dfSJerome Forissier 
1012039e02dfSJerome Forissier     /* Move the plaintext to the leftmost position where it can start in
1013039e02dfSJerome Forissier      * the working buffer, i.e. make it start plaintext_max_size from
1014039e02dfSJerome Forissier      * the end of the buffer. Do this with a memory access trace that
1015039e02dfSJerome Forissier      * does not depend on the plaintext size. After this move, the
1016039e02dfSJerome Forissier      * starting location of the plaintext is no longer sensitive
1017039e02dfSJerome Forissier      * information. */
1018039e02dfSJerome Forissier     mbedtls_ct_mem_move_to_left(input + ilen - plaintext_max_size,
1019039e02dfSJerome Forissier                                 plaintext_max_size,
1020039e02dfSJerome Forissier                                 plaintext_max_size - plaintext_size);
1021039e02dfSJerome Forissier 
1022039e02dfSJerome Forissier     /* Finally copy the decrypted plaintext plus trailing zeros into the output
1023039e02dfSJerome Forissier      * buffer. If output_max_len is 0, then output may be an invalid pointer
1024039e02dfSJerome Forissier      * and the result of memcpy() would be undefined; prevent undefined
1025039e02dfSJerome Forissier      * behavior making sure to depend only on output_max_len (the size of the
1026039e02dfSJerome Forissier      * user-provided output buffer), which is independent from plaintext
1027039e02dfSJerome Forissier      * length, validity of padding, success of the decryption, and other
1028039e02dfSJerome Forissier      * secrets. */
1029*32b31808SJens Wiklander     if (output_max_len != 0) {
1030039e02dfSJerome Forissier         memcpy(output, input + ilen - plaintext_max_size, plaintext_max_size);
1031*32b31808SJens Wiklander     }
1032039e02dfSJerome Forissier 
1033039e02dfSJerome Forissier     /* Report the amount of data we copied to the output buffer. In case
1034039e02dfSJerome Forissier      * of errors (bad padding or output too large), the value of *olen
1035039e02dfSJerome Forissier      * when this function returns is not specified. Making it equivalent
1036039e02dfSJerome Forissier      * to the good case limits the risks of leaking the padding validity. */
1037039e02dfSJerome Forissier     *olen = plaintext_size;
1038039e02dfSJerome Forissier 
1039*32b31808SJens Wiklander     return ret;
1040039e02dfSJerome Forissier }
1041039e02dfSJerome Forissier 
1042039e02dfSJerome Forissier #endif /* MBEDTLS_PKCS1_V15 && MBEDTLS_RSA_C && ! MBEDTLS_RSA_ALT */
1043