xref: /freebsd/crypto/openssl/crypto/threads_none.c (revision 1523ccfd9c8c254f7928143d31c305384b05fd11)
1 /*
2  * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 #include <openssl/crypto.h>
11 #include "internal/cryptlib.h"
12 #include "internal/rcu.h"
13 #include "crypto/cryptlib.h"
14 #include "rcu_internal.h"
15 
16 #if !defined(OPENSSL_THREADS) || defined(CRYPTO_TDEBUG)
17 
18 #if defined(OPENSSL_SYS_UNIX)
19 #include <sys/types.h>
20 #include <unistd.h>
21 #endif
22 
23 struct rcu_lock_st {
24     struct rcu_cb_item *cb_items;
25 };
26 
ossl_rcu_lock_new(int num_writers,ossl_unused OSSL_LIB_CTX * ctx)27 CRYPTO_RCU_LOCK *ossl_rcu_lock_new(int num_writers,
28     ossl_unused OSSL_LIB_CTX *ctx)
29 {
30     struct rcu_lock_st *lock;
31 
32     lock = OPENSSL_zalloc(sizeof(*lock));
33     return lock;
34 }
35 
ossl_rcu_lock_free(CRYPTO_RCU_LOCK * lock)36 void ossl_rcu_lock_free(CRYPTO_RCU_LOCK *lock)
37 {
38     OPENSSL_free(lock);
39 }
40 
ossl_rcu_read_lock(CRYPTO_RCU_LOCK * lock)41 void ossl_rcu_read_lock(CRYPTO_RCU_LOCK *lock)
42 {
43     return;
44 }
45 
ossl_rcu_write_lock(CRYPTO_RCU_LOCK * lock)46 void ossl_rcu_write_lock(CRYPTO_RCU_LOCK *lock)
47 {
48     return;
49 }
50 
ossl_rcu_write_unlock(CRYPTO_RCU_LOCK * lock)51 void ossl_rcu_write_unlock(CRYPTO_RCU_LOCK *lock)
52 {
53     return;
54 }
55 
ossl_rcu_read_unlock(CRYPTO_RCU_LOCK * lock)56 void ossl_rcu_read_unlock(CRYPTO_RCU_LOCK *lock)
57 {
58     return;
59 }
60 
ossl_synchronize_rcu(CRYPTO_RCU_LOCK * lock)61 void ossl_synchronize_rcu(CRYPTO_RCU_LOCK *lock)
62 {
63     struct rcu_cb_item *items = lock->cb_items;
64     struct rcu_cb_item *tmp;
65 
66     lock->cb_items = NULL;
67 
68     while (items != NULL) {
69         tmp = items->next;
70         items->fn(items->data);
71         OPENSSL_free(items);
72         items = tmp;
73     }
74 }
75 
ossl_rcu_cb_item_new(void)76 CRYPTO_RCU_CB_ITEM *ossl_rcu_cb_item_new(void)
77 {
78     return OPENSSL_zalloc(sizeof(CRYPTO_RCU_CB_ITEM));
79 }
80 
ossl_rcu_cb_item_free(CRYPTO_RCU_CB_ITEM * item)81 void ossl_rcu_cb_item_free(CRYPTO_RCU_CB_ITEM *item)
82 {
83     OPENSSL_free(item);
84 }
85 
ossl_rcu_call(CRYPTO_RCU_LOCK * lock,CRYPTO_RCU_CB_ITEM * item,rcu_cb_fn cb,void * data)86 void ossl_rcu_call(CRYPTO_RCU_LOCK *lock, CRYPTO_RCU_CB_ITEM *item,
87     rcu_cb_fn cb, void *data)
88 {
89     item->fn = cb;
90     item->data = data;
91     item->next = lock->cb_items;
92     lock->cb_items = item;
93 }
94 
ossl_rcu_uptr_deref(void ** p)95 void *ossl_rcu_uptr_deref(void **p)
96 {
97     return (void *)*p;
98 }
99 
ossl_rcu_assign_uptr(void ** p,void ** v)100 void ossl_rcu_assign_uptr(void **p, void **v)
101 {
102     *(void **)p = *(void **)v;
103 }
104 
CRYPTO_THREAD_lock_new(void)105 CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void)
106 {
107     CRYPTO_RWLOCK *lock;
108 
109     if ((lock = CRYPTO_zalloc(sizeof(unsigned int), NULL, 0)) == NULL)
110         /* Don't set error, to avoid recursion blowup. */
111         return NULL;
112 
113     *(unsigned int *)lock = 1;
114 
115     return lock;
116 }
117 
CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK * lock)118 __owur int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock)
119 {
120     if (!ossl_assert(*(unsigned int *)lock == 1))
121         return 0;
122     return 1;
123 }
124 
CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK * lock)125 __owur int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock)
126 {
127     if (!ossl_assert(*(unsigned int *)lock == 1))
128         return 0;
129     return 1;
130 }
131 
CRYPTO_THREAD_unlock(CRYPTO_RWLOCK * lock)132 int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock)
133 {
134     if (!ossl_assert(*(unsigned int *)lock == 1))
135         return 0;
136     return 1;
137 }
138 
CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK * lock)139 void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock)
140 {
141     if (lock == NULL)
142         return;
143 
144     *(unsigned int *)lock = 0;
145     OPENSSL_free(lock);
146 
147     return;
148 }
149 
CRYPTO_THREAD_run_once(CRYPTO_ONCE * once,void (* init)(void))150 int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void))
151 {
152     if (*once != 0)
153         return 1;
154 
155     init();
156     *once = 1;
157 
158     return 1;
159 }
160 
161 #define OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX 256
162 
163 struct thread_local_storage_entry {
164     void *data;
165     uint8_t used;
166 };
167 
168 static struct thread_local_storage_entry thread_local_storage[OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX];
169 
ossl_thread_init_local(CRYPTO_THREAD_LOCAL * key,void (* cleanup)(void *))170 int ossl_thread_init_local(CRYPTO_THREAD_LOCAL *key, void (*cleanup)(void *))
171 {
172     int entry_idx = 0;
173 
174     for (entry_idx = 0; entry_idx < OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX; entry_idx++) {
175         if (!thread_local_storage[entry_idx].used)
176             break;
177     }
178 
179     if (entry_idx == OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX)
180         return 0;
181 
182     *key = entry_idx;
183     thread_local_storage[*key].used = 1;
184     thread_local_storage[*key].data = NULL;
185 
186     return 1;
187 }
188 
CRYPTO_THREAD_get_local(CRYPTO_THREAD_LOCAL * key)189 void *CRYPTO_THREAD_get_local(CRYPTO_THREAD_LOCAL *key)
190 {
191     if (*key >= OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX)
192         return NULL;
193 
194     return thread_local_storage[*key].data;
195 }
196 
CRYPTO_THREAD_set_local(CRYPTO_THREAD_LOCAL * key,void * val)197 int CRYPTO_THREAD_set_local(CRYPTO_THREAD_LOCAL *key, void *val)
198 {
199     if (*key >= OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX)
200         return 0;
201 
202     thread_local_storage[*key].data = val;
203 
204     return 1;
205 }
206 
CRYPTO_THREAD_cleanup_local(CRYPTO_THREAD_LOCAL * key)207 int CRYPTO_THREAD_cleanup_local(CRYPTO_THREAD_LOCAL *key)
208 {
209     if (*key >= OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX)
210         return 0;
211 
212     thread_local_storage[*key].used = 0;
213     thread_local_storage[*key].data = NULL;
214     *key = OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX + 1;
215     return 1;
216 }
217 
CRYPTO_THREAD_get_current_id(void)218 CRYPTO_THREAD_ID CRYPTO_THREAD_get_current_id(void)
219 {
220     return 1;
221 }
222 
CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a,CRYPTO_THREAD_ID b)223 int CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a, CRYPTO_THREAD_ID b)
224 {
225     return (a == b);
226 }
227 
CRYPTO_atomic_add(int * val,int amount,int * ret,CRYPTO_RWLOCK * lock)228 int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock)
229 {
230     *val += amount;
231     *ret = *val;
232 
233     return 1;
234 }
235 
CRYPTO_atomic_add64(uint64_t * val,uint64_t op,uint64_t * ret,CRYPTO_RWLOCK * lock)236 int CRYPTO_atomic_add64(uint64_t *val, uint64_t op, uint64_t *ret,
237     CRYPTO_RWLOCK *lock)
238 {
239     *val += op;
240     *ret = *val;
241 
242     return 1;
243 }
244 
CRYPTO_atomic_and(uint64_t * val,uint64_t op,uint64_t * ret,CRYPTO_RWLOCK * lock)245 int CRYPTO_atomic_and(uint64_t *val, uint64_t op, uint64_t *ret,
246     CRYPTO_RWLOCK *lock)
247 {
248     *val &= op;
249     *ret = *val;
250 
251     return 1;
252 }
253 
CRYPTO_atomic_or(uint64_t * val,uint64_t op,uint64_t * ret,CRYPTO_RWLOCK * lock)254 int CRYPTO_atomic_or(uint64_t *val, uint64_t op, uint64_t *ret,
255     CRYPTO_RWLOCK *lock)
256 {
257     *val |= op;
258     *ret = *val;
259 
260     return 1;
261 }
262 
CRYPTO_atomic_load(uint64_t * val,uint64_t * ret,CRYPTO_RWLOCK * lock)263 int CRYPTO_atomic_load(uint64_t *val, uint64_t *ret, CRYPTO_RWLOCK *lock)
264 {
265     *ret = *val;
266 
267     return 1;
268 }
269 
CRYPTO_atomic_store(uint64_t * dst,uint64_t val,CRYPTO_RWLOCK * lock)270 int CRYPTO_atomic_store(uint64_t *dst, uint64_t val, CRYPTO_RWLOCK *lock)
271 {
272     *dst = val;
273 
274     return 1;
275 }
276 
CRYPTO_atomic_load_int(int * val,int * ret,CRYPTO_RWLOCK * lock)277 int CRYPTO_atomic_load_int(int *val, int *ret, CRYPTO_RWLOCK *lock)
278 {
279     *ret = *val;
280 
281     return 1;
282 }
283 
openssl_init_fork_handlers(void)284 int openssl_init_fork_handlers(void)
285 {
286     return 0;
287 }
288 
openssl_get_fork_id(void)289 int openssl_get_fork_id(void)
290 {
291 #if defined(OPENSSL_SYS_UNIX)
292     return getpid();
293 #else
294     return 0;
295 #endif
296 }
297 #endif
298