SAMV71 Xplained Ultra Software Package 1.4

main.c

Go to the documentation of this file.
00001 /* ----------------------------------------------------------------------------
00002  *         SAM Software Package License 
00003  * ----------------------------------------------------------------------------
00004  * Copyright (c) 2014, Atmel Corporation
00005  *
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *
00011  * - Redistributions of source code must retain the above copyright notice,
00012  * this list of conditions and the disclaimer below.
00013  *
00014  * Atmel's name may not be used to endorse or promote products derived from
00015  * this software without specific prior written permission.
00016  *
00017  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00019  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
00020  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00022  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00023  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00024  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00025  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
00026  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  * ----------------------------------------------------------------------------
00028  */
00029 
00030 /**
00031  *  \page aes Advanced Encryption Standard Example
00032  *
00033  *  \section Purpose
00034  *  This application demonstrates the Advanced Encryption Standard (AES) 
00035  *  peripheral integrated in some of SAMV7 micro-controllers family. It encrypts
00036  *  and decrypts several test values in Electronic CodeBook (ECB) and Cipher Block
00037  *  Chaining (CBC),OBC,OFB,TRC modes and checks them against the known answers.
00038  * 
00039  * \section Requirements
00040  *
00041  * This package can be used with SAM V71 Xplained Ultra board.
00042  *
00043  *  \section Description
00044  * This example shows how to configure AES in encryption and decryption mode.
00045  * In encryption mode, it encrypts plain text with one of ECB, CBC, OFB ,CFB and 
00046  * CTR mode. Programmable key mode with processing using with or without DMA 
00047  * support. 
00048  * In decryption mode, it decrypts cipher data generate from encryption mode and 
00049  * get the known plain value.
00050  *
00051  *  \section Usage
00052  *
00053  *  -# Build the program and download it inside the SAM V71 Xplained Ultra board. 
00054  *     Please refer to the Getting Started with SAM V71 Microcontrollers.pdf
00055  *  -# On the computer, open and configure a terminal application
00056  *     (e.g. HyperTerminal on Microsoft Windows) with these settings:
00057  *    - 115200 baud rate
00058  *    - 8 bits of data
00059  *    - No parity
00060  *    - 1 stop bit
00061  *    - No flow control
00062  *  -# In the terminal window, the
00063  *     following text should appear (values depend on the board and chip used):
00064  *     \code
00065  *      -- AES Example xxx --
00066  *      -- SAMxxxxx-xx
00067  *      -- Compiled: xxx xx xxxx xx:xx:xx --
00068  *      -- Menu Choices for this example--
00069  *      \endcode
00070  *  -# Input command according to the menu.
00071  *
00072  *  \section References
00073  *  - aes/main.c
00074  *  - aes.c 
00075  *  - aes.h */
00076 
00077 /** \file
00078  *
00079  *  This file contains all the specific code for the AES
00080  */
00081 
00082 /*----------------------------------------------------------------------------
00083  *        Headers
00084  *----------------------------------------------------------------------------*/
00085 #include <board.h>
00086 #include <string.h>
00087 /*----------------------------------------------------------------------------
00088  *        Local definitions
00089  *----------------------------------------------------------------------------*/
00090 #define DATA_LEN_INBYTE   640
00091 #define DATA_LEN_INWORD (DATA_LEN_INBYTE/4)
00092 #define DATA_LEN_INDWORD (DATA_LEN_INBYTE/8)
00093 
00094 #define AES_VECTOR_0     0x11223344
00095 #define AES_VECTOR_1     0x55667788
00096 #define AES_VECTOR_2     0x11112222
00097 #define AES_VECTOR_3     0x33334444
00098 
00099 #define AES_KEY_0       0x01234567
00100 #define AES_KEY_1       0x89ABCDEF
00101 #define AES_KEY_2       0x76543210
00102 #define AES_KEY_3       0xFEDCBA98
00103 #define AES_KEY_4       0x55AA55AA
00104 #define AES_KEY_5       0xAA55AA55
00105 #define AES_KEY_6       0x0000FFFF
00106 #define AES_KEY_7       0xFFFF0000
00107 
00108 /*----------------------------------------------------------------------------
00109  *        Local variables
00110  *----------------------------------------------------------------------------*/
00111 const uint32_t aes_keys[8] = {AES_KEY_0, AES_KEY_1, AES_KEY_2, AES_KEY_3, 
00112     AES_KEY_4, AES_KEY_5, AES_KEY_6, AES_KEY_7};
00113 const uint32_t aes_vectors[4] = { AES_VECTOR_0, 
00114                                 AES_VECTOR_1, 
00115                                 AES_VECTOR_2, 
00116                                 AES_VECTOR_3};
00117 
00118 static uint32_t bufPlaint[DATA_LEN_INWORD];
00119 static uint32_t bufCipher[DATA_LEN_INWORD];
00120 static uint32_t bufOut[DATA_LEN_INWORD];
00121 
00122 char plaintext[DATA_LEN_INBYTE]="\
00123   The Advanced Encryption Standard (AES) is compliant with the A\
00124 merican FIPS (Federal Information Processing Standard) Publicati\
00125 on 197 specification. AES supports all five confidentiality mode\
00126 s of operation for symmetrical key block cipher algorithms (ECB,\
00127 CBC,OFB, CFB and CTR), as specified in the NIST Special Publicat\
00128 ion 80038A. It is compatible with all these modes via Peripheral\
00129  DMA Controller channels, minimizing processor intervention for \
00130 large buffer transfers.The 128-bit/192-bit/256-bit key is stored\
00131 in four/six/eight 32-bit registers (AES_KEYWRx) which are all wr\
00132 ite-only .......................................................";
00133 
00134 static uint32_t operationMode, startMode, keyMode, keylength;
00135 static uint32_t desDone;
00136 /** Global DMA driver instance for all DMA transfers in application. */
00137 static sXdmad xdmad;
00138 static sXdmadCfg xdmadCfg;
00139 static uint32_t dmaWriteChannel,dmaReadChannel;
00140 static LinkedListDescriporView1 dmaWriteLinkList[DATA_LEN_INWORD];
00141 static LinkedListDescriporView1 dmaReadLinkList[DATA_LEN_INWORD];
00142 
00143 /*----------------------------------------------------------------------------
00144  *        Local functions
00145  *----------------------------------------------------------------------------*/
00146 /**
00147  * \brief Display main menu.
00148  */
00149 static void _displayMenu(void)
00150 {
00151     uint8_t ucChar[5];
00152     printf("\n\rAES Menu :\n\r");
00153     printf("Press [0|1|2|3|4] to set Operation Mode \n\r");
00154     ucChar[0] = (operationMode == AES_MR_OPMOD_ECB) ? 'X' : ' ';
00155     ucChar[1] = (operationMode == AES_MR_OPMOD_CBC) ? 'X' : ' ';
00156     ucChar[2] = (operationMode == AES_MR_OPMOD_OFB) ? 'X' : ' ';
00157     ucChar[3] = (operationMode == AES_MR_OPMOD_CFB) ? 'X' : ' ';
00158     ucChar[4] = (operationMode == AES_MR_OPMOD_CTR) ? 'X' : ' ';
00159     printf("   0: ECB[%c] 1: CBC[%c] 2: OFB[%c] 3: CFB[%c] 4: CTR[%c] \n\r", 
00160             ucChar[0], ucChar[1], ucChar[2], ucChar[3], ucChar[4]);
00161     printf("Press [5|6|7| set key size\n\r");
00162     ucChar[0] = (keyMode == AES_MR_KEYSIZE_AES128) ? 'X' : ' ';
00163     ucChar[1] = (keyMode == AES_MR_KEYSIZE_AES192) ? 'X' : ' ';
00164     ucChar[2] = (keyMode == AES_MR_KEYSIZE_AES256) ? 'X' : ' ';
00165     printf("    5: key 128-bits[%c] 6: key 192-bits[%c] 7: key 256-bits[%c]\n\r", 
00166             ucChar[0],ucChar[1],ucChar[2]);
00167     printf("Press [m|a|d] to set Start Mode \n\r");
00168     ucChar[0] = (startMode == AES_MR_SMOD_MANUAL_START) ? 'X' : ' ';
00169     ucChar[1] = (startMode == AES_MR_SMOD_AUTO_START) ? 'X' : ' ';
00170     ucChar[2] = (startMode == AES_MR_SMOD_IDATAR0_START) ? 'X' : ' ';
00171     printf("   m: MANUAL_START[%c] a: AUTO_START[%c] d: DMA[%c]\n\r", 
00172             ucChar[0],ucChar[1],ucChar[2]);
00173     printf("   p: Begin the encryption/decryption process \n\r");
00174     printf("   h: Display this menu\n\r");
00175     printf("\n\r");
00176 }
00177 
00178 /**
00179  * \brief xDMA handler.
00180  */
00181 void XDMAC_Handler(void)
00182 {
00183     XDMAD_Handler(&xdmad);
00184 }
00185 
00186 /**
00187  * \brief xDMA initialization.
00188  */
00189 
00190 static void _xdma_init(void)
00191 {
00192     /* Initialize XDMA driver instance with polling mode */
00193     XDMAD_Initialize( &xdmad, 1 );
00194 
00195     /* Allocate a XDMA channel, Write accesses into AES_IDATARx */
00196     dmaWriteChannel = XDMAD_AllocateChannel( &xdmad, XDMAD_TRANSFER_MEMORY, ID_AES);
00197     if ( dmaWriteChannel == XDMAD_ALLOC_FAILED ) {
00198         printf("-E- Can't allocate XDMA channel\n\r");
00199     }
00200     XDMAD_PrepareChannel(&xdmad, dmaWriteChannel );
00201 
00202     /* Allocate a XDMA channel, Read accesses into AES_ODATARx */
00203     dmaReadChannel = XDMAD_AllocateChannel( &xdmad, ID_AES, XDMAD_TRANSFER_MEMORY);
00204     if ( dmaReadChannel == XDMAD_ALLOC_FAILED ) {
00205         printf("-E- Can't allocate XDMA channel\n\r");
00206     }
00207     XDMAD_PrepareChannel(&xdmad, dmaReadChannel );
00208 }
00209 
00210 /**
00211  * \brief Configure xDMA write linker list for AES transfer.
00212  */
00213 static void _xdma_configure_write(uint32_t *buf, uint32_t len)
00214 {
00215     uint32_t i;
00216     uint32_t xdmaCndc;
00217     for ( i = 0; i < len; i++) {
00218         dmaWriteLinkList[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 
00219             |(( i == len - 1) ? 0: XDMA_UBC_NDE_FETCH_EN)
00220             | XDMA_UBC_NDEN_UPDATED 
00221             | 4 ;
00222         dmaWriteLinkList[i].mbr_sa = (uint32_t)&buf[i * 4];
00223         dmaWriteLinkList[i].mbr_da = (uint32_t)&(AES->AES_IDATAR[0]);
00224         if ( i == len - 1) dmaWriteLinkList[i].mbr_nda = 0;
00225         else dmaWriteLinkList[i].mbr_nda = (uint32_t)&dmaWriteLinkList[ i + 1 ];
00226     }
00227     xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN 
00228         | XDMAC_CC_MBSIZE_SINGLE 
00229         | XDMAC_CC_DSYNC_MEM2PER 
00230         | XDMAC_CC_CSIZE_CHK_4 
00231         | XDMAC_CC_DWIDTH_WORD
00232         | XDMAC_CC_SIF_AHB_IF0 
00233         | XDMAC_CC_DIF_AHB_IF1 
00234         | XDMAC_CC_SAM_INCREMENTED_AM 
00235         | XDMAC_CC_DAM_FIXED_AM 
00236         | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber( ID_AES, XDMAD_TRANSFER_TX ));
00237 
00238     xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1 
00239         | XDMAC_CNDC_NDE_DSCR_FETCH_EN 
00240         | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED
00241         | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED ;
00242     SCB_CleanInvalidateDCache();
00243     XDMAD_ConfigureTransfer( &xdmad, dmaWriteChannel, &xdmadCfg, xdmaCndc, 
00244         (uint32_t)&dmaWriteLinkList[0], XDMAC_CIE_LIE);
00245 }
00246 
00247 /**
00248  * \brief Configure xDMA read linker list for AES transfer.
00249  */
00250 static void _xdma_configure_read(uint32_t *buf, uint32_t len)
00251 {
00252     uint32_t i;
00253     uint32_t xdmaCndc;
00254     for ( i = 0; i < len; i++) {
00255         dmaReadLinkList[i].mbr_ubc = XDMA_UBC_NVIEW_NDV1 
00256             | (( i == len - 1) ? 0: XDMA_UBC_NDE_FETCH_EN)
00257             | XDMA_UBC_NDEN_UPDATED 
00258             | 4 ;
00259         dmaReadLinkList[i].mbr_sa  = (uint32_t)&(AES->AES_ODATAR[0]);
00260         dmaReadLinkList[i].mbr_da = (uint32_t)&buf[i * 4];
00261         if ( i == len - 1 ) dmaReadLinkList[i].mbr_nda = 0;
00262         else
00263             dmaReadLinkList[i].mbr_nda = (uint32_t)&dmaReadLinkList[ i + 1 ];
00264     }
00265     xdmadCfg.mbr_cfg = XDMAC_CC_TYPE_PER_TRAN 
00266         | XDMAC_CC_MBSIZE_SINGLE 
00267         | XDMAC_CC_DSYNC_PER2MEM 
00268         | XDMAC_CC_CSIZE_CHK_4 
00269         | XDMAC_CC_DWIDTH_WORD
00270         | XDMAC_CC_SIF_AHB_IF1 
00271         | XDMAC_CC_DIF_AHB_IF0 
00272         | XDMAC_CC_SAM_FIXED_AM 
00273         | XDMAC_CC_DAM_INCREMENTED_AM 
00274         | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber( ID_AES, XDMAD_TRANSFER_RX ));
00275     xdmaCndc = XDMAC_CNDC_NDVIEW_NDV1 
00276         | XDMAC_CNDC_NDE_DSCR_FETCH_EN 
00277         | XDMAC_CNDC_NDSUP_SRC_PARAMS_UPDATED
00278         | XDMAC_CNDC_NDDUP_DST_PARAMS_UPDATED ;
00279     SCB_CleanInvalidateDCache();
00280     XDMAD_ConfigureTransfer( &xdmad, dmaReadChannel, &xdmadCfg, xdmaCndc, 
00281         (uint32_t)&dmaReadLinkList[0], XDMAC_CIE_LIE);
00282 }
00283 
00284 /**
00285  * \brief AES interrupt hander.
00286  */
00287 void AES_Handler(void){
00288     if ((AES_GetStatus() & AES_ISR_DATRDY) == AES_ISR_DATRDY) {
00289         /* Disable AES interrupt */
00290     AES_DisableIt(AES_IER_DATRDY);
00291         desDone = 1;
00292     }
00293 }
00294 
00295 static void _startAES(void)
00296 {
00297     char * p;
00298     uint32_t i;
00299     uint32_t loop = DATA_LEN_INWORD;
00300     /* A software triggered hardware reset of the AES interface is performed */
00301     AES_SoftReset();
00302     /* Configure and enable interrupt on RC compare */    
00303     NVIC_ClearPendingIRQ(AES_IRQn);
00304     NVIC_EnableIRQ(AES_IRQn);
00305 
00306     if (startMode == AES_MR_SMOD_IDATAR0_START) {
00307         _xdma_init();
00308         loop = 1;
00309     }
00310     memcpy((char*)bufPlaint, plaintext, DATA_LEN_INBYTE);
00311     for ( i = 0 ; i < DATA_LEN_INWORD; i++) {
00312         bufCipher[i] = 0xffffffff;
00313         bufOut[i]  = 0xffffffff;
00314     }
00315     for( i = 0; i < loop; i+= 4) {
00316         /* Encrypts data */
00317         desDone = 0;
00318         /* Enable AES interrupt */
00319         AES_EnableIt(AES_IER_DATRDY);
00320 
00321         AES_Configure( AES_MR_CIPHER_ENCRYPT
00322                 | keyMode
00323                 | startMode
00324                 | operationMode
00325                 );
00326         /* Write the 128-bit/192-bit/256-bit key(s) in the Key Registers 
00327             (AES_KEYxWRx)*/
00328         AES_WriteKey(aes_keys, keylength);
00329 
00330         /* The Initialization Vector Registers concern all modes except ECB. */
00331         if (operationMode != AES_MR_OPMOD_ECB)
00332             AES_SetVector(aes_vectors);
00333         if (startMode != AES_MR_SMOD_IDATAR0_START) {
00334             /* Write the data to be encrypted in the authorized Input Data 
00335                 Registers */
00336             AES_SetInput(&bufPlaint[i]);
00337             if (startMode == AES_MR_SMOD_MANUAL_START) 
00338                 /* Set the START bit in the AES Control register AES_CR to 
00339                     begin the encryption process. */
00340                 AES_Start();
00341             while(!desDone);
00342             AES_GetOutput(&bufCipher[i]);
00343         } else {
00344             AES_SetDataLen(DATA_LEN_INBYTE);
00345             _xdma_configure_write(bufPlaint, DATA_LEN_INWORD/4);
00346             _xdma_configure_read(bufCipher, DATA_LEN_INWORD/4);
00347             XDMAD_StartTransfer( &xdmad, dmaWriteChannel);
00348             XDMAD_StartTransfer( &xdmad, dmaReadChannel );
00349             while (XDMAD_IsTransferDone(&xdmad, dmaReadChannel));
00350         }
00351         /* Decrypts data */
00352         desDone = 0;
00353         /* Enable AES interrupt */
00354         AES_EnableIt(AES_IER_DATRDY);
00355         AES_Configure( AES_MR_CIPHER_DECRYPT
00356                 | keyMode
00357                 | startMode
00358                 | operationMode );
00359         /* Write the 128-bit/192-bit/256-bit key(s) in the Key Registers 
00360             (AES_KEYxWRx)*/
00361         AES_WriteKey(aes_keys, keylength);
00362 
00363         /* The Initialization Vector Registers concern all modes except ECB. */
00364         if (operationMode != AES_MR_OPMOD_ECB)
00365             AES_SetVector(aes_vectors);
00366         if (startMode != AES_MR_SMOD_IDATAR0_START) {
00367             /* Write the data to be decrypted in the authorized Input Data 
00368                 Registers */
00369             AES_SetInput(&bufCipher[i]);
00370             if (startMode == AES_MR_SMOD_MANUAL_START) 
00371                 /* Set the START bit in the AES Control register AES_CR to 
00372                 begin the decryption process. */
00373                 AES_Start();
00374             while(!desDone);
00375             AES_GetOutput(&bufOut[i]);
00376         } else {
00377             XDMAD_FreeChannel(&xdmad, dmaWriteChannel);
00378             XDMAD_FreeChannel(&xdmad, dmaReadChannel);
00379             _xdma_init();
00380             AES_SetDataLen(DATA_LEN_INBYTE);
00381             SCB_CleanInvalidateDCache();
00382             _xdma_configure_write(bufCipher, DATA_LEN_INWORD / 4);
00383             _xdma_configure_read(bufOut, DATA_LEN_INWORD / 4);
00384             XDMAD_StartTransfer( &xdmad, dmaWriteChannel);
00385             XDMAD_StartTransfer( &xdmad, dmaReadChannel );
00386             while (XDMAD_IsTransferDone(&xdmad, dmaReadChannel));
00387             SCB_CleanInvalidateDCache();
00388         }
00389     }
00390     p = (char*)bufOut;
00391     printf("Dump plain text after AES decryption ...\n\r");
00392     for( i = 0; i < DATA_LEN_INBYTE; i++) {
00393         printf("%c", *p++);
00394     }
00395 }
00396 
00397 /*----------------------------------------------------------------------------
00398  *        Exported functions
00399  *----------------------------------------------------------------------------*/
00400 
00401 /**
00402  *  \brief AES Application entry point.
00403  *
00404  *  \return Unused (ANSI-C compatibility).
00405  *  \callgraph
00406  */
00407 int main( void )
00408 {
00409     uint32_t key;
00410     /* Disable watchdog */
00411     WDT_Disable( WDT ) ;
00412    
00413     /* Enable I and D cache */
00414     SCB_EnableICache();
00415     SCB_EnableDCache();
00416     
00417     /* Output example information */
00418     printf("-- AES Example %s --\n\r", SOFTPACK_VERSION ) ;
00419     printf("-- %s\n\r", BOARD_NAME);
00420     printf( "-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__ , COMPILER_NAME) ;
00421 
00422     /* Enable AES peripheral clock */
00423     PMC_EnablePeripheral(ID_AES);
00424 
00425     /* Configure and enable interrupt on XDMA */
00426     NVIC_ClearPendingIRQ(XDMAC_IRQn);
00427     NVIC_SetPriority( XDMAC_IRQn ,1);
00428     NVIC_EnableIRQ(XDMAC_IRQn);
00429 
00430     /* Display menu */
00431     _displayMenu();
00432     operationMode = AES_MR_OPMOD_ECB;
00433     startMode = AES_MR_SMOD_MANUAL_START;
00434 
00435     keyMode = 0;
00436     for(;;) {
00437         key = DBG_GetChar();
00438         switch (key) {
00439         case '5': case '6': case '7':
00440             keyMode = ((key - '5') << AES_MR_KEYSIZE_Pos ); 
00441             _displayMenu();
00442             keylength = (keyMode == AES_MR_KEYSIZE_AES128) ? 16 : \
00443                 ((keyMode == AES_MR_KEYSIZE_AES192)? 24: 32);
00444             break;
00445         case '0': case '1': case '2': case '3': case '4':
00446             operationMode = ((key - '0') << AES_MR_OPMOD_Pos ); 
00447             _displayMenu();
00448             break;
00449         case 'm': case 'M': 
00450             startMode = AES_MR_SMOD_MANUAL_START; _displayMenu();
00451             break;
00452         case 'a': case 'A':
00453             startMode = AES_MR_SMOD_AUTO_START; _displayMenu();
00454             break;
00455         case 'd': case 'D':
00456             startMode = AES_MR_SMOD_IDATAR0_START; _displayMenu();
00457             break;
00458         case 'h': case 'H':
00459             _displayMenu();
00460             break;
00461         case 'p': case 'P':
00462             _startAES();
00463             break;
00464         }
00465     }
00466 }
00467 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines