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.

[参考译文] LP-EM-CC2745R10-Q1:ECDH_OPEN ()返回 NULL

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

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1487961/lp-em-cc2745r10-q1-ecdh_open-return-null

器件型号:LP-EM-CC2745R10-Q1
主题中讨论的其他器件: SysConfig

工具与软件:

您好!

以下是我的软件和硬件版本:

LP-EM-CC2745R10-Q1

simplelink_lowpower_f3_sdk_8_40_00_61

CCS 版本:20.0.2.5__1.6.2

我根据 examples\rtos\LP_EM_CC2745R10_Q1\ble5stack\basic_ble 例程测试了 f3 SDK 中的 HSM 功能、并测试了 AES-CBC/AES-GCM 可以正常工作。 但当我添加 ECDH 测试时,我一直得到 ECDH_OPEN()返回 NULL。  我曾尝试在论坛上查找相关问题、并进行了一些修改、例如添加预定义符号"DeviceFamily_CC27XX"和"USE_HSM"、但这些仍然没有解决。  您能不能帮我看看导致出现这种现象的原因是什么?

这是我的函数、我删除了线程中的函数、然后刚刚运行我自己的测试函数

static const char ecdh_msg[]  = "\n\n\rECDH Open fail";

static void ECDH_Test(void)
{
    ECDH_Handle ecdhHandle;
    ECDH_Params ecdhParams;
    CryptoKey myPrivateKey;
    CryptoKey myPublicKey;
    CryptoKey theirPublicKey;
    CryptoKey theirPrivateKey;
    CryptoKey mysharedSecret;
    CryptoKey theirsharedSecret;
    CryptoKey symmetricKey;

    int_fast16_t operationResult;
    ECDH_OperationGeneratePublicKey operationGeneratePublicKey;
    ECDH_OperationComputeSharedSecret operationComputeSharedSecret;

    ECDH_init();

    ECDH_Params_init(&ecdhParams);
    ecdhParams.returnBehavior = ECDH_RETURN_BEHAVIOR_BLOCKING;

    ecdhHandle = ECDH_open(CONFIG_ECDH0, &ecdhParams);

    if (!ecdhHandle) 
    {
        printMessage(uart, (char *)ecdh_msg, NULL, 0);
        while(1);
    }

    // CryptoKeyPlaintextHSM_initKey(&myPrivateKey, myPrivateKeyingMaterial, sizeof(myPrivateKeyingMaterial));
    // CryptoKeyPlaintextHSM_initBlankKey(&myPublicKey, myPublicKeyingMaterial, sizeof(myPublicKeyingMaterial));

    // ECDH_OperationGeneratePublicKey_init(&operationGeneratePublicKey);
    // operationGeneratePublicKey.curve                 = &ECCParams_Curve25519;
    // operationGeneratePublicKey.myPrivateKey          = &myPrivateKey;
    // operationGeneratePublicKey.myPublicKey           = &myPublicKey;
    // // If generating public key in little-endian format, we use the following format:
    // operationGeneratePublicKey.keyMaterialEndianness = ECDH_LITTLE_ENDIAN_KEY;

    // //generate my pub-key
    // operationResult = ECDH_generatePublicKey(ecdhHandle, &operationGeneratePublicKey);

    // if (operationResult != ECDH_STATUS_SUCCESS) 
    // {
    //     printMessage(uart, (char *)ecdh_msg2, NULL, 0);
    // // Handle error
    // }


    //  printMessage(uart, (char *)promptClearText, (char *)myPublicKeyingMaterial, sizeof(myPublicKeyingMaterial));
    //  printBanner(uart, (char *)"*");

}

void App_StackInitDoneHandler(gapDeviceInitDoneEvent_t *deviceInitDoneData)
{
    bStatus_t status = SUCCESS;

    GPIO_init();
    GPIO_setConfig(CONFIG_GPIO_LED_GREEN, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    GPIO_setConfig(CONFIG_GPIO_LED_RED, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);

    GPIO_write( CONFIG_GPIO_LED_GREEN, CONFIG_LED_ON );
    GPIO_write( CONFIG_GPIO_LED_RED, CONFIG_LED_ON );

    UART2_Params_init(&uartParams);
    uartParams.baudRate = 115200;

    uart = UART2_open(CONFIG_UART2_0, &uartParams);

    if (uart == NULL)
    {
        /* UART2_open() failed */
        while (1) {}
    }

    char array[] = "example start !! \r\n";
    printClearText(uart,array,NULL,0);

    // AES_CBC_Test();
    // AES_GCM_Test();
    ECDH_Test();
    
}

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

    Ethan、您好!  

    首先要完成以下几项操作:  

    1.打开 ECDH 驱动程序时是否打开了其他加密功能? 如果您这么做了、并且加密函数使用了 HSM、则在打开 ECDH 时会遇到错误、因为 HSM 硬件正被另一个函数使用。  

    2.您在哪里调用 Basic_BLE 函数内的 ECDH_Test 函数?  

    3.当你说"我删除了线程内的函数"时,你到底是什么意思呢? 您是否删除了已添加到 Basic_BLE 示例项目中的 ECDH 实例。  

    我在空项目中对您的实现进行了测试、发现没有问题。 请提供上述问题的答案、我将使用 Basic_BLE 测试您的实施方案。  

    我认为您遇到的问题是由于您尝试打开 ECDH 驱动程序时使用 HSM 的另一个加密驱动程序引起的。 我可以使用您提供的答案进行进一步调试。  

    谢谢!  
    Isaac

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

    Ethan、您好!  

    我能够进一步调试您的实现、并解决了这个问题。  

    您正在使用的 ECDH 实例是在 BLE 连接期间用于加密连接事件的实例。 即使器件未处于连接中、此 ECDH 实例也将针对连接事件进行初始化、如果尝试将该实例用于其他目的、则会导致错误。  

    要解决此问题、请在 SysConfig 中创建另一个 ECDH 实例、并使用此示例。 此外、appMain 中的代码对 ECDH 驱动程序没有影响。 我保留了您注释掉的代码、并添加了在 Basic_BLE 项目中启用广播后要运行的 ECDH_Test 函数。  

    如果您对此有任何问题、敬请告知。  

    谢谢!  

    Isaac

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

    尊敬的  Isaac:

    感谢您的帮助,当我将另一个 ECDH 添加到.syscfg 文件, ECDH_open 运行良好。但随着我继续,我发现了一个新的问题: 当我使用 ECDH_generatePublicKey ()函数来生成公钥时,它生成了一个错误,返回-38没有任何解释。

    static void ECDH_Test(void)
    {
        ECDH_Handle ecdhHandle;
        ECDH_Params ecdhParams;
        CryptoKey myPrivateKey;
        CryptoKey myPublicKey;
        CryptoKey theirPublicKey;
        CryptoKey theirPrivateKey;
        CryptoKey mysharedSecret;
        CryptoKey theirsharedSecret;
        CryptoKey symmetricKey;
    
        int_fast16_t operationResult;
        ECDH_OperationGeneratePublicKey operationGeneratePublicKey;
        ECDH_OperationComputeSharedSecret operationComputeSharedSecret;
    
        char array[] = "\r\nECDH Test\r\n";
        printClearText(uart,array,NULL,0);
    
        ECDH_init();
    
        ECDH_Params_init(&ecdhParams);
        ecdhParams.returnBehavior = ECDH_RETURN_BEHAVIOR_BLOCKING;
    
        ecdhHandle = ECDH_open(CONFIG_ECDH1, &ecdhParams);
    
        if (!ecdhHandle) 
        {
            printMessage(uart, (char *)ecdh_msg, NULL, 0);
            while(1);
        }
    
        CryptoKeyPlaintextHSM_initKey(&myPrivateKey, myPrivateKeyingMaterial, sizeof(myPrivateKeyingMaterial));
        CryptoKeyPlaintextHSM_initBlankKey(&myPublicKey, myPublicKeyingMaterial, sizeof(myPublicKeyingMaterial));
    
        ECDH_OperationGeneratePublicKey_init(&operationGeneratePublicKey);
        operationGeneratePublicKey.curveType             = ECDH_TYPE_SEC_P_256_R1;
        operationGeneratePublicKey.myPrivateKey          = &myPrivateKey;
        operationGeneratePublicKey.myPublicKey           = &myPublicKey;
        // If generating public key in little-endian format, we use the following format:
        operationGeneratePublicKey.keyMaterialEndianness = ECDH_LITTLE_ENDIAN_KEY;
    
        //generate my pub-key
        operationResult = ECDH_generatePublicKey(ecdhHandle, &operationGeneratePublicKey);
    
        if (operationResult != ECDH_STATUS_SUCCESS) 
        {
            tprintf("generate pub-key fail: %d \r\n",operationResult);
            while(1){};
        }
    
    
         printMessage(uart, (char *)promptClearText, (char *)myPublicKeyingMaterial, sizeof(myPublicKeyingMaterial));
         printBanner(uart, (char *)"*");
    
        CryptoKeyPlaintextHSM_initKey(&theirPrivateKey, theirPrivateKeyMaterial, sizeof(theirPrivateKeyMaterial));
        CryptoKeyPlaintextHSM_initBlankKey(&theirPublicKey, theirPublicKeyingMaterial, sizeof(theirPublicKeyingMaterial));
    
        ECDH_OperationGeneratePublicKey_init(&operationGeneratePublicKey);
        operationGeneratePublicKey.curveType             = ECDH_TYPE_SEC_P_256_R1;
        operationGeneratePublicKey.myPrivateKey          = &theirPrivateKey;
        operationGeneratePublicKey.myPublicKey           = &theirPublicKey;
        // If generating public key in little-endian format, we use the following format:
        operationGeneratePublicKey.keyMaterialEndianness = ECDH_LITTLE_ENDIAN_KEY;
    
        //generate their pub-key
        operationResult = ECDH_generatePublicKey(ecdhHandle, &operationGeneratePublicKey);
    
        if (operationResult != ECDH_STATUS_SUCCESS) 
        {
            tprintf("generate pub-key fail: %d \r\n",operationResult);
        // Handle error
        }
    
        printMessage(uart, (char *)promptClearText, (char *)theirPublicKeyingMaterial, sizeof(theirPublicKeyingMaterial));
        printBanner(uart, (char *)"*");
    }

    您能不能看一下这个问题。

    谢谢!

    Ethan

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

    Ethan、您好!  

    该错误与无效公共密钥大小错误相关、请参阅此 链接。 

    我目前正在调查您看到的问题、并将在周一(03/24)结束前提供回复。  

    对于延迟、我们深表歉意。  

    谢谢!  
    Isaac

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

    尊敬的  Isaac:

    以下是我的公钥和私钥的数据结构:

    #define CURVE_LENGTH         32
    
    uint8_t myPrivateKeyingMaterial[CURVE_LENGTH] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA};
    uint8_t theirPrivateKeyMaterial[CURVE_LENGTH] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                                                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55};
    
    /***************私钥注意加密****************************/
     uint8_t myPublicKeyingMaterial[2 * CURVE_LENGTH + 1] = {0};
     uint8_t theirPublicKeyingMaterial[2 * CURVE_LENGTH + 1] = {0};
     uint8_t sharedSecretKeyingMaterial1[2 * CURVE_LENGTH + 1] = {0};
     uint8_t sharedSecretKeyingMaterial2[2 * CURVE_LENGTH + 1] = {0};

    虽然错误日志表明它是由错误的公共密钥长度引起的、但 当我阻止时、情况实际上是正常的 KeyMaterialEndianness 免受使用  ECDH_LITT_ENDIAN_KEY MODE。

    谢谢!

    Ethan

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

    Ethan、您好!  

    很高兴你找到它! 如果用于 RFC 7748样式公共密钥、则默认为 ECDH_BIG_ENDIAN_KEY 模式和 ECHD_LITT_ENDIAN_KEY 模式。  

    我很抱歉没有立即发现它!  

    如果您有任何其他问题、请告诉我。  

    谢谢!  

    Isaac