DoxigAlpha

Function parameters

Parameters

#
ptr:anytype
action:enum { classify, declassify }

Compares two arrays in constant time (for a given length) and returns whether they are equal.

Functions

#
eql
Compares two arrays in constant time (for a given length) and returns whether they are equal.
compare
Compare two integers serialized as arrays of the same size, in constant time.
add
Add two integers serialized as arrays of the same size, in constant time.
sub
Subtract two integers serialized as arrays of the same size, in constant time.
classify
Mark a value as sensitive or secret, helping to detect potential side-channel vulnerabilities.
declassify
Mark a value as non-sensitive or public, indicating it's safe from side-channel attacks.

Source

Implementation

#
fn markSecret(ptr: anytype, comptime action: enum { classify, declassify }) void {
    const t = @typeInfo(@TypeOf(ptr));
    if (t != .pointer) @compileError("Pointer expected - Found: " ++ @typeName(@TypeOf(ptr)));
    const p = t.pointer;
    if (p.is_allowzero) @compileError("A nullable pointer is always assumed to leak information via side channels");
    const child = @typeInfo(p.child);

    switch (child) {
        .void, .null, .comptime_int, .comptime_float => return,
        .pointer => {
            if (child.pointer.size == .Slice) {
                @compileError("Found pointer to pointer. If the intent was to pass a slice, maybe remove the leading & in the function call");
            }
            @compileError("A pointer value is always assumed leak information via side channels");
        },
        else => {
            const mem8: *const [@sizeOf(@TypeOf(ptr.*))]u8 = @ptrCast(@constCast(ptr));
            if (action == .classify) {
                std.valgrind.memcheck.makeMemUndefined(mem8);
            } else {
                std.valgrind.memcheck.makeMemDefined(mem8);
            }
        },
    }
}