noise.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /*
  2. * Noise generation for PuTTY's cryptographic random number
  3. * generator.
  4. */
  5. #include <windows.h>
  6. #include <stdio.h>
  7. #include "putty.h"
  8. #include "ssh.h"
  9. static char seedpath[2*MAX_PATH+10] = "\0";
  10. /*
  11. * Find the random seed file path and store it in `seedpath'.
  12. */
  13. static void get_seedpath(void) {
  14. HKEY rkey;
  15. DWORD type, size;
  16. size = sizeof(seedpath);
  17. if (RegOpenKey(HKEY_CURRENT_USER, PUTTY_REG_POS, &rkey)==ERROR_SUCCESS) {
  18. int ret = RegQueryValueEx(rkey, "RandSeedFile",
  19. 0, &type, seedpath, &size);
  20. if (ret != ERROR_SUCCESS || type != REG_SZ)
  21. seedpath[0] = '\0';
  22. RegCloseKey(rkey);
  23. } else
  24. seedpath[0] = '\0';
  25. if (!seedpath[0]) {
  26. int len, ret;
  27. len = GetEnvironmentVariable("HOMEDRIVE", seedpath, sizeof(seedpath));
  28. ret = GetEnvironmentVariable("HOMEPATH", seedpath+len,
  29. sizeof(seedpath)-len);
  30. if (ret == 0) { /* probably win95; store in \WINDOWS */
  31. GetWindowsDirectory(seedpath, sizeof(seedpath));
  32. len = strlen(seedpath);
  33. } else
  34. len += ret;
  35. strcpy(seedpath+len, "\\PUTTY.RND");
  36. }
  37. }
  38. /*
  39. * This function is called once, at PuTTY startup, and will do some
  40. * seriously silly things like listing directories and getting disk
  41. * free space and a process snapshot.
  42. */
  43. void noise_get_heavy(void (*func) (void *, int)) {
  44. HANDLE srch;
  45. HANDLE seedf;
  46. WIN32_FIND_DATA finddata;
  47. char winpath[MAX_PATH+3];
  48. GetWindowsDirectory(winpath, sizeof(winpath));
  49. strcat(winpath, "\\*");
  50. srch = FindFirstFile(winpath, &finddata);
  51. if (srch != INVALID_HANDLE_VALUE) {
  52. do {
  53. func(&finddata, sizeof(finddata));
  54. } while (FindNextFile(srch, &finddata));
  55. FindClose(srch);
  56. }
  57. if (!seedpath[0])
  58. get_seedpath();
  59. seedf = CreateFile(seedpath, GENERIC_READ,
  60. FILE_SHARE_READ | FILE_SHARE_WRITE,
  61. NULL, OPEN_EXISTING, 0, NULL);
  62. if (seedf != INVALID_HANDLE_VALUE) {
  63. while (1) {
  64. char buf[1024];
  65. DWORD len;
  66. if (ReadFile(seedf, buf, sizeof(buf), &len, NULL) && len)
  67. func(buf, len);
  68. else
  69. break;
  70. }
  71. CloseHandle(seedf);
  72. }
  73. }
  74. void random_save_seed(void) {
  75. HANDLE seedf;
  76. if (!seedpath[0])
  77. get_seedpath();
  78. seedf = CreateFile(seedpath, GENERIC_WRITE, 0,
  79. NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  80. if (seedf != INVALID_HANDLE_VALUE) {
  81. int len;
  82. DWORD lenwritten;
  83. void *data;
  84. random_get_savedata(&data, &len);
  85. WriteFile(seedf, data, len, &lenwritten, NULL);
  86. CloseHandle(seedf);
  87. }
  88. }
  89. /*
  90. * This function is called every time the random pool needs
  91. * stirring, and will acquire the system time in all available
  92. * forms and the battery status.
  93. */
  94. void noise_get_light(void (*func) (void *, int)) {
  95. SYSTEMTIME systime;
  96. DWORD adjust[2];
  97. BOOL rubbish;
  98. SYSTEM_POWER_STATUS pwrstat;
  99. GetSystemTime(&systime);
  100. func(&systime, sizeof(systime));
  101. GetSystemTimeAdjustment(&adjust[0], &adjust[1], &rubbish);
  102. func(&adjust, sizeof(adjust));
  103. #ifndef WIN32S_COMPAT
  104. if (GetSystemPowerStatus(&pwrstat))
  105. func(&pwrstat, sizeof(pwrstat));
  106. #endif
  107. }
  108. /*
  109. * This function is called on every keypress or mouse move, and
  110. * will add the current Windows time and performance monitor
  111. * counter to the noise pool. It gets the scan code or mouse
  112. * position passed in.
  113. */
  114. void noise_ultralight(DWORD data) {
  115. DWORD wintime;
  116. LARGE_INTEGER perftime;
  117. random_add_noise(&data, sizeof(DWORD));
  118. wintime = GetTickCount();
  119. random_add_noise(&wintime, sizeof(DWORD));
  120. if (QueryPerformanceCounter(&perftime))
  121. random_add_noise(&perftime, sizeof(perftime));
  122. }