libcoap 4.3.5-develop-490e4e0
Loading...
Searching...
No Matches
oscore_context.c
Go to the documentation of this file.
1/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
3/*
4 * Copyright (c) 2018, SICS, RISE AB
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the Institute nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 */
32
47
48#if COAP_OSCORE_SUPPORT
49
50#include <stdio.h>
51
52static void oscore_enter_context(coap_context_t *c_context,
53 oscore_ctx_t *osc_ctx);
54
55static size_t
56compose_info(uint8_t *buffer,
57 size_t buf_size,
58 uint8_t alg,
60 coap_bin_const_t *id_context,
61 coap_str_const_t *type,
62 size_t out_len) {
63 size_t ret = 0;
64 size_t rem_size = buf_size;
65
66 ret += oscore_cbor_put_array(&buffer, &rem_size, 5);
67 ret += oscore_cbor_put_bytes(&buffer,
68 &rem_size,
69 id ? id->s : NULL,
70 id ? id->length : 0);
71 if (id_context != NULL && id_context->length > 0) {
72 ret += oscore_cbor_put_bytes(&buffer,
73 &rem_size,
74 id_context->s,
75 id_context->length);
76 } else {
77 ret += oscore_cbor_put_nil(&buffer, &rem_size);
78 }
79 ret += oscore_cbor_put_unsigned(&buffer, &rem_size, alg);
80 ret += oscore_cbor_put_text(&buffer,
81 &rem_size,
82 (const char *)type->s,
83 type->length);
84 ret += oscore_cbor_put_unsigned(&buffer, &rem_size, out_len);
85 return ret;
86}
87
88uint8_t
89oscore_bytes_equal(uint8_t *a_ptr,
90 uint8_t a_len,
91 uint8_t *b_ptr,
92 uint8_t b_len) {
93 if (a_len != b_len) {
94 return 0;
95 }
96
97 if (memcmp(a_ptr, b_ptr, a_len) == 0) {
98 return 1;
99 } else {
100 return 0;
101 }
102}
103
104static void
105oscore_enter_context(coap_context_t *c_context, oscore_ctx_t *osc_ctx) {
106 if (c_context->p_osc_ctx) {
107 oscore_ctx_t *prev = c_context->p_osc_ctx;
108 oscore_ctx_t *next = c_context->p_osc_ctx->next;
109
110 while (next) {
111 prev = next;
112 next = next->next;
113 }
114 prev->next = osc_ctx;
115 } else
116 c_context->p_osc_ctx = osc_ctx;
117}
118
119static void
120oscore_free_recipient(oscore_recipient_ctx_t *recipient) {
124}
125
126void
128 if (osc_ctx == NULL)
129 return;
130 if (osc_ctx->sender_context) {
134 }
135
136 while (osc_ctx->recipient_chain) {
138
139 oscore_free_recipient(osc_ctx->recipient_chain);
140 osc_ctx->recipient_chain = next;
141 }
142
148}
149
150void
152 while (c_context->p_osc_ctx) {
153 oscore_ctx_t *osc_ctx = c_context->p_osc_ctx;
154
155 c_context->p_osc_ctx = osc_ctx->next;
156
157 oscore_free_context(osc_ctx);
158 }
159}
160
161int
163 oscore_ctx_t *prev = NULL;
164 oscore_ctx_t *next = c_context->p_osc_ctx;
165 while (next) {
166 if (next == osc_ctx) {
167 if (prev != NULL)
168 prev->next = next->next;
169 else
170 c_context->p_osc_ctx = next->next;
172 return 1;
173 }
174 prev = next;
175 next = next->next;
176 }
177 return 0;
178}
179
180/*
181 * oscore_find_context
182 * Finds OSCORE context for rcpkey_id and optional ctxkey_id
183 * rcpkey_id can be 0 length.
184 * Updates recipient_ctx.
185 */
187oscore_find_context(const coap_context_t *c_context,
188 const coap_bin_const_t rcpkey_id,
189 const coap_bin_const_t *ctxkey_id,
190 uint8_t *oscore_r2,
191 oscore_recipient_ctx_t **recipient_ctx) {
192 oscore_ctx_t *pt = c_context->p_osc_ctx;
193
194 *recipient_ctx = NULL;
195 assert(rcpkey_id.length == 0 || rcpkey_id.s != NULL);
196 while (pt != NULL) {
197 int ok = 0;
199
200 while (rpt) {
201 ok = 0;
202 if (rcpkey_id.length == rpt->recipient_id->length) {
203 if (rcpkey_id.length != 0)
204 ok = memcmp(rpt->recipient_id->s, rcpkey_id.s, rcpkey_id.length) != 0;
205 if (oscore_r2) {
206 if (pt->id_context != NULL && pt->id_context->length > 8) {
207 ok = ok + (memcmp(pt->id_context->s, oscore_r2, 8) != 0);
208 } else {
209 ok += 1;
210 }
211 } else if (ctxkey_id) {
212 if (pt->id_context != NULL) {
213 if (ctxkey_id->length != pt->id_context->length)
214 ok += 1;
215 else
216 ok = ok + (memcmp(pt->id_context->s,
217 ctxkey_id->s,
218 ctxkey_id->length) != 0);
219 } else if (ctxkey_id->length > 0)
220 ok += 1;
221 }
222 if (ok == 0) {
223 /* optional id context and recipient id are the same */
224 *recipient_ctx = rpt;
225 return pt; /* OSCORE context found */
226 }
227 }
228 rpt = rpt->next_recipient;
229 } /* while rpt */
230 pt = pt->next;
231 } /* end while */
232 return NULL;
233}
234
235#define OSCORE_LOG_SIZE 16
236void
238 const char *name,
239 coap_bin_const_t *value) {
240 size_t i;
241
242 if (value == NULL) {
243 coap_log(level, " %-16s\n", name);
244 return;
245 }
246 if (value->length == 0) {
247 coap_log(level, " %-16s <>\n", name);
248 return;
249 }
250 if (coap_get_log_level() >= level) {
251 for (i = 0; i < value->length; i += OSCORE_LOG_SIZE) {
252 char number[3 * OSCORE_LOG_SIZE + 4];
253
254 oscore_convert_to_hex(&value->s[i],
255 value->length - i > OSCORE_LOG_SIZE ?
256 OSCORE_LOG_SIZE : value->length - i,
257 number,
258 sizeof(number));
259 coap_log(level, " %-16s %s\n", i == 0 ? name : "", number);
260 }
261 }
262}
263
264void
265oscore_log_int_value(coap_log_t level, const char *name, int value) {
266 coap_log(level, " %-16s %2d\n", name, value);
267}
268
269void
270oscore_log_char_value(coap_log_t level, const char *name, const char *value) {
271 coap_log(level, " %-16s %s\n", name, value);
272}
273
274void
275oscore_convert_to_hex(const uint8_t *src,
276 size_t src_len,
277 char *dest,
278 size_t dst_len) {
279 /*
280 * Last output character will be '\000'
281 * (If output undersized, add trailing ... to indicate this.
282 */
283 size_t space = (dst_len - 4) / 3;
284 uint32_t qq;
285
286 for (qq = 0; qq < src_len && qq < space; qq++) {
287 char tmp = src[qq] >> 4;
288 if (tmp > 9)
289 tmp = tmp + 0x61 - 10;
290 else
291 tmp = tmp + 0x30;
292 dest[qq * 3] = tmp;
293 tmp = src[qq] & 0xf;
294 if (tmp > 9)
295 tmp = tmp + 0x61 - 10;
296 else
297 tmp = tmp + 0x30;
298 dest[qq * 3 + 1] = tmp;
299 dest[qq * 3 + 2] = 0x20;
300 }
301 if (qq != src_len) {
302 dest[qq * 3] = '.';
303 dest[qq * 3 + 1] = '.';
304 dest[qq * 3 + 2] = '.';
305 qq++;
306 }
307 dest[qq * 3] = 0;
308}
309
310static coap_bin_const_t *
311oscore_build_key(oscore_ctx_t *osc_ctx,
313 coap_str_const_t *type,
314 size_t out_len) {
315 uint8_t info_buffer[80];
316 size_t info_len;
317 uint8_t hkdf_tmp[CONTEXT_KEY_LEN > CONTEXT_INIT_VECT_LEN ?
320
321 info_len = compose_info(info_buffer,
322 sizeof(info_buffer),
323 osc_ctx->aead_alg,
324 id,
325 osc_ctx->id_context,
326 type,
327 out_len);
328 if (info_len == 0 || info_len > sizeof(info_buffer))
329 return NULL;
330
331 if (!oscore_hkdf(osc_ctx->hkdf_alg,
332 osc_ctx->master_salt,
333 osc_ctx->master_secret,
334 info_buffer,
335 info_len,
336 hkdf_tmp,
337 out_len))
338 return NULL;
339 return coap_new_bin_const(hkdf_tmp, out_len);
340}
341
342static void
343oscore_log_context(oscore_ctx_t *osc_ctx, const char *heading) {
344#if COAP_MAX_LOGGING_LEVEL < _COAP_LOG_OSCORE
345 (void)osc_ctx;
346 (void)heading;
347#else /* COAP_MAX_LOGGING_LEVEL >= _COAP_LOG_OSCORE */
349 char buffer[30];
351 size_t count = 0;
352
353 coap_log_oscore("%s\n", heading);
355 cose_get_alg_name(osc_ctx->aead_alg, buffer,
356 sizeof(buffer)));
358 cose_get_hkdf_alg_name(osc_ctx->hkdf_alg, buffer,
359 sizeof(buffer)));
360 oscore_log_hex_value(COAP_LOG_OSCORE, "ID Context", osc_ctx->id_context);
362 "Master Secret",
363 osc_ctx->master_secret);
364 oscore_log_hex_value(COAP_LOG_OSCORE, "Master Salt", osc_ctx->master_salt);
365 oscore_log_hex_value(COAP_LOG_OSCORE, "Common IV", osc_ctx->common_iv);
367 "Sender ID",
368 osc_ctx->sender_context->sender_id);
370 "Sender Key",
371 osc_ctx->sender_context->sender_key);
372 while (next) {
373 snprintf(buffer, sizeof(buffer), "Recipient ID[%zu]", count);
375 buffer,
376 next->recipient_id);
377 snprintf(buffer, sizeof(buffer), "Recipient Key[%zu]", count);
379 buffer,
380 next->recipient_key);
381 count++;
382 next = next->next_recipient;
383 }
384 }
385#endif /* COAP_MAX_LOGGING_LEVEL >= _COAP_LOG_OSCORE */
386}
387
388void
389oscore_update_ctx(oscore_ctx_t *osc_ctx, coap_bin_const_t *id_context) {
390 coap_bin_const_t *temp;
391
392 /* Update with new ID Context */
394 osc_ctx->id_context = id_context;
395
396 /* Update sender_key, recipient_key and common_iv */
397 temp = osc_ctx->sender_context->sender_key;
398 osc_ctx->sender_context->sender_key =
399 oscore_build_key(osc_ctx,
400 osc_ctx->sender_context->sender_id,
401 coap_make_str_const("Key"),
403 if (!osc_ctx->sender_context->sender_key)
404 osc_ctx->sender_context->sender_key = temp;
405 else
407 temp = osc_ctx->recipient_chain->recipient_key;
409 oscore_build_key(osc_ctx,
411 coap_make_str_const("Key"),
413 if (!osc_ctx->recipient_chain->recipient_key)
414 osc_ctx->recipient_chain->recipient_key = temp;
415 else
417 temp = osc_ctx->common_iv;
418 osc_ctx->common_iv = oscore_build_key(osc_ctx,
419 NULL,
422 if (!osc_ctx->common_iv)
423 osc_ctx->common_iv = temp;
424 else
426
427 oscore_log_context(osc_ctx, "Updated Common context");
428}
429
432 oscore_ctx_t *o_osc_ctx,
433 coap_bin_const_t *sender_id,
434 coap_bin_const_t *recipient_id,
435 coap_bin_const_t *id_context) {
436 oscore_ctx_t *osc_ctx = NULL;
437 oscore_sender_ctx_t *sender_ctx = NULL;
438 coap_bin_const_t *copy_rid = NULL;
439
441 if (osc_ctx == NULL)
442 goto error;
443 memset(osc_ctx, 0, sizeof(oscore_ctx_t));
444
446 if (sender_ctx == NULL)
447 goto error;
448 memset(sender_ctx, 0, sizeof(oscore_sender_ctx_t));
449
450 osc_ctx->sender_context = sender_ctx;
451 if (o_osc_ctx->master_secret)
452 osc_ctx->master_secret =
454 o_osc_ctx->master_secret->length);
455 if (o_osc_ctx->master_salt)
456 osc_ctx->master_salt = coap_new_bin_const(o_osc_ctx->master_salt->s,
457 o_osc_ctx->master_salt->length);
458 osc_ctx->aead_alg = o_osc_ctx->aead_alg;
459 osc_ctx->hkdf_alg = o_osc_ctx->hkdf_alg;
460 if (id_context)
461 osc_ctx->id_context = coap_new_bin_const(id_context->s, id_context->length);
462 osc_ctx->ssn_freq = o_osc_ctx->ssn_freq;
463 osc_ctx->replay_window_size = o_osc_ctx->replay_window_size;
464 osc_ctx->rfc8613_b_1_2 = o_osc_ctx->rfc8613_b_1_2;
465 osc_ctx->rfc8613_b_2 = o_osc_ctx->rfc8613_b_2;
466 osc_ctx->save_seq_num_func = o_osc_ctx->save_seq_num_func;
468
469 if (o_osc_ctx->master_secret) {
470 /* sender_ key */
471 sender_ctx->sender_key = oscore_build_key(osc_ctx,
472 sender_id,
473 coap_make_str_const("Key"),
475 if (!sender_ctx->sender_key)
476 goto error;
477
478 /* common IV */
479 osc_ctx->common_iv = oscore_build_key(osc_ctx,
480 NULL,
483 if (!osc_ctx->common_iv)
484 goto error;
485 }
486
487 /*
488 * Need to set the last Sender Seq Num based on ssn_freq
489 * The value should only change if there is a change to ssn_freq
490 * and (potentially) be lower than seq, then save_seq_num_func() is
491 * immediately called on next SSN update.
492 */
493 sender_ctx->next_seq = 0;
494 sender_ctx->seq = 0;
495
496 sender_ctx->sender_id = coap_new_bin_const(sender_id->s, sender_id->length);
497
498 copy_rid = coap_new_bin_const(recipient_id->s, recipient_id->length);
499 if (copy_rid == NULL)
500 goto error;
501 if (oscore_add_recipient(osc_ctx, copy_rid, 0) == NULL)
502 goto error;
503
504 oscore_log_context(osc_ctx, "New Common context");
505 oscore_enter_context(c_context, osc_ctx);
506
507 return osc_ctx;
508
509error:
510 oscore_free_context(osc_ctx);
511 return NULL;
512}
513
515oscore_derive_ctx(coap_context_t *c_context, coap_oscore_conf_t *oscore_conf) {
516 oscore_ctx_t *osc_ctx = NULL;
517 oscore_sender_ctx_t *sender_ctx = NULL;
518 size_t i;
519
521 if (osc_ctx == NULL)
522 goto error;
523 memset(osc_ctx, 0, sizeof(oscore_ctx_t));
524
526 if (sender_ctx == NULL)
527 goto error;
528 memset(sender_ctx, 0, sizeof(oscore_sender_ctx_t));
529
530 osc_ctx->sender_context = sender_ctx;
531 osc_ctx->master_secret = oscore_conf->master_secret;
532 osc_ctx->master_salt = oscore_conf->master_salt;
533 osc_ctx->aead_alg = oscore_conf->aead_alg;
534 osc_ctx->hkdf_alg = oscore_conf->hkdf_alg;
535 osc_ctx->id_context = oscore_conf->id_context;
536 osc_ctx->ssn_freq = oscore_conf->ssn_freq ? oscore_conf->ssn_freq : 1;
537 osc_ctx->replay_window_size = oscore_conf->replay_window ?
538 oscore_conf->replay_window :
540 osc_ctx->rfc8613_b_1_2 = oscore_conf->rfc8613_b_1_2;
541 osc_ctx->rfc8613_b_2 = oscore_conf->rfc8613_b_2;
542 osc_ctx->save_seq_num_func = oscore_conf->save_seq_num_func;
543 osc_ctx->save_seq_num_func_param = oscore_conf->save_seq_num_func_param;
544
545 if (oscore_conf->master_secret) {
546 /* sender_ key */
547 if (oscore_conf->break_sender_key)
548 /* Interop testing */
549 sender_ctx->sender_key = oscore_build_key(osc_ctx,
550 oscore_conf->sender_id,
551 coap_make_str_const("BAD"),
553 else
554 sender_ctx->sender_key = oscore_build_key(osc_ctx,
555 oscore_conf->sender_id,
556 coap_make_str_const("Key"),
558 if (!sender_ctx->sender_key)
559 goto error;
560
561 /* common IV */
562 osc_ctx->common_iv = oscore_build_key(osc_ctx,
563 NULL,
566 if (!osc_ctx->common_iv)
567 goto error;
568 }
569
570 /*
571 * Need to set the last Sender Seq Num based on ssn_freq
572 * The value should only change if there is a change to ssn_freq
573 * and (potentially) be lower than seq, then save_seq_num_func() is
574 * immediately called on next SSN update.
575 */
576 sender_ctx->next_seq = oscore_conf->start_seq_num -
577 (oscore_conf->start_seq_num % (oscore_conf->ssn_freq > 0 ? oscore_conf->ssn_freq : 1));
578
579 sender_ctx->sender_id = oscore_conf->sender_id;
580 sender_ctx->seq = oscore_conf->start_seq_num;
581
582 for (i = 0; i < oscore_conf->recipient_id_count; i++) {
583 if (oscore_add_recipient(osc_ctx, oscore_conf->recipient_id[i],
584 oscore_conf->break_recipient_key) == NULL) {
585 coap_log_warn("OSCORE: Failed to add Client ID\n");
586 goto error;
587 }
588 }
589 oscore_log_context(osc_ctx, "Common context");
590
591 oscore_enter_context(c_context, osc_ctx);
592
593 return osc_ctx;
594
595error:
597 coap_free_type(COAP_OSCORE_SEN, sender_ctx);
598 return NULL;
599}
600
603 uint32_t break_key) {
604 oscore_recipient_ctx_t *rcp_ctx = osc_ctx->recipient_chain;
605 oscore_recipient_ctx_t *recipient_ctx = NULL;
606
607 if (rid->length > 7) {
608 coap_log_warn("oscore_add_recipient: Maximum size of recipient_id is 7 bytes\n");
609 return NULL;
610 }
611 /* Check this is not a duplicate recipient id */
612 while (rcp_ctx) {
613 if (rcp_ctx->recipient_id->length == rid->length &&
614 memcmp(rcp_ctx->recipient_id->s, rid->s, rid->length) == 0) {
616 return NULL;
617 }
618 rcp_ctx = rcp_ctx->next_recipient;
619 }
620 recipient_ctx = (oscore_recipient_ctx_t *)coap_malloc_type(
622 sizeof(oscore_recipient_ctx_t));
623 if (recipient_ctx == NULL)
624 return NULL;
625 memset(recipient_ctx, 0, sizeof(oscore_recipient_ctx_t));
626
627 if (osc_ctx->master_secret) {
628 if (break_key)
629 /* Interop testing */
630 recipient_ctx->recipient_key = oscore_build_key(osc_ctx,
631 rid,
632 coap_make_str_const("BAD"),
634 else
635 recipient_ctx->recipient_key = oscore_build_key(osc_ctx,
636 rid,
637 coap_make_str_const("Key"),
639 if (!recipient_ctx->recipient_key) {
640 coap_free_type(COAP_OSCORE_REC, recipient_ctx);
641 return NULL;
642 }
643 }
644
645 recipient_ctx->recipient_id = rid;
646 recipient_ctx->initial_state = 1;
647 recipient_ctx->osc_ctx = osc_ctx;
648
649 rcp_ctx = osc_ctx->recipient_chain;
650 recipient_ctx->next_recipient = rcp_ctx;
651 osc_ctx->recipient_chain = recipient_ctx;
652 return recipient_ctx;
653}
654
655int
657 oscore_recipient_ctx_t *prev = NULL;
659 while (next) {
660 if (next->recipient_id->length == rid->length &&
661 memcmp(next->recipient_id->s, rid->s, rid->length) == 0) {
662 if (prev != NULL)
663 prev->next_recipient = next->next_recipient;
664 else
665 osc_ctx->recipient_chain = next->next_recipient;
666 oscore_free_recipient(next);
667 return 1;
668 }
669 prev = next;
670 next = next->next_recipient;
671 }
672 return 0;
673}
674
675void
677 if (association) {
678 coap_delete_pdu_lkd(association->sent_pdu);
679 coap_delete_bin_const(association->token);
680 coap_delete_bin_const(association->aad);
681 coap_delete_bin_const(association->nonce);
682 coap_delete_bin_const(association->partial_iv);
684 coap_free_type(COAP_STRING, association);
685 }
686}
687
688int
690 coap_pdu_t *sent_pdu,
691 coap_bin_const_t *token,
692 oscore_recipient_ctx_t *recipient_ctx,
693 coap_bin_const_t *aad,
694 coap_bin_const_t *nonce,
695 coap_bin_const_t *partial_iv,
696 int is_observe) {
697 oscore_association_t *association;
698
699 association = coap_malloc_type(COAP_STRING, sizeof(oscore_association_t));
700 if (association == NULL)
701 return 0;
702
703 memset(association, 0, sizeof(oscore_association_t));
704 association->recipient_ctx = recipient_ctx;
705 association->is_observe = is_observe;
706 association->just_set_up = 1;
707
708 if (sent_pdu) {
709 size_t size;
710 const uint8_t *data;
711
712 association->sent_pdu = coap_pdu_duplicate_lkd(sent_pdu, session,
713 token->length, token->s, NULL);
714 if (association->sent_pdu == NULL)
715 goto error;
716 if (coap_get_data(sent_pdu, &size, &data)) {
717 coap_add_data(association->sent_pdu, size, data);
718 }
719 }
720 association->token = coap_new_bin_const(token->s, token->length);
721 if (association->token == NULL)
722 goto error;
723
724 if (aad) {
725 association->aad = coap_new_bin_const(aad->s, aad->length);
726 if (association->aad == NULL)
727 goto error;
728 }
729
730 if (nonce) {
731 association->nonce = coap_new_bin_const(nonce->s, nonce->length);
732 if (association->nonce == NULL)
733 goto error;
734 }
735
736 if (partial_iv) {
737 association->partial_iv =
738 coap_new_bin_const(partial_iv->s, partial_iv->length);
739 if (association->partial_iv == NULL)
740 goto error;
741 }
742
743 OSCORE_ASSOCIATIONS_ADD(session->associations, association);
744 return 1;
745
746error:
747 oscore_free_association(association);
748 return 0;
749}
750
753 oscore_association_t *association;
754
755 OSCORE_ASSOCIATIONS_FIND(session->associations, token, association);
756 return association;
757}
758
759int
761 oscore_association_t *association) {
762 if (association) {
763 OSCORE_ASSOCIATIONS_DELETE(session->associations, association);
764 oscore_free_association(association);
765 return 1;
766 }
767 return 0;
768}
769
770void
772 if (session) {
773 oscore_association_t *association;
775
776 OSCORE_ASSOCIATIONS_ITER_SAFE(session->associations, association, tmp) {
777 OSCORE_ASSOCIATIONS_DELETE(session->associations, association);
778 oscore_free_association(association);
779 }
780 session->associations = NULL;
781 }
782}
783
784#else /* ! COAP_OSCORE_SUPPORT */
785
786#ifdef __clang__
787/* Make compilers happy that do not like empty modules. As this function is
788 * never used, we ignore -Wunused-function at the end of compiling this file
789 */
790#pragma GCC diagnostic ignored "-Wunused-function"
791#endif
792static inline void
793dummy(void) {
794}
795
796#endif /* ! COAP_OSCORE_SUPPORT */
Library specific build wrapper for coap_internal.h.
@ COAP_OSCORE_COM
Definition coap_mem.h:56
@ COAP_OSCORE_SEN
Definition coap_mem.h:57
@ COAP_OSCORE_REC
Definition coap_mem.h:58
@ COAP_STRING
Definition coap_mem.h:34
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
coap_log_t coap_get_log_level(void)
Get the current logging level.
Definition coap_debug.c:103
#define coap_log_oscore(...)
Definition coap_debug.h:132
coap_log_t
Logging type.
Definition coap_debug.h:56
#define coap_log_warn(...)
Definition coap_debug.h:108
#define coap_log(level,...)
Logging function.
Definition coap_debug.h:290
@ COAP_LOG_OSCORE
Definition coap_debug.h:65
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)
const char * cose_get_alg_name(cose_alg_t id, char *buffer, size_t buflen)
#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)
int oscore_delete_association(coap_session_t *session, oscore_association_t *association)
oscore_recipient_ctx_t * oscore_add_recipient(oscore_ctx_t *ctx, coap_bin_const_t *rid, uint32_t break_key)
oscore_add_recipient - add in recipient information
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
#define CONTEXT_KEY_LEN
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)
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)
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)
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)
#define OSCORE_ASSOCIATIONS_FIND(r, k, res)
#define CONTEXT_INIT_VECT_LEN
uint8_t oscore_bytes_equal(uint8_t *a_ptr, uint8_t a_len, uint8_t *b_ptr, uint8_t b_len)
void coap_delete_pdu_lkd(coap_pdu_t *pdu)
Dispose of an CoAP PDU and free off associated storage.
Definition coap_pdu.c:194
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:234
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:879
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:848
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_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_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
static void dummy(void)
CoAP binary data definition with const data.
Definition coap_str.h:67
size_t length
length of binary data
Definition coap_str.h:68
const uint8_t * s
read-only binary data
Definition coap_str.h:69
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
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.
coap_bin_const_t * sender_id
Sender ID (i.e.
coap_bin_const_t ** recipient_id
Recipient ID (i.e.
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.
uint32_t recipient_id_count
Number of recipient_id entries.
structure for CoAP PDUs
Abstraction of virtual session that can be attached to coap_context_t (client) or coap_endpoint_t (se...
CoAP string data definition with const data.
Definition coap_str.h:49
const uint8_t * s
read-only string data
Definition coap_str.h:51
size_t length
length of string
Definition coap_str.h:50
coap_bin_const_t * obs_partial_iv
coap_bin_const_t * partial_iv
coap_bin_const_t * aad
coap_bin_const_t * nonce
oscore_recipient_ctx_t * recipient_ctx
coap_bin_const_t * token
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
cose_alg_t aead_alg
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
coap_bin_const_t * recipient_key
coap_bin_const_t * recipient_id
coap_bin_const_t * sender_id
coap_bin_const_t * sender_key
uint64_t next_seq
Used for ssn_freq updating.