1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-01-10 13:04:23 +01:00

SCD: Add support of Covadis VEGA_ALPHA reader.

* scd/ccid-driver.c: Add 2013.
(VENDER_VEGA, VEGA_ALPHA):New.
(ccid_transceive_secure): VEGA_ALPHA is same firmware as GEMPC_PINPAD.
Change bNumberMessage to 0x01, as it works better (was: 0xff).
This commit is contained in:
NIIBE Yutaka 2013-01-10 10:49:27 +09:00
parent 15bf5a10d4
commit daafc1c8fd

View File

@ -1,6 +1,6 @@
/* ccid-driver.c - USB ChipCardInterfaceDevices driver /* ccid-driver.c - USB ChipCardInterfaceDevices driver
* Copyright (C) 2003, 2004, 2005, 2006, 2007 * Copyright (C) 2003, 2004, 2005, 2006, 2007
* 2008, 2009 Free Software Foundation, Inc. * 2008, 2009, 2013 Free Software Foundation, Inc.
* Written by Werner Koch. * Written by Werner Koch.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
@ -211,6 +211,7 @@ enum {
VENDOR_SCM = 0x04e6, VENDOR_SCM = 0x04e6,
VENDOR_OMNIKEY= 0x076b, VENDOR_OMNIKEY= 0x076b,
VENDOR_GEMPC = 0x08e6, VENDOR_GEMPC = 0x08e6,
VENDER_VEGA = 0x0982,
VENDOR_KAAN = 0x0d46, VENDOR_KAAN = 0x0d46,
VENDOR_FSIJ = 0x234b, VENDOR_FSIJ = 0x234b,
VENDOR_VASCO = 0x1a44 VENDOR_VASCO = 0x1a44
@ -224,7 +225,8 @@ enum {
#define SCM_SPR532 0xe003 #define SCM_SPR532 0xe003
#define CHERRY_ST2000 0x003e #define CHERRY_ST2000 0x003e
#define VASCO_920 0x0920 #define VASCO_920 0x0920
#define GEMPC_PINPAD 0x3478 #define GEMPC_PINPAD 0x3478
#define VEGA_ALPHA 0x0008
/* A list and a table with special transport descriptions. */ /* A list and a table with special transport descriptions. */
enum { enum {
@ -2383,7 +2385,7 @@ update_param_by_atr (unsigned char *param, unsigned char *atr, size_t atrlen)
NEXTBYTE (); NEXTBYTE ();
if (atr[i] == 0x3F) if (atr[i] == 0x3F)
param[1] |= 0x02; /* Convention is inverse. */ param[1] |= 0x02; /* Convention is inverse. */
NEXTBYTE (); NEXTBYTE ();
y = (atr[i] >> 4); y = (atr[i] >> 4);
@ -2392,91 +2394,91 @@ update_param_by_atr (unsigned char *param, unsigned char *atr, size_t atrlen)
if ((y & 1)) if ((y & 1))
{ {
param[0] = atr[i]; /* TA1 - Fi & Di */ param[0] = atr[i]; /* TA1 - Fi & Di */
NEXTBYTE (); NEXTBYTE ();
} }
if ((y & 2)) if ((y & 2))
NEXTBYTE (); /* TB1 - ignore */ NEXTBYTE (); /* TB1 - ignore */
if ((y & 4)) if ((y & 4))
{ {
param[2] = atr[i]; /* TC1 - Guard Time */ param[2] = atr[i]; /* TC1 - Guard Time */
NEXTBYTE (); NEXTBYTE ();
} }
if ((y & 8)) if ((y & 8))
{ {
y = (atr[i] >> 4); /* TD1 */ y = (atr[i] >> 4); /* TD1 */
t = atr[i] & 0x0f; t = atr[i] & 0x0f;
NEXTBYTE (); NEXTBYTE ();
if ((y & 1)) if ((y & 1))
{ /* TA2 - PPS mode */ { /* TA2 - PPS mode */
if ((atr[i] & 0x0f) != 1) if ((atr[i] & 0x0f) != 1)
return -2; /* Wrong card protocol (!= 1). */ return -2; /* Wrong card protocol (!= 1). */
if ((atr[i] & 0x10) != 0x10) if ((atr[i] & 0x10) != 0x10)
return -3; /* Transmission parameters are implicitly defined. */ return -3; /* Transmission parameters are implicitly defined. */
negotiable = 0; /* TA2 means specific mode. */ negotiable = 0; /* TA2 means specific mode. */
NEXTBYTE (); NEXTBYTE ();
} }
if ((y & 2)) if ((y & 2))
NEXTBYTE (); /* TB2 - ignore */ NEXTBYTE (); /* TB2 - ignore */
if ((y & 4)) if ((y & 4))
NEXTBYTE (); /* TC2 - ignore */ NEXTBYTE (); /* TC2 - ignore */
if ((y & 8)) if ((y & 8))
{ {
y = (atr[i] >> 4); /* TD2 */ y = (atr[i] >> 4); /* TD2 */
t = atr[i] & 0x0f; t = atr[i] & 0x0f;
NEXTBYTE (); NEXTBYTE ();
} }
else else
y = 0; y = 0;
while (y) while (y)
{ {
if ((y & 1)) if ((y & 1))
{ /* TAx */ { /* TAx */
if (t == 1) if (t == 1)
param[5] = atr[i]; /* IFSC */ param[5] = atr[i]; /* IFSC */
else if (t == 15) else if (t == 15)
/* XXX: check voltage? */ /* XXX: check voltage? */
param[4] = (atr[i] >> 6); /* ClockStop */ param[4] = (atr[i] >> 6); /* ClockStop */
NEXTBYTE (); NEXTBYTE ();
} }
if ((y & 2)) if ((y & 2))
{ {
if (t == 1) if (t == 1)
param[3] = atr[i]; /* TBx - BWI & CWI */ param[3] = atr[i]; /* TBx - BWI & CWI */
NEXTBYTE (); NEXTBYTE ();
} }
if ((y & 4)) if ((y & 4))
{ {
if (t == 1) if (t == 1)
param[1] |= (atr[i] & 0x01); /* TCx - LRC/CRC */ param[1] |= (atr[i] & 0x01); /* TCx - LRC/CRC */
NEXTBYTE (); NEXTBYTE ();
if (param[1] & 0x01) if (param[1] & 0x01)
return -4; /* CRC not supported yet. */ return -4; /* CRC not supported yet. */
} }
if ((y & 8)) if ((y & 8))
{ {
y = (atr[i] >> 4); /* TDx */ y = (atr[i] >> 4); /* TDx */
t = atr[i] & 0x0f; t = atr[i] & 0x0f;
NEXTBYTE (); NEXTBYTE ();
} }
else else
y = 0; y = 0;
} }
} }
i += historical_bytes_num - 1; i += historical_bytes_num - 1;
@ -2605,16 +2607,16 @@ ccid_get_atr (ccid_driver_t handle,
msglen = 10; msglen = 10;
rc = bulk_out (handle, msg, msglen, 0); rc = bulk_out (handle, msg, msglen, 0);
if (!rc) if (!rc)
rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_Parameters, rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_Parameters,
seqno, 2000, 0); seqno, 2000, 0);
if (rc) if (rc)
DEBUGOUT ("GetParameters failed\n"); DEBUGOUT ("GetParameters failed\n");
else if (msglen == 17 && msg[9] == 1) else if (msglen == 17 && msg[9] == 1)
got_param = 1; got_param = 1;
} }
else if (handle->auto_pps) else if (handle->auto_pps)
; ;
else if (rc == 1) /* It's negotiable, send PPS. */ else if (rc == 1) /* It's negotiable, send PPS. */
{ {
msg[0] = PC_to_RDR_XfrBlock; msg[0] = PC_to_RDR_XfrBlock;
msg[5] = 0; /* slot */ msg[5] = 0; /* slot */
@ -2622,33 +2624,33 @@ ccid_get_atr (ccid_driver_t handle,
msg[7] = 0; msg[7] = 0;
msg[8] = 0; msg[8] = 0;
msg[9] = 0; msg[9] = 0;
msg[10] = 0xff; /* PPSS */ msg[10] = 0xff; /* PPSS */
msg[11] = 0x11; /* PPS0: PPS1, Protocol T=1 */ msg[11] = 0x11; /* PPS0: PPS1, Protocol T=1 */
msg[12] = param[0]; /* PPS1: Fi / Di */ msg[12] = param[0]; /* PPS1: Fi / Di */
msg[13] = 0xff ^ 0x11 ^ param[0]; /* PCK */ msg[13] = 0xff ^ 0x11 ^ param[0]; /* PCK */
set_msg_len (msg, 4); set_msg_len (msg, 4);
msglen = 10 + 4; msglen = 10 + 4;
rc = bulk_out (handle, msg, msglen, 0); rc = bulk_out (handle, msg, msglen, 0);
if (rc) if (rc)
return rc; return rc;
rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_DataBlock, rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_DataBlock,
seqno, 5000, 0); seqno, 5000, 0);
if (rc) if (rc)
return rc; return rc;
if (msglen != 10 + 4) if (msglen != 10 + 4)
{ {
DEBUGOUT_1 ("Setting PPS failed: %d\n", msglen); DEBUGOUT_1 ("Setting PPS failed: %d\n", msglen);
return CCID_DRIVER_ERR_CARD_IO_ERROR; return CCID_DRIVER_ERR_CARD_IO_ERROR;
} }
if (msg[10] != 0xff || msg[11] != 0x11 || msg[12] != param[0]) if (msg[10] != 0xff || msg[11] != 0x11 || msg[12] != param[0])
{ {
DEBUGOUT_1 ("Setting PPS failed: 0x%02x\n", param[0]); DEBUGOUT_1 ("Setting PPS failed: 0x%02x\n", param[0]);
return CCID_DRIVER_ERR_CARD_IO_ERROR; return CCID_DRIVER_ERR_CARD_IO_ERROR;
} }
} }
/* Setup parameters to select T=1. */ /* Setup parameters to select T=1. */
@ -3299,7 +3301,7 @@ ccid_transceive (ccid_driver_t handle,
int int
ccid_transceive_secure (ccid_driver_t handle, ccid_transceive_secure (ccid_driver_t handle,
const unsigned char *apdu_buf, size_t apdu_buflen, const unsigned char *apdu_buf, size_t apdu_buflen,
pininfo_t *pininfo, pininfo_t *pininfo,
unsigned char *resp, size_t maxresplen, size_t *nresp) unsigned char *resp, size_t maxresplen, size_t *nresp)
{ {
int rc; int rc;
@ -3361,16 +3363,17 @@ ccid_transceive_secure (ccid_driver_t handle,
if (handle->id_product != CHERRY_ST2000) if (handle->id_product != CHERRY_ST2000)
cherry_mode = 1; cherry_mode = 1;
break; break;
case VENDOR_GEMPC:
if (handle->id_product == GEMPC_PINPAD)
{
enable_varlen = 0;
pininfo->minlen = 4;
pininfo->maxlen = 8;
break;
}
/* fall through */
default: default:
if ((handle->id_vendor == VENDOR_GEMPC &&
handle->id_product == GEMPC_PINPAD)
|| (handle->id_vendor == VENDOR_VEGA &&
handle->id_product == VEGA_ALPHA))
{
enable_varlen = 0;
pininfo->minlen = 4;
pininfo->maxlen = 8;
break;
}
return CCID_DRIVER_ERR_NOT_SUPPORTED; return CCID_DRIVER_ERR_NOT_SUPPORTED;
} }
@ -3413,8 +3416,8 @@ ccid_transceive_secure (ccid_driver_t handle,
else else
{ {
msg[13] = pininfo->fixedlen; /* bmPINBlockString: msg[13] = pininfo->fixedlen; /* bmPINBlockString:
0 bits of pin length to insert. 0 bits of pin length to insert.
PIN block size by fixedlen. */ PIN block size by fixedlen. */
msg[14] = 0x00; /* bmPINLengthFormat: msg[14] = 0x00; /* bmPINLengthFormat:
Units are bytes, position is 0. */ Units are bytes, position is 0. */
} }
@ -3446,7 +3449,7 @@ ccid_transceive_secure (ccid_driver_t handle,
msglen++; msglen++;
if (apdu_buf[1] == 0x20) if (apdu_buf[1] == 0x20)
msg[msglen++] = 0xff; /* bNumberMessage: Default. */ msg[msglen++] = 0x01; /* bNumberMessage. */
else else
msg[msglen++] = 0x03; /* bNumberMessage. */ msg[msglen++] = 0x03; /* bNumberMessage. */