commit 5bcf700: [Fix] Fix rfc base32 encode ordering (skip inverse bits)

Vsevolod Stakhov vsevolod at highsecure.ru
Fri Jul 3 16:21:07 UTC 2020


Author: Vsevolod Stakhov
Date: 2020-07-03 16:21:28 +0100
URL: https://github.com/rspamd/rspamd/commit/5bcf700ce9b09e6183897fb8d51227740eb7d78f

[Fix] Fix rfc base32 encode ordering (skip inverse bits)

---
 src/libutil/str_util.c | 128 +++++++++++++++++++++++++++++++++----------------
 1 file changed, 88 insertions(+), 40 deletions(-)

diff --git a/src/libutil/str_util.c b/src/libutil/str_util.c
index 882ac5565..5245cd516 100644
--- a/src/libutil/str_util.c
+++ b/src/libutil/str_util.c
@@ -549,6 +549,7 @@ rspamd_encode_base32_buf (const guchar *in, gsize inlen, gchar *out, gsize outle
 	gchar *o, *end;
 	gsize i;
 	gint remain = -1, x;
+	bool inverse_order = true;
 
 	end = out + outlen;
 	o = out;
@@ -559,58 +560,105 @@ rspamd_encode_base32_buf (const guchar *in, gsize inlen, gchar *out, gsize outle
 		break;
 	case RSPAMD_BASE32_BLEACH:
 		b32 = b32_bleach;
+		inverse_order = false;
 		break;
 	case RSPAMD_BASE32_RFC:
 		b32 = b32_rfc;
+		inverse_order = false;
 		break;
 	default:
 		g_assert_not_reached ();
 		abort ();
 	}
 
-	for (i = 0; i < inlen && o < end - 1; i++) {
-		switch (i % 5) {
-		case 0:
-			/* 8 bits of input and 3 to remain */
-			x = in[i];
-			remain = in[i] >> 5;
-			*o++ = b32[x & 0x1F];
-			break;
-		case 1:
-			/* 11 bits of input, 1 to remain */
-			x = remain | in[i] << 3;
-			*o++ = b32[x & 0x1F];
-			*o++ = b32[x >> 5 & 0x1F];
-			remain = x >> 10;
-			break;
-		case 2:
-			/* 9 bits of input, 4 to remain */
-			x = remain | in[i] << 1;
-			*o++ = b32[x & 0x1F];
-			remain = x >> 5;
-			break;
-		case 3:
-			/* 12 bits of input, 2 to remain */
-			x = remain | in[i] << 4;
-			*o++ = b32[x & 0x1F];
-			*o++ = b32[x >> 5 & 0x1F];
-			remain = x >> 10 & 0x3;
-			break;
-		case 4:
-			/* 10 bits of output, nothing to remain */
-			x = remain | in[i] << 2;
-			*o++ = b32[x & 0x1F];
-			*o++ = b32[x >> 5 & 0x1F];
-			remain = -1;
-			break;
-		default:
-			/* Not to be happen */
-			break;
+	if (inverse_order) {
+		/* Zbase32 as used in Rspamd */
+		for (i = 0; i < inlen && o < end - 1; i++) {
+			switch (i % 5) {
+			case 0:
+				/* 8 bits of input and 3 to remain */
+				x = in[i];
+				remain = in[i] >> 5;
+				*o++ = b32[x & 0x1F];
+				break;
+			case 1:
+				/* 11 bits of input, 1 to remain */
+				x = remain | in[i] << 3;
+				*o++ = b32[x & 0x1F];
+				*o++ = b32[x >> 5 & 0x1F];
+				remain = x >> 10;
+				break;
+			case 2:
+				/* 9 bits of input, 4 to remain */
+				x = remain | in[i] << 1;
+				*o++ = b32[x & 0x1F];
+				remain = x >> 5;
+				break;
+			case 3:
+				/* 12 bits of input, 2 to remain */
+				x = remain | in[i] << 4;
+				*o++ = b32[x & 0x1F];
+				*o++ = b32[x >> 5 & 0x1F];
+				remain = x >> 10 & 0x3;
+				break;
+			case 4:
+				/* 10 bits of output, nothing to remain */
+				x = remain | in[i] << 2;
+				*o++ = b32[x & 0x1F];
+				*o++ = b32[x >> 5 & 0x1F];
+				remain = -1;
+				break;
+			default:
+				/* Not to be happen */
+				break;
+			}
+		}
+	}
+	else {
+		/* Traditional base32 with no bits inversion */
+		for (i = 0; i < inlen && o < end - 1; i++) {
+			switch (i % 5) {
+			case 0:
+				/* 8 bits of input and 3 to remain */
+				x = in[i] >> 3;
+				remain = (in[i] & 7) << 2;
+				*o++ = b32[x & 0x1F];
+				break;
+			case 1:
+				/* 11 bits of input, 1 to remain */
+				x = (remain << 6) | in[i];
+				*o++ = b32[(x >> 6) & 0x1F];
+				*o++ = b32[(x >> 1) & 0x1F];
+				remain = (x & 0x1) << 4;
+				break;
+			case 2:
+				/* 9 bits of input, 4 to remain */
+				x = (remain << 4) | in[i];
+				*o++ = b32[(x >> 4) & 0x1F];
+				remain = (x & 15) << 1;
+				break;
+			case 3:
+				/* 12 bits of input, 2 to remain */
+				x = (remain << 7) | in[i];
+				*o++ = b32[(x >> 7) & 0x1F];
+				*o++ = b32[(x >> 2) & 0x1F];
+				remain = (x & 3) << 3;
+				break;
+			case 4:
+				/* 10 bits of output, nothing to remain */
+				x = (remain << 5) | in[i];
+				*o++ = b32[(x >> 5) & 0x1F];
+				*o++ = b32[x & 0x1F];
+				remain = -1;
+				break;
+			default:
+				/* Not to be happen */
+				break;
+			}
 		}
-
 	}
 	if (remain >= 0 && o < end) {
-		*o++ = b32[remain];
+		*o++ = b32[remain & 0x1F];
 	}
 
 	if (o <= end) {


More information about the Commits mailing list