Exemple #1
0
/**************************************************************************************************
 * @fn          aesSignature
 *
 * @brief       Run the AES CRC-MAC calculation over the RC image according to the
 *              AES Control Block parameters and update the control block accordingly.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * @param       pBuf - Pointer to the KEY_BLENGTH-byte buffer to hold the signature calculated.
 *
 * @return      TRUE or FALSE whether the AES signature could be calculated.
 */
static uint8 aesSignature(void *pBuf)
{
  aesInitSig();

#if defined AES_TEST_VECS
  uint8 testInput[48] = {
    0x00, 0x08, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
    0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  };
  memcpy(pageBuf+HAL_FLASH_PAGE_SIZE-48, testInput, 48);

  uint8 idx = 0;
  for (uint8 loop = 0; loop < 2; loop++)
  {
    ENCCS |= 0x01;
    for (uint8 cnt = 0; cnt < KEY_BLENGTH; cnt++)
    {
      ENCDI = testInput[idx++];
    }
    while ((ENCCS & BV(3)) == 0);
  }
#else
  const uint8 lastPg = imgHdr.len / SBL_PAGE_LEN + SBL_PAGE_BEG - 1;

  for (uint8 pg = SBL_PAGE_BEG; pg <= lastPg; pg++)
  {
    HalFlashRead(pg, 0, pageBuf, HAL_FLASH_PAGE_SIZE);

    for (uint16 oset = 0; oset < HAL_FLASH_PAGE_SIZE; )
    {
      if ((pg == SBL_PAGE_BEG) && (oset == sizeof(img_hdr_t)))
      {
        oset += KEY_BLENGTH;  // Must not include the signature bytes in the signature calculation.
      }
      else if ((pg == lastPg) && (oset == (HAL_FLASH_PAGE_SIZE - KEY_BLENGTH)))
      {
        break;  // Need to change mode to CBC-MAC for the last block.
      }

      ENCCS |= 0x01;
      for (uint8 cnt = 0; cnt < KEY_BLENGTH; cnt++)
      {
        ENCDI = pageBuf[oset++];
      }
      while ((ENCCS & BV(3)) == 0);
    }
  }
#endif

  ENCCS = CBC | AES_ENCRYPT | 0x01;  // Switch to CBC mode for the last block.

  // 'while ((ENCCS & BV(3)) == 0)' was seen to hang without #pragma optimize=none.
  // So proactively adding this wait after every 'ENCCS = ' which empirically seems to work.
  ASM_NOP; ASM_NOP; ASM_NOP; ASM_NOP; ASM_NOP; ASM_NOP; ASM_NOP; ASM_NOP;

  for (uint16 oset = (HAL_FLASH_PAGE_SIZE - KEY_BLENGTH); oset < HAL_FLASH_PAGE_SIZE; oset++)
  {
    ENCDI = pageBuf[oset];
  }
  HAL_AES_DELAY();  // Delay required for non-DMA AES as RDY bit only goes hi after read out below.

  // CBC-MAC generates output on the last block.
  for (uint8 cnt = 0, *pSig = (uint8 *)pBuf; cnt < KEY_BLENGTH; cnt++)
  {
    *pSig++ = ENCDO;
  }

  return TRUE;
}
Exemple #2
0
/**************************************************************************************************
 * @fn          aesSignature
 *
 * @brief       Run the AES CRC-MAC calculation over the image specified according to the
 *              AES Control Block parameters and update the control block accordingly.
 *
 * input parameters
 *
 * @param       imgSel - Image select: 0 for Image-A and 1 for Image-B.
 * @param       aesHdr - Pointer to the aes_hdr_t info to use for the signature calculation.
 *
 * output parameters
 *
 * @param       aesHdr - Pointer to the aes_hdr_t info with the signature calculated.
 *
 * @return      TRUE or FALSE whether the AES signature calculated matches the one in the header.
 */
static uint8 aesSignature(uint8 imgSel, aes_hdr_t *aesHdr)
{
  uint8 sigBuf[KEY_BLENGTH];
  aesInitSig(aesHdr);

  uint8 pgEnd = ImgPageBeg[imgSel] + aesHdr->spare[3] - 1;

  if (imgSel == 0)
  {
    pgEnd += ImgPageLen[1];
  }

  for (uint8 pgNum = ImgPageBeg[imgSel]; pgNum <= pgEnd; )
  {
    BEM_NVM_GET(pgNum, pageBuf, HAL_FLASH_PAGE_SIZE);

    for (uint16 oset = 0; oset < HAL_FLASH_PAGE_SIZE; )
    {
      if ((pgNum == ImgPageBeg[imgSel]) && (oset == sizeof(img_hdr_t)))
      {
        oset += KEY_BLENGTH;  // Must not include the signature bytes in the signature calculation.
      }
      else if ((pgNum == pgEnd) && (oset == (HAL_FLASH_PAGE_SIZE - KEY_BLENGTH)))
      {
        break;  // Need to change mode to CBC-MAC for the last block.
      }

      ENCCS |= 0x01;
      for (uint8 cnt = 0; cnt < KEY_BLENGTH; cnt++)
      {
        ENCDI = pageBuf[oset++];
      }
      while ((ENCCS & BV(3)) == 0);
    }

    pgNum++;

    if ((imgSel == 0) && (pgNum == ImgPageBeg[1]))
    {
      pgNum += ImgPageLen[1];
    }
  }

  ENCCS = CBC | AES_ENCRYPT | 0x01;  // Switch to CBC mode for the last block.

  // 'while ((ENCCS & BV(3)) == 0)' was seen to hang without #pragma optimize=none.
  // So proactively adding this wait after every 'ENCCS = ' which empirically seems to work.
  ASM_NOP; ASM_NOP; ASM_NOP; ASM_NOP; ASM_NOP; ASM_NOP; ASM_NOP; ASM_NOP;

  for (uint16 oset = (HAL_FLASH_PAGE_SIZE - KEY_BLENGTH); oset < HAL_FLASH_PAGE_SIZE; oset++)
  {
    ENCDI = pageBuf[oset];
  }
  HAL_AES_DELAY();  // Delay required for non-DMA AES as RDY bit only goes hi after read out below.

  // CBC-MAC generates output on the last block.
  for (uint8 cnt = 0; cnt < KEY_BLENGTH; cnt++)
  {
    sigBuf[cnt] = ENCDO;
  }

  return ((memcmp(sigBuf, aesHdr->signature, KEY_BLENGTH) == 0) ? TRUE : FALSE);
}