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