Interrupt for Data Co-Processor (DCP) NonBlocking API's?

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

Interrupt for Data Co-Processor (DCP) NonBlocking API's?

1,246 Views
karl_fraasch
Contributor III

Hello,

I am hoping to use the DCP for computing SHA256 and AES algorithms. Specifically, I would like to use the non-blocking versions of these functions. I modified the SDK demo apps to use the non-blocking functions which requires  DCP_WaitForChannelComplete. Is there any way to avoid using this function and receive and interrupt instead?

 

FYI, I am using NXP i.MX RT1064

0 Kudos
6 Replies

1,226 Views
karl_fraasch
Contributor III

Thanks for the quick reply Kerry. Correct, I am trying to avoid the blocking code in "DCP_WaitForChannelComplete".

I have looked into enabling interrupt functionality and still no luck. Here are my series of steps,

-  Enable DCP IRQ in NVIC (EnableIRQ(DCP_VMI_IRQn), EnableIRQ(DCP_IRQn))

- Enable Ch0 interrupt in DCP config

- Call DCP_AES_EncryptEcbNonBlocking

- Wait on blocking loop for flag to be set in DCP_IRQHandler or DCP_VMI_IRQHandler

Can you please see if there is anything I am missing or doing wrong? FYI, I am waiting on approval to RT1064 Security Reference Manual.

 

/*
 * Copyright 2017 NXP
 * All rights reserved.
 *
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

/*******************************************************************************
 * Includes
 ******************************************************************************/
#include "fsl_device_registers.h"
#include "fsl_debug_console.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"

#include "fsl_dcp.h"

dcp_work_packet_t work_packet;
volatile bool     encrypt_in_progress = false;

#define DCP_IRQ_HANDLER_FUNC DCP_IRQHandler
#define DCP_VMI_IRQ_HANDLER_FUNC DCP_VMI_IRQHandler

/*******************************************************************************
 * Definitions
 ******************************************************************************/

#define TEST_ASSERT(a)       \
    if (!(a))                \
    {                        \
        PRINTF("error\r\n"); \
        do                   \
        {                    \
        } while (1);         \
    }


/*******************************************************************************
 * Prototypes
 ******************************************************************************/

/*******************************************************************************
 * Code
 ******************************************************************************/

void TestAesEcb(void)
{
    /* Input data for DCP like IV, key and plaintext should be handled properly
     * when DCACHE is used (e.g. Clean&Invalidate, use non-cached memory)
     */
    static const uint8_t keyAes128[] __attribute__((aligned)) = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
                                                                 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
    static const uint8_t plainAes128[]                        = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
                                          0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
    static const uint8_t cipherAes128[]                       = {0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
                                           0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97};

    AT_NONCACHEABLE_SECTION_INIT(static uint8_t cipher[16]);
    AT_NONCACHEABLE_SECTION_INIT(static uint8_t output[16]);
    status_t status;

    dcp_handle_t m_handle;

    m_handle.channel    = kDCP_Channel0;
    m_handle.swapConfig = kDCP_NoSwap;

    m_handle.keySlot = kDCP_KeySlot0;

    status = DCP_AES_SetKey(DCP, &m_handle, keyAes128, 16);
    TEST_ASSERT(kStatus_Success == status);

    //DCP_AES_EncryptEcb(DCP, &m_handle, plainAes128, cipher, 16);
    encrypt_in_progress = true;
    DCP_AES_EncryptEcbNonBlocking(DCP, &m_handle, &work_packet, plainAes128, cipher, 16);
    
    
    while(encrypt_in_progress);
//    for(uint16_t i = 0; i<100; i++)
//    {
//        bool status = DCP_CheckChannelComplete(DCP, &m_handle);
//        PRINTF("%d\r\n", status);
//    }
    
    TEST_ASSERT(memcmp(cipher, cipherAes128, 16) == 0);
    

    

    DCP_AES_DecryptEcb(DCP, &m_handle, cipher, output, 16);
    TEST_ASSERT(memcmp(output, plainAes128, 16) == 0);

    PRINTF("AES ECB Test pass\r\n");
}


/*!
 * @brief Main function
 */
int main(void)
{
    dcp_config_t dcpConfig;

    /* Init hardware*/
    BOARD_ConfigMPU();
    BOARD_InitPins();
    BOARD_BootClockRUN();
    BOARD_InitDebugConsole();

    /* Note: When DCACHE is enabled input and output buffers should be in non-cached memory
     * or handled properly (DCACHE Clean and Invalidate).
     * Disable DCHACHE by calling SCB_DisableDCache();
     */
    
    /* Enable at the NVIC. */
    EnableIRQ(DCP_VMI_IRQn);
    EnableIRQ(DCP_IRQn);

    PRINTF("DCP Driver Example\r\n\r\n");

    /* Initialize DCP */
    DCP_GetDefaultConfig(&dcpConfig);
    
    dcpConfig.enableChannelInterrupt = kDCP_ch0IntEnable;
    
    /* Reset and initialize DCP */
    DCP_Init(DCP, &dcpConfig);
    
    /* Call DCP APIs */
    TestAesEcb();

    /* Deinitialize DCP */
    DCP_Deinit(DCP);

    while (1)
    {
    }
}

void DCP_IRQ_HANDLER_FUNC()
{
    encrypt_in_progress = false;
}

void DCP_VMI_IRQ_HANDLER_FUNC()
{
    encrypt_in_progress = false;  
}
0 Kudos

1,203 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi karl_fraasch,

   Sorry for the later reply.

    Do you already get the secure reference manual now?

   When you add the interrupt, and the service handler, run the code, do you meet the issues or not? Eg, hardfault. Or you still can run it, just the interrupt can't be triggered?

   Do you check the register, whether the related flag is set or not?

 

Best Regards,

Kerry

0 Kudos

1,197 Views
karl_fraasch
Contributor III

Hi Kerry,

Yes I was able to get interrupts to work for SDK's DCP DCP_AES_EncryptCbcNonBlocking function. I had to enable interrupts in control0 register.

Below is the change I had to make to "DCP_AES_EncryptCbcNonBlocking()" function inside of NXP's SDK fsl_dcp.c file.

// Added by K.F, must enable interrupts in control0 register
dcpPacket->control0 = dcpPacket->control0 | 0x0001;

 

FYI, I was able to get the RT1064 security reference manual. Thank you for checking.

0 Kudos

1,189 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi karl_fraasch,

  Really thanks so much for your solution sharing.

   In the future, if you have new issues, welcome to create a new question post.

 

Best Regards,

Kerry

0 Kudos

1,233 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi karl_fraasch,

 Do you mean, when you use the code, you need to call DCP_WaitForChannelComplete

status_t DCP_WaitForChannelComplete(DCP_Type *base, dcp_handle_t *handle)
{
/* wait if our channel is still active */
while ((base->STAT & (uint32_t)handle->channel) == (uint32_t)handle->channel)
{
}

if (dcp_get_channel_status(base, handle->channel) != kStatus_Success)
{
dcp_clear_status(base);
dcp_clear_channel_status(base, (uint32_t)handle->channel);
return kStatus_Fail;
}

dcp_clear_status(base);
return kStatus_Success;
}

That has the blocking code while, and you don't want to use it, right?

From the secure reference manual, the channel has the interrupt bit:

image.png

You can try to enable the interrupt and add the related interrupt service code.

Until now, we still don't have the direct DCP interrupt code.

Wish it helps you!

Best Regards,

Kerry

0 Kudos

1,224 Views
karl_fraasch
Contributor III

Hi Kerry,

Please see my response above.

0 Kudos