nisse@lysator.liu.se (Niels Möller) writes:
For now, I think I'll fix this, and add a TMP_ALIGN_DECL, TMP_ALIGN_ALLOC.
Below patch seems to work. Other options?
Regards, /Niels
diff --git a/nettle-internal.h b/nettle-internal.h index 38c8d2a8..b109e944 100644 --- a/nettle-internal.h +++ b/nettle-internal.h @@ -35,20 +35,41 @@ #ifndef NETTLE_INTERNAL_H_INCLUDED #define NETTLE_INTERNAL_H_INCLUDED
+#include <assert.h> + #include "nettle-meta.h"
+/* For definition of NETTLE_MAX_HASH_CONTEXT_SIZE. */ +#include "sha3.h" + /* Temporary allocation, for systems that don't support alloca. Note * that the allocation requests should always be reasonably small, so * that they can fit on the stack. For non-alloca systems, we use a - * fix maximum size, and abort if we ever need anything larger. */ + * fix maximum size + an assert. + * + * TMP_DECL and TMP_ALLOC allocate an array of the given type, and + * take the array size (not byte size) as argument. + * + * TMP_DECL_ALIGN and TMP_ALLOC_ALIGN are intended for context + * structs, with void * pointer, size in bytes, and alignment + * requirements. On systems without alloca, implemented as an array of + * uint64_t, to ensure alignment. Since it is used as void * argument, + * no type casts are needed. + */
#if HAVE_ALLOCA # define TMP_DECL(name, type, max) type *name # define TMP_ALLOC(name, size) (name = alloca(sizeof (*name) * (size))) +# define TMP_DECL_ALIGN(name, max) void *name +# define TMP_ALLOC_ALIGN(name, size) (name = alloca(size)) #else /* !HAVE_ALLOCA */ # define TMP_DECL(name, type, max) type name[max] # define TMP_ALLOC(name, size) \ - do { if ((size) > (sizeof(name) / sizeof(name[0]))) abort(); } while (0) + do { assert((size_t)(size) <= (sizeof(name) / sizeof(name[0]))); } while (0) +# define TMP_DECL_ALIGN(name, max) \ + uint64_t name[((max) + (sizeof(uint64_t) - 1))/ sizeof(uint64_t)] +# define TMP_ALLOC_ALIGN(name, size) \ + do { assert((size_t)(size) <= (sizeof(name))); } while (0) #endif
/* Arbitrary limits which apply to systems that don't have alloca */ diff --git a/pss-mgf1.c b/pss-mgf1.c index 67df5570..3f5e204b 100644 --- a/pss-mgf1.c +++ b/pss-mgf1.c @@ -48,12 +48,12 @@ pss_mgf1(const void *seed, const struct nettle_hash *hash, size_t length, uint8_t *mask) { TMP_DECL(h, uint8_t, NETTLE_MAX_HASH_DIGEST_SIZE); - TMP_DECL(state, uint8_t, NETTLE_MAX_HASH_CONTEXT_SIZE); + TMP_DECL_ALIGN(state, NETTLE_MAX_HASH_CONTEXT_SIZE); size_t i; uint8_t c[4];
TMP_ALLOC(h, hash->digest_size); - TMP_ALLOC(state, hash->context_size); + TMP_ALLOC_ALIGN(state, hash->context_size);
for (i = 0;; i++, mask += hash->digest_size, length -= hash->digest_size) diff --git a/pss.c b/pss.c index 88125c06..d28e7b13 100644 --- a/pss.c +++ b/pss.c @@ -67,12 +67,12 @@ pss_encode_mgf1(mpz_t m, size_t bits, const uint8_t *digest) { TMP_GMP_DECL(em, uint8_t); - TMP_DECL(state, uint8_t, NETTLE_MAX_HASH_CONTEXT_SIZE); + TMP_DECL_ALIGN(state, NETTLE_MAX_HASH_CONTEXT_SIZE); size_t key_size = (bits + 7) / 8; size_t j;
TMP_GMP_ALLOC(em, key_size); - TMP_ALLOC(state, hash->context_size); + TMP_ALLOC_ALIGN(state, hash->context_size);
if (key_size < hash->digest_size + salt_length + 2) { @@ -127,7 +127,7 @@ pss_verify_mgf1(const mpz_t m, size_t bits, { TMP_GMP_DECL(em, uint8_t); TMP_DECL(h2, uint8_t, NETTLE_MAX_HASH_DIGEST_SIZE); - TMP_DECL(state, uint8_t, NETTLE_MAX_HASH_CONTEXT_SIZE); + TMP_DECL_ALIGN(state, NETTLE_MAX_HASH_CONTEXT_SIZE); uint8_t *h, *db, *salt; size_t key_size = (bits + 7) / 8; size_t j; @@ -138,7 +138,7 @@ pss_verify_mgf1(const mpz_t m, size_t bits, TMP_GMP_ALLOC(em, key_size * 2);
TMP_ALLOC(h2, hash->digest_size); - TMP_ALLOC(state, hash->context_size); + TMP_ALLOC_ALIGN(state, hash->context_size);
if (key_size < hash->digest_size + salt_length + 2) goto cleanup;