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.

[参考译文] CC3235SF:CryptoCC32XX_encrypt 失败、-1、永远不会设置 g_bAESReadyFlag

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

https://e2e.ti.com/support/wireless-connectivity/wi-fi-group/wifi/f/wi-fi-forum/1517670/cc3235sf-cryptocc32xx_encrypt-fails-with--1-g_baesreadyflag-is-never-set

器件型号:CC3235SF
主题:SysConfig 中讨论的其他器件

工具/软件:

您好!
我正在尝试使用加密模块对数据进行加密、下面是我用于测试的一个简单示例。

// Initialize the crypto-drivers
CryptoCC32XX_init();
CryptoCC32XX_Handle handle = NULL;

handle = CryptoCC32XX_open(0, CryptoCC32XX_AES | CryptoCC32XX_DES | CryptoCC32XX_HMAC);

if (!handle) {
   Display_printf(dispHandle, 0, 0, "CryptoCC32XX did not open");
}
else
{
    //Space for input and data
    unsigned char   plainData[16]   = "whatsoever123456";
    unsigned int    plainDataLen    = sizeof(plainData);
    unsigned char   cipherData[16]  = {0};
    unsigned int    cipherDataLen   = 0;
    
    // 32 byte key (256bits)
    uint8_t key[32] = {
       0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
       0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
       0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
       0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
    };
    
    //12 byte nonce + 4 bytes counter (for AES_CTR)
    uint8_t nonce[16] = {
        0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
        0xF8, 0xF9, 0xFA, 0xFB, 0x00, 0x00, 0x00, 0x00,
    };
    
    CryptoCC32XX_EncryptParams aesParams;
    aesParams.aes.keySize   = CryptoCC32XX_AES_KEY_SIZE_256BIT;
    aesParams.aes.pKey      = &key[0];
    aesParams.aes.pIV       = (void *)&nonce[0];
    
    int32_t status = CryptoCC32XX_encrypt(handle, CryptoCC32XX_AES_CTR , plainData, plainDataLen, cipherData , &cipherDataLen , &aesParams);
    Display_printf(dispHandle, 0, 0, "Encrypting Data: status = %d", status);
    
}


 "CryptoCC32XX_encrypt ()"返回-1、当我进入函数时、它会正确调用"CryptoCC32XX_aesProcess ()"。
但随后会到达这一部分

    int32_t count = CryptoCC32XX_CONTEXT_READY_MAX_COUNTER;
    /*
    Step1:  Enable Interrupts
    Step2:  Wait for Context Ready Interrupt
    Step3:  Set the Configuration Parameters (Direction,AES Mode and Key Size)
    Step4:  Set the Initialization Vector
    Step5:  Write Key
    Step6:  Start the Crypt Process
    */

    /* Clear the flag. */
    g_bAESReadyFlag = false;

    /* Enable all interrupts. */
    MAP_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, the flag will be set in the Interrupt handler. */
    while((!g_bAESReadyFlag) && (count > 0))
    {
        count --;
    }
    if (count == 0)
    {
        return CryptoCC32XX_STATUS_ERROR;
    }


其中计数器始终变为0、这将返回"CryptoCC32XX_STATUS_ERROR"(-1值)。
因此、在1000次尝试中、"g_bAESReadyFlag"绝不会设置为 true。

它看起来应该在这里的"CryptoCC32XX_aesIntHandler ()"中设置
void CryptoCC32XX_aesIntHandler(void)
{
    uint32_t uiIntStatus;

    /* Read the AES masked interrupt status. */
    uiIntStatus = MAP_AESIntStatus(AES_BASE, true);

    /* Set Different flags depending on the interrupt source. */
    if(uiIntStatus & AES_INT_CONTEXT_IN)
    {
        MAP_AESIntDisable(AES_BASE, AES_INT_CONTEXT_IN);
        g_bAESReadyFlag = true;
    }
    if(uiIntStatus & AES_INT_DATA_IN)
    {
        MAP_AESIntDisable(AES_BASE, AES_INT_DATA_IN);
    }
    if(uiIntStatus & AES_INT_CONTEXT_OUT)
    {
        MAP_AESIntDisable(AES_BASE, AES_INT_CONTEXT_OUT);
    }
    if(uiIntStatus & AES_INT_DATA_OUT)
    {
        MAP_AESIntDisable(AES_BASE, AES_INT_DATA_OUT);
    }
}


如果设置了"AES_INT_CONTENT_IN"标志、 (尽管看起来它会禁用标志、其中"g_bAESReadyFlag"设置为 true。)

从这里开始有点难跟随,但我最好的猜测是这样

//This is a macro
MAP_AESIntEnable(AES_BASE, AES_INT_CONTEXT_IN | AES_INT_CONTEXT_OUT | AES_INT_DATA_IN | AES_INT_DATA_OUT);

//... which expands to
AESIntEnable(AES_BASE, AES_INT_CONTEXT_IN | AES_INT_CONTEXT_OUT | AES_INT_DATA_IN | AES_INT_DATA_OUT);


//The function looks for these flags and sets them (using some magic) if the type is AES.
    AES_INT_CONTEXT_IN
    AES_INT_CONTEXT_OUT
    AES_INT_DATA_IN
    AES_INT_DATA_OUT
    AES_INT_DMA_CONTEXT_IN
    AES_INT_DMA_CONTEXT_OUT
    AES_INT_DMA_DATA_IN
    AES_INT_DMA_DATA_OUT


所以,从我所能看到的。 它应该真的起作用。 如果我遗漏了一些东西、或者我误解了一些东西、请告诉我。
提前感谢您的帮助!

此致
David

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

    这个问题看起来与调试工具有关、因为如果在出现此错误时重新启动器件、那么它将再次开始工作。

    虽然我不知道为什么它会停止工作、但可能会将断点放置在不好的位置、并等待一段时间。
    这可能会导致一些不幸的超时、从而导致这个问题。 (只是猜测)

    但是、我上面的示例将生成错误的解密数据。 因为随机数内的计数器会递增
    使用 CryptoCC32XX_encrypt 和 CryptoCC32XX_D解密 。 这意味着、加密期间的随机数将在解密期间与随机数不匹配。

    解决方案是使用单独的 aesParams 进行加密和解密。 (是合理的、因为它们可能位于不同的器件上)
    函数将更改随机数、因此也要使用2个实例、这一点很重要。

    下面是一个工作示例。 (记得使用 #include  以及在 SysConfig 中添加加密实例)

    // Initialize the crypto-drivers
    CryptoCC32XX_init();
    CryptoCC32XX_Handle handle = NULL;
    handle = CryptoCC32XX_open(0, CryptoCC32XX_AES | CryptoCC32XX_HMAC);
    
    if (!handle) {
    Display_printf(dispHandle, 0, 0, "CryptoCC32XX did not open");
    }
    
    else
    {
        //Test data
        unsigned char   plainData[16] = "whatsoever123456";
        unsigned char   cipherData[16] = {0};
        unsigned char   decryptData[16] = {0};
    
        unsigned int    plainDataLen = sizeof(plainData);
        unsigned int    cipherDataLen = sizeof(plainData);
        unsigned int    decryptDataLen = sizeof(plainData);
        
        //Meta data for Encryption
        uint8_t key[32] = {
           0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
           0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
           0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
           0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
        };
    
        uint8_t nonceEnc[16] = {
            0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
            0xF8, 0xF9, 0xFA, 0xFB, 0x00, 0x00, 0x00, 0x00,
        };
    
        uint8_t nonceDec[16] = {
            0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
            0xF8, 0xF9, 0xFA, 0xFB, 0x00, 0x00, 0x00, 0x00,
        };
        
        
        // Encryption setup
        CryptoCC32XX_EncryptParams aesParamsEnc;
        memset(&aesParamsEnc, 0, sizeof(aesParamsEnc));
    
        aesParamsEnc.aes.keySize = CryptoCC32XX_AES_KEY_SIZE_256BIT;
        aesParamsEnc.aes.pKey = key;
        aesParamsEnc.aes.pIV = nonceEnc;  // Original nonce
        
        //Encrypt
        int32_t status = CryptoCC32XX_encrypt(handle, CryptoCC32XX_AES_CTR , plainData, plainDataLen, cipherData , &cipherDataLen , &aesParamsEnc);
        Display_printf(dispHandle, 0, 0, "Encrypting Data: status = %d", status);
        
        
        // Decryption setup
        CryptoCC32XX_EncryptParams aesParamsDec;
        memset(&aesParamsDec, 0, sizeof(aesParamsDec));
    
        aesParamsDec.aes.keySize = CryptoCC32XX_AES_KEY_SIZE_256BIT;
        aesParamsDec.aes.pKey = key;
        aesParamsDec.aes.pIV = nonceDec;  // Same original nonce
        
        //Decrypt
        status = CryptoCC32XX_decrypt(handle, CryptoCC32XX_AES_CTR, cipherData, cipherDataLen, decryptData, &decryptDataLen, &aesParamsDec);
        Display_printf(dispHandle, 0, 0, "Decrypting Data: status = %d", status);
        
    }

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

    不确定应该开始新问题还是在此继续、但它与测试这些功能有关、因此我会继续。

    在示例中添加 SHA256验证时、我会出现一种奇怪的行为、希望您能解释一下。 下面是代码

        //Put this at the end within the if-else block
        
        //Settings for HMAC-tag
        CryptoCC32XX_HmacParams hmacParams;
        CryptoCC32XX_HmacParams_init(&hmacParams);
        hmacParams.pKey = key;
        hmacParams.moreData = 0;
        
        //Generate tag
        uint8_t tag0[32] ={0};  // Full SHA-256 tag
        status = CryptoCC32XX_sign(handle, CryptoCC32XX_HMAC_SHA256, plainData, plainDataLen, tag0, &hmacParams);
        Display_printf(dispHandle, 0, 0, "Signing Data: status = %d", status);
    
        //Verify tag
        status = CryptoCC32XX_verify(handle, CryptoCC32XX_HMAC_SHA256, plainData, plainDataLen, tag0, &hmacParams);
        Display_printf(dispHandle, 0, 0, "Verifying Signature: status = %d", status);


    此操作将失败、返回-3 (CryptoCC32XX_STATUS_ERROR_VERIFY)。 但是... 经过一些进一步的测试后、它只会失败
    在某些情况下,并在一些奇怪的方式。 以下是一些测试用例的摘要。
        //Put this at the end within the if-else block
        
        //Settings for HMAC-tag
        CryptoCC32XX_HmacParams hmacParams;
        CryptoCC32XX_HmacParams_init(&hmacParams);
        hmacParams.pKey = key;
        hmacParams.moreData = 0;
        
        
        
        //Generate tag  (original pointer)
        uint8_t tag00[32] ={0};  // Full SHA-256 tag
        uint8_t tag01[32] ={0};  // Full SHA-256 tag
        status = CryptoCC32XX_sign(handle, CryptoCC32XX_HMAC_SHA256, plainData, plainDataLen, tag00, &hmacParams);
        Display_printf(dispHandle, 0, 0, "Signing Data: status = %d", status);
    
        //Verify tag  (original, copy)          #Fails  (Wrong content in the tag???)
        memcpy(tag01, tag00, 32);
        status = CryptoCC32XX_verify(handle, CryptoCC32XX_HMAC_SHA256, plainData, plainDataLen, tag01, &hmacParams);
        Display_printf(dispHandle, 0, 0, "Verifying Signature01: status = %d", status);
        
        //Verify tag  (original)                #Fails  (Wrong content in the tag???)
        status = CryptoCC32XX_verify(handle, CryptoCC32XX_HMAC_SHA256, plainData, plainDataLen, tag00, &hmacParams);
        Display_printf(dispHandle, 0, 0, "Verifying Signature00: status = %d", status);
        
        
        
        //Generate tag  (new pointer)
        uint8_t tag10[32] ={0};  // Full SHA-256 tag
        uint8_t tag11[32] ={0};  // Full SHA-256 tag
        status = CryptoCC32XX_sign(handle, CryptoCC32XX_HMAC_SHA256, plainData, plainDataLen, tag10, &hmacParams);
        Display_printf(dispHandle, 0, 0, "Signing Data: status = %d", status);
    
        //Verify tag  (new pointer, copy)       #Succeeds
        memcpy(tag11, tag10, 32);
        status = CryptoCC32XX_verify(handle, CryptoCC32XX_HMAC_SHA256, plainData, plainDataLen, tag11, &hmacParams);
        Display_printf(dispHandle, 0, 0, "Verifying Signature11: status = %d", status);
        
        //Verify tag  (new pointer)             #Succeeds
        status = CryptoCC32XX_verify(handle, CryptoCC32XX_HMAC_SHA256, plainData, plainDataLen, tag10, &hmacParams);
        Display_printf(dispHandle, 0, 0, "Verifying Signature10: status = %d", status);
        
        
        
        //Generate tag  (same pointer)
        status = CryptoCC32XX_sign(handle, CryptoCC32XX_HMAC_SHA256, plainData, plainDataLen, tag10, &hmacParams);
        Display_printf(dispHandle, 0, 0, "Signing Data: status = %d", status);
    
        //Verify tag  (same pointer, copy)      #Succeeds
        memcpy(tag11, tag10, 32);
        status = CryptoCC32XX_verify(handle, CryptoCC32XX_HMAC_SHA256, plainData, plainDataLen, tag11, &hmacParams);
        Display_printf(dispHandle, 0, 0, "Verifying Signature11: status = %d", status);
        
        //Verify tag  (same pointer)            #Succeeds
        status = CryptoCC32XX_verify(handle, CryptoCC32XX_HMAC_SHA256, plainData, plainDataLen, tag10, &hmacParams);
        Display_printf(dispHandle, 0, 0, "Verifying Signature10: status = %d", status);
        
        
        
        //Generate tag  (reuse original)
        status = CryptoCC32XX_sign(handle, CryptoCC32XX_HMAC_SHA256, plainData, plainDataLen, tag00, &hmacParams);
        Display_printf(dispHandle, 0, 0, "Signing Data: status = %d", status);
    
        //Verify tag  (original, copy)          #Fails  (The pointer becomes unusable after the first fail???)
        memcpy(tag01, tag00, 32);
        status = CryptoCC32XX_verify(handle, CryptoCC32XX_HMAC_SHA256, plainData, plainDataLen, tag11, &hmacParams);
        Display_printf(dispHandle, 0, 0, "Verifying Signature11: status = %d", status);
        
        //Verify tag  (reuse original)          #Fails  (The pointer becomes unusable after the first fail???)
        status = CryptoCC32XX_verify(handle, CryptoCC32XX_HMAC_SHA256, plainData, plainDataLen, tag10, &hmacParams);
        Display_printf(dispHandle, 0, 0, "Verifying Signature10: status = %d", status);


    从注释中可以看出、第一次失败后、第一个指针将无法使用、第一个值错误。
    但第二次使用它(使用新指针),然后它工作正常。

    Signing Data: status = 0
    Verifying Signature01: status = -3
    Verifying Signature00: status = -3
    Signing Data: status = 0
    Verifying Signature11: status = 0
    Verifying Signature10: status = 0
    Signing Data: status = 0
    Verifying Signature11: status = 0
    Verifying Signature10: status = 0
    Signing Data: status = 0
    Verifying Signature01: status = -3
    Verifying Signature00: status = -3
    


    不清楚为什么会发生这种情况。

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

    因此、要解决第二个问题、您需要签署一个"dummy"标签以在后台初始化内容。

        // Dummy HMAC to initialize internal state
        uint8_t dummyTag[32] = {0};
        uint8_t dummyData[1] = {0};
        CryptoCC32XX_sign(handle, CryptoCC32XX_HMAC_SHA256, dummyData, 1, dummyTag, &hmacParams);


    然后、在对真实数据签名之前应丢弃该虚拟数据。 我认为在启动时只需执行一次、
    但我不确定这一点。 (注意:我尝试将假用户放入"{}"中以不占用资源、但失败了。)  

    以下是完整的工作示例
    // Initialize the crypto-drivers
    CryptoCC32XX_init();
    CryptoCC32XX_Handle handle = NULL;
    handle = CryptoCC32XX_open(0, CryptoCC32XX_AES | CryptoCC32XX_HMAC);
    
    if (!handle) {
    Display_printf(dispHandle, 0, 0, "CryptoCC32XX did not open");
    }
    
    else
    {
        //Test data
        unsigned char   plainData[16] = "whatsoever123456";
        unsigned char   cipherData[16] = {0};
        unsigned char   decryptData[16] = {0};
    
        unsigned int    plainDataLen = sizeof(plainData);
        unsigned int    cipherDataLen = sizeof(plainData);
        unsigned int    decryptDataLen = sizeof(plainData);
        
        //Meta data for Encryption
        uint8_t key[32] = {
           0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
           0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
           0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
           0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
        };
    
        uint8_t nonceEnc[16] = {
            0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
            0xF8, 0xF9, 0xFA, 0xFB, 0x00, 0x00, 0x00, 0x00,
        };
    
        uint8_t nonceDec[16] = {
            0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
            0xF8, 0xF9, 0xFA, 0xFB, 0x00, 0x00, 0x00, 0x00,
        };
        
        
        
        // Encryption setup
        CryptoCC32XX_EncryptParams aesParamsEnc;
        memset(&aesParamsEnc, 0, sizeof(aesParamsEnc));
    
        aesParamsEnc.aes.keySize = CryptoCC32XX_AES_KEY_SIZE_256BIT;
        aesParamsEnc.aes.pKey = key;
        aesParamsEnc.aes.pIV = nonceEnc;  // Original nonce
        
        //Encrypt
        int32_t status = CryptoCC32XX_encrypt(handle, CryptoCC32XX_AES_CTR , plainData, plainDataLen, cipherData , &cipherDataLen , &aesParamsEnc);
        Display_printf(dispHandle, 0, 0, "Encrypting Data: status = %d", status);
        
        
        // Decryption setup
        CryptoCC32XX_EncryptParams aesParamsDec;
        memset(&aesParamsDec, 0, sizeof(aesParamsDec));
    
        aesParamsDec.aes.keySize = CryptoCC32XX_AES_KEY_SIZE_256BIT;
        aesParamsDec.aes.pKey = key;
        aesParamsDec.aes.pIV = nonceDec;  // Same original nonce
        
        //Decrypt
        status = CryptoCC32XX_decrypt(handle, CryptoCC32XX_AES_CTR, cipherData, cipherDataLen, decryptData, &decryptDataLen, &aesParamsDec);
        Display_printf(dispHandle, 0, 0, "Decrypting Data: status = %d", status);
        
        
        
        //Settings for HMAC-tag
        CryptoCC32XX_HmacParams hmacParams;
        CryptoCC32XX_HmacParams_init(&hmacParams);
        hmacParams.pKey = key;
        hmacParams.moreData = 0;
        
        // Dummy HMAC to initialize internal state
        uint8_t dummyTag[32] = {0};
        uint8_t dummyData[1] = {0};
        CryptoCC32XX_sign(handle, CryptoCC32XX_HMAC_SHA256, dummyData, 1, dummyTag, &hmacParams);
        
        //Generate tag
        uint8_t tag0[32] ={0};  // Full SHA-256 tag
        status = CryptoCC32XX_sign(handle, CryptoCC32XX_HMAC_SHA256, plainData, plainDataLen, tag0, &hmacParams);
        Display_printf(dispHandle, 0, 0, "Signing Data: status = %d", status);
    
        //Verify tag
        status = CryptoCC32XX_verify(handle, CryptoCC32XX_HMAC_SHA256, plainData, plainDataLen, tag0, &hmacParams);
        Display_printf(dispHandle, 0, 0, "Verifying Signature: status = %d", status);
        
        
    }


    这是日志、确认结果。
    Encrypting Data: status = 0
    Decrypting Data: status = 0
    Signing Data: status = 0
    Verifying Signature: status = 0


    希望这能帮助别人!