summaryrefslogtreecommitdiff
path: root/src/util.c
blob: bd2c9a7fd656e0f70fd48de6ca799dba32ce5e37 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include "util.h"

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/syscall.h>
#include <unistd.h>

ssize_t random_get(void *buf, size_t buflen, unsigned int flags) {
    memset(buf, 0, buflen);

    long rv = syscall(SYS_getrandom, buf, buflen, flags);
    if (rv == -1) {
        if (errno == ENOSYS) {
            fputs("getrandom returned ENOSYS. random-seed requires Linux 3.17\n", stderr);
            exit(1);
        }
    } else {
        bool all_zero = true;
        if (buflen > 32) {
            for (size_t i = 0; i < buflen; i++) {
                if (((unsigned char *)buf)[i] != 0) {
                    all_zero = false;
                    break;
                }
            }
        }
        if (all_zero) {
            fputs("getrandom returned all zeros, probably broken\n", stderr);
            exit(1);
        }
    }

    return rv;
}