1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci */
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci#include <openssl/crypto.h>
11e1051a39Sopenharmony_ci#include "internal/cryptlib.h"
12e1051a39Sopenharmony_ci
13e1051a39Sopenharmony_ci#if !defined(OPENSSL_THREADS) || defined(CRYPTO_TDEBUG)
14e1051a39Sopenharmony_ci
15e1051a39Sopenharmony_ci# if defined(OPENSSL_SYS_UNIX)
16e1051a39Sopenharmony_ci#  include <sys/types.h>
17e1051a39Sopenharmony_ci#  include <unistd.h>
18e1051a39Sopenharmony_ci# endif
19e1051a39Sopenharmony_ci
20e1051a39Sopenharmony_ciCRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void)
21e1051a39Sopenharmony_ci{
22e1051a39Sopenharmony_ci    CRYPTO_RWLOCK *lock;
23e1051a39Sopenharmony_ci
24e1051a39Sopenharmony_ci    if ((lock = OPENSSL_zalloc(sizeof(unsigned int))) == NULL) {
25e1051a39Sopenharmony_ci        /* Don't set error, to avoid recursion blowup. */
26e1051a39Sopenharmony_ci        return NULL;
27e1051a39Sopenharmony_ci    }
28e1051a39Sopenharmony_ci
29e1051a39Sopenharmony_ci    *(unsigned int *)lock = 1;
30e1051a39Sopenharmony_ci
31e1051a39Sopenharmony_ci    return lock;
32e1051a39Sopenharmony_ci}
33e1051a39Sopenharmony_ci
34e1051a39Sopenharmony_ci__owur int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock)
35e1051a39Sopenharmony_ci{
36e1051a39Sopenharmony_ci    if (!ossl_assert(*(unsigned int *)lock == 1))
37e1051a39Sopenharmony_ci        return 0;
38e1051a39Sopenharmony_ci    return 1;
39e1051a39Sopenharmony_ci}
40e1051a39Sopenharmony_ci
41e1051a39Sopenharmony_ci__owur int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock)
42e1051a39Sopenharmony_ci{
43e1051a39Sopenharmony_ci    if (!ossl_assert(*(unsigned int *)lock == 1))
44e1051a39Sopenharmony_ci        return 0;
45e1051a39Sopenharmony_ci    return 1;
46e1051a39Sopenharmony_ci}
47e1051a39Sopenharmony_ci
48e1051a39Sopenharmony_ciint CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock)
49e1051a39Sopenharmony_ci{
50e1051a39Sopenharmony_ci    if (!ossl_assert(*(unsigned int *)lock == 1))
51e1051a39Sopenharmony_ci        return 0;
52e1051a39Sopenharmony_ci    return 1;
53e1051a39Sopenharmony_ci}
54e1051a39Sopenharmony_ci
55e1051a39Sopenharmony_civoid CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock) {
56e1051a39Sopenharmony_ci    if (lock == NULL)
57e1051a39Sopenharmony_ci        return;
58e1051a39Sopenharmony_ci
59e1051a39Sopenharmony_ci    *(unsigned int *)lock = 0;
60e1051a39Sopenharmony_ci    OPENSSL_free(lock);
61e1051a39Sopenharmony_ci
62e1051a39Sopenharmony_ci    return;
63e1051a39Sopenharmony_ci}
64e1051a39Sopenharmony_ci
65e1051a39Sopenharmony_ciint CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void))
66e1051a39Sopenharmony_ci{
67e1051a39Sopenharmony_ci    if (*once != 0)
68e1051a39Sopenharmony_ci        return 1;
69e1051a39Sopenharmony_ci
70e1051a39Sopenharmony_ci    init();
71e1051a39Sopenharmony_ci    *once = 1;
72e1051a39Sopenharmony_ci
73e1051a39Sopenharmony_ci    return 1;
74e1051a39Sopenharmony_ci}
75e1051a39Sopenharmony_ci
76e1051a39Sopenharmony_ci#define OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX 256
77e1051a39Sopenharmony_ci
78e1051a39Sopenharmony_cistatic void *thread_local_storage[OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX];
79e1051a39Sopenharmony_ci
80e1051a39Sopenharmony_ciint CRYPTO_THREAD_init_local(CRYPTO_THREAD_LOCAL *key, void (*cleanup)(void *))
81e1051a39Sopenharmony_ci{
82e1051a39Sopenharmony_ci    static unsigned int thread_local_key = 0;
83e1051a39Sopenharmony_ci
84e1051a39Sopenharmony_ci    if (thread_local_key >= OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX)
85e1051a39Sopenharmony_ci        return 0;
86e1051a39Sopenharmony_ci
87e1051a39Sopenharmony_ci    *key = thread_local_key++;
88e1051a39Sopenharmony_ci
89e1051a39Sopenharmony_ci    thread_local_storage[*key] = NULL;
90e1051a39Sopenharmony_ci
91e1051a39Sopenharmony_ci    return 1;
92e1051a39Sopenharmony_ci}
93e1051a39Sopenharmony_ci
94e1051a39Sopenharmony_civoid *CRYPTO_THREAD_get_local(CRYPTO_THREAD_LOCAL *key)
95e1051a39Sopenharmony_ci{
96e1051a39Sopenharmony_ci    if (*key >= OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX)
97e1051a39Sopenharmony_ci        return NULL;
98e1051a39Sopenharmony_ci
99e1051a39Sopenharmony_ci    return thread_local_storage[*key];
100e1051a39Sopenharmony_ci}
101e1051a39Sopenharmony_ci
102e1051a39Sopenharmony_ciint CRYPTO_THREAD_set_local(CRYPTO_THREAD_LOCAL *key, void *val)
103e1051a39Sopenharmony_ci{
104e1051a39Sopenharmony_ci    if (*key >= OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX)
105e1051a39Sopenharmony_ci        return 0;
106e1051a39Sopenharmony_ci
107e1051a39Sopenharmony_ci    thread_local_storage[*key] = val;
108e1051a39Sopenharmony_ci
109e1051a39Sopenharmony_ci    return 1;
110e1051a39Sopenharmony_ci}
111e1051a39Sopenharmony_ci
112e1051a39Sopenharmony_ciint CRYPTO_THREAD_cleanup_local(CRYPTO_THREAD_LOCAL *key)
113e1051a39Sopenharmony_ci{
114e1051a39Sopenharmony_ci    *key = OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX + 1;
115e1051a39Sopenharmony_ci    return 1;
116e1051a39Sopenharmony_ci}
117e1051a39Sopenharmony_ci
118e1051a39Sopenharmony_ciCRYPTO_THREAD_ID CRYPTO_THREAD_get_current_id(void)
119e1051a39Sopenharmony_ci{
120e1051a39Sopenharmony_ci    return 0;
121e1051a39Sopenharmony_ci}
122e1051a39Sopenharmony_ci
123e1051a39Sopenharmony_ciint CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a, CRYPTO_THREAD_ID b)
124e1051a39Sopenharmony_ci{
125e1051a39Sopenharmony_ci    return (a == b);
126e1051a39Sopenharmony_ci}
127e1051a39Sopenharmony_ci
128e1051a39Sopenharmony_ciint CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock)
129e1051a39Sopenharmony_ci{
130e1051a39Sopenharmony_ci    *val += amount;
131e1051a39Sopenharmony_ci    *ret  = *val;
132e1051a39Sopenharmony_ci
133e1051a39Sopenharmony_ci    return 1;
134e1051a39Sopenharmony_ci}
135e1051a39Sopenharmony_ci
136e1051a39Sopenharmony_ciint CRYPTO_atomic_or(uint64_t *val, uint64_t op, uint64_t *ret,
137e1051a39Sopenharmony_ci                     CRYPTO_RWLOCK *lock)
138e1051a39Sopenharmony_ci{
139e1051a39Sopenharmony_ci    *val |= op;
140e1051a39Sopenharmony_ci    *ret  = *val;
141e1051a39Sopenharmony_ci
142e1051a39Sopenharmony_ci    return 1;
143e1051a39Sopenharmony_ci}
144e1051a39Sopenharmony_ci
145e1051a39Sopenharmony_ciint CRYPTO_atomic_load(uint64_t *val, uint64_t *ret, CRYPTO_RWLOCK *lock)
146e1051a39Sopenharmony_ci{
147e1051a39Sopenharmony_ci    *ret  = *val;
148e1051a39Sopenharmony_ci
149e1051a39Sopenharmony_ci    return 1;
150e1051a39Sopenharmony_ci}
151e1051a39Sopenharmony_ci
152e1051a39Sopenharmony_ciint openssl_init_fork_handlers(void)
153e1051a39Sopenharmony_ci{
154e1051a39Sopenharmony_ci    return 0;
155e1051a39Sopenharmony_ci}
156e1051a39Sopenharmony_ci
157e1051a39Sopenharmony_ciint openssl_get_fork_id(void)
158e1051a39Sopenharmony_ci{
159e1051a39Sopenharmony_ci# if defined(OPENSSL_SYS_UNIX)
160e1051a39Sopenharmony_ci    return getpid();
161e1051a39Sopenharmony_ci# else
162e1051a39Sopenharmony_ci    return 0;
163e1051a39Sopenharmony_ci# endif
164e1051a39Sopenharmony_ci}
165e1051a39Sopenharmony_ci#endif
166