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 "oscore_coap_defines.h"
18 #include "common/byte_array.h"
19 #include "common/oscore_edhoc_error.h"
20 
21 #define MAX_TOKEN_LEN 8
22 #define MAX_PIV_LEN 5
23 #define MAX_KID_CONTEXT_LEN                                                    \
24 	8 /*This implementation supports Context IDs up to 8 byte*/
25 #define MAX_KID_LEN 8
26 #define MAX_AAD_LEN 30
27 #define MAX_INFO_LEN 50
28 #define MAX_SSN_VALUE                                                          \
29 	0xFFFFFFFFFF /* maximum SSN value is 2^40-1, according to RFC 8613 p. 7.2.1.*/
30 
31 /* Mask and offset for first byte in CoAP/OSCORE header*/
32 #define HEADER_LEN 4
33 #define HEADER_VERSION_MASK 0xC0
34 #define HEADER_VERSION_OFFSET 6
35 #define HEADER_TYPE_MASK 0x30
36 #define HEADER_TYPE_OFFSET 4
37 #define HEADER_TKL_MASK 0x0F
38 #define HEADER_TKL_OFFSET 0
39 
40 /* Mask and offset for first byte in compressed OSCORE option*/
41 #define COMP_OSCORE_OPT_KIDC_H_MASK 0x10
42 #define COMP_OSCORE_OPT_KIDC_H_OFFSET 4
43 #define COMP_OSCORE_OPT_KID_K_MASK 0x08
44 #define COMP_OSCORE_OPT_KID_K_OFFSET 3
45 #define COMP_OSCORE_OPT_PIV_N_MASK 0x07
46 #define COMP_OSCORE_OPT_PIV_N_OFFSET 0
47 
48 #define ECHO_OPT_VALUE_LEN 12 /*see RFC9175 Appendix A.2*/
49 #define OSCORE_OPT_VALUE_LEN                                                   \
50 	(2 + MAX_PIV_LEN + MAX_KID_CONTEXT_LEN + MAX_KID_LEN)
51 
52 #define TYPE_CON 0x00
53 #define TYPE_NON 0x01
54 #define TYPE_ACK 0x02
55 #define TYPE_RST 0x03
56 
57 #define CODE_CLASS_MASK 0xe0
58 #define CODE_DETAIL_MASK 0x1f
59 #define CODE_EMPTY 0x00
60 #define CODE_REQ_GET 0x01
61 #define CODE_REQ_POST 0x02
62 #define CODE_REQ_FETCH 0x05
63 #define CODE_RESP_CHANGED 0x44
64 #define CODE_RESP_CONTENT 0x45
65 #define CODE_RESP_UNAUTHORIZED 0x81
66 #define REQUEST_CLASS 0x00
67 
68 #define OPTION_PAYLOAD_MARKER 0xFF
69 
70 #define MAX_OPTION_COUNT 20
71 #define MAX_E_OPTION_COUNT 10
72 
73 /* all CoAP instances are preceeded with 'o_' to show correspondence to
74  * OSCORE and prevent conflicts with networking CoAP libraries
75  */
76 struct o_coap_header {
77 	uint8_t ver;
78 	uint8_t type;
79 	uint8_t TKL;
80 	uint8_t code;
81 	uint16_t MID;
82 };
83 
84 struct o_coap_option {
85 	uint16_t delta;
86 	uint16_t len;
87 	uint8_t *value;
88 	uint16_t option_number;
89 };
90 
91 struct oscore_option {
92 	uint16_t delta;
93 	uint8_t len;
94 	uint8_t *value;
95 	uint8_t buf[OSCORE_OPT_VALUE_LEN];
96 	uint16_t option_number;
97 };
98 
99 struct o_coap_packet {
100 	struct o_coap_header header;
101 	uint8_t *token;
102 	uint8_t options_cnt;
103 	struct o_coap_option options[MAX_OPTION_COUNT];
104 	struct byte_array payload;
105 };
106 
107 struct compressed_oscore_option {
108 	uint8_t h; /*flag bit for KID_context*/
109 	uint8_t k; /*flag bit for KID*/
110 	uint8_t n; /*bytes number of PIV*/
111 	struct byte_array piv; /*same as sender sequence number*/
112 	struct byte_array kid_context;
113 	struct byte_array kid;
114 };
115 
116 /**
117  * @brief   Covert a byte array to a OSCORE/CoAP struct
118  * @param   in: pointer to an input message packet, in byte string format
119  * @param   out: pointer to an output OSCORE packet
120  * @return  err
121  */
122 enum err coap_deserialize(struct byte_array *in, struct o_coap_packet *out);
123 
124 /**
125  * @brief   Converts a CoAP/OSCORE packet to a byte string
126  * @param   in: input CoAP/OSCORE packet
127  * @param   out_byte_string: byte string containing the OSCORE packet
128  * @param   out_byte_string_len: length of the byte string
129  * @return  err
130  */
131 enum err coap_serialize(struct o_coap_packet *in, uint8_t *out_byte_string,
132 			uint32_t *out_byte_string_len);
133 
134 /**
135  * @brief   Convert input options into byte string
136  * @param   options: input pointer to an array of options
137  * @param   options_cnt: count number of input options
138  * @param   out_byte_string: output pointer to options byte string
139  * @return  err
140  *
141  */
142 enum err options_serialize(struct o_coap_option *options, uint8_t options_cnt,
143 			   struct byte_array *out_byte_string);
144 
145 /**
146  * @brief Deserializes a byte string containing options and eventually a payload
147  * @param in_data: input data
148  * @param opt: pointer to output options structure array
149  * @param opt_cnt: count number of output options
150  * @param payload: payload
151  * @return  err
152  */
153 enum err options_deserialize(struct byte_array *in_data,
154 			     struct o_coap_option *opt, uint8_t *opt_cnt,
155 			     struct byte_array *payload);
156 
157 /**
158  * @brief	Checks if a packet is a request
159  * @param	packet: a pointer to a CoAP/OSCORE packet
160  * @retval	true if the packet is a request else false
161  */
162 bool is_request(struct o_coap_packet *packet);
163 
164 /**
165  * @brief	Returns the number of extra bytes needed wen encoding an option.
166  * @param	delta_or_len option delta or option len depending on the use case
167  * @retval	The needed extra bytes
168 */
169 uint8_t opt_extra_bytes(uint16_t delta_or_len);
170 
171 /**
172  * @brief Get the message type of given coap packet.
173  * @param coap_packet coap packet
174  * @param msg_type message type
175  * @return ok or error code
176  */
177 enum err coap_get_message_type(struct o_coap_packet *coap_packet,
178 			       enum o_coap_msg *msg_type);
179 
180 #endif
181