13void 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;
35 uintptr_t decoy_addr = (uintptr_t)&decoys;
39 size_t byte_len = word_len *
sizeof(uint32_t);
40 for (; launderw(count) < expected_count; count = launderw(count) + 1) {
46 size_t byte_idx = launderw(random_order_advance(&order)) *
sizeof(uint32_t);
56 uintptr_t srcp = src_addr + byte_idx;
57 uintptr_t destp = dest_addr + byte_idx;
58 uintptr_t decoy1 = decoy_addr + (byte_idx %
sizeof(decoys));
61 ((byte_idx + (
sizeof(decoys) / 2) +
sizeof(uint32_t)) %
sizeof(decoys));
70 void *src = (
void *)launderw(
71 ct_cmovw(ct_sltuw(launderw(byte_idx), byte_len), srcp, decoy1));
72 void *dest = (
void *)launderw(
73 ct_cmovw(ct_sltuw(launderw(byte_idx), byte_len), destp, decoy2));
76 write_32(read_32(src), dest);
82void hardened_memshred(uint32_t *dest,
size_t word_len) {
84 random_order_init(&order, word_len);
87 size_t expected_count = random_order_len(&order);
89 uintptr_t data_addr = (uintptr_t)dest;
92 uintptr_t decoy_addr = (uintptr_t)&decoys;
94 size_t byte_len = word_len *
sizeof(uint32_t);
95 for (; count < expected_count; count = launderw(count) + 1) {
96 size_t byte_idx = launderw(random_order_advance(&order)) *
sizeof(uint32_t);
99 uintptr_t datap = data_addr + byte_idx;
100 uintptr_t decoy = decoy_addr + (byte_idx %
sizeof(decoys));
102 void *data = (
void *)launderw(
103 ct_cmovw(ct_sltuw(launderw(byte_idx), byte_len), datap, decoy));
116 random_order_init(&order, word_len);
119 size_t expected_count = random_order_len(&order);
121 uintptr_t lhs_addr = (uintptr_t)lhs;
122 uintptr_t rhs_addr = (uintptr_t)rhs;
127 uint32_t decoys[8] = {
128 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
129 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
131 uintptr_t decoy_addr = (uintptr_t)&decoys;
134 uint32_t ones = UINT32_MAX;
138 size_t byte_len = word_len *
sizeof(uint32_t);
139 for (; count < expected_count; count = launderw(count) + 1) {
140 size_t byte_idx = launderw(random_order_advance(&order)) *
sizeof(uint32_t);
143 uintptr_t ap = lhs_addr + byte_idx;
144 uintptr_t bp = rhs_addr + byte_idx;
145 uintptr_t decoy1 = decoy_addr + (byte_idx %
sizeof(decoys));
148 ((byte_idx + (
sizeof(decoys) / 2) +
sizeof(uint32_t)) %
sizeof(decoys));
150 void *av = (
void *)launderw(
151 ct_cmovw(ct_sltuw(launderw(byte_idx), byte_len), ap, decoy1));
152 void *bv = (
void *)launderw(
153 ct_cmovw(ct_sltuw(launderw(byte_idx), byte_len), bp, decoy2));
155 uint32_t a = read_32(av);
156 uint32_t b = read_32(bv);
163 zeros = launder32(zeros) | (launder32(a) ^ b);
167 ones = launder32(ones) & (launder32(a) ^ ~b);
172 if (launder32(zeros) == 0) {
177 HARDENED_CHECK_NE(ones, UINT32_MAX);
181void hardened_xor(uint32_t *restrict x,
const uint32_t *restrict y,
185 random_order_init(&order, word_len);
187 size_t expected_count = random_order_len(&order);
191 hardened_memshred(decoys,
ARRAYSIZE(decoys));
194 uintptr_t x_addr = (uintptr_t)x;
195 uintptr_t y_addr = (uintptr_t)y;
196 uintptr_t decoy_addr = (uintptr_t)&decoys;
200 size_t byte_len = word_len *
sizeof(uint32_t);
201 for (; launderw(count) < expected_count; count = launderw(count) + 1) {
202 size_t byte_idx = launderw(random_order_advance(&order)) *
sizeof(uint32_t);
209 uintptr_t xp = x_addr + byte_idx;
210 uintptr_t yp = y_addr + byte_idx;
211 uintptr_t decoy1 = decoy_addr + (byte_idx %
sizeof(decoys));
214 ((byte_idx + (
sizeof(decoys) / 2) +
sizeof(uint32_t)) %
sizeof(decoys));
217 void *xv = (
void *)launderw(
218 ct_cmovw(ct_sltuw(launderw(byte_idx), byte_len), xp, decoy1));
219 void *yv = (
void *)launderw(
220 ct_cmovw(ct_sltuw(launderw(byte_idx), byte_len), yp, decoy2));
223 write_32(read_32(xv) ^ read_32(yv), xv);