internal.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /* Copyright (C) 1995-1998 Eric Young ([email protected])
  2. * All rights reserved.
  3. *
  4. * This package is an SSL implementation written
  5. * by Eric Young ([email protected]).
  6. * The implementation was written so as to conform with Netscapes SSL.
  7. *
  8. * This library is free for commercial and non-commercial use as long as
  9. * the following conditions are aheared to. The following conditions
  10. * apply to all code found in this distribution, be it the RC4, RSA,
  11. * lhash, DES, etc., code; not just the SSL code. The SSL documentation
  12. * included with this distribution is covered by the same copyright terms
  13. * except that the holder is Tim Hudson ([email protected]).
  14. *
  15. * Copyright remains Eric Young's, and as such any Copyright notices in
  16. * the code are not to be removed.
  17. * If this package is used in a product, Eric Young should be given attribution
  18. * as the author of the parts of the library used.
  19. * This can be in the form of a textual message at program startup or
  20. * in documentation (online or textual) provided with the package.
  21. *
  22. * Redistribution and use in source and binary forms, with or without
  23. * modification, are permitted provided that the following conditions
  24. * are met:
  25. * 1. Redistributions of source code must retain the copyright
  26. * notice, this list of conditions and the following disclaimer.
  27. * 2. Redistributions in binary form must reproduce the above copyright
  28. * notice, this list of conditions and the following disclaimer in the
  29. * documentation and/or other materials provided with the distribution.
  30. * 3. All advertising materials mentioning features or use of this software
  31. * must display the following acknowledgement:
  32. * "This product includes cryptographic software written by
  33. * Eric Young ([email protected])"
  34. * The word 'cryptographic' can be left out if the rouines from the library
  35. * being used are not cryptographic related :-).
  36. * 4. If you include any Windows specific code (or a derivative thereof) from
  37. * the apps directory (application code) you must include an acknowledgement:
  38. * "This product includes software written by Tim Hudson ([email protected])"
  39. *
  40. * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  41. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  42. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  43. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  44. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  45. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  46. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  47. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  48. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  49. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  50. * SUCH DAMAGE.
  51. *
  52. * The licence and distribution terms for any publically available version or
  53. * derivative of this code cannot be changed. i.e. this code cannot simply be
  54. * copied and put under another distribution licence
  55. * [including the GNU Public Licence.]
  56. */
  57. /* ====================================================================
  58. * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
  59. *
  60. * Redistribution and use in source and binary forms, with or without
  61. * modification, are permitted provided that the following conditions
  62. * are met:
  63. *
  64. * 1. Redistributions of source code must retain the above copyright
  65. * notice, this list of conditions and the following disclaimer.
  66. *
  67. * 2. Redistributions in binary form must reproduce the above copyright
  68. * notice, this list of conditions and the following disclaimer in
  69. * the documentation and/or other materials provided with the
  70. * distribution.
  71. *
  72. * 3. All advertising materials mentioning features or use of this
  73. * software must display the following acknowledgment:
  74. * "This product includes software developed by the OpenSSL Project
  75. * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
  76. *
  77. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  78. * endorse or promote products derived from this software without
  79. * prior written permission. For written permission, please contact
  80. * [email protected].
  81. *
  82. * 5. Products derived from this software may not be called "OpenSSL"
  83. * nor may "OpenSSL" appear in their names without prior written
  84. * permission of the OpenSSL Project.
  85. *
  86. * 6. Redistributions of any form whatsoever must retain the following
  87. * acknowledgment:
  88. * "This product includes software developed by the OpenSSL Project
  89. * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
  90. *
  91. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  92. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  93. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  94. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  95. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  96. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  97. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  98. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  99. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  100. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  101. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  102. * OF THE POSSIBILITY OF SUCH DAMAGE.
  103. * ====================================================================
  104. *
  105. * This product includes cryptographic software written by Eric Young
  106. * ([email protected]). This product includes software written by Tim
  107. * Hudson ([email protected]). */
  108. #ifndef OPENSSL_HEADER_CRYPTO_INTERNAL_H
  109. #define OPENSSL_HEADER_CRYPTO_INTERNAL_H
  110. #include <GFp/base.h> // Must be first.
  111. #include "GFp/check.h"
  112. #if defined(__GNUC__) && \
  113. (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
  114. // |alignas| and |alignof| were added in C11. GCC added support in version 4.8.
  115. // Testing for __STDC_VERSION__/__cplusplus doesn't work because 4.7 already
  116. // reports support for C11.
  117. #define alignas(x) __attribute__ ((aligned (x)))
  118. #elif defined(_MSC_VER) && !defined(__clang__)
  119. #define alignas(x) __declspec(align(x))
  120. #else
  121. #include <stdalign.h>
  122. #endif
  123. #if (!defined(_MSC_VER) || defined(__clang__)) && defined(OPENSSL_64_BIT)
  124. #define BORINGSSL_HAS_UINT128
  125. typedef __int128_t int128_t;
  126. typedef __uint128_t uint128_t;
  127. #endif
  128. // Constant-time utility functions.
  129. //
  130. // The following methods return a bitmask of all ones (0xff...f) for true and 0
  131. // for false. This is useful for choosing a value based on the result of a
  132. // conditional in constant time. For example,
  133. //
  134. // if (a < b) {
  135. // c = a;
  136. // } else {
  137. // c = b;
  138. // }
  139. //
  140. // can be written as
  141. //
  142. // crypto_word lt = constant_time_lt_w(a, b);
  143. // c = constant_time_select_w(lt, a, b);
  144. // crypto_word is the type that most constant-time functions use. Ideally we
  145. // would like it to be |size_t|, but NaCl builds in 64-bit mode with 32-bit
  146. // pointers, which means that |size_t| can be 32 bits when |crypto_word| is 64
  147. // bits.
  148. #if defined(OPENSSL_64_BIT)
  149. typedef uint64_t crypto_word;
  150. #define CRYPTO_WORD_BITS (64u)
  151. #elif defined(OPENSSL_32_BIT)
  152. typedef uint32_t crypto_word;
  153. #define CRYPTO_WORD_BITS (32u)
  154. #else
  155. #error "Must define either OPENSSL_32_BIT or OPENSSL_64_BIT"
  156. #endif
  157. #define CONSTTIME_TRUE_W ~((crypto_word)0)
  158. #define CONSTTIME_FALSE_W ((crypto_word)0)
  159. // value_barrier_w returns |a|, but prevents GCC and Clang from reasoning about
  160. // the returned value. This is used to mitigate compilers undoing constant-time
  161. // code, until we can express our requirements directly in the language.
  162. //
  163. // Note the compiler is aware that |value_barrier_w| has no side effects and
  164. // always has the same output for a given input. This allows it to eliminate
  165. // dead code, move computations across loops, and vectorize.
  166. static inline crypto_word value_barrier_w(crypto_word a) {
  167. #if !defined(OPENSSL_NO_ASM) && (defined(__GNUC__) || defined(__clang__))
  168. __asm__("" : "+r"(a) : /* no inputs */);
  169. #endif
  170. return a;
  171. }
  172. // value_barrier_u32 behaves like |value_barrier_w| but takes a |uint32_t|.
  173. static inline uint32_t value_barrier_u32(uint32_t a) {
  174. #if !defined(OPENSSL_NO_ASM) && (defined(__GNUC__) || defined(__clang__))
  175. __asm__("" : "+r"(a) : /* no inputs */);
  176. #endif
  177. return a;
  178. }
  179. // value_barrier_u64 behaves like |value_barrier_w| but takes a |uint64_t|.
  180. static inline uint64_t value_barrier_u64(uint64_t a) {
  181. #if !defined(OPENSSL_NO_ASM) && (defined(__GNUC__) || defined(__clang__))
  182. __asm__("" : "+r"(a) : /* no inputs */);
  183. #endif
  184. return a;
  185. }
  186. // constant_time_msb_w returns the given value with the MSB copied to all the
  187. // other bits.
  188. static inline crypto_word constant_time_msb_w(crypto_word a) {
  189. return 0u - (a >> (sizeof(a) * 8 - 1));
  190. }
  191. // constant_time_is_zero_w returns 0xff..f if a == 0 and 0 otherwise.
  192. static inline crypto_word constant_time_is_zero_w(crypto_word a) {
  193. // Here is an SMT-LIB verification of this formula:
  194. //
  195. // (define-fun is_zero ((a (_ BitVec 32))) (_ BitVec 32)
  196. // (bvand (bvnot a) (bvsub a #x00000001))
  197. // )
  198. //
  199. // (declare-fun a () (_ BitVec 32))
  200. //
  201. // (assert (not (= (= #x00000001 (bvlshr (is_zero a) #x0000001f)) (= a #x00000000))))
  202. // (check-sat)
  203. // (get-model)
  204. return constant_time_msb_w(~a & (a - 1));
  205. }
  206. static inline crypto_word constant_time_is_nonzero_w(crypto_word a) {
  207. return ~constant_time_is_zero_w(a);
  208. }
  209. // constant_time_eq_w returns 0xff..f if a == b and 0 otherwise.
  210. static inline crypto_word constant_time_eq_w(crypto_word a,
  211. crypto_word b) {
  212. return constant_time_is_zero_w(a ^ b);
  213. }
  214. // constant_time_select_w returns (mask & a) | (~mask & b). When |mask| is all
  215. // 1s or all 0s (as returned by the methods above), the select methods return
  216. // either |a| (if |mask| is nonzero) or |b| (if |mask| is zero).
  217. static inline crypto_word constant_time_select_w(crypto_word mask,
  218. crypto_word a,
  219. crypto_word b) {
  220. // Clang recognizes this pattern as a select. While it usually transforms it
  221. // to a cmov, it sometimes further transforms it into a branch, which we do
  222. // not want.
  223. //
  224. // Adding barriers to both |mask| and |~mask| breaks the relationship between
  225. // the two, which makes the compiler stick with bitmasks.
  226. return (value_barrier_w(mask) & a) | (value_barrier_w(~mask) & b);
  227. }
  228. // Endianness conversions.
  229. #if defined(__GNUC__) && __GNUC__ >= 2
  230. static inline uint32_t CRYPTO_bswap4(uint32_t x) {
  231. return __builtin_bswap32(x);
  232. }
  233. #elif defined(_MSC_VER)
  234. #pragma warning(push, 3)
  235. #include <stdlib.h>
  236. #pragma warning(pop)
  237. #pragma intrinsic(_byteswap_uint64, _byteswap_ulong)
  238. static inline uint32_t CRYPTO_bswap4(uint32_t x) {
  239. return _byteswap_ulong(x);
  240. }
  241. #endif
  242. #if !defined(GFp_NOSTDLIBINC)
  243. #include <string.h>
  244. #endif
  245. static inline void *GFp_memcpy(void *dst, const void *src, size_t n) {
  246. #if !defined(GFp_NOSTDLIBINC)
  247. if (n == 0) {
  248. return dst;
  249. }
  250. return memcpy(dst, src, n);
  251. #else
  252. unsigned char *d = dst;
  253. const unsigned char *s = src;
  254. for (size_t i = 0; i < n; ++i) {
  255. d[i] = s[i];
  256. }
  257. return dst;
  258. #endif
  259. }
  260. static inline void *GFp_memset(void *dst, int c, size_t n) {
  261. #if !defined(GFp_NOSTDLIBINC)
  262. if (n == 0) {
  263. return dst;
  264. }
  265. return memset(dst, c, n);
  266. #else
  267. unsigned char *d = dst;
  268. for (size_t i = 0; i < n; ++i) {
  269. d[i] = (unsigned char)c;
  270. }
  271. return dst;
  272. #endif
  273. }
  274. #endif // OPENSSL_HEADER_CRYPTO_INTERNAL_H