Skip to content

Commit

Permalink
This commit supports spdm-requester-emu communicate with other endpoints
Browse files Browse the repository at this point in the history
via MCTP in kernel. It also supports sending single command GET_VERSION
to test the interface.

Tested:
Send command:
    spdm_requester_emu --trans MCTP_KERNEL --eid 20 --cmd GET_VERSION
Sample output:
    spdm_requester_emu version 0.1
    trans - 0x5
    spdm_cmd - 0x01
    connect success!
    context_size - 0x21d8
    libspdm_send_spdm_request[0] msg SPDM_GET_VERSION(0x84), size (0x4):
    0000: 10 84 00 00
    Platform port Transmit transport_type: 00 00 00 05
    Platform port Transmit size: 00 00 00 05
    Platform port Transmit buffer:
        05 10 84 00 00
    Platform port Receive buffer:
        05 10 04 00 00 00 03 00 10 00 11 00 12
    libspdm_receive_spdm_response[0] msg SPDM_VERSION(0x4), size (0xc):
    0000: 10 04 00 00 00 03 00 10 00 11 00 12
    Client stopped

Signed-off-by: Quang Nguyen <[email protected]>
  • Loading branch information
NguyenTanNhutQuang committed Apr 2, 2024
1 parent 9c5af97 commit b6685dc
Show file tree
Hide file tree
Showing 6 changed files with 286 additions and 106 deletions.
200 changes: 133 additions & 67 deletions spdm_emu/spdm_emu_common/command.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
**/

#include "spdm_emu.h"
#include <linux/mctp.h>
#include <errno.h>

/* hack to add MCTP header for PCAP*/
#include "industry_standard/mctp.h"
Expand All @@ -17,6 +19,8 @@ bool m_send_receive_buffer_acquired = false;
uint8_t m_send_receive_buffer[LIBSPDM_MAX_SENDER_RECEIVER_BUFFER_SIZE];
size_t m_send_receive_buffer_size;

uint8_t m_use_eid = 0;
uint8_t m_send_single_spdm_cmd = 0;
/**
* Read number of bytes data in blocking mode.
*
Expand All @@ -31,8 +35,17 @@ bool read_bytes(const SOCKET socket, uint8_t *buffer,

number_received = 0;
while (number_received < number_of_bytes) {
result = recv(socket, (char *)(buffer + number_received),
number_of_bytes - number_received, 0);
if (m_use_transport_layer == SOCKET_TRANSPORT_TYPE_MCTP_KERNEL) {
struct sockaddr_mctp addr = { 0 };
socklen_t addrlen = sizeof(addr);
result = recvfrom(socket, (char *)(buffer + number_received),
number_of_bytes - number_received, MSG_TRUNC,
(struct sockaddr *)&addr, &addrlen);
}
else {
result = recv(socket, (char *)(buffer + number_received),
number_of_bytes - number_received, 0);
}
if (result == -1) {
printf("Receive error - 0x%x\n",
#ifdef _MSC_VER
Expand Down Expand Up @@ -79,31 +92,51 @@ bool read_multiple_bytes(const SOCKET socket, uint8_t *buffer,
uint32_t length;
bool result;

result = read_data32(socket, &length);
if (!result) {
return result;
}
printf("Platform port Receive size: ");
length = ntohl(length);
dump_data((uint8_t *)&length, sizeof(uint32_t));
printf("\n");
length = ntohl(length);

*bytes_received = length;
if (*bytes_received > max_buffer_length) {
printf("buffer too small (0x%x). Expected - 0x%x\n",
max_buffer_length, *bytes_received);
return false;
}
if (length == 0) {
return true;
}
result = read_bytes(socket, buffer, length);
if (!result) {
return result;
if (m_use_transport_layer != SOCKET_TRANSPORT_TYPE_MCTP_KERNEL) {
result = read_data32(socket, &length);
if (!result) {
return result;
}
printf("Platform port Receive size: ");
length = ntohl(length);
dump_data((uint8_t *)&length, sizeof(uint32_t));
printf("\n");
length = ntohl(length);

*bytes_received = length;
if (*bytes_received > max_buffer_length) {
printf("buffer too small (0x%x). Expected - 0x%x\n",
max_buffer_length, *bytes_received);
return false;
}
if (length == 0) {
return true;
}
result = read_bytes(socket, buffer, length);
if (!result) {
return result;
}
} else {
length = recv(socket, NULL, 0, MSG_PEEK | MSG_TRUNC);
if (length == -1) {
printf("Error: %s\n", strerror(errno));
return false;
}
if (length > max_buffer_length - 1) {
printf("buffer too small (0x%x). Expected - 0x%x\n",
max_buffer_length, length);
return false;
}
result = read_bytes(socket, buffer+1, length);
if (!result)
return result;
// mctp kernel receive payload only.
// So add msg_type byte to receive_message
buffer[0] = MCTP_MESSAGE_TYPE_SPDM;
*bytes_received = length + 1;
}
printf("Platform port Receive buffer:\n ");
dump_data(buffer, length);
dump_data(buffer, length + 1);
printf("\n");

return true;
Expand All @@ -118,30 +151,31 @@ bool receive_platform_data(const SOCKET socket, uint32_t *command,
uint32_t transport_type;
uint32_t bytes_received;

result = read_data32(socket, &response);
if (!result) {
return result;
}
*command = response;
printf("Platform port Receive command: ");
response = ntohl(response);
dump_data((uint8_t *)&response, sizeof(uint32_t));
printf("\n");

result = read_data32(socket, &transport_type);
if (!result) {
return result;
}
printf("Platform port Receive transport_type: ");
transport_type = ntohl(transport_type);
dump_data((uint8_t *)&transport_type, sizeof(uint32_t));
printf("\n");
transport_type = ntohl(transport_type);
if (transport_type != m_use_transport_layer) {
printf("transport_type mismatch\n");
return false;
if (m_use_transport_layer != SOCKET_TRANSPORT_TYPE_MCTP_KERNEL) {
result = read_data32(socket, &response);
if (!result) {
return result;
}
*command = response;
printf("Platform port Receive command: ");
response = ntohl(response);
dump_data((uint8_t *)&response, sizeof(uint32_t));
printf("\n");

result = read_data32(socket, &transport_type);
if (!result) {
return result;
}
printf("Platform port Receive transport_type: ");
transport_type = ntohl(transport_type);
dump_data((uint8_t *)&transport_type, sizeof(uint32_t));
printf("\n");
transport_type = ntohl(transport_type);
if (transport_type != m_use_transport_layer) {
printf("transport_type mismatch\n");
return false;
}
}

bytes_received = 0;
result = read_multiple_bytes(socket, receive_buffer, &bytes_received,
(uint32_t)*bytes_to_receive);
Expand Down Expand Up @@ -193,8 +227,25 @@ bool write_bytes(const SOCKET socket, const uint8_t *buffer,

number_sent = 0;
while (number_sent < number_of_bytes) {
result = send(socket, (char *)(buffer + number_sent),
number_of_bytes - number_sent, 0);
if (m_use_transport_layer == SOCKET_TRANSPORT_TYPE_MCTP_KERNEL) {
/* MCTP kernel approach does not support send() syscall
* sendto() is recommanded to send messages currently
* https://discord.com/channels/775381525260664832/775381525260664836/1161513903319158904 */
struct sockaddr_mctp addr = { 0 };
addr.smctp_family = AF_MCTP;
if (m_use_eid != 0)
addr.smctp_addr.s_addr = m_use_eid;
addr.smctp_type = MCTP_MESSAGE_TYPE_SPDM;
addr.smctp_tag = MCTP_TAG_OWNER;
/* we own the tag, and so the kernel will allocate one for us */
result = sendto(socket, (char *)(buffer + number_sent),
number_of_bytes - number_sent, 0,
(struct sockaddr *)&addr, sizeof(addr));
}
else {
result = send(socket, (char *)(buffer + number_sent),
number_of_bytes - number_sent, 0);
}
if (result == -1) {
#ifdef _MSC_VER
if (WSAGetLastError() == 0x2745) {
Expand All @@ -208,6 +259,7 @@ bool write_bytes(const SOCKET socket, const uint8_t *buffer,
errno
#endif
);
printf("Something went wrong, cannot send()! errno = %s\n", strerror(errno));
#ifdef _MSC_VER
}
#endif
Expand Down Expand Up @@ -235,17 +287,25 @@ bool write_multiple_bytes(const SOCKET socket, const uint8_t *buffer,
{
bool result;

result = write_data32(socket, bytes_to_send);
if (!result) {
return result;
if (m_use_transport_layer != SOCKET_TRANSPORT_TYPE_MCTP_KERNEL)
{
result = write_data32(socket, bytes_to_send);
if (!result) {
return result;
}
}
printf("Platform port Transmit size: ");
bytes_to_send = htonl(bytes_to_send);
dump_data((uint8_t *)&bytes_to_send, sizeof(uint32_t));
printf("\n");
bytes_to_send = htonl(bytes_to_send);

result = write_bytes(socket, buffer, bytes_to_send);
if (m_use_transport_layer != SOCKET_TRANSPORT_TYPE_MCTP_KERNEL)
result = write_bytes(socket, buffer, bytes_to_send);
else {
//mctp kernel do not need to send message type in the payload
result = write_bytes(socket, buffer+1, bytes_to_send-1);
}
if (!result) {
return result;
}
Expand All @@ -262,19 +322,25 @@ bool send_platform_data(const SOCKET socket, uint32_t command,
uint32_t request;
uint32_t transport_type;

request = command;
result = write_data32(socket, request);
if (!result) {
return result;
}
printf("Platform port Transmit command: ");
request = htonl(request);
dump_data((uint8_t *)&request, sizeof(uint32_t));
printf("\n");

result = write_data32(socket, m_use_transport_layer);
if (!result) {
return result;
if(m_use_transport_layer != SOCKET_TRANSPORT_TYPE_MCTP_KERNEL)
{
request = command;
result = write_data32(socket, request);
if (!result) {
return result;
}
printf("Platform port Transmit command: ");
request = htonl(request);
dump_data((uint8_t *)&request, sizeof(uint32_t));
printf("\n");
result = write_data32(socket, m_use_transport_layer);
if (!result) {
return result;
}
printf("Platform port Transmit transport_type: ");
transport_type = ntohl(m_use_transport_layer);
dump_data((uint8_t *)&transport_type, sizeof(uint32_t));
printf("\n");
}
printf("Platform port Transmit transport_type: ");
transport_type = ntohl(m_use_transport_layer);
Expand Down
2 changes: 2 additions & 0 deletions spdm_emu/spdm_emu_common/command.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#define SOCKET_TRANSPORT_TYPE_MCTP 0x01
#define SOCKET_TRANSPORT_TYPE_PCI_DOE 0x02
#define SOCKET_TRANSPORT_TYPE_TCP 0x03
/* Support mctp kernel */
#define SOCKET_TRANSPORT_TYPE_MCTP_KERNEL 0x05

#define SOCKET_TCP_NO_HANDSHAKE 0x00
#define SOCKET_TCP_HANDSHAKE 0x01
Expand Down
Loading

0 comments on commit b6685dc

Please sign in to comment.