Bounding Unicorns

BT121 - Legacy pairing and fixed PIN code or Passkey

Mirrored from here

One important new feature introduced with the public official version 1.1.0 build 154 of the BT121 firmware is the support for legacy pairing.

\ In order to enter the legacy shared PIN code the new command to use is sm_enter_pin_code(...) and this command should be launched within 30 seconds from receiving the event sm_pin_code_request(...). Read more about the new command and event in the BGAPI pdf reference or in the HTML-based reference called dumo.html and found under the directory \hostbgapi\ of the SDK.

\ Notice the following:\ - No PIN code can be stored by the Smart Ready stack so that it is used automatically whenever legacy pairing is to be carried on.\ - The BT121 must be made bondable beforehand, with command sm_set_bondable_mode(1), for the link keys created during the pairing process to be locally stored for any future connection (until devices are un-bonded). This is in fact required for Bluetooth Classic.\ - When the BT121 makes a SPP call, and the called device is not already bonded, then pairing is always requested by the BT121, and the same PIN code must be entered at the both sides in case the remote device uses legacy pairing.\ - When the other side using legacy pairing calls the BT121, and the two devices are not already bonded, then the remote side might or might not request for pairing: if pairing is requested, then the same PIN code must be entered at the both sides; if pairing is not requested, then the BT121 will accept the clear-text connection.

\ You can see a typical case in the two pairs of attached logs: looking for example at the two *test1*.txt logs from the BT121 perspective, at the remote side we have a WT11i (with mac of 00:07:80:43:69:9c) where Secure Simple Pairing (SSP) is disabled and where we configured a legacy PIN code of \"0123456789\" - at the BGTool being used to test with the BT121, the legacy PIN code is entered with command seen at timestamp 09:14:30,0566 following the event seen at timestamp 09:14:18,0664\ \ Of course the mandatory SSP is also supported by the Smart Ready stack in the BT121. With it you first have to clarify which capabilities your device supports and then define if you want Man-In-The-Middle (MITM) protection or not: configuration will then happen with the BGAPI command sm_configure(...).\ Depending on the above configuration you might be prompted to display or confirm or enter a passkey respectively with the events sm_passkey_display or sm_confirm_passkey or sm_passkey_request. As a consequence your device will show the passkey to the user to be confirmed at the other side (for example if you have Display-only capability) or you will confirm or enter a passkey with the BGAPI commands sm_passkey_confirm(...) or sm_enter_passkey(...) respectively.\ \ One typical question is if there is any way to force a known PIN code for pairing in general. Unfortunately with SSP there is no way to do that according to the specification, except if you configure the module to have Keyboard-only capability and have your host MCU to enter the desired passkey with the command sm_enter_passkey(...). However, this requires the other side to also have Keyboard-only capability, otherwise, if the other side has for example Display-only capability, it will just display a randomly generated passkey that you will have to enter to module for pairing.\ Please refer to the tables below, which are part of the specification (and found also at to understand the possible SSP pairing mechanisms and which of them is selected depending on the capabilities at the Initiator and at the Responder.


\ Only the legacy pairing allows the use of a shared PIN code to be entered or pre-configured at both sides (like the typical 0000 or 1234 of many old Bluetooth hands-free headset), but legacy pairing happens only when at least one of the two sides is based on the very old Core Specification 2.0 and below. In fact, it is important here to notice that SSP is the mandatory pairing framework between two devices both supporting Core Specification 2.1 and above.\ \ So, again, it is not possible to configure a specific known passkey with the Secure Simple Pairing. In SSP the closest match to the legacy pairing is when both devices declare support for the capability called Keyboard-only. If you have control of both sides, then you can configure both for Keyboard-only capability, and in BT121 this is done with command dumo_cmd_sm_configure(1,2). With that configuration in place, you would then make sure that users at both sides enter the same known passkey, and in BT121 you would have your host program (or a BGScript) to simply issue sm_enter_passkey(connection, fixed_known_passkey) upon receiving the event sm_passkey_request. Unfortunately, it is rare to happen that you have full control of both sides: instead, a more typical case is when you want to force a PIN code to be entered by the user of some smartphone app, but it is a fact that for example smartphones and PCs normally declare to support for Keyboard+display which prevents the above workaround.\ \ Despite the demand for allowing a developer to disable SSP in the BT121 Smart Ready stack, so to fall back in any case to legacy pairing, and thus having the opportunity to use the fixed PIN code, our decision is for the moment not to introduce this configuration option, reason being that our Bluetooth stack would go out of specification. If you need the kind of security provided by the old legacy pairing mechanism between two devices following the Core Specification 2.1 and above, you will have to consider alternatives at the application level.

For example, with the BR/EDR Serial Port Profile you might consider authentication/authorization handshaking implemented by your application and carried on over RFCOMM just after SSP Just-works pairing (if you wish no additional user action) and connection establishment. Just to give an idea, this is the Apple\'s approach with iAP. One simple example of application level security has been added into the main.c of the host example program under the directory \host_example\spp_server\ of the latest SDK version 1.1.1 build 168.

For BLE things might be even easier: in case of a product with no display and also with no keyboard or a Yes/No button, then only the un-authenticated Just-works pairing mechanism would be available. In order to add a level of authentication/authorization, a characteristic in the GATT database could be used to verify/hold/enter a secret user code before the actual data exchange is started. Notice that this method would not replace the Bluetooth pairing itself, but it would be a replacement, or an addition to that, to overcome the lack of authentication/authorization in the Just-works mode.

A BGscript example with an idea of application level security is discussed at It presents an attempt to replicate the C example implementation seen in the spp_server host example, with the addition of the BLE part.