Home | History | Annotate | Download | only in crypto
      1 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com)
      2  * All rights reserved.
      3  *
      4  * This package is an SSL implementation written
      5  * by Eric Young (eay (at) cryptsoft.com).
      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 (tjh (at) cryptsoft.com).
     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 (eay (at) cryptsoft.com)"
     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 (tjh (at) cryptsoft.com)"
     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  *    openssl-core (at) openssl.org.
     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  * (eay (at) cryptsoft.com).  This product includes software written by Tim
    107  * Hudson (tjh (at) cryptsoft.com). */
    108 
    109 #ifndef OPENSSL_HEADER_CRYPTO_INTERNAL_H
    110 #define OPENSSL_HEADER_CRYPTO_INTERNAL_H
    111 
    112 #include <openssl/ex_data.h>
    113 #include <openssl/stack.h>
    114 #include <openssl/thread.h>
    115 
    116 #include <assert.h>
    117 #include <string.h>
    118 
    119 #if defined(__GNUC__) && \
    120     (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
    121 // |alignas| and |alignof| were added in C11. GCC added support in version 4.8.
    122 // Testing for __STDC_VERSION__/__cplusplus doesn't work because 4.7 already
    123 // reports support for C11.
    124 #define alignas(x) __attribute__ ((aligned (x)))
    125 #define alignof(x) __alignof__ (x)
    126 #elif !defined(__cplusplus)
    127 #if defined(_MSC_VER)
    128 #define alignas(x) __declspec(align(x))
    129 #define alignof __alignof
    130 #else
    131 #include <stdalign.h>
    132 #endif
    133 #endif
    134 
    135 #if !defined(OPENSSL_NO_THREADS) && \
    136     (!defined(OPENSSL_WINDOWS) || defined(__MINGW32__))
    137 #include <pthread.h>
    138 #define OPENSSL_PTHREADS
    139 #endif
    140 
    141 #if !defined(OPENSSL_NO_THREADS) && !defined(OPENSSL_PTHREADS) && \
    142     defined(OPENSSL_WINDOWS)
    143 #define OPENSSL_WINDOWS_THREADS
    144 OPENSSL_MSVC_PRAGMA(warning(push, 3))
    145 #include <windows.h>
    146 OPENSSL_MSVC_PRAGMA(warning(pop))
    147 #endif
    148 
    149 #if defined(__cplusplus)
    150 extern "C" {
    151 #endif
    152 
    153 
    154 #if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || defined(OPENSSL_ARM) || \
    155     defined(OPENSSL_AARCH64) || defined(OPENSSL_PPC64LE)
    156 // OPENSSL_cpuid_setup initializes the platform-specific feature cache.
    157 void OPENSSL_cpuid_setup(void);
    158 #endif
    159 
    160 
    161 #if (!defined(_MSC_VER) || defined(__clang__)) && defined(OPENSSL_64_BIT)
    162 #define BORINGSSL_HAS_UINT128
    163 typedef __int128_t int128_t;
    164 typedef __uint128_t uint128_t;
    165 
    166 // clang-cl supports __uint128_t but modulus and division don't work.
    167 // https://crbug.com/787617.
    168 #if !defined(_MSC_VER) || !defined(__clang__)
    169 #define BORINGSSL_CAN_DIVIDE_UINT128
    170 #endif
    171 #endif
    172 
    173 #define OPENSSL_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
    174 
    175 // Have a generic fall-through for different versions of C/C++.
    176 #if defined(__cplusplus) && __cplusplus >= 201703L
    177 #define OPENSSL_FALLTHROUGH [[fallthrough]]
    178 #elif defined(__cplusplus) && __cplusplus >= 201103L && defined(__clang__)
    179 #define OPENSSL_FALLTHROUGH [[clang::fallthrough]]
    180 #elif defined(__cplusplus) && __cplusplus >= 201103L && defined(__GNUC__) && \
    181     __GNUC__ >= 7
    182 #define OPENSSL_FALLTHROUGH [[gnu::fallthrough]]
    183 #elif defined(__GNUC__) && __GNUC__ >= 7 // gcc 7
    184 #define OPENSSL_FALLTHROUGH __attribute__ ((fallthrough))
    185 #else // C++11 on gcc 6, and all other cases
    186 #define OPENSSL_FALLTHROUGH
    187 #endif
    188 
    189 // buffers_alias returns one if |a| and |b| alias and zero otherwise.
    190 static inline int buffers_alias(const uint8_t *a, size_t a_len,
    191                                 const uint8_t *b, size_t b_len) {
    192   // Cast |a| and |b| to integers. In C, pointer comparisons between unrelated
    193   // objects are undefined whereas pointer to integer conversions are merely
    194   // implementation-defined. We assume the implementation defined it in a sane
    195   // way.
    196   uintptr_t a_u = (uintptr_t)a;
    197   uintptr_t b_u = (uintptr_t)b;
    198   return a_u + a_len > b_u && b_u + b_len > a_u;
    199 }
    200 
    201 
    202 // Constant-time utility functions.
    203 //
    204 // The following methods return a bitmask of all ones (0xff...f) for true and 0
    205 // for false. This is useful for choosing a value based on the result of a
    206 // conditional in constant time. For example,
    207 //
    208 // if (a < b) {
    209 //   c = a;
    210 // } else {
    211 //   c = b;
    212 // }
    213 //
    214 // can be written as
    215 //
    216 // crypto_word_t lt = constant_time_lt_w(a, b);
    217 // c = constant_time_select_w(lt, a, b);
    218 
    219 // crypto_word_t is the type that most constant-time functions use. Ideally we
    220 // would like it to be |size_t|, but NaCl builds in 64-bit mode with 32-bit
    221 // pointers, which means that |size_t| can be 32 bits when |BN_ULONG| is 64
    222 // bits. Since we want to be able to do constant-time operations on a
    223 // |BN_ULONG|, |crypto_word_t| is defined as an unsigned value with the native
    224 // word length.
    225 #if defined(OPENSSL_64_BIT)
    226 typedef uint64_t crypto_word_t;
    227 #elif defined(OPENSSL_32_BIT)
    228 typedef uint32_t crypto_word_t;
    229 #else
    230 #error "Must define either OPENSSL_32_BIT or OPENSSL_64_BIT"
    231 #endif
    232 
    233 #define CONSTTIME_TRUE_W ~((crypto_word_t)0)
    234 #define CONSTTIME_FALSE_W ((crypto_word_t)0)
    235 #define CONSTTIME_TRUE_8 ((uint8_t)0xff)
    236 
    237 #define CONSTTIME_TRUE_W ~((crypto_word_t)0)
    238 #define CONSTTIME_FALSE_W ((crypto_word_t)0)
    239 #define CONSTTIME_TRUE_8 ((uint8_t)0xff)
    240 #define CONSTTIME_FALSE_8 ((uint8_t)0)
    241 
    242 // constant_time_msb_w returns the given value with the MSB copied to all the
    243 // other bits.
    244 static inline crypto_word_t constant_time_msb_w(crypto_word_t a) {
    245   return 0u - (a >> (sizeof(a) * 8 - 1));
    246 }
    247 
    248 // constant_time_lt_w returns 0xff..f if a < b and 0 otherwise.
    249 static inline crypto_word_t constant_time_lt_w(crypto_word_t a,
    250                                                crypto_word_t b) {
    251   // Consider the two cases of the problem:
    252   //   msb(a) == msb(b): a < b iff the MSB of a - b is set.
    253   //   msb(a) != msb(b): a < b iff the MSB of b is set.
    254   //
    255   // If msb(a) == msb(b) then the following evaluates as:
    256   //   msb(a^((a^b)|((a-b)^a))) ==
    257   //   msb(a^((a-b) ^ a))       ==   (because msb(a^b) == 0)
    258   //   msb(a^a^(a-b))           ==   (rearranging)
    259   //   msb(a-b)                      (because x. x^x == 0)
    260   //
    261   // Else, if msb(a) != msb(b) then the following evaluates as:
    262   //   msb(a^((a^b)|((a-b)^a))) ==
    263   //   msb(a^( | ((a-b)^a)))   ==   (because msb(a^b) == 1 and 
    264   //                                  represents a value s.t. msb() = 1)
    265   //   msb(a^)                 ==   (because ORing with 1 results in 1)
    266   //   msb(b)
    267   //
    268   //
    269   // Here is an SMT-LIB verification of this formula:
    270   //
    271   // (define-fun lt ((a (_ BitVec 32)) (b (_ BitVec 32))) (_ BitVec 32)
    272   //   (bvxor a (bvor (bvxor a b) (bvxor (bvsub a b) a)))
    273   // )
    274   //
    275   // (declare-fun a () (_ BitVec 32))
    276   // (declare-fun b () (_ BitVec 32))
    277   //
    278   // (assert (not (= (= #x00000001 (bvlshr (lt a b) #x0000001f)) (bvult a b))))
    279   // (check-sat)
    280   // (get-model)
    281   return constant_time_msb_w(a^((a^b)|((a-b)^a)));
    282 }
    283 
    284 // constant_time_lt_8 acts like |constant_time_lt_w| but returns an 8-bit
    285 // mask.
    286 static inline uint8_t constant_time_lt_8(crypto_word_t a, crypto_word_t b) {
    287   return (uint8_t)(constant_time_lt_w(a, b));
    288 }
    289 
    290 // constant_time_ge_w returns 0xff..f if a >= b and 0 otherwise.
    291 static inline crypto_word_t constant_time_ge_w(crypto_word_t a,
    292                                                crypto_word_t b) {
    293   return ~constant_time_lt_w(a, b);
    294 }
    295 
    296 // constant_time_ge_8 acts like |constant_time_ge_w| but returns an 8-bit
    297 // mask.
    298 static inline uint8_t constant_time_ge_8(crypto_word_t a, crypto_word_t b) {
    299   return (uint8_t)(constant_time_ge_w(a, b));
    300 }
    301 
    302 // constant_time_is_zero returns 0xff..f if a == 0 and 0 otherwise.
    303 static inline crypto_word_t constant_time_is_zero_w(crypto_word_t a) {
    304   // Here is an SMT-LIB verification of this formula:
    305   //
    306   // (define-fun is_zero ((a (_ BitVec 32))) (_ BitVec 32)
    307   //   (bvand (bvnot a) (bvsub a #x00000001))
    308   // )
    309   //
    310   // (declare-fun a () (_ BitVec 32))
    311   //
    312   // (assert (not (= (= #x00000001 (bvlshr (is_zero a) #x0000001f)) (= a #x00000000))))
    313   // (check-sat)
    314   // (get-model)
    315   return constant_time_msb_w(~a & (a - 1));
    316 }
    317 
    318 // constant_time_is_zero_8 acts like |constant_time_is_zero_w| but returns an
    319 // 8-bit mask.
    320 static inline uint8_t constant_time_is_zero_8(crypto_word_t a) {
    321   return (uint8_t)(constant_time_is_zero_w(a));
    322 }
    323 
    324 // constant_time_eq_w returns 0xff..f if a == b and 0 otherwise.
    325 static inline crypto_word_t constant_time_eq_w(crypto_word_t a,
    326                                                crypto_word_t b) {
    327   return constant_time_is_zero_w(a ^ b);
    328 }
    329 
    330 // constant_time_eq_8 acts like |constant_time_eq_w| but returns an 8-bit
    331 // mask.
    332 static inline uint8_t constant_time_eq_8(crypto_word_t a, crypto_word_t b) {
    333   return (uint8_t)(constant_time_eq_w(a, b));
    334 }
    335 
    336 // constant_time_eq_int acts like |constant_time_eq_w| but works on int
    337 // values.
    338 static inline crypto_word_t constant_time_eq_int(int a, int b) {
    339   return constant_time_eq_w((crypto_word_t)(a), (crypto_word_t)(b));
    340 }
    341 
    342 // constant_time_eq_int_8 acts like |constant_time_eq_int| but returns an 8-bit
    343 // mask.
    344 static inline uint8_t constant_time_eq_int_8(int a, int b) {
    345   return constant_time_eq_8((crypto_word_t)(a), (crypto_word_t)(b));
    346 }
    347 
    348 // constant_time_select_w returns (mask & a) | (~mask & b). When |mask| is all
    349 // 1s or all 0s (as returned by the methods above), the select methods return
    350 // either |a| (if |mask| is nonzero) or |b| (if |mask| is zero).
    351 static inline crypto_word_t constant_time_select_w(crypto_word_t mask,
    352                                                    crypto_word_t a,
    353                                                    crypto_word_t b) {
    354   return (mask & a) | (~mask & b);
    355 }
    356 
    357 // constant_time_select_8 acts like |constant_time_select| but operates on
    358 // 8-bit values.
    359 static inline uint8_t constant_time_select_8(uint8_t mask, uint8_t a,
    360                                              uint8_t b) {
    361   return (uint8_t)(constant_time_select_w(mask, a, b));
    362 }
    363 
    364 // constant_time_select_int acts like |constant_time_select| but operates on
    365 // ints.
    366 static inline int constant_time_select_int(crypto_word_t mask, int a, int b) {
    367   return (int)(constant_time_select_w(mask, (crypto_word_t)(a),
    368                                       (crypto_word_t)(b)));
    369 }
    370 
    371 
    372 // Thread-safe initialisation.
    373 
    374 #if defined(OPENSSL_NO_THREADS)
    375 typedef uint32_t CRYPTO_once_t;
    376 #define CRYPTO_ONCE_INIT 0
    377 #elif defined(OPENSSL_WINDOWS_THREADS)
    378 typedef INIT_ONCE CRYPTO_once_t;
    379 #define CRYPTO_ONCE_INIT INIT_ONCE_STATIC_INIT
    380 #elif defined(OPENSSL_PTHREADS)
    381 typedef pthread_once_t CRYPTO_once_t;
    382 #define CRYPTO_ONCE_INIT PTHREAD_ONCE_INIT
    383 #else
    384 #error "Unknown threading library"
    385 #endif
    386 
    387 // CRYPTO_once calls |init| exactly once per process. This is thread-safe: if
    388 // concurrent threads call |CRYPTO_once| with the same |CRYPTO_once_t| argument
    389 // then they will block until |init| completes, but |init| will have only been
    390 // called once.
    391 //
    392 // The |once| argument must be a |CRYPTO_once_t| that has been initialised with
    393 // the value |CRYPTO_ONCE_INIT|.
    394 OPENSSL_EXPORT void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void));
    395 
    396 
    397 // Reference counting.
    398 
    399 // CRYPTO_REFCOUNT_MAX is the value at which the reference count saturates.
    400 #define CRYPTO_REFCOUNT_MAX 0xffffffff
    401 
    402 // CRYPTO_refcount_inc atomically increments the value at |*count| unless the
    403 // value would overflow. It's safe for multiple threads to concurrently call
    404 // this or |CRYPTO_refcount_dec_and_test_zero| on the same
    405 // |CRYPTO_refcount_t|.
    406 OPENSSL_EXPORT void CRYPTO_refcount_inc(CRYPTO_refcount_t *count);
    407 
    408 // CRYPTO_refcount_dec_and_test_zero tests the value at |*count|:
    409 //   if it's zero, it crashes the address space.
    410 //   if it's the maximum value, it returns zero.
    411 //   otherwise, it atomically decrements it and returns one iff the resulting
    412 //       value is zero.
    413 //
    414 // It's safe for multiple threads to concurrently call this or
    415 // |CRYPTO_refcount_inc| on the same |CRYPTO_refcount_t|.
    416 OPENSSL_EXPORT int CRYPTO_refcount_dec_and_test_zero(CRYPTO_refcount_t *count);
    417 
    418 
    419 // Locks.
    420 //
    421 // Two types of locks are defined: |CRYPTO_MUTEX|, which can be used in
    422 // structures as normal, and |struct CRYPTO_STATIC_MUTEX|, which can be used as
    423 // a global lock. A global lock must be initialised to the value
    424 // |CRYPTO_STATIC_MUTEX_INIT|.
    425 //
    426 // |CRYPTO_MUTEX| can appear in public structures and so is defined in
    427 // thread.h as a structure large enough to fit the real type. The global lock is
    428 // a different type so it may be initialized with platform initializer macros.
    429 
    430 #if defined(OPENSSL_NO_THREADS)
    431 struct CRYPTO_STATIC_MUTEX {
    432   char padding;  // Empty structs have different sizes in C and C++.
    433 };
    434 #define CRYPTO_STATIC_MUTEX_INIT { 0 }
    435 #elif defined(OPENSSL_WINDOWS_THREADS)
    436 struct CRYPTO_STATIC_MUTEX {
    437   SRWLOCK lock;
    438 };
    439 #define CRYPTO_STATIC_MUTEX_INIT { SRWLOCK_INIT }
    440 #elif defined(OPENSSL_PTHREADS)
    441 struct CRYPTO_STATIC_MUTEX {
    442   pthread_rwlock_t lock;
    443 };
    444 #define CRYPTO_STATIC_MUTEX_INIT { PTHREAD_RWLOCK_INITIALIZER }
    445 #else
    446 #error "Unknown threading library"
    447 #endif
    448 
    449 // CRYPTO_MUTEX_init initialises |lock|. If |lock| is a static variable, use a
    450 // |CRYPTO_STATIC_MUTEX|.
    451 OPENSSL_EXPORT void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock);
    452 
    453 // CRYPTO_MUTEX_lock_read locks |lock| such that other threads may also have a
    454 // read lock, but none may have a write lock.
    455 OPENSSL_EXPORT void CRYPTO_MUTEX_lock_read(CRYPTO_MUTEX *lock);
    456 
    457 // CRYPTO_MUTEX_lock_write locks |lock| such that no other thread has any type
    458 // of lock on it.
    459 OPENSSL_EXPORT void CRYPTO_MUTEX_lock_write(CRYPTO_MUTEX *lock);
    460 
    461 // CRYPTO_MUTEX_unlock_read unlocks |lock| for reading.
    462 OPENSSL_EXPORT void CRYPTO_MUTEX_unlock_read(CRYPTO_MUTEX *lock);
    463 
    464 // CRYPTO_MUTEX_unlock_write unlocks |lock| for writing.
    465 OPENSSL_EXPORT void CRYPTO_MUTEX_unlock_write(CRYPTO_MUTEX *lock);
    466 
    467 // CRYPTO_MUTEX_cleanup releases all resources held by |lock|.
    468 OPENSSL_EXPORT void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock);
    469 
    470 // CRYPTO_STATIC_MUTEX_lock_read locks |lock| such that other threads may also
    471 // have a read lock, but none may have a write lock. The |lock| variable does
    472 // not need to be initialised by any function, but must have been statically
    473 // initialised with |CRYPTO_STATIC_MUTEX_INIT|.
    474 OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_lock_read(
    475     struct CRYPTO_STATIC_MUTEX *lock);
    476 
    477 // CRYPTO_STATIC_MUTEX_lock_write locks |lock| such that no other thread has
    478 // any type of lock on it.  The |lock| variable does not need to be initialised
    479 // by any function, but must have been statically initialised with
    480 // |CRYPTO_STATIC_MUTEX_INIT|.
    481 OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_lock_write(
    482     struct CRYPTO_STATIC_MUTEX *lock);
    483 
    484 // CRYPTO_STATIC_MUTEX_unlock_read unlocks |lock| for reading.
    485 OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_unlock_read(
    486     struct CRYPTO_STATIC_MUTEX *lock);
    487 
    488 // CRYPTO_STATIC_MUTEX_unlock_write unlocks |lock| for writing.
    489 OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_unlock_write(
    490     struct CRYPTO_STATIC_MUTEX *lock);
    491 
    492 #if defined(__cplusplus)
    493 extern "C++" {
    494 
    495 namespace bssl {
    496 
    497 namespace internal {
    498 
    499 // MutexLockBase is a RAII helper for CRYPTO_MUTEX locking.
    500 template <void (*LockFunc)(CRYPTO_MUTEX *), void (*ReleaseFunc)(CRYPTO_MUTEX *)>
    501 class MutexLockBase {
    502  public:
    503   explicit MutexLockBase(CRYPTO_MUTEX *mu) : mu_(mu) {
    504     assert(mu_ != nullptr);
    505     LockFunc(mu_);
    506   }
    507   ~MutexLockBase() { ReleaseFunc(mu_); }
    508   MutexLockBase(const MutexLockBase<LockFunc, ReleaseFunc> &) = delete;
    509   MutexLockBase &operator=(const MutexLockBase<LockFunc, ReleaseFunc> &) =
    510       delete;
    511 
    512  private:
    513   CRYPTO_MUTEX *const mu_;
    514 };
    515 
    516 }  // namespace internal
    517 
    518 using MutexWriteLock =
    519     internal::MutexLockBase<CRYPTO_MUTEX_lock_write, CRYPTO_MUTEX_unlock_write>;
    520 using MutexReadLock =
    521     internal::MutexLockBase<CRYPTO_MUTEX_lock_read, CRYPTO_MUTEX_unlock_read>;
    522 
    523 }  // namespace bssl
    524 
    525 }  // extern "C++"
    526 #endif  // defined(__cplusplus)
    527 
    528 
    529 // Thread local storage.
    530 
    531 // thread_local_data_t enumerates the types of thread-local data that can be
    532 // stored.
    533 typedef enum {
    534   OPENSSL_THREAD_LOCAL_ERR = 0,
    535   OPENSSL_THREAD_LOCAL_RAND,
    536   OPENSSL_THREAD_LOCAL_TEST,
    537   NUM_OPENSSL_THREAD_LOCALS,
    538 } thread_local_data_t;
    539 
    540 // thread_local_destructor_t is the type of a destructor function that will be
    541 // called when a thread exits and its thread-local storage needs to be freed.
    542 typedef void (*thread_local_destructor_t)(void *);
    543 
    544 // CRYPTO_get_thread_local gets the pointer value that is stored for the
    545 // current thread for the given index, or NULL if none has been set.
    546 OPENSSL_EXPORT void *CRYPTO_get_thread_local(thread_local_data_t value);
    547 
    548 // CRYPTO_set_thread_local sets a pointer value for the current thread at the
    549 // given index. This function should only be called once per thread for a given
    550 // |index|: rather than update the pointer value itself, update the data that
    551 // is pointed to.
    552 //
    553 // The destructor function will be called when a thread exits to free this
    554 // thread-local data. All calls to |CRYPTO_set_thread_local| with the same
    555 // |index| should have the same |destructor| argument. The destructor may be
    556 // called with a NULL argument if a thread that never set a thread-local
    557 // pointer for |index|, exits. The destructor may be called concurrently with
    558 // different arguments.
    559 //
    560 // This function returns one on success or zero on error. If it returns zero
    561 // then |destructor| has been called with |value| already.
    562 OPENSSL_EXPORT int CRYPTO_set_thread_local(
    563     thread_local_data_t index, void *value,
    564     thread_local_destructor_t destructor);
    565 
    566 
    567 // ex_data
    568 
    569 typedef struct crypto_ex_data_func_st CRYPTO_EX_DATA_FUNCS;
    570 
    571 DECLARE_STACK_OF(CRYPTO_EX_DATA_FUNCS)
    572 
    573 // CRYPTO_EX_DATA_CLASS tracks the ex_indices registered for a type which
    574 // supports ex_data. It should defined as a static global within the module
    575 // which defines that type.
    576 typedef struct {
    577   struct CRYPTO_STATIC_MUTEX lock;
    578   STACK_OF(CRYPTO_EX_DATA_FUNCS) *meth;
    579   // num_reserved is one if the ex_data index zero is reserved for legacy
    580   // |TYPE_get_app_data| functions.
    581   uint8_t num_reserved;
    582 } CRYPTO_EX_DATA_CLASS;
    583 
    584 #define CRYPTO_EX_DATA_CLASS_INIT {CRYPTO_STATIC_MUTEX_INIT, NULL, 0}
    585 #define CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA \
    586     {CRYPTO_STATIC_MUTEX_INIT, NULL, 1}
    587 
    588 // CRYPTO_get_ex_new_index allocates a new index for |ex_data_class| and writes
    589 // it to |*out_index|. Each class of object should provide a wrapper function
    590 // that uses the correct |CRYPTO_EX_DATA_CLASS|. It returns one on success and
    591 // zero otherwise.
    592 OPENSSL_EXPORT int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class,
    593                                            int *out_index, long argl,
    594                                            void *argp,
    595                                            CRYPTO_EX_free *free_func);
    596 
    597 // CRYPTO_set_ex_data sets an extra data pointer on a given object. Each class
    598 // of object should provide a wrapper function.
    599 OPENSSL_EXPORT int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int index, void *val);
    600 
    601 // CRYPTO_get_ex_data returns an extra data pointer for a given object, or NULL
    602 // if no such index exists. Each class of object should provide a wrapper
    603 // function.
    604 OPENSSL_EXPORT void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int index);
    605 
    606 // CRYPTO_new_ex_data initialises a newly allocated |CRYPTO_EX_DATA|.
    607 OPENSSL_EXPORT void CRYPTO_new_ex_data(CRYPTO_EX_DATA *ad);
    608 
    609 // CRYPTO_free_ex_data frees |ad|, which is embedded inside |obj|, which is an
    610 // object of the given class.
    611 OPENSSL_EXPORT void CRYPTO_free_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class,
    612                                         void *obj, CRYPTO_EX_DATA *ad);
    613 
    614 
    615 // Endianness conversions.
    616 
    617 #if defined(__GNUC__) && __GNUC__ >= 2
    618 static inline uint32_t CRYPTO_bswap4(uint32_t x) {
    619   return __builtin_bswap32(x);
    620 }
    621 
    622 static inline uint64_t CRYPTO_bswap8(uint64_t x) {
    623   return __builtin_bswap64(x);
    624 }
    625 #elif defined(_MSC_VER)
    626 OPENSSL_MSVC_PRAGMA(warning(push, 3))
    627 #include <intrin.h>
    628 OPENSSL_MSVC_PRAGMA(warning(pop))
    629 #pragma intrinsic(_byteswap_uint64, _byteswap_ulong)
    630 static inline uint32_t CRYPTO_bswap4(uint32_t x) {
    631   return _byteswap_ulong(x);
    632 }
    633 
    634 static inline uint64_t CRYPTO_bswap8(uint64_t x) {
    635   return _byteswap_uint64(x);
    636 }
    637 #else
    638 static inline uint32_t CRYPTO_bswap4(uint32_t x) {
    639   x = (x >> 16) | (x << 16);
    640   x = ((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8);
    641   return x;
    642 }
    643 
    644 static inline uint64_t CRYPTO_bswap8(uint64_t x) {
    645   return CRYPTO_bswap4(x >> 32) | (((uint64_t)CRYPTO_bswap4(x)) << 32);
    646 }
    647 #endif
    648 
    649 
    650 // Language bug workarounds.
    651 //
    652 // Most C standard library functions are undefined if passed NULL, even when the
    653 // corresponding length is zero. This gives them (and, in turn, all functions
    654 // which call them) surprising behavior on empty arrays. Some compilers will
    655 // miscompile code due to this rule. See also
    656 // https://www.imperialviolet.org/2016/06/26/nonnull.html
    657 //
    658 // These wrapper functions behave the same as the corresponding C standard
    659 // functions, but behave as expected when passed NULL if the length is zero.
    660 //
    661 // Note |OPENSSL_memcmp| is a different function from |CRYPTO_memcmp|.
    662 
    663 // C++ defines |memchr| as a const-correct overload.
    664 #if defined(__cplusplus)
    665 extern "C++" {
    666 
    667 static inline const void *OPENSSL_memchr(const void *s, int c, size_t n) {
    668   if (n == 0) {
    669     return NULL;
    670   }
    671 
    672   return memchr(s, c, n);
    673 }
    674 
    675 static inline void *OPENSSL_memchr(void *s, int c, size_t n) {
    676   if (n == 0) {
    677     return NULL;
    678   }
    679 
    680   return memchr(s, c, n);
    681 }
    682 
    683 }  // extern "C++"
    684 #else  // __cplusplus
    685 
    686 static inline void *OPENSSL_memchr(const void *s, int c, size_t n) {
    687   if (n == 0) {
    688     return NULL;
    689   }
    690 
    691   return memchr(s, c, n);
    692 }
    693 
    694 #endif  // __cplusplus
    695 
    696 static inline int OPENSSL_memcmp(const void *s1, const void *s2, size_t n) {
    697   if (n == 0) {
    698     return 0;
    699   }
    700 
    701   return memcmp(s1, s2, n);
    702 }
    703 
    704 static inline void *OPENSSL_memcpy(void *dst, const void *src, size_t n) {
    705   if (n == 0) {
    706     return dst;
    707   }
    708 
    709   return memcpy(dst, src, n);
    710 }
    711 
    712 static inline void *OPENSSL_memmove(void *dst, const void *src, size_t n) {
    713   if (n == 0) {
    714     return dst;
    715   }
    716 
    717   return memmove(dst, src, n);
    718 }
    719 
    720 static inline void *OPENSSL_memset(void *dst, int c, size_t n) {
    721   if (n == 0) {
    722     return dst;
    723   }
    724 
    725   return memset(dst, c, n);
    726 }
    727 
    728 #if defined(BORINGSSL_FIPS)
    729 // BORINGSSL_FIPS_abort is called when a FIPS power-on or continuous test
    730 // fails. It prevents any further cryptographic operations by the current
    731 // process.
    732 void BORINGSSL_FIPS_abort(void) __attribute__((noreturn));
    733 #endif
    734 
    735 #if defined(__cplusplus)
    736 }  // extern C
    737 #endif
    738 
    739 #endif  // OPENSSL_HEADER_CRYPTO_INTERNAL_H
    740