Branch data Line data Source code
1 : : /**
2 : : * Copyright Notice:
3 : : * Copyright 2025-2026 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 : : #include "library/spdm_transport_tcp_lib.h"
8 : : #include "library/spdm_secured_message_lib.h"
9 : : #include "hal/library/debuglib.h"
10 : : #include "industry_standard/spdm_tcp_binding.h"
11 : :
12 : : /**
13 : : * Encode a normal message or secured message to a transport message.
14 : : *
15 : : * @param session_id Indicates if it is a secured message protected via SPDM session.
16 : : * If session_id is NULL, it is a normal message.
17 : : * If session_id is NOT NULL, it is a secured message.
18 : : * @param message_size size in bytes of the message data buffer.
19 : : * @param message A pointer to a source buffer to store the message.
20 : : * @param transport_message_size size in bytes of the transport message data buffer.
21 : : * @param transport_message A pointer to a destination buffer to store the transport message.
22 : : **/
23 : : libspdm_return_t libspdm_tcp_encode_message(const uint32_t *session_id, size_t message_size,
24 : : void *message,
25 : : size_t *transport_message_size,
26 : : void **transport_message);
27 : :
28 : : /**
29 : : * Decode a transport message to a normal message or secured message.
30 : : *
31 : : * @param session_id Indicates if it is a secured message protected via SPDM session.
32 : : * If *session_id is NULL, it is a normal message.
33 : : * If *session_id is NOT NULL, it is a secured message.
34 : : * @param transport_message_size size in bytes of the transport message data buffer.
35 : : * @param transport_message A pointer to a source buffer to store the transport message.
36 : : * @param message_size size in bytes of the message data buffer.
37 : : * @param message A pointer to a destination buffer to store the message.
38 : : **/
39 : : libspdm_return_t libspdm_tcp_decode_message(uint32_t **session_id,
40 : : size_t transport_message_size,
41 : : void *transport_message,
42 : : size_t *message_size,
43 : : void **message);
44 : :
45 : 20 : libspdm_return_t libspdm_transport_tcp_encode_message(
46 : : void *spdm_context, const uint32_t *session_id, bool is_app_message,
47 : : bool is_requester, size_t message_size, void *message,
48 : : size_t *transport_message_size, void **transport_message)
49 : : {
50 : : libspdm_return_t status;
51 : : uint8_t *secured_message;
52 : : size_t secured_message_size;
53 : : libspdm_secured_message_callbacks_t spdm_secured_message_callbacks;
54 : : void *secured_message_context;
55 : : size_t secure_transport_header_size;
56 : :
57 : 20 : spdm_secured_message_callbacks.version =
58 : : LIBSPDM_SECURED_MESSAGE_CALLBACKS_VERSION;
59 : 20 : spdm_secured_message_callbacks.get_sequence_number =
60 : : libspdm_tcp_get_sequence_number;
61 : 20 : spdm_secured_message_callbacks.get_max_random_number_count =
62 : : libspdm_tcp_get_max_random_number_count;
63 : 20 : spdm_secured_message_callbacks.get_secured_spdm_version =
64 : : libspdm_tcp_get_secured_spdm_version;
65 : :
66 [ + + ]: 20 : if (is_app_message) {
67 : 4 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
68 : : }
69 : :
70 [ + + ]: 16 : if (session_id != NULL) {
71 : : secured_message_context =
72 : 10 : libspdm_get_secured_message_context_via_session_id(
73 : : spdm_context, *session_id);
74 [ + + ]: 10 : if (secured_message_context == NULL) {
75 : 2 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
76 : : }
77 : :
78 : : /* SPDM message to secured message*/
79 : 8 : secure_transport_header_size = libspdm_transport_tcp_get_header_size(spdm_context);
80 : 8 : secured_message = (uint8_t *)*transport_message + secure_transport_header_size;
81 : 8 : secured_message_size = *transport_message_size - secure_transport_header_size;
82 : 8 : status = libspdm_encode_secured_message(
83 : : secured_message_context, *session_id, is_requester,
84 : : message_size, message, &secured_message_size,
85 : : secured_message, &spdm_secured_message_callbacks);
86 [ - + ]: 8 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
87 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "libspdm_encode_secured_message - %x\n", status));
88 : 0 : return status;
89 : : }
90 : :
91 : : /* secured message to secured TCP message*/
92 : 8 : status = libspdm_tcp_encode_message(
93 : : session_id, secured_message_size, secured_message,
94 : : transport_message_size, transport_message);
95 [ - + ]: 8 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
96 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "transport_encode_message - %x\n", status));
97 : 0 : return status;
98 : : }
99 : : } else {
100 : : /* SPDM message to normal TCP message*/
101 : 6 : status = libspdm_tcp_encode_message(NULL, message_size, message,
102 : : transport_message_size,
103 : : transport_message);
104 [ + + ]: 6 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
105 : 2 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "transport_encode_message - %x\n", status));
106 : 2 : return status;
107 : : }
108 : : }
109 : :
110 : 12 : return LIBSPDM_STATUS_SUCCESS;
111 : : }
112 : :
113 : 26 : libspdm_return_t libspdm_transport_tcp_decode_message(
114 : : void *spdm_context, uint32_t **session_id,
115 : : bool *is_app_message, bool is_requester,
116 : : size_t transport_message_size, void *transport_message,
117 : : size_t *message_size, void **message)
118 : : {
119 : : libspdm_return_t status;
120 : : uint32_t *secured_message_session_id;
121 : : uint8_t *secured_message;
122 : : size_t secured_message_size;
123 : : libspdm_secured_message_callbacks_t spdm_secured_message_callbacks;
124 : : void *secured_message_context;
125 : : libspdm_error_struct_t spdm_error;
126 : :
127 : 26 : spdm_error.error_code = 0;
128 : 26 : spdm_error.session_id = 0;
129 [ + - ]: 26 : if (spdm_context) {
130 : 26 : libspdm_set_last_spdm_error_struct(spdm_context, &spdm_error);
131 : : }
132 : :
133 : 26 : spdm_secured_message_callbacks.version =
134 : : LIBSPDM_SECURED_MESSAGE_CALLBACKS_VERSION;
135 : 26 : spdm_secured_message_callbacks.get_sequence_number =
136 : : libspdm_tcp_get_sequence_number;
137 : 26 : spdm_secured_message_callbacks.get_max_random_number_count =
138 : : libspdm_tcp_get_max_random_number_count;
139 : 26 : spdm_secured_message_callbacks.get_secured_spdm_version =
140 : : libspdm_tcp_get_secured_spdm_version;
141 : :
142 [ + - - + ]: 26 : if ((session_id == NULL) || (is_app_message == NULL)) {
143 : 0 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
144 : : }
145 : 26 : *is_app_message = false;
146 : :
147 : 26 : secured_message_session_id = NULL;
148 : : /* Detect received message*/
149 : 26 : status = libspdm_tcp_decode_message(
150 : : &secured_message_session_id, transport_message_size,
151 : : transport_message, &secured_message_size, (void **)&secured_message);
152 [ + + ]: 26 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
153 : 14 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "transport_decode_message - %x\n", status));
154 : 14 : return status;
155 : : }
156 : :
157 [ + + ]: 12 : if (secured_message_session_id != NULL) {
158 : 10 : *session_id = secured_message_session_id;
159 : :
160 : : secured_message_context =
161 : 10 : libspdm_get_secured_message_context_via_session_id(
162 : : spdm_context, *secured_message_session_id);
163 [ + + ]: 10 : if (secured_message_context == NULL) {
164 : 4 : spdm_error.error_code = SPDM_ERROR_CODE_INVALID_SESSION;
165 : 4 : spdm_error.session_id = *secured_message_session_id;
166 : 4 : libspdm_set_last_spdm_error_struct(spdm_context,
167 : : &spdm_error);
168 : 4 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
169 : : }
170 : :
171 : : /* Secured message to SPDM message*/
172 : 6 : status = libspdm_decode_secured_message(
173 : : secured_message_context, *secured_message_session_id,
174 : : is_requester, secured_message_size, secured_message,
175 : : message_size, message,
176 : : &spdm_secured_message_callbacks);
177 [ + + ]: 6 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
178 : 2 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "libspdm_decode_secured_message - %x\n", status));
179 : 2 : libspdm_secured_message_get_last_spdm_error_struct(
180 : : secured_message_context, &spdm_error);
181 : 2 : libspdm_set_last_spdm_error_struct(spdm_context,
182 : : &spdm_error);
183 : 2 : return status;
184 : : }
185 : 4 : return LIBSPDM_STATUS_SUCCESS;
186 : : } else {
187 : : /* get non-secured message*/
188 : 2 : status = libspdm_tcp_decode_message(&secured_message_session_id,
189 : : transport_message_size,
190 : : transport_message,
191 : : message_size, message);
192 [ - + ]: 2 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
193 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "transport_decode_message - %x\n", status));
194 : 0 : return status;
195 : : }
196 : 2 : LIBSPDM_ASSERT(secured_message_session_id == NULL);
197 : 2 : *session_id = NULL;
198 : 2 : return LIBSPDM_STATUS_SUCCESS;
199 : : }
200 : : }
|