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_RESPOND_IF_READY_SUPPORT
10 :
11 14 : libspdm_return_t libspdm_get_response_respond_if_ready(libspdm_context_t *spdm_context,
12 : size_t request_size,
13 : const void *request,
14 : size_t *response_size,
15 : void *response)
16 : {
17 : const spdm_message_header_t *spdm_request;
18 : libspdm_get_spdm_response_func get_response_func;
19 : libspdm_return_t status;
20 :
21 14 : spdm_request = request;
22 :
23 : /* -=[Check Parameters Phase]=- */
24 14 : LIBSPDM_ASSERT(spdm_request->request_response_code == SPDM_RESPOND_IF_READY);
25 :
26 14 : if (spdm_request->spdm_version != libspdm_get_connection_version(spdm_context)) {
27 0 : return libspdm_generate_error_response(spdm_context,
28 : SPDM_ERROR_CODE_VERSION_MISMATCH, 0,
29 : response_size, response);
30 : }
31 14 : if (spdm_context->response_state == LIBSPDM_RESPONSE_STATE_NEED_RESYNC ||
32 13 : spdm_context->response_state == LIBSPDM_RESPONSE_STATE_NOT_READY) {
33 2 : return libspdm_responder_handle_response_state(
34 2 : spdm_context, spdm_request->request_response_code,
35 : response_size, response);
36 : }
37 :
38 12 : if (request_size < sizeof(spdm_message_header_t)) {
39 0 : return libspdm_generate_error_response(spdm_context,
40 : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
41 : response_size, response);
42 : }
43 :
44 : /* The validity of the RESPOND_IF_READY request is defined by the original request that caused
45 : * the RESPOND_IF_READY flow (the last request to which the Responder sent an ERROR message of
46 : * ErrorCode=ResponseNotReady). The RESPOND_IF_READY shall therefore arrive in the same session
47 : * context as that original request: the same in-session / out-of-session state, and, when in a
48 : * session, the same session_id. Otherwise the cached response would be returned outside the
49 : * context it belongs to. (Only one deferred request is tracked per connection; a conformant
50 : * Requester does not have multiple outstanding requests to the same Responder within a
51 : * connection.) */
52 12 : if ((spdm_context->last_spdm_request_session_id_valid !=
53 12 : spdm_context->cache_spdm_request_session_id_valid) ||
54 11 : (spdm_context->cache_spdm_request_session_id_valid &&
55 1 : (spdm_context->last_spdm_request_session_id !=
56 1 : spdm_context->cache_spdm_request_session_id))) {
57 1 : return libspdm_generate_error_response(spdm_context,
58 : SPDM_ERROR_CODE_UNEXPECTED_REQUEST, 0,
59 : response_size, response);
60 : }
61 :
62 11 : if (spdm_request->param1 != spdm_context->error_data.request_code) {
63 1 : return libspdm_generate_error_response(spdm_context,
64 : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
65 : response_size, response);
66 : }
67 10 : if (spdm_request->param1 == SPDM_RESPOND_IF_READY) {
68 0 : return libspdm_generate_error_response(spdm_context,
69 : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
70 : response_size, response);
71 : }
72 10 : if (spdm_request->param2 != spdm_context->error_data.token) {
73 1 : return libspdm_generate_error_response(spdm_context,
74 : SPDM_ERROR_CODE_INVALID_REQUEST, 0,
75 : response_size, response);
76 : }
77 :
78 9 : get_response_func = NULL;
79 9 : get_response_func = libspdm_get_response_func_via_request_code(spdm_request->param1);
80 9 : if (get_response_func == NULL) {
81 0 : return libspdm_generate_error_response(
82 : spdm_context, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
83 0 : spdm_request->param1, response_size, response);
84 : }
85 9 : status = get_response_func(spdm_context,
86 : spdm_context->cache_spdm_request_size,
87 9 : spdm_context->cache_spdm_request,
88 : response_size, response);
89 :
90 9 : libspdm_zero_mem(spdm_context->cache_spdm_request, spdm_context->cache_spdm_request_size);
91 9 : spdm_context->cache_spdm_request_size = 0;
92 :
93 9 : return status;
94 : }
95 :
96 : #endif /* LIBSPDM_RESPOND_IF_READY_SUPPORT */
|