Loading...
Searching...
No Matches
oscore_context.c
Go to the documentation of this file.
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* Copyright (c) 2018, SICS, RISE AB
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include "coap3/coap_libcoap_build.h"
#include <stdio.h>
static void oscore_enter_context(coap_context_t *c_context,
oscore_ctx_t *osc_ctx);
static size_t
compose_info(uint8_t *buffer,
size_t buf_size,
uint8_t alg,
coap_bin_const_t *id,
coap_bin_const_t *id_context,
coap_str_const_t *type,
size_t out_len) {
size_t ret = 0;
size_t rem_size = buf_size;
ret += oscore_cbor_put_array(&buffer, &rem_size, 5);
ret += oscore_cbor_put_bytes(&buffer,
&rem_size,
id ? id->s : NULL,
id ? id->length : 0);
if (id_context != NULL && id_context->length > 0) {
ret += oscore_cbor_put_bytes(&buffer,
&rem_size,
id_context->s,
id_context->length);
} else {
ret += oscore_cbor_put_nil(&buffer, &rem_size);
}
ret += oscore_cbor_put_unsigned(&buffer, &rem_size, alg);
ret += oscore_cbor_put_text(&buffer,
&rem_size,
(const char *)type->s,
type->length);
ret += oscore_cbor_put_unsigned(&buffer, &rem_size, out_len);
return ret;
}
uint8_t
oscore_bytes_equal(uint8_t *a_ptr,
uint8_t a_len,
uint8_t *b_ptr,
uint8_t b_len) {
if (a_len != b_len) {
return 0;
}
if (memcmp(a_ptr, b_ptr, a_len) == 0) {
return 1;
} else {
return 0;
}
}
static void
oscore_enter_context(coap_context_t *c_context, oscore_ctx_t *osc_ctx) {
if (c_context->p_osc_ctx) {
oscore_ctx_t *prev = c_context->p_osc_ctx;
oscore_ctx_t *next = c_context->p_osc_ctx->next;
while (next) {
prev = next;
next = next->next;
}
prev->next = osc_ctx;
} else
c_context->p_osc_ctx = osc_ctx;
}
static void
oscore_free_recipient(oscore_recipient_ctx_t *recipient) {
coap_delete_bin_const(recipient->recipient_id);
coap_delete_bin_const(recipient->recipient_key);
coap_free_type(COAP_OSCORE_REC, recipient);
}
void
oscore_free_context(oscore_ctx_t *osc_ctx) {
if (osc_ctx == NULL)
return;
if (osc_ctx->sender_context) {
coap_delete_bin_const(osc_ctx->sender_context->sender_id);
coap_delete_bin_const(osc_ctx->sender_context->sender_key);
coap_free_type(COAP_OSCORE_SEN, osc_ctx->sender_context);
}
while (osc_ctx->recipient_chain) {
oscore_recipient_ctx_t *next = osc_ctx->recipient_chain->next_recipient;
oscore_free_recipient(osc_ctx->recipient_chain);
osc_ctx->recipient_chain = next;
}
coap_delete_bin_const(osc_ctx->master_secret);
coap_delete_bin_const(osc_ctx->master_salt);
coap_delete_bin_const(osc_ctx->id_context);
coap_delete_bin_const(osc_ctx->common_iv);
coap_free_type(COAP_OSCORE_COM, osc_ctx);
}
void
oscore_free_contexts(coap_context_t *c_context) {
while (c_context->p_osc_ctx) {
oscore_ctx_t *osc_ctx = c_context->p_osc_ctx;
c_context->p_osc_ctx = osc_ctx->next;
oscore_free_context(osc_ctx);
}
}
int
oscore_remove_context(coap_context_t *c_context, oscore_ctx_t *osc_ctx) {
oscore_ctx_t *prev = NULL;
oscore_ctx_t *next = c_context->p_osc_ctx;
while (next) {
if (next == osc_ctx) {
if (prev != NULL)
prev->next = next->next;
else
c_context->p_osc_ctx = next->next;
oscore_free_context(next);
return 1;
}
prev = next;
next = next->next;
}
return 0;
}
/*
* oscore_find_context
* Finds OSCORE context for rcpkey_id and optional ctxkey_id
* rcpkey_id can be 0 length.
* Updates recipient_ctx.
*/
oscore_ctx_t *
oscore_find_context(const coap_context_t *c_context,
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_ctx_t *pt = c_context->p_osc_ctx;
*recipient_ctx = NULL;
assert(rcpkey_id.length == 0 || rcpkey_id.s != NULL);
while (pt != NULL) {
int ok = 0;
oscore_recipient_ctx_t *rpt = pt->recipient_chain;
while (rpt) {
ok = 0;
if (rcpkey_id.length == rpt->recipient_id->length) {
if (rcpkey_id.length != 0)
ok = memcmp(rpt->recipient_id->s, rcpkey_id.s, rcpkey_id.length) != 0;
if (oscore_r2) {
if (pt->id_context != NULL && pt->id_context->length > 8) {
ok = ok + (memcmp(pt->id_context->s, oscore_r2, 8) != 0);
} else {
ok += 1;
}
} else if (ctxkey_id) {
if (pt->id_context != NULL) {
if (ctxkey_id->length != pt->id_context->length)
ok += 1;
else
ok = ok + (memcmp(pt->id_context->s,
ctxkey_id->s,
ctxkey_id->length) != 0);
} else if (ctxkey_id->length > 0)
ok += 1;
}
if (ok == 0) {
/* optional id context and recipient id are the same */
*recipient_ctx = rpt;
return pt; /* OSCORE context found */
}
}
rpt = rpt->next_recipient;
} /* while rpt */
pt = pt->next;
} /* end while */
return NULL;
}
#define OSCORE_LOG_SIZE 16
void
oscore_log_hex_value(coap_log_t level,
const char *name,
coap_bin_const_t *value) {
size_t i;
if (value == NULL) {
coap_log(level, " %-16s\n", name);
return;
}
if (value->length == 0) {
coap_log(level, " %-16s <>\n", name);
return;
}
if (coap_get_log_level() >= level) {
for (i = 0; i < value->length; i += OSCORE_LOG_SIZE) {
char number[3 * OSCORE_LOG_SIZE + 4];
oscore_convert_to_hex(&value->s[i],
value->length - i > OSCORE_LOG_SIZE ?
OSCORE_LOG_SIZE : value->length - i,
number,
sizeof(number));
coap_log(level, " %-16s %s\n", i == 0 ? name : "", number);
}
}
}
void
oscore_log_int_value(coap_log_t level, const char *name, int value) {
coap_log(level, " %-16s %2d\n", name, value);
}
void
oscore_log_char_value(coap_log_t level, const char *name, const char *value) {
coap_log(level, " %-16s %s\n", name, value);
}
void
oscore_convert_to_hex(const uint8_t *src,
size_t src_len,
char *dest,
size_t dst_len) {
/*
* Last output character will be '\000'
* (If output undersized, add trailing ... to indicate this.
*/
size_t space = (dst_len - 4) / 3;
uint32_t qq;
for (qq = 0; qq < src_len && qq < space; qq++) {
char tmp = src[qq] >> 4;
if (tmp > 9)
tmp = tmp + 0x61 - 10;
else
tmp = tmp + 0x30;
dest[qq * 3] = tmp;
tmp = src[qq] & 0xf;
if (tmp > 9)
tmp = tmp + 0x61 - 10;
else
tmp = tmp + 0x30;
dest[qq * 3 + 1] = tmp;
dest[qq * 3 + 2] = 0x20;
}
if (qq != src_len) {
dest[qq * 3] = '.';
dest[qq * 3 + 1] = '.';
dest[qq * 3 + 2] = '.';
qq++;
}
dest[qq * 3] = 0;
}
static coap_bin_const_t *
oscore_build_key(oscore_ctx_t *osc_ctx,
coap_bin_const_t *id,
coap_str_const_t *type,
size_t out_len) {
uint8_t info_buffer[80];
size_t info_len;
uint8_t hkdf_tmp[CONTEXT_KEY_LEN > CONTEXT_INIT_VECT_LEN ?
CONTEXT_KEY_LEN :
CONTEXT_INIT_VECT_LEN];
info_len = compose_info(info_buffer,
sizeof(info_buffer),
osc_ctx->aead_alg,
id,
osc_ctx->id_context,
type,
out_len);
if (info_len == 0 || info_len > sizeof(info_buffer))
return NULL;
if (!oscore_hkdf(osc_ctx->hkdf_alg,
osc_ctx->master_salt,
osc_ctx->master_secret,
info_buffer,
info_len,
hkdf_tmp,
out_len))
return NULL;
return coap_new_bin_const(hkdf_tmp, out_len);
}
static void
oscore_log_context(oscore_ctx_t *osc_ctx, const char *heading) {
#if COAP_MAX_LOGGING_LEVEL < _COAP_LOG_OSCORE
(void)osc_ctx;
(void)heading;
#else /* COAP_MAX_LOGGING_LEVEL >= _COAP_LOG_OSCORE */
if (coap_get_log_level() >= COAP_LOG_OSCORE) {
char buffer[30];
oscore_recipient_ctx_t *next = osc_ctx->recipient_chain;
size_t count = 0;
coap_log_oscore("%s\n", heading);
oscore_log_char_value(COAP_LOG_OSCORE, "AEAD alg",
cose_get_alg_name(osc_ctx->aead_alg, buffer,
sizeof(buffer)));
oscore_log_char_value(COAP_LOG_OSCORE, "HKDF alg",
cose_get_hkdf_alg_name(osc_ctx->hkdf_alg, buffer,
sizeof(buffer)));
oscore_log_hex_value(COAP_LOG_OSCORE, "ID Context", osc_ctx->id_context);
oscore_log_hex_value(COAP_LOG_OSCORE,
"Master Secret",
osc_ctx->master_secret);
oscore_log_hex_value(COAP_LOG_OSCORE, "Master Salt", osc_ctx->master_salt);
oscore_log_hex_value(COAP_LOG_OSCORE, "Common IV", osc_ctx->common_iv);
oscore_log_hex_value(COAP_LOG_OSCORE,
"Sender ID",
osc_ctx->sender_context->sender_id);
oscore_log_hex_value(COAP_LOG_OSCORE,
"Sender Key",
osc_ctx->sender_context->sender_key);
while (next) {
snprintf(buffer, sizeof(buffer), "Recipient ID[%zu]", count);
oscore_log_hex_value(COAP_LOG_OSCORE,
buffer,
next->recipient_id);
snprintf(buffer, sizeof(buffer), "Recipient Key[%zu]", count);
oscore_log_hex_value(COAP_LOG_OSCORE,
buffer,
next->recipient_key);
count++;
next = next->next_recipient;
}
}
#endif /* COAP_MAX_LOGGING_LEVEL >= _COAP_LOG_OSCORE */
}
void
oscore_update_ctx(oscore_ctx_t *osc_ctx, coap_bin_const_t *id_context) {
coap_bin_const_t *temp;
/* Update with new ID Context */
coap_delete_bin_const(osc_ctx->id_context);
osc_ctx->id_context = id_context;
/* Update sender_key, recipient_key and common_iv */
temp = osc_ctx->sender_context->sender_key;
osc_ctx->sender_context->sender_key =
oscore_build_key(osc_ctx,
osc_ctx->sender_context->sender_id,
coap_make_str_const("Key"),
CONTEXT_KEY_LEN);
if (!osc_ctx->sender_context->sender_key)
osc_ctx->sender_context->sender_key = temp;
else
coap_delete_bin_const(temp);
temp = osc_ctx->recipient_chain->recipient_key;
osc_ctx->recipient_chain->recipient_key =
oscore_build_key(osc_ctx,
osc_ctx->recipient_chain->recipient_id,
coap_make_str_const("Key"),
CONTEXT_KEY_LEN);
if (!osc_ctx->recipient_chain->recipient_key)
osc_ctx->recipient_chain->recipient_key = temp;
else
coap_delete_bin_const(temp);
temp = osc_ctx->common_iv;
osc_ctx->common_iv = oscore_build_key(osc_ctx,
NULL,
coap_make_str_const("IV"),
CONTEXT_INIT_VECT_LEN);
if (!osc_ctx->common_iv)
osc_ctx->common_iv = temp;
else
coap_delete_bin_const(temp);
oscore_log_context(osc_ctx, "Updated Common 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_ctx_t *osc_ctx = NULL;
oscore_sender_ctx_t *sender_ctx = NULL;
coap_bin_const_t *copy_rid = NULL;
osc_ctx = coap_malloc_type(COAP_OSCORE_COM, sizeof(oscore_ctx_t));
if (osc_ctx == NULL)
goto error;
memset(osc_ctx, 0, sizeof(oscore_ctx_t));
sender_ctx = coap_malloc_type(COAP_OSCORE_SEN, sizeof(oscore_sender_ctx_t));
if (sender_ctx == NULL)
goto error;
memset(sender_ctx, 0, sizeof(oscore_sender_ctx_t));
osc_ctx->sender_context = sender_ctx;
if (o_osc_ctx->master_secret)
osc_ctx->master_secret =
coap_new_bin_const(o_osc_ctx->master_secret->s,
o_osc_ctx->master_secret->length);
if (o_osc_ctx->master_salt)
osc_ctx->master_salt = coap_new_bin_const(o_osc_ctx->master_salt->s,
o_osc_ctx->master_salt->length);
osc_ctx->aead_alg = o_osc_ctx->aead_alg;
osc_ctx->hkdf_alg = o_osc_ctx->hkdf_alg;
if (id_context)
osc_ctx->id_context = coap_new_bin_const(id_context->s, id_context->length);
osc_ctx->ssn_freq = o_osc_ctx->ssn_freq;
osc_ctx->replay_window_size = o_osc_ctx->replay_window_size;
osc_ctx->rfc8613_b_1_2 = o_osc_ctx->rfc8613_b_1_2;
osc_ctx->rfc8613_b_2 = o_osc_ctx->rfc8613_b_2;
osc_ctx->save_seq_num_func = o_osc_ctx->save_seq_num_func;
osc_ctx->save_seq_num_func_param = o_osc_ctx->save_seq_num_func_param;
if (o_osc_ctx->master_secret) {
/* sender_ key */
sender_ctx->sender_key = oscore_build_key(osc_ctx,
sender_id,
coap_make_str_const("Key"),
CONTEXT_KEY_LEN);
if (!sender_ctx->sender_key)
goto error;
/* common IV */
osc_ctx->common_iv = oscore_build_key(osc_ctx,
NULL,
coap_make_str_const("IV"),
CONTEXT_INIT_VECT_LEN);
if (!osc_ctx->common_iv)
goto error;
}
/*
* Need to set the last Sender Seq Num based on ssn_freq
* The value should only change if there is a change to ssn_freq
* and (potentially) be lower than seq, then save_seq_num_func() is
* immediately called on next SSN update.
*/
sender_ctx->next_seq = 0;
sender_ctx->seq = 0;
sender_ctx->sender_id = coap_new_bin_const(sender_id->s, sender_id->length);
copy_rid = coap_new_bin_const(recipient_id->s, recipient_id->length);
if (copy_rid == NULL)
goto error;
if (oscore_add_recipient(osc_ctx, copy_rid, 0) == NULL)
goto error;
oscore_log_context(osc_ctx, "New Common context");
oscore_enter_context(c_context, osc_ctx);
return osc_ctx;
error:
oscore_free_context(osc_ctx);
return NULL;
}
oscore_ctx_t *
oscore_derive_ctx(coap_context_t *c_context, coap_oscore_conf_t *oscore_conf) {
oscore_ctx_t *osc_ctx = NULL;
oscore_sender_ctx_t *sender_ctx = NULL;
size_t i;
osc_ctx = coap_malloc_type(COAP_OSCORE_COM, sizeof(oscore_ctx_t));
if (osc_ctx == NULL)
goto error;
memset(osc_ctx, 0, sizeof(oscore_ctx_t));
sender_ctx = coap_malloc_type(COAP_OSCORE_SEN, sizeof(oscore_sender_ctx_t));
if (sender_ctx == NULL)
goto error;
memset(sender_ctx, 0, sizeof(oscore_sender_ctx_t));
osc_ctx->sender_context = sender_ctx;
osc_ctx->master_secret = oscore_conf->master_secret;
osc_ctx->master_salt = oscore_conf->master_salt;
osc_ctx->aead_alg = oscore_conf->aead_alg;
osc_ctx->hkdf_alg = oscore_conf->hkdf_alg;
osc_ctx->id_context = oscore_conf->id_context;
osc_ctx->ssn_freq = oscore_conf->ssn_freq ? oscore_conf->ssn_freq : 1;
osc_ctx->replay_window_size = oscore_conf->replay_window ?
oscore_conf->replay_window :
COAP_OSCORE_DEFAULT_REPLAY_WINDOW;
osc_ctx->rfc8613_b_1_2 = oscore_conf->rfc8613_b_1_2;
osc_ctx->rfc8613_b_2 = oscore_conf->rfc8613_b_2;
osc_ctx->save_seq_num_func = oscore_conf->save_seq_num_func;
osc_ctx->save_seq_num_func_param = oscore_conf->save_seq_num_func_param;
if (oscore_conf->master_secret) {
/* sender_ key */
if (oscore_conf->break_sender_key)
/* Interop testing */
sender_ctx->sender_key = oscore_build_key(osc_ctx,
oscore_conf->sender_id,
coap_make_str_const("BAD"),
CONTEXT_KEY_LEN);
else
sender_ctx->sender_key = oscore_build_key(osc_ctx,
oscore_conf->sender_id,
coap_make_str_const("Key"),
CONTEXT_KEY_LEN);
if (!sender_ctx->sender_key)
goto error;
/* common IV */
osc_ctx->common_iv = oscore_build_key(osc_ctx,
NULL,
coap_make_str_const("IV"),
CONTEXT_INIT_VECT_LEN);
if (!osc_ctx->common_iv)
goto error;
}
/*
* Need to set the last Sender Seq Num based on ssn_freq
* The value should only change if there is a change to ssn_freq
* and (potentially) be lower than seq, then save_seq_num_func() is
* immediately called on next SSN update.
*/
sender_ctx->next_seq = oscore_conf->start_seq_num -
(oscore_conf->start_seq_num % (oscore_conf->ssn_freq > 0 ? oscore_conf->ssn_freq : 1));
sender_ctx->sender_id = oscore_conf->sender_id;
sender_ctx->seq = oscore_conf->start_seq_num;
for (i = 0; i < oscore_conf->recipient_id_count; i++) {
if (oscore_add_recipient(osc_ctx, oscore_conf->recipient_id[i],
oscore_conf->break_recipient_key) == NULL) {
coap_log_warn("OSCORE: Failed to add Client ID\n");
goto error;
}
}
oscore_log_context(osc_ctx, "Common context");
oscore_enter_context(c_context, osc_ctx);
return osc_ctx;
error:
coap_free_type(COAP_OSCORE_COM, osc_ctx);
coap_free_type(COAP_OSCORE_SEN, sender_ctx);
return NULL;
}
oscore_recipient_ctx_t *
oscore_add_recipient(oscore_ctx_t *osc_ctx, coap_bin_const_t *rid,
uint32_t break_key) {
oscore_recipient_ctx_t *rcp_ctx = osc_ctx->recipient_chain;
oscore_recipient_ctx_t *recipient_ctx = NULL;
if (rid->length > 7) {
coap_log_warn("oscore_add_recipient: Maximum size of recipient_id is 7 bytes\n");
return NULL;
}
/* Check this is not a duplicate recipient id */
while (rcp_ctx) {
if (rcp_ctx->recipient_id->length == rid->length &&
memcmp(rcp_ctx->recipient_id->s, rid->s, rid->length) == 0) {
coap_delete_bin_const(rid);
return NULL;
}
rcp_ctx = rcp_ctx->next_recipient;
}
recipient_ctx = (oscore_recipient_ctx_t *)coap_malloc_type(
COAP_OSCORE_REC,
sizeof(oscore_recipient_ctx_t));
if (recipient_ctx == NULL)
return NULL;
memset(recipient_ctx, 0, sizeof(oscore_recipient_ctx_t));
if (osc_ctx->master_secret) {
if (break_key)
/* Interop testing */
recipient_ctx->recipient_key = oscore_build_key(osc_ctx,
rid,
coap_make_str_const("BAD"),
CONTEXT_KEY_LEN);
else
recipient_ctx->recipient_key = oscore_build_key(osc_ctx,
rid,
coap_make_str_const("Key"),
CONTEXT_KEY_LEN);
if (!recipient_ctx->recipient_key) {
coap_free_type(COAP_OSCORE_REC, recipient_ctx);
return NULL;
}
}
recipient_ctx->recipient_id = rid;
recipient_ctx->initial_state = 1;
recipient_ctx->osc_ctx = osc_ctx;
rcp_ctx = osc_ctx->recipient_chain;
recipient_ctx->next_recipient = rcp_ctx;
osc_ctx->recipient_chain = recipient_ctx;
return recipient_ctx;
}
int
oscore_delete_recipient(oscore_ctx_t *osc_ctx, coap_bin_const_t *rid) {
oscore_recipient_ctx_t *prev = NULL;
oscore_recipient_ctx_t *next = osc_ctx->recipient_chain;
while (next) {
if (next->recipient_id->length == rid->length &&
memcmp(next->recipient_id->s, rid->s, rid->length) == 0) {
if (prev != NULL)
prev->next_recipient = next->next_recipient;
else
osc_ctx->recipient_chain = next->next_recipient;
oscore_free_recipient(next);
return 1;
}
prev = next;
next = next->next_recipient;
}
return 0;
}
void
oscore_free_association(oscore_association_t *association) {
if (association) {
coap_delete_pdu(association->sent_pdu);
coap_delete_bin_const(association->token);
coap_delete_bin_const(association->aad);
coap_delete_bin_const(association->nonce);
coap_delete_bin_const(association->partial_iv);
coap_free_type(COAP_STRING, association);
}
}
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) {
oscore_association_t *association;
association = coap_malloc_type(COAP_STRING, sizeof(oscore_association_t));
if (association == NULL)
return 0;
memset(association, 0, sizeof(oscore_association_t));
association->recipient_ctx = recipient_ctx;
association->is_observe = is_observe;
if (sent_pdu) {
size_t size;
const uint8_t *data;
association->sent_pdu = coap_pdu_duplicate_lkd(sent_pdu, session,
token->length, token->s, NULL);
if (association->sent_pdu == NULL)
goto error;
if (coap_get_data(sent_pdu, &size, &data)) {
coap_add_data(association->sent_pdu, size, data);
}
}
association->token = coap_new_bin_const(token->s, token->length);
if (association->token == NULL)
goto error;
if (aad) {
association->aad = coap_new_bin_const(aad->s, aad->length);
if (association->aad == NULL)
goto error;
}
if (nonce) {
association->nonce = coap_new_bin_const(nonce->s, nonce->length);
if (association->nonce == NULL)
goto error;
}
if (partial_iv) {
association->partial_iv =
coap_new_bin_const(partial_iv->s, partial_iv->length);
if (association->partial_iv == NULL)
goto error;
}
OSCORE_ASSOCIATIONS_ADD(session->associations, association);
return 1;
error:
oscore_free_association(association);
return 0;
}
oscore_association_t *
oscore_find_association(coap_session_t *session, coap_bin_const_t *token) {
oscore_association_t *association;
OSCORE_ASSOCIATIONS_FIND(session->associations, token, association);
return association;
}
int
oscore_delete_association(coap_session_t *session,
oscore_association_t *association) {
if (association) {
OSCORE_ASSOCIATIONS_DELETE(session->associations, association);
oscore_free_association(association);
return 1;
}
return 0;
}
void
oscore_delete_server_associations(coap_session_t *session) {
if (session) {
oscore_association_t *association;
oscore_association_t *tmp;
OSCORE_ASSOCIATIONS_ITER_SAFE(session->associations, association, tmp) {
OSCORE_ASSOCIATIONS_DELETE(session->associations, association);
oscore_free_association(association);
}
session->associations = NULL;
}
}
coap_libcoap_build.h
Library specific build wrapper for coap_internal.h.
COAP_OSCORE_COM
@ COAP_OSCORE_COM
Definition coap_mem.h:61
COAP_OSCORE_SEN
@ COAP_OSCORE_SEN
Definition coap_mem.h:62
COAP_OSCORE_REC
@ COAP_OSCORE_REC
Definition coap_mem.h:63
COAP_STRING
@ COAP_STRING
Definition coap_mem.h:39
coap_malloc_type
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.
coap_free_type
void coap_free_type(coap_memory_tag_t type, void *p)
Releases the memory that was allocated by coap_malloc_type().
COAP_OSCORE_DEFAULT_REPLAY_WINDOW
#define COAP_OSCORE_DEFAULT_REPLAY_WINDOW
Definition coap_crypto_internal.h:38
coap_get_log_level
coap_log_t coap_get_log_level(void)
Get the current logging level.
Definition coap_debug.c:95
coap_log_oscore
#define coap_log_oscore(...)
Definition coap_debug.h:126
coap_log_t
coap_log_t
Logging type.
Definition coap_debug.h:50
coap_log_warn
#define coap_log_warn(...)
Definition coap_debug.h:102
coap_log
#define coap_log(level,...)
Logging function.
Definition coap_debug.h:284
COAP_LOG_OSCORE
@ COAP_LOG_OSCORE
Definition coap_debug.h:59
oscore_cbor_put_text
size_t oscore_cbor_put_text(uint8_t **buffer, size_t *buf_size, const char *text, size_t text_len)
Definition oscore_cbor.c:77
oscore_cbor_put_nil
size_t oscore_cbor_put_nil(uint8_t **buffer, size_t *buf_size)
Definition oscore_cbor.c:59
oscore_cbor_put_unsigned
size_t oscore_cbor_put_unsigned(uint8_t **buffer, size_t *buf_size, uint64_t value)
Definition oscore_cbor.c:168
oscore_cbor_put_bytes
size_t oscore_cbor_put_bytes(uint8_t **buffer, size_t *buf_size, const uint8_t *bytes, size_t bytes_len)
Definition oscore_cbor.c:100
oscore_cbor_put_array
size_t oscore_cbor_put_array(uint8_t **buffer, size_t *buf_size, size_t elements)
Definition oscore_cbor.c:92
cose_get_hkdf_alg_name
const char * cose_get_hkdf_alg_name(cose_hkdf_alg_t id, char *buffer, size_t buflen)
Definition oscore_cose.c:151
cose_get_alg_name
const char * cose_get_alg_name(cose_alg_t id, char *buffer, size_t buflen)
Definition oscore_cose.c:120
OSCORE_ASSOCIATIONS_ITER_SAFE
#define OSCORE_ASSOCIATIONS_ITER_SAFE(e, el, rtmp)
Definition oscore_context.h:136
oscore_convert_to_hex
void oscore_convert_to_hex(const uint8_t *src, size_t src_len, char *dest, size_t dst_len)
Definition oscore_context.c:273
oscore_delete_association
int oscore_delete_association(coap_session_t *session, oscore_association_t *association)
Definition oscore_context.c:756
oscore_add_recipient
oscore_recipient_ctx_t * oscore_add_recipient(oscore_ctx_t *osc_ctx, coap_bin_const_t *rid, uint32_t break_key)
oscore_add_recipient - add in recipient information
Definition oscore_context.c:600
oscore_delete_recipient
int oscore_delete_recipient(oscore_ctx_t *osc_ctx, coap_bin_const_t *rid)
Definition oscore_context.c:654
OSCORE_ASSOCIATIONS_DELETE
#define OSCORE_ASSOCIATIONS_DELETE(r, obj)
Definition oscore_context.h:130
oscore_update_ctx
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
Definition oscore_context.c:387
CONTEXT_KEY_LEN
#define CONTEXT_KEY_LEN
Definition oscore_context.h:61
oscore_free_context
void oscore_free_context(oscore_ctx_t *osc_ctx)
Definition oscore_context.c:125
OSCORE_ASSOCIATIONS_ADD
#define OSCORE_ASSOCIATIONS_ADD(r, obj)
Definition oscore_context.h:127
oscore_derive_ctx
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
Definition oscore_context.c:513
oscore_free_association
void oscore_free_association(oscore_association_t *association)
Definition oscore_context.c:674
oscore_hkdf
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.
Definition oscore_crypto.c:158
oscore_new_association
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)
Definition oscore_context.c:686
oscore_delete_server_associations
void oscore_delete_server_associations(coap_session_t *session)
Definition oscore_context.c:767
oscore_log_char_value
void oscore_log_char_value(coap_log_t level, const char *name, const char *value)
Definition oscore_context.c:268
oscore_free_contexts
void oscore_free_contexts(coap_context_t *c_context)
Definition oscore_context.c:149
oscore_log_hex_value
void oscore_log_hex_value(coap_log_t level, const char *name, coap_bin_const_t *value)
Definition oscore_context.c:235
oscore_log_int_value
void oscore_log_int_value(coap_log_t level, const char *name, int value)
Definition oscore_context.c:263
oscore_duplicate_ctx
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
Definition oscore_context.c:429
oscore_remove_context
int oscore_remove_context(coap_context_t *c_context, oscore_ctx_t *osc_ctx)
Definition oscore_context.c:160
oscore_find_association
oscore_association_t * oscore_find_association(coap_session_t *session, coap_bin_const_t *token)
Definition oscore_context.c:748
oscore_find_context
oscore_ctx_t * oscore_find_context(const coap_context_t *c_context, 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)
Definition oscore_context.c:185
OSCORE_ASSOCIATIONS_FIND
#define OSCORE_ASSOCIATIONS_FIND(r, k, res)
Definition oscore_context.h:139
CONTEXT_INIT_VECT_LEN
#define CONTEXT_INIT_VECT_LEN
Definition oscore_context.h:64
oscore_bytes_equal
uint8_t oscore_bytes_equal(uint8_t *a_ptr, uint8_t a_len, uint8_t *b_ptr, uint8_t b_len)
Definition oscore_context.c:87
coap_pdu_duplicate_lkd
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)
Duplicate an existing PDU.
Definition coap_pdu.c:214
coap_delete_pdu
void coap_delete_pdu(coap_pdu_t *pdu)
Dispose of an CoAP PDU and frees associated storage.
Definition coap_pdu.c:179
coap_get_data
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.
Definition coap_pdu.c:863
coap_add_data
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.
Definition coap_pdu.c:832
coap_delete_bin_const
void coap_delete_bin_const(coap_bin_const_t *s)
Deletes the given const binary data and releases any memory allocated.
Definition coap_str.c:120
coap_make_str_const
coap_str_const_t * coap_make_str_const(const char *string)
Take the specified byte array (text) and create a coap_str_const_t *.
Definition coap_str.c:66
coap_new_bin_const
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...
Definition coap_str.c:110
OSCORE_LOG_SIZE
#define OSCORE_LOG_SIZE
Definition oscore_context.c:233
oscore_log_context
static void oscore_log_context(oscore_ctx_t *osc_ctx, const char *heading)
Definition oscore_context.c:341
oscore_free_recipient
static void oscore_free_recipient(oscore_recipient_ctx_t *recipient)
Definition oscore_context.c:118
oscore_build_key
static coap_bin_const_t * oscore_build_key(oscore_ctx_t *osc_ctx, coap_bin_const_t *id, coap_str_const_t *type, size_t out_len)
Definition oscore_context.c:309
oscore_enter_context
static void oscore_enter_context(coap_context_t *c_context, oscore_ctx_t *osc_ctx)
Definition oscore_context.c:103
compose_info
static size_t compose_info(uint8_t *buffer, size_t buf_size, uint8_t alg, coap_bin_const_t *id, coap_bin_const_t *id_context, coap_str_const_t *type, size_t out_len)
Definition oscore_context.c:54
coap_bin_const_t
CoAP binary data definition with const data.
Definition coap_str.h:64
coap_bin_const_t::length
size_t length
length of binary data
Definition coap_str.h:65
coap_bin_const_t::s
const uint8_t * s
read-only binary data
Definition coap_str.h:66
coap_context_t
The CoAP stack's global state is stored in a coap_context_t object.
Definition coap_net_internal.h:50
coap_oscore_conf_t
The structure used to hold the OSCORE configuration information.
Definition coap_oscore_internal.h:36
coap_oscore_conf_t::save_seq_num_func_param
void * save_seq_num_func_param
Passed to save_seq_num_func().
Definition coap_oscore_internal.h:59
coap_oscore_conf_t::rfc8613_b_2
uint32_t rfc8613_b_2
1 if rfc8613 B.2 protocol else 0
Definition coap_oscore_internal.h:50
coap_oscore_conf_t::hkdf_alg
cose_hkdf_alg_t hkdf_alg
Set to one of COSE_HKDF_ALG_*.
Definition coap_oscore_internal.h:48
coap_oscore_conf_t::break_sender_key
uint32_t break_sender_key
1 if sender key to be broken, else 0
Definition coap_oscore_internal.h:53
coap_oscore_conf_t::ssn_freq
uint32_t ssn_freq
Sender Seq Num update frequency.
Definition coap_oscore_internal.h:46
coap_oscore_conf_t::save_seq_num_func
coap_oscore_save_seq_num_t save_seq_num_func
Called every seq num change.
Definition coap_oscore_internal.h:57
coap_oscore_conf_t::rfc8613_b_1_2
uint32_t rfc8613_b_1_2
1 if rfc8613 B.1.2 enabled else 0
Definition coap_oscore_internal.h:49
coap_oscore_conf_t::start_seq_num
uint64_t start_seq_num
Used for ssn_freq updating.
Definition coap_oscore_internal.h:60
coap_oscore_conf_t::sender_id
coap_bin_const_t * sender_id
Sender ID (i.e.
Definition coap_oscore_internal.h:39
coap_oscore_conf_t::recipient_id
coap_bin_const_t ** recipient_id
Recipient ID (i.e.
Definition coap_oscore_internal.h:41
coap_oscore_conf_t::break_recipient_key
uint32_t break_recipient_key
1 if recipient key to be broken, else 0
Definition coap_oscore_internal.h:54
coap_oscore_conf_t::master_secret
coap_bin_const_t * master_secret
Common Master Secret.
Definition coap_oscore_internal.h:37
coap_oscore_conf_t::aead_alg
cose_alg_t aead_alg
Set to one of COSE_ALGORITHM_AES*.
Definition coap_oscore_internal.h:47
coap_oscore_conf_t::master_salt
coap_bin_const_t * master_salt
Common Master Salt.
Definition coap_oscore_internal.h:38
coap_oscore_conf_t::replay_window
uint32_t replay_window
Replay window size Use COAP_OSCORE_DEFAULT_REPLAY_WINDOW.
Definition coap_oscore_internal.h:44
coap_oscore_conf_t::id_context
coap_bin_const_t * id_context
Common ID context.
Definition coap_oscore_internal.h:40
coap_oscore_conf_t::recipient_id_count
uint32_t recipient_id_count
Number of recipient_id entries.
Definition coap_oscore_internal.h:43
coap_pdu_t
structure for CoAP PDUs
Definition coap_pdu_internal.h:135
coap_session_t
Abstraction of virtual session that can be attached to coap_context_t (client) or coap_endpoint_t (se...
Definition coap_session_internal.h:68
coap_str_const_t
CoAP string data definition with const data.
Definition coap_str.h:46
coap_str_const_t::s
const uint8_t * s
read-only string data
Definition coap_str.h:48
coap_str_const_t::length
size_t length
length of string
Definition coap_str.h:47
oscore_association_t
Definition oscore_context.h:142
oscore_association_t::partial_iv
coap_bin_const_t * partial_iv
Definition oscore_context.h:149
oscore_association_t::sent_pdu
coap_pdu_t * sent_pdu
Definition oscore_context.h:145
oscore_association_t::aad
coap_bin_const_t * aad
Definition oscore_context.h:147
oscore_association_t::nonce
coap_bin_const_t * nonce
Definition oscore_context.h:148
oscore_association_t::recipient_ctx
oscore_recipient_ctx_t * recipient_ctx
Definition oscore_context.h:144
oscore_association_t::is_observe
uint8_t is_observe
Definition oscore_context.h:151
oscore_association_t::token
coap_bin_const_t * token
Definition oscore_context.h:146
oscore_ctx_t
Definition oscore_context.h:84
oscore_ctx_t::master_secret
coap_bin_const_t * master_secret
Definition oscore_context.h:86
oscore_ctx_t::replay_window_size
uint32_t replay_window_size
Definition oscore_context.h:99
oscore_ctx_t::common_iv
coap_bin_const_t * common_iv
Derived from Master Secret, Master Salt, and ID Context.
Definition oscore_context.h:88
oscore_ctx_t::next
struct oscore_ctx_t * next
Definition oscore_context.h:85
oscore_ctx_t::rfc8613_b_1_2
uint8_t rfc8613_b_1_2
1 if rfc8613 B.1.2 enabled else 0
Definition oscore_context.h:96
oscore_ctx_t::save_seq_num_func_param
void * save_seq_num_func_param
Passed to save_seq_num_func().
Definition oscore_context.h:102
oscore_ctx_t::sender_context
oscore_sender_ctx_t * sender_context
Definition oscore_context.h:91
oscore_ctx_t::hkdf_alg
cose_hkdf_alg_t hkdf_alg
Definition oscore_context.h:94
oscore_ctx_t::aead_alg
cose_alg_t aead_alg
Definition oscore_context.h:93
oscore_ctx_t::rfc8613_b_2
uint8_t rfc8613_b_2
1 if rfc8613 B.2 protocol else 0
Definition oscore_context.h:97
oscore_ctx_t::master_salt
coap_bin_const_t * master_salt
Definition oscore_context.h:87
oscore_ctx_t::save_seq_num_func
coap_oscore_save_seq_num_t save_seq_num_func
Called every seq num change.
Definition oscore_context.h:100
oscore_ctx_t::recipient_chain
oscore_recipient_ctx_t * recipient_chain
Definition oscore_context.h:92
oscore_ctx_t::id_context
coap_bin_const_t * id_context
contains GID in case of group
Definition oscore_context.h:90
oscore_ctx_t::ssn_freq
uint32_t ssn_freq
Sender Seq Num update frequency.
Definition oscore_context.h:98
oscore_recipient_ctx_t
Definition oscore_context.h:112
oscore_recipient_ctx_t::next_recipient
oscore_recipient_ctx_t * next_recipient
Definition oscore_context.h:114
oscore_recipient_ctx_t::recipient_key
coap_bin_const_t * recipient_key
Definition oscore_context.h:121
oscore_recipient_ctx_t::recipient_id
coap_bin_const_t * recipient_id
Definition oscore_context.h:122
oscore_recipient_ctx_t::initial_state
uint8_t initial_state
Definition oscore_context.h:124
oscore_recipient_ctx_t::osc_ctx
oscore_ctx_t * osc_ctx
Definition oscore_context.h:115
oscore_sender_ctx_t
Definition oscore_context.h:105
oscore_sender_ctx_t::sender_id
coap_bin_const_t * sender_id
Definition oscore_context.h:109
oscore_sender_ctx_t::seq
uint64_t seq
Definition oscore_context.h:106
oscore_sender_ctx_t::sender_key
coap_bin_const_t * sender_key
Definition oscore_context.h:108
oscore_sender_ctx_t::next_seq
uint64_t next_seq
Used for ssn_freq updating.
Definition oscore_context.h:107