This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF51822 Le secure connection

Hello all.

I am developing a BT4.2 compliant application.
I have a question about LESC (LE Secure Connection).

devzone.nordicsemi.com/.../how-to-implement-ecc-functions-on-sdk-v12- 3-0-and-nrf51822 / 142314 # 142314
I had add the above process.

But, if you connect using "nRF Connect" on a PC, a DHKEY error (BLE_GAP_SEC_STATUS_DHKEY_FAILURE) will occur.
And connecting with "nRF Connect" on ipad pro results in unspecified error in Public key exchange.

However, I can connect with the module I created.

Any idea what might be happening?
Thanks.

【Development environment】

nRF51822

SDK12.3

Parents Reply Children
  • Hi,

    I understand (I had a vague understanding that you were using Keil as well, but that was probably just for testing this).

    I was not able to test the way you describe since for some reason I did not see the advertisement packets on air. Since you reported that the issue was specifically with the calculation of the shared secret I instead put together a simple test function that verifies the crypto operations needed for LESC, which you can see here (and run yourself by copy-pasting into your code and calling from your main function):

    // Test crypto functions needed for LESC. To be used in the ble_app_multirole_lesc example in SDK 12.3.
    static void crypto_test(void)
    {
        ret_code_t err_code;
    
        // Own key structures
        __ALIGN(4) static const ble_gap_lesc_p256_sk_t sk =
        {{
            0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
            0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
            0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
            0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
        }};
        __ALIGN(4) static ble_gap_lesc_p256_pk_t lesc_pk;    /**< LESC ECC Public Key */
        __ALIGN(4) static ble_gap_lesc_dhkey_t lesc_dhkey;   /**< LESC ECC DH Key */
    
        static nrf_crypto_key_t own_sk =
        {
            .p_le_data = (uint8_t *) sk.sk,
            .len = sizeof(sk.sk)
        };
        static nrf_crypto_key_t own_pk =
        {
            .p_le_data = (uint8_t *) lesc_pk.pk,
            .len = sizeof(lesc_pk.pk)
        };
        static nrf_crypto_key_t key_dhkey =
        {
            .p_le_data = (uint8_t *) lesc_dhkey.key,
            .len = sizeof(lesc_dhkey.key)
        };
    
        // Valid own public key
        __ALIGN(4) static const uint8_t valid_own_pk[] =
        {
            0x02, 0x17, 0xE6, 0x17, 0xF0, 0xB6, 0x44, 0x39,
            0x28, 0x27, 0x8F, 0x96, 0x99, 0x9E, 0x69, 0xA2,
            0x3A, 0x4F, 0x2C, 0x15, 0x2B, 0xDF, 0x6D, 0x6C,
            0xDF, 0x66, 0xE5, 0xB8, 0x02, 0x82, 0xD4, 0xED,
            0x19, 0x4A, 0x7D, 0xEB, 0xCB, 0x97, 0x71, 0x2D,
            0x2D, 0xDA, 0x3C, 0xA8, 0x5A, 0xA8, 0x76, 0x5A,
            0x56, 0xF4, 0x5F, 0xC7, 0x58, 0x59, 0x96, 0x52,
            0xF2, 0x89, 0x7C, 0x65, 0x30, 0x6E, 0x57, 0x94,
        };
    
        // Peer public key structures
        __ALIGN(4) static const uint8_t peer_raw_public_key[] =
        {
            0xA5, 0x62, 0xBD, 0x02, 0x60, 0x88, 0x81, 0x2E,
            0x0A, 0x26, 0xE6, 0xA3, 0x55, 0x0E, 0xFA, 0xC6,
            0x06, 0xE6, 0x91, 0xDE, 0xB5, 0x6F, 0xA2, 0x1B,
            0x19, 0x8F, 0x2E, 0xFD, 0x0B, 0xD5, 0xCB, 0x25,
            0x9B, 0x4A, 0x96, 0x09, 0x12, 0xFD, 0x30, 0xD8,
            0x79, 0xA4, 0x52, 0x47, 0xF8, 0x05, 0x08, 0xE1,
            0x33, 0x3C, 0xA2, 0x5A, 0x4B, 0x83, 0x26, 0x23,
            0x3A, 0xE8, 0x26, 0x82, 0x46, 0x5A, 0x21, 0xCD,
        };
    
        static nrf_crypto_key_t peer_pk =
        {
            .p_le_data = (uint8_t *) peer_raw_public_key,
            .len = sizeof(peer_raw_public_key)
        };
    
        // Compare shared secret with valid shared secret
            __ALIGN(4) static const uint8_t valid_shared_secret[] =
        {
            0x6C, 0x21, 0xB1, 0xAB, 0xCF, 0x65, 0xFC, 0xB7,
            0x50, 0x48, 0xF2, 0x1B, 0x43, 0xA5, 0x31, 0x22,
            0xF8, 0x13, 0x65, 0x17, 0x02, 0x71, 0x5E, 0xBE,
            0xD2, 0x77, 0xFD, 0xB8, 0xA2, 0x4C, 0x5E, 0x73,
        };
    
        // -------------------------------- Begin test --------------------------------
    
        NRF_LOG_INFO("Test crypto operations used for LESC...\r\n");
    
        // Calculate own public key (not really needed in this test since we will not pass to a peer in
        // this test) but it is done to verify that it works since it is used in the real LESC procedure.
        nrf_crypto_init();
        err_code = nrf_crypto_public_key_compute(NRF_CRYPTO_CURVE_SECP256R1, &own_sk, &own_pk);
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_INFO("Calculated public key:\r\n");
        NRF_LOG_HEXDUMP_INFO(own_pk.p_le_data, own_pk.len);
    
        // Compare with valid public key
        if (memcmp(own_pk.p_le_data, valid_own_pk, 64) == 0)
        {
            NRF_LOG_INFO("Calculated public key is correct.\r\n");
        }
        else
        {
            NRF_LOG_ERROR("Fail: Calculated public key is INCORRECT!\r\n");
        }
    
        // Calculate shared secret
        err_code = nrf_crypto_shared_secret_compute(NRF_CRYPTO_CURVE_SECP256R1, &own_sk, &peer_pk, &key_dhkey);
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_INFO("Calculated shared secret:\r\n");
        NRF_LOG_HEXDUMP_INFO(key_dhkey.p_le_data, key_dhkey.len);
    
        // Compare with valid shared secret
        if (memcmp(key_dhkey.p_le_data, valid_shared_secret, 32) == 0)
        {
            NRF_LOG_INFO("Calculated shared secret is correct.\r\n");
        }
        else
        {
            NRF_LOG_ERROR("Fail: Calculated shared secret is INCORRECT!\r\n");
        }
    }

    Interestingly this test passes in your SES project, so there does not seem to be any problems with mciro-ecc. I don't know why LESC files when you test, nor do I know why I don't even see the advertisement packets on air on my side. Everything else looks OK to me. So it is a bit of a mystery for now.

  • Thank you for the test function.

    I will check it.

    Have you changed thumb_crt0.s?

  • Sorry, the above was unnecessary.

    The cause has been found.
    uECC.c was not working because it was included in the compilation.

    Thank you for your cooperation.

Related