mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
docs(secure_boot_v2): Mention idf.py and openssl commands to generate and verify signatures
- Adds support for verify_signature command in idf.py Closes https://github.com/espressif/esptool/issues/942
This commit is contained in:
parent
997512ace2
commit
e5f22521da
@ -654,24 +654,97 @@ Secure Boot Best Practices
|
||||
Technical Details
|
||||
-----------------
|
||||
|
||||
The following sections contain low-level reference descriptions of various Secure Boot elements:
|
||||
|
||||
|
||||
Manual Commands
|
||||
~~~~~~~~~~~~~~~
|
||||
The following sections contain low-level reference descriptions of various Secure Boot elements.
|
||||
|
||||
Secure Boot is integrated into the ESP-IDF build system, so ``idf.py build`` will sign an app image, and ``idf.py bootloader`` will produce a signed bootloader if :ref:`CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES` is enabled.
|
||||
|
||||
However, it is possible to use the ``idf.py`` tool to make standalone signatures and digests.
|
||||
However, it is possible to use the ``idf.py`` or the ``openssl`` tool to generate standalone signatures and verify them. Using ``idf.py`` is recommended, but in case you need to generate or verify signatures in non-ESP-IDF environments,
|
||||
you could also use the ``openssl`` commands as the Secure Boot V2 signature generation is compliant with the standard signing algorithms.
|
||||
|
||||
To sign a binary image:
|
||||
Generating and Verifying signatures using ``idf.py``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block::
|
||||
1. To sign a binary image:
|
||||
|
||||
idf.py secure-sign-data --keyfile ./my_signing_key.pem --output ./image_signed.bin image-unsigned.bin
|
||||
.. code-block::
|
||||
|
||||
idf.py secure-sign-data --keyfile ./my_signing_key.pem --output ./image_signed.bin image-unsigned.bin
|
||||
|
||||
Keyfile is the PEM file containing an {IDF_TARGET_SBV2_KEY} private signing key.
|
||||
|
||||
2. To verify a signed binary image:
|
||||
|
||||
.. code-block::
|
||||
|
||||
idf.py secure-verify-signature --keyfile ./my_signing_key.pem image_signed.bin
|
||||
|
||||
Keyfile is the PEM file containing an {IDF_TARGET_SBV2_KEY} public/\private signing key.
|
||||
|
||||
Generating and Verifying signatures using OpenSSL
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
It is preferred to use the ``idf.py`` tool to generate and verify signatures, but in case you need to perform these operations using OpenSSL, following are the reference commands to do so:
|
||||
|
||||
1. Generate digest of the image binary file whose signature needs to be calculated.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
openssl dgst -sha256 -binary BINARY_FILE > DIGEST_BINARY_FILE
|
||||
|
||||
2. Generate signature of the image using the above calculated digest.
|
||||
|
||||
.. only:: SOC_SECURE_BOOT_V2_RSA
|
||||
|
||||
For generating an RSA-PSS signature:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
openssl pkeyutl -sign \
|
||||
-in DIGEST_BINARY_FILE \
|
||||
-inkey PRIVATE_SIGNING_KEY \
|
||||
-out SIGNATURE_FILE \
|
||||
-pkeyopt digest:sha256 \
|
||||
-pkeyopt rsa_padding_mode:pss \
|
||||
-pkeyopt rsa_pss_saltlen:32
|
||||
|
||||
.. only:: SOC_SECURE_BOOT_V2_ECC
|
||||
|
||||
For generating an ECDSA signature:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
openssl pkeyutl -sign \
|
||||
-in DIGEST_BINARY_FILE \
|
||||
-inkey PRIVATE_SIGNING_KEY \
|
||||
-out SIGNATURE_FILE
|
||||
|
||||
3. Verify the generated signature.
|
||||
|
||||
.. only:: SOC_SECURE_BOOT_V2_RSA
|
||||
|
||||
For verifying an RSA-PSS signature:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
openssl pkeyutl -verify \
|
||||
-in DIGEST_BINARY_FILE \
|
||||
-pubin -inkey PUBLIC_SIGNING_KEY \
|
||||
-sigfile SIGNATURE_FILE \
|
||||
-pkeyopt rsa_padding_mode:pss \
|
||||
-pkeyopt rsa_pss_saltlen:32 \
|
||||
-pkeyopt digest:sha256
|
||||
|
||||
.. only:: SOC_SECURE_BOOT_V2_ECC
|
||||
|
||||
For verifying an ECDSA signature:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
openssl pkeyutl -verify \
|
||||
-in DIGEST_BINARY_FILE \
|
||||
-pubin -inkey PUBLIC_SIGNING_KEY \
|
||||
-sigfile SIGNATURE_FILE
|
||||
|
||||
|
||||
.. _secure-boot-v2-and-flash-encr:
|
||||
|
||||
|
@ -436,6 +436,22 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict:
|
||||
sign_data_args += [extra_args['datafile']]
|
||||
RunTool('espsecure', sign_data_args, args.build_dir)()
|
||||
|
||||
def secure_verify_signature(action: str,
|
||||
ctx: click.core.Context,
|
||||
args: PropertyDict,
|
||||
version: str,
|
||||
keyfile: str,
|
||||
**extra_args: str) -> None:
|
||||
ensure_build_directory(args, ctx.info_name)
|
||||
verify_signature_args = [PYTHON, '-m', 'espsecure', 'verify_signature']
|
||||
if version:
|
||||
verify_signature_args += ['--version', version]
|
||||
if keyfile:
|
||||
verify_signature_args += ['--keyfile', keyfile]
|
||||
if extra_args['datafile']:
|
||||
verify_signature_args += [extra_args['datafile']]
|
||||
RunTool('espsecure', verify_signature_args, args.build_dir)()
|
||||
|
||||
def _parse_efuse_args(ctx: click.core.Context, args: PropertyDict, extra_args: Dict) -> List:
|
||||
efuse_args = []
|
||||
if args.port:
|
||||
@ -792,6 +808,28 @@ def action_extensions(base_actions: Dict, project_path: str) -> Dict:
|
||||
},
|
||||
],
|
||||
},
|
||||
'secure-verify-signature': {
|
||||
'callback': secure_verify_signature,
|
||||
'help': ('Verify a previously signed binary image, using the ECDSA (V1) or either RSA or ECDSA (V2) public key.'),
|
||||
'options': [
|
||||
{
|
||||
'names': ['--version', '-v'],
|
||||
'help': ('Version of the secure boot signing scheme to use.'),
|
||||
'type': click.Choice(['1', '2']),
|
||||
'default': '2',
|
||||
},
|
||||
{
|
||||
'names': ['--keyfile', '-k'],
|
||||
'help': ('Public key file for verification. Can be private or public key in PEM format.'),
|
||||
},
|
||||
],
|
||||
'arguments': [
|
||||
{
|
||||
'names': ['datafile'],
|
||||
'nargs': 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
'efuse-burn': {
|
||||
'callback': efuse_burn,
|
||||
'help': 'Burn the eFuse with the specified name.',
|
||||
|
@ -521,6 +521,19 @@ class TestSecureCommands(TestWrapperCommands):
|
||||
output = self.call_command(sign_command)
|
||||
self.assertIn('Signed', output)
|
||||
|
||||
def secure_verify_signature(self):
|
||||
self.secure_sign_data()
|
||||
sign_command = [sys.executable,
|
||||
idf_py_path,
|
||||
'secure-verify-signature',
|
||||
'--version',
|
||||
'2',
|
||||
'--keyfile',
|
||||
f'../{self.signing_key}',
|
||||
'bootloader-signed.bin']
|
||||
output = self.call_command(sign_command)
|
||||
self.assertIn('verification successful', output)
|
||||
|
||||
|
||||
class TestMergeBinCommands(TestWrapperCommands):
|
||||
"""
|
||||
|
Loading…
Reference in New Issue
Block a user