Skip to content

Commit 53b18b0

Browse files
committed
Add secureZero function
This is identical to `mem.set(u8, slice, 0)` except that it will never be optimized out by the compiler. Intended usage is for clearing secret data. The resulting assembly has been manually verified in --release-* modes. It would be valuable to test the 'never be optimized out' claim in tests but this is harder than initially expected due to how much Zig appears to know locally. May be doable with @intToPtr, @ptrToInt to get around known data dependencies but I could not work it out right now.
1 parent 1da93ca commit 53b18b0

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

std/mem.zig

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,24 @@ pub fn set(comptime T: type, dest: []T, value: T) void {
175175
d.* = value;
176176
}
177177

178+
pub fn secureZero(comptime T: type, s: []T) void {
179+
// NOTE: We do not use a volatile slice cast here since LLVM cannot
180+
// see that it can be replaced by a memset.
181+
const ptr = @ptrCast([*]volatile u8, s.ptr);
182+
const len = s.len * @sizeOf(T);
183+
@memset(ptr, 0, len);
184+
}
185+
186+
test "mem.secureZero" {
187+
var a = []u8{0xfe} ** 8;
188+
var b = []u8{0xfe} ** 8;
189+
190+
set(u8, a[0..], 0);
191+
secureZero(u8, b[0..]);
192+
193+
assert(eql(u8, a[0..], b[0..]));
194+
}
195+
178196
pub fn compare(comptime T: type, lhs: []const T, rhs: []const T) Compare {
179197
const n = math.min(lhs.len, rhs.len);
180198
var i: usize = 0;

0 commit comments

Comments
 (0)