mirror of
https://github.com/monero-project/monero.git
synced 2026-07-28 14:47:15 -07:00
crypto: avoid unaligned word accesses
This commit is contained in:
@@ -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));
|
||||||
|
|||||||
@@ -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
@@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user