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
