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

Confirm Value Failed When Pairing

I am writing an App for the Central/Master side using the s130 v1.0.0 SD. I am connecting to the soft device using the python wrappers for the nRF51-BLE-Driver-Win 0.5.0.

I am getting an error 0x84 BLE_GAP_SEC_STATUS_CONFIRM_VALUE ("Confirm Value Failed") when bonding or pairing to my device. The pairing method being used is passkey entry (on the central).

Running a packet sniffer gives me this:

Slave -> Master: Rcvd Security Request: Bonding, MITM
Master -> Slave: Rcvd Pairing Request: Bonding, MITM, Initiator Key(s): LTK IRK , Responder Key(s): LTK IRK
Slave -> Master: Rcvd Pairing Response: Bonding, MITM, Initiator Key(s): LTK IRK , Responder Key(s): LTK IRK
Master -> Slave: Rcvd Pairing Confirm
Slave -> Master: Rcvd Pairing Confirm
Master -> Slave: Rcvd Pairing Random
Slave -> Master: Rcvd Pairing Failed: Confirm Value Failed

Looking at Bluetooth 4.1 spec, Volume 3, Part H, 2.3.5.5, this is happening because the slave's calculation of the Pairing Confirm value does not match what the master calculated and sent to the slave.

The spec says the Pairing Confirm (Mconfirm) value has the following inputs:

  • TK (based on Passkey)
  • Mrand (This is 'Pairing Random' value in the packet trace above)
  • Pairing Request command
  • Pairing Response command
  • initiating device address type
  • initiating device address
  • responding device address type
  • responding device address

The only thing my app has control over is the first one, TK (Passkey). Is this correct?

So, here is the code I use to respond to send the Passkey in response to the BLE_GAP_EVT_AUTH_KEY_REQUEST event (trimmed down):

key_type = gap_event.params.auth_key_request.key_type  # This is 1

# Passkey is 999999, sent as ASCII array per documentation
p_key = util.list_to_uint8_array([0x39, 0x39, 0x39, 0x39, 0x39, 0x39]).cast()
err_code = ble_driver.sd_ble_gap_auth_key_reply(self.__connection_handle, key_type, p_key)
if err_code == ble_driver.NRF_SUCCESS:
    self.log.debug("Successfully sent auth key reply")
else:
    self.log.error("Received error code from sd_ble_gap_auth_key_reply 0x{:02X}".format(err_code))

I can't figure out what I'm doing wrong. Other apps (such as the nRF Connect Android app) can pair fine.

Thanks in advance for any help!

Related