48#if COAP_OSCORE_SUPPORT
53#define OSC_MOVE_PTR(a,b) do { (a) = (b); (b) = NULL; } while(0)
55static int oscore_context_release_recipients(
oscore_ctx_t *osc_ctx);
58compose_info(uint8_t *buffer,
66 size_t rem_size = buf_size;
73 if (id_context !=
NULL && id_context->
length > 0) {
84 (
const char *)type->
s,
99 if (memcmp(a_ptr, b_ptr, a_len) == 0) {
108 if (c_context->p_osc_ctx) {
114 if (head == osc_ctx) {
117 while (next != head) {
118 if (next == osc_ctx) {
124 prev->
next = osc_ctx;
125 osc_ctx->
next = head;
127 c_context->p_osc_ctx = osc_ctx;
128 osc_ctx->
next = osc_ctx;
137 assert(rcp_ctx->
ref > 0);
138 if (--rcp_ctx->
ref > 0) {
196 while (c_context->p_osc_ctx) {
199 if (osc_ctx->
next == osc_ctx) {
200 c_context->p_osc_ctx =
NULL;
203 c_context->p_osc_ctx = osc_ctx->
next;
204 while (tail->
next != osc_ctx) {
207 tail->
next = c_context->p_osc_ctx;
217 if (oscore_context_release_recipients(osc_ctx) > 0) {
236oscore_context_release_recipients(
oscore_ctx_t *osc_ctx) {
242 while (next !=
NULL) {
244 if (next->
ref <= 1) {
247 oscore_free_recipient_ctx(to_free);
283 if (next == osc_ctx) {
284 if (next->
next == next) {
285 c_context->p_osc_ctx =
NULL;
287 while (prev->
next != next) {
291 if (next == c_context->p_osc_ctx)
292 c_context->p_osc_ctx = next->
next;
300 if (oscore_context_release_recipients(osc_ctx) <= 0) {
310 }
while (next != head);
330 if (session->recipient_ctx) {
331 tmp_ctx = session->recipient_ctx->osc_ctx;
339 if (memcmp(tmp_ctx->
id_context->
s, oscore_r2, 8) == 0) {
343 }
else if (ctxkey_id) {
344 if (session->recipient_ctx->osc_ctx->id_context !=
NULL) {
348 }
else if (ctxkey_id->
length > 0) {
353 *recipient_ctx = session->recipient_ctx;
354 return session->recipient_ctx->osc_ctx;
365 if (tmp_ctx !=
NULL) {
375 while (rcp_ctx !=
NULL) {
380 *recipient_ctx = ref_ctx;
394 (*recipient_ctx)->ref--;
401 *recipient_ctx =
NULL;
402 assert(rcpkey_id.
length == 0 || rcpkey_id.
s !=
NULL);
412 if (rcpkey_id.
length != 0)
416 ok = ok + (memcmp(pt->
id_context->
s, oscore_r2, 8) != 0);
420 }
else if (ctxkey_id) {
428 }
else if (ctxkey_id->
length > 0)
433 *recipient_ctx = rpt;
440 }
while (pt != session->
context->p_osc_ctx);
444#define OSCORE_LOG_SIZE 16
456 coap_log(level,
" %-16s <>\n", name);
460 for (i = 0; i < value->
length; i += OSCORE_LOG_SIZE) {
461 char number[3 * OSCORE_LOG_SIZE + 4];
464 value->
length - i > OSCORE_LOG_SIZE ?
465 OSCORE_LOG_SIZE : value->length - i,
468 coap_log(level,
" %-16s %s\n", i == 0 ? name :
"", number);
475 coap_log(level,
" %-16s %2d\n", name, value);
480 coap_log(level,
" %-16s %s\n", name, value);
492 size_t space = (dst_len - 4) / 3;
495 for (qq = 0; qq < src_len && qq < space; qq++) {
496 char tmp = src[qq] >> 4;
498 tmp = tmp + 0x61 - 10;
504 tmp = tmp + 0x61 - 10;
507 dest[qq * 3 + 1] = tmp;
508 dest[qq * 3 + 2] = 0x20;
512 dest[qq * 3 + 1] =
'.';
513 dest[qq * 3 + 2] =
'.';
527 uint8_t info_buffer[80];
532 if (hkdf_tmp ==
NULL)
535 info_len = compose_info(info_buffer,
542 if (info_len == 0 || info_len >
sizeof(info_buffer)) {
560oscore_log_context(
oscore_ctx_t *osc_ctx,
const char *heading) {
561#if COAP_MAX_LOGGING_LEVEL < _COAP_LOG_OSCORE
590 snprintf(buffer,
sizeof(buffer),
"Recipient ID[%zu]", count);
594 snprintf(buffer,
sizeof(buffer),
"Recipient Key[%zu]", count);
653 oscore_log_context(osc_ctx,
"Updated Common context");
672 if (sender_ctx ==
NULL)
732 if (rcp_conf ==
NULL)
742 oscore_log_context(osc_ctx,
"New Common context");
743 oscore_enter_context(c_context, osc_ctx);
765 if (sender_ctx ==
NULL)
829 if (oscore_conf->
sender) {
852 oscore_log_context(osc_ctx,
"Common context");
861 oscore_enter_context(c_context, osc_ctx);
873 oscore_enter_context(c_context, osc_ctx);
879 uint32_t break_key) {
884 coap_log_warn(
"oscore_add_recipient: Maximum size of recipient_id is 7 bytes\n");
898 if (rcp_ctx ==
NULL) {
960 oscore_free_recipient_ctx(next);
971 recipient_ctx->
ref++;
978 if (recipient_ctx ==
NULL || *recipient_ctx ==
NULL)
982 osc_ctx = (*recipient_ctx)->osc_ctx;
983 oscore_free_recipient_ctx(*recipient_ctx);
991 *recipient_ctx =
NULL;
1021 if (association ==
NULL)
1031 const uint8_t *data;
1102 session->associations =
NULL;
1112#pragma GCC diagnostic ignored "-Wunused-function"
Library specific build wrapper for coap_internal.h.
void * coap_malloc_type(coap_memory_tag_t type, size_t size)
Allocates a chunk of size bytes and returns a pointer to the newly allocated memory.
void coap_free_type(coap_memory_tag_t type, void *p)
Releases the memory that was allocated by coap_malloc_type().
#define COAP_OSCORE_DEFAULT_REPLAY_WINDOW
#define coap_lock_callback_ret(r, func)
Dummy for no thread-safe code.
coap_log_t coap_get_log_level(void)
Get the current logging level.
#define coap_log_oscore(...)
#define coap_log_warn(...)
#define coap_log(level,...)
Logging function.
size_t oscore_cbor_put_text(uint8_t **buffer, size_t *buf_size, const char *text, size_t text_len)
size_t oscore_cbor_put_nil(uint8_t **buffer, size_t *buf_size)
size_t oscore_cbor_put_unsigned(uint8_t **buffer, size_t *buf_size, uint64_t value)
size_t oscore_cbor_put_bytes(uint8_t **buffer, size_t *buf_size, const uint8_t *bytes, size_t bytes_len)
size_t oscore_cbor_put_array(uint8_t **buffer, size_t *buf_size, size_t elements)
const char * cose_get_hkdf_alg_name(cose_hkdf_alg_t id, char *buffer, size_t buflen)
size_t cose_nonce_len(cose_alg_t cose_alg)
size_t cose_key_len(cose_alg_t cose_alg)
const char * cose_get_alg_name(cose_alg_t id, char *buffer, size_t buflen)
void oscore_reference_recipient_ctx(oscore_recipient_ctx_t *recipient_ctx)
Increment the recipient context reference count.
#define OSCORE_ASSOCIATIONS_ITER_SAFE(e, el, rtmp)
void oscore_convert_to_hex(const uint8_t *src, size_t src_len, char *dest, size_t dst_len)
void coap_oscore_association_set_recipient_ctx(oscore_association_t *association, oscore_recipient_ctx_t *recipient_ctx)
Set the recipient context of an association.
oscore_ctx_t * oscore_derive_ctx_from_conf(coap_oscore_conf_t *oscore_conf)
oscore_derive_ctx_from_conf - derive a osc_ctx from oscore_conf information
int oscore_delete_association(coap_session_t *session, oscore_association_t *association)
oscore_recipient_ctx_t * oscore_add_recipient(oscore_ctx_t *ctx, coap_oscore_rcp_conf_t *rcp_conf, uint32_t break_key)
oscore_add_recipient - add in recipient information
oscore_ctx_t * coap_init_oscore_context_from_conf(coap_oscore_conf_t *oscore_conf)
Initializes an OSCORE context from the given configuration.
int oscore_add_context(coap_context_t *c_context, oscore_ctx_t *osc_ctx)
void oscore_free_sender(oscore_sender_ctx_t *snd_ctx)
void coap_oscore_session_set_recipient_ctx(coap_session_t *session, oscore_recipient_ctx_t *recipient_ctx)
Attach the OSCORE recipient context information to the session.
coap_bin_const_t * oscore_build_key(oscore_ctx_t *osc_ctx, coap_bin_const_t *salt, coap_bin_const_t *ikm, cose_alg_t aead_alg, coap_bin_const_t *id, coap_str_const_t *type, size_t out_len)
int oscore_delete_recipient(oscore_ctx_t *osc_ctx, coap_bin_const_t *rid)
#define OSCORE_ASSOCIATIONS_DELETE(r, obj)
void oscore_update_ctx(oscore_ctx_t *osc_ctx, coap_bin_const_t *id_context)
oscore_update_ctx - update a osc_ctx with a new id_context
void oscore_free_context(oscore_ctx_t *osc_ctx)
#define OSCORE_ASSOCIATIONS_ADD(r, obj)
oscore_ctx_t * oscore_derive_ctx(coap_context_t *c_context, coap_oscore_conf_t *oscore_conf)
oscore_derive_ctx - derive a osc_ctx from oscore_conf information
void oscore_free_association(oscore_association_t *association)
int oscore_hkdf(cose_hkdf_alg_t hkdf_alg, coap_bin_const_t *salt, coap_bin_const_t *ikm, uint8_t *info, size_t info_len, uint8_t *okm, size_t okm_len)
Derive the key using HKDF() function.
int oscore_new_association(coap_session_t *session, coap_pdu_t *sent_pdu, coap_bin_const_t *token, oscore_recipient_ctx_t *recipient_ctx, coap_bin_const_t *aad, coap_bin_const_t *nonce, coap_bin_const_t *partial_iv, int is_observe)
void oscore_delete_server_associations(coap_session_t *session)
void oscore_log_char_value(coap_log_t level, const char *name, const char *value)
oscore_ctx_t * oscore_find_context(coap_session_t *session, const coap_bin_const_t rcpkey_id, const coap_bin_const_t *ctxkey_id, uint8_t *oscore_r2, oscore_recipient_ctx_t **recipient_ctx)
oscore_find_context - Locate recipient context (and hence OSCORE context)
void oscore_free_contexts(coap_context_t *c_context)
void oscore_log_hex_value(coap_log_t level, const char *name, coap_bin_const_t *value)
void oscore_log_int_value(coap_log_t level, const char *name, int value)
int oscore_is_context_attached(const oscore_ctx_t *osc_ctx)
Check if oscore context is attached to a the provided context.
oscore_ctx_t * oscore_duplicate_ctx(coap_context_t *c_context, oscore_ctx_t *o_osc_ctx, coap_bin_const_t *sender_id, coap_bin_const_t *recipient_id, coap_bin_const_t *id_context)
oscore_duplicate_ctx - duplicate a osc_ctx
int oscore_remove_context(coap_context_t *c_context, oscore_ctx_t *osc_ctx)
oscore_association_t * oscore_find_association(coap_session_t *session, coap_bin_const_t *token)
int coap_delete_oscore_rcp_conf(coap_oscore_rcp_conf_t *oscore_rcp_conf)
Release all the information associated with the OSCORE complex Recipient configuration.
#define OSCORE_ASSOCIATIONS_FIND(r, k, res)
uint8_t oscore_bytes_equal(uint8_t *a_ptr, uint8_t a_len, uint8_t *b_ptr, uint8_t b_len)
void oscore_release_recipient_ctx(oscore_recipient_ctx_t **recipient_ctx)
Cleanup recipient context, including releasing the oscore context if the oscore context referenced is...
void coap_delete_pdu_lkd(coap_pdu_t *pdu)
Dispose of an CoAP PDU and free off associated storage.
coap_pdu_t * coap_pdu_duplicate_lkd(const coap_pdu_t *old_pdu, coap_session_t *session, size_t token_length, const uint8_t *token, coap_opt_filter_t *drop_options, coap_bool_t expand_opt_abb)
Duplicate an existing PDU.
int coap_get_data(const coap_pdu_t *pdu, size_t *len, const uint8_t **data)
Retrieves the length and data pointer of specified PDU.
int coap_add_data(coap_pdu_t *pdu, size_t len, const uint8_t *data)
Adds given data to the pdu that is passed as first parameter.
void coap_delete_bin_const(coap_bin_const_t *s)
Deletes the given const binary data and releases any memory allocated.
coap_str_const_t * coap_make_str_const(const char *string)
Take the specified byte array (text) and create a coap_str_const_t *.
coap_bin_const_t * coap_new_bin_const(const uint8_t *data, size_t size)
Take the specified byte array (text) and create a coap_bin_const_t * Returns a new const binary objec...
#define coap_binary_equal(binary1, binary2)
Compares the two binary data for equality.
CoAP binary data definition with const data.
size_t length
length of binary data
const uint8_t * s
read-only binary data
The CoAP stack's global state is stored in a coap_context_t object.
The structure used to hold the OSCORE configuration information.
void * save_seq_num_func_param
Passed to save_seq_num_func()
uint32_t rfc8613_b_2
1 if rfc8613 B.2 protocol else 0
cose_hkdf_alg_t hkdf_alg
Set to one of COSE_HKDF_ALG_*.
uint32_t break_sender_key
1 if sender key to be broken, else 0
coap_oscore_snd_conf_t * sender
The sender - i.e.
coap_oscore_rcp_conf_t * recipient_chain
The recipients as a chain.
uint32_t ssn_freq
Sender Seq Num update frequency.
coap_oscore_save_seq_num_t save_seq_num_func
Called every seq num change.
uint32_t rfc8613_b_1_2
1 if rfc8613 B.1.2 enabled else 0
uint64_t start_seq_num
Used for ssn_freq updating.
uint32_t break_recipient_key
1 if recipient key to be broken, else 0
coap_bin_const_t * master_secret
Common Master Secret.
cose_alg_t aead_alg
Set to one of COSE_ALGORITHM_AES*.
coap_bin_const_t * master_salt
Common Master Salt.
uint32_t replay_window
Replay window size Use COAP_OSCORE_DEFAULT_REPLAY_WINDOW.
coap_bin_const_t * id_context
Common ID context.
The structure used to hold the OSCORE Recipient configuration.
int silent_server
1 if server is likely to be silent else 0
coap_bin_const_t * recipient_id
Recipient ID (i.e.
uint64_t last_seq
Highest sequence number used for this recipient.
uint8_t window_initialized
Contains if the sliding window is initialized 1 if initialized, 0 otherwise.
struct coap_oscore_rcp_conf_t * next_recipient
Used to maintain the chain.
uint64_t sliding_window
bitfield sequence counter window
coap_bin_const_t * sender_id
Sender ID (i.e.
Abstraction of virtual session that can be attached to coap_context_t (client) or coap_endpoint_t (se...
coap_context_t * context
session's context
CoAP string data definition with const data.
const uint8_t * s
read-only string data
size_t length
length of string
coap_bin_const_t * obs_partial_iv
coap_bin_const_t * partial_iv
oscore_recipient_ctx_t * recipient_ctx
coap_bin_const_t * master_secret
uint32_t replay_window_size
coap_bin_const_t * common_iv
Derived from Master Secret, Master Salt, and ID Context.
struct oscore_ctx_t * next
uint8_t rfc8613_b_1_2
1 if rfc8613 B.1.2 enabled else 0
void * save_seq_num_func_param
Passed to save_seq_num_func()
oscore_sender_ctx_t * sender_context
cose_hkdf_alg_t hkdf_alg
Set to one of COSE_HKDF_ALG_*.
cose_alg_t aead_alg
Set to one of COSE_ALGORITHM_AES*.
uint8_t rfc8613_b_2
1 if rfc8613 B.2 protocol else 0
coap_bin_const_t * master_salt
coap_oscore_save_seq_num_t save_seq_num_func
Called every seq num change.
oscore_recipient_ctx_t * recipient_chain
coap_bin_const_t * id_context
contains GID in case of group
uint32_t ssn_freq
Sender Seq Num update frequency.
oscore_recipient_ctx_t * next_recipient
This field allows recipient chaining.
unsigned ref
Reference counter to keep track of linked associations / active sessions.
coap_bin_const_t * recipient_key
coap_bin_const_t * recipient_id
coap_bin_const_t * sender_id
uint64_t seq
Sender Sequence Number.
coap_bin_const_t * sender_key
uint64_t next_seq
Used for ssn_freq updating.