1 /* 2 * Copyright (c) 2020-2022, Arm Limited. All rights reserved. 3 * Copyright (c) 2024 Cypress Semiconductor Corporation (an Infineon 4 * company) or an affiliate of Cypress Semiconductor Corporation. All rights 5 * reserved. 6 * 7 * SPDX-License-Identifier: BSD-3-Clause 8 * 9 */ 10 11 #include "fih.h" 12 #include "tfm_hal_defs.h" 13 #include "tfm_hal_platform.h" 14 #ifdef FIH_ENABLE_DELAY 15 #include "tfm_fih_rng.h" 16 #endif 17 18 #ifdef TFM_FIH_PROFILE_ON 19 fih_int FIH_SUCCESS = FIH_INT_INIT(FIH_POSITIVE_VALUE); 20 fih_int FIH_FAILURE = FIH_INT_INIT(FIH_NEGATIVE_VALUE); 21 #endif 22 23 #ifdef FIH_ENABLE_CFI 24 fih_int _fih_cfi_ctr = FIH_INT_INIT(0); 25 fih_cfi_get_and_increment(uint8_t cnt)26fih_int fih_cfi_get_and_increment(uint8_t cnt) 27 { 28 fih_int saved_ctr = _fih_cfi_ctr; 29 30 if (fih_int_decode(_fih_cfi_ctr) < 0) { 31 FIH_PANIC; 32 } 33 34 /* Overflow */ 35 if (fih_int_decode(_fih_cfi_ctr) > (fih_int_decode(_fih_cfi_ctr) + cnt)) { 36 FIH_PANIC; 37 } 38 39 _fih_cfi_ctr = fih_int_encode(fih_int_decode(_fih_cfi_ctr) + cnt); 40 41 (void)fih_int_validate(_fih_cfi_ctr); 42 (void)fih_int_validate(saved_ctr); 43 44 return saved_ctr; 45 } 46 fih_cfi_validate(fih_int saved)47void fih_cfi_validate(fih_int saved) 48 { 49 if (fih_not_eq(saved, _fih_cfi_ctr)) { 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 (void)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