]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
New macro _NETTLE_ALIGN16, for 16-byte alignment.
authorNiels Möller <nisse@lysator.liu.se>
Sun, 22 Jun 2025 15:09:41 +0000 (17:09 +0200)
committerNiels Möller <nisse@lysator.liu.se>
Sun, 22 Jun 2025 15:09:41 +0000 (17:09 +0200)
Depends on stdalign.h. Used for nettle_block16, and for aes and umac
key arrays.

ChangeLog
aes.h
ctr16.c
nettle-types.h
umac.h

index 6e7b99acbdd1e9b562f08631079e2db2b5f49d1f..b0af0d0cfb7f23fbf22c01dac9fbf0156ae39b8f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2025-06-22  Niels Möller  <nisse@lysator.liu.se>
+
+       * nettle-types.h (_NETTLE_ALIGN16): New macro, to require 16-byte
+       alignment. Enabled only on platforms where uint64_t needs 8-byte
+       alignment. Intended to improve performance for SIMD load and
+       store, which on some platforms may be faster with proper
+       alignment. Depends on stdalign.h, defined in C11.
+       (union nettle_block16): Use _NETTLE_ALIGN16.
+
+       * ctr16.c (_nettle_ctr_crypt16): Update alignedness check to use
+       alignof(union nettle_block16).
+
+       * aes.h (struct aes128_ctx): Use _NETTLE_ALIGN16 for the array of subkeys.
+       (struct aes192_ctx): Likewise.
+       (struct aes256_ctx): Likewise.
+
+       * umac.h (_UMAC_STATE): Use _NETTLE_ALIGN16 for the l1_key array.
+
 2025-05-13  Niels Möller  <nisse@lysator.liu.se>
 
        Reduce size of sha3 context size to 216 bytes.
diff --git a/aes.h b/aes.h
index f3d60ea724fbb698031737326783c7b12941607e..de9f94b132f19acd1ebfd4646d07d8637d53c433 100644 (file)
--- a/aes.h
+++ b/aes.h
@@ -68,7 +68,7 @@ extern "C" {
 
 struct aes128_ctx
 {
-  uint32_t keys[4 * (_AES128_ROUNDS + 1)];
+  _NETTLE_ALIGN16 uint32_t keys[4 * (_AES128_ROUNDS + 1)];
 };
 
 void
@@ -89,7 +89,7 @@ aes128_decrypt(const struct aes128_ctx *ctx,
 
 struct aes192_ctx
 {
-  uint32_t keys[4 * (_AES192_ROUNDS + 1)];
+  _NETTLE_ALIGN16 uint32_t keys[4 * (_AES192_ROUNDS + 1)];
 };
 
 void
@@ -110,7 +110,7 @@ aes192_decrypt(const struct aes192_ctx *ctx,
 
 struct aes256_ctx
 {
-  uint32_t keys[4 * (_AES256_ROUNDS + 1)];
+  _NETTLE_ALIGN16 uint32_t keys[4 * (_AES256_ROUNDS + 1)];
 };
 
 void
diff --git a/ctr16.c b/ctr16.c
index d744d2a97199455a59d4e4a8ea6130a05309341e..341fac99ddd4a11a815a460e2339fe7a00b5450b 100644 (file)
--- a/ctr16.c
+++ b/ctr16.c
@@ -52,7 +52,7 @@ _nettle_ctr_crypt16(const void *ctx, nettle_cipher_func *f,
                    size_t length, uint8_t *dst,
                    const uint8_t *src)
 {
-  if (dst != src && !((uintptr_t) dst % sizeof(uint64_t)))
+  if (dst != src && !((uintptr_t) dst % alignof(union nettle_block16)))
     {
       size_t blocks = length / 16u;
       size_t done;
index 04febc7c65bf58f0fd2a85d31f9642693719181a..3069c377182920ad2ec8b746a8df0614e7f3833b 100644 (file)
@@ -34,6 +34,7 @@
 
 /* For size_t */
 #include <stddef.h>
+#include <stdalign.h>
 #include <stdint.h>
 
 /* Attributes we want to use in installed header files, and hence
 extern "C" {
 #endif
 
+/* On 64-bit platforms where uint64_t requires 8 byte alignment, use
+   twice the alignment. To work for both C and C++, needs to be placed
+   before the type, see example for nettle_block16 below. */
+#define _NETTLE_ALIGN16 alignas(alignof(uint64_t) == 8 ? 16 : 0)
+
 /* An aligned 16-byte block. */
 union nettle_block16
 {
   uint8_t b[16];
-  uint64_t u64[2];
+  _NETTLE_ALIGN16 uint64_t u64[2];
 };
 
 union nettle_block8
diff --git a/umac.h b/umac.h
index 5efb4338dd005c4795035ceb931833c2f0703ad1..88544e61e6eaa20f86e08e38c1eb94524605df1d 100644 (file)
--- a/umac.h
+++ b/umac.h
@@ -70,7 +70,7 @@ extern "C" {
 
 /* Subkeys and state for UMAC with tag size 32*n bits. */
 #define _UMAC_STATE(n)                                 \
-  uint32_t l1_key[UMAC_BLOCK_SIZE/4 + 4*((n)-1)];      \
+  _NETTLE_ALIGN16 uint32_t l1_key[UMAC_BLOCK_SIZE/4 + 4*((n)-1)];      \
   /* Keys in 32-bit pieces, high first */              \
   uint32_t l2_key[6*(n)];                              \
   uint64_t l3_key1[8*(n)];                             \