Paul Beesley | 07f0a31 | 2019-05-16 13:33:18 +0100 | [diff] [blame] | 1 | Secure Development Guidelines |
| 2 | ============================= |
Ambroise Vincent | cc28b21 | 2019-06-05 15:40:29 +0100 | [diff] [blame] | 3 | |
| 4 | This page contains guidance on what to check for additional security measures, |
| 5 | including build options that can be modified to improve security or catch issues |
| 6 | early in development. |
| 7 | |
Paul Beesley | 07f0a31 | 2019-05-16 13:33:18 +0100 | [diff] [blame] | 8 | Security considerations |
| 9 | ----------------------- |
| 10 | |
| 11 | Part of the security of a platform is handling errors correctly, as described in |
| 12 | the previous section. There are several other security considerations covered in |
| 13 | this section. |
| 14 | |
| 15 | Do not leak secrets to the normal world |
| 16 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 17 | |
| 18 | The secure world **must not** leak secrets to the normal world, for example in |
| 19 | response to an SMC. |
| 20 | |
| 21 | Handling Denial of Service attacks |
| 22 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 23 | |
| 24 | The secure world **should never** crash or become unusable due to receiving too |
| 25 | many normal world requests (a *Denial of Service* or *DoS* attack). It should |
| 26 | have a mechanism for throttling or ignoring normal world requests. |
| 27 | |
Petre-Ionut Tudor | 620a702 | 2019-09-27 15:13:21 +0100 | [diff] [blame] | 28 | Preventing Secure-world timing information leakage via PMU counters |
| 29 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 30 | |
| 31 | The Secure world needs to implement some defenses to prevent the Non-secure |
| 32 | world from making it leak timing information. In general, higher privilege |
| 33 | levels must defend from those below when the PMU is treated as an attack |
| 34 | vector. |
| 35 | |
| 36 | Refer to the :ref:`Performance Monitoring Unit` guide for detailed information |
| 37 | on the PMU registers. |
| 38 | |
| 39 | Timing leakage attacks from the Non-secure world |
| 40 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 41 | |
| 42 | Since the Non-secure world has access to the ``PMCR`` register, it can |
| 43 | configure the PMU to increment counters at any exception level and in both |
| 44 | Secure and Non-secure state. Thus, it attempts to leak timing information from |
| 45 | the Secure world. |
| 46 | |
| 47 | Shown below is an example of such a configuration: |
| 48 | |
| 49 | - ``PMEVTYPER0_EL0`` and ``PMCCFILTR_EL0``: |
| 50 | |
| 51 | - Set ``P`` to ``0``. |
| 52 | - Set ``NSK`` to ``1``. |
| 53 | - Set ``M`` to ``0``. |
| 54 | - Set ``NSH`` to ``0``. |
| 55 | - Set ``SH`` to ``1``. |
| 56 | |
| 57 | - ``PMCNTENSET_EL0``: |
| 58 | |
| 59 | - Set ``P[0]`` to ``1``. |
| 60 | - Set ``C`` to ``1``. |
| 61 | |
| 62 | - ``PMCR_EL0``: |
| 63 | |
| 64 | - Set ``DP`` to ``0``. |
| 65 | - Set ``E`` to ``1``. |
| 66 | |
| 67 | This configuration instructs ``PMEVCNTR0_EL0`` and ``PMCCNTR_EL0`` to increment |
| 68 | at Secure EL1, Secure EL2 (if implemented) and EL3. |
| 69 | |
| 70 | Since the Non-secure world has fine-grained control over where (at which |
| 71 | exception levels) it instructs counters to increment, obtaining event counts |
| 72 | would allow it to carry out side-channel timing attacks against the Secure |
| 73 | world. Examples include Spectre, Meltdown, as well as extracting secrets from |
| 74 | cryptographic algorithms with data-dependent variations in their execution |
| 75 | time. |
| 76 | |
| 77 | Secure world mitigation strategies |
| 78 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 79 | |
| 80 | The ``MDCR_EL3`` register allows EL3 to configure the PMU (among other things). |
| 81 | The `Arm ARM`_ details all of the bit fields in this register, but for the PMU |
| 82 | there are two bits which determine the permissions of the counters: |
| 83 | |
| 84 | - ``SPME`` for the programmable counters. |
| 85 | - ``SCCD`` for the cycle counter. |
| 86 | |
| 87 | Depending on the implemented features, the Secure world can prohibit counting |
| 88 | in AArch64 state via the following: |
| 89 | |
| 90 | - ARMv8.2-Debug not implemented: |
| 91 | |
| 92 | - Prohibit general event counters and the cycle counter: |
| 93 | ``MDCR_EL3.SPME == 0 && PMCR_EL0.DP == 1 && !ExternalSecureNoninvasiveDebugEnabled()``. |
| 94 | |
| 95 | - ``MDCR_EL3.SPME`` resets to ``0``, so by default general events should |
| 96 | not be counted in the Secure world. |
| 97 | - The ``PMCR_EL0.DP`` bit therefore needs to be set to ``1`` when EL3 is |
| 98 | entered and ``PMCR_EL0`` needs to be saved and restored in EL3. |
| 99 | - ``ExternalSecureNoninvasiveDebugEnabled()`` is an authentication |
| 100 | interface which is implementation-defined unless ARMv8.4-Debug is |
| 101 | implemented. The `Arm ARM`_ has detailed information on this topic. |
| 102 | |
| 103 | - The only other way is to disable the ``PMCR_EL0.E`` bit upon entering |
| 104 | EL3, which disables counting altogether. |
| 105 | |
| 106 | - ARMv8.2-Debug implemented: |
| 107 | |
| 108 | - Prohibit general event counters: ``MDCR_EL3.SPME == 0``. |
| 109 | - Prohibit cycle counter: ``MDCR_EL3.SPME == 0 && PMCR_EL0.DP == 1``. |
| 110 | ``PMCR_EL0`` therefore needs to be saved and restored in EL3. |
| 111 | |
| 112 | - ARMv8.5-PMU implemented: |
| 113 | |
| 114 | - Prohibit general event counters: as in ARMv8.2-Debug. |
| 115 | - Prohibit cycle counter: ``MDCR_EL3.SCCD == 1`` |
| 116 | |
| 117 | In Aarch32 execution state the ``MDCR_EL3`` alias is the ``SDCR`` register, |
| 118 | which has some of the bit fields of ``MDCR_EL3``, most importantly the ``SPME`` |
| 119 | and ``SCCD`` bits. |
| 120 | |
Ambroise Vincent | cc28b21 | 2019-06-05 15:40:29 +0100 | [diff] [blame] | 121 | Build options |
| 122 | ------------- |
| 123 | |
| 124 | Several build options can be used to check for security issues. Refer to the |
Paul Beesley | d2fcc4e | 2019-05-29 13:59:40 +0100 | [diff] [blame] | 125 | :ref:`Build Options` for detailed information on these. |
Ambroise Vincent | cc28b21 | 2019-06-05 15:40:29 +0100 | [diff] [blame] | 126 | |
| 127 | - The ``BRANCH_PROTECTION`` build flag can be used to enable Pointer |
| 128 | Authentication and Branch Target Identification. |
| 129 | |
| 130 | - The ``ENABLE_STACK_PROTECTOR`` build flag can be used to identify buffer |
| 131 | overflows. |
| 132 | |
| 133 | - The ``W`` build flag can be used to enable a number of compiler warning |
| 134 | options to detect potentially incorrect code. |
| 135 | |
| 136 | - W=0 (default value) |
| 137 | |
| 138 | The ``Wunused`` with ``Wno-unused-parameter``, ``Wdisabled-optimization`` |
| 139 | and ``Wvla`` flags are enabled. |
| 140 | |
| 141 | The ``Wunused-but-set-variable``, ``Wmaybe-uninitialized`` and |
| 142 | ``Wpacked-bitfield-compat`` are GCC specific flags that are also enabled. |
| 143 | |
| 144 | - W=1 |
| 145 | |
Justin Chadwell | 0c4eb60 | 2019-09-18 14:47:19 +0100 | [diff] [blame] | 146 | Adds ``Wextra``, ``Wmissing-format-attribute``, ``Wmissing-prototypes``, |
| 147 | ``Wold-style-definition`` and ``Wunused-const-variable``. |
Ambroise Vincent | cc28b21 | 2019-06-05 15:40:29 +0100 | [diff] [blame] | 148 | |
| 149 | - W=2 |
| 150 | |
| 151 | Adds ``Waggregate-return``, ``Wcast-align``, ``Wnested-externs``, |
Justin Chadwell | 80e264b | 2019-07-31 11:44:42 +0100 | [diff] [blame] | 152 | ``Wshadow``, ``Wlogical-op``. |
Ambroise Vincent | cc28b21 | 2019-06-05 15:40:29 +0100 | [diff] [blame] | 153 | |
| 154 | - W=3 |
| 155 | |
| 156 | Adds ``Wbad-function-cast``, ``Wcast-qual``, ``Wconversion``, ``Wpacked``, |
Justin Chadwell | 0c4eb60 | 2019-09-18 14:47:19 +0100 | [diff] [blame] | 157 | ``Wpointer-arith``, ``Wredundant-decls`` and |
Ambroise Vincent | cc28b21 | 2019-06-05 15:40:29 +0100 | [diff] [blame] | 158 | ``Wswitch-default``. |
| 159 | |
| 160 | Refer to the GCC or Clang documentation for more information on the individual |
| 161 | options: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html and |
| 162 | https://clang.llvm.org/docs/DiagnosticsReference.html. |
| 163 | |
| 164 | NB: The ``Werror`` flag is enabled by default in TF-A and can be disabled by |
| 165 | setting the ``E`` build flag to 0. |
| 166 | |
Petre-Ionut Tudor | 620a702 | 2019-09-27 15:13:21 +0100 | [diff] [blame] | 167 | .. rubric:: References |
| 168 | |
| 169 | - `Arm ARM`_ |
| 170 | |
Paul Beesley | f864067 | 2019-04-12 14:19:42 +0100 | [diff] [blame] | 171 | -------------- |
Ambroise Vincent | cc28b21 | 2019-06-05 15:40:29 +0100 | [diff] [blame] | 172 | |
Paul Beesley | 07f0a31 | 2019-05-16 13:33:18 +0100 | [diff] [blame] | 173 | *Copyright (c) 2019-2020, Arm Limited. All rights reserved.* |
Petre-Ionut Tudor | 620a702 | 2019-09-27 15:13:21 +0100 | [diff] [blame] | 174 | |
| 175 | .. _Arm ARM: https://developer.arm.com/docs/ddi0487/latest |