aboutsummaryrefslogtreecommitdiffstats
path: root/src/libcryptobox
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2015-10-18 22:12:20 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2015-10-18 22:12:20 +0100
commit3b2cf3cd2282eba2e76a71361d2354bfceb9656e (patch)
treeacd559b7a8145fcd2b30f9c0a0327bbc515e6381 /src/libcryptobox
parenta1ff4d1eca8578d3da6fbb7ede00e007e9a798d8 (diff)
downloadrspamd-3b2cf3cd2282eba2e76a71361d2354bfceb9656e.tar.gz
rspamd-3b2cf3cd2282eba2e76a71361d2354bfceb9656e.zip
Prepare cryptobox for aes plug.
Diffstat (limited to 'src/libcryptobox')
-rw-r--r--src/libcryptobox/cryptobox.c273
-rw-r--r--src/libcryptobox/cryptobox.h6
2 files changed, 228 insertions, 51 deletions
diff --git a/src/libcryptobox/cryptobox.c b/src/libcryptobox/cryptobox.c
index 5dffaff4e..fc2caacfa 100644
--- a/src/libcryptobox/cryptobox.c
+++ b/src/libcryptobox/cryptobox.c
@@ -39,12 +39,17 @@
#ifdef HAVE_CPUID_H
#include <cpuid.h>
#endif
+#ifdef HAVE_OPENSSL
+#include <openssl/evp.h>
+#endif
#include <signal.h>
#include <setjmp.h>
unsigned long cpu_config = 0;
+static gboolean use_openssl = FALSE;
+
static const guchar n0[16] = {0};
#ifdef HAVE_WEAK_SYMBOLS
@@ -56,6 +61,10 @@ _dummy_symbol_to_prevent_lto(void * const pnt, const size_t len)
}
#endif
+#define CRYPTOBOX_ALIGNMENT 32 /* Better for AVX */
+#define cryptobox_align_ptr(p, a) \
+ (void *) (((uintptr_t) (p) + ((uintptr_t) a - 1)) & ~((uintptr_t) a - 1))
+
void
rspamd_explicit_memzero(void * const pnt, const gsize len)
{
@@ -244,28 +253,180 @@ rspamd_cryptobox_nm (rspamd_nm_t nm, const rspamd_pk_t pk, const rspamd_sk_t sk)
rspamd_explicit_memzero (e, rspamd_cryptobox_SKBYTES);
}
-void rspamd_cryptobox_encrypt_nm_inplace (guchar *data, gsize len,
- const rspamd_nonce_t nonce,
- const rspamd_nm_t nm, rspamd_sig_t sig)
+static gsize
+rspamd_cryptobox_encrypt_ctx_len (void)
{
- poly1305_state mac_ctx;
+ return sizeof (chacha_state) + CRYPTOBOX_ALIGNMENT;
+}
+
+static gsize
+rspamd_cryptobox_auth_ctx_len (void)
+{
+ return sizeof (poly1305_state) + CRYPTOBOX_ALIGNMENT;
+}
+
+static void *
+rspamd_cryptobox_encrypt_init (void *enc_ctx, const rspamd_nonce_t nonce,
+ const rspamd_nm_t nm)
+{
+ chacha_state *s;
+
+ s = cryptobox_align_ptr (enc_ctx, CRYPTOBOX_ALIGNMENT);
+ xchacha_init (s, (const chacha_key *) nm, (const chacha_iv24 *) nonce, 20);
+
+ return s;
+}
+
+static void *
+rspamd_cryptobox_auth_init (void *auth_ctx, void *enc_ctx)
+{
+ poly1305_state *mac_ctx;
guchar RSPAMD_ALIGNED(32) subkey[CHACHA_BLOCKBYTES];
- chacha_state s;
- gsize r;
- xchacha_init (&s, (const chacha_key *)nm, (const chacha_iv24 *)nonce, 20);
+ mac_ctx = cryptobox_align_ptr (auth_ctx, CRYPTOBOX_ALIGNMENT);
memset (subkey, 0, sizeof (subkey));
- chacha_update (&s, subkey, subkey, sizeof (subkey));
+ chacha_update (enc_ctx, subkey, subkey, sizeof (subkey));
+ poly1305_init (mac_ctx, (const poly1305_key *) subkey);
+ rspamd_explicit_memzero (subkey, sizeof (subkey));
+
+ return mac_ctx;
+}
+
+static gboolean
+rspamd_cryptobox_encrypt_update (void *enc_ctx, const guchar *in, gsize inlen,
+ guchar *out, gsize *outlen)
+{
+ gsize r;
+
+ r = chacha_update (enc_ctx, in, out, inlen);
+
+ if (outlen != NULL) {
+ *outlen = r;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+rspamd_cryptobox_auth_update (void *auth_ctx, const guchar *in, gsize inlen)
+{
+ poly1305_update (auth_ctx, in, inlen);
- r = chacha_update (&s, data, data, len);
- chacha_final (&s, data + r);
+ return TRUE;
+}
- poly1305_init (&mac_ctx, (const poly1305_key *)subkey);
- poly1305_update (&mac_ctx, data, len);
- poly1305_finish (&mac_ctx, sig);
+static gsize
+rspamd_cryptobox_encrypt_final (void *enc_ctx, guchar *out)
+{
+ return chacha_final (enc_ctx, out);
+}
+
+static gboolean
+rspamd_cryptobox_auth_final (void *auth_ctx, rspamd_sig_t sig)
+{
+ poly1305_finish (auth_ctx, sig);
+
+ return TRUE;
+}
- rspamd_explicit_memzero (&mac_ctx, sizeof (mac_ctx));
+static void *
+rspamd_cryptobox_decrypt_init (void *enc_ctx, const rspamd_nonce_t nonce,
+ const rspamd_nm_t nm)
+{
+ chacha_state *s;
+
+ s = cryptobox_align_ptr (enc_ctx, CRYPTOBOX_ALIGNMENT);
+ xchacha_init (s, (const chacha_key *) nm, (const chacha_iv24 *) nonce, 20);
+
+ return s;
+}
+
+static void *
+rspamd_cryptobox_auth_verify_init (void *auth_ctx, void *enc_ctx)
+{
+ poly1305_state *mac_ctx;
+ guchar RSPAMD_ALIGNED(32) subkey[CHACHA_BLOCKBYTES];
+
+ mac_ctx = cryptobox_align_ptr (auth_ctx, CRYPTOBOX_ALIGNMENT);
+ memset (subkey, 0, sizeof (subkey));
+ chacha_update (enc_ctx, subkey, subkey, sizeof (subkey));
+ poly1305_init (mac_ctx, (const poly1305_key *) subkey);
rspamd_explicit_memzero (subkey, sizeof (subkey));
+
+ return mac_ctx;
+}
+
+static gboolean
+rspamd_cryptobox_decrypt_update (void *enc_ctx, const guchar *in, gsize inlen,
+ guchar *out, gsize *outlen)
+{
+ gsize r;
+
+ r = chacha_update (enc_ctx, in, out, inlen);
+
+ if (outlen != NULL) {
+ *outlen = r;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+rspamd_cryptobox_auth_verify_update (void *auth_ctx, const guchar *in, gsize inlen)
+{
+ poly1305_update (auth_ctx, in, inlen);
+
+ return TRUE;
+}
+
+static gsize
+rspamd_cryptobox_decrypt_final (void *enc_ctx, guchar *out)
+{
+ return chacha_final (enc_ctx, out);
+}
+
+static gboolean
+rspamd_cryptobox_auth_verify_final (void *auth_ctx, const rspamd_sig_t sig)
+{
+ rspamd_sig_t mac;
+
+ poly1305_finish (auth_ctx, mac);
+
+ if (!poly1305_verify (mac, sig)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+static void
+rspamd_cryptobox_cleanup (void *enc_ctx, void *auth_ctx)
+{
+ rspamd_explicit_memzero (auth_ctx, sizeof (poly1305_state));
+}
+
+void rspamd_cryptobox_encrypt_nm_inplace (guchar *data, gsize len,
+ const rspamd_nonce_t nonce,
+ const rspamd_nm_t nm,
+ rspamd_sig_t sig)
+{
+ gsize r;
+ void *enc_ctx, *auth_ctx;
+
+ enc_ctx = g_alloca (rspamd_cryptobox_encrypt_ctx_len ());
+ auth_ctx = g_alloca (rspamd_cryptobox_auth_ctx_len ());
+
+ enc_ctx = rspamd_cryptobox_encrypt_init (enc_ctx, nonce, nm);
+ auth_ctx = rspamd_cryptobox_auth_init (auth_ctx, enc_ctx);
+
+ rspamd_cryptobox_encrypt_update (enc_ctx, data, len, data, &r);
+ rspamd_cryptobox_encrypt_final (enc_ctx, data + r);
+
+ rspamd_cryptobox_auth_update (auth_ctx, data, len);
+ rspamd_cryptobox_auth_final (auth_ctx, sig);
+
+ rspamd_cryptobox_cleanup (enc_ctx, auth_ctx);
}
static void
@@ -284,23 +445,23 @@ rspamd_cryptobox_flush_outbuf (struct rspamd_cryptobox_segment *st,
}
}
-void rspamd_cryptobox_encryptv_nm_inplace (struct rspamd_cryptobox_segment *segments,
+void
+rspamd_cryptobox_encryptv_nm_inplace (struct rspamd_cryptobox_segment *segments,
gsize cnt,
const rspamd_nonce_t nonce,
const rspamd_nm_t nm, rspamd_sig_t sig)
{
struct rspamd_cryptobox_segment *cur = segments, *start_seg = segments;
- guchar RSPAMD_ALIGNED(32) subkey[CHACHA_BLOCKBYTES],
- outbuf[CHACHA_BLOCKBYTES * 16];
- poly1305_state mac_ctx;
+ guchar outbuf[CHACHA_BLOCKBYTES * 16];
+ void *enc_ctx, *auth_ctx;
guchar *out, *in;
- chacha_state s;
gsize r, remain, inremain, seg_offset;
- xchacha_init (&s, (const chacha_key *)nm, (const chacha_iv24 *)nonce, 20);
- memset (subkey, 0, sizeof (subkey));
- chacha_update (&s, subkey, subkey, sizeof (subkey));
- poly1305_init (&mac_ctx, (const poly1305_key *)subkey);
+ enc_ctx = g_alloca (rspamd_cryptobox_encrypt_ctx_len ());
+ auth_ctx = g_alloca (rspamd_cryptobox_auth_ctx_len ());
+
+ enc_ctx = rspamd_cryptobox_encrypt_init (enc_ctx, nonce, nm);
+ auth_ctx = rspamd_cryptobox_auth_init (auth_ctx, enc_ctx);
remain = sizeof (outbuf);
out = outbuf;
@@ -319,8 +480,9 @@ void rspamd_cryptobox_encryptv_nm_inplace (struct rspamd_cryptobox_segment *segm
cur ++;
if (remain == 0) {
- chacha_update (&s, outbuf, outbuf, sizeof (outbuf));
- poly1305_update (&mac_ctx, outbuf, sizeof (outbuf));
+ rspamd_cryptobox_encrypt_update (enc_ctx, outbuf, sizeof (outbuf),
+ outbuf, NULL);
+ rspamd_cryptobox_auth_update (auth_ctx, outbuf, sizeof (outbuf));
rspamd_cryptobox_flush_outbuf (start_seg, outbuf,
sizeof (outbuf), seg_offset);
start_seg = cur;
@@ -331,8 +493,9 @@ void rspamd_cryptobox_encryptv_nm_inplace (struct rspamd_cryptobox_segment *segm
}
else {
memcpy (out, cur->data, remain);
- chacha_update (&s, outbuf, outbuf, sizeof (outbuf));
- poly1305_update (&mac_ctx, outbuf, sizeof (outbuf));
+ rspamd_cryptobox_encrypt_update (enc_ctx, outbuf, sizeof (outbuf),
+ outbuf, NULL);
+ rspamd_cryptobox_auth_update (auth_ctx, outbuf, sizeof (outbuf));
rspamd_cryptobox_flush_outbuf (start_seg, outbuf, sizeof (outbuf),
seg_offset);
seg_offset = 0;
@@ -346,8 +509,14 @@ void rspamd_cryptobox_encryptv_nm_inplace (struct rspamd_cryptobox_segment *segm
while (inremain > 0) {
if (sizeof (outbuf) <= inremain) {
memcpy (outbuf, in, sizeof (outbuf));
- chacha_update (&s, outbuf, outbuf, sizeof (outbuf));
- poly1305_update (&mac_ctx, outbuf, sizeof (outbuf));
+ rspamd_cryptobox_encrypt_update (enc_ctx,
+ outbuf,
+ sizeof (outbuf),
+ outbuf,
+ NULL);
+ rspamd_cryptobox_auth_update (auth_ctx,
+ outbuf,
+ sizeof (outbuf));
memcpy (in, outbuf, sizeof (outbuf));
in += sizeof (outbuf);
inremain -= sizeof (outbuf);
@@ -366,48 +535,44 @@ void rspamd_cryptobox_encryptv_nm_inplace (struct rspamd_cryptobox_segment *segm
}
}
- r = chacha_update (&s, outbuf, outbuf, sizeof (outbuf) - remain);
+ rspamd_cryptobox_encrypt_update (enc_ctx, outbuf, sizeof (outbuf) - remain,
+ outbuf, &r);
out = outbuf + r;
- chacha_final (&s, out);
- poly1305_update (&mac_ctx, outbuf, sizeof (outbuf) - remain);
- poly1305_finish (&mac_ctx, sig);
+ rspamd_cryptobox_encrypt_final (enc_ctx, out);
+
+ rspamd_cryptobox_auth_update (auth_ctx, outbuf, sizeof (outbuf) - remain);
+ rspamd_cryptobox_auth_final (auth_ctx, sig);
rspamd_cryptobox_flush_outbuf (start_seg, outbuf, sizeof (outbuf) - remain,
seg_offset);
- rspamd_explicit_memzero (&mac_ctx, sizeof (mac_ctx));
- rspamd_explicit_memzero (subkey, sizeof (subkey));
+ rspamd_cryptobox_cleanup (auth_ctx, enc_ctx);
}
gboolean
rspamd_cryptobox_decrypt_nm_inplace (guchar *data, gsize len,
const rspamd_nonce_t nonce, const rspamd_nm_t nm, const rspamd_sig_t sig)
{
- poly1305_state mac_ctx;
- guchar RSPAMD_ALIGNED(32) subkey[CHACHA_BLOCKBYTES];
- rspamd_sig_t mac;
- chacha_state s;
gsize r;
gboolean ret = TRUE;
+ void *enc_ctx, *auth_ctx;
- /* Generate MAC key */
- xchacha_init (&s, (const chacha_key *)nm, (const chacha_iv24 *)nonce, 20);
- memset (subkey, 0, sizeof (subkey));
- chacha_update (&s, subkey, subkey, sizeof (subkey));
+ enc_ctx = g_alloca (rspamd_cryptobox_encrypt_ctx_len ());
+ auth_ctx = g_alloca (rspamd_cryptobox_auth_ctx_len ());
- poly1305_init (&mac_ctx, (const poly1305_key *)subkey);
- poly1305_update (&mac_ctx, data, len);
- poly1305_finish (&mac_ctx, mac);
+ enc_ctx = rspamd_cryptobox_decrypt_init (enc_ctx, nonce, nm);
+ auth_ctx = rspamd_cryptobox_auth_verify_init (auth_ctx, enc_ctx);
- if (!poly1305_verify (mac, sig)) {
+ rspamd_cryptobox_auth_verify_update (auth_ctx, data, len);
+
+ if (!rspamd_cryptobox_auth_verify_final (auth_ctx, sig)) {
ret = FALSE;
}
else {
- r = chacha_update (&s, data, data, len);
- chacha_final (&s, data + r);
+ rspamd_cryptobox_decrypt_update (enc_ctx, data, len, data, &r);
+ rspamd_cryptobox_decrypt_final (enc_ctx, data + r);
}
- rspamd_explicit_memzero (&mac_ctx, sizeof (mac_ctx));
- rspamd_explicit_memzero (subkey, sizeof (subkey));
+ rspamd_cryptobox_cleanup (enc_ctx, auth_ctx);
return ret;
}
@@ -519,3 +684,9 @@ rspamd_cryptobox_pbkdf (const char *pass, gsize pass_len,
return TRUE;
}
+
+void
+rspamd_cryptobox_openssl_mode (gboolean enable)
+{
+ use_openssl = enable;
+}
diff --git a/src/libcryptobox/cryptobox.h b/src/libcryptobox/cryptobox.h
index 9fb0cb113..3305fccc1 100644
--- a/src/libcryptobox/cryptobox.h
+++ b/src/libcryptobox/cryptobox.h
@@ -174,4 +174,10 @@ gboolean rspamd_cryptobox_pbkdf(const char *pass, gsize pass_len,
const guint8 *salt, gsize salt_len, guint8 *key, gsize key_len,
unsigned int rounds);
+/**
+ * Enable openssl mode in rspamd_cryptobox
+ * @param enable if TRUE then crypto code will use openssl, chacha20/poly1305 otherwize
+ */
+void rspamd_cryptobox_openssl_mode (gboolean enable);
+
#endif /* CRYPTOBOX_H_ */