libcoap 4.3.5-develop-f52fada
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_rand_get(buf, len);
122 return 1;
123
124#elif defined(HAVE_GETRANDOM)
125 return (getrandom(buf, len, 0) > 0) ? 1 : 0;
126
127#elif defined(HAVE_RANDOM)
128#define RAND_BYTES (RAND_MAX >= 0xffffff ? 3 : (RAND_MAX >= 0xffff ? 2 : 1))
129 unsigned char *dst = (unsigned char *)buf;
130
131 if (len) {
132 uint8_t byte_counter = RAND_BYTES;
133 uint32_t r_v = random();
134
135 while (1) {
136 *dst++ = r_v & 0xFF;
137 if (!--len) {
138 break;
139 }
140 if (--byte_counter) {
141 r_v >>= 8;
142 } else {
143 r_v = random();
144 byte_counter = RAND_BYTES;
145 }
146 }
147 }
148 return 1;
149#elif defined(RIOT_VERSION)
150#include <random.h>
151 random_bytes(buf, len);
152 return 1;
153
154#elif defined(WITH_CONTIKI)
155 return csprng_rand(buf, len);
156
157#elif defined(_WIN32)
158 return coap_prng_impl(buf,len);
159
160#else /* !MBEDTLS_ENTROPY_HARDWARE_ALT && !HAVE_GETRANDOM &&
161 !HAVE_RANDOM && !_WIN32 */
162#error "CVE-2021-34430: using rand() for crypto randoms is not secure!"
163#error "Please update you C-library and rerun the auto-configuration."
164 unsigned char *dst = (unsigned char *)buf;
165 while (len--)
166 *dst++ = rand() & 0xFF;
167 return 1;
168#endif /* !MBEDTLS_ENTROPY_HARDWARE_ALT && !HAVE_GETRANDOM &&
169 !HAVE_RANDOM && !_WIN32 */
170}
171
173
174void
178
179void
180coap_prng_init_lkd(unsigned int seed) {
181#ifdef HAVE_GETRANDOM
182 /* No seed to seed the random source if getrandom() is used */
183 (void)seed;
184#elif defined(HAVE_RANDOM)
185 srandom(seed);
186#else /* !HAVE_GETRANDOM && !HAVE_RANDOM */
187 srand(seed);
188#endif /* !HAVE_GETRANDOM */
189}
190
191int
192coap_prng_lkd(void *buf, size_t len) {
193 if (!rand_func) {
194 return 0;
195 }
196
197 return rand_func(buf, len);
198}
199
200#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:172
void coap_prng_init_lkd(unsigned int seed)
Seeds the default random number generation function with the given seed.
Definition coap_prng.c:180
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:192
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:175
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