aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libcryptobox/CMakeLists.txt5
-rw-r--r--src/libcryptobox/curve25519/fe.h1
-rw-r--r--src/libcryptobox/ed25519/ed25519.c107
-rw-r--r--src/libcryptobox/ed25519/ed25519.h41
-rw-r--r--src/libcryptobox/ed25519/ref.c140
5 files changed, 293 insertions, 1 deletions
diff --git a/src/libcryptobox/CMakeLists.txt b/src/libcryptobox/CMakeLists.txt
index 18736dc06..874e94567 100644
--- a/src/libcryptobox/CMakeLists.txt
+++ b/src/libcryptobox/CMakeLists.txt
@@ -13,6 +13,9 @@ SET(BLAKE2SRC ${CMAKE_CURRENT_SOURCE_DIR}/blake2/blake2.c
SET(CURVESRC ${CMAKE_CURRENT_SOURCE_DIR}/curve25519/ref.c
${CMAKE_CURRENT_SOURCE_DIR}/curve25519/curve25519.c)
+SET(EDSRC ${CMAKE_CURRENT_SOURCE_DIR}/ed25519/ref.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/ed25519/ed25519.c)
+
SET(ASM_CODE "
.macro TEST1 op
\\op %eax, %eax
@@ -85,4 +88,4 @@ INCLUDE_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}")
SET(LIBCRYPTOBOXSRC ${CMAKE_CURRENT_SOURCE_DIR}/cryptobox.c)
SET(RSPAMD_CRYPTOBOX ${LIBCRYPTOBOXSRC} ${CHACHASRC} ${POLYSRC} ${SIPHASHSRC}
- ${CURVESRC} ${BLAKE2SRC} PARENT_SCOPE)
+ ${CURVESRC} ${BLAKE2SRC} ${EDSRC} PARENT_SCOPE)
diff --git a/src/libcryptobox/curve25519/fe.h b/src/libcryptobox/curve25519/fe.h
index 1c4589659..d5d8b93fd 100644
--- a/src/libcryptobox/curve25519/fe.h
+++ b/src/libcryptobox/curve25519/fe.h
@@ -114,6 +114,7 @@ void ge_sub(ge_p1p1 *,const ge_p3 *,const ge_cached *);
void ge_scalarmult_base(ge_p3 *,const unsigned char *);
void ge_double_scalarmult_vartime(ge_p2 *,const unsigned char *,const ge_p3 *,const unsigned char *);
void ge_scalarmult_vartime(ge_p3 *,const unsigned char *,const ge_p3 *);
+int verify_32(const unsigned char *x, const unsigned char *y);
/*
The set of scalars is \Z/l
diff --git a/src/libcryptobox/ed25519/ed25519.c b/src/libcryptobox/ed25519/ed25519.c
new file mode 100644
index 000000000..776ac4e13
--- /dev/null
+++ b/src/libcryptobox/ed25519/ed25519.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2016, Vsevolod Stakhov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR ''AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "cryptobox.h"
+#include "ed25519.h"
+#include "platform_config.h"
+
+extern unsigned long cpu_config;
+
+typedef struct ed25519_impl_s {
+ unsigned long cpu_flags;
+ const char *desc;
+
+ void (*keypair) (unsigned char *pk, unsigned char *sk);
+ void (*sign) (unsigned char *sig, unsigned long long *siglen_p,
+ const unsigned char *m, unsigned long long mlen,
+ const unsigned char *sk);
+ bool (*verify) (const unsigned char *sig,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *pk);
+} ed25519_impl_t;
+
+#define ED25519_DECLARE(ext) \
+ void ed_keypair_##ext(unsigned char *pk, unsigned char *sk); \
+ void ed_sign_##ext(unsigned char *sig, unsigned long long *siglen_p, \
+ const unsigned char *m, unsigned long long mlen, \
+ const unsigned char *sk); \
+ bool ed_verify_##ext(const unsigned char *sig, \
+ const unsigned char *m, \
+ unsigned long long mlen, \
+ const unsigned char *pk)
+
+#define ED25519_IMPL(cpuflags, desc, ext) \
+ {(cpuflags), desc, ed_keypair_##ext, ed_sign_##ext, ed_verify_##ext}
+
+ED25519_DECLARE(ref);
+#define ED25519_REF ED25519_IMPL(0, "ref", ref)
+
+static const ed25519_impl_t ed25519_list[] = {
+ ED25519_REF,
+};
+
+static const ed25519_impl_t *ed25519_opt = &ed25519_list[0];
+
+const char*
+ed25519_load (void)
+{
+ guint i;
+
+ if (cpu_config != 0) {
+ for (i = 0; i < G_N_ELEMENTS(ed25519_list); i++) {
+ if (ed25519_list[i].cpu_flags & cpu_config) {
+ ed25519_opt = &ed25519_list[i];
+ break;
+ }
+ }
+ }
+
+
+ return ed25519_opt->desc;
+}
+
+void
+ed25519_keypair (unsigned char *pk, unsigned char *sk)
+{
+ ed25519_opt->keypair (pk, sk);
+}
+
+void
+ed25519_sign (unsigned char *sig, unsigned long long *siglen_p,
+ const unsigned char *m, unsigned long long mlen,
+ const unsigned char *sk)
+{
+ ed25519_opt->sign (sig, siglen_p, m, mlen, sk);
+}
+
+bool
+ed25519_verify (const unsigned char *sig,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *pk)
+{
+ return ed25519_opt->verify (sig, m, mlen, pk);
+}
diff --git a/src/libcryptobox/ed25519/ed25519.h b/src/libcryptobox/ed25519/ed25519.h
new file mode 100644
index 000000000..34814782b
--- /dev/null
+++ b/src/libcryptobox/ed25519/ed25519.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016, Vsevolod Stakhov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR ''AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_LIBCRYPTOBOX_ED25519_ED25519_H_
+#define SRC_LIBCRYPTOBOX_ED25519_ED25519_H_
+
+#include "config.h"
+#include <stdbool.h>
+
+const char* ed25519_load (void);
+void ed25519_keypair (unsigned char *pk, unsigned char *sk);
+void ed25519_sign (unsigned char *sig, unsigned long long *siglen_p,
+ const unsigned char *m, unsigned long long mlen,
+ const unsigned char *sk);
+bool ed25519_verify (const unsigned char *sig,
+ const unsigned char *m,
+ unsigned long long mlen,
+ const unsigned char *pk);
+
+#endif /* SRC_LIBCRYPTOBOX_ED25519_ED25519_H_ */
diff --git a/src/libcryptobox/ed25519/ref.c b/src/libcryptobox/ed25519/ref.c
new file mode 100644
index 000000000..a1053c607
--- /dev/null
+++ b/src/libcryptobox/ed25519/ref.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2013-2016
+ * Frank Denis <j at pureftpd dot org>
+ * Vsevolod Stakhov
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "config.h"
+#include "ed25519.h"
+#include "cryptobox.h"
+#include "../curve25519/fe.h"
+#include "ottery.h"
+#include <openssl/evp.h> /* SHA512 */
+
+static int
+ed_seed_keypair_ref (unsigned char *pk, unsigned char *sk,
+ const unsigned char *seed)
+{
+ ge_p3 A;
+
+ memmove (sk, seed, 32);
+ sk[0] &= 248;
+ sk[31] &= 63;
+ sk[31] |= 64;
+
+ ge_scalarmult_base (&A, sk);
+ ge_p3_tobytes (pk, &A);
+
+ memmove (sk, seed, 32);
+ memmove (sk + 32, pk, 32);
+
+ return 0;
+}
+
+int
+ed_keypair_ref (unsigned char *pk, unsigned char *sk)
+{
+ unsigned char seed[rspamd_cryptobox_HASHBYTES];
+ int ret;
+
+ ottery_rand_bytes (seed, sizeof (seed));
+ rspamd_cryptobox_hash (seed, seed, sizeof (seed), NULL, 0);
+ ret = ed_seed_keypair_ref (pk, sk, seed);
+ rspamd_explicit_memzero (seed, sizeof (seed));
+
+ return ret;
+}
+
+int
+ed_verify_ref(const unsigned char *sig, const unsigned char *m,
+ unsigned long long mlen, const unsigned char *pk)
+{
+ EVP_MD_CTX sha_ctx;
+ unsigned char h[64];
+ unsigned char rcheck[32];
+ unsigned int i;
+ unsigned char d = 0;
+ ge_p3 A;
+ ge_p2 R;
+
+ if (sig[63] & 224) {
+ return -1;
+ }
+ if (ge_frombytes_negate_vartime (&A, pk) != 0) {
+ return -1;
+ }
+ for (i = 0; i < 32; ++i) {
+ d |= pk[i];
+ }
+ if (d == 0) {
+ return -1;
+ }
+
+ g_assert (EVP_DigestInit (&sha_ctx, EVP_sha512()) == 1);
+ EVP_DigestUpdate (&sha_ctx, sig, 32);
+ EVP_DigestUpdate (&sha_ctx, pk, 32);
+ EVP_DigestUpdate (&sha_ctx, m, mlen);
+ EVP_DigestFinal (&sha_ctx, h, NULL);
+ sc_reduce (h);
+
+ ge_double_scalarmult_vartime (&R, h, &A, sig + 32);
+ ge_tobytes (rcheck, &R);
+
+ return verify_32 (rcheck, sig) | (-(rcheck == sig));
+}
+
+void
+ed_sign_ref(unsigned char *sig, unsigned long long *siglen_p,
+ const unsigned char *m, unsigned long long mlen,
+ const unsigned char *sk)
+{
+ EVP_MD_CTX sha_ctx;
+ unsigned char az[64];
+ unsigned char nonce[64];
+ unsigned char hram[64];
+ ge_p3 R;
+
+ g_assert (EVP_DigestInit (&sha_ctx, EVP_sha512()) == 1);
+ EVP_DigestUpdate (&sha_ctx, sk, 32);
+ EVP_DigestFinal (&sha_ctx, az, NULL);
+ az[0] &= 248;
+ az[31] &= 63;
+ az[31] |= 64;
+
+ g_assert (EVP_DigestInit (&sha_ctx, EVP_sha512()) == 1);
+ EVP_DigestUpdate (&sha_ctx, az + 32, 32);
+ EVP_DigestUpdate (&sha_ctx, m, mlen);
+ EVP_DigestFinal (&sha_ctx, nonce, NULL);
+
+ memmove (sig + 32, sk + 32, 32);
+
+ sc_reduce (nonce);
+ ge_scalarmult_base (&R, nonce);
+ ge_p3_tobytes (sig, &R);
+
+ g_assert (EVP_DigestInit (&sha_ctx, EVP_sha512()) == 1);
+ EVP_DigestUpdate (&sha_ctx, sig, 64);
+ EVP_DigestUpdate (&sha_ctx, m, mlen);
+ EVP_DigestFinal (&sha_ctx, hram, NULL);
+
+ sc_reduce (hram);
+ sc_muladd (sig + 32, hram, az, nonce);
+
+ rspamd_explicit_memzero (az, sizeof (az));
+
+ if (siglen_p != NULL) {
+ *siglen_p = 64U;
+ }
+}