/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 */ |