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