@jpthibault
I built such smart card extension which works very well. I am able to communicate (RX/TX) with the smart card using standard 20-pin cable and capture the power traces. The quality of the power traces is perfect. I didn’t expect to see high quality traces using just a prototype.
The things are interested to me are:
- UART triggering and capture the traces.
- UART triggering and measuring the interval between smart card request and response.
The first thing is conceptually more or less clean but the second thing is not so obvious.
Suppose, I send the message to the card [ SC message: XX XX XX XX XX 55 AA] [ SC processes the message ] [ SC replies: 90 00 ]
The goal is to measure this interval [ SC processes the message ]
Should below setup work? Briefly, the idea is to capture the last byte (0xAA) of the payload echo from the Husky TX line to trigger the UART trigger on the Husky RX line so that to run the logic analyzer to capture activity on the RX line. The main goal is to detect the start-bit of expected answer 0x90 and then calculate the number of Husky ticks between the trigger and the start-bit.
For unclear reasons, the UART trigger doesn’t fire on getting 0xAA. Maybe this configuration affect UART triggering? target.ser.cwlite_usart.init(baud=19200, stopbits=2, parity=“even”)
scope.io.tio1 = "serial_tx"
scope.io.tio2 = "serial_rx"
target.ser.cwlite_usart.init(baud=19200, stopbits=2, parity="even")
scope.clock.adc_src = "clkgen_x1"
scope.io.target_pwr = True
scope.clock.reset_adc()
scope.trigger.module = 'UART'
scope.trigger.triggers = 'tio2'
scope.UARTTrigger.enabled = True
scope.UARTTrigger.set_pattern_match(0, [0xAA])
scope.UARTTrigger.trigger_source = 0
scope.LA.enabled = True
scope.LA.capture_group = 'CW 20-pin'
scope.LA.clk_source = 'target'
scope.LA.oversampling_factor = 1
scope.LA.capture_depth = 1000
scope.LA.trigger_source = "capture"
def run_timing_analysis():
payload = [0xXX, 0xXX, 0xXX, 0x55, 0xAA]
apdu = [0xXX, 0xXX, 0xXX, 0xXX, len(payload)] + payload + [0xXX]
scope.LA.arm()
scope.arm()
target.ser.flush()
print(f"TX: {' '.join(f'{b:02X}' for b in apdu)}")
target.ser.write(apdu)
ret = scope.capture()
if ret:
print("[-] Error: trigger timeout")
return
raw_la = scope.LA.read_capture_data()
io_rx = scope.LA.extract(raw_la, 1)
try:
# processing
except IndexError:
# processing
…forgot to mention that the smart card implements IO as an open drain. So I used the BAT42 diode to connect Husky’s UART and IO SC. Cathode is connected to Husky TX, anode is connected to the Husky RX, IO SC and pulled up via a resistor 4.7 kOm to VCC.