File: fault_mitigation.c

package info (click to toggle)
optee-os 4.7.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 31,560 kB
  • sloc: ansic: 441,914; asm: 12,903; python: 3,719; makefile: 1,676; sh: 238
file content (153 lines) | stat: -rw-r--r-- 3,408 bytes parent folder | download | duplicates (2)
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;
}