-
Notifications
You must be signed in to change notification settings - Fork 1k
Add WISeKey/SealSQ VaultIC secure element port #10974
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
dgarske
wants to merge
3
commits into
wolfSSL:master
Choose a base branch
from
dgarske:sealsq_vaultic
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 1 commit
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,174 @@ | ||
| # WISeKey / SealSQ VaultIC Port | ||
|
|
||
| This port offloads TLS ECC P-256 operations to a WISeKey/SealSQ VaultIC secure | ||
| element (for example the VaultIC 408 on the DEVKIT_VIC408) using wolfSSL's | ||
| public-key (PK) callbacks. The private key never leaves the chip. | ||
|
|
||
| ## What it does | ||
|
|
||
| `wolfcrypt/src/port/sealsq/vaultic.c` provides: | ||
|
|
||
| * `WOLFSSL_VAULTIC_EccSignCb` - ECDSA P-256 sign on the device | ||
| * `WOLFSSL_VAULTIC_EccVerifyCb` - ECDSA P-256 verify on the device | ||
| * `WOLFSSL_VAULTIC_EccKeyGenCb` - ephemeral P-256 key generation on the device | ||
| * `WOLFSSL_VAULTIC_EccSharedSecretCb` - ECDH P-256 shared secret on the device | ||
| * `WOLFSSL_VAULTIC_LoadCertificates` - read the device and CA certificates | ||
| stored on the chip into a `WOLFSSL_CTX` | ||
| * `WOLFSSL_VAULTIC_SetupPkCallbacks` / `WOLFSSL_VAULTIC_SetupPkCallbackCtx` - | ||
| register the callbacks on a `WOLFSSL_CTX` / `WOLFSSL` | ||
|
|
||
| The key-generation and shared-secret (ECDH) callbacks can be compiled out by | ||
| defining `VLT_TLS_NO_ECDH`, matching the vendor library configuration. | ||
|
|
||
| ## Dependencies | ||
|
|
||
| This port is glue only. It requires the external SealSQ **VaultIC-TLS SDK**, | ||
| which provides `vaultic_tls.h` and the `vlt_tls_*` P-256 API that talks to the | ||
| chip. That SDK is distributed by SealSQ and is not part of wolfSSL. | ||
|
|
||
| ## Building | ||
|
|
||
| Enable the port and point the compiler/linker at the vendor SDK: | ||
|
|
||
| ```sh | ||
| ./configure --enable-vaultic \ | ||
| CFLAGS="-I/path/to/VaultIC-TLS/vaultic_tls-4xx/src" \ | ||
| LIBS="-lvaultic_tls_408" | ||
| make | ||
| ``` | ||
|
|
||
| `--enable-vaultic` defines `WOLFSSL_VAULTIC` and enables PK callbacks | ||
| (`HAVE_PK_CALLBACKS`) automatically. The port compiles to nothing when | ||
| `WOLFSSL_VAULTIC` is not defined. | ||
|
|
||
| ### Building the port outside libwolfssl | ||
|
|
||
| Like other wolfSSL port files, `vaultic.c` is meant to be compiled as part of | ||
| libwolfssl (via `--enable-vaultic`), where it inherits the wolfSSL | ||
| configuration through `config.h`. If instead you compile `vaultic.c` in a | ||
| separate target (for example the SealSQ devkit builds it into its own | ||
| `vaultic_wolfssl` library alongside an `add_subdirectory(wolfssl)` CMake | ||
| build), two things are required so the file sees the wolfSSL configuration: | ||
|
|
||
| * Define `WOLFSSL_USE_OPTIONS_H` when compiling `vaultic.c`, so | ||
| `settings.h` pulls in the generated `wolfssl/options.h`. Without it the | ||
| wolfSSL headers fall back to defaults (`ecc_key` is incomplete, | ||
| `ECC_SECP256R1` is undeclared). | ||
| * Enable PK callbacks through the wolfSSL build option | ||
| (autotools `--enable-pkcallbacks`, CMake `WOLFSSL_PKCALLBACKS=yes`), not a | ||
| bare `-DHAVE_PK_CALLBACKS` compile flag. The generated `options.h` contains | ||
| `#undef HAVE_PK_CALLBACKS` for disabled options, which cancels a | ||
| command-line define once `options.h` is included. | ||
|
|
||
| ## Usage | ||
|
|
||
| ```c | ||
| WOLFSSL_CTX* ctx = wolfSSL_CTX_new(wolfTLS_client_method()); | ||
|
|
||
| /* register the VaultIC ECC PK callbacks */ | ||
| WOLFSSL_VAULTIC_SetupPkCallbacks(ctx); | ||
|
|
||
| /* load the device + CA certificates stored on the chip */ | ||
| WOLFSSL_VAULTIC_LoadCertificates(ctx); | ||
|
|
||
| WOLFSSL* ssl = wolfSSL_new(ctx); | ||
| WOLFSSL_VAULTIC_SetupPkCallbackCtx(ssl, NULL); | ||
| /* ... proceed with the TLS handshake ... */ | ||
| ``` | ||
|
|
||
| The VaultIC-TLS SDK must be initialized (`vlt_tls_init()`) before the | ||
| handshake and closed (`vlt_tls_close()`) afterwards; see the SealSQ devkit | ||
| sample applications. | ||
|
|
||
| ## Building and provisioning with the SealSQ devkit | ||
|
|
||
| The SealSQ VaultIC-TLS devkit (for example `DEVKIT_VIC408_TLS_RPI`) drives the | ||
| whole build/provision/run flow with shell scripts. High-level orientation and | ||
| the files that matter: | ||
|
|
||
| * SDK library: `VaultIC-TLS/vaultic_tls/vaultic_tls-4xx/src` (`vaultic_tls.h` | ||
| API, `vaultic_tls_config.h`), on top of the low-level chip library | ||
| `vaultic_tls/vaultic_elib_408` (its Raspberry Pi I2C/SPI drivers live under | ||
| `src/arch/embedded/raspberry/pi3`, e.g. `vaultic_twi_driver.c`). | ||
| * Glue build: `vaultic_tls/vaultic_wolfssl/CMakeLists.txt` compiles this | ||
| port's `vaultic.c` and links it against `wolfssl` and `vaultic_tls_408`. | ||
| * Config: `demos/config.cfg` selects `PRODUCT` (408), `VAULTIC_COMM` | ||
| (`SPI` or `I2C`), and log level. | ||
| * Scripts: `demos/wolfssl/tls_client/scripts` - `install.sh` (set up the | ||
| CMake build trees), `build.sh` (build the perso apps, the glue, and the | ||
| demos), `perso_client_vaultic.sh` (provision the chip), `run_server.sh` and | ||
| `run_client_vaultic.sh` (start the plain server, then the VaultIC client). | ||
|
|
||
| Steps: | ||
|
|
||
| 1. Set `demos/config.cfg` (`PRODUCT=408`, `VAULTIC_COMM=I2C` or `SPI`), then | ||
| run `install.sh` and `build.sh`. Point the glue at a wolfSSL tree that | ||
| contains this port (the devkit's `wolfssl_patch` copy is no longer needed | ||
| once the port is upstream). When the glue compiles `vaultic.c` in its own | ||
| library, apply the two flags from "Building the port outside libwolfssl" | ||
| above. | ||
| 2. Provision the chip once with `perso_client_vaultic.sh`. It runs the | ||
| `perso_tls` app (`vaultic_tls-4xx/apps/perso_tls`) with the device key, | ||
| device cert, and root CA cert from `VaultIC-TLS/certificates` | ||
| (`deviceKey.der`, `deviceCert.der`, `rootCACert.der`), submitting the | ||
| manufacturer password supplied by your SealSQ FAE, then runs | ||
| `check_tls_perso` (`vaultic_tls-4xx/apps/check_tls_perso`) to read the | ||
| certificates back off the chip and confirm success. | ||
| 3. Run `run_server.sh` in one shell and `run_client_vaultic.sh` in another to | ||
| perform TLS 1.2 and TLS 1.3 handshakes whose ECC operations run on the | ||
| VaultIC. | ||
|
|
||
| ## Raspberry Pi I2C and clock stretching | ||
|
|
||
| This section is about the external VaultIC-TLS SDK's I2C transport on a | ||
| Raspberry Pi, not about the wolfSSL port itself, but it is the most common | ||
| thing that blocks bring-up, so it is documented here. The VaultIC is an I2C | ||
| (or SPI) secure element; when it is attached over I2C it stretches the clock | ||
| (holds SCL low) while it performs internal operations, and the Raspberry Pi | ||
| I2C hardware has long-standing trouble with clock-stretching peripherals. | ||
|
|
||
| Symptoms of the problem are `TWI Send/Receive failure` (status `CF0D`/`CF0F`), | ||
| `Block Protocol WARNING (comm error)` / `resync request` messages, and finally | ||
| `Block Protocol ERROR (too many rsync requests)`. Short exchanges (for example | ||
| reading a status) may succeed while longer, multi-block transfers (for example | ||
| the certificate writes done during personalization) fail. | ||
|
|
||
| ### Raspberry Pi 2/3/4 (BCM I2C) | ||
|
|
||
| The classic workaround is to lower the I2C bus clock so the timing margins are | ||
| wide enough to tolerate the stretching. The VaultIC-TLS SDK's own I2C driver | ||
| tries to do this by writing the BCM I2C `DIV` register directly through | ||
| `/dev/mem` (which is why it wants to be run with `sudo`), using hardcoded | ||
| controller base addresses for the Pi 2/3 (`0x3f804000`) and Pi 4 | ||
| (`0xfe804000`). A bus clock around 50 kHz is typically reliable. | ||
|
|
||
| ### Raspberry Pi 5 (RP1 / DesignWare I2C) - use a bit-banged bus | ||
|
|
||
| The Pi 5 does not work with the SDK's built-in bitrate control: its I2C | ||
| controller lives in the RP1 chip (a Synopsys DesignWare controller behind | ||
| PCIe) at a different address, so the SDK's `/dev/mem` register poke targets a | ||
| controller that is not there and has no effect. Worse, the RP1 DesignWare | ||
| controller itself hangs on the VaultIC's clock stretching during longer | ||
| transfers, reporting `i2c_designware ...: SDA stuck at low` in `dmesg`. | ||
| Lowering `dtparam=i2c_arm_baudrate` (even down to 10 kHz) does not fix this, | ||
| because the failure is the controller mishandling the stretch, not a timing | ||
| margin. | ||
|
|
||
| The reliable fix on the Pi 5 is to drive the same SDA/SCL pins with the | ||
| kernel's software (bit-banged) I2C driver, which polls SCL and therefore | ||
| honours clock stretching correctly. In `/boot/firmware/config.txt`, disable | ||
| the hardware I2C on those pins and add a software bus on GPIO 2 (SDA) and | ||
| GPIO 3 (SCL): | ||
|
|
||
| ``` | ||
| # dtparam=i2c_arm=on | ||
| dtoverlay=i2c-gpio,i2c_gpio_sda=2,i2c_gpio_scl=3,i2c_gpio_delay_us=4 | ||
| ``` | ||
|
|
||
| After rebooting, find the new bus (its `name` reads `i2c-gpio`, for example | ||
| `/dev/i2c-13`) and point the SDK's I2C device path at it (the VaultIC-TLS | ||
| elib hardcodes `/dev/i2c-1` in its Raspberry Pi TWI driver). With the | ||
| bit-banged bus, personalization and full TLS 1.2 / TLS 1.3 handshakes to the | ||
| VaultIC 408 complete with no I2C errors. | ||
|
|
||
| Alternatively, wiring the VaultIC over SPI avoids clock stretching entirely. | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.