Annotation of embedaddon/strongswan/src/libstrongswan/crypto/crypto_factory.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2013-2014 Tobias Brunner
                      3:  * Copyright (C) 2008 Martin Willi
                      4:  * Copyright (C) 2016-2019 Andreas Steffen
                      5:  * HSR Hochschule fuer Technik Rapperswil
                      6:  *
                      7:  * This program is free software; you can redistribute it and/or modify it
                      8:  * under the terms of the GNU General Public License as published by the
                      9:  * Free Software Foundation; either version 2 of the License, or (at your
                     10:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     11:  *
                     12:  * This program is distributed in the hope that it will be useful, but
                     13:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     14:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     15:  * for more details.
                     16:  */
                     17: 
                     18: #include "crypto_factory.h"
                     19: 
                     20: #include <utils/debug.h>
                     21: #include <threading/rwlock.h>
                     22: #include <collections/linked_list.h>
                     23: #include <crypto/crypto_tester.h>
                     24: #include <utils/test.h>
                     25: 
                     26: const char *default_plugin_name = "default";
                     27: 
                     28: typedef struct entry_t entry_t;
                     29: 
                     30: struct entry_t {
                     31:        /**
                     32:         * algorithm
                     33:         */
                     34:        u_int algo;
                     35: 
                     36:        /**
                     37:         * plugin that registered this algorithm
                     38:         */
                     39:        const char *plugin_name;
                     40: 
                     41:        /**
                     42:         * benchmarked speed
                     43:         */
                     44:        u_int speed;
                     45: 
                     46:        /**
                     47:         * constructor
                     48:         */
                     49:        union {
                     50:                crypter_constructor_t create_crypter;
                     51:                aead_constructor_t create_aead;
                     52:                signer_constructor_t create_signer;
                     53:                hasher_constructor_t create_hasher;
                     54:                prf_constructor_t create_prf;
                     55:                xof_constructor_t create_xof;
                     56:                drbg_constructor_t create_drbg;
                     57:                rng_constructor_t create_rng;
                     58:                nonce_gen_constructor_t create_nonce_gen;
                     59:                dh_constructor_t create_dh;
                     60:                void *create;
                     61:        };
                     62: };
                     63: 
                     64: typedef struct private_crypto_factory_t private_crypto_factory_t;
                     65: 
                     66: /**
                     67:  * private data of crypto_factory
                     68:  */
                     69: struct private_crypto_factory_t {
                     70: 
                     71:        /**
                     72:         * public functions
                     73:         */
                     74:        crypto_factory_t public;
                     75: 
                     76:        /**
                     77:         * registered crypters, as entry_t
                     78:         */
                     79:        linked_list_t *crypters;
                     80: 
                     81:        /**
                     82:         * registered aead transforms, as entry_t
                     83:         */
                     84:        linked_list_t *aeads;
                     85: 
                     86:        /**
                     87:         * registered signers, as entry_t
                     88:         */
                     89:        linked_list_t *signers;
                     90: 
                     91:        /**
                     92:         * registered hashers, as entry_t
                     93:         */
                     94:        linked_list_t *hashers;
                     95: 
                     96:        /**
                     97:         * registered prfs, as entry_t
                     98:         */
                     99:        linked_list_t *prfs;
                    100: 
                    101:        /**
                    102:         * registered xofs, as entry_t
                    103:         */
                    104:        linked_list_t *xofs;
                    105: 
                    106:        /**
                    107:         * registered drbgs, as entry_t
                    108:         */
                    109:        linked_list_t *drbgs;
                    110: 
                    111:        /**
                    112:         * registered rngs, as entry_t
                    113:         */
                    114:        linked_list_t *rngs;
                    115: 
                    116:        /**
                    117:         * registered nonce generators, as entry_t
                    118:         */
                    119:        linked_list_t *nonce_gens;
                    120: 
                    121:        /**
                    122:         * registered diffie hellman, as entry_t
                    123:         */
                    124:        linked_list_t *dhs;
                    125: 
                    126:        /**
                    127:         * test manager to test crypto algorithms
                    128:         */
                    129:        crypto_tester_t *tester;
                    130: 
                    131:        /**
                    132:         * whether to test algorithms during registration
                    133:         */
                    134:        bool test_on_add;
                    135: 
                    136:        /**
                    137:         * whether to test algorithms on each crypto primitive construction
                    138:         */
                    139:        bool test_on_create;
                    140: 
                    141:        /**
                    142:         * run algorithm benchmark during registration
                    143:         */
                    144:        bool bench;
                    145: 
                    146:        /**
                    147:         * Number of failed test vectors during "add".
                    148:         */
                    149:        u_int test_failures;
                    150: 
                    151:        /**
                    152:         * rwlock to lock access to modules
                    153:         */
                    154:        rwlock_t *lock;
                    155: };
                    156: 
                    157: METHOD(crypto_factory_t, create_crypter, crypter_t*,
                    158:        private_crypto_factory_t *this, encryption_algorithm_t algo,
                    159:        size_t key_size)
                    160: {
                    161:        enumerator_t *enumerator;
                    162:        entry_t *entry;
                    163:        crypter_t *crypter = NULL;
                    164: 
                    165:        this->lock->read_lock(this->lock);
                    166:        enumerator = this->crypters->create_enumerator(this->crypters);
                    167:        while (enumerator->enumerate(enumerator, &entry))
                    168:        {
                    169:                if (entry->algo == algo)
                    170:                {
                    171:                        if (this->test_on_create &&
                    172:                                !this->tester->test_crypter(this->tester, algo, key_size,
                    173:                                                                                        entry->create_crypter, NULL,
                    174:                                                                                        default_plugin_name))
                    175:                        {
                    176:                                continue;
                    177:                        }
                    178:                        crypter = entry->create_crypter(algo, key_size);
                    179:                        if (crypter)
                    180:                        {
                    181:                                break;
                    182:                        }
                    183:                }
                    184:        }
                    185:        enumerator->destroy(enumerator);
                    186:        this->lock->unlock(this->lock);
                    187:        return crypter;
                    188: }
                    189: 
                    190: METHOD(crypto_factory_t, create_aead, aead_t*,
                    191:        private_crypto_factory_t *this, encryption_algorithm_t algo,
                    192:        size_t key_size, size_t salt_size)
                    193: {
                    194:        enumerator_t *enumerator;
                    195:        entry_t *entry;
                    196:        aead_t *aead = NULL;
                    197: 
                    198:        this->lock->read_lock(this->lock);
                    199:        enumerator = this->aeads->create_enumerator(this->aeads);
                    200:        while (enumerator->enumerate(enumerator, &entry))
                    201:        {
                    202:                if (entry->algo == algo)
                    203:                {
                    204:                        if (this->test_on_create &&
                    205:                                !this->tester->test_aead(this->tester, algo, key_size,
                    206:                                                                                 salt_size, entry->create_aead, NULL,
                    207:                                                                                 default_plugin_name))
                    208:                        {
                    209:                                continue;
                    210:                        }
                    211:                        aead = entry->create_aead(algo, key_size, salt_size);
                    212:                        if (aead)
                    213:                        {
                    214:                                break;
                    215:                        }
                    216:                }
                    217:        }
                    218:        enumerator->destroy(enumerator);
                    219:        this->lock->unlock(this->lock);
                    220:        return aead;
                    221: }
                    222: 
                    223: METHOD(crypto_factory_t, create_signer, signer_t*,
                    224:        private_crypto_factory_t *this, integrity_algorithm_t algo)
                    225: {
                    226:        enumerator_t *enumerator;
                    227:        entry_t *entry;
                    228:        signer_t *signer = NULL;
                    229: 
                    230:        this->lock->read_lock(this->lock);
                    231:        enumerator = this->signers->create_enumerator(this->signers);
                    232:        while (enumerator->enumerate(enumerator, &entry))
                    233:        {
                    234:                if (entry->algo == algo)
                    235:                {
                    236:                        if (this->test_on_create &&
                    237:                                !this->tester->test_signer(this->tester, algo,
                    238:                                                                                   entry->create_signer, NULL,
                    239:                                                                                   default_plugin_name))
                    240:                        {
                    241:                                continue;
                    242:                        }
                    243:                        signer = entry->create_signer(algo);
                    244:                        if (signer)
                    245:                        {
                    246:                                break;
                    247:                        }
                    248:                }
                    249:        }
                    250:        enumerator->destroy(enumerator);
                    251:        this->lock->unlock(this->lock);
                    252:        return signer;
                    253: }
                    254: 
                    255: METHOD(crypto_factory_t, create_hasher, hasher_t*,
                    256:        private_crypto_factory_t *this, hash_algorithm_t algo)
                    257: {
                    258:        enumerator_t *enumerator;
                    259:        entry_t *entry;
                    260:        hasher_t *hasher = NULL;
                    261: 
                    262:        this->lock->read_lock(this->lock);
                    263:        enumerator = this->hashers->create_enumerator(this->hashers);
                    264:        while (enumerator->enumerate(enumerator, &entry))
                    265:        {
                    266:                if (entry->algo == algo)
                    267:                {
                    268:                        if (this->test_on_create &&
                    269:                                !this->tester->test_hasher(this->tester, algo,
                    270:                                                                                   entry->create_hasher, NULL,
                    271:                                                                                   default_plugin_name))
                    272:                        {
                    273:                                continue;
                    274:                        }
                    275:                        hasher = entry->create_hasher(entry->algo);
                    276:                        if (hasher)
                    277:                        {
                    278:                                break;
                    279:                        }
                    280:                }
                    281:        }
                    282:        enumerator->destroy(enumerator);
                    283:        this->lock->unlock(this->lock);
                    284:        return hasher;
                    285: }
                    286: 
                    287: METHOD(crypto_factory_t, create_prf, prf_t*,
                    288:        private_crypto_factory_t *this, pseudo_random_function_t algo)
                    289: {
                    290:        enumerator_t *enumerator;
                    291:        entry_t *entry;
                    292:        prf_t *prf = NULL;
                    293: 
                    294:        this->lock->read_lock(this->lock);
                    295:        enumerator = this->prfs->create_enumerator(this->prfs);
                    296:        while (enumerator->enumerate(enumerator, &entry))
                    297:        {
                    298:                if (entry->algo == algo)
                    299:                {
                    300:                        if (this->test_on_create &&
                    301:                                !this->tester->test_prf(this->tester, algo,
                    302:                                                                                entry->create_prf, NULL,
                    303:                                                                                default_plugin_name))
                    304:                        {
                    305:                                continue;
                    306:                        }
                    307:                        prf = entry->create_prf(algo);
                    308:                        if (prf)
                    309:                        {
                    310:                                break;
                    311:                        }
                    312:                }
                    313:        }
                    314:        enumerator->destroy(enumerator);
                    315:        this->lock->unlock(this->lock);
                    316:        return prf;
                    317: }
                    318: 
                    319: METHOD(crypto_factory_t, create_xof, xof_t*,
                    320:        private_crypto_factory_t *this, ext_out_function_t algo)
                    321: {
                    322:        enumerator_t *enumerator;
                    323:        entry_t *entry;
                    324:        xof_t *xof = NULL;
                    325: 
                    326:        this->lock->read_lock(this->lock);
                    327:        enumerator = this->xofs->create_enumerator(this->xofs);
                    328:        while (enumerator->enumerate(enumerator, &entry))
                    329:        {
                    330:                if (entry->algo == algo)
                    331:                {
                    332:                        if (this->test_on_create &&
                    333:                                !this->tester->test_xof(this->tester, algo,
                    334:                                                                                entry->create_xof, NULL,
                    335:                                                                                default_plugin_name))
                    336:                        {
                    337:                                continue;
                    338:                        }
                    339:                        xof = entry->create_xof(algo);
                    340:                        if (xof)
                    341:                        {
                    342:                                break;
                    343:                        }
                    344:                }
                    345:        }
                    346:        enumerator->destroy(enumerator);
                    347:        this->lock->unlock(this->lock);
                    348:        return xof;
                    349: }
                    350: 
                    351: METHOD(crypto_factory_t, create_drbg, drbg_t*,
                    352:        private_crypto_factory_t *this, drbg_type_t type, uint32_t strength,
                    353:        rng_t *entropy, chunk_t personalization_str)
                    354: {
                    355:        enumerator_t *enumerator;
                    356:        entry_t *entry;
                    357:        drbg_t *drbg = NULL;
                    358: 
                    359:        this->lock->read_lock(this->lock);
                    360:        enumerator = this->drbgs->create_enumerator(this->drbgs);
                    361:        while (enumerator->enumerate(enumerator, &entry))
                    362:        {
                    363:                if (entry->algo == type)
                    364:                {
                    365:                        if (this->test_on_create &&
                    366:                                !this->tester->test_drbg(this->tester, type,
                    367:                                                                                 entry->create_drbg, NULL,
                    368:                                                                                 default_plugin_name))
                    369:                        {
                    370:                                continue;
                    371:                        }
                    372:                        drbg = entry->create_drbg(type, strength, entropy,
                    373:                                                                          personalization_str);
                    374:                        if (drbg)
                    375:                        {
                    376:                                break;
                    377:                        }
                    378:                }
                    379:        }
                    380:        enumerator->destroy(enumerator);
                    381:        this->lock->unlock(this->lock);
                    382:        return drbg;
                    383: }
                    384: 
                    385: METHOD(crypto_factory_t, create_rng, rng_t*,
                    386:        private_crypto_factory_t *this, rng_quality_t quality)
                    387: {
                    388:        enumerator_t *enumerator;
                    389:        entry_t *entry;
                    390:        rng_t *rng = NULL;
                    391: 
                    392:        this->lock->read_lock(this->lock);
                    393:        enumerator = this->rngs->create_enumerator(this->rngs);
                    394:        while (enumerator->enumerate(enumerator, &entry))
                    395:        {       /* find the best matching quality, but at least as good as requested */
                    396:                if (entry->algo >= quality)
                    397:                {
                    398:                        if (this->test_on_create &&
                    399:                                !this->tester->test_rng(this->tester, quality,
                    400:                                                                                entry->create_rng, NULL,
                    401:                                                                                default_plugin_name))
                    402:                        {
                    403:                                continue;
                    404:                        }
                    405:                        rng = entry->create_rng(quality);
                    406:                        if (rng)
                    407:                        {
                    408:                                break;
                    409:                        }
                    410:                }
                    411:        }
                    412:        enumerator->destroy(enumerator);
                    413:        this->lock->unlock(this->lock);
                    414:        return rng;
                    415: }
                    416: 
                    417: METHOD(crypto_factory_t, create_nonce_gen, nonce_gen_t*,
                    418:        private_crypto_factory_t *this)
                    419: {
                    420:        enumerator_t *enumerator;
                    421:        entry_t *entry;
                    422:        nonce_gen_t *nonce_gen = NULL;
                    423: 
                    424:        this->lock->read_lock(this->lock);
                    425:        enumerator = this->nonce_gens->create_enumerator(this->nonce_gens);
                    426:        while (enumerator->enumerate(enumerator, &entry))
                    427:        {
                    428:                nonce_gen = entry->create_nonce_gen();
                    429:                if (nonce_gen)
                    430:                {
                    431:                        break;
                    432:                }
                    433:        }
                    434:        enumerator->destroy(enumerator);
                    435:        this->lock->unlock(this->lock);
                    436: 
                    437:        return nonce_gen;
                    438: }
                    439: 
                    440: METHOD(crypto_factory_t, create_dh, diffie_hellman_t*,
                    441:        private_crypto_factory_t *this, diffie_hellman_group_t group, ...)
                    442: {
                    443:        enumerator_t *enumerator;
                    444:        entry_t *entry;
                    445:        va_list args;
                    446:        chunk_t g = chunk_empty, p = chunk_empty;
                    447:        diffie_hellman_t *diffie_hellman = NULL;
                    448: 
                    449:        if (group == MODP_CUSTOM)
                    450:        {
                    451:                va_start(args, group);
                    452:                g = va_arg(args, chunk_t);
                    453:                p = va_arg(args, chunk_t);
                    454:                va_end(args);
                    455:        }
                    456: 
                    457:        this->lock->read_lock(this->lock);
                    458:        enumerator = this->dhs->create_enumerator(this->dhs);
                    459:        while (enumerator->enumerate(enumerator, &entry))
                    460:        {
                    461:                if (entry->algo == group)
                    462:                {
                    463:                        if (this->test_on_create && group != MODP_CUSTOM &&
                    464:                                !this->tester->test_dh(this->tester, group,
                    465:                                                                entry->create_dh, NULL, default_plugin_name))
                    466:                        {
                    467:                                continue;
                    468:                        }
                    469:                        diffie_hellman = entry->create_dh(group, g, p);
                    470:                        if (diffie_hellman)
                    471:                        {
                    472:                                break;
                    473:                        }
                    474:                }
                    475:        }
                    476:        enumerator->destroy(enumerator);
                    477:        this->lock->unlock(this->lock);
                    478:        return diffie_hellman;
                    479: }
                    480: 
                    481: /**
                    482:  * Insert an algorithm entry to a list
                    483:  *
                    484:  * Entries maintain the order in which algorithms were added, unless they were
                    485:  * benchmarked and speed is provided, which then is used to order entries of
                    486:  * the same algorithm.
                    487:  * An exception are RNG entries, which are sorted by algorithm identifier.
                    488:  */
                    489: static void add_entry(private_crypto_factory_t *this, linked_list_t *list,
                    490:                                          int algo, const char *plugin_name,
                    491:                                          u_int speed, void *create)
                    492: {
                    493:        enumerator_t *enumerator;
                    494:        entry_t *entry, *current;
                    495:        bool sort = (list == this->rngs), found = FALSE;
                    496: 
                    497:        INIT(entry,
                    498:                .algo = algo,
                    499:                .plugin_name = plugin_name,
                    500:                .speed = speed,
                    501:        );
                    502:        entry->create = create;
                    503: 
                    504:        this->lock->write_lock(this->lock);
                    505:        enumerator = list->create_enumerator(list);
                    506:        while (enumerator->enumerate(enumerator, &current))
                    507:        {
                    508:                if (sort && current->algo > algo)
                    509:                {
                    510:                        break;
                    511:                }
                    512:                else if (current->algo == algo)
                    513:                {
                    514:                        if (speed > current->speed)
                    515:                        {
                    516:                                break;
                    517:                        }
                    518:                        found = TRUE;
                    519:                }
                    520:                else if (found)
                    521:                {
                    522:                        break;
                    523:                }
                    524:        }
                    525:        list->insert_before(list, enumerator, entry);
                    526:        enumerator->destroy(enumerator);
                    527:        this->lock->unlock(this->lock);
                    528: }
                    529: 
                    530: METHOD(crypto_factory_t, add_crypter, bool,
                    531:        private_crypto_factory_t *this, encryption_algorithm_t algo, size_t key_size,
                    532:        const char *plugin_name, crypter_constructor_t create)
                    533: {
                    534:        u_int speed = 0;
                    535: 
                    536:        if (!this->test_on_add ||
                    537:                this->tester->test_crypter(this->tester, algo, key_size, create,
                    538:                                                                   this->bench ? &speed : NULL, plugin_name))
                    539:        {
                    540:                add_entry(this, this->crypters, algo, plugin_name, speed, create);
                    541:                return TRUE;
                    542:        }
                    543:        this->test_failures++;
                    544:        return FALSE;
                    545: }
                    546: 
                    547: METHOD(crypto_factory_t, remove_crypter, void,
                    548:        private_crypto_factory_t *this, crypter_constructor_t create)
                    549: {
                    550:        entry_t *entry;
                    551:        enumerator_t *enumerator;
                    552: 
                    553:        this->lock->write_lock(this->lock);
                    554:        enumerator = this->crypters->create_enumerator(this->crypters);
                    555:        while (enumerator->enumerate(enumerator, &entry))
                    556:        {
                    557:                if (entry->create_crypter == create)
                    558:                {
                    559:                        this->crypters->remove_at(this->crypters, enumerator);
                    560:                        free(entry);
                    561:                }
                    562:        }
                    563:        enumerator->destroy(enumerator);
                    564:        this->lock->unlock(this->lock);
                    565: }
                    566: 
                    567: METHOD(crypto_factory_t, add_aead, bool,
                    568:        private_crypto_factory_t *this, encryption_algorithm_t algo, size_t key_size,
                    569:        const char *plugin_name, aead_constructor_t create)
                    570: {
                    571:        u_int speed = 0;
                    572: 
                    573:        if (!this->test_on_add ||
                    574:                this->tester->test_aead(this->tester, algo, key_size, 0, create,
                    575:                                                                this->bench ? &speed : NULL, plugin_name))
                    576:        {
                    577:                add_entry(this, this->aeads, algo, plugin_name, speed, create);
                    578:                return TRUE;
                    579:        }
                    580:        this->test_failures++;
                    581:        return FALSE;
                    582: }
                    583: 
                    584: METHOD(crypto_factory_t, remove_aead, void,
                    585:        private_crypto_factory_t *this, aead_constructor_t create)
                    586: {
                    587:        entry_t *entry;
                    588:        enumerator_t *enumerator;
                    589: 
                    590:        this->lock->write_lock(this->lock);
                    591:        enumerator = this->aeads->create_enumerator(this->aeads);
                    592:        while (enumerator->enumerate(enumerator, &entry))
                    593:        {
                    594:                if (entry->create_aead == create)
                    595:                {
                    596:                        this->aeads->remove_at(this->aeads, enumerator);
                    597:                        free(entry);
                    598:                }
                    599:        }
                    600:        enumerator->destroy(enumerator);
                    601:        this->lock->unlock(this->lock);
                    602: }
                    603: 
                    604: METHOD(crypto_factory_t, add_signer, bool,
                    605:        private_crypto_factory_t *this, integrity_algorithm_t algo,
                    606:        const char *plugin_name, signer_constructor_t create)
                    607: {
                    608:        u_int speed = 0;
                    609: 
                    610:        if (!this->test_on_add ||
                    611:                this->tester->test_signer(this->tester, algo, create,
                    612:                                                                  this->bench ? &speed : NULL, plugin_name))
                    613:        {
                    614:                add_entry(this, this->signers, algo, plugin_name, speed, create);
                    615:                return TRUE;
                    616:        }
                    617:        this->test_failures++;
                    618:        return FALSE;
                    619: }
                    620: 
                    621: METHOD(crypto_factory_t, remove_signer, void,
                    622:        private_crypto_factory_t *this, signer_constructor_t create)
                    623: {
                    624:        entry_t *entry;
                    625:        enumerator_t *enumerator;
                    626: 
                    627:        this->lock->write_lock(this->lock);
                    628:        enumerator = this->signers->create_enumerator(this->signers);
                    629:        while (enumerator->enumerate(enumerator, &entry))
                    630:        {
                    631:                if (entry->create_signer == create)
                    632:                {
                    633:                        this->signers->remove_at(this->signers, enumerator);
                    634:                        free(entry);
                    635:                }
                    636:        }
                    637:        enumerator->destroy(enumerator);
                    638:        this->lock->unlock(this->lock);
                    639: }
                    640: 
                    641: METHOD(crypto_factory_t, add_hasher, bool,
                    642:        private_crypto_factory_t *this, hash_algorithm_t algo,
                    643:        const char *plugin_name, hasher_constructor_t create)
                    644: {
                    645:        u_int speed = 0;
                    646: 
                    647:        if (!this->test_on_add ||
                    648:                this->tester->test_hasher(this->tester, algo, create,
                    649:                                                                  this->bench ? &speed : NULL, plugin_name))
                    650:        {
                    651:                add_entry(this, this->hashers, algo, plugin_name, speed, create);
                    652:                return TRUE;
                    653:        }
                    654:        this->test_failures++;
                    655:        return FALSE;
                    656: }
                    657: 
                    658: METHOD(crypto_factory_t, remove_hasher, void,
                    659:        private_crypto_factory_t *this, hasher_constructor_t create)
                    660: {
                    661:        entry_t *entry;
                    662:        enumerator_t *enumerator;
                    663: 
                    664:        this->lock->write_lock(this->lock);
                    665:        enumerator = this->hashers->create_enumerator(this->hashers);
                    666:        while (enumerator->enumerate(enumerator, &entry))
                    667:        {
                    668:                if (entry->create_hasher == create)
                    669:                {
                    670:                        this->hashers->remove_at(this->hashers, enumerator);
                    671:                        free(entry);
                    672:                }
                    673:        }
                    674:        enumerator->destroy(enumerator);
                    675:        this->lock->unlock(this->lock);
                    676: }
                    677: 
                    678: METHOD(crypto_factory_t, add_prf, bool,
                    679:        private_crypto_factory_t *this, pseudo_random_function_t algo,
                    680:        const char *plugin_name, prf_constructor_t create)
                    681: {
                    682:        u_int speed = 0;
                    683: 
                    684:        if (!this->test_on_add ||
                    685:                this->tester->test_prf(this->tester, algo, create,
                    686:                                                           this->bench ? &speed : NULL, plugin_name))
                    687:        {
                    688:                add_entry(this, this->prfs, algo, plugin_name, speed, create);
                    689:                return TRUE;
                    690:        }
                    691:        this->test_failures++;
                    692:        return FALSE;
                    693: }
                    694: 
                    695: METHOD(crypto_factory_t, remove_prf, void,
                    696:        private_crypto_factory_t *this, prf_constructor_t create)
                    697: {
                    698:        entry_t *entry;
                    699:        enumerator_t *enumerator;
                    700: 
                    701:        this->lock->write_lock(this->lock);
                    702:        enumerator = this->prfs->create_enumerator(this->prfs);
                    703:        while (enumerator->enumerate(enumerator, &entry))
                    704:        {
                    705:                if (entry->create_prf == create)
                    706:                {
                    707:                        this->prfs->remove_at(this->prfs, enumerator);
                    708:                        free(entry);
                    709:                }
                    710:        }
                    711:        enumerator->destroy(enumerator);
                    712:        this->lock->unlock(this->lock);
                    713: }
                    714: 
                    715: METHOD(crypto_factory_t, add_xof, bool,
                    716:        private_crypto_factory_t *this, ext_out_function_t algo,
                    717:        const char *plugin_name, xof_constructor_t create)
                    718: {
                    719:        u_int speed = 0;
                    720: 
                    721:        if (!this->test_on_add ||
                    722:                this->tester->test_xof(this->tester, algo, create,
                    723:                                                           this->bench ? &speed : NULL, plugin_name))
                    724:        {
                    725:                add_entry(this, this->xofs, algo, plugin_name, speed, create);
                    726:                return TRUE;
                    727:        }
                    728:        this->test_failures++;
                    729:        return FALSE;
                    730: }
                    731: 
                    732: METHOD(crypto_factory_t, remove_xof, void,
                    733:        private_crypto_factory_t *this, xof_constructor_t create)
                    734: {
                    735:        entry_t *entry;
                    736:        enumerator_t *enumerator;
                    737: 
                    738:        this->lock->write_lock(this->lock);
                    739:        enumerator = this->xofs->create_enumerator(this->xofs);
                    740:        while (enumerator->enumerate(enumerator, &entry))
                    741:        {
                    742:                if (entry->create_xof == create)
                    743:                {
                    744:                        this->xofs->remove_at(this->xofs, enumerator);
                    745:                        free(entry);
                    746:                }
                    747:        }
                    748:        enumerator->destroy(enumerator);
                    749:        this->lock->unlock(this->lock);
                    750: }
                    751: 
                    752: METHOD(crypto_factory_t, add_drbg, bool,
                    753:        private_crypto_factory_t *this, drbg_type_t type,
                    754:        const char *plugin_name, drbg_constructor_t create)
                    755: {
                    756:        u_int speed = 0;
                    757: 
                    758:        if (!this->test_on_add ||
                    759:                this->tester->test_drbg(this->tester, type, create,
                    760:                                                           this->bench ? &speed : NULL, plugin_name))
                    761:        {
                    762:                add_entry(this, this->drbgs, type, plugin_name, speed, create);
                    763:                return TRUE;
                    764:        }
                    765:        this->test_failures++;
                    766:        return FALSE;
                    767: }
                    768: 
                    769: METHOD(crypto_factory_t, remove_drbg, void,
                    770:        private_crypto_factory_t *this, drbg_constructor_t create)
                    771: {
                    772:        entry_t *entry;
                    773:        enumerator_t *enumerator;
                    774: 
                    775:        this->lock->write_lock(this->lock);
                    776:        enumerator = this->drbgs->create_enumerator(this->drbgs);
                    777:        while (enumerator->enumerate(enumerator, &entry))
                    778:        {
                    779:                if (entry->create_drbg == create)
                    780:                {
                    781:                        this->drbgs->remove_at(this->drbgs, enumerator);
                    782:                        free(entry);
                    783:                }
                    784:        }
                    785:        enumerator->destroy(enumerator);
                    786:        this->lock->unlock(this->lock);
                    787: }
                    788: 
                    789: METHOD(crypto_factory_t, add_rng, bool,
                    790:        private_crypto_factory_t *this, rng_quality_t quality,
                    791:        const char *plugin_name, rng_constructor_t create)
                    792: {
                    793:        u_int speed = 0;
                    794: 
                    795:        if (!this->test_on_add ||
                    796:                this->tester->test_rng(this->tester, quality, create,
                    797:                                                           this->bench ? &speed : NULL, plugin_name))
                    798:        {
                    799:                add_entry(this, this->rngs, quality, plugin_name, speed, create);
                    800:                return TRUE;
                    801:        }
                    802:        this->test_failures++;
                    803:        return FALSE;
                    804: }
                    805: 
                    806: METHOD(crypto_factory_t, remove_rng, void,
                    807:        private_crypto_factory_t *this, rng_constructor_t create)
                    808: {
                    809:        entry_t *entry;
                    810:        enumerator_t *enumerator;
                    811: 
                    812:        this->lock->write_lock(this->lock);
                    813:        enumerator = this->rngs->create_enumerator(this->rngs);
                    814:        while (enumerator->enumerate(enumerator, &entry))
                    815:        {
                    816:                if (entry->create_rng == create)
                    817:                {
                    818:                        this->rngs->remove_at(this->rngs, enumerator);
                    819:                        free(entry);
                    820:                }
                    821:        }
                    822:        enumerator->destroy(enumerator);
                    823:        this->lock->unlock(this->lock);
                    824: }
                    825: 
                    826: METHOD(crypto_factory_t, add_nonce_gen, bool,
                    827:        private_crypto_factory_t *this, const char *plugin_name,
                    828:        nonce_gen_constructor_t create)
                    829: {
                    830:        add_entry(this, this->nonce_gens, 0, plugin_name, 0, create);
                    831:        return TRUE;
                    832: }
                    833: 
                    834: METHOD(crypto_factory_t, remove_nonce_gen, void,
                    835:        private_crypto_factory_t *this, nonce_gen_constructor_t create)
                    836: {
                    837:        entry_t *entry;
                    838:        enumerator_t *enumerator;
                    839: 
                    840:        this->lock->write_lock(this->lock);
                    841:        enumerator = this->nonce_gens->create_enumerator(this->nonce_gens);
                    842:        while (enumerator->enumerate(enumerator, &entry))
                    843:        {
                    844:                if (entry->create_nonce_gen == create)
                    845:                {
                    846:                        this->nonce_gens->remove_at(this->nonce_gens, enumerator);
                    847:                        free(entry);
                    848:                }
                    849:        }
                    850:        enumerator->destroy(enumerator);
                    851:        this->lock->unlock(this->lock);
                    852: }
                    853: 
                    854: METHOD(crypto_factory_t, add_dh, bool,
                    855:        private_crypto_factory_t *this, diffie_hellman_group_t group,
                    856:        const char *plugin_name, dh_constructor_t create)
                    857: {
                    858:        u_int speed = 0;
                    859: 
                    860:        if (!this->test_on_add ||
                    861:                this->tester->test_dh(this->tester, group, create,
                    862:                                                          this->bench ? &speed : NULL, plugin_name))
                    863:        {
                    864:                add_entry(this, this->dhs, group, plugin_name, 0, create);
                    865:                return TRUE;
                    866:        }
                    867:        this->test_failures++;
                    868:        return FALSE;
                    869: }
                    870: 
                    871: METHOD(crypto_factory_t, remove_dh, void,
                    872:        private_crypto_factory_t *this, dh_constructor_t create)
                    873: {
                    874:        entry_t *entry;
                    875:        enumerator_t *enumerator;
                    876: 
                    877:        this->lock->write_lock(this->lock);
                    878:        enumerator = this->dhs->create_enumerator(this->dhs);
                    879:        while (enumerator->enumerate(enumerator, &entry))
                    880:        {
                    881:                if (entry->create_dh == create)
                    882:                {
                    883:                        this->dhs->remove_at(this->dhs, enumerator);
                    884:                        free(entry);
                    885:                }
                    886:        }
                    887:        enumerator->destroy(enumerator);
                    888:        this->lock->unlock(this->lock);
                    889: }
                    890: 
                    891: CALLBACK(entry_match, bool,
                    892:        entry_t *a, va_list args)
                    893: {
                    894:        entry_t *b;
                    895: 
                    896:        VA_ARGS_VGET(args, b);
                    897:        return a->algo == b->algo;
                    898: }
                    899: 
                    900: CALLBACK(unique_check, bool,
                    901:        linked_list_t *list, enumerator_t *orig, va_list args)
                    902: {
                    903:        entry_t *entry, **out;
                    904: 
                    905:        VA_ARGS_VGET(args, out);
                    906: 
                    907:        while (orig->enumerate(orig, &entry))
                    908:        {
                    909:                if (list->find_first(list, entry_match, NULL, entry))
                    910:                {
                    911:                        continue;
                    912:                }
                    913:                *out = entry;
                    914:                list->insert_last(list, entry);
                    915:                return TRUE;
                    916:        }
                    917:        return FALSE;
                    918: }
                    919: 
                    920: /**
                    921:  * create an enumerator over entry->algo in list with locking and unique check
                    922:  */
                    923: static enumerator_t *create_enumerator(private_crypto_factory_t *this,
                    924:                                                                        linked_list_t *list,
                    925:                                                                        bool (*filter)(void*,enumerator_t*,va_list))
                    926: {
                    927:        this->lock->read_lock(this->lock);
                    928:        return enumerator_create_filter(
                    929:                                enumerator_create_filter(
                    930:                                        list->create_enumerator(list), unique_check,
                    931:                                        linked_list_create(), (void*)list->destroy),
                    932:                                filter, this->lock, (void*)this->lock->unlock);
                    933: }
                    934: 
                    935: CALLBACK(crypter_filter, bool,
                    936:        void *n, enumerator_t *orig, va_list args)
                    937: {
                    938:        entry_t *entry;
                    939:        encryption_algorithm_t *algo;
                    940:        const char **plugin_name;
                    941: 
                    942:        VA_ARGS_VGET(args, algo, plugin_name);
                    943: 
                    944:        if (orig->enumerate(orig, &entry))
                    945:        {
                    946:                *algo = entry->algo;
                    947:                *plugin_name = entry->plugin_name;
                    948:                return TRUE;
                    949:        }
                    950:        return FALSE;
                    951: }
                    952: 
                    953: METHOD(crypto_factory_t, create_crypter_enumerator, enumerator_t*,
                    954:        private_crypto_factory_t *this)
                    955: {
                    956:        return create_enumerator(this, this->crypters, crypter_filter);
                    957: }
                    958: 
                    959: METHOD(crypto_factory_t, create_aead_enumerator, enumerator_t*,
                    960:        private_crypto_factory_t *this)
                    961: {
                    962:        return create_enumerator(this, this->aeads, crypter_filter);
                    963: }
                    964: 
                    965: CALLBACK(signer_filter, bool,
                    966:        void *n, enumerator_t *orig, va_list args)
                    967: {
                    968:        entry_t *entry;
                    969:        integrity_algorithm_t *algo;
                    970:        const char **plugin_name;
                    971: 
                    972:        VA_ARGS_VGET(args, algo, plugin_name);
                    973: 
                    974:        if (orig->enumerate(orig, &entry))
                    975:        {
                    976:                *algo = entry->algo;
                    977:                *plugin_name = entry->plugin_name;
                    978:                return TRUE;
                    979:        }
                    980:        return FALSE;
                    981: }
                    982: 
                    983: METHOD(crypto_factory_t, create_signer_enumerator, enumerator_t*,
                    984:        private_crypto_factory_t *this)
                    985: {
                    986:        return create_enumerator(this, this->signers, signer_filter);
                    987: }
                    988: 
                    989: CALLBACK(hasher_filter, bool,
                    990:        void *n, enumerator_t *orig, va_list args)
                    991: {
                    992:        entry_t *entry;
                    993:        hash_algorithm_t *algo;
                    994:        const char **plugin_name;
                    995: 
                    996:        VA_ARGS_VGET(args, algo, plugin_name);
                    997: 
                    998:        if (orig->enumerate(orig, &entry))
                    999:        {
                   1000:                *algo = entry->algo;
                   1001:                *plugin_name = entry->plugin_name;
                   1002:                return TRUE;
                   1003:        }
                   1004:        return FALSE;
                   1005: }
                   1006: 
                   1007: METHOD(crypto_factory_t, create_hasher_enumerator, enumerator_t*,
                   1008:        private_crypto_factory_t *this)
                   1009: {
                   1010:        return create_enumerator(this, this->hashers, hasher_filter);
                   1011: }
                   1012: 
                   1013: CALLBACK(prf_filter, bool,
                   1014:        void *n, enumerator_t *orig, va_list args)
                   1015: {
                   1016:        entry_t *entry;
                   1017:        pseudo_random_function_t *algo;
                   1018:        const char **plugin_name;
                   1019: 
                   1020:        VA_ARGS_VGET(args, algo, plugin_name);
                   1021: 
                   1022:        if (orig->enumerate(orig, &entry))
                   1023:        {
                   1024:                *algo = entry->algo;
                   1025:                *plugin_name = entry->plugin_name;
                   1026:                return TRUE;
                   1027:        }
                   1028:        return FALSE;
                   1029: }
                   1030: 
                   1031: METHOD(crypto_factory_t, create_prf_enumerator, enumerator_t*,
                   1032:        private_crypto_factory_t *this)
                   1033: {
                   1034:        return create_enumerator(this, this->prfs, prf_filter);
                   1035: }
                   1036: 
                   1037: CALLBACK(xof_filter, bool,
                   1038:        void *n, enumerator_t *orig, va_list args)
                   1039: {
                   1040:        entry_t *entry;
                   1041:        ext_out_function_t *algo;
                   1042:        const char **plugin_name;
                   1043: 
                   1044:        VA_ARGS_VGET(args, algo, plugin_name);
                   1045: 
                   1046:        if (orig->enumerate(orig, &entry))
                   1047:        {
                   1048:                *algo = entry->algo;
                   1049:                *plugin_name = entry->plugin_name;
                   1050:                return TRUE;
                   1051:        }
                   1052:        return FALSE;
                   1053: }
                   1054: 
                   1055: METHOD(crypto_factory_t, create_xof_enumerator, enumerator_t*,
                   1056:        private_crypto_factory_t *this)
                   1057: {
                   1058:        return create_enumerator(this, this->xofs, xof_filter);
                   1059: }
                   1060: 
                   1061: CALLBACK(drbg_filter, bool,
                   1062:        void *n, enumerator_t *orig, va_list args)
                   1063: {
                   1064:        entry_t *entry;
                   1065:        drbg_type_t *type;
                   1066:        const char **plugin_name;
                   1067: 
                   1068:        VA_ARGS_VGET(args, type, plugin_name);
                   1069: 
                   1070:        if (orig->enumerate(orig, &entry))
                   1071:        {
                   1072:                *type = entry->algo;
                   1073:                *plugin_name = entry->plugin_name;
                   1074:                return TRUE;
                   1075:        }
                   1076:        return FALSE;
                   1077: }
                   1078: 
                   1079: METHOD(crypto_factory_t, create_drbg_enumerator, enumerator_t*,
                   1080:        private_crypto_factory_t *this)
                   1081: {
                   1082:        return create_enumerator(this, this->drbgs, drbg_filter);
                   1083: }
                   1084: 
                   1085: CALLBACK(dh_filter, bool,
                   1086:        void *n, enumerator_t *orig, va_list args)
                   1087: {
                   1088:        entry_t *entry;
                   1089:        diffie_hellman_group_t *algo;
                   1090:        const char **plugin_name;
                   1091: 
                   1092:        VA_ARGS_VGET(args, algo, plugin_name);
                   1093: 
                   1094:        if (orig->enumerate(orig, &entry))
                   1095:        {
                   1096:                *algo = entry->algo;
                   1097:                *plugin_name = entry->plugin_name;
                   1098:                return TRUE;
                   1099:        }
                   1100:        return FALSE;
                   1101: }
                   1102: 
                   1103: METHOD(crypto_factory_t, create_dh_enumerator, enumerator_t*,
                   1104:        private_crypto_factory_t *this)
                   1105: {
                   1106:        return create_enumerator(this, this->dhs, dh_filter);
                   1107: }
                   1108: 
                   1109: CALLBACK(rng_filter, bool,
                   1110:        void *n, enumerator_t *orig, va_list args)
                   1111: {
                   1112:        entry_t *entry;
                   1113:        rng_quality_t *algo;
                   1114:        const char **plugin_name;
                   1115: 
                   1116:        VA_ARGS_VGET(args, algo, plugin_name);
                   1117: 
                   1118:        if (orig->enumerate(orig, &entry))
                   1119:        {
                   1120:                *algo = entry->algo;
                   1121:                *plugin_name = entry->plugin_name;
                   1122:                return TRUE;
                   1123:        }
                   1124:        return FALSE;
                   1125: }
                   1126: 
                   1127: METHOD(crypto_factory_t, create_rng_enumerator, enumerator_t*,
                   1128:        private_crypto_factory_t *this)
                   1129: {
                   1130:        return create_enumerator(this, this->rngs, rng_filter);
                   1131: }
                   1132: 
                   1133: CALLBACK(nonce_gen_filter, bool,
                   1134:        void *n, enumerator_t *orig, va_list args)
                   1135: {
                   1136:        entry_t *entry;
                   1137:        const char **plugin_name;
                   1138: 
                   1139:        VA_ARGS_VGET(args, plugin_name);
                   1140: 
                   1141:        if (orig->enumerate(orig, &entry))
                   1142:        {
                   1143:                *plugin_name = entry->plugin_name;
                   1144:                return TRUE;
                   1145:        }
                   1146:        return FALSE;
                   1147: }
                   1148: 
                   1149: METHOD(crypto_factory_t, create_nonce_gen_enumerator, enumerator_t*,
                   1150:        private_crypto_factory_t *this)
                   1151: {
                   1152:        return create_enumerator(this, this->nonce_gens, nonce_gen_filter);
                   1153: }
                   1154: 
                   1155: METHOD(crypto_factory_t, add_test_vector, void,
                   1156:        private_crypto_factory_t *this, transform_type_t type, void *vector)
                   1157: {
                   1158:        switch (type)
                   1159:        {
                   1160:                case ENCRYPTION_ALGORITHM:
                   1161:                        return this->tester->add_crypter_vector(this->tester, vector);
                   1162:                case AEAD_ALGORITHM:
                   1163:                        return this->tester->add_aead_vector(this->tester, vector);
                   1164:                case INTEGRITY_ALGORITHM:
                   1165:                        return this->tester->add_signer_vector(this->tester, vector);
                   1166:                case HASH_ALGORITHM:
                   1167:                        return this->tester->add_hasher_vector(this->tester, vector);
                   1168:                case PSEUDO_RANDOM_FUNCTION:
                   1169:                        return this->tester->add_prf_vector(this->tester, vector);
                   1170:                case EXTENDED_OUTPUT_FUNCTION:
                   1171:                        return this->tester->add_xof_vector(this->tester, vector);
                   1172:                case DETERMINISTIC_RANDOM_BIT_GENERATOR:
                   1173:                        return this->tester->add_drbg_vector(this->tester, vector);
                   1174:                case RANDOM_NUMBER_GENERATOR:
                   1175:                        return this->tester->add_rng_vector(this->tester, vector);
                   1176:                case DIFFIE_HELLMAN_GROUP:
                   1177:                        return this->tester->add_dh_vector(this->tester, vector);
                   1178:                default:
                   1179:                        DBG1(DBG_LIB, "%N test vectors not supported, ignored",
                   1180:                                 transform_type_names, type);
                   1181:        }
                   1182: }
                   1183: 
                   1184: /**
                   1185:  * Private enumerator for create_verify_enumerator()
                   1186:  */
                   1187: typedef struct {
                   1188:        enumerator_t public;
                   1189:        enumerator_t *inner;
                   1190:        transform_type_t type;
                   1191:        crypto_tester_t *tester;
                   1192:        rwlock_t *lock;
                   1193: } verify_enumerator_t;
                   1194: 
                   1195: METHOD(enumerator_t, verify_enumerate, bool,
                   1196:        verify_enumerator_t *this, va_list args)
                   1197: {
                   1198:        const char **plugin;
                   1199:        entry_t *entry;
                   1200:        u_int *alg;
                   1201:        bool *valid;
                   1202: 
                   1203:        VA_ARGS_VGET(args, alg, plugin, valid);
                   1204: 
                   1205:        if (!this->inner->enumerate(this->inner, &entry))
                   1206:        {
                   1207:                return FALSE;
                   1208:        }
                   1209:        switch (this->type)
                   1210:        {
                   1211:                case ENCRYPTION_ALGORITHM:
                   1212:                        *valid = this->tester->test_crypter(this->tester, entry->algo, 0,
                   1213:                                                        entry->create_crypter, NULL, entry->plugin_name);
                   1214:                        break;
                   1215:                case AEAD_ALGORITHM:
                   1216:                        *valid = this->tester->test_aead(this->tester, entry->algo, 0, 0,
                   1217:                                                        entry->create_aead, NULL, entry->plugin_name);
                   1218:                        break;
                   1219:                case INTEGRITY_ALGORITHM:
                   1220:                        *valid = this->tester->test_signer(this->tester, entry->algo,
                   1221:                                                        entry->create_signer, NULL, entry->plugin_name);
                   1222:                        break;
                   1223:                case HASH_ALGORITHM:
                   1224:                        *valid = this->tester->test_hasher(this->tester, entry->algo,
                   1225:                                                        entry->create_hasher, NULL, entry->plugin_name);
                   1226:                        break;
                   1227:                case PSEUDO_RANDOM_FUNCTION:
                   1228:                        *valid = this->tester->test_prf(this->tester, entry->algo,
                   1229:                                                        entry->create_prf, NULL, entry->plugin_name);
                   1230:                        break;
                   1231:                case EXTENDED_OUTPUT_FUNCTION:
                   1232:                        *valid = this->tester->test_xof(this->tester, entry->algo,
                   1233:                                                        entry->create_xof, NULL, entry->plugin_name);
                   1234:                        break;
                   1235:                case DETERMINISTIC_RANDOM_BIT_GENERATOR:
                   1236:                        *valid = this->tester->test_drbg(this->tester, entry->algo,
                   1237:                                                        entry->create_drbg, NULL, entry->plugin_name);
                   1238:                        break;
                   1239:                case RANDOM_NUMBER_GENERATOR:
                   1240:                        *valid = this->tester->test_rng(this->tester, entry->algo,
                   1241:                                                        entry->create_rng, NULL, entry->plugin_name);
                   1242:                        break;
                   1243:                case DIFFIE_HELLMAN_GROUP:
                   1244:                        *valid = this->tester->test_dh(this->tester, entry->algo,
                   1245:                                                        entry->create_dh, NULL, entry->plugin_name);
                   1246:                        break;
                   1247:                default:
                   1248:                        return FALSE;
                   1249:        }
                   1250:        *plugin = entry->plugin_name;
                   1251:        *alg = entry->algo;
                   1252:        return TRUE;
                   1253: }
                   1254: 
                   1255: METHOD(enumerator_t, verify_destroy, void,
                   1256:        verify_enumerator_t *this)
                   1257: {
                   1258:        this->inner->destroy(this->inner);
                   1259:        this->lock->unlock(this->lock);
                   1260:        free(this);
                   1261: }
                   1262: 
                   1263: METHOD(crypto_factory_t, create_verify_enumerator, enumerator_t*,
                   1264:        private_crypto_factory_t *this, transform_type_t type)
                   1265: {
                   1266:        verify_enumerator_t *enumerator;
                   1267:        enumerator_t *inner;
                   1268: 
                   1269:        this->lock->read_lock(this->lock);
                   1270:        switch (type)
                   1271:        {
                   1272:                case ENCRYPTION_ALGORITHM:
                   1273:                        inner = this->crypters->create_enumerator(this->crypters);
                   1274:                        break;
                   1275:                case AEAD_ALGORITHM:
                   1276:                        inner = this->aeads->create_enumerator(this->aeads);
                   1277:                        break;
                   1278:                case INTEGRITY_ALGORITHM:
                   1279:                        inner = this->signers->create_enumerator(this->signers);
                   1280:                        break;
                   1281:                case HASH_ALGORITHM:
                   1282:                        inner = this->hashers->create_enumerator(this->hashers);
                   1283:                        break;
                   1284:                case PSEUDO_RANDOM_FUNCTION:
                   1285:                        inner = this->prfs->create_enumerator(this->prfs);
                   1286:                        break;
                   1287:                case EXTENDED_OUTPUT_FUNCTION:
                   1288:                        inner = this->xofs->create_enumerator(this->xofs);
                   1289:                        break;
                   1290:                case DETERMINISTIC_RANDOM_BIT_GENERATOR:
                   1291:                        inner = this->drbgs->create_enumerator(this->drbgs);
                   1292:                        break;
                   1293:                case RANDOM_NUMBER_GENERATOR:
                   1294:                        inner = this->rngs->create_enumerator(this->rngs);
                   1295:                        break;
                   1296:                case DIFFIE_HELLMAN_GROUP:
                   1297:                        inner = this->dhs->create_enumerator(this->dhs);
                   1298:                        break;
                   1299:                default:
                   1300:                        this->lock->unlock(this->lock);
                   1301:                        return enumerator_create_empty();
                   1302:        }
                   1303:        INIT(enumerator,
                   1304:                .public = {
                   1305:                        .enumerate = enumerator_enumerate_default,
                   1306:                        .venumerate = _verify_enumerate,
                   1307:                        .destroy = _verify_destroy,
                   1308:                },
                   1309:                .inner = inner,
                   1310:                .type = type,
                   1311:                .tester = this->tester,
                   1312:                .lock = this->lock,
                   1313:        );
                   1314:        return &enumerator->public;
                   1315: }
                   1316: 
                   1317: METHOD(crypto_factory_t, destroy, void,
                   1318:        private_crypto_factory_t *this)
                   1319: {
                   1320:        this->crypters->destroy(this->crypters);
                   1321:        this->aeads->destroy(this->aeads);
                   1322:        this->signers->destroy(this->signers);
                   1323:        this->hashers->destroy(this->hashers);
                   1324:        this->prfs->destroy(this->prfs);
                   1325:        this->xofs->destroy(this->xofs);
                   1326:        this->drbgs->destroy(this->drbgs);
                   1327:        this->rngs->destroy(this->rngs);
                   1328:        this->nonce_gens->destroy(this->nonce_gens);
                   1329:        this->dhs->destroy(this->dhs);
                   1330:        this->tester->destroy(this->tester);
                   1331:        this->lock->destroy(this->lock);
                   1332:        free(this);
                   1333: }
                   1334: 
                   1335: /*
                   1336:  * see header file
                   1337:  */
                   1338: crypto_factory_t *crypto_factory_create()
                   1339: {
                   1340:        private_crypto_factory_t *this;
                   1341: 
                   1342:        INIT(this,
                   1343:                .public = {
                   1344:                        .create_crypter = _create_crypter,
                   1345:                        .create_aead = _create_aead,
                   1346:                        .create_signer = _create_signer,
                   1347:                        .create_hasher = _create_hasher,
                   1348:                        .create_prf = _create_prf,
                   1349:                        .create_xof = _create_xof,
                   1350:                        .create_drbg = _create_drbg,
                   1351:                        .create_rng = _create_rng,
                   1352:                        .create_nonce_gen = _create_nonce_gen,
                   1353:                        .create_dh = _create_dh,
                   1354:                        .add_crypter = _add_crypter,
                   1355:                        .remove_crypter = _remove_crypter,
                   1356:                        .add_aead = _add_aead,
                   1357:                        .remove_aead = _remove_aead,
                   1358:                        .add_signer = _add_signer,
                   1359:                        .remove_signer = _remove_signer,
                   1360:                        .add_hasher = _add_hasher,
                   1361:                        .remove_hasher = _remove_hasher,
                   1362:                        .add_prf = _add_prf,
                   1363:                        .remove_prf = _remove_prf,
                   1364:                        .add_xof = _add_xof,
                   1365:                        .remove_xof = _remove_xof,
                   1366:                        .add_drbg = _add_drbg,
                   1367:                        .remove_drbg = _remove_drbg,
                   1368:                        .add_rng = _add_rng,
                   1369:                        .remove_rng = _remove_rng,
                   1370:                        .add_nonce_gen = _add_nonce_gen,
                   1371:                        .remove_nonce_gen = _remove_nonce_gen,
                   1372:                        .add_dh = _add_dh,
                   1373:                        .remove_dh = _remove_dh,
                   1374:                        .create_crypter_enumerator = _create_crypter_enumerator,
                   1375:                        .create_aead_enumerator = _create_aead_enumerator,
                   1376:                        .create_signer_enumerator = _create_signer_enumerator,
                   1377:                        .create_hasher_enumerator = _create_hasher_enumerator,
                   1378:                        .create_prf_enumerator = _create_prf_enumerator,
                   1379:                        .create_xof_enumerator = _create_xof_enumerator,
                   1380:                        .create_drbg_enumerator = _create_drbg_enumerator,
                   1381:                        .create_dh_enumerator = _create_dh_enumerator,
                   1382:                        .create_rng_enumerator = _create_rng_enumerator,
                   1383:                        .create_nonce_gen_enumerator = _create_nonce_gen_enumerator,
                   1384:                        .add_test_vector = _add_test_vector,
                   1385:                        .create_verify_enumerator = _create_verify_enumerator,
                   1386:                        .destroy = _destroy,
                   1387:                },
                   1388:                .crypters = linked_list_create(),
                   1389:                .aeads = linked_list_create(),
                   1390:                .signers = linked_list_create(),
                   1391:                .hashers = linked_list_create(),
                   1392:                .prfs = linked_list_create(),
                   1393:                .xofs = linked_list_create(),
                   1394:                .drbgs = linked_list_create(),
                   1395:                .rngs = linked_list_create(),
                   1396:                .nonce_gens = linked_list_create(),
                   1397:                .dhs = linked_list_create(),
                   1398:                .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
                   1399:                .tester = crypto_tester_create(),
                   1400:                .test_on_add = lib->settings->get_bool(lib->settings,
                   1401:                                                                "%s.crypto_test.on_add", FALSE, lib->ns),
                   1402:                .test_on_create = lib->settings->get_bool(lib->settings,
                   1403:                                                                "%s.crypto_test.on_create", FALSE, lib->ns),
                   1404:                .bench = lib->settings->get_bool(lib->settings,
                   1405:                                                                "%s.crypto_test.bench", FALSE, lib->ns),
                   1406:        );
                   1407: 
                   1408:        return &this->public;
                   1409: }

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