12 Commits

Author SHA1 Message Date
Harald Welte
4d2ff9a173 assert: Use printf_sync() to ensure printing of assert / panic
Change-Id: Icc202e60445d9be1cdcd61176db5ed1704d583e7
2021-04-06 02:17:39 +02:00
Kévin Redon
b6e421bcbe card_emu: use edge-triggered VCC ADC logic
Before this patch, we used to st ci->vcc_active depending on the
instantaneous ADC reading of VCC.  Is it > .5v, we claim VCC is active,
and if it's below, VCC is inactive.

With this patch we move to an edge triggered approach: Only change
ci->vcc_active if the previous reading was different from the current
reading.

FIXME: why?

Change-Id: I71b703162219484e43638f1f2f692e9dd554ef55
2021-04-06 02:17:39 +02:00
Harald Welte
e145a7aed4 card_emu: Fix computation of waiting time
As we store the waiting time (WT) in 'etu', we must adjust the formula
from ISO 7816-3.  The 'Fi' component in the formula only exists to
compute clock cycles from the etu, which we don't need here.

Without this patch, the waiting time would be way too large (by a factor
of 372 in the default case).

Change-Id: Ia21bc7303f9b38834b5b1753983ed2a99bfc7d95
2021-04-06 02:17:39 +02:00
Harald Welte
f83c69ff69 card_emu: Fix USART timer, particularly in re-start situations
The existing code started the timer once (and expired once) but didn't
properly handle re-starting of the timer.  Neither did it handle
the 'half time expiration' case.  If we want to call a function after
half the WT expiring, we must of course program the hardware for half
the timeout, and not the full timeout...

Change-Id: Ia999d97f835c27597fcd1cf7ac78bac0ab9c98c1
2021-04-06 02:17:39 +02:00
Harald Welte
2619862fba card_emu: Use USART timeout for waiting time
Instead of using the timer/counter peripheral to handle the waiting time
and corresponding timeout, the USART peripheral internal timeout
mechanism is used.

This is particularly important for the SIMtrace board since there
(contrary to other boards) the I/O signal is not wired to a TIO pin
of the timer/counter block, and hence Rx/Tx data cannot reset that
timer/counter.

As a result of this migration, cardem is now supported not only on
owhw + qmod, but also on the simtrace board.

The guts of this change have been lifted out of Change-Id
Ibcb2c8cace9137695adf5fb3de43566f7cfb93b5 by Kevin Redon, which was
unfortunately touching various different topics at the same time and
hence was split up. Some improvements are the introduction of the
ENABLE_TX_TIMER_ONLY mode, which avoids the USART interrupt handler
getting hammered with TXRDY between release of RST and start of the ATR.

Change-Id: Ibcb2c8cace9137695adf5fb3de43566f7cfb93b5
2021-04-06 02:17:39 +02:00
Harald Welte
deb322c36d card_emu: explicitly initialize PTS and TPDU states
Those are already initialized at various transitions of the master
7816 FSM, but let's properly initialize them at start-up, too.

Change-Id: I81b2a8ef3284559164700d94717e4ccf008f53df
2021-04-06 02:17:39 +02:00
Harald Welte
351dfd65d9 card_emu: improve reset detection conditions
* enter ISO_S_WAIT_RST when RST is asserted
* enter ISO_S_WAIT_ATR only when we RST is released while in state ISO_S_WAIT_RST

Change-Id: I620333aa8d45561a8028b948955a27f667b58406
2021-04-06 02:17:39 +02:00
Harald Welte
bc9b927569 iso7816_fidi: Add iso7816_3_ prefix to symbols; fix terminology
Fi/Di are not the index into the table, but the contents of the table
as resolved by Fi_index / Di_index.  Let's clarify the terminology.

Change-Id: If364e08e7c9a3a9707e6d54b9267c6a7c088e415
2021-04-06 02:17:39 +02:00
Harald Welte
e5c8833a97 card_emu: Clarify and differentiate F/Fi/F_index/Fi_index
The ISO7816 spec terms are well-defined, let's not abuse them. We used
to consider "Fi" as the "index into the table of F values", while the
spec actually considers Fi as the initial value for F.

Let's make sure we use the terms quite clearly:
* Fi and Di are the initial values for F and D
* F*_index and D*_index are the indexes into the ISO7816-3 Tables

Furthermore, let's track Fi separately from F, as e.g. the waiting
time definition only considers Fi as indicated in the ATR, despite
an actually different F value might have been negotiated via PTS
meanwhile.

Change-Id: Ieb2425e8380a81b79df7b2bd072902994e9c3ee7
2021-04-06 02:17:39 +02:00
Harald Welte
1a32601be7 card_emu: Rename fi to Fi and di to Di
As we will soon introduce the distinction between Fi and F, we should
use uppercase letters, as lower-case 'f' is defined in ISO7816-3 as
the frequency, which is different from the upper-case 'F'.

Change-Id: Iaede621551520576e9b9af878fa46fbc88e59c2a
2021-04-06 02:17:39 +02:00
Kévin Redon
ed3067e2ea make sim switch board specific
the simtrace board uses a bus switch not used on qmod and owhw to
switch the SIM between physical and virtual

Change-Id: Ieaf2ed4761fc3e04f33f9aac5c04a768c9a6f71e
2021-04-06 02:17:39 +02:00
Harald Welte
841a0b70ff card_emu: waiting_time is stored in etu, not clocks.
The comment didn't reflect the source.  I checked all users and
the code consistently stores the waiting time in units of 'etu'.

Change-Id: I2bc4a7c19cee5fb487ad639ee48ecaea706f6172
2021-04-06 02:17:39 +02:00
5 changed files with 65 additions and 73 deletions

View File

@@ -28,7 +28,7 @@ export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
export LD_LIBRARY_PATH="$inst/lib" export LD_LIBRARY_PATH="$inst/lib"
BUILDS="" BUILDS=""
BUILDS+="simtrace/dfu simtrace/trace simtrace/cardem " BUILDS+="simtrace/dfu simtrace/trace "
BUILDS+="qmod/dfu qmod/cardem " BUILDS+="qmod/dfu qmod/cardem "
BUILDS+="owhw/dfu owhw/cardem " BUILDS+="owhw/dfu owhw/cardem "
@@ -71,13 +71,13 @@ if [ "x$publish" = "x--publish" ]; then
$TOPDIR/contrib/prepare_upload.sh $TOPDIR/contrib/prepare_upload.sh
cat > "/build/known_hosts" <<EOF cat > "/build/known_hosts" <<EOF
[ftp.osmocom.org]:48 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDgQ9HntlpWNmh953a2Gc8NysKE4orOatVT1wQkyzhARnfYUerRuwyNr1GqMyBKdSI9amYVBXJIOUFcpV81niA7zQRUs66bpIMkE9/rHxBd81SkorEPOIS84W4vm3SZtuNqa+fADcqe88Hcb0ZdTzjKILuwi19gzrQyME2knHY71EOETe9Yow5RD2hTIpB5ecNxI0LUKDq+Ii8HfBvndPBIr0BWYDugckQ3Bocf+yn/tn2/GZieFEyFpBGF/MnLbAAfUKIdeyFRX7ufaiWWz5yKAfEhtziqdAGZaXNaLG6gkpy3EixOAy6ZXuTAk3b3Y0FUmDjhOHllbPmTOcKMry9 [rita.osmocom.org]:48 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDgQ9HntlpWNmh953a2Gc8NysKE4orOatVT1wQkyzhARnfYUerRuwyNr1GqMyBKdSI9amYVBXJIOUFcpV81niA7zQRUs66bpIMkE9/rHxBd81SkorEPOIS84W4vm3SZtuNqa+fADcqe88Hcb0ZdTzjKILuwi19gzrQyME2knHY71EOETe9Yow5RD2hTIpB5ecNxI0LUKDq+Ii8HfBvndPBIr0BWYDugckQ3Bocf+yn/tn2/GZieFEyFpBGF/MnLbAAfUKIdeyFRX7ufaiWWz5yKAfEhtziqdAGZaXNaLG6gkpy3EixOAy6ZXuTAk3b3Y0FUmDjhOHllbPmTOcKMry9
[ftp.osmocom.org]:48 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPdWn1kEousXuKsZ+qJEZTt/NSeASxCrUfNDW3LWtH+d8Ust7ZuKp/vuyG+5pe5pwpPOgFu7TjN+0lVjYJVXH54= [rita.osmocom.org]:48 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPdWn1kEousXuKsZ+qJEZTt/NSeASxCrUfNDW3LWtH+d8Ust7ZuKp/vuyG+5pe5pwpPOgFu7TjN+0lVjYJVXH54=
[ftp.osmocom.org]:48 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK8iivY70EiR5NiGChV39gRLjNpC8lvu1ZdHtdMw2zuX [rita.osmocom.org]:48 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK8iivY70EiR5NiGChV39gRLjNpC8lvu1ZdHtdMw2zuX
EOF EOF
SSH_COMMAND="ssh -o 'UserKnownHostsFile=/build/known_hosts' -p 48" SSH_COMMAND="ssh -o 'UserKnownHostsFile=/build/known_hosts' -p 48"
rsync --archive --verbose --compress --delete --rsh "$SSH_COMMAND" $TOPDIR/firmware/bin/*-latest.{bin,elf} binaries@ftp.osmocom.org:web-files/simtrace2/firmware/latest/ rsync --archive --verbose --compress --delete --rsh "$SSH_COMMAND" $TOPDIR/firmware/bin/*-latest.{bin,elf} binaries@rita.osmocom.org:web-files/simtrace2/firmware/latest/
rsync --archive --verbose --compress --rsh "$SSH_COMMAND" --exclude $TOPDIR/firmware/bin/*-latest.{bin,elf} $TOPDIR/firmware/bin/*-*-*-*.{bin,elf} binaries@ftp.osmocom.org:web-files/simtrace2/firmware/all/ rsync --archive --verbose --compress --rsh "$SSH_COMMAND" --exclude $TOPDIR/firmware/bin/*-latest.{bin,elf} $TOPDIR/firmware/bin/*-*-*-*.{bin,elf} binaries@rita.osmocom.org:web-files/simtrace2/firmware/all/
fi fi
echo echo

View File

@@ -178,14 +178,6 @@ CFLAGS += -ffunction-sections -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -DTRACE_L
CFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\" CFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\"
CFLAGS += -DBOARD=\"$(BOARD)\" -DBOARD_$(BOARD) CFLAGS += -DBOARD=\"$(BOARD)\" -DBOARD_$(BOARD)
CFLAGS += -DAPPLICATION=\"$(APP)\" -DAPPLICATION_$(APP) CFLAGS += -DAPPLICATION=\"$(APP)\" -DAPPLICATION_$(APP)
# Disable stack protector by default (OS#5081)
ifeq ($(STACK_PROTECTOR), 1)
CFLAGS += -fstack-protector
else
CFLAGS += -fno-stack-protector
endif
ASFLAGS = -mcpu=cortex-m3 -mthumb -Wall -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -D__ASSEMBLY__ ASFLAGS = -mcpu=cortex-m3 -mthumb -Wall -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -D__ASSEMBLY__
LDFLAGS = -mcpu=cortex-m3 -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=ResetException -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--print-memory-usage -Wl,--no-undefined $(LIB) LDFLAGS = -mcpu=cortex-m3 -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=ResetException -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--print-memory-usage -Wl,--no-undefined $(LIB)
#LD_OPTIONAL=-Wl,--print-gc-sections -Wl,--stats #LD_OPTIONAL=-Wl,--print-gc-sections -Wl,--stats

View File

@@ -153,14 +153,10 @@
/** Supported modes */ /** Supported modes */
/* SIMtrace board supports sniffer mode */ /* SIMtrace board supports sniffer mode */
#ifdef APPLICATION_trace
#define HAVE_SNIFFER #define HAVE_SNIFFER
#endif
/* SIMtrace board supports CCID mode */ /* SIMtrace board supports CCID mode */
//#define HAVE_CCID //#define HAVE_CCID
/* SIMtrace board supports card emulation mode */ /* SIMtrace board supports card emulation mode */
#ifdef APPLICATION_cardem //#define HAVE_CARDEM
#define HAVE_CARDEM
#endif
/* SIMtrace board supports man-in-the-middle mode */ /* SIMtrace board supports man-in-the-middle mode */
//#define HAVE_MITM //#define HAVE_MITM

View File

@@ -13,20 +13,6 @@
#define PHONE_INT 2 #define PHONE_INT 2
#define PHONE_DATAOUT 3 #define PHONE_DATAOUT 3
/* stub for stdio */
signed int printf_sync(const char *pFormat, ...)
{
va_list ap;
signed int result;
va_start(ap, pFormat);
result = vprintf(pFormat, ap);
va_end(ap);
return result;
}
/*********************************************************************** /***********************************************************************
* stub functions required by card_emu.c * stub functions required by card_emu.c
***********************************************************************/ ***********************************************************************/
@@ -64,9 +50,6 @@ void card_emu_uart_enable(uint8_t uart_chan, uint8_t rxtx)
case ENABLE_TX: case ENABLE_TX:
rts = "TX"; rts = "TX";
break; break;
case ENABLE_TX_TIMER_ONLY:
rts = "TX-TIMER-ONLY";
break;
case ENABLE_RX: case ENABLE_RX:
rts = "RX"; rts = "RX";
break; break;
@@ -83,14 +66,29 @@ void card_emu_uart_interrupt(uint8_t uart_chan)
printf("uart_interrupt(uart_chan=%u)\n", uart_chan); printf("uart_interrupt(uart_chan=%u)\n", uart_chan);
} }
void card_emu_uart_update_wt(uint8_t uart_chan, uint32_t wt) void tc_etu_set_wtime(uint8_t tc_chan, uint16_t wtime)
{ {
printf("%s(uart_chan=%u, wtime=%u)\n", __func__, uart_chan, wt); printf("tc_etu_set_wtime(tc_chan=%u, wtime=%u)\n", tc_chan, wtime);
} }
void card_emu_uart_reset_wt(uint8_t uart_chan) void tc_etu_set_etu(uint8_t tc_chan, uint16_t etu)
{ {
printf("%s(uart_chan=%u\n", __func__, uart_chan); printf("tc_etu_set_etu(tc_chan=%u, etu=%u)\n", tc_chan, etu);
}
void tc_etu_init(uint8_t chan_nr, void *handle)
{
printf("tc_etu_init(tc_chan=%u)\n", chan_nr);
}
void tc_etu_enable(uint8_t chan_nr)
{
printf("tc_etu_enable(tc_chan=%u)\n", chan_nr);
}
void tc_etu_disable(uint8_t chan_nr)
{
printf("tc_etu_disable(tc_chan=%u)\n", chan_nr);
} }
@@ -138,7 +136,7 @@ static void io_start_card(struct card_handle *ch)
/* release from reset and verify th ATR */ /* release from reset and verify th ATR */
card_emu_io_statechg(ch, CARD_IO_RST, 0); card_emu_io_statechg(ch, CARD_IO_RST, 0);
/* simulate waiting time before ATR expired */ /* simulate waiting time before ATR expired */
card_emu_wtime_expired(ch); tc_etu_wtime_expired(ch);
verify_atr(ch); verify_atr(ch);
} }
@@ -410,7 +408,7 @@ int main(int argc, char **argv)
struct card_handle *ch; struct card_handle *ch;
unsigned int i; unsigned int i;
ch = card_emu_init(0, 42, PHONE_DATAIN, PHONE_INT, false, true, false); ch = card_emu_init(0, 23, 42, PHONE_DATAIN, PHONE_INT, false, true, false);
assert(ch); assert(ch);
usb_buf_init(); usb_buf_init();

View File

@@ -1,7 +1,7 @@
/* simtrace2-cardem-pcsc - main program for the host PC to provide a remote SIM /* simtrace2-cardem-pcsc - main program for the host PC to provide a remote SIM
* using the SIMtrace 2 firmware in card emulation mode * using the SIMtrace 2 firmware in card emulation mode
* *
* (C) 2016-2021 by Harald Welte <hwelte@hmw-consulting.de> * (C) 2016-2020 by Harald Welte <hwelte@hmw-consulting.de>
* (C) 2018, sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.de> * (C) 2018, sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.de>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@@ -51,8 +51,29 @@
#include <osmocom/sim/class_tables.h> #include <osmocom/sim/class_tables.h>
#include <osmocom/sim/sim.h> #include <osmocom/sim/sim.h>
#define ATR_MAX_LEN 33
#define LOGCI(ci, lvl, fmt, args ...) printf(fmt, ## args) #define LOGCI(ci, lvl, fmt, args ...) printf(fmt, ## args)
/* reasonable ATR offering all protocols and voltages
* smartphones might not care, but other readers do
*
* TS = 0x3B Direct Convention
* T0 = 0x80 Y(1): b1000, K: 0 (historical bytes)
* TD(1) = 0x80 Y(i+1) = b1000, Protocol T=0
* ----
* TD(2) = 0x81 Y(i+1) = b1000, Protocol T=1
* ----
* TD(3) = 0x1F Y(i+1) = b0001, Protocol T=15
* ----
* TA(4) = 0xC7 Clock stop: no preference - Class accepted by the card: (3G) A 5V B 3V C 1.8V
* ----
* Historical bytes
* TCK = 0x59 correct checksum
*/
#define DEFAULT_ATR_STR "3B8080811FC759"
static void atr_update_csum(uint8_t *atr, unsigned int atr_len) static void atr_update_csum(uint8_t *atr, unsigned int atr_len)
{ {
uint8_t csum = 0; uint8_t csum = 0;
@@ -394,9 +415,9 @@ int main(int argc, char **argv)
int rc; int rc;
int c, ret = 1; int c, ret = 1;
int skip_atr = 0; int skip_atr = 0;
char *atr = NULL; char *atr = DEFAULT_ATR_STR;
uint8_t override_atr[OSIM_MAX_ATR_LEN]; uint8_t real_atr[ATR_MAX_LEN];
int override_atr_len = 0; int atr_len;
int keep_running = 0; int keep_running = 0;
int if_num = 0, vendor_id = -1, product_id = -1; int if_num = 0, vendor_id = -1, product_id = -1;
int config_id = -1, altsetting = 0, addr = -1; int config_id = -1, altsetting = 0, addr = -1;
@@ -463,13 +484,11 @@ int main(int argc, char **argv)
} }
} }
if (atr) { atr_len = osmo_hexparse(atr,real_atr,ATR_MAX_LEN);
override_atr_len = osmo_hexparse(atr, override_atr, sizeof(override_atr)); if (atr_len < 2) {
if (override_atr_len < 2) { fprintf(stderr, "Invalid ATR - please omit a leading 0x and only use valid hex "
fprintf(stderr, "Invalid ATR - please omit a leading 0x and only use valid hex " "digits and whitespace. ATRs need to be between 2 and 33 bytes long.\n");
"digits and whitespace. ATRs need to be between 2 and 33 bytes long.\n"); goto do_exit;
goto do_exit;
}
} }
if (vendor_id < 0 || product_id < 0) { if (vendor_id < 0 || product_id < 0) {
@@ -526,20 +545,20 @@ int main(int argc, char **argv)
transp->usb_devh = osmo_libusb_open_claim_interface(NULL, NULL, ifm); transp->usb_devh = osmo_libusb_open_claim_interface(NULL, NULL, ifm);
if (!transp->usb_devh) { if (!transp->usb_devh) {
fprintf(stderr, "can't open USB device\n"); fprintf(stderr, "can't open USB device\n");
goto close; goto close_exit;
} }
rc = libusb_claim_interface(transp->usb_devh, if_num); rc = libusb_claim_interface(transp->usb_devh, if_num);
if (rc < 0) { if (rc < 0) {
fprintf(stderr, "can't claim interface %d; rc=%d\n", if_num, rc); fprintf(stderr, "can't claim interface %d; rc=%d\n", if_num, rc);
goto close; goto close_exit;
} }
rc = osmo_libusb_get_ep_addrs(transp->usb_devh, if_num, &transp->usb_ep.out, rc = osmo_libusb_get_ep_addrs(transp->usb_devh, if_num, &transp->usb_ep.out,
&transp->usb_ep.in, &transp->usb_ep.irq_in); &transp->usb_ep.in, &transp->usb_ep.irq_in);
if (rc < 0) { if (rc < 0) {
fprintf(stderr, "can't obtain EP addrs; rc=%d\n", rc); fprintf(stderr, "can't obtain EP addrs; rc=%d\n", rc);
goto close; goto close_exit;
} }
allocate_and_submit_irq(ci); allocate_and_submit_irq(ci);
@@ -557,14 +576,8 @@ int main(int argc, char **argv)
if (!skip_atr) { if (!skip_atr) {
/* set the ATR */ /* set the ATR */
if (override_atr_len) { atr_update_csum(real_atr, atr_len);
/* user has specified an override-ATR */ osmo_st2_cardem_request_set_atr(ci, real_atr, atr_len);
atr_update_csum(override_atr, override_atr_len);
osmo_st2_cardem_request_set_atr(ci, override_atr, override_atr_len);
} else {
/* use the real ATR of the card */
osmo_st2_cardem_request_set_atr(ci, card->atr, card->atr_len);
}
} }
/* select remote (forwarded) SIM */ /* select remote (forwarded) SIM */
@@ -574,20 +587,13 @@ int main(int argc, char **argv)
ret = 0; ret = 0;
libusb_release_interface(transp->usb_devh, 0); libusb_release_interface(transp->usb_devh, 0);
close_exit:
close: if (transp->usb_devh)
if (transp->usb_devh) {
libusb_close(transp->usb_devh); libusb_close(transp->usb_devh);
transp->usb_devh = NULL;
}
if (keep_running) if (keep_running)
sleep(1); sleep(1);
} while (keep_running); } while (keep_running);
close_exit:
if (transp->usb_devh)
libusb_close(transp->usb_devh);
libusb_exit(NULL); libusb_exit(NULL);
do_exit: do_exit:
return ret; return ret;