crypto: fix chacha aliasing and alignment issues
What changed, and why it matters
This commit fixes low-level memory handling bugs in Monero's ChaCha encryption code. The old code read and wrote 32-bit numbers by directly casting byte pointers, which can break strict-aliasing compiler rules and crash or misbehave on processors that require aligned memory access. The fix copies bytes through memory-safe helper functions instead. This is a defensive correctness fix in cryptographic code; the commit message calls it an 'aliasing and alignment' fix but does not describe a specific exploit.
Treat as a routine but important cryptographic hardening fix. Review that load_num_32/save_num_32 are inlined by the compiler and verify test vectors still pass. No emergency response is warranted based solely on this diff.
Security signals we found
strict-aliasing violation removed
unaligned memory access replaced with memcpy
warning suppression removed
cryptographic primitive (ChaCha) modified
defensive correctness fix
Evidence from the diff
The patch replaces type-punning macros U8TO32_LITTLE and U32TO8_LITTLE with memcpy-based helpers load_num_32 and save_num_32. It also removes the DISABLE_GCC_AND_CLANG_WARNING(strict-aliasing) suppression and cleans up unused headers. Strict-aliasing violations and unaligned 32-bit loads can lead to undefined behavior, including incorrect keystream generation or crashes on alignment-sensitive architectures. The change is defensive and improves portability and compiler compliance, but the diff alone does not demonstrate a practical key-recovery or plaintext-recovery attack.
Changed components
src/crypto/chacha.csrc/crypto/chacha.hInspect captured patch +14 / −10
diff --git a/src/crypto/chacha.c b/src/crypto/chacha.c
index d734e8b..eff0d65 100644
--- a/src/crypto/chacha.c
+++ b/src/crypto/chacha.c
@@ -4,15 +4,11 @@ D. J. Bernstein
Public domain.
*/
-#include <memory.h>
-#include <stdio.h>
-#ifndef _MSC_VER
-#include <sys/param.h>
-#endif
+#include <stdint.h>
+#include <string.h>
#include "chacha.h"
#include "int-util.h"
-#include "warnings.h"
/*
* The following macros are used to obtain exact-width results.
@@ -24,8 +20,8 @@ Public domain.
* The following macros load words from an array of bytes with
* different types of endianness, and vice versa.
*/
-#define U8TO32_LITTLE(p) SWAP32LE(((uint32_t*)(p))[0])
-#define U32TO8_LITTLE(p, v) (((uint32_t*)(p))[0] = SWAP32LE(v))
+#define U8TO32_LITTLE(p) load_num_32(p)
+#define U32TO8_LITTLE(p, v) save_num_32(p, v)
#define ROTATE(v,c) (rol32(v,c))
#define XOR(v,w) ((v) ^ (w))
@@ -40,7 +36,16 @@ Public domain.
static const char sigma[] = "expand 32-byte k";
-DISABLE_GCC_AND_CLANG_WARNING(strict-aliasing)
+static uint32_t load_num_32(const void* p) {
+ uint32_t v;
+ memcpy(&v, p, sizeof(v));
+ return SWAP32LE(v);
+}
+
+static void save_num_32(void* p, uint32_t v) {
+ v = SWAP32LE(v);
+ memcpy(p, &v, sizeof(v));
+}
static void chacha(unsigned rounds, const void* data, size_t length, const uint8_t* key, const uint8_t* iv, char* cipher) {
uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
diff --git a/src/crypto/chacha.h b/src/crypto/chacha.h
index 8f1edbd..6245a6d 100644
--- a/src/crypto/chacha.h
+++ b/src/crypto/chacha.h
@@ -37,7 +37,6 @@
#define CHACHA_IV_SIZE 8
#if defined(__cplusplus)
-#include <memory.h>
#include "memwipe.h"
#include "mlocker.h"
Why this scored 46/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.