Package: punchboot
IntroductionPunchboot is a secure and fast bootloader for embedded systems. It is designed to:Boot as fast as possibleIntegrate with the SoC's secure boot functionalityAuthenticate the next piece of software in the boot chainSupport A/B system partitions for atomic updatesSupport automatic rollbacksMinimize software download time in productionBe useful for day-to-day developmentPunchboot is designed for embedded systems and therefore it has a minimalistic
apporach. There is no run-time configuration, everything is configured in
the board files.Punchboot could be useful if you care about the following:Boot speedSecure bootDownloading software quickly in productionDesignPunchboot is written in C and some assembler. Currently armv7a and armv8 is supported.The directory layout is as follows:FolderDescription/docDocumentation/pkiCrypto keys for testing/Bootloader source/src/boardBoard support/src/archArchitecture support/src/platPlatform support/src/driversDrivers/toolsToolsSupported architectures:ArchitectureSupportedarmv7aYesarmv8aYesarmv7mYesSupported platforms:PlatformSupportedUSBEMMCHW CryptoSecure BootFuseboxNXP imx6ulYesYesYesYesYesYesNXP imx8mYesYesYesYesNoYesNXP imx8xYesYesYesYesYesYesSupported boards:BoardSupportedMore infoJiffyFully supportedhttps://github.com/jonasblixt/jiffyBebopFully supportedhttps://github.com/jonasblixt/bebopTechnexion PICO-IMX8MPartial supporthttps://www.technexion.com/products/system-on-modules/pico/pico-compute-modules/detail/PICO-IMX8MNXP IMX8QXP MEKFully supportedhttps://www.nxp.com/products/processors-and-microcontrollers/arm-based-processors-and-mcus/i.mx-applications-processors/i.mx-8-processors/i.mx-8-multisensory-enablement-kit:i.MX8-MEKHardware accelerated signature verificationPlatformRSA4096EC secp256r1EC secp384r1EC secp521NXP imx6ulYesYesNoNoNXP imx8mYesYesNoNonxp imx8xyesyesyesyesnxp imx RTnonononoHardware accelerated hash algorithmsPlatformMD5SHA256SHA384SHA512NXP imx6ulYesYesNoNoNXP imx8mYesYesNoNoNXP imx8xYesYesYesYesNXP imx RTNoNoNoNoSecure BootTypical and simplified secure boot flowROM loads a set of public keys, calculates the checksum of the keys and compares the result to a fused checksumROM loads punchboot, calculates checksum and verifies signature using key's in step oneRun punchbootPunchboot loads a PBI bundle, calculates the checksum and verifies the signature using built in keysRun next step in boot chainMost SoC:s have a boot rom that includes meachanisms for calculating a checksum
of the bootloader and cryptographically verifying a signature using a public key
fused to the device.Normally fuses are a limited resource and therefor a common way is to calculate
a sha256 checksum of the public key(s) and then store this checksum in fuses,
this way many different public keys can be stored in a flash memory and every
time the device boots it will compute a sha256 checksum and compare it to the
fused checksum.Punchboot is designed to be a part of a secure boot chain. This means that
the bootloader is cryptographically signed, the ROM code of the SoC must
support a mechanism to validate this signature, otherwise there is no
root of trust.When punchboot has been verified it, in turn, will load and verify the next
software component in the boot chain. The bootloaderonlysupports signed
binaries.Testing and integration testsPunchboot uses QEMU for all module and integration tests. The 'test' platform
and board target relies on virtio serial ports and block devices. The punchboot
cli can be built with a domain socket transport instead of USB for communicating
with an QEMU environment.The test platform code includes gcov code that calls the QEMU semihosting API
for storing test coverage data on the host.Building and running tests:$ cp configs/test_defconfig .config
$ make
$ make checkDevice identityMost modern SoC's provide some kind of unique identity, that is guaranteed to
be unique for that particular type of SoC / Vendor etc but can not be guarateed
to be globally unique.Punchboot provides a UUID3 device identity based on a combination of the unique
data from the SoC and an allocated, random, namspace UUID per platform.When booting a linux system this information is relayed to linux through
in-line patching of the device-tree.
The device identity can be found in '/proc/device-tree/chosen/device-uuid'Command modeCommand mode is entered when the system can't boot or if the bootloader is
forced by a configurable, external event to do so.In the command mode it is possible to update the bootloader, write data to
partitions and install default settings. From v0.3 and forward
an 'authentication cookie' must be used to interact with the bootloader to
prevent malicious activity. The only command that can be executed without
authentication is listing the device information (including the device UUID)The authentication cookie consists of the device UUID encrypted with one of
the active key pair's private key.punchboot toolThe punchboot CLI is used for interacting with the command mode. A summary of the features available:Update the bootloader it selfManually start system A or BActivate boot partitionsLoad image to ram and execute itDisplay basic device infoConfigure fuses and GPT parition tablesCall board specific functionsThe tool is written in Python and some parts in C to allow bindings for other
languages. The tool is built on top of a library to make it possible to integrate
with other tooling and environments.The tool is distributed through PyPi. Binary wheels are available for Windows,
Linux and macos (x86_64 and arm64).Install using pypi:$ pip install punchbootImage formatPunchboot uses the bitpacker file format (https://github.com/jonasblixt/bpak)Authentication tokenPunchboot enforces authentication when the SLC (Security Life Cycle) is locked.
To interact with Punchboot the session must be authenticated by using a password
or a signed token.The authentication token is generated by hashing the device UUID and signing
it with one of the active key pairs.Example:$ punchboot dev show
Bootloader version: v0.6.1-40-ga47f-dirty
Device UUID:        0b177094-6b62-3572-902e-c1de339ecb01
Board name:         pico8mlCreating the authentication token using the 'createtoken.sh' script located
in the tools folder. In this example the private key is stored on a yubikey 5 HSM.$ ./createtoken.sh 0B177094-6B62-3572-902E-C1DE339ECB01 pkcs11 -sha256 "pkcs11:id=%02;type=private"
engine "pkcs11" set.
Enter PKCS#11 token PIN for PIV Card Holder pin (PIV_II):
Enter PKCS#11 key PIN for SIGN key:Authenticating the session:$ punchboot auth token ./0B177094-6B62-3572-902E-C1DE339ECB01.token <name of a key>
Signature format: secp256r1
Hash: sha256
Authenticating using key index 0 and './0B177094-6B62-3572-902E-C1DE339ECB01.token'
Read 103 bytes
Authentication successfulNow the command mode is fully unlocked. The token is of course only valid for
the individual unit with that perticular UUID.MetricsMeasurements taken on IMX6UL, running at 528 MHz loading a 400kByte binary.Using hardware accelerators for SHA and RSA signatures:ParameterValueUnitPower On Reset28msBootloader init7msBlockdev read13msSHA256 Hash4msRSA 4096 Signaure5msTotal57msUsing libtomcrypt for SHA and RSA:ParameterValueUnitPower On Reset28msBootloader init7msBlockdev read13msSHA256 Hash431msRSA 4096 Signaure567msTotal1046msMeasurements taken on IMX8QXP, loading a 14296kByte binary.Using hardware accelerators for SHA and RSA signatures:ParameterValueUnitPower On Reset175msBootloader init6.358msBlockdev read / hash107msRSA 4096 Signature0.676msTotal288msThe POR time is off due to some unidentified problem with the SCU firmware.
A guess would be that this metric should be in the 20ms -range.ContributingFork the repositoryImplement new feature or bugfix on a branchImplement test case(s) to ensure that future changes do not break legacyRun checks: cp configs/test_defconfig .config && make checkCreate pull request