xref: /btstack/tool/sm_random_check.py (revision 565fe80db1335fc811f93c03161901a9c5490478)
1*565fe80dSMatthias Ringwald#!/usr/bin/env python3
26b7b368aSMatthias Ringwald# BlueKitchen GmbH (c) 2014
36b7b368aSMatthias Ringwald
46b7b368aSMatthias Ringwald# Report SM Pairing Random packets with value zero
56b7b368aSMatthias Ringwald
66b7b368aSMatthias Ringwald
76b7b368aSMatthias Ringwaldimport re
86b7b368aSMatthias Ringwaldimport sys
96b7b368aSMatthias Ringwaldimport time
106b7b368aSMatthias Ringwaldimport datetime
116b7b368aSMatthias Ringwald
126b7b368aSMatthias Ringwaldpacket_types = [ "CMD =>", "EVT <=", "ACL =>", "ACL <="]
136b7b368aSMatthias Ringwald
146b7b368aSMatthias Ringwalddef read_net_32(f):
156b7b368aSMatthias Ringwald    a = f.read(1)
166b7b368aSMatthias Ringwald    if a == '':
176b7b368aSMatthias Ringwald    	return -1
186b7b368aSMatthias Ringwald    b = f.read(1)
196b7b368aSMatthias Ringwald    if b == '':
206b7b368aSMatthias Ringwald    	return -1
216b7b368aSMatthias Ringwald    c = f.read(1)
226b7b368aSMatthias Ringwald    if c == '':
236b7b368aSMatthias Ringwald    	return -1
246b7b368aSMatthias Ringwald    d = f.read(1)
256b7b368aSMatthias Ringwald    if d == '':
266b7b368aSMatthias Ringwald    	return -1
276b7b368aSMatthias Ringwald    return ord(a) << 24 | ord(b) << 16 | ord(c) << 8 | ord(d)
286b7b368aSMatthias Ringwald
296b7b368aSMatthias Ringwalddef as_hex(data):
306b7b368aSMatthias Ringwald	str_list = []
316b7b368aSMatthias Ringwald	for byte in data:
326b7b368aSMatthias Ringwald	    str_list.append("{0:02x} ".format(ord(byte)))
336b7b368aSMatthias Ringwald	return ''.join(str_list)
346b7b368aSMatthias Ringwald
356b7b368aSMatthias Ringwalddef check_file(infile):
366b7b368aSMatthias Ringwald	with open (infile, 'rb') as fin:
376b7b368aSMatthias Ringwald		pos = 0
386b7b368aSMatthias Ringwald		warning = True
396b7b368aSMatthias Ringwald		try:
406b7b368aSMatthias Ringwald			while True:
416b7b368aSMatthias Ringwald				len     = read_net_32(fin)
426b7b368aSMatthias Ringwald				if len < 0:
436b7b368aSMatthias Ringwald					break
446b7b368aSMatthias Ringwald				ts_sec  = read_net_32(fin)
456b7b368aSMatthias Ringwald				ts_usec = read_net_32(fin)
466b7b368aSMatthias Ringwald				type    = ord(fin.read(1))
476b7b368aSMatthias Ringwald				packet_len = len - 9;
486b7b368aSMatthias Ringwald				if (packet_len > 66000):
496b7b368aSMatthias Ringwald					print ("Error parsing pklg at offset %u (%x)." % (pos, pos))
506b7b368aSMatthias Ringwald					break
516b7b368aSMatthias Ringwald				packet  = fin.read(packet_len)
526b7b368aSMatthias Ringwald				pos     = pos + 4 + len
536b7b368aSMatthias Ringwald				time    = "[%s.%03u]" % (datetime.datetime.fromtimestamp(ts_sec).strftime("%Y-%m-%d %H:%M:%S"), ts_usec / 1000)
546b7b368aSMatthias Ringwald				if type not in [0x02, 0x03]:
556b7b368aSMatthias Ringwald					continue
566b7b368aSMatthias Ringwald				packet_boundary_flags = (ord(packet[1]) >> 4) & 3
576b7b368aSMatthias Ringwald				if packet_boundary_flags not in [0x00, 0x02]:
586b7b368aSMatthias Ringwald					continue
596b7b368aSMatthias Ringwald				channel = ord(packet[6]) | (ord(packet[7]) << 8)
606b7b368aSMatthias Ringwald				if channel != 0x06:
616b7b368aSMatthias Ringwald					continue
626b7b368aSMatthias Ringwald				smp_command = ord(packet[8])
636b7b368aSMatthias Ringwald				if smp_command != 4:
646b7b368aSMatthias Ringwald					continue
656b7b368aSMatthias Ringwald				random = [ ord(i) for i in packet[9:25] ]
666b7b368aSMatthias Ringwald				num_zeros = random.count(0)
676b7b368aSMatthias Ringwald				if num_zeros != 16:
686b7b368aSMatthias Ringwald					continue
696b7b368aSMatthias Ringwald				if warning:
706b7b368aSMatthias Ringwald					print("%s contains SM Pairing Random command with Zeroes:" % infile)
716b7b368aSMatthias Ringwald					warning = False
72*565fe80dSMatthias Ringwald				print (time, packet_types[type], as_hex(packet))
736b7b368aSMatthias Ringwald
746b7b368aSMatthias Ringwald			if not warning:
756b7b368aSMatthias Ringwald				print("")
766b7b368aSMatthias Ringwald
776b7b368aSMatthias Ringwald		except TypeError:
786b7b368aSMatthias Ringwald			print ("Error parsing pklg at offset %u (%x)." % (pos, pos))
796b7b368aSMatthias Ringwald
806b7b368aSMatthias Ringwaldif len(sys.argv) == 1:
81*565fe80dSMatthias Ringwald	print ('Usage: ' + sys.argv[0] + ' hci_dump.pklg')
826b7b368aSMatthias Ringwald	exit(0)
836b7b368aSMatthias Ringwald
846b7b368aSMatthias Ringwaldfor infile in sys.argv[2:]:
856b7b368aSMatthias Ringwald	check_file(infile)
866b7b368aSMatthias Ringwald
876b7b368aSMatthias Ringwaldinfile = sys.argv[1]
886b7b368aSMatthias Ringwald
89