curly wars / auto-indentation
[oweals/gnunet.git] / src / util / crypto_ksk.c
1 /*
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)
5
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.
10
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.
15
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.
20
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
24      ordinary RSA keys!
25 */
26
27
28 /**
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
33  */
34
35 #include "platform.h"
36 #include "gnunet_common.h"
37 #include "gnunet_crypto_lib.h"
38 #include "gnunet_os_lib.h"
39 #include <gcrypt.h>
40 #include <limits.h>
41
42 #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
43
44 /**
45  * Log an error message at log-level 'level' that indicates
46  * a failure of the command 'cmd' with the message given
47  * by gcry_strerror(rc).
48  */
49 #define LOG_GCRY(level, cmd, rc) do { LOG(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, gcry_strerror(rc)); } while(0);
50
51
52 typedef struct
53 {
54   gcry_mpi_t n;                 /* public modulus */
55   gcry_mpi_t e;                 /* public exponent */
56   gcry_mpi_t d;                 /* exponent */
57   gcry_mpi_t p;                 /* prime  p. */
58   gcry_mpi_t q;                 /* prime  q. */
59   gcry_mpi_t u;                 /* inverse of p mod q. */
60 } KBlock_secret_key;
61
62 /**
63  * The private information of an RSA key pair.
64  * NOTE: this must match the definition in crypto_rsa.c
65  */
66 struct GNUNET_CRYPTO_RsaPrivateKey
67 {
68   gcry_sexp_t sexp;
69 };
70
71
72 static void
73 mpz_randomize (gcry_mpi_t n, unsigned int nbits, GNUNET_HashCode * rnd)
74 {
75   GNUNET_HashCode hc;
76   GNUNET_HashCode tmp;
77   int bits_per_hc = sizeof (GNUNET_HashCode) * 8;
78   int cnt;
79   int i;
80
81   GNUNET_assert (nbits > 0);
82   cnt = (nbits + bits_per_hc - 1) / bits_per_hc;
83   gcry_mpi_set_ui (n, 0);
84
85   tmp = *rnd;
86   for (i = 0; i < cnt; i++)
87   {
88     int j;
89
90     if (i > 0)
91       GNUNET_CRYPTO_hash (&hc, sizeof (GNUNET_HashCode), &tmp);
92     for (j = 0; j < sizeof (GNUNET_HashCode) / sizeof (uint32_t); j++)
93     {
94 #if HAVE_GCRY_MPI_LSHIFT
95       gcry_mpi_lshift (n, n, sizeof (uint32_t) * 8);
96 #else
97       gcry_mpi_mul_ui (n, n, 1 << (sizeof (uint32_t) * 4));
98       gcry_mpi_mul_ui (n, n, 1 << (sizeof (uint32_t) * 4));
99 #endif
100       gcry_mpi_add_ui (n, n, ntohl (((uint32_t *) & tmp)[j]));
101     }
102     hc = tmp;
103   }
104   GNUNET_CRYPTO_hash (&hc, sizeof (GNUNET_HashCode), rnd);
105   i = gcry_mpi_get_nbits (n);
106   while (i > nbits)
107     gcry_mpi_clear_bit (n, --i);
108 }
109
110 static unsigned long
111 mpz_trailing_zeroes (gcry_mpi_t n)
112 {
113   unsigned int idx, cnt;
114
115   cnt = gcry_mpi_get_nbits (n);
116   for (idx = 0; idx < cnt; idx++)
117   {
118     if (gcry_mpi_test_bit (n, idx) == 0)
119       return idx;
120   }
121
122   return ULONG_MAX;
123 }
124
125 static void
126 mpz_tdiv_q_2exp (gcry_mpi_t q, gcry_mpi_t n, unsigned int b)
127 {
128   gcry_mpi_t u, d;
129
130   u = gcry_mpi_set_ui (NULL, 1);
131   d = gcry_mpi_new (0);
132   gcry_mpi_mul_2exp (d, u, b);
133   gcry_mpi_div (q, NULL, n, d, 0);
134 }
135
136 /**
137  * Return true if n is probably a prime
138  */
139 static int
140 is_prime (gcry_mpi_t n, int steps, GNUNET_HashCode * hc)
141 {
142   gcry_mpi_t x;
143   gcry_mpi_t y;
144   gcry_mpi_t z;
145   gcry_mpi_t nminus1;
146   gcry_mpi_t a2;
147   gcry_mpi_t q;
148   unsigned int i, j, k;
149   int rc = 0;
150   unsigned int nbits;
151
152   x = gcry_mpi_new (0);
153   y = gcry_mpi_new (0);
154   z = gcry_mpi_new (0);
155   nminus1 = gcry_mpi_new (0);
156   a2 = gcry_mpi_set_ui (NULL, 2);
157
158   nbits = gcry_mpi_get_nbits (n);
159   gcry_mpi_sub_ui (nminus1, n, 1);
160
161   /* Find q and k, so that n = 1 + 2^k * q . */
162   q = gcry_mpi_set (NULL, nminus1);
163   k = mpz_trailing_zeroes (q);
164   mpz_tdiv_q_2exp (q, q, k);
165
166   for (i = 0; i < steps; i++)
167   {
168     if (!i)
169     {
170       gcry_mpi_set_ui (x, 2);
171     }
172     else
173     {
174       mpz_randomize (x, nbits - 1, hc);
175       GNUNET_assert (gcry_mpi_cmp (x, nminus1) < 0);
176       GNUNET_assert (gcry_mpi_cmp_ui (x, 1) > 0);
177     }
178     gcry_mpi_powm (y, x, q, n);
179     if (gcry_mpi_cmp_ui (y, 1) && gcry_mpi_cmp (y, nminus1))
180     {
181       for (j = 1; j < k && gcry_mpi_cmp (y, nminus1); j++)
182       {
183         gcry_mpi_powm (y, y, a2, n);
184         if (!gcry_mpi_cmp_ui (y, 1))
185           goto leave;           /* Not a prime. */
186       }
187       if (gcry_mpi_cmp (y, nminus1))
188         goto leave;             /* Not a prime. */
189     }
190   }
191   rc = 1;                       /* May be a prime. */
192
193 leave:
194   gcry_mpi_release (x);
195   gcry_mpi_release (y);
196   gcry_mpi_release (z);
197   gcry_mpi_release (nminus1);
198   gcry_mpi_release (q);
199   gcry_mpi_release (a2);
200
201   return rc;
202 }
203
204 /**
205  * If target != size, move target bytes to the
206  * end of the size-sized buffer and zero out the
207  * first target-size bytes.
208  */
209 static void
210 adjust (unsigned char *buf, size_t size, size_t target)
211 {
212   if (size < target)
213   {
214     memmove (&buf[target - size], buf, size);
215     memset (buf, 0, target - size);
216   }
217 }
218
219
220 static void
221 gen_prime (gcry_mpi_t * ptest, unsigned int nbits, GNUNET_HashCode * hc)
222 {
223   /* Note: 2 is not included because it can be tested more easily by
224    * looking at bit 0. The last entry in this list is marked by a zero */
225   static const uint16_t small_prime_numbers[] = {
226     3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
227     47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101,
228     103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
229     157, 163, 167, 173, 179, 181, 191, 193, 197, 199,
230     211, 223, 227, 229, 233, 239, 241, 251, 257, 263,
231     269, 271, 277, 281, 283, 293, 307, 311, 313, 317,
232     331, 337, 347, 349, 353, 359, 367, 373, 379, 383,
233     389, 397, 401, 409, 419, 421, 431, 433, 439, 443,
234     449, 457, 461, 463, 467, 479, 487, 491, 499, 503,
235     509, 521, 523, 541, 547, 557, 563, 569, 571, 577,
236     587, 593, 599, 601, 607, 613, 617, 619, 631, 641,
237     643, 647, 653, 659, 661, 673, 677, 683, 691, 701,
238     709, 719, 727, 733, 739, 743, 751, 757, 761, 769,
239     773, 787, 797, 809, 811, 821, 823, 827, 829, 839,
240     853, 857, 859, 863, 877, 881, 883, 887, 907, 911,
241     919, 929, 937, 941, 947, 953, 967, 971, 977, 983,
242     991, 997, 1009, 1013, 1019, 1021, 1031, 1033,
243     1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091,
244     1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
245     1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213,
246     1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277,
247     1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307,
248     1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399,
249     1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
250     1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493,
251     1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559,
252     1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609,
253     1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667,
254     1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733,
255     1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789,
256     1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871,
257     1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931,
258     1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997,
259     1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053,
260     2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111,
261     2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161,
262     2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243,
263     2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297,
264     2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357,
265     2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411,
266     2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473,
267     2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551,
268     2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633,
269     2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687,
270     2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729,
271     2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791,
272     2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851,
273     2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917,
274     2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999,
275     3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061,
276     3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137,
277     3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209,
278     3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271,
279     3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331,
280     3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391,
281     3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467,
282     3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533,
283     3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583,
284     3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643,
285     3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709,
286     3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779,
287     3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851,
288     3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917,
289     3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989,
290     4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049,
291     4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111,
292     4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177,
293     4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243,
294     4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297,
295     4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391,
296     4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457,
297     4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519,
298     4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597,
299     4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657,
300     4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729,
301     4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799,
302     4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889,
303     4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951,
304     4957, 4967, 4969, 4973, 4987, 4993, 4999,
305     0
306   };
307 #define DIM(v) (sizeof(v)/sizeof((v)[0]))
308   static int no_of_small_prime_numbers = DIM (small_prime_numbers) - 1;
309
310   gcry_mpi_t prime, pminus1, val_2, val_3, result;
311   unsigned int i;
312   unsigned int step;
313   unsigned int mods[no_of_small_prime_numbers];
314   gcry_mpi_t tmp;
315   gcry_mpi_t sp;
316
317   GNUNET_assert (nbits >= 16);
318
319   /* Make nbits fit into mpz_t implementation. */
320   val_2 = gcry_mpi_set_ui (NULL, 2);
321   val_3 = gcry_mpi_set_ui (NULL, 3);
322   prime = gcry_mpi_snew (0);
323   result = gcry_mpi_new (0);
324   pminus1 = gcry_mpi_new (0);
325   *ptest = gcry_mpi_new (0);
326   tmp = gcry_mpi_new (0);
327   sp = gcry_mpi_new (0);
328   while (1)
329   {
330     /* generate a random number */
331     mpz_randomize (prime, nbits, hc);
332     /* Set high order bit to 1, set low order bit to 1.  If we are
333      * generating a secret prime we are most probably doing that
334      * for RSA, to make sure that the modulus does have the
335      * requested key size we set the 2 high order bits. */
336     gcry_mpi_set_bit (prime, nbits - 1);
337     gcry_mpi_set_bit (prime, nbits - 2);
338     gcry_mpi_set_bit (prime, 0);
339
340     /* Calculate all remainders. */
341     for (i = 0; i < no_of_small_prime_numbers; i++)
342     {
343       size_t written;
344
345       gcry_mpi_set_ui (sp, small_prime_numbers[i]);
346       gcry_mpi_div (NULL, tmp, prime, sp, -1);
347       mods[i] = 0;
348       written = sizeof (unsigned int);
349       GNUNET_assert (0 ==
350                      gcry_mpi_print (GCRYMPI_FMT_USG,
351                                      (unsigned char *) &mods[i], written,
352                                      &written, tmp));
353       adjust ((unsigned char *) &mods[i], written, sizeof (unsigned int));
354       mods[i] = ntohl (mods[i]);
355     }
356     /* Now try some primes starting with prime. */
357     for (step = 0; step < 20000; step += 2)
358     {
359       /* Check against all the small primes we have in mods. */
360       for (i = 0; i < no_of_small_prime_numbers; i++)
361       {
362         uint16_t x = small_prime_numbers[i];
363
364         while (mods[i] + step >= x)
365           mods[i] -= x;
366         if (!(mods[i] + step))
367           break;
368       }
369       if (i < no_of_small_prime_numbers)
370         continue;               /* Found a multiple of an already known prime. */
371
372       gcry_mpi_add_ui (*ptest, prime, step);
373       if (!gcry_mpi_test_bit (*ptest, nbits - 2))
374         break;
375
376       /* Do a fast Fermat test now. */
377       gcry_mpi_sub_ui (pminus1, *ptest, 1);
378       gcry_mpi_powm (result, val_2, pminus1, *ptest);
379       if ((!gcry_mpi_cmp_ui (result, 1)) && (is_prime (*ptest, 5, hc)))
380       {
381         /* Got it. */
382         gcry_mpi_release (sp);
383         gcry_mpi_release (tmp);
384         gcry_mpi_release (val_2);
385         gcry_mpi_release (val_3);
386         gcry_mpi_release (result);
387         gcry_mpi_release (pminus1);
388         gcry_mpi_release (prime);
389         return;
390       }
391     }
392   }
393 }
394
395 /**
396  * Generate a key pair with a key of size NBITS.
397  * @param sk where to store the key
398  * @param nbits the number of bits to use
399  * @param hc the HC to use for PRNG (modified!)
400  */
401 static void
402 generate_kblock_key (KBlock_secret_key *sk, unsigned int nbits,
403                      GNUNET_HashCode * hc)
404 {
405   gcry_mpi_t t1, t2;
406   gcry_mpi_t phi;               /* helper: (p-1)(q-1) */
407   gcry_mpi_t g;
408   gcry_mpi_t f;
409
410   /* make sure that nbits is even so that we generate p, q of equal size */
411   if ((nbits & 1))
412     nbits++;
413
414   sk->e = gcry_mpi_set_ui (NULL, 257);
415   sk->n = gcry_mpi_new (0);
416   sk->p = gcry_mpi_new (0);
417   sk->q = gcry_mpi_new (0);
418   sk->d = gcry_mpi_new (0);
419   sk->u = gcry_mpi_new (0);
420
421   t1 = gcry_mpi_new (0);
422   t2 = gcry_mpi_new (0);
423   phi = gcry_mpi_new (0);
424   g = gcry_mpi_new (0);
425   f = gcry_mpi_new (0);
426
427   do
428   {
429     do
430     {
431       gcry_mpi_release (sk->p);
432       gcry_mpi_release (sk->q);
433       gen_prime (&sk->p, nbits / 2, hc);
434       gen_prime (&sk->q, nbits / 2, hc);
435
436       if (gcry_mpi_cmp (sk->p, sk->q) > 0)      /* p shall be smaller than q (for calc of u) */
437         gcry_mpi_swap (sk->p, sk->q);
438       /* calculate the modulus */
439       gcry_mpi_mul (sk->n, sk->p, sk->q);
440     }
441     while (gcry_mpi_get_nbits (sk->n) != nbits);
442
443     /* calculate Euler totient: phi = (p-1)(q-1) */
444     gcry_mpi_sub_ui (t1, sk->p, 1);
445     gcry_mpi_sub_ui (t2, sk->q, 1);
446     gcry_mpi_mul (phi, t1, t2);
447     gcry_mpi_gcd (g, t1, t2);
448     gcry_mpi_div (f, NULL, phi, g, 0);
449     while (0 == gcry_mpi_gcd (t1, sk->e, phi))
450     {                           /* (while gcd is not 1) */
451       gcry_mpi_add_ui (sk->e, sk->e, 2);
452     }
453
454     /* calculate the secret key d = e^1 mod phi */
455   }
456   while ((0 == gcry_mpi_invm (sk->d, sk->e, f)) ||
457          (0 == gcry_mpi_invm (sk->u, sk->p, sk->q)));
458
459   gcry_mpi_release (t1);
460   gcry_mpi_release (t2);
461   gcry_mpi_release (phi);
462   gcry_mpi_release (f);
463   gcry_mpi_release (g);
464 }
465
466
467 /**
468  * Internal representation of the private key.
469  */
470 struct KskRsaPrivateKeyBinaryEncoded
471 {
472   /**
473    * Total size of the structure, in bytes, in big-endian!
474    */
475   uint16_t len GNUNET_PACKED;
476   uint16_t sizen GNUNET_PACKED; /*  in big-endian! */
477   uint16_t sizee GNUNET_PACKED; /*  in big-endian! */
478   uint16_t sized GNUNET_PACKED; /*  in big-endian! */
479   uint16_t sizep GNUNET_PACKED; /*  in big-endian! */
480   uint16_t sizeq GNUNET_PACKED; /*  in big-endian! */
481   uint16_t sizedmp1 GNUNET_PACKED;      /*  in big-endian! */
482   uint16_t sizedmq1 GNUNET_PACKED;      /*  in big-endian! */
483   /* followed by the actual values */
484 };
485
486
487 /**
488  * Deterministically (!) create a hostkey using only the
489  * given HashCode as input to the PRNG.
490  */
491 static struct KskRsaPrivateKeyBinaryEncoded *
492 makeKblockKeyInternal (const GNUNET_HashCode * hc)
493 {
494   KBlock_secret_key sk;
495   GNUNET_HashCode hx;
496   unsigned char *pbu[6];
497   gcry_mpi_t *pkv[6];
498   size_t sizes[6];
499   struct KskRsaPrivateKeyBinaryEncoded *retval;
500   int i;
501   size_t size;
502
503   hx = *hc;
504   generate_kblock_key (&sk, 1024,       /* at least 10x as fast than 2048 bits
505                                          * -- we simply cannot afford 2048 bits
506                                          * even on modern hardware, and especially
507                                          * not since clearly a dictionary attack
508                                          * will still be much cheaper
509                                          * than breaking a 1024 bit RSA key.
510                                          * If an adversary can spend the time to
511                                          * break a 1024 bit RSA key just to forge
512                                          * a signature -- SO BE IT. [ CG, 6/2005 ] */
513                        &hx);
514   pkv[0] = &sk.n;
515   pkv[1] = &sk.e;
516   pkv[2] = &sk.d;
517   pkv[3] = &sk.p;
518   pkv[4] = &sk.q;
519   pkv[5] = &sk.u;
520   size = sizeof (struct KskRsaPrivateKeyBinaryEncoded);
521   for (i = 0; i < 6; i++)
522   {
523     gcry_mpi_aprint (GCRYMPI_FMT_STD, &pbu[i], &sizes[i], *pkv[i]);
524     size += sizes[i];
525   }
526   GNUNET_assert (size < 65536);
527   retval = GNUNET_malloc (size);
528   retval->len = htons (size);
529   i = 0;
530   retval->sizen = htons (sizes[0]);
531   memcpy (&((char *) &retval[1])[i], pbu[0], sizes[0]);
532   i += sizes[0];
533   retval->sizee = htons (sizes[1]);
534   memcpy (&((char *) &retval[1])[i], pbu[1], sizes[1]);
535   i += sizes[1];
536   retval->sized = htons (sizes[2]);
537   memcpy (&((char *) &retval[1])[i], pbu[2], sizes[2]);
538   i += sizes[2];
539   /* swap p and q! */
540   retval->sizep = htons (sizes[4]);
541   memcpy (&((char *) &retval[1])[i], pbu[4], sizes[4]);
542   i += sizes[4];
543   retval->sizeq = htons (sizes[3]);
544   memcpy (&((char *) &retval[1])[i], pbu[3], sizes[3]);
545   i += sizes[3];
546   retval->sizedmp1 = htons (0);
547   retval->sizedmq1 = htons (0);
548   memcpy (&((char *) &retval[1])[i], pbu[5], sizes[5]);
549   for (i = 0; i < 6; i++)
550   {
551     gcry_mpi_release (*pkv[i]);
552     free (pbu[i]);
553   }
554   return retval;
555 }
556
557
558 /**
559  * Decode the internal format into the format used
560  * by libgcrypt.
561  */
562 static struct GNUNET_CRYPTO_RsaPrivateKey *
563 ksk_decode_key (const struct KskRsaPrivateKeyBinaryEncoded *encoding)
564 {
565   struct GNUNET_CRYPTO_RsaPrivateKey *ret;
566   gcry_sexp_t res;
567   gcry_mpi_t n, e, d, p, q, u;
568   int rc;
569   size_t size;
570   int pos;
571
572   pos = 0;
573   size = ntohs (encoding->sizen);
574   rc = gcry_mpi_scan (&n, GCRYMPI_FMT_USG,
575                       &((const unsigned char *) (&encoding[1]))[pos], size,
576                       &size);
577   pos += ntohs (encoding->sizen);
578   if (rc)
579   {
580     LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
581     return NULL;
582   }
583   size = ntohs (encoding->sizee);
584   rc = gcry_mpi_scan (&e, GCRYMPI_FMT_USG,
585                       &((const unsigned char *) (&encoding[1]))[pos], size,
586                       &size);
587   pos += ntohs (encoding->sizee);
588   if (rc)
589   {
590     LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
591     gcry_mpi_release (n);
592     return NULL;
593   }
594   size = ntohs (encoding->sized);
595   rc = gcry_mpi_scan (&d, GCRYMPI_FMT_USG,
596                       &((const unsigned char *) (&encoding[1]))[pos], size,
597                       &size);
598   pos += ntohs (encoding->sized);
599   if (rc)
600   {
601     LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
602     gcry_mpi_release (n);
603     gcry_mpi_release (e);
604     return NULL;
605   }
606   /* swap p and q! */
607   size = ntohs (encoding->sizep);
608   if (size > 0)
609   {
610     rc = gcry_mpi_scan (&q, GCRYMPI_FMT_USG,
611                         &((const unsigned char *) (&encoding[1]))[pos], size,
612                         &size);
613     pos += ntohs (encoding->sizep);
614     if (rc)
615     {
616       LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
617       gcry_mpi_release (n);
618       gcry_mpi_release (e);
619       gcry_mpi_release (d);
620       return NULL;
621     }
622   }
623   else
624     q = NULL;
625   size = ntohs (encoding->sizeq);
626   if (size > 0)
627   {
628     rc = gcry_mpi_scan (&p, GCRYMPI_FMT_USG,
629                         &((const unsigned char *) (&encoding[1]))[pos], size,
630                         &size);
631     pos += ntohs (encoding->sizeq);
632     if (rc)
633     {
634       LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
635       gcry_mpi_release (n);
636       gcry_mpi_release (e);
637       gcry_mpi_release (d);
638       if (q != NULL)
639         gcry_mpi_release (q);
640       return NULL;
641     }
642   }
643   else
644     p = NULL;
645   pos += ntohs (encoding->sizedmp1);
646   pos += ntohs (encoding->sizedmq1);
647   size =
648       ntohs (encoding->len) - sizeof (struct KskRsaPrivateKeyBinaryEncoded) -
649       pos;
650   if (size > 0)
651   {
652     rc = gcry_mpi_scan (&u, GCRYMPI_FMT_USG,
653                         &((const unsigned char *) (&encoding[1]))[pos], size,
654                         &size);
655     if (rc)
656     {
657       LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
658       gcry_mpi_release (n);
659       gcry_mpi_release (e);
660       gcry_mpi_release (d);
661       if (p != NULL)
662         gcry_mpi_release (p);
663       if (q != NULL)
664         gcry_mpi_release (q);
665       return NULL;
666     }
667   }
668   else
669     u = NULL;
670
671   if ((p != NULL) && (q != NULL) && (u != NULL))
672   {
673     rc = gcry_sexp_build (&res, &size,  /* erroff */
674                           "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)(u %m)))",
675                           n, e, d, p, q, u);
676   }
677   else
678   {
679     if ((p != NULL) && (q != NULL))
680     {
681       rc = gcry_sexp_build (&res, &size,        /* erroff */
682                             "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)))",
683                             n, e, d, p, q);
684     }
685     else
686     {
687       rc = gcry_sexp_build (&res, &size,        /* erroff */
688                             "(private-key(rsa(n %m)(e %m)(d %m)))", n, e, d);
689     }
690   }
691   gcry_mpi_release (n);
692   gcry_mpi_release (e);
693   gcry_mpi_release (d);
694   if (p != NULL)
695     gcry_mpi_release (p);
696   if (q != NULL)
697     gcry_mpi_release (q);
698   if (u != NULL)
699     gcry_mpi_release (u);
700
701   if (rc)
702     LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
703 #if EXTRA_CHECKS
704   if (gcry_pk_testkey (res))
705   {
706     LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
707     return NULL;
708   }
709 #endif
710   ret = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPrivateKey));
711   ret->sexp = res;
712   return ret;
713 }
714
715
716 struct KBlockKeyCacheLine
717 {
718   GNUNET_HashCode hc;
719   struct KskRsaPrivateKeyBinaryEncoded *pke;
720 };
721
722 static struct KBlockKeyCacheLine **cache;
723
724 static unsigned int cacheSize;
725
726 /**
727  * Deterministically (!) create a hostkey using only the
728  * given HashCode as input to the PRNG.
729  */
730 struct GNUNET_CRYPTO_RsaPrivateKey *
731 GNUNET_CRYPTO_rsa_key_create_from_hash (const GNUNET_HashCode * hc)
732 {
733   struct GNUNET_CRYPTO_RsaPrivateKey *ret;
734   struct KBlockKeyCacheLine *line;
735   unsigned int i;
736
737   for (i = 0; i < cacheSize; i++)
738   {
739     if (0 == memcmp (hc, &cache[i]->hc, sizeof (GNUNET_HashCode)))
740     {
741       ret = ksk_decode_key (cache[i]->pke);
742       return ret;
743     }
744   }
745
746   line = GNUNET_malloc (sizeof (struct KBlockKeyCacheLine));
747   line->hc = *hc;
748   line->pke = makeKblockKeyInternal (hc);
749   GNUNET_array_grow (cache, cacheSize, cacheSize + 1);
750   cache[cacheSize - 1] = line;
751   return ksk_decode_key (line->pke);
752 }
753
754
755 void __attribute__ ((destructor)) GNUNET_CRYPTO_ksk_fini ()
756 {
757   unsigned int i;
758
759   for (i = 0; i < cacheSize; i++)
760   {
761     GNUNET_free (cache[i]->pke);
762     GNUNET_free (cache[i]);
763   }
764   GNUNET_array_grow (cache, cacheSize, 0);
765 }
766
767
768 /* end of crypto_ksk.c */