⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hal_ccm.c

📁 Zigbee2006入门(源代码+文档讲解+系统推荐)
💻 C
📖 第 1 页 / 共 2 页
字号:

  uint8   A[16], T[16], *bptr;
  uint8   i, remainder;
  uint16  blocks, counter;

  osal_memcpy (T, Cstate, Mval);

  A[0] = 1;               // L=2, L-encoding = L-1 = 1
  osal_memcpy (A+1, N, 13);   // append Nonce
  counter = 1;
  bptr = M;

  blocks = len_m >> 4;
  remainder = len_m & 0x0f;

  while (blocks--)
  {
    osal_memcpy (Cstate, A, 14);
    Cstate[14] = (uint8) (counter >> 8);
    Cstate[15] = (uint8) (counter);
    pSspAesEncrypt (AesKey, Cstate);
    for (i=0; i < 16; i++) *bptr++ ^= Cstate[i];
    counter++;
  }

  if (remainder)
  {
    osal_memcpy (Cstate, A, 14);
    Cstate[14] = (uint8) (counter >> 8);
    Cstate[15] = (uint8) (counter);
    pSspAesEncrypt (AesKey, Cstate);
    for (i=0; i < remainder; i++) *bptr++ ^= Cstate[i];
  }

  osal_memcpy (Cstate, A, 14);
  Cstate[14] = Cstate[15] = 0;        // A0
  pSspAesEncrypt (AesKey, Cstate);     // Cstate = S0

  for (i=0; i < Mval; i++)  Cstate[i] ^= T[i];

#else /* HARDWARE_AES */

  uint8   A[STATE_BLENGTH], T[STATE_BLENGTH], *bptr;
  uint8   remainder;
  uint16  blocks;

  osal_memcpy (T, Cstate, Mval);

  A[0] = 1;                   /* L=2, L-encoding = L-1 = 1 */
  osal_memcpy (A+1, N, 13);   /* append Nonce */
  A[14] = A[15] = 0;          /* clear the CTR field */

  /* Claculate block sizes */
  blocks = len_m >> 4;
  remainder = len_m & 0x0f;
  if (remainder) blocks++;

  /* Allocate OSAL memory for message buffer */
  bptr = (uint8 *)osal_mem_alloc( blocks*STATE_BLENGTH );
  if (!bptr) return;

  /* Move message into position and pad with zeros */
  osal_memcpy( bptr, M, len_m );
  osal_memset( bptr+len_m, 0, STATE_BLENGTH-remainder );

  /* Set OFB mode and encrypt T to U */
  AES_SETMODE(OFB);
  AesLoadIV(A);
  AesDmaSetup( Cstate, STATE_BLENGTH, T, STATE_BLENGTH ); /* T -> U */
  AES_SET_ENCR_DECR_KEY_IV( AES_ENCRYPT );

  /* Kick it off */
  HAL_DMA_CLEAR_IRQ( HAL_DMA_AES_OUT );
  AES_START();
  while( !HAL_DMA_CHECK_IRQ( HAL_DMA_AES_OUT ) );

  /* Switch to CTR mode to encrypt message. CTR field must be greater than zero */
  AES_SETMODE(CTR);
  A[15] = 1;
  AesLoadIV(A);
  AesDmaSetup( bptr, blocks*STATE_BLENGTH, bptr, blocks*STATE_BLENGTH );
  AES_SET_ENCR_DECR_KEY_IV( AES_ENCRYPT );

  /* Kick it off */
  while (blocks--)
  {
    AES_START();
    while ( !(ENCCS & 0x08) );
  }

  /* Copy the encrypted message back to M and return OSAL memory */
  osal_memcpy( M, bptr, len_m );
  osal_mem_free( bptr );

#endif
}

/******************************************************************************
 * @fn      SSP_CCM_Decrypt
 *
 * @brief   Performs CCM decryption.
 *
 * input parameters
 *
 * @param   Mval    - Length of authentication field in octets [0,2,4,6,8,10,12,14 or 16]
 * @param   N       - Pointer to 13-byte Nonce
 * @param   C       - Pointer to octet string 'c', where 'c' = encrypted 'm' || encrypted auth tag U
 * @param   len_c   - Length of C[] in octets
 * @param   AesKey  - Pointer to AES Key or Pointer to Key Expansion buffer.
 * @param   Cstate  - Pointer AES state buffer (cannot be part of C[])
 *
 * output parameters
 *
 * @param   C[]         - Decrypted octet string 'm' || auth tag T
 * @param   Cstate[]    - The first Mval bytes contain  Authentication Tag T
 *
 * @return  None
 *
 */
void SSP_CCM_Decrypt (uint8 Mval, uint8 *N, uint8 *C, uint16 len_c,
                                                     uint8 *AesKey, uint8 *Cstate)
{
#if ((defined SOFTWARE_AES) && (SOFTWARE_AES == TRUE)) || ((defined SW_AES_AND_KEY_EXP) && (SW_AES_AND_KEY_EXP == TRUE))

  uint8   A[16], *bptr;
  uint8   i, remainder;
  uint16  blocks, counter;

  A[0] = 1;               // L=2, L-encoding = L-1 = 1
  osal_memcpy (A+1, N, 13);   // append Nonce
  counter = 1;
  bptr = C;

  i = len_c - Mval;
  blocks = i >> 4;
  remainder = i & 0x0f;

  while (blocks--)
  {
    osal_memcpy (Cstate, A, 14);
    Cstate[14] = (uint8) (counter >> 8);
    Cstate[15] = (uint8) (counter);
    pSspAesEncrypt (AesKey, Cstate);
    for (i=0; i < 16; i++) *bptr++ ^= Cstate[i];
    counter++;
  }

  if (remainder)
  {
    osal_memcpy (Cstate, A, 14);
    Cstate[14] = (uint8) (counter >> 8);
    Cstate[15] = (uint8) (counter);
    pSspAesEncrypt (AesKey, Cstate);
    for (i=0; i < remainder; i++) *bptr++ ^= Cstate[i];
  }

  osal_memcpy (Cstate, A, 14);
  Cstate[14] = Cstate[15] = 0;    // A0
  pSspAesEncrypt (AesKey, Cstate); // Cstate = S0

  counter = len_c - Mval;
  for (i=0; i < Mval; i++)
  {
    Cstate[i] ^= C[counter];    // save T in Cstate[]
    C[counter++] = Cstate[i];   // replace U with T (last Mval bytes of C[])
  }

#else /* HARDWARE_AES */

  uint8   *bptr;
  uint8   A[STATE_BLENGTH], U[STATE_BLENGTH];
  uint8   i;
  uint16  blocks;

  A[0] = 1;                  /* L=2, L-encoding = L-1 = 1 */
  osal_memcpy (A+1, N, 13);  /* append Nonce */
  A[14] = A[15] = 0;         /* clear the CTR field */

  /* Seperate M from C */
  i = len_c - Mval;
  blocks = i >> 4;
  if (i & 0x0f) blocks++;

  /* Extract U and pad it with zeros */
  osal_memset(U, 0, STATE_BLENGTH);
  osal_memcpy(U, C+i, Mval);

  /* Set OFB mode to encrypt U to T */
  AES_SETMODE(OFB);
  AesLoadIV(A);
  AesDmaSetup( Cstate, STATE_BLENGTH, U, STATE_BLENGTH ); /* U -> T */
  AES_SET_ENCR_DECR_KEY_IV( AES_ENCRYPT );

  /* Kick it off */
  HAL_DMA_CLEAR_IRQ( HAL_DMA_AES_OUT );
  AES_START();
  while ( !HAL_DMA_CHECK_IRQ( HAL_DMA_AES_OUT ) );

  /* Allocate OSAL memory for message buffer */
  bptr = (uint8 *)osal_mem_alloc( blocks*STATE_BLENGTH );
  if (!bptr) return;

  /* Move message into position and pad with zeros */
  osal_memset( bptr, 0, blocks*STATE_BLENGTH );
  osal_memcpy( bptr, C, i );

  /* Switch to CTR mode to decrypt message. CTR field must be greater than zero */
  AES_SETMODE(CTR);
  A[15] = 1;
  AesLoadIV(A);
  AesDmaSetup( bptr, blocks*STATE_BLENGTH, bptr, blocks*STATE_BLENGTH );
  AES_SET_ENCR_DECR_KEY_IV( AES_DECRYPT );

  /* Kick it off */
  while (blocks--)
  {
    AES_START();
    while ( !(ENCCS & 0x08) );
  }

  /* Copy the decrypted message back to M and return OSAL memory */
  osal_memcpy( C, bptr, i );
  osal_mem_free(bptr);

  /* Copy T to where U used to be */
  osal_memcpy(C+i, Cstate, Mval);

#endif
}

/******************************************************************************
 * @fn      SSP_CCM_InvAuth
 *
 * @brief   Verifies CCM authentication.
 *
 * input parameters
 *
 * @param   Mval    - Length of authentication field in octets [0,2,4,6,8,10,12,14 or 16]
 * @param   N       - Pointer to 13-byte Nonce
 * @param   C       - Pointer to octet string 'c' = 'm' || auth tag T
 * @param   len_c   - Length of C[] in octets
 * @param   A       - Pointer to octet string 'a'
 * @param   len_a   - Length of A[] in octets
 * @param   AesKey  - Pointer to AES Key or Pointer to Key Expansion buffer.
 * @param   Cstate  - Pointer to AES state buffer (cannot be part of C[])
 *
 * output parameters
 *
 * @param   Cstate[]    - The first Mval bytes contain computed Authentication Tag T
 *
 * @return  0 = Success, 1 = Failure
 *
 */
uint8 SSP_CCM_InvAuth (uint8 Mval, uint8 *N, uint8 *C, uint16 len_c, uint8 *A,
                                        uint16 len_a, uint8 *AesKey, uint8 *Cstate)
{
  uint8   i, t;
  uint8   status=0;

	// Check if authentication is even requested.  If not, return
	// success and exit.  This check is actually not needed because
	// the rest of the code works fine even with Mval==0.  I added
	// it to reduce unnecessary calculations and to speed up
	// performance when Mval==0
  if (!Mval) return 0;

  t = len_c - Mval;

  SSP_CCM_Auth (Mval, N, C, t, A, len_a, AesKey, Cstate);

  for (i=0; i < Mval; i++)
  {
    if (Cstate[i] != C[t++])
    {
      status = 1;
      break;
    }
  }
  return (status);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -