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