Beispiel #1
0
static void aesCrypt(uint8 skipCnt, uint8 *pBuf)
{
  // A0: L-encoding of L-1 = 2-1 = 1; starting 2-byte CTR at 1.
  uint8 ivNonce[KEY_BLENGTH] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };

  ENCCS = CTR | AES_LOAD_IV | 0x01;

  // '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 (uint8 idx = 0; idx < KEY_BLENGTH; idx++)
  {
    ENCDI = ivNonce[idx];
  }
  while ((ENCCS & BV(3)) == 0);

  for (uint8 cnt = 0; cnt < (SBL_RW_BUF_LEN / KEY_BLENGTH); cnt++)
  {
    if (skipCnt == 0)
    {
      ENCCS = CTR | AES_ENCRYPT | 0x01;

      // '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 (uint8 blk = 0; blk < 4; blk++)
      {
        for (uint8 idx = 0; idx < 4; idx++)
        {
          ENCDI = pBuf[idx];
        }

        HAL_AES_DELAY();  // Delay required for non-DMA AES as RDY bit only goes hi after read out.

        for (uint8 idx = 0; idx < 4; idx++)
        {
          pBuf[idx] = ENCDO;
        }

        pBuf += 4;
      }
    }
    else
    {
      skipCnt--;
      pBuf += KEY_BLENGTH;
    }
  }
}
Beispiel #2
0
/******************************************************************************
 * @fn      AesStartBlock
 *
 * @brief   Write and read a block to and from the AES engine
 *
 * input parameters
 *
 * @param   out  - Pointer to result to be read.
 *          in   - pointer to data to be written.
 *
 * @return  None
 */
void AesStartBlock( uint8 *out, uint8 *in )
{
  uint8 i;

  /* Kick it off */
  AES_START();

  /* Copy data to encryption input register */
  for (i = 0; i < STATE_BLENGTH; i++)
  {
    ENCDI = *in++;
  }

  /* Delay is required for non-DMA AES */
  HAL_AES_DELAY();

  /* Copy encryption output register to out */
  for (i = 0; i < STATE_BLENGTH; i++)
  {
    *out++ = ENCDO;
  }
}
Beispiel #3
0
/******************************************************************************
 * @fn      AesStartShortBlock
 *
 * @brief   Write and read a block to and from the AES engine. When using CFB,
 *          OFB, and CTR mode, the 128 bits blocks are divided into four 32 bit
 *          blocks.
 *
 * input parameters
 *
 * @param   out  - Pointer to result to be read.
 *          in   - pointer to data to be written.
 *
 * @return  None
 */
void AesStartShortBlock( uint8 *out, uint8 *in )
{
  uint8 i, j;

  AES_START();
  for (i = 0; i < 4; i++)
  {
    /* Copy in block to encryption input register */
    for (j = 0; j < 4; j++)
    {
      ENCDI = *in++;
    }

    /* Delay is required for non-DMA AES */
    HAL_AES_DELAY();

    /* Copy encryptioon output register to out block */
    for (j = 0; j < 4; j++)
    {
      *out++ = ENCDO;
    }
  }
}
Beispiel #4
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;
}
Beispiel #5
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);
}