1 /* 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 */ 13 volatile int _fih_mask = _FIH_MASK_VALUE; 14 #endif /* FIH_ENABLE_DOUBLE_VARS */ 15 16 fih_ret FIH_SUCCESS = FIH_POSITIVE_VALUE; 17 fih_ret FIH_FAILURE = FIH_NEGATIVE_VALUE; 18 fih_ret FIH_NO_BOOTABLE_IMAGE = FIH_CONST1; 19 fih_ret FIH_BOOT_HOOK_REGULAR = FIH_CONST2; 20 21 #ifdef FIH_ENABLE_CFI 22 23 #ifdef FIH_ENABLE_DOUBLE_VARS 24 fih_int _fih_cfi_ctr = {0, 0 ^ _FIH_MASK_VALUE}; 25 #else 26 fih_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 */ fih_cfi_get_and_increment(void)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 */ fih_cfi_validate(fih_int saved)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 */ fih_cfi_decrement(void)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)) fih_panic_loop(void)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 */ 79