5ba00d4da4fe57036efd38559c3f6b51cb85282d
[strongswan.git] / src / libstrongswan / plugins / openssl / openssl_plugin.c
1 /*
2 * Copyright (C) 2008 Tobias Brunner
3 * Copyright (C) 2008 Martin Willi
4 * Hochschule fuer Technik Rapperswil
5 *
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>.
10 *
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
14 * for more details.
15 */
16
17 #include <openssl/evp.h>
18 #include <openssl/conf.h>
19 #include <openssl/rand.h>
20 #include <openssl/crypto.h>
21 #ifndef OPENSSL_NO_ENGINE
22 #include <openssl/engine.h>
23 #endif
24
25 #include "openssl_plugin.h"
26
27 #include <library.h>
28 #include <debug.h>
29 #include <threading/thread.h>
30 #include <threading/mutex.h>
31 #include "openssl_util.h"
32 #include "openssl_crypter.h"
33 #include "openssl_hasher.h"
34 #include "openssl_sha1_prf.h"
35 #include "openssl_diffie_hellman.h"
36 #include "openssl_ec_diffie_hellman.h"
37 #include "openssl_rsa_private_key.h"
38 #include "openssl_rsa_public_key.h"
39 #include "openssl_ec_private_key.h"
40 #include "openssl_ec_public_key.h"
41 #include "openssl_x509.h"
42 #include "openssl_crl.h"
43 #include "openssl_rng.h"
44 #include "openssl_hmac_prf.h"
45
46 typedef struct private_openssl_plugin_t private_openssl_plugin_t;
47
48 /**
49 * private data of openssl_plugin
50 */
51 struct private_openssl_plugin_t {
52
53 /**
54 * public functions
55 */
56 openssl_plugin_t public;
57 };
58
59 /**
60 * Array of static mutexs, with CRYPTO_num_locks() mutex
61 */
62 static mutex_t **mutex = NULL;
63
64 /**
65 * Locking callback for static locks
66 */
67 static void locking_function(int mode, int type, const char *file, int line)
68 {
69 if (mutex)
70 {
71 if (mode & CRYPTO_LOCK)
72 {
73 mutex[type]->lock(mutex[type]);
74 }
75 else
76 {
77 mutex[type]->unlock(mutex[type]);
78 }
79 }
80 }
81
82 /**
83 * Implementation of dynlock
84 */
85 struct CRYPTO_dynlock_value {
86 mutex_t *mutex;
87 };
88
89 /**
90 * Callback to create a dynamic lock
91 */
92 static struct CRYPTO_dynlock_value *create_function(const char *file, int line)
93 {
94 struct CRYPTO_dynlock_value *lock;
95
96 lock = malloc_thing(struct CRYPTO_dynlock_value);
97 lock->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
98 return lock;
99 }
100
101 /**
102 * Callback to (un-)lock a dynamic lock
103 */
104 static void lock_function(int mode, struct CRYPTO_dynlock_value *lock,
105 const char *file, int line)
106 {
107 if (mode & CRYPTO_LOCK)
108 {
109 lock->mutex->lock(lock->mutex);
110 }
111 else
112 {
113 lock->mutex->unlock(lock->mutex);
114 }
115 }
116
117 /**
118 * Callback to destroy a dynamic lock
119 */
120 static void destroy_function(struct CRYPTO_dynlock_value *lock,
121 const char *file, int line)
122 {
123 lock->mutex->destroy(lock->mutex);
124 free(lock);
125 }
126
127 /**
128 * Thread-ID callback function
129 */
130 static unsigned long id_function(void)
131 {
132 return (unsigned long)thread_current_id();
133 }
134
135 /**
136 * initialize OpenSSL for multi-threaded use
137 */
138 static void threading_init()
139 {
140 int i, num_locks;
141
142 CRYPTO_set_id_callback(id_function);
143 CRYPTO_set_locking_callback(locking_function);
144
145 CRYPTO_set_dynlock_create_callback(create_function);
146 CRYPTO_set_dynlock_lock_callback(lock_function);
147 CRYPTO_set_dynlock_destroy_callback(destroy_function);
148
149 num_locks = CRYPTO_num_locks();
150 mutex = malloc(sizeof(mutex_t*) * num_locks);
151 for (i = 0; i < num_locks; i++)
152 {
153 mutex[i] = mutex_create(MUTEX_TYPE_DEFAULT);
154 }
155 }
156
157 /**
158 * Seed the OpenSSL RNG, if required
159 */
160 static bool seed_rng()
161 {
162 rng_t *rng = NULL;
163 char buf[32];
164
165 while (RAND_status() != 1)
166 {
167 if (!rng)
168 {
169 rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
170 if (!rng)
171 {
172 return FALSE;
173 }
174 }
175 rng->get_bytes(rng, sizeof(buf), buf);
176 RAND_seed(buf, sizeof(buf));
177 }
178 DESTROY_IF(rng);
179 return TRUE;
180 }
181
182 /**
183 * cleanup OpenSSL threading locks
184 */
185 static void threading_cleanup()
186 {
187 int i, num_locks;
188
189 num_locks = CRYPTO_num_locks();
190 for (i = 0; i < num_locks; i++)
191 {
192 mutex[i]->destroy(mutex[i]);
193 }
194 free(mutex);
195 mutex = NULL;
196 }
197
198 METHOD(plugin_t, get_name, char*,
199 private_openssl_plugin_t *this)
200 {
201 return "openssl";
202 }
203
204 METHOD(plugin_t, get_features, int,
205 private_openssl_plugin_t *this, plugin_feature_t *features[])
206 {
207 static plugin_feature_t f[] = {
208 /* crypters */
209 PLUGIN_REGISTER(CRYPTER, openssl_crypter_create),
210 #ifndef OPENSSL_NO_AES
211 PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 16),
212 PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 24),
213 PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 32),
214 #endif
215 #ifndef OPENSSL_NO_CAMELLIA
216 PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 16),
217 PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 24),
218 PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 32),
219 #endif
220 #ifndef OPENSSL_NO_RC5
221 PLUGIN_PROVIDE(CRYPTER, ENCR_RC5, 0),
222 #endif
223 #ifndef OPENSSL_NO_CAST
224 PLUGIN_PROVIDE(CRYPTER, ENCR_CAST, 0),
225 #endif
226 #ifndef OPENSSL_NO_BLOWFISH
227 PLUGIN_PROVIDE(CRYPTER, ENCR_BLOWFISH, 0),
228 #endif
229 #ifndef OPENSSL_NO_IDEA
230 PLUGIN_PROVIDE(CRYPTER, ENCR_IDEA, 16),
231 #endif
232 #ifndef OPENSSL_NO_DES
233 PLUGIN_PROVIDE(CRYPTER, ENCR_3DES, 24),
234 PLUGIN_PROVIDE(CRYPTER, ENCR_DES, 8),
235 PLUGIN_PROVIDE(CRYPTER, ENCR_DES_ECB, 8),
236 #endif
237 PLUGIN_PROVIDE(CRYPTER, ENCR_NULL, 0),
238 /* hashers */
239 PLUGIN_REGISTER(HASHER, openssl_hasher_create),
240 #ifndef OPENSSL_NO_SHA1
241 PLUGIN_PROVIDE(HASHER, HASH_SHA1),
242 #endif
243 #ifndef OPENSSL_NO_MD2
244 PLUGIN_PROVIDE(HASHER, HASH_MD2),
245 #endif
246 #ifndef OPENSSL_NO_MD4
247 PLUGIN_PROVIDE(HASHER, HASH_MD4),
248 #endif
249 #ifndef OPENSSL_NO_MD5
250 PLUGIN_PROVIDE(HASHER, HASH_MD5),
251 #endif
252 #ifndef OPENSSL_NO_SHA256
253 PLUGIN_PROVIDE(HASHER, HASH_SHA224),
254 PLUGIN_PROVIDE(HASHER, HASH_SHA256),
255 #endif
256 #ifndef OPENSSL_NO_SHA512
257 PLUGIN_PROVIDE(HASHER, HASH_SHA384),
258 PLUGIN_PROVIDE(HASHER, HASH_SHA512),
259 #endif
260 #ifndef OPENSSL_NO_SHA1
261 /* keyed sha1 hasher (aka prf) */
262 PLUGIN_REGISTER(PRF, openssl_sha1_prf_create),
263 PLUGIN_PROVIDE(PRF, PRF_KEYED_SHA1),
264 #endif
265 #ifndef OPENSSL_NO_HMAC
266 PLUGIN_REGISTER(PRF, openssl_hmac_prf_create),
267 #ifndef OPENSSL_NO_MD5
268 PLUGIN_PROVIDE(PRF, PRF_HMAC_MD5),
269 #endif
270 #ifndef OPENSSL_NO_SHA1
271 PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA1),
272 #endif
273 #ifndef OPENSSL_NO_SHA256
274 PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA2_256),
275 #endif
276 #ifndef OPENSSL_NO_SHA512
277 PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA2_384),
278 PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA2_512),
279 #endif
280 #endif /* OPENSSL_NO_HMAC */
281 #ifndef OPENSSL_NO_DH
282 /* MODP DH groups */
283 PLUGIN_REGISTER(DH, openssl_diffie_hellman_create),
284 PLUGIN_PROVIDE(DH, MODP_2048_BIT),
285 PLUGIN_PROVIDE(DH, MODP_2048_224),
286 PLUGIN_PROVIDE(DH, MODP_2048_256),
287 PLUGIN_PROVIDE(DH, MODP_1536_BIT),
288 PLUGIN_PROVIDE(DH, MODP_3072_BIT),
289 PLUGIN_PROVIDE(DH, MODP_4096_BIT),
290 PLUGIN_PROVIDE(DH, MODP_6144_BIT),
291 PLUGIN_PROVIDE(DH, MODP_8192_BIT),
292 PLUGIN_PROVIDE(DH, MODP_1024_BIT),
293 PLUGIN_PROVIDE(DH, MODP_1024_160),
294 PLUGIN_PROVIDE(DH, MODP_768_BIT),
295 PLUGIN_PROVIDE(DH, MODP_CUSTOM),
296 #endif
297 #ifndef OPENSSL_NO_RSA
298 /* RSA private/public key loading */
299 PLUGIN_REGISTER(PRIVKEY, openssl_rsa_private_key_load, TRUE),
300 PLUGIN_PROVIDE(PRIVKEY, KEY_RSA),
301 PLUGIN_REGISTER(PRIVKEY, openssl_rsa_private_key_connect, FALSE),
302 PLUGIN_PROVIDE(PRIVKEY, KEY_ANY),
303 PLUGIN_REGISTER(PRIVKEY_GEN, openssl_rsa_private_key_gen, FALSE),
304 PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_RSA),
305 PLUGIN_REGISTER(PUBKEY, openssl_rsa_public_key_load, FALSE),
306 PLUGIN_PROVIDE(PUBKEY, KEY_RSA),
307 PLUGIN_REGISTER(PUBKEY, openssl_rsa_public_key_load, TRUE),
308 PLUGIN_PROVIDE(PUBKEY, KEY_ANY),
309 /* signature/encryption schemes */
310 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_NULL),
311 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_NULL),
312 #ifndef OPENSSL_NO_SHA1
313 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA1),
314 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA1),
315 #endif
316 #ifndef OPENSSL_NO_SHA256
317 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA224),
318 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA256),
319 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA224),
320 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA256),
321 #endif
322 #ifndef OPENSSL_NO_SHA512
323 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA384),
324 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA512),
325 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA384),
326 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA512),
327 #endif
328 #ifndef OPENSSL_NO_MD5
329 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_MD5),
330 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_MD5),
331 #endif
332 PLUGIN_PROVIDE(PRIVKEY_DECRYPT, ENCRYPT_RSA_PKCS1),
333 PLUGIN_PROVIDE(PUBKEY_ENCRYPT, ENCRYPT_RSA_PKCS1),
334 #endif /* OPENSSL_NO_RSA */
335 /* certificate/CRL loading */
336 PLUGIN_REGISTER(CERT_DECODE, openssl_x509_load, TRUE),
337 PLUGIN_PROVIDE(CERT_DECODE, CERT_X509),
338 PLUGIN_SDEPEND(PUBKEY, KEY_RSA),
339 PLUGIN_SDEPEND(PUBKEY, KEY_ECDSA),
340 PLUGIN_SDEPEND(PUBKEY, KEY_DSA),
341 PLUGIN_REGISTER(CERT_DECODE, openssl_crl_load, TRUE),
342 PLUGIN_PROVIDE(CERT_DECODE, CERT_X509_CRL),
343 #ifndef OPENSSL_NO_ECDH
344 /* EC DH groups */
345 PLUGIN_REGISTER(DH, openssl_ec_diffie_hellman_create),
346 PLUGIN_PROVIDE(DH, ECP_256_BIT),
347 PLUGIN_PROVIDE(DH, ECP_384_BIT),
348 PLUGIN_PROVIDE(DH, ECP_521_BIT),
349 PLUGIN_PROVIDE(DH, ECP_224_BIT),
350 PLUGIN_PROVIDE(DH, ECP_192_BIT),
351 #endif
352 #ifndef OPENSSL_NO_ECDSA
353 /* EC private/public key loading */
354 PLUGIN_REGISTER(PRIVKEY, openssl_ec_private_key_load, TRUE),
355 PLUGIN_PROVIDE(PRIVKEY, KEY_ECDSA),
356 PLUGIN_REGISTER(PRIVKEY_GEN, openssl_ec_private_key_gen, FALSE),
357 PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_ECDSA),
358 PLUGIN_REGISTER(PUBKEY, openssl_ec_public_key_load, TRUE),
359 PLUGIN_PROVIDE(PUBKEY, KEY_ECDSA),
360 /* signature encryption schemes */
361 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_NULL),
362 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_NULL),
363 #ifndef OPENSSL_NO_SHA1
364 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA1_DER),
365 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA1_DER),
366 #endif
367 #ifndef OPENSSL_NO_SHA256
368 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA256_DER),
369 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA256_DER),
370 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_256),
371 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_256),
372 #endif
373 #ifndef OPENSSL_NO_SHA512
374 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA384_DER),
375 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA512_DER),
376 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA384_DER),
377 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA512_DER),
378 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_384),
379 PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_521),
380 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_384),
381 PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_521),
382 #endif
383 #endif /* OPENSSL_NO_ECDSA */
384 PLUGIN_REGISTER(RNG, openssl_rng_create),
385 PLUGIN_PROVIDE(RNG, RNG_STRONG),
386 PLUGIN_PROVIDE(RNG, RNG_WEAK),
387 };
388 *features = f;
389 return countof(f);
390 }
391
392 METHOD(plugin_t, destroy, void,
393 private_openssl_plugin_t *this)
394 {
395 #ifndef OPENSSL_NO_ENGINE
396 ENGINE_cleanup();
397 #endif /* OPENSSL_NO_ENGINE */
398 EVP_cleanup();
399 CONF_modules_free();
400
401 threading_cleanup();
402
403 free(this);
404 }
405
406 /*
407 * see header file
408 */
409 plugin_t *openssl_plugin_create()
410 {
411 private_openssl_plugin_t *this;
412
413 INIT(this,
414 .public = {
415 .plugin = {
416 .get_name = _get_name,
417 .get_features = _get_features,
418 .destroy = _destroy,
419 },
420 },
421 );
422
423 threading_init();
424
425 OPENSSL_config(NULL);
426 OpenSSL_add_all_algorithms();
427
428 #ifndef OPENSSL_NO_ENGINE
429 /* activate support for hardware accelerators */
430 ENGINE_load_builtin_engines();
431 ENGINE_register_all_complete();
432 #endif /* OPENSSL_NO_ENGINE */
433
434 if (!seed_rng())
435 {
436 DBG1(DBG_CFG, "no RNG found to seed OpenSSL");
437 destroy(this);
438 return NULL;
439 }
440
441 return &this->public.plugin;
442 }
443