xref: /rk3399_ARM-atf/lib/extensions/pauth/pauth.c (revision f8138056404d788c94bff8b159317bf38145f102)
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/extensions/pauth.h>
10 
11 void __no_pauth pauth_init_enable_el3(void)
12 {
13 	if (is_feat_pauth_supported()) {
14 		pauth_init();
15 		pauth_enable_el3();
16 	}
17 }
18 
19 void __no_pauth pauth_init_enable_el1(void)
20 {
21 	if (is_feat_pauth_supported()) {
22 		pauth_init();
23 		pauth_enable_el1();
24 	}
25 }
26 
27 void pauth_init(void)
28 {
29 	uint128_t keys = plat_init_apkey();
30 	uint64_t key_lo = LO_64(keys);
31 	uint64_t key_hi = HI_64(keys);
32 
33 	/* Program instruction key A used by the Trusted Firmware */
34 	write_apiakeylo_el1(key_lo);
35 	write_apiakeyhi_el1(key_hi);
36 }
37 
38 /*
39  * Begin checking function calls at the current EL. This function must not have
40  * PAuth guards because the signing will be a NOP and attempting to authenticate
41  * will fail. Includes an ISB to avoid accidental failures.
42  */
43 void __no_pauth pauth_enable_el3(void)
44 {
45 	write_sctlr_el3(read_sctlr_el3() | SCTLR_EnIA_BIT);
46 	isb();
47 }
48 
49 void __no_pauth pauth_enable_el1(void)
50 {
51 	write_sctlr_el1(read_sctlr_el1() | SCTLR_EnIA_BIT);
52 	isb();
53 }
54 
55 /* Enable PAuth for EL2 */
56 void pauth_enable_el2(void)
57 {
58 	u_register_t hcr_el2 = read_hcr_el2();
59 	/*
60 	 * For Armv8.3 pointer authentication feature, disable traps to EL2 when
61 	 * accessing key registers or using pointer authentication instructions
62 	 * from lower ELs.
63 	 */
64 	hcr_el2 |= (HCR_API_BIT | HCR_APK_BIT);
65 
66 	write_hcr_el2(hcr_el2);
67 }
68 
69 void __no_pauth pauth_disable_el1(void)
70 {
71 	write_sctlr_el1(read_sctlr_el1() & ~SCTLR_EnIA_BIT);
72 	isb(); /* usually called by caller, here it's for compatibility */
73 }
74 
75 void __no_pauth pauth_disable_el3(void)
76 {
77 	write_sctlr_el3(read_sctlr_el3() & ~SCTLR_EnIA_BIT);
78 	isb(); /* usually called by caller, here it's for compatibility */
79 }
80