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_requester_lib.h"
8 : : #include "internal/libspdm_secured_message_lib.h"
9 : :
10 : : #if (LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP) && \
11 : : ((LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP) || (LIBSPDM_ENABLE_CAPABILITY_PSK_CAP))
12 : :
13 : 16 : libspdm_return_t libspdm_get_encap_response_key_update(void *spdm_context,
14 : : size_t request_size,
15 : : void *request,
16 : : size_t *response_size,
17 : : void *response)
18 : : {
19 : : uint32_t session_id;
20 : : spdm_key_update_response_t *spdm_response;
21 : : spdm_key_update_request_t *spdm_request;
22 : : libspdm_context_t *context;
23 : : libspdm_session_info_t *session_info;
24 : : libspdm_session_state_t session_state;
25 : : spdm_key_update_request_t *prev_spdm_request;
26 : : spdm_key_update_request_t spdm_key_init_update_operation;
27 : : bool result;
28 : :
29 : 16 : context = spdm_context;
30 : 16 : spdm_request = request;
31 : :
32 [ - + ]: 16 : if (libspdm_get_connection_version(context) < SPDM_MESSAGE_VERSION_11) {
33 : 0 : return libspdm_generate_encap_error_response(
34 : : context, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
35 : : SPDM_KEY_UPDATE, response_size, response);
36 : : }
37 : :
38 [ - + ]: 16 : if (spdm_request->header.spdm_version != libspdm_get_connection_version(context)) {
39 : 0 : return libspdm_generate_encap_error_response(
40 : : context, SPDM_ERROR_CODE_VERSION_MISMATCH,
41 : : 0, response_size, response);
42 : : }
43 : :
44 [ + + ]: 16 : if (!libspdm_is_capabilities_flag_supported(
45 : : context, true,
46 : : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_UPD_CAP,
47 : : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_UPD_CAP)) {
48 : 1 : return libspdm_generate_encap_error_response(
49 : : context, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
50 : : SPDM_KEY_UPDATE, response_size, response);
51 : : }
52 : :
53 [ + + ]: 15 : if (!context->last_spdm_request_session_id_valid) {
54 [ - + ]: 1 : if (libspdm_get_connection_version(context) >= SPDM_MESSAGE_VERSION_12) {
55 : 0 : return libspdm_generate_encap_error_response(context,
56 : : SPDM_ERROR_CODE_SESSION_REQUIRED, 0,
57 : : response_size, response);
58 : : } else {
59 : 1 : return libspdm_generate_encap_error_response(context,
60 : : SPDM_ERROR_CODE_UNSPECIFIED, 0,
61 : : response_size, response);
62 : : }
63 : : }
64 : 14 : session_id = context->last_spdm_request_session_id;
65 : : session_info =
66 : 14 : libspdm_get_session_info_via_session_id(context, session_id);
67 [ - + ]: 14 : if (session_info == NULL) {
68 : 0 : return libspdm_generate_encap_error_response(
69 : : context, SPDM_ERROR_CODE_INVALID_REQUEST, 0,
70 : : response_size, response);
71 : : }
72 : 14 : session_state = libspdm_secured_message_get_session_state(
73 : : session_info->secured_message_context);
74 [ + + ]: 14 : if (session_state != LIBSPDM_SESSION_STATE_ESTABLISHED) {
75 : 1 : return libspdm_generate_encap_error_response(
76 : : context, SPDM_ERROR_CODE_INVALID_REQUEST, 0,
77 : : response_size, response);
78 : : }
79 : :
80 : : /* this message can only be in secured session
81 : : * thus don't need to consider transport layer padding, just check its exact size */
82 [ + + ]: 13 : if (request_size != sizeof(spdm_key_update_request_t)) {
83 : 2 : return libspdm_generate_encap_error_response(
84 : : context, SPDM_ERROR_CODE_INVALID_REQUEST, 0,
85 : : response_size, response);
86 : : }
87 : :
88 : : /*last key operation*/
89 : 11 : prev_spdm_request = &(session_info->last_key_update_request);
90 : :
91 : : /*the end status of the successful key update overall flow*/
92 : 11 : libspdm_zero_mem(&spdm_key_init_update_operation, sizeof(spdm_key_update_request_t));
93 : :
94 : 11 : result = true;
95 [ + + + + ]: 11 : switch (spdm_request->header.param1) {
96 : 6 : case SPDM_KEY_UPDATE_OPERATIONS_UPDATE_KEY:
97 [ + + ]: 6 : if (!libspdm_consttime_is_mem_equal(prev_spdm_request,
98 : : &spdm_key_init_update_operation,
99 : : sizeof(spdm_key_update_request_t))) {
100 : 1 : result = false;
101 : 1 : break;
102 : : }
103 : 5 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
104 : : "libspdm_create_update_session_data_key[%x] Responder\n",
105 : : session_id));
106 : 5 : result = libspdm_create_update_session_data_key(
107 : : session_info->secured_message_context,
108 : : LIBSPDM_KEY_UPDATE_ACTION_RESPONDER);
109 : :
110 : : /*save the last update operation*/
111 : 5 : libspdm_copy_mem(prev_spdm_request, sizeof(spdm_key_update_request_t),
112 : : spdm_request, request_size);
113 : 5 : break;
114 : 1 : case SPDM_KEY_UPDATE_OPERATIONS_UPDATE_ALL_KEYS:
115 : 1 : result = false;
116 : 1 : break;
117 : 3 : case SPDM_KEY_UPDATE_OPERATIONS_VERIFY_NEW_KEY:
118 [ + - ]: 3 : if (prev_spdm_request->header.param1 != SPDM_KEY_UPDATE_OPERATIONS_UPDATE_KEY) {
119 : 3 : result = false;
120 : 3 : break;
121 : : }
122 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
123 : : "libspdm_activate_update_session_data_key[%x] Responder new\n",
124 : : session_id));
125 : 0 : result = libspdm_activate_update_session_data_key(
126 : : session_info->secured_message_context,
127 : : LIBSPDM_KEY_UPDATE_ACTION_RESPONDER, true);
128 : :
129 : : /*clear last_key_update_request*/
130 : 0 : libspdm_zero_mem(prev_spdm_request, sizeof(spdm_key_update_request_t));
131 : 0 : break;
132 : 1 : default:
133 : 1 : result = false;
134 : 1 : break;
135 : : }
136 : :
137 [ + + ]: 11 : if (!result) {
138 : 6 : return libspdm_generate_encap_error_response(
139 : : context, SPDM_ERROR_CODE_INVALID_REQUEST, 0,
140 : : response_size, response);
141 : : }
142 : :
143 : 5 : libspdm_reset_message_buffer_via_request_code(context, session_info,
144 : 5 : spdm_request->header.request_response_code);
145 : :
146 [ - + ]: 5 : LIBSPDM_ASSERT(*response_size >= sizeof(spdm_key_update_response_t));
147 : 5 : *response_size = sizeof(spdm_key_update_response_t);
148 : 5 : libspdm_zero_mem(response, *response_size);
149 : 5 : spdm_response = response;
150 : :
151 : 5 : spdm_response->header.spdm_version = spdm_request->header.spdm_version;
152 : 5 : spdm_response->header.request_response_code = SPDM_KEY_UPDATE_ACK;
153 : 5 : spdm_response->header.param1 = spdm_request->header.param1;
154 : 5 : spdm_response->header.param2 = spdm_request->header.param2;
155 : :
156 : 5 : return LIBSPDM_STATUS_SUCCESS;
157 : : }
158 : :
159 : : #endif /* LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP && (...) */
|