Use libsodium for retrieving random bytes

This commit is contained in:
Jeremy Lakeman 2016-04-13 15:56:57 +09:30
parent e15e332072
commit bd47a8eb60
15 changed files with 71 additions and 271 deletions

View File

@ -430,7 +430,11 @@ int main(int argc,char **argv)
if (argc>=2)
ber=calc_ber(atof(argv[2]));
}
{
struct timeval tv;
gettimeofday(&tv, NULL);
srandom((getpid() << 16) ^ tv.tv_sec ^ tv.tv_usec);
}
struct pollfd fds[2];
struct radio_state radios[2];

View File

@ -105,8 +105,7 @@ static int keyring_initialise(keyring_file *k)
return WHYF_perror("fseeko(%d, 0, SEEK_SET)", fileno(k->file));
unsigned char buffer[KEYRING_PAGE_SIZE];
bzero(&buffer[0], KEYRING_BAM_BYTES);
if (urandombytes(&buffer[KEYRING_BAM_BYTES], KEYRING_PAGE_SIZE - KEYRING_BAM_BYTES))
return WHYF("Could not generate random keyring salt");
randombytes_buf(&buffer[KEYRING_BAM_BYTES], KEYRING_PAGE_SIZE - KEYRING_BAM_BYTES);
if (fwrite(buffer, KEYRING_PAGE_SIZE, 1, k->file) != 1) {
WHYF_perror("fwrite(%p, %zu, 1, %d)", buffer, KEYRING_PAGE_SIZE - KEYRING_BAM_BYTES, fileno(k->file));
return WHYF("Could not write page into keyring file");
@ -486,7 +485,7 @@ static void create_cryptosign(keypair *kp)
static void create_rhizome(keypair *kp)
{
urandombytes(kp->private_key, kp->private_key_len);
randombytes_buf(kp->private_key, kp->private_key_len);
}
static int pack_private_only(const keypair *kp, struct rotbuf *rb)
@ -852,8 +851,7 @@ static int keyring_pack_identity(const keyring_identity *id, unsigned char packe
{
/* Convert an identity to a KEYRING_PAGE_SIZE bytes long block that consists of 32 bytes of random
* salt, a 64 byte (512 bit) message authentication code (MAC) and the list of key pairs. */
if (urandombytes(packed, PKR_SALT_BYTES) == -1)
return WHY("Could not generate salt");
randombytes_buf(packed, PKR_SALT_BYTES);
/* Calculate MAC */
if (keyring_identity_mac(id, packed /* pkr salt */, packed + PKR_SALT_BYTES /* write mac in after salt */) == -1)
return -1;
@ -861,11 +859,9 @@ static int keyring_pack_identity(const keyring_identity *id, unsigned char packe
* likely deducible, e.g., the location of the trailing 0x00 byte can probably be guessed with
* confidence. Payload rotation will frustrate this attack.
*/
uint16_t rotation;
if (urandombytes((unsigned char *)&rotation, sizeof rotation) == -1)
return WHY("urandombytes() failed to generate random rotation");
#ifdef NO_ROTATION
rotation=0;
uint16_t rotation = 0;
#ifndef NO_ROTATION
rotation=randombytes_random();
#endif
// The two bytes immediately following the MAC describe the rotation offset.
packed[PKR_SALT_BYTES + PKR_MAC_BYTES] = rotation >> 8;
@ -946,16 +942,14 @@ static int keyring_pack_identity(const keyring_identity *id, unsigned char packe
unsigned char *buf;
size_t len;
while (rotbuf_next_chunk(&rbuf, &buf, &len))
if (urandombytes(buf, len))
return WHY("urandombytes() failed to back-fill packed identity block");
randombytes_buf(buf, len);
}
return 0;
scram:
/* Randomfill the entire slot to erase any secret keys that may have found their way into it, to
* avoid leaking sensitive information out through a possibly re-used memory buffer.
*/
if (urandombytes(packed, KEYRING_PAGE_SIZE) == -1)
WHY("urandombytes() failed to in-fill packed identity block");
randombytes_buf(packed, KEYRING_PAGE_SIZE);
return -1;
}
@ -1692,7 +1686,7 @@ static int keyring_send_challenge(struct subscriber *source, struct subscriber *
time_ms_t now = gettime_ms();
if (source->identity->challenge_expires < now){
source->identity->challenge_expires = now + 5000;
urandombytes(source->identity->challenge, sizeof(source->identity->challenge));
randombytes_buf(source->identity->challenge, sizeof(source->identity->challenge));
}
struct overlay_buffer *payload = ob_new();
@ -1974,7 +1968,7 @@ unsigned char *keyring_get_nm_bytes(const sid_t *known_sidp, const sid_t *unknow
if (nm_slots_used<NM_CACHE_SLOTS) {
i=nm_slots_used; nm_slots_used++;
} else {
i=random()%NM_CACHE_SLOTS;
i=randombytes_uniform(NM_CACHE_SLOTS);
}
/* calculate and store */

1
main.c
View File

@ -44,7 +44,6 @@ int main(int argc, char **argv)
signal(SIGPIPE,sigPipeHandler);
signal(SIGIO,sigIoHandler);
srandomdev();
cf_init();
int status = parseCommandLine(NULL, argv[0], argc - 1, (const char*const*)&argv[1]);
#if defined WIN32

View File

@ -266,10 +266,8 @@ int overlay_mdp_client_socket(void)
/* Create local per-client socket to MDP server (connection is always local) */
int mdp_sockfd;
struct socket_address addr;
uint32_t random_value;
if (urandombytes((unsigned char *)&random_value, sizeof random_value) == -1)
return WHY("urandombytes() failed");
if (make_local_sockaddr(&addr, "mdp.client.%u.%08lx.socket", getpid(), (unsigned long)random_value) == -1)
static unsigned seq = 0;
if (make_local_sockaddr(&addr, "mdp.client.%u.%08x.socket", getpid(), ++seq) == -1)
return -1;
if ((mdp_sockfd = esocket(AF_UNIX, SOCK_DGRAM, 0)) == -1)
return -1;

View File

@ -68,6 +68,11 @@ static int app_mdp_ping(const struct cli_parsed *parsed, struct cli_context *con
interval_ms = 1000;
/* First sequence number in the echo frames */
{
struct timeval tv;
gettimeofday(&tv, NULL);
srandom((getpid() << 16) ^ tv.tv_sec ^ tv.tv_usec);
}
uint32_t firstSeq = random();
uint32_t sequence_number = firstSeq;
@ -623,6 +628,11 @@ static int app_dna_lookup(const struct cli_parsed *parsed, struct cli_context *c
return WHY("Cannot create MDP socket");
/* Bind to MDP socket and await confirmation */
{
struct timeval tv;
gettimeofday(&tv, NULL);
srandom((getpid() << 16) ^ tv.tv_sec ^ tv.tv_usec);
}
sid_t srcsid;
mdp_port_t port=32768+(random()&32767);
if (overlay_mdp_getmyaddr(mdp_sockfd, 0, &srcsid)) {
@ -729,6 +739,11 @@ static int app_reverse_lookup(const struct cli_parsed *parsed, struct cli_contex
if (cli_arg(parsed, "timeout", &delay, NULL, "3000") == -1)
return -1;
{
struct timeval tv;
gettimeofday(&tv, NULL);
srandom((getpid() << 16) ^ tv.tv_sec ^ tv.tv_usec);
}
mdp_port_t port=32768+(random()&0xffff);
sid_t srcsid;

33
os.c
View File

@ -116,39 +116,6 @@ int _mkdirsn(struct __sourceloc whence, const char *path, size_t len, mode_t mod
return -1;
}
int urandombytes(unsigned char *buf, size_t len)
{
static int urandomfd = -1;
int tries = 0;
if (urandomfd == -1) {
for (tries = 0; tries < 4; ++tries) {
urandomfd = open("/dev/urandom",O_RDONLY);
if (urandomfd != -1) break;
sleep_ms(1000);
}
if (urandomfd == -1) {
WHY_perror("open(/dev/urandom)");
return -1;
}
}
tries = 0;
while (len > 0) {
ssize_t i = read(urandomfd, buf, (len < 1048576) ? len : 1048576);
if (i == -1) {
if (++tries > 4) {
WHY_perror("read(/dev/urandom)");
if (errno==EBADF) urandomfd=-1;
return -1;
}
} else {
tries = 0;
buf += i;
len -= i;
}
}
return 0;
}
time_ms_t gettime_ms()
{
struct timeval nowtv;

3
os.h
View File

@ -132,9 +132,6 @@ int _emkdirsn(struct __sourceloc, const char *path, size_t len, mode_t mode, MKD
#define emkdirs_info(path, mode) emkdirs_log((path), (mode), log_info_mkdir)
#define emkdirsn_info(path, len, mode) emkdirsn_log((path), (len), (mode), log_info_mkdir)
void srandomdev();
int urandombytes(unsigned char *buf, size_t len);
/* Read the symbolic link into the supplied buffer and add a terminating nul.
* Logs an ERROR and returns -1 if the buffer is too short to hold the link
* content and the terminating nul. If readlink(2) returns an error, then logs

View File

@ -695,8 +695,7 @@ static int generate_nonce(uint8_t *nonce, size_t bytes)
{
if (bytes<1||bytes>128) return -1;
if (!nonce_initialised) {
if (urandombytes(nonce_buffer,128))
return -1;
randombytes_buf(nonce_buffer,128);
nonce_initialised=1;
}
@ -1341,7 +1340,23 @@ static void mdp_interface_packet(struct socket_address *client, struct mdp_heade
}
}
static void mdp_process_packet(struct socket_address *client, struct mdp_header *header,
static mdp_port_t get_next_port(){
again:
if (next_port_binding > 32*1024)
next_port_binding=256;
else
next_port_binding++;
unsigned i;
for(i=0;i<MDP_MAX_BINDINGS;i++) {
if (mdp_bindings[i].port==next_port_binding)
goto again;
}
return next_port_binding;
}
static void mdp_process_packet(struct socket_address *client, struct mdp_header *header,
struct overlay_buffer *payload)
{
struct internal_mdp_header internal_header;
@ -1385,19 +1400,7 @@ static void mdp_process_packet(struct socket_address *client, struct mdp_header
// assign the next available port number
if (header->local.port==0 && header->flags & MDP_FLAG_BIND){
again:
if (next_port_binding > 32*1024)
next_port_binding=256;
else
next_port_binding++;
unsigned i;
for(i=0;i<MDP_MAX_BINDINGS;i++) {
if (mdp_bindings[i].port==next_port_binding)
goto again;
}
header->local.port=next_port_binding;
header->local.port=get_next_port();
}
internal_header.source_port = header->local.port;

View File

@ -1,56 +0,0 @@
/*
Serval Distributed Numbering Architecture (DNA)
Copyright (C) 2010 Paul Gardner-Stephen
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "os.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
/* it's really stupid that there isn't a syscall for this */
static int fd = -1;
void randombytes(unsigned char *x,unsigned long long xlen)
{
int i;
if (fd == -1) {
for (;;) {
fd = open("/dev/urandom",O_RDONLY);
if (fd != -1) break;
sleep_ms(1000);
}
}
while (xlen > 0) {
if (xlen < 1048576) i = xlen; else i = 1048576;
i = read(fd,x,i);
if (i < 1) {
sleep_ms(1000);
continue;
}
x += i;
xlen -= i;
}
}

View File

@ -226,7 +226,7 @@ struct vomp_call_state;
void set_codec_flag(int codec, unsigned char *flags);
struct vomp_call_state *vomp_find_call_by_session(unsigned int session_token);
struct vomp_call_state *vomp_find_call_by_session(uint16_t session_token);
int vomp_parse_dtmf_digit(char c);
int vomp_dial(struct subscriber *local, struct subscriber *remote, const char *local_did, const char *remote_did);
int vomp_pickup(struct vomp_call_state *call);

View File

@ -17,11 +17,9 @@ SERVAL_CLIENT_SOURCES = \
net.c \
os.c \
performance_timing.c \
randombytes.c \
rotbuf.c \
sighandlers.c \
socket.c \
srandomdev.c \
strbuf.c \
strbuf_helpers.c \
str.c \

View File

@ -1,116 +0,0 @@
/*
Serval Distributed Numbering Architecture (DNA)
Copyright (C) 2010 Paul Gardner-Stephen
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/*
Portions Copyright (C) 2013 Petter Reinholdtsen
Some rights reserved
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
/*-
* Copyright (c) 2006 Verdens Gang AS
* Copyright (c) 2006-2008 Linpro AS
* All rights reserved.
*
* Author: Dag-Erling SmÃ\u017ergrav <des@linpro.no>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
*/
#ifndef HAVE_SRANDOMDEV
#ifndef WIN32
#include <sys/time.h>
#include <unistd.h>
#endif
#include "os.h"
#include "log.h"
#include <fcntl.h>
#include <stdlib.h>
#include <time.h>
void
srandomdev(void)
{
unsigned int seed;
int seeded = 0;
#ifndef WIN32
FILE *fd;
fd = fopen("/dev/urandom", "r");
if (NULL != fd) {
if (fread(&seed, sizeof seed, 1, fd) != 1)
WARNF("fread(\"/dev/urandom\") failed -- falling back to gettimeofday()");
else
seeded = 1;
fclose(fd);
}
#endif
if (!seeded) {
struct timeval tv;
gettimeofday(&tv, NULL);
seed = (getpid() << 16) ^ tv.tv_sec ^ tv.tv_usec;
}
srandom(seed);
}
#endif

View File

@ -66,8 +66,8 @@ static int app_crypt_test(const struct cli_parsed *parsed, struct cli_context *c
unsigned char plain_block[65536];
urandombytes(nonce,sizeof(nonce));
urandombytes(k,sizeof(k));
randombytes_buf(nonce,sizeof(nonce));
randombytes_buf(k,sizeof(k));
int len,i;

4
uuid.c
View File

@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "uuid.h"
#include "os.h"
#include "str.h"
#include "sodium.h"
#include <assert.h>
#ifdef HAVE_ARPA_INET_H
@ -57,8 +58,7 @@ void uuid_set_version(serval_uuid_t *uuid, enum uuid_version version)
int uuid_generate_random(serval_uuid_t *uuid)
{
if (urandombytes(uuid->u.binary, sizeof uuid->u.binary) == -1)
return -1;
randombytes_buf(uuid->u.binary, sizeof uuid->u.binary);
// The following discards 6 random bits.
uuid->u.record.clock_seq_hi_and_reserved &= 0x3f;
uuid->u.record.clock_seq_hi_and_reserved |= 0x80;

33
vomp.c
View File

@ -134,7 +134,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#define VOMP_REJECT_BUSY 3
#define VOMP_REJECT_TIMEOUT 4
#define VOMP_SESSION_MASK 0xffff
#define VOMP_MAX_CALLS 16
#define VOMP_VERSION 0x02
@ -142,8 +141,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
struct vomp_call_half {
struct subscriber *subscriber;
char did[64];
unsigned char state;
unsigned int session;
uint8_t state;
uint16_t session;
unsigned int sequence;
};
@ -331,7 +330,7 @@ int is_codec_set(int codec, unsigned char *flags){
return flags[codec >> 3] & (1<<(codec & 7));
}
struct vomp_call_state *vomp_find_call_by_session(unsigned int session_token)
struct vomp_call_state *vomp_find_call_by_session(uint16_t session_token)
{
unsigned i;
for(i=0;i<vomp_call_count;i++)
@ -340,14 +339,12 @@ struct vomp_call_state *vomp_find_call_by_session(unsigned int session_token)
return NULL;
}
static int vomp_generate_session_id()
static uint16_t vomp_generate_session_id()
{
unsigned int session_id=0;
uint16_t session_id=0;
while (!session_id)
{
if (urandombytes((unsigned char *)&session_id, sizeof session_id))
return WHY("Insufficient entropy");
session_id&=VOMP_SESSION_MASK;
session_id = randombytes_random() & 0xFFFF;
DEBUGF(vomp, "session=0x%08x",session_id);
unsigned i;
/* reject duplicate call session numbers */
@ -363,8 +360,8 @@ static int vomp_generate_session_id()
static struct vomp_call_state *vomp_create_call(struct subscriber *remote,
struct subscriber *local,
unsigned int remote_session,
unsigned int local_session)
uint16_t remote_session,
uint16_t local_session)
{
if (!local_session)
local_session=vomp_generate_session_id();
@ -396,8 +393,8 @@ static struct vomp_call_state *vomp_create_call(struct subscriber *remote,
static struct vomp_call_state *vomp_find_or_create_call(struct subscriber *remote,
struct subscriber *local,
unsigned int sender_session,
unsigned int recvr_session,
uint16_t sender_session,
uint16_t recvr_session,
int sender_state,
int recvr_state)
{
@ -880,11 +877,11 @@ static int vomp_mdp_received(struct internal_mdp_header *header, struct overlay_
switch(version) {
case VOMP_VERSION:
{
unsigned int sender_session=ob_get_ui16(payload);
unsigned int recvr_session=ob_get_ui16(payload);
unsigned char state = ob_get(payload);
unsigned char recvr_state=state>>4;
unsigned char sender_state=state&0xf;
uint16_t sender_session=ob_get_ui16(payload);
uint16_t recvr_session=ob_get_ui16(payload);
uint8_t state = ob_get(payload);
uint8_t recvr_state=state>>4;
uint8_t sender_state=state&0xf;
/* wants to create a call session.
Main aim here: replay protection. An adversary should not be able to