blob: c3299de0caf7d70a1d5fa9a685f82ffc3ce355f7 [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 *
Harald Weltee92cb502019-12-14 21:48:45 +01003 * (C) 2010-2019 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 Weltee92cb502019-12-14 21:48:45 +0100236/* reset all the 'dynamic' state of the card handle to the initial/default values */
237static void card_handle_reset(struct card_handle *ch)
238{
Harald Welte81f4ef72019-12-14 22:20:00 +0100239 struct msgb *msg;
240
241 tc_etu_disable(ch->tc_chan);
242
Harald Weltee92cb502019-12-14 21:48:45 +0100243 ch->tpdu.state = TPDU_S_WAIT_CLA;
Harald Welte81f4ef72019-12-14 22:20:00 +0100244
245 /* release any buffers we may still own */
246 if (ch->uart_tx_msg) {
247 usb_buf_free(ch->uart_tx_msg);
248 ch->uart_tx_msg = NULL;
249 }
250 if (ch->uart_rx_msg) {
251 usb_buf_free(ch->uart_rx_msg);
252 ch->uart_rx_msg = NULL;
253 }
254 while ((msg = msgb_dequeue(&ch->uart_tx_queue))) {
255 usb_buf_free(msg);
256 }
Harald Weltee92cb502019-12-14 21:48:45 +0100257}
258
Harald Welte54cb3d02016-02-29 14:12:40 +0100259struct llist_head *card_emu_get_uart_tx_queue(struct card_handle *ch)
260{
261 return &ch->uart_tx_queue;
262}
263
Harald Welte2935b3c2015-11-14 20:00:14 +0100264static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts);
Harald Weltee7194ab2015-11-14 21:03:25 +0100265static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss);
Harald Welte2935b3c2015-11-14 20:00:14 +0100266
Harald Welte25a9a802017-05-08 13:30:09 +0200267/* update simtrace header msg_len and submit USB buffer */
268void usb_buf_upd_len_and_submit(struct msgb *msg)
269{
Harald Welteb91f6ad2017-05-10 22:51:30 +0200270 struct simtrace_msg_hdr *sh = (struct simtrace_msg_hdr *) msg->l1h;
Harald Welte25a9a802017-05-08 13:30:09 +0200271
272 sh->msg_len = msgb_length(msg);
273
274 usb_buf_submit(msg);
275}
276
277/* Allocate USB buffer and push + initialize simtrace_msg_hdr */
278struct msgb *usb_buf_alloc_st(uint8_t ep, uint8_t msg_class, uint8_t msg_type)
279{
Kévin Redonc90de692019-11-18 22:32:58 +0100280 struct msgb *msg = NULL;
Harald Welte25a9a802017-05-08 13:30:09 +0200281 struct simtrace_msg_hdr *sh;
282
Kévin Redonc90de692019-11-18 22:32:58 +0100283 while (!msg) {
284 msg = usb_buf_alloc(ep); // try to allocate some memory
285 if (!msg) { // allocation failed, we might be out of memory
Harald Weltef4a625b2019-12-14 19:07:57 +0100286 struct usb_buffered_ep *bep = usb_get_buf_ep(ep);
287 if (!bep) {
Kévin Redonc90de692019-11-18 22:32:58 +0100288 TRACE_ERROR("ep %u: %s queue does not exist\n\r",
289 ep, __func__);
290 return NULL;
291 }
Harald Weltef4a625b2019-12-14 19:07:57 +0100292 if (llist_empty(&bep->queue)) {
Kévin Redonc90de692019-11-18 22:32:58 +0100293 TRACE_ERROR("ep %u: %s EOMEM (queue already empty)\n\r",
294 ep, __func__);
295 return NULL;
296 }
Harald Weltef4a625b2019-12-14 19:07:57 +0100297 msg = msgb_dequeue_count(&bep->queue, &bep->queue_len);
Kévin Redonc90de692019-11-18 22:32:58 +0100298 if (!msg) {
299 TRACE_ERROR("ep %u: %s no msg in non-empty queue\n\r",
300 ep, __func__);
301 return NULL;
302 }
303 usb_buf_free(msg);
304 msg = NULL;
305 TRACE_DEBUG("ep %u: %s queue msg dropped\n\r",
306 ep, __func__);
307 }
308 }
Harald Welte25a9a802017-05-08 13:30:09 +0200309
310 msg->l1h = msgb_put(msg, sizeof(*sh));
311 sh = (struct simtrace_msg_hdr *) msg->l1h;
312 memset(sh, 0, sizeof(*sh));
313 sh->msg_class = msg_class;
314 sh->msg_type = msg_type;
315 msg->l2h = msg->l1h + sizeof(*sh);
316
317 return msg;
318}
319
Kévin Redon680bdab2018-07-18 14:00:57 +0200320/* Update cardemu_usb_msg_rx_data length + submit buffer */
Harald Welteb5288e82015-11-14 21:15:52 +0100321static void flush_rx_buffer(struct card_handle *ch)
322{
Harald Welte8e7fca32017-05-07 16:14:33 +0200323 struct msgb *msg;
Harald Welteb5288e82015-11-14 21:15:52 +0100324 struct cardemu_usb_msg_rx_data *rd;
Harald Welte8e7fca32017-05-07 16:14:33 +0200325 uint32_t data_len;
Harald Welteb5288e82015-11-14 21:15:52 +0100326
Harald Welte8e7fca32017-05-07 16:14:33 +0200327 msg = ch->uart_rx_msg;
328 if (!msg)
Harald Welteb5288e82015-11-14 21:15:52 +0100329 return;
330
Harald Welte8e7fca32017-05-07 16:14:33 +0200331 ch->uart_rx_msg = NULL;
Harald Welteb5288e82015-11-14 21:15:52 +0100332
Kévin Redon680bdab2018-07-18 14:00:57 +0200333 /* store length of data payload field in header */
Harald Welte25a9a802017-05-08 13:30:09 +0200334 rd = (struct cardemu_usb_msg_rx_data *) msg->l2h;
335 rd->data_len = msgb_l2len(msg) - sizeof(*rd);
Harald Welte54cb3d02016-02-29 14:12:40 +0100336
Kévin Redon910e6832018-08-02 17:47:57 +0200337 TRACE_INFO("%u: %s (%u)\n\r",
338 ch->num, __func__, rd->data_len);
339
Harald Welte25a9a802017-05-08 13:30:09 +0200340 usb_buf_upd_len_and_submit(msg);
Harald Welteb5288e82015-11-14 21:15:52 +0100341}
342
Kévin Redon680bdab2018-07-18 14:00:57 +0200343/* convert a non-contiguous PTS request/response into a contiguous
Harald Welte4ba66d02016-02-25 19:38:56 +0100344 * buffer, returning the number of bytes used in the buffer */
345static int serialize_pts(uint8_t *out, const uint8_t *in)
346{
347 int i = 0;
348
349 out[i++] = in[_PTSS];
350 out[i++] = in[_PTS0];
351 if (in[_PTS0] & (1 << 4))
352 out[i++] = in[_PTS1];
353 if (in[_PTS0] & (1 << 5))
354 out[i++] = in[_PTS2];
355 if (in[_PTS0] & (1 << 6))
356 out[i++] = in[_PTS3];
357 out[i++] = in[_PCK];
358
359 return i;
360}
361
Harald Welte17db2f12016-02-26 09:48:57 +0100362static uint8_t csum_pts(const uint8_t *in)
363{
364 uint8_t out[6];
365 int len = serialize_pts(out, in);
366 uint8_t csum = 0;
367 int i;
368
369 /* we don't include the PCK byte in the checksumming process */
370 len -= 1;
371
372 for (i = 0; i < len; i++)
373 csum = csum ^ out[i];
374
375 return csum;
376}
377
Harald Welte4ba66d02016-02-25 19:38:56 +0100378static void flush_pts(struct card_handle *ch)
379{
Harald Welte8e7fca32017-05-07 16:14:33 +0200380 struct msgb *msg;
Harald Welte4ba66d02016-02-25 19:38:56 +0100381 struct cardemu_usb_msg_pts_info *ptsi;
382
Harald Welte25a9a802017-05-08 13:30:09 +0200383 msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_DO_CEMU_PTS);
Harald Welte8e7fca32017-05-07 16:14:33 +0200384 if (!msg)
Harald Welte4ba66d02016-02-25 19:38:56 +0100385 return;
386
Harald Welte25a9a802017-05-08 13:30:09 +0200387 ptsi = (struct cardemu_usb_msg_pts_info *) msgb_put(msg, sizeof(*ptsi));
Harald Welted295b922016-03-18 21:01:36 +0100388 ptsi->pts_len = serialize_pts(ptsi->req, ch->pts.req);
Harald Welte4ba66d02016-02-25 19:38:56 +0100389 serialize_pts(ptsi->resp, ch->pts.resp);
390
Harald Welte25a9a802017-05-08 13:30:09 +0200391 usb_buf_upd_len_and_submit(msg);
Harald Welte4ba66d02016-02-25 19:38:56 +0100392}
393
Harald Welte8c496362016-02-27 16:24:09 +0100394static void emu_update_fidi(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100395{
396 int rc;
397
398 rc = compute_fidi_ratio(ch->fi, ch->di);
399 if (rc > 0 && rc < 0x400) {
Harald Weltedde112e2016-03-20 16:42:11 +0100400 TRACE_INFO("%u: computed Fi(%u) Di(%u) ratio: %d\r\n",
401 ch->num, ch->fi, ch->di, rc);
Harald Welte9d3e3822015-11-09 00:50:54 +0100402 /* make sure UART uses new F/D ratio */
403 card_emu_uart_update_fidi(ch->uart_chan, rc);
404 /* notify ETU timer about this */
405 tc_etu_set_etu(ch->tc_chan, rc);
406 } else
Harald Weltedde112e2016-03-20 16:42:11 +0100407 TRACE_INFO("%u: computed FiDi ration %d unsupported\r\n",
408 ch->num, rc);
Harald Welte9d3e3822015-11-09 00:50:54 +0100409}
410
411/* Update the ISO 7816-3 TPDU receiver state */
412static void card_set_state(struct card_handle *ch,
413 enum iso7816_3_card_state new_state)
414{
Harald Welte903d63a2016-03-20 13:38:39 +0100415 if (ch->state == new_state)
416 return;
417
Kévin Redon2fdcf3b2018-10-15 19:43:15 +0200418 TRACE_DEBUG("%u: 7816 card state %s -> %s\r\n", ch->num,
419 get_value_string(iso7816_3_card_state_names, ch->state),
420 get_value_string(iso7816_3_card_state_names, new_state));
Harald Welte903d63a2016-03-20 13:38:39 +0100421 ch->state = new_state;
422
Harald Welte9d3e3822015-11-09 00:50:54 +0100423 switch (new_state) {
424 case ISO_S_WAIT_POWER:
425 case ISO_S_WAIT_CLK:
426 case ISO_S_WAIT_RST:
427 /* disable Rx and Tx of UART */
428 card_emu_uart_enable(ch->uart_chan, 0);
Kévin Redonac7e73a2019-11-14 20:11:42 +0100429 /* check end activation state (only necessary if the reader to not respect the activation sequence) */
430 if (ch->vcc_active && ch->clocked && !ch->in_reset) {
431 /* enable the TC/ETU counter once reset has been released */
432 tc_etu_enable(ch->tc_chan);
433 /* prepare to send the ATR */
434 card_set_state(ch, ISO_S_WAIT_ATR);
435 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100436 break;
437 case ISO_S_WAIT_ATR:
438 /* Reset to initial Fi / Di ratio */
439 ch->fi = 1;
440 ch->di = 1;
Harald Welte8c496362016-02-27 16:24:09 +0100441 emu_update_fidi(ch);
Kévin Redonebe672e2018-07-29 00:18:12 +0200442 /* the ATR should only be sent 400 to 40k clock cycles after the RESET.
443 * we use the tc_etu mechanism to wait this time.
444 * since the initial ETU is Fd=372/Dd=1 clock cycles long, we have to wait 2-107 ETU.
445 */
446 tc_etu_set_wtime(ch->tc_chan, 2);
447 /* ensure the TC_ETU timer is enabled */
448 tc_etu_enable(ch->tc_chan);
449 break;
450 case ISO_S_IN_ATR:
Kévin Redon680bdab2018-07-18 14:00:57 +0200451 /* initialize to default WI, this will be overwritten if we
Kévin Redonebe672e2018-07-29 00:18:12 +0200452 * send TC2, and it will be programmed into hardware after
Harald Welte9d3e3822015-11-09 00:50:54 +0100453 * ATR is finished */
454 ch->wi = ISO7816_3_DEFAULT_WI;
455 /* update waiting time to initial waiting time */
456 ch->waiting_time = ISO7816_3_INIT_WTIME;
Kévin Redonebe672e2018-07-29 00:18:12 +0200457 /* set initial waiting time */
Harald Welte9d3e3822015-11-09 00:50:54 +0100458 tc_etu_set_wtime(ch->tc_chan, ch->waiting_time);
459 /* Set ATR sub-state to initial state */
460 ch->atr.idx = 0;
Kévin Redonebe672e2018-07-29 00:18:12 +0200461 /* enable USART transmission to reader */
Harald Welte9d3e3822015-11-09 00:50:54 +0100462 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
Kévin Redonebe672e2018-07-29 00:18:12 +0200463 /* trigger USART TX IRQ to sent first ATR byte TS */
464 card_emu_uart_interrupt(ch->uart_chan);
Harald Welte9d3e3822015-11-09 00:50:54 +0100465 break;
466 case ISO_S_WAIT_TPDU:
467 /* enable the receiver, disable transmitter */
Harald Welte2935b3c2015-11-14 20:00:14 +0100468 set_tpdu_state(ch, TPDU_S_WAIT_CLA);
Harald Welte9d3e3822015-11-09 00:50:54 +0100469 card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
470 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100471 case ISO_S_IN_PTS:
472 case ISO_S_IN_TPDU:
473 /* do nothing */
474 break;
475 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100476}
477
Kévin Redonebe672e2018-07-29 00:18:12 +0200478/**********************************************************************
479 * ATR handling
480 **********************************************************************/
481
482/*! Transmit ATR data to reader
483 * @param[in] ch card interface connected to reader
484 * @return numbers of bytes transmitted
485 */
486static int tx_byte_atr(struct card_handle *ch)
487{
488 if (NULL == ch) {
489 TRACE_ERROR("ATR TX: no card handle provided\n\r");
490 return 0;
491 }
492 if (ISO_S_IN_ATR != ch->state) {
493 TRACE_ERROR("%u: ATR TX: no in ATR state\n\r", ch->num);
494 return 0;
495 }
496
497 /* Transmit ATR */
498 if (ch->atr.idx < ch->atr.len) {
499 uint8_t byte = ch->atr.atr[ch->atr.idx++];
500 card_emu_uart_tx(ch->uart_chan, byte);
Kévin Redonebe672e2018-07-29 00:18:12 +0200501 return 1;
502 } else { /* The ATR has been completely transmitted */
Kévin Redon8b8e58b2018-07-30 18:19:11 +0200503 /* search for TC2 to updated WI */
504 ch->wi = ISO7816_3_DEFAULT_WI;
505 if (ch->atr.len >= 2 && ch->atr.atr[1] & 0xf0) { /* Y1 has some data */
506 uint8_t atr_td1 = 2;
507 if (ch->atr.atr[1] & 0x10) { /* TA1 is present */
508 atr_td1++;
509 }
510 if (ch->atr.atr[1] & 0x20) { /* TB1 is present */
511 atr_td1++;
512 }
513 if (ch->atr.atr[1] & 0x40) { /* TC1 is present */
514 atr_td1++;
515 }
516 if (ch->atr.atr[1] & 0x80) { /* TD1 is present */
517 if (ch->atr.len > atr_td1 && ch->atr.atr[atr_td1] & 0xf0) { /* Y2 has some data */
518 uint8_t atr_tc2 = atr_td1+1;
519 if (ch->atr.atr[atr_td1] & 0x10) { /* TA2 is present */
520 atr_tc2++;
521 }
522 if (ch->atr.atr[atr_td1] & 0x20) { /* TB2 is present */
523 atr_tc2++;
524 }
525 if (ch->atr.atr[atr_td1] & 0x40) { /* TC2 is present */
526 if (ch->atr.len > atr_tc2 && ch->atr.atr[atr_tc2]) { /* TC2 encodes WI */
527 ch->wi = ch->atr.atr[atr_tc2]; /* set WI */
528 }
529 }
530 }
531 }
532 }
533 /* update waiting time (see ISO 7816-3 10.2) */
534 ch->waiting_time = ch->wi * 960 * ch->fi;
535 tc_etu_set_wtime(ch->tc_chan, ch->waiting_time);
Kévin Redonebe672e2018-07-29 00:18:12 +0200536 /* go to next state */
537 card_set_state(ch, ISO_S_WAIT_TPDU);
538 return 0;
539 }
540
541 /* return number of bytes transmitted */
542 return 1;
543}
Harald Welte9d3e3822015-11-09 00:50:54 +0100544
545/**********************************************************************
546 * PTS / PPS handling
547 **********************************************************************/
548
Kévin Redon680bdab2018-07-18 14:00:57 +0200549/* Update the PTS sub-state */
Harald Welte9d3e3822015-11-09 00:50:54 +0100550static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss)
551{
Harald Weltedde112e2016-03-20 16:42:11 +0100552 TRACE_DEBUG("%u: 7816 PTS state %u -> %u\r\n",
553 ch->num, ch->pts.state, new_ptss);
Harald Welte9d3e3822015-11-09 00:50:54 +0100554 ch->pts.state = new_ptss;
555}
556
557/* Determine the next PTS state */
558static enum pts_state next_pts_state(struct card_handle *ch)
559{
560 uint8_t is_resp = ch->pts.state & 0x10;
561 uint8_t sstate = ch->pts.state & 0x0f;
562 uint8_t *pts_ptr;
563
564 if (!is_resp)
565 pts_ptr = ch->pts.req;
566 else
567 pts_ptr = ch->pts.resp;
568
569 switch (sstate) {
570 case PTS_S_WAIT_REQ_PTSS:
571 goto from_ptss;
572 case PTS_S_WAIT_REQ_PTS0:
573 goto from_pts0;
574 case PTS_S_WAIT_REQ_PTS1:
575 goto from_pts1;
576 case PTS_S_WAIT_REQ_PTS2:
577 goto from_pts2;
578 case PTS_S_WAIT_REQ_PTS3:
579 goto from_pts3;
580 }
581
582 if (ch->pts.state == PTS_S_WAIT_REQ_PCK)
583 return PTS_S_WAIT_RESP_PTSS;
584
585from_ptss:
586 return PTS_S_WAIT_REQ_PTS0 | is_resp;
587from_pts0:
588 if (pts_ptr[_PTS0] & (1 << 4))
589 return PTS_S_WAIT_REQ_PTS1 | is_resp;
590from_pts1:
591 if (pts_ptr[_PTS0] & (1 << 5))
592 return PTS_S_WAIT_REQ_PTS2 | is_resp;
593from_pts2:
594 if (pts_ptr[_PTS0] & (1 << 6))
595 return PTS_S_WAIT_REQ_PTS3 | is_resp;
596from_pts3:
597 return PTS_S_WAIT_REQ_PCK | is_resp;
598}
599
600
Harald Welteccb8a222016-03-20 13:37:11 +0100601static int
Harald Welte9d3e3822015-11-09 00:50:54 +0100602process_byte_pts(struct card_handle *ch, uint8_t byte)
603{
604 switch (ch->pts.state) {
605 case PTS_S_WAIT_REQ_PTSS:
606 ch->pts.req[_PTSS] = byte;
607 break;
608 case PTS_S_WAIT_REQ_PTS0:
609 ch->pts.req[_PTS0] = byte;
610 break;
611 case PTS_S_WAIT_REQ_PTS1:
612 ch->pts.req[_PTS1] = byte;
613 break;
614 case PTS_S_WAIT_REQ_PTS2:
615 ch->pts.req[_PTS2] = byte;
616 break;
617 case PTS_S_WAIT_REQ_PTS3:
618 ch->pts.req[_PTS3] = byte;
619 break;
620 case PTS_S_WAIT_REQ_PCK:
621 ch->pts.req[_PCK] = byte;
Harald Welte17db2f12016-02-26 09:48:57 +0100622 if (ch->pts.req[_PCK] != csum_pts(ch->pts.req)) {
Harald Weltedde112e2016-03-20 16:42:11 +0100623 TRACE_ERROR("%u: Error in PTS Checksum!\r\n",
624 ch->num);
Harald Welte17db2f12016-02-26 09:48:57 +0100625 /* Wait for the next TPDU */
626 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
627 return ISO_S_WAIT_TPDU;
628 }
Harald Welte4ba66d02016-02-25 19:38:56 +0100629 /* FIXME: check if proposal matches capabilities in ATR */
Harald Welte9d3e3822015-11-09 00:50:54 +0100630 memcpy(ch->pts.resp, ch->pts.req, sizeof(ch->pts.resp));
631 break;
Harald Welte4c473da2015-11-14 13:31:11 +0100632 default:
Harald Weltedde112e2016-03-20 16:42:11 +0100633 TRACE_ERROR("%u: process_byte_pts() in invalid state %u\r\n",
634 ch->num, ch->pts.state);
Harald Welte4c473da2015-11-14 13:31:11 +0100635 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100636 }
637 /* calculate the next state and set it */
638 set_pts_state(ch, next_pts_state(ch));
639
Harald Welte4ba66d02016-02-25 19:38:56 +0100640 if (ch->pts.state == PTS_S_WAIT_RESP_PTSS) {
641 flush_pts(ch);
642 /* activate UART TX to transmit PTS response */
643 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
Harald Welte53079bb2016-03-20 14:58:35 +0100644 /* don't fall-through to the 'return ISO_S_IN_PTS'
645 * below, rather keep ISO7816 state as-is, it will be
646 * further updated by the tx-completion handler */
Harald Welteccb8a222016-03-20 13:37:11 +0100647 return -1;
Harald Welte4ba66d02016-02-25 19:38:56 +0100648 }
649
Harald Welte9d3e3822015-11-09 00:50:54 +0100650 return ISO_S_IN_PTS;
651}
652
653/* return a single byte to be transmitted to the reader */
Harald Welte855ba9e2016-02-24 21:00:46 +0100654static int tx_byte_pts(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100655{
Harald Welte855ba9e2016-02-24 21:00:46 +0100656 uint8_t byte;
657
658 /* 1: Determine the next transmit byte */
Harald Welte9d3e3822015-11-09 00:50:54 +0100659 switch (ch->pts.state) {
660 case PTS_S_WAIT_RESP_PTSS:
Harald Welte855ba9e2016-02-24 21:00:46 +0100661 byte = ch->pts.resp[_PTSS];
Harald Welte9d3e3822015-11-09 00:50:54 +0100662 break;
663 case PTS_S_WAIT_RESP_PTS0:
Harald Welte855ba9e2016-02-24 21:00:46 +0100664 byte = ch->pts.resp[_PTS0];
Harald Welte9d3e3822015-11-09 00:50:54 +0100665 break;
666 case PTS_S_WAIT_RESP_PTS1:
Harald Welte855ba9e2016-02-24 21:00:46 +0100667 byte = ch->pts.resp[_PTS1];
Harald Welte9d3e3822015-11-09 00:50:54 +0100668 /* This must be TA1 */
Harald Welte855ba9e2016-02-24 21:00:46 +0100669 ch->fi = byte >> 4;
670 ch->di = byte & 0xf;
Harald Weltedde112e2016-03-20 16:42:11 +0100671 TRACE_DEBUG("%u: found Fi=%u Di=%u\r\n", ch->num,
672 ch->fi, ch->di);
Harald Welte9d3e3822015-11-09 00:50:54 +0100673 break;
674 case PTS_S_WAIT_RESP_PTS2:
Harald Welte855ba9e2016-02-24 21:00:46 +0100675 byte = ch->pts.resp[_PTS2];
Harald Welte9d3e3822015-11-09 00:50:54 +0100676 break;
677 case PTS_S_WAIT_RESP_PTS3:
Harald Welte855ba9e2016-02-24 21:00:46 +0100678 byte = ch->pts.resp[_PTS3];
Harald Welte9d3e3822015-11-09 00:50:54 +0100679 break;
680 case PTS_S_WAIT_RESP_PCK:
Harald Welte855ba9e2016-02-24 21:00:46 +0100681 byte = ch->pts.resp[_PCK];
Harald Welte855ba9e2016-02-24 21:00:46 +0100682 break;
Harald Welted79dc4f2015-11-14 13:32:21 +0100683 default:
Harald Weltedde112e2016-03-20 16:42:11 +0100684 TRACE_ERROR("%u: get_byte_pts() in invalid state %u\r\n",
685 ch->num, ch->pts.state);
Harald Welte855ba9e2016-02-24 21:00:46 +0100686 return 0;
687 }
688
689 /* 2: Transmit the byte */
690 card_emu_uart_tx(ch->uart_chan, byte);
691
692 /* 3: Update the state */
693
694 switch (ch->pts.state) {
695 case PTS_S_WAIT_RESP_PCK:
Harald Weltec58bba02016-03-20 14:57:53 +0100696 card_emu_uart_wait_tx_idle(ch->uart_chan);
Harald Welte52d55462016-03-20 13:38:05 +0100697 /* update baud rate generator with Fi/Di */
698 emu_update_fidi(ch);
Harald Welte855ba9e2016-02-24 21:00:46 +0100699 /* Wait for the next TPDU */
700 card_set_state(ch, ISO_S_WAIT_TPDU);
Harald Welte855ba9e2016-02-24 21:00:46 +0100701 break;
702 default:
703 /* calculate the next state and set it */
704 set_pts_state(ch, next_pts_state(ch));
Harald Welted79dc4f2015-11-14 13:32:21 +0100705 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100706 }
Harald Welted79dc4f2015-11-14 13:32:21 +0100707
Harald Welte855ba9e2016-02-24 21:00:46 +0100708 /* return number of bytes transmitted */
709 return 1;
Harald Welte9d3e3822015-11-09 00:50:54 +0100710}
711
712
713/**********************************************************************
714 * TPDU handling
715 **********************************************************************/
716
Harald Welte4d804672015-11-14 23:02:38 +0100717
718/* compute number of data bytes according to Chapter 10.3.2 of 7816-3 */
719static unsigned int t0_num_data_bytes(uint8_t p3, int reader_to_card)
720{
721 if (reader_to_card) {
722 return p3;
723 } else {
724 if (p3 == 0)
725 return 256;
726 else
727 return p3;
728 }
729}
730
Harald Welte9d3e3822015-11-09 00:50:54 +0100731/* add a just-received TPDU byte (from reader) to USB buffer */
Harald Welte61bb30e2015-11-14 23:44:14 +0100732static void add_tpdu_byte(struct card_handle *ch, uint8_t byte)
Harald Welte9d3e3822015-11-09 00:50:54 +0100733{
Harald Welte8e7fca32017-05-07 16:14:33 +0200734 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100735 struct cardemu_usb_msg_rx_data *rd;
Harald Welte4d804672015-11-14 23:02:38 +0100736 unsigned int num_data_bytes = t0_num_data_bytes(ch->tpdu.hdr[_P3], 0);
Harald Welte9d3e3822015-11-09 00:50:54 +0100737
738 /* ensure we have a buffer */
Harald Welte8e7fca32017-05-07 16:14:33 +0200739 if (!ch->uart_rx_msg) {
Harald Welte25a9a802017-05-08 13:30:09 +0200740 msg = ch->uart_rx_msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM,
741 SIMTRACE_MSGT_DO_CEMU_RX_DATA);
Harald Welte8e7fca32017-05-07 16:14:33 +0200742 if (!ch->uart_rx_msg) {
Harald Weltedde112e2016-03-20 16:42:11 +0100743 TRACE_ERROR("%u: Received UART byte but ENOMEM\r\n",
744 ch->num);
Harald Welte9d3e3822015-11-09 00:50:54 +0100745 return;
Harald Welte4d804672015-11-14 23:02:38 +0100746 }
Harald Welte25a9a802017-05-08 13:30:09 +0200747 msgb_put(msg, sizeof(*rd));
Harald Welte9d3e3822015-11-09 00:50:54 +0100748 } else
Harald Welte8e7fca32017-05-07 16:14:33 +0200749 msg = ch->uart_rx_msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100750
Harald Welte25a9a802017-05-08 13:30:09 +0200751 rd = (struct cardemu_usb_msg_rx_data *) msg->l2h;
Harald Welte8e7fca32017-05-07 16:14:33 +0200752 msgb_put_u8(msg, byte);
Harald Welte9d3e3822015-11-09 00:50:54 +0100753
754 /* check if the buffer is full. If so, send it */
Harald Welte25a9a802017-05-08 13:30:09 +0200755 if (msgb_l2len(msg) >= sizeof(*rd) + num_data_bytes) {
Harald Welte4d804672015-11-14 23:02:38 +0100756 rd->flags |= CEMU_DATA_F_FINAL;
Harald Welteb5288e82015-11-14 21:15:52 +0100757 flush_rx_buffer(ch);
Harald Welte61bb30e2015-11-14 23:44:14 +0100758 /* We need to transmit the SW now, */
759 set_tpdu_state(ch, TPDU_S_WAIT_TX);
Harald Welte8e7fca32017-05-07 16:14:33 +0200760 } else if (msgb_tailroom(msg) <= 0)
Harald Welte4d804672015-11-14 23:02:38 +0100761 flush_rx_buffer(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100762}
763
764static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts)
765{
Harald Welte05b41c62015-11-14 20:58:48 +0100766 if (ch->tpdu.state == new_ts)
767 return;
768
Kévin Redon2fdcf3b2018-10-15 19:43:15 +0200769 TRACE_DEBUG("%u: 7816 TPDU state %s -> %s\r\n", ch->num,
770 get_value_string(tpdu_state_names, ch->tpdu.state),
771 get_value_string(tpdu_state_names, new_ts));
Harald Welte903d63a2016-03-20 13:38:39 +0100772 ch->tpdu.state = new_ts;
773
Harald Welte9d3e3822015-11-09 00:50:54 +0100774 switch (new_ts) {
775 case TPDU_S_WAIT_CLA:
Harald Welte05b41c62015-11-14 20:58:48 +0100776 case TPDU_S_WAIT_RX:
Harald Welte9d3e3822015-11-09 00:50:54 +0100777 card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
778 break;
779 case TPDU_S_WAIT_PB:
780 /* we just completed the TPDU header from reader to card
781 * and now need to disable the receiver, enable the
782 * transmitter and transmit the procedure byte */
783 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
784 break;
Harald Weltead434402016-03-02 11:18:29 +0100785 default:
786 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100787 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100788}
789
790static enum tpdu_state next_tpdu_state(struct card_handle *ch)
791{
792 switch (ch->tpdu.state) {
793 case TPDU_S_WAIT_CLA:
794 return TPDU_S_WAIT_INS;
795 case TPDU_S_WAIT_INS:
796 return TPDU_S_WAIT_P1;
797 case TPDU_S_WAIT_P1:
798 return TPDU_S_WAIT_P2;
799 case TPDU_S_WAIT_P2:
800 return TPDU_S_WAIT_P3;
801 case TPDU_S_WAIT_P3:
802 return TPDU_S_WAIT_PB;
803 /* simply stay in Rx or Tx by default */
804 case TPDU_S_WAIT_PB:
805 return TPDU_S_WAIT_PB;
806 case TPDU_S_WAIT_RX:
807 return TPDU_S_WAIT_RX;
808 case TPDU_S_WAIT_TX:
809 return TPDU_S_WAIT_TX;
810 }
Harald Welte4c473da2015-11-14 13:31:11 +0100811 /* we should never reach here */
812 assert(0);
813 return -1;
Harald Welte9d3e3822015-11-09 00:50:54 +0100814}
815
816static void send_tpdu_header(struct card_handle *ch)
817{
Harald Welte8e7fca32017-05-07 16:14:33 +0200818 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100819 struct cardemu_usb_msg_rx_data *rd;
Harald Welte8e7fca32017-05-07 16:14:33 +0200820 uint8_t *cur;
Harald Welte9d3e3822015-11-09 00:50:54 +0100821
Harald Weltedde112e2016-03-20 16:42:11 +0100822 TRACE_INFO("%u: %s: %02x %02x %02x %02x %02x\r\n",
823 ch->num, __func__,
Harald Welte43f79492016-02-29 10:06:54 +0100824 ch->tpdu.hdr[0], ch->tpdu.hdr[1],
825 ch->tpdu.hdr[2], ch->tpdu.hdr[3],
826 ch->tpdu.hdr[4]);
827
Harald Welte9d3e3822015-11-09 00:50:54 +0100828 /* if we already/still have a context, send it off */
Harald Welte8e7fca32017-05-07 16:14:33 +0200829 if (ch->uart_rx_msg) {
Harald Weltedde112e2016-03-20 16:42:11 +0100830 TRACE_DEBUG("%u: have old buffer\r\n", ch->num);
Harald Welte8e7fca32017-05-07 16:14:33 +0200831 if (msgb_l2len(ch->uart_rx_msg)) {
Harald Weltedde112e2016-03-20 16:42:11 +0100832 TRACE_DEBUG("%u: flushing old buffer\r\n", ch->num);
Harald Weltef1697e22016-03-02 10:28:54 +0100833 flush_rx_buffer(ch);
834 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100835 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200836 TRACE_DEBUG("%u: allocating new buffer\r\n", ch->num);
837 /* ensure we have a new buffer */
Harald Welte25a9a802017-05-08 13:30:09 +0200838 ch->uart_rx_msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM,
839 SIMTRACE_MSGT_DO_CEMU_RX_DATA);
Harald Welte8e7fca32017-05-07 16:14:33 +0200840 if (!ch->uart_rx_msg) {
841 TRACE_ERROR("%u: %s: ENOMEM\r\n", ch->num, __func__);
842 return;
843 }
844 msg = ch->uart_rx_msg;
Harald Welte25a9a802017-05-08 13:30:09 +0200845 rd = (struct cardemu_usb_msg_rx_data *) msgb_put(msg, sizeof(*rd));
Harald Welte9d3e3822015-11-09 00:50:54 +0100846
Harald Welte8e7fca32017-05-07 16:14:33 +0200847 /* initialize header */
Harald Welte9d3e3822015-11-09 00:50:54 +0100848 rd->flags = CEMU_DATA_F_TPDU_HDR;
Harald Welte9d3e3822015-11-09 00:50:54 +0100849
850 /* copy TPDU header to data field */
Harald Welte8e7fca32017-05-07 16:14:33 +0200851 cur = msgb_put(msg, sizeof(ch->tpdu.hdr));
852 memcpy(cur, ch->tpdu.hdr, sizeof(ch->tpdu.hdr));
Harald Welteb5288e82015-11-14 21:15:52 +0100853 /* rd->data_len is set in flush_rx_buffer() */
Harald Welte9d3e3822015-11-09 00:50:54 +0100854
Harald Welteb5288e82015-11-14 21:15:52 +0100855 flush_rx_buffer(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100856}
857
858static enum iso7816_3_card_state
859process_byte_tpdu(struct card_handle *ch, uint8_t byte)
860{
861 switch (ch->tpdu.state) {
862 case TPDU_S_WAIT_CLA:
863 ch->tpdu.hdr[_CLA] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100864 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100865 break;
866 case TPDU_S_WAIT_INS:
867 ch->tpdu.hdr[_INS] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100868 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100869 break;
870 case TPDU_S_WAIT_P1:
871 ch->tpdu.hdr[_P1] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100872 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100873 break;
874 case TPDU_S_WAIT_P2:
875 ch->tpdu.hdr[_P2] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100876 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100877 break;
878 case TPDU_S_WAIT_P3:
879 ch->tpdu.hdr[_P3] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100880 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100881 /* FIXME: start timer to transmit further 0x60 */
882 /* send the TPDU header as part of a procedure byte
883 * request to the USB host */
884 send_tpdu_header(ch);
885 break;
886 case TPDU_S_WAIT_RX:
Harald Welte61bb30e2015-11-14 23:44:14 +0100887 add_tpdu_byte(ch, byte);
888 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100889 default:
Harald Weltedde112e2016-03-20 16:42:11 +0100890 TRACE_ERROR("%u: process_byte_tpdu() in invalid state %u\r\n",
891 ch->num, ch->tpdu.state);
Harald Welte9d3e3822015-11-09 00:50:54 +0100892 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100893
894 /* ensure we stay in TPDU ISO state */
895 return ISO_S_IN_TPDU;
896}
897
Harald Welte855ba9e2016-02-24 21:00:46 +0100898/* tx a single byte to be transmitted to the reader */
899static int tx_byte_tpdu(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100900{
Harald Welte8e7fca32017-05-07 16:14:33 +0200901 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100902 struct cardemu_usb_msg_tx_data *td;
Harald Welte855ba9e2016-02-24 21:00:46 +0100903 uint8_t byte;
Harald Welte9d3e3822015-11-09 00:50:54 +0100904
905 /* ensure we are aware of any data that might be pending for
906 * transmit */
Harald Welte8e7fca32017-05-07 16:14:33 +0200907 if (!ch->uart_tx_msg) {
Harald Welte53079bb2016-03-20 14:58:35 +0100908 /* uart_tx_queue is filled from main loop, so no need
909 * for irq-safe operations */
Harald Welte54cb3d02016-02-29 14:12:40 +0100910 if (llist_empty(&ch->uart_tx_queue))
Harald Welte9d3e3822015-11-09 00:50:54 +0100911 return 0;
912
Harald Welte54cb3d02016-02-29 14:12:40 +0100913 /* dequeue first at head */
Harald Welte8e7fca32017-05-07 16:14:33 +0200914 ch->uart_tx_msg = msgb_dequeue(&ch->uart_tx_queue);
Harald Welte25a9a802017-05-08 13:30:09 +0200915 ch->uart_tx_msg->l1h = ch->uart_tx_msg->head;
916 ch->uart_tx_msg->l2h = ch->uart_tx_msg->l1h + sizeof(struct simtrace_msg_hdr);
Harald Welte8e7fca32017-05-07 16:14:33 +0200917 msg = ch->uart_tx_msg;
Harald Welte25a9a802017-05-08 13:30:09 +0200918 /* remove the header */
919 msgb_pull(msg, sizeof(struct simtrace_msg_hdr) + sizeof(*td));
Harald Welte9d3e3822015-11-09 00:50:54 +0100920 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200921 msg = ch->uart_tx_msg;
Harald Welte25a9a802017-05-08 13:30:09 +0200922 td = (struct cardemu_usb_msg_tx_data *) msg->l2h;
Harald Welte9d3e3822015-11-09 00:50:54 +0100923
Harald Welte8e7fca32017-05-07 16:14:33 +0200924 /* take the next pending byte out of the msgb */
925 byte = msgb_pull_u8(msg);
Harald Welte855ba9e2016-02-24 21:00:46 +0100926
927 card_emu_uart_tx(ch->uart_chan, byte);
Harald Welte9d3e3822015-11-09 00:50:54 +0100928
Kévin Redon0f4abf52018-08-02 17:42:48 +0200929 /* this must happen _after_ the byte has been transmitted */
Harald Weltef16b6182016-02-24 22:18:46 +0100930 switch (ch->tpdu.state) {
931 case TPDU_S_WAIT_PB:
932 /* if we just transmitted the procedure byte, we need to decide
933 * if we want to continue to receive or transmit */
934 if (td->flags & CEMU_DATA_F_PB_AND_TX)
935 set_tpdu_state(ch, TPDU_S_WAIT_TX);
936 else if (td->flags & CEMU_DATA_F_PB_AND_RX)
937 set_tpdu_state(ch, TPDU_S_WAIT_RX);
938 break;
Harald Weltead434402016-03-02 11:18:29 +0100939 default:
940 break;
Harald Weltef16b6182016-02-24 22:18:46 +0100941 }
942
Harald Welte9d3e3822015-11-09 00:50:54 +0100943 /* check if the buffer has now been fully transmitted */
Harald Welte8e7fca32017-05-07 16:14:33 +0200944 if (msgb_length(msg) == 0) {
Harald Welte52922ff2015-11-14 20:59:56 +0100945 if (td->flags & CEMU_DATA_F_PB_AND_RX) {
946 /* we have just sent the procedure byte and now
947 * need to continue receiving */
948 set_tpdu_state(ch, TPDU_S_WAIT_RX);
Harald Welte2935b3c2015-11-14 20:00:14 +0100949 } else {
Harald Welte52922ff2015-11-14 20:59:56 +0100950 /* we have transmitted all bytes */
951 if (td->flags & CEMU_DATA_F_FINAL) {
952 /* this was the final part of the APDU, go
Harald Welte53079bb2016-03-20 14:58:35 +0100953 * back to state one */
Harald Welte52922ff2015-11-14 20:59:56 +0100954 card_set_state(ch, ISO_S_WAIT_TPDU);
Harald Welte52922ff2015-11-14 20:59:56 +0100955 }
Harald Welte2935b3c2015-11-14 20:00:14 +0100956 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200957 usb_buf_free(msg);
958 ch->uart_tx_msg = NULL;
Harald Welte9d3e3822015-11-09 00:50:54 +0100959 }
960
961 return 1;
962}
963
964/**********************************************************************
965 * Public API
966 **********************************************************************/
967
968/* process a single byte received from the reader */
969void card_emu_process_rx_byte(struct card_handle *ch, uint8_t byte)
970{
971 int new_state = -1;
972
973 ch->stats.rx_bytes++;
974
975 switch (ch->state) {
Harald Welte9d3e3822015-11-09 00:50:54 +0100976 case ISO_S_WAIT_TPDU:
977 if (byte == 0xff) {
Harald Welte02d0d732019-12-15 13:19:24 +0100978 /* reset PTS to initial state */
979 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
Harald Welte9d3e3822015-11-09 00:50:54 +0100980 new_state = process_byte_pts(ch, byte);
981 ch->stats.pps++;
982 goto out_silent;
983 }
984 /* fall-through */
985 case ISO_S_IN_TPDU:
986 new_state = process_byte_tpdu(ch, byte);
987 break;
988 case ISO_S_IN_PTS:
989 new_state = process_byte_pts(ch, byte);
990 goto out_silent;
Kévin Redon5f6b8712018-07-11 09:49:06 +0200991 default:
992 TRACE_ERROR("%u: Received UART char in invalid 7816 state "
993 "%u\r\n", ch->num, ch->state);
994 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100995 }
996
997out_silent:
998 if (new_state != -1)
999 card_set_state(ch, new_state);
1000}
1001
Harald Welte855ba9e2016-02-24 21:00:46 +01001002/* transmit a single byte to the reader */
1003int card_emu_tx_byte(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +01001004{
1005 int rc = 0;
1006
1007 switch (ch->state) {
1008 case ISO_S_IN_ATR:
Kévin Redonebe672e2018-07-29 00:18:12 +02001009 rc = tx_byte_atr(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +01001010 break;
1011 case ISO_S_IN_PTS:
Harald Welte855ba9e2016-02-24 21:00:46 +01001012 rc = tx_byte_pts(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +01001013 break;
1014 case ISO_S_IN_TPDU:
Harald Welte855ba9e2016-02-24 21:00:46 +01001015 rc = tx_byte_tpdu(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +01001016 break;
Harald Weltead434402016-03-02 11:18:29 +01001017 default:
1018 break;
Harald Welte9d3e3822015-11-09 00:50:54 +01001019 }
1020
1021 if (rc)
1022 ch->stats.tx_bytes++;
1023
Harald Welte4d804672015-11-14 23:02:38 +01001024 /* if we return 0 here, the UART needs to disable transmit-ready
1025 * interrupts */
Harald Welte9d3e3822015-11-09 00:50:54 +01001026 return rc;
1027}
1028
Harald Welteacae4122016-03-02 10:27:58 +01001029void card_emu_have_new_uart_tx(struct card_handle *ch)
1030{
1031 switch (ch->state) {
1032 case ISO_S_IN_TPDU:
1033 switch (ch->tpdu.state) {
1034 case TPDU_S_WAIT_TX:
1035 case TPDU_S_WAIT_PB:
1036 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
1037 break;
1038 default:
1039 break;
1040 }
1041 default:
1042 break;
1043 }
1044}
1045
Harald Welteff160652016-03-19 21:59:06 +01001046void card_emu_report_status(struct card_handle *ch)
1047{
Harald Welte8e7fca32017-05-07 16:14:33 +02001048 struct msgb *msg;
Harald Welteff160652016-03-19 21:59:06 +01001049 struct cardemu_usb_msg_status *sts;
1050
Harald Welte25a9a802017-05-08 13:30:09 +02001051 msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM,
1052 SIMTRACE_MSGT_BD_CEMU_STATUS);
Harald Welte8e7fca32017-05-07 16:14:33 +02001053 if (!msg)
Harald Welteff160652016-03-19 21:59:06 +01001054 return;
Harald Welte8e7fca32017-05-07 16:14:33 +02001055
Harald Welte25a9a802017-05-08 13:30:09 +02001056 sts = (struct cardemu_usb_msg_status *) msgb_put(msg, sizeof(*sts));
Harald Welteff160652016-03-19 21:59:06 +01001057 sts->flags = 0;
1058 if (ch->vcc_active)
1059 sts->flags |= CEMU_STATUS_F_VCC_PRESENT;
1060 if (ch->clocked)
1061 sts->flags |= CEMU_STATUS_F_CLK_ACTIVE;
1062 if (ch->in_reset)
1063 sts->flags |= CEMU_STATUS_F_RESET_ACTIVE;
1064 /* FIXME: voltage + card insert */
1065 sts->fi = ch->fi;
1066 sts->di = ch->di;
1067 sts->wi = ch->wi;
1068 sts->waiting_time = ch->waiting_time;
1069
Harald Welte25a9a802017-05-08 13:30:09 +02001070 usb_buf_upd_len_and_submit(msg);
Harald Welteff160652016-03-19 21:59:06 +01001071}
1072
Harald Welte9d3e3822015-11-09 00:50:54 +01001073/* hardware driver informs us that a card I/O signal has changed */
1074void card_emu_io_statechg(struct card_handle *ch, enum card_io io, int active)
1075{
1076 switch (io) {
1077 case CARD_IO_VCC:
Harald Welte47ee2832016-02-29 10:09:46 +01001078 if (active == 0 && ch->vcc_active == 1) {
Harald Weltedde112e2016-03-20 16:42:11 +01001079 TRACE_INFO("%u: VCC deactivated\r\n", ch->num);
Harald Welte81f4ef72019-12-14 22:20:00 +01001080 card_handle_reset(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +01001081 card_set_state(ch, ISO_S_WAIT_POWER);
Harald Welte47ee2832016-02-29 10:09:46 +01001082 } else if (active == 1 && ch->vcc_active == 0) {
Harald Weltedde112e2016-03-20 16:42:11 +01001083 TRACE_INFO("%u: VCC activated\r\n", ch->num);
Harald Welte9d3e3822015-11-09 00:50:54 +01001084 card_set_state(ch, ISO_S_WAIT_CLK);
Harald Welte47ee2832016-02-29 10:09:46 +01001085 }
Harald Welte9d3e3822015-11-09 00:50:54 +01001086 ch->vcc_active = active;
1087 break;
1088 case CARD_IO_CLK:
Harald Welte47ee2832016-02-29 10:09:46 +01001089 if (active == 1 && ch->clocked == 0) {
Harald Weltedde112e2016-03-20 16:42:11 +01001090 TRACE_INFO("%u: CLK activated\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +01001091 if (ch->state == ISO_S_WAIT_CLK)
1092 card_set_state(ch, ISO_S_WAIT_RST);
1093 } else if (active == 0 && ch->clocked == 1) {
Harald Weltedde112e2016-03-20 16:42:11 +01001094 TRACE_INFO("%u: CLK deactivated\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +01001095 }
Harald Welte9d3e3822015-11-09 00:50:54 +01001096 ch->clocked = active;
1097 break;
1098 case CARD_IO_RST:
Harald Welte47ee2832016-02-29 10:09:46 +01001099 if (active == 0 && ch->in_reset) {
Harald Weltedde112e2016-03-20 16:42:11 +01001100 TRACE_INFO("%u: RST released\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +01001101 if (ch->vcc_active && ch->clocked) {
1102 /* enable the TC/ETU counter once reset has been released */
1103 tc_etu_enable(ch->tc_chan);
Kévin Redonebe672e2018-07-29 00:18:12 +02001104 /* prepare to send the ATR */
Harald Welte47ee2832016-02-29 10:09:46 +01001105 card_set_state(ch, ISO_S_WAIT_ATR);
Harald Welte47ee2832016-02-29 10:09:46 +01001106 }
1107 } else if (active && !ch->in_reset) {
Harald Weltedde112e2016-03-20 16:42:11 +01001108 TRACE_INFO("%u: RST asserted\r\n", ch->num);
Harald Welte81f4ef72019-12-14 22:20:00 +01001109 card_handle_reset(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +01001110 }
1111 ch->in_reset = active;
1112 break;
1113 }
1114}
1115
1116/* User sets a new ATR to be returned during next card reset */
1117int card_emu_set_atr(struct card_handle *ch, const uint8_t *atr, uint8_t len)
1118{
1119 if (len > sizeof(ch->atr.atr))
1120 return -1;
1121
1122 memcpy(ch->atr.atr, atr, len);
1123 ch->atr.len = len;
1124 ch->atr.idx = 0;
1125
Kévin Redonebe672e2018-07-29 00:18:12 +02001126#if TRACE_LEVEL >= TRACE_LEVEL_INFO
1127 uint8_t i;
1128 TRACE_INFO("%u: ATR set: ", ch->num);
1129 for (i = 0; i < ch->atr.len; i++) {
1130 TRACE_INFO_WP("%02x ", atr[i]);
1131 }
1132 TRACE_INFO_WP("\n\r");
1133#endif
1134 /* FIXME: race condition with transmitting ATR to reader? */
Harald Welte9d3e3822015-11-09 00:50:54 +01001135
1136 return 0;
1137}
1138
1139/* hardware driver informs us that one (more) ETU has expired */
1140void tc_etu_wtime_half_expired(void *handle)
1141{
1142 struct card_handle *ch = handle;
1143 /* transmit NULL procedure byte well before waiting time expires */
Harald Weltedda73552016-03-02 10:29:55 +01001144 switch (ch->state) {
1145 case ISO_S_IN_TPDU:
1146 switch (ch->tpdu.state) {
1147 case TPDU_S_WAIT_PB:
1148 case TPDU_S_WAIT_TX:
1149 putchar('N');
1150 card_emu_uart_tx(ch->uart_chan, ISO7816_3_PB_NULL);
1151 break;
1152 default:
1153 break;
1154 }
1155 break;
1156 default:
1157 break;
1158 }
Harald Welte9d3e3822015-11-09 00:50:54 +01001159}
1160
1161/* hardware driver informs us that one (more) ETU has expired */
1162void tc_etu_wtime_expired(void *handle)
1163{
Harald Weltedde112e2016-03-20 16:42:11 +01001164 struct card_handle *ch = handle;
Kévin Redonebe672e2018-07-29 00:18:12 +02001165 switch (ch->state) {
1166 case ISO_S_WAIT_ATR:
1167 /* ISO 7816-3 6.2.1 time tc has passed, we can now send the ATR */
1168 card_set_state(ch, ISO_S_IN_ATR);
1169 break;
1170 default:
1171 TRACE_ERROR("%u: wtime_exp\r\n", ch->num);
1172 break;
1173 }
Harald Welte9d3e3822015-11-09 00:50:54 +01001174}
1175
Kévin Redon503e1842019-05-15 00:23:21 +02001176/* shortest ATR possible (uses default speed and no options) */
1177static const uint8_t default_atr[] = { 0x3B, 0x00 };
Harald Welte9d3e3822015-11-09 00:50:54 +01001178
1179static struct card_handle card_handles[NUM_SLOTS];
1180
Kévin Redon7233cf82019-11-14 19:37:32 +01001181struct 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 +01001182{
1183 struct card_handle *ch;
1184
1185 if (slot_num >= ARRAY_SIZE(card_handles))
1186 return NULL;
1187
1188 ch = &card_handles[slot_num];
1189
1190 memset(ch, 0, sizeof(*ch));
1191
Harald Welte54cb3d02016-02-29 14:12:40 +01001192 INIT_LLIST_HEAD(&ch->uart_tx_queue);
1193
Harald Weltedde112e2016-03-20 16:42:11 +01001194 ch->num = slot_num;
Harald Welte8e7fca32017-05-07 16:14:33 +02001195 ch->irq_ep = irq_ep;
1196 ch->in_ep = in_ep;
Harald Welte9d3e3822015-11-09 00:50:54 +01001197 ch->state = ISO_S_WAIT_POWER;
Kévin Redon7233cf82019-11-14 19:37:32 +01001198 ch->vcc_active = vcc_active;
1199 ch->in_reset = in_reset;
1200 ch->clocked = clocked;
Harald Welte9d3e3822015-11-09 00:50:54 +01001201
1202 ch->fi = 0;
1203 ch->di = 1;
1204 ch->wi = ISO7816_3_DEFAULT_WI;
1205
1206 ch->tc_chan = tc_chan;
1207 ch->uart_chan = uart_chan;
1208 ch->waiting_time = ISO7816_3_INIT_WTIME;
1209
1210 ch->atr.idx = 0;
1211 ch->atr.len = sizeof(default_atr);
1212 memcpy(ch->atr.atr, default_atr, ch->atr.len);
1213
Harald Weltee92cb502019-12-14 21:48:45 +01001214 card_handle_reset(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +01001215
1216 tc_etu_init(ch->tc_chan, ch);
1217
1218 return ch;
1219}