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