[Pcsclite-muscle] Bug in CCID library

Abraham Macias Paredes amacias at solutia-it.es
Wed Oct 5 06:44:05 UTC 2016


Hi everybody,

I found a bug in CCID library. 

 

In “src/ifdhandler.c” inside “IFDHSetProtocolParameters” function, the speed
in bauds of the serial communication is set. But to set this speed, the
maximum speed of the card must be lower than the máximum speed of the
reader, or the reader must define an “arrayOfSupportedDataRates”.

 

So, the problem is that my card is too fast for the reader (card baud rate
is 250000) and my reader has no “arrayOfSupportedDataRates”:

 

$ lsusb -v | grep DataRate

        dwDataRate           9600 bps

        dwMaxDataRate      230400 bps

        bNumDataRatesSupp.      0

 

That means that CCID set the speed in bauds to the default speed. That is
simply TOO SLOW.

 

I pathed this in my Linux by adding the following code:

 

 

         /* TA1 present */

         if (atr.ib[0][ATR_INTERFACE_BYTE_TA].present)

         {

              unsigned int card_baudrate;

              unsigned int default_baudrate;

              double f, d;

 

              (void)ATR_GetParameter(&atr, ATR_PARAMETER_D, &d);

              (void)ATR_GetParameter(&atr, ATR_PARAMETER_F, &f);

 

              /* may happen with non ISO cards */

              if ((0 == f) || (0 == d))

              {

                   /* values for TA1=11 */

                   f = 372;

                   d = 1;

              }

 

              /* Baudrate = f x D/F */

              card_baudrate = (unsigned int) (1000 *
ccid_desc->dwDefaultClock

                   * d / f);

 

              default_baudrate = (unsigned int) (1000 *
ccid_desc->dwDefaultClock

                   * ATR_DEFAULT_D / ATR_DEFAULT_F);

 

DEBUG_INFO3("card_baudrate = %i default_baudrate = %i", card_baudrate,
default_baudrate);

 

              /* if the card does not try to lower the default speed */

              if ((card_baudrate > default_baudrate)

                   /* and the reader is fast enough */

                   && (card_baudrate <= ccid_desc->dwMaxDataRate))

              {

                   /* the reader has no baud rates table */

                   if ((NULL == ccid_desc->arrayOfSupportedDataRates)

                        /* or explicitely support it */

                        || find_baud_rate(card_baudrate,

                            ccid_desc->arrayOfSupportedDataRates))

                   {

                        pps[1] |= 0x10; /* PTS1 presence */

                        pps[2] = atr.ib[0][ATR_INTERFACE_BYTE_TA].value;

 

                        DEBUG_COMM2("Set speed to %d bauds", card_baudrate);

                   }

                   else

                   {

                        DEBUG_COMM2("Reader does not support %d bauds",

                            card_baudrate);

 

                        /* TA2 present -> specific mode: the card is
supporting

                        * only the baud rate specified in TA1 but reader
does not

                        * support this value. Reject the card. */

                        if (atr.ib[1][ATR_INTERFACE_BYTE_TA].present)

                            return IFD_COMMUNICATION_ERROR;

                   }

              }

              else

              {

                   /* the card is too fast for the reader */

                   if ((card_baudrate > ccid_desc->dwMaxDataRate +2)

                        /* but TA1 <= 97 */

                        && (atr.ib[0][ATR_INTERFACE_BYTE_TA].value <= 0x97)

                        /* and the reader has a baud rate table */

                        && ccid_desc->arrayOfSupportedDataRates)

                   {

                        unsigned char old_TA1;

 

                        old_TA1 = atr.ib[0][ATR_INTERFACE_BYTE_TA].value;

                        while (atr.ib[0][ATR_INTERFACE_BYTE_TA].value >
0x94)

                        {

                            /* use a lower TA1 */

                            atr.ib[0][ATR_INTERFACE_BYTE_TA].value--;

 

                            (void)ATR_GetParameter(&atr, ATR_PARAMETER_D,
&d);

                            (void)ATR_GetParameter(&atr, ATR_PARAMETER_F,
&f);

 

                            /* Baudrate = f x D/F */

                            card_baudrate = (unsigned int) (1000 *

                                 ccid_desc->dwDefaultClock * d / f);

 

                            if (find_baud_rate(card_baudrate,

                                 ccid_desc->arrayOfSupportedDataRates))

                            {

                                 pps[1] |= 0x10; /* PTS1 presence */

                                 pps[2] =
atr.ib[0][ATR_INTERFACE_BYTE_TA].value;

 

                                 DEBUG_COMM2("Set adapted speed to %d
bauds",

                                      card_baudrate);

 

                                 break;

                            }

                        }

 

                        /* restore original TA1 value */

                        atr.ib[0][ATR_INTERFACE_BYTE_TA].value = old_TA1;

                   }

                   /* ================================ ADDED CODE -  BEGIN
================================ */

                   else if ((card_baudrate > ccid_desc->dwMaxDataRate +2)

                        /* but TA1 <= 97 */

                        && (atr.ib[0][ATR_INTERFACE_BYTE_TA].value <= 0x97)

                        /* and the reader hasn't a baud rate table */

                        && !ccid_desc->arrayOfSupportedDataRates)

                   {

                        unsigned char old_TA1;

 

                        old_TA1 = atr.ib[0][ATR_INTERFACE_BYTE_TA].value;

                        while (atr.ib[0][ATR_INTERFACE_BYTE_TA].value >
0x94)

                        {

                            /* use a lower TA1 */

                            atr.ib[0][ATR_INTERFACE_BYTE_TA].value--;

 

                            (void)ATR_GetParameter(&atr, ATR_PARAMETER_D,
&d);

                             (void)ATR_GetParameter(&atr, ATR_PARAMETER_F,
&f);

 

                            /* Baudrate = f x D/F */

                            card_baudrate = (unsigned int) (1000 *

                                 ccid_desc->dwDefaultClock * d / f);

 

                            /* if the card does not try to lower the default
speed */

                            if ((card_baudrate > default_baudrate)

                                 /* and the reader is fast enough */

                                 && (card_baudrate <=
ccid_desc->dwMaxDataRate))

                            {

 

                                 pps[1] |= 0x10; /* PTS1 presence */

                                 pps[2] =
atr.ib[0][ATR_INTERFACE_BYTE_TA].value;

         

                                 DEBUG_COMM2("Set speed to %d bauds",
card_baudrate);

                                 break;

                            }

                        }

 

                        /* restore original TA1 value */

                        atr.ib[0][ATR_INTERFACE_BYTE_TA].value = old_TA1;


                        

                   }

                   /* ================================ ADDED CODE -  END
================================ */

              }

         }

 

But this sets the speed to 125000 bauds. How can I set the speed to 230400
bps (the reader maximum data rate)?

 

Thank you and best regards!

 

 


Abraham Macías Paredes


Analista / Programador


Departamento de Desarrollo y Soluciones 


amacias at solutia-it.es <mailto:amacias at solutia-it.es> 


 




 <http://solutia-it.es/> 



	
Solutia Innovaworld Technologies S.L.
Parque empresarial Los Llanos
C/ Extremadura, 108 - 41909 - Salteras (Sevilla)
T: +34 955 11 11 55
F: +34 954 37 11 42
 <http://www.solutia-it.es> www.solutia-it.es

	
 <http://solutia-it.es/calidad/> 


Sus datos personales contenidos en esta comunicación han sido recogidos de
los contactos mantenidos por Vd. o por personas de su entorno, con personal
de SOLUTIA INNOVAWORLD TECHNOLOGIES, S.L. y han sido incorporados al fichero
de GESTIÓN COMERCIAL con la finalidad de realizar la gestión, seguimiento y
mantenimiento de nuestra relación comercial, o a otro fichero
correspondiente al tipo de relación que mantiene con nosotros, de lo que Vd.
fue convenientemente informado al recibir bien el documento contractual
entregado al inicio de los contactos bien en una comunicación inmediatamente
posterior en que se daba cumplimiento al derecho de información y se le
solicitaba consentimiento para tratar sus datos personales, tratamiento que
se efectuará de acuerdo a las finalidades allí expresadas.

En el caso en que ésta sea la primera comunicación que recibe por nuestra
parte, le solicitamos su consentimiento para proceder al tratamiento de sus
datos de acuerdo a las condiciones detalladas al inicio. Entenderemos que
nos presta su consentimiento si en el plazo de un mes a contar desde la
recepción de esta comunicación no nos expresa su voluntad en contra. Le
informamos que puede revocar en cualquier momento su consentimiento
respondiendo a este mail indicando que no desea recibir más información
acerca de nuestra empresa, supuesto en el que será automáticamente dado de
baja de nuestra lista de correo.

Podrá ejercer sus derechos de acceso, rectificación, cancelación y oposición
ante el Responsable del fichero, SOLUTIA INNOVAWORLD TECHNOLOGIES, S.L. en
la dirección C/ Extremadura, 108 Parque empresarial Los Llanos; 41909
Salteras, SEVILLA, indicando en la comunicación la referencia "LOPD"

				

 

 

 

 

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.alioth.debian.org/pipermail/pcsclite-muscle/attachments/20161005/164635f2/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image001.gif
Type: image/gif
Size: 1443 bytes
Desc: not available
URL: <http://lists.alioth.debian.org/pipermail/pcsclite-muscle/attachments/20161005/164635f2/attachment-0003.gif>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image002.gif
Type: image/gif
Size: 3498 bytes
Desc: not available
URL: <http://lists.alioth.debian.org/pipermail/pcsclite-muscle/attachments/20161005/164635f2/attachment-0004.gif>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image003.gif
Type: image/gif
Size: 13916 bytes
Desc: not available
URL: <http://lists.alioth.debian.org/pipermail/pcsclite-muscle/attachments/20161005/164635f2/attachment-0005.gif>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image004.jpg
Type: image/jpeg
Size: 9470 bytes
Desc: not available
URL: <http://lists.alioth.debian.org/pipermail/pcsclite-muscle/attachments/20161005/164635f2/attachment-0001.jpg>


More information about the Pcsclite-muscle mailing list