xref: /freebsd/crypto/openssl/crypto/threads_none.c (revision f25b8c9fb4f58cf61adb47d7570abe7caa6d385d)
1 /*
2  * Copyright 2016-2025 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_call(CRYPTO_RCU_LOCK * lock,rcu_cb_fn cb,void * data)76 int ossl_rcu_call(CRYPTO_RCU_LOCK *lock, rcu_cb_fn cb, void *data)
77 {
78     struct rcu_cb_item *new = OPENSSL_zalloc(sizeof(*new));
79 
80     if (new == NULL)
81         return 0;
82 
83     new->fn = cb;
84     new->data = data;
85     new->next = lock->cb_items;
86     lock->cb_items = new;
87     return 1;
88 }
89 
ossl_rcu_uptr_deref(void ** p)90 void *ossl_rcu_uptr_deref(void **p)
91 {
92     return (void *)*p;
93 }
94 
ossl_rcu_assign_uptr(void ** p,void ** v)95 void ossl_rcu_assign_uptr(void **p, void **v)
96 {
97     *(void **)p = *(void **)v;
98 }
99 
CRYPTO_THREAD_lock_new(void)100 CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void)
101 {
102     CRYPTO_RWLOCK *lock;
103 
104     if ((lock = CRYPTO_zalloc(sizeof(unsigned int), NULL, 0)) == NULL)
105         /* Don't set error, to avoid recursion blowup. */
106         return NULL;
107 
108     *(unsigned int *)lock = 1;
109 
110     return lock;
111 }
112 
CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK * lock)113 __owur int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock)
114 {
115     if (!ossl_assert(*(unsigned int *)lock == 1))
116         return 0;
117     return 1;
118 }
119 
CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK * lock)120 __owur int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock)
121 {
122     if (!ossl_assert(*(unsigned int *)lock == 1))
123         return 0;
124     return 1;
125 }
126 
CRYPTO_THREAD_unlock(CRYPTO_RWLOCK * lock)127 int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock)
128 {
129     if (!ossl_assert(*(unsigned int *)lock == 1))
130         return 0;
131     return 1;
132 }
133 
CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK * lock)134 void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock)
135 {
136     if (lock == NULL)
137         return;
138 
139     *(unsigned int *)lock = 0;
140     OPENSSL_free(lock);
141 
142     return;
143 }
144 
CRYPTO_THREAD_run_once(CRYPTO_ONCE * once,void (* init)(void))145 int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void))
146 {
147     if (*once != 0)
148         return 1;
149 
150     init();
151     *once = 1;
152 
153     return 1;
154 }
155 
156 #define OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX 256
157 
158 struct thread_local_storage_entry {
159     void *data;
160     uint8_t used;
161 };
162 
163 static struct thread_local_storage_entry thread_local_storage[OPENSSL_CRYPTO_THREAD_LOCAL_KEY_MAX];
164 
CRYPTO_THREAD_init_local(CRYPTO_THREAD_LOCAL * key,void (* cleanup)(void *))165 int CRYPTO_THREAD_init_local(CRYPTO_THREAD_LOCAL *key, void (*cleanup)(void *))
166 {
167     int entry_idx = 0;
168 
169 #ifndef FIPS_MODULE
170     if (!ossl_init_thread())
171         return 0;
172 #endif
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 0;
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