Skip to content
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

CAPABILITIES: Add SupportedAlgorithms #2968

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions doc/api/requester_api.md
Original file line number Diff line number Diff line change
@@ -31,6 +31,29 @@ returns early with value not equal to `LIBSPDM_STATUS_SUCCESS` then the SPDM con
before attempting establish a new connection.
<br/><br/>

---
### libspdm_get_supported_algorithms
---

### Description
Sends the `GET_VERSION` and `GET_CAPABILITIES` requests, where GET_CAPABILITIES.Param1[0] is set.
If the Responder supports this extended capability, the Responder will include the Supported
Algorithms Block in its CAPABILITIES response. If the requester wishes to continue with the
connection, they can call `libspdm_init_connection` to restart the connection process.

### Parameters

**spdm_context**<br/>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs to include the new parameters.

The SPDM context.

### Details
Before calling this function, the integrator must ensure that the SPDM context is initialized
with the necessary configuration, including the requester's capabilities and supported
cryptographic algorithms. When this function returns with the value `RETURN_SUCCESS`,
the SPDM context can be queried to determine the capabilities and algorithms supported
by the responder. If this function returns with a value not equal to `RETURN_SUCCESS`,
the SPDM context should be reset before attempting to establish a new connection.
<br/><br/>

---
### libspdm_get_digest
70 changes: 56 additions & 14 deletions include/industry_standard/spdm.h
Original file line number Diff line number Diff line change
@@ -161,8 +161,61 @@ typedef struct {
uint32_t max_spdm_msg_size;
} spdm_get_capabilities_request_t;

/* SPDM GET_CAPABILITIES response*/
/* SPDM extended algorithm */
typedef struct {
uint8_t registry_id;
uint8_t reserved;
uint16_t algorithm_id;
} spdm_extended_algorithm_t;

typedef struct {
uint8_t alg_type;
uint8_t alg_count;
uint16_t alg_supported;
} spdm_negotiate_algorithms_common_struct_table_t;

/* SPDM supported algorithms block */
typedef struct {
uint8_t param1; /* Number of Algorithms Structure Tables */
uint8_t param2; /* Reserved */
uint16_t length;
uint8_t measurement_specification;
uint8_t other_params_support;
uint32_t base_asym_algo;
uint32_t base_hash_algo;
uint8_t reserved2[12];
uint8_t ext_asym_count;
uint8_t ext_hash_count;
uint8_t reserved3;
uint8_t mel_specification;
/* Followed by dynamic arrays for ext_asym, ext_hash, and struct_tableif needed
* spdm_extended_algorithm_t ext_asym[ext_asym_count];
* spdm_extended_algorithm_t ext_hash[ext_hash_count];
* spdm_negotiate_algorithms_common_struct_table_t struct_table[
* SPDM_NEGOTIATE_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG];*/
} spdm_supported_algorithms_block_t;

/* Specification states that total Extended algorithms count is less than or equal to 20*/
#define SPDM_ALGORITHMS_MAX_NUM_EXT_ASYM_COUNT 20
Copy link
Contributor

@steven-bellock steven-bellock Mar 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually can just use SPDM_NEGOTIATE_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG instead of SPDM_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if we need to add SPDM version number here.

The MAX counter value maybe changed in different version.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is in the older specifications but it is an equation.

ExtAsymCount + ExtHashCount + ExtAlgCount2 + ExtAlgCount3 + ExtAlgCount4 + ExtAlgCount5 <= 20

So for spdm.h there can be

/* Maximum value for the sum of ExtAsymCount + ExtHashCount + ExtAlgCount2 + ExtAlgCount3 + ExtAlgCount4 + ExtAlgCount5 */
#define SPDM_ALGORITHMS_EXT_ALG_MAX_SUM 20

but that can be a separate issue. libspdm currently does not check that, but that does not need to be in this pull request. @ShitalJumbad you can remove SPDM_ALGORITHMS_MAX_NUM_EXT_ASYM_COUNT and SPDM_ALGORITHMS_MAX_NUM_EXT_HASH_COUNT from this pull request.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filed #3019.

#define SPDM_ALGORITHMS_MAX_NUM_EXT_HASH_COUNT 20
#define SPDM_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG 4

/* SPDM supported algorithms by responder */
typedef struct {
uint8_t measurement_specification;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest to add param1 and param2.
At least param1 means the Number of Algorithms Structure Tables
Otherwise, this information is lost.

uint8_t other_params_support;
uint32_t base_asym_algo;
uint32_t base_hash_algo;
uint8_t ext_asym_count;
uint8_t ext_hash_count;
uint8_t mel_specification;
spdm_extended_algorithm_t ext_asym[SPDM_ALGORITHMS_MAX_NUM_EXT_ASYM_COUNT];
spdm_extended_algorithm_t ext_hash[SPDM_ALGORITHMS_MAX_NUM_EXT_HASH_COUNT];
spdm_negotiate_algorithms_common_struct_table_t struct_table[
SPDM_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG];
} spdm_responder_supported_algorithms_t;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is NOT defined in SPDM specification.
I think it should be moved to requester lib or common lib.

Also, we should have version control for this structure, as it will be changed in new version.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be moved to requester lib

Agreed.


/* SPDM GET_CAPABILITIES response*/
typedef struct {
spdm_message_header_t header;
/* param1 == RSVD
@@ -174,6 +227,8 @@ typedef struct {
/* Below field is added in 1.2.*/
uint32_t data_transfer_size;
uint32_t max_spdm_msg_size;
/* Below field is added in 1.3.*/
spdm_supported_algorithms_block_t supported_algorithms;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe just comment this field?

This size is NOT accurate anyway.

Copy link
Contributor

@steven-bellock steven-bellock Mar 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is consistent with the other structs where they expand with each SPDM version.

This size is NOT accurate anyway.

This uses spdm_supported_algorithms_block_t which is accurate. spdm_responder_supported_algorithms_t, which is returned to the Integrator, would be inaccurate.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses spdm_supported_algorithms_block_t which is accurate.

I don't think so, the spdm_supported_algorithms_block_t does not include the extended algorithms and struct table, which are variable length.

} spdm_capabilities_response_t;

#define SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12 42
@@ -357,12 +412,6 @@ typedef struct {
#define SPDM_NEGOTIATE_ALGORITHMS_ALG_SUPPORTED_AEAD_12_MASK 0x000f
#define SPDM_NEGOTIATE_ALGORITHMS_ALG_SUPPORTED_REQ_BASE_ASYM_ALG_12_MASK 0x0fff

typedef struct {
uint8_t alg_type;
uint8_t alg_count;
uint16_t alg_supported;
} spdm_negotiate_algorithms_common_struct_table_t;


/* SPDM NEGOTIATE_ALGORITHMS request base_asym_algo/REQ_BASE_ASYM_ALG */
#define SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 0x00000001
@@ -481,13 +530,6 @@ typedef struct {
/*opaque_element_table_t opaque_list[];*/
} spdm_general_opaque_data_table_header_t;

/* SPDM extended algorithm */
typedef struct {
uint8_t registry_id;
uint8_t reserved;
uint16_t algorithm_id;
} spdm_extended_algorithm_t;

/* SPDM registry_id */
#define SPDM_REGISTRY_ID_DMTF 0x0
#define SPDM_REGISTRY_ID_TCG 0x1
7 changes: 5 additions & 2 deletions include/internal/libspdm_requester_lib.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* Copyright Notice:
* Copyright 2021-2024 DMTF. All rights reserved.
* Copyright 2021-2025 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/

@@ -133,6 +133,7 @@ libspdm_return_t libspdm_get_version(libspdm_context_t *spdm_context,
* This function sends GET_CAPABILITIES and receives CAPABILITIES.
*
* @param spdm_context A pointer to the SPDM context.
* @param get_supported_algorithms If true, indicates that the requester wants the responder to include its supported algorithms in the CAPABILITIES response.
* @param RequesterCTExponent RequesterCTExponent to the GET_CAPABILITIES request.
* @param RequesterFlags RequesterFlags to the GET_CAPABILITIES request.
* @param ResponderCTExponent ResponderCTExponent from the CAPABILITIES response.
@@ -141,7 +142,9 @@ libspdm_return_t libspdm_get_version(libspdm_context_t *spdm_context,
* @retval RETURN_SUCCESS The GET_CAPABILITIES is sent and the CAPABILITIES is received.
* @retval RETURN_DEVICE_ERROR A device error occurs when communicates with the device.
**/
libspdm_return_t libspdm_get_capabilities(libspdm_context_t *spdm_context);
libspdm_return_t libspdm_get_capabilities(libspdm_context_t *spdm_context,
bool get_supported_algorithms,
spdm_responder_supported_algorithms_t *supported_algs);

/**
* This function sends NEGOTIATE_ALGORITHMS and receives ALGORITHMS.
15 changes: 14 additions & 1 deletion include/library/spdm_requester_lib.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* Copyright Notice:
* Copyright 2021-2024 DMTF. All rights reserved.
* Copyright 2021-2025 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/

@@ -491,6 +491,19 @@ libspdm_return_t libspdm_start_session(void *spdm_context, bool use_psk,
uint8_t *heartbeat_period,
void *measurement_hash);

/**
* Sends the `GET_VERSION` and `GET_CAPABILITIES` requests, where GET_CAPABILITIES.Param1[0] is set
* If the Responder supports this extended capability, the Responder will include the Supported
* Algorithms Block in its CAPABILITIES response.
*
* @param spdm_context The SPDM context.
*
* @retval RETURN_SUCCESS The connection is initialized successfully.
* @retval RETURN_DEVICE_ERROR A device error occurs when communicates with the device.
**/
libspdm_return_t libspdm_get_supported_algorithms(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function needs to return the supported algorithms to the caller, presumably as a struct that looks a bit like spdm_supported_algorithms_block_t, but without the params and whatnot.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use spdm_responder_supported_algorithms_t instead of void.

void *spdm_context, void *responder_supported_algorithms);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need have responder_supported_algorithms_buffer_length parameter to indicate the input buffer size.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The expectation is that spdm_responder_supported_algorithms_t provides all the space needed.

Copy link
Member

@jyao1 jyao1 Mar 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The expectation is that spdm_responder_supported_algorithms_t provides all the space needed.

I don't think so. spdm_responder_supported_algorithms_t does not include the extended algorithms and struct table, which are variable length.


/**
* This function sends KEY_EXCHANGE/FINISH or PSK_EXCHANGE/PSK_FINISH to start an SPDM Session.
*
49 changes: 47 additions & 2 deletions library/spdm_requester_lib/libspdm_req_communication.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* Copyright Notice:
* Copyright 2021-2024 DMTF. All rights reserved.
* Copyright 2021-2025 DMTF. All rights reserved.
* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/

@@ -19,7 +19,7 @@ libspdm_return_t libspdm_init_connection(void *spdm_context, bool get_version_on
}

if (!get_version_only) {
status = libspdm_get_capabilities(context);
status = libspdm_get_capabilities(context, false, NULL);
if (LIBSPDM_STATUS_IS_ERROR(status)) {
return status;
}
@@ -31,6 +31,51 @@ libspdm_return_t libspdm_init_connection(void *spdm_context, bool get_version_on
return LIBSPDM_STATUS_SUCCESS;
}

libspdm_return_t libspdm_get_supported_algorithms(void *spdm_context,
void *responder_supported_algorithms)
{
libspdm_return_t status;
libspdm_context_t *context;
spdm_responder_supported_algorithms_t *algorithms;
bool has_version_1_3_or_above;
size_t index;

context = spdm_context;
algorithms = responder_supported_algorithms;
has_version_1_3_or_above = false;

/* Pre-check: Verify requester supports at least one version >= 1.3 */
for (index = 0; index < context->local_context.version.spdm_version_count; index++) {
if (context->local_context.version.spdm_version[index] >= SPDM_MESSAGE_VERSION_13) {
has_version_1_3_or_above = true;
break;
}
}
LIBSPDM_ASSERT(has_version_1_3_or_above);
if (!has_version_1_3_or_above) {
return LIBSPDM_STATUS_UNSUPPORTED_CAP;
}

LIBSPDM_ASSERT((context->local_context.capability.flags &
SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP) != 0);

status = libspdm_get_version(context, NULL, NULL);
if (LIBSPDM_STATUS_IS_ERROR(status)) {
return status;
}

if (context->connection_info.version < SPDM_MESSAGE_VERSION_13) {
return LIBSPDM_STATUS_UNSUPPORTED_CAP;
}

status = libspdm_get_capabilities(context, true, algorithms);
if (LIBSPDM_STATUS_IS_ERROR(status)) {
return status;
}

return LIBSPDM_STATUS_SUCCESS;
}

#if (LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP) || (LIBSPDM_ENABLE_CAPABILITY_PSK_CAP)
libspdm_return_t libspdm_start_session(void *spdm_context, bool use_psk,
const void *psk_hint,
Loading