constant_time_locl.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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. #ifndef HEADER_CONSTANT_TIME_LOCL_H
  47. # define HEADER_CONSTANT_TIME_LOCL_H
  48. # include "e_os.h" /* For 'inline' */
  49. #ifdef __cplusplus
  50. extern "C" {
  51. #endif
  52. /*-
  53. * The boolean methods return a bitmask of all ones (0xff...f) for true
  54. * and 0 for false. This is useful for choosing a value based on the result
  55. * of a conditional in constant time. For example,
  56. *
  57. * if (a < b) {
  58. * c = a;
  59. * } else {
  60. * c = b;
  61. * }
  62. *
  63. * can be written as
  64. *
  65. * unsigned int lt = constant_time_lt(a, b);
  66. * c = constant_time_select(lt, a, b);
  67. */
  68. /*
  69. * Returns the given value with the MSB copied to all the other
  70. * bits. Uses the fact that arithmetic shift shifts-in the sign bit.
  71. * However, this is not ensured by the C standard so you may need to
  72. * replace this with something else on odd CPUs.
  73. */
  74. static inline unsigned int constant_time_msb(unsigned int a);
  75. /*
  76. * Returns 0xff..f if a < b and 0 otherwise.
  77. */
  78. static inline unsigned int constant_time_lt(unsigned int a, unsigned int b);
  79. /* Convenience method for getting an 8-bit mask. */
  80. static inline unsigned char constant_time_lt_8(unsigned int a,
  81. unsigned int b);
  82. /*
  83. * Returns 0xff..f if a >= b and 0 otherwise.
  84. */
  85. static inline unsigned int constant_time_ge(unsigned int a, unsigned int b);
  86. /* Convenience method for getting an 8-bit mask. */
  87. static inline unsigned char constant_time_ge_8(unsigned int a,
  88. unsigned int b);
  89. /*
  90. * Returns 0xff..f if a == 0 and 0 otherwise.
  91. */
  92. static inline unsigned int constant_time_is_zero(unsigned int a);
  93. /* Convenience method for getting an 8-bit mask. */
  94. static inline unsigned char constant_time_is_zero_8(unsigned int a);
  95. /*
  96. * Returns 0xff..f if a == b and 0 otherwise.
  97. */
  98. static inline unsigned int constant_time_eq(unsigned int a, unsigned int b);
  99. /* Convenience method for getting an 8-bit mask. */
  100. static inline unsigned char constant_time_eq_8(unsigned int a,
  101. unsigned int b);
  102. /* Signed integers. */
  103. static inline unsigned int constant_time_eq_int(int a, int b);
  104. /* Convenience method for getting an 8-bit mask. */
  105. static inline unsigned char constant_time_eq_int_8(int a, int b);
  106. /*-
  107. * Returns (mask & a) | (~mask & b).
  108. *
  109. * When |mask| is all 1s or all 0s (as returned by the methods above),
  110. * the select methods return either |a| (if |mask| is nonzero) or |b|
  111. * (if |mask| is zero).
  112. */
  113. static inline unsigned int constant_time_select(unsigned int mask,
  114. unsigned int a,
  115. unsigned int b);
  116. /* Convenience method for unsigned chars. */
  117. static inline unsigned char constant_time_select_8(unsigned char mask,
  118. unsigned char a,
  119. unsigned char b);
  120. /* Convenience method for signed integers. */
  121. static inline int constant_time_select_int(unsigned int mask, int a, int b);
  122. static inline unsigned int constant_time_msb(unsigned int a)
  123. {
  124. return 0 - (a >> (sizeof(a) * 8 - 1));
  125. }
  126. static inline unsigned int constant_time_lt(unsigned int a, unsigned int b)
  127. {
  128. return constant_time_msb(a ^ ((a ^ b) | ((a - b) ^ b)));
  129. }
  130. static inline unsigned char constant_time_lt_8(unsigned int a, unsigned int b)
  131. {
  132. return (unsigned char)(constant_time_lt(a, b));
  133. }
  134. static inline unsigned int constant_time_ge(unsigned int a, unsigned int b)
  135. {
  136. return ~constant_time_lt(a, b);
  137. }
  138. static inline unsigned char constant_time_ge_8(unsigned int a, unsigned int b)
  139. {
  140. return (unsigned char)(constant_time_ge(a, b));
  141. }
  142. static inline unsigned int constant_time_is_zero(unsigned int a)
  143. {
  144. return constant_time_msb(~a & (a - 1));
  145. }
  146. static inline unsigned char constant_time_is_zero_8(unsigned int a)
  147. {
  148. return (unsigned char)(constant_time_is_zero(a));
  149. }
  150. static inline unsigned int constant_time_eq(unsigned int a, unsigned int b)
  151. {
  152. return constant_time_is_zero(a ^ b);
  153. }
  154. static inline unsigned char constant_time_eq_8(unsigned int a, unsigned int b)
  155. {
  156. return (unsigned char)(constant_time_eq(a, b));
  157. }
  158. static inline unsigned int constant_time_eq_int(int a, int b)
  159. {
  160. return constant_time_eq((unsigned)(a), (unsigned)(b));
  161. }
  162. static inline unsigned char constant_time_eq_int_8(int a, int b)
  163. {
  164. return constant_time_eq_8((unsigned)(a), (unsigned)(b));
  165. }
  166. static inline unsigned int constant_time_select(unsigned int mask,
  167. unsigned int a,
  168. unsigned int b)
  169. {
  170. return (mask & a) | (~mask & b);
  171. }
  172. static inline unsigned char constant_time_select_8(unsigned char mask,
  173. unsigned char a,
  174. unsigned char b)
  175. {
  176. return (unsigned char)(constant_time_select(mask, a, b));
  177. }
  178. static inline int constant_time_select_int(unsigned int mask, int a, int b)
  179. {
  180. return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b)));
  181. }
  182. #ifdef __cplusplus
  183. }
  184. #endif
  185. #endif /* HEADER_CONSTANT_TIME_LOCL_H */