random.c
上传用户:hepax88
上传日期:2007-01-03
资源大小:1101k
文件大小:3k
源码类别:

TCP/IP协议栈

开发平台:

Visual C++

  1. /* Maintain source of random numbers for cryptographic keys, etc
  2.  * This is inherently machine dependent code
  3.  */
  4. #include "stdio.h"
  5. #include <dos.h>
  6. #include "global.h"
  7. #include "timer.h"
  8. #include "md5.h"
  9. #include "nospc.h"
  10. static unsigned char Randstate[16];
  11. static unsigned long Randcntr;
  12. /* Spawned at startup to initialize random generator state.
  13.  * Rapidly reads counter/timer bits a few thousand times, relying
  14.  * on the phase jitter between the CPU clock and the counter/timer
  15.  * clock. THIS IS NOT RELIABLE! It works on some motherboards and
  16.  * not others. It's fast, so we might as well do it, but it must
  17.  * not be the only source of randomness.
  18.  */
  19. void
  20. rand_init(n,v1,v2)
  21. int n;
  22. void *v1,*v2;
  23. {
  24. MD5_CTX context;
  25. int i,j;
  26. unsigned short values[200];
  27. for(i = 0;i< 16;i++){
  28. for(j=0;j<200;j++)
  29. values[j] = clockbits();
  30. MD5Init(&context);
  31. MD5Update(&context,Randstate,sizeof(Randstate));
  32. MD5Update(&context,(unsigned char *)values,sizeof(values));
  33. MD5Final(Randstate,&context);
  34. kwait(NULL); /* Don't hog the machine */
  35. }
  36. }
  37. /* Fill user buffer with random data. This is done by hashing the random
  38.  * state with a counter so that the random state is not directly
  39.  * revealed.
  40.  */
  41. void
  42. getrand(buf,len)
  43. unsigned char *buf;
  44. int len;
  45. {
  46. uint16 t;
  47. MD5_CTX context;
  48. uint8 digest[16];
  49. int cnt;
  50. /* Fold the current time into the random state */
  51. t = clockbits();
  52. MD5Init(&context);
  53. MD5Update(&context,Randstate,sizeof(Randstate));
  54. MD5Update(&context,(unsigned char *)&t,sizeof(t));
  55. MD5Final(Randstate,&context);
  56. /* Now combine the random state and the counter to provide as
  57.  * much random data as needed
  58.  */
  59. while(len != 0){
  60. MD5Init(&context);
  61. MD5Update(&context,Randstate,sizeof(Randstate));
  62. MD5Update(&context,(unsigned char *)&Randcntr,sizeof(Randcntr));
  63. MD5Final(digest,&context);
  64. Randcntr++;
  65. cnt = min(len,sizeof(digest));
  66. memcpy(buf,digest,cnt);
  67. len -= cnt;
  68. buf += cnt;
  69. }
  70. }
  71. /* Called with a 16-bit scan code whenever a key is hit. Fold the current
  72.  * state, the typed character and the current clock into the new
  73.  * random state.
  74.  */
  75. void
  76. rtype(c)
  77. uint16 c;
  78. {
  79. uint16 t;
  80. MD5_CTX context;
  81. MD5Init(&context);
  82. MD5Update(&context,Randstate,sizeof(Randstate));
  83. t = clockbits();
  84. MD5Update(&context,(unsigned char *)&t,sizeof(t));
  85. MD5Update(&context,(unsigned char *)&c,sizeof(c));
  86. MD5Final(Randstate,&context);
  87. }
  88. /* Generate a uniformly-distributed random number between 0 and n-1
  89.  * Uses rejection method
  90.  */
  91. int
  92. urandom(n)
  93. unsigned int n;
  94. {
  95. uint32 k,i;
  96. #define MAXRANDOM ((unsigned long)0x7fffffff)
  97. k = MAXRANDOM - (MAXRANDOM+1) % n;
  98. do {
  99. getrand((unsigned char *)&i,sizeof(i));
  100. i &= ~0x80000000; /* Make i positive as signed long */
  101. } while(i > k);
  102. return i % n;
  103. }