blob: 8da844f00673b47319a0c8ffc1a8b11a5da92151 [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
Harald Weltea5bbe782019-12-16 10:39:55 +010040/* bit-mask of supported CEMU_FEAT_F_ flags */
41#define SUPPORTED_FEATURES 0
42
Harald Welte9d3e3822015-11-09 00:50:54 +010043#define ISO7816_3_INIT_WTIME 9600
44#define ISO7816_3_DEFAULT_WI 10
45#define ISO7816_3_ATR_LEN_MAX (1+32) /* TS plus 32 chars */
46
47#define ISO7816_3_PB_NULL 0x60
48
49enum iso7816_3_card_state {
50 ISO_S_WAIT_POWER, /* waiting for power being applied */
51 ISO_S_WAIT_CLK, /* waiting for clock being applied */
52 ISO_S_WAIT_RST, /* waiting for reset being released */
53 ISO_S_WAIT_ATR, /* waiting for start of ATR */
54 ISO_S_IN_ATR, /* transmitting ATR to reader */
55 ISO_S_IN_PTS, /* transmitting ATR to reader */
56 ISO_S_WAIT_TPDU, /* waiting for data from reader */
57 ISO_S_IN_TPDU, /* inside a TPDU */
58};
59
Kévin Redon8a4fba52018-08-02 17:44:16 +020060const struct value_string iso7816_3_card_state_names[] = {
Kévin Redon2fdcf3b2018-10-15 19:43:15 +020061 {
62 .value = ISO_S_WAIT_POWER,
63 .str = "WAIT_POWER",
64 },
65 {
66 .value = ISO_S_WAIT_CLK,
67 .str = "WAIT_CLK",
68 },
69 {
70 .value = ISO_S_WAIT_RST,
71 .str = "WAIT_RST",
72 },
73 {
74 .value = ISO_S_WAIT_ATR,
75 .str = "WAIT_ATR",
76 },
77 {
78 .value = ISO_S_IN_ATR,
79 .str = "IN_ATR",
80 },
81 {
82 .value = ISO_S_IN_PTS,
83 .str = "IN_PTS",
84 },
85 {
86 .value = ISO_S_WAIT_TPDU,
87 .str = "WAIT_TPDU",
88 },
89 {
90 .value = ISO_S_IN_TPDU,
91 .str = "IN_TPDU",
92 },
Kévin Redon8a4fba52018-08-02 17:44:16 +020093 {
94 .value = 0,
95 .str = NULL,
96 },
97};
98
99
Harald Welte9d3e3822015-11-09 00:50:54 +0100100/* detailed sub-states of ISO_S_IN_PTS */
101enum pts_state {
102 PTS_S_WAIT_REQ_PTSS,
103 PTS_S_WAIT_REQ_PTS0,
104 PTS_S_WAIT_REQ_PTS1,
105 PTS_S_WAIT_REQ_PTS2,
106 PTS_S_WAIT_REQ_PTS3,
107 PTS_S_WAIT_REQ_PCK,
108 PTS_S_WAIT_RESP_PTSS = PTS_S_WAIT_REQ_PTSS | 0x10,
109 PTS_S_WAIT_RESP_PTS0 = PTS_S_WAIT_REQ_PTS0 | 0x10,
110 PTS_S_WAIT_RESP_PTS1 = PTS_S_WAIT_REQ_PTS1 | 0x10,
111 PTS_S_WAIT_RESP_PTS2 = PTS_S_WAIT_REQ_PTS2 | 0x10,
112 PTS_S_WAIT_RESP_PTS3 = PTS_S_WAIT_REQ_PTS3 | 0x10,
113 PTS_S_WAIT_RESP_PCK = PTS_S_WAIT_REQ_PCK | 0x10,
114};
115
Harald Welte6a3a7142019-12-16 14:23:02 +0100116const struct value_string pts_state_names[] = {
117 { PTS_S_WAIT_REQ_PTSS, "WAIT_REQ_PTSS" },
118 { PTS_S_WAIT_REQ_PTS0, "WAIT_REQ_PTS0" },
119 { PTS_S_WAIT_REQ_PTS1, "WAIT_REQ_PTS1" },
120 { PTS_S_WAIT_REQ_PTS2, "WAIT_REQ_PTS2" },
121 { PTS_S_WAIT_REQ_PTS3, "WAIT_REQ_PTS3" },
122 { PTS_S_WAIT_REQ_PCK, "WAIT_REQ_PCK" },
123 { PTS_S_WAIT_RESP_PTSS, "WAIT_RESP_PTSS" },
124 { PTS_S_WAIT_RESP_PTS0, "WAIT_RESP_PTS0" },
125 { PTS_S_WAIT_RESP_PTS1, "WAIT_RESP_PTS1" },
126 { PTS_S_WAIT_RESP_PTS2, "WAIT_RESP_PTS2" },
127 { PTS_S_WAIT_RESP_PTS3, "WAIT_RESP_PTS3" },
128 { PTS_S_WAIT_RESP_PCK, "WAIT_RESP_PCK" },
129 { 0, NULL }
130};
131
Kévin Redon2fdcf3b2018-10-15 19:43:15 +0200132/* PTS field byte index */
Harald Welte9d3e3822015-11-09 00:50:54 +0100133#define _PTSS 0
134#define _PTS0 1
135#define _PTS1 2
136#define _PTS2 3
137#define _PTS3 4
138#define _PCK 5
139
Harald Welte16cf4082015-11-11 19:02:48 +0100140/* T-PDU state machine states */
Harald Welte9d3e3822015-11-09 00:50:54 +0100141enum tpdu_state {
Harald Welte16cf4082015-11-11 19:02:48 +0100142 TPDU_S_WAIT_CLA, /* waiting for CLA byte from reader */
143 TPDU_S_WAIT_INS, /* waiting for INS byte from reader */
144 TPDU_S_WAIT_P1, /* waiting for P1 byte from reader */
145 TPDU_S_WAIT_P2, /* waiting for P2 byte from reader */
146 TPDU_S_WAIT_P3, /* waiting for P3 byte from reader */
Harald Welte9d3e3822015-11-09 00:50:54 +0100147 TPDU_S_WAIT_PB, /* waiting for Tx of procedure byte */
Kévin Redon0f4abf52018-08-02 17:42:48 +0200148 TPDU_S_WAIT_RX, /* waiting for more data from reader */
Harald Welte9d3e3822015-11-09 00:50:54 +0100149 TPDU_S_WAIT_TX, /* waiting for more data to reader */
150};
151
Kévin Redon2fdcf3b2018-10-15 19:43:15 +0200152const struct value_string tpdu_state_names[] = {
153 {
154 .value = TPDU_S_WAIT_CLA,
155 .str = "WAIT_CLA",
156 },
157 {
158 .value = TPDU_S_WAIT_INS,
159 .str = "WAIT_INS",
160 },
161 {
162 .value = TPDU_S_WAIT_P1,
163 .str = "WAIT_P1",
164 },
165 {
166 .value = TPDU_S_WAIT_P2,
167 .str = "WAIT_P2",
168 },
169 {
170 .value = TPDU_S_WAIT_P3,
171 .str = "WAIT_P3",
172 },
173 {
174 .value = TPDU_S_WAIT_PB,
175 .str = "WAIT_PB",
176 },
177 {
178 .value = TPDU_S_WAIT_RX,
179 .str = "WAIT_RX",
180 },
181 {
182 .value = TPDU_S_WAIT_TX,
183 .str = "WAIT_TX",
184 },
185 {
186 .value = 0,
187 .str = NULL,
188 },
189};
190
191/* TPDU field byte index */
Harald Welte9d3e3822015-11-09 00:50:54 +0100192#define _CLA 0
193#define _INS 1
194#define _P1 2
195#define _P2 3
196#define _P3 4
197
198struct card_handle {
Harald Weltec3941092018-08-26 09:53:13 +0200199 unsigned int num;
Harald Weltedde112e2016-03-20 16:42:11 +0100200
Harald Weltea5bbe782019-12-16 10:39:55 +0100201 /* bit-mask of enabled optional features (CEMU_FEAT_F_*) */
202 uint32_t features;
203
Harald Welte9d3e3822015-11-09 00:50:54 +0100204 enum iso7816_3_card_state state;
205
206 /* signal levels */
Kévin Redon7233cf82019-11-14 19:37:32 +0100207 bool vcc_active; /*< if VCC is active (true = active/ON) */
208 bool in_reset; /*< if card is in reset (true = RST low/asserted, false = RST high/ released) */
209 bool clocked; /*< if clock is active ( true = active, false = inactive) */
Harald Welte9d3e3822015-11-09 00:50:54 +0100210
Harald Welte16cf4082015-11-11 19:02:48 +0100211 /* timing parameters, from PTS */
Harald Welte9d3e3822015-11-09 00:50:54 +0100212 uint8_t fi;
213 uint8_t di;
214 uint8_t wi;
215
216 uint8_t tc_chan; /* TC channel number */
217 uint8_t uart_chan; /* UART channel */
218
Harald Welte8e7fca32017-05-07 16:14:33 +0200219 uint8_t in_ep; /* USB IN EP */
220 uint8_t irq_ep; /* USB IN EP */
221
Harald Welte9d3e3822015-11-09 00:50:54 +0100222 uint32_t waiting_time; /* in clocks */
223
224 /* ATR state machine */
225 struct {
226 uint8_t idx;
227 uint8_t len;
228 //uint8_t hist_len;
229 //uint8_t last_td;
230 uint8_t atr[ISO7816_3_ATR_LEN_MAX];
231 } atr;
232
233 /* PPS / PTS support */
234 struct {
235 enum pts_state state;
Harald Welte16cf4082015-11-11 19:02:48 +0100236 uint8_t req[6]; /* request bytes */
237 uint8_t resp[6]; /* response bytes */
Harald Welte9d3e3822015-11-09 00:50:54 +0100238 } pts;
239
240 /* TPDU */
241 struct {
242 enum tpdu_state state;
Harald Welte16cf4082015-11-11 19:02:48 +0100243 uint8_t hdr[5]; /* CLA INS P1 P2 P3 */
Harald Welte9d3e3822015-11-09 00:50:54 +0100244 } tpdu;
245
Harald Welte8e7fca32017-05-07 16:14:33 +0200246 struct msgb *uart_rx_msg; /* UART RX -> USB TX */
247 struct msgb *uart_tx_msg; /* USB RX -> UART TX */
Harald Welte9d3e3822015-11-09 00:50:54 +0100248
Harald Welte54cb3d02016-02-29 14:12:40 +0100249 struct llist_head uart_tx_queue;
250
Harald Welte9d3e3822015-11-09 00:50:54 +0100251 struct {
252 uint32_t tx_bytes;
253 uint32_t rx_bytes;
254 uint32_t pps;
255 } stats;
256};
257
Harald Weltee92cb502019-12-14 21:48:45 +0100258/* reset all the 'dynamic' state of the card handle to the initial/default values */
259static void card_handle_reset(struct card_handle *ch)
260{
Harald Welte81f4ef72019-12-14 22:20:00 +0100261 struct msgb *msg;
262
263 tc_etu_disable(ch->tc_chan);
264
Harald Welte81f4ef72019-12-14 22:20:00 +0100265 /* release any buffers we may still own */
266 if (ch->uart_tx_msg) {
267 usb_buf_free(ch->uart_tx_msg);
268 ch->uart_tx_msg = NULL;
269 }
270 if (ch->uart_rx_msg) {
271 usb_buf_free(ch->uart_rx_msg);
272 ch->uart_rx_msg = NULL;
273 }
274 while ((msg = msgb_dequeue(&ch->uart_tx_queue))) {
275 usb_buf_free(msg);
276 }
Harald Weltee92cb502019-12-14 21:48:45 +0100277}
278
Harald Welte54cb3d02016-02-29 14:12:40 +0100279struct llist_head *card_emu_get_uart_tx_queue(struct card_handle *ch)
280{
281 return &ch->uart_tx_queue;
282}
283
Harald Welte2935b3c2015-11-14 20:00:14 +0100284static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts);
Harald Weltee7194ab2015-11-14 21:03:25 +0100285static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss);
Harald Welte2935b3c2015-11-14 20:00:14 +0100286
Harald Welte25a9a802017-05-08 13:30:09 +0200287/* update simtrace header msg_len and submit USB buffer */
288void usb_buf_upd_len_and_submit(struct msgb *msg)
289{
Harald Welteb91f6ad2017-05-10 22:51:30 +0200290 struct simtrace_msg_hdr *sh = (struct simtrace_msg_hdr *) msg->l1h;
Harald Welte25a9a802017-05-08 13:30:09 +0200291
292 sh->msg_len = msgb_length(msg);
293
294 usb_buf_submit(msg);
295}
296
297/* Allocate USB buffer and push + initialize simtrace_msg_hdr */
298struct msgb *usb_buf_alloc_st(uint8_t ep, uint8_t msg_class, uint8_t msg_type)
299{
Kévin Redonc90de692019-11-18 22:32:58 +0100300 struct msgb *msg = NULL;
Harald Welte25a9a802017-05-08 13:30:09 +0200301 struct simtrace_msg_hdr *sh;
302
Kévin Redonc90de692019-11-18 22:32:58 +0100303 while (!msg) {
304 msg = usb_buf_alloc(ep); // try to allocate some memory
305 if (!msg) { // allocation failed, we might be out of memory
Harald Weltef4a625b2019-12-14 19:07:57 +0100306 struct usb_buffered_ep *bep = usb_get_buf_ep(ep);
307 if (!bep) {
Kévin Redonc90de692019-11-18 22:32:58 +0100308 TRACE_ERROR("ep %u: %s queue does not exist\n\r",
309 ep, __func__);
310 return NULL;
311 }
Harald Weltef4a625b2019-12-14 19:07:57 +0100312 if (llist_empty(&bep->queue)) {
Kévin Redonc90de692019-11-18 22:32:58 +0100313 TRACE_ERROR("ep %u: %s EOMEM (queue already empty)\n\r",
314 ep, __func__);
315 return NULL;
316 }
Harald Weltef4a625b2019-12-14 19:07:57 +0100317 msg = msgb_dequeue_count(&bep->queue, &bep->queue_len);
Kévin Redonc90de692019-11-18 22:32:58 +0100318 if (!msg) {
319 TRACE_ERROR("ep %u: %s no msg in non-empty queue\n\r",
320 ep, __func__);
321 return NULL;
322 }
323 usb_buf_free(msg);
324 msg = NULL;
325 TRACE_DEBUG("ep %u: %s queue msg dropped\n\r",
326 ep, __func__);
327 }
328 }
Harald Welte25a9a802017-05-08 13:30:09 +0200329
330 msg->l1h = msgb_put(msg, sizeof(*sh));
331 sh = (struct simtrace_msg_hdr *) msg->l1h;
332 memset(sh, 0, sizeof(*sh));
333 sh->msg_class = msg_class;
334 sh->msg_type = msg_type;
335 msg->l2h = msg->l1h + sizeof(*sh);
336
337 return msg;
338}
339
Kévin Redon680bdab2018-07-18 14:00:57 +0200340/* Update cardemu_usb_msg_rx_data length + submit buffer */
Harald Welteb5288e82015-11-14 21:15:52 +0100341static void flush_rx_buffer(struct card_handle *ch)
342{
Harald Welte8e7fca32017-05-07 16:14:33 +0200343 struct msgb *msg;
Harald Welteb5288e82015-11-14 21:15:52 +0100344 struct cardemu_usb_msg_rx_data *rd;
Harald Welte8e7fca32017-05-07 16:14:33 +0200345 uint32_t data_len;
Harald Welteb5288e82015-11-14 21:15:52 +0100346
Harald Welte8e7fca32017-05-07 16:14:33 +0200347 msg = ch->uart_rx_msg;
348 if (!msg)
Harald Welteb5288e82015-11-14 21:15:52 +0100349 return;
350
Harald Welte8e7fca32017-05-07 16:14:33 +0200351 ch->uart_rx_msg = NULL;
Harald Welteb5288e82015-11-14 21:15:52 +0100352
Kévin Redon680bdab2018-07-18 14:00:57 +0200353 /* store length of data payload field in header */
Harald Welte25a9a802017-05-08 13:30:09 +0200354 rd = (struct cardemu_usb_msg_rx_data *) msg->l2h;
355 rd->data_len = msgb_l2len(msg) - sizeof(*rd);
Harald Welte54cb3d02016-02-29 14:12:40 +0100356
Kévin Redon910e6832018-08-02 17:47:57 +0200357 TRACE_INFO("%u: %s (%u)\n\r",
358 ch->num, __func__, rd->data_len);
359
Harald Welte25a9a802017-05-08 13:30:09 +0200360 usb_buf_upd_len_and_submit(msg);
Harald Welteb5288e82015-11-14 21:15:52 +0100361}
362
Kévin Redon680bdab2018-07-18 14:00:57 +0200363/* convert a non-contiguous PTS request/response into a contiguous
Harald Welte4ba66d02016-02-25 19:38:56 +0100364 * buffer, returning the number of bytes used in the buffer */
365static int serialize_pts(uint8_t *out, const uint8_t *in)
366{
367 int i = 0;
368
369 out[i++] = in[_PTSS];
370 out[i++] = in[_PTS0];
371 if (in[_PTS0] & (1 << 4))
372 out[i++] = in[_PTS1];
373 if (in[_PTS0] & (1 << 5))
374 out[i++] = in[_PTS2];
375 if (in[_PTS0] & (1 << 6))
376 out[i++] = in[_PTS3];
377 out[i++] = in[_PCK];
378
379 return i;
380}
381
Harald Welte17db2f12016-02-26 09:48:57 +0100382static uint8_t csum_pts(const uint8_t *in)
383{
384 uint8_t out[6];
385 int len = serialize_pts(out, in);
386 uint8_t csum = 0;
387 int i;
388
389 /* we don't include the PCK byte in the checksumming process */
390 len -= 1;
391
392 for (i = 0; i < len; i++)
393 csum = csum ^ out[i];
394
395 return csum;
396}
397
Harald Welte4ba66d02016-02-25 19:38:56 +0100398static void flush_pts(struct card_handle *ch)
399{
Harald Welte8e7fca32017-05-07 16:14:33 +0200400 struct msgb *msg;
Harald Welte4ba66d02016-02-25 19:38:56 +0100401 struct cardemu_usb_msg_pts_info *ptsi;
402
Harald Welte25a9a802017-05-08 13:30:09 +0200403 msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_DO_CEMU_PTS);
Harald Welte8e7fca32017-05-07 16:14:33 +0200404 if (!msg)
Harald Welte4ba66d02016-02-25 19:38:56 +0100405 return;
406
Harald Welte25a9a802017-05-08 13:30:09 +0200407 ptsi = (struct cardemu_usb_msg_pts_info *) msgb_put(msg, sizeof(*ptsi));
Harald Welted295b922016-03-18 21:01:36 +0100408 ptsi->pts_len = serialize_pts(ptsi->req, ch->pts.req);
Harald Welte4ba66d02016-02-25 19:38:56 +0100409 serialize_pts(ptsi->resp, ch->pts.resp);
410
Harald Welte25a9a802017-05-08 13:30:09 +0200411 usb_buf_upd_len_and_submit(msg);
Harald Welte4ba66d02016-02-25 19:38:56 +0100412}
413
Harald Welte8c496362016-02-27 16:24:09 +0100414static void emu_update_fidi(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100415{
416 int rc;
417
418 rc = compute_fidi_ratio(ch->fi, ch->di);
419 if (rc > 0 && rc < 0x400) {
Harald Weltedde112e2016-03-20 16:42:11 +0100420 TRACE_INFO("%u: computed Fi(%u) Di(%u) ratio: %d\r\n",
421 ch->num, ch->fi, ch->di, rc);
Harald Welte9d3e3822015-11-09 00:50:54 +0100422 /* make sure UART uses new F/D ratio */
423 card_emu_uart_update_fidi(ch->uart_chan, rc);
424 /* notify ETU timer about this */
425 tc_etu_set_etu(ch->tc_chan, rc);
426 } else
Harald Weltedde112e2016-03-20 16:42:11 +0100427 TRACE_INFO("%u: computed FiDi ration %d unsupported\r\n",
428 ch->num, rc);
Harald Welte9d3e3822015-11-09 00:50:54 +0100429}
430
431/* Update the ISO 7816-3 TPDU receiver state */
432static void card_set_state(struct card_handle *ch,
433 enum iso7816_3_card_state new_state)
434{
Harald Welte903d63a2016-03-20 13:38:39 +0100435 if (ch->state == new_state)
436 return;
437
Kévin Redon2fdcf3b2018-10-15 19:43:15 +0200438 TRACE_DEBUG("%u: 7816 card state %s -> %s\r\n", ch->num,
439 get_value_string(iso7816_3_card_state_names, ch->state),
440 get_value_string(iso7816_3_card_state_names, new_state));
Harald Welte903d63a2016-03-20 13:38:39 +0100441 ch->state = new_state;
442
Harald Welte9d3e3822015-11-09 00:50:54 +0100443 switch (new_state) {
444 case ISO_S_WAIT_POWER:
445 case ISO_S_WAIT_CLK:
446 case ISO_S_WAIT_RST:
447 /* disable Rx and Tx of UART */
448 card_emu_uart_enable(ch->uart_chan, 0);
449 break;
450 case ISO_S_WAIT_ATR:
451 /* Reset to initial Fi / Di ratio */
452 ch->fi = 1;
453 ch->di = 1;
Harald Welte8c496362016-02-27 16:24:09 +0100454 emu_update_fidi(ch);
Kévin Redonebe672e2018-07-29 00:18:12 +0200455 /* the ATR should only be sent 400 to 40k clock cycles after the RESET.
456 * we use the tc_etu mechanism to wait this time.
457 * since the initial ETU is Fd=372/Dd=1 clock cycles long, we have to wait 2-107 ETU.
458 */
459 tc_etu_set_wtime(ch->tc_chan, 2);
Harald Welte4d4405f2019-12-15 13:23:51 +0100460 /* enable the TC/ETU counter once reset has been released */
Kévin Redonebe672e2018-07-29 00:18:12 +0200461 tc_etu_enable(ch->tc_chan);
462 break;
463 case ISO_S_IN_ATR:
Kévin Redon680bdab2018-07-18 14:00:57 +0200464 /* initialize to default WI, this will be overwritten if we
Kévin Redonebe672e2018-07-29 00:18:12 +0200465 * send TC2, and it will be programmed into hardware after
Harald Welte9d3e3822015-11-09 00:50:54 +0100466 * ATR is finished */
467 ch->wi = ISO7816_3_DEFAULT_WI;
468 /* update waiting time to initial waiting time */
469 ch->waiting_time = ISO7816_3_INIT_WTIME;
Kévin Redonebe672e2018-07-29 00:18:12 +0200470 /* set initial waiting time */
Harald Welte9d3e3822015-11-09 00:50:54 +0100471 tc_etu_set_wtime(ch->tc_chan, ch->waiting_time);
472 /* Set ATR sub-state to initial state */
473 ch->atr.idx = 0;
Kévin Redonebe672e2018-07-29 00:18:12 +0200474 /* enable USART transmission to reader */
Harald Welte9d3e3822015-11-09 00:50:54 +0100475 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
Kévin Redonebe672e2018-07-29 00:18:12 +0200476 /* trigger USART TX IRQ to sent first ATR byte TS */
477 card_emu_uart_interrupt(ch->uart_chan);
Harald Welte9d3e3822015-11-09 00:50:54 +0100478 break;
479 case ISO_S_WAIT_TPDU:
480 /* enable the receiver, disable transmitter */
Harald Welte2935b3c2015-11-14 20:00:14 +0100481 set_tpdu_state(ch, TPDU_S_WAIT_CLA);
Harald Welte9d3e3822015-11-09 00:50:54 +0100482 card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
483 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100484 case ISO_S_IN_PTS:
485 case ISO_S_IN_TPDU:
486 /* do nothing */
487 break;
488 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100489}
490
Kévin Redonebe672e2018-07-29 00:18:12 +0200491/**********************************************************************
492 * ATR handling
493 **********************************************************************/
494
495/*! Transmit ATR data to reader
496 * @param[in] ch card interface connected to reader
497 * @return numbers of bytes transmitted
498 */
499static int tx_byte_atr(struct card_handle *ch)
500{
501 if (NULL == ch) {
502 TRACE_ERROR("ATR TX: no card handle provided\n\r");
503 return 0;
504 }
505 if (ISO_S_IN_ATR != ch->state) {
506 TRACE_ERROR("%u: ATR TX: no in ATR state\n\r", ch->num);
507 return 0;
508 }
509
510 /* Transmit ATR */
511 if (ch->atr.idx < ch->atr.len) {
512 uint8_t byte = ch->atr.atr[ch->atr.idx++];
513 card_emu_uart_tx(ch->uart_chan, byte);
Kévin Redonebe672e2018-07-29 00:18:12 +0200514 return 1;
515 } else { /* The ATR has been completely transmitted */
Kévin Redon8b8e58b2018-07-30 18:19:11 +0200516 /* search for TC2 to updated WI */
517 ch->wi = ISO7816_3_DEFAULT_WI;
518 if (ch->atr.len >= 2 && ch->atr.atr[1] & 0xf0) { /* Y1 has some data */
519 uint8_t atr_td1 = 2;
520 if (ch->atr.atr[1] & 0x10) { /* TA1 is present */
521 atr_td1++;
522 }
523 if (ch->atr.atr[1] & 0x20) { /* TB1 is present */
524 atr_td1++;
525 }
526 if (ch->atr.atr[1] & 0x40) { /* TC1 is present */
527 atr_td1++;
528 }
529 if (ch->atr.atr[1] & 0x80) { /* TD1 is present */
530 if (ch->atr.len > atr_td1 && ch->atr.atr[atr_td1] & 0xf0) { /* Y2 has some data */
531 uint8_t atr_tc2 = atr_td1+1;
532 if (ch->atr.atr[atr_td1] & 0x10) { /* TA2 is present */
533 atr_tc2++;
534 }
535 if (ch->atr.atr[atr_td1] & 0x20) { /* TB2 is present */
536 atr_tc2++;
537 }
538 if (ch->atr.atr[atr_td1] & 0x40) { /* TC2 is present */
539 if (ch->atr.len > atr_tc2 && ch->atr.atr[atr_tc2]) { /* TC2 encodes WI */
540 ch->wi = ch->atr.atr[atr_tc2]; /* set WI */
541 }
542 }
543 }
544 }
545 }
546 /* update waiting time (see ISO 7816-3 10.2) */
547 ch->waiting_time = ch->wi * 960 * ch->fi;
548 tc_etu_set_wtime(ch->tc_chan, ch->waiting_time);
Kévin Redonebe672e2018-07-29 00:18:12 +0200549 /* go to next state */
550 card_set_state(ch, ISO_S_WAIT_TPDU);
551 return 0;
552 }
553
554 /* return number of bytes transmitted */
555 return 1;
556}
Harald Welte9d3e3822015-11-09 00:50:54 +0100557
558/**********************************************************************
559 * PTS / PPS handling
560 **********************************************************************/
561
Kévin Redon680bdab2018-07-18 14:00:57 +0200562/* Update the PTS sub-state */
Harald Welte9d3e3822015-11-09 00:50:54 +0100563static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss)
564{
Harald Welte6a3a7142019-12-16 14:23:02 +0100565 TRACE_DEBUG("%u: 7816 PTS state %s -> %s\r\n", ch->num,
566 get_value_string(pts_state_names, ch->pts.state),
567 get_value_string(pts_state_names, new_ptss));
Harald Welte9d3e3822015-11-09 00:50:54 +0100568 ch->pts.state = new_ptss;
569}
570
571/* Determine the next PTS state */
572static enum pts_state next_pts_state(struct card_handle *ch)
573{
574 uint8_t is_resp = ch->pts.state & 0x10;
575 uint8_t sstate = ch->pts.state & 0x0f;
576 uint8_t *pts_ptr;
577
578 if (!is_resp)
579 pts_ptr = ch->pts.req;
580 else
581 pts_ptr = ch->pts.resp;
582
583 switch (sstate) {
584 case PTS_S_WAIT_REQ_PTSS:
585 goto from_ptss;
586 case PTS_S_WAIT_REQ_PTS0:
587 goto from_pts0;
588 case PTS_S_WAIT_REQ_PTS1:
589 goto from_pts1;
590 case PTS_S_WAIT_REQ_PTS2:
591 goto from_pts2;
592 case PTS_S_WAIT_REQ_PTS3:
593 goto from_pts3;
594 }
595
596 if (ch->pts.state == PTS_S_WAIT_REQ_PCK)
597 return PTS_S_WAIT_RESP_PTSS;
598
599from_ptss:
600 return PTS_S_WAIT_REQ_PTS0 | is_resp;
601from_pts0:
602 if (pts_ptr[_PTS0] & (1 << 4))
603 return PTS_S_WAIT_REQ_PTS1 | is_resp;
604from_pts1:
605 if (pts_ptr[_PTS0] & (1 << 5))
606 return PTS_S_WAIT_REQ_PTS2 | is_resp;
607from_pts2:
608 if (pts_ptr[_PTS0] & (1 << 6))
609 return PTS_S_WAIT_REQ_PTS3 | is_resp;
610from_pts3:
611 return PTS_S_WAIT_REQ_PCK | is_resp;
612}
613
614
Harald Welteccb8a222016-03-20 13:37:11 +0100615static int
Harald Welte9d3e3822015-11-09 00:50:54 +0100616process_byte_pts(struct card_handle *ch, uint8_t byte)
617{
618 switch (ch->pts.state) {
619 case PTS_S_WAIT_REQ_PTSS:
620 ch->pts.req[_PTSS] = byte;
621 break;
622 case PTS_S_WAIT_REQ_PTS0:
623 ch->pts.req[_PTS0] = byte;
624 break;
625 case PTS_S_WAIT_REQ_PTS1:
626 ch->pts.req[_PTS1] = byte;
627 break;
628 case PTS_S_WAIT_REQ_PTS2:
629 ch->pts.req[_PTS2] = byte;
630 break;
631 case PTS_S_WAIT_REQ_PTS3:
632 ch->pts.req[_PTS3] = byte;
633 break;
634 case PTS_S_WAIT_REQ_PCK:
635 ch->pts.req[_PCK] = byte;
Harald Welte17db2f12016-02-26 09:48:57 +0100636 if (ch->pts.req[_PCK] != csum_pts(ch->pts.req)) {
Harald Weltedde112e2016-03-20 16:42:11 +0100637 TRACE_ERROR("%u: Error in PTS Checksum!\r\n",
638 ch->num);
Harald Welte17db2f12016-02-26 09:48:57 +0100639 /* Wait for the next TPDU */
640 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
641 return ISO_S_WAIT_TPDU;
642 }
Harald Welte4ba66d02016-02-25 19:38:56 +0100643 /* FIXME: check if proposal matches capabilities in ATR */
Harald Welte9d3e3822015-11-09 00:50:54 +0100644 memcpy(ch->pts.resp, ch->pts.req, sizeof(ch->pts.resp));
645 break;
Harald Welte4c473da2015-11-14 13:31:11 +0100646 default:
Harald Welte6a3a7142019-12-16 14:23:02 +0100647 TRACE_ERROR("%u: process_byte_pts() in invalid PTS state %s\r\n", ch->num,
648 get_value_string(pts_state_names, ch->pts.state));
Harald Welte4c473da2015-11-14 13:31:11 +0100649 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100650 }
651 /* calculate the next state and set it */
652 set_pts_state(ch, next_pts_state(ch));
653
Harald Welte4ba66d02016-02-25 19:38:56 +0100654 if (ch->pts.state == PTS_S_WAIT_RESP_PTSS) {
655 flush_pts(ch);
656 /* activate UART TX to transmit PTS response */
657 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
Harald Welte53079bb2016-03-20 14:58:35 +0100658 /* don't fall-through to the 'return ISO_S_IN_PTS'
659 * below, rather keep ISO7816 state as-is, it will be
660 * further updated by the tx-completion handler */
Harald Welteccb8a222016-03-20 13:37:11 +0100661 return -1;
Harald Welte4ba66d02016-02-25 19:38:56 +0100662 }
663
Harald Welte9d3e3822015-11-09 00:50:54 +0100664 return ISO_S_IN_PTS;
665}
666
667/* return a single byte to be transmitted to the reader */
Harald Welte855ba9e2016-02-24 21:00:46 +0100668static int tx_byte_pts(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100669{
Harald Welte855ba9e2016-02-24 21:00:46 +0100670 uint8_t byte;
671
672 /* 1: Determine the next transmit byte */
Harald Welte9d3e3822015-11-09 00:50:54 +0100673 switch (ch->pts.state) {
674 case PTS_S_WAIT_RESP_PTSS:
Harald Welte855ba9e2016-02-24 21:00:46 +0100675 byte = ch->pts.resp[_PTSS];
Harald Welte9d3e3822015-11-09 00:50:54 +0100676 break;
677 case PTS_S_WAIT_RESP_PTS0:
Harald Welte855ba9e2016-02-24 21:00:46 +0100678 byte = ch->pts.resp[_PTS0];
Harald Welte9d3e3822015-11-09 00:50:54 +0100679 break;
680 case PTS_S_WAIT_RESP_PTS1:
Harald Welte855ba9e2016-02-24 21:00:46 +0100681 byte = ch->pts.resp[_PTS1];
Harald Welte9d3e3822015-11-09 00:50:54 +0100682 /* This must be TA1 */
Harald Welte855ba9e2016-02-24 21:00:46 +0100683 ch->fi = byte >> 4;
684 ch->di = byte & 0xf;
Harald Weltedde112e2016-03-20 16:42:11 +0100685 TRACE_DEBUG("%u: found Fi=%u Di=%u\r\n", ch->num,
686 ch->fi, ch->di);
Harald Welte9d3e3822015-11-09 00:50:54 +0100687 break;
688 case PTS_S_WAIT_RESP_PTS2:
Harald Welte855ba9e2016-02-24 21:00:46 +0100689 byte = ch->pts.resp[_PTS2];
Harald Welte9d3e3822015-11-09 00:50:54 +0100690 break;
691 case PTS_S_WAIT_RESP_PTS3:
Harald Welte855ba9e2016-02-24 21:00:46 +0100692 byte = ch->pts.resp[_PTS3];
Harald Welte9d3e3822015-11-09 00:50:54 +0100693 break;
694 case PTS_S_WAIT_RESP_PCK:
Harald Welte855ba9e2016-02-24 21:00:46 +0100695 byte = ch->pts.resp[_PCK];
Harald Welte855ba9e2016-02-24 21:00:46 +0100696 break;
Harald Welted79dc4f2015-11-14 13:32:21 +0100697 default:
Harald Welte6a3a7142019-12-16 14:23:02 +0100698 TRACE_ERROR("%u: get_byte_pts() in invalid PTS state %s\r\n", ch->num,
699 get_value_string(pts_state_names, ch->pts.state));
Harald Welte855ba9e2016-02-24 21:00:46 +0100700 return 0;
701 }
702
703 /* 2: Transmit the byte */
704 card_emu_uart_tx(ch->uart_chan, byte);
705
706 /* 3: Update the state */
707
708 switch (ch->pts.state) {
709 case PTS_S_WAIT_RESP_PCK:
Harald Weltec58bba02016-03-20 14:57:53 +0100710 card_emu_uart_wait_tx_idle(ch->uart_chan);
Harald Welte52d55462016-03-20 13:38:05 +0100711 /* update baud rate generator with Fi/Di */
712 emu_update_fidi(ch);
Harald Welte855ba9e2016-02-24 21:00:46 +0100713 /* Wait for the next TPDU */
714 card_set_state(ch, ISO_S_WAIT_TPDU);
Harald Welte855ba9e2016-02-24 21:00:46 +0100715 break;
716 default:
717 /* calculate the next state and set it */
718 set_pts_state(ch, next_pts_state(ch));
Harald Welted79dc4f2015-11-14 13:32:21 +0100719 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100720 }
Harald Welted79dc4f2015-11-14 13:32:21 +0100721
Harald Welte855ba9e2016-02-24 21:00:46 +0100722 /* return number of bytes transmitted */
723 return 1;
Harald Welte9d3e3822015-11-09 00:50:54 +0100724}
725
726
727/**********************************************************************
728 * TPDU handling
729 **********************************************************************/
730
Harald Welte4d804672015-11-14 23:02:38 +0100731
732/* compute number of data bytes according to Chapter 10.3.2 of 7816-3 */
733static unsigned int t0_num_data_bytes(uint8_t p3, int reader_to_card)
734{
735 if (reader_to_card) {
736 return p3;
737 } else {
738 if (p3 == 0)
739 return 256;
740 else
741 return p3;
742 }
743}
744
Harald Welte9d3e3822015-11-09 00:50:54 +0100745/* add a just-received TPDU byte (from reader) to USB buffer */
Harald Welte61bb30e2015-11-14 23:44:14 +0100746static void add_tpdu_byte(struct card_handle *ch, uint8_t byte)
Harald Welte9d3e3822015-11-09 00:50:54 +0100747{
Harald Welte8e7fca32017-05-07 16:14:33 +0200748 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100749 struct cardemu_usb_msg_rx_data *rd;
Harald Welte4d804672015-11-14 23:02:38 +0100750 unsigned int num_data_bytes = t0_num_data_bytes(ch->tpdu.hdr[_P3], 0);
Harald Welte9d3e3822015-11-09 00:50:54 +0100751
752 /* ensure we have a buffer */
Harald Welte8e7fca32017-05-07 16:14:33 +0200753 if (!ch->uart_rx_msg) {
Harald Welte25a9a802017-05-08 13:30:09 +0200754 msg = ch->uart_rx_msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM,
755 SIMTRACE_MSGT_DO_CEMU_RX_DATA);
Harald Welte8e7fca32017-05-07 16:14:33 +0200756 if (!ch->uart_rx_msg) {
Harald Weltedde112e2016-03-20 16:42:11 +0100757 TRACE_ERROR("%u: Received UART byte but ENOMEM\r\n",
758 ch->num);
Harald Welte9d3e3822015-11-09 00:50:54 +0100759 return;
Harald Welte4d804672015-11-14 23:02:38 +0100760 }
Harald Welte25a9a802017-05-08 13:30:09 +0200761 msgb_put(msg, sizeof(*rd));
Harald Welte9d3e3822015-11-09 00:50:54 +0100762 } else
Harald Welte8e7fca32017-05-07 16:14:33 +0200763 msg = ch->uart_rx_msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100764
Harald Welte25a9a802017-05-08 13:30:09 +0200765 rd = (struct cardemu_usb_msg_rx_data *) msg->l2h;
Harald Welte8e7fca32017-05-07 16:14:33 +0200766 msgb_put_u8(msg, byte);
Harald Welte9d3e3822015-11-09 00:50:54 +0100767
768 /* check if the buffer is full. If so, send it */
Harald Welte25a9a802017-05-08 13:30:09 +0200769 if (msgb_l2len(msg) >= sizeof(*rd) + num_data_bytes) {
Harald Welte4d804672015-11-14 23:02:38 +0100770 rd->flags |= CEMU_DATA_F_FINAL;
Harald Welteb5288e82015-11-14 21:15:52 +0100771 flush_rx_buffer(ch);
Harald Welte61bb30e2015-11-14 23:44:14 +0100772 /* We need to transmit the SW now, */
773 set_tpdu_state(ch, TPDU_S_WAIT_TX);
Harald Welte8e7fca32017-05-07 16:14:33 +0200774 } else if (msgb_tailroom(msg) <= 0)
Harald Welte4d804672015-11-14 23:02:38 +0100775 flush_rx_buffer(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100776}
777
778static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts)
779{
Harald Welte05b41c62015-11-14 20:58:48 +0100780 if (ch->tpdu.state == new_ts)
781 return;
782
Kévin Redon2fdcf3b2018-10-15 19:43:15 +0200783 TRACE_DEBUG("%u: 7816 TPDU state %s -> %s\r\n", ch->num,
784 get_value_string(tpdu_state_names, ch->tpdu.state),
785 get_value_string(tpdu_state_names, new_ts));
Harald Welte903d63a2016-03-20 13:38:39 +0100786 ch->tpdu.state = new_ts;
787
Harald Welte9d3e3822015-11-09 00:50:54 +0100788 switch (new_ts) {
789 case TPDU_S_WAIT_CLA:
Harald Welte05b41c62015-11-14 20:58:48 +0100790 case TPDU_S_WAIT_RX:
Harald Welte9d3e3822015-11-09 00:50:54 +0100791 card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
792 break;
793 case TPDU_S_WAIT_PB:
794 /* we just completed the TPDU header from reader to card
795 * and now need to disable the receiver, enable the
796 * transmitter and transmit the procedure byte */
797 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
798 break;
Harald Weltead434402016-03-02 11:18:29 +0100799 default:
800 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100801 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100802}
803
804static enum tpdu_state next_tpdu_state(struct card_handle *ch)
805{
806 switch (ch->tpdu.state) {
807 case TPDU_S_WAIT_CLA:
808 return TPDU_S_WAIT_INS;
809 case TPDU_S_WAIT_INS:
810 return TPDU_S_WAIT_P1;
811 case TPDU_S_WAIT_P1:
812 return TPDU_S_WAIT_P2;
813 case TPDU_S_WAIT_P2:
814 return TPDU_S_WAIT_P3;
815 case TPDU_S_WAIT_P3:
816 return TPDU_S_WAIT_PB;
817 /* simply stay in Rx or Tx by default */
818 case TPDU_S_WAIT_PB:
819 return TPDU_S_WAIT_PB;
820 case TPDU_S_WAIT_RX:
821 return TPDU_S_WAIT_RX;
822 case TPDU_S_WAIT_TX:
823 return TPDU_S_WAIT_TX;
824 }
Harald Welte4c473da2015-11-14 13:31:11 +0100825 /* we should never reach here */
826 assert(0);
827 return -1;
Harald Welte9d3e3822015-11-09 00:50:54 +0100828}
829
830static void send_tpdu_header(struct card_handle *ch)
831{
Harald Welte8e7fca32017-05-07 16:14:33 +0200832 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100833 struct cardemu_usb_msg_rx_data *rd;
Harald Welte8e7fca32017-05-07 16:14:33 +0200834 uint8_t *cur;
Harald Welte9d3e3822015-11-09 00:50:54 +0100835
Harald Weltedde112e2016-03-20 16:42:11 +0100836 TRACE_INFO("%u: %s: %02x %02x %02x %02x %02x\r\n",
837 ch->num, __func__,
Harald Welte43f79492016-02-29 10:06:54 +0100838 ch->tpdu.hdr[0], ch->tpdu.hdr[1],
839 ch->tpdu.hdr[2], ch->tpdu.hdr[3],
840 ch->tpdu.hdr[4]);
841
Harald Welte9d3e3822015-11-09 00:50:54 +0100842 /* if we already/still have a context, send it off */
Harald Welte8e7fca32017-05-07 16:14:33 +0200843 if (ch->uart_rx_msg) {
Harald Weltedde112e2016-03-20 16:42:11 +0100844 TRACE_DEBUG("%u: have old buffer\r\n", ch->num);
Harald Welte8e7fca32017-05-07 16:14:33 +0200845 if (msgb_l2len(ch->uart_rx_msg)) {
Harald Weltedde112e2016-03-20 16:42:11 +0100846 TRACE_DEBUG("%u: flushing old buffer\r\n", ch->num);
Harald Weltef1697e22016-03-02 10:28:54 +0100847 flush_rx_buffer(ch);
848 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100849 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200850 TRACE_DEBUG("%u: allocating new buffer\r\n", ch->num);
851 /* ensure we have a new buffer */
Harald Welte25a9a802017-05-08 13:30:09 +0200852 ch->uart_rx_msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM,
853 SIMTRACE_MSGT_DO_CEMU_RX_DATA);
Harald Welte8e7fca32017-05-07 16:14:33 +0200854 if (!ch->uart_rx_msg) {
855 TRACE_ERROR("%u: %s: ENOMEM\r\n", ch->num, __func__);
856 return;
857 }
858 msg = ch->uart_rx_msg;
Harald Welte25a9a802017-05-08 13:30:09 +0200859 rd = (struct cardemu_usb_msg_rx_data *) msgb_put(msg, sizeof(*rd));
Harald Welte9d3e3822015-11-09 00:50:54 +0100860
Harald Welte8e7fca32017-05-07 16:14:33 +0200861 /* initialize header */
Harald Welte9d3e3822015-11-09 00:50:54 +0100862 rd->flags = CEMU_DATA_F_TPDU_HDR;
Harald Welte9d3e3822015-11-09 00:50:54 +0100863
864 /* copy TPDU header to data field */
Harald Welte8e7fca32017-05-07 16:14:33 +0200865 cur = msgb_put(msg, sizeof(ch->tpdu.hdr));
866 memcpy(cur, ch->tpdu.hdr, sizeof(ch->tpdu.hdr));
Harald Welteb5288e82015-11-14 21:15:52 +0100867 /* rd->data_len is set in flush_rx_buffer() */
Harald Welte9d3e3822015-11-09 00:50:54 +0100868
Harald Welteb5288e82015-11-14 21:15:52 +0100869 flush_rx_buffer(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100870}
871
872static enum iso7816_3_card_state
873process_byte_tpdu(struct card_handle *ch, uint8_t byte)
874{
875 switch (ch->tpdu.state) {
876 case TPDU_S_WAIT_CLA:
877 ch->tpdu.hdr[_CLA] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100878 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100879 break;
880 case TPDU_S_WAIT_INS:
881 ch->tpdu.hdr[_INS] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100882 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100883 break;
884 case TPDU_S_WAIT_P1:
885 ch->tpdu.hdr[_P1] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100886 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100887 break;
888 case TPDU_S_WAIT_P2:
889 ch->tpdu.hdr[_P2] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100890 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100891 break;
892 case TPDU_S_WAIT_P3:
893 ch->tpdu.hdr[_P3] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100894 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100895 /* FIXME: start timer to transmit further 0x60 */
896 /* send the TPDU header as part of a procedure byte
897 * request to the USB host */
898 send_tpdu_header(ch);
899 break;
900 case TPDU_S_WAIT_RX:
Harald Welte61bb30e2015-11-14 23:44:14 +0100901 add_tpdu_byte(ch, byte);
902 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100903 default:
Harald Welte6a3a7142019-12-16 14:23:02 +0100904 TRACE_ERROR("%u: process_byte_tpdu() in invalid TPDU state %s\r\n", ch->num,
905 get_value_string(tpdu_state_names, ch->tpdu.state));
Harald Welte9d3e3822015-11-09 00:50:54 +0100906 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100907
908 /* ensure we stay in TPDU ISO state */
909 return ISO_S_IN_TPDU;
910}
911
Harald Welte855ba9e2016-02-24 21:00:46 +0100912/* tx a single byte to be transmitted to the reader */
913static int tx_byte_tpdu(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100914{
Harald Welte8e7fca32017-05-07 16:14:33 +0200915 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100916 struct cardemu_usb_msg_tx_data *td;
Harald Welte855ba9e2016-02-24 21:00:46 +0100917 uint8_t byte;
Harald Welte9d3e3822015-11-09 00:50:54 +0100918
919 /* ensure we are aware of any data that might be pending for
920 * transmit */
Harald Welte8e7fca32017-05-07 16:14:33 +0200921 if (!ch->uart_tx_msg) {
Harald Welte53079bb2016-03-20 14:58:35 +0100922 /* uart_tx_queue is filled from main loop, so no need
923 * for irq-safe operations */
Harald Welte54cb3d02016-02-29 14:12:40 +0100924 if (llist_empty(&ch->uart_tx_queue))
Harald Welte9d3e3822015-11-09 00:50:54 +0100925 return 0;
926
Harald Welte54cb3d02016-02-29 14:12:40 +0100927 /* dequeue first at head */
Harald Welte8e7fca32017-05-07 16:14:33 +0200928 ch->uart_tx_msg = msgb_dequeue(&ch->uart_tx_queue);
Harald Welte25a9a802017-05-08 13:30:09 +0200929 ch->uart_tx_msg->l1h = ch->uart_tx_msg->head;
930 ch->uart_tx_msg->l2h = ch->uart_tx_msg->l1h + sizeof(struct simtrace_msg_hdr);
Harald Welte8e7fca32017-05-07 16:14:33 +0200931 msg = ch->uart_tx_msg;
Harald Welte25a9a802017-05-08 13:30:09 +0200932 /* remove the header */
933 msgb_pull(msg, sizeof(struct simtrace_msg_hdr) + sizeof(*td));
Harald Welte9d3e3822015-11-09 00:50:54 +0100934 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200935 msg = ch->uart_tx_msg;
Harald Welte25a9a802017-05-08 13:30:09 +0200936 td = (struct cardemu_usb_msg_tx_data *) msg->l2h;
Harald Welte9d3e3822015-11-09 00:50:54 +0100937
Harald Welte8e7fca32017-05-07 16:14:33 +0200938 /* take the next pending byte out of the msgb */
939 byte = msgb_pull_u8(msg);
Harald Welte855ba9e2016-02-24 21:00:46 +0100940
941 card_emu_uart_tx(ch->uart_chan, byte);
Harald Welte9d3e3822015-11-09 00:50:54 +0100942
Kévin Redon0f4abf52018-08-02 17:42:48 +0200943 /* this must happen _after_ the byte has been transmitted */
Harald Weltef16b6182016-02-24 22:18:46 +0100944 switch (ch->tpdu.state) {
945 case TPDU_S_WAIT_PB:
946 /* if we just transmitted the procedure byte, we need to decide
947 * if we want to continue to receive or transmit */
948 if (td->flags & CEMU_DATA_F_PB_AND_TX)
949 set_tpdu_state(ch, TPDU_S_WAIT_TX);
950 else if (td->flags & CEMU_DATA_F_PB_AND_RX)
951 set_tpdu_state(ch, TPDU_S_WAIT_RX);
952 break;
Harald Weltead434402016-03-02 11:18:29 +0100953 default:
954 break;
Harald Weltef16b6182016-02-24 22:18:46 +0100955 }
956
Harald Welte9d3e3822015-11-09 00:50:54 +0100957 /* check if the buffer has now been fully transmitted */
Harald Welte8e7fca32017-05-07 16:14:33 +0200958 if (msgb_length(msg) == 0) {
Harald Welte52922ff2015-11-14 20:59:56 +0100959 if (td->flags & CEMU_DATA_F_PB_AND_RX) {
960 /* we have just sent the procedure byte and now
961 * need to continue receiving */
962 set_tpdu_state(ch, TPDU_S_WAIT_RX);
Harald Welte2935b3c2015-11-14 20:00:14 +0100963 } else {
Harald Welte52922ff2015-11-14 20:59:56 +0100964 /* we have transmitted all bytes */
965 if (td->flags & CEMU_DATA_F_FINAL) {
966 /* this was the final part of the APDU, go
Harald Welte53079bb2016-03-20 14:58:35 +0100967 * back to state one */
Harald Welte52922ff2015-11-14 20:59:56 +0100968 card_set_state(ch, ISO_S_WAIT_TPDU);
Harald Welte52922ff2015-11-14 20:59:56 +0100969 }
Harald Welte2935b3c2015-11-14 20:00:14 +0100970 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200971 usb_buf_free(msg);
972 ch->uart_tx_msg = NULL;
Harald Welte9d3e3822015-11-09 00:50:54 +0100973 }
974
975 return 1;
976}
977
978/**********************************************************************
979 * Public API
980 **********************************************************************/
981
982/* process a single byte received from the reader */
983void card_emu_process_rx_byte(struct card_handle *ch, uint8_t byte)
984{
985 int new_state = -1;
986
987 ch->stats.rx_bytes++;
988
989 switch (ch->state) {
Harald Welte9d3e3822015-11-09 00:50:54 +0100990 case ISO_S_WAIT_TPDU:
991 if (byte == 0xff) {
Harald Welte02d0d732019-12-15 13:19:24 +0100992 /* reset PTS to initial state */
993 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
Harald Welte9d3e3822015-11-09 00:50:54 +0100994 new_state = process_byte_pts(ch, byte);
995 ch->stats.pps++;
996 goto out_silent;
997 }
998 /* fall-through */
999 case ISO_S_IN_TPDU:
1000 new_state = process_byte_tpdu(ch, byte);
1001 break;
1002 case ISO_S_IN_PTS:
1003 new_state = process_byte_pts(ch, byte);
1004 goto out_silent;
Kévin Redon5f6b8712018-07-11 09:49:06 +02001005 default:
Harald Welte6a3a7142019-12-16 14:23:02 +01001006 TRACE_ERROR("%u: Received UART char in invalid 7816 state %s\r\n", ch->num,
1007 get_value_string(iso7816_3_card_state_names, ch->state));
Kévin Redon5f6b8712018-07-11 09:49:06 +02001008 break;
Harald Welte9d3e3822015-11-09 00:50:54 +01001009 }
1010
1011out_silent:
1012 if (new_state != -1)
1013 card_set_state(ch, new_state);
1014}
1015
Harald Welte855ba9e2016-02-24 21:00:46 +01001016/* transmit a single byte to the reader */
1017int card_emu_tx_byte(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +01001018{
1019 int rc = 0;
1020
1021 switch (ch->state) {
1022 case ISO_S_IN_ATR:
Kévin Redonebe672e2018-07-29 00:18:12 +02001023 rc = tx_byte_atr(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +01001024 break;
1025 case ISO_S_IN_PTS:
Harald Welte855ba9e2016-02-24 21:00:46 +01001026 rc = tx_byte_pts(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +01001027 break;
1028 case ISO_S_IN_TPDU:
Harald Welte855ba9e2016-02-24 21:00:46 +01001029 rc = tx_byte_tpdu(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +01001030 break;
Harald Weltead434402016-03-02 11:18:29 +01001031 default:
1032 break;
Harald Welte9d3e3822015-11-09 00:50:54 +01001033 }
1034
1035 if (rc)
1036 ch->stats.tx_bytes++;
1037
Harald Welte4d804672015-11-14 23:02:38 +01001038 /* if we return 0 here, the UART needs to disable transmit-ready
1039 * interrupts */
Harald Welte9d3e3822015-11-09 00:50:54 +01001040 return rc;
1041}
1042
Harald Welteacae4122016-03-02 10:27:58 +01001043void card_emu_have_new_uart_tx(struct card_handle *ch)
1044{
1045 switch (ch->state) {
1046 case ISO_S_IN_TPDU:
1047 switch (ch->tpdu.state) {
1048 case TPDU_S_WAIT_TX:
1049 case TPDU_S_WAIT_PB:
1050 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
1051 break;
1052 default:
1053 break;
1054 }
1055 default:
1056 break;
1057 }
1058}
1059
Harald Welte140f0072019-12-16 10:23:32 +01001060void card_emu_report_status(struct card_handle *ch, bool report_on_irq)
Harald Welteff160652016-03-19 21:59:06 +01001061{
Harald Welte8e7fca32017-05-07 16:14:33 +02001062 struct msgb *msg;
Harald Welteff160652016-03-19 21:59:06 +01001063 struct cardemu_usb_msg_status *sts;
Harald Welte140f0072019-12-16 10:23:32 +01001064 uint8_t ep = ch->in_ep;
Harald Welteff160652016-03-19 21:59:06 +01001065
Harald Welte140f0072019-12-16 10:23:32 +01001066 if (report_on_irq)
1067 ep = ch->irq_ep;
1068
1069 msg = usb_buf_alloc_st(ep, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_BD_CEMU_STATUS);
Harald Welte8e7fca32017-05-07 16:14:33 +02001070 if (!msg)
Harald Welteff160652016-03-19 21:59:06 +01001071 return;
Harald Welte8e7fca32017-05-07 16:14:33 +02001072
Harald Welte25a9a802017-05-08 13:30:09 +02001073 sts = (struct cardemu_usb_msg_status *) msgb_put(msg, sizeof(*sts));
Harald Welteff160652016-03-19 21:59:06 +01001074 sts->flags = 0;
1075 if (ch->vcc_active)
1076 sts->flags |= CEMU_STATUS_F_VCC_PRESENT;
1077 if (ch->clocked)
1078 sts->flags |= CEMU_STATUS_F_CLK_ACTIVE;
1079 if (ch->in_reset)
1080 sts->flags |= CEMU_STATUS_F_RESET_ACTIVE;
1081 /* FIXME: voltage + card insert */
1082 sts->fi = ch->fi;
1083 sts->di = ch->di;
1084 sts->wi = ch->wi;
1085 sts->waiting_time = ch->waiting_time;
1086
Harald Welte25a9a802017-05-08 13:30:09 +02001087 usb_buf_upd_len_and_submit(msg);
Harald Welteff160652016-03-19 21:59:06 +01001088}
1089
Harald Weltea5bbe782019-12-16 10:39:55 +01001090static void card_emu_report_config(struct card_handle *ch)
1091{
1092 struct msgb *msg;
1093 struct cardemu_usb_msg_config *cfg;
1094 uint8_t ep = ch->in_ep;
1095
1096 msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_BD_CEMU_CONFIG);
1097 if (!msg)
1098 return;
1099
1100 cfg = (struct cardemu_usb_msg_config *) msgb_put(msg, sizeof(*cfg));
1101 cfg->features = ch->features;
1102
1103 usb_buf_upd_len_and_submit(msg);
1104}
1105
Harald Welte9d3e3822015-11-09 00:50:54 +01001106/* hardware driver informs us that a card I/O signal has changed */
1107void card_emu_io_statechg(struct card_handle *ch, enum card_io io, int active)
1108{
1109 switch (io) {
1110 case CARD_IO_VCC:
Harald Welte47ee2832016-02-29 10:09:46 +01001111 if (active == 0 && ch->vcc_active == 1) {
Harald Weltedde112e2016-03-20 16:42:11 +01001112 TRACE_INFO("%u: VCC deactivated\r\n", ch->num);
Harald Welte81f4ef72019-12-14 22:20:00 +01001113 card_handle_reset(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +01001114 card_set_state(ch, ISO_S_WAIT_POWER);
Harald Welte47ee2832016-02-29 10:09:46 +01001115 } else if (active == 1 && ch->vcc_active == 0) {
Harald Weltedde112e2016-03-20 16:42:11 +01001116 TRACE_INFO("%u: VCC activated\r\n", ch->num);
Harald Welte9d3e3822015-11-09 00:50:54 +01001117 card_set_state(ch, ISO_S_WAIT_CLK);
Harald Welte47ee2832016-02-29 10:09:46 +01001118 }
Harald Welte9d3e3822015-11-09 00:50:54 +01001119 ch->vcc_active = active;
1120 break;
1121 case CARD_IO_CLK:
Harald Welte47ee2832016-02-29 10:09:46 +01001122 if (active == 1 && ch->clocked == 0) {
Harald Weltedde112e2016-03-20 16:42:11 +01001123 TRACE_INFO("%u: CLK activated\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +01001124 if (ch->state == ISO_S_WAIT_CLK)
1125 card_set_state(ch, ISO_S_WAIT_RST);
1126 } else if (active == 0 && ch->clocked == 1) {
Harald Weltedde112e2016-03-20 16:42:11 +01001127 TRACE_INFO("%u: CLK deactivated\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +01001128 }
Harald Welte9d3e3822015-11-09 00:50:54 +01001129 ch->clocked = active;
1130 break;
1131 case CARD_IO_RST:
Harald Welte47ee2832016-02-29 10:09:46 +01001132 if (active == 0 && ch->in_reset) {
Harald Weltedde112e2016-03-20 16:42:11 +01001133 TRACE_INFO("%u: RST released\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +01001134 if (ch->vcc_active && ch->clocked) {
1135 /* enable the TC/ETU counter once reset has been released */
1136 tc_etu_enable(ch->tc_chan);
Kévin Redonebe672e2018-07-29 00:18:12 +02001137 /* prepare to send the ATR */
Harald Welte47ee2832016-02-29 10:09:46 +01001138 card_set_state(ch, ISO_S_WAIT_ATR);
Harald Welte47ee2832016-02-29 10:09:46 +01001139 }
1140 } else if (active && !ch->in_reset) {
Harald Weltedde112e2016-03-20 16:42:11 +01001141 TRACE_INFO("%u: RST asserted\r\n", ch->num);
Harald Welte81f4ef72019-12-14 22:20:00 +01001142 card_handle_reset(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +01001143 }
1144 ch->in_reset = active;
1145 break;
1146 }
Harald Weltee9f429d2019-12-15 13:21:17 +01001147
1148 switch (ch->state) {
1149 case ISO_S_WAIT_POWER:
1150 case ISO_S_WAIT_CLK:
1151 case ISO_S_WAIT_RST:
1152 /* check end activation state (even if the reader does
1153 * not respect the activation sequence) */
1154 if (ch->vcc_active && ch->clocked && !ch->in_reset) {
Harald Weltee9f429d2019-12-15 13:21:17 +01001155 /* prepare to send the ATR */
1156 card_set_state(ch, ISO_S_WAIT_ATR);
1157 }
1158 break;
1159 default:
1160 break;
1161 }
Harald Welte9d3e3822015-11-09 00:50:54 +01001162}
1163
1164/* User sets a new ATR to be returned during next card reset */
1165int card_emu_set_atr(struct card_handle *ch, const uint8_t *atr, uint8_t len)
1166{
1167 if (len > sizeof(ch->atr.atr))
1168 return -1;
1169
1170 memcpy(ch->atr.atr, atr, len);
1171 ch->atr.len = len;
1172 ch->atr.idx = 0;
1173
Kévin Redonebe672e2018-07-29 00:18:12 +02001174#if TRACE_LEVEL >= TRACE_LEVEL_INFO
1175 uint8_t i;
1176 TRACE_INFO("%u: ATR set: ", ch->num);
1177 for (i = 0; i < ch->atr.len; i++) {
1178 TRACE_INFO_WP("%02x ", atr[i]);
1179 }
1180 TRACE_INFO_WP("\n\r");
1181#endif
1182 /* FIXME: race condition with transmitting ATR to reader? */
Harald Welte9d3e3822015-11-09 00:50:54 +01001183
1184 return 0;
1185}
1186
1187/* hardware driver informs us that one (more) ETU has expired */
1188void tc_etu_wtime_half_expired(void *handle)
1189{
1190 struct card_handle *ch = handle;
1191 /* transmit NULL procedure byte well before waiting time expires */
Harald Weltedda73552016-03-02 10:29:55 +01001192 switch (ch->state) {
1193 case ISO_S_IN_TPDU:
1194 switch (ch->tpdu.state) {
1195 case TPDU_S_WAIT_PB:
1196 case TPDU_S_WAIT_TX:
1197 putchar('N');
1198 card_emu_uart_tx(ch->uart_chan, ISO7816_3_PB_NULL);
1199 break;
1200 default:
1201 break;
1202 }
1203 break;
1204 default:
1205 break;
1206 }
Harald Welte9d3e3822015-11-09 00:50:54 +01001207}
1208
1209/* hardware driver informs us that one (more) ETU has expired */
1210void tc_etu_wtime_expired(void *handle)
1211{
Harald Weltedde112e2016-03-20 16:42:11 +01001212 struct card_handle *ch = handle;
Kévin Redonebe672e2018-07-29 00:18:12 +02001213 switch (ch->state) {
1214 case ISO_S_WAIT_ATR:
1215 /* ISO 7816-3 6.2.1 time tc has passed, we can now send the ATR */
1216 card_set_state(ch, ISO_S_IN_ATR);
1217 break;
1218 default:
1219 TRACE_ERROR("%u: wtime_exp\r\n", ch->num);
1220 break;
1221 }
Harald Welte9d3e3822015-11-09 00:50:54 +01001222}
1223
Kévin Redon503e1842019-05-15 00:23:21 +02001224/* shortest ATR possible (uses default speed and no options) */
1225static const uint8_t default_atr[] = { 0x3B, 0x00 };
Harald Welte9d3e3822015-11-09 00:50:54 +01001226
1227static struct card_handle card_handles[NUM_SLOTS];
1228
Harald Weltea5bbe782019-12-16 10:39:55 +01001229int card_emu_set_config(struct card_handle *ch, const struct cardemu_usb_msg_config *scfg,
1230 unsigned int scfg_len)
1231{
1232 if (scfg_len >= sizeof(uint32_t))
1233 ch->features = (scfg->features & SUPPORTED_FEATURES);
1234
1235 /* send back a report of our current configuration */
1236 card_emu_report_config(ch);
1237
1238 return 0;
1239}
1240
Kévin Redon7233cf82019-11-14 19:37:32 +01001241struct 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 +01001242{
1243 struct card_handle *ch;
1244
1245 if (slot_num >= ARRAY_SIZE(card_handles))
1246 return NULL;
1247
1248 ch = &card_handles[slot_num];
1249
1250 memset(ch, 0, sizeof(*ch));
1251
Harald Welte54cb3d02016-02-29 14:12:40 +01001252 INIT_LLIST_HEAD(&ch->uart_tx_queue);
1253
Harald Weltedde112e2016-03-20 16:42:11 +01001254 ch->num = slot_num;
Harald Welte8e7fca32017-05-07 16:14:33 +02001255 ch->irq_ep = irq_ep;
1256 ch->in_ep = in_ep;
Harald Welte9d3e3822015-11-09 00:50:54 +01001257 ch->state = ISO_S_WAIT_POWER;
Kévin Redon7233cf82019-11-14 19:37:32 +01001258 ch->vcc_active = vcc_active;
1259 ch->in_reset = in_reset;
1260 ch->clocked = clocked;
Harald Welte9d3e3822015-11-09 00:50:54 +01001261
1262 ch->fi = 0;
1263 ch->di = 1;
1264 ch->wi = ISO7816_3_DEFAULT_WI;
1265
1266 ch->tc_chan = tc_chan;
1267 ch->uart_chan = uart_chan;
1268 ch->waiting_time = ISO7816_3_INIT_WTIME;
1269
1270 ch->atr.idx = 0;
1271 ch->atr.len = sizeof(default_atr);
1272 memcpy(ch->atr.atr, default_atr, ch->atr.len);
1273
Harald Weltee92cb502019-12-14 21:48:45 +01001274 card_handle_reset(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +01001275
1276 tc_etu_init(ch->tc_chan, ch);
1277
1278 return ch;
1279}