13status_t hardened_memcpy(uint32_t *restrict dest,
const uint32_t *restrict src,
16 random_order_init(&order, word_len);
23 uintptr_t src_addr = (uintptr_t)src;
24 uintptr_t dest_addr = (uintptr_t)dest;
28 for (; launderw(count) < word_len; count = launderw(count) + 1) {
34 size_t byte_idx = launderw(random_order_advance(&order)) *
sizeof(uint32_t);
41 void *src = (
void *)launderw(src_addr + byte_idx);
42 void *dest = (
void *)launderw(dest_addr + byte_idx);
45 write_32(read_32(src), dest);
53status_t hardened_memshred(uint32_t *dest,
size_t word_len) {
55 random_order_init(&order, word_len);
59 uintptr_t data_addr = (uintptr_t)dest;
61 for (; count < word_len; count = launderw(count) + 1) {
62 size_t byte_idx = launderw(random_order_advance(&order)) *
sizeof(uint32_t);
66 void *data = (
void *)launderw(data_addr + byte_idx);
81 random_order_init(&order, word_len);
85 uintptr_t lhs_addr = (uintptr_t)lhs;
86 uintptr_t rhs_addr = (uintptr_t)rhs;
89 uint32_t ones = UINT32_MAX;
93 for (; count < word_len; count = launderw(count) + 1) {
94 size_t byte_idx = launderw(random_order_advance(&order)) *
sizeof(uint32_t);
98 void *av = (
void *)launderw(lhs_addr + byte_idx);
99 void *bv = (
void *)launderw(rhs_addr + byte_idx);
101 uint32_t a = read_32(av);
102 uint32_t b = read_32(bv);
109 zeros = launder32(zeros) | (launder32(a) ^ b);
113 ones = launder32(ones) & (launder32(a) ^ ~b);
118 if (launder32(zeros) == 0) {
123 HARDENED_CHECK_NE(ones, UINT32_MAX);
130 uint32_t ones = UINT32_MAX;
133 random_order_init(&order, len);
137 uintptr_t lhs_addr = (uintptr_t)lhs;
138 uintptr_t rhs_addr = (uintptr_t)rhs;
140 for (; launderw(count) < len; count = launderw(count) + 1) {
141 size_t byte_idx = launderw(random_order_advance(&order));
144 uint8_t *a = (uint8_t *)launderw(lhs_addr + byte_idx);
145 uint8_t *b = (uint8_t *)launderw(rhs_addr + byte_idx);
152 zeros = launder32(zeros) | (launder32((uint32_t)*a) ^ *b);
156 ones = launder32(ones) & (launder32((uint32_t)*a) ^ ~*b);
161 if (launder32(zeros) == 0) {
166 HARDENED_CHECK_NE(ones, UINT32_MAX);
170status_t hardened_xor(
const uint32_t *restrict x,
const uint32_t *restrict y,
171 size_t word_len, uint32_t *restrict dest) {
173 hardened_memshred(dest, word_len);
176 uint32_t rand[word_len];
177 hardened_memshred(rand, word_len);
180 uintptr_t x_addr = (uintptr_t)x;
181 uintptr_t y_addr = (uintptr_t)y;
182 uintptr_t dest_addr = (uintptr_t)dest;
183 uintptr_t rand_addr = (uintptr_t)&rand;
187 random_order_init(&order, word_len);
192 for (; launderw(count) < word_len; count = launderw(count) + 1) {
193 size_t byte_idx = launderw(random_order_advance(&order)) *
sizeof(uint32_t);
199 uintptr_t xp = x_addr + byte_idx;
200 uintptr_t yp = y_addr + byte_idx;
201 uintptr_t destp = dest_addr + byte_idx;
202 uintptr_t randp = rand_addr + byte_idx;
205 void *xv = (
void *)launderw(xp);
206 void *yv = (
void *)launderw(yp);
207 void *destv = (
void *)launderw(destp);
208 void *randv = (
void *)launderw(randp);
211 write_32(read_32(xv) ^ read_32(randv), destv);
212 write_32(read_32(destv) ^ read_32(yv), destv);
213 write_32(read_32(destv) ^ read_32(randv), destv);
221status_t hardened_xor_in_place(uint32_t *restrict x,
const uint32_t *restrict y,
225 random_order_init(&order, word_len);
229 uintptr_t x_addr = (uintptr_t)x;
230 uintptr_t y_addr = (uintptr_t)y;
234 for (; launderw(count) < word_len; count = launderw(count) + 1) {
235 size_t byte_idx = launderw(random_order_advance(&order)) *
sizeof(uint32_t);
241 void *xv = (
void *)launderw(x_addr + byte_idx);
242 void *yv = (
void *)launderw(y_addr + byte_idx);
245 write_32(read_32(xv) ^ read_32(yv), xv);
253status_t randomized_bytecopy(
void *restrict dest,
const void *restrict src,
256 random_order_init(&order, byte_len);
260 uintptr_t src_addr = (uintptr_t)src;
261 uintptr_t dest_addr = (uintptr_t)dest;
263 for (; launderw(count) < byte_len; count = launderw(count) + 1) {
264 size_t byte_idx = launderw(random_order_advance(&order));
267 uint8_t *src_byte_idx = (uint8_t *)launderw(src_addr + byte_idx);
268 uint8_t *dest_byte_idx = (uint8_t *)launderw(dest_addr + byte_idx);
270 *(dest_byte_idx) = *(src_byte_idx);
278status_t randomized_bytexor_in_place(
void *restrict x,
const void *restrict y,
281 random_order_init(&order, byte_len);
285 uintptr_t x_addr = (uintptr_t)x;
286 uintptr_t y_addr = (uintptr_t)y;
288 for (; launderw(count) < byte_len; count = launderw(count) + 1) {
289 size_t byte_idx = launderw(random_order_advance(&order));
293 uint8_t *x_byte_idx = (uint8_t *)launderw(x_addr + byte_idx);
294 uint8_t *y_byte_idx = (uint8_t *)launderw(y_addr + byte_idx);
296 *(x_byte_idx) = *(x_byte_idx) ^ *(y_byte_idx);