2 * Copyright (C) 2008 Tobias Brunner
3 * Copyright (C) 2008 Martin Willi
4 * Hochschule fuer Technik Rapperswil
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 #include <openssl/evp.h>
20 #include <openssl/engine.h>
21 #include <openssl/crypto.h>
24 #include "openssl_plugin.h"
27 #include <utils/mutex.h>
28 #include "openssl_crypter.h"
29 #include "openssl_hasher.h"
30 #include "openssl_diffie_hellman.h"
31 #include "openssl_ec_diffie_hellman.h"
32 #include "openssl_rsa_private_key.h"
33 #include "openssl_rsa_public_key.h"
34 #include "openssl_ec_private_key.h"
35 #include "openssl_ec_public_key.h"
37 typedef struct private_openssl_plugin_t private_openssl_plugin_t
;
40 * private data of openssl_plugin
42 struct private_openssl_plugin_t
{
47 openssl_plugin_t
public;
51 * Array of static mutexs, with CRYPTO_num_locks() mutex
53 static mutex_t
**mutex
= NULL
;
56 * Locking callback for static locks
58 static void locking_function(int mode
, int type
, const char *file
, int line
)
62 if (mode
& CRYPTO_LOCK
)
64 mutex
[type
]->lock(mutex
[type
]);
68 mutex
[type
]->unlock(mutex
[type
]);
74 * Implementation of dynlock
76 struct CRYPTO_dynlock_value
{
81 * Callback to create a dynamic lock
83 static struct CRYPTO_dynlock_value
*create_function(const char *file
, int line
)
85 struct CRYPTO_dynlock_value
*lock
;
87 lock
= malloc_thing(struct CRYPTO_dynlock_value
);
88 lock
->mutex
= mutex_create(MUTEX_DEFAULT
);
93 * Callback to (un-)lock a dynamic lock
95 static void lock_function(int mode
, struct CRYPTO_dynlock_value
*lock
,
96 const char *file
, int line
)
98 if (mode
& CRYPTO_LOCK
)
100 lock
->mutex
->lock(lock
->mutex
);
104 lock
->mutex
->unlock(lock
->mutex
);
109 * Callback to destroy a dynamic lock
111 static void destroy_function(struct CRYPTO_dynlock_value
*lock
,
112 const char *file
, int line
)
114 lock
->mutex
->destroy(lock
->mutex
);
119 * Thread-ID callback function
121 static unsigned long id_function(void)
123 return pthread_self();
127 * initialize OpenSSL for multi-threaded use
129 static void threading_init()
133 CRYPTO_set_id_callback(id_function
);
134 CRYPTO_set_locking_callback(locking_function
);
136 CRYPTO_set_dynlock_create_callback(create_function
);
137 CRYPTO_set_dynlock_lock_callback(lock_function
);
138 CRYPTO_set_dynlock_destroy_callback(destroy_function
);
140 num_locks
= CRYPTO_num_locks();
141 mutex
= malloc(sizeof(mutex_t
*) * num_locks
);
142 for (i
= 0; i
< num_locks
; i
++)
144 mutex
[i
] = mutex_create(MUTEX_DEFAULT
);
149 * cleanup OpenSSL threading locks
151 static void threading_cleanup()
155 num_locks
= CRYPTO_num_locks();
156 for (i
= 0; i
< num_locks
; i
++)
158 mutex
[i
]->destroy(mutex
[i
]);
165 * Implementation of openssl_plugin_t.destroy
167 static void destroy(private_openssl_plugin_t
*this)
169 lib
->crypto
->remove_crypter(lib
->crypto
,
170 (crypter_constructor_t
)openssl_crypter_create
);
171 lib
->crypto
->remove_hasher(lib
->crypto
,
172 (hasher_constructor_t
)openssl_hasher_create
);
173 lib
->crypto
->remove_dh(lib
->crypto
,
174 (dh_constructor_t
)openssl_diffie_hellman_create
);
175 lib
->crypto
->remove_dh(lib
->crypto
,
176 (dh_constructor_t
)openssl_ec_diffie_hellman_create
);
177 lib
->creds
->remove_builder(lib
->creds
,
178 (builder_constructor_t
)openssl_rsa_private_key_builder
);
179 lib
->creds
->remove_builder(lib
->creds
,
180 (builder_constructor_t
)openssl_rsa_public_key_builder
);
181 lib
->creds
->remove_builder(lib
->creds
,
182 (builder_constructor_t
)openssl_ec_private_key_builder
);
183 lib
->creds
->remove_builder(lib
->creds
,
184 (builder_constructor_t
)openssl_ec_public_key_builder
);
197 plugin_t
*plugin_create()
199 private_openssl_plugin_t
*this = malloc_thing(private_openssl_plugin_t
);
201 this->public.plugin
.destroy
= (void(*)(plugin_t
*))destroy
;
205 OpenSSL_add_all_algorithms();
207 /* activate support for hardware accelerators */
208 ENGINE_load_builtin_engines();
209 ENGINE_register_all_complete();
212 lib
->crypto
->add_crypter(lib
->crypto
, ENCR_AES_CBC
,
213 (crypter_constructor_t
)openssl_crypter_create
);
214 lib
->crypto
->add_crypter(lib
->crypto
, ENCR_3DES
,
215 (crypter_constructor_t
)openssl_crypter_create
);
216 lib
->crypto
->add_crypter(lib
->crypto
, ENCR_RC5
,
217 (crypter_constructor_t
)openssl_crypter_create
);
218 lib
->crypto
->add_crypter(lib
->crypto
, ENCR_IDEA
,
219 (crypter_constructor_t
)openssl_crypter_create
);
220 lib
->crypto
->add_crypter(lib
->crypto
, ENCR_CAST
,
221 (crypter_constructor_t
)openssl_crypter_create
);
222 lib
->crypto
->add_crypter(lib
->crypto
, ENCR_BLOWFISH
,
223 (crypter_constructor_t
)openssl_crypter_create
);
224 lib
->crypto
->add_crypter(lib
->crypto
, ENCR_DES
,
225 (crypter_constructor_t
)openssl_crypter_create
);
226 lib
->crypto
->add_crypter(lib
->crypto
, ENCR_NULL
,
227 (crypter_constructor_t
)openssl_crypter_create
);
230 lib
->crypto
->add_hasher(lib
->crypto
, HASH_SHA1
,
231 (hasher_constructor_t
)openssl_hasher_create
);
232 lib
->crypto
->add_hasher(lib
->crypto
, HASH_MD2
,
233 (hasher_constructor_t
)openssl_hasher_create
);
234 lib
->crypto
->add_hasher(lib
->crypto
, HASH_MD5
,
235 (hasher_constructor_t
)openssl_hasher_create
);
236 lib
->crypto
->add_hasher(lib
->crypto
, HASH_SHA256
,
237 (hasher_constructor_t
)openssl_hasher_create
);
238 lib
->crypto
->add_hasher(lib
->crypto
, HASH_SHA384
,
239 (hasher_constructor_t
)openssl_hasher_create
);
240 lib
->crypto
->add_hasher(lib
->crypto
, HASH_SHA512
,
241 (hasher_constructor_t
)openssl_hasher_create
);
243 /* ec diffie hellman */
244 lib
->crypto
->add_dh(lib
->crypto
, ECP_192_BIT
,
245 (dh_constructor_t
)openssl_ec_diffie_hellman_create
);
246 lib
->crypto
->add_dh(lib
->crypto
, ECP_224_BIT
,
247 (dh_constructor_t
)openssl_ec_diffie_hellman_create
);
248 lib
->crypto
->add_dh(lib
->crypto
, ECP_256_BIT
,
249 (dh_constructor_t
)openssl_ec_diffie_hellman_create
);
250 lib
->crypto
->add_dh(lib
->crypto
, ECP_384_BIT
,
251 (dh_constructor_t
)openssl_ec_diffie_hellman_create
);
252 lib
->crypto
->add_dh(lib
->crypto
, ECP_521_BIT
,
253 (dh_constructor_t
)openssl_ec_diffie_hellman_create
);
256 lib
->crypto
->add_dh(lib
->crypto
, MODP_2048_BIT
,
257 (dh_constructor_t
)openssl_diffie_hellman_create
);
258 lib
->crypto
->add_dh(lib
->crypto
, MODP_1536_BIT
,
259 (dh_constructor_t
)openssl_diffie_hellman_create
);
260 lib
->crypto
->add_dh(lib
->crypto
, MODP_3072_BIT
,
261 (dh_constructor_t
)openssl_diffie_hellman_create
);
262 lib
->crypto
->add_dh(lib
->crypto
, MODP_4096_BIT
,
263 (dh_constructor_t
)openssl_diffie_hellman_create
);
264 lib
->crypto
->add_dh(lib
->crypto
, MODP_6144_BIT
,
265 (dh_constructor_t
)openssl_diffie_hellman_create
);
266 lib
->crypto
->add_dh(lib
->crypto
, MODP_8192_BIT
,
267 (dh_constructor_t
)openssl_diffie_hellman_create
);
268 lib
->crypto
->add_dh(lib
->crypto
, MODP_1024_BIT
,
269 (dh_constructor_t
)openssl_diffie_hellman_create
);
270 lib
->crypto
->add_dh(lib
->crypto
, MODP_768_BIT
,
271 (dh_constructor_t
)openssl_diffie_hellman_create
);
274 lib
->creds
->add_builder(lib
->creds
, CRED_PRIVATE_KEY
, KEY_RSA
,
275 (builder_constructor_t
)openssl_rsa_private_key_builder
);
276 lib
->creds
->add_builder(lib
->creds
, CRED_PUBLIC_KEY
, KEY_RSA
,
277 (builder_constructor_t
)openssl_rsa_public_key_builder
);
280 lib
->creds
->add_builder(lib
->creds
, CRED_PRIVATE_KEY
, KEY_ECDSA
,
281 (builder_constructor_t
)openssl_ec_private_key_builder
);
282 lib
->creds
->add_builder(lib
->creds
, CRED_PUBLIC_KEY
, KEY_ECDSA
,
283 (builder_constructor_t
)openssl_ec_public_key_builder
);
285 return &this->public.plugin
;