aboutsummaryrefslogtreecommitdiff
path: root/src/util/crypto_ecc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/crypto_ecc.c')
-rw-r--r--src/util/crypto_ecc.c380
1 files changed, 95 insertions, 285 deletions
diff --git a/src/util/crypto_ecc.c b/src/util/crypto_ecc.c
index 9728084c9..2bd89c402 100644
--- a/src/util/crypto_ecc.c
+++ b/src/util/crypto_ecc.c
@@ -34,10 +34,8 @@
34 * structs that use 256 bits, so using a bigger curve will require 34 * structs that use 256 bits, so using a bigger curve will require
35 * changes that break stuff badly. The name of the curve given here 35 * changes that break stuff badly. The name of the curve given here
36 * must be agreed by all peers and be supported by libgcrypt. 36 * must be agreed by all peers and be supported by libgcrypt.
37 *
38 * NOTE: this will change to Curve25519 before GNUnet 0.10.0.
39 */ 37 */
40#define CURVE "NIST P-256" 38#define CURVE "Ed25519"
41 39
42#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) 40#define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__)
43 41
@@ -148,11 +146,31 @@ mpi_print (unsigned char *buf,
148{ 146{
149 size_t rsize; 147 size_t rsize;
150 148
151 rsize = size; 149 if (gcry_mpi_get_flag (val, GCRYMPI_FLAG_OPAQUE))
152 GNUNET_assert (0 == 150 {
153 gcry_mpi_print (GCRYMPI_FMT_USG, buf, rsize, &rsize, 151 /* Store opaque MPIs left aligned into the buffer. */
154 val)); 152 unsigned int nbits;
155 adjust (buf, rsize, size); 153 const void *p;
154
155 p = gcry_mpi_get_opaque (val, &nbits);
156 GNUNET_assert (p);
157 rsize = (nbits+7)/8;
158 if (rsize > size)
159 rsize = size;
160 memcpy (buf, p, rsize);
161 if (rsize < size)
162 memset (buf+rsize, 0, size - rsize);
163 }
164 else
165 {
166 /* Store regular MPIs as unsigned integers right aligned into
167 the buffer. */
168 rsize = size;
169 GNUNET_assert (0 ==
170 gcry_mpi_print (GCRYMPI_FMT_USG, buf, rsize, &rsize,
171 val));
172 adjust (buf, rsize, size);
173 }
156} 174}
157 175
158 176
@@ -191,16 +209,12 @@ static gcry_sexp_t
191decode_private_ecdsa_key (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv) 209decode_private_ecdsa_key (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv)
192{ 210{
193 gcry_sexp_t result; 211 gcry_sexp_t result;
194 gcry_mpi_t d;
195 int rc; 212 int rc;
196 213
197 mpi_scan (&d,
198 priv->d,
199 sizeof (priv->d));
200 rc = gcry_sexp_build (&result, NULL, 214 rc = gcry_sexp_build (&result, NULL,
201 "(private-key(ecdsa(curve \"" CURVE "\")(d %m)))", 215 "(private-key(ecc(curve \"" CURVE "\")"
202 d); 216 "(flags ecdsa)(d %b)))",
203 gcry_mpi_release (d); 217 (int)sizeof (priv->d), priv->d);
204 if (0 != rc) 218 if (0 != rc)
205 { 219 {
206 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); 220 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
@@ -228,16 +242,12 @@ static gcry_sexp_t
228decode_private_eddsa_key (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv) 242decode_private_eddsa_key (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
229{ 243{
230 gcry_sexp_t result; 244 gcry_sexp_t result;
231 gcry_mpi_t d;
232 int rc; 245 int rc;
233 246
234 mpi_scan (&d,
235 priv->d,
236 sizeof (priv->d));
237 rc = gcry_sexp_build (&result, NULL, 247 rc = gcry_sexp_build (&result, NULL,
238 "(private-key(ecdsa(curve \"" CURVE "\")(d %m)))", // FIXME: eddsa soon! 248 "(private-key(ecc(curve \"" CURVE "\")"
239 d); 249 "(d %b)))",
240 gcry_mpi_release (d); 250 (int)sizeof (priv->d), priv->d);
241 if (0 != rc) 251 if (0 != rc)
242 { 252 {
243 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); 253 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
@@ -265,16 +275,12 @@ static gcry_sexp_t
265decode_private_ecdhe_key (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv) 275decode_private_ecdhe_key (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv)
266{ 276{
267 gcry_sexp_t result; 277 gcry_sexp_t result;
268 gcry_mpi_t d;
269 int rc; 278 int rc;
270 279
271 mpi_scan (&d,
272 priv->d,
273 sizeof (priv->d));
274 rc = gcry_sexp_build (&result, NULL, 280 rc = gcry_sexp_build (&result, NULL,
275 "(private-key(ecdsa(curve \"" CURVE "\")(d %m)))", // FIXME: ecdh here? 281 "(private-key(ecc(curve \"" CURVE "\")"
276 d); 282 "(flags ecdsa)(d %b)))",
277 gcry_mpi_release (d); 283 (int)sizeof (priv->d), priv->d);
278 if (0 != rc) 284 if (0 != rc)
279 { 285 {
280 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); 286 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
@@ -292,99 +298,6 @@ decode_private_ecdhe_key (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv)
292 298
293 299
294/** 300/**
295 * Initialize public key struct from the respective point
296 * on the curve.
297 *
298 * @param q point on curve
299 * @param pub public key struct to initialize
300 * @param ctx context to use for ECC operations
301 */
302static void
303point_to_public_ecdsa_key (gcry_mpi_point_t q,
304 gcry_ctx_t ctx,
305 struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
306{
307 gcry_mpi_t q_x;
308 gcry_mpi_t q_y;
309
310 q_x = gcry_mpi_new (256);
311 q_y = gcry_mpi_new (256);
312 if (gcry_mpi_ec_get_affine (q_x, q_y, q, ctx))
313 {
314 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
315 return;
316 }
317
318 mpi_print (pub->q_x, sizeof (pub->q_x), q_x);
319 mpi_print (pub->q_y, sizeof (pub->q_y), q_y);
320 gcry_mpi_release (q_x);
321 gcry_mpi_release (q_y);
322}
323
324
325/**
326 * Initialize public key struct from the respective point
327 * on the curve.
328 *
329 * @param q point on curve
330 * @param pub public key struct to initialize
331 * @param ctx context to use for ECC operations
332 */
333static void
334point_to_public_eddsa_key (gcry_mpi_point_t q,
335 gcry_ctx_t ctx,
336 struct GNUNET_CRYPTO_EddsaPublicKey *pub)
337{
338 gcry_mpi_t q_x;
339 gcry_mpi_t q_y;
340
341 q_x = gcry_mpi_new (256);
342 q_y = gcry_mpi_new (256);
343 if (gcry_mpi_ec_get_affine (q_x, q_y, q, ctx))
344 {
345 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
346 return;
347 }
348
349 mpi_print (pub->q_x, sizeof (pub->q_x), q_x);
350 mpi_print (pub->q_y, sizeof (pub->q_y), q_y);
351 gcry_mpi_release (q_x);
352 gcry_mpi_release (q_y);
353}
354
355
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. 301 * Extract the public key for the given private key.
389 * 302 *
390 * @param priv the private key 303 * @param priv the private key
@@ -396,16 +309,17 @@ GNUNET_CRYPTO_ecdsa_key_get_public (const struct GNUNET_CRYPTO_EcdsaPrivateKey *
396{ 309{
397 gcry_sexp_t sexp; 310 gcry_sexp_t sexp;
398 gcry_ctx_t ctx; 311 gcry_ctx_t ctx;
399 gcry_mpi_point_t q; 312 gcry_mpi_t q;
400 313
401 sexp = decode_private_ecdsa_key (priv); 314 sexp = decode_private_ecdsa_key (priv);
402 GNUNET_assert (NULL != sexp); 315 GNUNET_assert (NULL != sexp);
403 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL)); 316 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL));
404 gcry_sexp_release (sexp); 317 gcry_sexp_release (sexp);
405 q = gcry_mpi_ec_get_point ("q", ctx, 0); 318 q = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0);
406 point_to_public_ecdsa_key (q, ctx, pub); 319 GNUNET_assert (q);
320 mpi_print (pub->q_y, sizeof (pub->q_y), q);
321 gcry_mpi_release (q);
407 gcry_ctx_release (ctx); 322 gcry_ctx_release (ctx);
408 gcry_mpi_point_release (q);
409} 323}
410 324
411 325
@@ -421,16 +335,17 @@ GNUNET_CRYPTO_eddsa_key_get_public (const struct GNUNET_CRYPTO_EddsaPrivateKey *
421{ 335{
422 gcry_sexp_t sexp; 336 gcry_sexp_t sexp;
423 gcry_ctx_t ctx; 337 gcry_ctx_t ctx;
424 gcry_mpi_point_t q; 338 gcry_mpi_t q;
425 339
426 sexp = decode_private_eddsa_key (priv); 340 sexp = decode_private_eddsa_key (priv);
427 GNUNET_assert (NULL != sexp); 341 GNUNET_assert (NULL != sexp);
428 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL)); 342 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL));
429 gcry_sexp_release (sexp); 343 gcry_sexp_release (sexp);
430 q = gcry_mpi_ec_get_point ("q", ctx, 0); 344 q = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0);
431 point_to_public_eddsa_key (q, ctx, pub); 345 GNUNET_assert (q);
346 mpi_print (pub->q_y, sizeof (pub->q_y), q);
347 gcry_mpi_release (q);
432 gcry_ctx_release (ctx); 348 gcry_ctx_release (ctx);
433 gcry_mpi_point_release (q);
434} 349}
435 350
436 351
@@ -446,16 +361,17 @@ GNUNET_CRYPTO_ecdhe_key_get_public (const struct GNUNET_CRYPTO_EcdhePrivateKey *
446{ 361{
447 gcry_sexp_t sexp; 362 gcry_sexp_t sexp;
448 gcry_ctx_t ctx; 363 gcry_ctx_t ctx;
449 gcry_mpi_point_t q; 364 gcry_mpi_t q;
450 365
451 sexp = decode_private_ecdhe_key (priv); 366 sexp = decode_private_ecdhe_key (priv);
452 GNUNET_assert (NULL != sexp); 367 GNUNET_assert (NULL != sexp);
453 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL)); 368 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL));
454 gcry_sexp_release (sexp); 369 gcry_sexp_release (sexp);
455 q = gcry_mpi_ec_get_point ("q", ctx, 0); 370 q = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0);
456 point_to_public_ecdhe_key (q, ctx, pub); 371 GNUNET_assert (q);
372 mpi_print (pub->q_y, sizeof (pub->q_y), q);
373 gcry_mpi_release (q);
457 gcry_ctx_release (ctx); 374 gcry_ctx_release (ctx);
458 gcry_mpi_point_release (q);
459} 375}
460 376
461 377
@@ -580,76 +496,6 @@ GNUNET_CRYPTO_eddsa_public_key_from_string (const char *enc,
580 496
581 497
582/** 498/**
583 * Convert the given public key from the network format to the
584 * S-expression that can be used by libgcrypt.
585 *
586 * @param pub public key to decode
587 * @return NULL on error
588 */
589static gcry_sexp_t
590decode_public_ecdsa_key (const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
591{
592 gcry_sexp_t pub_sexp;
593 gcry_mpi_t q_x;
594 gcry_mpi_t q_y;
595 gcry_mpi_point_t q;
596 gcry_ctx_t ctx;
597
598 mpi_scan (&q_x, pub->q_x, sizeof (pub->q_x));
599 mpi_scan (&q_y, pub->q_y, sizeof (pub->q_y));
600 q = gcry_mpi_point_new (256);
601 gcry_mpi_point_set (q, q_x, q_y, GCRYMPI_CONST_ONE);
602 gcry_mpi_release (q_x);
603 gcry_mpi_release (q_y);
604
605 /* initialize 'ctx' with 'q' */
606 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE)); // FIXME: need to say ECDSA?
607 gcry_mpi_ec_set_point ("q", q, ctx);
608 gcry_mpi_point_release (q);
609
610 /* convert 'ctx' to 'sexp' */
611 GNUNET_assert (0 == gcry_pubkey_get_sexp (&pub_sexp, GCRY_PK_GET_PUBKEY, ctx));
612 gcry_ctx_release (ctx);
613 return pub_sexp;
614}
615
616
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 499 * @ingroup crypto
654 * Clear memory that was used to store a private key. 500 * Clear memory that was used to store a private key.
655 * 501 *
@@ -703,7 +549,8 @@ GNUNET_CRYPTO_ecdhe_key_create ()
703 int rc; 549 int rc;
704 550
705 if (0 != (rc = gcry_sexp_build (&s_keyparam, NULL, 551 if (0 != (rc = gcry_sexp_build (&s_keyparam, NULL,
706 "(genkey(ecdsa(curve \"" CURVE "\")))"))) // FIXME: ECDHE? 552 "(genkey(ecc(curve \"" CURVE "\")"
553 "(flags noparam ecdsa)))")))
707 { 554 {
708 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); 555 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
709 return NULL; 556 return NULL;
@@ -752,7 +599,8 @@ GNUNET_CRYPTO_ecdsa_key_create ()
752 int rc; 599 int rc;
753 600
754 if (0 != (rc = gcry_sexp_build (&s_keyparam, NULL, 601 if (0 != (rc = gcry_sexp_build (&s_keyparam, NULL,
755 "(genkey(ecdsa(curve \"" CURVE "\")))"))) 602 "(genkey(ecc(curve \"" CURVE "\")"
603 "(flags noparam ecdsa)))")))
756 { 604 {
757 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); 605 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
758 return NULL; 606 return NULL;
@@ -800,7 +648,8 @@ GNUNET_CRYPTO_eddsa_key_create ()
800 int rc; 648 int rc;
801 649
802 if (0 != (rc = gcry_sexp_build (&s_keyparam, NULL, 650 if (0 != (rc = gcry_sexp_build (&s_keyparam, NULL,
803 "(genkey(ecdsa(curve \"" CURVE "\")))"))) // FIXME: EdDSA? 651 "(genkey(ecc(curve \"" CURVE "\")"
652 "(flags noparam)))")))
804 { 653 {
805 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); 654 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
806 return NULL; 655 return NULL;
@@ -1276,10 +1125,9 @@ data_to_eddsa_value (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose)
1276 1125
1277 GNUNET_CRYPTO_hash (purpose, ntohl (purpose->size), &hc); 1126 GNUNET_CRYPTO_hash (purpose, ntohl (purpose->size), &hc);
1278 if (0 != (rc = gcry_sexp_build (&data, NULL, 1127 if (0 != (rc = gcry_sexp_build (&data, NULL,
1279 "(data(flags rfc6979)(hash %s %b))", // FIXME: use EdDSA encoding! 1128 "(data(flags eddsa)(hash-algo %s)(value %b))",
1280 "sha512", 1129 "sha512",
1281 sizeof (hc), 1130 (int)sizeof (hc), &hc)))
1282 &hc)))
1283 { 1131 {
1284 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); 1132 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
1285 return NULL; 1133 return NULL;
@@ -1304,10 +1152,9 @@ data_to_ecdsa_value (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose)
1304 1152
1305 GNUNET_CRYPTO_hash (purpose, ntohl (purpose->size), &hc); 1153 GNUNET_CRYPTO_hash (purpose, ntohl (purpose->size), &hc);
1306 if (0 != (rc = gcry_sexp_build (&data, NULL, 1154 if (0 != (rc = gcry_sexp_build (&data, NULL,
1307 "(data(flags rfc6979)(hash %s %b))", 1155 "(data(flags ecdsa rfc6979)(hash %s %b))",
1308 "sha512", 1156 "sha512",
1309 sizeof (hc), 1157 (int)sizeof (hc), &hc)))
1310 &hc)))
1311 { 1158 {
1312 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); 1159 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
1313 return NULL; 1160 return NULL;
@@ -1435,28 +1282,23 @@ GNUNET_CRYPTO_ecdsa_verify (uint32_t purpose,
1435 gcry_sexp_t sig_sexpr; 1282 gcry_sexp_t sig_sexpr;
1436 gcry_sexp_t pub_sexpr; 1283 gcry_sexp_t pub_sexpr;
1437 int rc; 1284 int rc;
1438 gcry_mpi_t r;
1439 gcry_mpi_t s;
1440 1285
1441 if (purpose != ntohl (validate->purpose)) 1286 if (purpose != ntohl (validate->purpose))
1442 return GNUNET_SYSERR; /* purpose mismatch */ 1287 return GNUNET_SYSERR; /* purpose mismatch */
1443 1288
1444 /* build s-expression for signature */ 1289 /* build s-expression for signature */
1445 mpi_scan (&r, sig->r, sizeof (sig->r));
1446 mpi_scan (&s, sig->s, sizeof (sig->s));
1447 if (0 != (rc = gcry_sexp_build (&sig_sexpr, NULL, 1290 if (0 != (rc = gcry_sexp_build (&sig_sexpr, NULL,
1448 "(sig-val(ecdsa(r %m)(s %m)))", 1291 "(sig-val(ecdsa(r %b)(s %b)))",
1449 r, s))) 1292 (int)sizeof (sig->r), sig->r,
1293 (int)sizeof (sig->s), sig->s)))
1450 { 1294 {
1451 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); 1295 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
1452 gcry_mpi_release (r);
1453 gcry_mpi_release (s);
1454 return GNUNET_SYSERR; 1296 return GNUNET_SYSERR;
1455 } 1297 }
1456 gcry_mpi_release (r);
1457 gcry_mpi_release (s);
1458 data = data_to_ecdsa_value (validate); 1298 data = data_to_ecdsa_value (validate);
1459 if (! (pub_sexpr = decode_public_ecdsa_key (pub))) 1299 if (0 != (rc = gcry_sexp_build (&pub_sexpr, NULL,
1300 "(public-key(ecc(curve " CURVE ")(q %b)))",
1301 (int)sizeof (pub->q_y), pub->q_y)))
1460 { 1302 {
1461 gcry_sexp_release (data); 1303 gcry_sexp_release (data);
1462 gcry_sexp_release (sig_sexpr); 1304 gcry_sexp_release (sig_sexpr);
@@ -1497,28 +1339,23 @@ GNUNET_CRYPTO_eddsa_verify (uint32_t purpose,
1497 gcry_sexp_t sig_sexpr; 1339 gcry_sexp_t sig_sexpr;
1498 gcry_sexp_t pub_sexpr; 1340 gcry_sexp_t pub_sexpr;
1499 int rc; 1341 int rc;
1500 gcry_mpi_t r;
1501 gcry_mpi_t s;
1502 1342
1503 if (purpose != ntohl (validate->purpose)) 1343 if (purpose != ntohl (validate->purpose))
1504 return GNUNET_SYSERR; /* purpose mismatch */ 1344 return GNUNET_SYSERR; /* purpose mismatch */
1505 1345
1506 /* build s-expression for signature */ 1346 /* 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, 1347 if (0 != (rc = gcry_sexp_build (&sig_sexpr, NULL,
1510 "(sig-val(ecdsa(r %m)(s %m)))", // FIXME: eddsa soon... 1348 "(sig-val(eddsa(r %b)(s %b)))",
1511 r, s))) 1349 (int)sizeof (sig->r), sig->r,
1350 (int)sizeof (sig->s), sig->s)))
1512 { 1351 {
1513 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); 1352 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
1514 gcry_mpi_release (r);
1515 gcry_mpi_release (s);
1516 return GNUNET_SYSERR; 1353 return GNUNET_SYSERR;
1517 } 1354 }
1518 gcry_mpi_release (r);
1519 gcry_mpi_release (s);
1520 data = data_to_eddsa_value (validate); 1355 data = data_to_eddsa_value (validate);
1521 if (! (pub_sexpr = decode_public_eddsa_key (pub))) 1356 if (0 != (rc = gcry_sexp_build (&pub_sexpr, NULL,
1357 "(public-key(ecc(curve " CURVE ")(q %b)))",
1358 (int)sizeof (pub->q_y), pub->q_y)))
1522 { 1359 {
1523 gcry_sexp_release (data); 1360 gcry_sexp_release (data);
1524 gcry_sexp_release (sig_sexpr); 1361 gcry_sexp_release (sig_sexpr);
@@ -1540,41 +1377,6 @@ GNUNET_CRYPTO_eddsa_verify (uint32_t purpose,
1540 1377
1541 1378
1542/** 1379/**
1543 * Convert the given public key from the network format to the
1544 * S-expression that can be used by libgcrypt.
1545 *
1546 * @param pub public key to decode
1547 * @return NULL on error
1548 */
1549static gcry_sexp_t
1550decode_public_ecdhe_key (const struct GNUNET_CRYPTO_EcdhePublicKey *pub)
1551{
1552 gcry_sexp_t pub_sexp;
1553 gcry_mpi_t q_x;
1554 gcry_mpi_t q_y;
1555 gcry_mpi_point_t q;
1556 gcry_ctx_t ctx;
1557
1558 mpi_scan (&q_x, pub->q_x, sizeof (pub->q_x));
1559 mpi_scan (&q_y, pub->q_y, sizeof (pub->q_y));
1560 q = gcry_mpi_point_new (256);
1561 gcry_mpi_point_set (q, q_x, q_y, GCRYMPI_CONST_ONE);
1562 gcry_mpi_release (q_x);
1563 gcry_mpi_release (q_y);
1564
1565 /* initialize 'ctx' with 'q' */
1566 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE));
1567 gcry_mpi_ec_set_point ("q", q, ctx);
1568 gcry_mpi_point_release (q);
1569
1570 /* convert 'ctx' to 'sexp' */
1571 GNUNET_assert (0 == gcry_pubkey_get_sexp (&pub_sexp, GCRY_PK_GET_PUBKEY, ctx));
1572 gcry_ctx_release (ctx);
1573 return pub_sexp;
1574}
1575
1576
1577/**
1578 * Derive key material from a public and a private ECDHE key. 1380 * Derive key material from a public and a private ECDHE key.
1579 * 1381 *
1580 * @param priv private key to use for the ECDH (x) 1382 * @param priv private key to use for the ECDH (x)
@@ -1593,11 +1395,12 @@ GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
1593 gcry_ctx_t ctx; 1395 gcry_ctx_t ctx;
1594 gcry_sexp_t pub_sexpr; 1396 gcry_sexp_t pub_sexpr;
1595 gcry_mpi_t result_x; 1397 gcry_mpi_t result_x;
1596 gcry_mpi_t result_y;
1597 unsigned char xbuf[256 / 8]; 1398 unsigned char xbuf[256 / 8];
1598 1399
1599 /* first, extract the q = dP value from the public key */ 1400 /* first, extract the q = dP value from the public key */
1600 if (! (pub_sexpr = decode_public_ecdhe_key (pub))) 1401 if (0 != gcry_sexp_build (&pub_sexpr, NULL,
1402 "(public-key(ecc(curve " CURVE ")(q %b)))",
1403 (int)sizeof (pub->q_y), pub->q_y))
1601 return GNUNET_SYSERR; 1404 return GNUNET_SYSERR;
1602 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL)); 1405 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL));
1603 gcry_sexp_release (pub_sexpr); 1406 gcry_sexp_release (pub_sexpr);
@@ -1614,8 +1417,7 @@ GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
1614 1417
1615 /* finally, convert point to string for hashing */ 1418 /* finally, convert point to string for hashing */
1616 result_x = gcry_mpi_new (256); 1419 result_x = gcry_mpi_new (256);
1617 result_y = gcry_mpi_new (256); 1420 if (gcry_mpi_ec_get_affine (result_x, NULL, result, ctx))
1618 if (gcry_mpi_ec_get_affine (result_x, result_y, result, ctx))
1619 { 1421 {
1620 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0); 1422 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
1621 gcry_mpi_point_release (result); 1423 gcry_mpi_point_release (result);
@@ -1625,10 +1427,11 @@ GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
1625 gcry_mpi_point_release (result); 1427 gcry_mpi_point_release (result);
1626 gcry_ctx_release (ctx); 1428 gcry_ctx_release (ctx);
1627 1429
1430 /* FIXME: mpi_print creates an unsigned integer - is that intended
1431 or should we convert it to a signed integer (2-compl)? */
1628 mpi_print (xbuf, sizeof (xbuf), result_x); 1432 mpi_print (xbuf, sizeof (xbuf), result_x);
1629 GNUNET_CRYPTO_hash (xbuf, sizeof (xbuf), key_material); 1433 GNUNET_CRYPTO_hash (xbuf, sizeof (xbuf), key_material);
1630 gcry_mpi_release (result_x); 1434 gcry_mpi_release (result_x);
1631 gcry_mpi_release (result_y);
1632 return GNUNET_OK; 1435 return GNUNET_OK;
1633} 1436}
1634 1437
@@ -1688,8 +1491,10 @@ GNUNET_CRYPTO_ecdsa_private_key_derive (const struct GNUNET_CRYPTO_EcdsaPrivateK
1688 gcry_ctx_t ctx; 1491 gcry_ctx_t ctx;
1689 1492
1690 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE)); 1493 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE));
1494
1691 n = gcry_mpi_ec_get_mpi ("n", ctx, 1); 1495 n = gcry_mpi_ec_get_mpi ("n", ctx, 1);
1692 GNUNET_CRYPTO_ecdsa_key_get_public (priv, &pub); 1496 GNUNET_CRYPTO_ecdsa_key_get_public (priv, &pub);
1497
1693 h = derive_h (&pub, label, context); 1498 h = derive_h (&pub, label, context);
1694 mpi_scan (&x, priv->d, sizeof (priv->d)); 1499 mpi_scan (&x, priv->d, sizeof (priv->d));
1695 d = gcry_mpi_new (256); 1500 d = gcry_mpi_new (256);
@@ -1722,24 +1527,24 @@ GNUNET_CRYPTO_ecdsa_public_key_derive (const struct GNUNET_CRYPTO_EcdsaPublicKey
1722 struct GNUNET_CRYPTO_EcdsaPublicKey *result) 1527 struct GNUNET_CRYPTO_EcdsaPublicKey *result)
1723{ 1528{
1724 gcry_ctx_t ctx; 1529 gcry_ctx_t ctx;
1530 gcry_mpi_t q_y;
1725 gcry_mpi_t h; 1531 gcry_mpi_t h;
1726 gcry_mpi_t n; 1532 gcry_mpi_t n;
1727 gcry_mpi_t h_mod_n; 1533 gcry_mpi_t h_mod_n;
1728 gcry_mpi_t q_x;
1729 gcry_mpi_t q_y;
1730 gcry_mpi_point_t q; 1534 gcry_mpi_point_t q;
1731 gcry_mpi_point_t v; 1535 gcry_mpi_point_t v;
1732 1536
1733 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE)); 1537 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE));
1734 1538
1735 /* obtain point 'q' from original public key */ 1539 /* obtain point 'q' from original public key. The provided 'q' is
1736 mpi_scan (&q_x, pub->q_x, sizeof (pub->q_x)); 1540 compressed thus we first store it in the context and then get it
1737 mpi_scan (&q_y, pub->q_y, sizeof (pub->q_y)); 1541 back as a (decompresssed) point. */
1738 1542 q_y = gcry_mpi_set_opaque_copy (NULL, pub->q_y, 8*sizeof (pub->q_y));
1739 q = gcry_mpi_point_new (0); 1543 GNUNET_assert (q_y);
1740 gcry_mpi_point_set (q, q_x, q_y, GCRYMPI_CONST_ONE); 1544 GNUNET_assert (0 == gcry_mpi_ec_set_mpi ("q", q_y, ctx));
1741 gcry_mpi_release (q_x);
1742 gcry_mpi_release (q_y); 1545 gcry_mpi_release (q_y);
1546 q = gcry_mpi_ec_get_point ("q", ctx, 0);
1547 GNUNET_assert (q);
1743 1548
1744 /* calulcate h_mod_n = h % n */ 1549 /* calulcate h_mod_n = h % n */
1745 h = derive_h (pub, label, context); 1550 h = derive_h (pub, label, context);
@@ -1753,9 +1558,14 @@ GNUNET_CRYPTO_ecdsa_public_key_derive (const struct GNUNET_CRYPTO_EcdsaPublicKey
1753 gcry_mpi_release (h); 1558 gcry_mpi_release (h);
1754 gcry_mpi_release (n); 1559 gcry_mpi_release (n);
1755 gcry_mpi_point_release (q); 1560 gcry_mpi_point_release (q);
1561
1756 /* convert point 'v' to public key that we return */ 1562 /* convert point 'v' to public key that we return */
1757 point_to_public_ecdsa_key (v, ctx, result); 1563 GNUNET_assert (0 == gcry_mpi_ec_set_point ("q", v, ctx));
1758 gcry_mpi_point_release (v); 1564 gcry_mpi_point_release (v);
1565 q_y = gcry_mpi_ec_get_mpi ("q@eddsa", ctx, 0);
1566 GNUNET_assert (q_y);
1567 mpi_print (result->q_y, sizeof result->q_y, q_y);
1568 gcry_mpi_release (q_y);
1759 gcry_ctx_release (ctx); 1569 gcry_ctx_release (ctx);
1760} 1570}
1761 1571