Merge pull request #10804

4b042bb crypto: avoid unaligned word accesses (Samy)

ACKs: selsta, jeffro256
This commit is contained in:
tobtoht
2026-07-22 07:28:42 +00:00
4 changed files with 24 additions and 28 deletions
+1 -1
View File
@@ -102,7 +102,7 @@ int v4_generate_JIT_code(const struct V4_Instruction* code, v4_random_math_JIT_f
APPEND_CODE(p1, p2 - p1); APPEND_CODE(p1, p2 - p1);
if (inst.opcode == ADD) if (inst.opcode == ADD)
*(uint32_t*)(JIT_code - 4) = inst.C; memcpy(JIT_code - 4, &inst.C, sizeof(inst.C));
} }
APPEND_CODE(epilogue, sizeof(epilogue)); APPEND_CODE(epilogue, sizeof(epilogue));
+2 -2
View File
@@ -39,6 +39,7 @@
#include <assert.h> #include <assert.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdalign.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
@@ -65,13 +66,12 @@ static inline void place_length(uint8_t *buffer, size_t bufsize, size_t length)
} }
POP_WARNINGS POP_WARNINGS
#pragma pack(push, 1)
union hash_state { union hash_state {
uint8_t b[200]; uint8_t b[200];
uint64_t w[25]; uint64_t w[25];
}; };
#pragma pack(pop)
static_assert(sizeof(union hash_state) == 200, "Invalid structure size"); static_assert(sizeof(union hash_state) == 200, "Invalid structure size");
static_assert(alignof(union hash_state) == alignof(uint64_t), "Invalid structure alignment");
void hash_permutation(union hash_state *state); void hash_permutation(union hash_state *state);
void hash_process(union hash_state *state, const uint8_t *buf, size_t count); void hash_process(union hash_state *state, const uint8_t *buf, size_t count);
+16 -17
View File
@@ -119,50 +119,49 @@ typedef uint64_t state_t[25];
void keccak(const uint8_t *in, size_t inlen, uint8_t *md, int mdlen) void keccak(const uint8_t *in, size_t inlen, uint8_t *md, int mdlen)
{ {
state_t st; state_t st;
uint8_t temp[144]; uint64_t temp[18];
size_t i, rsiz, rsizw; size_t i, rsiz, rsizw;
static_assert(HASH_DATA_AREA <= sizeof(temp), "Bad keccak preconditions"); static_assert(HASH_DATA_AREA + sizeof(uint64_t) == sizeof(temp), "Bad keccak preconditions");
if (mdlen <= 0 || (mdlen >= 100 && sizeof(st) != (size_t)mdlen)) if (mdlen <= 0 || (mdlen >= 100 && sizeof(st) != (size_t)mdlen) || ((size_t)mdlen % sizeof(uint64_t)) != 0)
{ {
local_abort("Bad keccak use"); local_abort("Bad keccak use");
} }
rsiz = sizeof(state_t) == mdlen ? HASH_DATA_AREA : 200 - 2 * mdlen; rsiz = sizeof(state_t) == mdlen ? HASH_DATA_AREA : 200 - 2 * mdlen;
rsizw = rsiz / 8; rsizw = rsiz / 8;
if (rsiz == 0 || rsiz > sizeof(temp) || rsizw * sizeof(uint64_t) > sizeof(temp))
{
local_abort("Bad keccak use");
}
memset(st, 0, sizeof(st)); memset(st, 0, sizeof(st));
for ( ; inlen >= rsiz; inlen -= rsiz, in += rsiz) { for ( ; inlen >= rsiz; inlen -= rsiz, in += rsiz) {
memcpy(temp, in, rsiz);
for (i = 0; i < rsizw; i++) { for (i = 0; i < rsizw; i++) {
uint64_t ina; st[i] ^= SWAP64LE(temp[i]);
memcpy(&ina, in + i * 8, 8);
st[i] ^= swap64le(ina);
} }
keccakf(st, KECCAK_ROUNDS); keccakf(st, KECCAK_ROUNDS);
} }
// last block and padding // last block and padding
if (inlen + 1 >= sizeof(temp) || inlen > rsiz || rsiz - inlen + inlen + 1 >= sizeof(temp) || rsiz == 0 || rsiz - 1 >= sizeof(temp) || rsizw * 8 > sizeof(temp)) memset(temp, 0, sizeof(temp));
if (inlen >= rsiz)
{ {
local_abort("Bad keccak use"); local_abort("Bad keccak use");
} }
if (inlen > 0) if (inlen > 0)
memcpy(temp, in, inlen); memcpy(temp, in, inlen);
temp[inlen++] = 1; ((uint8_t *) temp)[inlen] = 1;
memset(temp + inlen, 0, rsiz - inlen); ((uint8_t *) temp)[rsiz - 1] |= 0x80;
temp[rsiz - 1] |= 0x80;
for (i = 0; i < rsizw; i++) for (i = 0; i < rsizw; i++) {
st[i] ^= swap64le(((uint64_t *) temp)[i]); st[i] ^= SWAP64LE(temp[i]);
}
keccakf(st, KECCAK_ROUNDS); keccakf(st, KECCAK_ROUNDS);
if (((size_t)mdlen % sizeof(uint64_t)) != 0)
{
local_abort("Bad keccak use");
}
memcpy_swap64le(md, st, mdlen/sizeof(uint64_t)); memcpy_swap64le(md, st, mdlen/sizeof(uint64_t));
} }
+5 -8
View File
@@ -155,11 +155,14 @@ static inline int force_software_aes(void)
} while(0) } while(0)
#define VARIANT1_INIT64() \ #define VARIANT1_INIT64() \
uint64_t tweak1_2 = 0; \
if (variant == 1) \ if (variant == 1) \
{ \ { \
uint64_t nonce; \
VARIANT1_CHECK(); \ VARIANT1_CHECK(); \
} \ memcpy(&nonce, NONCE_POINTER, sizeof(nonce)); \
const uint64_t tweak1_2 = (variant == 1) ? (state.hs.w[24] ^ (*((const uint64_t*)NONCE_POINTER))) : 0 tweak1_2 = state.hs.w[24] ^ nonce; \
}
#define VARIANT2_INIT64() \ #define VARIANT2_INIT64() \
uint64_t division_result = 0; \ uint64_t division_result = 0; \
@@ -469,7 +472,6 @@ static inline int force_software_aes(void)
_b1 = _b; \ _b1 = _b; \
_b = _c; \ _b = _c; \
#pragma pack(push, 1)
union cn_slow_hash_state union cn_slow_hash_state
{ {
union hash_state hs; union hash_state hs;
@@ -479,7 +481,6 @@ union cn_slow_hash_state
uint8_t init[INIT_SIZE_BYTE]; uint8_t init[INIT_SIZE_BYTE];
}; };
}; };
#pragma pack(pop)
THREADV uint8_t *hp_state = NULL; THREADV uint8_t *hp_state = NULL;
THREADV int hp_allocated = 0; THREADV int hp_allocated = 0;
@@ -1086,7 +1087,6 @@ STATIC INLINE void xor64(uint64_t *a, const uint64_t b)
*a ^= b; *a ^= b;
} }
#pragma pack(push, 1)
union cn_slow_hash_state union cn_slow_hash_state
{ {
union hash_state hs; union hash_state hs;
@@ -1096,7 +1096,6 @@ union cn_slow_hash_state
uint8_t init[INIT_SIZE_BYTE]; uint8_t init[INIT_SIZE_BYTE];
}; };
}; };
#pragma pack(pop)
#if defined(__aarch64__) && defined(__ARM_FEATURE_CRYPTO) #if defined(__aarch64__) && defined(__ARM_FEATURE_CRYPTO)
@@ -1767,7 +1766,6 @@ static void xor64(uint8_t* left, const uint8_t* right)
} }
} }
#pragma pack(push, 1)
union cn_slow_hash_state { union cn_slow_hash_state {
union hash_state hs; union hash_state hs;
struct { struct {
@@ -1775,7 +1773,6 @@ union cn_slow_hash_state {
uint8_t init[INIT_SIZE_BYTE]; uint8_t init[INIT_SIZE_BYTE];
}; };
}; };
#pragma pack(pop)
void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed, uint64_t height) { void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed, uint64_t height) {
#ifndef FORCE_USE_HEAP #ifndef FORCE_USE_HEAP