/src/openssl/crypto/constant_time_locl.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* crypto/constant_time_locl.h */ |
2 | | /*- |
3 | | * Utilities for constant-time cryptography. |
4 | | * |
5 | | * Author: Emilia Kasper (emilia@openssl.org) |
6 | | * Based on previous work by Bodo Moeller, Emilia Kasper, Adam Langley |
7 | | * (Google). |
8 | | * ==================================================================== |
9 | | * Copyright (c) 2014 The OpenSSL Project. All rights reserved. |
10 | | * |
11 | | * Redistribution and use in source and binary forms, with or without |
12 | | * modification, are permitted provided that the following conditions |
13 | | * are met: |
14 | | * 1. Redistributions of source code must retain the copyright |
15 | | * notice, this list of conditions and the following disclaimer. |
16 | | * 2. Redistributions in binary form must reproduce the above copyright |
17 | | * notice, this list of conditions and the following disclaimer in the |
18 | | * documentation and/or other materials provided with the distribution. |
19 | | * 3. All advertising materials mentioning features or use of this software |
20 | | * must display the following acknowledgement: |
21 | | * "This product includes cryptographic software written by |
22 | | * Eric Young (eay@cryptsoft.com)" |
23 | | * The word 'cryptographic' can be left out if the rouines from the library |
24 | | * being used are not cryptographic related :-). |
25 | | * 4. If you include any Windows specific code (or a derivative thereof) from |
26 | | * the apps directory (application code) you must include an acknowledgement: |
27 | | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" |
28 | | * |
29 | | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND |
30 | | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
31 | | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
32 | | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
33 | | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
34 | | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
35 | | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
36 | | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
37 | | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
38 | | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
39 | | * SUCH DAMAGE. |
40 | | * |
41 | | * The licence and distribution terms for any publically available version or |
42 | | * derivative of this code cannot be changed. i.e. this code cannot simply be |
43 | | * copied and put under another distribution licence |
44 | | * [including the GNU Public Licence.] |
45 | | */ |
46 | | |
47 | | #ifndef HEADER_CONSTANT_TIME_LOCL_H |
48 | | # define HEADER_CONSTANT_TIME_LOCL_H |
49 | | |
50 | | # include "e_os.h" /* For 'inline' */ |
51 | | |
52 | | #ifdef __cplusplus |
53 | | extern "C" { |
54 | | #endif |
55 | | |
56 | | /*- |
57 | | * The boolean methods return a bitmask of all ones (0xff...f) for true |
58 | | * and 0 for false. This is useful for choosing a value based on the result |
59 | | * of a conditional in constant time. For example, |
60 | | * |
61 | | * if (a < b) { |
62 | | * c = a; |
63 | | * } else { |
64 | | * c = b; |
65 | | * } |
66 | | * |
67 | | * can be written as |
68 | | * |
69 | | * unsigned int lt = constant_time_lt(a, b); |
70 | | * c = constant_time_select(lt, a, b); |
71 | | */ |
72 | | |
73 | | /* |
74 | | * Returns the given value with the MSB copied to all the other |
75 | | * bits. Uses the fact that arithmetic shift shifts-in the sign bit. |
76 | | * However, this is not ensured by the C standard so you may need to |
77 | | * replace this with something else on odd CPUs. |
78 | | */ |
79 | | static inline unsigned int constant_time_msb(unsigned int a); |
80 | | |
81 | | /* |
82 | | * Returns 0xff..f if a < b and 0 otherwise. |
83 | | */ |
84 | | static inline unsigned int constant_time_lt(unsigned int a, unsigned int b); |
85 | | /* Convenience method for getting an 8-bit mask. */ |
86 | | static inline unsigned char constant_time_lt_8(unsigned int a, |
87 | | unsigned int b); |
88 | | |
89 | | /* |
90 | | * Returns 0xff..f if a >= b and 0 otherwise. |
91 | | */ |
92 | | static inline unsigned int constant_time_ge(unsigned int a, unsigned int b); |
93 | | /* Convenience method for getting an 8-bit mask. */ |
94 | | static inline unsigned char constant_time_ge_8(unsigned int a, |
95 | | unsigned int b); |
96 | | |
97 | | /* |
98 | | * Returns 0xff..f if a == 0 and 0 otherwise. |
99 | | */ |
100 | | static inline unsigned int constant_time_is_zero(unsigned int a); |
101 | | /* Convenience method for getting an 8-bit mask. */ |
102 | | static inline unsigned char constant_time_is_zero_8(unsigned int a); |
103 | | |
104 | | /* |
105 | | * Returns 0xff..f if a == b and 0 otherwise. |
106 | | */ |
107 | | static inline unsigned int constant_time_eq(unsigned int a, unsigned int b); |
108 | | /* Convenience method for getting an 8-bit mask. */ |
109 | | static inline unsigned char constant_time_eq_8(unsigned int a, |
110 | | unsigned int b); |
111 | | /* Signed integers. */ |
112 | | static inline unsigned int constant_time_eq_int(int a, int b); |
113 | | /* Convenience method for getting an 8-bit mask. */ |
114 | | static inline unsigned char constant_time_eq_int_8(int a, int b); |
115 | | |
116 | | /*- |
117 | | * Returns (mask & a) | (~mask & b). |
118 | | * |
119 | | * When |mask| is all 1s or all 0s (as returned by the methods above), |
120 | | * the select methods return either |a| (if |mask| is nonzero) or |b| |
121 | | * (if |mask| is zero). |
122 | | */ |
123 | | static inline unsigned int constant_time_select(unsigned int mask, |
124 | | unsigned int a, |
125 | | unsigned int b); |
126 | | /* Convenience method for unsigned chars. */ |
127 | | static inline unsigned char constant_time_select_8(unsigned char mask, |
128 | | unsigned char a, |
129 | | unsigned char b); |
130 | | /* Convenience method for signed integers. */ |
131 | | static inline int constant_time_select_int(unsigned int mask, int a, int b); |
132 | | |
133 | | static inline unsigned int constant_time_msb(unsigned int a) |
134 | 0 | { |
135 | 0 | return 0 - (a >> (sizeof(a) * 8 - 1)); |
136 | 0 | } Unexecuted instantiation: s3_cbc.c:constant_time_msb Unexecuted instantiation: s3_srvr.c:constant_time_msb |
137 | | |
138 | | static inline unsigned int constant_time_lt(unsigned int a, unsigned int b) |
139 | 0 | { |
140 | 0 | return constant_time_msb(a ^ ((a ^ b) | ((a - b) ^ b))); |
141 | 0 | } Unexecuted instantiation: s3_cbc.c:constant_time_lt Unexecuted instantiation: s3_srvr.c:constant_time_lt |
142 | | |
143 | | static inline unsigned char constant_time_lt_8(unsigned int a, unsigned int b) |
144 | 0 | { |
145 | 0 | return (unsigned char)(constant_time_lt(a, b)); |
146 | 0 | } Unexecuted instantiation: s3_cbc.c:constant_time_lt_8 Unexecuted instantiation: s3_srvr.c:constant_time_lt_8 |
147 | | |
148 | | static inline unsigned int constant_time_ge(unsigned int a, unsigned int b) |
149 | 0 | { |
150 | 0 | return ~constant_time_lt(a, b); |
151 | 0 | } Unexecuted instantiation: s3_cbc.c:constant_time_ge Unexecuted instantiation: s3_srvr.c:constant_time_ge |
152 | | |
153 | | static inline unsigned char constant_time_ge_8(unsigned int a, unsigned int b) |
154 | 0 | { |
155 | 0 | return (unsigned char)(constant_time_ge(a, b)); |
156 | 0 | } Unexecuted instantiation: s3_cbc.c:constant_time_ge_8 Unexecuted instantiation: s3_srvr.c:constant_time_ge_8 |
157 | | |
158 | | static inline unsigned int constant_time_is_zero(unsigned int a) |
159 | 0 | { |
160 | 0 | return constant_time_msb(~a & (a - 1)); |
161 | 0 | } Unexecuted instantiation: s3_cbc.c:constant_time_is_zero Unexecuted instantiation: s3_srvr.c:constant_time_is_zero |
162 | | |
163 | | static inline unsigned char constant_time_is_zero_8(unsigned int a) |
164 | 0 | { |
165 | 0 | return (unsigned char)(constant_time_is_zero(a)); |
166 | 0 | } Unexecuted instantiation: s3_cbc.c:constant_time_is_zero_8 Unexecuted instantiation: s3_srvr.c:constant_time_is_zero_8 |
167 | | |
168 | | static inline unsigned int constant_time_eq(unsigned int a, unsigned int b) |
169 | 0 | { |
170 | 0 | return constant_time_is_zero(a ^ b); |
171 | 0 | } Unexecuted instantiation: s3_cbc.c:constant_time_eq Unexecuted instantiation: s3_srvr.c:constant_time_eq |
172 | | |
173 | | static inline unsigned char constant_time_eq_8(unsigned int a, unsigned int b) |
174 | 0 | { |
175 | 0 | return (unsigned char)(constant_time_eq(a, b)); |
176 | 0 | } Unexecuted instantiation: s3_cbc.c:constant_time_eq_8 Unexecuted instantiation: s3_srvr.c:constant_time_eq_8 |
177 | | |
178 | | static inline unsigned int constant_time_eq_int(int a, int b) |
179 | 0 | { |
180 | 0 | return constant_time_eq((unsigned)(a), (unsigned)(b)); |
181 | 0 | } Unexecuted instantiation: s3_cbc.c:constant_time_eq_int Unexecuted instantiation: s3_srvr.c:constant_time_eq_int |
182 | | |
183 | | static inline unsigned char constant_time_eq_int_8(int a, int b) |
184 | 0 | { |
185 | 0 | return constant_time_eq_8((unsigned)(a), (unsigned)(b)); |
186 | 0 | } Unexecuted instantiation: s3_cbc.c:constant_time_eq_int_8 Unexecuted instantiation: s3_srvr.c:constant_time_eq_int_8 |
187 | | |
188 | | static inline unsigned int constant_time_select(unsigned int mask, |
189 | | unsigned int a, |
190 | | unsigned int b) |
191 | 0 | { |
192 | 0 | return (mask & a) | (~mask & b); |
193 | 0 | } Unexecuted instantiation: s3_cbc.c:constant_time_select Unexecuted instantiation: s3_srvr.c:constant_time_select |
194 | | |
195 | | static inline unsigned char constant_time_select_8(unsigned char mask, |
196 | | unsigned char a, |
197 | | unsigned char b) |
198 | 0 | { |
199 | 0 | return (unsigned char)(constant_time_select(mask, a, b)); |
200 | 0 | } Unexecuted instantiation: s3_cbc.c:constant_time_select_8 Unexecuted instantiation: s3_srvr.c:constant_time_select_8 |
201 | | |
202 | | static inline int constant_time_select_int(unsigned int mask, int a, int b) |
203 | 0 | { |
204 | 0 | return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b))); |
205 | 0 | } Unexecuted instantiation: s3_cbc.c:constant_time_select_int Unexecuted instantiation: s3_srvr.c:constant_time_select_int |
206 | | |
207 | | #ifdef __cplusplus |
208 | | } |
209 | | #endif |
210 | | |
211 | | #endif /* HEADER_CONSTANT_TIME_LOCL_H */ |