forked from espressif/esp-idf
Merge branch 'docs/update_security_and_contribute' into 'master'
docs: update format issues for both EN and CN under security and contribute folder Closes DOC-5904 See merge request espressif/esp-idf!25109
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
Contributor Agreement
|
||||
=====================
|
||||
|
||||
Individual Contributor Non-Exclusive License Agreement including the Traditional Patent License OPTION
|
||||
Individual Contributor Non-Exclusive License Agreement Including the Traditional Patent License OPTION
|
||||
------------------------------------------------------------------------------------------------------
|
||||
|
||||
Thank you for your interest in contributing to this Espressif project hosted on GitHub ("We" or "Us").
|
||||
|
@@ -24,7 +24,7 @@ The checker can be configured with the ``tools/ci/check_copyright_config.yaml``
|
||||
Common Examples of Copyright Headers
|
||||
------------------------------------
|
||||
|
||||
The simplest case is when the code is not based on any licensed previous work, e.g. it was written completely from scratch. Such code can be decorated with the following copyright header and put under the license of ESP-IDF::
|
||||
The simplest case is when the code is not based on any licensed previous work, e.g., it was written completely from scratch. Such code can be decorated with the following copyright header and put under the license of ESP-IDF::
|
||||
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
|
@@ -1,5 +1,6 @@
|
||||
Creating Examples
|
||||
=================
|
||||
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
Each ESP-IDF example is a complete project that someone else can copy and adapt the code to solve their own problem. Examples should demonstrate ESP-IDF functionality, while keeping this purpose in mind.
|
||||
@@ -9,9 +10,9 @@ Structure
|
||||
|
||||
- The ``main`` directory should contain a source file named ``(something)_example_main.c`` with the main functionality.
|
||||
- If the example has additional functionality, split it logically into separate C or C++ source files under ``main`` and place a corresponding header file in the same directory.
|
||||
- If the example has a lot of additional functionality, consider adding a ``components`` directory to the example project and make some example-specific components with library functionality. Only do this if the components are specific to the example, if they're generic or common functionality then they should be added to ESP-IDF itself.
|
||||
- If the example has a lot of additional functionality, consider adding a ``components`` directory to the example project and make some example-specific components with library functionality. Only do this if the components are specific to the example, if they are generic or common functionality then they should be added to ESP-IDF itself.
|
||||
- The example should have a ``README.md`` file. Use the :idf_file:`template example README <docs/TEMPLATE_EXAMPLE_README.md>` and adapt it for your particular example.
|
||||
- Examples should have a ``pytest_<example name>.py`` file for running an automated example test. If submitting a GitHub Pull Request which includes an example, it's OK not to include this file initially. The details can be discussed as part of the `Pull Request <https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request>`_. Please refer to :doc:`IDF Tests with Pytest Guide <esp-idf-tests-with-pytest>` for details.
|
||||
- Examples should have a ``pytest_<example name>.py`` file for running an automated example test. If submitting a GitHub Pull Request which includes an example, it is OK not to include this file initially. The details can be discussed as part of the `Pull Request <https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request>`_. Please refer to :doc:`IDF Tests with Pytest Guide <esp-idf-tests-with-pytest>` for details.
|
||||
|
||||
General Guidelines
|
||||
------------------
|
||||
@@ -26,10 +27,10 @@ Checklist before submitting a new example:
|
||||
* Example project name (in ``README.md``) uses the word "example". Use "example" instead of "demo", "test" or similar words.
|
||||
* Example does one distinct thing. If the example does more than one thing at a time, split it into two or more examples.
|
||||
* Example has a ``README.md`` file which is similar to the :idf_file:`template example README <docs/TEMPLATE_EXAMPLE_README.md>`.
|
||||
* Functions and variables in the example are named according to :ref:`naming section of the style guide <style-guide-naming>`. (For non-static names which are only specific to the example's source files, you can use ``example`` or something similar as a prefix.)
|
||||
* Functions and variables in the example are named according to :ref:`naming section of the style guide <style-guide-naming>`. For non-static names which are only specific to the example's source files, you can use ``example`` or something similar as a prefix.
|
||||
* All code in the example is well structured and commented.
|
||||
* Any unnecessary code (old debugging logs, commented-out code, etc.) is removed from the example.
|
||||
* Options in the example (like network names, addresses, etc) are not hard-coded. Use configuration items if possible, or otherwise declare macros or constants)
|
||||
* Options in the example (like network names, addresses, etc) are not hard-coded. Use configuration items if possible, or otherwise declare macros or constants.
|
||||
* Configuration items are provided in a ``KConfig.projbuild`` file with a menu named "Example Configuration". See existing example projects to see how this is done.
|
||||
* All original example code has a license header saying it is "in the public domain / CC0", and a warranty disclaimer clause. Alternatively, the example is licensed under Apache License 2.0. See existing examples for headers to adapt from.
|
||||
* Any adapted or third party example code has the original license header on it. This code must be licensed compatible with Apache License 2.0.
|
||||
|
@@ -71,7 +71,7 @@ When writing code for this repository, please follow guidelines below:
|
||||
* - ESP_OK if erase operation was successful
|
||||
* - ESP_ERR_NVS_INVALID_HANDLE if handle has been closed or is NULL
|
||||
* - ESP_ERR_NVS_READ_ONLY if handle was opened as read only
|
||||
* - ESP_ERR_NVS_NOT_FOUND if the requested key doesn't exist
|
||||
* - ESP_ERR_NVS_NOT_FOUND if the requested key does not exist
|
||||
* - other error codes from the underlying storage driver
|
||||
*
|
||||
|
||||
@@ -142,7 +142,7 @@ Standardize Document Format
|
||||
|
||||
When it comes to text, please follow guidelines below to provide well-formatted Markdown (.md) or reST (.rst) documents.
|
||||
|
||||
1. Please ensure that one paragraph is written in one line. Don't break lines like below. Breaking lines to enhance readability is only suitable for writing code. To make the text easier to read, it is recommended to place an empty line to separate the paragraph.
|
||||
1. Please ensure that one paragraph is written in one line. Do not break lines like below. Breaking lines to enhance readability is only suitable for writing code. To make the text easier to read, it is recommended to place an empty line to separate the paragraph.
|
||||
|
||||
.. figure:: ../../_static/doc-format1-recommend.png
|
||||
:align: center
|
||||
|
@@ -28,10 +28,10 @@ All dependencies could be installed by running the install script with the ``--e
|
||||
Common Issues During Installation
|
||||
---------------------------------
|
||||
|
||||
No Package 'dbus-1' found
|
||||
No Package 'dbus-1' Found
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If you're facing an error message like:
|
||||
If you are facing an error message like:
|
||||
|
||||
.. code:: text
|
||||
|
||||
@@ -42,7 +42,7 @@ If you're facing an error message like:
|
||||
Consider adjusting the PKG_CONFIG_PATH environment variable if you
|
||||
installed software in a non-standard prefix.
|
||||
|
||||
If you're running under ubuntu system, you may need to run:
|
||||
If you are running under ubuntu system, you may need to run:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
@@ -56,10 +56,10 @@ or
|
||||
|
||||
For other linux distros, you may Google the error message and find the solution. This issue could be solved by installing the related header files.
|
||||
|
||||
Invalid command 'bdist_wheel'
|
||||
Invalid Command 'bdist_wheel'
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If you're facing an error message like:
|
||||
If you are facing an error message like:
|
||||
|
||||
.. code:: text
|
||||
|
||||
@@ -77,7 +77,7 @@ Or
|
||||
|
||||
python -m pip install wheel
|
||||
|
||||
Before running the pip commands, please make sure you're using the IDF python virtual environment.
|
||||
Before running the pip commands, please make sure you are using the IDF python virtual environment.
|
||||
|
||||
Basic Concepts
|
||||
==============
|
||||
@@ -220,7 +220,7 @@ This code example is taken from :idf_file:`pytest_console_basic.py <examples/sys
|
||||
elif config == 'nohistory':
|
||||
dut.expect('Command history disabled')
|
||||
|
||||
Let's go through this simple test case line by line in the following subsections.
|
||||
Let us go through this simple test case line by line in the following subsections.
|
||||
|
||||
Use Markers to Specify the Supported Targets
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -237,10 +237,10 @@ The above lines indicate that this test case supports target esp32 and esp32c3,
|
||||
|
||||
If the test case supports all officially ESP-IDF supported targets (You may check the value via "idf.py --list-targets"), you can use a special marker ``supported_targets`` to apply all of them in one line.
|
||||
|
||||
Use Params to Specify the sdkconfig Files
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Use Params to Specify the ``sdkconfig`` Files
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
You can use ``pytest.mark.parametrize`` with “config” to apply the same test to different apps with different sdkconfig files. For more information about ``sdkconfig.ci.xxx`` files, please refer to the Configuration Files section under :idf_file:`this readme <tools/test_apps/README.md>`.
|
||||
You can use ``pytest.mark.parametrize`` with "config" to apply the same test to different apps with different sdkconfig files. For more information about ``sdkconfig.ci.xxx`` files, please refer to the Configuration Files section under :idf_file:`this readme <tools/test_apps/README.md>`.
|
||||
|
||||
.. code:: python
|
||||
|
||||
@@ -256,7 +256,7 @@ Overall, this test function would be replicated to 4 test cases:
|
||||
- esp32c3.history.test_console_advanced
|
||||
- esp32c3.nohistory.test_console_advanced
|
||||
|
||||
Expect From the Serial output
|
||||
Expect From the Serial Output
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code:: python
|
||||
@@ -267,7 +267,7 @@ Expect From the Serial output
|
||||
elif config == 'nohistory':
|
||||
dut.expect('Command history disabled')
|
||||
|
||||
When we're using ``dut.expect(...)``, the string would be compiled into regex at first, and then seeks through the serial output until the compiled regex is matched, or a timeout is exceeded. You may have to pay extra attention when the string contains regex keyword characters, like parentheses, or square brackets.
|
||||
When we are using ``dut.expect(...)``, the string would be compiled into regex at first, and then seeks through the serial output until the compiled regex is matched, or a timeout is exceeded. You may have to pay extra attention when the string contains regex keyword characters, like parentheses, or square brackets.
|
||||
|
||||
Actually using ``dut.expect_exact(...)`` here is better, since it would seek until the string is matched. For further reading about the different types of ``expect`` functions, please refer to the `pytest-embedded Expecting documentation <https://docs.espressif.com/projects/pytest-embedded/en/latest/expecting.html>`__.
|
||||
|
||||
@@ -321,7 +321,7 @@ Here the first dut was flashed with the app :idf_file:`softap <examples/wifi/get
|
||||
Multi Dut Tests with Different Apps, and Targets
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This code example is taken from :idf_file:`pytest_wifi_getting_started.py <examples/wifi/getting_started/pytest_wifi_getting_started.py>`. As the comment says, for now it's not running in the ESP-IDF CI.
|
||||
This code example is taken from :idf_file:`pytest_wifi_getting_started.py <examples/wifi/getting_started/pytest_wifi_getting_started.py>`. As the comment says, for now it is not running in the ESP-IDF CI.
|
||||
|
||||
.. code:: python
|
||||
|
||||
@@ -346,8 +346,8 @@ Overall, this test function would be replicated to 2 test cases:
|
||||
- softap with esp32 target, and station with esp32s2 target
|
||||
- softap with esp32s2 target, and station with esp32 target
|
||||
|
||||
Support different targets with different sdkconfig files
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Support Different Targets with Different ``sdkconfig`` Files
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This code example is taken from :idf_file:`pytest_panic.py <tools/test_apps/system/panic/pytest_panic.py>` as an advanced example.
|
||||
|
||||
@@ -413,10 +413,10 @@ This flaky marker means that if the test function failed, the test case would re
|
||||
Mark Known Failure Cases
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Sometimes a test couldn't pass for the following reasons:
|
||||
Sometimes a test could not pass for the following reasons:
|
||||
|
||||
- Has a bug
|
||||
- The success ratio is too low because of environment issue, such as network issue. Retry couldn't help
|
||||
- The success ratio is too low because of environment issue, such as network issue. Retry could not help
|
||||
|
||||
Now you may mark this test case with marker `xfail <https://docs.pytest.org/en/latest/how-to/skipping.html#xfail-mark-test-functions-as-expected-to-fail>`__ with a user-friendly readable reason.
|
||||
|
||||
@@ -486,7 +486,7 @@ For further reading about our unit testing in ESP-IDF, please refer to :doc:`our
|
||||
Run the Tests in CI
|
||||
===================
|
||||
|
||||
The workflow in CI is simple, build jobs -> target test jobs.
|
||||
The workflow in CI is simple, build jobs > target test jobs.
|
||||
|
||||
Build Jobs
|
||||
----------
|
||||
@@ -568,7 +568,7 @@ For example, if you want to run all the esp32 tests under the ``$IDF_PATH/exampl
|
||||
$ idf.py build
|
||||
$ pytest --target esp32
|
||||
|
||||
If you have multiple sdkconfig files in your test app, like those ``sdkconfig.ci.*`` files, the simple ``idf.py build`` won't apply the extra sdkconfig files. Let's take ``$IDF_PATH/examples/system/console/basic`` as an example.
|
||||
If you have multiple sdkconfig files in your test app, like those ``sdkconfig.ci.*`` files, the simple ``idf.py build`` won't apply the extra sdkconfig files. Let us take ``$IDF_PATH/examples/system/console/basic`` as an example.
|
||||
|
||||
If you want to test this app with config ``history``, and build with ``idf.py build``, you should run
|
||||
|
||||
@@ -607,9 +607,9 @@ Filter the Test Cases
|
||||
Add New Markers
|
||||
---------------
|
||||
|
||||
We’re using two types of custom markers, target markers which indicate that the test cases should support this target, and env markers which indicate that the test case should be assigned to runners with these tags in CI.
|
||||
We are using two types of custom markers, target markers which indicate that the test cases should support this target, and env markers which indicate that the test case should be assigned to runners with these tags in CI.
|
||||
|
||||
You can add new markers by adding one line under the ``${IDF_PATH}/conftest.py``. If it's a target marker, it should be added into ``TARGET_MARKERS``. If it's a marker that specifies a type of test environment, it should be added into ``ENV_MARKERS``. The grammar should be: ``<marker_name>: <marker_description>``.
|
||||
You can add new markers by adding one line under the ``${IDF_PATH}/conftest.py``. If it is a target marker, it should be added into ``TARGET_MARKERS``. If it is a marker that specifies a type of test environment, it should be added into ``ENV_MARKERS``. The grammar should be: ``<marker_name>: <marker_description>``.
|
||||
|
||||
Generate JUnit Report
|
||||
---------------------
|
||||
@@ -619,7 +619,7 @@ You can call pytest with ``--junitxml <filepath>`` to generate the JUnit report.
|
||||
Skip Auto Flash Binary
|
||||
----------------------
|
||||
|
||||
Skipping auto-flash binary every time would be useful when you're debugging your test script.
|
||||
Skipping auto-flash binary every time would be useful when you are debugging your test script.
|
||||
|
||||
You can call pytest with ``--skip-autoflash y`` to achieve it.
|
||||
|
||||
@@ -664,7 +664,7 @@ The above example would log the performance item with pre-defined format: "[perf
|
||||
``check_performance``
|
||||
"""""""""""""""""""""
|
||||
|
||||
We provide C macros ``TEST_PERFORMANCE_LESS_THAN`` and ``TEST_PERFORMANCE_GREATER_THAN`` to log the performance item and check if the value is in the valid range. Sometimes the performance item value could not be measured in C code, so we also provide a python function for the same purpose. Please note that using C macros is the preferred approach, since the python function couldn't recognize the threshold values of the same performance item under different ifdef blocks well.
|
||||
We provide C macros ``TEST_PERFORMANCE_LESS_THAN`` and ``TEST_PERFORMANCE_GREATER_THAN`` to log the performance item and check if the value is in the valid range. Sometimes the performance item value could not be measured in C code, so we also provide a python function for the same purpose. Please note that using C macros is the preferred approach, since the python function could not recognize the threshold values of the same performance item under different ifdef blocks well.
|
||||
|
||||
.. code:: python
|
||||
|
||||
@@ -677,7 +677,7 @@ We provide C macros ``TEST_PERFORMANCE_LESS_THAN`` and ``TEST_PERFORMANCE_GREATE
|
||||
|
||||
The above example would first get the threshold values of the performance item ``RSA_2048KEY_PUBLIC_OP`` from :idf_file:`components/idf_test/include/idf_performance.h` and the target-specific one :idf_file:`components/idf_test/include/esp32/idf_performance_target.h`, then check if the value reached the minimum limit or exceeded the maximum limit.
|
||||
|
||||
Let's assume the value of ``IDF_PERFORMANCE_MAX_RSA_2048KEY_PUBLIC_OP`` is 19000. so the first ``check_performance`` line would pass and the second one would fail with warning: ``[Performance] RSA_2048KEY_PUBLIC_OP value is 19001, doesn\'t meet pass standard 19000.0``
|
||||
Let us assume the value of ``IDF_PERFORMANCE_MAX_RSA_2048KEY_PUBLIC_OP`` is 19000. so the first ``check_performance`` line would pass and the second one would fail with warning: ``[Performance] RSA_2048KEY_PUBLIC_OP value is 19001, doesn\'t meet pass standard 19000.0``
|
||||
|
||||
Further Readings
|
||||
================
|
||||
|
@@ -3,12 +3,12 @@ Contributions Guide
|
||||
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
We welcome contributions to the esp-idf project!
|
||||
We welcome contributions to the ESP-IDF project!
|
||||
|
||||
How to Contribute
|
||||
-----------------
|
||||
|
||||
Contributions to esp-idf - fixing bugs, adding features, adding documentation - are welcome. We accept contributions via `Github Pull Requests <https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests>`_.
|
||||
Contributions to ESP-IDF - fixing bugs, adding features, adding documentation - are welcome. We accept contributions via `Github Pull Requests <https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests>`_.
|
||||
|
||||
Before Contributing
|
||||
-------------------
|
||||
@@ -17,9 +17,9 @@ Before sending us a Pull Request, please consider this list of points:
|
||||
|
||||
* Is the contribution entirely your own work, or already licensed under an Apache License 2.0 compatible Open Source License? If not then we unfortunately cannot accept it. Please check the :doc:`Copyright Header Guide <copyright-guide>` for additional information.
|
||||
|
||||
* Does any new code conform to the esp-idf :doc:`Style Guide <style-guide>`?
|
||||
* Does any new code conform to the ESP-IDF :doc:`Style Guide <style-guide>`?
|
||||
|
||||
* Have you installed the :doc:`pre-commit hook <install-pre-commit-hook>` for esp-idf project?
|
||||
* Have you installed the :doc:`pre-commit hook <install-pre-commit-hook>` for ESP-IDF project?
|
||||
|
||||
* Does the code documentation follow requirements in :doc:`documenting-code`?
|
||||
|
||||
@@ -33,7 +33,7 @@ Before sending us a Pull Request, please consider this list of points:
|
||||
|
||||
* If the contribution contains multiple commits, are they grouped together into logical changes (one major change per pull request)? Are any commits with names like "fixed typo" `squashed into previous commits <https://eli.thegreenplace.net/2014/02/19/squashing-github-pull-requests-into-a-single-commit/>`_?
|
||||
|
||||
* If you're unsure about any of these points, please open the Pull Request anyhow and then ask us for feedback.
|
||||
* If you are unsure about any of these points, please open the Pull Request anyhow and then ask us for feedback.
|
||||
|
||||
Pull Request Process
|
||||
--------------------
|
||||
|
@@ -1,4 +1,4 @@
|
||||
Install pre-commit Hook for ESP-IDF Project
|
||||
Install Pre-commit Hook for ESP-IDF Project
|
||||
===========================================
|
||||
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
@@ -6,7 +6,7 @@ Install pre-commit Hook for ESP-IDF Project
|
||||
Required Dependency
|
||||
-------------------
|
||||
|
||||
Python 3.8.* or above. This is our recommended Python version for IDF developers.
|
||||
Python 3.8.* or above. This is our recommended Python version for ESP-IDF developers.
|
||||
|
||||
If you still have Python versions not compatible, update your Python versions before installing the pre-commit hook.
|
||||
|
||||
@@ -18,19 +18,19 @@ Run ``pip install pre-commit``
|
||||
Install pre-commit Hook
|
||||
-----------------------
|
||||
|
||||
1. Go to the IDF project directory.
|
||||
1. Go to the ESP-IDF project directory.
|
||||
|
||||
2. Run ``pre-commit install --allow-missing-config -t pre-commit -t commit-msg``. Install hook by this approach will let you commit successfully even in branches without the ``.pre-commit-config.yaml``
|
||||
|
||||
3. pre-commit hook will run automatically when you're running ``git commit`` command
|
||||
3. pre-commit hook will run automatically when you are running ``git commit`` command
|
||||
|
||||
Uninstall pre-commit Hook
|
||||
-----------------------------
|
||||
|
||||
Run ``pre-commit uninstall``
|
||||
|
||||
What's More?
|
||||
------------
|
||||
What Is More?
|
||||
-------------
|
||||
|
||||
For detailed usage, please refer to the documentation of pre-commit_.
|
||||
|
||||
@@ -41,9 +41,9 @@ Common Problems For Windows Users
|
||||
|
||||
``/usr/bin/env: python: Permission denied.``
|
||||
|
||||
If you're in Git Bash, please check the Python executable location by run ``which python``.
|
||||
If you are in Git Bash, please check the python executable location by run ``which python``.
|
||||
|
||||
If the executable is under ``~/AppData/Local/Microsoft/WindowsApps/``, then it's a link to Windows AppStore, not a real one.
|
||||
If the executable is under ``~/AppData/Local/Microsoft/WindowsApps/``, then it is a link to Windows AppStore, not a real one.
|
||||
|
||||
Please install Python manually and update this in your ``PATH`` environment variable.
|
||||
|
||||
|
@@ -32,31 +32,31 @@ Naming
|
||||
Indentation
|
||||
^^^^^^^^^^^
|
||||
|
||||
Use 4 spaces for each indentation level. Don't use tabs for indentation. Configure the editor to emit 4 spaces each time you press tab key.
|
||||
Use 4 spaces for each indentation level. Do not use tabs for indentation. Configure the editor to emit 4 spaces each time you press tab key.
|
||||
|
||||
Vertical Space
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
Place one empty line between functions. Don't begin or end a function with an empty line.
|
||||
Place one empty line between functions. Do not begin or end a function with an empty line.
|
||||
::
|
||||
|
||||
void function1()
|
||||
{
|
||||
do_one_thing();
|
||||
do_another_thing();
|
||||
// INCORRECT, don't place empty line here
|
||||
// INCORRECT, do not place empty line here
|
||||
}
|
||||
// place empty line here
|
||||
void function2()
|
||||
{
|
||||
// INCORRECT, don't use an empty line here
|
||||
// INCORRECT, do not use an empty line here
|
||||
int var = 0;
|
||||
while (var < SOME_CONSTANT) {
|
||||
do_stuff(&var);
|
||||
}
|
||||
}
|
||||
|
||||
The maximum line length is 120 characters as long as it doesn't seriously affect the readability.
|
||||
The maximum line length is 120 characters as long as it does not seriously affect the readability.
|
||||
|
||||
Horizontal Space
|
||||
^^^^^^^^^^^^^^^^
|
||||
@@ -98,7 +98,7 @@ Sometimes adding horizontal space within a line can help make code more readable
|
||||
esp_rom_gpio_connect_in_signal(PIN_CAM_HREF, I2S0I_H_ENABLE_IDX, false);
|
||||
esp_rom_gpio_connect_in_signal(PIN_CAM_PCLK, I2S0I_DATA_IN15_IDX, false);
|
||||
|
||||
Note however that if someone goes to add new line with a longer identifier as first argument (e.g. ``PIN_CAM_VSYNC``), it will not fit. So other lines would have to be realigned, adding meaningless changes to the commit.
|
||||
Note however that if someone goes to add new line with a longer identifier as first argument (e.g., ``PIN_CAM_VSYNC``), it will not fit. So other lines would have to be realigned, adding meaningless changes to the commit.
|
||||
|
||||
Therefore, use horizontal alignment sparingly, especially if you expect new lines to be added to the list later.
|
||||
|
||||
@@ -139,7 +139,7 @@ Use ``//`` for single line comments. For multi-line comments it is okay to use e
|
||||
|
||||
Although not directly related to formatting, here are a few notes about using comments effectively.
|
||||
|
||||
- Don't use single comments to disable some functionality::
|
||||
- Do not use single comments to disable some functionality::
|
||||
|
||||
void init_something()
|
||||
{
|
||||
@@ -158,9 +158,9 @@ Although not directly related to formatting, here are a few notes about using co
|
||||
start_timer();
|
||||
}
|
||||
|
||||
- Same goes for ``#if 0 ... #endif`` blocks. Remove code block completely if it is not used. Otherwise, add comment explaining why the block is disabled. Don't use ``#if 0 ... #endif`` or comments to store code snippets which you may need in the future.
|
||||
- Same goes for ``#if 0 ... #endif`` blocks. Remove code block completely if it is not used. Otherwise, add comment explaining why the block is disabled. Do not use ``#if 0 ... #endif`` or comments to store code snippets which you may need in the future.
|
||||
|
||||
- Don't add trivial comments about authorship and change date. You can always look up who modified any given line using git. E.g. this comment adds clutter to the code without adding any useful information::
|
||||
- Do not add trivial comments about authorship and change date. You can always look up who modified any given line using git. E.g., this comment adds clutter to the code without adding any useful information::
|
||||
|
||||
void init_something()
|
||||
{
|
||||
@@ -188,14 +188,14 @@ If you accidentally have some commits in your branch that add LF endings, you ca
|
||||
|
||||
(Note that this line rebases on master, change the branch name at the end to rebase on another branch.)
|
||||
|
||||
For updating a single commit, it's possible to run ``dos2unix FILENAME`` and then run ``git commit --amend``
|
||||
For updating a single commit, it is possible to run ``dos2unix FILENAME`` and then run ``git commit --amend``
|
||||
|
||||
Formatting Your Code
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
You can use ``astyle`` program to format your code according to the above recommendations.
|
||||
|
||||
If you are writing a file from scratch, or doing a complete rewrite, feel free to re-format the entire file. If you are changing a small portion of file, don't re-format the code you didn't change. This will help others when they review your changes.
|
||||
If you are writing a file from scratch, or doing a complete rewrite, feel free to re-format the entire file. If you are changing a small portion of file, do not re-format the code you did not change. This will help others when they review your changes.
|
||||
|
||||
To re-format a file, run:
|
||||
|
||||
@@ -229,17 +229,17 @@ Enums should be defined through the `typedef` and be namespaced::
|
||||
Assertions
|
||||
^^^^^^^^^^
|
||||
|
||||
The standard C ``assert()`` function, defined in ``assert.h`` should be used to check conditions that should be true in source code. In the default configuration, an assert condition that returns ``false`` or 0 will call ``abort()`` and trigger a :doc:`Fatal Error</api-guides/fatal-errors>`.
|
||||
The standard C ``assert()`` function, defined in ``assert.h`` should be used to check conditions that should be true in source code. In the default configuration, an assert condition that returns ``false`` or 0 will call ``abort()`` and trigger a :doc:`Fatal Error </api-guides/fatal-errors>`.
|
||||
|
||||
``assert()`` should only be used to detect unrecoverable errors due to a serious internal logic bug or corruption, where it's not possible for the program to continue. For recoverable errors, including errors that are possible due to invalid external input, an :doc:`error value should be returned </api-guides/error-handling>`.
|
||||
``assert()`` should only be used to detect unrecoverable errors due to a serious internal logic bug or corruption, where it is not possible for the program to continue. For recoverable errors, including errors that are possible due to invalid external input, an :doc:`error value should be returned </api-guides/error-handling>`.
|
||||
|
||||
.. note::
|
||||
|
||||
When asserting a value of type ``esp_err_t``is equal to ``ESP_OK``, use the :ref:`esp-error-check-macro` instead of an ``assert()``.
|
||||
|
||||
It's possible to configure ESP-IDF projects with assertions disabled (see :ref:`CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL`). Therefore, functions called in an ``assert()`` statement should not have side-effects.
|
||||
It is possible to configure ESP-IDF projects with assertions disabled (see :ref:`CONFIG_COMPILER_OPTIMIZATION_ASSERTION_LEVEL`). Therefore, functions called in an ``assert()`` statement should not have side-effects.
|
||||
|
||||
It's also necessary to use particular techniques to avoid "variable set but not used" warnings when assertions are disabled, due to code patterns such as::
|
||||
It is also necessary to use particular techniques to avoid "variable set but not used" warnings when assertions are disabled, due to code patterns such as::
|
||||
|
||||
int res = do_something();
|
||||
assert(res == 0);
|
||||
@@ -263,7 +263,7 @@ If the variable is declared separately, for example if it is used for multiple a
|
||||
assert(res != 0);
|
||||
|
||||
|
||||
Header file guards
|
||||
Header File Guards
|
||||
------------------
|
||||
|
||||
All public facing header files should have preprocessor guards. A pragma is preferred::
|
||||
@@ -294,7 +294,7 @@ In addition to guard macros, all C header files should have ``extern "C"`` guard
|
||||
#endif
|
||||
|
||||
|
||||
Include statements
|
||||
Include Statements
|
||||
------------------
|
||||
|
||||
When writing ``#include`` statements, try to maintain the following order:
|
||||
@@ -323,7 +323,7 @@ C++ Header files have the extension ``.hpp``. C++ source files have the extensio
|
||||
Naming
|
||||
^^^^^^
|
||||
|
||||
* **Class and struct** names shall be written in ``CamelCase`` with a capital letter as beginning. Member variables and methods shall be in ``snake_case``. An exception from ``CamelCase`` is if the readability is severely decreased, e.g. in ``GPIOOutput``, then an underscore ``_`` is allowed to make it more readable: ``GPIO_Output``.
|
||||
* **Class and struct** names shall be written in ``CamelCase`` with a capital letter as beginning. Member variables and methods shall be in ``snake_case``. An exception from ``CamelCase`` is if the readability is severely decreased, e.g., in ``GPIOOutput``, then an underscore ``_`` is allowed to make it more readable: ``GPIO_Output``.
|
||||
* **Namespaces** shall be in lower ``snake_case``.
|
||||
* **Templates** are specified in the line above the function declaration.
|
||||
* Interfaces in terms of Object-Oriented Programming shall be named without the suffix ``...Interface``. Later, this makes it easier to extract interfaces from normal classes and vice versa without making a breaking change.
|
||||
@@ -363,7 +363,7 @@ For example:
|
||||
Spacing
|
||||
^^^^^^^
|
||||
|
||||
* Don't indent inside namespaces.
|
||||
* Do not indent inside namespaces.
|
||||
* Put ``public``, ``protected`` and ``private`` labels at the same indentation level as the corresponding ``class`` label.
|
||||
|
||||
Simple Example
|
||||
@@ -446,7 +446,7 @@ CMake Code Style
|
||||
- Maximum line length 120 characters. When splitting lines, try to
|
||||
focus on readability where possible (for example, by pairing up
|
||||
keyword/argument pairs on individual lines).
|
||||
- Don't put anything in the optional parentheses after ``endforeach()``, ``endif()``, etc.
|
||||
- Do not put anything in the optional parentheses after ``endforeach()``, ``endif()``, etc.
|
||||
- Use lowercase (``with_underscores``) for command, function, and macro names.
|
||||
- For locally scoped variables, use lowercase (``with_underscores``).
|
||||
- For globally scoped variables, use uppercase (``WITH_UNDERSCORES``).
|
||||
|
@@ -22,8 +22,8 @@ Flash encryption is intended for encrypting the contents of the {IDF_TARGET_NAME
|
||||
:doc:`Secure Boot <secure-boot-v2>` is a separate feature which can be used together with flash encryption to create an even more secure environment.
|
||||
|
||||
.. important::
|
||||
For production use, flash encryption should be enabled in the "Release" mode only.
|
||||
|
||||
For production use, flash encryption should be enabled in the "Release" mode only.
|
||||
|
||||
.. important::
|
||||
|
||||
@@ -157,6 +157,7 @@ The flash encryption operation is controlled by various eFuses available on {IDF
|
||||
- 3
|
||||
|
||||
.. note::
|
||||
|
||||
* R/W access control is available for all the eFuse bits listed in the table above.
|
||||
* The default value of these bits is 0 afer manufacturing.
|
||||
|
||||
@@ -165,6 +166,7 @@ Read and write access to eFuse bits is controlled by appropriate fields in the r
|
||||
.. only:: esp32c2
|
||||
|
||||
.. important::
|
||||
|
||||
{IDF_TARGET_NAME} has only one eFuse key block for both keys: Secure Boot and Flash Encryption. As the eFuse key block can only be burned once, these keys should be burned together at the same time. Please note that "Secure Boot" and "Flash Encryption" can not be enabled separately as subsequent writes to eFuse key block shall return an error.
|
||||
|
||||
Flash Encryption Process
|
||||
@@ -178,7 +180,7 @@ Assuming that the eFuse values are in their default states and the firmware boot
|
||||
|
||||
2. Firmware bootloader reads the ``{IDF_TARGET_CRYPT_CNT}`` eFuse value (``0b0000000``). Since the value is ``0`` (even number of bits set), it configures and enables the flash encryption block. It also sets the ``FLASH_CRYPT_CONFIG`` eFuse to 0xF. For more information on the flash encryption block, see *{IDF_TARGET_NAME} Technical Reference Manual* > *eFuse Controller (eFuse)* > *Flash Encryption Block* [`PDF <{IDF_TARGET_TRM_EN_URL}#efuse>`__].
|
||||
|
||||
3. Fimware bootloader first checks if a valid key is already present in the eFuse (e.g. burned using espefuse tool) then the process of key generation is skipped and the same key is used for flash encryption process. Otherwise, Firmware bootloader uses RNG (random) module to generate an AES-256 bit key and then writes it into the ``flash_encryption`` eFuse. The key cannot be accessed via software as the write and read protection bits for the ``flash_encryption`` eFuse are set. The flash encryption operations happen entirely by hardware, and the key cannot be accessed via software.
|
||||
3. Fimware bootloader first checks if a valid key is already present in the eFuse (e.g., burned using espefuse tool) then the process of key generation is skipped and the same key is used for flash encryption process. Otherwise, Firmware bootloader uses RNG (random) module to generate an AES-256 bit key and then writes it into the ``flash_encryption`` eFuse. The key cannot be accessed via software as the write and read protection bits for the ``flash_encryption`` eFuse are set. The flash encryption operations happen entirely by hardware, and the key cannot be accessed via software.
|
||||
|
||||
4. Flash encryption block encrypts the flash contents - the firmware bootloader, applications and partitions marked as ``encrypted``. Encrypting in-place can take time, up to a minute for large partitions.
|
||||
|
||||
@@ -196,7 +198,7 @@ Assuming that the eFuse values are in their default states and the firmware boot
|
||||
|
||||
2. Firmware bootloader reads the ``{IDF_TARGET_CRYPT_CNT}`` eFuse value (``0b000``). Since the value is ``0`` (even number of bits set), it configures and enables the flash encryption block. For more information on the flash encryption block, see *{IDF_TARGET_NAME} Technical Reference Manual* > *eFuse Controller (eFuse)* > *Auto Encryption Block* [`PDF <{IDF_TARGET_TRM_EN_URL}#efuse>`__].
|
||||
|
||||
3.Firmware bootloader first checks if a valid key is already present in the eFuse (e.g. burned using espefuse tool) then the process of key generation is skipped and the same key is used for flash encryption process. Otherwise, Firmware bootloader uses RNG (random) module to generate an 256 bit or 512 bit key, depending on the value of :ref:`Size of generated XTS-AES key <CONFIG_SECURE_FLASH_ENCRYPTION_KEYSIZE>`, and then writes it into respectively one or two `BLOCK_KEYN` eFuses. The software also updates the ``KEY_PURPOSE_N`` for the blocks where the keys were stored. The key cannot be accessed via software as the write and read protection bits for one or two `BLOCK_KEYN` eFuses are set. ``KEY_PURPOSE_N`` field is write-protected as well. The flash encryption operations happen entirely by hardware, and the key cannot be accessed via software.
|
||||
3.Firmware bootloader first checks if a valid key is already present in the eFuse (e.g., burned using espefuse tool) then the process of key generation is skipped and the same key is used for flash encryption process. Otherwise, Firmware bootloader uses RNG (random) module to generate an 256 bit or 512 bit key, depending on the value of :ref:`Size of generated XTS-AES key <CONFIG_SECURE_FLASH_ENCRYPTION_KEYSIZE>`, and then writes it into respectively one or two `BLOCK_KEYN` eFuses. The software also updates the ``KEY_PURPOSE_N`` for the blocks where the keys were stored. The key cannot be accessed via software as the write and read protection bits for one or two `BLOCK_KEYN` eFuses are set. ``KEY_PURPOSE_N`` field is write-protected as well. The flash encryption operations happen entirely by hardware, and the key cannot be accessed via software.
|
||||
|
||||
4. Flash encryption block encrypts the flash contents - the firmware bootloader, applications and partitions marked as ``encrypted``. Encrypting in-place can take time, up to a minute for large partitions.
|
||||
|
||||
@@ -222,7 +224,7 @@ Assuming that the eFuse values are in their default states and the firmware boot
|
||||
|
||||
2. Firmware bootloader reads the ``{IDF_TARGET_CRYPT_CNT}`` eFuse value (``0b000``). Since the value is ``0`` (even number of bits set), it configures and enables the flash encryption block. For more information on the flash encryption block, see `{IDF_TARGET_NAME} Technical Reference Manual <{IDF_TARGET_TRM_EN_URL}>`_.
|
||||
|
||||
3. Firmware bootloader uses RNG (random) module to generate an 256 bit key and then writes it into `BLOCK_KEYN` eFuse. The software also updates the ``KEY_PURPOSE_N`` for the block where the key is stored. The key cannot be accessed via software as the write and read protection bits for `BLOCK_KEYN` eFuse are set. ``KEY_PURPOSE_N`` field is write-protected as well. The flash encryption is completely conducted by hardware, and the key cannot be accessed via software. If a valid key is already present in the eFuse (e.g. burned using espefuse tool) then the process of key generation is skipped and the same key is used for flash encryption process.
|
||||
3. Firmware bootloader uses RNG (random) module to generate an 256 bit key and then writes it into `BLOCK_KEYN` eFuse. The software also updates the ``KEY_PURPOSE_N`` for the block where the key is stored. The key cannot be accessed via software as the write and read protection bits for `BLOCK_KEYN` eFuse are set. ``KEY_PURPOSE_N`` field is write-protected as well. The flash encryption is completely conducted by hardware, and the key cannot be accessed via software. If a valid key is already present in the eFuse (e.g., burned using espefuse tool) then the process of key generation is skipped and the same key is used for flash encryption process.
|
||||
|
||||
4. Flash encryption block encrypts the flash contents - the firmware bootloader, applications and partitions marked as ``encrypted``. Encrypting in-place can take time, up to a minute for large partitions.
|
||||
|
||||
@@ -240,7 +242,7 @@ Assuming that the eFuse values are in their default states and the firmware boot
|
||||
|
||||
2. Firmware bootloader reads the ``{IDF_TARGET_CRYPT_CNT}`` eFuse value (``0b000``). Since the value is ``0`` (even number of bits set), it configures and enables the flash encryption block. For more information on the flash encryption block, see `{IDF_TARGET_NAME} Technical Reference Manual <{IDF_TARGET_TRM_EN_URL}>`_.
|
||||
|
||||
3. Firmware bootloader uses RNG (random) module to generate an 256 or 128 bit key (depends on :ref:`Size of generated XTS-AES key <CONFIG_SECURE_FLASH_ENCRYPTION_KEYSIZE>`) and then writes it into `BLOCK_KEY0` eFuse. The software also updates the ``XTS_KEY_LENGTH_256`` according to the chosen option. The key cannot be accessed via software as the write and read protection bits for `BLOCK_KEY0` eFuse are set. The flash encryption operations happen entirely by hardware, and the key cannot be accessed via software. If 128-bit flash encryption key is used, then only the lower 128 bits of the eFuse key block are read-protected, the remaining 128 bits are readable, which is required for secure boot. The entire eFuse block is write-protected. If the FE key is 256 bits long, then ``XTS_KEY_LENGTH_256`` is 1, otherwise it is 0. To prevent this eFuse from being accidentally changed in the future (from 0 to 1), we set a write-protect bit for the RELEASE mode. If a valid key is already present in the eFuse (e.g. burned using espefuse tool) then the process of key generation is skipped and the same key is used for flash encryption process.
|
||||
3. Firmware bootloader uses RNG (random) module to generate an 256 or 128 bit key (depends on :ref:`Size of generated XTS-AES key <CONFIG_SECURE_FLASH_ENCRYPTION_KEYSIZE>`) and then writes it into `BLOCK_KEY0` eFuse. The software also updates the ``XTS_KEY_LENGTH_256`` according to the chosen option. The key cannot be accessed via software as the write and read protection bits for `BLOCK_KEY0` eFuse are set. The flash encryption operations happen entirely by hardware, and the key cannot be accessed via software. If 128-bit flash encryption key is used, then only the lower 128 bits of the eFuse key block are read-protected, the remaining 128 bits are readable, which is required for secure boot. The entire eFuse block is write-protected. If the FE key is 256 bits long, then ``XTS_KEY_LENGTH_256`` is 1, otherwise it is 0. To prevent this eFuse from being accidentally changed in the future (from 0 to 1), we set a write-protect bit for the RELEASE mode. If a valid key is already present in the eFuse (e.g., burned using espefuse tool) then the process of key generation is skipped and the same key is used for flash encryption process.
|
||||
|
||||
4. Flash encryption block encrypts the flash contents - the firmware bootloader, applications and partitions marked as ``encrypted``. Encrypting in-place can take time, up to a minute for large partitions.
|
||||
|
||||
@@ -342,6 +344,7 @@ It is possible to pre-generate a flash encryption key on the host computer and b
|
||||
.. only:: esp32c2
|
||||
|
||||
.. note::
|
||||
|
||||
Note that {IDF_TARGET_NAME} only has one eFuse key block for both Secure Boot and Flash Encryption keys. Therefore, writing the host-generated Flash Encryption key must be done with Secure Boot key (if used), otherwise Secure Boot cannot be used.
|
||||
|
||||
To use a host generated key, take the following steps:
|
||||
@@ -524,7 +527,7 @@ To use this mode, take the following steps:
|
||||
|
||||
- :ref:`Enable flash encryption on boot <CONFIG_SECURE_FLASH_ENC_ENABLED>`
|
||||
:esp32: - :ref:`Select Release mode <CONFIG_SECURE_FLASH_ENCRYPTION_MODE>` (Note that once Release mode is selected, the ``DISABLE_DL_ENCRYPT`` and ``DISABLE_DL_DECRYPT`` eFuse bits will be burned to disable flash encryption hardware in ROM Download Mode.)
|
||||
:esp32: - :ref:`Select UART ROM download mode (Permanently disabled (recommended)) <CONFIG_SECURE_UART_ROM_DL_MODE>` (Note that this option is only available when :ref:`CONFIG_ESP32_REV_MIN` is set to 3 (ESP32 V3).) The default choice is to keep UART ROM download mode enabled, however it's recommended to permanently disable this mode to reduce the options available to an attacker.
|
||||
:esp32: - :ref:`Select UART ROM download mode (Permanently disabled (recommended)) <CONFIG_SECURE_UART_ROM_DL_MODE>` (Note that this option is only available when :ref:`CONFIG_ESP32_REV_MIN` is set to 3 (ESP32 V3).) The default choice is to keep UART ROM download mode enabled, however it is recommended to permanently disable this mode to reduce the options available to an attacker.
|
||||
:not esp32: - :ref:`Select Release mode <CONFIG_SECURE_FLASH_ENCRYPTION_MODE>` (Note that once Release mode is selected, the ``EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT`` eFuse bit will be burned to disable flash encryption hardware in ROM Download Mode.)
|
||||
:not esp32: - :ref:`Select UART ROM download mode (Permanently switch to Secure mode (recommended)) <CONFIG_SECURE_UART_ROM_DL_MODE>`. This is the default option, and is recommended. It is also possible to change this configuration setting to permanently disable UART ROM download mode, if this mode is not needed.
|
||||
- :ref:`Select the appropriate bootloader log verbosity <CONFIG_BOOTLOADER_LOG_LEVEL>`
|
||||
@@ -782,7 +785,7 @@ Flashing an encrypted device via serial bootloader requires that the serial boot
|
||||
|
||||
In Development Mode, the recommended method is :ref:`encrypt-partitions`.
|
||||
|
||||
In Release Mode, if a copy of the same key stored in eFuse is available on the host then it's possible to pre-encrypt files on the host and then flash them. See :ref:`manual-encryption`.
|
||||
In Release Mode, if a copy of the same key stored in eFuse is available on the host then it is possible to pre-encrypt files on the host and then flash them. See :ref:`manual-encryption`.
|
||||
|
||||
Disabling Flash Encryption
|
||||
--------------------------
|
||||
@@ -848,10 +851,10 @@ Flash encryption protects firmware against unauthorised readout and modification
|
||||
|
||||
.. list::
|
||||
|
||||
- Flash encryption is only as strong as the key. For this reason, we recommend keys are generated on the device during first boot (default behaviour). If generating keys off-device, ensure proper procedure is followed and don't share the same key between all production devices.
|
||||
- Flash encryption is only as strong as the key. For this reason, we recommend keys are generated on the device during first boot (default behaviour). If generating keys off-device, ensure proper procedure is followed and do not share the same key between all production devices.
|
||||
- Not all data is stored encrypted. If storing data on flash, check if the method you are using (library, API, etc.) supports flash encryption.
|
||||
- Flash encryption does not prevent an attacker from understanding the high-level layout of the flash. This is because the same AES key is used for every pair of adjacent 16 byte AES blocks. When these adjacent 16 byte blocks contain identical content (such as empty or padding areas), these blocks will encrypt to produce matching pairs of encrypted blocks. This may allow an attacker to make high-level comparisons between encrypted devices (i.e. to tell if two devices are probably running the same firmware version).
|
||||
:esp32: - For the same reason, an attacker can always tell when a pair of adjacent 16 byte blocks (32 byte aligned) contain two identical 16 byte sequences. Keep this in mind if storing sensitive data on the flash, design your flash storage so this doesn't happen (using a counter byte or some other non-identical value every 16 bytes is sufficient). :doc:`NVS Encryption <../api-reference/storage/nvs_encryption>` deals with this and is suitable for many uses.
|
||||
- Flash encryption does not prevent an attacker from understanding the high-level layout of the flash. This is because the same AES key is used for every pair of adjacent 16 byte AES blocks. When these adjacent 16 byte blocks contain identical content (such as empty or padding areas), these blocks will encrypt to produce matching pairs of encrypted blocks. This may allow an attacker to make high-level comparisons between encrypted devices (i.e., to tell if two devices are probably running the same firmware version).
|
||||
:esp32: - For the same reason, an attacker can always tell when a pair of adjacent 16 byte blocks (32 byte aligned) contain two identical 16 byte sequences. Keep this in mind if storing sensitive data on the flash, design your flash storage so this does not happen (using a counter byte or some other non-identical value every 16 bytes is sufficient). :doc:`NVS Encryption <../api-reference/storage/nvs_encryption>` deals with this and is suitable for many uses.
|
||||
- Flash encryption alone may not prevent an attacker from modifying the firmware of the device. To prevent unauthorised firmware from running on the device, use flash encryption in combination with :doc:`Secure Boot <secure-boot-v2>`.
|
||||
|
||||
.. _flash-encryption-and-secure-boot:
|
||||
@@ -988,7 +991,7 @@ See :ref:`jtag-debugging-security-features` for more information about using JTA
|
||||
Manually Encrypting Files
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Manually encrypting or decrypting files requires the flash encryption key to be pre-burned in eFuse (see :ref:`pregenerated-flash-encryption-key`) and a copy to be kept on the host. If the flash encryption is configured in Development Mode then it's not necessary to keep a copy of the key or follow these steps, the simpler :ref:`encrypt-partitions` steps can be used.
|
||||
Manually encrypting or decrypting files requires the flash encryption key to be pre-burned in eFuse (see :ref:`pregenerated-flash-encryption-key`) and a copy to be kept on the host. If the flash encryption is configured in Development Mode then it is not necessary to keep a copy of the key or follow these steps, the simpler :ref:`encrypt-partitions` steps can be used.
|
||||
|
||||
The key file should be a single raw binary file (example: ``key.bin``).
|
||||
|
||||
@@ -1076,7 +1079,7 @@ The following sections provide some reference information about the operation of
|
||||
|
||||
- {IDF_TARGET_NAME} use the XTS-AES block cipher mode with 256 bit or 512 bit key size for flash encryption.
|
||||
|
||||
- XTS-AES is a block cipher mode specifically designed for disc encryption and addresses the weaknesses other potential modes (e.g. AES-CTR) have for this use case. A detailed description of the XTS-AES algorithm can be found in `IEEE Std 1619-2007 <https://ieeexplore.ieee.org/document/4493450>`_.
|
||||
- XTS-AES is a block cipher mode specifically designed for disc encryption and addresses the weaknesses other potential modes (e.g., AES-CTR) have for this use case. A detailed description of the XTS-AES algorithm can be found in `IEEE Std 1619-2007 <https://ieeexplore.ieee.org/document/4493450>`_.
|
||||
|
||||
- The flash encryption key is stored in one or two ``BLOCK_KEYN`` eFuses and, by default, is protected from further writes or software readout.
|
||||
|
||||
@@ -1092,7 +1095,7 @@ The following sections provide some reference information about the operation of
|
||||
|
||||
- {IDF_TARGET_NAME} use the XTS-AES block chiper mode with 256 bit size for flash encryption.
|
||||
|
||||
- XTS-AES is a block chiper mode specifically designed for disc encryption and addresses the weaknesses other potential modes (e.g. AES-CTR) have for this use case. A detailed description of the XTS-AES algorithm can be found in `IEEE Std 1619-2007 <https://ieeexplore.ieee.org/document/4493450>`_.
|
||||
- XTS-AES is a block chiper mode specifically designed for disc encryption and addresses the weaknesses other potential modes (e.g., AES-CTR) have for this use case. A detailed description of the XTS-AES algorithm can be found in `IEEE Std 1619-2007 <https://ieeexplore.ieee.org/document/4493450>`_.
|
||||
|
||||
- The flash encryption key is stored in one ``BLOCK_KEYN`` eFuse and, by default, is protected from further writes or software readout.
|
||||
|
||||
@@ -1107,7 +1110,7 @@ The following sections provide some reference information about the operation of
|
||||
|
||||
- {IDF_TARGET_NAME} use the XTS-AES block chiper mode with 256 bit size for flash encryption. In case the 128-bit key is stored in the eFuse key block, the final 256-bit AES key is obtained as SHA256(EFUSE_KEY0_FE_128BIT).
|
||||
|
||||
- XTS-AES is a block chiper mode specifically designed for disc encryption and addresses the weaknesses other potential modes (e.g. AES-CTR) have for this use case. A detailed description of the XTS-AES algorithm can be found in `IEEE Std 1619-2007 <https://ieeexplore.ieee.org/document/4493450>`_.
|
||||
- XTS-AES is a block chiper mode specifically designed for disc encryption and addresses the weaknesses other potential modes (e.g., AES-CTR) have for this use case. A detailed description of the XTS-AES algorithm can be found in `IEEE Std 1619-2007 <https://ieeexplore.ieee.org/document/4493450>`_.
|
||||
|
||||
- The flash encryption key is stored in ``BLOCK_KEY0`` eFuse and, by default, is protected from further writes or software readout.
|
||||
|
||||
|
@@ -23,6 +23,7 @@ Goals
|
||||
|
||||
Pre-requisite
|
||||
-------------
|
||||
|
||||
* ``esptool``: Please make sure the ``esptool`` has been installed. It can be installed by running:
|
||||
|
||||
.. code:: bash
|
||||
@@ -31,6 +32,7 @@ Pre-requisite
|
||||
|
||||
Scope
|
||||
-----
|
||||
|
||||
* :ref:`enable-flash-encryption-and-secure-boot-v2-externally`
|
||||
* :ref:`enable-flash-encryption-externally`
|
||||
* :ref:`enable-secure-boot-v2-externally`
|
||||
@@ -65,8 +67,7 @@ In this case all the eFuses related to flash encryption are written with help of
|
||||
|
||||
See how to check :ref:`flash-encryption-status`.
|
||||
|
||||
In this case the Flash on the chip must be erased and flash encryption must not be enabled.
|
||||
The chip can be erased by running:
|
||||
In this case the flash on the chip must be erased and flash encryption must not be enabled. The chip can be erased by running:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
@@ -223,7 +224,7 @@ In this case all the eFuses related to flash encryption are written with help of
|
||||
|
||||
- :ref:`Enable flash encryption on boot <CONFIG_SECURE_FLASH_ENC_ENABLED>`
|
||||
:esp32: - :ref:`Select Release mode <CONFIG_SECURE_FLASH_ENCRYPTION_MODE>` (Note that once Release mode is selected, the ``DISABLE_DL_ENCRYPT`` and ``DISABLE_DL_DECRYPT`` eFuse bits will be burned to disable flash encryption hardware in ROM Download Mode.)
|
||||
:esp32: - :ref:`Select UART ROM download mode (Permanently disabled (recommended)) <CONFIG_SECURE_UART_ROM_DL_MODE>` (Note that this option is only available when :ref:`CONFIG_ESP32_REV_MIN` is set to 3 (ESP32 V3).) The default choice is to keep UART ROM download mode enabled, however it's recommended to permanently disable this mode to reduce the options available to an attacker.
|
||||
:esp32: - :ref:`Select UART ROM download mode (Permanently disabled (recommended)) <CONFIG_SECURE_UART_ROM_DL_MODE>` (Note that this option is only available when :ref:`CONFIG_ESP32_REV_MIN` is set to 3 (ESP32 V3).) The default choice is to keep UART ROM download mode enabled, however it is recommended to permanently disable this mode to reduce the options available to an attacker.
|
||||
:not esp32: - :ref:`Select Release mode <CONFIG_SECURE_FLASH_ENCRYPTION_MODE>` (Note that once Release mode is selected, the ``EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT`` eFuse bit will be burned to disable flash encryption hardware in ROM Download Mode.)
|
||||
:not esp32: - :ref:`Select UART ROM download mode (Permanently switch to Secure mode (recommended)) <CONFIG_SECURE_UART_ROM_DL_MODE>`. This is the default option, and is recommended. It is also possible to change this configuration setting to permanently disable UART ROM download mode, if this mode is not needed.
|
||||
- :ref:`Select the appropriate bootloader log verbosity <CONFIG_BOOTLOADER_LOG_LEVEL>`
|
||||
@@ -294,7 +295,9 @@ In this case all the eFuses related to flash encryption are written with help of
|
||||
|
||||
espefuse.py burn_efuse --port PORT EFUSE_NAME 0x1
|
||||
|
||||
.. note:: Please update the EFUSE_NAME with the eFuse that you need to burn. Multiple eFuses can be burned at the same time by appending them to the above command (e.g., EFUSE_NAME VAL EFUSE_NAME2 VAL2). More documentation about `espefuse.py` can be found `here <https://docs.espressif.com/projects/esptool/en/latest/esp32/espefuse/index.html>`_
|
||||
.. note::
|
||||
|
||||
Please update the EFUSE_NAME with the eFuse that you need to burn. Multiple eFuses can be burned at the same time by appending them to the above command (e.g., EFUSE_NAME VAL EFUSE_NAME2 VAL2). More documentation about `espefuse.py` can be found `here <https://docs.espressif.com/projects/esptool/en/latest/esp32/espefuse/index.html>`_
|
||||
|
||||
B) Write protect security eFuses:
|
||||
|
||||
@@ -366,6 +369,7 @@ Flash Encryption Guidelines
|
||||
|
||||
Enable Secure Boot V2 Externally
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
In this workflow we shall use ``espsecure`` tool to generate signing keys and use the ``espefuse`` tool to burn the relevant eFuses. The details about the Secure Boot V2 process can be found at :doc:`Secure Boot V2 Guide </security/secure-boot-v2>`
|
||||
|
||||
1. Generate Secure Boot V2 Signing Private Key.
|
||||
@@ -471,7 +475,7 @@ In this workflow we shall use ``espsecure`` tool to generate signing keys and us
|
||||
|
||||
6. Sign and Flash the binaries.
|
||||
|
||||
The Secure Boot V2 workflow only verifies the ``bootloader`` and ``application`` binaries, hence only those binaries need to be signed. The other binaries (e.g. ``partition-table.bin``) can be flashed as they are generated in the build stage.
|
||||
The Secure Boot V2 workflow only verifies the ``bootloader`` and ``application`` binaries, hence only those binaries need to be signed. The other binaries (e.g., ``partition-table.bin``) can be flashed as they are generated in the build stage.
|
||||
|
||||
The ``bootloader.bin`` and ``app.bin`` binaries can be signed by running:
|
||||
|
||||
@@ -499,7 +503,7 @@ In this workflow we shall use ``espsecure`` tool to generate signing keys and us
|
||||
|
||||
espsecure.py signature_info_v2 bootloader-signed.bin
|
||||
|
||||
The above files along with other binaries (e.g. partition table) can then be flashed to their respective offset using ``esptool.py``. To see all of the command line options recommended for ``esptool.py``, see the output printed when ``idf.py build`` succeeds. The flash offset for your firmware can be obtained by checking the partition table entry or by running ``idf.py partition-table``.
|
||||
The above files along with other binaries (e.g., partition table) can then be flashed to their respective offset using ``esptool.py``. To see all of the command line options recommended for ``esptool.py``, see the output printed when ``idf.py build`` succeeds. The flash offset for your firmware can be obtained by checking the partition table entry or by running ``idf.py partition-table``.
|
||||
|
||||
7. Burn relevant eFuses.
|
||||
|
||||
@@ -527,7 +531,9 @@ In this workflow we shall use ``espsecure`` tool to generate signing keys and us
|
||||
|
||||
espefuse.py burn_efuse --port PORT EFUSE_NAME 0x1
|
||||
|
||||
.. note:: Please update the EFUSE_NAME with the eFuse that you need to burn. Multiple eFuses can be burned at the same time by appending them to the above command (e.g., EFUSE_NAME VAL EFUSE_NAME2 VAL2). More documentation about `espefuse.py` can be found `here <https://docs.espressif.com/projects/esptool/en/latest/esp32/espefuse/index.html>`_
|
||||
.. note::
|
||||
|
||||
Please update the EFUSE_NAME with the eFuse that you need to burn. Multiple eFuses can be burned at the same time by appending them to the above command (e.g., EFUSE_NAME VAL EFUSE_NAME2 VAL2). More documentation about `espefuse.py` can be found `here <https://docs.espressif.com/projects/esptool/en/latest/esp32/espefuse/index.html>`_
|
||||
|
||||
B) Secure Boot V2 related eFuses:
|
||||
|
||||
|
@@ -1,5 +1,6 @@
|
||||
Security Guides
|
||||
***************
|
||||
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
Overview
|
||||
|
@@ -3,12 +3,12 @@ Secure Boot
|
||||
|
||||
.. important::
|
||||
|
||||
All references in this document are related to Secure Boot V1 (The AES based Secure Boot Scheme). ESP32 Revision 3 onwards, the preferred secure boot scheme is :doc:`Secure Boot V2 <secure-boot-v2>`.
|
||||
All references in this document are related to Secure Boot V1 (The AES based Secure Boot Scheme). ESP32 Revision 3 onwards, the preferred secure boot scheme is :doc:`secure-boot-v2`.
|
||||
Please refer to Secure Boot V2 document for ESP32 Revision 3 or ESP32-S2.
|
||||
|
||||
Secure Boot is a feature for ensuring only your code can run on the chip. Data loaded from flash is verified on each reset.
|
||||
|
||||
Secure Boot is separate from the :doc:`Flash Encryption <flash-encryption>` feature, and you can use secure boot without encrypting the flash contents. However, for a secure environment both should be used simultaneously. See :ref:`secure-boot-and-flash-encr` for more details.
|
||||
Secure Boot is separate from the :doc:`flash-encryption` feature, and you can use secure boot without encrypting the flash contents. However, for a secure environment both should be used simultaneously. See :ref:`secure-boot-and-flash-encr` for more details.
|
||||
|
||||
.. important::
|
||||
|
||||
@@ -21,7 +21,7 @@ Background
|
||||
|
||||
- Efuses are used to store the secure bootloader key (in efuse BLOCK2), and also a single Efuse bit (ABS_DONE_0) is burned (written to 1) to permanently enable secure boot on the chip. For more details on eFuses, see *{IDF_TARGET_NAME} Technical Reference Manual* > *eFuse Controller (eFuse)* [`PDF <{IDF_TARGET_TRM_EN_URL}#efuse>`__].
|
||||
|
||||
- To understand the secure boot process, first familiarise yourself with the standard :doc:`ESP-IDF boot process <../api-guides/startup>`.
|
||||
- To understand the secure boot process, first familiarise yourself with the standard :doc:`../api-guides/startup`.
|
||||
|
||||
- Both stages of the boot process (initial software bootloader load, and subsequent partition & app loading) are verified by the secure boot process, in a "chain of trust" relationship.
|
||||
|
||||
@@ -60,7 +60,7 @@ The following keys are used by the secure boot process:
|
||||
|
||||
For more details, see *{IDF_TARGET_NAME} Technical Reference Manual* > *eFuse Controller (eFuse)* > *System Parameter coding_scheme* [`PDF <{IDF_TARGET_TRM_EN_URL}#efuse>`__].
|
||||
|
||||
The algorithm operates on a 256 bit key in all cases, 192 bit keys are extended by repeating some bits (:ref:`details<secure-bootloader-digest-algorithm>`).
|
||||
The algorithm operates on a 256 bit key in all cases, 192 bit keys are extended by repeating some bits (:ref:`secure-bootloader-digest-algorithm`).
|
||||
|
||||
- "secure boot signing key" is a standard ECDSA public/private key pair (see :ref:`secure-boot-image-signing-algorithm`) in PEM format.
|
||||
|
||||
@@ -87,26 +87,34 @@ How To Enable Secure Boot
|
||||
4. The first time you run ``make``, if the signing key is not found then an error message will be printed with a command to generate a signing key via ``espsecure.py generate_signing_key``.
|
||||
|
||||
.. important::
|
||||
|
||||
A signing key generated this way will use the best random number source available to the OS and its Python installation (`/dev/urandom` on OSX/Linux and `CryptGenRandom()` on Windows). If this random number source is weak, then the private key will be weak.
|
||||
|
||||
.. important::
|
||||
|
||||
For production environments, we recommend generating the keypair using openssl or another industry standard encryption program. See :ref:`secure-boot-generate-key` for more details.
|
||||
|
||||
5. Run ``idf.py bootloader`` to build a secure boot enabled bootloader. The build output will include a prompt for a flashing command, using ``esptool.py write_flash``.
|
||||
|
||||
.. _secure-boot-resume-normal-flashing:
|
||||
|
||||
6. When you're ready to flash the bootloader, run the specified command (you have to enter it yourself, this step is not performed by make) and then wait for flashing to complete. **Remember this is a one time flash, you can't change the bootloader after this!**.
|
||||
6. When you are ready to flash the bootloader, run the specified command (you have to enter it yourself, this step is not performed by make) and then wait for flashing to complete. **Remember this is a one time flash, you can not change the bootloader after this!**.
|
||||
|
||||
7. Run ``idf.py flash`` to build and flash the partition table and the just-built app image. The app image will be signed using the signing key you generated in step 4.
|
||||
|
||||
.. note:: ``idf.py flash`` doesn't flash the bootloader if secure boot is enabled.
|
||||
.. note::
|
||||
|
||||
``idf.py flash`` does not flash the bootloader if secure boot is enabled.
|
||||
|
||||
8. Reset the {IDF_TARGET_NAME} and it will boot the software bootloader you flashed. The software bootloader will enable secure boot on the chip, and then it verifies the app image signature and boots the app. You should watch the serial console output from the {IDF_TARGET_NAME} to verify that secure boot is enabled and no errors have occurred due to the build configuration.
|
||||
|
||||
.. note:: Secure boot won't be enabled until after a valid partition table and app image have been flashed. This is to prevent accidents before the system is fully configured.
|
||||
.. note::
|
||||
|
||||
.. note:: If the {IDF_TARGET_NAME} is reset or powered down during the first boot, it will start the process again on the next boot.
|
||||
Secure boot will not be enabled until after a valid partition table and app image have been flashed. This is to prevent accidents before the system is fully configured.
|
||||
|
||||
.. note::
|
||||
|
||||
If the {IDF_TARGET_NAME} is reset or powered down during the first boot, it will start the process again on the next boot.
|
||||
|
||||
9. On subsequent boots, the secure boot hardware will verify the software bootloader has not changed (using the secure bootloader key) and then the software bootloader will verify the signed partition table and app image (using the public key portion of the secure boot signing key).
|
||||
|
||||
@@ -117,15 +125,17 @@ Re-Flashable Software Bootloader
|
||||
|
||||
Configuration "Secure Boot: One-Time Flash" is the recommended configuration for production devices. In this mode, each device gets a unique key that is never stored outside the device.
|
||||
|
||||
However, an alternative mode :ref:`Secure Boot: Reflashable <CONFIG_SECURE_BOOTLOADER_MODE>` is also available. This mode allows you to supply a binary key file that is used for the secure bootloader key. As you have the key file, you can generate new bootloader images and secure boot digests for them.
|
||||
However, an alternative mode :ref:`CONFIG_SECURE_BOOTLOADER_MODE` is also available. This mode allows you to supply a binary key file that is used for the secure bootloader key. As you have the key file, you can generate new bootloader images and secure boot digests for them.
|
||||
|
||||
In the esp-idf build process, this 256-bit key file is derived from the ECDSA app signing key generated by the user (see the :ref:`secure-boot-generate-key` step below). This private key's SHA-256 digest is used as the secure bootloader key in efuse (as-is for Coding Scheme None, or truncate to 192 bytes for 3/4 Encoding). This is a convenience so you only need to generate/protect a single private key.
|
||||
|
||||
.. note:: Although it's possible, we strongly recommend not generating one secure boot key and flashing it to every device in a production environment. The "One-Time Flash" option is recommended for production environments.
|
||||
.. note::
|
||||
|
||||
Although it is possible, we strongly recommend not generating one secure boot key and flashing it to every device in a production environment. The "One-Time Flash" option is recommended for production environments.
|
||||
|
||||
To enable a reflashable bootloader:
|
||||
|
||||
1. In the :ref:`project-configuration-menu`, select "Bootloader Config" -> :ref:`CONFIG_SECURE_BOOT` -> CONFIG_SECURE_BOOT_V1_ENABLED -> :ref:`CONFIG_SECURE_BOOTLOADER_MODE` -> Reflashable.
|
||||
1. In the :ref:`project-configuration-menu`, select "Bootloader Config" > :ref:`CONFIG_SECURE_BOOT` > CONFIG_SECURE_BOOT_V1_ENABLED > :ref:`CONFIG_SECURE_BOOTLOADER_MODE` > Reflashable.
|
||||
|
||||
2. If necessary, set the :ref:`CONFIG_SECURE_BOOTLOADER_KEY_ENCODING` based on the coding scheme used by the device. The coding scheme is shown in the ``Features`` line when ``esptool.py`` connects to the chip, or in the ``espefuse.py summary`` output.
|
||||
|
||||
@@ -182,7 +192,7 @@ Secure Boot Best Practices
|
||||
* Keep the signing key private at all times. A leak of this key will compromise the secure boot system.
|
||||
* Do not allow any third party to observe any aspects of the key generation or signing process using espsecure.py. Both processes are vulnerable to timing or other side-channel attacks.
|
||||
* Enable all secure boot options in the Secure Boot Configuration. These include flash encryption, disabling of JTAG, disabling BASIC ROM interpeter, and disabling the UART bootloader encrypted flash access.
|
||||
* Use secure boot in combination with :doc:`flash encryption<flash-encryption>` to prevent local readout of the flash contents.
|
||||
* Use secure boot in combination with :doc:`flash-encryption` to prevent local readout of the flash contents.
|
||||
|
||||
.. _secure-boot-technical-details:
|
||||
|
||||
@@ -271,7 +281,7 @@ The output of the ``espsecure.py digest_secure_bootloader`` command is a single
|
||||
Secure Boot & Flash Encryption
|
||||
------------------------------
|
||||
|
||||
If secure boot is used without :doc:`Flash Encryption <flash-encryption>`, it is possible to launch "time-of-check to time-of-use" attack, where flash contents are swapped after the image is verified and running. Therefore, it is recommended to use both the features together.
|
||||
If secure boot is used without :doc:`flash-encryption`, it is possible to launch "time-of-check to time-of-use" attack, where flash contents are swapped after the image is verified and running. Therefore, it is recommended to use both the features together.
|
||||
|
||||
.. _signed-app-verify:
|
||||
|
||||
@@ -286,20 +296,20 @@ An app can be verified on update and, optionally, be verified on boot.
|
||||
|
||||
- Verification on update: When enabled, the signature is automatically checked whenever the esp_ota_ops.h APIs are used for OTA updates. If hardware secure boot is enabled, this option is always enabled and cannot be disabled. If hardware secure boot is not enabled, this option still adds significant security against network-based attackers by preventing spoofing of OTA updates.
|
||||
|
||||
- Verification on boot: When enabled, the bootloader will be compiled with code to verify that an app is signed before booting it. If hardware secure boot is enabled, this option is always enabled and cannot be disabled. If hardware secure boot is not enabled, this option doesn't add significant security by itself so most users will want to leave it disabled.
|
||||
- Verification on boot: When enabled, the bootloader will be compiled with code to verify that an app is signed before booting it. If hardware secure boot is enabled, this option is always enabled and cannot be disabled. If hardware secure boot is not enabled, this option does not add significant security by itself so most users will want to leave it disabled.
|
||||
|
||||
.. _signed-app-verify-howto:
|
||||
|
||||
How To Enable Signed App Verification
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
1. Open :ref:`project-configuration-menu` -> Security features -> Enable :ref:`CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT`
|
||||
1. Open :ref:`project-configuration-menu` > Security features > Enable :ref:`CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT`
|
||||
|
||||
2. "Bootloader verifies app signatures" can be enabled, which verifies app on boot.
|
||||
|
||||
3. By default, "Sign binaries during build" will be enabled on selecting "Require signed app images" option, which will sign binary files as a part of build process. The file named in "Secure boot private signing key" will be used to sign the image.
|
||||
|
||||
4. If you disable "Sign binaries during build" option then you'll have to enter path of a public key file used to verify signed images in "Secure boot public signature verification key".
|
||||
4. If you disable "Sign binaries during build" option then you will have to enter path of a public key file used to verify signed images in "Secure boot public signature verification key".
|
||||
In this case, private signing key should be generated by following instructions in :ref:`secure-boot-generate-key`; public verification key and signed image should be generated by following instructions in :ref:`remote-sign-image`.
|
||||
|
||||
Advanced Features
|
||||
|
@@ -25,7 +25,7 @@ Secure Boot V2
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
For ESP32 before ECO3, refer to :doc:`Secure Boot <secure-boot-v1>`. It is recommended that users use Secure Boot V2 if they have a chip version that supports it. Secure Boot V2 is safer and more flexible than Secure Boot V1.
|
||||
For ESP32 before ECO3, refer to :doc:`secure-boot-v1`. It is recommended that users use Secure Boot V2 if they have a chip version that supports it. Secure Boot V2 is safer and more flexible than Secure Boot V1.
|
||||
|
||||
Secure Boot V2 uses {IDF_TARGET_SBV2_SCHEME} based app and bootloader (:ref:`second-stage-bootloader`) verification. This document can also be used as a reference for signing apps using the {IDF_TARGET_SBV2_SCHEME} scheme without signing the bootloader.
|
||||
|
||||
@@ -126,7 +126,7 @@ The Secure Boot V2 process follows these steps:
|
||||
Signature Block Format
|
||||
----------------------
|
||||
|
||||
The signature block starts on a 4KB aligned boundary and has a flash sector of its own. The signature is calculated over all bytes in the image including the padding bytes (:ref:`secure_padding`).
|
||||
The signature block starts on a 4 KB aligned boundary and has a flash sector of its own. The signature is calculated over all bytes in the image including the padding bytes (:ref:`secure_padding`).
|
||||
|
||||
.. only:: SOC_SECURE_BOOT_V2_RSA and SOC_SECURE_BOOT_V2_ECC
|
||||
|
||||
@@ -201,6 +201,7 @@ The content of each signature block is shown in the following table:
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
R and M' are used for hardware-assisted Montgomery Multiplication.
|
||||
|
||||
.. only:: SOC_SECURE_BOOT_V2_ECC
|
||||
@@ -278,6 +279,7 @@ Following table explains the Secure Boot V2 signed image with secure padding and
|
||||
- Signature block
|
||||
|
||||
.. note::
|
||||
|
||||
Please note that the application image always starts on the next flash MMU page size boundary (default 64KB) and hence the space left over after the signature block shown above can be utilized to store any other data partitions (e.g., ``nvs``).
|
||||
|
||||
.. _verify_signature-block:
|
||||
@@ -285,18 +287,18 @@ Following table explains the Secure Boot V2 signed image with secure padding and
|
||||
Verifying a Signature Block
|
||||
-----------------------------
|
||||
|
||||
A signature block is “valid” if the first byte is 0xe7 and a valid CRC32 is stored at offset 1196. Otherwise it's invalid.
|
||||
A signature block is "valid" if the first byte is 0xe7 and a valid CRC32 is stored at offset 1196. Otherwise it is invalid.
|
||||
|
||||
.. _verify_image:
|
||||
|
||||
Verifying an Image
|
||||
-----------------------------
|
||||
|
||||
An image is “verified” if the public key stored in any signature block is valid for this device, and if the stored signature is valid for the image data read from flash.
|
||||
An image is "verified" if the public key stored in any signature block is valid for this device, and if the stored signature is valid for the image data read from flash.
|
||||
|
||||
1. Compare the SHA-256 hash digest of the public key embedded in the bootloader's signature block with the digest(s) saved in the eFuses. If public key's hash doesn't match any of the hashes from the eFuses, the verification fails.
|
||||
1. Compare the SHA-256 hash digest of the public key embedded in the bootloader's signature block with the digest(s) saved in the eFuses. If public key's hash does not match any of the hashes from the eFuses, the verification fails.
|
||||
|
||||
2. Generate the application image digest and match it with the image digest in the signature block. If the digests don't match, the verification fails.
|
||||
2. Generate the application image digest and match it with the image digest in the signature block. If the digests do not match, the verification fails.
|
||||
|
||||
.. only:: esp32 or (SOC_SECURE_BOOT_V2_RSA and not SOC_SECURE_BOOT_V2_ECC)
|
||||
|
||||
@@ -320,7 +322,7 @@ In the case when :ref:`CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES` is disabled, th
|
||||
|
||||
.. _efuse-usage:
|
||||
|
||||
eFuse usage
|
||||
eFuse Usage
|
||||
-----------
|
||||
|
||||
.. only:: esp32
|
||||
@@ -329,7 +331,7 @@ eFuse usage
|
||||
|
||||
- ABS_DONE_1 - Enables Secure Boot protection on boot.
|
||||
|
||||
- BLK2 - Stores the SHA-256 digest of the public key. SHA-256 hash of public key modulus, exponent, pre-calculated R & M’ values (represented as 776 bytes – offsets 36 to 812 - as per the :ref:`signature-block-format`) is written to an eFuse key block. The write-protection bit must be set, but the read-protection bit must not.
|
||||
- BLK2 - Stores the SHA-256 digest of the public key. SHA-256 hash of public key modulus, exponent, pre-calculated R & M' values (represented as 776 bytes – offsets 36 to 812 - as per the :ref:`signature-block-format`) is written to an eFuse key block. The write-protection bit must be set, but the read-protection bit must not.
|
||||
|
||||
.. only:: not esp32
|
||||
|
||||
@@ -339,7 +341,7 @@ eFuse usage
|
||||
|
||||
- KEY_PURPOSE_X - Set the purpose of the key block on {IDF_TARGET_NAME} by programming SECURE_BOOT_DIGESTX (X = 0, 1, 2) into KEY_PURPOSE_X (X = 0, 1, 2, 3, 4, 5). Example: If KEY_PURPOSE_2 is set to SECURE_BOOT_DIGEST1, then BLOCK_KEY2 will have the Secure Boot V2 public key digest. The write-protection bit must be set (this field does not have a read-protection bit).
|
||||
|
||||
- BLOCK_KEYX - The block contains the data corresponding to its purpose programmed in KEY_PURPOSE_X. Stores the SHA-256 digest of the public key. SHA-256 hash of public key modulus, exponent, pre-calculated R & M’ values (represented as 776 bytes – offsets 36 to 812 - as per the :ref:`signature-block-format`) is written to an eFuse key block. The write-protection bit must be set, but the read-protection bit must not.
|
||||
- BLOCK_KEYX - The block contains the data corresponding to its purpose programmed in KEY_PURPOSE_X. Stores the SHA-256 digest of the public key. SHA-256 hash of public key modulus, exponent, pre-calculated R & M' values (represented as 776 bytes – offsets 36 to 812 - as per the :ref:`signature-block-format`) is written to an eFuse key block. The write-protection bit must be set, but the read-protection bit must not.
|
||||
|
||||
- KEY_REVOKEX - The revocation bits corresponding to each of the 3 key block. Ex. Setting KEY_REVOKE2 revokes the key block whose key purpose is SECURE_BOOT_DIGEST2.
|
||||
|
||||
@@ -384,21 +386,27 @@ How To Enable Secure Boot V2
|
||||
|
||||
7. Run ``idf.py bootloader`` to build a Secure Boot enabled bootloader. The build output will include a prompt for a flashing command, using ``esptool.py write_flash``.
|
||||
|
||||
8. When you're ready to flash the bootloader, run the specified command (you have to enter it yourself, this step is not performed by the build system) and then wait for flashing to complete.
|
||||
8. When you are ready to flash the bootloader, run the specified command (you have to enter it yourself, this step is not performed by the build system) and then wait for flashing to complete.
|
||||
|
||||
9. Run ``idf.py flash`` to build and flash the partition table and the just-built app image. The app image will be signed using the signing key you generated in step 6.
|
||||
|
||||
.. note:: ``idf.py flash`` doesn't flash the bootloader if Secure Boot is enabled.
|
||||
.. note::
|
||||
|
||||
``idf.py flash`` does not flash the bootloader if Secure Boot is enabled.
|
||||
|
||||
10. Reset the {IDF_TARGET_NAME} and it will boot the software bootloader you flashed. The software bootloader will enable Secure Boot on the chip, and then it verifies the app image signature and boots the app. You should watch the serial console output from the {IDF_TARGET_NAME} to verify that Secure Boot is enabled and no errors have occurred due to the build configuration.
|
||||
|
||||
.. note:: Secure boot won't be enabled until after a valid partition table and app image have been flashed. This is to prevent accidents before the system is fully configured.
|
||||
.. note::
|
||||
|
||||
.. note:: If the {IDF_TARGET_NAME} is reset or powered down during the first boot, it will start the process again on the next boot.
|
||||
Secure boot will not be enabled until after a valid partition table and app image have been flashed. This is to prevent accidents before the system is fully configured.
|
||||
|
||||
.. note::
|
||||
|
||||
If the {IDF_TARGET_NAME} is reset or powered down during the first boot, it will start the process again on the next boot.
|
||||
|
||||
11. On subsequent boots, the Secure Boot hardware will verify the software bootloader has not changed and the software bootloader will verify the signed app image (using the validated public key portion of its appended signature block).
|
||||
|
||||
Restrictions after Secure Boot is enabled
|
||||
Restrictions After Secure Boot Is Enabled
|
||||
-----------------------------------------
|
||||
|
||||
- Any updated bootloader or app will need to be signed with a key matching the digest already stored in eFuse.
|
||||
@@ -455,8 +463,8 @@ Remember that the strength of the Secure Boot system depends on keeping the sign
|
||||
Remote Signing of Images
|
||||
------------------------
|
||||
|
||||
Signing using espsecure.py
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Signing Using ``espsecure.py``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For production builds, it can be good practice to use a remote signing server rather than have the signing key on the build machine (which is the default esp-idf Secure Boot configuration). The espsecure.py command line program can be used to sign app images & partition table data for Secure Boot, on a remote system.
|
||||
|
||||
@@ -470,7 +478,7 @@ The above command appends the image signature to the existing binary. You can us
|
||||
|
||||
espsecure.py sign_data --version 2 --keyfile PRIVATE_SIGNING_KEY --output SIGNED_BINARY_FILE BINARY_FILE
|
||||
|
||||
Signing using Pre-calculated Signatures
|
||||
Signing Using Pre-calculated Signatures
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you have valid pre-calculated signatures generated for an image and their corresponding public keys, you can use these signatures to generate a signature sector and append it to the image. Note that the pre-calculated signature should be calculated over all bytes in the image including the secure-padding bytes.
|
||||
@@ -482,7 +490,7 @@ In such cases, the firmware image should be built by disabling the option :ref:`
|
||||
The above command verifies the signature, generates a signature block (refer to :ref:`signature-block-format`) and appends it to the binary file.
|
||||
|
||||
|
||||
Signing using an External Hardware Security Module (HSM)
|
||||
Signing Using an External Hardware Security Module (HSM)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For security reasons, you might also use an external Hardware Security Module (HSM) to store your private signing key, which cannot be accessed directly but has an interface to generate the signature of a binary file and its corresponding public key.
|
||||
@@ -506,7 +514,7 @@ Secure Boot Best Practices
|
||||
* Keep the signing key private at all times. A leak of this key will compromise the Secure Boot system.
|
||||
* Do not allow any third party to observe any aspects of the key generation or signing process using espsecure.py. Both processes are vulnerable to timing or other side-channel attacks.
|
||||
* Enable all Secure Boot options in the Secure Boot Configuration. These include flash encryption, disabling of JTAG, disabling BASIC ROM interpreter, and disabling the UART bootloader encrypted flash access.
|
||||
* Use Secure Boot in combination with :doc:`flash encryption<flash-encryption>` to prevent local readout of the flash contents.
|
||||
* Use Secure Boot in combination with :doc:`flash-encryption` to prevent local readout of the flash contents.
|
||||
|
||||
.. only:: SOC_EFUSE_REVOKE_BOOT_KEY_DIGESTS
|
||||
|
||||
@@ -539,7 +547,7 @@ Secure Boot Best Practices
|
||||
* Applications should be signed with only one key at a time, to minimize the exposure of unused private keys.
|
||||
* The bootloader can be signed with multiple keys from the factory.
|
||||
|
||||
Conservative approach:
|
||||
Conservative Approach:
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Assuming a trusted private key (N-1) has been compromised, to update to new key pair (N).
|
||||
@@ -556,14 +564,14 @@ Secure Boot Best Practices
|
||||
|
||||
.. _secure-boot-v2-aggressive-key-revocation:
|
||||
|
||||
Aggressive approach:
|
||||
Aggressive Approach:
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
ROM code has an additional feature of revoking a public key digest if the signature verification fails.
|
||||
|
||||
To enable this feature, you need to burn SECURE_BOOT_AGGRESSIVE_REVOKE efuse or enable :ref:`CONFIG_SECURE_BOOT_ENABLE_AGGRESSIVE_KEY_REVOKE`
|
||||
|
||||
Key revocation is not applicable unless secure boot is successfully enabled. Also, a key is not revoked in case of invalid signature block or invalid image digest, it is only revoked in case the signature verification fails, i.e. revoke key only if failure in step 3 of :ref:`verify_image`
|
||||
Key revocation is not applicable unless secure boot is successfully enabled. Also, a key is not revoked in case of invalid signature block or invalid image digest, it is only revoked in case the signature verification fails, i.e., revoke key only if failure in step 3 of :ref:`verify_image`
|
||||
|
||||
Once a key is revoked, it can never be used for verfying a signature of an image. This feature provides strong resistance against physical attacks on the device. However, this could also brick the device permanently if all the keys are revoked because of signature verification failure.
|
||||
|
||||
@@ -592,7 +600,7 @@ Keyfile is the PEM file containing an {IDF_TARGET_SBV2_KEY} private signing key.
|
||||
Secure Boot & Flash Encryption
|
||||
------------------------------
|
||||
|
||||
If Secure Boot is used without :doc:`Flash Encryption <flash-encryption>`, it is possible to launch "time-of-check to time-of-use" attack, where flash contents are swapped after the image is verified and running. Therefore, it is recommended to use both the features together.
|
||||
If Secure Boot is used without :doc:`flash-encryption`, it is possible to launch "time-of-check to time-of-use" attack, where flash contents are swapped after the image is verified and running. Therefore, it is recommended to use both the features together.
|
||||
|
||||
.. only:: esp32c2
|
||||
|
||||
@@ -608,17 +616,17 @@ The Secure Boot V2 signature of apps can be checked on OTA update, without enabl
|
||||
|
||||
This may be desirable in cases where the delay of Secure Boot verification on startup is unacceptable, and/or where the threat model does not include physical access or attackers writing to bootloader or app partitions in flash.
|
||||
|
||||
In this mode, the public key which is present in the signature block of the currently running app will be used to verify the signature of a newly updated app. (The signature on the running app isn't verified during the update process, it's assumed to be valid.) In this way the system creates a chain of trust from the running app to the newly updated app.
|
||||
In this mode, the public key which is present in the signature block of the currently running app will be used to verify the signature of a newly updated app. (The signature on the running app is not verified during the update process, it is assumed to be valid.) In this way the system creates a chain of trust from the running app to the newly updated app.
|
||||
|
||||
For this reason, it's essential that the initial app flashed to the device is also signed. A check is run on app startup and the app will abort if no signatures are found. This is to try and prevent a situation where no update is possible. The app should have only one valid signature block in the first position. Note again that, unlike hardware Secure Boot V2, the signature of the running app isn't verified on boot. The system only verifies a signature block in the first position and ignores any other appended signatures.
|
||||
For this reason, it is essential that the initial app flashed to the device is also signed. A check is run on app startup and the app will abort if no signatures are found. This is to try and prevent a situation where no update is possible. The app should have only one valid signature block in the first position. Note again that, unlike hardware Secure Boot V2, the signature of the running app is not verified on boot. The system only verifies a signature block in the first position and ignores any other appended signatures.
|
||||
|
||||
.. only:: not esp32
|
||||
|
||||
Although multiple trusted keys are supported when using hardware Secure Boot, only the first public key in the signature block is used to verify updates if signature checking without Secure Boot is configured. If multiple trusted public keys are required, it's necessary to enable the full Secure Boot feature instead.
|
||||
Although multiple trusted keys are supported when using hardware Secure Boot, only the first public key in the signature block is used to verify updates if signature checking without Secure Boot is configured. If multiple trusted public keys are required, it is necessary to enable the full Secure Boot feature instead.
|
||||
|
||||
.. note::
|
||||
|
||||
In general, it's recommended to use full hardware Secure Boot unless certain that this option is sufficient for application security needs.
|
||||
In general, it is recommended to use full hardware Secure Boot unless certain that this option is sufficient for application security needs.
|
||||
|
||||
.. _signed-app-verify-v2-howto:
|
||||
|
||||
|
@@ -1,5 +1,6 @@
|
||||
创建示例项目
|
||||
============
|
||||
|
||||
:link_to_translation:`en:[English]`
|
||||
|
||||
每个 ESP-IDF 的示例都是一个完整的项目,其他人可以将示例复制至本地,并根据实际情况进行一定修改。请注意,示例项目主要是为了展示 ESP-IDF 的功能。
|
||||
|
@@ -157,6 +157,7 @@ flash 加密操作由 {IDF_TARGET_NAME} 上的多个 eFuse 控制。以下是这
|
||||
- 3
|
||||
|
||||
.. note::
|
||||
|
||||
* 上表中列出的所有 eFuse 位都提供读/写访问控制。
|
||||
* 这些位的默认值是 0。
|
||||
|
||||
@@ -165,6 +166,7 @@ flash 加密操作由 {IDF_TARGET_NAME} 上的多个 eFuse 控制。以下是这
|
||||
.. only:: esp32c2
|
||||
|
||||
.. important::
|
||||
|
||||
{IDF_TARGET_NAME} 具有安全启动和 flash 加密两个密钥,但仅有一个 eFuse 密钥块。由于 eFuse 密钥块仅支持一次烧录,故应将密钥同时同批进行烧录。请勿单独启用“安全启动”或 “flash 加密”,否则在 eFuse 密钥块随后的写入中将返回错误。
|
||||
|
||||
flash 的加密过程
|
||||
@@ -176,7 +178,7 @@ flash 的加密过程
|
||||
|
||||
1. 第一次开机复位时,flash 中的所有数据都是未加密的(明文)。ROM 引导加载程序加载固件引导加载程序。
|
||||
|
||||
2. 固件的引导加载程序将读取 ``{IDF_TARGET_CRYPT_CNT}`` eFuse 值 (``0b0000000``)。因为该值为 0(偶数位),固件的引导加载程序将配置并启用 flash 加密块,同时将 ``FLASH_CRYPT_CONFIG`` eFuse 的值编程为 0xF。关于 flash 加密块的更多信息,请参考 *{IDF_TARGET_NAME} 技术参考手册* > *eFuse 控制器(eFuse)* > *flash 加密块* [`PDF <{IDF_TARGET_TRM_CN_URL}#efuse>`__]。
|
||||
2. 固件的引导加载程序将读取 ``{IDF_TARGET_CRYPT_CNT}`` eFuse 值 (``0b0000000``)。因为该值为 0(偶数位),固件的引导加载程序将配置并启用 flash 加密块,同时将 ``FLASH_CRYPT_CONFIG`` eFuse 的值编程为 0xF。关于 flash 加密块的更多信息,请参考 *{IDF_TARGET_NAME} 技术参考手册* > *eFuse 控制器 (eFuse)* > *flash 加密块* [`PDF <{IDF_TARGET_TRM_CN_URL}#efuse>`__]。
|
||||
|
||||
3. 固件的引导加载程序使用 RNG(随机数生成)模块生成 AES-256 位密钥,然后将其写入 ``flash_encryption`` eFuse 中。由于 ``flash_encryption`` eFuse 已设置编写和读取保护位,将无法通过软件访问密钥。flash 加密操作完全在硬件中完成,无法通过软件访问密钥。
|
||||
|
||||
@@ -194,7 +196,7 @@ flash 的加密过程
|
||||
|
||||
1. 第一次开机复位时,flash 中的所有数据都是未加密的(明文)。ROM 引导加载程序加载固件引导加载程序。
|
||||
|
||||
2. 固件的引导加载程序将读取 ``{IDF_TARGET_CRYPT_CNT}`` eFuse 值 (``0b000``)。因为该值为 0(偶数位),固件引导加载程序将配置并启用 flash 加密块。关于 flash 加密块的更多信息,请参考 *{IDF_TARGET_NAME} 技术参考手册* > *eFuse 控制器(eFuse)* > *自动加密块* [`PDF <{IDF_TARGET_TRM_CN_URL}#efuse>`__]。
|
||||
2. 固件的引导加载程序将读取 ``{IDF_TARGET_CRYPT_CNT}`` eFuse 值 (``0b000``)。因为该值为 0(偶数位),固件引导加载程序将配置并启用 flash 加密块。关于 flash 加密块的更多信息,请参考 *{IDF_TARGET_NAME} 技术参考手册* > *eFuse 控制器 (eFuse)* > *自动加密块* [`PDF <{IDF_TARGET_TRM_CN_URL}#efuse>`__]。
|
||||
|
||||
3. 固件的引导加载程序使用 RNG(随机数生成)模块生成 256 位或 512 位密钥,具体取决于 :ref:`生成的 XTS-AES 密钥的大小 <CONFIG_SECURE_FLASH_ENCRYPTION_KEYSIZE>`,然后分别将其写入一个或两个 `BLOCK_KEYN` eFuses。软件也为存储密钥的块更新了 ``KEY_PURPOSE_N``。由于一或两个 ``BLOCK_KEYN`` eFuse 已设置编写和读取保护位,将无法通过软件访问密钥。``KEY_PURPOSE_N`` 字段也受写保护。flash 加密操作完全在硬件中完成,无法通过软件访问密钥。
|
||||
|
||||
@@ -283,7 +285,7 @@ flash 加密设置
|
||||
|
||||
测试 flash 加密过程需完成以下步骤:
|
||||
|
||||
1. 确保您的 {IDF_TARGET_NAME} 设备有 :ref:`flash-encryption-efuse` 中所示的 flash 加密 eFuse 的默认设置。
|
||||
1. 确保你的 {IDF_TARGET_NAME} 设备有 :ref:`flash-encryption-efuse` 中所示的 flash 加密 eFuse 的默认设置。
|
||||
|
||||
请参考如何检查 :ref:`flash-encryption-status`。
|
||||
|
||||
@@ -342,11 +344,12 @@ flash 加密设置
|
||||
.. only:: esp32c2
|
||||
|
||||
.. note::
|
||||
|
||||
请注意, {IDF_TARGET_NAME} 只有一个 eFuse 密钥块,同时用于安全启动和 flash 加密密钥。因此,如果使用了安全启动密钥,则主机生成的 flash 加密密钥必须与安全启动密钥一起写入,否则将无法使用安全启动。
|
||||
|
||||
使用主机生成的密钥需完成以下步骤:
|
||||
|
||||
1. 确保您的 {IDF_TARGET_NAME} 设备有 :ref:`flash-encryption-efuse` 中所示的 flash 加密 eFuse 的默认设置。
|
||||
1. 确保你的 {IDF_TARGET_NAME} 设备有 :ref:`flash-encryption-efuse` 中所示的 flash 加密 eFuse 的默认设置。
|
||||
|
||||
请参考如何检查 :ref:`flash-encryption-status`。
|
||||
|
||||
@@ -421,7 +424,7 @@ flash 加密设置
|
||||
|
||||
espefuse.py --port PORT burn_key BLOCK my_flash_encryption_key.bin XTS_AES_256_KEY
|
||||
|
||||
如果您想指定使用哪两个区块,则可以将密钥分成两个 256 位密钥,并分别使用 ``XTS_AES_256_KEY_1`` 和 ``XTS_AES_256_KEY_2`` 为密钥用途进行手动烧录:
|
||||
如果你想指定使用哪两个区块,则可以将密钥分成两个 256 位密钥,并分别使用 ``XTS_AES_256_KEY_1`` 和 ``XTS_AES_256_KEY_2`` 为密钥用途进行手动烧录:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
@@ -446,7 +449,7 @@ flash 加密设置
|
||||
|
||||
espefuse.py --port PORT burn_key BLOCK_KEY0 flash_encryption_key256.bin XTS_AES_128_KEY
|
||||
|
||||
对于由 128 位导出的 AES-128 密钥(SHA256(128 位))- ``XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS``。flash 加密密钥会被写入 eFuse BLOCK_KEY0 的低位,留出高 128 位以支持软件读取。如小节 ``同时烧录两个密钥`` 所示,在 espefuse 工具的特殊模式下,您可以使用任意 espefuse 命令来写入数据。
|
||||
对于由 128 位导出的 AES-128 密钥(SHA256(128 位))- ``XTS_AES_128_KEY_DERIVED_FROM_128_EFUSE_BITS``。flash 加密密钥会被写入 eFuse BLOCK_KEY0 的低位,留出高 128 位以支持软件读取。如小节 ``同时烧录两个密钥`` 所示,在 espefuse 工具的特殊模式下,你可以使用任意 espefuse 命令来写入数据。
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
@@ -514,7 +517,7 @@ flash 加密设置
|
||||
|
||||
使用该模式需要执行以下步骤:
|
||||
|
||||
1. 确保您的 {IDF_TARGET_NAME} 设备有 :ref:`flash-encryption-efuse` 中所示的 flash 加密 eFuse 的默认设置。
|
||||
1. 确保你的 {IDF_TARGET_NAME} 设备有 :ref:`flash-encryption-efuse` 中所示的 flash 加密 eFuse 的默认设置。
|
||||
|
||||
请参考如何检查 :ref:`flash-encryption-status`。
|
||||
|
||||
@@ -690,11 +693,11 @@ In the process mentioned above, flash encryption related eFuses which ultimately
|
||||
{IDF_TARGET_NAME} flash 加密状态
|
||||
-----------------------------------------
|
||||
|
||||
1. 确保您的 {IDF_TARGET_NAME} 设备有 :ref:`flash-encryption-efuse` 中所示的 flash 加密 eFuse 的默认设置。
|
||||
1. 确保你的 {IDF_TARGET_NAME} 设备有 :ref:`flash-encryption-efuse` 中所示的 flash 加密 eFuse 的默认设置。
|
||||
|
||||
要检查您的 {IDF_TARGET_NAME} 设备上是否启用了 flash 加密,请执行以下操作之一:
|
||||
要检查你的 {IDF_TARGET_NAME} 设备上是否启用了 flash 加密,请执行以下操作之一:
|
||||
|
||||
- 将应用示例 :example:`security/flash_encryption` 烧录到您的设备上。此应用程序会打印 ``{IDF_TARGET_CRYPT_CNT}`` eFuse 值,以及是否启用了 flash 加密。
|
||||
- 将应用示例 :example:`security/flash_encryption` 烧录到你的设备上。此应用程序会打印 ``{IDF_TARGET_CRYPT_CNT}`` eFuse 值,以及是否启用了 flash 加密。
|
||||
|
||||
- :doc:`查询设备所连接的串口名称 <../get-started/establish-serial-connection>`,在以下命令中将 ``PORT`` 替换为串口名称后运行:
|
||||
|
||||
@@ -848,8 +851,8 @@ flash 加密可以保护固件,防止未经授权的读取与修改。了解 f
|
||||
|
||||
.. list::
|
||||
|
||||
- flash 加密功能与密钥同样稳固。因而,推荐您首次启动设备时在设备上生成密钥(默认行为)。如果在设备外生成密钥,请确保遵循正确的后续步骤,不要在所有生产设备之间使用相同的密钥。
|
||||
- 并非所有数据都是加密存储。因而在 flash 上存储数据时,请检查您使用的存储方式(库、API 等)是否支持 flash 加密。
|
||||
- flash 加密功能与密钥同样稳固。因而,推荐在首次启动设备时,在设备上生成密钥(默认行为)。如果在设备外生成密钥,请确保遵循正确的后续步骤,不要在所有生产设备之间使用相同的密钥。
|
||||
- 并非所有数据都是加密存储。因而在 flash 上存储数据时,请检查你使用的存储方式(库、API 等)是否支持 flash 加密。
|
||||
- flash 加密无法防止攻击者获取 flash 的高层次布局信息。这是因为每对相邻的 16 字节 AES 块都使用相邻的 AES 密钥。当这些相邻的 16 字节块中包含相同内容时(如空白或填充区域),这些字节块将加密以产生匹配的加密块对。这让攻击者可在加密设备间进行高层次对比(例如,确认两设备是否可能运行相同的固件版本)。
|
||||
:esp32: - 出于相同原因,攻击者始终可获知一对相邻的 16 字节块(32 字节对齐)何时包含相同的 16 字节序列。因此,在 flash 上存储敏感数据时应牢记这点,可进行相关设置避免该情况发生(可使用计数器字节或每 16 字节设置不同的值即可)。具体请参考 :ref:`NVS 加密 <nvs_encryption>`。
|
||||
- 单独使用 flash 加密可能无法防止攻击者修改本设备的固件。为防止设备上运行未经授权的固件,可搭配 flash 加密使用 :doc:`安全启动 <secure-boot-v2>`。
|
||||
@@ -893,7 +896,7 @@ flash 加密的高级功能
|
||||
|
||||
请参考 :doc:`分区表 <../api-guides/partition-tables>` 获取更多关于分区表描述的具体信息。
|
||||
|
||||
关于分区加密您还需要了解以下信息:
|
||||
关于分区加密,还需了解以下信息:
|
||||
|
||||
- 默认分区表都不包含任何加密数据分区。
|
||||
- 启用 flash 加密后,"app" 分区一般都视为加密分区,因此无需标记。
|
||||
@@ -1014,7 +1017,7 @@ JTAG 调试
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
如果您的 ESP32 在 eFuse 中使用了非默认的 :ref:`FLASH_CRYPT_CONFIG 值 <setting-flash-crypt-config>`,那么则需要向 ``espsecure.py`` 传递 ``--flash_crypt_conf`` 参数以设置匹配的值。如果设备自己设置了 flash 加密就不会出现这种情况,但如果手动烧录 eFuse 来启用 flash 加密就可能发生这种情况。
|
||||
如果你的 ESP32 在 eFuse 中使用了非默认的 :ref:`FLASH_CRYPT_CONFIG 值 <setting-flash-crypt-config>`,那么则需要向 ``espsecure.py`` 传递 ``--flash_crypt_conf`` 参数以设置匹配的值。如果设备自己设置了 flash 加密就不会出现这种情况,但如果手动烧录 eFuse 来启用 flash 加密就可能发生这种情况。
|
||||
|
||||
``espsecure.py decrypt_flash_data`` 命令可以使用同样的选项(和不同的输入/输出文件)来解密 flash 密文或之前加密的文件。
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
Security Guides
|
||||
***************
|
||||
:link_to_translation:`zh_CN:[中文]`
|
||||
|
||||
:link_to_translation:`en:[English]`
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
Reference in New Issue
Block a user