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

Add verify cert callback function for DiceTcbInfo #2672

Merged
merged 1 commit into from
May 21, 2024

Conversation

Wenxing-hou
Copy link
Contributor

Refer the spec: https://trustedcomputinggroup.org/wp-content/uploads/DICE-Attestation-Architecture-Version-1.1-Revision-18_pub.pdf ,
add verify cert callback function for cert DiceTcbInfo extension check.

@Wenxing-hou Wenxing-hou force-pushed the add_DiceTcbInfo branch 2 times, most recently from 3cef1fd to 488a782 Compare April 24, 2024 02:44
@jyao1 jyao1 added the test For tests and testing infrastructure label Apr 25, 2024
void *spdm_root_cert_for_dicetcbinfo;
size_t spdm_root_cert_size_for_dicetcbinfo;

spdm_context = (void *)malloc(libspdm_get_context_size());

Choose a reason for hiding this comment

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

The code should handle cases where malloc fails and returns NULL.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks. I have add the code to handle the failed case.

/*vendorInfo*/
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
LIBSPDM_CRYPTO_ASN1_CONTEXT_SPECIFIC + 8);
if (result) {

Choose a reason for hiding this comment

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

Why there is no check for vendorInfo and flags?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because there is no vendorInfo and flags reference. The check will skip.

Choose a reason for hiding this comment

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

What if the verifier would like to check vendorInfo and/or flags against references?

Because there is no vendorInfo and flags reference. The check will skip.

Copy link
Member

Choose a reason for hiding this comment

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

Please note, this is only reference implementation.

In a real production, the integrator can decide to add more fields to check, or skip some fields.

int32_t length;
size_t obj_len;
uint8_t *end;

Copy link

@xiaoyuruan xiaoyuruan Apr 26, 2024

Choose a reason for hiding this comment

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

General: we can't assume that the adopter code will provide reference values for all TCBinfo components hardcoded above (m_libspdm_dice_tcbinfo_xyz). If a reference is not provided, this function should skip mem_equal() for that component, even if the component is present in the TcbInfo extension.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. The code assume only follow reference will be provided. And the other components will be skip even if existing in cert.

/*vendor: INTC*/
/*model: S3M GNR*/
/*version: 000200000000008B*/
/*svn*/
/*layer*/
/*fwids*/
/*type*/

Choose a reason for hiding this comment

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

I was saying that the code should not require hardcoded references of these components (vendor, model, version, etc.). For example, the verifier can choose to hardcode reference for only "version" because the verifier only cares about version.

Copy link
Member

Choose a reason for hiding this comment

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

Please note, this test is only reference implementation, to demonstrate how to do the alias cert verification.

The integrator should decide what to do - input as parameter, or hardcode somewhere.

LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
if (result) {
/*verify Dice TCB info*/
result = libspdm_verify_cert_dicetcbinfo(tem_ptr, obj_len + (ptr - tem_ptr));

Choose a reason for hiding this comment

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

The "m_libspdm_must_have_dice_tcb_info" is a global that applies to all certs in the chain, but TcbInfo is usually present and required for some certs (e.g., Alias cert).

Copy link
Member

Choose a reason for hiding this comment

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

Please note, this is reference implementation. We cannot handle all difference use cases.

The integrator should choose what to do in the final production, based on their own use case.

@jyao1
Copy link
Member

jyao1 commented Apr 29, 2024

@xiaoyuruan, I would like to provide a general comment: This is only reference implementation to demonstrate how to do the alias cert check. If you have one specific use case to cover, please describe it clearly. We can cover that. That is not a problem.

However, it is impossible to cover all use cases, which is NOT the goal of this PR.

@xiaoyuruan
Copy link

@xiaoyuruan, I would like to provide a general comment: This is only reference implementation to demonstrate how to do the alias cert check. If you have one specific use case to cover, please describe it clearly. We can cover that. That is not a problem.

However, it is impossible to cover all use cases, which is NOT the goal of this PR.

OK that's fine. Please document all assumptions of the implementation (maybe in the readme file?), so reviewers and verifier integrators have a proper expectation.
For example:

  • TcbInfo is required for either all certificates or none certificates (controlled by m_libspdm_must_have_dice_tcb_info).
  • If a TcbInfo component is present in cert, then there must be a reference hardcoded for this component.
  • etc.

@Wenxing-hou Wenxing-hou force-pushed the add_DiceTcbInfo branch 2 times, most recently from 89ce60a to 17ab69d Compare April 29, 2024 02:47
@steven-bellock
Copy link
Contributor

@Wenxing-hou @jyao1 please file a separate issue for OpenSSL's validation of certificates with critical OIDs.

@jyao1
Copy link
Member

jyao1 commented Apr 30, 2024

@xiaoyuruan, I would like to provide a general comment: This is only reference implementation to demonstrate how to do the alias cert check. If you have one specific use case to cover, please describe it clearly. We can cover that. That is not a problem.
However, it is impossible to cover all use cases, which is NOT the goal of this PR.

OK that's fine. Please document all assumptions of the implementation (maybe in the readme file?), so reviewers and verifier integrators have a proper expectation. For example:

  • TcbInfo is required for either all certificates or none certificates (controlled by m_libspdm_must_have_dice_tcb_info).
  • If a TcbInfo component is present in cert, then there must be a reference hardcoded for this component.
  • etc.

Yes. That is good suggestion. We should add readme to document that.

I think current assumption is:

  1. Reference TcbInfo.
  • Only one reference TcbInfo entry is provided by the integrator. (Multiple reference TcbInfo is NOT supported in this PR.)
  1. Reported TcbInfo
  • The number of reported TcbInfo must match the number of reference TcbInfo.
  1. TcbInfo Matching
  • Each of the reported TcbInfo must fully match each of the reference TcbInfo with same order.
  1. TcbInfo Field
  • The reported TcbInfo must include all fields in the reference TcbInfo. If a field in the reference TcbInfo does not exist in the reported TcbInfo, the verification must fail.
  • The reported TcbInfo could include more fields which do not exist in the reference TcbInfo. The extra fields in the reported TcbInfo must be ignored and NOT validated, and they must not impact the final result.

@Wenxing-hou , please double check if above assumption is satisfied.
@xiaoyuruan , please review and comment if above assumption is OK.

@Wenxing-hou Wenxing-hou force-pushed the add_DiceTcbInfo branch 4 times, most recently from 9c56e14 to 642defe Compare April 30, 2024 06:07
@Wenxing-hou
Copy link
Contributor Author

@xiaoyuruan, I would like to provide a general comment: This is only reference implementation to demonstrate how to do the alias cert check. If you have one specific use case to cover, please describe it clearly. We can cover that. That is not a problem.
However, it is impossible to cover all use cases, which is NOT the goal of this PR.

OK that's fine. Please document all assumptions of the implementation (maybe in the readme file?), so reviewers and verifier integrators have a proper expectation. For example:

  • TcbInfo is required for either all certificates or none certificates (controlled by m_libspdm_must_have_dice_tcb_info).
  • If a TcbInfo component is present in cert, then there must be a reference hardcoded for this component.
  • etc.

Yes. That is good suggestion. We should add readme to document that.

I think current assumption is:

  1. Reference TcbInfo.
  • Only one reference TcbInfo entry is provided by the integrator. (Multiple reference TcbInfo is NOT supported in this PR.)
  1. Reported TcbInfo
  • Reported TcbInfo must be in at least one certificate.
  • If none of the certificates includes TcbInfo, the verification must fail.
  1. TcbInfo Matching
  • At least one reported TcbInfo must fully match the reference TcbInfo.
  • If none of the reported TcbInfos matches all fields in the reference TcbInfo, the verification must fail.
  • Once one of the reported TcbInfo fully matches, the verification must pass and the rests of reported TcbInfo must be ignored.
  1. TcbInfo Field
  • The reported TcbInfo must include all fields in the reference TcbInfo. If a field in the reference TcbInfo does not exist in the reported TcbInfo, the verification must fail.
  • The reported TcbInfo could include more fields which do not exist in the reference TcbInfo. The extra fields in the reported TcbInfo must be ignored and NOT validated, and they must not impact the final result.

@Wenxing-hou , please double check if above assumption is satisfied. @xiaoyuruan , please review and comment if above assumption is OK.

Hi Jiewen. I have checked the code, the code logic match the implementation assumption.

while (ptr < end) {
cert_dice_tcb_info_size = 0;
tem_ptr = ptr;
result = libspdm_asn1_get_tag(&ptr, end, &obj_len,
LIBSPDM_CRYPTO_ASN1_SEQUENCE |
LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
if (result) {
/*verify Dice TCB info*/
result = libspdm_verify_cert_dicetcbinfo(tem_ptr, obj_len + (ptr - tem_ptr),
&cert_dice_tcb_info_size);
if (!result) {
if (cert_dice_tcb_info_size == 0) {
return false;
}
} else {
if (cert_dice_tcb_info_size != 0) {
cert_chain_have_matched_dice = true;
}
}
/* Move to next cert*/
ptr += obj_len;
} else {
return false;
}
}
if (m_libspdm_must_have_dice_tcb_info && !cert_chain_have_matched_dice) {
return false;
}

And I have added the Readme for the Callback function.

@Wenxing-hou Wenxing-hou force-pushed the add_DiceTcbInfo branch 3 times, most recently from 3b21c2f to c1c1faa Compare April 30, 2024 06:23
LIBSPDM_CRYPTO_ASN1_CONSTRUCTED);
if (result) {
/*verify Dice TCB info*/
result = libspdm_verify_cert_dicetcbinfo(tem_ptr, obj_len + (ptr - tem_ptr),

Choose a reason for hiding this comment

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

If libspdm_verify_cert_dicetcbinfo returns FALSE and cert_dice_tcb_info_size!=0, tracing this function further, I think there is an error ("store buffer too small"- not sure what it meant). Is it necessary to handle the error 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.

Thanks.
Now libspdm_verify_cert_dicetcbinfo hard code the DiceTcbInfo buffer size, and the code categorizes the buffer error to invalid error.

spdm_dice_tcb_info_size = 256;
*spdm_get_dice_tcb_info_size = 0;
result = libspdm_x509_get_extension_data(cert, cert_size,
m_libspdm_tcg_dice_tcbinfo_oid,
sizeof(m_libspdm_tcg_dice_tcbinfo_oid),
spdm_dice_tcb_info, &spdm_dice_tcb_info_size);
if (!result) {
return false;
} else if (spdm_dice_tcb_info_size == 0) {
return true;
}

I don't think it is necessary to handle this issue.

Comment on lines 10 to 18
2) **Reported TcbInfo**

- Reported TcbInfo must be in at least one certificate.
- If none of the certificates includes TcbInfo, the verification must fail.
3) **TcbInfo Matching**

- At least one reported TcbInfo must fully match the reference TcbInfo.
- If none of the reported TcbInfos matches all fields in the reference TcbInfo, the verification must fail.
- Once one of the reported TcbInfo fully matches, the verification must pass and the rests of reported TcbInfo must be ignored.
Copy link
Member

Choose a reason for hiding this comment

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

Please change to below:

2) Reported TcbInfo
  * The number of reported TcbInfo must match the number of reference TcbInfo.
3) TcbInfo Matching
  * Each of the reported TcbInfo must fully match each of the reference TcbInfo with same order.

} else {
if (cert_dice_tcb_info_size != 0) {
cert_chain_have_matched_dice = true;
number_dice_tcb_info++;
Copy link
Member

@jyao1 jyao1 May 7, 2024

Choose a reason for hiding this comment

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

This is NOT correct.

The rule is to make sure the TcbInfo number matches, not the right TcbInfo number matches.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks.
I have updated the logic: change the number when the cert have DiceTcbInfo.

if (!result) {
if (cert_dice_tcb_info_size == 0) {
return false;
}
number_dice_tcb_info++;
} else {
if (cert_dice_tcb_info_size != 0) {
cert_chain_have_matched_dice = true;
number_dice_tcb_info++;
}
}

@Wenxing-hou Wenxing-hou force-pushed the add_DiceTcbInfo branch 2 times, most recently from 20640c8 to c9312da Compare May 9, 2024 02:21
@jyao1
Copy link
Member

jyao1 commented May 10, 2024

please resolve conflict.

@steven-bellock
Copy link
Contributor

I'll provide my comments tomorrow. Was busy today.

@Wenxing-hou
Copy link
Contributor Author

please resolve conflict.

Thanks. I have fixed the conflict.

@Wenxing-hou
Copy link
Contributor Author

I'll provide my comments tomorrow. Was busy today.

Thanks for your support.

@PrithviAPai
Copy link

@Wenxing-hou we have libspdm_verify_spdm_cert_chain_func where we can register libspdm_verify_spdm_cert_chain_with_dice as callback to verify the DICE certificates right ?

@PrithviAPai
Copy link

Also if we pass sample cert chain from libspdm unit test. Will this function verify that ?
We might have cases where on some devices we will have DICE certificates and rest without dice extension.

@steven-bellock
Copy link
Contributor

So I think there are three separate issues / pull requests here.

  1. Testing that Integrator-provided callbacks are registered properly.
  2. Testing that libspdm properly calls and handles the output of Integrator-provided functions.
    • For example there is currently no coverage for verify_peer_spdm_cert_chain in GET_CERTIFICATE and encapsulated GET_CERTIFICATE.
    • This would be tested in the unit tests for the corresponding SPDM message. For example test_spdm_requester/get_certificate.c.
    • Note that the callback function used for testing need not be elaborate. It can just return true or false.
  3. Sample implementation of a callback function.
    • This belongs, at a minimum, in os_stub/ or maybe make a new example_code/ directory or in the spdm-emu repository.

@Wenxing-hou
Copy link
Contributor Author

@Wenxing-hou we have libspdm_verify_spdm_cert_chain_func where we can register libspdm_verify_spdm_cert_chain_with_dice as callback to verify the DICE certificates right ?

Yes, the libspdm_verify_spdm_cert_chain_with_dice as callback need to register to libspdm_verify_spdm_cert_chain_func .
Please use the function libspdm_register_verify_spdm_cert_chain_func to register.
In the libspdm_register_verify_spdm_cert_chain_func comment, you can know:
This function must be called after libspdm_init_context, and before any SPDM communication.

Thanks.

@Wenxing-hou
Copy link
Contributor Author

Also if we pass sample cert chain from libspdm unit test. Will this function verify that ? We might have cases where on some devices we will have DICE certificates and rest without dice extension.

Please refer to the Readme.md:
https://github.com/DMTF/libspdm/blob/7d13678fec5b5c3479956b7c67cde2cf7cb053cb/unit_test/test_spdm_callback/README.md#implementation-assumption

Thanks.

@Wenxing-hou
Copy link
Contributor Author

So I think there are three separate issues / pull requests here.

  1. Testing that Integrator-provided callbacks are registered properly.

  2. Testing that libspdm properly calls and handles the output of Integrator-provided functions.

    • For example there is currently no coverage for verify_peer_spdm_cert_chain in GET_CERTIFICATE and encapsulated GET_CERTIFICATE.
    • This would be tested in the unit tests for the corresponding SPDM message. For example test_spdm_requester/get_certificate.c.
    • Note that the callback function used for testing need not be elaborate. It can just return true or false.
  3. Sample implementation of a callback function.

    • This belongs, at a minimum, in os_stub/ or maybe make a new example_code/ directory or in the spdm-emu repository.

Thanks for your suggestion. I will do the corresponding work based on your feedback.

@steven-bellock
Copy link
Contributor

Let's make sure @jyao1 approves first.

@jyao1
Copy link
Member

jyao1 commented May 13, 2024

So I think there are three separate issues / pull requests here.

  1. Testing that Integrator-provided callbacks are registered properly.

Agree. Please file a new issue.

  1. Testing that libspdm properly calls and handles the output of Integrator-provided functions.

    • For example there is currently no coverage for verify_peer_spdm_cert_chain in GET_CERTIFICATE and encapsulated GET_CERTIFICATE.
    • This would be tested in the unit tests for the corresponding SPDM message. For example test_spdm_requester/get_certificate.c.
    • Note that the callback function used for testing need not be elaborate. It can just return true or false.

Agree. Please file a new issue.

  1. Sample implementation of a callback function.

    • This belongs, at a minimum, in os_stub/ or maybe make a new example_code/ directory or in the spdm-emu repository.

Agree. Please move this to os_stub/spdm_cert_verify_callback_sample. Please only do this in this PR.

@Wenxing-hou
Copy link
Contributor Author

Wenxing-hou commented May 13, 2024

So I think there are three separate issues / pull requests here.

  1. Testing that Integrator-provided callbacks are registered properly.

Agree. Please file a new issue.

  1. Testing that libspdm properly calls and handles the output of Integrator-provided functions.

    • For example there is currently no coverage for verify_peer_spdm_cert_chain in GET_CERTIFICATE and encapsulated GET_CERTIFICATE.
    • This would be tested in the unit tests for the corresponding SPDM message. For example test_spdm_requester/get_certificate.c.
    • Note that the callback function used for testing need not be elaborate. It can just return true or false.

Agree. Please file a new issue.

  1. Sample implementation of a callback function.

    • This belongs, at a minimum, in os_stub/ or maybe make a new example_code/ directory or in the spdm-emu repository.

Agree. Please move this to os_stub/spdm_cert_verify_callback_sample. Please only do this in this PR.

For the first feedback, I have submitted the issue: #2695
For the second feedback, I have submitted the issue: #2696

For the third feedback, I have move this to os_stub/spdm_cert_verify_callback_sample. Thanks!

* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/

#include <stdarg.h>
Copy link
Contributor

Choose a reason for hiding this comment

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

Trim the headers to those that are actually used.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks. I have deleted the unused header.

* License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
**/

#ifndef __SPDM_CERT_VERIFY_CALLBACK_INTERNAL_H__
Copy link
Contributor

Choose a reason for hiding this comment

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

__SPDM_CERT_VERIFY_CALLBACK_INTERNAL_H__ -> SPDM_CERT_VERIFY_CALLBACK_INTERNAL_H

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks. I have fixed the MACRO.


#include "library/spdm_crypt_lib.h"
#include "spdm_crypt_ext_lib/spdm_crypt_ext_lib.h"
#include "spdm_crypt_ext_lib/cryptlib_ext.h"
Copy link
Contributor

Choose a reason for hiding this comment

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

Trim the headers to those that are actually used.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks. I have deleted the unused header.

@@ -0,0 +1,37 @@
## This is reference implementation to verify CertChain DiceTcbInfo extension.
Copy link
Contributor

Choose a reason for hiding this comment

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

This file should be in os_stub/spdm_cert_verify_callback_sample.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks. I have moved the README to os_stub.

@@ -0,0 +1,140 @@
/**
Copy link
Contributor

Choose a reason for hiding this comment

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

This directory should be called unit_test/test_spdm_sample.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks. I have changed the folder name.

free(file_data);
}

int libspdm_crypt_lib_setup(void **state)
Copy link
Contributor

Choose a reason for hiding this comment

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

All these instances of *_crypt_lib_* need to be renamed to *_spdm_sample_*.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks. I have changed the name.

Refer the spec
https://trustedcomputinggroup.org/resource/dice-attestation-architecture/
add verify cert callback function for Cert extentison DiceTcbInfo check.

Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
@jyao1 jyao1 merged commit 5fb242b into DMTF:main May 21, 2024
97 checks passed
@Wenxing-hou Wenxing-hou deleted the add_DiceTcbInfo branch June 25, 2024 03:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
test For tests and testing infrastructure
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants