sm_random_check.py 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #!/usr/bin/env python3
  2. # BlueKitchen GmbH (c) 2014
  3. # Report SM Pairing Random packets with value zero
  4. import re
  5. import sys
  6. import time
  7. import datetime
  8. packet_types = [ "CMD =>", "EVT <=", "ACL =>", "ACL <="]
  9. def read_net_32(f):
  10. a = f.read(1)
  11. if a == '':
  12. return -1
  13. b = f.read(1)
  14. if b == '':
  15. return -1
  16. c = f.read(1)
  17. if c == '':
  18. return -1
  19. d = f.read(1)
  20. if d == '':
  21. return -1
  22. return ord(a) << 24 | ord(b) << 16 | ord(c) << 8 | ord(d)
  23. def as_hex(data):
  24. str_list = []
  25. for byte in data:
  26. str_list.append("{0:02x} ".format(ord(byte)))
  27. return ''.join(str_list)
  28. def check_file(infile):
  29. with open (infile, 'rb') as fin:
  30. pos = 0
  31. warning = True
  32. try:
  33. while True:
  34. len = read_net_32(fin)
  35. if len < 0:
  36. break
  37. ts_sec = read_net_32(fin)
  38. ts_usec = read_net_32(fin)
  39. type = ord(fin.read(1))
  40. packet_len = len - 9;
  41. if (packet_len > 66000):
  42. print ("Error parsing pklg at offset %u (%x)." % (pos, pos))
  43. break
  44. packet = fin.read(packet_len)
  45. pos = pos + 4 + len
  46. time = "[%s.%03u]" % (datetime.datetime.fromtimestamp(ts_sec).strftime("%Y-%m-%d %H:%M:%S"), ts_usec / 1000)
  47. if type not in [0x02, 0x03]:
  48. continue
  49. packet_boundary_flags = (ord(packet[1]) >> 4) & 3
  50. if packet_boundary_flags not in [0x00, 0x02]:
  51. continue
  52. channel = ord(packet[6]) | (ord(packet[7]) << 8)
  53. if channel != 0x06:
  54. continue
  55. smp_command = ord(packet[8])
  56. if smp_command != 4:
  57. continue
  58. random = [ ord(i) for i in packet[9:25] ]
  59. num_zeros = random.count(0)
  60. if num_zeros != 16:
  61. continue
  62. if warning:
  63. print("%s contains SM Pairing Random command with Zeroes:" % infile)
  64. warning = False
  65. print (time, packet_types[type], as_hex(packet))
  66. if not warning:
  67. print("")
  68. except TypeError:
  69. print ("Error parsing pklg at offset %u (%x)." % (pos, pos))
  70. if len(sys.argv) == 1:
  71. print ('Usage: ' + sys.argv[0] + ' hci_dump.pklg')
  72. exit(0)
  73. for infile in sys.argv[2:]:
  74. check_file(infile)
  75. infile = sys.argv[1]