Changeset 826
- Timestamp:
- 04/18/06 14:38:32 (6 years ago)
- Location:
- trunk/src/ifd
- Files:
-
- 5 edited
-
atr.c (modified) (1 diff)
-
atr.h (modified) (1 diff)
-
ifd-eutron.c (modified) (8 diffs)
-
internal.h (modified) (1 diff)
-
proto-t1.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/ifd/atr.c
r818 r826 156 156 return 0; 157 157 } 158 159 int 160 ifd_pts_complete(const unsigned char *pts, size_t len) 161 { 162 unsigned int j=2; 163 164 if (j > len) 165 return 0; 166 j =+ ifd_count_bits(pts[1] & 0x70); 167 j++; 168 if (j > len) 169 return 0; 170 return 1; 171 } 172 -
trunk/src/ifd/atr.h
r818 r826 27 27 extern int ifd_verify_pts(ifd_atr_info_t *, int, 28 28 const unsigned char *, size_t); 29 extern int ifd_pts_complete(const unsigned char *pts, size_t len); 29 30 30 31 #ifdef __cplusplus -
trunk/src/ifd/ifd-eutron.c
r775 r826 4 4 * Copyright (C) 2003, Andreas Jellinghaus <aj@dungeon.inka.de> 5 5 * Copyright (C) 2003, Olaf Kirch <okir@suse.de> 6 * Copyright 2006, Chaskiel Grundman <cg2v@andrew.cmu.edu> 6 7 */ 7 8 8 9 #include "internal.h" 10 #include "atr.h" 11 #include "usb-descriptors.h" 9 12 #include <stdlib.h> 10 13 #include <string.h> 11 14 #include <unistd.h> 12 15 #include <errno.h> 16 17 #define EUTRON_OUT IFD_USB_ENDPOINT_OUT | IFD_USB_TYPE_VENDOR | IFD_USB_RECIP_ENDPOINT 18 #define EUTRON_IN IFD_USB_ENDPOINT_IN | IFD_USB_TYPE_VENDOR | IFD_USB_RECIP_ENDPOINT 19 20 #define EUTRON_CMD_WRITE 0x1 21 #define EUTRON_CMD_READ 0x2 22 #define EUTRON_CMD_ATR 0x9 23 #define EUTRON_CMD_SETPARAM 0x65 24 25 typedef struct eut_priv { 26 unsigned char readbuffer[500]; 27 int head; 28 int tail; 29 } eut_priv_t; 13 30 /* 14 31 * Initialize the device … … 17 34 { 18 35 ifd_device_t *dev; 19 20 reader->name = "Eutron CryptoIdendity IT-SEC"; 36 eut_priv_t *priv; 37 38 reader->name = "Eutron CryptoIdendity"; 21 39 reader->nslots = 1; 22 40 if (!(dev = ifd_device_open(device_name))) … … 28 46 } 29 47 48 priv = (eut_priv_t *) calloc(1, sizeof(eut_priv_t)); 49 if (!priv) { 50 ct_error("out of memory"); 51 return IFD_ERROR_NO_MEMORY; 52 } 53 54 reader->driver_data = priv; 55 30 56 reader->device = dev; 31 57 … … 64 90 ifd_device_t *dev = reader->device; 65 91 unsigned char buffer[IFD_MAX_ATR_LEN + 100]; 66 unsigned char cookie[] = { 0xff, 0x11, 0x98, 0x76 };67 92 int rc, lr, c, atrlen; 68 93 69 if (ifd_usb_control(dev, 0x41, 0xa3, 0, 0, NULL, 0, -1) != 0 70 || ifd_usb_control(dev, 0x41, 0xa1, 0, 0, NULL, 0, -1) != 0 71 || ifd_usb_control(dev, 0x41, 0xa2, 0, 0, NULL, 0, -1) != 0 72 || ifd_usb_control(dev, 0x41, 0xa0, 0, 0, NULL, 0, -1) != 0 73 || ifd_usb_control(dev, 0x41, 0x09, 0, 0, NULL, 0, -1) != 0) 94 if (ifd_usb_control(dev, EUTRON_OUT, 0xa3, 0, 0, NULL, 0, -1) != 0 95 || ifd_usb_control(dev, EUTRON_OUT, 0xa1, 0, 0, NULL, 0, -1) != 0 96 || ifd_usb_control(dev, EUTRON_OUT, 0xa2, 0, 0, NULL, 0, -1) != 0 97 || ifd_usb_control(dev, EUTRON_OUT, 0xa0, 0, 0, NULL, 0, -1) != 0) 74 98 goto failed; 99 /* flush any leftover buffered data */ 100 while (ifd_usb_control(dev, EUTRON_IN, EUTRON_CMD_READ, 0, 0, 101 buffer, IFD_MAX_ATR_LEN + 100, 1000) > 0) ; 102 if (ifd_usb_control(dev, EUTRON_OUT, EUTRON_CMD_ATR, 0, 0, NULL, 0, -1) 103 != 0) 104 goto failed; 75 105 76 106 for (lr = 0, c = 0; c < 20; c++) { 77 rc = ifd_usb_control(dev, 0xc1, 0x02, 0, 0,78 &buffer[lr], 100, 1000);107 rc = ifd_usb_control(dev, EUTRON_IN, EUTRON_CMD_READ, 0, 0, 108 &buffer[lr], IFD_MAX_ATR_LEN - lr, 1000); 79 109 80 110 if (rc < 0) … … 97 127 memcpy(atr, buffer, atrlen); 98 128 99 if (ifd_usb_control(dev, 0x41, 0x01, 0, 0,100 cookie, sizeof(cookie), 1000) != sizeof(cookie))101 goto failed;102 103 for (lr = 0, c = 0; c < 20; c++) {104 rc = ifd_usb_control(dev, 0xc1, 0x02, 0, 0,105 &buffer[lr], 100, 1000);106 107 if (rc < 0)108 goto failed;109 lr += rc;110 if (lr > IFD_MAX_ATR_LEN)111 goto failed;112 113 if (lr >= 4)114 break; /* heuristik: guess we got the full atr */115 usleep(100000);116 }117 if (c >= 20)118 goto failed;119 120 if (ifd_usb_control(dev, 0x41, 0x65, 0x98, 0, NULL, 0, -1) != 0121 || ifd_usb_control(dev, 0x41, 0xa0, 0, 0, NULL, 0, -1) != 0)122 goto failed;123 124 129 return atrlen; 125 130 … … 135 140 const unsigned char *buffer, size_t len) 136 141 { 137 return ifd_usb_control(reader->device, 0x42, 0x01, 0, 0,138 (void *)buffer, len, 1000);142 return ifd_usb_control(reader->device, EUTRON_OUT, EUTRON_CMD_WRITE, 0, 143 0, (void *)buffer, len, 1000); 139 144 } 140 145 … … 142 147 unsigned char *buffer, size_t len, long timeout) 143 148 { 144 int rc, lr, c, rbs; 145 146 for (lr = 0, c = 0; c < 200; c++) { 147 rbs = len - lr; 148 if (rbs > 100) 149 rbs = 100; 149 int rc, c, rbs; 150 eut_priv_t *priv = reader->driver_data; 151 152 ct_debug("eutron_recv: len=%d", len); 153 if (len <= priv->head - priv->tail) { 154 memcpy(buffer, priv->readbuffer + priv->tail, len); 155 priv->tail += len; 156 ct_debug("eutron_recv: returning buffered data, %d bytes left", 157 priv->head - priv->tail); 158 return len; 159 } 160 161 /* move the data to the beginning of the buffer, so there's a big 162 * contiguous chunk */ 163 memcpy(priv->readbuffer, &priv->readbuffer[priv->tail], 164 priv->head - priv->tail); 165 priv->head -= priv->tail; 166 /* since we set tail=0 here, the rest of the function can ignore it */ 167 priv->tail = 0; 168 for (c = 0; c < 20; c++) { 169 rbs = 499 - priv->head; 150 170 if (rbs == 0) 151 goto failed; 152 153 rc = ifd_usb_control(reader->device, 0xc1, 0x02, 0, 0, 154 &buffer[lr], rbs, timeout); 171 break; 172 173 rc = ifd_usb_control(reader->device, EUTRON_IN, EUTRON_CMD_READ, 174 0, 0, &priv->readbuffer[priv->head], rbs, 175 timeout); 155 176 156 177 if (rc < 0) 157 178 goto failed; 158 lr+= rc;159 160 if ( lr >= 4 && lr >= buffer[2] + 4)179 priv->head += rc; 180 181 if (priv->head >= len) 161 182 break; 162 183 usleep(100000); 163 184 } 164 if (c >= 200) 165 goto failed; 166 167 return lr; 185 if (len > priv->head) 186 len = priv->head; 187 memcpy(buffer, priv->readbuffer, len); 188 priv->tail += len; 189 if (priv->head - priv->tail) 190 ct_debug("eutron_recv: buffering %d bytes of data", 191 priv->head - priv->tail); 192 193 return len; 168 194 failed: 169 ct_error("eutron: failed to receive t=1 frame");195 ct_error("eutron: receive failed"); 170 196 return -1; 197 } 198 199 static int eutron_set_protocol(ifd_reader_t * reader, int nslot, int proto) 200 { 201 ifd_slot_t *slot; 202 ifd_atr_info_t atr_info; 203 unsigned char pts[7], ptsret[7]; 204 int ptslen, ptsrlen, r, c, speedparam; 205 206 slot = &reader->slot[nslot]; 207 if (proto != IFD_PROTOCOL_T0 && proto != IFD_PROTOCOL_T1) { 208 ct_error("%s: protocol not supported", reader->name); 209 return -1; 210 } 211 212 r = ifd_atr_parse(&atr_info, slot->atr, slot->atr_len); 213 if (r < 0) { 214 ct_error("%s: Bad ATR", reader->name); 215 return r; 216 } 217 218 /* if the card supports T=1, prefer it, even if 219 * it is not the default protocol */ 220 if (atr_info.supported_protocols & 0x2) { 221 proto = IFD_PROTOCOL_T1; 222 } 223 224 /* XXX disable baud change */ 225 atr_info.TA[0] = -1; 226 /* ITSEC-P does not respond correctly to request with PTS2 present */ 227 atr_info.TC[0] = -1; 228 229 ptslen = ifd_build_pts(&atr_info, proto, pts, 7); 230 if (ptslen < 0) { 231 return r; 232 } 233 if (eutron_send(reader, slot->dad, pts, ptslen) != ptslen) 234 return IFD_ERROR_COMM_ERROR; 235 236 for (ptsrlen = 0, c = 0; c < 20; c++) { 237 r = ifd_usb_control(reader->device, EUTRON_IN, EUTRON_CMD_READ, 238 0, 0, &ptsret[ptsrlen], 239 sizeof(ptsret) - ptsrlen, 1000); 240 241 if (r < 0) 242 return IFD_ERROR_COMM_ERROR; 243 ptsrlen += r; 244 if (ifd_pts_complete(ptsret, ptsrlen)) 245 break; 246 247 if (ptsrlen >= 7) 248 return IFD_ERROR_COMM_ERROR; 249 usleep(100000); 250 } 251 if (c >= 20) 252 return IFD_ERROR_TIMEOUT; 253 254 r = ifd_verify_pts(&atr_info, proto, ptsret, ptsrlen); 255 if (r < 0) { 256 ct_error("%s: Protocol selection failed", reader->name); 257 return r; 258 } 259 260 if (atr_info.TA[0] != -1) 261 speedparam = atr_info.TA[0]; 262 else 263 speedparam = 1; 264 if (ifd_usb_control 265 (reader->device, EUTRON_OUT, EUTRON_CMD_SETPARAM, speedparam, 0, 266 NULL, 0, -1) != 0 267 || ifd_usb_control(reader->device, EUTRON_OUT, 0xa1, 0, 0, NULL, 0, 268 -1) != 0 269 || ifd_usb_control(reader->device, EUTRON_OUT, 0xa0, 0, 0, NULL, 0, 270 -1) != 0) 271 return IFD_ERROR_COMM_ERROR; 272 273 slot->proto = ifd_protocol_new(proto, reader, slot->dad); 274 if (slot->proto == NULL) { 275 ct_error("%s: internal error", reader->name); 276 return -1; 277 } 278 /* device is not guaranteed to return whole frames */ 279 ifd_protocol_set_parameter(slot->proto, IFD_PROTOCOL_BLOCK_ORIENTED, 0); 280 /* Enable larger transfers */ 281 if (proto == IFD_PROTOCOL_T1 && atr_info.TA[2] != -1) { 282 ifd_protocol_set_parameter(slot->proto, IFD_PROTOCOL_T1_IFSC, 283 atr_info.TA[2]); 284 if (t1_negotiate_ifsd(slot->proto, slot->dad, atr_info.TA[2]) > 285 0) 286 ifd_protocol_set_parameter(slot->proto, 287 IFD_PROTOCOL_T1_IFSD, 288 atr_info.TA[2]); 289 290 } 291 return 0; 171 292 } 172 293 … … 188 309 eutron_driver.send = eutron_send; 189 310 eutron_driver.recv = eutron_recv; 311 eutron_driver.set_protocol = eutron_set_protocol; 190 312 191 313 ifd_driver_register("eutron", &eutron_driver); -
trunk/src/ifd/internal.h
r803 r826 199 199 extern unsigned int ifd_protocols_list(const char **, unsigned int); 200 200 201 /* proto-t1.c */ 202 extern int t1_negotiate_ifsd(ifd_protocol_t *, unsigned int, int); 203 201 204 #endif /* IFD_INTERNAL_H */ -
trunk/src/ifd/proto-t1.c
r774 r826 3 3 * 4 4 * Copyright (C) 2003, Olaf Kirch <okir@suse.de> 5 * 6 * improvements by: 7 * Copyright (C) 2004 Ludovic Rousseau <ludovic.rousseau@free.fr> 5 8 */ 6 9 … … 577 580 return n; 578 581 } 582 583 int t1_negotiate_ifsd(ifd_protocol_t * proto, unsigned int dad, int ifsd) 584 { 585 t1_state_t *t1 = (t1_state_t *) proto; 586 ct_buf_t sbuf; 587 unsigned char sdata[T1_BUFFER_SIZE]; 588 unsigned int slen; 589 unsigned int retries; 590 size_t snd_len; 591 int n; 592 unsigned char snd_buf[1], pcb; 593 594 retries = t1->retries; 595 596 /* S-block IFSD request */ 597 snd_buf[0] = ifsd; 598 snd_len = 1; 599 600 /* Initialize send/recv buffer */ 601 ct_buf_set(&sbuf, (void *)snd_buf, snd_len); 602 603 while (1) { 604 /* Build the block */ 605 slen = 606 t1_build(t1, sdata, dad, T1_S_BLOCK | T1_S_IFS, &sbuf, 607 NULL); 608 609 if ((n = t1_xcv(t1, sdata, slen, sizeof(sdata))) < 0) { 610 ifd_debug(1, "fatal: transmit/receive failed"); 611 t1->state = DEAD; 612 goto error; 613 } 614 615 if (!t1_verify_checksum(t1, sdata, n)) { 616 ifd_debug(1, "checksum failed"); 617 if (retries == 0) 618 goto error; 619 continue; 620 } 621 pcb = sdata[1]; 622 if (t1_block_type(pcb) == T1_S_BLOCK && 623 T1_S_TYPE(pcb) == T1_S_IFS && T1_S_IS_RESPONSE(pcb)) { 624 if (sdata[2] != 1 || sdata[3] != ifsd) 625 goto error; 626 break; 627 } 628 if (retries == 0) 629 goto error; 630 } 631 632 return n; 633 634 error: 635 t1_resynchronize(proto, dad); 636 return -1; 637 }
Note: See TracChangeset
for help on using the changeset viewer.
