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:
parent
d43fc12306
commit
1f0a8f29de
30
duiaid.c
30
duiaid.c
@ -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)
|
||||
|
4
duiaid.h
4
duiaid.h
@ -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
2
ndhc.c
@ -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;
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user