SET(udebug "")
ENDIF()
-ADD_LIBRARY(unet SHARED curve25519.c siphash.c sha512.c fprime.c f25519.c ed25519.c edsign.c auth-data.c chacha20.c pex-msg.c utils.c stun.c)
+ADD_LIBRARY(unet SHARED curve25519.c siphash.c sha512.c fprime.c f25519.c ed25519.c edsign.c auth-data.c chacha20.c pex-msg.c utils.c stun.c random.c)
TARGET_LINK_LIBRARIES(unet ubox)
ADD_EXECUTABLE(unetd ${SOURCES})
#include "ed25519.h"
#include "curve25519.h"
#include "auth-data.h"
+#include "random.h"
#include "pex-msg.h"
static uint8_t peerkey[EDSIGN_PUBLIC_KEY_SIZE];
static int generate_key(void)
{
- FILE *f;
- int ret;
-
if (has_key)
return 0;
- f = fopen("/dev/urandom", "r");
- if (!f) {
- INFO("Can't open /dev/urandom\n");
- return 1;
- }
-
- ret = fread(seckey, sizeof(seckey), 1, f);
- fclose(f);
-
- if (ret != 1) {
- INFO("Can't read data from /dev/urandom\n");
- return 1;
- }
-
+ randombytes(seckey, sizeof(seckey));
ed25519_prepare(seckey);
has_key = true;
#include "sha512.h"
#include "chacha20.h"
#include "unetd.h"
+#include "random.h"
#include <libubus.h>
#include <libubox/blobmsg_json.h>
struct blob_attr *meta_buf, *enroll_meta_buf;
unsigned int timeout, interval;
struct network *net = NULL;
- int n_connect = 0, err = 0;
+ int n_connect = 0;
size_t rem;
- FILE *f;
enroll_stop();
blobmsg_parse_attr(enroll_start_policy, __ENROLL_START_ATTR_MAX, tb, data);
state->n_connect++;
}
- f = fopen("/dev/urandom", "r");
- if (!f)
- return UBUS_STATUS_UNKNOWN_ERROR;
-
- if (fread(state->privkey, sizeof(state->privkey), 1, f) != 1)
- err = UBUS_STATUS_UNKNOWN_ERROR;
-
- fclose(f);
- if (err)
- goto error;
+ randombytes(state->privkey, sizeof(state->privkey));
curve25519_clamp_secret(state->privkey);
curve25519_generate_public(state->pubkey, state->privkey);
uloop_timeout_set(&state->connect_timer, 10);
return 0;
-
-error:
- free(state);
- state = NULL;
- return err;
}
void enroll_stop(void)
#include <libubox/list.h>
#include <libubox/uloop.h>
#include <libubox/usock.h>
+#include "random.h"
#include "pex-msg.h"
#include "chacha20.h"
#include "auth-data.h"
static char pex_tx_buf[PEX_BUF_SIZE];
-static FILE *pex_urandom;
static struct uloop_fd pex_fd, pex_unix_fd;
static LIST_HEAD(requests);
static struct uloop_timeout gc_timer;
hdr->len = sizeof(*ehdr);
- if (fread(&ehdr->nonce, sizeof(ehdr->nonce), 1, pex_urandom) != 1)
- return NULL;
-
+ randombytes(&ehdr->nonce, sizeof(ehdr->nonce));
hash = pex_network_hash(auth_key, ehdr->nonce);
*(uint64_t *)hdr->id ^= hash;
memcpy(ehdr->auth_id, auth_key, sizeof(ehdr->auth_id));
res->req_id = req->req_id;
res->data_len = cpu_to_be32(len);
- if (!fread(e_key_priv, sizeof(e_key_priv), 1, pex_urandom))
- return;
+ randombytes(e_key_priv, sizeof(e_key_priv));
curve25519_clamp_secret(e_key_priv);
curve25519_generate_public(res->e_key, e_key_priv);
memcpy(&ctx->addr, addr, sizeof(ctx->addr));
memcpy(ctx->auth_key, auth_key, sizeof(ctx->auth_key));
memcpy(ctx->priv_key, priv_key, sizeof(ctx->priv_key));
- if (!fread(&ctx->req_id, sizeof(ctx->req_id), 1, pex_urandom)) {
- free(ctx);
- return NULL;
- }
+ randombytes(&ctx->req_id, sizeof(ctx->req_id));
list_add_tail(&ctx->list, &requests);
if (!gc_timer.pending)
uloop_timeout_set(&gc_timer, 1000);
#endif
}
- pex_urandom = fopen("/dev/urandom", "r");
- if (!pex_urandom)
- goto close_raw;
-
fd = socket(sa->sa_family == AF_INET ? PF_INET : PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (fd < 0)
- goto close_urandom;
+ goto close_raw;
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
close_socket:
close(fd);
-close_urandom:
- fclose(pex_urandom);
close_raw:
if (pex_raw_v4_fd >= 0)
close(pex_raw_v4_fd);
pex_raw_v4_fd = -1;
pex_raw_v6_fd = -1;
- if (pex_urandom)
- fclose(pex_urandom);
-
if (pex_fd.cb) {
uloop_fd_delete(&pex_fd);
close(pex_fd.fd);
pex_fd.cb = NULL;
pex_unix_fd.cb = NULL;
- pex_urandom = NULL;
}
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2025 Felix Fietkau <nbd@nbd.name>
+ */
+#ifdef linux
+#include <sys/ramdom.h>
+#endif
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+
+ssize_t __getrandom(void *buf, size_t buflen)
+{
+ static FILE *urandom;
+ ssize_t ret;
+
+#ifdef linux
+ ret = getrandom(buf, buflen, 0);
+ if (ret > 0)
+ return ret;
+#endif
+
+#ifdef __APPLE__
+ arc4random_buf(buf, buflen);
+ return buflen;
+#endif
+
+ if (!urandom) {
+ urandom = fopen("/dev/urandom", "r");
+ if (!urandom)
+ abort();
+ }
+
+ ret = fread(buf, buflen, 1, urandom);
+ if (ret != 1)
+ return -1;
+
+ return buflen;
+}
+
+void randombytes(void *buf, size_t len)
+{
+ while (len > 0) {
+ ssize_t cur = len;
+
+ if (cur > 256)
+ cur = 256;
+
+ cur = __getrandom(buf, cur);
+ if (cur < 0)
+ continue;
+
+ buf += cur;
+ len -= cur;
+ }
+}
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2025 Felix Fietkau <nbd@nbd.name>
+ */
+#ifndef __UNET_RANDOM_H
+#define __UNET_RANDOM_H
+
+#include <stdlib.h>
+
+void randombytes(void *buf, size_t len);
+
+#endif
#include <string.h>
#include <stdio.h>
#include "stun.h"
+#include "random.h"
static uint8_t tx_buf[256];
uint16_t response_port)
{
struct stun_msg_hdr *hdr;
- FILE *f;
hdr = stun_msg_init(STUN_MSGTYPE_BINDING_REQUEST);
if (response_port) {
*tlv_port = htons(response_port);
}
- f = fopen("/dev/urandom", "r");
- if (!f)
- return NULL;
-
- if (fread(hdr->transaction, 12, 1, f) != 1)
- return NULL;
-
- fclose(f);
+ randombytes(hdr->transaction, 12);
memcpy(req->transaction, hdr->transaction, sizeof(req->transaction));
req->pending = true;
req->port = 0;
#include <time.h>
#include "unetd.h"
#include "sha512.h"
+#include "random.h"
static uint8_t salt[8];
static uint64_t nonce;
static bool token_init(void)
{
static bool init_done;
- FILE *f;
if (init_done)
return true;
- f = fopen("/dev/urandom", "r");
- if (!f)
- return false;
-
- init_done = fread(salt, sizeof(salt), 1, f) == 1;
- fclose(f);
+ init_done = true;
+ randombytes(salt, sizeof(salt));
return init_done;
}