Beispiel #1
0
static int  AesAlign16(Aes* aes, byte* out, const byte* in, word32 sz, word32 dir, word32 mode)
{
    wolfSSL_TI_lockCCM() ;
    ROM_AESReset(AES_BASE);
    ROM_AESConfigSet(AES_BASE, (aes->keylen | dir |
                                (mode==AES_CFG_MODE_CTR_NOCTR ? AES_CFG_MODE_CTR : mode)));
    ROM_AESIVSet(AES_BASE, aes->reg);
    ROM_AESKey1Set(AES_BASE, aes->key, aes->keylen);
    if((dir == AES_CFG_DIR_DECRYPT)&& (mode == AES_CFG_MODE_CBC))
        /* if input and output same will overwrite input iv */
        XMEMCPY(aes->tmp, in + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
    ROM_AESDataProcess(AES_BASE, (uint32_t *)in, (uint32_t *)out, sz);
    wolfSSL_TI_unlockCCM() ;

    /* store iv for next call */
    if(mode == AES_CFG_MODE_CBC) {
        if(dir == AES_CFG_DIR_ENCRYPT)
            XMEMCPY(aes->reg, out + sz - AES_BLOCK_SIZE, AES_BLOCK_SIZE);
        else
            XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
    }

    if(mode == AES_CFG_MODE_CTR) {
        do {
            int i ;
            for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) {
                if (++((byte *)aes->reg)[i])
                    break ;
            }
            sz -= AES_BLOCK_SIZE ;
        } while((int)sz > 0) ;
    }

    return 0 ;
}
//*****************************************************************************
//
// Perform an ECB encryption operation.
//
//*****************************************************************************
bool
AESECBEncrypt(uint32_t ui32Keysize, uint32_t *pui32Src, uint32_t *pui32Dst,
              uint32_t *pui32Key, uint32_t ui32Length)
{
    //
    // Perform a soft reset.
    //
    ROM_AESReset(AES_BASE);

    //
    // Configure the AES module.
    //
    ROM_AESConfigSet(AES_BASE, (ui32Keysize | AES_CFG_DIR_ENCRYPT |
                                AES_CFG_MODE_ECB));

    //
    // Write the key.
    //
    ROM_AESKey1Set(AES_BASE, pui32Key, ui32Keysize);

    //
    // Perform the encryption.
    //
    ROM_AESDataProcess(AES_BASE, pui32Src, pui32Dst, ui32Length);

    return(true);
}
//*****************************************************************************
//
// Perform a basic GHASH operation with the hashsubkey and IV.  This is
// used to get Y0 when the IV is not 96 bits.  To use this GCM mode, the
// operation direction must not be set and the counter should be disabled.
//
//*****************************************************************************
void
AESGHASH(uint32_t ui32Keysize, uint32_t *pui32HashSubkey, uint32_t *pui32IV,
         uint32_t ui32IVLength, uint32_t *pui32Result)
{
    uint32_t ui32Count;

    //
    // Perform a soft reset.
    //
    ROM_AESReset(AES_BASE);

    //
    // Configure the AES module.
    //
    ROM_AESConfigSet(AES_BASE, (ui32Keysize | AES_CFG_MODE_GCM_HLY0ZERO));

    //
    // Set the hash subkey.
    //
    ROM_AESKey2Set(AES_BASE, pui32HashSubkey, ui32Keysize);

    //
    // Write the lengths
    //
    ROM_AESLengthSet(AES_BASE, (uint64_t)ui32IVLength);
    ROM_AESAuthLengthSet(AES_BASE, 0);

    //
    // Write the data.
    //
    for(ui32Count = 0; ui32Count < ui32IVLength; ui32Count += 16)
    {
        //
        // Write the data registers.
        //
        ROM_AESDataWrite(AES_BASE, pui32IV + (ui32Count / 4));
    }

    //
    // Read the hash tag value.
    //
    AESTagRead(AES_BASE, pui32Result);
}
Beispiel #4
0
//*****************************************************************************
//
// Perform an CCM decryption operation.
// 
//*****************************************************************************
bool
AES128CCMDecrypt(uint32_t *pui32Key, uint32_t *pui32Src, uint32_t *pui32Dst,
                 uint32_t ui32DataLength, uint32_t *pui32Nonce, 
                 uint32_t ui32NonceLength, uint32_t *pui32AuthData, 
                 uint32_t ui32AuthDataLength, uint32_t *pui32Tag, 
                 uint32_t ui32TagLength, bool bUseDMA)
{
    uint32_t pui32IV[4], ui32Idx;
    uint32_t ui32M, ui32L;
    uint8_t *pui8Nonce, *pui8IV;

    //
    // Determine the value of M.  It is determined using 
    // the tag length.
    //
    if(ui32TagLength == 4)
    {
        ui32M = AES_CFG_CCM_M_4;
    }
    else if(ui32TagLength == 6)
    {
        ui32M = AES_CFG_CCM_M_6;
    }
    else if(ui32TagLength == 8)
    {
        ui32M = AES_CFG_CCM_M_8;
    }
    else if(ui32TagLength == 10)
    {
        ui32M = AES_CFG_CCM_M_10;
    }
    else if(ui32TagLength == 12)
    {
        ui32M = AES_CFG_CCM_M_12;
    }
    else if(ui32TagLength == 14)
    {
        ui32M = AES_CFG_CCM_M_14;
    }
    else if(ui32TagLength == 16)
    {
        ui32M = AES_CFG_CCM_M_16;
    }
    else
    {
        UARTprintf("Unexpected tag length.\n");
        return(false);
    }

    //
    // Determine the value of L. This is determined by using
    // the value of q from the NIST document:  n + q = 15
    //
    if(ui32NonceLength == 7)
    {   
        ui32L = AES_CFG_CCM_L_8;
    }
    else if(ui32NonceLength == 8)
    {   
        ui32L = AES_CFG_CCM_L_7;
    }
    else if(ui32NonceLength == 9)
    {   
        ui32L = AES_CFG_CCM_L_6;
    }
    else if(ui32NonceLength == 10)
    {   
        ui32L = AES_CFG_CCM_L_5;
    }
    else if(ui32NonceLength == 11)
    {
        ui32L = AES_CFG_CCM_L_4;
    }
    else if(ui32NonceLength == 12)
    {
        ui32L = AES_CFG_CCM_L_3;
    }
    else if(ui32NonceLength == 13)
    {
        ui32L = AES_CFG_CCM_L_2;
    }
    else if(ui32NonceLength == 14)
    {
        ui32L = AES_CFG_CCM_L_1;
    }
    else
    {
        UARTprintf("Unexpected nonce length.\n");
        return(false);
    }

    //
    // Perform a soft reset.
    //
    ROM_AESReset(AES_BASE);

    //
    // Clear the interrupt flags.
    //
    g_bContextInIntFlag = false;
    g_bDataInIntFlag = false;
    g_bContextOutIntFlag = false;
    g_bDataOutIntFlag = false;
    g_bContextInDMADoneIntFlag = false;
    g_bDataInDMADoneIntFlag = false;
    g_bContextOutDMADoneIntFlag = false;
    g_bDataOutDMADoneIntFlag = false;

    //
    // Enable all interrupts.
    //
    ROM_AESIntEnable(AES_BASE, (AES_INT_CONTEXT_IN | AES_INT_CONTEXT_OUT |
                                AES_INT_DATA_IN | AES_INT_DATA_OUT));

    //
    // Configure the AES module.
    //
    ROM_AESConfigSet(AES_BASE, (AES_CFG_KEY_SIZE_128BIT | AES_CFG_DIR_DECRYPT |
                                AES_CFG_CTR_WIDTH_128 |
                                AES_CFG_MODE_CCM | ui32L | ui32M));

    //
    // Determine the value to be written in the initial value registers.  It is 
    // the concatenation of 5 bits of zero, 3 bits of L, nonce, and the counter
    // value.  First, clear the contents of the IV.
    //
    for(ui32Idx = 0; ui32Idx < 4; ui32Idx++)
    {
        pui32IV[ui32Idx] = 0;
    }

    //
    // Now find the binary value of L.
    //
    if(ui32L == AES_CFG_CCM_L_8)
    {
        pui32IV[0] = 0x7;
    }
    else if(ui32L == AES_CFG_CCM_L_7)
    {
        pui32IV[0] = 0x6;
    }
    else if(ui32L == AES_CFG_CCM_L_6)
    {
        pui32IV[0] = 0x5;
    }
    else if(ui32L == AES_CFG_CCM_L_5)
    {
        pui32IV[0] = 0x4;
    }
    else if(ui32L == AES_CFG_CCM_L_4)
    {
        pui32IV[0] = 0x3;
    }
    else if(ui32L == AES_CFG_CCM_L_3)
    {
        pui32IV[0] = 0x2;
    }
    else if(ui32L == AES_CFG_CCM_L_2)
    {
        pui32IV[0] = 0x1;
    }

    //
    // Finally copy the contents of the nonce into the IV.  Convert
    // the pointers to simplify the copying.
    //
    pui8Nonce = (uint8_t *)pui32Nonce; 
    pui8IV = (uint8_t *)pui32IV;
    for(ui32Idx = 0; ui32Idx < ui32NonceLength; ui32Idx++)
    {
        pui8IV[ui32Idx + 1] = pui8Nonce[ui32Idx];
    }

    //
    // Write the initial value.
    //
    ROM_AESIVSet(AES_BASE, pui32IV);

    //
    // Write the key.
    //
    ROM_AESKey1Set(AES_BASE, pui32Key, AES_CFG_KEY_SIZE_128BIT);
    
    //
    // Depending on the argument, perform the decryption
    // with or without uDMA.
    //
    if(bUseDMA)
    {
        //
        // Enable DMA interrupts.
        //
        ROM_AESIntEnable(AES_BASE, (AES_INT_DMA_CONTEXT_IN |
                                    AES_INT_DMA_DATA_IN |
                                    AES_INT_DMA_CONTEXT_OUT |
                                    AES_INT_DMA_DATA_OUT));

        //
        // Setup the DMA module to copy auth data in.
        //
        ROM_uDMAChannelAssign(UDMA_CH14_AES0DIN);
        ROM_uDMAChannelAttributeDisable(UDMA_CH14_AES0DIN,
                                        UDMA_ATTR_ALTSELECT |
                                        UDMA_ATTR_USEBURST |
                                        UDMA_ATTR_HIGH_PRIORITY |
                                        UDMA_ATTR_REQMASK);
        ROM_uDMAChannelControlSet(UDMA_CH14_AES0DIN | UDMA_PRI_SELECT,
                                  UDMA_SIZE_32 | UDMA_SRC_INC_32 |
                                  UDMA_DST_INC_NONE | UDMA_ARB_4 |
                                  UDMA_DST_PROT_PRIV);
        ROM_uDMAChannelTransferSet(UDMA_CH14_AES0DIN | UDMA_PRI_SELECT,
                                   UDMA_MODE_BASIC, (void *)pui32AuthData,
                                   (void *)(AES_BASE + AES_O_DATA_IN_0),
                                   LengthRoundUp(ui32AuthDataLength) / 4);
        UARTprintf("Data in DMA request enabled.\n");

        //
        // Setup the DMA module to copy the data out.
        //
        ROM_uDMAChannelAssign(UDMA_CH15_AES0DOUT);
        ROM_uDMAChannelAttributeDisable(UDMA_CH15_AES0DOUT,
                                        UDMA_ATTR_ALTSELECT |
                                        UDMA_ATTR_USEBURST |
                                        UDMA_ATTR_HIGH_PRIORITY |
                                        UDMA_ATTR_REQMASK);
        ROM_uDMAChannelControlSet(UDMA_CH15_AES0DOUT | UDMA_PRI_SELECT,
                                  UDMA_SIZE_32 | UDMA_SRC_INC_NONE |
                                  UDMA_DST_INC_32 | UDMA_ARB_4 |
                                  UDMA_SRC_PROT_PRIV);
        ROM_uDMAChannelTransferSet(UDMA_CH15_AES0DOUT | UDMA_PRI_SELECT,
                                   UDMA_MODE_BASIC,
                                   (void *)(AES_BASE + AES_O_DATA_IN_0),
                                   (void *)pui32Dst,
                                   LengthRoundUp(ui32DataLength) / 4);
        UARTprintf("Data out DMA request enabled.\n");

        //
        // Write the length registers.
        //
        ROM_AESLengthSet(AES_BASE, (uint64_t)ui32DataLength);

        //
        // Write the auth length registers to start the process.
        //
        ROM_AESAuthLengthSet(AES_BASE, ui32AuthDataLength);
        
        //
        // Enable the DMA channels to start the transfers.  This must be done after
        // writing the length to prevent data from copying before the context is 
        // truly ready.
        // 
        ROM_uDMAChannelEnable(UDMA_CH14_AES0DIN);
        ROM_uDMAChannelEnable(UDMA_CH15_AES0DOUT);

        //
        // Enable DMA requests.
        //
        ROM_AESDMAEnable(AES_BASE, AES_DMA_DATA_IN | AES_DMA_DATA_OUT);

        //
        // Wait for the data in DMA done interrupt.
        //
        while(!g_bDataInDMADoneIntFlag)
        {
        }

        //
        // Setup the uDMA to copy the plaintext data.
        //
        ROM_uDMAChannelAssign(UDMA_CH14_AES0DIN);
        ROM_uDMAChannelAttributeDisable(UDMA_CH14_AES0DIN,
                                        UDMA_ATTR_ALTSELECT |
                                        UDMA_ATTR_USEBURST |
                                        UDMA_ATTR_HIGH_PRIORITY |
                                        UDMA_ATTR_REQMASK);
        ROM_uDMAChannelControlSet(UDMA_CH14_AES0DIN | UDMA_PRI_SELECT,
                                  UDMA_SIZE_32 | UDMA_SRC_INC_32 |
                                  UDMA_DST_INC_NONE | UDMA_ARB_4 |
                                  UDMA_DST_PROT_PRIV);
        ROM_uDMAChannelTransferSet(UDMA_CH14_AES0DIN | UDMA_PRI_SELECT,
                                   UDMA_MODE_BASIC, (void *)pui32Src,
                                   (void *)(AES_BASE + AES_O_DATA_IN_0),
                                   LengthRoundUp(ui32DataLength) / 4);
        ROM_uDMAChannelEnable(UDMA_CH14_AES0DIN);
        UARTprintf("Data in DMA request enabled.\n");

        //
        // Wait for the data out DMA done interrupt.
        //
        while(!g_bDataOutDMADoneIntFlag)
        {
        }

        //
        // Read the tag out.
        //
        ROM_AESTagRead(AES_BASE, pui32Tag);
    }
    else
    {
        //
        // Perform the decryption.
        //
        ROM_AESDataProcessAuth(AES_BASE, pui32Src, pui32Dst, ui32DataLength,
                               pui32AuthData, ui32AuthDataLength, pui32Tag);
    }
    return(true);
}
Beispiel #5
0
static int AesAuthDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz,
                          const byte* nonce, word32 nonceSz,
                          const byte* authTag, word32 authTagSz,
                          const byte* authIn, word32 authInSz, int mode)
{
    word32 M, L ;
    byte *in_a,     *in_save ;
    byte *out_a,    *out_save ;
    byte *authIn_a, *authIn_save ;
    byte *nonce_a,    *nonce_save ;
    word32 tmpTag[4] ;
    bool ret ;

    if(AesAuthArgCheck(aes, out, in, inSz, nonce, nonceSz, authTag, authTagSz, authIn, authInSz, &M, &L)
            == BAD_FUNC_ARG)return  BAD_FUNC_ARG ;

    /* 16 byte padding */
    in_save = NULL ;
    out_save = NULL ;
    authIn_save = NULL ;
    nonce_save = NULL ;
    if((inSz%16)==0) {
        in_save = NULL ;
        in_a = (byte *)in ;
        out_save = NULL ;
        out_a = out ;
    } else {
        if((in_save = XMALLOC(RoundUp16(inSz), NULL, DYNAMIC_TYPE_TMP_BUFFER)) == NULL) {
            FREE_ALL;
            return MEMORY_E;
        }
        in_a = in_save ;
        XMEMSET(in_a, 0, RoundUp16(inSz)) ;
        XMEMCPY(in_a, in, inSz) ;

        if((out_save = XMALLOC(RoundUp16(inSz), NULL, DYNAMIC_TYPE_TMP_BUFFER)) == NULL) {
            FREE_ALL;
            return MEMORY_E;
        }
        out_a = out_save ;
    }

    if((authInSz%16)==0) {
        authIn_save = NULL ;
        authIn_a = (byte *)authIn ;
    } else {
        if((authIn_save = XMALLOC(RoundUp16(authInSz), NULL, DYNAMIC_TYPE_TMP_BUFFER)) == NULL) {
            FREE_ALL;
            return MEMORY_E;
        }
        authIn_a = authIn_save ;
        XMEMSET(authIn_a, 0, RoundUp16(authInSz)) ;
        XMEMCPY(authIn_a, authIn, authInSz) ;
    }

    if((nonceSz%16)==0) {
        nonce_save = NULL ;
        nonce_a = (byte *)nonce ;
    } else {
        if((nonce_save = XMALLOC(RoundUp16(nonceSz), NULL, DYNAMIC_TYPE_TMP_BUFFER)) == NULL) {
            FREE_ALL;
            return MEMORY_E;
        }
        nonce_a = nonce_save ;
        XMEMSET(nonce_a, 0, RoundUp16(nonceSz)) ;
        XMEMCPY(nonce_a, nonce, nonceSz) ;
    }

    /* do aes-ccm */
    AesAuthSetIv(aes, nonce, nonceSz, L, mode) ;
    ROM_AESReset(AES_BASE);
    ROM_AESConfigSet(AES_BASE, (aes->keylen | AES_CFG_DIR_DECRYPT |
                                AES_CFG_CTR_WIDTH_128 |
                                mode | ((mode== AES_CFG_MODE_CCM) ? (L | M) : 0 ))) ;
    ROM_AESIVSet(AES_BASE, aes->reg);
    ROM_AESKey1Set(AES_BASE, aes->key, aes->keylen);
    ret = ROM_AESDataProcessAuth(AES_BASE, (unsigned int*)in_a, (unsigned int *)out_a, inSz,
                                 (unsigned int*)authIn_a, authInSz, (unsigned int *)tmpTag);
    if((ret == false) || (XMEMCMP(authTag, tmpTag, authTagSz) != 0)) {
        XMEMSET(out, 0, inSz) ;
        ret = false ;
    } else {
        XMEMCPY(out, out_a, inSz) ;
    }

    FREE_ALL ;
    return ret==true ? 0 : 1 ;
}
//*****************************************************************************
//
// Perform an GCM decryption operation.
//
//*****************************************************************************
bool
AESGCMDecrypt(uint32_t ui32Keysize, uint32_t *pui32Src, uint32_t *pui32Dst,
              uint32_t ui32Length, uint32_t *pui32Key, uint32_t *pui32IV,
              uint32_t *pui32AAD, uint32_t ui32AADLength, uint32_t *pui32Tag,
              bool bUseDMA)
{
    //
    // Perform a soft reset.
    //
    ROM_AESReset(AES_BASE);

    //
    // Clear the interrupt flags.
    //
    g_bContextInIntFlag = false;
    g_bDataInIntFlag = false;
    g_bContextOutIntFlag = false;
    g_bDataOutIntFlag = false;
    g_bContextInDMADoneIntFlag = false;
    g_bDataInDMADoneIntFlag = false;
    g_bContextOutDMADoneIntFlag = false;
    g_bDataOutDMADoneIntFlag = false;

    //
    // Enable all interrupts.
    //
    ROM_AESIntEnable(AES_BASE, (AES_INT_CONTEXT_IN | AES_INT_CONTEXT_OUT |
                                AES_INT_DATA_IN | AES_INT_DATA_OUT));

    //
    // Wait for the context in flag.
    //
    while(!g_bContextInIntFlag)
    {
    }

    //
    // Configure the AES module.
    //
    ROM_AESConfigSet(AES_BASE, (ui32Keysize | AES_CFG_DIR_DECRYPT |
                                AES_CFG_MODE_GCM_HY0CALC));

    //
    // Write the initialization value
    //
    ROM_AESIVSet(AES_BASE, pui32IV);

    //
    // Write the keys.
    //
    ROM_AESKey1Set(AES_BASE, pui32Key, ui32Keysize);

    //
    // Depending on the argument, perform the decryption
    // with or without uDMA.
    //
    if(bUseDMA)
    {
        //
        // Enable DMA interrupts.
        //
        ROM_AESIntEnable(AES_BASE, (AES_INT_DMA_CONTEXT_IN |
                                    AES_INT_DMA_DATA_IN |
                                    AES_INT_DMA_CONTEXT_OUT |
                                    AES_INT_DMA_DATA_OUT));

        if(ui32AADLength != 0)
        {
            //
            // Setup the DMA module to copy auth data in.
            //
            ROM_uDMAChannelAssign(UDMA_CH14_AES0DIN);
            ROM_uDMAChannelAttributeDisable(UDMA_CH14_AES0DIN,
                                            UDMA_ATTR_ALTSELECT |
                                            UDMA_ATTR_USEBURST |
                                            UDMA_ATTR_HIGH_PRIORITY |
                                            UDMA_ATTR_REQMASK);
            ROM_uDMAChannelControlSet(UDMA_CH14_AES0DIN | UDMA_PRI_SELECT,
                                      UDMA_SIZE_32 | UDMA_SRC_INC_32 |
                                      UDMA_DST_INC_NONE | UDMA_ARB_4 |
                                      UDMA_DST_PROT_PRIV);
            ROM_uDMAChannelTransferSet(UDMA_CH14_AES0DIN | UDMA_PRI_SELECT,
                                       UDMA_MODE_BASIC, (void *)pui32AAD,
                                       (void *)(AES_BASE + AES_O_DATA_IN_0),
                                       LengthRoundUp(ui32AADLength) / 4);
            UARTprintf("Data in DMA request enabled.\n");
        }

        //
        // Setup the DMA module to copy the data out.
        //
        ROM_uDMAChannelAssign(UDMA_CH15_AES0DOUT);
        ROM_uDMAChannelAttributeDisable(UDMA_CH15_AES0DOUT,
                                        UDMA_ATTR_ALTSELECT |
                                        UDMA_ATTR_USEBURST |
                                        UDMA_ATTR_HIGH_PRIORITY |
                                        UDMA_ATTR_REQMASK);
        ROM_uDMAChannelControlSet(UDMA_CH15_AES0DOUT | UDMA_PRI_SELECT,
                                  UDMA_SIZE_32 | UDMA_SRC_INC_NONE |
                                  UDMA_DST_INC_32 | UDMA_ARB_4 |
                                  UDMA_SRC_PROT_PRIV);
        ROM_uDMAChannelTransferSet(UDMA_CH15_AES0DOUT | UDMA_PRI_SELECT,
                                   UDMA_MODE_BASIC,
                                   (void *)(AES_BASE + AES_O_DATA_IN_0),
                                   (void *)pui32Dst,
                                   LengthRoundUp(ui32Length) / 4);
        UARTprintf("Data out DMA request enabled.\n");

        //
        // Write the plaintext length
        //
        ROM_AESLengthSet(AES_BASE, (uint64_t)ui32Length);

        //
        // Write the auth length registers to start the process.
        //
        ROM_AESAuthLengthSet(AES_BASE, ui32AADLength);
        
        //
        // Enable the DMA channels to start the transfers.  This must be done after
        // writing the length to prevent data from copying before the context is 
        // truly ready.
        // 
        if(ui32AADLength != 0)
        {
            ROM_uDMAChannelEnable(UDMA_CH14_AES0DIN);
        }
        ROM_uDMAChannelEnable(UDMA_CH15_AES0DOUT);

        //
        // Enable DMA requests
        //
        ROM_AESDMAEnable(AES_BASE, AES_DMA_DATA_IN | AES_DMA_DATA_OUT);

        if(ui32AADLength != 0)
        {
            //
            // Wait for the data in DMA done interrupt.
            //
            while(!g_bDataInDMADoneIntFlag)
            {
            }
        }

        if(ui32Length != 0)
        {
            //
            // Setup the uDMA to copy the plaintext data.
            //
            ROM_uDMAChannelAssign(UDMA_CH14_AES0DIN);
            ROM_uDMAChannelAttributeDisable(UDMA_CH14_AES0DIN,
                                            UDMA_ATTR_ALTSELECT |
                                            UDMA_ATTR_USEBURST |
                                            UDMA_ATTR_HIGH_PRIORITY |
                                            UDMA_ATTR_REQMASK);
            ROM_uDMAChannelControlSet(UDMA_CH14_AES0DIN | UDMA_PRI_SELECT,
                                      UDMA_SIZE_32 | UDMA_SRC_INC_32 |
                                      UDMA_DST_INC_NONE | UDMA_ARB_4 |
                                      UDMA_DST_PROT_PRIV);
            ROM_uDMAChannelTransferSet(UDMA_CH14_AES0DIN | UDMA_PRI_SELECT,
                                       UDMA_MODE_BASIC, (void *)pui32Src,
                                       (void *)(AES_BASE + AES_O_DATA_IN_0),
                                       LengthRoundUp(ui32Length) / 4);
            ROM_uDMAChannelEnable(UDMA_CH14_AES0DIN);
            UARTprintf("Data in DMA request enabled.\n");

            //
            // Wait for the data out DMA done interrupt.
            //
            while(!g_bDataOutDMADoneIntFlag)
            {
            }
        }

        //
        // Read out the tag.
        //
        AESTagRead(AES_BASE, pui32Tag);
    }
    else
    {
        //
        // Perform the decryption.
        //
        ROM_AESDataProcessAuth(AES_BASE, pui32Src, pui32Dst, ui32Length,
                               pui32AAD, ui32AADLength, pui32Tag);
    }

    return(true);
}