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

Cleanup csrlib #2923

Merged
merged 1 commit into from
Dec 7, 2024
Merged
Show file tree
Hide file tree
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
168 changes: 87 additions & 81 deletions include/hal/library/responder/csrlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,37 +14,36 @@

#if LIBSPDM_ENABLE_CAPABILITY_CSR_CAP
/**
* Gen CSR
*
* @param[in] spdm_context A pointer to the SPDM context.
*
* @param[in] base_hash_algo Indicates the hash algorithm.
* @param[in] base_asym_algo Indicates the signing algorithm.
* @param[in, out] need_reset For input, it gives the value of CERT_INSTALL_RESET_CAP:
* If true, then device needs to be reset to complete the CSR.
* If false, the device doesn`t need to be reset to complete the CSR.
* For output, it specifies whether the device needs to be reset to complete the CSR or not.
*
* @param[in] request A pointer to the SPDM request data.
* @param[in] request_size The size of SPDM request data.
*
* @param[in] requester_info Requester info to generate the CSR.
* @param[in] requester_info_length The length of requester info.
*
* @param[in] opaque_data opaque data to generate the CSR.
* @param[in] opaque_data_length The length of opaque data.
*
* @param[in, out] csr_len For input, csr_len is the size of store CSR buffer.
* For output, csr_len is CSR len for DER format
* @param[in, out] csr_pointer On input, csr_pointer is buffer address to store CSR.
* On output, csr_pointer is address for stored CSR.
* The csr_pointer address will be changed.
*
* @param[in] is_device_cert_model If true, the cert chain is DeviceCert model.
* If false, the cert chain is AliasCert model.
*
* @retval true Success.
* @retval false Failed to gen CSR.
* Generate a PKCS #10 certificate signing request.
*
* @param[in] spdm_context A pointer to the SPDM context.
* @param[in] base_hash_algo Indicates the hash algorithm.
* @param[in] base_asym_algo Indicates the signing algorithm.
* @param[in,out] need_reset On input, indicates the value of CERT_INSTALL_RESET_CAP.
* On output, indicates whether the device needs to be reset (true)
* for the GET_CSR operation to complete.
* @param[in] request A pointer to the SPDM request data.
* @param[in] request_size The size of SPDM request data.
* @param[in] requester_info Requester info used to generate the CSR.
* @param[in] requester_info_length The length, in bytes, of requester_info.
* @param[in] opaque_data Requester opaque data used to generate the CSR.
* @param[in] opaque_data_length The length, in bytes, of opaque_data.
* @param[in,out] csr_len On input, the size, in bytes, of the buffer to store the
* CSR.
* On output, the size, in bytes, of the CSR.
* @param[in,out] csr_pointer A pointer to the buffer to store the CSR.
* @param[in] is_device_cert_model If true, the certificate chain is the DeviceCert model.
* If false, the certificate chain is the AliasCert model.
* @param[out] is_busy If true, indicates that the CSR cannot be generated at
* this time, but it may be successful in a later call. The
* function's return value must be false if this parameter is
* true.
* @param[out] unexpected_request If true, then request is different than the request that
* triggered a ResetRequired error response. The function's
* return value must be false if this parameter is true.
*
* @retval true CSR generated successfully.
* @retval false Failed to generate CSR.
**/
extern bool libspdm_gen_csr(
#if LIBSPDM_HAL_PASS_SPDM_CONTEXT
Expand All @@ -55,57 +54,60 @@ extern bool libspdm_gen_csr(
uint8_t *requester_info, size_t requester_info_length,
uint8_t *opaque_data, uint16_t opaque_data_length,
size_t *csr_len, uint8_t *csr_pointer,
bool is_device_cert_model);
bool is_device_cert_model
#if LIBSPDM_SET_CERT_CSR_PARAMS
, bool *is_busy, bool *unexpected_request
#endif
);

/**
* Gen CSR, which is used for SPDM 1.3
*
* If the device need reset to gen csr, the all case is in the table.
* | Overwrite | Req CSRTrackingTag | Pending CSR | Reset | Res Action |
* |-----------|---------------------|-------------|-------|------------------------------|
* | No | 0 | No | - | ResetRequired |
* | No | 0 | Yes | - | ResetRequired or Busy |
* | No | Non-0 | No Match | - | Unexpected |
* | No | Non-0 | Match | Before| Busy |
* | No | Non-0 | Match | After | CSR |
* | Yes | 0 | No | - | ResetRequired |
* | Yes | 0 | Yes | - | ResetRequired |
* | Yes | Non-0 | - | - | Invalid |
*
* @param[in] spdm_context A pointer to the SPDM context.
*
* @param[in] base_hash_algo Indicates the hash algorithm.
* @param[in] base_asym_algo Indicates the signing algorithm.
* @param[in, out] need_reset For input, it gives the value of CERT_INSTALL_RESET_CAP:
* If true, then device needs to be reset to complete the CSR.
* If false, the device doesn`t need to be reset to complete the CSR.
* For output, it specifies whether the device needs to be reset to complete the CSR or not.
*
* @param[in] request A pointer to the SPDM request data.
* @param[in] request_size The size of SPDM request data.
*
* @param[in] requester_info Requester info to generate the CSR.
* @param[in] requester_info_length The length of requester info.
*
* @param[in] opaque_data opaque data to generate the CSR.
* @param[in] opaque_data_length The length of opaque data.
*
* @param[in, out] csr_len For input, csr_len is the size of store CSR buffer.
* For output, csr_len is CSR len for DER format
* @param[in, out] csr_pointer On input, csr_pointer is buffer address to store CSR.
* On output, csr_pointer is address for stored CSR.
* The csr_pointer address will be changed.
*
* @param[in] req_cert_model indicates the desired certificate model of the CSR
*
* @param[in, out] req_csr_tracking_tag For input, this field shall contain the CSRTrackingTag of the associated GET_CSR request.
* For output, this field indicate responder available csr_tracking_tag.
* @param[in] req_key_pair_id Indicates the desired key pair associated with the CSR.
* @param[in] overwrite If set, the Responder shall stop processing any existing GET_CSR request and
* overwrite it with this request
*
* @retval true Success.
* @retval false Failed to gen CSR.
* Generate a PKCS #10 certificate signing request for SPDM versions 1.3 and higher.
*
* Table for parameters and results when device requires a reset to process CSRs.
* Only valid if Responder sets CERT_INSTALL_RESET_CAP.
*
* | Overwrite | CSRTrackingTag | Pending CSR | Reset | Resulting Action |
* |-----------| ---------------|-------------|-------|------------------------------|
* | No | 0 | No | - | Return true |
* | No | 0 | Yes | - | Assert need_reset or is_busy |
* | No | Non-0 | No Match | - | Assert unexpected_request |
* | No | Non-0 | Match | Before| Assert is_busy |
* | No | Non-0 | Match | After | Return true |
* | Yes | 0 | - | - | Assert need_reset |
*
* @param[in] spdm_context A pointer to the SPDM context.
* @param[in] base_hash_algo Indicates the hash algorithm.
* @param[in] base_asym_algo Indicates the signing algorithm.
* @param[in,out] need_reset On input, indicates the value of CERT_INSTALL_RESET_CAP.
* On output, indicates whether the device needs to be reset (true)
* for the GET_CSR operation to complete. If true then
* req_csr_tracking_tag, on output, must be non-zero.
* @param[in] request A pointer to the SPDM request data.
* @param[in] request_size The size of SPDM request data.
* @param[in] requester_info Requester info used to generate the CSR.
* @param[in] requester_info_length The length, in bytes, of requester_info.
* @param[in] opaque_data Requester opaque data used to generate the CSR.
* @param[in] opaque_data_length The length, in bytes, of opaque_data.
* @param[in,out] csr_len On input, the size, in bytes, of the buffer to store the
* CSR.
* On output, the size, in bytes, of the CSR.
* @param[in,out] csr_pointer A pointer to the buffer to store the CSR.
* @param[in] req_cert_model Indicates the desired certificate model of the CSR.
* @param[in,out] req_csr_tracking_tag On input, the CSRTrackingTag of the GET_CSR request.
* On output, the CSRTrackingTag for the ResetRequired error.
* @param[in] req_key_pair_id Indicates the desired key pair associated with the CSR.
* @param[in] overwrite If set, the Responder shall stop processing any existing
* GET_CSR request and overwrite it with this request.
* @param[out] is_busy If true, indicates that the CSR cannot be generated at
* this time, but it may be successful in a later call. The
* function's return value must be false if this parameter is
* true.
* @param[out] unexpected_request If true, then request is different than the request that
* triggered a ResetRequired error response. The function's
* return value must be false if this parameter is true.
*
* @retval true CSR generated successfully.
* @retval false Failed to generate CSR.
**/

#if LIBSPDM_ENABLE_CAPABILITY_CSR_CAP_EX
Expand All @@ -121,7 +123,11 @@ extern bool libspdm_gen_csr_ex(
uint8_t req_cert_model,
uint8_t *req_csr_tracking_tag,
uint8_t req_key_pair_id,
bool overwrite);
bool overwrite
#if LIBSPDM_SET_CERT_CSR_PARAMS
, bool *is_busy, bool *unexpected_request
#endif
);
#endif /*LIBSPDM_ENABLE_CAPABILITY_CSR_CAP_EX*/
#endif /* LIBSPDM_ENABLE_CAPABILITY_CSR_CAP */

Expand Down
39 changes: 29 additions & 10 deletions library/spdm_responder_lib/libspdm_rsp_csr.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ libspdm_return_t libspdm_get_response_csr(libspdm_context_t *spdm_context,
uint8_t *requester_info;
bool need_reset;
bool is_device_cert_model;
bool is_busy;
bool unexpected_request;
uint8_t csr_tracking_tag;

spdm_request = request;
Expand Down Expand Up @@ -138,10 +140,6 @@ libspdm_return_t libspdm_get_response_csr(libspdm_context_t *spdm_context,
}
}

need_reset = libspdm_is_capabilities_flag_supported(
spdm_context, false, 0,
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_INSTALL_RESET_CAP);

result = libspdm_verify_req_info(requester_info, requester_info_length);
if (!result) {
return libspdm_generate_error_response(
Expand All @@ -165,7 +163,14 @@ libspdm_return_t libspdm_get_response_csr(libspdm_context_t *spdm_context,
csr_len = *response_size - sizeof(spdm_csr_response_t);
csr_p = (uint8_t*)(spdm_response + 1);

need_reset = libspdm_is_capabilities_flag_supported(
spdm_context, false, 0,
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_INSTALL_RESET_CAP);

is_busy = false;
unexpected_request = false;
csr_tracking_tag = 0;

if (libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_13) {
#if LIBSPDM_ENABLE_CAPABILITY_CSR_CAP_EX
const bool overwrite =
Expand Down Expand Up @@ -215,7 +220,11 @@ libspdm_return_t libspdm_get_response_csr(libspdm_context_t *spdm_context,
requester_info, requester_info_length,
opaque_data, opaque_data_length,
&csr_len, csr_p, req_cert_model,
&csr_tracking_tag, key_pair_id, overwrite);
&csr_tracking_tag, key_pair_id, overwrite
#if LIBSPDM_SET_CERT_CSR_PARAMS
, &is_busy, &unexpected_request
#endif
);
#else
return libspdm_generate_error_response(
spdm_context,
Expand All @@ -232,16 +241,27 @@ libspdm_return_t libspdm_get_response_csr(libspdm_context_t *spdm_context,
&need_reset, request, request_size,
requester_info, requester_info_length,
opaque_data, opaque_data_length,
&csr_len, csr_p, is_device_cert_model);
&csr_len, csr_p, is_device_cert_model
#if LIBSPDM_SET_CERT_CSR_PARAMS
, &is_busy, &unexpected_request
#endif
);
}

LIBSPDM_ASSERT(!(is_busy && unexpected_request));
LIBSPDM_ASSERT(!(is_busy || unexpected_request) || !result);

if (!result) {
if ((csr_tracking_tag == 0xFF) &&
(libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_13)) {
if (is_busy) {
return libspdm_generate_error_response(
spdm_context,
SPDM_ERROR_CODE_BUSY, 0,
response_size, response);
} else if (unexpected_request) {
return libspdm_generate_error_response(
spdm_context,
SPDM_ERROR_CODE_UNEXPECTED_REQUEST, 0,
response_size, response);
} else {
return libspdm_generate_error_response(
spdm_context,
Expand All @@ -255,8 +275,7 @@ libspdm_return_t libspdm_get_response_csr(libspdm_context_t *spdm_context,

if (libspdm_is_capabilities_flag_supported(
spdm_context, false, 0,
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_INSTALL_RESET_CAP) &&
need_reset) {
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_INSTALL_RESET_CAP) && need_reset) {
return libspdm_generate_error_response(spdm_context,
SPDM_ERROR_CODE_RESET_REQUIRED, csr_tracking_tag,
response_size, response);
Expand Down
12 changes: 10 additions & 2 deletions os_stub/spdm_device_secret_lib_null/lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,11 @@ bool libspdm_gen_csr(
uint8_t *requester_info, size_t requester_info_length,
uint8_t *opaque_data, uint16_t opaque_data_length,
size_t *csr_len, uint8_t *csr_pointer,
bool is_device_cert_model)
bool is_device_cert_model
#if LIBSPDM_SET_CERT_CSR_PARAMS
, bool *is_busy, bool *unexpected_request
#endif
)
{
return false;
}
Expand All @@ -222,7 +226,11 @@ bool libspdm_gen_csr_ex(
uint8_t req_cert_model,
uint8_t *csr_tracking_tag,
uint8_t req_key_pair_id,
bool overwrite)
bool overwrite
#if LIBSPDM_SET_CERT_CSR_PARAMS
, bool *is_busy, bool *unexpected_request
#endif
)
{
return false;
}
Expand Down
20 changes: 16 additions & 4 deletions os_stub/spdm_device_secret_lib_sample/csr.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,11 @@ bool libspdm_gen_csr(
uint8_t *requester_info, size_t requester_info_length,
uint8_t *opaque_data, uint16_t opaque_data_length,
size_t *csr_len, uint8_t *csr_pointer,
bool is_device_cert_model)
bool is_device_cert_model
#if LIBSPDM_SET_CERT_CSR_PARAMS
, bool *is_busy, bool *unexpected_request
#endif
)
{
bool result;
uint8_t *cached_last_csr_request;
Expand Down Expand Up @@ -293,7 +297,11 @@ bool libspdm_gen_csr_ex(
uint8_t req_cert_model,
uint8_t *req_csr_tracking_tag,
uint8_t req_key_pair_id,
bool overwrite)
bool overwrite
#if LIBSPDM_SET_CERT_CSR_PARAMS
, bool *is_busy, bool *unexpected_request
#endif
)
{
bool result;
uint8_t *cached_last_csr_request;
Expand Down Expand Up @@ -327,7 +335,9 @@ bool libspdm_gen_csr_ex(
if (*req_csr_tracking_tag == 0) {
if (available_csr_tracking_tag == 0) {
/*no available tracking tag*/
*req_csr_tracking_tag = 0xFF;
#if LIBSPDM_SET_CERT_CSR_PARAMS
*is_busy = true;
Copy link
Contributor

Choose a reason for hiding this comment

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

The comment above said "no available tracking tag" so I am confused how does this imply "device is busy".
Would you help clarify this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That comes from

If the Responder requires a reset to process a GET_CSR request, but does not have any available CSRTrackingTags, it shall respond with an ERROR message of ErrorCode=Busy.

Copy link
Contributor

Choose a reason for hiding this comment

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

Got it, thanks!

#endif
return false;
} else {
flag = false;
Expand Down Expand Up @@ -406,7 +416,9 @@ bool libspdm_gen_csr_ex(
return true;
} else {
/*the device is busy*/
*req_csr_tracking_tag = 0xFF;
#if LIBSPDM_SET_CERT_CSR_PARAMS
*is_busy = true;
#endif
return false;
}
}
Expand Down
16 changes: 8 additions & 8 deletions unit_test/test_spdm_responder/csr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1628,10 +1628,10 @@ void libspdm_test_responder_csr_case14(void **state)
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
assert_int_equal(response_size, sizeof(spdm_error_response_t));
spdm_response = (void *)response;
assert_int_equal(spdm_response->header.request_response_code,
SPDM_ERROR);
assert_int_equal(spdm_response->header.param1,
SPDM_ERROR_CODE_BUSY);
assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
(LIBSPDM_SET_CERT_CSR_PARAMS) ?
assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_BUSY) :
assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST);
assert_int_equal(spdm_response->header.param2, 0);
#else
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
Expand Down Expand Up @@ -1793,10 +1793,10 @@ void libspdm_test_responder_csr_case15(void **state)
assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
assert_int_equal(response_size, sizeof(spdm_error_response_t));
spdm_response = (void *)response;
assert_int_equal(spdm_response->header.request_response_code,
SPDM_ERROR);
assert_int_equal(spdm_response->header.param1,
SPDM_ERROR_CODE_BUSY);
assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
(LIBSPDM_SET_CERT_CSR_PARAMS) ?
assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_BUSY) :
assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST);
assert_int_equal(spdm_response->header.param2, 0);


Expand Down
Loading