Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2021-2024 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 8 : libspdm_return_t libspdm_get_response_end_session(libspdm_context_t *spdm_context,
10 : size_t request_size,
11 : const void *request,
12 : size_t *response_size,
13 : void *response)
14 : {
15 : spdm_end_session_response_t *spdm_response;
16 : const spdm_end_session_request_t *spdm_request;
17 : libspdm_session_info_t *session_info;
18 : libspdm_session_state_t session_state;
19 :
20 8 : spdm_request = request;
21 :
22 8 : if (libspdm_get_connection_version(spdm_context) < SPDM_MESSAGE_VERSION_11) {
23 0 : return libspdm_generate_error_response(spdm_context,
24 : SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
25 : SPDM_END_SESSION,
26 : response_size, response);
27 : }
28 :
29 8 : if (spdm_request->header.spdm_version != libspdm_get_connection_version(spdm_context)) {
30 0 : return libspdm_generate_error_response(spdm_context,
31 : SPDM_ERROR_CODE_VERSION_MISMATCH, 0,
32 : response_size, response);
33 : }
34 8 : if (spdm_context->response_state != LIBSPDM_RESPONSE_STATE_NORMAL) {
35 3 : return libspdm_responder_handle_response_state(
36 : spdm_context,
37 3 : spdm_request->header.request_response_code,
38 : response_size, response);
39 : }
40 5 : if (spdm_context->connection_info.connection_state < LIBSPDM_CONNECTION_STATE_NEGOTIATED) {
41 1 : return libspdm_generate_error_response(spdm_context,
42 : SPDM_ERROR_CODE_UNEXPECTED_REQUEST,
43 : 0, response_size, response);
44 : }
45 :
46 4 : if (!spdm_context->last_spdm_request_session_id_valid) {
47 0 : if (libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_12) {
48 0 : return libspdm_generate_error_response(spdm_context,
49 : SPDM_ERROR_CODE_SESSION_REQUIRED, 0,
50 : response_size, response);
51 : } else {
52 0 : return libspdm_generate_error_response(spdm_context,
53 : SPDM_ERROR_CODE_UNSPECIFIED, 0,
54 : response_size, response);
55 : }
56 : }
57 4 : session_info = libspdm_get_session_info_via_session_id(
58 : spdm_context, spdm_context->last_spdm_request_session_id);
59 4 : if (session_info == NULL) {
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 4 : session_state = libspdm_secured_message_get_session_state(
71 : session_info->secured_message_context);
72 4 : if (session_state != LIBSPDM_SESSION_STATE_ESTABLISHED) {
73 0 : return libspdm_generate_error_response(spdm_context,
74 : SPDM_ERROR_CODE_UNEXPECTED_REQUEST, 0,
75 : response_size, response);
76 : }
77 :
78 : /* this message can only be in secured session
79 : * thus don't need to consider transport layer padding, just check its exact size */
80 4 : if (request_size != sizeof(spdm_end_session_request_t)) {
81 1 : return libspdm_generate_error_response(spdm_context,
82 : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
83 : response_size, response);
84 : }
85 :
86 3 : libspdm_reset_message_buffer_via_request_code(spdm_context, session_info,
87 3 : spdm_request->header.request_response_code);
88 :
89 3 : session_info->end_session_attributes = spdm_request->header.param1;
90 3 : if ((spdm_request->header.param1 &
91 : SPDM_END_SESSION_REQUEST_ATTRIBUTES_PRESERVE_NEGOTIATED_STATE_CLEAR) != 0) {
92 1 : spdm_context->connection_info.end_session_attributes |=
93 : SPDM_END_SESSION_REQUEST_ATTRIBUTES_PRESERVE_NEGOTIATED_STATE_CLEAR;
94 : }
95 :
96 3 : LIBSPDM_ASSERT(*response_size >= sizeof(spdm_end_session_response_t));
97 3 : *response_size = sizeof(spdm_end_session_response_t);
98 3 : libspdm_zero_mem(response, *response_size);
99 3 : spdm_response = response;
100 :
101 3 : spdm_response->header.spdm_version = spdm_request->header.spdm_version;
102 3 : spdm_response->header.request_response_code = SPDM_END_SESSION_ACK;
103 3 : spdm_response->header.param1 = 0;
104 3 : spdm_response->header.param2 = 0;
105 :
106 3 : return LIBSPDM_STATUS_SUCCESS;
107 : }
|