Use Altera's libfcs recipes and document the wolfSSL master pin for Agilex 5
parent
774b1c2f61
commit
854d48cb0a
|
|
@ -55,13 +55,13 @@ BBFILES += "${LAYERDIR}/recipes-wolfssl/wolfssl/*.bb \
|
|||
# xilinx-bootbin bbappend requires meta-xilinx-tools layer
|
||||
BBFILES_DYNAMIC += "xilinx-tools:${LAYERDIR}/recipes-bsp/bootbin/*.bbappend"
|
||||
|
||||
# Enable with WOLFSSL_ALTERA_FCS = "1" in the build configuration.
|
||||
# Enable with WOLFSSL_ALTERA_FCS = "1" in the build configuration. libfcs comes
|
||||
# from an Altera layer (gsrd-intel-fcs-lib or socfpga-intel-fcs-lib) or the user.
|
||||
WOLFSSL_ALTERA_FCS ?= "0"
|
||||
WOLFSSL_FCS_PROVIDER ?= "libfcs"
|
||||
WOLFSSL_FCS_PROVIDER ?= "gsrd-intel-fcs-lib"
|
||||
WOLFSSL_ALTERA_FCS_BBFILES = \
|
||||
"${LAYERDIR}/recipes-support/libfcs/libfcs_git.bb \
|
||||
${LAYERDIR}/recipes-support/libfcs/wolfssl_%.bbappend \
|
||||
${@'${LAYERDIR}/recipes-support/libfcs/gsrd-intel-fcs-lib_%.bbappend' if d.getVar('WOLFSSL_FCS_PROVIDER') == 'gsrd-intel-fcs-lib' else ''}"
|
||||
"${LAYERDIR}/recipes-support/libfcs/wolfssl_%.bbappend \
|
||||
${LAYERDIR}/recipes-support/libfcs/${WOLFSSL_FCS_PROVIDER}_%.bbappend"
|
||||
BBFILES += "${@d.getVar('WOLFSSL_ALTERA_FCS_BBFILES') if d.getVar('WOLFSSL_ALTERA_FCS') == '1' else ''}"
|
||||
|
||||
# Uncomment if building bind with wolfSSL.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,15 @@ packaged wolfCrypt test on the board.
|
|||
|
||||
- An Agilex 5 GSRD Yocto build configured for the exact board and release.
|
||||
- This `meta-wolfssl` layer in `BBLAYERS`.
|
||||
- A kernel exposing `/sys/kernel/fcs_sysfs`.
|
||||
- A layer that builds Altera's libfcs. The 26.1 GSRD's `meta-altera-fpga`
|
||||
provides `gsrd-intel-fcs-lib`, and `meta-intel-fpga-refdes` provides
|
||||
`socfpga-intel-fcs-lib`. A user recipe that installs the libfcs headers and
|
||||
`libFCS.so` also works.
|
||||
- A wolfSSL revision that contains the Agilex 5 port. wolfSSL 5.9.4 predates
|
||||
it; see [Use a wolfSSL revision with the Agilex 5 port](#use-a-wolfssl-revision-with-the-agilex-5-port).
|
||||
- A kernel exposing `/sys/kernel/fcs_sysfs/platform`. libfcs reads that file
|
||||
during initialization. Older Altera kernels such as linux-socfpga 6.12.19
|
||||
create `/sys/kernel/fcs_sysfs` without it, and libfcs then fails to start.
|
||||
- An owner root key hash provisioned in the SDM.
|
||||
|
||||
Provisioning is outside this layer's scope. Follow Altera's device-security
|
||||
|
|
@ -67,6 +75,9 @@ local_conf_header:
|
|||
WOLFSSL_ALTERA_FCS = "1"
|
||||
WOLFSSL_FCS_PROVIDER = "gsrd-intel-fcs-lib"
|
||||
IMAGE_INSTALL:append = " wolfssl wolfcrypttest wolfcryptbenchmark "
|
||||
# Remove after the first wolfSSL release that contains the Agilex 5 port.
|
||||
SRC_URI:pn-wolfssl = "git://github.com/wolfssl/wolfssl.git;nobranch=1;protocol=https"
|
||||
SRCREV:pn-wolfssl = "c177f861d0ecba3a998e1cae3d18d21103572aed"
|
||||
```
|
||||
|
||||
Save the fragment as `wolfssl-fcs.yml`. Kas configurations can be combined
|
||||
|
|
@ -82,17 +93,39 @@ repository URL and branch with:
|
|||
.:
|
||||
```
|
||||
|
||||
The 26.1 GSRD already provides the required headers and versioned runtime
|
||||
library through `gsrd-intel-fcs-lib`. This layer adds the unversioned
|
||||
`libFCS.so` linker name required by dependent recipes. Selecting the GSRD
|
||||
provider prevents two recipes from installing the same library. A non-GSRD
|
||||
build can omit the override and use meta-wolfssl's `libfcs` recipe instead.
|
||||
meta-wolfssl does not build libfcs itself. `WOLFSSL_FCS_PROVIDER` names the
|
||||
recipe that does, and defaults to the 26.1 GSRD's `gsrd-intel-fcs-lib`. Altera's
|
||||
recipes install only the versioned runtime library, so this layer appends the
|
||||
unversioned `libFCS.so` linker name to `gsrd-intel-fcs-lib` and
|
||||
`socfpga-intel-fcs-lib`. Builds using `meta-intel-fpga-refdes` select its
|
||||
recipe instead:
|
||||
|
||||
```bitbake
|
||||
WOLFSSL_FCS_PROVIDER = "gsrd-intel-fcs-lib"
|
||||
WOLFSSL_FCS_PROVIDER = "socfpga-intel-fcs-lib"
|
||||
```
|
||||
|
||||
Use only one provider for `libFCS.so`.
|
||||
A user supplied recipe must install `libFCS.so` itself. The port has been
|
||||
validated with libfcs 3.01, the revision built by the 26.1 GSRD.
|
||||
|
||||
## Use a wolfSSL revision with the Agilex 5 port
|
||||
|
||||
The `--enable-alterafcs` option this layer passes exists only in wolfSSL
|
||||
releases after 5.9.4. Until the next release, add a bbappend to your own layer,
|
||||
for example `recipes-wolfssl/wolfssl/wolfssl_%.bbappend`, that builds a wolfSSL
|
||||
master commit containing the port:
|
||||
|
||||
```bitbake
|
||||
# Remove after the first wolfSSL release that contains the Agilex 5 port.
|
||||
SRC_URI = "git://github.com/wolfssl/wolfssl.git;nobranch=1;protocol=https"
|
||||
SRCREV = "c177f861d0ecba3a998e1cae3d18d21103572aed"
|
||||
```
|
||||
|
||||
Keep the revision in `SRCREV`, not as `rev=` in the URL. The `%` append also
|
||||
matches meta-openembedded's `wolfssl` recipe, which sets its own `SRCREV`, and a
|
||||
`rev=` parameter would then conflict with it during parsing. The same two
|
||||
assignments can be placed in `local.conf` or a Kas `local_conf_header` as
|
||||
`SRC_URI:pn-wolfssl` and `SRCREV:pn-wolfssl`. Without them, `do_configure`
|
||||
fails on the unrecognized option.
|
||||
|
||||
## Build the Agilex 5 image
|
||||
|
||||
|
|
@ -113,76 +146,65 @@ docker run --rm --user "$(id -u):$(id -g)" \
|
|||
build kas.yml:wolfssl-fcs.yml gsrd-console-image
|
||||
```
|
||||
|
||||
The expected SD card image is:
|
||||
|
||||
```text
|
||||
build/tmp/deploy/images/agilex5e_013b/gsrd-console-image-agilex5e_013b.rootfs.wic
|
||||
```
|
||||
|
||||
Fail the validation if that file is absent or empty:
|
||||
|
||||
```sh
|
||||
test -s build/tmp/deploy/images/agilex5e_013b/\
|
||||
gsrd-console-image-agilex5e_013b.rootfs.wic
|
||||
sha256sum build/tmp/deploy/images/agilex5e_013b/\
|
||||
gsrd-console-image-agilex5e_013b.rootfs.wic
|
||||
```
|
||||
|
||||
Inspect the partition table and the installed test from an initialized
|
||||
OpenEmbedded shell:
|
||||
The SD card image is written to BitBake's `DEPLOY_DIR_IMAGE`. Its parent
|
||||
`TMPDIR` depends on the distribution: Kas 4.x selects `poky` and uses
|
||||
`build/tmp`, while Kas 5.x defaults to `nodistro` and uses `build/tmp-glibc`.
|
||||
Ask BitBake for the directory instead of assuming either. From the same
|
||||
`software/yocto_linux` directory, inspect the image and the installed test in an
|
||||
initialized OpenEmbedded shell:
|
||||
|
||||
```sh
|
||||
(
|
||||
source poky/oe-init-build-env build
|
||||
image=tmp/deploy/images/agilex5e_013b/\
|
||||
gsrd-console-image-agilex5e_013b.rootfs.wic
|
||||
native="$(find "$PWD/tmp/work" -type d \
|
||||
-path '*/gsrd-console-image/*/recipe-sysroot-native' \
|
||||
-print -quit)"
|
||||
test -n "$native"
|
||||
set -e
|
||||
source poky/oe-init-build-env build >/dev/null
|
||||
deploy="$(bitbake-getvar --value DEPLOY_DIR_IMAGE)"
|
||||
image="$deploy/gsrd-console-image-agilex5e_013b.rootfs.wic"
|
||||
test -s "$image"
|
||||
sha256sum "$image"
|
||||
native="$(bitbake-getvar -r gsrd-console-image --value RECIPE_SYSROOT_NATIVE)"
|
||||
test -d "$native"
|
||||
wic ls -n "$native" "$image"
|
||||
wolfcrypt_bins="$(wic ls -n "$native" "$image:2/usr/bin/")"
|
||||
printf '%s\n' "$wolfcrypt_bins"
|
||||
printf '%s\n' "$wolfcrypt_bins" | grep -q 'wolfcrypttest'
|
||||
printf '%s\n' "$wolfcrypt_bins" | grep -q 'wolfcryptbenchmark'
|
||||
oe-pkgdata-util find-path /usr/bin/wolfcrypttest
|
||||
printf 'image=%s\n' "$image"
|
||||
)
|
||||
```
|
||||
|
||||
When the image was built with the Kas container, run the same checks through
|
||||
`kas shell` so Yocto's native tools retain the `/work` path used at build time:
|
||||
When the image was built with the Kas container, run the same commands, without
|
||||
the `source` line, through `kas shell` so Yocto's native tools retain the
|
||||
`/work` path used at build time:
|
||||
|
||||
```sh
|
||||
docker run --rm --user "$(id -u):$(id -g)" \
|
||||
-e HOME=/work -v "$PWD:/work" -w /work \
|
||||
ghcr.io/siemens/kas/kas:4.8 \
|
||||
shell kas.yml:wolfssl-fcs.yml -c '
|
||||
image=tmp/deploy/images/agilex5e_013b/\
|
||||
gsrd-console-image-agilex5e_013b.rootfs.wic
|
||||
native="$(find "$PWD/tmp/work" -type d \
|
||||
-path "*/gsrd-console-image/*/recipe-sysroot-native" \
|
||||
-print -quit)"
|
||||
test -n "$native"
|
||||
set -e
|
||||
deploy="$(bitbake-getvar --value DEPLOY_DIR_IMAGE)"
|
||||
image="$deploy/gsrd-console-image-agilex5e_013b.rootfs.wic"
|
||||
test -s "$image"
|
||||
sha256sum "$image"
|
||||
native="$(bitbake-getvar -r gsrd-console-image \
|
||||
--value RECIPE_SYSROOT_NATIVE)"
|
||||
test -d "$native"
|
||||
wic ls -n "$native" "$image"
|
||||
wolfcrypt_bins="$(wic ls -n "$native" "$image:2/usr/bin/")"
|
||||
printf "%s\n" "$wolfcrypt_bins"
|
||||
printf "%s\n" "$wolfcrypt_bins" | grep -q wolfcrypttest
|
||||
printf "%s\n" "$wolfcrypt_bins" | grep -q wolfcryptbenchmark
|
||||
oe-pkgdata-util find-path /usr/bin/wolfcrypttest
|
||||
printf "image=%s\n" "$image"
|
||||
'
|
||||
```
|
||||
|
||||
The image must contain a FAT boot partition and an ext4 root partition. The
|
||||
second `wic ls` command must show both `wolfcrypttest` and
|
||||
`wolfcryptbenchmark`, and the package lookup must report `wolfssl`.
|
||||
|
||||
Confirm that BitBake also staged the packaged test:
|
||||
|
||||
```sh
|
||||
test -n "$(find build/tmp/work \
|
||||
-path '*/wolfssl/*/packages-split/*/usr/bin/wolfcrypttest' \
|
||||
-print -quit)"
|
||||
```
|
||||
The container reports paths under `/work`, which is the current directory on
|
||||
the host. Either block must exit with status 0. The image must contain a FAT
|
||||
boot partition and an ext4 root partition, the second `wic ls` command must
|
||||
show both `wolfcrypttest` and `wolfcryptbenchmark`, and the package lookup must
|
||||
report `wolfssl`. Keep the printed `image` path and SHA-256 for deployment.
|
||||
|
||||
## Deploy the image
|
||||
|
||||
|
|
@ -190,11 +212,11 @@ Power off the board and remove its microSD card. Attach the card to the build
|
|||
server, identify the whole device by its capacity, and unmount any mounted
|
||||
partitions. Device names vary: USB readers commonly appear as `/dev/sdX`, while
|
||||
built-in readers may appear as `/dev/mmcblkN`. The example below uses the
|
||||
device observed on the build server; replace it only after checking `lsblk`:
|
||||
device observed on the build server; replace it only after checking `lsblk`.
|
||||
Set `image` to the absolute path printed by the inspection step:
|
||||
|
||||
```sh
|
||||
image=build/tmp/deploy/images/agilex5e_013b/\
|
||||
gsrd-console-image-agilex5e_013b.rootfs.wic
|
||||
image=/path/printed/by/inspection/gsrd-console-image-agilex5e_013b.rootfs.wic
|
||||
card=/dev/mmcblk0
|
||||
|
||||
lsblk -o NAME,SIZE,TYPE,TRAN,RM,MODEL,MOUNTPOINTS
|
||||
|
|
@ -240,9 +262,13 @@ Boot the deployed image and confirm that its packaged files are present:
|
|||
```sh
|
||||
test -x /usr/bin/wolfcrypttest
|
||||
/lib/ld-linux-aarch64.so.1 --list /usr/bin/wolfcrypttest
|
||||
test -e /sys/kernel/fcs_sysfs
|
||||
test -r /sys/kernel/fcs_sysfs/platform
|
||||
```
|
||||
|
||||
If `/sys/kernel/fcs_sysfs/platform` is missing, the kernel is too old for the
|
||||
libfcs build in the image. libfcs fails to initialize and `wolfcrypttest`
|
||||
skips the hardware test, so a zero exit status alone does not prove offload.
|
||||
|
||||
The DHCP address can change after booting a replacement image. Use the serial
|
||||
console, the DHCP server's leases, or a local subnet scan to find the target
|
||||
rather than assuming its previous address is retained.
|
||||
|
|
@ -267,7 +293,8 @@ The Altera subtests require successful hardware operations for RNG, SHA-256,
|
|||
and AES. They cannot pass solely through wolfSSL software fallback. Device
|
||||
resident ECDSA and ECDH keys and HMAC verification are also exercised.
|
||||
|
||||
If only the Altera test fails, check SDM provisioning status `0x85`. Status
|
||||
If the marker is missing, first confirm `/sys/kernel/fcs_sysfs/platform`
|
||||
exists. If only the Altera test fails, check SDM provisioning status `0x85`. Status
|
||||
`0x84` indicates session exhaustion and requires a board power cycle.
|
||||
|
||||
## Developer-only smoke test
|
||||
|
|
|
|||
|
|
@ -1,13 +1 @@
|
|||
# The Agilex 5 GSRD recipe installs only the versioned runtime library. Add the
|
||||
# development linker name so dependent recipes can use -lFCS from their
|
||||
# recipe-specific sysroots.
|
||||
do_install:append() {
|
||||
if [ -e ${D}${prefix}/lib/libFCS.so.3 ]; then
|
||||
install -d ${D}${libdir}
|
||||
if [ "${libdir}" = "${prefix}/lib" ]; then
|
||||
ln -sfn libFCS.so.3 ${D}${libdir}/libFCS.so
|
||||
else
|
||||
ln -sfn ../lib/libFCS.so.3 ${D}${libdir}/libFCS.so
|
||||
fi
|
||||
fi
|
||||
}
|
||||
require libfcs-linker-name.inc
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
# Altera's libfcs recipes install only the versioned runtime library. Add the
|
||||
# linker name so dependent recipes can use -lFCS from their sysroots.
|
||||
do_install:append() {
|
||||
for lib in ${D}${prefix}/lib/libFCS.so.[0-9]*; do
|
||||
[ -e "$lib" ] || continue
|
||||
name="$(basename "$lib")"
|
||||
install -d ${D}${libdir}
|
||||
if [ "${libdir}" = "${prefix}/lib" ]; then
|
||||
ln -sfn "$name" ${D}${libdir}/libFCS.so
|
||||
else
|
||||
ln -sfn "../lib/$name" ${D}${libdir}/libFCS.so
|
||||
fi
|
||||
break
|
||||
done
|
||||
}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
SUMMARY = "Altera FPGA Crypto Services library"
|
||||
DESCRIPTION = "Userspace library for the FPGA Crypto Services of Altera \
|
||||
SoCFPGA devices, exposing the Secure Device Manager crypto mailbox through \
|
||||
/sys/kernel/fcs_sysfs."
|
||||
HOMEPAGE = "https://github.com/altera-fpga/libfcs"
|
||||
LICENSE = "MIT-0"
|
||||
LIC_FILES_CHKSUM = "file://LICENSE;md5=6f25b4c3a6d23285f956387ab54830ad"
|
||||
|
||||
SRC_URI = "git://github.com/altera-fpga/libfcs.git;protocol=https;branch=main"
|
||||
SRCREV = "87b4b726f4981be102fc8f09feab051fe3578334"
|
||||
PV = "3.01+git"
|
||||
|
||||
DEPENDS = "dtc"
|
||||
|
||||
COMPATIBLE_HOST = "aarch64.*-linux"
|
||||
|
||||
python () {
|
||||
if d.getVar('UNPACKDIR', False):
|
||||
d.setVar('S', '${UNPACKDIR}/${BP}')
|
||||
else:
|
||||
d.setVar('S', '${WORKDIR}/git')
|
||||
}
|
||||
|
||||
inherit cmake
|
||||
|
||||
EXTRA_OECMAKE = "-DARCH=linux_aarch64"
|
||||
|
||||
# upstream install() destinations are relative, so they nest under ${prefix}
|
||||
wolfssl_fcs_fixup_install() {
|
||||
if [ -d ${D}${prefix}${prefix} ]; then
|
||||
cp -a ${D}${prefix}${prefix}/. ${D}${prefix}/
|
||||
rm -rf ${D}${prefix}${prefix}
|
||||
fi
|
||||
|
||||
# libfcs hardcodes /usr/lib. Move the library to Yocto's configured libdir,
|
||||
# then supply the linker name expected by consumers such as wolfSSL.
|
||||
if [ "${prefix}/lib" != "${libdir}" ] && \
|
||||
[ -e ${D}${prefix}/lib/libFCS.so.3 ]; then
|
||||
install -d ${D}${libdir}
|
||||
mv ${D}${prefix}/lib/libFCS.so.3 ${D}${libdir}/
|
||||
rmdir ${D}${prefix}/lib
|
||||
fi
|
||||
if [ -e ${D}${libdir}/libFCS.so.3 ]; then
|
||||
ln -sfn libFCS.so.3 ${D}${libdir}/libFCS.so
|
||||
fi
|
||||
}
|
||||
|
||||
do_install[postfuncs] += "wolfssl_fcs_fixup_install"
|
||||
|
|
@ -0,0 +1 @@
|
|||
require libfcs-linker-name.inc
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
# Altera Agilex 5 SDM crypto offload; needs an FCS provisioned device at
|
||||
# runtime. GSRD stacks that already build the library can point this at
|
||||
# their own recipe, e.g. WOLFSSL_FCS_PROVIDER = "gsrd-intel-fcs-lib".
|
||||
# runtime. WOLFSSL_FCS_PROVIDER names the recipe that supplies libfcs.
|
||||
|
||||
def wolfssl_fcs_is_target(d):
|
||||
return (d.getVar('CLASSOVERRIDE') == 'class-target' and
|
||||
(d.getVar('HOST_SYS') or '').startswith('aarch64-'))
|
||||
return (d.getVar('WOLFSSL_ALTERA_FCS') == '1' and
|
||||
'class-target' in (d.getVar('OVERRIDES') or '').split(':') and
|
||||
(d.getVar('TARGET_ARCH') or '') == 'aarch64')
|
||||
|
||||
WOLFSSL_FCS_CONFIGURE = "${@'--enable-alterafcs --enable-aesctr' if wolfssl_fcs_is_target(d) else ''}"
|
||||
WOLFSSL_FCS_DEPENDS = "${@d.getVar('WOLFSSL_FCS_PROVIDER') if wolfssl_fcs_is_target(d) else ''}"
|
||||
|
|
@ -13,8 +13,9 @@ EXTRA_OECONF += "${WOLFSSL_FCS_CONFIGURE}"
|
|||
DEPENDS += "${WOLFSSL_FCS_DEPENDS}"
|
||||
|
||||
python () {
|
||||
if (d.getVar('CLASSOVERRIDE') == 'class-target' and
|
||||
if (d.getVar('WOLFSSL_ALTERA_FCS') == '1' and
|
||||
'class-target' in (d.getVar('OVERRIDES') or '').split(':') and
|
||||
not d.getVar('MLPREFIX') and
|
||||
not (d.getVar('HOST_SYS') or '').startswith('aarch64-')):
|
||||
(d.getVar('TARGET_ARCH') or '') != 'aarch64'):
|
||||
bb.fatal('WOLFSSL_ALTERA_FCS requires an AArch64 target')
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue