libcoap 4.3.4
coap_prng.c
Go to the documentation of this file.
1/*
2 * coap_prng.c -- random number generation
3 *
4 * Copyright (C) 2020-2023 Olaf Bergmann <bergmann@tzi.org>
5 *
6 * SPDX-License-Identifier: BSD-2-Clause
7 *
8 * This file is part of the CoAP library libcoap. Please see README
9 * for terms of use.
10 */
11
17#include "coap3/coap_internal.h"
18
19#ifdef HAVE_GETRANDOM
20#include <sys/random.h>
21#elif defined(WITH_CONTIKI)
22#include "lib/csprng.h"
23#else /* !WITH_CONTIKI */
24#include <stdlib.h>
25#endif /* !WITH_CONTIKI */
26
27#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
28#include <entropy_poll.h>
29#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
30
31#if defined(_WIN32)
32
33errno_t __cdecl rand_s(_Out_ unsigned int *_RandomValue);
40coap_prng_impl(unsigned char *buf, size_t len) {
41 while (len != 0) {
42 uint32_t r = 0;
43 size_t i;
44
45 if (rand_s(&r) != 0)
46 return 0;
47 for (i = 0; i < len && i < 4; i++) {
48 *buf++ = (uint8_t)r;
49 r >>= 8;
50 }
51 len -= i;
52 }
53 return 1;
54}
55
56#endif /* _WIN32 */
57
58/*
59 * This, or any user provided alternative, function is expected to
60 * return 0 on failure and 1 on success.
61 */
62static int
63coap_prng_default(void *buf, size_t len) {
64#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
65 /* mbedtls_hardware_poll() returns 0 on success */
66 return (mbedtls_hardware_poll(NULL, buf, len, NULL) ? 0 : 1);
67
68#elif defined(HAVE_GETRANDOM)
69 return (getrandom(buf, len, 0) > 0) ? 1 : 0;
70
71#elif defined(HAVE_RANDOM)
72#define RAND_BYTES (RAND_MAX >= 0xffffff ? 3 : (RAND_MAX >= 0xffff ? 2 : 1))
73 unsigned char *dst = (unsigned char *)buf;
74
75 if (len) {
76 uint8_t byte_counter = RAND_BYTES;
77 uint32_t r_v = random();
78
79 while (1) {
80 *dst++ = r_v & 0xFF;
81 if (!--len) {
82 break;
83 }
84 if (--byte_counter) {
85 r_v >>= 8;
86 } else {
87 r_v = random();
88 byte_counter = RAND_BYTES;
89 }
90 }
91 }
92 return 1;
93#elif defined(RIOT_VERSION)
94#include <random.h>
95 random_bytes(buf, len);
96 return 1;
97
98#elif defined(WITH_CONTIKI)
99 return csprng_rand(buf, len);
100
101#elif defined(_WIN32)
102 return coap_prng_impl(buf,len);
103
104#else /* !MBEDTLS_ENTROPY_HARDWARE_ALT && !HAVE_GETRANDOM &&
105 !HAVE_RANDOM && !_WIN32 */
106#error "CVE-2021-34430: using rand() for crypto randoms is not secure!"
107#error "Please update you C-library and rerun the auto-configuration."
108 unsigned char *dst = (unsigned char *)buf;
109 while (len--)
110 *dst++ = rand() & 0xFF;
111 return 1;
112#endif /* !MBEDTLS_ENTROPY_HARDWARE_ALT && !HAVE_GETRANDOM &&
113 !HAVE_RANDOM && !_WIN32 */
114}
115
117
118#if defined(WITH_LWIP) && defined(LWIP_RAND)
119
120#else
121
122void
124 rand_func = rng;
125}
126
127void
128coap_prng_init(unsigned int seed) {
129#ifdef HAVE_GETRANDOM
130 /* No seed to seed the random source if getrandom() is used */
131 (void)seed;
132#elif defined(HAVE_RANDOM)
133 srandom(seed);
134#else /* !HAVE_GETRANDOM && !HAVE_RANDOM */
135 srand(seed);
136#endif /* !HAVE_GETRANDOM */
137}
138
139int
140coap_prng(void *buf, size_t len) {
141 if (!rand_func) {
142 return 0;
143 }
144
145 return rand_func(buf, len);
146}
147
148#endif
Pulls together all the internal only header files.
static int coap_prng_default(void *buf, size_t len)
Definition: coap_prng.c:63
static coap_rand_func_t rand_func
Definition: coap_prng.c:116
int(* coap_rand_func_t)(void *out, size_t len)
Data type for random number generator function.
Definition: coap_prng.h:53
void coap_set_prng(coap_rand_func_t rng)
Replaces the current random number generation function with the default function rng.
Definition: coap_prng.c:123
int coap_prng(void *buf, size_t len)
Fills buf with len random bytes using the default pseudo random number generator.
Definition: coap_prng.c:140
void coap_prng_init(unsigned int seed)
Seeds the default random number generation function with the given seed.
Definition: coap_prng.c:128
#define COAP_STATIC_INLINE
Definition: libcoap.h:53