use a consistent style for fixed-size int types
The stdint.h types don't cover 128-bit integers and the underscore makes them ill suited to usage in function suffixes. Instead, use the common naming style in the Linux kernel and elsewhere including the ChaCha8 implementation included here.pull/50/head
parent
92a33182fb
commit
dcd969ae04
5
chacha.h
5
chacha.h
|
@ -1,14 +1,11 @@
|
||||||
#ifndef CHACHA_H
|
#ifndef CHACHA_H
|
||||||
#define CHACHA_H
|
#define CHACHA_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include "util.h"
|
||||||
|
|
||||||
#define CHACHA_KEY_SIZE 32
|
#define CHACHA_KEY_SIZE 32
|
||||||
#define CHACHA_IV_SIZE 8
|
#define CHACHA_IV_SIZE 8
|
||||||
|
|
||||||
typedef uint8_t u8;
|
|
||||||
typedef uint32_t u32;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u32 input[16];
|
u32 input[16];
|
||||||
} chacha_ctx;
|
} chacha_ctx;
|
||||||
|
|
29
malloc.c
29
malloc.c
|
@ -2,7 +2,6 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdatomic.h>
|
#include <stdatomic.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -23,8 +22,8 @@ static_assert(sizeof(void *) == 8, "64-bit only");
|
||||||
|
|
||||||
static_assert(!WRITE_AFTER_FREE_CHECK || ZERO_ON_FREE, "WRITE_AFTER_FREE_CHECK depends on ZERO_ON_FREE");
|
static_assert(!WRITE_AFTER_FREE_CHECK || ZERO_ON_FREE, "WRITE_AFTER_FREE_CHECK depends on ZERO_ON_FREE");
|
||||||
|
|
||||||
// either sizeof(uint64_t) or 0
|
// either sizeof(u64) or 0
|
||||||
static const size_t canary_size = SLAB_CANARY ? sizeof(uint64_t) : 0;
|
static const size_t canary_size = SLAB_CANARY ? sizeof(u64) : 0;
|
||||||
|
|
||||||
#define CACHELINE_SIZE 64
|
#define CACHELINE_SIZE 64
|
||||||
|
|
||||||
|
@ -41,16 +40,16 @@ static union {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct slab_metadata {
|
struct slab_metadata {
|
||||||
uint64_t bitmap;
|
u64 bitmap;
|
||||||
struct slab_metadata *next;
|
struct slab_metadata *next;
|
||||||
struct slab_metadata *prev;
|
struct slab_metadata *prev;
|
||||||
uint64_t canary_value;
|
u64 canary_value;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const size_t min_align = 16;
|
static const size_t min_align = 16;
|
||||||
static const size_t max_slab_size_class = 16384;
|
static const size_t max_slab_size_class = 16384;
|
||||||
|
|
||||||
static const uint16_t size_classes[] = {
|
static const u16 size_classes[] = {
|
||||||
/* 0 */ 0,
|
/* 0 */ 0,
|
||||||
/* 16 */ 16, 32, 48, 64, 80, 96, 112, 128,
|
/* 16 */ 16, 32, 48, 64, 80, 96, 112, 128,
|
||||||
/* 32 */ 160, 192, 224, 256,
|
/* 32 */ 160, 192, 224, 256,
|
||||||
|
@ -62,7 +61,7 @@ static const uint16_t size_classes[] = {
|
||||||
/* 2048 */ 10240, 12288, 14336, 16384
|
/* 2048 */ 10240, 12288, 14336, 16384
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint16_t size_class_slots[] = {
|
static const u16 size_class_slots[] = {
|
||||||
/* 0 */ 256,
|
/* 0 */ 256,
|
||||||
/* 16 */ 256, 128, 85, 64, 51, 42, 36, 64,
|
/* 16 */ 256, 128, 85, 64, 51, 42, 36, 64,
|
||||||
/* 32 */ 51, 64, 54, 64,
|
/* 32 */ 51, 64, 54, 64,
|
||||||
|
@ -208,7 +207,7 @@ static bool get_slot(struct slab_metadata *metadata, size_t index) {
|
||||||
return (metadata->bitmap >> index) & 1UL;
|
return (metadata->bitmap >> index) & 1UL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t get_mask(size_t slots) {
|
static u64 get_mask(size_t slots) {
|
||||||
return slots < 64 ? ~0UL << slots : 0;
|
return slots < 64 ? ~0UL << slots : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,14 +216,14 @@ static size_t get_free_slot(struct random_state *rng, size_t slots, struct slab_
|
||||||
slots = 64;
|
slots = 64;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t masked = metadata->bitmap | get_mask(slots);
|
u64 masked = metadata->bitmap | get_mask(slots);
|
||||||
if (masked == ~0UL) {
|
if (masked == ~0UL) {
|
||||||
fatal_error("no zero bits");
|
fatal_error("no zero bits");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SLOT_RANDOMIZE) {
|
if (SLOT_RANDOMIZE) {
|
||||||
// randomize start location for linear search (uniform random choice is too slow)
|
// randomize start location for linear search (uniform random choice is too slow)
|
||||||
uint64_t random_split = ~(~0UL << get_random_u16_uniform(rng, slots));
|
u64 random_split = ~(~0UL << get_random_u16_uniform(rng, slots));
|
||||||
|
|
||||||
size_t slot = ffzl(masked | random_split);
|
size_t slot = ffzl(masked | random_split);
|
||||||
if (slot) {
|
if (slot) {
|
||||||
|
@ -240,7 +239,7 @@ static bool has_free_slots(size_t slots, struct slab_metadata *metadata) {
|
||||||
slots = 64;
|
slots = 64;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t masked = metadata->bitmap | get_mask(slots);
|
u64 masked = metadata->bitmap | get_mask(slots);
|
||||||
return masked != ~0UL;
|
return masked != ~0UL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,14 +266,14 @@ static void write_after_free_check(char *p, size_t size) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < size; i += sizeof(uint64_t)) {
|
for (size_t i = 0; i < size; i += sizeof(u64)) {
|
||||||
if (*(uint64_t *)(p + i)) {
|
if (*(u64 *)(p + i)) {
|
||||||
fatal_error("detected write after free");
|
fatal_error("detected write after free");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const uint64_t canary_mask = __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ?
|
static const u64 canary_mask = __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ?
|
||||||
0xffffffffffffff00UL :
|
0xffffffffffffff00UL :
|
||||||
0x00ffffffffffffffUL;
|
0x00ffffffffffffffUL;
|
||||||
|
|
||||||
|
@ -441,7 +440,7 @@ static inline void deallocate_small(void *p, size_t *expected_size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canary_size) {
|
if (canary_size) {
|
||||||
uint64_t canary_value;
|
u64 canary_value;
|
||||||
memcpy(&canary_value, (char *)p + size - canary_size, canary_size);
|
memcpy(&canary_value, (char *)p + size - canary_size, canary_size);
|
||||||
if (unlikely(canary_value != metadata->canary_value)) {
|
if (unlikely(canary_value != metadata->canary_value)) {
|
||||||
fatal_error("canary corrupted");
|
fatal_error("canary corrupted");
|
||||||
|
|
1
pages.c
1
pages.c
|
@ -1,5 +1,4 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "pages.h"
|
#include "pages.h"
|
||||||
|
|
32
random.c
32
random.c
|
@ -36,7 +36,7 @@ static void get_random_seed(void *buf, size_t size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void random_state_init(struct random_state *state) {
|
void random_state_init(struct random_state *state) {
|
||||||
uint8_t rnd[CHACHA_KEY_SIZE + CHACHA_IV_SIZE];
|
u8 rnd[CHACHA_KEY_SIZE + CHACHA_IV_SIZE];
|
||||||
get_random_seed(rnd, sizeof(rnd));
|
get_random_seed(rnd, sizeof(rnd));
|
||||||
chacha_keysetup(&state->ctx, rnd);
|
chacha_keysetup(&state->ctx, rnd);
|
||||||
chacha_ivsetup(&state->ctx, rnd + CHACHA_KEY_SIZE);
|
chacha_ivsetup(&state->ctx, rnd + CHACHA_KEY_SIZE);
|
||||||
|
@ -55,8 +55,8 @@ static void refill(struct random_state *state) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t get_random_u16(struct random_state *state) {
|
u16 get_random_u16(struct random_state *state) {
|
||||||
uint16_t value;
|
u16 value;
|
||||||
size_t remaining = RANDOM_CACHE_SIZE - state->index;
|
size_t remaining = RANDOM_CACHE_SIZE - state->index;
|
||||||
if (remaining < sizeof(value)) {
|
if (remaining < sizeof(value)) {
|
||||||
refill(state);
|
refill(state);
|
||||||
|
@ -67,23 +67,23 @@ uint16_t get_random_u16(struct random_state *state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// See Fast Random Integer Generation in an Interval by Daniel Lemire
|
// See Fast Random Integer Generation in an Interval by Daniel Lemire
|
||||||
uint16_t get_random_u16_uniform(struct random_state *state, uint16_t bound) {
|
u16 get_random_u16_uniform(struct random_state *state, u16 bound) {
|
||||||
uint32_t random = get_random_u16(state);
|
u32 random = get_random_u16(state);
|
||||||
uint32_t multiresult = random * bound;
|
u32 multiresult = random * bound;
|
||||||
uint16_t leftover = multiresult;
|
u16 leftover = multiresult;
|
||||||
if (leftover < bound) {
|
if (leftover < bound) {
|
||||||
uint16_t threshold = -bound % bound;
|
u16 threshold = -bound % bound;
|
||||||
while (leftover < threshold) {
|
while (leftover < threshold) {
|
||||||
random = get_random_u16(state);
|
random = get_random_u16(state);
|
||||||
multiresult = random * bound;
|
multiresult = random * bound;
|
||||||
leftover = (uint16_t)multiresult;
|
leftover = (u16)multiresult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return multiresult >> 16;
|
return multiresult >> 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t get_random_u64(struct random_state *state) {
|
u64 get_random_u64(struct random_state *state) {
|
||||||
uint64_t value;
|
u64 value;
|
||||||
size_t remaining = RANDOM_CACHE_SIZE - state->index;
|
size_t remaining = RANDOM_CACHE_SIZE - state->index;
|
||||||
if (remaining < sizeof(value)) {
|
if (remaining < sizeof(value)) {
|
||||||
refill(state);
|
refill(state);
|
||||||
|
@ -94,12 +94,12 @@ uint64_t get_random_u64(struct random_state *state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// See Fast Random Integer Generation in an Interval by Daniel Lemire
|
// See Fast Random Integer Generation in an Interval by Daniel Lemire
|
||||||
uint64_t get_random_u64_uniform(struct random_state *state, uint64_t bound) {
|
u64 get_random_u64_uniform(struct random_state *state, u64 bound) {
|
||||||
unsigned __int128 random = get_random_u64(state);
|
u128 random = get_random_u64(state);
|
||||||
unsigned __int128 multiresult = random * bound;
|
u128 multiresult = random * bound;
|
||||||
uint64_t leftover = multiresult;
|
u64 leftover = multiresult;
|
||||||
if (leftover < bound) {
|
if (leftover < bound) {
|
||||||
uint64_t threshold = -bound % bound;
|
u64 threshold = -bound % bound;
|
||||||
while (leftover < threshold) {
|
while (leftover < threshold) {
|
||||||
random = get_random_u64(state);
|
random = get_random_u64(state);
|
||||||
multiresult = random * bound;
|
multiresult = random * bound;
|
||||||
|
|
13
random.h
13
random.h
|
@ -1,9 +1,8 @@
|
||||||
#ifndef RANDOM_H
|
#ifndef RANDOM_H
|
||||||
#define RANDOM_H
|
#define RANDOM_H
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "chacha.h"
|
#include "chacha.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
#define RANDOM_CACHE_SIZE 256ULL
|
#define RANDOM_CACHE_SIZE 256ULL
|
||||||
#define RANDOM_RESEED_SIZE 256ULL * 1024
|
#define RANDOM_RESEED_SIZE 256ULL * 1024
|
||||||
|
@ -12,13 +11,13 @@ struct random_state {
|
||||||
size_t index;
|
size_t index;
|
||||||
size_t reseed;
|
size_t reseed;
|
||||||
chacha_ctx ctx;
|
chacha_ctx ctx;
|
||||||
uint8_t cache[RANDOM_CACHE_SIZE];
|
u8 cache[RANDOM_CACHE_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
void random_state_init(struct random_state *state);
|
void random_state_init(struct random_state *state);
|
||||||
uint16_t get_random_u16(struct random_state *state);
|
u16 get_random_u16(struct random_state *state);
|
||||||
uint16_t get_random_u16_uniform(struct random_state *state, uint16_t bound);
|
u16 get_random_u16_uniform(struct random_state *state, u16 bound);
|
||||||
uint64_t get_random_u64(struct random_state *state);
|
u64 get_random_u64(struct random_state *state);
|
||||||
uint64_t get_random_u64_uniform(struct random_state *state, uint64_t bound);
|
u64 get_random_u64_uniform(struct random_state *state, u64 bound);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
7
util.h
7
util.h
|
@ -1,6 +1,7 @@
|
||||||
#ifndef UTIL_H
|
#ifndef UTIL_H
|
||||||
#define UTIL_H
|
#define UTIL_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdnoreturn.h>
|
#include <stdnoreturn.h>
|
||||||
|
|
||||||
#define likely(x) __builtin_expect(!!(x), 1)
|
#define likely(x) __builtin_expect(!!(x), 1)
|
||||||
|
@ -19,4 +20,10 @@ static inline int ffzl(long x) {
|
||||||
|
|
||||||
COLD noreturn void fatal_error(const char *s);
|
COLD noreturn void fatal_error(const char *s);
|
||||||
|
|
||||||
|
typedef uint8_t u8;
|
||||||
|
typedef uint16_t u16;
|
||||||
|
typedef uint32_t u32;
|
||||||
|
typedef uint64_t u64;
|
||||||
|
typedef unsigned __int128 u128;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue