blob: 75910c13b16fc50656c8b1781f487dbe27ae3b20 [file] [log] [blame]
Kévin Redon9a12d682018-07-08 13:21:16 +02001/* ISO7816-3 state machine for the card side
Harald Welte9d3e3822015-11-09 00:50:54 +01002 *
Kévin Redon9a12d682018-07-08 13:21:16 +02003 * (C) 2010-2017 by Harald Welte <laforge@gnumonks.org>
Kévin Redonebe672e2018-07-29 00:18:12 +02004 * (C) 2018 by sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon@sysmocom.de>
Harald Welte9d3e3822015-11-09 00:50:54 +01005 *
Kévin Redon9a12d682018-07-08 13:21:16 +02006 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
Harald Welte9d3e3822015-11-09 00:50:54 +010010 *
Kévin Redon9a12d682018-07-08 13:21:16 +020011 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
Harald Welte9d3e3822015-11-09 00:50:54 +010015 *
Kévin Redon9a12d682018-07-08 13:21:16 +020016 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
Harald Welte9d3e3822015-11-09 00:50:54 +010019 */
Harald Weltec430ac12017-02-28 01:25:12 +010020#include <stdio.h>
Harald Welte4c473da2015-11-14 13:31:11 +010021#include <assert.h>
Harald Welte9d3e3822015-11-09 00:50:54 +010022#include <errno.h>
23#include <string.h>
24#include <stdint.h>
25#include <sys/types.h>
26
27#include "utils.h"
28#include "trace.h"
29#include "iso7816_fidi.h"
30#include "tc_etu.h"
31#include "card_emu.h"
Harald Welte25a9a802017-05-08 13:30:09 +020032#include "simtrace_prot.h"
Harald Welte8e7fca32017-05-07 16:14:33 +020033#include "usb_buf.h"
Harald Welte9d90d282018-06-29 22:25:42 +020034#include <osmocom/core/linuxlist.h>
35#include <osmocom/core/msgb.h>
Harald Welte9d3e3822015-11-09 00:50:54 +010036
37
38#define NUM_SLOTS 2
39
40#define ISO7816_3_INIT_WTIME 9600
41#define ISO7816_3_DEFAULT_WI 10
42#define ISO7816_3_ATR_LEN_MAX (1+32) /* TS plus 32 chars */
43
44#define ISO7816_3_PB_NULL 0x60
45
46enum iso7816_3_card_state {
47 ISO_S_WAIT_POWER, /* waiting for power being applied */
48 ISO_S_WAIT_CLK, /* waiting for clock being applied */
49 ISO_S_WAIT_RST, /* waiting for reset being released */
50 ISO_S_WAIT_ATR, /* waiting for start of ATR */
51 ISO_S_IN_ATR, /* transmitting ATR to reader */
52 ISO_S_IN_PTS, /* transmitting ATR to reader */
53 ISO_S_WAIT_TPDU, /* waiting for data from reader */
54 ISO_S_IN_TPDU, /* inside a TPDU */
55};
56
Kévin Redon8a4fba52018-08-02 17:44:16 +020057const struct value_string iso7816_3_card_state_names[] = {
58 OSMO_VALUE_STRING(ISO_S_WAIT_POWER),
59 OSMO_VALUE_STRING(ISO_S_WAIT_CLK),
60 OSMO_VALUE_STRING(ISO_S_WAIT_RST),
61 OSMO_VALUE_STRING(ISO_S_WAIT_ATR),
62 OSMO_VALUE_STRING(ISO_S_IN_ATR),
63 OSMO_VALUE_STRING(ISO_S_IN_PTS),
64 OSMO_VALUE_STRING(ISO_S_WAIT_TPDU),
65 OSMO_VALUE_STRING(ISO_S_IN_TPDU),
66 {
67 .value = 0,
68 .str = NULL,
69 },
70};
71
72
Harald Welte9d3e3822015-11-09 00:50:54 +010073/* detailed sub-states of ISO_S_IN_PTS */
74enum pts_state {
75 PTS_S_WAIT_REQ_PTSS,
76 PTS_S_WAIT_REQ_PTS0,
77 PTS_S_WAIT_REQ_PTS1,
78 PTS_S_WAIT_REQ_PTS2,
79 PTS_S_WAIT_REQ_PTS3,
80 PTS_S_WAIT_REQ_PCK,
81 PTS_S_WAIT_RESP_PTSS = PTS_S_WAIT_REQ_PTSS | 0x10,
82 PTS_S_WAIT_RESP_PTS0 = PTS_S_WAIT_REQ_PTS0 | 0x10,
83 PTS_S_WAIT_RESP_PTS1 = PTS_S_WAIT_REQ_PTS1 | 0x10,
84 PTS_S_WAIT_RESP_PTS2 = PTS_S_WAIT_REQ_PTS2 | 0x10,
85 PTS_S_WAIT_RESP_PTS3 = PTS_S_WAIT_REQ_PTS3 | 0x10,
86 PTS_S_WAIT_RESP_PCK = PTS_S_WAIT_REQ_PCK | 0x10,
87};
88
89#define _PTSS 0
90#define _PTS0 1
91#define _PTS1 2
92#define _PTS2 3
93#define _PTS3 4
94#define _PCK 5
95
Harald Welte16cf4082015-11-11 19:02:48 +010096/* T-PDU state machine states */
Harald Welte9d3e3822015-11-09 00:50:54 +010097enum tpdu_state {
Harald Welte16cf4082015-11-11 19:02:48 +010098 TPDU_S_WAIT_CLA, /* waiting for CLA byte from reader */
99 TPDU_S_WAIT_INS, /* waiting for INS byte from reader */
100 TPDU_S_WAIT_P1, /* waiting for P1 byte from reader */
101 TPDU_S_WAIT_P2, /* waiting for P2 byte from reader */
102 TPDU_S_WAIT_P3, /* waiting for P3 byte from reader */
Harald Welte9d3e3822015-11-09 00:50:54 +0100103 TPDU_S_WAIT_PB, /* waiting for Tx of procedure byte */
Kévin Redon0f4abf52018-08-02 17:42:48 +0200104 TPDU_S_WAIT_RX, /* waiting for more data from reader */
Harald Welte9d3e3822015-11-09 00:50:54 +0100105 TPDU_S_WAIT_TX, /* waiting for more data to reader */
106};
107
108#define _CLA 0
109#define _INS 1
110#define _P1 2
111#define _P2 3
112#define _P3 4
113
114struct card_handle {
Harald Weltec3941092018-08-26 09:53:13 +0200115 unsigned int num;
Harald Weltedde112e2016-03-20 16:42:11 +0100116
Harald Welte9d3e3822015-11-09 00:50:54 +0100117 enum iso7816_3_card_state state;
118
119 /* signal levels */
120 uint8_t vcc_active; /* 1 = on, 0 = off */
121 uint8_t in_reset; /* 1 = RST low, 0 = RST high */
122 uint8_t clocked; /* 1 = active, 0 = inactive */
123
Harald Welte16cf4082015-11-11 19:02:48 +0100124 /* timing parameters, from PTS */
Harald Welte9d3e3822015-11-09 00:50:54 +0100125 uint8_t fi;
126 uint8_t di;
127 uint8_t wi;
128
129 uint8_t tc_chan; /* TC channel number */
130 uint8_t uart_chan; /* UART channel */
131
Harald Welte8e7fca32017-05-07 16:14:33 +0200132 uint8_t in_ep; /* USB IN EP */
133 uint8_t irq_ep; /* USB IN EP */
134
Harald Welte9d3e3822015-11-09 00:50:54 +0100135 uint32_t waiting_time; /* in clocks */
136
137 /* ATR state machine */
138 struct {
139 uint8_t idx;
140 uint8_t len;
141 //uint8_t hist_len;
142 //uint8_t last_td;
143 uint8_t atr[ISO7816_3_ATR_LEN_MAX];
144 } atr;
145
146 /* PPS / PTS support */
147 struct {
148 enum pts_state state;
Harald Welte16cf4082015-11-11 19:02:48 +0100149 uint8_t req[6]; /* request bytes */
150 uint8_t resp[6]; /* response bytes */
Harald Welte9d3e3822015-11-09 00:50:54 +0100151 } pts;
152
153 /* TPDU */
154 struct {
155 enum tpdu_state state;
Harald Welte16cf4082015-11-11 19:02:48 +0100156 uint8_t hdr[5]; /* CLA INS P1 P2 P3 */
Harald Welte9d3e3822015-11-09 00:50:54 +0100157 } tpdu;
158
Harald Welte8e7fca32017-05-07 16:14:33 +0200159 struct msgb *uart_rx_msg; /* UART RX -> USB TX */
160 struct msgb *uart_tx_msg; /* USB RX -> UART TX */
Harald Welte9d3e3822015-11-09 00:50:54 +0100161
Harald Welte54cb3d02016-02-29 14:12:40 +0100162 struct llist_head uart_tx_queue;
163
Harald Welte9d3e3822015-11-09 00:50:54 +0100164 struct {
165 uint32_t tx_bytes;
166 uint32_t rx_bytes;
167 uint32_t pps;
168 } stats;
169};
170
Harald Welte54cb3d02016-02-29 14:12:40 +0100171struct llist_head *card_emu_get_uart_tx_queue(struct card_handle *ch)
172{
173 return &ch->uart_tx_queue;
174}
175
Harald Welte2935b3c2015-11-14 20:00:14 +0100176static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts);
Harald Weltee7194ab2015-11-14 21:03:25 +0100177static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss);
Harald Welte2935b3c2015-11-14 20:00:14 +0100178
Harald Welte25a9a802017-05-08 13:30:09 +0200179/* update simtrace header msg_len and submit USB buffer */
180void usb_buf_upd_len_and_submit(struct msgb *msg)
181{
Harald Welteb91f6ad2017-05-10 22:51:30 +0200182 struct simtrace_msg_hdr *sh = (struct simtrace_msg_hdr *) msg->l1h;
Harald Welte25a9a802017-05-08 13:30:09 +0200183
184 sh->msg_len = msgb_length(msg);
185
186 usb_buf_submit(msg);
187}
188
189/* Allocate USB buffer and push + initialize simtrace_msg_hdr */
190struct msgb *usb_buf_alloc_st(uint8_t ep, uint8_t msg_class, uint8_t msg_type)
191{
192 struct msgb *msg;
193 struct simtrace_msg_hdr *sh;
194
195 msg = usb_buf_alloc(ep);
196 if (!msg)
197 return NULL;
198
199 msg->l1h = msgb_put(msg, sizeof(*sh));
200 sh = (struct simtrace_msg_hdr *) msg->l1h;
201 memset(sh, 0, sizeof(*sh));
202 sh->msg_class = msg_class;
203 sh->msg_type = msg_type;
204 msg->l2h = msg->l1h + sizeof(*sh);
205
206 return msg;
207}
208
Kévin Redon680bdab2018-07-18 14:00:57 +0200209/* Update cardemu_usb_msg_rx_data length + submit buffer */
Harald Welteb5288e82015-11-14 21:15:52 +0100210static void flush_rx_buffer(struct card_handle *ch)
211{
Harald Welte8e7fca32017-05-07 16:14:33 +0200212 struct msgb *msg;
Harald Welteb5288e82015-11-14 21:15:52 +0100213 struct cardemu_usb_msg_rx_data *rd;
Harald Welte8e7fca32017-05-07 16:14:33 +0200214 uint32_t data_len;
Harald Welteb5288e82015-11-14 21:15:52 +0100215
Harald Welte8e7fca32017-05-07 16:14:33 +0200216 msg = ch->uart_rx_msg;
217 if (!msg)
Harald Welteb5288e82015-11-14 21:15:52 +0100218 return;
219
Harald Welte8e7fca32017-05-07 16:14:33 +0200220 ch->uart_rx_msg = NULL;
Harald Welteb5288e82015-11-14 21:15:52 +0100221
Kévin Redon680bdab2018-07-18 14:00:57 +0200222 /* store length of data payload field in header */
Harald Welte25a9a802017-05-08 13:30:09 +0200223 rd = (struct cardemu_usb_msg_rx_data *) msg->l2h;
224 rd->data_len = msgb_l2len(msg) - sizeof(*rd);
Harald Welte54cb3d02016-02-29 14:12:40 +0100225
Kévin Redon910e6832018-08-02 17:47:57 +0200226 TRACE_INFO("%u: %s (%u)\n\r",
227 ch->num, __func__, rd->data_len);
228
Harald Welte25a9a802017-05-08 13:30:09 +0200229 usb_buf_upd_len_and_submit(msg);
Harald Welteb5288e82015-11-14 21:15:52 +0100230}
231
Kévin Redon680bdab2018-07-18 14:00:57 +0200232/* convert a non-contiguous PTS request/response into a contiguous
Harald Welte4ba66d02016-02-25 19:38:56 +0100233 * buffer, returning the number of bytes used in the buffer */
234static int serialize_pts(uint8_t *out, const uint8_t *in)
235{
236 int i = 0;
237
238 out[i++] = in[_PTSS];
239 out[i++] = in[_PTS0];
240 if (in[_PTS0] & (1 << 4))
241 out[i++] = in[_PTS1];
242 if (in[_PTS0] & (1 << 5))
243 out[i++] = in[_PTS2];
244 if (in[_PTS0] & (1 << 6))
245 out[i++] = in[_PTS3];
246 out[i++] = in[_PCK];
247
248 return i;
249}
250
Harald Welte17db2f12016-02-26 09:48:57 +0100251static uint8_t csum_pts(const uint8_t *in)
252{
253 uint8_t out[6];
254 int len = serialize_pts(out, in);
255 uint8_t csum = 0;
256 int i;
257
258 /* we don't include the PCK byte in the checksumming process */
259 len -= 1;
260
261 for (i = 0; i < len; i++)
262 csum = csum ^ out[i];
263
264 return csum;
265}
266
Harald Welte4ba66d02016-02-25 19:38:56 +0100267static void flush_pts(struct card_handle *ch)
268{
Harald Welte8e7fca32017-05-07 16:14:33 +0200269 struct msgb *msg;
Harald Welte4ba66d02016-02-25 19:38:56 +0100270 struct cardemu_usb_msg_pts_info *ptsi;
271
Harald Welte25a9a802017-05-08 13:30:09 +0200272 msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_DO_CEMU_PTS);
Harald Welte8e7fca32017-05-07 16:14:33 +0200273 if (!msg)
Harald Welte4ba66d02016-02-25 19:38:56 +0100274 return;
275
Harald Welte25a9a802017-05-08 13:30:09 +0200276 ptsi = (struct cardemu_usb_msg_pts_info *) msgb_put(msg, sizeof(*ptsi));
Harald Welted295b922016-03-18 21:01:36 +0100277 ptsi->pts_len = serialize_pts(ptsi->req, ch->pts.req);
Harald Welte4ba66d02016-02-25 19:38:56 +0100278 serialize_pts(ptsi->resp, ch->pts.resp);
279
Harald Welte25a9a802017-05-08 13:30:09 +0200280 usb_buf_upd_len_and_submit(msg);
Harald Welte4ba66d02016-02-25 19:38:56 +0100281}
282
Harald Welte8c496362016-02-27 16:24:09 +0100283static void emu_update_fidi(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100284{
285 int rc;
286
287 rc = compute_fidi_ratio(ch->fi, ch->di);
288 if (rc > 0 && rc < 0x400) {
Harald Weltedde112e2016-03-20 16:42:11 +0100289 TRACE_INFO("%u: computed Fi(%u) Di(%u) ratio: %d\r\n",
290 ch->num, ch->fi, ch->di, rc);
Harald Welte9d3e3822015-11-09 00:50:54 +0100291 /* make sure UART uses new F/D ratio */
292 card_emu_uart_update_fidi(ch->uart_chan, rc);
293 /* notify ETU timer about this */
294 tc_etu_set_etu(ch->tc_chan, rc);
295 } else
Harald Weltedde112e2016-03-20 16:42:11 +0100296 TRACE_INFO("%u: computed FiDi ration %d unsupported\r\n",
297 ch->num, rc);
Harald Welte9d3e3822015-11-09 00:50:54 +0100298}
299
300/* Update the ISO 7816-3 TPDU receiver state */
301static void card_set_state(struct card_handle *ch,
302 enum iso7816_3_card_state new_state)
303{
Harald Welte903d63a2016-03-20 13:38:39 +0100304 if (ch->state == new_state)
305 return;
306
Kévin Redon8a4fba52018-08-02 17:44:16 +0200307 TRACE_DEBUG("%u: 7816 card state %u (%s) -> %u (%s)\r\n", ch->num,
308 ch->state, get_value_string(iso7816_3_card_state_names, ch->state),
309 new_state, get_value_string(iso7816_3_card_state_names, new_state));
Harald Welte903d63a2016-03-20 13:38:39 +0100310 ch->state = new_state;
311
Harald Welte9d3e3822015-11-09 00:50:54 +0100312 switch (new_state) {
313 case ISO_S_WAIT_POWER:
314 case ISO_S_WAIT_CLK:
315 case ISO_S_WAIT_RST:
316 /* disable Rx and Tx of UART */
317 card_emu_uart_enable(ch->uart_chan, 0);
318 break;
319 case ISO_S_WAIT_ATR:
320 /* Reset to initial Fi / Di ratio */
321 ch->fi = 1;
322 ch->di = 1;
Harald Welte8c496362016-02-27 16:24:09 +0100323 emu_update_fidi(ch);
Kévin Redonebe672e2018-07-29 00:18:12 +0200324 /* the ATR should only be sent 400 to 40k clock cycles after the RESET.
325 * we use the tc_etu mechanism to wait this time.
326 * since the initial ETU is Fd=372/Dd=1 clock cycles long, we have to wait 2-107 ETU.
327 */
328 tc_etu_set_wtime(ch->tc_chan, 2);
329 /* ensure the TC_ETU timer is enabled */
330 tc_etu_enable(ch->tc_chan);
331 break;
332 case ISO_S_IN_ATR:
Kévin Redon680bdab2018-07-18 14:00:57 +0200333 /* initialize to default WI, this will be overwritten if we
Kévin Redonebe672e2018-07-29 00:18:12 +0200334 * send TC2, and it will be programmed into hardware after
Harald Welte9d3e3822015-11-09 00:50:54 +0100335 * ATR is finished */
336 ch->wi = ISO7816_3_DEFAULT_WI;
337 /* update waiting time to initial waiting time */
338 ch->waiting_time = ISO7816_3_INIT_WTIME;
Kévin Redonebe672e2018-07-29 00:18:12 +0200339 /* set initial waiting time */
Harald Welte9d3e3822015-11-09 00:50:54 +0100340 tc_etu_set_wtime(ch->tc_chan, ch->waiting_time);
341 /* Set ATR sub-state to initial state */
342 ch->atr.idx = 0;
Kévin Redonebe672e2018-07-29 00:18:12 +0200343 /* enable USART transmission to reader */
Harald Welte9d3e3822015-11-09 00:50:54 +0100344 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
Kévin Redonebe672e2018-07-29 00:18:12 +0200345 /* trigger USART TX IRQ to sent first ATR byte TS */
346 card_emu_uart_interrupt(ch->uart_chan);
Harald Welte9d3e3822015-11-09 00:50:54 +0100347 break;
348 case ISO_S_WAIT_TPDU:
349 /* enable the receiver, disable transmitter */
Harald Welte2935b3c2015-11-14 20:00:14 +0100350 set_tpdu_state(ch, TPDU_S_WAIT_CLA);
Harald Welte9d3e3822015-11-09 00:50:54 +0100351 card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
352 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100353 case ISO_S_IN_PTS:
354 case ISO_S_IN_TPDU:
355 /* do nothing */
356 break;
357 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100358}
359
Kévin Redonebe672e2018-07-29 00:18:12 +0200360/**********************************************************************
361 * ATR handling
362 **********************************************************************/
363
364/*! Transmit ATR data to reader
365 * @param[in] ch card interface connected to reader
366 * @return numbers of bytes transmitted
367 */
368static int tx_byte_atr(struct card_handle *ch)
369{
370 if (NULL == ch) {
371 TRACE_ERROR("ATR TX: no card handle provided\n\r");
372 return 0;
373 }
374 if (ISO_S_IN_ATR != ch->state) {
375 TRACE_ERROR("%u: ATR TX: no in ATR state\n\r", ch->num);
376 return 0;
377 }
378
379 /* Transmit ATR */
380 if (ch->atr.idx < ch->atr.len) {
381 uint8_t byte = ch->atr.atr[ch->atr.idx++];
382 card_emu_uart_tx(ch->uart_chan, byte);
Kévin Redonebe672e2018-07-29 00:18:12 +0200383 return 1;
384 } else { /* The ATR has been completely transmitted */
Kévin Redon8b8e58b2018-07-30 18:19:11 +0200385 /* search for TC2 to updated WI */
386 ch->wi = ISO7816_3_DEFAULT_WI;
387 if (ch->atr.len >= 2 && ch->atr.atr[1] & 0xf0) { /* Y1 has some data */
388 uint8_t atr_td1 = 2;
389 if (ch->atr.atr[1] & 0x10) { /* TA1 is present */
390 atr_td1++;
391 }
392 if (ch->atr.atr[1] & 0x20) { /* TB1 is present */
393 atr_td1++;
394 }
395 if (ch->atr.atr[1] & 0x40) { /* TC1 is present */
396 atr_td1++;
397 }
398 if (ch->atr.atr[1] & 0x80) { /* TD1 is present */
399 if (ch->atr.len > atr_td1 && ch->atr.atr[atr_td1] & 0xf0) { /* Y2 has some data */
400 uint8_t atr_tc2 = atr_td1+1;
401 if (ch->atr.atr[atr_td1] & 0x10) { /* TA2 is present */
402 atr_tc2++;
403 }
404 if (ch->atr.atr[atr_td1] & 0x20) { /* TB2 is present */
405 atr_tc2++;
406 }
407 if (ch->atr.atr[atr_td1] & 0x40) { /* TC2 is present */
408 if (ch->atr.len > atr_tc2 && ch->atr.atr[atr_tc2]) { /* TC2 encodes WI */
409 ch->wi = ch->atr.atr[atr_tc2]; /* set WI */
410 }
411 }
412 }
413 }
414 }
415 /* update waiting time (see ISO 7816-3 10.2) */
416 ch->waiting_time = ch->wi * 960 * ch->fi;
417 tc_etu_set_wtime(ch->tc_chan, ch->waiting_time);
Kévin Redonebe672e2018-07-29 00:18:12 +0200418 /* reset PTS to initial state */
419 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
420 /* go to next state */
421 card_set_state(ch, ISO_S_WAIT_TPDU);
422 return 0;
423 }
424
425 /* return number of bytes transmitted */
426 return 1;
427}
Harald Welte9d3e3822015-11-09 00:50:54 +0100428
429/**********************************************************************
430 * PTS / PPS handling
431 **********************************************************************/
432
Kévin Redon680bdab2018-07-18 14:00:57 +0200433/* Update the PTS sub-state */
Harald Welte9d3e3822015-11-09 00:50:54 +0100434static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss)
435{
Harald Weltedde112e2016-03-20 16:42:11 +0100436 TRACE_DEBUG("%u: 7816 PTS state %u -> %u\r\n",
437 ch->num, ch->pts.state, new_ptss);
Harald Welte9d3e3822015-11-09 00:50:54 +0100438 ch->pts.state = new_ptss;
439}
440
441/* Determine the next PTS state */
442static enum pts_state next_pts_state(struct card_handle *ch)
443{
444 uint8_t is_resp = ch->pts.state & 0x10;
445 uint8_t sstate = ch->pts.state & 0x0f;
446 uint8_t *pts_ptr;
447
448 if (!is_resp)
449 pts_ptr = ch->pts.req;
450 else
451 pts_ptr = ch->pts.resp;
452
453 switch (sstate) {
454 case PTS_S_WAIT_REQ_PTSS:
455 goto from_ptss;
456 case PTS_S_WAIT_REQ_PTS0:
457 goto from_pts0;
458 case PTS_S_WAIT_REQ_PTS1:
459 goto from_pts1;
460 case PTS_S_WAIT_REQ_PTS2:
461 goto from_pts2;
462 case PTS_S_WAIT_REQ_PTS3:
463 goto from_pts3;
464 }
465
466 if (ch->pts.state == PTS_S_WAIT_REQ_PCK)
467 return PTS_S_WAIT_RESP_PTSS;
468
469from_ptss:
470 return PTS_S_WAIT_REQ_PTS0 | is_resp;
471from_pts0:
472 if (pts_ptr[_PTS0] & (1 << 4))
473 return PTS_S_WAIT_REQ_PTS1 | is_resp;
474from_pts1:
475 if (pts_ptr[_PTS0] & (1 << 5))
476 return PTS_S_WAIT_REQ_PTS2 | is_resp;
477from_pts2:
478 if (pts_ptr[_PTS0] & (1 << 6))
479 return PTS_S_WAIT_REQ_PTS3 | is_resp;
480from_pts3:
481 return PTS_S_WAIT_REQ_PCK | is_resp;
482}
483
484
Harald Welteccb8a222016-03-20 13:37:11 +0100485static int
Harald Welte9d3e3822015-11-09 00:50:54 +0100486process_byte_pts(struct card_handle *ch, uint8_t byte)
487{
488 switch (ch->pts.state) {
489 case PTS_S_WAIT_REQ_PTSS:
490 ch->pts.req[_PTSS] = byte;
491 break;
492 case PTS_S_WAIT_REQ_PTS0:
493 ch->pts.req[_PTS0] = byte;
494 break;
495 case PTS_S_WAIT_REQ_PTS1:
496 ch->pts.req[_PTS1] = byte;
497 break;
498 case PTS_S_WAIT_REQ_PTS2:
499 ch->pts.req[_PTS2] = byte;
500 break;
501 case PTS_S_WAIT_REQ_PTS3:
502 ch->pts.req[_PTS3] = byte;
503 break;
504 case PTS_S_WAIT_REQ_PCK:
505 ch->pts.req[_PCK] = byte;
Harald Welte17db2f12016-02-26 09:48:57 +0100506 if (ch->pts.req[_PCK] != csum_pts(ch->pts.req)) {
Harald Weltedde112e2016-03-20 16:42:11 +0100507 TRACE_ERROR("%u: Error in PTS Checksum!\r\n",
508 ch->num);
Harald Welte17db2f12016-02-26 09:48:57 +0100509 /* Wait for the next TPDU */
510 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
511 return ISO_S_WAIT_TPDU;
512 }
Harald Welte4ba66d02016-02-25 19:38:56 +0100513 /* FIXME: check if proposal matches capabilities in ATR */
Harald Welte9d3e3822015-11-09 00:50:54 +0100514 memcpy(ch->pts.resp, ch->pts.req, sizeof(ch->pts.resp));
515 break;
Harald Welte4c473da2015-11-14 13:31:11 +0100516 default:
Harald Weltedde112e2016-03-20 16:42:11 +0100517 TRACE_ERROR("%u: process_byte_pts() in invalid state %u\r\n",
518 ch->num, ch->pts.state);
Harald Welte4c473da2015-11-14 13:31:11 +0100519 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100520 }
521 /* calculate the next state and set it */
522 set_pts_state(ch, next_pts_state(ch));
523
Harald Welte4ba66d02016-02-25 19:38:56 +0100524 if (ch->pts.state == PTS_S_WAIT_RESP_PTSS) {
525 flush_pts(ch);
526 /* activate UART TX to transmit PTS response */
527 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
Harald Welte53079bb2016-03-20 14:58:35 +0100528 /* don't fall-through to the 'return ISO_S_IN_PTS'
529 * below, rather keep ISO7816 state as-is, it will be
530 * further updated by the tx-completion handler */
Harald Welteccb8a222016-03-20 13:37:11 +0100531 return -1;
Harald Welte4ba66d02016-02-25 19:38:56 +0100532 }
533
Harald Welte9d3e3822015-11-09 00:50:54 +0100534 return ISO_S_IN_PTS;
535}
536
537/* return a single byte to be transmitted to the reader */
Harald Welte855ba9e2016-02-24 21:00:46 +0100538static int tx_byte_pts(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100539{
Harald Welte855ba9e2016-02-24 21:00:46 +0100540 uint8_t byte;
541
542 /* 1: Determine the next transmit byte */
Harald Welte9d3e3822015-11-09 00:50:54 +0100543 switch (ch->pts.state) {
544 case PTS_S_WAIT_RESP_PTSS:
Harald Welte855ba9e2016-02-24 21:00:46 +0100545 byte = ch->pts.resp[_PTSS];
Harald Welte9d3e3822015-11-09 00:50:54 +0100546 break;
547 case PTS_S_WAIT_RESP_PTS0:
Harald Welte855ba9e2016-02-24 21:00:46 +0100548 byte = ch->pts.resp[_PTS0];
Harald Welte9d3e3822015-11-09 00:50:54 +0100549 break;
550 case PTS_S_WAIT_RESP_PTS1:
Harald Welte855ba9e2016-02-24 21:00:46 +0100551 byte = ch->pts.resp[_PTS1];
Harald Welte9d3e3822015-11-09 00:50:54 +0100552 /* This must be TA1 */
Harald Welte855ba9e2016-02-24 21:00:46 +0100553 ch->fi = byte >> 4;
554 ch->di = byte & 0xf;
Harald Weltedde112e2016-03-20 16:42:11 +0100555 TRACE_DEBUG("%u: found Fi=%u Di=%u\r\n", ch->num,
556 ch->fi, ch->di);
Harald Welte9d3e3822015-11-09 00:50:54 +0100557 break;
558 case PTS_S_WAIT_RESP_PTS2:
Harald Welte855ba9e2016-02-24 21:00:46 +0100559 byte = ch->pts.resp[_PTS2];
Harald Welte9d3e3822015-11-09 00:50:54 +0100560 break;
561 case PTS_S_WAIT_RESP_PTS3:
Harald Welte855ba9e2016-02-24 21:00:46 +0100562 byte = ch->pts.resp[_PTS3];
Harald Welte9d3e3822015-11-09 00:50:54 +0100563 break;
564 case PTS_S_WAIT_RESP_PCK:
Harald Welte855ba9e2016-02-24 21:00:46 +0100565 byte = ch->pts.resp[_PCK];
Harald Welte855ba9e2016-02-24 21:00:46 +0100566 break;
Harald Welted79dc4f2015-11-14 13:32:21 +0100567 default:
Harald Weltedde112e2016-03-20 16:42:11 +0100568 TRACE_ERROR("%u: get_byte_pts() in invalid state %u\r\n",
569 ch->num, ch->pts.state);
Harald Welte855ba9e2016-02-24 21:00:46 +0100570 return 0;
571 }
572
573 /* 2: Transmit the byte */
574 card_emu_uart_tx(ch->uart_chan, byte);
575
576 /* 3: Update the state */
577
578 switch (ch->pts.state) {
579 case PTS_S_WAIT_RESP_PCK:
Harald Weltec58bba02016-03-20 14:57:53 +0100580 card_emu_uart_wait_tx_idle(ch->uart_chan);
Harald Welte52d55462016-03-20 13:38:05 +0100581 /* update baud rate generator with Fi/Di */
582 emu_update_fidi(ch);
Harald Welte855ba9e2016-02-24 21:00:46 +0100583 /* Wait for the next TPDU */
584 card_set_state(ch, ISO_S_WAIT_TPDU);
585 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
586 break;
587 default:
588 /* calculate the next state and set it */
589 set_pts_state(ch, next_pts_state(ch));
Harald Welted79dc4f2015-11-14 13:32:21 +0100590 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100591 }
Harald Welted79dc4f2015-11-14 13:32:21 +0100592
Harald Welte855ba9e2016-02-24 21:00:46 +0100593 /* return number of bytes transmitted */
594 return 1;
Harald Welte9d3e3822015-11-09 00:50:54 +0100595}
596
597
598/**********************************************************************
599 * TPDU handling
600 **********************************************************************/
601
Harald Welte4d804672015-11-14 23:02:38 +0100602
603/* compute number of data bytes according to Chapter 10.3.2 of 7816-3 */
604static unsigned int t0_num_data_bytes(uint8_t p3, int reader_to_card)
605{
606 if (reader_to_card) {
607 return p3;
608 } else {
609 if (p3 == 0)
610 return 256;
611 else
612 return p3;
613 }
614}
615
Harald Welte9d3e3822015-11-09 00:50:54 +0100616/* add a just-received TPDU byte (from reader) to USB buffer */
Harald Welte61bb30e2015-11-14 23:44:14 +0100617static void add_tpdu_byte(struct card_handle *ch, uint8_t byte)
Harald Welte9d3e3822015-11-09 00:50:54 +0100618{
Harald Welte8e7fca32017-05-07 16:14:33 +0200619 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100620 struct cardemu_usb_msg_rx_data *rd;
Harald Welte4d804672015-11-14 23:02:38 +0100621 unsigned int num_data_bytes = t0_num_data_bytes(ch->tpdu.hdr[_P3], 0);
Harald Welte9d3e3822015-11-09 00:50:54 +0100622
623 /* ensure we have a buffer */
Harald Welte8e7fca32017-05-07 16:14:33 +0200624 if (!ch->uart_rx_msg) {
Harald Welte25a9a802017-05-08 13:30:09 +0200625 msg = ch->uart_rx_msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM,
626 SIMTRACE_MSGT_DO_CEMU_RX_DATA);
Harald Welte8e7fca32017-05-07 16:14:33 +0200627 if (!ch->uart_rx_msg) {
Harald Weltedde112e2016-03-20 16:42:11 +0100628 TRACE_ERROR("%u: Received UART byte but ENOMEM\r\n",
629 ch->num);
Harald Welte9d3e3822015-11-09 00:50:54 +0100630 return;
Harald Welte4d804672015-11-14 23:02:38 +0100631 }
Harald Welte25a9a802017-05-08 13:30:09 +0200632 msgb_put(msg, sizeof(*rd));
Harald Welte9d3e3822015-11-09 00:50:54 +0100633 } else
Harald Welte8e7fca32017-05-07 16:14:33 +0200634 msg = ch->uart_rx_msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100635
Harald Welte25a9a802017-05-08 13:30:09 +0200636 rd = (struct cardemu_usb_msg_rx_data *) msg->l2h;
Harald Welte8e7fca32017-05-07 16:14:33 +0200637 msgb_put_u8(msg, byte);
Harald Welte9d3e3822015-11-09 00:50:54 +0100638
639 /* check if the buffer is full. If so, send it */
Harald Welte25a9a802017-05-08 13:30:09 +0200640 if (msgb_l2len(msg) >= sizeof(*rd) + num_data_bytes) {
Harald Welte4d804672015-11-14 23:02:38 +0100641 rd->flags |= CEMU_DATA_F_FINAL;
Harald Welteb5288e82015-11-14 21:15:52 +0100642 flush_rx_buffer(ch);
Harald Welte61bb30e2015-11-14 23:44:14 +0100643 /* We need to transmit the SW now, */
644 set_tpdu_state(ch, TPDU_S_WAIT_TX);
Harald Welte8e7fca32017-05-07 16:14:33 +0200645 } else if (msgb_tailroom(msg) <= 0)
Harald Welte4d804672015-11-14 23:02:38 +0100646 flush_rx_buffer(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100647}
648
649static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts)
650{
Harald Welte05b41c62015-11-14 20:58:48 +0100651 if (ch->tpdu.state == new_ts)
652 return;
653
Harald Weltedde112e2016-03-20 16:42:11 +0100654 TRACE_DEBUG("%u: 7816 TPDU state %u -> %u\r\n", ch->num,
655 ch->tpdu.state, new_ts);
Harald Welte05b41c62015-11-14 20:58:48 +0100656
Harald Welte903d63a2016-03-20 13:38:39 +0100657 ch->tpdu.state = new_ts;
658
Harald Welte9d3e3822015-11-09 00:50:54 +0100659 switch (new_ts) {
660 case TPDU_S_WAIT_CLA:
Harald Welte05b41c62015-11-14 20:58:48 +0100661 case TPDU_S_WAIT_RX:
Harald Welte9d3e3822015-11-09 00:50:54 +0100662 card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
663 break;
664 case TPDU_S_WAIT_PB:
665 /* we just completed the TPDU header from reader to card
666 * and now need to disable the receiver, enable the
667 * transmitter and transmit the procedure byte */
668 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
669 break;
Harald Weltead434402016-03-02 11:18:29 +0100670 default:
671 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100672 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100673}
674
675static enum tpdu_state next_tpdu_state(struct card_handle *ch)
676{
677 switch (ch->tpdu.state) {
678 case TPDU_S_WAIT_CLA:
679 return TPDU_S_WAIT_INS;
680 case TPDU_S_WAIT_INS:
681 return TPDU_S_WAIT_P1;
682 case TPDU_S_WAIT_P1:
683 return TPDU_S_WAIT_P2;
684 case TPDU_S_WAIT_P2:
685 return TPDU_S_WAIT_P3;
686 case TPDU_S_WAIT_P3:
687 return TPDU_S_WAIT_PB;
688 /* simply stay in Rx or Tx by default */
689 case TPDU_S_WAIT_PB:
690 return TPDU_S_WAIT_PB;
691 case TPDU_S_WAIT_RX:
692 return TPDU_S_WAIT_RX;
693 case TPDU_S_WAIT_TX:
694 return TPDU_S_WAIT_TX;
695 }
Harald Welte4c473da2015-11-14 13:31:11 +0100696 /* we should never reach here */
697 assert(0);
698 return -1;
Harald Welte9d3e3822015-11-09 00:50:54 +0100699}
700
701static void send_tpdu_header(struct card_handle *ch)
702{
Harald Welte8e7fca32017-05-07 16:14:33 +0200703 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100704 struct cardemu_usb_msg_rx_data *rd;
Harald Welte8e7fca32017-05-07 16:14:33 +0200705 uint8_t *cur;
Harald Welte9d3e3822015-11-09 00:50:54 +0100706
Harald Weltedde112e2016-03-20 16:42:11 +0100707 TRACE_INFO("%u: %s: %02x %02x %02x %02x %02x\r\n",
708 ch->num, __func__,
Harald Welte43f79492016-02-29 10:06:54 +0100709 ch->tpdu.hdr[0], ch->tpdu.hdr[1],
710 ch->tpdu.hdr[2], ch->tpdu.hdr[3],
711 ch->tpdu.hdr[4]);
712
Harald Welte9d3e3822015-11-09 00:50:54 +0100713 /* if we already/still have a context, send it off */
Harald Welte8e7fca32017-05-07 16:14:33 +0200714 if (ch->uart_rx_msg) {
Harald Weltedde112e2016-03-20 16:42:11 +0100715 TRACE_DEBUG("%u: have old buffer\r\n", ch->num);
Harald Welte8e7fca32017-05-07 16:14:33 +0200716 if (msgb_l2len(ch->uart_rx_msg)) {
Harald Weltedde112e2016-03-20 16:42:11 +0100717 TRACE_DEBUG("%u: flushing old buffer\r\n", ch->num);
Harald Weltef1697e22016-03-02 10:28:54 +0100718 flush_rx_buffer(ch);
719 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100720 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200721 TRACE_DEBUG("%u: allocating new buffer\r\n", ch->num);
722 /* ensure we have a new buffer */
Harald Welte25a9a802017-05-08 13:30:09 +0200723 ch->uart_rx_msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM,
724 SIMTRACE_MSGT_DO_CEMU_RX_DATA);
Harald Welte8e7fca32017-05-07 16:14:33 +0200725 if (!ch->uart_rx_msg) {
726 TRACE_ERROR("%u: %s: ENOMEM\r\n", ch->num, __func__);
727 return;
728 }
729 msg = ch->uart_rx_msg;
Harald Welte25a9a802017-05-08 13:30:09 +0200730 rd = (struct cardemu_usb_msg_rx_data *) msgb_put(msg, sizeof(*rd));
Harald Welte9d3e3822015-11-09 00:50:54 +0100731
Harald Welte8e7fca32017-05-07 16:14:33 +0200732 /* initialize header */
Harald Welte9d3e3822015-11-09 00:50:54 +0100733 rd->flags = CEMU_DATA_F_TPDU_HDR;
Harald Welte9d3e3822015-11-09 00:50:54 +0100734
735 /* copy TPDU header to data field */
Harald Welte8e7fca32017-05-07 16:14:33 +0200736 cur = msgb_put(msg, sizeof(ch->tpdu.hdr));
737 memcpy(cur, ch->tpdu.hdr, sizeof(ch->tpdu.hdr));
Harald Welteb5288e82015-11-14 21:15:52 +0100738 /* rd->data_len is set in flush_rx_buffer() */
Harald Welte9d3e3822015-11-09 00:50:54 +0100739
Harald Welteb5288e82015-11-14 21:15:52 +0100740 flush_rx_buffer(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100741}
742
743static enum iso7816_3_card_state
744process_byte_tpdu(struct card_handle *ch, uint8_t byte)
745{
746 switch (ch->tpdu.state) {
747 case TPDU_S_WAIT_CLA:
748 ch->tpdu.hdr[_CLA] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100749 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100750 break;
751 case TPDU_S_WAIT_INS:
752 ch->tpdu.hdr[_INS] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100753 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100754 break;
755 case TPDU_S_WAIT_P1:
756 ch->tpdu.hdr[_P1] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100757 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100758 break;
759 case TPDU_S_WAIT_P2:
760 ch->tpdu.hdr[_P2] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100761 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100762 break;
763 case TPDU_S_WAIT_P3:
764 ch->tpdu.hdr[_P3] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100765 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100766 /* FIXME: start timer to transmit further 0x60 */
767 /* send the TPDU header as part of a procedure byte
768 * request to the USB host */
769 send_tpdu_header(ch);
770 break;
771 case TPDU_S_WAIT_RX:
Harald Welte61bb30e2015-11-14 23:44:14 +0100772 add_tpdu_byte(ch, byte);
773 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100774 default:
Harald Weltedde112e2016-03-20 16:42:11 +0100775 TRACE_ERROR("%u: process_byte_tpdu() in invalid state %u\r\n",
776 ch->num, ch->tpdu.state);
Harald Welte9d3e3822015-11-09 00:50:54 +0100777 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100778
779 /* ensure we stay in TPDU ISO state */
780 return ISO_S_IN_TPDU;
781}
782
Harald Welte855ba9e2016-02-24 21:00:46 +0100783/* tx a single byte to be transmitted to the reader */
784static int tx_byte_tpdu(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100785{
Harald Welte8e7fca32017-05-07 16:14:33 +0200786 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100787 struct cardemu_usb_msg_tx_data *td;
Harald Welte855ba9e2016-02-24 21:00:46 +0100788 uint8_t byte;
Harald Welte9d3e3822015-11-09 00:50:54 +0100789
790 /* ensure we are aware of any data that might be pending for
791 * transmit */
Harald Welte8e7fca32017-05-07 16:14:33 +0200792 if (!ch->uart_tx_msg) {
Harald Welte53079bb2016-03-20 14:58:35 +0100793 /* uart_tx_queue is filled from main loop, so no need
794 * for irq-safe operations */
Harald Welte54cb3d02016-02-29 14:12:40 +0100795 if (llist_empty(&ch->uart_tx_queue))
Harald Welte9d3e3822015-11-09 00:50:54 +0100796 return 0;
797
Harald Welte54cb3d02016-02-29 14:12:40 +0100798 /* dequeue first at head */
Harald Welte8e7fca32017-05-07 16:14:33 +0200799 ch->uart_tx_msg = msgb_dequeue(&ch->uart_tx_queue);
Harald Welte25a9a802017-05-08 13:30:09 +0200800 ch->uart_tx_msg->l1h = ch->uart_tx_msg->head;
801 ch->uart_tx_msg->l2h = ch->uart_tx_msg->l1h + sizeof(struct simtrace_msg_hdr);
Harald Welte8e7fca32017-05-07 16:14:33 +0200802 msg = ch->uart_tx_msg;
Harald Welte25a9a802017-05-08 13:30:09 +0200803 /* remove the header */
804 msgb_pull(msg, sizeof(struct simtrace_msg_hdr) + sizeof(*td));
Harald Welte9d3e3822015-11-09 00:50:54 +0100805 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200806 msg = ch->uart_tx_msg;
Harald Welte25a9a802017-05-08 13:30:09 +0200807 td = (struct cardemu_usb_msg_tx_data *) msg->l2h;
Harald Welte9d3e3822015-11-09 00:50:54 +0100808
Harald Welte8e7fca32017-05-07 16:14:33 +0200809 /* take the next pending byte out of the msgb */
810 byte = msgb_pull_u8(msg);
Harald Welte855ba9e2016-02-24 21:00:46 +0100811
812 card_emu_uart_tx(ch->uart_chan, byte);
Harald Welte9d3e3822015-11-09 00:50:54 +0100813
Kévin Redon0f4abf52018-08-02 17:42:48 +0200814 /* this must happen _after_ the byte has been transmitted */
Harald Weltef16b6182016-02-24 22:18:46 +0100815 switch (ch->tpdu.state) {
816 case TPDU_S_WAIT_PB:
817 /* if we just transmitted the procedure byte, we need to decide
818 * if we want to continue to receive or transmit */
819 if (td->flags & CEMU_DATA_F_PB_AND_TX)
820 set_tpdu_state(ch, TPDU_S_WAIT_TX);
821 else if (td->flags & CEMU_DATA_F_PB_AND_RX)
822 set_tpdu_state(ch, TPDU_S_WAIT_RX);
823 break;
Harald Weltead434402016-03-02 11:18:29 +0100824 default:
825 break;
Harald Weltef16b6182016-02-24 22:18:46 +0100826 }
827
Harald Welte9d3e3822015-11-09 00:50:54 +0100828 /* check if the buffer has now been fully transmitted */
Harald Welte8e7fca32017-05-07 16:14:33 +0200829 if (msgb_length(msg) == 0) {
Harald Welte52922ff2015-11-14 20:59:56 +0100830 if (td->flags & CEMU_DATA_F_PB_AND_RX) {
831 /* we have just sent the procedure byte and now
832 * need to continue receiving */
833 set_tpdu_state(ch, TPDU_S_WAIT_RX);
Harald Welte2935b3c2015-11-14 20:00:14 +0100834 } else {
Harald Welte52922ff2015-11-14 20:59:56 +0100835 /* we have transmitted all bytes */
836 if (td->flags & CEMU_DATA_F_FINAL) {
837 /* this was the final part of the APDU, go
Harald Welte53079bb2016-03-20 14:58:35 +0100838 * back to state one */
Harald Welte52922ff2015-11-14 20:59:56 +0100839 card_set_state(ch, ISO_S_WAIT_TPDU);
Harald Welte52922ff2015-11-14 20:59:56 +0100840 }
Harald Welte2935b3c2015-11-14 20:00:14 +0100841 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200842 usb_buf_free(msg);
843 ch->uart_tx_msg = NULL;
Harald Welte9d3e3822015-11-09 00:50:54 +0100844 }
845
846 return 1;
847}
848
849/**********************************************************************
850 * Public API
851 **********************************************************************/
852
853/* process a single byte received from the reader */
854void card_emu_process_rx_byte(struct card_handle *ch, uint8_t byte)
855{
856 int new_state = -1;
857
858 ch->stats.rx_bytes++;
859
860 switch (ch->state) {
Harald Welte9d3e3822015-11-09 00:50:54 +0100861 case ISO_S_WAIT_TPDU:
862 if (byte == 0xff) {
863 new_state = process_byte_pts(ch, byte);
864 ch->stats.pps++;
865 goto out_silent;
866 }
867 /* fall-through */
868 case ISO_S_IN_TPDU:
869 new_state = process_byte_tpdu(ch, byte);
870 break;
871 case ISO_S_IN_PTS:
872 new_state = process_byte_pts(ch, byte);
873 goto out_silent;
Kévin Redon5f6b8712018-07-11 09:49:06 +0200874 default:
875 TRACE_ERROR("%u: Received UART char in invalid 7816 state "
876 "%u\r\n", ch->num, ch->state);
877 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100878 }
879
880out_silent:
881 if (new_state != -1)
882 card_set_state(ch, new_state);
883}
884
Harald Welte855ba9e2016-02-24 21:00:46 +0100885/* transmit a single byte to the reader */
886int card_emu_tx_byte(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100887{
888 int rc = 0;
889
890 switch (ch->state) {
891 case ISO_S_IN_ATR:
Kévin Redonebe672e2018-07-29 00:18:12 +0200892 rc = tx_byte_atr(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100893 break;
894 case ISO_S_IN_PTS:
Harald Welte855ba9e2016-02-24 21:00:46 +0100895 rc = tx_byte_pts(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100896 break;
897 case ISO_S_IN_TPDU:
Harald Welte855ba9e2016-02-24 21:00:46 +0100898 rc = tx_byte_tpdu(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100899 break;
Harald Weltead434402016-03-02 11:18:29 +0100900 default:
901 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100902 }
903
904 if (rc)
905 ch->stats.tx_bytes++;
906
Harald Welte4d804672015-11-14 23:02:38 +0100907 /* if we return 0 here, the UART needs to disable transmit-ready
908 * interrupts */
Harald Welte9d3e3822015-11-09 00:50:54 +0100909 return rc;
910}
911
Harald Welteacae4122016-03-02 10:27:58 +0100912void card_emu_have_new_uart_tx(struct card_handle *ch)
913{
914 switch (ch->state) {
915 case ISO_S_IN_TPDU:
916 switch (ch->tpdu.state) {
917 case TPDU_S_WAIT_TX:
918 case TPDU_S_WAIT_PB:
919 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
920 break;
921 default:
922 break;
923 }
924 default:
925 break;
926 }
927}
928
Harald Welteff160652016-03-19 21:59:06 +0100929void card_emu_report_status(struct card_handle *ch)
930{
Harald Welte8e7fca32017-05-07 16:14:33 +0200931 struct msgb *msg;
Harald Welteff160652016-03-19 21:59:06 +0100932 struct cardemu_usb_msg_status *sts;
933
Harald Welte25a9a802017-05-08 13:30:09 +0200934 msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM,
935 SIMTRACE_MSGT_BD_CEMU_STATUS);
Harald Welte8e7fca32017-05-07 16:14:33 +0200936 if (!msg)
Harald Welteff160652016-03-19 21:59:06 +0100937 return;
Harald Welte8e7fca32017-05-07 16:14:33 +0200938
Harald Welte25a9a802017-05-08 13:30:09 +0200939 sts = (struct cardemu_usb_msg_status *) msgb_put(msg, sizeof(*sts));
Harald Welteff160652016-03-19 21:59:06 +0100940 sts->flags = 0;
941 if (ch->vcc_active)
942 sts->flags |= CEMU_STATUS_F_VCC_PRESENT;
943 if (ch->clocked)
944 sts->flags |= CEMU_STATUS_F_CLK_ACTIVE;
945 if (ch->in_reset)
946 sts->flags |= CEMU_STATUS_F_RESET_ACTIVE;
947 /* FIXME: voltage + card insert */
948 sts->fi = ch->fi;
949 sts->di = ch->di;
950 sts->wi = ch->wi;
951 sts->waiting_time = ch->waiting_time;
952
Harald Welte25a9a802017-05-08 13:30:09 +0200953 usb_buf_upd_len_and_submit(msg);
Harald Welteff160652016-03-19 21:59:06 +0100954}
955
Harald Welte9d3e3822015-11-09 00:50:54 +0100956/* hardware driver informs us that a card I/O signal has changed */
957void card_emu_io_statechg(struct card_handle *ch, enum card_io io, int active)
958{
959 switch (io) {
960 case CARD_IO_VCC:
Harald Welte47ee2832016-02-29 10:09:46 +0100961 if (active == 0 && ch->vcc_active == 1) {
Harald Weltedde112e2016-03-20 16:42:11 +0100962 TRACE_INFO("%u: VCC deactivated\r\n", ch->num);
Harald Welte22cdf2a2016-02-24 22:18:11 +0100963 tc_etu_disable(ch->tc_chan);
Harald Welte9d3e3822015-11-09 00:50:54 +0100964 card_set_state(ch, ISO_S_WAIT_POWER);
Harald Welte47ee2832016-02-29 10:09:46 +0100965 } else if (active == 1 && ch->vcc_active == 0) {
Harald Weltedde112e2016-03-20 16:42:11 +0100966 TRACE_INFO("%u: VCC activated\r\n", ch->num);
Harald Welte9d3e3822015-11-09 00:50:54 +0100967 card_set_state(ch, ISO_S_WAIT_CLK);
Harald Welte47ee2832016-02-29 10:09:46 +0100968 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100969 ch->vcc_active = active;
970 break;
971 case CARD_IO_CLK:
Harald Welte47ee2832016-02-29 10:09:46 +0100972 if (active == 1 && ch->clocked == 0) {
Harald Weltedde112e2016-03-20 16:42:11 +0100973 TRACE_INFO("%u: CLK activated\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +0100974 if (ch->state == ISO_S_WAIT_CLK)
975 card_set_state(ch, ISO_S_WAIT_RST);
976 } else if (active == 0 && ch->clocked == 1) {
Harald Weltedde112e2016-03-20 16:42:11 +0100977 TRACE_INFO("%u: CLK deactivated\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +0100978 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100979 ch->clocked = active;
980 break;
981 case CARD_IO_RST:
Harald Welte47ee2832016-02-29 10:09:46 +0100982 if (active == 0 && ch->in_reset) {
Harald Weltedde112e2016-03-20 16:42:11 +0100983 TRACE_INFO("%u: RST released\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +0100984 if (ch->vcc_active && ch->clocked) {
985 /* enable the TC/ETU counter once reset has been released */
986 tc_etu_enable(ch->tc_chan);
Kévin Redonebe672e2018-07-29 00:18:12 +0200987 /* prepare to send the ATR */
Harald Welte47ee2832016-02-29 10:09:46 +0100988 card_set_state(ch, ISO_S_WAIT_ATR);
Harald Welte47ee2832016-02-29 10:09:46 +0100989 }
990 } else if (active && !ch->in_reset) {
Harald Weltedde112e2016-03-20 16:42:11 +0100991 TRACE_INFO("%u: RST asserted\r\n", ch->num);
Harald Welte22cdf2a2016-02-24 22:18:11 +0100992 tc_etu_disable(ch->tc_chan);
Harald Welte9d3e3822015-11-09 00:50:54 +0100993 }
994 ch->in_reset = active;
995 break;
996 }
997}
998
999/* User sets a new ATR to be returned during next card reset */
1000int card_emu_set_atr(struct card_handle *ch, const uint8_t *atr, uint8_t len)
1001{
1002 if (len > sizeof(ch->atr.atr))
1003 return -1;
1004
1005 memcpy(ch->atr.atr, atr, len);
1006 ch->atr.len = len;
1007 ch->atr.idx = 0;
1008
Kévin Redonebe672e2018-07-29 00:18:12 +02001009#if TRACE_LEVEL >= TRACE_LEVEL_INFO
1010 uint8_t i;
1011 TRACE_INFO("%u: ATR set: ", ch->num);
1012 for (i = 0; i < ch->atr.len; i++) {
1013 TRACE_INFO_WP("%02x ", atr[i]);
1014 }
1015 TRACE_INFO_WP("\n\r");
1016#endif
1017 /* FIXME: race condition with transmitting ATR to reader? */
Harald Welte9d3e3822015-11-09 00:50:54 +01001018
1019 return 0;
1020}
1021
1022/* hardware driver informs us that one (more) ETU has expired */
1023void tc_etu_wtime_half_expired(void *handle)
1024{
1025 struct card_handle *ch = handle;
1026 /* transmit NULL procedure byte well before waiting time expires */
Harald Weltedda73552016-03-02 10:29:55 +01001027 switch (ch->state) {
1028 case ISO_S_IN_TPDU:
1029 switch (ch->tpdu.state) {
1030 case TPDU_S_WAIT_PB:
1031 case TPDU_S_WAIT_TX:
1032 putchar('N');
1033 card_emu_uart_tx(ch->uart_chan, ISO7816_3_PB_NULL);
1034 break;
1035 default:
1036 break;
1037 }
1038 break;
1039 default:
1040 break;
1041 }
Harald Welte9d3e3822015-11-09 00:50:54 +01001042}
1043
1044/* hardware driver informs us that one (more) ETU has expired */
1045void tc_etu_wtime_expired(void *handle)
1046{
Harald Weltedde112e2016-03-20 16:42:11 +01001047 struct card_handle *ch = handle;
Kévin Redonebe672e2018-07-29 00:18:12 +02001048 switch (ch->state) {
1049 case ISO_S_WAIT_ATR:
1050 /* ISO 7816-3 6.2.1 time tc has passed, we can now send the ATR */
1051 card_set_state(ch, ISO_S_IN_ATR);
1052 break;
1053 default:
1054 TRACE_ERROR("%u: wtime_exp\r\n", ch->num);
1055 break;
1056 }
Harald Welte9d3e3822015-11-09 00:50:54 +01001057}
1058
1059/* shortest ATR found in smartcard_list.txt */
1060static const uint8_t default_atr[] = { 0x3B, 0x02, 0x14, 0x50 };
1061
1062static struct card_handle card_handles[NUM_SLOTS];
1063
Harald Welte8e7fca32017-05-07 16:14:33 +02001064struct card_handle *card_emu_init(uint8_t slot_num, uint8_t tc_chan, uint8_t uart_chan,
1065 uint8_t in_ep, uint8_t irq_ep)
Harald Welte9d3e3822015-11-09 00:50:54 +01001066{
1067 struct card_handle *ch;
1068
1069 if (slot_num >= ARRAY_SIZE(card_handles))
1070 return NULL;
1071
1072 ch = &card_handles[slot_num];
1073
1074 memset(ch, 0, sizeof(*ch));
1075
Harald Welte54cb3d02016-02-29 14:12:40 +01001076 INIT_LLIST_HEAD(&ch->uart_tx_queue);
1077
Kévin Redon680bdab2018-07-18 14:00:57 +02001078 /* initialize the card_handle with reasonable defaults */
Harald Weltedde112e2016-03-20 16:42:11 +01001079 ch->num = slot_num;
Harald Welte8e7fca32017-05-07 16:14:33 +02001080 ch->irq_ep = irq_ep;
1081 ch->in_ep = in_ep;
Harald Welte9d3e3822015-11-09 00:50:54 +01001082 ch->state = ISO_S_WAIT_POWER;
1083 ch->vcc_active = 0;
1084 ch->in_reset = 1;
1085 ch->clocked = 0;
1086
1087 ch->fi = 0;
1088 ch->di = 1;
1089 ch->wi = ISO7816_3_DEFAULT_WI;
1090
1091 ch->tc_chan = tc_chan;
1092 ch->uart_chan = uart_chan;
1093 ch->waiting_time = ISO7816_3_INIT_WTIME;
1094
1095 ch->atr.idx = 0;
1096 ch->atr.len = sizeof(default_atr);
1097 memcpy(ch->atr.atr, default_atr, ch->atr.len);
1098
1099 ch->pts.state = PTS_S_WAIT_REQ_PTSS;
1100 ch->tpdu.state = TPDU_S_WAIT_CLA;
1101
1102 tc_etu_init(ch->tc_chan, ch);
1103
1104 return ch;
1105}