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
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>
25 #include "openssl_plugin.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.h"
46 typedef struct private_openssl_plugin_t private_openssl_plugin_t
;
49 * private data of openssl_plugin
51 struct private_openssl_plugin_t
{
56 openssl_plugin_t
public;
60 * Array of static mutexs, with CRYPTO_num_locks() mutex
62 static mutex_t
**mutex
= NULL
;
65 * Locking callback for static locks
67 static void locking_function(int mode
, int type
, const char *file
, int line
)
71 if (mode
& CRYPTO_LOCK
)
73 mutex
[type
]->lock(mutex
[type
]);
77 mutex
[type
]->unlock(mutex
[type
]);
83 * Implementation of dynlock
85 struct CRYPTO_dynlock_value
{
90 * Callback to create a dynamic lock
92 static struct CRYPTO_dynlock_value
*create_function(const char *file
, int line
)
94 struct CRYPTO_dynlock_value
*lock
;
96 lock
= malloc_thing(struct CRYPTO_dynlock_value
);
97 lock
->mutex
= mutex_create(MUTEX_TYPE_DEFAULT
);
102 * Callback to (un-)lock a dynamic lock
104 static void lock_function(int mode
, struct CRYPTO_dynlock_value
*lock
,
105 const char *file
, int line
)
107 if (mode
& CRYPTO_LOCK
)
109 lock
->mutex
->lock(lock
->mutex
);
113 lock
->mutex
->unlock(lock
->mutex
);
118 * Callback to destroy a dynamic lock
120 static void destroy_function(struct CRYPTO_dynlock_value
*lock
,
121 const char *file
, int line
)
123 lock
->mutex
->destroy(lock
->mutex
);
128 * Thread-ID callback function
130 static unsigned long id_function(void)
132 /* ensure the thread ID is never zero, otherwise OpenSSL might try to
133 * acquire locks recursively */
134 return 1 + (unsigned long)thread_current_id();
138 * initialize OpenSSL for multi-threaded use
140 static void threading_init()
144 CRYPTO_set_id_callback(id_function
);
145 CRYPTO_set_locking_callback(locking_function
);
147 CRYPTO_set_dynlock_create_callback(create_function
);
148 CRYPTO_set_dynlock_lock_callback(lock_function
);
149 CRYPTO_set_dynlock_destroy_callback(destroy_function
);
151 num_locks
= CRYPTO_num_locks();
152 mutex
= malloc(sizeof(mutex_t
*) * num_locks
);
153 for (i
= 0; i
< num_locks
; i
++)
155 mutex
[i
] = mutex_create(MUTEX_TYPE_DEFAULT
);
160 * Seed the OpenSSL RNG, if required
162 static bool seed_rng()
167 while (RAND_status() != 1)
171 rng
= lib
->crypto
->create_rng(lib
->crypto
, RNG_STRONG
);
177 if (!rng
->get_bytes(rng
, sizeof(buf
), buf
))
182 RAND_seed(buf
, sizeof(buf
));
189 * cleanup OpenSSL threading locks
191 static void threading_cleanup()
195 num_locks
= CRYPTO_num_locks();
196 for (i
= 0; i
< num_locks
; i
++)
198 mutex
[i
]->destroy(mutex
[i
]);
204 METHOD(plugin_t
, get_name
, char*,
205 private_openssl_plugin_t
*this)
210 METHOD(plugin_t
, get_features
, int,
211 private_openssl_plugin_t
*this, plugin_feature_t
*features
[])
213 static plugin_feature_t f
[] = {
215 PLUGIN_REGISTER(CRYPTER
, openssl_crypter_create
),
216 #ifndef OPENSSL_NO_AES
217 PLUGIN_PROVIDE(CRYPTER
, ENCR_AES_CBC
, 16),
218 PLUGIN_PROVIDE(CRYPTER
, ENCR_AES_CBC
, 24),
219 PLUGIN_PROVIDE(CRYPTER
, ENCR_AES_CBC
, 32),
221 #ifndef OPENSSL_NO_CAMELLIA
222 PLUGIN_PROVIDE(CRYPTER
, ENCR_CAMELLIA_CBC
, 16),
223 PLUGIN_PROVIDE(CRYPTER
, ENCR_CAMELLIA_CBC
, 24),
224 PLUGIN_PROVIDE(CRYPTER
, ENCR_CAMELLIA_CBC
, 32),
226 #ifndef OPENSSL_NO_RC5
227 PLUGIN_PROVIDE(CRYPTER
, ENCR_RC5
, 0),
229 #ifndef OPENSSL_NO_CAST
230 PLUGIN_PROVIDE(CRYPTER
, ENCR_CAST
, 0),
232 #ifndef OPENSSL_NO_BLOWFISH
233 PLUGIN_PROVIDE(CRYPTER
, ENCR_BLOWFISH
, 0),
235 #ifndef OPENSSL_NO_IDEA
236 PLUGIN_PROVIDE(CRYPTER
, ENCR_IDEA
, 16),
238 #ifndef OPENSSL_NO_DES
239 PLUGIN_PROVIDE(CRYPTER
, ENCR_3DES
, 24),
240 PLUGIN_PROVIDE(CRYPTER
, ENCR_DES
, 8),
241 PLUGIN_PROVIDE(CRYPTER
, ENCR_DES_ECB
, 8),
243 PLUGIN_PROVIDE(CRYPTER
, ENCR_NULL
, 0),
245 PLUGIN_REGISTER(HASHER
, openssl_hasher_create
),
246 #ifndef OPENSSL_NO_SHA1
247 PLUGIN_PROVIDE(HASHER
, HASH_SHA1
),
249 #ifndef OPENSSL_NO_MD2
250 PLUGIN_PROVIDE(HASHER
, HASH_MD2
),
252 #ifndef OPENSSL_NO_MD4
253 PLUGIN_PROVIDE(HASHER
, HASH_MD4
),
255 #ifndef OPENSSL_NO_MD5
256 PLUGIN_PROVIDE(HASHER
, HASH_MD5
),
258 #ifndef OPENSSL_NO_SHA256
259 PLUGIN_PROVIDE(HASHER
, HASH_SHA224
),
260 PLUGIN_PROVIDE(HASHER
, HASH_SHA256
),
262 #ifndef OPENSSL_NO_SHA512
263 PLUGIN_PROVIDE(HASHER
, HASH_SHA384
),
264 PLUGIN_PROVIDE(HASHER
, HASH_SHA512
),
266 #ifndef OPENSSL_NO_SHA1
267 /* keyed sha1 hasher (aka prf) */
268 PLUGIN_REGISTER(PRF
, openssl_sha1_prf_create
),
269 PLUGIN_PROVIDE(PRF
, PRF_KEYED_SHA1
),
271 #ifndef OPENSSL_NO_HMAC
272 PLUGIN_REGISTER(PRF
, openssl_hmac_prf_create
),
273 #ifndef OPENSSL_NO_MD5
274 PLUGIN_PROVIDE(PRF
, PRF_HMAC_MD5
),
276 #ifndef OPENSSL_NO_SHA1
277 PLUGIN_PROVIDE(PRF
, PRF_HMAC_SHA1
),
279 #ifndef OPENSSL_NO_SHA256
280 PLUGIN_PROVIDE(PRF
, PRF_HMAC_SHA2_256
),
282 #ifndef OPENSSL_NO_SHA512
283 PLUGIN_PROVIDE(PRF
, PRF_HMAC_SHA2_384
),
284 PLUGIN_PROVIDE(PRF
, PRF_HMAC_SHA2_512
),
286 PLUGIN_REGISTER(SIGNER
, openssl_hmac_signer_create
),
287 #ifndef OPENSSL_NO_MD5
288 PLUGIN_PROVIDE(SIGNER
, AUTH_HMAC_MD5_96
),
289 PLUGIN_PROVIDE(SIGNER
, AUTH_HMAC_MD5_128
),
291 #ifndef OPENSSL_NO_SHA1
292 PLUGIN_PROVIDE(SIGNER
, AUTH_HMAC_SHA1_96
),
293 PLUGIN_PROVIDE(SIGNER
, AUTH_HMAC_SHA1_128
),
294 PLUGIN_PROVIDE(SIGNER
, AUTH_HMAC_SHA1_160
),
296 #ifndef OPENSSL_NO_SHA256
297 PLUGIN_PROVIDE(SIGNER
, AUTH_HMAC_SHA2_256_128
),
298 PLUGIN_PROVIDE(SIGNER
, AUTH_HMAC_SHA2_256_256
),
300 #ifndef OPENSSL_NO_SHA512
301 PLUGIN_PROVIDE(SIGNER
, AUTH_HMAC_SHA2_384_192
),
302 PLUGIN_PROVIDE(SIGNER
, AUTH_HMAC_SHA2_384_384
),
303 PLUGIN_PROVIDE(SIGNER
, AUTH_HMAC_SHA2_512_256
),
305 #endif /* OPENSSL_NO_HMAC */
306 #ifndef OPENSSL_NO_DH
308 PLUGIN_REGISTER(DH
, openssl_diffie_hellman_create
),
309 PLUGIN_PROVIDE(DH
, MODP_2048_BIT
),
310 PLUGIN_PROVIDE(DH
, MODP_2048_224
),
311 PLUGIN_PROVIDE(DH
, MODP_2048_256
),
312 PLUGIN_PROVIDE(DH
, MODP_1536_BIT
),
313 PLUGIN_PROVIDE(DH
, MODP_3072_BIT
),
314 PLUGIN_PROVIDE(DH
, MODP_4096_BIT
),
315 PLUGIN_PROVIDE(DH
, MODP_6144_BIT
),
316 PLUGIN_PROVIDE(DH
, MODP_8192_BIT
),
317 PLUGIN_PROVIDE(DH
, MODP_1024_BIT
),
318 PLUGIN_PROVIDE(DH
, MODP_1024_160
),
319 PLUGIN_PROVIDE(DH
, MODP_768_BIT
),
320 PLUGIN_PROVIDE(DH
, MODP_CUSTOM
),
322 #ifndef OPENSSL_NO_RSA
323 /* RSA private/public key loading */
324 PLUGIN_REGISTER(PRIVKEY
, openssl_rsa_private_key_load
, TRUE
),
325 PLUGIN_PROVIDE(PRIVKEY
, KEY_RSA
),
326 PLUGIN_REGISTER(PRIVKEY
, openssl_rsa_private_key_connect
, FALSE
),
327 PLUGIN_PROVIDE(PRIVKEY
, KEY_ANY
),
328 PLUGIN_REGISTER(PRIVKEY_GEN
, openssl_rsa_private_key_gen
, FALSE
),
329 PLUGIN_PROVIDE(PRIVKEY_GEN
, KEY_RSA
),
330 PLUGIN_REGISTER(PUBKEY
, openssl_rsa_public_key_load
, TRUE
),
331 PLUGIN_PROVIDE(PUBKEY
, KEY_RSA
),
332 PLUGIN_REGISTER(PUBKEY
, openssl_rsa_public_key_load
, TRUE
),
333 PLUGIN_PROVIDE(PUBKEY
, KEY_ANY
),
334 /* signature/encryption schemes */
335 PLUGIN_PROVIDE(PRIVKEY_SIGN
, SIGN_RSA_EMSA_PKCS1_NULL
),
336 PLUGIN_PROVIDE(PUBKEY_VERIFY
, SIGN_RSA_EMSA_PKCS1_NULL
),
337 #ifndef OPENSSL_NO_SHA1
338 PLUGIN_PROVIDE(PRIVKEY_SIGN
, SIGN_RSA_EMSA_PKCS1_SHA1
),
339 PLUGIN_PROVIDE(PUBKEY_VERIFY
, SIGN_RSA_EMSA_PKCS1_SHA1
),
341 #ifndef OPENSSL_NO_SHA256
342 PLUGIN_PROVIDE(PRIVKEY_SIGN
, SIGN_RSA_EMSA_PKCS1_SHA224
),
343 PLUGIN_PROVIDE(PRIVKEY_SIGN
, SIGN_RSA_EMSA_PKCS1_SHA256
),
344 PLUGIN_PROVIDE(PUBKEY_VERIFY
, SIGN_RSA_EMSA_PKCS1_SHA224
),
345 PLUGIN_PROVIDE(PUBKEY_VERIFY
, SIGN_RSA_EMSA_PKCS1_SHA256
),
347 #ifndef OPENSSL_NO_SHA512
348 PLUGIN_PROVIDE(PRIVKEY_SIGN
, SIGN_RSA_EMSA_PKCS1_SHA384
),
349 PLUGIN_PROVIDE(PRIVKEY_SIGN
, SIGN_RSA_EMSA_PKCS1_SHA512
),
350 PLUGIN_PROVIDE(PUBKEY_VERIFY
, SIGN_RSA_EMSA_PKCS1_SHA384
),
351 PLUGIN_PROVIDE(PUBKEY_VERIFY
, SIGN_RSA_EMSA_PKCS1_SHA512
),
353 #ifndef OPENSSL_NO_MD5
354 PLUGIN_PROVIDE(PRIVKEY_SIGN
, SIGN_RSA_EMSA_PKCS1_MD5
),
355 PLUGIN_PROVIDE(PUBKEY_VERIFY
, SIGN_RSA_EMSA_PKCS1_MD5
),
357 PLUGIN_PROVIDE(PRIVKEY_DECRYPT
, ENCRYPT_RSA_PKCS1
),
358 PLUGIN_PROVIDE(PUBKEY_ENCRYPT
, ENCRYPT_RSA_PKCS1
),
359 #endif /* OPENSSL_NO_RSA */
360 /* certificate/CRL loading */
361 PLUGIN_REGISTER(CERT_DECODE
, openssl_x509_load
, TRUE
),
362 PLUGIN_PROVIDE(CERT_DECODE
, CERT_X509
),
363 PLUGIN_SDEPEND(PUBKEY
, KEY_RSA
),
364 PLUGIN_SDEPEND(PUBKEY
, KEY_ECDSA
),
365 PLUGIN_SDEPEND(PUBKEY
, KEY_DSA
),
366 PLUGIN_REGISTER(CERT_DECODE
, openssl_crl_load
, TRUE
),
367 PLUGIN_PROVIDE(CERT_DECODE
, CERT_X509_CRL
),
368 #ifndef OPENSSL_NO_ECDH
370 PLUGIN_REGISTER(DH
, openssl_ec_diffie_hellman_create
),
371 PLUGIN_PROVIDE(DH
, ECP_256_BIT
),
372 PLUGIN_PROVIDE(DH
, ECP_384_BIT
),
373 PLUGIN_PROVIDE(DH
, ECP_521_BIT
),
374 PLUGIN_PROVIDE(DH
, ECP_224_BIT
),
375 PLUGIN_PROVIDE(DH
, ECP_192_BIT
),
377 #ifndef OPENSSL_NO_ECDSA
378 /* EC private/public key loading */
379 PLUGIN_REGISTER(PRIVKEY
, openssl_ec_private_key_load
, TRUE
),
380 PLUGIN_PROVIDE(PRIVKEY
, KEY_ECDSA
),
381 PLUGIN_REGISTER(PRIVKEY_GEN
, openssl_ec_private_key_gen
, FALSE
),
382 PLUGIN_PROVIDE(PRIVKEY_GEN
, KEY_ECDSA
),
383 PLUGIN_REGISTER(PUBKEY
, openssl_ec_public_key_load
, TRUE
),
384 PLUGIN_PROVIDE(PUBKEY
, KEY_ECDSA
),
385 /* signature encryption schemes */
386 PLUGIN_PROVIDE(PRIVKEY_SIGN
, SIGN_ECDSA_WITH_NULL
),
387 PLUGIN_PROVIDE(PUBKEY_VERIFY
, SIGN_ECDSA_WITH_NULL
),
388 #ifndef OPENSSL_NO_SHA1
389 PLUGIN_PROVIDE(PRIVKEY_SIGN
, SIGN_ECDSA_WITH_SHA1_DER
),
390 PLUGIN_PROVIDE(PUBKEY_VERIFY
, SIGN_ECDSA_WITH_SHA1_DER
),
392 #ifndef OPENSSL_NO_SHA256
393 PLUGIN_PROVIDE(PRIVKEY_SIGN
, SIGN_ECDSA_WITH_SHA256_DER
),
394 PLUGIN_PROVIDE(PUBKEY_VERIFY
, SIGN_ECDSA_WITH_SHA256_DER
),
395 PLUGIN_PROVIDE(PRIVKEY_SIGN
, SIGN_ECDSA_256
),
396 PLUGIN_PROVIDE(PUBKEY_VERIFY
, SIGN_ECDSA_256
),
398 #ifndef OPENSSL_NO_SHA512
399 PLUGIN_PROVIDE(PRIVKEY_SIGN
, SIGN_ECDSA_WITH_SHA384_DER
),
400 PLUGIN_PROVIDE(PRIVKEY_SIGN
, SIGN_ECDSA_WITH_SHA512_DER
),
401 PLUGIN_PROVIDE(PUBKEY_VERIFY
, SIGN_ECDSA_WITH_SHA384_DER
),
402 PLUGIN_PROVIDE(PUBKEY_VERIFY
, SIGN_ECDSA_WITH_SHA512_DER
),
403 PLUGIN_PROVIDE(PRIVKEY_SIGN
, SIGN_ECDSA_384
),
404 PLUGIN_PROVIDE(PRIVKEY_SIGN
, SIGN_ECDSA_521
),
405 PLUGIN_PROVIDE(PUBKEY_VERIFY
, SIGN_ECDSA_384
),
406 PLUGIN_PROVIDE(PUBKEY_VERIFY
, SIGN_ECDSA_521
),
408 #endif /* OPENSSL_NO_ECDSA */
409 PLUGIN_REGISTER(RNG
, openssl_rng_create
),
410 PLUGIN_PROVIDE(RNG
, RNG_STRONG
),
411 PLUGIN_PROVIDE(RNG
, RNG_WEAK
),
417 METHOD(plugin_t
, destroy
, void,
418 private_openssl_plugin_t
*this)
420 #ifndef OPENSSL_NO_ENGINE
422 #endif /* OPENSSL_NO_ENGINE */
434 plugin_t
*openssl_plugin_create()
436 private_openssl_plugin_t
*this;
441 .get_name
= _get_name
,
442 .get_features
= _get_features
,
450 OPENSSL_config(NULL
);
451 OpenSSL_add_all_algorithms();
453 #ifndef OPENSSL_NO_ENGINE
454 /* activate support for hardware accelerators */
455 ENGINE_load_builtin_engines();
456 ENGINE_register_all_complete();
457 #endif /* OPENSSL_NO_ENGINE */
461 DBG1(DBG_CFG
, "no RNG found to seed OpenSSL");
466 return &this->public.plugin
;