]> source.dussan.org Git - rspamd.git/commitdiff
Add basic routines for digital signatures
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 2 Feb 2016 12:20:53 +0000 (12:20 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 2 Feb 2016 12:20:53 +0000 (12:20 +0000)
src/libcryptobox/cryptobox.c
src/libcryptobox/cryptobox.h
src/libcryptobox/ed25519/ed25519.c
src/libcryptobox/ed25519/ed25519.h
src/libcryptobox/ed25519/ref.c

index 5f0bb3b64e16c4dbcbaa31e691e7820bf3a26c74..3d7c57c854a2377a0da0fd4110044170dbba1a3f 100644 (file)
@@ -33,6 +33,7 @@
 #include "chacha20/chacha.h"
 #include "poly1305/poly1305.h"
 #include "curve25519/curve25519.h"
+#include "ed25519/ed25519.h"
 #include "blake2/blake2.h"
 #include "siphash/siphash.h"
 #include "ottery.h"
@@ -53,7 +54,7 @@
 #include <openssl/evp.h>
 #include <openssl/ec.h>
 #include <openssl/ecdh.h>
-
+#include <openssl/ecdsa.h>
 #define CRYPTOBOX_CURVE_NID NID_X9_62_prime256v1
 #endif
 
@@ -315,6 +316,7 @@ rspamd_cryptobox_init (void)
        ctx->siphash_impl = siphash_load ();
        ctx->curve25519_impl = curve25519_load ();
        ctx->blake2_impl = blake2b_load ();
+       ctx->ed25519_impl = ed25519_load ();
 
        return ctx;
 }
@@ -363,6 +365,45 @@ rspamd_cryptobox_keypair (rspamd_pk_t pk, rspamd_sk_t sk)
        }
 }
 
+void
+rspamd_cryptobox_keypair_sig (rspamd_sig_pk_t pk, rspamd_sig_sk_t sk)
+{
+       if (G_LIKELY (!use_openssl)) {
+               ed25519_keypair (pk, sk);
+       }
+       else {
+#ifndef HAVE_USABLE_OPENSSL
+               g_assert (0);
+#else
+               EC_KEY *ec_sec;
+               const BIGNUM *bn_sec;
+               BIGNUM *bn_pub;
+               const EC_POINT *ec_pub;
+               gint len;
+
+               ec_sec = EC_KEY_new_by_curve_name (CRYPTOBOX_CURVE_NID);
+               g_assert (ec_sec != NULL);
+               g_assert (EC_KEY_generate_key (ec_sec) != 0);
+
+               bn_sec = EC_KEY_get0_private_key (ec_sec);
+               g_assert (bn_sec != NULL);
+               ec_pub = EC_KEY_get0_public_key (ec_sec);
+               g_assert (ec_pub != NULL);
+               bn_pub = EC_POINT_point2bn (EC_KEY_get0_group (ec_sec),
+                               ec_pub, POINT_CONVERSION_UNCOMPRESSED, NULL, NULL);
+
+               len = BN_num_bytes (bn_sec);
+               g_assert (len <= (gint)sizeof (rspamd_sk_t));
+               BN_bn2bin (bn_sec, sk);
+               len = BN_num_bytes (bn_pub);
+               g_assert (len <= (gint)rspamd_cryptobox_pk_bytes ());
+               BN_bn2bin (bn_pub, pk);
+               BN_free (bn_pub);
+               EC_KEY_free (ec_sec);
+#endif
+       }
+}
+
 void
 rspamd_cryptobox_nm (rspamd_nm_t nm, const rspamd_pk_t pk, const rspamd_sk_t sk)
 {
@@ -415,6 +456,43 @@ rspamd_cryptobox_nm (rspamd_nm_t nm, const rspamd_pk_t pk, const rspamd_sk_t sk)
        }
 }
 
+void
+rspamd_cryptobox_sign (guchar *sig, gsize *siglen_p,
+               const guchar *m, gsize mlen,
+               const rspamd_sk_t sk)
+{
+       if (G_LIKELY (!use_openssl)) {
+               ed25519_sign (sig, siglen_p, m, mlen, sk);
+       }
+       else {
+#ifndef HAVE_USABLE_OPENSSL
+               g_assert (0);
+#else
+#endif
+       }
+}
+
+bool
+rspamd_cryptobox_verify (const guchar *sig,
+               const guchar *m,
+               gsize mlen,
+               const rspamd_pk_t pk)
+{
+       bool ret = false;
+
+       if (G_LIKELY (!use_openssl)) {
+               ret = ed25519_verify (sig, m, mlen, pk);
+       }
+       else {
+#ifndef HAVE_USABLE_OPENSSL
+               g_assert (0);
+#else
+#endif
+       }
+
+       return ret;
+}
+
 static gsize
 rspamd_cryptobox_encrypt_ctx_len (void)
 {
@@ -1104,6 +1182,17 @@ rspamd_cryptobox_pk_bytes (void)
        }
 }
 
+guint
+rspamd_cryptobox_pk_sig_bytes (void)
+{
+       if (G_UNLIKELY (!use_openssl)) {
+               return 32;
+       }
+       else {
+               return 65;
+       }
+}
+
 guint
 rspamd_cryptobox_nonce_bytes (void)
 {
@@ -1122,6 +1211,17 @@ rspamd_cryptobox_sk_bytes (void)
        return 32;
 }
 
+guint
+rspamd_cryptobox_sk_sig_bytes (void)
+{
+       if (G_UNLIKELY (!use_openssl)) {
+               return 32;
+       }
+       else {
+               return 64;
+       }
+}
+
 guint
 rspamd_cryptobox_nm_bytes (void)
 {
index 8673fa09158fdcd356ce01994e5c3ed572171739..966fc677ed2bd3b0c51786989fb53eaf6194dd10 100644 (file)
@@ -57,10 +57,14 @@ typedef guchar rspamd_mac_t[rspamd_cryptobox_MAX_MACBYTES];
 typedef guchar rspamd_nm_t[rspamd_cryptobox_MAX_NMBYTES];
 typedef guchar rspamd_nonce_t[rspamd_cryptobox_MAX_NONCEBYTES];
 typedef guchar rspamd_sipkey_t[rspamd_cryptobox_SIPKEYBYTES];
+typedef guchar rspamd_signature_t[rspamd_cryptobox_MAX_SIGBYTES];
+typedef guchar rspamd_sig_pk_t[rspamd_cryptobox_MAX_SIGPKBYTES];
+typedef guchar rspamd_sig_sk_t[rspamd_cryptobox_MAX_SIGSKBYTES];
 
 struct rspamd_cryptobox_library_ctx {
        gchar *cpu_extensions;
        const gchar *curve25519_impl;
+       const gchar *ed25519_impl;
        const gchar *chacha20_impl;
        const gchar *poly1305_impl;
        const gchar *siphash_impl;
@@ -80,6 +84,13 @@ struct rspamd_cryptobox_library_ctx* rspamd_cryptobox_init (void);
  */
 void rspamd_cryptobox_keypair (rspamd_pk_t pk, rspamd_sk_t sk);
 
+/**
+ * Generate new keypair for signing
+ * @param pk public key buffer
+ * @param sk secret key buffer
+ */
+void rspamd_cryptobox_keypair_sig (rspamd_sig_pk_t pk, rspamd_sig_sk_t sk);
+
 /**
  * Encrypt data inplace adding signature to sig afterwards
  * @param data input buffer
@@ -165,6 +176,32 @@ gboolean rspamd_cryptobox_decrypt_nm_inplace (guchar *data, gsize len,
  */
 void rspamd_cryptobox_nm (rspamd_nm_t nm, const rspamd_pk_t pk, const rspamd_sk_t sk);
 
+/**
+ * Create digital signature for the specified message and place result in `sig`
+ * @param sig signature target
+ * @param siglen_p pointer to signature length (might be NULL)
+ * @param m input message
+ * @param mlen input length
+ * @param sk secret key
+ */
+void rspamd_cryptobox_sign (guchar *sig, gsize *siglen_p,
+               const guchar *m, gsize mlen,
+               const rspamd_sk_t sk);
+
+/**
+ * Verifies digital signature for the specified message using the specified
+ * pubkey
+ * @param sig signature source
+ * @param m input message
+ * @param mlen message lenght
+ * @param pk public key for verification
+ * @return true if signature is valid, false otherwise
+ */
+bool rspamd_cryptobox_verify (const guchar *sig,
+               const guchar *m,
+               gsize mlen,
+               const rspamd_pk_t pk);
+
 /**
  * Securely clear the buffer specified
  * @param buf buffer to zero
@@ -209,6 +246,11 @@ gboolean rspamd_cryptobox_openssl_mode (gboolean enable);
  */
 guint rspamd_cryptobox_pk_bytes (void);
 
+/**
+ * Real size of rspamd cryptobox signing public key
+ */
+guint rspamd_cryptobox_pk_sig_bytes (void);
+
 /**
  * Real size of crypto nonce
  */
@@ -219,6 +261,11 @@ guint rspamd_cryptobox_nonce_bytes (void);
  */
 guint rspamd_cryptobox_sk_bytes (void);
 
+/**
+ * Real size of rspamd cryptobox signing secret key
+ */
+guint rspamd_cryptobox_sk_sig_bytes (void);
+
 /**
  * Real size of rspamd cryptobox shared key
  */
@@ -229,6 +276,11 @@ guint rspamd_cryptobox_nm_bytes (void);
  */
 guint rspamd_cryptobox_mac_bytes (void);
 
+/**
+ * Real size of rspamd cryptobox digital signature
+ */
+guint rspamd_cryptobox_signature_bytes (void);
+
 /* Hash IUF interface */
 typedef struct RSPAMD_ALIGNED(32) rspamd_cryptobox_hash_state_s  {
        unsigned char opaque[256];
index 776ac4e13b6073a84333c2920bde912da4505432..f4658aff52c741bc137411d50ee0c64ef2c1c371 100644 (file)
@@ -34,23 +34,23 @@ typedef struct ed25519_impl_s {
        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,
+       void (*sign) (unsigned char *sig, size_t *siglen_p,
+                       const unsigned char *m, size_t mlen,
                        const unsigned char *sk);
        bool (*verify) (const unsigned char *sig,
                        const unsigned char *m,
-                       unsigned long long mlen,
+                       size_t 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, \
+    void ed_sign_##ext(unsigned char *sig, size_t *siglen_p, \
+        const unsigned char *m, size_t mlen, \
         const unsigned char *sk); \
     bool ed_verify_##ext(const unsigned char *sig, \
         const unsigned char *m, \
-        unsigned long long mlen, \
+               size_t mlen, \
         const unsigned char *pk)
 
 #define ED25519_IMPL(cpuflags, desc, ext) \
@@ -90,8 +90,8 @@ 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,
+ed25519_sign (unsigned char *sig, size_t *siglen_p,
+               const unsigned char *m, size_t mlen,
                const unsigned char *sk)
 {
        ed25519_opt->sign (sig, siglen_p, m, mlen, sk);
@@ -100,7 +100,7 @@ ed25519_sign (unsigned char *sig, unsigned long long *siglen_p,
 bool
 ed25519_verify (const unsigned char *sig,
                const unsigned char *m,
-               unsigned long long mlen,
+               size_t mlen,
                const unsigned char *pk)
 {
        return ed25519_opt->verify (sig, m, mlen, pk);
index 34814782bbc85e1022a9a348f84adc037408d095..7a6cd796f10a88a00eb4f0c7c8eebbb112deb09c 100644 (file)
 
 #include "config.h"
 #include <stdbool.h>
+#include <stddef.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,
+void ed25519_sign (unsigned char *sig, size_t *siglen_p,
+               const unsigned char *m, size_t mlen,
                const unsigned char *sk);
 bool ed25519_verify (const unsigned char *sig,
                const unsigned char *m,
-               unsigned long long mlen,
+               size_t mlen,
                const unsigned char *pk);
 
 #endif /* SRC_LIBCRYPTOBOX_ED25519_ED25519_H_ */
index a1053c607fe70979edbf4145706336a2b03dbeab..5ae5eb898c2e0adaeb95b670991435a2ec09200e 100644 (file)
@@ -59,7 +59,7 @@ ed_keypair_ref (unsigned char *pk, unsigned char *sk)
 
 int
 ed_verify_ref(const unsigned char *sig, const unsigned char *m,
-               unsigned long long mlen, const unsigned char *pk)
+               size_t mlen, const unsigned char *pk)
 {
        EVP_MD_CTX sha_ctx;
        unsigned char h[64];
@@ -96,8 +96,8 @@ ed_verify_ref(const unsigned char *sig, const unsigned char *m,
 }
 
 void
-ed_sign_ref(unsigned char *sig, unsigned long long *siglen_p,
-               const unsigned char *m, unsigned long long mlen,
+ed_sign_ref(unsigned char *sig, size_t *siglen_p,
+               const unsigned char *m, size_t mlen,
                const unsigned char *sk)
 {
        EVP_MD_CTX sha_ctx;