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 OSCORE_H
13 #define OSCORE_H
14 
15 #include <stdbool.h>
16 #include <stdint.h>
17 
18 #include "oscore/security_context.h"
19 #include "oscore/supported_algorithm.h"
20 #include "oscore/nvm.h"
21 
22 #include "common/byte_array.h"
23 #include "common/oscore_edhoc_error.h"
24 #include "common/print_util.h"
25 
26 /*
27  * When OSCORE is used with fixed keys, i.e., no re-keying with EDHOC
28  * after reboot the SSN needs to be stored at runtime in NVM and restored
29  * at OSCORE initialization. The flowing two values are used to adjust the
30  * storing interval on the SSN. Those values may need to be adjusted by
31  * the user, see Appendix B.1.1.
32  */
33 #ifndef K_SSN_NVM_STORE_INTERVAL
34 #define K_SSN_NVM_STORE_INTERVAL 10
35 #endif
36 
37 #ifndef F_NVM_MAX_WRITE_FAILURE
38 #define F_NVM_MAX_WRITE_FAILURE 10
39 #endif
40 
41 #ifndef OSCORE_MAX_PLAINTEXT_LEN
42 #define OSCORE_E_OPTIONS_LEN 40
43 #define OSCORE_COAP_PAYLOAD_LEN 1024
44 /* OSCORE plaintext includes CoAP frame with CoAP payload */
45 #define OSCORE_MAX_PLAINTEXT_LEN                                               \
46 	(OSCORE_COAP_PAYLOAD_LEN + OSCORE_E_OPTIONS_LEN)
47 #endif
48 
49 #define MAX_PLAINTEXT_LEN OSCORE_MAX_PLAINTEXT_LEN
50 #define MAX_CIPHERTEXT_LEN (MAX_PLAINTEXT_LEN + AUTH_TAG_LEN)
51 #ifndef E_OPTIONS_BUFF_MAX_LEN
52 #define E_OPTIONS_BUFF_MAX_LEN                                                 \
53 	255 /* Maximal length of buffer with all encrypted CoAP options. */
54 #endif
55 #ifndef I_OPTIONS_BUFF_MAX_LEN
56 #define I_OPTIONS_BUFF_MAX_LEN                                                 \
57 	255 /* Maximal length of buffer with all not encrypted CoAP options. */
58 #endif
59 #define MAX_COAP_OPTIONS_LEN                                                   \
60 	((E_OPTIONS_BUFF_MAX_LEN > I_OPTIONS_BUFF_MAX_LEN) ?                   \
61 		 E_OPTIONS_BUFF_MAX_LEN :                                      \
62 		 I_OPTIONS_BUFF_MAX_LEN)
63 
64 /**
65  * Each endpoint derives the parameters in the security context from a
66  * small set of input parameters.
67  */
68 struct oscore_init_params {
69 	/*master_secret must be provided. Currently 16 byte secrets are supported*/
70 	const struct byte_array master_secret;
71 	/*sender_id must be provided*/
72 	const struct byte_array sender_id;
73 	/*recipient_id must be provided*/
74 	const struct byte_array recipient_id;
75 
76 	/*The specification doesn't describe how the ID Context is created */
77 	/*When the user wants to use ID Context it has to provide it in the initialization of the client. The servers ID Context is transported in the oscore option*/
78 	struct byte_array id_context;
79 	/*master_salt is optional (default empty byte string)*/
80 	const struct byte_array master_salt;
81 	/*aead_alg is optional (default AES-CCM-16-64-128)*/
82 	const enum AEAD_algorithm aead_alg;
83 	/*kdf is optional (default HKDF-SHA-256)*/
84 	const enum hkdf hkdf;
85 	/*True if the combination of master secret and master salt are unique at every boot of the device, e.g., they are computed with EDHOC.
86 	If not, OSCORE_NVM_SUPPORT flag must be defined, for proper non-volatile memory management.*/
87 	const bool fresh_master_secret_salt;
88 };
89 
90 /**
91  * @brief Initialize security context of OSCORE, including common context,
92  * recipient context and sender context.
93  *
94  * @param 	params a struct containing the initialization parameters
95  * @param	context a struct containing the contexts
96  * @return  err
97  */
98 enum err oscore_context_init(struct oscore_init_params *params,
99 			     struct context *c);
100 
101 /**
102  * @brief  	Checks if the packet in buf_in is a OSCORE packet.
103  * 		If so it converts it to a CoAP packet and sets the oscore_pkg to
104  * 		true in order to indicate the caller function that a
105  * 		OSCORE packet was received.
106  *
107  * @param 	buf_in a buffer containing an incoming packet which can be
108  * 		OSCORE or CoAP packet.
109  * @param 	buf_in_len length of the data in the buf_in
110  * @param 	buf_out when a OSCORE packet is found and decrypted the
111  * 		resulting CoAP is saved in buf_out
112  * @param 	buf_out_len length of the CoAP packet
113  * @param	flag  indicates if the
114  * @param 	c pointer to a security context
115  * @param 	oscore_pkg indicates if an incoming packet is OSCORE
116  * @return	err
117  */
118 enum err oscore2coap(uint8_t *buf_in, uint32_t buf_in_len, uint8_t *buf_out,
119 		     uint32_t *buf_out_len, struct context *c);
120 
121 /**
122  *@brief 	Converts a CoAP packet to OSCORE packet
123  *
124  *@param	buf_o_coap a buffer containing a CoAP packet
125  *@param	buf_o_coap_len length of the CoAP buffer
126  *@param	buf_oscore a buffer where the OSCORE packet will be written
127  *@param	buf_oscore_len length of the OSCORE packet
128  *@param	c a struct containing the OSCORE context
129  *@return	err
130  */
131 enum err coap2oscore(uint8_t *buf_o_coap, uint32_t buf_o_coap_len,
132 		     uint8_t *buf_oscore, uint32_t *buf_oscore_len,
133 		     struct context *c);
134 
135 #endif
136