Skip to content
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
54 changes: 49 additions & 5 deletions doc/multikey.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ while a different key can be restricted to only sign the M1/M2 transcript. As su
endpoint supports multikey, the local endpoint must ensure that it uses the appropriate key and
certificate slot when signing or verifying messages.

## Endpoint Support for Multikey
## libspdm Endpoint Support for Multikey

SPDM allows an endpoint to support multikey in one of three ways.
1. No support at all (`MULTI_KEY_CAP == 0`).
Expand All @@ -19,15 +19,59 @@ Use `libspdm_set_data`, `LIBSPDM_DATA_OTHER_PARAMS_SUPPORT`, and the
`SPDM_ALGORITHMS_MULTI_KEY_CONN` boolean to specify how libspdm should handle the case when the peer
endpoint's multikey support is conditional (`MULTI_KEY_CAP == 2`).

### Multikey Flow for libspdm Requester
## Multikey Flow for Requester

1. Call `libspdm_init_connection` and check that the call is successful.
2. Call `libspdm_get_data` with `LIBSPDM_DATA_MULTI_KEY_CONN_RSP` to determine whether the
2. Proceed through the "Responder Sign / Requester Verify Flow".
3. If Requester's `MULTI_KEY_CAP` is non-zero, then proceed through the
"Requester Sign / Responder Verify Flow".

If Requester's `MULTI_KEY_CAP` is non-zero then both `ENCAP_CAP` and `CERT_CAP` must be set.

### Responder Sign / Requester Verify Flow

1. Call `libspdm_get_data` with `LIBSPDM_DATA_MULTI_KEY_CONN_RSP` to determine whether the
connection utilizes multikey (`true`) or not (`false`). If the value is `true` then continue with
this flow, else the connection behaves in a single key manner.
3. Call `libspdm_get_digest` and check that the call is successful.
4. For each populated certificate chain slot call `libspdm_get_certificate` and check that each call
2. Call `libspdm_get_digest` and check that the call is successful.
3. For each populated certificate chain slot call `libspdm_get_certificate` and check that each call
is successful.
4. Use `libspdm_get_data` with `LIBSPDM_DATA_PEER_KEY_USAGE_BIT_MASK` to query the `KeyUsageMask`
for each populated certificate slot. Use the `SPDM_KEY_USAGE_BIT_MASK_*` macros to determine the
legal messages for that certificate slot and key.

### Requester Sign / Responder Verify Flow

1. If Requester's `MULTI_KEY_CAP == 1` then skip to Step 2. If `MULTI_KEY_CAP == 2` then call
`libspdm_get_data` with `LIBSPDM_DATA_MULTI_KEY_CONN_REQ` to determine whether the connection
utilizes multikey (`true`) or not (`false`). If it is `true` then continue to Step 2.
2. Call `libspdm_set_data` with `LIBSPDM_DATA_LOCAL_KEY_PAIR_ID` and
`LIBSPDM_DATA_LOCAL_KEY_USAGE_BIT_MASK` to map `KeyPairID`s with certificate slots for the
negotiated asymmetric cryptography algorithm (`ReqBaseAsymAlg` or `ReqPqcAsymAlg`) and to
specify the messages a key can be associated with.
- If `MULTI_KEY_CAP == 1` and the Requester supports only one asymmetric cryptography
algorithm for signing then this step can be performed before the connection is
established.
3. Calls to `libspdm_requester_data_sign` then specify the `KeyPairID`.

## Multikey Flow for Responder

### Responder Sign / Requester Verify Flow

1. If Responder's `MULTI_KEY_CAP == 1` then skip to Step 2. If `MULTI_KEY_CAP == 2` then, after
`VCA` has completed and the connection status has transitioned to
`LIBSPDM_CONNECTION_STATE_NEGOTIATED`, call `libspdm_get_data` with
`LIBSPDM_DATA_MULTI_KEY_CONN_RSP` to determine whether the connection utilizes multikey (`true`)
or not (`false`). If it is `true` then continue to Step 2.
2. Call `libspdm_set_data` with `LIBSPDM_DATA_LOCAL_KEY_PAIR_ID` and
`LIBSPDM_DATA_LOCAL_KEY_USAGE_BIT_MASK` to map `KeyPairID`s with certificate slots for the
negotiated asymmetric cryptography algorithm (`BaseAsymSel` or `PqcAsymSel`) and to specify
the messages a key can be associated with.
- If `MULTI_KEY_CAP == 1` and the Responder supports only one asymmetric cryptography
algorithm for signing then this step can be performed before the connection is
established.
3. Calls to `libspdm_responder_data_sign` then specify the `KeyPairID`.
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 to update requester as well, since we pass KeyPairID to libspdm_requester_data_sign

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 will be done as part of the encapsulated flow documentation cleanup.

Copy link
Member

Choose a reason for hiding this comment

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

That will be done as part of the encapsulated flow documentation cleanup.

But we are working on multikey here, not encapsulated flow document.
Looking at "Multikey Flow for libspdm Requester" section, it talks nothing about "encapsulated flow". Why mix them?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah it looks like I can document the multikey encapsulated flow for the Requester side. However it looks like, even ignoring multikey, parts of the encapsulated flow for the Responder side are broken, even on the 3.8 release. I will file an issue for that.

Copy link
Member

Choose a reason for hiding this comment

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

That is fine. You can work on other encapsulated feature later.
Here, my comment is to document same content between requester and responder.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The instructions have been updated. I went with "Requester Sign / Responder Verify Flow" instead of "Encapsulated", although ultimately, if the libspdm Requester is going to sign a message using multikey, it needs to set ENCAP_CAP. Let me know if the new document is clear.


### Requester Sign / Responder Verify Flow
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Document the current flow, that can be replaced later by https://github.com/DMTF/libspdm/blob/main/doc/internal/encapsulated_flow.md.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jyao1 actually, looking at the code for the mutual authentication flow it looks like it is impossible to currently do this with multikey. The Responder Integrator needs to examine LIBSPDM_DATA_PEER_KEY_USAGE_BIT_MASK after the Responder has issued the encapsulated GET_DIGESTS to the Requester. However, from what I can tell, there is no state change or callback that allows this. So it will need to wait for the new encapsulated handling in https://github.com/DMTF/libspdm/blob/main/doc/internal/encapsulated_flow.md.


TBD.