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