I have the following 128 bit service UUID:
0000FFE0-0000-1000-8000-00805F9B34FB
AFAIK, this is basically the base UUID of 00000000-0000-1000-8000-00805F9B34FB, thus, this can be simplified into the 16 bit UUID of "FFE0".
I can't find this 16 bit UUID in any of the predefined lists (https://btprodspecificationrefs.blob.core.windows.net/assigned-values/16-bit%20UUID%20Numbers%20Document.pdf), though, which leads me to believe that the manufactures of this particular BLE module are being a bit naughty and incorrectly defining a 128-bit UUID?
Have I missed something ?
It does appear to be a custom service in the Bluetooth SIG reserved range.
If a custom service is created it should use a UUID outside of that range.
Related
I use the Ble library, but I want to connect/pair only the first device/phone. After this only the first device is allowed to reconnect. How do I implement this? Is there a best practice? Do I need to filter the deviceid? Or are there better ways to acchieve this?
That can be achieved using the Filter Accept List (previously known as White List), which is standard in the BLE spec. How to use it depends on the Bluetooth stack you are using, so you should check the manual for the Bluetooth stack you are using (you didn't mention).
If you want to support Random Resolvable addresses, you can use the Resolving List where you put the corresponding IRKs.
But a personal opinion is to instead always let any device connect to your device, and then secure sensitive services using MITM-secure authentication instead (pairing). That could potentially lead to a better experience for the user, because otherwise any connection attempt from "wrong" device will just lead to a unknown connection error from the user which might be hard to understand.
I'm trying to learn how to use BLE on a Pi4.
I have installed hcitool and gatttool and have figured out how to use them. I have also set up a virtual device using LightBlue on a Mac.
pi#raspsky:~ $ sudo hcitool -i hci0 lescan
LE Scan ...
98:9E:63:39:8B:ED Blank
98:9E:63:39:8B:ED (unknown)
That "Blank" is the virtual device.
pi#raspsky:~ $ gatttool -b 98:9E:63:39:8B:ED -I
[98:9E:63:39:8B:ED][LE]> connect
Attempting to connect to 98:9E:63:39:8B:ED
Connection successful
[98:9E:63:39:8B:ED][LE]> primary
attr handle: 0x0001, end grp handle: 0x0005 uuid: 00001800-0000-1000-8000-00805f9b34fb
<snip>
attr handle: 0x0028, end grp handle: 0x002b uuid: 00001111-0000-1000-8000-00805f9b34fb
[98:9E:63:39:8B:ED][LE]> char-desc
handle: 0x0001, uuid: 00002800-0000-1000-8000-00805f9b34fb
<snip>
handle: 0x002b, uuid: 00002901-0000-1000-8000-00805f9b34fb
Now, I'd like to be able to read from the virtual device, but I have no idea which "handle" to use. I figured out by trial and error that I need to use 002b:
[98:9E:63:39:8B:ED][LE]> char-read-hnd 002b
Characteristic value/descriptor: 53 6f 6d 65 74 68 69 6e 67
That hex turns out to be the ascii string "Something" which is what I put in the virtual device.
But, where does that handle come from? It seems like I ought to be able to figure it out without having to use trial and error:
UPDATE:
In this example Using bash and gatttool to get readings from Xiaomi Mijia LYWSD03MMC Temperature Humidity sensor, the author shows how to use hcitool to get the mac address of a BLE Device. The article then goes on with an example:
bt=$(timeout 15 gatttool -b A4:C1:38:8C:77:CA --char-write-req --handle='0x0038' --value="0100" --listen)
But the author never explains where the handle (handle='0x0038') came from. I see how you can get a list of handles using gatttool, but the only way I can figure out what data goes with each handle is to try each one until I find the one I want. There must be an easier way.
Since you updated your question, I have another answer for you. But since your topic is not facing any programming issue, you better ask it again at another StackExchange.
the only way I can figure out what data goes with each handle is to try each one until I find the one I want. There must be an easier way.
I guess I have to disappoint you here.
While there are some predefined GATT profiles by Bluetooth SIG, most of the proprietary implementations do not expose any meaningful information about their characteristics but the mandatory UUIDs.
If you are lucky, you might be able to find a Characteristic User Description (Bluetooth Core Spec Vol. 3 Part G 3.3.3.2) or deduce some information from a Characteristic Presentation Format (Bluetooth Core Spec Vol. 3 Part G 3.3.3.5) characteristic descriptor; but since these are optional, I doubt that a proprietary implementation will provide these.
So for a proprietary implementation, you have to reverse engineer that information or try to find it online (often other people already reversed engineered common devices).
hcitool, and gatttool were deprecated by the BlueZ project in 2017. If you are following a tutorial that uses them, there is a chance that it might be out of date. The current BlueZ tool for generic scanning and exploration is bluetoothctl.
With BLE the UUID is the key to identifying the service/characteristic/descriptor that you are interested in.
The 16-bit UUID Numbers Document lists the adopted UUIDs. SIG-adopted attribute types (UUIDs) share all but 16 bits of a special 128-bit base UUID:0000xxxx-0000-1000-8000-00805F9B34FB. The document lists the 16-bit value that goes into that base.
As you have with the virtual device using LightBlue, custom UUIDs can be created. These need to be outside of the 128-bit base reserved for SIG-adopted values.
As SO is about software development, I'll point you at the BlueZ API documentation should you want to do any of this with code. There are also examples in the BlueZ source tree.
The thing you are looking for is generally speaking GATT/ATT itself.
Basically you query a device implementing a GATT server
The best (res)source and reference for anything related to Bluetooth® is IMHO the Bluetooth Core Specification in the version your devices support and you are developing for.
Attribute Protocol (ATT)
Bluetooth Core Specification 5.2 Vol. 3 Part F describes the ATTRIBUTE PROTOCOL (ATT) as follows:
This Part defines the Attribute protocol; a protocol for discovering, reading, and writing attributes on a peer device
The ATT is some sort of "low level" since it describe the actual protocol itself and its messages / Protocol Data Units (PDUs), but it's definitely worth a (periphere) read, especial chapters 3.1 Introduction and 3.2 Basic Concepts.
Generic Attribute Profile (GATT)
Bluetooth Core Specification 5.2 Vol. 3 Part G describes the GENERIC ATTRIBUTE PROFILE (GATT) as follows:
This Part defines the Generic Attribute Profile that describes a service framework using the Attribute protocol for discovering services, and for reading and writing characteristic values on a peer device.
You can think of GATT like a high-level API for issuing ATT queries and commands.
You should definitely give the complete chapter 2.6 GATT Profile Hierarchy a read and then head over to 4 GATT Feature Requirements, especially chapters 4.4 Primary Service Discovery, 4.6 Charateristic discovery and *4.7 Characteristic Descriptor Discovery - regarding your question
But, where does that handle come from?
I want to know if my BLE 5 (low energy, not "typical"/core bluetooth) embedded system uses (preferably asymmetric) encryption, if encrypted at all.
I'm using this ble module that is communicating with an SOC. My SOC is capable of encryption but the FAE of the BLE module product couldn't come up with any useful information.
My program doesn't appear to have a bonding/pairing process, but I could be wrong since I did not take a closer look at the HAL layer program.
My question is, does BLE 5 require encryption?
If not, how do I find out if my connection is encrypted or not, using methods other than sniffers? For example are there any steps which must be gone through to facilitate encryption, in which case I should check if these steps were skipped or not? (If skipped then surely my communication is in plain texts).
ETA: The target BLE module is based on nrf52832, don't know what BLE stack/softdevice they are using. My soc is STM32WB55 series, using a rather comprehensive BLE stack that supports most functions of which name I couldn't recall for the moment.
BLE does not require encryption for a connection to be made.
At first, every BLE connection starts in Security Mode 1, Level 1 which does not use any encryption at all. Every message will be sent in cleartext. To increase the security two devices have to "pair". Security keys are exchange during the pairing process. There are multiple different pairing methods with different requirements. Have a look at this article for a starting point.
The pairing process is usually not started manually but automatically as soon as a device tries to access a secured characteristic. If you are using a phone to access such a characteristic you will be prompted with a pairing request popup. Based on your description I would assume that your connection is currently not encrypted.
To enable encryption on your SoC please have a look at the function aci_gatt_add_char. This document (direct download link) refers to this function on page 55 and shows that it takes Security_Permissions as an argument. The next page states the possible options as:
0x00: ATTR_PERMISSION_NONE
0x01: Need authentication to read
0x02: Need authorization to read
0x04: Link should be encrypted to read
0x08: Need authentication to write
0x10: Need authorization to write
0x20: Link should be encrypted for write
Eddystone-EID beacons transmit Ephemeral Identifiers which will be resolved by Google's Proximity Beacon API. This means one can not detect an Eddystone-EID beacon without an active internet connection. The approach is pretty new, so there is not much info on the internet.
Generation of ephemeral identifier and resolving mechanism is described in this paper provided by Google researchers. Here is the summary of the procedure: Eddystone-EID beacons encrypt the value from their embedded time counters with AES-128 using their key, while the key is unique identifier for each beacon. The result is the ephemeral id that's goning to be transmitted. Like every 512 secs, beacons recomputes their ephemeral ids. When an ephemeral id received by the receiver side, the resolver tries to find the key which provides correct decryption among known predefined keys. The found key corresponds to identification of the beacon.
I'm wondering whether it's possible to implement an offline resolving/decryption procedure according to given paper, that works with Eddystone-EIDs on the market. Instead of using a global resolver at the cloud, can we develop a local resolver which works with much less number of beacons?
If yes, is there any previous attempts or implementations etc?
What's your opinions on this topic?
Yes, it is theoretically possible to implement an EID resolver in Android or iOS code that does the calculations to see if an EID transmission comes from a known beacon transmitter.
The mobile device implementation would need to use compatible AES-128 encryption libraries and somehow store copies of the keys needed to do the resolution for each beacon.
When building a server-side resolver implementation for testing purposes, I considered building such a library. I also learned it is very tricky to get everything exactly right. Many AES libraries only provide partial functionality so are unusable.
It is also important to note that US export restrictions on encryption software will make putting apps that do this in the Apple AppStore and Google Play Store problematic.
I hear that the creator of the melissa worm was convicted based on the fact that the GUIDs generated could be linked back to a MAC Address of a computer he used.
How hard is it to do this? And what data do they need other than the GUID? Like the MAC Address itself or the time it was created?
That relates to a specific version 1 UUID included in the office document that contained the macro virus, this was becuse it came from UuidCreate/Sequential which did contain MAC info;
For security reasons, UuidCreate was
modified so that it no longer uses a
machine's MAC address to generate
UUIDs. UuidCreateSequential was
introduced to allow creation of UUIDs
using the MAC address of a machine's
Ethernet card.
It depends on how and by what OS/library that GUID was generated. As of Windows and its standard UuidCreate() function:
The UuidCreate function generates a
UUID that cannot be traced to the
ethernet address of the computer on
which it was generated. It also cannot
be associated with other UUIDs created
on the same computer.
Here: http://msdn.microsoft.com/en-us/library/aa379205(v=vs.85).aspx
Whether or not you can identify someone based on a UUID (GUID) depends entirely on the implementation.
RFC 4122 (the RFC for UUID) has three reference implementation (see http://www.ietf.org/rfc/rfc4122.txt) the first of which uses the MAC-address in the unique node identifier, but the other two uses random numbers instead. I've seen both in libraries and sometimes libraries have a switch between these methods, so the only way to know for sure is to read the documentation/source for the specific library you use for UUID/GUID generation.
Usually the MAC-address is hashed, so you could compare the original to the generated, but not decypher the original MAC-address only from knowing the UUID. So far I have only seen UUID generators that don't hash the timestamp so that is easier to find. There is a simple tool that can decode a UUID for you (see http://linux.die.net/man/1/uuid)