diff options
Diffstat (limited to 'src/common/crypto_curve25519.c')
-rw-r--r-- | src/common/crypto_curve25519.c | 60 |
1 files changed, 54 insertions, 6 deletions
diff --git a/src/common/crypto_curve25519.c b/src/common/crypto_curve25519.c index 57c878b79a..fcbee3aba2 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,12 +77,19 @@ 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) { int r = 0; - if (PREDICT_UNLIKELY(curve25519_use_ed == -1)) { + if (BUG(curve25519_use_ed == -1)) { + /* LCOV_EXCL_START - Only reached if we forgot to call curve25519_init() */ pick_curve25519_basepoint_impl(); + /* LCOV_EXCL_STOP */ } /* TODO: Someone should benchmark curved25519_scalarmult_basepoint versus @@ -83,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) { @@ -140,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) @@ -147,6 +178,10 @@ 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) @@ -157,7 +192,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, @@ -180,7 +221,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, @@ -195,6 +239,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, @@ -290,10 +335,13 @@ pick_curve25519_basepoint_impl(void) if (curve25519_basepoint_spot_check() == 0) return; - log_warn(LD_CRYPTO, "The ed25519-based curve25519 basepoint " + /* LCOV_EXCL_START + * only reachable if our basepoint implementation broken */ + log_warn(LD_BUG|LD_CRYPTO, "The ed25519-based curve25519 basepoint " "multiplication seems broken; using the curve25519 " "implementation."); curve25519_use_ed = 0; + /* LCOV_EXCL_STOP */ } /** Initialize the curve25519 implementations. This is necessary if you're |