/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, ¤t)) |
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 | } |