Common: Add Random utilities

This makes it easier to generate random numbers or fill a buffer with
random data in a cryptographically secure way.

This also replaces existing usages of RNG functions in the codebase:

* <random> is pretty hard to use correctly, and std::random_device does
  not give enough guarantees about its results (it's
  implementation-defined, non cryptographically secure and could be
  deterministic on some platforms).
  Doing things correctly is error prone and verbose.

* rand() is terrible and should not be used especially in crypto code.
This commit is contained in:
Léo Lam
2018-05-21 15:48:17 +02:00
parent dd77ace56a
commit fff1db9730
10 changed files with 91 additions and 71 deletions

View File

@ -20,6 +20,7 @@
#include <systemd/sd-daemon.h>
#endif
#include "Common/Random.h"
#include "Common/TraversalProto.h"
#define DEBUG 0
@ -114,7 +115,6 @@ struct hash<TraversalHostId>
}
static int sock;
static int urandomFd;
static std::unordered_map<TraversalRequestId, OutgoingPacketInfo> outgoingPackets;
static std::unordered_map<TraversalHostId, EvictEntry<TraversalInetAddress>> connectedClients;
@ -166,28 +166,11 @@ static sockaddr_in6 MakeSinAddr(const TraversalInetAddress& addr)
return result;
}
static void GetRandomBytes(void* output, size_t size)
{
static u8 bytes[8192];
static size_t bytesLeft = 0;
if (bytesLeft < size)
{
ssize_t rv = read(urandomFd, bytes, sizeof(bytes));
if (rv != sizeof(bytes))
{
perror("read from /dev/urandom");
exit(1);
}
bytesLeft = sizeof(bytes);
}
memcpy(output, bytes + (bytesLeft -= size), size);
}
static void GetRandomHostId(TraversalHostId* hostId)
{
char buf[9];
u32 num;
GetRandomBytes(&num, sizeof(num));
Common::Random::Generate(&num, sizeof(num));
sprintf(buf, "%08x", num);
memcpy(hostId->data(), buf, 8);
}
@ -215,7 +198,7 @@ static void TrySend(const void* buffer, size_t size, sockaddr_in6* addr)
static TraversalPacket* AllocPacket(const sockaddr_in6& dest, TraversalRequestId misc = 0)
{
TraversalRequestId requestId;
GetRandomBytes(&requestId, sizeof(requestId));
Common::Random::Generate(&requestId, sizeof(requestId));
OutgoingPacketInfo* info = &outgoingPackets[requestId];
info->dest = dest;
info->misc = misc;
@ -376,14 +359,6 @@ static void HandlePacket(TraversalPacket* packet, sockaddr_in6* addr)
int main()
{
int rv;
urandomFd = open("/dev/urandom", O_RDONLY);
if (urandomFd < 0)
{
perror("open /dev/urandom");
return 1;
}
sock = socket(PF_INET6, SOCK_DGRAM, 0);
if (sock == -1)
{