xref: /rk3399_ARM-atf/lib/extensions/pauth/pauth.c (revision b67e984664a8644d6cfd1812cabaa02cf24f09c9)
1 /*
2  * Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 #include <arch.h>
7 #include <arch_features.h>
8 #include <arch_helpers.h>
9 #include <lib/el3_runtime/cpu_data.h>
10 #include <lib/extensions/pauth.h>
11 
12 extern uint64_t bl1_apiakey[2];
13 
14 void __no_pauth pauth_init_enable_el3(void)
15 {
16 	pauth_init();
17 	pauth_enable_el3();
18 }
19 
20 void __no_pauth pauth_init_enable_el1(void)
21 {
22 	pauth_init();
23 	pauth_enable_el1();
24 }
25 
26 void pauth_init(void)
27 {
28 	uint128_t keys = plat_init_apkey();
29 	uint64_t key_lo = LO_64(keys);
30 	uint64_t key_hi = HI_64(keys);
31 
32 	/* Program instruction key A used by the Trusted Firmware */
33 	write_apiakeylo_el1(key_lo);
34 	write_apiakeyhi_el1(key_hi);
35 
36 #if IMAGE_BL31
37 	set_cpu_data(apiakey[0], key_lo);
38 	set_cpu_data(apiakey[1], key_hi);
39 
40 	/*
41 	 * In the warmboot entrypoint, cpu_data may have been written before
42 	 * data caching was enabled. Flush the caches so nothing stale is read.
43 	 */
44 #if !(HW_ASSISTED_COHERENCY || WARMBOOT_ENABLE_DCACHE_EARLY)
45 	flush_cpu_data(apiakey);
46 #endif
47 #elif IMAGE_BL1
48 	bl1_apiakey[0] = key_lo;
49 	bl1_apiakey[1] = key_hi;
50 #endif
51 }
52 
53 /*
54  * Begin checking function calls at the current EL. This function must not have
55  * PAuth guards because the signing will be a NOP and attempting to authenticate
56  * will fail. Includes an ISB to avoid accidental failures.
57  */
58 void __no_pauth pauth_enable_el3(void)
59 {
60 	write_sctlr_el3(read_sctlr_el3() | SCTLR_EnIA_BIT);
61 
62 	if (is_feat_pauth_lr_supported()) {
63 		write_sctlr2_el3(read_sctlr2_el3() | SCTLR2_EnPACM_BIT);
64 	}
65 
66 	isb();
67 }
68 
69 void __no_pauth pauth_enable_el1(void)
70 {
71 	write_sctlr_el1(read_sctlr_el1() | SCTLR_EnIA_BIT);
72 
73 	if (is_feat_pauth_lr_supported()) {
74 		write_sctlr2_el1(read_sctlr2_el1() | SCTLR2_EnPACM_BIT);
75 	}
76 
77 	isb();
78 }
79 
80 void pauth_enable_el2(void)
81 {
82 	u_register_t hcr_el2 = read_hcr_el2();
83 	/*
84 	 * For Armv8.3 pointer authentication feature, disable traps to EL2 when
85 	 * accessing key registers or using pointer authentication instructions
86 	 * from lower ELs.
87 	 */
88 	hcr_el2 |= (HCR_API_BIT | HCR_APK_BIT);
89 
90 	write_hcr_el2(hcr_el2);
91 }
92 
93 void __no_pauth pauth_disable_el1(void)
94 {
95 	write_sctlr_el1(read_sctlr_el1() & ~SCTLR_EnIA_BIT);
96 	isb(); /* usually called by caller, here it's for compatibility */
97 }
98 
99 void __no_pauth pauth_disable_el3(void)
100 {
101 	write_sctlr_el3(read_sctlr_el3() & ~SCTLR_EnIA_BIT);
102 	isb(); /* usually called by caller, here it's for compatibility */
103 }
104