This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

LP-AM263P: HSMrt Streaming Authentication doesn't work

Part Number: LP-AM263P

Tool/software:

Hello,

Currently working with a HS-SE device. tifs lib version 1.0.0.5

No updates have been made to the HSMrt image, apart from rebuilding it for the HS variant.

ospi-sbl-mcelf is then rebuilt so the new HSMrt image is loaded.

What I'm finding is that the HSMrt streaming authentication service does not seem to be catching corruptions of the supplied application image.

If some error bytes are injected into some field of the x509 certificate at start of the Application image, ospi-sbl can generally capture the failure. For example, modifying 16 bytes on 0x400 for mcelf.hs:

 

Will result in sbl failure:

However, for a more subtle change, for example modifying 16 bytes which (after decoding) are destined to be loaded into 0x70041485 in my case, .text into OCRAM:

The section does not get picked up as erroneous as the authentication is completed throughIBootloader_finishUpdate(). This then results in the SBL booting the application image, and causing random exceptions as a result.

I've ensured doAuth is activated, ensuring authentication should happen.

 

I'm going to dig into the ipc messages to check HSM response, but to how much of an extent has this been tested for the tifs? Would it be reasonable to assume such a corruption should be picked up?

If IPC client/server messages don't show anything useful will likely have to debug HSMrt. What's the easiest way to do this?

Thanks,

Rens

  • Just to add one further finding, just after the call status = Bootloader_finishUpdate() is made, another IPC message is received from HSM under serType=49452 (==0xC12C, or HSM_MSG_PROC_AUTH_BOOT_FINISH) where gHsmClient.RespMsg.flags == 0x55 (= NACK), but ghsmClient.RespFlag == 0xAA (=ACK).

    So this seems to indicate that the HSM authentication has failed, but we're not waiting long enough for that to be picked up.

    Maybe ghsmClient.RespFlag is not updated quick enough for the erroneous value to be detected - maybe there's a place that ghsmClient.RespFlag is being used where gHsmClient.RespMsg.flags should be used..

    Thanks,

    Rens

  • To add another finding, I think the beginning call to Bootloader_socLoadHsmRtFw or Keyring_init might be upsetting a blocking loop further on. To me seems like it's due to Bootloader_socLoadHsmRtFw as we don't send an IPC message but only look for the HSM IPC return from HsmClient_waitForBootNotify.

    This then means that after Keyring_init function is done, gNum_HsmResponseReceived = 1, whilst gNum_HsmRequestSent = 0. 
    This in turn means that all calls to HSM after this will not be affected by the blocking loop HsmClient_waitForAllResponses - as this relies on those numbers. For example, at the start of HsmClient_procAuthBootStart call, gNum_HsmResponseReceived = 1 and gNum_HsmRequestSent ==0:
    This then subsequently means that when calling Bootloader_authFinish, gNum_HsmResponseReceived ==9 whilst gNum_HsmRequestSent ==8:

    The end of HsmClient_procAuthBootFinish is using the HsmClient_waitForAllResponses after sending the HSM_MSG_PROC_AUTH_BOOT_FINISH service type to HSM.

    In this case the blocking loop doesn't prevent further execution. There is a small time delay back from HSM to indicate a NACK response - but as this blocking loop doesn't hold it, we don't catch this on time.

    If I slowly step through HsmClient_procAuthBootFinish, there is plenty of time for the NACK message to be received from HSM, and so authentication fails as expected.

    So that is a bug which needs adressing.

    I've done a temp fix during HsmClient_procAuthBootStart() - equalising the two in case of any issues. With this applied, authentication works as expected.

    Thanks,

    Rens

  • Hi Rens,

    Thank you very much for this very detailed analysis on the issue.

    A few questions before confirming the issue. Meanwhile I will try the same tomorrow at my end and get back to you.

    This then means that after Keyring_init function is done, gNum_HsmResponseReceived = 1, whilst gNum_HsmRequestSent = 0. 

    In case of waiting for a bootnotify from HSM, the HsmClient_isr() does not increment the gNum_HsmResponseReceived as shown below.

    During Keyring_init, this could increment only gNum_HsmResponseReceived and not gNum_HsmRequestSent, as the API HsmClient_SendAndRecv() is used to send IPC instead of HsmClient_EnqueueAndSendMsg() where gNum_HsmRequestSent is incremented.

    Above is seen, when your Keyring_init function is defined. May I know if you are importing keyring in your SBL? or is Keyring_init a blank function?

    Again, thank you for pointing this out. I shall review and reproduce this at my end by tomorrow.

    Thanks and Regards,

    Nikhil Dasan

  • Hi Nikhil,

    No problem. One point which I did forget to mention earlier is that this is with SDK version 10.01.00.31. Believe the latest SDK version is 10.02.00.15, so it could well be something due to that or indeed fixed in the later version. I have not tested with 10.02.00.15 yet - not got round to it. 

    To answer your question, indeed I'm importing a keyring through sysCfg:

    Thanks,

    Rens

  • Hi Rens,

    Ok, this clarifies the increment of gNum_HsmResponseReceived before gNum_HsmRequestSent.

    HsmClient_ImportKeyring using HsmClient_SendAndRecv() API to send IPC message to HSM, whereas the mcelf authentication APIs like auth start, update and finish uses HsmClient_EnqueueAndSendMsg to send the message (which increments gNum_HsmRequestSent).

    As both the API call uses the same ISR, you are seeing increment in gNum_HsmResponseReceived in both cases.

    So, actually you wouldn't be seeing this issue when you don't do keyring init in this case.

    I believe this is there in the current SDK as well. I shall review and reproduce this at my end by tomorrow and file an internal bug to get this fixed after the same.

    Thanks again.

    Regards,

    Nikhil Dasan

  • Hi Nikhil, that indeed seems like the culprit. One other factor to the equation is that I'm using quite a large application file (5MB+..) so maybe with smaller application files the time taken to receive the HSM response nack for authentication is a lot smaller and so stop finishAuth from completing much earlier. So maybe that's why it's gone undetected until now. Good result in any case, thanks for checking

  • Hi Rens,

    HsmClient_ImportKeyring using HsmClient_SendAndRecv() API to send IPC message to HSM, whereas the mcelf authentication APIs like auth start, update and finish uses HsmClient_EnqueueAndSendMsg to send the message (which increments gNum_HsmRequestSent).

    The issue here occurs because of the issue above. 

    The quick workaround here is to increment gNum_HsmResponseReceived in HsmClient_isr() only if HsmClient->RespMsg.serType is HSM_MSG_PROC_AUTH_BOOT_START, HSM_MSG_PROC_AUTH_BOOT_UPDATE or HSM_MSG_PROC_AUTH_BOOT_FINISH and only if the HsmClient->RespMsg.flags is HSM_FLAG_ACK as shown below

    --- a/source/security/security_common/drivers/hsmclient/hsmclient.c
    +++ b/source/security/security_common/drivers/hsmclient/hsmclient.c
    @@ -374,7 +374,6 @@ void HsmClient_isr(uint8_t remoteCoreId, uint8_t localClientId,
         {
             if (gSecureBootStatus == SystemP_SUCCESS)
             {
    -            gNum_HsmResponseReceived++;
                 if (HsmClient->RespMsg.flags == HSM_FLAG_NACK)
                 {
                     gSecureBootStatus = SystemP_FAILURE;
    @@ -382,6 +381,12 @@ void HsmClient_isr(uint8_t remoteCoreId, uint8_t localClientId,
                 else if (HsmClient->RespMsg.flags == HSM_FLAG_ACK)
                 {
                     gSecureBootStatus = SystemP_SUCCESS;
    +                if ((HsmClient->RespMsg.serType == HSM_MSG_PROC_AUTH_BOOT_START)  ||  /* proc_auth_boot auth start */
    +                (HsmClient->RespMsg.serType == HSM_MSG_PROC_AUTH_BOOT_UPDATE) ||  /* proc_auth_boot auth update */
    +                (HsmClient->RespMsg.serType == HSM_MSG_PROC_AUTH_BOOT_FINISH))    /* proc_auth_boot auth finish */
    +                {
    +                    gNum_HsmResponseReceived++;
    +                }
                 }
                 else
                 {

    I have raised a bug to the dev team internally. Placing the JIRA link below for internal tracking

    [TIFSMCU-3991] HsmClient_waitForAllResponses() does not wait if TIFS service is called before MCELF parse - Texas Instruments JIRA

    Thanks and Regards,

    Nikhil Dasan

  • Hi Nikhil,

    Thanks for the confirmation and suggested fix, much appreciated,

    Thanks, Rens