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