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 const unsigned char *lh = (
const unsigned char *)lhs;
134 const unsigned char *rh = (
const unsigned char *)rhs;
135 for (; it < len; ++it, ++lh, ++rh) {
136 const unsigned char a = *lh;
137 const unsigned char b = *rh;
144 zeros = launder32(zeros) | (launder32((uint32_t)a) ^ b);
148 ones = launder32(ones) & (launder32((uint32_t)a) ^ ~b);
153 if (launder32(zeros) == 0) {
158 HARDENED_CHECK_NE(ones, UINT32_MAX);
162status_t hardened_xor(
const uint32_t *restrict x,
const uint32_t *restrict y,
163 size_t word_len, uint32_t *restrict dest) {
165 hardened_memshred(dest, word_len);
168 uint32_t rand[word_len];
169 hardened_memshred(rand, word_len);
172 uintptr_t x_addr = (uintptr_t)x;
173 uintptr_t y_addr = (uintptr_t)y;
174 uintptr_t dest_addr = (uintptr_t)dest;
175 uintptr_t rand_addr = (uintptr_t)&rand;
179 random_order_init(&order, word_len);
184 for (; launderw(count) < word_len; count = launderw(count) + 1) {
185 size_t byte_idx = launderw(random_order_advance(&order)) *
sizeof(uint32_t);
191 uintptr_t xp = x_addr + byte_idx;
192 uintptr_t yp = y_addr + byte_idx;
193 uintptr_t destp = dest_addr + byte_idx;
194 uintptr_t randp = rand_addr + byte_idx;
197 void *xv = (
void *)launderw(xp);
198 void *yv = (
void *)launderw(yp);
199 void *destv = (
void *)launderw(destp);
200 void *randv = (
void *)launderw(randp);
203 write_32(read_32(xv) ^ read_32(randv), destv);
204 write_32(read_32(destv) ^ read_32(yv), destv);
205 write_32(read_32(destv) ^ read_32(randv), destv);
213status_t hardened_xor_in_place(uint32_t *restrict x,
const uint32_t *restrict y,
217 random_order_init(&order, word_len);
221 uintptr_t x_addr = (uintptr_t)x;
222 uintptr_t y_addr = (uintptr_t)y;
226 for (; launderw(count) < word_len; count = launderw(count) + 1) {
227 size_t byte_idx = launderw(random_order_advance(&order)) *
sizeof(uint32_t);
233 void *xv = (
void *)launderw(x_addr + byte_idx);
234 void *yv = (
void *)launderw(y_addr + byte_idx);
237 write_32(read_32(xv) ^ read_32(yv), xv);