diff --git a/Makefile b/Makefile index e556a7e6..0d9948a4 100644 --- a/Makefile +++ b/Makefile @@ -154,11 +154,7 @@ include tools/test-delta.mk include tools/test-renode.mk PYTHON?=python3 -keytools_check: - $(Q)(test -x "$(KEYGEN_TOOL)") || \ - ($(PYTHON) -c "import wolfcrypt" > /dev/null 2>&1) || \ - (echo "ERROR: Key tool unavailable '$(KEYGEN_TOOL)'.\n"\ - "Run 'make keytools' or install wolfcrypt 'pip3 install wolfcrypt'" && false) +keytools_check: keytools FORCE $(PRIVATE_KEY): diff --git a/docs/Signing.md b/docs/Signing.md index c06188fe..a94af2fa 100644 --- a/docs/Signing.md +++ b/docs/Signing.md @@ -9,18 +9,8 @@ firmware and all the updates for the target. The tools are distributed in two versions, using the same command line syntax, for portability reasons. -By default, if no C keytools are compiled, the makefiles and scripts in this -repository will use the Python tools. - -### Python key tools - -In order to use the python key tools, ensure that the `wolfcrypt` package is -installed in your python environment. In most systems it's sufficient to run a -command similar to: - -`pip install wolfcrypt` - -to ensure that the dependencies are met. +By default, C keytools are compiled. The makefiles and scripts in this +repository will use the C tools. ### C Key Tools @@ -34,12 +24,23 @@ If the C version of the key tools exists they will be used by wolfBoot's makefil Use the `wolfBootSignTool.vcxproj` Visual Studio project to build the `sign.exe` and `keygen.exe` tools for use on Windows. +### Python key tools + +**Please note that the Python tools are deprecated and will be removed in future versions.** + +In order to use the python key tools, ensure that the `wolfcrypt` package is +installed in your python environment. In most systems it's sufficient to run a +command similar to: + +`pip install wolfcrypt` + +to ensure that the dependencies are met. ## Command Line Usage ### Keygen tool -Usage: `keygen[.py] [OPTIONS] [-g new-keypair.der] [-i existing-pubkey.der] [...]` +Usage: `keygen [OPTIONS] [-g new-keypair.der] [-i existing-pubkey.der] [...]` `keygen` is used to populate a keystore with existing and new public keys. Two options are supported: @@ -62,10 +63,10 @@ For more information about the keystore mechanism, see [keystore.md](keystore.md ### Sign tool -`sign` and `sign.py` produce a signed firmware image by creating a manifest header +`sign` produces a signed firmware image by creating a manifest header in the format supported by wolfBoot. -Usage: `sign[.py] [OPTIONS] IMAGE.BIN KEY.DER VERSION` +Usage: `sign [OPTIONS] IMAGE.BIN KEY.DER VERSION` `IMAGE.BIN`: A file containing the binary firmware/software to sign `KEY.DER`: Private key file, in DER format, to sign the binary image @@ -161,7 +162,7 @@ An incremental update is created using the sign tool when the following option is provided: * `--delta BASE_SIGNED_IMG.BIN` This option creates a binary diff file between - BASE_SIGNED_IMG.BIN and the new image signed starting from IMAGE.BIN. The + `BASE_SIGNED_IMG.BIN` and the new image signed starting from `IMAGE.BIN`. The result is stored in a file ending in `_signed_diff.bin`. #### Three-steps signing using external provisioning tools @@ -190,7 +191,7 @@ its raw format and copied to a file, e.g. IMAGE_SIGNATURE.SIG the public part of the key that was used to sign the firmware in Phase 2. This option requires one extra argument at the end, after VERSION, which should be the filename of the signature that was the output of the previous phase, so -IMAGE_SIGNATURE.SIG +`IMAGE_SIGNATURE.SIG` For a real-life example, see the section below. @@ -203,8 +204,6 @@ For a real-life example, see the section below. ```sh ./tools/keytools/sign --rsa2048 --sha256 test-app/image.bin wolfboot_signing_private_key.der 1 -# OR -python3 ./tools/keytools/sign.py --rsa2048 --sha256 test-app/image.bin wolfboot_signing_private_key.der 1 ``` Note: The last argument is the “version” number. @@ -219,21 +218,15 @@ openssl rsa -inform DER -outform DER -in my_key.der -out rsa2048_pub.der -pubout # Add the public key to the wolfBoot keystore using `keygen -i` ./tools/keytools/keygen --rsa2048 -i rsa2048_pub.der -# OR -python3 ./tools/keytools/keygen.py --rsa2048 -i rsa4096_pub.der # Generate Hash to Sign ./tools/keytools/sign --rsa2048 --sha-only --sha256 test-app/image.bin rsa2048_pub.der 1 -# OR -python3 ./tools/keytools/sign.py --rsa2048 --sha-only --sha256 test-app/image.bin rsa4096_pub.der 1 # Sign hash Example (here is where you would use an HSM) openssl pkeyutl -sign -keyform der -inkey my_key.der -in test-app/image_v1_digest.bin > test-app/image_v1.sig # Generate final signed binary ./tools/keytools/sign --rsa2048 --sha256 --manual-sign test-app/image.bin rsa2048_pub.der 1 test-app/image_v1.sig -# OR -python3 ./tools/keytools/sign.py --rsa2048 --sha256 --manual-sign test-app/image.bin rsa4096_pub.der 1 test-app/image_v1.sig # Combine into factory image (0xc0000 is the WOLFBOOT_PARTITION_BOOT_ADDRESS) tools/bin-assemble/bin-assemble factory.bin 0x0 wolfboot.bin \ diff --git a/docs/Targets.md b/docs/Targets.md index 28170180..7aa11afd 100644 --- a/docs/Targets.md +++ b/docs/Targets.md @@ -643,10 +643,10 @@ reset resume 0x0000001 ``` -To sign the same application image as new version (2), use the python script `sign.py` provided: +To sign the same application image as new version (2), use the `sign` tool provided: ``` -tools/keytools/sign.py test-app/image.bin wolfboot_signing_private_key.der 2 +tools/keytools/sign test-app/image.bin wolfboot_signing_private_key.der 2 ``` From OpenOCD, the updated image (version 2) can be flashed to the second bank: @@ -717,9 +717,9 @@ st-flash write test-app/image_v1_signed.bin 0x08020000 ### STM32H7 Testing -To sign the same application image as new version (2), use the sign tools +To sign the same application image as new version (2), use the sign tool -Python: `tools/keytools/sign.py --ecc256 --sha256 test-app/image.bin wolfboot_signing_private_key.der 2` +Python: `tools/keytools/sign --ecc256 --sha256 test-app/image.bin wolfboot_signing_private_key.der 2` C Tool: `tools/keytools/sign --ecc256 --sha256 test-app/image.bin wolfboot_signing_private_key.der 2` @@ -928,7 +928,7 @@ make CROSS_COMPILE=aarch64-unknown-nto-qnx7.0.0- #### Signing -`tools/keytools/sign.py --rsa4096 --sha3 /srv/linux-rpi4/vmlinux.bin wolfboot_signing_private_key.der 1` +`tools/keytools/sign --rsa4096 --sha3 /srv/linux-rpi4/vmlinux.bin wolfboot_signing_private_key.der 1` ## Cypress PSoC-6 @@ -1135,7 +1135,7 @@ To build the first stage load, wolfBoot, sign a custom application and assembly ``` cp config/examples/nxp-p1021.config .config -# build the C version of the key tools (instead of using the python ones) +# build the key tools make keytools make clean diff --git a/docs/encrypted_partitions.md b/docs/encrypted_partitions.md index 34e51a42..54d08df2 100644 --- a/docs/encrypted_partitions.md +++ b/docs/encrypted_partitions.md @@ -15,7 +15,7 @@ to hide the actual content of the external non-volatile memory. Vice-versa, all read operations will decrypt the data stored when the feature is enabled. -An extra option is provided to the `sign.py` sign tool to encrypt the firmware update after signing it, so +An extra option is provided to the `sign` tool to encrypt the firmware update after signing it, so that it can be stored as is in the external memory by the application, and will be decrypted by the bootloader in order to verify the update and begin the installation. @@ -76,7 +76,7 @@ select `ENCRYPT_WITH_AES128=1` or `ENCRYPT_WITH_AES256=1`. ### Signing and encrypting the update bundle with ChaCha20-256 -The `sign.py` tool can sign and encrypt the image with a single command. +The `sign` tool can sign and encrypt the image with a single command. In case of chacha20, the encryption secret is provided in a binary file that should contain a concatenation of a 32B ChaCha-256 key and a 12B nonce. @@ -93,11 +93,11 @@ So it is easy to prepare the encryption secret in the test scripts or from the c echo -n "0123456789abcdef0123456789abcdef0123456789ab" > enc_key.der ``` -The `sign.py` script can now be invoked to produce a signed+encrypted image, by using the extra argument `--encrypt` followed by the +The `sign` tool can now be invoked to produce a signed+encrypted image, by using the extra argument `--encrypt` followed by the secret file: ``` -./tools/keytools/sign.py --encrypt enc_key.der test-app/image.bin wolfboot_signing_private_key.der 24 +./tools/keytools/sign --encrypt enc_key.der test-app/image.bin wolfboot_signing_private_key.der 24 ``` @@ -121,11 +121,11 @@ So it is easy to prepare the encryption secret in the test scripts or from the c echo -n "0123456789abcdef0123456789abcdef0123456789abcdef" > enc_key.der ``` -The `sign.py` script can now be invoked to produce a signed+encrypted image, by using the extra argument `--encrypt` followed by the +The `sign` tool can now be invoked to produce a signed+encrypted image, by using the extra argument `--encrypt` followed by the secret file. To select AES-256, use the `--aes256` option. ``` -./tools/keytools/sign.py --aes256 --encrypt enc_key.der test-app/image.bin wolfboot_signing_private_key.der 24 +./tools/keytools/sign --aes256 --encrypt enc_key.der test-app/image.bin wolfboot_signing_private_key.der 24 ``` diff --git a/docs/firmware_update.md b/docs/firmware_update.md index 4d4d4ad8..4b546169 100644 --- a/docs/firmware_update.md +++ b/docs/firmware_update.md @@ -152,11 +152,11 @@ Requirement: wolfBoot is compiled with `DELTA_UPDATES=1` Version "1" is signed as usual, as a standalone image: -`tools/keytools/sign.py --ecc256 --sha256 test-app/image.bin wolfboot_signing_private_key.der 1` +`tools/keytools/sign --ecc256 --sha256 test-app/image.bin wolfboot_signing_private_key.der 1` When updating from version 1 to version 2, you can invoke the sign tool as: -`tools/keytools/sign.py --delta test-app/image_v1_signed.bin --ecc256 --sha256 test-app/image.bin wolfboot_signing_private_key.der 2` +`tools/keytools/sign --delta test-app/image_v1_signed.bin --ecc256 --sha256 test-app/image.bin wolfboot_signing_private_key.der 2` Besides the usual output file `image_v2_signed.bin`, the sign tool creates an additional `image_v2_signed_diff.bin` which should be noticeably smaller in size as long as the two binary files contain overlapping areas. diff --git a/docs/keystore.md b/docs/keystore.md index 347bbd6d..173ebfb8 100644 --- a/docs/keystore.md +++ b/docs/keystore.md @@ -63,7 +63,7 @@ Two arguments: Example of creation of a keystore with two ED25519 keys: -`./tools/keytools/keygen.py --ed25519 -g first.der -g second.der` +`./tools/keytools/keygen --ed25519 -g first.der -g second.der` will create the following files: diff --git a/tools/keytools/keygen.py b/tools/keytools/keygen.py index 6666e9bc..71f2f411 100755 --- a/tools/keytools/keygen.py +++ b/tools/keytools/keygen.py @@ -194,11 +194,17 @@ parser.add_argument('-i', dest='pubfile', nargs='+', action='extend') parser.add_argument('-g', dest='keyfile', nargs='+', action='extend') parser.add_argument('-keystoreDir', dest='storeDir', nargs='+', action='extend') +print(" *** WARNING ***") +print("Python key tools are now deprecated") +print("and will be removed in future versions.") +print("Please ensure that your scripts are using") +print("the compiled C version of these tools") +print("(e.g. by running 'make keytools').") +print(" *** ******* ***") +print("") args=parser.parse_args() -#sys.exit(0) #test - if (type(args.storeDir) == list): pubkey_cfile = "".join(args.storeDir)+"/keystore.c" keystore_imgfile = "".join(args.storeDir)+"/keystore.der" diff --git a/tools/keytools/sign.py b/tools/keytools/sign.py index 41c73691..cb20db9c 100755 --- a/tools/keytools/sign.py +++ b/tools/keytools/sign.py @@ -291,8 +291,14 @@ def make_header(image_file, fw_version, extra_fields=[]): print("wolfBoot KeyTools (Python version)") print("wolfcrypt-py version: " + wolfcrypt.__version__) - - +print(" *** WARNING ***") +print("Python key tools are now deprecated") +print("and will be removed in future versions.") +print("Please ensure that your scripts are using") +print("the compiled C version of these tools") +print("(e.g. by running 'make keytools').") +print(" *** ******* ***") +print("") if (argc < 4) or (argc > 12): print("Usage: "+argv[0]+" [options] image key version");