1 /* $Id: scT1.c,v 1.5 2001/07/20 15:51:45 rees Exp $ */
2
3 /*
4 copyright 1997, 1999, 2000
5 the regents of the university of michigan
6 all rights reserved
7
8 permission is granted to use, copy, create derivative works
9 and redistribute this software and such derivative works
10 for any purpose, so long as the name of the university of
11 michigan is not used in any advertising or publicity
12 pertaining to the use or distribution of this software
13 without specific, written prior authorization. if the
14 above copyright notice or any other identification of the
15 university of michigan is included in any copy of any
16 portion of this software, then the disclaimer below must
17 also be included.
18
19 this software is provided as is, without representation
20 from the university of michigan as to its fitness for any
21 purpose, and without warranty by the university of
22 michigan of any kind, either express or implied, including
23 without limitation the implied warranties of
24 merchantability and fitness for a particular purpose. the
25 regents of the university of michigan shall not be liable
26 for any damages, including special, indirect, incidental, or
27 consequential damages, with respect to any claim arising
28 out of or in connection with the use of the software, even
29 if it has been or is hereafter advised of the possibility of
30 such damages.
31 */
32
33 /*
34 * T=1 protocol engine
35 *
36 * Jim Rees, University of Michigan, October 1997
37 */
38
39 #ifdef __palmos__
40 #include <Common.h>
41 #include <System/SysAll.h>
42 #include <System/MemoryMgr.h>
43 #include <System/Unix/unix_stdlib.h>
44 #include <System/Unix/sys_socket.h>
45 #else
46 #include <stdio.h>
47 #endif
48 #include <string.h>
49 #ifdef TIMING
50 #include <sys/time.h>
51 #endif
52
53 #include "sectok.h"
54 #include "sc7816.h"
55
56 #ifdef __palmos__
57 #undef printf
58 #undef sprintf
59 #define printf palmprintf
60 #endif
61
62 int
scioT1(int ttyn,int cla,int ins,int p1,int p2,int ilen,unsigned char * ibuf,int olen,unsigned char * obuf,int * sw1p,int * sw2p)63 scioT1(int ttyn, int cla, int ins, int p1, int p2, int ilen, unsigned char *ibuf, int olen, unsigned char *obuf, int *sw1p, int *sw2p)
64 {
65 int i, len, n;
66 unsigned char *bp, *obp, tbuf[256];
67
68 /* Send 3 bytes prologue (7816-3 sec 9.4.1 fig 16) */
69
70 bp = tbuf;
71 len = 5 + ilen;
72
73 /* Send APDU */
74
75 *bp++ = cla;
76 *bp++ = ins;
77 *bp++ = p1;
78 *bp++ = p2;
79 *bp++ = ilen;
80
81 /* Send data */
82
83 for (i = 0; i < ilen; i++)
84 *bp++ = ibuf[i];
85 #ifndef HUH
86 if (ilen) {
87 /* I don't understand this, but Visa card wants it */
88 *bp++ = 0;
89 len++;
90 }
91 #endif
92
93 obp = obuf ? obuf : tbuf;
94
95 n = scioT1Iblk(ttyn, len, tbuf, obp);
96
97 if (n >= 2) {
98 *sw1p = obp[n-2];
99 *sw2p = obp[n-1];
100 n -= 2;
101 }
102 return n;
103 }
104
105 int
scioT1Iblk(int ttyn,int ilen,unsigned char * ibuf,unsigned char * obuf)106 scioT1Iblk(int ttyn, int ilen, unsigned char *ibuf, unsigned char *obuf)
107 {
108 int n;
109 unsigned char tbuf[256];
110 static unsigned char ssn;
111
112 tbuf[0] = 0;
113 tbuf[1] = ssn;
114 ssn ^= 0x40;
115 tbuf[2] = ilen;
116 memcpy(&tbuf[3], ibuf, ilen);
117 n = scioT1pkt(ttyn, tbuf, tbuf);
118 if (n < 0)
119 return n;
120 memcpy(obuf, &tbuf[3], tbuf[2]);
121 return tbuf[2];
122 }
123
124 int
scioT1pkt(int ttyn,unsigned char * ibuf,unsigned char * obuf)125 scioT1pkt(int ttyn, unsigned char *ibuf, unsigned char *obuf)
126 {
127 int i, len;
128 unsigned char edc, *bp;
129
130 len = ibuf[2] + 3;
131
132 /* Calculate checksum */
133
134 for (i = 0, edc = 0; i < len; i++)
135 edc ^= ibuf[i];
136 ibuf[len++] = edc;
137
138 /* Wait BGT = 22 etu */
139
140 scsleep(scparam[ttyn].etu * 22 / 1000 + 1);
141
142 /* Send the packet */
143
144 scputblk(ttyn, ibuf, len);
145
146 /* Read return packet */
147
148 bp = obuf;
149
150 /* Read three byte header */
151 for (i = 0; i < 3; i++) {
152 if (scgetc(ttyn, bp++, (i == 0) ? scparam[ttyn].bwt : scparam[ttyn].cwt) != SCEOK) {
153 #ifdef DEBUG
154 printf("T=1 header read timeout\n");
155 #endif
156 return -1;
157 }
158 }
159 len = obuf[2];
160
161 /* Read data and edc */
162 for (i = 0; i < len + 1; i++) {
163 if (scgetc(ttyn, bp++, scparam[ttyn].cwt) != SCEOK) {
164 #ifdef DEBUG
165 printf("T=1 data read timeout\n");
166 #endif
167 return -1;
168 }
169 }
170
171 /* Check edc */
172 for (i = 0, edc = 0; i < len + 3; i++)
173 edc ^= obuf[i];
174 #ifdef DEBUG
175 if (edc != obuf[len + 3])
176 printf("edc mismatch, %02x != %02x\n", edc, obuf[len + 3]);
177 #endif
178
179 return len;
180 }
181