Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2021-2022 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 118 : uint16_t libspdm_allocate_rsp_session_id(const libspdm_context_t *spdm_context, bool use_psk)
10 : {
11 : uint16_t rsp_session_id;
12 : const libspdm_session_info_t *session_info;
13 : size_t index;
14 :
15 118 : if (use_psk) {
16 46 : if ((spdm_context->max_psk_session_count != 0) &&
17 16 : (spdm_context->current_psk_session_count >= spdm_context->max_psk_session_count)) {
18 5 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
19 : "libspdm_allocate_req_session_id - MAX PSK session\n"));
20 5 : return (INVALID_SESSION_ID & 0xFFFF0000) >> 16;
21 : }
22 : } else {
23 72 : if ((spdm_context->max_dhe_session_count != 0) &&
24 16 : (spdm_context->current_dhe_session_count >= spdm_context->max_dhe_session_count)) {
25 5 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
26 : "libspdm_allocate_req_session_id - MAX DHE session\n"));
27 5 : return (INVALID_SESSION_ID & 0xFFFF0000) >> 16;
28 : }
29 : }
30 :
31 108 : session_info = spdm_context->session_info;
32 155 : for (index = 0; index < LIBSPDM_MAX_SESSION_COUNT; index++) {
33 155 : if ((session_info[index].session_id & 0xFFFF0000) == (INVALID_SESSION_ID & 0xFFFF0000)) {
34 108 : rsp_session_id = (uint16_t)(0xFFFF - index);
35 108 : return rsp_session_id;
36 : }
37 : }
38 :
39 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "libspdm_allocate_rsp_session_id - MAX session_id\n"));
40 0 : return (INVALID_SESSION_ID & 0xFFFF0000) >> 16;
41 : }
42 :
43 82 : void libspdm_build_opaque_data_version_selection_data(const libspdm_context_t *spdm_context,
44 : size_t *data_out_size,
45 : void *data_out)
46 : {
47 : size_t final_data_size;
48 : secured_message_general_opaque_data_table_header_t *general_opaque_data_table_header;
49 : spdm_general_opaque_data_table_header_t *spdm_general_opaque_data_table_header;
50 : secured_message_opaque_element_table_header_t *opaque_element_table_header;
51 : secured_message_opaque_element_version_selection_t *opaque_element_version_section;
52 : void *end;
53 :
54 82 : if (spdm_context->local_context.secured_message_version.spdm_version_count == 0) {
55 0 : *data_out_size = 0;
56 0 : return;
57 : }
58 :
59 82 : final_data_size = libspdm_get_opaque_data_version_selection_data_size(spdm_context);
60 82 : LIBSPDM_ASSERT(*data_out_size >= final_data_size);
61 :
62 82 : if (libspdm_get_connection_version (spdm_context) >= SPDM_MESSAGE_VERSION_12) {
63 10 : spdm_general_opaque_data_table_header = data_out;
64 10 : spdm_general_opaque_data_table_header->total_elements = 1;
65 10 : libspdm_write_uint24(spdm_general_opaque_data_table_header->reserved, 0);
66 :
67 10 : opaque_element_table_header = (void *)(spdm_general_opaque_data_table_header + 1);
68 : } else {
69 72 : general_opaque_data_table_header = data_out;
70 72 : general_opaque_data_table_header->spec_id = SECURED_MESSAGE_OPAQUE_DATA_SPEC_ID;
71 72 : general_opaque_data_table_header->opaque_version = SECURED_MESSAGE_OPAQUE_VERSION;
72 72 : general_opaque_data_table_header->total_elements = 1;
73 72 : general_opaque_data_table_header->reserved = 0;
74 :
75 72 : opaque_element_table_header = (void *)(general_opaque_data_table_header + 1);
76 : }
77 82 : opaque_element_table_header->id = SPDM_REGISTRY_ID_DMTF;
78 82 : opaque_element_table_header->vendor_len = 0;
79 82 : opaque_element_table_header->opaque_element_data_len =
80 : sizeof(secured_message_opaque_element_version_selection_t);
81 :
82 82 : opaque_element_version_section = (void *)(opaque_element_table_header + 1);
83 82 : opaque_element_version_section->sm_data_version =
84 : SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_DATA_VERSION;
85 82 : opaque_element_version_section->sm_data_id =
86 : SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_ID_VERSION_SELECTION;
87 82 : opaque_element_version_section->selected_version =
88 82 : spdm_context->connection_info.secured_message_version;
89 : /* Zero Padding*/
90 82 : end = opaque_element_version_section + 1;
91 82 : libspdm_zero_mem(end, (size_t)data_out + final_data_size - (size_t)end);
92 : }
93 :
94 : libspdm_return_t
95 26 : libspdm_process_opaque_data_supported_version_data(libspdm_context_t *spdm_context,
96 : size_t data_in_size,
97 : const void *data_in)
98 : {
99 : const secured_message_opaque_element_table_header_t
100 : *opaque_element_table_header;
101 : const secured_message_opaque_element_supported_version_t
102 : *opaque_element_support_version;
103 : const spdm_version_number_t *versions_list;
104 : spdm_version_number_t common_version;
105 : uint8_t version_count;
106 :
107 : bool result;
108 : const void *get_element_ptr;
109 : size_t get_element_len;
110 :
111 26 : result = false;
112 26 : get_element_ptr = NULL;
113 :
114 26 : if (spdm_context->local_context.secured_message_version.spdm_version_count == 0) {
115 0 : return LIBSPDM_STATUS_SUCCESS;
116 : }
117 :
118 26 : if (data_in_size <
119 26 : libspdm_get_untrusted_opaque_data_supported_version_data_size(spdm_context, 1)) {
120 0 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
121 : }
122 :
123 26 : result = libspdm_get_element_from_opaque_data(
124 : spdm_context, data_in_size,
125 : data_in, SPDM_REGISTRY_ID_DMTF,
126 : SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_ID_SUPPORTED_VERSION,
127 : &get_element_ptr, &get_element_len);
128 26 : if ((!result) || (get_element_ptr == NULL)) {
129 2 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,"get element error!\n"));
130 2 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
131 : }
132 :
133 24 : opaque_element_table_header = (const secured_message_opaque_element_table_header_t*)
134 : get_element_ptr;
135 :
136 : /*check for supported version data*/
137 24 : opaque_element_support_version = (const void *)(opaque_element_table_header + 1);
138 :
139 24 : if ((const uint8_t *)opaque_element_support_version +
140 : sizeof(secured_message_opaque_element_supported_version_t) >
141 24 : (const uint8_t *)opaque_element_table_header + get_element_len) {
142 0 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
143 : }
144 :
145 24 : if (opaque_element_support_version->version_count == 0) {
146 0 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
147 : }
148 :
149 24 : version_count = opaque_element_support_version->version_count;
150 :
151 24 : if ((opaque_element_table_header->vendor_len != 0) ||
152 24 : (opaque_element_table_header->opaque_element_data_len !=
153 24 : sizeof(secured_message_opaque_element_supported_version_t) +
154 24 : sizeof(spdm_version_number_t) * version_count)) {
155 0 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
156 : }
157 :
158 24 : versions_list = (const void *)(opaque_element_support_version + 1);
159 :
160 24 : if ((const uint8_t *)versions_list + sizeof(spdm_version_number_t) >
161 24 : (const uint8_t *)opaque_element_table_header + get_element_len) {
162 0 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
163 : }
164 :
165 24 : result = libspdm_negotiate_connection_version(
166 : &common_version,
167 24 : spdm_context->local_context.secured_message_version.spdm_version,
168 24 : spdm_context->local_context.secured_message_version.spdm_version_count,
169 : versions_list, version_count);
170 24 : if (!result) {
171 0 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
172 : }
173 :
174 24 : libspdm_copy_mem(&(spdm_context->connection_info.secured_message_version),
175 : sizeof(spdm_context->connection_info.secured_message_version),
176 : &(common_version),
177 : sizeof(spdm_version_number_t));
178 :
179 24 : return LIBSPDM_STATUS_SUCCESS;
180 : }
|