baseunix,unix,unixutil,sockets,\r
{$endif}\r
{$endif}\r
+ {$ifdef linux}\r
+ syscall,\r
+ {$endif}\r
fastmd5,sysutils;\r
{$endif}\r
\r
end;\r
\r
\r
+{$ifdef linux}\r
+ {$ifdef i386}\r
+ const sys_getrandom = 355;\r
+ {$endif}\r
+\r
+ {$ifdef cpux64}\r
+ const sys_getrandom = 318;\r
+ {$endif}\r
+{$endif}\r
+\r
+\r
function collect_seeding(var output;const bufsize:integer):integer;\r
var\r
f:file;\r
if (bufsize < sizeof(l)) then exit;\r
result := sizeof(l);\r
\r
- {/DEV/URANDOM}\r
- a := 1;\r
- assignfile(f,'/dev/urandom');\r
- filemode := 0;\r
- {$i-}reset(f,1);{$i+}\r
- a := ioresult;\r
- if (a <> 0) then begin\r
- assignfile(f,'/dev/random');\r
+ a := -1;\r
+ {$ifdef linux}\r
+ a := do_syscall(sys_getrandom,tsysparam(@l.devrnd),sizeof(l.devrnd),0);\r
+ {$endif}\r
+\r
+ if (a < sizeof(l.devrnd)) then begin\r
+ {if syscall misses or fails, fall back to /dev/urandom}\r
+ assignfile(f,'/dev/urandom');\r
+ filemode := 0;\r
{$i-}reset(f,1);{$i+}\r
a := ioresult;\r
- end;\r
- if (a = 0) then begin\r
- blockread(f,l.devrnd,sizeof(l.devrnd));\r
- closefile(f);\r
- end else begin\r
- {the OS we are on has no /dev/random or /dev/urandom, get a hash from /var/log/wtmp}\r
- wtmphash;\r
- move(wtmpcached,l.devrnd,sizeof(l.devrnd));\r
+ if (a <> 0) then begin\r
+ assignfile(f,'/dev/random');\r
+ {$i-}reset(f,1);{$i+}\r
+ a := ioresult;\r
+ end;\r
+ if (a = 0) then begin\r
+ blockread(f,l.devrnd,sizeof(l.devrnd));\r
+ closefile(f);\r
+ end else begin\r
+ {the OS we are on has no /dev/random or /dev/urandom, get a hash from /var/log/wtmp}\r
+ wtmphash;\r
+ move(wtmpcached,l.devrnd,sizeof(l.devrnd));\r
+ end;\r
end;\r
{get more randomness in case there's no /dev/random}\r
rdtsc(@l.rdtscbuf);\r