2 This file is part of GNUnet.
3 Copyright (C) 1994, 1996, 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
4 Copyright (C) 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
6 GNUnet is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published
8 by the Free Software Foundation; either version 2, or (at your
9 option) any later version.
11 GNUnet is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNUnet; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
21 Note: This code is based on code from libgcrypt
22 The code was adapted for GNUnet to support RSA-key generation
23 based on weak, pseudo-random keys. Do NOT use to generate
29 * @file util/crypto_ksk.c
30 * @brief implementation of RSA-Key generation for KBlocks
31 * (do NOT use for pseudonyms or hostkeys!)
32 * @author Christian Grothoff
36 #include "gnunet_common.h"
37 #include "gnunet_crypto_lib.h"
38 #include "gnunet_os_lib.h"
43 * Log an error message at log-level 'level' that indicates
44 * a failure of the command 'cmd' with the message given
45 * by gcry_strerror(rc).
47 #define LOG_GCRY(level, cmd, rc) do { GNUNET_log(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, gcry_strerror(rc)); } while(0);
52 mpz_t n; /* public modulus */
53 mpz_t e; /* public exponent */
54 mpz_t d; /* exponent */
55 mpz_t p; /* prime p. */
56 mpz_t q; /* prime q. */
57 mpz_t u; /* inverse of p mod q. */
61 * The private information of an RSA key pair.
62 * NOTE: this must match the definition in crypto_rsa.c
64 struct GNUNET_CRYPTO_RsaPrivateKey
70 /* Note: 2 is not included because it can be tested more easily by
71 looking at bit 0. The last entry in this list is marked by a zero */
72 static uint16_t small_prime_numbers[] = {
73 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
74 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101,
75 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
76 157, 163, 167, 173, 179, 181, 191, 193, 197, 199,
77 211, 223, 227, 229, 233, 239, 241, 251, 257, 263,
78 269, 271, 277, 281, 283, 293, 307, 311, 313, 317,
79 331, 337, 347, 349, 353, 359, 367, 373, 379, 383,
80 389, 397, 401, 409, 419, 421, 431, 433, 439, 443,
81 449, 457, 461, 463, 467, 479, 487, 491, 499, 503,
82 509, 521, 523, 541, 547, 557, 563, 569, 571, 577,
83 587, 593, 599, 601, 607, 613, 617, 619, 631, 641,
84 643, 647, 653, 659, 661, 673, 677, 683, 691, 701,
85 709, 719, 727, 733, 739, 743, 751, 757, 761, 769,
86 773, 787, 797, 809, 811, 821, 823, 827, 829, 839,
87 853, 857, 859, 863, 877, 881, 883, 887, 907, 911,
88 919, 929, 937, 941, 947, 953, 967, 971, 977, 983,
89 991, 997, 1009, 1013, 1019, 1021, 1031, 1033,
90 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091,
91 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
92 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213,
93 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277,
94 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307,
95 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399,
96 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
97 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493,
98 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559,
99 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609,
100 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667,
101 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733,
102 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789,
103 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871,
104 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931,
105 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997,
106 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053,
107 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111,
108 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161,
109 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243,
110 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297,
111 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357,
112 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411,
113 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473,
114 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551,
115 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633,
116 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687,
117 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729,
118 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791,
119 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851,
120 2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917,
121 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999,
122 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061,
123 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137,
124 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209,
125 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271,
126 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331,
127 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391,
128 3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467,
129 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533,
130 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583,
131 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643,
132 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709,
133 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779,
134 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851,
135 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917,
136 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989,
137 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049,
138 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111,
139 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177,
140 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243,
141 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297,
142 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391,
143 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457,
144 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519,
145 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597,
146 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657,
147 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729,
148 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799,
149 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889,
150 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951,
151 4957, 4967, 4969, 4973, 4987, 4993, 4999,
155 #define DIM(v) (sizeof(v)/sizeof((v)[0]))
156 static int no_of_small_prime_numbers = DIM (small_prime_numbers) - 1;
162 return mpz_sizeinbase (a, 2);
167 mpz_randomize (mpz_t n, unsigned int nbits, GNUNET_HashCode * rnd)
169 GNUNET_HashCode *tmp;
170 int bits_per_hc = sizeof (GNUNET_HashCode) * 8;
174 GNUNET_assert (nbits > 0);
175 cnt = (nbits + bits_per_hc - 1) / bits_per_hc;
176 tmp = GNUNET_malloc (sizeof (GNUNET_HashCode) * cnt);
179 for (i = 0; i < cnt - 1; i++)
181 GNUNET_CRYPTO_hash (&tmp[i], sizeof (GNUNET_HashCode), &tmp[i + 1]);
183 GNUNET_CRYPTO_hash (&tmp[i], sizeof (GNUNET_HashCode), rnd);
184 mpz_import (n, cnt * sizeof (GNUNET_HashCode) / sizeof (unsigned int),
185 1, sizeof (unsigned int), 1, 0, tmp);
193 * Return true if n is probably a prime
196 is_prime (mpz_t n, int steps, GNUNET_HashCode * hc)
204 unsigned int i, j, k;
212 mpz_init_set_ui (a2, 2);
213 nbits = get_nbits (n);
214 mpz_sub_ui (nminus1, n, 1);
216 /* Find q and k, so that n = 1 + 2^k * q . */
217 mpz_init_set (q, nminus1);
218 k = mpz_scan1 (q, 0);
219 mpz_tdiv_q_2exp (q, q, k);
221 for (i = 0; i < steps; i++)
229 mpz_randomize (x, nbits - 1, hc);
230 GNUNET_assert (mpz_cmp (x, nminus1) < 0 && mpz_cmp_ui (x, 1) > 0);
232 mpz_powm (y, x, q, n);
233 if (mpz_cmp_ui (y, 1) && mpz_cmp (y, nminus1))
235 for (j = 1; j < k && mpz_cmp (y, nminus1); j++)
237 mpz_powm (y, y, a2, n);
238 if (!mpz_cmp_ui (y, 1))
239 goto leave; /* Not a prime. */
241 if (mpz_cmp (y, nminus1))
242 goto leave; /* Not a prime. */
245 rc = 1; /* May be a prime. */
259 gen_prime (mpz_t ptest, unsigned int nbits, GNUNET_HashCode * hc)
261 mpz_t prime, pminus1, val_2, val_3, result;
267 GNUNET_assert (nbits >= 16);
269 mods = GNUNET_malloc (no_of_small_prime_numbers * sizeof (*mods));
270 /* Make nbits fit into mpz_t implementation. */
271 mpz_init_set_ui (val_2, 2);
272 mpz_init_set_ui (val_3, 3);
279 /* generate a random number */
280 mpz_randomize (prime, nbits, hc);
281 /* Set high order bit to 1, set low order bit to 1. If we are
282 generating a secret prime we are most probably doing that
283 for RSA, to make sure that the modulus does have the
284 requested key size we set the 2 high order bits. */
285 mpz_setbit (prime, nbits - 1);
286 mpz_setbit (prime, nbits - 2);
287 mpz_setbit (prime, 0);
289 /* Calculate all remainders. */
291 for (i = 0; (x = small_prime_numbers[i]); i++)
292 mods[i] = mpz_fdiv_r_ui (tmp, prime, x);
294 /* Now try some primes starting with prime. */
295 for (step = 0; step < 20000; step += 2)
297 /* Check against all the small primes we have in mods. */
298 for (i = 0; (x = small_prime_numbers[i]); i++)
300 while (mods[i] + step >= x)
302 if (!(mods[i] + step))
306 continue; /* Found a multiple of an already known prime. */
308 mpz_add_ui (ptest, prime, step);
309 if (!mpz_tstbit (ptest, nbits - 2))
312 /* Do a fast Fermat test now. */
313 mpz_sub_ui (pminus1, ptest, 1);
314 mpz_powm (result, val_2, pminus1, ptest);
315 if ((!mpz_cmp_ui (result, 1)) && (is_prime (ptest, 5, hc)))
331 * Find the greatest common divisor G of A and B.
332 * Return: 1 if this 1, 0 in all other cases
335 test_gcd (mpz_t g, mpz_t xa, mpz_t xb)
339 mpz_init_set (a, xa);
340 mpz_init_set (b, xb);
342 /* TAOCP Vol II, 4.5.2, Algorithm A */
343 while (mpz_cmp_ui (b, 0))
345 mpz_fdiv_r (g, a, b); /* g used as temorary variable */
353 return (0 == mpz_cmp_ui (g, 1));
357 * Generate a key pair with a key of size NBITS.
358 * @param sk where to store the key
359 * @param nbits the number of bits to use
360 * @param hc the HC to use for PRNG (modified!)
363 generate_kblock_key (KBlock_secret_key * sk,
364 unsigned int nbits, GNUNET_HashCode * hc)
367 mpz_t phi; /* helper: (p-1)(q-1) */
371 /* make sure that nbits is even so that we generate p, q of equal size */
375 mpz_init_set_ui (sk->e, 257);
394 gen_prime (sk->p, nbits / 2, hc);
395 gen_prime (sk->q, nbits / 2, hc);
397 if (mpz_cmp (sk->p, sk->q) > 0) /* p shall be smaller than q (for calc of u) */
398 mpz_swap (sk->p, sk->q);
399 /* calculate the modulus */
400 mpz_mul (sk->n, sk->p, sk->q);
402 while (get_nbits (sk->n) != nbits);
404 /* calculate Euler totient: phi = (p-1)(q-1) */
405 mpz_sub_ui (t1, sk->p, 1);
406 mpz_sub_ui (t2, sk->q, 1);
407 mpz_mul (phi, t1, t2);
409 mpz_fdiv_q (f, phi, g);
411 while (0 == test_gcd (t1, sk->e, phi))
412 { /* (while gcd is not 1) */
413 mpz_add_ui (sk->e, sk->e, 2);
416 /* calculate the secret key d = e^1 mod phi */
418 while ((0 == mpz_invert (sk->d, sk->e, f)) ||
419 (0 == mpz_invert (sk->u, sk->p, sk->q)));
430 * Internal representation of the private key.
432 struct KskRsaPrivateKeyBinaryEncoded
435 * Total size of the structure, in bytes, in big-endian!
437 uint16_t len GNUNET_PACKED;
438 uint16_t sizen GNUNET_PACKED; /* in big-endian! */
439 uint16_t sizee GNUNET_PACKED; /* in big-endian! */
440 uint16_t sized GNUNET_PACKED; /* in big-endian! */
441 uint16_t sizep GNUNET_PACKED; /* in big-endian! */
442 uint16_t sizeq GNUNET_PACKED; /* in big-endian! */
443 uint16_t sizedmp1 GNUNET_PACKED; /* in big-endian! */
444 uint16_t sizedmq1 GNUNET_PACKED; /* in big-endian! */
445 /* followed by the actual values */
450 * Deterministically (!) create a hostkey using only the
451 * given HashCode as input to the PRNG.
453 static struct KskRsaPrivateKeyBinaryEncoded *
454 makeKblockKeyInternal (const GNUNET_HashCode * hc)
456 KBlock_secret_key sk;
461 struct KskRsaPrivateKeyBinaryEncoded *retval;
466 generate_kblock_key (&sk, 1024, /* at least 10x as fast than 2048 bits
467 -- we simply cannot afford 2048 bits
468 even on modern hardware, and especially
469 not since clearly a dictionary attack
470 will still be much cheaper
471 than breaking a 1024 bit RSA key.
472 If an adversary can spend the time to
473 break a 1024 bit RSA key just to forge
474 a signature -- SO BE IT. [ CG, 6/2005 ] */
482 size = sizeof (struct KskRsaPrivateKeyBinaryEncoded);
483 for (i = 0; i < 6; i++)
485 pbu[i] = mpz_export (NULL, &sizes[i], 1, /* most significant word first */
486 1, /* unit is bytes */
492 GNUNET_assert (size < 65536);
493 retval = GNUNET_malloc (size);
494 retval->len = htons (size);
496 retval->sizen = htons (sizes[0]);
497 memcpy (&((char *) &retval[1])[i], pbu[0], sizes[0]);
499 retval->sizee = htons (sizes[1]);
500 memcpy (&((char *) &retval[1])[i], pbu[1], sizes[1]);
502 retval->sized = htons (sizes[2]);
503 memcpy (&((char *) &retval[1])[i], pbu[2], sizes[2]);
506 retval->sizep = htons (sizes[4]);
507 memcpy (&((char *) &retval[1])[i], pbu[4], sizes[4]);
509 retval->sizeq = htons (sizes[3]);
510 memcpy (&((char *) &retval[1])[i], pbu[3], sizes[3]);
512 retval->sizedmp1 = htons (0);
513 retval->sizedmq1 = htons (0);
514 memcpy (&((char *) &retval[1])[i], pbu[5], sizes[5]);
515 for (i = 0; i < 6; i++)
525 * Decode the internal format into the format used
528 static struct GNUNET_CRYPTO_RsaPrivateKey *
529 ksk_decode_key (const struct KskRsaPrivateKeyBinaryEncoded *encoding)
531 struct GNUNET_CRYPTO_RsaPrivateKey *ret;
533 gcry_mpi_t n, e, d, p, q, u;
539 size = ntohs (encoding->sizen);
540 rc = gcry_mpi_scan (&n,
542 &((const unsigned char *) (&encoding[1]))[pos],
544 pos += ntohs (encoding->sizen);
547 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
550 size = ntohs (encoding->sizee);
551 rc = gcry_mpi_scan (&e,
553 &((const unsigned char *) (&encoding[1]))[pos],
555 pos += ntohs (encoding->sizee);
558 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
559 gcry_mpi_release (n);
562 size = ntohs (encoding->sized);
563 rc = gcry_mpi_scan (&d,
565 &((const unsigned char *) (&encoding[1]))[pos],
567 pos += ntohs (encoding->sized);
570 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
571 gcry_mpi_release (n);
572 gcry_mpi_release (e);
576 size = ntohs (encoding->sizep);
579 rc = gcry_mpi_scan (&q,
581 &((const unsigned char *) (&encoding[1]))[pos],
583 pos += ntohs (encoding->sizep);
586 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
587 gcry_mpi_release (n);
588 gcry_mpi_release (e);
589 gcry_mpi_release (d);
595 size = ntohs (encoding->sizeq);
598 rc = gcry_mpi_scan (&p,
600 &((const unsigned char *) (&encoding[1]))[pos],
602 pos += ntohs (encoding->sizeq);
605 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
606 gcry_mpi_release (n);
607 gcry_mpi_release (e);
608 gcry_mpi_release (d);
610 gcry_mpi_release (q);
616 pos += ntohs (encoding->sizedmp1);
617 pos += ntohs (encoding->sizedmq1);
619 ntohs (encoding->len) - sizeof (struct KskRsaPrivateKeyBinaryEncoded) -
623 rc = gcry_mpi_scan (&u,
625 &((const unsigned char *) (&encoding[1]))[pos],
629 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
630 gcry_mpi_release (n);
631 gcry_mpi_release (e);
632 gcry_mpi_release (d);
634 gcry_mpi_release (p);
636 gcry_mpi_release (q);
643 if ((p != NULL) && (q != NULL) && (u != NULL))
645 rc = gcry_sexp_build (&res, &size, /* erroff */
646 "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)(u %m)))",
651 if ((p != NULL) && (q != NULL))
653 rc = gcry_sexp_build (&res, &size, /* erroff */
654 "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)))",
659 rc = gcry_sexp_build (&res, &size, /* erroff */
660 "(private-key(rsa(n %m)(e %m)(d %m)))",
664 gcry_mpi_release (n);
665 gcry_mpi_release (e);
666 gcry_mpi_release (d);
668 gcry_mpi_release (p);
670 gcry_mpi_release (q);
672 gcry_mpi_release (u);
675 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
677 if (gcry_pk_testkey (res))
679 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
683 ret = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPrivateKey));
694 struct KskRsaPrivateKeyBinaryEncoded *pke;
695 } KBlockKeyCacheLine;
697 static KBlockKeyCacheLine **cache;
698 static unsigned int cacheSize;
701 * Deterministically (!) create a hostkey using only the
702 * given HashCode as input to the PRNG.
704 struct GNUNET_CRYPTO_RsaPrivateKey *
705 GNUNET_CRYPTO_rsa_key_create_from_hash (const GNUNET_HashCode * hc)
707 struct GNUNET_CRYPTO_RsaPrivateKey *ret;
708 KBlockKeyCacheLine *line;
711 for (i = 0; i < cacheSize; i++)
713 if (0 == memcmp (hc, &cache[i]->hc, sizeof (GNUNET_HashCode)))
715 ret = ksk_decode_key (cache[i]->pke);
720 line = GNUNET_malloc (sizeof (KBlockKeyCacheLine));
722 line->pke = makeKblockKeyInternal (hc);
723 GNUNET_array_grow (cache, cacheSize, cacheSize + 1);
724 cache[cacheSize - 1] = line;
725 return ksk_decode_key (line->pke);
730 * Process ID of the "find" process that we use for
733 static pid_t genproc;
736 * Function called by libgcrypt whenever we are
737 * blocked gathering entropy.
740 entropy_generator (void *cls,
741 const char *what, int printchar, int current, int total)
744 enum GNUNET_OS_ProcessStatusType type;
747 if (0 != strcmp (what, "need_entropy"))
749 if (current == total)
753 if (0 != PLIBC_KILL (genproc, SIGTERM))
754 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "kill");
755 GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (genproc));
762 ret = GNUNET_OS_process_status (genproc, &type, &code);
763 if (ret == GNUNET_NO)
764 return; /* still running */
765 if (ret == GNUNET_SYSERR)
770 if (0 != PLIBC_KILL (genproc, SIGTERM))
771 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "kill");
772 GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (genproc));
775 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
776 _("Starting `%s' process to generate entropy\n"), "find");
777 genproc = GNUNET_OS_start_process (NULL, NULL, "sh",
780 "exec find / -mount -type f -exec cp {} /dev/null \\; 2>/dev/null",
790 PLIBC_KILL (genproc, SIGKILL);
796 void __attribute__ ((constructor)) GNUNET_CRYPTO_ksk_init ()
798 gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
799 if (!gcry_check_version (GCRYPT_VERSION))
803 ("libgcrypt has not the expected version (version %s is required).\n"),
807 #ifdef gcry_fast_random_poll
808 gcry_fast_random_poll ();
810 gcry_set_progress_handler (&entropy_generator, NULL);
815 void __attribute__ ((destructor)) GNUNET_CRYPTO_ksk_fini ()
819 for (i = 0; i < cacheSize; i++)
821 GNUNET_free (cache[i]->pke);
822 GNUNET_free (cache[i]);
824 GNUNET_array_grow (cache, cacheSize, 0);
825 gcry_set_progress_handler (NULL, NULL);
828 /* end of kblockkey.c */