1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2022, Linaro Limited 4 */ 5 6 #include <compiler.h> 7 #include <fault_mitigation.h> 8 9 #ifndef __KERNEL__ 10 struct ftmn_func_arg *__ftmn_global_func_arg; 11 #endif 12 13 /* 14 * These functions can be implemented in assembly if needed. They would 15 * provide the same API but an implementation more resilient to fault 16 * injections. 17 * 18 * For now there is no need since it's enough with the single redundancy 19 * provided just by having these function implemented separately from where 20 * they are used. 21 */ 22 23 unsigned long __weak ___ftmn_return_res(struct ftmn_check *check, 24 unsigned long steps, unsigned long res) 25 { 26 if (check->steps != steps) 27 FTMN_PANIC(); 28 if ((check->res ^ FTMN_DEFAULT_HASH) != res) 29 FTMN_PANIC(); 30 return res; 31 } 32 33 void __weak ___ftmn_expect_state(struct ftmn_check *check, enum ftmn_incr incr, 34 unsigned long steps, unsigned long res) 35 { 36 if ((check->res ^ FTMN_DEFAULT_HASH) != res) 37 FTMN_PANIC(); 38 if (check->steps != steps) 39 FTMN_PANIC(); 40 check->steps += incr; 41 } 42 43 void __weak ___ftmn_callee_done(struct ftmn_func_arg *arg, 44 unsigned long my_hash, 45 unsigned long res) 46 { 47 arg->hash ^= my_hash; 48 arg->res = arg->hash ^ res; 49 } 50 51 void __weak ___ftmn_callee_done_not_zero(struct ftmn_func_arg *arg, 52 unsigned long my_hash, 53 unsigned long res) 54 { 55 if (res == 0) 56 FTMN_PANIC(); 57 arg->hash ^= my_hash; 58 arg->res = arg->hash ^ res; 59 } 60 61 void __weak ___ftmn_callee_done_memcmp(struct ftmn_func_arg *arg, 62 unsigned long my_hash, int res, 63 ftmn_memcmp_t my_memcmp, 64 const void *p1, const void *p2, 65 size_t nb) 66 { 67 int res2 = 0; 68 69 if (!nb) 70 FTMN_PANIC(); 71 72 res2 = my_memcmp(p1, p2, nb); 73 if (res2 != res) 74 FTMN_PANIC(); 75 76 arg->hash ^= my_hash; 77 arg->res = arg->hash ^ res; 78 } 79 80 void __weak ___ftmn_callee_done_check(struct ftmn_func_arg *arg, 81 unsigned long my_hash, 82 struct ftmn_check *check, 83 enum ftmn_incr incr, unsigned long steps, 84 unsigned long res) 85 { 86 if ((check->res ^ FTMN_DEFAULT_HASH) != res) 87 FTMN_PANIC(); 88 if (check->steps != steps) 89 FTMN_PANIC(); 90 91 check->steps += incr; 92 if (arg) { 93 arg->hash ^= my_hash; 94 arg->res = check->res ^ FTMN_DEFAULT_HASH ^ arg->hash; 95 } 96 97 } 98 99 void ___ftmn_callee_update_not_zero(struct ftmn_func_arg *arg, 100 unsigned long res) 101 { 102 if (!res) 103 FTMN_PANIC(); 104 arg->res = arg->hash ^ res; 105 } 106 107 108 void __weak ___ftmn_copy_linked_call_res(struct ftmn_check *check, 109 enum ftmn_incr incr, 110 struct ftmn_func_arg *arg, 111 unsigned long res) 112 { 113 if ((arg->res ^ arg->hash) != res) 114 FTMN_PANIC(); 115 check->res = res ^ FTMN_DEFAULT_HASH; 116 check->steps += incr; 117 } 118 119 void __weak ___ftmn_set_check_res(struct ftmn_check *check, enum ftmn_incr incr, 120 unsigned long res) 121 { 122 check->steps += incr; 123 check->res = res ^ FTMN_DEFAULT_HASH; 124 } 125 126 void __weak ___ftmn_set_check_res_not_zero(struct ftmn_check *check, 127 enum ftmn_incr incr, 128 unsigned long res) 129 { 130 if (!res) 131 FTMN_PANIC(); 132 check->steps += incr; 133 check->res = res ^ FTMN_DEFAULT_HASH; 134 } 135 136 void __weak ___ftmn_set_check_res_memcmp(struct ftmn_check *check, 137 enum ftmn_incr incr, int res, 138 ftmn_memcmp_t my_memcmp, 139 const void *p1, const void *p2, 140 size_t nb) 141 { 142 int res2 = 0; 143 144 if (!nb) 145 FTMN_PANIC(); 146 147 res2 = my_memcmp(p1, p2, nb); 148 if (res2 != res) 149 FTMN_PANIC(); 150 151 check->steps += incr; 152 check->res = FTMN_DEFAULT_HASH ^ res; 153 } 154