Annotation of embedaddon/strongswan/src/libstrongswan/plugins/openssl/openssl_plugin.c, revision 1.1

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>