xref: /third_party/libcoap/tests/test_oscore.c (revision c87c5fba)
1/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
3/* libcoap unit tests
4 *
5 * Copyright (C) 2021-2023 Jon Shallow <supjps-libcoap@jpshallow.com>
6 *
7 * SPDX-License-Identifier: BSD-2-Clause
8 *
9 * This file is part of the CoAP library libcoap. Please see
10 * README for terms of use.
11 */
12
13#include "test_common.h"
14
15#if COAP_OSCORE_SUPPORT && COAP_SERVER_SUPPORT
16#include "test_oscore.h"
17#include "oscore/oscore.h"
18#include "oscore/oscore_context.h"
19
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23
24#define CHECK_SAME(a,b) \
25  (sizeof((a)) == (b)->length && memcmp((a), (b)->s, (b)->length) == 0)
26
27#define FailIf_CU_ASSERT_PTR_NOT_NULL(value) CU_ASSERT_PTR_NOT_NULL(value); if ((void*)value == NULL) goto fail
28
29/************************************************************************
30 ** RFC8613 tests
31 ************************************************************************/
32
33/* C.1.1.  Test Vector 1: Key Derivation with Master Salt, Client */
34static void
35t_oscore_c_1_1(void) {
36  static const char conf_data[] =
37      "master_secret,hex,\"0102030405060708090a0b0c0d0e0f10\"\n"
38      "master_salt,hex,\"9e7ca92223786340\"\n"
39      "sender_id,hex,\"\"\n"
40      "recipient_id,hex,\"01\"\n";
41  static const uint8_t sender_key[] = {
42    0xf0, 0x91, 0x0e, 0xd7, 0x29, 0x5e, 0x6a, 0xd4,
43    0xb5, 0x4f, 0xc7, 0x93, 0x15, 0x43, 0x02, 0xff
44  };
45  static const uint8_t recipient_key[] = {
46    0xff, 0xb1, 0x4e, 0x09, 0x3c, 0x94, 0xc9, 0xca,
47    0xc9, 0x47, 0x16, 0x48, 0xb4, 0xf9, 0x87, 0x10
48  };
49  static const uint8_t common_iv[] = {
50    0x46, 0x22, 0xd4, 0xdd, 0x6d, 0x94, 0x41, 0x68,
51    0xee, 0xfb, 0x54, 0x98, 0x7c
52  };
53  static const uint8_t sender_nonce[] = {
54    0x46, 0x22, 0xd4, 0xdd, 0x6d, 0x94, 0x41, 0x68,
55    0xee, 0xfb, 0x54, 0x98, 0x7c
56  };
57  static const uint8_t recipient_nonce[] = {
58    0x47, 0x22, 0xd4, 0xdd, 0x6d, 0x94, 0x41, 0x69,
59    0xee, 0xfb, 0x54, 0x98, 0x7c
60  };
61  const coap_str_const_t conf = { sizeof(conf_data)-1,
62                                  (const uint8_t *)conf_data
63                                };
64  coap_context_t ctx[1];
65  coap_oscore_conf_t *oscore_conf;
66  cose_encrypt0_t cose[1];
67  uint8_t nonce_buffer[13];
68  coap_bin_const_t nonce = { 13, nonce_buffer };
69
70  memset(&ctx, 0, sizeof(ctx));
71  oscore_conf = coap_new_oscore_conf(conf, NULL, NULL, 0);
72  FailIf_CU_ASSERT_PTR_NOT_NULL(oscore_conf);
73  coap_context_oscore_server(ctx, oscore_conf);
74  FailIf_CU_ASSERT_PTR_NOT_NULL(ctx->p_osc_ctx);
75
76  CU_ASSERT(CHECK_SAME(sender_key, ctx->p_osc_ctx->sender_context->sender_key));
77  CU_ASSERT(CHECK_SAME(recipient_key,
78                       ctx->p_osc_ctx->recipient_chain->recipient_key));
79  CU_ASSERT(CHECK_SAME(common_iv, ctx->p_osc_ctx->common_iv));
80
81  cose_encrypt0_init(cose);
82  cose_encrypt0_set_key_id(cose, ctx->p_osc_ctx->recipient_chain->recipient_id);
83  cose_encrypt0_set_partial_iv(cose, NULL);
84  oscore_generate_nonce(cose, ctx->p_osc_ctx, nonce_buffer, 13);
85  CU_ASSERT(CHECK_SAME(recipient_nonce, &nonce));
86
87  cose_encrypt0_init(cose);
88  cose_encrypt0_set_key_id(cose, ctx->p_osc_ctx->sender_context->sender_id);
89  cose_encrypt0_set_partial_iv(cose, NULL);
90  oscore_generate_nonce(cose, ctx->p_osc_ctx, nonce_buffer, 13);
91  CU_ASSERT(CHECK_SAME(sender_nonce, &nonce));
92
93fail:
94  oscore_free_contexts(ctx);
95}
96
97/* C.1.2.  Test Vector 1: Key Derivation with Master Salt, Server */
98static void
99t_oscore_c_1_2(void) {
100  static const char conf_data[] =
101      "master_secret,hex,\"0102030405060708090a0b0c0d0e0f10\"\n"
102      "master_salt,hex,\"9e7ca92223786340\"\n"
103      "sender_id,hex,\"01\"\n"
104      "recipient_id,hex,\"\"\n";
105  static const uint8_t sender_key[] = {
106    0xff, 0xb1, 0x4e, 0x09, 0x3c, 0x94, 0xc9, 0xca,
107    0xc9, 0x47, 0x16, 0x48, 0xb4, 0xf9, 0x87, 0x10
108  };
109  static const uint8_t recipient_key[] = {
110    0xf0, 0x91, 0x0e, 0xd7, 0x29, 0x5e, 0x6a, 0xd4,
111    0xb5, 0x4f, 0xc7, 0x93, 0x15, 0x43, 0x02, 0xff
112  };
113  static const uint8_t common_iv[] = {
114    0x46, 0x22, 0xd4, 0xdd, 0x6d, 0x94, 0x41, 0x68,
115    0xee, 0xfb, 0x54, 0x98, 0x7c
116  };
117  static const uint8_t sender_nonce[] = {
118    0x47, 0x22, 0xd4, 0xdd, 0x6d, 0x94, 0x41, 0x69,
119    0xee, 0xfb, 0x54, 0x98, 0x7c
120  };
121  static const uint8_t recipient_nonce[] = {
122    0x46, 0x22, 0xd4, 0xdd, 0x6d, 0x94, 0x41, 0x68,
123    0xee, 0xfb, 0x54, 0x98, 0x7c
124  };
125  const coap_str_const_t conf = { sizeof(conf_data)-1,
126                                  (const uint8_t *)conf_data
127                                };
128  coap_context_t ctx[1];
129  coap_oscore_conf_t *oscore_conf;
130  cose_encrypt0_t cose[1];
131  uint8_t nonce_buffer[13];
132  coap_bin_const_t nonce = { 13, nonce_buffer };
133
134  memset(&ctx, 0, sizeof(ctx));
135  oscore_conf = coap_new_oscore_conf(conf, NULL, NULL, 0);
136  FailIf_CU_ASSERT_PTR_NOT_NULL(oscore_conf);
137  coap_context_oscore_server(ctx, oscore_conf);
138  FailIf_CU_ASSERT_PTR_NOT_NULL(ctx->p_osc_ctx);
139
140  CU_ASSERT(CHECK_SAME(sender_key, ctx->p_osc_ctx->sender_context->sender_key));
141  CU_ASSERT(CHECK_SAME(recipient_key,
142                       ctx->p_osc_ctx->recipient_chain->recipient_key));
143  CU_ASSERT(CHECK_SAME(common_iv, ctx->p_osc_ctx->common_iv));
144
145  cose_encrypt0_init(cose);
146  cose_encrypt0_set_key_id(cose, ctx->p_osc_ctx->recipient_chain->recipient_id);
147  cose_encrypt0_set_partial_iv(cose, NULL);
148  oscore_generate_nonce(cose, ctx->p_osc_ctx, nonce_buffer, 13);
149  CU_ASSERT(CHECK_SAME(recipient_nonce, &nonce));
150
151  cose_encrypt0_init(cose);
152  cose_encrypt0_set_key_id(cose, ctx->p_osc_ctx->sender_context->sender_id);
153  cose_encrypt0_set_partial_iv(cose, NULL);
154  oscore_generate_nonce(cose, ctx->p_osc_ctx, nonce_buffer, 13);
155  CU_ASSERT(CHECK_SAME(sender_nonce, &nonce));
156
157fail:
158  oscore_free_contexts(ctx);
159}
160
161/* C.2.1.  Test Vector 2: Key Derivation without Master Salt, Client */
162static void
163t_oscore_c_2_1(void) {
164  static const char conf_data[] =
165      "master_secret,hex,\"0102030405060708090a0b0c0d0e0f10\"\n"
166      "sender_id,hex,\"00\"\n"
167      "recipient_id,hex,\"01\"\n";
168  static const uint8_t sender_key[] = {
169    0x32, 0x1b, 0x26, 0x94, 0x32, 0x53, 0xc7, 0xff,
170    0xb6, 0x00, 0x3b, 0x0b, 0x64, 0xd7, 0x40, 0x41
171  };
172  static const uint8_t recipient_key[] = {
173    0xe5, 0x7b, 0x56, 0x35, 0x81, 0x51, 0x77, 0xcd,
174    0x67, 0x9a, 0xb4, 0xbc, 0xec, 0x9d, 0x7d, 0xda
175  };
176  static const uint8_t common_iv[] = {
177    0xbe, 0x35, 0xae, 0x29, 0x7d, 0x2d, 0xac, 0xe9,
178    0x10, 0xc5, 0x2e, 0x99, 0xf9
179  };
180  static const uint8_t sender_nonce[] = {
181    0xbf, 0x35, 0xae, 0x29, 0x7d, 0x2d, 0xac, 0xe9,
182    0x10, 0xc5, 0x2e, 0x99, 0xf9
183  };
184  static const uint8_t recipient_nonce[] = {
185    0xbf, 0x35, 0xae, 0x29, 0x7d, 0x2d, 0xac, 0xe8,
186    0x10, 0xc5, 0x2e, 0x99, 0xf9
187  };
188  const coap_str_const_t conf = { sizeof(conf_data)-1,
189                                  (const uint8_t *)conf_data
190                                };
191  coap_context_t ctx[1];
192  coap_oscore_conf_t *oscore_conf;
193  cose_encrypt0_t cose[1];
194  uint8_t nonce_buffer[13];
195  coap_bin_const_t nonce = { 13, nonce_buffer };
196
197  memset(&ctx, 0, sizeof(ctx));
198  oscore_conf = coap_new_oscore_conf(conf, NULL, NULL, 0);
199  FailIf_CU_ASSERT_PTR_NOT_NULL(oscore_conf);
200  coap_context_oscore_server(ctx, oscore_conf);
201  FailIf_CU_ASSERT_PTR_NOT_NULL(ctx->p_osc_ctx);
202
203  CU_ASSERT(CHECK_SAME(sender_key, ctx->p_osc_ctx->sender_context->sender_key));
204  CU_ASSERT(CHECK_SAME(recipient_key,
205                       ctx->p_osc_ctx->recipient_chain->recipient_key));
206  CU_ASSERT(CHECK_SAME(common_iv, ctx->p_osc_ctx->common_iv));
207
208  cose_encrypt0_init(cose);
209  cose_encrypt0_set_key_id(cose, ctx->p_osc_ctx->recipient_chain->recipient_id);
210  cose_encrypt0_set_partial_iv(cose, NULL);
211  oscore_generate_nonce(cose, ctx->p_osc_ctx, nonce_buffer, 13);
212  CU_ASSERT(CHECK_SAME(recipient_nonce, &nonce));
213
214  cose_encrypt0_init(cose);
215  cose_encrypt0_set_key_id(cose, ctx->p_osc_ctx->sender_context->sender_id);
216  cose_encrypt0_set_partial_iv(cose, NULL);
217  oscore_generate_nonce(cose, ctx->p_osc_ctx, nonce_buffer, 13);
218  CU_ASSERT(CHECK_SAME(sender_nonce, &nonce));
219
220fail:
221  oscore_free_contexts(ctx);
222}
223
224/* C.2.2.  Test Vector 2: Key Derivation without Master Salt, Server */
225static void
226t_oscore_c_2_2(void) {
227  static const char conf_data[] =
228      "master_secret,hex,\"0102030405060708090a0b0c0d0e0f10\"\n"
229      "sender_id,hex,\"01\"\n"
230      "recipient_id,hex,\"00\"\n";
231  static const uint8_t sender_key[] = {
232    0xe5, 0x7b, 0x56, 0x35, 0x81, 0x51, 0x77, 0xcd,
233    0x67, 0x9a, 0xb4, 0xbc, 0xec, 0x9d, 0x7d, 0xda
234  };
235  static const uint8_t recipient_key[] = {
236    0x32, 0x1b, 0x26, 0x94, 0x32, 0x53, 0xc7, 0xff,
237    0xb6, 0x00, 0x3b, 0x0b, 0x64, 0xd7, 0x40, 0x41
238  };
239  static const uint8_t common_iv[] = {
240    0xbe, 0x35, 0xae, 0x29, 0x7d, 0x2d, 0xac, 0xe9,
241    0x10, 0xc5, 0x2e, 0x99, 0xf9
242  };
243  static const uint8_t sender_nonce[] = {
244    0xbf, 0x35, 0xae, 0x29, 0x7d, 0x2d, 0xac, 0xe8,
245    0x10, 0xc5, 0x2e, 0x99, 0xf9
246  };
247  static const uint8_t recipient_nonce[] = {
248    0xbf, 0x35, 0xae, 0x29, 0x7d, 0x2d, 0xac, 0xe9,
249    0x10, 0xc5, 0x2e, 0x99, 0xf9
250  };
251  const coap_str_const_t conf = { sizeof(conf_data)-1,
252                                  (const uint8_t *)conf_data
253                                };
254  coap_context_t ctx[1];
255  coap_oscore_conf_t *oscore_conf;
256  cose_encrypt0_t cose[1];
257  uint8_t nonce_buffer[13];
258  coap_bin_const_t nonce = { 13, nonce_buffer };
259
260  memset(&ctx, 0, sizeof(ctx));
261  oscore_conf = coap_new_oscore_conf(conf, NULL, NULL, 0);
262  FailIf_CU_ASSERT_PTR_NOT_NULL(oscore_conf);
263  coap_context_oscore_server(ctx, oscore_conf);
264  FailIf_CU_ASSERT_PTR_NOT_NULL(ctx->p_osc_ctx);
265
266  CU_ASSERT(CHECK_SAME(sender_key, ctx->p_osc_ctx->sender_context->sender_key));
267  CU_ASSERT(CHECK_SAME(recipient_key,
268                       ctx->p_osc_ctx->recipient_chain->recipient_key));
269  CU_ASSERT(CHECK_SAME(common_iv, ctx->p_osc_ctx->common_iv));
270
271  cose_encrypt0_init(cose);
272  cose_encrypt0_set_key_id(cose, ctx->p_osc_ctx->recipient_chain->recipient_id);
273  cose_encrypt0_set_partial_iv(cose, NULL);
274  oscore_generate_nonce(cose, ctx->p_osc_ctx, nonce_buffer, 13);
275  CU_ASSERT(CHECK_SAME(recipient_nonce, &nonce));
276
277  cose_encrypt0_init(cose);
278  cose_encrypt0_set_key_id(cose, ctx->p_osc_ctx->sender_context->sender_id);
279  cose_encrypt0_set_partial_iv(cose, NULL);
280  oscore_generate_nonce(cose, ctx->p_osc_ctx, nonce_buffer, 13);
281  CU_ASSERT(CHECK_SAME(sender_nonce, &nonce));
282
283fail:
284  oscore_free_contexts(ctx);
285}
286
287/* C.3.1.  Test Vector 3: Key Derivation with ID Context, Client */
288static void
289t_oscore_c_3_1(void) {
290  static const char conf_data[] =
291      "master_secret,hex,\"0102030405060708090a0b0c0d0e0f10\"\n"
292      "master_salt,hex,\"9e7ca92223786340\"\n"
293      "id_context,hex,\"37cbf3210017a2d3\"\n"
294      "sender_id,hex,\"\"\n"
295      "recipient_id,hex,\"01\"\n";
296  static const uint8_t sender_key[] = {
297    0xaf, 0x2a, 0x13, 0x00, 0xa5, 0xe9, 0x57, 0x88,
298    0xb3, 0x56, 0x33, 0x6e, 0xee, 0xcd, 0x2b, 0x92
299  };
300  static const uint8_t recipient_key[] = {
301    0xe3, 0x9a, 0x0c, 0x7c, 0x77, 0xb4, 0x3f, 0x03,
302    0xb4, 0xb3, 0x9a, 0xb9, 0xa2, 0x68, 0x69, 0x9f
303  };
304  static const uint8_t common_iv[] = {
305    0x2c, 0xa5, 0x8f, 0xb8, 0x5f, 0xf1, 0xb8, 0x1c,
306    0x0b, 0x71, 0x81, 0xb8, 0x5e
307  };
308  static const uint8_t sender_nonce[] = {
309    0x2c, 0xa5, 0x8f, 0xb8, 0x5f, 0xf1, 0xb8, 0x1c,
310    0x0b, 0x71, 0x81, 0xb8, 0x5e
311  };
312  static const uint8_t recipient_nonce[] = {
313    0x2d, 0xa5, 0x8f, 0xb8, 0x5f, 0xf1, 0xb8, 0x1d,
314    0x0b, 0x71, 0x81, 0xb8, 0x5e
315  };
316  const coap_str_const_t conf = { sizeof(conf_data)-1,
317                                  (const uint8_t *)conf_data
318                                };
319  coap_context_t ctx[1];
320  coap_oscore_conf_t *oscore_conf;
321  cose_encrypt0_t cose[1];
322  uint8_t nonce_buffer[13];
323  coap_bin_const_t nonce = { 13, nonce_buffer };
324
325  memset(&ctx, 0, sizeof(ctx));
326  oscore_conf = coap_new_oscore_conf(conf, NULL, NULL, 0);
327  FailIf_CU_ASSERT_PTR_NOT_NULL(oscore_conf);
328  coap_context_oscore_server(ctx, oscore_conf);
329  FailIf_CU_ASSERT_PTR_NOT_NULL(ctx->p_osc_ctx);
330
331  CU_ASSERT(CHECK_SAME(sender_key, ctx->p_osc_ctx->sender_context->sender_key));
332  CU_ASSERT(CHECK_SAME(recipient_key,
333                       ctx->p_osc_ctx->recipient_chain->recipient_key));
334  CU_ASSERT(CHECK_SAME(common_iv, ctx->p_osc_ctx->common_iv));
335
336  cose_encrypt0_init(cose);
337  cose_encrypt0_set_key_id(cose, ctx->p_osc_ctx->recipient_chain->recipient_id);
338  cose_encrypt0_set_partial_iv(cose, NULL);
339  oscore_generate_nonce(cose, ctx->p_osc_ctx, nonce_buffer, 13);
340  CU_ASSERT(CHECK_SAME(recipient_nonce, &nonce));
341
342  cose_encrypt0_init(cose);
343  cose_encrypt0_set_key_id(cose, ctx->p_osc_ctx->sender_context->sender_id);
344  cose_encrypt0_set_partial_iv(cose, NULL);
345  oscore_generate_nonce(cose, ctx->p_osc_ctx, nonce_buffer, 13);
346  CU_ASSERT(CHECK_SAME(sender_nonce, &nonce));
347
348fail:
349  oscore_free_contexts(ctx);
350}
351
352/* C.3.2.  Test Vector 3: Key Derivation with ID Context, Server */
353static void
354t_oscore_c_3_2(void) {
355  static const char conf_data[] =
356      "master_secret,hex,\"0102030405060708090a0b0c0d0e0f10\"\n"
357      "master_salt,hex,\"9e7ca92223786340\"\n"
358      "id_context,hex,\"37cbf3210017a2d3\"\n"
359      "sender_id,hex,\"01\"\n"
360      "recipient_id,hex,\"\"\n";
361  static const uint8_t sender_key[] = {
362    0xe3, 0x9a, 0x0c, 0x7c, 0x77, 0xb4, 0x3f, 0x03,
363    0xb4, 0xb3, 0x9a, 0xb9, 0xa2, 0x68, 0x69, 0x9f
364  };
365  static const uint8_t recipient_key[] = {
366    0xaf, 0x2a, 0x13, 0x00, 0xa5, 0xe9, 0x57, 0x88,
367    0xb3, 0x56, 0x33, 0x6e, 0xee, 0xcd, 0x2b, 0x92
368  };
369  static const uint8_t common_iv[] = {
370    0x2c, 0xa5, 0x8f, 0xb8, 0x5f, 0xf1, 0xb8, 0x1c,
371    0x0b, 0x71, 0x81, 0xb8, 0x5e
372  };
373  static const uint8_t sender_nonce[] = {
374    0x2d, 0xa5, 0x8f, 0xb8, 0x5f, 0xf1, 0xb8, 0x1d,
375    0x0b, 0x71, 0x81, 0xb8, 0x5e
376  };
377  static const uint8_t recipient_nonce[] = {
378    0x2c, 0xa5, 0x8f, 0xb8, 0x5f, 0xf1, 0xb8, 0x1c,
379    0x0b, 0x71, 0x81, 0xb8, 0x5e
380  };
381  const coap_str_const_t conf = { sizeof(conf_data)-1,
382                                  (const uint8_t *)conf_data
383                                };
384  coap_context_t ctx[1];
385  coap_oscore_conf_t *oscore_conf;
386  cose_encrypt0_t cose[1];
387  uint8_t nonce_buffer[13];
388  coap_bin_const_t nonce = { 13, nonce_buffer };
389
390  memset(&ctx, 0, sizeof(ctx));
391  oscore_conf = coap_new_oscore_conf(conf, NULL, NULL, 0);
392  FailIf_CU_ASSERT_PTR_NOT_NULL(oscore_conf);
393  coap_context_oscore_server(ctx, oscore_conf);
394  FailIf_CU_ASSERT_PTR_NOT_NULL(ctx->p_osc_ctx);
395
396  CU_ASSERT(CHECK_SAME(sender_key, ctx->p_osc_ctx->sender_context->sender_key));
397  CU_ASSERT(CHECK_SAME(recipient_key,
398                       ctx->p_osc_ctx->recipient_chain->recipient_key));
399  CU_ASSERT(CHECK_SAME(common_iv, ctx->p_osc_ctx->common_iv));
400
401  cose_encrypt0_init(cose);
402  cose_encrypt0_set_key_id(cose, ctx->p_osc_ctx->recipient_chain->recipient_id);
403  cose_encrypt0_set_partial_iv(cose, NULL);
404  oscore_generate_nonce(cose, ctx->p_osc_ctx, nonce_buffer, 13);
405  CU_ASSERT(CHECK_SAME(recipient_nonce, &nonce));
406
407  cose_encrypt0_init(cose);
408  cose_encrypt0_set_key_id(cose, ctx->p_osc_ctx->sender_context->sender_id);
409  cose_encrypt0_set_partial_iv(cose, NULL);
410  oscore_generate_nonce(cose, ctx->p_osc_ctx, nonce_buffer, 13);
411  CU_ASSERT(CHECK_SAME(sender_nonce, &nonce));
412
413fail:
414  oscore_free_contexts(ctx);
415}
416
417/* C.4.  Test Vector 4: OSCORE Request, Client */
418static void
419t_oscore_c_4(void) {
420  static const char conf_data[] =
421      "master_secret,hex,\"0102030405060708090a0b0c0d0e0f10\"\n"
422      "master_salt,hex,\"9e7ca92223786340\"\n"
423      "sender_id,hex,\"\"\n"
424      "recipient_id,hex,\"01\"\n";
425  static const uint8_t unprotected_coap_request[] = {
426    0x44, 0x01, 0x5d, 0x1f, 0x00, 0x00, 0x39, 0x74,
427    0x39, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
428    0x73, 0x74, 0x83, 0x74, 0x76, 0x31
429  };
430  static const uint8_t protected_coap_request[] = {
431    0x44, 0x02, 0x5d, 0x1f, 0x00, 0x00, 0x39, 0x74,
432    0x39, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
433    0x73, 0x74, 0x62, 0x09, 0x14, 0xff, 0x61, 0x2f,
434    0x10, 0x92, 0xf1, 0x77, 0x6f, 0x1c, 0x16, 0x68,
435    0xb3, 0x82, 0x5e
436  };
437  const coap_str_const_t conf = { sizeof(conf_data)-1,
438                                  (const uint8_t *)conf_data
439                                };
440  coap_context_t ctx[1];
441  coap_oscore_conf_t *oscore_conf;
442  int result;
443  coap_pdu_t *pdu = coap_pdu_init(0, 0, 0, COAP_DEFAULT_MTU);
444  coap_pdu_t *osc_pdu = NULL;
445  coap_session_t *session = NULL;
446
447  memset(&ctx, 0, sizeof(ctx));
448  FailIf_CU_ASSERT_PTR_NOT_NULL(pdu);
449
450  oscore_conf = coap_new_oscore_conf(conf, NULL, NULL, 20);
451  FailIf_CU_ASSERT_PTR_NOT_NULL(oscore_conf);
452  coap_context_oscore_server(ctx, oscore_conf);
453  FailIf_CU_ASSERT_PTR_NOT_NULL(ctx->p_osc_ctx);
454
455  result = coap_pdu_parse(COAP_PROTO_UDP, unprotected_coap_request,
456                          sizeof(unprotected_coap_request), pdu);
457  CU_ASSERT(result > 0);
458
459  session = coap_malloc_type(COAP_SESSION, sizeof(coap_session_t));
460  FailIf_CU_ASSERT_PTR_NOT_NULL(session);
461  memset(session, 0, sizeof(coap_session_t));
462  session->proto = COAP_PROTO_UDP;
463  session->type = COAP_SESSION_TYPE_CLIENT;
464  session->recipient_ctx = ctx->p_osc_ctx->recipient_chain;
465
466  osc_pdu = coap_oscore_new_pdu_encrypted(session, pdu, NULL, 0);
467  FailIf_CU_ASSERT_PTR_NOT_NULL(osc_pdu);
468
469  result = coap_pdu_encode_header(osc_pdu, session->proto);
470  CU_ASSERT(result != 0);
471  CU_ASSERT(osc_pdu->hdr_size + osc_pdu->used_size ==
472            sizeof(protected_coap_request));
473  result = memcmp(&osc_pdu->token[-osc_pdu->hdr_size], protected_coap_request,
474                  osc_pdu->hdr_size + osc_pdu->used_size);
475  CU_ASSERT(result == 0);
476
477fail:
478  oscore_free_contexts(ctx);
479  coap_delete_pdu(pdu);
480  coap_delete_pdu(osc_pdu);
481  oscore_delete_server_associations(session);
482  coap_free(session);
483}
484
485/* C.5.  Test Vector 5: OSCORE Request, Client */
486static void
487t_oscore_c_5(void) {
488  static const char conf_data[] =
489      "master_secret,hex,\"0102030405060708090a0b0c0d0e0f10\"\n"
490      "sender_id,hex,\"00\"\n"
491      "recipient_id,hex,\"01\"\n";
492  static const uint8_t unprotected_coap_request[] = {
493    0x44, 0x01, 0x71, 0xc3, 0x00, 0x00, 0xb9, 0x32,
494    0x39, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
495    0x73, 0x74, 0x83, 0x74, 0x76, 0x31
496  };
497  static const uint8_t protected[] = {
498    0x44, 0x02, 0x71, 0xc3, 0x00, 0x00, 0xb9, 0x32,
499    0x39, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
500    0x73, 0x74, 0x63, 0x09, 0x14, 0x00, 0xff, 0x4e,
501    0xd3, 0x39, 0xa5, 0xa3, 0x79, 0xb0, 0xb8, 0xbc,
502    0x73, 0x1f, 0xff, 0xb0
503  };
504  const coap_str_const_t conf = { sizeof(conf_data)-1,
505                                  (const uint8_t *)conf_data
506                                };
507  coap_context_t ctx[1];
508  coap_oscore_conf_t *oscore_conf;
509  int result;
510  coap_pdu_t *pdu = coap_pdu_init(0, 0, 0, COAP_DEFAULT_MTU);
511  coap_pdu_t *osc_pdu = NULL;
512  coap_session_t *session = NULL;
513
514  memset(&ctx, 0, sizeof(ctx));
515  FailIf_CU_ASSERT_PTR_NOT_NULL(pdu);
516
517  oscore_conf = coap_new_oscore_conf(conf, NULL, NULL, 20);
518  FailIf_CU_ASSERT_PTR_NOT_NULL(oscore_conf);
519  coap_context_oscore_server(ctx, oscore_conf);
520  FailIf_CU_ASSERT_PTR_NOT_NULL(ctx->p_osc_ctx);
521
522  result = coap_pdu_parse(COAP_PROTO_UDP, unprotected_coap_request,
523                          sizeof(unprotected_coap_request), pdu);
524  CU_ASSERT(result > 0);
525
526  session = coap_malloc_type(COAP_SESSION, sizeof(coap_session_t));
527  FailIf_CU_ASSERT_PTR_NOT_NULL(session);
528  memset(session, 0, sizeof(coap_session_t));
529  session->proto = COAP_PROTO_UDP;
530  session->type = COAP_SESSION_TYPE_CLIENT;
531  session->recipient_ctx = ctx->p_osc_ctx->recipient_chain;
532
533  osc_pdu = coap_oscore_new_pdu_encrypted(session, pdu, NULL, 0);
534  FailIf_CU_ASSERT_PTR_NOT_NULL(osc_pdu);
535
536  result = coap_pdu_encode_header(osc_pdu, session->proto);
537  CU_ASSERT(result != 0);
538  CU_ASSERT(osc_pdu->hdr_size + osc_pdu->used_size == sizeof(protected));
539  result = memcmp(&osc_pdu->token[-osc_pdu->hdr_size], protected,
540                  osc_pdu->hdr_size + osc_pdu->used_size);
541  CU_ASSERT(result == 0);
542
543fail:
544  oscore_free_contexts(ctx);
545  coap_delete_pdu(pdu);
546  coap_delete_pdu(osc_pdu);
547  oscore_delete_server_associations(session);
548  coap_free(session);
549}
550
551/* C.6.  Test Vector 6: OSCORE Request, Client */
552static void
553t_oscore_c_6(void) {
554  static const char conf_data[] =
555      "master_secret,hex,\"0102030405060708090a0b0c0d0e0f10\"\n"
556      "master_salt,hex,\"9e7ca92223786340\"\n"
557      "id_context,hex,\"37cbf3210017a2d3\"\n"
558      "sender_id,hex,\"\"\n"
559      "recipient_id,hex,\"01\"\n";
560  static const uint8_t unprotected_coap_request[] = {
561    0x44, 0x01, 0x2f, 0x8e, 0xef, 0x9b, 0xbf, 0x7a,
562    0x39, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
563    0x73, 0x74, 0x83, 0x74, 0x76, 0x31
564  };
565  static const uint8_t protected[] = {
566    0x44, 0x02, 0x2f, 0x8e, 0xef, 0x9b, 0xbf, 0x7a,
567    0x39, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
568    0x73, 0x74, 0x6b, 0x19, 0x14, 0x08, 0x37, 0xcb,
569    0xf3, 0x21, 0x00, 0x17, 0xa2, 0xd3, 0xff, 0x72,
570    0xcd, 0x72, 0x73, 0xfd, 0x33, 0x1a, 0xc4, 0x5c,
571    0xff, 0xbe, 0x55, 0xc3
572  };
573  const coap_str_const_t conf = { sizeof(conf_data)-1,
574                                  (const uint8_t *)conf_data
575                                };
576  coap_context_t ctx[1];
577  coap_oscore_conf_t *oscore_conf;
578  int result;
579  coap_pdu_t *pdu = coap_pdu_init(0, 0, 0, COAP_DEFAULT_MTU);
580  coap_pdu_t *osc_pdu = NULL;
581  coap_session_t *session = NULL;
582
583  memset(&ctx, 0, sizeof(ctx));
584  FailIf_CU_ASSERT_PTR_NOT_NULL(pdu);
585
586  oscore_conf = coap_new_oscore_conf(conf, NULL, NULL, 20);
587  FailIf_CU_ASSERT_PTR_NOT_NULL(oscore_conf);
588  coap_context_oscore_server(ctx, oscore_conf);
589  FailIf_CU_ASSERT_PTR_NOT_NULL(ctx->p_osc_ctx);
590
591  result = coap_pdu_parse(COAP_PROTO_UDP, unprotected_coap_request,
592                          sizeof(unprotected_coap_request), pdu);
593  CU_ASSERT(result > 0);
594
595  session = coap_malloc_type(COAP_SESSION, sizeof(coap_session_t));
596  FailIf_CU_ASSERT_PTR_NOT_NULL(session);
597  memset(session, 0, sizeof(coap_session_t));
598  session->proto = COAP_PROTO_UDP;
599  session->type = COAP_SESSION_TYPE_CLIENT;
600  session->recipient_ctx = ctx->p_osc_ctx->recipient_chain;
601
602  osc_pdu = coap_oscore_new_pdu_encrypted(session, pdu, NULL, 0);
603  FailIf_CU_ASSERT_PTR_NOT_NULL(osc_pdu);
604
605  result = coap_pdu_encode_header(osc_pdu, session->proto);
606  CU_ASSERT(result != 0);
607  CU_ASSERT(osc_pdu->hdr_size + osc_pdu->used_size == sizeof(protected));
608  result = memcmp(&osc_pdu->token[-osc_pdu->hdr_size], protected,
609                  osc_pdu->hdr_size + osc_pdu->used_size);
610  CU_ASSERT(result == 0);
611
612fail:
613  oscore_free_contexts(ctx);
614  coap_delete_pdu(pdu);
615  coap_delete_pdu(osc_pdu);
616  oscore_delete_server_associations(session);
617  coap_free(session);
618}
619
620/* C.7.  Test Vector 7: OSCORE Response, Server */
621static void
622t_oscore_c_7(void) {
623  static const char conf_data[] =
624      "master_secret,hex,\"0102030405060708090a0b0c0d0e0f10\"\n"
625      "master_salt,hex,\"9e7ca92223786340\"\n"
626      "sender_id,hex,\"01\"\n"
627      "recipient_id,hex,\"\"\n";
628  static const uint8_t protected_coap_request[] = {
629    0x44, 0x02, 0x5d, 0x1f, 0x00, 0x00, 0x39, 0x74,
630    0x39, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
631    0x73, 0x74, 0x62, 0x09, 0x14, 0xff, 0x61, 0x2f,
632    0x10, 0x92, 0xf1, 0x77, 0x6f, 0x1c, 0x16, 0x68,
633    0xb3, 0x82, 0x5e
634  };
635  static const uint8_t unprotected_coap_request[] = {
636    0x44, 0x01, 0x5d, 0x1f, 0x00, 0x00, 0x39, 0x74,
637    0x39, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
638    0x73, 0x74, 0x83, 0x74, 0x76, 0x31
639  };
640  static const uint8_t unprotected_coap_response[] = {
641    0x64, 0x45, 0x5d, 0x1f, 0x00, 0x00, 0x39, 0x74,
642    0xff, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57,
643    0x6f, 0x72, 0x6c, 0x64, 0x21
644  };
645  static const uint8_t protected_coap_response[] = {
646    0x64, 0x44, 0x5d, 0x1f, 0x00, 0x00, 0x39, 0x74,
647    0x90, 0xff, 0xdb, 0xaa, 0xd1, 0xe9, 0xa7, 0xe7,
648    0xb2, 0xa8, 0x13, 0xd3, 0xc3, 0x15, 0x24, 0x37,
649    0x83, 0x03, 0xcd, 0xaf, 0xae, 0x11, 0x91, 0x06
650  };
651  const coap_str_const_t conf = { sizeof(conf_data)-1,
652                                  (const uint8_t *)conf_data
653                                };
654  coap_context_t ctx[1];
655  coap_oscore_conf_t *oscore_conf;
656  int result;
657  coap_pdu_t *incoming_pdu = coap_pdu_init(0, 0, 0, COAP_DEFAULT_MTU);
658  coap_pdu_t *pdu = coap_pdu_init(0, 0, 0, COAP_DEFAULT_MTU);
659  coap_pdu_t *osc_pdu = NULL;
660  coap_session_t *session = NULL;
661
662  memset(&ctx, 0, sizeof(ctx));
663  FailIf_CU_ASSERT_PTR_NOT_NULL(incoming_pdu);
664  FailIf_CU_ASSERT_PTR_NOT_NULL(pdu);
665
666  oscore_conf = coap_new_oscore_conf(conf, NULL, NULL, 0);
667  FailIf_CU_ASSERT_PTR_NOT_NULL(oscore_conf);
668  coap_context_oscore_server(ctx, oscore_conf);
669  FailIf_CU_ASSERT_PTR_NOT_NULL(ctx->p_osc_ctx);
670
671  result = coap_pdu_parse(COAP_PROTO_UDP, protected_coap_request,
672                          sizeof(protected_coap_request), incoming_pdu);
673  CU_ASSERT(result > 0);
674
675  result = coap_pdu_parse(COAP_PROTO_UDP, unprotected_coap_response,
676                          sizeof(unprotected_coap_response), pdu);
677  CU_ASSERT(result > 0);
678
679  session = coap_malloc_type(COAP_SESSION, sizeof(coap_session_t));
680  FailIf_CU_ASSERT_PTR_NOT_NULL(session);
681  memset(session, 0, sizeof(coap_session_t));
682  session->proto = COAP_PROTO_UDP;
683  session->type = COAP_SESSION_TYPE_SERVER;
684  session->recipient_ctx = ctx->p_osc_ctx->recipient_chain;
685  session->recipient_ctx->initial_state = 0;
686  session->context = ctx;
687
688  /* First, decrypt incoming request to set up all variables for
689     sending response */
690  osc_pdu = coap_oscore_decrypt_pdu(session, incoming_pdu);
691  FailIf_CU_ASSERT_PTR_NOT_NULL(osc_pdu);
692  result = coap_pdu_encode_header(osc_pdu, session->proto);
693  CU_ASSERT(result != 0);
694  CU_ASSERT(osc_pdu->hdr_size + osc_pdu->used_size ==
695            sizeof(unprotected_coap_request));
696  result = memcmp(&osc_pdu->token[-osc_pdu->hdr_size], unprotected_coap_request,
697                  osc_pdu->hdr_size + osc_pdu->used_size);
698  CU_ASSERT(result == 0);
699  coap_delete_pdu(osc_pdu);
700  osc_pdu = NULL;
701  coap_delete_pdu(incoming_pdu);
702  incoming_pdu = NULL;
703
704  /* Now encrypt the server's response */
705  osc_pdu = coap_oscore_new_pdu_encrypted(session, pdu, NULL, 0);
706  FailIf_CU_ASSERT_PTR_NOT_NULL(osc_pdu);
707
708  result = coap_pdu_encode_header(osc_pdu, session->proto);
709  CU_ASSERT(result != 0);
710  CU_ASSERT(osc_pdu->hdr_size + osc_pdu->used_size ==
711            sizeof(protected_coap_response));
712  result = memcmp(&osc_pdu->token[-osc_pdu->hdr_size], protected_coap_response,
713                  osc_pdu->hdr_size + osc_pdu->used_size);
714  CU_ASSERT(result == 0);
715
716fail:
717  oscore_free_contexts(ctx);
718  coap_delete_pdu(pdu);
719  coap_delete_pdu(incoming_pdu);
720  coap_delete_pdu(osc_pdu);
721  oscore_delete_server_associations(session);
722  coap_free(session);
723}
724
725/*
726 * Decrypt the encrypted response from C.7 and check it matches input
727 */
728static void
729t_oscore_c_7_2(void) {
730  static const char conf_data[] =
731      "master_secret,hex,\"0102030405060708090a0b0c0d0e0f10\"\n"
732      "master_salt,hex,\"9e7ca92223786340\"\n"
733      "sender_id,hex,\"\"\n"
734      "recipient_id,hex,\"01\"\n";
735  static const uint8_t unprotected_coap_request[] = {
736    0x44, 0x01, 0x5d, 0x1f, 0x00, 0x00, 0x39, 0x74,
737    0x39, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
738    0x73, 0x74, 0x83, 0x74, 0x76, 0x31
739  };
740  static const uint8_t protected_coap_request[] = {
741    0x44, 0x02, 0x5d, 0x1f, 0x00, 0x00, 0x39, 0x74,
742    0x39, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
743    0x73, 0x74, 0x62, 0x09, 0x14, 0xff, 0x61, 0x2f,
744    0x10, 0x92, 0xf1, 0x77, 0x6f, 0x1c, 0x16, 0x68,
745    0xb3, 0x82, 0x5e
746  };
747  static const uint8_t unprotected_coap_response[] = {
748    0x64, 0x45, 0x5d, 0x1f, 0x00, 0x00, 0x39, 0x74,
749    0xff, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57,
750    0x6f, 0x72, 0x6c, 0x64, 0x21
751  };
752  static const uint8_t protected_coap_response[] = {
753    0x64, 0x44, 0x5d, 0x1f, 0x00, 0x00, 0x39, 0x74,
754    0x90, 0xff, 0xdb, 0xaa, 0xd1, 0xe9, 0xa7, 0xe7,
755    0xb2, 0xa8, 0x13, 0xd3, 0xc3, 0x15, 0x24, 0x37,
756    0x83, 0x03, 0xcd, 0xaf, 0xae, 0x11, 0x91, 0x06
757  };
758  const coap_str_const_t conf = { sizeof(conf_data)-1,
759                                  (const uint8_t *)conf_data
760                                };
761  coap_context_t ctx[1];
762  coap_oscore_conf_t *oscore_conf;
763  int result;
764  coap_pdu_t *outgoing_pdu = coap_pdu_init(0, 0, 0, COAP_DEFAULT_MTU);
765  coap_pdu_t *incoming_pdu = coap_pdu_init(0, 0, 0, COAP_DEFAULT_MTU);
766  coap_pdu_t *osc_pdu = NULL;
767  coap_session_t *session = NULL;
768
769  memset(&ctx, 0, sizeof(ctx));
770  FailIf_CU_ASSERT_PTR_NOT_NULL(outgoing_pdu);
771  FailIf_CU_ASSERT_PTR_NOT_NULL(incoming_pdu);
772
773  oscore_conf = coap_new_oscore_conf(conf, NULL, NULL, 20);
774  FailIf_CU_ASSERT_PTR_NOT_NULL(oscore_conf);
775  coap_context_oscore_server(ctx, oscore_conf);
776  FailIf_CU_ASSERT_PTR_NOT_NULL(ctx->p_osc_ctx);
777
778  result = coap_pdu_parse(COAP_PROTO_UDP, unprotected_coap_request,
779                          sizeof(unprotected_coap_request), outgoing_pdu);
780  CU_ASSERT(result > 0);
781  result = coap_pdu_parse(COAP_PROTO_UDP, protected_coap_response,
782                          sizeof(protected_coap_response), incoming_pdu);
783  CU_ASSERT(result > 0);
784
785  session = coap_malloc_type(COAP_SESSION, sizeof(coap_session_t));
786  FailIf_CU_ASSERT_PTR_NOT_NULL(session);
787  memset(session, 0, sizeof(coap_session_t));
788  session->proto = COAP_PROTO_UDP;
789  session->type = COAP_SESSION_TYPE_CLIENT;
790  session->recipient_ctx = ctx->p_osc_ctx->recipient_chain;
791  session->recipient_ctx->initial_state = 0;
792  session->context = ctx;
793
794  /* Send request, so that all associations etc. are correctly set up */
795
796  osc_pdu = coap_oscore_new_pdu_encrypted(session, outgoing_pdu, NULL, 0);
797  FailIf_CU_ASSERT_PTR_NOT_NULL(osc_pdu);
798
799  result = coap_pdu_encode_header(osc_pdu, session->proto);
800  CU_ASSERT(result != 0);
801  CU_ASSERT(osc_pdu->hdr_size + osc_pdu->used_size ==
802            sizeof(protected_coap_request));
803  result = memcmp(&osc_pdu->token[-osc_pdu->hdr_size], protected_coap_request,
804                  osc_pdu->hdr_size + osc_pdu->used_size);
805  CU_ASSERT(result == 0);
806  coap_delete_pdu(outgoing_pdu);
807  outgoing_pdu = NULL;
808  coap_delete_pdu(osc_pdu);
809  osc_pdu = NULL;
810
811  /* Decrypt the encrypted response */
812
813  osc_pdu = coap_oscore_decrypt_pdu(session, incoming_pdu);
814  FailIf_CU_ASSERT_PTR_NOT_NULL(osc_pdu);
815
816  result = coap_pdu_encode_header(osc_pdu, session->proto);
817  CU_ASSERT(result != 0);
818  CU_ASSERT(osc_pdu->hdr_size + osc_pdu->used_size ==
819            sizeof(unprotected_coap_response));
820  result = memcmp(&osc_pdu->token[-osc_pdu->hdr_size],
821                  unprotected_coap_response,
822                  osc_pdu->hdr_size + osc_pdu->used_size);
823  CU_ASSERT(result == 0);
824
825fail:
826  oscore_free_contexts(ctx);
827  coap_delete_pdu(incoming_pdu);
828  coap_delete_pdu(outgoing_pdu);
829  coap_delete_pdu(osc_pdu);
830  coap_free(session);
831}
832
833/* C.8.  Test Vector 8: OSCORE Response with Partial IV, Server */
834static void
835t_oscore_c_8(void) {
836  static const char conf_data[] =
837      "master_secret,hex,\"0102030405060708090a0b0c0d0e0f10\"\n"
838      "master_salt,hex,\"9e7ca92223786340\"\n"
839      "sender_id,hex,\"01\"\n"
840      "recipient_id,hex,\"\"\n";
841  static const uint8_t protected_coap_request[] = {
842    0x44, 0x02, 0x5d, 0x1f, 0x00, 0x00, 0x39, 0x74,
843    0x39, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
844    0x73, 0x74, 0x62, 0x09, 0x14, 0xff, 0x61, 0x2f,
845    0x10, 0x92, 0xf1, 0x77, 0x6f, 0x1c, 0x16, 0x68,
846    0xb3, 0x82, 0x5e
847  };
848  static const uint8_t unprotected_coap_request[] = {
849    0x44, 0x01, 0x5d, 0x1f, 0x00, 0x00, 0x39, 0x74,
850    0x39, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
851    0x73, 0x74, 0x83, 0x74, 0x76, 0x31
852  };
853  static const uint8_t unprotected_coap_response[] = {
854    0x64, 0x45, 0x5d, 0x1f, 0x00, 0x00, 0x39, 0x74,
855    0xff, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57,
856    0x6f, 0x72, 0x6c, 0x64, 0x21
857  };
858  static const uint8_t protected_coap_response[] = {
859    0x64, 0x44, 0x5d, 0x1f, 0x00, 0x00, 0x39, 0x74,
860    0x92, 0x01, 0x00, 0xff, 0x4d, 0x4c, 0x13, 0x66,
861    0x93, 0x84, 0xb6, 0x73, 0x54, 0xb2, 0xb6, 0x17,
862    0x5f, 0xf4, 0xb8, 0x65, 0x8c, 0x66, 0x6a, 0x6c,
863    0xf8, 0x8e
864  };
865  const coap_str_const_t conf = { sizeof(conf_data)-1,
866                                  (const uint8_t *)conf_data
867                                };
868  coap_context_t ctx[1];
869  coap_oscore_conf_t *oscore_conf;
870  int result;
871  coap_pdu_t *incoming_pdu = coap_pdu_init(0, 0, 0, COAP_DEFAULT_MTU);
872  coap_pdu_t *pdu = coap_pdu_init(0, 0, 0, COAP_DEFAULT_MTU);
873  coap_pdu_t *osc_pdu = NULL;
874  coap_session_t *session = NULL;
875
876  memset(&ctx, 0, sizeof(ctx));
877  FailIf_CU_ASSERT_PTR_NOT_NULL(incoming_pdu);
878  FailIf_CU_ASSERT_PTR_NOT_NULL(pdu);
879
880  oscore_conf = coap_new_oscore_conf(conf, NULL, NULL, 0);
881  FailIf_CU_ASSERT_PTR_NOT_NULL(oscore_conf);
882  coap_context_oscore_server(ctx, oscore_conf);
883  FailIf_CU_ASSERT_PTR_NOT_NULL(ctx->p_osc_ctx);
884
885  result = coap_pdu_parse(COAP_PROTO_UDP, protected_coap_request,
886                          sizeof(protected_coap_request), incoming_pdu);
887  CU_ASSERT(result > 0);
888
889  result = coap_pdu_parse(COAP_PROTO_UDP, unprotected_coap_response,
890                          sizeof(unprotected_coap_response), pdu);
891  CU_ASSERT(result > 0);
892
893  session = coap_malloc_type(COAP_SESSION, sizeof(coap_session_t));
894  FailIf_CU_ASSERT_PTR_NOT_NULL(session);
895  memset(session, 0, sizeof(coap_session_t));
896  session->proto = COAP_PROTO_UDP;
897  session->type = COAP_SESSION_TYPE_SERVER;
898  session->recipient_ctx = ctx->p_osc_ctx->recipient_chain;
899  session->recipient_ctx->initial_state = 0;
900  session->context = ctx;
901
902  /* First, decrypt incoming request to set up all variables for
903     sending response */
904  osc_pdu = coap_oscore_decrypt_pdu(session, incoming_pdu);
905  FailIf_CU_ASSERT_PTR_NOT_NULL(osc_pdu);
906  result = coap_pdu_encode_header(osc_pdu, session->proto);
907  CU_ASSERT(result != 0);
908  CU_ASSERT(osc_pdu->hdr_size + osc_pdu->used_size ==
909            sizeof(unprotected_coap_request));
910  result = memcmp(&osc_pdu->token[-osc_pdu->hdr_size], unprotected_coap_request,
911                  osc_pdu->hdr_size + osc_pdu->used_size);
912  CU_ASSERT(result == 0);
913  coap_delete_pdu(osc_pdu);
914  osc_pdu = NULL;
915  coap_delete_pdu(incoming_pdu);
916  incoming_pdu = NULL;
917
918  /* Now encrypt the server's response */
919  osc_pdu = coap_oscore_new_pdu_encrypted(session, pdu, NULL, 1);
920  FailIf_CU_ASSERT_PTR_NOT_NULL(osc_pdu);
921
922  result = coap_pdu_encode_header(osc_pdu, session->proto);
923  CU_ASSERT(result != 0);
924  CU_ASSERT(osc_pdu->hdr_size + osc_pdu->used_size ==
925            sizeof(protected_coap_response));
926  result = memcmp(&osc_pdu->token[-osc_pdu->hdr_size], protected_coap_response,
927                  osc_pdu->hdr_size + osc_pdu->used_size);
928  CU_ASSERT(result == 0);
929
930fail:
931  oscore_free_contexts(ctx);
932  coap_delete_pdu(pdu);
933  coap_delete_pdu(incoming_pdu);
934  coap_delete_pdu(osc_pdu);
935  oscore_delete_server_associations(session);
936  coap_free(session);
937}
938
939/*
940 * Decrypt the encrypted response from C.8 and check it matches input
941 */
942static void
943t_oscore_c_8_2(void) {
944  static const char conf_data[] =
945      "master_secret,hex,\"0102030405060708090a0b0c0d0e0f10\"\n"
946      "master_salt,hex,\"9e7ca92223786340\"\n"
947      "sender_id,hex,\"\"\n"
948      "recipient_id,hex,\"01\"\n";
949  static const uint8_t unprotected_coap_request[] = {
950    0x44, 0x01, 0x5d, 0x1f, 0x00, 0x00, 0x39, 0x74,
951    0x39, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
952    0x73, 0x74, 0x83, 0x74, 0x76, 0x31
953  };
954  static const uint8_t protected_coap_request[] = {
955    0x44, 0x02, 0x5d, 0x1f, 0x00, 0x00, 0x39, 0x74,
956    0x39, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
957    0x73, 0x74, 0x62, 0x09, 0x14, 0xff, 0x61, 0x2f,
958    0x10, 0x92, 0xf1, 0x77, 0x6f, 0x1c, 0x16, 0x68,
959    0xb3, 0x82, 0x5e
960  };
961  static const uint8_t unprotected_coap_response[] = {
962    0x64, 0x45, 0x5d, 0x1f, 0x00, 0x00, 0x39, 0x74,
963    0xff, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57,
964    0x6f, 0x72, 0x6c, 0x64, 0x21
965  };
966  static const uint8_t protected_coap_response[] = {
967    0x64, 0x44, 0x5d, 0x1f, 0x00, 0x00, 0x39, 0x74,
968    0x92, 0x01, 0x00, 0xff, 0x4d, 0x4c, 0x13, 0x66,
969    0x93, 0x84, 0xb6, 0x73, 0x54, 0xb2, 0xb6, 0x17,
970    0x5f, 0xf4, 0xb8, 0x65, 0x8c, 0x66, 0x6a, 0x6c,
971    0xf8, 0x8e
972  };
973  const coap_str_const_t conf = { sizeof(conf_data)-1,
974                                  (const uint8_t *)conf_data
975                                };
976  coap_context_t ctx[1];
977  coap_oscore_conf_t *oscore_conf;
978  int result;
979  coap_pdu_t *outgoing_pdu = coap_pdu_init(0, 0, 0, COAP_DEFAULT_MTU);
980  coap_pdu_t *incoming_pdu = coap_pdu_init(0, 0, 0, COAP_DEFAULT_MTU);
981  coap_pdu_t *osc_pdu = NULL;
982  coap_session_t *session = NULL;
983
984  memset(&ctx, 0, sizeof(ctx));
985  FailIf_CU_ASSERT_PTR_NOT_NULL(outgoing_pdu);
986  FailIf_CU_ASSERT_PTR_NOT_NULL(incoming_pdu);
987
988  oscore_conf = coap_new_oscore_conf(conf, NULL, NULL, 20);
989  FailIf_CU_ASSERT_PTR_NOT_NULL(oscore_conf);
990  coap_context_oscore_server(ctx, oscore_conf);
991  FailIf_CU_ASSERT_PTR_NOT_NULL(ctx->p_osc_ctx);
992
993  result = coap_pdu_parse(COAP_PROTO_UDP, unprotected_coap_request,
994                          sizeof(unprotected_coap_request), outgoing_pdu);
995  CU_ASSERT(result > 0);
996  result = coap_pdu_parse(COAP_PROTO_UDP, protected_coap_response,
997                          sizeof(protected_coap_response), incoming_pdu);
998  CU_ASSERT(result > 0);
999
1000  session = coap_malloc_type(COAP_SESSION, sizeof(coap_session_t));
1001  FailIf_CU_ASSERT_PTR_NOT_NULL(session);
1002  memset(session, 0, sizeof(coap_session_t));
1003  session->proto = COAP_PROTO_UDP;
1004  session->type = COAP_SESSION_TYPE_CLIENT;
1005  session->recipient_ctx = ctx->p_osc_ctx->recipient_chain;
1006  session->context = ctx;
1007
1008  /* Send request, so that all associations etc. are correctly set up */
1009
1010  osc_pdu = coap_oscore_new_pdu_encrypted(session, outgoing_pdu, NULL, 0);
1011  FailIf_CU_ASSERT_PTR_NOT_NULL(osc_pdu);
1012
1013  result = coap_pdu_encode_header(osc_pdu, session->proto);
1014  CU_ASSERT(result != 0);
1015  CU_ASSERT(osc_pdu->hdr_size + osc_pdu->used_size ==
1016            sizeof(protected_coap_request));
1017  result = memcmp(&osc_pdu->token[-osc_pdu->hdr_size], protected_coap_request,
1018                  osc_pdu->hdr_size + osc_pdu->used_size);
1019  CU_ASSERT(result == 0);
1020  coap_delete_pdu(outgoing_pdu);
1021  /* CDI 1566477 */
1022  outgoing_pdu = NULL;
1023  coap_delete_pdu(osc_pdu);
1024  osc_pdu = NULL;
1025
1026  /* Decrypt the encrypted response */
1027
1028  osc_pdu = coap_oscore_decrypt_pdu(session, incoming_pdu);
1029  FailIf_CU_ASSERT_PTR_NOT_NULL(osc_pdu);
1030
1031  result = coap_pdu_encode_header(osc_pdu, session->proto);
1032  CU_ASSERT(result != 0);
1033  CU_ASSERT(osc_pdu->hdr_size + osc_pdu->used_size ==
1034            sizeof(unprotected_coap_response));
1035  result = memcmp(&osc_pdu->token[-osc_pdu->hdr_size],
1036                  unprotected_coap_response,
1037                  osc_pdu->hdr_size + osc_pdu->used_size);
1038  CU_ASSERT(result == 0);
1039
1040fail:
1041  oscore_free_contexts(ctx);
1042  coap_delete_pdu(incoming_pdu);
1043  coap_delete_pdu(outgoing_pdu);
1044  coap_delete_pdu(osc_pdu);
1045  coap_free(session);
1046}
1047
1048/************************************************************************
1049 ** initialization
1050 ************************************************************************/
1051
1052CU_pSuite
1053t_init_oscore_tests(void) {
1054  CU_pSuite suite[5];
1055
1056  suite[0] = CU_add_suite("RFC8613 Appendix C OSCORE tests", NULL, NULL);
1057  if (!suite[0]) {                        /* signal error */
1058    fprintf(stderr, "W: cannot add OSCORE test suite (%s)\n",
1059            CU_get_error_msg());
1060
1061    return NULL;
1062  }
1063
1064#define OSCORE_TEST(n)                                  \
1065  if (!CU_add_test(suite[0], #n, n)) {                  \
1066    fprintf(stderr, "W: cannot add OSCORE test (%s)\n", \
1067            CU_get_error_msg());                        \
1068  }
1069
1070  if (coap_oscore_is_supported()) {
1071    OSCORE_TEST(t_oscore_c_1_1);
1072    OSCORE_TEST(t_oscore_c_1_2);
1073    OSCORE_TEST(t_oscore_c_2_1);
1074    OSCORE_TEST(t_oscore_c_2_2);
1075    OSCORE_TEST(t_oscore_c_3_1);
1076    OSCORE_TEST(t_oscore_c_3_2);
1077    OSCORE_TEST(t_oscore_c_4);
1078    OSCORE_TEST(t_oscore_c_5);
1079    OSCORE_TEST(t_oscore_c_6);
1080    OSCORE_TEST(t_oscore_c_7);
1081    OSCORE_TEST(t_oscore_c_7_2);
1082    OSCORE_TEST(t_oscore_c_8);
1083    OSCORE_TEST(t_oscore_c_8_2);
1084  }
1085
1086  return suite[0];
1087}
1088
1089#else /* COAP_OSCORE_SUPPORT && COAP_SERVER_SUPPORT  */
1090
1091#ifdef __clang__
1092/* Make compilers happy that do not like empty modules. As this function is
1093 * never used, we ignore -Wunused-function at the end of compiling this file
1094 */
1095#pragma GCC diagnostic ignored "-Wunused-function"
1096#endif
1097static inline void
1098dummy(void) {
1099}
1100
1101#endif /* COAP_OSCORE_SUPPORT && COAP_SERVER_SUPPORT  */
1102