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);
166 * Count the number of zerobits at the low end of A
169 get_trailing_zeros (mpz_t a)
171 unsigned int count = 0;
172 unsigned int nbits = get_nbits (a);
174 while ((mpz_tstbit (a, count)) && (count < nbits))
180 * Set bit N of A. and clear all bits above
183 set_highbit (mpz_t a, unsigned int n)
187 nbits = get_nbits (a);
189 mpz_clrbit (a, nbits--);
194 mpz_randomize (mpz_t n, unsigned int nbits, GNUNET_HashCode * rnd)
196 GNUNET_HashCode *tmp;
200 cnt = (nbits / sizeof (GNUNET_HashCode) / 8) + 1;
201 tmp = GNUNET_malloc (sizeof (GNUNET_HashCode) * cnt);
204 for (i = 0; i < cnt - 1; i++)
206 GNUNET_CRYPTO_hash (&tmp[i], sizeof (GNUNET_HashCode), &tmp[i + 1]);
209 mpz_import (n, cnt * sizeof (GNUNET_HashCode) / sizeof (unsigned int),
210 1, sizeof (unsigned int), 1, 0, tmp);
218 * Return true if n is probably a prime
221 is_prime (mpz_t n, int steps, GNUNET_HashCode * hc)
229 unsigned int i, j, k;
237 mpz_init_set_ui (a2, 2);
238 nbits = get_nbits (n);
239 mpz_sub_ui (nminus1, n, 1);
241 /* Find q and k, so that n = 1 + 2^k * q . */
242 mpz_init_set (q, nminus1);
243 k = get_trailing_zeros (q);
244 mpz_tdiv_q_2exp (q, q, k);
246 for (i = 0; i < steps; i++)
254 mpz_randomize (x, nbits, hc);
256 /* Make sure that the number is smaller than the prime and
257 keep the randomness of the high bit. */
258 if (mpz_tstbit (x, nbits - 2))
260 set_highbit (x, nbits - 2); /* Clear all higher bits. */
264 set_highbit (x, nbits - 2);
265 mpz_clrbit (x, nbits - 2);
267 GNUNET_assert (mpz_cmp (x, nminus1) < 0 && mpz_cmp_ui (x, 1) > 0);
269 mpz_powm (y, x, q, n);
270 if (mpz_cmp_ui (y, 1) && mpz_cmp (y, nminus1))
272 for (j = 1; j < k && mpz_cmp (y, nminus1); j++)
274 mpz_powm (y, y, a2, n);
275 if (!mpz_cmp_ui (y, 1))
276 goto leave; /* Not a prime. */
278 if (mpz_cmp (y, nminus1))
279 goto leave; /* Not a prime. */
282 rc = 1; /* May be a prime. */
296 gen_prime (mpz_t ptest, unsigned int nbits, GNUNET_HashCode * hc)
298 mpz_t prime, pminus1, val_2, val_3, result;
304 GNUNET_assert (nbits >= 16);
306 mods = GNUNET_malloc (no_of_small_prime_numbers * sizeof (*mods));
307 /* Make nbits fit into mpz_t implementation. */
308 mpz_init_set_ui (val_2, 2);
309 mpz_init_set_ui (val_3, 3);
316 /* generate a random number */
317 mpz_randomize (prime, nbits, hc);
318 /* Set high order bit to 1, set low order bit to 1. If we are
319 generating a secret prime we are most probably doing that
320 for RSA, to make sure that the modulus does have the
321 requested key size we set the 2 high order bits. */
322 set_highbit (prime, nbits - 1);
323 mpz_setbit (prime, nbits - 2);
324 mpz_setbit (prime, 0);
326 /* Calculate all remainders. */
328 for (i = 0; (x = small_prime_numbers[i]); i++)
329 mods[i] = mpz_fdiv_r_ui (tmp, prime, x);
331 /* Now try some primes starting with prime. */
332 for (step = 0; step < 20000; step += 2)
334 /* Check against all the small primes we have in mods. */
335 for (i = 0; (x = small_prime_numbers[i]); i++)
337 while (mods[i] + step >= x)
339 if (!(mods[i] + step))
343 continue; /* Found a multiple of an already known prime. */
345 mpz_add_ui (ptest, prime, step);
346 if (!mpz_tstbit (ptest, nbits - 2))
349 /* Do a fast Fermat test now. */
350 mpz_sub_ui (pminus1, ptest, 1);
351 mpz_powm (result, val_2, pminus1, ptest);
352 if ((!mpz_cmp_ui (result, 1)) && (is_prime (ptest, 5, hc)))
368 * Find the greatest common divisor G of A and B.
369 * Return: 1 if this 1, 0 in all other cases
372 test_gcd (mpz_t g, mpz_t xa, mpz_t xb)
376 mpz_init_set (a, xa);
377 mpz_init_set (b, xb);
379 /* TAOCP Vol II, 4.5.2, Algorithm A */
380 while (mpz_cmp_ui (b, 0))
382 mpz_fdiv_r (g, a, b); /* g used as temorary variable */
390 return (0 == mpz_cmp_ui (g, 1));
394 * Generate a key pair with a key of size NBITS.
395 * @param sk where to store the key
396 * @param nbits the number of bits to use
397 * @param hc the HC to use for PRNG (modified!)
400 generate_kblock_key (KBlock_secret_key * sk,
401 unsigned int nbits, GNUNET_HashCode * hc)
404 mpz_t phi; /* helper: (p-1)(q-1) */
408 /* make sure that nbits is even so that we generate p, q of equal size */
412 mpz_init_set_ui (sk->e, 257);
431 gen_prime (sk->p, nbits / 2, hc);
432 gen_prime (sk->q, nbits / 2, hc);
434 if (mpz_cmp (sk->p, sk->q) > 0) /* p shall be smaller than q (for calc of u) */
435 mpz_swap (sk->p, sk->q);
436 /* calculate the modulus */
437 mpz_mul (sk->n, sk->p, sk->q);
439 while (get_nbits (sk->n) != nbits);
441 /* calculate Euler totient: phi = (p-1)(q-1) */
442 mpz_sub_ui (t1, sk->p, 1);
443 mpz_sub_ui (t2, sk->q, 1);
444 mpz_mul (phi, t1, t2);
446 mpz_fdiv_q (f, phi, g);
448 while (0 == test_gcd (t1, sk->e, phi))
449 { /* (while gcd is not 1) */
450 mpz_add_ui (sk->e, sk->e, 2);
453 /* calculate the secret key d = e^1 mod phi */
455 while ((0 == mpz_invert (sk->d, sk->e, f)) ||
456 (0 == mpz_invert (sk->u, sk->p, sk->q)));
467 * Internal representation of the private key.
469 struct KskRsaPrivateKeyBinaryEncoded
472 * Total size of the structure, in bytes, in big-endian!
474 uint16_t len GNUNET_PACKED;
475 uint16_t sizen GNUNET_PACKED; /* in big-endian! */
476 uint16_t sizee GNUNET_PACKED; /* in big-endian! */
477 uint16_t sized GNUNET_PACKED; /* in big-endian! */
478 uint16_t sizep GNUNET_PACKED; /* in big-endian! */
479 uint16_t sizeq GNUNET_PACKED; /* in big-endian! */
480 uint16_t sizedmp1 GNUNET_PACKED; /* in big-endian! */
481 uint16_t sizedmq1 GNUNET_PACKED; /* in big-endian! */
482 /* followed by the actual values */
487 * Deterministically (!) create a hostkey using only the
488 * given HashCode as input to the PRNG.
490 static struct KskRsaPrivateKeyBinaryEncoded *
491 makeKblockKeyInternal (const GNUNET_HashCode * hc)
493 KBlock_secret_key sk;
498 struct KskRsaPrivateKeyBinaryEncoded *retval;
503 generate_kblock_key (&sk, 1024, /* at least 10x as fast than 2048 bits
504 -- we simply cannot afford 2048 bits
505 even on modern hardware, and especially
506 not since clearly a dictionary attack
507 will still be much cheaper
508 than breaking a 1024 bit RSA key.
509 If an adversary can spend the time to
510 break a 1024 bit RSA key just to forge
511 a signature -- SO BE IT. [ CG, 6/2005 ] */
519 size = sizeof (struct KskRsaPrivateKeyBinaryEncoded);
520 for (i = 0; i < 6; i++)
522 pbu[i] = mpz_export (NULL, &sizes[i], 1, /* most significant word first */
523 1, /* unit is bytes */
529 GNUNET_assert (size < 65536);
530 retval = GNUNET_malloc (size);
531 retval->len = htons (size);
533 retval->sizen = htons (sizes[0]);
534 memcpy (&((char *) &retval[1])[i], pbu[0], sizes[0]);
536 retval->sizee = htons (sizes[1]);
537 memcpy (&((char *) &retval[1])[i], pbu[1], sizes[1]);
539 retval->sized = htons (sizes[2]);
540 memcpy (&((char *) &retval[1])[i], pbu[2], sizes[2]);
543 retval->sizep = htons (sizes[4]);
544 memcpy (&((char *) &retval[1])[i], pbu[4], sizes[4]);
546 retval->sizeq = htons (sizes[3]);
547 memcpy (&((char *) &retval[1])[i], pbu[3], sizes[3]);
549 retval->sizedmp1 = htons (0);
550 retval->sizedmq1 = htons (0);
551 memcpy (&((char *) &retval[1])[i], pbu[5], sizes[5]);
552 for (i = 0; i < 6; i++)
562 * Decode the internal format into the format used
565 static struct GNUNET_CRYPTO_RsaPrivateKey *
566 ksk_decode_key (const struct KskRsaPrivateKeyBinaryEncoded *encoding)
568 struct GNUNET_CRYPTO_RsaPrivateKey *ret;
570 gcry_mpi_t n, e, d, p, q, u;
576 size = ntohs (encoding->sizen);
577 rc = gcry_mpi_scan (&n,
579 &((const unsigned char *) (&encoding[1]))[pos],
581 pos += ntohs (encoding->sizen);
584 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
587 size = ntohs (encoding->sizee);
588 rc = gcry_mpi_scan (&e,
590 &((const unsigned char *) (&encoding[1]))[pos],
592 pos += ntohs (encoding->sizee);
595 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
596 gcry_mpi_release (n);
599 size = ntohs (encoding->sized);
600 rc = gcry_mpi_scan (&d,
602 &((const unsigned char *) (&encoding[1]))[pos],
604 pos += ntohs (encoding->sized);
607 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
608 gcry_mpi_release (n);
609 gcry_mpi_release (e);
613 size = ntohs (encoding->sizep);
616 rc = gcry_mpi_scan (&q,
618 &((const unsigned char *) (&encoding[1]))[pos],
620 pos += ntohs (encoding->sizep);
623 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
624 gcry_mpi_release (n);
625 gcry_mpi_release (e);
626 gcry_mpi_release (d);
632 size = ntohs (encoding->sizeq);
635 rc = gcry_mpi_scan (&p,
637 &((const unsigned char *) (&encoding[1]))[pos],
639 pos += ntohs (encoding->sizeq);
642 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
643 gcry_mpi_release (n);
644 gcry_mpi_release (e);
645 gcry_mpi_release (d);
647 gcry_mpi_release (q);
653 pos += ntohs (encoding->sizedmp1);
654 pos += ntohs (encoding->sizedmq1);
656 ntohs (encoding->len) - sizeof (struct KskRsaPrivateKeyBinaryEncoded) -
660 rc = gcry_mpi_scan (&u,
662 &((const unsigned char *) (&encoding[1]))[pos],
666 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
667 gcry_mpi_release (n);
668 gcry_mpi_release (e);
669 gcry_mpi_release (d);
671 gcry_mpi_release (p);
673 gcry_mpi_release (q);
680 if ((p != NULL) && (q != NULL) && (u != NULL))
682 rc = gcry_sexp_build (&res, &size, /* erroff */
683 "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)(u %m)))",
688 if ((p != NULL) && (q != NULL))
690 rc = gcry_sexp_build (&res, &size, /* erroff */
691 "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)))",
696 rc = gcry_sexp_build (&res, &size, /* erroff */
697 "(private-key(rsa(n %m)(e %m)(d %m)))",
701 gcry_mpi_release (n);
702 gcry_mpi_release (e);
703 gcry_mpi_release (d);
705 gcry_mpi_release (p);
707 gcry_mpi_release (q);
709 gcry_mpi_release (u);
712 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
714 if (gcry_pk_testkey (res))
716 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
720 ret = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPrivateKey));
731 struct KskRsaPrivateKeyBinaryEncoded *pke;
732 } KBlockKeyCacheLine;
734 static KBlockKeyCacheLine **cache;
735 static unsigned int cacheSize;
738 * Deterministically (!) create a hostkey using only the
739 * given HashCode as input to the PRNG.
741 struct GNUNET_CRYPTO_RsaPrivateKey *
742 GNUNET_CRYPTO_rsa_key_create_from_hash (const GNUNET_HashCode * hc)
744 struct GNUNET_CRYPTO_RsaPrivateKey *ret;
745 KBlockKeyCacheLine *line;
748 for (i = 0; i < cacheSize; i++)
750 if (0 == memcmp (hc, &cache[i]->hc, sizeof (GNUNET_HashCode)))
752 ret = ksk_decode_key (cache[i]->pke);
757 line = GNUNET_malloc (sizeof (KBlockKeyCacheLine));
759 line->pke = makeKblockKeyInternal (hc);
760 GNUNET_array_grow (cache, cacheSize, cacheSize + 1);
761 cache[cacheSize - 1] = line;
762 return ksk_decode_key (line->pke);
767 * Process ID of the "find" process that we use for
770 static pid_t genproc;
773 * Function called by libgcrypt whenever we are
774 * blocked gathering entropy.
777 entropy_generator (void *cls,
778 const char *what, int printchar, int current, int total)
781 enum GNUNET_OS_ProcessStatusType type;
784 if (0 != strcmp (what, "need_entropy"))
786 if (current == total)
790 if (0 != PLIBC_KILL (genproc, SIGTERM))
791 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "kill");
792 GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (genproc));
799 ret = GNUNET_OS_process_status (genproc, &type, &code);
800 if (ret == GNUNET_NO)
801 return; /* still running */
802 if (ret == GNUNET_SYSERR)
807 if (0 != PLIBC_KILL (genproc, SIGTERM))
808 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "kill");
809 GNUNET_break (GNUNET_OK == GNUNET_OS_process_wait (genproc));
812 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
813 _("Starting `%s' process to generate entropy\n"), "find");
814 genproc = GNUNET_OS_start_process ("sh",
817 "exec find / -mount -type f -exec cp {} /dev/null \\; 2>/dev/null",
827 PLIBC_KILL (genproc, SIGKILL);
833 void __attribute__ ((constructor)) GNUNET_CRYPTO_ksk_init ()
835 gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
836 if (!gcry_check_version (GCRYPT_VERSION))
840 ("libgcrypt has not the expected version (version %s is required).\n"),
844 #ifdef gcry_fast_random_poll
845 gcry_fast_random_poll ();
847 gcry_set_progress_handler (&entropy_generator, NULL);
852 void __attribute__ ((destructor)) GNUNET_CRYPTO_ksk_fini ()
856 for (i = 0; i < cacheSize; i++)
858 GNUNET_free (cache[i]->pke);
859 GNUNET_free (cache[i]);
861 GNUNET_array_grow (cache, cacheSize, 0);
862 gcry_set_progress_handler (NULL, NULL);
865 /* end of kblockkey.c */