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
|
// SPDX-License-Identifier: MIT
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -11,7 +11,7 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "nk/log.h"
|
#include "nk/log.h"
|
||||||
#include "nk/random.h"
|
#include "nk/hwrng.h"
|
||||||
#include "nk/io.h"
|
#include "nk/io.h"
|
||||||
#include "duiaid.h"
|
#include "duiaid.h"
|
||||||
#include "ndhc.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
|
// RFC6355 specifies a RFC4122 UUID, but I simply use a 128-byte random
|
||||||
// value, as the complexity of RFC4122 UUID generation is completely
|
// value, as the complexity of RFC4122 UUID generation is completely
|
||||||
// unwarranted for DHCPv4.
|
// unwarranted for DHCPv4.
|
||||||
static size_t generate_duid(struct nk_random_state *s,
|
static size_t generate_duid(char *dest, size_t dlen)
|
||||||
char *dest, size_t dlen)
|
|
||||||
{
|
{
|
||||||
const size_t tlen = sizeof(uint16_t) + 4 * sizeof(uint32_t);
|
const size_t tlen = sizeof(uint16_t) + 4 * sizeof(uint32_t);
|
||||||
if (dlen < tlen)
|
if (dlen < tlen)
|
||||||
@ -102,32 +101,27 @@ static size_t generate_duid(struct nk_random_state *s,
|
|||||||
memcpy(dest+off, &typefield, sizeof typefield);
|
memcpy(dest+off, &typefield, sizeof typefield);
|
||||||
off += sizeof typefield;
|
off += sizeof typefield;
|
||||||
|
|
||||||
for (size_t i = 0; i < 4; ++i) {
|
nk_hwrng_bytes(dest+off, sizeof(uint32_t) * 4);
|
||||||
uint32_t r32 = nk_random_u32(s);
|
off += sizeof(uint32_t) * 4;
|
||||||
memcpy(dest+off, &r32, sizeof r32);
|
|
||||||
off += sizeof r32;
|
|
||||||
}
|
|
||||||
return off;
|
return off;
|
||||||
}
|
}
|
||||||
|
|
||||||
// RFC6355 specifies the IAID as a 32-bit value that uniquely identifies
|
// RFC6355 specifies the IAID as a 32-bit value that uniquely identifies
|
||||||
// a hardware link for a given host.
|
// a hardware link for a given host.
|
||||||
static size_t generate_iaid(struct nk_random_state *s,
|
static size_t generate_iaid(char *dest, size_t dlen)
|
||||||
char *dest, size_t dlen)
|
|
||||||
{
|
{
|
||||||
if (dlen < sizeof(uint32_t))
|
if (dlen < sizeof(uint32_t))
|
||||||
suicide("%s: dlen < %zu", __func__, sizeof(uint32_t));
|
suicide("%s: dlen < %zu", __func__, sizeof(uint32_t));
|
||||||
size_t off = 0;
|
size_t off = 0;
|
||||||
|
|
||||||
uint32_t r32 = nk_random_u32(s);
|
nk_hwrng_bytes(dest+off, sizeof(uint32_t));
|
||||||
memcpy(dest+off, &r32, sizeof r32);
|
off += sizeof(uint32_t);
|
||||||
off += sizeof r32;
|
|
||||||
return off;
|
return off;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Failures are all fatal.
|
// Failures are all fatal.
|
||||||
void get_clientid(struct client_state_t *cs,
|
void get_clientid(struct client_config_t *cc)
|
||||||
struct client_config_t *cc)
|
|
||||||
{
|
{
|
||||||
if (cc->clientid_len > 0)
|
if (cc->clientid_len > 0)
|
||||||
return;
|
return;
|
||||||
@ -138,7 +132,7 @@ void get_clientid(struct client_state_t *cs,
|
|||||||
|
|
||||||
int fd = open_iaidfile_read(cc->arp, sizeof cc->arp);
|
int fd = open_iaidfile_read(cc->arp, sizeof cc->arp);
|
||||||
if (fd < 0) {
|
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);
|
fd = open_iaidfile_write(cc->arp, sizeof cc->arp);
|
||||||
ssize_t r = safe_write(fd, iaid, iaid_len);
|
ssize_t r = safe_write(fd, iaid, iaid_len);
|
||||||
if (r < 0 || (size_t)r != 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();
|
fd = open_duidfile_read();
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
duid_len = generate_duid(&cs->rnd_state, duid, sizeof duid);
|
duid_len = generate_duid(duid, sizeof duid);
|
||||||
fd = open_duidfile_write();
|
fd = open_duidfile_write();
|
||||||
ssize_t r = safe_write(fd, duid, duid_len);
|
ssize_t r = safe_write(fd, duid, duid_len);
|
||||||
if (r < 0 || (size_t)r != 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
|
// SPDX-License-Identifier: MIT
|
||||||
#ifndef NJK_NDHC_DUIAID_H_
|
#ifndef NJK_NDHC_DUIAID_H_
|
||||||
#define NJK_NDHC_DUIAID_H_
|
#define NJK_NDHC_DUIAID_H_
|
||||||
|
|
||||||
#include "ndhc.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
|
#endif
|
||||||
|
|
||||||
|
2
ndhc.c
2
ndhc.c
@ -567,7 +567,7 @@ int main(int argc, char *argv[])
|
|||||||
if (nl_getifdata() < 0)
|
if (nl_getifdata() < 0)
|
||||||
suicide("failed to get interface MAC or index");
|
suicide("failed to get interface MAC or index");
|
||||||
|
|
||||||
get_clientid(&cs, &client_config);
|
get_clientid(&client_config);
|
||||||
|
|
||||||
switch (perform_ifup()) {
|
switch (perform_ifup()) {
|
||||||
case 1: case 0: break;
|
case 1: case 0: break;
|
||||||
|
@ -95,7 +95,7 @@ static bool nk_get_urandom(char *seed, size_t len)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nk_get_hwrng(void *seed, size_t len)
|
void nk_hwrng_bytes(void *seed, size_t len)
|
||||||
{
|
{
|
||||||
char *s = (char *)seed;
|
char *s = (char *)seed;
|
||||||
if (nk_getrandom(s, len))
|
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
|
// SPDX-License-Identifier: MIT
|
||||||
#ifndef NCMLIB_HWCRNG__
|
#ifndef NCMLIB_HWCRNG__
|
||||||
#define NCMLIB_HWCRNG__
|
#define NCMLIB_HWCRNG__
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
void nk_hwrng_bytes(void *seed, size_t len);
|
||||||
void nk_get_hwrng(void *seed, size_t len);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
void nk_random_init(struct nk_random_state *s)
|
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[2] = 2000001;
|
||||||
s->seed[3] = 0;
|
s->seed[3] = 0;
|
||||||
for (size_t i = 0; i < 14; ++i) nk_random_u64(s);
|
for (size_t i = 0; i < 14; ++i) nk_random_u64(s);
|
||||||
|
Loading…
Reference in New Issue
Block a user