libcoap 4.3.5-develop-bbeb8c1
Loading...
Searching...
No Matches
coap_prng.c
Go to the documentation of this file.
1/*
2 * coap_prng.c -- random number generation
3 *
4 * Copyright (C) 2020-2026 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
16
18
19
20#if defined(__ZEPHYR__)
21#include <zephyr/random/random.h>
22#elif defined(HAVE_GETRANDOM)
23#include <sys/random.h>
24#elif defined(WITH_CONTIKI)
25#include "lib/csprng.h"
26#else /* !WITH_CONTIKI */
27#include <stdlib.h>
28#endif /* !WITH_CONTIKI */
29
30#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
31#include <entropy_poll.h>
32#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */
33
34#if defined(_WIN32)
35
36errno_t __cdecl rand_s(_Out_ unsigned int *_RandomValue);
43coap_prng_impl(unsigned char *buf, size_t len) {
44 while (len != 0) {
45 uint32_t r = 0;
46 size_t i;
47
48 if (rand_s(&r) != 0)
49 return 0;
50 for (i = 0; i < len && i < 4; i++) {
51 *buf++ = (uint8_t)r;
52 r >>= 8;
53 }
54 len -= i;
55 }
56 return 1;
57}
58
59#endif /* _WIN32 */
60
61COAP_API void
62coap_prng_init(unsigned int seed) {
63 coap_lock_lock(return);
66}
67
68COAP_API int
69coap_prng(void *buf, size_t len) {
70 int ret;
71
72 coap_lock_lock(return 0);
73 ret = coap_prng_lkd(buf, len);
75 return ret;
76}
77
78#if defined(WITH_LWIP) && defined(LWIP_RAND)
79
80static unsigned int random_seed;
81
82void
83coap_prng_init_lkd(unsigned int seed) {
84 random_seed = seed;
85}
86
87int
88coap_prng_lkd(void *bufp, size_t len) {
89 unsigned char *buf = (unsigned char *)bufp;
90 u32_t v = LWIP_RAND() + random_seed;
91
92 while (len > sizeof(v)) {
93 memcpy(buf, &v, sizeof(v));
94 len -= sizeof(v);
95 buf += sizeof(v);
96 v = LWIP_RAND();
97 }
98
99 memcpy(buf, &v, len);
100 return 1;
101}
102
103#else
104
105/*
106 * This, or any user provided alternative, function is expected to
107 * return 0 on failure and 1 on success.
108 */
109static int
110coap_prng_default(void *buf, size_t len) {
111#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
112 /* mbedtls_hardware_poll() returns 0 on success */
113 return (mbedtls_hardware_poll(NULL, buf, len, NULL) ? 0 : 1);
114
115#elif defined(__ZEPHYR__)
116 /* Use Zephyr's cryptographically secure random number generator */
117 if (!buf || len == 0) {
118 return 0;
119 }
120
121 /* sys_csrand_get() returns 0 on success */
122 return (sys_csrand_get(buf, len) ? 0 : 1);
123
124#elif defined(HAVE_GETRANDOM)
125 return (getrandom(buf, len, 0) > 0) ? 1 : 0;
126
127#elif defined(HAVE_GETENTROPY)
128 return (getentropy(buf, len) == 0) ? 1 : 0;
129
130#elif defined(HAVE_RANDOM)
131#define RAND_BYTES (RAND_MAX >= 0xffffff ? 3 : (RAND_MAX >= 0xffff ? 2 : 1))
132 unsigned char *dst = (unsigned char *)buf;
133
134 if (len) {
135 uint8_t byte_counter = RAND_BYTES;
136 uint32_t r_v = random();
137
138 while (1) {
139 *dst++ = r_v & 0xFF;
140 if (!--len) {
141 break;
142 }
143 if (--byte_counter) {
144 r_v >>= 8;
145 } else {
146 r_v = random();
147 byte_counter = RAND_BYTES;
148 }
149 }
150 }
151 return 1;
152#elif defined(RIOT_VERSION)
153#include <random.h>
154 random_bytes(buf, len);
155 return 1;
156
157#elif defined(WITH_CONTIKI)
158 return csprng_rand(buf, len);
159
160#elif defined(_WIN32)
161 return coap_prng_impl(buf,len);
162
163#else /* !MBEDTLS_ENTROPY_HARDWARE_ALT && !HAVE_GETRANDOM &&
164 !HAVE_RANDOM && !_WIN32 */
165#error "CVE-2021-34430: using rand() for crypto randoms is not secure!"
166#error "Please update you C-library and rerun the auto-configuration."
167 unsigned char *dst = (unsigned char *)buf;
168 while (len--)
169 *dst++ = rand() & 0xFF;
170 return 1;
171#endif /* !MBEDTLS_ENTROPY_HARDWARE_ALT && !HAVE_GETRANDOM &&
172 !HAVE_RANDOM && !_WIN32 */
173}
174
176
177void
181
182void
183coap_prng_init_lkd(unsigned int seed) {
184#ifdef HAVE_GETRANDOM
185 /* No seed to seed the random source if getrandom() is used */
186 (void)seed;
187#elif defined(HAVE_RANDOM)
188 srandom(seed);
189#else /* !HAVE_GETRANDOM && !HAVE_RANDOM */
190 srand(seed);
191#endif /* !HAVE_GETRANDOM */
192}
193
194int
195coap_prng_lkd(void *buf, size_t len) {
196 if (!rand_func) {
197 return 0;
198 }
199
200 return rand_func(buf, len);
201}
202
203#endif
Library specific build wrapper for coap_internal.h.
#define COAP_API
#define NULL
Definition coap_option.h:30
static int coap_prng_default(void *buf, size_t len)
Definition coap_prng.c:110
static coap_rand_func_t rand_func
Definition coap_prng.c:175
void coap_prng_init_lkd(unsigned int seed)
Seeds the default random number generation function with the given seed.
Definition coap_prng.c:183
int coap_prng_lkd(void *buf, size_t len)
Fills buf with len random bytes using the default pseudo random number generator.
Definition coap_prng.c:195
int(* coap_rand_func_t)(void *out, size_t len)
Data type for random number generator function.
Definition coap_prng.h:36
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:178
COAP_API 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:69
COAP_API void coap_prng_init(unsigned int seed)
Seeds the default random number generation function with the given seed.
Definition coap_prng.c:62
#define coap_lock_unlock()
Dummy for no thread-safe code.
#define coap_lock_lock(failed)
Dummy for no thread-safe code.
#define COAP_STATIC_INLINE
Definition libcoap.h:57