Use the HWRNG for generating DUIDs and IAIDs.

Before these were generated from a freshly seeded PRNG which reduces the
state space of possible DUIDs and skews the distribution of both DUIDs
and IAIDs as a function of the PRNG choice.

None of this really matters much in practice, but do things right.
This commit is contained in:
Nicholas J. Kain 2022-08-28 03:52:44 -04:00
parent d43fc12306
commit 1f0a8f29de
No known key found for this signature in database
6 changed files with 19 additions and 26 deletions

View File

@ -1,4 +1,4 @@
// Copyright 2014-2018 Nicholas J. Kain <njkain at gmail dot com>
// Copyright 2014-2022 Nicholas J. Kain <njkain at gmail dot com>
// SPDX-License-Identifier: MIT
#include <string.h>
#include <stdlib.h>
@ -11,7 +11,7 @@
#include <limits.h>
#include <errno.h>
#include "nk/log.h"
#include "nk/random.h"
#include "nk/hwrng.h"
#include "nk/io.h"
#include "duiaid.h"
#include "ndhc.h"
@ -90,8 +90,7 @@ static int open_iaidfile_write(const uint8_t hwaddr[static 6],
// RFC6355 specifies a RFC4122 UUID, but I simply use a 128-byte random
// value, as the complexity of RFC4122 UUID generation is completely
// unwarranted for DHCPv4.
static size_t generate_duid(struct nk_random_state *s,
char *dest, size_t dlen)
static size_t generate_duid(char *dest, size_t dlen)
{
const size_t tlen = sizeof(uint16_t) + 4 * sizeof(uint32_t);
if (dlen < tlen)
@ -102,32 +101,27 @@ static size_t generate_duid(struct nk_random_state *s,
memcpy(dest+off, &typefield, sizeof typefield);
off += sizeof typefield;
for (size_t i = 0; i < 4; ++i) {
uint32_t r32 = nk_random_u32(s);
memcpy(dest+off, &r32, sizeof r32);
off += sizeof r32;
}
nk_hwrng_bytes(dest+off, sizeof(uint32_t) * 4);
off += sizeof(uint32_t) * 4;
return off;
}
// RFC6355 specifies the IAID as a 32-bit value that uniquely identifies
// a hardware link for a given host.
static size_t generate_iaid(struct nk_random_state *s,
char *dest, size_t dlen)
static size_t generate_iaid(char *dest, size_t dlen)
{
if (dlen < sizeof(uint32_t))
suicide("%s: dlen < %zu", __func__, sizeof(uint32_t));
size_t off = 0;
uint32_t r32 = nk_random_u32(s);
memcpy(dest+off, &r32, sizeof r32);
off += sizeof r32;
nk_hwrng_bytes(dest+off, sizeof(uint32_t));
off += sizeof(uint32_t);
return off;
}
// Failures are all fatal.
void get_clientid(struct client_state_t *cs,
struct client_config_t *cc)
void get_clientid(struct client_config_t *cc)
{
if (cc->clientid_len > 0)
return;
@ -138,7 +132,7 @@ void get_clientid(struct client_state_t *cs,
int fd = open_iaidfile_read(cc->arp, sizeof cc->arp);
if (fd < 0) {
iaid_len = generate_iaid(&cs->rnd_state, iaid, sizeof iaid);
iaid_len = generate_iaid(iaid, sizeof iaid);
fd = open_iaidfile_write(cc->arp, sizeof cc->arp);
ssize_t r = safe_write(fd, iaid, iaid_len);
if (r < 0 || (size_t)r != iaid_len)
@ -155,7 +149,7 @@ void get_clientid(struct client_state_t *cs,
fd = open_duidfile_read();
if (fd < 0) {
duid_len = generate_duid(&cs->rnd_state, duid, sizeof duid);
duid_len = generate_duid(duid, sizeof duid);
fd = open_duidfile_write();
ssize_t r = safe_write(fd, duid, duid_len);
if (r < 0 || (size_t)r != duid_len)

View File

@ -1,11 +1,11 @@
// Copyright 2014-2018 Nicholas J. Kain <njkain at gmail dot com>
// Copyright 2014-2022 Nicholas J. Kain <njkain at gmail dot com>
// SPDX-License-Identifier: MIT
#ifndef NJK_NDHC_DUIAID_H_
#define NJK_NDHC_DUIAID_H_
#include "ndhc.h"
void get_clientid(struct client_state_t *cs, struct client_config_t *cc);
void get_clientid(struct client_config_t *cc);
#endif

2
ndhc.c
View File

@ -567,7 +567,7 @@ int main(int argc, char *argv[])
if (nl_getifdata() < 0)
suicide("failed to get interface MAC or index");
get_clientid(&cs, &client_config);
get_clientid(&client_config);
switch (perform_ifup()) {
case 1: case 0: break;

View File

@ -95,7 +95,7 @@ static bool nk_get_urandom(char *seed, size_t len)
return ret;
}
void nk_get_hwrng(void *seed, size_t len)
void nk_hwrng_bytes(void *seed, size_t len)
{
char *s = (char *)seed;
if (nk_getrandom(s, len))

View File

@ -1,11 +1,10 @@
// Copyright 2016 Nicholas J. Kain <njkain at gmail dot com>
// Copyright 2016-2022 Nicholas J. Kain <njkain at gmail dot com>
// SPDX-License-Identifier: MIT
#ifndef NCMLIB_HWCRNG__
#define NCMLIB_HWCRNG__
#include <stddef.h>
void nk_get_hwrng(void *seed, size_t len);
void nk_hwrng_bytes(void *seed, size_t len);
#endif

View File

@ -8,7 +8,7 @@
void nk_random_init(struct nk_random_state *s)
{
nk_get_hwrng(s->seed, sizeof(uint64_t) * 2);
nk_hwrng_bytes(s->seed, sizeof(uint64_t) * 2);
s->seed[2] = 2000001;
s->seed[3] = 0;
for (size_t i = 0; i < 14; ++i) nk_random_u64(s);