GNUnet 0.28.0-dev.3-7-g31e20e2e6
 
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 "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 37 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 62 of file crypto_ecc.c.

◆ LOG

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

Definition at line 64 of file crypto_ecc.c.

◆ LOG_STRERROR

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

Definition at line 66 of file crypto_ecc.c.

79 { \
80 LOG (level, \
81 _ ("`%s' failed at %s:%d with error: %s\n"), \
82 cmd, \
83 __FILE__, \
84 __LINE__, \
85 gcry_strerror (rc)); \
86 } while (0)
87
88
98static int
99key_from_sexp (gcry_mpi_t *array,
100 gcry_sexp_t sexp,
101 const char *topname,
102 const char *elems)
103{
104 gcry_sexp_t list;
105 gcry_sexp_t l2;
106 unsigned int idx;
107
108 list = gcry_sexp_find_token (sexp, topname, 0);
109 if (! list)
110 return 1;
111 l2 = gcry_sexp_cadr (list);
112 gcry_sexp_release (list);
113 list = l2;
114 if (! list)
115 return 2;
116
117 idx = 0;
118 for (const char *s = elems; *s; s++, idx++)
119 {
120 l2 = gcry_sexp_find_token (list, s, 1);
121 if (! l2)
122 {
123 for (unsigned int i = 0; i < idx; i++)
124 {
125 gcry_free (array[i]);
126 array[i] = NULL;
127 }
128 gcry_sexp_release (list);
129 return 3; /* required parameter not found */
130 }
131 array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
132 gcry_sexp_release (l2);
133 if (! array[idx])
134 {
135 for (unsigned int i = 0; i < idx; i++)
136 {
137 gcry_free (array[i]);
138 array[i] = NULL;
139 }
140 gcry_sexp_release (list);
141 return 4; /* required parameter is invalid */
142 }
143 }
144 gcry_sexp_release (list);
145 return 0;
146}
147
148
156static gcry_sexp_t
158{
159 gcry_sexp_t result;
160 int rc;
161 uint8_t d[32];
162
163 for (size_t i = 0; i<32; i++)
164 d[i] = priv->d[31 - i];
165
166 rc = gcry_sexp_build (&result,
167 NULL,
168 "(private-key(ecc(curve \"" CURVE "\")"
169 "(d %b)))",
170 32,
171 d);
172 if (0 != rc)
173 {
174 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
175 GNUNET_assert (0);
176 }
177#if EXTRA_CHECKS
178 if (0 != (rc = gcry_pk_testkey (result)))
179 {
180 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
181 GNUNET_assert (0);
182 }
183#endif
184 return result;
185}
186
187
188void
190 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
192{
193 BENCHMARK_START (ecdsa_key_get_public);
194 crypto_scalarmult_ed25519_base_noclamp (pub->q_y, priv->d);
195 BENCHMARK_END (ecdsa_key_get_public);
196}
197
198
199void
201 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
203{
204 unsigned char pk[crypto_sign_PUBLICKEYBYTES];
205 unsigned char sk[crypto_sign_SECRETKEYBYTES];
206
207 BENCHMARK_START (eddsa_key_get_public);
208 GNUNET_assert (0 == crypto_sign_seed_keypair (pk, sk, priv->d));
209 GNUNET_memcpy (pub->q_y, pk, crypto_sign_PUBLICKEYBYTES);
210 sodium_memzero (sk, crypto_sign_SECRETKEYBYTES);
211 BENCHMARK_END (eddsa_key_get_public);
212}
213
214
215void
217 const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
219{
220 BENCHMARK_START (ecdhe_key_get_public);
221 GNUNET_assert (0 == crypto_scalarmult_base (pub->q_y, priv->d));
222 BENCHMARK_END (ecdhe_key_get_public);
223}
224
225
226char *
228 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
229{
230 char *pubkeybuf;
231 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8;
232 char *end;
233
234 if (keylen % 5 > 0)
235 keylen += 5 - keylen % 5;
236 keylen /= 5;
237 pubkeybuf = GNUNET_malloc (keylen + 1);
238 end =
239 GNUNET_STRINGS_data_to_string ((unsigned char *) pub,
240 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey),
241 pubkeybuf,
242 keylen);
243 if (NULL == end)
244 {
245 GNUNET_free (pubkeybuf);
246 return NULL;
247 }
248 *end = '\0';
249 return pubkeybuf;
250}
251
252
253char *
255 const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
256{
257 char *pubkeybuf;
258 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)) * 8;
259 char *end;
260
261 if (keylen % 5 > 0)
262 keylen += 5 - keylen % 5;
263 keylen /= 5;
264 pubkeybuf = GNUNET_malloc (keylen + 1);
265 end =
266 GNUNET_STRINGS_data_to_string ((unsigned char *) pub,
267 sizeof(struct GNUNET_CRYPTO_EddsaPublicKey),
268 pubkeybuf,
269 keylen);
270 if (NULL == end)
271 {
272 GNUNET_free (pubkeybuf);
273 return NULL;
274 }
275 *end = '\0';
276 return pubkeybuf;
277}
278
279
280char *
282 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv)
283{
284 char *privkeybuf;
285 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EddsaPrivateKey)) * 8;
286 char *end;
287
288 if (keylen % 5 > 0)
289 keylen += 5 - keylen % 5;
290 keylen /= 5;
291 privkeybuf = GNUNET_malloc (keylen + 1);
292 end = GNUNET_STRINGS_data_to_string ((unsigned char *) priv,
293 sizeof(
295 privkeybuf,
296 keylen);
297 if (NULL == end)
298 {
299 GNUNET_free (privkeybuf);
300 return NULL;
301 }
302 *end = '\0';
303 return privkeybuf;
304}
305
306
307char *
309 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv)
310{
311 char *privkeybuf;
312 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EcdsaPrivateKey)) * 8;
313 char *end;
314
315 if (keylen % 5 > 0)
316 keylen += 5 - keylen % 5;
317 keylen /= 5;
318 privkeybuf = GNUNET_malloc (keylen + 1);
319 end = GNUNET_STRINGS_data_to_string ((unsigned char *) priv,
320 sizeof(
322 privkeybuf,
323 keylen);
324 if (NULL == end)
325 {
326 GNUNET_free (privkeybuf);
327 return NULL;
328 }
329 *end = '\0';
330 return privkeybuf;
331}
332
333
336 const char *enc,
337 size_t enclen,
339{
340 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8;
341
342 if (keylen % 5 > 0)
343 keylen += 5 - keylen % 5;
344 keylen /= 5;
345 if (enclen != keylen)
346 return GNUNET_SYSERR;
347
348 if (GNUNET_OK !=
350 enclen,
351 pub,
352 sizeof(
354 return GNUNET_SYSERR;
355 return GNUNET_OK;
356}
357
358
361 const char *enc,
362 size_t enclen,
364{
365 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EddsaPublicKey)) * 8;
366
367 if (keylen % 5 > 0)
368 keylen += 5 - keylen % 5;
369 keylen /= 5;
370 if (enclen != keylen)
371 return GNUNET_SYSERR;
372
373 if (GNUNET_OK !=
375 enclen,
376 pub,
377 sizeof(
379 return GNUNET_SYSERR;
380 return GNUNET_OK;
381}
382
383
386 const char *enc,
387 size_t enclen,
389{
390 size_t keylen = (sizeof(struct GNUNET_CRYPTO_EddsaPrivateKey)) * 8;
391
392 if (keylen % 5 > 0)
393 keylen += 5 - keylen % 5;
394 keylen /= 5;
395 if (enclen != keylen)
396 return GNUNET_SYSERR;
397
398 if (GNUNET_OK !=
400 enclen,
401 priv,
402 sizeof(
404 return GNUNET_SYSERR;
405#if CRYPTO_BUG
406 if (GNUNET_OK != check_eddsa_key (priv))
407 {
408 GNUNET_break (0);
409 return GNUNET_OK;
410 }
411#endif
412 return GNUNET_OK;
413}
414
415
416static void
417buffer_clear (void *buf, size_t len)
418{
419#if HAVE_MEMSET_S
420 memset_s (buf, len, 0, len);
421#elif HAVE_EXPLICIT_BZERO
422 explicit_bzero (buf, len);
423#else
424 volatile unsigned char *p = buf;
425 while (len--)
426 *p++ = 0;
427#endif
428}
429
430
431void
433{
435}
436
437
438void
440{
442}
443
444
445void
447{
449}
450
451
452void
454{
455 BENCHMARK_START (ecdhe_key_create);
457 sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey));
458 BENCHMARK_END (ecdhe_key_create);
459}
460
461
462void
464{
465 BENCHMARK_START (ecdsa_key_create);
467 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey));
468 pk->d[0] &= 248;
469 pk->d[31] &= 127;
470 pk->d[31] |= 64;
471
472 BENCHMARK_END (ecdsa_key_create);
473}
474
475
476void
478{
479 BENCHMARK_START (eddsa_key_create);
480 /*
481 * We do not clamp for EdDSA, since all functions that use the private key do
482 * their own clamping (just like in libsodium). What we call "private key"
483 * here, actually corresponds to the seed in libsodium.
484 *
485 * (Contrast this to ECDSA, where functions using the private key can't clamp
486 * due to properties needed for GNS. That is a worse/unsafter API, but
487 * required for the GNS constructions to work.)
488 */
490 sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey));
491 BENCHMARK_END (eddsa_key_create);
492}
493
494
497{
502 static struct GNUNET_CRYPTO_EcdsaPrivateKey anonymous;
503 static int once;
504
505 if (once)
506 return &anonymous;
508 sizeof(anonymous.d),
509 GCRYMPI_CONST_ONE);
510 anonymous.d[0] &= 248;
511 anonymous.d[31] &= 127;
512 anonymous.d[31] |= 64;
513
514 once = 1;
515 return &anonymous;
516}
517
518
521{
526 static struct GNUNET_CRYPTO_EddsaPrivateKey anonymous;
527 static int once;
528
529 if (once)
530 return &anonymous;
531
532 memset (anonymous.d, 0, sizeof(anonymous.d));
533
534 // Set the first byte to 1 (Little-Endian representation of 1)
535 anonymous.d[0] = 1;
536
537 once = 1;
538 return &anonymous;
539}
540
541
549static gcry_sexp_t
551{
552 gcry_sexp_t data;
553 int rc;
554 /* Unlike EdDSA, libgcrypt expects a hash for ECDSA. */
555 struct GNUNET_HashCode hc;
556
557 GNUNET_CRYPTO_hash (purpose, ntohl (purpose->size), &hc);
558 if (0 != (rc = gcry_sexp_build (&data,
559 NULL,
560 "(data(flags rfc6979)(hash %s %b))",
561 "sha512",
562 (int) sizeof(hc),
563 &hc)))
564 {
565 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
566 return NULL;
567 }
568 return data;
569}
570
571
574 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
575 const struct GNUNET_CRYPTO_SignaturePurpose *purpose,
577{
578 gcry_sexp_t priv_sexp;
579 gcry_sexp_t sig_sexp;
580 gcry_sexp_t data;
581 int rc;
582 gcry_mpi_t rs[2];
583
584 BENCHMARK_START (ecdsa_sign);
585
586 priv_sexp = decode_private_ecdsa_key (priv);
587 data = data_to_ecdsa_value (purpose);
588 if (0 != (rc = gcry_pk_sign (&sig_sexp, data, priv_sexp)))
589 {
591 _ ("ECC signing failed at %s:%d: %s\n"),
592 __FILE__,
593 __LINE__,
594 gcry_strerror (rc));
595 gcry_sexp_release (data);
596 gcry_sexp_release (priv_sexp);
597 return GNUNET_SYSERR;
598 }
599 gcry_sexp_release (priv_sexp);
600 gcry_sexp_release (data);
601
602 /* extract 'r' and 's' values from sexpression 'sig_sexp' and store in
603 'signature' */
604 if (0 != (rc = key_from_sexp (rs, sig_sexp, "sig-val", "rs")))
605 {
606 GNUNET_break (0);
607 gcry_sexp_release (sig_sexp);
608 return GNUNET_SYSERR;
609 }
610 gcry_sexp_release (sig_sexp);
611 GNUNET_CRYPTO_mpi_print_unsigned (sig->r, sizeof(sig->r), rs[0]);
612 GNUNET_CRYPTO_mpi_print_unsigned (sig->s, sizeof(sig->s), rs[1]);
613 gcry_mpi_release (rs[0]);
614 gcry_mpi_release (rs[1]);
615
616 BENCHMARK_END (ecdsa_sign);
617
618 return GNUNET_OK;
619}
620
621
624 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
625 void *data,
626 size_t size,
628{
629 unsigned char sk[crypto_sign_SECRETKEYBYTES];
630 unsigned char pk[crypto_sign_PUBLICKEYBYTES];
631 int res;
632
633 GNUNET_assert (0 == crypto_sign_seed_keypair (pk, sk, priv->d));
634 res = crypto_sign_detached ((uint8_t *) sig,
635 NULL,
636 (uint8_t *) data,
637 size,
638 sk);
639 return (res == 0) ? GNUNET_OK : GNUNET_SYSERR;
640}
641
642
645 const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
646 const struct GNUNET_CRYPTO_SignaturePurpose *purpose,
648{
649
650 size_t mlen = ntohl (purpose->size);
651 unsigned char sk[crypto_sign_SECRETKEYBYTES];
652 unsigned char pk[crypto_sign_PUBLICKEYBYTES];
653 int res;
654
655 BENCHMARK_START (eddsa_sign);
656 GNUNET_assert (0 == crypto_sign_seed_keypair (pk, sk, priv->d));
657 res = crypto_sign_detached ((uint8_t *) sig,
658 NULL,
659 (uint8_t *) purpose,
660 mlen,
661 sk);
662 BENCHMARK_END (eddsa_sign);
663 return (res == 0) ? GNUNET_OK : GNUNET_SYSERR;
664}
665
666
669 uint32_t purpose,
670 const struct GNUNET_CRYPTO_SignaturePurpose *validate,
671 const struct GNUNET_CRYPTO_EcdsaSignature *sig,
672 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
673{
674 gcry_sexp_t data;
675 gcry_sexp_t sig_sexpr;
676 gcry_sexp_t pub_sexpr;
677 int rc;
678
679 BENCHMARK_START (ecdsa_verify);
680
681 if (purpose != ntohl (validate->purpose))
682 return GNUNET_SYSERR; /* purpose mismatch */
683
684 /* build s-expression for signature */
685 if (0 != (rc = gcry_sexp_build (&sig_sexpr,
686 NULL,
687 "(sig-val(ecdsa(r %b)(s %b)))",
688 (int) sizeof(sig->r),
689 sig->r,
690 (int) sizeof(sig->s),
691 sig->s)))
692 {
693 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
694 return GNUNET_SYSERR;
695 }
696 data = data_to_ecdsa_value (validate);
697 if (0 != (rc = gcry_sexp_build (&pub_sexpr,
698 NULL,
699 "(public-key(ecc(curve " CURVE ")(q %b)))",
700 (int) sizeof(pub->q_y),
701 pub->q_y)))
702 {
703 gcry_sexp_release (data);
704 gcry_sexp_release (sig_sexpr);
705 return GNUNET_SYSERR;
706 }
707 rc = gcry_pk_verify (sig_sexpr, data, pub_sexpr);
708 gcry_sexp_release (pub_sexpr);
709 gcry_sexp_release (data);
710 gcry_sexp_release (sig_sexpr);
711 if (0 != rc)
712 {
714 _ ("ECDSA signature verification failed at %s:%d: %s\n"),
715 __FILE__,
716 __LINE__,
717 gcry_strerror (rc));
718 BENCHMARK_END (ecdsa_verify);
719 return GNUNET_SYSERR;
720 }
721 BENCHMARK_END (ecdsa_verify);
722 return GNUNET_OK;
723}
724
725
728 uint32_t purpose,
729 const struct GNUNET_CRYPTO_SignaturePurpose *validate,
730 const struct GNUNET_CRYPTO_EddsaSignature *sig,
731 const struct GNUNET_CRYPTO_EddsaPublicKey *pub)
732{
733 const unsigned char *m = (const void *) validate;
734 size_t mlen = ntohl (validate->size);
735 const unsigned char *s = (const void *) sig;
736
737 int res;
738
739 if (purpose != ntohl (validate->purpose))
740 return GNUNET_SYSERR; /* purpose mismatch */
741
742 BENCHMARK_START (eddsa_verify);
743
744 res = crypto_sign_verify_detached (s, m, mlen, pub->q_y);
745 BENCHMARK_END (eddsa_verify);
746 return (res == 0) ? GNUNET_OK : GNUNET_SYSERR;
747}
748
749
752 const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
753 struct GNUNET_HashCode *key_material)
754{
755 uint8_t p[crypto_scalarmult_BYTES];
756 if (0 != crypto_scalarmult (p, priv->d, pub->q_y))
757 return GNUNET_SYSERR;
758 GNUNET_CRYPTO_hash (p, crypto_scalarmult_BYTES, key_material);
759 return GNUNET_OK;
760}
761
762
765 const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
766 struct GNUNET_HashCode *key_material)
767{
768 struct GNUNET_HashCode hc;
769 uint8_t a[crypto_scalarmult_SCALARBYTES];
770 uint8_t p[crypto_scalarmult_BYTES];
771
772 GNUNET_CRYPTO_hash (priv,
773 sizeof (struct GNUNET_CRYPTO_EcdsaPrivateKey),
774 &hc);
775 memcpy (a, &hc, sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey));
776 if (0 != crypto_scalarmult (p, a, pub->q_y))
777 return GNUNET_SYSERR;
779 crypto_scalarmult_BYTES,
780 key_material);
781 return GNUNET_OK;
782}
783
784
787 const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
789{
790 uint64_t checkbyte = 0;
791 size_t num_words = sizeof *dh / sizeof (uint64_t);
792 if (0 != crypto_scalarmult_curve25519 (dh->q_y, sk->d, pub->q_y))
793 return GNUNET_SYSERR;
794 // We need to check if this is the all-zero value
795 for (int i = 0; i < num_words; i++)
796 checkbyte |= ((uint64_t*) dh)[i];
797 return (0 == checkbyte) ? GNUNET_SYSERR : GNUNET_OK;
798}
799
800
803 const struct GNUNET_CRYPTO_EcdhePublicKey *pk,
805{
806 uint64_t checkbyte = 0;
807 size_t num_words = sizeof *dh / sizeof (uint64_t);
808 if (0 != crypto_scalarmult_curve25519 (dh->q_y, sk->d, pk->q_y))
809 return GNUNET_SYSERR;
810 // We need to check if this is the all-zero value
811 for (int i = 0; i < num_words; i++)
812 checkbyte |= ((uint64_t*) dh)[i];
813 if (0 == checkbyte)
814 {
816 "HPKE ECDH: X25519 all zero value!\n");
817 return GNUNET_SYSERR;
818 }
819 return GNUNET_OK;
820}
821
822
825 const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
826 struct GNUNET_HashCode *key_material)
827{
828 uint8_t p[crypto_scalarmult_BYTES];
829
830 BENCHMARK_START (ecdsa_ecdh);
831 if (0 != crypto_scalarmult (p, priv->d, pub->q_y))
832 return GNUNET_SYSERR;
834 crypto_scalarmult_BYTES,
835 key_material);
836 BENCHMARK_END (ecdsa_ecdh);
837 return GNUNET_OK;
838}
839
840
843 const struct GNUNET_CRYPTO_EddsaPublicKey *pub,
844 struct GNUNET_HashCode *key_material)
845{
846 uint8_t p[crypto_scalarmult_BYTES];
847 uint8_t curve25510_pk[crypto_scalarmult_BYTES];
848
849 if (0 != crypto_sign_ed25519_pk_to_curve25519 (curve25510_pk, pub->q_y))
850 return GNUNET_SYSERR;
851 if (0 != crypto_scalarmult (p, priv->d, curve25510_pk))
852 return GNUNET_SYSERR;
853 GNUNET_CRYPTO_hash (p, crypto_scalarmult_BYTES, key_material);
854 return GNUNET_OK;
855}
856
857
860 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub,
861 struct GNUNET_HashCode *key_material)
862{
863 uint8_t p[crypto_scalarmult_BYTES];
864 uint8_t curve25510_pk[crypto_scalarmult_BYTES];
865
866 if (0 != crypto_sign_ed25519_pk_to_curve25519 (curve25510_pk, pub->q_y))
867 return GNUNET_SYSERR;
868 if (0 != crypto_scalarmult (p, priv->d, curve25510_pk))
869 return GNUNET_SYSERR;
870 GNUNET_CRYPTO_hash (p, crypto_scalarmult_BYTES, key_material);
871 return GNUNET_OK;
872}
873
874
875/* 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:100
#define CURVE
IMPLEMENTATION NOTICE:
Definition crypto_ecc.c:62
static void buffer_clear(void *buf, size_t len)
Definition crypto_ecc.c:418
#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:78
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:551
#define LOG(kind,...)
Definition crypto_ecc.c:64
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:158
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:752
void GNUNET_CRYPTO_ecdhe_key_create(struct GNUNET_CRYPTO_EcdhePrivateKey *pk)
Create a new private key.
Definition crypto_ecc.c:454
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:728
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:787
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:521
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:201
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:825
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:447
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:645
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:765
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:860
void GNUNET_CRYPTO_eddsa_key_create(struct GNUNET_CRYPTO_EddsaPrivateKey *pk)
Create a new private key.
Definition crypto_ecc.c:478
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:843
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:574
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:464
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:440
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:497
void GNUNET_CRYPTO_ecdsa_key_get_public(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Derive key.
Definition crypto_ecc.c:190
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:803
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:433
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:217
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:669
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:282
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:624
#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:336
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:255
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:361
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:228
#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:386
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:309
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 69 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 78 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)

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 100 of file crypto_ecc.c.

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}

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 158 of file crypto_ecc.c.

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}

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 418 of file crypto_ecc.c.

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}

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 551 of file crypto_ecc.c.

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}

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: