Ed25519 Signature verification in HSE

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Ed25519 Signature verification in HSE

1,178 Views
cij45
Contributor II

Hello,

I am currently using the S32K312.

I imported a Ed25519 public key in the HSE and am attempting to verify a signature that was generated externally. However, the verification consistently returns the error code 0x55A5A164UL.

Could you please let me know if there is any issue with the parameters I am using for the Ed25519 verification service?

* If possible, I would also appreciate it if you could share a demo code or reference example for performing Ed25519 signature verification using the HSE on S32K312.

Thank you for your support!

 

const uint8_t eccPubKey[32] = {Ed25519 public key};

ImportEccKeyReq(NVM_ECC_SECUREBOOT_HANDLE, HSE_KEY_TYPE_ECC_PUB, HSE_KF_USAGE_VERIFY | HSE_KF_USAGE_AUTHORIZATION,					   				HSE_EC_25519_ED25519, 256, (HOST_ADDR)eccPubKey, NULL);

uint8_t demo_plain[16]= {input value not hashed };
uint8_t rsignature[32]= {First 32 signature};
uint8_t ssignature[32]= {Last 32 signature};
uint32_t demo_sigsize[1] = {32};
	 
EddsaVerify(NVM_ECC_SECUREBOOT_HANDLE, FALSE, 16, (uint8_t*)demo_plain, FALSE, 0, 0, demo_sigsize, rsignature, demo_sigsize, ssignature);

 

hseSrvResponse_t EddsaVerify(hseKeyHandle_t keyHandle, bool_t bHashEddsa,
                             uint32_t inputLength, const uint8_t* pInput, bool_t bInputIsHashed,
                             uint8_t userContextLength, const uint8_t* pUserContext,
                             const uint32_t* pRLen, const uint8_t* pR,
                             const uint32_t* pSLen, const uint8_t* pS)
{
    hseSignScheme_t signScheme;

    signScheme.signSch                 = HSE_SIGN_EDDSA;
    signScheme.sch.eddsa.bHashEddsa    = bHashEddsa;
    signScheme.sch.eddsa.contextLength = userContextLength;
    signScheme.sch.eddsa.pContext      = (HOST_ADDR)pUserContext;

    return VerReq(HSE_ACCESS_MODE_ONE_PASS, signScheme,
                  keyHandle, muIf, muChannelIdx,
                  inputLength, pInput, bInputIsHashed, 0,
                  pRLen, pR,
                  pSLen, pS, gSyncTxOption);
}


static hseSrvResponse_t VerReq(hseAccessMode_t accessMode, hseSignScheme_t signScheme,
                               hseKeyHandle_t keyHandle, const uint8_t muIf,
                               const uint8_t muChannelIdx, uint32_t inputLength,
                               const uint8_t* pInput, bool_t bInputIsHashed, hseSGTOption_t sgtOption,
                               const uint32_t* pSignatureLength0, const uint8_t* pSignature0,
                               const uint32_t* pSignatureLength1, const uint8_t* pSignature1,
                               hseTxOptions_t txOptions)
{
    hseSrvDescriptor_t* pHseSrvDesc = &gHseSrvDesc[muIf][muChannelIdx];
    hseSignSrv_t* pSignSrv;
    memset(pHseSrvDesc, 0, sizeof(hseSrvDescriptor_t));

    pHseSrvDesc->srvId = HSE_SRV_ID_SIGN;
    pSignSrv = &(pHseSrvDesc->hseSrv.signReq);

    pSignSrv->accessMode          = accessMode;
    pSignSrv->signScheme          = signScheme;
    pSignSrv->authDir             = HSE_AUTH_DIR_VERIFY;
    pSignSrv->keyHandle           = keyHandle;
    pSignSrv->inputLength         = inputLength;
    pSignSrv->pInput              = (HOST_ADDR)pInput;
    pSignSrv->bInputIsHashed      = bInputIsHashed;
    pSignSrv->sgtOption           = sgtOption;
	pSignSrv->pSignature[0] 	  = (HOST_ADDR)pSignature0; 	   // R
	pSignSrv->pSignatureLength[0] = (HOST_ADDR)pSignatureLength0; // R len
	
	pSignSrv->pSignature[1] 	  = (HOST_ADDR)pSignature1; 	   // S
	pSignSrv->pSignatureLength[1] = (HOST_ADDR)pSignatureLength1; // S len



    return _HSE_Send(muIf, muChannelIdx, txOptions, pHseSrvDesc);
}
 
 
 

 

Tags (2)
0 Kudos
Reply
2 Replies

1,118 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport

Hi

It’s caused by endianness, most likely. There’s a note in HSE Firmware reference manual rev. 2.7 on page 118 that keys on Ed29919 curve are processed by conversion to little-endian bit strings. But HSE expects the keys in big-endian format. It’s necessary to swap the keys and also the signature.

You can use function like this for keys and for the signature:

 

void SwapArrayBytes

(

                uint8_t *pu8Source,

                uint32_t u32ByteLen

)

{

                uint32_t u32Start = (uint32_t)0U;

    uint32_t u32End   = u32ByteLen - 1U ;

    uint8_t  u8Temp   = (uint8_t)0U;

 

    if ((NULL_PTR != pu8Source) && ((uint32_t)0U != u32ByteLen))

    {

        while (u32Start < u32End)

        {

            u8Temp              = pu8Source[u32Start];

            pu8Source[u32Start] = pu8Source[u32End];

            pu8Source[u32End]   = u8Temp;

            u32Start++;

            u32End--;

        }

    }

}

 

To test the result, you can use test vectors:

https://asecuritysite.com/ecc/eddsa4

 

Regards,

Lukas

0 Kudos
Reply

949 Views
cij45
Contributor II

That was the key point,
Thank you very much for your support!!

0 Kudos
Reply