Tor 0.4.9.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"
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
42static void pick_ed25519_impl(void);
43
44/** An Ed25519 implementation, as a set of function pointers. */
45typedef 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. */
74static 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. */
95static 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 NULL, /* Don't use donna's batching code because of #40078 */
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. */
116static 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 **/
123static 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 */
135static 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". */
139void
140crypto_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 */
154void
155crypto_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 */
167int
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 */
188int
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 */
201int
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. */
213int
214ed25519_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). */
226int
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. */
236static uint8_t *
237get_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 */
270int
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 */
288MOCK_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 */
324MOCK_IMPL(int,
325ed25519_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 */
338int
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 */
373MOCK_IMPL(int,
374ed25519_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 */
454int
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));
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 */
492int
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. */
513int
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 */
540int
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 */
552int
554 const char *filename,
555 const char *tag)
556{
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 */
569int
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 */
593int
595 const char *filename,
596 const char *tag)
597{
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 */
609int
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>. */
630void
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. */
641int
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 */
653void
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. */
664MOCK_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 */
745void
747{
748 if (use_donna)
750 else
752}
753
754/** Choose whether to use the Ed25519-donna implementation. */
755static 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. */
773void
774ed25519_init(void)
775{
777}
778
779/* Return true if <b>point</b> is the identity element of the ed25519 group. */
780static int
781ed25519_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. */
795int
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:2462
Header for crypto_curve25519.c.
Headers for crypto_digest.c.
crypto_digest_t * crypto_digest512_new(digest_algorithm_t algorithm)
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)
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)
static const ed25519_impl_t * get_ed_impl(void)
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 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:479
void crypto_strongest_rand(uint8_t *out, size_t out_len)
Definition: crypto_rand.c:342
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:56
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:103
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