Function classify [src]
Mark a value as sensitive or secret, helping to detect potential side-channel vulnerabilities.
When Valgrind is enabled, this function allows for the detection of conditional jumps or lookups
that depend on secrets or secret-derived data. Violations are reported by Valgrind as operations
relying on uninitialized values.
If Valgrind is disabled, it has no effect.
Use this function to verify that cryptographic operations perform constant-time arithmetic on sensitive data,
ensuring the confidentiality of secrets and preventing information leakage through side channels.
Prototype
pub fn classify(ptr: anytype) void
Example
test classify {
const random = std.crypto.random;
const expect = std.testing.expect;
var secret: [32]u8 = undefined;
random.bytes(&secret);
// Input of the hash function is marked as secret
classify(&secret);
var out: [32]u8 = undefined;
std.crypto.hash.sha3.TurboShake128(null).hash(&secret, &out, .{});
// Output of the hash function is derived from secret data, so
// it will automatically be considered secret as well. But it can be
// declassified; the input itself will still be considered secret.
declassify(&out);
// Comparing public data in non-constant time is acceptable.
try expect(!std.mem.eql(u8, &out, &[_]u8{0} ** out.len));
// Comparing secret data must be done in constant time. The result
// is going to be considered as secret as well.
var res = std.crypto.utils.timingSafeEql([32]u8, out, secret);
// If we want to make a conditional jump based on a secret,
// it has to be declassified.
declassify(&res);
try expect(!res);
// Once a secret has been declassified, a comparison in
// non-constant time is fine.
declassify(&secret);
try expect(!std.mem.eql(u8, &out, &secret));
}
Source
pub fn classify(ptr: anytype) void {
markSecret(ptr, .classify);
}