Mercurial > dropbear
comparison libtommath/bn_s_mp_rand_platform.c @ 1692:1051e4eea25a
Update LibTomMath to 1.2.0 (#84)
* update C files
* update other files
* update headers
* update makefiles
* remove mp_set/get_double()
* use ltm 1.2.0 API
* update ltm_desc
* use bundled tommath if system-tommath is too old
* XMALLOC etc. were changed to MP_MALLOC etc.
author | Steffen Jaeckel <s@jaeckel.eu> |
---|---|
date | Tue, 26 May 2020 17:36:47 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1691:2d3745d58843 | 1692:1051e4eea25a |
---|---|
1 #include "tommath_private.h" | |
2 #ifdef BN_S_MP_RAND_PLATFORM_C | |
3 /* LibTomMath, multiple-precision integer library -- Tom St Denis */ | |
4 /* SPDX-License-Identifier: Unlicense */ | |
5 | |
6 /* First the OS-specific special cases | |
7 * - *BSD | |
8 * - Windows | |
9 */ | |
10 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) | |
11 #define BN_S_READ_ARC4RANDOM_C | |
12 static mp_err s_read_arc4random(void *p, size_t n) | |
13 { | |
14 arc4random_buf(p, n); | |
15 return MP_OKAY; | |
16 } | |
17 #endif | |
18 | |
19 #if defined(_WIN32) || defined(_WIN32_WCE) | |
20 #define BN_S_READ_WINCSP_C | |
21 | |
22 #ifndef _WIN32_WINNT | |
23 #define _WIN32_WINNT 0x0400 | |
24 #endif | |
25 #ifdef _WIN32_WCE | |
26 #define UNDER_CE | |
27 #define ARM | |
28 #endif | |
29 | |
30 #define WIN32_LEAN_AND_MEAN | |
31 #include <windows.h> | |
32 #include <wincrypt.h> | |
33 | |
34 static mp_err s_read_wincsp(void *p, size_t n) | |
35 { | |
36 static HCRYPTPROV hProv = 0; | |
37 if (hProv == 0) { | |
38 HCRYPTPROV h = 0; | |
39 if (!CryptAcquireContext(&h, NULL, MS_DEF_PROV, PROV_RSA_FULL, | |
40 (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) && | |
41 !CryptAcquireContext(&h, NULL, MS_DEF_PROV, PROV_RSA_FULL, | |
42 CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET)) { | |
43 return MP_ERR; | |
44 } | |
45 hProv = h; | |
46 } | |
47 return CryptGenRandom(hProv, (DWORD)n, (BYTE *)p) == TRUE ? MP_OKAY : MP_ERR; | |
48 } | |
49 #endif /* WIN32 */ | |
50 | |
51 #if !defined(BN_S_READ_WINCSP_C) && defined(__linux__) && defined(__GLIBC_PREREQ) | |
52 #if __GLIBC_PREREQ(2, 25) | |
53 #define BN_S_READ_GETRANDOM_C | |
54 #include <sys/random.h> | |
55 #include <errno.h> | |
56 | |
57 static mp_err s_read_getrandom(void *p, size_t n) | |
58 { | |
59 char *q = (char *)p; | |
60 while (n > 0u) { | |
61 ssize_t ret = getrandom(q, n, 0); | |
62 if (ret < 0) { | |
63 if (errno == EINTR) { | |
64 continue; | |
65 } | |
66 return MP_ERR; | |
67 } | |
68 q += ret; | |
69 n -= (size_t)ret; | |
70 } | |
71 return MP_OKAY; | |
72 } | |
73 #endif | |
74 #endif | |
75 | |
76 /* We assume all platforms besides windows provide "/dev/urandom". | |
77 * In case yours doesn't, define MP_NO_DEV_URANDOM at compile-time. | |
78 */ | |
79 #if !defined(BN_S_READ_WINCSP_C) && !defined(MP_NO_DEV_URANDOM) | |
80 #define BN_S_READ_URANDOM_C | |
81 #ifndef MP_DEV_URANDOM | |
82 #define MP_DEV_URANDOM "/dev/urandom" | |
83 #endif | |
84 #include <fcntl.h> | |
85 #include <errno.h> | |
86 #include <unistd.h> | |
87 | |
88 static mp_err s_read_urandom(void *p, size_t n) | |
89 { | |
90 int fd; | |
91 char *q = (char *)p; | |
92 | |
93 do { | |
94 fd = open(MP_DEV_URANDOM, O_RDONLY); | |
95 } while ((fd == -1) && (errno == EINTR)); | |
96 if (fd == -1) return MP_ERR; | |
97 | |
98 while (n > 0u) { | |
99 ssize_t ret = read(fd, p, n); | |
100 if (ret < 0) { | |
101 if (errno == EINTR) { | |
102 continue; | |
103 } | |
104 close(fd); | |
105 return MP_ERR; | |
106 } | |
107 q += ret; | |
108 n -= (size_t)ret; | |
109 } | |
110 | |
111 close(fd); | |
112 return MP_OKAY; | |
113 } | |
114 #endif | |
115 | |
116 #if defined(MP_PRNG_ENABLE_LTM_RNG) | |
117 #define BN_S_READ_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 mp_err s_read_ltm_rng(void *p, size_t n) | |
122 { | |
123 unsigned long res; | |
124 if (ltm_rng == NULL) return MP_ERR; | |
125 res = ltm_rng(p, n, ltm_rng_callback); | |
126 if (res != n) return MP_ERR; | |
127 return MP_OKAY; | |
128 } | |
129 #endif | |
130 | |
131 mp_err s_read_arc4random(void *p, size_t n); | |
132 mp_err s_read_wincsp(void *p, size_t n); | |
133 mp_err s_read_getrandom(void *p, size_t n); | |
134 mp_err s_read_urandom(void *p, size_t n); | |
135 mp_err s_read_ltm_rng(void *p, size_t n); | |
136 | |
137 mp_err s_mp_rand_platform(void *p, size_t n) | |
138 { | |
139 mp_err err = MP_ERR; | |
140 if ((err != MP_OKAY) && MP_HAS(S_READ_ARC4RANDOM)) err = s_read_arc4random(p, n); | |
141 if ((err != MP_OKAY) && MP_HAS(S_READ_WINCSP)) err = s_read_wincsp(p, n); | |
142 if ((err != MP_OKAY) && MP_HAS(S_READ_GETRANDOM)) err = s_read_getrandom(p, n); | |
143 if ((err != MP_OKAY) && MP_HAS(S_READ_URANDOM)) err = s_read_urandom(p, n); | |
144 if ((err != MP_OKAY) && MP_HAS(S_READ_LTM_RNG)) err = s_read_ltm_rng(p, n); | |
145 return err; | |
146 } | |
147 | |
148 #endif |