diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/crypto_curve25519.c | 88 | ||||
-rw-r--r-- | src/common/crypto_curve25519.h | 43 | ||||
-rw-r--r-- | src/common/include.am | 20 |
3 files changed, 150 insertions, 1 deletions
diff --git a/src/common/crypto_curve25519.c b/src/common/crypto_curve25519.c new file mode 100644 index 0000000000..1985e8af2d --- /dev/null +++ b/src/common/crypto_curve25519.c @@ -0,0 +1,88 @@ +/* Copyright (c) 2012, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/* Wrapper code for a curve25519 implementation. */ + +#define CRYPTO_CURVE25519_PRIVATE +#include "orconfig.h" +#include "crypto.h" +#include "crypto_curve25519.h" +#include "util.h" + +/* ============================== + Part 1: wrap a suitable curve25519 implementation as curve25519_impl + ============================== */ + +#ifdef USE_CURVE25519_DONNA +int curve25519_donna(uint8_t *mypublic, + const uint8_t *secret, const uint8_t *basepoint); +#endif +#ifdef USE_CURVE25519_NACL +#include <crypto_scalarmult_curve25519.h> +#endif + +int +curve25519_impl(uint8_t *output, const uint8_t *secret, + const uint8_t *basepoint) +{ +#ifdef USE_CURVE25519_DONNA + return curve25519_donna(output, secret, basepoint); +#elif defined(USE_CURVE25519_NACL) + return crypto_scalarmult_curve25519(output, secret, basepoint); +#else +#error "No implementation of curve25519 is available." +#endif +} + +/* ============================== + Part 2: Wrap curve25519_impl with some convenience types and functions. + ============================== */ + +/** + * Return true iff a curve25519_public_key_t seems valid. (It's not necessary + * to see if the point is on the curve, since the twist is also secure, but we + * do need to make sure that it isn't the point at infinity.) */ +int +curve25519_public_key_is_ok(const curve25519_public_key_t *key) +{ + static const uint8_t zero[] = + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + + return tor_memneq(key->public_key, zero, CURVE25519_PUBKEY_LEN); +} + +/** Generate a new keypair and return the secret key. 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. */ +void +curve25519_secret_key_generate(curve25519_secret_key_t *key_out, + int extra_strong) +{ + (void)extra_strong; + + crypto_rand((char*)key_out->secret_key, 32); + key_out->secret_key[0] &= 248; + key_out->secret_key[31] &= 127; + key_out->secret_key[31] |= 64; +} + +void +curve25519_public_key_generate(curve25519_public_key_t *key_out, + const curve25519_secret_key_t *seckey) +{ + static const uint8_t basepoint[32] = {9}; + + curve25519_impl(key_out->public_key, seckey->secret_key, basepoint); +} + +/** Perform the curve25519 ECDH handshake with <b>skey</b> and <b>pkey</b>, + * writing CURVE25519_OUTPUT_LEN bytes of output into <b>output</b>. */ +void +curve25519_handshake(uint8_t *output, + const curve25519_secret_key_t *skey, + const curve25519_public_key_t *pkey) +{ + curve25519_impl(output, skey->secret_key, pkey->public_key); +} + diff --git a/src/common/crypto_curve25519.h b/src/common/crypto_curve25519.h new file mode 100644 index 0000000000..3e093be7bf --- /dev/null +++ b/src/common/crypto_curve25519.h @@ -0,0 +1,43 @@ +/* Copyright (c) 2012, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#ifndef TOR_CRYPTO_CURVE25519_H +#define TOR_CRYPTO_CURVE25519_H + +#include "torint.h" + +/** Length of a curve25519 public key when encoded. */ +#define CURVE25519_PUBKEY_LEN 32 +/** Length of a curve25519 secret key when encoded. */ +#define CURVE25519_SECKEY_LEN 32 +/** Length of the result of a curve25519 handshake. */ +#define CURVE25519_OUTPUT_LEN 32 + +/** Wrapper type for a curve25519 public key */ +typedef struct curve25519_public_key_t { + uint8_t public_key[CURVE25519_PUBKEY_LEN]; +} curve25519_public_key_t; + +/** Wrapper type for a curve25519 secret key */ +typedef struct curve25519_secret_key_t { + uint8_t secret_key[CURVE25519_SECKEY_LEN]; +} curve25519_secret_key_t; + +int curve25519_public_key_is_ok(const curve25519_public_key_t *); + +void curve25519_secret_key_generate(curve25519_secret_key_t *key_out, + int extra_strong); +void curve25519_public_key_generate(curve25519_public_key_t *key_out, + const curve25519_secret_key_t *seckey); + +void curve25519_handshake(uint8_t *output, + const curve25519_secret_key_t *, + const curve25519_public_key_t *); + +#ifdef CRYPTO_CURVE25519_PRIVATE +int curve25519_impl(uint8_t *output, const uint8_t *secret, + const uint8_t *basepoint); +#endif + +#endif + diff --git a/src/common/include.am b/src/common/include.am index 0fdc72057f..f986ba66d3 100644 --- a/src/common/include.am +++ b/src/common/include.am @@ -14,6 +14,22 @@ else libor_extra_source= endif +if BUILD_CURVE25519_DONNA +libcrypto_extra_source= \ + src/ext/curve25519_donna/curve25519-donna.c \ + src/common/crypto_curve25519.c +else +if BUILD_CURVE25519_DONNA_C64 +libcrypto_extra_source= \ + src/ext/curve25519_donna/curve25519-donna-c64.c \ + src/common/crypto_curve25519.c +else +if CURVE25519_ENABLED +libcrypto_extra_source=src/common/crypto_curve25519.c +endif +endif +endif + src_common_libor_a_SOURCES = \ src/common/address.c \ src/common/compat.c \ @@ -31,7 +47,8 @@ src_common_libor_crypto_a_SOURCES = \ src/common/aes.c \ src/common/crypto.c \ src/common/torgzip.c \ - src/common/tortls.c + src/common/tortls.c \ + $(libcrypto_extra_source) src_common_libor_event_a_SOURCES = src/common/compat_libevent.c @@ -43,6 +60,7 @@ COMMONHEADERS = \ src/common/compat_libevent.h \ src/common/container.h \ src/common/crypto.h \ + src/common/crypto_curve25519.h \ src/common/di_ops.h \ src/common/memarea.h \ src/common/mempool.h \ |