Keyturner Service: issue Bluetooth API Encryption

I can pair my FOB with a Nuki 2.0 but when I try to read lock state writing encrypted Request Data command, with Keyturner States command indentifier, to USDIO I don’t receive any indication.

I’m using crypto_secretbox_easy() from libsodium library ( Encryption: XSalsa20 stream cipher and Authentication: Poly1305 MAC)

https://libsodium.gitbook.io/doc/secret-key_cryptography/authenticated_encryption

I don’t now if it’s a issue with the encryption or something else. The problem It’s I don’t receive any error message even though I connect to Keyturner Service and have enable indications for USDIO char.

Can anybody help me? Thank you in advance.

Javier Suárez

I tried to change the encryption function e1 to crypto_secretbox_xsalsa20poly1305 (c,m,mlen,n,k)`but still not working.

shared_secret: 467aadc839a2f63ab58b664ec9848ef208ff738eb1dbd8bea86094c901fe560c
authorization_id: 3431680,
app_id: 3380583196

It’s been developed with Platformio IDE and the logs are the following
[D][myBLE.cpp:143] myBLE_connectToServer(): - Found our service
[D][BLERemoteService.cpp:122] retrieveCharacteristics(): >> retrieveCharacteristics() for service: a92ee200-5501-11e4-916c-0800200c9a66
[D][BLERemoteService.cpp:153] retrieveCharacteristics(): Found a characteristic: Handle: 143, UUID: a92ee201-5501-11e4-916c-0800200c9a66
[D][BLERemoteCharacteristic.cpp:43] BLERemoteCharacteristic(): >> BLERemoteCharacteristic: handle: 143 0x143, uuid: a92ee201-5501-11e4-916c-0800200c9a66
[D][BLERemoteCharacteristic.cpp:257] retrieveDescriptors(): >> retrieveDescriptors() for characteristic: a92ee201-5501-11e4-916c-0800200c9a66
[D][BLERemoteCharacteristic.cpp:287] retrieveDescriptors(): Found a descriptor: Handle: 144, UUID: 00002902-0000-1000-8000-00805f9b34fb
[D][BLERemoteCharacteristic.cpp:301] retrieveDescriptors(): << retrieveDescriptors(): Found 1 descriptors.
[D][BLERemoteCharacteristic.cpp:51] BLERemoteCharacteristic(): << BLERemoteCharacteristic
[D][BLERemoteService.cpp:153] retrieveCharacteristics(): Found a characteristic: Handle: 146, UUID: a92ee202-5501-11e4-916c-0800200c9a66
[D][BLERemoteCharacteristic.cpp:43] BLERemoteCharacteristic(): >> BLERemoteCharacteristic: handle: 146 0x146, uuid: a92ee202-5501-11e4-916c-0800200c9a66
[D][BLERemoteCharacteristic.cpp:257] retrieveDescriptors(): >> retrieveDescriptors() for characteristic: a92ee202-5501-11e4-916c-0800200c9a66
[D][BLERemoteCharacteristic.cpp:287] retrieveDescriptors(): Found a descriptor: Handle: 147, UUID: 00002902-0000-1000-8000-00805f9b34fb
[D][BLERemoteCharacteristic.cpp:301] retrieveDescriptors(): << retrieveDescriptors(): Found 1 descriptors.
[D][BLERemoteCharacteristic.cpp:51] BLERemoteCharacteristic(): << BLERemoteCharacteristic
[D][BLERemoteService.cpp:153] retrieveCharacteristics(): Found a characteristic: Handle: 149, UUID: a92ee203-5501-11e4-916c-0800200c9a66
[D][BLERemoteCharacteristic.cpp:43] BLERemoteCharacteristic(): >> BLERemoteCharacteristic: handle: 149 0x149, uuid: a92ee203-5501-11e4-916c-0800200c9a66
[D][BLERemoteCharacteristic.cpp:257] retrieveDescriptors(): >> retrieveDescriptors() for characteristic: a92ee203-5501-11e4-916c-0800200c9a66
[D][BLERemoteCharacteristic.cpp:301] retrieveDescriptors(): << retrieveDescriptors(): Found 0 descriptors.
[D][BLERemoteCharacteristic.cpp:51] BLERemoteCharacteristic(): << BLERemoteCharacteristic
[D][BLERemoteService.cpp:169] retrieveCharacteristics(): << retrieveCharacteristics()
[D][myBLE.cpp:152] myBLE_connectToServer(): - Found our characteristic
[D][myBLE.cpp:153] myBLE_connectToServer(): CanNotify 0
[D][myBLE.cpp:154] myBLE_connectToServer(): CanRead 1
[D][myBLE.cpp:155] myBLE_connectToServer(): CanIndicate 1
[D][myBLE.cpp:156] myBLE_connectToServer(): CanWrite 1
[D][BLERemoteCharacteristic.cpp:330] getDescriptor(): >> getDescriptor: uuid: 00002902-0000-1000-8000-00805f9b34fb
[D][BLERemoteCharacteristic.cpp:334] getDescriptor(): << getDescriptor: found
[D][BLERemoteDescriptor.cpp:138] writeValue(): >> writeValue: handle: 147, uuid: 00002902-0000-1000-8000-00805f9b34fb
[D][BLERemoteDescriptor.cpp:157] writeValue(): << writeValue
[D][BLERemoteCharacteristic.cpp:445] registerForNotify(): >> registerForNotify(): Characteristic: uuid: a92ee202-5501-11e4-916c-0800200c9a66, handle: 146 0x92, props: broadcast: 0, read: 1, write_nr: 0, write: 1, notify: 0, indicate: 1, auth: 0
[D][FreeRTOS.cpp:164] take(): Semaphore taking: name: RegForNotifyEvt (0x3ffe902c), owner: <N/A> for registerForNotify
[D][BLEDevice.cpp:152] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 5] … ESP_GATTC_WRITE_DESCR_EVT
[D][FreeRTOS.cpp:173] take(): Semaphore taken: name: RegForNotifyEvt (0x3ffe902c), owner: registerForNotify
[D][BLEClient.cpp:170] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 5] … ESP_GATTC_WRITE_DESCR_EVT
[D][BLERemoteCharacteristic.cpp:330] getDescriptor(): >> getDescriptor: uuid: 00002902-0000-1000-8000-00805f9b34fb
[D][BLEDevice.cpp:152] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 5] … ESP_GATTC_REG_FOR_NOTIFY_EVT
[D][BLERemoteCharacteristic.cpp:334] getDescriptor(): << getDescriptor: found
[D][BLERemoteDescriptor.cpp:138] writeValue(): >> writeValue: handle: 147, uuid: 00002902-0000-1000-8000-00805f9b34fb
[D][BLEClient.cpp:170] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 5] … ESP_GATTC_REG_FOR_NOTIFY_EVT
[D][BLERemoteDescriptor.cpp:157] writeValue(): << writeValue
[D][BLEDevice.cpp:152] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 5] … ESP_GATTC_WRITE_DESCR_EVT
[D][BLERemoteCharacteristic.cpp:487] registerForNotify(): << registerForNotify()
[D][BLEClient.cpp:170] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 5] … ESP_GATTC_WRITE_DESCR_EVT
[D][myBLE.cpp:72] myBLE_connect(): Start connection to BLE Server.
[D][nuki.cpp:142] create_challenge_payload(): CL Request Data 10 bytes (Unencrypted):
00 5D 34 00 01 00 0C 00
FC 3F
[D][nuki.cpp:66] encrypt_payload(): client is encrypting payload message 10 bytes…
[D][nuki.cpp:30] current_state(): Request lock state: CL sends 56 bytes.
EA 37 65 C4 EE D6 EB C6
BC 2C CF 28 B3 99 13 A4
18 C4 17 4D 7D AB 9C 65
00 5D 34 00 1A 00 E0 B4
FC 3F 60 B4 FC 3F 08 00
00 00 E0 B4 FC 3F 60 B4
FC 3F 08 00 00 00 20 33
[D][BLERemoteCharacteristic.cpp:554] writeValue(): >> writeValue(), length: 56
[D][FreeRTOS.cpp:164] take(): Semaphore taking: name: WriteCharEvt (0x3ffe908c), owner: <N/A> for writeValue
[D][FreeRTOS.cpp:173] take(): Semaphore taken: name: WriteCharEvt (0x3ffe908c), owner: writeValue
[D][BLEDevice.cpp:152] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 5] … ESP_GATTC_WRITE_CHAR_EVT
[D][BLEClient.cpp:170] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 5] … ESP_GATTC_WRITE_CHAR_EVT
[D][BLERemoteCharacteristic.cpp:581] writeValue(): << writeValue

Hi Javier,

So your key is 467AADC839A2F63AB58B664EC9848EF208FF738EB1DBD8BEA86094C901FE560C

The message you’re sending is EA3765C4EED6EBC6BC2CCF28B39913A418C4174D7DAB9C65005D34001A00E0B4FC3F60B4FC3F08000000E0B4FC3F60B4FC3F080000002033
This means the nonce is EA3765C4EED6EBC6BC2CCF28B39913A418C4174D7DAB9C65

With your key and the nonce the message fails to decrypt.
Using your nonce and key, the full message you’re sending should look like this: EA3765C4EED6EBC6BC2CCF28B39913A418C4174D7DAB9C65005D34001A00B1E7311B9B3B49B2938487CAC2DCBA3A8117136247FF524C60B4

Unencrypted message: 005D340001000C00
Unencrypted message with CRC: 005D340001000C00572B
Encrypted message: B1E7311B9B3B49B2938487CAC2DCBA3A8117136247FF524C60B4
Encrypted message with authId, length and nonce: EA3765C4EED6EBC6BC2CCF28B39913A418C4174D7DAB9C65005D34001A00B1E7311B9B3B49B2938487CAC2DCBA3A8117136247FF524C60B4

If you’re using libsodium, you may use crypto_secretbox() and crypto_secretbox_open() to encrypt and decrypt.


Note: please also register for indications on GDIO. You’ll receive the “NOT_AUTHORIZED” error there.

regards,
Marc

Hi Marc,

Following your advice I’ve changed to crypto_secretbox(), using libsodium library in C++, and also register for indications on GDIO to get the error.

Eventually the result was:

[D][nuki.cpp:155] create_challenge_payload(): CL Request Data 10 bytes (Unencrypted):
 00  5D  34  00  01  00  0C  00
 57  2B
[D][nuki.cpp:68] encrypt_payload(): client is encrypting payload message 10 bytes...
[D][nuki.cpp:81] encrypt_payload(): crypto_box(c,m,mlen,n,k)
[D][nuki.cpp:82] encrypt_payload(): m :
 00  5D  34  00  01  00  0C  00
 57  2B
[D][nuki.cpp:84] encrypt_payload(): mlen : 10
[D][nuki.cpp:85] encrypt_payload(): n :
 03  19  9B  C2  C1  71  4C  6C
 00  BA  93  40  A0  3C  BB  2C
 27  C0  E4  40  D9  98  CE  C4
[D][nuki.cpp:87] encrypt_payload(): k :
 FD  AF  DC  BF  9B  30  B3  E6
 58  C7  59  88  FA  7D  98  D0
 24  FA  E4  3E  E3  97  2D  78
 DB  06  D1  79  AD  E8  94  34
[D][nuki.cpp:30] current_state(): Request lock state: CL sends 56 bytes.
 03  19  9B  C2  C1  71  4C  6C
 00  BA  93  40  A0  3C  BB  2C
 27  C0  E4  40  D9  98  CE  C4
 00  5D  34  00  1A  00  C0  B4
 FC  3F  40  B4  FC  3F  08  00
 00  00  C0  B4  FC  3F  40  B4
 FC  3F  08  00  00  00  20  32
[D][BLERemoteCharacteristic.cpp:554] writeValue(): >> writeValue(), length: 56
[D][FreeRTOS.cpp:164] take(): Semaphore taking: name: WriteCharEvt (0x3ffe9220), owner: <N/A> for writeValue
[D][FreeRTOS.cpp:173] take(): Semaphore taken:  name: WriteCharEvt (0x3ffe9220), owner: writeValue
[D][BLEDevice.cpp:152] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 5] ... ESP_GATTC_NOTIFY_EVT
[D][BLEClient.cpp:170] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 5] ... ESP_GATTC_NOTIFY_EVT
[D][BLERemoteCharacteristic.cpp:170] gattClientEventHandler(): Invoking callback for notification on characteristic Characteristic: uuid: a92ee201-5501-11e4-916c-0800200c9a66, handle:
143 0x8f, props: broadcast: 0, read: 1, write_nr: 0, write: 1, notify: 0, indicate: 1, auth: 0
[D][myBLE.cpp:123] myBLE_notifyCallback(): ******************** Notify callback for characteristic
[D][myBLE.cpp:124] myBLE_notifyCallback(): a92ee201-5501-11e4-916c-0800200c9a66
[D][myBLE.cpp:125] myBLE_notifyCallback():  of data length 9

[D][nuki.cpp:272] processMessage(): client receives 9 bytes.
 12  00  20  00  00  C2  C1  B9
 17
[E][nuki.cpp:376] get_commandId(): Command Id: ERROR_REPORT >> K_ERROR_NOT_AUTHORIZED.
D][nuki.cpp:278] processMessage(): size of response buffer 9
[D][BLEDevice.cpp:152] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 5] ... ESP_GATTC_WRITE_CHAR_EVT
[D][BLEClient.cpp:170] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 5] ... ESP_GATTC_WRITE_CHAR_EVT
[D][BLERemoteCharacteristic.cpp:581] writeValue(): << writeValue
[E][myBLE.cpp:79] myBLE_connect(): Failed to connect to the server; there is nothing more we will do.
[D][BLEDevice.cpp:152] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_DISCONNECT_EVT
[D][BLEClient.cpp:170] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_DISCONNECT_EVT
[E][BLEClient.cpp:193] gattClientEventHandler(): disconnect event, reason: 19, connId: 0, my connId: 0, my IF: 4, gattc_if: 4
[D][BLEDevice.cpp:152] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_CLOSE_EVT
[D][BLEClient.cpp:170] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_CLOSE_EVT
[D][BLEDevice.cpp:152] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 5] ... ESP_GATTC_DISCONNECT_EVT
[D][BLEClient.cpp:170] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 5] ... ESP_GATTC_DISCONNECT_EVT
[E][BLEClient.cpp:193] gattClientEventHandler(): disconnect event, reason: 19, connId: 0, my connId: 0, my IF: 5, gattc_if: 5
[D][BLEDevice.cpp:152] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 5] ... ESP_GATTC_CLOSE_EVT
[D][BLEClient.cpp:170] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 5] ... ESP_GATTC_CLOSE_EVT
[E][myBLE.cpp:79] myBLE_connect(): Failed to connect to the server; there is nothing more we will do.

I don’t know if the issue It’s because original NaCl crypto_box() API needs for message padding and pointer arithmetic prior to encryption, if I use libsodium library with new wrappers crypto_secretbox_easy() remove this need.

Thank you very much.

Regards,
Javier

Hi Javier,

Again I’m using your key FDAFDCBF9B30B3E658C75988FA7D98D024FAE43EE3972D78DB06D179ADE89434 and fail to decrypt your message with it.

Your payload is 03199BC2C1714C6C00BA9340A03CBB2C27C0E440D998CEC4005D34001A00C0B4FC3F40B4FC3F08000000C0B4FC3F40B4FC3F080000002032

So your nonce is 03199BC2C1714C6C00BA9340A03CBB2C27C0E440D998CEC4 and the encrypted message is C0B4FC3F40B4FC3F08000000C0B4FC3F40B4FC3F080000002032.

So if I try to decrypt C0B4FC3F40B4FC3F08000000C0B4FC3F40B4FC3F080000002032 with your key and nonce (and crypto_secretbox_open) the decryption fails.


If I take your unencrypted message 005D340001000C00572B and encrypt it with your nonce and key, the result is CBD33270BB9F810421316E05657BD92417BAB9F43318862D2502, not C0B4FC3F40B4FC3F08000000C0B4FC3F40B4FC3F080000002032.

So the whole message should be:
03199BC2C1714C6C00BA9340A03CBB2C27C0E440D998CEC4 005D3400 1A00 CBD33270BB9F810421316E05657BD92417BAB9F43318862D2502


How to you get the C0B4FC3F40B4FC3F08000000C0B4FC3F40B4FC3F080000002032 message?

It seems to contain the same message twice and a CRC on the end:
C0B4FC3F40B4FC3F08000000 C0B4FC3F40B4FC3F08000000 2032

regards,
Marc

Hi Marc,

Thanks for the prompt answer.

I’m using crypto_secretbox(c,m,mlen,n,k) without appling any padding in m.

m= 00 5D 34 00 01 00 0C 00 57 2B
mlen = 10
n = 03 19 9B C2 C1 71 4C 6C 00 BA 93 40 A0 3C BB 2C 27 C0 E4 40 D9 98 CE C4
k = FD AF DC BF 9B 30 B3 E6 58 C7 59 88 FA 7D 98 D0 24 FA E4 3E E3 97 2D 78 DB 06 D1 79 AD E8 94 34

I don’t know if the issue It’s because original NaCl crypto_box() API needs for message padding and pointer arithmetic prior to encryption.

Should I apply padding in m?

m = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 5D 34 00 01 00 0C 00 57 2B
mlen : 42

If You use libsodium library with new wrappers crypto_secretbox_easy() remove this need.

Thank you.

Regards,
Javier

Hi Javier,

Please use crypto_secretbox, not crypto_box.
And yes, please add the padding.

regards,
Marc

Sorry I meant crypto_secretbox, I’m trying to add the padding

Thank you.

Regards,
Javier

Hi Marc,

I’ve found out a mistake that I was making, I need to initialize some constans in crypto_box:

#define crypto_secretbox_KEYBYTES 32
#define crypto_box_NONCEBYTES 24 -> Before the value was 32
#define crypto_secretbox_MACBYTES 16

And now I think It’s working.

Thank you again.

Regards,
Javier