blob: 5ee109cc1020253c98d10e1cb06aba7b2050445d [file] [log] [blame]
Raef Colese8fe6cf2020-05-26 13:07:40 +01001/*
2 * SPDX-License-Identifier: Apache-2.0
3 *
4 * Copyright (c) 2020 Arm Limited
5 */
6
7#include "bootutil/fault_injection_hardening.h"
8
9#ifdef FIH_ENABLE_DOUBLE_VARS
10/* Variable that could be (but isn't) changed at runtime to force the compiler
11 * not to optimize the double check. Value doesn't matter.
12 */
13volatile int _fih_mask = _FIH_MASK_VALUE;
14fih_int FIH_SUCCESS = {FIH_POSITIVE_VALUE, _FIH_MASK_VALUE ^ FIH_POSITIVE_VALUE};
15fih_int FIH_FAILURE = {FIH_NEGATIVE_VALUE, _FIH_MASK_VALUE ^ FIH_NEGATIVE_VALUE};
16#else
17fih_int FIH_SUCCESS = {FIH_POSITIVE_VALUE};
18fih_int FIH_FAILURE = {FIH_NEGATIVE_VALUE};
19#endif /* FIH_ENABLE_DOUBLE_VARS */
20
21#ifdef FIH_ENABLE_CFI
22
23#ifdef FIH_ENABLE_DOUBLE_VARS
24fih_int _fih_cfi_ctr = {0, 0 ^ _FIH_MASK_VALUE};
25#else
26fih_int _fih_cfi_ctr = {0};
27#endif /* FIH_ENABLE_DOUBLE_VARS */
28
29/* Increment the CFI counter by one, and return the value before the increment.
30 */
31fih_int fih_cfi_get_and_increment(void)
32{
33 fih_int saved = _fih_cfi_ctr;
34 _fih_cfi_ctr = fih_int_encode(fih_int_decode(saved) + 1);
35 return saved;
36}
37
38/* Validate that the saved precall value is the same as the value of the global
39 * counter. For this to be the case, a fih_ret must have been called between
40 * these functions being executed. If the values aren't the same then panic.
41 */
42void fih_cfi_validate(fih_int saved)
43{
44 if (fih_int_decode(saved) != fih_int_decode(_fih_cfi_ctr)) {
45 FIH_PANIC;
46 }
47}
48
49/* Decrement the global CFI counter by one, so that it has the same value as
50 * before the cfi_precall
51 */
52void fih_cfi_decrement(void)
53{
54 _fih_cfi_ctr = fih_int_encode(fih_int_decode(_fih_cfi_ctr) - 1);
55}
56
57#endif /* FIH_ENABLE_CFI */
58
59#ifdef FIH_ENABLE_GLOBAL_FAIL
60/* Global failure loop for bootloader code. Uses attribute used to prevent
61 * compiler removing due to non-standard calling procedure. Multiple loop jumps
62 * used to make unlooping difficult.
63 */
64__attribute__((used))
65__attribute__((noinline))
66void fih_panic_loop(void)
67{
68 __asm volatile ("b fih_panic_loop");
69 __asm volatile ("b fih_panic_loop");
70 __asm volatile ("b fih_panic_loop");
71 __asm volatile ("b fih_panic_loop");
72 __asm volatile ("b fih_panic_loop");
73 __asm volatile ("b fih_panic_loop");
74 __asm volatile ("b fih_panic_loop");
75 __asm volatile ("b fih_panic_loop");
76 __asm volatile ("b fih_panic_loop");
77}
78#endif /* FIH_ENABLE_GLOBAL_FAIL */