2019-05-16 13:33:18 +01:00
|
|
|
Secure Development Guidelines
|
|
|
|
=============================
|
2019-06-05 15:40:29 +01:00
|
|
|
|
|
|
|
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.
|
|
|
|
|
2019-05-16 13:33:18 +01:00
|
|
|
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.
|
|
|
|
|
2019-09-27 15:13:21 +01:00
|
|
|
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.
|
|
|
|
|
2019-06-05 15:40:29 +01:00
|
|
|
Build options
|
|
|
|
-------------
|
|
|
|
|
|
|
|
Several build options can be used to check for security issues. Refer to the
|
2019-05-29 13:59:40 +01:00
|
|
|
:ref:`Build Options` for detailed information on these.
|
2019-06-05 15:40:29 +01:00
|
|
|
|
|
|
|
- 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
|
|
|
|
|
2019-09-18 14:47:19 +01:00
|
|
|
Adds ``Wextra``, ``Wmissing-format-attribute``, ``Wmissing-prototypes``,
|
|
|
|
``Wold-style-definition`` and ``Wunused-const-variable``.
|
2019-06-05 15:40:29 +01:00
|
|
|
|
|
|
|
- W=2
|
|
|
|
|
|
|
|
Adds ``Waggregate-return``, ``Wcast-align``, ``Wnested-externs``,
|
2019-07-31 11:44:42 +01:00
|
|
|
``Wshadow``, ``Wlogical-op``.
|
2019-06-05 15:40:29 +01:00
|
|
|
|
|
|
|
- W=3
|
|
|
|
|
|
|
|
Adds ``Wbad-function-cast``, ``Wcast-qual``, ``Wconversion``, ``Wpacked``,
|
2019-09-18 14:47:19 +01:00
|
|
|
``Wpointer-arith``, ``Wredundant-decls`` and
|
2019-06-05 15:40:29 +01:00
|
|
|
``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.
|
|
|
|
|
2019-09-27 15:13:21 +01:00
|
|
|
.. rubric:: References
|
|
|
|
|
|
|
|
- `Arm ARM`_
|
|
|
|
|
doc: Convert internal links to RST format
Currently links between documents are using the format:
<path/to/><filename>.rst
This was required for services like GitHub because they render each
document in isolation - linking to another document is like linking
to any other file, just provide the full path.
However, with the new approach, the .rst files are only the raw
source for the documents. Once the documents have been rendered
the output is now in another format (HTML in our case) and so,
when linking to another document, the link must point to the
rendered version and not the .rst file.
The RST spec provides a few methods for linking between content.
The parent of this patch enabled the automatic creation of anchors
for document titles - we will use these anchors as the targets for
our links. Additional anchors can be added by hand if needed, on
section and sub-section titles, for example.
An example of this new format, for a document with the title
"Firmware Design" is :ref:`Firmware Design`.
One big advantage of this is that anchors are not dependent on
paths. We can then move documents around, even between directories,
without breaking any links between documents. Links will need to be
updated only if the title of a document changes.
Change-Id: I9e2340a61dd424cbd8fd1ecc2dc166f460d81703
Signed-off-by: Paul Beesley <paul.beesley@arm.com>
2019-04-12 14:19:42 +01:00
|
|
|
--------------
|
2019-06-05 15:40:29 +01:00
|
|
|
|
2019-05-16 13:33:18 +01:00
|
|
|
*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
|
2019-09-27 15:13:21 +01:00
|
|
|
|
|
|
|
.. _Arm ARM: https://developer.arm.com/docs/ddi0487/latest
|