From 91001260bc87b72668381b3a8536b76f93bac26a Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Tue, 2 Feb 2016 12:20:53 +0000 Subject: [PATCH] Add basic routines for digital signatures --- src/libcryptobox/cryptobox.c | 102 ++++++++++++++++++++++++++++- src/libcryptobox/cryptobox.h | 52 +++++++++++++++ src/libcryptobox/ed25519/ed25519.c | 18 ++--- src/libcryptobox/ed25519/ed25519.h | 7 +- src/libcryptobox/ed25519/ref.c | 6 +- 5 files changed, 169 insertions(+), 16 deletions(-) diff --git a/src/libcryptobox/cryptobox.c b/src/libcryptobox/cryptobox.c index 5f0bb3b64..3d7c57c85 100644 --- a/src/libcryptobox/cryptobox.c +++ b/src/libcryptobox/cryptobox.c @@ -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 #include #include - +#include #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) { diff --git a/src/libcryptobox/cryptobox.h b/src/libcryptobox/cryptobox.h index 8673fa091..966fc677e 100644 --- a/src/libcryptobox/cryptobox.h +++ b/src/libcryptobox/cryptobox.h @@ -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]; diff --git a/src/libcryptobox/ed25519/ed25519.c b/src/libcryptobox/ed25519/ed25519.c index 776ac4e13..f4658aff5 100644 --- a/src/libcryptobox/ed25519/ed25519.c +++ b/src/libcryptobox/ed25519/ed25519.c @@ -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); diff --git a/src/libcryptobox/ed25519/ed25519.h b/src/libcryptobox/ed25519/ed25519.h index 34814782b..7a6cd796f 100644 --- a/src/libcryptobox/ed25519/ed25519.h +++ b/src/libcryptobox/ed25519/ed25519.h @@ -27,15 +27,16 @@ #include "config.h" #include +#include 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_ */ diff --git a/src/libcryptobox/ed25519/ref.c b/src/libcryptobox/ed25519/ref.c index a1053c607..5ae5eb898 100644 --- a/src/libcryptobox/ed25519/ref.c +++ b/src/libcryptobox/ed25519/ref.c @@ -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; -- 2.39.5