33/* LibTomMath, multiple-precision integer library -- Tom St Denis */
44/* SPDX-License-Identifier: Unlicense */
55
6- /* First the OS-specific special cases
7- * - *BSD
8- * - Windows
9- */
10- #if defined(__FreeBSD__ ) || defined(__OpenBSD__ ) || defined(__NetBSD__ ) || defined(__DragonFly__ )
11- # define MP_ARC4RANDOM
12- #endif
13-
14- #if defined(_WIN32 ) || defined(_WIN32_WCE )
15- #define MP_WIN_CSP
16-
17- #ifndef _WIN32_WINNT
18- #define _WIN32_WINNT 0x0400
19- #endif
20- #ifdef _WIN32_WCE
21- #define UNDER_CE
22- #define ARM
23- #endif
24-
25- #define WIN32_LEAN_AND_MEAN
26- #include <windows.h>
27- #include <wincrypt.h>
28-
29- static HCRYPTPROV hProv = 0 ;
30-
31- static void s_cleanup_win_csp (void )
32- {
33- CryptReleaseContext (hProv , 0 );
34- hProv = 0 ;
35- }
36-
37- static int s_read_win_csp (void * p , size_t n )
38- {
39- if (hProv == 0 ) {
40- if (!CryptAcquireContext (& hProv , NULL , MS_DEF_PROV , PROV_RSA_FULL ,
41- (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET )) &&
42- !CryptAcquireContext (& hProv , NULL , MS_DEF_PROV , PROV_RSA_FULL ,
43- CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET )) {
44- hProv = 0 ;
45- return MP_ERR ;
46- }
47- atexit (s_cleanup_win_csp );
48- }
49- return CryptGenRandom (hProv , (DWORD )n , (BYTE * )p ) == TRUE ? MP_OKAY : MP_ERR ;
50- }
51- #endif /* WIN32 */
52-
53- #if !defined(MP_WIN_CSP ) && defined(__linux__ ) && defined(__GLIBC_PREREQ )
54- #if __GLIBC_PREREQ (2 , 25 )
55- #define MP_GETRANDOM
56- #include <sys/random.h>
57- #include <errno.h>
58-
59- static int s_read_getrandom (void * p , size_t n )
60- {
61- char * q = (char * )p ;
62- while (n > 0 ) {
63- ssize_t ret = getrandom (q , n , 0 );
64- if (ret < 0 ) {
65- if (errno == EINTR ) {
66- continue ;
67- }
68- return MP_ERR ;
69- }
70- q += ret ;
71- n -= (size_t )ret ;
72- }
73- return MP_OKAY ;
74- }
75- #endif
76- #endif
77-
78- /* We assume all platforms besides windows provide "/dev/urandom".
79- * In case yours doesn't, define MP_NO_DEV_URANDOM at compile-time.
80- */
81- #if !defined(MP_WIN_CSP ) && !defined(MP_NO_DEV_URANDOM )
82- #ifndef MP_DEV_URANDOM
83- #define MP_DEV_URANDOM "/dev/urandom"
84- #endif
85- #include <fcntl.h>
86- #include <errno.h>
87- #include <unistd.h>
88-
89- static int s_read_dev_urandom (void * p , size_t n )
90- {
91- int fd ;
92- char * q = (char * )p ;
93-
94- do {
95- fd = open (MP_DEV_URANDOM , O_RDONLY );
96- } while ((fd == -1 ) && (errno == EINTR ));
97- if (fd == -1 ) return MP_ERR ;
98-
99- while (n > 0 ) {
100- ssize_t ret = read (fd , p , n );
101- if (ret < 0 ) {
102- if (errno == EINTR ) {
103- continue ;
104- }
105- close (fd );
106- return MP_ERR ;
107- }
108- q += ret ;
109- n -= (size_t )ret ;
110- }
111-
112- close (fd );
113- return MP_OKAY ;
114- }
115- #endif
116-
117- #if defined(MP_PRNG_ENABLE_LTM_RNG )
118- unsigned long (* ltm_rng )(unsigned char * out , unsigned long outlen , void (* callback )(void ));
119- void (* ltm_rng_callback )(void );
120-
121- static int s_read_ltm_rng (void * p , size_t n )
122- {
123- unsigned long ret ;
124- if (ltm_rng == NULL ) return MP_ERR ;
125- ret = ltm_rng (p , n , ltm_rng_callback );
126- if (ret != n ) return MP_ERR ;
127- return MP_OKAY ;
128- }
129- #endif
130-
131- static int s_mp_rand_source_platform (void * p , size_t n )
132- {
133- #if defined(MP_ARC4RANDOM )
134- arc4random_buf (p , n );
135- return MP_OKAY ;
136- #else
137-
138- int ret = MP_ERR ;
139-
140- #if defined(MP_WIN_CSP )
141- ret = s_read_win_csp (p , n );
142- if (ret == MP_OKAY ) return ret ;
143- #endif
144-
145- #if defined(MP_GETRANDOM )
146- ret = s_read_getrandom (p , n );
147- if (ret == MP_OKAY ) return ret ;
148- #endif
149-
150- #if defined(MP_DEV_URANDOM )
151- ret = s_read_dev_urandom (p , n );
152- if (ret == MP_OKAY ) return ret ;
153- #endif
154-
155- #if defined(MP_PRNG_ENABLE_LTM_RNG )
156- ret = s_read_ltm_rng (p , n );
157- if (ret == MP_OKAY ) return ret ;
158- #endif
159-
160- return ret ;
161- #endif
162- }
163-
164- int (* s_rand_source )(void * out , size_t size ) = s_mp_rand_source_platform ;
6+ int (* s_mp_rand_source )(void * , size_t ) = s_mp_rand_platform ;
1657
1668void mp_rand_source (int (* source )(void * out , size_t size ))
1679{
168- s_rand_source = (source == NULL ) ? s_mp_rand_source_platform : source ;
10+ s_mp_rand_source = (source == NULL ) ? s_mp_rand_platform : source ;
16911}
17012
17113/* makes a pseudo-random int of a given size */
17214int mp_rand_digit (mp_digit * r )
17315{
174- int ret = s_rand_source (r , sizeof (mp_digit ));
16+ int ret = s_mp_rand_source (r , sizeof (mp_digit ));
17517 * r &= MP_MASK ;
17618 return ret ;
17719}
@@ -190,13 +32,13 @@ int mp_rand(mp_int *a, int digits)
19032 return ret ;
19133 }
19234
193- if ((ret = s_rand_source (a -> dp , (size_t )digits * sizeof (mp_digit ))) != MP_OKAY ) {
35+ if ((ret = s_mp_rand_source (a -> dp , (size_t )digits * sizeof (mp_digit ))) != MP_OKAY ) {
19436 return ret ;
19537 }
19638
19739 /* TODO: We ensure that the highest digit is nonzero. Should this be removed? */
19840 while ((a -> dp [digits - 1 ] & MP_MASK ) == 0 ) {
199- if ((ret = s_rand_source (a -> dp + digits - 1 , sizeof (mp_digit ))) != MP_OKAY ) {
41+ if ((ret = s_mp_rand_source (a -> dp + digits - 1 , sizeof (mp_digit ))) != MP_OKAY ) {
20042 return ret ;
20143 }
20244 }
0 commit comments