1 /*
2    Copyright (c) 2021 Fraunhofer AISEC. See the COPYRIGHT
3    file at the top-level directory of this distribution.
4 
5    Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6    http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7    <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8    option. This file may not be copied, modified, or distributed
9    except according to those terms.
10 */
11 
12 #ifndef COAP_H
13 #define COAP_H
14 
15 #include <stdint.h>
16 
17 #include "common/byte_array.h"
18 #include "common/oscore_edhoc_error.h"
19 
20 #define MAX_PIV_LEN 5
21 #define MAX_KID_CONTEXT_LEN                                                    \
22 	8 /*This implementation supports Context IDs up to 8 byte*/
23 #define MAX_KID_LEN 7
24 #define MAX_AAD_LEN 30
25 #define MAX_INFO_LEN 50
26 
27 /* Mask and offset for first byte in CoAP/OSCORE header*/
28 #define HEADER_LEN 4
29 #define HEADER_VERSION_MASK 0xC0
30 #define HEADER_VERSION_OFFSET 6
31 #define HEADER_TYPE_MASK 0x30
32 #define HEADER_TYPE_OFFSET 4
33 #define HEADER_CODE_MASK 0x0F
34 #define HEADER_CODE_OFFSET 0
35 
36 /* Mask and offset for first byte in compressed OSCORE option*/
37 #define COMP_OSCORE_OPT_KIDC_H_MASK 0x10
38 #define COMP_OSCORE_OPT_KIDC_H_OFFSET 4
39 #define COMP_OSCORE_OPT_KID_K_MASK 0x08
40 #define COMP_OSCORE_OPT_KID_K_OFFSET 3
41 #define COMP_OSCORE_OPT_PIV_N_MASK 0x07
42 #define COMP_OSCORE_OPT_PIV_N_OFFSET 0
43 
44 #define OSCORE_OPT_VALUE_LEN                                                   \
45 	(2 + MAX_PIV_LEN + MAX_KID_CONTEXT_LEN + MAX_KID_LEN)
46 
47 #define MAX_OPTION_COUNT 20
48 
49 
50 #define TYPE_CON			0x00
51 #define TYPE_NON			0x01
52 #define TYPE_ACK			0x02
53 #define TYPE_RST			0x03
54 
55 #define CODE_CLASS_MASK			0xe0
56 #define CODE_DETAIL_MASK		0x1f
57 #define CODE_EMPTY			0x00
58 #define CODE_REQ_POST			0x02
59 #define CODE_RESP_CHANGED		0x44
60 
61 #define REQUEST_CLASS 0
62 
63 /* all CoAP instances are preceeded with 'o_' to show correspondence to
64  * OSCORE and prevent conflicts with networking CoAP libraries
65  */
66 struct o_coap_header {
67 	uint8_t ver;
68 	uint8_t type;
69 	uint8_t TKL;
70 	uint8_t code;
71 	uint16_t MID;
72 };
73 
74 struct o_coap_option {
75 	uint16_t delta;
76 	uint8_t len;
77 	uint8_t *value;
78 	uint8_t option_number;
79 };
80 
81 struct oscore_option {
82 	uint16_t delta;
83 	uint8_t len;
84 	uint8_t *value;
85 	uint8_t buf[OSCORE_OPT_VALUE_LEN];
86 	uint8_t option_number;
87 };
88 
89 struct o_coap_packet {
90 	struct o_coap_header header;
91 	uint8_t *token;
92 	uint8_t options_cnt;
93 	struct o_coap_option options[MAX_OPTION_COUNT];
94 	uint32_t payload_len;
95 	uint8_t *payload;
96 };
97 
98 struct compressed_oscore_option {
99 	uint8_t h; /*flag bit for KID_context*/
100 	uint8_t k; /*flag bit for KID*/
101 	uint8_t n; /*bytes number of PIV*/
102 	struct byte_array piv; /*same as sender sequence number*/
103 	struct byte_array kid_context;
104 	struct byte_array kid;
105 };
106 
107 struct piv_kid_context {
108 	struct byte_array partial_iv;
109 	struct byte_array kid;
110 	struct byte_array kid_context;
111 };
112 
113 /**
114  * @brief   Covert a byte array to a OSCORE/CoAP struct
115  * @param   in: pointer input message packet, in byte string format
116  * @param   out: pointer to output OSCORE packet
117  * @return  err
118  */
119 enum err buf2coap(struct byte_array *in, struct o_coap_packet *out);
120 
121 /**
122  * @brief   Converts a CoAP/OSCORE packet to a byte string
123  * @param   in: input CoAP/OSCORE packet
124  * @param   out_byte_string: byte string containing the OSCORE packet
125  * @param   out_byte_string_len: length of the byte string
126  * @return  err
127  */
128 enum err coap2buf(struct o_coap_packet *in, uint8_t *out_byte_string,
129 		  uint32_t *out_byte_string_len);
130 
131 /**
132  * @brief   Convert input options into byte string
133  * @param   options: input pointer to an array of options
134  * @param   options_cnt: count number of input options
135  * @param   out_byte_string: output pointer to options byte string
136  * @return  err
137  *
138  */
139 enum err options_into_byte_string(struct o_coap_option *options,
140 				  uint8_t options_cnt,
141 				  struct byte_array *out_byte_string);
142 #endif
143