This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP432 AES Encryption using DMA

Other Parts Discussed in Thread: MSP432WARE, MSP430WARE

I'm working on an AES implementation for the MSP432 that uses the AES256 accelerator and DMA.  I'm using Code Composer Studio and an MSP-EXP432P401R development board.  For starters, I'm just implementing ECB encryption to keep it simple while I'm still learning.  I'm trying to follow the pseudocode in the Technical Reference Manual (SLAU356A p.543).  After a lot of trial and error, I've managed to get it partially working.  If I encrypt 1 AES block of data, it succeeds (i.e., encrypted data is written to the output buffer), but if I attempt to encrypt multiple blocks, it fails (i.e., no data is written to the output buffer).  I've run out of things to try, so any suggestions would be appreciated.  Thanks in advance.


// DriverLib Includes
#include "driverlib.h"

// Standard Includes
#include <stdint.h>
#include <stdbool.h>

// Statics
static uint8_t Data[48] =
{
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F
};
static uint8_t CipherKey[32] =
{
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
};
static uint8_t DataAESencrypted[48];       // Encrypted data

// DMA Control Table
#ifdef ewarm
#pragma data_alignment=1024
#else
#pragma DATA_ALIGN(controlTable, 1024)
#endif
uint8_t controlTable[256];

// AES ECB Encryption using DMA (SLAU356A p.543)
ECB_Encryption(uint8_t* key, uint8_t* plaintext, uint8_t* ciphertext, uint8_t num_blocks)
{
    // Reset AES Controller
    MAP_AES256_reset(AES256_BASE);

    // Configure AES for block cipher. (AESACTL0 Register: SLAU356A p.553)
    // AESCMEN = 1 (DMA)
    AESACTL0 |= AESCMEN;    // Enable DMA ciphermode support
    // AESCMx = 00b (ECB)
    AESACTL0 &= ~AESCM0;    // Select AES cipher mode (00b = ECB)
    AESACTL0 &= ~AESCM1;    // Select AES cipher mode (00b = ECB)
    // AESOPx = 00b (Encryption)
    AESACTL0 &= ~AESOP0;    // Select AES operation (00b = Encryption)
    AESACTL0 &= ~AESOP1;    // Select AES operation (00b = Encryption)
    // AESKLx = 10b (AES256)
    AESACTL0 |= AESKL1;     // Set AES key length (10b = AES256)
    AESACTL0 &= ~AESKL0;    // Set AES key length (10b = AES256)

    // Write key into AESAKEY.
    MAP_AES256_setCipherKey(AES256_BASE, key, AES256_KEYLENGTH_256BIT);

    // Assign DMA channels to AES triggers.
    MAP_DMA_assignChannel(DMA_CH0_AESTRIGGER0);
    MAP_DMA_assignChannel(DMA_CH1_AESTRIGGER1);

    // Set DMA priorities.
    MAP_DMA_enableChannelAttribute(DMA_CH0_AESTRIGGER0, UDMA_ATTR_HIGH_PRIORITY);
    MAP_DMA_enableChannelAttribute(DMA_CH1_AESTRIGGER1, UDMA_ATTR_HIGH_PRIORITY);

    // Setup DMA:
    // DMA0: Triggered by AES trigger 0,
    // Source: AESADOUT, Destination: ciphertext, Size: num_blocks*8 words
    MAP_DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH0_AESTRIGGER0,
            UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1024);
    MAP_DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH0_AESTRIGGER0,
            UDMA_MODE_AUTO,
            (uint16_t*) &(AES256->DOUT),
            ciphertext,
            num_blocks * 8);

    // Assign/Enable Interrupts.
    MAP_DMA_assignInterrupt(DMA_INT1, 0);
    MAP_Interrupt_enableInterrupt(INT_DMA_INT1);
    MAP_Interrupt_enableMaster();

    // Enable DMA Channel 0.
    MAP_DMA_enableChannel(0);

    // Setup DMA:
    // DMA1: Triggered by AES trigger 1,
    // Source: plaintext, Destination: AESADIN, Size: num_blocks*8 words
    MAP_DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH1_AESTRIGGER1,
            UDMA_SIZE_16 | UDMA_SRC_INC_16 | UDMA_DST_INC_NONE | UDMA_ARB_1024);
    MAP_DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH1_AESTRIGGER1,
            UDMA_MODE_AUTO,
            plaintext,
            (uint16_t*) &(AES256->DIN),
            num_blocks * 8);

    // Assign/Enable Interrupts.
    MAP_DMA_assignInterrupt(DMA_INT2, 1);
    MAP_Interrupt_enableInterrupt(INT_DMA_INT2);
    MAP_Interrupt_enableMaster();

    // Enable DMA Channel 1.
    MAP_DMA_enableChannel(1);

    // Start encryption.
    // AESBLKCNTx = Number of 16-byte blocks
    AESACTL1 = (uint16_t) num_blocks;   // Cipher Block Counter: Number of blocks to be encrypted or decrypted. (p.555)

    // End of encryption: DMA0IFG = 1
    // Wait for the AES accelerator to finish.
    while(AESASTAT & AESBUSY)
    {
    }
}

// Completion interrupt for DMA
void DMA_INT1_IRQHandler(void)
{
    MAP_DMA_disableChannel(0);
}

// Completion interrupt for DMA
void DMA_INT2_IRQHandler(void)
{
    MAP_DMA_disableChannel(1);
}

int main(void)
{
    // Stop Watchdog
    MAP_WDT_A_holdTimer();

    // Configuring DMA module
    MAP_DMA_enableModule();
    MAP_DMA_setControlBase(controlTable);

    ECB_Encryption(CipherKey, Data, DataAESencrypted, 3);

    return 0;
}

  • Hello Thomas,

    Sorry you had to wait for an answer here. I'm not completely familiar with MSP432 DMA +AES, but I did take a look at your code here. Were you aware that we already provide an example of MSP432 AES (ECB) + DMA? It is located in the DriverLib Examples in MSP432Ware. You can check it out here.

    When comparing these two code pieces, the only notable difference I saw was the DMA arbitration value set in MAP_DMA_setChannelControl(). Our code example uses a value of '1' while your code uses the max of 1024. Could you try lowering this value to see if this fixes your issue? It maybe that the DMA is not letting go of the bus to the CPU enough for your handover to the next block.

  • Thanks for your helpful response, Jace. I was unaware of that example. For some reason, it is included in the MSP432Ware MSP432P4xx DMA examples, but it is not included in the MSPWare MSP432P4xx DMA examples. I only have MSPWare installed, so I didn't see it. I would have assumed that MSPWare would include all MSP432Ware examples, but apparently that is not the case.

    However, the dma_aes256_ecb_encrypt_decrypt example is working no better than my implementation. The example works fine for one AES block, but fails for multiple AES blocks. Here's the examle, modified for three AES blocks.


    /*
     * -------------------------------------------
     *    MSP432 DriverLib - v3_21_00_05 
     * -------------------------------------------
     *
     * --COPYRIGHT--,BSD,BSD
     * Copyright (c) 2016, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     * --/COPYRIGHT--*/
    /*******************************************************************************
     * MSP432 DMA - AES256 ECB Encryption/Decryption
     *
     * Description: In this code example, the DMA module is used to encrypt and
     * decrypt of block of data using the AES256 module. The ECB (electronic code
     * book) method of encryption/decryption is used in this example. A block of
     * 128-bits of data is fed into the AES256's DIN module by the use of the
     * MSP432's DMA module. While the data is being encrypted, the device is put
     * into LPM0 for power conservation. When the data encryption has finished,
     * the DMA and AES256 modules are reconfigured for decryption and the process
     * is repeated. At the end of the code, a no operation is inserted so that the
     * user can set a breakpoint and observe that the decrypted data is the same
     * as the original plaintext data.
     *
     *              MSP432P401
     *             ------------------
     *         /|\|                  |
     *          | |                  |
     *          --|RST               |
     *            |                  |
     *            |                  |
     *            |                  |
     *            |                  |
     *
     * Author: Timothy Logan
     ******************************************************************************/
    
    /* DriverLib Include */
    #include "driverlib.h"
    
    /* Standard Includes */
    #include <stdint.h>
    #include <string.h>
    
    /* Static Variables */
    static bool isFinished;
    
    /* DMA Control Table */
    #ifdef ewarm
    #pragma data_alignment=1024
    #else
    #pragma DATA_ALIGN(controlTable, 1024)
    #endif
    uint8_t controlTable[256];
    
    /* AES Data and Cipher Key */
    static uint8_t Data[48] =
    {
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
        0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F
    };
    static uint8_t CipherKey[32] =
    {
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
    };
    static uint8_t DataAESencrypted[48];       // Encrypted data
    static uint8_t DataAESdecrypted[48];       // Decrypted data
    
    int main(void)
    {
        /* Halting WDT  */
        MAP_WDT_A_holdTimer();
        MAP_Interrupt_disableMaster();
    
        /* Initializing the variables */
        isFinished = false;
    
        /* Restting the module, enabling AES DMA triggers, and setting to
         * encrypt mode (ECB) */
        AES256->CTL0 = (AES256->CTL0 & ~(AESCM_3 | AESOP_3)) | AESCMEN;
    
        /* Load a cipher key to module */
        MAP_AES256_setCipherKey(AES256_BASE, CipherKey, AES256_KEYLENGTH_256BIT);
    
        /* Configuring DMA module */
        MAP_DMA_enableModule();
        MAP_DMA_setControlBase(controlTable);
    
        /*
         * Primary DMA Channel, AES256
         * Size = 16 bits
         * Source Increment = None
         * Destination Increment = 16bits
         * Arbitration = 1 , no other sources
         */
        MAP_DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH0_AESTRIGGER0,
                UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
        MAP_DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH0_AESTRIGGER0,
                UDMA_MODE_AUTO, (void*) &AES256->DOUT, DataAESencrypted, 3 * 8);
    
        /*
         * Primary DMA Channel, AES256
         * Size = 16 bits
         * Source Increment = 16 bits
         * Destination Increment = None
         * Arbitration = 1 , no other sources
         */
        MAP_DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH1_AESTRIGGER1,
                UDMA_SIZE_16 | UDMA_SRC_INC_16 | UDMA_DST_INC_NONE | UDMA_ARB_1);
        MAP_DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH1_AESTRIGGER1,
                UDMA_MODE_AUTO, (void*) Data, (void*) &AES256->DIN, 3 * 8);
    
        /* Assigning/Enabling Interrupts */
        MAP_DMA_assignInterrupt(DMA_INT1, 0);
        MAP_Interrupt_enableInterrupt(INT_DMA_INT1);
        MAP_DMA_assignChannel(DMA_CH0_AESTRIGGER0);
        MAP_DMA_assignChannel(DMA_CH1_AESTRIGGER1);
        MAP_DMA_clearInterruptFlag(0);
        MAP_DMA_clearInterruptFlag(1);
        MAP_Interrupt_enableMaster();
    
        /* Enabling the DMA channels. Channel 1 is used for transfering the
         * plaintext data to the DIN register and Channel 0 is used to transfer the
         * encrypted data to an intermediary register.
         */
        MAP_DMA_enableChannel(1);
        MAP_DMA_enableChannel(0);
    
        /* Setting the number of 128-bit blocks to encrypt. Setting the CTL1
         * register will initiate the DMA transfer. Once all of the encryption
         * is completed, the DMA completion interrupt will be fired. */
        AES256->CTL1 = 3;
    
        /* Waiting for the DMA finished flag */
        while (!isFinished)
        {
            MAP_PCM_gotoLPM0InterruptSafe();
        }
    
        /* Resetting the AES module */
        isFinished = false;
    
        /* Load a decipher key to module and resetting the module for decryption */
        AES256->CTL0 &= ~AESCMEN;
        MAP_AES256_setDecipherKey(AES256_BASE, CipherKey, AES256_KEYLENGTH_256BIT);
        AES256->CTL0 |= (AESCMEN | AESOP_3);
        AES256->STAT |= AESKEYWR;
    
        /*
         * Primary DMA Channel, AES256
         * Size = 16 bits
         * Source Increment = None
         * Destination Increment = 16bits
         * Arbitration = 1 , no other sources
         */
        MAP_DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH0_AESTRIGGER0,
                UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
        MAP_DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH0_AESTRIGGER0,
                UDMA_MODE_AUTO, (void*) &AES256->DOUT, (void*) DataAESdecrypted, 3 * 8);
    
        /*
         * Primary DMA Channel, AES256
         * Size = 16 bits
         * Source Increment = 16 bits
         * Destination Increment = None
         * Arbitration = 1 , no other sources
         */
        MAP_DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH1_AESTRIGGER1,
                UDMA_SIZE_16 | UDMA_SRC_INC_16 | UDMA_DST_INC_NONE | UDMA_ARB_1);
        MAP_DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH1_AESTRIGGER1,
                UDMA_MODE_AUTO, (void*) DataAESencrypted, (void*) &AES256->DIN, 3 * 8);
    
        /* Enabling the DMA channels. Channel 1 is used for transfering the
         * encrypted data to the DIN register and Channel 0 is used to transfer the
         * decrypted data to the decrypted data register */
        MAP_DMA_enableChannel(1);
        MAP_DMA_enableChannel(0);
    
        /* Setting the number of 128-bit blocks to decrypt. Setting the CTL1
         * register will initiate the DMA transfer. Once all of the decryption
         * is completed, the DMA completion interrupt will be fired. */
        AES256->CTL1 = 3;
    
        while (!isFinished)
        {
            MAP_PCM_gotoLPM0InterruptSafe();
        }
    
        /* Set a breakpoint here. The data in DataAESdecrypted should math the
         * original data in Data.
         */
        __no_operation();
    }
    
    /* Completion interrupt for DMA */
    void DMA_INT1_IRQHandler(void)
    {
        MAP_DMA_disableChannel(0);
        MAP_DMA_disableChannel(1);
        isFinished = true;
    }
    

  • Thomas,

    Sorry about the confusion with the examples. This example is only within the Driverlib examples for MSP432, and not the normal Register Level code examples. Also, we are in the process of splitting MSPWare back into MSP430Ware and MSP432Ware, so some things may not have crossed over fully. I'll take a further look into this with my colleagues to see why it is not working for multiple blocks.
  • Hi Thomas,

     I ran into the same problems but I did find a way to encrypt multiple AES blocks. Here's the example modified for two AES blocks.

    /*
     * -------------------------------------------
     *    MSP432 DriverLib - v3_21_00_05 
     * -------------------------------------------
     *
     * --COPYRIGHT--,BSD,BSD
     * Copyright (c) 2016, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     * --/COPYRIGHT--*/
    /*******************************************************************************
     * MSP432 DMA - AES256 ECB Encryption/Decryption
     *
     * Description: In this code example, the DMA module is used to encrypt and
     * decrypt of block of data using the AES256 module. The ECB (electronic code
     * book) method of encryption/decryption is used in this example. A block of
     * 128-bits of data is fed into the AES256's DIN module by the use of the
     * MSP432's DMA module. While the data is being encrypted, the device is put
     * into LPM0 for power conservation. When the data encryption has finished,
     * the DMA and AES256 modules are reconfigured for decryption and the process
     * is repeated. At the end of the code, a no operation is inserted so that the
     * user can set a breakpoint and observe that the decrypted data is the same
     * as the original plaintext data.
     *
     *              MSP432P401
     *             ------------------
     *         /|\|                  |
     *          | |                  |
     *          --|RST               |
     *            |                  |
     *            |                  |
     *            |                  |
     *            |                  |
     *
     ******************************************************************************/
    
    /* DriverLib Include */
    #include "driverlib.h"
    
    /* Standard Includes */
    #include <stdint.h>
    #include <string.h>
    
    /* Static Variables */
    static bool isFinished;
    
    /* DMA Control Table */
    #ifdef ewarm
    #pragma data_alignment=1024
    #else
    #pragma DATA_ALIGN(controlTable, 1024)
    #endif
    uint8_t controlTable[256];
    
    /* AES Data and Cipher Key */
    static uint8_t Data[32] =
    { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC,
            0xDD, 0xEE, 0xFF, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
    		0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F };
    static uint8_t CipherKey[32] =
    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
            0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
            0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f };
    static uint8_t DataAESencrypted[32];       // Encrypted data
    static uint8_t DataAESdecrypted[32];       // Decrypted data
    
    int main(void)
    {
        /* Halting WDT  */
        MAP_WDT_A_holdTimer();
        MAP_Interrupt_disableMaster();
    
        /* Initializing the variables */
        isFinished = false;
    
        /* Restting the module, enabling AES DMA triggers, and setting to
         * encrypt mode (ECB) */
        AES256->CTL0 = (AES256->CTL0 & ~(AESCM_3 | AESOP_3)) | AESCMEN;
    
        /* Load a cipher key to module */
        MAP_AES256_setCipherKey(AES256_BASE, CipherKey, AES256_KEYLENGTH_256BIT);
    
        /* Configuring DMA module */
        MAP_DMA_enableModule();
        MAP_DMA_setControlBase(controlTable);
    
        /*
         * Primary DMA Channel, AES256
         * Size = 16 bits
         * Source Increment = None
         * Destination Increment = 16bits
         * Arbitration = 1 , no other sources
         */
        MAP_DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH0_AESTRIGGER0,
                UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);
        MAP_DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH0_AESTRIGGER0,
        		UDMA_MODE_AUTO, (void*) &AES256->DOUT, DataAESencrypted, 8);
    
        /*
         * Primary DMA Channel, AES256
         * Size = 16 bits
         * Source Increment = 16 bits
         * Destination Increment = None
         * Arbitration = 1 , no other sources
         */
        MAP_DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH1_AESTRIGGER1,
        		UDMA_SIZE_16 | UDMA_SRC_INC_16 | UDMA_DST_INC_NONE | UDMA_ARB_1);
        MAP_DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH1_AESTRIGGER1,
        		UDMA_MODE_AUTO, (void*) Data, (void*) &AES256->DIN, 8);
    
        /* Assigning/Enabling Interrupts */
        MAP_DMA_assignInterrupt(DMA_INT1, 0);
        MAP_Interrupt_enableInterrupt(INT_DMA_INT1);
        MAP_DMA_assignChannel(DMA_CH0_AESTRIGGER0);
        MAP_DMA_assignChannel(DMA_CH1_AESTRIGGER1);
        MAP_DMA_clearInterruptFlag(0);
        MAP_DMA_clearInterruptFlag(1);
        MAP_Interrupt_enableMaster();
    
        /* Enabling the DMA channels. Channel 1 is used for transfering the
         * plaintext data to the DIN register and Channel 0 is used to transfer the
         * encrypted data to an intermediary register.
         */
        MAP_DMA_enableChannel(1);
        MAP_DMA_enableChannel(0);
    
        /* Setting the number of 128-bit blocks to encrypt. Setting the CTL1
         * register will initiate the DMA transfer. Once all of the encryption
         * is completed, the DMA completion interrupt will be fired. */
        AES256->CTL1 = 2;
    
        /* Waiting for the DMA finished flag */
        while (!isFinished)
        {
            MAP_PCM_gotoLPM0InterruptSafe();
        }
    
        while(1);
    }
    
    /* Completion interrupt for DMA */
    void DMA_INT1_IRQHandler(void)
    {
    	if (AES256->CTL1 == 0)
    	{
    		MAP_DMA_disableChannel(0);
    		MAP_DMA_disableChannel(1);
    		isFinished = true;
    	}
    	else
    	{
    		MAP_DMA_disableChannel(0);
    		MAP_DMA_disableChannel(1);
    
    	    MAP_DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH0_AESTRIGGER0,
    	            UDMA_MODE_AUTO, (void*) &AES256->DOUT, (DataAESencrypted + 16), 8);
    
    	    MAP_DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH1_AESTRIGGER1,
    	    UDMA_MODE_AUTO, (void*) (Data + 16), (void*) &AES256->DIN, 8);
    
    	    MAP_DMA_enableChannel(1);
    	    MAP_DMA_enableChannel(0);
    	}
    }
    
    

    Hopefully this helps.

    David

  • Thanks, David! I tried your work-around, and it works perfectly. However, am I correct in assuming that there should be a "hands-free" way to encrypt multiple blocks rather than re-configuring the DMA channels after every block?
  • Hi Thomas,

    Yes, your assumption is correct and I'm looking into this.

    Best regards,

    David
  • Hi David,

    Any update? Can you give me some insight on the issue? Is there a bug in the silicon?

    Thanks,
    Thomas
  • Has there been any progress? I still need a proper solution. Re-configuring the DMA channels after every block is not practical.
  • Hi Thomas,

     Please find below the updated example.

    /*
     * -------------------------------------------
     *    MSP432 DriverLib - v3_21_00_05 
     * -------------------------------------------
     *
     * --COPYRIGHT--,BSD,BSD
     * Copyright (c) 2016, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     * --/COPYRIGHT--*/
    /*******************************************************************************
     * MSP432 DMA - AES256 ECB Encryption/Decryption
     *
     * Description: In this code example, the DMA module is used to encrypt and
     * decrypt of block of data using the AES256 module. The ECB (electronic code
     * book) method of encryption/decryption is used in this example. A block of
     * 128-bits of data is fed into the AES256's DIN module by the use of the
     * MSP432's DMA module. While the data is being encrypted, the device is put
     * into LPM0 for power conservation. When the data encryption has finished,
     * the DMA and AES256 modules are reconfigured for decryption and the process
     * is repeated. At the end of the code, a no operation is inserted so that the
     * user can set a breakpoint and observe that the decrypted data is the same
     * as the original plaintext data.
     *
     *              MSP432P401
     *             ------------------
     *         /|\|                  |
     *          | |                  |
     *          --|RST               |
     *            |                  |
     *            |                  |
     *            |                  |
     *            |                  |
     *
     ******************************************************************************/
    
    /* DriverLib Include */
    #include "driverlib.h"
    
    /* Standard Includes */
    #include <stdint.h>
    #include <string.h>
    
    /* Static Variables */
    
    /* DMA Control Table */
    #ifdef ewarm
    #pragma data_alignment=1024
    #else
    #pragma DATA_ALIGN(controlTable, 1024)
    #endif
    uint8_t controlTable[256];
    
    /* AES Data and Cipher Key */
    static uint8_t Data[64] =
    {       0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
    	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
    	0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF,
    	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
    };
    
    static uint8_t CipherKey[32] =
    {
    		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
    		0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f 
    };
    
    static uint8_t DataAESencrypted[64];       // Encrypted data
    
    uint8_t numBlocks = 4;
    
    int main(void)
    {
        /* Halting WDT  */
        MAP_WDT_A_holdTimer();
        MAP_Interrupt_disableMaster();
    
        /* Restting the module, enabling AES DMA triggers, and setting to
         * encrypt mode (ECB) */
        AES256->CTL0 = (AES256->CTL0 & ~(AESCM_3 | AESOP_3)) | AESCMEN;
    
        /* Load a cipher key to module */
        MAP_AES256_setCipherKey(AES256_BASE, CipherKey, AES256_KEYLENGTH_256BIT);
    
        /* Configuring DMA module */
        MAP_DMA_enableModule();
        MAP_DMA_setControlBase(controlTable);
    
        /*
         * Primary DMA Channel, AES256
         */
        MAP_DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH0_AESTRIGGER0, 
        		UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_8);
        MAP_DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH0_AESTRIGGER0, 
        		UDMA_MODE_BASIC, (void*) &AES256->DOUT, DataAESencrypted, 8*numBlocks);
    
        /*
         * Primary DMA Channel, AES256
         */
        MAP_DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH1_AESTRIGGER1, 
        		UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_16);
        MAP_DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH1_AESTRIGGER1, 
        		UDMA_MODE_BASIC, (void*) Data, (void*) &AES256->DIN, 16*numBlocks);
    
        /* Assigning/Enabling Interrupts */
        MAP_DMA_assignInterrupt(DMA_INT1, 0);
        MAP_DMA_assignInterrupt(DMA_INT2, 1);
        MAP_Interrupt_enableInterrupt(INT_DMA_INT1);
        MAP_DMA_assignChannel(DMA_CH0_AESTRIGGER0);
        MAP_DMA_assignChannel(DMA_CH1_AESTRIGGER1);
        MAP_DMA_clearInterruptFlag(0);
        MAP_DMA_clearInterruptFlag(1);
        MAP_Interrupt_enableMaster();
    
        /* Enabling the DMA channels. Channel 1 is used for transfering the
         * plaintext data to the DIN register and Channel 0 is used to transfer the
         * encrypted data to an intermediary register.
         */
        MAP_DMA_enableChannel(1);
        MAP_DMA_enableChannel(0);
    
        /* Setting the number of 128-bit blocks to encrypt. Setting the CTL1
         * register will initiate the DMA transfer. Once all of the encryption
         * is completed, the DMA completion interrupt will be fired. */
        AES256->CTL1 = numBlocks;
    
        PCM_gotoLPM0();
    
        while(1);
    }
    
    /* Completion interrupt for DMA */
    void DMA_INT1_IRQHandler(void)
    {
    }

    Best regards,

       David

**Attention** This is a public forum