X-Git-Url: http://www.lcore.org/git/lcore.git/blobdiff_plain/987e8123d8ba3201ed2690004cfefd7983ff7487..ffb12fba43635d1d31d7dd073cd4d1ea7d8f4ebd:/lcorernd.pas?ds=inline diff --git a/lcorernd.pas b/lcorernd.pas index 64759e8..7dbd7f1 100644 --- a/lcorernd.pas +++ b/lcorernd.pas @@ -15,7 +15,7 @@ written by Bas Steendijk (beware) the aim of this unit is to provide randomness in a consistent way, using OS specific methods for seeding this unit uses MD5 for performance and code size, but it is made so it is easy to use a different hash, -as long as it is atleat 128 bits, and a multiple of the "word size" (32 bits) +as long as it is at least 128 bits, and a multiple of the "word size" (32 bits) goals: @@ -25,20 +25,20 @@ goals: - for the numbers to be - random: pass diehard and similar tests - - unique: generate UUID's + - unique: generate UUIDs - secure: difficult for a remote attacker to guess the internal state, even when given some output typical intended uses: - anything that needs random numbers without extreme demands on security or speed should be able to use this - - seeding other (faster) RNG's - - generation of passwords, UUID's, cookies, and session keys + - seeding other (faster) RNGs + - generation of passwords, UUIDs, cookies, and session keys - randomizing protocol fields to protect against spoofing attacks - randomness for games this is not intended to be directly used for: -- high securirity purposes (generating RSA root keys etc) +- high security purposes (generating RSA root keys etc) - needing random numbers at very high rates (disk wiping, some simulations, etc) performance: @@ -111,7 +111,7 @@ function randominteger(i:longint):longint; function randombits(b:integer):longint; {generate a version 4 random uuid} -function generate_uuid:string; +function generate_uuid:ansistring; {$ifndef nolcorernd} @@ -130,20 +130,39 @@ var implementation +{$include pgtypes.inc} + {$ifndef nolcorernd} uses - {$ifdef win32}windows,activex,{$endif} + {$ifdef mswindows}windows,activex,{$endif} {$ifdef unix} {$ifdef ver1_0} linux, {$else} - baseunix,unix,unixutil, + baseunix,unix,unixutil,sockets, {$endif} {$endif} fastmd5,sysutils; {$ifdef unix}{$include unixstuff.inc}{$endif} +procedure rdtsc(buf: pointer); +asm + {$ifdef cpux86} + mov ecx, buf + db $0f; db $31 {rdtsc} + mov [ecx], edx + mov [ecx+4], eax + {$endif} + + {$ifdef cpux64} + mov rcx, buf + rdtsc + mov [rcx], edx + mov [rcx+4], eax + {$endif} +end; + type {hashtype must be array of bytes} hashtype=tmd5; @@ -161,11 +180,11 @@ const hashpasssize=48; {this number has to be small enough that hashing this size uses only one block transform} var - {the seed part of this buffer must be atleast as big as the OS seed (windows: 104 bytes, unix: 36 bytes)} + {the seed part of this buffer must be at least as big as the OS seed (windows: 104 bytes, unix: 36 bytes)} pool:array[0..(pooldwords+seeddwords-1)] of wordtype; reseedcountdown:integer; -{$ifdef win32} +{$ifdef mswindows} function collect_seeding(var output;const bufsize:integer):integer; var l:packed record @@ -178,7 +197,6 @@ var cursor:tpoint; hs:theapstatus; end absolute output; - rdtsc_0,rdtsc_1:integer; begin result := 0; if (bufsize < sizeof(l)) then exit; @@ -194,15 +212,8 @@ begin queryperformancecounter(tlargeinteger(l.qpcbuf)); {RDTSC} - {$ifdef cpu386} - asm - db $0F; db $31 - mov rdtsc_0,eax - mov rdtsc_1,edx - end; - l.rdtscbuf[0] := rdtsc_0; - l.rdtscbuf[1] := rdtsc_1; - {$endif} + rdtsc(@l.rdtscbuf); + {GETSYSTEMTIME} getsystemtime(tsystemtime(l.systemtimebuf)); @@ -248,12 +259,11 @@ var f:file; a:integer; l:packed record - devrnd:array[0..3] of integer; + devrnd:array[0..7] of integer; rdtscbuf:array[0..1] of integer; tv:ttimeval; pid:integer; end absolute output; - rdtsc_0,rdtsc_1:integer; begin result := 0; @@ -280,15 +290,7 @@ begin move(wtmpcached,l.devrnd,sizeof(l.devrnd)); end; {get more randomness in case there's no /dev/random} - {$ifdef cpu386}{$ASMMODE intel} - asm - db $0F; db $31 - mov rdtsc_0,eax - mov rdtsc_1,edx - end; - l.rdtscbuf[0] := rdtsc_0; - l.rdtscbuf[1] := rdtsc_1; - {$endif} + rdtsc(@l.rdtscbuf); gettimeofday(l.tv); l.pid := getpid; @@ -402,12 +404,12 @@ begin end; const - ch:array[0..15] of char='0123456789abcdef'; + ch:array[0..15] of ansichar='0123456789abcdef'; -function generate_uuid:string; +function generate_uuid:ansistring; var buf:array[0..7] of word; -function inttohex(w:word):string; +function inttohex(w:word):ansistring; begin result := ch[w shr 12] + ch[(w shr 8) and $f] + ch[(w shr 4) and $f] + ch[w and $f]; end;