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 };
58 
59 /* Sender Context used for encrypting outbound messages */
60 struct sender_context {
61 	struct byte_array sender_id;
62 	uint8_t sender_id_buf[7];
63 	struct byte_array sender_key;
64 	uint8_t sender_key_buf[SENDER_KEY_LEN_];
65 	uint64_t ssn;
66 };
67 
68 /* Recipient Context used to decrypt inbound messages */
69 struct recipient_context {
70 	struct byte_array recipient_id;
71 	struct byte_array recipient_key;
72 	uint8_t recipient_key_buf[RECIPIENT_KEY_LEN_];
73 	uint8_t recipient_id_buf[RECIPIENT_ID_BUFF_LEN];
74 	struct server_replay_window_t replay_window;
75 	uint64_t notification_num;
76 	bool notification_num_initialized; /* this is only used to skip the first notification check after the reboot */
77 };
78 
79 /*request-response context contains parameters that need to persists between
80  * requests and responses*/
81 struct req_resp_context {
82 	struct byte_array nonce;
83 	uint8_t nonce_buf[NONCE_LEN];
84 
85 	struct oscore_interaction_t interactions[OSCORE_INTERACTIONS_COUNT];
86 
87 	struct byte_array echo_opt_val;
88 	uint8_t echo_opt_val_buf[ECHO_OPT_VALUE_LEN];
89 
90 	enum echo_state echo_state_machine;
91 };
92 
93 /* Context struct containing all contexts*/
94 struct context {
95 	struct req_resp_context rrc;
96 	struct common_context cc;
97 	struct sender_context sc;
98 	struct recipient_context rc;
99 };
100 
101 /**
102  * @brief   Converts the sender sequence number (uint64_t) to
103  *          piv (byte string of maximum 5 byte)
104  * @param   ssn the sender sequence number
105  * @param   piv Partial IV
106  */
107 enum err ssn2piv(uint64_t ssn, struct byte_array *piv);
108 
109 /**
110  * @brief Converts PIV (byte string of maximum 5 bytes) to
111  *        Sender Sequence Number (uint64_t)
112  * @param piv Partial IV
113  * @param ssn Sender Sequence Number
114  */
115 enum err piv2ssn(struct byte_array *piv, uint64_t *ssn);
116 
117 /**
118  * @brief Check if given security context is still safe to be used, or a new one must be established.
119  *        For more info, refer to RFC 8613 p. 7.2.1.
120  * @param c security context.
121  * @return enum err
122  */
123 enum err check_context_freshness(struct context *c);
124 
125 #endif
126