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.

[参考译文] AM3359:Sitara AM3359上的 AES-GCM 算法不能正常工作

Guru**** 1079370 points
Other Parts Discussed in Thread: AM3359
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1209521/am3359-aes-gcm-algorithm-on-sitara-am3359-not-working-properly

器件型号:AM3359

您好!

我在 AM3359中按照 AM335x ARM Cortex-A8加密附录"技术参考手册"实现了 AES-GCM 解密算法、并在 tivaware_c_serial_2_1_4_178/examples/boards/dk-tm4c129x/AES_GCM_Decrde 中给出的示例。

IM 运行 AES_GCM_Decrypt.c 文件中给定的测试、但未使用 DMA。 解密似乎效果不错、但标签计算仅在关闭和打开 Sitara 后有效一次。 AESTagRead 函数的每两次运行都会返回错误值。

下面是 AESTagRead 函数:

void
AESTagRead(uint32_t ui32Base, uint32_t *pui32TagData)
{
    //
    // Check the arguments.
    //
    ASSERT(ui32Base == AES_BASE);

    //
    // Wait for the output context to be ready.
    //
    while((AES_CTRL_SVCTXTRDY & (HWREG(ui32Base + AES_O_CTRL))) == 0)
    {
    }

    //
    // Read the tag data.
    //
    pui32TagData[0] = HWREG((ui32Base + AES_O_TAG_OUT_0));
    pui32TagData[1] = HWREG((ui32Base + AES_O_TAG_OUT_1));
    pui32TagData[2] = HWREG((ui32Base + AES_O_TAG_OUT_2));
    pui32TagData[3] = HWREG((ui32Base + AES_O_TAG_OUT_3));
}
 

您是否知道硬件启动后仅正确计算一次标签的原因?  此致

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    tivaware_c_series_2_1_4_178/examples/boards/dk-tm4c129x/aes_gcm_decrypde 中给出的示例。

    您是否会分享一些有关参考软件包的详细信息?
    此致!
    -洪

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Hong:

    下面是一些代码:

    测试向量:

    //*****************************************************************************
    //
    // Test Cases from NIST GCM Revised Spec.
    //
    //*****************************************************************************
    tAESGCMTestVector g_psAESGCMTestVectors[] =
    {
        //
        // Test Case #1
        // This is a special case that cannot use the GCM mode because the
        // data and AAD lengths are both zero.  The work around is to perform
        // an ECB encryption on Y0.
        //
        {
            { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
            12,
            { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
            0,
            { 0 },
            0,
            { 0 },
            { 0 },
            { 0xcefce258, 0x61307efa, 0x571d7f36, 0x5a45e7a4 }
        },
    
        //
        // Test Case #2
        // This is the first test in which the AAD length is zero.
        //
        {
            { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
            12,
            { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
            16,
            { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
            0,
            { 0 },
            { 0xceda8803, 0x92a3b660, 0xb9c228f3, 0x78feb271 },
            { 0xd4476eab, 0xbd13ec2c, 0xb2673af5, 0xdfbd5712 }
        },
    
        //
        // Test Case #3
        //
        {
            { 0x92e9fffe, 0x1c736586, 0x948f6a6d, 0x08833067 },
            12,
            { 0xbebafeca, 0xaddbcefa, 0x88f8cade, 0x00000000 },
            64,
            { 0x253231d9, 0xe50684f8, 0xc50959a5, 0x9a26f5af,
              0x53a9a786, 0xdaf73415, 0x3d304c2e, 0x728a318a,
              0x950c3c1c, 0x53096895, 0x240ecf2f, 0x25b5a649,
              0xf5ed6ab1, 0x57e60daa, 0x397b63ba, 0x55d2af1a },
            0,
            { 0 },
            { 0xc21e8342, 0x24747721, 0xb721724b, 0x9cd4d084,
              0x2f21aae3, 0xe0a4022c, 0x237ec135, 0x2ea1ac29,
              0xb214d521, 0x1c936654, 0x5a6a8f7d, 0x05aa84ac,
              0x390ba31b, 0x97ac0a6a, 0x91e0583d, 0x85593f47 },
            { 0xf32a5c4d, 0xa664cd27, 0xbd5af32c, 0xb4faa62b }
        },
    
        //
        // Test Case #4
        // When the data lengths do not align with the block
        // boundary, we need to pad with zeros to ensure unknown
        // data is not copied with uDMA.
        //
        {
            { 0x92e9fffe, 0x1c736586, 0x948f6a6d, 0x08833067 },
            12,
            { 0xbebafeca, 0xaddbcefa, 0x88f8cade, 0x00000000 },
            60,
            { 0x253231d9, 0xe50684f8, 0xc50959a5, 0x9a26f5af,
              0x53a9a786, 0xdaf73415, 0x3d304c2e, 0x728a318a,
              0x950c3c1c, 0x53096895, 0x240ecf2f, 0x25b5a649,
              0xf5ed6ab1, 0x57e60daa, 0x397b63ba, 0x00000000 },
            20,
            { 0xcefaedfe, 0xefbeadde, 0xcefaedfe, 0xefbeadde,
              0xd2daadab, 0x00000000, 0x00000000, 0x00000000 },
            { 0xc21e8342, 0x24747721, 0xb721724b, 0x9cd4d084,
              0x2f21aae3, 0xe0a4022c, 0x237ec135, 0x2ea1ac29,
              0xb214d521, 0x1c936654, 0x5a6a8f7d, 0x05aa84ac,
              0x390ba31b, 0x97ac0a6a, 0x91e0583d, 0x00000000 },
            { 0xbc4fc95b, 0xdba52132, 0x5ae9fa94, 0x471a12e7 }
        },
    
        //
        // Test Case #5
        // This is the first case in which IV is less than
        // 96 bits.
        //
        {
            { 0x92e9fffe, 0x1c736586, 0x948f6a6d, 0x08833067 },
            8,
            { 0xbebafeca, 0xaddbcefa, 0x00000000, 0x00000000 },
            60,
            { 0x253231d9, 0xe50684f8, 0xc50959a5, 0x9a26f5af,
              0x53a9a786, 0xdaf73415, 0x3d304c2e, 0x728a318a,
              0x950c3c1c, 0x53096895, 0x240ecf2f, 0x25b5a649,
              0xf5ed6ab1, 0x57e60daa, 0x397b63ba, 0x00000000 },
            20,
            { 0xcefaedfe, 0xefbeadde, 0xcefaedfe, 0xefbeadde,
              0xd2daadab, 0x00000000, 0x00000000, 0x00000000 },
            { 0x4c3b3561, 0x4a930628, 0x1ff57f77, 0x55472aa2,
              0x712a9b69, 0xf8c6cd4f, 0xf9e56637, 0x23746c7b,
              0x00698073, 0xb2249fe4, 0x4475092b, 0x426b89d4,
              0xe1b58949, 0x070faceb, 0x98453fc2, 0x00000000 },
            { 0xe7d21236, 0x85073b9e, 0x4ae11b56, 0xcbfca2ac }
        },
    
        //
        // Test Case #6
        // This is the first case in which IV is more than
        // 96 bits.
        //
        {
            { 0x92e9fffe, 0x1c736586, 0x948f6a6d, 0x08833067 },
            60,
            { 0x5d221393, 0xe50684f8, 0x5a9c9055, 0xaa6952ff,
              0x38957a6a, 0xa17d4f53, 0xd203c3e4, 0x28a718a3,
              0x51c9c0c3, 0x39958056, 0x42e2f0fc, 0x54526b9a,
              0xf5dbae16, 0x576adea0, 0x9bb337a6, 0x00000000 },
            60,
            { 0x253231d9, 0xe50684f8, 0xc50959a5, 0x9a26f5af,
              0x53a9a786, 0xdaf73415, 0x3d304c2e, 0x728a318a,
              0x950c3c1c, 0x53096895, 0x240ecf2f, 0x25b5a649,
              0xf5ed6ab1, 0x57e60daa, 0x397b63ba, 0x00000000 },
            20,
            { 0xcefaedfe, 0xefbeadde, 0xcefaedfe, 0xefbeadde,
              0xd2daadab },
            { 0x9849e28c, 0xb6155662, 0xac33a003, 0x94b83fa1,
              0xa51291be, 0xa811a2c3, 0x3c2a26ba, 0xa72c7eca,
              0xa4a9e401, 0x903ca4fb, 0x81b2dccc, 0x6f7c8cd4,
              0xd27528d6, 0x0317a4ac, 0xe5ae344c, 0x00000000 },
            { 0xaec59c61, 0xfa0bfeff, 0x3cf42a46, 0x50d09916 }
        }
    };

    在此、GCM 解密

    //*****************************************************************************
    //
    // 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);
    }

    我在没有 DMA 的情况下使用了 AESGCMDecrypt()函数。

    以下是指向 TIvaware 的链接:
    SW-TM4C 软件开发套件(SDK)| TI.com

    此致

    铁莫

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Timo:
    以下是一些供您参考的指针:

    1/. AM335x 加密 TRM
    2.4 AES 模块编程指南

    2/. Linux SDK 内核加密驱动程序
    -在线内核加密驱动程序指南
    software-dl.ti.com/.../Crypto.html
    -内核 AES 驱动程序
    git.ti.com/.../omap-aes.c
    git.ti.com/.../omap-aes-gcm.c

    此致!
    -洪