Coverage Report

Created: 2024-02-29 06:05

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