Changeset 826


Ignore:
Timestamp:
04/18/06 14:38:32 (6 years ago)
Author:
aj
Message:

improvements by Chaskiel Grundman to add support for more eutron
versions.

Location:
trunk/src/ifd
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/ifd/atr.c

    r818 r826  
    156156        return 0; 
    157157} 
     158 
     159int 
     160ifd_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  
    2727        extern int ifd_verify_pts(ifd_atr_info_t *, int, 
    2828                                  const unsigned char *, size_t); 
     29        extern int ifd_pts_complete(const unsigned char *pts, size_t len); 
    2930 
    3031#ifdef __cplusplus 
  • trunk/src/ifd/ifd-eutron.c

    r775 r826  
    44 * Copyright (C) 2003, Andreas Jellinghaus <aj@dungeon.inka.de> 
    55 * Copyright (C) 2003, Olaf Kirch <okir@suse.de> 
     6 * Copyright 2006, Chaskiel Grundman <cg2v@andrew.cmu.edu> 
    67 */ 
    78 
    89#include "internal.h" 
     10#include "atr.h" 
     11#include "usb-descriptors.h" 
    912#include <stdlib.h> 
    1013#include <string.h> 
    1114#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 
     25typedef struct eut_priv { 
     26        unsigned char readbuffer[500]; 
     27        int head; 
     28        int tail; 
     29} eut_priv_t; 
    1330/* 
    1431 * Initialize the device 
     
    1734{ 
    1835        ifd_device_t *dev; 
    19  
    20         reader->name = "Eutron CryptoIdendity IT-SEC"; 
     36        eut_priv_t *priv; 
     37 
     38        reader->name = "Eutron CryptoIdendity"; 
    2139        reader->nslots = 1; 
    2240        if (!(dev = ifd_device_open(device_name))) 
     
    2846        } 
    2947 
     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 
    3056        reader->device = dev; 
    3157 
     
    6490        ifd_device_t *dev = reader->device; 
    6591        unsigned char buffer[IFD_MAX_ATR_LEN + 100]; 
    66         unsigned char cookie[] = { 0xff, 0x11, 0x98, 0x76 }; 
    6792        int rc, lr, c, atrlen; 
    6893 
    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) 
    7498                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; 
    75105 
    76106        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); 
    79109 
    80110                if (rc < 0) 
     
    97127        memcpy(atr, buffer, atrlen); 
    98128 
    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) != 0 
    121             || ifd_usb_control(dev, 0x41, 0xa0, 0, 0, NULL, 0, -1) != 0) 
    122                 goto failed; 
    123  
    124129        return atrlen; 
    125130 
     
    135140                       const unsigned char *buffer, size_t len) 
    136141{ 
    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); 
    139144} 
    140145 
     
    142147                       unsigned char *buffer, size_t len, long timeout) 
    143148{ 
    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; 
    150170                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); 
    155176 
    156177                if (rc < 0) 
    157178                        goto failed; 
    158                 lr += rc; 
    159  
    160                 if (lr >= 4 && lr >= buffer[2] + 4) 
     179                priv->head += rc; 
     180 
     181                if (priv->head >= len) 
    161182                        break; 
    162183                usleep(100000); 
    163184        } 
    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; 
    168194      failed: 
    169         ct_error("eutron: failed to receive t=1 frame"); 
     195        ct_error("eutron: receive failed"); 
    170196        return -1; 
     197} 
     198 
     199static 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; 
    171292} 
    172293 
     
    188309        eutron_driver.send = eutron_send; 
    189310        eutron_driver.recv = eutron_recv; 
     311        eutron_driver.set_protocol = eutron_set_protocol; 
    190312 
    191313        ifd_driver_register("eutron", &eutron_driver); 
  • trunk/src/ifd/internal.h

    r803 r826  
    199199extern unsigned int ifd_protocols_list(const char **, unsigned int); 
    200200 
     201/* proto-t1.c */ 
     202extern int t1_negotiate_ifsd(ifd_protocol_t *, unsigned int, int); 
     203 
    201204#endif                          /* IFD_INTERNAL_H */ 
  • trunk/src/ifd/proto-t1.c

    r774 r826  
    33 * 
    44 * Copyright (C) 2003, Olaf Kirch <okir@suse.de> 
     5 * 
     6 * improvements by: 
     7 * Copyright (C) 2004 Ludovic Rousseau <ludovic.rousseau@free.fr> 
    58 */ 
    69 
     
    577580        return n; 
    578581} 
     582 
     583int 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.