GNUnet 0.28.0
 
Loading...
Searching...
No Matches
crypto_ecc.c File Reference

public key cryptography (ECC) with libgcrypt More...

#include "platform.h"
#include "gnunet_common.h"
#include <gcrypt.h>
#include <sodium.h>
#include <sodium/crypto_sign_ed25519.h>
#include "gnunet_util_lib.h"
#include "benchmark.h"
#include "sodium/crypto_scalarmult.h"
#include "sodium/crypto_scalarmult_curve25519.h"
#include "sodium/utils.h"
Include dependency graph for crypto_ecc.c:

Go to the source code of this file.

Macros

#define EXTRA_CHECKS   0
 
#define CURVE   "Ed25519"
 IMPLEMENTATION NOTICE:
 
#define LOG(kind, ...)   GNUNET_log_from (kind, "util-crypto-ecc", __VA_ARGS__)
 
#define LOG_STRERROR(kind, syscall)    GNUNET_log_from_strerror (kind, "util-crypto-ecc", syscall)
 
#define LOG_STRERROR_FILE(kind, syscall, filename)
 
#define LOG_GCRY(level, cmd, rc)
 Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the message given by gcry_strerror(rc).
 

Functions

static int key_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp, const char *topname, const char *elems)
 Extract values from an S-expression.
 
static gcry_sexp_t decode_private_ecdsa_key (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv)
 Convert the given private key from the network format to the S-expression that can be used by libgcrypt.
 
void GNUNET_CRYPTO_ecdsa_key_get_public (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
 Derive key.
 
void GNUNET_CRYPTO_eddsa_key_get_public (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
 Extract the public key for the given private key.
 
void GNUNET_CRYPTO_ecdhe_key_get_public (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, struct GNUNET_CRYPTO_EcdhePublicKey *pub)
 Extract the public key for the given private key.
 
char * GNUNET_CRYPTO_ecdsa_public_key_to_string (const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
 Convert a public key to a string.
 
char * GNUNET_CRYPTO_eddsa_public_key_to_string (const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
 Convert a public key to a string.
 
char * GNUNET_CRYPTO_eddsa_private_key_to_string (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
 Convert a private key to a string.
 
char * GNUNET_CRYPTO_ecdsa_private_key_to_string (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv)
 Convert a private key to a string.
 
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdsa_public_key_from_string (const char *enc, size_t enclen, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
 Convert a string representing a public key to a public key.
 
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_public_key_from_string (const char *enc, size_t enclen, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
 Convert a string representing a public key to a public key.
 
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_private_key_from_string (const char *enc, size_t enclen, struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
 Convert a string representing a private key to a private key.
 
static void buffer_clear (void *buf, size_t len)
 
void GNUNET_CRYPTO_ecdhe_key_clear (struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
 Clear memory that was used to store a private key.
 
void GNUNET_CRYPTO_ecdsa_key_clear (struct GNUNET_CRYPTO_EcdsaPrivateKey *pk)
 Clear memory that was used to store a private key.
 
void GNUNET_CRYPTO_eddsa_key_clear (struct GNUNET_CRYPTO_EddsaPrivateKey *pk)
 Clear memory that was used to store a private key.
 
void GNUNET_CRYPTO_ecdhe_key_create (struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
 Create a new private key.
 
void GNUNET_CRYPTO_ecdsa_key_create (struct GNUNET_CRYPTO_EcdsaPrivateKey *pk)
 Create a new private key.
 
void GNUNET_CRYPTO_eddsa_key_create (struct GNUNET_CRYPTO_EddsaPrivateKey *pk)
 Create a new private key.
 
const struct GNUNET_CRYPTO_EcdsaPrivateKeyGNUNET_CRYPTO_ecdsa_key_get_anonymous ()
 Get the shared private key we use for anonymous users.
 
const struct GNUNET_CRYPTO_EddsaPrivateKeyGNUNET_CRYPTO_eddsa_key_get_anonymous ()
 Get the shared private key we use for anonymous users.
 
static gcry_sexp_t data_to_ecdsa_value (const struct GNUNET_CRYPTO_SignaturePurpose *purpose)
 Convert the data specified in the given purpose argument to an S-expression suitable for signature operations.
 
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdsa_sign_ (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, const struct GNUNET_CRYPTO_SignaturePurpose *purpose, struct GNUNET_CRYPTO_EcdsaSignature *sig)
 ECDSA Sign a given block.
 
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_sign_raw (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, void *data, size_t size, struct GNUNET_CRYPTO_EddsaSignature *sig)
 
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_sign_ (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_SignaturePurpose *purpose, struct GNUNET_CRYPTO_EddsaSignature *sig)
 EdDSA sign a given block.
 
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdsa_verify_ (uint32_t purpose, const struct GNUNET_CRYPTO_SignaturePurpose *validate, const struct GNUNET_CRYPTO_EcdsaSignature *sig, const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
 Verify ECDSA signature.
 
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_verify_ (uint32_t purpose, const struct GNUNET_CRYPTO_SignaturePurpose *validate, const struct GNUNET_CRYPTO_EddsaSignature *sig, const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
 Verify EdDSA signature.
 
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material)
 Derive key material from a public and a private ECC key.
 
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_ecdh (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material)
 Derive key material from a ECDH public key and a private EdDSA key.
 
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_x25519_ecdh (const struct GNUNET_CRYPTO_EcdhePrivateKey *sk, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_CRYPTO_EcdhePublicKey *dh)
 Derive key material from a ECDH public key and a private X25519 key.
 
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdh_x25519 (const struct GNUNET_CRYPTO_EcdhePrivateKey *sk, const struct GNUNET_CRYPTO_EcdhePublicKey *pk, struct GNUNET_CRYPTO_EcdhePublicKey *dh)
 Derive key material from a EdDSA public key and a private ECDH key.
 
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdsa_ecdh (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material)
 HPKE END.
 
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdh_eddsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EddsaPublicKey *pub, struct GNUNET_HashCode *key_material)
 Derive key material from a EdDSA public key and a private ECDH key.
 
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdh_ecdsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, struct GNUNET_HashCode *key_material)
 Derive key material from a EcDSA public key and a private ECDH key.
 

Detailed Description

public key cryptography (ECC) with libgcrypt

Author
Christian Grothoff
Florian Dold

Definition in file crypto_ecc.c.

Macro Definition Documentation

◆ EXTRA_CHECKS

#define EXTRA_CHECKS   0

Definition at line 38 of file crypto_ecc.c.

◆ CURVE

#define CURVE   "Ed25519"

IMPLEMENTATION NOTICE:

ECDSA: We use a non-standard curve for ECDSA: Ed25519. For performance reasons, we use cryptographic operations from libsodium wherever we can get away with it, even though libsodium itself does not support ECDSA. This is why the sign and verify functionality from libgcrypt is required and used.

EdDSA: We use a standard EdDSA construction. (We still use libgcrypt for hashing and RNG, but not EC)

ECDHE: For both EdDSA and ECDSA keys, we use libsodium for ECDHE due to performance benefits over libgcrypt. Name of the curve we are using. Note that we have hard-coded structs that use 256 bits, so using a bigger curve will require changes that break stuff badly. The name of the curve given here must be agreed by all peers and be supported by libgcrypt.

Definition at line 63 of file crypto_ecc.c.

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "util-crypto-ecc", __VA_ARGS__)

Definition at line 65 of file crypto_ecc.c.

◆ LOG_STRERROR

#define LOG_STRERROR (   kind,
  syscall 
)     GNUNET_log_from_strerror (kind, "util-crypto-ecc", syscall)

Definition at line 67 of file crypto_ecc.c.

80 { \
81 LOG (level, \
82 _ ("`%s' failed at %s:%d with error: %s\n"), \
83 cmd, \
84 __FILE__, \
85 __LINE__, \
86 gcry_strerror (rc)); \
87 } while (0)
88
89
99static int
100key_from_sexp (gcry_mpi_t *array,
101 gcry_sexp_t sexp,
102 const char *topname,
103 const char *elems)
104{
105 gcry_sexp_t list;
106 gcry_sexp_t l2;
107 unsigned int idx;
108
109 list = gcry_sexp_find_token (sexp, topname, 0);
110 if (! list)
111 return 1;
112 l2 = gcry_sexp_cadr (list);
113 gcry_sexp_release (list);
114 list = l2;
115 if (! list)
116 return 2;
117
118 idx = 0;
119 for (const char *s = elems; *s; s++, idx++)
120 {
121 l2 = gcry_sexp_find_token (list, s, 1);
122 if (! l2)
123 {
124 for (unsigned int i = 0; i < idx; i++)
125 {
126 gcry_free (array[i]);
127 array[i] = NULL;
128 }
129 gcry_sexp_release (list);
130 return 3; /* required parameter not found */
131 }
132 array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
133 gcry_sexp_release (l2);
134 if (! array[idx])
135 {
136 for (unsigned int i = 0; i < idx; i++)
137 {
138 gcry_free (array[i]);
139 array[i] = NULL;
140 }
141 gcry_sexp_release (list);
142 return 4; /* required parameter is invalid */
143 }
144 }
145 gcry_sexp_release (list);
146 return 0;
147}
148
149
157static gcry_sexp_t
159{
160 gcry_sexp_t result;
161 int rc;
162 uint8_t d[32];
163
164 for (size_t i = 0; i<32; i++)
165 d[i] = priv->d[31 - i];
166
167 rc = gcry_sexp_build (&result,
168 NULL,
169 "(private-key(ecc(curve \"" CURVE "\")"
170 "(d %b)))",
171 32,
172 d);
173 if (0 != rc)
174 {
175 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
176 GNUNET_assert (0);
177 }
178#if EXTRA_CHECKS
179 if (0 != (rc = gcry_pk_testkey (result)))
180 {
181 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
182 GNUNET_assert (0);
183 }
184#endif
185 return result;
186}
187
188
189void
191 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
193{
194 BENCHMARK_START (ecdsa_key_get_public);
195 crypto_scalarmult_ed25519_base_noclamp (pub->q_y, priv->d);
196 BENCHMARK_END (ecdsa_key_get_public);
197}
198
199
200void
202 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
204{
205 unsigned char pk[crypto_sign_PUBLICKEYBYTES];
206 unsigned char sk[crypto_sign_SECRETKEYBYTES];
207
208 BENCHMARK_START (eddsa_key_get_public);
209 GNUNET_assert (0 == crypto_sign_seed_keypair (pk, sk, priv->d));
210 GNUNET_memcpy (pub->q_y, pk, crypto_sign_PUBLICKEYBYTES);
211 sodium_memzero (sk, crypto_sign_SECRETKEYBYTES);
212 BENCHMARK_END (eddsa_key_get_public);
213}
214
215
216void
218 const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
220{
221 BENCHMARK_START (ecdhe_key_get_public);
222 GNUNET_assert (0 == crypto_scalarmult_base (pub->q_y, priv->d));
223 BENCHMARK_END (ecdhe_key_get_public);
224}
225
226
227char *
229 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
230{
231 char *pubkeybuf;
232 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8;
233 char *end;
234
235 if (keylen % 5 > 0)
236 keylen += 5 - keylen % 5;
237 keylen /= 5;
238 pubkeybuf = GNUNET_malloc (keylen + 1);
239 end =
240 GNUNET_STRINGS_data_to_string ((unsigned char *) pub,
241 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
242 pubkeybuf,
243 keylen);
244 if (NULL == end)
245 {
246 GNUNET_free (pubkeybuf);
247 return NULL;
248 }
249 *end = '\0';
250 return pubkeybuf;
251}
252
253
254char *
256 const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
257{
258 char *pubkeybuf;
259 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)) * 8;
260 char *end;
261
262 if (keylen % 5 > 0)
263 keylen += 5 - keylen % 5;
264 keylen /= 5;
265 pubkeybuf = GNUNET_malloc (keylen + 1);
266 end =
267 GNUNET_STRINGS_data_to_string ((unsigned char *) pub,
268 sizeof(struct GNUNET_CRYPTO_EddsaPublicKey),
269 pubkeybuf,
270 keylen);
271 if (NULL == end)
272 {
273 GNUNET_free (pubkeybuf);
274 return NULL;
275 }
276 *end = '\0';
277 return pubkeybuf;
278}
279
280
281char *
283 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
284{
285 char *privkeybuf;
286 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EddsaPrivateKey)) * 8;
287 char *end;
288
289 if (keylen % 5 > 0)
290 keylen += 5 - keylen % 5;
291 keylen /= 5;
292 privkeybuf = GNUNET_malloc (keylen + 1);
293 end = GNUNET_STRINGS_data_to_string ((unsigned char *) priv,
294 sizeof(
296 privkeybuf,
297 keylen);
298 if (NULL == end)
299 {
300 GNUNET_free (privkeybuf);
301 return NULL;
302 }
303 *end = '\0';
304 return privkeybuf;
305}
306
307
308char *
310 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv)
311{
312 char *privkeybuf;
313 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EcdsaPrivateKey)) * 8;
314 char *end;
315
316 if (keylen % 5 > 0)
317 keylen += 5 - keylen % 5;
318 keylen /= 5;
319 privkeybuf = GNUNET_malloc (keylen + 1);
320 end = GNUNET_STRINGS_data_to_string ((unsigned char *) priv,
321 sizeof(
323 privkeybuf,
324 keylen);
325 if (NULL == end)
326 {
327 GNUNET_free (privkeybuf);
328 return NULL;
329 }
330 *end = '\0';
331 return privkeybuf;
332}
333
334
337 const char *enc,
338 size_t enclen,
340{
341 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8;
342
343 if (keylen % 5 > 0)
344 keylen += 5 - keylen % 5;
345 keylen /= 5;
346 if (enclen != keylen)
347 return GNUNET_SYSERR;
348
349 if (GNUNET_OK !=
351 enclen,
352 pub,
353 sizeof(
355 return GNUNET_SYSERR;
356 return GNUNET_OK;
357}
358
359
362 const char *enc,
363 size_t enclen,
365{
366 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)) * 8;
367
368 if (keylen % 5 > 0)
369 keylen += 5 - keylen % 5;
370 keylen /= 5;
371 if (enclen != keylen)
372 return GNUNET_SYSERR;
373
374 if (GNUNET_OK !=
376 enclen,
377 pub,
378 sizeof(
380 return GNUNET_SYSERR;
381 return GNUNET_OK;
382}
383
384
387 const char *enc,
388 size_t enclen,
390{
391 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EddsaPrivateKey)) * 8;
392
393 if (keylen % 5 > 0)
394 keylen += 5 - keylen % 5;
395 keylen /= 5;
396 if (enclen != keylen)
397 return GNUNET_SYSERR;
398
399 if (GNUNET_OK !=
401 enclen,
402 priv,
403 sizeof(
405 return GNUNET_SYSERR;
406#if CRYPTO_BUG
407 if (GNUNET_OK != check_eddsa_key (priv))
408 {
409 GNUNET_break (0);
410 return GNUNET_OK;
411 }
412#endif
413 return GNUNET_OK;
414}
415
416
417static void
418buffer_clear (void *buf, size_t len)
419{
420#if HAVE_MEMSET_S
421 memset_s (buf, len, 0, len);
422#elif HAVE_EXPLICIT_BZERO
423 explicit_bzero (buf, len);
424#else
425 volatile unsigned char *p = buf;
426 while (len--)
427 *p++ = 0;
428#endif
429}
430
431
432void
434{
436}
437
438
439void
441{
443}
444
445
446void
448{
450}
451
452
453void
455{
456 BENCHMARK_START (ecdhe_key_create);
458 sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey));
459 BENCHMARK_END (ecdhe_key_create);
460}
461
462
463void
465{
466 BENCHMARK_START (ecdsa_key_create);
468 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey));
469 pk->d[0] &= 248;
470 pk->d[31] &= 127;
471 pk->d[31] |= 64;
472
473 BENCHMARK_END (ecdsa_key_create);
474}
475
476
477void
479{
480 BENCHMARK_START (eddsa_key_create);
481 /*
482 * We do not clamp for EdDSA, since all functions that use the private key do
483 * their own clamping (just like in libsodium). What we call "private key"
484 * here, actually corresponds to the seed in libsodium.
485 *
486 * (Contrast this to ECDSA, where functions using the private key can't clamp
487 * due to properties needed for GNS. That is a worse/unsafter API, but
488 * required for the GNS constructions to work.)
489 */
491 sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey));
492 BENCHMARK_END (eddsa_key_create);
493}
494
495
498{
503 static struct GNUNET_CRYPTO_EcdsaPrivateKey anonymous;
504 static int once;
505
506 if (once)
507 return &anonymous;
509 sizeof(anonymous.d),
510 GCRYMPI_CONST_ONE);
511 anonymous.d[0] &= 248;
512 anonymous.d[31] &= 127;
513 anonymous.d[31] |= 64;
514
515 once = 1;
516 return &anonymous;
517}
518
519
522{
527 static struct GNUNET_CRYPTO_EddsaPrivateKey anonymous;
528 static int once;
529
530 if (once)
531 return &anonymous;
532
533 memset (anonymous.d, 0, sizeof(anonymous.d));
534
535 // Set the first byte to 1 (Little-Endian representation of 1)
536 anonymous.d[0] = 1;
537
538 once = 1;
539 return &anonymous;
540}
541
542
550static gcry_sexp_t
552{
553 gcry_sexp_t data;
554 int rc;
555 /* Unlike EdDSA, libgcrypt expects a hash for ECDSA. */
556 struct GNUNET_HashCode hc;
557
558 GNUNET_CRYPTO_hash (purpose, ntohl (purpose->size), &hc);
559 if (0 != (rc = gcry_sexp_build (&data,
560 NULL,
561 "(data(flags rfc6979)(hash %s %b))",
562 "sha512",
563 (int) sizeof(hc),
564 &hc)))
565 {
566 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
567 return NULL;
568 }
569 return data;
570}
571
572
575 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
576 const struct GNUNET_CRYPTO_SignaturePurpose *purpose,
578{
579 gcry_sexp_t priv_sexp;
580 gcry_sexp_t sig_sexp;
581 gcry_sexp_t data;
582 int rc;
583 gcry_mpi_t rs[2];
584
585 BENCHMARK_START (ecdsa_sign);
586
587 priv_sexp = decode_private_ecdsa_key (priv);
588 data = data_to_ecdsa_value (purpose);
589 if (0 != (rc = gcry_pk_sign (&sig_sexp, data, priv_sexp)))
590 {
592 _ ("ECC signing failed at %s:%d: %s\n"),
593 __FILE__,
594 __LINE__,
595 gcry_strerror (rc));
596 gcry_sexp_release (data);
597 gcry_sexp_release (priv_sexp);
598 return GNUNET_SYSERR;
599 }
600 gcry_sexp_release (priv_sexp);
601 gcry_sexp_release (data);
602
603 /* extract 'r' and 's' values from sexpression 'sig_sexp' and store in
604 'signature' */
605 if (0 != (rc = key_from_sexp (rs, sig_sexp, "sig-val", "rs")))
606 {
607 GNUNET_break (0);
608 gcry_sexp_release (sig_sexp);
609 return GNUNET_SYSERR;
610 }
611 gcry_sexp_release (sig_sexp);
612 GNUNET_CRYPTO_mpi_print_unsigned (sig->r, sizeof(sig->r), rs[0]);
613 GNUNET_CRYPTO_mpi_print_unsigned (sig->s, sizeof(sig->s), rs[1]);
614 gcry_mpi_release (rs[0]);
615 gcry_mpi_release (rs[1]);
616
617 BENCHMARK_END (ecdsa_sign);
618
619 return GNUNET_OK;
620}
621
622
625 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
626 void *data,
627 size_t size,
629{
630 unsigned char sk[crypto_sign_SECRETKEYBYTES];
631 unsigned char pk[crypto_sign_PUBLICKEYBYTES];
632 int res;
633
634 GNUNET_assert (0 == crypto_sign_seed_keypair (pk, sk, priv->d));
635 res = crypto_sign_detached ((uint8_t *) sig,
636 NULL,
637 (uint8_t *) data,
638 size,
639 sk);
640 return (res == 0) ? GNUNET_OK : GNUNET_SYSERR;
641}
642
643
646 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
647 const struct GNUNET_CRYPTO_SignaturePurpose *purpose,
649{
650
651 size_t mlen = ntohl (purpose->size);
652 unsigned char sk[crypto_sign_SECRETKEYBYTES];
653 unsigned char pk[crypto_sign_PUBLICKEYBYTES];
654 int res;
655
656 BENCHMARK_START (eddsa_sign);
657 GNUNET_assert (0 == crypto_sign_seed_keypair (pk, sk, priv->d));
658 res = crypto_sign_detached ((uint8_t *) sig,
659 NULL,
660 (uint8_t *) purpose,
661 mlen,
662 sk);
663 BENCHMARK_END (eddsa_sign);
664 return (res == 0) ? GNUNET_OK : GNUNET_SYSERR;
665}
666
667
670 uint32_t purpose,
671 const struct GNUNET_CRYPTO_SignaturePurpose *validate,
672 const struct GNUNET_CRYPTO_EcdsaSignature *sig,
673 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
674{
675 gcry_sexp_t data;
676 gcry_sexp_t sig_sexpr;
677 gcry_sexp_t pub_sexpr;
678 int rc;
679
680 BENCHMARK_START (ecdsa_verify);
681
682 if (purpose != ntohl (validate->purpose))
683 return GNUNET_SYSERR; /* purpose mismatch */
684
685 /* build s-expression for signature */
686 if (0 != (rc = gcry_sexp_build (&sig_sexpr,
687 NULL,
688 "(sig-val(ecdsa(r %b)(s %b)))",
689 (int) sizeof(sig->r),
690 sig->r,
691 (int) sizeof(sig->s),
692 sig->s)))
693 {
694 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
695 return GNUNET_SYSERR;
696 }
697 data = data_to_ecdsa_value (validate);
698 if (0 != (rc = gcry_sexp_build (&pub_sexpr,
699 NULL,
700 "(public-key(ecc(curve " CURVE ")(q %b)))",
701 (int) sizeof(pub->q_y),
702 pub->q_y)))
703 {
704 gcry_sexp_release (data);
705 gcry_sexp_release (sig_sexpr);
706 return GNUNET_SYSERR;
707 }
708 rc = gcry_pk_verify (sig_sexpr, data, pub_sexpr);
709 gcry_sexp_release (pub_sexpr);
710 gcry_sexp_release (data);
711 gcry_sexp_release (sig_sexpr);
712 if (0 != rc)
713 {
715 _ ("ECDSA signature verification failed at %s:%d: %s\n"),
716 __FILE__,
717 __LINE__,
718 gcry_strerror (rc));
719 BENCHMARK_END (ecdsa_verify);
720 return GNUNET_SYSERR;
721 }
722 BENCHMARK_END (ecdsa_verify);
723 return GNUNET_OK;
724}
725
726
729 uint32_t purpose,
730 const struct GNUNET_CRYPTO_SignaturePurpose *validate,
731 const struct GNUNET_CRYPTO_EddsaSignature *sig,
732 const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
733{
734 const unsigned char *m = (const void *) validate;
735 size_t mlen = ntohl (validate->size);
736 const unsigned char *s = (const void *) sig;
737
738 int res;
739
740 if (purpose != ntohl (validate->purpose))
741 return GNUNET_SYSERR; /* purpose mismatch */
742
743 BENCHMARK_START (eddsa_verify);
744
745 res = crypto_sign_verify_detached (s, m, mlen, pub->q_y);
746 BENCHMARK_END (eddsa_verify);
747 return (res == 0) ? GNUNET_OK : GNUNET_SYSERR;
748}
749
750
753 const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
754 struct GNUNET_HashCode *key_material)
755{
756 uint8_t p[crypto_scalarmult_BYTES];
757 if (0 != crypto_scalarmult (p, priv->d, pub->q_y))
758 return GNUNET_SYSERR;
759 GNUNET_CRYPTO_hash (p, crypto_scalarmult_BYTES, key_material);
760 return GNUNET_OK;
761}
762
763
766 const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
767 struct GNUNET_HashCode *key_material)
768{
769 struct GNUNET_HashCode hc;
770 uint8_t a[crypto_scalarmult_SCALARBYTES];
771 uint8_t p[crypto_scalarmult_BYTES];
772
773 GNUNET_CRYPTO_hash (priv,
774 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey),
775 &hc);
776 memcpy (a, &hc, sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey));
777 if (0 != crypto_scalarmult (p, a, pub->q_y))
778 return GNUNET_SYSERR;
780 crypto_scalarmult_BYTES,
781 key_material);
782 return GNUNET_OK;
783}
784
785
788 const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
790{
791 uint64_t checkbyte = 0;
792 size_t num_words = sizeof *dh / sizeof (uint64_t);
793 if (0 != crypto_scalarmult_curve25519 (dh->q_y, sk->d, pub->q_y))
794 return GNUNET_SYSERR;
795 // We need to check if this is the all-zero value
796 for (int i = 0; i < num_words; i++)
797 checkbyte |= ((uint64_t*) dh)[i];
798 return (0 == checkbyte) ? GNUNET_SYSERR : GNUNET_OK;
799}
800
801
804 const struct GNUNET_CRYPTO_EcdhePublicKey *pk,
806{
807 uint64_t checkbyte = 0;
808 size_t num_words = sizeof *dh / sizeof (uint64_t);
809 if (0 != crypto_scalarmult_curve25519 (dh->q_y, sk->d, pk->q_y))
810 return GNUNET_SYSERR;
811 // We need to check if this is the all-zero value
812 for (int i = 0; i < num_words; i++)
813 checkbyte |= ((uint64_t*) dh)[i];
814 if (0 == checkbyte)
815 {
817 "HPKE ECDH: X25519 all zero value!\n");
818 return GNUNET_SYSERR;
819 }
820 return GNUNET_OK;
821}
822
823
826 const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
827 struct GNUNET_HashCode *key_material)
828{
829 uint8_t p[crypto_scalarmult_BYTES];
830
831 BENCHMARK_START (ecdsa_ecdh);
832 if (0 != crypto_scalarmult (p, priv->d, pub->q_y))
833 return GNUNET_SYSERR;
835 crypto_scalarmult_BYTES,
836 key_material);
837 BENCHMARK_END (ecdsa_ecdh);
838 return GNUNET_OK;
839}
840
841
844 const struct GNUNET_CRYPTO_EddsaPublicKey *pub,
845 struct GNUNET_HashCode *key_material)
846{
847 uint8_t p[crypto_scalarmult_BYTES];
848 uint8_t curve25510_pk[crypto_scalarmult_BYTES];
849
850 if (0 != crypto_sign_ed25519_pk_to_curve25519 (curve25510_pk, pub->q_y))
851 return GNUNET_SYSERR;
852 if (0 != crypto_scalarmult (p, priv->d, curve25510_pk))
853 return GNUNET_SYSERR;
854 GNUNET_CRYPTO_hash (p, crypto_scalarmult_BYTES, key_material);
855 return GNUNET_OK;
856}
857
858
861 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub,
862 struct GNUNET_HashCode *key_material)
863{
864 uint8_t p[crypto_scalarmult_BYTES];
865 uint8_t curve25510_pk[crypto_scalarmult_BYTES];
866
867 if (0 != crypto_sign_ed25519_pk_to_curve25519 (curve25510_pk, pub->q_y))
868 return GNUNET_SYSERR;
869 if (0 != crypto_scalarmult (p, priv->d, curve25510_pk))
870 return GNUNET_SYSERR;
871 GNUNET_CRYPTO_hash (p, crypto_scalarmult_BYTES, key_material);
872 return GNUNET_OK;
873}
874
875
876/* end of crypto_ecc.c */
#define BENCHMARK_START(opname)
Definition benchmark.h:57
#define BENCHMARK_END(opname)
Definition benchmark.h:58
static int key_from_sexp(gcry_mpi_t *array, gcry_sexp_t sexp, const char *topname, const char *elems)
Extract values from an S-expression.
Definition crypto_ecc.c:101
#define CURVE
IMPLEMENTATION NOTICE:
Definition crypto_ecc.c:63
static void buffer_clear(void *buf, size_t len)
Definition crypto_ecc.c:419
#define LOG_GCRY(level, cmd, rc)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...
Definition crypto_ecc.c:79
static gcry_sexp_t data_to_ecdsa_value(const struct GNUNET_CRYPTO_SignaturePurpose *purpose)
Convert the data specified in the given purpose argument to an S-expression suitable for signature op...
Definition crypto_ecc.c:552
#define LOG(kind,...)
Definition crypto_ecc.c:65
static gcry_sexp_t decode_private_ecdsa_key(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv)
Convert the given private key from the network format to the S-expression that can be used by libgcry...
Definition crypto_ecc.c:159
static mp_limb_t d[(((256)+GMP_NUMB_BITS - 1)/GMP_NUMB_BITS)]
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition gnunet-arm.c:103
static int list
Set if we should print a list of currently running services.
Definition gnunet-arm.c:68
static int end
Set if we are to shutdown all services (including ARM).
Definition gnunet-arm.c:33
static char * data
The data to insert into the dht.
static OpusEncoder * enc
OPUS encoder.
struct GNUNET_CRYPTO_BlindablePrivateKey pk
Private key from command line option, or NULL.
static char * res
Currently read line or NULL on EOF.
static int once
Option -i.
Definition gnunet-pils.c:39
static int result
Global testing status.
static struct GNUNET_CRYPTO_EddsaPublicKey pub
static struct GNUNET_Process * p
Helper process we started.
Definition gnunet-uri.c:38
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecc_ecdh(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a public and a private ECC key.
Definition crypto_ecc.c:753
void GNUNET_CRYPTO_ecdhe_key_create(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Create a new private key.
Definition crypto_ecc.c:455
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_verify_(uint32_t purpose, const struct GNUNET_CRYPTO_SignaturePurpose *validate, const struct GNUNET_CRYPTO_EddsaSignature *sig, const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Verify EdDSA signature.
Definition crypto_ecc.c:729
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_x25519_ecdh(const struct GNUNET_CRYPTO_EcdhePrivateKey *sk, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_CRYPTO_EcdhePublicKey *dh)
Derive key material from a ECDH public key and a private X25519 key.
Definition crypto_ecc.c:788
const struct GNUNET_CRYPTO_EddsaPrivateKey * GNUNET_CRYPTO_eddsa_key_get_anonymous()
Get the shared private key we use for anonymous users.
Definition crypto_ecc.c:522
void GNUNET_CRYPTO_eddsa_key_get_public(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Extract the public key for the given private key.
Definition crypto_ecc.c:202
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdsa_ecdh(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material)
HPKE END.
Definition crypto_ecc.c:826
void GNUNET_CRYPTO_eddsa_key_clear(struct GNUNET_CRYPTO_EddsaPrivateKey *pk)
Clear memory that was used to store a private key.
Definition crypto_ecc.c:448
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_sign_(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_SignaturePurpose *purpose, struct GNUNET_CRYPTO_EddsaSignature *sig)
EdDSA sign a given block.
Definition crypto_ecc.c:646
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_ecdh(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, const struct GNUNET_CRYPTO_EcdhePublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a ECDH public key and a private EdDSA key.
Definition crypto_ecc.c:766
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdh_ecdsa(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EcdsaPublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a EcDSA public key and a private ECDH key.
Definition crypto_ecc.c:861
void GNUNET_CRYPTO_eddsa_key_create(struct GNUNET_CRYPTO_EddsaPrivateKey *pk)
Create a new private key.
Definition crypto_ecc.c:479
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdh_eddsa(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, const struct GNUNET_CRYPTO_EddsaPublicKey *pub, struct GNUNET_HashCode *key_material)
Derive key material from a EdDSA public key and a private ECDH key.
Definition crypto_ecc.c:844
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdsa_sign_(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, const struct GNUNET_CRYPTO_SignaturePurpose *purpose, struct GNUNET_CRYPTO_EcdsaSignature *sig)
ECDSA Sign a given block.
Definition crypto_ecc.c:575
void GNUNET_CRYPTO_random_block(void *buffer, size_t length)
Fill block with a random values.
void GNUNET_CRYPTO_ecdsa_key_create(struct GNUNET_CRYPTO_EcdsaPrivateKey *pk)
Create a new private key.
Definition crypto_ecc.c:465
void GNUNET_CRYPTO_ecdsa_key_clear(struct GNUNET_CRYPTO_EcdsaPrivateKey *pk)
Clear memory that was used to store a private key.
Definition crypto_ecc.c:441
const struct GNUNET_CRYPTO_EcdsaPrivateKey * GNUNET_CRYPTO_ecdsa_key_get_anonymous()
Get the shared private key we use for anonymous users.
Definition crypto_ecc.c:498
void GNUNET_CRYPTO_ecdsa_key_get_public(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Derive key.
Definition crypto_ecc.c:191
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdh_x25519(const struct GNUNET_CRYPTO_EcdhePrivateKey *sk, const struct GNUNET_CRYPTO_EcdhePublicKey *pk, struct GNUNET_CRYPTO_EcdhePublicKey *dh)
Derive key material from a EdDSA public key and a private ECDH key.
Definition crypto_ecc.c:804
void GNUNET_CRYPTO_ecdhe_key_clear(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Clear memory that was used to store a private key.
Definition crypto_ecc.c:434
void GNUNET_CRYPTO_ecdhe_key_get_public(const struct GNUNET_CRYPTO_EcdhePrivateKey *priv, struct GNUNET_CRYPTO_EcdhePublicKey *pub)
Extract the public key for the given private key.
Definition crypto_ecc.c:218
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdsa_verify_(uint32_t purpose, const struct GNUNET_CRYPTO_SignaturePurpose *validate, const struct GNUNET_CRYPTO_EcdsaSignature *sig, const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Verify ECDSA signature.
Definition crypto_ecc.c:670
void GNUNET_CRYPTO_hash(const void *block, size_t size, struct GNUNET_HashCode *ret)
Compute hash of a given block.
Definition crypto_hash.c:40
char * GNUNET_CRYPTO_eddsa_private_key_to_string(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
Convert a private key to a string.
Definition crypto_ecc.c:283
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_sign_raw(const struct GNUNET_CRYPTO_EddsaPrivateKey *priv, void *data, size_t size, struct GNUNET_CRYPTO_EddsaSignature *sig)
Definition crypto_ecc.c:625
#define GNUNET_log(kind,...)
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_ecdsa_public_key_from_string(const char *enc, size_t enclen, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Convert a string representing a public key to a public key.
Definition crypto_ecc.c:337
char * GNUNET_CRYPTO_eddsa_public_key_to_string(const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Convert a public key to a string.
Definition crypto_ecc.c:256
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_public_key_from_string(const char *enc, size_t enclen, struct GNUNET_CRYPTO_EddsaPublicKey *pub)
Convert a string representing a public key to a public key.
Definition crypto_ecc.c:362
void GNUNET_CRYPTO_mpi_print_unsigned(void *buf, size_t size, gcry_mpi_t val)
Output the given MPI value to the given buffer in network byte order.
Definition crypto_mpi.c:79
char * GNUNET_CRYPTO_ecdsa_public_key_to_string(const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Convert a public key to a string.
Definition crypto_ecc.c:229
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
enum GNUNET_GenericReturnValue GNUNET_CRYPTO_eddsa_private_key_from_string(const char *enc, size_t enclen, struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
Convert a string representing a private key to a private key.
Definition crypto_ecc.c:387
char * GNUNET_CRYPTO_ecdsa_private_key_to_string(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv)
Convert a private key to a string.
Definition crypto_ecc.c:310
GNUNET_GenericReturnValue
Named constants for return values.
@ GNUNET_OK
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_INFO
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
char * GNUNET_STRINGS_data_to_string(const void *data, size_t size, char *out, size_t out_size)
Convert binary data to ASCII encoding using CrockfordBase32.
Definition strings.c:763
enum GNUNET_GenericReturnValue GNUNET_STRINGS_string_to_data(const char *enc, size_t enclen, void *out, size_t out_size)
Convert CrockfordBase32 encoding back to data.
Definition strings.c:843
static unsigned int size
Size of the "table".
Definition peer.c:68
#define _(String)
GNU gettext support macro.
Definition platform.h:179
Private ECC key encoded for transmission.
unsigned char d[256/8]
d is a value mod n, where n has at most 256 bits.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and encr...
unsigned char q_y[256/8]
Q consists of an x- and a y-value, each mod p (256 bits), given here in affine coordinates and Ed2551...
Private ECC key encoded for transmission.
unsigned char d[256/8]
d is a value mod n, where n has at most 256 bits.
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
an ECC signature using ECDSA
unsigned char s[256/8]
S value.
unsigned char r[256/8]
R value.
Private ECC key encoded for transmission.
unsigned char d[256/8]
d is a value mod n, where n has at most 256 bits.
Public ECC key (always for curve Ed25519) encoded in a format suitable for network transmission and E...
unsigned char q_y[256/8]
Point Q consists of a y-value mod p (256 bits); the x-value is always positive.
an ECC signature using EdDSA.
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!...
A 512-bit hashcode.

◆ LOG_STRERROR_FILE

#define LOG_STRERROR_FILE (   kind,
  syscall,
  filename 
)
Value:
GNUNET_log_from_strerror_file (kind, "util-crypto-ecc", syscall, \
static char * filename
#define GNUNET_log_from_strerror_file(level, component, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...

Definition at line 70 of file crypto_ecc.c.

◆ LOG_GCRY

#define LOG_GCRY (   level,
  cmd,
  rc 
)
Value:
do \
{ \
LOG (level, \
_ ("`%s' failed at %s:%d with error: %s\n"), \
cmd, \
__FILE__, \
__LINE__, \
gcry_strerror (rc)); \
} while (0)

Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the message given by gcry_strerror(rc).

Definition at line 79 of file crypto_ecc.c.

81 { \
82 LOG (level, \
83 _ ("`%s' failed at %s:%d with error: %s\n"), \
84 cmd, \
85 __FILE__, \
86 __LINE__, \
87 gcry_strerror (rc)); \
88 } while (0)

Function Documentation

◆ key_from_sexp()

static int key_from_sexp ( gcry_mpi_t *  array,
gcry_sexp_t  sexp,
const char *  topname,
const char *  elems 
)
static

Extract values from an S-expression.

Parameters
arraywhere to store the result(s)
sexpS-expression to parse
topnametop-level name in the S-expression that is of interest
elemsnames of the elements to extract
Returns
0 on success

Definition at line 101 of file crypto_ecc.c.

105{
106 gcry_sexp_t list;
107 gcry_sexp_t l2;
108 unsigned int idx;
109
110 list = gcry_sexp_find_token (sexp, topname, 0);
111 if (! list)
112 return 1;
113 l2 = gcry_sexp_cadr (list);
114 gcry_sexp_release (list);
115 list = l2;
116 if (! list)
117 return 2;
118
119 idx = 0;
120 for (const char *s = elems; *s; s++, idx++)
121 {
122 l2 = gcry_sexp_find_token (list, s, 1);
123 if (! l2)
124 {
125 for (unsigned int i = 0; i < idx; i++)
126 {
127 gcry_free (array[i]);
128 array[i] = NULL;
129 }
130 gcry_sexp_release (list);
131 return 3; /* required parameter not found */
132 }
133 array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
134 gcry_sexp_release (l2);
135 if (! array[idx])
136 {
137 for (unsigned int i = 0; i < idx; i++)
138 {
139 gcry_free (array[i]);
140 array[i] = NULL;
141 }
142 gcry_sexp_release (list);
143 return 4; /* required parameter is invalid */
144 }
145 }
146 gcry_sexp_release (list);
147 return 0;
148}

References list.

Referenced by GNUNET_CRYPTO_ecdsa_sign_().

Here is the caller graph for this function:

◆ decode_private_ecdsa_key()

static gcry_sexp_t decode_private_ecdsa_key ( const struct GNUNET_CRYPTO_EcdsaPrivateKey priv)
static

Convert the given private key from the network format to the S-expression that can be used by libgcrypt.

Parameters
privprivate key to decode
Returns
NULL on error

Definition at line 159 of file crypto_ecc.c.

160{
161 gcry_sexp_t result;
162 int rc;
163 uint8_t d[32];
164
165 for (size_t i = 0; i<32; i++)
166 d[i] = priv->d[31 - i];
167
168 rc = gcry_sexp_build (&result,
169 NULL,
170 "(private-key(ecc(curve \"" CURVE "\")"
171 "(d %b)))",
172 32,
173 d);
174 if (0 != rc)
175 {
176 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
177 GNUNET_assert (0);
178 }
179#if EXTRA_CHECKS
180 if (0 != (rc = gcry_pk_testkey (result)))
181 {
182 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
183 GNUNET_assert (0);
184 }
185#endif
186 return result;
187}

References CURVE, d, GNUNET_CRYPTO_EcdsaPrivateKey::d, GNUNET_assert, GNUNET_ERROR_TYPE_ERROR, LOG_GCRY, and result.

Referenced by GNUNET_CRYPTO_ecdsa_sign_().

Here is the caller graph for this function:

◆ buffer_clear()

static void buffer_clear ( void *  buf,
size_t  len 
)
static

Definition at line 419 of file crypto_ecc.c.

420{
421#if HAVE_MEMSET_S
422 memset_s (buf, len, 0, len);
423#elif HAVE_EXPLICIT_BZERO
424 explicit_bzero (buf, len);
425#else
426 volatile unsigned char *p = buf;
427 while (len--)
428 *p++ = 0;
429#endif
430}

References p.

Referenced by GNUNET_CRYPTO_ecdhe_key_clear(), GNUNET_CRYPTO_ecdsa_key_clear(), and GNUNET_CRYPTO_eddsa_key_clear().

Here is the caller graph for this function:

◆ data_to_ecdsa_value()

static gcry_sexp_t data_to_ecdsa_value ( const struct GNUNET_CRYPTO_SignaturePurpose purpose)
static

Convert the data specified in the given purpose argument to an S-expression suitable for signature operations.

Parameters
purposedata to convert
Returns
converted s-expression

Definition at line 552 of file crypto_ecc.c.

553{
554 gcry_sexp_t data;
555 int rc;
556 /* Unlike EdDSA, libgcrypt expects a hash for ECDSA. */
557 struct GNUNET_HashCode hc;
558
559 GNUNET_CRYPTO_hash (purpose, ntohl (purpose->size), &hc);
560 if (0 != (rc = gcry_sexp_build (&data,
561 NULL,
562 "(data(flags rfc6979)(hash %s %b))",
563 "sha512",
564 (int) sizeof(hc),
565 &hc)))
566 {
567 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
568 return NULL;
569 }
570 return data;
571}

References data, GNUNET_CRYPTO_hash(), GNUNET_ERROR_TYPE_ERROR, LOG_GCRY, and GNUNET_CRYPTO_SignaturePurpose::size.

Referenced by GNUNET_CRYPTO_ecdsa_sign_(), and GNUNET_CRYPTO_ecdsa_verify_().

Here is the call graph for this function:
Here is the caller graph for this function: