1 /** 2 * Copyright Notice: 3 * Copyright 2021-2023 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_H 8 #define SPDM_SECURED_MESSAGE_LIB_H 9 10 #include "hal/base.h" 11 #include "industry_standard/spdm.h" 12 #include "industry_standard/spdm_secured_message.h" 13 #include "library/spdm_return_status.h" 14 15 typedef enum { 16 LIBSPDM_SESSION_TYPE_NONE, 17 LIBSPDM_SESSION_TYPE_MAC_ONLY, 18 LIBSPDM_SESSION_TYPE_ENC_MAC, 19 LIBSPDM_SESSION_TYPE_MAX 20 } libspdm_session_type_t; 21 22 typedef enum { 23 /* Before send KEY_EXCHANGE/PSK_EXCHANGE or after END_SESSION */ 24 LIBSPDM_SESSION_STATE_NOT_STARTED, 25 26 /* After send KEY_EXCHANGE, before send FINISH */ 27 LIBSPDM_SESSION_STATE_HANDSHAKING, 28 29 /* After send FINISH, before END_SESSION */ 30 LIBSPDM_SESSION_STATE_ESTABLISHED, 31 32 /* MAX */ 33 LIBSPDM_SESSION_STATE_MAX 34 } libspdm_session_state_t; 35 36 /* The InvalidSession error code was removed from the specification. This define was originally 37 * in spdm.h and has moved here since it is used in transport decode functions to convey that 38 * the session ID is not recognizable. 39 */ 40 #define SPDM_ERROR_CODE_INVALID_SESSION 0x02 41 42 /** 43 * Return the size in bytes of a single SPDM secured message context. 44 * 45 * @return the size in bytes of a single SPDM secured message context. 46 **/ 47 size_t libspdm_secured_message_get_context_size(void); 48 49 /** 50 * Return session_state of an SPDM secured message context. 51 * 52 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 53 * 54 * @return the SPDM session state. 55 */ 56 libspdm_session_state_t libspdm_secured_message_get_session_state( 57 void *spdm_secured_message_context); 58 59 /** 60 * Import the DHE Secret to an SPDM secured message context. 61 * 62 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 63 * @param dhe_secret Indicate the DHE secret. 64 * @param dhe_secret_size The size, in bytes, of the DHE secret. 65 */ 66 bool libspdm_secured_message_import_dhe_secret(void *spdm_secured_message_context, 67 const void *dhe_secret, 68 size_t dhe_secret_size); 69 70 /** 71 * Export the Export Master Secret from an SPDM secured message context. 72 * 73 * The size of the Export Master Secret is the size of the digest of the negotiated hash algorithm. 74 * If the size of the destination buffer is less than the size of the Export Master Secret then 75 * the first export_master_secret_size bytes are copied. 76 * 77 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 78 * @param export_master_secret A pointer to the buffer to store the export_master_secret. 79 * @param export_master_secret_size On input, the size of the destination buffer. 80 * On output, the lesser of either the size of the destination 81 * buffer or the size of the Export Master Secret. 82 */ 83 bool libspdm_secured_message_export_master_secret( 84 void *spdm_secured_message_context, void *export_master_secret, 85 size_t *export_master_secret_size); 86 87 /** 88 * Erase the Export Master Secret from an SPDM secured message context. 89 * 90 * This is typically called after libspdm_secured_message_export_master_secret(). 91 * 92 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 93 */ 94 void libspdm_secured_message_clear_export_master_secret(void *spdm_secured_message_context); 95 96 #define LIBSPDM_SECURE_SESSION_KEYS_STRUCT_VERSION 1 97 98 #pragma pack(1) 99 typedef struct { 100 uint32_t version; 101 uint32_t aead_key_size; 102 uint32_t aead_iv_size; 103 /* uint8_t request_data_encryption_key[aead_key_size]; 104 * uint8_t request_data_salt[aead_iv_size]; 105 * uint64_t request_data_sequence_number; 106 * uint8_t response_data_encryption_key[aead_key_size]; 107 * uint8_t response_data_salt[aead_iv_size]; 108 * uint64_t response_data_sequence_number;*/ 109 } libspdm_secure_session_keys_struct_t; 110 #pragma pack() 111 112 /** 113 * Export the session_keys from an SPDM secured message context. 114 * 115 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 116 * @param session_keys Indicate the buffer to store the session_keys in 117 * libspdm_secure_session_keys_struct_t. 118 * @param session_keys_size The size in bytes of the session_keys in 119 * libspdm_secure_session_keys_struct_t. 120 */ 121 bool libspdm_secured_message_export_session_keys(void *spdm_secured_message_context, 122 void *session_keys, 123 size_t *session_keys_size); 124 125 /** 126 * Import the session_keys from an SPDM secured message context. 127 * 128 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 129 * @param session_keys Indicate the buffer to store the session_keys in 130 * libspdm_secure_session_keys_struct_t. 131 * @param session_keys_size The size in bytes of the session_keys in 132 * libspdm_secure_session_keys_struct_t. 133 */ 134 bool libspdm_secured_message_import_session_keys(void *spdm_secured_message_context, 135 const void *session_keys, 136 size_t session_keys_size); 137 138 /** 139 * This function is used to clear handshake secret. 140 * 141 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 142 **/ 143 void libspdm_clear_handshake_secret(void *spdm_secured_message_context); 144 145 /** 146 * This function is used to clear the master secret; 147 * 148 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 149 **/ 150 void libspdm_clear_master_secret(void *spdm_secured_message_context); 151 152 /** 153 * This function concatenates binary data, which is used as info in HKDF expand later. 154 * 155 * @param label An ascii string label for the libspdm_bin_concat. 156 * @param label_size The size in bytes of the ASCII string label, not including NULL terminator. 157 * @param context A pre-defined hash value as the context for the libspdm_bin_concat. 158 * @param length 16 bits length for the libspdm_bin_concat. 159 * @param hash_size The size in bytes of the context hash. 160 * @param out_bin The buffer to store the output binary. 161 * @param out_bin_size The size in bytes for the out_bin. 162 **/ 163 void libspdm_bin_concat(spdm_version_number_t spdm_version, 164 const char *label, size_t label_size, 165 const uint8_t *context, uint16_t length, 166 size_t hash_size, uint8_t *out_bin, 167 size_t *out_bin_size); 168 169 typedef enum { 170 LIBSPDM_KEY_UPDATE_OPERATION_CREATE_UPDATE, 171 LIBSPDM_KEY_UPDATE_OPERATION_COMMIT_UPDATE, 172 LIBSPDM_KEY_UPDATE_OPERATION_DISCARD_UPDATE, 173 LIBSPDM_KEY_UPDATE_OPERATION_MAX 174 } libspdm_key_update_operation_t; 175 176 typedef enum { 177 LIBSPDM_KEY_UPDATE_ACTION_REQUESTER, 178 LIBSPDM_KEY_UPDATE_ACTION_RESPONDER, 179 LIBSPDM_KEY_UPDATE_ACTION_MAX 180 } libspdm_key_update_action_t; 181 182 /** 183 * Get sequence number in an SPDM secure message. 184 * 185 * This value is transport layer specific. 186 * 187 * @param sequence_number The current sequence number used to encode or decode message. 188 * @param sequence_number_buffer A buffer to hold the sequence number output used in the secured message. 189 * The size in byte of the output buffer shall be 8. 190 * 191 * @return size in byte of the sequence_number_buffer. 192 * It shall be no greater than 8. 193 * 0 means no sequence number is required. 194 **/ 195 typedef uint8_t (*libspdm_secured_message_get_sequence_number_func)( 196 uint64_t sequence_number, uint8_t *sequence_number_buffer); 197 198 /** 199 * Return max random number count in an SPDM secure message. 200 * 201 * This value is transport layer specific. 202 * 203 * @return Max random number count in an SPDM secured message. 204 * 0 means no random number is required. 205 **/ 206 typedef uint32_t (*libspdm_secured_message_get_max_random_number_count_func)(void); 207 208 /** 209 * This function translates the negotiated secured_message_version to a DSP0277 version. 210 * 211 * @param secured_message_version The version specified in binding specification and 212 * negotiated in KEY_EXCHANGE/KEY_EXCHANGE_RSP. 213 * 214 * @return The DSP0277 version specified in binding specification, 215 * which is bound to secured_message_version. 216 */ 217 typedef spdm_version_number_t (*libspdm_secured_message_get_secured_spdm_version)( 218 spdm_version_number_t secured_message_version); 219 220 #define LIBSPDM_SECURED_MESSAGE_CALLBACKS_VERSION 2 221 222 typedef struct { 223 uint32_t version; 224 libspdm_secured_message_get_sequence_number_func get_sequence_number; 225 libspdm_secured_message_get_max_random_number_count_func get_max_random_number_count; 226 libspdm_secured_message_get_secured_spdm_version get_secured_spdm_version; 227 } libspdm_secured_message_callbacks_t; 228 229 typedef struct { 230 uint8_t error_code; 231 uint32_t session_id; 232 } libspdm_error_struct_t; 233 234 /** 235 * Encode an application message to a secured message. 236 * 237 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 238 * @param session_id The session ID of the SPDM session. 239 * @param is_request_message Indicates if it is a request message. 240 * @param app_message_size size in bytes of the application message data buffer. 241 * @param app_message A pointer to a source buffer to store the application message. 242 * It shall point to the scratch buffer in spdm_context. 243 * On input, the app_message pointer shall point to a big enough buffer. 244 * Before app_message, there is room for spdm_secured_message_cipher_header_t. 245 * After (app_message + app_message_size), there is room for random bytes. 246 * @param secured_message_size size in bytes of the secured message data buffer. 247 * @param secured_message A pointer to a destination buffer to store the secured message. 248 * It shall point to the acquired sender buffer. 249 * @param spdm_secured_message_callbacks A pointer to a secured message callback functions structure. 250 * 251 * @retval RETURN_SUCCESS The application message is encoded successfully. 252 * @retval RETURN_INVALID_PARAMETER The message is NULL or the message_size is zero. 253 **/ 254 libspdm_return_t libspdm_encode_secured_message( 255 void *spdm_secured_message_context, uint32_t session_id, 256 bool is_request_message, size_t app_message_size, 257 void *app_message, size_t *secured_message_size, 258 void *secured_message, 259 const libspdm_secured_message_callbacks_t *spdm_secured_message_callbacks); 260 261 /** 262 * Decode an application message from a secured message. 263 * 264 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 265 * @param session_id The session ID of the SPDM session. 266 * @param is_request_message Indicates if it is a request message. 267 * @param secured_message_size size in bytes of the secured message data buffer. 268 * @param secured_message A pointer to a source buffer to store the secured message. 269 * It shall point to the acquired receiver buffer. 270 * @param app_message_size size in bytes of the application message data buffer. 271 * @param app_message A pointer to a destination buffer to store the application message. 272 * It shall point to the scratch buffer in spdm_context. 273 * On input, the app_message pointer shall point to a big enough buffer to hold the decrypted message 274 * On output, the app_message pointer shall be inside of [app_message, app_message + app_message_size] 275 * @param spdm_secured_message_callbacks A pointer to a secured message callback functions structure. 276 * 277 * @retval RETURN_SUCCESS The application message is decoded successfully. 278 * @retval RETURN_INVALID_PARAMETER The message is NULL or the message_size is zero. 279 * @retval RETURN_UNSUPPORTED The secured_message is unsupported. 280 **/ 281 libspdm_return_t libspdm_decode_secured_message( 282 void *spdm_secured_message_context, uint32_t session_id, 283 bool is_request_message, size_t secured_message_size, 284 void *secured_message, size_t *app_message_size, 285 void **app_message, 286 const libspdm_secured_message_callbacks_t *spdm_secured_message_callbacks); 287 288 /** 289 * Get the last SPDM error struct of an SPDM secured message context. 290 * 291 * @param spdm_secured_message_context A pointer to the SPDM secured message context. 292 * @param last_spdm_error Last SPDM error struct of an SPDM secured message context. 293 */ 294 void libspdm_secured_message_get_last_spdm_error_struct( 295 void *spdm_secured_message_context, 296 libspdm_error_struct_t *last_spdm_error); 297 298 #endif /* SPDM_SECURED_MESSAGE_LIB_H */ 299