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/hkdf_info.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_MAX_SIZE 100 33 #define CIPHERTEXT2_DEFAULT_SIZE 100 34 #define CIPHERTEXT3_DEFAULT_SIZE 100 35 #define A_2M_DEFAULT_SIZE 200 36 #define M_3_DEFAULT_SIZE 200 37 #define CRED_DEFAULT_SIZE 128 38 #define SGN_OR_MAC_DEFAULT_SIZE 128 39 #define ID_CRED_DEFAULT_SIZE 20 40 #define PRK_3AE_DEFAULT_SIZE 100 41 #define CERT_DEFAUT_SIZE 128 42 #define CONTEXT_MAC_DEFAULT_SIZE 200 43 #define INFO_DEFAULT_SIZE 250 44 #define SIGNATURE_STRUCT_DEFAULT_SIZE 300 45 #endif 46 47 #if defined EDHOC_BUF_SIZES_C509_CERT 48 #define MSG_MAX_SIZE 255 49 #define CIPHERTEXT2_DEFAULT_SIZE 255 50 #define CIPHERTEXT3_DEFAULT_SIZE 255 51 #define CIPHERTEXT4_DEFAULT_SIZE 255 52 #define A_2M_DEFAULT_SIZE 512 53 #define M_3_DEFAULT_SIZE 512 54 #define CRED_DEFAULT_SIZE 255 55 #define SGN_OR_MAC_DEFAULT_SIZE 128 56 #define ID_CRED_DEFAULT_SIZE 255 57 #define PLAINTEXT_DEFAULT_SIZE 255 58 #define CERT_DEFAUT_SIZE 255 59 #define CONTEXT_MAC_DEFAULT_SIZE 200 60 #define INFO_DEFAULT_SIZE 250 61 #define SIGNATURE_STRUCT_DEFAULT_SIZE 300 62 #endif 63 64 #if defined EDHOC_BUF_SIZES_X509_CERT 65 #define MSG_MAX_SIZE 700 66 #define PLAINTEXT_DEFAULT_SIZE 1580 67 #define CIPHERTEXT2_DEFAULT_SIZE PLAINTEXT_DEFAULT_SIZE 68 #define CIPHERTEXT3_DEFAULT_SIZE PLAINTEXT_DEFAULT_SIZE 69 #define CIPHERTEXT4_DEFAULT_SIZE PLAINTEXT_DEFAULT_SIZE 70 #define A_2M_DEFAULT_SIZE 512 71 #define M_3_DEFAULT_SIZE 512 72 #define CRED_DEFAULT_SIZE 600 73 #define SGN_OR_MAC_DEFAULT_SIZE 128 74 #define ID_CRED_DEFAULT_SIZE 600 75 #define CERT_DEFAULT_SIZE 600 76 #define CONTEXT_MAC_DEFAULT_SIZE 1580 77 #define INFO_DEFAULT_SIZE 1580 78 #define SIGNATURE_STRUCT_DEFAULT_SIZE 1580 79 #endif 80 81 #define SUITES_MAX 5 82 #define ERR_MSG_DEFAULT_SIZE 64 83 #define P_256_PRIV_KEY_DEFAULT_SIZE 32 84 #define P_256_PUB_KEY_COMPRESSED_SIZE 33 85 #define P_256_PUB_KEY_UNCOMPRESSED_SIZE 65 86 #define P_256_PUB_KEY_X_CORD_SIZE 32 87 #define PK_DEFAULT_SIZE P_256_PUB_KEY_UNCOMPRESSED_SIZE 88 #define C_R_DEFAULT_SIZE 16 89 #define C_I_DEFAULT_SIZE 16 90 #define G_Y_DEFAULT_SIZE P_256_PUB_KEY_X_CORD_SIZE 91 #define G_X_DEFAULT_SIZE P_256_PUB_KEY_X_CORD_SIZE 92 #define G_R_DEFAULT_SIZE P_256_PUB_KEY_UNCOMPRESSED_SIZE 93 #define G_I_DEFAULT_SIZE P_256_PUB_KEY_UNCOMPRESSED_SIZE 94 #define DATA_2_DEFAULT_SIZE \ 95 (C_I_DEFAULT_SIZE + G_Y_DEFAULT_SIZE + C_R_DEFAULT_SIZE) 96 #define TH2_INPUT_DEFAULT_SIZE \ 97 (G_Y_DEFAULT_SIZE + C_R_DEFAULT_SIZE + HASH_DEFAULT_SIZE) 98 #define TH34_INPUT_DEFAULT_SIZE \ 99 (HASH_DEFAULT_SIZE + PLAINTEXT_DEFAULT_SIZE + CRED_DEFAULT_SIZE) 100 #define ECDH_SECRET_DEFAULT_SIZE 32 101 #define DERIVED_SECRET_DEFAULT_SIZE 32 102 #define AD_DEFAULT_SIZE 256 103 #define PRK_DEFAULT_SIZE 32 104 #define ASSOCIATED_DATA_DEFAULT_SIZE 64 105 #define KID_DEFAULT_SIZE 8 106 #define HASH_DEFAULT_SIZE 32 107 #define AEAD_KEY_DEFAULT_SIZE 16 108 #define MAC_DEFAULT_SIZE 16 109 #define AEAD_IV_DEFAULT_SIZE 13 110 #define SIGNATURE_DEFAULT_SIZE 64 111 #define TH_ENC_DEFAULT_SIZE 42 112 #define ENCODING_OVERHEAD 6 113 114 #ifdef _WIN32 115 #define WEAK 116 #else 117 #define WEAK __attribute__((weak)) 118 #endif 119 120 struct other_party_cred { 121 struct byte_array id_cred; /*ID_CRED_x of the other party*/ 122 struct byte_array cred; /*CBOR encoded credentials*/ 123 struct byte_array pk; /*authentication pub key of the other party */ 124 struct byte_array g; /*authentication static DH pub key of other party */ 125 struct byte_array ca; /*use only when authentication with certificates*/ 126 struct byte_array 127 ca_pk; /*use only when authentication with certificates*/ 128 }; 129 130 struct edhoc_responder_context { 131 bool msg4; /*if true massage 4 will be send by the responder*/ 132 struct byte_array c_r; /*connection identifier of the responder*/ 133 struct byte_array suites_r; 134 struct byte_array g_y; /*ephemeral dh public key*/ 135 struct byte_array y; /*ephemeral dh secret key*/ 136 137 struct byte_array g_r; /* static DH pk -> use only with method 1 or 3*/ 138 struct byte_array r; /* static DH sk -> use only with method 1 or 3*/ 139 struct byte_array ead_2; 140 struct byte_array ead_4; 141 struct byte_array id_cred_r; 142 struct byte_array cred_r; 143 struct byte_array sk_r; /*sign key -use with method 0 and 2*/ 144 struct byte_array pk_r; /*coresp. pk to sk_r -use with method 0 and 2*/ 145 void *sock; /*pointer used as handler for sockets by tx/rx */ 146 }; 147 148 struct edhoc_initiator_context { 149 bool msg4; /*if true massage 4 will be send by the responder*/ 150 struct byte_array c_i; /*connection identifier of the initiator*/ 151 enum method_type method; 152 //uint8_t corr; 153 struct byte_array suites_i; 154 struct byte_array ead_1; 155 struct byte_array ead_3; 156 struct byte_array id_cred_i; 157 struct byte_array cred_i; 158 struct byte_array g_x; /*ephemeral dh public key*/ 159 struct byte_array x; /*ephemeral dh secret key*/ 160 struct byte_array g_i; /* static DH pk -> use only with method 2 or 3*/ 161 struct byte_array i; /* static DH sk -> use only with method 2 or 3*/ 162 struct byte_array sk_i; /*sign key use with method 0 and 2*/ 163 struct byte_array pk_i; /*coresp. pk to sk_r -use with method 0 and 2*/ 164 void *sock; /*pointer used as handler for sockets by tx/rx */ 165 }; 166 167 /** 168 * @brief Generates public and private ephemeral DH keys from a random seed. 169 * 170 * IMPORTANT!!! PROVIDE A GOOD RANDOM SEED! 171 * 172 * @param curve DH curve to used 173 * @param seed a random seed 174 * @param sk pointer to a buffer where the secret key will be strored 175 * @param pk pointer to a buffer where the public key will be strored 176 * @param pk_size pointer to a variable with public key buffer size as input, 177 * and public key length as output. 178 179 */ 180 enum err WEAK ephemeral_dh_key_gen(enum ecdh_alg alg, uint32_t seed, 181 uint8_t *sk, uint8_t *pk, uint32_t *pk_size); 182 183 /** 184 * @brief Executes the EDHOC protocol on the initiator side 185 * @param c cointer to a structure containing initialization parameters 186 * @param cred_r_array containing elements of type other_party_cred used for 187 * the retrival of the other party (the responder) parameters at run 188 * time 189 * @param num_cred_r number of the elements in cred_r_array 190 * @param err_msg in case that an error message is received its contend is 191 * provided to the caller though the err_msg 192 * @param ead_2 the received in msg2 additional data is provided to the 193 * caller through ead_2 194 * @param ead_2_len length of ead_2 195 * @param prk_out the derived shared secret 196 * @param prk_out_len length of prk_out 197 */ 198 enum err edhoc_initiator_run( 199 const struct edhoc_initiator_context *c, 200 struct other_party_cred *cred_r_array, uint16_t num_cred_r, 201 uint8_t *err_msg, uint32_t *err_msg_len, uint8_t *ead_2, 202 uint32_t *ead_2_len, uint8_t *ead_4, uint32_t *ead_4_len, 203 uint8_t *prk_out, uint32_t prk_out_len, 204 enum err (*tx)(void *sock, uint8_t *data, uint32_t data_len), 205 enum err (*rx)(void *sock, uint8_t *data, uint32_t *data_len)); 206 207 /** 208 * @brief Executes the EDHOC protocol on the initiator side 209 * @param c cointer to a structure containing initialization parameters 210 * @param cred_r_array containing elements of type other_party_cred used for 211 * the retrival of the other party (the responder) parameters at run 212 * time 213 * @param num_cred_r number of the elements in cred_r_array 214 * @param err_msg in case that an error message is received its contend is 215 * provided to the caller though the err_msg 216 * @param ead_2 the received in msg2 additional data is provided to the 217 * caller through ead_2 218 * @param ead_2_len length of ead_2 219 * @param c_r_bytes connection identifier 220 * @param c_r_bytes_len length of c_i_bytes 221 * @param prk_out the derived shared secret 222 * @param prk_out_len length of prk_out 223 */ 224 enum err edhoc_initiator_run_extended( 225 const struct edhoc_initiator_context *c, 226 struct other_party_cred *cred_r_array, uint16_t num_cred_r, 227 uint8_t *err_msg, uint32_t *err_msg_len, uint8_t *ead_2, 228 uint32_t *ead_2_len, uint8_t *ead_4, uint32_t *ead_4_len, 229 uint8_t *c_r_bytes, uint32_t *c_r_bytes_len, uint8_t *prk_out, 230 uint32_t prk_out_len, 231 enum err (*tx)(void *sock, uint8_t *data, uint32_t data_len), 232 enum err (*rx)(void *sock, uint8_t *data, uint32_t *data_len)); 233 234 /** 235 * @brief Executes the EDHOC protocol on the responder side 236 * @param c cointer to a structure containing initialization parameters 237 * @param cred_i_array containing elements of type other_party_cred used for 238 * the retrival of the other party (the initiator) parameters at run 239 * time 240 * @param num_cred_i number of the elements in cred_i_array 241 * @param err_msg in case that an error message is received its contend is 242 * provided to the caller though the err_msg 243 * @param ead_1 the received in msg1 additional data is provided to the caller 244 * through ead_1 245 * @param ead_1_len length of ead_1 246 * @param ead_3 the received in msg3 additional data is provided to the caller 247 * through ead_3 248 * @param ead_3_len length of ead_3 249 * @param prk_out the derived shared secret 250 * @param prk_out_len length of prk_out 251 */ 252 enum err edhoc_responder_run( 253 struct edhoc_responder_context *c, 254 struct other_party_cred *cred_i_array, uint16_t num_cred_i, 255 uint8_t *err_msg, uint32_t *err_msg_len, uint8_t *ead_1, 256 uint32_t *ead_1_len, uint8_t *ead_3, uint32_t *ead_3_len, 257 uint8_t *prk_out, uint32_t prk_out_len, 258 enum err (*tx)(void *sock, uint8_t *data, uint32_t data_len), 259 enum err (*rx)(void *sock, uint8_t *data, uint32_t *data_len)); 260 261 /** 262 * @brief Executes the EDHOC protocol on the responder side 263 * @param c cointer to a structure containing initialization parameters 264 * @param cred_i_array containing elements of type other_party_cred used for 265 * the retrival of the other party (the initiator) parameters at run 266 * time 267 * @param num_cred_i number of the elements in cred_i_array 268 * @param err_msg in case that an error message is received its contend is 269 * provided to the caller though the err_msg 270 * @param ead_1 the received in msg1 additional data is provided to the caller 271 * through ead_1 272 * @param ead_1_len length of ead_1 273 * @param ead_3 the received in msg3 additional data is provided to the caller 274 * through ead_3 275 * @param ead_3_len length of ead_3 276 * @param prk_out the derived shared secret 277 * @param prk_out_len length of prk_out 278 * @param client_pub_key public key of the initiator 279 * @param client_pub_key_size length of client_pub_key 280 * @param c_i_bytes connection identifier 281 * @param c_i_bytes_len length of c_i_bytes 282 */ 283 enum err edhoc_responder_run_extended( 284 struct edhoc_responder_context *c, 285 struct other_party_cred *cred_i_array, uint16_t num_cred_i, 286 uint8_t *err_msg, uint32_t *err_msg_len, uint8_t *ead_1, 287 uint32_t *ead_1_len, uint8_t *ead_3, uint32_t *ead_3_len, 288 uint8_t *prk_out, uint32_t prk_out_len, uint8_t *client_pub_key, 289 uint32_t *client_pub_key_size, uint8_t *c_i_bytes, 290 uint32_t *c_i_bytes_len, 291 enum err (*tx)(void *sock, uint8_t *data, uint32_t data_len), 292 enum err (*rx)(void *sock, uint8_t *data, uint32_t *data_len)); 293 294 /** 295 * @brief Computes PRK_exporter from PRK_out 296 * 297 * @param app_hash_alg the EDHOC hash algorithm 298 * @param prk_out the product of a successful EDHOC execution 299 * @param prk_out_len length of prk_out 300 * @param prk_exporter pointer where the prk_exporter value will be written 301 * @return enum err 0 or error code 302 */ 303 enum err prk_out2exporter(enum hash_alg app_hash_alg, uint8_t *prk_out, 304 uint32_t prk_out_len, uint8_t *prk_exporter); 305 306 /** 307 * @brief Updates PRK_out 308 * 309 * @param app_hash_alg the EDHOC hash algorithm 310 * @param prk_out the product of a successful EDHOC execution 311 * @param prk_out_len length of prk_out 312 * @param context A context on which initiator and responder needs to 313 * agree in front 314 * @param context_len length of context 315 * @param prk_out_new pointer where the prk_out_new value will be written 316 * @return enum err 0 or error code 317 */ 318 enum err prk_out_update(enum hash_alg app_hash_alg, uint8_t *prk_out, 319 uint32_t prk_out_len, uint8_t *context, 320 uint32_t context_len, uint8_t *prk_out_new); 321 322 enum export_label { 323 OSCORE_MASTER_SECRET = 0, 324 OSCORE_MASTER_SALT = 1, 325 }; 326 327 /** 328 * @brief Computes key material to be used within the application, 329 * e.g., OSCORE master secret or OSCORE master salt 330 * 331 * @param app_hash_alg the application hash algorithm 332 * @param label an uint value defined by the application 333 * @param prk_exporter PRK computed with prk_out2exporter() 334 * @param prk_exporter_len length of prk_exporter 335 * @param out the result of the computation, 336 * e.g., OSCORE master secret or OSCORE master salt 337 * @param out_len length of out 338 * @return enum err 0 or error code 339 */ 340 enum err edhoc_exporter(enum hash_alg app_hash_alg, enum export_label label, 341 uint8_t *prk_exporter, uint32_t prk_exporter_len, 342 uint8_t *out, uint32_t out_len); 343 344 #endif 345