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 EDHOC_H
13 #define EDHOC_H
14 
15 #include <stdint.h>
16 
17 #include "edhoc/edhoc_method_type.h"
18 #include "edhoc/messages.h"
19 #include "edhoc/suites.h"
20 #include "edhoc/c_x.h"
21 
22 #include "common/oscore_edhoc_error.h"
23 #include "common/byte_array.h"
24 #include "common/print_util.h"
25 
26 /*define EDHOC_BUF_SIZES_RPK in order to use smaller buffers and save some RAM if need when RPKs are used*/
27 //#define EDHOC_BUF_SIZES_RPK
28 //#define EDHOC_BUF_SIZES_C509_CERT
29 #define EDHOC_BUF_SIZES_X509_CERT
30 
31 #if defined EDHOC_BUF_SIZES_RPK
32 #define MSG_1_DEFAULT_SIZE 64
33 #define MSG_2_DEFAULT_SIZE 128
34 #define MSG_3_DEFAULT_SIZE 100
35 #define MSG_4_DEFAULT_SIZE 100
36 #define CIPHERTEXT2_DEFAULT_SIZE 100
37 #define CIPHERTEXT3_DEFAULT_SIZE 100
38 #define A_2M_DEFAULT_SIZE 200
39 #define M_3_DEFAULT_SIZE 200
40 #define CRED_DEFAULT_SIZE 128
41 #define SGN_OR_MAC_DEFAULT_SIZE 128
42 #define ID_CRED_DEFAULT_SIZE 20
43 #define PRK_3AE_DEFAULT_SIZE 100
44 #define CERT_DEFAUT_SIZE 128
45 #define CONTEXT_MAC_DEFAULT_SIZE 200
46 #define INFO_DEFAULT_SIZE 250
47 #define SIGNATURE_STRUCT_DEFAULT_SIZE 300
48 #endif
49 
50 #if defined EDHOC_BUF_SIZES_C509_CERT
51 #define MSG_1_DEFAULT_SIZE 255
52 #define MSG_2_DEFAULT_SIZE 255
53 #define MSG_3_DEFAULT_SIZE 255
54 #define MSG_4_DEFAULT_SIZE 255
55 #define CIPHERTEXT2_DEFAULT_SIZE 255
56 #define CIPHERTEXT3_DEFAULT_SIZE 255
57 #define CIPHERTEXT4_DEFAULT_SIZE 255
58 #define A_2M_DEFAULT_SIZE 512
59 #define M_3_DEFAULT_SIZE 512
60 #define CRED_DEFAULT_SIZE 255
61 #define SGN_OR_MAC_DEFAULT_SIZE 128
62 #define ID_CRED_DEFAULT_SIZE 255
63 #define PLAINTEXT_DEFAULT_SIZE 255
64 #define CERT_DEFAUT_SIZE 255
65 #define CONTEXT_MAC_DEFAULT_SIZE 200
66 #define INFO_DEFAULT_SIZE 250
67 #define SIGNATURE_STRUCT_DEFAULT_SIZE 300
68 #endif
69 
70 #if defined EDHOC_BUF_SIZES_X509_CERT
71 #define MSG_1_DEFAULT_SIZE 255
72 #define MSG_2_DEFAULT_SIZE 700
73 #define MSG_3_DEFAULT_SIZE 700
74 #define MSG_4_DEFAULT_SIZE 700
75 #define PLAINTEXT_DEFAULT_SIZE 650
76 #define CIPHERTEXT2_DEFAULT_SIZE PLAINTEXT_DEFAULT_SIZE
77 #define CIPHERTEXT3_DEFAULT_SIZE PLAINTEXT_DEFAULT_SIZE
78 #define CIPHERTEXT4_DEFAULT_SIZE PLAINTEXT_DEFAULT_SIZE
79 #define A_2M_DEFAULT_SIZE 512
80 #define M_3_DEFAULT_SIZE 512
81 #define CRED_DEFAULT_SIZE 600
82 #define SGN_OR_MAC_DEFAULT_SIZE 128
83 #define ID_CRED_DEFAULT_SIZE 600
84 #define CERT_DEFAUT_SIZE 600
85 #define CONTEXT_MAC_DEFAULT_SIZE 1200
86 #define INFO_DEFAULT_SIZE 1200
87 #define SIGNATURE_STRUCT_DEFAULT_SIZE 1200
88 #endif
89 
90 #define ERR_MSG_DEFAULT_SIZE 64
91 #define P_256_PRIV_KEY_DEFAULT_SIZE 32
92 #define P_256_PUB_KEY_COMPRESSED_SIZE 33
93 #define P_256_PUB_KEY_UNCOMPRESSED_SIZE 65
94 #define PK_DEFAULT_SIZE P_256_PUB_KEY_UNCOMPRESSED_SIZE
95 #define C_R_DEFAULT_SIZE 1
96 #define C_I_DEFAULT_SIZE 8
97 #define G_Y_DEFAULT_SIZE P_256_PUB_KEY_COMPRESSED_SIZE
98 #define G_X_DEFAULT_SIZE P_256_PUB_KEY_COMPRESSED_SIZE
99 #define G_R_DEFAULT_SIZE P_256_PUB_KEY_UNCOMPRESSED_SIZE
100 #define G_I_DEFAULT_SIZE P_256_PUB_KEY_UNCOMPRESSED_SIZE
101 #define DATA_2_DEFAULT_SIZE                                                    \
102 	(C_I_DEFAULT_SIZE + G_Y_DEFAULT_SIZE + C_R_DEFAULT_SIZE)
103 #define TH2_INPUT_DEFAULT_SIZE (MSG_1_DEFAULT_SIZE + DATA_2_DEFAULT_SIZE)
104 #define TH3_INPUT_DEFAULT_SIZE (SHA_DEFAULT_SIZE + CIPHERTEXT3_DEFAULT_SIZE)
105 #define TH4_INPUT_DEFAULT_SIZE (SHA_DEFAULT_SIZE + CIPHERTEXT4_DEFAULT_SIZE)
106 #define ECDH_SECRET_DEFAULT_SIZE 32
107 #define DERIVED_SECRET_DEFAULT_SIZE 32
108 #define AD_DEFAULT_SIZE 256
109 #define PRK_DEFAULT_SIZE 32
110 #define ASSOCIATED_DATA_DEFAULT_SIZE 64
111 #define KID_DEFAULT_SIZE 8
112 #define SHA_DEFAULT_SIZE 32
113 #define AEAD_KEY_DEFAULT_SIZE 16
114 #define MAC_DEFAULT_SIZE 16
115 #define AEAD_IV_DEFAULT_SIZE 13
116 #define SIGNATURE_DEFAULT_SIZE 64
117 #define TH_ENC_DEFAULT_SIZE 42
118 #define ENCODING_OVERHEAD 6
119 
120 
121 
122 struct other_party_cred {
123 	struct byte_array id_cred; /*ID_CRED_x of the other party*/
124 	struct byte_array cred; /*CBOR encoded credentials*/
125 	struct byte_array pk; /*authentication pub key of the party */
126 	struct byte_array g; /*authentication static DH pub key of other party */
127 	struct byte_array ca; /*use only when authentication with certificates*/
128 	struct byte_array
129 		ca_pk; /*use only when authentication with certificates*/
130 };
131 
132 struct edhoc_responder_context {
133 	bool msg4; /*if true massage 4 will be send by the responder*/
134 	struct c_x c_r; /*connection identifier of the responder*/
135 	struct byte_array suites_r;
136 	struct byte_array g_y; /*ephemeral dh public key*/
137 	struct byte_array y; /*ephemeral dh secret key*/
138 
139 	struct byte_array g_r; /* static DH pk -> use only with method 1 or 3*/
140 	struct byte_array r; /* static DH sk -> use only with method 1 or 3*/
141 	struct byte_array ead_2;
142 	struct byte_array ead_4;
143 	struct byte_array id_cred_r;
144 	struct byte_array cred_r;
145 	struct byte_array sk_r; /*sign key -use with method 0 and 2*/
146 	struct byte_array pk_r; /*coresp. pk to sk_r -use with method 0 and 2*/
147 	void *sock; /*pointer used as handler for sockets by tx/rx */
148 };
149 
150 struct edhoc_initiator_context {
151 	bool msg4; /*if true massage 4 will be send by the responder*/
152 	struct c_x c_i; /*connection identifier of the initiator*/
153 	enum method_type method;
154 	//uint8_t corr;
155 	struct byte_array suites_i;
156 	struct byte_array ead_1;
157 	struct byte_array ead_3;
158 	struct byte_array id_cred_i;
159 	struct byte_array cred_i;
160 	struct byte_array g_x; /*ephemeral dh public key*/
161 	struct byte_array x; /*ephemeral dh secret key*/
162 	struct byte_array g_i; /* static DH pk -> use only with method 2 or 3*/
163 	struct byte_array i; /* static DH sk -> use only with method 2 or 3*/
164 	struct byte_array sk_i; /*sign key use with method 0 and 2*/
165 	struct byte_array pk_i; /*coresp. pk to sk_r -use with method 0 and 2*/
166 	void *sock; /*pointer used as handler for sockets by tx/rx */
167 };
168 
169 /**
170  * @brief   Generates public and private ephemeral DH keys from a random seed.
171  *
172  *          IMPORTANT!!! PROVIDE A GOOD RANDOM SEED!
173  *
174  * @param   curve DH curve to used
175  * @param   seed a random seed
176  * @param   sk pointer to a buffer where the secret key will be strored
177  * @param   pk pointer to a buffer where the public key will be strored
178  * @param   pk_size pointer to a variable with public key buffer size as input,
179  *          and public key length as output.
180 
181  */
182 enum err __attribute__((weak))
183 ephemeral_dh_key_gen(
184 	enum ecdh_alg alg, uint32_t seed, uint8_t *sk,
185 	uint8_t *pk, uint32_t *pk_size);
186 
187 /**
188  * @brief   Executes the EDHOC protocol on the initiator side
189  * @param   c cointer to a structure containing initialization parameters
190  * @param   cred_r_array containing elements of type other_party_cred used for
191  *          the retrival of the other party (the responder) parameters at run
192  *          time
193  * @param   num_cred_r number of the elements in cred_r_array
194  * @param   err_msg in case that an error message is received its contend is
195  *          provided to the caller though the err_msg
196  * @param   ead_2 the received in msg2 additional data is provided to the
197  *          caller through ead_2
198  * @param   ead_2_len length of ead_2
199  * @param   prk_4x3m used in the exporter interface
200  * @param   prk_4x3m_len length of prk_4x3m
201  * @param   th4 transcript hash4 used in the exporter interface
202  * @param   th4_len length of th4
203  */
204 enum err edhoc_initiator_run(
205 	const struct edhoc_initiator_context *c,
206 	struct other_party_cred *cred_r_array, uint16_t num_cred_r,
207 	uint8_t *err_msg, uint32_t *err_msg_len, uint8_t *ead_2,
208 	uint32_t *ead_2_len, uint8_t *ead_4, uint32_t *ead_4_len,
209 	uint8_t *prk_4x3m, uint32_t prk_4x3m_len, uint8_t *th4,
210 	uint32_t th4_len,
211 	enum err (*tx)(void *sock, uint8_t *data, uint32_t data_len),
212 	enum err (*rx)(void *sock, uint8_t *data, uint32_t *data_len));
213 
214 /**
215  * @brief   Executes the EDHOC protocol on the responder side
216  * @param   c cointer to a structure containing initialization parameters
217  * @param   cred_i_array containing elements of type other_party_cred used for
218  *          the retrival of the other party (the initiator) parameters at run
219  *          time
220  * @param   num_cred_i number of the elements in cred_i_array
221  * @param   err_msg in case that an error message is received its contend is
222  *          provided to the caller though the err_msg
223  * @param   ead_1 the received in msg1 additional data is provided to the caller
224  *          through ead_1
225  * @param   ead_1_len length of ead_1
226  * @param   ead_3 the received in msg3 additional data is provided to the caller
227  *          through ead_3
228  * @param   ead_3_len length of ead_3
229  * @param   prk_4x3m used in the exporter interface
230  * @param   prk_4x3m_len length of prk_4x3m
231  * @param   th4 transcript hash4 used in the exporter interface
232  * @param   th4_len length of th4
233  */
234 enum err edhoc_responder_run(
235 	struct edhoc_responder_context *c,
236 	struct other_party_cred *cred_i_array, uint16_t num_cred_i,
237 	uint8_t *err_msg, uint32_t *err_msg_len, uint8_t *ead_1,
238 	uint32_t *ead_1_len, uint8_t *ead_3, uint32_t *ead_3_len,
239 	uint8_t *prk_4x3m, uint32_t prk_4x3m_len, uint8_t *th4,
240 	uint32_t th4_len,
241 	enum err (*tx)(void *sock, uint8_t *data, uint32_t data_len),
242 	enum err (*rx)(void *sock, uint8_t *data, uint32_t *data_len));
243 
244 /**
245  * @brief   used to create application specific symmetric keys using the
246  *          calculated in edhoc_initiator_run()/edhoc_responder_run() prk_4x3m
247  *          and th4
248  * @param   app_hash_alg hash algorithm to be used in the derivation
249  * @param   app_aead_alg AEAD algorithm to be used in the derivation
250  * @param   prk_4x3m derived key
251  * @param   prk_4x3m_len length of prk_4x3m
252  * @param   th4 transcripthash see edhoc_initiator_run()/edhoc_responder_run()
253  * @param   th4_len length of th4
254  * @param   label a human readble string idicating the key purpose
255  * @param   out container for the derivide key
256  * @param   out_len length of the derived key
257  */
258 enum err edhoc_exporter(enum hash_alg app_hash_alg, const uint8_t *prk_4x3m,
259 			uint32_t prk_4x3m_len, const uint8_t *th4,
260 			uint32_t th4_len, const char *label, uint8_t *out,
261 			uint32_t out_len);
262 #endif
263