rand_vms.c 18 KB

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