rand_vms.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
  1. /*
  2. * Copyright 2001-2022 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include "internal/e_os.h"
  10. #define __NEW_STARLET 1 /* New starlet definitions since VMS 7.0 */
  11. #include <unistd.h>
  12. #include "internal/cryptlib.h"
  13. #include <openssl/rand.h>
  14. #include "crypto/rand.h"
  15. #include "crypto/rand_pool.h"
  16. #include "prov/seeding.h"
  17. #include <descrip.h>
  18. #include <dvidef.h>
  19. #include <jpidef.h>
  20. #include <rmidef.h>
  21. #include <syidef.h>
  22. #include <ssdef.h>
  23. #include <starlet.h>
  24. #include <efndef.h>
  25. #include <gen64def.h>
  26. #include <iosbdef.h>
  27. #include <iledef.h>
  28. #include <lib$routines.h>
  29. #ifdef __DECC
  30. # pragma message disable DOLLARID
  31. #endif
  32. #include <dlfcn.h> /* SYS$GET_ENTROPY presence */
  33. #ifndef OPENSSL_RAND_SEED_OS
  34. # error "Unsupported seeding method configured; must be os"
  35. #endif
  36. /*
  37. * DATA COLLECTION METHOD
  38. * ======================
  39. *
  40. * This is a method to get low quality entropy.
  41. * It works by collecting all kinds of statistical data that
  42. * VMS offers and using them as random seed.
  43. */
  44. /* We need to make sure we have the right size pointer in some cases */
  45. #if __INITIAL_POINTER_SIZE == 64
  46. # pragma pointer_size save
  47. # pragma pointer_size 32
  48. #endif
  49. typedef uint32_t *uint32_t__ptr32;
  50. #if __INITIAL_POINTER_SIZE == 64
  51. # pragma pointer_size restore
  52. #endif
  53. struct item_st {
  54. short length, code; /* length is number of bytes */
  55. };
  56. static const struct item_st DVI_item_data[] = {
  57. {4, DVI$_ERRCNT},
  58. {4, DVI$_REFCNT},
  59. };
  60. static const struct item_st JPI_item_data[] = {
  61. {4, JPI$_BUFIO},
  62. {4, JPI$_CPUTIM},
  63. {4, JPI$_DIRIO},
  64. {4, JPI$_IMAGECOUNT},
  65. {4, JPI$_PAGEFLTS},
  66. {4, JPI$_PID},
  67. {4, JPI$_PPGCNT},
  68. {4, JPI$_WSPEAK},
  69. /*
  70. * Note: the direct result is just a 32-bit address. However, it points
  71. * to a list of 4 32-bit words, so we make extra space for them so we can
  72. * do in-place replacement of values
  73. */
  74. {16, JPI$_FINALEXC},
  75. };
  76. static const struct item_st JPI_item_data_64bit[] = {
  77. {8, JPI$_LAST_LOGIN_I},
  78. {8, JPI$_LOGINTIM},
  79. };
  80. static const struct item_st RMI_item_data[] = {
  81. {4, RMI$_COLPG},
  82. {4, RMI$_MWAIT},
  83. {4, RMI$_CEF},
  84. {4, RMI$_PFW},
  85. {4, RMI$_LEF},
  86. {4, RMI$_LEFO},
  87. {4, RMI$_HIB},
  88. {4, RMI$_HIBO},
  89. {4, RMI$_SUSP},
  90. {4, RMI$_SUSPO},
  91. {4, RMI$_FPG},
  92. {4, RMI$_COM},
  93. {4, RMI$_COMO},
  94. {4, RMI$_CUR},
  95. #if defined __alpha
  96. {4, RMI$_FRLIST},
  97. {4, RMI$_MODLIST},
  98. #endif
  99. {4, RMI$_FAULTS},
  100. {4, RMI$_PREADS},
  101. {4, RMI$_PWRITES},
  102. {4, RMI$_PWRITIO},
  103. {4, RMI$_PREADIO},
  104. {4, RMI$_GVALFLTS},
  105. {4, RMI$_WRTINPROG},
  106. {4, RMI$_FREFLTS},
  107. {4, RMI$_DZROFLTS},
  108. {4, RMI$_SYSFAULTS},
  109. {4, RMI$_ISWPCNT},
  110. {4, RMI$_DIRIO},
  111. {4, RMI$_BUFIO},
  112. {4, RMI$_MBREADS},
  113. {4, RMI$_MBWRITES},
  114. {4, RMI$_LOGNAM},
  115. {4, RMI$_FCPCALLS},
  116. {4, RMI$_FCPREAD},
  117. {4, RMI$_FCPWRITE},
  118. {4, RMI$_FCPCACHE},
  119. {4, RMI$_FCPCPU},
  120. {4, RMI$_FCPHIT},
  121. {4, RMI$_FCPSPLIT},
  122. {4, RMI$_FCPFAULT},
  123. {4, RMI$_ENQNEW},
  124. {4, RMI$_ENQCVT},
  125. {4, RMI$_DEQ},
  126. {4, RMI$_BLKAST},
  127. {4, RMI$_ENQWAIT},
  128. {4, RMI$_ENQNOTQD},
  129. {4, RMI$_DLCKSRCH},
  130. {4, RMI$_DLCKFND},
  131. {4, RMI$_NUMLOCKS},
  132. {4, RMI$_NUMRES},
  133. {4, RMI$_ARRLOCPK},
  134. {4, RMI$_DEPLOCPK},
  135. {4, RMI$_ARRTRAPK},
  136. {4, RMI$_TRCNGLOS},
  137. {4, RMI$_RCVBUFFL},
  138. {4, RMI$_ENQNEWLOC},
  139. {4, RMI$_ENQNEWIN},
  140. {4, RMI$_ENQNEWOUT},
  141. {4, RMI$_ENQCVTLOC},
  142. {4, RMI$_ENQCVTIN},
  143. {4, RMI$_ENQCVTOUT},
  144. {4, RMI$_DEQLOC},
  145. {4, RMI$_DEQIN},
  146. {4, RMI$_DEQOUT},
  147. {4, RMI$_BLKLOC},
  148. {4, RMI$_BLKIN},
  149. {4, RMI$_BLKOUT},
  150. {4, RMI$_DIRIN},
  151. {4, RMI$_DIROUT},
  152. /* We currently get a fault when trying these */
  153. #if 0
  154. {140, RMI$_MSCP_EVERYTHING}, /* 35 32-bit words */
  155. {152, RMI$_DDTM_ALL}, /* 38 32-bit words */
  156. {80, RMI$_TMSCP_EVERYTHING} /* 20 32-bit words */
  157. #endif
  158. {4, RMI$_LPZ_PAGCNT},
  159. {4, RMI$_LPZ_HITS},
  160. {4, RMI$_LPZ_MISSES},
  161. {4, RMI$_LPZ_EXPCNT},
  162. {4, RMI$_LPZ_ALLOCF},
  163. {4, RMI$_LPZ_ALLOC2},
  164. {4, RMI$_ACCESS},
  165. {4, RMI$_ALLOC},
  166. {4, RMI$_FCPCREATE},
  167. {4, RMI$_VOLWAIT},
  168. {4, RMI$_FCPTURN},
  169. {4, RMI$_FCPERASE},
  170. {4, RMI$_OPENS},
  171. {4, RMI$_FIDHIT},
  172. {4, RMI$_FIDMISS},
  173. {4, RMI$_FILHDR_HIT},
  174. {4, RMI$_DIRFCB_HIT},
  175. {4, RMI$_DIRFCB_MISS},
  176. {4, RMI$_DIRDATA_HIT},
  177. {4, RMI$_EXTHIT},
  178. {4, RMI$_EXTMISS},
  179. {4, RMI$_QUOHIT},
  180. {4, RMI$_QUOMISS},
  181. {4, RMI$_STORAGMAP_HIT},
  182. {4, RMI$_VOLLCK},
  183. {4, RMI$_SYNCHLCK},
  184. {4, RMI$_SYNCHWAIT},
  185. {4, RMI$_ACCLCK},
  186. {4, RMI$_XQPCACHEWAIT},
  187. {4, RMI$_DIRDATA_MISS},
  188. {4, RMI$_FILHDR_MISS},
  189. {4, RMI$_STORAGMAP_MISS},
  190. {4, RMI$_PROCCNTMAX},
  191. {4, RMI$_PROCBATCNT},
  192. {4, RMI$_PROCINTCNT},
  193. {4, RMI$_PROCNETCNT},
  194. {4, RMI$_PROCSWITCHCNT},
  195. {4, RMI$_PROCBALSETCNT},
  196. {4, RMI$_PROCLOADCNT},
  197. {4, RMI$_BADFLTS},
  198. {4, RMI$_EXEFAULTS},
  199. {4, RMI$_HDRINSWAPS},
  200. {4, RMI$_HDROUTSWAPS},
  201. {4, RMI$_IOPAGCNT},
  202. {4, RMI$_ISWPCNTPG},
  203. {4, RMI$_OSWPCNT},
  204. {4, RMI$_OSWPCNTPG},
  205. {4, RMI$_RDFAULTS},
  206. {4, RMI$_TRANSFLTS},
  207. {4, RMI$_WRTFAULTS},
  208. #if defined __alpha
  209. {4, RMI$_USERPAGES},
  210. #endif
  211. {4, RMI$_VMSPAGES},
  212. {4, RMI$_TTWRITES},
  213. {4, RMI$_BUFOBJPAG},
  214. {4, RMI$_BUFOBJPAGPEAK},
  215. {4, RMI$_BUFOBJPAGS01},
  216. {4, RMI$_BUFOBJPAGS2},
  217. {4, RMI$_BUFOBJPAGMAXS01},
  218. {4, RMI$_BUFOBJPAGMAXS2},
  219. {4, RMI$_BUFOBJPAGPEAKS01},
  220. {4, RMI$_BUFOBJPAGPEAKS2},
  221. {4, RMI$_BUFOBJPGLTMAXS01},
  222. {4, RMI$_BUFOBJPGLTMAXS2},
  223. {4, RMI$_DLCK_INCMPLT},
  224. {4, RMI$_DLCKMSGS_IN},
  225. {4, RMI$_DLCKMSGS_OUT},
  226. {4, RMI$_MCHKERRS},
  227. {4, RMI$_MEMERRS},
  228. };
  229. static const struct item_st RMI_item_data_64bit[] = {
  230. #if defined __ia64
  231. {8, RMI$_FRLIST},
  232. {8, RMI$_MODLIST},
  233. #endif
  234. {8, RMI$_LCKMGR_REQCNT},
  235. {8, RMI$_LCKMGR_REQTIME},
  236. {8, RMI$_LCKMGR_SPINCNT},
  237. {8, RMI$_LCKMGR_SPINTIME},
  238. {8, RMI$_CPUINTSTK},
  239. {8, RMI$_CPUMPSYNCH},
  240. {8, RMI$_CPUKERNEL},
  241. {8, RMI$_CPUEXEC},
  242. {8, RMI$_CPUSUPER},
  243. {8, RMI$_CPUUSER},
  244. #if defined __ia64
  245. {8, RMI$_USERPAGES},
  246. #endif
  247. {8, RMI$_TQETOTAL},
  248. {8, RMI$_TQESYSUB},
  249. {8, RMI$_TQEUSRTIMR},
  250. {8, RMI$_TQEUSRWAKE},
  251. };
  252. static const struct item_st SYI_item_data[] = {
  253. {4, SYI$_PAGEFILE_FREE},
  254. };
  255. /*
  256. * Input:
  257. * items_data - an array of lengths and codes
  258. * items_data_num - number of elements in that array
  259. *
  260. * Output:
  261. * items - pre-allocated ILE3 array to be filled.
  262. * It's assumed to have items_data_num elements plus
  263. * one extra for the terminating NULL element
  264. * databuffer - pre-allocated 32-bit word array.
  265. *
  266. * Returns the number of elements used in databuffer
  267. */
  268. static size_t prepare_item_list(const struct item_st *items_input,
  269. size_t items_input_num,
  270. ILE3 *items,
  271. uint32_t__ptr32 databuffer)
  272. {
  273. size_t data_sz = 0;
  274. for (; items_input_num-- > 0; items_input++, items++) {
  275. items->ile3$w_code = items_input->code;
  276. /* Special treatment of JPI$_FINALEXC */
  277. if (items->ile3$w_code == JPI$_FINALEXC)
  278. items->ile3$w_length = 4;
  279. else
  280. items->ile3$w_length = items_input->length;
  281. items->ile3$ps_bufaddr = databuffer;
  282. items->ile3$ps_retlen_addr = 0;
  283. databuffer += items_input->length / sizeof(databuffer[0]);
  284. data_sz += items_input->length;
  285. }
  286. /* Terminating NULL entry */
  287. items->ile3$w_length = items->ile3$w_code = 0;
  288. items->ile3$ps_bufaddr = items->ile3$ps_retlen_addr = NULL;
  289. return data_sz / sizeof(databuffer[0]);
  290. }
  291. static void massage_JPI(ILE3 *items)
  292. {
  293. /*
  294. * Special treatment of JPI$_FINALEXC
  295. * The result of that item's data buffer is a 32-bit address to a list of
  296. * 4 32-bit words.
  297. */
  298. for (; items->ile3$w_length != 0; items++) {
  299. if (items->ile3$w_code == JPI$_FINALEXC) {
  300. uint32_t *data = items->ile3$ps_bufaddr;
  301. uint32_t *ptr = (uint32_t *)*data;
  302. size_t j;
  303. /*
  304. * We know we made space for 4 32-bit words, so we can do in-place
  305. * replacement.
  306. */
  307. for (j = 0; j < 4; j++)
  308. data[j] = ptr[j];
  309. break;
  310. }
  311. }
  312. }
  313. /*
  314. * This number expresses how many bits of data contain 1 bit of entropy.
  315. *
  316. * For the moment, we assume about 0.05 entropy bits per data bit, or 1
  317. * bit of entropy per 20 data bits.
  318. */
  319. #define ENTROPY_FACTOR 20
  320. size_t data_collect_method(RAND_POOL *pool)
  321. {
  322. ILE3 JPI_items_64bit[OSSL_NELEM(JPI_item_data_64bit) + 1];
  323. ILE3 RMI_items_64bit[OSSL_NELEM(RMI_item_data_64bit) + 1];
  324. ILE3 DVI_items[OSSL_NELEM(DVI_item_data) + 1];
  325. ILE3 JPI_items[OSSL_NELEM(JPI_item_data) + 1];
  326. ILE3 RMI_items[OSSL_NELEM(RMI_item_data) + 1];
  327. ILE3 SYI_items[OSSL_NELEM(SYI_item_data) + 1];
  328. union {
  329. /* This ensures buffer starts at 64 bit boundary */
  330. uint64_t dummy;
  331. uint32_t buffer[OSSL_NELEM(JPI_item_data_64bit) * 2
  332. + OSSL_NELEM(RMI_item_data_64bit) * 2
  333. + OSSL_NELEM(DVI_item_data)
  334. + OSSL_NELEM(JPI_item_data)
  335. + OSSL_NELEM(RMI_item_data)
  336. + OSSL_NELEM(SYI_item_data)
  337. + 4 /* For JPI$_FINALEXC */];
  338. } data;
  339. size_t total_elems = 0;
  340. size_t total_length = 0;
  341. size_t bytes_needed = ossl_rand_pool_bytes_needed(pool, ENTROPY_FACTOR);
  342. size_t bytes_remaining = ossl_rand_pool_bytes_remaining(pool);
  343. /* Take all the 64-bit items first, to ensure proper alignment of data */
  344. total_elems +=
  345. prepare_item_list(JPI_item_data_64bit, OSSL_NELEM(JPI_item_data_64bit),
  346. JPI_items_64bit, &data.buffer[total_elems]);
  347. total_elems +=
  348. prepare_item_list(RMI_item_data_64bit, OSSL_NELEM(RMI_item_data_64bit),
  349. RMI_items_64bit, &data.buffer[total_elems]);
  350. /* Now the 32-bit items */
  351. total_elems += prepare_item_list(DVI_item_data, OSSL_NELEM(DVI_item_data),
  352. DVI_items, &data.buffer[total_elems]);
  353. total_elems += prepare_item_list(JPI_item_data, OSSL_NELEM(JPI_item_data),
  354. JPI_items, &data.buffer[total_elems]);
  355. total_elems += prepare_item_list(RMI_item_data, OSSL_NELEM(RMI_item_data),
  356. RMI_items, &data.buffer[total_elems]);
  357. total_elems += prepare_item_list(SYI_item_data, OSSL_NELEM(SYI_item_data),
  358. SYI_items, &data.buffer[total_elems]);
  359. total_length = total_elems * sizeof(data.buffer[0]);
  360. /* Fill data.buffer with various info bits from this process */
  361. {
  362. uint32_t status;
  363. uint32_t efn;
  364. IOSB iosb;
  365. $DESCRIPTOR(SYSDEVICE, "SYS$SYSDEVICE:");
  366. if ((status = sys$getdviw(EFN$C_ENF, 0, &SYSDEVICE, DVI_items,
  367. 0, 0, 0, 0, 0)) != SS$_NORMAL) {
  368. lib$signal(status);
  369. return 0;
  370. }
  371. if ((status = sys$getjpiw(EFN$C_ENF, 0, 0, JPI_items_64bit, 0, 0, 0))
  372. != SS$_NORMAL) {
  373. lib$signal(status);
  374. return 0;
  375. }
  376. if ((status = sys$getjpiw(EFN$C_ENF, 0, 0, JPI_items, 0, 0, 0))
  377. != SS$_NORMAL) {
  378. lib$signal(status);
  379. return 0;
  380. }
  381. if ((status = sys$getsyiw(EFN$C_ENF, 0, 0, SYI_items, 0, 0, 0))
  382. != SS$_NORMAL) {
  383. lib$signal(status);
  384. return 0;
  385. }
  386. /*
  387. * The RMI service is a bit special, as there is no synchronous
  388. * variant, so we MUST create an event flag to synchronise on.
  389. */
  390. if ((status = lib$get_ef(&efn)) != SS$_NORMAL) {
  391. lib$signal(status);
  392. return 0;
  393. }
  394. if ((status = sys$getrmi(efn, 0, 0, RMI_items_64bit, &iosb, 0, 0))
  395. != SS$_NORMAL) {
  396. lib$signal(status);
  397. return 0;
  398. }
  399. if ((status = sys$synch(efn, &iosb)) != SS$_NORMAL) {
  400. lib$signal(status);
  401. return 0;
  402. }
  403. if (iosb.iosb$l_getxxi_status != SS$_NORMAL) {
  404. lib$signal(iosb.iosb$l_getxxi_status);
  405. return 0;
  406. }
  407. if ((status = sys$getrmi(efn, 0, 0, RMI_items, &iosb, 0, 0))
  408. != SS$_NORMAL) {
  409. lib$signal(status);
  410. return 0;
  411. }
  412. if ((status = sys$synch(efn, &iosb)) != SS$_NORMAL) {
  413. lib$signal(status);
  414. return 0;
  415. }
  416. if (iosb.iosb$l_getxxi_status != SS$_NORMAL) {
  417. lib$signal(iosb.iosb$l_getxxi_status);
  418. return 0;
  419. }
  420. if ((status = lib$free_ef(&efn)) != SS$_NORMAL) {
  421. lib$signal(status);
  422. return 0;
  423. }
  424. }
  425. massage_JPI(JPI_items);
  426. /*
  427. * If we can't feed the requirements from the caller, we're in deep trouble.
  428. */
  429. if (!ossl_assert(total_length >= bytes_needed)) {
  430. ERR_raise_data(ERR_LIB_RAND, RAND_R_RANDOM_POOL_UNDERFLOW,
  431. "Needed: %zu, Available: %zu",
  432. bytes_needed, total_length);
  433. return 0;
  434. }
  435. /*
  436. * Try not to overfeed the pool
  437. */
  438. if (total_length > bytes_remaining)
  439. total_length = bytes_remaining;
  440. /* We give the pessimistic value for the amount of entropy */
  441. ossl_rand_pool_add(pool, (unsigned char *)data.buffer, total_length,
  442. 8 * total_length / ENTROPY_FACTOR);
  443. return ossl_rand_pool_entropy_available(pool);
  444. }
  445. int ossl_pool_add_nonce_data(RAND_POOL *pool)
  446. {
  447. struct {
  448. pid_t pid;
  449. CRYPTO_THREAD_ID tid;
  450. unsigned __int64 time;
  451. } data;
  452. /* Erase the entire structure including any padding */
  453. memset(&data, 0, sizeof(data));
  454. /*
  455. * Add process id, thread id, and a high resolution timestamp
  456. * (where available, which is OpenVMS v8.4 and up) to ensure that
  457. * the nonce is unique with high probability for different process
  458. * instances.
  459. */
  460. data.pid = getpid();
  461. data.tid = CRYPTO_THREAD_get_current_id();
  462. #if __CRTL_VER >= 80400000
  463. sys$gettim_prec(&data.time);
  464. #else
  465. sys$gettim((void*)&data.time);
  466. #endif
  467. return ossl_rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0);
  468. }
  469. /*
  470. * SYS$GET_ENTROPY METHOD
  471. * ======================
  472. *
  473. * This is a high entropy method based on a new system service that is
  474. * based on getentropy() from FreeBSD 12. It's only used if available,
  475. * and its availability is detected at run-time.
  476. *
  477. * We assume that this function provides full entropy random output.
  478. */
  479. #define PUBLIC_VECTORS "SYS$LIBRARY:SYS$PUBLIC_VECTORS.EXE"
  480. #define GET_ENTROPY "SYS$GET_ENTROPY"
  481. static int get_entropy_address_flag = 0;
  482. static int (*get_entropy_address)(void *buffer, size_t buffer_size) = NULL;
  483. static int init_get_entropy_address(void)
  484. {
  485. if (get_entropy_address_flag == 0)
  486. get_entropy_address = dlsym(dlopen(PUBLIC_VECTORS, 0), GET_ENTROPY);
  487. get_entropy_address_flag = 1;
  488. return get_entropy_address != NULL;
  489. }
  490. size_t get_entropy_method(RAND_POOL *pool)
  491. {
  492. /*
  493. * The documentation says that SYS$GET_ENTROPY will give a maximum of
  494. * 256 bytes of data.
  495. */
  496. unsigned char buffer[256];
  497. size_t bytes_needed;
  498. size_t bytes_to_get = 0;
  499. uint32_t status;
  500. for (bytes_needed = ossl_rand_pool_bytes_needed(pool, 1);
  501. bytes_needed > 0;
  502. bytes_needed -= bytes_to_get) {
  503. bytes_to_get =
  504. bytes_needed > sizeof(buffer) ? sizeof(buffer) : bytes_needed;
  505. status = get_entropy_address(buffer, bytes_to_get);
  506. if (status == SS$_RETRY) {
  507. /* Set to zero so the loop doesn't diminish |bytes_needed| */
  508. bytes_to_get = 0;
  509. /* Should sleep some amount of time */
  510. continue;
  511. }
  512. if (status != SS$_NORMAL) {
  513. lib$signal(status);
  514. return 0;
  515. }
  516. ossl_rand_pool_add(pool, buffer, bytes_to_get, 8 * bytes_to_get);
  517. }
  518. return ossl_rand_pool_entropy_available(pool);
  519. }
  520. /*
  521. * MAIN ENTROPY ACQUISITION FUNCTIONS
  522. * ==================================
  523. *
  524. * These functions are called by the RAND / DRBG functions
  525. */
  526. size_t ossl_pool_acquire_entropy(RAND_POOL *pool)
  527. {
  528. if (init_get_entropy_address())
  529. return get_entropy_method(pool);
  530. return data_collect_method(pool);
  531. }
  532. int ossl_rand_pool_add_additional_data(RAND_POOL *pool)
  533. {
  534. struct {
  535. CRYPTO_THREAD_ID tid;
  536. unsigned __int64 time;
  537. } data;
  538. /* Erase the entire structure including any padding */
  539. memset(&data, 0, sizeof(data));
  540. /*
  541. * Add some noise from the thread id and a high resolution timer.
  542. * The thread id adds a little randomness if the drbg is accessed
  543. * concurrently (which is the case for the <master> drbg).
  544. */
  545. data.tid = CRYPTO_THREAD_get_current_id();
  546. #if __CRTL_VER >= 80400000
  547. sys$gettim_prec(&data.time);
  548. #else
  549. sys$gettim((void*)&data.time);
  550. #endif
  551. return ossl_rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0);
  552. }
  553. int ossl_rand_pool_init(void)
  554. {
  555. return 1;
  556. }
  557. void ossl_rand_pool_cleanup(void)
  558. {
  559. }
  560. void ossl_rand_pool_keep_random_devices_open(int keep)
  561. {
  562. }