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