xref: /netbsd-src/crypto/external/bsd/openssl.old/dist/include/internal/constant_time.h (revision 4724848cf0da353df257f730694b7882798e5daf)
1*4724848cSchristos /*
2*4724848cSchristos  * Copyright 2014-2019 The OpenSSL Project Authors. All Rights Reserved.
3*4724848cSchristos  *
4*4724848cSchristos  * Licensed under the OpenSSL license (the "License").  You may not use
5*4724848cSchristos  * this file except in compliance with the License.  You can obtain a copy
6*4724848cSchristos  * in the file LICENSE in the source distribution or at
7*4724848cSchristos  * https://www.openssl.org/source/license.html
8*4724848cSchristos  */
9*4724848cSchristos 
10*4724848cSchristos #ifndef OSSL_INTERNAL_CONSTANT_TIME_H
11*4724848cSchristos # define OSSL_INTERNAL_CONSTANT_TIME_H
12*4724848cSchristos 
13*4724848cSchristos # include <stdlib.h>
14*4724848cSchristos # include <string.h>
15*4724848cSchristos # include <openssl/e_os2.h>              /* For 'ossl_inline' */
16*4724848cSchristos 
17*4724848cSchristos /*-
18*4724848cSchristos  * The boolean methods return a bitmask of all ones (0xff...f) for true
19*4724848cSchristos  * and 0 for false. This is useful for choosing a value based on the result
20*4724848cSchristos  * of a conditional in constant time. For example,
21*4724848cSchristos  *      if (a < b) {
22*4724848cSchristos  *        c = a;
23*4724848cSchristos  *      } else {
24*4724848cSchristos  *        c = b;
25*4724848cSchristos  *      }
26*4724848cSchristos  * can be written as
27*4724848cSchristos  *      unsigned int lt = constant_time_lt(a, b);
28*4724848cSchristos  *      c = constant_time_select(lt, a, b);
29*4724848cSchristos  */
30*4724848cSchristos 
31*4724848cSchristos /* Returns the given value with the MSB copied to all the other bits. */
32*4724848cSchristos static ossl_inline unsigned int constant_time_msb(unsigned int a);
33*4724848cSchristos /* Convenience method for uint32_t. */
34*4724848cSchristos static ossl_inline uint32_t constant_time_msb_32(uint32_t a);
35*4724848cSchristos /* Convenience method for uint64_t. */
36*4724848cSchristos static ossl_inline uint64_t constant_time_msb_64(uint64_t a);
37*4724848cSchristos 
38*4724848cSchristos /* Returns 0xff..f if a < b and 0 otherwise. */
39*4724848cSchristos static ossl_inline unsigned int constant_time_lt(unsigned int a,
40*4724848cSchristos                                                  unsigned int b);
41*4724848cSchristos /* Convenience method for getting an 8-bit mask. */
42*4724848cSchristos static ossl_inline unsigned char constant_time_lt_8(unsigned int a,
43*4724848cSchristos                                                     unsigned int b);
44*4724848cSchristos /* Convenience method for uint64_t. */
45*4724848cSchristos static ossl_inline uint64_t constant_time_lt_64(uint64_t a, uint64_t b);
46*4724848cSchristos 
47*4724848cSchristos /* Returns 0xff..f if a >= b and 0 otherwise. */
48*4724848cSchristos static ossl_inline unsigned int constant_time_ge(unsigned int a,
49*4724848cSchristos                                                  unsigned int b);
50*4724848cSchristos /* Convenience method for getting an 8-bit mask. */
51*4724848cSchristos static ossl_inline unsigned char constant_time_ge_8(unsigned int a,
52*4724848cSchristos                                                     unsigned int b);
53*4724848cSchristos 
54*4724848cSchristos /* Returns 0xff..f if a == 0 and 0 otherwise. */
55*4724848cSchristos static ossl_inline unsigned int constant_time_is_zero(unsigned int a);
56*4724848cSchristos /* Convenience method for getting an 8-bit mask. */
57*4724848cSchristos static ossl_inline unsigned char constant_time_is_zero_8(unsigned int a);
58*4724848cSchristos /* Convenience method for getting a 32-bit mask. */
59*4724848cSchristos static ossl_inline uint32_t constant_time_is_zero_32(uint32_t a);
60*4724848cSchristos 
61*4724848cSchristos /* Returns 0xff..f if a == b and 0 otherwise. */
62*4724848cSchristos static ossl_inline unsigned int constant_time_eq(unsigned int a,
63*4724848cSchristos                                                  unsigned int b);
64*4724848cSchristos /* Convenience method for getting an 8-bit mask. */
65*4724848cSchristos static ossl_inline unsigned char constant_time_eq_8(unsigned int a,
66*4724848cSchristos                                                     unsigned int b);
67*4724848cSchristos /* Signed integers. */
68*4724848cSchristos static ossl_inline unsigned int constant_time_eq_int(int a, int b);
69*4724848cSchristos /* Convenience method for getting an 8-bit mask. */
70*4724848cSchristos static ossl_inline unsigned char constant_time_eq_int_8(int a, int b);
71*4724848cSchristos 
72*4724848cSchristos /*-
73*4724848cSchristos  * Returns (mask & a) | (~mask & b).
74*4724848cSchristos  *
75*4724848cSchristos  * When |mask| is all 1s or all 0s (as returned by the methods above),
76*4724848cSchristos  * the select methods return either |a| (if |mask| is nonzero) or |b|
77*4724848cSchristos  * (if |mask| is zero).
78*4724848cSchristos  */
79*4724848cSchristos static ossl_inline unsigned int constant_time_select(unsigned int mask,
80*4724848cSchristos                                                      unsigned int a,
81*4724848cSchristos                                                      unsigned int b);
82*4724848cSchristos /* Convenience method for unsigned chars. */
83*4724848cSchristos static ossl_inline unsigned char constant_time_select_8(unsigned char mask,
84*4724848cSchristos                                                         unsigned char a,
85*4724848cSchristos                                                         unsigned char b);
86*4724848cSchristos 
87*4724848cSchristos /* Convenience method for uint32_t. */
88*4724848cSchristos static ossl_inline uint32_t constant_time_select_32(uint32_t mask, uint32_t a,
89*4724848cSchristos                                                     uint32_t b);
90*4724848cSchristos 
91*4724848cSchristos /* Convenience method for uint64_t. */
92*4724848cSchristos static ossl_inline uint64_t constant_time_select_64(uint64_t mask, uint64_t a,
93*4724848cSchristos                                                     uint64_t b);
94*4724848cSchristos /* Convenience method for signed integers. */
95*4724848cSchristos static ossl_inline int constant_time_select_int(unsigned int mask, int a,
96*4724848cSchristos                                                 int b);
97*4724848cSchristos 
98*4724848cSchristos 
constant_time_msb(unsigned int a)99*4724848cSchristos static ossl_inline unsigned int constant_time_msb(unsigned int a)
100*4724848cSchristos {
101*4724848cSchristos     return 0 - (a >> (sizeof(a) * 8 - 1));
102*4724848cSchristos }
103*4724848cSchristos 
104*4724848cSchristos 
constant_time_msb_32(uint32_t a)105*4724848cSchristos static ossl_inline uint32_t constant_time_msb_32(uint32_t a)
106*4724848cSchristos {
107*4724848cSchristos     return 0 - (a >> 31);
108*4724848cSchristos }
109*4724848cSchristos 
constant_time_msb_64(uint64_t a)110*4724848cSchristos static ossl_inline uint64_t constant_time_msb_64(uint64_t a)
111*4724848cSchristos {
112*4724848cSchristos     return 0 - (a >> 63);
113*4724848cSchristos }
114*4724848cSchristos 
constant_time_msb_s(size_t a)115*4724848cSchristos static ossl_inline size_t constant_time_msb_s(size_t a)
116*4724848cSchristos {
117*4724848cSchristos     return 0 - (a >> (sizeof(a) * 8 - 1));
118*4724848cSchristos }
119*4724848cSchristos 
constant_time_lt(unsigned int a,unsigned int b)120*4724848cSchristos static ossl_inline unsigned int constant_time_lt(unsigned int a,
121*4724848cSchristos                                                  unsigned int b)
122*4724848cSchristos {
123*4724848cSchristos     return constant_time_msb(a ^ ((a ^ b) | ((a - b) ^ b)));
124*4724848cSchristos }
125*4724848cSchristos 
constant_time_lt_s(size_t a,size_t b)126*4724848cSchristos static ossl_inline size_t constant_time_lt_s(size_t a, size_t b)
127*4724848cSchristos {
128*4724848cSchristos     return constant_time_msb_s(a ^ ((a ^ b) | ((a - b) ^ b)));
129*4724848cSchristos }
130*4724848cSchristos 
constant_time_lt_8(unsigned int a,unsigned int b)131*4724848cSchristos static ossl_inline unsigned char constant_time_lt_8(unsigned int a,
132*4724848cSchristos                                                     unsigned int b)
133*4724848cSchristos {
134*4724848cSchristos     return (unsigned char)constant_time_lt(a, b);
135*4724848cSchristos }
136*4724848cSchristos 
constant_time_lt_64(uint64_t a,uint64_t b)137*4724848cSchristos static ossl_inline uint64_t constant_time_lt_64(uint64_t a, uint64_t b)
138*4724848cSchristos {
139*4724848cSchristos     return constant_time_msb_64(a ^ ((a ^ b) | ((a - b) ^ b)));
140*4724848cSchristos }
141*4724848cSchristos 
constant_time_ge(unsigned int a,unsigned int b)142*4724848cSchristos static ossl_inline unsigned int constant_time_ge(unsigned int a,
143*4724848cSchristos                                                  unsigned int b)
144*4724848cSchristos {
145*4724848cSchristos     return ~constant_time_lt(a, b);
146*4724848cSchristos }
147*4724848cSchristos 
constant_time_ge_s(size_t a,size_t b)148*4724848cSchristos static ossl_inline size_t constant_time_ge_s(size_t a, size_t b)
149*4724848cSchristos {
150*4724848cSchristos     return ~constant_time_lt_s(a, b);
151*4724848cSchristos }
152*4724848cSchristos 
constant_time_ge_8(unsigned int a,unsigned int b)153*4724848cSchristos static ossl_inline unsigned char constant_time_ge_8(unsigned int a,
154*4724848cSchristos                                                     unsigned int b)
155*4724848cSchristos {
156*4724848cSchristos     return (unsigned char)constant_time_ge(a, b);
157*4724848cSchristos }
158*4724848cSchristos 
constant_time_ge_8_s(size_t a,size_t b)159*4724848cSchristos static ossl_inline unsigned char constant_time_ge_8_s(size_t a, size_t b)
160*4724848cSchristos {
161*4724848cSchristos     return (unsigned char)constant_time_ge_s(a, b);
162*4724848cSchristos }
163*4724848cSchristos 
constant_time_is_zero(unsigned int a)164*4724848cSchristos static ossl_inline unsigned int constant_time_is_zero(unsigned int a)
165*4724848cSchristos {
166*4724848cSchristos     return constant_time_msb(~a & (a - 1));
167*4724848cSchristos }
168*4724848cSchristos 
constant_time_is_zero_s(size_t a)169*4724848cSchristos static ossl_inline size_t constant_time_is_zero_s(size_t a)
170*4724848cSchristos {
171*4724848cSchristos     return constant_time_msb_s(~a & (a - 1));
172*4724848cSchristos }
173*4724848cSchristos 
constant_time_is_zero_8(unsigned int a)174*4724848cSchristos static ossl_inline unsigned char constant_time_is_zero_8(unsigned int a)
175*4724848cSchristos {
176*4724848cSchristos     return (unsigned char)constant_time_is_zero(a);
177*4724848cSchristos }
178*4724848cSchristos 
constant_time_is_zero_32(uint32_t a)179*4724848cSchristos static ossl_inline uint32_t constant_time_is_zero_32(uint32_t a)
180*4724848cSchristos {
181*4724848cSchristos     return constant_time_msb_32(~a & (a - 1));
182*4724848cSchristos }
183*4724848cSchristos 
constant_time_eq(unsigned int a,unsigned int b)184*4724848cSchristos static ossl_inline unsigned int constant_time_eq(unsigned int a,
185*4724848cSchristos                                                  unsigned int b)
186*4724848cSchristos {
187*4724848cSchristos     return constant_time_is_zero(a ^ b);
188*4724848cSchristos }
189*4724848cSchristos 
constant_time_eq_s(size_t a,size_t b)190*4724848cSchristos static ossl_inline size_t constant_time_eq_s(size_t a, size_t b)
191*4724848cSchristos {
192*4724848cSchristos     return constant_time_is_zero_s(a ^ b);
193*4724848cSchristos }
194*4724848cSchristos 
constant_time_eq_8(unsigned int a,unsigned int b)195*4724848cSchristos static ossl_inline unsigned char constant_time_eq_8(unsigned int a,
196*4724848cSchristos                                                     unsigned int b)
197*4724848cSchristos {
198*4724848cSchristos     return (unsigned char)constant_time_eq(a, b);
199*4724848cSchristos }
200*4724848cSchristos 
constant_time_eq_8_s(size_t a,size_t b)201*4724848cSchristos static ossl_inline unsigned char constant_time_eq_8_s(size_t a, size_t b)
202*4724848cSchristos {
203*4724848cSchristos     return (unsigned char)constant_time_eq_s(a, b);
204*4724848cSchristos }
205*4724848cSchristos 
constant_time_eq_int(int a,int b)206*4724848cSchristos static ossl_inline unsigned int constant_time_eq_int(int a, int b)
207*4724848cSchristos {
208*4724848cSchristos     return constant_time_eq((unsigned)(a), (unsigned)(b));
209*4724848cSchristos }
210*4724848cSchristos 
constant_time_eq_int_8(int a,int b)211*4724848cSchristos static ossl_inline unsigned char constant_time_eq_int_8(int a, int b)
212*4724848cSchristos {
213*4724848cSchristos     return constant_time_eq_8((unsigned)(a), (unsigned)(b));
214*4724848cSchristos }
215*4724848cSchristos 
216*4724848cSchristos /*
217*4724848cSchristos  * Returns the value unmodified, but avoids optimizations.
218*4724848cSchristos  * The barriers prevent the compiler from narrowing down the
219*4724848cSchristos  * possible value range of the mask and ~mask in the select
220*4724848cSchristos  * statements, which avoids the recognition of the select
221*4724848cSchristos  * and turning it into a conditional load or branch.
222*4724848cSchristos  */
value_barrier(unsigned int a)223*4724848cSchristos static ossl_inline unsigned int value_barrier(unsigned int a)
224*4724848cSchristos {
225*4724848cSchristos #if !defined(OPENSSL_NO_ASM) && defined(__GNUC__)
226*4724848cSchristos     unsigned int r;
227*4724848cSchristos     __asm__("" : "=r"(r) : "0"(a));
228*4724848cSchristos #else
229*4724848cSchristos     volatile unsigned int r = a;
230*4724848cSchristos #endif
231*4724848cSchristos     return r;
232*4724848cSchristos }
233*4724848cSchristos 
234*4724848cSchristos /* Convenience method for uint32_t. */
value_barrier_32(uint32_t a)235*4724848cSchristos static ossl_inline uint32_t value_barrier_32(uint32_t a)
236*4724848cSchristos {
237*4724848cSchristos #if !defined(OPENSSL_NO_ASM) && defined(__GNUC__)
238*4724848cSchristos     uint32_t r;
239*4724848cSchristos     __asm__("" : "=r"(r) : "0"(a));
240*4724848cSchristos #else
241*4724848cSchristos     volatile uint32_t r = a;
242*4724848cSchristos #endif
243*4724848cSchristos     return r;
244*4724848cSchristos }
245*4724848cSchristos 
246*4724848cSchristos /* Convenience method for uint64_t. */
value_barrier_64(uint64_t a)247*4724848cSchristos static ossl_inline uint64_t value_barrier_64(uint64_t a)
248*4724848cSchristos {
249*4724848cSchristos #if !defined(OPENSSL_NO_ASM) && defined(__GNUC__)
250*4724848cSchristos     uint64_t r;
251*4724848cSchristos     __asm__("" : "=r"(r) : "0"(a));
252*4724848cSchristos #else
253*4724848cSchristos     volatile uint64_t r = a;
254*4724848cSchristos #endif
255*4724848cSchristos     return r;
256*4724848cSchristos }
257*4724848cSchristos 
258*4724848cSchristos /* Convenience method for size_t. */
value_barrier_s(size_t a)259*4724848cSchristos static ossl_inline size_t value_barrier_s(size_t a)
260*4724848cSchristos {
261*4724848cSchristos #if !defined(OPENSSL_NO_ASM) && defined(__GNUC__)
262*4724848cSchristos     size_t r;
263*4724848cSchristos     __asm__("" : "=r"(r) : "0"(a));
264*4724848cSchristos #else
265*4724848cSchristos     volatile size_t r = a;
266*4724848cSchristos #endif
267*4724848cSchristos     return r;
268*4724848cSchristos }
269*4724848cSchristos 
constant_time_select(unsigned int mask,unsigned int a,unsigned int b)270*4724848cSchristos static ossl_inline unsigned int constant_time_select(unsigned int mask,
271*4724848cSchristos                                                      unsigned int a,
272*4724848cSchristos                                                      unsigned int b)
273*4724848cSchristos {
274*4724848cSchristos     return (value_barrier(mask) & a) | (value_barrier(~mask) & b);
275*4724848cSchristos }
276*4724848cSchristos 
constant_time_select_s(size_t mask,size_t a,size_t b)277*4724848cSchristos static ossl_inline size_t constant_time_select_s(size_t mask,
278*4724848cSchristos                                                  size_t a,
279*4724848cSchristos                                                  size_t b)
280*4724848cSchristos {
281*4724848cSchristos     return (value_barrier_s(mask) & a) | (value_barrier_s(~mask) & b);
282*4724848cSchristos }
283*4724848cSchristos 
constant_time_select_8(unsigned char mask,unsigned char a,unsigned char b)284*4724848cSchristos static ossl_inline unsigned char constant_time_select_8(unsigned char mask,
285*4724848cSchristos                                                         unsigned char a,
286*4724848cSchristos                                                         unsigned char b)
287*4724848cSchristos {
288*4724848cSchristos     return (unsigned char)constant_time_select(mask, a, b);
289*4724848cSchristos }
290*4724848cSchristos 
constant_time_select_int(unsigned int mask,int a,int b)291*4724848cSchristos static ossl_inline int constant_time_select_int(unsigned int mask, int a,
292*4724848cSchristos                                                 int b)
293*4724848cSchristos {
294*4724848cSchristos     return (int)constant_time_select(mask, (unsigned)(a), (unsigned)(b));
295*4724848cSchristos }
296*4724848cSchristos 
constant_time_select_int_s(size_t mask,int a,int b)297*4724848cSchristos static ossl_inline int constant_time_select_int_s(size_t mask, int a, int b)
298*4724848cSchristos {
299*4724848cSchristos     return (int)constant_time_select((unsigned)mask, (unsigned)(a),
300*4724848cSchristos                                       (unsigned)(b));
301*4724848cSchristos }
302*4724848cSchristos 
constant_time_select_32(uint32_t mask,uint32_t a,uint32_t b)303*4724848cSchristos static ossl_inline uint32_t constant_time_select_32(uint32_t mask, uint32_t a,
304*4724848cSchristos                                                     uint32_t b)
305*4724848cSchristos {
306*4724848cSchristos     return (value_barrier_32(mask) & a) | (value_barrier_32(~mask) & b);
307*4724848cSchristos }
308*4724848cSchristos 
constant_time_select_64(uint64_t mask,uint64_t a,uint64_t b)309*4724848cSchristos static ossl_inline uint64_t constant_time_select_64(uint64_t mask, uint64_t a,
310*4724848cSchristos                                                     uint64_t b)
311*4724848cSchristos {
312*4724848cSchristos     return (value_barrier_64(mask) & a) | (value_barrier_64(~mask) & b);
313*4724848cSchristos }
314*4724848cSchristos 
315*4724848cSchristos /*
316*4724848cSchristos  * mask must be 0xFFFFFFFF or 0x00000000.
317*4724848cSchristos  *
318*4724848cSchristos  * if (mask) {
319*4724848cSchristos  *     uint32_t tmp = *a;
320*4724848cSchristos  *
321*4724848cSchristos  *     *a = *b;
322*4724848cSchristos  *     *b = tmp;
323*4724848cSchristos  * }
324*4724848cSchristos  */
constant_time_cond_swap_32(uint32_t mask,uint32_t * a,uint32_t * b)325*4724848cSchristos static ossl_inline void constant_time_cond_swap_32(uint32_t mask, uint32_t *a,
326*4724848cSchristos                                                    uint32_t *b)
327*4724848cSchristos {
328*4724848cSchristos     uint32_t xor = *a ^ *b;
329*4724848cSchristos 
330*4724848cSchristos     xor &= mask;
331*4724848cSchristos     *a ^= xor;
332*4724848cSchristos     *b ^= xor;
333*4724848cSchristos }
334*4724848cSchristos 
335*4724848cSchristos /*
336*4724848cSchristos  * mask must be 0xFFFFFFFF or 0x00000000.
337*4724848cSchristos  *
338*4724848cSchristos  * if (mask) {
339*4724848cSchristos  *     uint64_t tmp = *a;
340*4724848cSchristos  *
341*4724848cSchristos  *     *a = *b;
342*4724848cSchristos  *     *b = tmp;
343*4724848cSchristos  * }
344*4724848cSchristos  */
constant_time_cond_swap_64(uint64_t mask,uint64_t * a,uint64_t * b)345*4724848cSchristos static ossl_inline void constant_time_cond_swap_64(uint64_t mask, uint64_t *a,
346*4724848cSchristos                                                    uint64_t *b)
347*4724848cSchristos {
348*4724848cSchristos     uint64_t xor = *a ^ *b;
349*4724848cSchristos 
350*4724848cSchristos     xor &= mask;
351*4724848cSchristos     *a ^= xor;
352*4724848cSchristos     *b ^= xor;
353*4724848cSchristos }
354*4724848cSchristos 
355*4724848cSchristos /*
356*4724848cSchristos  * table is a two dimensional array of bytes. Each row has rowsize elements.
357*4724848cSchristos  * Copies row number idx into out. rowsize and numrows are not considered
358*4724848cSchristos  * private.
359*4724848cSchristos  */
constant_time_lookup(void * out,const void * table,size_t rowsize,size_t numrows,size_t idx)360*4724848cSchristos static ossl_inline void constant_time_lookup(void *out,
361*4724848cSchristos                                              const void *table,
362*4724848cSchristos                                              size_t rowsize,
363*4724848cSchristos                                              size_t numrows,
364*4724848cSchristos                                              size_t idx)
365*4724848cSchristos {
366*4724848cSchristos     size_t i, j;
367*4724848cSchristos     const unsigned char *tablec = (const unsigned char *)table;
368*4724848cSchristos     unsigned char *outc = (unsigned char *)out;
369*4724848cSchristos     unsigned char mask;
370*4724848cSchristos 
371*4724848cSchristos     memset(out, 0, rowsize);
372*4724848cSchristos 
373*4724848cSchristos     /* Note idx may underflow - but that is well defined */
374*4724848cSchristos     for (i = 0; i < numrows; i++, idx--) {
375*4724848cSchristos         mask = (unsigned char)constant_time_is_zero_s(idx);
376*4724848cSchristos         for (j = 0; j < rowsize; j++)
377*4724848cSchristos             *(outc + j) |= constant_time_select_8(mask, *(tablec++), 0);
378*4724848cSchristos     }
379*4724848cSchristos }
380*4724848cSchristos 
381*4724848cSchristos /*
382*4724848cSchristos  * Expected usage pattern is to unconditionally set error and then
383*4724848cSchristos  * wipe it if there was no actual error. |clear| is 1 or 0.
384*4724848cSchristos  */
385*4724848cSchristos void err_clear_last_constant_time(int clear);
386*4724848cSchristos 
387*4724848cSchristos #endif                          /* OSSL_INTERNAL_CONSTANT_TIME_H */
388