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 SECURITY_CONTEXT_H
13 #define SECURITY_CONTEXT_H
14 
15 #include "supported_algorithm.h"
16 #include "oscore_coap.h"
17 #include "oscore/replay_protection.h"
18 #include "oscore/oscore_interactions.h"
19 
20 #include "common/byte_array.h"
21 #include "common/oscore_edhoc_error.h"
22 
23 /* Upper limit of SSN that is allowed by AEAD algorithm (AES-CCM-16-64-128) is 2^23-1, according to RFC 9053 p. 4.2.1.
24    Exceeding this value results in constant 4.01 Unauthorized error, so new security context must be established.
25    Note that this value is lower than MAX_PIV_FIELD_VALUE, which only defines maximum value that is writable to the SSN/PIV field.
26 */
27 #ifndef OSCORE_SSN_OVERFLOW_VALUE
28 #define OSCORE_SSN_OVERFLOW_VALUE 0x7FFFFF
29 #endif
30 
31 enum derive_type {
32 	KEY,
33 	IV,
34 };
35 
36 /**
37  * @brief State machine for replay window synchronization using ECHO option after server reboot.
38  */
39 enum echo_state {
40 	ECHO_REBOOT, /* default value after reboot */
41 	ECHO_VERIFY, /* verification in progress */
42 	ECHO_SYNCHRONIZED, /* synchronized, normal operation */
43 };
44 
45 /**
46  * @brief Common Context
47  * Contains information common to the Sender and Recipient Contexts
48  */
49 struct common_context {
50 	enum AEAD_algorithm aead_alg;
51 	enum hkdf kdf;
52 	struct byte_array master_secret;
53 	struct byte_array master_salt; /*optional*/
54 	struct byte_array id_context; /*optional*/
55 	struct byte_array common_iv;
56 	uint8_t common_iv_buf[COMMON_IV_LEN];
57         bool fresh_master_secret_salt;
58 };
59 
60 /* Sender Context used for encrypting outbound messages */
61 struct sender_context {
62 	struct byte_array sender_id;
63 	uint8_t sender_id_buf[7];
64 	struct byte_array sender_key;
65 	uint8_t sender_key_buf[SENDER_KEY_LEN_];
66 	uint64_t ssn;
67 };
68 
69 /* Recipient Context used to decrypt inbound messages */
70 struct recipient_context {
71 	struct byte_array recipient_id;
72 	struct byte_array recipient_key;
73 	uint8_t recipient_key_buf[RECIPIENT_KEY_LEN_];
74 	uint8_t recipient_id_buf[RECIPIENT_ID_BUFF_LEN];
75 	struct server_replay_window_t replay_window;
76 	uint64_t notification_num;
77 	bool notification_num_initialized; /* this is only used to skip the first notification check after the reboot */
78 };
79 
80 /*request-response context contains parameters that need to persists between
81  * requests and responses*/
82 struct req_resp_context {
83 	struct byte_array nonce;
84 	uint8_t nonce_buf[NONCE_LEN];
85 
86 	struct oscore_interaction_t interactions[OSCORE_INTERACTIONS_COUNT];
87 
88 	struct byte_array echo_opt_val;
89 	uint8_t echo_opt_val_buf[ECHO_OPT_VALUE_LEN];
90 
91 	enum echo_state echo_state_machine;
92 };
93 
94 /* Context struct containing all contexts*/
95 struct context {
96 	struct req_resp_context rrc;
97 	struct common_context cc;
98 	struct sender_context sc;
99 	struct recipient_context rc;
100 };
101 
102 /**
103  * @brief   Converts the sender sequence number (uint64_t) to
104  *          piv (byte string of maximum 5 byte)
105  * @param   ssn the sender sequence number
106  * @param   piv Partial IV
107  */
108 enum err ssn2piv(uint64_t ssn, struct byte_array *piv);
109 
110 /**
111  * @brief Converts PIV (byte string of maximum 5 bytes) to
112  *        Sender Sequence Number (uint64_t)
113  * @param piv Partial IV
114  * @param ssn Sender Sequence Number
115  */
116 enum err piv2ssn(struct byte_array *piv, uint64_t *ssn);
117 
118 /**
119  * @brief	Updates the request_piv and the request_kid
120  * @param	c the context
121  * @param	piv	the new PIV
122  * @param 	kid the new KID
123  * @retval 	error code
124 */
125 enum err update_request_piv_request_kid(struct context *c,
126 					struct byte_array *piv,
127 					struct byte_array *kid);
128 
129 /**
130  * @brief Check if given security context is still safe to be used, or a new one must be established.
131  *        For more info, refer to RFC 8613 p. 7.2.1.
132  * @param c security context.
133  * @return enum err
134  */
135 enum err check_context_freshness(struct context *c);
136 #endif
137