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