MISO
is an example application that combines the power of the Zig programming language together with a curated selection of services supported by the XDK110 sensor.
zig-build passing means that a binary build is possible. Further testing on target is necessary.
MISO
is not affiliated with LEGIC Identsystems Ltd, the LEGIC XDK Secure Sensor Evaluation Kit, the Rust Foundation or the Rust Project. Furthermore, it's important to note that this codebase should not be used in use cases which have strict safety and/or availability requirements.
The current version of MISO
boasts a set of features, including:
- read configuration files from a SD card,
- provide configuration persistance using non-volatile memory (NVM),
- connect to a designated WiFi AP,
- get a sNTP timestamp from an internet server and run a real-time clock (RTC) with seconds (s) resolution,
- provide a HTTP file download client for firmware updates
- mbedTLS PSK and x509 certificate authentication tested with TLS (MQTTS) and DTLS (COAPS),
- HW Watchdog (7s idle timeout)
- Bootloader with support for MCUBoot firmware containers
Either a binary with LwM2M via secure COAP (DTLS) or MQTT via TLS can be loaded at a time.
- The LwM2M client will do a watchdog reset after approximately 7 minutes.
- The current architecture is dependent on FreeRTOS.
- Current no entropy is being queried when starting MbedTLS functionality.
- Implementation of SimpleLink File Storage
- Stability improvements of the LwM2M client
- Stability improvements of the connection manager
- Memory optimization of statically allocated memory.
- Improvements on documentation.
- Programming via openOCD
- Programming scripts via console
- HTTP deployment script for FW update
- MQTT FW update
For design, and legal reasons, the following hardware capabilities of the XDK110 will not be supported:
- BLE
- Light Sensor
- Acoustic sensor / Microphone AKU340
- Other IP protocols
Download and install the Zig Compiler
This software has been tested using the Windows x86-64Bit 0.11.0, macOS (via brew) and python ziglang builds.
The Arm GNU Toolchain is now optional for building since
MISO
's move topicolibc
.
Install the Arm GNU toolchain if debugging the code is required.
https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads
Picolibc is provided precompiled using the clang compiler on Ubuntu WSL.
Perform a recursive clone:
git clone --recursive https://github.com/FranciscoLlobet/efm32-freertos-zig.git
Alternatively clone and update submodules:
git clone https://github.com/FranciscoLlobet/efm32-freertos-zig.git
cd .\efm32-freertos-zig\
git submodule init
git submodule update
zig build
zig build
will build the binaries for:
And the corresponding elf
files for direct debugger (SWD) deployment.
Links only work in your local system after build
If using the python-based ziglang
package:
python -m ziglang build
The automatization toolchain requires Python 3.x and modules like invoke
/ìnv
, doit
.
Furthermore it also requires a working copy of OpenSSL
See the zig-build.yml
Github workflow for the current automatisation workflow
Get the tooling dependencies
python -m pip install --upgrade pip setuptools wheel -r requirements.txt
inv get-mcuboot-deps
To generate the firmware signing key:
inv private-key
Keep the private key safe.
-
Via invoke:
inv sign-fw-images
-
Via do-it:
doit
- jsmn. Jsmn, a very simple JSON parser.
- Paho MQTT Embedded-C. MQTT v3.1.1 protocol service.
- Wakaama. LWM2M protocol service.
- PicoHTTParser. Tiny HTTP request and response parser.
- BMA2-Sensor-API
- BME280_driver
- BMG160_driver
- BMI160_driver
- BMM150-Sensor-API
Configuration can be loaded via SD card by config.txt
Field | Description | Type | |
---|---|---|---|
wifi.ssid | Wifi WPA2 SSID | String | Mandadory |
wifi.key | Wifi WPA2 SSID Key | String | Mandatory |
lwm2m.endpoint | LWM2M endpoint | String | If LwM2M is compiled |
lwm2m.uri | LWM2M Server Uri | URI String | If LwM2M is compiled |
lwm2m.psk.id | LwM2M DTLS Psk ID | String | Optional |
lwm2m.psk.key | LwM2M DTLS PSK Key | Base64 encoded String | Optional |
ntp.url[] | sNTP server URI/URL | URI String Array | Not implemented |
http.uri | Firmware image URI | URI String | Mandatory |
http.key | Firmware public key | Base64 encoded string | Mandatory |
{
"wifi": {
"ssid": "WIFI_SSID",
"key": "WIFI_KEY"
},
"lwm2m": {
"endpoint": "LWM2M_DEVICE_NAME",
"uri": "coaps://leshan.eclipseprojects.io:5684",
"psk": {
"id": "LWM2M_DTLS_PSK_ID",
"key": "LWM2M_DTLS_PSK_KEY_BASE64"
},
"bootstrap": false,
},
"ntp": {
"url": [
"0.de.pool.ntp.org",
"1.de.pool.ntp.org"
]
},
"mqtt": {
"url": "mqtts://MQTT_BROKER_HOST:8883",
"device": "MQTT_DEVICE_ID",
"username": "MQTT_USER_NAME",
"password": "MQTT_PASSWORD",
"psk": {
"id": "MQTT_PSK_TLS_ID",
"key": "MQTT_PSK_TLS_KEY_BASE64"
},
"cert": {
"client": "MQTT_CERT",
"server_cert": "MQTT_SERVER_C"
}
},
"http": {
"url": "http://HTTP_HOST:80/app.bin",
"key": "APP_PUB_KEY_BASE64"
}
}
MISO
uses elliptic curve cryptography for signature creation and validation of configuration and firmware images using the ECDSA (Eliptic Curve Digital Signature Algorithm).
Parameters:
P-256
Weierstrass curveprime256v1
(OpenSSL)secp256r1
(mbedTLS)
SHA256
hash digest.
The algorithms have been tested using OpenSSL on host (MacOS, Win11) and mbedTLS on target (EFM32/XDK110)
AES-Based Suites
- TLS_PSK_WITH_AES_128_GCM_SHA256
- TLS_PSK_WITH_AES_128_CCM_8
- TLS_PSK_WITH_AES_128_CCM
ECDHE
- TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8
- TLS_ECDHE_ECDSA_WITH_AES_128_CCM
- MBEDTLS_ECP_DP_SECP256R1_ENABLED
To perform a firmware update, the MISO
application needs to fetch an unecrypted firmware image signed in a MCUboot container
These files can be stored in a HTTP server that must support range requests for the downloads. The public key is provided in the configuration file.
The firmware update process takes the firmware container and the locally stored public key to perform the validation.
FW download has been tested on a non-public (https://nginx.org) server.
Some of following actions actions have also corresponding
inv
tasks described previously.
This is an example using openssl. Please keep the private key secret and offline.
openssl ecparam -genkey -name prime256v1 -noout -out fw_private_key.pem
Generate the public key in PEM format.
openssl ec -in fw_private_key.pem -pubout -out fw.pub
openssl ec -in fw_private_key.pem -pubout -outform DER -out fw.der
openssl base64 --in fw.der --out fw.b64
Use the base64 output as a one-line string in the config (http.key
)
Use the MCUBoot imgtool
script to sign and generate the fw container.
The firmware container header is 0x80
(128) bytes long and the start address is currently 0x40000
(256kB)
python .\csrc\mcuboot\mcuboot\scripts\imgtool.py sign -v "0.1.2" -F 0x40000 -R 0xff --header-size 0x80 --pad-header -k .\fw_private_key.pem --overwrite-only --public-key-format full -S 0xB0000 --align 4 .\zig-out\firmware\lwm2m.bin lwm2m_sig.bin
Verify the content of the firmware container.
python .\csrc\mcuboot\mcuboot\scripts\imgtool.py dumpinfo .\lwm2m_sig.bin
For signing the configuration, please create a private key
openssl ecparam -genkey -name prime256v1 -noout -out private_key.pem
openssl ec -in private_key.pem -pubout -out config.pub
private_key.pem
a private key used for signing the configuration.config.pub
a public key used for signing the configuration.config.sig
a signature file.
openssl dgst -sha256 -sign private_key.pem -out config.sig config.txt
Verify Configuration
openssl dgst -sha256 -verify config.pub -signature config.sig config.txt
meson setup --cross-file scripts/cross-clang-thumbv7m-none-eabi-miso.txt --optimization 2 ./build --wipe