Re: Storing Bonding information in NVS memory

2019-02-15 Thread Andrzej Kaczmarek
Hi Prasad,

On Fri, Feb 15, 2019 at 1:24 PM prasad  wrote:

> Hi Chris,
>
> Currently I have been able to develop an app which is able to store bond
> information in NVS flash. If my device (ESP32) based on NIMBLE stack is
> rebooted, the bond remains intact. But if the other device is rebooted
> the ` key_sec->peer_addr.val` gets changed based on
> `key_sec->peer_addr.type = 1` (static address, random device address).
>
> As I understand, it is expected of static address type to change to new
> value, generated after each power cycle.
>

It is allowed, but not required - device may use single static address for
its lifetime.


> So in this case how to keep bond between devices intact ?
>
> If in case static address type is not to be used for bonded devices then
> why our NIMBLE stack uses static type of address even after setting
> `bonding` flag to 1 ?
>

Static address can be used to create bond, there's nothing wrong here.
However, if you or any other vendor devices decide that their device will
use new static random address after each power cycle, then it's basically
considered as a "new" device and all bonds created using previous static
address are effectively lost. There's nothing you can do here as this is
"by design". For reference, see Core 5.0 spec, Vol 6, Part B, section 1.3.6.


> Could you help me resolve this issue? Or I am missing on something obvious?
>
> Below is the snippet of code which tries to retrieve index from database
> but fails to do so since the `peer_addr.val` field has been changed.
>
> `
>
> if (ble_addr_cmp(_sec->peer_addr, BLE_ADDR_ANY)) {
>  if (*ble_addr_cmp(>peer_addr, _sec->peer_addr*)) {
>  continue;
> `
>
> Regards
>
> Prasad
>

Best,
Andrzej


Re: Storing Bonding information in NVS memory

2019-02-15 Thread prasad

Hi Chris,

Currently I have been able to develop an app which is able to store bond 
information in NVS flash. If my device (ESP32) based on NIMBLE stack is 
rebooted, the bond remains intact. But if the other device is rebooted 
the ` key_sec->peer_addr.val` gets changed based on 
`key_sec->peer_addr.type = 1` (static address, random device address).


As I understand, it is expected of static address type to change to new 
value, generated after each power cycle.


So in this case how to keep bond between devices intact ?

If in case static address type is not to be used for bonded devices then 
why our NIMBLE stack uses static type of address even after setting 
`bonding` flag to 1 ?


Could you help me resolve this issue? Or I am missing on something obvious?

Below is the snippet of code which tries to retrieve index from database 
but fails to do so since the `peer_addr.val` field has been changed.


`

if (ble_addr_cmp(_sec->peer_addr, BLE_ADDR_ANY)) {
    if (*ble_addr_cmp(>peer_addr, _sec->peer_addr*)) {
    continue;
`

Regards

Prasad

On 14/02/19 11:53 AM, prasad wrote:


Hi Chris,

Thank you for your response. As I build my understanding from your 
response,


The `idx` field most probably is useful in searching the case where 
`key.sec.peer_addr = *BLE_ADDR_ANY`, which most probably is useful to 
search our security keys. Correct me if I am wrong.


The reason behind asking use-case of `idx` was, when we are to write 
security keys to database, we call `ble_store_key_from_value_sec` 
which does the following:


{
        out_key->peer_addr = value->peer_addr;

    out_key->ediv = value->ediv;
    out_key->rand_num = value->rand_num;
    out_key->ediv_rand_present = 1;
*o**ut_key->idx = 0;*  // /This made me wonder why we need to search 
based on this criteria./

}

Thank you for response anyways. Really helpful.

Regards

Prasad

On 13/02/19 9:44 PM, Christopher Collins wrote:

Hi Prasad,

On Wed, Feb 13, 2019 at 03:13:26PM +0530, prasad wrote:

Hi all,

As it happens, I fixed the bug in my code. It now correctly retrieves
LTKs and bond is maintained even after reboot.

Apart from this I just wanted to understand reason behind including
'idx' in structure 'ble_store_key_sec'. Could you please help me
understand use-case behind including 'idx'?

/** Number of results to skip; 0 means retrieve the first match. */
          uint8_t idx;

The `idx` field is useful when your search criteria matches several
entries and you want to process them one by one.  For example, the
`ble_store_iterate()` function constructs a `ble_store_key_sec` object
with the following values:

 {
 /**
  * Key by peer identity address;
  * peer_addr=BLE_ADDR_NONE means don't key off peer.
  */
 peer_addr = *BLE_ADDR_ANY,

 /** Key by ediv; ediv_rand_present=0 means don't key off ediv. */
 ediv = 0,

 /** Key by rand_num; ediv_rand_present=0 means don't key off rand_num. 
*/
 rand_num = 0

 ediv_rand_present = 0,

 /** Number of results to skip; 0 means retrieve the first match. */
 idx = 0,
 }

Then it repeatedly calls `ble_store_read()`, incrementing the `idx`
member each time.  This allows all stored bonds to be processed.

Chris)


Re: Storing Bonding information in NVS memory

2019-02-13 Thread prasad

Hi Chris,

Thank you for your response. As I build my understanding from your response,

The `idx` field most probably is useful in searching the case where 
`key.sec.peer_addr = *BLE_ADDR_ANY`, which most probably is useful to 
search our security keys. Correct me if I am wrong.


The reason behind asking use-case of `idx` was, when we are to write 
security keys to database, we call `ble_store_key_from_value_sec` which 
does the following:


{
        out_key->peer_addr = value->peer_addr;

    out_key->ediv = value->ediv;
    out_key->rand_num = value->rand_num;
    out_key->ediv_rand_present = 1;
*o**ut_key->idx = 0;*  // /This made me wonder why we need to search 
based on this criteria./

}

Thank you for response anyways. Really helpful.

Regards

Prasad

On 13/02/19 9:44 PM, Christopher Collins wrote:

Hi Prasad,

On Wed, Feb 13, 2019 at 03:13:26PM +0530, prasad wrote:

Hi all,

As it happens, I fixed the bug in my code. It now correctly retrieves
LTKs and bond is maintained even after reboot.

Apart from this I just wanted to understand reason behind including
'idx' in structure 'ble_store_key_sec'. Could you please help me
understand use-case behind including 'idx'?

/** Number of results to skip; 0 means retrieve the first match. */
          uint8_t idx;

The `idx` field is useful when your search criteria matches several
entries and you want to process them one by one.  For example, the
`ble_store_iterate()` function constructs a `ble_store_key_sec` object
with the following values:

 {
 /**
  * Key by peer identity address;
  * peer_addr=BLE_ADDR_NONE means don't key off peer.
  */
 peer_addr = *BLE_ADDR_ANY,

 /** Key by ediv; ediv_rand_present=0 means don't key off ediv. */
 ediv = 0,

 /** Key by rand_num; ediv_rand_present=0 means don't key off rand_num. 
*/
 rand_num = 0

 ediv_rand_present = 0,

 /** Number of results to skip; 0 means retrieve the first match. */
 idx = 0,
 }

Then it repeatedly calls `ble_store_read()`, incrementing the `idx`
member each time.  This allows all stored bonds to be processed.

Chris)


Re: Storing Bonding information in NVS memory

2019-02-13 Thread Christopher Collins
Hi Prasad,

On Wed, Feb 13, 2019 at 03:13:26PM +0530, prasad wrote:
> Hi all,
> 
> As it happens, I fixed the bug in my code. It now correctly retrieves 
> LTKs and bond is maintained even after reboot.
> 
> Apart from this I just wanted to understand reason behind including 
> 'idx' in structure 'ble_store_key_sec'. Could you please help me 
> understand use-case behind including 'idx'?
> 
> /** Number of results to skip; 0 means retrieve the first match. */
>          uint8_t idx;

The `idx` field is useful when your search criteria matches several
entries and you want to process them one by one.  For example, the
`ble_store_iterate()` function constructs a `ble_store_key_sec` object
with the following values:

{
/**
 * Key by peer identity address;
 * peer_addr=BLE_ADDR_NONE means don't key off peer.
 */
peer_addr = *BLE_ADDR_ANY,

/** Key by ediv; ediv_rand_present=0 means don't key off ediv. */
ediv = 0,

/** Key by rand_num; ediv_rand_present=0 means don't key off rand_num. 
*/
rand_num = 0

ediv_rand_present = 0,

/** Number of results to skip; 0 means retrieve the first match. */
idx = 0,
}

Then it repeatedly calls `ble_store_read()`, incrementing the `idx`
member each time.  This allows all stored bonds to be processed.

Chris


Re: Storing Bonding information in NVS memory

2019-02-13 Thread prasad

Hi all,

As it happens, I fixed the bug in my code. It now correctly retrieves 
LTKs and bond is maintained even after reboot.


Apart from this I just wanted to understand reason behind including 
'idx' in structure 'ble_store_key_sec'. Could you please help me 
understand use-case behind including 'idx'?


/** Number of results to skip; 0 means retrieve the first match. */
        uint8_t idx;

Regards

Prasad

On 12/02/19 7:35 PM, prasad wrote:


Hi all,

With further debug effort the disconnect happens with HCI error 0x3d: 
BLE_ERR_CONN_TERM_MIC.


Once the connection is establish, if we disconnect and try to 
reconnect it is disconnecting with said reason.


I am attaching logs with additional prints. Please help me to know if 
I am making any obvious mistake.



Regards

Prasad

On 11/02/19 7:10 PM, prasad wrote:


Hi all,

Are there any pointers/documentation for storing NIMBLE bond 
information in NVS memory?


I tried to quickly implement simple application by modifying 
'*ble_store_ram.c*'. I modified 
/ble_hs_cfg.store_read_cb/store_write_cb/store_delete_cb/ callbacks 
according to the requirement. I find this much of change is not 
sufficient to get NVS bond stored in NVS as I am continuously getting 
disconnect HCI event.


FYI, I am putting snippet of my code for each of these 3 callbacks 
which will help you understand the changes I have made.


1.**/*ble_hs_cfg.store_read_cb* :
/

/case BLE_STORE_OBJ_TYPE_OUR_SEC:
    nvs_open("nimble_bond", NVS_READWRITE, _handle);

    BLE_HS_LOG(DEBUG, "looking up our sec; ");
    err = nvs_get_blob(nimble_handle, "our_sec_key", NULL, 
_size);

    if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) return err;
    if (required_size == 0) {
    nvs_close(nimble_handle);
    return BLE_HS_ENOENT;
    } else {
    struct ble_store_key_sec* our_sec_key = 
malloc(required_size);
    err = nvs_get_blob(nimble_handle, "our_sec_key", 
our_sec_key, _size);

    if (err != ESP_OK) {
    free(our_sec_key);
    return err;
    }

    if (ble_addr_cmp(>sec.peer_addr, BLE_ADDR_ANY)) {
    if (ble_addr_cmp(_sec_key->peer_addr, 
>sec.peer_addr)){
    err = nvs_get_blob(nimble_handle, "our_sec", NULL, 
_size);
    if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) return 
err;


    struct ble_store_value_sec* our_sec = malloc(required_size);
    err = nvs_get_blob(nimble_handle, "our_sec", our_sec, 
_size);

    if (err != ESP_OK) {
    free(our_sec);
    return err;
    }

    memcpy(>sec, our_sec, required_size);
    free(our_sec);
    }
    }

    free(our_sec_key);
    }
    /* NVS Close */
    nvs_close(nimble_handle);

/

/2. ///*ble_hs_cfg.store_write_cb
*//

//case BLE_STORE_OBJ_TYPE_OUR_SEC:
    ble_store_key_from_value_sec(_sec, >sec);

    required_size = sizeof(struct ble_store_key_sec);
    err = nvs_set_blob(nimble_handle, "our_sec_key", _sec, 
required_size);

    required_size = sizeof(struct ble_store_value_sec);
    err = nvs_set_blob(nimble_handle, "our_sec", >sec, 
required_size);


    /* NVS Commit */
    err = nvs_commit(nimble_handle);
    if (err != ESP_OK) return err;
    /* NVS Close */
    nvs_close(nimble_handle);

    return 0;//

Regards

Prasad



Re: Storing Bonding information in NVS memory

2019-02-12 Thread prasad

Hi all,

With further debug effort the disconnect happens with HCI error 0x3d: 
BLE_ERR_CONN_TERM_MIC.


Once the connection is establish, if we disconnect and try to reconnect 
it is disconnecting with said reason.


I am attaching logs with additional prints. Please help me to know if I 
am making any obvious mistake.



Regards

Prasad

On 11/02/19 7:10 PM, prasad wrote:


Hi all,

Are there any pointers/documentation for storing NIMBLE bond 
information in NVS memory?


I tried to quickly implement simple application by modifying 
'*ble_store_ram.c*'. I modified 
/ble_hs_cfg.store_read_cb/store_write_cb/store_delete_cb/ callbacks 
according to the requirement. I find this much of change is not 
sufficient to get NVS bond stored in NVS as I am continuously getting 
disconnect HCI event.


FYI, I am putting snippet of my code for each of these 3 callbacks 
which will help you understand the changes I have made.


1.**/*ble_hs_cfg.store_read_cb* :
/

/case BLE_STORE_OBJ_TYPE_OUR_SEC:
    nvs_open("nimble_bond", NVS_READWRITE, _handle);

    BLE_HS_LOG(DEBUG, "looking up our sec; ");
    err = nvs_get_blob(nimble_handle, "our_sec_key", NULL, 
_size);

    if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) return err;
    if (required_size == 0) {
    nvs_close(nimble_handle);
    return BLE_HS_ENOENT;
    } else {
    struct ble_store_key_sec* our_sec_key = malloc(required_size);
    err = nvs_get_blob(nimble_handle, "our_sec_key", 
our_sec_key, _size);

    if (err != ESP_OK) {
    free(our_sec_key);
    return err;
    }

    if (ble_addr_cmp(>sec.peer_addr, BLE_ADDR_ANY)) {
    if (ble_addr_cmp(_sec_key->peer_addr, 
>sec.peer_addr)){
    err = nvs_get_blob(nimble_handle, "our_sec", NULL, 
_size);

    if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) return err;

    struct ble_store_value_sec* our_sec = malloc(required_size);
    err = nvs_get_blob(nimble_handle, "our_sec", our_sec, 
_size);

    if (err != ESP_OK) {
    free(our_sec);
    return err;
    }

    memcpy(>sec, our_sec, required_size);
    free(our_sec);
    }
    }

    free(our_sec_key);
    }
    /* NVS Close */
    nvs_close(nimble_handle);

/

/2. ///*ble_hs_cfg.store_write_cb
*//

//case BLE_STORE_OBJ_TYPE_OUR_SEC:
    ble_store_key_from_value_sec(_sec, >sec);

    required_size = sizeof(struct ble_store_key_sec);
    err = nvs_set_blob(nimble_handle, "our_sec_key", _sec, 
required_size);

    required_size = sizeof(struct ble_store_value_sec);
    err = nvs_set_blob(nimble_handle, "our_sec", >sec, 
required_size);


    /* NVS Commit */
    err = nvs_commit(nimble_handle);
    if (err != ESP_OK) return err;
    /* NVS Close */
    nvs_close(nimble_handle);

    return 0;//

Regards

Prasad

disconnect; reason=531 handle=0 our_ota_addr_type=0 
our_ota_addr=24:0a:c4:23:be:76 our_id_addr_type=0 our_id_addr=24:0a:c4:23:be:76 
peer_ota_addr_type=1 peer_ota_addr=4c:fb:ae:cb:1e:d0 peer_id_addr_type=1 
peer_id_addr=4c:fb:ae:cb:1e:d0 conn_itvl=36 conn_latency=0 
supervision_timeout=500 encrypted=1 authenticated=1 bonded=1

ble_hs_hci_cmd_send: ogf=0x08 ocf=0x0007 len=0
0x07 0x20 0x00 
ble_hs_hci_cmd_send: ogf=0x08 ocf=0x0008 len=32
0x08 0x20 0x20 0x1f 0x02 0x01 0x06 0x03 0x03 0x11 0x18 0x14 0x09 0x42 0x4f 0x4e 
0x44 0x5f 0x6e 0x69 0x6d 0x62 0x6c 0x65 0x2d 0x62 0x6c 0x65 0x70 0x72 0x70 0x68 
0x02 0x0a 0x03 
GAP procedure initiated: advertise; disc_mode=2 adv_channel_map=0 
own_addr_type=0 adv_filter_policy=0 adv_itvl_min=0 adv_itvl_max=0
ble_hs_hci_cmd_send: ogf=0x08 ocf=0x0006 len=15
0x06 0x20 0x0f 0x30 0x00 0x60 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 
0x07 0x00 
ble_hs_hci_cmd_send: ogf=0x08 ocf=0x000a len=1
0x0a 0x20 0x01 0x01 

* ble_hs_hci_evt_process:: Data=003e *
I (31215) NIMBLE_BLE_PRPH: Entered event BLE_GAP_EVENT_CONNECT

 *Entered ble_sm_slave_initiate...* 

 *proc result called from ble_SM_SLAVE_initiate * 

 ** Entered into ble_sm_process_result ** 

 ** res->exec=1, res->app_status=0, proc->state=8,  ** 

-* Entered into ble_sm_sec_req_exec * - 
ble_sm_sec_req:: auth_req:: 13 sm_sm_sc_sm_MITM_^_sm_bondinghost tx hci data; 
handle=0 length=6
ble_hs_hci_acl_tx(): 0x00 0x00 0x06 0x00 0x02 0x00 0x06 0x00 0x0b 0x0d 
connection established; status=0 handle=0 our_ota_addr_type=0 
our_ota_addr=24:0a:c4:23:be:76 our_id_addr_type=0 our_id_addr=24:0a:c4:23:be:76 
peer_ota_addr_type=1 peer_ota_addr=4c:fb:ae:cb:1e:d0 peer_id_addr_type=1 
peer_id_addr=4c:fb:ae:cb:1e:d0 conn_itvl=36 conn_latency=0 
supervision_timeout=500 encrypted=0 authenticated=0 bonded=0

ble_hs_hci_cmd_send: ogf=0x08 ocf=0x0016 len=2
0x16 0x20 0x02 0x00 0x00 

* ble_hs_hci_evt_process:: Data=003e *

* ble_hs_hci_evt_process:: Data=0013 *

* ble_hs_hci_evt_process::