]>
Commit | Line | Data |
---|---|---|
17353034 | 1 | /* |
cbf07ab5 | 2 | * Copyright (C) 2008-2018 Tobias Brunner |
ddd7e6c6 | 3 | * Copyright (C) 2008 Martin Willi |
4a6f97d0 | 4 | * HSR Hochschule fuer Technik Rapperswil |
17353034 TB |
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. | |
17353034 TB |
15 | */ |
16 | ||
06c33ebf MW |
17 | #include <library.h> |
18 | #include <utils/debug.h> | |
19 | #include <threading/thread.h> | |
20 | #include <threading/mutex.h> | |
21 | #include <threading/thread_value.h> | |
22 | ||
651d5ab8 | 23 | #include <openssl/err.h> |
17353034 | 24 | #include <openssl/evp.h> |
1e3d66f8 | 25 | #include <openssl/conf.h> |
ed174fd7 | 26 | #include <openssl/rand.h> |
7de6da0c | 27 | #include <openssl/crypto.h> |
1e3d66f8 TB |
28 | #ifndef OPENSSL_NO_ENGINE |
29 | #include <openssl/engine.h> | |
30 | #endif | |
17353034 TB |
31 | |
32 | #include "openssl_plugin.h" | |
e35c3e2a | 33 | #include "openssl_util.h" |
17353034 | 34 | #include "openssl_crypter.h" |
63cdbca2 | 35 | #include "openssl_hasher.h" |
40f130da | 36 | #include "openssl_sha1_prf.h" |
ae7e837c | 37 | #include "openssl_diffie_hellman.h" |
fc1a31d5 | 38 | #include "openssl_ec_diffie_hellman.h" |
84770ded TB |
39 | #include "openssl_rsa_private_key.h" |
40 | #include "openssl_rsa_public_key.h" | |
ea0823df TB |
41 | #include "openssl_ec_private_key.h" |
42 | #include "openssl_ec_public_key.h" | |
5728c6aa | 43 | #include "openssl_x509.h" |
6d7eed9a | 44 | #include "openssl_crl.h" |
568ad938 | 45 | #include "openssl_pkcs7.h" |
780900ab | 46 | #include "openssl_pkcs12.h" |
4faece7b | 47 | #include "openssl_rng.h" |
73d032e4 | 48 | #include "openssl_hmac.h" |
81f9cd39 | 49 | #include "openssl_gcm.h" |
57cb4c8d | 50 | #include "openssl_x_diffie_hellman.h" |
cbf07ab5 TB |
51 | #include "openssl_ed_public_key.h" |
52 | #include "openssl_ed_private_key.h" | |
17353034 | 53 | |
2d7b55bf TB |
54 | #ifndef FIPS_MODE |
55 | #define FIPS_MODE 0 | |
56 | #endif | |
57 | ||
17353034 TB |
58 | typedef struct private_openssl_plugin_t private_openssl_plugin_t; |
59 | ||
60 | /** | |
61 | * private data of openssl_plugin | |
62 | */ | |
63 | struct private_openssl_plugin_t { | |
64 | ||
65 | /** | |
66 | * public functions | |
67 | */ | |
68 | openssl_plugin_t public; | |
7de6da0c MW |
69 | }; |
70 | ||
a6c43a8d TB |
71 | /** |
72 | * OpenSSL is thread-safe since 1.1.0 | |
73 | */ | |
74 | #if OPENSSL_VERSION_NUMBER < 0x10100000L | |
75 | ||
7de6da0c MW |
76 | /** |
77 | * Array of static mutexs, with CRYPTO_num_locks() mutex | |
78 | */ | |
2abc66b9 | 79 | static mutex_t **mutex = NULL; |
7de6da0c MW |
80 | |
81 | /** | |
82 | * Locking callback for static locks | |
83 | */ | |
84 | static void locking_function(int mode, int type, const char *file, int line) | |
85 | { | |
2abc66b9 | 86 | if (mutex) |
7de6da0c | 87 | { |
2abc66b9 MW |
88 | if (mode & CRYPTO_LOCK) |
89 | { | |
90 | mutex[type]->lock(mutex[type]); | |
91 | } | |
92 | else | |
93 | { | |
94 | mutex[type]->unlock(mutex[type]); | |
95 | } | |
7de6da0c MW |
96 | } |
97 | } | |
98 | ||
99 | /** | |
100 | * Implementation of dynlock | |
101 | */ | |
102 | struct CRYPTO_dynlock_value { | |
3ac5a0db | 103 | mutex_t *mutex; |
17353034 TB |
104 | }; |
105 | ||
7de6da0c MW |
106 | /** |
107 | * Callback to create a dynamic lock | |
108 | */ | |
109 | static struct CRYPTO_dynlock_value *create_function(const char *file, int line) | |
110 | { | |
111 | struct CRYPTO_dynlock_value *lock; | |
7daf5226 | 112 | |
7de6da0c | 113 | lock = malloc_thing(struct CRYPTO_dynlock_value); |
3901937d | 114 | lock->mutex = mutex_create(MUTEX_TYPE_DEFAULT); |
7de6da0c MW |
115 | return lock; |
116 | } | |
117 | ||
118 | /** | |
119 | * Callback to (un-)lock a dynamic lock | |
120 | */ | |
121 | static void lock_function(int mode, struct CRYPTO_dynlock_value *lock, | |
122 | const char *file, int line) | |
123 | { | |
124 | if (mode & CRYPTO_LOCK) | |
125 | { | |
3ac5a0db | 126 | lock->mutex->lock(lock->mutex); |
7de6da0c MW |
127 | } |
128 | else | |
129 | { | |
3ac5a0db | 130 | lock->mutex->unlock(lock->mutex); |
7de6da0c MW |
131 | } |
132 | } | |
133 | ||
134 | /** | |
135 | * Callback to destroy a dynamic lock | |
136 | */ | |
137 | static void destroy_function(struct CRYPTO_dynlock_value *lock, | |
138 | const char *file, int line) | |
139 | { | |
3ac5a0db | 140 | lock->mutex->destroy(lock->mutex); |
7de6da0c MW |
141 | free(lock); |
142 | } | |
143 | ||
904390e8 TB |
144 | /** |
145 | * Thread-local value used to cleanup thread-specific error buffers | |
146 | */ | |
147 | static thread_value_t *cleanup; | |
148 | ||
149 | /** | |
150 | * Called when a thread is destroyed. Avoid recursion by setting the thread id | |
151 | * explicitly. | |
152 | */ | |
153 | static void cleanup_thread(void *arg) | |
154 | { | |
155 | #if OPENSSL_VERSION_NUMBER >= 0x1000000fL | |
156 | CRYPTO_THREADID tid; | |
157 | ||
158 | CRYPTO_THREADID_set_numeric(&tid, (u_long)(uintptr_t)arg); | |
159 | ERR_remove_thread_state(&tid); | |
160 | #else | |
161 | ERR_remove_state((u_long)(uintptr_t)arg); | |
162 | #endif | |
163 | } | |
164 | ||
7de6da0c MW |
165 | /** |
166 | * Thread-ID callback function | |
167 | */ | |
904390e8 | 168 | static u_long id_function(void) |
7de6da0c | 169 | { |
904390e8 TB |
170 | u_long id; |
171 | ||
901dbc10 TB |
172 | /* ensure the thread ID is never zero, otherwise OpenSSL might try to |
173 | * acquire locks recursively */ | |
904390e8 TB |
174 | id = 1 + (u_long)thread_current_id(); |
175 | ||
176 | /* cleanup a thread's state later if OpenSSL interacted with it */ | |
177 | cleanup->set(cleanup, (void*)(uintptr_t)id); | |
178 | return id; | |
7de6da0c MW |
179 | } |
180 | ||
3ee2af97 | 181 | #if OPENSSL_VERSION_NUMBER >= 0x1000000fL |
904390e8 TB |
182 | /** |
183 | * Callback for thread ID | |
184 | */ | |
3ee2af97 TB |
185 | static void threadid_function(CRYPTO_THREADID *threadid) |
186 | { | |
187 | CRYPTO_THREADID_set_numeric(threadid, id_function()); | |
188 | } | |
189 | #endif /* OPENSSL_VERSION_NUMBER */ | |
190 | ||
7de6da0c MW |
191 | /** |
192 | * initialize OpenSSL for multi-threaded use | |
193 | */ | |
194 | static void threading_init() | |
195 | { | |
196 | int i, num_locks; | |
197 | ||
904390e8 TB |
198 | cleanup = thread_value_create(cleanup_thread); |
199 | ||
3ee2af97 TB |
200 | #if OPENSSL_VERSION_NUMBER >= 0x1000000fL |
201 | CRYPTO_THREADID_set_callback(threadid_function); | |
202 | #else | |
7de6da0c | 203 | CRYPTO_set_id_callback(id_function); |
3ee2af97 TB |
204 | #endif |
205 | ||
7b3814f7 | 206 | CRYPTO_set_locking_callback(locking_function); |
7daf5226 | 207 | |
7de6da0c MW |
208 | CRYPTO_set_dynlock_create_callback(create_function); |
209 | CRYPTO_set_dynlock_lock_callback(lock_function); | |
210 | CRYPTO_set_dynlock_destroy_callback(destroy_function); | |
7daf5226 | 211 | |
7de6da0c | 212 | num_locks = CRYPTO_num_locks(); |
3ac5a0db | 213 | mutex = malloc(sizeof(mutex_t*) * num_locks); |
7de6da0c MW |
214 | for (i = 0; i < num_locks; i++) |
215 | { | |
3901937d | 216 | mutex[i] = mutex_create(MUTEX_TYPE_DEFAULT); |
7de6da0c MW |
217 | } |
218 | } | |
219 | ||
3ee2af97 TB |
220 | /** |
221 | * cleanup OpenSSL threading locks | |
222 | */ | |
223 | static void threading_cleanup() | |
224 | { | |
225 | int i, num_locks; | |
226 | ||
227 | num_locks = CRYPTO_num_locks(); | |
228 | for (i = 0; i < num_locks; i++) | |
229 | { | |
230 | mutex[i]->destroy(mutex[i]); | |
231 | } | |
232 | free(mutex); | |
233 | mutex = NULL; | |
904390e8 TB |
234 | |
235 | cleanup->destroy(cleanup); | |
3ee2af97 TB |
236 | } |
237 | ||
a6c43a8d TB |
238 | #else /* OPENSSL_VERSION_NUMBER */ |
239 | ||
240 | #define threading_init() | |
241 | ||
242 | #define threading_cleanup() | |
243 | ||
244 | #endif | |
245 | ||
4ec53e95 MW |
246 | /** |
247 | * Seed the OpenSSL RNG, if required | |
248 | */ | |
249 | static bool seed_rng() | |
250 | { | |
251 | rng_t *rng = NULL; | |
252 | char buf[32]; | |
253 | ||
254 | while (RAND_status() != 1) | |
255 | { | |
256 | if (!rng) | |
257 | { | |
258 | rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG); | |
259 | if (!rng) | |
260 | { | |
261 | return FALSE; | |
262 | } | |
263 | } | |
99dc3d2c TB |
264 | if (!rng->get_bytes(rng, sizeof(buf), buf)) |
265 | { | |
266 | rng->destroy(rng); | |
267 | return FALSE; | |
268 | } | |
4ec53e95 MW |
269 | RAND_seed(buf, sizeof(buf)); |
270 | } | |
271 | DESTROY_IF(rng); | |
272 | return TRUE; | |
273 | } | |
274 | ||
4a6f97d0 TB |
275 | /** |
276 | * Generic key loader | |
277 | */ | |
278 | static private_key_t *openssl_private_key_load(key_type_t type, va_list args) | |
279 | { | |
280 | chunk_t blob = chunk_empty; | |
281 | EVP_PKEY *key; | |
282 | ||
283 | while (TRUE) | |
284 | { | |
285 | switch (va_arg(args, builder_part_t)) | |
286 | { | |
287 | case BUILD_BLOB_ASN1_DER: | |
288 | blob = va_arg(args, chunk_t); | |
289 | continue; | |
290 | case BUILD_END: | |
291 | break; | |
292 | default: | |
293 | return NULL; | |
294 | } | |
295 | break; | |
296 | } | |
297 | ||
298 | if (blob.ptr) | |
299 | { | |
300 | key = d2i_AutoPrivateKey(NULL, (const u_char**)&blob.ptr, blob.len); | |
301 | if (key) | |
302 | { | |
303 | switch (EVP_PKEY_base_id(key)) | |
304 | { | |
305 | #ifndef OPENSSL_NO_RSA | |
306 | case EVP_PKEY_RSA: | |
b2266280 | 307 | return openssl_rsa_private_key_create(key, FALSE); |
4a6f97d0 TB |
308 | #endif |
309 | #ifndef OPENSSL_NO_ECDSA | |
310 | case EVP_PKEY_EC: | |
b2266280 | 311 | return openssl_ec_private_key_create(key, FALSE); |
4a6f97d0 | 312 | #endif |
cbf07ab5 TB |
313 | #if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_EC) |
314 | case EVP_PKEY_ED25519: | |
315 | case EVP_PKEY_ED448: | |
316 | return openssl_ed_private_key_create(key, FALSE); | |
317 | #endif /* OPENSSL_VERSION_NUMBER */ | |
4a6f97d0 TB |
318 | default: |
319 | EVP_PKEY_free(key); | |
320 | break; | |
321 | } | |
322 | } | |
323 | } | |
324 | return NULL; | |
325 | } | |
326 | ||
b2266280 TB |
327 | #ifndef OPENSSL_NO_ENGINE |
328 | /** | |
329 | * Login to engine with a PIN specified for a keyid | |
330 | */ | |
331 | static bool login(ENGINE *engine, chunk_t keyid) | |
332 | { | |
333 | enumerator_t *enumerator; | |
334 | shared_key_t *shared; | |
335 | identification_t *id; | |
336 | chunk_t key; | |
337 | char pin[64]; | |
338 | bool found = FALSE, success = FALSE; | |
339 | ||
340 | id = identification_create_from_encoding(ID_KEY_ID, keyid); | |
341 | enumerator = lib->credmgr->create_shared_enumerator(lib->credmgr, | |
342 | SHARED_PIN, id, NULL); | |
343 | while (enumerator->enumerate(enumerator, &shared, NULL, NULL)) | |
344 | { | |
345 | found = TRUE; | |
346 | key = shared->get_key(shared); | |
347 | if (snprintf(pin, sizeof(pin), | |
348 | "%.*s", (int)key.len, key.ptr) >= sizeof(pin)) | |
349 | { | |
350 | continue; | |
351 | } | |
352 | if (ENGINE_ctrl_cmd_string(engine, "PIN", pin, 0)) | |
353 | { | |
354 | success = TRUE; | |
355 | break; | |
356 | } | |
357 | else | |
358 | { | |
359 | DBG1(DBG_CFG, "setting PIN on engine failed"); | |
360 | } | |
361 | } | |
362 | enumerator->destroy(enumerator); | |
363 | id->destroy(id); | |
364 | if (!found) | |
365 | { | |
366 | DBG1(DBG_CFG, "no PIN found for %#B", &keyid); | |
367 | } | |
368 | return success; | |
369 | } | |
370 | #endif /* OPENSSL_NO_ENGINE */ | |
371 | ||
372 | /** | |
373 | * Load private key via engine | |
374 | */ | |
375 | static private_key_t *openssl_private_key_connect(key_type_t type, | |
376 | va_list args) | |
377 | { | |
378 | #ifndef OPENSSL_NO_ENGINE | |
379 | char *engine_id = NULL; | |
380 | char keyname[BUF_LEN]; | |
6b3dfe9c | 381 | chunk_t keyid = chunk_empty; |
b2266280 TB |
382 | EVP_PKEY *key; |
383 | ENGINE *engine; | |
384 | int slot = -1; | |
385 | ||
386 | while (TRUE) | |
387 | { | |
388 | switch (va_arg(args, builder_part_t)) | |
389 | { | |
390 | case BUILD_PKCS11_KEYID: | |
391 | keyid = va_arg(args, chunk_t); | |
392 | continue; | |
393 | case BUILD_PKCS11_SLOT: | |
394 | slot = va_arg(args, int); | |
395 | continue; | |
396 | case BUILD_PKCS11_MODULE: | |
397 | engine_id = va_arg(args, char*); | |
398 | continue; | |
399 | case BUILD_END: | |
400 | break; | |
401 | default: | |
402 | return NULL; | |
403 | } | |
404 | break; | |
405 | } | |
b9e45b5b | 406 | if (!keyid.len) |
b2266280 TB |
407 | { |
408 | return NULL; | |
409 | } | |
410 | ||
411 | memset(keyname, 0, sizeof(keyname)); | |
412 | if (slot != -1) | |
413 | { | |
414 | snprintf(keyname, sizeof(keyname), "%d:", slot); | |
415 | } | |
b148517c | 416 | if (sizeof(keyname) - strlen(keyname) <= keyid.len * 2 + 1) |
b2266280 TB |
417 | { |
418 | return NULL; | |
419 | } | |
420 | chunk_to_hex(keyid, keyname + strlen(keyname), FALSE); | |
421 | ||
422 | if (!engine_id) | |
423 | { | |
424 | engine_id = lib->settings->get_str(lib->settings, | |
425 | "%s.plugins.openssl.engine_id", "pkcs11", lib->ns); | |
426 | } | |
427 | engine = ENGINE_by_id(engine_id); | |
428 | if (!engine) | |
429 | { | |
430 | DBG2(DBG_LIB, "engine '%s' is not available", engine_id); | |
431 | return NULL; | |
432 | } | |
433 | if (!ENGINE_init(engine)) | |
434 | { | |
435 | DBG1(DBG_LIB, "failed to initialize engine '%s'", engine_id); | |
436 | ENGINE_free(engine); | |
437 | return NULL; | |
438 | } | |
322daff8 | 439 | ENGINE_free(engine); |
b2266280 TB |
440 | if (!login(engine, keyid)) |
441 | { | |
442 | DBG1(DBG_LIB, "login to engine '%s' failed", engine_id); | |
322daff8 | 443 | ENGINE_finish(engine); |
b2266280 TB |
444 | return NULL; |
445 | } | |
446 | key = ENGINE_load_private_key(engine, keyname, NULL, NULL); | |
322daff8 | 447 | ENGINE_finish(engine); |
b2266280 TB |
448 | if (!key) |
449 | { | |
450 | DBG1(DBG_LIB, "failed to load private key with ID '%s' from " | |
451 | "engine '%s'", keyname, engine_id); | |
b2266280 TB |
452 | return NULL; |
453 | } | |
b2266280 TB |
454 | |
455 | switch (EVP_PKEY_base_id(key)) | |
456 | { | |
457 | #ifndef OPENSSL_NO_RSA | |
458 | case EVP_PKEY_RSA: | |
459 | return openssl_rsa_private_key_create(key, TRUE); | |
460 | #endif | |
461 | #ifndef OPENSSL_NO_ECDSA | |
462 | case EVP_PKEY_EC: | |
463 | return openssl_ec_private_key_create(key, TRUE); | |
464 | #endif | |
cbf07ab5 TB |
465 | #if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_EC) |
466 | case EVP_PKEY_ED25519: | |
467 | case EVP_PKEY_ED448: | |
468 | return openssl_ed_private_key_create(key, TRUE); | |
469 | #endif /* OPENSSL_VERSION_NUMBER */ | |
b2266280 TB |
470 | default: |
471 | EVP_PKEY_free(key); | |
472 | break; | |
473 | } | |
474 | #endif /* OPENSSL_NO_ENGINE */ | |
475 | return NULL; | |
476 | } | |
477 | ||
787b5884 MW |
478 | METHOD(plugin_t, get_name, char*, |
479 | private_openssl_plugin_t *this) | |
480 | { | |
481 | return "openssl"; | |
482 | } | |
483 | ||
9dc54fc5 MW |
484 | METHOD(plugin_t, get_features, int, |
485 | private_openssl_plugin_t *this, plugin_feature_t *features[]) | |
17353034 | 486 | { |
9dc54fc5 | 487 | static plugin_feature_t f[] = { |
a336aefa MW |
488 | /* we provide OpenSSL threading callbacks */ |
489 | PLUGIN_PROVIDE(CUSTOM, "openssl-threading"), | |
9dc54fc5 MW |
490 | /* crypters */ |
491 | PLUGIN_REGISTER(CRYPTER, openssl_crypter_create), | |
02572b84 | 492 | #ifndef OPENSSL_NO_AES |
f5c574e1 | 493 | PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 16), |
9dc54fc5 MW |
494 | PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 24), |
495 | PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 32), | |
02572b84 MW |
496 | #endif |
497 | #ifndef OPENSSL_NO_CAMELLIA | |
f5c574e1 | 498 | PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 16), |
9dc54fc5 MW |
499 | PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 24), |
500 | PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 32), | |
02572b84 MW |
501 | #endif |
502 | #ifndef OPENSSL_NO_RC5 | |
9dc54fc5 | 503 | PLUGIN_PROVIDE(CRYPTER, ENCR_RC5, 0), |
02572b84 MW |
504 | #endif |
505 | #ifndef OPENSSL_NO_CAST | |
9dc54fc5 | 506 | PLUGIN_PROVIDE(CRYPTER, ENCR_CAST, 0), |
02572b84 MW |
507 | #endif |
508 | #ifndef OPENSSL_NO_BLOWFISH | |
9dc54fc5 | 509 | PLUGIN_PROVIDE(CRYPTER, ENCR_BLOWFISH, 0), |
02572b84 MW |
510 | #endif |
511 | #ifndef OPENSSL_NO_IDEA | |
9dc54fc5 | 512 | PLUGIN_PROVIDE(CRYPTER, ENCR_IDEA, 16), |
02572b84 MW |
513 | #endif |
514 | #ifndef OPENSSL_NO_DES | |
515 | PLUGIN_PROVIDE(CRYPTER, ENCR_3DES, 24), | |
9dc54fc5 MW |
516 | PLUGIN_PROVIDE(CRYPTER, ENCR_DES, 8), |
517 | PLUGIN_PROVIDE(CRYPTER, ENCR_DES_ECB, 8), | |
02572b84 | 518 | #endif |
9dc54fc5 MW |
519 | PLUGIN_PROVIDE(CRYPTER, ENCR_NULL, 0), |
520 | /* hashers */ | |
521 | PLUGIN_REGISTER(HASHER, openssl_hasher_create), | |
02572b84 | 522 | #ifndef OPENSSL_NO_MD2 |
9dc54fc5 | 523 | PLUGIN_PROVIDE(HASHER, HASH_MD2), |
02572b84 MW |
524 | #endif |
525 | #ifndef OPENSSL_NO_MD4 | |
9dc54fc5 | 526 | PLUGIN_PROVIDE(HASHER, HASH_MD4), |
02572b84 MW |
527 | #endif |
528 | #ifndef OPENSSL_NO_MD5 | |
9dc54fc5 | 529 | PLUGIN_PROVIDE(HASHER, HASH_MD5), |
02572b84 | 530 | #endif |
e2c9a03d TB |
531 | #ifndef OPENSSL_NO_SHA1 |
532 | PLUGIN_PROVIDE(HASHER, HASH_SHA1), | |
533 | #endif | |
02572b84 | 534 | #ifndef OPENSSL_NO_SHA256 |
9dc54fc5 MW |
535 | PLUGIN_PROVIDE(HASHER, HASH_SHA224), |
536 | PLUGIN_PROVIDE(HASHER, HASH_SHA256), | |
02572b84 MW |
537 | #endif |
538 | #ifndef OPENSSL_NO_SHA512 | |
9dc54fc5 MW |
539 | PLUGIN_PROVIDE(HASHER, HASH_SHA384), |
540 | PLUGIN_PROVIDE(HASHER, HASH_SHA512), | |
02572b84 MW |
541 | #endif |
542 | #ifndef OPENSSL_NO_SHA1 | |
9dc54fc5 MW |
543 | /* keyed sha1 hasher (aka prf) */ |
544 | PLUGIN_REGISTER(PRF, openssl_sha1_prf_create), | |
545 | PLUGIN_PROVIDE(PRF, PRF_KEYED_SHA1), | |
02572b84 | 546 | #endif |
0504b0a0 AG |
547 | #ifndef OPENSSL_NO_HMAC |
548 | PLUGIN_REGISTER(PRF, openssl_hmac_prf_create), | |
549 | #ifndef OPENSSL_NO_MD5 | |
550 | PLUGIN_PROVIDE(PRF, PRF_HMAC_MD5), | |
551 | #endif | |
552 | #ifndef OPENSSL_NO_SHA1 | |
553 | PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA1), | |
554 | #endif | |
555 | #ifndef OPENSSL_NO_SHA256 | |
556 | PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA2_256), | |
557 | #endif | |
558 | #ifndef OPENSSL_NO_SHA512 | |
559 | PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA2_384), | |
560 | PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA2_512), | |
54081897 AG |
561 | #endif |
562 | PLUGIN_REGISTER(SIGNER, openssl_hmac_signer_create), | |
563 | #ifndef OPENSSL_NO_MD5 | |
564 | PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_MD5_96), | |
565 | PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_MD5_128), | |
566 | #endif | |
567 | #ifndef OPENSSL_NO_SHA1 | |
568 | PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA1_96), | |
569 | PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA1_128), | |
570 | PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA1_160), | |
571 | #endif | |
572 | #ifndef OPENSSL_NO_SHA256 | |
573 | PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_256_128), | |
574 | PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_256_256), | |
575 | #endif | |
576 | #ifndef OPENSSL_NO_SHA512 | |
577 | PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_384_192), | |
578 | PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_384_384), | |
579 | PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_512_256), | |
1f2a34d6 | 580 | PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_512_512), |
0504b0a0 AG |
581 | #endif |
582 | #endif /* OPENSSL_NO_HMAC */ | |
4c969f79 | 583 | #if OPENSSL_VERSION_NUMBER >= 0x1000100fL |
81f9cd39 TB |
584 | #ifndef OPENSSL_NO_AES |
585 | /* AES GCM */ | |
586 | PLUGIN_REGISTER(AEAD, openssl_gcm_create), | |
81f9cd39 TB |
587 | PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV16, 16), |
588 | PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV16, 24), | |
589 | PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV16, 32), | |
a78e1c3b AS |
590 | PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV12, 16), |
591 | PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV12, 24), | |
592 | PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV12, 32), | |
593 | PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV8, 16), | |
594 | PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV8, 24), | |
595 | PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV8, 32), | |
81f9cd39 | 596 | #endif /* OPENSSL_NO_AES */ |
4c969f79 | 597 | #endif /* OPENSSL_VERSION_NUMBER */ |
a78e1c3b AS |
598 | #ifndef OPENSSL_NO_ECDH |
599 | /* EC DH groups */ | |
600 | PLUGIN_REGISTER(DH, openssl_ec_diffie_hellman_create), | |
601 | PLUGIN_PROVIDE(DH, ECP_256_BIT), | |
602 | PLUGIN_PROVIDE(DH, ECP_384_BIT), | |
603 | PLUGIN_PROVIDE(DH, ECP_521_BIT), | |
604 | PLUGIN_PROVIDE(DH, ECP_224_BIT), | |
605 | PLUGIN_PROVIDE(DH, ECP_192_BIT), | |
606 | PLUGIN_PROVIDE(DH, ECP_256_BP), | |
607 | PLUGIN_PROVIDE(DH, ECP_384_BP), | |
608 | PLUGIN_PROVIDE(DH, ECP_512_BP), | |
609 | PLUGIN_PROVIDE(DH, ECP_224_BP), | |
57cb4c8d | 610 | #endif /* OPENSSL_NO_ECDH */ |
02572b84 | 611 | #ifndef OPENSSL_NO_DH |
9dc54fc5 MW |
612 | /* MODP DH groups */ |
613 | PLUGIN_REGISTER(DH, openssl_diffie_hellman_create), | |
9dc54fc5 MW |
614 | PLUGIN_PROVIDE(DH, MODP_3072_BIT), |
615 | PLUGIN_PROVIDE(DH, MODP_4096_BIT), | |
616 | PLUGIN_PROVIDE(DH, MODP_6144_BIT), | |
617 | PLUGIN_PROVIDE(DH, MODP_8192_BIT), | |
5e2b740a AS |
618 | PLUGIN_PROVIDE(DH, MODP_2048_BIT), |
619 | PLUGIN_PROVIDE(DH, MODP_2048_224), | |
620 | PLUGIN_PROVIDE(DH, MODP_2048_256), | |
621 | PLUGIN_PROVIDE(DH, MODP_1536_BIT), | |
9dc54fc5 MW |
622 | PLUGIN_PROVIDE(DH, MODP_1024_BIT), |
623 | PLUGIN_PROVIDE(DH, MODP_1024_160), | |
624 | PLUGIN_PROVIDE(DH, MODP_768_BIT), | |
625 | PLUGIN_PROVIDE(DH, MODP_CUSTOM), | |
02572b84 MW |
626 | #endif |
627 | #ifndef OPENSSL_NO_RSA | |
628 | /* RSA private/public key loading */ | |
9dc54fc5 MW |
629 | PLUGIN_REGISTER(PRIVKEY, openssl_rsa_private_key_load, TRUE), |
630 | PLUGIN_PROVIDE(PRIVKEY, KEY_RSA), | |
9dc54fc5 MW |
631 | PLUGIN_REGISTER(PRIVKEY_GEN, openssl_rsa_private_key_gen, FALSE), |
632 | PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_RSA), | |
3570c439 | 633 | PLUGIN_REGISTER(PUBKEY, openssl_rsa_public_key_load, TRUE), |
9dc54fc5 MW |
634 | PLUGIN_PROVIDE(PUBKEY, KEY_RSA), |
635 | PLUGIN_REGISTER(PUBKEY, openssl_rsa_public_key_load, TRUE), | |
636 | PLUGIN_PROVIDE(PUBKEY, KEY_ANY), | |
637 | /* signature/encryption schemes */ | |
638 | PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_NULL), | |
02572b84 | 639 | PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_NULL), |
51dd2fd2 TB |
640 | #if OPENSSL_VERSION_NUMBER >= 0x10000000L |
641 | PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PSS), | |
2f95d719 | 642 | PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PSS), |
51dd2fd2 | 643 | #endif |
02572b84 | 644 | #ifndef OPENSSL_NO_SHA1 |
9dc54fc5 | 645 | PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA1), |
02572b84 MW |
646 | PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA1), |
647 | #endif | |
648 | #ifndef OPENSSL_NO_SHA256 | |
40f2589a AS |
649 | PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_224), |
650 | PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_256), | |
651 | PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_224), | |
652 | PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_256), | |
02572b84 MW |
653 | #endif |
654 | #ifndef OPENSSL_NO_SHA512 | |
40f2589a AS |
655 | PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_384), |
656 | PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_512), | |
657 | PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_384), | |
658 | PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_512), | |
02572b84 MW |
659 | #endif |
660 | #ifndef OPENSSL_NO_MD5 | |
661 | PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_MD5), | |
9dc54fc5 | 662 | PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_MD5), |
02572b84 | 663 | #endif |
9dc54fc5 MW |
664 | PLUGIN_PROVIDE(PRIVKEY_DECRYPT, ENCRYPT_RSA_PKCS1), |
665 | PLUGIN_PROVIDE(PUBKEY_ENCRYPT, ENCRYPT_RSA_PKCS1), | |
02572b84 | 666 | #endif /* OPENSSL_NO_RSA */ |
9dc54fc5 MW |
667 | /* certificate/CRL loading */ |
668 | PLUGIN_REGISTER(CERT_DECODE, openssl_x509_load, TRUE), | |
669 | PLUGIN_PROVIDE(CERT_DECODE, CERT_X509), | |
0c7af2ce MW |
670 | PLUGIN_SDEPEND(PUBKEY, KEY_RSA), |
671 | PLUGIN_SDEPEND(PUBKEY, KEY_ECDSA), | |
672 | PLUGIN_SDEPEND(PUBKEY, KEY_DSA), | |
9dc54fc5 MW |
673 | PLUGIN_REGISTER(CERT_DECODE, openssl_crl_load, TRUE), |
674 | PLUGIN_PROVIDE(CERT_DECODE, CERT_X509_CRL), | |
0d237763 | 675 | #if OPENSSL_VERSION_NUMBER >= 0x0090807fL |
568ad938 MW |
676 | #ifndef OPENSSL_NO_CMS |
677 | PLUGIN_REGISTER(CONTAINER_DECODE, openssl_pkcs7_load, TRUE), | |
678 | PLUGIN_PROVIDE(CONTAINER_DECODE, CONTAINER_PKCS7), | |
679 | #endif /* OPENSSL_NO_CMS */ | |
0d237763 | 680 | #endif /* OPENSSL_VERSION_NUMBER */ |
780900ab TB |
681 | PLUGIN_REGISTER(CONTAINER_DECODE, openssl_pkcs12_load, TRUE), |
682 | PLUGIN_PROVIDE(CONTAINER_DECODE, CONTAINER_PKCS12), | |
02572b84 | 683 | #ifndef OPENSSL_NO_ECDSA |
9dc54fc5 MW |
684 | /* EC private/public key loading */ |
685 | PLUGIN_REGISTER(PRIVKEY, openssl_ec_private_key_load, TRUE), | |
686 | PLUGIN_PROVIDE(PRIVKEY, KEY_ECDSA), | |
687 | PLUGIN_REGISTER(PRIVKEY_GEN, openssl_ec_private_key_gen, FALSE), | |
688 | PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_ECDSA), | |
689 | PLUGIN_REGISTER(PUBKEY, openssl_ec_public_key_load, TRUE), | |
690 | PLUGIN_PROVIDE(PUBKEY, KEY_ECDSA), | |
691 | /* signature encryption schemes */ | |
692 | PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_NULL), | |
02572b84 MW |
693 | PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_NULL), |
694 | #ifndef OPENSSL_NO_SHA1 | |
9dc54fc5 | 695 | PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA1_DER), |
02572b84 MW |
696 | PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA1_DER), |
697 | #endif | |
698 | #ifndef OPENSSL_NO_SHA256 | |
9dc54fc5 | 699 | PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA256_DER), |
02572b84 MW |
700 | PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA256_DER), |
701 | PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_256), | |
702 | PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_256), | |
703 | #endif | |
704 | #ifndef OPENSSL_NO_SHA512 | |
9dc54fc5 MW |
705 | PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA384_DER), |
706 | PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA512_DER), | |
9dc54fc5 MW |
707 | PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA384_DER), |
708 | PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA512_DER), | |
02572b84 MW |
709 | PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_384), |
710 | PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_521), | |
9dc54fc5 MW |
711 | PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_384), |
712 | PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_521), | |
02572b84 MW |
713 | #endif |
714 | #endif /* OPENSSL_NO_ECDSA */ | |
cbf07ab5 TB |
715 | #if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_EC) |
716 | PLUGIN_REGISTER(DH, openssl_x_diffie_hellman_create), | |
717 | /* available since 1.1.0a, but we require 1.1.1 features */ | |
718 | PLUGIN_PROVIDE(DH, CURVE_25519), | |
719 | /* available since 1.1.1 */ | |
720 | PLUGIN_PROVIDE(DH, CURVE_448), | |
721 | /* EdDSA private/public key loading */ | |
722 | PLUGIN_REGISTER(PUBKEY, openssl_ed_public_key_load, TRUE), | |
723 | PLUGIN_PROVIDE(PUBKEY, KEY_ED25519), | |
724 | PLUGIN_PROVIDE(PUBKEY, KEY_ED448), | |
725 | PLUGIN_REGISTER(PRIVKEY, openssl_ed_private_key_load, TRUE), | |
726 | PLUGIN_PROVIDE(PRIVKEY, KEY_ED25519), | |
727 | PLUGIN_PROVIDE(PRIVKEY, KEY_ED448), | |
728 | PLUGIN_REGISTER(PRIVKEY_GEN, openssl_ed_private_key_gen, FALSE), | |
729 | PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_ED25519), | |
730 | PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_ED448), | |
731 | PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ED25519), | |
732 | PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ED448), | |
733 | PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ED25519), | |
734 | PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ED448), | |
735 | /* register a pro forma identity hasher, never instantiated */ | |
736 | PLUGIN_REGISTER(HASHER, return_null), | |
737 | PLUGIN_PROVIDE(HASHER, HASH_IDENTITY), | |
738 | #endif /* OPENSSL_VERSION_NUMBER && !OPENSSL_NO_EC */ | |
4a6f97d0 TB |
739 | /* generic key loader */ |
740 | PLUGIN_REGISTER(PRIVKEY, openssl_private_key_load, TRUE), | |
741 | PLUGIN_PROVIDE(PRIVKEY, KEY_ANY), | |
b2266280 TB |
742 | PLUGIN_REGISTER(PRIVKEY, openssl_private_key_connect, FALSE), |
743 | PLUGIN_PROVIDE(PRIVKEY, KEY_ANY), | |
4faece7b AG |
744 | PLUGIN_REGISTER(RNG, openssl_rng_create), |
745 | PLUGIN_PROVIDE(RNG, RNG_STRONG), | |
746 | PLUGIN_PROVIDE(RNG, RNG_WEAK), | |
9dc54fc5 MW |
747 | }; |
748 | *features = f; | |
749 | return countof(f); | |
750 | } | |
7daf5226 | 751 | |
9dc54fc5 MW |
752 | METHOD(plugin_t, destroy, void, |
753 | private_openssl_plugin_t *this) | |
754 | { | |
e2abe7ae TB |
755 | /* OpenSSL 1.1.0 cleans up itself at exit and while OPENSSL_cleanup() exists we |
756 | * can't call it as we couldn't re-initialize the library (as required by the | |
757 | * unit tests and the Android app) */ | |
758 | #if OPENSSL_VERSION_NUMBER < 0x10100000L | |
47a46be5 | 759 | #ifndef OPENSSL_IS_BORINGSSL |
651d5ab8 TB |
760 | CONF_modules_free(); |
761 | OBJ_cleanup(); | |
47a46be5 | 762 | #endif |
651d5ab8 | 763 | EVP_cleanup(); |
1e3d66f8 | 764 | #ifndef OPENSSL_NO_ENGINE |
1b7d2e31 | 765 | ENGINE_cleanup(); |
1e3d66f8 | 766 | #endif /* OPENSSL_NO_ENGINE */ |
651d5ab8 | 767 | CRYPTO_cleanup_all_ex_data(); |
2abc66b9 | 768 | threading_cleanup(); |
904390e8 | 769 | ERR_free_strings(); |
e2abe7ae | 770 | #endif /* OPENSSL_VERSION_NUMBER */ |
7daf5226 | 771 | |
17353034 TB |
772 | free(this); |
773 | } | |
774 | ||
775 | /* | |
776 | * see header file | |
777 | */ | |
9ce567f8 | 778 | plugin_t *openssl_plugin_create() |
17353034 | 779 | { |
57202484 | 780 | private_openssl_plugin_t *this; |
f4de6496 AS |
781 | int fips_mode; |
782 | ||
783 | fips_mode = lib->settings->get_int(lib->settings, | |
8dc6e716 | 784 | "%s.plugins.openssl.fips_mode", FIPS_MODE, lib->ns); |
f4de6496 | 785 | #ifdef OPENSSL_FIPS |
c8f34ba7 | 786 | if (fips_mode) |
f4de6496 | 787 | { |
d34d800c | 788 | if (FIPS_mode() != fips_mode && !FIPS_mode_set(fips_mode)) |
c8f34ba7 | 789 | { |
d34d800c MW |
790 | DBG1(DBG_LIB, "unable to set openssl FIPS mode(%d) from (%d)", |
791 | fips_mode, FIPS_mode()); | |
c8f34ba7 TB |
792 | return NULL; |
793 | } | |
f4de6496 | 794 | } |
f4de6496 | 795 | #else |
f4de6496 AS |
796 | if (fips_mode) |
797 | { | |
bd538e8c | 798 | DBG1(DBG_LIB, "openssl FIPS mode(%d) unavailable", fips_mode); |
f4de6496 AS |
799 | return NULL; |
800 | } | |
801 | #endif | |
7daf5226 | 802 | |
57202484 | 803 | INIT(this, |
ba31fe1f MW |
804 | .public = { |
805 | .plugin = { | |
787b5884 | 806 | .get_name = _get_name, |
9dc54fc5 | 807 | .get_features = _get_features, |
ba31fe1f MW |
808 | .destroy = _destroy, |
809 | }, | |
810 | }, | |
57202484 | 811 | ); |
7daf5226 | 812 | |
e2abe7ae TB |
813 | #if OPENSSL_VERSION_NUMBER >= 0x10100000L |
814 | /* note that we can't call OPENSSL_cleanup() when the plugin is destroyed | |
815 | * as we couldn't initialize the library again afterwards */ | |
816 | OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG | | |
817 | OPENSSL_INIT_ENGINE_ALL_BUILTIN, NULL); | |
818 | #else /* OPENSSL_VERSION_NUMBER */ | |
7de6da0c | 819 | threading_init(); |
47a46be5 | 820 | #ifndef OPENSSL_IS_BORINGSSL |
83c42156 | 821 | OPENSSL_config(NULL); |
47a46be5 | 822 | #endif |
17353034 | 823 | OpenSSL_add_all_algorithms(); |
e2abe7ae TB |
824 | #ifndef OPENSSL_NO_ENGINE |
825 | /* activate support for hardware accelerators */ | |
826 | ENGINE_load_builtin_engines(); | |
827 | ENGINE_register_all_complete(); | |
828 | #endif /* OPENSSL_NO_ENGINE */ | |
829 | #endif /* OPENSSL_VERSION_NUMBER */ | |
7daf5226 | 830 | |
c8f34ba7 TB |
831 | #ifdef OPENSSL_FIPS |
832 | /* we do this here as it may have been enabled via openssl.conf */ | |
833 | fips_mode = FIPS_mode(); | |
93168c5f MW |
834 | dbg(DBG_LIB, strpfx(lib->ns, "charon") ? 1 : 2, |
835 | "openssl FIPS mode(%d) - %sabled ", fips_mode, fips_mode ? "en" : "dis"); | |
c8f34ba7 TB |
836 | #endif /* OPENSSL_FIPS */ |
837 | ||
4ec53e95 MW |
838 | if (!seed_rng()) |
839 | { | |
840 | DBG1(DBG_CFG, "no RNG found to seed OpenSSL"); | |
841 | destroy(this); | |
842 | return NULL; | |
843 | } | |
844 | ||
17353034 TB |
845 | return &this->public.plugin; |
846 | } |