openssl/crypto
Russ Butler 19e277dd19 aarch64: support BTI and pointer authentication in assembly
This change adds optional support for
- Armv8.3-A Pointer Authentication (PAuth) and
- Armv8.5-A Branch Target Identification (BTI)
features to the perl scripts.

Both features can be enabled with additional compiler flags.
Unless any of these are enabled explicitly there is no code change at
all.

The extensions are briefly described below. Please read the appropriate
chapters of the Arm Architecture Reference Manual for the complete
specification.

Scope
-----

This change only affects generated assembly code.

Armv8.3-A Pointer Authentication
--------------------------------

Pointer Authentication extension supports the authentication of the
contents of registers before they are used for indirect branching
or load.

PAuth provides a probabilistic method to detect corruption of register
values. PAuth signing instructions generate a Pointer Authentication
Code (PAC) based on the value of a register, a seed and a key.
The generated PAC is inserted into the original value in the register.
A PAuth authentication instruction recomputes the PAC, and if it matches
the PAC in the register, restores its original value. In case of a
mismatch, an architecturally unmapped address is generated instead.

With PAuth, mitigation against ROP (Return-oriented Programming) attacks
can be implemented. This is achieved by signing the contents of the
link-register (LR) before it is pushed to stack. Once LR is popped,
it is authenticated. This way a stack corruption which overwrites the
LR on the stack is detectable.

The PAuth extension adds several new instructions, some of which are not
recognized by older hardware. To support a single codebase for both pre
Armv8.3-A targets and newer ones, only NOP-space instructions are added
by this patch. These instructions are treated as NOPs on hardware
which does not support Armv8.3-A. Furthermore, this patch only considers
cases where LR is saved to the stack and then restored before branching
to its content. There are cases in the code where LR is pushed to stack
but it is not used later. We do not address these cases as they are not
affected by PAuth.

There are two keys available to sign an instruction address: A and B.
PACIASP and PACIBSP only differ in the used keys: A and B, respectively.
The keys are typically managed by the operating system.

To enable generating code for PAuth compile with
-mbranch-protection=<mode>:

- standard or pac-ret: add PACIASP and AUTIASP, also enables BTI
  (read below)
- pac-ret+b-key: add PACIBSP and AUTIBSP

Armv8.5-A Branch Target Identification
--------------------------------------

Branch Target Identification features some new instructions which
protect the execution of instructions on guarded pages which are not
intended branch targets.

If Armv8.5-A is supported by the hardware, execution of an instruction
changes the value of PSTATE.BTYPE field. If an indirect branch
lands on a guarded page the target instruction must be one of the
BTI <jc> flavors, or in case of a direct call or jump it can be any
other instruction. If the target instruction is not compatible with the
value of PSTATE.BTYPE a Branch Target Exception is generated.

In short, indirect jumps are compatible with BTI <j> and <jc> while
indirect calls are compatible with BTI <c> and <jc>. Please refer to the
specification for the details.

Armv8.3-A PACIASP and PACIBSP are implicit branch target
identification instructions which are equivalent with BTI c or BTI jc
depending on system register configuration.

BTI is used to mitigate JOP (Jump-oriented Programming) attacks by
limiting the set of instructions which can be jumped to.

BTI requires active linker support to mark the pages with BTI-enabled
code as guarded. For ELF64 files BTI compatibility is recorded in the
.note.gnu.property section. For a shared object or static binary it is
required that all linked units support BTI. This means that even a
single assembly file without the required note section turns-off BTI
for the whole binary or shared object.

The new BTI instructions are treated as NOPs on hardware which does
not support Armv8.5-A or on pages which are not guarded.

To insert this new and optional instruction compile with
-mbranch-protection=standard (also enables PAuth) or +bti.

When targeting a guarded page from a non-guarded page, weaker
compatibility restrictions apply to maintain compatibility between
legacy and new code. For detailed rules please refer to the Arm ARM.

Compiler support
----------------

Compiler support requires understanding '-mbranch-protection=<mode>'
and emitting the appropriate feature macros (__ARM_FEATURE_BTI_DEFAULT
and __ARM_FEATURE_PAC_DEFAULT). The current state is the following:

-------------------------------------------------------
| Compiler | -mbranch-protection | Feature macros     |
+----------+---------------------+--------------------+
| clang    | 9.0.0               | 11.0.0             |
+----------+---------------------+--------------------+
| gcc      | 9                   | expected in 10.1+  |
-------------------------------------------------------

Available Platforms
------------------

Arm Fast Model and QEMU support both extensions.

https://developer.arm.com/tools-and-software/simulation-models/fast-models
https://www.qemu.org/

Implementation Notes
--------------------

This change adds BTI landing pads even to assembly functions which are
likely to be directly called only. In these cases, landing pads might
be superfluous depending on what code the linker generates.
Code size and performance impact for these cases would be negligible.

Interaction with C code
-----------------------

Pointer Authentication is a per-frame protection while Branch Target
Identification can be turned on and off only for all code pages of a
whole shared object or static binary. Because of these properties if
C/C++ code is compiled without any of the above features but assembly
files support any of them unconditionally there is no incompatibility
between the two.

Useful Links
------------

To fully understand the details of both PAuth and BTI it is advised to
read the related chapters of the Arm Architecture Reference Manual
(Arm ARM):
https://developer.arm.com/documentation/ddi0487/latest/

Additional materials:

"Providing protection for complex software"
https://developer.arm.com/architectures/learn-the-architecture/providing-protection-for-complex-software

Arm Compiler Reference Guide Version 6.14: -mbranch-protection
https://developer.arm.com/documentation/101754/0614/armclang-Reference/armclang-Command-line-Options/-mbranch-protection?lang=en

Arm C Language Extensions (ACLE)
https://developer.arm.com/docs/101028/latest

Addional Notes
--------------

This patch is a copy of the work done by Tamas Petz in boringssl. It
contains the changes from the following commits:

aarch64: support BTI and pointer authentication in assembly
    Change-Id: I4335f92e2ccc8e209c7d68a0a79f1acdf3aeb791
    URL: https://boringssl-review.googlesource.com/c/boringssl/+/42084
aarch64: Improve conditional compilation
    Change-Id: I14902a64e5f403c2b6a117bc9f5fb1a4f4611ebf
    URL: https://boringssl-review.googlesource.com/c/boringssl/+/43524
aarch64: Fix name of gnu property note section
    Change-Id: I6c432d1c852129e9c273f6469a8b60e3983671ec
    URL: https://boringssl-review.googlesource.com/c/boringssl/+/44024

Change-Id: I2d95ebc5e4aeb5610d3b226f9754ee80cf74a9af

Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/16674)
2021-10-01 09:35:38 +02:00
..
aes aarch64: support BTI and pointer authentication in assembly 2021-10-01 09:35:38 +02:00
aria
asn1 Update copyright year 2021-09-07 13:35:43 +02:00
async Update copyright year 2021-06-17 13:24:59 +01:00
bf
bio BIO_ctrl: Avoid spurious error being raised on NULL bio parameter 2021-09-28 12:12:32 +02:00
bn aarch64: support BTI and pointer authentication in assembly 2021-10-01 09:35:38 +02:00
buffer Update copyright year 2021-06-17 13:24:59 +01:00
camellia Update copyright year 2021-07-29 15:41:35 +01:00
cast
chacha aarch64: support BTI and pointer authentication in assembly 2021-10-01 09:35:38 +02:00
cmac Rename all getters to use get/get0 in name 2021-06-01 12:40:00 +02:00
cmp Update copyright year 2021-09-07 13:35:43 +02:00
cms cms: fix memleaks in cms_env.c 2021-08-27 09:26:12 +02:00
comp Update copyright year 2021-06-17 13:24:59 +01:00
conf Update copyright year 2021-06-17 13:24:59 +01:00
crmf OSSL_CRMF_{CERTTEMPLATE,CERTID}_get0_serialNumber(): Make result const for consistency 2021-06-30 10:38:23 +02:00
ct Update copyright year 2021-06-17 13:24:59 +01:00
des Update copyright year 2021-07-29 15:41:35 +01:00
dh dh_ameth: Fix dh_cmp_parameters to really compare the params 2021-09-10 12:07:01 +02:00
dsa Update copyright year 2021-07-29 15:41:35 +01:00
dso Update copyright year 2021-06-17 13:24:59 +01:00
ec aarch64: support BTI and pointer authentication in assembly 2021-10-01 09:35:38 +02:00
encode_decode DECODER: check the first decoded structure name against user given structure 2021-09-05 21:34:50 +02:00
engine Update copyright year 2021-06-17 13:24:59 +01:00
err Add invalid input length error 2021-08-26 09:33:39 +10:00
ess err: rename err_load_xxx_strings_int functions 2021-05-26 13:01:47 +10:00
evp Fix double free in EVP_PKEY_CTX_dup() 2021-09-03 12:31:59 +02:00
ffc Set FFC_PARAM_FLAG_VALIDATE_LEGACY on params generated with FIPS 186-2 gen 2021-08-11 12:07:08 +02:00
hmac Adapt other parts of the source to the changed EVP_Q_digest() and EVP_Q_mac() 2021-06-23 23:00:36 +02:00
http OSSL_HTTP_open(): Fix memory leak on TLS connect failure via proxy 2021-07-22 10:14:47 +02:00
idea
kdf
lhash
md2
md4
md5 Update copyright year 2021-07-29 15:41:35 +01:00
mdc2
modes aarch64: support BTI and pointer authentication in assembly 2021-10-01 09:35:38 +02:00
objects obj: add locking to the OBJ sigid calls 2021-09-25 10:39:20 +10:00
ocsp Update copyright year 2021-06-17 13:24:59 +01:00
pem pvk: use PVK KDF 2021-09-28 18:08:41 +10:00
perlasm Update copyright year 2021-06-17 13:24:59 +01:00
pkcs7 Update copyright year 2021-06-17 13:24:59 +01:00
pkcs12 Update copyright year 2021-06-17 13:24:59 +01:00
poly1305 aarch64: support BTI and pointer authentication in assembly 2021-10-01 09:35:38 +02:00
property property: remove spurious incorrect comments 2021-06-24 15:51:48 +10:00
rand rand: avoid using the derivation function for the public and private DRBGs 2021-09-03 10:23:21 +10:00
rc2
rc4
rc5
ripemd
rsa Allow small RSA exponents in the default provider 2021-08-13 10:35:56 +02:00
seed Update copyright year 2021-06-17 13:24:59 +01:00
sha aarch64: support BTI and pointer authentication in assembly 2021-10-01 09:35:38 +02:00
siphash
sm2 sm2: fix error raise to not fail make update 2021-08-25 10:12:17 +10:00
sm3
sm4
srp add zero strenght arguments to BN and RAND RNG calls 2021-05-29 17:17:12 +10:00
stack
store PROV & STORE: Make the 'file:' store loader understand more binary formats 2021-07-03 19:44:15 +02:00
ts ts: fix memleaks caused by TS_VERIFY_CTX_set_imprint 2021-08-26 11:06:06 +02:00
txt_db
ui Update copyright year 2021-07-29 15:41:35 +01:00
whrlpool
x509 Fix nc_email to check ASN1 strings with NULL byte in the middle 2021-09-13 17:02:37 +10:00
alphacpuid.pl
arm64cpuid.pl aarch64: support BTI and pointer authentication in assembly 2021-10-01 09:35:38 +02:00
arm_arch.h aarch64: support BTI and pointer authentication in assembly 2021-10-01 09:35:38 +02:00
armcap.c enable getauxval on android 10 2021-06-25 18:31:05 +10:00
armv4cpuid.pl
asn1_dsa.c
bsearch.c
build.info FIPS: don't include crypto/passphrase.c in libfips.a 2021-06-05 10:32:13 +02:00
c64xpluscpuid.pl
context.c
core_algorithm.c
core_fetch.c CORE: Do a bit of cleanup of core fetching 2021-06-16 12:32:53 +01:00
core_namemap.c Rename all getters to use get/get0 in name 2021-06-01 12:40:00 +02:00
cpt_err.c err: rename err_load_xxx_strings_int functions 2021-05-26 13:01:47 +10:00
cpuid.c
cryptlib.c crypto: remove TODOs 2021-06-02 16:30:15 +10:00
ctype.c Use <> for #include openssl/xxx 2021-05-27 09:56:41 +10:00
cversion.c
der_writer.c
dllmain.c
ebcdic.c
ex_data.c
getenv.c
ia64cpuid.S
info.c
init.c Prevent recursive call of OPENSSL_INIT_LOAD_CONFIG 2021-08-05 09:21:00 +10:00
initthread.c Fix a memleak in the FIPS provider 2021-05-24 09:39:15 +10:00
LPdir_nyi.c
LPdir_unix.c
LPdir_vms.c
LPdir_win32.c
LPdir_win.c
LPdir_wince.c
mem_clr.c
mem_sec.c
mem.c
mips_arch.h
o_dir.c
o_fopen.c
o_init.c
o_str.c
o_time.c
packet.c Update copyright year 2021-06-17 13:24:59 +01:00
param_build_set.c
param_build.c
params_dup.c
params_from_text.c
params.c params: fix range check when converting double to uint64_t. 2021-06-19 15:47:57 +10:00
pariscid.pl
passphrase.c Update copyright year 2021-07-29 15:41:35 +01:00
ppccap.c enable getauxval on android 10 2021-06-25 18:31:05 +10:00
ppccpuid.pl
provider_child.c Fix a race in ossl_provider_add_to_store() 2021-06-24 14:48:15 +01:00
provider_conf.c Add locking for the provider_conf.c 2021-08-27 09:51:00 +10:00
provider_core.c Refactor provider_core.c to adhere to the locking rules 2021-08-31 20:44:16 +10:00
provider_local.h make struct provider_info_st a full type 2021-06-24 14:48:15 +01:00
provider_predefined.c make struct provider_info_st a full type 2021-06-24 14:48:15 +01:00
provider.c Fix a race in ossl_provider_add_to_store() 2021-06-24 14:48:15 +01:00
punycode.c
README-sparse_array.md
s390x_arch.h Add default provider support for Keccak 224, 256, 384 and 512 2021-09-23 12:07:57 +10:00
s390xcap.c
s390xcpuid.pl
self_test_core.c Update copyright year 2021-05-20 14:22:33 +01:00
sparccpuid.S
sparcv9cap.c Split bignum code out of the sparcv9cap.c 2021-07-15 09:33:04 +02:00
sparse_array.c
threads_lib.c
threads_none.c
threads_pthread.c Defined out MUTEX attributes not available on NonStop SPT Threads. 2021-07-02 12:33:45 +10:00
threads_win.c Explicitly #include <synchapi.h> is unnecessary 2021-09-23 14:07:18 +02:00
trace.c Rework and make DEBUG macros consistent. 2021-05-28 10:04:31 +02:00
uid.c Openssl fails to compile on Debian with kfreebsd kernels 2021-09-02 10:02:32 +10:00
vms_rms.h
x86_64cpuid.pl
x86cpuid.pl