Coverage for src / bluetooth_sig / gatt / characteristics / encrypted_data_key_material.py: 100%

18 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-04-03 16:41 +0000

1"""Encrypted Data Key Material characteristic (0x2B88). 

2 

3Session key (16 bytes) + initialisation vector (8 bytes) for encrypted data. 

4 

5References: 

6 Bluetooth SIG Encrypted Advertising Data specification 

7""" 

8 

9from __future__ import annotations 

10 

11import msgspec 

12 

13from ..context import CharacteristicContext 

14from .base import BaseCharacteristic 

15 

16 

17class EncryptedDataKeyMaterialData(msgspec.Struct, frozen=True, kw_only=True): 

18 """Parsed data from Encrypted Data Key Material. 

19 

20 Attributes: 

21 session_key: 16-byte session key. 

22 iv: 8-byte initialisation vector. 

23 

24 """ 

25 

26 session_key: bytes 

27 iv: bytes 

28 

29 

30class EncryptedDataKeyMaterialCharacteristic(BaseCharacteristic[EncryptedDataKeyMaterialData]): 

31 """Encrypted Data Key Material characteristic (0x2B88). 

32 

33 org.bluetooth.characteristic.encrypted_data_key_material 

34 

35 Contains the session key and initialisation vector for encrypted 

36 advertising data. 

37 """ 

38 

39 expected_length = 24 

40 

41 def _decode_value( 

42 self, data: bytearray, ctx: CharacteristicContext | None = None, *, validate: bool = True 

43 ) -> EncryptedDataKeyMaterialData: 

44 """Parse Encrypted Data Key Material. 

45 

46 Format: Session Key (16 bytes) + IV (8 bytes). 

47 """ 

48 session_key = bytes(data[:16]) 

49 iv = bytes(data[16:24]) 

50 

51 return EncryptedDataKeyMaterialData( 

52 session_key=session_key, 

53 iv=iv, 

54 ) 

55 

56 def _encode_value(self, data: EncryptedDataKeyMaterialData) -> bytearray: 

57 """Encode Encrypted Data Key Material.""" 

58 result = bytearray() 

59 result.extend(data.session_key[:16].ljust(16, b"\x00")) 

60 result.extend(data.iv[:8].ljust(8, b"\x00")) 

61 return result