summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/crypto_curve25519.c52
-rw-r--r--src/common/crypto_curve25519.h12
-rw-r--r--src/common/crypto_ed25519.c29
-rw-r--r--src/common/crypto_format.c7
-rw-r--r--src/common/workqueue.c14
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"