blob: 093e9a1ba285736c1a8281ec4bd4b36c8f70b089 [file] [log] [blame]
Harald Welte9d3e3822015-11-09 00:50:54 +01001/* ISO7816-3 state machine for the card side */
2/* (C) 2010-2015 by Harald Welte <hwelte@hmw-consulting.de>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 */
19
Harald Welte4c473da2015-11-14 13:31:11 +010020#include <assert.h>
Harald Welte9d3e3822015-11-09 00:50:54 +010021#include <errno.h>
22#include <string.h>
23#include <stdint.h>
24#include <sys/types.h>
25
26#include "utils.h"
27#include "trace.h"
28#include "iso7816_fidi.h"
29#include "tc_etu.h"
30#include "card_emu.h"
31#include "req_ctx.h"
32#include "cardemu_prot.h"
33
34
35#define NUM_SLOTS 2
36
37#define ISO7816_3_INIT_WTIME 9600
38#define ISO7816_3_DEFAULT_WI 10
39#define ISO7816_3_ATR_LEN_MAX (1+32) /* TS plus 32 chars */
40
41#define ISO7816_3_PB_NULL 0x60
42
43enum iso7816_3_card_state {
44 ISO_S_WAIT_POWER, /* waiting for power being applied */
45 ISO_S_WAIT_CLK, /* waiting for clock being applied */
46 ISO_S_WAIT_RST, /* waiting for reset being released */
47 ISO_S_WAIT_ATR, /* waiting for start of ATR */
48 ISO_S_IN_ATR, /* transmitting ATR to reader */
49 ISO_S_IN_PTS, /* transmitting ATR to reader */
50 ISO_S_WAIT_TPDU, /* waiting for data from reader */
51 ISO_S_IN_TPDU, /* inside a TPDU */
52};
53
54/* detailed sub-states of ISO_S_IN_PTS */
55enum pts_state {
56 PTS_S_WAIT_REQ_PTSS,
57 PTS_S_WAIT_REQ_PTS0,
58 PTS_S_WAIT_REQ_PTS1,
59 PTS_S_WAIT_REQ_PTS2,
60 PTS_S_WAIT_REQ_PTS3,
61 PTS_S_WAIT_REQ_PCK,
62 PTS_S_WAIT_RESP_PTSS = PTS_S_WAIT_REQ_PTSS | 0x10,
63 PTS_S_WAIT_RESP_PTS0 = PTS_S_WAIT_REQ_PTS0 | 0x10,
64 PTS_S_WAIT_RESP_PTS1 = PTS_S_WAIT_REQ_PTS1 | 0x10,
65 PTS_S_WAIT_RESP_PTS2 = PTS_S_WAIT_REQ_PTS2 | 0x10,
66 PTS_S_WAIT_RESP_PTS3 = PTS_S_WAIT_REQ_PTS3 | 0x10,
67 PTS_S_WAIT_RESP_PCK = PTS_S_WAIT_REQ_PCK | 0x10,
68};
69
70#define _PTSS 0
71#define _PTS0 1
72#define _PTS1 2
73#define _PTS2 3
74#define _PTS3 4
75#define _PCK 5
76
Harald Welte16cf4082015-11-11 19:02:48 +010077/* T-PDU state machine states */
Harald Welte9d3e3822015-11-09 00:50:54 +010078enum tpdu_state {
Harald Welte16cf4082015-11-11 19:02:48 +010079 TPDU_S_WAIT_CLA, /* waiting for CLA byte from reader */
80 TPDU_S_WAIT_INS, /* waiting for INS byte from reader */
81 TPDU_S_WAIT_P1, /* waiting for P1 byte from reader */
82 TPDU_S_WAIT_P2, /* waiting for P2 byte from reader */
83 TPDU_S_WAIT_P3, /* waiting for P3 byte from reader */
Harald Welte9d3e3822015-11-09 00:50:54 +010084 TPDU_S_WAIT_PB, /* waiting for Tx of procedure byte */
85 TPDU_S_WAIT_RX, /* waiitng for more data from reader */
86 TPDU_S_WAIT_TX, /* waiting for more data to reader */
87};
88
89#define _CLA 0
90#define _INS 1
91#define _P1 2
92#define _P2 3
93#define _P3 4
94
95struct card_handle {
96 enum iso7816_3_card_state state;
97
98 /* signal levels */
99 uint8_t vcc_active; /* 1 = on, 0 = off */
100 uint8_t in_reset; /* 1 = RST low, 0 = RST high */
101 uint8_t clocked; /* 1 = active, 0 = inactive */
102
Harald Welte16cf4082015-11-11 19:02:48 +0100103 /* timing parameters, from PTS */
Harald Welte9d3e3822015-11-09 00:50:54 +0100104 uint8_t fi;
105 uint8_t di;
106 uint8_t wi;
107
108 uint8_t tc_chan; /* TC channel number */
109 uint8_t uart_chan; /* UART channel */
110
111 uint32_t waiting_time; /* in clocks */
112
113 /* ATR state machine */
114 struct {
115 uint8_t idx;
116 uint8_t len;
117 //uint8_t hist_len;
118 //uint8_t last_td;
119 uint8_t atr[ISO7816_3_ATR_LEN_MAX];
120 } atr;
121
122 /* PPS / PTS support */
123 struct {
124 enum pts_state state;
Harald Welte16cf4082015-11-11 19:02:48 +0100125 uint8_t req[6]; /* request bytes */
126 uint8_t resp[6]; /* response bytes */
Harald Welte9d3e3822015-11-09 00:50:54 +0100127 } pts;
128
129 /* TPDU */
130 struct {
131 enum tpdu_state state;
Harald Welte16cf4082015-11-11 19:02:48 +0100132 uint8_t hdr[5]; /* CLA INS P1 P2 P3 */
Harald Welte9d3e3822015-11-09 00:50:54 +0100133 } tpdu;
134
Harald Welte16cf4082015-11-11 19:02:48 +0100135 struct req_ctx *uart_rx_ctx; /* UART RX -> USB TX */
136 struct req_ctx *uart_tx_ctx; /* USB RX -> UART TX */
Harald Welte9d3e3822015-11-09 00:50:54 +0100137
138 struct {
139 uint32_t tx_bytes;
140 uint32_t rx_bytes;
141 uint32_t pps;
142 } stats;
143};
144
Harald Welte2935b3c2015-11-14 20:00:14 +0100145static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts);
Harald Weltee7194ab2015-11-14 21:03:25 +0100146static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss);
Harald Welte2935b3c2015-11-14 20:00:14 +0100147
Harald Welteb5288e82015-11-14 21:15:52 +0100148static void flush_rx_buffer(struct card_handle *ch)
149{
150 struct req_ctx *rctx;
151 struct cardemu_usb_msg_rx_data *rd;
152
153 rctx = ch->uart_rx_ctx;
154 if (!rctx)
155 return;
156
157 rd = (struct cardemu_usb_msg_rx_data *) ch->uart_rx_ctx->data;
158
159 /* store length of data payload fild in header */
160 rd->hdr.data_len = rctx->idx;
161 req_ctx_set_state(rctx, RCTX_S_USB_TX_PENDING);
162 ch->uart_rx_ctx = NULL;
163
164 /* FIXME: call into USB code to see if this buffer can
165 * be transmitted now */
166}
167
Harald Welte612d65a2015-11-14 13:30:43 +0100168static void update_fidi(struct card_handle *ch)
Harald Welte9d3e3822015-11-09 00:50:54 +0100169{
170 int rc;
171
172 rc = compute_fidi_ratio(ch->fi, ch->di);
173 if (rc > 0 && rc < 0x400) {
174 TRACE_DEBUG("computed Fi(%u) Di(%u) ratio: %d\n",
175 ch->fi, ch->di, rc);
176 /* make sure UART uses new F/D ratio */
177 card_emu_uart_update_fidi(ch->uart_chan, rc);
178 /* notify ETU timer about this */
179 tc_etu_set_etu(ch->tc_chan, rc);
180 } else
181 TRACE_DEBUG("computed FiDi ration %d unsupported\n", rc);
182}
183
184/* Update the ISO 7816-3 TPDU receiver state */
185static void card_set_state(struct card_handle *ch,
186 enum iso7816_3_card_state new_state)
187{
188 switch (new_state) {
189 case ISO_S_WAIT_POWER:
190 case ISO_S_WAIT_CLK:
191 case ISO_S_WAIT_RST:
192 /* disable Rx and Tx of UART */
193 card_emu_uart_enable(ch->uart_chan, 0);
194 break;
195 case ISO_S_WAIT_ATR:
Harald Weltee7194ab2015-11-14 21:03:25 +0100196 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
Harald Welte9d3e3822015-11-09 00:50:54 +0100197 /* Reset to initial Fi / Di ratio */
198 ch->fi = 1;
199 ch->di = 1;
200 update_fidi(ch);
201 /* initialize todefault WI, this will be overwritten if we
202 * receive TC2, and it will be programmed into hardware after
203 * ATR is finished */
204 ch->wi = ISO7816_3_DEFAULT_WI;
205 /* update waiting time to initial waiting time */
206 ch->waiting_time = ISO7816_3_INIT_WTIME;
207 tc_etu_set_wtime(ch->tc_chan, ch->waiting_time);
208 /* Set ATR sub-state to initial state */
209 ch->atr.idx = 0;
210 //set_atr_state(ch, ATR_S_WAIT_TS);
211 /* Notice that we are just coming out of reset */
212 //ch->sh.flags |= SIMTRACE_FLAG_ATR;
213 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
214 break;
215 break;
216 case ISO_S_WAIT_TPDU:
217 /* enable the receiver, disable transmitter */
Harald Welte2935b3c2015-11-14 20:00:14 +0100218 set_tpdu_state(ch, TPDU_S_WAIT_CLA);
Harald Welte9d3e3822015-11-09 00:50:54 +0100219 card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
220 break;
221 case ISO_S_IN_ATR:
222 case ISO_S_IN_PTS:
223 case ISO_S_IN_TPDU:
224 /* do nothing */
225 break;
226 }
227
228 if (ch->state == new_state)
229 return;
230
231 TRACE_DEBUG("7816 card state %u -> %u\n", ch->state, new_state);
232 ch->state = new_state;
233}
234
235
236/**********************************************************************
237 * PTS / PPS handling
238 **********************************************************************/
239
240/* Update the ATR sub-state */
241static void set_pts_state(struct card_handle *ch, enum pts_state new_ptss)
242{
243 TRACE_DEBUG("7816 PTS state %u -> %u\n", ch->pts.state, new_ptss);
244 ch->pts.state = new_ptss;
245}
246
247/* Determine the next PTS state */
248static enum pts_state next_pts_state(struct card_handle *ch)
249{
250 uint8_t is_resp = ch->pts.state & 0x10;
251 uint8_t sstate = ch->pts.state & 0x0f;
252 uint8_t *pts_ptr;
253
254 if (!is_resp)
255 pts_ptr = ch->pts.req;
256 else
257 pts_ptr = ch->pts.resp;
258
259 switch (sstate) {
260 case PTS_S_WAIT_REQ_PTSS:
261 goto from_ptss;
262 case PTS_S_WAIT_REQ_PTS0:
263 goto from_pts0;
264 case PTS_S_WAIT_REQ_PTS1:
265 goto from_pts1;
266 case PTS_S_WAIT_REQ_PTS2:
267 goto from_pts2;
268 case PTS_S_WAIT_REQ_PTS3:
269 goto from_pts3;
270 }
271
272 if (ch->pts.state == PTS_S_WAIT_REQ_PCK)
273 return PTS_S_WAIT_RESP_PTSS;
274
275from_ptss:
276 return PTS_S_WAIT_REQ_PTS0 | is_resp;
277from_pts0:
278 if (pts_ptr[_PTS0] & (1 << 4))
279 return PTS_S_WAIT_REQ_PTS1 | is_resp;
280from_pts1:
281 if (pts_ptr[_PTS0] & (1 << 5))
282 return PTS_S_WAIT_REQ_PTS2 | is_resp;
283from_pts2:
284 if (pts_ptr[_PTS0] & (1 << 6))
285 return PTS_S_WAIT_REQ_PTS3 | is_resp;
286from_pts3:
287 return PTS_S_WAIT_REQ_PCK | is_resp;
288}
289
290
291static enum iso7816_3_card_state
292process_byte_pts(struct card_handle *ch, uint8_t byte)
293{
294 switch (ch->pts.state) {
295 case PTS_S_WAIT_REQ_PTSS:
296 ch->pts.req[_PTSS] = byte;
297 break;
298 case PTS_S_WAIT_REQ_PTS0:
299 ch->pts.req[_PTS0] = byte;
300 break;
301 case PTS_S_WAIT_REQ_PTS1:
302 ch->pts.req[_PTS1] = byte;
303 break;
304 case PTS_S_WAIT_REQ_PTS2:
305 ch->pts.req[_PTS2] = byte;
306 break;
307 case PTS_S_WAIT_REQ_PTS3:
308 ch->pts.req[_PTS3] = byte;
309 break;
310 case PTS_S_WAIT_REQ_PCK:
311 ch->pts.req[_PCK] = byte;
312 /* FIXME: check PCK */
313 memcpy(ch->pts.resp, ch->pts.req, sizeof(ch->pts.resp));
314 break;
Harald Welte4c473da2015-11-14 13:31:11 +0100315 default:
316 TRACE_DEBUG("process_byte_pts() in invalid state %u\n",
317 ch->pts.state);
318 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100319 }
320 /* calculate the next state and set it */
321 set_pts_state(ch, next_pts_state(ch));
322
323 return ISO_S_IN_PTS;
324}
325
326/* return a single byte to be transmitted to the reader */
Harald Welted79dc4f2015-11-14 13:32:21 +0100327static int get_byte_pts(struct card_handle *ch, uint8_t *byte)
Harald Welte9d3e3822015-11-09 00:50:54 +0100328{
Harald Welte9d3e3822015-11-09 00:50:54 +0100329 switch (ch->pts.state) {
330 case PTS_S_WAIT_RESP_PTSS:
Harald Welted79dc4f2015-11-14 13:32:21 +0100331 *byte = ch->pts.resp[_PTSS];
Harald Welte9d3e3822015-11-09 00:50:54 +0100332 break;
333 case PTS_S_WAIT_RESP_PTS0:
Harald Welted79dc4f2015-11-14 13:32:21 +0100334 *byte = ch->pts.resp[_PTS0];
Harald Welte9d3e3822015-11-09 00:50:54 +0100335 break;
336 case PTS_S_WAIT_RESP_PTS1:
Harald Welted79dc4f2015-11-14 13:32:21 +0100337 *byte = ch->pts.resp[_PTS1];
Harald Welte9d3e3822015-11-09 00:50:54 +0100338 /* This must be TA1 */
Harald Welted79dc4f2015-11-14 13:32:21 +0100339 ch->fi = *byte >> 4;
340 ch->di = *byte & 0xf;
Harald Welte9d3e3822015-11-09 00:50:54 +0100341 TRACE_DEBUG("found Fi=%u Di=%u\n", ch->fi, ch->di);
Harald Welted79dc4f2015-11-14 13:32:21 +0100342 //ch->sh.flags |= SIMTRACE_FLAG_PPS_FIDI;
Harald Welte9d3e3822015-11-09 00:50:54 +0100343 break;
344 case PTS_S_WAIT_RESP_PTS2:
Harald Welted79dc4f2015-11-14 13:32:21 +0100345 *byte = ch->pts.resp[_PTS2];
Harald Welte9d3e3822015-11-09 00:50:54 +0100346 break;
347 case PTS_S_WAIT_RESP_PTS3:
Harald Welted79dc4f2015-11-14 13:32:21 +0100348 *byte = ch->pts.resp[_PTS3];
Harald Welte9d3e3822015-11-09 00:50:54 +0100349 break;
350 case PTS_S_WAIT_RESP_PCK:
Harald Welted79dc4f2015-11-14 13:32:21 +0100351 *byte = ch->pts.resp[_PCK];
Harald Welte9d3e3822015-11-09 00:50:54 +0100352 set_pts_state(ch, PTS_S_WAIT_REQ_PTSS);
353 /* update baud rate generator with Fi/Di */
354 update_fidi(ch);
355 /* Wait for the next TPDU */
356 card_set_state(ch, ISO_S_WAIT_TPDU);
Harald Welted79dc4f2015-11-14 13:32:21 +0100357 default:
358 TRACE_DEBUG("get_byte_pts() in invalid state %u\n",
359 ch->pts.state);
360 break;
Harald Welte9d3e3822015-11-09 00:50:54 +0100361 }
Harald Welted79dc4f2015-11-14 13:32:21 +0100362
Harald Welte9d3e3822015-11-09 00:50:54 +0100363 /* calculate the next state and set it */
364 set_pts_state(ch, next_pts_state(ch));
365
366 return 0;
367}
368
369
370/**********************************************************************
371 * TPDU handling
372 **********************************************************************/
373
Harald Welte4d804672015-11-14 23:02:38 +0100374
375/* compute number of data bytes according to Chapter 10.3.2 of 7816-3 */
376static unsigned int t0_num_data_bytes(uint8_t p3, int reader_to_card)
377{
378 if (reader_to_card) {
379 return p3;
380 } else {
381 if (p3 == 0)
382 return 256;
383 else
384 return p3;
385 }
386}
387
Harald Welte9d3e3822015-11-09 00:50:54 +0100388/* add a just-received TPDU byte (from reader) to USB buffer */
Harald Welte4d804672015-11-14 23:02:38 +0100389static enum iso7816_3_card_state add_tpdu_byte(struct card_handle *ch, uint8_t byte)
Harald Welte9d3e3822015-11-09 00:50:54 +0100390{
391 struct req_ctx *rctx;
392 struct cardemu_usb_msg_rx_data *rd;
Harald Welte4d804672015-11-14 23:02:38 +0100393 unsigned int num_data_bytes = t0_num_data_bytes(ch->tpdu.hdr[_P3], 0);
Harald Welte9d3e3822015-11-09 00:50:54 +0100394
395 /* ensure we have a buffer */
396 if (!ch->uart_rx_ctx) {
Harald Welte4d804672015-11-14 23:02:38 +0100397 rctx = ch->uart_rx_ctx = req_ctx_find_get(0, RCTX_S_FREE, RCTX_S_UART_RX_BUSY);
398 if (!ch->uart_rx_ctx) {
399 TRACE_DEBUG("Received UART byte but unable to allocate Rx Buf\n");
Harald Welte9d3e3822015-11-09 00:50:54 +0100400 return;
Harald Welte4d804672015-11-14 23:02:38 +0100401 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100402 rd = (struct cardemu_usb_msg_rx_data *) ch->uart_rx_ctx->data;
403 cardemu_hdr_set(&rd->hdr, CEMU_USB_MSGT_DO_RX_DATA);
404 rctx->tot_len = sizeof(*rd);
405 rctx->idx = 0;
406 } else
407 rctx = ch->uart_rx_ctx;
408
409 rd = (struct cardemu_usb_msg_rx_data *) rctx->data;
410
411 rd->data[rctx->idx++] = byte;
412 rctx->tot_len++;
413
414 /* check if the buffer is full. If so, send it */
Harald Welte4d804672015-11-14 23:02:38 +0100415 if (rctx->tot_len >= sizeof(*rd) + num_data_bytes) {
416 rd->flags |= CEMU_DATA_F_FINAL;
Harald Welteb5288e82015-11-14 21:15:52 +0100417 flush_rx_buffer(ch);
Harald Welte4d804672015-11-14 23:02:38 +0100418 return ISO_S_WAIT_TPDU;
419 } else if (rctx->tot_len >= rctx->size)
420 flush_rx_buffer(ch);
421
422 return ISO_S_IN_TPDU;
Harald Welte9d3e3822015-11-09 00:50:54 +0100423}
424
425static void set_tpdu_state(struct card_handle *ch, enum tpdu_state new_ts)
426{
Harald Welte05b41c62015-11-14 20:58:48 +0100427 if (ch->tpdu.state == new_ts)
428 return;
429
Harald Welte9d3e3822015-11-09 00:50:54 +0100430 TRACE_DEBUG("7816 TPDU state %u -> %u\n", ch->tpdu.state, new_ts);
Harald Welte05b41c62015-11-14 20:58:48 +0100431
Harald Welte9d3e3822015-11-09 00:50:54 +0100432 switch (new_ts) {
433 case TPDU_S_WAIT_CLA:
Harald Welte05b41c62015-11-14 20:58:48 +0100434 case TPDU_S_WAIT_RX:
Harald Welte9d3e3822015-11-09 00:50:54 +0100435 card_emu_uart_enable(ch->uart_chan, ENABLE_RX);
436 break;
437 case TPDU_S_WAIT_PB:
438 /* we just completed the TPDU header from reader to card
439 * and now need to disable the receiver, enable the
440 * transmitter and transmit the procedure byte */
441 card_emu_uart_enable(ch->uart_chan, ENABLE_TX);
442 break;
443 }
Harald Welte05b41c62015-11-14 20:58:48 +0100444
Harald Welte9d3e3822015-11-09 00:50:54 +0100445 ch->tpdu.state = new_ts;
446}
447
448static enum tpdu_state next_tpdu_state(struct card_handle *ch)
449{
450 switch (ch->tpdu.state) {
451 case TPDU_S_WAIT_CLA:
452 return TPDU_S_WAIT_INS;
453 case TPDU_S_WAIT_INS:
454 return TPDU_S_WAIT_P1;
455 case TPDU_S_WAIT_P1:
456 return TPDU_S_WAIT_P2;
457 case TPDU_S_WAIT_P2:
458 return TPDU_S_WAIT_P3;
459 case TPDU_S_WAIT_P3:
460 return TPDU_S_WAIT_PB;
461 /* simply stay in Rx or Tx by default */
462 case TPDU_S_WAIT_PB:
463 return TPDU_S_WAIT_PB;
464 case TPDU_S_WAIT_RX:
465 return TPDU_S_WAIT_RX;
466 case TPDU_S_WAIT_TX:
467 return TPDU_S_WAIT_TX;
468 }
Harald Welte4c473da2015-11-14 13:31:11 +0100469 /* we should never reach here */
470 assert(0);
471 return -1;
Harald Welte9d3e3822015-11-09 00:50:54 +0100472}
473
474static void send_tpdu_header(struct card_handle *ch)
475{
476 struct req_ctx *rctx;
477 struct cardemu_usb_msg_rx_data *rd;
478
479 /* if we already/still have a context, send it off */
Harald Welte2935b3c2015-11-14 20:00:14 +0100480 if (ch->uart_rx_ctx && ch->uart_rx_ctx->idx) {
Harald Welteb5288e82015-11-14 21:15:52 +0100481 flush_rx_buffer(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100482 }
483
484 /* ensure we have a new buffer */
Harald Welte4d804672015-11-14 23:02:38 +0100485 ch->uart_rx_ctx = req_ctx_find_get(0, RCTX_S_FREE, RCTX_S_UART_RX_BUSY);
Harald Welte9d3e3822015-11-09 00:50:54 +0100486 if (!ch->uart_rx_ctx)
487 return;
488 rctx = ch->uart_rx_ctx;
489 rd = (struct cardemu_usb_msg_rx_data *) rctx->data;
490
491 /* initializ header */
492 cardemu_hdr_set(&rd->hdr, CEMU_USB_MSGT_DO_RX_DATA);
493 rd->flags = CEMU_DATA_F_TPDU_HDR;
494 rctx->tot_len = sizeof(*rd) + sizeof(ch->tpdu.hdr);
495 rctx->idx = 0;
496
497 /* copy TPDU header to data field */
498 memcpy(rd->data, ch->tpdu.hdr, sizeof(ch->tpdu.hdr));
Harald Welteb5288e82015-11-14 21:15:52 +0100499 /* rd->data_len is set in flush_rx_buffer() */
Harald Welte9d3e3822015-11-09 00:50:54 +0100500
Harald Welteb5288e82015-11-14 21:15:52 +0100501 flush_rx_buffer(ch);
Harald Welte9d3e3822015-11-09 00:50:54 +0100502}
503
504static enum iso7816_3_card_state
505process_byte_tpdu(struct card_handle *ch, uint8_t byte)
506{
507 switch (ch->tpdu.state) {
508 case TPDU_S_WAIT_CLA:
509 ch->tpdu.hdr[_CLA] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100510 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100511 break;
512 case TPDU_S_WAIT_INS:
513 ch->tpdu.hdr[_INS] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100514 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100515 break;
516 case TPDU_S_WAIT_P1:
517 ch->tpdu.hdr[_P1] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100518 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100519 break;
520 case TPDU_S_WAIT_P2:
521 ch->tpdu.hdr[_P2] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100522 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100523 break;
524 case TPDU_S_WAIT_P3:
525 ch->tpdu.hdr[_P3] = byte;
Harald Welte4d804672015-11-14 23:02:38 +0100526 set_tpdu_state(ch, next_tpdu_state(ch));
Harald Welte9d3e3822015-11-09 00:50:54 +0100527 /* FIXME: start timer to transmit further 0x60 */
528 /* send the TPDU header as part of a procedure byte
529 * request to the USB host */
530 send_tpdu_header(ch);
531 break;
532 case TPDU_S_WAIT_RX:
Harald Welte4d804672015-11-14 23:02:38 +0100533 return add_tpdu_byte(ch, byte);
Harald Welte9d3e3822015-11-09 00:50:54 +0100534 default:
535 TRACE_DEBUG("process_byte_tpdu() in invalid state %u\n",
536 ch->tpdu.state);
537 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100538
539 /* ensure we stay in TPDU ISO state */
540 return ISO_S_IN_TPDU;
541}
542
543/* return a single byte to be transmitted to the reader */
544static int get_byte_tpdu(struct card_handle *ch, uint8_t *byte)
545{
546 struct req_ctx *rctx;
547 struct cardemu_usb_msg_tx_data *td;
548
549 /* ensure we are aware of any data that might be pending for
550 * transmit */
551 if (!ch->uart_tx_ctx) {
Harald Welte4d804672015-11-14 23:02:38 +0100552 ch->uart_tx_ctx = req_ctx_find_get(0, RCTX_S_UART_TX_PENDING,
Harald Welte9d3e3822015-11-09 00:50:54 +0100553 RCTX_S_UART_TX_BUSY);
554 if (!ch->uart_tx_ctx)
555 return 0;
556
557 /* start with index zero */
558 ch->uart_tx_ctx->idx = 0;
559
560 }
561 rctx = ch->uart_tx_ctx;
562 td = (struct cardemu_usb_msg_tx_data *) rctx->data;
563
564#if 0
Harald Welte4d804672015-11-14 23:02:38 +0100565 /* FIXME: this must happen _after_ the byte has been transmittd */
Harald Welte9d3e3822015-11-09 00:50:54 +0100566 switch (ch->tpdu.state) {
567 case TPDU_S_WAIT_PB:
568 if (td->flags & CEMU_DATA_F_PB_AND_TX)
569 set_tpdu_state(ch, TPDU_S_WAIT_TX);
570 else if (td->flags & CEMU_DATA_F_PB_AND_RX)
571 set_tpdu_state(ch, TPDU_S_WAIT_RX);
572 break;
573 }
574#endif
575
576 /* take the next pending byte out of the rctx */
577 *byte = td->data[rctx->idx++];
578
579 /* check if the buffer has now been fully transmitted */
580 if ((rctx->idx >= td->hdr.data_len) ||
581 (rctx->idx + sizeof(*td) - sizeof(td->hdr) >= rctx->tot_len)) {
Harald Welte52922ff2015-11-14 20:59:56 +0100582 if (td->flags & CEMU_DATA_F_PB_AND_RX) {
583 /* we have just sent the procedure byte and now
584 * need to continue receiving */
585 set_tpdu_state(ch, TPDU_S_WAIT_RX);
Harald Welte2935b3c2015-11-14 20:00:14 +0100586 } else {
Harald Welte52922ff2015-11-14 20:59:56 +0100587 /* we have transmitted all bytes */
588 if (td->flags & CEMU_DATA_F_FINAL) {
589 /* this was the final part of the APDU, go
590 * back to state one*/
591 card_set_state(ch, ISO_S_WAIT_TPDU);
592 } else {
593 /* FIXME: call into USB code to chec if we need
594 * to submit a free buffer to accept
595 * further data on bulk out endpoint */
596 }
Harald Welte2935b3c2015-11-14 20:00:14 +0100597 }
Harald Welte9d3e3822015-11-09 00:50:54 +0100598 req_ctx_set_state(rctx, RCTX_S_FREE);
599 ch->uart_tx_ctx = NULL;
Harald Welte9d3e3822015-11-09 00:50:54 +0100600 }
601
602 return 1;
603}
604
605/**********************************************************************
606 * Public API
607 **********************************************************************/
608
609/* process a single byte received from the reader */
610void card_emu_process_rx_byte(struct card_handle *ch, uint8_t byte)
611{
612 int new_state = -1;
613
614 ch->stats.rx_bytes++;
615
616 switch (ch->state) {
617 case ISO_S_WAIT_POWER:
618 case ISO_S_WAIT_CLK:
619 case ISO_S_WAIT_RST:
620 case ISO_S_WAIT_ATR:
Harald Welte4d804672015-11-14 23:02:38 +0100621 TRACE_DEBUG("Received UART char in 7816 state %u\n",
622 ch->state);
Harald Welte9d3e3822015-11-09 00:50:54 +0100623 /* we shouldn't receive any data from the reader yet! */
624 break;
625 case ISO_S_WAIT_TPDU:
626 if (byte == 0xff) {
627 new_state = process_byte_pts(ch, byte);
628 ch->stats.pps++;
629 goto out_silent;
630 }
631 /* fall-through */
632 case ISO_S_IN_TPDU:
633 new_state = process_byte_tpdu(ch, byte);
634 break;
635 case ISO_S_IN_PTS:
636 new_state = process_byte_pts(ch, byte);
637 goto out_silent;
638 }
639
640out_silent:
641 if (new_state != -1)
642 card_set_state(ch, new_state);
643}
644
645/* return a single byte to be transmitted to the reader */
646int card_emu_get_tx_byte(struct card_handle *ch, uint8_t *byte)
647{
648 int rc = 0;
649
650 switch (ch->state) {
651 case ISO_S_IN_ATR:
652 if (ch->atr.idx < ch->atr.len) {
653 *byte = ch->atr.atr[ch->atr.idx++];
654 rc = 1;
655 /* detect end of ATR */
656 if (ch->atr.idx >= ch->atr.len)
657 card_set_state(ch, ISO_S_WAIT_TPDU);
658 }
659 break;
660 case ISO_S_IN_PTS:
Harald Welted79dc4f2015-11-14 13:32:21 +0100661 rc = get_byte_pts(ch, byte);
Harald Welte9d3e3822015-11-09 00:50:54 +0100662 break;
663 case ISO_S_IN_TPDU:
664 rc = get_byte_tpdu(ch, byte);
665 break;
666 }
667
668 if (rc)
669 ch->stats.tx_bytes++;
670
Harald Welte4d804672015-11-14 23:02:38 +0100671 /* if we return 0 here, the UART needs to disable transmit-ready
672 * interrupts */
Harald Welte9d3e3822015-11-09 00:50:54 +0100673 return rc;
674}
675
676/* hardware driver informs us that a card I/O signal has changed */
677void card_emu_io_statechg(struct card_handle *ch, enum card_io io, int active)
678{
679 switch (io) {
680 case CARD_IO_VCC:
681 if (active == 0)
682 card_set_state(ch, ISO_S_WAIT_POWER);
683 else if (active == 1 && ch->vcc_active == 0)
684 card_set_state(ch, ISO_S_WAIT_CLK);
685 ch->vcc_active = active;
686 break;
687 case CARD_IO_CLK:
688 if (active == 1 && ch->state == ISO_S_WAIT_CLK)
689 card_set_state(ch, ISO_S_WAIT_RST);
690 ch->clocked = active;
691 break;
692 case CARD_IO_RST:
693 if (active == 0 && ch->in_reset &&
694 ch->vcc_active && ch->clocked) {
Harald Weltee7194ab2015-11-14 21:03:25 +0100695 card_set_state(ch, ISO_S_WAIT_ATR);
Harald Welte9d3e3822015-11-09 00:50:54 +0100696 /* FIXME: wait 400 clocks */
Harald Welte9d3e3822015-11-09 00:50:54 +0100697 card_set_state(ch, ISO_S_IN_ATR);
698 }
699 ch->in_reset = active;
700 break;
701 }
702}
703
704/* User sets a new ATR to be returned during next card reset */
705int card_emu_set_atr(struct card_handle *ch, const uint8_t *atr, uint8_t len)
706{
707 if (len > sizeof(ch->atr.atr))
708 return -1;
709
710 memcpy(ch->atr.atr, atr, len);
711 ch->atr.len = len;
712 ch->atr.idx = 0;
713
714 /* FIXME: race condition with trasmitting ATR to reader? */
715
716 return 0;
717}
718
719/* hardware driver informs us that one (more) ETU has expired */
720void tc_etu_wtime_half_expired(void *handle)
721{
722 struct card_handle *ch = handle;
723 /* transmit NULL procedure byte well before waiting time expires */
724 card_emu_uart_tx(ch->uart_chan, ISO7816_3_PB_NULL);
725}
726
727/* hardware driver informs us that one (more) ETU has expired */
728void tc_etu_wtime_expired(void *handle)
729{
730}
731
732/* shortest ATR found in smartcard_list.txt */
733static const uint8_t default_atr[] = { 0x3B, 0x02, 0x14, 0x50 };
734
735static struct card_handle card_handles[NUM_SLOTS];
736
737struct card_handle *card_emu_init(uint8_t slot_num, uint8_t tc_chan, uint8_t uart_chan)
738{
739 struct card_handle *ch;
740
741 if (slot_num >= ARRAY_SIZE(card_handles))
742 return NULL;
743
744 ch = &card_handles[slot_num];
745
746 memset(ch, 0, sizeof(*ch));
747
748 /* initialize the card_handle with reasonabe defaults */
749 ch->state = ISO_S_WAIT_POWER;
750 ch->vcc_active = 0;
751 ch->in_reset = 1;
752 ch->clocked = 0;
753
754 ch->fi = 0;
755 ch->di = 1;
756 ch->wi = ISO7816_3_DEFAULT_WI;
757
758 ch->tc_chan = tc_chan;
759 ch->uart_chan = uart_chan;
760 ch->waiting_time = ISO7816_3_INIT_WTIME;
761
762 ch->atr.idx = 0;
763 ch->atr.len = sizeof(default_atr);
764 memcpy(ch->atr.atr, default_atr, ch->atr.len);
765
766 ch->pts.state = PTS_S_WAIT_REQ_PTSS;
767 ch->tpdu.state = TPDU_S_WAIT_CLA;
768
769 tc_etu_init(ch->tc_chan, ch);
770
771 return ch;
772}