1 /** 2 * Copyright Notice: 3 * Copyright 2021-2022 DMTF. All rights reserved. 4 * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md 5 **/ 6 7 #ifndef SPDM_SECURED_MESSAGE_LIB_INTERNAL_H 8 #define SPDM_SECURED_MESSAGE_LIB_INTERNAL_H 9 10 #include "library/spdm_secured_message_lib.h" 11 #include "library/spdm_crypt_lib.h" 12 #include "internal/libspdm_common_lib.h" 13 #include "hal/library/memlib.h" 14 #include "hal/library/cryptlib.h" 15 16 typedef struct { 17 uint8_t dhe_secret[LIBSPDM_MAX_DHE_KEY_SIZE]; 18 uint8_t handshake_secret[LIBSPDM_MAX_HASH_SIZE]; 19 uint8_t master_secret[LIBSPDM_MAX_HASH_SIZE]; 20 } libspdm_session_info_struct_master_secret_t; 21 22 typedef struct { 23 uint8_t request_handshake_secret[LIBSPDM_MAX_HASH_SIZE]; 24 uint8_t response_handshake_secret[LIBSPDM_MAX_HASH_SIZE]; 25 uint8_t request_finished_key[LIBSPDM_MAX_HASH_SIZE]; 26 uint8_t response_finished_key[LIBSPDM_MAX_HASH_SIZE]; 27 uint8_t request_handshake_encryption_key[LIBSPDM_MAX_AEAD_KEY_SIZE]; 28 uint8_t request_handshake_salt[LIBSPDM_MAX_AEAD_IV_SIZE]; 29 uint64_t request_handshake_sequence_number; 30 uint8_t response_handshake_encryption_key[LIBSPDM_MAX_AEAD_KEY_SIZE]; 31 uint8_t response_handshake_salt[LIBSPDM_MAX_AEAD_IV_SIZE]; 32 uint64_t response_handshake_sequence_number; 33 } libspdm_session_info_struct_handshake_secret_t; 34 35 typedef struct { 36 uint8_t request_data_secret[LIBSPDM_MAX_HASH_SIZE]; 37 uint8_t response_data_secret[LIBSPDM_MAX_HASH_SIZE]; 38 uint8_t request_data_encryption_key[LIBSPDM_MAX_AEAD_KEY_SIZE]; 39 uint8_t request_data_salt[LIBSPDM_MAX_AEAD_IV_SIZE]; 40 uint64_t request_data_sequence_number; 41 uint8_t response_data_encryption_key[LIBSPDM_MAX_AEAD_KEY_SIZE]; 42 uint8_t response_data_salt[LIBSPDM_MAX_AEAD_IV_SIZE]; 43 uint64_t response_data_sequence_number; 44 } libspdm_session_info_struct_application_secret_t; 45 46 typedef struct { 47 libspdm_session_type_t session_type; 48 spdm_version_number_t version; 49 spdm_version_number_t secured_message_version; 50 uint32_t base_hash_algo; 51 uint16_t dhe_named_group; 52 uint16_t aead_cipher_suite; 53 uint16_t key_schedule; 54 size_t hash_size; 55 size_t dhe_key_size; 56 size_t aead_key_size; 57 size_t aead_iv_size; 58 size_t aead_tag_size; 59 uint64_t max_spdm_session_sequence_number; 60 bool use_psk; 61 libspdm_session_state_t session_state; 62 libspdm_session_info_struct_master_secret_t master_secret; 63 libspdm_session_info_struct_handshake_secret_t handshake_secret; 64 libspdm_session_info_struct_application_secret_t application_secret; 65 libspdm_session_info_struct_application_secret_t application_secret_backup; 66 bool requester_backup_valid; 67 bool responder_backup_valid; 68 size_t psk_hint_size; 69 uint8_t psk_hint[LIBSPDM_PSK_MAX_HINT_LENGTH]; 70 uint8_t export_master_secret[LIBSPDM_MAX_HASH_SIZE]; 71 uint8_t sequence_number_endian; 72 73 /* Cache the error in libspdm_decode_secured_message. 74 * It is handled in libspdm_build_response. */ 75 libspdm_error_struct_t last_spdm_error; 76 } libspdm_secured_message_context_t; 77 78 #define LIBSPDM_SECURED_MESSAGE_CONTEXT_SIZE (sizeof(libspdm_secured_message_context_t)) 79 80 /** 81 * Initialize an SPDM secured message context. 82 * 83 * The size in bytes of the spdm_secured_message_context can be returned by libspdm_secured_message_get_context_size. 84 * 85 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 86 */ 87 void libspdm_secured_message_init_context(void *spdm_secured_message_context); 88 89 /** 90 * Set use_psk to an SPDM secured message context. 91 * 92 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 93 * @param use_psk Indicate if the SPDM session use PSK. 94 */ 95 void libspdm_secured_message_set_use_psk(void *spdm_secured_message_context, bool use_psk); 96 97 /** 98 * Set session_state to an SPDM secured message context. 99 * 100 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 101 * @param session_state Indicate the SPDM session state. 102 */ 103 void libspdm_secured_message_set_session_state( 104 void *spdm_secured_message_context, 105 libspdm_session_state_t session_state); 106 107 /** 108 * Set session_type to an SPDM secured message context. 109 * 110 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 111 * @param session_type Indicate the SPDM session type. 112 */ 113 void libspdm_secured_message_set_session_type(void *spdm_secured_message_context, 114 libspdm_session_type_t session_type); 115 116 /** 117 * Set algorithm to an SPDM secured message context. 118 * 119 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 120 * @param base_hash_algo Indicate the negotiated base_hash_algo for the SPDM session. 121 * @param dhe_named_group Indicate the negotiated dhe_named_group for the SPDM session. 122 * @param aead_cipher_suite Indicate the negotiated aead_cipher_suite for the SPDM session. 123 * @param key_schedule Indicate the negotiated key_schedule for the SPDM session. 124 */ 125 void libspdm_secured_message_set_algorithms(void *spdm_secured_message_context, 126 const spdm_version_number_t version, 127 const spdm_version_number_t secured_message_version, 128 uint32_t base_hash_algo, 129 uint16_t dhe_named_group, 130 uint16_t aead_cipher_suite, 131 uint16_t key_schedule); 132 133 /** 134 * Set the psk_hint to an SPDM secured message context. 135 * 136 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 137 * @param psk_hint Indicate the PSK hint. 138 * @param psk_hint_size The size in bytes of the PSK hint. 139 */ 140 void libspdm_secured_message_set_psk_hint(void *spdm_secured_message_context, 141 const void *psk_hint, 142 size_t psk_hint_size); 143 144 /** 145 * Set the maximum sequence_number to an SPDM secured message context. 146 * 147 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 148 * @param max_spdm_session_sequence_number Indicate the maximum sequence_number in SPDM session. 149 */ 150 void libspdm_secured_message_set_max_spdm_session_sequence_number( 151 void *spdm_secured_message_context, 152 uint64_t max_spdm_session_sequence_number); 153 154 /** 155 * Set the endianness of the sequence number used to construct the AEAD IV. 156 * 157 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 158 * @param endian_value The endianness value. 159 * 160 */ 161 void libspdm_secured_message_set_sequence_number_endian( 162 void *spdm_secured_message_context, 163 uint8_t endian_value); 164 165 /** 166 * Allocates and Initializes one Diffie-Hellman Ephemeral (DHE) context for subsequent use, 167 * based upon negotiated DHE algorithm. 168 * 169 * @param dhe_named_group SPDM dhe_named_group 170 * @param is_initiator if the caller is initiator. 171 * true: initiator 172 * false: not an initiator 173 * 174 * @return Pointer to the Diffie-Hellman context that has been initialized. 175 **/ 176 void *libspdm_secured_message_dhe_new(spdm_version_number_t spdm_version, 177 uint16_t dhe_named_group, bool is_initiator); 178 179 /** 180 * Release the specified DHE context, 181 * based upon negotiated DHE algorithm. 182 * 183 * @param dhe_named_group SPDM dhe_named_group 184 * @param dhe_context Pointer to the DHE context to be released. 185 **/ 186 void libspdm_secured_message_dhe_free(uint16_t dhe_named_group, void *dhe_context); 187 188 /** 189 * Generates DHE public key, 190 * based upon negotiated DHE algorithm. 191 * 192 * This function generates random secret exponent, and computes the public key, which is 193 * returned via parameter public_key and public_key_size. DH context is updated accordingly. 194 * If the public_key buffer is too small to hold the public key, false is returned and 195 * public_key_size is set to the required buffer size to obtain the public key. 196 * 197 * @param dhe_named_group SPDM dhe_named_group 198 * @param dhe_context Pointer to the DHE context. 199 * @param public_key Pointer to the buffer to receive generated public key. 200 * @param public_key_size On input, the size of public_key buffer in bytes. 201 * On output, the size of data returned in public_key buffer in bytes. 202 * 203 * @retval true DHE public key generation succeeded. 204 * @retval false DHE public key generation failed. 205 * @retval false public_key_size is not large enough. 206 **/ 207 bool libspdm_secured_message_dhe_generate_key(uint16_t dhe_named_group, 208 void *dhe_context, 209 uint8_t *public_key, 210 size_t *public_key_size); 211 212 /** 213 * Computes exchanged common key, 214 * based upon negotiated DHE algorithm. 215 * 216 * Given peer's public key, this function computes the exchanged common key, based on its own 217 * context including value of prime modulus and random secret exponent. 218 * 219 * @param dhe_named_group SPDM dhe_named_group 220 * @param dhe_context Pointer to the DHE context. 221 * @param peer_public_key Pointer to the peer's public key. 222 * @param peer_public_key_size size of peer's public key in bytes. 223 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 224 * 225 * @retval true DHE exchanged key generation succeeded. 226 * @retval false DHE exchanged key generation failed. 227 * @retval false key_size is not large enough. 228 **/ 229 bool libspdm_secured_message_dhe_compute_key( 230 uint16_t dhe_named_group, void *dhe_context, 231 const uint8_t *peer_public, size_t peer_public_size, 232 void *spdm_secured_message_context); 233 234 /** 235 * Allocates and initializes one HMAC context for subsequent use, with request_finished_key. 236 * 237 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 238 * 239 * @return Pointer to the HMAC context that has been initialized. 240 **/ 241 void *libspdm_hmac_new_with_request_finished_key(void *spdm_secured_message_context); 242 243 /** 244 * Release the specified HMAC context, with request_finished_key. 245 * 246 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 247 * @param hmac_ctx Pointer to the HMAC context to be released. 248 **/ 249 void libspdm_hmac_free_with_request_finished_key( 250 void *spdm_secured_message_context, void *hmac_ctx); 251 252 /** 253 * Set request_finished_key for subsequent use. It must be done before any 254 * calling to hmac_update(). 255 * 256 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 257 * @param hmac_ctx Pointer to HMAC context. 258 * 259 * @retval true The key is set successfully. 260 * @retval false The key is set unsuccessfully. 261 **/ 262 bool libspdm_hmac_init_with_request_finished_key( 263 void *spdm_secured_message_context, void *hmac_ctx); 264 265 /** 266 * Makes a copy of an existing HMAC context, with request_finished_key. 267 * 268 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 269 * @param hmac_ctx Pointer to HMAC context being copied. 270 * @param new_hmac_ctx Pointer to new HMAC context. 271 * 272 * @retval true HMAC context copy succeeded. 273 * @retval false HMAC context copy failed. 274 **/ 275 bool libspdm_hmac_duplicate_with_request_finished_key( 276 void *spdm_secured_message_context, 277 const void *hmac_ctx, void *new_hmac_ctx); 278 279 /** 280 * Digests the input data and updates HMAC context, with request_finished_key. 281 * 282 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 283 * @param hmac_ctx Pointer to HMAC context being copied. 284 * @param data Pointer to the buffer containing the data to be digested. 285 * @param data_size size of data buffer in bytes. 286 * 287 * @retval true HMAC data digest succeeded. 288 * @retval false HMAC data digest failed. 289 **/ 290 bool libspdm_hmac_update_with_request_finished_key( 291 void *spdm_secured_message_context, 292 void *hmac_ctx, const void *data, 293 size_t data_size); 294 295 /** 296 * Completes computation of the HMAC digest value, with request_finished_key. 297 * 298 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 299 * @param hmac_ctx Pointer to HMAC context being copied. 300 * @param hmac_value Pointer to a buffer that receives the HMAC digest value 301 * 302 * @retval true HMAC data digest succeeded. 303 * @retval false HMAC data digest failed. 304 **/ 305 bool libspdm_hmac_final_with_request_finished_key( 306 void *spdm_secured_message_context, 307 void *hmac_ctx, uint8_t *hmac_value); 308 309 /** 310 * Computes the HMAC of a input data buffer, with request_finished_key. 311 * 312 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 313 * @param data Pointer to the buffer containing the data to be HMACed. 314 * @param data_size size of data buffer in bytes. 315 * @param hash_value Pointer to a buffer that receives the HMAC value. 316 * 317 * @retval true HMAC computation succeeded. 318 * @retval false HMAC computation failed. 319 **/ 320 bool libspdm_hmac_all_with_request_finished_key(void *spdm_secured_message_context, 321 const void *data, size_t data_size, 322 uint8_t *hmac_value); 323 324 /** 325 * Allocates and initializes one HMAC context for subsequent use, with response_finished_key. 326 * 327 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 328 * 329 * @return Pointer to the HMAC context that has been initialized. 330 **/ 331 void *libspdm_hmac_new_with_response_finished_key(void *spdm_secured_message_context); 332 333 /** 334 * Release the specified HMAC context, with response_finished_key. 335 * 336 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 337 * @param hmac_ctx Pointer to the HMAC context to be released. 338 **/ 339 void libspdm_hmac_free_with_response_finished_key( 340 void *spdm_secured_message_context, void *hmac_ctx); 341 342 /** 343 * Set response_finished_key for subsequent use. It must be done before any 344 * calling to hmac_update(). 345 * 346 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 347 * @param hmac_ctx Pointer to HMAC context. 348 * 349 * @retval true The key is set successfully. 350 * @retval false The key is set unsuccessfully. 351 **/ 352 bool libspdm_hmac_init_with_response_finished_key( 353 void *spdm_secured_message_context, void *hmac_ctx); 354 355 /** 356 * Makes a copy of an existing HMAC context, with response_finished_key. 357 * 358 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 359 * @param hmac_ctx Pointer to HMAC context being copied. 360 * @param new_hmac_ctx Pointer to new HMAC context. 361 * 362 * @retval true HMAC context copy succeeded. 363 * @retval false HMAC context copy failed. 364 **/ 365 bool libspdm_hmac_duplicate_with_response_finished_key( 366 void *spdm_secured_message_context, 367 const void *hmac_ctx, void *new_hmac_ctx); 368 369 /** 370 * Digests the input data and updates HMAC context, with response_finished_key. 371 * 372 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 373 * @param hmac_ctx Pointer to HMAC context being copied. 374 * @param data Pointer to the buffer containing the data to be digested. 375 * @param data_size size of data buffer in bytes. 376 * 377 * @retval true HMAC data digest succeeded. 378 * @retval false HMAC data digest failed. 379 **/ 380 bool libspdm_hmac_update_with_response_finished_key( 381 void *spdm_secured_message_context, 382 void *hmac_ctx, const void *data, 383 size_t data_size); 384 385 /** 386 * Completes computation of the HMAC digest value, with response_finished_key. 387 * 388 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 389 * @param hmac_ctx Pointer to HMAC context being copied. 390 * @param hmac_value Pointer to a buffer that receives the HMAC digest value 391 * 392 * @retval true HMAC data digest succeeded. 393 * @retval false HMAC data digest failed. 394 **/ 395 bool libspdm_hmac_final_with_response_finished_key( 396 void *spdm_secured_message_context, 397 void *hmac_ctx, uint8_t *hmac_value); 398 399 /** 400 * Computes the HMAC of a input data buffer, with response_finished_key. 401 * 402 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 403 * @param data Pointer to the buffer containing the data to be HMACed. 404 * @param data_size size of data buffer in bytes. 405 * @param hash_value Pointer to a buffer that receives the HMAC value. 406 * 407 * @retval true HMAC computation succeeded. 408 * @retval false HMAC computation failed. 409 **/ 410 bool libspdm_hmac_all_with_response_finished_key( 411 void *spdm_secured_message_context, const void *data, 412 size_t data_size, uint8_t *hmac_value); 413 414 /** 415 * Set the last SPDM error struct of an SPDM secured message context. 416 * 417 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 418 * @param last_spdm_error Last SPDM error struct of an SPDM secured message context. 419 */ 420 void libspdm_secured_message_set_last_spdm_error_struct( 421 void *spdm_secured_message_context, 422 const libspdm_error_struct_t *last_spdm_error); 423 424 /** 425 * This function generates SPDM HandshakeKey for a session. 426 * 427 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 428 * @param th1_hash_data th1 hash 429 * 430 * @retval RETURN_SUCCESS SPDM HandshakeKey for a session is generated. 431 **/ 432 bool libspdm_generate_session_handshake_key(void *spdm_secured_message_context, 433 const uint8_t *th1_hash_data); 434 435 /** 436 * This function generates SPDM DataKey for a session. 437 * 438 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 439 * @param th2_hash_data th2 hash 440 * 441 * @retval RETURN_SUCCESS SPDM DataKey for a session is generated. 442 **/ 443 bool libspdm_generate_session_data_key(void *spdm_secured_message_context, 444 const uint8_t *th2_hash_data); 445 446 /** 447 * This function creates the updates of SPDM DataKey for a session. 448 * 449 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 450 * @param action Indicate of the key update action. 451 * 452 * @retval RETURN_SUCCESS SPDM DataKey update is created. 453 **/ 454 bool libspdm_create_update_session_data_key(void *spdm_secured_message_context, 455 libspdm_key_update_action_t action); 456 457 /** 458 * This function activates the update of SPDM DataKey for a session. 459 * 460 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 461 * @param action Indicate of the key update action. 462 * @param use_new_key Indicate if the new key should be used. 463 * 464 * @retval RETURN_SUCCESS SPDM DataKey update is activated. 465 **/ 466 bool libspdm_activate_update_session_data_key(void *spdm_secured_message_context, 467 libspdm_key_update_action_t action, 468 bool use_new_key); 469 470 #endif /* SPDM_SECURED_MESSAGE_LIB_INTERNAL_H */ 471