aboutsummaryrefslogtreecommitdiff
path: root/src/util/crypto_ecc.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-10-10 14:38:55 +0000
committerChristian Grothoff <christian@grothoff.org>2013-10-10 14:38:55 +0000
commit9351b1e9bdf2b067b6db06562c26ba658cff42b8 (patch)
tree68dc4ab447e7e8b6a20a706858cd36238c1c7c5f /src/util/crypto_ecc.c
parent8beabcd96c0cf1e1873c0b5ff96e537f1beb0b34 (diff)
downloadgnunet-9351b1e9bdf2b067b6db06562c26ba658cff42b8.tar.gz
gnunet-9351b1e9bdf2b067b6db06562c26ba658cff42b8.zip
separating ECC crypto into functions/structs for ECDHE, ECDSA and EDDSA
Diffstat (limited to 'src/util/crypto_ecc.c')
-rw-r--r--src/util/crypto_ecc.c827
1 files changed, 734 insertions, 93 deletions
diff --git a/src/util/crypto_ecc.c b/src/util/crypto_ecc.c
index 34edec3de..e2eaaa269 100644
--- a/src/util/crypto_ecc.c
+++ b/src/util/crypto_ecc.c
@@ -188,7 +188,7 @@ mpi_scan (gcry_mpi_t *result,
188 * @return NULL on error 188 * @return NULL on error
189 */ 189 */
190static gcry_sexp_t 190static gcry_sexp_t
191decode_private_key (const struct GNUNET_CRYPTO_EccPrivateKey *priv) 191decode_private_ecdsa_key (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv)
192{ 192{
193 gcry_sexp_t result; 193 gcry_sexp_t result;
194 gcry_mpi_t d; 194 gcry_mpi_t d;
@@ -218,6 +218,80 @@ decode_private_key (const struct GNUNET_CRYPTO_EccPrivateKey *priv)
218 218
219 219
220/** 220/**
221 * Convert the given private key from the network format to the
222 * S-expression that can be used by libgcrypt.
223 *
224 * @param priv private key to decode
225 * @return NULL on error
226 */
227static gcry_sexp_t
228decode_private_eddsa_key (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
229{
230 gcry_sexp_t result;
231 gcry_mpi_t d;
232 int rc;
233
234 mpi_scan (&d,
235 priv->d,
236 sizeof (priv->d));
237 rc = gcry_sexp_build (&result, NULL,
238 "(private-key(ecdsa(curve \"" CURVE "\")(d %m)))", // FIXME: eddsa soon!
239 d);
240 gcry_mpi_release (d);
241 if (0 != rc)
242 {
243 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
244 GNUNET_assert (0);
245 }
246#if EXTRA_CHECKS
247 if (0 != (rc = gcry_pk_testkey (result)))
248 {
249 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
250 GNUNET_assert (0);
251 }
252#endif
253 return result;
254}
255
256
257/**
258 * Convert the given private key from the network format to the
259 * S-expression that can be used by libgcrypt.
260 *
261 * @param priv private key to decode
262 * @return NULL on error
263 */
264static gcry_sexp_t
265decode_private_ecdhe_key (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv)
266{
267 gcry_sexp_t result;
268 gcry_mpi_t d;
269 int rc;
270
271 mpi_scan (&d,
272 priv->d,
273 sizeof (priv->d));
274 rc = gcry_sexp_build (&result, NULL,
275 "(private-key(ecdsa(curve \"" CURVE "\")(d %m)))", // FIXME: ecdh here?
276 d);
277 gcry_mpi_release (d);
278 if (0 != rc)
279 {
280 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
281 GNUNET_assert (0);
282 }
283#if EXTRA_CHECKS
284 if (0 != (rc = gcry_pk_testkey (result)))
285 {
286 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
287 GNUNET_assert (0);
288 }
289#endif
290 return result;
291}
292
293
294/**
221 * Initialize public key struct from the respective point 295 * Initialize public key struct from the respective point
222 * on the curve. 296 * on the curve.
223 * 297 *
@@ -226,9 +300,9 @@ decode_private_key (const struct GNUNET_CRYPTO_EccPrivateKey *priv)
226 * @param ctx context to use for ECC operations 300 * @param ctx context to use for ECC operations
227 */ 301 */
228static void 302static void
229point_to_public_sign_key (gcry_mpi_point_t q, 303point_to_public_ecdsa_key (gcry_mpi_point_t q,
230 gcry_ctx_t ctx, 304 gcry_ctx_t ctx,
231 struct GNUNET_CRYPTO_EccPublicSignKey *pub) 305 struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
232{ 306{
233 gcry_mpi_t q_x; 307 gcry_mpi_t q_x;
234 gcry_mpi_t q_y; 308 gcry_mpi_t q_y;
@@ -257,9 +331,9 @@ point_to_public_sign_key (gcry_mpi_point_t q,
257 * @param ctx context to use for ECC operations 331 * @param ctx context to use for ECC operations
258 */ 332 */
259static void 333static void
260point_to_public_encrypt_key (gcry_mpi_point_t q, 334point_to_public_eddsa_key (gcry_mpi_point_t q,
261 gcry_ctx_t ctx, 335 gcry_ctx_t ctx,
262 struct GNUNET_CRYPTO_EccPublicEncryptKey *pub) 336 struct GNUNET_CRYPTO_EddsaPublicKey *pub)
263{ 337{
264 gcry_mpi_t q_x; 338 gcry_mpi_t q_x;
265 gcry_mpi_t q_y; 339 gcry_mpi_t q_y;
@@ -280,25 +354,81 @@ point_to_public_encrypt_key (gcry_mpi_point_t q,
280 354
281 355
282/** 356/**
357 * Initialize public key struct from the respective point
358 * on the curve.
359 *
360 * @param q point on curve
361 * @param pub public key struct to initialize
362 * @param ctx context to use for ECC operations
363 */
364static void
365point_to_public_ecdhe_key (gcry_mpi_point_t q,
366 gcry_ctx_t ctx,
367 struct GNUNET_CRYPTO_EcdhePublicKey *pub)
368{
369 gcry_mpi_t q_x;
370 gcry_mpi_t q_y;
371
372 q_x = gcry_mpi_new (256);
373 q_y = gcry_mpi_new (256);
374 if (gcry_mpi_ec_get_affine (q_x, q_y, q, ctx))
375 {
376 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
377 return;
378 }
379
380 mpi_print (pub->q_x, sizeof (pub->q_x), q_x);
381 mpi_print (pub->q_y, sizeof (pub->q_y), q_y);
382 gcry_mpi_release (q_x);
383 gcry_mpi_release (q_y);
384}
385
386
387/**
388 * Extract the public key for the given private key.
389 *
390 * @param priv the private key
391 * @param pub where to write the public key
392 */
393void
394GNUNET_CRYPTO_ecdsa_key_get_public (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
395 struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
396{
397 gcry_sexp_t sexp;
398 gcry_ctx_t ctx;
399 gcry_mpi_point_t q;
400
401 sexp = decode_private_ecdsa_key (priv);
402 GNUNET_assert (NULL != sexp);
403 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL));
404 gcry_sexp_release (sexp);
405 q = gcry_mpi_ec_get_point ("q", ctx, 0);
406 point_to_public_ecdsa_key (q, ctx, pub);
407 gcry_ctx_release (ctx);
408 gcry_mpi_point_release (q);
409}
410
411
412/**
283 * Extract the public key for the given private key. 413 * Extract the public key for the given private key.
284 * 414 *
285 * @param priv the private key 415 * @param priv the private key
286 * @param pub where to write the public key 416 * @param pub where to write the public key
287 */ 417 */
288void 418void
289GNUNET_CRYPTO_ecc_key_get_public_for_signature (const struct GNUNET_CRYPTO_EccPrivateKey *priv, 419GNUNET_CRYPTO_eddsa_key_get_public (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
290 struct GNUNET_CRYPTO_EccPublicSignKey *pub) 420 struct GNUNET_CRYPTO_EddsaPublicKey *pub)
291{ 421{
292 gcry_sexp_t sexp; 422 gcry_sexp_t sexp;
293 gcry_ctx_t ctx; 423 gcry_ctx_t ctx;
294 gcry_mpi_point_t q; 424 gcry_mpi_point_t q;
295 425
296 sexp = decode_private_key (priv); 426 sexp = decode_private_eddsa_key (priv);
297 GNUNET_assert (NULL != sexp); 427 GNUNET_assert (NULL != sexp);
298 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL)); 428 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL));
299 gcry_sexp_release (sexp); 429 gcry_sexp_release (sexp);
300 q = gcry_mpi_ec_get_point ("q", ctx, 0); 430 q = gcry_mpi_ec_get_point ("q", ctx, 0);
301 point_to_public_sign_key (q, ctx, pub); 431 point_to_public_eddsa_key (q, ctx, pub);
302 gcry_ctx_release (ctx); 432 gcry_ctx_release (ctx);
303 gcry_mpi_point_release (q); 433 gcry_mpi_point_release (q);
304} 434}
@@ -311,19 +441,19 @@ GNUNET_CRYPTO_ecc_key_get_public_for_signature (const struct GNUNET_CRYPTO_EccPr
311 * @param pub where to write the public key 441 * @param pub where to write the public key
312 */ 442 */
313void 443void
314GNUNET_CRYPTO_ecc_key_get_public_for_encryption (const struct GNUNET_CRYPTO_EccPrivateKey *priv, 444GNUNET_CRYPTO_ecdhe_key_get_public (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
315 struct GNUNET_CRYPTO_EccPublicEncryptKey *pub) 445 struct GNUNET_CRYPTO_EcdhePublicKey *pub)
316{ 446{
317 gcry_sexp_t sexp; 447 gcry_sexp_t sexp;
318 gcry_ctx_t ctx; 448 gcry_ctx_t ctx;
319 gcry_mpi_point_t q; 449 gcry_mpi_point_t q;
320 450
321 sexp = decode_private_key (priv); 451 sexp = decode_private_ecdhe_key (priv);
322 GNUNET_assert (NULL != sexp); 452 GNUNET_assert (NULL != sexp);
323 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL)); 453 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL));
324 gcry_sexp_release (sexp); 454 gcry_sexp_release (sexp);
325 q = gcry_mpi_ec_get_point ("q", ctx, 0); 455 q = gcry_mpi_ec_get_point ("q", ctx, 0);
326 point_to_public_encrypt_key (q, ctx, pub); 456 point_to_public_ecdhe_key (q, ctx, pub);
327 gcry_ctx_release (ctx); 457 gcry_ctx_release (ctx);
328 gcry_mpi_point_release (q); 458 gcry_mpi_point_release (q);
329} 459}
@@ -336,10 +466,41 @@ GNUNET_CRYPTO_ecc_key_get_public_for_encryption (const struct GNUNET_CRYPTO_EccP
336 * @return string representing @a pub 466 * @return string representing @a pub
337 */ 467 */
338char * 468char *
339GNUNET_CRYPTO_ecc_public_sign_key_to_string (const struct GNUNET_CRYPTO_EccPublicSignKey *pub) 469GNUNET_CRYPTO_ecdsa_public_key_to_string (const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
470{
471 char *pubkeybuf;
472 size_t keylen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8;
473 char *end;
474
475 if (keylen % 5 > 0)
476 keylen += 5 - keylen % 5;
477 keylen /= 5;
478 pubkeybuf = GNUNET_malloc (keylen + 1);
479 end = GNUNET_STRINGS_data_to_string ((unsigned char *) pub,
480 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey),
481 pubkeybuf,
482 keylen);
483 if (NULL == end)
484 {
485 GNUNET_free (pubkeybuf);
486 return NULL;
487 }
488 *end = '\0';
489 return pubkeybuf;
490}
491
492
493/**
494 * Convert a public key to a string.
495 *
496 * @param pub key to convert
497 * @return string representing @a pub
498 */
499char *
500GNUNET_CRYPTO_eddsa_public_key_to_string (const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
340{ 501{
341 char *pubkeybuf; 502 char *pubkeybuf;
342 size_t keylen = (sizeof (struct GNUNET_CRYPTO_EccPublicSignKey)) * 8; 503 size_t keylen = (sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)) * 8;
343 char *end; 504 char *end;
344 505
345 if (keylen % 5 > 0) 506 if (keylen % 5 > 0)
@@ -347,7 +508,7 @@ GNUNET_CRYPTO_ecc_public_sign_key_to_string (const struct GNUNET_CRYPTO_EccPubli
347 keylen /= 5; 508 keylen /= 5;
348 pubkeybuf = GNUNET_malloc (keylen + 1); 509 pubkeybuf = GNUNET_malloc (keylen + 1);
349 end = GNUNET_STRINGS_data_to_string ((unsigned char *) pub, 510 end = GNUNET_STRINGS_data_to_string ((unsigned char *) pub,
350 sizeof (struct GNUNET_CRYPTO_EccPublicSignKey), 511 sizeof (struct GNUNET_CRYPTO_EddsaPublicKey),
351 pubkeybuf, 512 pubkeybuf,
352 keylen); 513 keylen);
353 if (NULL == end) 514 if (NULL == end)
@@ -369,11 +530,11 @@ GNUNET_CRYPTO_ecc_public_sign_key_to_string (const struct GNUNET_CRYPTO_EccPubli
369 * @return #GNUNET_OK on success 530 * @return #GNUNET_OK on success
370 */ 531 */
371int 532int
372GNUNET_CRYPTO_ecc_public_sign_key_from_string (const char *enc, 533GNUNET_CRYPTO_ecdsa_public_key_from_string (const char *enc,
373 size_t enclen, 534 size_t enclen,
374 struct GNUNET_CRYPTO_EccPublicSignKey *pub) 535 struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
375{ 536{
376 size_t keylen = (sizeof (struct GNUNET_CRYPTO_EccPublicSignKey)) * 8; 537 size_t keylen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8;
377 538
378 if (keylen % 5 > 0) 539 if (keylen % 5 > 0)
379 keylen += 5 - keylen % 5; 540 keylen += 5 - keylen % 5;
@@ -383,7 +544,36 @@ GNUNET_CRYPTO_ecc_public_sign_key_from_string (const char *enc,
383 544
384 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (enc, enclen, 545 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (enc, enclen,
385 pub, 546 pub,
386 sizeof (struct GNUNET_CRYPTO_EccPublicSignKey))) 547 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
548 return GNUNET_SYSERR;
549 return GNUNET_OK;
550}
551
552
553/**
554 * Convert a string representing a public key to a public key.
555 *
556 * @param enc encoded public key
557 * @param enclen number of bytes in @a enc (without 0-terminator)
558 * @param pub where to store the public key
559 * @return #GNUNET_OK on success
560 */
561int
562GNUNET_CRYPTO_eddsa_public_key_from_string (const char *enc,
563 size_t enclen,
564 struct GNUNET_CRYPTO_EddsaPublicKey *pub)
565{
566 size_t keylen = (sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)) * 8;
567
568 if (keylen % 5 > 0)
569 keylen += 5 - keylen % 5;
570 keylen /= 5;
571 if (enclen != keylen)
572 return GNUNET_SYSERR;
573
574 if (GNUNET_OK != GNUNET_STRINGS_string_to_data (enc, enclen,
575 pub,
576 sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)))
387 return GNUNET_SYSERR; 577 return GNUNET_SYSERR;
388 return GNUNET_OK; 578 return GNUNET_OK;
389} 579}
@@ -397,7 +587,7 @@ GNUNET_CRYPTO_ecc_public_sign_key_from_string (const char *enc,
397 * @return NULL on error 587 * @return NULL on error
398 */ 588 */
399static gcry_sexp_t 589static gcry_sexp_t
400decode_public_sign_key (const struct GNUNET_CRYPTO_EccPublicSignKey *pub) 590decode_public_ecdsa_key (const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
401{ 591{
402 gcry_sexp_t pub_sexp; 592 gcry_sexp_t pub_sexp;
403 gcry_mpi_t q_x; 593 gcry_mpi_t q_x;
@@ -413,7 +603,7 @@ decode_public_sign_key (const struct GNUNET_CRYPTO_EccPublicSignKey *pub)
413 gcry_mpi_release (q_y); 603 gcry_mpi_release (q_y);
414 604
415 /* initialize 'ctx' with 'q' */ 605 /* initialize 'ctx' with 'q' */
416 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE)); 606 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE)); // FIXME: need to say ECDSA?
417 gcry_mpi_ec_set_point ("q", q, ctx); 607 gcry_mpi_ec_set_point ("q", q, ctx);
418 gcry_mpi_point_release (q); 608 gcry_mpi_point_release (q);
419 609
@@ -425,15 +615,125 @@ decode_public_sign_key (const struct GNUNET_CRYPTO_EccPublicSignKey *pub)
425 615
426 616
427/** 617/**
618 * Convert the given public key from the network format to the
619 * S-expression that can be used by libgcrypt.
620 *
621 * @param pub public key to decode
622 * @return NULL on error
623 */
624static gcry_sexp_t
625decode_public_eddsa_key (const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
626{
627 gcry_sexp_t pub_sexp;
628 gcry_mpi_t q_x;
629 gcry_mpi_t q_y;
630 gcry_mpi_point_t q;
631 gcry_ctx_t ctx;
632
633 mpi_scan (&q_x, pub->q_x, sizeof (pub->q_x));
634 mpi_scan (&q_y, pub->q_y, sizeof (pub->q_y));
635 q = gcry_mpi_point_new (256);
636 gcry_mpi_point_set (q, q_x, q_y, GCRYMPI_CONST_ONE);
637 gcry_mpi_release (q_x);
638 gcry_mpi_release (q_y);
639
640 /* initialize 'ctx' with 'q' */
641 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE)); // FIXME: need to say EdDSA?
642 gcry_mpi_ec_set_point ("q", q, ctx);
643 gcry_mpi_point_release (q);
644
645 /* convert 'ctx' to 'sexp' */
646 GNUNET_assert (0 == gcry_pubkey_get_sexp (&pub_sexp, GCRY_PK_GET_PUBKEY, ctx));
647 gcry_ctx_release (ctx);
648 return pub_sexp;
649}
650
651
652/**
653 * @ingroup crypto
654 * Clear memory that was used to store a private key.
655 *
656 * @param pk location of the key
657 */
658void
659GNUNET_CRYPTO_ecdhe_key_clear (struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
660{
661 memset (pk, 0, sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey));
662}
663
664
665/**
428 * @ingroup crypto 666 * @ingroup crypto
429 * Clear memory that was used to store a private key. 667 * Clear memory that was used to store a private key.
430 * 668 *
431 * @param pk location of the key 669 * @param pk location of the key
432 */ 670 */
433void 671void
434GNUNET_CRYPTO_ecc_key_clear (struct GNUNET_CRYPTO_EccPrivateKey *pk) 672GNUNET_CRYPTO_ecdsa_key_clear (struct GNUNET_CRYPTO_EcdsaPrivateKey *pk)
435{ 673{
436 memset (pk, 0, sizeof (struct GNUNET_CRYPTO_EccPrivateKey)); 674 memset (pk, 0, sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey));
675}
676
677
678/**
679 * @ingroup crypto
680 * Clear memory that was used to store a private key.
681 *
682 * @param pk location of the key
683 */
684void
685GNUNET_CRYPTO_eddsa_key_clear (struct GNUNET_CRYPTO_EddsaPrivateKey *pk)
686{
687 memset (pk, 0, sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey));
688}
689
690
691/**
692 * Create a new private key. Caller must free return value.
693 *
694 * @return fresh private key
695 */
696struct GNUNET_CRYPTO_EcdhePrivateKey *
697GNUNET_CRYPTO_ecdhe_key_create ()
698{
699 struct GNUNET_CRYPTO_EcdhePrivateKey *priv;
700 gcry_sexp_t priv_sexp;
701 gcry_sexp_t s_keyparam;
702 gcry_mpi_t d;
703 int rc;
704
705 if (0 != (rc = gcry_sexp_build (&s_keyparam, NULL,
706 "(genkey(ecdsa(curve \"" CURVE "\")))"))) // FIXME: ECDHE?
707 {
708 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
709 return NULL;
710 }
711 if (0 != (rc = gcry_pk_genkey (&priv_sexp, s_keyparam)))
712 {
713 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_genkey", rc);
714 gcry_sexp_release (s_keyparam);
715 return NULL;
716 }
717 gcry_sexp_release (s_keyparam);
718#if EXTRA_CHECKS
719 if (0 != (rc = gcry_pk_testkey (priv_sexp)))
720 {
721 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
722 gcry_sexp_release (priv_sexp);
723 return NULL;
724 }
725#endif
726 if (0 != (rc = key_from_sexp (&d, priv_sexp, "private-key", "d")))
727 {
728 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "key_from_sexp", rc);
729 gcry_sexp_release (priv_sexp);
730 return NULL;
731 }
732 gcry_sexp_release (priv_sexp);
733 priv = GNUNET_new (struct GNUNET_CRYPTO_EcdhePrivateKey);
734 mpi_print (priv->d, sizeof (priv->d), d);
735 gcry_mpi_release (d);
736 return priv;
437} 737}
438 738
439 739
@@ -442,10 +742,10 @@ GNUNET_CRYPTO_ecc_key_clear (struct GNUNET_CRYPTO_EccPrivateKey *pk)
442 * 742 *
443 * @return fresh private key 743 * @return fresh private key
444 */ 744 */
445struct GNUNET_CRYPTO_EccPrivateKey * 745struct GNUNET_CRYPTO_EcdsaPrivateKey *
446GNUNET_CRYPTO_ecc_key_create () 746GNUNET_CRYPTO_ecdsa_key_create ()
447{ 747{
448 struct GNUNET_CRYPTO_EccPrivateKey *priv; 748 struct GNUNET_CRYPTO_EcdsaPrivateKey *priv;
449 gcry_sexp_t priv_sexp; 749 gcry_sexp_t priv_sexp;
450 gcry_sexp_t s_keyparam; 750 gcry_sexp_t s_keyparam;
451 gcry_mpi_t d; 751 gcry_mpi_t d;
@@ -479,7 +779,55 @@ GNUNET_CRYPTO_ecc_key_create ()
479 return NULL; 779 return NULL;
480 } 780 }
481 gcry_sexp_release (priv_sexp); 781 gcry_sexp_release (priv_sexp);
482 priv = GNUNET_new (struct GNUNET_CRYPTO_EccPrivateKey); 782 priv = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPrivateKey);
783 mpi_print (priv->d, sizeof (priv->d), d);
784 gcry_mpi_release (d);
785 return priv;
786}
787
788/**
789 * Create a new private key. Caller must free return value.
790 *
791 * @return fresh private key
792 */
793struct GNUNET_CRYPTO_EddsaPrivateKey *
794GNUNET_CRYPTO_eddsa_key_create ()
795{
796 struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
797 gcry_sexp_t priv_sexp;
798 gcry_sexp_t s_keyparam;
799 gcry_mpi_t d;
800 int rc;
801
802 if (0 != (rc = gcry_sexp_build (&s_keyparam, NULL,
803 "(genkey(ecdsa(curve \"" CURVE "\")))"))) // FIXME: EdDSA?
804 {
805 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
806 return NULL;
807 }
808 if (0 != (rc = gcry_pk_genkey (&priv_sexp, s_keyparam)))
809 {
810 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_genkey", rc);
811 gcry_sexp_release (s_keyparam);
812 return NULL;
813 }
814 gcry_sexp_release (s_keyparam);
815#if EXTRA_CHECKS
816 if (0 != (rc = gcry_pk_testkey (priv_sexp)))
817 {
818 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
819 gcry_sexp_release (priv_sexp);
820 return NULL;
821 }
822#endif
823 if (0 != (rc = key_from_sexp (&d, priv_sexp, "private-key", "d")))
824 {
825 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "key_from_sexp", rc);
826 gcry_sexp_release (priv_sexp);
827 return NULL;
828 }
829 gcry_sexp_release (priv_sexp);
830 priv = GNUNET_new (struct GNUNET_CRYPTO_EddsaPrivateKey);
483 mpi_print (priv->d, sizeof (priv->d), d); 831 mpi_print (priv->d, sizeof (priv->d), d);
484 gcry_mpi_release (d); 832 gcry_mpi_release (d);
485 return priv; 833 return priv;
@@ -491,14 +839,14 @@ GNUNET_CRYPTO_ecc_key_create ()
491 * 839 *
492 * @return "anonymous" private key 840 * @return "anonymous" private key
493 */ 841 */
494const struct GNUNET_CRYPTO_EccPrivateKey * 842const struct GNUNET_CRYPTO_EcdsaPrivateKey *
495GNUNET_CRYPTO_ecc_key_get_anonymous () 843GNUNET_CRYPTO_ecdsa_key_get_anonymous ()
496{ 844{
497 /** 845 /**
498 * 'anonymous' pseudonym (global static, d=1, public key = G 846 * 'anonymous' pseudonym (global static, d=1, public key = G
499 * (generator). 847 * (generator).
500 */ 848 */
501 static struct GNUNET_CRYPTO_EccPrivateKey anonymous; 849 static struct GNUNET_CRYPTO_EcdsaPrivateKey anonymous;
502 static int once; 850 static int once;
503 851
504 if (once) 852 if (once)
@@ -542,10 +890,10 @@ short_wait ()
542 * @return new private key, NULL on error (for example, 890 * @return new private key, NULL on error (for example,
543 * permission denied) 891 * permission denied)
544 */ 892 */
545struct GNUNET_CRYPTO_EccPrivateKey * 893struct GNUNET_CRYPTO_EddsaPrivateKey *
546GNUNET_CRYPTO_ecc_key_create_from_file (const char *filename) 894GNUNET_CRYPTO_eddsa_key_create_from_file (const char *filename)
547{ 895{
548 struct GNUNET_CRYPTO_EccPrivateKey *priv; 896 struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
549 struct GNUNET_DISK_FileHandle *fd; 897 struct GNUNET_DISK_FileHandle *fd;
550 unsigned int cnt; 898 unsigned int cnt;
551 int ec; 899 int ec;
@@ -581,7 +929,7 @@ GNUNET_CRYPTO_ecc_key_create_from_file (const char *filename)
581 cnt = 0; 929 cnt = 0;
582 while (GNUNET_YES != 930 while (GNUNET_YES !=
583 GNUNET_DISK_file_lock (fd, 0, 931 GNUNET_DISK_file_lock (fd, 0,
584 sizeof (struct GNUNET_CRYPTO_EccPrivateKey), 932 sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey),
585 GNUNET_YES)) 933 GNUNET_YES))
586 { 934 {
587 short_wait (); 935 short_wait ();
@@ -595,14 +943,14 @@ GNUNET_CRYPTO_ecc_key_create_from_file (const char *filename)
595 } 943 }
596 LOG (GNUNET_ERROR_TYPE_INFO, 944 LOG (GNUNET_ERROR_TYPE_INFO,
597 _("Creating a new private key. This may take a while.\n")); 945 _("Creating a new private key. This may take a while.\n"));
598 priv = GNUNET_CRYPTO_ecc_key_create (); 946 priv = GNUNET_CRYPTO_eddsa_key_create ();
599 GNUNET_assert (NULL != priv); 947 GNUNET_assert (NULL != priv);
600 GNUNET_assert (sizeof (*priv) == 948 GNUNET_assert (sizeof (*priv) ==
601 GNUNET_DISK_file_write (fd, priv, sizeof (*priv))); 949 GNUNET_DISK_file_write (fd, priv, sizeof (*priv)));
602 GNUNET_DISK_file_sync (fd); 950 GNUNET_DISK_file_sync (fd);
603 if (GNUNET_YES != 951 if (GNUNET_YES !=
604 GNUNET_DISK_file_unlock (fd, 0, 952 GNUNET_DISK_file_unlock (fd, 0,
605 sizeof (struct GNUNET_CRYPTO_EccPrivateKey))) 953 sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)))
606 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); 954 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
607 GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd)); 955 GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd));
608 return priv; 956 return priv;
@@ -620,7 +968,7 @@ GNUNET_CRYPTO_ecc_key_create_from_file (const char *filename)
620 { 968 {
621 if (GNUNET_YES != 969 if (GNUNET_YES !=
622 GNUNET_DISK_file_lock (fd, 0, 970 GNUNET_DISK_file_lock (fd, 0,
623 sizeof (struct GNUNET_CRYPTO_EccPrivateKey), 971 sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey),
624 GNUNET_NO)) 972 GNUNET_NO))
625 { 973 {
626 if (0 == ++cnt % 60) 974 if (0 == ++cnt % 60)
@@ -642,7 +990,7 @@ GNUNET_CRYPTO_ecc_key_create_from_file (const char *filename)
642 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", filename); 990 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", filename);
643 if (GNUNET_YES != 991 if (GNUNET_YES !=
644 GNUNET_DISK_file_unlock (fd, 0, 992 GNUNET_DISK_file_unlock (fd, 0,
645 sizeof (struct GNUNET_CRYPTO_EccPrivateKey))) 993 sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)))
646 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); 994 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
647 GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fd)); 995 GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fd));
648 996
@@ -650,36 +998,190 @@ GNUNET_CRYPTO_ecc_key_create_from_file (const char *filename)
650 } 998 }
651 if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fs, GNUNET_YES, GNUNET_YES)) 999 if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fs, GNUNET_YES, GNUNET_YES))
652 fs = 0; 1000 fs = 0;
653 if (fs < sizeof (struct GNUNET_CRYPTO_EccPrivateKey)) 1001 if (fs < sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey))
654 { 1002 {
655 /* maybe we got the read lock before the key generating 1003 /* maybe we got the read lock before the key generating
656 * process had a chance to get the write lock; give it up! */ 1004 * process had a chance to get the write lock; give it up! */
657 if (GNUNET_YES != 1005 if (GNUNET_YES !=
658 GNUNET_DISK_file_unlock (fd, 0, 1006 GNUNET_DISK_file_unlock (fd, 0,
659 sizeof (struct GNUNET_CRYPTO_EccPrivateKey))) 1007 sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)))
660 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); 1008 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
661 if (0 == ++cnt % 10) 1009 if (0 == ++cnt % 10)
662 { 1010 {
663 LOG (GNUNET_ERROR_TYPE_ERROR, 1011 LOG (GNUNET_ERROR_TYPE_ERROR,
664 _ 1012 _("When trying to read key file `%s' I found %u bytes but I need at least %u.\n"),
665 ("When trying to read key file `%s' I found %u bytes but I need at least %u.\n"),
666 filename, (unsigned int) fs, 1013 filename, (unsigned int) fs,
667 (unsigned int) sizeof (struct GNUNET_CRYPTO_EccPrivateKey)); 1014 (unsigned int) sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey));
1015 LOG (GNUNET_ERROR_TYPE_ERROR,
1016 _("This may be ok if someone is currently generating a key.\n"));
1017 }
1018 short_wait (); /* wait a bit longer! */
1019 continue;
1020 }
1021 break;
1022 }
1023 fs = sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey);
1024 priv = GNUNET_malloc (fs);
1025 GNUNET_assert (fs == GNUNET_DISK_file_read (fd, priv, fs));
1026 if (GNUNET_YES !=
1027 GNUNET_DISK_file_unlock (fd, 0,
1028 sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)))
1029 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
1030 GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd));
1031 return priv;
1032}
1033
1034
1035/**
1036 * Create a new private key by reading it from a file. If the
1037 * files does not exist, create a new key and write it to the
1038 * file. Caller must free return value. Note that this function
1039 * can not guarantee that another process might not be trying
1040 * the same operation on the same file at the same time.
1041 * If the contents of the file
1042 * are invalid the old file is deleted and a fresh key is
1043 * created.
1044 *
1045 * @param filename name of file to use to store the key
1046 * @return new private key, NULL on error (for example,
1047 * permission denied)
1048 */
1049struct GNUNET_CRYPTO_EcdsaPrivateKey *
1050GNUNET_CRYPTO_ecdsa_key_create_from_file (const char *filename)
1051{
1052 struct GNUNET_CRYPTO_EcdsaPrivateKey *priv;
1053 struct GNUNET_DISK_FileHandle *fd;
1054 unsigned int cnt;
1055 int ec;
1056 uint64_t fs;
1057
1058 if (GNUNET_SYSERR == GNUNET_DISK_directory_create_for_file (filename))
1059 return NULL;
1060 while (GNUNET_YES != GNUNET_DISK_file_test (filename))
1061 {
1062 fd = GNUNET_DISK_file_open (filename,
1063 GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE
1064 | GNUNET_DISK_OPEN_FAILIFEXISTS,
1065 GNUNET_DISK_PERM_USER_READ |
1066 GNUNET_DISK_PERM_USER_WRITE);
1067 if (NULL == fd)
1068 {
1069 if (EEXIST == errno)
1070 {
1071 if (GNUNET_YES != GNUNET_DISK_file_test (filename))
1072 {
1073 /* must exist but not be accessible, fail for good! */
1074 if (0 != ACCESS (filename, R_OK))
1075 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "access", filename);
1076 else
1077 GNUNET_break (0); /* what is going on!? */
1078 return NULL;
1079 }
1080 continue;
1081 }
1082 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename);
1083 return NULL;
1084 }
1085 cnt = 0;
1086 while (GNUNET_YES !=
1087 GNUNET_DISK_file_lock (fd, 0,
1088 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey),
1089 GNUNET_YES))
1090 {
1091 short_wait ();
1092 if (0 == ++cnt % 10)
1093 {
1094 ec = errno;
1095 LOG (GNUNET_ERROR_TYPE_ERROR,
1096 _("Could not acquire lock on file `%s': %s...\n"), filename,
1097 STRERROR (ec));
1098 }
1099 }
1100 LOG (GNUNET_ERROR_TYPE_INFO,
1101 _("Creating a new private key. This may take a while.\n"));
1102 priv = GNUNET_CRYPTO_ecdsa_key_create ();
1103 GNUNET_assert (NULL != priv);
1104 GNUNET_assert (sizeof (*priv) ==
1105 GNUNET_DISK_file_write (fd, priv, sizeof (*priv)));
1106 GNUNET_DISK_file_sync (fd);
1107 if (GNUNET_YES !=
1108 GNUNET_DISK_file_unlock (fd, 0,
1109 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)))
1110 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
1111 GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd));
1112 return priv;
1113 }
1114 /* key file exists already, read it! */
1115 fd = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ,
1116 GNUNET_DISK_PERM_NONE);
1117 if (NULL == fd)
1118 {
1119 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "open", filename);
1120 return NULL;
1121 }
1122 cnt = 0;
1123 while (1)
1124 {
1125 if (GNUNET_YES !=
1126 GNUNET_DISK_file_lock (fd, 0,
1127 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey),
1128 GNUNET_NO))
1129 {
1130 if (0 == ++cnt % 60)
1131 {
1132 ec = errno;
1133 LOG (GNUNET_ERROR_TYPE_ERROR,
1134 _("Could not acquire lock on file `%s': %s...\n"), filename,
1135 STRERROR (ec));
668 LOG (GNUNET_ERROR_TYPE_ERROR, 1136 LOG (GNUNET_ERROR_TYPE_ERROR,
669 _ 1137 _
670 ("This may be ok if someone is currently generating a key.\n")); 1138 ("This may be ok if someone is currently generating a private key.\n"));
1139 }
1140 short_wait ();
1141 continue;
1142 }
1143 if (GNUNET_YES != GNUNET_DISK_file_test (filename))
1144 {
1145 /* eh, what!? File we opened is now gone!? */
1146 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", filename);
1147 if (GNUNET_YES !=
1148 GNUNET_DISK_file_unlock (fd, 0,
1149 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)))
1150 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
1151 GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fd));
1152
1153 return NULL;
1154 }
1155 if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fs, GNUNET_YES, GNUNET_YES))
1156 fs = 0;
1157 if (fs < sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey))
1158 {
1159 /* maybe we got the read lock before the key generating
1160 * process had a chance to get the write lock; give it up! */
1161 if (GNUNET_YES !=
1162 GNUNET_DISK_file_unlock (fd, 0,
1163 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)))
1164 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
1165 if (0 == ++cnt % 10)
1166 {
1167 LOG (GNUNET_ERROR_TYPE_ERROR,
1168 _("When trying to read key file `%s' I found %u bytes but I need at least %u.\n"),
1169 filename, (unsigned int) fs,
1170 (unsigned int) sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey));
1171 LOG (GNUNET_ERROR_TYPE_ERROR,
1172 _("This may be ok if someone is currently generating a key.\n"));
671 } 1173 }
672 short_wait (); /* wait a bit longer! */ 1174 short_wait (); /* wait a bit longer! */
673 continue; 1175 continue;
674 } 1176 }
675 break; 1177 break;
676 } 1178 }
677 fs = sizeof (struct GNUNET_CRYPTO_EccPrivateKey); 1179 fs = sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey);
678 priv = GNUNET_malloc (fs); 1180 priv = GNUNET_malloc (fs);
679 GNUNET_assert (fs == GNUNET_DISK_file_read (fd, priv, fs)); 1181 GNUNET_assert (fs == GNUNET_DISK_file_read (fd, priv, fs));
680 if (GNUNET_YES != 1182 if (GNUNET_YES !=
681 GNUNET_DISK_file_unlock (fd, 0, 1183 GNUNET_DISK_file_unlock (fd, 0,
682 sizeof (struct GNUNET_CRYPTO_EccPrivateKey))) 1184 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey)))
683 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename); 1185 LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fcntl", filename);
684 GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd)); 1186 GNUNET_assert (GNUNET_YES == GNUNET_DISK_file_close (fd));
685 return priv; 1187 return priv;
@@ -694,16 +1196,16 @@ GNUNET_CRYPTO_ecc_key_create_from_file (const char *filename)
694 * @return new private key, NULL on error (for example, 1196 * @return new private key, NULL on error (for example,
695 * permission denied) 1197 * permission denied)
696 */ 1198 */
697struct GNUNET_CRYPTO_EccPrivateKey * 1199struct GNUNET_CRYPTO_EddsaPrivateKey *
698GNUNET_CRYPTO_ecc_key_create_from_configuration (const struct GNUNET_CONFIGURATION_Handle *cfg) 1200GNUNET_CRYPTO_eddsa_key_create_from_configuration (const struct GNUNET_CONFIGURATION_Handle *cfg)
699{ 1201{
700 struct GNUNET_CRYPTO_EccPrivateKey *priv; 1202 struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
701 char *fn; 1203 char *fn;
702 1204
703 if (GNUNET_OK != 1205 if (GNUNET_OK !=
704 GNUNET_CONFIGURATION_get_value_filename (cfg, "PEER", "PRIVATE_KEY", &fn)) 1206 GNUNET_CONFIGURATION_get_value_filename (cfg, "PEER", "PRIVATE_KEY", &fn))
705 return NULL; 1207 return NULL;
706 priv = GNUNET_CRYPTO_ecc_key_create_from_file (fn); 1208 priv = GNUNET_CRYPTO_eddsa_key_create_from_file (fn);
707 GNUNET_free (fn); 1209 GNUNET_free (fn);
708 return priv; 1210 return priv;
709} 1211}
@@ -718,14 +1220,14 @@ GNUNET_CRYPTO_ecc_key_create_from_configuration (const struct GNUNET_CONFIGURATI
718 * @param cfg_name name of the configuration file to use 1220 * @param cfg_name name of the configuration file to use
719 */ 1221 */
720void 1222void
721GNUNET_CRYPTO_ecc_setup_key (const char *cfg_name) 1223GNUNET_CRYPTO_eddsa_setup_key (const char *cfg_name)
722{ 1224{
723 struct GNUNET_CONFIGURATION_Handle *cfg; 1225 struct GNUNET_CONFIGURATION_Handle *cfg;
724 struct GNUNET_CRYPTO_EccPrivateKey *priv; 1226 struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
725 1227
726 cfg = GNUNET_CONFIGURATION_create (); 1228 cfg = GNUNET_CONFIGURATION_create ();
727 (void) GNUNET_CONFIGURATION_load (cfg, cfg_name); 1229 (void) GNUNET_CONFIGURATION_load (cfg, cfg_name);
728 priv = GNUNET_CRYPTO_ecc_key_create_from_configuration (cfg); 1230 priv = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg);
729 if (NULL != priv) 1231 if (NULL != priv)
730 GNUNET_free (priv); 1232 GNUNET_free (priv);
731 GNUNET_CONFIGURATION_destroy (cfg); 1233 GNUNET_CONFIGURATION_destroy (cfg);
@@ -744,15 +1246,15 @@ int
744GNUNET_CRYPTO_get_peer_identity (const struct GNUNET_CONFIGURATION_Handle *cfg, 1246GNUNET_CRYPTO_get_peer_identity (const struct GNUNET_CONFIGURATION_Handle *cfg,
745 struct GNUNET_PeerIdentity *dst) 1247 struct GNUNET_PeerIdentity *dst)
746{ 1248{
747 struct GNUNET_CRYPTO_EccPrivateKey *priv; 1249 struct GNUNET_CRYPTO_EddsaPrivateKey *priv;
748 1250
749 if (NULL == (priv = GNUNET_CRYPTO_ecc_key_create_from_configuration (cfg))) 1251 if (NULL == (priv = GNUNET_CRYPTO_eddsa_key_create_from_configuration (cfg)))
750 { 1252 {
751 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1253 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
752 _("Could not load peer's private key\n")); 1254 _("Could not load peer's private key\n"));
753 return GNUNET_SYSERR; 1255 return GNUNET_SYSERR;
754 } 1256 }
755 GNUNET_CRYPTO_ecc_key_get_public_for_signature (priv, &dst->public_key); 1257 GNUNET_CRYPTO_eddsa_key_get_public (priv, &dst->public_key);
756 GNUNET_free (priv); 1258 GNUNET_free (priv);
757 return GNUNET_OK; 1259 return GNUNET_OK;
758} 1260}
@@ -766,7 +1268,35 @@ GNUNET_CRYPTO_get_peer_identity (const struct GNUNET_CONFIGURATION_Handle *cfg,
766 * @return converted s-expression 1268 * @return converted s-expression
767 */ 1269 */
768static gcry_sexp_t 1270static gcry_sexp_t
769data_to_pkcs1 (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose) 1271data_to_eddsa_value (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose)
1272{
1273 struct GNUNET_HashCode hc;
1274 gcry_sexp_t data;
1275 int rc;
1276
1277 GNUNET_CRYPTO_hash (purpose, ntohl (purpose->size), &hc);
1278 if (0 != (rc = gcry_sexp_build (&data, NULL,
1279 "(data(flags rfc6979)(hash %s %b))", // FIXME: use EdDSA encoding!
1280 "sha512",
1281 sizeof (hc),
1282 &hc)))
1283 {
1284 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
1285 return NULL;
1286 }
1287 return data;
1288}
1289
1290
1291/**
1292 * Convert the data specified in the given purpose argument to an
1293 * S-expression suitable for signature operations.
1294 *
1295 * @param purpose data to convert
1296 * @return converted s-expression
1297 */
1298static gcry_sexp_t
1299data_to_ecdsa_value (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose)
770{ 1300{
771 struct GNUNET_HashCode hc; 1301 struct GNUNET_HashCode hc;
772 gcry_sexp_t data; 1302 gcry_sexp_t data;
@@ -795,9 +1325,9 @@ data_to_pkcs1 (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose)
795 * @return #GNUNET_SYSERR on error, #GNUNET_OK on success 1325 * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
796 */ 1326 */
797int 1327int
798GNUNET_CRYPTO_ecc_sign (const struct GNUNET_CRYPTO_EccPrivateKey *priv, 1328GNUNET_CRYPTO_ecdsa_sign (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
799 const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, 1329 const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
800 struct GNUNET_CRYPTO_EccSignature *sig) 1330 struct GNUNET_CRYPTO_EcdsaSignature *sig)
801{ 1331{
802 gcry_sexp_t priv_sexp; 1332 gcry_sexp_t priv_sexp;
803 gcry_sexp_t sig_sexp; 1333 gcry_sexp_t sig_sexp;
@@ -805,8 +1335,8 @@ GNUNET_CRYPTO_ecc_sign (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
805 int rc; 1335 int rc;
806 gcry_mpi_t rs[2]; 1336 gcry_mpi_t rs[2];
807 1337
808 priv_sexp = decode_private_key (priv); 1338 priv_sexp = decode_private_ecdsa_key (priv);
809 data = data_to_pkcs1 (purpose); 1339 data = data_to_ecdsa_value (purpose);
810 if (0 != (rc = gcry_pk_sign (&sig_sexp, data, priv_sexp))) 1340 if (0 != (rc = gcry_pk_sign (&sig_sexp, data, priv_sexp)))
811 { 1341 {
812 LOG (GNUNET_ERROR_TYPE_WARNING, 1342 LOG (GNUNET_ERROR_TYPE_WARNING,
@@ -837,6 +1367,56 @@ GNUNET_CRYPTO_ecc_sign (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
837 1367
838 1368
839/** 1369/**
1370 * Sign a given block.
1371 *
1372 * @param priv private key to use for the signing
1373 * @param purpose what to sign (size, purpose)
1374 * @param sig where to write the signature
1375 * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
1376 */
1377int
1378GNUNET_CRYPTO_eddsa_sign (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
1379 const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
1380 struct GNUNET_CRYPTO_EddsaSignature *sig)
1381{
1382 gcry_sexp_t priv_sexp;
1383 gcry_sexp_t sig_sexp;
1384 gcry_sexp_t data;
1385 int rc;
1386 gcry_mpi_t rs[2];
1387
1388 priv_sexp = decode_private_eddsa_key (priv);
1389 data = data_to_eddsa_value (purpose);
1390 if (0 != (rc = gcry_pk_sign (&sig_sexp, data, priv_sexp)))
1391 {
1392 LOG (GNUNET_ERROR_TYPE_WARNING,
1393 _("EdDSA signing failed at %s:%d: %s\n"), __FILE__,
1394 __LINE__, gcry_strerror (rc));
1395 gcry_sexp_release (data);
1396 gcry_sexp_release (priv_sexp);
1397 return GNUNET_SYSERR;
1398 }
1399 gcry_sexp_release (priv_sexp);
1400 gcry_sexp_release (data);
1401
1402 /* extract 'r' and 's' values from sexpression 'sig_sexp' and store in
1403 'signature' */
1404 if (0 != (rc = key_from_sexp (rs, sig_sexp, "sig-val", "rs")))
1405 {
1406 GNUNET_break (0);
1407 gcry_sexp_release (sig_sexp);
1408 return GNUNET_SYSERR;
1409 }
1410 gcry_sexp_release (sig_sexp);
1411 mpi_print (sig->r, sizeof (sig->r), rs[0]);
1412 mpi_print (sig->s, sizeof (sig->s), rs[1]);
1413 gcry_mpi_release (rs[0]);
1414 gcry_mpi_release (rs[1]);
1415 return GNUNET_OK;
1416}
1417
1418
1419/**
840 * Verify signature. 1420 * Verify signature.
841 * 1421 *
842 * @param purpose what is the purpose that the signature should have? 1422 * @param purpose what is the purpose that the signature should have?
@@ -846,11 +1426,10 @@ GNUNET_CRYPTO_ecc_sign (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
846 * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid 1426 * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid
847 */ 1427 */
848int 1428int
849GNUNET_CRYPTO_ecc_verify (uint32_t purpose, 1429GNUNET_CRYPTO_ecdsa_verify (uint32_t purpose,
850 const struct GNUNET_CRYPTO_EccSignaturePurpose 1430 const struct GNUNET_CRYPTO_EccSignaturePurpose *validate,
851 *validate, 1431 const struct GNUNET_CRYPTO_EcdsaSignature *sig,
852 const struct GNUNET_CRYPTO_EccSignature *sig, 1432 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
853 const struct GNUNET_CRYPTO_EccPublicSignKey *pub)
854{ 1433{
855 gcry_sexp_t data; 1434 gcry_sexp_t data;
856 gcry_sexp_t sig_sexpr; 1435 gcry_sexp_t sig_sexpr;
@@ -876,8 +1455,70 @@ GNUNET_CRYPTO_ecc_verify (uint32_t purpose,
876 } 1455 }
877 gcry_mpi_release (r); 1456 gcry_mpi_release (r);
878 gcry_mpi_release (s); 1457 gcry_mpi_release (s);
879 data = data_to_pkcs1 (validate); 1458 data = data_to_ecdsa_value (validate);
880 if (! (pub_sexpr = decode_public_sign_key (pub))) 1459 if (! (pub_sexpr = decode_public_ecdsa_key (pub)))
1460 {
1461 gcry_sexp_release (data);
1462 gcry_sexp_release (sig_sexpr);
1463 return GNUNET_SYSERR;
1464 }
1465 rc = gcry_pk_verify (sig_sexpr, data, pub_sexpr);
1466 gcry_sexp_release (pub_sexpr);
1467 gcry_sexp_release (data);
1468 gcry_sexp_release (sig_sexpr);
1469 if (0 != rc)
1470 {
1471 LOG (GNUNET_ERROR_TYPE_INFO,
1472 _("ECDSA signature verification failed at %s:%d: %s\n"), __FILE__,
1473 __LINE__, gcry_strerror (rc));
1474 return GNUNET_SYSERR;
1475 }
1476 return GNUNET_OK;
1477}
1478
1479
1480
1481/**
1482 * Verify signature.
1483 *
1484 * @param purpose what is the purpose that the signature should have?
1485 * @param validate block to validate (size, purpose, data)
1486 * @param sig signature that is being validated
1487 * @param pub public key of the signer
1488 * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid
1489 */
1490int
1491GNUNET_CRYPTO_eddsa_verify (uint32_t purpose,
1492 const struct GNUNET_CRYPTO_EccSignaturePurpose *validate,
1493 const struct GNUNET_CRYPTO_EddsaSignature *sig,
1494 const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
1495{
1496 gcry_sexp_t data;
1497 gcry_sexp_t sig_sexpr;
1498 gcry_sexp_t pub_sexpr;
1499 int rc;
1500 gcry_mpi_t r;
1501 gcry_mpi_t s;
1502
1503 if (purpose != ntohl (validate->purpose))
1504 return GNUNET_SYSERR; /* purpose mismatch */
1505
1506 /* build s-expression for signature */
1507 mpi_scan (&r, sig->r, sizeof (sig->r));
1508 mpi_scan (&s, sig->s, sizeof (sig->s));
1509 if (0 != (rc = gcry_sexp_build (&sig_sexpr, NULL,
1510 "(sig-val(eddsa(r %m)(s %m)))",
1511 r, s)))
1512 {
1513 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
1514 gcry_mpi_release (r);
1515 gcry_mpi_release (s);
1516 return GNUNET_SYSERR;
1517 }
1518 gcry_mpi_release (r);
1519 gcry_mpi_release (s);
1520 data = data_to_eddsa_value (validate);
1521 if (! (pub_sexpr = decode_public_eddsa_key (pub)))
881 { 1522 {
882 gcry_sexp_release (data); 1523 gcry_sexp_release (data);
883 gcry_sexp_release (sig_sexpr); 1524 gcry_sexp_release (sig_sexpr);
@@ -890,7 +1531,7 @@ GNUNET_CRYPTO_ecc_verify (uint32_t purpose,
890 if (0 != rc) 1531 if (0 != rc)
891 { 1532 {
892 LOG (GNUNET_ERROR_TYPE_INFO, 1533 LOG (GNUNET_ERROR_TYPE_INFO,
893 _("ECC signature verification failed at %s:%d: %s\n"), __FILE__, 1534 _("EdDSA signature verification failed at %s:%d: %s\n"), __FILE__,
894 __LINE__, gcry_strerror (rc)); 1535 __LINE__, gcry_strerror (rc));
895 return GNUNET_SYSERR; 1536 return GNUNET_SYSERR;
896 } 1537 }
@@ -906,7 +1547,7 @@ GNUNET_CRYPTO_ecc_verify (uint32_t purpose,
906 * @return NULL on error 1547 * @return NULL on error
907 */ 1548 */
908static gcry_sexp_t 1549static gcry_sexp_t
909decode_public_encrypt_key (const struct GNUNET_CRYPTO_EccPublicEncryptKey *pub) 1550decode_public_ecdhe_key (const struct GNUNET_CRYPTO_EcdhePublicKey *pub)
910{ 1551{
911 gcry_sexp_t pub_sexp; 1552 gcry_sexp_t pub_sexp;
912 gcry_mpi_t q_x; 1553 gcry_mpi_t q_x;
@@ -934,7 +1575,7 @@ decode_public_encrypt_key (const struct GNUNET_CRYPTO_EccPublicEncryptKey *pub)
934 1575
935 1576
936/** 1577/**
937 * Derive key material from a public and a private ECC key. 1578 * Derive key material from a public and a private ECDHE key.
938 * 1579 *
939 * @param priv private key to use for the ECDH (x) 1580 * @param priv private key to use for the ECDH (x)
940 * @param pub public key to use for the ECDH (yG) 1581 * @param pub public key to use for the ECDH (yG)
@@ -942,8 +1583,8 @@ decode_public_encrypt_key (const struct GNUNET_CRYPTO_EccPublicEncryptKey *pub)
942 * @return #GNUNET_SYSERR on error, #GNUNET_OK on success 1583 * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
943 */ 1584 */
944int 1585int
945GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EccPrivateKey *priv, 1586GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
946 const struct GNUNET_CRYPTO_EccPublicEncryptKey *pub, 1587 const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
947 struct GNUNET_HashCode *key_material) 1588 struct GNUNET_HashCode *key_material)
948{ 1589{
949 gcry_mpi_point_t result; 1590 gcry_mpi_point_t result;
@@ -956,7 +1597,7 @@ GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
956 unsigned char xbuf[256 / 8]; 1597 unsigned char xbuf[256 / 8];
957 1598
958 /* first, extract the q = dP value from the public key */ 1599 /* first, extract the q = dP value from the public key */
959 if (! (pub_sexpr = decode_public_encrypt_key (pub))) 1600 if (! (pub_sexpr = decode_public_ecdhe_key (pub)))
960 return GNUNET_SYSERR; 1601 return GNUNET_SYSERR;
961 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL)); 1602 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL));
962 gcry_sexp_release (pub_sexpr); 1603 gcry_sexp_release (pub_sexpr);
@@ -1003,7 +1644,7 @@ GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
1003 * @return h value 1644 * @return h value
1004 */ 1645 */
1005static gcry_mpi_t 1646static gcry_mpi_t
1006derive_h (const struct GNUNET_CRYPTO_EccPublicSignKey *pub, 1647derive_h (const struct GNUNET_CRYPTO_EcdsaPublicKey *pub,
1007 const char *label, 1648 const char *label,
1008 const char *context) 1649 const char *context)
1009{ 1650{
@@ -1033,13 +1674,13 @@ derive_h (const struct GNUNET_CRYPTO_EccPublicSignKey *pub,
1033 * typically the name of the subsystem/application 1674 * typically the name of the subsystem/application
1034 * @return derived private key 1675 * @return derived private key
1035 */ 1676 */
1036struct GNUNET_CRYPTO_EccPrivateKey * 1677struct GNUNET_CRYPTO_EcdsaPrivateKey *
1037GNUNET_CRYPTO_ecc_key_derive (const struct GNUNET_CRYPTO_EccPrivateKey *priv, 1678GNUNET_CRYPTO_ecdsa_private_key_derive (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
1038 const char *label, 1679 const char *label,
1039 const char *context) 1680 const char *context)
1040{ 1681{
1041 struct GNUNET_CRYPTO_EccPublicSignKey pub; 1682 struct GNUNET_CRYPTO_EcdsaPublicKey pub;
1042 struct GNUNET_CRYPTO_EccPrivateKey *ret; 1683 struct GNUNET_CRYPTO_EcdsaPrivateKey *ret;
1043 gcry_mpi_t h; 1684 gcry_mpi_t h;
1044 gcry_mpi_t x; 1685 gcry_mpi_t x;
1045 gcry_mpi_t d; 1686 gcry_mpi_t d;
@@ -1048,7 +1689,7 @@ GNUNET_CRYPTO_ecc_key_derive (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
1048 1689
1049 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE)); 1690 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE));
1050 n = gcry_mpi_ec_get_mpi ("n", ctx, 1); 1691 n = gcry_mpi_ec_get_mpi ("n", ctx, 1);
1051 GNUNET_CRYPTO_ecc_key_get_public_for_signature (priv, &pub); 1692 GNUNET_CRYPTO_ecdsa_key_get_public (priv, &pub);
1052 h = derive_h (&pub, label, context); 1693 h = derive_h (&pub, label, context);
1053 mpi_scan (&x, priv->d, sizeof (priv->d)); 1694 mpi_scan (&x, priv->d, sizeof (priv->d));
1054 d = gcry_mpi_new (256); 1695 d = gcry_mpi_new (256);
@@ -1057,7 +1698,7 @@ GNUNET_CRYPTO_ecc_key_derive (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
1057 gcry_mpi_release (x); 1698 gcry_mpi_release (x);
1058 gcry_mpi_release (n); 1699 gcry_mpi_release (n);
1059 gcry_ctx_release (ctx); 1700 gcry_ctx_release (ctx);
1060 ret = GNUNET_new (struct GNUNET_CRYPTO_EccPrivateKey); 1701 ret = GNUNET_new (struct GNUNET_CRYPTO_EcdsaPrivateKey);
1061 mpi_print (ret->d, sizeof (ret->d), d); 1702 mpi_print (ret->d, sizeof (ret->d), d);
1062 gcry_mpi_release (d); 1703 gcry_mpi_release (d);
1063 return ret; 1704 return ret;
@@ -1075,10 +1716,10 @@ GNUNET_CRYPTO_ecc_key_derive (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
1075 * @param result where to write the derived public key 1716 * @param result where to write the derived public key
1076 */ 1717 */
1077void 1718void
1078GNUNET_CRYPTO_ecc_public_key_derive (const struct GNUNET_CRYPTO_EccPublicSignKey *pub, 1719GNUNET_CRYPTO_ecdsa_public_key_derive (const struct GNUNET_CRYPTO_EcdsaPublicKey *pub,
1079 const char *label, 1720 const char *label,
1080 const char *context, 1721 const char *context,
1081 struct GNUNET_CRYPTO_EccPublicSignKey *result) 1722 struct GNUNET_CRYPTO_EcdsaPublicKey *result)
1082{ 1723{
1083 gcry_ctx_t ctx; 1724 gcry_ctx_t ctx;
1084 gcry_mpi_t h; 1725 gcry_mpi_t h;
@@ -1113,7 +1754,7 @@ GNUNET_CRYPTO_ecc_public_key_derive (const struct GNUNET_CRYPTO_EccPublicSignKey
1113 gcry_mpi_release (n); 1754 gcry_mpi_release (n);
1114 gcry_mpi_point_release (q); 1755 gcry_mpi_point_release (q);
1115 /* convert point 'v' to public key that we return */ 1756 /* convert point 'v' to public key that we return */
1116 point_to_public_sign_key (v, ctx, result); 1757 point_to_public_ecdsa_key (v, ctx, result);
1117 gcry_mpi_point_release (v); 1758 gcry_mpi_point_release (v);
1118 gcry_ctx_release (ctx); 1759 gcry_ctx_release (ctx);
1119} 1760}