1 /* 2 * Copyright (c) 2020-2022, Arm Limited. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 */ 7 8 #include "fih.h" 9 #include "tfm_hal_defs.h" 10 #include "tfm_hal_platform.h" 11 #ifdef FIH_ENABLE_DELAY 12 #include "tfm_fih_rng.h" 13 #endif 14 15 #ifdef TFM_FIH_PROFILE_ON 16 fih_int FIH_SUCCESS = FIH_INT_INIT(FIH_POSITIVE_VALUE); 17 fih_int FIH_FAILURE = FIH_INT_INIT(FIH_NEGATIVE_VALUE); 18 #endif 19 20 #ifdef FIH_ENABLE_CFI 21 fih_int _fih_cfi_ctr = FIH_INT_INIT(0); 22 fih_cfi_get_and_increment(uint8_t cnt)23fih_int fih_cfi_get_and_increment(uint8_t cnt) 24 { 25 fih_int saved_ctr = _fih_cfi_ctr; 26 27 if (fih_int_decode(_fih_cfi_ctr) < 0) { 28 FIH_PANIC; 29 } 30 31 /* Overflow */ 32 if (fih_int_decode(_fih_cfi_ctr) > (fih_int_decode(_fih_cfi_ctr) + cnt)) { 33 FIH_PANIC; 34 } 35 36 _fih_cfi_ctr = fih_int_encode(fih_int_decode(_fih_cfi_ctr) + cnt); 37 38 fih_int_validate(_fih_cfi_ctr); 39 fih_int_validate(saved_ctr); 40 41 return saved_ctr; 42 } 43 fih_cfi_validate(fih_int saved)44void fih_cfi_validate(fih_int saved) 45 { 46 volatile int32_t rc = FIH_FALSE; 47 48 rc = fih_eq(saved, _fih_cfi_ctr); 49 if (rc != FIH_TRUE) { 50 FIH_PANIC; 51 } 52 } 53 fih_cfi_decrement(void)54void fih_cfi_decrement(void) 55 { 56 if (fih_int_decode(_fih_cfi_ctr) < 1) { 57 FIH_PANIC; 58 } 59 60 _fih_cfi_ctr = fih_int_encode(fih_int_decode(_fih_cfi_ctr) - 1); 61 62 fih_int_validate(_fih_cfi_ctr); 63 } 64 #endif /* FIH_ENABLE_CFI */ 65 66 #ifdef FIH_ENABLE_GLOBAL_FAIL 67 /* Global failure loop for bootloader code. Uses attribute used to prevent 68 * compiler removing due to non-standard calling procedure. Multiple loop jumps 69 * used to make unlooping difficult. 70 */ 71 __attribute__((used)) 72 __attribute__((noinline)) fih_panic_loop(void)73void fih_panic_loop(void) 74 { 75 FIH_LABEL("FAILURE_LOOP"); 76 __asm volatile ("b fih_panic_loop"); 77 __asm volatile ("b fih_panic_loop"); 78 __asm volatile ("b fih_panic_loop"); 79 __asm volatile ("b fih_panic_loop"); 80 __asm volatile ("b fih_panic_loop"); 81 __asm volatile ("b fih_panic_loop"); 82 __asm volatile ("b fih_panic_loop"); 83 __asm volatile ("b fih_panic_loop"); 84 __asm volatile ("b fih_panic_loop"); 85 } 86 #endif /* FIH_ENABLE_GLOBAL_FAIL */ 87 88 #ifdef FIH_ENABLE_DELAY fih_delay_init(void)89void fih_delay_init(void) 90 { 91 fih_int ret = FIH_FAILURE; 92 93 ret = tfm_fih_random_init(); 94 95 #ifdef FIH_ENABLE_DOUBLE_VARS 96 if (ret.val != FIH_SUCCESS.val) { 97 FIH_PANIC; 98 } 99 100 if (ret.msk != FIH_SUCCESS.msk) { 101 FIH_PANIC; 102 } 103 #else /* FIH_ENABLE_DOUBLE_VARS */ 104 if (ret != FIH_SUCCESS) { 105 FIH_PANIC; 106 } 107 #endif /* FIH_ENABLE_DOUBLE_VARS */ 108 } 109 fih_delay_random(void)110uint8_t fih_delay_random(void) 111 { 112 uint8_t rand_value = 0xFF; 113 114 /* Repeat random generation to mitigate instruction skip */ 115 tfm_fih_random_generate(&rand_value); 116 tfm_fih_random_generate(&rand_value); 117 tfm_fih_random_generate(&rand_value); 118 119 return rand_value; 120 } 121 #endif /* FIH_ENABLE_DELAY */ 122