Project

General

Profile

Actions

Feature #5600

open

SIMtrace2 fails to emulate EMV cards

Added by boggy123 over 1 year ago. Updated over 1 year ago.

Status:
Feedback
Priority:
Normal
Assignee:
Category:
-
Target version:
Start date:
07/03/2022
Due date:
% Done:

0%

Spec Reference:

Description

Greetings!

I acquired a SIMtrace2 with the hopes of using it for my undergrad dissertation. Many thanks for the hardware and software. I want to relay an EMV ISO-7816 card and observe the communication. I've set the simtrace2-cardem-pcsc to use data found in a virtual smart card interface. When I attempt to make a payment(Ingenico 5000/Square reader) it fails as the command that I have to return to the card fails to transmit. There are traces in the log for an 'Unknown APDU case 0'.

My assumption is that the command received by the emulator(GPO - Get Processing Options) is not interpreted correctly.
Command in question: DLGLOBAL INFO => DATA: flags=0x01 (HDR ), 80 a8 00 00 02. I can only assume that 02 is the length of data that should follow but no data is available.

firmware: latest -- simtrace-cardem-dfu-0.8.1.34-e450.bin
Terminal output: https://pastebin.com/raw/tYUGSc6k

Many thanks


Files

packetss.pcapng packetss.pcapng 1.32 KB boggy123, 07/03/2022 07:13 PM
GPO-FORMAT-PAGE-59.png View GPO-FORMAT-PAGE-59.png 53.6 KB https://www.emvco.com/wp-content/uploads/2017/04/EMV_v4.3_Book_3_Application_Specification_20120607062110791.pdf boggy123, 07/03/2022 07:15 PM
funny.jpg View funny.jpg 18.9 KB anton123, 12/14/2022 12:15 PM
Actions #1

Updated by fixeria over 1 year ago

Hello,

as far as I can see from your pastebin, simtrace2-cardem-pcsc basically crashes due to an integer overflow.

https://gerrit.osmocom.org/c/simtrace2/+/28513 host/cardem: fix integer overflow in process_do_rx_da()

This patch is not going to solve your problem, but should fix the segfault.

Actions #2

Updated by laforge over 1 year ago

  • Tracker changed from Bug to Feature
  • Status changed from New to Feedback
  • Assignee set to boggy123

re-classifing this as a "feature" as it is not something we claim to support. The only bug is that it segfaults right now.

First of all, I would assume that normally EMV cards use T=1, while SIMtrace (both for tracing and for cardem) only supports T=0.

In your case, surprisingly, they seem to use T=0 (maybe it's a fall-back?)

adding the paste here in-line:

boggy@boggy-HP-Laptop-14-dk0xxx:~/Work/simtrace2/host/src$ sudo ./simtrace2-cardem-pcsc --usb-vendor 1d50 --usb-product 60e3 --usb-path 1-1.1 --usb-config 1 --pcsc-reader-num 1 --skip-atr
simtrace2-cardem-pcsc - Using PC/SC reader as SIM
(C) 2010-2022, Harald Welte <laforge@gnumonks.org>
(C) 2018, sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.de>

DLINP NOTICE [0] <= osmo_st2_cardem_request_config(features=00000001)
DLINP NOTICE [0] <= osmo_st2_cardem_request_card_insert(inserted=1)
DLINP NOTICE [0] <= _modem_sim_select(remote_sim=1)
DLINP NOTICE [0] <= _modem_reset(asserted=2, pulse_ms=300)
Entering main loop
DLGLOBAL NOTICE => IRQ STATUS: flags=0x0, fi=1, di=1, wi=10 wtime=9600 ()
DLGLOBAL NOTICE => IRQ STATUS: flags=0x10, fi=1, di=1, wi=10 wtime=9600 (RESET )
DLGLOBAL NOTICE => IRQ STATUS: flags=0x11, fi=1, di=1, wi=10 wtime=9600 (RESET VCC )
DLGLOBAL NOTICE => IRQ STATUS: flags=0x13, fi=1, di=1, wi=10 wtime=9600 (RESET VCC CLK )
DLGLOBAL NOTICE => IRQ STATUS: flags=0x12, fi=1, di=1, wi=10 wtime=9600 (RESET CLK )
DLGLOBAL NOTICE => IRQ STATUS: flags=0x10, fi=1, di=1, wi=10 wtime=9600 (RESET )
DLGLOBAL NOTICE => IRQ STATUS: flags=0x11, fi=1, di=1, wi=10 wtime=9600 (RESET VCC )
DLGLOBAL NOTICE => IRQ STATUS: flags=0x13, fi=1, di=1, wi=10 wtime=9600 (RESET VCC CLK )
DLGLOBAL NOTICE => IRQ STATUS: flags=0x3, fi=1, di=1, wi=10 wtime=9600 (VCC CLK )
DLGLOBAL NOTICE Warm Resetting card in reader...
DLGLOBAL INFO => DATA: flags=0x01 (HDR ), 00 a4 04 00 0e 
 DLINP DEBUG [0] <= osmo_st2_cardem_request_pb_and_rx(pb=a4, le=14)
DLGLOBAL NOTICE => IRQ STATUS: flags=0x13, fi=1, di=1, wi=10 wtime=9600 (RESET VCC CLK )
DLGLOBAL NOTICE => IRQ STATUS: flags=0x3, fi=1, di=1, wi=10 wtime=9600 (VCC CLK )
DLGLOBAL NOTICE Warm Resetting card in reader...
DLGLOBAL INFO => DATA: flags=0x02 (FINAL ), 31 50 41 59 2e 53 59 53 2e 44 44 46 30 31 
 DLINP DEBUG [0] <= osmo_st2_cardem_request_sw_tx(sw=611c)
DLGLOBAL INFO => DATA: flags=0x01 (HDR ), 00 c0 00 00 1c 
 DLINP DEBUG [0] <= osmo_st2_cardem_request_pb_and_tx(pb=c0, tx=6f 1a 84 0e 31 50 41 59 2e 53 59 53 2e 44 44 46 30 31 a5 08 88 01 01 5f 2d 02 65 6e , len=28)
DLINP DEBUG [0] <= osmo_st2_cardem_request_sw_tx(sw=9000)
DLGLOBAL INFO => DATA: flags=0x01 (HDR ), 00 b2 01 0c 00 
 DLINP DEBUG [0] <= osmo_st2_cardem_request_sw_tx(sw=6c59)
DLGLOBAL INFO => DATA: flags=0x01 (HDR ), 00 b2 01 0c 59 
 DLINP DEBUG [0] <= osmo_st2_cardem_request_pb_and_tx(pb=b2, tx=70 57 61 25 4f 07 a0 00 00 00 03 10 10 50 0a 56 69 73 61 20 44 65 62 69 74 87 01 02 73 0b 9f 0a 08 00 01 05 01 00 00 00 00 61 16 4f 07 a0 00 00 00 29 10 10 50 08 4c 49 4e 4b 20 41 54 4d 87 01 01 61 16 4f 07 a0 00 00 00 03 80 02 50 08 42 41 52 43 4c 41 59 53 87 01 00 , len=89)
DLINP DEBUG [0] <= osmo_st2_cardem_request_sw_tx(sw=9000)
DLGLOBAL INFO => DATA: flags=0x01 (HDR ), 00 b2 02 0c 00 
 DLINP DEBUG [0] <= osmo_st2_cardem_request_sw_tx(sw=6a83)
DLGLOBAL INFO => DATA: flags=0x01 (HDR ), 00 a4 04 00 07 
 DLINP DEBUG [0] <= osmo_st2_cardem_request_pb_and_rx(pb=a4, le=7)
DLGLOBAL INFO => DATA: flags=0x02 (FINAL ), a0 00 00 00 03 10 10 
 DLINP DEBUG [0] <= osmo_st2_cardem_request_sw_tx(sw=612f)
DLGLOBAL INFO => DATA: flags=0x01 (HDR ), 00 c0 00 00 2f 
 DLINP DEBUG [0] <= osmo_st2_cardem_request_pb_and_tx(pb=c0, tx=6f 2d 84 07 a0 00 00 00 03 10 10 a5 22 50 0a 56 69 73 61 20 44 65 62 69 74 87 01 02 5f 2d 02 65 6e bf 0c 0b 9f 0a 08 00 01 05 01 00 00 00 00 , len=47)
DLINP DEBUG [0] <= osmo_st2_cardem_request_sw_tx(sw=9000)
DLGLOBAL INFO => DATA: flags=0x01 (HDR ), 80 a8 00 00 02 
 DLGLOBAL ERROR Unknown APDU case 0
DLINP DEBUG [0] <= osmo_st2_cardem_request_pb_and_tx(pb=a8, tx=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 11 05 00 00 00 00 00 00 e0 c7 88 7a ef 7f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f0 a0 76 30 ef 7f 00 00 a8 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 76 d2 72 30 ef 7f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 04 06 00 00 00 00 00 28 a9 7a cf d2 55 00 00 4e a9 7a cf d2 55 00 00 48 a9 7a cf d2 55 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 msgb(0x55d2cf7aa8a0): Not enough tailroom msgb_put (allocated 920, head at 0, len 7, tailroom 1017 < want tailroom 65534)
backtrace() returned 19 addresses
/usr/local/lib/libosmocore.so.19(osmo_generate_backtrace+0x1c) [0x7fef3070c238]
/usr/local/lib/libosmocore.so.19(+0x2ce8c) [0x7fef3070be8c]
/usr/local/lib/libosmocore.so.19(osmo_panic+0xe0) [0x7fef3070bf71]
/home/boggy/Work/simtrace2/host/lib/.libs/libosmo-simtrace2.so.1(+0x35cc) [0x7fef307695cc]
/home/boggy/Work/simtrace2/host/src/.libs/simtrace2-cardem-pcsc(+0x3c6e) [0x55d2cea98c6e]
/lib/x86_64-linux-gnu/libusb-1.0.so.0(+0xe5f5) [0x7fef306be5f5]
/lib/x86_64-linux-gnu/libusb-1.0.so.0(+0xf104) [0x7fef306bf104]
/lib/x86_64-linux-gnu/libusb-1.0.so.0(+0xf661) [0x7fef306bf661]
/lib/x86_64-linux-gnu/libusb-1.0.so.0(+0x104ec) [0x7fef306c04ec]
/lib/x86_64-linux-gnu/libusb-1.0.so.0(libusb_handle_events_timeout_completed+0x208) [0x7fef306c1cd8]
/usr/local/lib/libosmousb.so.0(+0x274a) [0x7fef3073f74a]
/usr/local/lib/libosmocore.so.19(+0x12a5c) [0x7fef306f1a5c]
/usr/local/lib/libosmocore.so.19(+0x12b76) [0x7fef306f1b76]
/usr/local/lib/libosmocore.so.19(osmo_select_main+0x19) [0x7fef306f1b95]
/home/boggy/Work/simtrace2/host/src/.libs/simtrace2-cardem-pcsc(+0x2efd) [0x55d2cea97efd]
/lib/x86_64-linux-gnu/libc.so.6(+0x29d90) [0x7fef304afd90]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x80) [0x7fef304afe40]
/home/boggy/Work/simtrace2/host/src/.libs/simtrace2-cardem-pcsc(+0x2fc5) [0x55d2cea97fc5]
Aborted

// I would ignore trail of 0's. It's being displayed when the reader and card fail to transmit the GPO and is just a side effect not the main cause in my estimation

The general problem is that the simtrace software doesn't know about instruction 'a8', as this is one that's not used in SIM card communication. You will have to teach osmo_apdu_segment_in about the specific instructions of your application (EMV). This is probably best done by creating an alternative card profile, similar to the osim_uicc_sim_cic_profile we currently use for SIM/UICC cards. You can find the source at https://gitea.osmocom.org/osmocom/libosmocore/src/branch/master/src/sim/class_tables.c

What those tables do is tell the code which APDU case (see ISO 7816-4) is present for each combination of CLA+INS bytes. We need this to know the direction of transmission after the TPDU header.

Once you have created (and start using) a table for EMV, I would assume it should work just fine, judging from how far you get in your paste.

Actions #3

Updated by laforge over 1 year ago

additional note: You can just define your own const struct osim_cla_ins_card_profile in your application (the simtrace2 code right now?). This will avoid having to rebuild patch + libosmocore all the time during R&D.

Actions #4

Updated by laforge over 1 year ago

I'm curious if you implemented that card profile telling the code how to handle the EMV APDU cases?

Actions #5

Updated by anton123 over 1 year ago

laforge wrote in #note-3:

additional note: You can just define your own const struct osim_cla_ins_card_profile in your application (the simtrace2 code right now?). This will avoid having to rebuild patch + libosmocore all the time during R&D.

laforge wrote in #note-4:

I'm curious if you implemented that card profile telling the code how to handle the EMV APDU cases?

Happy Holidays!

Seems I got stuck on same problem as boggy123. can you explain a bit more where and in which file should add the EMV support, I will share any updates please help. :-).

PS: any other pointers or advice is very welcome

thank you

Actions #6

Updated by laforge over 1 year ago

anton123 wrote in #note-5:

Seems I got stuck on same problem as boggy123. can you explain a bit more where and in which file should add the EMV support, I will share any updates please help. :-).

I don'r think I can be any more specific than the previous you commented on, sorry.

  1. in general, I would be surprised if EMV does T=0 (what simtrace implements) as normally it's all T=1. That's a completely different protocol requiring completely different state machines etc. in the firmware. Even for somebody knowing exactly what they do I'd say it's a couple of person-days of focused full-time work.
  2. onyl if you have evidence that your particular card is actually using T=0, you would have to define your own const struct osim_cla_ins_card_profile for the CMD/INS used in the EMV protocol.
Actions

Also available in: Atom PDF

Add picture from clipboard (Maximum size: 48.8 MB)