gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libmicrohttpd] branch master updated (7676e698 -> 7b3e010b)


From: gnunet
Subject: [libmicrohttpd] branch master updated (7676e698 -> 7b3e010b)
Date: Tue, 18 May 2021 19:27:28 +0200

This is an automated email from the git hooks/post-receive script.

karlson2k pushed a change to branch master
in repository libmicrohttpd.

    from 7676e698 Updated test_sha* and test_md5 with unaligned data
     new 89387e53 Implemented basement to work with unaligned data
     new f5977567 Fixed SHA-1 calculation with unaligned data
     new 7b3e010b sha-1 minor improvements

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 configure.ac                    | 50 +++++++++++++++++++++++++++
 src/microhttpd/Makefile.am      | 16 ++++-----
 src/microhttpd/mhd_align.h      | 75 +++++++++++++++++++++++++++++++++++++++++
 src/microhttpd/mhd_bithelpers.h | 44 +++++++++++++++++++-----
 src/microhttpd/sha1.c           | 51 +++++++++++++++++++++-------
 src/microhttpd/sha1.h           | 14 ++++++--
 6 files changed, 218 insertions(+), 32 deletions(-)
 create mode 100644 src/microhttpd/mhd_align.h

diff --git a/configure.ac b/configure.ac
index cfe3e554..0cf4e43f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -307,6 +307,56 @@ AS_IF([[test "x$inln_prfx" != "xnone"]],
 AC_MSG_RESULT([[$inln_prfx]])
 CFLAGS="$save_CFLAGS"
 
+AC_CHECK_HEADERS([stdalign.h], [], [], [AC_INCLUDES_DEFAULT])
+AC_CACHE_CHECK([[for C11 'alignof()' support]], [[mhd_cv_c_alignof]],
+  [AC_COMPILE_IFELSE(
+     [AC_LANG_PROGRAM(
+        [[
+#ifdef HAVE_STDALIGN_H
+#include <stdalign.h>
+#endif
+        ]], [[
+#if (defined (__GNUC__) && __GNUC__ < 4 && __GNUC_MINOR__ < 9 && ! 
defined(__clang__)) || \
+    (defined (__clang__) && __clang_major__ < 8)
+/* GCC before 4.9 and clang before 8.0 have incorrect implementation of 
'alignof()'
+   which returns preferred alignment instead of minimal required alignment */  
  
+#error Compiler has incorrect implementation of alignof()
+choke me now
+#endif
+          int var1[(alignof(int) >= 2) ? 1 : -1];
+          int var2[alignof(unsigned int) - 1];
+          int var3[(alignof(char) > 0) ? 1 : -1];
+          int var4[(alignof(long) >= 4) ? 1 : -1];
+          
+          /* Mute compiler warnings */
+          var1[0] = var2[0] = var3[0] = 0;
+          var4[0] = 1;
+          if (var1[0] + var2[0] + var3[0] == var4[0])
+            return 1;
+        ]])
+     ], [
+          AC_COMPILE_IFELSE(
+                   [AC_LANG_PROGRAM(
+                       [[
+#ifdef HAVE_STDALIGN_H
+#include <stdalign.h>
+#endif
+                       ]], [[
+                         /* Should fail if 'alignof()' works */
+                         int var1[alignof(nonexisting_type) - 1];
+                         
+                         /* Mute compiler warnings */
+                         var1[0] = 1;
+                         if (var1[0] + 1 == 1)
+                           return 1;
+                       ]])
+                   ], [[mhd_cv_c_alignof='no']], [[mhd_cv_c_alignof='yes']])
+        ], [[mhd_cv_c_alignof='no']])
+  ])
+AS_VAR_IF([mhd_cv_c_alignof], ["yes"],
+  [AC_DEFINE([[HAVE_C_ALIGNOF]], [1], [Define to 1 if your compiler supports 
'alignof()'])])
+
+
 # Check system type
 shutdown_trig_select='no'
 AC_MSG_CHECKING([[for target host OS]])
diff --git a/src/microhttpd/Makefile.am b/src/microhttpd/Makefile.am
index 84fe4f81..abcbeba7 100644
--- a/src/microhttpd/Makefile.am
+++ b/src/microhttpd/Makefile.am
@@ -59,7 +59,7 @@ libmicrohttpd_la_SOURCES = \
   internal.c internal.h \
   memorypool.c memorypool.h \
   mhd_mono_clock.c mhd_mono_clock.h \
-  mhd_limits.h mhd_byteorder.h \
+  mhd_limits.h \
   sysfdsetsize.c sysfdsetsize.h \
   mhd_str.c mhd_str.h \
   mhd_send.h mhd_send.c \
@@ -138,7 +138,7 @@ endif
 if ENABLE_DAUTH
 libmicrohttpd_la_SOURCES += \
   digestauth.c \
-  mhd_bithelpers.h \
+  mhd_bithelpers.h mhd_byteorder.h mhd_align.h \
   md5.c md5.h \
   sha256.c sha256.h
 endif
@@ -345,13 +345,13 @@ test_shutdown_poll_ignore_LDADD = \
 endif
 
 test_str_compare_SOURCES = \
-  test_str.c test_helpers.h mhd_str.c
+  test_str.c test_helpers.h mhd_str.c mhd_str.h
 
 test_str_to_value_SOURCES = \
-  test_str.c test_helpers.h mhd_str.c
+  test_str.c test_helpers.h mhd_str.c mhd_str.h
 
 test_str_token_SOURCES = \
-  test_str_token.c mhd_str.c
+  test_str_token.c mhd_str.c mhd_str.h
 
 test_http_reasons_SOURCES = \
   test_http_reasons.c \
@@ -359,15 +359,15 @@ test_http_reasons_SOURCES = \
 
 test_md5_SOURCES = \
   test_md5.c test_helpers.h \
-  md5.c md5.h mhd_bithelpers.h
+  md5.c md5.h mhd_bithelpers.h mhd_byteorder.h mhd_align.h
 
 test_sha256_SOURCES = \
   test_sha256.c test_helpers.h \
-  sha256.c sha256.h mhd_bithelpers.h
+  sha256.c sha256.h mhd_bithelpers.h mhd_byteorder.h mhd_align.h
 
 test_sha1_SOURCES = \
   test_sha1.c test_helpers.h \
-  sha1.c sha1.h mhd_bithelpers.h
+  sha1.c sha1.h mhd_bithelpers.h mhd_byteorder.h mhd_align.h
 
 test_options_SOURCES = \
   test_options.c
diff --git a/src/microhttpd/mhd_align.h b/src/microhttpd/mhd_align.h
new file mode 100644
index 00000000..4464b6cd
--- /dev/null
+++ b/src/microhttpd/mhd_align.h
@@ -0,0 +1,75 @@
+/*
+  This file is part of libmicrohttpd
+  Copyright (C) 2021 Karlson2k (Evgeny Grin)
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library.
+  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file microhttpd/mhd_align.h
+ * @brief  types alignment macros
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+#ifndef MHD_ALIGN_H
+#define MHD_ALIGN_H 1
+
+#include <stdint.h>
+#include "mhd_options.h"
+#ifdef HAVE_STDDEF_H
+#include <stddef.h>
+#endif
+
+#ifdef HAVE_C_ALIGNOF
+
+#ifdef HAVE_STDALIGN_H
+#include <stdalign.h>
+#endif
+
+#define _MHD_ALIGNOF(type) alignof(type)
+
+#endif /* HAVE_C_ALIGNOF */
+
+#ifdef offsetof
+#define _MHD_OFFSETOF(strct, membr) offsetof(strct, membr)
+#else  /* ! offsetof */
+#define _MHD_OFFSETOF(strct, membr) (size_t)(((char*)&(((strct*)0)->membr)) - \
+                                     ((char*)((strct*)0)))
+#endif /* ! offsetof */
+
+/* Provide a limited set of alignment macros */
+/* The set could be extended as needed */
+#ifdef _MHD_ALIGNOF
+#define _MHD_UINT32_ALIGN _MHD_ALIGNOF(uint32_t)
+#define _MHD_UINT64_ALIGN _MHD_ALIGNOF(uint64_t)
+#else  /* ! _MHD_ALIGNOF */
+struct _mhd_dummy_uint32_offset_test
+{
+  char dummy;
+  uint32_t ui32;
+};
+#define _MHD_UINT32_ALIGN \
+  _MHD_OFFSETOF(struct _mhd_dummy_uint32_offset_test, ui32)
+
+struct _mhd_dummy_uint64_offset_test
+{
+  char dummy;
+  uint32_t ui64;
+};
+#define _MHD_UINT32_ALIGN \
+  _MHD_OFFSETOF(struct _mhd_dummy_uint64_offset_test, ui64)
+#endif /* ! _MHD_ALIGNOF */
+
+#endif /* ! MHD_ALIGN_H */
diff --git a/src/microhttpd/mhd_bithelpers.h b/src/microhttpd/mhd_bithelpers.h
index c8c814ac..12e1a569 100644
--- a/src/microhttpd/mhd_bithelpers.h
+++ b/src/microhttpd/mhd_bithelpers.h
@@ -32,8 +32,13 @@
 /* Declarations for VC & Clang/C2 built-ins */
 #include <intrin.h>
 #endif /* _MSC_FULL_VER  */
+#include "mhd_options.h"
 #include "mhd_assert.h"
 #include "mhd_byteorder.h"
+#if _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN || _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN
+#include "mhd_align.h"
+#endif /* _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN ||
+          _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN */
 
 #ifndef __has_builtin
 /* Avoid precompiler errors with non-clang */
@@ -158,15 +163,8 @@
  * put native-endian 64-bit value64 to addr
  * in big-endian mode.
  */
-#if _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN
-#define _MHD_PUT_64BIT_BE(addr, value64)             \
-  ((*(uint64_t*) (addr)) = (uint64_t) (value64))
-#elif _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN
-#define _MHD_PUT_64BIT_BE(addr, value64)             \
-  ((*(uint64_t*) (addr)) = _MHD_BYTES_SWAP64 (value64))
-#else  /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */
-/* Endianness was not detected or non-standard like PDP-endian */
-#define _MHD_PUT_64BIT_BE(addr, value64) do {                            \
+/* Slow version that works with unaligned addr and with any bytes order */
+#define _MHD_PUT_64BIT_BE_SLOW(addr, value64) do {                       \
     ((uint8_t*) (addr))[7] = (uint8_t) ((uint64_t) (value64));           \
     ((uint8_t*) (addr))[6] = (uint8_t) (((uint64_t) (value64)) >> 8);    \
     ((uint8_t*) (addr))[5] = (uint8_t) (((uint64_t) (value64)) >> 16);   \
@@ -176,8 +174,32 @@
     ((uint8_t*) (addr))[1] = (uint8_t) (((uint64_t) (value64)) >> 48);   \
     ((uint8_t*) (addr))[0] = (uint8_t) (((uint64_t) (value64)) >> 56);   \
 } while (0)
+#if _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN
+#define _MHD_PUT_64BIT_BE(addr, value64)             \
+  ((*(uint64_t*) (addr)) = (uint64_t) (value64))
+#elif _MHD_BYTE_ORDER == _MHD_LITTLE_ENDIAN
+#define _MHD_PUT_64BIT_BE(addr, value64)             \
+  ((*(uint64_t*) (addr)) = _MHD_BYTES_SWAP64 (value64))
+#else  /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */
+/* Endianness was not detected or non-standard like PDP-endian */
+#define _MHD_PUT_64BIT_BE(addr, value64) _MHD_PUT_64BIT_BE_SLOW(addr, value64)
+/* Indicate that _MHD_PUT_64BIT_BE does not need aligned pointer */
+#define _MHD_PUT_64BIT_BE_UNALIGNED 1
 #endif /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */
 
+/* Put result safely to unaligned address */
+_MHD_static_inline void
+_MHD_PUT_64BIT_BE_SAFE (void *dst, uint64_t value)
+{
+#ifndef _MHD_PUT_64BIT_BE_UNALIGNED
+  if (0 != ((uintptr_t) dst) % (_MHD_UINT64_ALIGN))
+    _MHD_PUT_64BIT_BE_SLOW (dst, value);
+  else
+#endif /* _MHD_BYTE_ORDER_IS_BIG_OR_LITTLE_ENDIAN */
+  _MHD_PUT_64BIT_BE (dst, value);
+}
+
+
 /* _MHD_PUT_32BIT_BE (addr, value32)
  * put native-endian 32-bit value32 to addr
  * in big-endian mode.
@@ -196,6 +218,8 @@
     ((uint8_t*) (addr))[1] = (uint8_t) (((uint32_t) (value32)) >> 16);   \
     ((uint8_t*) (addr))[0] = (uint8_t) (((uint32_t) (value32)) >> 24);   \
 } while (0)
+/* Indicate that _MHD_PUT_32BIT_BE does not need aligned pointer */
+#define _MHD_PUT_32BIT_BE_UNALIGNED 1
 #endif /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */
 
 /* _MHD_GET_32BIT_BE (addr)
@@ -215,6 +239,8 @@
     | (((uint32_t) (((const uint8_t*) addr)[1])) << 16)   \
     | (((uint32_t) (((const uint8_t*) addr)[2])) << 8)    \
     | ((uint32_t) (((const uint8_t*) addr)[3])) )
+/* Indicate that _MHD_GET_32BIT_BE does not need aligned pointer */
+#define _MHD_GET_32BIT_BE_UNALIGNED 1
 #endif /* _MHD_BYTE_ORDER != _MHD_LITTLE_ENDIAN */
 
 
diff --git a/src/microhttpd/sha1.c b/src/microhttpd/sha1.c
index 51deabaa..2ed84208 100644
--- a/src/microhttpd/sha1.c
+++ b/src/microhttpd/sha1.c
@@ -54,11 +54,6 @@ MHD_SHA1_init (void *ctx_)
 }
 
 
-/**
- * Number of bytes in single SHA-1 word
- */
-#define SHA1_BYTES_IN_WORD (32 / 8)
-
 /**
  * Base of SHA-1 transformation.
  * Gets full 512 bits / 64 bytes block of data and updates hash values;
@@ -113,6 +108,18 @@ sha1_transform (uint32_t H[_SHA1_DIGEST_LENGTH],
 #define GET_W_FROM_DATA(buf,t) \
   _MHD_GET_32BIT_BE (((const uint8_t*) (buf)) + (t) * SHA1_BYTES_IN_WORD)
 
+#ifndef _MHD_GET_32BIT_BE_UNALIGNED
+  if (0 != ((size_t) data % _MHD_UINT32_ALIGN))
+  {
+    /* Copy the unaligned input data to the aligned buffer */
+    memcpy (W, data, SHA1_BLOCK_SIZE);
+    /* The W[] buffer itself will be used as the source of the data,
+     * but data will be reloaded in correct bytes order during
+     * the next steps */
+    data = (uint8_t*) W;
+  }
+#endif /* _MHD_GET_32BIT_BE_UNALIGNED */
+
 /* SHA-1 values of Kt for t=0..19, see FIPS PUB 180-4 paragraph 4.2.1. */
 #define K00      0x5a827999UL
 /* SHA-1 values of Kt for t=20..39, see FIPS PUB 180-4 paragraph 4.2.1.*/
@@ -310,7 +317,7 @@ MHD_SHA1_finish (void *ctx_,
 
   num_bits = ctx->count << 3;
   /* Note: (count & (SHA1_BLOCK_SIZE-1))
-           equal (count % SHA1_BLOCK_SIZE) for this block size. */
+           equals (count % SHA1_BLOCK_SIZE) for this block size. */
   bytes_have = (unsigned) (ctx->count & (SHA1_BLOCK_SIZE - 1));
 
   /* Input data must be padded with bit "1" and with length of data in bits.
@@ -336,17 +343,35 @@ MHD_SHA1_finish (void *ctx_,
   memset (ctx->buffer + bytes_have, 0,
           SHA1_BLOCK_SIZE - SHA1_SIZE_OF_LEN_ADD - bytes_have);
   /* Put the number of bits in the processed message as a big-endian value. */
-  _MHD_PUT_64BIT_BE (ctx->buffer + SHA1_BLOCK_SIZE - SHA1_SIZE_OF_LEN_ADD,
-                     num_bits);
+  _MHD_PUT_64BIT_BE_SAFE (ctx->buffer + SHA1_BLOCK_SIZE - SHA1_SIZE_OF_LEN_ADD,
+                          num_bits);
   /* Process the full final block. */
   sha1_transform (ctx->H, ctx->buffer);
 
   /* Put final hash/digest in BE mode */
-  _MHD_PUT_32BIT_BE (digest + 0 * SHA1_BYTES_IN_WORD, ctx->H[0]);
-  _MHD_PUT_32BIT_BE (digest + 1 * SHA1_BYTES_IN_WORD, ctx->H[1]);
-  _MHD_PUT_32BIT_BE (digest + 2 * SHA1_BYTES_IN_WORD, ctx->H[2]);
-  _MHD_PUT_32BIT_BE (digest + 3 * SHA1_BYTES_IN_WORD, ctx->H[3]);
-  _MHD_PUT_32BIT_BE (digest + 4 * SHA1_BYTES_IN_WORD, ctx->H[4]);
+#ifndef _MHD_PUT_32BIT_BE_UNALIGNED
+  if (0 != ((uintptr_t) digest) % _MHD_UINT32_ALIGN)
+  {
+    uint32_t alig_dgst[_SHA1_DIGEST_LENGTH];
+    _MHD_PUT_32BIT_BE (alig_dgst + 0, ctx->H[0]);
+    _MHD_PUT_32BIT_BE (alig_dgst + 1, ctx->H[1]);
+    _MHD_PUT_32BIT_BE (alig_dgst + 2, ctx->H[2]);
+    _MHD_PUT_32BIT_BE (alig_dgst + 3, ctx->H[3]);
+    _MHD_PUT_32BIT_BE (alig_dgst + 4, ctx->H[4]);
+    /* Copy result to unaligned destination address */
+    memcpy (digest, alig_dgst, SHA1_DIGEST_SIZE);
+  }
+  else
+#else  /* _MHD_PUT_32BIT_BE_UNALIGNED */
+  if (1)
+#endif /* _MHD_PUT_32BIT_BE_UNALIGNED */
+  {
+    _MHD_PUT_32BIT_BE (digest + 0 * SHA1_BYTES_IN_WORD, ctx->H[0]);
+    _MHD_PUT_32BIT_BE (digest + 1 * SHA1_BYTES_IN_WORD, ctx->H[1]);
+    _MHD_PUT_32BIT_BE (digest + 2 * SHA1_BYTES_IN_WORD, ctx->H[2]);
+    _MHD_PUT_32BIT_BE (digest + 3 * SHA1_BYTES_IN_WORD, ctx->H[3]);
+    _MHD_PUT_32BIT_BE (digest + 4 * SHA1_BYTES_IN_WORD, ctx->H[4]);
+  }
 
   /* Erase potentially sensitive data. */
   memset (ctx, 0, sizeof(struct sha1_ctx));
diff --git a/src/microhttpd/sha1.h b/src/microhttpd/sha1.h
index 800a4909..59f00217 100644
--- a/src/microhttpd/sha1.h
+++ b/src/microhttpd/sha1.h
@@ -28,17 +28,27 @@
 
 #include "mhd_options.h"
 #include <stdint.h>
-#include <stddef.h>
+#include <stddef.h> /* for size_t */
 
 /**
  *  SHA-1 digest is kept internally as 5 32-bit words.
  */
 #define _SHA1_DIGEST_LENGTH 5
 
+/**
+ * Number of bytes in single SHA-1 word
+ */
+#define SHA1_WORD_SIZE_BITS 32
+
+/**
+ * Number of bytes in single SHA-1 word
+ */
+#define SHA1_BYTES_IN_WORD (SHA1_WORD_SIZE_BITS / 8)
+
 /**
  * Size of SHA-1 digest in bytes
  */
-#define SHA1_DIGEST_SIZE (_SHA1_DIGEST_LENGTH * 4)
+#define SHA1_DIGEST_SIZE (_SHA1_DIGEST_LENGTH * SHA1_BYTES_IN_WORD)
 
 /**
  * Size of SHA-1 digest string in chars including termination NUL

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]