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

Using encryption between central and peripheral.

Hi there,

I am working with softdevice v5.0.0, and trying to have central and peripheral do encryption.

The peripheral has a r/w characteristic, and another one with read with notify (cccd r/w), but no write.

When I enable BOND, LESC and the usual encryption options in peer manager, it seems to work with permisions ENC_NO_MITM or NO_ACCESS on the characteristics read or write. But if I set the cccd write with ENC_NO_MITM, that seems to break the notifications. Setting the cccd read with ENC_NO_MITM makes the SD complain with invalid params.

I have seen those permissions in some examples, and the code I have comes from an old SD v4.0.2 I belive.

Is there anything obvious I should be looking at, or any constrains I am breaking?

Regards

Parents
  • Hi,

    This should work, I just verified it with the hrs example from SDK 14.2.0 (s132 v5). Can you check which softdevice function it is that returns invalid param? 

    Regards,

    Vidar

  • Hi Vidar,

    This is the initialization code in the peripheral:

    static uint32_t button_char_add(ble_mydev_t * p_mydev, const ble_mydev_init_t * p_mydev_init)
    {
        ble_gatts_char_md_t char_md;
        ble_gatts_attr_md_t cccd_md;
        ble_gatts_attr_t    attr_char_value;
        ble_uuid_t          ble_uuid;
        ble_gatts_attr_md_t attr_md;
    
        memset(&cccd_md, 0, sizeof(cccd_md));
    
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
        cccd_md.vloc = BLE_GATTS_VLOC_STACK;
    
        memset(&char_md, 0, sizeof(char_md));
    
        char_md.char_props.read   = 1;
        char_md.char_props.notify = 1;
        char_md.p_char_user_desc  = NULL;
        char_md.p_char_pf         = NULL;
        char_md.p_user_desc_md    = NULL;
        char_md.p_cccd_md         = &cccd_md;
        char_md.p_sccd_md         = NULL;
    
        ble_uuid.type = p_mydev->uuid_type;
        ble_uuid.uuid = MYDEV_UUID_BUTTON_CHAR;
    
        memset(&attr_md, 0, sizeof(attr_md));
    
        BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attr_md.read_perm);
        BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);
        attr_md.vloc    = BLE_GATTS_VLOC_STACK;
        attr_md.rd_auth = 0;
        attr_md.wr_auth = 0;
        attr_md.vlen    = 0;
    
        memset(&attr_char_value, 0, sizeof(attr_char_value));
    
        attr_char_value.p_uuid    = &ble_uuid;
        attr_char_value.p_attr_md = &attr_md;
        attr_char_value.init_len  = sizeof(uint8_t);
        attr_char_value.init_offs = 0;
        attr_char_value.max_len   = sizeof(uint8_t);
        attr_char_value.p_value   = NULL;
    
        return sd_ble_gatts_characteristic_add(p_mydev->service_handle,
                                               &char_md,
                                               &attr_char_value,
                                               &p_mydev->button_char_handles);
    }
    
    
    uint32_t ble_mydev_init(ble_mydev_t * p_mydev, const ble_mydev_init_t * p_mydev_init)
    {
        uint32_t   err_code;
        ble_uuid_t ble_uuid;
    
        // Initialize service structure.
        p_mydev->led_write_handler = p_mydev_init->led_write_handler;
    
        // Add service.
        ble_uuid128_t base_uuid = {MYDEV_UUID_BASE};
        err_code = sd_ble_uuid_vs_add(&base_uuid, &p_mydev->uuid_type);
        VERIFY_SUCCESS(err_code);
    
        ble_uuid.type = p_mydev->uuid_type;
        ble_uuid.uuid = MYDEV_UUID_SERVICE;
    
        err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_mydev->service_handle);
        VERIFY_SUCCESS(err_code);
    
        // Add characteristics.
        err_code = button_char_add(p_mydev, p_mydev_init);
        VERIFY_SUCCESS(err_code);
    ...

    If I replace the:

        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);

    with

        BLE_GAP_CONN_SEC_MODE_ENC_NO_MITM(&cccd_md.read_perm);
        BLE_GAP_CONN_SEC_MODE_ENC_NO_MITM(&cccd_md.write_perm);

    The function sd_ble_gatts_characteristic_add will return invalid param.

    If I only replace:

        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);

    with

        BLE_GAP_CONN_SEC_MODE_ENC_NO_MITM(&cccd_md.write_perm);

    Then the notifications for the button won't work anymore.

    I wonder if I am missing some required change either in the peripheral or the central when setting the cccd_md.write_perm as encoded with no mitm protection.

    I know there are examples that do it and work, but comming from an old code base, I have applied the changes that seem required to do it, so I may be missing one of the required changes.

    I would need help to trouble shoot that.

    Regards

  • Hi,

    Read permission must be set to "open" according to the specification (ref. core spec. 5.0, vol 3, Part G, section 3.3.3.3 (table 3.10)). The softdevice enforces this requirement and is probably why you get the invalid param error. However, it should work if you only require authentication for write access. What central are you using for test? In case it's an iOS device, try to 'forget' the device from ios settings -> Bluetooth, enable and disable flight mode (clears device cache on phone), then re-connect.  

    Regards,

    Vidar

Reply
  • Hi,

    Read permission must be set to "open" according to the specification (ref. core spec. 5.0, vol 3, Part G, section 3.3.3.3 (table 3.10)). The softdevice enforces this requirement and is probably why you get the invalid param error. However, it should work if you only require authentication for write access. What central are you using for test? In case it's an iOS device, try to 'forget' the device from ios settings -> Bluetooth, enable and disable flight mode (clears device cache on phone), then re-connect.  

    Regards,

    Vidar

Children
Related