diff --git a/.gitignore b/.gitignore index 71084052..91edf706 100644 --- a/.gitignore +++ b/.gitignore @@ -57,3 +57,4 @@ dkms.conf build/ projects/platform/build/ samples/bin/ +pki_certs/ diff --git a/docs/trustedge_zephyr_rtos_build_guide.md b/docs/trustedge_zephyr_rtos_build_guide.md new file mode 100644 index 00000000..7b10fd5b --- /dev/null +++ b/docs/trustedge_zephyr_rtos_build_guide.md @@ -0,0 +1,565 @@ +# TrustEdge Zephyr RTOS Build Guide + +This guide describes how to install Zephyr RTOS support, build TrustEdge for Zephyr, provision the Zephyr flash file system, flash supported boards, and run TrustEdge from the Zephyr shell. + +This guide uses `${TRUSTCORE}` to refer to the TrustCore package root. + +## Scope + +The DigiCert Developer procedure documents these Zephyr targets: + +- `native_sim`, the Zephyr native simulator 64-bit board +- `stm32h745i_disco`, the STM32H745 Discovery Kit +- `esp32s3_devkitc`, the ESP32-S3-DevKitC + +## Before You Begin + +Ensure that you have the following: + +- Ubuntu 64-bit. The minimum version tested is Ubuntu 22.04. +- At least 40 GB of disk space for the Zephyr tools, SDK, dependencies, and build artifacts. +- A TrustCore repository checkout. +- A bootstrap ZIP from DigiCert Device Trust Manager for device provisioning workflows. +- The `trustedge_zephyr.patch` file, located at `${TRUSTCORE}/projects/trustedge/boards/trustedge_zephyr.patch`. + +Set `${TRUSTCORE}` to the root of this TrustCore repository: + +```bash +export TRUSTCORE=/path/to/trustcore +cd ${TRUSTCORE} +``` + +Set `ZEPHYR_BASE` to the Zephyr root folder after Zephyr is installed: + +```bash +export ZEPHYR_BASE=~/zephyrproject/zephyr +``` + +## Install Zephyr + +The Zephyr build script installs Zephyr OS, the required dependencies, and the Zephyr SDK. It also writes Zephyr environment variables to `.bashrc` for TrustEdge development and builds. + +The script automates the Zephyr [Getting Started Guide](https://docs.zephyrproject.org/latest/develop/getting_started/index.html) and [Beyond the Getting Started Guide](https://docs.zephyrproject.org/latest/develop/beyond-GSG.html) setup steps. + +Run the installation from the repository root: + +```bash +cd ${TRUSTCORE} +./scripts/ci/trustedge/ci_trustedge_build_zephyr.sh --zephyr-install +``` + +The current script performs the following setup actions: + +- Updates Ubuntu packages with `sudo apt update` and `sudo apt upgrade -y`. +- Installs system dependencies, including `build-essential`, `git`, `cmake`, `ninja-build`, `gperf`, `ccache`, `dfu-util`, `device-tree-compiler`, `wget`, Python development packages, `libsdl2-dev`, `libmagic1`, `python3-venv`, `libfuse-dev`, and `minicom`. +- Creates a Python virtual environment under `${HOME}/zephyrproject/.venv`. +- Installs `west`. +- Initializes Zephyr from `https://github.com/zephyrproject-rtos/zephyr` at `v4.2.0`. +- Runs `west update` and `west zephyr-export`. +- Installs Python requirements from `projects/trustedge/zephyr_deps/*.txt`. +- Installs the Zephyr SDK under `${HOME}`. +- Appends these environment settings and aliases to `${HOME}/.bashrc`: + - `ZEPHYR_BASE=${HOME}/zephyrproject/zephyr` + - `ZEPHYR_TOOLCHAIN_VARIANT=zephyr` + - `ZEPHYR_SDK_INSTALL_DIR=${HOME}/zephyr-sdk-` + - Zephyr scripts added to `PATH` + - `zephenv` alias for activating the Zephyr virtual environment + +After installation, restart the shell or reload `.bashrc`, then activate the Zephyr virtual environment before using `west`: + +```bash +source ~/.bashrc +zephenv +``` + +## Apply the TrustEdge Zephyr Patch + +Apply `trustedge_zephyr.patch` to the Zephyr tree before building TrustEdge Zephyr applications: + +```bash +cd ${ZEPHYR_BASE} +git apply ${TRUSTCORE}/projects/trustedge/boards/trustedge_zephyr.patch +cd ${TRUSTCORE} +``` + +## Build TrustEdge on Native Sim 64-Bit + +The native simulator flow builds TrustEdge with the Zephyr runtime, places the TrustEdge binary in `bin/trustedge`, and builds the `device_provision` tool that prepares the flash file system. + +Build TrustEdge for `native_sim`: + +```bash +cd ${TRUSTCORE} +./scripts/ci/trustedge/ci_trustedge_build_zephyr.sh --board native_sim +``` + +Add a host entry to /etc/hosts for provisioning: + +```text +127.0.0.1 provision.digicert.com +``` + +Prepare `flash.bin` with the bootstrap ZIP: + +```bash +cd ${TRUSTCORE} +./samples/zephyr_examples/device_provision/provision_flash.sh --bootstrap +``` + +If flash provisioning is skipped, run the helper TCP server so the TrustEdge binary can fetch the bootstrap and file-system ZIP files: + +```bash +cd ${TRUSTCORE} +cd ./samples/zephyr_examples/trustedge_sample/helper +python3 tcp_server.py --bootstrap --filesys +``` + +The file-system ZIP is located at `${TRUSTCORE}/projects/trustedge/trustedge_2.0.2.arm.zip`. + +Run TrustEdge in another terminal: + +```bash +cd ${TRUSTCORE} +./bin/trustedge +``` + +The `trustedge start` command can be issued from another terminal by redirecting it to the UART pseudo-terminal used by `./bin/trustedge`. + +For example: + +```bash +printf 'trustedge start\r' > /dev/pts/16 +``` + +When `./bin/trustedge` starts, it displays the UART pseudo-terminal: + +```text +uart connected to pseudotty: /dev/pts/16 +``` + +You can now test device provisioning and certificate policy handling scenarios. + +### Native Sim REST API Examples + +TrustEdge includes a REST API over HTTPS. Install the additional tools used by the examples: + +```bash +sudo apt install zip unzip +``` + +To load certificates into flash and run TrustEdge: + +```bash +cd ${TRUSTCORE} +./scripts/ci/trustedge/ci_trustedge_build_zephyr.sh --board native_sim +./samples/zephyr_examples/device_provision/provision_flash.sh --load-certs --bootstrap +``` + +This loads the Root CA certificate and the server private key and certificate into flash storage. The Root CA certificate is required for EST when connecting to DigiCert Device Trust Manager. The server key and certificate secure the TLS connection to the TrustEdge REST API server. + +When the Zephyr shell prompt appears, run `trustedge start` before sending REST API requests to TrustEdge. + +Confirm that the REST API is listening before running the HTTPS examples: + +```bash +pgrep -af trustedge +ss -tlnp | grep ':8469' +nc -vz localhost 8469 +openssl s_client -connect localhost:8469 \ + -servername localhost \ + -CAfile ${TRUSTCORE}/pki_certs/rootCA.pem +``` + +The TrustEdge log should show the REST API thread and HTTPS listener, for example: + +```text +Launching agent rest api thread +HTTPS server listening on [https://localhost:8469] +Certificate & Key alias for TLS auth: te-api-server +``` + +If port `8469` is not listening, the REST API has not started yet or TrustEdge failed during initialization. Recheck that `trustedge start` was issued and that flash was provisioned with `--load-certs` so the `te-api-server` certificate and key exist in LittleFS. + +Verify key generation with `curl`: + +```bash +curl --cacert ${TRUSTCORE}/pki_certs/rootCA.pem \ + https://localhost:8469/v1/key/asymmetric \ + -H 'Content-Type: application/json' \ + -d '{ + "keyCertAttributes": { + "outputMode": "buffered", + "algorithm": "rsa+2048", + "keySource": "SW" + } + }' +``` + +Trigger an EST enrollment flow: + +```bash +curl --cacert ${TRUSTCORE}/pki_certs/rootCA.pem \ + https://localhost:8469/v1/certificate/enroll \ + -H 'Content-Type: application/json' \ + -d@${TRUSTCORE}/src/trustedge/test/data/est_request.json +``` + +Inspect the native simulator flash file system with the FUSE-based provisioning tool: + +```bash +cd ${TRUSTCORE} +./samples/zephyr_examples/device_provision/build/zephyr/zephyr.exe +FUSE mounting flash in host flash/ +uart connected to pseudotty: /dev/pts/8 +[00:00:00.000,000] littlefs: littlefs partition at /lfs1 +*** Booting Zephyr OS build v4.2.0 *** +[00:00:00.000,000] littlefs: LittleFS version 2.11, disk version 2.1 +[00:00:00.000,000] littlefs: FS at flash-controller@0:0x100000 is 768 0x1000-byte blocks with 512 cycle +[00:00:00.000,000] littlefs: partition sizes: rd 16 ; pr 16 ; ca 64 ; la 32 +[00:00:00.000,000] app: Total partition size: 12288 bytes +[00:00:00.000,000] app: Available size: 11392 bytes +``` + +In another terminal, inspect the mounted LittleFS directory: + +```bash +$ cd ${TRUSTCORE} +$ tree flash/ +flash +└── lfs1 + ├── bootstrap.zip + ├── etc + │   └── digicert + │   ├── conf + │   │   ├── applied_policy.json + │   │   ├── bootstrap_config.json + │   │   ├── failed_policy.json + │   │   ├── metrics.pb + │   │   ├── pending_policy.json + │   │   ├── processing_policy.json + │   │   └── version.txt + │   ├── keystore + │   │   ├── ca + │   │   │   ├── devtm-integration-account-intermediate-ca.crt + │   │   │   ├── devtm-integration-account-root-ca.crt + │   │   │   ├── DigiCertGlobalRootCA.crt + │   │   │   ├── DigiCertGlobalRootG2.crt + │   │   │   ├── Rendezvous-zone-1-0.crt + │   │   │   └── Rendezvous-zone-2-0.crt + │   │   ├── certs + │   │   │   ├── be_zephy00.crt + │   │   │   └── te-api-server.pem + │   │   ├── conf + │   │   ├── crls + │   │   ├── keys + │   │   │   ├── be_zephy00-key.crt + │   │   │   ├── server_key_gen.pem + │   │   │   └── te-api-server.pem + │   │   ├── psks + │   │   └── req + │   │   └── issued + │   ├── scripts + │   ├── service + │   │   ├── completed + │   │   ├── failed + │   │   ├── processing + │   │   └── request + │   └── trustedge.json + └── tmp + +20 directories, 20 files + +``` + +The `flash/lfs1` tree should include the bootstrap ZIP, the `/etc/digicert` configuration, keystore directories, service directories, logs, and temporary files. + +## Build TrustEdge on STM32H745 Discovery Kit + +Build TrustEdge for the STM32H745 Discovery Kit: + +```bash +cd ${ZEPHYR_BASE} +git apply ${TRUSTCORE}/projects/trustedge/boards/trustedge_zephyr.patch +cd ${TRUSTCORE} +./scripts/ci/trustedge/ci_trustedge_build_zephyr.sh --board stm32h745i_disco +``` + +The build places the TrustEdge binary in `bin/trustedge`. Flash the board from the TrustEdge sample directory: + +```bash +cd ${TRUSTCORE}/samples/zephyr_examples/trustedge_sample +west flash +``` + +Start the TCP server so the device can fetch the file-system and bootstrap files: + +```bash +cd ${TRUSTCORE} +cd ./samples/zephyr_examples/trustedge_sample/helper +python3 tcp_server.py --bootstrap --filesys +``` + +Connect to the UART shell: + +```bash +minicom --device /dev/pts/ +``` + +Start TrustEdge from the UART shell: + +```bash +uart:~$ trustedge start +``` + +Check TrustEdge logs: + +```bash +uart:~$ fs cat /lfs1/log/log.0000 +``` + +Optionally check TrustEdge status and connection state: + +```bash +uart:~$ trustedge status +uart:~$ trustedge state +``` + +## Build TrustEdge on ESP32-S3-DevKitC + +The following ESP32-S3-DevKitC features as tested: + +- Device provisioning workflow with bootstrap certificates +- EST enrollment workflow + +ESP32-S3 requirements and memory notes are as follows: + +- Zephyr version `4.2.0` +- Zephyr SDK version `0.17.2` +- TrustEdge binary size: `1,487,308 bytes`, or approximately 1.5 MB for a full build +- Available flash: approximately 8 MB on ESP32-S3-DevKitC +- Internal RAM: 642 KB total (329 KB + 313 KB), with approximately 512 KB effectively usable + +ESP32-S3 memory usage breakdown: + +| Segment | Used | Available | Usage | +| --- | --- | --- | --- | +| `mcuboot_hdr` | 32 bytes | 32 bytes | 100 percent | +| `metadata` | 80 bytes | 96 bytes | 83.33 percent | +| `FLASH` | 1,487,180 bytes | 8,388,480 bytes | 17.73 percent | +| `iram0_0_seg` | 60,764 bytes | 329 KB | 18.04 percent | +| `dram0_0_seg` | 240,728 bytes | 313 KB | 75.11 percent | +| `irom0_0_seg` | 1,034,314 bytes | 32 MB | 3.08 percent | +| `drom0_0_seg` | 1,356,236 bytes | 32 MB | 4.04 percent | +| `ext_dram_seg` | 5,902,720 bytes | 8 MB | 70.37 percent | +| `ext_iram_seg` | 0 bytes | 8 MB | 0 percent | +| `rtc_iram_seg` | 0 bytes | 8 KB | 0 percent | +| `rtc_slow_seg` | 0 bytes | 8 KB | 0 percent | +| `IDT_LIST` | 0 bytes | 8 KB | 0 percent | + +### ESP32-S3 Prerequisites + +Fetch the Espressif HAL blobs required for networking support: + +```bash +cd ~/zephyrproject +west blobs fetch hal_espressif +``` + +Add the current user to the `dialout` group to access the serial port: + +```bash +sudo usermod -a -G dialout $USER +``` + +Log out and log back in for the group change to take effect. + +After connecting the ESP32-S3 board, verify the serial device. The device is usually `/dev/ttyS*` or `/dev/ttyUSB*`. This guide uses `/dev/ttyUSB0` as an example: + +```bash +/dev/ttyUSB0 +``` + +### ESP32-S3 Build + +Build all required libraries against Zephyr, compile the TrustEdge binary with the Zephyr runtime, and build the provisioning tool: + +```bash +cd ${TRUSTCORE} +./scripts/ci/trustedge/ci_trustedge_build_zephyr.sh --board esp32s3_devkitc --clean +``` + +The ESP32-S3 build process auto-detects `ZEPHYR_HOST_IP` if it is not already set. If detection fails, export the host IP address manually and rerun the command: + +```bash +export ZEPHYR_HOST_IP= +``` + +After a successful ESP32-S3 build, these build directories are created: + +```text +./samples/zephyr_examples/trustedge_sample/build_mcuboot/ +./samples/zephyr_examples/trustedge_sample/build/ +``` + +The current script copies `trustedge.signed.bin` to `bin/trustedge`. + +### ESP32-S3 Flash + +Flash the ESP32-S3 in two stages. + +Navigate to the TrustEdge sample directory: + +```bash +cd ${TRUSTCORE}/samples/zephyr_examples/trustedge_sample +``` + +Flash the MCUboot bootloader: + +```bash +west flash --esp-flash-bootloader build_mcuboot/zephyr/zephyr.bin --esp-boot-address 0x0 +``` + +Flash the TrustEdge binary: + +```bash +west flash +``` + +### ESP32-S3 Run + +Prepare the file-system ZIP for EST enrollment: + +```bash +cd ${TRUSTCORE} +cd ./samples/zephyr_examples/trustedge_sample/helper +./prepare_trustedge_est.sh +``` + +Run the TCP server so the device can fetch the bootstrap and file-system files: + +```bash +python3 tcp_server.py --bootstrap --filesys +``` + +Connect to the ESP32-S3 serial port with `minicom`: + +```bash +sudo minicom -b 115200 -D /dev/ttyUSB0 +``` + +You can find the correct serial port in the output of the `west flash` command. + +From the UART shell, reboot and connect to Wi-Fi: + +```bash +uart:~$ kernel reboot +uart:~$ wifi connect -k -s -p +``` + +Where: + +- `-s ` is the wireless network SSID. +- `-p ` is the wireless network password. +- `-k ` is the key management type. + +Valid `-k` values: + +| Value | Key management type | +| --- | --- | +| `0` | None | +| `1` | WPA2-PSK | +| `2` | WPA2-PSK-256 | +| `3` | SAE-HNP | +| `4` | SAE-H2E | +| `5` | SAE-AUTO | +| `6` | WAPI | +| `7` | EAP-TLS | +| `8` | WEP | +| `9` | WPA-PSK | +| `10` | WPA-Auto-Personal | +| `11` | DPP | + +Start TrustEdge: + +```bash +uart:~$ trustedge start +``` + +Check logs, connection state, and provisioning status: + +```bash +uart:~$ fs cat /lfs1/log/log.0000 +uart:~$ trustedge state +uart:~$ trustedge status +``` + +During device provisioning, a known ESP32 Wi-Fi driver issue might cause the console to hang and drop the connection. If this happens, reconnect to Wi-Fi and restart TrustEdge to complete provisioning: + +```bash +uart:~$ wifi connect -k -s -p +uart:~$ trustedge start +``` + +If Wi-Fi connection fails with error `-120`, reboot the kernel and retry: + +```bash +uart:~$ kernel reboot +uart:~$ wifi connect -k -s -p +``` + +## Zephyr Shell FAQ + +List available TrustEdge commands from the Zephyr shell: + +```bash +uart:~$ trustedge +``` + +The expected subcommands include: + +```text +trustedge - Demo commands +Subcommands: + start : Run TrustEdge. + state : Show TrustEdge state. + status : Show TrustEdge status. + reboot : reboot device. + reset : reset file system. + confirm : confirm image. +``` + +Reset the TrustEdge file system when switching to a different bootstrap or when a clean state is needed: + +```bash +uart:~$ trustedge reset +``` + +## Build Script Reference + +The Zephyr build script is: + +```bash +./scripts/ci/trustedge/ci_trustedge_build_zephyr.sh +``` + +Supported board values in the current script: + +| Board argument | Zephyr board type used by the script | Notes | +| --- | --- | --- | +| `native_sim` | `native_sim/native/64` | Default board. Uses `native_sim_prj.conf` and `boards/flash_size.overlay`. | +| `stm32h745i_disco` | `stm32h745i_disco/stm32h745xx/m7` | Uses STM32 overlay and `stm32_prj.conf`. | +| `esp32s3_devkitc` | `esp32s3_devkitc/esp32s3/procpu` | Builds MCUboot first and uses `esp32s3_prj.conf`. | + +## Final Checklist + +Before using the guide end to end, verify: + +- `${TRUSTCORE}` points to the repository root. +- `ZEPHYR_BASE` points to the Zephyr checkout. +- The Zephyr virtual environment is active and `west` is available. +- `trustedge_zephyr.patch` has been applied to the Zephyr tree. +- The bootstrap ZIP path is correct. +- The board is connected and visible to the host before flashing. +- For ESP32-S3, `hal_espressif` blobs are fetched and the current user has serial-port access. +- For REST API checks, the Root CA certificate exists at `${TRUSTCORE}/pki_certs/rootCA.pem`. +- For REST API checks, the native_sim flash image was provisioned with `--load-certs` and `trustedge start` has been issued from the Zephyr shell. diff --git a/projects/trustedge/boards/trustedge_zephyr.patch b/projects/trustedge/boards/trustedge_zephyr.patch new file mode 100755 index 00000000..daaffb1a --- /dev/null +++ b/projects/trustedge/boards/trustedge_zephyr.patch @@ -0,0 +1,67 @@ +diff --git a/boards/native/native_sim/native_sim.dts b/boards/native/native_sim/native_sim.dts +index 162fcf07457..48fe6402074 100644 +--- a/boards/native/native_sim/native_sim.dts ++++ b/boards/native/native_sim/native_sim.dts +@@ -61,7 +61,7 @@ + + flashcontroller0: flash-controller@0 { + compatible = "zephyr,sim-flash"; +- reg = <0x00000000 DT_SIZE_K(2048)>; ++ reg = <0x00000000 DT_SIZE_K(4096)>; + + #address-cells = <1>; + #size-cells = <1>; +@@ -72,7 +72,7 @@ + compatible = "soc-nv-flash"; + erase-block-size = <4096>; + write-block-size = <1>; +- reg = <0x00000000 DT_SIZE_K(2048)>; ++ reg = <0x00000000 DT_SIZE_K(4096)>; + + partitions { + compatible = "fixed-partitions"; +diff --git a/dts/arm/st/h7/stm32h745.dtsi b/dts/arm/st/h7/stm32h745.dtsi +index 294fd02c502..871343b6667 100644 +--- a/dts/arm/st/h7/stm32h745.dtsi ++++ b/dts/arm/st/h7/stm32h745.dtsi +@@ -19,7 +19,7 @@ + /* maximum erase time for a 128K sector */ + max-erase-time = <4000>; + }; +- flash1: flash@8100000 { ++ flash1: flash@81FFC00 { + compatible = "st,stm32-nv-flash", "soc-nv-flash"; + write-block-size = <32>; + erase-block-size = ; +diff --git a/dts/arm/st/h7/stm32h745Xi_m4.dtsi b/dts/arm/st/h7/stm32h745Xi_m4.dtsi +index 8ad4e0f871e..3f8446eaa9a 100644 +--- a/dts/arm/st/h7/stm32h745Xi_m4.dtsi ++++ b/dts/arm/st/h7/stm32h745Xi_m4.dtsi +@@ -16,9 +16,9 @@ + + soc { + flash-controller@52002000 { +- flash1: flash@8100000 { +- reg = <0x08100000 DT_SIZE_K(1024)>; +- bank2-flash-size = <1024>; ++ flash1: flash@81FFC00 { ++ reg = <0x081FFC00 DT_SIZE_K(1)>; ++ bank2-flash-size = <1>; + }; + }; + +diff --git a/dts/arm/st/h7/stm32h745Xi_m7.dtsi b/dts/arm/st/h7/stm32h745Xi_m7.dtsi +index 0e79c0150f3..e059bdbfd8a 100644 +--- a/dts/arm/st/h7/stm32h745Xi_m7.dtsi ++++ b/dts/arm/st/h7/stm32h745Xi_m7.dtsi +@@ -23,7 +23,9 @@ + soc { + flash-controller@52002000 { + flash0: flash@8000000 { +- reg = <0x08000000 DT_SIZE_K(1024)>; ++ erase-block-size = <4096>; ++ write-block-size = <1>; ++ reg = <0x08000000 DT_SIZE_K(2047)>; + }; + }; + diff --git a/projects/trustedge/zephyr/initialize_sources.txt b/projects/trustedge/zephyr/initialize_sources.txt index d1ee88f5..faa0cf2d 100644 --- a/projects/trustedge/zephyr/initialize_sources.txt +++ b/projects/trustedge/zephyr/initialize_sources.txt @@ -1,4 +1,4 @@ MSS_SRC_DIR/common/initmocana.c MSS_SRC_DIR/common/mocana.c -MSS_SRC_DIR/examples/custom_entropy.c -MSS_SRC_DIR/examples/external_rand_thread.c +MSS_SRC_DIR/../samples/common/custom_entropy.c +MSS_SRC_DIR/../samples/common/external_rand_thread.c diff --git a/samples/common/custom_entropy.c b/samples/common/custom_entropy.c index 2412b220..892cad63 100644 --- a/samples/common/custom_entropy.c +++ b/samples/common/custom_entropy.c @@ -18,7 +18,7 @@ * *Contact DigiCert at sales@digicert.com for more details.* */ -#include "../common/moptions.h" +#include "../../src/common/moptions.h" #ifdef __ENABLE_DIGICERT_CUSTOM_ENTROPY_INJECT__ diff --git a/samples/common/external_rand_thread.c b/samples/common/external_rand_thread.c index d7c04f6e..1c32cb3d 100644 --- a/samples/common/external_rand_thread.c +++ b/samples/common/external_rand_thread.c @@ -14,7 +14,7 @@ * *Contact DigiCert at sales@digicert.com for more details.* */ -#include "../common/moptions.h" +#include "../../src/common/moptions.h" #ifdef __DIGICERT_FORCE_ENTROPY__ #ifndef __DISABLE_DIGICERT_ADD_ENTROPY__ #include "../common/mdefs.h" diff --git a/samples/trustedge/BUILD_RUN.md b/samples/trustedge/BUILD_RUN.md index 3cdd0a47..7d9640ec 100644 --- a/samples/trustedge/BUILD_RUN.md +++ b/samples/trustedge/BUILD_RUN.md @@ -85,6 +85,10 @@ If you need to add or configure a new TrustEdge cross-compilation toolchain, use If you need to integrate TrustEdge into a Yocto/Poky-based embedded Linux image, use the detailed Yocto guide instead of duplicating setup steps here. For guidance on creating a custom TrustEdge layer, adding the TrustEdge recipe, building the image, and running TrustEdge in QEMU, see [TrustEdge Yocto Build Guide](../../docs/trustedge_yocto_build_guide.md). +### Building with Zephyr RTOS + +If you need to install, build, provision, flash, or run TrustEdge with Zephyr RTOS, use the detailed Zephyr guide instead of duplicating board-specific setup here. For guidance on the Zephyr environment, supported boards, native simulator flow, STM32H745 Discovery Kit flow, ESP32-S3-DevKitC flow, and validation commands, see [TrustEdge Zephyr RTOS Build Guide](../../docs/trustedge_zephyr_rtos_build_guide.md). + ### Windows From the Visual Studio developer environment, run the Windows build script: diff --git a/samples/zephyr_examples/crypto_sample/CMakeLists.txt b/samples/zephyr_examples/crypto_sample/CMakeLists.txt index be693bbc..78e611c9 100644 --- a/samples/zephyr_examples/crypto_sample/CMakeLists.txt +++ b/samples/zephyr_examples/crypto_sample/CMakeLists.txt @@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(fs_shell) -set(MSS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../..") +set(MSS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../..") set(MSS_SRC_DIR "${MSS_DIR}/src") set(TRUSTCORE_LIB_DIR "${MSS_DIR}/bin_static") diff --git a/samples/zephyr_examples/device_provision/provision_flash.sh b/samples/zephyr_examples/device_provision/provision_flash.sh index ab727fc9..5aa4a1a4 100755 --- a/samples/zephyr_examples/device_provision/provision_flash.sh +++ b/samples/zephyr_examples/device_provision/provision_flash.sh @@ -1,5 +1,6 @@ #!/usr/bin/env bash +set -euo pipefail set -m show_usage() @@ -9,15 +10,113 @@ show_usage() echo " --help - Build options information." } -SCRIPT_DIR=$( cd $(dirname $0) ; pwd -P ) -MSS_DIR=${SCRIPT_DIR}/../../../.. +SCRIPT_DIR=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P ) +MSS_DIR=$( cd "${SCRIPT_DIR}/../../.." ; pwd -P ) +TRUSTEDGE_ZIP="${MSS_DIR}/projects/trustedge/trustedge_2.0.2.arm.zip" BOOTSTRAP_PATH="" LOAD_CERTS=0 +PROVISION_PID="" + +cleanup_on_exit() +{ + local exit_code=$? + + trap - EXIT INT TERM + + if [ ${exit_code} -ne 0 ] && [ -n "${PROVISION_PID}" ] && kill -0 "${PROVISION_PID}" 2>/dev/null; then + kill "${PROVISION_PID}" 2>/dev/null || true + wait "${PROVISION_PID}" 2>/dev/null || true + fi + + exit ${exit_code} +} + +make_absolute_path() +{ + local input_path="$1" + local input_dir + local input_file + + input_dir=$(dirname -- "${input_path}") + input_file=$(basename -- "${input_path}") + + printf '%s/%s\n' "$( cd "${input_dir}" ; pwd -P )" "${input_file}" +} + +download_file() +{ + local output_path="$1" + local url="$2" + + if command -v curl >/dev/null 2>&1; then + curl -fsSL -o "${output_path}" "${url}" + elif command -v wget >/dev/null 2>&1; then + wget -q -O "${output_path}" "${url}" + else + echo "Error: neither curl nor wget found. Please install one of them." + return 1 + fi +} + +prepare_server_certs() +{ + local cert_dir="${MSS_DIR}/pki_certs" + local ext_file="${cert_dir}/server.ext" + + mkdir -p "${cert_dir}" + + download_file "${cert_dir}/DigiCertGlobalRootG2.crt" "https://cacerts.digicert.com/DigiCertGlobalRootG2.crt" + download_file "${cert_dir}/DigiCertGlobalRootCA.crt" "https://cacerts.digicert.com/DigiCertGlobalRootCA.crt" + + if [ -f "${cert_dir}/server.pem" ] && [ -f "${cert_dir}/server.key" ]; then + return 0 + fi + + if ! command -v openssl >/dev/null 2>&1; then + echo "Error: openssl is required to generate native_sim REST API server certificates." + return 1 + fi + + openssl req -x509 -newkey rsa:2048 -sha256 -days 365 -nodes \ + -keyout "${cert_dir}/rootCA.key" \ + -out "${cert_dir}/rootCA.pem" \ + -subj "/CN=TrustEdge native_sim local root CA" + + openssl req -newkey rsa:2048 -nodes \ + -keyout "${cert_dir}/server.key" \ + -out "${cert_dir}/server.csr" \ + -subj "/CN=localhost" + + chmod 600 "${cert_dir}/rootCA.key" "${cert_dir}/server.key" + + cat > "${ext_file}" </dev/null rm -rf flash 2>/dev/null || true rm -f flash.bin 2>/dev/null || true +rm -rf etc/ 2>/dev/null || true ${SCRIPT_DIR}/build/zephyr/zephyr.exe & -bg %1 +PROVISION_PID=$! echo "provision flash drive.." sleep 2 -unzip ./projects/trustedge/trustedge_2.0.2.arm.zip +if [ ! -d flash/lfs1 ]; then + echo "flash/lfs1 was not created by device_provision" + exit 1 +fi + +unzip -q "${TRUSTEDGE_ZIP}" + +if [ ! -d etc ]; then + echo "${TRUSTEDGE_ZIP} did not extract an etc/ directory" + exit 1 +fi cp -r etc/ flash/lfs1/ rm -rf etc/ -cp -r "${BOOTSTRAP_PATH}" flash/lfs1/bootstrap.zip +cp "${BOOTSTRAP_PATH}" flash/lfs1/bootstrap.zip if [ ${LOAD_CERTS} -eq 1 ]; then - rm -rf pki_certs 2>/dev/null || true - wget -P ./pki_certs https://cacerts.digicert.com/DigiCertGlobalRootG2.crt - wget -P ./pki_certs https://cacerts.digicert.com/DigiCertGlobalRootCA.crt - cp ./pki_certs/server.pem flash/lfs1/etc/digicert/keystore/certs/te-api-server.pem - cp ./pki_certs/server.key flash/lfs1/etc/digicert/keystore/keys/te-api-server.pem - cp ./pki_certs/DigiCertGlobalRoot* flash/lfs1/etc/digicert/keystore/ca/ + prepare_server_certs + cp "${MSS_DIR}/pki_certs/server.pem" flash/lfs1/etc/digicert/keystore/certs/te-api-server.pem + cp "${MSS_DIR}/pki_certs/server.key" flash/lfs1/etc/digicert/keystore/keys/te-api-server.pem + cp "${MSS_DIR}"/pki_certs/DigiCertGlobalRoot* flash/lfs1/etc/digicert/keystore/ca/ fi rm -rf etc/ 2>/dev/null || true -popd || true +popd >/dev/null echo "returning to foreground" -fg %1 +wait "${PROVISION_PID}" diff --git a/samples/zephyr_examples/network_sample/CMakeLists.txt b/samples/zephyr_examples/network_sample/CMakeLists.txt index dcd98441..ef8f3666 100644 --- a/samples/zephyr_examples/network_sample/CMakeLists.txt +++ b/samples/zephyr_examples/network_sample/CMakeLists.txt @@ -15,7 +15,7 @@ endif() find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(fs_shell) -set(MSS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../..") +set(MSS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../..") set(MSS_SRC_DIR "${MSS_DIR}/src") set(TRUSTCORE_LIB_DIR "${MSS_DIR}/bin_static") diff --git a/samples/zephyr_examples/ota_handler_sample/CMakeLists.txt b/samples/zephyr_examples/ota_handler_sample/CMakeLists.txt index bc4a229e..6f69cad0 100644 --- a/samples/zephyr_examples/ota_handler_sample/CMakeLists.txt +++ b/samples/zephyr_examples/ota_handler_sample/CMakeLists.txt @@ -6,7 +6,7 @@ find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(trustedge_sample C) -set(MSS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../..") +set(MSS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../..") set(MSS_SRC_DIR "${MSS_DIR}/src") set(TRUSTCORE_LIB_DIR "${MSS_DIR}/bin_static") diff --git a/samples/zephyr_examples/trustedge_sample/CMakeLists.txt b/samples/zephyr_examples/trustedge_sample/CMakeLists.txt index 4f0a30f8..2b189a71 100644 --- a/samples/zephyr_examples/trustedge_sample/CMakeLists.txt +++ b/samples/zephyr_examples/trustedge_sample/CMakeLists.txt @@ -27,7 +27,7 @@ find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(trustedge_sample C) -set(MSS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../..") +set(MSS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../..") set(MSS_SRC_DIR "${MSS_DIR}/src") set(TRUSTCORE_LIB_DIR "${MSS_DIR}/bin_static") diff --git a/samples/zephyr_examples/trustedge_sample/src/main.c b/samples/zephyr_examples/trustedge_sample/src/main.c index 05909f02..b3841ad1 100644 --- a/samples/zephyr_examples/trustedge_sample/src/main.c +++ b/samples/zephyr_examples/trustedge_sample/src/main.c @@ -43,7 +43,7 @@ #endif /* #include "common/mrtos.h" */ #include "common/mfmgmt.h" -#include "trustedge/trustedge_main.h" +#include "trustedge_main.h" #if !defined(__ENABLE_DIGICERT_NATIVE_SIM__) #include "dns.h" diff --git a/scripts/ci/trustedge/ci_trustedge_build_zephyr.bat b/scripts/ci/trustedge/ci_trustedge_build_zephyr.bat index 4190c617..e72c35ec 100644 --- a/scripts/ci/trustedge/ci_trustedge_build_zephyr.bat +++ b/scripts/ci/trustedge/ci_trustedge_build_zephyr.bat @@ -5,7 +5,7 @@ SETLOCAL ENABLEDELAYEDEXPANSION set SCRIPT_DIR=%~dp0 set ROOT_DIR=%SCRIPT_DIR%\..\..\.. -set "EXAMPLE_DIR=%ROOT_DIR%/src/examples/zephyr_examples" +set "EXAMPLE_DIR=%ROOT_DIR%/samples/zephyr_examples" set BUILD_TYPE="Release" set FMGMT_SAMPLE=0 @@ -138,15 +138,15 @@ if %BUILD_TRUSTEDGE_LIB%==1 ( if %APP_SAMPLE%==0 ( echo "building trustedge sample" - set "SAMPLE_DIR=%ROOT_DIR%\src\examples\zephyr_examples\trustedge_sample\" + set "SAMPLE_DIR=%ROOT_DIR%\samples\zephyr_examples\trustedge_sample\" ) if %APP_SAMPLE%==1 ( echo "building tests sample" - set "SAMPLE_DIR=%ROOT_DIR%\src\examples\zephyr_examples\network_sample\" + set "SAMPLE_DIR=%ROOT_DIR%\samples\zephyr_examples\network_sample\" ) if %APP_SAMPLE%==2 ( echo "building OTA sample" - set "SAMPLE_DIR=%ROOT_DIR%\src\examples\zephyr_examples\trustedge_dfu_handler_sample\" + set "SAMPLE_DIR=%ROOT_DIR%\samples\zephyr_examples\ota_handler_sample\" ) echo sample directory: !SAMPLE_DIR! diff --git a/scripts/ci/trustedge/ci_trustedge_build_zephyr.sh b/scripts/ci/trustedge/ci_trustedge_build_zephyr.sh index 882c20b2..71abf00a 100755 --- a/scripts/ci/trustedge/ci_trustedge_build_zephyr.sh +++ b/scripts/ci/trustedge/ci_trustedge_build_zephyr.sh @@ -3,7 +3,7 @@ set -e SCRIPT_DIR=$( cd $(dirname $0) ; pwd -P ) ROOT_DIR=${SCRIPT_DIR}/../../.. -EXAMPLE_DIR=${ROOT_DIR}/src/examples/zephyr_examples +EXAMPLE_DIR=${ROOT_DIR}/samples/zephyr_examples ZEPHYR_DEPS_DIR=${ROOT_DIR}/projects/trustedge/zephyr_deps MSS_SRC_DIR=${ROOT_DIR}/src @@ -94,7 +94,7 @@ run_setup() { echo "export ZEPHYR_BASE=${ZEPHYR_INSTALL_DIR}/zephyrproject/zephyr" >> ${HOME}/.bashrc echo "export ZEPHYR_TOOLCHAIN_VARIANT=zephyr" >> ${HOME}/.bashrc echo "export ZEPHYR_SDK_INSTALL_DIR=\"${ZEPHYR_INSTALL_DIR}/zephyr-sdk-`cat SDK_VERSION`\"" >> ${HOME}/.bashrc - echo "export PATH=${ZEPHYR_INSTALL_DIR}/zephyrproject/scripts:$PATH" >> ${HOME}/.bashrc + echo "export PATH=\"${ZEPHYR_INSTALL_DIR}/zephyrproject/scripts:\$PATH\"" >> ${HOME}/.bashrc echo "alias zephenv='source ${ZEPHYR_INSTALL_DIR}/zephyrproject/.venv/bin/activate'" >> ${HOME}/.bashrc echo "Zephyr installed in ${ZEPHYR_INSTALL_DIR}" echo "IMPORTANT: Run command \"zephenv\" to use west and other utilitis and run \"deactivate\" when done." @@ -434,7 +434,7 @@ if [ ${TRUSTEDGE_SAMPLE} -eq 1 ]; then echo "combine bootloader and application into one image.." pushd "${MCUBOOT_PATH}" - python scripts/assemble.py -b "${MCUBOOT_PATH}/boot/zephyr/build/" -p ${ROOT_DIR}/src/examples/zephyr_examples/trustedge_sample/build/zephyr/trustedge.signed.bin -o ${ROOT_DIR}/bin/trustedge_with_mcuboot.bin + python scripts/assemble.py -b "${MCUBOOT_PATH}/boot/zephyr/build/" -p ${ROOT_DIR}/samples/zephyr_examples/trustedge_sample/build/zephyr/trustedge.signed.bin -o ${ROOT_DIR}/bin/trustedge_with_mcuboot.bin popd fi @@ -446,7 +446,7 @@ if [ ${TRUSTEDGE_SAMPLE} -eq 1 ]; then popd rm -f ${ROOT_DIR}/bin_static/libtrustedge.so 2>/dev/null || true - echo "build dir => src/examples/zephyr_examples/trustedge_sample/build/" + echo "build dir => samples/zephyr_examples/trustedge_sample/build/" if [ "native_sim" == "${BOARD_ARG}" ]; then if [ -f ${TRUSTEDGE_SAMPLE_DIR}/build/zephyr/trustedge.exe ]; then @@ -457,10 +457,15 @@ if [ ${TRUSTEDGE_SAMPLE} -eq 1 ]; then exit 1 fi - #echo "building provisioning tool" - #pushd ${EXAMPLE_DIR}/device_provision - #west build -b ${BOARD_TYPE} -p -- -DCONFIG_FUSE_FS_ACCESS=y -DDTC_OVERLAY_FILE="${BOARD_OVERLAY}" - #popd + echo "building provisioning tool" + pushd ${EXAMPLE_DIR}/device_provision + west build -b ${BOARD_TYPE} -p -- -DCONFIG_FUSE_FS_ACCESS=y -DDTC_OVERLAY_FILE="${BOARD_OVERLAY}" + popd + + if [ ! -f ${EXAMPLE_DIR}/device_provision/build/zephyr/zephyr.exe ]; then + echo "could not find ${EXAMPLE_DIR}/device_provision/build/zephyr/zephyr.exe" + exit 1 + fi elif [ "stm32h745i_disco" == "${BOARD_ARG}" ]; then if [ -f ${TRUSTEDGE_SAMPLE_DIR}/build/zephyr/trustedge.bin ]; then @@ -525,17 +530,22 @@ if [ ${TRUSTEDGE_SAMPLE} -eq 2 ]; then fi if [ ${TRUSTEDGE_SAMPLE} -eq 3 ]; then - UNITTEST_SAMPLE_DIR=${EXAMPLE_DIR}/trustedge_dfu_handler_sample + UNITTEST_SAMPLE_DIR=${EXAMPLE_DIR}/ota_handler_sample echo "building OTA sample application" - if [ "native" == "${BOARD_ARG}" ]; then - FINAL_BIN_NAME="trustedge.exe" - CMAKE_ARGS="-DCONFIG_NET_NO_REBOOT=y" - elif [ "stm32" == "${BOARD_ARG}" ]; then - FINAL_BIN_NAME="trustedge.bin" - CMAKE_ARGS="" - fi + case "${BOARD_ARG}" in + native_sim) + FINAL_BIN_NAME="trustedge.exe" + ;; + stm32h745i_disco|nucleo_h745zi_q) + FINAL_BIN_NAME="trustedge.bin" + ;; + *) + echo "ota_handler_sample does not support board: ${BOARD_ARG}" + exit 1 + ;; + esac pushd "${UNITTEST_SAMPLE_DIR}" west build -b ${BOARD_TYPE} -p --build-dir "${UNITTEST_SAMPLE_DIR}/build" -- -DDTC_OVERLAY_FILE="${BOARD_OVERLAY}" -DEXTRA_CONF_FILE="${BOARD_CONF_FILE}" -DIMAGE_NAME="OTA sample" @@ -543,8 +553,8 @@ if [ ${TRUSTEDGE_SAMPLE} -eq 3 ]; then echo "build dir => ${UNITTEST_SAMPLE_DIR}/build/" if [ -f "${UNITTEST_SAMPLE_DIR}/build/zephyr/${FINAL_BIN_NAME}" ]; then - cp "${UNITTEST_SAMPLE_DIR}/build/zephyr/${FINAL_BIN_NAME}" "${ROOT_DIR}/bin/network_sample" - echo "binary location => bin/network_sample" + cp "${UNITTEST_SAMPLE_DIR}/build/zephyr/${FINAL_BIN_NAME}" "${ROOT_DIR}/bin/ota_handler_sample" + echo "binary location => bin/ota_handler_sample" else echo "could not find ${FINAL_BIN_NAME}" exit 1