summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/crypto_curve25519.c88
-rw-r--r--src/common/crypto_curve25519.h43
-rw-r--r--src/common/include.am20
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 \