Lines Matching +full:- +full:x
2 * Constant-time functions
5 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
28 * This appears to behave as if the declaration-without-definition was not present
29 * (except for warnings if gcc -Wredundant-decls or similar is used).
31 * Disable -Wredundant-decls so that gcc does not warn about this. This is re-enabled
36 #pragma GCC diagnostic ignored "-Wredundant-decls"
39 /* armcc5 --gnu defines __GNUC__ but doesn't support GNU's extended asm */
58 * Core const-time primitives
61 /* Ensure that the compiler cannot know the value of x (i.e., cannot optimise
75 * \param x The value to hide from the compiler.
78 * x = mbedtls_ct_compiler_opaque(1), x will be unknown).
85 static inline mbedtls_ct_uint_t mbedtls_ct_compiler_opaque(mbedtls_ct_uint_t x) in mbedtls_ct_compiler_opaque() argument
88 asm volatile ("" : [x] "+r" (x) :); in mbedtls_ct_compiler_opaque()
89 return x; in mbedtls_ct_compiler_opaque()
91 return x ^ mbedtls_ct_zero; in mbedtls_ct_compiler_opaque()
109 * syntax afterwards - otherwise old versions of gcc seem to apply
120 static inline mbedtls_ct_condition_t mbedtls_ct_bool(mbedtls_ct_uint_t x) in mbedtls_ct_bool() argument
123 …* Define mask-generation code that, as far as possible, will not use branches or conditional instr… in mbedtls_ct_bool()
132 asm volatile ("neg %x[s], %x[x] \n\t" in mbedtls_ct_bool()
133 "orr %x[x], %x[s], %x[x] \n\t" in mbedtls_ct_bool()
134 "asr %x[x], %x[x], 63 \n\t" in mbedtls_ct_bool()
137 [x] "+&r" (x) in mbedtls_ct_bool()
141 return (mbedtls_ct_condition_t) x; in mbedtls_ct_bool()
145 "negs %[s], %[x] \n\t" in mbedtls_ct_bool()
146 "orrs %[x], %[x], %[s] \n\t" in mbedtls_ct_bool()
147 "asrs %[x], %[x], #31 \n\t" in mbedtls_ct_bool()
151 [x] "+&l" (x) in mbedtls_ct_bool()
156 return (mbedtls_ct_condition_t) x; in mbedtls_ct_bool()
159 asm volatile ("mov %[x], %[s] \n\t" in mbedtls_ct_bool()
161 "or %[x], %[s] \n\t" in mbedtls_ct_bool()
166 [x] "D" (x) in mbedtls_ct_bool()
172 asm volatile ("mov %[x], %[s] \n\t" in mbedtls_ct_bool()
174 "or %[s], %[x] \n\t" in mbedtls_ct_bool()
175 "sar $31, %[x] \n\t" in mbedtls_ct_bool()
178 [x] "+&a" (x) in mbedtls_ct_bool()
182 return (mbedtls_ct_condition_t) x; in mbedtls_ct_bool()
184 const mbedtls_ct_uint_t xo = mbedtls_ct_compiler_opaque(x); in mbedtls_ct_bool()
187 * well-defined and precisely what we want to do here */ in mbedtls_ct_bool()
191 // y is negative (i.e., top bit set) iff x is non-zero in mbedtls_ct_bool()
192 mbedtls_ct_int_t y = (-xo) | -(xo >> 1); in mbedtls_ct_bool()
194 // extract only the sign bit of y so that y == 1 (if x is non-zero) or 0 (if x is zero) in mbedtls_ct_bool()
195 y = (((mbedtls_ct_uint_t) y) >> (MBEDTLS_CT_SIZE - 1)); in mbedtls_ct_bool()
197 // -y has all bits set (if x is non-zero), or all bits clear (if x is zero) in mbedtls_ct_bool()
198 return (mbedtls_ct_condition_t) (-y); in mbedtls_ct_bool()
210 asm volatile ("and %x[if1], %x[if1], %x[condition] \n\t" in mbedtls_ct_if()
211 "mvn %x[condition], %x[condition] \n\t" in mbedtls_ct_if()
212 "and %x[condition], %x[condition], %x[if0] \n\t" in mbedtls_ct_if()
213 "orr %x[condition], %x[if1], %x[condition]" in mbedtls_ct_if()
271 static inline mbedtls_ct_condition_t mbedtls_ct_uint_lt(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y) in mbedtls_ct_uint_lt() argument
275 asm volatile ("eor %x[s1], %x[y], %x[x] \n\t" in mbedtls_ct_uint_lt()
276 "sub %x[x], %x[x], %x[y] \n\t" in mbedtls_ct_uint_lt()
277 "bic %x[x], %x[x], %x[s1] \n\t" in mbedtls_ct_uint_lt()
278 "and %x[s1], %x[s1], %x[y] \n\t" in mbedtls_ct_uint_lt()
279 "orr %x[s1], %x[x], %x[s1] \n\t" in mbedtls_ct_uint_lt()
280 "asr %x[x], %x[s1], 63" in mbedtls_ct_uint_lt()
283 [x] "+&r" (x) in mbedtls_ct_uint_lt()
288 return (mbedtls_ct_condition_t) x; in mbedtls_ct_uint_lt()
294 "movs %[s1], %[x] \n\t" in mbedtls_ct_uint_lt()
297 "eors %[s1], %[x], %[y] \n\t" in mbedtls_ct_uint_lt()
299 "subs %[x], %[x], %[y] \n\t" in mbedtls_ct_uint_lt()
300 "bics %[x], %[x], %[s1] \n\t" in mbedtls_ct_uint_lt()
302 "orrs %[x], %[x], %[y] \n\t" in mbedtls_ct_uint_lt()
303 "asrs %[x], %[x], #31 \n\t" in mbedtls_ct_uint_lt()
307 [x] "+&l" (x), in mbedtls_ct_uint_lt()
313 return (mbedtls_ct_condition_t) x; in mbedtls_ct_uint_lt()
316 asm volatile ("mov %[x], %[s] \n\t" in mbedtls_ct_uint_lt()
318 "sub %[y], %[x] \n\t" in mbedtls_ct_uint_lt()
321 "and %[s], %[x] \n\t" in mbedtls_ct_uint_lt()
322 "or %[y], %[x] \n\t" in mbedtls_ct_uint_lt()
323 "sar $63, %[x] \n\t" in mbedtls_ct_uint_lt()
326 [x] "+&D" (x), in mbedtls_ct_uint_lt()
331 return (mbedtls_ct_condition_t) x; in mbedtls_ct_uint_lt()
334 asm volatile ("mov %[x], %[s] \n\t" in mbedtls_ct_uint_lt()
336 "sub %[y], %[x] \n\t" in mbedtls_ct_uint_lt()
339 "and %[s], %[x] \n\t" in mbedtls_ct_uint_lt()
340 "or %[y], %[x] \n\t" in mbedtls_ct_uint_lt()
341 "sar $31, %[x] \n\t" in mbedtls_ct_uint_lt()
344 [x] "+&a" (x), in mbedtls_ct_uint_lt()
349 return (mbedtls_ct_condition_t) x; in mbedtls_ct_uint_lt()
351 /* Ensure that the compiler cannot optimise the following operations over x and y, in mbedtls_ct_uint_lt()
352 * even if it knows the value of x and y. in mbedtls_ct_uint_lt()
354 const mbedtls_ct_uint_t xo = mbedtls_ct_compiler_opaque(x); in mbedtls_ct_uint_lt()
360 mbedtls_ct_condition_t cond = mbedtls_ct_bool((xo ^ yo) >> (MBEDTLS_CT_SIZE - 1)); in mbedtls_ct_uint_lt()
363 * If the MSB are the same then the difference x-y will be negative (and in mbedtls_ct_uint_lt()
364 * have its MSB set to 1 during conversion to unsigned) if and only if x<y. in mbedtls_ct_uint_lt()
367 * bigger. (That is if y has MSB of 1, then x<y is true and it is false if in mbedtls_ct_uint_lt()
371 // Select either y, or x - y in mbedtls_ct_uint_lt()
372 mbedtls_ct_uint_t ret = mbedtls_ct_if(cond, yo, (mbedtls_ct_uint_t) (xo - yo)); in mbedtls_ct_uint_lt()
375 ret = ret >> (MBEDTLS_CT_SIZE - 1); in mbedtls_ct_uint_lt()
377 // Convert to a condition (i.e., all bits set iff non-zero) in mbedtls_ct_uint_lt()
382 static inline mbedtls_ct_condition_t mbedtls_ct_uint_ne(mbedtls_ct_uint_t x, mbedtls_ct_uint_t y) in mbedtls_ct_uint_ne() argument
384 /* diff = 0 if x == y, non-zero otherwise */ in mbedtls_ct_uint_ne()
385 const mbedtls_ct_uint_t diff = mbedtls_ct_compiler_opaque(x) ^ mbedtls_ct_compiler_opaque(y); in mbedtls_ct_uint_ne()
387 /* all ones if x != y, 0 otherwise */ in mbedtls_ct_uint_ne()
399 /* low_mask is: 0 if low <= c, 0x...ff if low > c */ in mbedtls_ct_uchar_in_range_if()
400 unsigned low_mask = ((unsigned) co - low) >> 8; in mbedtls_ct_uchar_in_range_if()
401 /* high_mask is: 0 if c <= high, 0x...ff if c > high */ in mbedtls_ct_uchar_in_range_if()
402 unsigned high_mask = ((unsigned) high - co) >> 8; in mbedtls_ct_uchar_in_range_if()
474 /* Coverting int -> uint -> int here is safe, because we require if1 and if0 to be in mbedtls_ct_error_if()
475 * in the range -32767..0, and we require 32-bit int and uint types. in mbedtls_ct_error_if()
477 * This means that (0 <= -if0 < INT_MAX), so negating if0 is safe, and similarly for in mbedtls_ct_error_if()
480 return -((int) mbedtls_ct_if(condition, (mbedtls_ct_uint_t) (-if1), in mbedtls_ct_error_if()
481 (mbedtls_ct_uint_t) (-if0))); in mbedtls_ct_error_if()
486 return -((int) (condition & (-if1))); in mbedtls_ct_error_if_else_0()
489 static inline mbedtls_ct_condition_t mbedtls_ct_uint_eq(mbedtls_ct_uint_t x, in mbedtls_ct_uint_eq() argument
492 return ~mbedtls_ct_uint_ne(x, y); in mbedtls_ct_uint_eq()
495 static inline mbedtls_ct_condition_t mbedtls_ct_uint_gt(mbedtls_ct_uint_t x, in mbedtls_ct_uint_gt() argument
498 return mbedtls_ct_uint_lt(y, x); in mbedtls_ct_uint_gt()
501 static inline mbedtls_ct_condition_t mbedtls_ct_uint_ge(mbedtls_ct_uint_t x, in mbedtls_ct_uint_ge() argument
504 return ~mbedtls_ct_uint_lt(x, y); in mbedtls_ct_uint_ge()
507 static inline mbedtls_ct_condition_t mbedtls_ct_uint_le(mbedtls_ct_uint_t x, in mbedtls_ct_uint_le() argument
510 return ~mbedtls_ct_uint_gt(x, y); in mbedtls_ct_uint_le()
513 static inline mbedtls_ct_condition_t mbedtls_ct_bool_ne(mbedtls_ct_condition_t x, in mbedtls_ct_bool_ne() argument
516 return (mbedtls_ct_condition_t) (x ^ y); in mbedtls_ct_bool_ne()
519 static inline mbedtls_ct_condition_t mbedtls_ct_bool_and(mbedtls_ct_condition_t x, in mbedtls_ct_bool_and() argument
522 return (mbedtls_ct_condition_t) (x & y); in mbedtls_ct_bool_and()
525 static inline mbedtls_ct_condition_t mbedtls_ct_bool_or(mbedtls_ct_condition_t x, in mbedtls_ct_bool_or() argument
528 return (mbedtls_ct_condition_t) (x | y); in mbedtls_ct_bool_or()
531 static inline mbedtls_ct_condition_t mbedtls_ct_bool_not(mbedtls_ct_condition_t x) in mbedtls_ct_bool_not() argument
533 return (mbedtls_ct_condition_t) (~x); in mbedtls_ct_bool_not()
537 /* Restore warnings for -Wredundant-decls on gcc */