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