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