| ... | ... | @@ -1744,18 +1744,17 @@ const statx_use_c = std.c.versionCheck(if (builtin.abi.isAndroid()) |
| 1744 | 1744 | else |
| 1745 | 1745 | .{ .major = 2, .minor = 28, .patch = 0 }); |
| 1746 | 1746 | |
| 1747 | | const getrandom_use_libc = @TypeOf(posix.system.getrandom) != void and (native_os != .linux or |
| 1748 | | std.c.versionCheck(if (builtin.abi.isAndroid()) .{ |
| 1749 | | .major = 28, |
| 1750 | | .minor = 0, |
| 1751 | | .patch = 0, |
| 1752 | | } else .{ |
| 1753 | | .major = 2, |
| 1754 | | .minor = 25, |
| 1755 | | .patch = 0, |
| 1756 | | })); |
| 1747 | const use_libc_getrandom = std.c.versionCheck(if (builtin.abi.isAndroid()) .{ |
| 1748 | .major = 28, |
| 1749 | .minor = 0, |
| 1750 | .patch = 0, |
| 1751 | } else .{ |
| 1752 | .major = 2, |
| 1753 | .minor = 25, |
| 1754 | .patch = 0, |
| 1755 | }); |
| 1757 | 1756 | |
| 1758 | | const use_dev_urandom = !getrandom_use_libc and native_os == .linux; |
| 1757 | const use_dev_urandom = @TypeOf(posix.system.getrandom) == void and native_os == .linux; |
| 1759 | 1758 | |
| 1760 | 1759 | fn async( |
| 1761 | 1760 | userdata: ?*anyopaque, |
| ... | ... | @@ -15149,9 +15148,9 @@ fn fallbackSeedWasi(seed: *[Csprng.seed_len]u8) void { |
| 15149 | 15148 | |
| 15150 | 15149 | fn randomSecure(userdata: ?*anyopaque, buffer: []u8) Io.RandomSecureError!void { |
| 15151 | 15150 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 15151 | if (buffer.len == 0) return; |
| 15152 | 15152 | |
| 15153 | 15153 | if (is_windows) { |
| 15154 | | if (buffer.len == 0) return; |
| 15155 | 15154 | // ProcessPrng from bcryptprimitives.dll has the following properties: |
| 15156 | 15155 | // * introduces a dependency on bcryptprimitives.dll, which apparently |
| 15157 | 15156 | // runs a test suite every time it is loaded |
| ... | ... | @@ -15213,7 +15212,7 @@ fn randomSecure(userdata: ?*anyopaque, buffer: []u8) Io.RandomSecureError!void { |
| 15213 | 15212 | } |
| 15214 | 15213 | |
| 15215 | 15214 | if (@TypeOf(posix.system.getrandom) != void) { |
| 15216 | | const getrandom = if (getrandom_use_libc) std.c.getrandom else std.os.linux.getrandom; |
| 15215 | const getrandom = if (use_libc_getrandom) std.c.getrandom else std.os.linux.getrandom; |
| 15217 | 15216 | var i: usize = 0; |
| 15218 | 15217 | const syscall: Syscall = try .start(); |
| 15219 | 15218 | while (i < buffer.len) { |
| ... | ... | @@ -15244,34 +15243,38 @@ fn randomSecure(userdata: ?*anyopaque, buffer: []u8) Io.RandomSecureError!void { |
| 15244 | 15243 | } |
| 15245 | 15244 | } |
| 15246 | 15245 | |
| 15247 | | if (buffer.len == 0) return; |
| 15248 | | const urandom_fd = try getRandomFd(t); |
| 15246 | if (native_os == .linux) { |
| 15247 | comptime assert(use_dev_urandom); |
| 15248 | const urandom_fd = try getRandomFd(t); |
| 15249 | 15249 | |
| 15250 | | var i: usize = 0; |
| 15251 | | while (buffer.len - i != 0) { |
| 15252 | | const syscall: Syscall = try .start(); |
| 15253 | | const rc = posix.system.read(urandom_fd, buffer[i..].ptr, buffer.len - i); |
| 15254 | | switch (posix.errno(rc)) { |
| 15255 | | .SUCCESS => { |
| 15256 | | syscall.finish(); |
| 15257 | | const n: usize = @intCast(rc); |
| 15258 | | if (n == 0) { |
| 15259 | | if (buffer.len - i != 0) { |
| 15260 | | return error.EntropyUnavailable; |
| 15261 | | } else { |
| 15262 | | return; |
| 15250 | var i: usize = 0; |
| 15251 | while (buffer.len - i != 0) { |
| 15252 | const syscall: Syscall = try .start(); |
| 15253 | const rc = posix.system.read(urandom_fd, buffer[i..].ptr, buffer.len - i); |
| 15254 | switch (posix.errno(rc)) { |
| 15255 | .SUCCESS => { |
| 15256 | syscall.finish(); |
| 15257 | const n: usize = @intCast(rc); |
| 15258 | if (n == 0) { |
| 15259 | if (buffer.len - i != 0) { |
| 15260 | return error.EntropyUnavailable; |
| 15261 | } else { |
| 15262 | return; |
| 15263 | } |
| 15263 | 15264 | } |
| 15264 | | } |
| 15265 | | i += n; |
| 15266 | | continue; |
| 15267 | | }, |
| 15268 | | .INTR => { |
| 15269 | | try syscall.checkCancel(); |
| 15270 | | continue; |
| 15271 | | }, |
| 15272 | | else => return syscall.fail(error.EntropyUnavailable), |
| 15265 | i += n; |
| 15266 | continue; |
| 15267 | }, |
| 15268 | .INTR => { |
| 15269 | try syscall.checkCancel(); |
| 15270 | continue; |
| 15271 | }, |
| 15272 | else => return syscall.fail(error.EntropyUnavailable), |
| 15273 | } |
| 15273 | 15274 | } |
| 15274 | 15275 | } |
| 15276 | |
| 15277 | return error.EntropyUnavailable; |
| 15275 | 15278 | } |
| 15276 | 15279 | |
| 15277 | 15280 | fn getRandomFd(t: *Threaded) Io.RandomSecureError!posix.fd_t { |