blob: 923226aae4df46c6125a4c2d5972e4ca29ec720c [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[] = {
Kévin Redon2fdcf3b2018-10-15 19:43:15 +020058 {
59 .value = ISO_S_WAIT_POWER,
60 .str = "WAIT_POWER",
61 },
62 {
63 .value = ISO_S_WAIT_CLK,
64 .str = "WAIT_CLK",
65 },
66 {
67 .value = ISO_S_WAIT_RST,
68 .str = "WAIT_RST",
69 },
70 {
71 .value = ISO_S_WAIT_ATR,
72 .str = "WAIT_ATR",
73 },
74 {
75 .value = ISO_S_IN_ATR,
76 .str = "IN_ATR",
77 },
78 {
79 .value = ISO_S_IN_PTS,
80 .str = "IN_PTS",
81 },
82 {
83 .value = ISO_S_WAIT_TPDU,
84 .str = "WAIT_TPDU",
85 },
86 {
87 .value = ISO_S_IN_TPDU,
88 .str = "IN_TPDU",
89 },
Kévin Redon8a4fba52018-08-02 17:44:16 +020090 {
91 .value = 0,
92 .str = NULL,
93 },
94};
95
96
Harald Welte9d3e3822015-11-09 00:50:54 +010097/* detailed sub-states of ISO_S_IN_PTS */
98enum pts_state {
99 PTS_S_WAIT_REQ_PTSS,
100 PTS_S_WAIT_REQ_PTS0,
101 PTS_S_WAIT_REQ_PTS1,
102 PTS_S_WAIT_REQ_PTS2,
103 PTS_S_WAIT_REQ_PTS3,
104 PTS_S_WAIT_REQ_PCK,
105 PTS_S_WAIT_RESP_PTSS = PTS_S_WAIT_REQ_PTSS | 0x10,
106 PTS_S_WAIT_RESP_PTS0 = PTS_S_WAIT_REQ_PTS0 | 0x10,
107 PTS_S_WAIT_RESP_PTS1 = PTS_S_WAIT_REQ_PTS1 | 0x10,
108 PTS_S_WAIT_RESP_PTS2 = PTS_S_WAIT_REQ_PTS2 | 0x10,
109 PTS_S_WAIT_RESP_PTS3 = PTS_S_WAIT_REQ_PTS3 | 0x10,
110 PTS_S_WAIT_RESP_PCK = PTS_S_WAIT_REQ_PCK | 0x10,
111};
112
Kévin Redon2fdcf3b2018-10-15 19:43:15 +0200113/* PTS field byte index */
Harald Welte9d3e3822015-11-09 00:50:54 +0100114#define _PTSS 0
115#define _PTS0 1
116#define _PTS1 2
117#define _PTS2 3
118#define _PTS3 4
119#define _PCK 5
120
Harald Welte16cf4082015-11-11 19:02:48 +0100121/* T-PDU state machine states */
Harald Welte9d3e3822015-11-09 00:50:54 +0100122enum tpdu_state {
Harald Welte16cf4082015-11-11 19:02:48 +0100123 TPDU_S_WAIT_CLA, /* waiting for CLA byte from reader */
124 TPDU_S_WAIT_INS, /* waiting for INS byte from reader */
125 TPDU_S_WAIT_P1, /* waiting for P1 byte from reader */
126 TPDU_S_WAIT_P2, /* waiting for P2 byte from reader */
127 TPDU_S_WAIT_P3, /* waiting for P3 byte from reader */
Harald Welte9d3e3822015-11-09 00:50:54 +0100128 TPDU_S_WAIT_PB, /* waiting for Tx of procedure byte */
Kévin Redon0f4abf52018-08-02 17:42:48 +0200129 TPDU_S_WAIT_RX, /* waiting for more data from reader */
Harald Welte9d3e3822015-11-09 00:50:54 +0100130 TPDU_S_WAIT_TX, /* waiting for more data to reader */
131};
132
Kévin Redon2fdcf3b2018-10-15 19:43:15 +0200133const struct value_string tpdu_state_names[] = {
134 {
135 .value = TPDU_S_WAIT_CLA,
136 .str = "WAIT_CLA",
137 },
138 {
139 .value = TPDU_S_WAIT_INS,
140 .str = "WAIT_INS",
141 },
142 {
143 .value = TPDU_S_WAIT_P1,
144 .str = "WAIT_P1",
145 },
146 {
147 .value = TPDU_S_WAIT_P2,
148 .str = "WAIT_P2",
149 },
150 {
151 .value = TPDU_S_WAIT_P3,
152 .str = "WAIT_P3",
153 },
154 {
155 .value = TPDU_S_WAIT_PB,
156 .str = "WAIT_PB",
157 },
158 {
159 .value = TPDU_S_WAIT_RX,
160 .str = "WAIT_RX",
161 },
162 {
163 .value = TPDU_S_WAIT_TX,
164 .str = "WAIT_TX",
165 },
166 {
167 .value = 0,
168 .str = NULL,
169 },
170};
171
172/* TPDU field byte index */
Harald Welte9d3e3822015-11-09 00:50:54 +0100173#define _CLA 0
174#define _INS 1
175#define _P1 2
176#define _P2 3
177#define _P3 4
178
179struct card_handle {
Harald Weltec3941092018-08-26 09:53:13 +0200180 unsigned int num;
Harald Weltedde112e2016-03-20 16:42:11 +0100181
Harald Welte9d3e3822015-11-09 00:50:54 +0100182 enum iso7816_3_card_state state;
183
184 /* signal levels */
Kévin Redon7233cf82019-11-14 19:37:32 +0100185 bool vcc_active; /*< if VCC is active (true = active/ON) */
186 bool in_reset; /*< if card is in reset (true = RST low/asserted, false = RST high/ released) */
187 bool clocked; /*< if clock is active ( true = active, false = inactive) */
Harald Welte9d3e3822015-11-09 00:50:54 +0100188
Harald Welte16cf4082015-11-11 19:02:48 +0100189 /* timing parameters, from PTS */
Harald Welte9d3e3822015-11-09 00:50:54 +0100190 uint8_t fi;
191 uint8_t di;
192 uint8_t wi;
193
194 uint8_t tc_chan; /* TC channel number */
195 uint8_t uart_chan; /* UART channel */
196
Harald Welte8e7fca32017-05-07 16:14:33 +0200197 uint8_t in_ep; /* USB IN EP */
198 uint8_t irq_ep; /* USB IN EP */
199
Harald Welte9d3e3822015-11-09 00:50:54 +0100200 uint32_t waiting_time; /* in clocks */
201
202 /* ATR state machine */
203 struct {
204 uint8_t idx;
205 uint8_t len;
206 //uint8_t hist_len;
207 //uint8_t last_td;
208 uint8_t atr[ISO7816_3_ATR_LEN_MAX];
209 } atr;
210
211 /* PPS / PTS support */
212 struct {
213 enum pts_state state;
Harald Welte16cf4082015-11-11 19:02:48 +0100214 uint8_t req[6]; /* request bytes */
215 uint8_t resp[6]; /* response bytes */
Harald Welte9d3e3822015-11-09 00:50:54 +0100216 } pts;
217
218 /* TPDU */
219 struct {
220 enum tpdu_state state;
Harald Welte16cf4082015-11-11 19:02:48 +0100221 uint8_t hdr[5]; /* CLA INS P1 P2 P3 */
Harald Welte9d3e3822015-11-09 00:50:54 +0100222 } tpdu;
223
Harald Welte8e7fca32017-05-07 16:14:33 +0200224 struct msgb *uart_rx_msg; /* UART RX -> USB TX */
225 struct msgb *uart_tx_msg; /* USB RX -> UART TX */
Harald Welte9d3e3822015-11-09 00:50:54 +0100226
Harald Welte54cb3d02016-02-29 14:12:40 +0100227 struct llist_head uart_tx_queue;
228
Harald Welte9d3e3822015-11-09 00:50:54 +0100229 struct {
230 uint32_t tx_bytes;
231 uint32_t rx_bytes;
232 uint32_t pps;
233 } stats;
234};
235
Harald Welte54cb3d02016-02-29 14:12:40 +0100236struct llist_head *card_emu_get_uart_tx_queue(struct card_handle *ch)
237{
238 return &ch->uart_tx_queue;
239}
240
Harald Welte2935b3c2015-11-14 20:00:14 +0100241static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts);
Harald Weltee7194ab2015-11-14 21:03:25 +0100242static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss);
Harald Welte2935b3c2015-11-14 20:00:14 +0100243
Harald Welte25a9a802017-05-08 13:30:09 +0200244/* update simtrace header msg_len and submit USB buffer */
245void usb_buf_upd_len_and_submit(struct msgb *msg)
246{
Harald Welteb91f6ad2017-05-10 22:51:30 +0200247 struct simtrace_msg_hdr *sh = (struct simtrace_msg_hdr *) msg->l1h;
Harald Welte25a9a802017-05-08 13:30:09 +0200248
249 sh->msg_len = msgb_length(msg);
250
251 usb_buf_submit(msg);
252}
253
254/* Allocate USB buffer and push + initialize simtrace_msg_hdr */
255struct msgb *usb_buf_alloc_st(uint8_t ep, uint8_t msg_class, uint8_t msg_type)
256{
Kévin Redonc90de692019-11-18 22:32:58 +0100257 struct msgb *msg = NULL;
Harald Welte25a9a802017-05-08 13:30:09 +0200258 struct simtrace_msg_hdr *sh;
259
Kévin Redonc90de692019-11-18 22:32:58 +0100260 while (!msg) {
261 msg = usb_buf_alloc(ep); // try to allocate some memory
262 if (!msg) { // allocation failed, we might be out of memory
263 struct llist_head *queue = usb_get_queue(ep);
264 if (!queue) {
265 TRACE_ERROR("ep %u: %s queue does not exist\n\r",
266 ep, __func__);
267 return NULL;
268 }
269 if (llist_empty(queue)) {
270 TRACE_ERROR("ep %u: %s EOMEM (queue already empty)\n\r",
271 ep, __func__);
272 return NULL;
273 }
274 msg = msgb_dequeue(queue);
275 if (!msg) {
276 TRACE_ERROR("ep %u: %s no msg in non-empty queue\n\r",
277 ep, __func__);
278 return NULL;
279 }
280 usb_buf_free(msg);
281 msg = NULL;
282 TRACE_DEBUG("ep %u: %s queue msg dropped\n\r",
283 ep, __func__);
284 }
285 }
Harald Welte25a9a802017-05-08 13:30:09 +0200286
287 msg->l1h = msgb_put(msg, sizeof(*sh));
288 sh = (struct simtrace_msg_hdr *) msg->l1h;
289 memset(sh, 0, sizeof(*sh));
290 sh->msg_class = msg_class;
291 sh->msg_type = msg_type;
292 msg->l2h = msg->l1h + sizeof(*sh);
293
294 return msg;
295}
296
Kévin Redon680bdab2018-07-18 14:00:57 +0200297/* Update cardemu_usb_msg_rx_data length + submit buffer */
Harald Welteb5288e82015-11-14 21:15:52 +0100298static void flush_rx_buffer(struct card_handle *ch)
299{
Harald Welte8e7fca32017-05-07 16:14:33 +0200300 struct msgb *msg;
Harald Welteb5288e82015-11-14 21:15:52 +0100301 struct cardemu_usb_msg_rx_data *rd;
Harald Welte8e7fca32017-05-07 16:14:33 +0200302 uint32_t data_len;
Harald Welteb5288e82015-11-14 21:15:52 +0100303
Harald Welte8e7fca32017-05-07 16:14:33 +0200304 msg = ch->uart_rx_msg;
305 if (!msg)
Harald Welteb5288e82015-11-14 21:15:52 +0100306 return;
307
Harald Welte8e7fca32017-05-07 16:14:33 +0200308 ch->uart_rx_msg = NULL;
Harald Welteb5288e82015-11-14 21:15:52 +0100309
Kévin Redon680bdab2018-07-18 14:00:57 +0200310 /* store length of data payload field in header */
Harald Welte25a9a802017-05-08 13:30:09 +0200311 rd = (struct cardemu_usb_msg_rx_data *) msg->l2h;
312 rd->data_len = msgb_l2len(msg) - sizeof(*rd);
Harald Welte54cb3d02016-02-29 14:12:40 +0100313
Kévin Redon910e6832018-08-02 17:47:57 +0200314 TRACE_INFO("%u: %s (%u)\n\r",
315 ch->num, __func__, rd->data_len);
316
Harald Welte25a9a802017-05-08 13:30:09 +0200317 usb_buf_upd_len_and_submit(msg);
Harald Welteb5288e82015-11-14 21:15:52 +0100318}
319
Kévin Redon680bdab2018-07-18 14:00:57 +0200320/* convert a non-contiguous PTS request/response into a contiguous
Harald Welte4ba66d02016-02-25 19:38:56 +0100321 * buffer, returning the number of bytes used in the buffer */
322static int serialize_pts(uint8_t *out, const uint8_t *in)
323{
324 int i = 0;
325
326 out[i++] = in[_PTSS];
327 out[i++] = in[_PTS0];
328 if (in[_PTS0] & (1 << 4))
329 out[i++] = in[_PTS1];
330 if (in[_PTS0] & (1 << 5))
331 out[i++] = in[_PTS2];
332 if (in[_PTS0] & (1 << 6))
333 out[i++] = in[_PTS3];
334 out[i++] = in[_PCK];
335
336 return i;
337}
338
Harald Welte17db2f12016-02-26 09:48:57 +0100339static uint8_t csum_pts(const uint8_t *in)
340{
341 uint8_t out[6];
342 int len = serialize_pts(out, in);
343 uint8_t csum = 0;
344 int i;
345
346 /* we don't include the PCK byte in the checksumming process */
347 len -= 1;
348
349 for (i = 0; i < len; i++)
350 csum = csum ^ out[i];
351
352 return csum;
353}
354
Harald Welte4ba66d02016-02-25 19:38:56 +0100355static void flush_pts(struct card_handle *ch)
356{
Harald Welte8e7fca32017-05-07 16:14:33 +0200357 struct msgb *msg;
Harald Welte4ba66d02016-02-25 19:38:56 +0100358 struct cardemu_usb_msg_pts_info *ptsi;
359
Harald Welte25a9a802017-05-08 13:30:09 +0200360 msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_DO_CEMU_PTS);
Harald Welte8e7fca32017-05-07 16:14:33 +0200361 if (!msg)
Harald Welte4ba66d02016-02-25 19:38:56 +0100362 return;
363
Harald Welte25a9a802017-05-08 13:30:09 +0200364 ptsi = (struct cardemu_usb_msg_pts_info *) msgb_put(msg, sizeof(*ptsi));
Harald Welted295b922016-03-18 21:01:36 +0100365 ptsi->pts_len = serialize_pts(ptsi->req, ch->pts.req);
Harald Welte4ba66d02016-02-25 19:38:56 +0100366 serialize_pts(ptsi->resp, ch->pts.resp);
367
Harald Welte25a9a802017-05-08 13:30:09 +0200368 usb_buf_upd_len_and_submit(msg);
Harald Welte4ba66d02016-02-25 19:38:56 +0100369}
370
Harald Welte8c496362016-02-27 16:24:09 +0100371static void emu_update_fidi(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100372{
373 int rc;
374
375 rc = compute_fidi_ratio(ch->fi, ch->di);
376 if (rc > 0 && rc < 0x400) {
Harald Weltedde112e2016-03-20 16:42:11 +0100377 TRACE_INFO("%u: computed Fi(%u) Di(%u) ratio: %d\r\n",
378 ch->num, ch->fi, ch->di, rc);
Harald Welte9d3e3822015-11-09 00:50:54 +0100379 /* make sure UART uses new F/D ratio */
380 card_emu_uart_update_fidi(ch->uart_chan, rc);
381 /* notify ETU timer about this */
382 tc_etu_set_etu(ch->tc_chan, rc);
383 } else
Harald Weltedde112e2016-03-20 16:42:11 +0100384 TRACE_INFO("%u: computed FiDi ration %d unsupported\r\n",
385 ch->num, rc);
Harald Welte9d3e3822015-11-09 00:50:54 +0100386}
387
388/* Update the ISO 7816-3 TPDU receiver state */
389static void card_set_state(struct card_handle *ch,
390 enum iso7816_3_card_state new_state)
391{
Harald Welte903d63a2016-03-20 13:38:39 +0100392 if (ch->state == new_state)
393 return;
394
Kévin Redon2fdcf3b2018-10-15 19:43:15 +0200395 TRACE_DEBUG("%u: 7816 card state %s -> %s\r\n", ch->num,
396 get_value_string(iso7816_3_card_state_names, ch->state),
397 get_value_string(iso7816_3_card_state_names, new_state));
Harald Welte903d63a2016-03-20 13:38:39 +0100398 ch->state = new_state;
399
Harald Welte9d3e3822015-11-09 00:50:54 +0100400 switch (new_state) {
401 case ISO_S_WAIT_POWER:
402 case ISO_S_WAIT_CLK:
403 case ISO_S_WAIT_RST:
404 /* disable Rx and Tx of UART */
405 card_emu_uart_enable(ch->uart_chan, 0);
Kévin Redonac7e73a2019-11-14 20:11:42 +0100406 /* check end activation state (only necessary if the reader to not respect the activation sequence) */
407 if (ch->vcc_active && ch->clocked && !ch->in_reset) {
408 /* enable the TC/ETU counter once reset has been released */
409 tc_etu_enable(ch->tc_chan);
410 /* prepare to send the ATR */
411 card_set_state(ch, ISO_S_WAIT_ATR);
412 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100413 break;
414 case ISO_S_WAIT_ATR:
415 /* Reset to initial Fi / Di ratio */
416 ch->fi = 1;
417 ch->di = 1;
Harald Welte8c496362016-02-27 16:24:09 +0100418 emu_update_fidi(ch);
Kévin Redonebe672e2018-07-29 00:18:12 +0200419 /* the ATR should only be sent 400 to 40k clock cycles after the RESET.
420 * we use the tc_etu mechanism to wait this time.
421 * since the initial ETU is Fd=372/Dd=1 clock cycles long, we have to wait 2-107 ETU.
422 */
423 tc_etu_set_wtime(ch->tc_chan, 2);
424 /* ensure the TC_ETU timer is enabled */
425 tc_etu_enable(ch->tc_chan);
426 break;
427 case ISO_S_IN_ATR:
Kévin Redon680bdab2018-07-18 14:00:57 +0200428 /* initialize to default WI, this will be overwritten if we
Kévin Redonebe672e2018-07-29 00:18:12 +0200429 * send TC2, and it will be programmed into hardware after
Harald Welte9d3e3822015-11-09 00:50:54 +0100430 * ATR is finished */
431 ch->wi = ISO7816_3_DEFAULT_WI;
432 /* update waiting time to initial waiting time */
433 ch->waiting_time = ISO7816_3_INIT_WTIME;
Kévin Redonebe672e2018-07-29 00:18:12 +0200434 /* set initial waiting time */
Harald Welte9d3e3822015-11-09 00:50:54 +0100435 tc_etu_set_wtime(ch->tc_chan, ch->waiting_time);
436 /* Set ATR sub-state to initial state */
437 ch->atr.idx = 0;
Kévin Redonebe672e2018-07-29 00:18:12 +0200438 /* enable USART transmission to reader */
Harald Welte9d3e3822015-11-09 00:50:54 +0100439 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
Kévin Redonebe672e2018-07-29 00:18:12 +0200440 /* trigger USART TX IRQ to sent first ATR byte TS */
441 card_emu_uart_interrupt(ch->uart_chan);
Harald Welte9d3e3822015-11-09 00:50:54 +0100442 break;
443 case ISO_S_WAIT_TPDU:
444 /* enable the receiver, disable transmitter */
Harald Welte2935b3c2015-11-14 20:00:14 +0100445 set_tpdu_state(ch, TPDU_S_WAIT_CLA);
Harald Welte9d3e3822015-11-09 00:50:54 +0100446 card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
447 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100448 case ISO_S_IN_PTS:
449 case ISO_S_IN_TPDU:
450 /* do nothing */
451 break;
452 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100453}
454
Kévin Redonebe672e2018-07-29 00:18:12 +0200455/**********************************************************************
456 * ATR handling
457 **********************************************************************/
458
459/*! Transmit ATR data to reader
460 * @param[in] ch card interface connected to reader
461 * @return numbers of bytes transmitted
462 */
463static int tx_byte_atr(struct card_handle *ch)
464{
465 if (NULL == ch) {
466 TRACE_ERROR("ATR TX: no card handle provided\n\r");
467 return 0;
468 }
469 if (ISO_S_IN_ATR != ch->state) {
470 TRACE_ERROR("%u: ATR TX: no in ATR state\n\r", ch->num);
471 return 0;
472 }
473
474 /* Transmit ATR */
475 if (ch->atr.idx < ch->atr.len) {
476 uint8_t byte = ch->atr.atr[ch->atr.idx++];
477 card_emu_uart_tx(ch->uart_chan, byte);
Kévin Redonebe672e2018-07-29 00:18:12 +0200478 return 1;
479 } else { /* The ATR has been completely transmitted */
Kévin Redon8b8e58b2018-07-30 18:19:11 +0200480 /* search for TC2 to updated WI */
481 ch->wi = ISO7816_3_DEFAULT_WI;
482 if (ch->atr.len >= 2 && ch->atr.atr[1] & 0xf0) { /* Y1 has some data */
483 uint8_t atr_td1 = 2;
484 if (ch->atr.atr[1] & 0x10) { /* TA1 is present */
485 atr_td1++;
486 }
487 if (ch->atr.atr[1] & 0x20) { /* TB1 is present */
488 atr_td1++;
489 }
490 if (ch->atr.atr[1] & 0x40) { /* TC1 is present */
491 atr_td1++;
492 }
493 if (ch->atr.atr[1] & 0x80) { /* TD1 is present */
494 if (ch->atr.len > atr_td1 && ch->atr.atr[atr_td1] & 0xf0) { /* Y2 has some data */
495 uint8_t atr_tc2 = atr_td1+1;
496 if (ch->atr.atr[atr_td1] & 0x10) { /* TA2 is present */
497 atr_tc2++;
498 }
499 if (ch->atr.atr[atr_td1] & 0x20) { /* TB2 is present */
500 atr_tc2++;
501 }
502 if (ch->atr.atr[atr_td1] & 0x40) { /* TC2 is present */
503 if (ch->atr.len > atr_tc2 && ch->atr.atr[atr_tc2]) { /* TC2 encodes WI */
504 ch->wi = ch->atr.atr[atr_tc2]; /* set WI */
505 }
506 }
507 }
508 }
509 }
510 /* update waiting time (see ISO 7816-3 10.2) */
511 ch->waiting_time = ch->wi * 960 * ch->fi;
512 tc_etu_set_wtime(ch->tc_chan, ch->waiting_time);
Kévin Redonebe672e2018-07-29 00:18:12 +0200513 /* reset PTS to initial state */
514 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
515 /* go to next state */
516 card_set_state(ch, ISO_S_WAIT_TPDU);
517 return 0;
518 }
519
520 /* return number of bytes transmitted */
521 return 1;
522}
Harald Welte9d3e3822015-11-09 00:50:54 +0100523
524/**********************************************************************
525 * PTS / PPS handling
526 **********************************************************************/
527
Kévin Redon680bdab2018-07-18 14:00:57 +0200528/* Update the PTS sub-state */
Harald Welte9d3e3822015-11-09 00:50:54 +0100529static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss)
530{
Harald Weltedde112e2016-03-20 16:42:11 +0100531 TRACE_DEBUG("%u: 7816 PTS state %u -> %u\r\n",
532 ch->num, ch->pts.state, new_ptss);
Harald Welte9d3e3822015-11-09 00:50:54 +0100533 ch->pts.state = new_ptss;
534}
535
536/* Determine the next PTS state */
537static enum pts_state next_pts_state(struct card_handle *ch)
538{
539 uint8_t is_resp = ch->pts.state & 0x10;
540 uint8_t sstate = ch->pts.state & 0x0f;
541 uint8_t *pts_ptr;
542
543 if (!is_resp)
544 pts_ptr = ch->pts.req;
545 else
546 pts_ptr = ch->pts.resp;
547
548 switch (sstate) {
549 case PTS_S_WAIT_REQ_PTSS:
550 goto from_ptss;
551 case PTS_S_WAIT_REQ_PTS0:
552 goto from_pts0;
553 case PTS_S_WAIT_REQ_PTS1:
554 goto from_pts1;
555 case PTS_S_WAIT_REQ_PTS2:
556 goto from_pts2;
557 case PTS_S_WAIT_REQ_PTS3:
558 goto from_pts3;
559 }
560
561 if (ch->pts.state == PTS_S_WAIT_REQ_PCK)
562 return PTS_S_WAIT_RESP_PTSS;
563
564from_ptss:
565 return PTS_S_WAIT_REQ_PTS0 | is_resp;
566from_pts0:
567 if (pts_ptr[_PTS0] & (1 << 4))
568 return PTS_S_WAIT_REQ_PTS1 | is_resp;
569from_pts1:
570 if (pts_ptr[_PTS0] & (1 << 5))
571 return PTS_S_WAIT_REQ_PTS2 | is_resp;
572from_pts2:
573 if (pts_ptr[_PTS0] & (1 << 6))
574 return PTS_S_WAIT_REQ_PTS3 | is_resp;
575from_pts3:
576 return PTS_S_WAIT_REQ_PCK | is_resp;
577}
578
579
Harald Welteccb8a222016-03-20 13:37:11 +0100580static int
Harald Welte9d3e3822015-11-09 00:50:54 +0100581process_byte_pts(struct card_handle *ch, uint8_t byte)
582{
583 switch (ch->pts.state) {
584 case PTS_S_WAIT_REQ_PTSS:
585 ch->pts.req[_PTSS] = byte;
586 break;
587 case PTS_S_WAIT_REQ_PTS0:
588 ch->pts.req[_PTS0] = byte;
589 break;
590 case PTS_S_WAIT_REQ_PTS1:
591 ch->pts.req[_PTS1] = byte;
592 break;
593 case PTS_S_WAIT_REQ_PTS2:
594 ch->pts.req[_PTS2] = byte;
595 break;
596 case PTS_S_WAIT_REQ_PTS3:
597 ch->pts.req[_PTS3] = byte;
598 break;
599 case PTS_S_WAIT_REQ_PCK:
600 ch->pts.req[_PCK] = byte;
Harald Welte17db2f12016-02-26 09:48:57 +0100601 if (ch->pts.req[_PCK] != csum_pts(ch->pts.req)) {
Harald Weltedde112e2016-03-20 16:42:11 +0100602 TRACE_ERROR("%u: Error in PTS Checksum!\r\n",
603 ch->num);
Harald Welte17db2f12016-02-26 09:48:57 +0100604 /* Wait for the next TPDU */
605 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
606 return ISO_S_WAIT_TPDU;
607 }
Harald Welte4ba66d02016-02-25 19:38:56 +0100608 /* FIXME: check if proposal matches capabilities in ATR */
Harald Welte9d3e3822015-11-09 00:50:54 +0100609 memcpy(ch->pts.resp, ch->pts.req, sizeof(ch->pts.resp));
610 break;
Harald Welte4c473da2015-11-14 13:31:11 +0100611 default:
Harald Weltedde112e2016-03-20 16:42:11 +0100612 TRACE_ERROR("%u: process_byte_pts() in invalid state %u\r\n",
613 ch->num, ch->pts.state);
Harald Welte4c473da2015-11-14 13:31:11 +0100614 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100615 }
616 /* calculate the next state and set it */
617 set_pts_state(ch, next_pts_state(ch));
618
Harald Welte4ba66d02016-02-25 19:38:56 +0100619 if (ch->pts.state == PTS_S_WAIT_RESP_PTSS) {
620 flush_pts(ch);
621 /* activate UART TX to transmit PTS response */
622 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
Harald Welte53079bb2016-03-20 14:58:35 +0100623 /* don't fall-through to the 'return ISO_S_IN_PTS'
624 * below, rather keep ISO7816 state as-is, it will be
625 * further updated by the tx-completion handler */
Harald Welteccb8a222016-03-20 13:37:11 +0100626 return -1;
Harald Welte4ba66d02016-02-25 19:38:56 +0100627 }
628
Harald Welte9d3e3822015-11-09 00:50:54 +0100629 return ISO_S_IN_PTS;
630}
631
632/* return a single byte to be transmitted to the reader */
Harald Welte855ba9e2016-02-24 21:00:46 +0100633static int tx_byte_pts(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100634{
Harald Welte855ba9e2016-02-24 21:00:46 +0100635 uint8_t byte;
636
637 /* 1: Determine the next transmit byte */
Harald Welte9d3e3822015-11-09 00:50:54 +0100638 switch (ch->pts.state) {
639 case PTS_S_WAIT_RESP_PTSS:
Harald Welte855ba9e2016-02-24 21:00:46 +0100640 byte = ch->pts.resp[_PTSS];
Harald Welte9d3e3822015-11-09 00:50:54 +0100641 break;
642 case PTS_S_WAIT_RESP_PTS0:
Harald Welte855ba9e2016-02-24 21:00:46 +0100643 byte = ch->pts.resp[_PTS0];
Harald Welte9d3e3822015-11-09 00:50:54 +0100644 break;
645 case PTS_S_WAIT_RESP_PTS1:
Harald Welte855ba9e2016-02-24 21:00:46 +0100646 byte = ch->pts.resp[_PTS1];
Harald Welte9d3e3822015-11-09 00:50:54 +0100647 /* This must be TA1 */
Harald Welte855ba9e2016-02-24 21:00:46 +0100648 ch->fi = byte >> 4;
649 ch->di = byte & 0xf;
Harald Weltedde112e2016-03-20 16:42:11 +0100650 TRACE_DEBUG("%u: found Fi=%u Di=%u\r\n", ch->num,
651 ch->fi, ch->di);
Harald Welte9d3e3822015-11-09 00:50:54 +0100652 break;
653 case PTS_S_WAIT_RESP_PTS2:
Harald Welte855ba9e2016-02-24 21:00:46 +0100654 byte = ch->pts.resp[_PTS2];
Harald Welte9d3e3822015-11-09 00:50:54 +0100655 break;
656 case PTS_S_WAIT_RESP_PTS3:
Harald Welte855ba9e2016-02-24 21:00:46 +0100657 byte = ch->pts.resp[_PTS3];
Harald Welte9d3e3822015-11-09 00:50:54 +0100658 break;
659 case PTS_S_WAIT_RESP_PCK:
Harald Welte855ba9e2016-02-24 21:00:46 +0100660 byte = ch->pts.resp[_PCK];
Harald Welte855ba9e2016-02-24 21:00:46 +0100661 break;
Harald Welted79dc4f2015-11-14 13:32:21 +0100662 default:
Harald Weltedde112e2016-03-20 16:42:11 +0100663 TRACE_ERROR("%u: get_byte_pts() in invalid state %u\r\n",
664 ch->num, ch->pts.state);
Harald Welte855ba9e2016-02-24 21:00:46 +0100665 return 0;
666 }
667
668 /* 2: Transmit the byte */
669 card_emu_uart_tx(ch->uart_chan, byte);
670
671 /* 3: Update the state */
672
673 switch (ch->pts.state) {
674 case PTS_S_WAIT_RESP_PCK:
Harald Weltec58bba02016-03-20 14:57:53 +0100675 card_emu_uart_wait_tx_idle(ch->uart_chan);
Harald Welte52d55462016-03-20 13:38:05 +0100676 /* update baud rate generator with Fi/Di */
677 emu_update_fidi(ch);
Harald Welte855ba9e2016-02-24 21:00:46 +0100678 /* Wait for the next TPDU */
679 card_set_state(ch, ISO_S_WAIT_TPDU);
680 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
681 break;
682 default:
683 /* calculate the next state and set it */
684 set_pts_state(ch, next_pts_state(ch));
Harald Welted79dc4f2015-11-14 13:32:21 +0100685 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100686 }
Harald Welted79dc4f2015-11-14 13:32:21 +0100687
Harald Welte855ba9e2016-02-24 21:00:46 +0100688 /* return number of bytes transmitted */
689 return 1;
Harald Welte9d3e3822015-11-09 00:50:54 +0100690}
691
692
693/**********************************************************************
694 * TPDU handling
695 **********************************************************************/
696
Harald Welte4d804672015-11-14 23:02:38 +0100697
698/* compute number of data bytes according to Chapter 10.3.2 of 7816-3 */
699static unsigned int t0_num_data_bytes(uint8_t p3, int reader_to_card)
700{
701 if (reader_to_card) {
702 return p3;
703 } else {
704 if (p3 == 0)
705 return 256;
706 else
707 return p3;
708 }
709}
710
Harald Welte9d3e3822015-11-09 00:50:54 +0100711/* add a just-received TPDU byte (from reader) to USB buffer */
Harald Welte61bb30e2015-11-14 23:44:14 +0100712static void add_tpdu_byte(struct card_handle *ch, uint8_t byte)
Harald Welte9d3e3822015-11-09 00:50:54 +0100713{
Harald Welte8e7fca32017-05-07 16:14:33 +0200714 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100715 struct cardemu_usb_msg_rx_data *rd;
Harald Welte4d804672015-11-14 23:02:38 +0100716 unsigned int num_data_bytes = t0_num_data_bytes(ch->tpdu.hdr[_P3], 0);
Harald Welte9d3e3822015-11-09 00:50:54 +0100717
718 /* ensure we have a buffer */
Harald Welte8e7fca32017-05-07 16:14:33 +0200719 if (!ch->uart_rx_msg) {
Harald Welte25a9a802017-05-08 13:30:09 +0200720 msg = 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) {
Harald Weltedde112e2016-03-20 16:42:11 +0100723 TRACE_ERROR("%u: Received UART byte but ENOMEM\r\n",
724 ch->num);
Harald Welte9d3e3822015-11-09 00:50:54 +0100725 return;
Harald Welte4d804672015-11-14 23:02:38 +0100726 }
Harald Welte25a9a802017-05-08 13:30:09 +0200727 msgb_put(msg, sizeof(*rd));
Harald Welte9d3e3822015-11-09 00:50:54 +0100728 } else
Harald Welte8e7fca32017-05-07 16:14:33 +0200729 msg = ch->uart_rx_msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100730
Harald Welte25a9a802017-05-08 13:30:09 +0200731 rd = (struct cardemu_usb_msg_rx_data *) msg->l2h;
Harald Welte8e7fca32017-05-07 16:14:33 +0200732 msgb_put_u8(msg, byte);
Harald Welte9d3e3822015-11-09 00:50:54 +0100733
734 /* check if the buffer is full. If so, send it */
Harald Welte25a9a802017-05-08 13:30:09 +0200735 if (msgb_l2len(msg) >= sizeof(*rd) + num_data_bytes) {
Harald Welte4d804672015-11-14 23:02:38 +0100736 rd->flags |= CEMU_DATA_F_FINAL;
Harald Welteb5288e82015-11-14 21:15:52 +0100737 flush_rx_buffer(ch);
Harald Welte61bb30e2015-11-14 23:44:14 +0100738 /* We need to transmit the SW now, */
739 set_tpdu_state(ch, TPDU_S_WAIT_TX);
Harald Welte8e7fca32017-05-07 16:14:33 +0200740 } else if (msgb_tailroom(msg) <= 0)
Harald Welte4d804672015-11-14 23:02:38 +0100741 flush_rx_buffer(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100742}
743
744static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts)
745{
Harald Welte05b41c62015-11-14 20:58:48 +0100746 if (ch->tpdu.state == new_ts)
747 return;
748
Kévin Redon2fdcf3b2018-10-15 19:43:15 +0200749 TRACE_DEBUG("%u: 7816 TPDU state %s -> %s\r\n", ch->num,
750 get_value_string(tpdu_state_names, ch->tpdu.state),
751 get_value_string(tpdu_state_names, new_ts));
Harald Welte903d63a2016-03-20 13:38:39 +0100752 ch->tpdu.state = new_ts;
753
Harald Welte9d3e3822015-11-09 00:50:54 +0100754 switch (new_ts) {
755 case TPDU_S_WAIT_CLA:
Harald Welte05b41c62015-11-14 20:58:48 +0100756 case TPDU_S_WAIT_RX:
Harald Welte9d3e3822015-11-09 00:50:54 +0100757 card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
758 break;
759 case TPDU_S_WAIT_PB:
760 /* we just completed the TPDU header from reader to card
761 * and now need to disable the receiver, enable the
762 * transmitter and transmit the procedure byte */
763 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
764 break;
Harald Weltead434402016-03-02 11:18:29 +0100765 default:
766 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100767 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100768}
769
770static enum tpdu_state next_tpdu_state(struct card_handle *ch)
771{
772 switch (ch->tpdu.state) {
773 case TPDU_S_WAIT_CLA:
774 return TPDU_S_WAIT_INS;
775 case TPDU_S_WAIT_INS:
776 return TPDU_S_WAIT_P1;
777 case TPDU_S_WAIT_P1:
778 return TPDU_S_WAIT_P2;
779 case TPDU_S_WAIT_P2:
780 return TPDU_S_WAIT_P3;
781 case TPDU_S_WAIT_P3:
782 return TPDU_S_WAIT_PB;
783 /* simply stay in Rx or Tx by default */
784 case TPDU_S_WAIT_PB:
785 return TPDU_S_WAIT_PB;
786 case TPDU_S_WAIT_RX:
787 return TPDU_S_WAIT_RX;
788 case TPDU_S_WAIT_TX:
789 return TPDU_S_WAIT_TX;
790 }
Harald Welte4c473da2015-11-14 13:31:11 +0100791 /* we should never reach here */
792 assert(0);
793 return -1;
Harald Welte9d3e3822015-11-09 00:50:54 +0100794}
795
796static void send_tpdu_header(struct card_handle *ch)
797{
Harald Welte8e7fca32017-05-07 16:14:33 +0200798 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100799 struct cardemu_usb_msg_rx_data *rd;
Harald Welte8e7fca32017-05-07 16:14:33 +0200800 uint8_t *cur;
Harald Welte9d3e3822015-11-09 00:50:54 +0100801
Harald Weltedde112e2016-03-20 16:42:11 +0100802 TRACE_INFO("%u: %s: %02x %02x %02x %02x %02x\r\n",
803 ch->num, __func__,
Harald Welte43f79492016-02-29 10:06:54 +0100804 ch->tpdu.hdr[0], ch->tpdu.hdr[1],
805 ch->tpdu.hdr[2], ch->tpdu.hdr[3],
806 ch->tpdu.hdr[4]);
807
Harald Welte9d3e3822015-11-09 00:50:54 +0100808 /* if we already/still have a context, send it off */
Harald Welte8e7fca32017-05-07 16:14:33 +0200809 if (ch->uart_rx_msg) {
Harald Weltedde112e2016-03-20 16:42:11 +0100810 TRACE_DEBUG("%u: have old buffer\r\n", ch->num);
Harald Welte8e7fca32017-05-07 16:14:33 +0200811 if (msgb_l2len(ch->uart_rx_msg)) {
Harald Weltedde112e2016-03-20 16:42:11 +0100812 TRACE_DEBUG("%u: flushing old buffer\r\n", ch->num);
Harald Weltef1697e22016-03-02 10:28:54 +0100813 flush_rx_buffer(ch);
814 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100815 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200816 TRACE_DEBUG("%u: allocating new buffer\r\n", ch->num);
817 /* ensure we have a new buffer */
Harald Welte25a9a802017-05-08 13:30:09 +0200818 ch->uart_rx_msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM,
819 SIMTRACE_MSGT_DO_CEMU_RX_DATA);
Harald Welte8e7fca32017-05-07 16:14:33 +0200820 if (!ch->uart_rx_msg) {
821 TRACE_ERROR("%u: %s: ENOMEM\r\n", ch->num, __func__);
822 return;
823 }
824 msg = ch->uart_rx_msg;
Harald Welte25a9a802017-05-08 13:30:09 +0200825 rd = (struct cardemu_usb_msg_rx_data *) msgb_put(msg, sizeof(*rd));
Harald Welte9d3e3822015-11-09 00:50:54 +0100826
Harald Welte8e7fca32017-05-07 16:14:33 +0200827 /* initialize header */
Harald Welte9d3e3822015-11-09 00:50:54 +0100828 rd->flags = CEMU_DATA_F_TPDU_HDR;
Harald Welte9d3e3822015-11-09 00:50:54 +0100829
830 /* copy TPDU header to data field */
Harald Welte8e7fca32017-05-07 16:14:33 +0200831 cur = msgb_put(msg, sizeof(ch->tpdu.hdr));
832 memcpy(cur, ch->tpdu.hdr, sizeof(ch->tpdu.hdr));
Harald Welteb5288e82015-11-14 21:15:52 +0100833 /* rd->data_len is set in flush_rx_buffer() */
Harald Welte9d3e3822015-11-09 00:50:54 +0100834
Harald Welteb5288e82015-11-14 21:15:52 +0100835 flush_rx_buffer(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100836}
837
838static enum iso7816_3_card_state
839process_byte_tpdu(struct card_handle *ch, uint8_t byte)
840{
841 switch (ch->tpdu.state) {
842 case TPDU_S_WAIT_CLA:
843 ch->tpdu.hdr[_CLA] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100844 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100845 break;
846 case TPDU_S_WAIT_INS:
847 ch->tpdu.hdr[_INS] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100848 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100849 break;
850 case TPDU_S_WAIT_P1:
851 ch->tpdu.hdr[_P1] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100852 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100853 break;
854 case TPDU_S_WAIT_P2:
855 ch->tpdu.hdr[_P2] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100856 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100857 break;
858 case TPDU_S_WAIT_P3:
859 ch->tpdu.hdr[_P3] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100860 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100861 /* FIXME: start timer to transmit further 0x60 */
862 /* send the TPDU header as part of a procedure byte
863 * request to the USB host */
864 send_tpdu_header(ch);
865 break;
866 case TPDU_S_WAIT_RX:
Harald Welte61bb30e2015-11-14 23:44:14 +0100867 add_tpdu_byte(ch, byte);
868 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100869 default:
Harald Weltedde112e2016-03-20 16:42:11 +0100870 TRACE_ERROR("%u: process_byte_tpdu() in invalid state %u\r\n",
871 ch->num, ch->tpdu.state);
Harald Welte9d3e3822015-11-09 00:50:54 +0100872 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100873
874 /* ensure we stay in TPDU ISO state */
875 return ISO_S_IN_TPDU;
876}
877
Harald Welte855ba9e2016-02-24 21:00:46 +0100878/* tx a single byte to be transmitted to the reader */
879static int tx_byte_tpdu(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100880{
Harald Welte8e7fca32017-05-07 16:14:33 +0200881 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100882 struct cardemu_usb_msg_tx_data *td;
Harald Welte855ba9e2016-02-24 21:00:46 +0100883 uint8_t byte;
Harald Welte9d3e3822015-11-09 00:50:54 +0100884
885 /* ensure we are aware of any data that might be pending for
886 * transmit */
Harald Welte8e7fca32017-05-07 16:14:33 +0200887 if (!ch->uart_tx_msg) {
Harald Welte53079bb2016-03-20 14:58:35 +0100888 /* uart_tx_queue is filled from main loop, so no need
889 * for irq-safe operations */
Harald Welte54cb3d02016-02-29 14:12:40 +0100890 if (llist_empty(&ch->uart_tx_queue))
Harald Welte9d3e3822015-11-09 00:50:54 +0100891 return 0;
892
Harald Welte54cb3d02016-02-29 14:12:40 +0100893 /* dequeue first at head */
Harald Welte8e7fca32017-05-07 16:14:33 +0200894 ch->uart_tx_msg = msgb_dequeue(&ch->uart_tx_queue);
Harald Welte25a9a802017-05-08 13:30:09 +0200895 ch->uart_tx_msg->l1h = ch->uart_tx_msg->head;
896 ch->uart_tx_msg->l2h = ch->uart_tx_msg->l1h + sizeof(struct simtrace_msg_hdr);
Harald Welte8e7fca32017-05-07 16:14:33 +0200897 msg = ch->uart_tx_msg;
Harald Welte25a9a802017-05-08 13:30:09 +0200898 /* remove the header */
899 msgb_pull(msg, sizeof(struct simtrace_msg_hdr) + sizeof(*td));
Harald Welte9d3e3822015-11-09 00:50:54 +0100900 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200901 msg = ch->uart_tx_msg;
Harald Welte25a9a802017-05-08 13:30:09 +0200902 td = (struct cardemu_usb_msg_tx_data *) msg->l2h;
Harald Welte9d3e3822015-11-09 00:50:54 +0100903
Harald Welte8e7fca32017-05-07 16:14:33 +0200904 /* take the next pending byte out of the msgb */
905 byte = msgb_pull_u8(msg);
Harald Welte855ba9e2016-02-24 21:00:46 +0100906
907 card_emu_uart_tx(ch->uart_chan, byte);
Harald Welte9d3e3822015-11-09 00:50:54 +0100908
Kévin Redon0f4abf52018-08-02 17:42:48 +0200909 /* this must happen _after_ the byte has been transmitted */
Harald Weltef16b6182016-02-24 22:18:46 +0100910 switch (ch->tpdu.state) {
911 case TPDU_S_WAIT_PB:
912 /* if we just transmitted the procedure byte, we need to decide
913 * if we want to continue to receive or transmit */
914 if (td->flags & CEMU_DATA_F_PB_AND_TX)
915 set_tpdu_state(ch, TPDU_S_WAIT_TX);
916 else if (td->flags & CEMU_DATA_F_PB_AND_RX)
917 set_tpdu_state(ch, TPDU_S_WAIT_RX);
918 break;
Harald Weltead434402016-03-02 11:18:29 +0100919 default:
920 break;
Harald Weltef16b6182016-02-24 22:18:46 +0100921 }
922
Harald Welte9d3e3822015-11-09 00:50:54 +0100923 /* check if the buffer has now been fully transmitted */
Harald Welte8e7fca32017-05-07 16:14:33 +0200924 if (msgb_length(msg) == 0) {
Harald Welte52922ff2015-11-14 20:59:56 +0100925 if (td->flags & CEMU_DATA_F_PB_AND_RX) {
926 /* we have just sent the procedure byte and now
927 * need to continue receiving */
928 set_tpdu_state(ch, TPDU_S_WAIT_RX);
Harald Welte2935b3c2015-11-14 20:00:14 +0100929 } else {
Harald Welte52922ff2015-11-14 20:59:56 +0100930 /* we have transmitted all bytes */
931 if (td->flags & CEMU_DATA_F_FINAL) {
932 /* this was the final part of the APDU, go
Harald Welte53079bb2016-03-20 14:58:35 +0100933 * back to state one */
Harald Welte52922ff2015-11-14 20:59:56 +0100934 card_set_state(ch, ISO_S_WAIT_TPDU);
Harald Welte52922ff2015-11-14 20:59:56 +0100935 }
Harald Welte2935b3c2015-11-14 20:00:14 +0100936 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200937 usb_buf_free(msg);
938 ch->uart_tx_msg = NULL;
Harald Welte9d3e3822015-11-09 00:50:54 +0100939 }
940
941 return 1;
942}
943
944/**********************************************************************
945 * Public API
946 **********************************************************************/
947
948/* process a single byte received from the reader */
949void card_emu_process_rx_byte(struct card_handle *ch, uint8_t byte)
950{
951 int new_state = -1;
952
953 ch->stats.rx_bytes++;
954
955 switch (ch->state) {
Harald Welte9d3e3822015-11-09 00:50:54 +0100956 case ISO_S_WAIT_TPDU:
957 if (byte == 0xff) {
958 new_state = process_byte_pts(ch, byte);
959 ch->stats.pps++;
960 goto out_silent;
961 }
962 /* fall-through */
963 case ISO_S_IN_TPDU:
964 new_state = process_byte_tpdu(ch, byte);
965 break;
966 case ISO_S_IN_PTS:
967 new_state = process_byte_pts(ch, byte);
968 goto out_silent;
Kévin Redon5f6b8712018-07-11 09:49:06 +0200969 default:
970 TRACE_ERROR("%u: Received UART char in invalid 7816 state "
971 "%u\r\n", ch->num, ch->state);
972 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100973 }
974
975out_silent:
976 if (new_state != -1)
977 card_set_state(ch, new_state);
978}
979
Harald Welte855ba9e2016-02-24 21:00:46 +0100980/* transmit a single byte to the reader */
981int card_emu_tx_byte(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100982{
983 int rc = 0;
984
985 switch (ch->state) {
986 case ISO_S_IN_ATR:
Kévin Redonebe672e2018-07-29 00:18:12 +0200987 rc = tx_byte_atr(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100988 break;
989 case ISO_S_IN_PTS:
Harald Welte855ba9e2016-02-24 21:00:46 +0100990 rc = tx_byte_pts(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100991 break;
992 case ISO_S_IN_TPDU:
Harald Welte855ba9e2016-02-24 21:00:46 +0100993 rc = tx_byte_tpdu(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100994 break;
Harald Weltead434402016-03-02 11:18:29 +0100995 default:
996 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100997 }
998
999 if (rc)
1000 ch->stats.tx_bytes++;
1001
Harald Welte4d804672015-11-14 23:02:38 +01001002 /* if we return 0 here, the UART needs to disable transmit-ready
1003 * interrupts */
Harald Welte9d3e3822015-11-09 00:50:54 +01001004 return rc;
1005}
1006
Harald Welteacae4122016-03-02 10:27:58 +01001007void card_emu_have_new_uart_tx(struct card_handle *ch)
1008{
1009 switch (ch->state) {
1010 case ISO_S_IN_TPDU:
1011 switch (ch->tpdu.state) {
1012 case TPDU_S_WAIT_TX:
1013 case TPDU_S_WAIT_PB:
1014 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
1015 break;
1016 default:
1017 break;
1018 }
1019 default:
1020 break;
1021 }
1022}
1023
Harald Welteff160652016-03-19 21:59:06 +01001024void card_emu_report_status(struct card_handle *ch)
1025{
Harald Welte8e7fca32017-05-07 16:14:33 +02001026 struct msgb *msg;
Harald Welteff160652016-03-19 21:59:06 +01001027 struct cardemu_usb_msg_status *sts;
1028
Harald Welte25a9a802017-05-08 13:30:09 +02001029 msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM,
1030 SIMTRACE_MSGT_BD_CEMU_STATUS);
Harald Welte8e7fca32017-05-07 16:14:33 +02001031 if (!msg)
Harald Welteff160652016-03-19 21:59:06 +01001032 return;
Harald Welte8e7fca32017-05-07 16:14:33 +02001033
Harald Welte25a9a802017-05-08 13:30:09 +02001034 sts = (struct cardemu_usb_msg_status *) msgb_put(msg, sizeof(*sts));
Harald Welteff160652016-03-19 21:59:06 +01001035 sts->flags = 0;
1036 if (ch->vcc_active)
1037 sts->flags |= CEMU_STATUS_F_VCC_PRESENT;
1038 if (ch->clocked)
1039 sts->flags |= CEMU_STATUS_F_CLK_ACTIVE;
1040 if (ch->in_reset)
1041 sts->flags |= CEMU_STATUS_F_RESET_ACTIVE;
1042 /* FIXME: voltage + card insert */
1043 sts->fi = ch->fi;
1044 sts->di = ch->di;
1045 sts->wi = ch->wi;
1046 sts->waiting_time = ch->waiting_time;
1047
Harald Welte25a9a802017-05-08 13:30:09 +02001048 usb_buf_upd_len_and_submit(msg);
Harald Welteff160652016-03-19 21:59:06 +01001049}
1050
Harald Welte9d3e3822015-11-09 00:50:54 +01001051/* hardware driver informs us that a card I/O signal has changed */
1052void card_emu_io_statechg(struct card_handle *ch, enum card_io io, int active)
1053{
1054 switch (io) {
1055 case CARD_IO_VCC:
Harald Welte47ee2832016-02-29 10:09:46 +01001056 if (active == 0 && ch->vcc_active == 1) {
Harald Weltedde112e2016-03-20 16:42:11 +01001057 TRACE_INFO("%u: VCC deactivated\r\n", ch->num);
Harald Welte22cdf2a2016-02-24 22:18:11 +01001058 tc_etu_disable(ch->tc_chan);
Harald Welte9d3e3822015-11-09 00:50:54 +01001059 card_set_state(ch, ISO_S_WAIT_POWER);
Harald Welte47ee2832016-02-29 10:09:46 +01001060 } else if (active == 1 && ch->vcc_active == 0) {
Harald Weltedde112e2016-03-20 16:42:11 +01001061 TRACE_INFO("%u: VCC activated\r\n", ch->num);
Harald Welte9d3e3822015-11-09 00:50:54 +01001062 card_set_state(ch, ISO_S_WAIT_CLK);
Harald Welte47ee2832016-02-29 10:09:46 +01001063 }
Harald Welte9d3e3822015-11-09 00:50:54 +01001064 ch->vcc_active = active;
1065 break;
1066 case CARD_IO_CLK:
Harald Welte47ee2832016-02-29 10:09:46 +01001067 if (active == 1 && ch->clocked == 0) {
Harald Weltedde112e2016-03-20 16:42:11 +01001068 TRACE_INFO("%u: CLK activated\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +01001069 if (ch->state == ISO_S_WAIT_CLK)
1070 card_set_state(ch, ISO_S_WAIT_RST);
1071 } else if (active == 0 && ch->clocked == 1) {
Harald Weltedde112e2016-03-20 16:42:11 +01001072 TRACE_INFO("%u: CLK deactivated\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +01001073 }
Harald Welte9d3e3822015-11-09 00:50:54 +01001074 ch->clocked = active;
1075 break;
1076 case CARD_IO_RST:
Harald Welte47ee2832016-02-29 10:09:46 +01001077 if (active == 0 && ch->in_reset) {
Harald Weltedde112e2016-03-20 16:42:11 +01001078 TRACE_INFO("%u: RST released\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +01001079 if (ch->vcc_active && ch->clocked) {
1080 /* enable the TC/ETU counter once reset has been released */
1081 tc_etu_enable(ch->tc_chan);
Kévin Redonebe672e2018-07-29 00:18:12 +02001082 /* prepare to send the ATR */
Harald Welte47ee2832016-02-29 10:09:46 +01001083 card_set_state(ch, ISO_S_WAIT_ATR);
Harald Welte47ee2832016-02-29 10:09:46 +01001084 }
1085 } else if (active && !ch->in_reset) {
Harald Weltedde112e2016-03-20 16:42:11 +01001086 TRACE_INFO("%u: RST asserted\r\n", ch->num);
Harald Welte22cdf2a2016-02-24 22:18:11 +01001087 tc_etu_disable(ch->tc_chan);
Harald Welte9d3e3822015-11-09 00:50:54 +01001088 }
1089 ch->in_reset = active;
1090 break;
1091 }
1092}
1093
1094/* User sets a new ATR to be returned during next card reset */
1095int card_emu_set_atr(struct card_handle *ch, const uint8_t *atr, uint8_t len)
1096{
1097 if (len > sizeof(ch->atr.atr))
1098 return -1;
1099
1100 memcpy(ch->atr.atr, atr, len);
1101 ch->atr.len = len;
1102 ch->atr.idx = 0;
1103
Kévin Redonebe672e2018-07-29 00:18:12 +02001104#if TRACE_LEVEL >= TRACE_LEVEL_INFO
1105 uint8_t i;
1106 TRACE_INFO("%u: ATR set: ", ch->num);
1107 for (i = 0; i < ch->atr.len; i++) {
1108 TRACE_INFO_WP("%02x ", atr[i]);
1109 }
1110 TRACE_INFO_WP("\n\r");
1111#endif
1112 /* FIXME: race condition with transmitting ATR to reader? */
Harald Welte9d3e3822015-11-09 00:50:54 +01001113
1114 return 0;
1115}
1116
1117/* hardware driver informs us that one (more) ETU has expired */
1118void tc_etu_wtime_half_expired(void *handle)
1119{
1120 struct card_handle *ch = handle;
1121 /* transmit NULL procedure byte well before waiting time expires */
Harald Weltedda73552016-03-02 10:29:55 +01001122 switch (ch->state) {
1123 case ISO_S_IN_TPDU:
1124 switch (ch->tpdu.state) {
1125 case TPDU_S_WAIT_PB:
1126 case TPDU_S_WAIT_TX:
1127 putchar('N');
1128 card_emu_uart_tx(ch->uart_chan, ISO7816_3_PB_NULL);
1129 break;
1130 default:
1131 break;
1132 }
1133 break;
1134 default:
1135 break;
1136 }
Harald Welte9d3e3822015-11-09 00:50:54 +01001137}
1138
1139/* hardware driver informs us that one (more) ETU has expired */
1140void tc_etu_wtime_expired(void *handle)
1141{
Harald Weltedde112e2016-03-20 16:42:11 +01001142 struct card_handle *ch = handle;
Kévin Redonebe672e2018-07-29 00:18:12 +02001143 switch (ch->state) {
1144 case ISO_S_WAIT_ATR:
1145 /* ISO 7816-3 6.2.1 time tc has passed, we can now send the ATR */
1146 card_set_state(ch, ISO_S_IN_ATR);
1147 break;
1148 default:
1149 TRACE_ERROR("%u: wtime_exp\r\n", ch->num);
1150 break;
1151 }
Harald Welte9d3e3822015-11-09 00:50:54 +01001152}
1153
Kévin Redon503e1842019-05-15 00:23:21 +02001154/* shortest ATR possible (uses default speed and no options) */
1155static const uint8_t default_atr[] = { 0x3B, 0x00 };
Harald Welte9d3e3822015-11-09 00:50:54 +01001156
1157static struct card_handle card_handles[NUM_SLOTS];
1158
Kévin Redon7233cf82019-11-14 19:37:32 +01001159struct card_handle *card_emu_init(uint8_t slot_num, uint8_t tc_chan, uint8_t uart_chan, uint8_t in_ep, uint8_t irq_ep, bool vcc_active, bool in_reset, bool clocked)
Harald Welte9d3e3822015-11-09 00:50:54 +01001160{
1161 struct card_handle *ch;
1162
1163 if (slot_num >= ARRAY_SIZE(card_handles))
1164 return NULL;
1165
1166 ch = &card_handles[slot_num];
1167
1168 memset(ch, 0, sizeof(*ch));
1169
Harald Welte54cb3d02016-02-29 14:12:40 +01001170 INIT_LLIST_HEAD(&ch->uart_tx_queue);
1171
Harald Weltedde112e2016-03-20 16:42:11 +01001172 ch->num = slot_num;
Harald Welte8e7fca32017-05-07 16:14:33 +02001173 ch->irq_ep = irq_ep;
1174 ch->in_ep = in_ep;
Harald Welte9d3e3822015-11-09 00:50:54 +01001175 ch->state = ISO_S_WAIT_POWER;
Kévin Redon7233cf82019-11-14 19:37:32 +01001176 ch->vcc_active = vcc_active;
1177 ch->in_reset = in_reset;
1178 ch->clocked = clocked;
Harald Welte9d3e3822015-11-09 00:50:54 +01001179
1180 ch->fi = 0;
1181 ch->di = 1;
1182 ch->wi = ISO7816_3_DEFAULT_WI;
1183
1184 ch->tc_chan = tc_chan;
1185 ch->uart_chan = uart_chan;
1186 ch->waiting_time = ISO7816_3_INIT_WTIME;
1187
1188 ch->atr.idx = 0;
1189 ch->atr.len = sizeof(default_atr);
1190 memcpy(ch->atr.atr, default_atr, ch->atr.len);
1191
1192 ch->pts.state = PTS_S_WAIT_REQ_PTSS;
1193 ch->tpdu.state = TPDU_S_WAIT_CLA;
1194
1195 tc_etu_init(ch->tc_chan, ch);
1196
1197 return ch;
1198}