Line data Source code
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"
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"
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 *);
70 : } ed25519_impl_t;
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 *
124 41431 : get_ed_impl(void)
125 : {
126 41431 : if (BUG(ed25519_impl == NULL)) {
127 : pick_ed25519_impl(); // LCOV_EXCL_LINE - We always call ed25519_init().
128 : }
129 41431 : 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 18 : crypto_ed25519_testing_force_impl(const char *name)
141 : {
142 18 : tor_assert(saved_ed25519_impl == NULL);
143 18 : saved_ed25519_impl = ed25519_impl;
144 18 : if (! strcmp(name, "donna")) {
145 9 : ed25519_impl = &impl_donna;
146 : } else {
147 9 : tor_assert(!strcmp(name, "ref10"));
148 9 : ed25519_impl = &impl_ref10;
149 : }
150 18 : }
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 18 : crypto_ed25519_testing_restore_impl(void)
156 : {
157 18 : ed25519_impl = saved_ed25519_impl;
158 18 : saved_ed25519_impl = NULL;
159 18 : }
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
168 2564 : ed25519_secret_key_generate(ed25519_secret_key_t *seckey_out,
169 : int extra_strong)
170 : {
171 2564 : int r;
172 2564 : uint8_t seed[32];
173 2564 : if (extra_strong)
174 1058 : crypto_strongest_rand(seed, sizeof(seed));
175 : else
176 1506 : crypto_rand((char*)seed, sizeof(seed));
177 :
178 2564 : r = get_ed_impl()->seckey_expand(seckey_out->seckey, seed);
179 2564 : memwipe(seed, 0, sizeof(seed));
180 :
181 2564 : 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
189 57 : ed25519_secret_key_from_seed(ed25519_secret_key_t *seckey_out,
190 : const uint8_t *seed)
191 : {
192 57 : if (get_ed_impl()->seckey_expand(seckey_out->seckey, seed) < 0)
193 0 : 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
202 9164 : ed25519_public_key_generate(ed25519_public_key_t *pubkey_out,
203 : const ed25519_secret_key_t *seckey)
204 : {
205 9164 : if (get_ed_impl()->pubkey(pubkey_out->pubkey, seckey->seckey) < 0)
206 0 : 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 2519 : ed25519_keypair_generate(ed25519_keypair_t *keypair_out, int extra_strong)
215 : {
216 2519 : if (ed25519_secret_key_generate(&keypair_out->seckey, extra_strong) < 0)
217 : return -1;
218 2519 : if (ed25519_public_key_generate(&keypair_out->pubkey,
219 : &keypair_out->seckey)<0)
220 0 : 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
227 42917 : ed25519_public_key_is_zero(const ed25519_public_key_t *pubkey)
228 : {
229 42917 : 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 186 : 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 186 : size_t prefixed_msg_len, prefix_len;
242 186 : uint8_t *prefixed_msg;
243 :
244 186 : tor_assert(prefix_str);
245 186 : tor_assert(final_msg_len_out);
246 :
247 186 : prefix_len = strlen(prefix_str);
248 :
249 : /* msg_len + strlen(prefix_str) must not overflow. */
250 186 : if (msg_len > SIZE_T_CEILING - prefix_len) {
251 : return NULL;
252 : }
253 :
254 186 : prefixed_msg_len = msg_len + prefix_len;
255 186 : prefixed_msg = tor_malloc_zero(prefixed_msg_len);
256 :
257 186 : memcpy(prefixed_msg, prefix_str, prefix_len);
258 186 : memcpy(prefixed_msg + prefix_len, msg, msg_len);
259 :
260 186 : *final_msg_len_out = prefixed_msg_len;
261 186 : 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
271 4873 : ed25519_sign(ed25519_signature_t *signature_out,
272 : const uint8_t *msg, size_t len,
273 : const ed25519_keypair_t *keypair)
274 : {
275 9746 : if (get_ed_impl()->sign(signature_out->sig, msg, len,
276 4873 : keypair->seckey.seckey,
277 4873 : keypair->pubkey.pubkey) < 0) {
278 0 : 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 77 : 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))
293 : {
294 77 : int retval;
295 77 : size_t prefixed_msg_len;
296 77 : uint8_t *prefixed_msg;
297 :
298 77 : tor_assert(prefix_str);
299 :
300 77 : prefixed_msg = get_prefixed_msg(msg, msg_len, prefix_str,
301 : &prefixed_msg_len);
302 77 : 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 77 : retval = ed25519_sign(signature_out,
311 : prefixed_msg, prefixed_msg_len,
312 : keypair);
313 77 : tor_free(prefixed_msg);
314 :
315 77 : 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 6640 : 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 6640 : return
330 6640 : 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
339 109 : 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)
343 : {
344 109 : int retval;
345 109 : size_t prefixed_msg_len;
346 109 : uint8_t *prefixed_msg;
347 :
348 109 : prefixed_msg = get_prefixed_msg(msg, msg_len, prefix_str,
349 : &prefixed_msg_len);
350 109 : 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 109 : retval = ed25519_checksig(signature,
359 : prefixed_msg, prefixed_msg_len,
360 : pubkey);
361 109 : tor_free(prefixed_msg);
362 :
363 109 : 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 1326 : MOCK_IMPL(int,
374 : ed25519_checksig_batch,(int *okay_out,
375 : const ed25519_checkable_t *checkable,
376 : int n_checkable))
377 : {
378 1326 : int i, res;
379 1326 : const ed25519_impl_t *impl = get_ed_impl();
380 :
381 1326 : 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 16 : for (i = 0; i < n_checkable; ++i) {
387 12 : const ed25519_checkable_t *ch = &checkable[i];
388 12 : int r = ed25519_checksig(&ch->signature, ch->msg, ch->len, ch->pubkey);
389 12 : if (r < 0)
390 4 : --res;
391 12 : if (okay_out)
392 6 : 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 1322 : const uint8_t **ms;
402 1322 : size_t *lens;
403 1322 : const uint8_t **pks;
404 1322 : const uint8_t **sigs;
405 1322 : int *oks;
406 1322 : int all_ok;
407 :
408 1322 : ms = tor_calloc(n_checkable, sizeof(uint8_t*));
409 1322 : lens = tor_calloc(n_checkable, sizeof(size_t));
410 1322 : pks = tor_calloc(n_checkable, sizeof(uint8_t*));
411 1322 : sigs = tor_calloc(n_checkable, sizeof(uint8_t*));
412 1322 : oks = okay_out ? okay_out : tor_calloc(n_checkable, sizeof(int));
413 :
414 2830 : for (i = 0; i < n_checkable; ++i) {
415 1508 : ms[i] = checkable[i].msg;
416 1508 : lens[i] = checkable[i].len;
417 1508 : pks[i] = checkable[i].pubkey->pubkey;
418 1508 : sigs[i] = checkable[i].signature.sig;
419 1508 : oks[i] = 0;
420 : }
421 :
422 1322 : res = 0;
423 1322 : all_ok = impl->open_batch(ms, lens, pks, sigs, n_checkable, oks);
424 4152 : for (i = 0; i < n_checkable; ++i) {
425 1508 : if (!oks[i])
426 10 : --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 1322 : tor_assert(((res == 0) && !all_ok) || ((res < 0) && all_ok));
433 :
434 1322 : tor_free(ms);
435 1322 : tor_free(lens);
436 1322 : tor_free(pks);
437 1322 : tor_free(sigs);
438 1322 : if (! okay_out)
439 7 : tor_free(oks);
440 : }
441 :
442 1326 : 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
455 2243 : ed25519_keypair_from_curve25519_keypair(ed25519_keypair_t *out,
456 : int *signbit_out,
457 : const curve25519_keypair_t *inp)
458 : {
459 2243 : const char string[] = "Derive high part of ed25519 key from curve25519 key";
460 2243 : ed25519_public_key_t pubkey_check;
461 2243 : crypto_digest_t *ctx;
462 2243 : uint8_t sha512_output[DIGEST512_LEN];
463 :
464 2243 : memcpy(out->seckey.seckey, inp->seckey.secret_key, 32);
465 :
466 2243 : ctx = crypto_digest512_new(DIGEST_SHA512);
467 2243 : crypto_digest_add_bytes(ctx, (const char*)out->seckey.seckey, 32);
468 2243 : crypto_digest_add_bytes(ctx, (const char*)string, sizeof(string));
469 2243 : crypto_digest_get_digest(ctx, (char *)sha512_output, sizeof(sha512_output));
470 2243 : crypto_digest_free(ctx);
471 2243 : memcpy(out->seckey.seckey + 32, sha512_output, 32);
472 :
473 2243 : ed25519_public_key_generate(&out->pubkey, &out->seckey);
474 :
475 2243 : *signbit_out = out->pubkey.pubkey[31] >> 7;
476 :
477 2243 : ed25519_public_key_from_curve25519_public_key(&pubkey_check, &inp->pubkey,
478 : *signbit_out);
479 :
480 2243 : tor_assert(fast_memeq(pubkey_check.pubkey, out->pubkey.pubkey, 32));
481 :
482 2243 : memwipe(&pubkey_check, 0, sizeof(pubkey_check));
483 2243 : memwipe(sha512_output, 0, sizeof(sha512_output));
484 :
485 2243 : 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
493 4473 : ed25519_public_key_from_curve25519_public_key(ed25519_public_key_t *pubkey,
494 : const curve25519_public_key_t *pubkey_in,
495 : int signbit)
496 : {
497 4473 : return get_ed_impl()->pubkey_from_curve25519_pubkey(pubkey->pubkey,
498 4473 : 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
514 2201 : ed25519_keypair_blind(ed25519_keypair_t *out,
515 : const ed25519_keypair_t *inp,
516 : const uint8_t *param)
517 : {
518 2201 : ed25519_public_key_t pubkey_check;
519 :
520 2201 : get_ed_impl()->blind_secret_key(out->seckey.seckey,
521 2201 : inp->seckey.seckey, param);
522 :
523 2201 : if (ed25519_public_blind(&pubkey_check, &inp->pubkey, param) < 0) {
524 : return -1;
525 : }
526 2201 : ed25519_public_key_generate(&out->pubkey, &out->seckey);
527 :
528 2201 : tor_assert(fast_memeq(pubkey_check.pubkey, out->pubkey.pubkey, 32));
529 :
530 2201 : memwipe(&pubkey_check, 0, sizeof(pubkey_check));
531 :
532 2201 : 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
541 4423 : ed25519_public_blind(ed25519_public_key_t *out,
542 : const ed25519_public_key_t *inp,
543 : const uint8_t *param)
544 : {
545 4423 : 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
553 30 : ed25519_seckey_write_to_file(const ed25519_secret_key_t *seckey,
554 : const char *filename,
555 : const char *tag)
556 : {
557 60 : return crypto_write_tagged_contents_to_file(filename,
558 : "ed25519v1-secret",
559 : tag,
560 30 : 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
570 107 : ed25519_seckey_read_from_file(ed25519_secret_key_t *seckey_out,
571 : char **tag_out,
572 : const char *filename)
573 : {
574 107 : ssize_t len;
575 :
576 214 : len = crypto_read_tagged_contents_from_file(filename, "ed25519v1-secret",
577 107 : tag_out, seckey_out->seckey,
578 : sizeof(seckey_out->seckey));
579 107 : if (len == sizeof(seckey_out->seckey)) {
580 : return 0;
581 59 : } else if (len >= 0) {
582 1 : errno = EINVAL;
583 : }
584 :
585 59 : tor_free(*tag_out);
586 59 : 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
594 16 : ed25519_pubkey_write_to_file(const ed25519_public_key_t *pubkey,
595 : const char *filename,
596 : const char *tag)
597 : {
598 32 : return crypto_write_tagged_contents_to_file(filename,
599 : "ed25519v1-public",
600 : tag,
601 16 : 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
610 93 : ed25519_pubkey_read_from_file(ed25519_public_key_t *pubkey_out,
611 : char **tag_out,
612 : const char *filename)
613 : {
614 93 : ssize_t len;
615 :
616 186 : len = crypto_read_tagged_contents_from_file(filename, "ed25519v1-public",
617 93 : tag_out, pubkey_out->pubkey,
618 : sizeof(pubkey_out->pubkey));
619 93 : if (len == sizeof(pubkey_out->pubkey)) {
620 : return 0;
621 53 : } else if (len >= 0) {
622 1 : errno = EINVAL;
623 : }
624 :
625 53 : tor_free(*tag_out);
626 53 : return -1;
627 : }
628 :
629 : /** Release all storage held for <b>kp</b>. */
630 : void
631 1229 : ed25519_keypair_free_(ed25519_keypair_t *kp)
632 : {
633 1229 : if (! kp)
634 : return;
635 :
636 173 : memwipe(kp, 0, sizeof(*kp));
637 173 : tor_free(kp);
638 : }
639 :
640 : /** Return true iff <b>key1</b> and <b>key2</b> are the same public key. */
641 : int
642 16238 : ed25519_pubkey_eq(const ed25519_public_key_t *key1,
643 : const ed25519_public_key_t *key2)
644 : {
645 16238 : tor_assert(key1);
646 16238 : tor_assert(key2);
647 16238 : 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
654 357 : ed25519_pubkey_copy(ed25519_public_key_t *dest,
655 : const ed25519_public_key_t *src)
656 : {
657 357 : tor_assert(dest);
658 357 : tor_assert(src);
659 357 : memcpy(dest, src, sizeof(ed25519_public_key_t));
660 357 : }
661 :
662 : /** Check whether the given Ed25519 implementation seems to be working.
663 : * If so, return 0; otherwise return -1. */
664 5561 : MOCK_IMPL(STATIC int,
665 : ed25519_impl_spot_check,(void))
666 : {
667 5561 : 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 5561 : 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 5561 : static const uint8_t alicemsg[2] = { 0xaf, 0x82 };
680 5561 : 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 5561 : const ed25519_impl_t *impl = get_ed_impl();
691 5561 : uint8_t sk[ED25519_SECKEY_LEN];
692 5561 : uint8_t pk[ED25519_PUBKEY_LEN];
693 5561 : uint8_t sig[ED25519_SIG_LEN];
694 5561 : 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 5561 : if (impl->selftest && impl->selftest() != 0)
701 0 : 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 5561 : if (impl->seckey_expand(sk, alicesk) < 0)
713 0 : goto fail;
714 5561 : if (impl->pubkey(pk, sk) < 0)
715 0 : goto fail;
716 5561 : if (fast_memneq(pk, alicepk, ED25519_PUBKEY_LEN))
717 0 : goto fail;
718 :
719 : /* Signing, verification. */
720 5561 : if (impl->sign(sig, alicemsg, sizeof(alicemsg), sk, pk) < 0)
721 : return -1;
722 5561 : if (fast_memneq(sig, alicesig, ED25519_SIG_LEN))
723 : return -1;
724 5561 : 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 5561 : 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
746 4096 : ed25519_set_impl_params(int use_donna)
747 : {
748 4096 : if (use_donna)
749 2048 : ed25519_impl = &impl_donna;
750 : else
751 2048 : ed25519_impl = &impl_ref10;
752 4096 : }
753 :
754 : /** Choose whether to use the Ed25519-donna implementation. */
755 : static void
756 9558 : pick_ed25519_impl(void)
757 : {
758 9558 : ed25519_impl = &impl_donna;
759 :
760 9558 : 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.");
767 : ed25519_impl = &impl_ref10;
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 9558 : ed25519_init(void)
775 : {
776 9558 : pick_ed25519_impl();
777 9558 : }
778 :
779 : /* Return true if <b>point</b> is the identity element of the ed25519 group. */
780 : static int
781 296 : ed25519_point_is_identity_element(const uint8_t *point)
782 : {
783 : /* The identity element in ed25159 is the point with coordinates (0,1). */
784 296 : 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 296 : tor_assert(sizeof(ed25519_identity) == ED25519_PUBKEY_LEN);
790 296 : 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
796 150 : ed25519_validate_pubkey(const ed25519_public_key_t *pubkey)
797 : {
798 150 : uint8_t result[32] = {0};
799 :
800 : /* First check that we were not given the identity element */
801 150 : if (ed25519_point_is_identity_element(pubkey->pubkey)) {
802 1 : log_warn(LD_CRYPTO, "ed25519 pubkey is the identity");
803 1 : 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 149 : if (get_ed_impl()->ed25519_scalarmult_with_group_order(result,
810 : pubkey->pubkey) < 0) {
811 3 : log_warn(LD_CRYPTO, "ed25519 group order scalarmult failed");
812 3 : return -1;
813 : }
814 :
815 146 : if (!ed25519_point_is_identity_element(result)) {
816 6 : log_warn(LD_CRYPTO, "ed25519 validation failed");
817 6 : return -1;
818 : }
819 :
820 : return 0;
821 : }
|