Questions about LESC, MITM and passkey

Hi! I am using SDK15 to develop an application for nordic chip which won't be using any kind of display nor keyboard input, so probably I'm gonna go for static passkey option. I can't also use OOB.

My requirements are to:
a) authenticate devices wanting to connect to my chip and disallow them to or at least prevent them from accessing services without pairing,
b) assure certain level of encryption confidential data sent, so noone can sniff them

I have seen some posts saying that static passkey doesn't provide much protection and it doesn't work with LESC.

1. Is it true that every attempt to guess passkey reveals one bit of the key? So after a few attempts anyone is able to read my confidential characteristics attributes? Or am I messing the security key with the passkey?

Offline Emil Lenngren 11 months ago in reply to Ulrich Myhre
You should ask yourself what your security goals are (and tell us). As Ulrich mentioned, a passkey in the legacy pairing adds almost no security. In the LESC model, a static passkey adds no security at all since each failed attempt reveals 1 bit of the key, so you can crack it in on average 10 attempts.

2. I realize that knowing the static passkey makes it possible to decipher the data sent over air, for example with sniffer. What condition has to be met in order to do this? Eavesdropping during pairing, during connecting with already bonded device or anytime the connection is alive?

3. Is there an option for blacklisting devices, I mean for those trying to bruteforce passkey? For example insert wrong passkey three times in a row and don't accept connection from them anymore or something like that.

4. As I have read that LESC doesn't work with static passkey. Here's what I did just now:
ble_app_multirole_lesc with


<info> app: CENTRAL: BLE_GAP_EVT_AUTH_STATUS: status=0x0 bond=0x1 lv4: 1 kdist_own:0x3 kdist_peer:0x2

when I changed iocaps to display_only despite my device having no display:



uint8_t passkey [] = "123456";
ble_opt_t passkey_t;
passkey_t.gap_opt.passkey.p_passkey = &passkey[0];

err_code = sd_ble_opt_set(BLE_GAP_OPT_PASSKEY, &passkey_t);

<info> app: CENTRAL: BLE_GAP_EVT_AUTH_STATUS: status=0x0 bond=0x1 lv4: 1 kdist_own:0x3 kdist_peer:0x2

The logger output is exactly the same. Does that mean I have used static passkey to successfully protect my device from MITM attack (with ECC) and assured authentication?

  • Hi,

    You can find some guidelines here on BLE security: 

    Our latest nRF5 SDKv15 should contain various examples that show bonding from just works to lesc.

    What is important to understand is that the only potential weakness is if someone is sniffing when the initial bonding occurs, and the level of weakness then depending on the capabilities and bonding procedure used. A sniffer may be able to get the long term key that is used for all later communication and encryption if using passkey (can be brute forced) or just works.

    However if the sniffer is not present during the bonding procedure, then all communication is equally safe, since all bonding procedures generate a 128bit long term key which can't be cracked or brute-forced. 

    The link can only be encrypted by two devices that have been previously bonded re-establish connection, and it's only then they may exchange data.

    Best regards,