polhenarejos / pico-hsm

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

pico-hsm 2.6 becomes unavailable after first boot #3

Closed rrottmann closed 1 year ago

rrottmann commented 1 year ago

When building 2.6 release with custom VID/PID so that pcscd recognizes the hardware, copying the uf2 file to a Waveshare RP2040 Zero, the pico-hsm gets recognized by sc-hsm-tool and I can initialize it and create a RSA key using pkcs11-tool.

After reboot, the pcio-hsm seems to be stuck and no dmes output appears.

The most success I had on Debian. On Arch/EndeavorOS, the pico-hsm gets recognized after uploading the firmware file but even sc-hsm-tool is not able to initialize it and it hangs.

I suspect that maybe the driver to interact with the smartcard APDUs somehow blocks the card and corrupts it somehow. Maybe I selected also a wrong VID/PID combination that uses different commands/timings to interact? Just guessing here as I cannot make sense out of the debug output of pcscd -f -d.

Also on Windows when trying to use Smartcardshell3 (patched) this somewhat works just after the MCU resets during flashing but fails after unplug / plug of the board.

Is there some firstboot running, that needs to settle some time when it gets first used? Maybe I am too impatient and unplug when the card still rolls some internal dices?

polhenarejos commented 1 year ago

Was the pico flushed? When set ups, it creates an internal file mapping, which requires that the flash has to be all zeroed. Give a glance to https://github.com/polhenarejos/pico-nuke/releases/tag/v1.0 to erase all the memory and then copy the uf2 again.

If this step is done, try if opensc-tool -an gives something useful.

I did not test it with Waveshare, but check that you download the correct version of your flash size. If the downloaded version does not match with the size of your flash, it will not even boot up (i.e., use a 16mb.uf2 to a 8mb board).

rrottmann commented 1 year ago

Used the nuke uf2 file for the waveshare RP2040 zero. Whileit does not blink, it re-entered BOOTSEL mode after a while and did not contain any flash program. I added the 2.6 pico-hsm again and after flashing it, it is useable. After reboot it is gone.

Right now I think the issue may be related to the oscillator that is still not stable after 1 second and might need PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 parameter to give more time to settle.

I think that the program is there and simply does not boot correctly.

rrottmann commented 1 year ago

Yes, that seemed to be the issue. I did a test build with the following modifications:

pico-hsm-sdk

(unrelated but code did not compile due to realloc() after free().)

diff --git a/src/fs/file.c b/src/fs/file.c
index 390dc87..f1850e0 100644
--- a/src/fs/file.c
+++ b/src/fs/file.c
@@ -397,8 +397,16 @@ int meta_add(uint16_t fid, const uint8_t *data, uint16_t len) {
                 tpos += fdata+ef_size-p;
                 uintptr_t meta_offset = tpos-fdata;
                 ef_size += len - (tag_len-2);
-                if (len > tag_len-2)
-                    fdata = (uint8_t *)realloc(fdata, ef_size);
+                if (len > tag_len-2) {
+                   // my realloc quickfix
+                    uint8_t *fdata_new = (uint8_t *)calloc(1, ef_size);
+                    fdata_new = (uint8_t *)realloc(fdata_new, ef_size);
+                   if ( fdata_new ) {
+                       fdata = fdata_new;
+                   } else {
+                       return CCID_EXEC_ERROR;
+                   }
+               }
                 uint8_t *f = fdata+meta_offset;
                 *f++ = fid & 0xff;
                 f += format_tlv_len(len+2, f);

pico-sdk

diff --git a/src/boards/include/boards/waveshare_rp2040_zero.h b/src/boards/include/boards/waveshare_rp2040_zero.h
index 281b4dc..d1758ce 100644
--- a/src/boards/include/boards/waveshare_rp2040_zero.h
+++ b/src/boards/include/boards/waveshare_rp2040_zero.h
@@ -16,6 +16,11 @@
 // For board detection
 #define WAVESHARE_RP2040_ZERO

+// On some samples, the xosc can take longer to stabilize than is usual
+#ifndef PICO_XOSC_STARTUP_DELAY_MULTIPLIER
+#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64
+#endif
+
 // --- UART ---
 #ifndef PICO_DEFAULT_UART
 #define PICO_DEFAULT_UART 0

Basically this fix is present in other boards and should help to mitigate issues when there is a spread in board quality/components and the board takes longer to initialize/settle due to the oscillator.

polhenarejos commented 1 year ago

Glad to see it got fixed. Despite it is related with specific board (waveshare in your case), I added the flag ENABLE_DELAYED_BOOT in CMake.

I also pushed a fix for realloc complaint. Note that your solution allocate 2 chunks (previous malloc and calloc). The solution is to keep the variable meta_offset as volatile to avoid optimizations.

Thanks for the help.