diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/crypto_curve25519.c | 52 | ||||
-rw-r--r-- | src/common/crypto_curve25519.h | 12 | ||||
-rw-r--r-- | src/common/crypto_ed25519.c | 29 | ||||
-rw-r--r-- | src/common/crypto_format.c | 7 | ||||
-rw-r--r-- | src/common/workqueue.c | 14 |
5 files changed, 107 insertions, 7 deletions
diff --git a/src/common/crypto_curve25519.c b/src/common/crypto_curve25519.c index 58ec923638..0a744ef56d 100644 --- a/src/common/crypto_curve25519.c +++ b/src/common/crypto_curve25519.c @@ -5,6 +5,14 @@ * \file crypto_curve25519.c * * \brief Wrapper code for a curve25519 implementation. + * + * Curve25519 is an Elliptic-Curve Diffie Hellman handshake, designed by + * Dan Bernstein. For more information, see https://cr.yp.to/ecdh.html + * + * Tor uses Curve25519 as the basis of its "ntor" circuit extension + * handshake, and in related code. The functions in this module are + * used to find the most suitable available Curve25519 implementation, + * to provide wrappers around it, and so on. */ #define CRYPTO_CURVE25519_PRIVATE @@ -39,15 +47,23 @@ int curve25519_donna(uint8_t *mypublic, static void pick_curve25519_basepoint_impl(void); +/** This is set to 1 if we have an optimized Ed25519-based + * implementation for multiplying a value by the basepoint; to 0 if we + * don't, and to -1 if we haven't checked. */ static int curve25519_use_ed = -1; +/** + * Helper function: call the most appropriate backend to compute the + * scalar "secret" times the point "point". Store the result in + * "output". Return 0 on success, negative on failure. + **/ STATIC int curve25519_impl(uint8_t *output, const uint8_t *secret, - const uint8_t *basepoint) + const uint8_t *point) { uint8_t bp[CURVE25519_PUBKEY_LEN]; int r; - memcpy(bp, basepoint, CURVE25519_PUBKEY_LEN); + memcpy(bp, point, CURVE25519_PUBKEY_LEN); /* Clear the high bit, in case our backend foolishly looks at it. */ bp[31] &= 0x7f; #ifdef USE_CURVE25519_DONNA @@ -61,6 +77,11 @@ curve25519_impl(uint8_t *output, const uint8_t *secret, return r; } +/** + * Helper function: Multiply the scalar "secret" by the Curve25519 + * basepoint (X=9), and store the result in "output". Return 0 on + * success, -1 on false. + */ STATIC int curve25519_basepoint_impl(uint8_t *output, const uint8_t *secret) { @@ -85,6 +106,10 @@ curve25519_basepoint_impl(uint8_t *output, const uint8_t *secret) return r; } +/** + * Override the decision of whether to use the Ed25519-based basepoint + * multiply function. Used for testing. + */ void curve25519_set_impl_params(int use_ed) { @@ -142,6 +167,10 @@ curve25519_secret_key_generate(curve25519_secret_key_t *key_out, return 0; } +/** + * Given a secret key in <b>seckey</b>, create the corresponding public + * key in <b>key_out</b>. + */ void curve25519_public_key_generate(curve25519_public_key_t *key_out, const curve25519_secret_key_t *seckey) @@ -149,6 +178,11 @@ curve25519_public_key_generate(curve25519_public_key_t *key_out, curve25519_basepoint_impl(key_out->public_key, seckey->secret_key); } +/** + * Construct a new keypair in *<b>keypair_out</b>. If <b>extra_strong</b> + * is true, this key is possibly going to get used more than once, so + * use a better-than-usual RNG. Return 0 on success, -1 on failure. */ + */ int curve25519_keypair_generate(curve25519_keypair_t *keypair_out, int extra_strong) @@ -159,7 +193,13 @@ curve25519_keypair_generate(curve25519_keypair_t *keypair_out, return 0; } -/* DOCDOC */ +/** Store the keypair <b>keypair</b>, including its secret and public + * parts, to the file <b>fname</b>. Use the string tag <b>tag</b> to + * distinguish this from other Curve25519 keypairs. Return 0 on success, + * -1 on failure. + * + * See crypto_write_tagged_contents_to_file() for more information on + * the metaformat used for these keys.*/ int curve25519_keypair_write_to_file(const curve25519_keypair_t *keypair, const char *fname, @@ -182,7 +222,10 @@ curve25519_keypair_write_to_file(const curve25519_keypair_t *keypair, return r; } -/* DOCDOC */ +/** Read a curve25519 keypair from a file named <b>fname</b> created by + * curve25519_keypair_write_to_file(). Store the keypair in + * <b>keypair_out</b>, and the associated tag string in <b>tag_out</b>. + * Return 0 on success, and -1 on failure. */ int curve25519_keypair_read_from_file(curve25519_keypair_t *keypair_out, char **tag_out, @@ -197,6 +240,7 @@ curve25519_keypair_read_from_file(curve25519_keypair_t *keypair_out, if (len != sizeof(content)) goto end; + /* Make sure that the public key matches the secret key */ memcpy(keypair_out->seckey.secret_key, content, CURVE25519_SECKEY_LEN); curve25519_public_key_generate(&keypair_out->pubkey, &keypair_out->seckey); if (tor_memneq(keypair_out->pubkey.public_key, diff --git a/src/common/crypto_curve25519.h b/src/common/crypto_curve25519.h index 547e393567..4011820949 100644 --- a/src/common/crypto_curve25519.h +++ b/src/common/crypto_curve25519.h @@ -14,12 +14,20 @@ /** Length of the result of a curve25519 handshake. */ #define CURVE25519_OUTPUT_LEN 32 -/** Wrapper type for a curve25519 public key */ +/** Wrapper type for a curve25519 public key. + * + * (We define a separate type for these to make it less likely that we'll + * mistake them for secret keys.) + * */ typedef struct curve25519_public_key_t { uint8_t public_key[CURVE25519_PUBKEY_LEN]; } curve25519_public_key_t; -/** Wrapper type for a curve25519 secret key */ +/** Wrapper type for a curve25519 secret key + * + * (We define a separate type for these to make it less likely that we'll + * mistake them for public keys.) + **/ typedef struct curve25519_secret_key_t { uint8_t secret_key[CURVE25519_SECKEY_LEN]; } curve25519_secret_key_t; diff --git a/src/common/crypto_ed25519.c b/src/common/crypto_ed25519.c index 817c1a271b..30ed772274 100644 --- a/src/common/crypto_ed25519.c +++ b/src/common/crypto_ed25519.c @@ -5,6 +5,14 @@ * \file crypto_ed25519.c * * \brief Wrapper code for an ed25519 implementation. + * + * Ed25519 is a Schnorr signature on a Twisted Edwards curve, defined + * by Dan Bernstein. For more information, see https://ed25519.cr.yp.to/ + * + * This module wraps our choice of Ed25519 backend, and provides a few + * convenience functions for checking and generating signatures. It also + * provides Tor-specific tools for key blinding and for converting Ed25519 + * keys to and from the corresponding Curve25519 keys. */ #include "orconfig.h" @@ -28,7 +36,7 @@ static void pick_ed25519_impl(void); static int ed25519_impl_spot_check(void); -/** An Ed25519 implementation */ +/** An Ed25519 implementation, as a set of function pointers. */ typedef struct { int (*selftest)(void); @@ -53,6 +61,8 @@ typedef struct { int); } ed25519_impl_t; +/** The Ref10 Ed25519 implementation. This one is pure C and lightly + * optimized. */ static const ed25519_impl_t impl_ref10 = { NULL, @@ -71,6 +81,8 @@ static const ed25519_impl_t impl_ref10 = { ed25519_ref10_pubkey_from_curve25519_pubkey, }; +/** The Ref10 Ed25519 implementation. This one is heavily optimized, but still + * mostly C. The C still tends to be heavily platform-specific. */ static const ed25519_impl_t impl_donna = { ed25519_donna_selftest, @@ -89,8 +101,15 @@ static const ed25519_impl_t impl_donna = { ed25519_donna_pubkey_from_curve25519_pubkey, }; +/** Which Ed25519 implementation are we using? NULL if we haven't decided + * yet. */ static const ed25519_impl_t *ed25519_impl = NULL; +/** Helper: Return our chosen Ed25519 implementation. + * + * This should only be called after we've picked an implementation, but + * it _does_ recover if you forget this. + **/ static inline const ed25519_impl_t * get_ed_impl(void) { @@ -101,7 +120,12 @@ get_ed_impl(void) } #ifdef TOR_UNIT_TESTS +/** For testing: used to remember our actual choice of Ed25519 + * implementation */ static const ed25519_impl_t *saved_ed25519_impl = NULL; +/** For testing: Use the Ed25519 implementation called <b>name</b> until + * crypto_ed25519_testing_restore_impl is called. Recognized names are + * "donna" and "ref10". */ void crypto_ed25519_testing_force_impl(const char *name) { @@ -114,6 +138,9 @@ crypto_ed25519_testing_force_impl(const char *name) ed25519_impl = &impl_ref10; } } +/** For testing: go back to whatever Ed25519 implementation we had picked + * before crypto_ed25519_testing_force_impl was called. + */ void crypto_ed25519_testing_restore_impl(void) { diff --git a/src/common/crypto_format.c b/src/common/crypto_format.c index bdf9bfd613..2f6d847c83 100644 --- a/src/common/crypto_format.c +++ b/src/common/crypto_format.c @@ -123,6 +123,10 @@ crypto_read_tagged_contents_from_file(const char *fname, return r; } +/** Encode <b>pkey</b> as a base64-encoded string, without trailing "=" + * characters, in the buffer <b>output</b>, which must have at least + * CURVE25519_BASE64_PADDED_LEN+1 bytes available. Return 0 on success, -1 on + * failure. */ int curve25519_public_to_base64(char *output, const curve25519_public_key_t *pkey) @@ -135,6 +139,9 @@ curve25519_public_to_base64(char *output, return 0; } +/** Try to decode a base64-encoded curve25519 public key from <b>input</b> + * into the object at <b>pkey</b>. Return 0 on success, -1 on failure. + * Accepts keys with or without a trailing "=". */ int curve25519_public_from_base64(curve25519_public_key_t *pkey, const char *input) diff --git a/src/common/workqueue.c b/src/common/workqueue.c index 48c0cca01f..e1fb663a2a 100644 --- a/src/common/workqueue.c +++ b/src/common/workqueue.c @@ -6,6 +6,20 @@ * * \brief Implements worker threads, queues of work for them, and mechanisms * for them to send answers back to the main thread. + * + * The main structure here is a threadpool_t : it manages a set of worker + * threads, a queue of pending work, and a reply queue. Every piece of work + * is a workqueue_entry_t, containing data to process and a function to + * process it with. + * + * The main thread informs the worker threads of pending work by using a + * condition variable. The workers inform the main process of completed work + * by using an alert_sockets_t object, as implemented in compat_threads.c. + * + * The main thread can also queue an "update" that will be handled by all the + * workers. This is useful for updating state that all the workers share. + * + * In Tor today, there is currently only one thread pool, used in cpuworker.c. */ #include "orconfig.h" |