/***********************************************/ /* An entropy gathering demon written for OS/2 */ /* Version 0.1 */ /* This software is Public Domain */ /***********************************************/ /* Initalize main variables */ /* Users can adjust these values */ /*********************************/ Pipe = '\PIPE\ENTROPY' PoolSize = 520 DigestSize = 100 GatherInterval = 1000*60*5 /*milliseconds*/ EntropySources.0 = 12 EntropySources.1.interperate = 1 EntropySources.1.cmd = "Call SysInfo" EntropySources.2.interperate = 0 EntropySources.2.cmd = "GO -lpl 2> NUL | RXQUEUE" EntropySources.3.interperate = 0 EntropySources.3.cmd = "GO -tl 2> NUL | RXQUEUE" EntropySources.4.interperate = 0 EntropySources.4.cmd = "GO -sl 2> NUL | RXQUEUE" EntropySources.5.interperate = 0 EntropySources.5.cmd = "GO -ml 2> NUL | RXQUEUE" EntropySources.6.interperate = 0 EntropySources.6.cmd = "netstat -m | RXQUEUE" EntropySources.7.interperate = 0 EntropySources.7.cmd = "netstat -u | RXQUEUE" EntropySources.8.interperate = 0 EntropySources.8.cmd = "netstat -i | RXQUEUE" EntropySources.9.interperate = 0 EntropySources.9.cmd = "netstat -s | RXQUEUE" EntropySources.10.interperate = 0 EntropySources.10.cmd = "netstat -r | RXQUEUE" EntropySources.11.interperate = 0 EntropySources.11.cmd = "netstat -n | RXQUEUE" EntropySources.12.interperate = 0 EntropySources.12.cmd = "netstat -p | RXQUEUE" /* Load REXX extensions */ /************************/ call RxFuncAdd 'IPCLoadFuncs', 'REXXIPC', 'IPCLoadFuncs' call IPCLoadFuncs if rxfuncquery('srx_sha')=1 then do call RXFuncAdd 'srx_sha', 'SRXFUNC', 'srx_sha' end if rxfuncquery('srx_sha')=1 then do say " Could not load SRX_SHA from SRXFUNC.DLL" exit end if rxfuncquery('RxQuerySysInfo')=1 then do call RxFuncAdd 'RxQuerySysInfo', 'rxu', 'RxQuerySysInfo' end if rxfuncquery('RxQuerySysInfo')=1 then do say " Could not load RxQuerySysInfo from RXU.DLL" exit end if rxfuncquery('RxProcId')=1 then do call RxFuncAdd 'RxProcId', 'rxu', 'RxProcId' end if rxfuncquery('RxProcId')=1 then do say " Could not load RxProcId from RXU.DLL" exit end /* Add inital entropy to pool */ /* Run all Entropy Sources */ /******************************/ pool = COPIES('00'x, PoolSize) say 'Adding Inital Entropy' do i = 1 to EntropySources.0 Call GatherEntropy EntropySources.i.interperate, EntropySources.i.cmd end say 'Entropy Added' /* Get PID */ /***********/ procinfo = rxprocid() PID = WORD(procinfo, 1) /* Create waitable pipe */ /************************/ sourceCount=0 curSource=1 call PipeCreate 'pipeHandle', Pipe, 'Duplex', 'Byte' if result \= 0 then signal PipeCreateError call SemEventCreate 'pipeSem' if result \= 0 then signal SemaphoreCreateError call IPCContextCreate 'pipeContext', pipeSem if result \= 0 then signal IpcContextCreateError /* Enter main loop */ /*******************/ do forever call PipeConnectAsync pipeHandle, pipeContext if result \= 0 then signal PipeConnectAsyncError /* Wait for request, or timeout */ /********************************/ do forever call SemEventWait pipeSem, GatherInterval if result=640 then do /* Time expired. Gather more entropy */ /**************************************/ say 'Adding Entropy' Call GatherEntropy EntropySources.curSource.interperate, EntropySources.curSource.cmd sourceCount = curSource // EntropySources.0 curSource = sourceCount+1 say 'Entropy Added' end /* do */ else if result = 0 then leave else signal SemaphoreEventWaitError end /* do */ /* Handle request */ /******************/ call PipeRead pipeHandle, 'request', 1 if result \= 0 then signal PipeReadError select when request='00'x then do call PipeWrite pipeHandle, RIGHT(D2C(PoolSize*8),4,'00'x) if result \= 0 then signal PipeWriteError end /* do */ when request='01'x then do call PipeRead pipeHandle, 'size', 1 if result \= 0 then signal PipeReadError say "Nonblocking Read Requested:" C2D(size) call PipeWrite pipeHandle, size''GetEntropy(C2D(size)) if result \= 0 then signal PipeWriteError end /* do */ when request='02'x then do call PipeRead pipeHandle, 'size', 1 if result \= 0 then signal PipeReadError say "Blocking Read Requested:" C2D(size) call PipeWrite pipeHandle, GetEntropy(C2D(size)) if result \= 0 then signal PipeWriteError end /* do */ when request='03'x then do call PipeRead pipeHandle, 'buffer' if result \= 0 then signal PipeReadError say 'Adding Entropy' call AddEntropy buffer say 'Entropy Added' end when request='04'x then do call PipeWrite pipeHandle, '02'x''RIGHT(D2C(PID),2,'00'x) if result \= 0 then signal PipeWriteError end otherwise say 'Bad Requst:' C2X(request) end /* select */ call PipeDisconnect pipeHandle if result \= 0 then signal PipeDisconnectError end leave: call SemEventClose pipeSem call IPCContextClose pipeContext call PipeClose pipeHandle exit -1 /* Procedures */ /**************/ GatherEntropy: PROCEDURE EXPOSE pool DigestSize cmd = ARG(2) if ARG(1) then INTERPRET cmd else cmd do while QUEUED() > 0 pull line Call AddEntropy SPACE(line,0) end RETURN AddEntropy: PROCEDURE EXPOSE pool DigestSize data = ARG(1) /* say data */ DO WHILE LENGTH(data) > 0 chunk = SUBSTR(data, 1, DigestSize) pool = BITXOR(pool, chunk) CALL stir data = SUBSTR(data, DigestSize+1) END RETURN Stir: PROCEDURE EXPOSE pool location = 1 DO WHILE location < LENGTH(pool) hash = X2C(SPACE(srx_sha(pool),0)) pool = OVERLAY(BITXOR(hash, substr(pool, location, LENGTH(hash))),pool,location) location = location + length(hash) end /* do */ RETURN GetEntropy: PROCEDURE EXPOSE pool size = ARG(1) data = '' count = 0 DO WHILE size > count hash = X2C(SPACE(srx_sha(pool),0)) call Stir data=data''hash count = count+LENGTH(hash) end RETURN SUBSTR(data,1,size) SysInfo: PROCEDURE CALL RxQuerySysInfo 'sysInfo.' DO i = 1 to 26 QUEUE sysInfo.i END RETURN /* Error handling */ /******************/ PipeCreateError: SemaphoreCreateError: IpcContextCreateError: say 'Could not create waitable pipe:' result say 'line:' sigl signal leave PipeConnectAsyncError: say 'Could not connect to pipe:' result say 'line:' sigl signal leave SemaphoreEventWaitError: say 'Error waiting on semaphore:' result say 'line:' sigl signal leave PipeReadError: say 'Error reading from pipe:' result say 'line:' sigl signal leave PipeWriteError: say 'Error writing from pipe:' result say 'line:' sigl signal leave PipeDisconnectError: say 'Error disconnecting pipe:' result say 'line:' sigl signal leave