Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

LESC_DEBUG_MODE define in ble_app_multirole_lesc, nRF5 SDK 15.0.0

Device: nRF52832

SDK: nRF5 SDK 15.0.0

SoftDevice 6.0.0

Hello. I'm using using the ble_app_multirole_lesc example with nRF5 SDK 15.0.0. I'm trying to debug using my sniffer, and want to use the debug private key. The following define exists in the main.c code which seems like it should set the private key to the debug key:

#define LESC_DEBUG_MODE 1 /**< Set to 1 to use LESC debug keys, allows you to use a sniffer to inspect traffic. */

The problem, though, is that this define doesn't appear to do anything. The LESC_DEBUG_MODE symbol is not used anywhere else in the code. I went back to the 14.2.0 SDK and found some code in the sample application that made use of the LESC_DEBUG_MODE flag:

#if LESC_DEBUG_MODE

/**@brief Bluetooth SIG debug mode Private Key */
#error Generated private key is not supported.
__ALIGN(4) static const ble_gap_lesc_p256_sk_t m_lesc_private_key =
{{
0xbd,0x1a,0x3c,0xcd,0xa6,0xb8,0x99,0x58,0x99,0xb7,0x40,0xeb,0x7b,0x60,0xff,0x4a,
0x50,0x3f,0x10,0xd2,0xe3,0xb3,0xc9,0x74,0x38,0x5f,0xc5,0xa3,0xd4,0xf6,0x49,0x3f
}};

#else

#endif

Unfortunately, even with the above code I don't quite understand how the debug key works because the m_lesc_private_key structure is not actually used anywhere. I would think that 

In any case, what I really need is to use the private key with SDK 15.0.0, not 14.2.0. From my understanding of the code I would have though that the code related to the debug private key would need to be in ble_lesc.c rather than in the application code (since the key generation and management are handled by that module rather than the application).

Could you please provide guidance for using the debug key?

Thanks.

Parents
  • Using the debug key, and using a sniffer to monitor the encrypted connection is mostly done for very specific testing, and generally not something developers need to do.

    If you need to diagnose any kind of Bluetooth issue with a sniffer, it is something you need to do!

    To build on Daniel's answer, to do this only for the lesc key (not all generated keys) and regardless of backend, modify the following function in nrf_ble_lesc.c:

    ret_code_t nrf_ble_lesc_keypair_generate(void)
    {
        ret_code_t err_code;
        size_t     public_len = NRF_CRYPTO_ECC_SECP256R1_RAW_PUBLIC_KEY_SIZE;
    
        // Check if any DH computation is pending
        for (uint32_t i = 0; i < ARRAY_SIZE(m_peer_keys); i++)
        {
            if (m_peer_keys[i].is_valid)
            {
                return NRF_ERROR_BUSY;
            }
        }
    
        // Update flag to indicate that there is no valid private key.
        m_keypair_generated       = false;
        m_lesc_oobd_own_generated = false;
    
    #if defined(DEBUG) && LESC_DEBUG_MODE
    #warning "Compiling with ECC debug key"
        UNUSED_VARIABLE(m_keygen_context);
        NRF_LOG_WARNING("Using debug ECC key pair");
        static const uint8_t LESC_DEBUG_KEY[32] = {
                0x3f, 0x49, 0xf6, 0xd4, 0xa3, 0xc5, 0x5f, 0x38, 0x74, 0xc9, 0xb3, 0xe3, 0xd2, 0x10, 0x3f, 0x50,
                0x4a, 0xff, 0x60, 0x7b, 0xeb, 0x40, 0xb7, 0x99, 0x58, 0x99, 0xb8, 0xa6, 0xcd, 0x3c, 0x1a, 0xbd
        };
    
        err_code = nrf_crypto_ecc_private_key_from_raw(&g_nrf_crypto_ecc_secp256r1_curve_info, &m_private_key, LESC_DEBUG_KEY, sizeof(LESC_DEBUG_KEY));
        if (err_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("nrf_crypto_ecc_private_key_from_raw() returned error 0x%x.", err_code);
            return err_code;
        }
        nrf_crypto_ecc_public_key_calculate_context_t calc_context;
        err_code = nrf_crypto_ecc_public_key_calculate(&calc_context, &m_private_key, &m_public_key);
        if (err_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("nrf_crypto_ecc_public_key_calculate() returned error 0x%x.", err_code);
            return err_code;
        }
    #else
        NRF_LOG_DEBUG("Generating ECC key pair");
        err_code = nrf_crypto_ecc_key_pair_generate(&m_keygen_context,
                                                    &g_nrf_crypto_ecc_secp256r1_curve_info,
                                                    &m_private_key,
                                                    &m_public_key);
        if (err_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("nrf_crypto_ecc_key_pair_generate() returned error 0x%x.", err_code);
            return err_code;
        }
    #endif
    
    
    
        // Convert to a raw type.
        err_code = nrf_crypto_ecc_public_key_to_raw(&m_public_key,
                                                    m_lesc_public_key.pk,
                                                    &public_len);
        if (err_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("nrf_crypto_ecc_public_key_to_raw() returned error 0x%x.", err_code);
            return err_code;
        }
    
        // Invert the raw type to little-endian (required for BLE).
        err_code = nrf_crypto_ecc_byte_order_invert(&g_nrf_crypto_ecc_secp256r1_curve_info,
                                                    m_lesc_public_key.pk,
                                                    m_lesc_public_key.pk,
                                                    NRF_CRYPTO_ECC_SECP256R1_RAW_PUBLIC_KEY_SIZE);
        if (err_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("nrf_crypto_ecc_byte_order_invert() returned error 0x%x.", err_code);
        }
        else
        {
            // Set the flag to indicate that there is a valid ECDH key pair generated.
            m_keypair_generated = true;
        }
    
        return err_code;
    }

Reply
  • Using the debug key, and using a sniffer to monitor the encrypted connection is mostly done for very specific testing, and generally not something developers need to do.

    If you need to diagnose any kind of Bluetooth issue with a sniffer, it is something you need to do!

    To build on Daniel's answer, to do this only for the lesc key (not all generated keys) and regardless of backend, modify the following function in nrf_ble_lesc.c:

    ret_code_t nrf_ble_lesc_keypair_generate(void)
    {
        ret_code_t err_code;
        size_t     public_len = NRF_CRYPTO_ECC_SECP256R1_RAW_PUBLIC_KEY_SIZE;
    
        // Check if any DH computation is pending
        for (uint32_t i = 0; i < ARRAY_SIZE(m_peer_keys); i++)
        {
            if (m_peer_keys[i].is_valid)
            {
                return NRF_ERROR_BUSY;
            }
        }
    
        // Update flag to indicate that there is no valid private key.
        m_keypair_generated       = false;
        m_lesc_oobd_own_generated = false;
    
    #if defined(DEBUG) && LESC_DEBUG_MODE
    #warning "Compiling with ECC debug key"
        UNUSED_VARIABLE(m_keygen_context);
        NRF_LOG_WARNING("Using debug ECC key pair");
        static const uint8_t LESC_DEBUG_KEY[32] = {
                0x3f, 0x49, 0xf6, 0xd4, 0xa3, 0xc5, 0x5f, 0x38, 0x74, 0xc9, 0xb3, 0xe3, 0xd2, 0x10, 0x3f, 0x50,
                0x4a, 0xff, 0x60, 0x7b, 0xeb, 0x40, 0xb7, 0x99, 0x58, 0x99, 0xb8, 0xa6, 0xcd, 0x3c, 0x1a, 0xbd
        };
    
        err_code = nrf_crypto_ecc_private_key_from_raw(&g_nrf_crypto_ecc_secp256r1_curve_info, &m_private_key, LESC_DEBUG_KEY, sizeof(LESC_DEBUG_KEY));
        if (err_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("nrf_crypto_ecc_private_key_from_raw() returned error 0x%x.", err_code);
            return err_code;
        }
        nrf_crypto_ecc_public_key_calculate_context_t calc_context;
        err_code = nrf_crypto_ecc_public_key_calculate(&calc_context, &m_private_key, &m_public_key);
        if (err_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("nrf_crypto_ecc_public_key_calculate() returned error 0x%x.", err_code);
            return err_code;
        }
    #else
        NRF_LOG_DEBUG("Generating ECC key pair");
        err_code = nrf_crypto_ecc_key_pair_generate(&m_keygen_context,
                                                    &g_nrf_crypto_ecc_secp256r1_curve_info,
                                                    &m_private_key,
                                                    &m_public_key);
        if (err_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("nrf_crypto_ecc_key_pair_generate() returned error 0x%x.", err_code);
            return err_code;
        }
    #endif
    
    
    
        // Convert to a raw type.
        err_code = nrf_crypto_ecc_public_key_to_raw(&m_public_key,
                                                    m_lesc_public_key.pk,
                                                    &public_len);
        if (err_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("nrf_crypto_ecc_public_key_to_raw() returned error 0x%x.", err_code);
            return err_code;
        }
    
        // Invert the raw type to little-endian (required for BLE).
        err_code = nrf_crypto_ecc_byte_order_invert(&g_nrf_crypto_ecc_secp256r1_curve_info,
                                                    m_lesc_public_key.pk,
                                                    m_lesc_public_key.pk,
                                                    NRF_CRYPTO_ECC_SECP256R1_RAW_PUBLIC_KEY_SIZE);
        if (err_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("nrf_crypto_ecc_byte_order_invert() returned error 0x%x.", err_code);
        }
        else
        {
            // Set the flag to indicate that there is a valid ECDH key pair generated.
            m_keypair_generated = true;
        }
    
        return err_code;
    }

Children
No Data
Related