| ... | ... | @@ -13929,7 +13929,7 @@ fn processSpawnWindows(userdata: ?*anyopaque, options: process.SpawnOptions) pro |
| 13929 | 13929 | }; |
| 13930 | 13930 | } |
| 13931 | 13931 | |
| 13932 | | fn getCngHandle(t: *Threaded) !windows.HANDLE { |
| 13932 | fn getCngHandle(t: *Threaded) Io.RandomSecureError!windows.HANDLE { |
| 13933 | 13933 | { |
| 13934 | 13934 | t.mutex.lock(); |
| 13935 | 13935 | defer t.mutex.unlock(); |
| ... | ... | @@ -13980,8 +13980,8 @@ fn getCngHandle(t: *Threaded) !windows.HANDLE { |
| 13980 | 13980 | try syscall.checkCancel(); |
| 13981 | 13981 | continue; |
| 13982 | 13982 | }, |
| 13983 | | .OBJECT_NAME_NOT_FOUND => return syscall.fail(error.Unexpected), // Observed on wine 10.0 |
| 13984 | | else => |status| return syscall.unexpectedNtstatus(status), |
| 13983 | .OBJECT_NAME_NOT_FOUND => return syscall.fail(error.EntropyUnavailable), // Observed on wine 10.0 |
| 13984 | else => return syscall.fail(error.EntropyUnavailable), |
| 13985 | 13985 | }; |
| 13986 | 13986 | } |
| 13987 | 13987 | |
| ... | ... | @@ -15096,23 +15096,13 @@ fn randomMainThread(t: *Threaded, buffer: []u8) void { |
| 15096 | 15096 | randomSecure(t, &seed) catch |err| switch (err) { |
| 15097 | 15097 | error.Canceled => unreachable, |
| 15098 | 15098 | error.EntropyUnavailable => { |
| 15099 | | seed = @splat(0); |
| 15100 | | std.mem.writeInt(posix.pid_t, seed[0..@sizeOf(posix.pid_t)], posix.system.getpid(), .native); |
| 15101 | | const i_1 = @sizeOf(posix.pid_t); |
| 15102 | | |
| 15103 | | var ts: posix.timespec = undefined; |
| 15104 | | const Sec = @TypeOf(ts.sec); |
| 15105 | | const Nsec = @TypeOf(ts.nsec); |
| 15106 | | const i_2 = i_1 + @sizeOf(Sec); |
| 15107 | | const i_3 = i_2 + @sizeOf(Nsec); |
| 15108 | | switch (posix.errno(posix.system.clock_gettime(.REALTIME, &ts))) { |
| 15109 | | .SUCCESS => { |
| 15110 | | std.mem.writeInt(Sec, seed[i_1..][0..@sizeOf(Sec)], ts.sec, .native); |
| 15111 | | std.mem.writeInt(Nsec, seed[i_2..][0..@sizeOf(Nsec)], ts.nsec, .native); |
| 15112 | | }, |
| 15113 | | else => {}, |
| 15099 | @memset(&seed, 0); |
| 15100 | const aslr_addr = @intFromPtr(t); |
| 15101 | std.mem.writeInt(usize, seed[seed.len - @sizeOf(usize) ..][0..@sizeOf(usize)], aslr_addr, .native); |
| 15102 | switch (native_os) { |
| 15103 | .windows => fallbackSeedWindows(&seed), |
| 15104 | else => fallbackSeedPosix(&seed), |
| 15114 | 15105 | } |
| 15115 | | std.mem.writeInt(usize, seed[i_3..][0..@sizeOf(usize)], @intFromPtr(t), .native); |
| 15116 | 15106 | }, |
| 15117 | 15107 | }; |
| 15118 | 15108 | } |
| ... | ... | @@ -15122,6 +15112,29 @@ fn randomMainThread(t: *Threaded, buffer: []u8) void { |
| 15122 | 15112 | t.csprng.rng.fill(buffer); |
| 15123 | 15113 | } |
| 15124 | 15114 | |
| 15115 | fn fallbackSeedPosix(seed: *[Csprng.seed_len]u8) void { |
| 15116 | std.mem.writeInt(posix.pid_t, seed[0..@sizeOf(posix.pid_t)], posix.system.getpid(), .native); |
| 15117 | const i_1 = @sizeOf(posix.pid_t); |
| 15118 | |
| 15119 | var ts: posix.timespec = undefined; |
| 15120 | const Sec = @TypeOf(ts.sec); |
| 15121 | const Nsec = @TypeOf(ts.nsec); |
| 15122 | const i_2 = i_1 + @sizeOf(Sec); |
| 15123 | switch (posix.errno(posix.system.clock_gettime(.REALTIME, &ts))) { |
| 15124 | .SUCCESS => { |
| 15125 | std.mem.writeInt(Sec, seed[i_1..][0..@sizeOf(Sec)], ts.sec, .native); |
| 15126 | std.mem.writeInt(Nsec, seed[i_2..][0..@sizeOf(Nsec)], ts.nsec, .native); |
| 15127 | }, |
| 15128 | else => {}, |
| 15129 | } |
| 15130 | } |
| 15131 | |
| 15132 | fn fallbackSeedWindows(seed: *[Csprng.seed_len]u8) void { |
| 15133 | var pc: windows.LARGE_INTEGER = undefined; |
| 15134 | _ = windows.ntdll.RtlQueryPerformanceCounter(&pc); |
| 15135 | std.mem.writeInt(windows.LARGE_INTEGER, seed[0..@sizeOf(windows.LARGE_INTEGER)], pc, .native); |
| 15136 | } |
| 15137 | |
| 15125 | 15138 | fn randomSecure(userdata: ?*anyopaque, buffer: []u8) Io.RandomSecureError!void { |
| 15126 | 15139 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 15127 | 15140 | |