blob: fa0982938f00138a8c8865e0852e095c16582156 [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 Weltedde112e2016-03-20 16:42:11 +0100115 uint32_t num;
116
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
Harald Welte25a9a802017-05-08 13:30:09 +0200226 usb_buf_upd_len_and_submit(msg);
Harald Welteb5288e82015-11-14 21:15:52 +0100227}
228
Kévin Redon680bdab2018-07-18 14:00:57 +0200229/* convert a non-contiguous PTS request/response into a contiguous
Harald Welte4ba66d02016-02-25 19:38:56 +0100230 * buffer, returning the number of bytes used in the buffer */
231static int serialize_pts(uint8_t *out, const uint8_t *in)
232{
233 int i = 0;
234
235 out[i++] = in[_PTSS];
236 out[i++] = in[_PTS0];
237 if (in[_PTS0] & (1 << 4))
238 out[i++] = in[_PTS1];
239 if (in[_PTS0] & (1 << 5))
240 out[i++] = in[_PTS2];
241 if (in[_PTS0] & (1 << 6))
242 out[i++] = in[_PTS3];
243 out[i++] = in[_PCK];
244
245 return i;
246}
247
Harald Welte17db2f12016-02-26 09:48:57 +0100248static uint8_t csum_pts(const uint8_t *in)
249{
250 uint8_t out[6];
251 int len = serialize_pts(out, in);
252 uint8_t csum = 0;
253 int i;
254
255 /* we don't include the PCK byte in the checksumming process */
256 len -= 1;
257
258 for (i = 0; i < len; i++)
259 csum = csum ^ out[i];
260
261 return csum;
262}
263
Harald Welte4ba66d02016-02-25 19:38:56 +0100264static void flush_pts(struct card_handle *ch)
265{
Harald Welte8e7fca32017-05-07 16:14:33 +0200266 struct msgb *msg;
Harald Welte4ba66d02016-02-25 19:38:56 +0100267 struct cardemu_usb_msg_pts_info *ptsi;
268
Harald Welte25a9a802017-05-08 13:30:09 +0200269 msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_DO_CEMU_PTS);
Harald Welte8e7fca32017-05-07 16:14:33 +0200270 if (!msg)
Harald Welte4ba66d02016-02-25 19:38:56 +0100271 return;
272
Harald Welte25a9a802017-05-08 13:30:09 +0200273 ptsi = (struct cardemu_usb_msg_pts_info *) msgb_put(msg, sizeof(*ptsi));
Harald Welted295b922016-03-18 21:01:36 +0100274 ptsi->pts_len = serialize_pts(ptsi->req, ch->pts.req);
Harald Welte4ba66d02016-02-25 19:38:56 +0100275 serialize_pts(ptsi->resp, ch->pts.resp);
276
Harald Welte25a9a802017-05-08 13:30:09 +0200277 usb_buf_upd_len_and_submit(msg);
Harald Welte4ba66d02016-02-25 19:38:56 +0100278}
279
Harald Welte8c496362016-02-27 16:24:09 +0100280static void emu_update_fidi(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100281{
282 int rc;
283
284 rc = compute_fidi_ratio(ch->fi, ch->di);
285 if (rc > 0 && rc < 0x400) {
Harald Weltedde112e2016-03-20 16:42:11 +0100286 TRACE_INFO("%u: computed Fi(%u) Di(%u) ratio: %d\r\n",
287 ch->num, ch->fi, ch->di, rc);
Harald Welte9d3e3822015-11-09 00:50:54 +0100288 /* make sure UART uses new F/D ratio */
289 card_emu_uart_update_fidi(ch->uart_chan, rc);
290 /* notify ETU timer about this */
291 tc_etu_set_etu(ch->tc_chan, rc);
292 } else
Harald Weltedde112e2016-03-20 16:42:11 +0100293 TRACE_INFO("%u: computed FiDi ration %d unsupported\r\n",
294 ch->num, rc);
Harald Welte9d3e3822015-11-09 00:50:54 +0100295}
296
297/* Update the ISO 7816-3 TPDU receiver state */
298static void card_set_state(struct card_handle *ch,
299 enum iso7816_3_card_state new_state)
300{
Harald Welte903d63a2016-03-20 13:38:39 +0100301 if (ch->state == new_state)
302 return;
303
Kévin Redon8a4fba52018-08-02 17:44:16 +0200304 TRACE_DEBUG("%u: 7816 card state %u (%s) -> %u (%s)\r\n", ch->num,
305 ch->state, get_value_string(iso7816_3_card_state_names, ch->state),
306 new_state, get_value_string(iso7816_3_card_state_names, new_state));
Harald Welte903d63a2016-03-20 13:38:39 +0100307 ch->state = new_state;
308
Harald Welte9d3e3822015-11-09 00:50:54 +0100309 switch (new_state) {
310 case ISO_S_WAIT_POWER:
311 case ISO_S_WAIT_CLK:
312 case ISO_S_WAIT_RST:
313 /* disable Rx and Tx of UART */
314 card_emu_uart_enable(ch->uart_chan, 0);
315 break;
316 case ISO_S_WAIT_ATR:
317 /* Reset to initial Fi / Di ratio */
318 ch->fi = 1;
319 ch->di = 1;
Harald Welte8c496362016-02-27 16:24:09 +0100320 emu_update_fidi(ch);
Kévin Redonebe672e2018-07-29 00:18:12 +0200321 /* the ATR should only be sent 400 to 40k clock cycles after the RESET.
322 * we use the tc_etu mechanism to wait this time.
323 * since the initial ETU is Fd=372/Dd=1 clock cycles long, we have to wait 2-107 ETU.
324 */
325 tc_etu_set_wtime(ch->tc_chan, 2);
326 /* ensure the TC_ETU timer is enabled */
327 tc_etu_enable(ch->tc_chan);
328 break;
329 case ISO_S_IN_ATR:
Kévin Redon680bdab2018-07-18 14:00:57 +0200330 /* initialize to default WI, this will be overwritten if we
Kévin Redonebe672e2018-07-29 00:18:12 +0200331 * send TC2, and it will be programmed into hardware after
Harald Welte9d3e3822015-11-09 00:50:54 +0100332 * ATR is finished */
333 ch->wi = ISO7816_3_DEFAULT_WI;
334 /* update waiting time to initial waiting time */
335 ch->waiting_time = ISO7816_3_INIT_WTIME;
Kévin Redonebe672e2018-07-29 00:18:12 +0200336 /* set initial waiting time */
Harald Welte9d3e3822015-11-09 00:50:54 +0100337 tc_etu_set_wtime(ch->tc_chan, ch->waiting_time);
338 /* Set ATR sub-state to initial state */
339 ch->atr.idx = 0;
Kévin Redonebe672e2018-07-29 00:18:12 +0200340 /* enable USART transmission to reader */
Harald Welte9d3e3822015-11-09 00:50:54 +0100341 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
Kévin Redonebe672e2018-07-29 00:18:12 +0200342 /* trigger USART TX IRQ to sent first ATR byte TS */
343 card_emu_uart_interrupt(ch->uart_chan);
Harald Welte9d3e3822015-11-09 00:50:54 +0100344 break;
345 case ISO_S_WAIT_TPDU:
346 /* enable the receiver, disable transmitter */
Harald Welte2935b3c2015-11-14 20:00:14 +0100347 set_tpdu_state(ch, TPDU_S_WAIT_CLA);
Harald Welte9d3e3822015-11-09 00:50:54 +0100348 card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
349 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100350 case ISO_S_IN_PTS:
351 case ISO_S_IN_TPDU:
352 /* do nothing */
353 break;
354 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100355}
356
Kévin Redonebe672e2018-07-29 00:18:12 +0200357/**********************************************************************
358 * ATR handling
359 **********************************************************************/
360
361/*! Transmit ATR data to reader
362 * @param[in] ch card interface connected to reader
363 * @return numbers of bytes transmitted
364 */
365static int tx_byte_atr(struct card_handle *ch)
366{
367 if (NULL == ch) {
368 TRACE_ERROR("ATR TX: no card handle provided\n\r");
369 return 0;
370 }
371 if (ISO_S_IN_ATR != ch->state) {
372 TRACE_ERROR("%u: ATR TX: no in ATR state\n\r", ch->num);
373 return 0;
374 }
375
376 /* Transmit ATR */
377 if (ch->atr.idx < ch->atr.len) {
378 uint8_t byte = ch->atr.atr[ch->atr.idx++];
379 card_emu_uart_tx(ch->uart_chan, byte);
Kévin Redonebe672e2018-07-29 00:18:12 +0200380 return 1;
381 } else { /* The ATR has been completely transmitted */
Kévin Redon8b8e58b2018-07-30 18:19:11 +0200382 /* search for TC2 to updated WI */
383 ch->wi = ISO7816_3_DEFAULT_WI;
384 if (ch->atr.len >= 2 && ch->atr.atr[1] & 0xf0) { /* Y1 has some data */
385 uint8_t atr_td1 = 2;
386 if (ch->atr.atr[1] & 0x10) { /* TA1 is present */
387 atr_td1++;
388 }
389 if (ch->atr.atr[1] & 0x20) { /* TB1 is present */
390 atr_td1++;
391 }
392 if (ch->atr.atr[1] & 0x40) { /* TC1 is present */
393 atr_td1++;
394 }
395 if (ch->atr.atr[1] & 0x80) { /* TD1 is present */
396 if (ch->atr.len > atr_td1 && ch->atr.atr[atr_td1] & 0xf0) { /* Y2 has some data */
397 uint8_t atr_tc2 = atr_td1+1;
398 if (ch->atr.atr[atr_td1] & 0x10) { /* TA2 is present */
399 atr_tc2++;
400 }
401 if (ch->atr.atr[atr_td1] & 0x20) { /* TB2 is present */
402 atr_tc2++;
403 }
404 if (ch->atr.atr[atr_td1] & 0x40) { /* TC2 is present */
405 if (ch->atr.len > atr_tc2 && ch->atr.atr[atr_tc2]) { /* TC2 encodes WI */
406 ch->wi = ch->atr.atr[atr_tc2]; /* set WI */
407 }
408 }
409 }
410 }
411 }
412 /* update waiting time (see ISO 7816-3 10.2) */
413 ch->waiting_time = ch->wi * 960 * ch->fi;
414 tc_etu_set_wtime(ch->tc_chan, ch->waiting_time);
Kévin Redonebe672e2018-07-29 00:18:12 +0200415 /* reset PTS to initial state */
416 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
417 /* go to next state */
418 card_set_state(ch, ISO_S_WAIT_TPDU);
419 return 0;
420 }
421
422 /* return number of bytes transmitted */
423 return 1;
424}
Harald Welte9d3e3822015-11-09 00:50:54 +0100425
426/**********************************************************************
427 * PTS / PPS handling
428 **********************************************************************/
429
Kévin Redon680bdab2018-07-18 14:00:57 +0200430/* Update the PTS sub-state */
Harald Welte9d3e3822015-11-09 00:50:54 +0100431static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss)
432{
Harald Weltedde112e2016-03-20 16:42:11 +0100433 TRACE_DEBUG("%u: 7816 PTS state %u -> %u\r\n",
434 ch->num, ch->pts.state, new_ptss);
Harald Welte9d3e3822015-11-09 00:50:54 +0100435 ch->pts.state = new_ptss;
436}
437
438/* Determine the next PTS state */
439static enum pts_state next_pts_state(struct card_handle *ch)
440{
441 uint8_t is_resp = ch->pts.state & 0x10;
442 uint8_t sstate = ch->pts.state & 0x0f;
443 uint8_t *pts_ptr;
444
445 if (!is_resp)
446 pts_ptr = ch->pts.req;
447 else
448 pts_ptr = ch->pts.resp;
449
450 switch (sstate) {
451 case PTS_S_WAIT_REQ_PTSS:
452 goto from_ptss;
453 case PTS_S_WAIT_REQ_PTS0:
454 goto from_pts0;
455 case PTS_S_WAIT_REQ_PTS1:
456 goto from_pts1;
457 case PTS_S_WAIT_REQ_PTS2:
458 goto from_pts2;
459 case PTS_S_WAIT_REQ_PTS3:
460 goto from_pts3;
461 }
462
463 if (ch->pts.state == PTS_S_WAIT_REQ_PCK)
464 return PTS_S_WAIT_RESP_PTSS;
465
466from_ptss:
467 return PTS_S_WAIT_REQ_PTS0 | is_resp;
468from_pts0:
469 if (pts_ptr[_PTS0] & (1 << 4))
470 return PTS_S_WAIT_REQ_PTS1 | is_resp;
471from_pts1:
472 if (pts_ptr[_PTS0] & (1 << 5))
473 return PTS_S_WAIT_REQ_PTS2 | is_resp;
474from_pts2:
475 if (pts_ptr[_PTS0] & (1 << 6))
476 return PTS_S_WAIT_REQ_PTS3 | is_resp;
477from_pts3:
478 return PTS_S_WAIT_REQ_PCK | is_resp;
479}
480
481
Harald Welteccb8a222016-03-20 13:37:11 +0100482static int
Harald Welte9d3e3822015-11-09 00:50:54 +0100483process_byte_pts(struct card_handle *ch, uint8_t byte)
484{
485 switch (ch->pts.state) {
486 case PTS_S_WAIT_REQ_PTSS:
487 ch->pts.req[_PTSS] = byte;
488 break;
489 case PTS_S_WAIT_REQ_PTS0:
490 ch->pts.req[_PTS0] = byte;
491 break;
492 case PTS_S_WAIT_REQ_PTS1:
493 ch->pts.req[_PTS1] = byte;
494 break;
495 case PTS_S_WAIT_REQ_PTS2:
496 ch->pts.req[_PTS2] = byte;
497 break;
498 case PTS_S_WAIT_REQ_PTS3:
499 ch->pts.req[_PTS3] = byte;
500 break;
501 case PTS_S_WAIT_REQ_PCK:
502 ch->pts.req[_PCK] = byte;
Harald Welte17db2f12016-02-26 09:48:57 +0100503 if (ch->pts.req[_PCK] != csum_pts(ch->pts.req)) {
Harald Weltedde112e2016-03-20 16:42:11 +0100504 TRACE_ERROR("%u: Error in PTS Checksum!\r\n",
505 ch->num);
Harald Welte17db2f12016-02-26 09:48:57 +0100506 /* Wait for the next TPDU */
507 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
508 return ISO_S_WAIT_TPDU;
509 }
Harald Welte4ba66d02016-02-25 19:38:56 +0100510 /* FIXME: check if proposal matches capabilities in ATR */
Harald Welte9d3e3822015-11-09 00:50:54 +0100511 memcpy(ch->pts.resp, ch->pts.req, sizeof(ch->pts.resp));
512 break;
Harald Welte4c473da2015-11-14 13:31:11 +0100513 default:
Harald Weltedde112e2016-03-20 16:42:11 +0100514 TRACE_ERROR("%u: process_byte_pts() in invalid state %u\r\n",
515 ch->num, ch->pts.state);
Harald Welte4c473da2015-11-14 13:31:11 +0100516 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100517 }
518 /* calculate the next state and set it */
519 set_pts_state(ch, next_pts_state(ch));
520
Harald Welte4ba66d02016-02-25 19:38:56 +0100521 if (ch->pts.state == PTS_S_WAIT_RESP_PTSS) {
522 flush_pts(ch);
523 /* activate UART TX to transmit PTS response */
524 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
Harald Welte53079bb2016-03-20 14:58:35 +0100525 /* don't fall-through to the 'return ISO_S_IN_PTS'
526 * below, rather keep ISO7816 state as-is, it will be
527 * further updated by the tx-completion handler */
Harald Welteccb8a222016-03-20 13:37:11 +0100528 return -1;
Harald Welte4ba66d02016-02-25 19:38:56 +0100529 }
530
Harald Welte9d3e3822015-11-09 00:50:54 +0100531 return ISO_S_IN_PTS;
532}
533
534/* return a single byte to be transmitted to the reader */
Harald Welte855ba9e2016-02-24 21:00:46 +0100535static int tx_byte_pts(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100536{
Harald Welte855ba9e2016-02-24 21:00:46 +0100537 uint8_t byte;
538
539 /* 1: Determine the next transmit byte */
Harald Welte9d3e3822015-11-09 00:50:54 +0100540 switch (ch->pts.state) {
541 case PTS_S_WAIT_RESP_PTSS:
Harald Welte855ba9e2016-02-24 21:00:46 +0100542 byte = ch->pts.resp[_PTSS];
Harald Welte9d3e3822015-11-09 00:50:54 +0100543 break;
544 case PTS_S_WAIT_RESP_PTS0:
Harald Welte855ba9e2016-02-24 21:00:46 +0100545 byte = ch->pts.resp[_PTS0];
Harald Welte9d3e3822015-11-09 00:50:54 +0100546 break;
547 case PTS_S_WAIT_RESP_PTS1:
Harald Welte855ba9e2016-02-24 21:00:46 +0100548 byte = ch->pts.resp[_PTS1];
Harald Welte9d3e3822015-11-09 00:50:54 +0100549 /* This must be TA1 */
Harald Welte855ba9e2016-02-24 21:00:46 +0100550 ch->fi = byte >> 4;
551 ch->di = byte & 0xf;
Harald Weltedde112e2016-03-20 16:42:11 +0100552 TRACE_DEBUG("%u: found Fi=%u Di=%u\r\n", ch->num,
553 ch->fi, ch->di);
Harald Welte9d3e3822015-11-09 00:50:54 +0100554 break;
555 case PTS_S_WAIT_RESP_PTS2:
Harald Welte855ba9e2016-02-24 21:00:46 +0100556 byte = ch->pts.resp[_PTS2];
Harald Welte9d3e3822015-11-09 00:50:54 +0100557 break;
558 case PTS_S_WAIT_RESP_PTS3:
Harald Welte855ba9e2016-02-24 21:00:46 +0100559 byte = ch->pts.resp[_PTS3];
Harald Welte9d3e3822015-11-09 00:50:54 +0100560 break;
561 case PTS_S_WAIT_RESP_PCK:
Harald Welte855ba9e2016-02-24 21:00:46 +0100562 byte = ch->pts.resp[_PCK];
Harald Welte855ba9e2016-02-24 21:00:46 +0100563 break;
Harald Welted79dc4f2015-11-14 13:32:21 +0100564 default:
Harald Weltedde112e2016-03-20 16:42:11 +0100565 TRACE_ERROR("%u: get_byte_pts() in invalid state %u\r\n",
566 ch->num, ch->pts.state);
Harald Welte855ba9e2016-02-24 21:00:46 +0100567 return 0;
568 }
569
570 /* 2: Transmit the byte */
571 card_emu_uart_tx(ch->uart_chan, byte);
572
573 /* 3: Update the state */
574
575 switch (ch->pts.state) {
576 case PTS_S_WAIT_RESP_PCK:
Harald Weltec58bba02016-03-20 14:57:53 +0100577 card_emu_uart_wait_tx_idle(ch->uart_chan);
Harald Welte52d55462016-03-20 13:38:05 +0100578 /* update baud rate generator with Fi/Di */
579 emu_update_fidi(ch);
Harald Welte855ba9e2016-02-24 21:00:46 +0100580 /* Wait for the next TPDU */
581 card_set_state(ch, ISO_S_WAIT_TPDU);
582 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
583 break;
584 default:
585 /* calculate the next state and set it */
586 set_pts_state(ch, next_pts_state(ch));
Harald Welted79dc4f2015-11-14 13:32:21 +0100587 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100588 }
Harald Welted79dc4f2015-11-14 13:32:21 +0100589
Harald Welte855ba9e2016-02-24 21:00:46 +0100590 /* return number of bytes transmitted */
591 return 1;
Harald Welte9d3e3822015-11-09 00:50:54 +0100592}
593
594
595/**********************************************************************
596 * TPDU handling
597 **********************************************************************/
598
Harald Welte4d804672015-11-14 23:02:38 +0100599
600/* compute number of data bytes according to Chapter 10.3.2 of 7816-3 */
601static unsigned int t0_num_data_bytes(uint8_t p3, int reader_to_card)
602{
603 if (reader_to_card) {
604 return p3;
605 } else {
606 if (p3 == 0)
607 return 256;
608 else
609 return p3;
610 }
611}
612
Harald Welte9d3e3822015-11-09 00:50:54 +0100613/* add a just-received TPDU byte (from reader) to USB buffer */
Harald Welte61bb30e2015-11-14 23:44:14 +0100614static void add_tpdu_byte(struct card_handle *ch, uint8_t byte)
Harald Welte9d3e3822015-11-09 00:50:54 +0100615{
Harald Welte8e7fca32017-05-07 16:14:33 +0200616 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100617 struct cardemu_usb_msg_rx_data *rd;
Harald Welte4d804672015-11-14 23:02:38 +0100618 unsigned int num_data_bytes = t0_num_data_bytes(ch->tpdu.hdr[_P3], 0);
Harald Welte9d3e3822015-11-09 00:50:54 +0100619
620 /* ensure we have a buffer */
Harald Welte8e7fca32017-05-07 16:14:33 +0200621 if (!ch->uart_rx_msg) {
Harald Welte25a9a802017-05-08 13:30:09 +0200622 msg = ch->uart_rx_msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM,
623 SIMTRACE_MSGT_DO_CEMU_RX_DATA);
Harald Welte8e7fca32017-05-07 16:14:33 +0200624 if (!ch->uart_rx_msg) {
Harald Weltedde112e2016-03-20 16:42:11 +0100625 TRACE_ERROR("%u: Received UART byte but ENOMEM\r\n",
626 ch->num);
Harald Welte9d3e3822015-11-09 00:50:54 +0100627 return;
Harald Welte4d804672015-11-14 23:02:38 +0100628 }
Harald Welte25a9a802017-05-08 13:30:09 +0200629 msgb_put(msg, sizeof(*rd));
Harald Welte9d3e3822015-11-09 00:50:54 +0100630 } else
Harald Welte8e7fca32017-05-07 16:14:33 +0200631 msg = ch->uart_rx_msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100632
Harald Welte25a9a802017-05-08 13:30:09 +0200633 rd = (struct cardemu_usb_msg_rx_data *) msg->l2h;
Harald Welte8e7fca32017-05-07 16:14:33 +0200634 msgb_put_u8(msg, byte);
Harald Welte9d3e3822015-11-09 00:50:54 +0100635
636 /* check if the buffer is full. If so, send it */
Harald Welte25a9a802017-05-08 13:30:09 +0200637 if (msgb_l2len(msg) >= sizeof(*rd) + num_data_bytes) {
Harald Welte4d804672015-11-14 23:02:38 +0100638 rd->flags |= CEMU_DATA_F_FINAL;
Harald Welteb5288e82015-11-14 21:15:52 +0100639 flush_rx_buffer(ch);
Harald Welte61bb30e2015-11-14 23:44:14 +0100640 /* We need to transmit the SW now, */
641 set_tpdu_state(ch, TPDU_S_WAIT_TX);
Harald Welte8e7fca32017-05-07 16:14:33 +0200642 } else if (msgb_tailroom(msg) <= 0)
Harald Welte4d804672015-11-14 23:02:38 +0100643 flush_rx_buffer(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100644}
645
646static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts)
647{
Harald Welte05b41c62015-11-14 20:58:48 +0100648 if (ch->tpdu.state == new_ts)
649 return;
650
Harald Weltedde112e2016-03-20 16:42:11 +0100651 TRACE_DEBUG("%u: 7816 TPDU state %u -> %u\r\n", ch->num,
652 ch->tpdu.state, new_ts);
Harald Welte05b41c62015-11-14 20:58:48 +0100653
Harald Welte903d63a2016-03-20 13:38:39 +0100654 ch->tpdu.state = new_ts;
655
Harald Welte9d3e3822015-11-09 00:50:54 +0100656 switch (new_ts) {
657 case TPDU_S_WAIT_CLA:
Harald Welte05b41c62015-11-14 20:58:48 +0100658 case TPDU_S_WAIT_RX:
Harald Welte9d3e3822015-11-09 00:50:54 +0100659 card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
660 break;
661 case TPDU_S_WAIT_PB:
662 /* we just completed the TPDU header from reader to card
663 * and now need to disable the receiver, enable the
664 * transmitter and transmit the procedure byte */
665 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
666 break;
Harald Weltead434402016-03-02 11:18:29 +0100667 default:
668 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100669 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100670}
671
672static enum tpdu_state next_tpdu_state(struct card_handle *ch)
673{
674 switch (ch->tpdu.state) {
675 case TPDU_S_WAIT_CLA:
676 return TPDU_S_WAIT_INS;
677 case TPDU_S_WAIT_INS:
678 return TPDU_S_WAIT_P1;
679 case TPDU_S_WAIT_P1:
680 return TPDU_S_WAIT_P2;
681 case TPDU_S_WAIT_P2:
682 return TPDU_S_WAIT_P3;
683 case TPDU_S_WAIT_P3:
684 return TPDU_S_WAIT_PB;
685 /* simply stay in Rx or Tx by default */
686 case TPDU_S_WAIT_PB:
687 return TPDU_S_WAIT_PB;
688 case TPDU_S_WAIT_RX:
689 return TPDU_S_WAIT_RX;
690 case TPDU_S_WAIT_TX:
691 return TPDU_S_WAIT_TX;
692 }
Harald Welte4c473da2015-11-14 13:31:11 +0100693 /* we should never reach here */
694 assert(0);
695 return -1;
Harald Welte9d3e3822015-11-09 00:50:54 +0100696}
697
698static void send_tpdu_header(struct card_handle *ch)
699{
Harald Welte8e7fca32017-05-07 16:14:33 +0200700 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100701 struct cardemu_usb_msg_rx_data *rd;
Harald Welte8e7fca32017-05-07 16:14:33 +0200702 uint8_t *cur;
Harald Welte9d3e3822015-11-09 00:50:54 +0100703
Harald Weltedde112e2016-03-20 16:42:11 +0100704 TRACE_INFO("%u: %s: %02x %02x %02x %02x %02x\r\n",
705 ch->num, __func__,
Harald Welte43f79492016-02-29 10:06:54 +0100706 ch->tpdu.hdr[0], ch->tpdu.hdr[1],
707 ch->tpdu.hdr[2], ch->tpdu.hdr[3],
708 ch->tpdu.hdr[4]);
709
Harald Welte9d3e3822015-11-09 00:50:54 +0100710 /* if we already/still have a context, send it off */
Harald Welte8e7fca32017-05-07 16:14:33 +0200711 if (ch->uart_rx_msg) {
Harald Weltedde112e2016-03-20 16:42:11 +0100712 TRACE_DEBUG("%u: have old buffer\r\n", ch->num);
Harald Welte8e7fca32017-05-07 16:14:33 +0200713 if (msgb_l2len(ch->uart_rx_msg)) {
Harald Weltedde112e2016-03-20 16:42:11 +0100714 TRACE_DEBUG("%u: flushing old buffer\r\n", ch->num);
Harald Weltef1697e22016-03-02 10:28:54 +0100715 flush_rx_buffer(ch);
716 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100717 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200718 TRACE_DEBUG("%u: allocating new buffer\r\n", ch->num);
719 /* ensure we have a new buffer */
Harald Welte25a9a802017-05-08 13:30:09 +0200720 ch->uart_rx_msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM,
721 SIMTRACE_MSGT_DO_CEMU_RX_DATA);
Harald Welte8e7fca32017-05-07 16:14:33 +0200722 if (!ch->uart_rx_msg) {
723 TRACE_ERROR("%u: %s: ENOMEM\r\n", ch->num, __func__);
724 return;
725 }
726 msg = ch->uart_rx_msg;
Harald Welte25a9a802017-05-08 13:30:09 +0200727 rd = (struct cardemu_usb_msg_rx_data *) msgb_put(msg, sizeof(*rd));
Harald Welte9d3e3822015-11-09 00:50:54 +0100728
Harald Welte8e7fca32017-05-07 16:14:33 +0200729 /* initialize header */
Harald Welte9d3e3822015-11-09 00:50:54 +0100730 rd->flags = CEMU_DATA_F_TPDU_HDR;
Harald Welte9d3e3822015-11-09 00:50:54 +0100731
732 /* copy TPDU header to data field */
Harald Welte8e7fca32017-05-07 16:14:33 +0200733 cur = msgb_put(msg, sizeof(ch->tpdu.hdr));
734 memcpy(cur, ch->tpdu.hdr, sizeof(ch->tpdu.hdr));
Harald Welteb5288e82015-11-14 21:15:52 +0100735 /* rd->data_len is set in flush_rx_buffer() */
Harald Welte9d3e3822015-11-09 00:50:54 +0100736
Harald Welteb5288e82015-11-14 21:15:52 +0100737 flush_rx_buffer(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100738}
739
740static enum iso7816_3_card_state
741process_byte_tpdu(struct card_handle *ch, uint8_t byte)
742{
743 switch (ch->tpdu.state) {
744 case TPDU_S_WAIT_CLA:
745 ch->tpdu.hdr[_CLA] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100746 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100747 break;
748 case TPDU_S_WAIT_INS:
749 ch->tpdu.hdr[_INS] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100750 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100751 break;
752 case TPDU_S_WAIT_P1:
753 ch->tpdu.hdr[_P1] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100754 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100755 break;
756 case TPDU_S_WAIT_P2:
757 ch->tpdu.hdr[_P2] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100758 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100759 break;
760 case TPDU_S_WAIT_P3:
761 ch->tpdu.hdr[_P3] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100762 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100763 /* FIXME: start timer to transmit further 0x60 */
764 /* send the TPDU header as part of a procedure byte
765 * request to the USB host */
766 send_tpdu_header(ch);
767 break;
768 case TPDU_S_WAIT_RX:
Harald Welte61bb30e2015-11-14 23:44:14 +0100769 add_tpdu_byte(ch, byte);
770 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100771 default:
Harald Weltedde112e2016-03-20 16:42:11 +0100772 TRACE_ERROR("%u: process_byte_tpdu() in invalid state %u\r\n",
773 ch->num, ch->tpdu.state);
Harald Welte9d3e3822015-11-09 00:50:54 +0100774 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100775
776 /* ensure we stay in TPDU ISO state */
777 return ISO_S_IN_TPDU;
778}
779
Harald Welte855ba9e2016-02-24 21:00:46 +0100780/* tx a single byte to be transmitted to the reader */
781static int tx_byte_tpdu(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100782{
Harald Welte8e7fca32017-05-07 16:14:33 +0200783 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100784 struct cardemu_usb_msg_tx_data *td;
Harald Welte855ba9e2016-02-24 21:00:46 +0100785 uint8_t byte;
Harald Welte9d3e3822015-11-09 00:50:54 +0100786
787 /* ensure we are aware of any data that might be pending for
788 * transmit */
Harald Welte8e7fca32017-05-07 16:14:33 +0200789 if (!ch->uart_tx_msg) {
Harald Welte53079bb2016-03-20 14:58:35 +0100790 /* uart_tx_queue is filled from main loop, so no need
791 * for irq-safe operations */
Harald Welte54cb3d02016-02-29 14:12:40 +0100792 if (llist_empty(&ch->uart_tx_queue))
Harald Welte9d3e3822015-11-09 00:50:54 +0100793 return 0;
794
Harald Welte54cb3d02016-02-29 14:12:40 +0100795 /* dequeue first at head */
Harald Welte8e7fca32017-05-07 16:14:33 +0200796 ch->uart_tx_msg = msgb_dequeue(&ch->uart_tx_queue);
Harald Welte25a9a802017-05-08 13:30:09 +0200797 ch->uart_tx_msg->l1h = ch->uart_tx_msg->head;
798 ch->uart_tx_msg->l2h = ch->uart_tx_msg->l1h + sizeof(struct simtrace_msg_hdr);
Harald Welte8e7fca32017-05-07 16:14:33 +0200799 msg = ch->uart_tx_msg;
Harald Welte25a9a802017-05-08 13:30:09 +0200800 /* remove the header */
801 msgb_pull(msg, sizeof(struct simtrace_msg_hdr) + sizeof(*td));
Harald Welte9d3e3822015-11-09 00:50:54 +0100802 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200803 msg = ch->uart_tx_msg;
Harald Welte25a9a802017-05-08 13:30:09 +0200804 td = (struct cardemu_usb_msg_tx_data *) msg->l2h;
Harald Welte9d3e3822015-11-09 00:50:54 +0100805
Harald Welte8e7fca32017-05-07 16:14:33 +0200806 /* take the next pending byte out of the msgb */
807 byte = msgb_pull_u8(msg);
Harald Welte855ba9e2016-02-24 21:00:46 +0100808
809 card_emu_uart_tx(ch->uart_chan, byte);
Harald Welte9d3e3822015-11-09 00:50:54 +0100810
Kévin Redon0f4abf52018-08-02 17:42:48 +0200811 /* this must happen _after_ the byte has been transmitted */
Harald Weltef16b6182016-02-24 22:18:46 +0100812 switch (ch->tpdu.state) {
813 case TPDU_S_WAIT_PB:
814 /* if we just transmitted the procedure byte, we need to decide
815 * if we want to continue to receive or transmit */
816 if (td->flags & CEMU_DATA_F_PB_AND_TX)
817 set_tpdu_state(ch, TPDU_S_WAIT_TX);
818 else if (td->flags & CEMU_DATA_F_PB_AND_RX)
819 set_tpdu_state(ch, TPDU_S_WAIT_RX);
820 break;
Harald Weltead434402016-03-02 11:18:29 +0100821 default:
822 break;
Harald Weltef16b6182016-02-24 22:18:46 +0100823 }
824
Harald Welte9d3e3822015-11-09 00:50:54 +0100825 /* check if the buffer has now been fully transmitted */
Harald Welte8e7fca32017-05-07 16:14:33 +0200826 if (msgb_length(msg) == 0) {
Harald Welte52922ff2015-11-14 20:59:56 +0100827 if (td->flags & CEMU_DATA_F_PB_AND_RX) {
828 /* we have just sent the procedure byte and now
829 * need to continue receiving */
830 set_tpdu_state(ch, TPDU_S_WAIT_RX);
Harald Welte2935b3c2015-11-14 20:00:14 +0100831 } else {
Harald Welte52922ff2015-11-14 20:59:56 +0100832 /* we have transmitted all bytes */
833 if (td->flags & CEMU_DATA_F_FINAL) {
834 /* this was the final part of the APDU, go
Harald Welte53079bb2016-03-20 14:58:35 +0100835 * back to state one */
Harald Welte52922ff2015-11-14 20:59:56 +0100836 card_set_state(ch, ISO_S_WAIT_TPDU);
Harald Welte52922ff2015-11-14 20:59:56 +0100837 }
Harald Welte2935b3c2015-11-14 20:00:14 +0100838 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200839 usb_buf_free(msg);
840 ch->uart_tx_msg = NULL;
Harald Welte9d3e3822015-11-09 00:50:54 +0100841 }
842
843 return 1;
844}
845
846/**********************************************************************
847 * Public API
848 **********************************************************************/
849
850/* process a single byte received from the reader */
851void card_emu_process_rx_byte(struct card_handle *ch, uint8_t byte)
852{
853 int new_state = -1;
854
855 ch->stats.rx_bytes++;
856
857 switch (ch->state) {
Harald Welte9d3e3822015-11-09 00:50:54 +0100858 case ISO_S_WAIT_TPDU:
859 if (byte == 0xff) {
860 new_state = process_byte_pts(ch, byte);
861 ch->stats.pps++;
862 goto out_silent;
863 }
864 /* fall-through */
865 case ISO_S_IN_TPDU:
866 new_state = process_byte_tpdu(ch, byte);
867 break;
868 case ISO_S_IN_PTS:
869 new_state = process_byte_pts(ch, byte);
870 goto out_silent;
Kévin Redon5f6b8712018-07-11 09:49:06 +0200871 default:
872 TRACE_ERROR("%u: Received UART char in invalid 7816 state "
873 "%u\r\n", ch->num, ch->state);
874 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100875 }
876
877out_silent:
878 if (new_state != -1)
879 card_set_state(ch, new_state);
880}
881
Harald Welte855ba9e2016-02-24 21:00:46 +0100882/* transmit a single byte to the reader */
883int card_emu_tx_byte(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100884{
885 int rc = 0;
886
887 switch (ch->state) {
888 case ISO_S_IN_ATR:
Kévin Redonebe672e2018-07-29 00:18:12 +0200889 rc = tx_byte_atr(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100890 break;
891 case ISO_S_IN_PTS:
Harald Welte855ba9e2016-02-24 21:00:46 +0100892 rc = tx_byte_pts(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100893 break;
894 case ISO_S_IN_TPDU:
Harald Welte855ba9e2016-02-24 21:00:46 +0100895 rc = tx_byte_tpdu(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100896 break;
Harald Weltead434402016-03-02 11:18:29 +0100897 default:
898 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100899 }
900
901 if (rc)
902 ch->stats.tx_bytes++;
903
Harald Welte4d804672015-11-14 23:02:38 +0100904 /* if we return 0 here, the UART needs to disable transmit-ready
905 * interrupts */
Harald Welte9d3e3822015-11-09 00:50:54 +0100906 return rc;
907}
908
Harald Welteacae4122016-03-02 10:27:58 +0100909void card_emu_have_new_uart_tx(struct card_handle *ch)
910{
911 switch (ch->state) {
912 case ISO_S_IN_TPDU:
913 switch (ch->tpdu.state) {
914 case TPDU_S_WAIT_TX:
915 case TPDU_S_WAIT_PB:
916 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
917 break;
918 default:
919 break;
920 }
921 default:
922 break;
923 }
924}
925
Harald Welteff160652016-03-19 21:59:06 +0100926void card_emu_report_status(struct card_handle *ch)
927{
Harald Welte8e7fca32017-05-07 16:14:33 +0200928 struct msgb *msg;
Harald Welteff160652016-03-19 21:59:06 +0100929 struct cardemu_usb_msg_status *sts;
930
Harald Welte25a9a802017-05-08 13:30:09 +0200931 msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM,
932 SIMTRACE_MSGT_BD_CEMU_STATUS);
Harald Welte8e7fca32017-05-07 16:14:33 +0200933 if (!msg)
Harald Welteff160652016-03-19 21:59:06 +0100934 return;
Harald Welte8e7fca32017-05-07 16:14:33 +0200935
Harald Welte25a9a802017-05-08 13:30:09 +0200936 sts = (struct cardemu_usb_msg_status *) msgb_put(msg, sizeof(*sts));
Harald Welteff160652016-03-19 21:59:06 +0100937 sts->flags = 0;
938 if (ch->vcc_active)
939 sts->flags |= CEMU_STATUS_F_VCC_PRESENT;
940 if (ch->clocked)
941 sts->flags |= CEMU_STATUS_F_CLK_ACTIVE;
942 if (ch->in_reset)
943 sts->flags |= CEMU_STATUS_F_RESET_ACTIVE;
944 /* FIXME: voltage + card insert */
945 sts->fi = ch->fi;
946 sts->di = ch->di;
947 sts->wi = ch->wi;
948 sts->waiting_time = ch->waiting_time;
949
Harald Welte25a9a802017-05-08 13:30:09 +0200950 usb_buf_upd_len_and_submit(msg);
Harald Welteff160652016-03-19 21:59:06 +0100951}
952
Harald Welte9d3e3822015-11-09 00:50:54 +0100953/* hardware driver informs us that a card I/O signal has changed */
954void card_emu_io_statechg(struct card_handle *ch, enum card_io io, int active)
955{
956 switch (io) {
957 case CARD_IO_VCC:
Harald Welte47ee2832016-02-29 10:09:46 +0100958 if (active == 0 && ch->vcc_active == 1) {
Harald Weltedde112e2016-03-20 16:42:11 +0100959 TRACE_INFO("%u: VCC deactivated\r\n", ch->num);
Harald Welte22cdf2a2016-02-24 22:18:11 +0100960 tc_etu_disable(ch->tc_chan);
Harald Welte9d3e3822015-11-09 00:50:54 +0100961 card_set_state(ch, ISO_S_WAIT_POWER);
Harald Welte47ee2832016-02-29 10:09:46 +0100962 } else if (active == 1 && ch->vcc_active == 0) {
Harald Weltedde112e2016-03-20 16:42:11 +0100963 TRACE_INFO("%u: VCC activated\r\n", ch->num);
Harald Welte9d3e3822015-11-09 00:50:54 +0100964 card_set_state(ch, ISO_S_WAIT_CLK);
Harald Welte47ee2832016-02-29 10:09:46 +0100965 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100966 ch->vcc_active = active;
967 break;
968 case CARD_IO_CLK:
Harald Welte47ee2832016-02-29 10:09:46 +0100969 if (active == 1 && ch->clocked == 0) {
Harald Weltedde112e2016-03-20 16:42:11 +0100970 TRACE_INFO("%u: CLK activated\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +0100971 if (ch->state == ISO_S_WAIT_CLK)
972 card_set_state(ch, ISO_S_WAIT_RST);
973 } else if (active == 0 && ch->clocked == 1) {
Harald Weltedde112e2016-03-20 16:42:11 +0100974 TRACE_INFO("%u: CLK deactivated\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +0100975 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100976 ch->clocked = active;
977 break;
978 case CARD_IO_RST:
Harald Welte47ee2832016-02-29 10:09:46 +0100979 if (active == 0 && ch->in_reset) {
Harald Weltedde112e2016-03-20 16:42:11 +0100980 TRACE_INFO("%u: RST released\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +0100981 if (ch->vcc_active && ch->clocked) {
982 /* enable the TC/ETU counter once reset has been released */
983 tc_etu_enable(ch->tc_chan);
Kévin Redonebe672e2018-07-29 00:18:12 +0200984 /* prepare to send the ATR */
Harald Welte47ee2832016-02-29 10:09:46 +0100985 card_set_state(ch, ISO_S_WAIT_ATR);
Harald Welte47ee2832016-02-29 10:09:46 +0100986 }
987 } else if (active && !ch->in_reset) {
Harald Weltedde112e2016-03-20 16:42:11 +0100988 TRACE_INFO("%u: RST asserted\r\n", ch->num);
Harald Welte22cdf2a2016-02-24 22:18:11 +0100989 tc_etu_disable(ch->tc_chan);
Harald Welte9d3e3822015-11-09 00:50:54 +0100990 }
991 ch->in_reset = active;
992 break;
993 }
994}
995
996/* User sets a new ATR to be returned during next card reset */
997int card_emu_set_atr(struct card_handle *ch, const uint8_t *atr, uint8_t len)
998{
999 if (len > sizeof(ch->atr.atr))
1000 return -1;
1001
1002 memcpy(ch->atr.atr, atr, len);
1003 ch->atr.len = len;
1004 ch->atr.idx = 0;
1005
Kévin Redonebe672e2018-07-29 00:18:12 +02001006#if TRACE_LEVEL >= TRACE_LEVEL_INFO
1007 uint8_t i;
1008 TRACE_INFO("%u: ATR set: ", ch->num);
1009 for (i = 0; i < ch->atr.len; i++) {
1010 TRACE_INFO_WP("%02x ", atr[i]);
1011 }
1012 TRACE_INFO_WP("\n\r");
1013#endif
1014 /* FIXME: race condition with transmitting ATR to reader? */
Harald Welte9d3e3822015-11-09 00:50:54 +01001015
1016 return 0;
1017}
1018
1019/* hardware driver informs us that one (more) ETU has expired */
1020void tc_etu_wtime_half_expired(void *handle)
1021{
1022 struct card_handle *ch = handle;
1023 /* transmit NULL procedure byte well before waiting time expires */
Harald Weltedda73552016-03-02 10:29:55 +01001024 switch (ch->state) {
1025 case ISO_S_IN_TPDU:
1026 switch (ch->tpdu.state) {
1027 case TPDU_S_WAIT_PB:
1028 case TPDU_S_WAIT_TX:
1029 putchar('N');
1030 card_emu_uart_tx(ch->uart_chan, ISO7816_3_PB_NULL);
1031 break;
1032 default:
1033 break;
1034 }
1035 break;
1036 default:
1037 break;
1038 }
Harald Welte9d3e3822015-11-09 00:50:54 +01001039}
1040
1041/* hardware driver informs us that one (more) ETU has expired */
1042void tc_etu_wtime_expired(void *handle)
1043{
Harald Weltedde112e2016-03-20 16:42:11 +01001044 struct card_handle *ch = handle;
Kévin Redonebe672e2018-07-29 00:18:12 +02001045 switch (ch->state) {
1046 case ISO_S_WAIT_ATR:
1047 /* ISO 7816-3 6.2.1 time tc has passed, we can now send the ATR */
1048 card_set_state(ch, ISO_S_IN_ATR);
1049 break;
1050 default:
1051 TRACE_ERROR("%u: wtime_exp\r\n", ch->num);
1052 break;
1053 }
Harald Welte9d3e3822015-11-09 00:50:54 +01001054}
1055
1056/* shortest ATR found in smartcard_list.txt */
1057static const uint8_t default_atr[] = { 0x3B, 0x02, 0x14, 0x50 };
1058
1059static struct card_handle card_handles[NUM_SLOTS];
1060
Harald Welte8e7fca32017-05-07 16:14:33 +02001061struct card_handle *card_emu_init(uint8_t slot_num, uint8_t tc_chan, uint8_t uart_chan,
1062 uint8_t in_ep, uint8_t irq_ep)
Harald Welte9d3e3822015-11-09 00:50:54 +01001063{
1064 struct card_handle *ch;
1065
1066 if (slot_num >= ARRAY_SIZE(card_handles))
1067 return NULL;
1068
1069 ch = &card_handles[slot_num];
1070
1071 memset(ch, 0, sizeof(*ch));
1072
Harald Welte54cb3d02016-02-29 14:12:40 +01001073 INIT_LLIST_HEAD(&ch->uart_tx_queue);
1074
Kévin Redon680bdab2018-07-18 14:00:57 +02001075 /* initialize the card_handle with reasonable defaults */
Harald Weltedde112e2016-03-20 16:42:11 +01001076 ch->num = slot_num;
Harald Welte8e7fca32017-05-07 16:14:33 +02001077 ch->irq_ep = irq_ep;
1078 ch->in_ep = in_ep;
Harald Welte9d3e3822015-11-09 00:50:54 +01001079 ch->state = ISO_S_WAIT_POWER;
1080 ch->vcc_active = 0;
1081 ch->in_reset = 1;
1082 ch->clocked = 0;
1083
1084 ch->fi = 0;
1085 ch->di = 1;
1086 ch->wi = ISO7816_3_DEFAULT_WI;
1087
1088 ch->tc_chan = tc_chan;
1089 ch->uart_chan = uart_chan;
1090 ch->waiting_time = ISO7816_3_INIT_WTIME;
1091
1092 ch->atr.idx = 0;
1093 ch->atr.len = sizeof(default_atr);
1094 memcpy(ch->atr.atr, default_atr, ch->atr.len);
1095
1096 ch->pts.state = PTS_S_WAIT_REQ_PTSS;
1097 ch->tpdu.state = TPDU_S_WAIT_CLA;
1098
1099 tc_etu_init(ch->tc_chan, ch);
1100
1101 return ch;
1102}