Skip to content

CAPABILITIES: Add SupportedAlgorithms #2968

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

ShitalJumbad
Copy link
Contributor

fix #2279

@ShitalJumbad ShitalJumbad force-pushed the fix-2279 branch 3 times, most recently from a061ee9 to c0d1cd5 Compare January 25, 2025 03:08
Copy link
Contributor

@steven-bellock steven-bellock left a comment

Choose a reason for hiding this comment

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

Still need to figure out how this information is conveyed to the Integrator.

@ShitalJumbad ShitalJumbad force-pushed the fix-2279 branch 11 times, most recently from d8be4bf to edf4eaa Compare February 13, 2025 01:06
@@ -271,10 +271,98 @@ libspdm_return_t libspdm_get_response_capabilities(libspdm_context_t *spdm_conte
spdm_context->local_context.capability.max_spdm_msg_size;
}

Copy link
Contributor

Choose a reason for hiding this comment

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

As a basic validation step, need to check that if negotiated version is >= 1.3 and Param1[0] is set then the Requester's CHUNK_CAP is also set.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added above.

SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP)) {
index++;
}
spdm_response_size = sizeof(spdm_capabilities_response_t)+
Copy link
Contributor

Choose a reason for hiding this comment

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

This also includes ExtAsym and ExtHash. In addition the ExtAsymCount and ExtHashCount should be validated with respect to the response size.

} 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.

if (spdm_response_size < sizeof(spdm_capabilities_response_t)) {
status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
goto receive_done;
}
} else if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
if (spdm_response_size < (sizeof(spdm_capabilities_response_t) -
sizeof(spdm_supported_algorithms_block_t))) {
Copy link
Member

Choose a reason for hiding this comment

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

If you remove spdm_supported_algorithms_block_t from definition, then you dont need to change here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

spdm_supported_algorithms_block_t should be part of the definition for specificati1.3 versions as per the specifications?

if (spdm_response_size < sizeof(spdm_capabilities_response_t) -
sizeof(spdm_response->data_transfer_size) - sizeof(spdm_response->max_spdm_msg_size)) {
if (spdm_response_size < (sizeof(spdm_capabilities_response_t) -
sizeof(spdm_supported_algorithms_block_t) -
Copy link
Member

Choose a reason for hiding this comment

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

If you remove spdm_supported_algorithms_block_t from definition, then you dont need to change here.

index++;
}
spdm_response_size = sizeof(spdm_capabilities_response_t)+
index*sizeof(spdm_negotiate_algorithms_common_struct_table_t);
Copy link
Member

Choose a reason for hiding this comment

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

I dont understand. Why index is calculated according to the CAP???

Copy link
Contributor Author

Choose a reason for hiding this comment

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

corrected.

Comment on lines 440 to 472
spdm_supported_algorithms_block_t *src = &spdm_response->supported_algorithms;
spdm_responder_supported_algorithms_t *dst = supported_algs;
uint8_t *src_bytes = (uint8_t *)src;

dst->measurement_specification = src->measurement_specification;
dst->other_params_support = src->other_params_support;
dst->base_asym_algo = src->base_asym_algo;
dst->base_hash_algo = src->base_hash_algo;
dst->ext_asym_count = src->ext_asym_count;
dst->ext_hash_count = src->ext_hash_count;
dst->mel_specification = src->mel_specification;

if (src->ext_asym_count > SPDM_ALGORITHMS_MAX_NUM_EXT_ASYM_COUNT ||
src->ext_hash_count > SPDM_ALGORITHMS_MAX_NUM_EXT_HASH_COUNT ||
src->param1 > SPDM_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG) {
return LIBSPDM_STATUS_INVALID_MSG_FIELD;
}

size_t offset = sizeof(spdm_supported_algorithms_block_t);

if (src->ext_asym_count > 0) {
size_t copy_size = src->ext_asym_count * sizeof(spdm_extended_algorithm_t);
libspdm_copy_mem(dst->ext_asym,
sizeof(dst->ext_asym),
src_bytes + offset,
copy_size);
offset += copy_size;
}

if (src->ext_hash_count > 0) {
size_t copy_size = src->ext_hash_count * sizeof(spdm_extended_algorithm_t);
libspdm_copy_mem(dst->ext_hash,
sizeof(dst->ext_hash),
src_bytes + offset,
copy_size);
offset += copy_size;
}

if (src->param1 > 0) {
size_t copy_size = src->param1 *
sizeof(spdm_negotiate_algorithms_common_struct_table_t);
libspdm_copy_mem(dst->struct_table,
sizeof(dst->struct_table),
src_bytes + offset,
copy_size);
}
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 why we need to copy by bytes.

Whey not just calculate the whole buffer size, then use one copy_mem() for the whole buffer?

Copy link
Contributor

Choose a reason for hiding this comment

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

The intent is that the Integrator does not have to parse these fields and spdm_responder_supported_algorithms_t contains only the fields the Integrator is interested in.

Copy link
Member

Choose a reason for hiding this comment

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

Ah, I think that I overlooked spdm_responder_supported_algorithms_t.

I feel this definition is problematic, because we will keep changing the data structure whenever we have new fields, e.g. in SPDM 1.4.

To keep the interface simple, we can

  1. return everything as is to the integrator.
  2. (or) record individual inside of context, then allow the integrator retrieve based on the need.

Copy link
Contributor

Choose a reason for hiding this comment

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

I feel this definition is problematic, because we will keep changing the data structure whenever we have new fields

That's fine, we do that already with the _ex functions.

record individual inside of context, then allow the integrator retrieve based on the need.

The spdm_context? This is ephemeral data and should not increase the size of the context. Once the Integrator has consumed it then they don't need to retrieve it again, at least from the connection's context.

Copy link
Member

Choose a reason for hiding this comment

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

That's fine, we do that already with the _ex functions.

But current _ex function only add more parameter, we did not change any data structure. Here, you must change a data structure.
Also, with current data structure, the integrator cannot know which field is valid or invalid. They should be based on the version.

If you really like to use this style API, here is my thought (combining other feedback):

  1. Move the structure definition to request lib (because it is NOT defined in SPDM spec)
  2. Add a SPDM version as the first field for the data structure, to indicate the structure version.
  3. Add SPDM version as prefix or suffix for the data structure name, as indicated by the first SPDM version field.
  4. Add Length field in the function as input or output (which allows the integrator or libspdm checking the structure size.)

Something like:

libspdm_get_supported_algorithms (
void spdm_context,
// on input: indicate the max size of the responder_supported_algorithms_buffer
// on output: indicate the valid size of the responder_supported_algorithms_buffer
size_t *responder_supported_algorithms_length,
// on output: the consumer must get the spdm_version to know the version of the data structure
void *responder_supported_algorithms_buffer);

typedef struct {
    uint8 spdm_version; // must be 0x13
    ...... // rest version 1.3 specific field
} libspdm_responder_supported_algorithms_13_t;

typedef struct {
    uint8 spdm_version; // must be 0x14
    ...... // rest version 1.4 specific field
} libspdm_responder_supported_algorithms_14_t;

Copy link
Contributor

Choose a reason for hiding this comment

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

spdm_version should be an output parameter from libspdm_get_supported_algorithms.

} 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

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.

Comment on lines 440 to 472
spdm_supported_algorithms_block_t *src = &spdm_response->supported_algorithms;
spdm_responder_supported_algorithms_t *dst = supported_algs;
uint8_t *src_bytes = (uint8_t *)src;

dst->measurement_specification = src->measurement_specification;
dst->other_params_support = src->other_params_support;
dst->base_asym_algo = src->base_asym_algo;
dst->base_hash_algo = src->base_hash_algo;
dst->ext_asym_count = src->ext_asym_count;
dst->ext_hash_count = src->ext_hash_count;
dst->mel_specification = src->mel_specification;

if (src->ext_asym_count > SPDM_ALGORITHMS_MAX_NUM_EXT_ASYM_COUNT ||
src->ext_hash_count > SPDM_ALGORITHMS_MAX_NUM_EXT_HASH_COUNT ||
src->param1 > SPDM_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG) {
return LIBSPDM_STATUS_INVALID_MSG_FIELD;
}

size_t offset = sizeof(spdm_supported_algorithms_block_t);

if (src->ext_asym_count > 0) {
size_t copy_size = src->ext_asym_count * sizeof(spdm_extended_algorithm_t);
libspdm_copy_mem(dst->ext_asym,
sizeof(dst->ext_asym),
src_bytes + offset,
copy_size);
offset += copy_size;
}

if (src->ext_hash_count > 0) {
size_t copy_size = src->ext_hash_count * sizeof(spdm_extended_algorithm_t);
libspdm_copy_mem(dst->ext_hash,
sizeof(dst->ext_hash),
src_bytes + offset,
copy_size);
offset += copy_size;
}

if (src->param1 > 0) {
size_t copy_size = src->param1 *
sizeof(spdm_negotiate_algorithms_common_struct_table_t);
libspdm_copy_mem(dst->struct_table,
sizeof(dst->struct_table),
src_bytes + offset,
copy_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 intent is that the Integrator does not have to parse these fields and spdm_responder_supported_algorithms_t contains only the fields the Integrator is interested in.


/* 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.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added struct_table_count instead of param1 to make it more intuitive to the integrator.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

param2 is probably not necessary to add?

@ShitalJumbad ShitalJumbad force-pushed the fix-2279 branch 2 times, most recently from f386e11 to 317ce9f Compare April 3, 2025 23:31
Comment on lines +79 to +80
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.

Need to add version of the structure.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Could you please help me understand the motivation for this and adding version to the name?

Copy link
Member

Choose a reason for hiding this comment

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

uint8_t struct_table_count;
libspdm_supported_algorithms_alg_struct_t
struct_table[SPDM_NEGOTIATE_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG];
} libspdm_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.

Need to add version to the name.

Copy link
Member

Choose a reason for hiding this comment

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

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,
libspdm_responder_supported_algorithms_t *supported_algs);
Copy link
Member

@jyao1 jyao1 Apr 9, 2025

Choose a reason for hiding this comment

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

Need to use void * for supported_algs, because the structure may be changed in the future version.
Also add length for the function.

Copy link
Member

Choose a reason for hiding this comment

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

* @retval RETURN_DEVICE_ERROR A device error occurs when communicates with the device.
**/
libspdm_return_t libspdm_get_supported_algorithms(
void *spdm_context, libspdm_responder_supported_algorithms_t *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.

Need to use void * for responder_supported_algorithms, because the structure may be changed in the future version.
Also add length for the function.

Copy link
Member

Choose a reason for hiding this comment

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

uint8_t struct_table_count;
libspdm_supported_algorithms_alg_struct_t
struct_table[SPDM_NEGOTIATE_ALGORITHMS_MAX_NUM_STRUCT_TABLE_ALG];
} libspdm_responder_supported_algorithms_t;
Copy link
Contributor

Choose a reason for hiding this comment

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

This needs to be in spdm_requester_lib.h.

@@ -12,6 +12,7 @@ extern "C" {
#endif

#include "library/spdm_common_lib.h"
#include "internal/libspdm_common_lib.h"
Copy link
Contributor

Choose a reason for hiding this comment

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

This needs to be removed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[SPDM 1.3] CAPABILITIES: Add SupportedAlgorithms
4 participants