//*****************************************************************************
//
// Calculate hash subkey with the given key.
// This is performed by encrypting 128 zeroes with the key.
//
//*****************************************************************************
void
AESHashSubkeyGet(uint32_t ui32Keysize, uint32_t *pui32Key,
                 uint32_t *pui32HashSubkey)
{
    uint32_t pui32ZeroArray[8];

    //
    // Put zeroes into the first 4 words of the array.
    //
    pui32ZeroArray[0] = 0x0;
    pui32ZeroArray[1] = 0x0;
    pui32ZeroArray[2] = 0x0;
    pui32ZeroArray[3] = 0x0;

    //
    // Put zeroes into the next 4 words if the key size is 256bit
    //
    if(ui32Keysize == AES_CFG_KEY_SIZE_256BIT)
    {
        pui32ZeroArray[4] = 0x0;
        pui32ZeroArray[5] = 0x0;
        pui32ZeroArray[6] = 0x0;
        pui32ZeroArray[7] = 0x0;
    }

    //
    // Perform the encryption.
    //
    AESECBEncrypt(ui32Keysize, pui32ZeroArray, pui32HashSubkey, pui32Key,
                  (ui32Keysize == AES_CFG_KEY_SIZE_128BIT?16:32));
}
//*****************************************************************************
//
// This example decrypts blocks ciphertext using AES128 and AES256 in GCM
// mode.  It does the decryption first without uDMA and then with uDMA.
// The results are checked after each operation.
//
//*****************************************************************************
int
main(void)
{
    uint32_t pui32PlainText[64], pui32Tag[4], pui32Y0[4], ui32Errors, ui32Idx;
    uint32_t *pui32Key, ui32IVLength, *pui32IV, ui32DataLength;
    uint32_t *pui32ExpPlainText, ui32AuthDataLength, *pui32AuthData;
    uint32_t *pui32CipherText, *pui32ExpTag;
    uint32_t ui32KeySize;
    uint32_t ui32SysClock;
    uint8_t ui8Vector;
    tContext sContext;
    
    //
    // Run from the PLL at 120 MHz.
    //
    ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                           SYSCTL_OSC_MAIN |
                                           SYSCTL_USE_PLL |
                                           SYSCTL_CFG_VCO_480), 120000000);

    //
    // Configure the device pins.
    //
    PinoutSet();

    //
    // Initialize the display driver.
    //
    Kentec320x240x16_SSD2119Init(ui32SysClock);

    //
    // Initialize the graphics context.
    //
    GrContextInit(&sContext, &g_sKentec320x240x16_SSD2119);

    //
    // Draw the application frame.
    //
    FrameDraw(&sContext, "aes-gcm-decrypt");
    
    //
    // Show some instructions on the display
    //
    GrContextFontSet(&sContext, g_psFontCm20);
    GrContextForegroundSet(&sContext, ClrWhite);
    GrStringDrawCentered(&sContext, "Connect a terminal to", -1,
                         GrContextDpyWidthGet(&sContext) / 2, 60, false);
    GrStringDrawCentered(&sContext, "UART0 (115200,N,8,1)", -1,
                         GrContextDpyWidthGet(&sContext) / 2, 80, false);
    GrStringDrawCentered(&sContext, "for more information.", -1,
                         GrContextDpyWidthGet(&sContext) / 2, 100, false);

    //
    // Initialize local variables.
    //
    ui32Errors = 0;
    for(ui32Idx = 0; ui32Idx < 16; ui32Idx++)
    {
        pui32PlainText[ui32Idx] = 0;
    }
    for(ui32Idx = 0; ui32Idx < 4; ui32Idx++)
    {
        pui32Tag[ui32Idx] = 0;
    }

    //
    // Enable stacking for interrupt handlers.  This allows floating-point
    // instructions to be used within interrupt handlers, but at the expense of
    // extra stack usage.
    //
    ROM_FPUStackingEnable();

    //
    // Enable AES interrupts.
    //
    ROM_IntEnable(INT_AES0);

    //
    // Enable debug output on UART0 and print a welcome message.
    //
    ConfigureUART();
    UARTprintf("Starting AES GCM decryption demo.\n");
    GrStringDrawCentered(&sContext, "Starting demo...", -1,
                         GrContextDpyWidthGet(&sContext) / 2, 140, false);

    //
    // Enable the uDMA module.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);

    //
    // Setup the control table.
    //
    ROM_uDMAEnable();
    ROM_uDMAControlBaseSet(g_psDMAControlTable);

    //
    // Initialize the CCM and AES modules.
    //
    if(!AESInit())
    {
        UARTprintf("Initialization of the AES module failed.\n");
        ui32Errors |= 0x00000001;
    }

    //
    // Loop through all the given vectors.
    //
    for(ui8Vector = 0;
        (ui8Vector <
         (sizeof(g_psAESGCMTestVectors) / sizeof(g_psAESGCMTestVectors[0]))) &&
        (ui32Errors == 0);
        ui8Vector++)
    {
        UARTprintf("Starting vector #%d\n", ui8Vector);

        //
        // Get the current vector's data members.
        //
        ui32KeySize = g_psAESGCMTestVectors[ui8Vector].ui32KeySize;
        pui32Key = g_psAESGCMTestVectors[ui8Vector].pui32Key;
        ui32IVLength = g_psAESGCMTestVectors[ui8Vector].ui32IVLength;
        pui32IV = g_psAESGCMTestVectors[ui8Vector].pui32IV;
        ui32DataLength = g_psAESGCMTestVectors[ui8Vector].ui32DataLength;
        pui32ExpPlainText = g_psAESGCMTestVectors[ui8Vector].pui32PlainText;
        ui32AuthDataLength =
            g_psAESGCMTestVectors[ui8Vector].ui32AuthDataLength;
        pui32AuthData = g_psAESGCMTestVectors[ui8Vector].pui32AuthData;
        pui32CipherText = g_psAESGCMTestVectors[ui8Vector].pui32CipherText;
        pui32ExpTag = g_psAESGCMTestVectors[ui8Vector].pui32Tag;

        //
        // If both the data lengths are zero, then it's a special case.
        //
        if((ui32DataLength == 0) && (ui32AuthDataLength == 0))
        {
            UARTprintf("Performing decryption without uDMA.\n");

            //
            // Figure out the value of Y0 depending on the IV length.
            //
            AESGCMY0Get(ui32KeySize, pui32IV, ui32IVLength, pui32Key, pui32Y0);

            //
            // Perform the basic encryption.
            //
            AESECBEncrypt(ui32KeySize, pui32Y0, pui32Tag, pui32Key, 16);
        }
        else
        {
            //
            // Figure out the value of Y0 depending on the IV length.
            //
            AESGCMY0Get(ui32KeySize, pui32IV, ui32IVLength, pui32Key, pui32Y0);

            //
            // Perform the decryption without uDMA.
            //
            UARTprintf("Performing decryption without uDMA.\n");
            AESGCMDecrypt(ui32KeySize, pui32CipherText, pui32PlainText,
                          ui32DataLength, pui32Key, pui32Y0, pui32AuthData,
                          ui32AuthDataLength, pui32Tag, false);
        }

        //
        // Check the results.
        //
        for(ui32Idx = 0; ui32Idx < (ui32DataLength / 4); ui32Idx++)
        {
            if(pui32ExpPlainText[ui32Idx] != pui32PlainText[ui32Idx])
            {
                UARTprintf("Plaintext mismatch on word %d. Exp: 0x%x, Act: "
                           "0x%x\n", ui32Idx, pui32ExpPlainText[ui32Idx],
                           pui32PlainText[ui32Idx]);
                ui32Errors |= (ui32Idx << 16) | 0x00000002;
            }
        }
        for(ui32Idx = 0; ui32Idx < 4; ui32Idx++)
        {
            if(pui32ExpTag[ui32Idx] != pui32Tag[ui32Idx])
            {
                UARTprintf("Tag mismatch on word %d. Exp: 0x%x, Act: 0x%x\n",
                           ui32Idx, pui32ExpTag[ui32Idx], pui32Tag[ui32Idx]);
                ui32Errors |= (ui32Idx << 16) | 0x00000003;
            }
        }

        //
        // Clear the arrays containing the ciphertext and tag to ensure things
        // are working correctly.
        //
        for(ui32Idx = 0; ui32Idx < 16; ui32Idx++)
        {
            pui32PlainText[ui32Idx] = 0;
        }
        for(ui32Idx = 0; ui32Idx < 4; ui32Idx++)
        {
            pui32Tag[ui32Idx] = 0;
        }

        //
        // Only use DMA with the vectors that have data.
        //
        if((ui32DataLength != 0) || (ui32AuthDataLength != 0))
        {
            //
            // Perform the decryption with uDMA.
            //
            UARTprintf("Performing decryption with uDMA.\n");
            AESGCMDecrypt(ui32KeySize, pui32CipherText, pui32PlainText,
                          ui32DataLength, pui32Key, pui32Y0, pui32AuthData,
                          ui32AuthDataLength, pui32Tag, true);

            //
            // Check the result.
            //
            for(ui32Idx = 0; ui32Idx < (ui32DataLength / 4); ui32Idx++)
            {
                if(pui32ExpPlainText[ui32Idx] != pui32PlainText[ui32Idx])
                {
                    UARTprintf("Plaintext mismatch on word %d. Exp: 0x%x, "
                               "Act: 0x%x\n", ui32Idx,
                               pui32ExpPlainText[ui32Idx],
                               pui32PlainText[ui32Idx]);
                    ui32Errors |= (ui32Idx << 16) | 0x00000002;
                }
            }
            for(ui32Idx = 0; ui32Idx < 4; ui32Idx++)
            {
                if(pui32ExpTag[ui32Idx] != pui32Tag[ui32Idx])
                {
                    UARTprintf("Tag mismatch on word %d. Exp: 0x%x, Act: "
                               "0x%x\n", ui32Idx, pui32ExpTag[ui32Idx],
                               pui32Tag[ui32Idx]);
                    ui32Errors |= (ui32Idx << 16) | 0x00000003;
                }
            }
        }
    }

    //
    // Finished.
    //
    if(ui32Errors)
    {
        UARTprintf("Demo failed with error code 0x%x.\n", ui32Errors);
        GrStringDrawCentered(&sContext, "Demo failed.", -1,
                             GrContextDpyWidthGet(&sContext) / 2, 180, false);
    }
    else
    {
        UARTprintf("Demo completed successfully.\n");
        GrStringDrawCentered(&sContext, "Demo passed.", -1,
                             GrContextDpyWidthGet(&sContext) / 2, 180, false);
    }

    //
    // Wait forever.
    //
    while(1)
    {
    }
}
Пример #3
0
//*****************************************************************************
//
// This example encrypts blocks of plaintext using AES128 in ECB mode.  It
// does the encryption first without uDMA and then with uDMA.  The results
// are checked after each operation.
//
//*****************************************************************************
int
main(void)
{
    uint32_t pui32CipherText[16], ui32Errors, ui32Idx, ui32SysClock;
    uint32_t ui32Keysize;
    uint32_t *pui32CipherTextExp;
    tContext sContext;
    uint8_t  ui8Loop;

    //
    // Run from the PLL at 120 MHz.
    //
    ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                           SYSCTL_OSC_MAIN |
                                           SYSCTL_USE_PLL |
                                           SYSCTL_CFG_VCO_480), 120000000);

    //
    // Configure the device pins.
    //
    PinoutSet();

    //
    // Initialize the display driver.
    //
    Kentec320x240x16_SSD2119Init(ui32SysClock);

    //
    // Initialize the graphics context.
    //
    GrContextInit(&sContext, &g_sKentec320x240x16_SSD2119);

    //
    // Draw the application frame.
    //
    FrameDraw(&sContext, "aes-ecb-encrypt");

    //
    // Show some instructions on the display
    //
    GrContextFontSet(&sContext, g_psFontCm20);
    GrStringDrawCentered(&sContext, "Connect a terminal to", -1,
                         GrContextDpyWidthGet(&sContext) / 2, 60, false);
    GrStringDrawCentered(&sContext, "UART0 (115200,N,8,1)", -1,
                         GrContextDpyWidthGet(&sContext) / 2, 80, false);
    GrStringDrawCentered(&sContext, "for more information.", -1,
                         GrContextDpyWidthGet(&sContext) / 2, 100, false);

    //
    // Initialize local variables.
    //
    ui32Errors = 0;
    for(ui32Idx = 0; ui32Idx < 16; ui32Idx++) {
        pui32CipherText[ui32Idx] = 0;
    }

    //
    // Enable stacking for interrupt handlers.  This allows floating-point
    // instructions to be used within interrupt handlers, but at the expense of
    // extra stack usage.
    //
    ROM_FPUStackingEnable();

    //
    // Configure the system clock to run off the internal 16MHz oscillator.
    //
    MAP_SysCtlClockFreqSet(SYSCTL_OSC_INT | SYSCTL_USE_OSC, 16000000);

    //
    // Enable AES interrupts.
    //
    ROM_IntEnable(INT_AES0);

    //
    // Enable debug output on UART0 and print a welcome message.
    //
    ConfigureUART();
    UARTprintf("Starting AES ECB encryption demo.\n");
    GrStringDrawCentered(&sContext, "Starting demo...", -1,
                         GrContextDpyWidthGet(&sContext) / 2, 140, false);

    //
    // Enable the uDMA module.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);

    //
    // Setup the control table.
    //
    ROM_uDMAEnable();
    ROM_uDMAControlBaseSet(g_psDMAControlTable);

    //
    // Initialize the CCM and AES modules.
    //
    if(!AESInit()) {
        UARTprintf("Initialization of the AES module failed.\n");
        ui32Errors |= 0x00000001;
    }

    //
    // Perform the same operation with 128bit key first, then 256bit key.
    //
    for(ui8Loop = 0; ui8Loop < 2; ui8Loop++) {

        ui32Keysize = (ui8Loop == 0)?AES_CFG_KEY_SIZE_128BIT:AES_CFG_KEY_SIZE_256BIT;
        UARTprintf("\nKey Size: %sbit\n", ((ui8Loop == 0)?"128":"256"));

        //
        // Clear the array containing the cipher text.
        //
        for(ui32Idx = 0; ui32Idx < 16; ui32Idx++) {
            pui32CipherText[ui32Idx] = 0;
        }

        //
        // Perform the encryption without uDMA.
        //
        UARTprintf("Performing encryption without uDMA.\n");
        AESECBEncrypt(ui32Keysize, g_pui32AESPlainText, pui32CipherText,
                      (ui8Loop == 0)?g_pui32AES128Key:g_pui32AES256Key,
                      64, false);

        //
        // Check the result.
        //
        pui32CipherTextExp = (ui8Loop == 0)?g_pui32AES128CipherText:
                             g_pui32AES256CipherText;
        for(ui32Idx = 0; ui32Idx < 16; ui32Idx++) {
            if(pui32CipherText[ui32Idx] != pui32CipherTextExp[ui32Idx]) {
                UARTprintf("Ciphertext mismatch on word %d. Exp: 0x%x, Act: "
                           "0x%x\n", ui32Idx, pui32CipherTextExp[ui32Idx],
                           pui32CipherText[ui32Idx]);
                ui32Errors |= (ui32Idx << 16) | 0x00000002;
            }
        }

        //
        // Clear the array containing the ciphertext.
        //
        for(ui32Idx = 0; ui32Idx < 16; ui32Idx++) {
            pui32CipherText[ui32Idx] = 0;
        }

        //
        // Perform the encryption with uDMA.
        //
        UARTprintf("Performing encryption with uDMA.\n");
        AESECBEncrypt(ui32Keysize, g_pui32AESPlainText, pui32CipherText,
                      (ui8Loop == 0)?g_pui32AES128Key:g_pui32AES256Key,
                      64, true);

        //
        // Check the result.
        //
        for(ui32Idx = 0; ui32Idx < 16; ui32Idx++) {
            if(pui32CipherText[ui32Idx] != pui32CipherTextExp[ui32Idx]) {
                UARTprintf("Ciphertext mismatch on word %d. Exp: 0x%x, Act: "
                           "0x%x\n", ui32Idx, pui32CipherTextExp[ui32Idx],
                           pui32CipherText[ui32Idx]);
                ui32Errors |= (ui32Idx << 16) | 0x00000004;
            }
        }
    }

    //
    // Finished.
    //
    if(ui32Errors) {
        UARTprintf("Demo failed with error code 0x%x.\n", ui32Errors);
        GrStringDrawCentered(&sContext, "Demo failed.", -1,
                             GrContextDpyWidthGet(&sContext) / 2, 180, false);
    } else {
        UARTprintf("Demo completed successfully.\n");
        GrStringDrawCentered(&sContext, "Demo passed.", -1,
                             GrContextDpyWidthGet(&sContext) / 2, 180, false);
    }

    while(1) {
    }
}