2010/7/27 Douglas E. Engert <[email protected]>:
> On a Solaris 10 sparc machine, using pcsc and opensc both from
> svn, there appears to be a mismatch of handing the length
> field within the message for using a pin pad reader.
>
> pcscd trace shows:
>
> 00000126 ../../src/src/ifdhandler.c:1307:IFDHControl() ControlCode: 
> 0x42330006, usb:076b/3821:libusb:/dev/usb:76b.
> 3821/0 (lun: 0)
> 00000068 Control TxBuffer: 1E 1E 02 08 00 04 08 02 FF 00 00 00 00 00 00 00 00 
> 00 0D 00 20 00 80 08 FF FF FF FF FF
> FF FF FF
> 00000636 ../../src/src/commands.c:312:SecurePINVerify() Wrong lengths: 
> 218103827 32
> 00000055 Control RxBuffer:
> 00000049 ../../src/src/ifdwrapper.c:644:IFDControl() Card not transacted: 614
>
> This comes down to: 218103827 = 0x0D000013
> as the test in ccid commands.c is testing:
>  if (dw2i(TxBuffer, 15) + 19 != TxLength)
> which if it was stored as 0D 00 00 00, dw2i would have converted it to
>  13+19=32, and the length would have been correct.
>
> OpenSC internal-winscard.h  appears to be where the problem is:
> #define HOST_TO_CCID_16(x) (x)
> #define HOST_TO_CCID_32(x) (x)
>
> Where as PCSC/reader.h has:
> #define HOST_TO_CCID_16(x) ((((x) >> 8) & 0xFF) + ((x & 0xFF) << 8))
> #define HOST_TO_CCID_32(x) ((((x) >> 24) & 0xFF) + (((x) >> 8) & 0xFF00) + 
> ((x & 0xFF00) << 8) + (((x) & 0xFF) <<
> 24))
>
> and PCSC has in "configure.in" tests for bigendian using:
>
>  # HOST_TO_CCID
>  if test "x$ac_cv_c_bigendian" = "xyes"; then
>      AC_SUBST(host_to_ccid_16, ['((((x) >> 8) & 0xFF) + ((x & 0xFF) << 8))'])
>      AC_SUBST(host_to_ccid_32, ['((((x) >> 24) & 0xFF) + (((x) >> 8) & 0xFF00 
>    ) + ((x & 0xFF00) << 8) + (((x
> ) & 0xFF) << 24))'])
>      AC_MSG_RESULT([plateform endianess           : big endian])
>  else
>      AC_SUBST(host_to_ccid_16, ['(x)'])
>      AC_SUBST(host_to_ccid_32, ['(x)'])
>      AC_MSG_RESULT([plateform endianess           : little endian])
>  fi
>
>
> It looks like OpenSC need to test for bigendian.

Yes.

You can either test:
- at configure time: easy and not need to define a define
- at compilation time: if you generate a binary for little and big
endian from the same source code

For example reader.h on Mac OS X contains:

/** the wLangId and wPINMaxExtraDigit are 16-bits long so are subject to byte
 * ordering */
#ifdef __BIG_ENDIAN__
#define HOST_TO_CCID_16(x) ((((x) >> 8) & 0xFF) + ((x & 0xFF) << 8))
#define HOST_TO_CCID_32(x) ((((x) >> 24) & 0xFF) + (((x) >> 8) &
0xFF00) + ((x & 0xFF00) << 8) + (((x) & 0xFF) << 24))
#else
#define HOST_TO_CCID_16(x) (x)
#define HOST_TO_CCID_32(x) (x)
#endif

It does work because __BIG_ENDIAN__ is always defined on big endian
Mac computers.
And this is needed because gcc on Mac OS X generates code for Motorola
PowerPC (big endian) and Intel i386 or x86_64 (little endian).

Does the compiler on Solaris also defines __BIG_ENDIAN__ where needed?

> (On the Muscle list there is a discussion of size of DWORD, and since the
> SecurePINVerify is using dw2i() assuming 32 bit number,
> this might also cause an error on a 64 bit machine trying to use a
> pin pad reader.)

I don't see a problem here.
dw2i() assumes a 32-bit number but the value to convert is also
32-bits even on 64-bits systems.

Maybe you can show me a counter example?

Bye

-- 
 Dr. Ludovic Rousseau
_______________________________________________
opensc-devel mailing list
[email protected]
http://www.opensc-project.org/mailman/listinfo/opensc-devel

Reply via email to