Skip to content

Harden SPDM 1.4 PSK_FINISH opaque handling with core unit test coverage#3606

Open
czwolak wants to merge 1 commit intoDMTF:mainfrom
czwolak:czwolak/issue-3592-psk-finish-opaque
Open

Harden SPDM 1.4 PSK_FINISH opaque handling with core unit test coverage#3606
czwolak wants to merge 1 commit intoDMTF:mainfrom
czwolak:czwolak/issue-3592-psk-finish-opaque

Conversation

@czwolak
Copy link
Copy Markdown
Contributor

@czwolak czwolak commented Apr 22, 2026

Fix #3592.

  • Harden requester/responder SPDM 1.4 PSK_FINISH opaque validation paths.
  • Align requester SPDM 1.4 opaque format negotiation setup in UT.
  • Keep core opaque boundary/error coverage: req cases 18/19 and rsp cases 17/18.
  • Remove optional requester cases 20/21 and related harness scaffolding.

@czwolak czwolak force-pushed the czwolak/issue-3592-psk-finish-opaque branch from 93d5603 to ce5ae7d Compare April 22, 2026 11:48
@steven-bellock steven-bellock changed the title #3592 Harden SPDM 1.4 PSK_FINISH opaque handling with core UT coverage Harden SPDM 1.4 PSK_FINISH opaque handling with core unit test coverage Apr 22, 2026
status = LIBSPDM_STATUS_INVALID_PARAMETER;
libspdm_release_sender_buffer (spdm_context);
goto error;
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

In current libspdm, we always use ASSERT for SPDM_MAX_OPAQUE_DATA_SIZE check.
You may search others, such as key_exchange, finish.
Why we have to add check here, in this psk_finish?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agree. For outbound requester input-size validation, key_exchange / psk_exchange / finish use LIBSPDM_ASSERT and do not return runtime INVALID_PARAMETER.
I will align psk_finish with existing style by removing the runtime check and keeping ASSERT-only

Comment on lines +191 to +195
if (requester_opaque_data_size != 0) {
status = LIBSPDM_STATUS_INVALID_PARAMETER;
libspdm_release_sender_buffer (spdm_context);
goto error;
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same question.
I think we need use a consistent way to decide when to check and when not to check.
Please refer to opaque data handling in other command.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agree. The requester_opaque_data == NULL && requester_opaque_data_size != 0 runtime error is also not used in peer commands.
I will remove this runtime check for consistency with existing requester command patterns.

Comment on lines +307 to +312
if (((spdm_context->connection_info.algorithm.other_params_support &
SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK) == SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_NONE)
&& (opaque_data_size != 0)) {
status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
goto receive_done;
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is already checked in key_exchange. Why we need to check again?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agree this is redundant with current negotiated state handling and inconsistent with finish/key_exchange response parsing style.
I will remove this extra check to keep behavior/policy consistent.


if ((responder_opaque_data != NULL) && (responder_opaque_data_size != NULL)) {
if (opaque_data_size >= *responder_opaque_data_size) {
if (opaque_data_size > *responder_opaque_data_size) {
Copy link
Copy Markdown
Member

@jyao1 jyao1 Apr 23, 2026

Choose a reason for hiding this comment

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

Good catch!

I notice finish has same issue.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks. Do you think we better create separate follow-up issue or propose "finish" fix within this PR ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I am OK to create another PR.
I just want to ensure 1) all issues are fixed, 2) the solution is consistent, especially the similar ones.
That is why I cross-check other commands.

Copy link
Copy Markdown
Contributor Author

@czwolak czwolak Apr 24, 2026

Choose a reason for hiding this comment

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

Thank you :) can we confirm also another cases?

  1. FINISH - what you found

if (opaque_data_size >= *responder_opaque_data_size) {
status = LIBSPDM_STATUS_BUFFER_TOO_SMALL;
goto receive_done;
}

  1. KEY_EXCHANGE

if (opaque_length >= *responder_opaque_data_size) {
status = LIBSPDM_STATUS_BUFFER_TOO_SMALL;
goto receive_done;
}

  1. PSK_EXCHANGE

if (spdm_response->opaque_length >= *responder_opaque_data_size) {
status = LIBSPDM_STATUS_BUFFER_TOO_SMALL;
goto receive_done;
}

opaque_data_entry_size = 0;
}
spdm_response_size = sizeof(spdm_finish_response_t) + opaque_data_entry_size;
spdm_response_size = sizeof(spdm_psk_finish_response_t) + opaque_data_entry_size;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Good catch!

}

if ((opaque_data_size > SPDM_MAX_OPAQUE_DATA_SIZE) ||
(opaque_data_size > max_opaque_data_size)) {
Copy link
Copy Markdown
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 how it is possible that (opaque_data_size > max_opaque_data_size).

I feel (opaque_data_size > SPDM_MAX_OPAQUE_DATA_SIZE) should be enough.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I recommend keeping both checks:

SPDM_MAX_OPAQUE_DATA_SIZE: protocol/library upper bound
max_opaque_data_size: output-buffer capacity bound
They protect different constraints, so both are valid.

It can happen when the protocol limit and the actual buffer capacity are different.

SPDM_MAX_OPAQUE_DATA_SIZE is a global maximum allowed by libspdm/protocol.
max_opaque_data_size is how many bytes are currently free in this specific response buffer after headers.
So opaque_data_size may still be valid globally, but too large for the current output buffer.
Example: global max is 1024, but current buffer has only 80 bytes left; function generates 120 bytes. Then:

120 <= 1024 (passes global check)
120 > 80 (fails buffer-capacity check)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I am looking at libspdm_psk_finish_rsp_opaque_data() API. opaque_data_size is an IN OUT.
opaque_data_size is already max_opaque_data_size on input.

The output opaque_data_size must be equal or smaller than the input size.
That is why I think it is impossible. Otherwise, the buffer overflow already happened.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

OK, I understand we want to assume IN OUT is working here, if it didn't then it is already too late to detect. I will remove this.

@czwolak czwolak force-pushed the czwolak/issue-3592-psk-finish-opaque branch 2 times, most recently from 38d26ed to 08382fc Compare April 24, 2026 07:57
…erage

- Harden requester/responder SPDM 1.4 PSK_FINISH opaque validation paths.
- Align requester SPDM 1.4 opaque format negotiation setup in UT.
- Keep core opaque boundary/error coverage: req cases 18/19 and rsp cases 17/18.
- Remove optional requester cases 20/21 and related harness scaffolding.

Signed-off-by: Cezary Zwolak <cezary.zwolak@intel.com>
@czwolak czwolak force-pushed the czwolak/issue-3592-psk-finish-opaque branch from 08382fc to be32879 Compare April 24, 2026 08:29
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.

PSK_FINISH/PSK_FINISH_RSP (SPDM 1.4): Opaque-Length Validation and Response Completeness Gaps

2 participants