214bd21999-08-25Henrik Grubbström (Grubba) /* $Id: randomness.pmod,v 1.11 1999/08/25 17:32:54 grubba Exp $
6d00f01997-03-15Niels Möller  */
214bd21999-08-25Henrik Grubbström (Grubba) //! module Crypto //! submodule randomness //! Assorted stronger or weaker randomnumber generators.
6d00f01997-03-15Niels Möller /* These devices tries to collect entropy from the environment. * They differ in behaviour when they run low on entropy, /dev/random * will block if it can't provide enough random bits, while /dev/urandom * will degenerate into a reasonably strong pseudo random generator */
214bd21999-08-25Henrik Grubbström (Grubba) static constant RANDOM_DEVICE = "/dev/random"; static constant PRANDOM_DEVICE = "/dev/urandom";
6d00f01997-03-15Niels Möller  /* Collect somewhat random data from the environment. Unfortunately, * this is quite system dependent */
214bd21999-08-25Henrik Grubbström (Grubba) static constant PATH = "/usr/sbin:/usr/etc:/usr/bin/:/sbin/:/etc:/bin";
ddab201998-01-19Fredrik Hübinette (Hubbe)  #ifndef __NT__
214bd21999-08-25Henrik Grubbström (Grubba) static constant SYSTEM_COMMANDS = ({ "last -256", "arp -a", "netstat -anv","netstat -mv","netstat -sv", "uptime","ps -fel","ps aux", "vmstat -s","vmstat -M", "iostat","iostat -cdDItx" });
ddab201998-01-19Fredrik Hübinette (Hubbe) #else
214bd21999-08-25Henrik Grubbström (Grubba) static constant SYSTEM_COMMANDS = ({ "mem /c", "arp -a", "vol", "dir", "net view", "net statistics workstation","net statistics server", "net user" });
ddab201998-01-19Fredrik Hübinette (Hubbe) #endif
6d00f01997-03-15Niels Möller  #define PRIVATE PRIVATE object global_rc4;
214bd21999-08-25Henrik Grubbström (Grubba) // method string some_entropy() // Executes several programs to generate some entropy from their output.
6d00f01997-03-15Niels Möller PRIVATE string some_entropy() {
ddab201998-01-19Fredrik Hübinette (Hubbe)  string res;
6d00f01997-03-15Niels Möller  object parent_pipe, child_pipe;
c3f7751998-02-06Fredrik Hübinette (Hubbe)  mapping env=getenv()+([]);
6d00f01997-03-15Niels Möller  parent_pipe = Stdio.File(); child_pipe = parent_pipe->pipe(); if (!child_pipe) throw( ({ "Crypto.random->popen: couldn't create pipe\n", backtrace() }) );
ddab201998-01-19Fredrik Hübinette (Hubbe)  #ifndef __NT__ object null=Stdio.File("/dev/null","rw"); env["PATH"]=PATH; #else object null=Stdio.File("nul:","rw"); #endif foreach(SYSTEM_COMMANDS, string cmd) { catch { Process.create_process(Process.split_quoted_string(cmd),
c029131998-02-06Fredrik Hübinette (Hubbe)  (["stdin":null, "stdout":child_pipe, "stderr":null, "env":env]));
ddab201998-01-19Fredrik Hübinette (Hubbe)  }; } destruct(child_pipe); return parent_pipe->read();
6d00f01997-03-15Niels Möller }
ddab201998-01-19Fredrik Hübinette (Hubbe) 
214bd21999-08-25Henrik Grubbström (Grubba) //! class pike_random //! A pseudo random generator based on the ordinary random() function.
6d00f01997-03-15Niels Möller class pike_random {
214bd21999-08-25Henrik Grubbström (Grubba)  //! method string read(int len) //! Returns a string of length len with pseudo random values.
6d00f01997-03-15Niels Möller  string read(int len) {
8177c41999-06-16David Hedbor  if (len > 16384) return read(len/2)+read(len-len/2); return (string)allocate(len, random)(256);
6d00f01997-03-15Niels Möller  } }
214bd21999-08-25Henrik Grubbström (Grubba) //! class rc4_random //! A pseudo random generator based on the rc4 crypto.
6d00f01997-03-15Niels Möller class rc4_random { inherit Crypto.rc4 : rc4;
214bd21999-08-25Henrik Grubbström (Grubba)  //! method void create(string secret) //! Initialize and seed the rc4 random generator.
6d00f01997-03-15Niels Möller  void create(string secret) { object hash = Crypto.sha(); hash->update(secret); rc4::set_encrypt_key(hash->digest()); }
214bd21999-08-25Henrik Grubbström (Grubba)  //! method string read(int len) //! Return a string of the next len random characters from the //! rc4 random generator.
6d00f01997-03-15Niels Möller  string read(int len) {
0c8b101999-06-17Henrik Grubbström (Grubba)  if (len > 16384) return read(len/2)+read(len-len/2); return rc4::crypt("\47" * len);
6d00f01997-03-15Niels Möller  } }
214bd21999-08-25Henrik Grubbström (Grubba) 
6d00f01997-03-15Niels Möller object reasonably_random() { if (file_stat(PRANDOM_DEVICE)) { object res = Stdio.File(); if (res->open(PRANDOM_DEVICE, "r")) return res; } if (global_rc4) return global_rc4; string seed = some_entropy(); if (strlen(seed) > 2000) return (global_rc4 = rc4_random(sprintf("%4c%O%s", time(), _memory_usage(), seed))); throw( ({ "Crypto.randomness.reasonably_random: No source found\n", backtrace() }) ); } object really_random(int|void may_block) {
e106c71997-04-10Niels Möller  object res = Stdio.File();
6d00f01997-03-15Niels Möller  if (may_block && file_stat(RANDOM_DEVICE)) { if (res->open(RANDOM_DEVICE, "r")) return res; } if (file_stat(PRANDOM_DEVICE)) { if (res->open(PRANDOM_DEVICE, "r")) return res; } throw( ({ "Crypto.randomness.really_random: No source found\n", backtrace() }) ); }
ddab201998-01-19Fredrik Hübinette (Hubbe)