{"id":47807148,"url":"https://github.com/librekeys/pico-hsm","last_synced_at":"2026-04-03T17:48:02.442Z","repository":{"id":341066915,"uuid":"1146343800","full_name":"librekeys/pico-hsm","owner":"librekeys","description":"Hardware Security Module (HSM) for Raspberry Pico and ESP32","archived":false,"fork":false,"pushed_at":"2026-02-27T19:40:16.000Z","size":2452,"stargazers_count":0,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-27T23:54:03.776Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/librekeys.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-31T00:19:08.000Z","updated_at":"2026-02-27T19:39:27.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/librekeys/pico-hsm","commit_stats":null,"previous_names":["librekeys/pico-hsm"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/librekeys/pico-hsm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/librekeys%2Fpico-hsm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/librekeys%2Fpico-hsm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/librekeys%2Fpico-hsm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/librekeys%2Fpico-hsm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/librekeys","download_url":"https://codeload.github.com/librekeys/pico-hsm/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/librekeys%2Fpico-hsm/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31366617,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-03T17:13:05.644Z","status":"ssl_error","status_checked_at":"2026-04-03T17:13:04.413Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-03T17:48:01.328Z","updated_at":"2026-04-03T17:48:02.425Z","avatar_url":"https://github.com/librekeys.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pico HSM\nThis project aims to transform a Raspberry Pi Pico or ESP32 microcontroller into a Hardware Security Module (HSM). The modified Pico or ESP32 board will be capable of generating and storing private keys, performing AES encryption or decryption, and signing data without exposing the private key. Specifically, the private key remains securely on the board and cannot be retrieved since it is encrypted within the flash memory.\n\nThis is a fork of the community edition of the project located at https://github.com/polhenarejos/pico-hsm\nFor licensing information, see the LICENSE file\n\n## Capabilities\n### \u003e Key generation and encrypted storage\nPrivate and secret keys are secured using a master AES 256 key (MKEK). The MKEK is encrypted with a hashed and salted version of the PIN.\n**No private/secret keys, DKEK or PIN are stored in plain text ever. Never.**\n\n### \u003e RSA Key Generation (1024 to 4096 Bits)\nRSA key generation is supported for 1024, 2048, 3072, and 4096 bits. Private keys never leave the device.\n\n### \u003e ECDSA Key Generation (192 to 521 Bits)\nECDSA key generation supports various curves from 192 to 521 bits.\n\n### \u003e ECC Curves\nSupported ECC curves include secp192r1, secp256r1, secp384r1, secp521r1, brainpoolP256r1, brainpoolP384r1, brainpoolP512r1, secp192k1 (insecure), secp256k1, Curve25519, and Curve448.\n\n### \u003e SHA Digests\nECDSA and RSA signatures can be combined with SHA-1, SHA-224, SHA-256, SHA-384, and SHA-512 digests.\n\n### \u003e Multiple RSA Signature Algorithms\nSupported RSA signature algorithms include RSA-PSS, RSA-PKCS, and raw RSA signatures.\n\n### \u003e ECDSA Signatures\nECDSA signatures can be raw or pre-hashed.\n\n### \u003e ECDH Key Derivation\nSupports the ECDH algorithm for calculating shared secrets.\n\n### \u003e EC Private Key Derivation\nAllows ECDSA key derivation.\n\n### \u003e RSA Decryption\nSupports RSA-OEP and RSA-X.509 decryption.\n\n### \u003e AES Key Generation\nSupports AES key generation with keys of 128, 192, and 256 bits.\n\n### \u003e AES-CBC Encryption/Decryption\nPerforms AES-CBC encryption and decryption.\n\n### \u003e Advanced AES Modes\nSupports AES encryption and decryption in ECB, CBC, CFB, OFB, XTS, CTR, GCM, and CCM modes, with customizable IV/nonce and additional authenticated data (AAD).[^4]\n\n### \u003e AES Key Generation (128, 192, 256, 512 Bits)\nSupports AES key generation up to 512 bits, useful for AES XTS where two 256-bit keys are concatenated.\n\n### \u003e CMAC\nSupports AES-CMAC authentication.[^1]\n\n### \u003e AES Secret Key Derivation\nSupports AES secret key derivation.[^1]\n\n### \u003e PIN Authorization\nPrivate and secret keys require prior PIN authentication. Supports alphanumeric PINs.\n\n### \u003e PKCS11 Compliant Interface\nInterfacing with the PKCS11 standard is supported.\n\n### \u003e Hardware Random Number Generator (HRNG)\nContains an HRNG designed for maximum entropy.\n\n### \u003e Device Key Encryption Key (DKEK) Shares\nSupports importing DKEK shares to wrap, unwrap, and encrypt keys.\n\n### \u003e DKEK n-of-m Threshold Scheme\nSupports an n-of-m threshold scheme to prevent outages when a DKEK custodian is unavailable.\n\n### \u003e USB/CCID Support\nFull USB CCID stack for communication with the host via OpenSC and PCSC, allowing the use of frontend applications like OpenSSL via the PKCS11 module.\n\n### \u003e Extended APDU Support\nSupports extended APDU packets, allowing up to 65535 bytes.\n\n### \u003e CV Certificates\nHandles CVC certificates and requests to minimize internal certificate storage.\n\n### \u003e Attestation\nEach generated key is attached to a certificate signed by an external PKI, ensuring the key was generated by the specific device.\n\n### \u003e Import External Keys and Certificates\nAllows importing private keys and certificates via WKY or PKCS#12 files.[^2][^3]\n\n### \u003e Transport PIN\nAllows a transport PIN for provisioning, ensuring the device has not been tampered with during transportation.[^2]\n\n### \u003e Press-to-Confirm Button\nUses the BOOTSEL button to confirm operations with private/secret keys, providing a 15-second window to confirm the operation to protect against unauthorized use.\n\n### \u003e Store and Retrieve Binary Data\nAllows the storage of arbitrary binary data files.\n\n### \u003e Real-Time Clock (RTC)\nIncludes an RTC with external date and time setting and retrieval.\n\n### \u003e Secure Messaging\nSupports secure channels to encrypt data packets between the host and device, preventing man-in-the-middle attacks.\n\n### \u003e Session PIN\nA specific session PIN can be set during session opening to avoid systematic PIN usage.\n\n### \u003e PKI CVCert Remote Issuing for Secure Messaging\nSecure channel messages are secured with a certificate issued by an external PKI.\n\n### \u003e Multiple Key Domains\nSupports separate key domains protected by independent DKEKs, allowing different keys in different domains.\n\n### \u003e Key Usage Counter\nTracks and limits the usage of private/secret keys, disabling keys once their usage counter reaches zero.\n\n### \u003e Public Key Authentication (PKA)\nSupports PKA for enhanced security, requiring a secondary device for authentication using a challenge-response mechanism.\n\n### \u003e Secure Lock\nAdds an extra layer of security by locking the Pico HSM to a specific computer using a private key.\n\n### \u003e ChaCha20-Poly1305\nSupports the ChaCha20-Poly1305 encryption algorithm for secure data encryption.[^4]\n\n### \u003e X25519 and X448\nSupports DH X25519 and X448 for key agreement, though these cannot be used for signing.\n\n### \u003e Key Derivation Functions\nSupports HKDF, PBKDF2, and X963-KDF for symmetric key derivation.\n\n### \u003e HMAC\nSupports HMAC generation with SHA digest algorithms.\n\n### \u003e CMAC\nSupports CMAC with AES for keys of 128, 192, and 256 bits.\n\n### \u003e XKEK\nSupports an advanced key sharing scheme (XKEK) for securely wrapping and unwrapping keys within authorized domains.\n\n### \u003e Master Key Encryption Key (MKEK)\nUses an MKEK to securely store all keys, encrypted with an ephemeral key derived from the hashed PIN.\n\n### \u003e Hierarchical Deterministic Key Generation\nSupports BIP32 for asymmetric key derivation and SLIP10 for symmetric key derivation, enabling crypto wallet deployment with infinite key generation. Supports NIST 256 and Koblitz 256 curves for master key generation.[^4]\n\n### \u003e One Time Programming (OTP) Storage\nThe OTP securely stores the MKEK (Master Key Encryption Key) and Device Key permanently, making it inaccessible from external interfaces. This ensures that the key is protected against unauthorized access and tampering.\n\n### \u003e Secure Boot\nSecure Boot ensures only authenticated firmware can run on the device, verifying each firmware’s digital signature to block unauthorized code.\n\n### \u003e Secure Lock\nSecure Lock restricts the device to the manufacturer’s firmware only, locking out debug access and preventing any further boot key installations.\n\n### \u003e Rescue Interface\n A built-in rescue interface allows recovery of the device if it becomes unresponsive or undetectable. This feature provides a way to restore the device to operational status without compromising security.\n\n### \u003e LED Customization\n The LED can be customized to reflect device status and user preferences, offering flexible color and brightness options for an enhanced user experience.\n\n[^1]: PKCS11 modules (`pkcs11-tool` and `sc-tool`) do not support CMAC and key derivation. It must be processed through raw APDU command (`opensc-tool -s`).\n[^2]: Available via SCS3 tool. See [SCS3](/doc/scs3.md \"SCS3\") for more information.\n[^3]: Imports are available only if the Pico HSM is previously initialized with a DKEK and DKEK shares are available during the import process.\n[^4]: Available by using PicoHSM python tool.\n\n### \u003e ESP32-S3 support\nPico HSM also supports ESP32-S3 boards, which add secure storage, flash encryption and secure boot.\n\n### \u003e Dynamic VID/PID\nSupports setting VID \u0026 PID on-the-fly. U\n\n### \u003e Rescue Pico HSM\nPico HSM Tool implements a new CCID stack to rescue the Pico HSM in case it has wrong VID/PID values and it is not recognized by the OS.\n\n## Security considerations\nAll secret keys (both asymmetric and symmetric) are encrypted and stored in the flash memory. The MKEK, a 256-bit AES key, is used to protect these private and secret keys. Keys are held in RAM only during signature and decryption operations, and are loaded and cleared each time to avoid potential security vulnerabilities.\n\nThe MKEK itself is encrypted using a doubly salted and hashed PIN, and the PIN is hashed in memory during sessions. This ensures that the PIN is never stored in plaintext, neither in flash memory nor in RAM. However, if no secure channel is used, the PIN may be transmitted in plaintext from the host to the HSM.\n\nDKEKs are used during the export and import of private/secret keys and are part of a Key Domain. A Key Domain is a set of secret/private keys that share the same DKEK. These are also shared by the custodians and are not specific to Pico HSM. Therefore, if a key does not belong to a Key Domain (and thus lacks a DKEK), it cannot be exported.\n\nIn the event that the Pico is stolen, the private and secret key contents cannot be accessed without the PIN, even if the flash memory is dumped.\n\n### RP2350 and ESP32-S3\nRP2350 and ESP32-S3 microcontrollers are equipped with advanced security features, including Secure Boot and Secure Lock, ensuring that firmware integrity and authenticity are tightly controlled. Both devices support the storage of the Master Key Encryption Key (MKEK) in an OTP (One-Time Programmable) memory region, making it permanently inaccessible for external access or tampering. This secure, non-volatile region guarantees that critical security keys are embedded into the hardware, preventing unauthorized access and supporting robust defenses against code injection or firmware modification. Together, Secure Boot and Secure Lock enforce firmware authentication, while the MKEK in OTP memory solidifies the foundation for secure operations.\n\n## Build for Raspberry Pico\nBefore building, ensure you have installed the toolchain for the Pico and the Pico SDK is properly located in your drive.\n\n```\ngit clone https://github.com/librekeys/pico-hsm\ngit submodule update --init --recursive\ncd pico-hsm\nmkdir build\ncd build\nPICO_SDK_PATH=/path/to/pico-sdk cmake .. -DPICO_BOARD=board_type -DUSB_VID=0x1D50 -DUSB_PID=0x619B\nmake\n```\nNote that `PICO_BOARD`, `USB_VID` and `USB_PID` are optional. If not provided, `pico` board and VID/PID `1D50:619B` will be used.\n\nAdditionally, you can pass the `VIDPID=value` parameter to build the firmware with a known VID/PID. The supported values are:\n\n- `NitroHSM`\n- `NitroFIDO2`\n- `NitroStart`\n- `NitroPro`\n- `Nitro3`\n- `Yubikey5`\n- `YubikeyNeo`\n- `YubiHSM`\n- `Gnuk`\n- `GnuPG`\n\nYou can use whatever VID/PID for your own personal use. **But remember that you are not authorized to distribute the binary with a VID/PID that you do not own.**\nThe VID/PID `1D50:619B` is provided to the project by [OpenMoko](https://wiki.openmoko.org/wiki/USB_Product_IDs). It can only be used for builds distributed under a free and open source license.\n\nAfter running `make`, the binary file `pico_hsm.uf2` will be generated. To load this onto your Pico board:\n\n1. Put the Pico board into loading mode by holding the `BOOTSEL` button while plugging it in.\n2. Copy the `pico_hsm.uf2` file to the new USB mass storage device that appears.\n3. Once the file is copied, the Pico mass storage device will automatically disconnect, and the Pico board will reset with the new firmware.\n4. A blinking LED will indicate that the device is ready to work.\n\n### Docker\nIndependent from your Linux distribution or when using another OS that supports Docker, you could build a specific pico-hsm version in a Linux container.\n\n```\nsudo docker build \\\n    --build-arg VERSION_PICO_SDK=2.0.0 \\\n    --build-arg VERSION_MAJOR=5 \\\n    --build-arg VERSION_MINOR=0 \\\n    --build-arg PICO_BOARD=waveshare_rp2040_zero \\\n    --build-arg USB_VID=0xfeff \\\n    --build-arg USB_PID=0xfcfd \\\n    -t pico-hsm-builder .\n\nsudo docker run \\\n    --name mybuild \\\n    -it pico-hsm-builder \\\n    ls -l /home/builduser/pico-hsm/build_release/pico_hsm.uf2\n\nsudo docker cp mybuild:/home/builduser/pico-hsm/build_release/pico_hsm.uf2 .\n\nsudo docker rm mybuild\n```\n\n## Usage\nThe firmware uploaded to the Pico contains a reader and a virtual smart card, similar to having a physical reader with an inserted SIM card. We recommend using [OpenSC](http://github.com/opensc/opensc/ \"OpenSC\") to communicate with the reader. If OpenSC is not installed, you can download and build it or install the binaries for your system.\n\nTo ensure that the Pico is detected as an HSM, use the following command:\n```sh\nopensc-tool -an\n```\nIt should return a text similar to:\n```sh\nUsing reader with a card: Free Software Initiative of Japan Gnuk\n3b:fe:18:00:00:81:31:fe:45:80:31:81:54:48:53:4d:31:73:80:21:40:81:07:fa\nSmartCard-HSM\n```\nThe name of the reader may vary if you modified the VID/PID.\n\nFor further details and operations, refer to the following documentation:\n\n- Initialization and Asymmetric Operations [doc/usage.md](/doc/usage.md)\n- Signing and Verification Operations [doc/sign-verify.md](/doc/sign-verify.md)\n- Asymmetric Encryption and Decryption [doc/asymmetric-ciphering.md](/doc/asymmetric-ciphering.md)\n- Backup, Restore, and DKEK Share Management [doc/backup-and-restore.md](/doc/backup-and-restore.md)\n- AES Key Generation, Encryption, and Decryption [doc/aes.md](/doc/aes.md)\n- 4096 Bits RSA Support [doc/scs3.md](/doc/scs3.md)\n- Storing and Retrieving Arbitrary Data [doc/store_data.md](/doc/store_data.md)\n- Extra Options (e.g., set/get real datetime, enable/disable press-to-confirm button [doc/extra_command.md](/doc/extra_command.md)\n- Public Key Authentication [doc/public_key_authentication.md](/doc/public_key_authentication.md)\n\n## Operation time\n### Keypair generation\nGenerating EC keys is almost instant. RSA keypair generation takes some time, specially for `3072` and `4096` bits.\n\n| RSA key length (bits) | Average time (seconds) |\n| :---: | :---: |\n| 1024 | 16 |\n| 2048 | 124 |\n| 3072 | 600 |\n| 4096 | ~1000 |\n\n### Signature and decrypt\n| RSA key length (bits) | Average time (seconds) |\n| :---: | :---: |\n| 1024 | 1 |\n| 2048 | 3 |\n| 3072 | 7 |\n| 4096 | 15 |\n\n## Press-to-confirm button\nThe Raspberry Pico includes a BOOTSEL button used for loading firmware initially. Once the Pico HSM firmware is running, this button can be repurposed for additional functionalities. Specifically, the Pico HSM utilizes this button to confirm private and secret operations, a feature that is optional but highly recommended for enhanced security.\n\nWhen enabled, each time a private or secret key operation is initiated, the Pico HSM enters a waiting state where it awaits user confirmation by pressing the BOOTSEL button. During this waiting period, the Pico HSM's LED remains mostly illuminated but blinks off briefly every second, signaling to the user to press the button for confirmation. If no action is taken, the Pico HSM will continue to wait indefinitely. This operation mode includes periodic timeout commands sent to the host to prevent the session from timing out prematurely.\n\nThis feature adds an additional layer of security by requiring physical user intervention for sensitive operations such as signing or decrypting data. It mitigates risks associated with unauthorized applications or scripts using the Pico HSM without user awareness. However, it is not recommended for server environments or other automated settings where physical access to press the button may not be practical.\n\nFor more details on configuring and using this feature, refer to the [doc/extra_command.md](/doc/extra_command.md) document.\n\n## Led blink\nPico HSM uses the led to indicate the current status. Four states are available:\n\n### Press to confirm\nThe Led is almost on all the time. It goes off for 100 miliseconds every second.\n\n![Press to confirm](https://user-images.githubusercontent.com/55573252/162008917-6a730eac-396c-44cc-890e-802294be30a3.gif)\n\n### Idle mode\nIn idle mode, the Pico HSM goes to sleep. It waits for a command and it is awaken by the driver. The Led is almost off all the time. It goes on for 500 milliseconds every second.\n\n![Idle mode](https://user-images.githubusercontent.com/55573252/162008980-d5a5caad-072e-400c-98e3-2c606b4b2af9.gif)\n\n### Active mode\nIn active mode, the Pico HSM is awaken and ready to receive a command. It blinks four times in a second.\n\n![Active](https://user-images.githubusercontent.com/55573252/162008997-1ea8cd7e-5384-4893-9dcb-b473153fc375.gif)\n\n### Processing\nWhile processing, the Pico HSM is busy and cannot receive additional commands until the current is processed. In this state, the Led blinks 20 times in a second.\n\n![Processing](https://user-images.githubusercontent.com/55573252/162009007-df45111e-2473-4a92-97c5-15c3cd19babd.gif)\n\n## Driver\n\nThe Pico HSM uses either the `sc-hsm` driver from [OpenSC](https://github.com/OpenSC/OpenSC/) or the `sc-hsm-embedded` driver from [CardContact](https://github.com/CardContact/sc-hsm-embedded/) to interface with external applications. These drivers employ the standardized PKCS#11 interface, making it compatible with various cryptographic engines that support PKCS#11, such as OpenSSL, P11 library, or pkcs11-tool.\n\nInternally, the Pico HSM organizes and manages its data using the PKCS#15 structure, which includes elements like PINs, private keys, and certificates. Commands can be issued to interact with these stored elements using tools such as `pkcs15-tool`. For example, `pkcs15-tool -D` lists all elements stored within the Pico HSM.\n\nCommunication with the Pico HSM follows the same protocols and methods used with other smart cards, such as OpenPGP cards or similar devices.\n\nFor advanced usage scenarios, refer to the documentation and examples provided. Additionally, the Pico HSM supports the SCS3 tool for more sophisticated operations and includes features like multiple key domains. For detailed information on SCS3 usage, refer to [SCS3 documentation](/doc/scs3.md).\n\n## License and Commercial Use\n\nThis project is released under the GNU Affero General Public License v3 (AGPLv3).\nA copy of the AGPLv3 license is available in the `LICENSE` file.\n\n## Credits\nThis project uses libraries and portion of code from other projects that are detailed in the `LICENSE` file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flibrekeys%2Fpico-hsm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flibrekeys%2Fpico-hsm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flibrekeys%2Fpico-hsm/lists"}