Skip to content

Commit

Permalink
coap_prng: Provide global_lock protection
Browse files Browse the repository at this point in the history
  • Loading branch information
mrdeep1 committed Jul 19, 2024
1 parent bbefdfc commit 48b56aa
Show file tree
Hide file tree
Showing 17 changed files with 155 additions and 55 deletions.
1 change: 1 addition & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ EXTRA_DIST = \
include/coap$(LIBCOAP_API_VERSION)/coap_netif_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_oscore_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_pdu_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_prng_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_resource_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_session_internal.h \
include/coap$(LIBCOAP_API_VERSION)/coap_sha1_internal.h \
Expand Down
1 change: 1 addition & 0 deletions examples/lwip/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ COAP_SRC = coap_address.c \
coap_option.c \
coap_oscore.c \
coap_pdu.c \
coap_prng.c \
coap_resource.c \
coap_session.c \
coap_sha1.c \
Expand Down
1 change: 1 addition & 0 deletions include/coap3/coap_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ typedef struct oscore_ctx_t oscore_ctx_t;
#include "coap_oscore_internal.h"
#endif /* COAP_OSCORE_SUPPORT */
#include "coap_pdu_internal.h"
#include "coap_prng_internal.h"
#include "coap_resource_internal.h"
#include "coap_session_internal.h"
#include "coap_sha1_internal.h"
Expand Down
27 changes: 2 additions & 25 deletions include/coap3/coap_prng.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,27 +24,6 @@
* @{
*/

#if defined(WITH_LWIP) && defined(LWIP_RAND)

COAP_STATIC_INLINE int
lwip_prng_impl(unsigned char *buf, size_t len) {
u32_t v = LWIP_RAND();
while (len > sizeof(v)) {
memcpy(buf, &v, sizeof(v));
len -= sizeof(v);
buf += sizeof(v);
v = LWIP_RAND();
}

memcpy(buf, &v, len);
return 1;
}

#define coap_prng(Buf,Length) lwip_prng_impl((Buf), (Length))
#define coap_prng_init(Value) (void)Value

#else

/**
* Data type for random number generator function. The function must
* fill @p len bytes of random data into the buffer starting at @p
Expand All @@ -67,7 +46,7 @@ void coap_set_prng(coap_rand_func_t rng);
*
* @param seed The seed for the pseudo random number generator.
*/
void coap_prng_init(unsigned int seed);
COAP_API void coap_prng_init(unsigned int seed);

/**
* Fills @p buf with @p len random bytes using the default pseudo
Expand All @@ -80,9 +59,7 @@ void coap_prng_init(unsigned int seed);
*
* @return 1 on success, 0 otherwise.
*/
int coap_prng(void *buf, size_t len);

#endif /* POSIX */
COAP_API int coap_prng(void *buf, size_t len);

/** @} */

Expand Down
51 changes: 51 additions & 0 deletions include/coap3/coap_prng_internal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* coap_prng_internal.h -- Pseudo Random Numbers
*
* Copyright (C) 2024 Olaf Bergmann <[email protected]>
*
* SPDX-License-Identifier: BSD-2-Clause
*
* This file is part of the CoAP library libcoap. Please see README for terms
* of use.
*/

/**
* @file coap_prng_internal.h
* @brief Internal Pseudo Random Numbers
*/

#ifndef COAP_PRNG_INTERNAL_H_
#define COAP_PRNG_INTERNAL_H_

/**
* @ingroup internal_api
* @defgroup coap_prng_internal Pseudo Random Numbers
* Internal API for generating pseudo random numbers
* @{
*/

/**
* Seeds the default random number generation function with the given
* @p seed. The default random number generation function will use
* getrandom() if available, ignoring the seed.
*
* @param seed The seed for the pseudo random number generator.
*/
void coap_prng_init_lkd(unsigned int seed);

/**
* Fills @p buf with @p len random bytes using the default pseudo
* random number generator. The default PRNG can be changed with
* coap_set_prng(). This function returns 1 when @p len random bytes
* have been written to @p buf, zero otherwise.
*
* @param buf The buffer to fill with random bytes.
* @param len The number of random bytes to write into @p buf.
*
* @return 1 on success, 0 otherwise.
*/
int coap_prng_lkd(void *buf, size_t len);

/** @} */

#endif /* COAP_PRNG_H_ */
1 change: 0 additions & 1 deletion include/coap3/coap_threadsafe_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,6 @@ int coap_lock_lock_func(void);
*
*/
#define coap_lock_lock(c,failed) do { \
assert(c); \
if (!coap_lock_lock_func()) { \
failed; \
} \
Expand Down
2 changes: 1 addition & 1 deletion src/coap_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -1386,7 +1386,7 @@ coap_debug_send_packet(void) {
}
if (packet_loss_level > 0) {
uint16_t r = 0;
coap_prng((uint8_t *)&r, 2);
coap_prng_lkd((uint8_t *)&r, 2);
if (r < packet_loss_level) {
coap_log_debug("Packet %u dropped\n", send_packet_count);
return 0;
Expand Down
4 changes: 2 additions & 2 deletions src/coap_mbedtls.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ typedef enum coap_enc_method_t {
*/
static int
coap_rng(void *ctx COAP_UNUSED, unsigned char *buf, size_t len) {
return coap_prng(buf, len) ? 0 : MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED;
return coap_prng_lkd(buf, len) ? 0 : MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED;
}
#endif /* MBEDTLS_2_X_COMPAT */

Expand Down Expand Up @@ -1757,7 +1757,7 @@ coap_dtls_new_mbedtls_env(coap_session_t *c_session,
* to use RFC9146 extension ID of 54, rather than the draft version -05
* value of 254.
*/
coap_prng(cid, sizeof(cid));
coap_prng_lkd(cid, sizeof(cid));
mbedtls_ssl_set_cid(&m_env->ssl, MBEDTLS_SSL_CID_ENABLED, cid,
sizeof(cid));
}
Expand Down
8 changes: 4 additions & 4 deletions src/coap_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -1818,7 +1818,7 @@ coap_send_internal(coap_session_t *session, coap_pdu_t *pdu) {

node->id = pdu->mid;
node->pdu = pdu;
coap_prng(&r, sizeof(r));
coap_prng_lkd(&r, sizeof(r));
/* add timeout in range [ACK_TIMEOUT...ACK_TIMEOUT * ACK_RANDOM_FACTOR] */
node->timeout = coap_calc_timeout(session, r);
return coap_wait_ack(session->context, session, node);
Expand Down Expand Up @@ -1846,7 +1846,7 @@ coap_retransmit(coap_context_t *context, coap_queue_t *node) {
context->ping_timeout * COAP_TICKS_PER_SECOND < next_delay) {
uint8_t byte;

coap_prng(&byte, sizeof(byte));
coap_prng_lkd(&byte, sizeof(byte));
/* Don't exceed the ping timeout value */
next_delay = context->ping_timeout * COAP_TICKS_PER_SECOND - 255 + byte;
}
Expand Down Expand Up @@ -3548,7 +3548,7 @@ handle_request(coap_context_t *context, coap_session_t *session, coap_pdu_t *pdu
node->id = response->mid;
node->pdu = response;
node->is_mcast = 1;
coap_prng(&r, sizeof(r));
coap_prng_lkd(&r, sizeof(r));
delay = (COAP_DEFAULT_LEISURE_TICKS(session) * r) / 256;
coap_log_debug(" %s: mid=0x%04x: mcast response delayed for %u.%03u secs\n",
coap_session_str(session),
Expand Down Expand Up @@ -4441,7 +4441,7 @@ coap_startup(void) {
#ifndef WITH_CONTIKI
us = coap_ticks_to_rt_us(now);
/* Be accurate to the nearest (approx) us */
coap_prng_init((unsigned int)us);
coap_prng_init_lkd((unsigned int)us);
#else /* WITH_CONTIKI */
coap_start_io_process();
#endif /* WITH_CONTIKI */
Expand Down
2 changes: 1 addition & 1 deletion src/coap_openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1100,7 +1100,7 @@ coap_dtls_new_context(coap_context_t *coap_context) {
if (!RAND_bytes(cookie_secret, (int)sizeof(cookie_secret))) {
coap_dtls_log(COAP_LOG_WARN,
"Insufficient entropy for random cookie generation");
coap_prng(cookie_secret, sizeof(cookie_secret));
coap_prng_lkd(cookie_secret, sizeof(cookie_secret));
}
context->dtls.cookie_hmac = HMAC_CTX_new();
if (!HMAC_Init_ex(context->dtls.cookie_hmac, cookie_secret, (int)sizeof(cookie_secret),
Expand Down
8 changes: 4 additions & 4 deletions src/coap_oscore.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ coap_oscore_initiate(coap_session_t *session, coap_oscore_conf_t *oscore_conf) {
if (id_context == NULL)
return 0;
coap_delete_bin_const(oscore_conf->id_context);
coap_prng(id_context->s, id_context->length);
coap_prng_lkd(id_context->s, id_context->length);
oscore_conf->id_context = (coap_bin_const_t *)id_context;
session->b_2_step = COAP_OSCORE_B_2_STEP_1;
coap_log_oscore("Appendix B.2 client step 1 (Generated ID1)\n");
Expand Down Expand Up @@ -1399,7 +1399,7 @@ coap_oscore_decrypt_pdu(coap_session_t *session,
goto error;
}

coap_prng(&session->oscore_r2, sizeof(session->oscore_r2));
coap_prng_lkd(&session->oscore_r2, sizeof(session->oscore_r2));
memcpy(kc->s, &session->oscore_r2, sizeof(session->oscore_r2));
memcpy(&kc->s[sizeof(session->oscore_r2)],
cose->kid_context.s,
Expand Down Expand Up @@ -1453,7 +1453,7 @@ coap_oscore_decrypt_pdu(coap_session_t *session,
goto error;
}
memcpy(kc->s, cose->kid_context.s, cose->kid_context.length);
coap_prng(&kc->s[cose->kid_context.length], 8);
coap_prng_lkd(&kc->s[cose->kid_context.length], 8);

oscore_update_ctx(osc_ctx, (coap_bin_const_t *)kc);

Expand Down Expand Up @@ -1501,7 +1501,7 @@ coap_oscore_decrypt_pdu(coap_session_t *session,
session->b_2_step = COAP_OSCORE_B_2_NONE;
coap_log_oscore("Appendix B.2 server finished\n");
}
coap_prng(rcp_ctx->echo_value, sizeof(rcp_ctx->echo_value));
coap_prng_lkd(rcp_ctx->echo_value, sizeof(rcp_ctx->echo_value));
coap_log_oscore("Appendix B.1.2 server plain response\n");
build_and_send_error_pdu(session,
pdu,
Expand Down
50 changes: 44 additions & 6 deletions src/coap_prng.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,48 @@ coap_prng_impl(unsigned char *buf, size_t len) {

#endif /* _WIN32 */

COAP_API void
coap_prng_init(unsigned int seed) {
coap_lock_lock(NULL, return);
coap_prng_init_lkd(seed);
coap_lock_unlock(NULL);
}

COAP_API int
coap_prng(void *buf, size_t len) {
int ret;

coap_lock_lock(NULL, return 0);
ret = coap_prng_lkd(buf, len);
coap_lock_unlock(NULL);
return ret;
}

#if defined(WITH_LWIP) && defined(LWIP_RAND)

void
coap_prng_init_lkd(unsigned int seed) {
(void)seed;
}

int
coap_prng_lkd(void *bufp, size_t len) {
unsigned char *buf = (unsigned char *)bufp;
u32_t v = LWIP_RAND();

while (len > sizeof(v)) {
memcpy(buf, &v, sizeof(v));
len -= sizeof(v);
buf += sizeof(v);
v = LWIP_RAND();
}

memcpy(buf, &v, len);
return 1;
}

#else

/*
* This, or any user provided alternative, function is expected to
* return 0 on failure and 1 on success.
Expand Down Expand Up @@ -115,17 +157,13 @@ coap_prng_default(void *buf, size_t len) {

static coap_rand_func_t rand_func = coap_prng_default;

#if defined(WITH_LWIP) && defined(LWIP_RAND)

#else

void
coap_set_prng(coap_rand_func_t rng) {
rand_func = rng;
}

void
coap_prng_init(unsigned int seed) {
coap_prng_init_lkd(unsigned int seed) {
#ifdef HAVE_GETRANDOM
/* No seed to seed the random source if getrandom() is used */
(void)seed;
Expand All @@ -137,7 +175,7 @@ coap_prng_init(unsigned int seed) {
}

int
coap_prng(void *buf, size_t len) {
coap_prng_lkd(void *buf, size_t len) {
if (!rand_func) {
return 0;
}
Expand Down
8 changes: 4 additions & 4 deletions src/coap_session.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ coap_get_non_timeout_random(coap_session_t *session) {
coap_fixed_point_t res;
uint8_t ran;

coap_prng(&ran, sizeof(ran));
coap_prng_lkd(&ran, sizeof(ran));
res = coap_sub_fixed_uint(COAP_ACK_RANDOM_FACTOR(session), 1);
res = coap_multi_fixed_uint(res, ran);
res = coap_div_fixed_uint(res, 0xff);
Expand Down Expand Up @@ -478,8 +478,8 @@ coap_make_session(coap_proto_t proto, coap_session_type_t type,
/* Randomly initialize */
/* TCP/TLS have no notion of mid */
if (COAP_PROTO_NOT_RELIABLE(session->proto))
coap_prng((unsigned char *)&session->tx_mid, sizeof(session->tx_mid));
coap_prng((unsigned char *)&session->tx_rtag, sizeof(session->tx_rtag));
coap_prng_lkd((unsigned char *)&session->tx_mid, sizeof(session->tx_mid));
coap_prng_lkd((unsigned char *)&session->tx_rtag, sizeof(session->tx_rtag));

return session;
}
Expand Down Expand Up @@ -719,7 +719,7 @@ coap_session_delay_pdu(coap_session_t *session, coap_pdu_t *pdu,
node->pdu = pdu;
if (pdu->type == COAP_MESSAGE_CON && COAP_PROTO_NOT_RELIABLE(session->proto)) {
uint8_t r;
coap_prng(&r, sizeof(r));
coap_prng_lkd(&r, sizeof(r));
/* add timeout in range [ACK_TIMEOUT...ACK_TIMEOUT * ACK_RANDOM_FACTOR] */
node->timeout = coap_calc_timeout(session, r);
}
Expand Down
2 changes: 1 addition & 1 deletion src/coap_wolfssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -890,7 +890,7 @@ setup_dtls_context(coap_wolfssl_context_t *w_context) {
if (!wolfSSL_RAND_bytes(cookie_secret, (int)sizeof(cookie_secret))) {
coap_dtls_log(COAP_LOG_WARN,
"Insufficient entropy for random cookie generation");
coap_prng(cookie_secret, sizeof(cookie_secret));
coap_prng_lkd(cookie_secret, sizeof(cookie_secret));
}
w_context->dtls.cookie_hmac = wolfSSL_HMAC_CTX_new();
if (!wolfSSL_HMAC_Init_ex(w_context->dtls.cookie_hmac, cookie_secret, (int)sizeof(cookie_secret),
Expand Down
6 changes: 3 additions & 3 deletions src/coap_ws.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ coap_ws_write(coap_session_t *session, const uint8_t *data, size_t datalen) {
/* Need to set the Mask bit, and set the masking key */
ws_header[1] |= WS_B1_MASK_BIT;
/* TODO Masking Key and mask provided data */
coap_prng(&ws_header[hdr_len], 4);
coap_prng_lkd(&ws_header[hdr_len], 4);
memcpy(session->ws->mask_key, &ws_header[hdr_len], 4);
hdr_len += 4;
}
Expand Down Expand Up @@ -810,7 +810,7 @@ coap_ws_establish(coap_session_t *session) {
coap_session_disconnected_lkd(session, COAP_NACK_WS_LAYER_FAILED);
return;
}
coap_prng(session->ws->key, sizeof(session->ws->key));
coap_prng_lkd(session->ws->key, sizeof(session->ws->key));
coap_ws_log_key(session);
if (!coap_base64_encode_buffer(session->ws->key, sizeof(session->ws->key),
base64, sizeof(base64)))
Expand Down Expand Up @@ -866,7 +866,7 @@ coap_ws_close(coap_session_t *session) {
if (session->ws->state == COAP_SESSION_TYPE_CLIENT) {
/* Need to set the Mask bit, and set the masking key */
ws_header[1] |= WS_B1_MASK_BIT;
coap_prng(&ws_header[hdr_len], 4);
coap_prng_lkd(&ws_header[hdr_len], 4);
memcpy(session->ws->mask_key, &ws_header[hdr_len], 4);
hdr_len += 4;
}
Expand Down
Loading

0 comments on commit 48b56aa

Please sign in to comment.