17d004720Schristos /*
2*0e2e28bcSchristos * Copyright 2014-2024 The OpenSSL Project Authors. All Rights Reserved.
37d004720Schristos *
4b0d17251Schristos * Licensed under the Apache License 2.0 (the "License"). You may not use
57d004720Schristos * this file except in compliance with the License. You can obtain a copy
67d004720Schristos * in the file LICENSE in the source distribution or at
77d004720Schristos * https://www.openssl.org/source/license.html
87d004720Schristos */
97d004720Schristos
107d004720Schristos #ifndef OSSL_INTERNAL_CONSTANT_TIME_H
117d004720Schristos # define OSSL_INTERNAL_CONSTANT_TIME_H
12b0d17251Schristos # pragma once
137d004720Schristos
147d004720Schristos # include <stdlib.h>
157d004720Schristos # include <string.h>
167d004720Schristos # include <openssl/e_os2.h> /* For 'ossl_inline' */
177d004720Schristos
187d004720Schristos /*-
197d004720Schristos * The boolean methods return a bitmask of all ones (0xff...f) for true
207d004720Schristos * and 0 for false. This is useful for choosing a value based on the result
217d004720Schristos * of a conditional in constant time. For example,
227d004720Schristos * if (a < b) {
237d004720Schristos * c = a;
247d004720Schristos * } else {
257d004720Schristos * c = b;
267d004720Schristos * }
277d004720Schristos * can be written as
287d004720Schristos * unsigned int lt = constant_time_lt(a, b);
297d004720Schristos * c = constant_time_select(lt, a, b);
307d004720Schristos */
317d004720Schristos
327d004720Schristos /* Returns the given value with the MSB copied to all the other bits. */
337d004720Schristos static ossl_inline unsigned int constant_time_msb(unsigned int a);
347d004720Schristos /* Convenience method for uint32_t. */
357d004720Schristos static ossl_inline uint32_t constant_time_msb_32(uint32_t a);
367d004720Schristos /* Convenience method for uint64_t. */
377d004720Schristos static ossl_inline uint64_t constant_time_msb_64(uint64_t a);
387d004720Schristos
397d004720Schristos /* Returns 0xff..f if a < b and 0 otherwise. */
407d004720Schristos static ossl_inline unsigned int constant_time_lt(unsigned int a,
417d004720Schristos unsigned int b);
427d004720Schristos /* Convenience method for getting an 8-bit mask. */
437d004720Schristos static ossl_inline unsigned char constant_time_lt_8(unsigned int a,
447d004720Schristos unsigned int b);
457d004720Schristos /* Convenience method for uint64_t. */
467d004720Schristos static ossl_inline uint64_t constant_time_lt_64(uint64_t a, uint64_t b);
477d004720Schristos
487d004720Schristos /* Returns 0xff..f if a >= b and 0 otherwise. */
497d004720Schristos static ossl_inline unsigned int constant_time_ge(unsigned int a,
507d004720Schristos unsigned int b);
517d004720Schristos /* Convenience method for getting an 8-bit mask. */
527d004720Schristos static ossl_inline unsigned char constant_time_ge_8(unsigned int a,
537d004720Schristos unsigned int b);
547d004720Schristos
557d004720Schristos /* Returns 0xff..f if a == 0 and 0 otherwise. */
567d004720Schristos static ossl_inline unsigned int constant_time_is_zero(unsigned int a);
577d004720Schristos /* Convenience method for getting an 8-bit mask. */
587d004720Schristos static ossl_inline unsigned char constant_time_is_zero_8(unsigned int a);
597d004720Schristos /* Convenience method for getting a 32-bit mask. */
607d004720Schristos static ossl_inline uint32_t constant_time_is_zero_32(uint32_t a);
617d004720Schristos
627d004720Schristos /* Returns 0xff..f if a == b and 0 otherwise. */
637d004720Schristos static ossl_inline unsigned int constant_time_eq(unsigned int a,
647d004720Schristos unsigned int b);
657d004720Schristos /* Convenience method for getting an 8-bit mask. */
667d004720Schristos static ossl_inline unsigned char constant_time_eq_8(unsigned int a,
677d004720Schristos unsigned int b);
687d004720Schristos /* Signed integers. */
697d004720Schristos static ossl_inline unsigned int constant_time_eq_int(int a, int b);
707d004720Schristos /* Convenience method for getting an 8-bit mask. */
717d004720Schristos static ossl_inline unsigned char constant_time_eq_int_8(int a, int b);
727d004720Schristos
737d004720Schristos /*-
747d004720Schristos * Returns (mask & a) | (~mask & b).
757d004720Schristos *
767d004720Schristos * When |mask| is all 1s or all 0s (as returned by the methods above),
777d004720Schristos * the select methods return either |a| (if |mask| is nonzero) or |b|
787d004720Schristos * (if |mask| is zero).
797d004720Schristos */
807d004720Schristos static ossl_inline unsigned int constant_time_select(unsigned int mask,
817d004720Schristos unsigned int a,
827d004720Schristos unsigned int b);
837d004720Schristos /* Convenience method for unsigned chars. */
847d004720Schristos static ossl_inline unsigned char constant_time_select_8(unsigned char mask,
857d004720Schristos unsigned char a,
867d004720Schristos unsigned char b);
877d004720Schristos
887d004720Schristos /* Convenience method for uint32_t. */
897d004720Schristos static ossl_inline uint32_t constant_time_select_32(uint32_t mask, uint32_t a,
907d004720Schristos uint32_t b);
917d004720Schristos
927d004720Schristos /* Convenience method for uint64_t. */
937d004720Schristos static ossl_inline uint64_t constant_time_select_64(uint64_t mask, uint64_t a,
947d004720Schristos uint64_t b);
957d004720Schristos /* Convenience method for signed integers. */
967d004720Schristos static ossl_inline int constant_time_select_int(unsigned int mask, int a,
977d004720Schristos int b);
987d004720Schristos
997d004720Schristos
constant_time_msb(unsigned int a)1007d004720Schristos static ossl_inline unsigned int constant_time_msb(unsigned int a)
1017d004720Schristos {
1027d004720Schristos return 0 - (a >> (sizeof(a) * 8 - 1));
1037d004720Schristos }
1047d004720Schristos
1057d004720Schristos
constant_time_msb_32(uint32_t a)1067d004720Schristos static ossl_inline uint32_t constant_time_msb_32(uint32_t a)
1077d004720Schristos {
1087d004720Schristos return 0 - (a >> 31);
1097d004720Schristos }
1107d004720Schristos
constant_time_msb_64(uint64_t a)1117d004720Schristos static ossl_inline uint64_t constant_time_msb_64(uint64_t a)
1127d004720Schristos {
1137d004720Schristos return 0 - (a >> 63);
1147d004720Schristos }
1157d004720Schristos
constant_time_msb_s(size_t a)1167d004720Schristos static ossl_inline size_t constant_time_msb_s(size_t a)
1177d004720Schristos {
1187d004720Schristos return 0 - (a >> (sizeof(a) * 8 - 1));
1197d004720Schristos }
1207d004720Schristos
constant_time_lt(unsigned int a,unsigned int b)1217d004720Schristos static ossl_inline unsigned int constant_time_lt(unsigned int a,
1227d004720Schristos unsigned int b)
1237d004720Schristos {
1247d004720Schristos return constant_time_msb(a ^ ((a ^ b) | ((a - b) ^ b)));
1257d004720Schristos }
1267d004720Schristos
constant_time_lt_s(size_t a,size_t b)1277d004720Schristos static ossl_inline size_t constant_time_lt_s(size_t a, size_t b)
1287d004720Schristos {
1297d004720Schristos return constant_time_msb_s(a ^ ((a ^ b) | ((a - b) ^ b)));
1307d004720Schristos }
1317d004720Schristos
constant_time_lt_8(unsigned int a,unsigned int b)1327d004720Schristos static ossl_inline unsigned char constant_time_lt_8(unsigned int a,
1337d004720Schristos unsigned int b)
1347d004720Schristos {
1357d004720Schristos return (unsigned char)constant_time_lt(a, b);
1367d004720Schristos }
1377d004720Schristos
constant_time_lt_64(uint64_t a,uint64_t b)1387d004720Schristos static ossl_inline uint64_t constant_time_lt_64(uint64_t a, uint64_t b)
1397d004720Schristos {
1407d004720Schristos return constant_time_msb_64(a ^ ((a ^ b) | ((a - b) ^ b)));
1417d004720Schristos }
1427d004720Schristos
143*0e2e28bcSchristos #ifdef BN_ULONG
constant_time_msb_bn(BN_ULONG a)144*0e2e28bcSchristos static ossl_inline BN_ULONG constant_time_msb_bn(BN_ULONG a)
145*0e2e28bcSchristos {
146*0e2e28bcSchristos return 0 - (a >> (sizeof(a) * 8 - 1));
147*0e2e28bcSchristos }
148*0e2e28bcSchristos
constant_time_lt_bn(BN_ULONG a,BN_ULONG b)149*0e2e28bcSchristos static ossl_inline BN_ULONG constant_time_lt_bn(BN_ULONG a, BN_ULONG b)
150*0e2e28bcSchristos {
151*0e2e28bcSchristos return constant_time_msb_bn(a ^ ((a ^ b) | ((a - b) ^ b)));
152*0e2e28bcSchristos }
153*0e2e28bcSchristos
constant_time_is_zero_bn(BN_ULONG a)154*0e2e28bcSchristos static ossl_inline BN_ULONG constant_time_is_zero_bn(BN_ULONG a)
155*0e2e28bcSchristos {
156*0e2e28bcSchristos return constant_time_msb_bn(~a & (a - 1));
157*0e2e28bcSchristos }
158*0e2e28bcSchristos
constant_time_eq_bn(BN_ULONG a,BN_ULONG b)159*0e2e28bcSchristos static ossl_inline BN_ULONG constant_time_eq_bn(BN_ULONG a,
160*0e2e28bcSchristos BN_ULONG b)
161*0e2e28bcSchristos {
162*0e2e28bcSchristos return constant_time_is_zero_bn(a ^ b);
163*0e2e28bcSchristos }
164*0e2e28bcSchristos #endif
165*0e2e28bcSchristos
constant_time_ge(unsigned int a,unsigned int b)1667d004720Schristos static ossl_inline unsigned int constant_time_ge(unsigned int a,
1677d004720Schristos unsigned int b)
1687d004720Schristos {
1697d004720Schristos return ~constant_time_lt(a, b);
1707d004720Schristos }
1717d004720Schristos
constant_time_ge_s(size_t a,size_t b)1727d004720Schristos static ossl_inline size_t constant_time_ge_s(size_t a, size_t b)
1737d004720Schristos {
1747d004720Schristos return ~constant_time_lt_s(a, b);
1757d004720Schristos }
1767d004720Schristos
constant_time_ge_8(unsigned int a,unsigned int b)1777d004720Schristos static ossl_inline unsigned char constant_time_ge_8(unsigned int a,
1787d004720Schristos unsigned int b)
1797d004720Schristos {
1807d004720Schristos return (unsigned char)constant_time_ge(a, b);
1817d004720Schristos }
1827d004720Schristos
constant_time_ge_8_s(size_t a,size_t b)1837d004720Schristos static ossl_inline unsigned char constant_time_ge_8_s(size_t a, size_t b)
1847d004720Schristos {
1857d004720Schristos return (unsigned char)constant_time_ge_s(a, b);
1867d004720Schristos }
1877d004720Schristos
constant_time_is_zero(unsigned int a)1887d004720Schristos static ossl_inline unsigned int constant_time_is_zero(unsigned int a)
1897d004720Schristos {
1907d004720Schristos return constant_time_msb(~a & (a - 1));
1917d004720Schristos }
1927d004720Schristos
constant_time_is_zero_s(size_t a)1937d004720Schristos static ossl_inline size_t constant_time_is_zero_s(size_t a)
1947d004720Schristos {
1957d004720Schristos return constant_time_msb_s(~a & (a - 1));
1967d004720Schristos }
1977d004720Schristos
constant_time_is_zero_8(unsigned int a)1987d004720Schristos static ossl_inline unsigned char constant_time_is_zero_8(unsigned int a)
1997d004720Schristos {
2007d004720Schristos return (unsigned char)constant_time_is_zero(a);
2017d004720Schristos }
2027d004720Schristos
constant_time_is_zero_32(uint32_t a)2037d004720Schristos static ossl_inline uint32_t constant_time_is_zero_32(uint32_t a)
2047d004720Schristos {
2057d004720Schristos return constant_time_msb_32(~a & (a - 1));
2067d004720Schristos }
2077d004720Schristos
constant_time_is_zero_64(uint64_t a)208b0d17251Schristos static ossl_inline uint64_t constant_time_is_zero_64(uint64_t a)
209b0d17251Schristos {
210b0d17251Schristos return constant_time_msb_64(~a & (a - 1));
211b0d17251Schristos }
212b0d17251Schristos
constant_time_eq(unsigned int a,unsigned int b)2137d004720Schristos static ossl_inline unsigned int constant_time_eq(unsigned int a,
2147d004720Schristos unsigned int b)
2157d004720Schristos {
2167d004720Schristos return constant_time_is_zero(a ^ b);
2177d004720Schristos }
2187d004720Schristos
constant_time_eq_s(size_t a,size_t b)2197d004720Schristos static ossl_inline size_t constant_time_eq_s(size_t a, size_t b)
2207d004720Schristos {
2217d004720Schristos return constant_time_is_zero_s(a ^ b);
2227d004720Schristos }
2237d004720Schristos
constant_time_eq_8(unsigned int a,unsigned int b)2247d004720Schristos static ossl_inline unsigned char constant_time_eq_8(unsigned int a,
2257d004720Schristos unsigned int b)
2267d004720Schristos {
2277d004720Schristos return (unsigned char)constant_time_eq(a, b);
2287d004720Schristos }
2297d004720Schristos
constant_time_eq_8_s(size_t a,size_t b)2307d004720Schristos static ossl_inline unsigned char constant_time_eq_8_s(size_t a, size_t b)
2317d004720Schristos {
2327d004720Schristos return (unsigned char)constant_time_eq_s(a, b);
2337d004720Schristos }
2347d004720Schristos
constant_time_eq_int(int a,int b)2357d004720Schristos static ossl_inline unsigned int constant_time_eq_int(int a, int b)
2367d004720Schristos {
2377d004720Schristos return constant_time_eq((unsigned)(a), (unsigned)(b));
2387d004720Schristos }
2397d004720Schristos
constant_time_eq_int_8(int a,int b)2407d004720Schristos static ossl_inline unsigned char constant_time_eq_int_8(int a, int b)
2417d004720Schristos {
2427d004720Schristos return constant_time_eq_8((unsigned)(a), (unsigned)(b));
2437d004720Schristos }
2447d004720Schristos
2457d004720Schristos /*
2467d004720Schristos * Returns the value unmodified, but avoids optimizations.
2477d004720Schristos * The barriers prevent the compiler from narrowing down the
2487d004720Schristos * possible value range of the mask and ~mask in the select
2497d004720Schristos * statements, which avoids the recognition of the select
2507d004720Schristos * and turning it into a conditional load or branch.
2517d004720Schristos */
value_barrier(unsigned int a)2527d004720Schristos static ossl_inline unsigned int value_barrier(unsigned int a)
2537d004720Schristos {
2547d004720Schristos #if !defined(OPENSSL_NO_ASM) && defined(__GNUC__)
2557d004720Schristos unsigned int r;
2567d004720Schristos __asm__("" : "=r"(r) : "0"(a));
2577d004720Schristos #else
2587d004720Schristos volatile unsigned int r = a;
2597d004720Schristos #endif
2607d004720Schristos return r;
2617d004720Schristos }
2627d004720Schristos
2637d004720Schristos /* Convenience method for uint32_t. */
value_barrier_32(uint32_t a)2647d004720Schristos static ossl_inline uint32_t value_barrier_32(uint32_t a)
2657d004720Schristos {
2667d004720Schristos #if !defined(OPENSSL_NO_ASM) && defined(__GNUC__)
2677d004720Schristos uint32_t r;
2687d004720Schristos __asm__("" : "=r"(r) : "0"(a));
2697d004720Schristos #else
2707d004720Schristos volatile uint32_t r = a;
2717d004720Schristos #endif
2727d004720Schristos return r;
2737d004720Schristos }
2747d004720Schristos
2757d004720Schristos /* Convenience method for uint64_t. */
value_barrier_64(uint64_t a)2767d004720Schristos static ossl_inline uint64_t value_barrier_64(uint64_t a)
2777d004720Schristos {
2787d004720Schristos #if !defined(OPENSSL_NO_ASM) && defined(__GNUC__)
2797d004720Schristos uint64_t r;
2807d004720Schristos __asm__("" : "=r"(r) : "0"(a));
2817d004720Schristos #else
2827d004720Schristos volatile uint64_t r = a;
2837d004720Schristos #endif
2847d004720Schristos return r;
2857d004720Schristos }
2867d004720Schristos
2877d004720Schristos /* Convenience method for size_t. */
value_barrier_s(size_t a)2887d004720Schristos static ossl_inline size_t value_barrier_s(size_t a)
2897d004720Schristos {
2907d004720Schristos #if !defined(OPENSSL_NO_ASM) && defined(__GNUC__)
2917d004720Schristos size_t r;
2927d004720Schristos __asm__("" : "=r"(r) : "0"(a));
2937d004720Schristos #else
2947d004720Schristos volatile size_t r = a;
2957d004720Schristos #endif
2967d004720Schristos return r;
2977d004720Schristos }
2987d004720Schristos
constant_time_select(unsigned int mask,unsigned int a,unsigned int b)2997d004720Schristos static ossl_inline unsigned int constant_time_select(unsigned int mask,
3007d004720Schristos unsigned int a,
3017d004720Schristos unsigned int b)
3027d004720Schristos {
3037d004720Schristos return (value_barrier(mask) & a) | (value_barrier(~mask) & b);
3047d004720Schristos }
3057d004720Schristos
constant_time_select_s(size_t mask,size_t a,size_t b)3067d004720Schristos static ossl_inline size_t constant_time_select_s(size_t mask,
3077d004720Schristos size_t a,
3087d004720Schristos size_t b)
3097d004720Schristos {
3107d004720Schristos return (value_barrier_s(mask) & a) | (value_barrier_s(~mask) & b);
3117d004720Schristos }
3127d004720Schristos
constant_time_select_8(unsigned char mask,unsigned char a,unsigned char b)3137d004720Schristos static ossl_inline unsigned char constant_time_select_8(unsigned char mask,
3147d004720Schristos unsigned char a,
3157d004720Schristos unsigned char b)
3167d004720Schristos {
3177d004720Schristos return (unsigned char)constant_time_select(mask, a, b);
3187d004720Schristos }
3197d004720Schristos
constant_time_select_int(unsigned int mask,int a,int b)3207d004720Schristos static ossl_inline int constant_time_select_int(unsigned int mask, int a,
3217d004720Schristos int b)
3227d004720Schristos {
3237d004720Schristos return (int)constant_time_select(mask, (unsigned)(a), (unsigned)(b));
3247d004720Schristos }
3257d004720Schristos
constant_time_select_int_s(size_t mask,int a,int b)3267d004720Schristos static ossl_inline int constant_time_select_int_s(size_t mask, int a, int b)
3277d004720Schristos {
3287d004720Schristos return (int)constant_time_select((unsigned)mask, (unsigned)(a),
3297d004720Schristos (unsigned)(b));
3307d004720Schristos }
3317d004720Schristos
constant_time_select_32(uint32_t mask,uint32_t a,uint32_t b)3327d004720Schristos static ossl_inline uint32_t constant_time_select_32(uint32_t mask, uint32_t a,
3337d004720Schristos uint32_t b)
3347d004720Schristos {
3357d004720Schristos return (value_barrier_32(mask) & a) | (value_barrier_32(~mask) & b);
3367d004720Schristos }
3377d004720Schristos
constant_time_select_64(uint64_t mask,uint64_t a,uint64_t b)3387d004720Schristos static ossl_inline uint64_t constant_time_select_64(uint64_t mask, uint64_t a,
3397d004720Schristos uint64_t b)
3407d004720Schristos {
3417d004720Schristos return (value_barrier_64(mask) & a) | (value_barrier_64(~mask) & b);
3427d004720Schristos }
3437d004720Schristos
3447d004720Schristos /*
3457d004720Schristos * mask must be 0xFFFFFFFF or 0x00000000.
3467d004720Schristos *
3477d004720Schristos * if (mask) {
3487d004720Schristos * uint32_t tmp = *a;
3497d004720Schristos *
3507d004720Schristos * *a = *b;
3517d004720Schristos * *b = tmp;
3527d004720Schristos * }
3537d004720Schristos */
constant_time_cond_swap_32(uint32_t mask,uint32_t * a,uint32_t * b)3547d004720Schristos static ossl_inline void constant_time_cond_swap_32(uint32_t mask, uint32_t *a,
3557d004720Schristos uint32_t *b)
3567d004720Schristos {
3577d004720Schristos uint32_t xor = *a ^ *b;
3587d004720Schristos
3597d004720Schristos xor &= mask;
3607d004720Schristos *a ^= xor;
3617d004720Schristos *b ^= xor;
3627d004720Schristos }
3637d004720Schristos
3647d004720Schristos /*
3657d004720Schristos * mask must be 0xFFFFFFFF or 0x00000000.
3667d004720Schristos *
3677d004720Schristos * if (mask) {
3687d004720Schristos * uint64_t tmp = *a;
3697d004720Schristos *
3707d004720Schristos * *a = *b;
3717d004720Schristos * *b = tmp;
3727d004720Schristos * }
3737d004720Schristos */
constant_time_cond_swap_64(uint64_t mask,uint64_t * a,uint64_t * b)3747d004720Schristos static ossl_inline void constant_time_cond_swap_64(uint64_t mask, uint64_t *a,
3757d004720Schristos uint64_t *b)
3767d004720Schristos {
3777d004720Schristos uint64_t xor = *a ^ *b;
3787d004720Schristos
3797d004720Schristos xor &= mask;
3807d004720Schristos *a ^= xor;
3817d004720Schristos *b ^= xor;
3827d004720Schristos }
3837d004720Schristos
3847d004720Schristos /*
385b0d17251Schristos * mask must be 0xFF or 0x00.
386b0d17251Schristos * "constant time" is per len.
387b0d17251Schristos *
388b0d17251Schristos * if (mask) {
389b0d17251Schristos * unsigned char tmp[len];
390b0d17251Schristos *
391b0d17251Schristos * memcpy(tmp, a, len);
392b0d17251Schristos * memcpy(a, b);
393b0d17251Schristos * memcpy(b, tmp);
394b0d17251Schristos * }
395b0d17251Schristos */
constant_time_cond_swap_buff(unsigned char mask,unsigned char * a,unsigned char * b,size_t len)396b0d17251Schristos static ossl_inline void constant_time_cond_swap_buff(unsigned char mask,
397b0d17251Schristos unsigned char *a,
398b0d17251Schristos unsigned char *b,
399b0d17251Schristos size_t len)
400b0d17251Schristos {
401b0d17251Schristos size_t i;
402b0d17251Schristos unsigned char tmp;
403b0d17251Schristos
404b0d17251Schristos for (i = 0; i < len; i++) {
405b0d17251Schristos tmp = a[i] ^ b[i];
406b0d17251Schristos tmp &= mask;
407b0d17251Schristos a[i] ^= tmp;
408b0d17251Schristos b[i] ^= tmp;
409b0d17251Schristos }
410b0d17251Schristos }
411b0d17251Schristos
412b0d17251Schristos /*
4137d004720Schristos * table is a two dimensional array of bytes. Each row has rowsize elements.
4147d004720Schristos * Copies row number idx into out. rowsize and numrows are not considered
4157d004720Schristos * private.
4167d004720Schristos */
constant_time_lookup(void * out,const void * table,size_t rowsize,size_t numrows,size_t idx)4177d004720Schristos static ossl_inline void constant_time_lookup(void *out,
4187d004720Schristos const void *table,
4197d004720Schristos size_t rowsize,
4207d004720Schristos size_t numrows,
4217d004720Schristos size_t idx)
4227d004720Schristos {
4237d004720Schristos size_t i, j;
4247d004720Schristos const unsigned char *tablec = (const unsigned char *)table;
4257d004720Schristos unsigned char *outc = (unsigned char *)out;
4267d004720Schristos unsigned char mask;
4277d004720Schristos
4287d004720Schristos memset(out, 0, rowsize);
4297d004720Schristos
4307d004720Schristos /* Note idx may underflow - but that is well defined */
4317d004720Schristos for (i = 0; i < numrows; i++, idx--) {
4327d004720Schristos mask = (unsigned char)constant_time_is_zero_s(idx);
4337d004720Schristos for (j = 0; j < rowsize; j++)
4347d004720Schristos *(outc + j) |= constant_time_select_8(mask, *(tablec++), 0);
4357d004720Schristos }
4367d004720Schristos }
4377d004720Schristos
4387d004720Schristos /*
4397d004720Schristos * Expected usage pattern is to unconditionally set error and then
4407d004720Schristos * wipe it if there was no actual error. |clear| is 1 or 0.
4417d004720Schristos */
4427d004720Schristos void err_clear_last_constant_time(int clear);
4437d004720Schristos
4447d004720Schristos #endif /* OSSL_INTERNAL_CONSTANT_TIME_H */
445