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