bits.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /* portable way to get secure random bits to feed a PRNG */
  2. #include "mycrypt.h"
  3. #ifdef DEVRANDOM
  4. /* on *NIX read /dev/random */
  5. static unsigned long rng_nix(unsigned char *buf, unsigned long len,
  6. void (*callback)(void))
  7. {
  8. #ifdef NO_FILE
  9. return 0;
  10. #else
  11. FILE *f;
  12. unsigned long x;
  13. #ifdef TRY_URANDOM_FIRST
  14. f = fopen("/dev/urandom", "rb");
  15. if (f == NULL)
  16. #endif /* TRY_URANDOM_FIRST */
  17. f = fopen("/dev/random", "rb");
  18. if (f == NULL) {
  19. return 0;
  20. }
  21. /* disable buffering */
  22. if (setvbuf(f, NULL, _IONBF, 0) != 0) {
  23. fclose(f);
  24. return 0;
  25. }
  26. x = (unsigned long)fread(buf, 1, (size_t)len, f);
  27. fclose(f);
  28. return x;
  29. #endif /* NO_FILE */
  30. }
  31. #endif /* DEVRANDOM */
  32. #ifdef SONY_PS2
  33. #include <eetypes.h>
  34. #include <eeregs.h>
  35. #define min(a,b) ((a) < (b) ? (a) : (b))
  36. // Very simple/stupid MD5-based RNG that samples "entropy" from various PS2 control registers
  37. static unsigned long rng_ps2(unsigned char *buf, unsigned long len,
  38. void (*callback)(void))
  39. {
  40. static unsigned long lastx[2] = { 0xaab7cb4b2fd3b2b9, 0xcec58aff72afe49f }; // md5sum of bits.c
  41. unsigned long j;
  42. unsigned int samples[10]; // number of sample data sources
  43. int l;
  44. hash_state md;
  45. for (j = 0; j < len; j += sizeof(lastx)) {
  46. md5_init(&md);
  47. samples[0] = *T2_COUNT;
  48. samples[1] = *T3_COUNT;
  49. samples[2] = *IPU_TOP;
  50. samples[3] = *GIF_TAG0;
  51. samples[4] = *GIF_TAG1;
  52. samples[5] = *GIF_TAG2;
  53. samples[6] = *VIF1_CODE;
  54. samples[7] = *VIF0_CODE;
  55. samples[8] = *D0_MADR;
  56. samples[9] = *D1_MADR;
  57. md5_process(&md, (unsigned char *)(&samples[0]), sizeof(samples));
  58. // include previous round
  59. md5_process(&md, (unsigned char *)(&lastx[0]), sizeof(lastx));
  60. md5_done(&md, (unsigned char *)(&lastx[0]));
  61. l = min(sizeof(lastx), len-j);
  62. memcpy(buf+j, &lastx[0], l); //min(sizeof(lastx), len-j));
  63. }
  64. return len;
  65. }
  66. #endif /* SONY_PS2 */
  67. /* on ANSI C platforms with 100 < CLOCKS_PER_SEC < 10000 */
  68. #if !defined(SONY_PS2) && defined(CLOCKS_PER_SEC)
  69. #define ANSI_RNG
  70. static unsigned long rng_ansic(unsigned char *buf, unsigned long len,
  71. void (*callback)(void))
  72. {
  73. clock_t t1;
  74. int l, acc, bits, a, b;
  75. if (XCLOCKS_PER_SEC < 100 || XCLOCKS_PER_SEC > 10000) {
  76. return 0;
  77. }
  78. l = len;
  79. bits = 8;
  80. acc = a = b = 0;
  81. while (len--) {
  82. if (callback != NULL) callback();
  83. while (bits--) {
  84. do {
  85. t1 = XCLOCK(); while (t1 == XCLOCK()) a ^= 1;
  86. t1 = XCLOCK(); while (t1 == XCLOCK()) b ^= 1;
  87. } while (a == b);
  88. acc = (acc << 1) | a;
  89. }
  90. *buf++ = acc;
  91. acc = 0;
  92. bits = 8;
  93. }
  94. acc = bits = a = b = 0;
  95. return l;
  96. }
  97. #endif
  98. /* Try the Microsoft CSP */
  99. #ifdef WIN32
  100. #define _WIN32_WINNT 0x0400
  101. #include <windows.h>
  102. #include <wincrypt.h>
  103. static unsigned long rng_win32(unsigned char *buf, unsigned long len,
  104. void (*callback)(void))
  105. {
  106. HCRYPTPROV hProv = 0;
  107. if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL,
  108. (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) &&
  109. !CryptAcquireContext (&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL,
  110. CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET))
  111. return 0;
  112. if (CryptGenRandom(hProv, len, buf) == TRUE) {
  113. CryptReleaseContext(hProv, 0);
  114. return len;
  115. } else {
  116. CryptReleaseContext(hProv, 0);
  117. return 0;
  118. }
  119. }
  120. #endif /* WIN32 */
  121. unsigned long rng_get_bytes(unsigned char *buf, unsigned long len,
  122. void (*callback)(void))
  123. {
  124. unsigned long x;
  125. _ARGCHK(buf != NULL);
  126. #ifdef SONY_PS2
  127. x = rng_ps2(buf, len, callback); if (x != 0) { return x; }
  128. #elif defined(DEVRANDOM)
  129. x = rng_nix(buf, len, callback); if (x != 0) { return x; }
  130. #endif
  131. #ifdef WIN32
  132. x = rng_win32(buf, len, callback); if (x != 0) { return x; }
  133. #endif
  134. #ifdef ANSI_RNG
  135. x = rng_ansic(buf, len, callback); if (x != 0) { return x; }
  136. #endif
  137. return 0;
  138. }
  139. int rng_make_prng(int bits, int wprng, prng_state *prng,
  140. void (*callback)(void))
  141. {
  142. unsigned char buf[256];
  143. int err;
  144. _ARGCHK(prng != NULL);
  145. /* check parameter */
  146. if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
  147. return err;
  148. }
  149. if (bits < 64 || bits > 1024) {
  150. return CRYPT_INVALID_PRNGSIZE;
  151. }
  152. if ((err = prng_descriptor[wprng].start(prng)) != CRYPT_OK) {
  153. return err;
  154. }
  155. bits = ((bits/8)+((bits&7)!=0?1:0)) * 2;
  156. if (rng_get_bytes(buf, (unsigned long)bits, callback) != (unsigned long)bits) {
  157. return CRYPT_ERROR_READPRNG;
  158. }
  159. if ((err = prng_descriptor[wprng].add_entropy(buf, (unsigned long)bits, prng)) != CRYPT_OK) {
  160. return err;
  161. }
  162. if ((err = prng_descriptor[wprng].ready(prng)) != CRYPT_OK) {
  163. return err;
  164. }
  165. #ifdef CLEAN_STACK
  166. zeromem(buf, sizeof(buf));
  167. #endif
  168. return CRYPT_OK;
  169. }