You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
175 lines
6.1 KiB
175 lines
6.1 KiB
Secure Development Guidelines
|
|
=============================
|
|
|
|
This page contains guidance on what to check for additional security measures,
|
|
including build options that can be modified to improve security or catch issues
|
|
early in development.
|
|
|
|
Security considerations
|
|
-----------------------
|
|
|
|
Part of the security of a platform is handling errors correctly, as described in
|
|
the previous section. There are several other security considerations covered in
|
|
this section.
|
|
|
|
Do not leak secrets to the normal world
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
The secure world **must not** leak secrets to the normal world, for example in
|
|
response to an SMC.
|
|
|
|
Handling Denial of Service attacks
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
The secure world **should never** crash or become unusable due to receiving too
|
|
many normal world requests (a *Denial of Service* or *DoS* attack). It should
|
|
have a mechanism for throttling or ignoring normal world requests.
|
|
|
|
Preventing Secure-world timing information leakage via PMU counters
|
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
The Secure world needs to implement some defenses to prevent the Non-secure
|
|
world from making it leak timing information. In general, higher privilege
|
|
levels must defend from those below when the PMU is treated as an attack
|
|
vector.
|
|
|
|
Refer to the :ref:`Performance Monitoring Unit` guide for detailed information
|
|
on the PMU registers.
|
|
|
|
Timing leakage attacks from the Non-secure world
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Since the Non-secure world has access to the ``PMCR`` register, it can
|
|
configure the PMU to increment counters at any exception level and in both
|
|
Secure and Non-secure state. Thus, it attempts to leak timing information from
|
|
the Secure world.
|
|
|
|
Shown below is an example of such a configuration:
|
|
|
|
- ``PMEVTYPER0_EL0`` and ``PMCCFILTR_EL0``:
|
|
|
|
- Set ``P`` to ``0``.
|
|
- Set ``NSK`` to ``1``.
|
|
- Set ``M`` to ``0``.
|
|
- Set ``NSH`` to ``0``.
|
|
- Set ``SH`` to ``1``.
|
|
|
|
- ``PMCNTENSET_EL0``:
|
|
|
|
- Set ``P[0]`` to ``1``.
|
|
- Set ``C`` to ``1``.
|
|
|
|
- ``PMCR_EL0``:
|
|
|
|
- Set ``DP`` to ``0``.
|
|
- Set ``E`` to ``1``.
|
|
|
|
This configuration instructs ``PMEVCNTR0_EL0`` and ``PMCCNTR_EL0`` to increment
|
|
at Secure EL1, Secure EL2 (if implemented) and EL3.
|
|
|
|
Since the Non-secure world has fine-grained control over where (at which
|
|
exception levels) it instructs counters to increment, obtaining event counts
|
|
would allow it to carry out side-channel timing attacks against the Secure
|
|
world. Examples include Spectre, Meltdown, as well as extracting secrets from
|
|
cryptographic algorithms with data-dependent variations in their execution
|
|
time.
|
|
|
|
Secure world mitigation strategies
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
The ``MDCR_EL3`` register allows EL3 to configure the PMU (among other things).
|
|
The `Arm ARM`_ details all of the bit fields in this register, but for the PMU
|
|
there are two bits which determine the permissions of the counters:
|
|
|
|
- ``SPME`` for the programmable counters.
|
|
- ``SCCD`` for the cycle counter.
|
|
|
|
Depending on the implemented features, the Secure world can prohibit counting
|
|
in AArch64 state via the following:
|
|
|
|
- ARMv8.2-Debug not implemented:
|
|
|
|
- Prohibit general event counters and the cycle counter:
|
|
``MDCR_EL3.SPME == 0 && PMCR_EL0.DP == 1 && !ExternalSecureNoninvasiveDebugEnabled()``.
|
|
|
|
- ``MDCR_EL3.SPME`` resets to ``0``, so by default general events should
|
|
not be counted in the Secure world.
|
|
- The ``PMCR_EL0.DP`` bit therefore needs to be set to ``1`` when EL3 is
|
|
entered and ``PMCR_EL0`` needs to be saved and restored in EL3.
|
|
- ``ExternalSecureNoninvasiveDebugEnabled()`` is an authentication
|
|
interface which is implementation-defined unless ARMv8.4-Debug is
|
|
implemented. The `Arm ARM`_ has detailed information on this topic.
|
|
|
|
- The only other way is to disable the ``PMCR_EL0.E`` bit upon entering
|
|
EL3, which disables counting altogether.
|
|
|
|
- ARMv8.2-Debug implemented:
|
|
|
|
- Prohibit general event counters: ``MDCR_EL3.SPME == 0``.
|
|
- Prohibit cycle counter: ``MDCR_EL3.SPME == 0 && PMCR_EL0.DP == 1``.
|
|
``PMCR_EL0`` therefore needs to be saved and restored in EL3.
|
|
|
|
- ARMv8.5-PMU implemented:
|
|
|
|
- Prohibit general event counters: as in ARMv8.2-Debug.
|
|
- Prohibit cycle counter: ``MDCR_EL3.SCCD == 1``
|
|
|
|
In Aarch32 execution state the ``MDCR_EL3`` alias is the ``SDCR`` register,
|
|
which has some of the bit fields of ``MDCR_EL3``, most importantly the ``SPME``
|
|
and ``SCCD`` bits.
|
|
|
|
Build options
|
|
-------------
|
|
|
|
Several build options can be used to check for security issues. Refer to the
|
|
:ref:`Build Options` for detailed information on these.
|
|
|
|
- The ``BRANCH_PROTECTION`` build flag can be used to enable Pointer
|
|
Authentication and Branch Target Identification.
|
|
|
|
- The ``ENABLE_STACK_PROTECTOR`` build flag can be used to identify buffer
|
|
overflows.
|
|
|
|
- The ``W`` build flag can be used to enable a number of compiler warning
|
|
options to detect potentially incorrect code.
|
|
|
|
- W=0 (default value)
|
|
|
|
The ``Wunused`` with ``Wno-unused-parameter``, ``Wdisabled-optimization``
|
|
and ``Wvla`` flags are enabled.
|
|
|
|
The ``Wunused-but-set-variable``, ``Wmaybe-uninitialized`` and
|
|
``Wpacked-bitfield-compat`` are GCC specific flags that are also enabled.
|
|
|
|
- W=1
|
|
|
|
Adds ``Wextra``, ``Wmissing-format-attribute``, ``Wmissing-prototypes``,
|
|
``Wold-style-definition`` and ``Wunused-const-variable``.
|
|
|
|
- W=2
|
|
|
|
Adds ``Waggregate-return``, ``Wcast-align``, ``Wnested-externs``,
|
|
``Wshadow``, ``Wlogical-op``.
|
|
|
|
- W=3
|
|
|
|
Adds ``Wbad-function-cast``, ``Wcast-qual``, ``Wconversion``, ``Wpacked``,
|
|
``Wpointer-arith``, ``Wredundant-decls`` and
|
|
``Wswitch-default``.
|
|
|
|
Refer to the GCC or Clang documentation for more information on the individual
|
|
options: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html and
|
|
https://clang.llvm.org/docs/DiagnosticsReference.html.
|
|
|
|
NB: The ``Werror`` flag is enabled by default in TF-A and can be disabled by
|
|
setting the ``E`` build flag to 0.
|
|
|
|
.. rubric:: References
|
|
|
|
- `Arm ARM`_
|
|
|
|
--------------
|
|
|
|
*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
|
|
|
|
.. _Arm ARM: https://developer.arm.com/docs/ddi0487/latest
|
|
|