-
Notifications
You must be signed in to change notification settings - Fork 99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
transport: storage: add support for SPDM over the storage binding (DSP0286) #2827
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
@@ -0,0 +1,50 @@ | ||||
/** | ||||
* Copyright Notice: | ||||
* Copyright 2024 DMTF. All rights reserved. | ||||
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md | ||||
**/ | ||||
|
||||
/** | ||||
* Author: Wilfred Mallawa <[email protected]> | ||||
* Alistair Francis <[email protected]> | ||||
**/ | ||||
|
||||
/** @file | ||||
* Definitions of SPDM over the Storage as defined in DSP0286 | ||||
**/ | ||||
|
||||
#ifndef STORAGE_BINDING_H | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we add |
||||
#define STORAGE_BINDING_H | ||||
|
||||
#pragma pack(1) | ||||
|
||||
typedef struct { | ||||
uint16_t data_length; | ||||
uint16_t storage_binding_version; | ||||
uint8_t max_connection_id : 2; | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The codebase avoids bitfields due to ambiguities in the C specification. The current specification calls this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. okay sounds good, do we want to wait on this until the spec is updated then? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, we'll probably discuss this issue at the VF2F meeting today. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. right. Using bitfield is not recommended. I recommend you just using |
||||
uint8_t reserved1[3]; | ||||
uint8_t supported_operations[8]; | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be one byte in the specification if https://github.com/DMTF/SPDM-WG/issues/3609 gets approved. |
||||
uint8_t reserved2[16]; | ||||
} storage_discovery_response_t; | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If this is SPDM storage binding spec, please always use |
||||
|
||||
typedef struct { | ||||
uint16_t data_length; | ||||
uint16_t storage_binding_version; | ||||
uint32_t pending_info_flag; | ||||
uint32_t response_length; | ||||
} storage_pending_info_response_t; | ||||
|
||||
#define STORAGE_SECURITY_BINDING_VERSION 0x1000 | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If this is SPDM storage binding spec, please always use |
||||
#define STORAGE_SECURITY_PROTOCOL_DMTF 0xE8 | ||||
|
||||
#define STORAGE_OPERATION_CODE_DISCOVERY 0x01 | ||||
#define STORAGE_OPERATION_CODE_PENDING_INFO 0x02 | ||||
#define STORAGE_OPERATION_CODE_MESSAGE 0x05 | ||||
#define STORAGE_OPERATION_CODE_SECURED_MESSAGE 0x06 | ||||
|
||||
#define STORAGE_MAX_SIZE_IN_BYTE 0x00100000 | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is defined or inferred from the specification? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not from the spec, we used the DoE transport for layer as a reference for this.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The PCIe specification explicitly defines those values. If they are not in DSP0286 or an underlying specification then they should be removed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. right. only SPDM storage binding spec defined data should be here. Any other implementation definition should NOT be added here. |
||||
#define STORAGE_MAX_SIZE_IN_DW 0x00040000 | ||||
|
||||
#pragma pack() | ||||
|
||||
#endif /* STORAGE_BINDING_H */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,248 @@ | ||
/** | ||
* Copyright Notice: | ||
* Copyright 2024 DMTF. All rights reserved. | ||
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md | ||
**/ | ||
|
||
/** | ||
* Author: Wilfred Mallawa <[email protected]> | ||
* Alistair Francis <[email protected]> | ||
**/ | ||
|
||
#ifndef STORAGE_TRANSPORT_LIB_H | ||
#define STORAGE_TRANSPORT_LIB_H | ||
|
||
#include "library/spdm_common_lib.h" | ||
#include "library/spdm_crypt_lib.h" | ||
|
||
#define LIBSPDM_STORAGE_SEQUENCE_NUMBER_COUNT 0 | ||
#define LIBSPDM_STORAGE_MAX_RANDOM_NUMBER_COUNT 0 | ||
|
||
/* | ||
* SPDM Storage transport binding header for request encoding as defined by | ||
* DSP0286. This header is not specific to any particular storage type, i.e | ||
* SCSI, NVMe or ATA. Instead, it is used to encode requests (host to controller), | ||
* to provide transport specific SPDM information. This information shall then | ||
* be used to generate the storage protocol specific command. Refer to the | ||
* storage specification for field sizes, offsets and application. | ||
* | ||
* As such, this header *shall not* be transmitted as a part of the libspdm | ||
* message, instead be used only as required to generate the storage specific | ||
* command(s). | ||
* | ||
* +-----------------+--------+-------------------+---------+--------+--+ | ||
* | TYPE |Security| Security | INC_512 | Length | | | ||
* | |Protocol| Protocol Specific | | | | | ||
* +-----------------+--------+-------------------+---------+--------+ + | ||
* |Security Protocol| 1 | 2 | 1 | 4 | | | ||
* +-----------------+--------+-------------------+---------+--------+--+ | ||
* | ||
* This structure is publicly defined to provide transport encoding information | ||
* to the caller from transport_message buffer(s). | ||
*/ | ||
#pragma pack(1) | ||
typedef struct { | ||
uint8_t security_protocol; | ||
uint16_t security_protocol_specific; | ||
bool inc_512; | ||
uint32_t length; | ||
} storage_spdm_transport_header; | ||
#pragma pack() | ||
|
||
#define LIBSPDM_STORAGE_TRANSPORT_HEADER_SIZE (1 + 2 + 1 + 4) | ||
#define LIBSPDM_STORAGE_TRANSPORT_TAIL_SIZE (0) | ||
|
||
#define LIBSPDM_STORAGE_CMD_DIRECTION_IF_SEND 0x01 | ||
#define LIBSPDM_STORAGE_CMD_DIRECTION_IF_RECV 0x02 | ||
|
||
/** | ||
* Decode an Security Protocol Command message to a normal message or secured message. | ||
* | ||
* @param session_id Indicates if it is a secured message protected via SPDM session. | ||
* If *session_id is NULL, it is a normal message. | ||
* If *session_id is NOT NULL, it is a secured message. | ||
* @param connection_id Indicates the connection ID of the message. | ||
* @param transport_message_size size in bytes of the transport message data buffer. | ||
* @param transport_message A pointer to a source buffer to store the transport message. | ||
* @param message_size size in bytes of the message data buffer. | ||
* @param message A pointer to a destination buffer to store the message. | ||
* | ||
* @retval RETURN_SUCCESS The message is encoded successfully. | ||
* @retval LIBSPDM_STATUS_INVALID_MSG_SIZE The message is NULL or the transport_message_size is zero. | ||
* @retval LIBSPDM_STATUS_INVALID_MSG_FIELD The message field is incorrect. | ||
**/ | ||
libspdm_return_t libspdm_storage_decode_message(uint32_t **session_id, | ||
uint8_t *connection_id, | ||
size_t transport_message_size, | ||
void *transport_message, | ||
size_t *message_size, | ||
void **message); | ||
/** | ||
* Decode an SPDM or APP message from a storage transport layer message. | ||
* | ||
* For normal SPDM message, it removes the transport layer wrapper, | ||
* For secured SPDM message, it removes the transport layer wrapper, then decrypts and verifies a secured message. | ||
* For secured APP message, it removes the transport layer wrapper, then decrypts and verifies a secured message. | ||
* | ||
* The APP message is decoded from a secured message directly in SPDM session. | ||
* The APP message format is defined by the transport layer. | ||
* Take MCTP as example: APP message == MCTP header (MCTP_MESSAGE_TYPE_SPDM) + SPDM message | ||
* | ||
* @param spdm_context A pointer to the SPDM context. | ||
* @param session_id Indicates if it is a secured message protected via SPDM session. | ||
* If session_id is NULL, it is a normal message. | ||
* If session_id is not NULL, it is a secured message. | ||
* @param is_app_message Indicates if it is an APP message or SPDM message. | ||
* @param is_request_message Indicates if it is a request message. | ||
* @param transport_message_size Size in bytes of the transport message data buffer. | ||
* @param transport_message A pointer to a source buffer to store the transport message. | ||
* For normal message or secured message, it shall point to acquired receiver buffer. | ||
* @param message_size Size in bytes of the message data buffer. | ||
* @param message A pointer to a destination buffer to store the message. | ||
* On input, it shall point to the scratch buffer in spdm_context. | ||
* On output, for normal message, it will point to the original receiver buffer. | ||
* On output, for secured message, it will point to the scratch buffer in spdm_context. | ||
* | ||
* @retval RETURN_SUCCESS The message is decoded successfully. | ||
* @retval LIBSPDM_STATUS_INVALID_MSG_SIZE The message is NULL or the message_size is zero. | ||
* @retval LIBSPDM_STATUS_INVALID_MSG_FIELD The message field is incorrect. | ||
* @retval LIBSPDM_STATUS_UNSUPPORTED_CAP The transport_message is unsupported. | ||
**/ | ||
libspdm_return_t libspdm_transport_storage_decode_message( | ||
void *spdm_context, uint32_t **session_id, | ||
bool *is_app_message, bool is_request_message, | ||
size_t transport_message_size, void *transport_message, | ||
size_t *message_size, void **message); | ||
|
||
|
||
/** | ||
* Encode a normal message or secured message to a storage transport message. | ||
* | ||
* @param session_id Indicates if it is a secured message protected via SPDM session. | ||
* If *session_id is NULL, it is a normal message. | ||
* If *session_id is NOT NULL, it is a secured message. | ||
* @param connection_id Indicates the connection ID of the message. | ||
* @param message_size size in bytes of the message data buffer. | ||
* @param message A pointer to a destination buffer to store the message. | ||
* @param transport_message_size Size in bytes of the transport message data buffer. | ||
* On return, length of the transport message. | ||
* @param transport_message A pointer to a source buffer to store the transport message. | ||
* | ||
* @retval RETURN_SUCCESS The message is encoded successfully. | ||
* @retval LIBSPDM_STATUS_INVALID_MSG_SIZE The message is NULL or the message_size/transport_message_size is zero. | ||
* @retval LIBSPDM_STATUS_INVALID_MSG_FIELD The message field is incorrect. | ||
**/ | ||
libspdm_return_t libspdm_storage_encode_message(const uint32_t *session_id, | ||
uint8_t connection_id, | ||
size_t message_size, void *message, | ||
size_t *transport_message_size, | ||
void **transport_message); | ||
|
||
/** | ||
* Encode an SPDM or APP message into a transport layer message. | ||
* | ||
* @param spdm_context A pointer to the SPDM context. | ||
* @param session_id Indicates if it is a secured message protected via SPDM session. | ||
* If session_id is NULL, it is a normal message. | ||
* If session_id is not NULL, it is a secured message. | ||
* @param is_app_message Indicates if it is an APP message or SPDM message. | ||
* @param is_request_message Indicates if it is a request message. | ||
* @param transport_message_size Size in bytes of the transport message data buffer. | ||
* @param transport_message A pointer to a source buffer to store the transport message. | ||
* For normal message or secured message, it shall point to acquired receiver buffer. | ||
* @param message_size Size in bytes of the message data buffer. | ||
* @param message A pointer to a destination buffer to store the message. | ||
* On input, it shall point to the scratch buffer in spdm_context. | ||
* On output, for normal message, it will point to the original receiver buffer. | ||
* On output, for secured message, it will point to the scratch buffer in spdm_context. | ||
* | ||
* @retval RETURN_SUCCESS The message is decoded successfully. | ||
* @retval LIBSPDM_STATUS_INVALID_MSG_SIZE The message is NULL or the message_size is zero. | ||
* @retval LIBSPDM_STATUS_INVALID_MSG_FIELD The message field is incorrect. | ||
* @retval LIBSPDM_STATUS_UNSUPPORTED_CAP The transport_message is unsupported. | ||
**/ | ||
libspdm_return_t libspdm_transport_storage_encode_message( | ||
void *spdm_context, const uint32_t *session_id, | ||
bool is_app_message, | ||
bool is_request_message, size_t message_size, void *message, | ||
size_t *transport_message_size, void **transport_message); | ||
|
||
/** | ||
* Decode a storage transport management command | ||
* | ||
* @param transport_message_size Size in bytes of the transport message data buffer. | ||
* @param transport_message A pointer to an encoded transport message buffer. | ||
* @param transport_command Storage transport command contained in transport message | ||
* @param length On return, this specifies allocation length | ||
* or transfer length. Depending of if the | ||
* message was an IF_RECV or IF_SEND respectively. | ||
* | ||
* @retval RETURN_SUCCESS The message is decoded successfully. | ||
* @retval LIBSPDM_STATUS_INVALID_MSG_SIZE The message is NULL or the message_size is zero. | ||
* @retval LIBSPDM_STATUS_INVALID_MSG_FIELD The message field is incorrect. | ||
* @retval LIBSPDM_STATUS_UNSUPPORTED_CAP The transport_message is unsupported. | ||
**/ | ||
libspdm_return_t libspdm_transport_storage_decode_management_cmd( | ||
size_t transport_message_size, | ||
const void *transport_message, | ||
uint8_t *transport_command, | ||
uint32_t *length); | ||
|
||
/** | ||
* Encode a storage transport management command, supports only Discovery and | ||
* Pending Info. | ||
* | ||
* @param transport_message_size Size in bytes of the transport message data buffer. | ||
* On return, the length of the encoded message | ||
* @param transport_message A pointer to an encoded transport message buffer. | ||
* @param transport_command Storage transport command contained in transport message | ||
* | ||
* @retval RETURN_SUCCESS The message is decoded successfully. | ||
* @retval LIBSPDM_STATUS_INVALID_MSG_SIZE The message is NULL or the message_size is zero. | ||
* @retval LIBSPDM_STATUS_INVALID_MSG_FIELD The message field is incorrect. | ||
**/ | ||
libspdm_return_t libspdm_transport_storage_encode_management_cmd( | ||
uint8_t cmd_direction, uint8_t transport_operation, | ||
uint8_t connection_id, size_t *transport_message_size, | ||
size_t *allocation_length, void *transport_message); | ||
|
||
/** | ||
* Encode a storage transport pending response. As defined by the DMTF DSP0286 | ||
* | ||
* @param transport_message_size Size in bytes of the transport message data buffer. | ||
* On return, the size of the response | ||
* @param transport_message A pointer to a source buffer to store the transport message. | ||
* @param response_pending If true, the responder has a pending response | ||
* @param pending_response_length Valid only if @response_pending is true, | ||
* specifies the length of the pending message | ||
* in bytes. | ||
* | ||
* @retval RETURN_SUCCESS The message is decoded successfully. | ||
* @retval LIBSPDM_STATUS_INVALID_MSG_SIZE The message is NULL or the message_size is zero. | ||
* @retval LIBSPDM_STATUS_BUFFER_TOO_SMALL @transport_message is too small | ||
**/ | ||
libspdm_return_t libspdm_transport_storage_encode_discovery_response( | ||
size_t *transport_message_size, | ||
void *transport_message); | ||
|
||
/** | ||
* Encode a storage transport pending response. As defined by the DMTF DSP0286 | ||
* | ||
* @param transport_message_size Size in bytes of the transport message data buffer. | ||
* On return, the size of the response | ||
* @param transport_message A pointer to a source buffer to store the transport message. | ||
* @param response_pending If true, the responder has a pending response | ||
* @param pending_response_length Valid only if @response_pending is true, | ||
* specifies the length of the pending message | ||
* in bytes. | ||
* | ||
* @retval RETURN_SUCCESS The message is decoded successfully. | ||
* @retval LIBSPDM_STATUS_INVALID_MSG_SIZE The message is NULL or the message_size is zero. | ||
* @retval LIBSPDM_STATUS_BUFFER_TOO_SMALL @transport_message is too small | ||
**/ | ||
libspdm_return_t libspdm_transport_storage_encode_pending_info_response( | ||
size_t *transport_message_size, | ||
void *transport_message, bool response_pending, | ||
uint32_t pending_response_length); | ||
|
||
#endif /* STORAGE_TRANSPORT_LIB_H */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
cmake_minimum_required(VERSION 3.5) | ||
|
||
INCLUDE_DIRECTORIES(${LIBSPDM_DIR}/include) | ||
|
||
SET(src_spdm_transport_storage_lib | ||
libspdm_storage.c | ||
) | ||
|
||
ADD_LIBRARY(spdm_transport_storage_lib STATIC ${src_spdm_transport_storage_lib}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Usually, we dont put author name in this project.