libcoap 4.3.5-develop-4fa3dfa
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-2025 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
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
80void
81coap_prng_init_lkd(unsigned int seed) {
82 (void)seed;
83}
84
85int
86coap_prng_lkd(void *bufp, size_t len) {
87 unsigned char *buf = (unsigned char *)bufp;
88 u32_t v = LWIP_RAND();
89
90 while (len > sizeof(v)) {
91 memcpy(buf, &v, sizeof(v));
92 len -= sizeof(v);
93 buf += sizeof(v);
94 v = LWIP_RAND();
95 }
96
97 memcpy(buf, &v, len);
98 return 1;
99}
100
101#else
102
103/*
104 * This, or any user provided alternative, function is expected to
105 * return 0 on failure and 1 on success.
106 */
107static int
108coap_prng_default(void *buf, size_t len) {
109#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
110 /* mbedtls_hardware_poll() returns 0 on success */
111 return (mbedtls_hardware_poll(NULL, buf, len, NULL) ? 0 : 1);
112
113#elif defined(__ZEPHYR__)
114 /* Use Zephyr's cryptographically secure random number generator */
115 if (!buf || len == 0) {
116 return 0;
117 }
118
119 sys_rand_get(buf, len);
120 return 1;
121
122#elif defined(HAVE_GETRANDOM)
123 return (getrandom(buf, len, 0) > 0) ? 1 : 0;
124
125#elif defined(HAVE_RANDOM)
126#define RAND_BYTES (RAND_MAX >= 0xffffff ? 3 : (RAND_MAX >= 0xffff ? 2 : 1))
127 unsigned char *dst = (unsigned char *)buf;
128
129 if (len) {
130 uint8_t byte_counter = RAND_BYTES;
131 uint32_t r_v = random();
132
133 while (1) {
134 *dst++ = r_v & 0xFF;
135 if (!--len) {
136 break;
137 }
138 if (--byte_counter) {
139 r_v >>= 8;
140 } else {
141 r_v = random();
142 byte_counter = RAND_BYTES;
143 }
144 }
145 }
146 return 1;
147#elif defined(RIOT_VERSION)
148#include <random.h>
149 random_bytes(buf, len);
150 return 1;
151
152#elif defined(WITH_CONTIKI)
153 return csprng_rand(buf, len);
154
155#elif defined(_WIN32)
156 return coap_prng_impl(buf,len);
157
158#else /* !MBEDTLS_ENTROPY_HARDWARE_ALT && !HAVE_GETRANDOM &&
159 !HAVE_RANDOM && !_WIN32 */
160#error "CVE-2021-34430: using rand() for crypto randoms is not secure!"
161#error "Please update you C-library and rerun the auto-configuration."
162 unsigned char *dst = (unsigned char *)buf;
163 while (len--)
164 *dst++ = rand() & 0xFF;
165 return 1;
166#endif /* !MBEDTLS_ENTROPY_HARDWARE_ALT && !HAVE_GETRANDOM &&
167 !HAVE_RANDOM && !_WIN32 */
168}
169
171
172void
176
177void
178coap_prng_init_lkd(unsigned int seed) {
179#ifdef HAVE_GETRANDOM
180 /* No seed to seed the random source if getrandom() is used */
181 (void)seed;
182#elif defined(HAVE_RANDOM)
183 srandom(seed);
184#else /* !HAVE_GETRANDOM && !HAVE_RANDOM */
185 srand(seed);
186#endif /* !HAVE_GETRANDOM */
187}
188
189int
190coap_prng_lkd(void *buf, size_t len) {
191 if (!rand_func) {
192 return 0;
193 }
194
195 return rand_func(buf, len);
196}
197
198#endif
Library specific build wrapper for coap_internal.h.
#define COAP_API
static int coap_prng_default(void *buf, size_t len)
Definition coap_prng.c:108
static coap_rand_func_t rand_func
Definition coap_prng.c:170
void coap_prng_init_lkd(unsigned int seed)
Seeds the default random number generation function with the given seed.
Definition coap_prng.c:178
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:190
int(* coap_rand_func_t)(void *out, size_t len)
Data type for random number generator function.
Definition coap_prng.h:32
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:173
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:55