polhenarejos / pico-hsm

Hardware Security Module for Raspberry Pico
GNU General Public License v3.0
180 stars 23 forks source link

Usage on MacOS and Windows with Microsoft CCID driver #19

Closed petrn closed 1 year ago

petrn commented 1 year ago

I have tried to use this project on RPi Pico and on Waveshare RP2040 Zero. As the LED on the Zero is not working, I am mainly using the original RPi Pico.

Under Linux (Ubuntu 22.04) I was able to get this project to work after editing the Info.plist to include the default VID/PID combination. I was using the release version 3.2. So I know my Pico board is working correctly here.

On MacOS without changing the VID and PID, the default combination is not known to the Apple CCID driver. On older versions of MacOS, it used to be possible to manually edit the Info.plist and add a new VID/PID combination, but now the Info.plist is in the read-only partition. Is there any known way to get it working with the default VID/PID or does one have to set one of the known VID/PID combinations to get it to work on a Mac?

However, on Windows, the Device Manager shows the Microsoft CCID driver attached to the VID/PID combination, but any attempt to use it just hangs (like doing reset in SCSH3 after selecting the pico-hsm in Reader selection). The task needs to be killed from the Task Manager, it is blocked that it cannot be closed normally.

Is this a known problem with Windows or is it something specific on my machine? I have multiple other CCID drivers installed and working correctly, I am a long term regular user of SCSH3.

polhenarejos commented 1 year ago

I faced the same problem on my Mac. I contacted Ludovic, the developer of ICCID driver, who indicated to create a new driver /usr/local/libexec/SmartCardServices/drivers/.

https://salsa.debian.org/rousseau/PCSC/-/issues/23

To me, it is too cumbersome.

You have 2 possible workarounds:

  1. Compile your own firmware by providing -DUSB_VID=0x20a0 -DUSB_PID=0x4230 parameters. These VID/PID are from Nitrokey HSM product. With this way you have to install the PicoSDK, cross-compile toolchain and other software. It is not difficult but you need to have some kind of practice beforehand.
  2. Patch the binary you just download from pico-hsm repo and patch it with the pico-hsm-patch-vidpid.sh 20a0:4230 file.uf2. It will modify the binary to replace the dummy VID/PID for the valid.

You can use other VID/PID like from FSIJ (0234:0000) and it will also be recognized by your host. However keep in mind that you are not allowed (neither me) to distribute a USB device with VID/PID that you do not own. So, for personal use it is fine.

For Windows I did not have the opportunity to test the HSM deeply. I used the windows build of OpenSC https://github.com/OpenSC/OpenSC/releases/tag/0.23.0 and it worked smoothly, so I guess there is some problem with JAVA PSCS interface. I will make some tests.

petrn commented 1 year ago

Thanks a lot for the hints on MacOS.

I will trace the USB trafffic on Windows and send you the result. Yesterday, connecting the Pico to Windows did actually crash the Resource Manager and the whole smart card subsystem was not working, I had to restart the machine.

I have noticed you do not implement the interrupt pipe in your card side CCID implementation, perhaps the Microsoft CCID driver crashes without the interrupt pipe being present?

polhenarejos commented 1 year ago

It shouldn't. Interrupt pipe is used to notify the host any change on the card status, like card removal or insert. It is mainly for true readers. From USB Alliance it is stated that Interrupt endpoint is optional but Windows usually tends to do not follow standards. Anyway, I will add support for the interrupt endpoint. Are you able to build and test it?

petrn commented 1 year ago

Yes, I can build the pico-HSM, I have set up your project.

Here is the analysis of the pico-HSM for the RPi Pico board version 3.2 (pico_hsm_pico-3.2.uf2) freshly loaded to the board and connected to a Windows 10 system.

fresh-3.2-pico-on-W10.ulz.zip

You would need the usblyzer (free for 33 days, the company behind it seems to be gone since April 2022), you can fetch it via the Internet Archive through this link: https://web.archive.org/web/20220404072242if_/http://www.usblyzer.com/files/USBlyzer.zip

You can see that at seq 140 the CCID message "6C 00 00 00 00 00 03 00 00 00" is sent but is never replied to. this message then repeats (with the incrementing bSeq), again with no answer. So it seems to suggest that the Microsoft default CCID driver requires the PC_to_RDR_GetParameters to be supported.

You seem to have it defined but not implemented:

src/usb/ccid/ccid.c:#define CCID_GET_PARAMS 0x6C / non-ICCD command /

If it was working for you, perhaps you have changed the VID and PID and therefore used a different than the Microsoft driver for the CCID class device.

polhenarejos commented 1 year ago

Can you try with latest commit? Ensure updating hsm sdk.

petrn commented 1 year ago

I have updated to the most recent commit on the development brach. It now gets a bit further, but still it does not work under W10 with the Microsoft default CCID driver, it reports that there is no card in the reader. The ULZ is again attached. fresh-3.2-pico-on-W10-after-update.ulz.zip

You can see that after the PC_to_RDR_GetSlotStatus the driver is issuing the PC_to_RDR_IccPowerOff command and receives the RDR_to_PC_SlotStatus. It then sends the PC_to_RDR_IccPowerOn with bPowerSelect = 5V. It receives RDR_to_PC_DataBlock with the ATR and no error.

Then it sends PC_to_RDR_GetParameters and the response is RDR_to_PC_Parameters with: 82 07 00 00 00 00 0B 00 01 00 11 11 FE 55 03 FE 00

I think this response is NOT correct, I believe after the 0B there should be 2 00 bytes, followed by 01 for bProtocolNum and the 7 bytes for the T=1 protocol data.

The T=1 protocol data bmTCCKST1 I am not sure why you have the B0 set to 1 as the ATR does not signal that CRC would be used (section 11.4.4 of 7816-3).

Then the driver powers down the card, as it seems to be confused by the response to the PC_to_RDR_GetParameters command.

polhenarejos commented 1 year ago

Actually is an error with endianness (pico is LE). You are right, instead of 01 00 should be 00 01.

About bmTCCKST1, I took the same value as Gnuk, which also does not signals CRC in its ATR. In any case, I doubt these parameters are used in a ICCD.

I pushed the fix for endianness at pico-hsm-sdk

petrn commented 1 year ago

This looks better, now it seems to work OK. Thanks a lot for the fix.