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