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 "library/spdm_transport_test_lib.h"
8 : #include "internal/libspdm_common_lib.h"
9 :
10 : /**
11 : * Get sequence number in an SPDM secure message.
12 : *
13 : * This value is transport layer specific.
14 : *
15 : * @param sequence_number The current sequence number used to encode or decode message.
16 : * @param sequence_number_buffer A buffer to hold the sequence number output used in the secured message.
17 : * The size in byte of the output buffer shall be 8.
18 : *
19 : * @return size in byte of the sequence_number_buffer.
20 : * It shall be no greater than 8.
21 : * 0 means no sequence number is required.
22 : **/
23 794 : uint8_t libspdm_test_get_sequence_number(uint64_t sequence_number,
24 : uint8_t *sequence_number_buffer)
25 : {
26 794 : libspdm_copy_mem(sequence_number_buffer, LIBSPDM_TEST_SEQUENCE_NUMBER_COUNT,
27 : &sequence_number, LIBSPDM_TEST_SEQUENCE_NUMBER_COUNT);
28 794 : return LIBSPDM_TEST_SEQUENCE_NUMBER_COUNT;
29 : }
30 :
31 : /**
32 : * Return max random number count in an SPDM secure message.
33 : *
34 : * This value is transport layer specific.
35 : *
36 : * @return Max random number count in an SPDM secured message.
37 : * 0 means no random number is required.
38 : **/
39 466 : uint32_t libspdm_test_get_max_random_number_count(void)
40 : {
41 466 : return LIBSPDM_TEST_MAX_RANDOM_NUMBER_COUNT;
42 : }
43 :
44 : /**
45 : * This function translates the negotiated secured_message_version to a DSP0277 version.
46 : *
47 : * @param secured_message_version The version specified in binding specification and
48 : * negotiated in KEY_EXCHANGE/KEY_EXCHANGE_RSP.
49 : *
50 : * @return The DSP0277 version specified in binding specification,
51 : * which is bound to secured_message_version.
52 : */
53 794 : spdm_version_number_t libspdm_test_get_secured_spdm_version(
54 : spdm_version_number_t secured_message_version)
55 : {
56 794 : return secured_message_version;
57 : }
58 :
59 : /**
60 : * Encode a normal message or secured message to a transport message.
61 : *
62 : * @param session_id Indicates if it is a secured message protected via SPDM session.
63 : * If session_id is NULL, it is a normal message.
64 : * If session_id is NOT NULL, it is a secured message.
65 : * @param message_size size in bytes of the message data buffer.
66 : * @param message A pointer to a source buffer to store the message.
67 : * @param transport_message_size size in bytes of the transport message data buffer.
68 : * @param transport_message A pointer to a destination buffer to store the transport message.
69 : *
70 : * @retval RETURN_SUCCESS The message is encoded successfully.
71 : * @retval RETURN_INVALID_PARAMETER The message is NULL or the message_size is zero.
72 : **/
73 136773 : libspdm_return_t libspdm_test_encode_message(const uint32_t *session_id,
74 : bool need_alignment,
75 : size_t message_size,
76 : void *message,
77 : size_t *transport_message_size,
78 : void **transport_message)
79 : {
80 : size_t aligned_message_size;
81 : size_t alignment;
82 : uint32_t data32;
83 : libspdm_test_message_header_t *test_message_header;
84 :
85 136773 : if (need_alignment) {
86 136307 : alignment = LIBSPDM_TEST_ALIGNMENT;
87 : } else {
88 466 : alignment = 1;
89 : }
90 136773 : aligned_message_size =
91 136773 : (message_size + (alignment - 1)) & ~(alignment - 1);
92 :
93 136773 : LIBSPDM_ASSERT(*transport_message_size >=
94 : aligned_message_size + sizeof(libspdm_test_message_header_t));
95 136773 : if (*transport_message_size <
96 136773 : aligned_message_size + sizeof(libspdm_test_message_header_t)) {
97 0 : *transport_message_size = aligned_message_size +
98 : sizeof(libspdm_test_message_header_t);
99 0 : return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
100 : }
101 :
102 136773 : *transport_message_size =
103 136773 : aligned_message_size + sizeof(libspdm_test_message_header_t);
104 136773 : *transport_message = (uint8_t *)message - sizeof(libspdm_test_message_header_t);
105 136773 : test_message_header = *transport_message;
106 136773 : if (session_id != NULL) {
107 466 : test_message_header->message_type =
108 : LIBSPDM_TEST_MESSAGE_TYPE_SECURED_TEST;
109 466 : data32 = libspdm_read_uint32((const uint8_t *)message);
110 466 : LIBSPDM_ASSERT(*session_id == data32);
111 466 : if (*session_id != data32) {
112 0 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
113 : }
114 : } else {
115 136307 : test_message_header->message_type = LIBSPDM_TEST_MESSAGE_TYPE_SPDM;
116 : }
117 136773 : libspdm_zero_mem((uint8_t *)message + message_size,
118 : aligned_message_size - message_size);
119 136773 : return LIBSPDM_STATUS_SUCCESS;
120 : }
121 :
122 : /**
123 : * Decode a transport message to a normal message or secured message.
124 : *
125 : * @param session_id Indicates if it is a secured message protected via SPDM session.
126 : * If *session_id is NULL, it is a normal message.
127 : * If *session_id is NOT NULL, it is a secured message.
128 : * @param transport_message_size size in bytes of the transport message data buffer.
129 : * @param transport_message A pointer to a source buffer to store the transport message.
130 : * @param message_size size in bytes of the message data buffer.
131 : * @param message A pointer to a destination buffer to store the message.
132 : *
133 : * @retval RETURN_SUCCESS The message is encoded successfully.
134 : * @retval RETURN_INVALID_PARAMETER The message is NULL or the message_size is zero.
135 : **/
136 136444 : libspdm_return_t libspdm_test_decode_message(uint32_t **session_id,
137 : bool need_alignment,
138 : size_t transport_message_size,
139 : void *transport_message,
140 : size_t *message_size, void **message)
141 : {
142 : const libspdm_test_message_header_t *test_message_header;
143 :
144 136444 : LIBSPDM_ASSERT(transport_message_size > sizeof(libspdm_test_message_header_t));
145 136444 : if (transport_message_size <= sizeof(libspdm_test_message_header_t)) {
146 0 : return LIBSPDM_STATUS_INVALID_MSG_SIZE;
147 : }
148 :
149 136444 : test_message_header = transport_message;
150 :
151 136444 : switch (test_message_header->message_type) {
152 328 : case LIBSPDM_TEST_MESSAGE_TYPE_SECURED_TEST:
153 328 : LIBSPDM_ASSERT(session_id != NULL);
154 328 : if (session_id == NULL) {
155 0 : return LIBSPDM_STATUS_INVALID_MSG_FIELD;
156 : }
157 328 : if (transport_message_size <=
158 : sizeof(libspdm_test_message_header_t) + sizeof(uint32_t)) {
159 0 : return LIBSPDM_STATUS_INVALID_MSG_SIZE;
160 : }
161 328 : *session_id = (uint32_t *)((uint8_t *)transport_message +
162 : sizeof(libspdm_test_message_header_t));
163 328 : break;
164 136116 : case LIBSPDM_TEST_MESSAGE_TYPE_SPDM:
165 136116 : if (session_id != NULL) {
166 136116 : *session_id = NULL;
167 : }
168 136116 : break;
169 0 : default:
170 0 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
171 : }
172 :
173 136444 : if (need_alignment) {
174 136144 : LIBSPDM_ASSERT(((transport_message_size - sizeof(libspdm_test_message_header_t)) &
175 : (LIBSPDM_TEST_ALIGNMENT - 1)) == 0);
176 : }
177 :
178 136444 : *message_size = transport_message_size - sizeof(libspdm_test_message_header_t);
179 136444 : *message = (uint8_t *)transport_message + sizeof(libspdm_test_message_header_t);
180 136444 : return LIBSPDM_STATUS_SUCCESS;
181 : }
|