- fix Building without Nagra not possible at Nagra_Merlin https://trac.streamboard...
[oscam.git] / csctapi / protocol_t0.c
blobcd691c4c7732802fe4b873c29f1d04bc3c5a1b49
1 /*
2 protocol_t0.c
3 Handling of ISO 7816 T=0 protocol
5 This file is part of the Unix driver for Towitoko smartcard readers
6 Copyright (C) 2000 Carlos Prados <cprados@yahoo.com>
8 This version is modified by doz21 to work in a special manner ;)
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 2 of the License, or (at your option) any later version.
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "../globals.h"
27 #ifdef WITH_CARDREADER
28 #include "../oscam-time.h"
29 #include "icc_async.h"
30 #include "protocol_t0.h"
32 * Not exported constants definition
35 #define OK 0
36 #define ERROR 1
38 #define PROTOCOL_T0_MAX_NULLS 200
39 #define PROTOCOL_T0_DEFAULT_WI 10
40 #define PROTOCOL_T0_MAX_SHORT_COMMAND 260
41 #define PROTOCOL_T0_MAX_SHORT_RESPONSE 258
43 #define PROTOCOL_T14_MAX_NULLS 200
44 #define PROTOCOL_T14_DEFAULT_WI 10
45 #define PROTOCOL_T14_MAX_SHORT_COMMAND 260
46 #define PROTOCOL_T14_MAX_SHORT_RESPONSE 258
48 /* Types of APDU's */
49 #define APDU_CASE_1 0x0001 /* Nor send neither receive data */
50 #define APDU_CASE_2S 0x0002 /* Receive data (1..256) */
51 #define APDU_CASE_3S 0x0003 /* Send data (1..255) */
52 #define APDU_CASE_4S 0x0004 /* Send data (1..255) and receive data (1..256) */
53 #define APDU_CASE_2E 0x0102 /* Receive data (1..65536) */
54 #define APDU_CASE_3E 0x0103 /* Send data (1..65535) */
55 #define APDU_CASE_4E 0x0104 /* Send data (1..65535) and receive data (1..65536) */
56 #define APDU_MALFORMED 5 /* Malformed APDU */
58 /* Timings in ATR are not used in T=0 cards */
59 /* #undef PROTOCOL_T0_USE_DEFAULT_TIMINGS */
62 * Not exported functions declaration
65 static int32_t Protocol_T0_Case2E(struct s_reader *reader, unsigned char *command, uint16_t command_len, unsigned char *rsp, uint16_t *lr);
66 static int32_t Protocol_T0_Case3E(struct s_reader *reader, unsigned char *command, unsigned char *rsp, uint16_t *lr);
67 static int32_t Protocol_T0_Case4E(struct s_reader *reader, unsigned char *command, uint16_t command_len, unsigned char *rsp, uint16_t *lr);
68 static int32_t Protocol_T0_ExchangeTPDU(struct s_reader *reader, unsigned char *command, uint16_t command_len, unsigned char *rsp, uint16_t *lr);
70 static int32_t APDU_Cmd_Case(unsigned char *command, uint16_t command_len){
71 unsigned char B1;
72 uint16_t B2B3;
73 uint32_t L;
74 int32_t res;
76 /* Calculate length of body */
77 L = MAX(command_len - 4, 0);
79 /* Case 1 */
80 if(L == 0)
81 { res = APDU_CASE_1; }
82 else
84 /* Get first byte of body */
85 B1 = command[4];
87 if((B1 != 0) && (L == (uint32_t)B1 + 1))
88 { res = APDU_CASE_2S; }
89 else if(L == 1)
90 { res = APDU_CASE_3S; }
91 else if((B1 != 0) && (L == (uint32_t)B1 + 2))
92 { res = APDU_CASE_4S; }
93 else if((B1 == 0) && (L > 2))
95 /* Get second and third byte of body */
96 B2B3 = (((uint16_t)(command[5]) << 8) | command[6]);
98 if((B2B3 != 0) && (L == (uint32_t)B2B3 + 3))
99 { res = APDU_CASE_2E; }
100 else if(L == 3)
101 { res = APDU_CASE_3E; }
102 else if((B2B3 != 0) && (L == (uint32_t)B2B3 + 5))
103 { res = APDU_CASE_4E; }
104 else
105 { res = APDU_MALFORMED; }
107 else
108 { res = APDU_MALFORMED; }
110 return res;
114 * Exported funtions definition
117 int32_t Protocol_T0_Command(struct s_reader *reader, unsigned char *command, uint16_t command_len, unsigned char *rsp, uint16_t *lr)
119 *lr = 0; //will be returned in case of error
120 if(command_len < 5) //APDU_CASE_1 or malformed
121 { return ERROR; }
122 int32_t cmd_case = APDU_Cmd_Case(command, command_len);
123 switch(cmd_case)
125 case APDU_CASE_2E:
126 return Protocol_T0_Case2E(reader, command, command_len, rsp, lr); /* fallthrough */
127 case APDU_CASE_3E:
128 return Protocol_T0_Case3E(reader, command, rsp, lr); /* fallthrough */
129 case APDU_CASE_4E:
130 return Protocol_T0_Case4E(reader, command, command_len, rsp, lr); /* fallthrough */
131 case APDU_CASE_4S:
132 command_len--; /* fallthrough */ //FIXME this should change 4S to 2S/3S command
133 case APDU_CASE_2S: /* fallthrough */
134 case APDU_CASE_3S:
135 return Protocol_T0_ExchangeTPDU(reader, command, command_len, rsp, lr); /* fallthrough */
136 default:
137 rdr_log_dbg(reader, D_IFD, "Protocol: T=0: Invalid APDU");
138 return ERROR;
143 * Not exported functions definition
147 static int32_t Protocol_T0_Case2E(struct s_reader *reader, unsigned char *command, uint16_t command_len, unsigned char *rsp, uint16_t *lr)
149 unsigned char buffer[PROTOCOL_T0_MAX_SHORT_COMMAND];
150 unsigned char tpdu_rsp[CTA_RES_LEN];
151 uint16_t tpdu_lr = 0;
152 uint32_t i;
154 uint32_t Lc = (((uint32_t)(command[5]) << 8) | command[6]);
155 if(Lc < 256)
157 /* MAP APDU onto command TPDU */
158 memcpy(buffer, command, 4);
159 buffer[4] = (unsigned char) Lc;
160 memcpy(buffer + 5, command + 7, buffer[4]);
161 return Protocol_T0_ExchangeTPDU(reader, buffer, buffer[4] + 5, rsp, lr);
164 /* Prepare envelope TPDU */
165 buffer[0] = command[0];
166 buffer[1] = 0xC2;
167 buffer[2] = 0x00;
168 buffer[3] = 0x00;
170 for(i = 0; i < command_len; i += buffer[4])
172 /* Create envelope command TPDU */
173 buffer[4] = MIN(255, command_len - i);
174 memcpy(buffer + 5, command + i, buffer[4]);
175 call(Protocol_T0_ExchangeTPDU(reader, buffer, buffer[4] + 5, tpdu_rsp, &tpdu_lr));
176 /* Card does support envelope command */
177 if(tpdu_rsp[tpdu_lr - 2] == 0x90)
179 /* This is not the last segment */
180 if(buffer[4] + i < command_len)
181 { tpdu_lr = 0; }
182 else
184 memcpy(rsp, tpdu_rsp, tpdu_lr); // Map response TPDU onto APDU
185 *lr = tpdu_lr;
188 else /* Card does not support envelope command or error */
190 memcpy(rsp, tpdu_rsp, tpdu_lr); // Map response TPDU onto APDU
191 *lr = tpdu_lr;
192 break;
195 return OK;
199 static int32_t Protocol_T0_Case3E(struct s_reader *reader, unsigned char *command, unsigned char *rsp, uint16_t *lr)
201 int32_t ret;
202 unsigned char buffer[5];
203 unsigned char tpdu_rsp[CTA_RES_LEN];
204 uint16_t tpdu_lr = 0;
205 int32_t Lm, Lx;
207 uint32_t Le = ((((uint32_t)(command[5]) << 8) | command[6]) == 0 ? 65536 : (((uint32_t)(command[5]) << 8) | command[6]));
208 memcpy(buffer, command, 4);//Map APDU command onto TPDU
210 if(Le <= 256)
212 buffer[4] = (unsigned char)Le;
213 return Protocol_T0_ExchangeTPDU(reader, buffer, 5, rsp, lr); //this was Case3S !!!
216 /* Map APDU onto command TPDU */
217 buffer[4] = 0x00;
218 call(Protocol_T0_ExchangeTPDU(reader, buffer, 5 , tpdu_rsp, &tpdu_lr));
220 if(tpdu_rsp[tpdu_lr - 2] == 0x6C) /* Le not accepted, La indicated */
222 /* Map command APDU onto TPDU */
223 memcpy(buffer, command, 4);
224 buffer[4] = tpdu_rsp[tpdu_lr - 1];
226 /* Delete response TPDU */
227 tpdu_lr = 0;
229 return Protocol_T0_ExchangeTPDU(reader, buffer, 5, rsp, lr); //Reissue command
232 memcpy(rsp, tpdu_rsp, tpdu_lr);//Map response TPDU onto APDU without change , also for SW1 = 0x67
233 *lr = tpdu_lr;
234 ret = OK;
235 if(tpdu_rsp[tpdu_lr - 2] == 0x61) /* Command processed, Lx indicated */
237 Lx = (tpdu_rsp[tpdu_lr - 1] == 0x00) ? 256 : tpdu_rsp[tpdu_lr - 1];
238 Lm = Le - (*lr - 2);
240 /* Prepare Get Response TPDU */
241 buffer[0] = command[0];
242 buffer[1] = 0xC0;
243 buffer[2] = 0x00;
244 buffer[3] = 0x00;
246 while(Lm > 0)
248 buffer[4] = (unsigned char) MIN(Lm, Lx);
249 call(Protocol_T0_ExchangeTPDU(reader, buffer, 5, tpdu_rsp, &tpdu_lr));
251 /* Append response TPDU to APDU */
252 if((*lr + tpdu_lr) > CTA_RES_LEN)
254 rdr_log(reader, "TPDU Append error, new length %i exceeds max length %i", *lr + tpdu_lr, CTA_RES_LEN);
255 return ERROR;
257 memcpy(rsp + (*lr - 2), tpdu_rsp, tpdu_lr);
258 *lr += tpdu_lr;
260 /* Delete response TPDU */
261 tpdu_lr = 0;
263 Lm = Le - (*lr - 2);
264 }/* Lm == 0 */
266 return ret;
270 static int32_t Protocol_T0_Case4E(struct s_reader *reader, unsigned char *command, uint16_t command_len, unsigned char *rsp, uint16_t *lr)
272 int32_t ret;
273 unsigned char buffer[PROTOCOL_T0_MAX_SHORT_COMMAND];
274 unsigned char tpdu_rsp[CTA_RES_LEN];
275 memset(tpdu_rsp, 0, sizeof(tpdu_rsp));
276 uint16_t tpdu_lr = 0;
277 int32_t Le;
279 uint32_t Lc = (((uint32_t)(command[5]) << 8) | command[6]);
280 /* 4E1 */
281 if(Lc < 256)
283 /* Map APDU onto command TPDU */
284 memcpy(buffer, command, 4);
285 buffer[4] = (unsigned char) Lc;
286 memcpy(buffer + 5, command, buffer[4]);
287 ret = Protocol_T0_ExchangeTPDU(reader, buffer, buffer[4] + 5, tpdu_rsp, &tpdu_lr);
289 else /* 4E2 */
290 { ret = Protocol_T0_Case2E(reader, command, command_len, tpdu_rsp, &tpdu_lr); }
292 /* 4E1 a) b) and c) */
293 if(ret == OK)
295 Le = ((((uint32_t)(command[command_len - 2]) << 8) | command[command_len - 1]) == 0 ? 65536 : (((uint32_t)(command[command_len - 2]) << 8) | command[command_len - 1]));
296 if(tpdu_lr > 1 && tpdu_rsp[tpdu_lr - 2] == 0x61)
298 /* Lm == (Le - APDU_Rsp_RawLen (tpdu_rsp)) == 0 */
299 if(tpdu_rsp[tpdu_lr - 1] != 0x00)
300 { Le = MIN(tpdu_rsp[tpdu_lr - 1], Le); }
302 /* Delete response TPDU */
303 tpdu_lr = 0;
305 /* Prepare extended Get Response APDU command */
306 buffer[0] = command[0];
307 buffer[1] = 0xC0;
308 buffer[2] = 0x00;
309 buffer[3] = 0x00;
310 buffer[4] = 0x00; /* B1 = 0x00 */
311 buffer[5] = (unsigned char)(Le >> 8); /* B2 = BL-1 */
312 buffer[6] = (unsigned char)(Le & 0x00FF); /* B3 = BL */
313 ret = Protocol_T0_Case3E(reader, buffer, rsp, lr);
315 else if(tpdu_lr > 1 && (tpdu_rsp[tpdu_lr - 2] & 0xF0) == 0x60)
317 /* Map response TPDU onto APDU without change */
318 memcpy(rsp, tpdu_rsp, tpdu_lr);
319 *lr = tpdu_lr;
321 else
323 /* Delete response TPDU */
324 tpdu_lr = 0;
326 /* Prepare extended Get Response APDU command */
327 buffer[0] = command[0];
328 buffer[1] = 0xC0;
329 buffer[2] = 0x00;
330 buffer[3] = 0x00;
331 buffer[4] = 0x00; /* B1 = 0x00 */
332 buffer[5] = (unsigned char) Le >> 8; /* B2 = BL-1 */
333 buffer[6] = (unsigned char) Le & 0x00FF; /* B3 = BL */
334 ret = Protocol_T0_Case3E(reader, buffer, rsp, lr);
337 return ret;
341 static int32_t Protocol_T0_ExchangeTPDU(struct s_reader *reader, unsigned char *command, uint16_t command_len, unsigned char *rsp, uint16_t *lr)
343 unsigned char buffer[PROTOCOL_T0_MAX_SHORT_RESPONSE];
344 unsigned char *data;
345 int32_t Lc, Le, sent, recved, expectedlen;
346 int32_t nulls, cmd_case;
347 int32_t timeout;
348 *lr = 0; //in case of error this will be returned
350 cmd_case = APDU_Cmd_Case(command, command_len);
351 switch(cmd_case)
353 case APDU_CASE_2S:
354 Lc = command[4];
355 Le = 0;
356 expectedlen = 1;
357 data = command + 5;
358 break;
359 case APDU_CASE_3S:
360 Lc = 0;
361 Le = command[4];
362 if(!Le)
363 { expectedlen = 2; }
364 else
365 { expectedlen = 1 + Le + 2; }
366 data = NULL;
367 break;
368 default:
369 rdr_log_dbg(reader, D_TRACE, "ERROR: invalid cmd_case = %i in Protocol_T0_ExchangeTPDU", cmd_case);
370 return ERROR;
372 timeout = ICC_Async_GetTimings(reader, reader->char_delay); // we are going to send: char delay timeout
373 if(ICC_Async_Transmit(reader, 5, expectedlen, command, 0, timeout) != OK) { return ERROR; } //Send header bytes
375 /* Initialise counters */
376 nulls = 0;
377 sent = 0;
378 recved = 0;
381 * Let's be a bit paranoid with buffer sizes within this loop
382 * so it doesn't overflow reception and transmission buffers
383 * if card does not strictly respect the protocol
386 while(recved < PROTOCOL_T0_MAX_SHORT_RESPONSE)
388 timeout = ICC_Async_GetTimings(reader, reader->read_timeout); // we are going to receive: WWT timeout
389 if(ICC_Async_Receive(reader, 1, buffer + recved, 0, timeout) != OK) { return ERROR; } //Read one procedure byte
391 /* NULL byte received */
392 if(buffer[recved] == 0x60)
394 nulls++;
395 if(nulls >= PROTOCOL_T0_MAX_NULLS) //Maximum number of nulls reached
397 rdr_log_dbg(reader, D_TRACE, "ERROR: %s: Maximum number of nulls reached: %d", __func__, nulls);
398 return ERROR;
401 else if((buffer[recved] & 0xF0) == 0x60 || (buffer[recved] & 0xF0) == 0x90) /* SW1 byte received */
403 rdr_log_dbg(reader, D_TRACE, "SW1: %02X", buffer[recved] & 0xf0);
404 recved++;
405 if(recved >= PROTOCOL_T0_MAX_SHORT_RESPONSE)
407 rdr_log_dbg(reader, D_TRACE, "ERROR: %s: Maximum short response exceeded: %d", __func__, recved);
408 return ERROR;
410 timeout = ICC_Async_GetTimings(reader, reader->read_timeout); // we are going to receive: WWT timeout
411 if(ICC_Async_Receive(reader, 1, buffer + recved, 0, timeout) != OK) { return ERROR; } //Read SW2 byte
412 rdr_log_dbg(reader, D_TRACE, "SW2: %02X", buffer[recved] & 0xf0);
413 recved++;
414 break;
416 else if((buffer[recved] & 0x0E) == (command[1] & 0x0E)) /* ACK byte received */
418 //printf("ack\n");
419 /* Reset null's counter */
420 nulls = 0;
422 /* Case 2 command: send data */
423 if(cmd_case == APDU_CASE_2S)
425 if(sent >= Lc)
427 rdr_log_dbg(reader, D_TRACE, "ERROR: %s: ACK byte: sent=%d exceeds Lc=%d", __func__, sent, Lc);
428 return ERROR;
430 timeout = ICC_Async_GetTimings(reader, reader->char_delay); // we are going to send: char delay timeout
431 if(ICC_Async_Transmit(reader, MAX(Lc - sent, 0), 2, data + sent, 0, timeout) != OK) { return ERROR; } /* Send remaining data bytes */
432 sent = Lc;
433 continue;
435 else /* Case 3 command: receive data */
437 if(recved > PROTOCOL_T0_MAX_SHORT_RESPONSE)
439 rdr_log_dbg(reader, D_TRACE, "ERROR: %s: Case 3 ACK - maximum short response exceeded: %d", __func__, recved);
440 return ERROR;
444 * Le <= PROTOCOL_T0_MAX_SHORT_RESPONSE - 2 for short commands
447 /* Read remaining data bytes */
448 timeout = ICC_Async_GetTimings(reader, reader->read_timeout); // we are going to receive: WWT timeout
449 if(ICC_Async_Receive(reader, MAX(Le - recved, 0), buffer + recved, 0, timeout) != OK) { return ERROR; }
450 recved = Le;
451 continue;
454 else if((buffer[recved] & 0x0E) == ((~command[1]) & 0x0E)) /* ~ACK byte received */
456 //printf("~ack\n");
457 nulls = 0; //Reset null's counter
459 /* Case 2 command: send data */
460 if(cmd_case == APDU_CASE_2S)
462 if(sent >= Lc)
464 rdr_log_dbg(reader, D_TRACE, "ERROR: %s: ~ACK byte: sent=%d exceeds Lc=%d", __func__, sent, Lc);
465 return ERROR;
467 timeout = ICC_Async_GetTimings(reader, reader->char_delay); // we are going to send: char delay timeout
468 if(ICC_Async_Transmit(reader, 1, 1, data + sent, 0, timeout) != OK) { return ERROR; } //Send next data byte
469 sent++;
470 continue;
472 else /* Case 3 command: receive data */
474 if(recved > PROTOCOL_T0_MAX_SHORT_RESPONSE)
476 rdr_log_dbg(reader, D_TRACE, "ERROR: %s: Case 3 ~ACK - maximum short response exceeded: %d", __func__, recved);
477 return ERROR;
479 timeout = ICC_Async_GetTimings(reader, reader->read_timeout); // we are going to receive: WWT timeout
480 if(ICC_Async_Receive(reader, 1, buffer + recved, 0, timeout) != OK) { return ERROR; } //Read next data byte
481 recved++;
482 continue;
485 else /* Anything else received */
487 rdr_log_dbg(reader, D_TRACE, "ERROR: %s: Received unexpected character: %02X", __func__, buffer[recved]);
488 return ERROR;
490 }//while
492 memcpy(rsp, buffer, recved);
493 *lr = recved;
494 return OK;
497 int32_t Protocol_T14_ExchangeTPDU(struct s_reader *reader, unsigned char *cmd_raw, uint16_t command_len, unsigned char *rsp, uint16_t *lr)
499 unsigned char buffer[PROTOCOL_T14_MAX_SHORT_RESPONSE];
500 int32_t recved;
501 int32_t cmd_case;
502 int32_t timeout;
503 unsigned char ixor = 0x3E;
504 unsigned char ixor1 = 0x3F;
505 int32_t i;
506 int32_t cmd_len = (int32_t) command_len;
507 *lr = 0; //in case of error this is returned
509 /* Parse APDU */
510 cmd_case = APDU_Cmd_Case(cmd_raw, cmd_len);
511 for(i = 0; i < cmd_len; i++)
512 { ixor ^= cmd_raw[i]; }
514 /* Check case of command */
515 if((cmd_case != APDU_CASE_2S) && (cmd_case != APDU_CASE_3S))
517 rdr_log_dbg(reader, D_TRACE, "ERROR: invalid cmd_case = %i in Protocol_T14_ExchangeTPDU", cmd_case);
518 return ERROR;
521 buffer[0] = 0x01; //send 0x01 byte
522 memcpy(buffer + 1, cmd_raw, cmd_len); // apdu
523 buffer[cmd_len + 1] = ixor; // xor byte
525 /* Send apdu */
526 timeout = ICC_Async_GetTimings(reader, reader->char_delay); // we are going to send: char delay timeout
527 if(ICC_Async_Transmit(reader, cmd_len + 2, 0, buffer, 0, timeout) != OK) { return ERROR; } //send apdu
528 if(cmd_raw[0] == 0x02 && cmd_raw[1] == 0x09) { cs_sleepms(2500); } //FIXME why wait? -> needed for init on overclocked T14 cards
530 timeout = ICC_Async_GetTimings(reader, reader->read_timeout); // we are going to receive: WWT timeout
531 // if ((reader->typ == R_SMART) && (reader->smart_type >= 2)) timeout *= 1.1;
532 if(ICC_Async_Receive(reader, 8, buffer, 0, timeout) != OK) { return ERROR; } //Read one procedure byte
533 recved = (int32_t)buffer[7];
534 if(recved)
536 timeout = ICC_Async_GetTimings(reader, reader->read_timeout); // we are going to receive: WWT timeout
537 // if ((reader->typ == R_SMART) && (reader->smart_type >= 2)) timeout *= 1.1;
538 if(ICC_Async_Receive(reader, recved, buffer + 8, 0 , timeout) != OK) {return ERROR; }
540 timeout = ICC_Async_GetTimings(reader, reader->read_timeout); // we are going to receive: WWT timeout
541 // if ((reader->typ == R_SMART) && (reader->smart_type >= 2)) timeout *= 1.1;
542 if(ICC_Async_Receive(reader, 1, &ixor, 0, timeout) != OK) {return ERROR; }
543 for(i = 0; i < 8 + recved; i++)
544 { ixor1 ^= buffer[i]; }
545 if(ixor1 != ixor)
547 rdr_log_dbg(reader, D_TRACE, "ERROR: invalid checksum = %02X expected %02X", ixor1, ixor);
548 return ERROR;
550 memcpy(buffer + 8 + recved, buffer + 2, 2);
551 *lr = recved + 2;
552 memcpy(rsp, buffer + 8, *lr);
553 return OK;
555 #endif