mirror of
https://github.com/eclipse/tinydtls.git
synced 2025-05-08 19:41:19 +08:00

Use of random() requires that _GNU_SOURCE is defined. Cannot use variables named rand. Make sure that dtls_prng.o is rebuilt whenever any of the platform-specific/dtls_prng_*.c files are updated. Signed-off-by: Jon Shallow <supjps-libcoap@jpshallow.com>
108 lines
2.8 KiB
C
108 lines
2.8 KiB
C
/*******************************************************************************
|
|
*
|
|
* Copyright (c) 2011-2020 Olaf Bergmann (TZI) and others.
|
|
* All rights reserved. This program and the accompanying materials
|
|
* are made available under the terms of the Eclipse Public License v1.0
|
|
* and Eclipse Distribution License v. 1.0 which accompanies this distribution.
|
|
*
|
|
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
|
|
* and the Eclipse Distribution License is available at
|
|
* http://www.eclipse.org/org/documents/edl-v10.php.
|
|
*
|
|
* Contributors:
|
|
* Olaf Bergmann - initial API and implementation
|
|
* Hauke Mehrtens - memory optimization, ECC integration
|
|
* Achim Kraus - session recovery
|
|
* Sachin Agrawal - rehandshake support
|
|
* Jon Shallow - platform dependent prng support
|
|
*
|
|
*******************************************************************************/
|
|
|
|
#ifdef HAVE_RANDOM
|
|
#ifndef _GNU_SOURCE
|
|
#define _GNU_SOURCE
|
|
#endif /* _GNU_SOURCE */
|
|
#endif /* HAVE_RANDOM */
|
|
|
|
#include "tinydtls.h"
|
|
#include "dtls_prng.h"
|
|
#include "dtls_debug.h"
|
|
|
|
#ifdef HAVE_GETRANDOM
|
|
#include <sys/random.h>
|
|
#endif /* HAVE_GETRANDOM */
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
|
|
/**
|
|
* Fills @p buf with @p len random bytes. This is the default
|
|
* implementation for prng(). You might want to change prng() to use
|
|
* a better PRNG on your specific platform.
|
|
*/
|
|
int
|
|
dtls_prng(unsigned char *buf, size_t len) {
|
|
#ifdef HAVE_GETRANDOM
|
|
return getrandom(buf, len, 0);
|
|
#elif defined(HAVE_RANDOM)
|
|
|
|
#define RAND_BYTES (RAND_MAX >= 0xffffff ? 3 : (RAND_MAX >= 0xffff ? 2 : 1))
|
|
|
|
if (len) {
|
|
size_t klen = len;
|
|
uint8_t byte_counter = RAND_BYTES;
|
|
uint32_t rand_val = random();
|
|
while (1) {
|
|
*buf++ = rand_val & 0xFF;
|
|
if (!--klen) {
|
|
break;
|
|
}
|
|
if (--byte_counter) {
|
|
rand_val >>= 8;
|
|
} else {
|
|
rand_val = random();
|
|
byte_counter = RAND_BYTES;
|
|
}
|
|
}
|
|
}
|
|
return len;
|
|
#else /*!HAVE_GETRANDOM && !HAVE_RANDOM */
|
|
#error "CVE-2021-34430: using rand() for crypto randoms is not secure!"
|
|
#error "Please update you C-library and rerun the auto-configuration."
|
|
size_t klen = len;
|
|
while (len--)
|
|
*buf++ = rand() & 0xFF;
|
|
return klen;
|
|
#endif /* !HAVE_GETRANDOM */
|
|
}
|
|
|
|
void
|
|
dtls_prng_init(unsigned seed) {
|
|
#ifdef HAVE_GETRANDOM
|
|
/* No seed to seed the random source if getrandom() is used,
|
|
* see dtls_prng(). */
|
|
(void)seed;
|
|
#else /* !HAVE_GETRANDOM */
|
|
FILE *urandom = fopen("/dev/urandom", "r");
|
|
unsigned char buf[sizeof(unsigned long)];
|
|
(void)seed;
|
|
|
|
if (!urandom) {
|
|
dtls_emerg("cannot initialize PRNG\n");
|
|
return;
|
|
}
|
|
|
|
if (fread(buf, 1, sizeof(buf), urandom) != sizeof(buf)) {
|
|
dtls_emerg("cannot initialize PRNG\n");
|
|
return;
|
|
}
|
|
|
|
fclose(urandom);
|
|
#ifdef HAVE_RANDOM
|
|
srandom((unsigned long)*buf);
|
|
#else
|
|
srand((unsigned long)*buf);
|
|
#endif
|
|
#endif /* !HAVE_GETRANDOM */
|
|
}
|
|
|