--On Saturday, March 18, 2006 09:06:56 PM -0500 Chaskiel Grundman
<[EMAIL PROTECTED]> wrote:
If I decide to pick one of these devices up, I might try to fix the T=0
stuff, but the cost seems a bit high for experimentation.
I ended up purchasing a 'demo kit' from eutron that includes one of each of
their 5 cryptoidentity tokens. The price was much more reasonable than
buying individual tokens from Chirson (which was the only other source I
could easily find) The FIPS model was backordered, so I don't have that one
yet. In any event, I've learned some things today:
- the 0x65 parameter should match the PTS1 byte. this is what the windows
software does for all 4 tokens (ITSEC-I, ITSEC-P, 5, 2048) that I tested,
even the ones that are T=0 only.
- the ITSEC-P doesn't handle full pts correctly (it sends back a broken PTS
response if PTS2 is sent. the other cards' ATR's do not trigger the PTS2
logic)
- the ITSEC-I (cardos based) works with the ifd-eutron changes I made
earlier
I am unfortunately encountering frequent usb errors with the itsec-p and
5/2048. ifd_usb_control is failing with EOVERFLOW, which apparently means
that a usb condition known as 'babble' has been detected. I don't really
know what this means or if it's the fault of openct, linux, or the hardware
Two patches are attached. One is what I've been running for most of today.
it successfully resets and can do some communication with ITSEC-P/2048/5
devices.
The second implements Justin's suggestion that we just ignore TA(0) in the
ATR, not negotiate higher speed serial communication with PTS, and use 01
as the parameter when configuring the baud rate of the 'reader' (in the
0x65 request) This version seems to behave no worse with the ITSEC-P, and
does not seem to bother the ITSEC-I either. If it fixes the problems with
the FIPS model, it may be the right way to go
Index: src/ifd/atr.c
===================================================================
--- src/ifd/atr.c (revision 819)
+++ src/ifd/atr.c (working copy)
@@ -155,3 +155,18 @@
return IFD_ERROR_INCOMPATIBLE_DEVICE;
return 0;
}
+
+int
+ifd_pts_complete(const unsigned char *pts, size_t len)
+{
+ unsigned int j=2;
+
+ if (j > len)
+ return 0;
+ j =+ ifd_count_bits(pts[1] & 0x70);
+ j++;
+ if (j > len)
+ return 0;
+ return 1;
+}
+
Index: src/ifd/atr.h
===================================================================
--- src/ifd/atr.h (revision 819)
+++ src/ifd/atr.h (working copy)
@@ -26,6 +26,7 @@
size_t);
extern int ifd_verify_pts(ifd_atr_info_t *, int,
const unsigned char *, size_t);
+ extern int ifd_pts_complete(const unsigned char *pts, size_t len);
#ifdef __cplusplus
}
Index: src/ifd/ifd-eutron.c
===================================================================
--- src/ifd/ifd-eutron.c (revision 819)
+++ src/ifd/ifd-eutron.c (working copy)
@@ -6,18 +6,24 @@
*/
#include "internal.h"
+#include "atr.h"
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+
+typedef struct eut_priv {
+ int icc_proto;
+} eut_priv_t;
/*
* Initialize the device
*/
static int eutron_open(ifd_reader_t * reader, const char *device_name)
{
ifd_device_t *dev;
+ eut_priv_t *priv;
- reader->name = "Eutron CryptoIdendity IT-SEC";
+ reader->name = "Eutron CryptoIdendity";
reader->nslots = 1;
if (!(dev = ifd_device_open(device_name)))
return -1;
@@ -27,6 +33,14 @@
return -1;
}
+ priv = (eut_priv_t *) calloc(1, sizeof(eut_priv_t));
+ if (!priv) {
+ ct_error("out of memory");
+ return IFD_ERROR_NO_MEMORY;
+ }
+
+ reader->driver_data = priv;
+
reader->device = dev;
return 0;
@@ -63,7 +77,6 @@
{
ifd_device_t *dev = reader->device;
unsigned char buffer[IFD_MAX_ATR_LEN + 100];
- unsigned char cookie[] = { 0xff, 0x11, 0x98, 0x76 };
int rc, lr, c, atrlen;
if (ifd_usb_control(dev, 0x41, 0xa3, 0, 0, NULL, 0, -1) != 0
@@ -75,7 +88,7 @@
for (lr = 0, c = 0; c < 20; c++) {
rc = ifd_usb_control(dev, 0xc1, 0x02, 0, 0,
- &buffer[lr], 100, 1000);
+ &buffer[lr], IFD_MAX_ATR_LEN - lr, 1000);
if (rc < 0)
goto failed;
@@ -96,31 +109,6 @@
atrlen = lr;
memcpy(atr, buffer, atrlen);
- if (ifd_usb_control(dev, 0x41, 0x01, 0, 0,
- cookie, sizeof(cookie), 1000) != sizeof(cookie))
- goto failed;
-
- for (lr = 0, c = 0; c < 20; c++) {
- rc = ifd_usb_control(dev, 0xc1, 0x02, 0, 0,
- &buffer[lr], 100, 1000);
-
- if (rc < 0)
- goto failed;
- lr += rc;
- if (lr > IFD_MAX_ATR_LEN)
- goto failed;
-
- if (lr >= 4)
- break; /* heuristik: guess we got the full atr */
- usleep(100000);
- }
- if (c >= 20)
- goto failed;
-
- if (ifd_usb_control(dev, 0x41, 0x65, 0x98, 0, NULL, 0, -1) != 0
- || ifd_usb_control(dev, 0x41, 0xa0, 0, 0, NULL, 0, -1) != 0)
- goto failed;
-
return atrlen;
failed:
@@ -142,34 +130,121 @@
unsigned char *buffer, size_t len, long timeout)
{
int rc, lr, c, rbs;
+ eut_priv_t *priv = reader->driver_data;
+ int is_t1;
- for (lr = 0, c = 0; c < 200; c++) {
+ is_t1 = (priv->icc_proto == IFD_PROTOCOL_T1);
+
+ for (lr = 0, c = 0; c < is_t1 ? 200 : 20; c++) {
rbs = len - lr;
if (rbs > 100)
rbs = 100;
if (rbs == 0)
- goto failed;
+ break;
rc = ifd_usb_control(reader->device, 0xc1, 0x02, 0, 0,
- &buffer[lr], rbs, timeout);
+ &buffer[lr], rbs, timeout);
if (rc < 0)
goto failed;
lr += rc;
- if (lr >= 4 && lr >= buffer[2] + 4)
+ if (is_t1 && lr >= 4 && lr >= buffer[2] + 4)
break;
usleep(100000);
}
- if (c >= 200)
+ if (is_t1 && (c >= 200 || rbs == 0))
goto failed;
return lr;
failed:
- ct_error("eutron: failed to receive t=1 frame");
+ if (is_t1)
+ ct_error("eutron: failed to receive t=1 frame");
+ else
+ ct_error("eutron: receive failed");
return -1;
}
+static int
+eutron_set_protocol(ifd_reader_t *reader, int nslot, int proto)
+{
+ ifd_slot_t *slot;
+ ifd_atr_info_t atr_info;
+ unsigned char pts[7], ptsret[7];
+ int ptslen, ptsrlen, r, c ;
+ eut_priv_t *priv = reader->driver_data;
+
+ slot = &reader->slot[nslot];
+ if (proto != IFD_PROTOCOL_T0 && proto != IFD_PROTOCOL_T1) {
+ ct_error("%s: protocol not supported", reader->name);
+ return -1;
+ }
+
+ r = ifd_atr_parse(&atr_info, slot->atr, slot->atr_len);
+ if (r < 0) {
+ ct_error("%s: Bad ATR", reader->name);
+ return r;
+ }
+
+ /* if the card supports T=1, prefer it, even if
+ * it is not the default protocol */
+ if (atr_info.supported_protocols & 0x2) {
+ proto = IFD_PROTOCOL_T1;
+ }
+
+ /* ITSEC-P does not respond correctly to request with PTS2 present */
+ atr_info.TC[0] = -1;
+
+ ptslen = ifd_build_pts(&atr_info, proto, pts, 7);
+ if (ptslen < 0) {
+ return r;
+ }
+ if (eutron_send(reader, slot->dad, pts, ptslen) != ptslen)
+ return IFD_ERROR_COMM_ERROR;
+
+ for (ptsrlen=0,c=0;c < 20;c++) {
+ r = ifd_usb_control(reader->device, 0xc1, 0x02, 0, 0,
+ &ptsret[ptsrlen], sizeof(ptsret) - ptsrlen,
+ 1000);
+
+ if (r < 0)
+ return IFD_ERROR_COMM_ERROR;
+ ptsrlen+=r;
+ if (ifd_pts_complete(ptsret, ptsrlen))
+ break;
+
+ if (ptsrlen >= 7)
+ return IFD_ERROR_COMM_ERROR;
+ usleep(100000);
+ }
+ if (c >= 20)
+ return IFD_ERROR_TIMEOUT;
+
+ r = ifd_verify_pts(&atr_info, proto, ptsret, ptsrlen);
+ if (r < 0) {
+ ct_error("%s: Protocol selection failed", reader->name);
+ return r;
+ }
+
+ if (atr_info.TA[0] != -1
+ && (ifd_usb_control(reader->device, 0x41, 0x65, atr_info.TA[0],
+ 0, NULL, 0, -1) != 0
+ || ifd_usb_control(reader->device, 0x41, 0xa1, 0, 0, NULL,
+ 0, -1) != 0
+ || ifd_usb_control(reader->device, 0x41, 0xa0, 0, 0, NULL,
+ 0, -1) != 0))
+ return IFD_ERROR_COMM_ERROR;
+
+ slot->proto = ifd_protocol_new(proto, reader, slot->dad);
+ if (slot->proto == NULL) {
+ ct_error("%s: internal error", reader->name);
+ return -1;
+ }
+ priv->icc_proto = proto;
+ return 0;
+}
+
+
/*
* Driver operations
*/
@@ -187,6 +262,7 @@
eutron_driver.card_reset = eutron_card_reset;
eutron_driver.send = eutron_send;
eutron_driver.recv = eutron_recv;
+ eutron_driver.set_protocol = eutron_set_protocol;
ifd_driver_register("eutron", &eutron_driver);
}
Index: src/ifd/atr.c
===================================================================
--- src/ifd/atr.c (revision 819)
+++ src/ifd/atr.c (working copy)
@@ -155,3 +155,18 @@
return IFD_ERROR_INCOMPATIBLE_DEVICE;
return 0;
}
+
+int
+ifd_pts_complete(const unsigned char *pts, size_t len)
+{
+ unsigned int j=2;
+
+ if (j > len)
+ return 0;
+ j =+ ifd_count_bits(pts[1] & 0x70);
+ j++;
+ if (j > len)
+ return 0;
+ return 1;
+}
+
Index: src/ifd/atr.h
===================================================================
--- src/ifd/atr.h (revision 819)
+++ src/ifd/atr.h (working copy)
@@ -26,6 +26,7 @@
size_t);
extern int ifd_verify_pts(ifd_atr_info_t *, int,
const unsigned char *, size_t);
+ extern int ifd_pts_complete(const unsigned char *pts, size_t len);
#ifdef __cplusplus
}
Index: src/ifd/ifd-eutron.c
===================================================================
--- src/ifd/ifd-eutron.c (revision 819)
+++ src/ifd/ifd-eutron.c (working copy)
@@ -6,18 +6,24 @@
*/
#include "internal.h"
+#include "atr.h"
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+
+typedef struct eut_priv {
+ int icc_proto;
+} eut_priv_t;
/*
* Initialize the device
*/
static int eutron_open(ifd_reader_t * reader, const char *device_name)
{
ifd_device_t *dev;
+ eut_priv_t *priv;
- reader->name = "Eutron CryptoIdendity IT-SEC";
+ reader->name = "Eutron CryptoIdendity";
reader->nslots = 1;
if (!(dev = ifd_device_open(device_name)))
return -1;
@@ -27,6 +33,14 @@
return -1;
}
+ priv = (eut_priv_t *) calloc(1, sizeof(eut_priv_t));
+ if (!priv) {
+ ct_error("out of memory");
+ return IFD_ERROR_NO_MEMORY;
+ }
+
+ reader->driver_data = priv;
+
reader->device = dev;
return 0;
@@ -63,7 +77,6 @@
{
ifd_device_t *dev = reader->device;
unsigned char buffer[IFD_MAX_ATR_LEN + 100];
- unsigned char cookie[] = { 0xff, 0x11, 0x98, 0x76 };
int rc, lr, c, atrlen;
if (ifd_usb_control(dev, 0x41, 0xa3, 0, 0, NULL, 0, -1) != 0
@@ -75,7 +88,7 @@
for (lr = 0, c = 0; c < 20; c++) {
rc = ifd_usb_control(dev, 0xc1, 0x02, 0, 0,
- &buffer[lr], 100, 1000);
+ &buffer[lr], IFD_MAX_ATR_LEN - lr, 1000);
if (rc < 0)
goto failed;
@@ -96,31 +109,6 @@
atrlen = lr;
memcpy(atr, buffer, atrlen);
- if (ifd_usb_control(dev, 0x41, 0x01, 0, 0,
- cookie, sizeof(cookie), 1000) != sizeof(cookie))
- goto failed;
-
- for (lr = 0, c = 0; c < 20; c++) {
- rc = ifd_usb_control(dev, 0xc1, 0x02, 0, 0,
- &buffer[lr], 100, 1000);
-
- if (rc < 0)
- goto failed;
- lr += rc;
- if (lr > IFD_MAX_ATR_LEN)
- goto failed;
-
- if (lr >= 4)
- break; /* heuristik: guess we got the full atr */
- usleep(100000);
- }
- if (c >= 20)
- goto failed;
-
- if (ifd_usb_control(dev, 0x41, 0x65, 0x98, 0, NULL, 0, -1) != 0
- || ifd_usb_control(dev, 0x41, 0xa0, 0, 0, NULL, 0, -1) != 0)
- goto failed;
-
return atrlen;
failed:
@@ -142,34 +130,126 @@
unsigned char *buffer, size_t len, long timeout)
{
int rc, lr, c, rbs;
+ eut_priv_t *priv = reader->driver_data;
+ int is_t1;
- for (lr = 0, c = 0; c < 200; c++) {
+ is_t1 = (priv->icc_proto == IFD_PROTOCOL_T1);
+
+ for (lr = 0, c = 0; c < is_t1 ? 200 : 20; c++) {
rbs = len - lr;
if (rbs > 100)
rbs = 100;
if (rbs == 0)
- goto failed;
+ break;
rc = ifd_usb_control(reader->device, 0xc1, 0x02, 0, 0,
- &buffer[lr], rbs, timeout);
+ &buffer[lr], rbs, timeout);
if (rc < 0)
goto failed;
lr += rc;
- if (lr >= 4 && lr >= buffer[2] + 4)
+ if (is_t1 && lr >= 4 && lr >= buffer[2] + 4)
break;
usleep(100000);
}
- if (c >= 200)
+ if (is_t1 && (c >= 200 || rbs == 0))
goto failed;
return lr;
failed:
- ct_error("eutron: failed to receive t=1 frame");
+ if (is_t1)
+ ct_error("eutron: failed to receive t=1 frame");
+ else
+ ct_error("eutron: receive failed");
return -1;
}
+static int
+eutron_set_protocol(ifd_reader_t *reader, int nslot, int proto)
+{
+ ifd_slot_t *slot;
+ ifd_atr_info_t atr_info;
+ unsigned char pts[7], ptsret[7];
+ int ptslen, ptsrlen, r, c, speedparam;
+ eut_priv_t *priv = reader->driver_data;
+
+ slot = &reader->slot[nslot];
+ if (proto != IFD_PROTOCOL_T0 && proto != IFD_PROTOCOL_T1) {
+ ct_error("%s: protocol not supported", reader->name);
+ return -1;
+ }
+
+ r = ifd_atr_parse(&atr_info, slot->atr, slot->atr_len);
+ if (r < 0) {
+ ct_error("%s: Bad ATR", reader->name);
+ return r;
+ }
+
+ /* if the card supports T=1, prefer it, even if
+ * it is not the default protocol */
+ if (atr_info.supported_protocols & 0x2) {
+ proto = IFD_PROTOCOL_T1;
+ }
+
+ /* disable baud change */
+ atr_info.TA[0] = -1;
+ /* ITSEC-P does not respond correctly to request with PTS2 present */
+ atr_info.TC[0] = -1;
+
+ ptslen = ifd_build_pts(&atr_info, proto, pts, 7);
+ if (ptslen < 0) {
+ return r;
+ }
+ if (eutron_send(reader, slot->dad, pts, ptslen) != ptslen)
+ return IFD_ERROR_COMM_ERROR;
+
+ for (ptsrlen=0,c=0;c < 20;c++) {
+ r = ifd_usb_control(reader->device, 0xc1, 0x02, 0, 0,
+ &ptsret[ptsrlen], sizeof(ptsret) - ptsrlen,
+ 1000);
+
+ if (r < 0)
+ return IFD_ERROR_COMM_ERROR;
+ ptsrlen+=r;
+ if (ifd_pts_complete(ptsret, ptsrlen))
+ break;
+
+ if (ptsrlen >= 7)
+ return IFD_ERROR_COMM_ERROR;
+ usleep(100000);
+ }
+ if (c >= 20)
+ return IFD_ERROR_TIMEOUT;
+
+ r = ifd_verify_pts(&atr_info, proto, ptsret, ptsrlen);
+ if (r < 0) {
+ ct_error("%s: Protocol selection failed", reader->name);
+ return r;
+ }
+
+ if (atr_info.TA[0] != -1)
+ speedparam=atr_info.TA[0];
+ else
+ speedparam=1;
+ if (ifd_usb_control(reader->device, 0x41, 0x65, speedparam,
+ 0, NULL, 0, -1) != 0
+ || ifd_usb_control(reader->device, 0x41, 0xa1, 0, 0, NULL,
+ 0, -1) != 0
+ || ifd_usb_control(reader->device, 0x41, 0xa0, 0, 0, NULL,
+ 0, -1) != 0)
+ return IFD_ERROR_COMM_ERROR;
+
+ slot->proto = ifd_protocol_new(proto, reader, slot->dad);
+ if (slot->proto == NULL) {
+ ct_error("%s: internal error", reader->name);
+ return -1;
+ }
+ priv->icc_proto = proto;
+ return 0;
+}
+
+
/*
* Driver operations
*/
@@ -187,6 +267,7 @@
eutron_driver.card_reset = eutron_card_reset;
eutron_driver.send = eutron_send;
eutron_driver.recv = eutron_recv;
+ eutron_driver.set_protocol = eutron_set_protocol;
ifd_driver_register("eutron", &eutron_driver);
}
_______________________________________________
opensc-devel mailing list
opensc-devel@lists.opensc-project.org
http://www.opensc-project.org/mailman/listinfo/opensc-devel