Branch data Line data Source code
1 : : /**
2 : : * Copyright Notice:
3 : : * Copyright 2021-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 "internal/libspdm_responder_lib.h"
8 : :
9 : : #if (LIBSPDM_ENABLE_CAPABILITY_HBEAT_CAP) && \
10 : : ((LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP) || (LIBSPDM_ENABLE_CAPABILITY_PSK_CAP))
11 : :
12 : 24 : libspdm_return_t libspdm_get_response_heartbeat(libspdm_context_t *spdm_context,
13 : : size_t request_size,
14 : : const void *request,
15 : : size_t *response_size,
16 : : void *response)
17 : : {
18 : : spdm_heartbeat_response_t *spdm_response;
19 : : const spdm_heartbeat_request_t *spdm_request;
20 : : libspdm_session_info_t *session_info;
21 : : libspdm_session_state_t session_state;
22 : :
23 : 24 : spdm_request = request;
24 : :
25 : : /* -=[Check Parameters Phase]=- */
26 : 24 : LIBSPDM_ASSERT(spdm_request->header.request_response_code == SPDM_HEARTBEAT);
27 : :
28 [ - + ]: 24 : if (libspdm_get_connection_version(spdm_context) < SPDM_MESSAGE_VERSION_11) {
29 : 0 : return libspdm_generate_error_response(spdm_context,
30 : : SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
31 : : SPDM_HEARTBEAT,
32 : : response_size, response);
33 : : }
34 : :
35 [ - + ]: 24 : if (spdm_request->header.spdm_version != libspdm_get_connection_version(spdm_context)) {
36 : 0 : return libspdm_generate_error_response(spdm_context,
37 : : SPDM_ERROR_CODE_VERSION_MISMATCH, 0,
38 : : response_size, response);
39 : : }
40 [ + + ]: 24 : if (spdm_context->response_state != LIBSPDM_RESPONSE_STATE_NORMAL) {
41 : 8 : return libspdm_responder_handle_response_state(
42 : : spdm_context,
43 : 8 : spdm_request->header.request_response_code,
44 : : response_size, response);
45 : : }
46 [ - + ]: 16 : if (!libspdm_is_capabilities_flag_supported(
47 : : spdm_context, false,
48 : : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP,
49 : : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP)) {
50 : 0 : return libspdm_generate_error_response(spdm_context,
51 : : SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
52 : : SPDM_HEARTBEAT, response_size, response);
53 : : }
54 [ + + ]: 16 : if (spdm_context->connection_info.connection_state < LIBSPDM_CONNECTION_STATE_NEGOTIATED) {
55 : 4 : return libspdm_generate_error_response(spdm_context,
56 : : SPDM_ERROR_CODE_UNEXPECTED_REQUEST,
57 : : 0, response_size, response);
58 : : }
59 : :
60 [ - + ]: 12 : if (!spdm_context->last_spdm_request_session_id_valid) {
61 [ # # ]: 0 : if (libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_12) {
62 : 0 : return libspdm_generate_error_response(spdm_context,
63 : : SPDM_ERROR_CODE_SESSION_REQUIRED, 0,
64 : : response_size, response);
65 : : } else {
66 : 0 : return libspdm_generate_error_response(spdm_context,
67 : : SPDM_ERROR_CODE_UNSPECIFIED, 0,
68 : : response_size, response);
69 : : }
70 : : }
71 : 12 : session_info = libspdm_get_session_info_via_session_id(
72 : : spdm_context, spdm_context->last_spdm_request_session_id);
73 [ - + ]: 12 : if (session_info == NULL) {
74 [ # # ]: 0 : if (libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_12) {
75 : 0 : return libspdm_generate_error_response(spdm_context,
76 : : SPDM_ERROR_CODE_SESSION_REQUIRED, 0,
77 : : response_size, response);
78 : : } else {
79 : 0 : return libspdm_generate_error_response(spdm_context,
80 : : SPDM_ERROR_CODE_UNSPECIFIED, 0,
81 : : response_size, response);
82 : : }
83 : : }
84 : 12 : session_state = libspdm_secured_message_get_session_state(
85 : : session_info->secured_message_context);
86 [ - + ]: 12 : if (session_state != LIBSPDM_SESSION_STATE_ESTABLISHED) {
87 : 0 : return libspdm_generate_error_response(spdm_context,
88 : : SPDM_ERROR_CODE_UNEXPECTED_REQUEST, 0,
89 : : response_size, response);
90 : : }
91 : :
92 : : /* this message can only be in secured session
93 : : * thus don't need to consider transport layer padding, just check its exact size */
94 [ + + ]: 12 : if (request_size != sizeof(spdm_heartbeat_request_t)) {
95 : 2 : return libspdm_generate_error_response(spdm_context,
96 : : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
97 : : response_size, response);
98 : : }
99 : :
100 [ + + ]: 10 : if (session_info->heartbeat_period == 0) {
101 : 4 : return libspdm_generate_error_response(spdm_context,
102 : : SPDM_ERROR_CODE_UNEXPECTED_REQUEST, 0,
103 : : response_size, response);
104 : : }
105 : :
106 : 6 : libspdm_reset_message_buffer_via_request_code(spdm_context, session_info,
107 : 6 : spdm_request->header.request_response_code);
108 : :
109 : 6 : LIBSPDM_ASSERT(*response_size >= sizeof(spdm_heartbeat_response_t));
110 : 6 : *response_size = sizeof(spdm_heartbeat_response_t);
111 : 6 : libspdm_zero_mem(response, *response_size);
112 : 6 : spdm_response = response;
113 : :
114 : 6 : spdm_response->header.spdm_version = spdm_request->header.spdm_version;
115 : 6 : spdm_response->header.request_response_code = SPDM_HEARTBEAT_ACK;
116 : 6 : spdm_response->header.param1 = 0;
117 : 6 : spdm_response->header.param2 = 0;
118 : :
119 : 6 : return LIBSPDM_STATUS_SUCCESS;
120 : : }
121 : :
122 : : #endif /* (LIBSPDM_ENABLE_CAPABILITY_HBEAT_CAP) && (...) */
|