Caractéristiques
Service Association express
Le fournisseur Association express doit disposer du service GATT suivant.
Service | UUID |
---|---|
Service Association express | 0xFE2C |
Ce service doit présenter les caractéristiques suivantes.
Caractéristique du service d'association express | Chiffrée | Autorisations | UUID |
---|---|---|---|
Model ID | Non | Read | FE2C1233-8366-4814-8EB0-01DE32100BEA |
Association à clé | Non | Écrire et avertir | FE2C1234-8366-4814-8EB0-01DE32100BEA |
Clé d'accès | Non | Écrire et avertir | FE2C1235-8366-4814-8EB0-01DE32100BEA |
Clé de compte | Non | Écriture | FE2C1236-8366-4814-8EB0-01DE32100BEA |
Service d'information sur les appareils
Le fournisseur Association express doit également prendre en charge le service d'information sur les appareils.
Service | UUID |
---|---|
Service d'information sur les appareils | 0x180A |
Le chercheur d'association express utilise les caractéristiques suivantes.
Nom | Chiffrée | Autorisations | UUID |
---|---|---|---|
Version du micrologiciel | Non | Read | 0x2A26 |
Caractéristique: ID du modèle
Cette caractéristique permet au demandeur de lire l'ID de modèle si nécessaire, en dehors du moment où l'appareil fait de la publicité en mode visible. Il doit toujours renvoyer les données suivantes:
Octet | Type de données | Description | Valeur |
---|---|---|---|
0 – 2 | uint24 |
Model ID | Variable |
Caractéristique: association par clé
Cette caractéristique contrôle la procédure d'association basée sur des clés. Dans cette procédure, un certain niveau de confiance est établi en vérifiant que le demandeur et le fournisseur possèdent tous deux une clé pré-partagée. La clé est différente dans chaque cas:
Cas 1: la clé pré-partagée est basée sur la paire de clés publique/privée anti-spoofing et sur la paire de clés publique/privée du demandeur, qui sera modifiée à chaque tentative d'association.
- Le fournisseur est en mode association.
- Le demandeur vérifie que le fournisseur est en possession de la clé privée anti-spoofing.
Notez qu'en mode association, le fournisseur peut bien entendu également s'associer de la manière habituelle, par exemple pour l'associer à un appareil qui n'est pas compatible avec l'association express basée sur des clés.
Cas 2: la clé pré-partagée est l'une des clés de compte.
- Le Fournisseur n'est généralement pas en mode association. (Cependant, ce n'est pas une exigence : le fournisseur doit permettre l'utilisation d'une clé de compte même en mode association.)
- Le demandeur et le fournisseur vérifient chacun que l'autre est en possession de la clé de compte.
Étant donné que les deux cas sont extrêmement similaires, à l'exception de la clé pré-partagée utilisée, ils sont combinés dans la procédure.
Format des données
Reportez-vous à la procédure pour en savoir plus sur l'utilisation de chaque format.
Octet | Type de données | Description | Valeur | Obligatoire ? |
---|---|---|---|---|
0 à 15 | uint128 |
Requête chiffrée | Variable | Obligatoire |
16–79 | Clé publique | Variable | Facultatif |
Tableau 1.1:Requête chiffrée, écrite sur la caractéristique par le demandeur.
Octet | Type de données | Description | Valeur | Obligatoire ? |
---|---|---|---|---|
0 | uint8 |
Type de message | 0x00 = demande d'association basée sur des clés |
Obligatoire |
1 | uint8 |
Indicateurs
|
varie | Obligatoire |
2 – 7 | uint48 |
Soit:
|
varie | Obligatoire |
8 – 13 | uint48 |
Adresse BR/EDR du demandeur | varie | Présent uniquement si les bits 1 ou 3 sont définis |
n – 15 | Valeur aléatoire (sel) | varie | Obligatoire |
Tableau 1.2.1:Requête brute (type 0x00). Déchiffrement à partir de la requête chiffrée dans le tableau 1.1.
Octet | Type de données | Description | Valeur | Obligatoire ? |
---|---|---|---|---|
0 | uint8 |
Type de message | 0x10 = demande d'action |
Obligatoire |
1 | uint8 |
Indicateurs
|
varie | Obligatoire |
2 – 7 | uint48 |
Soit:
|
varie | Obligatoire |
8 | uint8 |
Envoyer un message au groupe | varie | Obligatoire si le bit 0 est défini sur "Flags" (Indicateurs) |
9 | uint8 |
Code du message | varie | Obligatoire si le bit 0 est défini sur "Flags" (Indicateurs) |
10 | uint8 |
Dépend des indicateurs:
|
varie | Obligatoire si les indicateurs (bit 0 ou 1) sont définis |
11 - n | Données supplémentaires | varie | Facultatif | |
n – 15 | Valeur aléatoire (sel) | varie | Obligatoire |
Tableau 1.2.2:Requête brute (type 0x10). Déchiffrement à partir de la requête chiffrée dans le tableau 1.1.
Octet | Type de données | Description | Valeur |
---|---|---|---|
0 | uint8 |
Type de message | 0x01 = réponse de l'association basée sur des clés |
1 – 6 | uint48 |
Adresse publique (BR/EDR) du fournisseur | varie |
7 – 15 | Valeur aléatoire (sel) | varie |
Tableau 1.3:Réponse brute. Chiffrer pour produire la réponse chiffrée décrite dans le Tableau 1.4
Octet | Type de données | Description | Valeur |
---|---|---|---|
0 à 15 | uint128 |
Réponse chiffrée | varie |
Tableau 1.4:Réponse chiffrée, envoyée par le fournisseur au demandeur via une notification.
Caractéristique: clé d'accès
Cette caractéristique est utilisée lors de la procédure d' association basée sur des clés.
Octet | Type de données | Description | Valeur |
---|---|---|---|
0 à 15 | uint128 |
Bloc de clés d'accès chiffrées | varie |
Tableau 2.1:Bloc de clé d'accès chiffrée. Consultez la procédure d'association basée sur des clés pour en savoir plus.
Octet | Type de données | Description | Valeur |
---|---|---|---|
0 | uint8 |
Type de message | Choisissez l'une des options suivantes:
|
1 – 3 | unit32 |
Clé d'accès à six chiffres | varie |
4 – 15 | Valeur aléatoire (sel) | varie |
Tableau 2.2:bloc de clé d'accès brut. Version déchiffrée du Tableau 2.1.
Caractéristique: clé de compte
Après l'association, le chercheur d'association express écrit une clé de compte sur le fournisseur d'association express.
Octet | Type de données | Description | Valeur |
---|---|---|---|
0 à 15 | uint128 |
Clé de compte (chiffrée) | varie |
Après avoir reçu une requête d'écriture, le fournisseur Association express doit procéder comme suit:
- Déchiffrez la clé de compte à l'aide de la clé secrète partagée générée à l'étape 4 de la procédure.
- Pour les fournisseurs nécessitant une liaison (courante) :
- Avant de procéder au déchiffrement, vérifiez que la clé secrète partagée a bien été utilisée pour déchiffrer la requête de clé d'accès de l'étape 12. Si cette étape n'a pas abouti à l'aide de ce secret, ignorez cette écriture et quittez.
- À ce stade, la clé secrète partagée (K dans la procédure) n'est plus utilisée pour cette association. Toutes les requêtes chiffrées avec cette clé sans redémarrer la procédure doivent être rejetées.
- Pour les fournisseurs nécessitant une liaison (courante) :
- Vérifiez que la valeur déchiffrée commence par
0x04
. Si ce n'est pas le cas, ignorez cette écriture et quittez. - Vérifiez si la liste des clés de compte persistante contient de l'espace pour la nouvelle valeur.
- Si ce n'est pas le cas, supprimez de la liste la valeur la moins récemment utilisée.
- Ajoutez la nouvelle valeur à la liste.
Les clés de compte figurant dans la liste sont utilisées lors de l'association par clé.
Caractéristique: révision du micrologiciel
Cette caractéristique permet au demandeur de lire la révision du micrologiciel du fournisseur si nécessaire. Il doit toujours renvoyer les données suivantes:
Octet | Type de données | Description | Valeur |
---|---|---|---|
0 - var | utf8s |
Code de révision du micrologiciel | varie |
Il doit être encapsulé dans une seule chaîne utf8, même si le fournisseur possède plusieurs micrologiciels (par exemple, trois micrologiciels pour l'écouteur gauche, l'écouteur droit et l'étui). Le fournisseur peut également renvoyer les chaînes spécifiques pour des cas particuliers:
status-updates: si le fournisseur met actuellement à jour le micrologiciel. Le fournisseur peut également renvoyer la version du micrologiciel mis en place.
status-abnormal: si le fournisseur présente un état anormal. Par exemple, il a rencontré un dysfonctionnement à cause de l'échec de la mise à jour du micrologiciel. Avec cette valeur, le moteur de recherche affiche un message indiquant à l'utilisateur qu'il doit maintenant être mis à jour.
Le fournisseur doit limiter l'accès à la caractéristique de révision du micrologiciel pour empêcher le suivi de l'appareil. Restrictions suggérées:
- les appareils associés doivent pouvoir y accéder à tout moment
- n'importe quel appareil doit y avoir accès lorsque le fournisseur est visible
Caractéristique: données supplémentaires
Ce service doit présenter les caractéristiques suivantes :
Caractéristique du service d'association express | Chiffrée | Autorisations | UUID |
---|---|---|---|
Données | Non | Écrire et avertir | FE2C1237-8366-4814-8EB0-01DE32100BEA |
Ancienne caractéristique du service Association express (objectif qui sera abandonné le 01/01/2021) | Chiffrée | Autorisations | UUID |
---|---|---|---|
Données | Non | Écrire et avertir | 0x1237 |
Avant d'écrire ou d'envoyer une notification à cette caractéristique, il doit y avoir un handshake via la caractéristique FE2C1234-8366-4814-8EB0-01DE32100BEA
pour disposer d'une clé secrète partagée. AES-CTR sera utilisé pour chiffrer les données qui transitent par cette caractéristique, dont l'algorithme est défini ci-dessous. Ce mode est plus sécurisé pour les données qui s'étendent au-delà d'un seul bloc de 16 octets. HMAC-SHA256 sera utilisé pour garantir l'intégrité des données, également définie ci-dessous.
Octet | Description | Valeur |
---|---|---|
0 - 7 | Huit premiers octets de HMAC-SHA256. | varie |
8 – 15 | Nonce, utilisé par le chiffrement AES-CTR. | varie |
16 – var | Données chiffrées. | varie |
Tableau 3.1:Paquet de données envoyé par le fournisseur au fournisseur via une notification ou envoyé par celui-ci au fournisseur via une écriture.
Octet | Type de données | Description | Valeur |
---|---|---|---|
0 - var | byte array |
Données | varie, décodez-la en fonction de l'ID de données du Tableau 1.2.2:
|
Tableau 3.2:données brutes. déchiffré à partir des données chiffrées : Tableau 3.1.
Lorsqu'une notification est demandée (par exemple, demande un nom personnalisé via le bit 2 du Tableau 1.2.1), le fournisseur d'Association express doit procéder comme suit:
- Générez 8 octets aléatoires de manière cryptographique pour le nonce.
Chiffrer les données à l'aide de l'algorithme AES-CTR, où chaque bloc de 16 octets est généré à l'aide de la méthode
encryptedBlock[i] = clearBlock[i] ^ AES(key, concat((uint8) i, 0x00000000000000, nonce))
où
- La clé AES est la clé secrète partagée de l'étape 4 de la procédure.
- clearBlock[i] est un bloc de 16 octets à partir de data[i * 16]. La taille du dernier bloc peut être inférieure à 16 octets.
Exécutez concat(encryptedBlock[0], encryptedBlock[1],...) pour créer les données chiffrées.
Générer le code HMAC-SHA256
sha256(concat((K ^ opad), sha256(concat((K ^ ipad), concat(nonce, encrypted_data)))))
où
- K est généré par concat(shared_secret, 48 octets ZERO), shared_secret provient de l'étape 4 de la procédure.
- opad correspond à une marge intérieure externe de 64 octets, composée d'octets répétés associés à la valeur
0x5C
. - ipad correspond à une marge intérieure de 64 octets, composée d'octets répétés associés à la valeur
0x36
.
Prenez les huit premiers octets de l'algorithme HMAC-SHA256 comme préfixe du paquet de données.
Après avoir reçu une requête d'écriture, le fournisseur Association express doit procéder comme suit:
- Vérifiez l'intégrité des données en vérifiant les huit premiers octets de HMAC-SHA256.
Déchiffrer les données chiffrées à l'aide d'AES-CTR, où chaque bloc est généré à l'aide de
clearBlock[i] = encryptedBlock[i] ^ AES(key, concat((uint8) i, 0x00000000000000, nonce))
où
- encryptionBlock[i] est un début de bloc de 16 octets à partir de encryption_data[i * 16]. La longueur du dernier bloc peut être inférieure à 16 octets.
- La clé AES est générée ou identifiée lors du handshake, par exemple :
- dans le flux de nommage 1, il provient d'ECDH et ne sera pas utilisé à nouveau pour cette association. Toutes les requêtes chiffrées avec cette clé sans redémarrer la procédure doivent être refusées.
- dans le flux de nommage 2, il s'agit de la clé de compte.
Exécutez concat(clearBlock[0], clearBlock[1],...) pour créer les données brutes.