xref: /rk3399_ARM-atf/plat/renesas/common/rcar_stack_protector.c (revision 223d989ed990fedf58c8f605d5e4c924b022cd62)
1*223d989eSMarek Vasut /*
2*223d989eSMarek Vasut  * Copyright (c) 2021-2025, Renesas Electronics Corporation. All rights reserved.
3*223d989eSMarek Vasut  *
4*223d989eSMarek Vasut  * SPDX-License-Identifier: BSD-3-Clause
5*223d989eSMarek Vasut  */
6*223d989eSMarek Vasut 
7*223d989eSMarek Vasut #include <stdint.h>
8*223d989eSMarek Vasut 
9*223d989eSMarek Vasut #include <arch_helpers.h>
10*223d989eSMarek Vasut #include <common/debug.h>
11*223d989eSMarek Vasut 
12*223d989eSMarek Vasut #define RANDOM_CANARY_VALUE	((u_register_t)0xDFF5FC8A720E205EULL)
13*223d989eSMarek Vasut 
14*223d989eSMarek Vasut u_register_t plat_get_stack_protector_canary(void)
15*223d989eSMarek Vasut {
16*223d989eSMarek Vasut 	uintptr_t val1 = (uintptr_t)__builtin_return_address(0U);
17*223d989eSMarek Vasut 	uintptr_t val2 = (uintptr_t)__builtin_frame_address(0U);
18*223d989eSMarek Vasut 	u_register_t cnt;
19*223d989eSMarek Vasut 	u_register_t seed;
20*223d989eSMarek Vasut 	u_register_t mul;
21*223d989eSMarek Vasut 	u_register_t ret;
22*223d989eSMarek Vasut 
23*223d989eSMarek Vasut 	cnt = read_cntpct_el0();
24*223d989eSMarek Vasut 	seed = (cnt ^ RANDOM_CANARY_VALUE) & ULONG_MAX;
25*223d989eSMarek Vasut 	ret = seed;
26*223d989eSMarek Vasut 
27*223d989eSMarek Vasut 	INFO("seed value: 0x%16lx    cnt: 0x%16lx\n", seed, cnt);
28*223d989eSMarek Vasut 
29*223d989eSMarek Vasut 	if ((ULONG_MAX / val1) > seed) {
30*223d989eSMarek Vasut 		mul = (u_register_t)(val1 * seed);
31*223d989eSMarek Vasut 		if ((ULONG_MAX - mul) > val2) {
32*223d989eSMarek Vasut 			ret = mul + val2;
33*223d989eSMarek Vasut 		}
34*223d989eSMarek Vasut 	}
35*223d989eSMarek Vasut 
36*223d989eSMarek Vasut 	INFO("canary value: 0x%lx    cnt: 0x%16lx\n", ret, read_cntpct_el0());
37*223d989eSMarek Vasut 
38*223d989eSMarek Vasut 	return ret;
39*223d989eSMarek Vasut }
40