Christina Quast | 74876d2 | 2015-03-13 23:45:30 +0100 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
| 2 | |
| 3 | import usb.core |
| 4 | import usb.util |
| 5 | import sys |
| 6 | |
Christina Quast | 5a691a3 | 2015-03-18 18:45:14 +0100 | [diff] [blame] | 7 | import time # needed for sleep() |
| 8 | import traceback # Exception timeout |
| 9 | |
| 10 | # Sniffed Phone to SIM card communication: |
| 11 | # phone < sim : ATR |
| 12 | # phone > sim : A0 A4 00 00 02 (Select File) |
| 13 | # phone < sim : A4 (INS repeated) |
| 14 | # phone > sim : 7F 02 (= ??) |
| 15 | # phone < sim : 9F 16 (9F: success, can deliver 0x16 (=22) byte) |
| 16 | # phone > sim : ?? (A0 C0 00 00 16) |
| 17 | # phone < sim : C0 (INS repeated) |
| 18 | # phone < sim : 00 00 00 00 7F 20 02 00 00 00 00 00 09 91 00 17 04 00 83 8A (data of length 22) |
| 19 | # phone < sim : 90 00 (OK, everything went fine) |
| 20 | # phone ? sim : 00 (??) |
| 21 | |
Christina Quast | 74876d2 | 2015-03-13 23:45:30 +0100 | [diff] [blame] | 22 | # SuperSIM ATR |
Christina Quast | 4bcc023 | 2015-03-24 21:59:32 +0100 | [diff] [blame] | 23 | # atr= [0x3B, 0x9A, 0x94, 0x00, 0x92, 0x02, 0x75, 0x93, 0x11, 0x00, 0x01, 0x02, 0x02, 0x19] |
| 24 | |
| 25 | # Faster sysmocom SIM |
| 26 | #atr = [0x3B, 0x99, 0x18, 0x00, 0x11, 0x88, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x60] |
| 27 | atr = [0x3B, 0x99, 0x11, 0x00, 0x11, 0x88, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x60] |
| 28 | |
Christina Quast | 69734e9 | 2015-03-15 16:09:55 +0100 | [diff] [blame] | 29 | RESP_OK = [0x60, 0x00] |
Christina Quast | 74876d2 | 2015-03-13 23:45:30 +0100 | [diff] [blame] | 30 | |
| 31 | def find_dev(): |
| 32 | dev = usb.core.find(idVendor=0x03eb, idProduct=0x6004) |
| 33 | if dev is None: |
| 34 | raise ValueError("Device not found") |
| 35 | else: |
| 36 | print("Found device") |
| 37 | return dev |
| 38 | |
Christina Quast | 4e4682c | 2015-03-18 18:48:57 +0100 | [diff] [blame] | 39 | WAIT_RST = 0 |
| 40 | WAIT_CMD = 1 |
| 41 | |
| 42 | def handle_wait_rst(dev): |
Christina Quast | 69734e9 | 2015-03-15 16:09:55 +0100 | [diff] [blame] | 43 | # ATR handling |
Christina Quast | 4bcc023 | 2015-03-24 21:59:32 +0100 | [diff] [blame] | 44 | print("Handle ATR") |
Christina Quast | 1dd996a | 2015-04-03 11:42:29 +0200 | [diff] [blame] | 45 | arr = dev.read(PHONE_INT, 64, 300) # Notification endpoint |
Christina Quast | 5134fb6 | 2015-03-22 19:09:02 +0100 | [diff] [blame] | 46 | # print("arr: ", arr) |
Christina Quast | 4e4682c | 2015-03-18 18:48:57 +0100 | [diff] [blame] | 47 | c=arr.pop() |
Christina Quast | 5134fb6 | 2015-03-22 19:09:02 +0100 | [diff] [blame] | 48 | # print(c) |
Christina Quast | 74876d2 | 2015-03-13 23:45:30 +0100 | [diff] [blame] | 49 | |
Christina Quast | 4e4682c | 2015-03-18 18:48:57 +0100 | [diff] [blame] | 50 | if c == ord('R'): |
| 51 | # We received a Reset, so we send ATR |
Christina Quast | 1dd996a | 2015-04-03 11:42:29 +0200 | [diff] [blame] | 52 | written = dev.write(PHONE_DATAOUT, atr, 1000) |
Christina Quast | 4bcc023 | 2015-03-24 21:59:32 +0100 | [diff] [blame] | 53 | print("Written ATR of size: ") |
| 54 | print(written) |
Christina Quast | 4e4682c | 2015-03-18 18:48:57 +0100 | [diff] [blame] | 55 | state = WAIT_CMD; |
| 56 | return state |
Christina Quast | 74876d2 | 2015-03-13 23:45:30 +0100 | [diff] [blame] | 57 | |
Christina Quast | 4e4682c | 2015-03-18 18:48:57 +0100 | [diff] [blame] | 58 | def handle_wait_cmd(dev): |
Christina Quast | 69734e9 | 2015-03-15 16:09:55 +0100 | [diff] [blame] | 59 | # Read phone request |
Christina Quast | 4e4682c | 2015-03-18 18:48:57 +0100 | [diff] [blame] | 60 | print("Wait cmd") |
Christina Quast | 1dd996a | 2015-04-03 11:42:29 +0200 | [diff] [blame] | 61 | cmd = dev.read(PHONE_DATAIN, 64, 1000) |
Christina Quast | 4e4682c | 2015-03-18 18:48:57 +0100 | [diff] [blame] | 62 | print("Received request!: ") |
| 63 | print("".join("%02x " % b for b in cmd)) |
Christina Quast | 69734e9 | 2015-03-15 16:09:55 +0100 | [diff] [blame] | 64 | |
Christina Quast | 4bcc023 | 2015-03-24 21:59:32 +0100 | [diff] [blame] | 65 | return send_response(dev, cmd); |
Christina Quast | 69734e9 | 2015-03-15 16:09:55 +0100 | [diff] [blame] | 66 | |
Christina Quast | 4e4682c | 2015-03-18 18:48:57 +0100 | [diff] [blame] | 67 | handle_msg_funcs = { WAIT_RST: handle_wait_rst, |
| 68 | WAIT_CMD: handle_wait_cmd } |
| 69 | |
| 70 | def handle_phone_request(dev, state): |
Christina Quast | 4bcc023 | 2015-03-24 21:59:32 +0100 | [diff] [blame] | 71 | if state == WAIT_CMD: |
| 72 | try: |
| 73 | state = handle_msg_funcs[WAIT_RST](dev) |
| 74 | except usb.USBError as e: |
Christina Quast | b65b881 | 2015-04-04 10:51:37 +0200 | [diff] [blame] | 75 | print(e) |
Christina Quast | 4e4682c | 2015-03-18 18:48:57 +0100 | [diff] [blame] | 76 | state = handle_msg_funcs[state](dev) |
| 77 | return state |
| 78 | |
| 79 | INS = 1 |
Christina Quast | 1dd996a | 2015-04-03 11:42:29 +0200 | [diff] [blame] | 80 | CNT = 4 |
| 81 | |
Christina Quast | b65b881 | 2015-04-04 10:51:37 +0200 | [diff] [blame] | 82 | PHONE_DATAOUT = 0x04 |
| 83 | PHONE_DATAIN = 0x85 |
| 84 | PHONE_INT = 0x86 |
Christina Quast | 4e4682c | 2015-03-18 18:48:57 +0100 | [diff] [blame] | 85 | |
| 86 | def send_response(dev, cmd): |
Christina Quast | 4e4682c | 2015-03-18 18:48:57 +0100 | [diff] [blame] | 87 | # FIXME: We could get data of length 5 as well! Implement another distinct criteria! |
Christina Quast | 4bcc023 | 2015-03-24 21:59:32 +0100 | [diff] [blame] | 88 | state = WAIT_CMD |
Christina Quast | 4e4682c | 2015-03-18 18:48:57 +0100 | [diff] [blame] | 89 | if len(cmd) == 5: # Received cmd from phone |
| 90 | if cmd[INS] == 0xA4: |
| 91 | resp = [cmd[INS]] # Respond with INS byte |
Christina Quast | 4e4682c | 2015-03-18 18:48:57 +0100 | [diff] [blame] | 92 | elif cmd[INS] == 0xC0: |
Christina Quast | e5342b3 | 2015-03-19 19:29:49 +0100 | [diff] [blame] | 93 | data = [0x00, 0x00, 0x00, 0x00, |
| 94 | 0x7F, 0x20, 0x02, 0x00, |
| 95 | 0x00, 0x00, 0x00, 0x00, |
| 96 | 0x09, 0x91, 0x00, 0x17, |
| 97 | 0x04, 0x00, 0x83, 0x8A, |
| 98 | 0x83, 0x8A] |
Christina Quast | 4e4682c | 2015-03-18 18:48:57 +0100 | [diff] [blame] | 99 | SW = [0x90, 0x00] |
Christina Quast | 5134fb6 | 2015-03-22 19:09:02 +0100 | [diff] [blame] | 100 | resp = [cmd[INS]] + data + SW # Respond with INS byte |
Christina Quast | 97922ba | 2015-04-03 11:46:34 +0200 | [diff] [blame] | 101 | #state = WAIT_RST |
Christina Quast | e5342b3 | 2015-03-19 19:29:49 +0100 | [diff] [blame] | 102 | else: |
| 103 | print("Unknown cmd") |
| 104 | resp = [0x60, 0x00] |
| 105 | elif len(cmd) == 2: |
| 106 | resp = [0x9F, 0x16] |
Christina Quast | 4e4682c | 2015-03-18 18:48:57 +0100 | [diff] [blame] | 107 | else: |
Christina Quast | e5342b3 | 2015-03-19 19:29:49 +0100 | [diff] [blame] | 108 | resp = [0x60, 0x00] |
Christina Quast | 4e4682c | 2015-03-18 18:48:57 +0100 | [diff] [blame] | 109 | |
Christina Quast | 1dd996a | 2015-04-03 11:42:29 +0200 | [diff] [blame] | 110 | written = dev.write(PHONE_DATAOUT, resp, 10000); |
Christina Quast | e5342b3 | 2015-03-19 19:29:49 +0100 | [diff] [blame] | 111 | if written > 0: |
| 112 | print("Bytes written:") |
| 113 | print(written) |
Christina Quast | 69734e9 | 2015-03-15 16:09:55 +0100 | [diff] [blame] | 114 | |
Christina Quast | 5134fb6 | 2015-03-22 19:09:02 +0100 | [diff] [blame] | 115 | print("Cmd, resp: ") |
| 116 | print("".join("%02x " % b for b in cmd)) |
| 117 | print("".join("%02x " % b for b in resp)) |
Christina Quast | 4bcc023 | 2015-03-24 21:59:32 +0100 | [diff] [blame] | 118 | |
| 119 | return state |
Christina Quast | 5134fb6 | 2015-03-22 19:09:02 +0100 | [diff] [blame] | 120 | |
Christina Quast | 69734e9 | 2015-03-15 16:09:55 +0100 | [diff] [blame] | 121 | def emulate_sim(): |
| 122 | dev = find_dev() |
Christina Quast | 4e4682c | 2015-03-18 18:48:57 +0100 | [diff] [blame] | 123 | state = WAIT_RST; |
Christina Quast | 69734e9 | 2015-03-15 16:09:55 +0100 | [diff] [blame] | 124 | |
| 125 | while True: |
| 126 | try: |
Christina Quast | 4e4682c | 2015-03-18 18:48:57 +0100 | [diff] [blame] | 127 | state = handle_phone_request(dev, state) |
Christina Quast | 69734e9 | 2015-03-15 16:09:55 +0100 | [diff] [blame] | 128 | |
Christina Quast | 4e4682c | 2015-03-18 18:48:57 +0100 | [diff] [blame] | 129 | except usb.USBError as e: |
Christina Quast | 5134fb6 | 2015-03-22 19:09:02 +0100 | [diff] [blame] | 130 | # print e |
| 131 | pass |