UnitTest/TestSpdmResponder/TestSpdmResponderCertificate.c
/**
  Test 9: request Offset and Length at the boundary of maximum integer values
  Expected Behavior: generate correctly formed Certficate messages, including its PortionLength and RemainderLength fields
**/
Test 9: request Offset and Length at the boundary of maximum integer values
Expected Behavior: generate correctly formed Certficate messages, including its PortionLength and RemainderLength fields
Test 9 : request Offset and Length at the boundary of maximum integer values Expected Behavior : generate correctly formed Certficate messages including its PortionLength and RemainderLength fields
void TestSpdmResponderCertificateCase9(void **state) {
  RETURN_STATUS        Status;
  SPDM_TEST_CONTEXT    *SpdmTestContext;
  SPDM_DEVICE_CONTEXT  *SpdmContext;
  UINTN                ResponseSize;
  UINT8                Response[MAX_SPDM_MESSAGE_BUFFER_SIZE];
  SPDM_CERTIFICATE_RESPONSE *SpdmResponse;
  SPDM_ERROR_RESPONSE  *SpdmResponseError;
  VOID                 *Data;
  UINTN                DataSize;
  UINT16               TestSizes[] =   {(UINT16)(-1), 0, +1, 
                                        (UINT16)(-1), 0, +1,
                                        (UINT16)(MAX_INT8-1), MAX_INT8, (UINT16)(MAX_INT8+1),
                                        (UINT16)(MAX_UINT8-1), MAX_UINT8,
                                        (UINT16)(MAX_INT16-1), MAX_INT16, (UINT16)(MAX_INT16+1),
                                        (UINT16)(MAX_UINT16-1), MAX_UINT16
                                       };
  UINT16               ExpectedChunkSize;
  UINT16               ExpectedRemainder;
  SpdmTestContext = *state;
  SpdmContext = SpdmTestContext->SpdmContext;
  SpdmTestContext->CaseId = 0x9;
  SpdmContext->ConnectionInfo.ConnectionState = SpdmConnectionStateAfterDigests;
  SpdmContext->LocalContext.Capability.Flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
  ReadResponderPublicCertificateChain (mUseHashAlgo, mUseAsymAlgo, &Data, &DataSize, NULL, NULL);
  SpdmContext->LocalContext.LocalCertChainProvision[0] = Data;
  SpdmContext->LocalContext.LocalCertChainProvisionSize[0] = DataSize;
  SpdmContext->LocalContext.SlotCount = 1;
  TestSizes[0] += (UINT16)(TestSizes[0] + DataSize);
  TestSizes[1] += (UINT16)(TestSizes[1] + DataSize);
  TestSizes[2] += (UINT16)(TestSizes[2] + DataSize);
  for(int i=0; i<sizeof(TestSizes)/sizeof(TestSizes[0]); i++) {
    TEST_DEBUG_PRINT("i:%d TestSizes[i]=Length:%u\n",i, TestSizes[i]);
    mSpdmGetCertificateRequest3.Length = TestSizes[i];
    for(int j=0; j<sizeof(TestSizes)/sizeof(TestSizes[0]); j++) {
      TEST_DEBUG_PRINT("\tj:%d TestSizes[j]=Offset:%u\n",j, TestSizes[j]);
      mSpdmGetCertificateRequest3.Offset = TestSizes[j];
      ResetManagedBuffer (&SpdmContext->Transcript.MessageB);
      ResponseSize = sizeof(Response);
      Status = SpdmGetResponseCertificate (SpdmContext, mSpdmGetCertificateRequest3Size, &mSpdmGetCertificateRequest3, &ResponseSize, Response);
      assert_int_equal (Status, RETURN_SUCCESS);
      if(mSpdmGetCertificateRequest3.Offset >= DataSize) {
        SpdmResponseError = (VOID *)Response;
        assert_int_equal (SpdmResponseError->Header.RequestResponseCode, SPDM_ERROR);
        assert_int_equal (SpdmResponseError->Header.Param1, SPDM_ERROR_CODE_INVALID_REQUEST);
      } else {
        ExpectedChunkSize = (UINT16)(MIN(mSpdmGetCertificateRequest3.Length, DataSize - mSpdmGetCertificateRequest3.Offset));
        ExpectedChunkSize = MIN(ExpectedChunkSize, MAX_SPDM_CERT_CHAIN_BLOCK_LEN);
        ExpectedRemainder = (UINT16)(DataSize - mSpdmGetCertificateRequest3.Offset - ExpectedChunkSize);
        assert_int_equal (ResponseSize, sizeof(SPDM_CERTIFICATE_RESPONSE) + ExpectedChunkSize);
        SpdmResponse = (VOID *)Response;
        assert_int_equal (SpdmResponse->Header.RequestResponseCode, SPDM_CERTIFICATE);
        assert_int_equal (SpdmResponse->Header.Param1, 0);
        assert_int_equal (SpdmResponse->PortionLength, ExpectedChunkSize);
        assert_int_equal (SpdmResponse->RemainderLength, ExpectedRemainder);
      }
    }
  }
  free(Data);
}
void TestSpdmResponderCertificateCase9 ( void * * state ) { RETURN_STATUS Status ; SPDM_TEST_CONTEXT * SpdmTestContext ; SPDM_DEVICE_CONTEXT * SpdmContext ; UINTN ResponseSize ; UINT8 Response [ MAX_SPDM_MESSAGE_BUFFER_SIZE ] ; SPDM_CERTIFICATE_RESPONSE * SpdmResponse ; SPDM_ERROR_RESPONSE * SpdmResponseError ; VOID * Data ; UINTN DataSize ; UINT16 TestSizes [ ] = { ( UINT16 ) ( -1 ) , 0 , +1 , ( UINT16 ) ( -1 ) , 0 , +1 , ( UINT16 ) ( MAX_INT8 - 1 ) , MAX_INT8 , ( UINT16 ) ( MAX_INT8 + 1 ) , ( UINT16 ) ( MAX_UINT8 - 1 ) , MAX_UINT8 , ( UINT16 ) ( MAX_INT16 - 1 ) , MAX_INT16 , ( UINT16 ) ( MAX_INT16 + 1 ) , ( UINT16 ) ( MAX_UINT16 - 1 ) , MAX_UINT16 } ; UINT16 ExpectedChunkSize ; UINT16 ExpectedRemainder ; SpdmTestContext = * state ; SpdmContext = SpdmTestContext -> SpdmContext ; SpdmTestContext -> CaseId = 0x9 ; SpdmContext -> ConnectionInfo . ConnectionState = SpdmConnectionStateAfterDigests ; SpdmContext -> LocalContext . Capability . Flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP ; ReadResponderPublicCertificateChain ( mUseHashAlgo , mUseAsymAlgo , & Data , & DataSize , NULL , NULL ) ; SpdmContext -> LocalContext . LocalCertChainProvision [ 0 ] = Data ; SpdmContext -> LocalContext . LocalCertChainProvisionSize [ 0 ] = DataSize ; SpdmContext -> LocalContext . SlotCount = 1 ; TestSizes [ 0 ] += ( UINT16 ) ( TestSizes [ 0 ] + DataSize ) ; TestSizes [ 1 ] += ( UINT16 ) ( TestSizes [ 1 ] + DataSize ) ; TestSizes [ 2 ] += ( UINT16 ) ( TestSizes [ 2 ] + DataSize ) ; for ( int i = 0 ; i < sizeof ( TestSizes ) / sizeof ( TestSizes [ 0 ] ) ; i ++ ) { TEST_DEBUG_PRINT ( " \n " , i , TestSizes [ i ] ) ; mSpdmGetCertificateRequest3 . Length = TestSizes [ i ] ; for ( int j = 0 ; j < sizeof ( TestSizes ) / sizeof ( TestSizes [ 0 ] ) ; j ++ ) { TEST_DEBUG_PRINT ( " \t \n " , j , TestSizes [ j ] ) ; mSpdmGetCertificateRequest3 . Offset = TestSizes [ j ] ; ResetManagedBuffer ( & SpdmContext -> Transcript . MessageB ) ; ResponseSize = sizeof ( Response ) ; Status = SpdmGetResponseCertificate ( SpdmContext , mSpdmGetCertificateRequest3Size , & mSpdmGetCertificateRequest3 , & ResponseSize , Response ) ; assert_int_equal ( Status , RETURN_SUCCESS ) ; if ( mSpdmGetCertificateRequest3 . Offset >= DataSize ) { SpdmResponseError = ( VOID * ) Response ; assert_int_equal ( SpdmResponseError -> Header . RequestResponseCode , SPDM_ERROR ) ; assert_int_equal ( SpdmResponseError -> Header . Param1 , SPDM_ERROR_CODE_INVALID_REQUEST ) ; } else { ExpectedChunkSize = ( UINT16 ) ( MIN ( mSpdmGetCertificateRequest3 . Length , DataSize - mSpdmGetCertificateRequest3 . Offset ) ) ; ExpectedChunkSize = MIN ( ExpectedChunkSize , MAX_SPDM_CERT_CHAIN_BLOCK_LEN ) ; ExpectedRemainder = ( UINT16 ) ( DataSize - mSpdmGetCertificateRequest3 . Offset - ExpectedChunkSize ) ; assert_int_equal ( ResponseSize , sizeof ( SPDM_CERTIFICATE_RESPONSE ) + ExpectedChunkSize ) ; SpdmResponse = ( VOID * ) Response ; assert_int_equal ( SpdmResponse -> Header . RequestResponseCode , SPDM_CERTIFICATE ) ; assert_int_equal ( SpdmResponse -> Header . Param1 , 0 ) ; assert_int_equal ( SpdmResponse -> PortionLength , ExpectedChunkSize ) ; assert_int_equal ( SpdmResponse -> RemainderLength , ExpectedRemainder ) ; } } } free ( Data ) ; }
Test 9: request Offset and Length at the boundary of maximum integer values
Expected Behavior: generate correctly formed Certficate messages, including its PortionLength and RemainderLength fields
Test 9 : request Offset and Length at the boundary of maximum integer values Expected Behavior : generate correctly formed Certficate messages including its PortionLength and RemainderLength fields
// Testing Offsets and Length combinations // Check at the boundary of maximum integer values and at the boundary of certificate length // reserved for sizes around the certificate chain size // Setting up the SpdmContext and loading a sample certificate chain // Setting up offset values at the boundary of certificate length // reseting an internal buffer to avoid overflow and prevent tests to succeed // A too long of an offset should return an error // Otherwise it should work properly // Expected received length is limited by MAX_SPDM_CERT_CHAIN_BLOCK_LEN and by the remaining length // Expected certificate length left