NeoMutt
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
random.c
Go to the documentation of this file.
1
29#include "config.h"
30#include <stddef.h>
31#include <errno.h>
32#include <stdint.h>
33#include <stdio.h>
34#include <string.h>
35#include "random.h"
36#include "exit.h"
37#include "logging2.h"
38#include "message.h"
39#ifdef HAVE_SYS_RANDOM_H
40#include <sys/random.h>
41#endif
42
44static FILE *FpRandom = NULL;
45
47static const unsigned char Base32[] = "abcdefghijklmnopqrstuvwxyz234567";
48
56static int mutt_randbuf(void *buf, size_t buflen)
57{
58 if (buflen > 1048576)
59 {
60 mutt_error(_("mutt_randbuf buflen=%zu"), buflen);
61 return -1;
62 }
63
64#ifdef HAVE_GETRANDOM
65 ssize_t rc;
66 ssize_t count = 0;
67 do
68 {
69 // getrandom() can return less than requested if there's insufficient
70 // entropy or it's interrupted by a signal.
71 rc = getrandom((char *) buf + count, buflen - count, 0);
72 if (rc > 0)
73 count += rc;
74 } while (((rc >= 0) && (count < buflen)) || ((rc == -1) && (errno == EINTR)));
75 if (count == buflen)
76 return 0;
77#endif
78 /* let's try urandom in case we're on an old kernel, or the user has
79 * configured selinux, seccomp or something to not allow getrandom */
80 if (!FpRandom)
81 {
82 FpRandom = fopen("/dev/urandom", "rb");
83 if (!FpRandom)
84 {
85 mutt_error(_("open /dev/urandom: %s"), strerror(errno));
86 return -1;
87 }
88 setbuf(FpRandom, NULL);
89 }
90 if (fread(buf, 1, buflen, FpRandom) != buflen)
91 {
92 mutt_error(_("read /dev/urandom: %s"), strerror(errno));
93 return -1;
94 }
95
96 return 0;
97}
98
104void mutt_rand_base32(char *buf, size_t buflen)
105{
106 if (!buf || (buflen == 0))
107 return;
108
109 uint8_t *p = (uint8_t *) buf;
110
111 if (mutt_randbuf(p, buflen) < 0)
112 mutt_exit(1); // LCOV_EXCL_LINE
113 for (size_t pos = 0; pos < buflen; pos++)
114 p[pos] = Base32[p[pos] % 32];
115}
116
121uint32_t mutt_rand32(void)
122{
123 uint32_t num = 0;
124
125 if (mutt_randbuf(&num, sizeof(num)) < 0)
126 mutt_exit(1); // LCOV_EXCL_LINE
127 return num;
128}
129
134uint64_t mutt_rand64(void)
135{
136 uint64_t num = 0;
137
138 if (mutt_randbuf(&num, sizeof(num)) < 0)
139 mutt_exit(1); // LCOV_EXCL_LINE
140 return num;
141}
Leave the program NOW.
#define mutt_error(...)
Definition: logging2.h:92
Logging Dispatcher.
void mutt_exit(int code)
Leave NeoMutt NOW.
Definition: main.c:236
Message logging.
#define _(a)
Definition: message.h:28
static const unsigned char Base32[]
Base 32 alphabet.
Definition: random.c:47
uint64_t mutt_rand64(void)
Create a 64-bit random number.
Definition: random.c:134
static int mutt_randbuf(void *buf, size_t buflen)
Fill a buffer with randomness.
Definition: random.c:56
uint32_t mutt_rand32(void)
Create a 32-bit random number.
Definition: random.c:121
static FILE * FpRandom
FILE pointer of the random source.
Definition: random.c:44
void mutt_rand_base32(char *buf, size_t buflen)
Fill a buffer with a base32-encoded random string.
Definition: random.c:104
Random number/string functions.