-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathossl_locking.cc
101 lines (85 loc) · 3.05 KB
/
ossl_locking.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/* This file is part of libtrevisan, a modular implementation of
Trevisan's randomness extraction construction.
Copyright (C) 2011-2012, Wolfgang Mauerer <[email protected]>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with libtrevisan. If not, see <http://www.gnu.org/licenses/>. */
#include<iostream>
#include<vector>
#include<mutex>
#include<openssl/crypto.h>
#include <pthread.h>
struct CRYPTO_dynlock_value {
std::mutex mutex;
};
using namespace std;
static vector<class std::mutex*> ossl_mutexes;
#if OPENSSL_VERSION_NUMBER >= 0x01000000f
static void ossl_thread_id(CRYPTO_THREADID *id) {
#if EXPENSIVE_SANITY_CHECKS
cerr << "pthreads_thread_id=" << pthread_self() << " determined" << endl;
#endif
CRYPTO_THREADID_set_pointer(id, (void*) pthread_self());
}
#else
static unsigned long ossl_thread_id() {
#if EXPENSIVE_SANITY_CHECKS
cerr << "pthreads_thread_id=" << pthread_self() << " determined" << endl;
#endif
return (unsigned long)pthread_self();
}
#endif
static void ossl_locking_callback(int mode, int type, const char *file, int line) {
#if EXPENSIVE_SANITY_CHECKS
cerr << "thread=" << pthread_self() << ", " << "mode="
<< ((mode&CRYPTO_LOCK)?"l":"u") << ", lock="
<< ((type&CRYPTO_READ)?"r":"w") << ", file=" << file
<< ", line=" << line << endl;
#endif
if (mode & CRYPTO_LOCK) {
ossl_mutexes[type]->lock();
} else {
ossl_mutexes[type]->unlock();
}
}
static void ossl_dynlock_lock(int mode, struct CRYPTO_dynlock_value *lock,
const char *file, int line) {
cout << "OPENSSL: dynlock operation @" << lock << endl;
if (mode & CRYPTO_LOCK) {
lock->mutex.lock();
} else {
lock->mutex.unlock();
}
}
static struct CRYPTO_dynlock_value *ossl_dynlock_create(const char *file, int line) {
struct CRYPTO_dynlock_value *lock = new CRYPTO_dynlock_value;
cout << "OPENSSL: Created new dynamic lock @" << lock << endl;
return lock;
}
static void ossl_dynlock_destroy(struct CRYPTO_dynlock_value *lock, const char *file,
int line) {
delete lock;
}
void init_openssl_locking() {
unsigned num_locks = CRYPTO_num_locks();
ossl_mutexes.reserve(num_locks);
for (unsigned i=0; i < num_locks; i++) {
ossl_mutexes.push_back(new std::mutex());
}
#if OPENSSL_VERSION_NUMBER >= 0x01000000f
CRYPTO_THREADID_set_callback(ossl_thread_id);
#else
CRYPTO_set_id_callback(ossl_thread_id);
#endif
CRYPTO_set_locking_callback(ossl_locking_callback);
CRYPTO_set_dynlock_create_callback(ossl_dynlock_create);
CRYPTO_set_dynlock_destroy_callback(ossl_dynlock_destroy);
CRYPTO_set_dynlock_lock_callback(ossl_dynlock_lock);
}