|
| 1 | +# wolfSSL FCS offload on Altera Agilex 5 |
| 2 | + |
| 3 | +This guide builds wolfSSL with Secure Device Manager crypto offload, includes |
| 4 | +the result in an Agilex 5 Linux image, deploys that image, and verifies the |
| 5 | +packaged wolfCrypt test on the board. |
| 6 | + |
| 7 | +## Prerequisites |
| 8 | + |
| 9 | +- An Agilex 5 GSRD Yocto build configured for the exact board and release. |
| 10 | +- This `meta-wolfssl` layer in `BBLAYERS`. |
| 11 | +- A kernel exposing `/sys/kernel/fcs_sysfs`. |
| 12 | +- An owner root key hash provisioned in the SDM. |
| 13 | + |
| 14 | +Provisioning is outside this layer's scope. Follow Altera's device-security |
| 15 | +procedure and distinguish recoverable virtual-key programming from permanent |
| 16 | +eFuse programming before changing a board. A virtual owner key is cleared when |
| 17 | +the board loses power and must be reapplied before each cold-boot test. Once an |
| 18 | +owner key is active, boot and FPGA configuration artifacts must be signed by |
| 19 | +that owner. |
| 20 | + |
| 21 | +Run BitBake on a Linux build server with the memory and storage required by the |
| 22 | +GSRD release. Do not run BitBake on the target board. |
| 23 | + |
| 24 | +The 26.1 GSRD source and board-specific build instructions are published in |
| 25 | +Altera's |
| 26 | +[DK-A5E013BM16AEA GSRD guide](https://altera-fpga.github.io/rel-26.1/embedded-designs/agilex-5/e-series/013B/gsrd/ug-gsrd-agx5e-013b/). |
| 27 | +Install `python3-venv` and Kas as described there. If the build server cannot |
| 28 | +install Python packages, the official Kas container is an alternative: |
| 29 | + |
| 30 | +```sh |
| 31 | +docker pull ghcr.io/siemens/kas/kas:4.8 |
| 32 | +``` |
| 33 | + |
| 34 | +The 26.1 GSRD kernel append uses Bash conditionals in a BitBake task that runs |
| 35 | +under `/bin/sh`. Make those conditionals portable before building: |
| 36 | + |
| 37 | +```sh |
| 38 | +sed -i \ |
| 39 | + -e 's/if \[\[/if [/g' \ |
| 40 | + -e 's/\]\]; then/]; then/g' \ |
| 41 | + -e 's/" == "/" = "/g' \ |
| 42 | + meta-altera-fpga/meta-altera-bsp/recipes-kernel/linux/\ |
| 43 | +linux-socfpga-lts_%.bbappend |
| 44 | +``` |
| 45 | + |
| 46 | +Without this correction, `linux-socfpga-lts:do_deploy` reports `[[: not |
| 47 | +found` and selects a nonexistent `fit_agilex5_kernel_no_rbf.its` file. |
| 48 | + |
| 49 | +## Add the layer to an Agilex 5 GSRD build |
| 50 | + |
| 51 | +The 26.1 GSRD for the DK-A5E013BM16AEA uses Kas. Add `meta-wolfssl` to the |
| 52 | +GSRD `kas.yml` or to a Kas configuration fragment: |
| 53 | + |
| 54 | +```yaml |
| 55 | +header: |
| 56 | + version: 17 |
| 57 | + |
| 58 | +repos: |
| 59 | + meta-wolfssl: |
| 60 | + url: https://github.com/wolfSSL/meta-wolfssl.git |
| 61 | + branch: master |
| 62 | + layers: |
| 63 | + .: |
| 64 | + |
| 65 | +local_conf_header: |
| 66 | + wolfssl-altera-fcs: | |
| 67 | + WOLFSSL_ALTERA_FCS = "1" |
| 68 | + WOLFSSL_FCS_PROVIDER = "gsrd-intel-fcs-lib" |
| 69 | + IMAGE_INSTALL:append = " wolfssl wolfcrypttest wolfcryptbenchmark " |
| 70 | +``` |
| 71 | +
|
| 72 | +Save the fragment as `wolfssl-fcs.yml`. Kas configurations can be combined |
| 73 | +without changing the GSRD's supplied `kas.yml`. |
| 74 | + |
| 75 | +For a local `meta-wolfssl` checkout under the GSRD Yocto directory, replace the |
| 76 | +repository URL and branch with: |
| 77 | + |
| 78 | +```yaml |
| 79 | + meta-wolfssl: |
| 80 | + path: meta-wolfssl |
| 81 | + layers: |
| 82 | + .: |
| 83 | +``` |
| 84 | + |
| 85 | +The 26.1 GSRD already provides the required headers and versioned runtime |
| 86 | +library through `gsrd-intel-fcs-lib`. This layer adds the unversioned |
| 87 | +`libFCS.so` linker name required by dependent recipes. Selecting the GSRD |
| 88 | +provider prevents two recipes from installing the same library. A non-GSRD |
| 89 | +build can omit the override and use meta-wolfssl's `libfcs` recipe instead. |
| 90 | + |
| 91 | +```bitbake |
| 92 | +WOLFSSL_FCS_PROVIDER = "gsrd-intel-fcs-lib" |
| 93 | +``` |
| 94 | + |
| 95 | +Use only one provider for `libFCS.so`. |
| 96 | + |
| 97 | +## Build the Agilex 5 image |
| 98 | + |
| 99 | +From the 26.1 DK-A5E013BM16AEA GSRD `software/yocto_linux` directory, build the |
| 100 | +same `gsrd-console-image` target documented by Altera: |
| 101 | + |
| 102 | +```sh |
| 103 | +source venv/bin/activate |
| 104 | +kas build kas.yml:wolfssl-fcs.yml gsrd-console-image |
| 105 | +``` |
| 106 | + |
| 107 | +With the Kas container, run the equivalent command from the same directory: |
| 108 | + |
| 109 | +```sh |
| 110 | +docker run --rm --user "$(id -u):$(id -g)" \ |
| 111 | + -e HOME=/work -v "$PWD:/work" -w /work \ |
| 112 | + ghcr.io/siemens/kas/kas:4.8 \ |
| 113 | + build kas.yml:wolfssl-fcs.yml gsrd-console-image |
| 114 | +``` |
| 115 | + |
| 116 | +The expected SD card image is: |
| 117 | + |
| 118 | +```text |
| 119 | +build/tmp/deploy/images/agilex5e_013b/gsrd-console-image-agilex5e_013b.rootfs.wic |
| 120 | +``` |
| 121 | + |
| 122 | +Fail the validation if that file is absent or empty: |
| 123 | + |
| 124 | +```sh |
| 125 | +test -s build/tmp/deploy/images/agilex5e_013b/\ |
| 126 | +gsrd-console-image-agilex5e_013b.rootfs.wic |
| 127 | +sha256sum build/tmp/deploy/images/agilex5e_013b/\ |
| 128 | +gsrd-console-image-agilex5e_013b.rootfs.wic |
| 129 | +``` |
| 130 | + |
| 131 | +Inspect the partition table and the installed test from an initialized |
| 132 | +OpenEmbedded shell: |
| 133 | + |
| 134 | +```sh |
| 135 | +( |
| 136 | + source poky/oe-init-build-env build |
| 137 | + image=tmp/deploy/images/agilex5e_013b/\ |
| 138 | +gsrd-console-image-agilex5e_013b.rootfs.wic |
| 139 | + native="$(find "$PWD/tmp/work" -type d \ |
| 140 | + -path '*/gsrd-console-image/*/recipe-sysroot-native' \ |
| 141 | + -print -quit)" |
| 142 | + test -n "$native" |
| 143 | + wic ls -n "$native" "$image" |
| 144 | + wolfcrypt_bins="$(wic ls -n "$native" "$image:2/usr/bin/")" |
| 145 | + printf '%s\n' "$wolfcrypt_bins" |
| 146 | + printf '%s\n' "$wolfcrypt_bins" | grep -q 'wolfcrypttest' |
| 147 | + printf '%s\n' "$wolfcrypt_bins" | grep -q 'wolfcryptbenchmark' |
| 148 | + oe-pkgdata-util find-path /usr/bin/wolfcrypttest |
| 149 | +) |
| 150 | +``` |
| 151 | + |
| 152 | +When the image was built with the Kas container, run the same checks through |
| 153 | +`kas shell` so Yocto's native tools retain the `/work` path used at build time: |
| 154 | + |
| 155 | +```sh |
| 156 | +docker run --rm --user "$(id -u):$(id -g)" \ |
| 157 | + -e HOME=/work -v "$PWD:/work" -w /work \ |
| 158 | + ghcr.io/siemens/kas/kas:4.8 \ |
| 159 | + shell kas.yml:wolfssl-fcs.yml -c ' |
| 160 | + image=tmp/deploy/images/agilex5e_013b/\ |
| 161 | +gsrd-console-image-agilex5e_013b.rootfs.wic |
| 162 | + native="$(find "$PWD/tmp/work" -type d \ |
| 163 | + -path "*/gsrd-console-image/*/recipe-sysroot-native" \ |
| 164 | + -print -quit)" |
| 165 | + test -n "$native" |
| 166 | + wic ls -n "$native" "$image" |
| 167 | + wolfcrypt_bins="$(wic ls -n "$native" "$image:2/usr/bin/")" |
| 168 | + printf "%s\n" "$wolfcrypt_bins" |
| 169 | + printf "%s\n" "$wolfcrypt_bins" | grep -q wolfcrypttest |
| 170 | + printf "%s\n" "$wolfcrypt_bins" | grep -q wolfcryptbenchmark |
| 171 | + oe-pkgdata-util find-path /usr/bin/wolfcrypttest |
| 172 | + ' |
| 173 | +``` |
| 174 | + |
| 175 | +The image must contain a FAT boot partition and an ext4 root partition. The |
| 176 | +second `wic ls` command must show both `wolfcrypttest` and |
| 177 | +`wolfcryptbenchmark`, and the package lookup must report `wolfssl`. |
| 178 | + |
| 179 | +Confirm that BitBake also staged the packaged test: |
| 180 | + |
| 181 | +```sh |
| 182 | +test -n "$(find build/tmp/work \ |
| 183 | + -path '*/wolfssl/*/packages-split/*/usr/bin/wolfcrypttest' \ |
| 184 | + -print -quit)" |
| 185 | +``` |
| 186 | + |
| 187 | +## Deploy the image |
| 188 | + |
| 189 | +Power off the board and remove its microSD card. Attach the card to the build |
| 190 | +server, identify the whole device by its capacity, and unmount any mounted |
| 191 | +partitions. Device names vary: USB readers commonly appear as `/dev/sdX`, while |
| 192 | +built-in readers may appear as `/dev/mmcblkN`. The example below uses the |
| 193 | +device observed on the build server; replace it only after checking `lsblk`: |
| 194 | + |
| 195 | +```sh |
| 196 | +image=build/tmp/deploy/images/agilex5e_013b/\ |
| 197 | +gsrd-console-image-agilex5e_013b.rootfs.wic |
| 198 | +card=/dev/mmcblk0 |
| 199 | +
|
| 200 | +lsblk -o NAME,SIZE,TYPE,TRAN,RM,MODEL,MOUNTPOINTS |
| 201 | +test -b "$card" |
| 202 | +for part in $(lsblk -lnpo NAME "$card" | tail -n +2); do |
| 203 | + if findmnt -rn -S "$part" >/dev/null; then |
| 204 | + sudo umount "$part" |
| 205 | + fi |
| 206 | +done |
| 207 | +
|
| 208 | +sudo dd if="$image" of="$card" bs=4M status=progress conv=fsync |
| 209 | +image_size=$(stat -Lc %s "$image") |
| 210 | +sudo cmp -n "$image_size" "$image" "$card" && echo "WIC verified" |
| 211 | +sync |
| 212 | +sudo blockdev --flushbufs "$card" |
| 213 | +``` |
| 214 | + |
| 215 | +Verify the destination with `lsblk` before writing. This operation replaces the |
| 216 | +card contents. Do not use a disk containing the build server's root filesystem. |
| 217 | +Use a spare card or make a full-device backup first if the existing image must |
| 218 | +be recoverable. `cmp` is silent on success; do not remove the card unless it |
| 219 | +returns zero and prints `WIC verified`. A built-in MMC reader may not implement |
| 220 | +the `eject` command. Once the partitions are unmounted and `blockdev` has |
| 221 | +flushed the device, it is safe to remove the card physically. |
| 222 | + |
| 223 | +If the target image enables a package manager and a compatible package feed, |
| 224 | +an incremental update is also valid: |
| 225 | + |
| 226 | +```sh |
| 227 | +bitbake wolfssl wolfcrypttest |
| 228 | +bitbake package-index |
| 229 | +``` |
| 230 | + |
| 231 | +Publish the generated package feed, refresh the target package index, and |
| 232 | +install or upgrade `wolfssl` and `wolfcrypttest` with the target's package |
| 233 | +manager. Do not copy a package from a different machine, tune, C library, or |
| 234 | +Yocto release. |
| 235 | + |
| 236 | +## Verify on the board |
| 237 | + |
| 238 | +Boot the deployed image and confirm that its packaged files are present: |
| 239 | + |
| 240 | +```sh |
| 241 | +test -x /usr/bin/wolfcrypttest |
| 242 | +/lib/ld-linux-aarch64.so.1 --list /usr/bin/wolfcrypttest |
| 243 | +test -e /sys/kernel/fcs_sysfs |
| 244 | +``` |
| 245 | + |
| 246 | +The DHCP address can change after booting a replacement image. Use the serial |
| 247 | +console, the DHCP server's leases, or a local subnet scan to find the target |
| 248 | +rather than assuming its previous address is retained. |
| 249 | + |
| 250 | +The GSRD image does not install `ldd` by default. Invoking the AArch64 dynamic |
| 251 | +loader with `--list` performs the same runtime dependency check without adding |
| 252 | +a diagnostic package to the image. |
| 253 | + |
| 254 | +Run the installed test: |
| 255 | + |
| 256 | +```sh |
| 257 | +/usr/bin/wolfcrypttest |
| 258 | +``` |
| 259 | + |
| 260 | +The run must exit with status 0 and print: |
| 261 | + |
| 262 | +```text |
| 263 | +ALTERA-FCS test passed! |
| 264 | +``` |
| 265 | + |
| 266 | +The Altera subtests require successful hardware operations for RNG, SHA-256, |
| 267 | +and AES. They cannot pass solely through wolfSSL software fallback. Device |
| 268 | +resident ECDSA and ECDH keys and HMAC verification are also exercised. |
| 269 | + |
| 270 | +If only the Altera test fails, check SDM provisioning status `0x85`. Status |
| 271 | +`0x84` indicates session exhaustion and requires a board power cycle. |
| 272 | + |
| 273 | +## Developer-only smoke test |
| 274 | + |
| 275 | +Copying `${B}/wolfcrypt/test/.libs/testwolfcrypt` directly to a running target |
| 276 | +is useful while developing the recipe. It is not the final integration test |
| 277 | +because it bypasses image construction, package installation, and runtime |
| 278 | +dependency resolution. Use the packaged `/usr/bin/wolfcrypttest` flow above |
| 279 | +for release validation. |
0 commit comments