1 Reply Latest reply on Sep 21, 2020 7:44 AM by user_1669321

    CYBLE-416045-02 - Encryption broken with PDL 3.1.2 when using along with IPC

    user_1669321

      Hi,

       

      My module does not seem to properly encrypt since moving to PDL 3.1.2 (I was before with 3.0.4).

       

      Here is the dataflow:

      1. CM0+ fills a part of a buffer, notifies the CM4 that it's its turn
      2. CM4 fills the rest of the buffer, notifies the CM0+ that it's done
      3. CM0+ encrypts buffer (AES-128)

       

      For the same input buffer with PDL 3.0.4 and same encryption key+IV, I get a different encrypted buffer with PDL 3.1.2.

       

      I have tested encrypting directly in main_cm0p.c without interacting with the CM4 and it works fine, it seems that the problem arises when the CM4 is involved.

       

      I have looked at the input buffer data before encrypting (aka what is received from the CM4) and after and the contents are ok.

       

      Have there been issue observed with PDL 3.1.2 regarding crypto and IPC?

       

      Thanks,

       

      Fred

        • 1. Re: CYBLE-416045-02 - Encryption broken with PDL 3.1.2 when using along with IPC
          user_1669321

          I haven't been able to resolve my problem, but maybe it comes from a bad usage of IPC channels/semaphores/interrupts. I will share my IPC/Crypto configuration, if it helps.

           

          Here are the IPC semaphores that I use:

           

          #define FIRST_PROCESS_IPC_SEMAPHORE          (0)
          #define SECOND_PROCESS_IPC_SEMAPHORE         (1)
          
          
          
          #define BLOCKING_SEMA_LOCK(_s)   { while (Cy_IPC_Sema_Set  (_s, 1) != CY_IPC_SEMA_SUCCESS); }
          #define BLOCKING_SEMA_UNLOCK(_s) { while (Cy_IPC_Sema_Clear(_s, 1) != CY_IPC_SEMA_SUCCESS); }
          
          
          
          

           

           

          Here are the IPC channels that I use for sharing messages:

           

          
          #define PROCESS_1_IPC_CHANNEL     (8)
          #define PROCESS_2_IPC_CHANNEL     (9)
          
          
          typedef enum {
              SHARED_MSG_TYPE_1,
              SHARED_MSG_TYPE_2,
              SHARED_MSG_TYPE_3,
          } SharedMsgType;
          
          
          typedef struct {
              uint32_t scratchpad;    /*!< Scratchpad provided to the PDL. It should be initialized and never touched again. */
              SharedMsgType type;
              uint8_t* data;
              uint16_t len;
          } SharedIpcMsg;
          
          
          // Fix for toggling between PDL 3.0.4 and PDL 3.1.2
          #ifndef CY_IPC_CYPIPE_INTR_MASK
              #define CY_IPC_CYPIPE_INTR_MASK     CY_SYS_CYPIPE_INTR_MASK
          #endif
          #define IPC_MSG_INIT_SCRATCHPAD(_msg)   { (_msg)->scratchpad = _VAL2FLD(CY_IPC_PIPE_MSG_CLIENT,  CY_IPC_EP_CYPIPE_ADDR)     \
                                                                       | _VAL2FLD(CY_IPC_PIPE_MSG_USR,     0)                         \
                                                                       | _VAL2FLD(CY_IPC_PIPE_MSG_RELEASE, CY_IPC_CYPIPE_INTR_MASK);  }
          

           

          firstProcessIpcHandle = Cy_IPC_Drv_GetIpcBaseAddress(PROCESS_1_IPC_CHANNEL);
          SecondProcessIpcHandle = Cy_IPC_Drv_GetIpcBaseAddress(PROCESS_2_IPC_CHANNEL);
          
          
          Cy_IPC_Pipe_RegisterCallback(CY_IPC_EP_CYPIPE_ADDR,
                                       _IpcMsgCallback,
                                       CY_IPC_EP_CYPIPE_CM4_ADDR);
          

           

          
          cy_en_ipc_pipe_status_t _Cm4_SendIpcMessage(SharedIpcMsg* msg) {
              dataReleased = 0;
              return Cy_IPC_Pipe_SendMessage(CY_IPC_EP_CYPIPE_CM0_ADDR,
                                             CY_IPC_EP_CYPIPE_CM4_ADDR,
                                             (void *) msg, 
                                             _Cm4_ReleaseCallback);
          }
          

           

           

          And here is the configuration of the crypto block:

           

          /* Macros to configure the Crypto block */
          /* IPC data channel for the Crypto */
          #define CHAN_CRYPTO                             (uint32_t)(3u)  
          /* IPC interrupt structure for the Crypto server */  
          #define INTR_CRYPTO_SRV                         (uint32_t)(1u) 
          /* IPC interrupt structure for the Crypto client */   
          #define INTR_CRYPTO_CLI                         (uint32_t)(2u) 
          /* CM0+ IPC interrupt mux number the Crypto server */   
          #define INTR_CRYPTO_SRV_MUX                     (IRQn_Type)(2u)
          /* CM0+ IPC interrupt mux number the Crypto client */   
          #define INTR_CRYPTO_CLI_MUX                     (IRQn_Type)(3u)
          /* CM0+ ERROR interrupt mux number the Crypto server */  
          #define INTR_CRYPTO_ERR_MUX                     (IRQn_Type)(4u)   
          
          
          
          
          /* Crypto context structure to store and manipulate the global context */
          cy_stc_crypto_context_t cryptoScratch;
          cy_stc_crypto_server_context_t cryptoServerContext;
          
          
          /* Crypto configuration structure */
          const cy_stc_crypto_config_t localCryptoConfig = {
              /* .ipcChannel             */ CHAN_CRYPTO,
              /* .acquireNotifierChannel */ INTR_CRYPTO_SRV,
              /* .releaseNotifierChannel */ INTR_CRYPTO_CLI,
              /* .releaseNotifierConfig */ {
              #if (CY_CPU_CORTEX_M0P)
                  /* .intrSrc            */ INTR_CRYPTO_CLI_MUX,
                  /* .cm0pSrc            */ cpuss_interrupts_ipc_2_IRQn, /* depends on selected releaseNotifierChannel value */
              #else
                  /* .intrSrc            */ cpuss_interrupts_ipc_2_IRQn, /* depends on selected releaseNotifierChannel value */
              #endif
                  /* .intrPriority       */ 2u,
              },
              /* .userCompleteCallback   */ NULL,
              /* .userGetDataHandler     */ NULL,
              /* .userErrorHandler       */ NULL,
              /* .acquireNotifierConfig */ {
              #if (CY_CPU_CORTEX_M0P)
                  /* .intrSrc            */ INTR_CRYPTO_SRV_MUX,      /* to use with DeepSleep mode should be in DeepSleep capable muxer's range */
                  /* .cm0pSrc            */ cpuss_interrupts_ipc_1_IRQn, /* depends on selected acquireNotifierChannel value */
              #else
                  /* .intrSrc            */ cpuss_interrupts_ipc_1_IRQn, /* depends on selected acquireNotifierChannel value */
              #endif
                  /* .intrPriority       */ 2u,
              },
              /* .cryptoErrorIntrConfig */ {
              #if (CY_CPU_CORTEX_M0P)
                  /* .intrSrc            */ INTR_CRYPTO_ERR_MUX,
                  /* .cm0pSrc            */ cpuss_interrupt_crypto_IRQn,
              #else
                  /* .intrSrc            */ cpuss_interrupt_crypto_IRQn,
              #endif
                  /* .intrPriority       */ 2u,
              }
          };
          

           

           

          Are any of the IPC resources that I used reserved for the PDL?