Tor  0.4.7.0-alpha-dev
crypto_ed25519.c
Go to the documentation of this file.
1 /* Copyright (c) 2013-2021, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
3 
4 /**
5  * \file crypto_ed25519.c
6  *
7  * \brief Wrapper code for an ed25519 implementation.
8  *
9  * Ed25519 is a Schnorr signature on a Twisted Edwards curve, defined
10  * by Dan Bernstein. For more information, see https://ed25519.cr.yp.to/
11  *
12  * This module wraps our choice of Ed25519 backend, and provides a few
13  * convenience functions for checking and generating signatures. It also
14  * provides Tor-specific tools for key blinding and for converting Ed25519
15  * keys to and from the corresponding Curve25519 keys.
16  */
17 
18 #define CRYPTO_ED25519_PRIVATE
19 #include "orconfig.h"
20 #ifdef HAVE_SYS_STAT_H
21 #include <sys/stat.h>
22 #endif
23 
24 #include "lib/ctime/di_ops.h"
31 #include "lib/log/log.h"
32 #include "lib/log/util_bug.h"
33 #include "lib/encoding/binascii.h"
34 #include "lib/string/util_string.h"
35 
36 #include "ed25519/ref10/ed25519_ref10.h"
37 #include "ed25519/donna/ed25519_donna_tor.h"
38 
39 #include <string.h>
40 #include <errno.h>
41 
42 static void pick_ed25519_impl(void);
43 
44 /** An Ed25519 implementation, as a set of function pointers. */
45 typedef struct {
46  int (*selftest)(void);
47 
48  int (*seckey)(unsigned char *);
49  int (*seckey_expand)(unsigned char *, const unsigned char *);
50  int (*pubkey)(unsigned char *, const unsigned char *);
51  int (*keygen)(unsigned char *, unsigned char *);
52 
53  int (*open)(const unsigned char *, const unsigned char *, size_t, const
54  unsigned char *);
55  int (*sign)(unsigned char *, const unsigned char *, size_t,
56  const unsigned char *, const unsigned char *);
57  int (*open_batch)(const unsigned char **, size_t *, const unsigned char **,
58  const unsigned char **, size_t, int *);
59 
60  int (*blind_secret_key)(unsigned char *, const unsigned char *,
61  const unsigned char *);
62  int (*blind_public_key)(unsigned char *, const unsigned char *,
63  const unsigned char *);
64 
65  int (*pubkey_from_curve25519_pubkey)(unsigned char *, const unsigned char *,
66  int);
67 
68  int (*ed25519_scalarmult_with_group_order)(unsigned char *,
69  const unsigned char *);
71 
72 /** The Ref10 Ed25519 implementation. This one is pure C and lightly
73  * optimized. */
74 static const ed25519_impl_t impl_ref10 = {
75  NULL,
76 
77  ed25519_ref10_seckey,
78  ed25519_ref10_seckey_expand,
79  ed25519_ref10_pubkey,
80  ed25519_ref10_keygen,
81 
82  ed25519_ref10_open,
83  ed25519_ref10_sign,
84  NULL,
85 
86  ed25519_ref10_blind_secret_key,
87  ed25519_ref10_blind_public_key,
88 
89  ed25519_ref10_pubkey_from_curve25519_pubkey,
90  ed25519_ref10_scalarmult_with_group_order,
91 };
92 
93 /** The Ref10 Ed25519 implementation. This one is heavily optimized, but still
94  * mostly C. The C still tends to be heavily platform-specific. */
95 static const ed25519_impl_t impl_donna = {
96  ed25519_donna_selftest,
97 
98  ed25519_donna_seckey,
99  ed25519_donna_seckey_expand,
100  ed25519_donna_pubkey,
101  ed25519_donna_keygen,
102 
103  ed25519_donna_open,
104  ed25519_donna_sign,
105  ed25519_sign_open_batch_donna,
106 
107  ed25519_donna_blind_secret_key,
108  ed25519_donna_blind_public_key,
109 
110  ed25519_donna_pubkey_from_curve25519_pubkey,
111  ed25519_donna_scalarmult_with_group_order,
112 };
113 
114 /** Which Ed25519 implementation are we using? NULL if we haven't decided
115  * yet. */
116 static const ed25519_impl_t *ed25519_impl = NULL;
117 
118 /** Helper: Return our chosen Ed25519 implementation.
119  *
120  * This should only be called after we've picked an implementation, but
121  * it _does_ recover if you forget this.
122  **/
123 static inline const ed25519_impl_t *
125 {
126  if (BUG(ed25519_impl == NULL)) {
127  pick_ed25519_impl(); // LCOV_EXCL_LINE - We always call ed25519_init().
128  }
129  return ed25519_impl;
130 }
131 
132 #ifdef TOR_UNIT_TESTS
133 /** For testing: used to remember our actual choice of Ed25519
134  * implementation */
135 static const ed25519_impl_t *saved_ed25519_impl = NULL;
136 /** For testing: Use the Ed25519 implementation called <b>name</b> until
137  * crypto_ed25519_testing_restore_impl is called. Recognized names are
138  * "donna" and "ref10". */
139 void
140 crypto_ed25519_testing_force_impl(const char *name)
141 {
142  tor_assert(saved_ed25519_impl == NULL);
143  saved_ed25519_impl = ed25519_impl;
144  if (! strcmp(name, "donna")) {
146  } else {
147  tor_assert(!strcmp(name, "ref10"));
149  }
150 }
151 /** For testing: go back to whatever Ed25519 implementation we had picked
152  * before crypto_ed25519_testing_force_impl was called.
153  */
154 void
155 crypto_ed25519_testing_restore_impl(void)
156 {
157  ed25519_impl = saved_ed25519_impl;
158  saved_ed25519_impl = NULL;
159 }
160 #endif /* defined(TOR_UNIT_TESTS) */
161 
162 /**
163  * Initialize a new ed25519 secret key in <b>seckey_out</b>. If
164  * <b>extra_strong</b>, take the RNG inputs directly from the operating
165  * system. Return 0 on success, -1 on failure.
166  */
167 int
169  int extra_strong)
170 {
171  int r;
172  uint8_t seed[32];
173  if (extra_strong)
174  crypto_strongest_rand(seed, sizeof(seed));
175  else
176  crypto_rand((char*)seed, sizeof(seed));
177 
178  r = get_ed_impl()->seckey_expand(seckey_out->seckey, seed);
179  memwipe(seed, 0, sizeof(seed));
180 
181  return r < 0 ? -1 : 0;
182 }
183 
184 /**
185  * Given a 32-byte random seed in <b>seed</b>, expand it into an ed25519
186  * secret key in <b>seckey_out</b>. Return 0 on success, -1 on failure.
187  */
188 int
190  const uint8_t *seed)
191 {
192  if (get_ed_impl()->seckey_expand(seckey_out->seckey, seed) < 0)
193  return -1;
194  return 0;
195 }
196 
197 /**
198  * Given a secret key in <b>seckey</b>, expand it into an
199  * ed25519 public key. Return 0 on success, -1 on failure.
200  */
201 int
203  const ed25519_secret_key_t *seckey)
204 {
205  if (get_ed_impl()->pubkey(pubkey_out->pubkey, seckey->seckey) < 0)
206  return -1;
207  return 0;
208 }
209 
210 /** Generate a new ed25519 keypair in <b>keypair_out</b>. If
211  * <b>extra_strong</b> is set, try to mix some system entropy into the key
212  * generation process. Return 0 on success, -1 on failure. */
213 int
214 ed25519_keypair_generate(ed25519_keypair_t *keypair_out, int extra_strong)
215 {
216  if (ed25519_secret_key_generate(&keypair_out->seckey, extra_strong) < 0)
217  return -1;
218  if (ed25519_public_key_generate(&keypair_out->pubkey,
219  &keypair_out->seckey)<0)
220  return -1;
221  return 0;
222 }
223 
224 /** Return true iff 'pubkey' is set to zero (eg to indicate that it is not
225  * set). */
226 int
228 {
229  return safe_mem_is_zero((char*)pubkey->pubkey, ED25519_PUBKEY_LEN);
230 }
231 
232 /* Return a heap-allocated array that contains <b>msg</b> prefixed by the
233  * string <b>prefix_str</b>. Set <b>final_msg_len_out</b> to the size of the
234  * final array. If an error occurred, return NULL. It's the responsibility of
235  * the caller to free the returned array. */
236 static uint8_t *
237 get_prefixed_msg(const uint8_t *msg, size_t msg_len,
238  const char *prefix_str,
239  size_t *final_msg_len_out)
240 {
241  size_t prefixed_msg_len, prefix_len;
242  uint8_t *prefixed_msg;
243 
244  tor_assert(prefix_str);
245  tor_assert(final_msg_len_out);
246 
247  prefix_len = strlen(prefix_str);
248 
249  /* msg_len + strlen(prefix_str) must not overflow. */
250  if (msg_len > SIZE_T_CEILING - prefix_len) {
251  return NULL;
252  }
253 
254  prefixed_msg_len = msg_len + prefix_len;
255  prefixed_msg = tor_malloc_zero(prefixed_msg_len);
256 
257  memcpy(prefixed_msg, prefix_str, prefix_len);
258  memcpy(prefixed_msg + prefix_len, msg, msg_len);
259 
260  *final_msg_len_out = prefixed_msg_len;
261  return prefixed_msg;
262 }
263 
264 /**
265  * Set <b>signature_out</b> to a signature of the <b>len</b>-byte message
266  * <b>msg</b>, using the secret and public key in <b>keypair</b>.
267  *
268  * Return 0 if we successfully signed the message, otherwise return -1.
269  */
270 int
272  const uint8_t *msg, size_t len,
273  const ed25519_keypair_t *keypair)
274 {
275  if (get_ed_impl()->sign(signature_out->sig, msg, len,
276  keypair->seckey.seckey,
277  keypair->pubkey.pubkey) < 0) {
278  return -1;
279  }
280 
281  return 0;
282 }
283 
284 /**
285  * Like ed25519_sign(), but also prefix <b>msg</b> with <b>prefix_str</b>
286  * before signing. <b>prefix_str</b> must be a NUL-terminated string.
287  */
288 MOCK_IMPL(int,
290  const uint8_t *msg, size_t msg_len,
291  const char *prefix_str,
292  const ed25519_keypair_t *keypair))
293 {
294  int retval;
295  size_t prefixed_msg_len;
296  uint8_t *prefixed_msg;
297 
298  tor_assert(prefix_str);
299 
300  prefixed_msg = get_prefixed_msg(msg, msg_len, prefix_str,
301  &prefixed_msg_len);
302  if (BUG(!prefixed_msg)) {
303  /* LCOV_EXCL_START -- only possible when the message and prefix are
304  * ridiculously huge */
305  log_warn(LD_GENERAL, "Failed to get prefixed msg.");
306  return -1;
307  /* LCOV_EXCL_STOP */
308  }
309 
310  retval = ed25519_sign(signature_out,
311  prefixed_msg, prefixed_msg_len,
312  keypair);
313  tor_free(prefixed_msg);
314 
315  return retval;
316 }
317 
318 /**
319  * Check whether if <b>signature</b> is a valid signature for the
320  * <b>len</b>-byte message in <b>msg</b> made with the key <b>pubkey</b>.
321  *
322  * Return 0 if the signature is valid; -1 if it isn't.
323  */
324 MOCK_IMPL(int,
325 ed25519_checksig,(const ed25519_signature_t *signature,
326  const uint8_t *msg, size_t len,
327  const ed25519_public_key_t *pubkey))
328 {
329  return
330  get_ed_impl()->open(signature->sig, msg, len, pubkey->pubkey) < 0 ? -1 : 0;
331 }
332 
333 /**
334  * Like ed2519_checksig(), but also prefix <b>msg</b> with <b>prefix_str</b>
335  * before verifying signature. <b>prefix_str</b> must be a NUL-terminated
336  * string.
337  */
338 int
340  const uint8_t *msg, size_t msg_len,
341  const char *prefix_str,
342  const ed25519_public_key_t *pubkey)
343 {
344  int retval;
345  size_t prefixed_msg_len;
346  uint8_t *prefixed_msg;
347 
348  prefixed_msg = get_prefixed_msg(msg, msg_len, prefix_str,
349  &prefixed_msg_len);
350  if (BUG(!prefixed_msg)) {
351  /* LCOV_EXCL_START -- only possible when the message and prefix are
352  * ridiculously huge */
353  log_warn(LD_GENERAL, "Failed to get prefixed msg.");
354  return -1;
355  /* LCOV_EXCL_STOP */
356  }
357 
358  retval = ed25519_checksig(signature,
359  prefixed_msg, prefixed_msg_len,
360  pubkey);
361  tor_free(prefixed_msg);
362 
363  return retval;
364 }
365 
366 /** Validate every signature among those in <b>checkable</b>, which contains
367  * exactly <b>n_checkable</b> elements. If <b>okay_out</b> is non-NULL, set
368  * the i'th element of <b>okay_out</b> to 1 if the i'th element of
369  * <b>checkable</b> is valid, and to 0 otherwise. Return 0 if every signature
370  * was valid. Otherwise return -N, where N is the number of invalid
371  * signatures.
372  */
373 MOCK_IMPL(int,
374 ed25519_checksig_batch,(int *okay_out,
375  const ed25519_checkable_t *checkable,
376  int n_checkable))
377 {
378  int i, res;
379  const ed25519_impl_t *impl = get_ed_impl();
380 
381  if (impl->open_batch == NULL) {
382  /* No batch verification implementation available, fake it by checking the
383  * each signature individually.
384  */
385  res = 0;
386  for (i = 0; i < n_checkable; ++i) {
387  const ed25519_checkable_t *ch = &checkable[i];
388  int r = ed25519_checksig(&ch->signature, ch->msg, ch->len, ch->pubkey);
389  if (r < 0)
390  --res;
391  if (okay_out)
392  okay_out[i] = (r == 0);
393  }
394  } else {
395  /* ed25519-donna style batch verification available.
396  *
397  * Theoretically, this should only be called if n_checkable >= 3, since
398  * that's the threshold where the batch verification actually kicks in,
399  * but the only difference is a few mallocs/frees.
400  */
401  const uint8_t **ms;
402  size_t *lens;
403  const uint8_t **pks;
404  const uint8_t **sigs;
405  int *oks;
406  int all_ok;
407 
408  ms = tor_calloc(n_checkable, sizeof(uint8_t*));
409  lens = tor_calloc(n_checkable, sizeof(size_t));
410  pks = tor_calloc(n_checkable, sizeof(uint8_t*));
411  sigs = tor_calloc(n_checkable, sizeof(uint8_t*));
412  oks = okay_out ? okay_out : tor_calloc(n_checkable, sizeof(int));
413 
414  for (i = 0; i < n_checkable; ++i) {
415  ms[i] = checkable[i].msg;
416  lens[i] = checkable[i].len;
417  pks[i] = checkable[i].pubkey->pubkey;
418  sigs[i] = checkable[i].signature.sig;
419  oks[i] = 0;
420  }
421 
422  res = 0;
423  all_ok = impl->open_batch(ms, lens, pks, sigs, n_checkable, oks);
424  for (i = 0; i < n_checkable; ++i) {
425  if (!oks[i])
426  --res;
427  }
428  /* XXX: For now sanity check oks with the return value. Once we have
429  * more confidence in the code, if `all_ok == 0` we can skip iterating
430  * over oks since all the signatures were found to be valid.
431  */
432  tor_assert(((res == 0) && !all_ok) || ((res < 0) && all_ok));
433 
434  tor_free(ms);
435  tor_free(lens);
436  tor_free(pks);
437  tor_free(sigs);
438  if (! okay_out)
439  tor_free(oks);
440  }
441 
442  return res;
443 }
444 
445 /**
446  * Given a curve25519 keypair in <b>inp</b>, generate a corresponding
447  * ed25519 keypair in <b>out</b>, and set <b>signbit_out</b> to the
448  * sign bit of the X coordinate of the ed25519 key.
449  *
450  * NOTE THAT IT IS PROBABLY NOT SAFE TO USE THE GENERATED KEY FOR ANYTHING
451  * OUTSIDE OF WHAT'S PRESENTED IN PROPOSAL 228. In particular, it's probably
452  * not a great idea to use it to sign attacker-supplied anything.
453  */
454 int
456  int *signbit_out,
457  const curve25519_keypair_t *inp)
458 {
459  const char string[] = "Derive high part of ed25519 key from curve25519 key";
460  ed25519_public_key_t pubkey_check;
461  crypto_digest_t *ctx;
462  uint8_t sha512_output[DIGEST512_LEN];
463 
464  memcpy(out->seckey.seckey, inp->seckey.secret_key, 32);
465 
466  ctx = crypto_digest512_new(DIGEST_SHA512);
467  crypto_digest_add_bytes(ctx, (const char*)out->seckey.seckey, 32);
468  crypto_digest_add_bytes(ctx, (const char*)string, sizeof(string));
469  crypto_digest_get_digest(ctx, (char *)sha512_output, sizeof(sha512_output));
470  crypto_digest_free(ctx);
471  memcpy(out->seckey.seckey + 32, sha512_output, 32);
472 
473  ed25519_public_key_generate(&out->pubkey, &out->seckey);
474 
475  *signbit_out = out->pubkey.pubkey[31] >> 7;
476 
477  ed25519_public_key_from_curve25519_public_key(&pubkey_check, &inp->pubkey,
478  *signbit_out);
479 
480  tor_assert(fast_memeq(pubkey_check.pubkey, out->pubkey.pubkey, 32));
481 
482  memwipe(&pubkey_check, 0, sizeof(pubkey_check));
483  memwipe(sha512_output, 0, sizeof(sha512_output));
484 
485  return 0;
486 }
487 
488 /**
489  * Given a curve25519 public key and sign bit of X coordinate of the ed25519
490  * public key, generate the corresponding ed25519 public key.
491  */
492 int
494  const curve25519_public_key_t *pubkey_in,
495  int signbit)
496 {
497  return get_ed_impl()->pubkey_from_curve25519_pubkey(pubkey->pubkey,
498  pubkey_in->public_key,
499  signbit);
500 }
501 
502 /**
503  * Given an ed25519 keypair in <b>inp</b>, generate a corresponding
504  * ed25519 keypair in <b>out</b>, blinded by the corresponding 32-byte input
505  * in 'param'.
506  *
507  * Tor uses key blinding for the "next-generation" hidden services design:
508  * service descriptors are encrypted with a key derived from the service's
509  * long-term public key, and then signed with (and stored at a position
510  * indexed by) a short-term key derived by blinding the long-term keys.
511  *
512  * Return 0 if blinding was successful, else return -1. */
513 int
515  const ed25519_keypair_t *inp,
516  const uint8_t *param)
517 {
518  ed25519_public_key_t pubkey_check;
519 
520  get_ed_impl()->blind_secret_key(out->seckey.seckey,
521  inp->seckey.seckey, param);
522 
523  if (ed25519_public_blind(&pubkey_check, &inp->pubkey, param) < 0) {
524  return -1;
525  }
526  ed25519_public_key_generate(&out->pubkey, &out->seckey);
527 
528  tor_assert(fast_memeq(pubkey_check.pubkey, out->pubkey.pubkey, 32));
529 
530  memwipe(&pubkey_check, 0, sizeof(pubkey_check));
531 
532  return 0;
533 }
534 
535 /**
536  * Given an ed25519 public key in <b>inp</b>, generate a corresponding blinded
537  * public key in <b>out</b>, blinded with the 32-byte parameter in
538  * <b>param</b>. Return 0 on success, -1 on railure.
539  */
540 int
542  const ed25519_public_key_t *inp,
543  const uint8_t *param)
544 {
545  return get_ed_impl()->blind_public_key(out->pubkey, inp->pubkey, param);
546 }
547 
548 /**
549  * Store seckey unencrypted to <b>filename</b>, marking it with <b>tag</b>.
550  * Return 0 on success, -1 on failure.
551  */
552 int
554  const char *filename,
555  const char *tag)
556 {
557  return crypto_write_tagged_contents_to_file(filename,
558  "ed25519v1-secret",
559  tag,
560  seckey->seckey,
561  sizeof(seckey->seckey));
562 }
563 
564 /**
565  * Read seckey unencrypted from <b>filename</b>, storing it into
566  * <b>seckey_out</b>. Set *<b>tag_out</b> to the tag it was marked with.
567  * Return 0 on success, -1 on failure.
568  */
569 int
571  char **tag_out,
572  const char *filename)
573 {
574  ssize_t len;
575 
576  len = crypto_read_tagged_contents_from_file(filename, "ed25519v1-secret",
577  tag_out, seckey_out->seckey,
578  sizeof(seckey_out->seckey));
579  if (len == sizeof(seckey_out->seckey)) {
580  return 0;
581  } else if (len >= 0) {
582  errno = EINVAL;
583  }
584 
585  tor_free(*tag_out);
586  return -1;
587 }
588 
589 /**
590  * Store pubkey unencrypted to <b>filename</b>, marking it with <b>tag</b>.
591  * Return 0 on success, -1 on failure.
592  */
593 int
595  const char *filename,
596  const char *tag)
597 {
598  return crypto_write_tagged_contents_to_file(filename,
599  "ed25519v1-public",
600  tag,
601  pubkey->pubkey,
602  sizeof(pubkey->pubkey));
603 }
604 
605 /**
606  * Store pubkey unencrypted to <b>filename</b>, marking it with <b>tag</b>.
607  * Return 0 on success, -1 on failure.
608  */
609 int
611  char **tag_out,
612  const char *filename)
613 {
614  ssize_t len;
615 
616  len = crypto_read_tagged_contents_from_file(filename, "ed25519v1-public",
617  tag_out, pubkey_out->pubkey,
618  sizeof(pubkey_out->pubkey));
619  if (len == sizeof(pubkey_out->pubkey)) {
620  return 0;
621  } else if (len >= 0) {
622  errno = EINVAL;
623  }
624 
625  tor_free(*tag_out);
626  return -1;
627 }
628 
629 /** Release all storage held for <b>kp</b>. */
630 void
632 {
633  if (! kp)
634  return;
635 
636  memwipe(kp, 0, sizeof(*kp));
637  tor_free(kp);
638 }
639 
640 /** Return true iff <b>key1</b> and <b>key2</b> are the same public key. */
641 int
643  const ed25519_public_key_t *key2)
644 {
645  tor_assert(key1);
646  tor_assert(key2);
647  return tor_memeq(key1->pubkey, key2->pubkey, ED25519_PUBKEY_LEN);
648 }
649 
650 /**
651  * Set <b>dest</b> to contain the same key as <b>src</b>.
652  */
653 void
655  const ed25519_public_key_t *src)
656 {
657  tor_assert(dest);
658  tor_assert(src);
659  memcpy(dest, src, sizeof(ed25519_public_key_t));
660 }
661 
662 /** Check whether the given Ed25519 implementation seems to be working.
663  * If so, return 0; otherwise return -1. */
664 MOCK_IMPL(STATIC int,
666 {
667  static const uint8_t alicesk[32] = {
668  0xc5,0xaa,0x8d,0xf4,0x3f,0x9f,0x83,0x7b,
669  0xed,0xb7,0x44,0x2f,0x31,0xdc,0xb7,0xb1,
670  0x66,0xd3,0x85,0x35,0x07,0x6f,0x09,0x4b,
671  0x85,0xce,0x3a,0x2e,0x0b,0x44,0x58,0xf7
672  };
673  static const uint8_t alicepk[32] = {
674  0xfc,0x51,0xcd,0x8e,0x62,0x18,0xa1,0xa3,
675  0x8d,0xa4,0x7e,0xd0,0x02,0x30,0xf0,0x58,
676  0x08,0x16,0xed,0x13,0xba,0x33,0x03,0xac,
677  0x5d,0xeb,0x91,0x15,0x48,0x90,0x80,0x25
678  };
679  static const uint8_t alicemsg[2] = { 0xaf, 0x82 };
680  static const uint8_t alicesig[64] = {
681  0x62,0x91,0xd6,0x57,0xde,0xec,0x24,0x02,
682  0x48,0x27,0xe6,0x9c,0x3a,0xbe,0x01,0xa3,
683  0x0c,0xe5,0x48,0xa2,0x84,0x74,0x3a,0x44,
684  0x5e,0x36,0x80,0xd7,0xdb,0x5a,0xc3,0xac,
685  0x18,0xff,0x9b,0x53,0x8d,0x16,0xf2,0x90,
686  0xae,0x67,0xf7,0x60,0x98,0x4d,0xc6,0x59,
687  0x4a,0x7c,0x15,0xe9,0x71,0x6e,0xd2,0x8d,
688  0xc0,0x27,0xbe,0xce,0xea,0x1e,0xc4,0x0a
689  };
690  const ed25519_impl_t *impl = get_ed_impl();
691  uint8_t sk[ED25519_SECKEY_LEN];
692  uint8_t pk[ED25519_PUBKEY_LEN];
693  uint8_t sig[ED25519_SIG_LEN];
694  int r = 0;
695 
696  /* Some implementations (eg: The modified Ed25519-donna) have handy self-test
697  * code that sanity-checks the internals. If present, use that to screen out
698  * catastrophic errors like massive compiler failure.
699  */
700  if (impl->selftest && impl->selftest() != 0)
701  goto fail;
702 
703  /* Validate results versus known answer tests. People really should be
704  * running "make test" instead of relying on this, but it's better than
705  * nothing.
706  *
707  * Test vectors taken from "EdDSA & Ed25519 - 6. Test Vectors for Ed25519
708  * (TEST3)" (draft-josefsson-eddsa-ed25519-03).
709  */
710 
711  /* Key expansion, public key derivation. */
712  if (impl->seckey_expand(sk, alicesk) < 0)
713  goto fail;
714  if (impl->pubkey(pk, sk) < 0)
715  goto fail;
716  if (fast_memneq(pk, alicepk, ED25519_PUBKEY_LEN))
717  goto fail;
718 
719  /* Signing, verification. */
720  if (impl->sign(sig, alicemsg, sizeof(alicemsg), sk, pk) < 0)
721  return -1;
722  if (fast_memneq(sig, alicesig, ED25519_SIG_LEN))
723  return -1;
724  if (impl->open(sig, alicemsg, sizeof(alicemsg), pk) < 0)
725  return -1;
726 
727  /* XXX/yawning: Someone that's more paranoid than I am, can write "Assume
728  * ref0 is canonical, and fuzz impl against it" if they want, but I doubt
729  * that will catch anything that the known answer tests won't.
730  */
731  goto end;
732 
733  // LCOV_EXCL_START -- We can only reach this if our ed25519 implementation is
734  // broken.
735  fail:
736  r = -1;
737  // LCOV_EXCL_STOP
738  end:
739  return r;
740 }
741 
742 /** Force the Ed25519 implementation to a given one, without sanity checking
743  * the output. Used for testing.
744  */
745 void
747 {
748  if (use_donna)
750  else
752 }
753 
754 /** Choose whether to use the Ed25519-donna implementation. */
755 static void
757 {
759 
760  if (ed25519_impl_spot_check() == 0)
761  return;
762 
763  /* LCOV_EXCL_START
764  * unreachable unless ed25519_donna is broken */
765  log_warn(LD_CRYPTO, "The Ed25519-donna implementation seems broken; using "
766  "the ref10 implementation.");
768  /* LCOV_EXCL_STOP */
769 }
770 
771 /* Initialize the Ed25519 implementation. This is necessary if you're
772  * going to use them in a multithreaded setting, and not otherwise. */
773 void
774 ed25519_init(void)
775 {
777 }
778 
779 /* Return true if <b>point</b> is the identity element of the ed25519 group. */
780 static int
781 ed25519_point_is_identity_element(const uint8_t *point)
782 {
783  /* The identity element in ed25159 is the point with coordinates (0,1). */
784  static const uint8_t ed25519_identity[32] = {
785  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
786  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
787  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
788  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
789  tor_assert(sizeof(ed25519_identity) == ED25519_PUBKEY_LEN);
790  return tor_memeq(point, ed25519_identity, sizeof(ed25519_identity));
791 }
792 
793 /** Validate <b>pubkey</b> to ensure that it has no torsion component.
794  * Return 0 if <b>pubkey</b> is valid, else return -1. */
795 int
797 {
798  uint8_t result[32] = {0};
799 
800  /* First check that we were not given the identity element */
801  if (ed25519_point_is_identity_element(pubkey->pubkey)) {
802  log_warn(LD_CRYPTO, "ed25519 pubkey is the identity");
803  return -1;
804  }
805 
806  /* For any point on the curve, doing l*point should give the identity element
807  * (where l is the group order). Do the computation and check that the
808  * identity element is returned. */
809  if (get_ed_impl()->ed25519_scalarmult_with_group_order(result,
810  pubkey->pubkey) < 0) {
811  log_warn(LD_CRYPTO, "ed25519 group order scalarmult failed");
812  return -1;
813  }
814 
815  if (!ed25519_point_is_identity_element(result)) {
816  log_warn(LD_CRYPTO, "ed25519 validation failed");
817  return -1;
818  }
819 
820  return 0;
821 }
Header for binascii.c.
const char * name
Definition: config.c:2434
Header for crypto_curve25519.c.
Headers for crypto_digest.c.
void crypto_digest_get_digest(crypto_digest_t *digest, char *out, size_t out_len)
#define crypto_digest_free(d)
void crypto_digest_add_bytes(crypto_digest_t *digest, const char *data, size_t len)
crypto_digest_t * crypto_digest512_new(digest_algorithm_t algorithm)
int ed25519_checksig_prefixed(const ed25519_signature_t *signature, const uint8_t *msg, size_t msg_len, const char *prefix_str, const ed25519_public_key_t *pubkey)
void ed25519_pubkey_copy(ed25519_public_key_t *dest, const ed25519_public_key_t *src)
int ed25519_public_key_is_zero(const ed25519_public_key_t *pubkey)
int ed25519_public_key_generate(ed25519_public_key_t *pubkey_out, const ed25519_secret_key_t *seckey)
int ed25519_validate_pubkey(const ed25519_public_key_t *pubkey)
void ed25519_keypair_free_(ed25519_keypair_t *kp)
int ed25519_checksig_batch(int *okay_out, const ed25519_checkable_t *checkable, int n_checkable)
int ed25519_seckey_read_from_file(ed25519_secret_key_t *seckey_out, char **tag_out, const char *filename)
int ed25519_sign(ed25519_signature_t *signature_out, const uint8_t *msg, size_t len, const ed25519_keypair_t *keypair)
int ed25519_secret_key_generate(ed25519_secret_key_t *seckey_out, int extra_strong)
int ed25519_keypair_generate(ed25519_keypair_t *keypair_out, int extra_strong)
int ed25519_keypair_blind(ed25519_keypair_t *out, const ed25519_keypair_t *inp, const uint8_t *param)
int ed25519_checksig(const ed25519_signature_t *signature, const uint8_t *msg, size_t len, const ed25519_public_key_t *pubkey)
int ed25519_pubkey_write_to_file(const ed25519_public_key_t *pubkey, const char *filename, const char *tag)
int ed25519_sign_prefixed(ed25519_signature_t *signature_out, const uint8_t *msg, size_t msg_len, const char *prefix_str, const ed25519_keypair_t *keypair)
static const ed25519_impl_t impl_donna
int ed25519_public_key_from_curve25519_public_key(ed25519_public_key_t *pubkey, const curve25519_public_key_t *pubkey_in, int signbit)
int ed25519_seckey_write_to_file(const ed25519_secret_key_t *seckey, const char *filename, const char *tag)
int ed25519_public_blind(ed25519_public_key_t *out, const ed25519_public_key_t *inp, const uint8_t *param)
int ed25519_pubkey_read_from_file(ed25519_public_key_t *pubkey_out, char **tag_out, const char *filename)
static const ed25519_impl_t * get_ed_impl(void)
static const ed25519_impl_t impl_ref10
int ed25519_keypair_from_curve25519_keypair(ed25519_keypair_t *out, int *signbit_out, const curve25519_keypair_t *inp)
STATIC int ed25519_impl_spot_check(void)
void ed25519_set_impl_params(int use_donna)
int ed25519_secret_key_from_seed(ed25519_secret_key_t *seckey_out, const uint8_t *seed)
static const ed25519_impl_t * ed25519_impl
int ed25519_pubkey_eq(const ed25519_public_key_t *key1, const ed25519_public_key_t *key2)
static void pick_ed25519_impl(void)
Header for crypto_ed25519.c.
ssize_t crypto_read_tagged_contents_from_file(const char *fname, const char *typestring, char **tag_out, uint8_t *data_out, ssize_t data_out_len)
Definition: crypto_format.c:77
int crypto_write_tagged_contents_to_file(const char *fname, const char *typestring, const char *tag, const uint8_t *data, size_t datalen)
Definition: crypto_format.c:42
Header for crypto_format.c.
void crypto_rand(char *to, size_t n)
Definition: crypto_rand.c:477
void crypto_strongest_rand(uint8_t *out, size_t out_len)
Definition: crypto_rand.c:340
Common functions for using (pseudo-)random number generators.
void memwipe(void *mem, uint8_t byte, size_t sz)
Definition: crypto_util.c:55
Common functions for cryptographic routines.
int tor_memeq(const void *a, const void *b, size_t sz)
Definition: di_ops.c:107
int safe_mem_is_zero(const void *mem, size_t sz)
Definition: di_ops.c:224
Headers for di_ops.c.
#define fast_memeq(a, b, c)
Definition: di_ops.h:35
#define fast_memneq(a, b, c)
Definition: di_ops.h:42
#define DIGEST512_LEN
Definition: digest_sizes.h:25
Headers for log.c.
#define LD_CRYPTO
Definition: log.h:64
#define LD_GENERAL
Definition: log.h:62
#define tor_free(p)
Definition: malloc.h:52
const ed25519_public_key_t * pubkey
ed25519_signature_t signature
const uint8_t * msg
uint8_t seckey[ED25519_SECKEY_LEN]
#define STATIC
Definition: testsupport.h:32
#define MOCK_IMPL(rv, funcname, arglist)
Definition: testsupport.h:133
#define SIZE_T_CEILING
Definition: torint.h:126
Macros to manage assertions, fatal and non-fatal.
#define tor_assert(expr)
Definition: util_bug.h:102
Header for util_string.c.
#define ED25519_SIG_LEN
Definition: x25519_sizes.h:34
#define ED25519_SECKEY_LEN
Definition: x25519_sizes.h:29
#define ED25519_PUBKEY_LEN
Definition: x25519_sizes.h:27