Breadcrumbs

swubuilder

A host tool to generate SWU update package for SWUpdate.

Used to modify and recreate the swu file offline

Create SWU file

The builder-*.tar archive contains all the files required to create an SWU file without a Yocto environment. It essentially comprises all components, the key files known at build time and the swu-builder tool for creating the SWU file. The functions of swu-builder are described below.

swu-builder

swu-builder is a bash script with the following functions:

  • Allows you to customize individual image components in a .swu file. This is helpful if, for example, the root file system component is to be extended with its own files.

  • Versioning of the individual components

  • Customization of the partition layout

  • Signing the .swu file with your own key

  • Encryption of the individual components and the sw-description file with a separate key

The script requires root rights or must be executed with fakeroot. Below is the command line syntax of swu-builder:

Bash
$ bash swu-builder -h
Usage: swu-builder --conf=CONFFILE SWUFILE [-- ARG1 ARG2 ...]
       swu-builder -h|--help
  This tool generates a SWU file based on the configuration file.
OPTIONS:
  -- ARG1 ARG2 ...
    parameters passed to the external signing tool
  --conf=CONFFILE
    configuration file to use
  -h, --help
    display this help message

The configuration file (parameter --conf) can be used to control the creation of the .swu file. The configuration is carried out using variables in the format VARIABLE=“VALUE”.

Variable

Description

SWUPDATE_DESCRIPTION

Defines the 'description' property in the .swu file.

SWUPDATE_BORDNAME

Defines the name of the board. The name is saved in the /etc/hwrevision file and in the SWU file in the sw-description. SWUpdate uses the values for the compatibility check of the .swu file.

SWUPDATE_BORDREV

Defines the revision of the board. The revision is saved in the /etc/hwrevision and sw-description files. SWUpdate uses the values for the compatibility check of the .swu file.

SWUPDATE_HWCOMPATIBILITY

Defines the string to be used for the HW compatibility in the sw-description file, default is “#RE:.*”, i.e. the SWU image created is compatible for all board revisions.

SWUPDATE_COMPATIBILITY

Specifies the minimum major version of the update system with which the SWU file to be created should be compatible. The update system is downward compatible with older SWU files. The value of the variable is an integer. For example: If SWUPDATE_COMPATIBILITY = “1” is set, the SWU file created is supported by the update system from version 1.0.0, but not by versions 0.x.x.
The version of the update system can be queried at runtime with swu-info version.

SWUPDATE_PRIVATE_KEY

This variable defines the path name of the file with the private key. The key is required to create the signed .swu files.

SWUPDATE_PASSWORD_FILE

This variable defines the path name of the file with the passphrase.

SWUPDATE_SIGNINGTOOL

Name of the external signing tool, if not defined openssl is used.

SWUPDATE_ENCRYPT_FILE

Path name of the file with the symmetric key and the initialization vector (IV). This key is used to encrypt the components and the sw-description file.

SWU_IMAGES_FILENAME[{extra|rootfs|rescue|bootloader|bootenv|sram}]

Defines the file name to be used for the corresponding component.

SWU_IMAGES_VERSION[{extra|rootfs|rescue|bootloader|bootenv|sram}]

Defines the version of the corresponding component. The version string must be in semantic format.

SWU_IMAGES_ENCRYPTED[{extra|rootfs|rescue|bootloader|bootenv|sram}]

Defines whether the corresponding component is added to the SWU file encrypted (true) or unencrypted (false, default). The symmetric key in the SWUPDATE_ENCRYPT_FILE file is used for encryption. The component is only encrypted if SWU_IMAGES_ENCRYPTED = “true” and the key file (SWUPDATE_ENCRYPT_FILE) is defined.

SWUPDATE_TARGET_DECRYPT_KEYFILE

Path name of the file with the symmetric key and the initialization vector (IV). swu-builder installs this key in the corresponding component. This means that after successful installation, SWUpdate uses this key for decryption.

SWUPDATE_TARGET_PUBLIC_KEYFILE

Path name of the file with the public RSA key. swu-builder installs this key in the corresponding component. This means that after successful installation, SWUpdate uses this key to check the signing.

Example of a configuration file:


# swu-builder configuration file
# SWUpdate strategy
SWU_SYSTEM="single-rescue"
# Defines description property in sw-description file
SWUPDATE_DESCRIPTION="01088 0A - Linux WPC 6x Web"
# Defines the name of the board. SWUpdate uses the values for the compatibility check of the swu file
SWUPDATE_BORDNAME="KCH-11758"
# Defines the revision of the board. SWUpdate uses the values for the compatibility check of the swu file
SWUPDATE_BORDREV="1.0.0"
# Defines the string to be used for HW revision compatibility check
SWUPDATE_HWCOMPATIBILITY="#RE:.*"
# Defines the minimum version of the Update System to which the swu file must be compatible
SWUPDATE_COMPATIBILITY="2"
# Private RSA swu key file in PEM format for signing the swu file
SWUPDATE_PRIVATE_KEY="swu-priv.pem"
# Passphrase file for private RSA swu key
SWUPDATE_PASSWORD_FILE="swu-pw.txt"
# name of external signing tool (openssl is used by default)
# builder calls the external signing tool:
#     <infile>:  name of input file to create the signature
#     <outfile>: name of output signature file
#     <args...>: forwarded parameters from swu-builder cmdline
#SWUPDATE_SIGNINGTOOL="/path/to/external/signing/tool"
# name of the AES key file to encrypt components
SWUPDATE_ENCRYPT_FILE="encryption.key"
# Defines the file name, version and encrypted flag to be used for the corresponding component
SWU_IMAGES_FILENAME[rootfs]="base-rootfs.tar.gz.enc"
SWU_IMAGES_VERSION[rootfs]="1.0.0"
SWU_IMAGES_ENCRYPTED[rootfs]="true"
SWU_IMAGES_FILENAME[rescue]="base-rescue.tar.gz2.enc"
SWU_IMAGES_VERSION[rescue]="2.2.1"
SWU_IMAGES_ENCRYPTED[rescue]="true"
SWU_IMAGES_FILENAME[bootloader]="bootloader.bin.enc"
SWU_IMAGES_VERSION[bootloader]="1.0.0"
SWU_IMAGES_ENCRYPTED[bootloader]="true"
SWU_IMAGES_FILENAME[bootenv]="base-bootenv.enc"
SWU_IMAGES_VERSION[bootenv]="1.0.0"
SWU_IMAGES_ENCRYPTED[bootenv]="true"
#SWU_IMAGES_FILENAME[extra]=""
#SWU_IMAGES_VERSION[extra]="0.0.0"
#SWU_IMAGES_ENCRYPTED[extra]="false"
#SWU_IMAGES_SPEC[extra]=""
# name of the AES key file used by SWUpdate to decrypt components
# swu-builder updates the key file in the components to be installed
SWUPDATE_TARGET_DECRYPT_KEYFILE="encryption.key"
# Public RSA key file in PEM format used by SWUpdate to verify the swu file
# swu-builder updates the key file in the components to be installed
SWUPDATE_TARGET_PUBLIC_KEYFILE="swu-public.pem"
Signing

By default, the SWU file is signed with a dummy private key and the device has the corresponding dummy public key. However, to increase security, the SWU file can be signed with its own key. RSA encryption is used to verify the SWU file: The private key is used to sign the file, while the public key is used for verification during installation.

The following commands create a key pair for RSA-2048:

echo "my-password" > swu-pw.txt
openssl genrsa -aes256 -passout file:swu-pw.txt -out swu-priv.pem 2048
openssl rsa -in swu-priv.pem -passin file:swu-pw.txt -outform PEM -out swu-public.pem -pubout

To create a key pair for RSA4096, the parameter 2048 must be replaced with 4096.

To sign the SWU file with swu-builder, the following variables must be adjusted in the configuration file:

SWUPDATE_PRIVATE_KEY="swu-priv.pem"
SWUPDATE_PASSWORD_FILE="swu-pw.txt"
SWUPDATE_TARGET_PUBLIC_KEYFILE="swu-public.pem"

The swu-builder requires the files with the private key (swu-priv.pem) and the passphrase (swu-pw.txt) to sign the SWU file. The public key file under SWUPDATE_TARGET_PUBLIC_KEYFILE is integrated into the corresponding component by the SWU-Builder so that the key becomes active after successful installation. The variable SWUPDATE_TARGET_PUBLIC_KEYFILE can therefore be used to exchange the public key in the system.

Encryption

The individual components of an SWU file are not encrypted by default. However, the data can be protected with symmetric AES encryption.

The following commands create a symmetric key file with a key length of 256 bits. However, you can also use other key lengths:

openssl enc -aes-256-cbc -k "my-password" -P -md sha1 -nosalt > encryption.key

To encrypt the SWU components with swu-builder, the following variables must be adjusted in the configuration file:

SWU_IMAGES_ENCRYPTED[{extra|rootfs|rescue|bootloader|bootenv|sram}]="true"      # bestimmt ob die Komponente verschlüsselt (true) oder unverschlüsselt (false) zur SWU-Datei eingebunden wird 
SWUPDATE_ENCRYPT_FILE="encryption.key"
SWUPDATE_TARGET_DECRYPT_KEYFILE="encryption.key"

The swu-builder requires the file with the symmetric key (SWUPDATE_ENCRYPT_FILE) to encrypt the components. The key file under SWUPDATE_TARGET_DECRYPT_KEYFILE is integrated into the corresponding component by swu-builder so that the key becomes active after successful installation. The variable SWUPDATE_TARGET_DECRYPT_KEYFILE can therefore be used to exchange a symmetric key in the system.

Partitioning

An installation script and a configuration script are required to create the SWU file. Both scripts are integrated into the SWU file by swu-builder. The installation script is executed during the installation by SWUpdate. The configuration script is platform-dependent and enables the configuration of the general, platform-independent installation script.
There is a predefined configuration script for each strategy. The names of the scripts are templates/v2/install.{single|single-rescue|double}.conf.

For example, the script for the single-rescue strategy:

# install.sh script configuration
declare -A instcfg=(
	# bootloader
	[bootloader_partname]="^u-boot$"
	# rescue partition
	[rescue_dev]="/dev/mmcblk0p1"
	[rescue_fslabel]="rescue"
	# rootfs partition
	[rootfs_dev]="/dev/mmcblk0p2"
	[rootfs_fslabel]="rootfs"
	# information to create partitions
	[part_dev]="/dev/mmcblk0"
	[part_cfg]="part_emmc"
)
# eMMC partition layout
# 48MB      rescueOS part
# xMB       rootfs part
# 24MB      swu-data part
declare -A part_emmc=(
	[part_type]="msdos"
	[end_gap]=$((5*MB))
	[p1_start]=${MB} [p1_size]=$((48*MB)) [p1_type]=primary [p1_fstype]=ext4 [p1_fslabel]=rescue
	                 [p2_size]=0          [p2_type]=primary [p2_fstype]=ext4 [p2_fslabel]=rootfs
	                 [p3_size]=$((24*MB)) [p3_type]=primary [p3_fstype]=ext4 [p3_fslabel]=swu-data
)
# location of u-boot environment in nor flash
# note: the environment location must not change, otherwise an update with SWUpdate is no more possible
case "$(cat /sys/devices/soc0/soc_id)" in
	"i.MX8MP")
		instcfg[bootloader_env_offset]="0x1E8000"         # must match CONFIG_ENV_OFFSET 
		instcfg[bootloader_env_offset_redund]="0x1EC000"  # must match CONFIG_ENV_OFFSET_REDUND
		instcfg[bootloader_env_size]="0x4000"             # must match CONFIG_ENV_SIZE
		;;
	"i.MX8MM")
		instcfg[bootloader_env_offset]="0xf8000"          # must match CONFIG_ENV_OFFSET 
		instcfg[bootloader_env_offset_redund]="0xfb000"   # must match CONFIG_ENV_OFFSET_REDUND
		instcfg[bootloader_env_size]="0x3000"             # must match CONFIG_ENV_SIZE
		;;
	*)
		instcfg[bootloader_env_size]="0"
esac


The partitioning of the eMMC is configured with the variable part_emmc. The following example adds an extra 512MB partition to the image:

declare -A part_emmc=(
	[part_type]="msdos"
	[end_gap]=$((5*MB))
	[p1_start]=${MB} [p1_size]=$((48*MB))  [p1_type]=primary [p1_fstype]=ext4 [p1_fslabel]=rescue
	                 [p2_size]=0           [p2_type]=primary [p2_fstype]=ext4 [p2_fslabel]=rootfs
					 [p3_size]=$((512*MB)) [p3_type]=primary [p3_fstype]=ext4 [p3_fslabel]=extra
	                 [p4_size]=$((24*MB))  [p4_type]=primary [p4_fstype]=ext4 [p4_fslabel]=swu-data
)