commit 763627c: [Project] Fix digest calculation (use siphash)

Vsevolod Stakhov vsevolod at highsecure.ru
Fri Jul 12 16:42:25 UTC 2019


Author: Vsevolod Stakhov
Date: 2019-07-12 15:11:19 +0100
URL: https://github.com/rspamd/rspamd/commit/763627cbcb9ffcb0a29e94152fe4ff907099678c

[Project] Fix digest calculation (use siphash)

---
 src/libmime/message.c | 51 +++++++++++++++++++++++++++++++++++++--------------
 src/libmime/message.h | 28 ++++++++++++++++------------
 2 files changed, 53 insertions(+), 26 deletions(-)

diff --git a/src/libmime/message.c b/src/libmime/message.c
index 106556c66..a725d7e89 100644
--- a/src/libmime/message.c
+++ b/src/libmime/message.c
@@ -34,6 +34,7 @@
 
 #include <math.h>
 #include <unicode/uchar.h>
+#include "sodium.h"
 #include "libserver/cfg_file_private.h"
 #include "lua/lua_common.h"
 #include "contrib/uthash/utlist.h"
@@ -1157,8 +1158,6 @@ rspamd_message_parse (struct rspamd_task *task)
 	gsize len;
 	guint i;
 	GError *err = NULL;
-	rspamd_cryptobox_hash_state_t st;
-	guchar digest_out[rspamd_cryptobox_HASHBYTES];
 
 	if (RSPAMD_TASK_IS_EMPTY (task)) {
 		/* Don't do anything with empty task */
@@ -1210,7 +1209,6 @@ rspamd_message_parse (struct rspamd_task *task)
 		rspamd_message_unref (task->message);
 	}
 
-	rspamd_cryptobox_hash_init (&st, NULL, 0);
 	task->message = rspamd_message_new (task);
 
 	if (task->flags & RSPAMD_TASK_FLAG_MIME) {
@@ -1344,26 +1342,37 @@ rspamd_message_parse (struct rspamd_task *task)
 		}
 	}
 
+	struct rspamd_mime_part *part;
+
+	/* Blake2b applied to string 'rspamd' */
+	static const guchar RSPAMD_ALIGNED(32) hash_key[] = {
+			0xef,0x43,0xae,0x80,0xcc,0x8d,0xc3,0x4c,
+			0x6f,0x1b,0xd6,0x18,0x1b,0xae,0x87,0x74,
+			0x0c,0xca,0xf7,0x8e,0x5f,0x2e,0x54,0x32,
+			0xf6,0x79,0xb9,0x27,0x26,0x96,0x20,0x92,
+			0x70,0x07,0x85,0xeb,0x83,0xf7,0x89,0xe0,
+			0xd7,0x32,0x2a,0xd2,0x1a,0x64,0x41,0xef,
+			0x49,0xff,0xc3,0x8c,0x54,0xf9,0x67,0x74,
+			0x30,0x1e,0x70,0x2e,0xb7,0x12,0x09,0xfe,
+	};
+
+	PTR_ARRAY_FOREACH (MESSAGE_FIELD (task, parts), i, part) {
+		crypto_shorthash_siphashx24 (MESSAGE_FIELD (task, digest),
+				part->digest, sizeof (part->digest),
+				i == 0 ? hash_key : MESSAGE_FIELD (task, digest));
+	}
+
 	/* Parse urls inside Subject header */
 	if (MESSAGE_FIELD (task, subject)) {
 		p = MESSAGE_FIELD (task, subject);
 		len = strlen (p);
-		rspamd_cryptobox_hash_update (&st, p, len);
+		crypto_shorthash_siphashx24 (MESSAGE_FIELD (task, digest), p, len,
+				MESSAGE_FIELD (task, digest));
 		rspamd_url_find_multiple (task->task_pool, p, len,
 				RSPAMD_URL_FIND_STRICT, NULL,
 				rspamd_url_task_subject_callback, task);
 	}
 
-	struct rspamd_mime_part *part;
-
-	PTR_ARRAY_FOREACH (MESSAGE_FIELD (task, parts), i, part) {
-		rspamd_cryptobox_hash_update (&st, part->digest, sizeof (part->digest));
-	}
-
-	rspamd_cryptobox_hash_final (&st, digest_out);
-	memcpy (MESSAGE_FIELD (task, digest), digest_out,
-			sizeof (MESSAGE_FIELD (task, digest)));
-
 	if (task->queue_id) {
 		msg_info_task ("loaded message; id: <%s>; queue-id: <%s>; size: %z; "
 				"checksum: <%*xs>",
@@ -1558,3 +1567,17 @@ void rspamd_message_unref (struct rspamd_message *msg)
 		REF_RELEASE (msg);
 	}
 }
+
+void rspamd_message_update_digest (struct rspamd_message *msg,
+								   const void *input, gsize len)
+{
+	guchar RSPAMD_ALIGNED(32) ex_key[crypto_shorthash_siphashx24_KEYBYTES];
+
+	/* Sanity */
+	G_STATIC_ASSERT (sizeof (ex_key) == sizeof (msg->digest));
+	G_STATIC_ASSERT (crypto_shorthash_siphashx24_BYTES == sizeof (msg->digest));
+
+	memcpy (ex_key, msg->digest, sizeof (msg->digest));
+
+	crypto_shorthash_siphashx24 (msg->digest, input, len, ex_key);
+}
\ No newline at end of file
diff --git a/src/libmime/message.h b/src/libmime/message.h
index a453db086..cc4db39f4 100644
--- a/src/libmime/message.h
+++ b/src/libmime/message.h
@@ -132,17 +132,19 @@ struct rspamd_mime_text_part {
 	guint unicode_scripts;
 };
 
+struct rspamd_message_raw_headers_content {
+	const gchar *begin;
+	gsize len;
+	const gchar *body_start;
+};
+
 struct rspamd_message {
 	const gchar *message_id;
 	gchar *subject;
 
 	GPtrArray *parts;				/**< list of parsed parts							*/
 	GPtrArray *text_parts;			/**< list of text parts								*/
-	struct {
-		const gchar *begin;
-		gsize len;
-		const gchar *body_start;
-	} raw_headers_content;						/**< list of raw headers							*/
+	struct rspamd_message_raw_headers_content raw_headers_content;
 	struct rspamd_received_header *received;	/**< list of received headers						*/
 	GHashTable *urls;							/**< list of parsed urls							*/
 	GHashTable *emails;							/**< list of parsed emails							*/
@@ -155,14 +157,7 @@ struct rspamd_message {
 	ref_entry_t ref;
 };
 
-#ifndef FULL_DEBUG
 #define MESSAGE_FIELD(task, field) ((task)->message->field)
-#else
-#define MESSAGE_FIELD(task, field)
-	((!(task)->message) ? \
-	(__typeof__((task)->message->field))(msg_err_task("no message when getting field %s", #field), g_assert(0), NULL) : \
-	((task)->message->field))
-#endif
 
 /**
  * Parse and pre-process mime message
@@ -198,6 +193,15 @@ struct rspamd_message *rspamd_message_ref (struct rspamd_message *msg);
 
 void rspamd_message_unref (struct rspamd_message *msg);
 
+/**
+ * Updates digest of the message if modified
+ * @param msg
+ * @param input
+ * @param len
+ */
+void rspamd_message_update_digest (struct rspamd_message *msg,
+		const void *input, gsize len);
+
 #ifdef  __cplusplus
 }
 #endif


More information about the Commits mailing list