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