blob: 352284fd18765b45f8ab678f81ac6aa2b7abef8e [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
Harald Welte6a3a7142019-12-16 14:23:02 +0100113const struct value_string pts_state_names[] = {
114 { PTS_S_WAIT_REQ_PTSS, "WAIT_REQ_PTSS" },
115 { PTS_S_WAIT_REQ_PTS0, "WAIT_REQ_PTS0" },
116 { PTS_S_WAIT_REQ_PTS1, "WAIT_REQ_PTS1" },
117 { PTS_S_WAIT_REQ_PTS2, "WAIT_REQ_PTS2" },
118 { PTS_S_WAIT_REQ_PTS3, "WAIT_REQ_PTS3" },
119 { PTS_S_WAIT_REQ_PCK, "WAIT_REQ_PCK" },
120 { PTS_S_WAIT_RESP_PTSS, "WAIT_RESP_PTSS" },
121 { PTS_S_WAIT_RESP_PTS0, "WAIT_RESP_PTS0" },
122 { PTS_S_WAIT_RESP_PTS1, "WAIT_RESP_PTS1" },
123 { PTS_S_WAIT_RESP_PTS2, "WAIT_RESP_PTS2" },
124 { PTS_S_WAIT_RESP_PTS3, "WAIT_RESP_PTS3" },
125 { PTS_S_WAIT_RESP_PCK, "WAIT_RESP_PCK" },
126 { 0, NULL }
127};
128
Kévin Redon2fdcf3b2018-10-15 19:43:15 +0200129/* PTS field byte index */
Harald Welte9d3e3822015-11-09 00:50:54 +0100130#define _PTSS 0
131#define _PTS0 1
132#define _PTS1 2
133#define _PTS2 3
134#define _PTS3 4
135#define _PCK 5
136
Harald Welte16cf4082015-11-11 19:02:48 +0100137/* T-PDU state machine states */
Harald Welte9d3e3822015-11-09 00:50:54 +0100138enum tpdu_state {
Harald Welte16cf4082015-11-11 19:02:48 +0100139 TPDU_S_WAIT_CLA, /* waiting for CLA byte from reader */
140 TPDU_S_WAIT_INS, /* waiting for INS byte from reader */
141 TPDU_S_WAIT_P1, /* waiting for P1 byte from reader */
142 TPDU_S_WAIT_P2, /* waiting for P2 byte from reader */
143 TPDU_S_WAIT_P3, /* waiting for P3 byte from reader */
Harald Welte9d3e3822015-11-09 00:50:54 +0100144 TPDU_S_WAIT_PB, /* waiting for Tx of procedure byte */
Kévin Redon0f4abf52018-08-02 17:42:48 +0200145 TPDU_S_WAIT_RX, /* waiting for more data from reader */
Harald Welte9d3e3822015-11-09 00:50:54 +0100146 TPDU_S_WAIT_TX, /* waiting for more data to reader */
147};
148
Kévin Redon2fdcf3b2018-10-15 19:43:15 +0200149const struct value_string tpdu_state_names[] = {
150 {
151 .value = TPDU_S_WAIT_CLA,
152 .str = "WAIT_CLA",
153 },
154 {
155 .value = TPDU_S_WAIT_INS,
156 .str = "WAIT_INS",
157 },
158 {
159 .value = TPDU_S_WAIT_P1,
160 .str = "WAIT_P1",
161 },
162 {
163 .value = TPDU_S_WAIT_P2,
164 .str = "WAIT_P2",
165 },
166 {
167 .value = TPDU_S_WAIT_P3,
168 .str = "WAIT_P3",
169 },
170 {
171 .value = TPDU_S_WAIT_PB,
172 .str = "WAIT_PB",
173 },
174 {
175 .value = TPDU_S_WAIT_RX,
176 .str = "WAIT_RX",
177 },
178 {
179 .value = TPDU_S_WAIT_TX,
180 .str = "WAIT_TX",
181 },
182 {
183 .value = 0,
184 .str = NULL,
185 },
186};
187
188/* TPDU field byte index */
Harald Welte9d3e3822015-11-09 00:50:54 +0100189#define _CLA 0
190#define _INS 1
191#define _P1 2
192#define _P2 3
193#define _P3 4
194
195struct card_handle {
Harald Weltec3941092018-08-26 09:53:13 +0200196 unsigned int num;
Harald Weltedde112e2016-03-20 16:42:11 +0100197
Harald Welte9d3e3822015-11-09 00:50:54 +0100198 enum iso7816_3_card_state state;
199
200 /* signal levels */
Kévin Redon7233cf82019-11-14 19:37:32 +0100201 bool vcc_active; /*< if VCC is active (true = active/ON) */
202 bool in_reset; /*< if card is in reset (true = RST low/asserted, false = RST high/ released) */
203 bool clocked; /*< if clock is active ( true = active, false = inactive) */
Harald Welte9d3e3822015-11-09 00:50:54 +0100204
Harald Welte16cf4082015-11-11 19:02:48 +0100205 /* timing parameters, from PTS */
Harald Welte9d3e3822015-11-09 00:50:54 +0100206 uint8_t fi;
207 uint8_t di;
208 uint8_t wi;
209
210 uint8_t tc_chan; /* TC channel number */
211 uint8_t uart_chan; /* UART channel */
212
Harald Welte8e7fca32017-05-07 16:14:33 +0200213 uint8_t in_ep; /* USB IN EP */
214 uint8_t irq_ep; /* USB IN EP */
215
Harald Welte9d3e3822015-11-09 00:50:54 +0100216 uint32_t waiting_time; /* in clocks */
217
218 /* ATR state machine */
219 struct {
220 uint8_t idx;
221 uint8_t len;
222 //uint8_t hist_len;
223 //uint8_t last_td;
224 uint8_t atr[ISO7816_3_ATR_LEN_MAX];
225 } atr;
226
227 /* PPS / PTS support */
228 struct {
229 enum pts_state state;
Harald Welte16cf4082015-11-11 19:02:48 +0100230 uint8_t req[6]; /* request bytes */
231 uint8_t resp[6]; /* response bytes */
Harald Welte9d3e3822015-11-09 00:50:54 +0100232 } pts;
233
234 /* TPDU */
235 struct {
236 enum tpdu_state state;
Harald Welte16cf4082015-11-11 19:02:48 +0100237 uint8_t hdr[5]; /* CLA INS P1 P2 P3 */
Harald Welte9d3e3822015-11-09 00:50:54 +0100238 } tpdu;
239
Harald Welte8e7fca32017-05-07 16:14:33 +0200240 struct msgb *uart_rx_msg; /* UART RX -> USB TX */
241 struct msgb *uart_tx_msg; /* USB RX -> UART TX */
Harald Welte9d3e3822015-11-09 00:50:54 +0100242
Harald Welte54cb3d02016-02-29 14:12:40 +0100243 struct llist_head uart_tx_queue;
244
Harald Welte9d3e3822015-11-09 00:50:54 +0100245 struct {
246 uint32_t tx_bytes;
247 uint32_t rx_bytes;
248 uint32_t pps;
249 } stats;
250};
251
Harald Weltee92cb502019-12-14 21:48:45 +0100252/* reset all the 'dynamic' state of the card handle to the initial/default values */
253static void card_handle_reset(struct card_handle *ch)
254{
Harald Welte81f4ef72019-12-14 22:20:00 +0100255 struct msgb *msg;
256
257 tc_etu_disable(ch->tc_chan);
258
Harald Welte81f4ef72019-12-14 22:20:00 +0100259 /* release any buffers we may still own */
260 if (ch->uart_tx_msg) {
261 usb_buf_free(ch->uart_tx_msg);
262 ch->uart_tx_msg = NULL;
263 }
264 if (ch->uart_rx_msg) {
265 usb_buf_free(ch->uart_rx_msg);
266 ch->uart_rx_msg = NULL;
267 }
268 while ((msg = msgb_dequeue(&ch->uart_tx_queue))) {
269 usb_buf_free(msg);
270 }
Harald Weltee92cb502019-12-14 21:48:45 +0100271}
272
Harald Welte54cb3d02016-02-29 14:12:40 +0100273struct llist_head *card_emu_get_uart_tx_queue(struct card_handle *ch)
274{
275 return &ch->uart_tx_queue;
276}
277
Harald Welte2935b3c2015-11-14 20:00:14 +0100278static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts);
Harald Weltee7194ab2015-11-14 21:03:25 +0100279static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss);
Harald Welte2935b3c2015-11-14 20:00:14 +0100280
Harald Welte25a9a802017-05-08 13:30:09 +0200281/* update simtrace header msg_len and submit USB buffer */
282void usb_buf_upd_len_and_submit(struct msgb *msg)
283{
Harald Welteb91f6ad2017-05-10 22:51:30 +0200284 struct simtrace_msg_hdr *sh = (struct simtrace_msg_hdr *) msg->l1h;
Harald Welte25a9a802017-05-08 13:30:09 +0200285
286 sh->msg_len = msgb_length(msg);
287
288 usb_buf_submit(msg);
289}
290
291/* Allocate USB buffer and push + initialize simtrace_msg_hdr */
292struct msgb *usb_buf_alloc_st(uint8_t ep, uint8_t msg_class, uint8_t msg_type)
293{
Kévin Redonc90de692019-11-18 22:32:58 +0100294 struct msgb *msg = NULL;
Harald Welte25a9a802017-05-08 13:30:09 +0200295 struct simtrace_msg_hdr *sh;
296
Kévin Redonc90de692019-11-18 22:32:58 +0100297 while (!msg) {
298 msg = usb_buf_alloc(ep); // try to allocate some memory
299 if (!msg) { // allocation failed, we might be out of memory
Harald Weltef4a625b2019-12-14 19:07:57 +0100300 struct usb_buffered_ep *bep = usb_get_buf_ep(ep);
301 if (!bep) {
Kévin Redonc90de692019-11-18 22:32:58 +0100302 TRACE_ERROR("ep %u: %s queue does not exist\n\r",
303 ep, __func__);
304 return NULL;
305 }
Harald Weltef4a625b2019-12-14 19:07:57 +0100306 if (llist_empty(&bep->queue)) {
Kévin Redonc90de692019-11-18 22:32:58 +0100307 TRACE_ERROR("ep %u: %s EOMEM (queue already empty)\n\r",
308 ep, __func__);
309 return NULL;
310 }
Harald Weltef4a625b2019-12-14 19:07:57 +0100311 msg = msgb_dequeue_count(&bep->queue, &bep->queue_len);
Kévin Redonc90de692019-11-18 22:32:58 +0100312 if (!msg) {
313 TRACE_ERROR("ep %u: %s no msg in non-empty queue\n\r",
314 ep, __func__);
315 return NULL;
316 }
317 usb_buf_free(msg);
318 msg = NULL;
319 TRACE_DEBUG("ep %u: %s queue msg dropped\n\r",
320 ep, __func__);
321 }
322 }
Harald Welte25a9a802017-05-08 13:30:09 +0200323
324 msg->l1h = msgb_put(msg, sizeof(*sh));
325 sh = (struct simtrace_msg_hdr *) msg->l1h;
326 memset(sh, 0, sizeof(*sh));
327 sh->msg_class = msg_class;
328 sh->msg_type = msg_type;
329 msg->l2h = msg->l1h + sizeof(*sh);
330
331 return msg;
332}
333
Kévin Redon680bdab2018-07-18 14:00:57 +0200334/* Update cardemu_usb_msg_rx_data length + submit buffer */
Harald Welteb5288e82015-11-14 21:15:52 +0100335static void flush_rx_buffer(struct card_handle *ch)
336{
Harald Welte8e7fca32017-05-07 16:14:33 +0200337 struct msgb *msg;
Harald Welteb5288e82015-11-14 21:15:52 +0100338 struct cardemu_usb_msg_rx_data *rd;
Harald Welte8e7fca32017-05-07 16:14:33 +0200339 uint32_t data_len;
Harald Welteb5288e82015-11-14 21:15:52 +0100340
Harald Welte8e7fca32017-05-07 16:14:33 +0200341 msg = ch->uart_rx_msg;
342 if (!msg)
Harald Welteb5288e82015-11-14 21:15:52 +0100343 return;
344
Harald Welte8e7fca32017-05-07 16:14:33 +0200345 ch->uart_rx_msg = NULL;
Harald Welteb5288e82015-11-14 21:15:52 +0100346
Kévin Redon680bdab2018-07-18 14:00:57 +0200347 /* store length of data payload field in header */
Harald Welte25a9a802017-05-08 13:30:09 +0200348 rd = (struct cardemu_usb_msg_rx_data *) msg->l2h;
349 rd->data_len = msgb_l2len(msg) - sizeof(*rd);
Harald Welte54cb3d02016-02-29 14:12:40 +0100350
Kévin Redon910e6832018-08-02 17:47:57 +0200351 TRACE_INFO("%u: %s (%u)\n\r",
352 ch->num, __func__, rd->data_len);
353
Harald Welte25a9a802017-05-08 13:30:09 +0200354 usb_buf_upd_len_and_submit(msg);
Harald Welteb5288e82015-11-14 21:15:52 +0100355}
356
Kévin Redon680bdab2018-07-18 14:00:57 +0200357/* convert a non-contiguous PTS request/response into a contiguous
Harald Welte4ba66d02016-02-25 19:38:56 +0100358 * buffer, returning the number of bytes used in the buffer */
359static int serialize_pts(uint8_t *out, const uint8_t *in)
360{
361 int i = 0;
362
363 out[i++] = in[_PTSS];
364 out[i++] = in[_PTS0];
365 if (in[_PTS0] & (1 << 4))
366 out[i++] = in[_PTS1];
367 if (in[_PTS0] & (1 << 5))
368 out[i++] = in[_PTS2];
369 if (in[_PTS0] & (1 << 6))
370 out[i++] = in[_PTS3];
371 out[i++] = in[_PCK];
372
373 return i;
374}
375
Harald Welte17db2f12016-02-26 09:48:57 +0100376static uint8_t csum_pts(const uint8_t *in)
377{
378 uint8_t out[6];
379 int len = serialize_pts(out, in);
380 uint8_t csum = 0;
381 int i;
382
383 /* we don't include the PCK byte in the checksumming process */
384 len -= 1;
385
386 for (i = 0; i < len; i++)
387 csum = csum ^ out[i];
388
389 return csum;
390}
391
Harald Welte4ba66d02016-02-25 19:38:56 +0100392static void flush_pts(struct card_handle *ch)
393{
Harald Welte8e7fca32017-05-07 16:14:33 +0200394 struct msgb *msg;
Harald Welte4ba66d02016-02-25 19:38:56 +0100395 struct cardemu_usb_msg_pts_info *ptsi;
396
Harald Welte25a9a802017-05-08 13:30:09 +0200397 msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_DO_CEMU_PTS);
Harald Welte8e7fca32017-05-07 16:14:33 +0200398 if (!msg)
Harald Welte4ba66d02016-02-25 19:38:56 +0100399 return;
400
Harald Welte25a9a802017-05-08 13:30:09 +0200401 ptsi = (struct cardemu_usb_msg_pts_info *) msgb_put(msg, sizeof(*ptsi));
Harald Welted295b922016-03-18 21:01:36 +0100402 ptsi->pts_len = serialize_pts(ptsi->req, ch->pts.req);
Harald Welte4ba66d02016-02-25 19:38:56 +0100403 serialize_pts(ptsi->resp, ch->pts.resp);
404
Harald Welte25a9a802017-05-08 13:30:09 +0200405 usb_buf_upd_len_and_submit(msg);
Harald Welte4ba66d02016-02-25 19:38:56 +0100406}
407
Harald Welte8c496362016-02-27 16:24:09 +0100408static void emu_update_fidi(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100409{
410 int rc;
411
412 rc = compute_fidi_ratio(ch->fi, ch->di);
413 if (rc > 0 && rc < 0x400) {
Harald Weltedde112e2016-03-20 16:42:11 +0100414 TRACE_INFO("%u: computed Fi(%u) Di(%u) ratio: %d\r\n",
415 ch->num, ch->fi, ch->di, rc);
Harald Welte9d3e3822015-11-09 00:50:54 +0100416 /* make sure UART uses new F/D ratio */
417 card_emu_uart_update_fidi(ch->uart_chan, rc);
418 /* notify ETU timer about this */
419 tc_etu_set_etu(ch->tc_chan, rc);
420 } else
Harald Weltedde112e2016-03-20 16:42:11 +0100421 TRACE_INFO("%u: computed FiDi ration %d unsupported\r\n",
422 ch->num, rc);
Harald Welte9d3e3822015-11-09 00:50:54 +0100423}
424
425/* Update the ISO 7816-3 TPDU receiver state */
426static void card_set_state(struct card_handle *ch,
427 enum iso7816_3_card_state new_state)
428{
Harald Welte903d63a2016-03-20 13:38:39 +0100429 if (ch->state == new_state)
430 return;
431
Kévin Redon2fdcf3b2018-10-15 19:43:15 +0200432 TRACE_DEBUG("%u: 7816 card state %s -> %s\r\n", ch->num,
433 get_value_string(iso7816_3_card_state_names, ch->state),
434 get_value_string(iso7816_3_card_state_names, new_state));
Harald Welte903d63a2016-03-20 13:38:39 +0100435 ch->state = new_state;
436
Harald Welte9d3e3822015-11-09 00:50:54 +0100437 switch (new_state) {
438 case ISO_S_WAIT_POWER:
439 case ISO_S_WAIT_CLK:
440 case ISO_S_WAIT_RST:
441 /* disable Rx and Tx of UART */
442 card_emu_uart_enable(ch->uart_chan, 0);
443 break;
444 case ISO_S_WAIT_ATR:
445 /* Reset to initial Fi / Di ratio */
446 ch->fi = 1;
447 ch->di = 1;
Harald Welte8c496362016-02-27 16:24:09 +0100448 emu_update_fidi(ch);
Kévin Redonebe672e2018-07-29 00:18:12 +0200449 /* the ATR should only be sent 400 to 40k clock cycles after the RESET.
450 * we use the tc_etu mechanism to wait this time.
451 * since the initial ETU is Fd=372/Dd=1 clock cycles long, we have to wait 2-107 ETU.
452 */
453 tc_etu_set_wtime(ch->tc_chan, 2);
Harald Welte4d4405f2019-12-15 13:23:51 +0100454 /* enable the TC/ETU counter once reset has been released */
Kévin Redonebe672e2018-07-29 00:18:12 +0200455 tc_etu_enable(ch->tc_chan);
456 break;
457 case ISO_S_IN_ATR:
Kévin Redon680bdab2018-07-18 14:00:57 +0200458 /* initialize to default WI, this will be overwritten if we
Kévin Redonebe672e2018-07-29 00:18:12 +0200459 * send TC2, and it will be programmed into hardware after
Harald Welte9d3e3822015-11-09 00:50:54 +0100460 * ATR is finished */
461 ch->wi = ISO7816_3_DEFAULT_WI;
462 /* update waiting time to initial waiting time */
463 ch->waiting_time = ISO7816_3_INIT_WTIME;
Kévin Redonebe672e2018-07-29 00:18:12 +0200464 /* set initial waiting time */
Harald Welte9d3e3822015-11-09 00:50:54 +0100465 tc_etu_set_wtime(ch->tc_chan, ch->waiting_time);
466 /* Set ATR sub-state to initial state */
467 ch->atr.idx = 0;
Kévin Redonebe672e2018-07-29 00:18:12 +0200468 /* enable USART transmission to reader */
Harald Welte9d3e3822015-11-09 00:50:54 +0100469 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
Kévin Redonebe672e2018-07-29 00:18:12 +0200470 /* trigger USART TX IRQ to sent first ATR byte TS */
471 card_emu_uart_interrupt(ch->uart_chan);
Harald Welte9d3e3822015-11-09 00:50:54 +0100472 break;
473 case ISO_S_WAIT_TPDU:
474 /* enable the receiver, disable transmitter */
Harald Welte2935b3c2015-11-14 20:00:14 +0100475 set_tpdu_state(ch, TPDU_S_WAIT_CLA);
Harald Welte9d3e3822015-11-09 00:50:54 +0100476 card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
477 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100478 case ISO_S_IN_PTS:
479 case ISO_S_IN_TPDU:
480 /* do nothing */
481 break;
482 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100483}
484
Kévin Redonebe672e2018-07-29 00:18:12 +0200485/**********************************************************************
486 * ATR handling
487 **********************************************************************/
488
489/*! Transmit ATR data to reader
490 * @param[in] ch card interface connected to reader
491 * @return numbers of bytes transmitted
492 */
493static int tx_byte_atr(struct card_handle *ch)
494{
495 if (NULL == ch) {
496 TRACE_ERROR("ATR TX: no card handle provided\n\r");
497 return 0;
498 }
499 if (ISO_S_IN_ATR != ch->state) {
500 TRACE_ERROR("%u: ATR TX: no in ATR state\n\r", ch->num);
501 return 0;
502 }
503
504 /* Transmit ATR */
505 if (ch->atr.idx < ch->atr.len) {
506 uint8_t byte = ch->atr.atr[ch->atr.idx++];
507 card_emu_uart_tx(ch->uart_chan, byte);
Kévin Redonebe672e2018-07-29 00:18:12 +0200508 return 1;
509 } else { /* The ATR has been completely transmitted */
Kévin Redon8b8e58b2018-07-30 18:19:11 +0200510 /* search for TC2 to updated WI */
511 ch->wi = ISO7816_3_DEFAULT_WI;
512 if (ch->atr.len >= 2 && ch->atr.atr[1] & 0xf0) { /* Y1 has some data */
513 uint8_t atr_td1 = 2;
514 if (ch->atr.atr[1] & 0x10) { /* TA1 is present */
515 atr_td1++;
516 }
517 if (ch->atr.atr[1] & 0x20) { /* TB1 is present */
518 atr_td1++;
519 }
520 if (ch->atr.atr[1] & 0x40) { /* TC1 is present */
521 atr_td1++;
522 }
523 if (ch->atr.atr[1] & 0x80) { /* TD1 is present */
524 if (ch->atr.len > atr_td1 && ch->atr.atr[atr_td1] & 0xf0) { /* Y2 has some data */
525 uint8_t atr_tc2 = atr_td1+1;
526 if (ch->atr.atr[atr_td1] & 0x10) { /* TA2 is present */
527 atr_tc2++;
528 }
529 if (ch->atr.atr[atr_td1] & 0x20) { /* TB2 is present */
530 atr_tc2++;
531 }
532 if (ch->atr.atr[atr_td1] & 0x40) { /* TC2 is present */
533 if (ch->atr.len > atr_tc2 && ch->atr.atr[atr_tc2]) { /* TC2 encodes WI */
534 ch->wi = ch->atr.atr[atr_tc2]; /* set WI */
535 }
536 }
537 }
538 }
539 }
540 /* update waiting time (see ISO 7816-3 10.2) */
541 ch->waiting_time = ch->wi * 960 * ch->fi;
542 tc_etu_set_wtime(ch->tc_chan, ch->waiting_time);
Kévin Redonebe672e2018-07-29 00:18:12 +0200543 /* go to next state */
544 card_set_state(ch, ISO_S_WAIT_TPDU);
545 return 0;
546 }
547
548 /* return number of bytes transmitted */
549 return 1;
550}
Harald Welte9d3e3822015-11-09 00:50:54 +0100551
552/**********************************************************************
553 * PTS / PPS handling
554 **********************************************************************/
555
Kévin Redon680bdab2018-07-18 14:00:57 +0200556/* Update the PTS sub-state */
Harald Welte9d3e3822015-11-09 00:50:54 +0100557static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss)
558{
Harald Welte6a3a7142019-12-16 14:23:02 +0100559 TRACE_DEBUG("%u: 7816 PTS state %s -> %s\r\n", ch->num,
560 get_value_string(pts_state_names, ch->pts.state),
561 get_value_string(pts_state_names, new_ptss));
Harald Welte9d3e3822015-11-09 00:50:54 +0100562 ch->pts.state = new_ptss;
563}
564
565/* Determine the next PTS state */
566static enum pts_state next_pts_state(struct card_handle *ch)
567{
568 uint8_t is_resp = ch->pts.state & 0x10;
569 uint8_t sstate = ch->pts.state & 0x0f;
570 uint8_t *pts_ptr;
571
572 if (!is_resp)
573 pts_ptr = ch->pts.req;
574 else
575 pts_ptr = ch->pts.resp;
576
577 switch (sstate) {
578 case PTS_S_WAIT_REQ_PTSS:
579 goto from_ptss;
580 case PTS_S_WAIT_REQ_PTS0:
581 goto from_pts0;
582 case PTS_S_WAIT_REQ_PTS1:
583 goto from_pts1;
584 case PTS_S_WAIT_REQ_PTS2:
585 goto from_pts2;
586 case PTS_S_WAIT_REQ_PTS3:
587 goto from_pts3;
588 }
589
590 if (ch->pts.state == PTS_S_WAIT_REQ_PCK)
591 return PTS_S_WAIT_RESP_PTSS;
592
593from_ptss:
594 return PTS_S_WAIT_REQ_PTS0 | is_resp;
595from_pts0:
596 if (pts_ptr[_PTS0] & (1 << 4))
597 return PTS_S_WAIT_REQ_PTS1 | is_resp;
598from_pts1:
599 if (pts_ptr[_PTS0] & (1 << 5))
600 return PTS_S_WAIT_REQ_PTS2 | is_resp;
601from_pts2:
602 if (pts_ptr[_PTS0] & (1 << 6))
603 return PTS_S_WAIT_REQ_PTS3 | is_resp;
604from_pts3:
605 return PTS_S_WAIT_REQ_PCK | is_resp;
606}
607
608
Harald Welteccb8a222016-03-20 13:37:11 +0100609static int
Harald Welte9d3e3822015-11-09 00:50:54 +0100610process_byte_pts(struct card_handle *ch, uint8_t byte)
611{
612 switch (ch->pts.state) {
613 case PTS_S_WAIT_REQ_PTSS:
614 ch->pts.req[_PTSS] = byte;
615 break;
616 case PTS_S_WAIT_REQ_PTS0:
617 ch->pts.req[_PTS0] = byte;
618 break;
619 case PTS_S_WAIT_REQ_PTS1:
620 ch->pts.req[_PTS1] = byte;
621 break;
622 case PTS_S_WAIT_REQ_PTS2:
623 ch->pts.req[_PTS2] = byte;
624 break;
625 case PTS_S_WAIT_REQ_PTS3:
626 ch->pts.req[_PTS3] = byte;
627 break;
628 case PTS_S_WAIT_REQ_PCK:
629 ch->pts.req[_PCK] = byte;
Harald Welte17db2f12016-02-26 09:48:57 +0100630 if (ch->pts.req[_PCK] != csum_pts(ch->pts.req)) {
Harald Weltedde112e2016-03-20 16:42:11 +0100631 TRACE_ERROR("%u: Error in PTS Checksum!\r\n",
632 ch->num);
Harald Welte17db2f12016-02-26 09:48:57 +0100633 /* Wait for the next TPDU */
634 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
635 return ISO_S_WAIT_TPDU;
636 }
Harald Welte4ba66d02016-02-25 19:38:56 +0100637 /* FIXME: check if proposal matches capabilities in ATR */
Harald Welte9d3e3822015-11-09 00:50:54 +0100638 memcpy(ch->pts.resp, ch->pts.req, sizeof(ch->pts.resp));
639 break;
Harald Welte4c473da2015-11-14 13:31:11 +0100640 default:
Harald Welte6a3a7142019-12-16 14:23:02 +0100641 TRACE_ERROR("%u: process_byte_pts() in invalid PTS state %s\r\n", ch->num,
642 get_value_string(pts_state_names, ch->pts.state));
Harald Welte4c473da2015-11-14 13:31:11 +0100643 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100644 }
645 /* calculate the next state and set it */
646 set_pts_state(ch, next_pts_state(ch));
647
Harald Welte4ba66d02016-02-25 19:38:56 +0100648 if (ch->pts.state == PTS_S_WAIT_RESP_PTSS) {
649 flush_pts(ch);
650 /* activate UART TX to transmit PTS response */
651 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
Harald Welte53079bb2016-03-20 14:58:35 +0100652 /* don't fall-through to the 'return ISO_S_IN_PTS'
653 * below, rather keep ISO7816 state as-is, it will be
654 * further updated by the tx-completion handler */
Harald Welteccb8a222016-03-20 13:37:11 +0100655 return -1;
Harald Welte4ba66d02016-02-25 19:38:56 +0100656 }
657
Harald Welte9d3e3822015-11-09 00:50:54 +0100658 return ISO_S_IN_PTS;
659}
660
661/* return a single byte to be transmitted to the reader */
Harald Welte855ba9e2016-02-24 21:00:46 +0100662static int tx_byte_pts(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100663{
Harald Welte855ba9e2016-02-24 21:00:46 +0100664 uint8_t byte;
665
666 /* 1: Determine the next transmit byte */
Harald Welte9d3e3822015-11-09 00:50:54 +0100667 switch (ch->pts.state) {
668 case PTS_S_WAIT_RESP_PTSS:
Harald Welte855ba9e2016-02-24 21:00:46 +0100669 byte = ch->pts.resp[_PTSS];
Harald Welte9d3e3822015-11-09 00:50:54 +0100670 break;
671 case PTS_S_WAIT_RESP_PTS0:
Harald Welte855ba9e2016-02-24 21:00:46 +0100672 byte = ch->pts.resp[_PTS0];
Harald Welte9d3e3822015-11-09 00:50:54 +0100673 break;
674 case PTS_S_WAIT_RESP_PTS1:
Harald Welte855ba9e2016-02-24 21:00:46 +0100675 byte = ch->pts.resp[_PTS1];
Harald Welte9d3e3822015-11-09 00:50:54 +0100676 /* This must be TA1 */
Harald Welte855ba9e2016-02-24 21:00:46 +0100677 ch->fi = byte >> 4;
678 ch->di = byte & 0xf;
Harald Weltedde112e2016-03-20 16:42:11 +0100679 TRACE_DEBUG("%u: found Fi=%u Di=%u\r\n", ch->num,
680 ch->fi, ch->di);
Harald Welte9d3e3822015-11-09 00:50:54 +0100681 break;
682 case PTS_S_WAIT_RESP_PTS2:
Harald Welte855ba9e2016-02-24 21:00:46 +0100683 byte = ch->pts.resp[_PTS2];
Harald Welte9d3e3822015-11-09 00:50:54 +0100684 break;
685 case PTS_S_WAIT_RESP_PTS3:
Harald Welte855ba9e2016-02-24 21:00:46 +0100686 byte = ch->pts.resp[_PTS3];
Harald Welte9d3e3822015-11-09 00:50:54 +0100687 break;
688 case PTS_S_WAIT_RESP_PCK:
Harald Welte855ba9e2016-02-24 21:00:46 +0100689 byte = ch->pts.resp[_PCK];
Harald Welte855ba9e2016-02-24 21:00:46 +0100690 break;
Harald Welted79dc4f2015-11-14 13:32:21 +0100691 default:
Harald Welte6a3a7142019-12-16 14:23:02 +0100692 TRACE_ERROR("%u: get_byte_pts() in invalid PTS state %s\r\n", ch->num,
693 get_value_string(pts_state_names, ch->pts.state));
Harald Welte855ba9e2016-02-24 21:00:46 +0100694 return 0;
695 }
696
697 /* 2: Transmit the byte */
698 card_emu_uart_tx(ch->uart_chan, byte);
699
700 /* 3: Update the state */
701
702 switch (ch->pts.state) {
703 case PTS_S_WAIT_RESP_PCK:
Harald Weltec58bba02016-03-20 14:57:53 +0100704 card_emu_uart_wait_tx_idle(ch->uart_chan);
Harald Welte52d55462016-03-20 13:38:05 +0100705 /* update baud rate generator with Fi/Di */
706 emu_update_fidi(ch);
Harald Welte855ba9e2016-02-24 21:00:46 +0100707 /* Wait for the next TPDU */
708 card_set_state(ch, ISO_S_WAIT_TPDU);
Harald Welte855ba9e2016-02-24 21:00:46 +0100709 break;
710 default:
711 /* calculate the next state and set it */
712 set_pts_state(ch, next_pts_state(ch));
Harald Welted79dc4f2015-11-14 13:32:21 +0100713 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100714 }
Harald Welted79dc4f2015-11-14 13:32:21 +0100715
Harald Welte855ba9e2016-02-24 21:00:46 +0100716 /* return number of bytes transmitted */
717 return 1;
Harald Welte9d3e3822015-11-09 00:50:54 +0100718}
719
720
721/**********************************************************************
722 * TPDU handling
723 **********************************************************************/
724
Harald Welte4d804672015-11-14 23:02:38 +0100725
726/* compute number of data bytes according to Chapter 10.3.2 of 7816-3 */
727static unsigned int t0_num_data_bytes(uint8_t p3, int reader_to_card)
728{
729 if (reader_to_card) {
730 return p3;
731 } else {
732 if (p3 == 0)
733 return 256;
734 else
735 return p3;
736 }
737}
738
Harald Welte9d3e3822015-11-09 00:50:54 +0100739/* add a just-received TPDU byte (from reader) to USB buffer */
Harald Welte61bb30e2015-11-14 23:44:14 +0100740static void add_tpdu_byte(struct card_handle *ch, uint8_t byte)
Harald Welte9d3e3822015-11-09 00:50:54 +0100741{
Harald Welte8e7fca32017-05-07 16:14:33 +0200742 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100743 struct cardemu_usb_msg_rx_data *rd;
Harald Welte4d804672015-11-14 23:02:38 +0100744 unsigned int num_data_bytes = t0_num_data_bytes(ch->tpdu.hdr[_P3], 0);
Harald Welte9d3e3822015-11-09 00:50:54 +0100745
746 /* ensure we have a buffer */
Harald Welte8e7fca32017-05-07 16:14:33 +0200747 if (!ch->uart_rx_msg) {
Harald Welte25a9a802017-05-08 13:30:09 +0200748 msg = ch->uart_rx_msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM,
749 SIMTRACE_MSGT_DO_CEMU_RX_DATA);
Harald Welte8e7fca32017-05-07 16:14:33 +0200750 if (!ch->uart_rx_msg) {
Harald Weltedde112e2016-03-20 16:42:11 +0100751 TRACE_ERROR("%u: Received UART byte but ENOMEM\r\n",
752 ch->num);
Harald Welte9d3e3822015-11-09 00:50:54 +0100753 return;
Harald Welte4d804672015-11-14 23:02:38 +0100754 }
Harald Welte25a9a802017-05-08 13:30:09 +0200755 msgb_put(msg, sizeof(*rd));
Harald Welte9d3e3822015-11-09 00:50:54 +0100756 } else
Harald Welte8e7fca32017-05-07 16:14:33 +0200757 msg = ch->uart_rx_msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100758
Harald Welte25a9a802017-05-08 13:30:09 +0200759 rd = (struct cardemu_usb_msg_rx_data *) msg->l2h;
Harald Welte8e7fca32017-05-07 16:14:33 +0200760 msgb_put_u8(msg, byte);
Harald Welte9d3e3822015-11-09 00:50:54 +0100761
762 /* check if the buffer is full. If so, send it */
Harald Welte25a9a802017-05-08 13:30:09 +0200763 if (msgb_l2len(msg) >= sizeof(*rd) + num_data_bytes) {
Harald Welte4d804672015-11-14 23:02:38 +0100764 rd->flags |= CEMU_DATA_F_FINAL;
Harald Welteb5288e82015-11-14 21:15:52 +0100765 flush_rx_buffer(ch);
Harald Welte61bb30e2015-11-14 23:44:14 +0100766 /* We need to transmit the SW now, */
767 set_tpdu_state(ch, TPDU_S_WAIT_TX);
Harald Welte8e7fca32017-05-07 16:14:33 +0200768 } else if (msgb_tailroom(msg) <= 0)
Harald Welte4d804672015-11-14 23:02:38 +0100769 flush_rx_buffer(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100770}
771
772static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts)
773{
Harald Welte05b41c62015-11-14 20:58:48 +0100774 if (ch->tpdu.state == new_ts)
775 return;
776
Kévin Redon2fdcf3b2018-10-15 19:43:15 +0200777 TRACE_DEBUG("%u: 7816 TPDU state %s -> %s\r\n", ch->num,
778 get_value_string(tpdu_state_names, ch->tpdu.state),
779 get_value_string(tpdu_state_names, new_ts));
Harald Welte903d63a2016-03-20 13:38:39 +0100780 ch->tpdu.state = new_ts;
781
Harald Welte9d3e3822015-11-09 00:50:54 +0100782 switch (new_ts) {
783 case TPDU_S_WAIT_CLA:
Harald Welte05b41c62015-11-14 20:58:48 +0100784 case TPDU_S_WAIT_RX:
Harald Welte9d3e3822015-11-09 00:50:54 +0100785 card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
786 break;
787 case TPDU_S_WAIT_PB:
788 /* we just completed the TPDU header from reader to card
789 * and now need to disable the receiver, enable the
790 * transmitter and transmit the procedure byte */
791 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
792 break;
Harald Weltead434402016-03-02 11:18:29 +0100793 default:
794 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100795 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100796}
797
798static enum tpdu_state next_tpdu_state(struct card_handle *ch)
799{
800 switch (ch->tpdu.state) {
801 case TPDU_S_WAIT_CLA:
802 return TPDU_S_WAIT_INS;
803 case TPDU_S_WAIT_INS:
804 return TPDU_S_WAIT_P1;
805 case TPDU_S_WAIT_P1:
806 return TPDU_S_WAIT_P2;
807 case TPDU_S_WAIT_P2:
808 return TPDU_S_WAIT_P3;
809 case TPDU_S_WAIT_P3:
810 return TPDU_S_WAIT_PB;
811 /* simply stay in Rx or Tx by default */
812 case TPDU_S_WAIT_PB:
813 return TPDU_S_WAIT_PB;
814 case TPDU_S_WAIT_RX:
815 return TPDU_S_WAIT_RX;
816 case TPDU_S_WAIT_TX:
817 return TPDU_S_WAIT_TX;
818 }
Harald Welte4c473da2015-11-14 13:31:11 +0100819 /* we should never reach here */
820 assert(0);
821 return -1;
Harald Welte9d3e3822015-11-09 00:50:54 +0100822}
823
824static void send_tpdu_header(struct card_handle *ch)
825{
Harald Welte8e7fca32017-05-07 16:14:33 +0200826 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100827 struct cardemu_usb_msg_rx_data *rd;
Harald Welte8e7fca32017-05-07 16:14:33 +0200828 uint8_t *cur;
Harald Welte9d3e3822015-11-09 00:50:54 +0100829
Harald Weltedde112e2016-03-20 16:42:11 +0100830 TRACE_INFO("%u: %s: %02x %02x %02x %02x %02x\r\n",
831 ch->num, __func__,
Harald Welte43f79492016-02-29 10:06:54 +0100832 ch->tpdu.hdr[0], ch->tpdu.hdr[1],
833 ch->tpdu.hdr[2], ch->tpdu.hdr[3],
834 ch->tpdu.hdr[4]);
835
Harald Welte9d3e3822015-11-09 00:50:54 +0100836 /* if we already/still have a context, send it off */
Harald Welte8e7fca32017-05-07 16:14:33 +0200837 if (ch->uart_rx_msg) {
Harald Weltedde112e2016-03-20 16:42:11 +0100838 TRACE_DEBUG("%u: have old buffer\r\n", ch->num);
Harald Welte8e7fca32017-05-07 16:14:33 +0200839 if (msgb_l2len(ch->uart_rx_msg)) {
Harald Weltedde112e2016-03-20 16:42:11 +0100840 TRACE_DEBUG("%u: flushing old buffer\r\n", ch->num);
Harald Weltef1697e22016-03-02 10:28:54 +0100841 flush_rx_buffer(ch);
842 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100843 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200844 TRACE_DEBUG("%u: allocating new buffer\r\n", ch->num);
845 /* ensure we have a new buffer */
Harald Welte25a9a802017-05-08 13:30:09 +0200846 ch->uart_rx_msg = usb_buf_alloc_st(ch->in_ep, SIMTRACE_MSGC_CARDEM,
847 SIMTRACE_MSGT_DO_CEMU_RX_DATA);
Harald Welte8e7fca32017-05-07 16:14:33 +0200848 if (!ch->uart_rx_msg) {
849 TRACE_ERROR("%u: %s: ENOMEM\r\n", ch->num, __func__);
850 return;
851 }
852 msg = ch->uart_rx_msg;
Harald Welte25a9a802017-05-08 13:30:09 +0200853 rd = (struct cardemu_usb_msg_rx_data *) msgb_put(msg, sizeof(*rd));
Harald Welte9d3e3822015-11-09 00:50:54 +0100854
Harald Welte8e7fca32017-05-07 16:14:33 +0200855 /* initialize header */
Harald Welte9d3e3822015-11-09 00:50:54 +0100856 rd->flags = CEMU_DATA_F_TPDU_HDR;
Harald Welte9d3e3822015-11-09 00:50:54 +0100857
858 /* copy TPDU header to data field */
Harald Welte8e7fca32017-05-07 16:14:33 +0200859 cur = msgb_put(msg, sizeof(ch->tpdu.hdr));
860 memcpy(cur, ch->tpdu.hdr, sizeof(ch->tpdu.hdr));
Harald Welteb5288e82015-11-14 21:15:52 +0100861 /* rd->data_len is set in flush_rx_buffer() */
Harald Welte9d3e3822015-11-09 00:50:54 +0100862
Harald Welteb5288e82015-11-14 21:15:52 +0100863 flush_rx_buffer(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100864}
865
866static enum iso7816_3_card_state
867process_byte_tpdu(struct card_handle *ch, uint8_t byte)
868{
869 switch (ch->tpdu.state) {
870 case TPDU_S_WAIT_CLA:
871 ch->tpdu.hdr[_CLA] = 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_INS:
875 ch->tpdu.hdr[_INS] = 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_P1:
879 ch->tpdu.hdr[_P1] = 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 break;
882 case TPDU_S_WAIT_P2:
883 ch->tpdu.hdr[_P2] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100884 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100885 break;
886 case TPDU_S_WAIT_P3:
887 ch->tpdu.hdr[_P3] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100888 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100889 /* FIXME: start timer to transmit further 0x60 */
890 /* send the TPDU header as part of a procedure byte
891 * request to the USB host */
892 send_tpdu_header(ch);
893 break;
894 case TPDU_S_WAIT_RX:
Harald Welte61bb30e2015-11-14 23:44:14 +0100895 add_tpdu_byte(ch, byte);
896 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100897 default:
Harald Welte6a3a7142019-12-16 14:23:02 +0100898 TRACE_ERROR("%u: process_byte_tpdu() in invalid TPDU state %s\r\n", ch->num,
899 get_value_string(tpdu_state_names, ch->tpdu.state));
Harald Welte9d3e3822015-11-09 00:50:54 +0100900 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100901
902 /* ensure we stay in TPDU ISO state */
903 return ISO_S_IN_TPDU;
904}
905
Harald Welte855ba9e2016-02-24 21:00:46 +0100906/* tx a single byte to be transmitted to the reader */
907static int tx_byte_tpdu(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100908{
Harald Welte8e7fca32017-05-07 16:14:33 +0200909 struct msgb *msg;
Harald Welte9d3e3822015-11-09 00:50:54 +0100910 struct cardemu_usb_msg_tx_data *td;
Harald Welte855ba9e2016-02-24 21:00:46 +0100911 uint8_t byte;
Harald Welte9d3e3822015-11-09 00:50:54 +0100912
913 /* ensure we are aware of any data that might be pending for
914 * transmit */
Harald Welte8e7fca32017-05-07 16:14:33 +0200915 if (!ch->uart_tx_msg) {
Harald Welte53079bb2016-03-20 14:58:35 +0100916 /* uart_tx_queue is filled from main loop, so no need
917 * for irq-safe operations */
Harald Welte54cb3d02016-02-29 14:12:40 +0100918 if (llist_empty(&ch->uart_tx_queue))
Harald Welte9d3e3822015-11-09 00:50:54 +0100919 return 0;
920
Harald Welte54cb3d02016-02-29 14:12:40 +0100921 /* dequeue first at head */
Harald Welte8e7fca32017-05-07 16:14:33 +0200922 ch->uart_tx_msg = msgb_dequeue(&ch->uart_tx_queue);
Harald Welte25a9a802017-05-08 13:30:09 +0200923 ch->uart_tx_msg->l1h = ch->uart_tx_msg->head;
924 ch->uart_tx_msg->l2h = ch->uart_tx_msg->l1h + sizeof(struct simtrace_msg_hdr);
Harald Welte8e7fca32017-05-07 16:14:33 +0200925 msg = ch->uart_tx_msg;
Harald Welte25a9a802017-05-08 13:30:09 +0200926 /* remove the header */
927 msgb_pull(msg, sizeof(struct simtrace_msg_hdr) + sizeof(*td));
Harald Welte9d3e3822015-11-09 00:50:54 +0100928 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200929 msg = ch->uart_tx_msg;
Harald Welte25a9a802017-05-08 13:30:09 +0200930 td = (struct cardemu_usb_msg_tx_data *) msg->l2h;
Harald Welte9d3e3822015-11-09 00:50:54 +0100931
Harald Welte8e7fca32017-05-07 16:14:33 +0200932 /* take the next pending byte out of the msgb */
933 byte = msgb_pull_u8(msg);
Harald Welte855ba9e2016-02-24 21:00:46 +0100934
935 card_emu_uart_tx(ch->uart_chan, byte);
Harald Welte9d3e3822015-11-09 00:50:54 +0100936
Kévin Redon0f4abf52018-08-02 17:42:48 +0200937 /* this must happen _after_ the byte has been transmitted */
Harald Weltef16b6182016-02-24 22:18:46 +0100938 switch (ch->tpdu.state) {
939 case TPDU_S_WAIT_PB:
940 /* if we just transmitted the procedure byte, we need to decide
941 * if we want to continue to receive or transmit */
942 if (td->flags & CEMU_DATA_F_PB_AND_TX)
943 set_tpdu_state(ch, TPDU_S_WAIT_TX);
944 else if (td->flags & CEMU_DATA_F_PB_AND_RX)
945 set_tpdu_state(ch, TPDU_S_WAIT_RX);
946 break;
Harald Weltead434402016-03-02 11:18:29 +0100947 default:
948 break;
Harald Weltef16b6182016-02-24 22:18:46 +0100949 }
950
Harald Welte9d3e3822015-11-09 00:50:54 +0100951 /* check if the buffer has now been fully transmitted */
Harald Welte8e7fca32017-05-07 16:14:33 +0200952 if (msgb_length(msg) == 0) {
Harald Welte52922ff2015-11-14 20:59:56 +0100953 if (td->flags & CEMU_DATA_F_PB_AND_RX) {
954 /* we have just sent the procedure byte and now
955 * need to continue receiving */
956 set_tpdu_state(ch, TPDU_S_WAIT_RX);
Harald Welte2935b3c2015-11-14 20:00:14 +0100957 } else {
Harald Welte52922ff2015-11-14 20:59:56 +0100958 /* we have transmitted all bytes */
959 if (td->flags & CEMU_DATA_F_FINAL) {
960 /* this was the final part of the APDU, go
Harald Welte53079bb2016-03-20 14:58:35 +0100961 * back to state one */
Harald Welte52922ff2015-11-14 20:59:56 +0100962 card_set_state(ch, ISO_S_WAIT_TPDU);
Harald Welte52922ff2015-11-14 20:59:56 +0100963 }
Harald Welte2935b3c2015-11-14 20:00:14 +0100964 }
Harald Welte8e7fca32017-05-07 16:14:33 +0200965 usb_buf_free(msg);
966 ch->uart_tx_msg = NULL;
Harald Welte9d3e3822015-11-09 00:50:54 +0100967 }
968
969 return 1;
970}
971
972/**********************************************************************
973 * Public API
974 **********************************************************************/
975
976/* process a single byte received from the reader */
977void card_emu_process_rx_byte(struct card_handle *ch, uint8_t byte)
978{
979 int new_state = -1;
980
981 ch->stats.rx_bytes++;
982
983 switch (ch->state) {
Harald Welte9d3e3822015-11-09 00:50:54 +0100984 case ISO_S_WAIT_TPDU:
985 if (byte == 0xff) {
Harald Welte02d0d732019-12-15 13:19:24 +0100986 /* reset PTS to initial state */
987 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
Harald Welte9d3e3822015-11-09 00:50:54 +0100988 new_state = process_byte_pts(ch, byte);
989 ch->stats.pps++;
990 goto out_silent;
991 }
992 /* fall-through */
993 case ISO_S_IN_TPDU:
994 new_state = process_byte_tpdu(ch, byte);
995 break;
996 case ISO_S_IN_PTS:
997 new_state = process_byte_pts(ch, byte);
998 goto out_silent;
Kévin Redon5f6b8712018-07-11 09:49:06 +0200999 default:
Harald Welte6a3a7142019-12-16 14:23:02 +01001000 TRACE_ERROR("%u: Received UART char in invalid 7816 state %s\r\n", ch->num,
1001 get_value_string(iso7816_3_card_state_names, ch->state));
Kévin Redon5f6b8712018-07-11 09:49:06 +02001002 break;
Harald Welte9d3e3822015-11-09 00:50:54 +01001003 }
1004
1005out_silent:
1006 if (new_state != -1)
1007 card_set_state(ch, new_state);
1008}
1009
Harald Welte855ba9e2016-02-24 21:00:46 +01001010/* transmit a single byte to the reader */
1011int card_emu_tx_byte(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +01001012{
1013 int rc = 0;
1014
1015 switch (ch->state) {
1016 case ISO_S_IN_ATR:
Kévin Redonebe672e2018-07-29 00:18:12 +02001017 rc = tx_byte_atr(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +01001018 break;
1019 case ISO_S_IN_PTS:
Harald Welte855ba9e2016-02-24 21:00:46 +01001020 rc = tx_byte_pts(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +01001021 break;
1022 case ISO_S_IN_TPDU:
Harald Welte855ba9e2016-02-24 21:00:46 +01001023 rc = tx_byte_tpdu(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +01001024 break;
Harald Weltead434402016-03-02 11:18:29 +01001025 default:
1026 break;
Harald Welte9d3e3822015-11-09 00:50:54 +01001027 }
1028
1029 if (rc)
1030 ch->stats.tx_bytes++;
1031
Harald Welte4d804672015-11-14 23:02:38 +01001032 /* if we return 0 here, the UART needs to disable transmit-ready
1033 * interrupts */
Harald Welte9d3e3822015-11-09 00:50:54 +01001034 return rc;
1035}
1036
Harald Welteacae4122016-03-02 10:27:58 +01001037void card_emu_have_new_uart_tx(struct card_handle *ch)
1038{
1039 switch (ch->state) {
1040 case ISO_S_IN_TPDU:
1041 switch (ch->tpdu.state) {
1042 case TPDU_S_WAIT_TX:
1043 case TPDU_S_WAIT_PB:
1044 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
1045 break;
1046 default:
1047 break;
1048 }
1049 default:
1050 break;
1051 }
1052}
1053
Harald Welte140f0072019-12-16 10:23:32 +01001054void card_emu_report_status(struct card_handle *ch, bool report_on_irq)
Harald Welteff160652016-03-19 21:59:06 +01001055{
Harald Welte8e7fca32017-05-07 16:14:33 +02001056 struct msgb *msg;
Harald Welteff160652016-03-19 21:59:06 +01001057 struct cardemu_usb_msg_status *sts;
Harald Welte140f0072019-12-16 10:23:32 +01001058 uint8_t ep = ch->in_ep;
Harald Welteff160652016-03-19 21:59:06 +01001059
Harald Welte140f0072019-12-16 10:23:32 +01001060 if (report_on_irq)
1061 ep = ch->irq_ep;
1062
1063 msg = usb_buf_alloc_st(ep, SIMTRACE_MSGC_CARDEM, SIMTRACE_MSGT_BD_CEMU_STATUS);
Harald Welte8e7fca32017-05-07 16:14:33 +02001064 if (!msg)
Harald Welteff160652016-03-19 21:59:06 +01001065 return;
Harald Welte8e7fca32017-05-07 16:14:33 +02001066
Harald Welte25a9a802017-05-08 13:30:09 +02001067 sts = (struct cardemu_usb_msg_status *) msgb_put(msg, sizeof(*sts));
Harald Welteff160652016-03-19 21:59:06 +01001068 sts->flags = 0;
1069 if (ch->vcc_active)
1070 sts->flags |= CEMU_STATUS_F_VCC_PRESENT;
1071 if (ch->clocked)
1072 sts->flags |= CEMU_STATUS_F_CLK_ACTIVE;
1073 if (ch->in_reset)
1074 sts->flags |= CEMU_STATUS_F_RESET_ACTIVE;
1075 /* FIXME: voltage + card insert */
1076 sts->fi = ch->fi;
1077 sts->di = ch->di;
1078 sts->wi = ch->wi;
1079 sts->waiting_time = ch->waiting_time;
1080
Harald Welte25a9a802017-05-08 13:30:09 +02001081 usb_buf_upd_len_and_submit(msg);
Harald Welteff160652016-03-19 21:59:06 +01001082}
1083
Harald Welte9d3e3822015-11-09 00:50:54 +01001084/* hardware driver informs us that a card I/O signal has changed */
1085void card_emu_io_statechg(struct card_handle *ch, enum card_io io, int active)
1086{
1087 switch (io) {
1088 case CARD_IO_VCC:
Harald Welte47ee2832016-02-29 10:09:46 +01001089 if (active == 0 && ch->vcc_active == 1) {
Harald Weltedde112e2016-03-20 16:42:11 +01001090 TRACE_INFO("%u: VCC deactivated\r\n", ch->num);
Harald Welte81f4ef72019-12-14 22:20:00 +01001091 card_handle_reset(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +01001092 card_set_state(ch, ISO_S_WAIT_POWER);
Harald Welte47ee2832016-02-29 10:09:46 +01001093 } else if (active == 1 && ch->vcc_active == 0) {
Harald Weltedde112e2016-03-20 16:42:11 +01001094 TRACE_INFO("%u: VCC activated\r\n", ch->num);
Harald Welte9d3e3822015-11-09 00:50:54 +01001095 card_set_state(ch, ISO_S_WAIT_CLK);
Harald Welte47ee2832016-02-29 10:09:46 +01001096 }
Harald Welte9d3e3822015-11-09 00:50:54 +01001097 ch->vcc_active = active;
1098 break;
1099 case CARD_IO_CLK:
Harald Welte47ee2832016-02-29 10:09:46 +01001100 if (active == 1 && ch->clocked == 0) {
Harald Weltedde112e2016-03-20 16:42:11 +01001101 TRACE_INFO("%u: CLK activated\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +01001102 if (ch->state == ISO_S_WAIT_CLK)
1103 card_set_state(ch, ISO_S_WAIT_RST);
1104 } else if (active == 0 && ch->clocked == 1) {
Harald Weltedde112e2016-03-20 16:42:11 +01001105 TRACE_INFO("%u: CLK deactivated\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +01001106 }
Harald Welte9d3e3822015-11-09 00:50:54 +01001107 ch->clocked = active;
1108 break;
1109 case CARD_IO_RST:
Harald Welte47ee2832016-02-29 10:09:46 +01001110 if (active == 0 && ch->in_reset) {
Harald Weltedde112e2016-03-20 16:42:11 +01001111 TRACE_INFO("%u: RST released\r\n", ch->num);
Harald Welte47ee2832016-02-29 10:09:46 +01001112 if (ch->vcc_active && ch->clocked) {
1113 /* enable the TC/ETU counter once reset has been released */
1114 tc_etu_enable(ch->tc_chan);
Kévin Redonebe672e2018-07-29 00:18:12 +02001115 /* prepare to send the ATR */
Harald Welte47ee2832016-02-29 10:09:46 +01001116 card_set_state(ch, ISO_S_WAIT_ATR);
Harald Welte47ee2832016-02-29 10:09:46 +01001117 }
1118 } else if (active && !ch->in_reset) {
Harald Weltedde112e2016-03-20 16:42:11 +01001119 TRACE_INFO("%u: RST asserted\r\n", ch->num);
Harald Welte81f4ef72019-12-14 22:20:00 +01001120 card_handle_reset(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +01001121 }
1122 ch->in_reset = active;
1123 break;
1124 }
Harald Weltee9f429d2019-12-15 13:21:17 +01001125
1126 switch (ch->state) {
1127 case ISO_S_WAIT_POWER:
1128 case ISO_S_WAIT_CLK:
1129 case ISO_S_WAIT_RST:
1130 /* check end activation state (even if the reader does
1131 * not respect the activation sequence) */
1132 if (ch->vcc_active && ch->clocked && !ch->in_reset) {
Harald Weltee9f429d2019-12-15 13:21:17 +01001133 /* prepare to send the ATR */
1134 card_set_state(ch, ISO_S_WAIT_ATR);
1135 }
1136 break;
1137 default:
1138 break;
1139 }
Harald Welte9d3e3822015-11-09 00:50:54 +01001140}
1141
1142/* User sets a new ATR to be returned during next card reset */
1143int card_emu_set_atr(struct card_handle *ch, const uint8_t *atr, uint8_t len)
1144{
1145 if (len > sizeof(ch->atr.atr))
1146 return -1;
1147
1148 memcpy(ch->atr.atr, atr, len);
1149 ch->atr.len = len;
1150 ch->atr.idx = 0;
1151
Kévin Redonebe672e2018-07-29 00:18:12 +02001152#if TRACE_LEVEL >= TRACE_LEVEL_INFO
1153 uint8_t i;
1154 TRACE_INFO("%u: ATR set: ", ch->num);
1155 for (i = 0; i < ch->atr.len; i++) {
1156 TRACE_INFO_WP("%02x ", atr[i]);
1157 }
1158 TRACE_INFO_WP("\n\r");
1159#endif
1160 /* FIXME: race condition with transmitting ATR to reader? */
Harald Welte9d3e3822015-11-09 00:50:54 +01001161
1162 return 0;
1163}
1164
1165/* hardware driver informs us that one (more) ETU has expired */
1166void tc_etu_wtime_half_expired(void *handle)
1167{
1168 struct card_handle *ch = handle;
1169 /* transmit NULL procedure byte well before waiting time expires */
Harald Weltedda73552016-03-02 10:29:55 +01001170 switch (ch->state) {
1171 case ISO_S_IN_TPDU:
1172 switch (ch->tpdu.state) {
1173 case TPDU_S_WAIT_PB:
1174 case TPDU_S_WAIT_TX:
1175 putchar('N');
1176 card_emu_uart_tx(ch->uart_chan, ISO7816_3_PB_NULL);
1177 break;
1178 default:
1179 break;
1180 }
1181 break;
1182 default:
1183 break;
1184 }
Harald Welte9d3e3822015-11-09 00:50:54 +01001185}
1186
1187/* hardware driver informs us that one (more) ETU has expired */
1188void tc_etu_wtime_expired(void *handle)
1189{
Harald Weltedde112e2016-03-20 16:42:11 +01001190 struct card_handle *ch = handle;
Kévin Redonebe672e2018-07-29 00:18:12 +02001191 switch (ch->state) {
1192 case ISO_S_WAIT_ATR:
1193 /* ISO 7816-3 6.2.1 time tc has passed, we can now send the ATR */
1194 card_set_state(ch, ISO_S_IN_ATR);
1195 break;
1196 default:
1197 TRACE_ERROR("%u: wtime_exp\r\n", ch->num);
1198 break;
1199 }
Harald Welte9d3e3822015-11-09 00:50:54 +01001200}
1201
Kévin Redon503e1842019-05-15 00:23:21 +02001202/* shortest ATR possible (uses default speed and no options) */
1203static const uint8_t default_atr[] = { 0x3B, 0x00 };
Harald Welte9d3e3822015-11-09 00:50:54 +01001204
1205static struct card_handle card_handles[NUM_SLOTS];
1206
Kévin Redon7233cf82019-11-14 19:37:32 +01001207struct 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 +01001208{
1209 struct card_handle *ch;
1210
1211 if (slot_num >= ARRAY_SIZE(card_handles))
1212 return NULL;
1213
1214 ch = &card_handles[slot_num];
1215
1216 memset(ch, 0, sizeof(*ch));
1217
Harald Welte54cb3d02016-02-29 14:12:40 +01001218 INIT_LLIST_HEAD(&ch->uart_tx_queue);
1219
Harald Weltedde112e2016-03-20 16:42:11 +01001220 ch->num = slot_num;
Harald Welte8e7fca32017-05-07 16:14:33 +02001221 ch->irq_ep = irq_ep;
1222 ch->in_ep = in_ep;
Harald Welte9d3e3822015-11-09 00:50:54 +01001223 ch->state = ISO_S_WAIT_POWER;
Kévin Redon7233cf82019-11-14 19:37:32 +01001224 ch->vcc_active = vcc_active;
1225 ch->in_reset = in_reset;
1226 ch->clocked = clocked;
Harald Welte9d3e3822015-11-09 00:50:54 +01001227
1228 ch->fi = 0;
1229 ch->di = 1;
1230 ch->wi = ISO7816_3_DEFAULT_WI;
1231
1232 ch->tc_chan = tc_chan;
1233 ch->uart_chan = uart_chan;
1234 ch->waiting_time = ISO7816_3_INIT_WTIME;
1235
1236 ch->atr.idx = 0;
1237 ch->atr.len = sizeof(default_atr);
1238 memcpy(ch->atr.atr, default_atr, ch->atr.len);
1239
Harald Weltee92cb502019-12-14 21:48:45 +01001240 card_handle_reset(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +01001241
1242 tc_etu_init(ch->tc_chan, ch);
1243
1244 return ch;
1245}