Merge branch 'maint-0.3.5' into maint-0.4.5
[tor.git] / src / lib / crypt_ops / crypto_ed25519.c
blob5823b4e5571b8c17cfead246ca618d01e221682e
1 /* Copyright (c) 2013-2020, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
4 /**
5 * \file crypto_ed25519.c
7 * \brief Wrapper code for an ed25519 implementation.
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/
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.
18 #define CRYPTO_ED25519_PRIVATE
19 #include "orconfig.h"
20 #ifdef HAVE_SYS_STAT_H
21 #include <sys/stat.h>
22 #endif
24 #include "lib/ctime/di_ops.h"
25 #include "lib/crypt_ops/crypto_curve25519.h"
26 #include "lib/crypt_ops/crypto_digest.h"
27 #include "lib/crypt_ops/crypto_ed25519.h"
28 #include "lib/crypt_ops/crypto_format.h"
29 #include "lib/crypt_ops/crypto_rand.h"
30 #include "lib/crypt_ops/crypto_util.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"
36 #include "ed25519/ref10/ed25519_ref10.h"
37 #include "ed25519/donna/ed25519_donna_tor.h"
39 #include <string.h>
40 #include <errno.h>
42 static void pick_ed25519_impl(void);
44 /** An Ed25519 implementation, as a set of function pointers. */
45 typedef struct {
46 int (*selftest)(void);
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 *);
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 *);
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 *);
65 int (*pubkey_from_curve25519_pubkey)(unsigned char *, const unsigned char *,
66 int);
68 int (*ed25519_scalarmult_with_group_order)(unsigned char *,
69 const unsigned char *);
70 } ed25519_impl_t;
72 /** The Ref10 Ed25519 implementation. This one is pure C and lightly
73 * optimized. */
74 static const ed25519_impl_t impl_ref10 = {
75 NULL,
77 ed25519_ref10_seckey,
78 ed25519_ref10_seckey_expand,
79 ed25519_ref10_pubkey,
80 ed25519_ref10_keygen,
82 ed25519_ref10_open,
83 ed25519_ref10_sign,
84 NULL,
86 ed25519_ref10_blind_secret_key,
87 ed25519_ref10_blind_public_key,
89 ed25519_ref10_pubkey_from_curve25519_pubkey,
90 ed25519_ref10_scalarmult_with_group_order,
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,
98 ed25519_donna_seckey,
99 ed25519_donna_seckey_expand,
100 ed25519_donna_pubkey,
101 ed25519_donna_keygen,
103 ed25519_donna_open,
104 ed25519_donna_sign,
105 NULL, /* Don't use donna's batching code because of #40078 */
107 ed25519_donna_blind_secret_key,
108 ed25519_donna_blind_public_key,
110 ed25519_donna_pubkey_from_curve25519_pubkey,
111 ed25519_donna_scalarmult_with_group_order,
114 /** Which Ed25519 implementation are we using? NULL if we haven't decided
115 * yet. */
116 static const ed25519_impl_t *ed25519_impl = NULL;
118 /** Helper: Return our chosen Ed25519 implementation.
120 * This should only be called after we've picked an implementation, but
121 * it _does_ recover if you forget this.
123 static inline const ed25519_impl_t *
124 get_ed_impl(void)
126 if (BUG(ed25519_impl == NULL)) {
127 pick_ed25519_impl(); // LCOV_EXCL_LINE - We always call ed25519_init().
129 return ed25519_impl;
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)
142 tor_assert(saved_ed25519_impl == NULL);
143 saved_ed25519_impl = ed25519_impl;
144 if (! strcmp(name, "donna")) {
145 ed25519_impl = &impl_donna;
146 } else {
147 tor_assert(!strcmp(name, "ref10"));
148 ed25519_impl = &impl_ref10;
151 /** For testing: go back to whatever Ed25519 implementation we had picked
152 * before crypto_ed25519_testing_force_impl was called.
154 void
155 crypto_ed25519_testing_restore_impl(void)
157 ed25519_impl = saved_ed25519_impl;
158 saved_ed25519_impl = NULL;
160 #endif /* defined(TOR_UNIT_TESTS) */
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.
168 ed25519_secret_key_generate(ed25519_secret_key_t *seckey_out,
169 int extra_strong)
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));
178 r = get_ed_impl()->seckey_expand(seckey_out->seckey, seed);
179 memwipe(seed, 0, sizeof(seed));
181 return r < 0 ? -1 : 0;
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.
189 ed25519_secret_key_from_seed(ed25519_secret_key_t *seckey_out,
190 const uint8_t *seed)
192 if (get_ed_impl()->seckey_expand(seckey_out->seckey, seed) < 0)
193 return -1;
194 return 0;
198 * Given a secret key in <b>seckey</b>, expand it into an
199 * ed25519 public key. Return 0 on success, -1 on failure.
202 ed25519_public_key_generate(ed25519_public_key_t *pubkey_out,
203 const ed25519_secret_key_t *seckey)
205 if (get_ed_impl()->pubkey(pubkey_out->pubkey, seckey->seckey) < 0)
206 return -1;
207 return 0;
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. */
214 ed25519_keypair_generate(ed25519_keypair_t *keypair_out, int extra_strong)
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;
224 /** Return true iff 'pubkey' is set to zero (eg to indicate that it is not
225 * set). */
227 ed25519_public_key_is_zero(const ed25519_public_key_t *pubkey)
229 return safe_mem_is_zero((char*)pubkey->pubkey, ED25519_PUBKEY_LEN);
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)
241 size_t prefixed_msg_len, prefix_len;
242 uint8_t *prefixed_msg;
244 tor_assert(prefix_str);
245 tor_assert(final_msg_len_out);
247 prefix_len = strlen(prefix_str);
249 /* msg_len + strlen(prefix_str) must not overflow. */
250 if (msg_len > SIZE_T_CEILING - prefix_len) {
251 return NULL;
254 prefixed_msg_len = msg_len + prefix_len;
255 prefixed_msg = tor_malloc_zero(prefixed_msg_len);
257 memcpy(prefixed_msg, prefix_str, prefix_len);
258 memcpy(prefixed_msg + prefix_len, msg, msg_len);
260 *final_msg_len_out = prefixed_msg_len;
261 return prefixed_msg;
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>.
268 * Return 0 if we successfully signed the message, otherwise return -1.
271 ed25519_sign(ed25519_signature_t *signature_out,
272 const uint8_t *msg, size_t len,
273 const ed25519_keypair_t *keypair)
275 if (get_ed_impl()->sign(signature_out->sig, msg, len,
276 keypair->seckey.seckey,
277 keypair->pubkey.pubkey) < 0) {
278 return -1;
281 return 0;
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.
288 MOCK_IMPL(int,
289 ed25519_sign_prefixed,(ed25519_signature_t *signature_out,
290 const uint8_t *msg, size_t msg_len,
291 const char *prefix_str,
292 const ed25519_keypair_t *keypair))
294 int retval;
295 size_t prefixed_msg_len;
296 uint8_t *prefixed_msg;
298 tor_assert(prefix_str);
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 */
310 retval = ed25519_sign(signature_out,
311 prefixed_msg, prefixed_msg_len,
312 keypair);
313 tor_free(prefixed_msg);
315 return retval;
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>.
322 * Return 0 if the signature is valid; -1 if it isn't.
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))
329 return
330 get_ed_impl()->open(signature->sig, msg, len, pubkey->pubkey) < 0 ? -1 : 0;
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.
339 ed25519_checksig_prefixed(const ed25519_signature_t *signature,
340 const uint8_t *msg, size_t msg_len,
341 const char *prefix_str,
342 const ed25519_public_key_t *pubkey)
344 int retval;
345 size_t prefixed_msg_len;
346 uint8_t *prefixed_msg;
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 */
358 retval = ed25519_checksig(signature,
359 prefixed_msg, prefixed_msg_len,
360 pubkey);
361 tor_free(prefixed_msg);
363 return retval;
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.
373 MOCK_IMPL(int,
374 ed25519_checksig_batch,(int *okay_out,
375 const ed25519_checkable_t *checkable,
376 int n_checkable))
378 int i, res;
379 const ed25519_impl_t *impl = get_ed_impl();
381 if (impl->open_batch == NULL) {
382 /* No batch verification implementation available, fake it by checking the
383 * each signature individually.
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);
394 } else {
395 /* ed25519-donna style batch verification available.
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.
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;
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));
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;
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;
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.
432 tor_assert(((res == 0) && !all_ok) || ((res < 0) && all_ok));
434 tor_free(ms);
435 tor_free(lens);
436 tor_free(pks);
437 tor_free(sigs);
438 if (! okay_out)
439 tor_free(oks);
442 return res;
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.
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.
455 ed25519_keypair_from_curve25519_keypair(ed25519_keypair_t *out,
456 int *signbit_out,
457 const curve25519_keypair_t *inp)
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];
464 memcpy(out->seckey.seckey, inp->seckey.secret_key, 32);
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);
473 ed25519_public_key_generate(&out->pubkey, &out->seckey);
475 *signbit_out = out->pubkey.pubkey[31] >> 7;
477 ed25519_public_key_from_curve25519_public_key(&pubkey_check, &inp->pubkey,
478 *signbit_out);
480 tor_assert(fast_memeq(pubkey_check.pubkey, out->pubkey.pubkey, 32));
482 memwipe(&pubkey_check, 0, sizeof(pubkey_check));
483 memwipe(sha512_output, 0, sizeof(sha512_output));
485 return 0;
489 * Given a curve25519 public key and sign bit of X coordinate of the ed25519
490 * public key, generate the corresponding ed25519 public key.
493 ed25519_public_key_from_curve25519_public_key(ed25519_public_key_t *pubkey,
494 const curve25519_public_key_t *pubkey_in,
495 int signbit)
497 return get_ed_impl()->pubkey_from_curve25519_pubkey(pubkey->pubkey,
498 pubkey_in->public_key,
499 signbit);
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'.
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.
512 * Return 0 if blinding was successful, else return -1. */
514 ed25519_keypair_blind(ed25519_keypair_t *out,
515 const ed25519_keypair_t *inp,
516 const uint8_t *param)
518 ed25519_public_key_t pubkey_check;
520 get_ed_impl()->blind_secret_key(out->seckey.seckey,
521 inp->seckey.seckey, param);
523 if (ed25519_public_blind(&pubkey_check, &inp->pubkey, param) < 0) {
524 return -1;
526 ed25519_public_key_generate(&out->pubkey, &out->seckey);
528 tor_assert(fast_memeq(pubkey_check.pubkey, out->pubkey.pubkey, 32));
530 memwipe(&pubkey_check, 0, sizeof(pubkey_check));
532 return 0;
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.
541 ed25519_public_blind(ed25519_public_key_t *out,
542 const ed25519_public_key_t *inp,
543 const uint8_t *param)
545 return get_ed_impl()->blind_public_key(out->pubkey, inp->pubkey, param);
549 * Store seckey unencrypted to <b>filename</b>, marking it with <b>tag</b>.
550 * Return 0 on success, -1 on failure.
553 ed25519_seckey_write_to_file(const ed25519_secret_key_t *seckey,
554 const char *filename,
555 const char *tag)
557 return crypto_write_tagged_contents_to_file(filename,
558 "ed25519v1-secret",
559 tag,
560 seckey->seckey,
561 sizeof(seckey->seckey));
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.
570 ed25519_seckey_read_from_file(ed25519_secret_key_t *seckey_out,
571 char **tag_out,
572 const char *filename)
574 ssize_t len;
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;
585 tor_free(*tag_out);
586 return -1;
590 * Store pubkey unencrypted to <b>filename</b>, marking it with <b>tag</b>.
591 * Return 0 on success, -1 on failure.
594 ed25519_pubkey_write_to_file(const ed25519_public_key_t *pubkey,
595 const char *filename,
596 const char *tag)
598 return crypto_write_tagged_contents_to_file(filename,
599 "ed25519v1-public",
600 tag,
601 pubkey->pubkey,
602 sizeof(pubkey->pubkey));
606 * Store pubkey unencrypted to <b>filename</b>, marking it with <b>tag</b>.
607 * Return 0 on success, -1 on failure.
610 ed25519_pubkey_read_from_file(ed25519_public_key_t *pubkey_out,
611 char **tag_out,
612 const char *filename)
614 ssize_t len;
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;
625 tor_free(*tag_out);
626 return -1;
629 /** Release all storage held for <b>kp</b>. */
630 void
631 ed25519_keypair_free_(ed25519_keypair_t *kp)
633 if (! kp)
634 return;
636 memwipe(kp, 0, sizeof(*kp));
637 tor_free(kp);
640 /** Return true iff <b>key1</b> and <b>key2</b> are the same public key. */
642 ed25519_pubkey_eq(const ed25519_public_key_t *key1,
643 const ed25519_public_key_t *key2)
645 tor_assert(key1);
646 tor_assert(key2);
647 return tor_memeq(key1->pubkey, key2->pubkey, ED25519_PUBKEY_LEN);
651 * Set <b>dest</b> to contain the same key as <b>src</b>.
653 void
654 ed25519_pubkey_copy(ed25519_public_key_t *dest,
655 const ed25519_public_key_t *src)
657 tor_assert(dest);
658 tor_assert(src);
659 memcpy(dest, src, sizeof(ed25519_public_key_t));
662 /** Check whether the given Ed25519 implementation seems to be working.
663 * If so, return 0; otherwise return -1. */
664 MOCK_IMPL(STATIC int,
665 ed25519_impl_spot_check,(void))
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
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
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
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;
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.
700 if (impl->selftest && impl->selftest() != 0)
701 goto fail;
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.
707 * Test vectors taken from "EdDSA & Ed25519 - 6. Test Vectors for Ed25519
708 * (TEST3)" (draft-josefsson-eddsa-ed25519-03).
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;
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;
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.
731 goto end;
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;
742 /** Force the Ed25519 implementation to a given one, without sanity checking
743 * the output. Used for testing.
745 void
746 ed25519_set_impl_params(int use_donna)
748 if (use_donna)
749 ed25519_impl = &impl_donna;
750 else
751 ed25519_impl = &impl_ref10;
754 /** Choose whether to use the Ed25519-donna implementation. */
755 static void
756 pick_ed25519_impl(void)
758 ed25519_impl = &impl_donna;
760 if (ed25519_impl_spot_check() == 0)
761 return;
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.");
767 ed25519_impl = &impl_ref10;
768 /* LCOV_EXCL_STOP */
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)
776 pick_ed25519_impl();
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)
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));
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. */
796 ed25519_validate_pubkey(const ed25519_public_key_t *pubkey)
798 uint8_t result[32] = {0};
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;
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;
815 if (!ed25519_point_is_identity_element(result)) {
816 log_warn(LD_CRYPTO, "ed25519 validation failed");
817 return -1;
820 return 0;