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