static void
-mpz_randomize (gcry_mpi_t n, unsigned int nbits, GNUNET_HashCode * rnd)
+mpz_randomize (gcry_mpi_t n, unsigned int nbits, struct GNUNET_HashCode * rnd)
{
- GNUNET_HashCode hc;
- GNUNET_HashCode tmp;
- int bits_per_hc = sizeof (GNUNET_HashCode) * 8;
+ struct GNUNET_HashCode hc;
+ struct GNUNET_HashCode tmp;
+ int bits_per_hc = sizeof (struct GNUNET_HashCode) * 8;
int cnt;
int i;
int j;
if (i > 0)
- GNUNET_CRYPTO_hash (&hc, sizeof (GNUNET_HashCode), &tmp);
- for (j = 0; j < sizeof (GNUNET_HashCode) / sizeof (uint32_t); j++)
+ GNUNET_CRYPTO_hash (&hc, sizeof (struct GNUNET_HashCode), &tmp);
+ for (j = 0; j < sizeof (struct GNUNET_HashCode) / sizeof (uint32_t); j++)
{
#if HAVE_GCRY_MPI_LSHIFT
gcry_mpi_lshift (n, n, sizeof (uint32_t) * 8);
}
hc = tmp;
}
- GNUNET_CRYPTO_hash (&hc, sizeof (GNUNET_HashCode), rnd);
+ GNUNET_CRYPTO_hash (&hc, sizeof (struct GNUNET_HashCode), rnd);
i = gcry_mpi_get_nbits (n);
while (i > nbits)
gcry_mpi_clear_bit (n, --i);
* Return true if n is probably a prime
*/
static int
-is_prime (gcry_mpi_t n, int steps, GNUNET_HashCode * hc)
+is_prime (gcry_mpi_t n, int steps, struct GNUNET_HashCode * hc)
{
gcry_mpi_t x;
gcry_mpi_t y;
static void
-gen_prime (gcry_mpi_t * ptest, unsigned int nbits, GNUNET_HashCode * hc)
+gen_prime (gcry_mpi_t * ptest, unsigned int nbits, struct GNUNET_HashCode * hc)
{
/* Note: 2 is not included because it can be tested more easily by
* looking at bit 0. The last entry in this list is marked by a zero */
*/
static void
generate_kblock_key (KBlock_secret_key *sk, unsigned int nbits,
- GNUNET_HashCode * hc)
+ struct GNUNET_HashCode * hc)
{
gcry_mpi_t t1, t2;
gcry_mpi_t phi; /* helper: (p-1)(q-1) */
gcry_mpi_release (g);
}
+GNUNET_NETWORK_STRUCT_BEGIN
/**
* Internal representation of the private key.
uint16_t sizedmq1 GNUNET_PACKED; /* in big-endian! */
/* followed by the actual values */
};
-
+GNUNET_NETWORK_STRUCT_END
/**
* Deterministically (!) create a hostkey using only the
* given HashCode as input to the PRNG.
*/
static struct KskRsaPrivateKeyBinaryEncoded *
-makeKblockKeyInternal (const GNUNET_HashCode * hc)
+makeKblockKeyInternal (const struct GNUNET_HashCode * hc)
{
KBlock_secret_key sk;
- GNUNET_HashCode hx;
+ struct GNUNET_HashCode hx;
unsigned char *pbu[6];
gcry_mpi_t *pkv[6];
size_t sizes[6];
/**
- * Decode the internal format into the format used
- * by libgcrypt.
+ * Entry in the KSK cache.
*/
-static struct GNUNET_CRYPTO_RsaPrivateKey *
-ksk_decode_key (const struct KskRsaPrivateKeyBinaryEncoded *encoding)
-{
- struct GNUNET_CRYPTO_RsaPrivateKey *ret;
- gcry_sexp_t res;
- gcry_mpi_t n, e, d, p, q, u;
- int rc;
- size_t size;
- int pos;
-
- pos = 0;
- size = ntohs (encoding->sizen);
- rc = gcry_mpi_scan (&n, GCRYMPI_FMT_USG,
- &((const unsigned char *) (&encoding[1]))[pos], size,
- &size);
- pos += ntohs (encoding->sizen);
- if (rc)
- {
- LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
- return NULL;
- }
- size = ntohs (encoding->sizee);
- rc = gcry_mpi_scan (&e, GCRYMPI_FMT_USG,
- &((const unsigned char *) (&encoding[1]))[pos], size,
- &size);
- pos += ntohs (encoding->sizee);
- if (rc)
- {
- LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
- gcry_mpi_release (n);
- return NULL;
- }
- size = ntohs (encoding->sized);
- rc = gcry_mpi_scan (&d, GCRYMPI_FMT_USG,
- &((const unsigned char *) (&encoding[1]))[pos], size,
- &size);
- pos += ntohs (encoding->sized);
- if (rc)
- {
- LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
- gcry_mpi_release (n);
- gcry_mpi_release (e);
- return NULL;
- }
- /* swap p and q! */
- size = ntohs (encoding->sizep);
- if (size > 0)
- {
- rc = gcry_mpi_scan (&q, GCRYMPI_FMT_USG,
- &((const unsigned char *) (&encoding[1]))[pos], size,
- &size);
- pos += ntohs (encoding->sizep);
- if (rc)
- {
- LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
- gcry_mpi_release (n);
- gcry_mpi_release (e);
- gcry_mpi_release (d);
- return NULL;
- }
- }
- else
- q = NULL;
- size = ntohs (encoding->sizeq);
- if (size > 0)
- {
- rc = gcry_mpi_scan (&p, GCRYMPI_FMT_USG,
- &((const unsigned char *) (&encoding[1]))[pos], size,
- &size);
- pos += ntohs (encoding->sizeq);
- if (rc)
- {
- LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
- gcry_mpi_release (n);
- gcry_mpi_release (e);
- gcry_mpi_release (d);
- if (q != NULL)
- gcry_mpi_release (q);
- return NULL;
- }
- }
- else
- p = NULL;
- pos += ntohs (encoding->sizedmp1);
- pos += ntohs (encoding->sizedmq1);
- size =
- ntohs (encoding->len) - sizeof (struct KskRsaPrivateKeyBinaryEncoded) -
- pos;
- if (size > 0)
- {
- rc = gcry_mpi_scan (&u, GCRYMPI_FMT_USG,
- &((const unsigned char *) (&encoding[1]))[pos], size,
- &size);
- if (rc)
- {
- LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
- gcry_mpi_release (n);
- gcry_mpi_release (e);
- gcry_mpi_release (d);
- if (p != NULL)
- gcry_mpi_release (p);
- if (q != NULL)
- gcry_mpi_release (q);
- return NULL;
- }
- }
- else
- u = NULL;
-
- if ((p != NULL) && (q != NULL) && (u != NULL))
- {
- rc = gcry_sexp_build (&res, &size, /* erroff */
- "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)(u %m)))",
- n, e, d, p, q, u);
- }
- else
- {
- if ((p != NULL) && (q != NULL))
- {
- rc = gcry_sexp_build (&res, &size, /* erroff */
- "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)))",
- n, e, d, p, q);
- }
- else
- {
- rc = gcry_sexp_build (&res, &size, /* erroff */
- "(private-key(rsa(n %m)(e %m)(d %m)))", n, e, d);
- }
- }
- gcry_mpi_release (n);
- gcry_mpi_release (e);
- gcry_mpi_release (d);
- if (p != NULL)
- gcry_mpi_release (p);
- if (q != NULL)
- gcry_mpi_release (q);
- if (u != NULL)
- gcry_mpi_release (u);
-
- if (rc)
- LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
-#if EXTRA_CHECKS
- if (gcry_pk_testkey (res))
- {
- LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
- return NULL;
- }
-#endif
- ret = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPrivateKey));
- ret->sexp = res;
- return ret;
-}
-
-
struct KBlockKeyCacheLine
{
- GNUNET_HashCode hc;
+ /**
+ * Hash from which the key was generated.
+ */
+ struct GNUNET_HashCode hc;
+
+ /**
+ * The encoded key.
+ */
struct KskRsaPrivateKeyBinaryEncoded *pke;
};
+
+/**
+ * Cached KSK keys so that we don't have to recompute them
+ * all the time.
+ */
static struct KBlockKeyCacheLine **cache;
+
+/**
+ * Size of the 'cache' array.
+ */
static unsigned int cacheSize;
+
/**
* Deterministically (!) create a hostkey using only the
* given HashCode as input to the PRNG.
+ *
+ * @param hc hash code to generate the key from
+ * @return corresponding private key; must not be freed!
*/
struct GNUNET_CRYPTO_RsaPrivateKey *
-GNUNET_CRYPTO_rsa_key_create_from_hash (const GNUNET_HashCode * hc)
+GNUNET_CRYPTO_rsa_key_create_from_hash (const struct GNUNET_HashCode * hc)
{
- struct GNUNET_CRYPTO_RsaPrivateKey *ret;
struct KBlockKeyCacheLine *line;
unsigned int i;
- for (i = 0; i < cacheSize; i++)
- {
- if (0 == memcmp (hc, &cache[i]->hc, sizeof (GNUNET_HashCode)))
- {
- ret = ksk_decode_key (cache[i]->pke);
- return ret;
- }
- }
-
+ for (i = 0; i < cacheSize; i++)
+ if (0 == memcmp (hc, &cache[i]->hc, sizeof (struct GNUNET_HashCode)))
+ return GNUNET_CRYPTO_rsa_decode_key ((const char*) cache[i]->pke,
+ ntohs (cache[i]->pke->len));
line = GNUNET_malloc (sizeof (struct KBlockKeyCacheLine));
line->hc = *hc;
line->pke = makeKblockKeyInternal (hc);
GNUNET_array_grow (cache, cacheSize, cacheSize + 1);
cache[cacheSize - 1] = line;
- return ksk_decode_key (line->pke);
+ return GNUNET_CRYPTO_rsa_decode_key ((const char*) line->pke,
+ ntohs (line->pke->len));
}
+/**
+ * Destructor that frees the KSK cache.
+ */
void __attribute__ ((destructor)) GNUNET_CRYPTO_ksk_fini ()
{
unsigned int i;