net: coap: Add internal init function to seed message_id

Randomly generating ID the first time coap_next_id() is called is more
in accordance with CoAP recommendations (see
https://tools.ietf.org/html/draft-ietf-core-coap-18, section 4.4)

"It is strongly recommended that the initial value of the
variable (e.g., on startup) be randomized, in order to make successful
off-path attacks on the protocol less likely."

Doing this in a dedicated init function is the cleanest and most
idiomatic approach. This init function is not exposed publically which
means it will be called only once, by the network stack init procedure.

Signed-off-by: Benjamin Lindqvist <benjamin.lindqvist@endian.se>
This commit is contained in:
Benjamin Lindqvist 2019-09-17 13:42:46 +02:00 committed by Jukka Rissanen
commit 81ccbd96c9
4 changed files with 46 additions and 6 deletions

View file

@ -357,12 +357,7 @@ u8_t *coap_next_token(void);
* *
* @return a new message id * @return a new message id
*/ */
static inline u16_t coap_next_id(void) u16_t coap_next_id(void);
{
static u16_t message_id;
return ++message_id;
}
/** /**
* @brief Return the values associated with the option of value @a * @brief Return the values associated with the option of value @a

View file

@ -453,6 +453,8 @@ static inline int services_init(void)
dns_init_resolver(); dns_init_resolver();
websocket_init(); websocket_init();
net_coap_init();
net_shell_init(); net_shell_init();
return status; return status;

View file

@ -90,6 +90,22 @@ int net_context_get_timestamp(struct net_context *context,
struct net_ptp_time *timestamp); struct net_ptp_time *timestamp);
#endif #endif
#if defined(CONFIG_COAP)
/**
* @brief CoAP init function declaration. It belongs here because we don't want
* to expose it as a public API -- it should only be called once, and only by
* net_core.
*/
extern void net_coap_init(void);
#else
static inline void net_coap_init(void)
{
return;
}
#endif
#if defined(CONFIG_NET_GPTP) #if defined(CONFIG_NET_GPTP)
/** /**
* @brief Initialize Precision Time Protocol Layer. * @brief Initialize Precision Time Protocol Layer.

View file

@ -12,6 +12,8 @@ LOG_MODULE_REGISTER(net_coap, CONFIG_COAP_LOG_LEVEL);
#include <string.h> #include <string.h>
#include <stdbool.h> #include <stdbool.h>
#include <errno.h> #include <errno.h>
#include <random/rand32.h>
#include <atomic.h>
#include <zephyr/types.h> #include <zephyr/types.h>
#include <sys/byteorder.h> #include <sys/byteorder.h>
@ -45,6 +47,9 @@ LOG_MODULE_REGISTER(net_coap, CONFIG_COAP_LOG_LEVEL);
#define BASIC_HEADER_SIZE 4 #define BASIC_HEADER_SIZE 4
/* The CoAP message ID that is incremented each time coap_next_id() is called. */
static u16_t message_id;
static inline bool append_u8(struct coap_packet *cpkt, u8_t data) static inline bool append_u8(struct coap_packet *cpkt, u8_t data)
{ {
if (!cpkt) { if (!cpkt) {
@ -1397,3 +1402,25 @@ struct coap_observer *coap_find_observer_by_addr(
return NULL; return NULL;
} }
/**
* @brief Internal initialization function for CoAP library.
*
* Called by the network layer init procedure. Seeds the CoAP @message_id with a
* random number in accordance with recommendations in CoAP specification.
*
* @note This function is not exposed in a public header, as it's for internal
* use and should therefore not be exposed to applications.
*
* @return N/A
*/
void net_coap_init(void)
{
/* Initialize message_id to a random number */
message_id = (u16_t)sys_rand32_get();
}
u16_t coap_next_id(void)
{
return message_id++;
}