13status_t hardened_memcpy(uint32_t *restrict dest,
const uint32_t *restrict src,
16 random_order_init(&order, word_len);
19 size_t expected_count = random_order_len(&order);
24 uintptr_t src_addr = (uintptr_t)src;
25 uintptr_t dest_addr = (uintptr_t)dest;
29 for (; launderw(count) < expected_count; count = launderw(count) + 1) {
35 size_t byte_idx = launderw(random_order_advance(&order)) *
sizeof(uint32_t);
42 void *src = (
void *)launderw(src_addr + byte_idx);
43 void *dest = (
void *)launderw(dest_addr + byte_idx);
46 write_32(read_32(src), dest);
54status_t hardened_memshred(uint32_t *dest,
size_t word_len) {
56 random_order_init(&order, word_len);
59 size_t expected_count = random_order_len(&order);
61 uintptr_t data_addr = (uintptr_t)dest;
63 for (; count < expected_count; count = launderw(count) + 1) {
64 size_t byte_idx = launderw(random_order_advance(&order)) *
sizeof(uint32_t);
68 void *data = (
void *)launderw(data_addr + byte_idx);
83 random_order_init(&order, word_len);
86 size_t expected_count = random_order_len(&order);
88 uintptr_t lhs_addr = (uintptr_t)lhs;
89 uintptr_t rhs_addr = (uintptr_t)rhs;
92 uint32_t ones = UINT32_MAX;
96 for (; count < expected_count; count = launderw(count) + 1) {
97 size_t byte_idx = launderw(random_order_advance(&order)) *
sizeof(uint32_t);
101 void *av = (
void *)launderw(lhs_addr + byte_idx);
102 void *bv = (
void *)launderw(rhs_addr + byte_idx);
104 uint32_t a = read_32(av);
105 uint32_t b = read_32(bv);
112 zeros = launder32(zeros) | (launder32(a) ^ b);
116 ones = launder32(ones) & (launder32(a) ^ ~b);
121 if (launder32(zeros) == 0) {
126 HARDENED_CHECK_NE(ones, UINT32_MAX);
130status_t hardened_xor(
const uint32_t *restrict x,
const uint32_t *restrict y,
131 size_t word_len, uint32_t *restrict dest) {
133 hardened_memshred(dest, word_len);
136 uint32_t rand[word_len];
137 hardened_memshred(rand, word_len);
140 uintptr_t x_addr = (uintptr_t)x;
141 uintptr_t y_addr = (uintptr_t)y;
142 uintptr_t dest_addr = (uintptr_t)dest;
143 uintptr_t rand_addr = (uintptr_t)&rand;
147 random_order_init(&order, word_len);
149 size_t expected_count = random_order_len(&order);
153 for (; launderw(count) < expected_count; count = launderw(count) + 1) {
154 size_t byte_idx = launderw(random_order_advance(&order)) *
sizeof(uint32_t);
160 uintptr_t xp = x_addr + byte_idx;
161 uintptr_t yp = y_addr + byte_idx;
162 uintptr_t destp = dest_addr + byte_idx;
163 uintptr_t randp = rand_addr + byte_idx;
166 void *xv = (
void *)launderw(xp);
167 void *yv = (
void *)launderw(yp);
168 void *destv = (
void *)launderw(destp);
169 void *randv = (
void *)launderw(randp);
172 write_32(read_32(xv) ^ read_32(randv), destv);
173 write_32(read_32(destv) ^ read_32(yv), destv);
174 write_32(read_32(destv) ^ read_32(randv), destv);
182status_t hardened_xor_in_place(uint32_t *restrict x,
const uint32_t *restrict y,
186 random_order_init(&order, word_len);
188 size_t expected_count = random_order_len(&order);
191 uintptr_t x_addr = (uintptr_t)x;
192 uintptr_t y_addr = (uintptr_t)y;
196 for (; launderw(count) < expected_count; count = launderw(count) + 1) {
197 size_t byte_idx = launderw(random_order_advance(&order)) *
sizeof(uint32_t);
203 void *xv = (
void *)launderw(x_addr + byte_idx);
204 void *yv = (
void *)launderw(y_addr + byte_idx);
207 write_32(read_32(xv) ^ read_32(yv), xv);