Bluetooth Low Energy (a.k.a Bluetooth LE, BTLE, Bluetooth Smart)

security extensions for BLE_API

23 Apr 2015


I'd like to introduce some APIs to allow link security in BLE.

Encryption/pairing/bonding can be enabled by initializing security-manager module of the BLE stack. Marking characteristics as requiring security will then enforce pairing/bonding during attribute access. I've also added some callbacks to get indications about the progress of the pairing procedure.

These APIs depend on v8 of the Nordic SDK. You can review the proposed extensions at

I request your feedback.


security extensions to BLEDevice.h

     * Enable the BLE stack's Security Manager. The Security Manager implements
     * the actual cryptographic algorithms and protocol exchanges that allow two
     * devices to securely exchange data and privately detect each other.
     * Calling this API is a prerequisite for encryption and pairing (bonding).
    ble_error_t initializeSecurity(void);

     * Setup a callback for when the security procedure for a link has started.
    void setOnSecuritySetupStarted(Gap::HandleSpecificEvent_t callback);

     * Setup a callback for when the security procedure for a link has
     * completed.
    void setOnSecuritySetupCompleted(Gap::HandleSpecificEvent_t callback);

     * Setup a callback for when a link with the peer is secured. For bonded
     * devices, subsequent reconnections with bonded peer will result only in
     * this callback when the link is secured and setup procedures will not
     * occur unless the bonding information is either lost or deleted on either
     * or both sides.
    void setOnLinkSecured(Gap::HandleSpecificEvent_t callback);

     * Setup a callback for bonding; i.e. that link-specific security context
     * is stored persistently for a peer device.
    void setOnSecurityContextStored(Gap::HandleSpecificEvent_t callback);

security extensions to GattCharacteristic.h

    enum ble_gatt_char_required_security_t {
        SECURITY_MODE_ENCRYPTION_OPEN_LINK = 0x00, /**< Set security mode to require no protection, open link. */
        SECURITY_MODE_ENCRYPTION_NO_MITM   = 0x01, /**< Set security mode to require encryption, but no MITM protection. */
        SECURITY_MODE_ENCRYPTION_WITH_MITM = 0x02, /**< Set security mode to require encryption and MITM protection. */
        SECURITY_MODE_SIGNED_NO_MITM       = 0x04, /**< Set security mode to require signing or encryption, but no MITM protection. */
        SECURITY_MODE_SIGNED_WITH_MITM     = 0x08, /**< Set security mode to require signing or encryption, and MITM protection. */

     * Setup the minimum security (mode and level) requirements for access to the characteristic's value attribute.
     * @param securityMode Can be one of encryption or signing, with or without protection for MITM (man in the middle attacks).
    void requireSecurity(ble_gatt_char_required_security_t securityMode) {
        _requiredSecurity = securityMode;
24 Apr 2015

should someone want to try this out, the corresponding changes to the nRF51822 can be found at

03 Jun 2015

Is there a mbed sample application that exercises these features?

05 Jun 2015
10 Jul 2015

Hi Rohit Grover,

I have found this feature very interesting, seems it not only support binding, but also support pstorage, would you explain more details for me?

Q1. Where does it store informations about the bonding? Do I need to reserve and tell the class where to store?

Q2. Is there any guidence on how to use pstorage? Including, how to specify flash erea, how to erase and write a page or block?

Thanks very much!

10 Jul 2015

The device manager and pstorage modules together provide support for security and persistent keys. Pstorage provides key persistence. The device manager registers a region with pstorage during initialization to be used for keys. The application doesn't need to do anything, this is handled automatically by ble initialization.

Pstorage module comes from Nordic. They are behind the features it provides. There is a separate thread which captures some of this information:

You can refer to URIBeaconConfigService for an example.

11 Jul 2015

Rohit, thanks for the example and kind explaination. I have read the HRM sec and URIBeacon both. I am now confusing on two questions.

Because device manager and your URIstorage all make pstorage initialize, while will make the last n pages for storing some data, the storage size is counted automatically by pstorage function.

I feel they are possibly going to disturb each other if not well configured. My question is how do you pre-allocate the flash spaces for each application if they are both used. Do you use the definitions inside psstorage_platform.h? I see in dm_init.c, there are 3 storage instances: application, connection and peer.

A further question is, if I use device manager, or security manager which registrates a storage handle, and assume I have allocated my storage space inside pstorage_platform.h, then, I may want to enumates my storage handle to read or write, do I need to retrieve the storage handle from device manager(it claimed as static)? or do I simply make another registration to get a new handle?

11 Jul 2015

I get my pstorage works, one questions is I can erase and write, or use "update" just like your example, what is the advantage of "update"?

11 Jul 2015

perhaps you'll find your answer here:

Let us know if this doesn't help.

11 Jul 2015

@Ma Yunfei: you've asked several questions. Please let us know which one are still unanswered after studying the Nordic docs and code in

12 Jul 2015

Hi Rohit, Thanks very much for your help, Here is only one question not understand exactly, when there is an existing record, I can pstorage_clear following with pstorage_store, or use "pstorage_read" following with "pstorage_update" , they have the same result to me, what is the advantage of "pstorage_update"?

Anyway, I feel I understand it better now, I'd like to share my understanding here, hope it helpful, correct me if I am wrong. Like the picture in @ shows, there are three "blocks for application module", First, we define the total "persistent storage module size" in "pstorage_platform.h" to allocate flashes by modify the PSTORAGE_MAX_APPLICATIONS like following code. It will allocate corresponding pages for use.(In my opinion, this can be optimized a little by simply rename the macro to PSTORAGE_MAX_FLASH_PAGES)

#define PSTORAGE_FLASH_PAGE_END                                     \

#define PSTORAGE_MAX_APPLICATIONS   1                                                           /**< Maximum number of applications that can be registered with the module, configurable based on system requirements. */
#define PSTORAGE_MIN_BLOCK_SIZE     0x0010                                                      /**< Minimum size of block that can be registered with the module. Should be configured based on system requirements, recommendation is not have this value to be at least size of word. */

                                    * PSTORAGE_FLASH_PAGE_SIZE)                                 /**< Start address for persistent data, configurable according to system requirements. */
#define PSTORAGE_DATA_END_ADDR      ((PSTORAGE_FLASH_PAGE_END - 1) * PSTORAGE_FLASH_PAGE_SIZE)  /**< End address for persistent data, configurable according to system requirements. */
#define PSTORAGE_SWAP_ADDR          PSTORAGE_DATA_END_ADDR                                      /**< Top-most page is used as swap area for clear and update. */

These definitions will be initialized during pstorage_init.

Second, use “pstorage_register”, you are required to tell the block number and size. Pstorage will allocate corresponding flash pages for your application. Each registration not limited within one page, but if all pages allocated previously has been used out, it will fail. And this function can be invoked for several times, depending on your applications number.

13 Jul 2015

@Ma Yunfei: I believe pstorage_update() is a better API because it hides an implementation detail (pstorage_clear()) underneath.

22 Jul 2015

Hi Rohit,

These extensions seem to work for individual characteristics only. Is there a way to enable secure pairing/bonding when connecting to the device, rather than when accessing characteristics with security enabled? Basically, what I want is to expose advertising data only until the connection is established using a passkey.

22 Jul 2015

A Central can trigger a pairing request after a connection has been established; this will be independent of security requirements of characteristics. You'd need an app which allows you to bond regardless of characteristic access; Nordic's Master Control Panel does.

22 Jul 2015

Thanks. I see. So the connection process itself is always insecure; then, once connected, a central can pair/bond to the peripheral and access all the characteristics. Am I correct? Just tried to bond using Master Control Panel, it says it's bonding but doesn't show any dialog to enter the passkey. It must be possible to set it somehow through the settings, I couldn't find.

22 Jul 2015

Yes, pairing is initiated either by the Central after a connection has been established, or when the client accesses a characteristic (on the GattServer) which requires security.

The policy for the use of passkey can be set when initializing the securityManager.

23 Jul 2015

Thanks for the explanation, Rohit. It's all clear to me now.

23 Oct 2015

Hi Rohit, i have seen this "issue" when we bond a nrf with iPhone. 1: we bond the board with de device and now we can look on bluetooth settings of iphone that the device is connect and bonded. 2: now, if we are on bluetooth settings we click "Home Button"; 3: now we reopen the settings and we can't look that the "(i)" near the list of bonded device. 4: now if we click on back button named "Settings" and we reopen "bluetooth settings" we can see the "(i)" near every name.

The "(i)" is used for delete the bonding.

On android and windows phone there aren't any problem

I hope I was clear.

Sorry for the English. Enrico

23 Oct 2015

Hi Enrico,

You can setup callbacks for various events around pairing/bonding (refer to Could you please try to setup some of these callbacks with some basic printfs and confirm that pairing and bonding are taking place on the peripheral as expected during your usage scenario with iPhone? You can even setup a periodic callback and print the link's security status (

If bonding state is stored properly and the system doesn't report a loss of link security over time, then the issue is with the phone UI or phone's ble stack. If you think there is a problem with the nRF port for BLE, then please log an issue at


23 Oct 2015

hi, i try to do it, i have see this issue with BLE_SecureHeartRate thanks

23 Oct 2015

i have see that with android i put the passKey and with iphone nothing

23 Oct 2015

We're a very thin layer above the Nordic Bluetooth stack and Security Manager APIs. You might want to post to Nordic's developer forums.

20 Jun 2016

@Rohit, Sorry to open old thread, but I'm having some issues with the security, and you seem to be the go-to man.

I have a peripheral device based on nRF51822, and want to enable encryption, but not necessarily bonding. My device has no IO capabilities so am using the just works model, however the central device (iPhone) is having lots of trouble connecting. I've tried various combinations of security manager settings with enabledBonding and requireMITM,

enableBonding = true, requireMITM = false connection works ok using Master Control Panel and Nordic dongle, however iPhone will connect and pair and read characterisitics on first connection, then not be able to read any characterisitics on subsequent connections.

enableBonding = false, requireMITM = false connection works ok using Master Control Panel and Nordic dongle, however iPhone keeps requesting pairing, and won't exit popup unless user cancels pairing operation.

Also, on all of my custom characterisitics, I've set the security requirements to ENCRYPTION_NO_MITM

Do you have any suggestions? Are there more security settings that might be relevant? I'm also searching through Nordic forum but not finding anything specifically helpful.


29 Sep 2016

What if we have a mode on this lock that allows a user to set their own 4-digit pin? That way, we’re not worried about someone decompiling an Android app and then being able to open all locks everywhere.

That’s much better! Well… No. Still not.

While this custom PIN method at least stops 1 PIN code from being used everywhere, there is absolutely no security surrounding the value of the PIN.

By that, I mean someone with a $30 Bluetooth sniffer could be within range of you, while you’re locking or unlocking your safe – and capture your PIN code out of the air. Your safe will still lock and unlock correctly, and you’ll be none-the-wiser, but some malicious thief lurking in the bushes will have your safe’s PIN code…

In this case, the thief still needs to get into your house, but instead of a safe, let’s pretend this is the security you use for your car, or your front door. For more details visit:

04 Nov 2016

Hi Rohit,

I have gone through the sample application of ble secure heart rate and successfully secured the particular characteristics. I wanted to secure the whole ble device so that no third party can connect to my ble device. Is there a way to set a static passkey during connection establishment? please help me in this problem. Thanks

30 Jan 2017


i am using security manager to implement security. since my security key is public i need to accept pairing request only for a short duration .

my requirements is this.

my system should accept connection from already bonded device at any time. the system should reject any pairing request normally. there is a button in the system . when the button is pressed , the system should accept pairing from any central for few minutes

how can i implement this.

02 Mar 2017

Hi Rohit, I have gone through the sample application of ble secure heart rate and successfully secured the particular characteristics too. And I find that although we cancel the pairing, we can listen the notifications of Hear Rate Measurement (read unable). We also can read Body Sensor Location. Could you tell me why? I think it's not safe, so I wanna konw how to secure the whole ble device. Thanks!