Coverage Report

Created: 2025-08-26 06:43

/src/opensc/src/common/constant-time.h
Line
Count
Source (jump to first uncovered line)
1
/* Original source: https://github.com/openssl/openssl/blob/9890cc42daff5e2d0cad01ac4bf78c391f599a6e/include/internal/constant_time.h */
2
3
#ifndef CONSTANT_TIME_H
4
#define CONSTANT_TIME_H
5
6
#include <stdlib.h>
7
#include <string.h>
8
9
#if !defined(inline)
10
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
11
#define constant_inline inline
12
#elif defined(__GNUC__) && __GNUC__ >= 2
13
#elif defined(__GNUC__) && __GNUC__ >= 2
14
#elif defined(_MSC_VER)
15
#define constant_inline __inline
16
#else
17
#define constant_inline
18
#endif
19
#else            /* use what caller wants as inline  may be from config.h */
20
#define constant_inline inline /* inline */
21
#endif
22
23
/*-
24
 * The boolean methods return a bitmask of all ones (0xff...f) for true
25
 * and 0 for false. For example,
26
 *      if (a < b) {
27
 *        c = a;
28
 *      } else {
29
 *        c = b;
30
 *      }
31
 * can be written as
32
 *      unsigned int lt = constant_time_lt(a, b);
33
 *      c = constant_time_select(lt, a, b);
34
 */
35
36
static constant_inline unsigned int
37
value_barrier(unsigned int a)
38
0
{
39
0
  volatile unsigned int r = a;
40
0
  return r;
41
0
}
42
43
static constant_inline size_t
44
value_barrier_s(size_t a)
45
0
{
46
0
  volatile size_t r = a;
47
0
  return r;
48
0
}
49
50
/* MSB */
51
static constant_inline size_t
52
constant_time_msb_s(size_t a)
53
0
{
54
0
  return 0 - (a >> (sizeof(a) * 8 - 1));
55
0
}
56
57
static constant_inline unsigned int
58
constant_time_msb(unsigned int a)
59
0
{
60
0
  return 0 - (a >> (sizeof(a) * 8 - 1));
61
0
}
62
63
/* Select */
64
static constant_inline unsigned int
65
constant_time_select(unsigned int mask, unsigned int a, unsigned int b)
66
0
{
67
0
  return (value_barrier(mask) & a) | (value_barrier(~mask) & b);
68
0
}
69
70
static constant_inline unsigned char
71
constant_time_select_8(unsigned char mask, unsigned char a, unsigned char b)
72
0
{
73
0
  return (unsigned char)constant_time_select(mask, a, b);
74
0
}
75
76
static constant_inline size_t
77
constant_time_select_s(size_t mask, size_t a, size_t b)
78
0
{
79
0
  return (value_barrier_s(mask) & a) | (value_barrier_s(~mask) & b);
80
0
}
81
82
/* Zero */
83
static constant_inline unsigned int
84
constant_time_is_zero(unsigned int a)
85
0
{
86
0
  return constant_time_msb(~a & (a - 1));
87
0
}
88
89
static constant_inline size_t
90
constant_time_is_zero_s(size_t a)
91
0
{
92
0
  return constant_time_msb_s(~a & (a - 1));
93
0
}
94
95
/* Comparison*/
96
static constant_inline size_t
97
constant_time_lt_s(size_t a, size_t b)
98
0
{
99
0
  return constant_time_msb_s(a ^ ((a ^ b) | ((a - b) ^ b)));
100
0
}
101
102
static constant_inline unsigned int
103
constant_time_lt(unsigned int a, unsigned int b)
104
0
{
105
0
  return constant_time_msb(a ^ ((a ^ b) | ((a - b) ^ b)));
106
0
}
107
108
static constant_inline unsigned int
109
constant_time_ge(unsigned int a, unsigned int b)
110
0
{
111
0
  return ~constant_time_lt(a, b);
112
0
}
113
114
/* Equality*/
115
116
static constant_inline unsigned int
117
constant_time_eq(unsigned int a, unsigned int b)
118
0
{
119
0
  return constant_time_is_zero(a ^ b);
120
0
}
121
122
static constant_inline size_t
123
constant_time_eq_s(size_t a, size_t b)
124
0
{
125
0
  return constant_time_is_zero_s(a ^ b);
126
0
}
127
128
static constant_inline unsigned int
129
constant_time_eq_i(int a, int b)
130
0
{
131
0
  return constant_time_eq((unsigned int)a, (unsigned int)b);
132
0
}
133
134
#endif /* CONSTANT_TIME_H */